Merge "Progress notification for interactive bugreports"
diff --git a/Android.bp b/Android.bp
index 90bc9f2..7693a66 100644
--- a/Android.bp
+++ b/Android.bp
@@ -136,7 +136,6 @@
         "core/java/android/content/pm/IDexModuleRegisterCallback.aidl",
         "core/java/android/content/pm/ILauncherApps.aidl",
         "core/java/android/content/pm/IOnAppsChangedListener.aidl",
-        "core/java/android/content/pm/IOnPermissionsChangeListener.aidl",
         "core/java/android/content/pm/IOtaDexopt.aidl",
         "core/java/android/content/pm/IPackageDataObserver.aidl",
         "core/java/android/content/pm/IPackageDeleteObserver.aidl",
@@ -278,7 +277,9 @@
         "core/java/android/os/storage/IStorageEventListener.aidl",
         "core/java/android/os/storage/IStorageShutdownObserver.aidl",
         "core/java/android/os/storage/IObbActionListener.aidl",
+        "core/java/android/permission/IOnPermissionsChangeListener.aidl",
         "core/java/android/permission/IPermissionController.aidl",
+        "core/java/android/permission/IPermissionManager.aidl",
         ":keystore_aidl",
         "core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl",
         "core/java/android/service/appprediction/IPredictionService.aidl",
@@ -307,7 +308,7 @@
         "core/java/android/service/euicc/IRetainSubscriptionsForFactoryResetCallback.aidl",
         "core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl",
         "core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl",
-        "core/java/android/service/gatekeeper/IGateKeeperService.aidl",
+        ":gatekeeper_aidl",
         "core/java/android/service/contentcapture/IContentCaptureService.aidl",
         "core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl",
         "core/java/android/service/notification/INotificationListener.aidl",
@@ -564,7 +565,7 @@
         "telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl",
         "telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl",
         "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl",
-        "telephony/java/android/telephony/ims/aidl/IRcs.aidl",
+        "telephony/java/android/telephony/ims/aidl/IRcsMessage.aidl",
         "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
         "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
         "telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl",
@@ -731,6 +732,7 @@
             "frameworks/av/media/libaudioclient/aidl",
             "frameworks/native/aidl/gui",
             "frameworks/native/libs/incidentcompanion/binder",
+            "system/core/gatekeeperd/binder",
             "system/core/storaged/binder",
             "system/vold/binder",
             "system/gsid/aidl",
@@ -746,7 +748,7 @@
         "core/java/android/content/pm/AndroidTestBaseUpdater.java",
     ],
 
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     libs: [
         "ext",
         "updatable_media_stubs",
@@ -756,6 +758,7 @@
 
     static_libs: [
         "apex_aidl_interface-java",
+        "suspend_control_aidl_interface-java",
         "framework-protos",
         "game-driver-protos",
         "android.hidl.base-V1.0-java",
@@ -809,6 +812,7 @@
         "core/java/android/os/IIncidentManager.aidl",
         "core/java/android/os/IIncidentReportStatusListener.aidl",
     ],
+    path: "core/java",
 }
 
 filegroup {
@@ -818,6 +822,7 @@
         "core/java/android/os/IStatsManager.aidl",
         "core/java/android/os/IStatsPullerCallback.aidl",
     ],
+    path: "core/java",
 }
 
 filegroup {
@@ -826,6 +831,7 @@
         "core/java/android/os/IExternalVibrationController.aidl",
         "core/java/android/os/IExternalVibratorService.aidl",
     ],
+    path: "core/java",
 }
 
 java_library {
@@ -837,19 +843,27 @@
 java_library {
     name: "framework-annotation-proc",
     defaults: ["framework-defaults"],
+    installable: false,
     // Use UsedByApps annotation processor
     plugins: ["unsupportedappusage-annotation-processor"],
 }
 
-// A host library including just UnsupportedAppUsage.java so that the annotation
-// processor can also use this annotation.
-java_library_host {
+// A library including just UnsupportedAppUsage.java classes.
+//
+// Provided for target so that libraries can use it without depending on
+// the whole of framework or the core platform API.
+//
+// Built for host so that the annotation processor can also use this annotation.
+java_library {
     name: "unsupportedappusage-annotation",
+    host_supported: true,
     srcs: [
         "core/java/android/annotation/IntDef.java",
         "core/java/android/annotation/UnsupportedAppUsage.java",
         ":unsupportedappusage_annotation_files",
     ],
+
+    sdk_version: "core_current",
 }
 
 // A temporary build target that is conditionally included on the bootclasspath if
@@ -940,7 +954,7 @@
 java_library {
     name: "ext",
     installable: true,
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     static_libs: [
         "libphonenumber-platform",
         "nist-sip",
@@ -1164,7 +1178,7 @@
 // updated to use hwbinder.stubs.
 java_library {
     name: "hwbinder",
-    no_framework_libs: true,
+    sdk_version: "core_platform",
 
     srcs: [
         "core/java/android/os/HidlSupport.java",
@@ -1252,6 +1266,24 @@
     ],
 }
 
+// Make the api/system-current.txt file available for use by modules in other
+// directories.
+filegroup {
+    name: "frameworks-base-api-system-current.txt",
+    srcs: [
+        "api/system-current.txt",
+    ],
+}
+
+// Make the api/system-removed.txt file available for use by modules in other
+// directories.
+filegroup {
+    name: "frameworks-base-api-system-removed.txt",
+    srcs: [
+        "api/system-removed.txt",
+    ],
+}
+
 framework_docs_only_args = " -android -manifest $(location core/res/AndroidManifest.xml) " +
     "-werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " +
     "-overview $(location core/java/overview.html) " +
@@ -1388,7 +1420,6 @@
     libs: [
         "ext",
         "framework",
-        "voip-common",
     ],
     local_sourcepaths: frameworks_base_subdirs,
     installable: false,
@@ -1673,7 +1704,7 @@
         "core/java/android/util/AndroidException.java",
     ],
     installable: false,
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     annotations_enabled: true,
     previous_api: ":last-released-public-api",
     merge_annotations_dirs: [
@@ -1850,3 +1881,13 @@
     srcs: [":framework-defaults"],
     output: "framework-aidl-mappings.txt",
 }
+
+genrule {
+    name: "framework-annotation-proc-index",
+    srcs: [":framework-annotation-proc"],
+    cmd: "unzip -qp $(in) unsupportedappusage/unsupportedappusage_index.csv > $(out)",
+    out: ["unsupportedappusage_index.csv"],
+    dist: {
+        targets: ["droidcore"],
+    },
+}
diff --git a/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
new file mode 100644
index 0000000..f0c474b
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/wm/RelayoutPerfTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.wm;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.perftests.utils.StubActivity;
+import android.util.MergedConfiguration;
+import android.view.DisplayCutout;
+import android.view.IWindow;
+import android.view.IWindowSession;
+import android.view.InsetsState;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.widget.LinearLayout;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.function.IntSupplier;
+
+@RunWith(Parameterized.class)
+@LargeTest
+public class RelayoutPerfTest extends WindowManagerPerfTestBase {
+    private int mIteration;
+
+    @Rule
+    public final PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Rule
+    public final ActivityTestRule<StubActivity> mActivityRule =
+            new ActivityTestRule<>(StubActivity.class);
+
+    /** This is only a placement to match the input parameters from {@link #getParameters}. */
+    @Parameterized.Parameter(0)
+    public String testName;
+
+    /** The visibilities to loop for relayout. */
+    @Parameterized.Parameter(1)
+    public int[] visibilities;
+
+    /**
+     * Each row will be mapped into {@link #testName} and {@link #visibilities} of a new test
+     * instance according to the index of the parameter.
+     */
+    @Parameterized.Parameters(name = "{0}")
+    public static Collection<Object[]> getParameters() {
+        return Arrays.asList(new Object[][] {
+                { "Visible", new int[] { View.VISIBLE } },
+                { "Invisible~Visible", new int[] { View.INVISIBLE, View.VISIBLE } },
+                { "Gone~Visible", new int[] { View.GONE, View.VISIBLE } },
+                { "Gone~Invisible", new int[] { View.GONE, View.INVISIBLE } }
+        });
+    }
+
+    @Test
+    public void testRelayout() throws Throwable {
+        final Activity activity = mActivityRule.getActivity();
+        final ContentView contentView = new ContentView(activity);
+        mActivityRule.runOnUiThread(() -> {
+            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+            activity.setContentView(contentView);
+        });
+        getInstrumentation().waitForIdleSync();
+
+        final RelayoutRunner relayoutRunner = new RelayoutRunner(activity, contentView.getWindow(),
+                () -> visibilities[mIteration++ % visibilities.length]);
+        relayoutRunner.runBenchmark(mPerfStatusReporter.getBenchmarkState());
+    }
+
+    /** A dummy view to get IWindow. */
+    private static class ContentView extends LinearLayout {
+        ContentView(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected IWindow getWindow() {
+            return super.getWindow();
+        }
+    }
+
+    private static class RelayoutRunner {
+        final Rect mOutFrame = new Rect();
+        final Rect mOutOverscanInsets = new Rect();
+        final Rect mOutContentInsets = new Rect();
+        final Rect mOutVisibleInsets = new Rect();
+        final Rect mOutStableInsets = new Rect();
+        final Rect mOutOutsets = new Rect();
+        final Rect mOutBackDropFrame = new Rect();
+        final DisplayCutout.ParcelableWrapper mOutDisplayCutout =
+                new DisplayCutout.ParcelableWrapper(DisplayCutout.NO_CUTOUT);
+        final MergedConfiguration mOutMergedConfiguration = new MergedConfiguration();
+        final InsetsState mOutInsetsState = new InsetsState();
+        final IWindow mWindow;
+        final View mView;
+        final WindowManager.LayoutParams mParams;
+        final int mWidth;
+        final int mHeight;
+        final SurfaceControl mOutSurfaceControl;
+
+        final IntSupplier mViewVisibility;
+
+        int mSeq;
+        int mFrameNumber;
+        int mFlags;
+
+        RelayoutRunner(Activity activity, IWindow window, IntSupplier visibilitySupplier) {
+            mWindow = window;
+            mView = activity.getWindow().getDecorView();
+            mParams = (WindowManager.LayoutParams) mView.getLayoutParams();
+            mWidth = mView.getMeasuredWidth();
+            mHeight = mView.getMeasuredHeight();
+            mOutSurfaceControl = mView.getViewRootImpl().getSurfaceControl();
+            mViewVisibility = visibilitySupplier;
+        }
+
+        void runBenchmark(BenchmarkState state) throws RemoteException {
+            final IWindowSession session = WindowManagerGlobal.getWindowSession();
+            while (state.keepRunning()) {
+                session.relayout(mWindow, mSeq, mParams, mWidth, mHeight,
+                        mViewVisibility.getAsInt(), mFlags, mFrameNumber, mOutFrame,
+                        mOutOverscanInsets, mOutContentInsets, mOutVisibleInsets, mOutStableInsets,
+                        mOutOutsets, mOutBackDropFrame, mOutDisplayCutout, mOutMergedConfiguration,
+                        mOutSurfaceControl, mOutInsetsState);
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java b/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java
new file mode 100644
index 0000000..a951869
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/wm/WindowAddRemovePerfTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.wm;
+
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.perftests.utils.ManualBenchmarkState;
+import android.perftests.utils.ManualBenchmarkState.ManualBenchmarkTest;
+import android.perftests.utils.PerfManualStatusReporter;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.InsetsState;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import androidx.test.filters.LargeTest;
+
+import com.android.internal.view.BaseIWindow;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+@LargeTest
+public class WindowAddRemovePerfTest extends WindowManagerPerfTestBase {
+    @Rule
+    public final PerfManualStatusReporter mPerfStatusReporter = new PerfManualStatusReporter();
+
+    @BeforeClass
+    public static void setUpClass() {
+        // Get the permission to use most window types.
+        sUiAutomation.adoptShellPermissionIdentity();
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        sUiAutomation.dropShellPermissionIdentity();
+    }
+
+    @Test
+    @ManualBenchmarkTest(warmupDurationNs = WARMUP_DURATION, targetTestDurationNs = TEST_DURATION)
+    public void testAddRemoveWindow() throws Throwable {
+        new TestWindow().runBenchmark(mPerfStatusReporter.getBenchmarkState());
+    }
+
+    private static class TestWindow extends BaseIWindow {
+        final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams();
+        final Rect mOutFrame = new Rect();
+        final Rect mOutContentInsets = new Rect();
+        final Rect mOutStableInsets = new Rect();
+        final Rect mOutOutsets = new Rect();
+        final DisplayCutout.ParcelableWrapper mOutDisplayCutout =
+                new DisplayCutout.ParcelableWrapper();
+        final InsetsState mOutInsetsState = new InsetsState();
+
+        TestWindow() {
+            mLayoutParams.setTitle(TestWindow.class.getName());
+            mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+            // Simulate as common phone window.
+            mLayoutParams.flags = FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+        }
+
+        void runBenchmark(ManualBenchmarkState state) throws RemoteException {
+            final IWindowSession session = WindowManagerGlobal.getWindowSession();
+            long elapsedTimeNs = 0;
+            while (state.keepRunning(elapsedTimeNs)) {
+                // InputChannel cannot be reused.
+                final InputChannel inputChannel = new InputChannel();
+
+                long startTime = SystemClock.elapsedRealtimeNanos();
+                session.addToDisplay(this, mSeq, mLayoutParams, View.VISIBLE,
+                        Display.DEFAULT_DISPLAY, mOutFrame, mOutContentInsets, mOutStableInsets,
+                        mOutOutsets, mOutDisplayCutout, inputChannel, mOutInsetsState);
+                final long elapsedTimeNsOfAdd = SystemClock.elapsedRealtimeNanos() - startTime;
+                state.addExtraResult("add", elapsedTimeNsOfAdd);
+
+                startTime = SystemClock.elapsedRealtimeNanos();
+                session.remove(this);
+                final long elapsedTimeNsOfRemove = SystemClock.elapsedRealtimeNanos() - startTime;
+                state.addExtraResult("remove", elapsedTimeNsOfRemove);
+
+                elapsedTimeNs = elapsedTimeNsOfAdd + elapsedTimeNsOfRemove;
+            }
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
new file mode 100644
index 0000000..b2c6168
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/wm/WindowManagerPerfTestBase.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.wm;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import android.app.UiAutomation;
+
+import org.junit.Before;
+
+public class WindowManagerPerfTestBase {
+    static final UiAutomation sUiAutomation = getInstrumentation().getUiAutomation();
+    static final long NANOS_PER_S = 1000L * 1000 * 1000;
+    static final long WARMUP_DURATION = 1 * NANOS_PER_S;
+    static final long TEST_DURATION = 5 * NANOS_PER_S;
+
+    @Before
+    public void setUp() {
+        // In order to be closer to the real use case.
+        sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
+        sUiAutomation.executeShellCommand("wm dismiss-keyguard");
+    }
+}
diff --git a/apct-tests/perftests/multiuser/AndroidTest.xml b/apct-tests/perftests/multiuser/AndroidTest.xml
index d8e3f01..9117561 100644
--- a/apct-tests/perftests/multiuser/AndroidTest.xml
+++ b/apct-tests/perftests/multiuser/AndroidTest.xml
@@ -19,7 +19,7 @@
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="MultiUserPerfTests.apk" />
-        <option name="test-file-name" value="PerftestMultiuserDummyApp.apk" />
+        <option name="test-file-name" value="MultiUserPerfDummyApp.apk" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/apct-tests/perftests/multiuser/apps/Android.mk b/apct-tests/perftests/multiuser/apps/Android.mk
deleted file mode 100644
index e01225b..0000000
--- a/apct-tests/perftests/multiuser/apps/Android.mk
+++ /dev/null
@@ -1,20 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Build the test APKs using their own makefiles
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/apct-tests/perftests/multiuser/apps/dummyapp/Android.bp b/apct-tests/perftests/multiuser/apps/dummyapp/Android.bp
index 73b2a01..08c54a6 100644
--- a/apct-tests/perftests/multiuser/apps/dummyapp/Android.bp
+++ b/apct-tests/perftests/multiuser/apps/dummyapp/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_test_helper_app {
-    name: "PerftestMultiuserDummyApp",
+    name: "MultiUserPerfDummyApp",
 
     srcs: ["src/**/*.java"],
 
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index ee4e1e4..e2ef7a1 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -326,6 +326,34 @@
         }
     }
 
+    /**
+     * Tests starting (unlocking) and launching a previously-launched app
+     * in an already-created, but no-longer-running, profile.
+     * A sort of combination of {@link #managedProfileUnlockAndLaunchApp} and
+     * {@link #managedProfileUnlock_stopped}}.
+     */
+    @Test
+    public void managedProfileUnlockAndLaunchApp_stopped() throws Exception {
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createManagedProfile();
+            WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
+            installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+            startUserInBackground(userId);
+            startApp(userId, DUMMY_PACKAGE_NAME);
+            stopUser(userId, true);
+            TimeUnit.SECONDS.sleep(1); // Brief cool-down before re-starting profile.
+            mRunner.resumeTiming();
+
+            startUserInBackground(userId);
+            startApp(userId, DUMMY_PACKAGE_NAME);
+
+            mRunner.pauseTiming();
+            removeUser(userId);
+            mRunner.resumeTiming();
+        }
+    }
+
     /** Tests installing a pre-existing app in a newly-created profile. */
     @Test
     public void managedProfileInstall() throws Exception {
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
index 40778de..dd43ae7 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/ManualBenchmarkState.java
@@ -19,8 +19,13 @@
 import android.app.Activity;
 import android.app.Instrumentation;
 import android.os.Bundle;
+import android.util.ArrayMap;
 import android.util.Log;
 
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 import java.util.ArrayList;
 import java.util.concurrent.TimeUnit;
 
@@ -71,6 +76,8 @@
 
     private int mState = NOT_STARTED;  // Current benchmark state.
 
+    private long mWarmupDurationNs = WARMUP_DURATION_NS;
+    private long mTargetTestDurationNs = TARGET_TEST_DURATION_NS;
     private long mWarmupStartTime = 0;
     private int mWarmupIterations = 0;
 
@@ -79,12 +86,30 @@
     // Individual duration in nano seconds.
     private ArrayList<Long> mResults = new ArrayList<>();
 
+    /** @see #addExtraResult(String, long) */
+    private ArrayMap<String, ArrayList<Long>> mExtraResults;
+
     // Statistics. These values will be filled when the benchmark has finished.
     // The computation needs double precision, but long int is fine for final reporting.
     private Stats mStats;
 
+    void configure(ManualBenchmarkTest testAnnotation) {
+        if (testAnnotation == null) {
+            return;
+        }
+
+        final long warmupDurationNs = testAnnotation.warmupDurationNs();
+        if (warmupDurationNs >= 0) {
+            mWarmupDurationNs = warmupDurationNs;
+        }
+        final long targetTestDurationNs = testAnnotation.targetTestDurationNs();
+        if (targetTestDurationNs >= 0) {
+            mTargetTestDurationNs = targetTestDurationNs;
+        }
+    }
+
     private void beginBenchmark(long warmupDuration, int iterations) {
-        mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations));
+        mMaxIterations = (int) (mTargetTestDurationNs / (warmupDuration / iterations));
         mMaxIterations = Math.min(MAX_TEST_ITERATIONS,
                 Math.max(mMaxIterations, MIN_TEST_ITERATIONS));
         mState = RUNNING;
@@ -108,7 +133,7 @@
                 final long timeSinceStartingWarmup = System.nanoTime() - mWarmupStartTime;
                 ++mWarmupIterations;
                 if (mWarmupIterations >= WARMUP_MIN_ITERATIONS
-                        && timeSinceStartingWarmup >= WARMUP_DURATION_NS) {
+                        && timeSinceStartingWarmup >= mWarmupDurationNs) {
                     beginBenchmark(timeSinceStartingWarmup, mWarmupIterations);
                 }
                 return true;
@@ -129,31 +154,69 @@
         }
     }
 
-    private String summaryLine() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("Summary: ");
-        sb.append("median=").append(mStats.getMedian()).append("ns, ");
-        sb.append("mean=").append(mStats.getMean()).append("ns, ");
-        sb.append("min=").append(mStats.getMin()).append("ns, ");
-        sb.append("max=").append(mStats.getMax()).append("ns, ");
-        sb.append("sigma=").append(mStats.getStandardDeviation()).append(", ");
-        sb.append("iteration=").append(mResults.size()).append(", ");
-        sb.append("values=").append(mResults.toString());
+    /**
+     * Adds additional result while this benchmark is running. It is used when a sequence of
+     * operations is executed consecutively, the duration of each operation can also be recorded.
+     */
+    public void addExtraResult(String key, long duration) {
+        if (mState != RUNNING) {
+            return;
+        }
+        if (mExtraResults == null) {
+            mExtraResults = new ArrayMap<>();
+        }
+        mExtraResults.computeIfAbsent(key, k -> new ArrayList<>()).add(duration);
+    }
+
+    private static String summaryLine(String key, Stats stats, ArrayList<Long> results) {
+        final StringBuilder sb = new StringBuilder(key);
+        sb.append(" Summary: ");
+        sb.append("median=").append(stats.getMedian()).append("ns, ");
+        sb.append("mean=").append(stats.getMean()).append("ns, ");
+        sb.append("min=").append(stats.getMin()).append("ns, ");
+        sb.append("max=").append(stats.getMax()).append("ns, ");
+        sb.append("sigma=").append(stats.getStandardDeviation()).append(", ");
+        sb.append("iteration=").append(results.size()).append(", ");
+        sb.append("values=");
+        if (results.size() > 100) {
+            sb.append(results.subList(0, 100)).append(" ...");
+        } else {
+            sb.append(results);
+        }
         return sb.toString();
     }
 
+    private static void fillStatus(Bundle status, String key, Stats stats) {
+        status.putLong(key + "_median", stats.getMedian());
+        status.putLong(key + "_mean", (long) stats.getMean());
+        status.putLong(key + "_percentile90", stats.getPercentile90());
+        status.putLong(key + "_percentile95", stats.getPercentile95());
+        status.putLong(key + "_stddev", (long) stats.getStandardDeviation());
+    }
+
     public void sendFullStatusReport(Instrumentation instrumentation, String key) {
         if (mState != FINISHED) {
             throw new IllegalStateException("The benchmark hasn't finished");
         }
-        Log.i(TAG, key + summaryLine());
+        Log.i(TAG, summaryLine(key, mStats, mResults));
         final Bundle status = new Bundle();
-        status.putLong(key + "_median", mStats.getMedian());
-        status.putLong(key + "_mean", (long) mStats.getMean());
-        status.putLong(key + "_percentile90", mStats.getPercentile90());
-        status.putLong(key + "_percentile95", mStats.getPercentile95());
-        status.putLong(key + "_stddev", (long) mStats.getStandardDeviation());
+        fillStatus(status, key, mStats);
+        if (mExtraResults != null) {
+            for (int i = 0; i < mExtraResults.size(); i++) {
+                final String subKey = key + "_" + mExtraResults.keyAt(i);
+                final Stats stats = new Stats(mExtraResults.valueAt(i));
+                Log.i(TAG, summaryLine(subKey, mStats, mResults));
+                fillStatus(status, subKey, stats);
+            }
+        }
         instrumentation.sendStatus(Activity.RESULT_OK, status);
     }
-}
 
+    /** The annotation to customize the test, e.g. the duration of warm-up and target test. */
+    @Target(ElementType.METHOD)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface ManualBenchmarkTest {
+        long warmupDurationNs() default -1;
+        long targetTestDurationNs() default -1;
+    }
+}
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/PerfManualStatusReporter.java b/apct-tests/perftests/utils/src/android/perftests/utils/PerfManualStatusReporter.java
index 8187c6f..8ff6a16 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/PerfManualStatusReporter.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/PerfManualStatusReporter.java
@@ -16,7 +16,7 @@
 
 package android.perftests.utils;
 
-import androidx.test.InstrumentationRegistry;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
@@ -59,15 +59,15 @@
 
     @Override
     public Statement apply(Statement base, Description description) {
+        mState.configure(description.getAnnotation(ManualBenchmarkState.ManualBenchmarkTest.class));
+
         return new Statement() {
             @Override
             public void evaluate() throws Throwable {
                 base.evaluate();
 
-                mState.sendFullStatusReport(InstrumentationRegistry.getInstrumentation(),
-                        description.getMethodName());
+                mState.sendFullStatusReport(getInstrumentation(), description.getMethodName());
             }
         };
     }
 }
-
diff --git a/api/current.txt b/api/current.txt
index d9fbe4b..a7b38a5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5808,8 +5808,9 @@
     method public boolean areNotificationsPaused();
     method public boolean canNotifyAsPackage(@NonNull String);
     method public void cancel(int);
-    method public void cancel(String, int);
+    method public void cancel(@Nullable String, int);
     method public void cancelAll();
+    method public void cancelAsPackage(@NonNull String, @Nullable String, int);
     method public void createNotificationChannel(@NonNull android.app.NotificationChannel);
     method public void createNotificationChannelGroup(@NonNull android.app.NotificationChannelGroup);
     method public void createNotificationChannelGroups(@NonNull java.util.List<android.app.NotificationChannelGroup>);
@@ -5831,7 +5832,7 @@
     method public boolean isNotificationPolicyAccessGranted();
     method public void notify(int, android.app.Notification);
     method public void notify(String, int, android.app.Notification);
-    method public void notifyAsPackage(@NonNull String, @NonNull String, int, @NonNull android.app.Notification);
+    method public void notifyAsPackage(@NonNull String, @Nullable String, int, @NonNull android.app.Notification);
     method public boolean removeAutomaticZenRule(String);
     method public void setAutomaticZenRuleState(@NonNull String, @NonNull android.service.notification.Condition);
     method public final void setInterruptionFilter(int);
@@ -5841,12 +5842,19 @@
     method public boolean updateAutomaticZenRule(String, android.app.AutomaticZenRule);
     field public static final String ACTION_APP_BLOCK_STATE_CHANGED = "android.app.action.APP_BLOCK_STATE_CHANGED";
     field public static final String ACTION_AUTOMATIC_ZEN_RULE = "android.app.action.AUTOMATIC_ZEN_RULE";
+    field public static final String ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED = "android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED";
     field public static final String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
     field public static final String ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED = "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED";
     field public static final String ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED = "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
     field public static final String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
     field public static final String ACTION_NOTIFICATION_POLICY_CHANGED = "android.app.action.NOTIFICATION_POLICY_CHANGED";
+    field public static final int AUTOMATIC_RULE_STATUS_DISABLED = 2; // 0x2
+    field public static final int AUTOMATIC_RULE_STATUS_ENABLED = 1; // 0x1
+    field public static final int AUTOMATIC_RULE_STATUS_REMOVED = 3; // 0x3
+    field public static final int AUTOMATIC_RULE_STATUS_UNKNOWN = -1; // 0xffffffff
     field public static final String EXTRA_AUTOMATIC_RULE_ID = "android.app.extra.AUTOMATIC_RULE_ID";
+    field public static final String EXTRA_AUTOMATIC_ZEN_RULE_ID = "android.app.extra.AUTOMATIC_ZEN_RULE_ID";
+    field public static final String EXTRA_AUTOMATIC_ZEN_RULE_STATUS = "android.app.extra.AUTOMATIC_ZEN_RULE_STATUS";
     field public static final String EXTRA_BLOCKED_STATE = "android.app.extra.BLOCKED_STATE";
     field public static final String EXTRA_NOTIFICATION_CHANNEL_GROUP_ID = "android.app.extra.NOTIFICATION_CHANNEL_GROUP_ID";
     field public static final String EXTRA_NOTIFICATION_CHANNEL_ID = "android.app.extra.NOTIFICATION_CHANNEL_ID";
@@ -9809,6 +9817,7 @@
     field public static final int BIND_IMPORTANT = 64; // 0x40
     field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000
     field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
+    field public static final int BIND_NOT_PERCEPTIBLE = 256; // 0x100
     field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
     field public static final String BIOMETRIC_SERVICE = "biometric";
     field public static final String BLUETOOTH_SERVICE = "bluetooth";
@@ -10825,7 +10834,9 @@
     method @Nullable public String getString(String, @Nullable String);
     method @Nullable public java.util.Set<java.lang.String> getStringSet(String, @Nullable java.util.Set<java.lang.String>);
     method public void registerOnSharedPreferenceChangeListener(android.content.SharedPreferences.OnSharedPreferenceChangeListener);
+    method public default void registerOnSharedPreferencesClearListener(@NonNull android.content.SharedPreferences.OnSharedPreferencesClearListener);
     method public void unregisterOnSharedPreferenceChangeListener(android.content.SharedPreferences.OnSharedPreferenceChangeListener);
+    method public default void unregisterOnSharedPreferencesClearListener(@NonNull android.content.SharedPreferences.OnSharedPreferencesClearListener);
   }
 
   public static interface SharedPreferences.Editor {
@@ -10845,6 +10856,10 @@
     method public void onSharedPreferenceChanged(android.content.SharedPreferences, String);
   }
 
+  public static interface SharedPreferences.OnSharedPreferencesClearListener {
+    method public void onSharedPreferencesClear(@NonNull android.content.SharedPreferences, @NonNull java.util.Set<java.lang.String>);
+  }
+
   public class SyncAdapterType implements android.os.Parcelable {
     ctor public SyncAdapterType(String, String, boolean, boolean);
     ctor public SyncAdapterType(android.os.Parcel);
@@ -13114,8 +13129,11 @@
     method @Nullable public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
     method @Nullable public java.util.Map<java.lang.String,java.lang.String> getProjectionMap();
     method @Nullable public String getTables();
+    method public long insert(@NonNull android.database.sqlite.SQLiteDatabase, @NonNull android.content.ContentValues);
     method public boolean isDistinct();
     method public boolean isStrict();
+    method public boolean isStrictColumns();
+    method public boolean isStrictGrammar();
     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);
@@ -13123,6 +13141,8 @@
     method public void setDistinct(boolean);
     method public void setProjectionMap(@Nullable java.util.Map<java.lang.String,java.lang.String>);
     method public void setStrict(boolean);
+    method public void setStrictColumns(boolean);
+    method public void setStrictGrammar(boolean);
     method public void setTables(@Nullable String);
     method public int update(@NonNull android.database.sqlite.SQLiteDatabase, @NonNull android.content.ContentValues, @Nullable String, @Nullable String[]);
   }
@@ -14804,6 +14824,7 @@
     ctor public PointF();
     ctor public PointF(float, float);
     ctor public PointF(@NonNull android.graphics.Point);
+    ctor public PointF(@NonNull android.graphics.PointF);
     method public int describeContents();
     method public final boolean equals(float, float);
     method public final float length();
@@ -23975,6 +23996,7 @@
     field public static final String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal";
     field public static final String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
     field public static final String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
+    field public static final String TAG_THUMBNAIL_ORIENTATION = "ThumbnailOrientation";
     field public static final String TAG_TRANSFER_FUNCTION = "TransferFunction";
     field public static final String TAG_USER_COMMENT = "UserComment";
     field public static final String TAG_WHITE_BALANCE = "WhiteBalance";
@@ -38634,6 +38656,7 @@
     field public static final String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
     field public static final String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
     field public static final String ACTION_CHANNEL_NOTIFICATION_SETTINGS = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
+    field public static final String ACTION_CONDITION_PROVIDER_SETTINGS = "android.settings.ACTION_CONDITION_PROVIDER_SETTINGS";
     field public static final String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
     field public static final String ACTION_DATA_USAGE_SETTINGS = "android.settings.DATA_USAGE_SETTINGS";
     field public static final String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
@@ -41041,6 +41064,7 @@
     method public int getType();
     field public static final int TYPE_AUTHENTICATION_SELECTED = 2; // 0x2
     field public static final int TYPE_CONTEXT_COMMITTED = 4; // 0x4
+    field public static final int TYPE_DATASETS_SHOWN = 5; // 0x5
     field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
     field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
     field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
@@ -47848,6 +47872,7 @@
     field public static final int DENSITY_400 = 400; // 0x190
     field public static final int DENSITY_420 = 420; // 0x1a4
     field public static final int DENSITY_440 = 440; // 0x1b8
+    field public static final int DENSITY_450 = 450; // 0x1c2
     field public static final int DENSITY_560 = 560; // 0x230
     field public static final int DENSITY_600 = 600; // 0x258
     field public static final int DENSITY_DEFAULT = 160; // 0xa0
@@ -49938,10 +49963,11 @@
     method @NonNull public android.view.SurfaceControl.Builder setParent(@Nullable android.view.SurfaceControl);
   }
 
-  public static class SurfaceControl.Transaction implements java.io.Closeable {
+  public static class SurfaceControl.Transaction implements java.io.Closeable android.os.Parcelable {
     ctor public SurfaceControl.Transaction();
     method public void apply();
     method public void close();
+    method public int describeContents();
     method @NonNull public android.view.SurfaceControl.Transaction merge(@NonNull android.view.SurfaceControl.Transaction);
     method @NonNull public android.view.SurfaceControl.Transaction reparent(@NonNull android.view.SurfaceControl, @Nullable android.view.SurfaceControl);
     method @NonNull public android.view.SurfaceControl.Transaction setAlpha(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0, to=1.0) float);
@@ -49949,6 +49975,8 @@
     method @NonNull public android.view.SurfaceControl.Transaction setGeometry(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, int);
     method @NonNull public android.view.SurfaceControl.Transaction setLayer(@NonNull android.view.SurfaceControl, @IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) int);
     method @NonNull public android.view.SurfaceControl.Transaction setVisibility(@NonNull android.view.SurfaceControl, boolean);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.view.SurfaceControl.Transaction> CREATOR;
   }
 
   public interface SurfaceHolder {
@@ -52415,9 +52443,11 @@
     method public void getBoundsInScreen(android.graphics.Rect);
     method public android.view.accessibility.AccessibilityWindowInfo getChild(int);
     method public int getChildCount();
+    method public int getDisplayId();
     method public int getId();
     method public int getLayer();
     method public android.view.accessibility.AccessibilityWindowInfo getParent();
+    method public void getRegionInScreen(@NonNull android.graphics.Region);
     method public android.view.accessibility.AccessibilityNodeInfo getRoot();
     method @Nullable public CharSequence getTitle();
     method public int getType();
diff --git a/api/removed.txt b/api/removed.txt
index 7713070..b075f9e 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -1,11 +1,6 @@
 // Signature format: 2.0
 package android.app {
 
-  public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
-    method @Deprecated public boolean enterPictureInPictureMode(@NonNull android.app.PictureInPictureArgs);
-    method @Deprecated public void setPictureInPictureArgs(@NonNull android.app.PictureInPictureArgs);
-  }
-
   public class ActivityManager {
     method @Deprecated public static int getMaxNumPictureInPictureActions();
   }
@@ -26,51 +21,6 @@
     method @Deprecated public android.app.Notification.Builder setTimeout(long);
   }
 
-  @Deprecated public final class PictureInPictureArgs implements android.os.Parcelable {
-    method public static android.app.PictureInPictureArgs convert(android.app.PictureInPictureParams);
-    method public static android.app.PictureInPictureParams convert(android.app.PictureInPictureArgs);
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int CONTENTS_FILE_DESCRIPTOR = 1; // 0x1
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.PictureInPictureArgs> CREATOR;
-    field public static final int PARCELABLE_WRITE_RETURN_VALUE = 1; // 0x1
-  }
-
-  public static class PictureInPictureArgs.Builder {
-    ctor public PictureInPictureArgs.Builder();
-    method public android.app.PictureInPictureArgs build();
-    method public android.app.PictureInPictureArgs.Builder setActions(java.util.List<android.app.RemoteAction>);
-    method public android.app.PictureInPictureArgs.Builder setAspectRatio(android.util.Rational);
-    method public android.app.PictureInPictureArgs.Builder setSourceRectHint(android.graphics.Rect);
-  }
-
-}
-
-package android.app.admin {
-
-  public class DevicePolicyManager {
-    method @Deprecated @Nullable public android.os.UserHandle createAndInitializeUser(@NonNull android.content.ComponentName, String, String, @NonNull android.content.ComponentName, android.os.Bundle);
-    method @Deprecated @Nullable public android.os.UserHandle createUser(@NonNull android.content.ComponentName, String);
-  }
-
-}
-
-package android.app.job {
-
-  public class JobInfo implements android.os.Parcelable {
-    method @Deprecated public long getEstimatedNetworkBytes();
-  }
-
-  public static final class JobInfo.Builder {
-    method @Deprecated public android.app.job.JobInfo.Builder setEstimatedNetworkBytes(long);
-    method @Deprecated public android.app.job.JobInfo.Builder setIsPrefetch(boolean);
-  }
-
-  public final class JobWorkItem implements android.os.Parcelable {
-    ctor @Deprecated public JobWorkItem(android.content.Intent, long);
-    method @Deprecated public long getEstimatedNetworkBytes();
-  }
-
 }
 
 package android.app.slice {
@@ -123,10 +73,6 @@
 
 package android.content {
 
-  public class ClipData implements android.os.Parcelable {
-    method @Deprecated public void addItem(android.content.ClipData.Item, android.content.ContentResolver);
-  }
-
   public abstract class Context {
     method public abstract android.content.SharedPreferences getSharedPreferences(java.io.File, int);
     method public abstract java.io.File getSharedPreferencesPath(String);
@@ -145,14 +91,6 @@
 
 package android.content.pm {
 
-  public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
-    field @Deprecated public String volumeUuid;
-  }
-
-  public class ComponentInfo extends android.content.pm.PackageItemInfo {
-    field @Deprecated public boolean encryptionAware;
-  }
-
   public class PackageInfo implements android.os.Parcelable {
     field public static final int REQUESTED_PERMISSION_REQUIRED = 1; // 0x1
   }
@@ -161,10 +99,6 @@
     method public abstract boolean setInstantAppCookie(@Nullable byte[]);
   }
 
-  public class ResolveInfo implements android.os.Parcelable {
-    field @Deprecated public boolean instantAppAvailable;
-  }
-
   public final class SharedLibraryInfo implements android.os.Parcelable {
     method public boolean isBuiltin();
     method public boolean isDynamic();
@@ -265,19 +199,10 @@
 
 package android.hardware {
 
-  public final class HardwareBuffer implements java.lang.AutoCloseable android.os.Parcelable {
-    method @Deprecated public void destroy();
-    method @Deprecated public boolean isDestroyed();
-  }
-
   public final class SensorDirectChannel implements java.nio.channels.Channel {
     method @Deprecated public boolean isValid();
   }
 
-  public abstract class SensorManager {
-    method @Deprecated public int configureDirectChannel(android.hardware.SensorDirectChannel, android.hardware.Sensor, int);
-  }
-
 }
 
 package android.icu.util {
@@ -375,7 +300,6 @@
   public final class SystemClock {
     method @NonNull public static java.time.Clock elapsedRealtimeClock();
     method @NonNull public static java.time.Clock uptimeClock();
-    method @Deprecated @NonNull public static java.time.Clock uptimeMillisClock();
   }
 
   public class TestLooperManager {
diff --git a/api/system-current.txt b/api/system-current.txt
index ce7df5e..eef6b3f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3693,8 +3693,18 @@
 package android.media.session {
 
   public final class MediaSessionManager {
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void registerCallback(@NonNull android.media.session.MediaSessionManager.Callback, @Nullable android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.SET_MEDIA_KEY_LISTENER) public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, @Nullable android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER) public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, @Nullable android.os.Handler);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void unregisterCallback(@NonNull android.media.session.MediaSessionManager.Callback);
+  }
+
+  public abstract static class MediaSessionManager.Callback {
+    ctor public MediaSessionManager.Callback();
+    method public abstract void onAddressedPlayerChanged(android.media.session.MediaSession.Token);
+    method public abstract void onAddressedPlayerChanged(android.content.ComponentName);
+    method public abstract void onMediaKeyEventDispatched(android.view.KeyEvent, android.media.session.MediaSession.Token);
+    method public abstract void onMediaKeyEventDispatched(android.view.KeyEvent, android.content.ComponentName);
   }
 
   public static interface MediaSessionManager.OnMediaKeyListener {
@@ -5169,7 +5179,8 @@
     method @NonNull public static java.io.File getOdmDirectory();
     method @NonNull public static java.io.File getOemDirectory();
     method @NonNull public static java.io.File getProductDirectory();
-    method @NonNull public static java.io.File getProductServicesDirectory();
+    method @Deprecated @NonNull public static java.io.File getProductServicesDirectory();
+    method @NonNull public static java.io.File getSystemExtDirectory();
     method @NonNull public static java.io.File getVendorDirectory();
   }
 
@@ -5473,6 +5484,7 @@
   public class UpdateEngine {
     ctor public UpdateEngine();
     method public void applyPayload(String, long, long, String[]);
+    method public void applyPayload(java.io.FileDescriptor, long, long, String[]);
     method public boolean bind(android.os.UpdateEngineCallback, android.os.Handler);
     method public boolean bind(android.os.UpdateEngineCallback);
     method public void cancel();
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 5802f6c..07b8969 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -23,15 +23,6 @@
 
 }
 
-package android.app.admin {
-
-  public class DevicePolicyManager {
-    method @Deprecated @Nullable public String getDeviceInitializerApp();
-    method @Deprecated @Nullable public android.content.ComponentName getDeviceInitializerComponent();
-  }
-
-}
-
 package android.app.backup {
 
   public class RestoreSession {
@@ -151,24 +142,6 @@
     field public static final boolean PERMISSIONS_REVIEW_REQUIRED = true;
   }
 
-  public final class PowerManager {
-    method @Deprecated public boolean isScreenBrightnessBoosted();
-    field @Deprecated public static final String ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED = "android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED";
-  }
-
-}
-
-package android.provider {
-
-  public final class DeviceConfig {
-    method @RequiresPermission(android.Manifest.permission.READ_DEVICE_CONFIG) public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
-    method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
-  }
-
-  public static interface DeviceConfig.OnPropertyChangedListener {
-    method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String);
-  }
-
 }
 
 package android.service.notification {
diff --git a/api/test-current.txt b/api/test-current.txt
index 11e0479..b393fcc 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -54,6 +54,7 @@
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getPackageImportance(String);
     method public long getTotalRam();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public int getUidImportance(int);
+    method public static boolean isHighEndGfx();
     method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
     method public static void resumeAppSwitches() throws android.os.RemoteException;
     method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
@@ -318,10 +319,16 @@
   }
 
   public final class NotificationChannel implements android.os.Parcelable {
+    method public int getOriginalImportance();
+    method public boolean isBlockableSystem();
     method public boolean isImportanceLockedByCriticalDeviceFunction();
     method public boolean isImportanceLockedByOEM();
+    method public void setBlockableSystem(boolean);
+    method public void setDeleted(boolean);
+    method public void setFgServiceShown(boolean);
     method public void setImportanceLockedByCriticalDeviceFunction(boolean);
     method public void setImportanceLockedByOEM(boolean);
+    method public void setOriginalImportance(int);
   }
 
   public final class NotificationChannelGroup implements android.os.Parcelable {
@@ -646,6 +653,7 @@
     method public void setContentCaptureOptions(@Nullable android.content.ContentCaptureOptions);
     field public static final String BUGREPORT_SERVICE = "bugreport";
     field public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "content_capture";
+    field public static final String PERMISSION_SERVICE = "permission";
     field public static final String ROLLBACK_SERVICE = "rollback";
     field public static final String STATUS_BAR_SERVICE = "statusbar";
     field public static final String TEST_NETWORK_SERVICE = "test_network";
@@ -689,10 +697,12 @@
     method public void setEnableRollback(boolean);
     method @RequiresPermission("android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS") public void setGrantedRuntimePermissions(String[]);
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
+    method public void setRequestDowngrade(boolean);
     method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
   }
 
   public abstract class PackageManager {
+    method @RequiresPermission("android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void addOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
     method public abstract boolean arePermissionsIndividuallyControlled();
     method @Nullable @RequiresPermission("android.permission.INTERACT_ACROSS_USERS_FULL") public abstract String getDefaultBrowserPackageNameAsUser(int);
     method @Nullable public String getIncidentReportApproverPackageName();
@@ -706,6 +716,7 @@
     method @NonNull public abstract String getSharedSystemSharedLibraryPackageName();
     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.OBSERVE_GRANT_REVOKE_PERMISSIONS") public abstract void removeOnPermissionsChangeListener(@NonNull android.content.pm.PackageManager.OnPermissionsChangedListener);
     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(@NonNull String, @NonNull String, int, int, @NonNull android.os.UserHandle);
     field public static final String FEATURE_ADOPTABLE_STORAGE = "android.software.adoptable_storage";
@@ -728,6 +739,10 @@
     field public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared";
   }
 
+  public static interface PackageManager.OnPermissionsChangedListener {
+    method public void onPermissionsChanged(int);
+  }
+
   public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
     field public static final int FLAG_REMOVED = 2; // 0x2
     field public static final int PROTECTION_FLAG_APP_PREDICTOR = 2097152; // 0x200000
@@ -788,6 +803,7 @@
   }
 
   public final class RollbackManager {
+    method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void blockRollbackManager(long);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender);
     method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void expireRollbackForPackage(@NonNull String);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
@@ -2215,6 +2231,18 @@
     method public abstract void onRevokeRuntimePermissions(@NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>);
   }
 
+  public final class PermissionManager {
+    method @IntRange(from=0) @RequiresPermission("android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY") public int getRuntimePermissionsVersion();
+    method @NonNull public java.util.List<android.permission.PermissionManager.SplitPermissionInfo> getSplitPermissions();
+    method @RequiresPermission("android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY") public void setRuntimePermissionsVersion(@IntRange(from=0) int);
+  }
+
+  public static final class PermissionManager.SplitPermissionInfo {
+    method @NonNull public java.util.List<java.lang.String> getNewPermissions();
+    method @NonNull public String getSplitPermission();
+    method public int getTargetSdk();
+  }
+
   public final class RuntimePermissionPresentationInfo implements android.os.Parcelable {
     ctor public RuntimePermissionPresentationInfo(@NonNull CharSequence, boolean, boolean);
     method public int describeContents();
@@ -2282,6 +2310,7 @@
     field public static final String NAMESPACE_PRIVACY = "privacy";
     field public static final String NAMESPACE_ROLLBACK = "rollback";
     field public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";
+    field public static final String NAMESPACE_WINDOW_MANAGER = "android:window_manager";
   }
 
   public static interface DeviceConfig.OnPropertiesChangedListener {
@@ -2298,6 +2327,11 @@
     method @Nullable public String getString(@NonNull String, @Nullable String);
   }
 
+  public static interface DeviceConfig.WindowManager {
+    field public static final String KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE = "system_gestures_excluded_by_pre_q_sticky_immersive";
+    field public static final String KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP = "system_gesture_exclusion_limit_dp";
+  }
+
   public final class MediaStore {
     method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static void deleteContributedMedia(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
     method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
diff --git a/api/test-removed.txt b/api/test-removed.txt
index ef0aac7..e47f6ed 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -8,16 +8,3 @@
 
 }
 
-package android.provider {
-
-  public final class DeviceConfig {
-    method @RequiresPermission("android.permission.READ_DEVICE_CONFIG") public static void addOnPropertyChangedListener(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
-    method public static void removeOnPropertyChangedListener(@NonNull android.provider.DeviceConfig.OnPropertyChangedListener);
-  }
-
-  public static interface DeviceConfig.OnPropertyChangedListener {
-    method public void onPropertyChanged(@NonNull String, @NonNull String, @Nullable String);
-  }
-
-}
-
diff --git a/cmds/am/Android.bp b/cmds/am/Android.bp
index bb16df1..ed73d55 100644
--- a/cmds/am/Android.bp
+++ b/cmds/am/Android.bp
@@ -10,3 +10,16 @@
         export_proto_headers: true,
     },
 }
+
+java_binary {
+    name: "am",
+    wrapper: "am",
+    srcs: [
+        "src/**/*.java",
+        "proto/**/*.proto",
+    ],
+    proto: {
+        plugin: "javastream",
+    },
+    static_libs: ["libprotobuf-java-lite"],
+}
diff --git a/cmds/am/Android.mk b/cmds/am/Android.mk
deleted file mode 100644
index 9411c32..0000000
--- a/cmds/am/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src) \
-    $(call all-proto-files-under, proto)
-LOCAL_MODULE := am
-LOCAL_PROTOC_OPTIMIZE_TYPE := stream
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := am
-LOCAL_SRC_FILES := am
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp
new file mode 100644
index 0000000..f925023
--- /dev/null
+++ b/cmds/app_process/Android.bp
@@ -0,0 +1,64 @@
+cc_binary {
+    name: "app_process",
+
+    srcs: ["app_main.cpp"],
+
+    multilib: {
+        lib32: {
+            version_script: ":art_sigchain_version_script32.txt",
+            suffix: "32",
+        },
+        lib64: {
+            version_script: ":art_sigchain_version_script64.txt",
+            suffix: "64",
+        },
+    },
+
+    ldflags: ["-Wl,--export-dynamic"],
+
+    shared_libs: [
+        "libandroid_runtime",
+        "libbinder",
+        "libcutils",
+        "libdl",
+        "libhidlbase",
+        "libhwbinder",
+        "liblog",
+        "libnativeloader",
+        "libutils",
+
+        // This is a list of libraries that need to be included in order to avoid
+        // bad apps. This prevents a library from having a mismatch when resolving
+        // new/delete from an app shared library.
+        // See b/21032018 for more details.
+        "libwilhelm",
+    ],
+
+    whole_static_libs: ["libsigchain"],
+
+    compile_multilib: "both",
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wunused",
+        "-Wunreachable-code",
+    ],
+
+    // If SANITIZE_LITE is revived this will need:
+    //product_variables: {
+    //    sanitize_lite: {
+    //        // In SANITIZE_LITE mode, we create the sanitized binary in a separate location (but reuse
+    //        // the same module). Using the same module also works around an issue with make: binaries
+    //        // that depend on sanitized libraries will be relinked, even if they set LOCAL_SANITIZE := never.
+    //        //
+    //        // Also pull in the asanwrapper helper.
+    //        relative_install_path: "asan",
+    //        required: ["asanwrapper"],
+    //    },
+    //},
+
+    // Create a symlink from app_process to app_process32 or 64
+    // depending on the target configuration.
+    symlink_preferred_arch: true,
+}
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
deleted file mode 100644
index 72fe051..0000000
--- a/cmds/app_process/Android.mk
+++ /dev/null
@@ -1,68 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-app_process_common_shared_libs := \
-    libandroid_runtime \
-    libbinder \
-    libcutils \
-    libdl \
-    libhwbinder \
-    liblog \
-    libnativeloader \
-    libutils \
-
-# This is a list of libraries that need to be included in order to avoid
-# bad apps. This prevents a library from having a mismatch when resolving
-# new/delete from an app shared library.
-# See b/21032018 for more details.
-app_process_common_shared_libs += \
-    libwilhelm \
-
-app_process_common_static_libs := \
-    libsigchain \
-
-app_process_src_files := \
-    app_main.cpp \
-
-app_process_cflags := \
-    -Wall -Werror -Wunused -Wunreachable-code
-
-app_process_ldflags_32 := \
-    -Wl,--version-script,art/sigchainlib/version-script32.txt -Wl,--export-dynamic
-app_process_ldflags_64 := \
-    -Wl,--version-script,art/sigchainlib/version-script64.txt -Wl,--export-dynamic
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= $(app_process_src_files)
-
-LOCAL_LDFLAGS_32 := $(app_process_ldflags_32)
-LOCAL_LDFLAGS_64 := $(app_process_ldflags_64)
-
-LOCAL_SHARED_LIBRARIES := $(app_process_common_shared_libs)
-
-LOCAL_WHOLE_STATIC_LIBRARIES := $(app_process_common_static_libs)
-
-LOCAL_MODULE:= app_process
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := app_process32
-LOCAL_MODULE_STEM_64 := app_process64
-
-LOCAL_CFLAGS += $(app_process_cflags)
-
-# In SANITIZE_LITE mode, we create the sanitized binary in a separate location (but reuse
-# the same module). Using the same module also works around an issue with make: binaries
-# that depend on sanitized libraries will be relinked, even if they set LOCAL_SANITIZE := never.
-#
-# Also pull in the asanwrapper helper.
-ifeq ($(SANITIZE_LITE),true)
-LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan
-LOCAL_REQUIRED_MODULES := asanwrapper
-endif
-
-include $(BUILD_EXECUTABLE)
-
-# Create a symlink from app_process to app_process32 or 64
-# depending on the target configuration.
-ifneq ($(SANITIZE_LITE),true)
-include  $(BUILD_SYSTEM)/executable_prefer_symlink.mk
-endif
diff --git a/cmds/appops/Android.bp b/cmds/appops/Android.bp
new file mode 100644
index 0000000..9f330fa
--- /dev/null
+++ b/cmds/appops/Android.bp
@@ -0,0 +1,6 @@
+// Copyright 2014 The Android Open Source Project
+
+sh_binary {
+    name: "appops",
+    src: "appops",
+}
diff --git a/cmds/appops/Android.mk b/cmds/appops/Android.mk
deleted file mode 100644
index 6801ce9..0000000
--- a/cmds/appops/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2014 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := appops
-LOCAL_SRC_FILES := appops
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/appwidget/Android.bp b/cmds/appwidget/Android.bp
new file mode 100644
index 0000000..487d3e1
--- /dev/null
+++ b/cmds/appwidget/Android.bp
@@ -0,0 +1,7 @@
+// Copyright 2014 The Android Open Source Project
+
+java_binary {
+    name: "appwidget",
+    wrapper: "appwidget",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/appwidget/Android.mk b/cmds/appwidget/Android.mk
deleted file mode 100644
index 1fb258d..0000000
--- a/cmds/appwidget/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2014 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := appwidget
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := appwidget
-LOCAL_SRC_FILES := appwidget
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-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 680ccfc..76b905d 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -64,6 +64,10 @@
 
     private static final String BMGR_NOT_RUNNING_ERR =
             "Error: Could not access the Backup Manager.  Is the system running?";
+    private static final String BMGR_NOT_ACTIVATED_FOR_USER =
+            "Error: Backup Manager is not activated for user ";
+    private static final String BMGR_ERR_NO_RESTORESESSION_FOR_USER =
+            "Error: Could not get restore session for user ";
     private static final String TRANSPORT_NOT_RUNNING_ERR =
             "Error: Could not access the backup transport.  Is the system running?";
     private static final String PM_NOT_RUNNING_ERR =
@@ -190,15 +194,19 @@
         showUsage();
     }
 
-    boolean isBackupActive(@UserIdInt int userId) {
+    private void handleRemoteException(RemoteException e) {
+        System.err.println(e.toString());
+        System.err.println(BMGR_NOT_RUNNING_ERR);
+    }
+
+    private boolean isBackupActive(@UserIdInt int userId) {
         try {
             if (!mBmgr.isBackupServiceActive(userId)) {
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                System.err.println(BMGR_NOT_ACTIVATED_FOR_USER + userId);
                 return false;
             }
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
             return false;
         }
 
@@ -214,8 +222,7 @@
             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);
+            handleRemoteException(e);
         }
 
     }
@@ -230,8 +237,7 @@
             System.out.println("Backup Manager currently "
                     + enableToString(isEnabled));
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -250,8 +256,7 @@
             showUsage();
             return;
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -259,8 +264,7 @@
         try {
             mBmgr.backupNowForUser(userId);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -274,8 +278,7 @@
         try {
             mBmgr.dataChangedForUser(userId, pkg);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -292,8 +295,7 @@
                 mBmgr.fullTransportBackupForUser(
                         userId, allPkgs.toArray(new String[allPkgs.size()]));
             } catch (RemoteException e) {
-                System.err.println(e.toString());
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                handleRemoteException(e);
             }
         }
     }
@@ -421,8 +423,7 @@
             try {
                 filteredPackages = mBmgr.filterAppsEligibleForBackupForUser(userId, packages);
             } catch (RemoteException e) {
-                System.err.println(e.toString());
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                handleRemoteException(e);
             }
             backupNowPackages(userId, Arrays.asList(filteredPackages), nonIncrementalBackup,
                     monitorState);
@@ -455,8 +456,7 @@
                 System.err.println("Unable to run backup");
             }
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -506,8 +506,7 @@
             try {
                 mBmgr.cancelBackupsForUser(userId);
             } catch (RemoteException e) {
-                System.err.println(e.toString());
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                handleRemoteException(e);
             }
             return;
         }
@@ -537,8 +536,7 @@
             }
 
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -569,8 +567,7 @@
                         }
                     });
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
             return;
         }
 
@@ -598,8 +595,7 @@
             mBmgr.clearBackupDataForUser(userId, transport, pkg);
             System.out.println("Wiped backup data for " + pkg + " on " + transport);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -632,8 +628,7 @@
             observer.waitForCompletion(30*1000L);
             System.out.println("Initialization result: " + observer.result);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -648,7 +643,7 @@
         try {
             mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null);
             if (mRestore == null) {
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                System.err.println(BMGR_ERR_NO_RESTORESESSION_FOR_USER + userId);
                 return;
             }
 
@@ -658,8 +653,7 @@
 
             mRestore.endRestoreSession();
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -686,8 +680,7 @@
                 System.out.println(pad + t);
             }
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -805,7 +798,7 @@
             boolean didRestore = false;
             mRestore = mBmgr.beginRestoreSessionForUser(userId, null, null);
             if (mRestore == null) {
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+                System.err.println(BMGR_ERR_NO_RESTORESESSION_FOR_USER + userId);
                 return;
             }
             RestoreSet[] sets = null;
@@ -851,8 +844,7 @@
 
             System.out.println("done");
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -865,8 +857,7 @@
                 }
             }
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
@@ -886,8 +877,7 @@
                             + " for user "
                             + userId);
         } catch (RemoteException e) {
-            System.err.println(e.toString());
-            System.err.println(BMGR_NOT_RUNNING_ERR);
+            handleRemoteException(e);
         }
     }
 
diff --git a/cmds/bootanimation/Android.bp b/cmds/bootanimation/Android.bp
index 31bd612..c1f8654 100644
--- a/cmds/bootanimation/Android.bp
+++ b/cmds/bootanimation/Android.bp
@@ -79,7 +79,6 @@
         "libEGL",
         "libGLESv1_CM",
         "libgui",
-        "libtinyalsa",
     ],
 
     product_variables: {
diff --git a/cmds/bu/Android.bp b/cmds/bu/Android.bp
new file mode 100644
index 0000000..0866ee0
--- /dev/null
+++ b/cmds/bu/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2011 The Android Open Source Project
+//
+
+java_binary {
+    name: "bu",
+    wrapper: "bu",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/bu/Android.mk b/cmds/bu/Android.mk
deleted file mode 100644
index 4fd5fec..0000000
--- a/cmds/bu/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2011 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := bu
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := bu
-LOCAL_SRC_FILES := bu
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
-
-
diff --git a/cmds/content/Android.bp b/cmds/content/Android.bp
new file mode 100644
index 0000000..96d1469
--- /dev/null
+++ b/cmds/content/Android.bp
@@ -0,0 +1,7 @@
+// Copyright 2012 The Android Open Source Project
+
+java_binary {
+    name: "content",
+    wrapper: "content",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/content/Android.mk b/cmds/content/Android.mk
deleted file mode 100644
index 9302e2f..0000000
--- a/cmds/content/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2012 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := content
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := content
-LOCAL_SRC_FILES := content
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/dpm/Android.bp b/cmds/dpm/Android.bp
new file mode 100644
index 0000000..753121e
--- /dev/null
+++ b/cmds/dpm/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2014 The Android Open Source Project
+//
+
+java_binary {
+    name: "dpm",
+    wrapper: "dpm",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/dpm/Android.mk b/cmds/dpm/Android.mk
deleted file mode 100644
index 9f5aee4..0000000
--- a/cmds/dpm/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := dpm
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := dpm
-LOCAL_SRC_FILES := dpm
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/hid/Android.bp b/cmds/hid/Android.bp
index 2b7963a..54c8bf3 100644
--- a/cmds/hid/Android.bp
+++ b/cmds/hid/Android.bp
@@ -1 +1,9 @@
-subdirs = ["jni"]
+// Copyright 2015 The Android Open Source Project
+//
+
+java_binary {
+    name: "hid",
+    wrapper: "hid",
+    srcs: ["**/*.java"],
+    required: ["libhidcommand_jni"],
+}
diff --git a/cmds/hid/Android.mk b/cmds/hid/Android.mk
deleted file mode 100644
index 574834d..0000000
--- a/cmds/hid/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2015 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := hid
-LOCAL_JNI_SHARED_LIBRARIES := libhidcommand_jni
-LOCAL_REQUIRED_MODULES := libhidcommand_jni
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := hid
-LOCAL_SRC_FILES := hid
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := EXECUTABLES
-include $(BUILD_PREBUILT)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 18d56fa..3bb9929 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -222,4 +222,5 @@
     srcs: [
         "idmap2d/aidl/android/os/IIdmap2.aidl",
     ],
+    path: "idmap2d/aidl",
 }
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index 83c034b..0b349e1 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -68,9 +68,13 @@
 };
 
 bool VendorIsQOrLater() {
-  // STOPSHIP(b/119390857): Check api version once Q sdk version is finalized
-  std::string version = android::base::GetProperty("ro.vndk.version", "Q");
-  return version == "Q" || version == "q";
+  constexpr int kQSdkVersion = 29;
+  constexpr int kBase = 10;
+  std::string version_prop = android::base::GetProperty("ro.vndk.version", "29");
+  int version = strtol(version_prop.data(), nullptr, kBase);
+
+  // If the string cannot be parsed, it is a development sdk codename.
+  return version >= kQSdkVersion || version == 0;
 }
 
 Result<std::unique_ptr<std::vector<std::string>>> FindApkFiles(const std::vector<std::string>& dirs,
@@ -99,6 +103,7 @@
       {"/oem/", kPolicyOem},
       {"/product/", kPolicyProduct},
       {"/system/", kPolicySystem},
+      {"/system_ext/", kPolicySystem},
       {"/vendor/", kPolicyVendor},
   };
 
diff --git a/cmds/ime/Android.bp b/cmds/ime/Android.bp
new file mode 100644
index 0000000..76a16c8
--- /dev/null
+++ b/cmds/ime/Android.bp
@@ -0,0 +1,7 @@
+// Copyright 2007 The Android Open Source Project
+//
+
+sh_binary {
+    name: "ime",
+    src: "ime",
+}
diff --git a/cmds/ime/Android.mk b/cmds/ime/Android.mk
deleted file mode 100644
index ca608e8..0000000
--- a/cmds/ime/Android.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ime
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_SRC_FILES := ime
-include $(BUILD_PREBUILT)
diff --git a/cmds/incident_helper/src/main.cpp b/cmds/incident_helper/src/main.cpp
index 809a771..ff5fd86 100644
--- a/cmds/incident_helper/src/main.cpp
+++ b/cmds/incident_helper/src/main.cpp
@@ -72,6 +72,8 @@
             return new PsParser();
         case 2006:
             return new BatteryTypeParser();
+        case 3026: // system_trace is already a serialized protobuf
+            return new NoopParser();
         default:
             // Return no op parser when no specific ones are implemented.
             return new NoopParser();
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index a8b99ce..a527263 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -564,7 +564,8 @@
     int skipped[] = SKIPPED_SECTIONS;
     for (const Section** section = SECTION_LIST; *section; section++) {
         const int id = (*section)->id;
-        if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)) {
+        if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)
+                && !section_requires_specific_mention(id)) {
             incidentArgs.addSection(id);
         }
     }
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 85c5a20..1572114 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -67,6 +67,8 @@
     switch (sectionId) {
         case 3025: // restricted_images
             return true;
+        case 3026: // system_trace
+            return true;
         default:
             return false;
     }
diff --git a/cmds/input/Android.bp b/cmds/input/Android.bp
new file mode 100644
index 0000000..a0ebde6
--- /dev/null
+++ b/cmds/input/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2008 The Android Open Source Project
+//
+
+java_binary {
+    name: "input",
+    wrapper: "input",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/input/Android.mk b/cmds/input/Android.mk
deleted file mode 100644
index 4e983e3..0000000
--- a/cmds/input/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2008 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := inputlib
-LOCAL_MODULE_STEM := input
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := input
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_SRC_FILES := input
-LOCAL_REQUIRED_MODULES := inputlib
-include $(BUILD_PREBUILT)
diff --git a/cmds/locksettings/Android.bp b/cmds/locksettings/Android.bp
new file mode 100644
index 0000000..59ccc5c
--- /dev/null
+++ b/cmds/locksettings/Android.bp
@@ -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.
+
+java_binary {
+    name: "locksettings",
+    wrapper: "locksettings",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/locksettings/Android.mk b/cmds/locksettings/Android.mk
deleted file mode 100644
index 76766c7..0000000
--- a/cmds/locksettings/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := locksettings
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := locksettings
-LOCAL_SRC_FILES := locksettings
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
-
-
diff --git a/cmds/pm/Android.bp b/cmds/pm/Android.bp
new file mode 100644
index 0000000..0644f6e
--- /dev/null
+++ b/cmds/pm/Android.bp
@@ -0,0 +1,7 @@
+// Copyright 2007 The Android Open Source Project
+//
+
+sh_binary {
+    name: "pm",
+    src: "pm",
+}
diff --git a/cmds/pm/Android.mk b/cmds/pm/Android.mk
deleted file mode 100644
index 960c805..0000000
--- a/cmds/pm/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := pm
-LOCAL_SRC_FILES := pm
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/requestsync/Android.bp b/cmds/requestsync/Android.bp
new file mode 100644
index 0000000..ef2a8a6
--- /dev/null
+++ b/cmds/requestsync/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2012 The Android Open Source Project
+//
+
+java_binary {
+    name: "requestsync",
+    wrapper: "requestsync",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/requestsync/Android.mk b/cmds/requestsync/Android.mk
deleted file mode 100644
index fe2ffd8..0000000
--- a/cmds/requestsync/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2012 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := requestsync
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := requestsync
-LOCAL_SRC_FILES := requestsync
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/settings/Android.bp b/cmds/settings/Android.bp
new file mode 100644
index 0000000..8a78e54
--- /dev/null
+++ b/cmds/settings/Android.bp
@@ -0,0 +1,7 @@
+// Copyright 2011 The Android Open Source Project
+//
+
+sh_binary {
+    name: "settings",
+    src: "settings",
+}
diff --git a/cmds/settings/Android.mk b/cmds/settings/Android.mk
deleted file mode 100644
index 8a8d1bb..0000000
--- a/cmds/settings/Android.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2011 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := settings
-LOCAL_SRC_FILES := settings
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
-
-
diff --git a/cmds/sm/Android.bp b/cmds/sm/Android.bp
new file mode 100644
index 0000000..11e4e72
--- /dev/null
+++ b/cmds/sm/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2015 The Android Open Source Project
+//
+
+java_binary {
+    name: "sm",
+    wrapper: "sm",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/sm/Android.mk b/cmds/sm/Android.mk
deleted file mode 100644
index 7cb1e12..0000000
--- a/cmds/sm/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2015 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := sm
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := sm
-LOCAL_SRC_FILES := sm
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index d59d0e2..6df0a8e 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -71,7 +71,6 @@
         "src/config/ConfigManager.cpp",
         "src/external/GpuStatsPuller.cpp",
         "src/external/Perfetto.cpp",
-        "src/external/Perfprofd.cpp",
         "src/external/StatsPuller.cpp",
         "src/external/StatsCallbackPuller.cpp",
         "src/external/StatsCompanionServicePuller.cpp",
@@ -109,8 +108,6 @@
         "src/socket/StatsSocketListener.cpp",
         "src/shell/ShellSubscriber.cpp",
         "src/shell/shell_config.proto",
-
-        ":perfprofd_aidl",
     ],
 
     local_include_dirs: [
@@ -263,6 +260,7 @@
         "tests/e2e/Anomaly_duration_sum_e2e_test.cpp",
         "tests/e2e/ConfigTtl_e2e_test.cpp",
         "tests/e2e/PartialBucket_e2e_test.cpp",
+        "tests/e2e/DurationMetric_e2e_test.cpp",
         "tests/shell/ShellSubscriber_test.cpp",
     ],
 
@@ -332,7 +330,7 @@
 // ====  java proto device library (for test only)  ==============================
 java_library {
     name: "statsdprotolite",
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     proto: {
         type: "lite",
         include_dirs: ["external/protobuf/src"],
diff --git a/cmds/statsd/OWNERS b/cmds/statsd/OWNERS
index 380e499..04464ce 100644
--- a/cmds/statsd/OWNERS
+++ b/cmds/statsd/OWNERS
@@ -3,5 +3,6 @@
 jtnguyen@google.com
 muhammadq@google.com
 singhtejinder@google.com
+tsaichristine@google.com
 yaochen@google.com
 yro@google.com
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
index 13f5c8a..1185127 100644
--- a/cmds/statsd/src/FieldValue.cpp
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -149,6 +149,18 @@
     return false;
 }
 
+bool isUidField(const Field& field, const Value& value) {
+    auto it = android::util::AtomsInfo::kAtomsWithUidField.find(field.getTag());
+
+    if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) {
+        int uidField = it->second;
+        return field.getDepth() == 0 && field.getPosAtDepth(0) == uidField &&
+               value.getType() == INT;
+    }
+
+    return false;
+}
+
 Value::Value(const Value& from) {
     type = from.getType();
     switch (type) {
@@ -464,4 +476,4 @@
 
 }  // namespace statsd
 }  // namespace os
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index 6729e05..0e033e0 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -392,6 +392,7 @@
 void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output);
 
 bool isAttributionUidField(const Field& field, const Value& value);
+bool isUidField(const Field& field, const Value& value);
 
 bool equalDimensions(const std::vector<Matcher>& dimension_a,
                      const std::vector<Matcher>& dimension_b);
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 4e0a8eb..ff7416c 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -269,6 +269,7 @@
         if (lastBroadcastTime != mLastActivationBroadcastTimes.end()) {
             if (currentTimestampNs - lastBroadcastTime->second <
                     StatsdStats::kMinActivationBroadcastPeriodNs) {
+                StatsdStats::getInstance().noteActivationBroadcastGuardrailHit(uid);
                 VLOG("StatsD would've sent an activation broadcast but the rate limit stopped us.");
                 return;
             }
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 92aa425..f0db1b0 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -272,7 +272,15 @@
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
+
+    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
+    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp
index 548a686..e09d575 100644
--- a/cmds/statsd/src/anomaly/subscriber_util.cpp
+++ b/cmds/statsd/src/anomaly/subscriber_util.cpp
@@ -22,7 +22,6 @@
 #include <binder/IServiceManager.h>
 
 #include "external/Perfetto.h"
-#include "external/Perfprofd.h"
 #include "subscriber/IncidentdReporter.h"
 #include "subscriber/SubscriberReporter.h"
 
@@ -64,12 +63,6 @@
                 SubscriberReporter::getInstance().alertBroadcastSubscriber(configKey, subscription,
                                                                            dimensionKey);
                 break;
-            case Subscription::SubscriberInformationCase::kPerfprofdDetails:
-                if (!CollectPerfprofdTraceAndUploadToDropbox(subscription.perfprofd_details(),
-                                                             ruleId, configKey)) {
-                    ALOGW("Failed to generate perfprofd traces.");
-                }
-                break;
             default:
                 break;
         }
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index adfebb3..ceabd39 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -303,10 +303,26 @@
         ContentCaptureSessionEvents content_capture_session_events = 208;
         ContentCaptureFlushed content_capture_flushed = 209;
         LocationManagerApiUsageReported location_manager_api_usage_reported = 210;
+        ReviewPermissionsFragmentResultReported review_permissions_fragment_result_reported =
+            211 [(log_from_module) = "permissioncontroller"];
+        RuntimePermissionsUpgradeResult runtime_permissions_upgrade_result =
+            212 [(log_from_module) = "permissioncontroller"];
+        GrantPermissionsActivityButtonActions grant_permissions_activity_button_actions =
+            213 [(log_from_module) = "permissioncontroller"];
+        LocationAccessCheckNotificationAction location_access_check_notification_action =
+            214 [(log_from_module) = "permissioncontroller"];
+        AppPermissionFragmentActionReported app_permission_fragment_action_reported =
+            215 [(log_from_module) = "permissioncontroller"];
+        AppPermissionFragmentViewed app_permission_fragment_viewed =
+            216 [(log_from_module) = "permissioncontroller"];
+        AppPermissionsFragmentViewed app_permissions_fragment_viewed =
+            217 [(log_from_module) = "permissioncontroller"];
+        PermissionAppsFragmentViewed permission_apps_fragment_viewed =
+            218  [(log_from_module) = "permissioncontroller"];
     }
 
     // Pulled events will start at field 10000.
-    // Next: 10059
+    // Next: 10062
     oneof pulled {
         WifiBytesTransfer wifi_bytes_transfer = 10000;
         WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -369,6 +385,7 @@
         FaceSettings face_settings = 10058;
         CoolingDevice cooling_device = 10059;
         AppOps app_ops = 10060;
+        ProcessSystemIonHeapSize process_system_ion_heap_size = 10061;
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -3274,6 +3291,8 @@
     optional int32 error_info_vendor = 7;
     // Dictates if this message should trigger additional debugging.
     optional bool debug = 8;
+    // Time spent during the authentication attempt.
+    optional int64 latency_millis = 9;
 }
 
 /**
@@ -3942,7 +3961,7 @@
     optional int64 page_major_fault = 5;
 
     // RSS
-    // Value is read from /proc/PID/stat, field 24. Or from memory.stat, field
+    // Value is read from /proc/PID/status. Or from memory.stat, field
     // total_rss if per-app memory cgroups are enabled.
     optional int64 rss_in_bytes = 6;
 
@@ -3962,6 +3981,9 @@
     // Elapsed real time when the process started.
     // Value is read from /proc/PID/stat, field 22. 0 if read from per-app memory cgroups.
     optional int64 start_time_nanos = 10;
+
+    // Anonymous page size plus swap size. Values are read from /proc/PID/status.
+    optional int32 anon_rss_and_swap_in_kilobytes = 11;
 }
 
 /*
@@ -3984,7 +4006,7 @@
     optional int64 page_major_fault = 4;
 
     // RSS
-    // Value read from /proc/PID/stat, field 24.
+    // Value read from /proc/PID/status.
     optional int64 rss_in_bytes = 5;
 
     // Deprecated: use ProcessMemoryHighWaterMark atom instead. Always 0.
@@ -3997,6 +4019,9 @@
     // SWAP
     // Value read from /proc/PID/status, field VmSwap.
     optional int64 swap_in_bytes = 8;
+
+    // Anonymous page size plus swap size. Values are read from /proc/PID/status.
+    optional int32 anon_rss_and_swap_in_kilobytes = 9;
 }
 
 /*
@@ -5276,7 +5301,7 @@
     // Only valid for event_type = EVENT_RESNSEND.
     optional int32 res_nsend_flags = 5;
 
-    optional android.stats.dnsresolver.Transport network_type = 6;
+    optional android.stats.dnsresolver.NetworkType network_type = 6;
 
     // The DNS over TLS mode on a specific netId.
     optional android.stats.dnsresolver.PrivateDnsModes private_dns_modes = 7;
@@ -6335,6 +6360,9 @@
 
     // CPU Vulkan implementation is in use.
     optional bool cpu_vulkan_in_use = 6;
+
+    // App is not doing pre-rotation correctly.
+    optional bool false_prerotation = 7;
 }
 
 /*
@@ -6347,6 +6375,28 @@
     optional int64 size_in_bytes = 1;
 }
 
+/*
+ * Logs the per-process size of the system ion heap.
+ *
+ * Pulled from StatsCompanionService.
+ */
+message ProcessSystemIonHeapSize {
+    // The uid if available. -1 means not available.
+    optional int32 uid = 1 [(is_uid) = true];
+
+    // The process name (from /proc/PID/cmdline).
+    optional string process_name = 2;
+
+    // Sum of sizes of all allocations.
+    optional int32 total_size_in_kilobytes = 3;
+
+    // Number of allocations.
+    optional int32 allocation_count = 4;
+
+    // Size of the largest allocation.
+    optional int32 max_size_in_kilobytes = 5;
+}
+
 /**
  * Push network stack events.
  *
@@ -6550,3 +6600,190 @@
     // Categorized to 3 types that are interesting from location's perspective.
     optional android.stats.location.ActivityImportance activiy_importance = 12;
 }
+
+/**
+ * Information about a permission grant or denial made by user inside ReviewPermissionsFragment
+ */
+message ReviewPermissionsFragmentResultReported {
+    // unique value identifying a permission group change. A permission group change might result
+    // in multiple of these atoms
+    optional int64 change_id = 1;
+
+    // UID of package the permission belongs to
+    optional int32 uid = 2 [(is_uid) = true];
+
+    // Name of package the permission belongs to
+    optional string package_name = 3;
+
+    // The permission to be granted
+    optional string permission_name = 4;
+
+    // The result of the permission grant
+    optional bool permission_granted = 5;
+}
+
+/**
+* Information about results of permission upgrade by RuntimePermissionsUpgradeController
+* Logged from: RuntimePermissionUpdgradeController
+*/
+message RuntimePermissionsUpgradeResult {
+    // Permission granted as result of upgrade
+    optional string permission_name = 1;
+
+    // UID of package granted permission
+    optional int32 uid = 2 [(is_uid) = true];
+
+    // Name of package granted permission
+    optional string package_name = 3;
+}
+
+/**
+* Information about a buttons presented in GrantPermissionsActivty and choice made by user
+*/
+message GrantPermissionsActivityButtonActions {
+    // Permission granted as result of upgrade
+    optional string permission_group_name = 1;
+
+    // UID of package granted permission
+    optional int32 uid = 2 [(is_uid) = true];
+
+    // Name of package requesting permission
+    optional string package_name = 3;
+
+    // Buttons presented in the dialog - bit flags, bit numbers are in accordance with
+    // LABEL_ constants in GrantPermissionActivity.java
+    optional int32 buttons_presented = 4;
+
+    // Button clicked by user - same as bit flags in buttons_presented with only single bit set
+    optional int32 button_clicked = 5;
+}
+
+/**
+ * Information about LocationAccessCheck notification presented to user
+ */
+message LocationAccessCheckNotificationAction {
+
+    // id which identifies single session of user interacting with permission controller
+    optional int64 session_id = 1;
+
+    // Uid of package for which location access check is presented
+    optional int32 package_uid = 2;
+
+    // Name of package for which location access check is presented
+    optional string package_name = 3;
+
+    enum Result {
+        UNDEFINED = 0;
+        // notification was presented to the user
+        NOTIFICATION_PRESENTED = 1;
+        // notification was declined by the user
+        NOTIFICATION_DECLINED = 2;
+        // notification was clicked by the user
+        NOTIFICATION_CLICKED = 3;
+    }
+
+    // View / interaction recorded
+    optional Result result = 4;
+}
+
+/**
+ * Information about a permission grant or revoke made by user inside AppPermissionFragment
+ */
+message AppPermissionFragmentActionReported {
+    // id which identifies single session of user interacting with permission controller
+    optional int64 session_id = 1;
+
+    // unique value identifying a permission group change. A permission group change might result
+    // in multiple of these atoms
+    optional int64 change_id = 2;
+
+    // UID of package the permission belongs to
+    optional int32 uid = 3 [(is_uid) = true];
+
+    // Name of package the permission belongs to
+    optional string package_name = 4;
+
+    // The permission to be granted
+    optional string permission_name = 5;
+
+    // The result of the permission grant
+    optional bool permission_granted = 6;
+}
+
+/**
+* Information about a AppPermissionFragment viewed by user
+*/
+message AppPermissionFragmentViewed {
+    // id which identifies single session of user interacting with permission controller
+    optional int64 session_id = 1;
+
+    // UID of package for which permissions are viewed
+    optional int32 uid = 2 [(is_uid) = true];
+
+    // Name of package for which permissions are viewed
+    optional string package_name = 3;
+
+    // Permission group viewed
+    optional string permission_group_name = 4;
+}
+
+/**
+* Information about a AppPermissionsFragment viewed by user
+*/
+message AppPermissionsFragmentViewed {
+    // id which identifies single session of user interacting with permission controller
+    optional int64 session_id = 1;
+
+    // id which identifies single view as every view might have several logging records
+    // with different package information attached
+    optional int64 view_id = 2;
+
+    // Permission group viewed
+    optional string permission_group_name = 3;
+
+    // UID of package for which permissions are viewed
+    optional int32 uid = 4 [(is_uid) = true];
+
+    // Name of package for which permissions are viewed
+    optional string package_name = 5;
+
+    // Category in which permission is included
+    enum Category {
+      UNDEFINED = 0;
+      ALLOWED = 1;
+      ALLOWED_FOREGROUND = 2;
+      DENIED = 3;
+    }
+    optional Category category = 6;
+}
+
+/**
+* Information about a PermissionAppsFragment viewed by user.
+* Logged from ui/handheld/PermissionAppsFragment.java
+*/
+message PermissionAppsFragmentViewed {
+    // id which identifies single session of user interacting with permission controller
+    optional int64 session_id = 1;
+
+    // id which identifies single view as every view might have several logging records
+    // with different package information attached
+    optional int64 view_id = 2;
+
+    // Permission group viewed
+    optional string permission_group_name = 3;
+
+    // UID of package for which permissions are viewed
+    optional int32 uid = 4 [(is_uid) = true];
+
+    // Name of package for which permissions are viewed
+    optional string package_name = 5;
+
+    // Category in which app is included
+    enum Category {
+        UNDEFINED = 0;
+        ALLOWED = 1;
+        ALLOWED_FOREGROUND = 2;
+        DENIED = 3;
+    }
+    optional Category category = 6;
+}
diff --git a/cmds/statsd/src/external/GpuStatsPuller.cpp b/cmds/statsd/src/external/GpuStatsPuller.cpp
index 0d3aca0..bbdb540 100644
--- a/cmds/statsd/src/external/GpuStatsPuller.cpp
+++ b/cmds/statsd/src/external/GpuStatsPuller.cpp
@@ -96,6 +96,7 @@
         if (!event->write(int64VectorToProtoByteString(info.vkDriverLoadingTime))) return false;
         if (!event->write(int64VectorToProtoByteString(info.angleDriverLoadingTime))) return false;
         if (!event->write(info.cpuVulkanInUse)) return false;
+        if (!event->write(info.falsePrerotation)) return false;
         event->init();
         data->emplace_back(event);
     }
diff --git a/cmds/statsd/src/external/Perfprofd.cpp b/cmds/statsd/src/external/Perfprofd.cpp
deleted file mode 100644
index 1678f10..0000000
--- a/cmds/statsd/src/external/Perfprofd.cpp
+++ /dev/null
@@ -1,74 +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.
- */
-
-#include "Perfprofd.h"
-
-#define DEBUG false  // STOPSHIP if true
-#include "config/ConfigKey.h"
-#include "Log.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <string>
-
-#include <binder/IServiceManager.h>
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"  // Alert
-
-#include "android/os/IPerfProfd.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool CollectPerfprofdTraceAndUploadToDropbox(const PerfprofdDetails& config,
-                                             int64_t alert_id,
-                                             const ConfigKey& configKey) {
-    VLOG("Starting trace collection through perfprofd");
-
-    if (!config.has_perfprofd_config()) {
-      ALOGE("The perfprofd trace config is empty, aborting");
-      return false;
-    }
-
-    sp<IPerfProfd> service = interface_cast<IPerfProfd>(
-        defaultServiceManager()->getService(android::String16("perfprofd")));
-    if (service == NULL) {
-      ALOGE("Could not find perfprofd service");
-      return false;
-    }
-
-    auto* data = reinterpret_cast<const uint8_t*>(config.perfprofd_config().data());
-    std::vector<uint8_t> proto_serialized(data, data + config.perfprofd_config().size());
-
-    // TODO: alert-id etc?
-
-    binder::Status status = service->startProfilingProtobuf(proto_serialized);
-    if (status.isOk()) {
-      return true;
-    }
-
-    ALOGE("Error starting perfprofd profiling: %s", status.toString8().c_str());
-    return false;
-}
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/Perfprofd.h b/cmds/statsd/src/external/Perfprofd.h
deleted file mode 100644
index b93fdf8..0000000
--- a/cmds/statsd/src/external/Perfprofd.h
+++ /dev/null
@@ -1,38 +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.
- */
-
-#pragma once
-
-#include <inttypes.h>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-class ConfigKey;
-class PerfprofdDetails;  // Declared in statsd_config.pb.h
-
-// Starts the collection of a Perfprofd trace with the given |config|.
-// The trace is uploaded to Dropbox by the perfprofd service once done.
-// This method returns immediately after passing the config and does NOT wait
-// for the full duration of the trace.
-bool CollectPerfprofdTraceAndUploadToDropbox(const PerfprofdDetails& config,
-                                             int64_t alert_id,
-                                             const ConfigKey& configKey);
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 914d60d..475f18a 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -156,6 +156,9 @@
         // system_ion_heap_size
         {android::util::SYSTEM_ION_HEAP_SIZE,
          {.puller = new StatsCompanionServicePuller(android::util::SYSTEM_ION_HEAP_SIZE)}},
+        // process_system_ion_heap_size
+        {android::util::PROCESS_SYSTEM_ION_HEAP_SIZE,
+         {.puller = new StatsCompanionServicePuller(android::util::PROCESS_SYSTEM_ION_HEAP_SIZE)}},
         // temperature
         {android::util::TEMPERATURE,
          {.puller = new StatsCompanionServicePuller(android::util::TEMPERATURE)}},
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index ce0e561..a836bd1 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -51,6 +51,7 @@
 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_ACTIVATION_BROADCAST_GUARDRAIL = 19;
 
 const int FIELD_ID_ATOM_STATS_TAG = 1;
 const int FIELD_ID_ATOM_STATS_COUNT = 2;
@@ -109,6 +110,9 @@
 const int FIELD_ID_UID_MAP_DROPPED_CHANGES = 3;
 const int FIELD_ID_UID_MAP_DELETED_APPS = 4;
 
+const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID = 1;
+const int FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME = 2;
+
 const std::map<int, std::pair<size_t, size_t>> StatsdStats::kAtomDimensionKeySizeLimitMap = {
         {android::util::BINDER_CALLS, {6000, 10000}},
         {android::util::LOOPER_STATS, {1500, 2500}},
@@ -236,6 +240,19 @@
     vec.push_back(timeSec);
 }
 
+void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid) {
+    noteActivationBroadcastGuardrailHit(uid, getWallClockSec());
+}
+
+void StatsdStats::noteActivationBroadcastGuardrailHit(const int uid, const int32_t timeSec) {
+    lock_guard<std::mutex> lock(mLock);
+    auto& guardrailTimes = mActivationBroadcastGuardrailStats[uid];
+    if (guardrailTimes.size() == kMaxTimestampCount) {
+        guardrailTimes.pop_front();
+    }
+    guardrailTimes.push_back(timeSec);
+}
+
 void StatsdStats::noteDataDropped(const ConfigKey& key, const size_t totalBytes) {
     noteDataDropped(key, totalBytes, getWallClockSec());
 }
@@ -590,6 +607,7 @@
         pullStats.second.unregisteredCount = 0;
     }
     mAtomMetricStats.clear();
+    mActivationBroadcastGuardrailStats.clear();
 }
 
 string buildTimeString(int64_t timeSec) {
@@ -758,6 +776,17 @@
 
     dprintf(out, "Event queue overflow: %d; MaxHistoryNs: %lld; MinHistoryNs: %lld\n",
             mOverflowCount, (long long)mMaxQueueHistoryNs, (long long)mMinQueueHistoryNs);
+
+    if (mActivationBroadcastGuardrailStats.size() > 0) {
+        dprintf(out, "********mActivationBroadcastGuardrail stats***********\n");
+        for (const auto& pair: mActivationBroadcastGuardrailStats) {
+            dprintf(out, "Uid %d: Times: ", pair.first);
+            for (const auto& guardrailHitTime : pair.second) {
+                dprintf(out, "%d ", guardrailHitTime);
+            }
+        }
+        dprintf(out, "\n");
+    }
 }
 
 void addConfigStatsToProto(const ConfigStats& configStats, ProtoOutputStream* proto) {
@@ -959,6 +988,20 @@
                     restart);
     }
 
+    for (const auto& pair: mActivationBroadcastGuardrailStats) {
+        uint64_t token = proto.start(FIELD_TYPE_MESSAGE |
+                                     FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL |
+                                     FIELD_COUNT_REPEATED);
+        proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_UID,
+                    (int32_t) pair.first);
+        for (const auto& guardrailHitTime : pair.second) {
+            proto.write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVATION_BROADCAST_GUARDRAIL_TIME |
+                            FIELD_COUNT_REPEATED,
+                        guardrailHitTime);
+        }
+        proto.end(token);
+    }
+
     output->clear();
     size_t bufferSize = proto.size();
     output->resize(bufferSize);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 8b39f5f..23d2ace 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -170,6 +170,12 @@
     // Vendor pulled atom start id.
     static const int32_t kVendorPulledAtomStartTag = 150000;
 
+    // Beginning of range for timestamp truncation.
+    static const int32_t kTimestampTruncationStartTag = 300000;
+
+    // End of range for timestamp truncation.
+    static const int32_t kTimestampTruncationEndTag = 304999;
+
     // Max accepted atom id.
     static const int32_t kMaxAtomTag = 200000;
 
@@ -439,6 +445,12 @@
     void noteEventQueueOverflow(int64_t oldestEventTimestampNs);
 
     /**
+     * Reports that the activation broadcast guardrail was hit for this uid. Namely, the broadcast
+     * should have been sent, but instead was skipped due to hitting the guardrail.
+     */
+     void noteActivationBroadcastGuardrailHit(const int uid);
+
+    /**
      * 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
      * to collect stats after reset() has been called.
@@ -526,6 +538,10 @@
     // Maps metric ID to its stats. The size is capped by the number of metrics.
     std::map<int64_t, AtomMetricStats> mAtomMetricStats;
 
+    // Maps uids to times when the activation changed broadcast not sent due to hitting the
+    // guardrail. The size is capped by the number of configs, and up to 20 times per uid.
+    std::map<int, std::list<int32_t>> mActivationBroadcastGuardrailStats;
+
     struct LogLossStats {
         LogLossStats(int32_t sec, int32_t count, int32_t error, int32_t tag, int32_t uid,
                      int32_t pid)
@@ -582,6 +598,8 @@
 
     void noteActiveStatusChanged(const ConfigKey& key, bool activate, int32_t timeSec);
 
+    void noteActivationBroadcastGuardrailHit(const int uid, int32_t timeSec);
+
     void addToIceBoxLocked(std::shared_ptr<ConfigStats>& stats);
 
     /**
@@ -601,6 +619,7 @@
     FRIEND_TEST(StatsdStatsTest, TestSystemServerCrash);
     FRIEND_TEST(StatsdStatsTest, TestPullAtomStats);
     FRIEND_TEST(StatsdStatsTest, TestAtomMetricsStats);
+    FRIEND_TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
index 8dc5cef..10ac4a1 100644
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ b/cmds/statsd/src/matchers/matcher_util.cpp
@@ -84,7 +84,7 @@
 
 bool tryMatchString(const UidMap& uidMap, const Field& field, const Value& value,
                     const string& str_match) {
-    if (isAttributionUidField(field, value)) {
+    if (isAttributionUidField(field, value) || isUidField(field, value)) {
         int uid = value.int_value;
         auto aidIt = UidMap::sAidToUidMapping.find(str_match);
         if (aidIt != UidMap::sAidToUidMapping.end()) {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 615c7f2..96fbf7f 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -220,7 +220,7 @@
                     trueConditionDimensions.end()) {
                 for (auto& condIt : whatIt.second) {
                     condIt.second->onConditionChanged(
-                        currentUnSlicedPartCondition, eventTime);
+                            currentUnSlicedPartCondition, eventTime);
                 }
             }
         }
@@ -314,7 +314,7 @@
                 auto condIt = whatIt.second.find(trueDim);
                 if (condIt != whatIt.second.end()) {
                     condIt->second->onConditionChanged(
-                        currentUnSlicedPartCondition, eventTime);
+                            currentUnSlicedPartCondition, eventTime);
                 } else {
                     if (mMetric2ConditionLinks.size() == 0 ||
                         trueDim.contains(linkedConditionDimensionKey)) {
@@ -338,32 +338,25 @@
     }
 }
 
-void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
-                                                              const int64_t eventTime) {
-    VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
-    flushIfNeededLocked(eventTime);
-
-    if (!mConditionSliced) {
-        return;
-    }
-
+void DurationMetricProducer::onSlicedConditionMayChangeInternalLocked(bool overallCondition,
+        const int64_t eventTimeNs) {
     bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
     if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker &&
         mDimensionsInCondition.empty()) {
-        onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTime);
+        onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTimeNs);
         return;
     }
 
     if (changeDimTrackable && mSameConditionDimensionsInTracker &&
         mMetric2ConditionLinks.size() <= 1) {
-        onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTime);
+        onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTimeNs);
         return;
     }
 
     // Now for each of the on-going event, check if the condition has changed for them.
     for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
         for (auto& pair : whatIt.second) {
-            pair.second->onSlicedConditionMayChange(overallCondition, eventTime);
+            pair.second->onSlicedConditionMayChange(overallCondition, eventTimeNs);
         }
     }
 
@@ -389,10 +382,10 @@
                         continue;
                     }
                     unique_ptr<DurationTracker> newTracker =
-                        whatIt.second.begin()->second->clone(eventTime);
+                        whatIt.second.begin()->second->clone(eventTimeNs);
                     if (newTracker != nullptr) {
                         newTracker->setEventKey(MetricDimensionKey(newEventKey));
-                        newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
+                        newTracker->onSlicedConditionMayChange(overallCondition, eventTimeNs);
                         whatIt.second[conditionDimension] = std::move(newTracker);
                     }
                 }
@@ -418,10 +411,10 @@
                     if (hitGuardRailLocked(newEventKey)) {
                         continue;
                     }
-                    auto newTracker = whatIt.second.begin()->second->clone(eventTime);
+                    auto newTracker = whatIt.second.begin()->second->clone(eventTimeNs);
                     if (newTracker != nullptr) {
                         newTracker->setEventKey(newEventKey);
-                        newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
+                        newTracker->onSlicedConditionMayChange(overallCondition, eventTimeNs);
                         whatIt.second[conditionDimension] = std::move(newTracker);
                     }
                 }
@@ -430,10 +423,61 @@
     }
 }
 
+void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
+                                                              const int64_t eventTime) {
+    VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
+
+    if (!mIsActive) {
+        return;
+    }
+
+    flushIfNeededLocked(eventTime);
+
+    if (!mConditionSliced) {
+        return;
+    }
+
+    onSlicedConditionMayChangeInternalLocked(overallCondition, eventTime);
+}
+
+void DurationMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
+    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
+
+    if (!mConditionSliced) {
+        if (ConditionState::kTrue != mCondition) {
+            return;
+        }
+
+        if (mIsActive) {
+            flushIfNeededLocked(eventTimeNs);
+        }
+
+        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+            for (auto& pair : whatIt.second) {
+                pair.second->onConditionChanged(mIsActive, eventTimeNs);
+            }
+        }
+    } else if (mIsActive) {
+        flushIfNeededLocked(eventTimeNs);
+        onSlicedConditionMayChangeInternalLocked(mIsActive, eventTimeNs);
+    } else { // mConditionSliced == true && !mIsActive
+        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
+            for (auto& pair : whatIt.second) {
+                pair.second->onConditionChanged(mIsActive, eventTimeNs);
+            }
+        }
+    }
+}
+
 void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet,
                                                       const int64_t eventTime) {
     VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
     mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
+
+    if (!mIsActive) {
+        return;
+    }
+
     flushIfNeededLocked(eventTime);
     for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
         for (auto& pair : whatIt.second) {
@@ -696,7 +740,9 @@
         return;
     }
 
-    flushIfNeededLocked(event.GetElapsedTimestampNs());
+    if (mIsActive) {
+        flushIfNeededLocked(event.GetElapsedTimestampNs());
+    }
 
     // Handles Stopall events.
     if (matcherIndex == mStopAllIndex) {
@@ -767,6 +813,8 @@
         }
     }
 
+    condition = condition && mIsActive;
+
     if (dimensionKeysInCondition.empty()) {
         handleStartEvent(MetricDimensionKey(dimensionInWhat, DEFAULT_DIMENSION_KEY),
                          conditionKey, condition, event);
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index f711df2..56c9fd6 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -73,9 +73,15 @@
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
 
+    // Internal interface to handle active state change.
+    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
+
     // Internal interface to handle sliced condition change.
     void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
 
+    void onSlicedConditionMayChangeInternalLocked(bool overallCondition,
+                                                  const int64_t eventTimeNs);
+
     void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const int64_t eventTime);
     void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const int64_t eventTime);
 
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 69816cb..96133bd 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -146,16 +146,9 @@
 
     uint64_t wrapperToken =
             mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
-    const bool truncateTimestamp =
-            android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.find(event.GetTagId()) ==
-            android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.end();
-    if (truncateTimestamp) {
-        mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS,
-            (long long)truncateTimestampNsToFiveMinutes(event.GetElapsedTimestampNs()));
-    } else {
-        mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS,
-            (long long)event.GetElapsedTimestampNs());
-    }
+    const int64_t elapsedTimeNs = truncateTimestampIfNecessary(
+            event.GetTagId(), event.GetElapsedTimestampNs());
+    mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS, (long long) elapsedTimeNs);
 
     uint64_t eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
     event.ToProto(*mProto);
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 41000da..a64bbc1 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -283,14 +283,9 @@
                     writeFieldValueTreeToStream(mAtomId, *(atom.mFields), protoOutput);
                     protoOutput->end(atomsToken);
                 }
-                const bool truncateTimestamp =
-                        android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.find(
-                                mAtomId) ==
-                        android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.end();
                 for (const auto& atom : bucket.mGaugeAtoms) {
-                    const int64_t elapsedTimestampNs =  truncateTimestamp ?
-                        truncateTimestampNsToFiveMinutes(atom.mElapsedTimestamps) :
-                            atom.mElapsedTimestamps;
+                    const int64_t elapsedTimestampNs =
+                            truncateTimestampIfNecessary(mAtomId, atom.mElapsedTimestamps);
                     protoOutput->write(
                         FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_ELAPSED_ATOM_TIMESTAMP,
                         (long long)elapsedTimestampNs);
@@ -364,11 +359,27 @@
     }
 }
 
+void GaugeMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
+    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
+    if (ConditionState::kTrue != mCondition || !mIsPulled) {
+        return;
+    }
+    if (mTriggerAtomId == -1 || (mIsActive && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE)) {
+        pullAndMatchEventsLocked(eventTimeNs);
+    }
+
+}
+
 void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
                                                    const int64_t eventTimeNs) {
     VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
-    flushIfNeededLocked(eventTimeNs);
+
     mCondition = conditionMet ? ConditionState::kTrue : ConditionState::kFalse;
+    if (!mIsActive) {
+        return;
+    }
+
+    flushIfNeededLocked(eventTimeNs);
     if (mIsPulled && mTriggerAtomId == -1) {
         pullAndMatchEventsLocked(eventTimeNs);
     }  // else: Push mode. No need to proactively pull the gauge data.
@@ -378,10 +389,14 @@
                                                            const int64_t eventTimeNs) {
     VLOG("GaugeMetric %lld onSlicedConditionMayChange overall condition %d", (long long)mMetricId,
          overallCondition);
+    mCondition = overallCondition ? ConditionState::kTrue : ConditionState::kFalse;
+    if (!mIsActive) {
+        return;
+    }
+
     flushIfNeededLocked(eventTimeNs);
     // If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
     // pull for every dimension.
-    mCondition = overallCondition ? ConditionState::kTrue : ConditionState::kFalse;
     if (mIsPulled && mTriggerAtomId == -1) {
         pullAndMatchEventsLocked(eventTimeNs);
     }  // else: Push mode. No need to proactively pull the gauge data.
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 1b43d43..a612adf 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -106,6 +106,9 @@
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
 
+    // Internal interface to handle active state change.
+    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
+
     // Internal interface to handle sliced condition change.
     void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
 
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index d913427..92752b2 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -107,7 +107,7 @@
     }
     mIsActive = evaluateActiveStateLocked(elapsedTimestampNs);
     if (!mIsActive) {
-        flushLocked(elapsedTimestampNs);
+        onActiveStateChangedLocked(elapsedTimestampNs);
     }
 }
 
@@ -124,7 +124,8 @@
             std::make_shared<Activation>(activationType, ttl_seconds * NS_PER_SEC);
     mEventActivationMap.emplace(activationTrackerIndex, activation);
     if (-1 != deactivationTrackerIndex) {
-        mEventDeactivationMap.emplace(deactivationTrackerIndex, activation);
+        auto& deactivationList = mEventDeactivationMap[deactivationTrackerIndex];
+        deactivationList.push_back(activation);
     }
 }
 
@@ -143,7 +144,11 @@
     }
     activation->start_ns = elapsedTimestampNs;
     activation->state = ActivationState::kActive;
+    bool oldActiveState = mIsActive;
     mIsActive = true;
+    if (!oldActiveState) { // Metric went from not active to active.
+        onActiveStateChangedLocked(elapsedTimestampNs);
+    }
 }
 
 void MetricProducer::cancelEventActivationLocked(int deactivationTrackerIndex) {
@@ -151,7 +156,9 @@
     if (it == mEventDeactivationMap.end()) {
         return;
     }
-    it->second->state = ActivationState::kNotActive;
+    for (auto activationToCancelIt : it->second)  {
+        activationToCancelIt->state = ActivationState::kNotActive;
+    }
 }
 
 void MetricProducer::loadActiveMetricLocked(const ActiveMetric& activeMetric,
@@ -167,7 +174,9 @@
             continue;
         }
         auto& activation = it->second;
-        if (activeEventActivation.state() == ActiveEventActivation::ACTIVE) {
+        // If the event activation does not have a state, assume it is active.
+        if (!activeEventActivation.has_state() ||
+                activeEventActivation.state() == ActiveEventActivation::ACTIVE) {
             // We don't want to change the ttl for future activations, so we set the start_ns
             // such that start_ns + ttl_ns == currentTimeNs + remaining_ttl_nanos
             activation->start_ns =
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 3ddbef4..09ad290 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -132,23 +132,17 @@
     // Consume the parsed stats log entry that already matched the "what" of the metric.
     void onMatchedLogEvent(const size_t matcherIndex, const LogEvent& event) {
         std::lock_guard<std::mutex> lock(mMutex);
-        if (mIsActive) {
-            onMatchedLogEventLocked(matcherIndex, event);
-        }
+        onMatchedLogEventLocked(matcherIndex, event);
     }
 
     void onConditionChanged(const bool condition, const int64_t eventTime) {
         std::lock_guard<std::mutex> lock(mMutex);
-        if (mIsActive) {
-            onConditionChangedLocked(condition, eventTime);
-        }
+        onConditionChangedLocked(condition, eventTime);
     }
 
     void onSlicedConditionMayChange(bool overallCondition, const int64_t eventTime) {
         std::lock_guard<std::mutex> lock(mMutex);
-        if (mIsActive) {
-            onSlicedConditionMayChangeLocked(overallCondition, eventTime);
-        }
+        onSlicedConditionMayChangeLocked(overallCondition, eventTime);
     }
 
     bool isConditionSliced() const {
@@ -304,12 +298,18 @@
      * bucket's end timestamp, than we flush up to the end of the latest full bucket; otherwise,
      * we assume that we want to flush a partial bucket. The bucket start timestamp and bucket
      * number are not changed by this function. This method should only be called by
-     * flushIfNeededLocked or the app upgrade handler; the caller MUST update the bucket timestamp
-     * and bucket number as needed.
+     * flushIfNeededLocked or flushLocked or the app upgrade handler; the caller MUST update the
+     * bucket timestamp and bucket number as needed.
      */
     virtual void flushCurrentBucketLocked(const int64_t& eventTimeNs,
                                           const int64_t& nextBucketStartTimeNs) {};
 
+    virtual void onActiveStateChangedLocked(const int64_t& eventTimeNs) {
+        if (!mIsActive) {
+            flushLocked(eventTimeNs);
+        }
+    }
+
     // Convenience to compute the current bucket's end time, which is always aligned with the
     // start time of the metric.
     int64_t getCurrentBucketEndTimeNs() const {
@@ -407,14 +407,22 @@
     // whether the metric producer is ready to generate metrics.
     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;
+    // Maps index of atom matcher for deactivation to a list of Activation structs.
+    std::unordered_map<int, std::vector<std::shared_ptr<Activation>>> mEventDeactivationMap;
 
     bool mIsActive;
 
+    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
+    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
+
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 
     FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 207a7dd..963205e 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -521,6 +521,10 @@
             if (metric->getMetricId() == activeMetric.id()) {
                 VLOG("Setting active metric: %lld", (long long)metric->getMetricId());
                 metric->loadActiveMetric(activeMetric, currentTimeNs);
+                if (!mIsActive && metric->isActive()) {
+                    StatsdStats::getInstance().noteActiveStatusChanged(mConfigKey,
+                                                                       /*activate=*/ true);
+                }
                 mIsActive |= metric->isActive();
             }
         }
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index da3be06..8efca1e 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -283,6 +283,7 @@
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 
     FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
@@ -291,6 +292,13 @@
     FRIEND_TEST(StatsLogProcessorTest,
             TestActivationOnBootMultipleActivationsDifferentActivationTypes);
     FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
+
+    FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
+    FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivation);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition);
+    FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 17f2994..0e33a0f 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -109,7 +109,8 @@
       mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
                                                       : StatsdStats::kPullMaxDelayNs),
       mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()),
-      mConditionTimer(mCondition == ConditionState::kTrue, timeBaseNs) {
+      // Condition timer will be set in prepareFirstBucketLocked.
+      mConditionTimer(false, timeBaseNs) {
     int64_t bucketSizeMills = 0;
     if (metric.has_bucket()) {
         bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
@@ -175,6 +176,9 @@
     if (mIsActive && mIsPulled && mCondition == ConditionState::kTrue && mUseDiff) {
         pullAndMatchEventsLocked(mCurrentBucketStartTimeNs, mCondition);
     }
+    // Now that activations are processed, start the condition timer if needed.
+    mConditionTimer.onConditionChanged(mIsActive && mCondition == ConditionState::kTrue,
+                                       mCurrentBucketStartTimeNs);
 }
 
 void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
@@ -364,58 +368,98 @@
     mHasGlobalBase = false;
 }
 
-void ValueMetricProducer::onConditionChangedLocked(const bool condition,
-                                                   const int64_t eventTimeNs) {
+// Handle active state change. Active state change is treated like a condition change:
+// - drop bucket if active state change event arrives too late
+// - if condition is true, pull data on active state changes
+// - ConditionTimer tracks changes based on AND of condition and active state.
+void ValueMetricProducer::onActiveStateChangedLocked(const int64_t& eventTimeNs) {
     bool isEventTooLate  = eventTimeNs < mCurrentBucketStartTimeNs;
-    if (!isEventTooLate) {
-        if (mCondition == ConditionState::kUnknown) {
-            // If the condition was unknown, we mark the bucket as invalid since the bucket will
-            // contain partial data. For instance, the condition change might happen close to the
-            // end of the bucket and we might miss lots of data.
-            //
-            // We still want to pull to set the base.
-            invalidateCurrentBucket();
-        }
-
-        // Pull on condition changes.
-        ConditionState newCondition = condition ? ConditionState::kTrue : ConditionState::kFalse;
-        bool conditionChanged =
-                (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)
-                || (mCondition == ConditionState::kFalse && newCondition == ConditionState::kTrue);
-        // We do not need to pull when we go from unknown to false.
-        //
-        // We also pull if the condition was already true in order to be able to flush the bucket at
-        // the end if needed.
-        //
-        // onConditionChangedLocked might happen on bucket boundaries if this is called before
-        // #onDataPulled.
-        if (mIsPulled && (conditionChanged || condition)) {
-            pullAndMatchEventsLocked(eventTimeNs, newCondition);
-        }
-
-        // When condition change from true to false, clear diff base but don't
-        // reset other counters as we may accumulate more value in the bucket.
-        if (mUseDiff && mCondition == ConditionState::kTrue
-                && newCondition == ConditionState::kFalse) {
-            resetBase();
-        }
-        mCondition = newCondition;
-    } else {
-        VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
-             (long long)mCurrentBucketStartTimeNs);
-        StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
+    if (ConditionState::kTrue == mCondition && isEventTooLate) {
+        // Drop bucket because event arrived too late, ie. we are missing data for this bucket.
         invalidateCurrentBucket();
-        // Something weird happened. If we received another event in the future, the condition might
-        // be wrong.
-        mCondition = initialCondition(mConditionTrackerIndex);
     }
 
-    // This part should alway be called.
+    // Call parent method once we've verified the validity of current bucket.
+    MetricProducer::onActiveStateChangedLocked(eventTimeNs);
+
+    if (ConditionState::kTrue != mCondition) {
+        return;
+    }
+
+    // Pull on active state changes.
+    if (!isEventTooLate) {
+        if (mIsPulled) {
+            pullAndMatchEventsLocked(eventTimeNs, mCondition);
+        }
+        // When active state changes from true to false, clear diff base but don't
+        // reset other counters as we may accumulate more value in the bucket.
+        if (mUseDiff && !mIsActive) {
+            resetBase();
+        }
+    }
+
     flushIfNeededLocked(eventTimeNs);
-    mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
+
+    // Let condition timer know of new active state.
+    mConditionTimer.onConditionChanged(mIsActive, eventTimeNs);
 }
 
-void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs, ConditionState condition) {
+void ValueMetricProducer::onConditionChangedLocked(const bool condition,
+                                                   const int64_t eventTimeNs) {
+    ConditionState newCondition = condition ? ConditionState::kTrue : ConditionState::kFalse;
+    bool isEventTooLate  = eventTimeNs < mCurrentBucketStartTimeNs;
+
+    if (mIsActive) {
+        if (isEventTooLate) {
+            VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
+                 (long long)mCurrentBucketStartTimeNs);
+            StatsdStats::getInstance().noteConditionChangeInNextBucket(mMetricId);
+            invalidateCurrentBucket();
+        } else {
+            if (mCondition == ConditionState::kUnknown) {
+                // If the condition was unknown, we mark the bucket as invalid since the bucket will
+                // contain partial data. For instance, the condition change might happen close to
+                // the end of the bucket and we might miss lots of data.
+                //
+                // We still want to pull to set the base.
+                invalidateCurrentBucket();
+            }
+
+            // Pull on condition changes.
+            bool conditionChanged =
+                    (mCondition == ConditionState::kTrue && newCondition == ConditionState::kFalse)
+                    || (mCondition == ConditionState::kFalse &&
+                            newCondition == ConditionState::kTrue);
+            // We do not need to pull when we go from unknown to false.
+            //
+            // We also pull if the condition was already true in order to be able to flush the
+            // bucket at the end if needed.
+            //
+            // onConditionChangedLocked might happen on bucket boundaries if this is called before
+            // #onDataPulled.
+            if (mIsPulled && (conditionChanged || condition)) {
+                pullAndMatchEventsLocked(eventTimeNs, newCondition);
+            }
+
+            // When condition change from true to false, clear diff base but don't
+            // reset other counters as we may accumulate more value in the bucket.
+            if (mUseDiff && mCondition == ConditionState::kTrue
+                    && newCondition == ConditionState::kFalse) {
+                resetBase();
+            }
+        }
+    }
+
+    mCondition = isEventTooLate ? initialCondition(mConditionTrackerIndex) : newCondition;
+
+    if (mIsActive) {
+        flushIfNeededLocked(eventTimeNs);
+        mConditionTimer.onConditionChanged(mCondition, eventTimeNs);
+    }
+}
+
+void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs,
+        ConditionState condition) {
     vector<std::shared_ptr<LogEvent>> allData;
     if (!mPullerManager->Pull(mPullTagId, &allData)) {
         ALOGE("Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index de01e72..739f6ef 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -93,6 +93,9 @@
                             android::util::ProtoOutputStream* protoOutput) override;
     void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
 
+    // Internal interface to handle active state change.
+    void onActiveStateChangedLocked(const int64_t& eventTimeNs) override;
+
     // Internal interface to handle condition change.
     void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
 
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 54ca757..b875470 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -470,6 +470,13 @@
     }
 
     optional EventQueueOverflow queue_overflow = 18;
+
+    message ActivationBroadcastGuardrail {
+        optional int32 uid = 1;
+        repeated int32 guardrail_met_sec = 2;
+    }
+
+    repeated ActivationBroadcastGuardrail activation_guardrail_stats = 19;
 }
 
 message AlertTriggerDetails {
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 31f160d..67625eb 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -545,8 +545,15 @@
     return time(nullptr) * MS_PER_SEC;
 }
 
-int64_t truncateTimestampNsToFiveMinutes(int64_t timestampNs) {
-    return timestampNs / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60);
+int64_t truncateTimestampIfNecessary(int atomId, int64_t timestampNs) {
+    if (AtomsInfo::kTruncatingTimestampAtomBlackList.find(atomId) !=
+            AtomsInfo::kTruncatingTimestampAtomBlackList.end() ||
+        (atomId >= StatsdStats::kTimestampTruncationStartTag &&
+         atomId <= StatsdStats::kTimestampTruncationEndTag)) {
+        return timestampNs / NS_PER_SEC / (5 * 60) * NS_PER_SEC * (5 * 60);
+    } else {
+        return timestampNs;
+    }
 }
 
 int64_t NanoToMillis(const int64_t nano) {
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index 53dd5b7..bfb84cf 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -89,8 +89,9 @@
     return message->ParseFromArray(pbBytes.c_str(), pbBytes.size());
 }
 
-// Returns the truncated timestamp.
-int64_t truncateTimestampNsToFiveMinutes(int64_t timestampNs);
+// Checks the blacklist of atoms as well as the blacklisted range of 300,000 - 304,999.
+// Returns the truncated timestamp to the nearest 5 minutes if needed.
+int64_t truncateTimestampIfNecessary(int atomId, int64_t timestampNs);
 
 inline bool isVendorPulledAtom(int atomId) {
     return atomId >= StatsdStats::kVendorPulledAtomStartTag && atomId < StatsdStats::kMaxAtomTag;
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index a2fd9d4..79c06b9 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -343,15 +343,6 @@
   optional bytes trace_config = 1;
 }
 
-message PerfprofdDetails {
-  // The |perfprofd_config| field is a proto-encoded message of type
-  // android.perfprofd.ProfilingConfig defined in
-  // //system/extras/perfprofd/. On device, statsd doesn't need to
-  // deserialize the message as it's just passed binary-encoded to
-  // the perfprofd service.
-  optional bytes perfprofd_config = 1;
-}
-
 message BroadcastSubscriberDetails {
   optional int64 subscriber_id = 1;
   repeated string cookie = 2;
@@ -373,10 +364,12 @@
     IncidentdDetails incidentd_details = 4;
     PerfettoDetails perfetto_details = 5;
     BroadcastSubscriberDetails broadcast_subscriber_details = 6;
-    PerfprofdDetails perfprofd_details = 8;
   }
 
   optional float probability_of_informing = 7 [default = 1.1];
+
+  // This was used for perfprofd historically.
+  reserved 8;
 }
 
 enum ActivationType {
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 0a9161d..9b48a02 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -442,7 +442,7 @@
 
         if (erase_data) {
             remove(fullPathName.c_str());
-        } else if (output.mIsHistory && !isAdb) {
+        } else if (!output.mIsHistory && !isAdb) {
             // This means a real data owner has called to get this data. But the config says it
             // wants to keep a local history. So now this file must be renamed as a history file.
             // So that next time, when owner calls getData() again, this data won't be uploaded
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
index 2b9528f..70f0f6f 100644
--- a/cmds/statsd/tests/LogEntryMatcher_test.cpp
+++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp
@@ -29,6 +29,7 @@
 using std::vector;
 
 const int32_t TAG_ID = 123;
+const int32_t TAG_ID_2 = 28;  // hardcoded tag of atom with uid field
 const int FIELD_ID_1 = 1;
 const int FIELD_ID_2 = 2;
 const int FIELD_ID_3 = 2;
@@ -297,6 +298,45 @@
     EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
 }
 
+TEST(AtomMatcherTest, TestUidFieldMatcher) {
+    UidMap uidMap;
+    uidMap.updateMap(
+        1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
+        {android::String16("v1"), android::String16("v1"), android::String16("v2"),
+         android::String16("v1"), android::String16("v2")},
+        {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"),
+         android::String16("Pkg2"), android::String16("PkG3")} /* package name list */,
+        {android::String16(""), android::String16(""), android::String16(""),
+         android::String16(""), android::String16("")});
+
+    // Set up matcher
+    AtomMatcher matcher;
+    auto simpleMatcher = matcher.mutable_simple_atom_matcher();
+    simpleMatcher->set_atom_id(TAG_ID);
+    simpleMatcher->add_field_value_matcher()->set_field(1);
+    simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("pkg0");
+
+    // Set up the event
+    LogEvent event(TAG_ID, 0);
+    event.write(1111);
+    event.init();
+
+    LogEvent event2(TAG_ID_2, 0);
+    event2.write(1111);
+    event2.write("some value");
+    event2.init();
+
+    // Tag not in kAtomsWithUidField
+    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
+
+    // Tag found in kAtomsWithUidField and has matching uid
+    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
+
+    // Tag found in kAtomsWithUidField but has non-matching uid
+    simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("Pkg2");
+    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
+}
+
 TEST(AtomMatcherTest, TestNeqAnyStringMatcher) {
     UidMap uidMap;
     uidMap.updateMap(
diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
new file mode 100644
index 0000000..5da0fca
--- /dev/null
+++ b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
@@ -0,0 +1,717 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <gtest/gtest.h>
+
+#include "src/StatsLogProcessor.h"
+#include "src/stats_log_util.h"
+#include "tests/statsd_test_util.h"
+
+#include <vector>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+#ifdef __ANDROID__
+
+TEST(DurationMetricE2eTest, TestOneBucket) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = screenOffMatcher;
+
+    auto durationPredicate = CreateScreenIsOnPredicate();
+    *config.add_predicate() = durationPredicate;
+
+    int64_t metricId = 123456;
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(metricId);
+    durationMetric->set_what(durationPredicate.id());
+    durationMetric->set_bucket(FIVE_MINUTES);
+    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
+
+
+    const int64_t baseTimeNs = 0; // 0:00
+    const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
+    const int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
+
+    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];
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+
+    std::unique_ptr<LogEvent> event;
+
+    // Screen is off at start of bucket.
+    event = CreateScreenStateChangedEvent(
+            android::view::DISPLAY_STATE_OFF, configAddedTimeNs); // 0:01
+    processor->OnLogEvent(event.get());
+
+    // Turn screen on.
+    const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
+    processor->OnLogEvent(event.get());
+
+    // Turn off screen 30 seconds after turning on.
+    const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
+    processor->OnLogEvent(event.get());
+
+    event = CreateScreenBrightnessChangedEvent(64, durationEndNs + 1 * NS_PER_SEC); // 0:42
+    processor->OnLogEvent(event.get());
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
+                            ADB_DUMP, FAST, &buffer); // 5:01
+    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(metricId, reports.reports(0).metrics(0).metric_id());
+    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
+
+    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
+            reports.reports(0).metrics(0).duration_metrics();
+    EXPECT_EQ(1, durationMetrics.data_size());
+
+    auto data = durationMetrics.data(0);
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
+    EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestTwoBuckets) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = screenOffMatcher;
+
+    auto durationPredicate = CreateScreenIsOnPredicate();
+    *config.add_predicate() = durationPredicate;
+
+    int64_t metricId = 123456;
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(metricId);
+    durationMetric->set_what(durationPredicate.id());
+    durationMetric->set_bucket(FIVE_MINUTES);
+    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
+
+
+    const int64_t baseTimeNs = 0; // 0:00
+    const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC; // 0:01
+    const int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
+
+    int uid = 12345;
+    int64_t cfgId = 98765;
+    ConfigKey cfgKey(uid, cfgId);
+
+    auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
+
+    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];
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+
+    std::unique_ptr<LogEvent> event;
+
+    // Screen is off at start of bucket.
+    event = CreateScreenStateChangedEvent(
+            android::view::DISPLAY_STATE_OFF, configAddedTimeNs); // 0:01
+    processor->OnLogEvent(event.get());
+
+    // Turn screen on.
+    const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC; // 0:11
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
+    processor->OnLogEvent(event.get());
+
+    // Turn off screen 30 seconds after turning on.
+    const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC; // 0:41
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
+    processor->OnLogEvent(event.get());
+
+    event = CreateScreenBrightnessChangedEvent(64, durationEndNs + 1 * NS_PER_SEC); // 0:42
+    processor->OnLogEvent(event.get());
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor->onDumpReport(cfgKey, configAddedTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, false, true,
+                            ADB_DUMP, FAST, &buffer); // 10:01
+    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(metricId, reports.reports(0).metrics(0).metric_id());
+    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
+
+    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
+            reports.reports(0).metrics(0).duration_metrics();
+    EXPECT_EQ(1, durationMetrics.data_size());
+
+    auto data = durationMetrics.data(0);
+    EXPECT_EQ(1, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(0, bucketInfo.bucket_num());
+    EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
+    EXPECT_EQ(configAddedTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestWithActivation) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
+    auto crashMatcher = CreateProcessCrashAtomMatcher();
+    *config.add_atom_matcher() = screenOnMatcher;
+    *config.add_atom_matcher() = screenOffMatcher;
+    *config.add_atom_matcher() = crashMatcher;
+
+    auto durationPredicate = CreateScreenIsOnPredicate();
+    *config.add_predicate() = durationPredicate;
+
+    int64_t metricId = 123456;
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(metricId);
+    durationMetric->set_what(durationPredicate.id());
+    durationMetric->set_bucket(FIVE_MINUTES);
+    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
+
+    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(crashMatcher.id());
+    event_activation1->set_ttl_seconds(30); // 30 secs.
+
+    const int64_t bucketStartTimeNs = 10000000000;
+    const int64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_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;
+
+    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); // 0:00
+
+    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;
+
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap.size(), 1u);
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    std::unique_ptr<LogEvent> event;
+
+    // Turn screen off.
+    event = CreateScreenStateChangedEvent(
+            android::view::DISPLAY_STATE_OFF, bucketStartTimeNs + 2 * NS_PER_SEC); // 0:02
+    processor.OnLogEvent(event.get());
+
+    // Turn screen on.
+    const int64_t durationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:05
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
+    processor.OnLogEvent(event.get());
+
+    // Activate metric.
+    const int64_t activationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC; // 0:10
+    const int64_t activationEndNs =
+            activationStartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 0:40
+    event = CreateAppCrashEvent(111, activationStartNs);
+    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[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    // Expire activation.
+    const int64_t expirationNs = activationEndNs + 7 * NS_PER_SEC;
+    event = CreateScreenBrightnessChangedEvent(64, expirationNs); // 0:47
+    processor.OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 2);
+    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    EXPECT_EQ(eventActivationMap.size(), 1u);
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    // Turn off screen 10 seconds after activation expiration.
+    const int64_t durationEndNs = activationEndNs + 10 * NS_PER_SEC; // 0:50
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, durationEndNs);
+    processor.OnLogEvent(event.get());
+
+    // Turn screen on.
+    const int64_t duration2StartNs = durationEndNs + 5 * NS_PER_SEC; // 0:55
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, duration2StartNs);
+    processor.OnLogEvent(event.get());
+
+    // Turn off screen.
+    const int64_t duration2EndNs = duration2StartNs + 10 * NS_PER_SEC; // 1:05
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, duration2EndNs);
+    processor.OnLogEvent(event.get());
+
+    // Activate metric.
+    const int64_t activation2StartNs = duration2EndNs + 5 * NS_PER_SEC; // 1:10
+    const int64_t activation2EndNs =
+            activation2StartNs + event_activation1->ttl_seconds() * NS_PER_SEC; // 1:40
+    event = CreateAppCrashEvent(211, activation2StartNs);
+    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[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, activation2StartNs);
+    EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor.onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
+                            ADB_DUMP, FAST, &buffer); // 5:01
+    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(metricId, reports.reports(0).metrics(0).metric_id());
+    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
+
+    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
+            reports.reports(0).metrics(0).duration_metrics();
+    EXPECT_EQ(1, durationMetrics.data_size());
+
+    auto data = durationMetrics.data(0);
+    EXPECT_EQ(1, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(0, bucketInfo.bucket_num());
+    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(expirationNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(expirationNs - durationStartNs, bucketInfo.duration_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestWithCondition) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
+
+    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
+    *config.add_predicate() = holdingWakelockPredicate;
+
+    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
+    *config.add_predicate() = isInBackgroundPredicate;
+
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(StringToId("WakelockDuration"));
+    durationMetric->set_what(holdingWakelockPredicate.id());
+    durationMetric->set_condition(isInBackgroundPredicate.id());
+    durationMetric->set_aggregation_type(DurationMetric::SUM);
+    durationMetric->set_bucket(FIVE_MINUTES);
+
+    ConfigKey cfgKey;
+    uint64_t bucketStartTimeNs = 10000000000;
+    uint64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+    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;
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_TRUE(eventActivationMap.empty());
+
+    int appUid = 123;
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
+
+    auto event = CreateAcquireWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
+    processor->OnLogEvent(event.get());
+
+    event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
+    processor->OnLogEvent(event.get());
+
+    event = CreateMoveToForegroundEvent(
+            appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
+    processor->OnLogEvent(event.get());
+
+    event = CreateReleaseWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 4 * 60 * NS_PER_SEC); // 4:00
+    processor->OnLogEvent(event.get());
+
+    vector<uint8_t> buffer;
+    ConfigMetricsReportList reports;
+    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_GT(buffer.size(), 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStringInReport(&reports);
+    backfillStartEndTimestamp(&reports);
+
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+
+    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
+
+    // Validate bucket info.
+    EXPECT_EQ(1, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ((2 * 60 + 53) * NS_PER_SEC, bucketInfo.duration_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestWithSlicedCondition) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
+
+    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
+    // The predicate is dimensioning by first attribution node by uid.
+    FieldMatcher dimensions = CreateAttributionUidDimensions(
+            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
+    *config.add_predicate() = holdingWakelockPredicate;
+
+    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
+    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
+        CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
+    *config.add_predicate() = isInBackgroundPredicate;
+
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(StringToId("WakelockDuration"));
+    durationMetric->set_what(holdingWakelockPredicate.id());
+    durationMetric->set_condition(isInBackgroundPredicate.id());
+    durationMetric->set_aggregation_type(DurationMetric::SUM);
+    // The metric is dimensioning by first attribution node and only by uid.
+    *durationMetric->mutable_dimensions_in_what() =
+        CreateAttributionUidDimensions(
+            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+    durationMetric->set_bucket(FIVE_MINUTES);
+
+    // Links between wakelock state atom and condition of app is in background.
+    auto links = durationMetric->add_links();
+    links->set_condition(isInBackgroundPredicate.id());
+    auto dimensionWhat = links->mutable_fields_in_what();
+    dimensionWhat->set_field(android::util::WAKELOCK_STATE_CHANGED);
+    dimensionWhat->add_child()->set_field(1);  // uid field.
+    *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
+            android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, { Position::FIRST });
+
+    ConfigKey cfgKey;
+    uint64_t bucketStartTimeNs = 10000000000;
+    uint64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+    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;
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_TRUE(eventActivationMap.empty());
+
+    int appUid = 123;
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
+
+    auto event = CreateAcquireWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
+    processor->OnLogEvent(event.get());
+
+    event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
+    processor->OnLogEvent(event.get());
+
+    event = CreateReleaseWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 60 * NS_PER_SEC); // 1:00
+    processor->OnLogEvent(event.get());
+
+
+    event = CreateMoveToForegroundEvent(
+            appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
+    processor->OnLogEvent(event.get());
+
+    vector<uint8_t> buffer;
+    ConfigMetricsReportList reports;
+    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_GT(buffer.size(), 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStringInReport(&reports);
+    backfillStartEndTimestamp(&reports);
+
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+
+    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    // Validate dimension value.
+    ValidateAttributionUidDimension(data.dimensions_in_what(),
+                                    android::util::WAKELOCK_STATE_CHANGED, appUid);
+    // Validate bucket info.
+    EXPECT_EQ(1, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(38 * NS_PER_SEC, bucketInfo.duration_nanos());
+}
+
+TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition) {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
+    *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
+    *config.add_atom_matcher() = screenOnMatcher;
+
+    auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
+    // The predicate is dimensioning by first attribution node by uid.
+    FieldMatcher dimensions = CreateAttributionUidDimensions(
+            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+    *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
+    *config.add_predicate() = holdingWakelockPredicate;
+
+    auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
+    *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
+        CreateDimensions(android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
+    *config.add_predicate() = isInBackgroundPredicate;
+
+    auto durationMetric = config.add_duration_metric();
+    durationMetric->set_id(StringToId("WakelockDuration"));
+    durationMetric->set_what(holdingWakelockPredicate.id());
+    durationMetric->set_condition(isInBackgroundPredicate.id());
+    durationMetric->set_aggregation_type(DurationMetric::SUM);
+    // The metric is dimensioning by first attribution node and only by uid.
+    *durationMetric->mutable_dimensions_in_what() =
+        CreateAttributionUidDimensions(
+            android::util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
+    durationMetric->set_bucket(FIVE_MINUTES);
+
+    // Links between wakelock state atom and condition of app is in background.
+    auto links = durationMetric->add_links();
+    links->set_condition(isInBackgroundPredicate.id());
+    auto dimensionWhat = links->mutable_fields_in_what();
+    dimensionWhat->set_field(android::util::WAKELOCK_STATE_CHANGED);
+    dimensionWhat->add_child()->set_field(1);  // uid field.
+    *links->mutable_fields_in_condition() = CreateAttributionUidDimensions(
+            android::util::ACTIVITY_FOREGROUND_STATE_CHANGED, { Position::FIRST });
+
+    auto metric_activation1 = config.add_metric_activation();
+    metric_activation1->set_metric_id(durationMetric->id());
+    auto event_activation1 = metric_activation1->add_event_activation();
+    event_activation1->set_atom_matcher_id(screenOnMatcher.id());
+    event_activation1->set_ttl_seconds(60 * 2);  // 2 minutes.
+
+    ConfigKey cfgKey;
+    uint64_t bucketStartTimeNs = 10000000000;
+    uint64_t bucketSizeNs =
+            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
+    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+    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;
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap.size(), 1u);
+    EXPECT_TRUE(eventActivationMap.find(4) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    int appUid = 123;
+    std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(appUid, "App1")};
+
+    auto event = CreateAcquireWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + 10 * NS_PER_SEC); // 0:10
+    processor->OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    event = CreateMoveToBackgroundEvent(appUid, bucketStartTimeNs + 22 * NS_PER_SEC); // 0:22
+    processor->OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    const int64_t durationStartNs = bucketStartTimeNs + 30 * NS_PER_SEC; // 0:30
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, durationStartNs);
+    processor->OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    const int64_t durationEndNs =
+            durationStartNs + (event_activation1->ttl_seconds() + 30) * NS_PER_SEC; // 3:00
+    event = CreateAppCrashEvent(333, durationEndNs);
+    processor->OnLogEvent(event.get());
+    EXPECT_FALSE(metricsManager->isActive());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    event = CreateMoveToForegroundEvent(
+            appUid, bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC); // 3:15
+    processor->OnLogEvent(event.get());
+
+    event = CreateReleaseWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + (4 * 60 + 17) * NS_PER_SEC); // 4:17
+    processor->OnLogEvent(event.get());
+
+    event = CreateMoveToBackgroundEvent(
+            appUid, bucketStartTimeNs + (4 * 60 + 20) * NS_PER_SEC); // 4:20
+    processor->OnLogEvent(event.get());
+
+    event = CreateAcquireWakelockEvent(
+            attributions1, "wl1", bucketStartTimeNs + (4 * 60 + 25) * NS_PER_SEC); // 4:25
+    processor->OnLogEvent(event.get());
+
+    const int64_t duration2StartNs = bucketStartTimeNs + (4 * 60 + 30) * NS_PER_SEC; // 4:30
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, duration2StartNs);
+    processor->OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[4]->start_ns, duration2StartNs);
+    EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
+
+    vector<uint8_t> buffer;
+    ConfigMetricsReportList reports;
+    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true,
+                            ADB_DUMP, FAST, &buffer);
+    EXPECT_GT(buffer.size(), 0);
+    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
+    backfillDimensionPath(&reports);
+    backfillStringInReport(&reports);
+    backfillStartEndTimestamp(&reports);
+
+    EXPECT_EQ(1, reports.reports_size());
+    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+
+    auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    // Validate dimension value.
+    ValidateAttributionUidDimension(data.dimensions_in_what(),
+                                    android::util::WAKELOCK_STATE_CHANGED, appUid);
+    // Validate bucket info.
+    EXPECT_EQ(2, data.bucket_info_size());
+
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(durationEndNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
+
+    bucketInfo = data.bucket_info(1);
+    EXPECT_EQ(durationEndNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - duration2StartNs, bucketInfo.duration_nanos());
+}
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index 6ec0a11..c7ba9be 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -446,22 +446,23 @@
 
     // Pulling alarm arrives on time and reset the sequential pulling alarm.
     // Event should not be kept.
-    processor->informPullAlarmFired(nextPullTimeNs + 1);
+    processor->informPullAlarmFired(nextPullTimeNs + 1); // 15 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, nextPullTimeNs);
     EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
+    // Activate the metric. A pull occurs upon activation.
     const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
     auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
-    processor->OnLogEvent(batterySaverOnEvent.get());
+    processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
-    // This event should be kept. 1 total.
-    processor->informPullAlarmFired(nextPullTimeNs + 1);
+    // This event should be kept. 2 total.
+    processor->informPullAlarmFired(nextPullTimeNs + 1); // 20 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs,
               nextPullTimeNs);
 
-    // This event should be kept. 2 total.
-    processor->informPullAlarmFired(nextPullTimeNs + 2);
+    // This event should be kept. 3 total.
+    processor->informPullAlarmFired(nextPullTimeNs + 2); // 25 mins + 2 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, nextPullTimeNs);
 
     // Create random event to deactivate metric.
@@ -469,7 +470,7 @@
     processor->OnLogEvent(deactivationEvent.get());
     EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
-    // Event should not be kept. 2 total.
+    // Event should not be kept. 3 total.
     processor->informPullAlarmFired(nextPullTimeNs + 3);
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, nextPullTimeNs);
 
@@ -497,27 +498,39 @@
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(2, data.bucket_info_size());
+    EXPECT_EQ(3, data.bucket_info_size());
 
-    EXPECT_EQ(1, data.bucket_info(0).atom_size());
-    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(1, bucketInfo.atom_size());
+    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
+    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
+    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
+    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(1).atom_size());
-    EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, data.bucket_info(1).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size());
+    bucketInfo = data.bucket_info(1);
+    EXPECT_EQ(1, bucketInfo.atom_size());
+    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
+    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
+    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
+
+    bucketInfo = data.bucket_info(2);
+    EXPECT_EQ(1, bucketInfo.atom_size());
+    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
+    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
     EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
-            data.bucket_info(1).start_bucket_elapsed_nanos());
+            bucketInfo.start_bucket_elapsed_nanos());
     EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)),
-            data.bucket_info(1).end_bucket_elapsed_nanos());
-    EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
+            bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
+    EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
 }
 
 TEST(GaugeMetricE2eTest, TestRandomSamplePulledEventsNoCondition) {
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
index d99d281..f1b6029 100644
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -134,6 +134,42 @@
     return config;
 }
 
+StatsdConfig CreateStatsdConfigWithSameDeactivations() {
+    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
+    event_activation2->set_deactivation_atom_matcher_id(brightnessChangedMatcher.id());
+
+    return config;
+}
+
 StatsdConfig CreateStatsdConfigWithTwoMetricsTwoDeactivations() {
     StatsdConfig config;
     config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
@@ -467,7 +503,8 @@
     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]);
+    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     std::unique_ptr<LogEvent> event;
 
@@ -491,7 +528,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // First processed event.
     event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
@@ -509,7 +546,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // 2nd processed event.
     // The activation by screen_on event expires, but the one by battery save mode is still active.
@@ -523,7 +560,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
     // No new broadcast since the config should still be active.
     EXPECT_EQ(broadcastCount, 1);
 
@@ -545,7 +582,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 20);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap[3], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     // Re-activate metric via screen on.
     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
@@ -562,7 +599,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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[3][0], eventActivationMap[0]);
 
     // 4th processed event.
     event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
@@ -582,7 +619,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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[3][0], eventActivationMap[0]);
 
     // 5th processed event.
     event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
@@ -602,7 +639,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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[3][0], eventActivationMap[0]);
 
     // Screen-on activation expired.
     event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
@@ -618,7 +655,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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[3][0], eventActivationMap[0]);
 
     event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
     processor.OnLogEvent(event.get());
@@ -637,7 +674,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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[3][0], eventActivationMap[0]);
 
     // Cancel battery saver mode activation.
     event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
@@ -652,7 +689,7 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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[3][0], eventActivationMap[0]);
 
     ConfigMetricsReportList reports;
     vector<uint8_t> buffer;
@@ -790,8 +827,10 @@
     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(eventDeactivationMap[3].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     std::unique_ptr<LogEvent> event;
 
@@ -815,8 +854,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // First processed event.
     event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
@@ -834,8 +873,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // 2nd processed event.
     // The activation by screen_on event expires, but the one by battery save mode is still active.
@@ -849,8 +888,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     // No new broadcast since the config should still be active.
     EXPECT_EQ(broadcastCount, 1);
 
@@ -872,8 +911,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // Re-activate metric via screen on.
     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
@@ -890,8 +929,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // 4th processed event.
     event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
@@ -911,8 +950,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // 5th processed event.
     event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
@@ -932,8 +971,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // Screen-on activation expired.
     event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
@@ -948,8 +987,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
     processor.OnLogEvent(event.get());
@@ -968,8 +1007,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     // Cancel battery saver mode and screen on activation.
     event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
@@ -984,8 +1023,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     ConfigMetricsReportList reports;
     vector<uint8_t> buffer;
@@ -1066,6 +1105,203 @@
               data.bucket_info(0).end_bucket_elapsed_nanos());
 }
 
+TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation) {
+    auto config = CreateStatsdConfigWithSameDeactivations();
+
+    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]->start_ns, 0);
+    EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->start_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].size(), 2u);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[3][1], eventActivationMap[2]);
+    EXPECT_EQ(broadcastCount, 0);
+
+    std::unique_ptr<LogEvent> event;
+
+    // Event that should be ignored.
+    event = CreateAppCrashEvent(111, bucketStartTimeNs + 1);
+    processor.OnLogEvent(event.get());
+
+    // Activate metric via screen on for 2 minutes.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON, 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::kNotActive);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
+
+    // 1st processed event.
+    event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
+    processor.OnLogEvent(event.get());
+
+    // Enable battery saver mode activation for 5 minutes.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 + 10);
+    processor.OnLogEvent(event.get());
+    EXPECT_TRUE(metricsManager->isActive());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(broadcastCount, 1);
+    EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 + 10);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2]->start_ns, bucketStartTimeNs + 10);
+
+    // 2nd processed event.
+    event = CreateAppCrashEvent(333, bucketStartTimeNs + NS_PER_SEC * 60 + 40);
+    processor.OnLogEvent(event.get());
+
+    // Cancel battery saver mode and screen on activation.
+    int64_t firstDeactivation = bucketStartTimeNs + NS_PER_SEC * 61;
+    event = CreateScreenBrightnessChangedEvent(64, firstDeactivation);
+    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[2]->state, ActivationState::kNotActive);
+
+    // Should be ignored
+    event = CreateAppCrashEvent(444, bucketStartTimeNs + NS_PER_SEC * 61 + 80);
+    processor.OnLogEvent(event.get());
+
+    // Re-enable battery saver mode activation.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 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]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
+    EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
+
+    // 3rd processed event.
+    event = CreateAppCrashEvent(555, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 80);
+    processor.OnLogEvent(event.get());
+
+    // Cancel battery saver mode activation.
+    int64_t secondDeactivation = bucketStartTimeNs + NS_PER_SEC * 60 * 13;
+    event = CreateScreenBrightnessChangedEvent(140, secondDeactivation);
+    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[2]->state, ActivationState::kNotActive);
+
+    // Should be ignored.
+    event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 13 + 80);
+    processor.OnLogEvent(event.get());
+
+    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(3, reports.reports(0).metrics(0).count_metrics().data_size());
+
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(
+            reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(3, 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(firstDeactivation, 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(firstDeactivation, 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(555, 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 + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(secondDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
+}
+
 TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations) {
     auto config = CreateStatsdConfigWithTwoMetricsTwoDeactivations();
 
@@ -1127,8 +1363,10 @@
     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(eventDeactivationMap[3].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
     EXPECT_EQ(eventActivationMap2.size(), 2u);
     EXPECT_TRUE(eventActivationMap2.find(0) != eventActivationMap2.end());
@@ -1142,8 +1380,10 @@
     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]);
+    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     std::unique_ptr<LogEvent> event;
 
@@ -1170,8 +1410,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1179,8 +1419,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // First processed event.
     event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
@@ -1200,8 +1440,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1209,8 +1449,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // 2nd processed event.
     // The activation by screen_on event expires, but the one by battery save mode is still active.
@@ -1226,8 +1466,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1235,8 +1475,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
     // No new broadcast since the config should still be active.
     EXPECT_EQ(broadcastCount, 1);
 
@@ -1262,8 +1502,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_FALSE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1271,8 +1511,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // Re-activate metric via screen on.
     event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
@@ -1289,8 +1529,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + 10);
@@ -1298,8 +1538,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // 4th processed event.
     event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
@@ -1321,8 +1561,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -1330,8 +1570,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // 5th processed event.
     event = CreateAppCrashEvent(777, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 40);
@@ -1353,8 +1593,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_FALSE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -1362,8 +1602,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // Screen-on activation expired.
     event = CreateAppCrashEvent(888, bucketStartTimeNs + NS_PER_SEC * 60 * 13);
@@ -1380,8 +1620,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_FALSE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -1389,8 +1629,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     event = CreateAppCrashEvent(999, bucketStartTimeNs + NS_PER_SEC * 60 * 14 + 1);
     processor.OnLogEvent(event.get());
@@ -1411,8 +1651,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_TRUE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
@@ -1420,8 +1660,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     // Cancel battery saver mode and screen on activation.
     event = CreateScreenBrightnessChangedEvent(140, bucketStartTimeNs + NS_PER_SEC * 60 * 16);
@@ -1436,8 +1676,8 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_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_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
+    EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
     EXPECT_FALSE(metricProducer2->mIsActive);
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
@@ -1445,8 +1685,8 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_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]);
+    EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
+    EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
     ConfigMetricsReportList reports;
     vector<uint8_t> buffer;
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index ff6af38..fb878dc7 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -306,18 +306,20 @@
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
 
     // Pulling alarm arrives on time and reset the sequential pulling alarm.
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 1); // 15 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
+    EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
+    // Activate the metric. A pull occurs here
     const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
     auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
-    processor->OnLogEvent(batterySaverOnEvent.get());
+    processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 1); // 20 mins + 1 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, expectedPullTimeNs);
 
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 2); // 25 mins + 2 ns.
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
 
     // Create random event to deactivate metric.
@@ -325,10 +327,11 @@
     processor->OnLogEvent(deactivationEvent.get());
     EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
 
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 3);
     EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, expectedPullTimeNs);
 
-    processor->informPullAlarmFired(expectedPullTimeNs + 1);
+    processor->informPullAlarmFired(expectedPullTimeNs + 4);
+    EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
 
     ConfigMetricsReportList reports;
     vector<uint8_t> buffer;
@@ -352,12 +355,18 @@
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    // We have 1 full bucket, the two surrounding the activation are dropped.
-    EXPECT_EQ(1, data.bucket_info_size());
+    // We have 2 full buckets, the two surrounding the activation are dropped.
+    EXPECT_EQ(2, data.bucket_info_size());
 
-    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(0).values_size());
+    auto bucketInfo = data.bucket_info(0);
+    EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(1, bucketInfo.values_size());
+
+    bucketInfo = data.bucket_info(1);
+    EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
+    EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
+    EXPECT_EQ(1, bucketInfo.values_size());
 }
 
 #else
diff --git a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp
index bdc52b0..e91fb0d 100644
--- a/cmds/statsd/tests/external/GpuStatsPuller_test.cpp
+++ b/cmds/statsd/tests/external/GpuStatsPuller_test.cpp
@@ -56,8 +56,9 @@
 static const int32_t CPU_VULKAN_VERSION           = 2;
 static const int32_t GLES_VERSION                 = 3;
 static const bool CPU_VULKAN_IN_USE               = true;
+static const bool FALSE_PREROTATION               = true;
 static const size_t NUMBER_OF_VALUES_GLOBAL       = 13;
-static const size_t NUMBER_OF_VALUES_APP          = 6;
+static const size_t NUMBER_OF_VALUES_APP          = 7;
 // clang-format on
 
 class MockGpuStatsPuller : public GpuStatsPuller {
@@ -150,6 +151,7 @@
     EXPECT_TRUE(event->write(int64VectorToProtoByteString(vkDriverLoadingTime)));
     EXPECT_TRUE(event->write(int64VectorToProtoByteString(angleDriverLoadingTime)));
     EXPECT_TRUE(event->write(CPU_VULKAN_IN_USE));
+    EXPECT_TRUE(event->write(FALSE_PREROTATION));
     event->init();
     inData.emplace_back(event);
     MockGpuStatsPuller mockPuller(android::util::GPU_STATS_APP_INFO, &inData);
@@ -168,6 +170,7 @@
     EXPECT_EQ(int64VectorToProtoByteString(angleDriverLoadingTime),
               outData[0]->getValues()[4].mValue.str_value);
     EXPECT_EQ(CPU_VULKAN_IN_USE, outData[0]->getValues()[5].mValue.int_value);
+    EXPECT_EQ(FALSE_PREROTATION, outData[0]->getValues()[6].mValue.int_value);
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index 1b8a3b5..2a43d9b 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -445,6 +445,47 @@
     EXPECT_EQ(StatsdStats::kMaxSystemServerRestarts + 1, report.system_restart_sec(maxCount - 1));
 }
 
+TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit) {
+    StatsdStats stats;
+    int uid1 = 1;
+    int uid2 = 2;
+    stats.noteActivationBroadcastGuardrailHit(uid1, 10);
+    stats.noteActivationBroadcastGuardrailHit(uid1, 20);
+
+    // Test that we only keep 20 timestamps.
+    for (int i = 0; i < 100; i++) {
+        stats.noteActivationBroadcastGuardrailHit(uid2, i);
+    }
+
+    vector<uint8_t> output;
+    stats.dumpStats(&output, false);
+    StatsdStatsReport report;
+    EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
+
+    EXPECT_EQ(2, report.activation_guardrail_stats_size());
+    bool uid1Good = false;
+    bool uid2Good = false;
+    for (const auto& guardrailTimes : report.activation_guardrail_stats()) {
+        if (uid1 == guardrailTimes.uid()) {
+            uid1Good = true;
+            EXPECT_EQ(2, guardrailTimes.guardrail_met_sec_size());
+            EXPECT_EQ(10, guardrailTimes.guardrail_met_sec(0));
+            EXPECT_EQ(20, guardrailTimes.guardrail_met_sec(1));
+        } else if (uid2 == guardrailTimes.uid()) {
+            int maxCount = StatsdStats::kMaxTimestampCount;
+            uid2Good = true;
+            EXPECT_EQ(maxCount, guardrailTimes.guardrail_met_sec_size());
+            for (int i = 0; i < maxCount; i++) {
+                EXPECT_EQ(100 - maxCount + i, guardrailTimes.guardrail_met_sec(i));
+            }
+        } else {
+            FAIL() << "Unexpected uid.";
+        }
+    }
+    EXPECT_TRUE(uid1Good);
+    EXPECT_TRUE(uid2Good);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/tests/storage/StorageManager_test.cpp b/cmds/statsd/tests/storage/StorageManager_test.cpp
index cae2f30..9e15e99 100644
--- a/cmds/statsd/tests/storage/StorageManager_test.cpp
+++ b/cmds/statsd/tests/storage/StorageManager_test.cpp
@@ -125,6 +125,105 @@
     EXPECT_EQ("300_2000_123454_history", list[3].mFileName);
 }
 
+const string testDir = "/data/misc/stats-data/";
+const string file1 = testDir + "2557169347_1066_1";
+const string file2 = testDir + "2557169349_1066_1";
+const string file1_history = file1 + "_history";
+const string file2_history = file2 + "_history";
+
+bool prepareLocalHistoryTestFiles() {
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(
+            open(file1.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
+    if (fd != -1) {
+        dprintf(fd, "content");
+    } else {
+        return false;
+    }
+
+    android::base::unique_fd fd2(TEMP_FAILURE_RETRY(
+            open(file2.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)));
+    if (fd2 != -1) {
+        dprintf(fd2, "content");
+    } else {
+        return false;
+    }
+    return true;
+}
+
+void clearLocalHistoryTestFiles() {
+    TEMP_FAILURE_RETRY(remove(file1.c_str()));
+    TEMP_FAILURE_RETRY(remove(file2.c_str()));
+    TEMP_FAILURE_RETRY(remove(file1_history.c_str()));
+    TEMP_FAILURE_RETRY(remove(file2_history.c_str()));
+}
+
+bool fileExist(string name) {
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(name.c_str(), O_RDONLY | O_CLOEXEC)));
+    return fd != -1;
+}
+
+/* The following AppendConfigReportTests test the 4 combinations of [whether erase data] [whether
+ * the caller is adb] */
+TEST(StorageManagerTest, AppendConfigReportTest1) {
+    EXPECT_TRUE(prepareLocalHistoryTestFiles());
+
+    ProtoOutputStream out;
+    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
+                                              false /*isAdb?*/);
+
+    EXPECT_FALSE(fileExist(file1));
+    EXPECT_FALSE(fileExist(file2));
+
+    EXPECT_TRUE(fileExist(file1_history));
+    EXPECT_TRUE(fileExist(file2_history));
+    clearLocalHistoryTestFiles();
+}
+
+TEST(StorageManagerTest, AppendConfigReportTest2) {
+    EXPECT_TRUE(prepareLocalHistoryTestFiles());
+
+    ProtoOutputStream out;
+    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
+                                              false /*isAdb?*/);
+
+    EXPECT_FALSE(fileExist(file1));
+    EXPECT_FALSE(fileExist(file2));
+    EXPECT_FALSE(fileExist(file1_history));
+    EXPECT_FALSE(fileExist(file2_history));
+
+    clearLocalHistoryTestFiles();
+}
+
+TEST(StorageManagerTest, AppendConfigReportTest3) {
+    EXPECT_TRUE(prepareLocalHistoryTestFiles());
+
+    ProtoOutputStream out;
+    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, false /*erase?*/,
+                                              true /*isAdb?*/);
+
+    EXPECT_TRUE(fileExist(file1));
+    EXPECT_TRUE(fileExist(file2));
+    EXPECT_FALSE(fileExist(file1_history));
+    EXPECT_FALSE(fileExist(file2_history));
+
+    clearLocalHistoryTestFiles();
+}
+
+TEST(StorageManagerTest, AppendConfigReportTest4) {
+    EXPECT_TRUE(prepareLocalHistoryTestFiles());
+
+    ProtoOutputStream out;
+    StorageManager::appendConfigMetricsReport(ConfigKey(1066, 1), &out, true /*erase?*/,
+                                              true /*isAdb?*/);
+
+    EXPECT_FALSE(fileExist(file1));
+    EXPECT_FALSE(fileExist(file2));
+    EXPECT_FALSE(fileExist(file1_history));
+    EXPECT_FALSE(fileExist(file2_history));
+
+    clearLocalHistoryTestFiles();
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/svc/Android.bp b/cmds/svc/Android.bp
new file mode 100644
index 0000000..68b48f1
--- /dev/null
+++ b/cmds/svc/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2007 The Android Open Source Project
+//
+
+java_binary {
+    name: "svc",
+    wrapper: "svc",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/svc/Android.mk b/cmds/svc/Android.mk
deleted file mode 100644
index a4824c7..0000000
--- a/cmds/svc/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 := svclib
-LOCAL_MODULE_STEM := svc
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := svc
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_SRC_FILES := svc
-LOCAL_REQUIRED_MODULES := svclib
-include $(BUILD_PREBUILT)
diff --git a/cmds/telecom/Android.bp b/cmds/telecom/Android.bp
new file mode 100644
index 0000000..56e147c
--- /dev/null
+++ b/cmds/telecom/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2015 The Android Open Source Project
+//
+
+java_binary {
+    name: "telecom",
+    wrapper: "telecom",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/telecom/Android.mk b/cmds/telecom/Android.mk
deleted file mode 100644
index 5f7bdf7..0000000
--- a/cmds/telecom/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2015 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := telecom
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := telecom
-LOCAL_SRC_FILES := telecom
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/uiautomator/Android.bp b/cmds/uiautomator/Android.bp
new file mode 100644
index 0000000..f9cb3dd
--- /dev/null
+++ b/cmds/uiautomator/Android.bp
@@ -0,0 +1,18 @@
+genrule {
+    name: "uiautomator-last-released-api",
+    srcs: ["api/*.txt"],
+    cmd: "cp -f $$(echo $(in) | tr \" \" \"\\n\" | sort -n | tail -1) $(genDir)/last-released-api.txt",
+    out: [
+        "last-released-api.txt",
+    ],
+}
+
+filegroup {
+    name: "uiautomator-current-api",
+    srcs: ["api/current.txt"],
+}
+
+filegroup {
+    name: "uiautomator-removed-api",
+    srcs: ["api/removed.txt"],
+}
diff --git a/cmds/uiautomator/Android.mk b/cmds/uiautomator/Android.mk
deleted file mode 100644
index 5391305..0000000
--- a/cmds/uiautomator/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# don't build uiautomator in unbundled env
-ifndef TARGET_BUILD_APPS
-include $(call all-subdir-makefiles)
-else
-ifneq ($(filter uiautomator,$(TARGET_BUILD_APPS)),)
-# used by the platform apps build.
-include $(call all-subdir-makefiles)
-endif
-endif
diff --git a/cmds/uiautomator/cmds/Android.mk b/cmds/uiautomator/cmds/Android.mk
deleted file mode 100644
index c141484..0000000
--- a/cmds/uiautomator/cmds/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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 $(call all-subdir-makefiles)
diff --git a/cmds/uiautomator/cmds/uiautomator/Android.bp b/cmds/uiautomator/cmds/uiautomator/Android.bp
new file mode 100644
index 0000000..68cc5a3
--- /dev/null
+++ b/cmds/uiautomator/cmds/uiautomator/Android.bp
@@ -0,0 +1,22 @@
+//
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_binary {
+    name: "uiautomator",
+    wrapper: "uiautomator",
+    srcs: ["src/**/*.java"],
+    static_libs: ["uiautomator.core"],
+}
diff --git a/cmds/uiautomator/cmds/uiautomator/Android.mk b/cmds/uiautomator/cmds/uiautomator/Android.mk
deleted file mode 100644
index 5c91b52..0000000
--- a/cmds/uiautomator/cmds/uiautomator/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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_TAGS := optional
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := uiautomator.core
-LOCAL_MODULE := uiautomator
-
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := uiautomator
-LOCAL_SRC_FILES := uiautomator
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_PREBUILT)
diff --git a/cmds/uiautomator/instrumentation/Android.bp b/cmds/uiautomator/instrumentation/Android.bp
new file mode 100644
index 0000000..477f0d1
--- /dev/null
+++ b/cmds/uiautomator/instrumentation/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2012 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_test {
+    name: "uiautomator-instrumentation",
+
+    srcs: [
+        "testrunner-src/**/*.java",
+    ],
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+    static_libs: [
+        "junit",
+        "uiautomator.library",
+    ],
+    // TODO: change this to 18 when it's available
+    sdk_version: "test_current",
+}
diff --git a/cmds/uiautomator/instrumentation/Android.mk b/cmds/uiautomator/instrumentation/Android.mk
deleted file mode 100644
index e887539..0000000
--- a/cmds/uiautomator/instrumentation/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, testrunner-src) \
-    $(call all-java-files-under, ../library/core-src)
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-LOCAL_STATIC_JAVA_LIBRARIES := junit
-LOCAL_MODULE := uiautomator-instrumentation
-# TODO: change this to 18 when it's available
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/cmds/uiautomator/library/Android.bp b/cmds/uiautomator/library/Android.bp
index 77f17c5..1173d57 100644
--- a/cmds/uiautomator/library/Android.bp
+++ b/cmds/uiautomator/library/Android.bp
@@ -30,6 +30,17 @@
     api_tag_name: "UIAUTOMATOR",
     api_filename: "uiautomator_api.txt",
     removed_api_filename: "uiautomator_removed_api.txt",
+
+    check_api: {
+        current: {
+            api_file: ":uiautomator-current-api",
+            removed_api_file: ":uiautomator-removed-api",
+        },
+        last_released: {
+            api_file: ":uiautomator-last-released-api",
+            removed_api_file: ":uiautomator-removed-api",
+        },
+    },
 }
 
 java_library_static {
@@ -57,3 +68,10 @@
         "junit",
     ]
 }
+
+java_library_static {
+    name: "uiautomator.library",
+    srcs: [
+        "core-src/**/*.java",
+    ],
+}
diff --git a/cmds/uiautomator/library/Android.mk b/cmds/uiautomator/library/Android.mk
deleted file mode 100644
index 5ca201c..0000000
--- a/cmds/uiautomator/library/Android.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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)
-
-###############################################
-# API check
-# Please refer to build/core/tasks/apicheck.mk.
-uiautomator_api_dir := frameworks/base/cmds/uiautomator/api
-last_released_sdk_version := $(lastword $(call numerically_sort, \
-    $(filter-out current, \
-        $(patsubst $(uiautomator_api_dir)/%.txt,%, $(wildcard $(uiautomator_api_dir)/*.txt)) \
-    )))
-
-checkapi_last_error_level_flags := \
-    -hide 2 -hide 3 -hide 4 -hide 5 -hide 6 -hide 24 -hide 25 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18
-
-# Check that the API we're building hasn't broken the last-released SDK version.
-$(eval $(call check-api, \
-    uiautomator-checkapi-last, \
-    $(uiautomator_api_dir)/$(last_released_sdk_version).txt, \
-    $(INTERNAL_PLATFORM_UIAUTOMATOR_API_FILE), \
-    $(uiautomator_api_dir)/removed.txt, \
-    $(INTERNAL_PLATFORM_UIAUTOMATOR_REMOVED_API_FILE), \
-    $(checkapi_last_error_level_flags), \
-    cat $(LOCAL_PATH)/apicheck_msg_last.txt, \
-    uiautomator.core, \
-    $(OUT_DOCS)/uiautomator-stubs-docs-stubs.srcjar))
-
-checkapi_current_error_level_flags := \
-    -error 2 -error 3 -error 4 -error 5 -error 6 \
-    -error 7 -error 8 -error 9 -error 10 -error 11 -error 12 -error 13 -error 14 -error 15 \
-    -error 16 -error 17 -error 18 -error 19 -error 20 -error 21 -error 23 -error 24 \
-    -error 25
-
-# Check that the API we're building hasn't changed from the not-yet-released
-# SDK version.
-$(eval $(call check-api, \
-    uiautomator-checkapi-current, \
-    $(uiautomator_api_dir)/current.txt, \
-    $(INTERNAL_PLATFORM_UIAUTOMATOR_API_FILE), \
-    $(uiautomator_api_dir)/removed.txt, \
-    $(INTERNAL_PLATFORM_UIAUTOMATOR_REMOVED_API_FILE), \
-    $(checkapi_current_error_level_flags), \
-    cat $(LOCAL_PATH)/apicheck_msg_current.txt, \
-    uiautomator.core, \
-    $(OUT_DOCS)/uiautomator-stubs-docs-stubs.srcjar))
-
-.PHONY: update-uiautomator-api
-update-uiautomator-api: PRIVATE_API_DIR := $(uiautomator_api_dir)
-update-uiautomator-api: PRIVATE_REMOVED_API_FILE := $(INTERNAL_PLATFORM_UIAUTOMATOR_REMOVED_API_FILE)
-update-uiautomator-api: $(INTERNAL_PLATFORM_UIAUTOMATOR_API_FILE)
-	@echo Copying uiautomator current.txt
-	$(hide) cp $< $(PRIVATE_API_DIR)/current.txt
-	@echo Copying uiautomator removed.txt
-	$(hide) cp $(PRIVATE_REMOVED_API_FILE) $(PRIVATE_API_DIR)/removed.txt
-###############################################
-# clean up temp vars
-uiautomator_api_dir :=
-checkapi_last_error_level_flags :=
-checkapi_current_error_level_flags :=
diff --git a/cmds/uiautomator/library/apicheck_msg_current.txt b/cmds/uiautomator/library/apicheck_msg_current.txt
deleted file mode 100644
index 989248d..0000000
--- a/cmds/uiautomator/library/apicheck_msg_current.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-
-******************************
-You have tried to change the API from what has been previously approved.
-
-To make these errors go away, you have two choices:
-   1) You can add "@hide" javadoc comments to the methods, etc. listed in the
-      errors above.
-
-   2) You can update current.txt by executing the following command:
-         make update-uiautomator-api
-
-      To submit the revised current.txt to the main Android repository,
-      you will need approval.
-******************************
-
-
-
diff --git a/cmds/uiautomator/library/apicheck_msg_last.txt b/cmds/uiautomator/library/apicheck_msg_last.txt
deleted file mode 100644
index 2993157..0000000
--- a/cmds/uiautomator/library/apicheck_msg_last.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-******************************
-You have tried to change the API from what has been previously released in
-an SDK.  Please fix the errors listed above.
-******************************
-
-
diff --git a/cmds/vr/Android.bp b/cmds/vr/Android.bp
new file mode 100644
index 0000000..cb129bd
--- /dev/null
+++ b/cmds/vr/Android.bp
@@ -0,0 +1,8 @@
+// Copyright 2017 The Android Open Source Project
+//
+
+java_binary {
+    name: "vr",
+    wrapper: "vr",
+    srcs: ["**/*.java"],
+}
diff --git a/cmds/vr/Android.mk b/cmds/vr/Android.mk
deleted file mode 100644
index d0dc25a..0000000
--- a/cmds/vr/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2017 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_MODULE := vr
-include $(BUILD_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vr
-LOCAL_SRC_FILES := vr
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/cmds/wm/Android.bp b/cmds/wm/Android.bp
new file mode 100644
index 0000000..609f84b
--- /dev/null
+++ b/cmds/wm/Android.bp
@@ -0,0 +1,7 @@
+// Copyright 2013 The Android Open Source Project
+//
+
+sh_binary {
+    name: "wm",
+    src: "wm",
+}
diff --git a/cmds/wm/Android.mk b/cmds/wm/Android.mk
deleted file mode 100644
index 693c6e7..0000000
--- a/cmds/wm/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2013 The Android Open Source Project
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := wm
-LOCAL_SRC_FILES := wm
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_PREBUILT)
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index 09a8546..2ac8409 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -24,6 +24,7 @@
 HSPLandroid/accessibilityservice/AccessibilityServiceInfo;->getResolveInfo()Landroid/content/pm/ResolveInfo;
 HSPLandroid/accessibilityservice/AccessibilityServiceInfo;->initFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/accessibilityservice/AccessibilityServiceInfo;->isDirectBootAware()Z
+HSPLandroid/accessibilityservice/AccessibilityServiceInfo;->loadSummary(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
 HSPLandroid/accessibilityservice/AccessibilityServiceInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/accounts/Account$1;-><init>()V
 HSPLandroid/accounts/Account$1;->createFromParcel(Landroid/os/Parcel;)Landroid/accounts/Account;
@@ -36,6 +37,8 @@
 HSPLandroid/accounts/Account;->equals(Ljava/lang/Object;)Z
 HPLandroid/accounts/Account;->getAccessId()Ljava/lang/String;
 HSPLandroid/accounts/Account;->hashCode()I
+HPLandroid/accounts/Account;->toSafeName(Ljava/lang/String;C)Ljava/lang/String;
+HPLandroid/accounts/Account;->toSafeString()Ljava/lang/String;
 HSPLandroid/accounts/Account;->toString()Ljava/lang/String;
 HSPLandroid/accounts/Account;->writeToParcel(Landroid/os/Parcel;I)V
 HPLandroid/accounts/AccountAndUser;-><init>(Landroid/accounts/Account;I)V
@@ -76,6 +79,7 @@
 HSPLandroid/accounts/AccountManager;->getAuthToken(Landroid/accounts/Account;Ljava/lang/String;ZLandroid/accounts/AccountManagerCallback;Landroid/os/Handler;)Landroid/accounts/AccountManagerFuture;
 HPLandroid/accounts/AccountManager;->hasAccountAccess(Landroid/accounts/Account;Ljava/lang/String;Landroid/os/UserHandle;)Z
 HSPLandroid/accounts/AccountManager;->hasFeatures(Landroid/accounts/Account;[Ljava/lang/String;Landroid/accounts/AccountManagerCallback;Landroid/os/Handler;)Landroid/accounts/AccountManagerFuture;
+HSPLandroid/accounts/AccountManager;->invalidateAuthToken(Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/accounts/AuthenticatorDescription$1;-><init>()V
 HSPLandroid/accounts/AuthenticatorDescription$1;->createFromParcel(Landroid/os/Parcel;)Landroid/accounts/AuthenticatorDescription;
 HSPLandroid/accounts/AuthenticatorDescription$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -98,10 +102,11 @@
 HSPLandroid/accounts/IAccountManager$Stub$Proxy;->getAuthToken(Landroid/accounts/IAccountManagerResponse;Landroid/accounts/Account;Ljava/lang/String;ZZLandroid/os/Bundle;)V
 HSPLandroid/accounts/IAccountManager$Stub$Proxy;->getAuthenticatorTypes(I)[Landroid/accounts/AuthenticatorDescription;
 HSPLandroid/accounts/IAccountManager$Stub$Proxy;->hasFeatures(Landroid/accounts/IAccountManagerResponse;Landroid/accounts/Account;[Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/accounts/IAccountManager$Stub$Proxy;->invalidateAuthToken(Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/accounts/IAccountManager$Stub$Proxy;->onAccountAccessed(Ljava/lang/String;)V
 HSPLandroid/accounts/IAccountManager$Stub$Proxy;->registerAccountListener([Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/accounts/IAccountManager$Stub;-><init>()V
-PLandroid/accounts/IAccountManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/accounts/IAccountManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HPLandroid/accounts/IAccountManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLandroid/accounts/IAccountManagerResponse$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HPLandroid/accounts/IAccountManagerResponse$Stub$Proxy;->onResult(Landroid/os/Bundle;)V
@@ -129,6 +134,7 @@
 HSPLandroid/animation/Animator;->createConstantState()Landroid/content/res/ConstantState;
 HSPLandroid/animation/Animator;->getChangingConfigurations()I
 HSPLandroid/animation/Animator;->getListeners()Ljava/util/ArrayList;
+HSPLandroid/animation/Animator;->pause()V
 HSPLandroid/animation/Animator;->removeAllListeners()V
 HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V
 HSPLandroid/animation/Animator;->setAllowRunningAsynchronously(Z)V
@@ -154,6 +160,7 @@
 HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I
 HSPLandroid/animation/AnimatorSet$3;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J
+HSPLandroid/animation/AnimatorSet$Builder;->after(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Builder;->before(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Builder;->with(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Node;->addChild(Landroid/animation/AnimatorSet$Node;)V
@@ -185,10 +192,12 @@
 HSPLandroid/animation/AnimatorSet;->isStarted()Z
 HSPLandroid/animation/AnimatorSet;->play(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet;->playSequentially([Landroid/animation/Animator;)V
+HSPLandroid/animation/AnimatorSet;->playTogether(Ljava/util/Collection;)V
 HSPLandroid/animation/AnimatorSet;->playTogether([Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet;->pulseAnimationFrame(J)Z
 HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/AnimatorSet;
 HSPLandroid/animation/AnimatorSet;->setInterpolator(Landroid/animation/TimeInterpolator;)V
+HSPLandroid/animation/AnimatorSet;->setStartDelay(J)V
 HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V
 HSPLandroid/animation/AnimatorSet;->shouldPlayTogether()Z
 HSPLandroid/animation/AnimatorSet;->skipToEndValue(Z)V
@@ -279,6 +288,7 @@
 HSPLandroid/animation/ObjectAnimator;->isInitialized()Z
 HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Landroid/util/Property;[F)Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Ljava/lang/String;[F)Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/ObjectAnimator;->ofInt(Ljava/lang/Object;Landroid/util/Property;[I)Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->ofInt(Ljava/lang/Object;Ljava/lang/String;[I)Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->ofPropertyValuesHolder(Ljava/lang/Object;[Landroid/animation/PropertyValuesHolder;)Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/Animator;
@@ -286,13 +296,19 @@
 HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
 HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V
 HSPLandroid/animation/ObjectAnimator;->setIntValues([I)V
+HSPLandroid/animation/ObjectAnimator;->setObjectValues([Ljava/lang/Object;)V
 HSPLandroid/animation/ObjectAnimator;->setProperty(Landroid/util/Property;)V
 HSPLandroid/animation/ObjectAnimator;->setTarget(Ljava/lang/Object;)V
 HSPLandroid/animation/ObjectAnimator;->setupEndValues()V
 HSPLandroid/animation/ObjectAnimator;->setupStartValues()V
 HSPLandroid/animation/ObjectAnimator;->start()V
+HSPLandroid/animation/PathKeyframes$1;->getFloatValue(F)F
+HSPLandroid/animation/PathKeyframes$2;->getFloatValue(F)F
+HSPLandroid/animation/PathKeyframes$FloatKeyframesBase;->getValue(F)Ljava/lang/Object;
 HSPLandroid/animation/PathKeyframes$SimpleKeyframes;->clone()Landroid/animation/Keyframes;
 HSPLandroid/animation/PathKeyframes;-><init>(Landroid/graphics/Path;F)V
+HSPLandroid/animation/PathKeyframes;->getValue(F)Ljava/lang/Object;
+HSPLandroid/animation/PathKeyframes;->interpolateInRange(FII)Landroid/graphics/PointF;
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->calculateValue(F)V
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
@@ -333,6 +349,7 @@
 HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V
 HSPLandroid/animation/RectEvaluator;-><init>()V
 HSPLandroid/animation/StateListAnimator$1;->onAnimationEnd(Landroid/animation/Animator;)V
+HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->getChangingConfigurations()I
 HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->newInstance()Landroid/animation/StateListAnimator;
 HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->newInstance()Ljava/lang/Object;
 HSPLandroid/animation/StateListAnimator;-><init>()V
@@ -347,6 +364,12 @@
 HSPLandroid/animation/StateListAnimator;->setChangingConfigurations(I)V
 HSPLandroid/animation/StateListAnimator;->setState([I)V
 HSPLandroid/animation/StateListAnimator;->setTarget(Landroid/view/View;)V
+HSPLandroid/animation/TimeAnimator;-><init>()V
+HSPLandroid/animation/TimeAnimator;->animateBasedOnTime(J)Z
+HSPLandroid/animation/TimeAnimator;->initAnimation()V
+HSPLandroid/animation/TimeAnimator;->setCurrentPlayTime(J)V
+HSPLandroid/animation/TimeAnimator;->setTimeListener(Landroid/animation/TimeAnimator$TimeListener;)V
+HSPLandroid/animation/TimeAnimator;->start()V
 HSPLandroid/animation/ValueAnimator;-><init>()V
 HSPLandroid/animation/ValueAnimator;->addUpdateListener(Landroid/animation/ValueAnimator$AnimatorUpdateListener;)V
 HSPLandroid/animation/ValueAnimator;->animateBasedOnTime(J)Z
@@ -378,6 +401,7 @@
 HSPLandroid/animation/ValueAnimator;->ofInt([I)Landroid/animation/ValueAnimator;
 HSPLandroid/animation/ValueAnimator;->ofObject(Landroid/animation/TypeEvaluator;[Ljava/lang/Object;)Landroid/animation/ValueAnimator;
 HSPLandroid/animation/ValueAnimator;->overrideDurationScale(F)V
+HSPLandroid/animation/ValueAnimator;->pause()V
 HSPLandroid/animation/ValueAnimator;->pulseAnimationFrame(J)Z
 HSPLandroid/animation/ValueAnimator;->setAllowRunningAsynchronously(Z)V
 HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V
@@ -406,7 +430,7 @@
 PLandroid/apex/ApexInfo$1;->newArray(I)[Landroid/apex/ApexInfo;
 PLandroid/apex/ApexInfo$1;->newArray(I)[Ljava/lang/Object;
 PLandroid/apex/ApexInfo;->readFromParcel(Landroid/os/Parcel;)V
-PLandroid/apex/IApexService$Stub$Proxy;->getActivePackages()[Landroid/apex/ApexInfo;
+HPLandroid/apex/IApexService$Stub$Proxy;->getActivePackages()[Landroid/apex/ApexInfo;
 HSPLandroid/apex/IApexService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/apex/IApexService;
 HSPLandroid/app/-$$Lambda$ActivityThread$ActivityClientRecord$HOrG1qglSjSUHSjKBn2rXtX0gGg;->onConfigurationChanged(Landroid/content/res/Configuration;I)V
 HSPLandroid/app/-$$Lambda$ActivityThread$ApplicationThread$tUGFX7CUhzB4Pg5wFd5yeqOnu38;-><init>()V
@@ -421,12 +445,16 @@
 HSPLandroid/app/-$$Lambda$ResourcesManager$QJ7UiVk_XS90KuXAsIjIEym1DnM;->test(Ljava/lang/Object;)Z
 HSPLandroid/app/-$$Lambda$SharedPreferencesImpl$EditorImpl$3CAjkhzA131V3V-sLfP2uy0FWZ0;->run()V
 HSPLandroid/app/ActionBar$LayoutParams;-><init>(II)V
+HSPLandroid/app/ActionBar$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/app/Activity$HostCallbacks;->onAttachFragment(Landroid/app/Fragment;)V
+HSPLandroid/app/Activity$HostCallbacks;->onFindViewById(I)Landroid/view/View;
 HSPLandroid/app/Activity$HostCallbacks;->onGetLayoutInflater()Landroid/view/LayoutInflater;
+HSPLandroid/app/Activity$HostCallbacks;->onHasView()Z
 HSPLandroid/app/Activity$HostCallbacks;->onUseFragmentManagerInflaterFactory()Z
 HSPLandroid/app/Activity;-><init>()V
 HSPLandroid/app/Activity;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Landroid/app/Instrumentation;Landroid/os/IBinder;ILandroid/app/Application;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Ljava/lang/CharSequence;Landroid/app/Activity;Ljava/lang/String;Landroid/app/Activity$NonConfigurationInstances;Landroid/content/res/Configuration;Ljava/lang/String;Lcom/android/internal/app/IVoiceInteractor;Landroid/view/Window;Landroid/view/ViewRootImpl$ActivityConfigCallback;)V
 HSPLandroid/app/Activity;->attachBaseContext(Landroid/content/Context;)V
+HSPLandroid/app/Activity;->autofillClientGetComponentName()Landroid/content/ComponentName;
 HSPLandroid/app/Activity;->autofillClientIsFillUiShowing()Z
 HSPLandroid/app/Activity;->autofillClientRequestHideFillUi()Z
 HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
@@ -437,6 +465,7 @@
 HSPLandroid/app/Activity;->finish()V
 HSPLandroid/app/Activity;->finish(I)V
 HSPLandroid/app/Activity;->finishAfterTransition()V
+HSPLandroid/app/Activity;->finishAndRemoveTask()V
 HSPLandroid/app/Activity;->getActionBar()Landroid/app/ActionBar;
 HSPLandroid/app/Activity;->getActivityOptions()Landroid/app/ActivityOptions;
 HSPLandroid/app/Activity;->getApplication()Landroid/app/Application;
@@ -454,6 +483,7 @@
 HSPLandroid/app/Activity;->getTitle()Ljava/lang/CharSequence;
 HSPLandroid/app/Activity;->getWindow()Landroid/view/Window;
 HSPLandroid/app/Activity;->getWindowManager()Landroid/view/WindowManager;
+HSPLandroid/app/Activity;->hasWindowFocus()Z
 HSPLandroid/app/Activity;->initWindowDecorActionBar()V
 HSPLandroid/app/Activity;->invalidateOptionsMenu()V
 HSPLandroid/app/Activity;->isChangingConfigurations()Z
@@ -478,6 +508,7 @@
 HSPLandroid/app/Activity;->onEnterAnimationComplete()V
 HSPLandroid/app/Activity;->onKeyDown(ILandroid/view/KeyEvent;)Z
 HSPLandroid/app/Activity;->onKeyUp(ILandroid/view/KeyEvent;)Z
+HSPLandroid/app/Activity;->onNewIntent(Landroid/content/Intent;)V
 HSPLandroid/app/Activity;->onPause()V
 HSPLandroid/app/Activity;->onPostCreate(Landroid/os/Bundle;)V
 HSPLandroid/app/Activity;->onPostResume()V
@@ -485,12 +516,15 @@
 HSPLandroid/app/Activity;->onPreparePanel(ILandroid/view/View;Landroid/view/Menu;)Z
 HSPLandroid/app/Activity;->onProvideReferrer()Landroid/net/Uri;
 HSPLandroid/app/Activity;->onRestart()V
+HSPLandroid/app/Activity;->onRestoreInstanceState(Landroid/os/Bundle;)V
 HSPLandroid/app/Activity;->onResume()V
 HSPLandroid/app/Activity;->onSaveInstanceState(Landroid/os/Bundle;)V
 HSPLandroid/app/Activity;->onStart()V
+HSPLandroid/app/Activity;->onStateNotSaved()V
 HSPLandroid/app/Activity;->onStop()V
 HSPLandroid/app/Activity;->onTitleChanged(Ljava/lang/CharSequence;I)V
 HSPLandroid/app/Activity;->onTopResumedActivityChanged(Z)V
+HSPLandroid/app/Activity;->onTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/app/Activity;->onTrimMemory(I)V
 HSPLandroid/app/Activity;->onUserInteraction()V
 HSPLandroid/app/Activity;->onUserLeaveHint()V
@@ -505,11 +539,15 @@
 HSPLandroid/app/Activity;->performStart(Ljava/lang/String;)V
 HSPLandroid/app/Activity;->performStop(ZLjava/lang/String;)V
 HSPLandroid/app/Activity;->reportFullyDrawn()V
+HSPLandroid/app/Activity;->requestWindowFeature(I)Z
+HSPLandroid/app/Activity;->restoreManagedDialogs(Landroid/os/Bundle;)V
 HSPLandroid/app/Activity;->saveManagedDialogs(Landroid/os/Bundle;)V
+HSPLandroid/app/Activity;->setActionBar(Landroid/widget/Toolbar;)V
 HSPLandroid/app/Activity;->setContentView(I)V
 HSPLandroid/app/Activity;->setIntent(Landroid/content/Intent;)V
 HSPLandroid/app/Activity;->setTaskDescription(Landroid/app/ActivityManager$TaskDescription;)V
 HSPLandroid/app/Activity;->setTheme(I)V
+HSPLandroid/app/Activity;->setTitle(I)V
 HSPLandroid/app/Activity;->setTitle(Ljava/lang/CharSequence;)V
 HSPLandroid/app/Activity;->startActivity(Landroid/content/Intent;)V
 HSPLandroid/app/Activity;->startActivity(Landroid/content/Intent;Landroid/os/Bundle;)V
@@ -572,7 +610,7 @@
 HSPLandroid/app/ActivityManager$TaskDescription;->setBackgroundColor(I)V
 HSPLandroid/app/ActivityManager$TaskDescription;->setIcon(I)V
 HSPLandroid/app/ActivityManager$TaskDescription;->setIconFilename(Ljava/lang/String;)V
-PLandroid/app/ActivityManager$TaskDescription;->setLabel(Ljava/lang/String;)V
+HPLandroid/app/ActivityManager$TaskDescription;->setLabel(Ljava/lang/String;)V
 HSPLandroid/app/ActivityManager$TaskDescription;->setNavigationBarColor(I)V
 HSPLandroid/app/ActivityManager$TaskDescription;->setPrimaryColor(I)V
 HSPLandroid/app/ActivityManager$TaskDescription;->setStatusBarColor(I)V
@@ -600,6 +638,7 @@
 HSPLandroid/app/ActivityManager;->checkUidPermission(Ljava/lang/String;I)I
 HSPLandroid/app/ActivityManager;->getAppTasks()Ljava/util/List;
 HSPLandroid/app/ActivityManager;->getCurrentUser()I
+HSPLandroid/app/ActivityManager;->getLargeMemoryClass()I
 HSPLandroid/app/ActivityManager;->getMemoryClass()I
 HSPLandroid/app/ActivityManager;->getMemoryInfo(Landroid/app/ActivityManager$MemoryInfo;)V
 HSPLandroid/app/ActivityManager;->getMyMemoryState(Landroid/app/ActivityManager$RunningAppProcessInfo;)V
@@ -607,14 +646,14 @@
 HSPLandroid/app/ActivityManager;->getProcessMemoryInfo([I)[Landroid/os/Debug$MemoryInfo;
 HSPLandroid/app/ActivityManager;->getRunningAppProcesses()Ljava/util/List;
 HSPLandroid/app/ActivityManager;->getService()Landroid/app/IActivityManager;
-PLandroid/app/ActivityManager;->getUidImportance(I)I
+HPLandroid/app/ActivityManager;->getUidImportance(I)I
 HSPLandroid/app/ActivityManager;->handleIncomingUser(IIIZZLjava/lang/String;Ljava/lang/String;)I
 HSPLandroid/app/ActivityManager;->isHighEndGfx()Z
 HSPLandroid/app/ActivityManager;->isLowRamDevice()Z
 HSPLandroid/app/ActivityManager;->isLowRamDeviceStatic()Z
 HSPLandroid/app/ActivityManager;->isRunningInTestHarness()Z
 HSPLandroid/app/ActivityManager;->isSmallBatteryDevice()Z
-PLandroid/app/ActivityManager;->isSystemReady()Z
+HPLandroid/app/ActivityManager;->isSystemReady()Z
 HSPLandroid/app/ActivityManager;->isUserAMonkey()Z
 HSPLandroid/app/ActivityManager;->isUserRunning(I)Z
 HSPLandroid/app/ActivityManager;->noteAlarmFinish(Landroid/app/PendingIntent;Landroid/os/WorkSource;ILjava/lang/String;)V
@@ -623,24 +662,24 @@
 HSPLandroid/app/ActivityManager;->processStateAmToProto(I)I
 HSPLandroid/app/ActivityManager;->staticGetMemoryClass()I
 HSPLandroid/app/ActivityOptions;-><init>(Landroid/os/Bundle;)V
-PLandroid/app/ActivityOptions;->abort()V
+HPLandroid/app/ActivityOptions;->abort()V
 HSPLandroid/app/ActivityOptions;->abort(Landroid/app/ActivityOptions;)V
 HSPLandroid/app/ActivityOptions;->disallowEnterPictureInPictureWhileLaunching()Z
-PLandroid/app/ActivityOptions;->freezeRecentTasksReordering()Z
+HPLandroid/app/ActivityOptions;->freezeRecentTasksReordering()Z
 HSPLandroid/app/ActivityOptions;->fromBundle(Landroid/os/Bundle;)Landroid/app/ActivityOptions;
 HSPLandroid/app/ActivityOptions;->getAnimationType()I
 HSPLandroid/app/ActivityOptions;->getAvoidMoveToFront()Z
-PLandroid/app/ActivityOptions;->getCustomEnterResId()I
-PLandroid/app/ActivityOptions;->getCustomExitResId()I
-PLandroid/app/ActivityOptions;->getLaunchActivityType()I
+HPLandroid/app/ActivityOptions;->getCustomEnterResId()I
+HPLandroid/app/ActivityOptions;->getCustomExitResId()I
+HPLandroid/app/ActivityOptions;->getLaunchActivityType()I
 HSPLandroid/app/ActivityOptions;->getLaunchBounds()Landroid/graphics/Rect;
 HSPLandroid/app/ActivityOptions;->getLaunchDisplayId()I
 HSPLandroid/app/ActivityOptions;->getLaunchTaskBehind()Z
 HSPLandroid/app/ActivityOptions;->getLaunchTaskId()I
 HSPLandroid/app/ActivityOptions;->getLaunchWindowingMode()I
 HSPLandroid/app/ActivityOptions;->getLockTaskMode()Z
-PLandroid/app/ActivityOptions;->getOnAnimationStartListener()Landroid/os/IRemoteCallback;
-PLandroid/app/ActivityOptions;->getPackageName()Ljava/lang/String;
+HPLandroid/app/ActivityOptions;->getOnAnimationStartListener()Landroid/os/IRemoteCallback;
+HPLandroid/app/ActivityOptions;->getPackageName()Ljava/lang/String;
 HPLandroid/app/ActivityOptions;->getPendingIntentLaunchFlags()I
 HSPLandroid/app/ActivityOptions;->getRemoteAnimationAdapter()Landroid/view/RemoteAnimationAdapter;
 HSPLandroid/app/ActivityOptions;->getRotationAnimationHint()I
@@ -651,7 +690,7 @@
 HSPLandroid/app/ActivityOptions;->setLaunchActivityType(I)V
 HSPLandroid/app/ActivityOptions;->setLaunchDisplayId(I)Landroid/app/ActivityOptions;
 HSPLandroid/app/ActivityOptions;->setLaunchWindowingMode(I)V
-PLandroid/app/ActivityOptions;->setRemoteAnimationAdapter(Landroid/view/RemoteAnimationAdapter;)V
+HPLandroid/app/ActivityOptions;->setRemoteAnimationAdapter(Landroid/view/RemoteAnimationAdapter;)V
 HSPLandroid/app/ActivityOptions;->toBundle()Landroid/os/Bundle;
 HSPLandroid/app/ActivityTaskManager$1;-><init>()V
 HSPLandroid/app/ActivityTaskManager$1;->create()Landroid/app/IActivityTaskManager;
@@ -677,10 +716,11 @@
 HSPLandroid/app/ActivityThread$ApplicationThread;->clearDnsCache()V
 HSPLandroid/app/ActivityThread$ApplicationThread;->dispatchPackageBroadcast(I[Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->dumpDbInfo(Landroid/os/ParcelFileDescriptor;[Ljava/lang/String;)V
-PLandroid/app/ActivityThread$ApplicationThread;->dumpGfxInfo(Landroid/os/ParcelFileDescriptor;[Ljava/lang/String;)V
+HPLandroid/app/ActivityThread$ApplicationThread;->dumpGfxInfo(Landroid/os/ParcelFileDescriptor;[Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->dumpMemInfo(Landroid/os/ParcelFileDescriptor;Landroid/os/Debug$MemoryInfo;ZZZZZ[Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->dumpMemInfo(Ljava/io/PrintWriter;Landroid/os/Debug$MemoryInfo;ZZZZZ)V
-PLandroid/app/ActivityThread$ApplicationThread;->dumpService(Landroid/os/ParcelFileDescriptor;Landroid/os/IBinder;[Ljava/lang/String;)V
+HSPLandroid/app/ActivityThread$ApplicationThread;->dumpProvider(Landroid/os/ParcelFileDescriptor;Landroid/os/IBinder;[Ljava/lang/String;)V
+HPLandroid/app/ActivityThread$ApplicationThread;->dumpService(Landroid/os/ParcelFileDescriptor;Landroid/os/IBinder;[Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->requestAssistContextExtras(Landroid/os/IBinder;Landroid/os/IBinder;III)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleApplicationInfoChanged(Landroid/content/pm/ApplicationInfo;)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleBindService(Landroid/os/IBinder;Landroid/content/Intent;ZI)V
@@ -688,7 +728,8 @@
 HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleCreateService(Landroid/os/IBinder;Landroid/content/pm/ServiceInfo;Landroid/content/res/CompatibilityInfo;I)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleDestroyBackupAgent(Landroid/content/pm/ApplicationInfo;Landroid/content/res/CompatibilityInfo;I)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleEnterAnimationComplete(Landroid/os/IBinder;)V
-PLandroid/app/ActivityThread$ApplicationThread;->scheduleLowMemory()V
+HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleInstallProvider(Landroid/content/pm/ProviderInfo;)V
+HPLandroid/app/ActivityThread$ApplicationThread;->scheduleLowMemory()V
 HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleReceiver(Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Landroid/content/res/CompatibilityInfo;ILjava/lang/String;Landroid/os/Bundle;ZII)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleRegisteredReceiver(Landroid/content/IIntentReceiver;Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZII)V
 HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleServiceArgs(Landroid/os/IBinder;Landroid/content/pm/ParceledListSlice;)V
@@ -728,6 +769,7 @@
 HSPLandroid/app/ActivityThread;->currentApplication()Landroid/app/Application;
 HSPLandroid/app/ActivityThread;->currentOpPackageName()Ljava/lang/String;
 HSPLandroid/app/ActivityThread;->currentPackageName()Ljava/lang/String;
+HSPLandroid/app/ActivityThread;->currentProcessName()Ljava/lang/String;
 HSPLandroid/app/ActivityThread;->deliverNewIntents(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/util/List;)V
 HSPLandroid/app/ActivityThread;->dumpMemInfoTable(Ljava/io/PrintWriter;Landroid/os/Debug$MemoryInfo;ZZZZILjava/lang/String;JJJJJJ)V
 HSPLandroid/app/ActivityThread;->getActivitiesToBeDestroyed()Ljava/util/Map;
@@ -753,7 +795,9 @@
 HSPLandroid/app/ActivityThread;->handleDestroyActivity(Landroid/os/IBinder;ZIZLjava/lang/String;)V
 HSPLandroid/app/ActivityThread;->handleDestroyBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
 HSPLandroid/app/ActivityThread;->handleDispatchPackageBroadcast(I[Ljava/lang/String;)V
-PLandroid/app/ActivityThread;->handleDumpService(Landroid/app/ActivityThread$DumpComponentInfo;)V
+HSPLandroid/app/ActivityThread;->handleDumpProvider(Landroid/app/ActivityThread$DumpComponentInfo;)V
+HPLandroid/app/ActivityThread;->handleDumpService(Landroid/app/ActivityThread$DumpComponentInfo;)V
+HSPLandroid/app/ActivityThread;->handleInstallProvider(Landroid/content/pm/ProviderInfo;)V
 HSPLandroid/app/ActivityThread;->handleLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/app/servertransaction/PendingTransactionActions;Landroid/content/Intent;)Landroid/app/Activity;
 HPLandroid/app/ActivityThread;->handleLowMemory()V
 HSPLandroid/app/ActivityThread;->handleNewIntent(Landroid/os/IBinder;Ljava/util/List;Z)V
@@ -824,14 +868,14 @@
 HSPLandroid/app/AlarmManager;->cancel(Landroid/app/AlarmManager$OnAlarmListener;)V
 HSPLandroid/app/AlarmManager;->cancel(Landroid/app/PendingIntent;)V
 HSPLandroid/app/AlarmManager;->getNextAlarmClock(I)Landroid/app/AlarmManager$AlarmClockInfo;
-PLandroid/app/AlarmManager;->getNextWakeFromIdleTime()J
+HPLandroid/app/AlarmManager;->getNextWakeFromIdleTime()J
 HSPLandroid/app/AlarmManager;->set(IJJJLjava/lang/String;Landroid/app/AlarmManager$OnAlarmListener;Landroid/os/Handler;Landroid/os/WorkSource;)V
 HSPLandroid/app/AlarmManager;->set(IJLandroid/app/PendingIntent;)V
 HSPLandroid/app/AlarmManager;->set(IJLjava/lang/String;Landroid/app/AlarmManager$OnAlarmListener;Landroid/os/Handler;)V
 HSPLandroid/app/AlarmManager;->setExact(IJLandroid/app/PendingIntent;)V
 HSPLandroid/app/AlarmManager;->setExact(IJLjava/lang/String;Landroid/app/AlarmManager$OnAlarmListener;Landroid/os/Handler;)V
 HSPLandroid/app/AlarmManager;->setExactAndAllowWhileIdle(IJLandroid/app/PendingIntent;)V
-PLandroid/app/AlarmManager;->setIdleUntil(IJLjava/lang/String;Landroid/app/AlarmManager$OnAlarmListener;Landroid/os/Handler;)V
+HPLandroid/app/AlarmManager;->setIdleUntil(IJLjava/lang/String;Landroid/app/AlarmManager$OnAlarmListener;Landroid/os/Handler;)V
 HSPLandroid/app/AlarmManager;->setImpl(IJJJILandroid/app/PendingIntent;Landroid/app/AlarmManager$OnAlarmListener;Ljava/lang/String;Landroid/os/Handler;Landroid/os/WorkSource;Landroid/app/AlarmManager$AlarmClockInfo;)V
 HSPLandroid/app/AlarmManager;->setInexactRepeating(IJJLandroid/app/PendingIntent;)V
 HSPLandroid/app/AlarmManager;->setTime(J)V
@@ -869,7 +913,7 @@
 HSPLandroid/app/AppOpsManager$HistoricalOps;->merge(Landroid/app/AppOpsManager$HistoricalOps;)V
 HSPLandroid/app/AppOpsManager$HistoricalOps;->round(D)D
 HPLandroid/app/AppOpsManager$HistoricalOps;->splice(DZ)Landroid/app/AppOpsManager$HistoricalOps;
-PLandroid/app/AppOpsManager$HistoricalOps;->spliceFromEnd(D)Landroid/app/AppOpsManager$HistoricalOps;
+HPLandroid/app/AppOpsManager$HistoricalOps;->spliceFromEnd(D)Landroid/app/AppOpsManager$HistoricalOps;
 HSPLandroid/app/AppOpsManager$HistoricalPackageOps$1;-><init>()V
 HSPLandroid/app/AppOpsManager$HistoricalPackageOps;->access$2700(Landroid/app/AppOpsManager$HistoricalPackageOps;IIIJ)V
 HSPLandroid/app/AppOpsManager$HistoricalPackageOps;->access$2800(Landroid/app/AppOpsManager$HistoricalPackageOps;IIIJ)V
@@ -904,7 +948,7 @@
 HSPLandroid/app/AppOpsManager;->getPackagesForOps([I)Ljava/util/List;
 HSPLandroid/app/AppOpsManager;->getSystemAlertWindowDefault()I
 HSPLandroid/app/AppOpsManager;->getToken(Lcom/android/internal/app/IAppOpsService;)Landroid/os/IBinder;
-PLandroid/app/AppOpsManager;->isOperationActive(IILjava/lang/String;)Z
+HPLandroid/app/AppOpsManager;->isOperationActive(IILjava/lang/String;)Z
 HSPLandroid/app/AppOpsManager;->logOperationIfNeeded(ILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/app/AppOpsManager;->maxForFlagsInStates(Landroid/util/LongSparseLongArray;III)J
 HSPLandroid/app/AppOpsManager;->noteOp(IILjava/lang/String;)I
@@ -973,11 +1017,12 @@
 HSPLandroid/app/Application;->getAutofillClient()Landroid/view/autofill/AutofillManager$AutofillClient;
 HSPLandroid/app/Application;->onConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLandroid/app/Application;->onCreate()V
-PLandroid/app/Application;->onLowMemory()V
+HPLandroid/app/Application;->onLowMemory()V
 HSPLandroid/app/Application;->onTrimMemory(I)V
 HSPLandroid/app/Application;->registerActivityLifecycleCallbacks(Landroid/app/Application$ActivityLifecycleCallbacks;)V
 HSPLandroid/app/Application;->registerComponentCallbacks(Landroid/content/ComponentCallbacks;)V
 HSPLandroid/app/Application;->unregisterActivityLifecycleCallbacks(Landroid/app/Application$ActivityLifecycleCallbacks;)V
+HSPLandroid/app/Application;->unregisterComponentCallbacks(Landroid/content/ComponentCallbacks;)V
 HSPLandroid/app/ApplicationErrorReport$1;-><init>()V
 HSPLandroid/app/ApplicationErrorReport$CrashInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/ApplicationErrorReport$CrashInfo;-><init>(Ljava/lang/Throwable;)V
@@ -999,6 +1044,7 @@
 HSPLandroid/app/ApplicationPackageManager$ResourceName;->hashCode()I
 HSPLandroid/app/ApplicationPackageManager;-><init>(Landroid/app/ContextImpl;Landroid/content/pm/IPackageManager;)V
 HSPLandroid/app/ApplicationPackageManager;->addOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
+HSPLandroid/app/ApplicationPackageManager;->canonicalToCurrentPackageNames([Ljava/lang/String;)[Ljava/lang/String;
 HSPLandroid/app/ApplicationPackageManager;->checkPermission(Ljava/lang/String;Ljava/lang/String;)I
 HSPLandroid/app/ApplicationPackageManager;->checkSignatures(Ljava/lang/String;Ljava/lang/String;)I
 HSPLandroid/app/ApplicationPackageManager;->configurationChanged()V
@@ -1010,6 +1056,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getCachedIcon(Landroid/app/ApplicationPackageManager$ResourceName;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/app/ApplicationPackageManager;->getCachedString(Landroid/app/ApplicationPackageManager$ResourceName;)Ljava/lang/CharSequence;
 HSPLandroid/app/ApplicationPackageManager;->getComponentEnabledSetting(Landroid/content/ComponentName;)I
+HSPLandroid/app/ApplicationPackageManager;->getDefaultActivityIcon()Landroid/graphics/drawable/Drawable;
 HSPLandroid/app/ApplicationPackageManager;->getDrawable(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/app/ApplicationPackageManager;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
 HSPLandroid/app/ApplicationPackageManager;->getInstalledApplications(I)Ljava/util/List;
@@ -1018,6 +1065,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getInstalledPackages(I)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(II)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/app/ApplicationPackageManager;->getInstantAppResolverSettingsComponent()Landroid/content/ComponentName;
 HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;
 HSPLandroid/app/ApplicationPackageManager;->getModuleInfo(Ljava/lang/String;I)Landroid/content/pm/ModuleInfo;
 HSPLandroid/app/ApplicationPackageManager;->getNameForUid(I)Ljava/lang/String;
@@ -1032,7 +1080,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getPermissionControllerPackageName()Ljava/lang/String;
 HSPLandroid/app/ApplicationPackageManager;->getPermissionFlags(Ljava/lang/String;Ljava/lang/String;Landroid/os/UserHandle;)I
 HSPLandroid/app/ApplicationPackageManager;->getPermissionInfo(Ljava/lang/String;I)Landroid/content/pm/PermissionInfo;
-PLandroid/app/ApplicationPackageManager;->getPrimaryStorageCurrentVolume()Landroid/os/storage/VolumeInfo;
+HPLandroid/app/ApplicationPackageManager;->getPrimaryStorageCurrentVolume()Landroid/os/storage/VolumeInfo;
 HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ActivityInfo;
 HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;)Landroid/content/res/Resources;
 HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Ljava/lang/String;)Landroid/content/res/Resources;
@@ -1086,6 +1134,7 @@
 HSPLandroid/app/BackStackRecord;->expandOps(Ljava/util/ArrayList;Landroid/app/Fragment;)Landroid/app/Fragment;
 HSPLandroid/app/BackStackRecord;->generateOps(Ljava/util/ArrayList;Ljava/util/ArrayList;)Z
 HSPLandroid/app/BackStackRecord;->interactsWith(I)Z
+HSPLandroid/app/BackStackRecord;->isEmpty()Z
 HSPLandroid/app/BroadcastOptions;-><init>(Landroid/os/Bundle;)V
 HSPLandroid/app/BroadcastOptions;->allowsBackgroundActivityStarts()Z
 HSPLandroid/app/BroadcastOptions;->getMaxManifestReceiverApiLevel()I
@@ -1094,6 +1143,7 @@
 HSPLandroid/app/BroadcastOptions;->isDontSendToRestrictedApps()Z
 HSPLandroid/app/BroadcastOptions;->makeBasic()Landroid/app/BroadcastOptions;
 HSPLandroid/app/BroadcastOptions;->setBackgroundActivityStartsAllowed(Z)V
+HPLandroid/app/BroadcastOptions;->setDontSendToRestrictedApps(Z)V
 HSPLandroid/app/BroadcastOptions;->setMaxManifestReceiverApiLevel(I)V
 HSPLandroid/app/BroadcastOptions;->setTemporaryAppWhitelistDuration(J)V
 HSPLandroid/app/BroadcastOptions;->toBundle()Landroid/os/Bundle;
@@ -1201,7 +1251,7 @@
 HSPLandroid/app/ContextImpl;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V
 HSPLandroid/app/ContextImpl;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;)V
 HSPLandroid/app/ContextImpl;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;I)V
-PLandroid/app/ContextImpl;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;Landroid/os/Bundle;)V
+HPLandroid/app/ContextImpl;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;Landroid/os/Bundle;)V
 HSPLandroid/app/ContextImpl;->sendBroadcastAsUserMultiplePermissions(Landroid/content/Intent;Landroid/os/UserHandle;[Ljava/lang/String;)V
 HSPLandroid/app/ContextImpl;->sendOrderedBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;ILandroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V
 HSPLandroid/app/ContextImpl;->sendOrderedBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V
@@ -1239,6 +1289,8 @@
 HSPLandroid/app/Dialog;->dismissDialog()V
 HSPLandroid/app/Dialog;->dispatchOnCreate(Landroid/os/Bundle;)V
 HSPLandroid/app/Dialog;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
+HSPLandroid/app/Dialog;->findViewById(I)Landroid/view/View;
+HSPLandroid/app/Dialog;->getContext()Landroid/content/Context;
 HSPLandroid/app/Dialog;->getWindow()Landroid/view/Window;
 HSPLandroid/app/Dialog;->hide()V
 HSPLandroid/app/Dialog;->onAttachedToWindow()V
@@ -1247,6 +1299,7 @@
 HSPLandroid/app/Dialog;->onDetachedFromWindow()V
 HSPLandroid/app/Dialog;->onStart()V
 HSPLandroid/app/Dialog;->onStop()V
+HSPLandroid/app/Dialog;->onTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/app/Dialog;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
 HSPLandroid/app/Dialog;->onWindowFocusChanged(Z)V
 HSPLandroid/app/Dialog;->setCancelable(Z)V
@@ -1314,6 +1367,7 @@
 HSPLandroid/app/Fragment;->setIndex(ILandroid/app/Fragment;)V
 HSPLandroid/app/Fragment;->setNextAnim(I)V
 HSPLandroid/app/Fragment;->setNextTransition(II)V
+HSPLandroid/app/Fragment;->setRetainInstance(Z)V
 HSPLandroid/app/FragmentContainer;->instantiate(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;
 HSPLandroid/app/FragmentController;->attachHost(Landroid/app/Fragment;)V
 HSPLandroid/app/FragmentController;->createController(Landroid/app/FragmentHostCallback;)Landroid/app/FragmentController;
@@ -1346,6 +1400,7 @@
 HSPLandroid/app/FragmentHostCallback;->getFragmentManagerImpl()Landroid/app/FragmentManagerImpl;
 HSPLandroid/app/FragmentHostCallback;->getHandler()Landroid/os/Handler;
 HSPLandroid/app/FragmentHostCallback;->getLoaderManager(Ljava/lang/String;ZZ)Landroid/app/LoaderManagerImpl;
+HSPLandroid/app/FragmentHostCallback;->getRetainLoaders()Z
 HSPLandroid/app/FragmentHostCallback;->inactivateFragment(Ljava/lang/String;)V
 HSPLandroid/app/FragmentHostCallback;->reportLoaderStart()V
 HSPLandroid/app/FragmentManagerImpl$1;->run()V
@@ -1401,6 +1456,7 @@
 HSPLandroid/app/FragmentManagerImpl;->restoreAllState(Landroid/os/Parcelable;Landroid/app/FragmentManagerNonConfig;)V
 HSPLandroid/app/FragmentManagerImpl;->saveAllState()Landroid/os/Parcelable;
 HSPLandroid/app/FragmentManagerImpl;->saveFragmentBasicState(Landroid/app/Fragment;)Landroid/os/Bundle;
+HSPLandroid/app/FragmentManagerImpl;->saveFragmentViewState(Landroid/app/Fragment;)V
 HSPLandroid/app/FragmentManagerImpl;->saveNonConfig()V
 HSPLandroid/app/FragmentManagerImpl;->scheduleCommit()V
 HSPLandroid/app/FragmentManagerState$1;-><init>()V
@@ -1432,6 +1488,7 @@
 HSPLandroid/app/IActivityManager$Stub$Proxy;->getProcessMemoryInfo([I)[Landroid/os/Debug$MemoryInfo;
 HSPLandroid/app/IActivityManager$Stub$Proxy;->getProviderMimeType(Landroid/net/Uri;I)Ljava/lang/String;
 HSPLandroid/app/IActivityManager$Stub$Proxy;->getRunningAppProcesses()Ljava/util/List;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->handleApplicationStrictModeViolation(Landroid/os/IBinder;ILandroid/os/StrictMode$ViolationInfo;)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->isUserAMonkey()Z
 HSPLandroid/app/IActivityManager$Stub$Proxy;->publishContentProviders(Landroid/app/IApplicationThread;Ljava/util/List;)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->publishService(Landroid/os/IBinder;Landroid/content/Intent;Landroid/os/IBinder;)V
@@ -1469,12 +1526,13 @@
 HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getTaskForActivity(Landroid/os/IBinder;Z)I
 HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->isInMultiWindowMode(Landroid/os/IBinder;)Z
 HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->overridePendingTransition(Landroid/os/IBinder;Ljava/lang/String;II)V
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->reportActivityFullyDrawn(Landroid/os/IBinder;Z)V
 HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->reportAssistContextExtras(Landroid/os/IBinder;Landroid/os/Bundle;Landroid/app/assist/AssistStructure;Landroid/app/assist/AssistContent;Landroid/net/Uri;)V
 HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->reportSizeConfigurations(Landroid/os/IBinder;[I[I[I)V
 HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->setTaskDescription(Landroid/os/IBinder;Landroid/app/ActivityManager$TaskDescription;)V
 HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
 HSPLandroid/app/IActivityTaskManager$Stub;-><init>()V
-PLandroid/app/IActivityTaskManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/app/IActivityTaskManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/app/IActivityTaskManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/IAlarmCompleteListener$Stub$Proxy;->alarmComplete(Landroid/os/IBinder;)V
 HSPLandroid/app/IAlarmCompleteListener$Stub;-><init>()V
@@ -1491,19 +1549,19 @@
 HSPLandroid/app/IAlarmManager$Stub$Proxy;->setTimeZone(Ljava/lang/String;)V
 HSPLandroid/app/IAlarmManager$Stub;-><init>()V
 HSPLandroid/app/IAlarmManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IAlarmManager;
-PLandroid/app/IAlarmManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/app/IAlarmManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/app/IAlarmManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/IAppTask$Stub$Proxy;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo;
 HSPLandroid/app/IAppTask$Stub$Proxy;->setExcludeFromRecents(Z)V
-PLandroid/app/IAppTask$Stub;-><init>()V
+HPLandroid/app/IAppTask$Stub;-><init>()V
 HPLandroid/app/IAppTask$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/IApplicationThread$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->bindApplication(Ljava/lang/String;Landroid/content/pm/ApplicationInfo;Ljava/util/List;Landroid/content/ComponentName;Landroid/app/ProfilerInfo;Landroid/os/Bundle;Landroid/app/IInstrumentationWatcher;Landroid/app/IUiAutomationConnection;IZZZZLandroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;Ljava/util/Map;Landroid/os/Bundle;Ljava/lang/String;Landroid/content/AutofillOptions;Landroid/content/ContentCaptureOptions;)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->clearDnsCache()V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->dispatchPackageBroadcast(I[Ljava/lang/String;)V
-PLandroid/app/IApplicationThread$Stub$Proxy;->dumpService(Landroid/os/ParcelFileDescriptor;Landroid/os/IBinder;[Ljava/lang/String;)V
-PLandroid/app/IApplicationThread$Stub$Proxy;->requestAssistContextExtras(Landroid/os/IBinder;Landroid/os/IBinder;III)V
+HPLandroid/app/IApplicationThread$Stub$Proxy;->dumpService(Landroid/os/ParcelFileDescriptor;Landroid/os/IBinder;[Ljava/lang/String;)V
+HPLandroid/app/IApplicationThread$Stub$Proxy;->requestAssistContextExtras(Landroid/os/IBinder;Landroid/os/IBinder;III)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->runIsolatedEntryPoint(Ljava/lang/String;[Ljava/lang/String;)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleBindService(Landroid/os/IBinder;Landroid/content/Intent;ZI)V
 HPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleCreateBackupAgent(Landroid/content/pm/ApplicationInfo;Landroid/content/res/CompatibilityInfo;II)V
@@ -1511,18 +1569,19 @@
 HPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleDestroyBackupAgent(Landroid/content/pm/ApplicationInfo;Landroid/content/res/CompatibilityInfo;I)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleEnterAnimationComplete(Landroid/os/IBinder;)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleInstallProvider(Landroid/content/pm/ProviderInfo;)V
+HPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleLowMemory()V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleReceiver(Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Landroid/content/res/CompatibilityInfo;ILjava/lang/String;Landroid/os/Bundle;ZII)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleRegisteredReceiver(Landroid/content/IIntentReceiver;Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZII)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleServiceArgs(Landroid/os/IBinder;Landroid/content/pm/ParceledListSlice;)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleSleeping(Landroid/os/IBinder;Z)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleStopService(Landroid/os/IBinder;)V
-PLandroid/app/IApplicationThread$Stub$Proxy;->scheduleSuicide()V
+HPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleSuicide()V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleTransaction(Landroid/app/servertransaction/ClientTransaction;)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleTrimMemory(I)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->scheduleUnbindService(Landroid/os/IBinder;Landroid/content/Intent;)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->setNetworkBlockSeq(J)V
 HSPLandroid/app/IApplicationThread$Stub$Proxy;->setProcessState(I)V
-PLandroid/app/IApplicationThread$Stub$Proxy;->unstableProviderDied(Landroid/os/IBinder;)V
+HPLandroid/app/IApplicationThread$Stub$Proxy;->unstableProviderDied(Landroid/os/IBinder;)V
 HSPLandroid/app/IApplicationThread$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/IApplicationThread$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IApplicationThread;
 HSPLandroid/app/IApplicationThread$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -1531,7 +1590,7 @@
 HPLandroid/app/IBackupAgent$Stub$Proxy;->doBackup(Landroid/os/ParcelFileDescriptor;Landroid/os/ParcelFileDescriptor;Landroid/os/ParcelFileDescriptor;JLandroid/app/backup/IBackupCallback;I)V
 PLandroid/app/IBackupAgent$Stub$Proxy;->doFullBackup(Landroid/os/ParcelFileDescriptor;JILandroid/app/backup/IBackupManager;I)V
 HPLandroid/app/IBackupAgent$Stub$Proxy;->doMeasureFullBackup(JILandroid/app/backup/IBackupManager;I)V
-PLandroid/app/IBackupAgent$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IBackupAgent;
+HPLandroid/app/IBackupAgent$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IBackupAgent;
 HSPLandroid/app/IBackupAgent$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLandroid/app/IInstantAppResolver$Stub$Proxy;->getInstantAppResolveInfoList(Landroid/content/Intent;[IILjava/lang/String;ILandroid/os/IRemoteCallback;)V
 PLandroid/app/IInstantAppResolver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstantAppResolver;
@@ -1549,7 +1608,7 @@
 HSPLandroid/app/INotificationManager$Stub$Proxy;->getZenMode()I
 HSPLandroid/app/INotificationManager$Stub;-><init>()V
 HSPLandroid/app/INotificationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/INotificationManager;
-PLandroid/app/INotificationManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/app/INotificationManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/app/INotificationManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/IProcessObserver$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HPLandroid/app/IProcessObserver$Stub$Proxy;->onForegroundActivitiesChanged(IIZ)V
@@ -1557,6 +1616,7 @@
 HPLandroid/app/IProcessObserver$Stub$Proxy;->onProcessDied(II)V
 HSPLandroid/app/IProcessObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IProcessObserver;
 HSPLandroid/app/ISearchManager$Stub;-><init>()V
+HPLandroid/app/ISearchManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/IServiceConnection$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/IServiceConnection$Stub$Proxy;->connected(Landroid/content/ComponentName;Landroid/os/IBinder;Z)V
 HSPLandroid/app/IServiceConnection$Stub;->asBinder()Landroid/os/IBinder;
@@ -1577,8 +1637,9 @@
 PLandroid/app/ITransientNotification$Stub$Proxy;->show(Landroid/os/IBinder;)V
 HSPLandroid/app/ITransientNotification$Stub;-><init>()V
 HSPLandroid/app/ITransientNotification$Stub;->asBinder()Landroid/os/IBinder;
-PLandroid/app/ITransientNotification$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/ITransientNotification;
+HPLandroid/app/ITransientNotification$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/ITransientNotification;
 HSPLandroid/app/IUiAutomationConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUiAutomationConnection;
+HSPLandroid/app/IUiModeManager$Stub$Proxy;->getCurrentModeType()I
 HSPLandroid/app/IUiModeManager$Stub$Proxy;->getNightMode()I
 HSPLandroid/app/IUiModeManager$Stub;-><init>()V
 HSPLandroid/app/IUiModeManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUiModeManager;
@@ -1592,13 +1653,14 @@
 HSPLandroid/app/IUidObserver$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/IUidObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUidObserver;
 HSPLandroid/app/IUriGrantsManager$Stub;-><init>()V
-PLandroid/app/IUriGrantsManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/app/IUriGrantsManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/IUserSwitchObserver$Stub$Proxy;->asBinder()Landroid/os/IBinder;
-PLandroid/app/IUserSwitchObserver$Stub$Proxy;->onForegroundProfileSwitch(I)V
+HPLandroid/app/IUserSwitchObserver$Stub$Proxy;->onForegroundProfileSwitch(I)V
 HSPLandroid/app/IUserSwitchObserver$Stub$Proxy;->onLockedBootComplete(I)V
 HSPLandroid/app/IUserSwitchObserver$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/IUserSwitchObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUserSwitchObserver;
 HSPLandroid/app/IUserSwitchObserver$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->getWallpaperColors(III)Landroid/app/WallpaperColors;
 HSPLandroid/app/IWallpaperManager$Stub;-><init>()V
 HSPLandroid/app/IWallpaperManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/IWallpaperManagerCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
@@ -1612,6 +1674,7 @@
 HSPLandroid/app/Instrumentation;->callActivityOnPause(Landroid/app/Activity;)V
 HSPLandroid/app/Instrumentation;->callActivityOnPostCreate(Landroid/app/Activity;Landroid/os/Bundle;)V
 HSPLandroid/app/Instrumentation;->callActivityOnRestart(Landroid/app/Activity;)V
+HSPLandroid/app/Instrumentation;->callActivityOnRestoreInstanceState(Landroid/app/Activity;Landroid/os/Bundle;)V
 HSPLandroid/app/Instrumentation;->callActivityOnResume(Landroid/app/Activity;)V
 HSPLandroid/app/Instrumentation;->callActivityOnSaveInstanceState(Landroid/app/Activity;Landroid/os/Bundle;)V
 HSPLandroid/app/Instrumentation;->callActivityOnStart(Landroid/app/Activity;)V
@@ -1641,8 +1704,8 @@
 HSPLandroid/app/JobSchedulerImpl;->schedule(Landroid/app/job/JobInfo;)I
 HSPLandroid/app/JobSchedulerImpl;->scheduleAsPackage(Landroid/app/job/JobInfo;Ljava/lang/String;ILjava/lang/String;)I
 HSPLandroid/app/KeyguardManager;-><init>(Landroid/content/Context;)V
-PLandroid/app/KeyguardManager;->createConfirmDeviceCredentialIntent(Ljava/lang/CharSequence;Ljava/lang/CharSequence;I)Landroid/content/Intent;
-PLandroid/app/KeyguardManager;->getSettingsPackageForIntent(Landroid/content/Intent;)Ljava/lang/String;
+HPLandroid/app/KeyguardManager;->createConfirmDeviceCredentialIntent(Ljava/lang/CharSequence;Ljava/lang/CharSequence;I)Landroid/content/Intent;
+HPLandroid/app/KeyguardManager;->getSettingsPackageForIntent(Landroid/content/Intent;)Ljava/lang/String;
 HSPLandroid/app/KeyguardManager;->inKeyguardRestrictedInputMode()Z
 HSPLandroid/app/KeyguardManager;->isDeviceLocked()Z
 HSPLandroid/app/KeyguardManager;->isDeviceLocked(I)Z
@@ -1702,7 +1765,8 @@
 HSPLandroid/app/Notification$Action$Builder;->addExtras(Landroid/os/Bundle;)Landroid/app/Notification$Action$Builder;
 HSPLandroid/app/Notification$Action$Builder;->build()Landroid/app/Notification$Action;
 HSPLandroid/app/Notification$Action$Builder;->setAllowGeneratedReplies(Z)Landroid/app/Notification$Action$Builder;
-PLandroid/app/Notification$Action$Builder;->setContextual(Z)Landroid/app/Notification$Action$Builder;
+HPLandroid/app/Notification$Action$Builder;->setContextual(Z)Landroid/app/Notification$Action$Builder;
+HSPLandroid/app/Notification$Action$Builder;->setSemanticAction(I)Landroid/app/Notification$Action$Builder;
 HSPLandroid/app/Notification$Action;-><init>(Landroid/graphics/drawable/Icon;Ljava/lang/CharSequence;Landroid/app/PendingIntent;Landroid/os/Bundle;[Landroid/app/RemoteInput;ZIZ)V
 HSPLandroid/app/Notification$Action;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/Notification$Action;->clone()Landroid/app/Notification$Action;
@@ -1713,11 +1777,13 @@
 HSPLandroid/app/Notification$Action;->isContextual()Z
 HSPLandroid/app/Notification$Action;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/Notification$BigTextStyle;-><init>()V
+HSPLandroid/app/Notification$BigTextStyle;-><init>(Landroid/app/Notification$Builder;)V
 HSPLandroid/app/Notification$BigTextStyle;->addExtras(Landroid/os/Bundle;)V
 HPLandroid/app/Notification$BigTextStyle;->areNotificationsVisiblyDifferent(Landroid/app/Notification$Style;)Z
 HSPLandroid/app/Notification$BigTextStyle;->bigText(Ljava/lang/CharSequence;)Landroid/app/Notification$BigTextStyle;
-PLandroid/app/Notification$BigTextStyle;->getBigText()Ljava/lang/CharSequence;
+HPLandroid/app/Notification$BigTextStyle;->getBigText()Ljava/lang/CharSequence;
 HSPLandroid/app/Notification$BigTextStyle;->restoreFromExtras(Landroid/os/Bundle;)V
+HSPLandroid/app/Notification$BigTextStyle;->setBigContentTitle(Ljava/lang/CharSequence;)Landroid/app/Notification$BigTextStyle;
 HSPLandroid/app/Notification$Builder;-><init>(Landroid/content/Context;)V
 HSPLandroid/app/Notification$Builder;-><init>(Landroid/content/Context;Landroid/app/Notification;)V
 HSPLandroid/app/Notification$Builder;-><init>(Landroid/content/Context;Ljava/lang/String;)V
@@ -1737,6 +1803,7 @@
 HSPLandroid/app/Notification$Builder;->setCategory(Ljava/lang/String;)Landroid/app/Notification$Builder;
 HSPLandroid/app/Notification$Builder;->setChannelId(Ljava/lang/String;)Landroid/app/Notification$Builder;
 HSPLandroid/app/Notification$Builder;->setColor(I)Landroid/app/Notification$Builder;
+HSPLandroid/app/Notification$Builder;->setColorized(Z)Landroid/app/Notification$Builder;
 HSPLandroid/app/Notification$Builder;->setContent(Landroid/widget/RemoteViews;)Landroid/app/Notification$Builder;
 HSPLandroid/app/Notification$Builder;->setContentInfo(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;
 HSPLandroid/app/Notification$Builder;->setContentIntent(Landroid/app/PendingIntent;)Landroid/app/Notification$Builder;
@@ -1780,15 +1847,19 @@
 HSPLandroid/app/Notification$Builder;->setVisibility(I)Landroid/app/Notification$Builder;
 HSPLandroid/app/Notification$Builder;->setWhen(J)Landroid/app/Notification$Builder;
 HSPLandroid/app/Notification$Builder;->usesStandardHeader()Z
+HSPLandroid/app/Notification$InboxStyle;-><init>()V
+HSPLandroid/app/Notification$InboxStyle;->restoreFromExtras(Landroid/os/Bundle;)V
 HSPLandroid/app/Notification$MediaStyle;-><init>()V
+HPLandroid/app/Notification$MediaStyle;->areNotificationsVisiblyDifferent(Landroid/app/Notification$Style;)Z
+HSPLandroid/app/Notification$MediaStyle;->restoreFromExtras(Landroid/os/Bundle;)V
 HSPLandroid/app/Notification$MessagingStyle$Message;->getMessageFromBundle(Landroid/os/Bundle;)Landroid/app/Notification$MessagingStyle$Message;
 HSPLandroid/app/Notification$MessagingStyle$Message;->getMessagesFromBundleArray([Landroid/os/Parcelable;)Ljava/util/List;
-PLandroid/app/Notification$MessagingStyle$Message;->getSenderPerson()Landroid/app/Person;
-PLandroid/app/Notification$MessagingStyle$Message;->getText()Ljava/lang/CharSequence;
-PLandroid/app/Notification$MessagingStyle$Message;->getTimestamp()J
+HPLandroid/app/Notification$MessagingStyle$Message;->getSenderPerson()Landroid/app/Person;
+HPLandroid/app/Notification$MessagingStyle$Message;->getText()Ljava/lang/CharSequence;
+HPLandroid/app/Notification$MessagingStyle$Message;->getTimestamp()J
 HSPLandroid/app/Notification$MessagingStyle;-><init>()V
 HPLandroid/app/Notification$MessagingStyle;->areNotificationsVisiblyDifferent(Landroid/app/Notification$Style;)Z
-PLandroid/app/Notification$MessagingStyle;->getMessages()Ljava/util/List;
+HPLandroid/app/Notification$MessagingStyle;->getMessages()Ljava/util/List;
 HSPLandroid/app/Notification$MessagingStyle;->restoreFromExtras(Landroid/os/Bundle;)V
 HSPLandroid/app/Notification$Style;->addExtras(Landroid/os/Bundle;)V
 HSPLandroid/app/Notification$Style;->buildStyled(Landroid/app/Notification;)Landroid/app/Notification;
@@ -1808,7 +1879,7 @@
 HSPLandroid/app/Notification;->clone()Landroid/app/Notification;
 HSPLandroid/app/Notification;->cloneInto(Landroid/app/Notification;Z)V
 HSPLandroid/app/Notification;->findRemoteInputActionPair(Z)Landroid/util/Pair;
-PLandroid/app/Notification;->getAllowSystemGeneratedContextualActions()Z
+HPLandroid/app/Notification;->getAllowSystemGeneratedContextualActions()Z
 HSPLandroid/app/Notification;->getChannelId()Ljava/lang/String;
 HSPLandroid/app/Notification;->getContextualActions()Ljava/util/List;
 HSPLandroid/app/Notification;->getGroup()Ljava/lang/String;
@@ -1883,6 +1954,7 @@
 HSPLandroid/app/NotificationManager$Policy;->allowAlarms()Z
 HSPLandroid/app/NotificationManager$Policy;->allowCalls()Z
 HSPLandroid/app/NotificationManager$Policy;->allowMedia()Z
+HPLandroid/app/NotificationManager$Policy;->allowMessages()Z
 HSPLandroid/app/NotificationManager$Policy;->allowRepeatCallers()Z
 HSPLandroid/app/NotificationManager$Policy;->allowSystem()Z
 HSPLandroid/app/NotificationManager$Policy;->areAllVisualEffectsSuppressed(I)Z
@@ -1914,6 +1986,7 @@
 HSPLandroid/app/NotificationManager;->getNotificationChannels()Ljava/util/List;
 HSPLandroid/app/NotificationManager;->getService()Landroid/app/INotificationManager;
 HSPLandroid/app/NotificationManager;->getZenMode()I
+HPLandroid/app/NotificationManager;->matchesCallFilter(Landroid/os/Bundle;)Z
 HSPLandroid/app/NotificationManager;->notify(ILandroid/app/Notification;)V
 HSPLandroid/app/NotificationManager;->notify(Ljava/lang/String;ILandroid/app/Notification;)V
 HSPLandroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
@@ -1937,7 +2010,7 @@
 HSPLandroid/app/PendingIntent;->getBroadcastAsUser(Landroid/content/Context;ILandroid/content/Intent;ILandroid/os/UserHandle;)Landroid/app/PendingIntent;
 HSPLandroid/app/PendingIntent;->getCreatorPackage()Ljava/lang/String;
 HSPLandroid/app/PendingIntent;->getCreatorUid()I
-PLandroid/app/PendingIntent;->getIntent()Landroid/content/Intent;
+HPLandroid/app/PendingIntent;->getIntent()Landroid/content/Intent;
 HSPLandroid/app/PendingIntent;->getService(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
 HSPLandroid/app/PendingIntent;->getTag(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/app/PendingIntent;->hashCode()I
@@ -1960,9 +2033,9 @@
 HSPLandroid/app/Person$Builder;->setKey(Ljava/lang/String;)Landroid/app/Person$Builder;
 HSPLandroid/app/Person;-><init>(Landroid/app/Person$Builder;)V
 HSPLandroid/app/Person;-><init>(Landroid/os/Parcel;)V
-PLandroid/app/Person;->equals(Ljava/lang/Object;)Z
-PLandroid/app/Person;->getKey()Ljava/lang/String;
-PLandroid/app/Person;->getName()Ljava/lang/CharSequence;
+HPLandroid/app/Person;->equals(Ljava/lang/Object;)Z
+HPLandroid/app/Person;->getKey()Ljava/lang/String;
+HPLandroid/app/Person;->getName()Ljava/lang/CharSequence;
 HPLandroid/app/Person;->hashCode()I
 HPLandroid/app/Person;->resolveToLegacyUri()Ljava/lang/String;
 HSPLandroid/app/Person;->writeToParcel(Landroid/os/Parcel;I)V
@@ -1993,8 +2066,8 @@
 HSPLandroid/app/RemoteInput$1;->newArray(I)[Landroid/app/RemoteInput;
 HSPLandroid/app/RemoteInput$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/app/RemoteInput;-><init>(Landroid/os/Parcel;)V
-PLandroid/app/RemoteInput;->getAllowFreeFormInput()Z
-PLandroid/app/RemoteInput;->getChoices()[Ljava/lang/CharSequence;
+HPLandroid/app/RemoteInput;->getAllowFreeFormInput()Z
+HPLandroid/app/RemoteInput;->getChoices()[Ljava/lang/CharSequence;
 HSPLandroid/app/RemoteInput;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/ResourcesManager$ApkKey;->equals(Ljava/lang/Object;)Z
 HSPLandroid/app/ResourcesManager$ApkKey;->hashCode()I
@@ -2005,6 +2078,7 @@
 HSPLandroid/app/ResourcesManager;->createAssetManager(Landroid/content/res/ResourcesKey;)Landroid/content/res/AssetManager;
 HSPLandroid/app/ResourcesManager;->createBaseActivityResources(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;Ljava/lang/ClassLoader;)Landroid/content/res/Resources;
 HSPLandroid/app/ResourcesManager;->createResourcesImpl(Landroid/content/res/ResourcesKey;)Landroid/content/res/ResourcesImpl;
+HSPLandroid/app/ResourcesManager;->findKeyForResourceImplLocked(Landroid/content/res/ResourcesImpl;)Landroid/content/res/ResourcesKey;
 HSPLandroid/app/ResourcesManager;->findResourcesImplForKeyLocked(Landroid/content/res/ResourcesKey;)Landroid/content/res/ResourcesImpl;
 HSPLandroid/app/ResourcesManager;->generateConfig(Landroid/content/res/ResourcesKey;Landroid/util/DisplayMetrics;)Landroid/content/res/Configuration;
 HSPLandroid/app/ResourcesManager;->getAdjustedDisplay(ILandroid/content/res/Resources;)Landroid/view/Display;
@@ -2023,19 +2097,19 @@
 HSPLandroid/app/ResourcesManager;->redirectResourcesToNewImplLocked(Landroid/util/ArrayMap;)V
 HSPLandroid/app/ResourcesManager;->updateResourcesForActivity(Landroid/os/IBinder;Landroid/content/res/Configuration;IZ)V
 HSPLandroid/app/ResultInfo$1;-><init>()V
-PLandroid/app/ResultInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/app/ResultInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/SearchableInfo$1;-><init>()V
 HSPLandroid/app/SearchableInfo;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;Landroid/content/ComponentName;)V
 HSPLandroid/app/SearchableInfo;->createActivityContext(Landroid/content/Context;Landroid/content/ComponentName;)Landroid/content/Context;
 HSPLandroid/app/SearchableInfo;->getActivityMetaData(Landroid/content/Context;Landroid/content/pm/ActivityInfo;I)Landroid/app/SearchableInfo;
 HSPLandroid/app/SearchableInfo;->getActivityMetaData(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/content/ComponentName;)Landroid/app/SearchableInfo;
 HSPLandroid/app/Service;-><init>()V
-PLandroid/app/Service;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
+HPLandroid/app/Service;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
 HSPLandroid/app/Service;->getApplication()Landroid/app/Application;
 HSPLandroid/app/Service;->onConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLandroid/app/Service;->onCreate()V
 HSPLandroid/app/Service;->onDestroy()V
-PLandroid/app/Service;->onLowMemory()V
+HPLandroid/app/Service;->onLowMemory()V
 HSPLandroid/app/Service;->onStart(Landroid/content/Intent;I)V
 HSPLandroid/app/Service;->onStartCommand(Landroid/content/Intent;II)I
 HSPLandroid/app/Service;->onTrimMemory(I)V
@@ -2088,6 +2162,7 @@
 HSPLandroid/app/SharedPreferencesImpl;->startReloadIfChangedUnexpectedly()V
 HSPLandroid/app/SharedPreferencesImpl;->unregisterOnSharedPreferenceChangeListener(Landroid/content/SharedPreferences$OnSharedPreferenceChangeListener;)V
 HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V
+HSPLandroid/app/StatsManager;->getIStatsManagerLocked()Landroid/os/IStatsManager;
 HSPLandroid/app/StatusBarManager;->getService()Lcom/android/internal/statusbar/IStatusBarService;
 HSPLandroid/app/SynchronousUserSwitchObserver;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$100;-><init>()V
@@ -2107,6 +2182,8 @@
 HSPLandroid/app/SystemServiceRegistry$108;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$109;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$10;-><init>()V
+HSPLandroid/app/SystemServiceRegistry$10;->createService(Landroid/app/ContextImpl;)Landroid/bluetooth/BluetoothManager;
+HSPLandroid/app/SystemServiceRegistry$10;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$110;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$110;->createService(Landroid/app/ContextImpl;)Landroid/app/timedetector/TimeDetector;
 HSPLandroid/app/SystemServiceRegistry$110;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2203,6 +2280,8 @@
 HSPLandroid/app/SystemServiceRegistry$3;->createService(Landroid/app/ContextImpl;)Landroid/accounts/AccountManager;
 HSPLandroid/app/SystemServiceRegistry$3;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$40;-><init>()V
+HSPLandroid/app/SystemServiceRegistry$40;->createService(Landroid/app/ContextImpl;)Landroid/app/StatsManager;
+HSPLandroid/app/SystemServiceRegistry$40;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$41;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$41;->createService(Landroid/app/ContextImpl;)Landroid/app/StatusBarManager;
 HSPLandroid/app/SystemServiceRegistry$41;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2257,6 +2336,8 @@
 HSPLandroid/app/SystemServiceRegistry$5;->createService(Landroid/app/ContextImpl;)Landroid/app/ActivityTaskManager;
 HSPLandroid/app/SystemServiceRegistry$5;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$60;-><init>()V
+HSPLandroid/app/SystemServiceRegistry$60;->createService()Landroid/net/wifi/p2p/WifiP2pManager;
+HSPLandroid/app/SystemServiceRegistry$60;->createService()Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$61;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$62;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$63;-><init>()V
@@ -2276,6 +2357,8 @@
 HSPLandroid/app/SystemServiceRegistry$69;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$6;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$70;-><init>()V
+HSPLandroid/app/SystemServiceRegistry$70;->createService(Landroid/app/ContextImpl;)Landroid/content/pm/LauncherApps;
+HSPLandroid/app/SystemServiceRegistry$70;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$71;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$71;->createService(Landroid/app/ContextImpl;)Landroid/content/RestrictionsManager;
 HSPLandroid/app/SystemServiceRegistry$71;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2331,6 +2414,8 @@
 HSPLandroid/app/SystemServiceRegistry$95;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$96;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$97;-><init>()V
+HSPLandroid/app/SystemServiceRegistry$97;->createService(Landroid/app/ContextImpl;)Landroid/os/health/SystemHealthManager;
+HSPLandroid/app/SystemServiceRegistry$97;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$98;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$99;-><init>()V
 HSPLandroid/app/SystemServiceRegistry$9;-><init>()V
@@ -2347,12 +2432,12 @@
 HSPLandroid/app/TaskStackListener;->onTaskCreated(ILandroid/content/ComponentName;)V
 HSPLandroid/app/TaskStackListener;->onTaskDescriptionChanged(ILandroid/app/ActivityManager$TaskDescription;)V
 HSPLandroid/app/TaskStackListener;->onTaskDescriptionChanged(Landroid/app/ActivityManager$RunningTaskInfo;)V
-PLandroid/app/TaskStackListener;->onTaskMovedToFront(I)V
-PLandroid/app/TaskStackListener;->onTaskMovedToFront(Landroid/app/ActivityManager$RunningTaskInfo;)V
+HPLandroid/app/TaskStackListener;->onTaskMovedToFront(I)V
+HPLandroid/app/TaskStackListener;->onTaskMovedToFront(Landroid/app/ActivityManager$RunningTaskInfo;)V
 HSPLandroid/app/TaskStackListener;->onTaskRemovalStarted(I)V
 HSPLandroid/app/TaskStackListener;->onTaskRemovalStarted(Landroid/app/ActivityManager$RunningTaskInfo;)V
 HSPLandroid/app/TaskStackListener;->onTaskRemoved(I)V
-PLandroid/app/TaskStackListener;->onTaskSnapshotChanged(ILandroid/app/ActivityManager$TaskSnapshot;)V
+HPLandroid/app/TaskStackListener;->onTaskSnapshotChanged(ILandroid/app/ActivityManager$TaskSnapshot;)V
 HSPLandroid/app/UiModeManager;->getCurrentModeType()I
 HSPLandroid/app/UiModeManager;->getNightMode()I
 HSPLandroid/app/UriGrantsManager$1;-><init>()V
@@ -2360,7 +2445,7 @@
 HSPLandroid/app/UriGrantsManager$1;->create()Ljava/lang/Object;
 HSPLandroid/app/UriGrantsManager;->getService()Landroid/app/IUriGrantsManager;
 HSPLandroid/app/UserSwitchObserver;-><init>()V
-PLandroid/app/UserSwitchObserver;->onForegroundProfileSwitch(I)V
+HPLandroid/app/UserSwitchObserver;->onForegroundProfileSwitch(I)V
 HSPLandroid/app/UserSwitchObserver;->onLockedBootComplete(I)V
 HSPLandroid/app/WallpaperColors$1;-><init>()V
 HSPLandroid/app/WallpaperColors$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/WallpaperColors;
@@ -2374,16 +2459,21 @@
 HSPLandroid/app/WallpaperInfo;->getPackageName()Ljava/lang/String;
 HSPLandroid/app/WallpaperInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/WallpaperManager$Globals;->forgetLoadedWallpaper()V
+HSPLandroid/app/WallpaperManager$Globals;->getWallpaperColors(III)Landroid/app/WallpaperColors;
 HSPLandroid/app/WallpaperManager;->getDefaultWallpaperComponent(Landroid/content/Context;)Landroid/content/ComponentName;
+HSPLandroid/app/WallpaperManager;->getWallpaperColors(I)Landroid/app/WallpaperColors;
+HSPLandroid/app/WallpaperManager;->getWallpaperColors(II)Landroid/app/WallpaperColors;
 HSPLandroid/app/WallpaperManager;->getWallpaperFile(II)Landroid/os/ParcelFileDescriptor;
 HSPLandroid/app/WallpaperManager;->getWallpaperIdForUser(II)I
 HSPLandroid/app/WallpaperManager;->initGlobals(Landroid/app/IWallpaperManager;Landroid/os/Looper;)V
+HPLandroid/app/WallpaperManager;->isWallpaperBackupEligible(I)Z
 HSPLandroid/app/WindowConfiguration$1;-><init>()V
 HSPLandroid/app/WindowConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/WindowConfiguration;-><init>()V
 HSPLandroid/app/WindowConfiguration;->activityTypeToString(I)Ljava/lang/String;
 HSPLandroid/app/WindowConfiguration;->canReceiveKeys()Z
+HPLandroid/app/WindowConfiguration;->canResizeTask()Z
 HSPLandroid/app/WindowConfiguration;->compareTo(Landroid/app/WindowConfiguration;)I
 HSPLandroid/app/WindowConfiguration;->diff(Landroid/app/WindowConfiguration;Z)J
 HSPLandroid/app/WindowConfiguration;->equals(Ljava/lang/Object;)Z
@@ -2430,24 +2520,26 @@
 PLandroid/app/admin/DevicePolicyEventLogger;->createEvent(I)Landroid/app/admin/DevicePolicyEventLogger;
 PLandroid/app/admin/DevicePolicyEventLogger;->write()V
 HSPLandroid/app/admin/DevicePolicyManager;->checkDeviceIdentifierAccessAsUser(Ljava/lang/String;I)Z
+HPLandroid/app/admin/DevicePolicyManager;->getAccountTypesWithManagementDisabledAsUser(I)[Ljava/lang/String;
 HSPLandroid/app/admin/DevicePolicyManager;->getDeviceOwnerComponentInner(Z)Landroid/content/ComponentName;
 HSPLandroid/app/admin/DevicePolicyManager;->getDeviceOwnerComponentOnAnyUser()Landroid/content/ComponentName;
 HSPLandroid/app/admin/DevicePolicyManager;->getGuestUserDisabled(Landroid/content/ComponentName;)Z
 HSPLandroid/app/admin/DevicePolicyManager;->getKeyguardDisabledFeatures(Landroid/content/ComponentName;I)I
 HSPLandroid/app/admin/DevicePolicyManager;->getMaximumTimeToLock(Landroid/content/ComponentName;I)J
+HSPLandroid/app/admin/DevicePolicyManager;->getPasswordQuality(Landroid/content/ComponentName;I)I
 HSPLandroid/app/admin/DevicePolicyManager;->getProfileOwnerAsUser(I)Landroid/content/ComponentName;
-PLandroid/app/admin/DevicePolicyManager;->getProfileOwnerAsUser(Landroid/os/UserHandle;)Landroid/content/ComponentName;
-PLandroid/app/admin/DevicePolicyManager;->getRequiredStrongAuthTimeout(Landroid/content/ComponentName;I)J
+HPLandroid/app/admin/DevicePolicyManager;->getProfileOwnerAsUser(Landroid/os/UserHandle;)Landroid/content/ComponentName;
+HPLandroid/app/admin/DevicePolicyManager;->getRequiredStrongAuthTimeout(Landroid/content/ComponentName;I)J
 HSPLandroid/app/admin/DevicePolicyManager;->getStorageEncryptionStatus()I
 HSPLandroid/app/admin/DevicePolicyManager;->getStorageEncryptionStatus(I)I
 HSPLandroid/app/admin/DevicePolicyManager;->isDeviceManaged()Z
 HSPLandroid/app/admin/DevicePolicyManager;->isDeviceOwnerApp(Ljava/lang/String;)Z
 HSPLandroid/app/admin/DevicePolicyManager;->isDeviceOwnerAppOnCallingUser(Ljava/lang/String;)Z
-PLandroid/app/admin/DevicePolicyManager;->isDeviceProvisioned()Z
-PLandroid/app/admin/DevicePolicyManager;->isNotificationListenerServicePermitted(Ljava/lang/String;I)Z
+HPLandroid/app/admin/DevicePolicyManager;->isDeviceProvisioned()Z
+HPLandroid/app/admin/DevicePolicyManager;->isNotificationListenerServicePermitted(Ljava/lang/String;I)Z
 HSPLandroid/app/admin/DevicePolicyManager;->isProfileOwnerApp(Ljava/lang/String;)Z
 HSPLandroid/app/admin/DevicePolicyManager;->myUserId()I
-PLandroid/app/admin/DevicePolicyManager;->setActivePasswordState(Landroid/app/admin/PasswordMetrics;I)V
+HPLandroid/app/admin/DevicePolicyManager;->setActivePasswordState(Landroid/app/admin/PasswordMetrics;I)V
 PLandroid/app/admin/IDeviceAdminService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/admin/IDeviceAdminService;
 HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->checkDeviceIdentifierAccess(Ljava/lang/String;III)Z
 HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->getDeviceOwnerComponent(Z)Landroid/content/ComponentName;
@@ -2457,10 +2549,10 @@
 HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->hasDeviceOwner()Z
 HSPLandroid/app/admin/IDevicePolicyManager$Stub;-><init>()V
 HSPLandroid/app/admin/IDevicePolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/admin/IDevicePolicyManager;
-PLandroid/app/admin/IDevicePolicyManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/app/admin/IDevicePolicyManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/app/admin/IDevicePolicyManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/admin/PasswordMetrics$1;-><init>()V
-PLandroid/app/admin/PasswordMetrics;->computeForCredential(I[B)Landroid/app/admin/PasswordMetrics;
+HPLandroid/app/admin/PasswordMetrics;->computeForCredential(I[B)Landroid/app/admin/PasswordMetrics;
 HSPLandroid/app/admin/PasswordMetrics;->computeForPassword([B)Landroid/app/admin/PasswordMetrics;
 HSPLandroid/app/admin/PasswordMetrics;->maxLengthSequence([B)I
 HSPLandroid/app/admin/SecurityLog$SecurityEvent$1;-><init>()V
@@ -2473,8 +2565,8 @@
 HSPLandroid/app/assist/AssistContent;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/assist/AssistContent;->getClipData()Landroid/content/ClipData;
 HSPLandroid/app/assist/AssistContent;->getIntent()Landroid/content/Intent;
-PLandroid/app/assist/AssistContent;->writeToParcel(Landroid/os/Parcel;I)V
-PLandroid/app/assist/AssistContent;->writeToParcelInternal(Landroid/os/Parcel;I)V
+HPLandroid/app/assist/AssistContent;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/app/assist/AssistContent;->writeToParcelInternal(Landroid/os/Parcel;I)V
 HSPLandroid/app/assist/AssistStructure$1;-><init>()V
 HSPLandroid/app/assist/AssistStructure$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/assist/AssistStructure;
 HSPLandroid/app/assist/AssistStructure$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -2489,11 +2581,11 @@
 HSPLandroid/app/assist/AssistStructure$ParcelTransferWriter;->writeView(Landroid/app/assist/AssistStructure$ViewNode;Landroid/os/Parcel;Landroid/os/PooledStringWriter;I)V
 HSPLandroid/app/assist/AssistStructure$SendChannel;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/assist/AssistStructure$ViewNode;-><init>(Landroid/app/assist/AssistStructure$ParcelTransferReader;I)V
-PLandroid/app/assist/AssistStructure$ViewNode;->getAutofillId()Landroid/view/autofill/AutofillId;
+HPLandroid/app/assist/AssistStructure$ViewNode;->getAutofillId()Landroid/view/autofill/AutofillId;
 HPLandroid/app/assist/AssistStructure$ViewNode;->getAutofillType()I
 HSPLandroid/app/assist/AssistStructure$ViewNode;->getChildAt(I)Landroid/app/assist/AssistStructure$ViewNode;
 HSPLandroid/app/assist/AssistStructure$ViewNode;->getChildCount()I
-PLandroid/app/assist/AssistStructure$ViewNode;->setAutofillOverlay(Landroid/app/assist/AssistStructure$AutofillOverlay;)V
+HPLandroid/app/assist/AssistStructure$ViewNode;->setAutofillOverlay(Landroid/app/assist/AssistStructure$AutofillOverlay;)V
 HSPLandroid/app/assist/AssistStructure$ViewNode;->writeSelfToParcel(Landroid/os/Parcel;Landroid/os/PooledStringWriter;Z[F)I
 HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->getChildCount()I
 HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->newChild(I)Landroid/view/ViewStructure;
@@ -2510,6 +2602,7 @@
 HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->setId(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->setImportantForAutofill(I)V
 HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->setInputType(I)V
+HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->setLongClickable(Z)V
 HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->setMaxTextEms(I)V
 HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->setMaxTextLength(I)V
 HSPLandroid/app/assist/AssistStructure$ViewNodeBuilder;->setMinTextEms(I)V
@@ -2528,19 +2621,19 @@
 HSPLandroid/app/assist/AssistStructure;-><init>(Landroid/app/Activity;ZI)V
 HSPLandroid/app/assist/AssistStructure;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/assist/AssistStructure;->ensureData()V
-PLandroid/app/assist/AssistStructure;->ensureDataForAutofill()V
-PLandroid/app/assist/AssistStructure;->getFlags()I
+HPLandroid/app/assist/AssistStructure;->ensureDataForAutofill()V
+HPLandroid/app/assist/AssistStructure;->getFlags()I
 HSPLandroid/app/assist/AssistStructure;->getWindowNodeAt(I)Landroid/app/assist/AssistStructure$WindowNode;
 HSPLandroid/app/assist/AssistStructure;->getWindowNodeCount()I
-PLandroid/app/assist/AssistStructure;->sanitizeForParceling(Z)V
-PLandroid/app/assist/AssistStructure;->setActivityComponent(Landroid/content/ComponentName;)V
-PLandroid/app/assist/AssistStructure;->setHomeActivity(Z)V
-PLandroid/app/assist/AssistStructure;->setTaskId(I)V
+HPLandroid/app/assist/AssistStructure;->sanitizeForParceling(Z)V
+HPLandroid/app/assist/AssistStructure;->setActivityComponent(Landroid/content/ComponentName;)V
+HPLandroid/app/assist/AssistStructure;->setHomeActivity(Z)V
+HPLandroid/app/assist/AssistStructure;->setTaskId(I)V
 HSPLandroid/app/assist/AssistStructure;->waitForReady()Z
 HSPLandroid/app/assist/AssistStructure;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/backup/BackupAgent$BackupServiceBinder;->doBackup(Landroid/os/ParcelFileDescriptor;Landroid/os/ParcelFileDescriptor;Landroid/os/ParcelFileDescriptor;JLandroid/app/backup/IBackupCallback;I)V
-PLandroid/app/backup/BackupAgent$BackupServiceBinder;->doFullBackup(Landroid/os/ParcelFileDescriptor;JILandroid/app/backup/IBackupManager;I)V
-PLandroid/app/backup/BackupAgent$BackupServiceBinder;->doMeasureFullBackup(JILandroid/app/backup/IBackupManager;I)V
+HPLandroid/app/backup/BackupAgent$BackupServiceBinder;->doFullBackup(Landroid/os/ParcelFileDescriptor;JILandroid/app/backup/IBackupManager;I)V
+HPLandroid/app/backup/BackupAgent$BackupServiceBinder;->doMeasureFullBackup(JILandroid/app/backup/IBackupManager;I)V
 HSPLandroid/app/backup/BackupAgent$SharedPrefsSynchronizer;->run()V
 HSPLandroid/app/backup/BackupAgent;-><init>()V
 HSPLandroid/app/backup/BackupAgent;->attach(Landroid/content/Context;)V
@@ -2553,11 +2646,11 @@
 HSPLandroid/app/backup/BackupAgentHelper;-><init>()V
 HSPLandroid/app/backup/BackupAgentHelper;->addHelper(Ljava/lang/String;Landroid/app/backup/BackupHelper;)V
 HSPLandroid/app/backup/BackupAgentHelper;->onBackup(Landroid/os/ParcelFileDescriptor;Landroid/app/backup/BackupDataOutput;Landroid/os/ParcelFileDescriptor;)V
-PLandroid/app/backup/BackupDataInput;-><init>(Ljava/io/FileDescriptor;)V
-PLandroid/app/backup/BackupDataInput;->finalize()V
-PLandroid/app/backup/BackupDataInput;->getKey()Ljava/lang/String;
-PLandroid/app/backup/BackupDataInput;->readNextHeader()Z
-PLandroid/app/backup/BackupDataInput;->skipEntityData()V
+HPLandroid/app/backup/BackupDataInput;-><init>(Ljava/io/FileDescriptor;)V
+HPLandroid/app/backup/BackupDataInput;->finalize()V
+HPLandroid/app/backup/BackupDataInput;->getKey()Ljava/lang/String;
+HPLandroid/app/backup/BackupDataInput;->readNextHeader()Z
+HPLandroid/app/backup/BackupDataInput;->skipEntityData()V
 HSPLandroid/app/backup/BackupDataOutput;-><init>(Ljava/io/FileDescriptor;JI)V
 HSPLandroid/app/backup/BackupDataOutput;->finalize()V
 HSPLandroid/app/backup/BackupDataOutput;->setKeyPrefix(Ljava/lang/String;)V
@@ -2574,22 +2667,30 @@
 PLandroid/app/backup/BlobBackupHelper;->performBackup(Landroid/os/ParcelFileDescriptor;Landroid/app/backup/BackupDataOutput;Landroid/os/ParcelFileDescriptor;)V
 PLandroid/app/backup/BlobBackupHelper;->readOldState(Landroid/os/ParcelFileDescriptor;)Landroid/util/ArrayMap;
 PLandroid/app/backup/BlobBackupHelper;->writeBackupState(Landroid/util/ArrayMap;Landroid/os/ParcelFileDescriptor;)V
-PLandroid/app/backup/FullBackupDataOutput;-><init>(Landroid/os/ParcelFileDescriptor;JI)V
-PLandroid/app/backup/FullBackupDataOutput;->addSize(J)V
+HSPLandroid/app/backup/FileBackupHelperBase;->finalize()V
+HSPLandroid/app/backup/FileBackupHelperBase;->performBackup_checked(Landroid/os/ParcelFileDescriptor;Landroid/app/backup/BackupDataOutput;Landroid/os/ParcelFileDescriptor;[Ljava/lang/String;[Ljava/lang/String;)V
+HPLandroid/app/backup/FullBackupDataOutput;-><init>(Landroid/os/ParcelFileDescriptor;JI)V
+HPLandroid/app/backup/FullBackupDataOutput;->addSize(J)V
 PLandroid/app/backup/IBackupCallback$Stub;-><init>()V
 PLandroid/app/backup/IBackupCallback$Stub;->asBinder()Landroid/os/IBinder;
 PLandroid/app/backup/IBackupCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/backup/IBackupManager$Stub$Proxy;->dataChanged(Ljava/lang/String;)V
+HSPLandroid/app/backup/IBackupManager$Stub$Proxy;->isBackupServiceActive(I)Z
+HPLandroid/app/backup/IBackupManager$Stub$Proxy;->opCompleteForUser(IIJ)V
 HSPLandroid/app/backup/IBackupManager$Stub;-><init>()V
 HSPLandroid/app/backup/IBackupManager$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/backup/IBackupManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/backup/IBackupManager;
 HSPLandroid/app/backup/IBackupManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/backup/SharedPreferencesBackupHelper;-><init>(Landroid/content/Context;[Ljava/lang/String;)V
+HSPLandroid/app/backup/SharedPreferencesBackupHelper;->performBackup(Landroid/os/ParcelFileDescriptor;Landroid/app/backup/BackupDataOutput;Landroid/os/ParcelFileDescriptor;)V
 HSPLandroid/app/contentsuggestions/IContentSuggestionsManager$Stub;-><init>()V
 HSPLandroid/app/job/IJobCallback$Stub$Proxy;->acknowledgeStartMessage(IZ)V
 HSPLandroid/app/job/IJobCallback$Stub$Proxy;->acknowledgeStopMessage(IZ)V
+HSPLandroid/app/job/IJobCallback$Stub$Proxy;->completeWork(II)Z
+HSPLandroid/app/job/IJobCallback$Stub$Proxy;->dequeueWork(I)Landroid/app/job/JobWorkItem;
 HSPLandroid/app/job/IJobCallback$Stub$Proxy;->jobFinished(IZ)V
 HSPLandroid/app/job/IJobCallback$Stub;-><init>()V
-PLandroid/app/job/IJobCallback$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/app/job/IJobCallback$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/app/job/IJobCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/job/IJobScheduler$Stub$Proxy;->cancel(I)V
 HSPLandroid/app/job/IJobScheduler$Stub$Proxy;->enqueue(Landroid/app/job/JobInfo;Landroid/app/job/JobWorkItem;)I
@@ -2597,7 +2698,7 @@
 HSPLandroid/app/job/IJobScheduler$Stub$Proxy;->getPendingJob(I)Landroid/app/job/JobInfo;
 HSPLandroid/app/job/IJobScheduler$Stub$Proxy;->schedule(Landroid/app/job/JobInfo;)I
 HSPLandroid/app/job/IJobScheduler$Stub;-><init>()V
-PLandroid/app/job/IJobScheduler$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/app/job/IJobScheduler$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/app/job/IJobScheduler$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/job/IJobService$Stub$Proxy;->startJob(Landroid/app/job/JobParameters;)V
 HPLandroid/app/job/IJobService$Stub$Proxy;->stopJob(Landroid/app/job/JobParameters;)V
@@ -2620,11 +2721,13 @@
 HSPLandroid/app/job/JobInfo$Builder;->setRequiredNetworkType(I)Landroid/app/job/JobInfo$Builder;
 HSPLandroid/app/job/JobInfo$Builder;->setRequiresCharging(Z)Landroid/app/job/JobInfo$Builder;
 HSPLandroid/app/job/JobInfo$Builder;->setRequiresDeviceIdle(Z)Landroid/app/job/JobInfo$Builder;
+HSPLandroid/app/job/JobInfo$Builder;->setTriggerContentMaxDelay(J)Landroid/app/job/JobInfo$Builder;
 HSPLandroid/app/job/JobInfo$TriggerContentUri$1;-><init>()V
 HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/job/JobInfo$TriggerContentUri;
 HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->newArray(I)[Landroid/app/job/JobInfo$TriggerContentUri;
 HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->newArray(I)[Ljava/lang/Object;
+HSPLandroid/app/job/JobInfo$TriggerContentUri;-><init>(Landroid/net/Uri;I)V
 HPLandroid/app/job/JobInfo$TriggerContentUri;->equals(Ljava/lang/Object;)Z
 HPLandroid/app/job/JobInfo$TriggerContentUri;->hashCode()I
 HSPLandroid/app/job/JobInfo$TriggerContentUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -2662,6 +2765,8 @@
 HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/job/JobParameters;
 HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/job/JobParameters;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/job/JobParameters;->completeWork(Landroid/app/job/JobWorkItem;)V
+HSPLandroid/app/job/JobParameters;->dequeueWork()Landroid/app/job/JobWorkItem;
 HSPLandroid/app/job/JobParameters;->getCallback()Landroid/app/job/IJobCallback;
 HPLandroid/app/job/JobParameters;->getDebugStopReason()Ljava/lang/String;
 HSPLandroid/app/job/JobParameters;->getExtras()Landroid/os/PersistableBundle;
@@ -2684,7 +2789,9 @@
 HSPLandroid/app/job/JobWorkItem$1;-><init>()V
 HSPLandroid/app/job/JobWorkItem$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/job/JobWorkItem;
 HSPLandroid/app/job/JobWorkItem$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/job/JobWorkItem;-><init>(Landroid/content/Intent;)V
 HSPLandroid/app/job/JobWorkItem;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/job/JobWorkItem;->getIntent()Landroid/content/Intent;
 HSPLandroid/app/job/JobWorkItem;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/prediction/AppPredictionContext$1;-><init>()V
 HSPLandroid/app/prediction/AppPredictionContext$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/prediction/AppPredictionContext;
@@ -2709,7 +2816,7 @@
 HSPLandroid/app/prediction/AppTargetId;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/prediction/IPredictionCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/prediction/IPredictionManager$Stub;-><init>()V
-PLandroid/app/prediction/IPredictionManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/app/prediction/IPredictionManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/role/-$$Lambda$RoleControllerManager$GrantDefaultRolesRequest$Qrnu382yknLH4_TvruMvYuK_N8M;->run()V
 HSPLandroid/app/role/-$$Lambda$RoleControllerManager$GrantDefaultRolesRequest$uMND2yv3BzXWyrtureF8K8b0f0A;->onResult(Landroid/os/Bundle;)V
 HSPLandroid/app/role/-$$Lambda$RoleControllerManager$RemoteService$45dMO3SdHJhfBB_YKrC44Sznmoo;-><init>()V
@@ -2742,9 +2849,9 @@
 HSPLandroid/app/servertransaction/ActivityRelaunchItem;->recycle()V
 HSPLandroid/app/servertransaction/ActivityRelaunchItem;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/servertransaction/ActivityResultItem$1;-><init>()V
-PLandroid/app/servertransaction/ActivityResultItem;->obtain(Ljava/util/List;)Landroid/app/servertransaction/ActivityResultItem;
-PLandroid/app/servertransaction/ActivityResultItem;->recycle()V
-PLandroid/app/servertransaction/ActivityResultItem;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/app/servertransaction/ActivityResultItem;->obtain(Ljava/util/List;)Landroid/app/servertransaction/ActivityResultItem;
+HPLandroid/app/servertransaction/ActivityResultItem;->recycle()V
+HPLandroid/app/servertransaction/ActivityResultItem;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/servertransaction/BaseClientRequest;->postExecute(Landroid/app/ClientTransactionHandler;Landroid/os/IBinder;Landroid/app/servertransaction/PendingTransactionActions;)V
 HSPLandroid/app/servertransaction/BaseClientRequest;->preExecute(Landroid/app/ClientTransactionHandler;Landroid/os/IBinder;)V
 HSPLandroid/app/servertransaction/ClientTransaction$1;-><init>()V
@@ -2864,6 +2971,7 @@
 HSPLandroid/app/servertransaction/WindowVisibilityItem;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->checkSlicePermission(Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;II[Ljava/lang/String;)I
 HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->getPinnedSlices(Ljava/lang/String;)[Landroid/net/Uri;
+HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->getPinnedSpecs(Landroid/net/Uri;Ljava/lang/String;)[Landroid/app/slice/SliceSpec;
 HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->grantSlicePermission(Ljava/lang/String;Ljava/lang/String;Landroid/net/Uri;)V
 HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->pinSlice(Ljava/lang/String;Landroid/net/Uri;[Landroid/app/slice/SliceSpec;Landroid/os/IBinder;)V
 HSPLandroid/app/slice/ISliceManager$Stub;-><init>()V
@@ -2881,18 +2989,25 @@
 HSPLandroid/app/slice/Slice$Builder;->build()Landroid/app/slice/Slice;
 HSPLandroid/app/slice/Slice;->getHints()Ljava/util/List;
 HSPLandroid/app/slice/Slice;->getItems()Ljava/util/List;
+HSPLandroid/app/slice/Slice;->getSpec()Landroid/app/slice/SliceSpec;
+HSPLandroid/app/slice/Slice;->getUri()Landroid/net/Uri;
+HSPLandroid/app/slice/Slice;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/slice/SliceItem$1;-><init>()V
 HSPLandroid/app/slice/SliceItem;->getAction()Landroid/app/PendingIntent;
+HSPLandroid/app/slice/SliceItem;->getFormat()Ljava/lang/String;
 HSPLandroid/app/slice/SliceItem;->getHints()Ljava/util/List;
 HSPLandroid/app/slice/SliceItem;->getIcon()Landroid/graphics/drawable/Icon;
 HSPLandroid/app/slice/SliceItem;->getLong()J
 HSPLandroid/app/slice/SliceItem;->getSlice()Landroid/app/slice/Slice;
+HSPLandroid/app/slice/SliceItem;->getSubType()Ljava/lang/String;
 HSPLandroid/app/slice/SliceItem;->getText()Ljava/lang/CharSequence;
+HSPLandroid/app/slice/SliceItem;->writeObj(Landroid/os/Parcel;ILjava/lang/Object;Ljava/lang/String;)V
 HSPLandroid/app/slice/SliceManager;->$closeResource(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V
 HSPLandroid/app/slice/SliceManager;->bindSlice(Landroid/net/Uri;Ljava/util/Set;)Landroid/app/slice/Slice;
 HSPLandroid/app/slice/SliceManager;->checkSlicePermission(Landroid/net/Uri;II)I
 HSPLandroid/app/slice/SliceManager;->enforceSlicePermission(Landroid/net/Uri;Ljava/lang/String;II[Ljava/lang/String;)V
 HSPLandroid/app/slice/SliceManager;->getPinnedSlices()Ljava/util/List;
+HSPLandroid/app/slice/SliceManager;->getPinnedSpecs(Landroid/net/Uri;)Ljava/util/Set;
 HSPLandroid/app/slice/SliceManager;->grantSlicePermission(Ljava/lang/String;Landroid/net/Uri;)V
 HSPLandroid/app/slice/SliceManager;->pinSlice(Landroid/net/Uri;Ljava/util/Set;)V
 HSPLandroid/app/slice/SliceProvider;-><init>([Ljava/lang/String;)V
@@ -2927,6 +3042,7 @@
 HSPLandroid/app/trust/ITrustListener$Stub$Proxy;->onTrustManagedChanged(ZI)V
 HSPLandroid/app/trust/ITrustManager$Stub$Proxy;->isDeviceLocked(I)Z
 HSPLandroid/app/trust/ITrustManager$Stub;-><init>()V
+HPLandroid/app/trust/ITrustManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/app/trust/ITrustManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/app/usage/AppStandbyInfo$1;-><init>()V
 HSPLandroid/app/usage/AppStandbyInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/AppStandbyInfo;
@@ -2960,6 +3076,7 @@
 HSPLandroid/app/usage/ICacheQuotaService$Stub$Proxy;->computeCacheQuotaHints(Landroid/os/RemoteCallback;Ljava/util/List;)V
 HSPLandroid/app/usage/ICacheQuotaService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/usage/ICacheQuotaService;
 HSPLandroid/app/usage/ICacheQuotaService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/usage/IStorageStatsManager$Stub$Proxy;->getFreeBytes(Ljava/lang/String;Ljava/lang/String;)J
 HSPLandroid/app/usage/IStorageStatsManager$Stub$Proxy;->queryStatsForPackage(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)Landroid/app/usage/StorageStats;
 HSPLandroid/app/usage/IStorageStatsManager$Stub;-><init>()V
 HPLandroid/app/usage/IStorageStatsManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -2967,23 +3084,24 @@
 HSPLandroid/app/usage/IUsageStatsManager$Stub$Proxy;->queryUsageStats(IJJLjava/lang/String;)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/app/usage/IUsageStatsManager$Stub;-><init>()V
 HSPLandroid/app/usage/IUsageStatsManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/usage/IUsageStatsManager;
-PLandroid/app/usage/IUsageStatsManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/app/usage/IUsageStatsManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/app/usage/IUsageStatsManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/app/usage/NetworkStatsManager$CallbackHandler;->handleMessage(Landroid/os/Message;)V
 HSPLandroid/app/usage/NetworkStatsManager;->registerUsageCallback(Landroid/net/NetworkTemplate;IJLandroid/app/usage/NetworkStatsManager$UsageCallback;Landroid/os/Handler;)V
-PLandroid/app/usage/NetworkStatsManager;->unregisterUsageCallback(Landroid/app/usage/NetworkStatsManager$UsageCallback;)V
+HPLandroid/app/usage/NetworkStatsManager;->unregisterUsageCallback(Landroid/app/usage/NetworkStatsManager$UsageCallback;)V
 HSPLandroid/app/usage/StorageStats$1;-><init>()V
 HSPLandroid/app/usage/StorageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/StorageStats;
 HSPLandroid/app/usage/StorageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/usage/StorageStats;->getAppBytes()J
 HSPLandroid/app/usage/StorageStats;->getCacheBytes()J
 HSPLandroid/app/usage/StorageStats;->getDataBytes()J
-PLandroid/app/usage/StorageStatsManager;->getCacheBytes(Ljava/lang/String;)J
-PLandroid/app/usage/StorageStatsManager;->getCacheBytes(Ljava/util/UUID;)J
-PLandroid/app/usage/StorageStatsManager;->isQuotaSupported(Ljava/lang/String;)Z
-PLandroid/app/usage/StorageStatsManager;->isQuotaSupported(Ljava/util/UUID;)Z
-PLandroid/app/usage/StorageStatsManager;->queryExternalStatsForUser(Ljava/lang/String;Landroid/os/UserHandle;)Landroid/app/usage/ExternalStorageStats;
-PLandroid/app/usage/StorageStatsManager;->queryExternalStatsForUser(Ljava/util/UUID;Landroid/os/UserHandle;)Landroid/app/usage/ExternalStorageStats;
+HPLandroid/app/usage/StorageStatsManager;->getCacheBytes(Ljava/lang/String;)J
+HPLandroid/app/usage/StorageStatsManager;->getCacheBytes(Ljava/util/UUID;)J
+HSPLandroid/app/usage/StorageStatsManager;->getFreeBytes(Ljava/util/UUID;)J
+HPLandroid/app/usage/StorageStatsManager;->isQuotaSupported(Ljava/lang/String;)Z
+HPLandroid/app/usage/StorageStatsManager;->isQuotaSupported(Ljava/util/UUID;)Z
+HPLandroid/app/usage/StorageStatsManager;->queryExternalStatsForUser(Ljava/lang/String;Landroid/os/UserHandle;)Landroid/app/usage/ExternalStorageStats;
+HPLandroid/app/usage/StorageStatsManager;->queryExternalStatsForUser(Ljava/util/UUID;Landroid/os/UserHandle;)Landroid/app/usage/ExternalStorageStats;
 HSPLandroid/app/usage/StorageStatsManager;->queryStatsForPackage(Ljava/util/UUID;Ljava/lang/String;Landroid/os/UserHandle;)Landroid/app/usage/StorageStats;
 HSPLandroid/app/usage/TimeSparseArray;-><init>()V
 HSPLandroid/app/usage/TimeSparseArray;->closestIndexOnOrAfter(J)I
@@ -3004,6 +3122,7 @@
 HSPLandroid/app/usage/UsageStats;-><init>()V
 HSPLandroid/app/usage/UsageStats;-><init>(Landroid/app/usage/UsageStats;)V
 HSPLandroid/app/usage/UsageStats;->eventMapToBundle(Landroid/util/ArrayMap;)Landroid/os/Bundle;
+HSPLandroid/app/usage/UsageStats;->getLastTimeUsed()J
 HSPLandroid/app/usage/UsageStats;->getPackageName()Ljava/lang/String;
 HSPLandroid/app/usage/UsageStats;->getTotalTimeInForeground()J
 HSPLandroid/app/usage/UsageStats;->update(Ljava/lang/String;JII)V
@@ -3013,7 +3132,7 @@
 HSPLandroid/app/usage/UsageStatsManager;->onCarrierPrivilegedAppsChanged()V
 HSPLandroid/app/usage/UsageStatsManager;->queryUsageStats(IJJ)Ljava/util/List;
 HPLandroid/app/usage/UsageStatsManager;->reasonToString(I)Ljava/lang/String;
-PLandroid/app/usage/UsageStatsManager;->usageSourceToString(I)Ljava/lang/String;
+HPLandroid/app/usage/UsageStatsManager;->usageSourceToString(I)Ljava/lang/String;
 HSPLandroid/app/usage/UsageStatsManagerInternal$AppIdleStateChangeListener;->onUserInteractionStarted(Ljava/lang/String;I)V
 HSPLandroid/appwidget/AppWidgetManager;->getAppWidgetIds(Landroid/content/ComponentName;)[I
 HSPLandroid/appwidget/AppWidgetManager;->getInstance(Landroid/content/Context;)Landroid/appwidget/AppWidgetManager;
@@ -3027,10 +3146,11 @@
 HSPLandroid/bluetooth/BluetoothA2dp;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 HSPLandroid/bluetooth/BluetoothA2dp;->doBind()Z
 HSPLandroid/bluetooth/BluetoothA2dp;->getActiveDevice()Landroid/bluetooth/BluetoothDevice;
+HPLandroid/bluetooth/BluetoothA2dp;->getCodecStatus(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothCodecStatus;
 HSPLandroid/bluetooth/BluetoothA2dp;->getConnectedDevices()Ljava/util/List;
 HSPLandroid/bluetooth/BluetoothActivityEnergyInfo$1;-><init>()V
-PLandroid/bluetooth/BluetoothActivityEnergyInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/bluetooth/BluetoothActivityEnergyInfo;
-PLandroid/bluetooth/BluetoothActivityEnergyInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/bluetooth/BluetoothActivityEnergyInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/bluetooth/BluetoothActivityEnergyInfo;
+HPLandroid/bluetooth/BluetoothActivityEnergyInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HPLandroid/bluetooth/BluetoothActivityEnergyInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/bluetooth/BluetoothAdapter$1;-><init>()V
 HSPLandroid/bluetooth/BluetoothAdapter$2;->onBluetoothServiceUp(Landroid/bluetooth/IBluetooth;)V
@@ -3050,6 +3170,10 @@
 HSPLandroid/bluetooth/BluetoothClass$1;-><init>()V
 HSPLandroid/bluetooth/BluetoothClass;->toString()Ljava/lang/String;
 HSPLandroid/bluetooth/BluetoothCodecConfig$1;-><init>()V
+HPLandroid/bluetooth/BluetoothCodecConfig$1;->createFromParcel(Landroid/os/Parcel;)Landroid/bluetooth/BluetoothCodecConfig;
+HPLandroid/bluetooth/BluetoothCodecConfig$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/bluetooth/BluetoothCodecConfig$1;->newArray(I)[Landroid/bluetooth/BluetoothCodecConfig;
+HPLandroid/bluetooth/BluetoothCodecConfig$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/bluetooth/BluetoothDevice$1;-><init>()V
 HSPLandroid/bluetooth/BluetoothDevice$2;-><init>()V
 HSPLandroid/bluetooth/BluetoothDevice$2;->createFromParcel(Landroid/os/Parcel;)Landroid/bluetooth/BluetoothDevice;
@@ -3068,12 +3192,15 @@
 HSPLandroid/bluetooth/BluetoothDevice;->getService()Landroid/bluetooth/IBluetooth;
 HSPLandroid/bluetooth/BluetoothDevice;->getUuids()[Landroid/os/ParcelUuid;
 HSPLandroid/bluetooth/BluetoothDevice;->hashCode()I
+HSPLandroid/bluetooth/BluetoothDevice;->isConnected()Z
 HSPLandroid/bluetooth/BluetoothDevice;->toString()Ljava/lang/String;
 HSPLandroid/bluetooth/BluetoothHeadset$1;->onBluetoothStateChange(Z)V
 HSPLandroid/bluetooth/BluetoothHeadset$2;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
+HSPLandroid/bluetooth/BluetoothHeadset$2;->onServiceDisconnected(Landroid/content/ComponentName;)V
 HSPLandroid/bluetooth/BluetoothHeadset$3;->handleMessage(Landroid/os/Message;)V
 HSPLandroid/bluetooth/BluetoothHeadset;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 HSPLandroid/bluetooth/BluetoothHeadset;->doBind()Z
+HSPLandroid/bluetooth/BluetoothHeadset;->doUnbind()V
 HSPLandroid/bluetooth/BluetoothHeadset;->getActiveDevice()Landroid/bluetooth/BluetoothDevice;
 HSPLandroid/bluetooth/BluetoothHeadset;->getConnectedDevices()Ljava/util/List;
 HSPLandroid/bluetooth/BluetoothHeadset;->phoneStateChanged(IIILjava/lang/String;ILjava/lang/String;)V
@@ -3088,6 +3215,7 @@
 HSPLandroid/bluetooth/BluetoothHidDevice;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 HSPLandroid/bluetooth/BluetoothHidDevice;->doBind()Z
 HSPLandroid/bluetooth/BluetoothHidDevice;->getConnectedDevices()Ljava/util/List;
+HSPLandroid/bluetooth/BluetoothHidDevice;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
 HSPLandroid/bluetooth/BluetoothHidHost$2;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
 HSPLandroid/bluetooth/BluetoothHidHost;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 HSPLandroid/bluetooth/BluetoothHidHost;->doBind()Z
@@ -3096,12 +3224,15 @@
 HSPLandroid/bluetooth/BluetoothMap;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 HSPLandroid/bluetooth/BluetoothMap;->doBind()Z
 HSPLandroid/bluetooth/BluetoothMap;->getConnectedDevices()Ljava/util/List;
+HSPLandroid/bluetooth/BluetoothMap;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
 HSPLandroid/bluetooth/BluetoothPan$2;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
 HSPLandroid/bluetooth/BluetoothPan;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 HSPLandroid/bluetooth/BluetoothPan;->doBind()Z
 HSPLandroid/bluetooth/BluetoothPbap$2;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
 HSPLandroid/bluetooth/BluetoothPbap;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothPbap$ServiceListener;)V
 HSPLandroid/bluetooth/BluetoothPbap;->doBind()Z
+HSPLandroid/bluetooth/BluetoothPbap;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
+HSPLandroid/bluetooth/BluetoothPbap;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
 HSPLandroid/bluetooth/BluetoothSap$2;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
 HSPLandroid/bluetooth/BluetoothSap;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
 HSPLandroid/bluetooth/BluetoothSap;->doBind()Z
@@ -3113,6 +3244,7 @@
 HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->enable()Z
 HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->getBondState(Landroid/bluetooth/BluetoothDevice;)I
 HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->getBondedDevices()[Landroid/bluetooth/BluetoothDevice;
+HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
 HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->getName()Ljava/lang/String;
 HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->getPhonebookAccessPermission(Landroid/bluetooth/BluetoothDevice;)I
 HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->getRemoteAlias(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String;
@@ -3128,6 +3260,7 @@
 HPLandroid/bluetooth/IBluetooth$Stub$Proxy;->requestActivityInfo(Landroid/os/ResultReceiver;)V
 HSPLandroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth;
 HSPLandroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getActiveDevice()Landroid/bluetooth/BluetoothDevice;
+HPLandroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getCodecStatus(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothCodecStatus;
 HSPLandroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
 HSPLandroid/bluetooth/IBluetoothCallback$Stub;-><init>()V
 HSPLandroid/bluetooth/IBluetoothCallback$Stub;->asBinder()Landroid/os/IBinder;
@@ -3138,6 +3271,7 @@
 HSPLandroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
 HSPLandroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->phoneStateChanged(IIILjava/lang/String;ILjava/lang/String;)V
 HSPLandroid/bluetooth/IBluetoothHeadsetPhone$Stub;-><init>()V
+HPLandroid/bluetooth/IBluetoothHeadsetPhone$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getActiveDevices()Ljava/util/List;
 HSPLandroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
 HSPLandroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getHiSyncId(Landroid/bluetooth/BluetoothDevice;)J
@@ -3148,6 +3282,7 @@
 HSPLandroid/bluetooth/IBluetoothManager$Stub$Proxy;->registerAdapter(Landroid/bluetooth/IBluetoothManagerCallback;)Landroid/bluetooth/IBluetooth;
 HSPLandroid/bluetooth/IBluetoothManager$Stub$Proxy;->registerStateChangeCallback(Landroid/bluetooth/IBluetoothStateChangeCallback;)V
 HSPLandroid/bluetooth/IBluetoothManager$Stub;-><init>()V
+HPLandroid/bluetooth/IBluetoothManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/bluetooth/IBluetoothManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/bluetooth/IBluetoothManagerCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/bluetooth/IBluetoothManagerCallback$Stub$Proxy;->onBluetoothServiceUp(Landroid/bluetooth/IBluetooth;)V
@@ -3171,6 +3306,7 @@
 HSPLandroid/bluetooth/le/ScanSettings$1;-><init>()V
 HSPLandroid/companion/ICompanionDeviceManager$Stub;-><init>()V
 HSPLandroid/companion/ICompanionDeviceManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/companion/ICompanionDeviceManager;
+HPLandroid/companion/ICompanionDeviceManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/content/-$$Lambda$AbstractThreadedSyncAdapter$ISyncAdapterImpl$L6ZtOCe8gjKwJj0908ytPlrD8Rc;-><init>()V
 HSPLandroid/content/AsyncQueryHandler$WorkerHandler;-><init>(Landroid/content/AsyncQueryHandler;Landroid/os/Looper;)V
 HSPLandroid/content/AsyncQueryHandler$WorkerHandler;->handleMessage(Landroid/os/Message;)V
@@ -3178,6 +3314,14 @@
 HSPLandroid/content/AsyncQueryHandler;->createHandler(Landroid/os/Looper;)Landroid/os/Handler;
 HSPLandroid/content/AsyncQueryHandler;->handleMessage(Landroid/os/Message;)V
 HSPLandroid/content/AsyncQueryHandler;->startQuery(ILjava/lang/Object;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/content/AsyncTaskLoader$LoadTask;->doInBackground([Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/content/AsyncTaskLoader$LoadTask;->doInBackground([Ljava/lang/Void;)Ljava/lang/Object;
+HSPLandroid/content/AsyncTaskLoader$LoadTask;->onPostExecute(Ljava/lang/Object;)V
+HSPLandroid/content/AsyncTaskLoader;->dispatchOnLoadComplete(Landroid/content/AsyncTaskLoader$LoadTask;Ljava/lang/Object;)V
+HSPLandroid/content/AsyncTaskLoader;->executePendingTask()V
+HSPLandroid/content/AsyncTaskLoader;->onCancelLoad()Z
+HSPLandroid/content/AsyncTaskLoader;->onForceLoad()V
+HSPLandroid/content/AsyncTaskLoader;->onLoadInBackground()Ljava/lang/Object;
 HSPLandroid/content/AutofillOptions$1;-><init>()V
 HSPLandroid/content/AutofillOptions$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/AutofillOptions;
 HSPLandroid/content/AutofillOptions$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3186,12 +3330,13 @@
 HSPLandroid/content/BroadcastReceiver$PendingResult$1;->run()V
 HSPLandroid/content/BroadcastReceiver$PendingResult;-><init>(ILjava/lang/String;Landroid/os/Bundle;IZZLandroid/os/IBinder;II)V
 HSPLandroid/content/BroadcastReceiver$PendingResult;->finish()V
-PLandroid/content/BroadcastReceiver$PendingResult;->getSendingUserId()I
+HPLandroid/content/BroadcastReceiver$PendingResult;->getSendingUserId()I
 HSPLandroid/content/BroadcastReceiver$PendingResult;->sendFinished(Landroid/app/IActivityManager;)V
 HSPLandroid/content/BroadcastReceiver;-><init>()V
 HSPLandroid/content/BroadcastReceiver;->checkSynchronousHint()V
 HSPLandroid/content/BroadcastReceiver;->getSendingUserId()I
 HSPLandroid/content/BroadcastReceiver;->goAsync()Landroid/content/BroadcastReceiver$PendingResult;
+HSPLandroid/content/BroadcastReceiver;->isInitialStickyBroadcast()Z
 HSPLandroid/content/BroadcastReceiver;->isOrderedBroadcast()Z
 HSPLandroid/content/BroadcastReceiver;->setResultCode(I)V
 HSPLandroid/content/ClipData$1;-><init>()V
@@ -3217,12 +3362,12 @@
 HSPLandroid/content/ComponentName;-><init>(Landroid/content/Context;Ljava/lang/String;)V
 HSPLandroid/content/ComponentName;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/ComponentName;-><init>(Ljava/lang/String;Ljava/lang/String;)V
-PLandroid/content/ComponentName;->appendShortString(Ljava/lang/StringBuilder;)V
+HPLandroid/content/ComponentName;->appendShortString(Ljava/lang/StringBuilder;)V
 HSPLandroid/content/ComponentName;->compareTo(Landroid/content/ComponentName;)I
 HSPLandroid/content/ComponentName;->createRelative(Ljava/lang/String;Ljava/lang/String;)Landroid/content/ComponentName;
 HSPLandroid/content/ComponentName;->equals(Ljava/lang/Object;)Z
 HSPLandroid/content/ComponentName;->flattenToShortString()Ljava/lang/String;
-PLandroid/content/ComponentName;->flattenToShortString(Landroid/content/ComponentName;)Ljava/lang/String;
+HPLandroid/content/ComponentName;->flattenToShortString(Landroid/content/ComponentName;)Ljava/lang/String;
 HSPLandroid/content/ComponentName;->flattenToString()Ljava/lang/String;
 HSPLandroid/content/ComponentName;->getClassName()Ljava/lang/String;
 HSPLandroid/content/ComponentName;->getPackageName()Ljava/lang/String;
@@ -3238,6 +3383,7 @@
 HSPLandroid/content/ContentProvider$Transport;->bulkInsert(Ljava/lang/String;Landroid/net/Uri;[Landroid/content/ContentValues;)I
 HSPLandroid/content/ContentProvider$Transport;->call(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/Bundle;)Landroid/os/Bundle;
 HSPLandroid/content/ContentProvider$Transport;->canonicalize(Ljava/lang/String;Landroid/net/Uri;)Landroid/net/Uri;
+HSPLandroid/content/ContentProvider$Transport;->createCancellationSignal()Landroid/os/ICancellationSignal;
 HSPLandroid/content/ContentProvider$Transport;->delete(Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I
 HSPLandroid/content/ContentProvider$Transport;->enforceFilePermission(Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;Landroid/os/IBinder;)V
 HSPLandroid/content/ContentProvider$Transport;->getContentProvider()Landroid/content/ContentProvider;
@@ -3255,6 +3401,7 @@
 HSPLandroid/content/ContentProvider;->call(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/Bundle;)Landroid/os/Bundle;
 HPLandroid/content/ContentProvider;->canonicalize(Landroid/net/Uri;)Landroid/net/Uri;
 HSPLandroid/content/ContentProvider;->checkUser(IILandroid/content/Context;)Z
+HSPLandroid/content/ContentProvider;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
 HSPLandroid/content/ContentProvider;->enforceReadPermissionInner(Landroid/net/Uri;Ljava/lang/String;Landroid/os/IBinder;)I
 HSPLandroid/content/ContentProvider;->enforceWritePermissionInner(Landroid/net/Uri;Ljava/lang/String;Landroid/os/IBinder;)I
 HSPLandroid/content/ContentProvider;->getAuthorityWithoutUserId(Ljava/lang/String;)Ljava/lang/String;
@@ -3268,7 +3415,7 @@
 HSPLandroid/content/ContentProvider;->matchesOurAuthorities(Ljava/lang/String;)Z
 HSPLandroid/content/ContentProvider;->maybeAddUserId(Landroid/net/Uri;I)Landroid/net/Uri;
 HSPLandroid/content/ContentProvider;->onConfigurationChanged(Landroid/content/res/Configuration;)V
-PLandroid/content/ContentProvider;->onLowMemory()V
+HPLandroid/content/ContentProvider;->onLowMemory()V
 HSPLandroid/content/ContentProvider;->onTrimMemory(I)V
 HSPLandroid/content/ContentProvider;->openAssetFile(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;
 HSPLandroid/content/ContentProvider;->openTypedAssetFile(Landroid/net/Uri;Ljava/lang/String;Landroid/os/Bundle;)Landroid/content/res/AssetFileDescriptor;
@@ -3286,15 +3433,27 @@
 HSPLandroid/content/ContentProviderClient;->close()V
 HSPLandroid/content/ContentProviderClient;->closeInternal()Z
 HSPLandroid/content/ContentProviderClient;->finalize()V
+HSPLandroid/content/ContentProviderClient;->query(Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/content/ContentProviderClient;->query(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
+HSPLandroid/content/ContentProviderClient;->query(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
 HSPLandroid/content/ContentProviderClient;->release()Z
 HSPLandroid/content/ContentProviderClient;->setDetectNotResponding(J)V
 HSPLandroid/content/ContentProviderNative;->asBinder()Landroid/os/IBinder;
 HSPLandroid/content/ContentProviderNative;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/content/ContentProviderOperation$1;-><init>()V
+HSPLandroid/content/ContentProviderOperation$Builder;->build()Landroid/content/ContentProviderOperation;
+HSPLandroid/content/ContentProviderOperation$Builder;->withValue(Ljava/lang/String;Ljava/lang/Object;)Landroid/content/ContentProviderOperation$Builder;
+HSPLandroid/content/ContentProviderOperation;-><init>(Landroid/content/ContentProviderOperation$Builder;)V
+HSPLandroid/content/ContentProviderOperation;->apply(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
 HSPLandroid/content/ContentProviderOperation;->getUri()Landroid/net/Uri;
+HSPLandroid/content/ContentProviderOperation;->isReadOperation()Z
+HSPLandroid/content/ContentProviderOperation;->isWriteOperation()Z
+HSPLandroid/content/ContentProviderOperation;->newInsert(Landroid/net/Uri;)Landroid/content/ContentProviderOperation$Builder;
+HSPLandroid/content/ContentProviderOperation;->resolveSelectionArgsBackReferences([Landroid/content/ContentProviderResult;I)[Ljava/lang/String;
+HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;
 HSPLandroid/content/ContentProviderProxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/content/ContentProviderProxy;->call(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/Bundle;)Landroid/os/Bundle;
-PLandroid/content/ContentProviderProxy;->canonicalize(Ljava/lang/String;Landroid/net/Uri;)Landroid/net/Uri;
+HPLandroid/content/ContentProviderProxy;->canonicalize(Ljava/lang/String;Landroid/net/Uri;)Landroid/net/Uri;
 HSPLandroid/content/ContentProviderProxy;->createCancellationSignal()Landroid/os/ICancellationSignal;
 HSPLandroid/content/ContentProviderProxy;->delete(Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I
 HSPLandroid/content/ContentProviderProxy;->getType(Landroid/net/Uri;)Ljava/lang/String;
@@ -3317,12 +3476,13 @@
 HPLandroid/content/ContentResolver;->canonicalize(Landroid/net/Uri;)Landroid/net/Uri;
 HSPLandroid/content/ContentResolver;->createSqlQueryBundle(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/os/Bundle;
 HSPLandroid/content/ContentResolver;->delete(Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I
-PLandroid/content/ContentResolver;->getIsSyncableAsUser(Landroid/accounts/Account;Ljava/lang/String;I)I
-PLandroid/content/ContentResolver;->getMasterSyncAutomaticallyAsUser(I)Z
+HSPLandroid/content/ContentResolver;->getIsSyncable(Landroid/accounts/Account;Ljava/lang/String;)I
+HPLandroid/content/ContentResolver;->getIsSyncableAsUser(Landroid/accounts/Account;Ljava/lang/String;I)I
+HPLandroid/content/ContentResolver;->getMasterSyncAutomaticallyAsUser(I)Z
 HSPLandroid/content/ContentResolver;->getPackageName()Ljava/lang/String;
 HSPLandroid/content/ContentResolver;->getSyncAdapterPackagesForAuthorityAsUser(Ljava/lang/String;I)[Ljava/lang/String;
 HSPLandroid/content/ContentResolver;->getSyncAdapterTypesAsUser(I)[Landroid/content/SyncAdapterType;
-PLandroid/content/ContentResolver;->getSyncAutomaticallyAsUser(Landroid/accounts/Account;Ljava/lang/String;I)Z
+HPLandroid/content/ContentResolver;->getSyncAutomaticallyAsUser(Landroid/accounts/Account;Ljava/lang/String;I)Z
 HSPLandroid/content/ContentResolver;->getType(Landroid/net/Uri;)Ljava/lang/String;
 HSPLandroid/content/ContentResolver;->getUserId()I
 HSPLandroid/content/ContentResolver;->insert(Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
@@ -3342,7 +3502,7 @@
 HSPLandroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;)V
 HSPLandroid/content/ContentResolver;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/ContentObserver;I)V
 HSPLandroid/content/ContentResolver;->resolveUserId(Landroid/net/Uri;)I
-PLandroid/content/ContentResolver;->syncErrorToString(I)Ljava/lang/String;
+HPLandroid/content/ContentResolver;->syncErrorToString(I)Ljava/lang/String;
 HSPLandroid/content/ContentResolver;->unregisterContentObserver(Landroid/database/ContentObserver;)V
 HSPLandroid/content/ContentResolver;->update(Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
 HSPLandroid/content/ContentUris;->appendId(Landroid/net/Uri$Builder;J)Landroid/net/Uri$Builder;
@@ -3364,6 +3524,8 @@
 HSPLandroid/content/ContentValues;->getAsString(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/ContentValues;->keySet()Ljava/util/Set;
 HSPLandroid/content/ContentValues;->put(Ljava/lang/String;Ljava/lang/Boolean;)V
+HSPLandroid/content/ContentValues;->put(Ljava/lang/String;Ljava/lang/Double;)V
+HSPLandroid/content/ContentValues;->put(Ljava/lang/String;Ljava/lang/Float;)V
 HSPLandroid/content/ContentValues;->put(Ljava/lang/String;Ljava/lang/Integer;)V
 HSPLandroid/content/ContentValues;->put(Ljava/lang/String;Ljava/lang/Long;)V
 HSPLandroid/content/ContentValues;->put(Ljava/lang/String;Ljava/lang/String;)V
@@ -3371,11 +3533,13 @@
 HSPLandroid/content/ContentValues;->putNull(Ljava/lang/String;)V
 HSPLandroid/content/ContentValues;->remove(Ljava/lang/String;)V
 HSPLandroid/content/ContentValues;->size()I
+HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;
 HSPLandroid/content/Context;->assertRuntimeOverlayThemable()V
 HSPLandroid/content/Context;->getColor(I)I
 HSPLandroid/content/Context;->getColorStateList(I)Landroid/content/res/ColorStateList;
 HSPLandroid/content/Context;->getDrawable(I)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/Context;->getNextAutofillId()I
+HSPLandroid/content/Context;->getSharedPrefsFile(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/content/Context;->getString(I)Ljava/lang/String;
 HSPLandroid/content/Context;->getString(I[Ljava/lang/Object;)Ljava/lang/String;
 HSPLandroid/content/Context;->getSystemService(Ljava/lang/Class;)Ljava/lang/Object;
@@ -3421,6 +3585,7 @@
 HSPLandroid/content/ContextWrapper;->getDataDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getDatabasePath(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getDir(Ljava/lang/String;I)Ljava/io/File;
+HSPLandroid/content/ContextWrapper;->getDisplay()Landroid/view/Display;
 HSPLandroid/content/ContextWrapper;->getDisplayId()I
 HSPLandroid/content/ContextWrapper;->getExternalCacheDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getExternalFilesDir(Ljava/lang/String;)Ljava/io/File;
@@ -3436,6 +3601,7 @@
 HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;
 HSPLandroid/content/ContextWrapper;->getPackageName()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getResources()Landroid/content/res/Resources;
+HPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;
 HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
 HSPLandroid/content/ContextWrapper;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
@@ -3454,9 +3620,10 @@
 HSPLandroid/content/ContextWrapper;->sendBroadcast(Landroid/content/Intent;Ljava/lang/String;Landroid/os/Bundle;)V
 HSPLandroid/content/ContextWrapper;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V
 HSPLandroid/content/ContextWrapper;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;)V
-PLandroid/content/ContextWrapper;->sendOrderedBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;ILandroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V
+HPLandroid/content/ContextWrapper;->sendOrderedBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;Ljava/lang/String;ILandroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/Handler;ILjava/lang/String;Landroid/os/Bundle;)V
 HSPLandroid/content/ContextWrapper;->sendStickyBroadcast(Landroid/content/Intent;)V
 HSPLandroid/content/ContextWrapper;->sendStickyBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V
+HSPLandroid/content/ContextWrapper;->setAutofillClient(Landroid/view/autofill/AutofillManager$AutofillClient;)V
 HSPLandroid/content/ContextWrapper;->setAutofillOptions(Landroid/content/AutofillOptions;)V
 HSPLandroid/content/ContextWrapper;->setContentCaptureOptions(Landroid/content/ContentCaptureOptions;)V
 HSPLandroid/content/ContextWrapper;->setTheme(I)V
@@ -3469,11 +3636,12 @@
 HSPLandroid/content/IClipboard$Stub$Proxy;->addPrimaryClipChangedListener(Landroid/content/IOnPrimaryClipChangedListener;Ljava/lang/String;)V
 HSPLandroid/content/IClipboard$Stub;-><init>()V
 HPLandroid/content/IClipboard$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/content/IContentService$Stub$Proxy;->getIsSyncable(Landroid/accounts/Account;Ljava/lang/String;)I
 HSPLandroid/content/IContentService$Stub$Proxy;->notifyChange(Landroid/net/Uri;Landroid/database/IContentObserver;ZIIILjava/lang/String;)V
 HSPLandroid/content/IContentService$Stub$Proxy;->registerContentObserver(Landroid/net/Uri;ZLandroid/database/IContentObserver;II)V
 HSPLandroid/content/IContentService$Stub$Proxy;->unregisterContentObserver(Landroid/database/IContentObserver;)V
 HSPLandroid/content/IContentService$Stub;-><init>()V
-PLandroid/content/IContentService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/content/IContentService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/content/IContentService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/content/IIntentReceiver$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/content/IIntentReceiver$Stub$Proxy;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZI)V
@@ -3493,15 +3661,15 @@
 PLandroid/content/ISyncAdapter$Stub$Proxy;->onUnsyncableAccount(Landroid/content/ISyncAdapterUnsyncableAccountCallback;)V
 HPLandroid/content/ISyncAdapter$Stub$Proxy;->startSync(Landroid/content/ISyncContext;Ljava/lang/String;Landroid/accounts/Account;Landroid/os/Bundle;)V
 HPLandroid/content/ISyncAdapter$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/ISyncAdapter;
-PLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub;-><init>()V
-PLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub;->asBinder()Landroid/os/IBinder;
-PLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub;-><init>()V
+HPLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub;->asBinder()Landroid/os/IBinder;
+HPLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLandroid/content/ISyncContext$Stub;-><init>()V
 HPLandroid/content/ISyncContext$Stub;->asBinder()Landroid/os/IBinder;
 HPLandroid/content/ISyncContext$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/content/ISyncStatusObserver$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HPLandroid/content/ISyncStatusObserver$Stub$Proxy;->onStatusChanged(I)V
-PLandroid/content/ISyncStatusObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/ISyncStatusObserver;
+HPLandroid/content/ISyncStatusObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/ISyncStatusObserver;
 HSPLandroid/content/Intent$1;-><init>()V
 HSPLandroid/content/Intent$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/Intent;
 HSPLandroid/content/Intent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3545,6 +3713,7 @@
 HSPLandroid/content/Intent;->getLongExtra(Ljava/lang/String;J)J
 HSPLandroid/content/Intent;->getPackage()Ljava/lang/String;
 HSPLandroid/content/Intent;->getParcelableArrayExtra(Ljava/lang/String;)[Landroid/os/Parcelable;
+HSPLandroid/content/Intent;->getParcelableArrayListExtra(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/content/Intent;->getParcelableExtra(Ljava/lang/String;)Landroid/os/Parcelable;
 HSPLandroid/content/Intent;->getScheme()Ljava/lang/String;
 HSPLandroid/content/Intent;->getSelector()Landroid/content/Intent;
@@ -3586,7 +3755,7 @@
 HSPLandroid/content/Intent;->putStringArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/content/Intent;->removeExtra(Ljava/lang/String;)V
-PLandroid/content/Intent;->removeFlags(I)V
+HPLandroid/content/Intent;->removeFlags(I)V
 HSPLandroid/content/Intent;->replaceExtras(Landroid/content/Intent;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->replaceExtras(Landroid/os/Bundle;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->resolveActivity(Landroid/content/pm/PackageManager;)Landroid/content/ComponentName;
@@ -3608,6 +3777,7 @@
 HSPLandroid/content/Intent;->setFlags(I)Landroid/content/Intent;
 HSPLandroid/content/Intent;->setPackage(Ljava/lang/String;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->setSourceBounds(Landroid/graphics/Rect;)V
+HSPLandroid/content/Intent;->setType(Ljava/lang/String;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->toInsecureString()Ljava/lang/String;
 HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V
 HSPLandroid/content/Intent;->toShortString(ZZZZ)Ljava/lang/String;
@@ -3651,7 +3821,7 @@
 HSPLandroid/content/IntentFilter;->getDataAuthority(I)Landroid/content/IntentFilter$AuthorityEntry;
 HSPLandroid/content/IntentFilter;->getDataPath(I)Landroid/os/PatternMatcher;
 HSPLandroid/content/IntentFilter;->getDataScheme(I)Ljava/lang/String;
-PLandroid/content/IntentFilter;->getDataSchemeSpecificPart(I)Landroid/os/PatternMatcher;
+HPLandroid/content/IntentFilter;->getDataSchemeSpecificPart(I)Landroid/os/PatternMatcher;
 HSPLandroid/content/IntentFilter;->getHostsList()Ljava/util/ArrayList;
 HSPLandroid/content/IntentFilter;->getPriority()I
 HSPLandroid/content/IntentFilter;->handleAllWebDataURI()Z
@@ -3662,16 +3832,17 @@
 HSPLandroid/content/IntentFilter;->hasDataPath(Landroid/os/PatternMatcher;)Z
 HPLandroid/content/IntentFilter;->hasDataPath(Ljava/lang/String;)Z
 HSPLandroid/content/IntentFilter;->hasDataScheme(Ljava/lang/String;)Z
-PLandroid/content/IntentFilter;->hasDataSchemeSpecificPart(Landroid/os/PatternMatcher;)Z
+HPLandroid/content/IntentFilter;->hasDataSchemeSpecificPart(Landroid/os/PatternMatcher;)Z
 HSPLandroid/content/IntentFilter;->hasDataSchemeSpecificPart(Ljava/lang/String;)Z
 HSPLandroid/content/IntentFilter;->match(Landroid/content/ContentResolver;Landroid/content/Intent;ZLjava/lang/String;)I
 HSPLandroid/content/IntentFilter;->match(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/net/Uri;Ljava/util/Set;Ljava/lang/String;)I
 HSPLandroid/content/IntentFilter;->matchCategories(Ljava/util/Set;)Ljava/lang/String;
 HSPLandroid/content/IntentFilter;->matchData(Ljava/lang/String;Ljava/lang/String;Landroid/net/Uri;)I
 HSPLandroid/content/IntentFilter;->matchDataAuthority(Landroid/net/Uri;)I
-PLandroid/content/IntentFilter;->needsVerification()Z
+HPLandroid/content/IntentFilter;->needsVerification()Z
 HSPLandroid/content/IntentFilter;->readFromXml(Lorg/xmlpull/v1/XmlPullParser;)V
 HSPLandroid/content/IntentFilter;->schemesIterator()Ljava/util/Iterator;
+HSPLandroid/content/IntentFilter;->setPriority(I)V
 HSPLandroid/content/IntentFilter;->setVisibilityToInstantApp(I)V
 HSPLandroid/content/IntentFilter;->typesIterator()Ljava/util/Iterator;
 HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V
@@ -3680,8 +3851,15 @@
 HSPLandroid/content/IntentSender$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/IntentSender;
 HSPLandroid/content/IntentSender$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HPLandroid/content/IntentSender;-><init>(Landroid/os/IBinder;)V
-PLandroid/content/IntentSender;->sendIntent(Landroid/content/Context;ILandroid/content/Intent;Landroid/content/IntentSender$OnFinished;Landroid/os/Handler;)V
+HPLandroid/content/IntentSender;->sendIntent(Landroid/content/Context;ILandroid/content/Intent;Landroid/content/IntentSender$OnFinished;Landroid/os/Handler;)V
 HPLandroid/content/IntentSender;->sendIntent(Landroid/content/Context;ILandroid/content/Intent;Landroid/content/IntentSender$OnFinished;Landroid/os/Handler;Ljava/lang/String;)V
+HSPLandroid/content/Loader;->cancelLoad()Z
+HSPLandroid/content/Loader;->commitContentChanged()V
+HSPLandroid/content/Loader;->forceLoad()V
+HSPLandroid/content/Loader;->getContext()Landroid/content/Context;
+HSPLandroid/content/Loader;->isAbandoned()Z
+HSPLandroid/content/Loader;->registerListener(ILandroid/content/Loader$OnLoadCompleteListener;)V
+HSPLandroid/content/Loader;->reset()V
 HSPLandroid/content/PeriodicSync$1;-><init>()V
 PLandroid/content/PeriodicSync;-><init>(Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;JJ)V
 PLandroid/content/PeriodicSync;->writeToParcel(Landroid/os/Parcel;I)V
@@ -3699,7 +3877,7 @@
 HSPLandroid/content/SyncAdapterType;->equals(Ljava/lang/Object;)Z
 HSPLandroid/content/SyncAdapterType;->hashCode()I
 HPLandroid/content/SyncAdapterType;->isAlwaysSyncable()Z
-PLandroid/content/SyncAdapterType;->isUserVisible()Z
+HPLandroid/content/SyncAdapterType;->isUserVisible()Z
 HSPLandroid/content/SyncAdapterType;->newKey(Ljava/lang/String;Ljava/lang/String;)Landroid/content/SyncAdapterType;
 HPLandroid/content/SyncAdapterType;->supportsUploading()Z
 HPLandroid/content/SyncAdapterType;->writeToParcel(Landroid/os/Parcel;I)V
@@ -3713,7 +3891,7 @@
 HSPLandroid/content/SyncAdaptersCache;->parseServiceAttributes(Landroid/content/res/Resources;Ljava/lang/String;Landroid/util/AttributeSet;)Ljava/lang/Object;
 PLandroid/content/SyncInfo$1;-><init>()V
 HSPLandroid/content/SyncRequest$1;-><init>()V
-PLandroid/content/SyncRequest$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/SyncRequest;
+HPLandroid/content/SyncRequest$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/SyncRequest;
 HPLandroid/content/SyncRequest$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HPLandroid/content/SyncRequest;-><init>(Landroid/os/Parcel;)V
 HPLandroid/content/SyncRequest;->getAccount()Landroid/accounts/Account;
@@ -3723,37 +3901,40 @@
 HPLandroid/content/SyncRequest;->getSyncRunTime()J
 HPLandroid/content/SyncRequest;->isPeriodic()Z
 HSPLandroid/content/SyncResult$1;-><init>()V
-PLandroid/content/SyncResult$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/SyncResult;
-PLandroid/content/SyncResult$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/content/SyncResult$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/SyncResult;
+HPLandroid/content/SyncResult$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HPLandroid/content/SyncResult;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/SyncResult;-><init>(Z)V
 HSPLandroid/content/SyncResult;->hasError()Z
 HSPLandroid/content/SyncResult;->hasHardError()Z
 HSPLandroid/content/SyncResult;->hasSoftError()Z
-PLandroid/content/SyncResult;->madeSomeProgress()Z
+HPLandroid/content/SyncResult;->madeSomeProgress()Z
 HSPLandroid/content/SyncResult;->toString()Ljava/lang/String;
 HSPLandroid/content/SyncStats$1;-><init>()V
 HPLandroid/content/SyncStats;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/SyncStats;->toString()Ljava/lang/String;
 HSPLandroid/content/SyncStatusInfo$1;-><init>()V
-PLandroid/content/SyncStatusInfo$Stats;->clear()V
-PLandroid/content/SyncStatusInfo$Stats;->copyTo(Landroid/content/SyncStatusInfo$Stats;)V
+HPLandroid/content/SyncStatusInfo$Stats;->clear()V
+HPLandroid/content/SyncStatusInfo$Stats;->copyTo(Landroid/content/SyncStatusInfo$Stats;)V
 HSPLandroid/content/SyncStatusInfo$Stats;->readFromParcel(Landroid/os/Parcel;)V
 HPLandroid/content/SyncStatusInfo$Stats;->writeToParcel(Landroid/os/Parcel;)V
+HPLandroid/content/SyncStatusInfo;-><init>(I)V
 HSPLandroid/content/SyncStatusInfo;-><init>(Landroid/os/Parcel;)V
 HPLandroid/content/SyncStatusInfo;->addEvent(Ljava/lang/String;)V
 HPLandroid/content/SyncStatusInfo;->areSameDates(JJ)Z
 HPLandroid/content/SyncStatusInfo;->maybeResetTodayStats(ZZ)V
-PLandroid/content/SyncStatusInfo;->setLastFailure(IJLjava/lang/String;)V
+HPLandroid/content/SyncStatusInfo;->setLastFailure(IJLjava/lang/String;)V
 HPLandroid/content/SyncStatusInfo;->setLastSuccess(IJ)V
 HPLandroid/content/SyncStatusInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/UndoManager$UndoState;->addOperation(Landroid/content/UndoOperation;)V
 HSPLandroid/content/UndoManager$UndoState;->destroy()V
 HSPLandroid/content/UndoManager$UndoState;->getLastOperation(Ljava/lang/Class;Landroid/content/UndoOwner;)Landroid/content/UndoOperation;
 HSPLandroid/content/UndoManager$UndoState;->hasMultipleOwners()Z
+HSPLandroid/content/UndoManager$UndoState;->hasOperation(Landroid/content/UndoOwner;)Z
 HSPLandroid/content/UndoManager;-><init>()V
 HSPLandroid/content/UndoManager;->addOperation(Landroid/content/UndoOperation;I)V
 HSPLandroid/content/UndoManager;->beginUpdate(Ljava/lang/CharSequence;)V
+HSPLandroid/content/UndoManager;->commitState(Landroid/content/UndoOwner;)I
 HSPLandroid/content/UndoManager;->endUpdate()V
 HSPLandroid/content/UndoManager;->findPrevState(Ljava/util/ArrayList;[Landroid/content/UndoOwner;I)I
 HSPLandroid/content/UndoManager;->forgetRedos([Landroid/content/UndoOwner;I)I
@@ -3762,11 +3943,14 @@
 HSPLandroid/content/UndoManager;->getOwner(Ljava/lang/String;Ljava/lang/Object;)Landroid/content/UndoOwner;
 HSPLandroid/content/UndoManager;->getTopUndo([Landroid/content/UndoOwner;)Landroid/content/UndoManager$UndoState;
 HSPLandroid/content/UndoManager;->isInUndo()Z
+HSPLandroid/content/UndoManager;->matchOwners(Landroid/content/UndoManager$UndoState;[Landroid/content/UndoOwner;)Z
 HSPLandroid/content/UndoManager;->pushWorkingState()V
+HSPLandroid/content/UndoManager;->removeOwner(Landroid/content/UndoOwner;)V
 HSPLandroid/content/UndoManager;->saveInstanceState(Landroid/os/Parcel;)V
 HSPLandroid/content/UndoOperation;->allowMerge()Z
 HSPLandroid/content/UndoOperation;->getOwner()Landroid/content/UndoOwner;
 HSPLandroid/content/UndoOperation;->hasData()Z
+HSPLandroid/content/UndoOperation;->matchOwner(Landroid/content/UndoOwner;)Z
 HSPLandroid/content/UriMatcher;-><init>(I)V
 HSPLandroid/content/UriMatcher;->addURI(Ljava/lang/String;Ljava/lang/String;I)V
 HSPLandroid/content/UriMatcher;->createChild(Ljava/lang/String;)Landroid/content/UriMatcher;
@@ -3823,7 +4007,7 @@
 HSPLandroid/content/pm/ApplicationInfo;->hasRtlSupport()Z
 HSPLandroid/content/pm/ApplicationInfo;->initForUser(I)V
 HSPLandroid/content/pm/ApplicationInfo;->isAllowedToUseHiddenApis()Z
-PLandroid/content/pm/ApplicationInfo;->isAudioPlaybackCaptureAllowed()Z
+HPLandroid/content/pm/ApplicationInfo;->isAudioPlaybackCaptureAllowed()Z
 HSPLandroid/content/pm/ApplicationInfo;->isDirectBootAware()Z
 HSPLandroid/content/pm/ApplicationInfo;->isEmbeddedDexUsed()Z
 HSPLandroid/content/pm/ApplicationInfo;->isEncryptionAware()Z
@@ -3885,9 +4069,9 @@
 HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/FeatureInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/ICrossProfileApps$Stub;-><init>()V
-PLandroid/content/pm/ICrossProfileApps$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/content/pm/ICrossProfileApps$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/content/pm/ILauncherApps$Stub;-><init>()V
-PLandroid/content/pm/ILauncherApps$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/content/pm/ILauncherApps$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/content/pm/ILauncherApps$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/content/pm/IOnAppsChangedListener$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 PLandroid/content/pm/IOnAppsChangedListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
@@ -3899,10 +4083,10 @@
 HSPLandroid/content/pm/IOnPermissionsChangeListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IOnPermissionsChangeListener;
 HSPLandroid/content/pm/IOtaDexopt$Stub;-><init>()V
 PLandroid/content/pm/IPackageDataObserver$Stub$Proxy;->onRemoveCompleted(Ljava/lang/String;Z)V
-PLandroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
+HPLandroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
 PLandroid/content/pm/IPackageInstallObserver2$Stub;-><init>()V
 HSPLandroid/content/pm/IPackageInstaller$Stub;-><init>()V
-PLandroid/content/pm/IPackageInstaller$Stub;->asBinder()Landroid/os/IBinder;
+HPLandroid/content/pm/IPackageInstaller$Stub;->asBinder()Landroid/os/IBinder;
 HPLandroid/content/pm/IPackageInstaller$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/content/pm/IPackageInstallerCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 PLandroid/content/pm/IPackageInstallerCallback$Stub$Proxy;->onSessionActiveChanged(IZ)V
@@ -3922,6 +4106,7 @@
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledModules(I)Ljava/util/List;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstantAppResolverSettingsComponent()Landroid/content/ComponentName;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getNameForUid(I)Ljava/lang/String;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageUid(Ljava/lang/String;II)I
@@ -3953,7 +4138,7 @@
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->setSystemAppHiddenUntilInstalled(Ljava/lang/String;Z)V
 HSPLandroid/content/pm/IPackageManager$Stub;-><init>()V
 HSPLandroid/content/pm/IPackageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageManager;
-PLandroid/content/pm/IPackageManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/content/pm/IPackageManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/content/pm/IPackageManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/content/pm/IPackageManagerNative$Stub;-><init>()V
 HSPLandroid/content/pm/IPackageManagerNative$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -3991,9 +4176,12 @@
 HSPLandroid/content/pm/IntentFilterVerificationInfo;->getStringFromXml(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/pm/IntentFilterVerificationInfo;->readFromXml(Lorg/xmlpull/v1/XmlPullParser;)V
 HSPLandroid/content/pm/IntentFilterVerificationInfo;->writeToXml(Lorg/xmlpull/v1/XmlSerializer;)V
+HSPLandroid/content/pm/LauncherApps;-><init>(Landroid/content/Context;Landroid/content/pm/ILauncherApps;)V
 HSPLandroid/content/pm/ModuleInfo$1;-><init>()V
 HSPLandroid/content/pm/ModuleInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ModuleInfo;
 HSPLandroid/content/pm/ModuleInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/content/pm/ModuleInfo;->getPackageName()Ljava/lang/String;
+HSPLandroid/content/pm/ModuleInfo;->isHidden()Z
 HPLandroid/content/pm/ModuleInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/OrgApacheHttpLegacyUpdater;-><init>()V
 HSPLandroid/content/pm/OrgApacheHttpLegacyUpdater;->updatePackage(Landroid/content/pm/PackageParser$Package;)V
@@ -4016,19 +4204,21 @@
 HSPLandroid/content/pm/PackageInfo;->writeToParcel(Landroid/os/Parcel;I)V
 PLandroid/content/pm/PackageInfoLite$1;-><init>()V
 PLandroid/content/pm/PackageInfoLite;->getLongVersionCode()J
-PLandroid/content/pm/PackageInstaller$SessionCallbackDelegate;->onSessionActiveChanged(IZ)V
-PLandroid/content/pm/PackageInstaller$SessionCallbackDelegate;->onSessionCreated(I)V
-PLandroid/content/pm/PackageInstaller$SessionCallbackDelegate;->onSessionFinished(IZ)V
+HPLandroid/content/pm/PackageInstaller$SessionCallbackDelegate;->onSessionActiveChanged(IZ)V
+HPLandroid/content/pm/PackageInstaller$SessionCallbackDelegate;->onSessionCreated(I)V
+HPLandroid/content/pm/PackageInstaller$SessionCallbackDelegate;->onSessionFinished(IZ)V
 HPLandroid/content/pm/PackageInstaller$SessionCallbackDelegate;->onSessionProgressChanged(IF)V
 HSPLandroid/content/pm/PackageInstaller$SessionInfo$1;-><init>()V
-PLandroid/content/pm/PackageInstaller$SessionInfo;-><init>()V
+HPLandroid/content/pm/PackageInstaller$SessionInfo;-><init>()V
+HPLandroid/content/pm/PackageInstaller$SessionInfo;->describeContents()I
 HSPLandroid/content/pm/PackageInstaller$SessionInfo;->getInstallerPackageName()Ljava/lang/String;
 HPLandroid/content/pm/PackageInstaller$SessionInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/PackageInstaller$SessionParams$1;-><init>()V
-PLandroid/content/pm/PackageInstaller$SessionParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageInstaller$SessionParams;
-PLandroid/content/pm/PackageInstaller$SessionParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-PLandroid/content/pm/PackageInstaller$SessionParams;-><init>(Landroid/os/Parcel;)V
+HPLandroid/content/pm/PackageInstaller$SessionParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageInstaller$SessionParams;
+HPLandroid/content/pm/PackageInstaller$SessionParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/content/pm/PackageInstaller$SessionParams;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/PackageInstaller$SessionParams;->dump(Lcom/android/internal/util/IndentingPrintWriter;)V
+HSPLandroid/content/pm/PackageInstaller;->getSessionInfo(I)Landroid/content/pm/PackageInstaller$SessionInfo;
 HSPLandroid/content/pm/PackageInstaller;->registerSessionCallback(Landroid/content/pm/PackageInstaller$SessionCallback;Landroid/os/Handler;)V
 HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/content/pm/PackageItemInfo;)V
 HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V
@@ -4040,9 +4230,9 @@
 HSPLandroid/content/pm/PackageItemInfo;->loadXmlMetaData(Landroid/content/pm/PackageManager;Ljava/lang/String;)Landroid/content/res/XmlResourceParser;
 HSPLandroid/content/pm/PackageItemInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/PackageList;->getPackageNames()Ljava/util/List;
-PLandroid/content/pm/PackageManager;->installStatusToPublicStatus(I)I
-PLandroid/content/pm/PackageManager;->installStatusToString(I)Ljava/lang/String;
-PLandroid/content/pm/PackageManager;->installStatusToString(ILjava/lang/String;)Ljava/lang/String;
+HPLandroid/content/pm/PackageManager;->installStatusToPublicStatus(I)I
+HPLandroid/content/pm/PackageManager;->installStatusToString(I)Ljava/lang/String;
+HPLandroid/content/pm/PackageManager;->installStatusToString(ILjava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/pm/PackageManager;->queryBroadcastReceiversAsUser(Landroid/content/Intent;ILandroid/os/UserHandle;)Ljava/util/List;
 HSPLandroid/content/pm/PackageParser$Activity$1;-><init>()V
 HSPLandroid/content/pm/PackageParser$Activity$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageParser$Activity;
@@ -4054,6 +4244,7 @@
 HSPLandroid/content/pm/PackageParser$Activity;->setMinAspectRatio(F)V
 HSPLandroid/content/pm/PackageParser$Activity;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/PackageParser$ActivityIntentInfo;-><init>(Landroid/content/pm/PackageParser$Activity;)V
+HSPLandroid/content/pm/PackageParser$ActivityIntentInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/PackageParser$ApkLite;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;ZIIIILjava/util/List;Landroid/content/pm/PackageParser$SigningDetails;ZZZZZZZII)V
 HSPLandroid/content/pm/PackageParser$ApkLite;->getLongVersionCode()J
 HSPLandroid/content/pm/PackageParser$CachedComponentArgs;-><init>()V
@@ -4076,7 +4267,7 @@
 HPLandroid/content/pm/PackageParser$Package;->canHaveOatDir()Z
 HSPLandroid/content/pm/PackageParser$Package;->fixupOwner(Ljava/util/List;)V
 HSPLandroid/content/pm/PackageParser$Package;->getAllCodePaths()Ljava/util/List;
-PLandroid/content/pm/PackageParser$Package;->getAllCodePathsExcludingResourceOnly()Ljava/util/List;
+HPLandroid/content/pm/PackageParser$Package;->getAllCodePathsExcludingResourceOnly()Ljava/util/List;
 HSPLandroid/content/pm/PackageParser$Package;->getChildPackageNames()Ljava/util/List;
 HPLandroid/content/pm/PackageParser$Package;->getLatestForegroundPackageUseTimeInMills()J
 HSPLandroid/content/pm/PackageParser$Package;->getLatestPackageUseTimeInMills()J
@@ -4095,7 +4286,7 @@
 HSPLandroid/content/pm/PackageParser$Package;->setApplicationInfoBaseCodePath(Ljava/lang/String;)V
 HSPLandroid/content/pm/PackageParser$Package;->setApplicationInfoBaseResourcePath(Ljava/lang/String;)V
 HSPLandroid/content/pm/PackageParser$Package;->setApplicationInfoCodePath(Ljava/lang/String;)V
-PLandroid/content/pm/PackageParser$Package;->setApplicationInfoFlags(II)V
+HPLandroid/content/pm/PackageParser$Package;->setApplicationInfoFlags(II)V
 HSPLandroid/content/pm/PackageParser$Package;->setApplicationInfoResourcePath(Ljava/lang/String;)V
 HSPLandroid/content/pm/PackageParser$Package;->setApplicationInfoSplitCodePaths([Ljava/lang/String;)V
 HSPLandroid/content/pm/PackageParser$Package;->setApplicationInfoSplitResourcePaths([Ljava/lang/String;)V
@@ -4114,12 +4305,18 @@
 HSPLandroid/content/pm/PackageParser$Permission$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageParser$Permission;
 HSPLandroid/content/pm/PackageParser$Permission$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/PackageParser$Permission;-><init>(Landroid/os/Parcel;)V
-PLandroid/content/pm/PackageParser$Permission;->isAppOp()Z
+HPLandroid/content/pm/PackageParser$Permission;->isAppOp()Z
 HSPLandroid/content/pm/PackageParser$Permission;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/PackageParser$PermissionGroup$1;-><init>()V
+HSPLandroid/content/pm/PackageParser$PermissionGroup$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageParser$PermissionGroup;
+HSPLandroid/content/pm/PackageParser$PermissionGroup$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/PackageParser$PermissionGroup;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/PackageParser$Provider$1;-><init>()V
+HSPLandroid/content/pm/PackageParser$Provider$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageParser$Provider;
+HSPLandroid/content/pm/PackageParser$Provider$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/content/pm/PackageParser$Provider;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/PackageParser$Provider;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/PackageParser$ProviderIntentInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/PackageParser$Service$1;-><init>()V
 HSPLandroid/content/pm/PackageParser$Service$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageParser$Service;
 HSPLandroid/content/pm/PackageParser$Service$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4166,7 +4363,7 @@
 HSPLandroid/content/pm/PackageParser;->generateAppDetailsHiddenActivity(Landroid/content/pm/PackageParser$Package;I[Ljava/lang/String;Z)Landroid/content/pm/PackageParser$Activity;
 HSPLandroid/content/pm/PackageParser;->generateApplicationInfo(Landroid/content/pm/PackageParser$Package;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ApplicationInfo;
 HSPLandroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;I)Landroid/content/pm/PackageInfo;
-PLandroid/content/pm/PackageParser;->generatePackageInfoFromApex(Ljava/io/File;Z)Landroid/content/pm/PackageInfo;
+HPLandroid/content/pm/PackageParser;->generatePackageInfoFromApex(Ljava/io/File;Z)Landroid/content/pm/PackageInfo;
 HSPLandroid/content/pm/PackageParser;->generatePermissionGroupInfo(Landroid/content/pm/PackageParser$PermissionGroup;I)Landroid/content/pm/PermissionGroupInfo;
 HSPLandroid/content/pm/PackageParser;->generatePermissionInfo(Landroid/content/pm/PackageParser$Permission;I)Landroid/content/pm/PermissionInfo;
 HSPLandroid/content/pm/PackageParser;->generateProviderInfo(Landroid/content/pm/PackageParser$Provider;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ProviderInfo;
@@ -4274,7 +4471,7 @@
 HSPLandroid/content/pm/PermissionInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/PermissionInfo;->getProtection()I
 HSPLandroid/content/pm/PermissionInfo;->getProtectionFlags()I
-PLandroid/content/pm/PermissionInfo;->isAppOp()Z
+HPLandroid/content/pm/PermissionInfo;->isAppOp()Z
 HSPLandroid/content/pm/PermissionInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/ProviderInfo$1;-><init>()V
 HSPLandroid/content/pm/ProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ProviderInfo;
@@ -4310,6 +4507,7 @@
 HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/content/pm/ResolveInfo;)V
 HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/ResolveInfo;->getComponentInfo()Landroid/content/pm/ComponentInfo;
+HSPLandroid/content/pm/ResolveInfo;->getIconResource()I
 HSPLandroid/content/pm/ResolveInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/pm/ResolveInfo;->loadLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
 HSPLandroid/content/pm/ResolveInfo;->toString()Ljava/lang/String;
@@ -4341,6 +4539,7 @@
 HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/ShortcutInfo$Builder;-><init>(Landroid/content/Context;Ljava/lang/String;)V
 HSPLandroid/content/pm/ShortcutInfo$Builder;->build()Landroid/content/pm/ShortcutInfo;
+HSPLandroid/content/pm/ShortcutInfo$Builder;->setActivity(Landroid/content/ComponentName;)Landroid/content/pm/ShortcutInfo$Builder;
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setIcon(Landroid/graphics/drawable/Icon;)Landroid/content/pm/ShortcutInfo$Builder;
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setIntent(Landroid/content/Intent;)Landroid/content/pm/ShortcutInfo$Builder;
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setIntents([Landroid/content/Intent;)Landroid/content/pm/ShortcutInfo$Builder;
@@ -4353,7 +4552,7 @@
 HSPLandroid/content/pm/ShortcutInfo;->cloneCategories(Ljava/util/Set;)Landroid/util/ArraySet;
 HSPLandroid/content/pm/ShortcutInfo;->cloneIntents([Landroid/content/Intent;)[Landroid/content/Intent;
 HSPLandroid/content/pm/ShortcutInfo;->clonePersons([Landroid/app/Person;)[Landroid/app/Person;
-PLandroid/content/pm/ShortcutInfo;->copyNonNullFieldsFrom(Landroid/content/pm/ShortcutInfo;)V
+HPLandroid/content/pm/ShortcutInfo;->copyNonNullFieldsFrom(Landroid/content/pm/ShortcutInfo;)V
 HPLandroid/content/pm/ShortcutInfo;->enforceMandatoryFields(Z)V
 HPLandroid/content/pm/ShortcutInfo;->ensureUpdatableWith(Landroid/content/pm/ShortcutInfo;Z)V
 HSPLandroid/content/pm/ShortcutInfo;->fixUpIntentExtras()V
@@ -4362,11 +4561,11 @@
 HSPLandroid/content/pm/ShortcutInfo;->getResourceString(Landroid/content/res/Resources;ILjava/lang/CharSequence;)Ljava/lang/CharSequence;
 HPLandroid/content/pm/ShortcutInfo;->isDynamicVisible()Z
 HPLandroid/content/pm/ShortcutInfo;->isManifestVisible()Z
-PLandroid/content/pm/ShortcutInfo;->isPinnedVisible()Z
+HPLandroid/content/pm/ShortcutInfo;->isPinnedVisible()Z
 HPLandroid/content/pm/ShortcutInfo;->isVisibleToPublisher()Z
-PLandroid/content/pm/ShortcutInfo;->lookUpResourceId(Landroid/content/res/Resources;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
+HPLandroid/content/pm/ShortcutInfo;->lookUpResourceId(Landroid/content/res/Resources;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
 HSPLandroid/content/pm/ShortcutInfo;->lookUpResourceName(Landroid/content/res/Resources;IZLjava/lang/String;)Ljava/lang/String;
-PLandroid/content/pm/ShortcutInfo;->lookupAndFillInResourceIds(Landroid/content/res/Resources;)V
+HPLandroid/content/pm/ShortcutInfo;->lookupAndFillInResourceIds(Landroid/content/res/Resources;)V
 HSPLandroid/content/pm/ShortcutInfo;->lookupAndFillInResourceNames(Landroid/content/res/Resources;)V
 HSPLandroid/content/pm/ShortcutInfo;->resolveResourceStrings(Landroid/content/res/Resources;)V
 HSPLandroid/content/pm/ShortcutInfo;->setCategories(Ljava/util/Set;)V
@@ -4374,6 +4573,7 @@
 HSPLandroid/content/pm/ShortcutInfo;->setIntents([Landroid/content/Intent;)V
 HSPLandroid/content/pm/ShortcutInfo;->validateIcon(Landroid/graphics/drawable/Icon;)Landroid/graphics/drawable/Icon;
 HSPLandroid/content/pm/ShortcutInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/ShortcutManager;->disableShortcuts(Ljava/util/List;)V
 HSPLandroid/content/pm/ShortcutManager;->getDynamicShortcuts()Ljava/util/List;
 HSPLandroid/content/pm/ShortcutManager;->injectMyUserId()I
 HSPLandroid/content/pm/ShortcutManager;->setDynamicShortcuts(Ljava/util/List;)Z
@@ -4407,7 +4607,7 @@
 HSPLandroid/content/pm/UserInfo;-><init>(ILjava/lang/String;Ljava/lang/String;I)V
 HSPLandroid/content/pm/UserInfo;-><init>(Landroid/content/pm/UserInfo;)V
 HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V
-PLandroid/content/pm/UserInfo;->canHaveProfile()Z
+HPLandroid/content/pm/UserInfo;->canHaveProfile()Z
 HSPLandroid/content/pm/UserInfo;->getUserHandle()Landroid/os/UserHandle;
 HSPLandroid/content/pm/UserInfo;->isAdmin()Z
 HSPLandroid/content/pm/UserInfo;->isDemo()Z
@@ -4430,7 +4630,7 @@
 HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/VersionedPackage;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/dex/ArtManager;->getProfileName(Ljava/lang/String;)Ljava/lang/String;
-PLandroid/content/pm/dex/ArtManager;->getProfileSnapshotFileForName(Ljava/lang/String;Ljava/lang/String;)Ljava/io/File;
+HPLandroid/content/pm/dex/ArtManager;->getProfileSnapshotFileForName(Ljava/lang/String;Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/content/pm/dex/DexMetadataHelper;->buildDexMetadataPathForApk(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/pm/dex/DexMetadataHelper;->buildDexMetadataPathForFile(Ljava/io/File;)Ljava/lang/String;
 PLandroid/content/pm/dex/DexMetadataHelper;->buildPackageApkToDexMetadataMap(Ljava/util/List;)Ljava/util/Map;
@@ -4440,8 +4640,8 @@
 PLandroid/content/pm/dex/DexMetadataHelper;->validateDexMetadataFile(Ljava/lang/String;)V
 PLandroid/content/pm/dex/DexMetadataHelper;->validatePackageDexMetadata(Landroid/content/pm/PackageParser$Package;)V
 HSPLandroid/content/pm/dex/IArtManager$Stub;-><init>()V
-PLandroid/content/pm/dex/IArtManager$Stub;->asBinder()Landroid/os/IBinder;
-PLandroid/content/pm/dex/IArtManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/content/pm/dex/IArtManager$Stub;->asBinder()Landroid/os/IBinder;
+HPLandroid/content/pm/dex/IArtManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/content/pm/dex/ISnapshotRuntimeProfileCallback$Stub$Proxy;->onError(I)V
 PLandroid/content/pm/dex/ISnapshotRuntimeProfileCallback$Stub$Proxy;->onSuccess(Landroid/os/ParcelFileDescriptor;)V
 HSPLandroid/content/pm/dex/PackageOptimizationInfo;->getCompilationFilter()I
@@ -4581,11 +4781,11 @@
 HSPLandroid/content/res/Configuration;->getLayoutDirection()I
 HSPLandroid/content/res/Configuration;->getLocales()Landroid/os/LocaleList;
 HSPLandroid/content/res/Configuration;->hashCode()I
-PLandroid/content/res/Configuration;->localesToResourceQualifier(Landroid/os/LocaleList;)Ljava/lang/String;
+HPLandroid/content/res/Configuration;->localesToResourceQualifier(Landroid/os/LocaleList;)Ljava/lang/String;
 HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/content/res/Configuration;->readFromProto(Landroid/util/proto/ProtoInputStream;J)V
 HSPLandroid/content/res/Configuration;->reduceScreenLayout(III)I
-PLandroid/content/res/Configuration;->resourceQualifierString(Landroid/content/res/Configuration;)Ljava/lang/String;
+HPLandroid/content/res/Configuration;->resourceQualifierString(Landroid/content/res/Configuration;)Ljava/lang/String;
 HPLandroid/content/res/Configuration;->resourceQualifierString(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;)Ljava/lang/String;
 HSPLandroid/content/res/Configuration;->setLocales(Landroid/os/LocaleList;)V
 HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V
@@ -4658,6 +4858,7 @@
 HSPLandroid/content/res/Resources;->getIntArray(I)[I
 HSPLandroid/content/res/Resources;->getInteger(I)I
 HSPLandroid/content/res/Resources;->getLayout(I)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->getQuantityString(II)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getQuantityString(II[Ljava/lang/Object;)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getQuantityText(II)Ljava/lang/CharSequence;
 HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;
@@ -4671,7 +4872,7 @@
 HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getSystem()Landroid/content/res/Resources;
 HSPLandroid/content/res/Resources;->getText(I)Ljava/lang/CharSequence;
-PLandroid/content/res/Resources;->getText(ILjava/lang/CharSequence;)Ljava/lang/CharSequence;
+HPLandroid/content/res/Resources;->getText(ILjava/lang/CharSequence;)Ljava/lang/CharSequence;
 HSPLandroid/content/res/Resources;->getTextArray(I)[Ljava/lang/CharSequence;
 HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/Resources;->getValueForDensity(IILandroid/util/TypedValue;Z)V
@@ -4834,7 +5035,7 @@
 HSPLandroid/content/res/XmlBlock;->finalize()V
 HSPLandroid/content/res/XmlBlock;->newParser(I)Landroid/content/res/XmlResourceParser;
 HSPLandroid/content/rollback/IRollbackManager$Stub;-><init>()V
-PLandroid/content/rollback/IRollbackManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/rollback/IRollbackManager;
+HPLandroid/content/rollback/IRollbackManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/rollback/IRollbackManager;
 HSPLandroid/database/AbstractCursor$SelfContentObserver;->onChange(Z)V
 HSPLandroid/database/AbstractCursor;->close()V
 HSPLandroid/database/AbstractCursor;->fillWindow(ILandroid/database/CursorWindow;)V
@@ -4853,10 +5054,12 @@
 HSPLandroid/database/AbstractCursor;->moveToFirst()Z
 HSPLandroid/database/AbstractCursor;->moveToNext()Z
 HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z
+HSPLandroid/database/AbstractCursor;->moveToPrevious()Z
 HSPLandroid/database/AbstractCursor;->onChange(Z)V
 HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V
 HSPLandroid/database/AbstractCursor;->onMove(II)Z
 HSPLandroid/database/AbstractCursor;->registerContentObserver(Landroid/database/ContentObserver;)V
+HSPLandroid/database/AbstractCursor;->registerDataSetObserver(Landroid/database/DataSetObserver;)V
 HSPLandroid/database/AbstractCursor;->setNotificationUri(Landroid/content/ContentResolver;Landroid/net/Uri;)V
 HSPLandroid/database/AbstractCursor;->setNotificationUris(Landroid/content/ContentResolver;Ljava/util/List;)V
 HSPLandroid/database/AbstractCursor;->setNotificationUris(Landroid/content/ContentResolver;Ljava/util/List;I)V
@@ -4916,6 +5119,7 @@
 HSPLandroid/database/CursorWindow;->clear()V
 HSPLandroid/database/CursorWindow;->finalize()V
 HSPLandroid/database/CursorWindow;->getBlob(II)[B
+HSPLandroid/database/CursorWindow;->getCursorWindowSize()I
 HSPLandroid/database/CursorWindow;->getDouble(II)D
 HSPLandroid/database/CursorWindow;->getInt(II)I
 HSPLandroid/database/CursorWindow;->getLong(II)J
@@ -4939,6 +5143,7 @@
 HSPLandroid/database/CursorWrapper;->getColumnIndex(Ljava/lang/String;)I
 HSPLandroid/database/CursorWrapper;->getColumnIndexOrThrow(Ljava/lang/String;)I
 HSPLandroid/database/CursorWrapper;->getColumnName(I)Ljava/lang/String;
+HSPLandroid/database/CursorWrapper;->getColumnNames()[Ljava/lang/String;
 HSPLandroid/database/CursorWrapper;->getCount()I
 HSPLandroid/database/CursorWrapper;->getInt(I)I
 HSPLandroid/database/CursorWrapper;->getLong(I)J
@@ -4957,11 +5162,13 @@
 HSPLandroid/database/DataSetObservable;->notifyChanged()V
 HSPLandroid/database/DataSetObservable;->notifyInvalidated()V
 HSPLandroid/database/DataSetObserver;-><init>()V
+HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V
 HSPLandroid/database/DatabaseUtils;->cursorFillWindow(Landroid/database/Cursor;ILandroid/database/CursorWindow;)V
 HSPLandroid/database/DatabaseUtils;->getSqlStatementType(Ljava/lang/String;)I
 HSPLandroid/database/DatabaseUtils;->getTypeOfObject(Ljava/lang/Object;)I
 HSPLandroid/database/DatabaseUtils;->longForQuery(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/String;)J
 HSPLandroid/database/DatabaseUtils;->readExceptionWithFileNotFoundExceptionFromParcel(Landroid/os/Parcel;)V
+HSPLandroid/database/DatabaseUtils;->sqlEscapeString(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/database/DefaultDatabaseErrorHandler;-><init>()V
 HSPLandroid/database/IContentObserver$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/database/IContentObserver$Stub$Proxy;->onChange(ZLandroid/net/Uri;I)V
@@ -4980,6 +5187,7 @@
 HSPLandroid/database/MatrixCursor;->getLong(I)J
 HSPLandroid/database/MatrixCursor;->getString(I)Ljava/lang/String;
 HSPLandroid/database/MatrixCursor;->getType(I)I
+HSPLandroid/database/MatrixCursor;->newRow()Landroid/database/MatrixCursor$RowBuilder;
 HSPLandroid/database/Observable;-><init>()V
 HSPLandroid/database/Observable;->registerObserver(Ljava/lang/Object;)V
 HSPLandroid/database/Observable;->unregisterAll()V
@@ -5095,6 +5303,7 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->isReadOnly()Z
 HSPLandroid/database/sqlite/SQLiteDatabase;->onAllReferencesReleased()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->open()V
+HSPLandroid/database/sqlite/SQLiteDatabase;->openDatabase(Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;I)Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->openDatabase(Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ILandroid/database/DatabaseErrorHandler;)Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->openDatabase(Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->openInner()V
@@ -5134,6 +5343,7 @@
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->setWriteAheadLoggingEnabled(Z)V
 HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteProgram;->bind(ILjava/lang/Object;)V
+HSPLandroid/database/sqlite/SQLiteProgram;->bindBlob(I[B)V
 HSPLandroid/database/sqlite/SQLiteProgram;->bindDouble(ID)V
 HSPLandroid/database/sqlite/SQLiteProgram;->bindLong(IJ)V
 HSPLandroid/database/sqlite/SQLiteProgram;->bindString(ILjava/lang/String;)V
@@ -5228,6 +5438,7 @@
 HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(I)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawPaint(Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawPatch(Landroid/graphics/NinePatch;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(FFFFLandroid/graphics/Paint;)V
@@ -5236,6 +5447,7 @@
 HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/String;FFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawText([CIIFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun([CIIIIFFZLandroid/graphics/Paint;)V
 HSPLandroid/graphics/Bitmap$1;-><init>()V
@@ -5254,11 +5466,12 @@
 HSPLandroid/graphics/Bitmap;->checkXYSign(II)V
 HSPLandroid/graphics/Bitmap;->compress(Landroid/graphics/Bitmap$CompressFormat;ILjava/io/OutputStream;)Z
 HSPLandroid/graphics/Bitmap;->copy(Landroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;
+HPLandroid/graphics/Bitmap;->createAshmemBitmap(Landroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/Bitmap;->createBitmap(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/Bitmap;->createBitmap(Landroid/graphics/Bitmap;IIIILandroid/graphics/Matrix;Z)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/Bitmap;->createBitmap(Landroid/util/DisplayMetrics;IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/Bitmap;->createBitmap(Landroid/util/DisplayMetrics;IILandroid/graphics/Bitmap$Config;ZLandroid/graphics/ColorSpace;)Landroid/graphics/Bitmap;
-PLandroid/graphics/Bitmap;->createGraphicBufferHandle()Landroid/graphics/GraphicBuffer;
+HPLandroid/graphics/Bitmap;->createGraphicBufferHandle()Landroid/graphics/GraphicBuffer;
 HSPLandroid/graphics/Bitmap;->createScaledBitmap(Landroid/graphics/Bitmap;IIZ)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/Bitmap;->eraseColor(I)V
 HSPLandroid/graphics/Bitmap;->getAllocationByteCount()I
@@ -5266,6 +5479,7 @@
 HSPLandroid/graphics/Bitmap;->getColorSpace()Landroid/graphics/ColorSpace;
 HSPLandroid/graphics/Bitmap;->getConfig()Landroid/graphics/Bitmap$Config;
 HSPLandroid/graphics/Bitmap;->getHeight()I
+HSPLandroid/graphics/Bitmap;->getPixel(II)I
 HSPLandroid/graphics/Bitmap;->getPixels([IIIIIII)V
 HSPLandroid/graphics/Bitmap;->getScaledHeight(I)I
 HSPLandroid/graphics/Bitmap;->getScaledWidth(I)I
@@ -5274,8 +5488,10 @@
 HSPLandroid/graphics/Bitmap;->isMutable()Z
 HSPLandroid/graphics/Bitmap;->isRecycled()Z
 HSPLandroid/graphics/Bitmap;->prepareToDraw()V
+HSPLandroid/graphics/Bitmap;->reconfigure(IILandroid/graphics/Bitmap$Config;)V
 HSPLandroid/graphics/Bitmap;->recycle()V
 HSPLandroid/graphics/Bitmap;->reinit(IIZ)V
+HSPLandroid/graphics/Bitmap;->sameAs(Landroid/graphics/Bitmap;)Z
 HSPLandroid/graphics/Bitmap;->scaleFromDensity(III)I
 HSPLandroid/graphics/Bitmap;->setDensity(I)V
 HSPLandroid/graphics/Bitmap;->setHasAlpha(Z)V
@@ -5290,6 +5506,7 @@
 HSPLandroid/graphics/BitmapFactory;->decodeResource(Landroid/content/res/Resources;I)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/BitmapFactory;->decodeResource(Landroid/content/res/Resources;ILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/BitmapFactory;->decodeResourceStream(Landroid/content/res/Resources;Landroid/util/TypedValue;Ljava/io/InputStream;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
+HSPLandroid/graphics/BitmapFactory;->decodeStream(Ljava/io/InputStream;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/BitmapFactory;->decodeStream(Ljava/io/InputStream;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/BitmapFactory;->setDensityFromOptions(Landroid/graphics/Bitmap;Landroid/graphics/BitmapFactory$Options;)V
 HSPLandroid/graphics/BitmapShader;-><init>(Landroid/graphics/Bitmap;II)V
@@ -5298,6 +5515,7 @@
 HSPLandroid/graphics/BlendMode;-><init>(Ljava/lang/String;II)V
 HSPLandroid/graphics/BlendMode;->values()[Landroid/graphics/BlendMode;
 HSPLandroid/graphics/BlurMaskFilter$Blur;-><init>(Ljava/lang/String;II)V
+HSPLandroid/graphics/BlurMaskFilter;-><init>(FLandroid/graphics/BlurMaskFilter$Blur;)V
 HSPLandroid/graphics/Canvas$EdgeType;-><init>(Ljava/lang/String;II)V
 HSPLandroid/graphics/Canvas;-><init>()V
 HSPLandroid/graphics/Canvas;-><init>(J)V
@@ -5309,6 +5527,7 @@
 HSPLandroid/graphics/Canvas;->clipRect(FFFF)Z
 HSPLandroid/graphics/Canvas;->clipRect(IIII)Z
 HSPLandroid/graphics/Canvas;->clipRect(Landroid/graphics/Rect;)Z
+HSPLandroid/graphics/Canvas;->clipRect(Landroid/graphics/Rect;Landroid/graphics/Region$Op;)Z
 HSPLandroid/graphics/Canvas;->concat(Landroid/graphics/Matrix;)V
 HSPLandroid/graphics/Canvas;->drawARGB(IIII)V
 HSPLandroid/graphics/Canvas;->drawBitmap(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V
@@ -5345,6 +5564,8 @@
 HSPLandroid/graphics/Canvas;->rotate(FFF)V
 HSPLandroid/graphics/Canvas;->save()I
 HSPLandroid/graphics/Canvas;->save(I)I
+HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFI)I
+HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFII)I
 HSPLandroid/graphics/Canvas;->scale(FF)V
 HSPLandroid/graphics/Canvas;->scale(FFFF)V
 HSPLandroid/graphics/Canvas;->setBitmap(Landroid/graphics/Bitmap;)V
@@ -5354,6 +5575,7 @@
 HSPLandroid/graphics/Canvas;->setScreenDensity(I)V
 HSPLandroid/graphics/Canvas;->translate(FF)V
 HSPLandroid/graphics/CanvasProperty;->getNativeContainer()J
+HSPLandroid/graphics/Color;->HSVToColor([F)I
 HSPLandroid/graphics/Color;->alpha(I)I
 HSPLandroid/graphics/Color;->alpha(J)F
 HSPLandroid/graphics/Color;->argb(IIII)I
@@ -5372,6 +5594,9 @@
 HSPLandroid/graphics/Color;->valueOf(I)Landroid/graphics/Color;
 HSPLandroid/graphics/ColorFilter;->access$000()J
 HSPLandroid/graphics/ColorFilter;->getNativeInstance()J
+HSPLandroid/graphics/ColorMatrix;-><init>()V
+HSPLandroid/graphics/ColorMatrix;-><init>([F)V
+HSPLandroid/graphics/ColorMatrix;->reset()V
 HSPLandroid/graphics/ColorMatrix;->set(Landroid/graphics/ColorMatrix;)V
 HSPLandroid/graphics/ColorMatrixColorFilter;-><init>(Landroid/graphics/ColorMatrix;)V
 HSPLandroid/graphics/ColorMatrixColorFilter;->createNativeInstance()J
@@ -5434,7 +5659,7 @@
 HPLandroid/graphics/GraphicBuffer;-><init>(IIIIJ)V
 HSPLandroid/graphics/GraphicBuffer;->createFromExisting(IIIIJ)Landroid/graphics/GraphicBuffer;
 HSPLandroid/graphics/GraphicBuffer;->finalize()V
-PLandroid/graphics/GraphicBuffer;->getFormat()I
+HPLandroid/graphics/GraphicBuffer;->getFormat()I
 HPLandroid/graphics/GraphicBuffer;->getHeight()I
 HPLandroid/graphics/GraphicBuffer;->getWidth()I
 HPLandroid/graphics/GraphicBuffer;->writeToParcel(Landroid/os/Parcel;I)V
@@ -5449,7 +5674,7 @@
 HSPLandroid/graphics/HardwareRenderer;-><init>()V
 HSPLandroid/graphics/HardwareRenderer;->allocateBuffers()V
 HSPLandroid/graphics/HardwareRenderer;->clearContent()V
-PLandroid/graphics/HardwareRenderer;->createHardwareBitmap(Landroid/graphics/RenderNode;II)Landroid/graphics/Bitmap;
+HPLandroid/graphics/HardwareRenderer;->createHardwareBitmap(Landroid/graphics/RenderNode;II)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/HardwareRenderer;->destroy()V
 HSPLandroid/graphics/HardwareRenderer;->loadSystemProperties()Z
 HSPLandroid/graphics/HardwareRenderer;->notifyFramePending()V
@@ -5489,6 +5714,7 @@
 HSPLandroid/graphics/ImageDecoder;->computeDensity(Landroid/graphics/ImageDecoder$Source;)I
 HSPLandroid/graphics/ImageDecoder;->createFromAsset(Landroid/content/res/AssetManager$AssetInputStream;Landroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;
 HSPLandroid/graphics/ImageDecoder;->createFromStream(Ljava/io/InputStream;ZLandroid/graphics/ImageDecoder$Source;)Landroid/graphics/ImageDecoder;
+HSPLandroid/graphics/ImageDecoder;->createSource(Landroid/content/res/Resources;Ljava/io/InputStream;)Landroid/graphics/ImageDecoder$Source;
 HSPLandroid/graphics/ImageDecoder;->createSource(Landroid/content/res/Resources;Ljava/io/InputStream;I)Landroid/graphics/ImageDecoder$Source;
 HSPLandroid/graphics/ImageDecoder;->decodeBitmap(Landroid/graphics/ImageDecoder$Source;Landroid/graphics/ImageDecoder$OnHeaderDecodedListener;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/ImageDecoder;->decodeBitmapImpl(Landroid/graphics/ImageDecoder$Source;Landroid/graphics/ImageDecoder$OnHeaderDecodedListener;)Landroid/graphics/Bitmap;
@@ -5549,6 +5775,7 @@
 HSPLandroid/graphics/Matrix;->setScale(FF)V
 HSPLandroid/graphics/Matrix;->setScale(FFFF)V
 HSPLandroid/graphics/Matrix;->setTranslate(FF)V
+HSPLandroid/graphics/Matrix;->setValues([F)V
 HSPLandroid/graphics/NinePatch$InsetStruct;-><init>(IIIIIIIIFIF)V
 HSPLandroid/graphics/NinePatch$InsetStruct;->scaleInsets(IIIIF)Landroid/graphics/Rect;
 HSPLandroid/graphics/NinePatch;->draw(Landroid/graphics/Canvas;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
@@ -5558,6 +5785,7 @@
 HSPLandroid/graphics/NinePatch;->getHeight()I
 HSPLandroid/graphics/NinePatch;->getWidth()I
 HSPLandroid/graphics/Outline;-><init>()V
+HSPLandroid/graphics/Outline;->setAlpha(F)V
 HSPLandroid/graphics/Outline;->setConvexPath(Landroid/graphics/Path;)V
 HSPLandroid/graphics/Outline;->setEmpty()V
 HSPLandroid/graphics/Outline;->setOval(IIII)V
@@ -5566,6 +5794,7 @@
 HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V
 HSPLandroid/graphics/Paint$Align;-><init>(Ljava/lang/String;II)V
 HSPLandroid/graphics/Paint$Cap;-><init>(Ljava/lang/String;II)V
+HSPLandroid/graphics/Paint$FontMetrics;-><init>()V
 HSPLandroid/graphics/Paint$Join;-><init>(Ljava/lang/String;II)V
 HSPLandroid/graphics/Paint$Style;-><init>(Ljava/lang/String;II)V
 HSPLandroid/graphics/Paint;-><init>()V
@@ -5607,6 +5836,8 @@
 HSPLandroid/graphics/Paint;->getTextScaleX()F
 HSPLandroid/graphics/Paint;->getTextSize()F
 HSPLandroid/graphics/Paint;->getTypeface()Landroid/graphics/Typeface;
+HSPLandroid/graphics/Paint;->getUnderlinePosition()F
+HSPLandroid/graphics/Paint;->getUnderlineThickness()F
 HSPLandroid/graphics/Paint;->getXfermode()Landroid/graphics/Xfermode;
 HSPLandroid/graphics/Paint;->hasGlyph(Ljava/lang/String;)Z
 HSPLandroid/graphics/Paint;->isAntiAlias()Z
@@ -5631,6 +5862,7 @@
 HSPLandroid/graphics/Paint;->setFilterBitmap(Z)V
 HSPLandroid/graphics/Paint;->setFlags(I)V
 HSPLandroid/graphics/Paint;->setLetterSpacing(F)V
+HSPLandroid/graphics/Paint;->setMaskFilter(Landroid/graphics/MaskFilter;)Landroid/graphics/MaskFilter;
 HSPLandroid/graphics/Paint;->setPathEffect(Landroid/graphics/PathEffect;)Landroid/graphics/PathEffect;
 HSPLandroid/graphics/Paint;->setShader(Landroid/graphics/Shader;)Landroid/graphics/Shader;
 HSPLandroid/graphics/Paint;->setShadowLayer(FFFI)V
@@ -5654,7 +5886,9 @@
 HSPLandroid/graphics/Path$FillType;-><init>(Ljava/lang/String;II)V
 HSPLandroid/graphics/Path;-><init>()V
 HSPLandroid/graphics/Path;-><init>(Landroid/graphics/Path;)V
+HSPLandroid/graphics/Path;->addOval(FFFFLandroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRect(FFFFLandroid/graphics/Path$Direction;)V
+HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRoundRect(FFFF[FLandroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRoundRect(Landroid/graphics/RectF;[FLandroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->approximate(F)[F
@@ -5687,6 +5921,7 @@
 HSPLandroid/graphics/Point;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/graphics/PointF$1;-><init>()V
 HSPLandroid/graphics/PointF;-><init>()V
+HSPLandroid/graphics/PointF;-><init>(FF)V
 HSPLandroid/graphics/PointF;->length(FF)F
 HSPLandroid/graphics/PointF;->set(FF)V
 HSPLandroid/graphics/PorterDuff$Mode;-><init>(Ljava/lang/String;II)V
@@ -5717,6 +5952,7 @@
 HSPLandroid/graphics/Rect;->centerX()I
 HSPLandroid/graphics/Rect;->centerY()I
 HSPLandroid/graphics/Rect;->contains(II)Z
+HSPLandroid/graphics/Rect;->contains(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/Rect;->equals(Ljava/lang/Object;)Z
 HSPLandroid/graphics/Rect;->exactCenterX()F
 HSPLandroid/graphics/Rect;->exactCenterY()F
@@ -5788,7 +6024,7 @@
 HSPLandroid/graphics/RenderNode;->beginRecording(II)Landroid/graphics/RecordingCanvas;
 HSPLandroid/graphics/RenderNode;->create(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)Landroid/graphics/RenderNode;
 HSPLandroid/graphics/RenderNode;->discardDisplayList()V
-PLandroid/graphics/RenderNode;->end(Landroid/graphics/RecordingCanvas;)V
+HPLandroid/graphics/RenderNode;->end(Landroid/graphics/RecordingCanvas;)V
 HSPLandroid/graphics/RenderNode;->endRecording()V
 HSPLandroid/graphics/RenderNode;->getClipToOutline()Z
 HSPLandroid/graphics/RenderNode;->getElevation()F
@@ -5811,6 +6047,7 @@
 HSPLandroid/graphics/RenderNode;->setAlpha(F)Z
 HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z
 HSPLandroid/graphics/RenderNode;->setBottom(I)Z
+HSPLandroid/graphics/RenderNode;->setClipRect(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/RenderNode;->setClipToBounds(Z)Z
 HSPLandroid/graphics/RenderNode;->setClipToOutline(Z)Z
 HSPLandroid/graphics/RenderNode;->setElevation(F)Z
@@ -5834,7 +6071,7 @@
 HSPLandroid/graphics/RenderNode;->setTranslationY(F)Z
 HSPLandroid/graphics/RenderNode;->setTranslationZ(F)Z
 HSPLandroid/graphics/RenderNode;->setUsageHint(I)V
-PLandroid/graphics/RenderNode;->start(II)Landroid/graphics/RecordingCanvas;
+HPLandroid/graphics/RenderNode;->start(II)Landroid/graphics/RecordingCanvas;
 HSPLandroid/graphics/Shader$TileMode;-><init>(Ljava/lang/String;II)V
 HSPLandroid/graphics/Shader;->access$000()J
 HSPLandroid/graphics/Shader;->colorSpace()Landroid/graphics/ColorSpace;
@@ -5852,6 +6089,7 @@
 HSPLandroid/graphics/SurfaceTexture;->updateTexImage()V
 HSPLandroid/graphics/TemporaryBuffer;->obtain(I)[C
 HSPLandroid/graphics/TemporaryBuffer;->recycle([C)V
+HSPLandroid/graphics/Typeface$Builder;->build()Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;
 HSPLandroid/graphics/Typeface$CustomFallbackBuilder;-><init>(Landroid/graphics/fonts/FontFamily;)V
 HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->build()Landroid/graphics/Typeface;
@@ -5860,6 +6098,7 @@
 HSPLandroid/graphics/Typeface;->create(Ljava/lang/String;I)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->createFromFamiliesWithDefault([Landroid/graphics/FontFamily;Ljava/lang/String;II)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->createFromResources(Landroid/content/res/FontResourcesParser$FamilyResourceEntry;Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;
+HSPLandroid/graphics/Typeface;->defaultFromStyle(I)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->getStyle()I
 HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;
@@ -5877,6 +6116,7 @@
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable$LayerState;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable$LayerState;->invalidateCache()V
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable$LayerState;->isStateful()Z
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable$LayerState;->newDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable$LayerState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;-><init>(Landroid/graphics/drawable/AdaptiveIconDrawable$LayerState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->canApplyTheme()Z
@@ -5886,11 +6126,13 @@
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->getIntrinsicHeight()I
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->getIntrinsicWidth()I
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->getOpacity()I
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->inflateLayers(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->invalidateSelf()V
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->isStateful()Z
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->setVisible(ZZ)Z
 HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->updateLayerBounds(Landroid/graphics/Rect;)V
@@ -5908,6 +6150,8 @@
 HSPLandroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;->mutate()V
 HSPLandroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;->transitionHasReversibleFlag(II)Z
+HSPLandroid/graphics/drawable/AnimatedStateListDrawable$AnimatedVectorDrawableTransition;->start()V
+HSPLandroid/graphics/drawable/AnimatedStateListDrawable$AnimatedVectorDrawableTransition;->stop()V
 HSPLandroid/graphics/drawable/AnimatedStateListDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/AnimatedStateListDrawable;->clearMutated()V
 HSPLandroid/graphics/drawable/AnimatedStateListDrawable;->cloneConstantState()Landroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;
@@ -5944,6 +6188,7 @@
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->createRTAnimatorForPath(Landroid/animation/ObjectAnimator;Landroid/graphics/drawable/VectorDrawable$VPath;J)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->end()V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->getAnimatorNativePtr()J
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->getFrameCount(J)I
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->handlePendingAction(I)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->init(Landroid/animation/AnimatorSet;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->isInfinite()Z
@@ -5970,7 +6215,9 @@
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->setHotspot(FF)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->setTintMode(Landroid/graphics/PorterDuff$Mode;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->setVisible(ZZ)Z
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->start()V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->stop()V
@@ -5986,10 +6233,13 @@
 HSPLandroid/graphics/drawable/AnimationDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/AnimationDrawable;->isRunning()Z
 HSPLandroid/graphics/drawable/AnimationDrawable;->mutate()Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/AnimationDrawable;->nextFrame(Z)V
+HSPLandroid/graphics/drawable/AnimationDrawable;->run()V
 HSPLandroid/graphics/drawable/AnimationDrawable;->setConstantState(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;)V
 HSPLandroid/graphics/drawable/AnimationDrawable;->setFrame(IZZ)V
 HSPLandroid/graphics/drawable/AnimationDrawable;->setVisible(ZZ)Z
 HSPLandroid/graphics/drawable/AnimationDrawable;->start()V
+HSPLandroid/graphics/drawable/AnimationDrawable;->stop()V
 HSPLandroid/graphics/drawable/AnimationDrawable;->unscheduleSelf(Ljava/lang/Runnable;)V
 HSPLandroid/graphics/drawable/BitmapDrawable$BitmapState;-><init>(Landroid/graphics/Bitmap;)V
 HSPLandroid/graphics/drawable/BitmapDrawable$BitmapState;-><init>(Landroid/graphics/drawable/BitmapDrawable$BitmapState;)V
@@ -6056,9 +6306,16 @@
 HSPLandroid/graphics/drawable/Drawable$ConstantState;-><init>()V
 HSPLandroid/graphics/drawable/Drawable$ConstantState;->newDrawable(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/Drawable;-><init>()V
+HSPLandroid/graphics/drawable/Drawable;->canApplyTheme()Z
+HSPLandroid/graphics/drawable/Drawable;->clearColorFilter()V
+HSPLandroid/graphics/drawable/Drawable;->copyBounds()Landroid/graphics/Rect;
 HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V
+HSPLandroid/graphics/drawable/Drawable;->createFromResourceStream(Landroid/content/res/Resources;Landroid/util/TypedValue;Ljava/io/InputStream;Ljava/lang/String;)Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/Drawable;->createFromResourceStream(Landroid/content/res/Resources;Landroid/util/TypedValue;Ljava/io/InputStream;Ljava/lang/String;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/Drawable;->createFromStream(Ljava/io/InputStream;Ljava/lang/String;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/Drawable;->createFromXmlForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/Drawable;->createFromXmlInner(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/Drawable;->getBitmapDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;Ljava/io/InputStream;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/Drawable;->getBounds()Landroid/graphics/Rect;
 HSPLandroid/graphics/drawable/Drawable;->getCallback()Landroid/graphics/drawable/Drawable$Callback;
 HSPLandroid/graphics/drawable/Drawable;->getChangingConfigurations()I
@@ -6102,6 +6359,7 @@
 HSPLandroid/graphics/drawable/Drawable;->unscheduleSelf(Ljava/lang/Runnable;)V
 HSPLandroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;Ljava/lang/Runnable;)V
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->unwrap()Landroid/graphics/drawable/Drawable$Callback;
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->wrap(Landroid/graphics/drawable/Drawable$Callback;)Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;
 HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V
@@ -6142,6 +6400,7 @@
 HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/DrawableContainer;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/DrawableContainer;->onBoundsChange(Landroid/graphics/Rect;)V
+HSPLandroid/graphics/drawable/DrawableContainer;->onLevelChange(I)Z
 HSPLandroid/graphics/drawable/DrawableContainer;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/DrawableContainer;->selectDrawable(I)Z
 HSPLandroid/graphics/drawable/DrawableContainer;->setAlpha(I)V
@@ -6153,6 +6412,7 @@
 HSPLandroid/graphics/drawable/DrawableContainer;->setTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/DrawableContainer;->setTintMode(Landroid/graphics/PorterDuff$Mode;)V
 HSPLandroid/graphics/drawable/DrawableContainer;->setVisible(ZZ)Z
+HSPLandroid/graphics/drawable/DrawableContainer;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;Ljava/lang/Runnable;)V
 HSPLandroid/graphics/drawable/DrawableContainer;->updateDensity(Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/DrawableInflater;->inflateFromClass(Ljava/lang/String;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/DrawableInflater;->inflateFromTag(Ljava/lang/String;)Landroid/graphics/drawable/Drawable;
@@ -6185,6 +6445,7 @@
 HSPLandroid/graphics/drawable/DrawableWrapper;->setColorFilter(Landroid/graphics/ColorFilter;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setHotspot(FF)V
+HSPLandroid/graphics/drawable/DrawableWrapper;->setTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setVisible(ZZ)Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->updateLocalState(Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
@@ -6200,6 +6461,7 @@
 HSPLandroid/graphics/drawable/GradientDrawable$Orientation;->values()[Landroid/graphics/drawable/GradientDrawable$Orientation;
 HSPLandroid/graphics/drawable/GradientDrawable;-><init>()V
 HSPLandroid/graphics/drawable/GradientDrawable;-><init>(Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/GradientDrawable;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V
 HSPLandroid/graphics/drawable/GradientDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->applyThemeChildElements(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->canApplyTheme()Z
@@ -6229,6 +6491,8 @@
 HSPLandroid/graphics/drawable/GradientDrawable;->setCornerRadii([F)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setCornerRadius(F)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setDither(Z)V
+HSPLandroid/graphics/drawable/GradientDrawable;->setGradientRadius(F)V
+HSPLandroid/graphics/drawable/GradientDrawable;->setGradientType(I)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setShape(I)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setStroke(II)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setStroke(IIFF)V
@@ -6332,6 +6596,7 @@
 HSPLandroid/graphics/drawable/LayerDrawable;->setAutoMirrored(Z)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setDither(Z)V
+HSPLandroid/graphics/drawable/LayerDrawable;->setDrawable(ILandroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setHotspot(FF)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setId(II)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setLayerInset(IIIII)V
@@ -6344,6 +6609,7 @@
 HSPLandroid/graphics/drawable/NinePatchDrawable$NinePatchState;-><init>()V
 HSPLandroid/graphics/drawable/NinePatchDrawable$NinePatchState;-><init>(Landroid/graphics/NinePatch;Landroid/graphics/Rect;Landroid/graphics/Rect;ZZ)V
 HSPLandroid/graphics/drawable/NinePatchDrawable$NinePatchState;-><init>(Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;)V
+HSPLandroid/graphics/drawable/NinePatchDrawable$NinePatchState;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/NinePatchDrawable$NinePatchState;->newDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/NinePatchDrawable$NinePatchState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/NinePatchDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
@@ -6432,6 +6698,7 @@
 HSPLandroid/graphics/drawable/RippleForeground;-><init>(Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/Rect;FFZ)V
 HSPLandroid/graphics/drawable/RippleForeground;->clampStartingPosition()V
 HSPLandroid/graphics/drawable/RippleForeground;->draw(Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
+HSPLandroid/graphics/drawable/RippleForeground;->drawSoftware(Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/drawable/RippleForeground;->end()V
 HSPLandroid/graphics/drawable/RippleForeground;->getBounds(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/RippleForeground;->hasFinishedExit()Z
@@ -6461,10 +6728,13 @@
 HSPLandroid/graphics/drawable/ScaleDrawable;->onLevelChange(I)Z
 HSPLandroid/graphics/drawable/ScaleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/ScaleDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
+HSPLandroid/graphics/drawable/ShapeDrawable$ShapeState;-><init>(Landroid/graphics/drawable/ShapeDrawable$ShapeState;)V
+HSPLandroid/graphics/drawable/ShapeDrawable;-><init>()V
 HSPLandroid/graphics/drawable/ShapeDrawable;-><init>(Landroid/graphics/drawable/shapes/Shape;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->getAlpha()I
 HSPLandroid/graphics/drawable/ShapeDrawable;->getChangingConfigurations()I
+HSPLandroid/graphics/drawable/ShapeDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
 HSPLandroid/graphics/drawable/ShapeDrawable;->getIntrinsicHeight()I
 HSPLandroid/graphics/drawable/ShapeDrawable;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/ShapeDrawable;->getOpacity()I
@@ -6472,10 +6742,13 @@
 HSPLandroid/graphics/drawable/ShapeDrawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/ShapeDrawable;->getPaint()Landroid/graphics/Paint;
 HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z
+HSPLandroid/graphics/drawable/ShapeDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/ShapeDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->onDraw(Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->setAlpha(I)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
+HSPLandroid/graphics/drawable/ShapeDrawable;->setIntrinsicHeight(I)V
+HSPLandroid/graphics/drawable/ShapeDrawable;->setIntrinsicWidth(I)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->setShape(Landroid/graphics/drawable/shapes/Shape;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V
 HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->addStateSet([ILandroid/graphics/drawable/Drawable;)I
@@ -6496,6 +6769,7 @@
 HSPLandroid/graphics/drawable/StateListDrawable;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/StateListDrawable;->setConstantState(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;)V
 HSPLandroid/graphics/drawable/StateListDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
+HSPLandroid/graphics/drawable/TransitionDrawable$TransitionState;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/TransitionDrawable;-><init>([Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/TransitionDrawable;->createConstantState(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)Landroid/graphics/drawable/LayerDrawable$LayerState;
 HSPLandroid/graphics/drawable/TransitionDrawable;->draw(Landroid/graphics/Canvas;)V
@@ -6517,6 +6791,7 @@
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath$9;-><init>(Ljava/lang/String;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->canApplyTheme()Z
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getFillColor()I
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getNativePtr()J
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getNativeSize()I
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getProperty(Ljava/lang/String;)Landroid/util/Property;
@@ -6544,6 +6819,7 @@
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
+HSPLandroid/graphics/drawable/VectorDrawable$VObject;->isTreeValid()Z
 HSPLandroid/graphics/drawable/VectorDrawable$VObject;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VPath$1;-><init>(Ljava/lang/Class;Ljava/lang/String;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState$1;-><init>(Ljava/lang/String;)V
@@ -6592,6 +6868,7 @@
 HSPLandroid/graphics/drawable/VectorDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
+HSPLandroid/graphics/drawable/VectorDrawable;->setAlpha(I)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setAutoMirrored(Z)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
@@ -6606,6 +6883,7 @@
 HSPLandroid/graphics/drawable/shapes/PathShape;->onResize(FF)V
 HSPLandroid/graphics/drawable/shapes/RectShape;->onResize(FF)V
 HSPLandroid/graphics/drawable/shapes/RoundRectShape;-><init>([FLandroid/graphics/RectF;[F)V
+HSPLandroid/graphics/drawable/shapes/RoundRectShape;->draw(Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/drawable/shapes/RoundRectShape;->onResize(FF)V
 HSPLandroid/graphics/fonts/Font$Builder;-><init>(Ljava/nio/ByteBuffer;)V
 HSPLandroid/graphics/fonts/Font$Builder;->build()Landroid/graphics/fonts/Font;
@@ -6648,6 +6926,7 @@
 HSPLandroid/graphics/text/LineBreaker;->access$100()J
 HSPLandroid/graphics/text/LineBreaker;->computeLineBreaks(Landroid/graphics/text/MeasuredText;Landroid/graphics/text/LineBreaker$ParagraphConstraints;I)Landroid/graphics/text/LineBreaker$Result;
 HSPLandroid/graphics/text/MeasuredText$Builder;-><init>([C)V
+HSPLandroid/graphics/text/MeasuredText$Builder;->appendReplacementRun(Landroid/graphics/Paint;IF)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;IZ)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->build()Landroid/graphics/text/MeasuredText;
 HSPLandroid/graphics/text/MeasuredText;->access$000()J
@@ -6657,6 +6936,7 @@
 PLandroid/gsi/IGsiService$Stub$Proxy;->isGsiInstalled()Z
 PLandroid/gsi/IGsiService$Stub$Proxy;->isGsiRunning()Z
 PLandroid/gsi/IGsiService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/gsi/IGsiService;
+HSPLandroid/hardware/Camera;->getCameraInfo(ILandroid/hardware/Camera$CameraInfo;)V
 HSPLandroid/hardware/CameraStatus$1;-><init>()V
 HSPLandroid/hardware/CameraStatus$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/CameraStatus;
 HSPLandroid/hardware/CameraStatus$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -6669,7 +6949,7 @@
 HSPLandroid/hardware/GeomagneticField;->getDeclination()F
 HSPLandroid/hardware/GeomagneticField;->getFieldStrength()F
 HSPLandroid/hardware/GeomagneticField;->getHorizontalStrength()F
-PLandroid/hardware/GeomagneticField;->getInclination()F
+HPLandroid/hardware/GeomagneticField;->getInclination()F
 HSPLandroid/hardware/HardwareBuffer$1;-><init>()V
 HSPLandroid/hardware/HardwareBuffer;-><init>(J)V
 HSPLandroid/hardware/HardwareBuffer;->createFromGraphicBuffer(Landroid/graphics/GraphicBuffer;)Landroid/hardware/HardwareBuffer;
@@ -6689,6 +6969,7 @@
 HSPLandroid/hardware/ISensorPrivacyManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/hardware/ISerialManager$Stub;-><init>()V
 HSPLandroid/hardware/Sensor;->getName()Ljava/lang/String;
+HSPLandroid/hardware/Sensor;->getVendor()Ljava/lang/String;
 HSPLandroid/hardware/Sensor;->setType(I)Z
 HSPLandroid/hardware/Sensor;->setUuid(JJ)V
 PLandroid/hardware/SensorAdditionalInfo;->createLocalGeomagneticField(FFF)Landroid/hardware/SensorAdditionalInfo;
@@ -6699,7 +6980,7 @@
 HSPLandroid/hardware/SensorManager;->registerListener(Landroid/hardware/SensorEventListener;Landroid/hardware/Sensor;I)Z
 HSPLandroid/hardware/SensorManager;->registerListener(Landroid/hardware/SensorEventListener;Landroid/hardware/Sensor;ILandroid/os/Handler;)Z
 HSPLandroid/hardware/SensorManager;->requestTriggerSensor(Landroid/hardware/TriggerEventListener;Landroid/hardware/Sensor;)Z
-PLandroid/hardware/SensorManager;->setOperationParameter(Landroid/hardware/SensorAdditionalInfo;)Z
+HPLandroid/hardware/SensorManager;->setOperationParameter(Landroid/hardware/SensorAdditionalInfo;)Z
 HSPLandroid/hardware/SensorManager;->unregisterListener(Landroid/hardware/SensorEventListener;)V
 HSPLandroid/hardware/SystemSensorManager$BaseEventQueue;-><init>(Landroid/os/Looper;Landroid/hardware/SystemSensorManager;ILjava/lang/String;)V
 HSPLandroid/hardware/SystemSensorManager$BaseEventQueue;->addSensor(Landroid/hardware/Sensor;II)Z
@@ -6717,11 +6998,11 @@
 HSPLandroid/hardware/SystemSensorManager;->getFullSensorList()Ljava/util/List;
 HSPLandroid/hardware/SystemSensorManager;->registerListenerImpl(Landroid/hardware/SensorEventListener;Landroid/hardware/Sensor;ILandroid/os/Handler;II)Z
 HSPLandroid/hardware/SystemSensorManager;->requestTriggerSensorImpl(Landroid/hardware/TriggerEventListener;Landroid/hardware/Sensor;)Z
-PLandroid/hardware/SystemSensorManager;->setOperationParameterImpl(Landroid/hardware/SensorAdditionalInfo;)Z
+HPLandroid/hardware/SystemSensorManager;->setOperationParameterImpl(Landroid/hardware/SensorAdditionalInfo;)Z
 HSPLandroid/hardware/SystemSensorManager;->unregisterListenerImpl(Landroid/hardware/SensorEventListener;Landroid/hardware/Sensor;)V
 HSPLandroid/hardware/biometrics/BiometricAuthenticator$Identifier;->getBiometricId()I
 HSPLandroid/hardware/biometrics/BiometricManager;->hasBiometrics(Landroid/content/Context;)Z
-PLandroid/hardware/biometrics/BiometricManager;->resetLockout([B)V
+HPLandroid/hardware/biometrics/BiometricManager;->resetLockout([B)V
 HSPLandroid/hardware/biometrics/BiometricSourceType$1;-><init>()V
 HSPLandroid/hardware/biometrics/BiometricSourceType$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/biometrics/BiometricSourceType;
 HSPLandroid/hardware/biometrics/BiometricSourceType$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -6809,6 +7090,7 @@
 HSPLandroid/hardware/camera2/impl/CameraMetadataNative;->setDisplaySize(Landroid/util/Size;)V
 HSPLandroid/hardware/camera2/impl/CameraMetadataNative;->setupGlobalVendorTagDescriptor()V
 HSPLandroid/hardware/camera2/marshal/MarshalHelpers;->checkNativeType(I)I
+HSPLandroid/hardware/camera2/marshal/MarshalRegistry$MarshalToken;->equals(Ljava/lang/Object;)Z
 HSPLandroid/hardware/camera2/marshal/MarshalRegistry$MarshalToken;->hashCode()I
 HSPLandroid/hardware/camera2/marshal/MarshalRegistry;->getMarshaler(Landroid/hardware/camera2/utils/TypeReference;I)Landroid/hardware/camera2/marshal/Marshaler;
 HSPLandroid/hardware/camera2/marshal/MarshalRegistry;->registerMarshalQueryable(Landroid/hardware/camera2/marshal/MarshalQueryable;)V
@@ -6829,6 +7111,7 @@
 PLandroid/hardware/camera2/utils/ArrayUtils;->contains([Ljava/lang/Object;Ljava/lang/Object;)Z
 HSPLandroid/hardware/camera2/utils/TypeReference;-><init>()V
 HSPLandroid/hardware/camera2/utils/TypeReference;->containsTypeVariable(Ljava/lang/reflect/Type;)Z
+HSPLandroid/hardware/camera2/utils/TypeReference;->equals(Ljava/lang/Object;)Z
 HSPLandroid/hardware/camera2/utils/TypeReference;->getRawType(Ljava/lang/reflect/Type;)Ljava/lang/Class;
 HSPLandroid/hardware/camera2/utils/TypeReference;->getType()Ljava/lang/reflect/Type;
 HSPLandroid/hardware/camera2/utils/TypeReference;->hashCode()I
@@ -6841,11 +7124,11 @@
 HSPLandroid/hardware/contexthub/V1_0/HubAppInfo;->readVectorFromParcel(Landroid/os/HwParcel;)Ljava/util/ArrayList;
 HSPLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->getHubs()Ljava/util/ArrayList;
 HSPLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->interfaceChain()Ljava/util/ArrayList;
-PLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->loadNanoApp(ILandroid/hardware/contexthub/V1_0/NanoAppBinary;I)I
+HPLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->loadNanoApp(ILandroid/hardware/contexthub/V1_0/NanoAppBinary;I)I
 HSPLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->queryApps(I)I
 HSPLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->registerCallback(ILandroid/hardware/contexthub/V1_0/IContexthubCallback;)I
 HSPLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->sendMessageToHub(ILandroid/hardware/contexthub/V1_0/ContextHubMsg;)I
-PLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->unloadNanoApp(IJI)I
+HPLandroid/hardware/contexthub/V1_0/IContexthub$Proxy;->unloadNanoApp(IJI)I
 HSPLandroid/hardware/contexthub/V1_0/IContexthub;->asInterface(Landroid/os/IHwBinder;)Landroid/hardware/contexthub/V1_0/IContexthub;
 HSPLandroid/hardware/contexthub/V1_0/IContexthub;->getService(Z)Landroid/hardware/contexthub/V1_0/IContexthub;
 HSPLandroid/hardware/contexthub/V1_0/IContexthubCallback$Stub;-><init>()V
@@ -6858,10 +7141,11 @@
 HSPLandroid/hardware/display/AmbientBrightnessDayStats;-><init>(Ljava/time/LocalDate;[F[F)V
 HSPLandroid/hardware/display/AmbientBrightnessDayStats;->getBucketIndex(F)I
 HSPLandroid/hardware/display/AmbientBrightnessDayStats;->log(FF)V
-PLandroid/hardware/display/AmbientBrightnessDayStats;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/hardware/display/AmbientBrightnessDayStats;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;-><init>(Landroid/content/Context;)V
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->accessibilityInversionEnabled(I)Z
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->alwaysOnAvailable()Z
+HSPLandroid/hardware/display/AmbientDisplayConfiguration;->alwaysOnAvailableForUser(I)Z
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->alwaysOnEnabled(I)Z
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->ambientDisplayAvailable()Z
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->ambientDisplayComponent()Ljava/lang/String;
@@ -6870,6 +7154,8 @@
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->doubleTapSensorType()Ljava/lang/String;
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->dozePickupSensorAvailable()Z
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->enabled(I)Z
+HSPLandroid/hardware/display/AmbientDisplayConfiguration;->longPressSensorType()Ljava/lang/String;
+HSPLandroid/hardware/display/AmbientDisplayConfiguration;->pickupGestureEnabled(I)Z
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->pulseOnNotificationAvailable()Z
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->pulseOnNotificationEnabled(I)Z
 HSPLandroid/hardware/display/AmbientDisplayConfiguration;->tapSensorAvailable()Z
@@ -6880,9 +7166,10 @@
 HSPLandroid/hardware/display/BrightnessChangeEvent$Builder;->build()Landroid/hardware/display/BrightnessChangeEvent;
 HSPLandroid/hardware/display/BrightnessChangeEvent$Builder;->setColorValues([JJ)Landroid/hardware/display/BrightnessChangeEvent$Builder;
 HSPLandroid/hardware/display/BrightnessChangeEvent;-><init>(FJLjava/lang/String;I[F[JFFZIFZZ[JJ)V
+HPLandroid/hardware/display/BrightnessChangeEvent;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/display/BrightnessConfiguration$1;-><init>()V
-PLandroid/hardware/display/BrightnessConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/display/BrightnessConfiguration;
-PLandroid/hardware/display/BrightnessConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/hardware/display/BrightnessConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/display/BrightnessConfiguration;
+HPLandroid/hardware/display/BrightnessConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/hardware/display/BrightnessConfiguration$Builder;-><init>([F[F)V
 HSPLandroid/hardware/display/BrightnessConfiguration$Builder;->addCorrectionByCategory(ILandroid/hardware/display/BrightnessCorrection;)Landroid/hardware/display/BrightnessConfiguration$Builder;
 HSPLandroid/hardware/display/BrightnessConfiguration$Builder;->addCorrectionByPackageName(Ljava/lang/String;Landroid/hardware/display/BrightnessCorrection;)Landroid/hardware/display/BrightnessConfiguration$Builder;
@@ -6891,12 +7178,15 @@
 HSPLandroid/hardware/display/BrightnessConfiguration$Builder;->getMaxCorrectionsByCategory()I
 HSPLandroid/hardware/display/BrightnessConfiguration$Builder;->getMaxCorrectionsByPackageName()I
 HSPLandroid/hardware/display/BrightnessConfiguration;->equals(Ljava/lang/Object;)Z
-PLandroid/hardware/display/BrightnessConfiguration;->getCorrectionByCategory(I)Landroid/hardware/display/BrightnessCorrection;
+HPLandroid/hardware/display/BrightnessConfiguration;->getCorrectionByCategory(I)Landroid/hardware/display/BrightnessCorrection;
 HSPLandroid/hardware/display/BrightnessConfiguration;->getCorrectionByPackageName(Ljava/lang/String;)Landroid/hardware/display/BrightnessCorrection;
 HSPLandroid/hardware/display/BrightnessConfiguration;->getCurve()Landroid/util/Pair;
 HSPLandroid/hardware/display/BrightnessConfiguration;->loadFloatFromXml(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;)F
 HSPLandroid/hardware/display/BrightnessConfiguration;->loadFromXml(Lorg/xmlpull/v1/XmlPullParser;)Landroid/hardware/display/BrightnessConfiguration;
+HPLandroid/hardware/display/BrightnessConfiguration;->saveToXml(Lorg/xmlpull/v1/XmlSerializer;)V
 HSPLandroid/hardware/display/BrightnessCorrection$1;-><init>()V
+HPLandroid/hardware/display/BrightnessCorrection$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/display/BrightnessCorrection;
+HPLandroid/hardware/display/BrightnessCorrection$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/hardware/display/BrightnessCorrection$ScaleAndTranslateLog;-><init>(FF)V
 HSPLandroid/hardware/display/BrightnessCorrection$ScaleAndTranslateLog;->apply(F)F
 HSPLandroid/hardware/display/BrightnessCorrection;->apply(F)F
@@ -6950,7 +7240,7 @@
 HSPLandroid/hardware/display/IDisplayManager$Stub$Proxy;->getWifiDisplayStatus()Landroid/hardware/display/WifiDisplayStatus;
 HSPLandroid/hardware/display/IDisplayManager$Stub$Proxy;->registerCallback(Landroid/hardware/display/IDisplayManagerCallback;)V
 HSPLandroid/hardware/display/IDisplayManager$Stub;-><init>()V
-PLandroid/hardware/display/IDisplayManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/hardware/display/IDisplayManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/hardware/display/IDisplayManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/hardware/display/IDisplayManagerCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/hardware/display/IDisplayManagerCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
@@ -6978,8 +7268,10 @@
 HSPLandroid/hardware/fingerprint/Fingerprint$1;-><init>()V
 HSPLandroid/hardware/fingerprint/Fingerprint;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/fingerprint/FingerprintManager;-><init>(Landroid/content/Context;Landroid/hardware/fingerprint/IFingerprintService;)V
+HSPLandroid/hardware/fingerprint/FingerprintManager;->getAcquiredString(Landroid/content/Context;II)Ljava/lang/String;
 HSPLandroid/hardware/fingerprint/FingerprintManager;->getEnrolledFingerprints(I)Ljava/util/List;
 HSPLandroid/hardware/fingerprint/FingerprintManager;->isHardwareDetected()Z
+HSPLandroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;->getEnrolledFingerprints(ILjava/lang/String;)Ljava/util/List;
 HSPLandroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;->isHardwareDetected(JLjava/lang/String;)Z
 HSPLandroid/hardware/fingerprint/IFingerprintService$Stub;-><init>()V
 HSPLandroid/hardware/fingerprint/IFingerprintService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/fingerprint/IFingerprintService;
@@ -7002,9 +7294,11 @@
 HSPLandroid/hardware/input/InputDeviceIdentifier;-><init>(Ljava/lang/String;II)V
 HSPLandroid/hardware/input/InputManager$InputDevicesChangedListener;->onInputDevicesChanged([I)V
 HSPLandroid/hardware/input/InputManager;->getInputDevice(I)Landroid/view/InputDevice;
+HSPLandroid/hardware/input/InputManager;->getInputDeviceIds()[I
 HSPLandroid/hardware/input/InputManager;->getInstance()Landroid/hardware/input/InputManager;
 HSPLandroid/hardware/input/InputManager;->onInputDevicesChanged([I)V
 HSPLandroid/hardware/input/InputManager;->populateInputDevicesLocked()V
+HSPLandroid/hardware/input/InputManager;->registerInputDeviceListener(Landroid/hardware/input/InputManager$InputDeviceListener;Landroid/os/Handler;)V
 HSPLandroid/hardware/input/KeyboardLayout$1;-><init>()V
 HSPLandroid/hardware/input/TouchCalibration$1;-><init>()V
 HSPLandroid/hardware/input/TouchCalibration;-><init>()V
@@ -7099,7 +7393,7 @@
 HSPLandroid/hardware/location/NanoAppInstanceInfo;->getAppVersion()I
 HSPLandroid/hardware/location/NanoAppInstanceInfo;->getContexthubId()I
 HSPLandroid/hardware/location/NanoAppInstanceInfo;->getHandle()I
-PLandroid/hardware/location/NanoAppInstanceInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/hardware/location/NanoAppInstanceInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/location/NanoAppMessage$1;-><init>()V
 HSPLandroid/hardware/location/NanoAppMessage$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/location/NanoAppMessage;
 HSPLandroid/hardware/location/NanoAppMessage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -7199,8 +7493,10 @@
 HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->getSignalStrength(I)V
 HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->getVoiceRadioTechnology(I)V
 HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->getVoiceRegistrationState(I)V
+HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->iccCloseLogicalChannel(II)V
 HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->iccIOForApp(ILandroid/hardware/radio/V1_0/IccIo;)V
 HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->iccOpenLogicalChannel(ILjava/lang/String;I)V
+HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->iccTransmitApduLogicalChannel(ILandroid/hardware/radio/V1_0/SimApdu;)V
 HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->interfaceChain()Ljava/util/ArrayList;
 HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->linkToDeath(Landroid/os/IHwBinder$DeathRecipient;J)Z
 HSPLandroid/hardware/radio/V1_3/IRadio$Proxy;->reportStkServiceIsRunning(I)V
@@ -7252,39 +7548,42 @@
 HSPLandroid/hardware/soundtrigger/IRecognitionStatusCallback$Stub;->asBinder()Landroid/os/IBinder;
 PLandroid/hardware/soundtrigger/IRecognitionStatusCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/soundtrigger/IRecognitionStatusCallback;
 HSPLandroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel$1;->newArray(I)[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;
-PLandroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel$1;->newArray(I)[Ljava/lang/Object;
+HPLandroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel$1;->newArray(I)[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;
+HPLandroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
+HPLandroid/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
+HPLandroid/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent;->toString()Ljava/lang/String;
 HSPLandroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel;
-PLandroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-PLandroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel;->fromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel;
+HPLandroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel;
+HPLandroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel;->fromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel;
 HSPLandroid/hardware/soundtrigger/SoundTrigger$Keyphrase$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->equals(Ljava/lang/Object;)Z
+HPLandroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->equals(Ljava/lang/Object;)Z
 HSPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V
-PLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V
+HPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
-PLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-PLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;->newArray(I)[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
-PLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;->newArray(I)[Ljava/lang/Object;
+HPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
+HPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;->newArray(I)[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
+HPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;-><init>(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V
 HSPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;->equals(Ljava/lang/Object;)Z
+HPLandroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;->equals(Ljava/lang/Object;)Z
 HSPLandroid/hardware/soundtrigger/SoundTrigger$ModuleProperties$1;-><init>()V
 HSPLandroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;-><init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V
-PLandroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;
-PLandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-PLandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->fromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;
+HPLandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;
+HPLandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->fromParcel(Landroid/os/Parcel;)Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;
 HSPLandroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger$SoundModel;->equals(Ljava/lang/Object;)Z
+HPLandroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->toString()Ljava/lang/String;
+HPLandroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/hardware/soundtrigger/SoundTrigger$SoundModel;->equals(Ljava/lang/Object;)Z
 HSPLandroid/hardware/soundtrigger/SoundTrigger$SoundModelEvent$1;-><init>()V
-PLandroid/hardware/soundtrigger/SoundTrigger;->attachModule(ILandroid/hardware/soundtrigger/SoundTrigger$StatusListener;Landroid/os/Handler;)Landroid/hardware/soundtrigger/SoundTriggerModule;
+HPLandroid/hardware/soundtrigger/SoundTrigger;->attachModule(ILandroid/hardware/soundtrigger/SoundTrigger$StatusListener;Landroid/os/Handler;)Landroid/hardware/soundtrigger/SoundTriggerModule;
 PLandroid/hardware/soundtrigger/SoundTriggerModule$NativeEventHandlerDelegate$1;->handleMessage(Landroid/os/Message;)V
 PLandroid/hardware/soundtrigger/SoundTriggerModule$NativeEventHandlerDelegate;->handler()Landroid/os/Handler;
 HPLandroid/hardware/soundtrigger/SoundTriggerModule;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
@@ -7300,6 +7599,7 @@
 HSPLandroid/hardware/thermal/V2_0/IThermalChangedCallback$Stub;->onTransact(ILandroid/os/HwParcel;Landroid/os/HwParcel;I)V
 HSPLandroid/hardware/thermal/V2_0/Temperature;->readEmbeddedFromParcel(Landroid/os/HwParcel;Landroid/os/HwBlob;J)V
 HSPLandroid/hardware/thermal/V2_0/Temperature;->readVectorFromParcel(Landroid/os/HwParcel;)Ljava/util/ArrayList;
+HSPLandroid/hardware/usb/IUsbManager$Stub$Proxy;->getDeviceList(Landroid/os/Bundle;)V
 HSPLandroid/hardware/usb/IUsbManager$Stub;-><init>()V
 HSPLandroid/hardware/usb/IUsbManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/hardware/usb/ParcelableUsbPort$1;-><init>()V
@@ -7551,8 +7851,11 @@
 HSPLandroid/icu/impl/ICUService;->markDefault()V
 HSPLandroid/icu/impl/ICUService;->registerFactory(Landroid/icu/impl/ICUService$Factory;)Landroid/icu/impl/ICUService$Factory;
 HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertIDNToUnicode(Ljava/lang/String;I)Ljava/lang/StringBuffer;
 HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertToUnicode(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;
 HSPLandroid/icu/impl/IDNA2003;->isLDHChar(I)Z
+HSPLandroid/icu/impl/IDNA2003;->startsWithPrefix(Ljava/lang/StringBuffer;)Z
 HSPLandroid/icu/impl/JavaTimeZone;->clone()Ljava/lang/Object;
 HSPLandroid/icu/impl/JavaTimeZone;->getOffset(JZ[I)V
 HSPLandroid/icu/impl/JavaTimeZone;->hashCode()I
@@ -7578,6 +7881,7 @@
 HSPLandroid/icu/impl/Normalizer2Impl$IsAcceptable;-><init>(Landroid/icu/impl/Normalizer2Impl$1;)V
 HSPLandroid/icu/impl/Normalizer2Impl$IsAcceptable;->isDataVersionAcceptable([B)Z
 HSPLandroid/icu/impl/Normalizer2Impl;->addLcccChars(Landroid/icu/text/UnicodeSet;)V
+HSPLandroid/icu/impl/Normalizer2Impl;->composeQuickCheck(Ljava/lang/CharSequence;IIZZ)I
 HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I
 HSPLandroid/icu/impl/Normalizer2Impl;->getFCD16FromNormData(I)I
 HSPLandroid/icu/impl/Normalizer2Impl;->load(Ljava/nio/ByteBuffer;)Landroid/icu/impl/Normalizer2Impl;
@@ -7610,6 +7914,7 @@
 HSPLandroid/icu/impl/RBBIDataWrapper$IsAcceptable;->isDataVersionAcceptable([B)Z
 HSPLandroid/icu/impl/RBBIDataWrapper$RBBIStateTable;->get(Ljava/nio/ByteBuffer;I)Landroid/icu/impl/RBBIDataWrapper$RBBIStateTable;
 HSPLandroid/icu/impl/RBBIDataWrapper;->get(Ljava/nio/ByteBuffer;)Landroid/icu/impl/RBBIDataWrapper;
+HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getIndex()I
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getLength()I
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getText([CI)I
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I
@@ -7630,6 +7935,7 @@
 HSPLandroid/icu/impl/SimpleFormatterImpl;->compileToStringMinMaxArguments(Ljava/lang/CharSequence;Ljava/lang/StringBuilder;II)Ljava/lang/String;
 HSPLandroid/icu/impl/SimpleFormatterImpl;->format(Ljava/lang/String;[Ljava/lang/CharSequence;Ljava/lang/StringBuilder;Ljava/lang/String;Z[I)Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/SimpleFormatterImpl;->formatAndReplace(Ljava/lang/String;Ljava/lang/StringBuilder;[I[Ljava/lang/CharSequence;)Ljava/lang/StringBuilder;
+HSPLandroid/icu/impl/SimpleFormatterImpl;->formatCompiledPattern(Ljava/lang/String;[Ljava/lang/CharSequence;)Ljava/lang/String;
 HSPLandroid/icu/impl/SimpleFormatterImpl;->getArgumentLimit(Ljava/lang/String;)I
 HSPLandroid/icu/impl/SoftCache;->getInstance(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/icu/impl/StandardPlural;-><init>(Ljava/lang/String;ILjava/lang/String;)V
@@ -7768,6 +8074,7 @@
 HSPLandroid/icu/impl/coll/CollationFastLatin;->getOptions(Landroid/icu/impl/coll/CollationData;Landroid/icu/impl/coll/CollationSettings;[C)I
 HSPLandroid/icu/impl/coll/CollationLoader;->loadTailoring(Landroid/icu/util/ULocale;Landroid/icu/util/Output;)Landroid/icu/impl/coll/CollationTailoring;
 HSPLandroid/icu/impl/coll/CollationSettings;->clone()Landroid/icu/impl/coll/SharedObject;
+HSPLandroid/icu/impl/coll/CollationSettings;->setStrength(I)V
 HSPLandroid/icu/impl/coll/CollationTailoring;-><init>(Landroid/icu/impl/coll/SharedObject$Reference;)V
 HSPLandroid/icu/impl/coll/CollationTailoring;->ensureOwnedData()V
 HSPLandroid/icu/impl/coll/SharedObject$Reference;->clone()Landroid/icu/impl/coll/SharedObject$Reference;
@@ -7956,6 +8263,7 @@
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->negativeHasMinusSign()Z
 HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOrUnlimited(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
 HSPLandroid/icu/impl/number/RoundingUtils;->scaleFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/Scale;
+HSPLandroid/icu/lang/UCharacter;->codePointAt(Ljava/lang/CharSequence;I)I
 HSPLandroid/icu/lang/UCharacter;->getIntPropertyMaxValue(I)I
 HSPLandroid/icu/lang/UCharacter;->getPropertyEnum(Ljava/lang/CharSequence;)I
 HSPLandroid/icu/lang/UCharacter;->getPropertyValueEnum(ILjava/lang/CharSequence;)I
@@ -8022,6 +8330,7 @@
 HSPLandroid/icu/text/BreakIterator;->getBreakInstance(Landroid/icu/util/ULocale;I)Landroid/icu/text/BreakIterator;
 HSPLandroid/icu/text/BreakIterator;->getShim()Landroid/icu/text/BreakIterator$BreakIteratorServiceShim;
 HSPLandroid/icu/text/BreakIterator;->getWordInstance(Ljava/util/Locale;)Landroid/icu/text/BreakIterator;
+HSPLandroid/icu/text/BreakIterator;->setText(Ljava/lang/String;)V
 HSPLandroid/icu/text/BreakIteratorFactory$BFService;-><init>()V
 HSPLandroid/icu/text/BreakIteratorFactory;-><init>()V
 HSPLandroid/icu/text/BreakIteratorFactory;->createBreakInstance(Landroid/icu/util/ULocale;I)Landroid/icu/text/BreakIterator;
@@ -8049,6 +8358,7 @@
 HSPLandroid/icu/text/DateFormat;->get(IILandroid/icu/util/ULocale;Landroid/icu/util/Calendar;)Landroid/icu/text/DateFormat;
 HSPLandroid/icu/text/DateFormat;->getCalendar()Landroid/icu/util/Calendar;
 HSPLandroid/icu/text/DateFormat;->getContext(Landroid/icu/text/DisplayContext$Type;)Landroid/icu/text/DisplayContext;
+HSPLandroid/icu/text/DateFormat;->getInstanceForSkeleton(Ljava/lang/String;)Landroid/icu/text/DateFormat;
 HSPLandroid/icu/text/DateFormat;->setCalendar(Landroid/icu/util/Calendar;)V
 HSPLandroid/icu/text/DateFormat;->setTimeZone(Landroid/icu/util/TimeZone;)V
 HSPLandroid/icu/text/DateFormatSymbols$1;-><init>()V
@@ -8159,6 +8469,7 @@
 HSPLandroid/icu/text/DateTimePatternGenerator;->setAppendItemFormat(ILjava/lang/String;)V
 HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;I)V
 HSPLandroid/icu/text/DecimalFormat;->clone()Ljava/lang/Object;
+HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
 HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V
 HSPLandroid/icu/text/DecimalFormat;->setPropertiesFromPattern(Ljava/lang/String;I)V
 HSPLandroid/icu/text/DecimalFormatSymbols$1;-><init>()V
@@ -8285,6 +8596,7 @@
 HSPLandroid/icu/text/Edits;->addReplace(II)V
 HSPLandroid/icu/text/Edits;->addUnchanged(I)V
 HSPLandroid/icu/text/IDNA;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;
+HSPLandroid/icu/text/IDNA;->convertIDNToUnicode(Ljava/lang/String;I)Ljava/lang/StringBuffer;
 HSPLandroid/icu/text/ListFormatter$Cache;-><init>(Landroid/icu/text/ListFormatter$1;)V
 HSPLandroid/icu/text/ListFormatter$Cache;->get(Landroid/icu/util/ULocale;Ljava/lang/String;)Landroid/icu/text/ListFormatter;
 HSPLandroid/icu/text/ListFormatter$Cache;->load(Landroid/icu/util/ULocale;Ljava/lang/String;)Landroid/icu/text/ListFormatter;
@@ -8295,17 +8607,20 @@
 HSPLandroid/icu/text/Normalizer$ModeImpl;-><init>(Landroid/icu/text/Normalizer2;Landroid/icu/text/Normalizer$1;)V
 HSPLandroid/icu/text/Normalizer$NFCMode;-><init>(Landroid/icu/text/Normalizer$1;)V
 HSPLandroid/icu/text/Normalizer$NFDMode;-><init>(Landroid/icu/text/Normalizer$1;)V
+HSPLandroid/icu/text/Normalizer$NFDMode;->getNormalizer2(I)Landroid/icu/text/Normalizer2;
 HSPLandroid/icu/text/Normalizer$NFKCMode;-><init>(Landroid/icu/text/Normalizer$1;)V
 HSPLandroid/icu/text/Normalizer$NFKDMode;-><init>(Landroid/icu/text/Normalizer$1;)V
 HSPLandroid/icu/text/Normalizer$NFKDMode;->getNormalizer2(I)Landroid/icu/text/Normalizer2;
 HSPLandroid/icu/text/Normalizer$NONEMode;-><init>(Landroid/icu/text/Normalizer$1;)V
 HSPLandroid/icu/text/Normalizer$QuickCheckResult;-><init>(ILandroid/icu/text/Normalizer$1;)V
+HSPLandroid/icu/text/Normalizer2;->getNFDInstance()Landroid/icu/text/Normalizer2;
 HSPLandroid/icu/text/Normalizer2;->getNFKDInstance()Landroid/icu/text/Normalizer2;
 HSPLandroid/icu/text/Normalizer2;->normalize(Ljava/lang/CharSequence;)Ljava/lang/String;
 HSPLandroid/icu/text/Normalizer;->normalize(Ljava/lang/String;Landroid/icu/text/Normalizer$Mode;)Ljava/lang/String;
 HSPLandroid/icu/text/NumberFormat$Field;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/text/NumberFormat;-><init>()V
 HSPLandroid/icu/text/NumberFormat;->createInstance(Landroid/icu/util/ULocale;I)Landroid/icu/text/NumberFormat;
+HSPLandroid/icu/text/NumberFormat;->format(Ljava/lang/Object;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
 HSPLandroid/icu/text/NumberFormat;->getMaximumFractionDigits()I
 HSPLandroid/icu/text/NumberFormat;->getMaximumIntegerDigits()I
 HSPLandroid/icu/text/NumberFormat;->getMinimumFractionDigits()I
@@ -8377,6 +8692,19 @@
 HSPLandroid/icu/text/PluralRules;->parseRuleChain(Ljava/lang/String;)Landroid/icu/text/PluralRules$RuleList;
 HSPLandroid/icu/text/PluralRules;->select(D)Ljava/lang/String;
 HSPLandroid/icu/text/PluralRules;->select(Landroid/icu/text/PluralRules$IFixedDecimal;)Ljava/lang/String;
+HSPLandroid/icu/text/RelativeDateTimeFormatter$Cache$1;->createInstance(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/icu/text/RelativeDateTimeFormatter$Cache$1;->createInstance(Ljava/lang/String;Landroid/icu/util/ULocale;)Landroid/icu/text/RelativeDateTimeFormatter$RelativeDateTimeFormatterData;
+HSPLandroid/icu/text/RelativeDateTimeFormatter$Cache;-><init>(Landroid/icu/text/RelativeDateTimeFormatter$1;)V
+HSPLandroid/icu/text/RelativeDateTimeFormatter$Cache;->get(Landroid/icu/util/ULocale;)Landroid/icu/text/RelativeDateTimeFormatter$RelativeDateTimeFormatterData;
+HSPLandroid/icu/text/RelativeDateTimeFormatter$Loader;->getDateTimePattern(Landroid/icu/impl/ICUResourceBundle;)Ljava/lang/String;
+HSPLandroid/icu/text/RelativeDateTimeFormatter$Loader;->load()Landroid/icu/text/RelativeDateTimeFormatter$RelativeDateTimeFormatterData;
+HSPLandroid/icu/text/RelativeDateTimeFormatter$RelDateTimeDataSink;->consumeTableRelative(Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)V
+HSPLandroid/icu/text/RelativeDateTimeFormatter$RelDateTimeDataSink;->consumeTableRelativeTime(Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)V
+HSPLandroid/icu/text/RelativeDateTimeFormatter$RelDateTimeDataSink;->consumeTimeDetail(Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)V
+HSPLandroid/icu/text/RelativeDateTimeFormatter$RelDateTimeDataSink;->consumeTimeUnit(Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)V
+HSPLandroid/icu/text/RelativeDateTimeFormatter$RelDateTimeDataSink;->handleAlias(Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;Z)V
+HSPLandroid/icu/text/RelativeDateTimeFormatter$RelDateTimeDataSink;->handlePlainDirection(Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)V
+HSPLandroid/icu/text/RelativeDateTimeFormatter$RelDateTimeDataSink;->put(Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;Z)V
 HSPLandroid/icu/text/ReplaceableString;->charAt(I)C
 HSPLandroid/icu/text/ReplaceableString;->getChars(II[CI)V
 HSPLandroid/icu/text/ReplaceableString;->length()I
@@ -8400,12 +8728,14 @@
 HSPLandroid/icu/text/RuleBasedBreakIterator;->first()I
 HSPLandroid/icu/text/RuleBasedBreakIterator;->following(I)I
 HSPLandroid/icu/text/RuleBasedBreakIterator;->handleNext()I
+HSPLandroid/icu/text/RuleBasedBreakIterator;->next()I
 HSPLandroid/icu/text/RuleBasedBreakIterator;->preceding(I)I
 HSPLandroid/icu/text/RuleBasedBreakIterator;->setText(Ljava/text/CharacterIterator;)V
 HSPLandroid/icu/text/RuleBasedCollator;->clone()Ljava/lang/Object;
 HSPLandroid/icu/text/RuleBasedCollator;->cloneAsThawed()Landroid/icu/text/RuleBasedCollator;
 HSPLandroid/icu/text/RuleBasedCollator;->compare(Ljava/lang/String;Ljava/lang/String;)I
 HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
+HSPLandroid/icu/text/RuleBasedCollator;->setStrength(I)V
 HSPLandroid/icu/text/SimpleDateFormat;->fastZeroPaddingNumber(Ljava/lang/StringBuffer;III)V
 HSPLandroid/icu/text/SimpleDateFormat;->format(Landroid/icu/util/Calendar;Landroid/icu/text/DisplayContext;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;Ljava/util/List;)Ljava/lang/StringBuffer;
 HSPLandroid/icu/text/SimpleDateFormat;->format(Landroid/icu/util/Calendar;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
@@ -8420,6 +8750,7 @@
 HSPLandroid/icu/text/SimpleDateFormat;->parsePattern()V
 HSPLandroid/icu/text/SimpleDateFormat;->safeAppend([Ljava/lang/String;ILjava/lang/StringBuffer;)V
 HSPLandroid/icu/text/SimpleDateFormat;->safeAppendWithMonthPattern([Ljava/lang/String;ILjava/lang/StringBuffer;Ljava/lang/String;)V
+HSPLandroid/icu/text/SimpleDateFormat;->setContext(Landroid/icu/text/DisplayContext;)V
 HSPLandroid/icu/text/SimpleDateFormat;->subFormat(Ljava/lang/StringBuffer;CIIILandroid/icu/text/DisplayContext;Ljava/text/FieldPosition;Landroid/icu/util/Calendar;)V
 HSPLandroid/icu/text/SimpleDateFormat;->toPattern()Ljava/lang/String;
 HSPLandroid/icu/text/SimpleDateFormat;->zeroPaddingNumber(Landroid/icu/text/NumberFormat;Ljava/lang/StringBuffer;III)V
@@ -8434,6 +8765,7 @@
 HSPLandroid/icu/text/TimeZoneNames;->getInstance(Ljava/util/Locale;)Landroid/icu/text/TimeZoneNames;
 HSPLandroid/icu/text/UCharacterIterator;->getText()Ljava/lang/String;
 HSPLandroid/icu/text/UCharacterIterator;->setToStart()V
+HSPLandroid/icu/text/UFieldPosition;->setFractionDigits(IJ)V
 HSPLandroid/icu/text/UFormat;-><init>()V
 HSPLandroid/icu/text/UFormat;->setLocale(Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;)V
 HSPLandroid/icu/text/UTF16;->append(Ljava/lang/StringBuffer;I)Ljava/lang/StringBuffer;
@@ -8762,7 +9094,7 @@
 HSPLandroid/location/Address$1;->createFromParcel(Landroid/os/Parcel;)Landroid/location/Address;
 HSPLandroid/location/Address$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/location/Address;->getCountryCode()Ljava/lang/String;
-PLandroid/location/Address;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/location/Address;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/location/Country$1;-><init>()V
 HSPLandroid/location/Country$1;->createFromParcel(Landroid/os/Parcel;)Landroid/location/Country;
 HSPLandroid/location/Country$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -8773,7 +9105,7 @@
 HSPLandroid/location/CountryDetector;->detectCountry()Landroid/location/Country;
 HSPLandroid/location/Criteria$1;-><init>()V
 HPLandroid/location/Criteria$1;->createFromParcel(Landroid/os/Parcel;)Landroid/location/Criteria;
-PLandroid/location/Criteria$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/location/Criteria$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 PLandroid/location/Criteria;->getAccuracy()I
 PLandroid/location/Criteria;->getPowerRequirement()I
 PLandroid/location/Criteria;->isAltitudeRequired()Z
@@ -8785,8 +9117,8 @@
 HSPLandroid/location/Geocoder;->getFromLocation(DDI)Ljava/util/List;
 HSPLandroid/location/Geocoder;->isPresent()Z
 HSPLandroid/location/GeocoderParams$1;-><init>()V
-PLandroid/location/GeocoderParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/location/GeocoderParams;
-PLandroid/location/GeocoderParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/location/GeocoderParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/location/GeocoderParams;
+HPLandroid/location/GeocoderParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/location/GeocoderParams;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/location/GnssClock$1;-><init>()V
 PLandroid/location/GnssClock;-><init>()V
@@ -8832,7 +9164,7 @@
 PLandroid/location/IGnssMeasurementsListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 PLandroid/location/IGnssMeasurementsListener$Stub$Proxy;->onGnssMeasurementsReceived(Landroid/location/GnssMeasurementsEvent;)V
 PLandroid/location/IGnssMeasurementsListener$Stub$Proxy;->onStatusChanged(I)V
-PLandroid/location/IGnssMeasurementsListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/IGnssMeasurementsListener;
+HPLandroid/location/IGnssMeasurementsListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/IGnssMeasurementsListener;
 HSPLandroid/location/IGpsGeofenceHardware$Stub;-><init>()V
 HPLandroid/location/ILocationListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HPLandroid/location/ILocationListener$Stub$Proxy;->onLocationChanged(Landroid/location/Location;)V
@@ -8846,7 +9178,7 @@
 HSPLandroid/location/ILocationManager$Stub$Proxy;->requestLocationUpdates(Landroid/location/LocationRequest;Landroid/location/ILocationListener;Landroid/app/PendingIntent;Ljava/lang/String;)V
 HSPLandroid/location/ILocationManager$Stub;-><init>()V
 HSPLandroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
-PLandroid/location/ILocationManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/location/ILocationManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/location/ILocationManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/location/INetInitiatedListener$Stub;-><init>()V
 HSPLandroid/location/Location$1;-><init>()V
@@ -8865,11 +9197,13 @@
 HSPLandroid/location/Location;-><init>(Landroid/location/Location;)V
 HSPLandroid/location/Location;-><init>(Ljava/lang/String;)V
 HSPLandroid/location/Location;->computeDistanceAndBearing(DDDDLandroid/location/Location$BearingDistanceCache;)V
+HPLandroid/location/Location;->describeContents()I
 HSPLandroid/location/Location;->distanceTo(Landroid/location/Location;)F
 HSPLandroid/location/Location;->getAccuracy()F
 HSPLandroid/location/Location;->getAltitude()D
 HSPLandroid/location/Location;->getElapsedRealtimeNanos()J
 HPLandroid/location/Location;->getExtraLocation(Ljava/lang/String;)Landroid/location/Location;
+HSPLandroid/location/Location;->getExtras()Landroid/os/Bundle;
 HSPLandroid/location/Location;->getLatitude()D
 HSPLandroid/location/Location;->getLongitude()D
 HSPLandroid/location/Location;->getProvider()Ljava/lang/String;
@@ -8948,6 +9282,7 @@
 HSPLandroid/media/AudioAttributes;->toLegacyStreamType(Landroid/media/AudioAttributes;)I
 HSPLandroid/media/AudioAttributes;->toVolumeStreamType(ZLandroid/media/AudioAttributes;)I
 HSPLandroid/media/AudioAttributes;->usageForStreamType(I)I
+HSPLandroid/media/AudioAttributes;->usageToString(I)Ljava/lang/String;
 HSPLandroid/media/AudioAttributes;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/media/AudioDeviceCallback;-><init>()V
 HSPLandroid/media/AudioDeviceInfo;->getType()I
@@ -8958,13 +9293,14 @@
 HSPLandroid/media/AudioDevicePortConfig;-><init>(Landroid/media/AudioDevicePort;IIILandroid/media/AudioGainConfig;)V
 HSPLandroid/media/AudioFocusInfo$1;-><init>()V
 HSPLandroid/media/AudioFocusInfo;-><init>(Landroid/media/AudioAttributes;ILjava/lang/String;Ljava/lang/String;IIII)V
+HSPLandroid/media/AudioFocusRequest$Builder;->build()Landroid/media/AudioFocusRequest;
 HSPLandroid/media/AudioFormat$1;-><init>()V
 HSPLandroid/media/AudioFormat$Builder;-><init>()V
 HSPLandroid/media/AudioFormat$Builder;->build()Landroid/media/AudioFormat;
 HSPLandroid/media/AudioFormat$Builder;->setChannelMask(I)Landroid/media/AudioFormat$Builder;
 HSPLandroid/media/AudioFormat$Builder;->setEncoding(I)Landroid/media/AudioFormat$Builder;
 HSPLandroid/media/AudioFormat$Builder;->setSampleRate(I)Landroid/media/AudioFormat$Builder;
-PLandroid/media/AudioFormat;-><init>(IIII)V
+HPLandroid/media/AudioFormat;-><init>(IIII)V
 HSPLandroid/media/AudioFormat;-><init>(IIIII)V
 HSPLandroid/media/AudioFormat;->getBytesPerSample(I)I
 HSPLandroid/media/AudioHandle;-><init>(I)V
@@ -8976,19 +9312,21 @@
 HSPLandroid/media/AudioManager$OnAmPortUpdateListener;->onAudioPortListUpdate([Landroid/media/AudioPort;)V
 HSPLandroid/media/AudioManager$ServiceEventHandlerDelegate;-><init>(Landroid/media/AudioManager;Landroid/os/Handler;)V
 HSPLandroid/media/AudioManager;-><init>(Landroid/content/Context;)V
-PLandroid/media/AudioManager;->abandonAudioFocusForCall()V
+HPLandroid/media/AudioManager;->abandonAudioFocusForCall()V
 HSPLandroid/media/AudioManager;->broadcastDeviceListChange_sync(Landroid/os/Handler;)V
 HSPLandroid/media/AudioManager;->calcListDeltas(Ljava/util/ArrayList;Ljava/util/ArrayList;I)[Landroid/media/AudioDeviceInfo;
 HSPLandroid/media/AudioManager;->getDevices(I)[Landroid/media/AudioDeviceInfo;
 HSPLandroid/media/AudioManager;->getDevicesForStream(I)I
 HSPLandroid/media/AudioManager;->getFocusRampTimeMs(ILandroid/media/AudioAttributes;)I
 HSPLandroid/media/AudioManager;->getIdForAudioFocusListener(Landroid/media/AudioManager$OnAudioFocusChangeListener;)Ljava/lang/String;
+HSPLandroid/media/AudioManager;->getRingerMode()I
 HSPLandroid/media/AudioManager;->getRingerModeInternal()I
 HSPLandroid/media/AudioManager;->getRingtonePlayer()Landroid/media/IRingtonePlayer;
 HSPLandroid/media/AudioManager;->getStreamMaxVolume(I)I
 HSPLandroid/media/AudioManager;->getStreamVolume(I)I
 HSPLandroid/media/AudioManager;->infoListFromPortList(Ljava/util/ArrayList;I)[Landroid/media/AudioDeviceInfo;
 HSPLandroid/media/AudioManager;->isAudioFocusExclusive()Z
+HSPLandroid/media/AudioManager;->isBluetoothA2dpOn()Z
 HSPLandroid/media/AudioManager;->isBluetoothScoOn()Z
 HSPLandroid/media/AudioManager;->isMicrophoneMute()Z
 HSPLandroid/media/AudioManager;->isStreamMute(I)Z
@@ -8997,7 +9335,12 @@
 HSPLandroid/media/AudioManager;->playSoundEffect(I)V
 HSPLandroid/media/AudioManager;->preDispatchKeyEvent(Landroid/view/KeyEvent;I)V
 HSPLandroid/media/AudioManager;->registerAudioDeviceCallback(Landroid/media/AudioDeviceCallback;Landroid/os/Handler;)V
+HSPLandroid/media/AudioManager;->registerAudioFocusRequest(Landroid/media/AudioFocusRequest;)V
 HSPLandroid/media/AudioManager;->registerAudioPortUpdateListener(Landroid/media/AudioManager$OnAudioPortUpdateListener;)V
+HSPLandroid/media/AudioManager;->requestAudioFocus(Landroid/media/AudioFocusRequest;Landroid/media/audiopolicy/AudioPolicy;)I
+HSPLandroid/media/AudioManager;->requestAudioFocus(Landroid/media/AudioManager$OnAudioFocusChangeListener;Landroid/media/AudioAttributes;II)I
+HSPLandroid/media/AudioManager;->requestAudioFocus(Landroid/media/AudioManager$OnAudioFocusChangeListener;Landroid/media/AudioAttributes;IILandroid/media/audiopolicy/AudioPolicy;)I
+HPLandroid/media/AudioManager;->requestAudioFocusForCall(II)V
 HSPLandroid/media/AudioManager;->resetAudioPortGeneration()I
 HSPLandroid/media/AudioManager;->setMode(I)V
 HSPLandroid/media/AudioManager;->setParameter(Ljava/lang/String;Ljava/lang/String;)V
@@ -9017,7 +9360,7 @@
 HSPLandroid/media/AudioPlaybackConfiguration$IPlayerShell;->monitorDeath()V
 HSPLandroid/media/AudioPlaybackConfiguration$IPlayerShell;->release()V
 HSPLandroid/media/AudioPlaybackConfiguration;-><init>(Landroid/media/PlayerBase$PlayerIdCard;III)V
-PLandroid/media/AudioPlaybackConfiguration;->anonymizedCopy(Landroid/media/AudioPlaybackConfiguration;)Landroid/media/AudioPlaybackConfiguration;
+HPLandroid/media/AudioPlaybackConfiguration;->anonymizedCopy(Landroid/media/AudioPlaybackConfiguration;)Landroid/media/AudioPlaybackConfiguration;
 HSPLandroid/media/AudioPlaybackConfiguration;->handleAudioAttributesEvent(Landroid/media/AudioAttributes;)Z
 HSPLandroid/media/AudioPlaybackConfiguration;->handleStateEvent(I)Z
 HSPLandroid/media/AudioPlaybackConfiguration;->init()V
@@ -9038,6 +9381,14 @@
 HSPLandroid/media/AudioPortEventHandler;->init()V
 HSPLandroid/media/AudioPortEventHandler;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
 HSPLandroid/media/AudioPortEventHandler;->registerListener(Landroid/media/AudioManager$OnAudioPortUpdateListener;)V
+HSPLandroid/media/AudioRecord;-><init>(Landroid/media/AudioAttributes;Landroid/media/AudioFormat;II)V
+HSPLandroid/media/AudioRecord;->audioBuffSizeCheck(I)V
+HSPLandroid/media/AudioRecord;->audioParamCheck(III)V
+HSPLandroid/media/AudioRecord;->getChannelMaskFromLegacyConfig(IZ)I
+HSPLandroid/media/AudioRecord;->handleFullVolumeRec(Z)V
+HSPLandroid/media/AudioRecord;->release()V
+HSPLandroid/media/AudioRecord;->startRecording()V
+HSPLandroid/media/AudioRecord;->stop()V
 PLandroid/media/AudioRecordingConfiguration$1;-><init>()V
 PLandroid/media/AudioRecordingConfiguration;-><init>(IIILandroid/media/AudioFormat;Landroid/media/AudioFormat;ILjava/lang/String;IZI[Landroid/media/audiofx/AudioEffect$Descriptor;[Landroid/media/audiofx/AudioEffect$Descriptor;)V
 HSPLandroid/media/AudioRoutesInfo$1;-><init>()V
@@ -9050,10 +9401,11 @@
 HSPLandroid/media/AudioSystem;->getOutputDeviceName(I)Ljava/lang/String;
 HSPLandroid/media/AudioSystem;->getPlatformType(Landroid/content/Context;)I
 HSPLandroid/media/AudioSystem;->isSingleVolume(Landroid/content/Context;)Z
-PLandroid/media/AudioSystem;->recordingCallbackFromNative(IIIIIZ[I[Landroid/media/audiofx/AudioEffect$Descriptor;[Landroid/media/audiofx/AudioEffect$Descriptor;I)V
+HPLandroid/media/AudioSystem;->recordingCallbackFromNative(IIIIIZ[I[Landroid/media/audiofx/AudioEffect$Descriptor;[Landroid/media/audiofx/AudioEffect$Descriptor;I)V
 HSPLandroid/media/AudioSystem;->setErrorCallback(Landroid/media/AudioSystem$ErrorCallback;)V
 HSPLandroid/media/AudioSystem;->setRecordingCallback(Landroid/media/AudioSystem$AudioRecordingCallback;)V
 HSPLandroid/media/AudioSystem;->setStreamVolumeIndexAS(III)I
+HSPLandroid/media/AudioTrack;->getNativeOutputSampleRate(I)I
 HSPLandroid/media/ExifInterface$ByteOrderedDataInputStream;-><init>(Ljava/io/InputStream;)V
 HSPLandroid/media/ExifInterface$ByteOrderedDataInputStream;->read()I
 HSPLandroid/media/ExifInterface$ByteOrderedDataInputStream;->readByte()B
@@ -9091,28 +9443,33 @@
 HSPLandroid/media/IAudioRoutesObserver$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/media/IAudioRoutesObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioRoutesObserver;
 PLandroid/media/IAudioServerStateDispatcher$Stub$Proxy;->asBinder()Landroid/os/IBinder;
-PLandroid/media/IAudioServerStateDispatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioServerStateDispatcher;
+HPLandroid/media/IAudioServerStateDispatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioServerStateDispatcher;
+HSPLandroid/media/IAudioService$Stub$Proxy;->getRingerModeExternal()I
 HSPLandroid/media/IAudioService$Stub$Proxy;->getRingerModeInternal()I
 HSPLandroid/media/IAudioService$Stub$Proxy;->getStreamMaxVolume(I)I
 HSPLandroid/media/IAudioService$Stub$Proxy;->getStreamVolume(I)I
 HSPLandroid/media/IAudioService$Stub$Proxy;->isBluetoothScoOn()Z
+HSPLandroid/media/IAudioService$Stub$Proxy;->isCameraSoundForced()Z
 HSPLandroid/media/IAudioService$Stub$Proxy;->isStreamMute(I)Z
 HSPLandroid/media/IAudioService$Stub$Proxy;->playSoundEffect(I)V
+HSPLandroid/media/IAudioService$Stub$Proxy;->playerAttributes(ILandroid/media/AudioAttributes;)V
 HSPLandroid/media/IAudioService$Stub$Proxy;->playerEvent(II)V
 HSPLandroid/media/IAudioService$Stub$Proxy;->playerHasOpPlayAudio(IZ)V
 HSPLandroid/media/IAudioService$Stub$Proxy;->releasePlayer(I)V
+HSPLandroid/media/IAudioService$Stub$Proxy;->requestAudioFocus(Landroid/media/AudioAttributes;ILandroid/os/IBinder;Landroid/media/IAudioFocusDispatcher;Ljava/lang/String;Ljava/lang/String;ILandroid/media/audiopolicy/IAudioPolicyCallback;I)I
 HSPLandroid/media/IAudioService$Stub$Proxy;->startWatchingRoutes(Landroid/media/IAudioRoutesObserver;)Landroid/media/AudioRoutesInfo;
 HSPLandroid/media/IAudioService$Stub$Proxy;->trackPlayer(Landroid/media/PlayerBase$PlayerIdCard;)I
 HSPLandroid/media/IAudioService$Stub;-><init>()V
 HSPLandroid/media/IAudioService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioService;
-PLandroid/media/IAudioService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/media/IAudioService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/media/IAudioService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/media/IMediaResourceMonitor$Stub;-><init>()V
 HPLandroid/media/IMediaResourceMonitor$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/media/IMediaRouterClient$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HPLandroid/media/IMediaRouterClient$Stub$Proxy;->onRestoreRoute()V
-PLandroid/media/IMediaRouterClient$Stub$Proxy;->onStateChanged()V
+HPLandroid/media/IMediaRouterClient$Stub$Proxy;->onStateChanged()V
 HSPLandroid/media/IMediaRouterClient$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/IMediaRouterClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/media/IMediaRouterService$Stub$Proxy;->getState(Landroid/media/IMediaRouterClient;)Landroid/media/MediaRouterClientState;
 HSPLandroid/media/IMediaRouterService$Stub$Proxy;->isPlaybackActive(Landroid/media/IMediaRouterClient;)Z
 HSPLandroid/media/IMediaRouterService$Stub$Proxy;->registerClientAsUser(Landroid/media/IMediaRouterClient;Ljava/lang/String;I)V
@@ -9127,10 +9484,12 @@
 HSPLandroid/media/IPlaybackConfigDispatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IPlaybackConfigDispatcher;
 HSPLandroid/media/IPlayer$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/media/IPlayer$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/IRecordingConfigDispatcher$Stub;-><init>()V
 HSPLandroid/media/IRemoteVolumeController$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/media/IRemoteVolumeController$Stub$Proxy;->updateRemoteController(Landroid/media/session/MediaSession$Token;)V
 HSPLandroid/media/IRemoteVolumeController$Stub;-><init>()V
 HSPLandroid/media/IRingtonePlayer$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/IRingtonePlayer$Stub$Proxy;->playAsync(Landroid/net/Uri;Landroid/os/UserHandle;ZLandroid/media/AudioAttributes;)V
 HSPLandroid/media/IRingtonePlayer$Stub$Proxy;->stopAsync()V
 HSPLandroid/media/IRingtonePlayer$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IRingtonePlayer;
 HSPLandroid/media/IVolumeController$Stub$Proxy;->asBinder()Landroid/os/IBinder;
@@ -9138,6 +9497,25 @@
 HSPLandroid/media/IVolumeController$Stub$Proxy;->volumeChanged(II)V
 HSPLandroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IVolumeController;
 HSPLandroid/media/MediaCodec$BufferInfo;-><init>()V
+HSPLandroid/media/MediaCodec$BufferInfo;->set(IIJI)V
+HSPLandroid/media/MediaCodec$BufferMap;->clear()V
+HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V
+HSPLandroid/media/MediaCodec$CryptoInfo;-><init>()V
+HSPLandroid/media/MediaCodec;-><init>(Ljava/lang/String;ZZ)V
+HSPLandroid/media/MediaCodec;->cacheBuffers(Z)V
+HSPLandroid/media/MediaCodec;->configure(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V
+HSPLandroid/media/MediaCodec;->configure(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;Landroid/os/IHwBinder;I)V
+HSPLandroid/media/MediaCodec;->dequeueInputBuffer(J)I
+HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I
+HSPLandroid/media/MediaCodec;->finalize()V
+HSPLandroid/media/MediaCodec;->freeAllTrackedBuffers()V
+HSPLandroid/media/MediaCodec;->lockAndGetContext()J
+HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V
+HSPLandroid/media/MediaCodec;->release()V
+HSPLandroid/media/MediaCodec;->releaseOutputBuffer(IZ)V
+HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V
+HSPLandroid/media/MediaCodec;->start()V
+HSPLandroid/media/MediaCodec;->stop()V
 HSPLandroid/media/MediaCodecInfo$AudioCapabilities;->applyLevelLimits()V
 HSPLandroid/media/MediaCodecInfo$AudioCapabilities;->applyLimits(ILandroid/util/Range;)V
 HSPLandroid/media/MediaCodecInfo$AudioCapabilities;->createDiscreteSampleRates()V
@@ -9186,6 +9564,9 @@
 HSPLandroid/media/MediaDescription;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/media/MediaDescription;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/media/MediaDrm;->getMaxSecurityLevel()I
+HSPLandroid/media/MediaFormat;->getInteger(Ljava/lang/String;)I
+HSPLandroid/media/MediaFormat;->getString(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/media/MediaFormat;->setInteger(Ljava/lang/String;I)V
 HSPLandroid/media/MediaMetadata$1;-><init>()V
 HSPLandroid/media/MediaMetadata$1;->createFromParcel(Landroid/os/Parcel;)Landroid/media/MediaMetadata;
 HSPLandroid/media/MediaMetadata$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -9193,6 +9574,13 @@
 HSPLandroid/media/MediaMetadata$Builder;->build()Landroid/media/MediaMetadata;
 HPLandroid/media/MediaMetadata;->size()I
 HSPLandroid/media/MediaMetadata;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/media/MediaParceledListSlice$2;-><init>()V
+HSPLandroid/media/MediaParceledListSlice$2;->createFromParcel(Landroid/os/Parcel;)Landroid/media/MediaParceledListSlice;
+HSPLandroid/media/MediaParceledListSlice$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/media/MediaParceledListSlice;-><init>(Landroid/os/Parcel;)V
+HPLandroid/media/MediaParceledListSlice;-><init>(Ljava/util/List;)V
+HSPLandroid/media/MediaParceledListSlice;->getList()Ljava/util/List;
+HSPLandroid/media/MediaParceledListSlice;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/media/MediaPlayer$2$1;->getSubtitleLooper()Landroid/os/Looper;
 HSPLandroid/media/MediaPlayer$2$1;->setSubtitleWidget(Landroid/media/SubtitleTrack$RenderingWidget;)V
 HSPLandroid/media/MediaPlayer$2;->run()V
@@ -9244,7 +9632,7 @@
 HSPLandroid/media/MediaPlayer;->setVolume(FF)V
 HSPLandroid/media/MediaPlayer;->start()V
 HSPLandroid/media/MediaPlayer;->stayAwake(Z)V
-PLandroid/media/MediaRecorder;->isSystemOnlyAudioSource(I)Z
+HPLandroid/media/MediaRecorder;->isSystemOnlyAudioSource(I)Z
 HSPLandroid/media/MediaRouter$Callback;-><init>()V
 HSPLandroid/media/MediaRouter$CallbackInfo;->filterRouteEvent(I)Z
 HSPLandroid/media/MediaRouter$CallbackInfo;->filterRouteEvent(Landroid/media/MediaRouter$RouteInfo;)Z
@@ -9256,10 +9644,21 @@
 HSPLandroid/media/MediaRouter$RouteInfo;->choosePresentationDisplay()Landroid/view/Display;
 HSPLandroid/media/MediaRouter$RouteInfo;->getCategory()Landroid/media/MediaRouter$RouteCategory;
 HSPLandroid/media/MediaRouter$RouteInfo;->getDescription()Ljava/lang/CharSequence;
+HSPLandroid/media/MediaRouter$RouteInfo;->getDeviceType()I
 HSPLandroid/media/MediaRouter$RouteInfo;->getName()Ljava/lang/CharSequence;
+HSPLandroid/media/MediaRouter$RouteInfo;->getName(Landroid/content/Context;)Ljava/lang/CharSequence;
 HSPLandroid/media/MediaRouter$RouteInfo;->getName(Landroid/content/res/Resources;)Ljava/lang/CharSequence;
+HSPLandroid/media/MediaRouter$RouteInfo;->getPlaybackStream()I
+HSPLandroid/media/MediaRouter$RouteInfo;->getPlaybackType()I
+HSPLandroid/media/MediaRouter$RouteInfo;->getPresentationDisplay()Landroid/view/Display;
 HSPLandroid/media/MediaRouter$RouteInfo;->getStatus()Ljava/lang/CharSequence;
 HSPLandroid/media/MediaRouter$RouteInfo;->getSupportedTypes()I
+HSPLandroid/media/MediaRouter$RouteInfo;->getTag()Ljava/lang/Object;
+HSPLandroid/media/MediaRouter$RouteInfo;->getVolume()I
+HSPLandroid/media/MediaRouter$RouteInfo;->getVolumeHandling()I
+HSPLandroid/media/MediaRouter$RouteInfo;->getVolumeMax()I
+HSPLandroid/media/MediaRouter$RouteInfo;->isConnecting()Z
+HSPLandroid/media/MediaRouter$RouteInfo;->isEnabled()Z
 HSPLandroid/media/MediaRouter$RouteInfo;->isSelected()Z
 HSPLandroid/media/MediaRouter$RouteInfo;->matchesTypes(I)Z
 HSPLandroid/media/MediaRouter$RouteInfo;->resolveStatusCode()Z
@@ -9290,14 +9689,21 @@
 HSPLandroid/media/MediaRouter;-><init>(Landroid/content/Context;)V
 HSPLandroid/media/MediaRouter;->addCallback(ILandroid/media/MediaRouter$Callback;I)V
 HSPLandroid/media/MediaRouter;->addRouteStatic(Landroid/media/MediaRouter$RouteInfo;)V
+HSPLandroid/media/MediaRouter;->createRouteCategory(Ljava/lang/CharSequence;Z)Landroid/media/MediaRouter$RouteCategory;
 HSPLandroid/media/MediaRouter;->dispatchRouteAdded(Landroid/media/MediaRouter$RouteInfo;)V
+HSPLandroid/media/MediaRouter;->dispatchRouteChanged(Landroid/media/MediaRouter$RouteInfo;I)V
 HSPLandroid/media/MediaRouter;->dispatchRouteRemoved(Landroid/media/MediaRouter$RouteInfo;)V
 HSPLandroid/media/MediaRouter;->dispatchRouteSelected(ILandroid/media/MediaRouter$RouteInfo;)V
 HSPLandroid/media/MediaRouter;->dispatchRouteUnselected(ILandroid/media/MediaRouter$RouteInfo;)V
 HSPLandroid/media/MediaRouter;->dispatchRouteVolumeChanged(Landroid/media/MediaRouter$RouteInfo;)V
+HSPLandroid/media/MediaRouter;->getDefaultRoute()Landroid/media/MediaRouter$RouteInfo;
+HSPLandroid/media/MediaRouter;->getRouteAt(I)Landroid/media/MediaRouter$RouteInfo;
+HSPLandroid/media/MediaRouter;->getRouteCount()I
+HSPLandroid/media/MediaRouter;->getSelectedRoute(I)Landroid/media/MediaRouter$RouteInfo;
 HSPLandroid/media/MediaRouter;->removeCallback(Landroid/media/MediaRouter$Callback;)V
 HSPLandroid/media/MediaRouter;->removeRouteStatic(Landroid/media/MediaRouter$RouteInfo;)V
 HSPLandroid/media/MediaRouter;->selectDefaultRouteStatic()V
+HSPLandroid/media/MediaRouter;->selectRoute(ILandroid/media/MediaRouter$RouteInfo;)V
 HSPLandroid/media/MediaRouter;->selectRouteStatic(ILandroid/media/MediaRouter$RouteInfo;Z)V
 HSPLandroid/media/MediaRouter;->systemVolumeChanged(I)V
 HSPLandroid/media/MediaRouter;->typesToString(I)Ljava/lang/String;
@@ -9330,6 +9736,9 @@
 HSPLandroid/media/PlayerBase;->updateAppOpsPlayAudio_sync(Z)V
 HSPLandroid/media/PlayerBase;->updatePlayerVolume()V
 HSPLandroid/media/PlayerBase;->updateState(I)V
+HSPLandroid/media/Rating$1;-><init>()V
+HSPLandroid/media/Rating$1;->createFromParcel(Landroid/os/Parcel;)Landroid/media/Rating;
+HSPLandroid/media/Rating$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/media/Ringtone;-><init>(Landroid/content/Context;Z)V
 HSPLandroid/media/Ringtone;->applyPlaybackProperties_sync()V
 HSPLandroid/media/Ringtone;->destroyLocalPlayer()V
@@ -9342,11 +9751,13 @@
 HSPLandroid/media/RingtoneManager;->getDefaultUri(I)Landroid/net/Uri;
 HSPLandroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;)Landroid/media/Ringtone;
 HSPLandroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;ILandroid/media/VolumeShaper$Configuration;)Landroid/media/Ringtone;
+HPLandroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;Landroid/media/VolumeShaper$Configuration;)Landroid/media/Ringtone;
 HSPLandroid/media/SoundPool$Builder;->build()Landroid/media/SoundPool;
 HSPLandroid/media/SoundPool$Builder;->setAudioAttributes(Landroid/media/AudioAttributes;)Landroid/media/SoundPool$Builder;
 HSPLandroid/media/SoundPool$EventHandler;->handleMessage(Landroid/os/Message;)V
 HSPLandroid/media/SoundPool;-><init>(ILandroid/media/AudioAttributes;)V
 HSPLandroid/media/SoundPool;->load(Ljava/lang/String;I)I
+HSPLandroid/media/SoundPool;->play(IFFIIF)I
 HSPLandroid/media/SoundPool;->playerSetAuxEffectSendLevel(ZF)I
 HSPLandroid/media/SoundPool;->playerSetVolume(ZFF)V
 HSPLandroid/media/SoundPool;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
@@ -9364,7 +9775,7 @@
 HSPLandroid/media/SubtitleController;->setAnchor(Landroid/media/SubtitleController$Anchor;)V
 HSPLandroid/media/ToneGenerator;-><init>(II)V
 HSPLandroid/media/ToneGenerator;->finalize()V
-PLandroid/media/ToneGenerator;->startTone(I)Z
+HPLandroid/media/ToneGenerator;->startTone(I)Z
 HSPLandroid/media/Utils$1;->compare(Landroid/util/Range;Landroid/util/Range;)I
 HSPLandroid/media/Utils$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/media/Utils$2;->compare(Landroid/util/Range;Landroid/util/Range;)I
@@ -9429,17 +9840,18 @@
 PLandroid/media/session/ICallback$Stub$Proxy;->onAddressedPlayerChangedToMediaSession(Landroid/media/session/MediaSession$Token;)V
 HSPLandroid/media/session/ICallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/session/ICallback;
 HSPLandroid/media/session/ISession$Stub;-><init>()V
-PLandroid/media/session/ISession$Stub;->asBinder()Landroid/os/IBinder;
+HPLandroid/media/session/ISession$Stub;->asBinder()Landroid/os/IBinder;
 HPLandroid/media/session/ISession$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/media/session/ISessionCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/media/session/ISessionCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/session/ISessionController$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/media/session/ISessionController$Stub;-><init>()V
 HPLandroid/media/session/ISessionController$Stub;->asBinder()Landroid/os/IBinder;
 HPLandroid/media/session/ISessionController$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLandroid/media/session/ISessionControllerCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HPLandroid/media/session/ISessionControllerCallback$Stub$Proxy;->onMetadataChanged(Landroid/media/MediaMetadata;)V
 HPLandroid/media/session/ISessionControllerCallback$Stub$Proxy;->onPlaybackStateChanged(Landroid/media/session/PlaybackState;)V
-HPLandroid/media/session/ISessionControllerCallback$Stub$Proxy;->onQueueChanged(Landroid/media/ParceledListSlice;)V
+HPLandroid/media/session/ISessionControllerCallback$Stub$Proxy;->onQueueChanged(Landroid/media/MediaParceledListSlice;)V
 HPLandroid/media/session/ISessionControllerCallback$Stub$Proxy;->onSessionDestroyed()V
 HSPLandroid/media/session/ISessionManager$Stub$Proxy;->getSessions(Landroid/content/ComponentName;I)Ljava/util/List;
 HSPLandroid/media/session/ISessionManager$Stub;-><init>()V
@@ -9553,12 +9965,12 @@
 HSPLandroid/net/ConnectivityManager;->requestNetwork(Landroid/net/NetworkRequest;Landroid/net/ConnectivityManager$NetworkCallback;IILandroid/os/Handler;)V
 HSPLandroid/net/ConnectivityManager;->requestNetwork(Landroid/net/NetworkRequest;Landroid/net/ConnectivityManager$NetworkCallback;Landroid/os/Handler;)V
 HSPLandroid/net/ConnectivityManager;->requestNetwork(Landroid/net/NetworkRequest;Landroid/net/ConnectivityManager$NetworkCallback;Landroid/os/Handler;I)V
-PLandroid/net/ConnectivityManager;->requestRouteToHostAddress(ILjava/net/InetAddress;)Z
+HPLandroid/net/ConnectivityManager;->requestRouteToHostAddress(ILjava/net/InetAddress;)Z
 HSPLandroid/net/ConnectivityManager;->sendRequestForNetwork(Landroid/net/NetworkCapabilities;Landroid/net/ConnectivityManager$NetworkCallback;IIILandroid/net/ConnectivityManager$CallbackHandler;)Landroid/net/NetworkRequest;
 HSPLandroid/net/ConnectivityManager;->setProcessDefaultNetwork(Landroid/net/Network;)Z
 HSPLandroid/net/ConnectivityManager;->setProvisioningNotificationVisible(ZILjava/lang/String;)V
 HSPLandroid/net/ConnectivityManager;->unregisterNetworkCallback(Landroid/net/ConnectivityManager$NetworkCallback;)V
-PLandroid/net/ConnectivityManager;->unsupportedStartingFrom(I)V
+HPLandroid/net/ConnectivityManager;->unsupportedStartingFrom(I)V
 HSPLandroid/net/ConnectivityMetricsEvent$1;-><init>()V
 HSPLandroid/net/ConnectivityMetricsEvent$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/ConnectivityMetricsEvent;
 HSPLandroid/net/ConnectivityMetricsEvent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -9572,10 +9984,10 @@
 HSPLandroid/net/DhcpInfo$1;-><init>()V
 HPLandroid/net/DhcpInfo;->writeToParcel(Landroid/os/Parcel;I)V
 PLandroid/net/DhcpResults$1;-><init>()V
-PLandroid/net/DhcpResults;-><init>(Landroid/net/DhcpResults;)V
+HPLandroid/net/DhcpResults;-><init>(Landroid/net/DhcpResults;)V
 HPLandroid/net/DhcpResults;-><init>(Landroid/net/StaticIpConfiguration;)V
-PLandroid/net/DhcpResults;->clear()V
-PLandroid/net/DhcpResults;->hasMeteredHint()Z
+HPLandroid/net/DhcpResults;->clear()V
+HPLandroid/net/DhcpResults;->hasMeteredHint()Z
 HPLandroid/net/DhcpResults;->toStaticIpConfiguration()Landroid/net/StaticIpConfiguration;
 HPLandroid/net/DhcpResults;->toString()Ljava/lang/String;
 HSPLandroid/net/EventLogTags;->writeNtpSuccess(Ljava/lang/String;JJ)V
@@ -9598,7 +10010,7 @@
 HSPLandroid/net/IConnectivityManager$Stub$Proxy;->setProvisioningNotificationVisible(ZILjava/lang/String;)V
 HSPLandroid/net/IConnectivityManager$Stub;-><init>()V
 HSPLandroid/net/IConnectivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/IConnectivityManager;
-PLandroid/net/IConnectivityManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/net/IConnectivityManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/net/IConnectivityManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/net/IEthernetManager$Stub;-><init>()V
 HSPLandroid/net/IIpConnectivityMetrics$Stub;-><init>()V
@@ -9633,7 +10045,7 @@
 HSPLandroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
 HSPLandroid/net/INetworkStatsService$Stub;-><init>()V
 HSPLandroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
-PLandroid/net/INetworkStatsService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/net/INetworkStatsService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/net/INetworkStatsService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLandroid/net/INetworkStatsSession$Stub;-><init>()V
 HPLandroid/net/INetworkStatsSession$Stub;->asBinder()Landroid/os/IBinder;
@@ -9642,7 +10054,7 @@
 HSPLandroid/net/InetAddresses;->parseNumericAddress(Ljava/lang/String;)Ljava/net/InetAddress;
 HSPLandroid/net/InterfaceConfiguration$1;-><init>()V
 HSPLandroid/net/InterfaceConfiguration;-><init>()V
-PLandroid/net/InterfaceConfiguration;->getLinkAddress()Landroid/net/LinkAddress;
+HPLandroid/net/InterfaceConfiguration;->getLinkAddress()Landroid/net/LinkAddress;
 HSPLandroid/net/InterfaceConfiguration;->hasFlag(Ljava/lang/String;)Z
 HSPLandroid/net/InterfaceConfiguration;->isUp()Z
 HSPLandroid/net/InterfaceConfiguration;->setFlag(Ljava/lang/String;)V
@@ -9698,6 +10110,7 @@
 HSPLandroid/net/LinkProperties;->addLinkAddress(Landroid/net/LinkAddress;)Z
 HSPLandroid/net/LinkProperties;->addPcscfServer(Ljava/net/InetAddress;)Z
 HSPLandroid/net/LinkProperties;->addRoute(Landroid/net/RouteInfo;)Z
+HSPLandroid/net/LinkProperties;->addStackedLink(Landroid/net/LinkProperties;)Z
 HSPLandroid/net/LinkProperties;->addValidatedPrivateDnsServer(Ljava/net/InetAddress;)Z
 HSPLandroid/net/LinkProperties;->clear()V
 HSPLandroid/net/LinkProperties;->describeContents()I
@@ -9712,6 +10125,7 @@
 HSPLandroid/net/LinkProperties;->getInterfaceName()Ljava/lang/String;
 HSPLandroid/net/LinkProperties;->getLinkAddresses()Ljava/util/List;
 HSPLandroid/net/LinkProperties;->getMtu()I
+HSPLandroid/net/LinkProperties;->getPrivateDnsServerName()Ljava/lang/String;
 HSPLandroid/net/LinkProperties;->getRoutes()Ljava/util/List;
 HSPLandroid/net/LinkProperties;->getStackedLinks()Ljava/util/List;
 HSPLandroid/net/LinkProperties;->hasGlobalIPv6Address()Z
@@ -9726,6 +10140,7 @@
 HSPLandroid/net/LinkProperties;->hasIpv6DefaultRoute()Z
 HSPLandroid/net/LinkProperties;->isIdenticalAddresses(Landroid/net/LinkProperties;)Z
 HSPLandroid/net/LinkProperties;->isIdenticalDnses(Landroid/net/LinkProperties;)Z
+HSPLandroid/net/LinkProperties;->isIdenticalInterfaceName(Landroid/net/LinkProperties;)Z
 HSPLandroid/net/LinkProperties;->isIdenticalRoutes(Landroid/net/LinkProperties;)Z
 HSPLandroid/net/LinkProperties;->isIdenticalStackedLinks(Landroid/net/LinkProperties;)Z
 HSPLandroid/net/LinkProperties;->isPrivateDnsActive()Z
@@ -9803,14 +10218,18 @@
 HSPLandroid/net/Network$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/net/Network$1;->newArray(I)[Landroid/net/Network;
 HSPLandroid/net/Network$1;->newArray(I)[Ljava/lang/Object;
+HSPLandroid/net/Network$NetworkBoundSocketFactory;->createSocket()Ljava/net/Socket;
 HSPLandroid/net/Network;-><init>(I)V
 HSPLandroid/net/Network;->bindSocket(Ljava/io/FileDescriptor;)V
 HSPLandroid/net/Network;->bindSocket(Ljava/net/DatagramSocket;)V
+HSPLandroid/net/Network;->bindSocket(Ljava/net/Socket;)V
 HSPLandroid/net/Network;->equals(Ljava/lang/Object;)Z
+HSPLandroid/net/Network;->getAllByName(Ljava/lang/String;)[Ljava/net/InetAddress;
 HSPLandroid/net/Network;->getByName(Ljava/lang/String;)Ljava/net/InetAddress;
 HSPLandroid/net/Network;->getNetIdForResolv()I
 HSPLandroid/net/Network;->getNetworkHandle()J
 HSPLandroid/net/Network;->getPrivateDnsBypassingCopy()Landroid/net/Network;
+HSPLandroid/net/Network;->getSocketFactory()Ljavax/net/SocketFactory;
 HSPLandroid/net/Network;->hashCode()I
 HSPLandroid/net/Network;->toString()Ljava/lang/String;
 HSPLandroid/net/Network;->writeToParcel(Landroid/os/Parcel;I)V
@@ -9947,6 +10366,7 @@
 HSPLandroid/net/NetworkPolicy;->hasCycle()Z
 HSPLandroid/net/NetworkPolicy;->isOverLimit(J)Z
 HSPLandroid/net/NetworkPolicy;->isOverWarning(J)Z
+HSPLandroid/net/NetworkPolicy;->toString()Ljava/lang/String;
 HSPLandroid/net/NetworkPolicyManager$1;->hasNext()Z
 HSPLandroid/net/NetworkPolicyManager$1;->next()Landroid/util/Pair;
 HSPLandroid/net/NetworkPolicyManager$1;->next()Ljava/lang/Object;
@@ -10063,9 +10483,12 @@
 HSPLandroid/net/NetworkTemplate;-><init>(ILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/net/NetworkTemplate;-><init>(ILjava/lang/String;[Ljava/lang/String;Ljava/lang/String;III)V
 HSPLandroid/net/NetworkTemplate;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/net/NetworkTemplate;->buildTemplateMobileAll(Ljava/lang/String;)Landroid/net/NetworkTemplate;
 HSPLandroid/net/NetworkTemplate;->buildTemplateMobileWildcard()Landroid/net/NetworkTemplate;
 HSPLandroid/net/NetworkTemplate;->buildTemplateWifiWildcard()Landroid/net/NetworkTemplate;
+HSPLandroid/net/NetworkTemplate;->equals(Ljava/lang/Object;)Z
 HSPLandroid/net/NetworkTemplate;->getMatchRule()I
+HSPLandroid/net/NetworkTemplate;->getMatchRuleName(I)Ljava/lang/String;
 HSPLandroid/net/NetworkTemplate;->getNetworkId()Ljava/lang/String;
 HSPLandroid/net/NetworkTemplate;->getSubscriberId()Ljava/lang/String;
 HSPLandroid/net/NetworkTemplate;->hashCode()I
@@ -10074,14 +10497,15 @@
 HSPLandroid/net/NetworkTemplate;->matches(Landroid/net/NetworkIdentity;)Z
 HSPLandroid/net/NetworkTemplate;->matchesMobile(Landroid/net/NetworkIdentity;)Z
 HSPLandroid/net/NetworkTemplate;->normalize(Landroid/net/NetworkTemplate;[Ljava/lang/String;)Landroid/net/NetworkTemplate;
+HSPLandroid/net/NetworkTemplate;->toString()Ljava/lang/String;
 HSPLandroid/net/NetworkTemplate;->writeToParcel(Landroid/os/Parcel;I)V
 HPLandroid/net/NetworkUtils;->inetAddressToInt(Ljava/net/Inet4Address;)I
 HSPLandroid/net/NetworkUtils;->makeStrings(Ljava/util/Collection;)[Ljava/lang/String;
 HSPLandroid/net/NetworkUtils;->maskRawAddress([BI)V
 HSPLandroid/net/NetworkUtils;->numericToInetAddress(Ljava/lang/String;)Ljava/net/InetAddress;
 HSPLandroid/net/NetworkUtils;->parseIpAndMask(Ljava/lang/String;)Landroid/util/Pair;
-PLandroid/net/NetworkWatchlistManager;-><init>(Landroid/content/Context;)V
-PLandroid/net/NetworkWatchlistManager;->reportWatchlistIfNecessary()V
+HPLandroid/net/NetworkWatchlistManager;-><init>(Landroid/content/Context;)V
+HPLandroid/net/NetworkWatchlistManager;->reportWatchlistIfNecessary()V
 HSPLandroid/net/Proxy;->setHttpProxySystemProperty(Landroid/net/ProxyInfo;)V
 HSPLandroid/net/Proxy;->setHttpProxySystemProperty(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/net/Uri;)V
 HSPLandroid/net/ProxyInfo$1;-><init>()V
@@ -10090,6 +10514,7 @@
 HSPLandroid/net/RouteInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/net/RouteInfo;-><init>(Landroid/net/IpPrefix;Ljava/net/InetAddress;Ljava/lang/String;)V
 HSPLandroid/net/RouteInfo;-><init>(Landroid/net/IpPrefix;Ljava/net/InetAddress;Ljava/lang/String;I)V
+HPLandroid/net/RouteInfo;-><init>(Landroid/net/LinkAddress;Ljava/net/InetAddress;Ljava/lang/String;)V
 HSPLandroid/net/RouteInfo;-><init>(Ljava/net/InetAddress;)V
 HSPLandroid/net/RouteInfo;->equals(Ljava/lang/Object;)Z
 HSPLandroid/net/RouteInfo;->isHost()Z
@@ -10099,6 +10524,8 @@
 HSPLandroid/net/ScoredNetwork$1;-><init>()V
 HSPLandroid/net/ScoredNetwork$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/ScoredNetwork;
 HSPLandroid/net/ScoredNetwork$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/net/ScoredNetwork$1;->newArray(I)[Landroid/net/ScoredNetwork;
+HPLandroid/net/ScoredNetwork$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/net/ScoredNetwork;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/net/SntpClient;->checkValidServerReply(BBIJ)V
 HSPLandroid/net/SntpClient;->read32([BI)J
@@ -10168,6 +10595,7 @@
 HSPLandroid/net/Uri$Builder;->fragment(Ljava/lang/String;)Landroid/net/Uri$Builder;
 HSPLandroid/net/Uri$Builder;->path(Ljava/lang/String;)Landroid/net/Uri$Builder;
 HSPLandroid/net/Uri$Builder;->scheme(Ljava/lang/String;)Landroid/net/Uri$Builder;
+HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;-><init>(Ljava/lang/String;Landroid/net/Uri$Part;Landroid/net/Uri$PathPart;Landroid/net/Uri$Part;Landroid/net/Uri$Part;)V
 HSPLandroid/net/Uri$HierarchicalUri;-><init>(Ljava/lang/String;Landroid/net/Uri$Part;Landroid/net/Uri$PathPart;Landroid/net/Uri$Part;Landroid/net/Uri$Part;Landroid/net/Uri$1;)V
 HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V
@@ -10218,6 +10646,7 @@
 HSPLandroid/net/Uri$StringUri;->getEncodedAuthority()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->getEncodedPath()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->getEncodedQuery()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->getFragment()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->getPath()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->getPathSegments()Ljava/util/List;
 HSPLandroid/net/Uri$StringUri;->getScheme()Ljava/lang/String;
@@ -10243,6 +10672,7 @@
 HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;
 HSPLandroid/net/Uri;->getQueryParameters(Ljava/lang/String;)Ljava/util/List;
 HSPLandroid/net/Uri;->hashCode()I
+HSPLandroid/net/Uri;->isAbsolute()Z
 HSPLandroid/net/Uri;->isAllowed(CLjava/lang/String;)Z
 HSPLandroid/net/Uri;->isOpaque()Z
 HSPLandroid/net/Uri;->isPathPrefixMatch(Landroid/net/Uri;)Z
@@ -10318,7 +10748,7 @@
 PLandroid/net/metrics/WakeupStats;->countEvent(Landroid/net/metrics/WakeupEvent;)V
 PLandroid/net/metrics/WakeupStats;->updateDuration()V
 HSPLandroid/net/nsd/INsdManager$Stub;-><init>()V
-PLandroid/net/nsd/INsdManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/net/nsd/INsdManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/net/shared/Inet4AddressUtils;->inet4AddressToIntHTH(Ljava/net/Inet4Address;)I
 HSPLandroid/net/sip/SipManager;->newInstance(Landroid/content/Context;)Landroid/net/sip/SipManager;
 HSPLandroid/net/util/-$$Lambda$MultinetworkPolicyTracker$0siHK6f4lHJz8hbdHbT6G4Kp-V4;->run()V
@@ -10347,17 +10777,18 @@
 HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->getScanResults(Ljava/lang/String;)Ljava/util/List;
 HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->getSupportedFeatures()J
 HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->getVerboseLoggingLevel()I
+HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->getWifiApEnabledState()I
 HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->getWifiEnabledState()I
 HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->isScanAlwaysAvailable()Z
 HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->setCountryCode(Ljava/lang/String;)V
 HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->startScan(Ljava/lang/String;)Z
 HSPLandroid/net/wifi/IWifiManager$Stub;-><init>()V
 HSPLandroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager;
-PLandroid/net/wifi/IWifiManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/net/wifi/IWifiManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/net/wifi/IWifiManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/net/wifi/IWifiScanner$Stub;-><init>()V
 HSPLandroid/net/wifi/IWifiScanner$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiScanner;
-PLandroid/net/wifi/IWifiScanner$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/net/wifi/IWifiScanner$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/net/wifi/ParcelUtil;->readPrivateKey(Landroid/os/Parcel;)Ljava/security/PrivateKey;
 HSPLandroid/net/wifi/ScanResult$1;-><init>()V
 HSPLandroid/net/wifi/ScanResult$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/wifi/ScanResult;
@@ -10368,7 +10799,7 @@
 HPLandroid/net/wifi/ScanResult;->is24GHz()Z
 HPLandroid/net/wifi/ScanResult;->is5GHz()Z
 HPLandroid/net/wifi/ScanResult;->isPasspointNetwork()Z
-PLandroid/net/wifi/ScanResult;->setFlag(J)V
+HPLandroid/net/wifi/ScanResult;->setFlag(J)V
 HSPLandroid/net/wifi/ScanResult;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/net/wifi/SupplicantState$1;-><init>()V
 HSPLandroid/net/wifi/SupplicantState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/wifi/SupplicantState;
@@ -10378,16 +10809,16 @@
 HSPLandroid/net/wifi/SupplicantState;->isConnecting(Landroid/net/wifi/SupplicantState;)Z
 HSPLandroid/net/wifi/SupplicantState;->isHandshakeState(Landroid/net/wifi/SupplicantState;)Z
 HSPLandroid/net/wifi/SupplicantState;->values()[Landroid/net/wifi/SupplicantState;
-PLandroid/net/wifi/SupplicantState;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/net/wifi/SupplicantState;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/net/wifi/WifiActivityEnergyInfo$1;-><init>()V
 HSPLandroid/net/wifi/WifiActivityEnergyInfo;-><init>(JIJ[JJJJJ)V
-PLandroid/net/wifi/WifiActivityEnergyInfo;->toString()Ljava/lang/String;
+HPLandroid/net/wifi/WifiActivityEnergyInfo;->toString()Ljava/lang/String;
 HSPLandroid/net/wifi/WifiConfiguration$1;-><init>()V
 HSPLandroid/net/wifi/WifiConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/wifi/WifiConfiguration;
 HSPLandroid/net/wifi/WifiConfiguration$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;-><init>()V
-PLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->clearDisableReasonCounter()V
-PLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->clearDisableReasonCounter(I)V
+HPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->clearDisableReasonCounter()V
+HPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->clearDisableReasonCounter(I)V
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->copy(Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;)V
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getCandidate()Landroid/net/wifi/ScanResult;
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getCandidateScore()I
@@ -10402,6 +10833,7 @@
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getNetworkSelectionStatus()I
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getNetworkStatusString()Ljava/lang/String;
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->getSeenInLastQualifiedNetworkSelection()Z
+HPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->incrementDisableReasonCounter(I)V
 HPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->isDisabledByReason(I)Z
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->isNetworkEnabled()Z
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->isNetworkPermanentlyDisabled()Z
@@ -10421,28 +10853,28 @@
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setNotRecommended(Z)V
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->setSeenInLastQualifiedNetworkSelection(Z)V
 HSPLandroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;->writeToParcel(Landroid/os/Parcel;)V
-PLandroid/net/wifi/WifiConfiguration$RecentFailure;->clear()V
+HPLandroid/net/wifi/WifiConfiguration$RecentFailure;->clear()V
 HSPLandroid/net/wifi/WifiConfiguration$RecentFailure;->getAssociationStatus()I
 HSPLandroid/net/wifi/WifiConfiguration$RecentFailure;->setAssociationStatus(I)V
 HSPLandroid/net/wifi/WifiConfiguration;-><init>()V
 HSPLandroid/net/wifi/WifiConfiguration;-><init>(Landroid/net/wifi/WifiConfiguration;)V
 HSPLandroid/net/wifi/WifiConfiguration;->configKey()Ljava/lang/String;
 HSPLandroid/net/wifi/WifiConfiguration;->configKey(Z)Ljava/lang/String;
-PLandroid/net/wifi/WifiConfiguration;->describeContents()I
+HPLandroid/net/wifi/WifiConfiguration;->describeContents()I
 HSPLandroid/net/wifi/WifiConfiguration;->getAuthType()I
-PLandroid/net/wifi/WifiConfiguration;->getBytesForBackup()[B
-PLandroid/net/wifi/WifiConfiguration;->getHttpProxy()Landroid/net/ProxyInfo;
+HPLandroid/net/wifi/WifiConfiguration;->getBytesForBackup()[B
+HPLandroid/net/wifi/WifiConfiguration;->getHttpProxy()Landroid/net/ProxyInfo;
 HSPLandroid/net/wifi/WifiConfiguration;->getIpAssignment()Landroid/net/IpConfiguration$IpAssignment;
 HSPLandroid/net/wifi/WifiConfiguration;->getIpConfiguration()Landroid/net/IpConfiguration;
 HSPLandroid/net/wifi/WifiConfiguration;->getNetworkSelectionStatus()Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;
 HSPLandroid/net/wifi/WifiConfiguration;->getOrCreateRandomizedMacAddress()Landroid/net/MacAddress;
-PLandroid/net/wifi/WifiConfiguration;->getPrintableSsid()Ljava/lang/String;
+HPLandroid/net/wifi/WifiConfiguration;->getPrintableSsid()Ljava/lang/String;
 HSPLandroid/net/wifi/WifiConfiguration;->getRandomizedMacAddress()Landroid/net/MacAddress;
 HPLandroid/net/wifi/WifiConfiguration;->isEnterprise()Z
 HSPLandroid/net/wifi/WifiConfiguration;->isEphemeral()Z
 HSPLandroid/net/wifi/WifiConfiguration;->isMetered(Landroid/net/wifi/WifiConfiguration;Landroid/net/wifi/WifiInfo;)Z
 HSPLandroid/net/wifi/WifiConfiguration;->isPasspoint()Z
-PLandroid/net/wifi/WifiConfiguration;->isValidMacAddressForRandomization(Landroid/net/MacAddress;)Z
+HPLandroid/net/wifi/WifiConfiguration;->isValidMacAddressForRandomization(Landroid/net/MacAddress;)Z
 HSPLandroid/net/wifi/WifiConfiguration;->setIpConfiguration(Landroid/net/IpConfiguration;)V
 HSPLandroid/net/wifi/WifiConfiguration;->setNetworkSelectionStatus(Landroid/net/wifi/WifiConfiguration$NetworkSelectionStatus;)V
 HSPLandroid/net/wifi/WifiConfiguration;->setRandomizedMacAddress(Landroid/net/MacAddress;)V
@@ -10451,12 +10883,12 @@
 HSPLandroid/net/wifi/WifiEnterpriseConfig$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/wifi/WifiEnterpriseConfig;
 HSPLandroid/net/wifi/WifiEnterpriseConfig$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/net/wifi/WifiEnterpriseConfig;->copyFrom(Landroid/net/wifi/WifiEnterpriseConfig;ZLjava/lang/String;)V
-PLandroid/net/wifi/WifiEnterpriseConfig;->getAnonymousIdentity()Ljava/lang/String;
-PLandroid/net/wifi/WifiEnterpriseConfig;->getCaCertificates()[Ljava/security/cert/X509Certificate;
+HPLandroid/net/wifi/WifiEnterpriseConfig;->getAnonymousIdentity()Ljava/lang/String;
+HPLandroid/net/wifi/WifiEnterpriseConfig;->getCaCertificates()[Ljava/security/cert/X509Certificate;
 HSPLandroid/net/wifi/WifiEnterpriseConfig;->getEapMethod()I
 HSPLandroid/net/wifi/WifiEnterpriseConfig;->getFieldValue(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/net/wifi/WifiEnterpriseConfig;->getFieldValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-PLandroid/net/wifi/WifiEnterpriseConfig;->getIdentity()Ljava/lang/String;
+HPLandroid/net/wifi/WifiEnterpriseConfig;->getIdentity()Ljava/lang/String;
 HSPLandroid/net/wifi/WifiEnterpriseConfig;->getPassword()Ljava/lang/String;
 HSPLandroid/net/wifi/WifiEnterpriseConfig;->getPhase2Method()I
 HSPLandroid/net/wifi/WifiEnterpriseConfig;->writeToParcel(Landroid/os/Parcel;I)V
@@ -10475,7 +10907,7 @@
 HPLandroid/net/wifi/WifiInfo;->getRxLinkSpeedMbps()I
 HSPLandroid/net/wifi/WifiInfo;->getSSID()Ljava/lang/String;
 HSPLandroid/net/wifi/WifiInfo;->getSupplicantState()Landroid/net/wifi/SupplicantState;
-PLandroid/net/wifi/WifiInfo;->getWifiSsid()Landroid/net/wifi/WifiSsid;
+HPLandroid/net/wifi/WifiInfo;->getWifiSsid()Landroid/net/wifi/WifiSsid;
 HPLandroid/net/wifi/WifiInfo;->is24GHz()Z
 HSPLandroid/net/wifi/WifiInfo;->is5GHz()Z
 HSPLandroid/net/wifi/WifiInfo;->isEphemeral()Z
@@ -10519,13 +10951,15 @@
 HSPLandroid/net/wifi/WifiManager;->getSupportedFeatures()J
 HSPLandroid/net/wifi/WifiManager;->getVerboseLoggingLevel()I
 HSPLandroid/net/wifi/WifiManager;->getWifiApConfiguration()Landroid/net/wifi/WifiConfiguration;
+HSPLandroid/net/wifi/WifiManager;->getWifiApState()I
 HSPLandroid/net/wifi/WifiManager;->getWifiState()I
 HSPLandroid/net/wifi/WifiManager;->isEnhancedOpenSupported()Z
 HSPLandroid/net/wifi/WifiManager;->isScanAlwaysAvailable()Z
+HSPLandroid/net/wifi/WifiManager;->isWifiApEnabled()Z
 HSPLandroid/net/wifi/WifiManager;->isWifiEnabled()Z
 HSPLandroid/net/wifi/WifiManager;->isWpa3SaeSupported()Z
 HSPLandroid/net/wifi/WifiManager;->isWpa3SuiteBSupported()Z
-PLandroid/net/wifi/WifiManager;->retrieveBackupData()[B
+HPLandroid/net/wifi/WifiManager;->retrieveBackupData()[B
 HSPLandroid/net/wifi/WifiManager;->setCountryCode(Ljava/lang/String;)V
 HSPLandroid/net/wifi/WifiManager;->startScan()Z
 HSPLandroid/net/wifi/WifiManager;->startScan(Landroid/os/WorkSource;)Z
@@ -10556,8 +10990,8 @@
 HSPLandroid/net/wifi/WifiScanner$ScanData$1;-><init>()V
 HPLandroid/net/wifi/WifiScanner$ScanData;->getBandScanned()I
 HPLandroid/net/wifi/WifiScanner$ScanData;->getBucketsScanned()I
-PLandroid/net/wifi/WifiScanner$ScanData;->getFlags()I
-PLandroid/net/wifi/WifiScanner$ScanData;->getId()I
+HPLandroid/net/wifi/WifiScanner$ScanData;->getFlags()I
+HPLandroid/net/wifi/WifiScanner$ScanData;->getId()I
 HPLandroid/net/wifi/WifiScanner$ScanData;->getResults()[Landroid/net/wifi/ScanResult;
 HPLandroid/net/wifi/WifiScanner$ScanData;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/net/wifi/WifiScanner$ScanSettings$1;-><init>()V
@@ -10575,9 +11009,9 @@
 HSPLandroid/net/wifi/WifiScanner;->removeListener(I)Ljava/lang/Object;
 HSPLandroid/net/wifi/WifiScanner;->removeListener(Ljava/lang/Object;)I
 HSPLandroid/net/wifi/WifiScanner;->setScanningEnabled(Z)V
-PLandroid/net/wifi/WifiScanner;->startDisconnectedPnoScan(Landroid/net/wifi/WifiScanner$ScanSettings;Landroid/net/wifi/WifiScanner$PnoSettings;Landroid/net/wifi/WifiScanner$PnoScanListener;)V
+HPLandroid/net/wifi/WifiScanner;->startDisconnectedPnoScan(Landroid/net/wifi/WifiScanner$ScanSettings;Landroid/net/wifi/WifiScanner$PnoSettings;Landroid/net/wifi/WifiScanner$PnoScanListener;)V
 HSPLandroid/net/wifi/WifiScanner;->startScan(Landroid/net/wifi/WifiScanner$ScanSettings;Landroid/net/wifi/WifiScanner$ScanListener;Landroid/os/WorkSource;)V
-PLandroid/net/wifi/WifiScanner;->stopPnoScan(Landroid/net/wifi/WifiScanner$ScanListener;)V
+HPLandroid/net/wifi/WifiScanner;->stopPnoScan(Landroid/net/wifi/WifiScanner$ScanListener;)V
 HSPLandroid/net/wifi/WifiSsid$1;-><init>()V
 HSPLandroid/net/wifi/WifiSsid$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/wifi/WifiSsid;
 HSPLandroid/net/wifi/WifiSsid$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -10603,16 +11037,20 @@
 HSPLandroid/net/wifi/p2p/WifiP2pGroupList;-><init>(Landroid/net/wifi/p2p/WifiP2pGroupList;Landroid/net/wifi/p2p/WifiP2pGroupList$GroupDeleteListener;)V
 HSPLandroid/net/wifi/p2p/WifiP2pInfo$1;-><init>()V
 HSPLandroid/net/wifi/rtt/IWifiRttManager$Stub;-><init>()V
-PLandroid/net/wifi/rtt/IWifiRttManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/net/wifi/rtt/IWifiRttManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/nfc/INfcAdapter$Stub$Proxy;->deviceSupportsNfcSecure()Z
 HSPLandroid/nfc/INfcAdapter$Stub$Proxy;->getNfcCardEmulationInterface()Landroid/nfc/INfcCardEmulation;
 HSPLandroid/nfc/INfcAdapter$Stub$Proxy;->getNfcFCardEmulationInterface()Landroid/nfc/INfcFCardEmulation;
 HSPLandroid/nfc/INfcAdapter$Stub$Proxy;->getNfcTagInterface()Landroid/nfc/INfcTag;
+HSPLandroid/nfc/INfcAdapter$Stub$Proxy;->getState()I
 HSPLandroid/nfc/NfcAdapter;-><init>(Landroid/content/Context;)V
 HSPLandroid/nfc/NfcAdapter;->getDefaultAdapter(Landroid/content/Context;)Landroid/nfc/NfcAdapter;
 HSPLandroid/nfc/NfcAdapter;->getNfcAdapter(Landroid/content/Context;)Landroid/nfc/NfcAdapter;
 HSPLandroid/nfc/NfcAdapter;->hasBeamFeature()Z
 HSPLandroid/nfc/NfcAdapter;->hasNfcFeature()Z
 HSPLandroid/nfc/NfcAdapter;->hasNfcHceFeature()Z
+HSPLandroid/nfc/NfcAdapter;->isEnabled()Z
+HSPLandroid/nfc/NfcAdapter;->isSecureNfcSupported()Z
 HSPLandroid/nfc/NfcManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/opengl/EGL14;->eglCreateWindowSurface(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/lang/Object;[II)Landroid/opengl/EGLSurface;
 HSPLandroid/opengl/EGLConfig;-><init>(J)V
@@ -10742,6 +11180,7 @@
 HPLandroid/os/BatteryStats$LevelStepTracker;->getModModeAt(I)I
 HSPLandroid/os/BatteryStats$LevelStepTracker;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/os/BatteryStats$LevelStepTracker;->writeToParcel(Landroid/os/Parcel;)V
+HSPLandroid/os/BatteryStats$Timer;-><init>()V
 HPLandroid/os/BatteryStats$Timer;->getCurrentDurationMsLocked(J)J
 HPLandroid/os/BatteryStats$Timer;->getMaxDurationMsLocked(J)J
 HPLandroid/os/BatteryStats$Timer;->getTotalDurationMsLocked(J)J
@@ -10763,12 +11202,14 @@
 HSPLandroid/os/Binder$PropagateWorkSourceTransactListener;->onTransactEnded(Ljava/lang/Object;)V
 HSPLandroid/os/Binder$PropagateWorkSourceTransactListener;->onTransactStarted(Landroid/os/IBinder;I)Ljava/lang/Object;
 HSPLandroid/os/Binder;-><init>()V
+HSPLandroid/os/Binder;-><init>(Ljava/lang/String;)V
 HSPLandroid/os/Binder;->access$000()J
 HSPLandroid/os/Binder;->allowBlocking(Landroid/os/IBinder;)Landroid/os/IBinder;
 HSPLandroid/os/Binder;->attachInterface(Landroid/os/IInterface;Ljava/lang/String;)V
 HSPLandroid/os/Binder;->copyAllowBlocking(Landroid/os/IBinder;Landroid/os/IBinder;)V
 HSPLandroid/os/Binder;->defaultBlocking(Landroid/os/IBinder;)Landroid/os/IBinder;
 HSPLandroid/os/Binder;->doDump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
+HPLandroid/os/Binder;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
 HSPLandroid/os/Binder;->dump(Ljava/io/FileDescriptor;[Ljava/lang/String;)V
 HSPLandroid/os/Binder;->execTransact(IJJI)Z
 HSPLandroid/os/Binder;->execTransactInternal(IJJII)Z
@@ -10784,6 +11225,7 @@
 HSPLandroid/os/Binder;->setProxyTransactListener(Landroid/os/Binder$ProxyTransactListener;)V
 HSPLandroid/os/Binder;->setWarnOnBlocking(Z)V
 HSPLandroid/os/Binder;->setWorkSourceProvider(Lcom/android/internal/os/BinderInternal$WorkSourceProvider;)V
+HSPLandroid/os/Binder;->shellCommand(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/lang/String;Landroid/os/ShellCallback;Landroid/os/ResultReceiver;)V
 HSPLandroid/os/Binder;->transact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/Binder;->unlinkToDeath(Landroid/os/IBinder$DeathRecipient;I)Z
 HSPLandroid/os/Binder;->withCleanCallingIdentity(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;)V
@@ -10811,6 +11253,8 @@
 HSPLandroid/os/Bundle$1;-><init>()V
 HSPLandroid/os/Bundle$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/Bundle;
 HSPLandroid/os/Bundle$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/Bundle$1;->newArray(I)[Landroid/os/Bundle;
+HSPLandroid/os/Bundle$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/os/Bundle;-><init>()V
 HSPLandroid/os/Bundle;-><init>(I)V
 HSPLandroid/os/Bundle;-><init>(Landroid/os/Bundle;)V
@@ -10858,6 +11302,8 @@
 HSPLandroid/os/Bundle;->toString()Ljava/lang/String;
 HSPLandroid/os/Bundle;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/os/CancellationSignal;-><init>()V
+HSPLandroid/os/CancellationSignal;->cancel()V
+HSPLandroid/os/CancellationSignal;->createTransport()Landroid/os/ICancellationSignal;
 HSPLandroid/os/CancellationSignal;->fromTransport(Landroid/os/ICancellationSignal;)Landroid/os/CancellationSignal;
 HSPLandroid/os/CancellationSignal;->isCanceled()Z
 HSPLandroid/os/CancellationSignal;->setOnCancelListener(Landroid/os/CancellationSignal$OnCancelListener;)V
@@ -10869,6 +11315,7 @@
 HSPLandroid/os/ConditionVariable;-><init>(Z)V
 HSPLandroid/os/ConditionVariable;->block()V
 HSPLandroid/os/ConditionVariable;->block(J)Z
+HSPLandroid/os/ConditionVariable;->close()V
 HSPLandroid/os/ConditionVariable;->open()V
 HSPLandroid/os/CpuUsageInfo$1;-><init>()V
 HSPLandroid/os/DeadObjectException;-><init>()V
@@ -10878,6 +11325,7 @@
 HSPLandroid/os/Debug$MemoryInfo$1;->newArray(I)[Landroid/os/Debug$MemoryInfo;
 HSPLandroid/os/Debug$MemoryInfo$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/os/Debug$MemoryInfo;-><init>()V
+HSPLandroid/os/Debug$MemoryInfo;->getMemoryStats()Ljava/util/Map;
 HSPLandroid/os/Debug$MemoryInfo;->getOtherLabel(I)Ljava/lang/String;
 HSPLandroid/os/Debug$MemoryInfo;->getOtherPrivate(I)I
 HSPLandroid/os/Debug$MemoryInfo;->getOtherPrivateClean(I)I
@@ -10896,6 +11344,7 @@
 HSPLandroid/os/Debug$MemoryInfo;->getSummaryStack()I
 HSPLandroid/os/Debug$MemoryInfo;->getSummarySystem()I
 HSPLandroid/os/Debug$MemoryInfo;->getSummaryTotalPss()I
+HSPLandroid/os/Debug$MemoryInfo;->getSummaryTotalSwap()I
 HSPLandroid/os/Debug$MemoryInfo;->getSummaryTotalSwapPss()I
 HSPLandroid/os/Debug$MemoryInfo;->getTotalPrivateClean()I
 HSPLandroid/os/Debug$MemoryInfo;->getTotalPrivateDirty()I
@@ -10938,10 +11387,11 @@
 HSPLandroid/os/Environment$UserEnvironment;->buildExternalStorageAppFilesDirs(Ljava/lang/String;)[Ljava/io/File;
 HSPLandroid/os/Environment$UserEnvironment;->buildExternalStoragePublicDirs(Ljava/lang/String;)[Ljava/io/File;
 HSPLandroid/os/Environment$UserEnvironment;->getExternalDirs()[Ljava/io/File;
-PLandroid/os/Environment$UserEnvironment;->getExternalStoragePublicDirectory(Ljava/lang/String;)Ljava/io/File;
+HPLandroid/os/Environment$UserEnvironment;->getExternalStoragePublicDirectory(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/os/Environment;->buildExternalStorageAppCacheDirs(Ljava/lang/String;)[Ljava/io/File;
 HSPLandroid/os/Environment;->buildExternalStorageAppFilesDirs(Ljava/lang/String;)[Ljava/io/File;
 HSPLandroid/os/Environment;->buildPath(Ljava/io/File;[Ljava/lang/String;)Ljava/io/File;
+HSPLandroid/os/Environment;->buildPaths([Ljava/io/File;[Ljava/lang/String;)[Ljava/io/File;
 HSPLandroid/os/Environment;->getDataAppDirectory(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/os/Environment;->getDataDirectory()Ljava/io/File;
 HSPLandroid/os/Environment;->getDataMiscCeDirectory()Ljava/io/File;
@@ -10949,7 +11399,7 @@
 HSPLandroid/os/Environment;->getDataMiscDirectory()Ljava/io/File;
 HSPLandroid/os/Environment;->getDataProfilesDeDirectory(I)Ljava/io/File;
 HSPLandroid/os/Environment;->getDataProfilesDePackageDirectory(ILjava/lang/String;)Ljava/io/File;
-PLandroid/os/Environment;->getDataRefProfilesDePackageDirectory(Ljava/lang/String;)Ljava/io/File;
+HPLandroid/os/Environment;->getDataRefProfilesDePackageDirectory(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/os/Environment;->getDataSystemCeDirectory()Ljava/io/File;
 HSPLandroid/os/Environment;->getDataSystemCeDirectory(I)Ljava/io/File;
 HSPLandroid/os/Environment;->getDataSystemDeDirectory()Ljava/io/File;
@@ -10981,7 +11431,7 @@
 HSPLandroid/os/Environment;->isExternalStorageEmulated(Ljava/io/File;)Z
 HSPLandroid/os/Environment;->setUserRequired(Z)V
 HSPLandroid/os/FactoryTest;->getMode()I
-PLandroid/os/FactoryTest;->isLongPressOnPowerOffEnabled()Z
+HPLandroid/os/FactoryTest;->isLongPressOnPowerOffEnabled()Z
 PLandroid/os/FileBridge;-><init>()V
 PLandroid/os/FileBridge;->forceClose()V
 PLandroid/os/FileBridge;->isClosed()Z
@@ -11009,10 +11459,10 @@
 HSPLandroid/os/FileUtils;->listFilesOrEmpty(Ljava/io/File;)[Ljava/io/File;
 HSPLandroid/os/FileUtils;->newFileOrNull(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/os/FileUtils;->readTextFile(Ljava/io/File;ILjava/lang/String;)Ljava/lang/String;
-PLandroid/os/FileUtils;->rewriteAfterRename(Ljava/io/File;Ljava/io/File;Ljava/io/File;)Ljava/io/File;
-PLandroid/os/FileUtils;->rewriteAfterRename(Ljava/io/File;Ljava/io/File;Ljava/lang/String;)Ljava/lang/String;
-PLandroid/os/FileUtils;->rewriteAfterRename(Ljava/io/File;Ljava/io/File;[Ljava/lang/String;)[Ljava/lang/String;
-PLandroid/os/FileUtils;->roundStorageSize(J)J
+HPLandroid/os/FileUtils;->rewriteAfterRename(Ljava/io/File;Ljava/io/File;Ljava/io/File;)Ljava/io/File;
+HPLandroid/os/FileUtils;->rewriteAfterRename(Ljava/io/File;Ljava/io/File;Ljava/lang/String;)Ljava/lang/String;
+HPLandroid/os/FileUtils;->rewriteAfterRename(Ljava/io/File;Ljava/io/File;[Ljava/lang/String;)[Ljava/lang/String;
+HPLandroid/os/FileUtils;->roundStorageSize(J)J
 HSPLandroid/os/FileUtils;->setPermissions(Ljava/io/File;III)I
 HSPLandroid/os/FileUtils;->setPermissions(Ljava/io/FileDescriptor;III)I
 HSPLandroid/os/FileUtils;->setPermissions(Ljava/lang/String;III)I
@@ -11103,7 +11553,7 @@
 HSPLandroid/os/HwParcel;->readInt32Vector()Ljava/util/ArrayList;
 HSPLandroid/os/HwParcel;->readInt8Vector()Ljava/util/ArrayList;
 HSPLandroid/os/HwParcel;->readStringVector()Ljava/util/ArrayList;
-PLandroid/os/HwParcel;->writeInt16Vector(Ljava/util/ArrayList;)V
+HPLandroid/os/HwParcel;->writeInt16Vector(Ljava/util/ArrayList;)V
 HSPLandroid/os/HwParcel;->writeInt32Vector(Ljava/util/ArrayList;)V
 HSPLandroid/os/HwParcel;->writeInt8Vector(Ljava/util/ArrayList;)V
 HSPLandroid/os/HwParcel;->writeStringVector(Ljava/util/ArrayList;)V
@@ -11131,21 +11581,22 @@
 HSPLandroid/os/IInstalld$Stub$Proxy;->assertFsverityRootHashMatches(Ljava/lang/String;[B)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->clearAppData(Ljava/lang/String;Ljava/lang/String;IIJ)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->clearAppProfiles(Ljava/lang/String;Ljava/lang/String;)V
-PLandroid/os/IInstalld$Stub$Proxy;->copySystemProfile(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
+HPLandroid/os/IInstalld$Stub$Proxy;->copySystemProfile(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z
 HSPLandroid/os/IInstalld$Stub$Proxy;->createAppData(Ljava/lang/String;Ljava/lang/String;IIILjava/lang/String;I)J
 HPLandroid/os/IInstalld$Stub$Proxy;->createOatDir(Ljava/lang/String;Ljava/lang/String;)V
-PLandroid/os/IInstalld$Stub$Proxy;->createProfileSnapshot(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
+HPLandroid/os/IInstalld$Stub$Proxy;->createProfileSnapshot(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
 HSPLandroid/os/IInstalld$Stub$Proxy;->createUserData(Ljava/lang/String;III)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->destroyAppData(Ljava/lang/String;Ljava/lang/String;IIJ)V
-PLandroid/os/IInstalld$Stub$Proxy;->destroyProfileSnapshot(Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/os/IInstalld$Stub$Proxy;->destroyAppProfiles(Ljava/lang/String;)V
+HPLandroid/os/IInstalld$Stub$Proxy;->destroyProfileSnapshot(Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->dexopt(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->fixupAppData(Ljava/lang/String;I)V
 HPLandroid/os/IInstalld$Stub$Proxy;->getAppSize(Ljava/lang/String;[Ljava/lang/String;III[J[Ljava/lang/String;)[J
-PLandroid/os/IInstalld$Stub$Proxy;->getExternalSize(Ljava/lang/String;II[I)[J
+HPLandroid/os/IInstalld$Stub$Proxy;->getExternalSize(Ljava/lang/String;II[I)[J
 HPLandroid/os/IInstalld$Stub$Proxy;->getUserSize(Ljava/lang/String;II[I)[J
 HPLandroid/os/IInstalld$Stub$Proxy;->hashSecondaryDexFile(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)[B
 HSPLandroid/os/IInstalld$Stub$Proxy;->idmap(Ljava/lang/String;Ljava/lang/String;I)V
-PLandroid/os/IInstalld$Stub$Proxy;->installApkVerity(Ljava/lang/String;Ljava/io/FileDescriptor;I)V
+HPLandroid/os/IInstalld$Stub$Proxy;->installApkVerity(Ljava/lang/String;Ljava/io/FileDescriptor;I)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->invalidateMounts()V
 HPLandroid/os/IInstalld$Stub$Proxy;->isQuotaSupported(Ljava/lang/String;)Z
 HSPLandroid/os/IInstalld$Stub$Proxy;->linkNativeLibraryDirectory(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
@@ -11153,7 +11604,7 @@
 HPLandroid/os/IInstalld$Stub$Proxy;->mergeProfiles(ILjava/lang/String;Ljava/lang/String;)Z
 HPLandroid/os/IInstalld$Stub$Proxy;->moveAb(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->prepareAppProfile(Ljava/lang/String;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
-PLandroid/os/IInstalld$Stub$Proxy;->reconcileSecondaryDexFile(Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;Ljava/lang/String;I)Z
+HPLandroid/os/IInstalld$Stub$Proxy;->reconcileSecondaryDexFile(Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;Ljava/lang/String;I)Z
 HSPLandroid/os/IInstalld$Stub$Proxy;->rmPackageDir(Ljava/lang/String;)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->rmdex(Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/os/IInstalld$Stub$Proxy;->setAppQuota(Ljava/lang/String;IIJ)V
@@ -11165,10 +11616,11 @@
 PLandroid/os/INetworkActivityListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HPLandroid/os/INetworkActivityListener$Stub$Proxy;->onNetworkActive()V
 PLandroid/os/INetworkActivityListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkActivityListener;
+HSPLandroid/os/INetworkManagementService$Stub$Proxy;->isBandwidthControlEnabled()Z
 HSPLandroid/os/INetworkManagementService$Stub$Proxy;->setUidCleartextNetworkPolicy(II)V
 HSPLandroid/os/INetworkManagementService$Stub;-><init>()V
 HSPLandroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
-PLandroid/os/INetworkManagementService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/os/INetworkManagementService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/os/INetworkManagementService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/IPermissionController$Stub;-><init>()V
 HSPLandroid/os/IPermissionController$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -11176,14 +11628,16 @@
 HSPLandroid/os/IPowerManager$Stub$Proxy;->isDeviceIdleMode()Z
 HSPLandroid/os/IPowerManager$Stub$Proxy;->isInteractive()Z
 HSPLandroid/os/IPowerManager$Stub$Proxy;->isPowerSaveMode()Z
+HSPLandroid/os/IPowerManager$Stub$Proxy;->isWakeLockLevelSupported(I)Z
 HSPLandroid/os/IPowerManager$Stub$Proxy;->releaseWakeLock(Landroid/os/IBinder;I)V
 HSPLandroid/os/IPowerManager$Stub$Proxy;->updateWakeLockWorkSource(Landroid/os/IBinder;Landroid/os/WorkSource;Ljava/lang/String;)V
+HSPLandroid/os/IPowerManager$Stub$Proxy;->userActivity(JII)V
 HSPLandroid/os/IPowerManager$Stub;-><init>()V
 HSPLandroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
-PLandroid/os/IPowerManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/os/IPowerManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/os/IPowerManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/IProcessInfoService$Stub;-><init>()V
-PLandroid/os/IProcessInfoService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/os/IProcessInfoService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/IProgressListener$Stub;-><init>()V
 HSPLandroid/os/IProgressListener$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/os/IRecoverySystem$Stub;-><init>()V
@@ -11195,10 +11649,11 @@
 HSPLandroid/os/ISchedulingPolicyService$Stub;-><init>()V
 HSPLandroid/os/ISchedulingPolicyService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/IStatsCompanionService$Stub;-><init>()V
+HPLandroid/os/IStatsCompanionService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/os/IStatsCompanionService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/IStatsManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/os/IStatsManager$Stub$Proxy;->informAllUidData([I[J[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V
-PLandroid/os/IStatsManager$Stub$Proxy;->informOnePackage(Ljava/lang/String;IJLjava/lang/String;Ljava/lang/String;)V
+HPLandroid/os/IStatsManager$Stub$Proxy;->informOnePackage(Ljava/lang/String;IJLjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/os/IStatsManager$Stub$Proxy;->informPollAlarmFired()V
 HSPLandroid/os/IStatsManager$Stub$Proxy;->statsCompanionReady()V
 HSPLandroid/os/IStatsManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IStatsManager;
@@ -11207,7 +11662,7 @@
 HSPLandroid/os/IStoraged$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IStoraged;
 HSPLandroid/os/ISystemUpdateManager$Stub;-><init>()V
 HSPLandroid/os/ISystemUpdateManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/ISystemUpdateManager;
-PLandroid/os/ISystemUpdateManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/os/ISystemUpdateManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/IThermalEventListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/os/IThermalEventListener$Stub$Proxy;->notifyThrottling(Landroid/os/Temperature;)V
 HSPLandroid/os/IThermalEventListener$Stub;-><init>()V
@@ -11233,12 +11688,13 @@
 HSPLandroid/os/IUserManager$Stub$Proxy;->isUserUnlockingOrUnlocked(I)Z
 HSPLandroid/os/IUserManager$Stub;-><init>()V
 HSPLandroid/os/IUserManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IUserManager;
-PLandroid/os/IUserManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/os/IUserManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/os/IUserManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/IVibratorService$Stub$Proxy;->hasVibrator()Z
 HSPLandroid/os/IVibratorService$Stub;-><init>()V
 HSPLandroid/os/IVibratorService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/IVold$Stub$Proxy;->commitChanges()V
+HSPLandroid/os/IVold$Stub$Proxy;->destroySandboxForApp(Ljava/lang/String;Ljava/lang/String;I)V
 HSPLandroid/os/IVold$Stub$Proxy;->fdeClearPassword()V
 HSPLandroid/os/IVold$Stub$Proxy;->fdeGetPassword()Ljava/lang/String;
 HSPLandroid/os/IVold$Stub$Proxy;->monitor()V
@@ -11248,6 +11704,7 @@
 HSPLandroid/os/IVold$Stub$Proxy;->onUserStarted(I[Ljava/lang/String;[I[Ljava/lang/String;)V
 HSPLandroid/os/IVold$Stub$Proxy;->prepareUserStorage(Ljava/lang/String;III)V
 HSPLandroid/os/IVold$Stub$Proxy;->reset()V
+HPLandroid/os/IVold$Stub$Proxy;->runIdleMaint(Landroid/os/IVoldTaskListener;)V
 HSPLandroid/os/IVold$Stub$Proxy;->setListener(Landroid/os/IVoldListener;)V
 HSPLandroid/os/IVold$Stub$Proxy;->unlockUserKey(IILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/os/IVold$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IVold;
@@ -11297,12 +11754,15 @@
 HSPLandroid/os/MemoryFile;->close()V
 HSPLandroid/os/MemoryFile;->deactivate()V
 HSPLandroid/os/MemoryFile;->getFileDescriptor()Ljava/io/FileDescriptor;
+HSPLandroid/os/MemoryFile;->getSize(Ljava/io/FileDescriptor;)I
 HSPLandroid/os/MemoryFile;->readBytes([BIII)I
 HSPLandroid/os/MemoryFile;->writeBytes([BIII)V
 HSPLandroid/os/Message$1;-><init>()V
 HSPLandroid/os/Message$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/Message;
 HSPLandroid/os/Message$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/Message;-><init>()V
 HSPLandroid/os/Message;->copyFrom(Landroid/os/Message;)V
+HSPLandroid/os/Message;->getCallback()Ljava/lang/Runnable;
 HSPLandroid/os/Message;->getData()Landroid/os/Bundle;
 HSPLandroid/os/Message;->getTarget()Landroid/os/Handler;
 HSPLandroid/os/Message;->obtain()Landroid/os/Message;
@@ -11358,6 +11818,7 @@
 HSPLandroid/os/Parcel;->copyClassCookies()Ljava/util/Map;
 HSPLandroid/os/Parcel;->createBinderArrayList()Ljava/util/ArrayList;
 HSPLandroid/os/Parcel;->createByteArray()[B
+HSPLandroid/os/Parcel;->createDoubleArray()[D
 HSPLandroid/os/Parcel;->createException(ILjava/lang/String;)Ljava/lang/Exception;
 HSPLandroid/os/Parcel;->createFloatArray()[F
 HSPLandroid/os/Parcel;->createIntArray()[I
@@ -11455,6 +11916,7 @@
 HSPLandroid/os/Parcel;->writePersistableBundle(Landroid/os/PersistableBundle;)V
 HSPLandroid/os/Parcel;->writeSerializable(Ljava/io/Serializable;)V
 HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V
+HSPLandroid/os/Parcel;->writeSparseBooleanArray(Landroid/util/SparseBooleanArray;)V
 HSPLandroid/os/Parcel;->writeString(Ljava/lang/String;)V
 HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V
 HSPLandroid/os/Parcel;->writeStringList(Ljava/util/List;)V
@@ -11484,7 +11946,7 @@
 HSPLandroid/os/ParcelFileDescriptor;->dup()Landroid/os/ParcelFileDescriptor;
 HSPLandroid/os/ParcelFileDescriptor;->dup(Ljava/io/FileDescriptor;)Landroid/os/ParcelFileDescriptor;
 HSPLandroid/os/ParcelFileDescriptor;->finalize()V
-PLandroid/os/ParcelFileDescriptor;->fromData([BLjava/lang/String;)Landroid/os/ParcelFileDescriptor;
+HPLandroid/os/ParcelFileDescriptor;->fromData([BLjava/lang/String;)Landroid/os/ParcelFileDescriptor;
 HSPLandroid/os/ParcelFileDescriptor;->getFd()I
 HSPLandroid/os/ParcelFileDescriptor;->getFile(Ljava/io/FileDescriptor;)Ljava/io/File;
 HSPLandroid/os/ParcelFileDescriptor;->getFileDescriptor()Ljava/io/FileDescriptor;
@@ -11550,20 +12012,20 @@
 HSPLandroid/os/PowerManager$WakeLock;->acquireLocked()V
 HSPLandroid/os/PowerManager$WakeLock;->finalize()V
 HSPLandroid/os/PowerManager$WakeLock;->isHeld()Z
-PLandroid/os/PowerManager$WakeLock;->lambda$wrap$0$PowerManager$WakeLock(Ljava/lang/Runnable;)V
+HPLandroid/os/PowerManager$WakeLock;->lambda$wrap$0$PowerManager$WakeLock(Ljava/lang/Runnable;)V
 HSPLandroid/os/PowerManager$WakeLock;->release()V
 HSPLandroid/os/PowerManager$WakeLock;->release(I)V
 HSPLandroid/os/PowerManager$WakeLock;->setReferenceCounted(Z)V
 HSPLandroid/os/PowerManager$WakeLock;->setWorkSource(Landroid/os/WorkSource;)V
 HSPLandroid/os/PowerManager$WakeLock;->toString()Ljava/lang/String;
-PLandroid/os/PowerManager$WakeLock;->wrap(Ljava/lang/Runnable;)Ljava/lang/Runnable;
+HPLandroid/os/PowerManager$WakeLock;->wrap(Ljava/lang/Runnable;)Ljava/lang/Runnable;
 HSPLandroid/os/PowerManager;-><init>(Landroid/content/Context;Landroid/os/IPowerManager;Landroid/os/Handler;)V
 HSPLandroid/os/PowerManager;->getDefaultScreenBrightnessSetting()I
 HSPLandroid/os/PowerManager;->getLocationPowerSaveMode()I
 HSPLandroid/os/PowerManager;->getMaximumScreenBrightnessSetting()I
 HSPLandroid/os/PowerManager;->getMinimumScreenBrightnessSetting()I
 HSPLandroid/os/PowerManager;->getPowerSaveState(I)Landroid/os/PowerSaveState;
-PLandroid/os/PowerManager;->goToSleep(JII)V
+HPLandroid/os/PowerManager;->goToSleep(JII)V
 HSPLandroid/os/PowerManager;->isDeviceIdleMode()Z
 HSPLandroid/os/PowerManager;->isInteractive()Z
 HSPLandroid/os/PowerManager;->isLightDeviceIdleMode()Z
@@ -11571,11 +12033,11 @@
 HSPLandroid/os/PowerManager;->isScreenOn()Z
 HSPLandroid/os/PowerManager;->isWakeLockLevelSupported(I)Z
 HSPLandroid/os/PowerManager;->newWakeLock(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;
-PLandroid/os/PowerManager;->sleepReasonToString(I)Ljava/lang/String;
+HPLandroid/os/PowerManager;->sleepReasonToString(I)Ljava/lang/String;
 HSPLandroid/os/PowerManager;->userActivity(JII)V
 HSPLandroid/os/PowerManager;->userActivity(JZ)V
 HSPLandroid/os/PowerManager;->validateWakeLockParameters(ILjava/lang/String;)V
-PLandroid/os/PowerManager;->wakeReasonToString(I)Ljava/lang/String;
+HPLandroid/os/PowerManager;->wakeReasonToString(I)Ljava/lang/String;
 HSPLandroid/os/PowerManager;->wakeUp(JILjava/lang/String;)V
 HSPLandroid/os/PowerManagerInternal;->registerLowPowerModeObserver(ILjava/util/function/Consumer;)V
 HSPLandroid/os/PowerManagerInternal;->wakefulnessToString(I)Ljava/lang/String;
@@ -11597,8 +12059,8 @@
 HSPLandroid/os/Process;->myUserHandle()Landroid/os/UserHandle;
 HSPLandroid/os/Process;->setStartTimes(JJ)V
 HSPLandroid/os/Process;->start(Ljava/lang/String;Ljava/lang/String;II[IIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)Landroid/os/Process$ProcessStartResult;
-PLandroid/os/Process;->startWebView(Ljava/lang/String;Ljava/lang/String;II[IIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)Landroid/os/Process$ProcessStartResult;
-PLandroid/os/RecoverySystem;->handleAftermath(Landroid/content/Context;)Ljava/lang/String;
+HPLandroid/os/Process;->startWebView(Ljava/lang/String;Ljava/lang/String;II[IIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)Landroid/os/Process$ProcessStartResult;
+HPLandroid/os/RecoverySystem;->handleAftermath(Landroid/content/Context;)Ljava/lang/String;
 HSPLandroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLandroid/os/Registrant;->clear()V
 HSPLandroid/os/Registrant;->getHandler()Landroid/os/Handler;
@@ -11651,7 +12113,7 @@
 HSPLandroid/os/ResultReceiver;->send(ILandroid/os/Bundle;)V
 HSPLandroid/os/ResultReceiver;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/os/SELinux;->restorecon(Ljava/io/File;)Z
-PLandroid/os/SELinux;->restoreconRecursive(Ljava/io/File;)Z
+HPLandroid/os/SELinux;->restoreconRecursive(Ljava/io/File;)Z
 HSPLandroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;)V
 HSPLandroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;ZI)V
 HSPLandroid/os/ServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
@@ -11669,13 +12131,21 @@
 HSPLandroid/os/SharedMemory$MemoryRegistration;->release()V
 HSPLandroid/os/SharedMemory$Unmapper;->run()V
 HSPLandroid/os/SharedMemory;-><init>(Ljava/io/FileDescriptor;)V
-PLandroid/os/SharedMemory;->close()V
+HPLandroid/os/SharedMemory;->close()V
 HSPLandroid/os/SharedMemory;->create(Ljava/lang/String;I)Landroid/os/SharedMemory;
 HSPLandroid/os/SharedMemory;->map(III)Ljava/nio/ByteBuffer;
 HSPLandroid/os/SharedMemory;->mapReadWrite()Ljava/nio/ByteBuffer;
-PLandroid/os/SharedMemory;->setProtect(I)Z
-PLandroid/os/SharedMemory;->unmap(Ljava/nio/ByteBuffer;)V
+HPLandroid/os/SharedMemory;->setProtect(I)Z
+HPLandroid/os/SharedMemory;->unmap(Ljava/nio/ByteBuffer;)V
 HSPLandroid/os/ShellCallback$1;-><init>()V
+HSPLandroid/os/ShellCallback$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/ShellCallback;
+HSPLandroid/os/ShellCallback$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/ShellCommand;->exec(Landroid/os/Binder;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/lang/String;Landroid/os/ShellCallback;Landroid/os/ResultReceiver;)I
+HSPLandroid/os/ShellCommand;->getNextArg()Ljava/lang/String;
+HSPLandroid/os/ShellCommand;->getNextOption()Ljava/lang/String;
+HSPLandroid/os/ShellCommand;->getOutPrintWriter()Ljava/io/PrintWriter;
+HSPLandroid/os/ShellCommand;->getRawOutputStream()Ljava/io/OutputStream;
+HSPLandroid/os/ShellCommand;->init(Landroid/os/Binder;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;[Ljava/lang/String;Landroid/os/ShellCallback;I)V
 HSPLandroid/os/SimpleClock;->instant()Ljava/time/Instant;
 HSPLandroid/os/StatFs;-><init>(Ljava/lang/String;)V
 HSPLandroid/os/StatFs;->doStat(Ljava/lang/String;)Landroid/system/StructStatVfs;
@@ -11720,6 +12190,7 @@
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onCustomSlowCall(Ljava/lang/String;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onExplicitGc()V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V
+HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onResourceMismatch(Ljava/lang/Object;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onThreadPolicyViolation(Landroid/os/StrictMode$ViolationInfo;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onUnbufferedIO()V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onWriteToDisk()V
@@ -11810,6 +12281,7 @@
 HSPLandroid/os/SystemService;->getState(Ljava/lang/String;)Landroid/os/SystemService$State;
 HSPLandroid/os/SystemService;->isRunning(Ljava/lang/String;)Z
 HSPLandroid/os/SystemUpdateManager;-><init>(Landroid/os/ISystemUpdateManager;)V
+HPLandroid/os/SystemVibrator;-><init>()V
 HSPLandroid/os/SystemVibrator;-><init>(Landroid/content/Context;)V
 HSPLandroid/os/SystemVibrator;->cancel()V
 HSPLandroid/os/SystemVibrator;->hasVibrator()Z
@@ -11828,7 +12300,7 @@
 HSPLandroid/os/Trace;->traceBegin(JLjava/lang/String;)V
 HSPLandroid/os/Trace;->traceCounter(JLjava/lang/String;I)V
 HSPLandroid/os/Trace;->traceEnd(J)V
-PLandroid/os/TransactionTooLargeException;-><init>(Ljava/lang/String;)V
+HPLandroid/os/TransactionTooLargeException;-><init>(Ljava/lang/String;)V
 HSPLandroid/os/UEventObserver$UEventThread;->addObserver(Ljava/lang/String;Landroid/os/UEventObserver;)V
 HSPLandroid/os/UEventObserver$UEventThread;->removeObserver(Landroid/os/UEventObserver;)V
 HSPLandroid/os/UEventObserver$UEventThread;->run()V
@@ -11842,7 +12314,7 @@
 HSPLandroid/os/UserHandle$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/UserHandle;
 HSPLandroid/os/UserHandle$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/os/UserHandle;-><init>(I)V
-PLandroid/os/UserHandle;->describeContents()I
+HPLandroid/os/UserHandle;->describeContents()I
 HSPLandroid/os/UserHandle;->equals(Ljava/lang/Object;)Z
 HSPLandroid/os/UserHandle;->formatUid(Ljava/io/PrintWriter;I)V
 HSPLandroid/os/UserHandle;->formatUid(Ljava/lang/StringBuilder;I)V
@@ -11870,7 +12342,7 @@
 HSPLandroid/os/UserHandle;->writeToParcel(Landroid/os/UserHandle;Landroid/os/Parcel;)V
 HSPLandroid/os/UserManager$EnforcingUser$1;-><init>()V
 HSPLandroid/os/UserManager;-><init>(Landroid/content/Context;Landroid/os/IUserManager;)V
-PLandroid/os/UserManager;->canAddMoreManagedProfiles(IZ)Z
+HPLandroid/os/UserManager;->canAddMoreManagedProfiles(IZ)Z
 HSPLandroid/os/UserManager;->get(Landroid/content/Context;)Landroid/os/UserManager;
 HSPLandroid/os/UserManager;->getApplicationRestrictions(Ljava/lang/String;)Landroid/os/Bundle;
 HSPLandroid/os/UserManager;->getCredentialOwnerProfile(I)I
@@ -11905,6 +12377,7 @@
 HSPLandroid/os/UserManager;->isQuietModeEnabled(Landroid/os/UserHandle;)Z
 HSPLandroid/os/UserManager;->isSameProfileGroup(II)Z
 HSPLandroid/os/UserManager;->isSplitSystemUser()Z
+HSPLandroid/os/UserManager;->isSystemUser()Z
 HSPLandroid/os/UserManager;->isUserAdmin(I)Z
 HSPLandroid/os/UserManager;->isUserRunning(I)Z
 HSPLandroid/os/UserManager;->isUserRunning(Landroid/os/UserHandle;)Z
@@ -11913,26 +12386,31 @@
 HSPLandroid/os/UserManager;->isUserUnlocked(I)Z
 HSPLandroid/os/UserManager;->isUserUnlocked(Landroid/os/UserHandle;)Z
 HSPLandroid/os/UserManager;->isUserUnlockingOrUnlocked(I)Z
-PLandroid/os/UserManager;->isUserUnlockingOrUnlocked(Landroid/os/UserHandle;)Z
+HPLandroid/os/UserManager;->isUserUnlockingOrUnlocked(Landroid/os/UserHandle;)Z
 HSPLandroid/os/UserManager;->supportsMultipleUsers()Z
 HSPLandroid/os/VibrationEffect$1;-><init>()V
-PLandroid/os/VibrationEffect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/VibrationEffect;
-PLandroid/os/VibrationEffect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/os/VibrationEffect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/VibrationEffect;
+HPLandroid/os/VibrationEffect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/os/VibrationEffect$OneShot$1;-><init>()V
+HPLandroid/os/VibrationEffect$OneShot;->getAmplitude()I
+HPLandroid/os/VibrationEffect$OneShot;->getDuration()J
+HPLandroid/os/VibrationEffect$OneShot;->resolve(I)Landroid/os/VibrationEffect$OneShot;
+HPLandroid/os/VibrationEffect$OneShot;->scale(FI)Landroid/os/VibrationEffect$OneShot;
 HSPLandroid/os/VibrationEffect$OneShot;->validate()V
 HSPLandroid/os/VibrationEffect$Prebaked$1;-><init>()V
 HPLandroid/os/VibrationEffect$Prebaked;->getDuration()J
 HPLandroid/os/VibrationEffect$Prebaked;->getEffectStrength()I
 HPLandroid/os/VibrationEffect$Prebaked;->getId()I
 HPLandroid/os/VibrationEffect$Prebaked;->setEffectStrength(I)V
+HPLandroid/os/VibrationEffect$Prebaked;->shouldFallback()Z
 HSPLandroid/os/VibrationEffect$Prebaked;->validate()V
 HSPLandroid/os/VibrationEffect$Waveform$1;-><init>()V
-PLandroid/os/VibrationEffect$Waveform;->getAmplitudes()[I
-PLandroid/os/VibrationEffect$Waveform;->getDuration()J
-PLandroid/os/VibrationEffect$Waveform;->getRepeatIndex()I
-PLandroid/os/VibrationEffect$Waveform;->getTimings()[J
-PLandroid/os/VibrationEffect$Waveform;->resolve(I)Landroid/os/VibrationEffect$Waveform;
-PLandroid/os/VibrationEffect$Waveform;->scale(FI)Landroid/os/VibrationEffect$Waveform;
+HPLandroid/os/VibrationEffect$Waveform;->getAmplitudes()[I
+HPLandroid/os/VibrationEffect$Waveform;->getDuration()J
+HPLandroid/os/VibrationEffect$Waveform;->getRepeatIndex()I
+HPLandroid/os/VibrationEffect$Waveform;->getTimings()[J
+HPLandroid/os/VibrationEffect$Waveform;->resolve(I)Landroid/os/VibrationEffect$Waveform;
+HPLandroid/os/VibrationEffect$Waveform;->scale(FI)Landroid/os/VibrationEffect$Waveform;
 HSPLandroid/os/VibrationEffect$Waveform;->validate()V
 HSPLandroid/os/VibrationEffect;->createOneShot(JI)Landroid/os/VibrationEffect;
 HSPLandroid/os/VibrationEffect;->createWaveform([JI)Landroid/os/VibrationEffect;
@@ -11947,17 +12425,17 @@
 HSPLandroid/os/WorkSource$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/WorkSource;
 HSPLandroid/os/WorkSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/os/WorkSource$WorkChain$1;-><init>()V
-PLandroid/os/WorkSource$WorkChain$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/WorkSource$WorkChain;
+HPLandroid/os/WorkSource$WorkChain$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/WorkSource$WorkChain;
 HPLandroid/os/WorkSource$WorkChain$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/os/WorkSource$WorkChain;->equals(Ljava/lang/Object;)Z
-PLandroid/os/WorkSource$WorkChain;->getAttributionUid()I
-PLandroid/os/WorkSource$WorkChain;->getTags()[Ljava/lang/String;
-PLandroid/os/WorkSource$WorkChain;->getUids()[I
+HPLandroid/os/WorkSource$WorkChain;->getAttributionUid()I
+HPLandroid/os/WorkSource$WorkChain;->getTags()[Ljava/lang/String;
+HPLandroid/os/WorkSource$WorkChain;->getUids()[I
 HSPLandroid/os/WorkSource;-><init>(I)V
 HSPLandroid/os/WorkSource;-><init>(ILjava/lang/String;)V
 HSPLandroid/os/WorkSource;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/os/WorkSource;-><init>(Landroid/os/WorkSource;)V
-PLandroid/os/WorkSource;->add(I)Z
+HPLandroid/os/WorkSource;->add(I)Z
 HSPLandroid/os/WorkSource;->add(ILjava/lang/String;)Z
 HSPLandroid/os/WorkSource;->add(Landroid/os/WorkSource;)Z
 HSPLandroid/os/WorkSource;->clearNames()V
@@ -11968,13 +12446,13 @@
 HSPLandroid/os/WorkSource;->getAttributionUid()I
 HSPLandroid/os/WorkSource;->getName(I)Ljava/lang/String;
 HSPLandroid/os/WorkSource;->getWorkChains()Ljava/util/ArrayList;
-PLandroid/os/WorkSource;->insert(II)V
+HPLandroid/os/WorkSource;->insert(II)V
 HSPLandroid/os/WorkSource;->insert(IILjava/lang/String;)V
 HSPLandroid/os/WorkSource;->isChainedBatteryAttributionEnabled(Landroid/content/Context;)Z
 HSPLandroid/os/WorkSource;->isEmpty()Z
 HSPLandroid/os/WorkSource;->remove(Landroid/os/WorkSource;)Z
 HSPLandroid/os/WorkSource;->removeUidsAndNames(Landroid/os/WorkSource;)Z
-PLandroid/os/WorkSource;->set(I)V
+HPLandroid/os/WorkSource;->set(I)V
 HSPLandroid/os/WorkSource;->set(Landroid/os/WorkSource;)V
 HSPLandroid/os/WorkSource;->setReturningDiffs(Landroid/os/WorkSource;)[Landroid/os/WorkSource;
 HSPLandroid/os/WorkSource;->size()I
@@ -12038,7 +12516,20 @@
 PLandroid/os/health/HealthKeys$Constants;->getSize(I)I
 PLandroid/os/health/HealthKeys$SortedIntArray;->addValue(I)V
 PLandroid/os/health/HealthKeys$SortedIntArray;->getArray()[I
+HSPLandroid/os/health/HealthStats;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/os/health/HealthStats;->getMeasurement(I)J
+HSPLandroid/os/health/HealthStats;->getStats(I)Ljava/util/Map;
+HSPLandroid/os/health/HealthStats;->getTimer(I)Landroid/os/health/TimerStat;
+HSPLandroid/os/health/HealthStats;->getTimers(I)Ljava/util/Map;
+HSPLandroid/os/health/HealthStats;->hasMeasurement(I)Z
+HSPLandroid/os/health/HealthStats;->hasMeasurements(I)Z
+HSPLandroid/os/health/HealthStats;->hasStats(I)Z
+HSPLandroid/os/health/HealthStats;->hasTimer(I)Z
+HSPLandroid/os/health/HealthStats;->hasTimers(I)Z
 HSPLandroid/os/health/HealthStatsParceler$1;-><init>()V
+HSPLandroid/os/health/HealthStatsParceler$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/health/HealthStatsParceler;
+HSPLandroid/os/health/HealthStatsParceler$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/health/HealthStatsParceler;->getHealthStats()Landroid/os/health/HealthStats;
 HPLandroid/os/health/HealthStatsParceler;->writeToParcel(Landroid/os/Parcel;I)V
 HPLandroid/os/health/HealthStatsWriter;-><init>(Landroid/os/health/HealthKeys$Constants;)V
 HPLandroid/os/health/HealthStatsWriter;->addMeasurement(IJ)V
@@ -12049,11 +12540,15 @@
 HPLandroid/os/health/HealthStatsWriter;->flattenToParcel(Landroid/os/Parcel;)V
 HPLandroid/os/health/HealthStatsWriter;->writeLongsMap(Landroid/os/Parcel;Landroid/util/ArrayMap;)V
 HPLandroid/os/health/HealthStatsWriter;->writeParcelableMap(Landroid/os/Parcel;Landroid/util/ArrayMap;)V
+HSPLandroid/os/health/SystemHealthManager;->takeMyUidSnapshot()Landroid/os/health/HealthStats;
+HSPLandroid/os/health/SystemHealthManager;->takeUidSnapshot(I)Landroid/os/health/HealthStats;
 HSPLandroid/os/health/TimerStat$1;-><init>()V
+HSPLandroid/os/health/TimerStat$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/health/TimerStat;
+HSPLandroid/os/health/TimerStat$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/os/health/TimerStat;-><init>(IJ)V
 HPLandroid/os/health/TimerStat;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/os/image/IDynamicSystemService$Stub;-><init>()V
-PLandroid/os/image/IDynamicSystemService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/os/image/IDynamicSystemService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->onStorageStateChanged(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->onVolumeStateChanged(Landroid/os/storage/VolumeInfo;II)V
@@ -12063,7 +12558,7 @@
 HSPLandroid/os/storage/IStorageManager$Stub$Proxy;->isUserKeyUnlocked(I)Z
 HSPLandroid/os/storage/IStorageManager$Stub;-><init>()V
 HSPLandroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
-PLandroid/os/storage/IStorageManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/os/storage/IStorageManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/os/storage/IStorageManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/storage/StorageEventListener;->onStorageStateChanged(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/os/storage/StorageManager$StorageEventListenerDelegate;->handleMessage(Landroid/os/Message;)Z
@@ -12084,8 +12579,8 @@
 HSPLandroid/os/storage/StorageManager;->from(Landroid/content/Context;)Landroid/os/storage/StorageManager;
 HSPLandroid/os/storage/StorageManager;->getAllocatableBytes(Ljava/util/UUID;I)J
 HSPLandroid/os/storage/StorageManager;->getBestVolumeDescription(Landroid/os/storage/VolumeInfo;)Ljava/lang/String;
-PLandroid/os/storage/StorageManager;->getPrimaryStorageSize()J
-PLandroid/os/storage/StorageManager;->getPrimaryStorageUuid()Ljava/lang/String;
+HPLandroid/os/storage/StorageManager;->getPrimaryStorageSize()J
+HPLandroid/os/storage/StorageManager;->getPrimaryStorageUuid()Ljava/lang/String;
 HSPLandroid/os/storage/StorageManager;->getPrimaryVolume()Landroid/os/storage/StorageVolume;
 HSPLandroid/os/storage/StorageManager;->getStorageCacheBytes(Ljava/io/File;I)J
 HSPLandroid/os/storage/StorageManager;->getStorageFullBytes(Ljava/io/File;)J
@@ -12152,8 +12647,8 @@
 HSPLandroid/os/storage/VolumeInfo;->writeToParcel(Landroid/os/Parcel;I)V
 PLandroid/permission/-$$Lambda$PermissionControllerManager$PendingGetRuntimePermissionBackup$TnLX6gxZCMF3D0czwj_XwNhPIgE;->run()V
 HSPLandroid/permission/-$$Lambda$PermissionControllerManager$RemoteService$L8N-TbqIPWKu7tyiOxbu_00YKss;-><init>()V
-PLandroid/permission/IPermissionController$Stub$Proxy;->asBinder()Landroid/os/IBinder;
-PLandroid/permission/IPermissionController$Stub$Proxy;->getRuntimePermissionBackup(Landroid/os/UserHandle;Landroid/os/ParcelFileDescriptor;)V
+HPLandroid/permission/IPermissionController$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HPLandroid/permission/IPermissionController$Stub$Proxy;->getRuntimePermissionBackup(Landroid/os/UserHandle;Landroid/os/ParcelFileDescriptor;)V
 PLandroid/permission/PermissionControllerManager$FileReaderTask;->doInBackground([Ljava/lang/Object;)Ljava/lang/Object;
 PLandroid/permission/PermissionControllerManager$FileReaderTask;->doInBackground([Ljava/lang/Void;)[B
 PLandroid/permission/PermissionControllerManager$FileReaderTask;->getRemotePipe()Landroid/os/ParcelFileDescriptor;
@@ -12167,7 +12662,7 @@
 HSPLandroid/permission/PermissionControllerManager$RemoteService;->getServiceInterface(Landroid/os/IBinder;)Landroid/os/IInterface;
 HSPLandroid/permission/PermissionControllerManager$RemoteService;->getTimeoutIdleBindMillis()J
 HSPLandroid/permission/PermissionControllerManager;-><init>(Landroid/content/Context;)V
-PLandroid/permission/PermissionControllerManager;->getRuntimePermissionBackup(Landroid/os/UserHandle;Ljava/util/concurrent/Executor;Landroid/permission/PermissionControllerManager$OnGetRuntimePermissionBackupCallback;)V
+HPLandroid/permission/PermissionControllerManager;->getRuntimePermissionBackup(Landroid/os/UserHandle;Ljava/util/concurrent/Executor;Landroid/permission/PermissionControllerManager$OnGetRuntimePermissionBackupCallback;)V
 HSPLandroid/permission/PermissionManager$SplitPermissionInfo;->getNewPermissions()Ljava/util/List;
 HSPLandroid/permission/PermissionManager$SplitPermissionInfo;->getSplitPermission()Ljava/lang/String;
 HSPLandroid/permission/PermissionManager$SplitPermissionInfo;->getTargetSdk()I
@@ -12205,17 +12700,19 @@
 HSPLandroid/provider/BlockedNumberContract$SystemContract;->shouldShowEmergencyCallNotification(Landroid/content/Context;)Z
 PLandroid/provider/BlockedNumberContract$SystemContract;->shouldSystemBlockNumber(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)I
 HPLandroid/provider/CallLog$Calls;->addCall(Lcom/android/internal/telephony/CallerInfo;Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIILandroid/telecom/PhoneAccountHandle;JILjava/lang/Long;ZLandroid/os/UserHandle;ZILjava/lang/CharSequence;Ljava/lang/String;Landroid/telecom/CallIdentification;)Landroid/net/Uri;
-PLandroid/provider/CallLog$Calls;->addEntryAndRemoveExpiredEntries(Landroid/content/Context;Landroid/os/UserManager;Landroid/os/UserHandle;Landroid/content/ContentValues;)Landroid/net/Uri;
-PLandroid/provider/CallLog$Calls;->charSequenceToString(Ljava/lang/CharSequence;)Ljava/lang/String;
-PLandroid/provider/CallLog$Calls;->getLogAccountAddress(Landroid/content/Context;Landroid/telecom/PhoneAccountHandle;)Ljava/lang/String;
-PLandroid/provider/CallLog$Calls;->getLogNumberPresentation(Ljava/lang/String;I)I
+HPLandroid/provider/CallLog$Calls;->addEntryAndRemoveExpiredEntries(Landroid/content/Context;Landroid/os/UserManager;Landroid/os/UserHandle;Landroid/content/ContentValues;)Landroid/net/Uri;
+HPLandroid/provider/CallLog$Calls;->charSequenceToString(Ljava/lang/CharSequence;)Ljava/lang/String;
+HPLandroid/provider/CallLog$Calls;->getLogAccountAddress(Landroid/content/Context;Landroid/telecom/PhoneAccountHandle;)Ljava/lang/String;
+HPLandroid/provider/CallLog$Calls;->getLogNumberPresentation(Ljava/lang/String;I)I
+HSPLandroid/provider/CallLog$Calls;->shouldHaveSharedCallLogEntries(Landroid/content/Context;Landroid/os/UserManager;I)Z
 HSPLandroid/provider/ContactsContract$CommonDataKinds$Phone;->getTypeLabel(Landroid/content/res/Resources;ILjava/lang/CharSequence;)Ljava/lang/CharSequence;
 HSPLandroid/provider/ContactsContract$CommonDataKinds$Phone;->getTypeLabelResource(I)I
 HSPLandroid/provider/ContactsContract$Contacts;->getLookupUri(JLjava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/ContactsContract$Contacts;->isEnterpriseContactId(J)Z
-PLandroid/provider/DeviceConfig$1;->onChange(ZLandroid/net/Uri;)V
+HPLandroid/provider/DeviceConfig$1;->onChange(ZLandroid/net/Uri;)V
 PLandroid/provider/DeviceConfig$3;->run()V
 HSPLandroid/provider/DeviceConfig;->addOnPropertyChangedListener(Ljava/lang/String;Ljava/util/concurrent/Executor;Landroid/provider/DeviceConfig$OnPropertyChangedListener;)V
+HSPLandroid/provider/DeviceConfig;->decrementNamespace(Ljava/lang/String;)V
 HSPLandroid/provider/DeviceConfig;->enforceReadPermission(Landroid/content/Context;Ljava/lang/String;)V
 HSPLandroid/provider/DeviceConfig;->getBoolean(Ljava/lang/String;Ljava/lang/String;Z)Z
 HSPLandroid/provider/DeviceConfig;->getFloat(Ljava/lang/String;Ljava/lang/String;F)F
@@ -12225,10 +12722,11 @@
 HSPLandroid/provider/DeviceConfig;->getString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HPLandroid/provider/DeviceConfig;->handleChange(Landroid/net/Uri;)V
 HSPLandroid/provider/DeviceConfig;->incrementNamespace(Ljava/lang/String;)V
+HSPLandroid/provider/DeviceConfig;->removeOnPropertyChangedListener(Landroid/provider/DeviceConfig$OnPropertyChangedListener;)V
 PLandroid/provider/Downloads;->removeAllDownloadsByPackage(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/provider/FontRequest;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V
 HSPLandroid/provider/FontsContract$1;-><init>()V
-PLandroid/provider/FontsContract$1;->run()V
+HPLandroid/provider/FontsContract$1;->run()V
 HSPLandroid/provider/FontsContract$FontFamilyResult;->getFonts()[Landroid/provider/FontsContract$FontInfo;
 HSPLandroid/provider/FontsContract$FontFamilyResult;->getStatusCode()I
 HSPLandroid/provider/FontsContract$FontInfo;->getAxes()[Landroid/graphics/fonts/FontVariationAxis;
@@ -12250,6 +12748,7 @@
 HSPLandroid/provider/MediaStore$Files;->getContentUri(Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/MediaStore$Images$Media;->getContentUri(Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/MediaStore$Video$Media;->getContentUri(Ljava/lang/String;)Landroid/net/Uri;
+HSPLandroid/provider/SearchIndexableResource;-><init>(Landroid/content/Context;)V
 HSPLandroid/provider/SearchIndexablesProvider;-><init>()V
 HSPLandroid/provider/SearchIndexablesProvider;->attachInfo(Landroid/content/Context;Landroid/content/pm/ProviderInfo;)V
 HSPLandroid/provider/Settings$ContentProviderHolder;-><init>(Landroid/net/Uri;)V
@@ -12364,8 +12863,9 @@
 HSPLandroid/security/KeyStore$OperationPromise;->onFinished(Landroid/security/keymaster/OperationResult;)V
 HSPLandroid/security/KeyStore$State;-><init>(Ljava/lang/String;I)V
 HSPLandroid/security/KeyStore;->abort(Landroid/os/IBinder;)I
-PLandroid/security/KeyStore;->addAuthToken([B)I
+HPLandroid/security/KeyStore;->addAuthToken([B)I
 HSPLandroid/security/KeyStore;->begin(Ljava/lang/String;IZLandroid/security/keymaster/KeymasterArguments;[BI)Landroid/security/keymaster/OperationResult;
+HSPLandroid/security/KeyStore;->clearUid(I)Z
 HSPLandroid/security/KeyStore;->contains(Ljava/lang/String;)Z
 HSPLandroid/security/KeyStore;->contains(Ljava/lang/String;I)Z
 HSPLandroid/security/KeyStore;->finish(Landroid/os/IBinder;Landroid/security/keymaster/KeymasterArguments;[B[B)Landroid/security/keymaster/OperationResult;
@@ -12374,13 +12874,13 @@
 HSPLandroid/security/KeyStore;->getToken()Landroid/os/IBinder;
 HPLandroid/security/KeyStore;->grant(Ljava/lang/String;I)Ljava/lang/String;
 HSPLandroid/security/KeyStore;->state(I)Landroid/security/KeyStore$State;
-PLandroid/security/KeyStore;->unlock(ILjava/lang/String;)Z
+HPLandroid/security/KeyStore;->unlock(ILjava/lang/String;)Z
 HSPLandroid/security/KeyStore;->update(Landroid/os/IBinder;Landroid/security/keymaster/KeymasterArguments;[B)Landroid/security/keymaster/OperationResult;
 HSPLandroid/security/NetworkSecurityPolicy;-><init>()V
-PLandroid/security/Scrypt;-><init>()V
-PLandroid/security/Scrypt;->scrypt([B[BIIII)[B
+HPLandroid/security/Scrypt;-><init>()V
+HPLandroid/security/Scrypt;->scrypt([B[BIIII)[B
 HSPLandroid/security/keymaster/IKeyAttestationApplicationIdProvider$Stub;-><init>()V
-PLandroid/security/keymaster/IKeyAttestationApplicationIdProvider$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/security/keymaster/IKeyAttestationApplicationIdProvider$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/security/keymaster/KeyAttestationApplicationId$1;-><init>()V
 PLandroid/security/keymaster/KeyAttestationApplicationId;->writeToParcel(Landroid/os/Parcel;I)V
 PLandroid/security/keymaster/KeyAttestationPackageInfo$1;-><init>()V
@@ -12476,13 +12976,14 @@
 HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->abort(Landroid/security/keystore/IKeystoreResponseCallback;Landroid/os/IBinder;)I
 HPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->addAuthToken([B)I
 HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->begin(Landroid/security/keystore/IKeystoreOperationResultCallback;Landroid/os/IBinder;Ljava/lang/String;IZLandroid/security/keymaster/KeymasterArguments;[BI)I
+HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->clear_uid(J)I
 HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->exist(Ljava/lang/String;I)I
 HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->finish(Landroid/security/keystore/IKeystoreOperationResultCallback;Landroid/os/IBinder;Landroid/security/keymaster/KeymasterArguments;[B[B)I
 HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->getKeyCharacteristics(Landroid/security/keystore/IKeystoreKeyCharacteristicsCallback;Ljava/lang/String;Landroid/security/keymaster/KeymasterBlob;Landroid/security/keymaster/KeymasterBlob;I)I
 HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->getState(I)I
 HPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->grant(Ljava/lang/String;I)Ljava/lang/String;
 HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->onKeyguardVisibilityChanged(ZI)I
-PLandroid/security/keystore/IKeystoreService$Stub$Proxy;->unlock(ILjava/lang/String;)I
+HPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->unlock(ILjava/lang/String;)I
 HSPLandroid/security/keystore/IKeystoreService$Stub$Proxy;->update(Landroid/security/keystore/IKeystoreOperationResultCallback;Landroid/os/IBinder;Landroid/security/keymaster/KeymasterArguments;[B)I
 HSPLandroid/security/keystore/IKeystoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/security/keystore/IKeystoreService;
 HSPLandroid/security/keystore/KeyProperties$KeyAlgorithm;->fromKeymasterSecretKeyAlgorithm(II)Ljava/lang/String;
@@ -12533,6 +13034,7 @@
 HSPLandroid/security/net/config/ApplicationConfig;->getDefaultInstance()Landroid/security/net/config/ApplicationConfig;
 HSPLandroid/security/net/config/ApplicationConfig;->setDefaultInstance(Landroid/security/net/config/ApplicationConfig;)V
 HSPLandroid/security/net/config/ConfigNetworkSecurityPolicy;->isCertificateTransparencyVerificationRequired(Ljava/lang/String;)Z
+HSPLandroid/security/net/config/ConfigNetworkSecurityPolicy;->isCleartextTrafficPermitted(Ljava/lang/String;)Z
 HSPLandroid/security/net/config/DirectoryCertificateSource$3;->match(Ljava/security/cert/X509Certificate;)Z
 HSPLandroid/security/net/config/DirectoryCertificateSource;-><init>(Ljava/io/File;)V
 HSPLandroid/security/net/config/DirectoryCertificateSource;->findCert(Ljavax/security/auth/x500/X500Principal;Landroid/security/net/config/DirectoryCertificateSource$CertSelector;)Ljava/security/cert/X509Certificate;
@@ -12582,6 +13084,7 @@
 HSPLandroid/security/net/config/XmlConfigSource;->getPerDomainConfigs()Ljava/util/Set;
 HSPLandroid/security/net/config/XmlConfigSource;->parseCertificatesEntry(Landroid/content/res/XmlResourceParser;Z)Landroid/security/net/config/CertificatesEntryRef;
 HSPLandroid/security/net/config/XmlConfigSource;->parseConfigEntry(Landroid/content/res/XmlResourceParser;Ljava/util/Set;Landroid/security/net/config/NetworkSecurityConfig$Builder;I)Ljava/util/List;
+HSPLandroid/security/net/config/XmlConfigSource;->parseDomain(Landroid/content/res/XmlResourceParser;Ljava/util/Set;)Landroid/security/net/config/Domain;
 HSPLandroid/security/net/config/XmlConfigSource;->parseNetworkSecurityConfig(Landroid/content/res/XmlResourceParser;)V
 HSPLandroid/security/net/config/XmlConfigSource;->parseTrustAnchors(Landroid/content/res/XmlResourceParser;Z)Ljava/util/Collection;
 PLandroid/service/appprediction/IPredictionService$Stub$Proxy;->notifyAppTargetEvent(Landroid/app/prediction/AppPredictionSessionId;Landroid/app/prediction/AppTargetEvent;)V
@@ -12633,6 +13136,7 @@
 HSPLandroid/service/contentcapture/IContentCaptureServiceCallback$Stub;->asBinder()Landroid/os/IBinder;
 PLandroid/service/contentcapture/IContentCaptureServiceCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/service/contentcapture/SnapshotData$1;-><init>()V
+HSPLandroid/service/dreams/IDreamManager$Stub$Proxy;->getDefaultDreamComponent()Landroid/content/ComponentName;
 HSPLandroid/service/dreams/IDreamManager$Stub;-><init>()V
 HSPLandroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager;
 HSPLandroid/service/dreams/IDreamManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -12654,8 +13158,15 @@
 PLandroid/service/gatekeeper/GateKeeperResponse$1;-><init>()V
 PLandroid/service/gatekeeper/GateKeeperResponse$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/gatekeeper/GateKeeperResponse;
 PLandroid/service/gatekeeper/GateKeeperResponse$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-PLandroid/service/gatekeeper/IGateKeeperService$Stub$Proxy;->verifyChallenge(IJ[B[B)Landroid/service/gatekeeper/GateKeeperResponse;
+HPLandroid/service/gatekeeper/IGateKeeperService$Stub$Proxy;->verifyChallenge(IJ[B[B)Landroid/service/gatekeeper/GateKeeperResponse;
 HSPLandroid/service/gatekeeper/IGateKeeperService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/gatekeeper/IGateKeeperService;
+HSPLandroid/service/media/IMediaBrowserService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/service/media/IMediaBrowserServiceCallbacks$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLandroid/service/media/MediaBrowserService$ServiceBinder$1;->run()V
+HSPLandroid/service/media/MediaBrowserService$ServiceBinder;->connect(Ljava/lang/String;Landroid/os/Bundle;Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/service/media/MediaBrowserService;-><init>()V
+HSPLandroid/service/media/MediaBrowserService;->onBind(Landroid/content/Intent;)Landroid/os/IBinder;
+HSPLandroid/service/media/MediaBrowserService;->onCreate()V
 HSPLandroid/service/notification/Adjustment$1;-><init>()V
 HSPLandroid/service/notification/Adjustment$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/Adjustment;
 HSPLandroid/service/notification/Adjustment$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -12703,9 +13214,10 @@
 HSPLandroid/service/notification/IStatusBarNotificationHolder$Stub$Proxy;->get()Landroid/service/notification/StatusBarNotification;
 HSPLandroid/service/notification/IStatusBarNotificationHolder$Stub;-><init>()V
 HSPLandroid/service/notification/IStatusBarNotificationHolder$Stub;->asBinder()Landroid/os/IBinder;
+HPLandroid/service/notification/IStatusBarNotificationHolder$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/service/notification/IStatusBarNotificationHolder$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/service/notification/NotificationAssistantService$MyHandler;->handleMessage(Landroid/os/Message;)V
-PLandroid/service/notification/NotificationAssistantService$NotificationAssistantServiceWrapper;->onActionClicked(Ljava/lang/String;Landroid/app/Notification$Action;I)V
+HPLandroid/service/notification/NotificationAssistantService$NotificationAssistantServiceWrapper;->onActionClicked(Ljava/lang/String;Landroid/app/Notification$Action;I)V
 HSPLandroid/service/notification/NotificationAssistantService$NotificationAssistantServiceWrapper;->onNotificationEnqueuedWithChannel(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/app/NotificationChannel;)V
 HSPLandroid/service/notification/NotificationAssistantService$NotificationAssistantServiceWrapper;->onNotificationExpansionChanged(Ljava/lang/String;ZZ)V
 HSPLandroid/service/notification/NotificationAssistantService$NotificationAssistantServiceWrapper;->onNotificationsSeen(Ljava/util/List;)V
@@ -12755,6 +13267,7 @@
 HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getUserSentiment(Ljava/lang/String;)I
 HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getVisibilityOverride(Ljava/lang/String;)I
 HSPLandroid/service/notification/NotificationListenerService$RankingMap;->isIntercepted(Ljava/lang/String;)Z
+HSPLandroid/service/notification/NotificationListenerService;-><init>()V
 HSPLandroid/service/notification/NotificationListenerService;->cleanUpNotificationList(Landroid/content/pm/ParceledListSlice;)[Landroid/service/notification/StatusBarNotification;
 HSPLandroid/service/notification/NotificationListenerService;->createLegacyIconExtras(Landroid/app/Notification;)V
 HSPLandroid/service/notification/NotificationListenerService;->getActiveNotifications()[Landroid/service/notification/StatusBarNotification;
@@ -12767,6 +13280,8 @@
 HSPLandroid/service/notification/NotificationListenerService;->onInterruptionFilterChanged(I)V
 HSPLandroid/service/notification/NotificationListenerService;->onNotificationPosted(Landroid/service/notification/StatusBarNotification;)V
 HSPLandroid/service/notification/NotificationListenerService;->onNotificationRankingUpdate(Landroid/service/notification/NotificationListenerService$RankingMap;)V
+HSPLandroid/service/notification/NotificationListenerService;->onNotificationRemoved(Landroid/service/notification/StatusBarNotification;Landroid/service/notification/NotificationListenerService$RankingMap;I)V
+HSPLandroid/service/notification/NotificationListenerService;->onNotificationRemoved(Landroid/service/notification/StatusBarNotification;Landroid/service/notification/NotificationListenerService$RankingMap;Landroid/service/notification/NotificationStats;I)V
 HSPLandroid/service/notification/NotificationRankingUpdate$1;-><init>()V
 HSPLandroid/service/notification/NotificationRankingUpdate$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/NotificationRankingUpdate;
 HSPLandroid/service/notification/NotificationRankingUpdate$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -12795,6 +13310,7 @@
 HSPLandroid/service/notification/NotificationStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/NotificationStats;
 HSPLandroid/service/notification/NotificationStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/service/notification/NotificationStats;-><init>(Landroid/os/Parcel;)V
+HPLandroid/service/notification/NotificationStats;->hasInteracted()Z
 HSPLandroid/service/notification/NotificationStats;->hasSeen()Z
 HSPLandroid/service/notification/NotificationStats;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/service/notification/NotifyingApp$1;-><init>()V
@@ -12832,7 +13348,7 @@
 HSPLandroid/service/notification/StatusBarNotification;->isAppGroup()Z
 HSPLandroid/service/notification/StatusBarNotification;->isGroup()Z
 HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;
-PLandroid/service/notification/StatusBarNotification;->setOverrideGroupKey(Ljava/lang/String;)V
+HPLandroid/service/notification/StatusBarNotification;->setOverrideGroupKey(Ljava/lang/String;)V
 HSPLandroid/service/notification/StatusBarNotification;->shortenTag(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/service/notification/StatusBarNotification;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/service/notification/ZenModeConfig$1;-><init>()V
@@ -12894,12 +13410,14 @@
 HSPLandroid/service/notification/ZenPolicy;->getZenPolicyPriorityCategoryState(I)I
 HSPLandroid/service/notification/ZenPolicy;->getZenPolicyVisualEffectState(I)I
 HSPLandroid/service/oemlock/IOemLockService$Stub;-><init>()V
+HPLandroid/service/oemlock/IOemLockService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/service/persistentdata/IPersistentDataBlockService$Stub;-><init>()V
-PLandroid/service/persistentdata/IPersistentDataBlockService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/service/persistentdata/IPersistentDataBlockService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLandroid/service/textclassifier/ITextClassifierCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/service/textclassifier/ITextClassifierCallback$Stub;-><init>()V
 HSPLandroid/service/textclassifier/ITextClassifierCallback$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/service/textclassifier/ITextClassifierCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/service/textclassifier/ITextClassifierService$Stub$Proxy;->onGenerateLinks(Landroid/view/textclassifier/TextClassificationSessionId;Landroid/view/textclassifier/TextLinks$Request;Landroid/service/textclassifier/ITextClassifierCallback;)V
 HPLandroid/service/textclassifier/ITextClassifierService$Stub$Proxy;->onSuggestConversationActions(Landroid/view/textclassifier/TextClassificationSessionId;Landroid/view/textclassifier/ConversationActions$Request;Landroid/service/textclassifier/ITextClassifierCallback;)V
 HPLandroid/service/textclassifier/ITextClassifierService$Stub$Proxy;->onTextClassifierEvent(Landroid/view/textclassifier/TextClassificationSessionId;Landroid/view/textclassifier/TextClassifierEvent;)V
 HSPLandroid/service/textclassifier/ITextClassifierService$Stub;-><init>()V
@@ -12917,7 +13435,7 @@
 PLandroid/service/trust/ITrustAgentServiceCallback$Stub;->asBinder()Landroid/os/IBinder;
 PLandroid/service/voice/IVoiceInteractionService$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 PLandroid/service/voice/IVoiceInteractionService$Stub$Proxy;->ready()V
-PLandroid/service/voice/IVoiceInteractionService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/voice/IVoiceInteractionService;
+HPLandroid/service/voice/IVoiceInteractionService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/voice/IVoiceInteractionService;
 PLandroid/service/voice/IVoiceInteractionSession$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 PLandroid/service/voice/IVoiceInteractionSession$Stub$Proxy;->closeSystemDialogs()V
 PLandroid/service/voice/IVoiceInteractionSession$Stub$Proxy;->handleAssist(Landroid/os/Bundle;Landroid/app/assist/AssistStructure;Landroid/app/assist/AssistContent;II)V
@@ -12927,7 +13445,7 @@
 PLandroid/service/voice/IVoiceInteractionSession$Stub$Proxy;->show(Landroid/os/Bundle;ILcom/android/internal/app/IVoiceInteractionSessionShowCallback;)V
 PLandroid/service/voice/IVoiceInteractionSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/voice/IVoiceInteractionSession;
 PLandroid/service/voice/IVoiceInteractionSessionService$Stub$Proxy;->newSession(Landroid/os/IBinder;Landroid/os/Bundle;I)V
-PLandroid/service/voice/IVoiceInteractionSessionService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/voice/IVoiceInteractionSessionService;
+HPLandroid/service/voice/IVoiceInteractionSessionService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/voice/IVoiceInteractionSessionService;
 HSPLandroid/service/voice/VoiceInteractionServiceInfo;-><init>(Landroid/content/pm/PackageManager;Landroid/content/ComponentName;I)V
 HSPLandroid/service/voice/VoiceInteractionServiceInfo;-><init>(Landroid/content/pm/PackageManager;Landroid/content/pm/ServiceInfo;)V
 HSPLandroid/service/voice/VoiceInteractionServiceInfo;->getParseError()Ljava/lang/String;
@@ -12977,12 +13495,13 @@
 HSPLandroid/system/Os;->chmod(Ljava/lang/String;I)V
 HSPLandroid/system/Os;->chown(Ljava/lang/String;II)V
 HSPLandroid/system/Os;->close(Ljava/io/FileDescriptor;)V
-PLandroid/system/Os;->dup(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;
+HPLandroid/system/Os;->dup(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;
 HSPLandroid/system/Os;->fchmod(Ljava/io/FileDescriptor;I)V
 HSPLandroid/system/Os;->fchown(Ljava/io/FileDescriptor;II)V
 HSPLandroid/system/Os;->fcntlInt(Ljava/io/FileDescriptor;II)I
+HSPLandroid/system/Os;->fdatasync(Ljava/io/FileDescriptor;)V
 HSPLandroid/system/Os;->fstat(Ljava/io/FileDescriptor;)Landroid/system/StructStat;
-PLandroid/system/Os;->fsync(Ljava/io/FileDescriptor;)V
+HPLandroid/system/Os;->fsync(Ljava/io/FileDescriptor;)V
 HSPLandroid/system/Os;->getenv(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/system/Os;->getgid()I
 HSPLandroid/system/Os;->getpeername(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;
@@ -13039,8 +13558,12 @@
 HSPLandroid/telecom/CallAudioState$1;-><init>()V
 HSPLandroid/telecom/CallAudioState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telecom/CallAudioState;
 HSPLandroid/telecom/CallAudioState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/telecom/CallAudioState;-><init>(Landroid/telecom/CallAudioState;)V
+HSPLandroid/telecom/CallAudioState;-><init>(ZII)V
 HSPLandroid/telecom/CallAudioState;->audioRouteToString(I)Ljava/lang/String;
 HSPLandroid/telecom/CallAudioState;->equals(Ljava/lang/Object;)Z
+HSPLandroid/telecom/CallAudioState;->getRoute()I
+HSPLandroid/telecom/CallAudioState;->getSupportedRouteMask()I
 HSPLandroid/telecom/CallAudioState;->toString()Ljava/lang/String;
 HPLandroid/telecom/CallAudioState;->writeToParcel(Landroid/os/Parcel;I)V
 PLandroid/telecom/Connection;->capabilitiesToString(I)Ljava/lang/String;
@@ -13054,15 +13577,33 @@
 PLandroid/telecom/ConnectionRequest$Builder;->build()Landroid/telecom/ConnectionRequest;
 PLandroid/telecom/ConnectionRequest;-><init>(Landroid/os/Parcel;)V
 PLandroid/telecom/ConnectionRequest;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/telecom/ConnectionService;-><init>()V
+HPLandroid/telecom/ConnectionService;->access$100(Landroid/telecom/ConnectionService;)Landroid/telecom/ConnectionServiceAdapter;
+HPLandroid/telecom/ConnectionService;->access$1900(Landroid/telecom/ConnectionService;Ljava/lang/String;Landroid/telecom/CallAudioState;)V
+HPLandroid/telecom/ConnectionService;->access$200(Landroid/telecom/ConnectionService;)V
+HPLandroid/telecom/ConnectionService;->access$300(Landroid/telecom/ConnectionService;)Z
+HPLandroid/telecom/ConnectionService;->access$500(Landroid/telecom/ConnectionService;)Ljava/util/List;
+HPLandroid/telecom/ConnectionService;->access$600(Landroid/telecom/ConnectionService;Ljava/lang/String;)V
+HPLandroid/telecom/ConnectionService;->addConnection(Landroid/telecom/PhoneAccountHandle;Ljava/lang/String;Landroid/telecom/Connection;)V
+HPLandroid/telecom/ConnectionService;->createConnection(Landroid/telecom/PhoneAccountHandle;Ljava/lang/String;Landroid/telecom/ConnectionRequest;ZZ)V
+HPLandroid/telecom/ConnectionService;->createIdList(Ljava/util/List;)Ljava/util/List;
+HPLandroid/telecom/ConnectionService;->endAllConnections()V
+HPLandroid/telecom/ConnectionService;->findConnectionForAction(Ljava/lang/String;Ljava/lang/String;)Landroid/telecom/Connection;
+HPLandroid/telecom/ConnectionService;->getAllConnections()Ljava/util/Collection;
+HPLandroid/telecom/ConnectionService;->notifyCreateConnectionComplete(Ljava/lang/String;)V
+HPLandroid/telecom/ConnectionService;->onBind(Landroid/content/Intent;)Landroid/os/IBinder;
+HPLandroid/telecom/ConnectionService;->onCallAudioStateChanged(Ljava/lang/String;Landroid/telecom/CallAudioState;)V
+HPLandroid/telecom/ConnectionService;->onUnbind(Landroid/content/Intent;)Z
+HPLandroid/telecom/ConnectionService;->removeConnection(Landroid/telecom/Connection;)V
 HSPLandroid/telecom/DefaultDialerManager;->getDefaultDialerApplication(Landroid/content/Context;I)Ljava/lang/String;
 HSPLandroid/telecom/DisconnectCause$1;-><init>()V
 HSPLandroid/telecom/DisconnectCause$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telecom/DisconnectCause;
 HSPLandroid/telecom/DisconnectCause$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/telecom/DisconnectCause;-><init>(I)V
 HPLandroid/telecom/DisconnectCause;->toString()Ljava/lang/String;
-PLandroid/telecom/Log;->addEvent(Landroid/telecom/Logging/EventManager$Loggable;Ljava/lang/String;)V
+HPLandroid/telecom/Log;->addEvent(Landroid/telecom/Logging/EventManager$Loggable;Ljava/lang/String;)V
 HSPLandroid/telecom/Log;->addEvent(Landroid/telecom/Logging/EventManager$Loggable;Ljava/lang/String;Ljava/lang/Object;)V
-PLandroid/telecom/Log;->addEvent(Landroid/telecom/Logging/EventManager$Loggable;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+HPLandroid/telecom/Log;->addEvent(Landroid/telecom/Logging/EventManager$Loggable;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
 HSPLandroid/telecom/Log;->addRequestResponsePair(Landroid/telecom/Logging/EventManager$TimedEventPair;)V
 HSPLandroid/telecom/Log;->buildMessage(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
 HSPLandroid/telecom/Log;->continueSession(Landroid/telecom/Logging/Session;Ljava/lang/String;)V
@@ -13071,7 +13612,7 @@
 HSPLandroid/telecom/Log;->d(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
 HSPLandroid/telecom/Log;->endSession()V
 HSPLandroid/telecom/Log;->getEventManager()Landroid/telecom/Logging/EventManager;
-PLandroid/telecom/Log;->getExternalSession()Landroid/telecom/Logging/Session$Info;
+HPLandroid/telecom/Log;->getExternalSession()Landroid/telecom/Logging/Session$Info;
 HSPLandroid/telecom/Log;->getSessionId()Ljava/lang/String;
 HSPLandroid/telecom/Log;->getSessionManager()Landroid/telecom/Logging/SessionManager;
 HSPLandroid/telecom/Log;->i(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V
@@ -13086,8 +13627,9 @@
 HSPLandroid/telecom/Log;->setTag(Ljava/lang/String;)V
 HPLandroid/telecom/Log;->startSession(Landroid/telecom/Logging/Session$Info;Ljava/lang/String;)V
 HSPLandroid/telecom/Log;->startSession(Ljava/lang/String;)V
+HPLandroid/telecom/Log;->startSession(Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/telecom/Log;->v(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V
-PLandroid/telecom/Log;->w(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V
+HPLandroid/telecom/Log;->w(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V
 HSPLandroid/telecom/Logging/-$$Lambda$L5F_SL2jOCUETYvgdB36aGwY50E;-><init>()V
 HSPLandroid/telecom/Logging/-$$Lambda$L5F_SL2jOCUETYvgdB36aGwY50E;->get()I
 HPLandroid/telecom/Logging/-$$Lambda$SessionManager$VyH2gT1EjIvzDy_C9JfTT60CISM;->run()V
@@ -13188,6 +13730,7 @@
 HSPLandroid/telecom/PhoneAccount;->capabilitiesToString()Ljava/lang/String;
 HSPLandroid/telecom/PhoneAccount;->equals(Ljava/lang/Object;)Z
 HSPLandroid/telecom/PhoneAccount;->getAccountHandle()Landroid/telecom/PhoneAccountHandle;
+HSPLandroid/telecom/PhoneAccount;->getExtras()Landroid/os/Bundle;
 HSPLandroid/telecom/PhoneAccount;->hasCapabilities(I)Z
 HSPLandroid/telecom/PhoneAccount;->supportsUriScheme(Ljava/lang/String;)Z
 HSPLandroid/telecom/PhoneAccount;->toString()Ljava/lang/String;
@@ -13207,6 +13750,7 @@
 HSPLandroid/telecom/PhoneAccountHandle;->writeToParcel(Landroid/os/Parcel;I)V
 PLandroid/telecom/TelecomAnalytics$SessionTiming$1;-><init>()V
 HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;)V
+HPLandroid/telecom/TelecomManager;->addNewIncomingCall(Landroid/telecom/PhoneAccountHandle;Landroid/os/Bundle;)V
 HSPLandroid/telecom/TelecomManager;->from(Landroid/content/Context;)Landroid/telecom/TelecomManager;
 HSPLandroid/telecom/TelecomManager;->getCallCapablePhoneAccounts()Ljava/util/List;
 HSPLandroid/telecom/TelecomManager;->getCallCapablePhoneAccounts(Z)Ljava/util/List;
@@ -13221,6 +13765,7 @@
 HSPLandroid/telecom/TelecomManager;->getUserSelectedOutgoingPhoneAccount()Landroid/telecom/PhoneAccountHandle;
 HSPLandroid/telecom/TelecomManager;->isInCall()Z
 HSPLandroid/telecom/TelecomManager;->isRinging()Z
+HSPLandroid/telecom/TelecomManager;->isVoiceMailNumber(Landroid/telecom/PhoneAccountHandle;Ljava/lang/String;)Z
 HSPLandroid/telecom/TelecomManager;->registerPhoneAccount(Landroid/telecom/PhoneAccount;)V
 HSPLandroid/telecom/TelecomManager;->unregisterPhoneAccount(Landroid/telecom/PhoneAccountHandle;)V
 HSPLandroid/telecom/VideoProfile$1;-><init>()V
@@ -13260,13 +13805,14 @@
 HSPLandroid/telephony/CallAttributes$1;-><init>()V
 HPLandroid/telephony/CallAttributes;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/telephony/CallQuality$1;-><init>()V
+HPLandroid/telephony/CallQuality;->toString()Ljava/lang/String;
 HPLandroid/telephony/CallQuality;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/telephony/CarrierConfigManager$Gps;->access$000()Landroid/os/PersistableBundle;
 HSPLandroid/telephony/CarrierConfigManager$Gps;->getDefaults()Landroid/os/PersistableBundle;
 HSPLandroid/telephony/CarrierConfigManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/telephony/CarrierConfigManager;->getConfig()Landroid/os/PersistableBundle;
 HSPLandroid/telephony/CarrierConfigManager;->getConfigForSubId(I)Landroid/os/PersistableBundle;
-PLandroid/telephony/CarrierConfigManager;->getDefaultCarrierServicePackageName()Ljava/lang/String;
+HPLandroid/telephony/CarrierConfigManager;->getDefaultCarrierServicePackageName()Ljava/lang/String;
 HSPLandroid/telephony/CarrierConfigManager;->getDefaultConfig()Landroid/os/PersistableBundle;
 HSPLandroid/telephony/CarrierConfigManager;->isConfigForIdentifiedCarrier(Landroid/os/PersistableBundle;)Z
 HSPLandroid/telephony/CarrierConfigManager;->updateConfigForPhoneId(ILjava/lang/String;)V
@@ -13346,6 +13892,7 @@
 HSPLandroid/telephony/CellSignalStrengthGsm;-><init>(III)V
 HSPLandroid/telephony/CellSignalStrengthGsm;->describeContents()I
 HSPLandroid/telephony/CellSignalStrengthGsm;->equals(Ljava/lang/Object;)Z
+HSPLandroid/telephony/CellSignalStrengthGsm;->getLevel()I
 HSPLandroid/telephony/CellSignalStrengthGsm;->toString()Ljava/lang/String;
 HSPLandroid/telephony/CellSignalStrengthGsm;->updateLevel(Landroid/os/PersistableBundle;Landroid/telephony/ServiceState;)V
 HSPLandroid/telephony/CellSignalStrengthLte$1;-><init>()V
@@ -13392,6 +13939,7 @@
 HSPLandroid/telephony/CellSignalStrengthWcdma;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/telephony/CellSignalStrengthWcdma;->describeContents()I
 HSPLandroid/telephony/CellSignalStrengthWcdma;->equals(Ljava/lang/Object;)Z
+HPLandroid/telephony/CellSignalStrengthWcdma;->getDbm()I
 HSPLandroid/telephony/CellSignalStrengthWcdma;->getLevel()I
 HSPLandroid/telephony/CellSignalStrengthWcdma;->toString()Ljava/lang/String;
 HSPLandroid/telephony/CellSignalStrengthWcdma;->updateLevel(Landroid/os/PersistableBundle;Landroid/telephony/ServiceState;)V
@@ -13497,12 +14045,15 @@
 HSPLandroid/telephony/PhoneCapability;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/telephony/PhoneNumberUtils;->bcdToChar(BI)C
 HSPLandroid/telephony/PhoneNumberUtils;->calledPartyBCDToString([BIII)Ljava/lang/String;
+HSPLandroid/telephony/PhoneNumberUtils;->compare(Ljava/lang/String;Ljava/lang/String;)Z
 HSPLandroid/telephony/PhoneNumberUtils;->compareLoosely(Ljava/lang/String;Ljava/lang/String;)Z
 HSPLandroid/telephony/PhoneNumberUtils;->convertKeypadLettersToDigits(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/telephony/PhoneNumberUtils;->createTtsSpan(Ljava/lang/String;)Landroid/text/style/TtsSpan;
+HSPLandroid/telephony/PhoneNumberUtils;->createTtsSpannable(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
 HSPLandroid/telephony/PhoneNumberUtils;->extractNetworkPortion(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/telephony/PhoneNumberUtils;->extractNetworkPortionAlt(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/telephony/PhoneNumberUtils;->extractPostDialPortion(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/telephony/PhoneNumberUtils;->formatNumber(Landroid/text/Editable;I)V
 HSPLandroid/telephony/PhoneNumberUtils;->formatNumber(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/telephony/PhoneNumberUtils;->formatNumber(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/telephony/PhoneNumberUtils;->formatNumberInternal(Ljava/lang/String;Ljava/lang/String;Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;)Ljava/lang/String;
@@ -13514,10 +14065,13 @@
 HSPLandroid/telephony/PhoneNumberUtils;->isLocalEmergencyNumber(Landroid/content/Context;Ljava/lang/String;)Z
 HSPLandroid/telephony/PhoneNumberUtils;->isLocalEmergencyNumberInternal(ILjava/lang/String;Landroid/content/Context;Z)Z
 HSPLandroid/telephony/PhoneNumberUtils;->isNonSeparator(C)Z
-PLandroid/telephony/PhoneNumberUtils;->isUriNumber(Ljava/lang/String;)Z
-PLandroid/telephony/PhoneNumberUtils;->isVoiceMailNumber(Landroid/content/Context;ILjava/lang/String;)Z
+HPLandroid/telephony/PhoneNumberUtils;->isUriNumber(Ljava/lang/String;)Z
+HPLandroid/telephony/PhoneNumberUtils;->isVoiceMailNumber(Landroid/content/Context;ILjava/lang/String;)Z
 HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/telephony/PhoneNumberUtils;->splitAtNonNumerics(Ljava/lang/CharSequence;)Ljava/lang/String;
+HPLandroid/telephony/PhoneNumberUtils;->stringFromStringAndTOA(Ljava/lang/String;I)Ljava/lang/String;
 HSPLandroid/telephony/PhoneNumberUtils;->stripSeparators(Ljava/lang/String;)Ljava/lang/String;
+HPLandroid/telephony/PhoneNumberUtils;->toaFromString(Ljava/lang/String;)I
 HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->lambda$onCallForwardingIndicatorChanged$7$PhoneStateListener$IPhoneStateListenerStub(Landroid/telephony/PhoneStateListener;Z)V
 HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->lambda$onCallStateChanged$11$PhoneStateListener$IPhoneStateListenerStub(Landroid/telephony/PhoneStateListener;ILjava/lang/String;)V
 HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->lambda$onCellInfoChanged$21$PhoneStateListener$IPhoneStateListenerStub(Landroid/telephony/PhoneStateListener;Ljava/util/List;)V
@@ -13678,11 +14232,14 @@
 HPLandroid/telephony/SignalStrength;->getCellSignalStrengths(Ljava/lang/Class;)Ljava/util/List;
 HSPLandroid/telephony/SignalStrength;->getLevel()I
 HSPLandroid/telephony/SignalStrength;->getPrimary()Landroid/telephony/CellSignalStrength;
+HSPLandroid/telephony/SignalStrength;->isGsm()Z
 HSPLandroid/telephony/SignalStrength;->toString()Ljava/lang/String;
 HSPLandroid/telephony/SignalStrength;->updateLevel(Landroid/os/PersistableBundle;Landroid/telephony/ServiceState;)V
 HSPLandroid/telephony/SignalStrength;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/telephony/SmsManager;-><init>(I)V
+HPLandroid/telephony/SmsManager;->getAutoPersisting()Z
 HSPLandroid/telephony/SmsManager;->getDefault()Landroid/telephony/SmsManager;
+HSPLandroid/telephony/SmsManager;->getMmsConfig(Landroid/os/BaseBundle;)Landroid/os/Bundle;
 PLandroid/telephony/SmsMessage;->createFromPdu([BLjava/lang/String;)Landroid/telephony/SmsMessage;
 HSPLandroid/telephony/SmsMessage;->createFromPdu([BLjava/lang/String;Z)Landroid/telephony/SmsMessage;
 HSPLandroid/telephony/SubscriptionInfo$1;-><init>()V
@@ -13690,6 +14247,7 @@
 HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionInfo;-><init>(ILjava/lang/String;ILjava/lang/CharSequence;Ljava/lang/CharSequence;IILjava/lang/String;ILandroid/graphics/Bitmap;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z[Landroid/telephony/UiccAccessRule;Ljava/lang/String;IZLjava/lang/String;ZIII)V
 HSPLandroid/telephony/SubscriptionInfo;->getCarrierId()I
+HSPLandroid/telephony/SubscriptionInfo;->getCarrierName()Ljava/lang/CharSequence;
 HSPLandroid/telephony/SubscriptionInfo;->getCountryIso()Ljava/lang/String;
 HSPLandroid/telephony/SubscriptionInfo;->getDisplayName()Ljava/lang/CharSequence;
 HSPLandroid/telephony/SubscriptionInfo;->getGroupUuid()Landroid/os/ParcelUuid;
@@ -13720,7 +14278,9 @@
 HSPLandroid/telephony/SubscriptionManager;->getActiveSubscriptionInfoForSimSlotIndex(I)Landroid/telephony/SubscriptionInfo;
 HSPLandroid/telephony/SubscriptionManager;->getActiveSubscriptionInfoList()Ljava/util/List;
 HSPLandroid/telephony/SubscriptionManager;->getActiveSubscriptionInfoList(Z)Ljava/util/List;
+HSPLandroid/telephony/SubscriptionManager;->getDefaultDataPhoneId()I
 HSPLandroid/telephony/SubscriptionManager;->getDefaultDataSubscriptionId()I
+HSPLandroid/telephony/SubscriptionManager;->getDefaultDataSubscriptionInfo()Landroid/telephony/SubscriptionInfo;
 HSPLandroid/telephony/SubscriptionManager;->getDefaultSmsSubscriptionId()I
 HSPLandroid/telephony/SubscriptionManager;->getDefaultSubscriptionId()I
 HSPLandroid/telephony/SubscriptionManager;->getDefaultVoicePhoneId()I
@@ -13751,10 +14311,10 @@
 HSPLandroid/telephony/SubscriptionPlan$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/telephony/TelephonyHistogram$1;-><init>()V
 HSPLandroid/telephony/TelephonyHistogram;-><init>(III)V
-PLandroid/telephony/TelephonyHistogram;-><init>(Landroid/telephony/TelephonyHistogram;)V
+HPLandroid/telephony/TelephonyHistogram;-><init>(Landroid/telephony/TelephonyHistogram;)V
 HSPLandroid/telephony/TelephonyHistogram;->addTimeTaken(I)V
-PLandroid/telephony/TelephonyHistogram;->getBucketCounters()[I
-PLandroid/telephony/TelephonyHistogram;->getBucketEndPoints()[I
+HPLandroid/telephony/TelephonyHistogram;->getBucketCounters()[I
+HPLandroid/telephony/TelephonyHistogram;->getBucketEndPoints()[I
 HSPLandroid/telephony/TelephonyManager$MultiSimVariants;-><init>(Ljava/lang/String;I)V
 HSPLandroid/telephony/TelephonyManager$MultiSimVariants;->values()[Landroid/telephony/TelephonyManager$MultiSimVariants;
 HSPLandroid/telephony/TelephonyManager;-><init>()V
@@ -13766,6 +14326,7 @@
 HSPLandroid/telephony/TelephonyManager;->createForSubscriptionId(I)Landroid/telephony/TelephonyManager;
 HSPLandroid/telephony/TelephonyManager;->enableIms(I)V
 HSPLandroid/telephony/TelephonyManager;->from(Landroid/content/Context;)Landroid/telephony/TelephonyManager;
+HPLandroid/telephony/TelephonyManager;->getActiveVisualVoicemailSmsFilterSettings(I)Landroid/telephony/VisualVoicemailSmsFilterSettings;
 HSPLandroid/telephony/TelephonyManager;->getAllCellInfo()Ljava/util/List;
 HSPLandroid/telephony/TelephonyManager;->getCallState()I
 HSPLandroid/telephony/TelephonyManager;->getCardIdForDefaultEuicc()I
@@ -13790,6 +14351,7 @@
 HSPLandroid/telephony/TelephonyManager;->getImsConfig(II)Landroid/telephony/ims/aidl/IImsConfig;
 HSPLandroid/telephony/TelephonyManager;->getImsMmTelFeatureAndListen(ILcom/android/ims/internal/IImsServiceFeatureCallback;)Landroid/telephony/ims/aidl/IImsMmTelFeature;
 HSPLandroid/telephony/TelephonyManager;->getImsRegistration(II)Landroid/telephony/ims/aidl/IImsRegistration;
+HSPLandroid/telephony/TelephonyManager;->getIsimIst()Ljava/lang/String;
 HSPLandroid/telephony/TelephonyManager;->getLine1Number()Ljava/lang/String;
 HSPLandroid/telephony/TelephonyManager;->getLine1Number(I)Ljava/lang/String;
 HSPLandroid/telephony/TelephonyManager;->getMergedSubscriberIds()[Ljava/lang/String;
@@ -13841,6 +14403,7 @@
 HSPLandroid/telephony/TelephonyManager;->getUiccCardsInfo()Ljava/util/List;
 HSPLandroid/telephony/TelephonyManager;->getVisualVoicemailPackageName()Ljava/lang/String;
 HSPLandroid/telephony/TelephonyManager;->getVoiceMailNumber(I)Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getVoiceNetworkType()I
 HSPLandroid/telephony/TelephonyManager;->getVoiceNetworkType(I)I
 HSPLandroid/telephony/TelephonyManager;->getVtDataUsage(I)Landroid/net/NetworkStats;
 HSPLandroid/telephony/TelephonyManager;->isDataCapable()Z
@@ -13991,6 +14554,7 @@
 HSPLandroid/telephony/euicc/EuiccManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/telephony/euicc/EuiccManager;->isEnabled()Z
 HSPLandroid/telephony/gsm/GsmCellLocation;->fillInNotifierBundle(Landroid/os/Bundle;)V
+HSPLandroid/telephony/gsm/GsmCellLocation;->getCid()I
 HSPLandroid/telephony/ims/-$$Lambda$ImsMmTelManager$CapabilityCallback$CapabilityBinder$4YNlUy9HsD02E7Sbv2VeVtbao08;->run()V
 HSPLandroid/telephony/ims/-$$Lambda$ImsMmTelManager$CapabilityCallback$CapabilityBinder$gK2iK9ZQ3GDeuMTfhRd7yjiYlO8;->runOrThrow()V
 HSPLandroid/telephony/ims/-$$Lambda$ImsMmTelManager$RegistrationCallback$RegistrationBinder$8xq93ap6i0L56Aegaj-ZEUt9ISc;->runOrThrow()V
@@ -14057,6 +14621,7 @@
 HSPLandroid/telephony/ims/aidl/IImsCapabilityCallback$Stub;-><init>()V
 HSPLandroid/telephony/ims/aidl/IImsCapabilityCallback$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/telephony/ims/aidl/IImsConfig$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/telephony/ims/aidl/IImsConfig$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/ims/aidl/IImsConfig;
 HSPLandroid/telephony/ims/aidl/IImsConfig$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/telephony/ims/aidl/IImsConfigCallback$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/telephony/ims/aidl/IImsMmTelFeature$Stub$Proxy;->asBinder()Landroid/os/IBinder;
@@ -14072,6 +14637,7 @@
 HSPLandroid/telephony/ims/aidl/IImsRegistrationCallback$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/telephony/ims/aidl/IImsRegistrationCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/ims/aidl/IImsRegistrationCallback;
 HSPLandroid/telephony/ims/aidl/IImsServiceController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/ims/aidl/IImsServiceController;
+HSPLandroid/telephony/ims/aidl/IImsServiceControllerListener$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/telephony/ims/aidl/IImsSmsListener$Stub;-><init>()V
 HSPLandroid/telephony/ims/aidl/IRcs$Stub;-><init>()V
 HSPLandroid/telephony/ims/feature/CapabilityChangeRequest$1;-><init>()V
@@ -14111,7 +14677,9 @@
 HSPLandroid/telephony/ims/feature/MmTelFeature$Listener;-><init>()V
 HSPLandroid/telephony/ims/feature/MmTelFeature$MmTelCapabilities;-><init>()V
 HSPLandroid/telephony/ims/feature/MmTelFeature$MmTelCapabilities;-><init>(Landroid/telephony/ims/feature/ImsFeature$Capabilities;)V
+HSPLandroid/telephony/ims/feature/MmTelFeature$MmTelCapabilities;->addCapabilities(I)V
 HSPLandroid/telephony/ims/feature/MmTelFeature$MmTelCapabilities;->isCapable(I)Z
+HSPLandroid/telephony/ims/feature/MmTelFeature$MmTelCapabilities;->removeCapabilities(I)V
 HSPLandroid/telephony/ims/feature/MmTelFeature$MmTelCapabilities;->toString()Ljava/lang/String;
 HSPLandroid/telephony/ims/feature/MmTelFeature;-><init>()V
 HSPLandroid/telephony/ims/feature/MmTelFeature;->getEcbmInterface()Lcom/android/ims/internal/IImsEcbm;
@@ -14127,6 +14695,7 @@
 HSPLandroid/telephony/ims/stub/-$$Lambda$ImsRegistrationImplBase$sbjuTvW-brOSWMR74UInSZEIQB0;->accept(Ljava/lang/Object;)V
 HSPLandroid/telephony/ims/stub/-$$Lambda$ImsRegistrationImplBase$wwtkoeOtGwMjG5I0-ZTfjNpGU-s;->accept(Ljava/lang/Object;)V
 HSPLandroid/telephony/ims/stub/ImsConfigImplBase$ImsConfigStub;->addImsConfigCallback(Landroid/telephony/ims/aidl/IImsConfigCallback;)V
+HPLandroid/telephony/ims/stub/ImsConfigImplBase$ImsConfigStub;->getConfigInt(I)I
 HSPLandroid/telephony/ims/stub/ImsConfigImplBase$ImsConfigStub;->getImsConfigImpl()Landroid/telephony/ims/stub/ImsConfigImplBase;
 HSPLandroid/telephony/ims/stub/ImsConfigImplBase$ImsConfigStub;->notifyImsConfigChanged(II)V
 HSPLandroid/telephony/ims/stub/ImsConfigImplBase$ImsConfigStub;->setConfigInt(II)I
@@ -14139,6 +14708,8 @@
 HSPLandroid/telephony/ims/stub/ImsEcbmImplBase;->getImsEcbm()Lcom/android/ims/internal/IImsEcbm;
 HSPLandroid/telephony/ims/stub/ImsFeatureConfiguration$FeatureSlotPair;->hashCode()I
 HSPLandroid/telephony/ims/stub/ImsFeatureConfiguration$FeatureSlotPair;->toString()Ljava/lang/String;
+HSPLandroid/telephony/ims/stub/ImsFeatureConfiguration;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/ims/stub/ImsFeatureConfiguration;->getServiceFeatures()Ljava/util/Set;
 HSPLandroid/telephony/ims/stub/ImsMultiEndpointImplBase$1;->setListener(Lcom/android/ims/internal/IImsExternalCallStateListener;)V
 HSPLandroid/telephony/ims/stub/ImsMultiEndpointImplBase;-><init>()V
 HSPLandroid/telephony/ims/stub/ImsMultiEndpointImplBase;->getIImsMultiEndpoint()Lcom/android/ims/internal/IImsMultiEndpoint;
@@ -14302,6 +14873,7 @@
 HSPLandroid/text/Layout;->getEndHyphenEdit(I)I
 HSPLandroid/text/Layout;->getHeight()I
 HSPLandroid/text/Layout;->getHeight(Z)I
+HSPLandroid/text/Layout;->getHorizontal(IZ)F
 HSPLandroid/text/Layout;->getHorizontal(IZIZ)F
 HSPLandroid/text/Layout;->getIndentAdjust(ILandroid/text/Layout$Alignment;)I
 HSPLandroid/text/Layout;->getLineBaseline(I)I
@@ -14320,6 +14892,8 @@
 HSPLandroid/text/Layout;->getLineVisibleEnd(I)I
 HSPLandroid/text/Layout;->getLineVisibleEnd(III)I
 HSPLandroid/text/Layout;->getLineWidth(I)F
+HSPLandroid/text/Layout;->getOffsetForHorizontal(IF)I
+HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I
 HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;
 HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I
 HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;
@@ -14335,6 +14909,7 @@
 HSPLandroid/text/Layout;->shouldClampCursor(I)Z
 HSPLandroid/text/MeasuredParagraph;-><init>()V
 HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;[Landroid/text/style/MetricAffectingSpan;IILandroid/graphics/text/MeasuredText$Builder;)V
+HSPLandroid/text/MeasuredParagraph;->applyReplacementRun(Landroid/text/style/ReplacementSpan;IILandroid/graphics/text/MeasuredText$Builder;)V
 HSPLandroid/text/MeasuredParagraph;->applyStyleRun(IILandroid/graphics/text/MeasuredText$Builder;)V
 HSPLandroid/text/MeasuredParagraph;->breakText(IZF)I
 HSPLandroid/text/MeasuredParagraph;->buildForBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
@@ -14401,6 +14976,7 @@
 HSPLandroid/text/SpannableStringBuilder;-><init>()V
 HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V
 HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;II)V
+HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/Editable;
 HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->calcMax(I)I
@@ -14459,9 +15035,11 @@
 HSPLandroid/text/SpannableStringInternal;->length()I
 HSPLandroid/text/SpannableStringInternal;->nextSpanTransition(IILjava/lang/Class;)I
 HSPLandroid/text/SpannableStringInternal;->removeSpan(Ljava/lang/Object;I)V
+HSPLandroid/text/SpannableStringInternal;->sendSpanChanged(Ljava/lang/Object;IIII)V
 HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V
 HSPLandroid/text/SpannableStringInternal;->toString()Ljava/lang/String;
 HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;)V
+HSPLandroid/text/SpannedString;->equals(Ljava/lang/Object;)Z
 HSPLandroid/text/SpannedString;->getSpanEnd(Ljava/lang/Object;)I
 HSPLandroid/text/SpannedString;->getSpanFlags(Ljava/lang/Object;)I
 HSPLandroid/text/SpannedString;->getSpanStart(Ljava/lang/Object;)I
@@ -14521,6 +15099,7 @@
 HSPLandroid/text/TextLine;-><init>()V
 HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V
 HSPLandroid/text/TextLine;->drawRun(Landroid/graphics/Canvas;IIZFIIIZ)F
+HSPLandroid/text/TextLine;->drawStroke(Landroid/text/TextPaint;Landroid/graphics/Canvas;IFFFFF)V
 HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V
 HSPLandroid/text/TextLine;->equalAttributes(Landroid/text/TextPaint;Landroid/text/TextPaint;)Z
 HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V
@@ -14539,6 +15118,7 @@
 HSPLandroid/text/TextPaint;-><init>()V
 HSPLandroid/text/TextPaint;-><init>(I)V
 HSPLandroid/text/TextPaint;-><init>(Landroid/graphics/Paint;)V
+HSPLandroid/text/TextPaint;->getUnderlineThickness()F
 HSPLandroid/text/TextPaint;->set(Landroid/text/TextPaint;)V
 HSPLandroid/text/TextPaint;->setUnderlineText(IF)V
 HSPLandroid/text/TextUtils$1;-><init>()V
@@ -14553,6 +15133,7 @@
 HSPLandroid/text/TextUtils$StringWithRemovedChars;->toString()Ljava/lang/String;
 HSPLandroid/text/TextUtils$TruncateAt;-><init>(Ljava/lang/String;I)V
 HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/text/TextUtils;->copySpansFrom(Landroid/text/Spanned;IILjava/lang/Class;Landroid/text/Spannable;I)V
 HSPLandroid/text/TextUtils;->couldAffectRtl(C)Z
 HSPLandroid/text/TextUtils;->delimitedStringContains(Ljava/lang/String;CLjava/lang/String;)Z
 HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;)Ljava/lang/CharSequence;
@@ -14586,10 +15167,12 @@
 HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V
 HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;J)Ljava/lang/CharSequence;
 HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Calendar;)Ljava/lang/CharSequence;
+HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Date;)Ljava/lang/CharSequence;
 HSPLandroid/text/format/DateFormat;->getBestDateTimePattern(Ljava/util/Locale;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/text/format/DateFormat;->getDayOfWeekString(Llibcore/icu/LocaleData;III)Ljava/lang/String;
 HSPLandroid/text/format/DateFormat;->getMonthString(Llibcore/icu/LocaleData;III)Ljava/lang/String;
 HSPLandroid/text/format/DateFormat;->getTimeFormat(Landroid/content/Context;)Ljava/text/DateFormat;
+HSPLandroid/text/format/DateFormat;->getTimeFormatString(Landroid/content/Context;)Ljava/lang/String;
 HSPLandroid/text/format/DateFormat;->hasDesignator(Ljava/lang/CharSequence;C)Z
 HSPLandroid/text/format/DateFormat;->is24HourFormat(Landroid/content/Context;)Z
 HSPLandroid/text/format/DateFormat;->is24HourFormat(Landroid/content/Context;I)Z
@@ -14612,6 +15195,7 @@
 HSPLandroid/text/format/Time;-><init>()V
 HSPLandroid/text/format/Time;-><init>(Ljava/lang/String;)V
 HSPLandroid/text/format/Time;->format(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/text/format/Time;->getJulianDay(JJ)I
 HSPLandroid/text/format/Time;->set(J)V
 HSPLandroid/text/format/Time;->setToNow()V
 HSPLandroid/text/format/Time;->toMillis(Z)J
@@ -14651,9 +15235,11 @@
 HSPLandroid/text/method/TextKeyListener;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
 HSPLandroid/text/method/TextKeyListener;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
 HSPLandroid/text/method/WordIterator;->checkOffsetIsValid(I)V
+HSPLandroid/text/method/WordIterator;->following(I)I
 HSPLandroid/text/method/WordIterator;->getBeginning(I)I
 HSPLandroid/text/method/WordIterator;->getBeginning(IZ)I
 HSPLandroid/text/method/WordIterator;->setCharSequence(Ljava/lang/CharSequence;II)V
+HSPLandroid/text/style/BackgroundColorSpan;-><init>(I)V
 HSPLandroid/text/style/CharacterStyle;->getUnderlying()Landroid/text/style/CharacterStyle;
 HSPLandroid/text/style/DynamicDrawableSpan;->getSize(Landroid/graphics/Paint;Ljava/lang/CharSequence;IILandroid/graphics/Paint$FontMetricsInt;)I
 HSPLandroid/text/style/ForegroundColorSpan;-><init>(I)V
@@ -14667,8 +15253,10 @@
 HSPLandroid/text/style/StyleSpan;->apply(Landroid/graphics/Paint;I)V
 HSPLandroid/text/style/StyleSpan;->getSpanTypeIdInternal()I
 HSPLandroid/text/style/StyleSpan;->updateDrawState(Landroid/text/TextPaint;)V
+HSPLandroid/text/style/StyleSpan;->updateMeasureState(Landroid/text/TextPaint;)V
 HSPLandroid/text/style/StyleSpan;->writeToParcelInternal(Landroid/os/Parcel;I)V
 HSPLandroid/text/style/SuggestionSpan$1;-><init>()V
+HSPLandroid/text/style/SuggestionSpan;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/text/style/TextAppearanceSpan;-><init>(Landroid/content/Context;I)V
 HSPLandroid/text/style/TextAppearanceSpan;-><init>(Landroid/content/Context;II)V
 HSPLandroid/text/style/TextAppearanceSpan;-><init>(Landroid/os/Parcel;)V
@@ -14677,6 +15265,9 @@
 HSPLandroid/text/style/TtsSpan;->getSpanTypeIdInternal()I
 HSPLandroid/text/style/TtsSpan;->writeToParcelInternal(Landroid/os/Parcel;I)V
 HSPLandroid/text/style/UnderlineSpan;-><init>()V
+HSPLandroid/text/style/UnderlineSpan;->getSpanTypeIdInternal()I
+HSPLandroid/text/style/UnderlineSpan;->updateDrawState(Landroid/text/TextPaint;)V
+HSPLandroid/text/style/UnderlineSpan;->writeToParcelInternal(Landroid/os/Parcel;I)V
 HSPLandroid/transition/AutoTransition;-><init>()V
 HSPLandroid/transition/ChangeBounds$1;-><init>(Ljava/lang/Class;Ljava/lang/String;)V
 HSPLandroid/transition/ChangeBounds$2;-><init>(Ljava/lang/Class;Ljava/lang/String;)V
@@ -14697,6 +15288,7 @@
 HSPLandroid/transition/TransitionInflater;->from(Landroid/content/Context;)Landroid/transition/TransitionInflater;
 HSPLandroid/transition/TransitionInflater;->inflateTransition(I)Landroid/transition/Transition;
 HSPLandroid/transition/TransitionManager;-><init>()V
+HSPLandroid/transition/TransitionManager;->beginDelayedTransition(Landroid/view/ViewGroup;)V
 HSPLandroid/transition/TransitionManager;->beginDelayedTransition(Landroid/view/ViewGroup;Landroid/transition/Transition;)V
 HSPLandroid/transition/TransitionManager;->getRunningTransitions()Landroid/util/ArrayMap;
 HSPLandroid/transition/TransitionSet;-><init>()V
@@ -14741,7 +15333,7 @@
 HSPLandroid/util/ArrayMap;->putAll(Ljava/util/Map;)V
 HSPLandroid/util/ArrayMap;->remove(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/ArrayMap;->removeAt(I)Ljava/lang/Object;
-PLandroid/util/ArrayMap;->setValueAt(ILjava/lang/Object;)Ljava/lang/Object;
+HPLandroid/util/ArrayMap;->setValueAt(ILjava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/ArrayMap;->size()I
 HSPLandroid/util/ArrayMap;->toString()Ljava/lang/String;
 HSPLandroid/util/ArrayMap;->validate()V
@@ -14813,6 +15405,7 @@
 HSPLandroid/util/DataUnit$5;->toBytes(J)J
 HSPLandroid/util/DataUnit$6;-><init>(Ljava/lang/String;I)V
 HSPLandroid/util/DataUnit$6;->toBytes(J)J
+HSPLandroid/util/DebugUtils;->buildShortClassTag(Ljava/lang/Object;Ljava/lang/StringBuilder;)V
 HSPLandroid/util/DebugUtils;->flagsToString(Ljava/lang/Class;Ljava/lang/String;I)Ljava/lang/String;
 HSPLandroid/util/DebugUtils;->valueToString(Ljava/lang/Class;Ljava/lang/String;I)Ljava/lang/String;
 HSPLandroid/util/DisplayMetrics;-><init>()V
@@ -14825,7 +15418,7 @@
 HPLandroid/util/EventLog$Event;->getUid()I
 HSPLandroid/util/EventLog;->getTagCode(Ljava/lang/String;)I
 HSPLandroid/util/EventLog;->readTagsFile()V
-PLandroid/util/ExceptionUtils;->propagate(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;
+HPLandroid/util/ExceptionUtils;->propagate(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;
 HSPLandroid/util/FastImmutableArraySet$FastIterator;->hasNext()Z
 HSPLandroid/util/FastImmutableArraySet$FastIterator;->next()Ljava/lang/Object;
 HSPLandroid/util/FastImmutableArraySet;->iterator()Ljava/util/Iterator;
@@ -14856,8 +15449,10 @@
 HSPLandroid/util/JsonReader;->expect(Landroid/util/JsonToken;)V
 HSPLandroid/util/JsonReader;->fillBuffer(I)Z
 HSPLandroid/util/JsonReader;->hasNext()Z
+HSPLandroid/util/JsonReader;->nextBoolean()Z
 HSPLandroid/util/JsonReader;->nextInArray(Z)Landroid/util/JsonToken;
 HSPLandroid/util/JsonReader;->nextInObject(Z)Landroid/util/JsonToken;
+HSPLandroid/util/JsonReader;->nextInt()I
 HSPLandroid/util/JsonReader;->nextLiteral(Z)Ljava/lang/String;
 HSPLandroid/util/JsonReader;->nextLong()J
 HSPLandroid/util/JsonReader;->nextName()Ljava/lang/String;
@@ -14884,7 +15479,9 @@
 HSPLandroid/util/JsonWriter;->endArray()Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->endObject()Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->name(Ljava/lang/String;)Landroid/util/JsonWriter;
+HSPLandroid/util/JsonWriter;->open(Landroid/util/JsonScope;Ljava/lang/String;)Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V
+HSPLandroid/util/JsonWriter;->value(J)Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->value(Ljava/lang/String;)Landroid/util/JsonWriter;
 HSPLandroid/util/KeyValueListParser$IntValue;-><init>(Ljava/lang/String;I)V
 HSPLandroid/util/KeyValueListParser$IntValue;->getValue()I
@@ -14974,6 +15571,8 @@
 HSPLandroid/util/LruCache;->entryRemoved(ZLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/util/LruCache;->evictAll()V
 HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->hitCount()I
+HSPLandroid/util/LruCache;->missCount()I
 HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/LruCache;->remove(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/LruCache;->resize(I)V
@@ -15050,7 +15649,7 @@
 HSPLandroid/util/NtpTrustedTime;->hasCache()Z
 HSPLandroid/util/PackageUtils;->computeSha256Digest([B)Ljava/lang/String;
 HSPLandroid/util/PackageUtils;->computeSha256DigestBytes([B)[B
-PLandroid/util/PackageUtils;->computeSignaturesSha256Digest([Landroid/content/pm/Signature;)Ljava/lang/String;
+HPLandroid/util/PackageUtils;->computeSignaturesSha256Digest([Landroid/content/pm/Signature;)Ljava/lang/String;
 HSPLandroid/util/Pair;-><init>(Ljava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/util/Pair;->create(Ljava/lang/Object;Ljava/lang/Object;)Landroid/util/Pair;
 HSPLandroid/util/Pair;->equals(Ljava/lang/Object;)Z
@@ -15175,7 +15774,7 @@
 HSPLandroid/util/SparseLongArray;->delete(I)V
 HSPLandroid/util/SparseLongArray;->get(I)J
 HSPLandroid/util/SparseLongArray;->get(IJ)J
-PLandroid/util/SparseLongArray;->indexOfKey(I)I
+HPLandroid/util/SparseLongArray;->indexOfKey(I)I
 HSPLandroid/util/SparseLongArray;->keyAt(I)I
 HSPLandroid/util/SparseLongArray;->put(IJ)V
 HSPLandroid/util/SparseLongArray;->removeAt(I)V
@@ -15194,17 +15793,17 @@
 HSPLandroid/util/StateSet;->stateSetMatches([I[I)Z
 HSPLandroid/util/StateSet;->trimStateSet([II)[I
 HSPLandroid/util/StatsLogInternal;->write(ILandroid/os/WorkSource;I)V
-PLandroid/util/StatsLogInternal;->write(ILandroid/os/WorkSource;II)V
+HPLandroid/util/StatsLogInternal;->write(ILandroid/os/WorkSource;II)V
 HSPLandroid/util/StatsLogInternal;->write(ILandroid/os/WorkSource;Ljava/lang/String;Ljava/lang/String;)V
 HPLandroid/util/StatsLogInternal;->write(ILandroid/os/WorkSource;Ljava/lang/String;Ljava/lang/String;I)V
 HPLandroid/util/StringBuilderPrinter;->println(Ljava/lang/String;)V
 HSPLandroid/util/TimeUtils;->formatDuration(J)Ljava/lang/String;
 HSPLandroid/util/TimeUtils;->formatDuration(JJLjava/io/PrintWriter;)V
-PLandroid/util/TimeUtils;->formatDuration(JLjava/io/PrintWriter;)V
+HPLandroid/util/TimeUtils;->formatDuration(JLjava/io/PrintWriter;)V
 HSPLandroid/util/TimeUtils;->formatDuration(JLjava/io/PrintWriter;I)V
 HSPLandroid/util/TimeUtils;->formatDuration(JLjava/lang/StringBuilder;)V
 HSPLandroid/util/TimeUtils;->formatDurationLocked(JI)I
-PLandroid/util/TimeUtils;->formatForLogging(J)Ljava/lang/String;
+HPLandroid/util/TimeUtils;->formatForLogging(J)Ljava/lang/String;
 HSPLandroid/util/TimeUtils;->printFieldLocked([CICIZI)I
 HSPLandroid/util/TimedRemoteCaller;-><init>(J)V
 HPLandroid/util/TimedRemoteCaller;->getResultTimed(I)Ljava/lang/Object;
@@ -15214,6 +15813,11 @@
 HSPLandroid/util/TimestampedValue;->referenceTimeDifference(Landroid/util/TimestampedValue;Landroid/util/TimestampedValue;)J
 HSPLandroid/util/TimestampedValue;->toString()Ljava/lang/String;
 HSPLandroid/util/TimestampedValue;->writeToParcel(Landroid/os/Parcel;Landroid/util/TimestampedValue;)V
+HSPLandroid/util/TimingLogger;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/util/TimingLogger;->addSplit(Ljava/lang/String;)V
+HSPLandroid/util/TimingLogger;->dumpToLog()V
+HSPLandroid/util/TimingLogger;->reset()V
+HSPLandroid/util/TimingLogger;->reset(Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/util/TimingsTraceLog;-><init>(Ljava/lang/String;J)V
 HSPLandroid/util/TimingsTraceLog;->assertSameThread()V
 HSPLandroid/util/TimingsTraceLog;->logDuration(Ljava/lang/String;J)V
@@ -15243,18 +15847,18 @@
 HSPLandroid/util/apk/ApkSignatureSchemeV2Verifier;->verifyAdditionalAttributes(Ljava/nio/ByteBuffer;)V
 HSPLandroid/util/apk/ApkSignatureSchemeV2Verifier;->verifySigner(Ljava/nio/ByteBuffer;Ljava/util/Map;Ljava/security/cert/CertificateFactory;)[Ljava/security/cert/X509Certificate;
 HSPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->$closeResource(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V
-PLandroid/util/apk/ApkSignatureSchemeV3Verifier;->generateApkVerity(Ljava/lang/String;Landroid/util/apk/ByteBufferFactory;)[B
+HPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->generateApkVerity(Ljava/lang/String;Landroid/util/apk/ByteBufferFactory;)[B
 HSPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->generateApkVerityRootHash(Ljava/lang/String;)[B
-PLandroid/util/apk/ApkSignatureSchemeV3Verifier;->getVerityRootHash(Ljava/lang/String;)[B
+HPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->getVerityRootHash(Ljava/lang/String;)[B
 HSPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->isSupportedSignatureAlgorithm(I)Z
 HSPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->verify(Ljava/io/RandomAccessFile;Landroid/util/apk/SignatureInfo;Z)Landroid/util/apk/ApkSignatureSchemeV3Verifier$VerifiedSigner;
 HSPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->verify(Ljava/lang/String;Z)Landroid/util/apk/ApkSignatureSchemeV3Verifier$VerifiedSigner;
 HSPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->verifyAdditionalAttributes(Ljava/nio/ByteBuffer;Ljava/util/List;Ljava/security/cert/CertificateFactory;)Landroid/util/apk/ApkSignatureSchemeV3Verifier$VerifiedSigner;
 HSPLandroid/util/apk/ApkSignatureSchemeV3Verifier;->verifySigner(Ljava/nio/ByteBuffer;Ljava/util/Map;Ljava/security/cert/CertificateFactory;)Landroid/util/apk/ApkSignatureSchemeV3Verifier$VerifiedSigner;
 HSPLandroid/util/apk/ApkSignatureVerifier;->closeQuietly(Landroid/util/jar/StrictJarFile;)V
-PLandroid/util/apk/ApkSignatureVerifier;->generateApkVerity(Ljava/lang/String;Landroid/util/apk/ByteBufferFactory;)[B
+HPLandroid/util/apk/ApkSignatureVerifier;->generateApkVerity(Ljava/lang/String;Landroid/util/apk/ByteBufferFactory;)[B
 HSPLandroid/util/apk/ApkSignatureVerifier;->generateApkVerityRootHash(Ljava/lang/String;)[B
-PLandroid/util/apk/ApkSignatureVerifier;->getVerityRootHash(Ljava/lang/String;)[B
+HPLandroid/util/apk/ApkSignatureVerifier;->getVerityRootHash(Ljava/lang/String;)[B
 HSPLandroid/util/apk/ApkSignatureVerifier;->loadCertificates(Landroid/util/jar/StrictJarFile;Ljava/util/zip/ZipEntry;)[[Ljava/security/cert/Certificate;
 HSPLandroid/util/apk/ApkSignatureVerifier;->readFullyIgnoringContents(Ljava/io/InputStream;)V
 HSPLandroid/util/apk/ApkSignatureVerifier;->unsafeGetCertsWithoutVerification(Ljava/lang/String;I)Landroid/content/pm/PackageParser$SigningDetails;
@@ -15293,7 +15897,7 @@
 HSPLandroid/util/apk/VerityBuilder$BufferedDigester;->consume(Ljava/nio/ByteBuffer;)V
 HSPLandroid/util/apk/VerityBuilder;->assertSigningBlockAlignedAndHasFullPages(Landroid/util/apk/SignatureInfo;)V
 HSPLandroid/util/apk/VerityBuilder;->calculateVerityLevelOffset(J)[I
-PLandroid/util/apk/VerityBuilder;->generateApkVerity(Ljava/lang/String;Landroid/util/apk/ByteBufferFactory;Landroid/util/apk/SignatureInfo;)[B
+HPLandroid/util/apk/VerityBuilder;->generateApkVerity(Ljava/lang/String;Landroid/util/apk/ByteBufferFactory;Landroid/util/apk/SignatureInfo;)[B
 HSPLandroid/util/apk/VerityBuilder;->generateApkVerityDigestAtLeafLevel(Ljava/io/RandomAccessFile;Landroid/util/apk/SignatureInfo;[BLjava/nio/ByteBuffer;)V
 HSPLandroid/util/apk/VerityBuilder;->generateApkVerityExtensions(Ljava/nio/ByteBuffer;JJJ)Ljava/nio/ByteBuffer;
 HSPLandroid/util/apk/VerityBuilder;->generateApkVerityHeader(Ljava/nio/ByteBuffer;J[B)Ljava/nio/ByteBuffer;
@@ -15371,6 +15975,7 @@
 HSPLandroid/util/proto/ProtoInputStream;->readVarint()J
 HSPLandroid/util/proto/ProtoInputStream;->start(J)J
 HSPLandroid/util/proto/ProtoOutputStream;-><init>(I)V
+HPLandroid/util/proto/ProtoOutputStream;-><init>(Ljava/io/FileDescriptor;)V
 HSPLandroid/util/proto/ProtoOutputStream;-><init>(Ljava/io/OutputStream;)V
 HSPLandroid/util/proto/ProtoOutputStream;->compactIfNecessary()V
 HSPLandroid/util/proto/ProtoOutputStream;->compactSizes(I)V
@@ -15402,6 +16007,7 @@
 HSPLandroid/view/AbsSavedState$1;-><init>()V
 HSPLandroid/view/AbsSavedState$2;-><init>()V
 HSPLandroid/view/AbsSavedState;-><init>(Landroid/os/Parcelable;)V
+HSPLandroid/view/AbsSavedState;->getSuperState()Landroid/os/Parcelable;
 HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/Choreographer$1;-><init>()V
 HSPLandroid/view/Choreographer$1;->initialValue()Landroid/view/Choreographer;
@@ -15437,6 +16043,7 @@
 HSPLandroid/view/ContextThemeWrapper;-><init>(Landroid/content/Context;I)V
 HSPLandroid/view/ContextThemeWrapper;->applyOverrideConfiguration(Landroid/content/res/Configuration;)V
 HSPLandroid/view/ContextThemeWrapper;->attachBaseContext(Landroid/content/Context;)V
+HSPLandroid/view/ContextThemeWrapper;->getAssets()Landroid/content/res/AssetManager;
 HSPLandroid/view/ContextThemeWrapper;->getResources()Landroid/content/res/Resources;
 HSPLandroid/view/ContextThemeWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
 HSPLandroid/view/ContextThemeWrapper;->getTheme()Landroid/content/res/Resources$Theme;
@@ -15460,6 +16067,7 @@
 HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;)V
 HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V
 HSPLandroid/view/Display;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
+HSPLandroid/view/Display;->getDisplayId()I
 HSPLandroid/view/Display;->getDisplayInfo(Landroid/view/DisplayInfo;)Z
 HSPLandroid/view/Display;->getHeight()I
 HSPLandroid/view/Display;->getMaximumSizeDimension()I
@@ -15551,6 +16159,8 @@
 HSPLandroid/view/FocusFinder;->findNextFocusInAbsoluteDirection(Ljava/util/ArrayList;Landroid/view/ViewGroup;Landroid/view/View;Landroid/graphics/Rect;I)Landroid/view/View;
 HSPLandroid/view/FocusFinder;->findNextUserSpecifiedFocus(Landroid/view/ViewGroup;Landroid/view/View;I)Landroid/view/View;
 HSPLandroid/view/FocusFinder;->getEffectiveRoot(Landroid/view/ViewGroup;Landroid/view/View;)Landroid/view/ViewGroup;
+HSPLandroid/view/FocusFinder;->isBetterCandidate(ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;)Z
+HSPLandroid/view/FocusFinder;->isCandidate(Landroid/graphics/Rect;Landroid/graphics/Rect;I)Z
 HSPLandroid/view/GestureDetector$GestureHandler;->handleMessage(Landroid/os/Message;)V
 HSPLandroid/view/GestureDetector$SimpleOnGestureListener;-><init>()V
 HSPLandroid/view/GestureDetector$SimpleOnGestureListener;->onDoubleTap(Landroid/view/MotionEvent;)Z
@@ -15572,6 +16182,7 @@
 HSPLandroid/view/GestureDetector;->setContextClickListener(Landroid/view/GestureDetector$OnContextClickListener;)V
 HSPLandroid/view/GestureDetector;->setOnDoubleTapListener(Landroid/view/GestureDetector$OnDoubleTapListener;)V
 HSPLandroid/view/Gravity;->apply(IIILandroid/graphics/Rect;IILandroid/graphics/Rect;)V
+HSPLandroid/view/Gravity;->apply(IIILandroid/graphics/Rect;Landroid/graphics/Rect;)V
 HSPLandroid/view/Gravity;->apply(IIILandroid/graphics/Rect;Landroid/graphics/Rect;I)V
 HSPLandroid/view/Gravity;->applyDisplay(ILandroid/graphics/Rect;Landroid/graphics/Rect;)V
 HSPLandroid/view/Gravity;->getAbsoluteGravity(II)I
@@ -15649,10 +16260,11 @@
 HSPLandroid/view/IWindowManager$Stub$Proxy;->openSession(Landroid/view/IWindowSessionCallback;)Landroid/view/IWindowSession;
 HSPLandroid/view/IWindowManager$Stub;-><init>()V
 HSPLandroid/view/IWindowManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowManager;
-PLandroid/view/IWindowManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/view/IWindowManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/view/IWindowManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/view/IWindowSession$Stub$Proxy;->addToDisplay(Landroid/view/IWindow;ILandroid/view/WindowManager$LayoutParams;IILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/InputChannel;Landroid/view/InsetsState;)I
 HSPLandroid/view/IWindowSession$Stub$Proxy;->finishDrawing(Landroid/view/IWindow;)V
+HSPLandroid/view/IWindowSession$Stub$Proxy;->getDisplayFrame(Landroid/view/IWindow;Landroid/graphics/Rect;)V
 HSPLandroid/view/IWindowSession$Stub$Proxy;->getInTouchMode()Z
 HSPLandroid/view/IWindowSession$Stub$Proxy;->onRectangleOnScreenRequested(Landroid/os/IBinder;Landroid/graphics/Rect;)V
 HSPLandroid/view/IWindowSession$Stub$Proxy;->performHapticFeedback(IZ)Z
@@ -15662,7 +16274,7 @@
 HSPLandroid/view/IWindowSession$Stub$Proxy;->setInsets(Landroid/view/IWindow;ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Region;)V
 HSPLandroid/view/IWindowSession$Stub;-><init>()V
 HSPLandroid/view/IWindowSession$Stub;->asBinder()Landroid/os/IBinder;
-PLandroid/view/IWindowSession$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLandroid/view/IWindowSession$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLandroid/view/IWindowSession$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/view/IWindowSessionCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/IWindowSessionCallback$Stub;->asBinder()Landroid/os/IBinder;
@@ -15686,6 +16298,7 @@
 HSPLandroid/view/InputDevice$1;-><init>()V
 HSPLandroid/view/InputDevice$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/InputDevice;
 HSPLandroid/view/InputDevice$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/view/InputDevice$MotionRange;-><init>(IIFFFFFLandroid/view/InputDevice$1;)V
 HSPLandroid/view/InputDevice;-><init>(IIILjava/lang/String;IILjava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZZ)V
 HSPLandroid/view/InputDevice;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/view/InputDevice;->addMotionRange(IIFFFFF)V
@@ -15751,6 +16364,7 @@
 HSPLandroid/view/KeyCharacterMap;->addDeadKey(III)V
 HSPLandroid/view/KeyCharacterMap;->finalize()V
 HSPLandroid/view/KeyCharacterMap;->get(II)I
+HSPLandroid/view/KeyCharacterMap;->getKeyboardType()I
 HSPLandroid/view/KeyCharacterMap;->load(I)Landroid/view/KeyCharacterMap;
 HSPLandroid/view/KeyCharacterMap;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/KeyEvent$1;-><init>()V
@@ -15758,25 +16372,29 @@
 HSPLandroid/view/KeyEvent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/view/KeyEvent$DispatcherState;-><init>()V
 HSPLandroid/view/KeyEvent$DispatcherState;->handleUpEvent(Landroid/view/KeyEvent;)V
+HSPLandroid/view/KeyEvent$DispatcherState;->isTracking(Landroid/view/KeyEvent;)Z
 HSPLandroid/view/KeyEvent$DispatcherState;->reset()V
 HSPLandroid/view/KeyEvent$DispatcherState;->reset(Ljava/lang/Object;)V
 HSPLandroid/view/KeyEvent$DispatcherState;->startTracking(Landroid/view/KeyEvent;Ljava/lang/Object;)V
+HSPLandroid/view/KeyEvent;-><init>(JJIIIIIII)V
 HSPLandroid/view/KeyEvent;-><init>(Landroid/os/Parcel;)V
 HPLandroid/view/KeyEvent;->actionToString(I)Ljava/lang/String;
 HSPLandroid/view/KeyEvent;->dispatch(Landroid/view/KeyEvent$Callback;Landroid/view/KeyEvent$DispatcherState;Ljava/lang/Object;)Z
 HSPLandroid/view/KeyEvent;->getAction()I
 HSPLandroid/view/KeyEvent;->getDeviceId()I
 HSPLandroid/view/KeyEvent;->getEventTimeNano()J
+HSPLandroid/view/KeyEvent;->getFlags()I
 HSPLandroid/view/KeyEvent;->getKeyCharacterMap()Landroid/view/KeyCharacterMap;
 HSPLandroid/view/KeyEvent;->getKeyCode()I
+HSPLandroid/view/KeyEvent;->getMetaState()I
 HSPLandroid/view/KeyEvent;->getUnicodeChar()I
 HSPLandroid/view/KeyEvent;->getUnicodeChar(I)I
-PLandroid/view/KeyEvent;->isAltPressed()Z
+HPLandroid/view/KeyEvent;->isAltPressed()Z
 HSPLandroid/view/KeyEvent;->isCtrlPressed()Z
 HPLandroid/view/KeyEvent;->isMetaKey(I)Z
-PLandroid/view/KeyEvent;->isMetaPressed()Z
+HPLandroid/view/KeyEvent;->isMetaPressed()Z
 HSPLandroid/view/KeyEvent;->isModifierKey(I)Z
-PLandroid/view/KeyEvent;->isShiftPressed()Z
+HPLandroid/view/KeyEvent;->isShiftPressed()Z
 HSPLandroid/view/KeyEvent;->isSystem()Z
 HSPLandroid/view/KeyEvent;->isSystemKey(I)Z
 HSPLandroid/view/KeyEvent;->isWakeKey()Z
@@ -15829,6 +16447,7 @@
 HSPLandroid/view/MotionEvent;->getEventTimeNano()J
 HSPLandroid/view/MotionEvent;->getFlags()I
 HSPLandroid/view/MotionEvent;->getHistoricalEventTime(I)J
+HSPLandroid/view/MotionEvent;->getHistoricalPressure(II)F
 HSPLandroid/view/MotionEvent;->getHistoricalX(II)F
 HSPLandroid/view/MotionEvent;->getHistoricalY(II)F
 HSPLandroid/view/MotionEvent;->getHistorySize()I
@@ -15854,20 +16473,23 @@
 HSPLandroid/view/MotionEvent;->recycle()V
 HSPLandroid/view/MotionEvent;->setAction(I)V
 HSPLandroid/view/MotionEvent;->setLocation(FF)V
+HSPLandroid/view/MotionEvent;->split(I)Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->transform(Landroid/graphics/Matrix;)V
 HSPLandroid/view/OrientationEventListener;-><init>(Landroid/content/Context;)V
 HSPLandroid/view/OrientationEventListener;-><init>(Landroid/content/Context;I)V
 HSPLandroid/view/PointerIcon$1;-><init>()V
 HSPLandroid/view/PointerIcon;-><init>(I)V
+HSPLandroid/view/PointerIcon;->getSystemIcon(Landroid/content/Context;I)Landroid/view/PointerIcon;
+HSPLandroid/view/PointerIcon;->getSystemIconTypeIndex(I)I
 HSPLandroid/view/PointerIcon;->setUseLargeIcons(Z)V
 HSPLandroid/view/RemoteAnimationAdapter$1;-><init>()V
 PLandroid/view/RemoteAnimationAdapter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RemoteAnimationAdapter;
 PLandroid/view/RemoteAnimationAdapter$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-PLandroid/view/RemoteAnimationAdapter;->getCallingPid()I
-PLandroid/view/RemoteAnimationAdapter;->getDuration()J
-PLandroid/view/RemoteAnimationAdapter;->getRunner()Landroid/view/IRemoteAnimationRunner;
-PLandroid/view/RemoteAnimationAdapter;->getStatusBarTransitionDelay()J
-PLandroid/view/RemoteAnimationAdapter;->setCallingPid(I)V
+HPLandroid/view/RemoteAnimationAdapter;->getCallingPid()I
+HPLandroid/view/RemoteAnimationAdapter;->getDuration()J
+HPLandroid/view/RemoteAnimationAdapter;->getRunner()Landroid/view/IRemoteAnimationRunner;
+HPLandroid/view/RemoteAnimationAdapter;->getStatusBarTransitionDelay()J
+HPLandroid/view/RemoteAnimationAdapter;->setCallingPid(I)V
 HSPLandroid/view/RemoteAnimationDefinition$1;-><init>()V
 PLandroid/view/RemoteAnimationDefinition$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RemoteAnimationDefinition;
 PLandroid/view/RemoteAnimationDefinition$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -15900,6 +16522,7 @@
 HSPLandroid/view/RenderNodeAnimatorSetHelper;->getTarget(Landroid/graphics/RecordingCanvas;)Landroid/graphics/RenderNode;
 HSPLandroid/view/ScaleGestureDetector;-><init>(Landroid/content/Context;Landroid/view/ScaleGestureDetector$OnScaleGestureListener;)V
 HSPLandroid/view/ScaleGestureDetector;-><init>(Landroid/content/Context;Landroid/view/ScaleGestureDetector$OnScaleGestureListener;Landroid/os/Handler;)V
+HSPLandroid/view/ScaleGestureDetector;->onTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/ScaleGestureDetector;->setQuickScaleEnabled(Z)V
 HSPLandroid/view/ScaleGestureDetector;->setStylusScaleEnabled(Z)V
 HSPLandroid/view/Surface$1;-><init>()V
@@ -15933,6 +16556,7 @@
 HSPLandroid/view/SurfaceControl$Builder;->setSecure(Z)Landroid/view/SurfaceControl$Builder;
 HSPLandroid/view/SurfaceControl$PhysicalDisplayInfo;-><init>()V
 HSPLandroid/view/SurfaceControl$ScreenshotGraphicBuffer;->createFromNative(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;
+HPLandroid/view/SurfaceControl$ScreenshotGraphicBuffer;->getColorSpace()Landroid/graphics/ColorSpace;
 HSPLandroid/view/SurfaceControl$ScreenshotGraphicBuffer;->getGraphicBuffer()Landroid/graphics/GraphicBuffer;
 HSPLandroid/view/SurfaceControl$Transaction;-><init>()V
 HSPLandroid/view/SurfaceControl$Transaction;->apply()V
@@ -15947,7 +16571,7 @@
 HSPLandroid/view/SurfaceControl$Transaction;->setAlpha(Landroid/view/SurfaceControl;F)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setAnimationTransaction()Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setBufferSize(Landroid/view/SurfaceControl;II)Landroid/view/SurfaceControl$Transaction;
-PLandroid/view/SurfaceControl$Transaction;->setColor(Landroid/view/SurfaceControl;[F)Landroid/view/SurfaceControl$Transaction;
+HPLandroid/view/SurfaceControl$Transaction;->setColor(Landroid/view/SurfaceControl;[F)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setColorSpaceAgnostic(Landroid/view/SurfaceControl;Z)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setCornerRadius(Landroid/view/SurfaceControl;F)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setDisplayLayerStack(Landroid/os/IBinder;I)Landroid/view/SurfaceControl$Transaction;
@@ -15996,13 +16620,14 @@
 HSPLandroid/view/SurfaceControl;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/view/SurfaceControl;->release()V
 HSPLandroid/view/SurfaceControl;->remove()V
-PLandroid/view/SurfaceControl;->screenshot(Landroid/os/IBinder;Landroid/view/Surface;)V
-PLandroid/view/SurfaceControl;->screenshot(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIZI)V
+HPLandroid/view/SurfaceControl;->screenshot(Landroid/graphics/Rect;IIZI)Landroid/graphics/Bitmap;
+HPLandroid/view/SurfaceControl;->screenshot(Landroid/os/IBinder;Landroid/view/Surface;)V
+HPLandroid/view/SurfaceControl;->screenshot(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIZI)V
 HSPLandroid/view/SurfaceControl;->screenshotToBufferWithSecureLayersUnsafe(Landroid/os/IBinder;Landroid/graphics/Rect;IIZI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;
 HSPLandroid/view/SurfaceControl;->setAllowedDisplayConfigs(Landroid/os/IBinder;[I)Z
 HSPLandroid/view/SurfaceControl;->setAlpha(F)V
 HSPLandroid/view/SurfaceControl;->setBufferSize(II)V
-PLandroid/view/SurfaceControl;->setColor([F)V
+HPLandroid/view/SurfaceControl;->setColor([F)V
 HSPLandroid/view/SurfaceControl;->setColorSpaceAgnostic(Z)V
 HSPLandroid/view/SurfaceControl;->setDisplayPowerMode(Landroid/os/IBinder;I)V
 HSPLandroid/view/SurfaceControl;->setDisplayedContentSamplingEnabled(Landroid/os/IBinder;ZII)Z
@@ -16020,11 +16645,18 @@
 HSPLandroid/view/SurfaceSession;->finalize()V
 HSPLandroid/view/SurfaceSession;->kill()V
 HSPLandroid/view/SurfaceView$2;->onPreDraw()Z
+HSPLandroid/view/SurfaceView;-><init>(Landroid/content/Context;)V
 HSPLandroid/view/SurfaceView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/view/SurfaceView;->onAttachedToWindow()V
 HSPLandroid/view/SurfaceView;->onDetachedFromWindow()V
 HSPLandroid/view/SurfaceView;->onWindowVisibilityChanged(I)V
 HSPLandroid/view/SurfaceView;->updateSurface()V
+HSPLandroid/view/SurfaceView;->windowStopped(Z)V
+HSPLandroid/view/TextureView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+HSPLandroid/view/TextureView;->onAttachedToWindow()V
+HSPLandroid/view/TextureView;->onDetachedFromWindowInternal()V
+HSPLandroid/view/TextureView;->onVisibilityChanged(Landroid/view/View;I)V
+HSPLandroid/view/TextureView;->releaseSurfaceTexture()V
 HSPLandroid/view/ThreadedRenderer;-><init>(Landroid/content/Context;ZLjava/lang/String;)V
 HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
 HSPLandroid/view/ThreadedRenderer;->enableForegroundTrimming()V
@@ -16040,9 +16672,12 @@
 HSPLandroid/view/TouchDelegate;-><init>(Landroid/graphics/Rect;Landroid/view/View;)V
 HSPLandroid/view/VelocityTracker;->addMovement(Landroid/view/MotionEvent;)V
 HSPLandroid/view/VelocityTracker;->clear()V
+HSPLandroid/view/VelocityTracker;->computeCurrentVelocity(I)V
 HSPLandroid/view/VelocityTracker;->computeCurrentVelocity(IF)V
 HSPLandroid/view/VelocityTracker;->finalize()V
+HSPLandroid/view/VelocityTracker;->getXVelocity()F
 HSPLandroid/view/VelocityTracker;->getXVelocity(I)F
+HSPLandroid/view/VelocityTracker;->getYVelocity()F
 HSPLandroid/view/VelocityTracker;->getYVelocity(I)F
 HSPLandroid/view/VelocityTracker;->obtain()Landroid/view/VelocityTracker;
 HSPLandroid/view/VelocityTracker;->recycle()V
@@ -16078,6 +16713,8 @@
 HSPLandroid/view/View$6;->setValue(Landroid/view/View;F)V
 HSPLandroid/view/View$6;->setValue(Ljava/lang/Object;F)V
 HSPLandroid/view/View$7;-><init>(Ljava/lang/String;)V
+HSPLandroid/view/View$7;->setValue(Landroid/view/View;F)V
+HSPLandroid/view/View$7;->setValue(Ljava/lang/Object;F)V
 HSPLandroid/view/View$8;-><init>(Ljava/lang/String;)V
 HSPLandroid/view/View$9;-><init>(Ljava/lang/String;)V
 HSPLandroid/view/View$AccessibilityDelegate;-><init>()V
@@ -16119,11 +16756,13 @@
 HSPLandroid/view/View;->bringToFront()V
 HSPLandroid/view/View;->buildDrawingCache(Z)V
 HSPLandroid/view/View;->buildDrawingCacheImpl(Z)V
+HSPLandroid/view/View;->buildLayer()V
 HSPLandroid/view/View;->calculateIsImportantForContentCapture()Z
 HSPLandroid/view/View;->canHaveDisplayList()Z
 HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z
 HSPLandroid/view/View;->canResolveLayoutDirection()Z
 HSPLandroid/view/View;->canResolveTextDirection()Z
+HSPLandroid/view/View;->canScrollHorizontally(I)Z
 HSPLandroid/view/View;->canScrollVertically(I)Z
 HSPLandroid/view/View;->canTakeFocus()Z
 HSPLandroid/view/View;->cancelLongPress()V
@@ -16140,6 +16779,7 @@
 HSPLandroid/view/View;->combineVisibility(II)I
 HSPLandroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z
 HSPLandroid/view/View;->computeHorizontalScrollExtent()I
+HSPLandroid/view/View;->computeHorizontalScrollRange()I
 HSPLandroid/view/View;->computeOpaqueFlags()V
 HSPLandroid/view/View;->computeScroll()V
 HSPLandroid/view/View;->computeSystemWindowInsets(Landroid/view/WindowInsets;Landroid/graphics/Rect;)Landroid/view/WindowInsets;
@@ -16160,6 +16800,8 @@
 HSPLandroid/view/View;->dispatchDrawableHotspotChanged(FF)V
 HSPLandroid/view/View;->dispatchFinishTemporaryDetach()V
 HSPLandroid/view/View;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
+HSPLandroid/view/View;->dispatchPopulateAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)Z
+HSPLandroid/view/View;->dispatchPopulateAccessibilityEventInternal(Landroid/view/accessibility/AccessibilityEvent;)Z
 HSPLandroid/view/View;->dispatchProvideAutofillStructure(Landroid/view/ViewStructure;I)V
 HSPLandroid/view/View;->dispatchProvideStructure(Landroid/view/ViewStructure;II)V
 HSPLandroid/view/View;->dispatchRestoreInstanceState(Landroid/util/SparseArray;)V
@@ -16200,8 +16842,10 @@
 HSPLandroid/view/View;->getAccessibilityLiveRegion()I
 HSPLandroid/view/View;->getAccessibilityNodeProvider()Landroid/view/accessibility/AccessibilityNodeProvider;
 HSPLandroid/view/View;->getAccessibilityViewId()I
+HSPLandroid/view/View;->getAccessibilityWindowId()I
 HSPLandroid/view/View;->getAlpha()F
 HSPLandroid/view/View;->getAnimation()Landroid/view/animation/Animation;
+HSPLandroid/view/View;->getApplicationWindowToken()Landroid/os/IBinder;
 HSPLandroid/view/View;->getAutofillHints()[Ljava/lang/String;
 HSPLandroid/view/View;->getAutofillType()I
 HSPLandroid/view/View;->getAutofillViewId()I
@@ -16223,6 +16867,7 @@
 HSPLandroid/view/View;->getFitsSystemWindows()Z
 HSPLandroid/view/View;->getFocusable()I
 HSPLandroid/view/View;->getFocusableAttribute(Landroid/content/res/TypedArray;)I
+HSPLandroid/view/View;->getFocusedRect(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->getForeground()Landroid/graphics/drawable/Drawable;
 HSPLandroid/view/View;->getForegroundGravity()I
 HSPLandroid/view/View;->getGlobalVisibleRect(Landroid/graphics/Rect;)Z
@@ -16242,6 +16887,7 @@
 HSPLandroid/view/View;->getLeft()I
 HSPLandroid/view/View;->getListenerInfo()Landroid/view/View$ListenerInfo;
 HSPLandroid/view/View;->getLocationInWindow([I)V
+HSPLandroid/view/View;->getLocationOnScreen()[I
 HSPLandroid/view/View;->getLocationOnScreen([I)V
 HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;
 HSPLandroid/view/View;->getMeasuredHeight()I
@@ -16258,6 +16904,7 @@
 HSPLandroid/view/View;->getPaddingStart()I
 HSPLandroid/view/View;->getPaddingTop()I
 HSPLandroid/view/View;->getParent()Landroid/view/ViewParent;
+HSPLandroid/view/View;->getParentForAccessibility()Landroid/view/ViewParent;
 HSPLandroid/view/View;->getPivotX()F
 HSPLandroid/view/View;->getPivotY()F
 HSPLandroid/view/View;->getRawLayoutDirection()I
@@ -16270,10 +16917,12 @@
 HSPLandroid/view/View;->getRotation()F
 HSPLandroid/view/View;->getRotationX()F
 HSPLandroid/view/View;->getRotationY()F
+HSPLandroid/view/View;->getRunQueue()Landroid/view/HandlerActionQueue;
 HSPLandroid/view/View;->getScaleX()F
 HSPLandroid/view/View;->getScaleY()F
 HSPLandroid/view/View;->getScrollX()I
 HSPLandroid/view/View;->getScrollY()I
+HSPLandroid/view/View;->getSelfOrParentImportantForA11y()Landroid/view/View;
 HSPLandroid/view/View;->getStraightVerticalScrollBarBounds(Landroid/graphics/Rect;Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->getSuggestedMinimumHeight()I
 HSPLandroid/view/View;->getSuggestedMinimumWidth()I
@@ -16292,9 +16941,11 @@
 HSPLandroid/view/View;->getViewTreeObserver()Landroid/view/ViewTreeObserver;
 HSPLandroid/view/View;->getVisibility()I
 HSPLandroid/view/View;->getWidth()I
+HSPLandroid/view/View;->getWindowAttachCount()I
 HSPLandroid/view/View;->getWindowSystemUiVisibility()I
 HSPLandroid/view/View;->getWindowToken()Landroid/os/IBinder;
 HSPLandroid/view/View;->getWindowVisibility()I
+HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->getX()F
 HSPLandroid/view/View;->getY()F
 HSPLandroid/view/View;->getZ()F
@@ -16302,6 +16953,7 @@
 HSPLandroid/view/View;->handleScrollBarDragging(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/View;->hasAncestorThatBlocksDescendantFocus()Z
 HSPLandroid/view/View;->hasDefaultFocus()Z
+HSPLandroid/view/View;->hasExplicitFocusable()Z
 HSPLandroid/view/View;->hasFocus()Z
 HSPLandroid/view/View;->hasFocusable()Z
 HSPLandroid/view/View;->hasFocusable(ZZ)Z
@@ -16400,6 +17052,7 @@
 HSPLandroid/view/View;->onAttachedToWindow()V
 HSPLandroid/view/View;->onCancelPendingInputEvents()V
 HSPLandroid/view/View;->onCheckIsTextEditor()Z
+HSPLandroid/view/View;->onCloseSystemDialogs(Ljava/lang/String;)V
 HSPLandroid/view/View;->onConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLandroid/view/View;->onCreateDrawableState(I)[I
 HSPLandroid/view/View;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
@@ -16415,10 +17068,14 @@
 HSPLandroid/view/View;->onFinishTemporaryDetach()V
 HSPLandroid/view/View;->onFocusChanged(ZILandroid/graphics/Rect;)V
 HSPLandroid/view/View;->onFocusLost()V
+HSPLandroid/view/View;->onInitializeAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)V
+HSPLandroid/view/View;->onInitializeAccessibilityEventInternal(Landroid/view/accessibility/AccessibilityEvent;)V
 HSPLandroid/view/View;->onKeyDown(ILandroid/view/KeyEvent;)Z
 HSPLandroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
 HSPLandroid/view/View;->onLayout(ZIIII)V
 HSPLandroid/view/View;->onMeasure(II)V
+HSPLandroid/view/View;->onPopulateAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)V
+HSPLandroid/view/View;->onPopulateAccessibilityEventInternal(Landroid/view/accessibility/AccessibilityEvent;)V
 HSPLandroid/view/View;->onProvideAutofillStructure(Landroid/view/ViewStructure;I)V
 HSPLandroid/view/View;->onProvideAutofillVirtualStructure(Landroid/view/ViewStructure;I)V
 HSPLandroid/view/View;->onProvideStructure(Landroid/view/ViewStructure;II)V
@@ -16495,6 +17152,8 @@
 HSPLandroid/view/View;->scrollTo(II)V
 HSPLandroid/view/View;->sendAccessibilityEvent(I)V
 HSPLandroid/view/View;->sendAccessibilityEventInternal(I)V
+HSPLandroid/view/View;->sendAccessibilityEventUnchecked(Landroid/view/accessibility/AccessibilityEvent;)V
+HSPLandroid/view/View;->sendAccessibilityEventUncheckedInternal(Landroid/view/accessibility/AccessibilityEvent;)V
 HSPLandroid/view/View;->setAccessibilityDelegate(Landroid/view/View$AccessibilityDelegate;)V
 HSPLandroid/view/View;->setAccessibilityHeading(Z)V
 HSPLandroid/view/View;->setAccessibilityLiveRegion(I)V
@@ -16509,8 +17168,10 @@
 HSPLandroid/view/View;->setBackgroundColor(I)V
 HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/view/View;->setBackgroundResource(I)V
+HSPLandroid/view/View;->setBackgroundTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/view/View;->setBottom(I)V
 HSPLandroid/view/View;->setClickable(Z)V
+HSPLandroid/view/View;->setClipBounds(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->setClipToOutline(Z)V
 HSPLandroid/view/View;->setContentDescription(Ljava/lang/CharSequence;)V
 HSPLandroid/view/View;->setDefaultFocusHighlightEnabled(Z)V
@@ -16534,7 +17195,9 @@
 HSPLandroid/view/View;->setImportantForAutofill(I)V
 HSPLandroid/view/View;->setImportantForContentCapture(I)V
 HSPLandroid/view/View;->setIsRootNamespace(Z)V
+HSPLandroid/view/View;->setKeepScreenOn(Z)V
 HSPLandroid/view/View;->setKeyboardNavigationCluster(Z)V
+HSPLandroid/view/View;->setLayerPaint(Landroid/graphics/Paint;)V
 HSPLandroid/view/View;->setLayerType(ILandroid/graphics/Paint;)V
 HSPLandroid/view/View;->setLayoutDirection(I)V
 HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V
@@ -16544,6 +17207,10 @@
 HSPLandroid/view/View;->setMinimumHeight(I)V
 HSPLandroid/view/View;->setMinimumWidth(I)V
 HSPLandroid/view/View;->setNextFocusDownId(I)V
+HSPLandroid/view/View;->setNextFocusForwardId(I)V
+HSPLandroid/view/View;->setNextFocusLeftId(I)V
+HSPLandroid/view/View;->setNextFocusRightId(I)V
+HSPLandroid/view/View;->setNextFocusUpId(I)V
 HSPLandroid/view/View;->setOnApplyWindowInsetsListener(Landroid/view/View$OnApplyWindowInsetsListener;)V
 HSPLandroid/view/View;->setOnClickListener(Landroid/view/View$OnClickListener;)V
 HSPLandroid/view/View;->setOnCreateContextMenuListener(Landroid/view/View$OnCreateContextMenuListener;)V
@@ -16559,6 +17226,7 @@
 HSPLandroid/view/View;->setPaddingRelative(IIII)V
 HSPLandroid/view/View;->setPivotX(F)V
 HSPLandroid/view/View;->setPivotY(F)V
+HSPLandroid/view/View;->setPointerIcon(Landroid/view/PointerIcon;)V
 HSPLandroid/view/View;->setPressed(Z)V
 HSPLandroid/view/View;->setRight(I)V
 HSPLandroid/view/View;->setRotation(F)V
@@ -16569,6 +17237,7 @@
 HSPLandroid/view/View;->setScaleX(F)V
 HSPLandroid/view/View;->setScaleY(F)V
 HSPLandroid/view/View;->setScrollContainer(Z)V
+HSPLandroid/view/View;->setScrollIndicators(II)V
 HSPLandroid/view/View;->setScrollX(I)V
 HSPLandroid/view/View;->setScrollY(I)V
 HSPLandroid/view/View;->setSelected(Z)V
@@ -16577,6 +17246,7 @@
 HSPLandroid/view/View;->setTag(ILjava/lang/Object;)V
 HSPLandroid/view/View;->setTag(Ljava/lang/Object;)V
 HSPLandroid/view/View;->setTagInternal(ILjava/lang/Object;)V
+HSPLandroid/view/View;->setTextAlignment(I)V
 HSPLandroid/view/View;->setTextDirection(I)V
 HSPLandroid/view/View;->setTooltipText(Ljava/lang/CharSequence;)V
 HSPLandroid/view/View;->setTop(I)V
@@ -16585,6 +17255,7 @@
 HSPLandroid/view/View;->setTranslationX(F)V
 HSPLandroid/view/View;->setTranslationY(F)V
 HSPLandroid/view/View;->setTranslationZ(F)V
+HSPLandroid/view/View;->setVerticalScrollBarEnabled(Z)V
 HSPLandroid/view/View;->setVisibility(I)V
 HSPLandroid/view/View;->setWillNotDraw(Z)V
 HSPLandroid/view/View;->setX(F)V
@@ -16608,7 +17279,7 @@
 HSPLandroid/view/ViewAnimationHostBridge;->registerVectorDrawableAnimator(Landroid/view/NativeVectorDrawableAnimator;)V
 HSPLandroid/view/ViewConfiguration;-><init>(Landroid/content/Context;)V
 HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;
-PLandroid/view/ViewConfiguration;->getDeviceGlobalActionKeyTimeout()J
+HPLandroid/view/ViewConfiguration;->getDeviceGlobalActionKeyTimeout()J
 HSPLandroid/view/ViewConfiguration;->getDoubleTapMinTime()I
 HSPLandroid/view/ViewConfiguration;->getDoubleTapTimeout()I
 HSPLandroid/view/ViewConfiguration;->getKeyRepeatTimeout()I
@@ -16629,6 +17300,7 @@
 HSPLandroid/view/ViewConfiguration;->getScaledScrollBarSize()I
 HSPLandroid/view/ViewConfiguration;->getScaledTouchSlop()I
 HSPLandroid/view/ViewConfiguration;->getScaledVerticalScrollFactor()F
+HSPLandroid/view/ViewConfiguration;->getScaledWindowTouchSlop()I
 HSPLandroid/view/ViewConfiguration;->getTapTimeout()I
 HSPLandroid/view/ViewConfiguration;->isFadingMarqueeEnabled()Z
 HSPLandroid/view/ViewDebug;->getViewInstanceCount()J
@@ -16698,16 +17370,19 @@
 HSPLandroid/view/ViewGroup;->dispatchDetachedFromWindow()V
 HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/view/ViewGroup;->dispatchDrawableHotspotChanged(FF)V
+HSPLandroid/view/ViewGroup;->dispatchFinishTemporaryDetach()V
 HSPLandroid/view/ViewGroup;->dispatchFreezeSelfOnly(Landroid/util/SparseArray;)V
 HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V
 HSPLandroid/view/ViewGroup;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
 HSPLandroid/view/ViewGroup;->dispatchKeyEventPreIme(Landroid/view/KeyEvent;)Z
+HSPLandroid/view/ViewGroup;->dispatchPopulateAccessibilityEventInternal(Landroid/view/accessibility/AccessibilityEvent;)Z
 HSPLandroid/view/ViewGroup;->dispatchProvideAutofillStructure(Landroid/view/ViewStructure;I)V
 HSPLandroid/view/ViewGroup;->dispatchRestoreInstanceState(Landroid/util/SparseArray;)V
 HSPLandroid/view/ViewGroup;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V
 HSPLandroid/view/ViewGroup;->dispatchScreenStateChanged(I)V
 HSPLandroid/view/ViewGroup;->dispatchSetPressed(Z)V
 HSPLandroid/view/ViewGroup;->dispatchSetSelected(Z)V
+HSPLandroid/view/ViewGroup;->dispatchStartTemporaryDetach()V
 HSPLandroid/view/ViewGroup;->dispatchThawSelfOnly(Landroid/util/SparseArray;)V
 HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z
@@ -16748,6 +17423,7 @@
 HSPLandroid/view/ViewGroup;->getFocusedChild()Landroid/view/View;
 HSPLandroid/view/ViewGroup;->getLayoutMode()I
 HSPLandroid/view/ViewGroup;->getLayoutTransition()Landroid/animation/LayoutTransition;
+HSPLandroid/view/ViewGroup;->getScrollIndicatorBounds(Landroid/graphics/Rect;)V
 HSPLandroid/view/ViewGroup;->getTouchscreenBlocksFocus()Z
 HSPLandroid/view/ViewGroup;->handleFocusGainInternal(ILandroid/graphics/Rect;)V
 HSPLandroid/view/ViewGroup;->hasDefaultFocus()Z
@@ -16773,6 +17449,7 @@
 HSPLandroid/view/ViewGroup;->measureChild(Landroid/view/View;II)V
 HSPLandroid/view/ViewGroup;->measureChildWithMargins(Landroid/view/View;IIII)V
 HSPLandroid/view/ViewGroup;->measureChildren(II)V
+HSPLandroid/view/ViewGroup;->notifySubtreeAccessibilityStateChanged(Landroid/view/View;Landroid/view/View;I)V
 HSPLandroid/view/ViewGroup;->notifySubtreeAccessibilityStateChangedIfNeeded()V
 HSPLandroid/view/ViewGroup;->offsetRectBetweenParentAndChild(Landroid/view/View;Landroid/graphics/Rect;ZZ)V
 HSPLandroid/view/ViewGroup;->onAttachedToWindow()V
@@ -16782,11 +17459,14 @@
 HSPLandroid/view/ViewGroup;->onDetachedFromWindow()V
 HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/ViewGroup;->onRequestFocusInDescendants(ILandroid/graphics/Rect;)Z
+HSPLandroid/view/ViewGroup;->onRequestSendAccessibilityEvent(Landroid/view/View;Landroid/view/accessibility/AccessibilityEvent;)Z
+HSPLandroid/view/ViewGroup;->onRequestSendAccessibilityEventInternal(Landroid/view/View;Landroid/view/accessibility/AccessibilityEvent;)Z
 HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
 HSPLandroid/view/ViewGroup;->onViewAdded(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->onViewRemoved(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->populateChildrenForAutofill(Ljava/util/ArrayList;I)V
+HSPLandroid/view/ViewGroup;->recomputeViewAttributes(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->removeAllViews()V
 HSPLandroid/view/ViewGroup;->removeAllViewsInLayout()V
 HSPLandroid/view/ViewGroup;->removeDetachedView(Landroid/view/View;Z)V
@@ -16800,6 +17480,7 @@
 HSPLandroid/view/ViewGroup;->requestChildRectangleOnScreen(Landroid/view/View;Landroid/graphics/Rect;Z)Z
 HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V
 HSPLandroid/view/ViewGroup;->requestFocus(ILandroid/graphics/Rect;)Z
+HSPLandroid/view/ViewGroup;->requestSendAccessibilityEvent(Landroid/view/View;Landroid/view/accessibility/AccessibilityEvent;)Z
 HSPLandroid/view/ViewGroup;->requestTransitionStart(Landroid/animation/LayoutTransition;)V
 HSPLandroid/view/ViewGroup;->requestTransparentRegion(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V
@@ -16822,6 +17503,7 @@
 HSPLandroid/view/ViewGroup;->setClipChildren(Z)V
 HSPLandroid/view/ViewGroup;->setClipToPadding(Z)V
 HSPLandroid/view/ViewGroup;->setDescendantFocusability(I)V
+HSPLandroid/view/ViewGroup;->setLayoutAnimation(Landroid/view/animation/LayoutAnimationController;)V
 HSPLandroid/view/ViewGroup;->setLayoutTransition(Landroid/animation/LayoutTransition;)V
 HSPLandroid/view/ViewGroup;->setMotionEventSplittingEnabled(Z)V
 HSPLandroid/view/ViewGroup;->setOnHierarchyChangeListener(Landroid/view/ViewGroup$OnHierarchyChangeListener;)V
@@ -16861,6 +17543,7 @@
 HSPLandroid/view/ViewPropertyAnimator;->withEndAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
 HSPLandroid/view/ViewRootImpl$1;->onDisplayChanged(I)V
 HSPLandroid/view/ViewRootImpl$4;->run()V
+HSPLandroid/view/ViewRootImpl$AccessibilityInteractionConnectionManager;->ensureConnection()V
 HSPLandroid/view/ViewRootImpl$AsyncInputStage;->apply(Landroid/view/ViewRootImpl$QueuedInputEvent;I)V
 HSPLandroid/view/ViewRootImpl$AsyncInputStage;->defer(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl$AsyncInputStage;->dequeue(Landroid/view/ViewRootImpl$QueuedInputEvent;Landroid/view/ViewRootImpl$QueuedInputEvent;)V
@@ -16886,6 +17569,9 @@
 HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$NativePreImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$QueuedInputEvent;->shouldSkipIme()Z
+HSPLandroid/view/ViewRootImpl$SendWindowContentChangedAccessibilityEvent;->removeCallbacksAndRun()V
+HSPLandroid/view/ViewRootImpl$SendWindowContentChangedAccessibilityEvent;->run()V
+HSPLandroid/view/ViewRootImpl$SendWindowContentChangedAccessibilityEvent;->runOrPost(Landroid/view/View;I)V
 HSPLandroid/view/ViewRootImpl$SyntheticInputStage;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$SyntheticInputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl$SyntheticInputStage;->onDetachedFromWindow()V
@@ -16907,6 +17593,7 @@
 HSPLandroid/view/ViewRootImpl$ViewRootHandler;->sendMessageAtTime(Landroid/os/Message;J)Z
 HSPLandroid/view/ViewRootImpl$W;->closeSystemDialogs(Ljava/lang/String;)V
 HSPLandroid/view/ViewRootImpl$W;->dispatchAppVisibility(Z)V
+HSPLandroid/view/ViewRootImpl$W;->dispatchSystemUiVisibilityChanged(IIII)V
 HSPLandroid/view/ViewRootImpl$W;->dispatchWindowShown()V
 HSPLandroid/view/ViewRootImpl$W;->insetsChanged(Landroid/view/InsetsState;)V
 HSPLandroid/view/ViewRootImpl$W;->moved(II)V
@@ -16956,6 +17643,7 @@
 HSPLandroid/view/ViewRootImpl;->getAudioManager()Landroid/media/AudioManager;
 HSPLandroid/view/ViewRootImpl;->getAutofillManager()Landroid/view/autofill/AutofillManager;
 HSPLandroid/view/ViewRootImpl;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
+HSPLandroid/view/ViewRootImpl;->getCommonPredecessor(Landroid/view/View;Landroid/view/View;)Landroid/view/View;
 HSPLandroid/view/ViewRootImpl;->getDisplayId()I
 HSPLandroid/view/ViewRootImpl;->getHostVisibility()I
 HSPLandroid/view/ViewRootImpl;->getParent()Landroid/view/ViewParent;
@@ -16967,7 +17655,9 @@
 HSPLandroid/view/ViewRootImpl;->getWindowFlags()I
 HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;
 HSPLandroid/view/ViewRootImpl;->handleContentCaptureFlush()V
+HSPLandroid/view/ViewRootImpl;->handleDispatchSystemUiVisibilityChanged(Landroid/view/ViewRootImpl$SystemUiVisibilityInfo;)V
 HSPLandroid/view/ViewRootImpl;->handleDispatchWindowShown()V
+HSPLandroid/view/ViewRootImpl;->handleWindowContentChangedEvent(Landroid/view/accessibility/AccessibilityEvent;)V
 HSPLandroid/view/ViewRootImpl;->handleWindowFocusChanged()V
 HSPLandroid/view/ViewRootImpl;->hasColorModeChanged(I)Z
 HSPLandroid/view/ViewRootImpl;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V
@@ -16982,6 +17672,7 @@
 HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V
 HSPLandroid/view/ViewRootImpl;->maybeUpdateTooltip(Landroid/view/MotionEvent;)V
 HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;II)Z
+HSPLandroid/view/ViewRootImpl;->notifySubtreeAccessibilityStateChanged(Landroid/view/View;Landroid/view/View;I)V
 HSPLandroid/view/ViewRootImpl;->onDescendantInvalidated(Landroid/view/View;Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->onPostDraw(Landroid/graphics/RecordingCanvas;)V
 HSPLandroid/view/ViewRootImpl;->onPreDraw(Landroid/graphics/RecordingCanvas;)V
@@ -17007,6 +17698,7 @@
 HSPLandroid/view/ViewRootImpl;->requestDisallowInterceptTouchEvent(Z)V
 HSPLandroid/view/ViewRootImpl;->requestFitSystemWindows()V
 HSPLandroid/view/ViewRootImpl;->requestLayout()V
+HSPLandroid/view/ViewRootImpl;->requestSendAccessibilityEvent(Landroid/view/View;Landroid/view/accessibility/AccessibilityEvent;)Z
 HSPLandroid/view/ViewRootImpl;->requestTransparentRegion(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V
 HSPLandroid/view/ViewRootImpl;->scrollToRectOrFocus(Landroid/graphics/Rect;Z)Z
@@ -17070,6 +17762,7 @@
 HSPLandroid/view/Window;->getWindowStyle()Landroid/content/res/TypedArray;
 HSPLandroid/view/Window;->hasFeature(I)Z
 HSPLandroid/view/Window;->haveDimAmount()Z
+HSPLandroid/view/Window;->isOutOfBounds(Landroid/content/Context;Landroid/view/MotionEvent;)Z
 HSPLandroid/view/Window;->makeActive()V
 HSPLandroid/view/Window;->setCallback(Landroid/view/Window$Callback;)V
 HSPLandroid/view/Window;->setCloseOnTouchOutside(Z)V
@@ -17096,13 +17789,18 @@
 HSPLandroid/view/WindowInsets;->createCompatTypeMap(Landroid/graphics/Rect;)[Landroid/graphics/Insets;
 HSPLandroid/view/WindowInsets;->displayCutoutCopyConstructorArgument(Landroid/view/WindowInsets;)Landroid/view/DisplayCutout;
 HSPLandroid/view/WindowInsets;->equals(Ljava/lang/Object;)Z
+HSPLandroid/view/WindowInsets;->getDisplayCutout()Landroid/view/DisplayCutout;
 HSPLandroid/view/WindowInsets;->getInsets([Landroid/graphics/Insets;I)Landroid/graphics/Insets;
+HSPLandroid/view/WindowInsets;->getStableInsetBottom()I
+HSPLandroid/view/WindowInsets;->getStableInsetLeft()I
+HSPLandroid/view/WindowInsets;->getStableInsetRight()I
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetBottom()I
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetLeft()I
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetRight()I
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetTop()I
 HSPLandroid/view/WindowInsets;->inset(IIII)Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->insetInsets(Landroid/graphics/Insets;IIII)Landroid/graphics/Insets;
+HSPLandroid/view/WindowInsets;->isConsumed()Z
 HSPLandroid/view/WindowInsets;->replaceSystemWindowInsets(IIII)Landroid/view/WindowInsets;
 HSPLandroid/view/WindowManager$LayoutParams$1;-><init>()V
 HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/WindowManager$LayoutParams;
@@ -17123,7 +17821,7 @@
 HSPLandroid/view/WindowManagerGlobal;->closeAllExceptView(Landroid/os/IBinder;Landroid/view/View;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/view/WindowManagerGlobal;->doRemoveView(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/WindowManagerGlobal;->doTrimForeground()V
-PLandroid/view/WindowManagerGlobal;->dumpGfxInfo(Ljava/io/FileDescriptor;[Ljava/lang/String;)V
+HPLandroid/view/WindowManagerGlobal;->dumpGfxInfo(Ljava/io/FileDescriptor;[Ljava/lang/String;)V
 HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I
 HSPLandroid/view/WindowManagerGlobal;->getInstance()Landroid/view/WindowManagerGlobal;
 HSPLandroid/view/WindowManagerGlobal;->getRootViews(Landroid/os/IBinder;)Ljava/util/ArrayList;
@@ -17145,11 +17843,17 @@
 HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/accessibility/-$$Lambda$AccessibilityManager$1$o7fCplskH9NlBwJvkl6NoZ0L_BA;->run()V
 HSPLandroid/view/accessibility/AccessibilityEvent$1;-><init>()V
+HSPLandroid/view/accessibility/AccessibilityEvent;->clear()V
+HSPLandroid/view/accessibility/AccessibilityEvent;->setEventTime(J)V
+HSPLandroid/view/accessibility/AccessibilityEvent;->setPackageName(Ljava/lang/CharSequence;)V
+HSPLandroid/view/accessibility/AccessibilityEvent;->writeAccessibilityRecordToParcel(Landroid/view/accessibility/AccessibilityRecord;Landroid/os/Parcel;I)V
+HSPLandroid/view/accessibility/AccessibilityEvent;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/accessibility/AccessibilityManager$1;->lambda$notifyServicesStateChanged$0$AccessibilityManager$1(Landroid/view/accessibility/AccessibilityManager$AccessibilityServicesStateChangeListener;)V
 HSPLandroid/view/accessibility/AccessibilityManager$1;->notifyServicesStateChanged(J)V
 HSPLandroid/view/accessibility/AccessibilityManager$1;->setState(I)V
 HSPLandroid/view/accessibility/AccessibilityManager$MyCallback;->handleMessage(Landroid/os/Message;)Z
 HSPLandroid/view/accessibility/AccessibilityManager;-><init>(Landroid/content/Context;Landroid/view/accessibility/IAccessibilityManager;I)V
+HSPLandroid/view/accessibility/AccessibilityManager;->addAccessibilityInteractionConnection(Landroid/view/IWindow;Ljava/lang/String;Landroid/view/accessibility/IAccessibilityInteractionConnection;)I
 HSPLandroid/view/accessibility/AccessibilityManager;->addAccessibilityServicesStateChangeListener(Landroid/view/accessibility/AccessibilityManager$AccessibilityServicesStateChangeListener;Landroid/os/Handler;)V
 HSPLandroid/view/accessibility/AccessibilityManager;->addAccessibilityStateChangeListener(Landroid/view/accessibility/AccessibilityManager$AccessibilityStateChangeListener;)Z
 HSPLandroid/view/accessibility/AccessibilityManager;->addAccessibilityStateChangeListener(Landroid/view/accessibility/AccessibilityManager$AccessibilityStateChangeListener;Landroid/os/Handler;)V
@@ -17157,6 +17861,7 @@
 HSPLandroid/view/accessibility/AccessibilityManager;->addTouchExplorationStateChangeListener(Landroid/view/accessibility/AccessibilityManager$TouchExplorationStateChangeListener;)Z
 HSPLandroid/view/accessibility/AccessibilityManager;->addTouchExplorationStateChangeListener(Landroid/view/accessibility/AccessibilityManager$TouchExplorationStateChangeListener;Landroid/os/Handler;)V
 HSPLandroid/view/accessibility/AccessibilityManager;->getEnabledAccessibilityServiceList(I)Ljava/util/List;
+HSPLandroid/view/accessibility/AccessibilityManager;->getInstalledAccessibilityServiceList()Ljava/util/List;
 HSPLandroid/view/accessibility/AccessibilityManager;->getInstance(Landroid/content/Context;)Landroid/view/accessibility/AccessibilityManager;
 HSPLandroid/view/accessibility/AccessibilityManager;->getRecommendedTimeoutMillis(II)I
 HSPLandroid/view/accessibility/AccessibilityManager;->isAccessibilityVolumeStreamActive()Z
@@ -17165,10 +17870,13 @@
 HSPLandroid/view/accessibility/AccessibilityManager;->isTouchExplorationEnabled()Z
 HSPLandroid/view/accessibility/AccessibilityManager;->notifyAccessibilityButtonVisibilityChanged(Z)V
 HSPLandroid/view/accessibility/AccessibilityManager;->notifyAccessibilityStateChanged()V
+HSPLandroid/view/accessibility/AccessibilityManager;->removeAccessibilityInteractionConnection(Landroid/view/IWindow;)V
 HSPLandroid/view/accessibility/AccessibilityManager;->removeAccessibilityStateChangeListener(Landroid/view/accessibility/AccessibilityManager$AccessibilityStateChangeListener;)Z
 HSPLandroid/view/accessibility/AccessibilityManager;->removeHighTextContrastStateChangeListener(Landroid/view/accessibility/AccessibilityManager$HighTextContrastChangeListener;)V
+HSPLandroid/view/accessibility/AccessibilityManager;->sendAccessibilityEvent(Landroid/view/accessibility/AccessibilityEvent;)V
 HSPLandroid/view/accessibility/AccessibilityManager;->setStateLocked(I)V
 HSPLandroid/view/accessibility/AccessibilityManager;->tryConnectToServiceLocked(Landroid/view/accessibility/IAccessibilityManager;)V
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->findView(I)Landroid/view/View;
 HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->getInstance()Landroid/view/accessibility/AccessibilityNodeIdManager;
 HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V
 HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V
@@ -17179,15 +17887,25 @@
 HSPLandroid/view/accessibility/AccessibilityNodeInfo;-><init>()V
 HSPLandroid/view/accessibility/AccessibilityNodeInfo;->makeNodeId(II)J
 HSPLandroid/view/accessibility/AccessibilityRecord;-><init>()V
+HSPLandroid/view/accessibility/AccessibilityRecord;->clear()V
+HSPLandroid/view/accessibility/AccessibilityRecord;->enforceNotSealed()V
+HSPLandroid/view/accessibility/AccessibilityRecord;->isSealed()Z
+HSPLandroid/view/accessibility/AccessibilityRecord;->setClassName(Ljava/lang/CharSequence;)V
+HSPLandroid/view/accessibility/AccessibilityRecord;->setSource(Landroid/view/View;I)V
 HSPLandroid/view/accessibility/CaptioningManager$CaptionStyle;-><init>(IIIIILjava/lang/String;)V
 HSPLandroid/view/accessibility/CaptioningManager;-><init>(Landroid/content/Context;)V
+HSPLandroid/view/accessibility/CaptioningManager;->addCaptioningChangeListener(Landroid/view/accessibility/CaptioningManager$CaptioningChangeListener;)V
+HSPLandroid/view/accessibility/CaptioningManager;->getFontScale()F
 HSPLandroid/view/accessibility/CaptioningManager;->getLocale()Ljava/util/Locale;
+HSPLandroid/view/accessibility/CaptioningManager;->getRawUserStyle()I
+HSPLandroid/view/accessibility/CaptioningManager;->getUserStyle()Landroid/view/accessibility/CaptioningManager$CaptionStyle;
 HSPLandroid/view/accessibility/CaptioningManager;->isEnabled()Z
 HSPLandroid/view/accessibility/CaptioningManager;->removeCaptioningChangeListener(Landroid/view/accessibility/CaptioningManager$CaptioningChangeListener;)V
 HSPLandroid/view/accessibility/IAccessibilityInteractionConnection$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/accessibility/IAccessibilityInteractionConnection$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/accessibility/IAccessibilityManager$Stub$Proxy;->addClient(Landroid/view/accessibility/IAccessibilityManagerClient;I)J
 HSPLandroid/view/accessibility/IAccessibilityManager$Stub$Proxy;->getEnabledAccessibilityServiceList(II)Ljava/util/List;
+HSPLandroid/view/accessibility/IAccessibilityManager$Stub$Proxy;->getInstalledAccessibilityServiceList(I)Ljava/util/List;
 HSPLandroid/view/accessibility/IAccessibilityManager$Stub$Proxy;->getRecommendedTimeoutMillis()J
 HSPLandroid/view/accessibility/IAccessibilityManager$Stub;-><init>()V
 HSPLandroid/view/accessibility/IAccessibilityManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -17195,7 +17913,9 @@
 HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub$Proxy;->notifyServicesStateChanged(J)V
 HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub$Proxy;->setState(I)V
 HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/view/animation/AccelerateDecelerateInterpolator;-><init>()V
+HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->createNativeInterpolator()J
 HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->getInterpolation(F)F
 HSPLandroid/view/animation/AccelerateInterpolator;-><init>()V
 HSPLandroid/view/animation/AccelerateInterpolator;-><init>(F)V
@@ -17221,7 +17941,7 @@
 HSPLandroid/view/animation/Animation;->getBackgroundColor()I
 HSPLandroid/view/animation/Animation;->getDuration()J
 HSPLandroid/view/animation/Animation;->getFillAfter()Z
-PLandroid/view/animation/Animation;->getInterpolator()Landroid/view/animation/Interpolator;
+HPLandroid/view/animation/Animation;->getInterpolator()Landroid/view/animation/Interpolator;
 HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Animation;->getRepeatCount()I
 HSPLandroid/view/animation/Animation;->getScaleFactor()F
@@ -17289,10 +18009,12 @@
 HSPLandroid/view/animation/AnimationUtils$1;->initialValue()Ljava/lang/Object;
 HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/view/animation/AnimationSet;Landroid/util/AttributeSet;)Landroid/view/animation/Animation;
 HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;
+HSPLandroid/view/animation/AnimationUtils;->createLayoutAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;)Landroid/view/animation/LayoutAnimationController;
 HSPLandroid/view/animation/AnimationUtils;->currentAnimationTimeMillis()J
 HSPLandroid/view/animation/AnimationUtils;->loadAnimation(Landroid/content/Context;I)Landroid/view/animation/Animation;
 HSPLandroid/view/animation/AnimationUtils;->loadInterpolator(Landroid/content/Context;I)Landroid/view/animation/Interpolator;
 HSPLandroid/view/animation/AnimationUtils;->loadInterpolator(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;I)Landroid/view/animation/Interpolator;
+HSPLandroid/view/animation/AnimationUtils;->loadLayoutAnimation(Landroid/content/Context;I)Landroid/view/animation/LayoutAnimationController;
 HSPLandroid/view/animation/BaseInterpolator;->getChangingConfiguration()I
 HSPLandroid/view/animation/BaseInterpolator;->setChangingConfiguration(I)V
 HPLandroid/view/animation/ClipRectAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -17302,9 +18024,13 @@
 HSPLandroid/view/animation/DecelerateInterpolator;-><init>(F)V
 HSPLandroid/view/animation/DecelerateInterpolator;-><init>(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;)V
 HSPLandroid/view/animation/DecelerateInterpolator;->getInterpolation(F)F
+HSPLandroid/view/animation/LayoutAnimationController;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+HSPLandroid/view/animation/LayoutAnimationController;->setAnimation(Landroid/content/Context;I)V
+HSPLandroid/view/animation/LayoutAnimationController;->setAnimation(Landroid/view/animation/Animation;)V
 HSPLandroid/view/animation/LinearInterpolator;-><init>()V
 HSPLandroid/view/animation/LinearInterpolator;->createNativeInterpolator()J
 HSPLandroid/view/animation/LinearInterpolator;->getInterpolation(F)F
+HSPLandroid/view/animation/OvershootInterpolator;-><init>()V
 HSPLandroid/view/animation/PathInterpolator;-><init>(FFFF)V
 HSPLandroid/view/animation/PathInterpolator;-><init>(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;)V
 HSPLandroid/view/animation/PathInterpolator;->createNativeInterpolator()J
@@ -17328,7 +18054,8 @@
 HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Transformation;->setAlpha(F)V
 HPLandroid/view/animation/Transformation;->setClipRect(IIII)V
-PLandroid/view/animation/Transformation;->setClipRect(Landroid/graphics/Rect;)V
+HPLandroid/view/animation/Transformation;->setClipRect(Landroid/graphics/Rect;)V
+HSPLandroid/view/animation/TranslateAnimation;-><init>(FFFF)V
 HSPLandroid/view/animation/TranslateAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/animation/TranslateAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/TranslateAnimation;->initialize(IIII)V
@@ -17342,18 +18069,20 @@
 HSPLandroid/view/autofill/AutofillManager;-><init>(Landroid/content/Context;Landroid/view/autofill/IAutoFillManager;)V
 HSPLandroid/view/autofill/AutofillManager;->ensureServiceClientAddedIfNeededLocked()V
 HSPLandroid/view/autofill/AutofillManager;->getClient()Landroid/view/autofill/AutofillManager$AutofillClient;
+HSPLandroid/view/autofill/AutofillManager;->isEnabled()Z
 HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V
 HSPLandroid/view/autofill/AutofillManager;->notifyViewVisibilityChangedInternal(Landroid/view/View;IZZ)V
 HSPLandroid/view/autofill/AutofillManager;->requestHideFillUi(Landroid/view/autofill/AutofillId;Z)V
 HSPLandroid/view/autofill/AutofillValue$1;-><init>()V
 HPLandroid/view/autofill/AutofillValue$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/autofill/AutofillValue;
-PLandroid/view/autofill/AutofillValue$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLandroid/view/autofill/AutofillValue$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HPLandroid/view/autofill/AutofillValue;-><init>(Landroid/os/Parcel;)V
 HPLandroid/view/autofill/AutofillValue;->equals(Ljava/lang/Object;)Z
 HPLandroid/view/autofill/AutofillValue;->getTextValue()Ljava/lang/CharSequence;
 HPLandroid/view/autofill/AutofillValue;->isEmpty()Z
 HSPLandroid/view/autofill/AutofillValue;->writeToParcel(Landroid/os/Parcel;I)V
-PLandroid/view/autofill/Helper;->toList(Ljava/util/Set;)Ljava/util/ArrayList;
+HPLandroid/view/autofill/Helper;->toList(Ljava/util/Set;)Ljava/util/ArrayList;
+HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->addClient(Landroid/view/autofill/IAutoFillManagerClient;Landroid/content/ComponentName;ILcom/android/internal/os/IResultReceiver;)V
 HSPLandroid/view/autofill/IAutoFillManager$Stub;-><init>()V
 HSPLandroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager;
 HPLandroid/view/autofill/IAutoFillManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -17361,7 +18090,8 @@
 PLandroid/view/autofill/IAutoFillManagerClient$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 PLandroid/view/autofill/IAutoFillManagerClient$Stub$Proxy;->getAugmentedAutofillClient(Lcom/android/internal/os/IResultReceiver;)V
 PLandroid/view/autofill/IAutoFillManagerClient$Stub$Proxy;->setSessionFinished(ILjava/util/List;)V
-PLandroid/view/autofill/IAutoFillManagerClient$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManagerClient;
+HSPLandroid/view/autofill/IAutoFillManagerClient$Stub;->asBinder()Landroid/os/IBinder;
+HPLandroid/view/autofill/IAutoFillManagerClient$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManagerClient;
 HSPLandroid/view/contentcapture/ContentCaptureContext$1;-><init>()V
 HSPLandroid/view/contentcapture/ContentCaptureContext;-><init>(Landroid/view/contentcapture/ContentCaptureContext;Landroid/content/ComponentName;III)V
 PLandroid/view/contentcapture/ContentCaptureContext;->writeToParcel(Landroid/os/Parcel;I)V
@@ -17369,7 +18099,7 @@
 HSPLandroid/view/contentcapture/ContentCaptureHelper;->getLoggingLevelAsString(I)Ljava/lang/String;
 HSPLandroid/view/contentcapture/ContentCaptureHelper;->setLoggingLevel(I)V
 HSPLandroid/view/contentcapture/IContentCaptureManager$Stub;-><init>()V
-PLandroid/view/contentcapture/IContentCaptureManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLandroid/view/contentcapture/IContentCaptureManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/view/inputmethod/BaseInputConnection;->beginBatchEdit()Z
 HSPLandroid/view/inputmethod/BaseInputConnection;->endBatchEdit()Z
 HSPLandroid/view/inputmethod/BaseInputConnection;->finishComposingText()Z
@@ -17397,6 +18127,7 @@
 HSPLandroid/view/inputmethod/InputBinding$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/inputmethod/InputBinding;
 HSPLandroid/view/inputmethod/InputBinding$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/view/inputmethod/InputBinding;-><init>(Landroid/view/inputmethod/InputConnection;Landroid/view/inputmethod/InputBinding;)V
+HSPLandroid/view/inputmethod/InputBinding;->getConnection()Landroid/view/inputmethod/InputConnection;
 HSPLandroid/view/inputmethod/InputConnectionInspector;->getMissingMethodFlags(Landroid/view/inputmethod/InputConnection;)I
 HSPLandroid/view/inputmethod/InputMethodInfo$1;-><init>()V
 HSPLandroid/view/inputmethod/InputMethodInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/inputmethod/InputMethodInfo;
@@ -17425,6 +18156,7 @@
 HSPLandroid/view/inputmethod/InputMethodManager$PendingEvent;->run()V
 HSPLandroid/view/inputmethod/InputMethodManager;-><init>(Lcom/android/internal/view/IInputMethodManager;ILandroid/os/Looper;)V
 HSPLandroid/view/inputmethod/InputMethodManager;->checkFocusNoStartInput(Z)Z
+HSPLandroid/view/inputmethod/InputMethodManager;->closeCurrentInput()V
 HSPLandroid/view/inputmethod/InputMethodManager;->createRealInstance(ILandroid/os/Looper;)Landroid/view/inputmethod/InputMethodManager;
 HSPLandroid/view/inputmethod/InputMethodManager;->dispatchInputEvent(Landroid/view/InputEvent;Ljava/lang/Object;Landroid/view/inputmethod/InputMethodManager$FinishedInputEventCallback;Landroid/os/Handler;)I
 HSPLandroid/view/inputmethod/InputMethodManager;->finishedInputEvent(IZZ)V
@@ -17450,6 +18182,7 @@
 HSPLandroid/view/inputmethod/InputMethodManager;->restartInput(Landroid/view/View;)V
 HSPLandroid/view/inputmethod/InputMethodManager;->sendInputEventOnMainLooperLocked(Landroid/view/inputmethod/InputMethodManager$PendingEvent;)I
 HSPLandroid/view/inputmethod/InputMethodManager;->setInputChannelLocked(Landroid/view/InputChannel;)V
+HSPLandroid/view/inputmethod/InputMethodManager;->showSoftInput(Landroid/view/View;I)Z
 HSPLandroid/view/inputmethod/InputMethodManager;->showSoftInput(Landroid/view/View;ILandroid/os/ResultReceiver;)Z
 HSPLandroid/view/inputmethod/InputMethodManager;->startInputInner(ILandroid/os/IBinder;III)Z
 HSPLandroid/view/inputmethod/InputMethodManager;->updateSelection(Landroid/view/View;IIII)V
@@ -17477,7 +18210,7 @@
 HSPLandroid/view/textclassifier/-$$Lambda$0biFK4yZBmWN1EO2wtnXskzuEcE;-><init>()V
 HSPLandroid/view/textclassifier/-$$Lambda$0biFK4yZBmWN1EO2wtnXskzuEcE;->apply(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/view/textclassifier/-$$Lambda$9N8WImc0VBjy2oxI_Gk5_Pbye_A;-><init>()V
-PLandroid/view/textclassifier/-$$Lambda$9N8WImc0VBjy2oxI_Gk5_Pbye_A;->apply(Ljava/lang/Object;)Ljava/lang/Object;
+HPLandroid/view/textclassifier/-$$Lambda$9N8WImc0VBjy2oxI_Gk5_Pbye_A;->apply(Ljava/lang/Object;)Ljava/lang/Object;
 PLandroid/view/textclassifier/-$$Lambda$ActionsSuggestionsHelper$6oTtcn9bDE-u-8FbiyGdntqoQG0;-><init>()V
 PLandroid/view/textclassifier/-$$Lambda$ActionsSuggestionsHelper$6oTtcn9bDE-u-8FbiyGdntqoQG0;->test(Ljava/lang/Object;)Z
 PLandroid/view/textclassifier/-$$Lambda$ActionsSuggestionsHelper$YTQv8oPvlmJL4tITUFD4z4JWKRk;-><init>()V
@@ -17493,7 +18226,7 @@
 HSPLandroid/view/textclassifier/-$$Lambda$TextClassifierImpl$RRbXefHgcUymI9-P95ArUyMvfbw;->apply(Ljava/lang/Object;)Ljava/lang/Object;
 PLandroid/view/textclassifier/-$$Lambda$TextClassifierImpl$ftq-sQqJYwUdrdbbr9jz3p4AWos;->apply(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/view/textclassifier/-$$Lambda$XeE_KI7QgMKzF9vYRSoFWAolyuA;-><init>()V
-PLandroid/view/textclassifier/-$$Lambda$XeE_KI7QgMKzF9vYRSoFWAolyuA;->apply(Ljava/lang/Object;)Ljava/lang/Object;
+HPLandroid/view/textclassifier/-$$Lambda$XeE_KI7QgMKzF9vYRSoFWAolyuA;->apply(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/view/textclassifier/-$$Lambda$jJq8RXuVdjYF3lPq-77PEw1NJLM;-><init>()V
 HSPLandroid/view/textclassifier/-$$Lambda$jJq8RXuVdjYF3lPq-77PEw1NJLM;->apply(Ljava/lang/Object;)Ljava/lang/Object;
 HPLandroid/view/textclassifier/ActionsSuggestionsHelper$PersonEncoder;->encode(Landroid/app/Person;)I
@@ -17547,8 +18280,8 @@
 HSPLandroid/view/textclassifier/SystemTextClassifier$BlockingCallback;->onSuccess(Landroid/os/Bundle;)V
 HSPLandroid/view/textclassifier/SystemTextClassifier$ResponseReceiver;->get()Ljava/lang/Object;
 HSPLandroid/view/textclassifier/SystemTextClassifier;-><init>(Landroid/content/Context;Landroid/view/textclassifier/TextClassificationConstants;)V
-PLandroid/view/textclassifier/SystemTextClassifier;->onTextClassifierEvent(Landroid/view/textclassifier/TextClassifierEvent;)V
-PLandroid/view/textclassifier/SystemTextClassifier;->suggestConversationActions(Landroid/view/textclassifier/ConversationActions$Request;)Landroid/view/textclassifier/ConversationActions;
+HPLandroid/view/textclassifier/SystemTextClassifier;->onTextClassifierEvent(Landroid/view/textclassifier/TextClassifierEvent;)V
+HPLandroid/view/textclassifier/SystemTextClassifier;->suggestConversationActions(Landroid/view/textclassifier/ConversationActions$Request;)Landroid/view/textclassifier/ConversationActions;
 HSPLandroid/view/textclassifier/TextClassification$1;-><init>()V
 HSPLandroid/view/textclassifier/TextClassification$Builder;-><init>()V
 HSPLandroid/view/textclassifier/TextClassification$Builder;->build()Landroid/view/textclassifier/TextClassification;
@@ -17564,6 +18297,7 @@
 HSPLandroid/view/textclassifier/TextClassificationManager$SettingsObserver;-><init>(Landroid/view/textclassifier/TextClassificationManager;)V
 HSPLandroid/view/textclassifier/TextClassificationManager$SettingsObserver;->onChange(Z)V
 HSPLandroid/view/textclassifier/TextClassificationManager;-><init>(Landroid/content/Context;)V
+HSPLandroid/view/textclassifier/TextClassificationManager;->finalize()V
 HSPLandroid/view/textclassifier/TextClassificationManager;->getLocalTextClassifier()Landroid/view/textclassifier/TextClassifier;
 HSPLandroid/view/textclassifier/TextClassificationManager;->getSettings()Landroid/view/textclassifier/TextClassificationConstants;
 HSPLandroid/view/textclassifier/TextClassificationManager;->getSettings(Landroid/content/Context;)Landroid/view/textclassifier/TextClassificationConstants;
@@ -17594,14 +18328,14 @@
 HPLandroid/view/textclassifier/TextClassifierImpl;->createConversationActionResult(Landroid/view/textclassifier/ConversationActions$Request;[Lcom/google/android/textclassifier/ActionsSuggestionsModel$ActionSuggestion;)Landroid/view/textclassifier/ConversationActions;
 HSPLandroid/view/textclassifier/TextClassifierImpl;->detectLanguage(Landroid/view/textclassifier/TextLanguage$Request;)Landroid/view/textclassifier/TextLanguage;
 HSPLandroid/view/textclassifier/TextClassifierImpl;->detectLanguageTagsFromText(Ljava/lang/CharSequence;)Ljava/lang/String;
-PLandroid/view/textclassifier/TextClassifierImpl;->getActionsImpl()Lcom/google/android/textclassifier/ActionsSuggestionsModel;
+HPLandroid/view/textclassifier/TextClassifierImpl;->getActionsImpl()Lcom/google/android/textclassifier/ActionsSuggestionsModel;
 HSPLandroid/view/textclassifier/TextClassifierImpl;->getAnnotatorImpl(Landroid/os/LocaleList;)Lcom/google/android/textclassifier/AnnotatorModel;
 HSPLandroid/view/textclassifier/TextClassifierImpl;->getLangIdImpl()Lcom/google/android/textclassifier/LangIdModel;
 HSPLandroid/view/textclassifier/TextClassifierImpl;->getLangIdThreshold()F
 HSPLandroid/view/textclassifier/TextClassifierImpl;->getResourceLocalesString()Ljava/lang/String;
 HSPLandroid/view/textclassifier/TextClassifierImpl;->maybeCloseAndLogError(Landroid/os/ParcelFileDescriptor;)V
-PLandroid/view/textclassifier/TextClassifierImpl;->resolveActionTypesFromRequest(Landroid/view/textclassifier/ConversationActions$Request;)Ljava/util/Collection;
-PLandroid/view/textclassifier/TextClassifierImpl;->suggestConversationActions(Landroid/view/textclassifier/ConversationActions$Request;)Landroid/view/textclassifier/ConversationActions;
+HPLandroid/view/textclassifier/TextClassifierImpl;->resolveActionTypesFromRequest(Landroid/view/textclassifier/ConversationActions$Request;)Ljava/util/Collection;
+HPLandroid/view/textclassifier/TextClassifierImpl;->suggestConversationActions(Landroid/view/textclassifier/ConversationActions$Request;)Landroid/view/textclassifier/ConversationActions;
 HSPLandroid/view/textclassifier/TextLanguage$1;-><init>()V
 HSPLandroid/view/textclassifier/TextLanguage$Builder;-><init>()V
 HSPLandroid/view/textclassifier/TextLanguage$Builder;->build()Landroid/view/textclassifier/TextLanguage;
@@ -17611,14 +18345,14 @@
 PLandroid/view/textclassifier/intent/-$$Lambda$LabeledIntent$LaL7EfxShgNu4lrdo3mv85g49Jg;-><init>()V
 PLandroid/view/textclassifier/intent/LabeledIntent;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/content/Intent;I)V
 PLandroid/view/textclassifier/intent/LabeledIntent;->resolve(Landroid/content/Context;Landroid/view/textclassifier/intent/LabeledIntent$TitleChooser;Landroid/os/Bundle;)Landroid/view/textclassifier/intent/LabeledIntent$Result;
-PLandroid/view/textclassifier/intent/TemplateIntentFactory;->create([Lcom/google/android/textclassifier/RemoteActionTemplate;)Ljava/util/List;
-PLandroid/view/textclassifier/intent/TemplateIntentFactory;->createIntent(Lcom/google/android/textclassifier/RemoteActionTemplate;)Landroid/content/Intent;
-PLandroid/view/textclassifier/intent/TemplateIntentFactory;->isValidTemplate(Lcom/google/android/textclassifier/RemoteActionTemplate;)Z
-PLandroid/view/textclassifier/intent/TemplateIntentFactory;->nameVariantsToBundle([Lcom/google/android/textclassifier/NamedVariant;)Landroid/os/Bundle;
+HPLandroid/view/textclassifier/intent/TemplateIntentFactory;->create([Lcom/google/android/textclassifier/RemoteActionTemplate;)Ljava/util/List;
+HPLandroid/view/textclassifier/intent/TemplateIntentFactory;->createIntent(Lcom/google/android/textclassifier/RemoteActionTemplate;)Landroid/content/Intent;
+HPLandroid/view/textclassifier/intent/TemplateIntentFactory;->isValidTemplate(Lcom/google/android/textclassifier/RemoteActionTemplate;)Z
+HPLandroid/view/textclassifier/intent/TemplateIntentFactory;->nameVariantsToBundle([Lcom/google/android/textclassifier/NamedVariant;)Landroid/os/Bundle;
 HSPLandroid/view/textservice/SpellCheckerInfo$1;-><init>()V
 HSPLandroid/view/textservice/SpellCheckerInfo;-><init>(Landroid/content/Context;Landroid/content/pm/ResolveInfo;)V
-PLandroid/view/textservice/SpellCheckerInfo;->getComponent()Landroid/content/ComponentName;
-PLandroid/view/textservice/SpellCheckerInfo;->getPackageName()Ljava/lang/String;
+HPLandroid/view/textservice/SpellCheckerInfo;->getComponent()Landroid/content/ComponentName;
+HPLandroid/view/textservice/SpellCheckerInfo;->getPackageName()Ljava/lang/String;
 HSPLandroid/view/textservice/SpellCheckerInfo;->getSubtypeAt(I)Landroid/view/textservice/SpellCheckerSubtype;
 HSPLandroid/view/textservice/SpellCheckerInfo;->getSubtypeCount()I
 HSPLandroid/view/textservice/SpellCheckerSubtype$1;-><init>()V
@@ -17695,28 +18429,47 @@
 HSPLandroid/widget/AbsListView$RecycleBin;->setViewTypeCount(I)V
 HSPLandroid/widget/AbsListView$RecycleBin;->shouldRecycleViewType(I)Z
 HSPLandroid/widget/AbsListView$SavedState$1;-><init>()V
+HSPLandroid/widget/AbsListView$SavedState;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/widget/AbsListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/AbsListView;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/widget/AbsListView;->clearChoices()V
+HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I
+HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I
+HSPLandroid/widget/AbsListView;->computeVerticalScrollRange()I
 HSPLandroid/widget/AbsListView;->dispatchDraw(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/AbsListView;->dispatchSetPressed(Z)V
 HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/AbsListView;->drawableStateChanged()V
+HSPLandroid/widget/AbsListView;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/view/ViewGroup$LayoutParams;
+HSPLandroid/widget/AbsListView;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/widget/AbsListView$LayoutParams;
+HSPLandroid/widget/AbsListView;->getVerticalScrollbarWidth()I
 HSPLandroid/widget/AbsListView;->handleBoundsChange()V
 HSPLandroid/widget/AbsListView;->handleDataChanged()V
+HSPLandroid/widget/AbsListView;->handleScrollBarDragging(Landroid/view/MotionEvent;)Z
 HSPLandroid/widget/AbsListView;->hideSelector()V
 HSPLandroid/widget/AbsListView;->initAbsListView()V
 HSPLandroid/widget/AbsListView;->internalSetPadding(IIII)V
 HSPLandroid/widget/AbsListView;->invokeOnItemScrollListener()V
+HSPLandroid/widget/AbsListView;->isFastScrollEnabled()Z
 HSPLandroid/widget/AbsListView;->isInFilterMode()Z
+HSPLandroid/widget/AbsListView;->isVerticalScrollBarHidden()Z
 HSPLandroid/widget/AbsListView;->jumpDrawablesToCurrentState()V
 HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;
 HSPLandroid/widget/AbsListView;->onAttachedToWindow()V
 HSPLandroid/widget/AbsListView;->onDetachedFromWindow()V
+HSPLandroid/widget/AbsListView;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/widget/AbsListView;->onLayout(ZIIII)V
 HSPLandroid/widget/AbsListView;->onMeasure(II)V
 HSPLandroid/widget/AbsListView;->onRtlPropertiesChanged(I)V
+HSPLandroid/widget/AbsListView;->onSaveInstanceState()Landroid/os/Parcelable;
+HSPLandroid/widget/AbsListView;->onTouchDown(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/widget/AbsListView;->onTouchModeChanged(Z)V
+HSPLandroid/widget/AbsListView;->onTouchUp(Landroid/view/MotionEvent;)V
 HSPLandroid/widget/AbsListView;->onWindowFocusChanged(Z)V
+HSPLandroid/widget/AbsListView;->pointToPosition(II)I
+HSPLandroid/widget/AbsListView;->positionSelector(ILandroid/view/View;)V
+HSPLandroid/widget/AbsListView;->positionSelector(ILandroid/view/View;ZFF)V
 HSPLandroid/widget/AbsListView;->requestLayout()V
 HSPLandroid/widget/AbsListView;->resetList()V
 HSPLandroid/widget/AbsListView;->setAdapter(Landroid/widget/ListAdapter;)V
@@ -17741,11 +18494,17 @@
 HSPLandroid/widget/AbsSeekBar;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/AbsSeekBar;->applyThumbTint()V
 HSPLandroid/widget/AbsSeekBar;->applyTickMarkTint()V
+HSPLandroid/widget/AbsSeekBar;->drawThumb(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/AbsSeekBar;->drawTickMarks(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/AbsSeekBar;->drawTrack(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/AbsSeekBar;->drawableStateChanged()V
 HSPLandroid/widget/AbsSeekBar;->getThumbOffset()I
 HSPLandroid/widget/AbsSeekBar;->jumpDrawablesToCurrentState()V
+HSPLandroid/widget/AbsSeekBar;->onDraw(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/AbsSeekBar;->onMeasure(II)V
 HSPLandroid/widget/AbsSeekBar;->onResolveDrawables(I)V
 HSPLandroid/widget/AbsSeekBar;->onRtlPropertiesChanged(I)V
+HSPLandroid/widget/AbsSeekBar;->onSizeChanged(IIII)V
 HSPLandroid/widget/AbsSeekBar;->onVisualProgressChanged(IF)V
 HSPLandroid/widget/AbsSeekBar;->setKeyProgressIncrement(I)V
 HSPLandroid/widget/AbsSeekBar;->setMax(I)V
@@ -17754,11 +18513,16 @@
 HSPLandroid/widget/AbsSeekBar;->setThumbOffset(I)V
 HSPLandroid/widget/AbsSeekBar;->setThumbPos(ILandroid/graphics/drawable/Drawable;FI)V
 HSPLandroid/widget/AbsSeekBar;->setTickMark(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/AbsSeekBar;->updateThumbAndTrackPos(II)V
 HSPLandroid/widget/AbsSeekBar;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
+HSPLandroid/widget/ActionMenuPresenter$2;->onViewDetachedFromWindow(Landroid/view/View;)V
 HSPLandroid/widget/ActionMenuPresenter;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/ActionMenuPresenter;->bindItemView(Lcom/android/internal/view/menu/MenuItemImpl;Lcom/android/internal/view/menu/MenuView$ItemView;)V
+HSPLandroid/widget/ActionMenuPresenter;->dismissPopupMenus()Z
 HSPLandroid/widget/ActionMenuPresenter;->flagActionItems()Z
 HSPLandroid/widget/ActionMenuPresenter;->getItemView(Lcom/android/internal/view/menu/MenuItemImpl;Landroid/view/View;Landroid/view/ViewGroup;)Landroid/view/View;
+HSPLandroid/widget/ActionMenuPresenter;->hideOverflowMenu()Z
+HSPLandroid/widget/ActionMenuPresenter;->hideSubMenus()Z
 HSPLandroid/widget/ActionMenuPresenter;->initForMenu(Landroid/content/Context;Lcom/android/internal/view/menu/MenuBuilder;)V
 HSPLandroid/widget/ActionMenuPresenter;->isOverflowMenuShowing()Z
 HSPLandroid/widget/ActionMenuPresenter;->setExpandedActionViewsExclusive(Z)V
@@ -17768,12 +18532,16 @@
 HSPLandroid/widget/ActionMenuPresenter;->updateMenuView(Z)V
 HSPLandroid/widget/ActionMenuView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/ActionMenuView;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
+HSPLandroid/widget/ActionMenuView;->dismissPopupMenus()V
+HSPLandroid/widget/ActionMenuView;->generateDefaultLayoutParams()Landroid/widget/ActionMenuView$LayoutParams;
 HSPLandroid/widget/ActionMenuView;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/view/ViewGroup$LayoutParams;
 HSPLandroid/widget/ActionMenuView;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/widget/ActionMenuView$LayoutParams;
+HSPLandroid/widget/ActionMenuView;->generateOverflowButtonLayoutParams()Landroid/widget/ActionMenuView$LayoutParams;
 HSPLandroid/widget/ActionMenuView;->getMenu()Landroid/view/Menu;
 HSPLandroid/widget/ActionMenuView;->hasDividerBeforeChildAt(I)Z
 HSPLandroid/widget/ActionMenuView;->initialize(Lcom/android/internal/view/menu/MenuBuilder;)V
 HSPLandroid/widget/ActionMenuView;->isOverflowMenuShowing()Z
+HSPLandroid/widget/ActionMenuView;->onDetachedFromWindow()V
 HSPLandroid/widget/ActionMenuView;->onLayout(ZIIII)V
 HSPLandroid/widget/ActionMenuView;->onMeasure(II)V
 HSPLandroid/widget/ActionMenuView;->peekMenu()Lcom/android/internal/view/menu/MenuBuilder;
@@ -17801,11 +18569,14 @@
 HSPLandroid/widget/BaseAdapter;->getItemViewType(I)I
 HSPLandroid/widget/BaseAdapter;->getViewTypeCount()I
 HSPLandroid/widget/BaseAdapter;->hasStableIds()Z
+HSPLandroid/widget/BaseAdapter;->isEnabled(I)Z
 HSPLandroid/widget/BaseAdapter;->notifyDataSetChanged()V
 HSPLandroid/widget/BaseAdapter;->registerDataSetObserver(Landroid/database/DataSetObserver;)V
 HSPLandroid/widget/BaseAdapter;->unregisterDataSetObserver(Landroid/database/DataSetObserver;)V
 HSPLandroid/widget/Button;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/Button;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
+HSPLandroid/widget/Button;->getAccessibilityClassName()Ljava/lang/CharSequence;
+HSPLandroid/widget/CheckBox;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/Chronometer;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/Chronometer;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/Chronometer;->onDetachedFromWindow()V
@@ -17827,6 +18598,7 @@
 HSPLandroid/widget/CompoundButton;->onCreateDrawableState(I)[I
 HSPLandroid/widget/CompoundButton;->onDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/CompoundButton;->onResolveDrawables(I)V
+HSPLandroid/widget/CompoundButton;->setButtonDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/CompoundButton;->setChecked(Z)V
 HSPLandroid/widget/CompoundButton;->setOnCheckedChangeListener(Landroid/widget/CompoundButton$OnCheckedChangeListener;)V
 HSPLandroid/widget/CompoundButton;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
@@ -17860,15 +18632,18 @@
 HSPLandroid/widget/Editor$EditOperation;->commit()V
 HSPLandroid/widget/Editor$EditOperation;->mergeInsertWith(Landroid/widget/Editor$EditOperation;)Z
 HSPLandroid/widget/Editor$InsertionPointCursorController;->hide()V
+HSPLandroid/widget/Editor$InsertionPointCursorController;->invalidateHandle()V
 HSPLandroid/widget/Editor$InsertionPointCursorController;->isActive()Z
 HSPLandroid/widget/Editor$InsertionPointCursorController;->isCursorBeingModified()Z
 HSPLandroid/widget/Editor$InsertionPointCursorController;->onDetached()V
 HSPLandroid/widget/Editor$MagnifierMotionAnimator;-><init>(Landroid/widget/Magnifier;)V
 HSPLandroid/widget/Editor$PositionListener;->addSubscriber(Landroid/widget/Editor$TextViewPositionListener;Z)V
 HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z
+HSPLandroid/widget/Editor$PositionListener;->onScrollChanged()V
 HSPLandroid/widget/Editor$PositionListener;->removeSubscriber(Landroid/widget/Editor$TextViewPositionListener;)V
 HSPLandroid/widget/Editor$PositionListener;->updatePosition()V
 HSPLandroid/widget/Editor$ProcessTextIntentActionsHandler;-><init>(Landroid/widget/Editor;)V
+HSPLandroid/widget/Editor$SelectionModifierCursorController;->invalidateHandles()V
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->isCursorBeingModified()Z
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->isDragAcceleratorActive()Z
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->isSelectionStartDragged()Z
@@ -17912,13 +18687,16 @@
 HSPLandroid/widget/Editor;->hideInsertionPointCursorController()V
 HSPLandroid/widget/Editor;->invalidateHandlesAndActionMode()V
 HSPLandroid/widget/Editor;->invalidateTextDisplayList()V
+HSPLandroid/widget/Editor;->invalidateTextDisplayList(Landroid/text/Layout;II)V
 HSPLandroid/widget/Editor;->loadCursorDrawable()V
 HSPLandroid/widget/Editor;->makeBlink()V
 HSPLandroid/widget/Editor;->onAttachedToWindow()V
 HSPLandroid/widget/Editor;->onDetachedFromWindow()V
 HSPLandroid/widget/Editor;->onDraw(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
 HSPLandroid/widget/Editor;->onFocusChanged(ZI)V
+HSPLandroid/widget/Editor;->onLocaleChanged()V
 HSPLandroid/widget/Editor;->onScreenStateChanged(I)V
+HSPLandroid/widget/Editor;->onScrollChanged()V
 HSPLandroid/widget/Editor;->onWindowFocusChanged(Z)V
 HSPLandroid/widget/Editor;->prepareCursorControllers()V
 HSPLandroid/widget/Editor;->refreshTextActionMode()V
@@ -17935,9 +18713,11 @@
 HSPLandroid/widget/Editor;->updateSpellCheckSpans(IIZ)V
 HSPLandroid/widget/ForwardingListener;-><init>(Landroid/view/View;)V
 HSPLandroid/widget/ForwardingListener;->onViewAttachedToWindow(Landroid/view/View;)V
+HSPLandroid/widget/ForwardingListener;->onViewDetachedFromWindow(Landroid/view/View;)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(II)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(III)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
@@ -17960,6 +18740,8 @@
 HSPLandroid/widget/GridLayout$1;-><init>()V
 HSPLandroid/widget/GridLayout$2;-><init>()V
 HSPLandroid/widget/GridLayout$3;-><init>()V
+HSPLandroid/widget/GridLayout$3;->getAlignmentValue(Landroid/view/View;II)I
+HSPLandroid/widget/GridLayout$3;->getGravityOffset(Landroid/view/View;I)I
 HSPLandroid/widget/GridLayout$4;-><init>()V
 HSPLandroid/widget/GridLayout$6;-><init>()V
 HSPLandroid/widget/GridLayout$7$1;->getOffset(Landroid/widget/GridLayout;Landroid/view/View;Landroid/widget/GridLayout$Alignment;IZ)I
@@ -18076,6 +18858,7 @@
 HSPLandroid/widget/ImageView;->drawableStateChanged()V
 HSPLandroid/widget/ImageView;->getBaseline()I
 HSPLandroid/widget/ImageView;->getDrawable()Landroid/graphics/drawable/Drawable;
+HSPLandroid/widget/ImageView;->getImageMatrix()Landroid/graphics/Matrix;
 HSPLandroid/widget/ImageView;->getScaleType()Landroid/widget/ImageView$ScaleType;
 HSPLandroid/widget/ImageView;->hasOverlappingRendering()Z
 HSPLandroid/widget/ImageView;->initImageView()V
@@ -18098,10 +18881,12 @@
 HSPLandroid/widget/ImageView;->setColorFilter(I)V
 HSPLandroid/widget/ImageView;->setColorFilter(ILandroid/graphics/PorterDuff$Mode;)V
 HSPLandroid/widget/ImageView;->setColorFilter(Landroid/graphics/ColorFilter;)V
+HSPLandroid/widget/ImageView;->setCropToPadding(Z)V
 HSPLandroid/widget/ImageView;->setFrame(IIII)Z
 HSPLandroid/widget/ImageView;->setImageAlpha(I)V
 HSPLandroid/widget/ImageView;->setImageBitmap(Landroid/graphics/Bitmap;)V
 HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ImageView;->setImageIcon(Landroid/graphics/drawable/Icon;)V
 HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V
 HSPLandroid/widget/ImageView;->setImageResource(I)V
 HSPLandroid/widget/ImageView;->setImageTintList(Landroid/content/res/ColorStateList;)V
@@ -18132,6 +18917,8 @@
 HSPLandroid/widget/LinearLayout;->getAccessibilityClassName()Ljava/lang/CharSequence;
 HSPLandroid/widget/LinearLayout;->getBaseline()I
 HSPLandroid/widget/LinearLayout;->getChildrenSkipCount(Landroid/view/View;I)I
+HSPLandroid/widget/LinearLayout;->getDividerDrawable()Landroid/graphics/drawable/Drawable;
+HSPLandroid/widget/LinearLayout;->getGravity()I
 HSPLandroid/widget/LinearLayout;->getLocationOffset(Landroid/view/View;)I
 HSPLandroid/widget/LinearLayout;->getNextLocationOffset(Landroid/view/View;)I
 HSPLandroid/widget/LinearLayout;->getOrientation()I
@@ -18164,6 +18951,7 @@
 HSPLandroid/widget/ListView;->fillFromTop(I)Landroid/view/View;
 HSPLandroid/widget/ListView;->fillSpecific(II)Landroid/view/View;
 HSPLandroid/widget/ListView;->fillUp(II)Landroid/view/View;
+HSPLandroid/widget/ListView;->findMotionRow(I)I
 HSPLandroid/widget/ListView;->findViewInHeadersOrFooters(Ljava/util/ArrayList;I)Landroid/view/View;
 HSPLandroid/widget/ListView;->findViewTraversal(I)Landroid/view/View;
 HSPLandroid/widget/ListView;->getAdapter()Landroid/widget/Adapter;
@@ -18180,6 +18968,7 @@
 HSPLandroid/widget/ListView;->resetList()V
 HSPLandroid/widget/ListView;->setAdapter(Landroid/widget/ListAdapter;)V
 HSPLandroid/widget/ListView;->setCacheColorHint(I)V
+HSPLandroid/widget/ListView;->setDivider(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V
 HSPLandroid/widget/Magnifier$Builder;->applyDefaults()V
 HSPLandroid/widget/Magnifier;-><init>(Landroid/widget/Magnifier$Builder;)V
@@ -18207,20 +18996,31 @@
 HSPLandroid/widget/OverScroller;->isFinished()Z
 HSPLandroid/widget/OverScroller;->springBack(IIIIII)Z
 HSPLandroid/widget/PopupMenu;-><init>(Landroid/content/Context;Landroid/view/View;III)V
+HSPLandroid/widget/PopupMenu;->getMenu()Landroid/view/Menu;
 HSPLandroid/widget/PopupMenu;->getMenuInflater()Landroid/view/MenuInflater;
+HSPLandroid/widget/PopupMenu;->inflate(I)V
+HSPLandroid/widget/PopupMenu;->setOnMenuItemClickListener(Landroid/widget/PopupMenu$OnMenuItemClickListener;)V
 HSPLandroid/widget/PopupWindow;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
+HSPLandroid/widget/PopupWindow;->dismiss()V
 HSPLandroid/widget/PopupWindow;->getTransition(I)Landroid/transition/Transition;
 HSPLandroid/widget/PopupWindow;->isShowing()Z
+HSPLandroid/widget/PopupWindow;->setAttachedInDecor(Z)V
 HSPLandroid/widget/PopupWindow;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/PopupWindow;->setContentView(Landroid/view/View;)V
 HSPLandroid/widget/PopupWindow;->setEnterTransition(Landroid/transition/Transition;)V
 HSPLandroid/widget/PopupWindow;->setExitTransition(Landroid/transition/Transition;)V
+HSPLandroid/widget/PopupWindow;->setFocusable(Z)V
+HSPLandroid/widget/PopupWindow;->setInputMethodMode(I)V
 HSPLandroid/widget/ProgressBar$SavedState$1;-><init>()V
+HSPLandroid/widget/ProgressBar$SavedState;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/widget/ProgressBar;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/ProgressBar;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/ProgressBar;->applyIndeterminateTint()V
+HSPLandroid/widget/ProgressBar;->applyPrimaryProgressTint()V
 HSPLandroid/widget/ProgressBar;->doRefreshProgress(IIZZZ)V
 HSPLandroid/widget/ProgressBar;->drawTrack(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/ProgressBar;->drawableStateChanged()V
+HSPLandroid/widget/ProgressBar;->getCurrentDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/widget/ProgressBar;->getIndeterminateDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/widget/ProgressBar;->getMax()I
 HSPLandroid/widget/ProgressBar;->getMin()I
@@ -18267,9 +19067,15 @@
 HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(II)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->access$100(Landroid/widget/RelativeLayout$LayoutParams;)I
+HSPLandroid/widget/RelativeLayout$LayoutParams;->access$112(Landroid/widget/RelativeLayout$LayoutParams;I)I
 HSPLandroid/widget/RelativeLayout$LayoutParams;->access$200(Landroid/widget/RelativeLayout$LayoutParams;)I
+HSPLandroid/widget/RelativeLayout$LayoutParams;->access$212(Landroid/widget/RelativeLayout$LayoutParams;I)I
 HSPLandroid/widget/RelativeLayout$LayoutParams;->access$300(Landroid/widget/RelativeLayout$LayoutParams;)I
+HSPLandroid/widget/RelativeLayout$LayoutParams;->access$302(Landroid/widget/RelativeLayout$LayoutParams;I)I
+HSPLandroid/widget/RelativeLayout$LayoutParams;->access$312(Landroid/widget/RelativeLayout$LayoutParams;I)I
 HSPLandroid/widget/RelativeLayout$LayoutParams;->access$400(Landroid/widget/RelativeLayout$LayoutParams;)I
+HSPLandroid/widget/RelativeLayout$LayoutParams;->access$402(Landroid/widget/RelativeLayout$LayoutParams;I)I
+HSPLandroid/widget/RelativeLayout$LayoutParams;->access$412(Landroid/widget/RelativeLayout$LayoutParams;I)I
 HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(II)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->getRules()[I
@@ -18303,6 +19109,7 @@
 HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
 HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
 HSPLandroid/widget/RelativeLayout;->requestLayout()V
+HSPLandroid/widget/RelativeLayout;->setGravity(I)V
 HSPLandroid/widget/RelativeLayout;->shouldDelayChildPressedState()Z
 HSPLandroid/widget/RelativeLayout;->sortChildren()V
 HSPLandroid/widget/RemoteViews$1;-><init>()V
@@ -18311,7 +19118,7 @@
 HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/widget/RemoteViews$Action;->hasSameAppInfo(Landroid/content/pm/ApplicationInfo;)Z
 HSPLandroid/widget/RemoteViews$Action;->setBitmapCache(Landroid/widget/RemoteViews$BitmapCache;)V
-PLandroid/widget/RemoteViews$Action;->visitUris(Ljava/util/function/Consumer;)V
+HPLandroid/widget/RemoteViews$Action;->visitUris(Ljava/util/function/Consumer;)V
 HSPLandroid/widget/RemoteViews$BitmapCache;->getBitmapForId(I)Landroid/graphics/Bitmap;
 HSPLandroid/widget/RemoteViews$BitmapCache;->getBitmapId(Landroid/graphics/Bitmap;)I
 HPLandroid/widget/RemoteViews$BitmapCache;->getBitmapMemory()I
@@ -18328,7 +19135,7 @@
 HSPLandroid/widget/RemoteViews$ReflectionAction;->apply(Landroid/view/View;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)V
 HSPLandroid/widget/RemoteViews$ReflectionAction;->getActionTag()I
 HSPLandroid/widget/RemoteViews$ReflectionAction;->getParameterType()Ljava/lang/Class;
-PLandroid/widget/RemoteViews$ReflectionAction;->visitUris(Ljava/util/function/Consumer;)V
+HPLandroid/widget/RemoteViews$ReflectionAction;->visitUris(Ljava/util/function/Consumer;)V
 HSPLandroid/widget/RemoteViews$ReflectionAction;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/widget/RemoteViews$RemoteResponse;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/widget/RemoteViews$RemoteResponse;->writeToParcel(Landroid/os/Parcel;I)V
@@ -18339,6 +19146,8 @@
 HSPLandroid/widget/RemoteViews$TextViewSizeAction;->getActionTag()I
 HSPLandroid/widget/RemoteViews$TextViewSizeAction;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/widget/RemoteViews$ViewGroupActionAdd;-><init>(Landroid/widget/RemoteViews;Landroid/os/Parcel;Landroid/widget/RemoteViews$BitmapCache;Landroid/content/pm/ApplicationInfo;ILjava/util/Map;)V
+HSPLandroid/widget/RemoteViews$ViewPaddingAction;-><init>(Landroid/widget/RemoteViews;Landroid/os/Parcel;)V
+HSPLandroid/widget/RemoteViews$ViewPaddingAction;->apply(Landroid/view/View;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)V
 HSPLandroid/widget/RemoteViews;-><init>(Landroid/os/Parcel;Landroid/widget/RemoteViews$BitmapCache;Landroid/content/pm/ApplicationInfo;ILjava/util/Map;)V
 HSPLandroid/widget/RemoteViews;-><init>(Landroid/widget/RemoteViews;)V
 HSPLandroid/widget/RemoteViews;-><init>(Ljava/lang/String;I)V
@@ -18352,6 +19161,7 @@
 HSPLandroid/widget/RemoteViews;->getMethod(Landroid/view/View;Ljava/lang/String;Ljava/lang/Class;Z)Ljava/lang/invoke/MethodHandle;
 HSPLandroid/widget/RemoteViews;->getPackage()Ljava/lang/String;
 HSPLandroid/widget/RemoteViews;->hasFlags(I)Z
+HSPLandroid/widget/RemoteViews;->hasSameAppInfo(Landroid/content/pm/ApplicationInfo;)Z
 HSPLandroid/widget/RemoteViews;->inflateView(Landroid/content/Context;Landroid/widget/RemoteViews;Landroid/view/ViewGroup;I)Landroid/view/View;
 HSPLandroid/widget/RemoteViews;->onLoadClass(Ljava/lang/Class;)Z
 HSPLandroid/widget/RemoteViews;->performApply(Landroid/view/View;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)V
@@ -18366,7 +19176,7 @@
 HSPLandroid/widget/RemoteViews;->setOnClickResponse(ILandroid/widget/RemoteViews$RemoteResponse;)V
 HSPLandroid/widget/RemoteViews;->setTextViewText(ILjava/lang/CharSequence;)V
 HSPLandroid/widget/RemoteViews;->setViewVisibility(II)V
-PLandroid/widget/RemoteViews;->visitUris(Ljava/util/function/Consumer;)V
+HPLandroid/widget/RemoteViews;->visitUris(Ljava/util/function/Consumer;)V
 HSPLandroid/widget/RemoteViews;->writeActionsToParcel(Landroid/os/Parcel;)V
 HSPLandroid/widget/RemoteViews;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/widget/RtlSpacingHelper;->getEnd()I
@@ -18384,12 +19194,14 @@
 HSPLandroid/widget/ScrollBarDrawable;->onStateChange([I)Z
 HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ScrollBarDrawable;->setAlpha(I)V
+HSPLandroid/widget/ScrollBarDrawable;->setAlwaysDrawVerticalTrack(Z)V
 HSPLandroid/widget/ScrollBarDrawable;->setHorizontalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ScrollBarDrawable;->setHorizontalTrackDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ScrollBarDrawable;->setParameters(IIIZ)V
 HSPLandroid/widget/ScrollBarDrawable;->setVerticalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ScrollBarDrawable;->setVerticalTrackDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ScrollView$SavedState$1;-><init>()V
+HSPLandroid/widget/ScrollView$SavedState;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/widget/ScrollView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/ScrollView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/ScrollView;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
@@ -18398,6 +19210,7 @@
 HSPLandroid/widget/ScrollView;->computeVerticalScrollOffset()I
 HSPLandroid/widget/ScrollView;->computeVerticalScrollRange()I
 HSPLandroid/widget/ScrollView;->draw(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/ScrollView;->getAccessibilityClassName()Ljava/lang/CharSequence;
 HSPLandroid/widget/ScrollView;->initScrollView()V
 HSPLandroid/widget/ScrollView;->measureChildWithMargins(Landroid/view/View;IIII)V
 HSPLandroid/widget/ScrollView;->onDetachedFromWindow()V
@@ -18409,9 +19222,11 @@
 HSPLandroid/widget/ScrollView;->requestLayout()V
 HSPLandroid/widget/ScrollView;->scrollTo(II)V
 HSPLandroid/widget/ScrollView;->setFillViewport(Z)V
+HSPLandroid/widget/ScrollView;->shouldDelayChildPressedState()Z
 HSPLandroid/widget/Scroller$ViscousFluidInterpolator;->viscousFluid(F)F
 HSPLandroid/widget/Scroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;)V
 HSPLandroid/widget/Scroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;Z)V
+HSPLandroid/widget/Scroller;->computeScrollOffset()Z
 HSPLandroid/widget/Scroller;->isFinished()Z
 HSPLandroid/widget/SeekBar;->onProgressRefresh(FZI)V
 HSPLandroid/widget/SeekBar;->setOnSeekBarChangeListener(Landroid/widget/SeekBar$OnSeekBarChangeListener;)V
@@ -18422,6 +19237,10 @@
 HSPLandroid/widget/Space;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/Space;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/Space;->onMeasure(II)V
+HSPLandroid/widget/SpellChecker;-><init>(Landroid/widget/TextView;)V
+HSPLandroid/widget/SpellChecker;->closeSession()V
+HSPLandroid/widget/SpellChecker;->resetSession()V
+HSPLandroid/widget/SpellChecker;->spellCheck(II)V
 HSPLandroid/widget/Switch$1;-><init>(Ljava/lang/String;)V
 HSPLandroid/widget/Switch;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/Switch;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
@@ -18523,12 +19342,16 @@
 HSPLandroid/widget/TextView;->getLineSpacingExtra()F
 HSPLandroid/widget/TextView;->getLineSpacingMultiplier()F
 HSPLandroid/widget/TextView;->getMaxEms()I
+HSPLandroid/widget/TextView;->getMaxHeight()I
 HSPLandroid/widget/TextView;->getMaxLines()I
+HSPLandroid/widget/TextView;->getMaxWidth()I
 HSPLandroid/widget/TextView;->getMinEms()I
 HSPLandroid/widget/TextView;->getPaint()Landroid/text/TextPaint;
 HSPLandroid/widget/TextView;->getSelectionEnd()I
 HSPLandroid/widget/TextView;->getSelectionStart()I
+HSPLandroid/widget/TextView;->getSpellCheckerLocale()Ljava/util/Locale;
 HSPLandroid/widget/TextView;->getText()Ljava/lang/CharSequence;
+HSPLandroid/widget/TextView;->getTextColors()Landroid/content/res/ColorStateList;
 HSPLandroid/widget/TextView;->getTextCursorDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;
 HSPLandroid/widget/TextView;->getTextLocale()Ljava/util/Locale;
@@ -18574,7 +19397,9 @@
 HSPLandroid/widget/TextView;->onEndBatchEdit()V
 HSPLandroid/widget/TextView;->onFocusChanged(ZILandroid/graphics/Rect;)V
 HSPLandroid/widget/TextView;->onLayout(ZIIII)V
+HSPLandroid/widget/TextView;->onLocaleChanged()V
 HSPLandroid/widget/TextView;->onMeasure(II)V
+HSPLandroid/widget/TextView;->onPopulateAccessibilityEventInternal(Landroid/view/accessibility/AccessibilityEvent;)V
 HSPLandroid/widget/TextView;->onPreDraw()Z
 HSPLandroid/widget/TextView;->onProvideStructure(Landroid/view/ViewStructure;II)V
 HSPLandroid/widget/TextView;->onResolveDrawables(I)V
@@ -18662,6 +19487,7 @@
 HSPLandroid/widget/TextView;->setTypefaceFromAttrs(Landroid/graphics/Typeface;Ljava/lang/String;III)V
 HSPLandroid/widget/TextView;->setupAutoSizeText()Z
 HSPLandroid/widget/TextView;->setupAutoSizeUniformPresetSizesConfiguration()Z
+HSPLandroid/widget/TextView;->shouldAdvanceFocusOnEnter()Z
 HSPLandroid/widget/TextView;->spanChange(Landroid/text/Spanned;Ljava/lang/Object;IIII)V
 HSPLandroid/widget/TextView;->startMarquee()V
 HSPLandroid/widget/TextView;->stopMarquee()V
@@ -18728,6 +19554,7 @@
 HSPLandroid/widget/Toolbar;->onSaveInstanceState()Landroid/os/Parcelable;
 HSPLandroid/widget/Toolbar;->setContentInsetsRelative(II)V
 HSPLandroid/widget/Toolbar;->setLogo(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/Toolbar;->setMenuCallbacks(Lcom/android/internal/view/menu/MenuPresenter$Callback;Lcom/android/internal/view/menu/MenuBuilder$Callback;)V
 HSPLandroid/widget/Toolbar;->setNavigationContentDescription(Ljava/lang/CharSequence;)V
 HSPLandroid/widget/Toolbar;->setNavigationIcon(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/Toolbar;->setNavigationOnClickListener(Landroid/view/View$OnClickListener;)V
@@ -18741,10 +19568,13 @@
 HSPLandroid/widget/Toolbar;->shouldLayout(Landroid/view/View;)Z
 HSPLandroid/widget/ViewAnimator;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/ViewAnimator;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/widget/ViewAnimator;->getBaseline()I
+HSPLandroid/widget/ViewAnimator;->getCurrentView()Landroid/view/View;
 HSPLandroid/widget/ViewAnimator;->setAnimateFirstView(Z)V
 HSPLandroid/widget/ViewAnimator;->setDisplayedChild(I)V
 HSPLandroid/widget/ViewAnimator;->showOnly(I)V
 HSPLandroid/widget/ViewAnimator;->showOnly(IZ)V
+HSPLandroid/widget/ViewSwitcher;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/ViewSwitcher;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
 PLcom/android/framework/protobuf/nano/CodedInputByteBufferNano;->checkLastTagWas(I)V
 PLcom/android/framework/protobuf/nano/CodedInputByteBufferNano;->readRawVarint32()I
@@ -18776,11 +19606,11 @@
 HPLcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;->writeStringNoTag(Ljava/lang/String;)V
 HPLcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;->writeTag(II)V
 HPLcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;->writeUInt32NoTag(I)V
-PLcom/android/framework/protobuf/nano/MessageNano;->getCachedSize()I
-PLcom/android/framework/protobuf/nano/MessageNano;->getSerializedSize()I
-PLcom/android/framework/protobuf/nano/MessageNano;->mergeFrom(Lcom/android/framework/protobuf/nano/MessageNano;[BII)Lcom/android/framework/protobuf/nano/MessageNano;
-PLcom/android/framework/protobuf/nano/MessageNano;->toByteArray(Lcom/android/framework/protobuf/nano/MessageNano;)[B
-PLcom/android/framework/protobuf/nano/MessageNano;->toByteArray(Lcom/android/framework/protobuf/nano/MessageNano;[BII)V
+HPLcom/android/framework/protobuf/nano/MessageNano;->getCachedSize()I
+HPLcom/android/framework/protobuf/nano/MessageNano;->getSerializedSize()I
+HPLcom/android/framework/protobuf/nano/MessageNano;->mergeFrom(Lcom/android/framework/protobuf/nano/MessageNano;[BII)Lcom/android/framework/protobuf/nano/MessageNano;
+HPLcom/android/framework/protobuf/nano/MessageNano;->toByteArray(Lcom/android/framework/protobuf/nano/MessageNano;)[B
+HPLcom/android/framework/protobuf/nano/MessageNano;->toByteArray(Lcom/android/framework/protobuf/nano/MessageNano;[BII)V
 HSPLcom/android/i18n/phonenumbers/AlternateFormatsCountryCodeSet;->getCountryCodeSet()Ljava/util/Set;
 HSPLcom/android/i18n/phonenumbers/CountryCodeToRegionCodeMap;->getCountryCodeToRegionCodeMap()Ljava/util/Map;
 HSPLcom/android/i18n/phonenumbers/MetadataManager$1;-><init>()V
@@ -18817,11 +19647,13 @@
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNationalSignificantNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNddPrefixForRegion(Ljava/lang/String;Z)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberDescByType(Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;
+HPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberType(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForCountryCode(I)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->hasFormattingPatternForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
+HPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberGeographical(Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;I)Z
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumberForRegion(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/lang/String;)Z
@@ -18914,6 +19746,7 @@
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->getCountryCodeSource()Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->getNationalNumber()J
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->getRawInput()Ljava/lang/String;
+HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->hasCountryCode()Z
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->hasCountryCodeSource()Z
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->hasExtension()Z
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->hasRawInput()Z
@@ -18943,6 +19776,7 @@
 HSPLcom/android/ims/ImsConfig;->addConfigCallback(Landroid/telephony/ims/ProvisioningManager$Callback;)V
 HSPLcom/android/ims/ImsConfig;->addConfigCallback(Landroid/telephony/ims/aidl/IImsConfigCallback;)V
 HSPLcom/android/ims/ImsConfig;->getConfigInt(I)I
+HSPLcom/android/ims/ImsConfig;->getProvisionedValue(I)I
 HSPLcom/android/ims/ImsConfig;->setConfig(II)I
 HSPLcom/android/ims/ImsConfig;->setProvisionedValue(II)I
 HSPLcom/android/ims/ImsConfigListener$Stub;-><init>()V
@@ -18987,11 +19821,13 @@
 HSPLcom/android/ims/ImsManager;->isTtyOnVoLteCapable()Z
 HSPLcom/android/ims/ImsManager;->isTurnOffImsAllowedByPlatform()Z
 HSPLcom/android/ims/ImsManager;->isVolteEnabledByPlatform()Z
+HSPLcom/android/ims/ImsManager;->isVolteProvisionedOnDevice()Z
 HSPLcom/android/ims/ImsManager;->isVtEnabledByPlatform()Z
 HSPLcom/android/ims/ImsManager;->isVtEnabledByUser()Z
 HSPLcom/android/ims/ImsManager;->isWfcEnabledByPlatform()Z
 HSPLcom/android/ims/ImsManager;->isWfcEnabledByUser()Z
 HSPLcom/android/ims/ImsManager;->isWfcRoamingEnabledByUser()Z
+HSPLcom/android/ims/ImsManager;->lambda$setRttConfig$4$ImsManager(ZI)V
 HSPLcom/android/ims/ImsManager;->lambda$setWfcModeInternal$1$ImsManager(I)V
 HSPLcom/android/ims/ImsManager;->lambda$setWfcRoamingSettingInternal$2$ImsManager(I)V
 HSPLcom/android/ims/ImsManager;->onSmsReady()V
@@ -19061,6 +19897,7 @@
 HSPLcom/android/ims/internal/IImsEcbmListener$Stub;-><init>()V
 HSPLcom/android/ims/internal/IImsExternalCallStateListener$Stub;-><init>()V
 HSPLcom/android/ims/internal/IImsFeatureStatusCallback$Stub;-><init>()V
+HSPLcom/android/ims/internal/IImsFeatureStatusCallback$Stub;->asBinder()Landroid/os/IBinder;
 HSPLcom/android/ims/internal/IImsMultiEndpoint$Stub;-><init>()V
 HSPLcom/android/ims/internal/IImsServiceFeatureCallback$Stub$Proxy;->imsFeatureCreated(II)V
 HSPLcom/android/ims/internal/IImsServiceFeatureCallback$Stub;-><init>()V
@@ -19097,10 +19934,20 @@
 HSPLcom/android/internal/accessibility/AccessibilityShortcutController;->setCurrentUser(I)V
 HSPLcom/android/internal/alsa/AlsaCardsParser;-><init>()V
 HSPLcom/android/internal/alsa/LineTokenizer;-><init>(Ljava/lang/String;)V
+HSPLcom/android/internal/app/AlertController;-><init>(Landroid/content/Context;Landroid/content/DialogInterface;Landroid/view/Window;)V
+HSPLcom/android/internal/app/AlertController;->create(Landroid/content/Context;Landroid/content/DialogInterface;Landroid/view/Window;)Lcom/android/internal/app/AlertController;
+HSPLcom/android/internal/app/AlertController;->installContent()V
+HSPLcom/android/internal/app/AlertController;->resolvePanel(Landroid/view/View;Landroid/view/View;)Landroid/view/ViewGroup;
+HSPLcom/android/internal/app/AlertController;->setBackground(Landroid/content/res/TypedArray;Landroid/view/View;Landroid/view/View;Landroid/view/View;Landroid/view/View;ZZZ)V
+HSPLcom/android/internal/app/AlertController;->setupButtons(Landroid/view/ViewGroup;)V
+HSPLcom/android/internal/app/AlertController;->setupContent(Landroid/view/ViewGroup;)V
+HSPLcom/android/internal/app/AlertController;->setupCustomContent(Landroid/view/ViewGroup;)V
+HSPLcom/android/internal/app/AlertController;->setupTitle(Landroid/view/ViewGroup;)V
+HSPLcom/android/internal/app/AlertController;->setupView()V
 HSPLcom/android/internal/app/AssistUtils;-><init>(Landroid/content/Context;)V
 HSPLcom/android/internal/app/AssistUtils;->getAssistComponentForUser(I)Landroid/content/ComponentName;
-PLcom/android/internal/app/AssistUtils;->isPreinstalledAssistant(Landroid/content/Context;Landroid/content/ComponentName;)Z
-PLcom/android/internal/app/AssistUtils;->shouldDisclose(Landroid/content/Context;Landroid/content/ComponentName;)Z
+HPLcom/android/internal/app/AssistUtils;->isPreinstalledAssistant(Landroid/content/Context;Landroid/content/ComponentName;)Z
+HPLcom/android/internal/app/AssistUtils;->shouldDisclose(Landroid/content/Context;Landroid/content/ComponentName;)Z
 HSPLcom/android/internal/app/IAppOpsActiveCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLcom/android/internal/app/IAppOpsActiveCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HPLcom/android/internal/app/IAppOpsActiveCallback$Stub$Proxy;->opActiveChanged(IILjava/lang/String;Z)V
@@ -19125,16 +19972,18 @@
 HSPLcom/android/internal/app/IAppOpsService$Stub;-><init>()V
 HSPLcom/android/internal/app/IAppOpsService$Stub;->asBinder()Landroid/os/IBinder;
 HSPLcom/android/internal/app/IAppOpsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IAppOpsService;
-PLcom/android/internal/app/IAppOpsService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLcom/android/internal/app/IAppOpsService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLcom/android/internal/app/IAppOpsService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
-PLcom/android/internal/app/IBatteryStats$Stub$Proxy;->getCellularBatteryStats()Landroid/os/connectivity/CellularBatteryStats;
+HPLcom/android/internal/app/IBatteryStats$Stub$Proxy;->getCellularBatteryStats()Landroid/os/connectivity/CellularBatteryStats;
+HSPLcom/android/internal/app/IBatteryStats$Stub$Proxy;->getStatisticsStream()Landroid/os/ParcelFileDescriptor;
 HSPLcom/android/internal/app/IBatteryStats$Stub$Proxy;->isCharging()Z
+HSPLcom/android/internal/app/IBatteryStats$Stub$Proxy;->takeUidSnapshot(I)Landroid/os/health/HealthStatsParceler;
 HSPLcom/android/internal/app/IBatteryStats$Stub;-><init>()V
 HSPLcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats;
-PLcom/android/internal/app/IBatteryStats$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLcom/android/internal/app/IBatteryStats$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLcom/android/internal/app/IBatteryStats$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/app/ISoundTriggerService$Stub;-><init>()V
-PLcom/android/internal/app/ISoundTriggerService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLcom/android/internal/app/ISoundTriggerService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/app/IVoiceInteractionManagerService$Stub;-><init>()V
 HSPLcom/android/internal/app/IVoiceInteractionManagerService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/app/IVoiceInteractionSessionListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
@@ -19149,7 +19998,7 @@
 HSPLcom/android/internal/app/ProcessMap;->getMap()Landroid/util/ArrayMap;
 HSPLcom/android/internal/app/ProcessMap;->put(Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/Object;
 HSPLcom/android/internal/app/ProcessMap;->remove(Ljava/lang/String;I)Ljava/lang/Object;
-PLcom/android/internal/app/ProcessMap;->size()I
+HPLcom/android/internal/app/ProcessMap;->size()I
 HSPLcom/android/internal/app/ResolverActivity$ActionTitle;-><init>(Ljava/lang/String;ILjava/lang/String;III)V
 HSPLcom/android/internal/app/ResolverActivity;->getLabelRes(Ljava/lang/String;)I
 HSPLcom/android/internal/app/procstats/AssociationState$SourceKey;->equals(Ljava/lang/Object;)Z
@@ -19176,7 +20025,7 @@
 HSPLcom/android/internal/app/procstats/DurationsTable;->addDurations(Lcom/android/internal/app/procstats/DurationsTable;)V
 HSPLcom/android/internal/app/procstats/IProcessStats$Stub;-><init>()V
 HSPLcom/android/internal/app/procstats/IProcessStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/procstats/IProcessStats;
-PLcom/android/internal/app/procstats/IProcessStats$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLcom/android/internal/app/procstats/IProcessStats$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/app/procstats/ProcessState$1;-><init>()V
 HSPLcom/android/internal/app/procstats/ProcessState$PssAggr;-><init>()V
 HSPLcom/android/internal/app/procstats/ProcessState$PssAggr;->add(JJ)V
@@ -19201,18 +20050,18 @@
 HSPLcom/android/internal/app/procstats/ProcessState;->pullFixedProc(Landroid/util/ArrayMap;I)Lcom/android/internal/app/procstats/ProcessState;
 HSPLcom/android/internal/app/procstats/ProcessState;->pullFixedProc(Ljava/lang/String;)Lcom/android/internal/app/procstats/ProcessState;
 HSPLcom/android/internal/app/procstats/ProcessState;->readFromParcel(Landroid/os/Parcel;Z)Z
-PLcom/android/internal/app/procstats/ProcessState;->reportExcessiveCpu(Landroid/util/ArrayMap;)V
+HPLcom/android/internal/app/procstats/ProcessState;->reportExcessiveCpu(Landroid/util/ArrayMap;)V
 HSPLcom/android/internal/app/procstats/ProcessState;->setCombinedState(IJ)V
 HSPLcom/android/internal/app/procstats/ProcessState;->setState(IIJLandroid/util/ArrayMap;)V
 HSPLcom/android/internal/app/procstats/ProcessState;->toString()Ljava/lang/String;
 HPLcom/android/internal/app/procstats/ProcessState;->writeToParcel(Landroid/os/Parcel;J)V
 HSPLcom/android/internal/app/procstats/ProcessStats$1;-><init>()V
-PLcom/android/internal/app/procstats/ProcessStats$1;->createFromParcel(Landroid/os/Parcel;)Lcom/android/internal/app/procstats/ProcessStats;
-PLcom/android/internal/app/procstats/ProcessStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HPLcom/android/internal/app/procstats/ProcessStats$1;->createFromParcel(Landroid/os/Parcel;)Lcom/android/internal/app/procstats/ProcessStats;
+HPLcom/android/internal/app/procstats/ProcessStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLcom/android/internal/app/procstats/ProcessStats$PackageState;-><init>(Lcom/android/internal/app/procstats/ProcessStats;Ljava/lang/String;IJ)V
 HSPLcom/android/internal/app/procstats/ProcessStats$PackageState;->getAssociationStateLocked(Lcom/android/internal/app/procstats/ProcessState;Ljava/lang/String;)Lcom/android/internal/app/procstats/AssociationState;
 HSPLcom/android/internal/app/procstats/ProcessStats$TotalMemoryUseCollection;-><init>([I[I)V
-PLcom/android/internal/app/procstats/ProcessStats;-><init>(Landroid/os/Parcel;)V
+HPLcom/android/internal/app/procstats/ProcessStats;-><init>(Landroid/os/Parcel;)V
 HSPLcom/android/internal/app/procstats/ProcessStats;-><init>(Z)V
 HPLcom/android/internal/app/procstats/ProcessStats;->add(Lcom/android/internal/app/procstats/ProcessStats;)V
 HSPLcom/android/internal/app/procstats/ProcessStats;->addSysMemUsage(JJJJJ)V
@@ -19237,7 +20086,7 @@
 HSPLcom/android/internal/app/procstats/ProcessStats;->updateTrackingAssociationsLocked(IJ)V
 HPLcom/android/internal/app/procstats/ProcessStats;->writeCommonString(Landroid/os/Parcel;Ljava/lang/String;)V
 HPLcom/android/internal/app/procstats/ProcessStats;->writeCompactedLongArray(Landroid/os/Parcel;[JI)V
-PLcom/android/internal/app/procstats/ProcessStats;->writeToParcel(Landroid/os/Parcel;I)V
+HPLcom/android/internal/app/procstats/ProcessStats;->writeToParcel(Landroid/os/Parcel;I)V
 HPLcom/android/internal/app/procstats/ProcessStats;->writeToParcel(Landroid/os/Parcel;JI)V
 HSPLcom/android/internal/app/procstats/PssTable;->mergeStats(IIJJJJJJJJJ)V
 HPLcom/android/internal/app/procstats/PssTable;->mergeStats(Lcom/android/internal/app/procstats/PssTable;)V
@@ -19284,7 +20133,7 @@
 HPLcom/android/internal/app/procstats/SparseMappingTable;->writeToParcel(Landroid/os/Parcel;)V
 HSPLcom/android/internal/app/procstats/SysMemUsageTable;->getTotalMemUsage()[J
 HSPLcom/android/internal/app/procstats/SysMemUsageTable;->mergeStats(I[JI)V
-PLcom/android/internal/app/procstats/SysMemUsageTable;->mergeStats(Lcom/android/internal/app/procstats/SysMemUsageTable;)V
+HPLcom/android/internal/app/procstats/SysMemUsageTable;->mergeStats(Lcom/android/internal/app/procstats/SysMemUsageTable;)V
 HSPLcom/android/internal/app/procstats/SysMemUsageTable;->mergeSysMemUsage([JI[JI)V
 HSPLcom/android/internal/appwidget/IAppWidgetService$Stub$Proxy;->getAppWidgetIds(Landroid/content/ComponentName;)[I
 HSPLcom/android/internal/appwidget/IAppWidgetService$Stub$Proxy;->updateAppWidgetProvider(Landroid/content/ComponentName;Landroid/widget/RemoteViews;)V
@@ -19309,35 +20158,35 @@
 HPLcom/android/internal/backup/IBackupTransport$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/backup/IBackupTransport;
 HSPLcom/android/internal/content/NativeLibraryHelper$Handle;->close()V
 HSPLcom/android/internal/content/NativeLibraryHelper$Handle;->create(Landroid/content/pm/PackageParser$Package;)Lcom/android/internal/content/NativeLibraryHelper$Handle;
-PLcom/android/internal/content/NativeLibraryHelper$Handle;->create(Ljava/io/File;)Lcom/android/internal/content/NativeLibraryHelper$Handle;
+HPLcom/android/internal/content/NativeLibraryHelper$Handle;->create(Ljava/io/File;)Lcom/android/internal/content/NativeLibraryHelper$Handle;
 HSPLcom/android/internal/content/NativeLibraryHelper$Handle;->create(Ljava/util/List;ZZZ)Lcom/android/internal/content/NativeLibraryHelper$Handle;
 HSPLcom/android/internal/content/NativeLibraryHelper$Handle;->finalize()V
 HSPLcom/android/internal/content/NativeLibraryHelper;->copyNativeBinariesForSupportedAbi(Lcom/android/internal/content/NativeLibraryHelper$Handle;Ljava/io/File;[Ljava/lang/String;Z)I
-PLcom/android/internal/content/NativeLibraryHelper;->copyNativeBinariesWithOverride(Lcom/android/internal/content/NativeLibraryHelper$Handle;Ljava/io/File;Ljava/lang/String;)I
+HPLcom/android/internal/content/NativeLibraryHelper;->copyNativeBinariesWithOverride(Lcom/android/internal/content/NativeLibraryHelper$Handle;Ljava/io/File;Ljava/lang/String;)I
 HSPLcom/android/internal/content/NativeLibraryHelper;->createNativeLibrarySubdir(Ljava/io/File;)V
 HSPLcom/android/internal/content/NativeLibraryHelper;->findSupportedAbi(Lcom/android/internal/content/NativeLibraryHelper$Handle;[Ljava/lang/String;)I
 HSPLcom/android/internal/content/NativeLibraryHelper;->hasRenderscriptBitcode(Lcom/android/internal/content/NativeLibraryHelper$Handle;)Z
-PLcom/android/internal/content/NativeLibraryHelper;->removeNativeBinariesFromDirLI(Ljava/io/File;Z)V
-PLcom/android/internal/content/NativeLibraryHelper;->sumNativeBinariesWithOverride(Lcom/android/internal/content/NativeLibraryHelper$Handle;Ljava/lang/String;)J
+HPLcom/android/internal/content/NativeLibraryHelper;->removeNativeBinariesFromDirLI(Ljava/io/File;Z)V
+HPLcom/android/internal/content/NativeLibraryHelper;->sumNativeBinariesWithOverride(Lcom/android/internal/content/NativeLibraryHelper$Handle;Ljava/lang/String;)J
 PLcom/android/internal/content/PackageHelper$1;->getAllow3rdPartyOnInternalConfig(Landroid/content/Context;)Z
 PLcom/android/internal/content/PackageHelper$1;->getExistingAppInfo(Landroid/content/Context;Ljava/lang/String;)Landroid/content/pm/ApplicationInfo;
 PLcom/android/internal/content/PackageHelper$1;->getForceAllowOnExternalSetting(Landroid/content/Context;)Z
 PLcom/android/internal/content/PackageHelper$1;->getStorageManager(Landroid/content/Context;)Landroid/os/storage/StorageManager;
-PLcom/android/internal/content/PackageHelper;->calculateInstalledSize(Landroid/content/pm/PackageParser$PackageLite;Lcom/android/internal/content/NativeLibraryHelper$Handle;Ljava/lang/String;)J
-PLcom/android/internal/content/PackageHelper;->calculateInstalledSize(Landroid/content/pm/PackageParser$PackageLite;Ljava/lang/String;)J
-PLcom/android/internal/content/PackageHelper;->calculateInstalledSize(Landroid/content/pm/PackageParser$PackageLite;Ljava/lang/String;Ljava/io/FileDescriptor;)J
-PLcom/android/internal/content/PackageHelper;->fitsOnInternal(Landroid/content/Context;Landroid/content/pm/PackageInstaller$SessionParams;)Z
-PLcom/android/internal/content/PackageHelper;->getDefaultTestableInterface()Lcom/android/internal/content/PackageHelper$TestableInterface;
+HPLcom/android/internal/content/PackageHelper;->calculateInstalledSize(Landroid/content/pm/PackageParser$PackageLite;Lcom/android/internal/content/NativeLibraryHelper$Handle;Ljava/lang/String;)J
+HPLcom/android/internal/content/PackageHelper;->calculateInstalledSize(Landroid/content/pm/PackageParser$PackageLite;Ljava/lang/String;)J
+HPLcom/android/internal/content/PackageHelper;->calculateInstalledSize(Landroid/content/pm/PackageParser$PackageLite;Ljava/lang/String;Ljava/io/FileDescriptor;)J
+HPLcom/android/internal/content/PackageHelper;->fitsOnInternal(Landroid/content/Context;Landroid/content/pm/PackageInstaller$SessionParams;)Z
+HPLcom/android/internal/content/PackageHelper;->getDefaultTestableInterface()Lcom/android/internal/content/PackageHelper$TestableInterface;
 HSPLcom/android/internal/content/PackageHelper;->getStorageManager()Landroid/os/storage/IStorageManager;
-PLcom/android/internal/content/PackageHelper;->resolveInstallLocation(Landroid/content/Context;Landroid/content/pm/PackageInstaller$SessionParams;)I
-PLcom/android/internal/content/PackageHelper;->resolveInstallLocation(Landroid/content/Context;Ljava/lang/String;IJI)I
-PLcom/android/internal/content/PackageHelper;->resolveInstallVolume(Landroid/content/Context;Landroid/content/pm/PackageInstaller$SessionParams;)Ljava/lang/String;
-PLcom/android/internal/content/PackageHelper;->resolveInstallVolume(Landroid/content/Context;Landroid/content/pm/PackageInstaller$SessionParams;Lcom/android/internal/content/PackageHelper$TestableInterface;)Ljava/lang/String;
+HPLcom/android/internal/content/PackageHelper;->resolveInstallLocation(Landroid/content/Context;Landroid/content/pm/PackageInstaller$SessionParams;)I
+HPLcom/android/internal/content/PackageHelper;->resolveInstallLocation(Landroid/content/Context;Ljava/lang/String;IJI)I
+HPLcom/android/internal/content/PackageHelper;->resolveInstallVolume(Landroid/content/Context;Landroid/content/pm/PackageInstaller$SessionParams;)Ljava/lang/String;
+HPLcom/android/internal/content/PackageHelper;->resolveInstallVolume(Landroid/content/Context;Landroid/content/pm/PackageInstaller$SessionParams;Lcom/android/internal/content/PackageHelper$TestableInterface;)Ljava/lang/String;
 HSPLcom/android/internal/content/PackageMonitor;-><init>()V
 HSPLcom/android/internal/content/PackageMonitor;->didSomePackagesChange()Z
 HSPLcom/android/internal/content/PackageMonitor;->getChangingUserId()I
 HSPLcom/android/internal/content/PackageMonitor;->getPackageName(Landroid/content/Intent;)Ljava/lang/String;
-PLcom/android/internal/content/PackageMonitor;->isComponentModified(Ljava/lang/String;)Z
+HPLcom/android/internal/content/PackageMonitor;->isComponentModified(Ljava/lang/String;)Z
 HSPLcom/android/internal/content/PackageMonitor;->isPackageAppearing(Ljava/lang/String;)I
 HSPLcom/android/internal/content/PackageMonitor;->isPackageDisappearing(Ljava/lang/String;)I
 HSPLcom/android/internal/content/PackageMonitor;->isPackageModified(Ljava/lang/String;)Z
@@ -19349,8 +20198,8 @@
 HSPLcom/android/internal/content/PackageMonitor;->onPackageDisappeared(Ljava/lang/String;I)V
 HSPLcom/android/internal/content/PackageMonitor;->onPackageModified(Ljava/lang/String;)V
 HSPLcom/android/internal/content/PackageMonitor;->onPackageRemoved(Ljava/lang/String;I)V
-PLcom/android/internal/content/PackageMonitor;->onPackageUpdateFinished(Ljava/lang/String;I)V
-PLcom/android/internal/content/PackageMonitor;->onPackageUpdateStarted(Ljava/lang/String;I)V
+HPLcom/android/internal/content/PackageMonitor;->onPackageUpdateFinished(Ljava/lang/String;I)V
+HPLcom/android/internal/content/PackageMonitor;->onPackageUpdateStarted(Ljava/lang/String;I)V
 HSPLcom/android/internal/content/PackageMonitor;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
 HSPLcom/android/internal/content/PackageMonitor;->onSomePackagesChanged()V
 HSPLcom/android/internal/content/PackageMonitor;->onUidRemoved(I)V
@@ -19388,7 +20237,7 @@
 HSPLcom/android/internal/infra/-$$Lambda$AbstractRemoteService$9IBVTCLLZgndvH7fu1P14PW1_1o;-><init>()V
 HSPLcom/android/internal/infra/-$$Lambda$AbstractRemoteService$9IBVTCLLZgndvH7fu1P14PW1_1o;->accept(Ljava/lang/Object;)V
 HSPLcom/android/internal/infra/-$$Lambda$AbstractRemoteService$MDW40b8CzodE5xRowI9wDEyXEnw;-><init>()V
-PLcom/android/internal/infra/-$$Lambda$AbstractRemoteService$MDW40b8CzodE5xRowI9wDEyXEnw;->accept(Ljava/lang/Object;)V
+HPLcom/android/internal/infra/-$$Lambda$AbstractRemoteService$MDW40b8CzodE5xRowI9wDEyXEnw;->accept(Ljava/lang/Object;)V
 HSPLcom/android/internal/infra/-$$Lambda$AbstractRemoteService$YSUzqqi1Pbrg2dlwMGMtKWbGXck;-><init>()V
 HSPLcom/android/internal/infra/-$$Lambda$AbstractRemoteService$YSUzqqi1Pbrg2dlwMGMtKWbGXck;->accept(Ljava/lang/Object;)V
 PLcom/android/internal/infra/-$$Lambda$EbzSql2RHkXox5Myj8A-7kLC4_A;-><init>()V
@@ -19400,16 +20249,18 @@
 HSPLcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;->finish()Z
 HSPLcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;->getService()Lcom/android/internal/infra/AbstractRemoteService;
 HSPLcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;->isFinal()Z
-PLcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;->onFinished()V
+HPLcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;->onFinished()V
 HPLcom/android/internal/infra/AbstractRemoteService$MyAsyncPendingRequest;->run()V
 HSPLcom/android/internal/infra/AbstractRemoteService$PendingRequest;-><init>(Lcom/android/internal/infra/AbstractRemoteService;)V
 HSPLcom/android/internal/infra/AbstractRemoteService$PendingRequest;->onFinished()V
 HSPLcom/android/internal/infra/AbstractRemoteService$RemoteServiceConnection;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
+HPLcom/android/internal/infra/AbstractRemoteService$RemoteServiceConnection;->onServiceDisconnected(Landroid/content/ComponentName;)V
 HSPLcom/android/internal/infra/AbstractRemoteService;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/content/ComponentName;ILcom/android/internal/infra/AbstractRemoteService$VultureCallback;Landroid/os/Handler;IZ)V
+HPLcom/android/internal/infra/AbstractRemoteService;->binderDied()V
 HSPLcom/android/internal/infra/AbstractRemoteService;->checkIfDestroyed()Z
 HSPLcom/android/internal/infra/AbstractRemoteService;->destroy()V
 HSPLcom/android/internal/infra/AbstractRemoteService;->finishRequest(Lcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;)V
-PLcom/android/internal/infra/AbstractRemoteService;->handleBinderDied()V
+HPLcom/android/internal/infra/AbstractRemoteService;->handleBinderDied()V
 HSPLcom/android/internal/infra/AbstractRemoteService;->handleEnsureBound()V
 HSPLcom/android/internal/infra/AbstractRemoteService;->handleEnsureUnbound()V
 HSPLcom/android/internal/infra/AbstractRemoteService;->handleOnConnectedStateChanged(Z)V
@@ -19418,16 +20269,16 @@
 HSPLcom/android/internal/infra/AbstractRemoteService;->scheduleBind()V
 HSPLcom/android/internal/infra/AbstractRemoteService;->scheduleRequest(Lcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;)V
 HSPLcom/android/internal/infra/AbstractRemoteService;->scheduleUnbind()V
-PLcom/android/internal/infra/AbstractRemoteService;->toString()Ljava/lang/String;
+HPLcom/android/internal/infra/AbstractRemoteService;->toString()Ljava/lang/String;
 HSPLcom/android/internal/infra/AbstractSinglePendingRequestRemoteService;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/content/ComponentName;ILcom/android/internal/infra/AbstractRemoteService$VultureCallback;Landroid/os/Handler;IZ)V
-PLcom/android/internal/infra/AbstractSinglePendingRequestRemoteService;->handleOnDestroy()V
-PLcom/android/internal/infra/AbstractSinglePendingRequestRemoteService;->handlePendingRequestWhileUnBound(Lcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;)V
-PLcom/android/internal/infra/AbstractSinglePendingRequestRemoteService;->handlePendingRequests()V
+HPLcom/android/internal/infra/AbstractSinglePendingRequestRemoteService;->handleOnDestroy()V
+HPLcom/android/internal/infra/AbstractSinglePendingRequestRemoteService;->handlePendingRequestWhileUnBound(Lcom/android/internal/infra/AbstractRemoteService$BasePendingRequest;)V
+HPLcom/android/internal/infra/AbstractSinglePendingRequestRemoteService;->handlePendingRequests()V
 HSPLcom/android/internal/infra/WhitelistHelper;->getWhitelistedComponents(Ljava/lang/String;)Landroid/util/ArraySet;
-PLcom/android/internal/infra/WhitelistHelper;->isWhitelisted(Landroid/content/ComponentName;)Z
+HPLcom/android/internal/infra/WhitelistHelper;->isWhitelisted(Landroid/content/ComponentName;)Z
 HSPLcom/android/internal/infra/WhitelistHelper;->isWhitelisted(Ljava/lang/String;)Z
-PLcom/android/internal/infra/WhitelistHelper;->setWhitelist(Landroid/util/ArraySet;Landroid/util/ArraySet;)V
-PLcom/android/internal/infra/WhitelistHelper;->setWhitelist(Ljava/util/List;Ljava/util/List;)V
+HPLcom/android/internal/infra/WhitelistHelper;->setWhitelist(Landroid/util/ArraySet;Landroid/util/ArraySet;)V
+HPLcom/android/internal/infra/WhitelistHelper;->setWhitelist(Ljava/util/List;Ljava/util/List;)V
 HSPLcom/android/internal/inputmethod/IInputMethodPrivilegedOperations$Stub$Proxy;->notifyUserAction()V
 HSPLcom/android/internal/inputmethod/IInputMethodPrivilegedOperations$Stub$Proxy;->reportFullscreenMode(Z)V
 HSPLcom/android/internal/inputmethod/IInputMethodPrivilegedOperations$Stub$Proxy;->reportStartInput(Landroid/os/IBinder;)V
@@ -19448,7 +20299,7 @@
 HSPLcom/android/internal/inputmethod/InputMethodPrivilegedOperationsRegistry;->put(Landroid/os/IBinder;Lcom/android/internal/inputmethod/InputMethodPrivilegedOperations;)V
 HSPLcom/android/internal/inputmethod/SubtypeLocaleUtils;->constructLocaleFromString(Ljava/lang/String;)Ljava/util/Locale;
 HSPLcom/android/internal/location/GpsNetInitiatedHandler$1;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
-PLcom/android/internal/location/GpsNetInitiatedHandler$2;->onCallStateChanged(ILjava/lang/String;)V
+HPLcom/android/internal/location/GpsNetInitiatedHandler$2;->onCallStateChanged(ILjava/lang/String;)V
 HSPLcom/android/internal/location/GpsNetInitiatedHandler;-><init>(Landroid/content/Context;Landroid/location/INetInitiatedListener;Z)V
 HSPLcom/android/internal/location/GpsNetInitiatedHandler;->setEmergencyExtensionSeconds(I)V
 HSPLcom/android/internal/location/GpsNetInitiatedHandler;->setSuplEsEnabled(Z)V
@@ -19458,7 +20309,7 @@
 HSPLcom/android/internal/location/ILocationProvider$Stub;-><init>()V
 HSPLcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
 HSPLcom/android/internal/location/ILocationProviderManager$Stub;-><init>()V
-PLcom/android/internal/location/ILocationProviderManager$Stub;->asBinder()Landroid/os/IBinder;
+HPLcom/android/internal/location/ILocationProviderManager$Stub;->asBinder()Landroid/os/IBinder;
 HPLcom/android/internal/location/ILocationProviderManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/location/ProviderProperties$1;-><init>()V
 HSPLcom/android/internal/location/ProviderProperties$1;->createFromParcel(Landroid/os/Parcel;)Lcom/android/internal/location/ProviderProperties;
@@ -19468,21 +20319,21 @@
 HSPLcom/android/internal/location/ProviderRequest$1;-><init>()V
 HSPLcom/android/internal/location/ProviderRequest;-><init>()V
 HPLcom/android/internal/location/ProviderRequest;->writeToParcel(Landroid/os/Parcel;I)V
-PLcom/android/internal/location/gnssmetrics/GnssMetrics$GnssPowerMetrics;->buildProto()Lcom/android/internal/location/nano/GnssLogsProto$PowerMetrics;
-PLcom/android/internal/location/gnssmetrics/GnssMetrics$GnssPowerMetrics;->getGpsBatteryStats()Landroid/os/connectivity/GpsBatteryStats;
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics$GnssPowerMetrics;->buildProto()Lcom/android/internal/location/nano/GnssLogsProto$PowerMetrics;
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics$GnssPowerMetrics;->getGpsBatteryStats()Landroid/os/connectivity/GpsBatteryStats;
 HPLcom/android/internal/location/gnssmetrics/GnssMetrics$GnssPowerMetrics;->reportSignalQuality([FI)V
-PLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->addItem(D)V
-PLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->getCount()I
-PLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->getMean()D
-PLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->getStandardDeviation()D
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->addItem(D)V
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->getCount()I
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->getMean()D
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->getStandardDeviation()D
 HSPLcom/android/internal/location/gnssmetrics/GnssMetrics$Statistics;->reset()V
 HSPLcom/android/internal/location/gnssmetrics/GnssMetrics;-><init>(Lcom/android/internal/app/IBatteryStats;)V
-PLcom/android/internal/location/gnssmetrics/GnssMetrics;->dumpGnssMetricsAsProtoString()Ljava/lang/String;
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics;->dumpGnssMetricsAsProtoString()Ljava/lang/String;
 HPLcom/android/internal/location/gnssmetrics/GnssMetrics;->logCn0([FI)V
-PLcom/android/internal/location/gnssmetrics/GnssMetrics;->logMissedReports(II)V
-PLcom/android/internal/location/gnssmetrics/GnssMetrics;->logPositionAccuracyMeters(F)V
-PLcom/android/internal/location/gnssmetrics/GnssMetrics;->logReceivedLocationStatus(Z)V
-PLcom/android/internal/location/gnssmetrics/GnssMetrics;->logTimeToFirstFixMilliSecs(I)V
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics;->logMissedReports(II)V
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics;->logPositionAccuracyMeters(F)V
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics;->logReceivedLocationStatus(Z)V
+HPLcom/android/internal/location/gnssmetrics/GnssMetrics;->logTimeToFirstFixMilliSecs(I)V
 HSPLcom/android/internal/location/gnssmetrics/GnssMetrics;->reset()V
 PLcom/android/internal/location/nano/GnssLogsProto$GnssLog;->clear()Lcom/android/internal/location/nano/GnssLogsProto$GnssLog;
 PLcom/android/internal/location/nano/GnssLogsProto$GnssLog;->computeSerializedSize()I
@@ -19495,6 +20346,7 @@
 HSPLcom/android/internal/logging/AndroidHandler;->publish(Ljava/util/logging/LogRecord;)V
 HSPLcom/android/internal/logging/EventLogTags;->writeCommitSysConfigFile(Ljava/lang/String;J)V
 HSPLcom/android/internal/logging/MetricsLogger;-><init>()V
+HSPLcom/android/internal/logging/MetricsLogger;->action(I)V
 HSPLcom/android/internal/logging/MetricsLogger;->action(II)V
 HSPLcom/android/internal/logging/MetricsLogger;->action(IZ)V
 HSPLcom/android/internal/logging/MetricsLogger;->action(Landroid/content/Context;II)V
@@ -19510,11 +20362,12 @@
 HSPLcom/android/internal/logging/MetricsLogger;->visible(Landroid/content/Context;I)V
 HSPLcom/android/internal/logging/MetricsLogger;->write(Landroid/metrics/LogMaker;)V
 HSPLcom/android/internal/net/INetworkWatchlistManager$Stub;-><init>()V
-PLcom/android/internal/net/INetworkWatchlistManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/net/INetworkWatchlistManager;
+HPLcom/android/internal/net/INetworkWatchlistManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/net/INetworkWatchlistManager;
 HSPLcom/android/internal/net/NetworkStatsFactory;-><init>()V
 HSPLcom/android/internal/net/NetworkStatsFactory;-><init>(Ljava/io/File;Z)V
 HSPLcom/android/internal/net/NetworkStatsFactory;->apply464xlatAdjustments(Landroid/net/NetworkStats;Landroid/net/NetworkStats;Z)V
 HPLcom/android/internal/net/NetworkStatsFactory;->augmentWithStackedInterfaces([Ljava/lang/String;)[Ljava/lang/String;
+HPLcom/android/internal/net/NetworkStatsFactory;->noteStackedIface(Ljava/lang/String;Ljava/lang/String;)V
 HSPLcom/android/internal/net/NetworkStatsFactory;->readBpfNetworkStatsDev()Landroid/net/NetworkStats;
 HSPLcom/android/internal/net/NetworkStatsFactory;->readNetworkStatsDetail(I[Ljava/lang/String;ILandroid/net/NetworkStats;)Landroid/net/NetworkStats;
 HSPLcom/android/internal/net/NetworkStatsFactory;->readNetworkStatsDetailInternal(I[Ljava/lang/String;ILandroid/net/NetworkStats;)Landroid/net/NetworkStats;
@@ -19543,6 +20396,7 @@
 HSPLcom/android/internal/os/AtomicDirectory;->startWrite()Ljava/io/File;
 HSPLcom/android/internal/os/AtomicDirectory;->throwIfSomeFilesOpen()V
 HSPLcom/android/internal/os/AtomicFile;-><init>(Ljava/io/File;)V
+HSPLcom/android/internal/os/AtomicFile;->delete()V
 HSPLcom/android/internal/os/AtomicFile;->exists()Z
 HSPLcom/android/internal/os/AtomicFile;->finishWrite(Ljava/io/FileOutputStream;)V
 HSPLcom/android/internal/os/AtomicFile;->openRead()Ljava/io/FileInputStream;
@@ -19554,7 +20408,7 @@
 HSPLcom/android/internal/os/BackgroundThread;->getExecutor()Ljava/util/concurrent/Executor;
 HSPLcom/android/internal/os/BackgroundThread;->getHandler()Landroid/os/Handler;
 HSPLcom/android/internal/os/BatterySipper$DrainType;-><init>(Ljava/lang/String;I)V
-PLcom/android/internal/os/BatterySipper$DrainType;->values()[Lcom/android/internal/os/BatterySipper$DrainType;
+HPLcom/android/internal/os/BatterySipper$DrainType;->values()[Lcom/android/internal/os/BatterySipper$DrainType;
 HSPLcom/android/internal/os/BatterySipper;->add(Lcom/android/internal/os/BatterySipper;)V
 HSPLcom/android/internal/os/BatterySipper;->compareTo(Lcom/android/internal/os/BatterySipper;)I
 HSPLcom/android/internal/os/BatterySipper;->compareTo(Ljava/lang/Object;)I
@@ -19563,6 +20417,7 @@
 HSPLcom/android/internal/os/BatterySipper;->sumPower()D
 HSPLcom/android/internal/os/BatteryStatsHelper$1;->compare(Lcom/android/internal/os/BatterySipper;Lcom/android/internal/os/BatterySipper;)I
 HSPLcom/android/internal/os/BatteryStatsHelper$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLcom/android/internal/os/BatteryStatsHelper;-><init>(Landroid/content/Context;Z)V
 HSPLcom/android/internal/os/BatteryStatsHelper;-><init>(Landroid/content/Context;ZZ)V
 HSPLcom/android/internal/os/BatteryStatsHelper;->addAmbientDisplayUsage()V
 HSPLcom/android/internal/os/BatteryStatsHelper;->addBluetoothUsage()V
@@ -19575,17 +20430,20 @@
 HSPLcom/android/internal/os/BatteryStatsHelper;->addWiFiUsage()V
 HSPLcom/android/internal/os/BatteryStatsHelper;->checkHasBluetoothPowerReporting(Landroid/os/BatteryStats;Lcom/android/internal/os/PowerProfile;)Z
 HSPLcom/android/internal/os/BatteryStatsHelper;->checkHasWifiPowerReporting(Landroid/os/BatteryStats;Lcom/android/internal/os/PowerProfile;)Z
-PLcom/android/internal/os/BatteryStatsHelper;->checkWifiOnly(Landroid/content/Context;)Z
+HPLcom/android/internal/os/BatteryStatsHelper;->checkWifiOnly(Landroid/content/Context;)Z
+HSPLcom/android/internal/os/BatteryStatsHelper;->clearStats()V
 HSPLcom/android/internal/os/BatteryStatsHelper;->convertMsToUs(J)J
 HSPLcom/android/internal/os/BatteryStatsHelper;->convertUsToMs(J)J
-PLcom/android/internal/os/BatteryStatsHelper;->create(Landroid/os/BatteryStats;)V
-PLcom/android/internal/os/BatteryStatsHelper;->getComputedPower()D
+HPLcom/android/internal/os/BatteryStatsHelper;->create(Landroid/os/BatteryStats;)V
+HSPLcom/android/internal/os/BatteryStatsHelper;->create(Landroid/os/Bundle;)V
+HPLcom/android/internal/os/BatteryStatsHelper;->getComputedPower()D
 HSPLcom/android/internal/os/BatteryStatsHelper;->getForegroundActivityTotalTimeUs(Landroid/os/BatteryStats$Uid;J)J
-PLcom/android/internal/os/BatteryStatsHelper;->getMaxDrainedPower()D
-PLcom/android/internal/os/BatteryStatsHelper;->getMinDrainedPower()D
-PLcom/android/internal/os/BatteryStatsHelper;->getPowerProfile()Lcom/android/internal/os/PowerProfile;
+HPLcom/android/internal/os/BatteryStatsHelper;->getMaxDrainedPower()D
+HPLcom/android/internal/os/BatteryStatsHelper;->getMinDrainedPower()D
+HPLcom/android/internal/os/BatteryStatsHelper;->getPowerProfile()Lcom/android/internal/os/PowerProfile;
 HSPLcom/android/internal/os/BatteryStatsHelper;->getProcessForegroundTimeMs(Landroid/os/BatteryStats$Uid;I)J
 HSPLcom/android/internal/os/BatteryStatsHelper;->getStats()Landroid/os/BatteryStats;
+HSPLcom/android/internal/os/BatteryStatsHelper;->getStats(Lcom/android/internal/app/IBatteryStats;)Lcom/android/internal/os/BatteryStatsImpl;
 HSPLcom/android/internal/os/BatteryStatsHelper;->getTotalPower()D
 HSPLcom/android/internal/os/BatteryStatsHelper;->getUsageList()Ljava/util/List;
 HSPLcom/android/internal/os/BatteryStatsHelper;->isTypeService(Lcom/android/internal/os/BatterySipper;)Z
@@ -19595,6 +20453,7 @@
 HSPLcom/android/internal/os/BatteryStatsHelper;->refreshStats(II)V
 HSPLcom/android/internal/os/BatteryStatsHelper;->refreshStats(ILandroid/util/SparseArray;)V
 HSPLcom/android/internal/os/BatteryStatsHelper;->refreshStats(ILandroid/util/SparseArray;JJ)V
+HSPLcom/android/internal/os/BatteryStatsHelper;->refreshStats(ILjava/util/List;)V
 HSPLcom/android/internal/os/BatteryStatsHelper;->removeHiddenBatterySippers(Ljava/util/List;)D
 HSPLcom/android/internal/os/BatteryStatsHelper;->shouldHideSipper(Lcom/android/internal/os/BatterySipper;)Z
 HSPLcom/android/internal/os/BatteryStatsHelper;->smearScreenBatterySipper(Ljava/util/List;Lcom/android/internal/os/BatterySipper;)V
@@ -19613,12 +20472,15 @@
 HSPLcom/android/internal/os/BatteryStatsHistory;->startIteratingHistory()Z
 HSPLcom/android/internal/os/BatteryStatsHistory;->writeToParcel(Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$1;-><init>(Lcom/android/internal/os/BatteryStatsImpl;)V
-PLcom/android/internal/os/BatteryStatsImpl$1;->run()V
+HPLcom/android/internal/os/BatteryStatsImpl$1;->run()V
 HSPLcom/android/internal/os/BatteryStatsImpl$2;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$3;->run()V
 HSPLcom/android/internal/os/BatteryStatsImpl$5;->run()V
 HSPLcom/android/internal/os/BatteryStatsImpl$6;-><init>()V
-PLcom/android/internal/os/BatteryStatsImpl$BatchTimer;->abortLastDuration(Lcom/android/internal/os/BatteryStatsImpl;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$6;->createFromParcel(Landroid/os/Parcel;)Lcom/android/internal/os/BatteryStatsImpl;
+HSPLcom/android/internal/os/BatteryStatsImpl$6;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLcom/android/internal/os/BatteryStatsImpl$BatchTimer;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;Lcom/android/internal/os/BatteryStatsImpl$Uid;ILcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
+HPLcom/android/internal/os/BatteryStatsImpl$BatchTimer;->abortLastDuration(Lcom/android/internal/os/BatteryStatsImpl;)V
 HPLcom/android/internal/os/BatteryStatsImpl$BatchTimer;->addDuration(Lcom/android/internal/os/BatteryStatsImpl;J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$BatchTimer;->computeCurrentCountLocked()I
 HSPLcom/android/internal/os/BatteryStatsImpl$BatchTimer;->computeRunTimeLocked(J)J
@@ -19627,24 +20489,25 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$BatchTimer;->reset(Z)Z
 HPLcom/android/internal/os/BatteryStatsImpl$BatchTimer;->writeToParcel(Landroid/os/Parcel;J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$BluetoothActivityInfoCache;-><init>(Lcom/android/internal/os/BatteryStatsImpl;Lcom/android/internal/os/BatteryStatsImpl$1;)V
-PLcom/android/internal/os/BatteryStatsImpl$BluetoothActivityInfoCache;->set(Landroid/bluetooth/BluetoothActivityEnergyInfo;)V
+HPLcom/android/internal/os/BatteryStatsImpl$BluetoothActivityInfoCache;->set(Landroid/bluetooth/BluetoothActivityEnergyInfo;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Constants;-><init>(Lcom/android/internal/os/BatteryStatsImpl;Landroid/os/Handler;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Constants;->updateConstants()V
 HSPLcom/android/internal/os/BatteryStatsImpl$Constants;->updateKernelUidReadersThrottleTime(JJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Constants;->updateTrackCpuTimesByProcStateLocked(ZZ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;-><init>(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;I)V
+HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;-><init>(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;ILandroid/os/Parcel;)V
 HPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->detach()V
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getIdleTimeCounter()Landroid/os/BatteryStats$LongCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getIdleTimeCounter()Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;
-PLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getMonitoredRailChargeConsumedMaMs()Landroid/os/BatteryStats$LongCounter;
+HPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getMonitoredRailChargeConsumedMaMs()Landroid/os/BatteryStats$LongCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getMonitoredRailChargeConsumedMaMs()Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getPowerCounter()Landroid/os/BatteryStats$LongCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getPowerCounter()Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getRxTimeCounter()Landroid/os/BatteryStats$LongCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getRxTimeCounter()Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;
-PLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getScanTimeCounter()Landroid/os/BatteryStats$LongCounter;
+HPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getScanTimeCounter()Landroid/os/BatteryStats$LongCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getScanTimeCounter()Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;
-PLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getSleepTimeCounter()Landroid/os/BatteryStats$LongCounter;
+HPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getSleepTimeCounter()Landroid/os/BatteryStats$LongCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getSleepTimeCounter()Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getTxTimeCounters()[Landroid/os/BatteryStats$LongCounter;
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->getTxTimeCounters()[Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;
@@ -19653,16 +20516,19 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->writeSummaryToParcel(Landroid/os/Parcel;)V
 HPLcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;-><init>(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Counter;-><init>(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->addAtomic(I)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->detach()V
 HPLcom/android/internal/os/BatteryStatsImpl$Counter;->getCountLocked(I)I
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->onTimeStarted(JJJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->onTimeStopped(JJJ)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->readCounterFromParcel(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)Lcom/android/internal/os/BatteryStatsImpl$Counter;
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->readSummaryFromParcelLocked(Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->reset(Z)Z
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->stepAtomic()V
 HSPLcom/android/internal/os/BatteryStatsImpl$Counter;->writeSummaryFromParcelLocked(Landroid/os/Parcel;)V
 HPLcom/android/internal/os/BatteryStatsImpl$Counter;->writeToParcel(Landroid/os/Parcel;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$DualTimer;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;Lcom/android/internal/os/BatteryStatsImpl$Uid;ILjava/util/ArrayList;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$DualTimer;->detach()V
 HPLcom/android/internal/os/BatteryStatsImpl$DualTimer;->getSubTimer()Landroid/os/BatteryStats$Timer;
 HPLcom/android/internal/os/BatteryStatsImpl$DualTimer;->getSubTimer()Lcom/android/internal/os/BatteryStatsImpl$DurationTimer;
@@ -19671,7 +20537,8 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$DualTimer;->startRunningLocked(J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$DualTimer;->stopRunningLocked(J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$DualTimer;->writeSummaryFromParcelLocked(Landroid/os/Parcel;J)V
-PLcom/android/internal/os/BatteryStatsImpl$DualTimer;->writeToParcel(Landroid/os/Parcel;J)V
+HPLcom/android/internal/os/BatteryStatsImpl$DualTimer;->writeToParcel(Landroid/os/Parcel;J)V
+HSPLcom/android/internal/os/BatteryStatsImpl$DurationTimer;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;Lcom/android/internal/os/BatteryStatsImpl$Uid;ILjava/util/ArrayList;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$DurationTimer;->getCurrentDurationMsLocked(J)J
 HSPLcom/android/internal/os/BatteryStatsImpl$DurationTimer;->getMaxDurationMsLocked(J)J
 HSPLcom/android/internal/os/BatteryStatsImpl$DurationTimer;->getTotalDurationMsLocked(J)J
@@ -19684,6 +20551,7 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$DurationTimer;->writeSummaryFromParcelLocked(Landroid/os/Parcel;J)V
 HPLcom/android/internal/os/BatteryStatsImpl$DurationTimer;->writeToParcel(Landroid/os/Parcel;J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;-><init>(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;-><init>(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;->addCountLocked(J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;->addCountLocked(JZ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounter;->detach()V
@@ -19702,6 +20570,7 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;->getSize()I
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;->onTimeStarted(JJJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;->onTimeStopped(JJJ)V
+HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;->readFromParcel(Landroid/os/Parcel;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;)Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;->readSummaryFromParcelLocked(Landroid/os/Parcel;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;)Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;->reset(Z)Z
 HSPLcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;->writeSummaryToParcelLocked(Landroid/os/Parcel;Lcom/android/internal/os/BatteryStatsImpl$LongSamplingCounterArray;)V
@@ -19709,9 +20578,11 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$MyHandler;->handleMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$OverflowArrayMap;->add(Ljava/lang/String;Ljava/lang/Object;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$OverflowArrayMap;->cleanup()V
+HSPLcom/android/internal/os/BatteryStatsImpl$OverflowArrayMap;->clear()V
 HSPLcom/android/internal/os/BatteryStatsImpl$OverflowArrayMap;->getMap()Landroid/util/ArrayMap;
 HSPLcom/android/internal/os/BatteryStatsImpl$OverflowArrayMap;->startObject(Ljava/lang/String;)Ljava/lang/Object;
 HSPLcom/android/internal/os/BatteryStatsImpl$OverflowArrayMap;->stopObject(Ljava/lang/String;)Ljava/lang/Object;
+HSPLcom/android/internal/os/BatteryStatsImpl$SamplingTimer;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HPLcom/android/internal/os/BatteryStatsImpl$SamplingTimer;->add(JI)V
 HSPLcom/android/internal/os/BatteryStatsImpl$SamplingTimer;->computeCurrentCountLocked()I
 HSPLcom/android/internal/os/BatteryStatsImpl$SamplingTimer;->computeRunTimeLocked(J)J
@@ -19723,6 +20594,7 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$SamplingTimer;->update(JI)V
 HPLcom/android/internal/os/BatteryStatsImpl$SamplingTimer;->writeToParcel(Landroid/os/Parcel;J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$StopwatchTimer;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;Lcom/android/internal/os/BatteryStatsImpl$Uid;ILjava/util/ArrayList;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$StopwatchTimer;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;Lcom/android/internal/os/BatteryStatsImpl$Uid;ILjava/util/ArrayList;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$StopwatchTimer;->computeCurrentCountLocked()I
 HSPLcom/android/internal/os/BatteryStatsImpl$StopwatchTimer;->computeRunTimeLocked(J)J
 HSPLcom/android/internal/os/BatteryStatsImpl$StopwatchTimer;->detach()V
@@ -19746,12 +20618,14 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->getUptime(J)J
 HSPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->init(JJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->isRunning()Z
+HSPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->readFromParcel(Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->readSummaryFromParcel(Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->remove(Lcom/android/internal/os/BatteryStatsImpl$TimeBaseObs;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->setRunning(ZJJ)Z
 HSPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->writeSummaryToParcel(Landroid/os/Parcel;JJ)V
 HPLcom/android/internal/os/BatteryStatsImpl$TimeBase;->writeToParcel(Landroid/os/Parcel;JJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Timer;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;ILcom/android/internal/os/BatteryStatsImpl$TimeBase;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Timer;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;ILcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Timer;->detach()V
 HPLcom/android/internal/os/BatteryStatsImpl$Timer;->getCountLocked(I)I
 HSPLcom/android/internal/os/BatteryStatsImpl$Timer;->getTimeSinceMarkLocked(J)J
@@ -19773,21 +20647,25 @@
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->getStarts(I)I
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->onTimeStarted(JJJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->onTimeStopped(JJJ)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->readFromParcelLocked(Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->startLaunchedLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->startRunningLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->stopLaunchedLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->stopRunningLocked()V
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;->writeToParcelLocked(Landroid/os/Parcel;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;-><init>(Lcom/android/internal/os/BatteryStatsImpl;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;->detach()V
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;->getServiceStats()Landroid/util/ArrayMap;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;->getWakeupAlarmStats()Landroid/util/ArrayMap;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;->noteWakeupAlarmLocked(Ljava/lang/String;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;->onTimeStarted(JJJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;->onTimeStopped(JJJ)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;->readFromParcelLocked(Landroid/os/Parcel;)V
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;->writeToParcelLocked(Landroid/os/Parcel;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;-><init>(Lcom/android/internal/os/BatteryStatsImpl;Ljava/lang/String;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->addCpuTimeLocked(II)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->addCpuTimeLocked(IIZ)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->addExcessiveCpu(JJ)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->addExcessiveCpu(JJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->addForegroundTimeLocked(J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->detach()V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->getForegroundTime(I)J
@@ -19804,14 +20682,18 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->readExcessivePowerFromParcelLocked(Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->writeExcessivePowerToParcelLocked(Landroid/os/Parcel;)V
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Proc;->writeToParcelLocked(Landroid/os/Parcel;)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;-><init>(Lcom/android/internal/os/BatteryStatsImpl;Lcom/android/internal/os/BatteryStatsImpl$Uid;I)V
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getSensorBackgroundTime()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getSensorBackgroundTime()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getSensorBackgroundTime()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->getSensorTime()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->readTimersFromParcel(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)Lcom/android/internal/os/BatteryStatsImpl$DualTimer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->reset()Z
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Sensor;->writeToParcelLocked(Landroid/os/Parcel;J)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Wakelock;-><init>(Lcom/android/internal/os/BatteryStatsImpl;Lcom/android/internal/os/BatteryStatsImpl$Uid;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Wakelock;->getWakeTime(I)Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Wakelock;->readFromParcelLocked(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid$Wakelock;->reset()Z
 HPLcom/android/internal/os/BatteryStatsImpl$Uid$Wakelock;->writeToParcelLocked(Landroid/os/Parcel;J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;-><init>(Lcom/android/internal/os/BatteryStatsImpl;I)V
@@ -19832,22 +20714,22 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->createVideoTurnedOnTimerLocked()Lcom/android/internal/os/BatteryStatsImpl$StopwatchTimer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->detachFromTimeBase()V
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getAggregatedPartialWakelockTimer()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getAggregatedPartialWakelockTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getAggregatedPartialWakelockTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getAudioTurnedOnTimer()Landroid/os/BatteryStats$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getAudioTurnedOnTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothControllerActivity()Landroid/os/BatteryStats$ControllerActivityCounter;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanBackgroundTimer()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanBackgroundTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanResultBgCounter()Landroid/os/BatteryStats$Counter;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanResultBgCounter()Lcom/android/internal/os/BatteryStatsImpl$Counter;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanResultCounter()Landroid/os/BatteryStats$Counter;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanResultCounter()Lcom/android/internal/os/BatteryStatsImpl$Counter;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanBackgroundTimer()Landroid/os/BatteryStats$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanBackgroundTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanResultBgCounter()Landroid/os/BatteryStats$Counter;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanResultBgCounter()Lcom/android/internal/os/BatteryStatsImpl$Counter;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanResultCounter()Landroid/os/BatteryStats$Counter;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanResultCounter()Lcom/android/internal/os/BatteryStatsImpl$Counter;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanTimer()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothUnoptimizedScanBackgroundTimer()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothUnoptimizedScanBackgroundTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothUnoptimizedScanTimer()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothUnoptimizedScanTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothScanTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothUnoptimizedScanBackgroundTimer()Landroid/os/BatteryStats$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothUnoptimizedScanBackgroundTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothUnoptimizedScanTimer()Landroid/os/BatteryStats$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getBluetoothUnoptimizedScanTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getCameraTurnedOnTimer()Landroid/os/BatteryStats$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getCameraTurnedOnTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getCpuActiveTime()J
@@ -19860,7 +20742,7 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getForegroundActivityTimer()Landroid/os/BatteryStats$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getForegroundActivityTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getForegroundServiceTimer()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getForegroundServiceTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getForegroundServiceTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getFullWifiLockTime(JI)J
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getJobCompletionStats()Landroid/util/ArrayMap;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getJobStats()Landroid/util/ArrayMap;
@@ -19869,19 +20751,19 @@
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getMobileRadioApWakeupCount(I)J
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getModemControllerActivity()Landroid/os/BatteryStats$ControllerActivityCounter;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getMulticastWakelockStats()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getMulticastWakelockStats()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getMulticastWakelockStats()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getNetworkActivityBytes(II)J
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getNetworkActivityPackets(II)J
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getOrCreateBluetoothControllerActivityLocked()Lcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getOrCreateBluetoothControllerActivityLocked()Lcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getOrCreateModemControllerActivityLocked()Lcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getOrCreateWifiControllerActivityLocked()Lcom/android/internal/os/BatteryStatsImpl$ControllerActivityCounterImpl;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getPackageStats()Landroid/util/ArrayMap;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getPackageStatsLocked(Ljava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getPidStats()Landroid/util/SparseArray;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getPidStats()Landroid/util/SparseArray;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getPidStatsLocked(I)Landroid/os/BatteryStats$Uid$Pid;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getProcessStateTime(IJI)J
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getProcessStateTimer(I)Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getProcessStateTimer(I)Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getProcessStateTimer(I)Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getProcessStats()Landroid/util/ArrayMap;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getProcessStatsLocked(Ljava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getScreenOffCpuFreqTimes(I)[J
@@ -19895,7 +20777,7 @@
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getUserActivityCount(II)I
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getUserCpuTimeUs(I)J
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getVibratorOnTimer()Landroid/os/BatteryStats$Timer;
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->getVibratorOnTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->getVibratorOnTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getVideoTurnedOnTimer()Landroid/os/BatteryStats$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getVideoTurnedOnTimer()Lcom/android/internal/os/BatteryStatsImpl$Timer;
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->getWakelockStats()Landroid/util/ArrayMap;
@@ -19916,47 +20798,48 @@
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->makeProcessState(ILandroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteActivityPausedLocked(J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteActivityResumedLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteAudioTurnedOffLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteAudioTurnedOnLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteBluetoothScanResultsLocked(I)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteBluetoothScanStartedLocked(JZ)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteBluetoothScanStoppedLocked(JZ)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteCameraTurnedOffLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteCameraTurnedOnLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteForegroundServicePausedLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteForegroundServiceResumedLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteFullWifiLockAcquiredLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteFullWifiLockReleasedLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteAudioTurnedOffLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteAudioTurnedOnLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteBluetoothScanResultsLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteBluetoothScanStartedLocked(JZ)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteBluetoothScanStoppedLocked(JZ)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteCameraTurnedOffLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteCameraTurnedOnLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteForegroundServicePausedLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteForegroundServiceResumedLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteFullWifiLockAcquiredLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteFullWifiLockReleasedLocked(J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteJobsDeferredLocked(IJ)V
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteMobileRadioActiveTimeLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteMobileRadioApWakeupLocked()V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteMobileRadioApWakeupLocked()V
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteNetworkActivityLocked(IJJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStartGps(J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStartJobLocked(Ljava/lang/String;J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStartSensor(IJ)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStartSyncLocked(Ljava/lang/String;J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStartSyncLocked(Ljava/lang/String;J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStartWakeLocked(ILjava/lang/String;IJ)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStopGps(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStopGps(J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStopJobLocked(Ljava/lang/String;JI)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStopSensor(IJ)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStopSyncLocked(Ljava/lang/String;J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStopSyncLocked(Ljava/lang/String;J)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteStopWakeLocked(ILjava/lang/String;IJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteUserActivityLocked(I)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteVibratorOffLocked()V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteVibratorOnLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteVideoTurnedOffLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteVideoTurnedOnLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiMulticastDisabledLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiMulticastEnabledLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiRadioApWakeupLocked()V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteVibratorOffLocked()V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteVibratorOnLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteVideoTurnedOffLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteVideoTurnedOnLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiMulticastDisabledLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiMulticastEnabledLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiRadioApWakeupLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiScanStartedLocked(J)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiScanStoppedLocked(J)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->noteWifiScanStoppedLocked(J)V
+HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->readFromParcelLocked(Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Lcom/android/internal/os/BatteryStatsImpl$TimeBase;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->readJobCompletionsFromParcelLocked(Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->readJobSummaryFromParcelLocked(Ljava/lang/String;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->readSyncSummaryFromParcelLocked(Ljava/lang/String;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->readWakeSummaryFromParcelLocked(Ljava/lang/String;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->removeIsolatedUid(I)V
-PLcom/android/internal/os/BatteryStatsImpl$Uid;->reportExcessiveCpuLocked(Ljava/lang/String;JJ)V
+HPLcom/android/internal/os/BatteryStatsImpl$Uid;->reportExcessiveCpuLocked(Ljava/lang/String;JJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->reset(JJ)Z
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->updateOnBatteryBgTimeBase(JJ)Z
 HSPLcom/android/internal/os/BatteryStatsImpl$Uid;->updateOnBatteryScreenOffBgTimeBase(JJ)Z
@@ -19965,6 +20848,7 @@
 HPLcom/android/internal/os/BatteryStatsImpl$Uid;->writeToParcelLocked(Landroid/os/Parcel;JJ)V
 HPLcom/android/internal/os/BatteryStatsImpl$UidToRemove;->remove()V
 HSPLcom/android/internal/os/BatteryStatsImpl$UserInfoProvider;->exists(I)Z
+HSPLcom/android/internal/os/BatteryStatsImpl;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;-><init>(Lcom/android/internal/os/BatteryStatsImpl$Clocks;Ljava/io/File;Landroid/os/Handler;Lcom/android/internal/os/BatteryStatsImpl$PlatformIdleStateCallback;Lcom/android/internal/os/BatteryStatsImpl$RailEnergyDataCallback;Lcom/android/internal/os/BatteryStatsImpl$UserInfoProvider;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;-><init>(Ljava/io/File;Landroid/os/Handler;Lcom/android/internal/os/BatteryStatsImpl$PlatformIdleStateCallback;Lcom/android/internal/os/BatteryStatsImpl$RailEnergyDataCallback;Lcom/android/internal/os/BatteryStatsImpl$UserInfoProvider;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->addHistoryBufferLocked(JBLandroid/os/BatteryStats$HistoryItem;)V
@@ -20002,8 +20886,8 @@
 HSPLcom/android/internal/os/BatteryStatsImpl;->getBatteryUptimeLocked()J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getBluetoothControllerActivity()Landroid/os/BatteryStats$ControllerActivityCounter;
 HPLcom/android/internal/os/BatteryStatsImpl;->getCellularBatteryStats()Landroid/os/connectivity/CellularBatteryStats;
-PLcom/android/internal/os/BatteryStatsImpl;->getChargeLevelStepTracker()Landroid/os/BatteryStats$LevelStepTracker;
-PLcom/android/internal/os/BatteryStatsImpl;->getCpuFreqs()[J
+HPLcom/android/internal/os/BatteryStatsImpl;->getChargeLevelStepTracker()Landroid/os/BatteryStats$LevelStepTracker;
+HPLcom/android/internal/os/BatteryStatsImpl;->getCpuFreqs()[J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getDeltaModemActivityInfo(Landroid/telephony/ModemActivityInfo;)Landroid/telephony/ModemActivityInfo;
 HPLcom/android/internal/os/BatteryStatsImpl;->getDeviceIdleModeCount(II)I
 HPLcom/android/internal/os/BatteryStatsImpl;->getDeviceIdleModeTime(IJI)J
@@ -20012,41 +20896,41 @@
 HSPLcom/android/internal/os/BatteryStatsImpl;->getDischargeAmountScreenDozeSinceCharge()I
 HSPLcom/android/internal/os/BatteryStatsImpl;->getDischargeAmountScreenOffSinceCharge()I
 HSPLcom/android/internal/os/BatteryStatsImpl;->getDischargeAmountScreenOnSinceCharge()I
-PLcom/android/internal/os/BatteryStatsImpl;->getDischargeLevelStepTracker()Landroid/os/BatteryStats$LevelStepTracker;
-PLcom/android/internal/os/BatteryStatsImpl;->getEndPlatformVersion()Ljava/lang/String;
-PLcom/android/internal/os/BatteryStatsImpl;->getEstimatedBatteryCapacity()I
-PLcom/android/internal/os/BatteryStatsImpl;->getExternalStatsCollectionRateLimitMs()J
-PLcom/android/internal/os/BatteryStatsImpl;->getGlobalWifiRunningTime(JI)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getDischargeLevelStepTracker()Landroid/os/BatteryStats$LevelStepTracker;
+HPLcom/android/internal/os/BatteryStatsImpl;->getEndPlatformVersion()Ljava/lang/String;
+HPLcom/android/internal/os/BatteryStatsImpl;->getEstimatedBatteryCapacity()I
+HPLcom/android/internal/os/BatteryStatsImpl;->getExternalStatsCollectionRateLimitMs()J
+HPLcom/android/internal/os/BatteryStatsImpl;->getGlobalWifiRunningTime(JI)J
 HPLcom/android/internal/os/BatteryStatsImpl;->getGpsBatteryDrainMaMs()J
 HPLcom/android/internal/os/BatteryStatsImpl;->getGpsBatteryStats()Landroid/os/connectivity/GpsBatteryStats;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getGpsSignalQualityTime(IJI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getHighDischargeAmountSinceCharge()I
-PLcom/android/internal/os/BatteryStatsImpl;->getHistoryBaseTime()J
-PLcom/android/internal/os/BatteryStatsImpl;->getHistoryStringPoolSize()I
-PLcom/android/internal/os/BatteryStatsImpl;->getHistoryTagPoolString(I)Ljava/lang/String;
-PLcom/android/internal/os/BatteryStatsImpl;->getHistoryTagPoolUid(I)I
-PLcom/android/internal/os/BatteryStatsImpl;->getInteractiveTime(JI)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getHistoryBaseTime()J
+HPLcom/android/internal/os/BatteryStatsImpl;->getHistoryStringPoolSize()I
+HPLcom/android/internal/os/BatteryStatsImpl;->getHistoryTagPoolString(I)Ljava/lang/String;
+HPLcom/android/internal/os/BatteryStatsImpl;->getHistoryTagPoolUid(I)I
+HPLcom/android/internal/os/BatteryStatsImpl;->getInteractiveTime(JI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getIsOnBattery()Z
 HSPLcom/android/internal/os/BatteryStatsImpl;->getKernelMemoryStats()Landroid/util/LongSparseArray;
-PLcom/android/internal/os/BatteryStatsImpl;->getKernelWakelockStats()Ljava/util/Map;
+HPLcom/android/internal/os/BatteryStatsImpl;->getKernelWakelockStats()Ljava/util/Map;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getKernelWakelockTimerLocked(Ljava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$SamplingTimer;
-PLcom/android/internal/os/BatteryStatsImpl;->getLongestDeviceIdleModeTime(I)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getLongestDeviceIdleModeTime(I)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getLowDischargeAmountSinceCharge()I
-PLcom/android/internal/os/BatteryStatsImpl;->getMaxLearnedBatteryCapacity()I
-PLcom/android/internal/os/BatteryStatsImpl;->getMinLearnedBatteryCapacity()I
+HPLcom/android/internal/os/BatteryStatsImpl;->getMaxLearnedBatteryCapacity()I
+HPLcom/android/internal/os/BatteryStatsImpl;->getMinLearnedBatteryCapacity()I
 HSPLcom/android/internal/os/BatteryStatsImpl;->getMobileIfaces()[Ljava/lang/String;
-PLcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveAdjustedTime(I)J
-PLcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveCount(I)I
+HPLcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveAdjustedTime(I)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveCount(I)I
 HSPLcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveTime(JI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveUnknownCount(I)I
-PLcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveUnknownTime(I)J
-PLcom/android/internal/os/BatteryStatsImpl;->getModemControllerActivity()Landroid/os/BatteryStats$ControllerActivityCounter;
+HPLcom/android/internal/os/BatteryStatsImpl;->getMobileRadioActiveUnknownTime(I)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getModemControllerActivity()Landroid/os/BatteryStats$ControllerActivityCounter;
 HPLcom/android/internal/os/BatteryStatsImpl;->getNetworkActivityBytes(II)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getNetworkActivityPackets(II)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
-PLcom/android/internal/os/BatteryStatsImpl;->getNumConnectivityChange(I)I
+HPLcom/android/internal/os/BatteryStatsImpl;->getNumConnectivityChange(I)I
 HSPLcom/android/internal/os/BatteryStatsImpl;->getPackageStatsLocked(ILjava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$Uid$Pkg;
-PLcom/android/internal/os/BatteryStatsImpl;->getParcelVersion()I
+HPLcom/android/internal/os/BatteryStatsImpl;->getParcelVersion()I
 HPLcom/android/internal/os/BatteryStatsImpl;->getPhoneDataConnectionCount(II)I
 HPLcom/android/internal/os/BatteryStatsImpl;->getPhoneDataConnectionTime(IJI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getPhoneOnTime(JI)J
@@ -20054,33 +20938,33 @@
 HPLcom/android/internal/os/BatteryStatsImpl;->getPhoneSignalStrengthCount(II)I
 HSPLcom/android/internal/os/BatteryStatsImpl;->getPhoneSignalStrengthTime(IJI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getPowerManagerWakeLockLevel(I)I
-PLcom/android/internal/os/BatteryStatsImpl;->getPowerSaveModeEnabledTime(JI)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getPowerSaveModeEnabledTime(JI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getProcessStatsLocked(ILjava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$Uid$Proc;
-PLcom/android/internal/os/BatteryStatsImpl;->getRpmStats()Ljava/util/Map;
+HPLcom/android/internal/os/BatteryStatsImpl;->getRpmStats()Ljava/util/Map;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getRpmTimerLocked(Ljava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$SamplingTimer;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getScreenBrightnessTime(IJI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getScreenDozeTime(JI)J
-PLcom/android/internal/os/BatteryStatsImpl;->getScreenOffRpmStats()Ljava/util/Map;
+HPLcom/android/internal/os/BatteryStatsImpl;->getScreenOffRpmStats()Ljava/util/Map;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getScreenOnTime(JI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getServiceStatsLocked(ILjava/lang/String;Ljava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$Uid$Pkg$Serv;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getStartClockTime()J
-PLcom/android/internal/os/BatteryStatsImpl;->getStartCount()I
-PLcom/android/internal/os/BatteryStatsImpl;->getStartPlatformVersion()Ljava/lang/String;
-PLcom/android/internal/os/BatteryStatsImpl;->getUahDischarge(I)J
-PLcom/android/internal/os/BatteryStatsImpl;->getUahDischargeDeepDoze(I)J
-PLcom/android/internal/os/BatteryStatsImpl;->getUahDischargeLightDoze(I)J
-PLcom/android/internal/os/BatteryStatsImpl;->getUahDischargeScreenDoze(I)J
-PLcom/android/internal/os/BatteryStatsImpl;->getUahDischargeScreenOff(I)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getStartCount()I
+HPLcom/android/internal/os/BatteryStatsImpl;->getStartPlatformVersion()Ljava/lang/String;
+HPLcom/android/internal/os/BatteryStatsImpl;->getUahDischarge(I)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getUahDischargeDeepDoze(I)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getUahDischargeLightDoze(I)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getUahDischargeScreenDoze(I)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getUahDischargeScreenOff(I)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->getUidStats()Landroid/util/SparseArray;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getUidStatsLocked(I)Lcom/android/internal/os/BatteryStatsImpl$Uid;
-PLcom/android/internal/os/BatteryStatsImpl;->getWakeupReasonStats()Ljava/util/Map;
+HPLcom/android/internal/os/BatteryStatsImpl;->getWakeupReasonStats()Ljava/util/Map;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getWakeupReasonTimerLocked(Ljava/lang/String;)Lcom/android/internal/os/BatteryStatsImpl$SamplingTimer;
-PLcom/android/internal/os/BatteryStatsImpl;->getWifiActiveTime(JI)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getWifiActiveTime(JI)J
 HPLcom/android/internal/os/BatteryStatsImpl;->getWifiBatteryStats()Landroid/os/connectivity/WifiBatteryStats;
 HSPLcom/android/internal/os/BatteryStatsImpl;->getWifiControllerActivity()Landroid/os/BatteryStats$ControllerActivityCounter;
-PLcom/android/internal/os/BatteryStatsImpl;->getWifiMulticastWakelockCount(I)I
-PLcom/android/internal/os/BatteryStatsImpl;->getWifiMulticastWakelockTime(JI)J
-PLcom/android/internal/os/BatteryStatsImpl;->getWifiOnTime(JI)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getWifiMulticastWakelockCount(I)I
+HPLcom/android/internal/os/BatteryStatsImpl;->getWifiMulticastWakelockTime(JI)J
+HPLcom/android/internal/os/BatteryStatsImpl;->getWifiOnTime(JI)J
 HPLcom/android/internal/os/BatteryStatsImpl;->getWifiSignalStrengthCount(II)I
 HPLcom/android/internal/os/BatteryStatsImpl;->getWifiSignalStrengthTime(IJI)J
 HPLcom/android/internal/os/BatteryStatsImpl;->getWifiStateCount(II)I
@@ -20089,6 +20973,7 @@
 HPLcom/android/internal/os/BatteryStatsImpl;->getWifiSupplStateTime(IJI)J
 HSPLcom/android/internal/os/BatteryStatsImpl;->hasBluetoothActivityReporting()Z
 HSPLcom/android/internal/os/BatteryStatsImpl;->hasWifiActivityReporting()Z
+HSPLcom/android/internal/os/BatteryStatsImpl;->init(Lcom/android/internal/os/BatteryStatsImpl$Clocks;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->initActiveHistoryEventsLocked(JJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->initDischarge()V
 HSPLcom/android/internal/os/BatteryStatsImpl;->initTimes(JJ)V
@@ -20114,22 +20999,22 @@
 HPLcom/android/internal/os/BatteryStatsImpl;->noteAudioOnLocked(I)V
 HPLcom/android/internal/os/BatteryStatsImpl;->noteBluetoothScanResultsFromSourceLocked(Landroid/os/WorkSource;I)V
 HPLcom/android/internal/os/BatteryStatsImpl;->noteBluetoothScanStartedFromSourceLocked(Landroid/os/WorkSource;Z)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteBluetoothScanStartedLocked(Landroid/os/WorkSource$WorkChain;IZ)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteBluetoothScanStartedLocked(Landroid/os/WorkSource$WorkChain;IZ)V
 HPLcom/android/internal/os/BatteryStatsImpl;->noteBluetoothScanStoppedFromSourceLocked(Landroid/os/WorkSource;Z)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteBluetoothScanStoppedLocked(Landroid/os/WorkSource$WorkChain;IZ)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteCameraOffLocked(I)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteCameraOnLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteBluetoothScanStoppedLocked(Landroid/os/WorkSource$WorkChain;IZ)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteCameraOffLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteCameraOnLocked(I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteChangeWakelockFromSourceLocked(Landroid/os/WorkSource;ILjava/lang/String;Ljava/lang/String;ILandroid/os/WorkSource;ILjava/lang/String;Ljava/lang/String;IZ)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteConnectivityChangedLocked(ILjava/lang/String;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteCurrentTimeChangedLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteDeviceIdleModeLocked(ILjava/lang/String;I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteEventLocked(ILjava/lang/String;I)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteFullWifiLockAcquiredFromSourceLocked(Landroid/os/WorkSource;)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteFullWifiLockAcquiredLocked(I)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteFullWifiLockReleasedFromSourceLocked(Landroid/os/WorkSource;)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteFullWifiLockReleasedLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteFullWifiLockAcquiredFromSourceLocked(Landroid/os/WorkSource;)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteFullWifiLockAcquiredLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteFullWifiLockReleasedFromSourceLocked(Landroid/os/WorkSource;)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteFullWifiLockReleasedLocked(I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteGpsChangedLocked(Landroid/os/WorkSource;Landroid/os/WorkSource;)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteGpsSignalQualityLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteGpsSignalQualityLocked(I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteInteractiveLocked(Z)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteJobFinishLocked(Ljava/lang/String;II)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteJobStartLocked(Ljava/lang/String;I)V
@@ -20142,13 +21027,15 @@
 HPLcom/android/internal/os/BatteryStatsImpl;->noteLongPartialWakelockStartFromSource(Ljava/lang/String;Ljava/lang/String;Landroid/os/WorkSource;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteMobileRadioPowerStateLocked(IJI)Z
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteNetworkInterfaceTypeLocked(Ljava/lang/String;I)V
-PLcom/android/internal/os/BatteryStatsImpl;->notePackageInstalledLocked(Ljava/lang/String;J)V
+HPLcom/android/internal/os/BatteryStatsImpl;->notePackageInstalledLocked(Ljava/lang/String;J)V
+HSPLcom/android/internal/os/BatteryStatsImpl;->notePackageUninstalledLocked(Ljava/lang/String;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->notePhoneDataConnectionStateLocked(IZ)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->notePhoneOffLocked()V
-PLcom/android/internal/os/BatteryStatsImpl;->notePhoneOnLocked()V
+HPLcom/android/internal/os/BatteryStatsImpl;->notePhoneOnLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl;->notePhoneSignalStrengthLocked(Landroid/telephony/SignalStrength;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->notePhoneStateLocked(II)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->notePowerSaveModeLocked(Z)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteProcessAnrLocked(Ljava/lang/String;I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteProcessCrashLocked(Ljava/lang/String;I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteProcessDiedLocked(II)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteProcessFinishLocked(Ljava/lang/String;I)V
@@ -20171,8 +21058,8 @@
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteUserActivityLocked(II)V
 HPLcom/android/internal/os/BatteryStatsImpl;->noteVibratorOffLocked(I)V
 HPLcom/android/internal/os/BatteryStatsImpl;->noteVibratorOnLocked(IJ)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteVideoOffLocked(I)V
-PLcom/android/internal/os/BatteryStatsImpl;->noteVideoOnLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteVideoOffLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->noteVideoOnLocked(I)V
 HPLcom/android/internal/os/BatteryStatsImpl;->noteWakeUpLocked(Ljava/lang/String;I)V
 HPLcom/android/internal/os/BatteryStatsImpl;->noteWakeupReasonLocked(Ljava/lang/String;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteWakupAlarmLocked(Ljava/lang/String;ILandroid/os/WorkSource;Ljava/lang/String;)V
@@ -20190,12 +21077,14 @@
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteWifiStateLocked(ILjava/lang/String;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->noteWifiSupplicantStateChangedLocked(IZ)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->postBatteryNeedsCpuUpdateMsg()V
-PLcom/android/internal/os/BatteryStatsImpl;->prepareForDumpLocked()V
+HPLcom/android/internal/os/BatteryStatsImpl;->prepareForDumpLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl;->pullPendingStateUpdatesLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl;->readDailyItemTagDetailsLocked(Lorg/xmlpull/v1/XmlPullParser;Landroid/os/BatteryStats$DailyItem;ZLjava/lang/String;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->readDailyItemTagLocked(Lorg/xmlpull/v1/XmlPullParser;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->readDailyItemsLocked(Lorg/xmlpull/v1/XmlPullParser;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->readDailyStatsLocked()V
+HSPLcom/android/internal/os/BatteryStatsImpl;->readFromParcel(Landroid/os/Parcel;)V
+HSPLcom/android/internal/os/BatteryStatsImpl;->readFromParcelLocked(Landroid/os/Parcel;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->readHistoryBuffer(Landroid/os/Parcel;Z)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->readHistoryDelta(Landroid/os/Parcel;Landroid/os/BatteryStats$HistoryItem;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->readKernelUidCpuActiveTimesLocked(Z)V
@@ -20210,8 +21099,9 @@
 HSPLcom/android/internal/os/BatteryStatsImpl;->recordDailyStatsLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl;->registerUsbStateReceiver(Landroid/content/Context;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->removeIsolatedUidLocked(I)V
+HSPLcom/android/internal/os/BatteryStatsImpl;->removeUidStatsLocked(I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->reportChangesToStatsLog(Landroid/os/BatteryStats$HistoryItem;III)V
-PLcom/android/internal/os/BatteryStatsImpl;->reportExcessiveCpuLocked(ILjava/lang/String;JJ)V
+HPLcom/android/internal/os/BatteryStatsImpl;->reportExcessiveCpuLocked(ILjava/lang/String;JJ)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->resetAllStatsLocked()V
 HSPLcom/android/internal/os/BatteryStatsImpl;->scheduleRemoveIsolatedUidLocked(II)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->setBatteryStateLocked(IIIIIIII)V
@@ -20224,7 +21114,7 @@
 HSPLcom/android/internal/os/BatteryStatsImpl;->startAddingCpuLocked()Z
 HSPLcom/android/internal/os/BatteryStatsImpl;->startIteratingHistoryLocked()Z
 HSPLcom/android/internal/os/BatteryStatsImpl;->startRecordingHistory(JJZ)V
-PLcom/android/internal/os/BatteryStatsImpl;->stopAllGpsSignalQualityTimersLocked(I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->stopAllGpsSignalQualityTimersLocked(I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->stopAllPhoneSignalStrengthTimersLocked(I)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->systemServicesReady(Landroid/content/Context;)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->trackPerProcStateCpuTimes()Z
@@ -20255,20 +21145,20 @@
 HSPLcom/android/internal/os/BatteryStatsImpl;->writeParcelToFileLocked(Landroid/os/Parcel;Lcom/android/internal/os/AtomicFile;Z)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->writeStatsLocked(Z)V
 HSPLcom/android/internal/os/BatteryStatsImpl;->writeSummaryToParcel(Landroid/os/Parcel;Z)V
-PLcom/android/internal/os/BatteryStatsImpl;->writeToParcel(Landroid/os/Parcel;I)V
+HPLcom/android/internal/os/BatteryStatsImpl;->writeToParcel(Landroid/os/Parcel;I)V
 HPLcom/android/internal/os/BatteryStatsImpl;->writeToParcelLocked(Landroid/os/Parcel;ZI)V
 HSPLcom/android/internal/os/BinderCallsStats$CallStatKey;-><init>()V
 HSPLcom/android/internal/os/BinderCallsStats$CallStatKey;->equals(Ljava/lang/Object;)Z
 HSPLcom/android/internal/os/BinderCallsStats$CallStatKey;->hashCode()I
 HSPLcom/android/internal/os/BinderCallsStats$Injector;->getRandomGenerator()Ljava/util/Random;
 HSPLcom/android/internal/os/BinderCallsStats$UidEntry;->get(ILjava/lang/Class;IZ)Lcom/android/internal/os/BinderCallsStats$CallStat;
-PLcom/android/internal/os/BinderCallsStats$UidEntry;->getCallStatsList()Ljava/util/Collection;
+HPLcom/android/internal/os/BinderCallsStats$UidEntry;->getCallStatsList()Ljava/util/Collection;
 HSPLcom/android/internal/os/BinderCallsStats$UidEntry;->getOrCreate(ILjava/lang/Class;IZZ)Lcom/android/internal/os/BinderCallsStats$CallStat;
 HSPLcom/android/internal/os/BinderCallsStats;-><init>(Lcom/android/internal/os/BinderCallsStats$Injector;)V
 HSPLcom/android/internal/os/BinderCallsStats;->callEnded(Lcom/android/internal/os/BinderInternal$CallSession;III)V
 HSPLcom/android/internal/os/BinderCallsStats;->callStarted(Landroid/os/Binder;II)Lcom/android/internal/os/BinderInternal$CallSession;
 HSPLcom/android/internal/os/BinderCallsStats;->callThrewException(Lcom/android/internal/os/BinderInternal$CallSession;Ljava/lang/Exception;)V
-PLcom/android/internal/os/BinderCallsStats;->createDebugEntry(Ljava/lang/String;J)Lcom/android/internal/os/BinderCallsStats$ExportedCallStat;
+HPLcom/android/internal/os/BinderCallsStats;->createDebugEntry(Ljava/lang/String;J)Lcom/android/internal/os/BinderCallsStats$ExportedCallStat;
 HSPLcom/android/internal/os/BinderCallsStats;->getCallingUid()I
 HPLcom/android/internal/os/BinderCallsStats;->getDefaultTransactionNameMethod(Ljava/lang/Class;)Ljava/lang/reflect/Method;
 HSPLcom/android/internal/os/BinderCallsStats;->getElapsedRealtimeMicro()J
@@ -20300,7 +21190,7 @@
 HSPLcom/android/internal/os/BluetoothPowerCalculator;->reset()V
 HSPLcom/android/internal/os/CachedDeviceState$Readonly;->createTimeOnBatteryStopwatch()Lcom/android/internal/os/CachedDeviceState$TimeInStateStopwatch;
 HSPLcom/android/internal/os/CachedDeviceState$Readonly;->isCharging()Z
-PLcom/android/internal/os/CachedDeviceState$TimeInStateStopwatch;->getMillis()J
+HPLcom/android/internal/os/CachedDeviceState$TimeInStateStopwatch;->getMillis()J
 HSPLcom/android/internal/os/CachedDeviceState$TimeInStateStopwatch;->isRunning()Z
 HSPLcom/android/internal/os/CachedDeviceState$TimeInStateStopwatch;->reset()V
 HSPLcom/android/internal/os/CachedDeviceState$TimeInStateStopwatch;->start()V
@@ -20334,9 +21224,10 @@
 HSPLcom/android/internal/os/HandlerCaller;->obtainMessageOO(ILjava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
 HSPLcom/android/internal/os/HandlerCaller;->obtainMessageOOO(ILjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
 HSPLcom/android/internal/os/HandlerCaller;->obtainMessageOOOOO(ILjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
+HSPLcom/android/internal/os/HandlerCaller;->sendMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/os/IDropBoxManagerService$Stub;-><init>()V
 HSPLcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService;
-PLcom/android/internal/os/IDropBoxManagerService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLcom/android/internal/os/IDropBoxManagerService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLcom/android/internal/os/IDropBoxManagerService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLcom/android/internal/os/IResultReceiver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLcom/android/internal/os/IResultReceiver$Stub$Proxy;->asBinder()Landroid/os/IBinder;
@@ -20360,7 +21251,7 @@
 HPLcom/android/internal/os/KernelCpuThreadReader$Injector;->getUidForPid(I)I
 HPLcom/android/internal/os/KernelCpuThreadReader;->$closeResource(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V
 HSPLcom/android/internal/os/KernelCpuThreadReader;->create(ILjava/util/function/Predicate;I)Lcom/android/internal/os/KernelCpuThreadReader;
-PLcom/android/internal/os/KernelCpuThreadReader;->getCpuFrequenciesKhz()[I
+HPLcom/android/internal/os/KernelCpuThreadReader;->getCpuFrequenciesKhz()[I
 HPLcom/android/internal/os/KernelCpuThreadReader;->getProcessCpuUsage()Ljava/util/ArrayList;
 HPLcom/android/internal/os/KernelCpuThreadReader;->getProcessCpuUsage(Ljava/nio/file/Path;II)Lcom/android/internal/os/KernelCpuThreadReader$ProcessCpuUsage;
 HPLcom/android/internal/os/KernelCpuThreadReader;->getProcessId(Ljava/nio/file/Path;)I
@@ -20394,7 +21285,7 @@
 HPLcom/android/internal/os/KernelCpuUidTimeReader$KernelCpuUidUserSysTimeReader;->removeUid(I)V
 HPLcom/android/internal/os/KernelCpuUidTimeReader$KernelCpuUidUserSysTimeReader;->removeUidsFromKernelModule(II)V
 HSPLcom/android/internal/os/KernelCpuUidTimeReader;-><init>(Lcom/android/internal/os/KernelCpuProcStringReader;Z)V
-PLcom/android/internal/os/KernelCpuUidTimeReader;->readAbsolute(Lcom/android/internal/os/KernelCpuUidTimeReader$Callback;)V
+HPLcom/android/internal/os/KernelCpuUidTimeReader;->readAbsolute(Lcom/android/internal/os/KernelCpuUidTimeReader$Callback;)V
 HSPLcom/android/internal/os/KernelCpuUidTimeReader;->readDelta(Lcom/android/internal/os/KernelCpuUidTimeReader$Callback;)V
 HPLcom/android/internal/os/KernelCpuUidTimeReader;->removeUid(I)V
 HSPLcom/android/internal/os/KernelCpuUidTimeReader;->setThrottle(J)V
@@ -20411,13 +21302,13 @@
 HSPLcom/android/internal/os/LooperStats$Entry;->reset()V
 HPLcom/android/internal/os/LooperStats$ExportedEntry;-><init>(Lcom/android/internal/os/LooperStats$Entry;)V
 HSPLcom/android/internal/os/LooperStats;-><init>(II)V
-PLcom/android/internal/os/LooperStats;->createDebugEntry(Ljava/lang/String;J)Lcom/android/internal/os/LooperStats$ExportedEntry;
+HPLcom/android/internal/os/LooperStats;->createDebugEntry(Ljava/lang/String;J)Lcom/android/internal/os/LooperStats$ExportedEntry;
 HSPLcom/android/internal/os/LooperStats;->findEntry(Landroid/os/Message;Z)Lcom/android/internal/os/LooperStats$Entry;
 HSPLcom/android/internal/os/LooperStats;->getElapsedRealtimeMicro()J
 HPLcom/android/internal/os/LooperStats;->getEntries()Ljava/util/List;
 HSPLcom/android/internal/os/LooperStats;->getSystemUptimeMillis()J
 HSPLcom/android/internal/os/LooperStats;->getThreadTimeMicro()J
-PLcom/android/internal/os/LooperStats;->maybeAddSpecialEntry(Ljava/util/List;Lcom/android/internal/os/LooperStats$Entry;)V
+HPLcom/android/internal/os/LooperStats;->maybeAddSpecialEntry(Ljava/util/List;Lcom/android/internal/os/LooperStats$Entry;)V
 HSPLcom/android/internal/os/LooperStats;->messageDispatchStarting()Ljava/lang/Object;
 HSPLcom/android/internal/os/LooperStats;->messageDispatched(Ljava/lang/Object;Landroid/os/Message;)V
 HSPLcom/android/internal/os/LooperStats;->reset()V
@@ -20454,8 +21345,11 @@
 HPLcom/android/internal/os/ProcTimeInStateReader;->getUsageTimesMillis(Ljava/nio/file/Path;)[J
 HSPLcom/android/internal/os/ProcTimeInStateReader;->initializeTimeInStateFormat(Ljava/nio/file/Path;)V
 HSPLcom/android/internal/os/ProcessCpuTracker$1;-><init>()V
+HPLcom/android/internal/os/ProcessCpuTracker$1;->compare(Lcom/android/internal/os/ProcessCpuTracker$Stats;Lcom/android/internal/os/ProcessCpuTracker$Stats;)I
+HPLcom/android/internal/os/ProcessCpuTracker$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLcom/android/internal/os/ProcessCpuTracker$Stats;-><init>(IIZ)V
 HSPLcom/android/internal/os/ProcessCpuTracker;-><init>(Z)V
+HPLcom/android/internal/os/ProcessCpuTracker;->buildWorkingProcs()V
 HSPLcom/android/internal/os/ProcessCpuTracker;->collectStats(Ljava/lang/String;IZ[ILjava/util/ArrayList;)[I
 HSPLcom/android/internal/os/ProcessCpuTracker;->countStats()I
 HSPLcom/android/internal/os/ProcessCpuTracker;->getCpuTimeForPid(I)J
@@ -20465,6 +21359,10 @@
 HSPLcom/android/internal/os/ProcessCpuTracker;->init()V
 HSPLcom/android/internal/os/ProcessCpuTracker;->onLoadChanged(FFF)V
 HSPLcom/android/internal/os/ProcessCpuTracker;->onMeasureProcessName(Ljava/lang/String;)I
+HPLcom/android/internal/os/ProcessCpuTracker;->printCurrentLoad()Ljava/lang/String;
+HPLcom/android/internal/os/ProcessCpuTracker;->printCurrentState(J)Ljava/lang/String;
+HPLcom/android/internal/os/ProcessCpuTracker;->printProcessCPU(Ljava/io/PrintWriter;Ljava/lang/String;ILjava/lang/String;IIIIIIII)V
+HPLcom/android/internal/os/ProcessCpuTracker;->printRatio(Ljava/io/PrintWriter;JJ)V
 HSPLcom/android/internal/os/ProcessCpuTracker;->update()V
 HSPLcom/android/internal/os/RailStats;-><init>()V
 HSPLcom/android/internal/os/RailStats;->setRailStatsAvailability(Z)V
@@ -20509,6 +21407,7 @@
 HSPLcom/android/internal/os/Zygote;->callPostForkChildHooks(IZZLjava/lang/String;)V
 HSPLcom/android/internal/os/Zygote;->callPostForkSystemServerHooks()V
 HSPLcom/android/internal/os/Zygote;->createManagedSocketFromInitSocket(Ljava/lang/String;)Landroid/net/LocalServerSocket;
+HSPLcom/android/internal/os/Zygote;->forkAndSpecialize(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I
 HSPLcom/android/internal/os/Zygote;->forkAndSpecialize(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;I)I
 HSPLcom/android/internal/os/Zygote;->getConfigurationProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLcom/android/internal/os/Zygote;->getConfigurationPropertyBoolean(Ljava/lang/String;Ljava/lang/Boolean;)Z
@@ -20526,7 +21425,10 @@
 HSPLcom/android/internal/os/ZygoteConnection;->handleChildProc(Lcom/android/internal/os/ZygoteArguments;[Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Z)Ljava/lang/Runnable;
 HSPLcom/android/internal/os/ZygoteConnection;->handleHiddenApiAccessLogSampleRate(Lcom/android/internal/os/ZygoteServer;II)Ljava/lang/Runnable;
 HSPLcom/android/internal/os/ZygoteConnection;->handleParentProc(I[Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;)V
+HSPLcom/android/internal/os/ZygoteConnection;->handlePreload()V
 HSPLcom/android/internal/os/ZygoteConnection;->isClosedByPeer()Z
+HSPLcom/android/internal/os/ZygoteConnection;->isPreloadComplete()Z
+HSPLcom/android/internal/os/ZygoteConnection;->preload()V
 HSPLcom/android/internal/os/ZygoteConnection;->processOneCommand(Lcom/android/internal/os/ZygoteServer;)Ljava/lang/Runnable;
 HSPLcom/android/internal/os/ZygoteConnection;->setChildPgid(I)V
 HSPLcom/android/internal/os/ZygoteConnection;->stateChangeWithUsapPoolReset(Lcom/android/internal/os/ZygoteServer;Ljava/lang/Runnable;)Ljava/lang/Runnable;
@@ -20559,11 +21461,12 @@
 HSPLcom/android/internal/policy/DecorView$1;-><init>()V
 HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;-><init>(IIIIILjava/lang/String;IILcom/android/internal/policy/DecorView$1;)V
 HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isPresent(IIZ)Z
-PLcom/android/internal/policy/DecorView$ColorViewAttributes;->isVisible(IIIZ)Z
+HPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isVisible(IIIZ)Z
 HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isVisible(ZIIZ)Z
 HSPLcom/android/internal/policy/DecorView;-><init>(Landroid/content/Context;ILcom/android/internal/policy/PhoneWindow;Landroid/view/WindowManager$LayoutParams;)V
 HSPLcom/android/internal/policy/DecorView;->createDecorCaptionView(Landroid/view/LayoutInflater;)Lcom/android/internal/widget/DecorCaptionView;
 HSPLcom/android/internal/policy/DecorView;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
+HSPLcom/android/internal/policy/DecorView;->dispatchPopulateAccessibilityEventInternal(Landroid/view/accessibility/AccessibilityEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->draw(Landroid/graphics/Canvas;)V
 HSPLcom/android/internal/policy/DecorView;->drawResizingShadowIfNeeded(Landroid/graphics/RecordingCanvas;)V
@@ -20574,7 +21477,7 @@
 HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Landroid/graphics/Region;)Z
 HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Lcom/android/internal/policy/DecorView$ColorViewState;Landroid/graphics/Region;)Z
 HSPLcom/android/internal/policy/DecorView;->getAccessibilityViewId()I
-PLcom/android/internal/policy/DecorView;->getNavigationBarRect(IILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
+HPLcom/android/internal/policy/DecorView;->getNavigationBarRect(IILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
 HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;
 HSPLcom/android/internal/policy/DecorView;->initResizingPaints()V
 HSPLcom/android/internal/policy/DecorView;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
@@ -20652,6 +21555,7 @@
 HSPLcom/android/internal/policy/PhoneWindow$RotationWatcher;-><init>()V
 HSPLcom/android/internal/policy/PhoneWindow;-><init>(Landroid/content/Context;)V
 HSPLcom/android/internal/policy/PhoneWindow;-><init>(Landroid/content/Context;Landroid/view/Window;Landroid/view/ViewRootImpl$ActivityConfigCallback;)V
+HSPLcom/android/internal/policy/PhoneWindow;->alwaysReadCloseOnTouchAttr()V
 HSPLcom/android/internal/policy/PhoneWindow;->closeAllPanels()V
 HSPLcom/android/internal/policy/PhoneWindow;->closeContextMenu()V
 HSPLcom/android/internal/policy/PhoneWindow;->closePanel(Lcom/android/internal/policy/PhoneWindow$PanelFeatureState;Z)V
@@ -20666,12 +21570,14 @@
 HSPLcom/android/internal/policy/PhoneWindow;->getPanelState(IZ)Lcom/android/internal/policy/PhoneWindow$PanelFeatureState;
 HSPLcom/android/internal/policy/PhoneWindow;->getPanelState(IZLcom/android/internal/policy/PhoneWindow$PanelFeatureState;)Lcom/android/internal/policy/PhoneWindow$PanelFeatureState;
 HSPLcom/android/internal/policy/PhoneWindow;->getTransition(Landroid/transition/Transition;Landroid/transition/Transition;I)Landroid/transition/Transition;
+HSPLcom/android/internal/policy/PhoneWindow;->getVolumeControlStream()I
 HSPLcom/android/internal/policy/PhoneWindow;->installDecor()V
 HSPLcom/android/internal/policy/PhoneWindow;->invalidatePanelMenu(I)V
 HSPLcom/android/internal/policy/PhoneWindow;->isFloating()Z
 HSPLcom/android/internal/policy/PhoneWindow;->isShowingWallpaper()Z
 HSPLcom/android/internal/policy/PhoneWindow;->isTranslucent()Z
 HSPLcom/android/internal/policy/PhoneWindow;->onActive()V
+HSPLcom/android/internal/policy/PhoneWindow;->onKeyDown(IILandroid/view/KeyEvent;)Z
 HSPLcom/android/internal/policy/PhoneWindow;->onKeyUp(IILandroid/view/KeyEvent;)Z
 HSPLcom/android/internal/policy/PhoneWindow;->onViewRootImplSet(Landroid/view/ViewRootImpl;)V
 HSPLcom/android/internal/policy/PhoneWindow;->openPanelsAfterRestore()V
@@ -20732,6 +21638,7 @@
 PLcom/android/internal/statusbar/NotificationVisibility$NotificationLocation;->values()[Lcom/android/internal/statusbar/NotificationVisibility$NotificationLocation;
 HPLcom/android/internal/statusbar/NotificationVisibility;->readFromParcel(Landroid/os/Parcel;)V
 HSPLcom/android/internal/statusbar/NotificationVisibility;->recycle()V
+HSPLcom/android/internal/statusbar/StatusBarIcon;-><init>(Landroid/os/UserHandle;Ljava/lang/String;Landroid/graphics/drawable/Icon;IILjava/lang/CharSequence;)V
 PLcom/android/internal/telecom/IConnectionService$Stub$Proxy;->addConnectionServiceAdapter(Lcom/android/internal/telecom/IConnectionServiceAdapter;Landroid/telecom/Logging/Session$Info;)V
 PLcom/android/internal/telecom/IConnectionService$Stub$Proxy;->createConnection(Landroid/telecom/PhoneAccountHandle;Ljava/lang/String;Landroid/telecom/ConnectionRequest;ZZLandroid/telecom/Logging/Session$Info;)V
 PLcom/android/internal/telecom/IConnectionService$Stub$Proxy;->createConnectionComplete(Ljava/lang/String;Landroid/telecom/Logging/Session$Info;)V
@@ -20749,6 +21656,7 @@
 PLcom/android/internal/telecom/IInCallService$Stub$Proxy;->setInCallAdapter(Lcom/android/internal/telecom/IInCallAdapter;)V
 HPLcom/android/internal/telecom/IInCallService$Stub$Proxy;->updateCall(Landroid/telecom/ParcelableCall;)V
 PLcom/android/internal/telecom/IInCallService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telecom/IInCallService;
+HPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->addNewIncomingCall(Landroid/telecom/PhoneAccountHandle;Landroid/os/Bundle;)V
 HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->getCallCapablePhoneAccounts(ZLjava/lang/String;)Ljava/util/List;
 HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->getCallState()I
 HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->getCurrentTtyMode(Ljava/lang/String;)I
@@ -20759,10 +21667,12 @@
 HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->getSystemDialerPackage()Ljava/lang/String;
 HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->getUserSelectedOutgoingPhoneAccount(Ljava/lang/String;)Landroid/telecom/PhoneAccountHandle;
 HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->isInCall(Ljava/lang/String;)Z
+HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->isVoiceMailNumber(Landroid/telecom/PhoneAccountHandle;Ljava/lang/String;Ljava/lang/String;)Z
 HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->registerPhoneAccount(Landroid/telecom/PhoneAccount;)V
 HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->unregisterPhoneAccount(Landroid/telecom/PhoneAccountHandle;)V
 HSPLcom/android/internal/telecom/ITelecomService$Stub;-><init>()V
 HSPLcom/android/internal/telecom/ITelecomService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telecom/ITelecomService;
+HPLcom/android/internal/telecom/ITelecomService$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLcom/android/internal/telecom/ITelecomService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/telecom/IVideoProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telecom/IVideoProvider;
 PLcom/android/internal/telecom/RemoteServiceCallback$Stub$Proxy;->onResult(Ljava/util/List;Ljava/util/List;)V
@@ -20868,11 +21778,14 @@
 HSPLcom/android/internal/telephony/BaseCommands;->unregisterForCallWaitingInfo(Landroid/os/Handler;)V
 HSPLcom/android/internal/telephony/BaseCommands;->unregisterForCdmaOtaProvision(Landroid/os/Handler;)V
 HSPLcom/android/internal/telephony/BaseCommands;->unregisterForCdmaPrlChanged(Landroid/os/Handler;)V
+HPLcom/android/internal/telephony/BaseCommands;->unregisterForInCallVoicePrivacyOff(Landroid/os/Handler;)V
+HPLcom/android/internal/telephony/BaseCommands;->unregisterForInCallVoicePrivacyOn(Landroid/os/Handler;)V
 HSPLcom/android/internal/telephony/BaseCommands;->unregisterForLceInfo(Landroid/os/Handler;)V
 HSPLcom/android/internal/telephony/BaseCommands;->unregisterForNattKeepaliveStatus(Landroid/os/Handler;)V
 PLcom/android/internal/telephony/BlockChecker;->getBlockStatus(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)I
 HSPLcom/android/internal/telephony/Call$SrvccState;-><init>(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/Call$State;-><init>(Ljava/lang/String;I)V
+HPLcom/android/internal/telephony/Call$State;->isRinging()Z
 HSPLcom/android/internal/telephony/Call$State;->values()[Lcom/android/internal/telephony/Call$State;
 HSPLcom/android/internal/telephony/Call;->clearDisconnected()V
 HSPLcom/android/internal/telephony/Call;->getEarliestConnection()Lcom/android/internal/telephony/Connection;
@@ -20882,7 +21795,13 @@
 HSPLcom/android/internal/telephony/Call;->setState(Lcom/android/internal/telephony/Call$State;)V
 HSPLcom/android/internal/telephony/CallManager$CallManagerHandler;->handleMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/CallManager;-><init>()V
+HPLcom/android/internal/telephony/CallManager;->getActiveFgCall(I)Lcom/android/internal/telephony/Call;
+HPLcom/android/internal/telephony/CallManager;->getActiveFgCallState(I)Lcom/android/internal/telephony/Call$State;
+HPLcom/android/internal/telephony/CallManager;->getFirstNonIdleCall(Ljava/util/List;I)Lcom/android/internal/telephony/Call;
 HSPLcom/android/internal/telephony/CallManager;->getInstance()Lcom/android/internal/telephony/CallManager;
+HPLcom/android/internal/telephony/CallManager;->getPhone(I)Lcom/android/internal/telephony/Phone;
+HPLcom/android/internal/telephony/CallManager;->hasActiveFgCall()Z
+HPLcom/android/internal/telephony/CallManager;->hasMoreThanOneRingingCall()Z
 HSPLcom/android/internal/telephony/CallManager;->registerForDisconnect(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/CallManager;->registerForDisplayInfo(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/CallManager;->registerForInCallVoicePrivacyOff(Landroid/os/Handler;ILjava/lang/Object;)V
@@ -20895,9 +21814,10 @@
 HSPLcom/android/internal/telephony/CallManager;->registerPhone(Lcom/android/internal/telephony/Phone;)Z
 HSPLcom/android/internal/telephony/CallTracker;->handleRadioAvailable()V
 HSPLcom/android/internal/telephony/CallTracker;->pollCallsWhenSafe()V
-PLcom/android/internal/telephony/CallerInfo;->doSecondaryLookupIfNecessary(Landroid/content/Context;Ljava/lang/String;Lcom/android/internal/telephony/CallerInfo;)Lcom/android/internal/telephony/CallerInfo;
-PLcom/android/internal/telephony/CallerInfo;->getCallerInfo(Landroid/content/Context;Landroid/net/Uri;Landroid/database/Cursor;)Lcom/android/internal/telephony/CallerInfo;
-PLcom/android/internal/telephony/CallerInfo;->getCurrentCountryIso(Landroid/content/Context;Ljava/util/Locale;)Ljava/lang/String;
+HPLcom/android/internal/telephony/CallerInfo;->doSecondaryLookupIfNecessary(Landroid/content/Context;Ljava/lang/String;Lcom/android/internal/telephony/CallerInfo;)Lcom/android/internal/telephony/CallerInfo;
+HPLcom/android/internal/telephony/CallerInfo;->getCallerInfo(Landroid/content/Context;Landroid/net/Uri;Landroid/database/Cursor;)Lcom/android/internal/telephony/CallerInfo;
+HPLcom/android/internal/telephony/CallerInfo;->getCurrentCountryIso(Landroid/content/Context;Ljava/util/Locale;)Ljava/lang/String;
+HPLcom/android/internal/telephony/CallerInfo;->getGeoDescription(Landroid/content/Context;Ljava/lang/String;)Ljava/lang/String;
 HPLcom/android/internal/telephony/CallerInfo;->toString()Ljava/lang/String;
 PLcom/android/internal/telephony/CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler$1;->run()V
 HPLcom/android/internal/telephony/CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler$CallerInfoWorkerHandler;->handleMessage(Landroid/os/Message;)V
@@ -20955,7 +21875,7 @@
 HSPLcom/android/internal/telephony/CarrierServiceBindHelper$AppBinding;->unbind(Z)V
 HSPLcom/android/internal/telephony/CarrierServiceBindHelper$CarrierServicePackageMonitor;->evaluateBinding(Ljava/lang/String;Z)V
 HSPLcom/android/internal/telephony/CarrierServiceBindHelper$CarrierServicePackageMonitor;->onPackageModified(Ljava/lang/String;)V
-PLcom/android/internal/telephony/CarrierServiceBindHelper$CarrierServicePackageMonitor;->onPackageUpdateFinished(Ljava/lang/String;I)V
+HPLcom/android/internal/telephony/CarrierServiceBindHelper$CarrierServicePackageMonitor;->onPackageUpdateFinished(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/CarrierServiceBindHelper;-><init>(Landroid/content/Context;)V
 HSPLcom/android/internal/telephony/CarrierServiceBindHelper;->updateForPhoneId(ILjava/lang/String;)V
 HSPLcom/android/internal/telephony/CarrierServiceStateTracker$1;->onSubscriptionsChanged()V
@@ -21011,13 +21931,43 @@
 HSPLcom/android/internal/telephony/CommandException$Error;-><init>(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/CommandException;->fromRilErrno(I)Lcom/android/internal/telephony/CommandException;
 HSPLcom/android/internal/telephony/CommandException;->getCommandError()Lcom/android/internal/telephony/CommandException$Error;
+HPLcom/android/internal/telephony/Connection;-><init>(I)V
+HPLcom/android/internal/telephony/Connection;->addListener(Lcom/android/internal/telephony/Connection$Listener;)V
+HPLcom/android/internal/telephony/Connection;->addPostDialListener(Lcom/android/internal/telephony/Connection$PostDialListener;)V
+HPLcom/android/internal/telephony/Connection;->getAddress()Ljava/lang/String;
+HPLcom/android/internal/telephony/Connection;->getAudioModeIsVoip()Z
+HPLcom/android/internal/telephony/Connection;->getAudioQuality()I
+HPLcom/android/internal/telephony/Connection;->getCallRadioTech()I
+HPLcom/android/internal/telephony/Connection;->getCnapName()Ljava/lang/String;
+HPLcom/android/internal/telephony/Connection;->getCnapNamePresentation()I
+HPLcom/android/internal/telephony/Connection;->getConnectTime()J
+HPLcom/android/internal/telephony/Connection;->getConnectionCapabilities()I
+HPLcom/android/internal/telephony/Connection;->getConnectionExtras()Landroid/os/Bundle;
+HPLcom/android/internal/telephony/Connection;->getCreateTime()J
+HPLcom/android/internal/telephony/Connection;->getDisconnectCause()I
+HPLcom/android/internal/telephony/Connection;->getPhoneType()I
+HPLcom/android/internal/telephony/Connection;->getPostDialState()Lcom/android/internal/telephony/Connection$PostDialState;
+HPLcom/android/internal/telephony/Connection;->getTelecomCallId()Ljava/lang/String;
+HPLcom/android/internal/telephony/Connection;->getVideoProvider()Landroid/telecom/Connection$VideoProvider;
+HPLcom/android/internal/telephony/Connection;->getVideoState()I
+HPLcom/android/internal/telephony/Connection;->isActiveCallDisconnectedOnAnswer()Z
+HPLcom/android/internal/telephony/Connection;->isIncoming()Z
+HPLcom/android/internal/telephony/Connection;->isNetworkIdentifiedEmergencyCall()Z
+HPLcom/android/internal/telephony/Connection;->isPulledCall()Z
+HPLcom/android/internal/telephony/Connection;->notifyDisconnect(I)V
+HPLcom/android/internal/telephony/Connection;->removeListener(Lcom/android/internal/telephony/Connection$Listener;)V
+HPLcom/android/internal/telephony/Connection;->removePostDialListener(Lcom/android/internal/telephony/Connection$PostDialListener;)V
+HPLcom/android/internal/telephony/Connection;->setAudioQuality(I)V
+HPLcom/android/internal/telephony/Connection;->setCallRadioTech(I)V
+HPLcom/android/internal/telephony/Connection;->setTelecomCallId(Ljava/lang/String;)V
+HPLcom/android/internal/telephony/Connection;->shouldAllowAddCallDuringVideoCall()Z
 HSPLcom/android/internal/telephony/DctConstants$Activity;-><init>(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/DctConstants$Activity;->values()[Lcom/android/internal/telephony/DctConstants$Activity;
 HSPLcom/android/internal/telephony/DctConstants$State;-><init>(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/DctConstants$State;->values()[Lcom/android/internal/telephony/DctConstants$State;
 HSPLcom/android/internal/telephony/DebugService;-><init>()V
-PLcom/android/internal/telephony/DebugService;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
-PLcom/android/internal/telephony/DefaultPhoneNotifier;->convertDataActivityState(Lcom/android/internal/telephony/PhoneInternalInterface$DataActivityState;)I
+HPLcom/android/internal/telephony/DebugService;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
+HPLcom/android/internal/telephony/DefaultPhoneNotifier;->convertDataActivityState(Lcom/android/internal/telephony/PhoneInternalInterface$DataActivityState;)I
 HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->convertPreciseCallState(Lcom/android/internal/telephony/Call$State;)I
 HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->doNotifyDataConnection(Lcom/android/internal/telephony/Phone;Ljava/lang/String;Lcom/android/internal/telephony/PhoneConstants$DataState;)V
 HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->notifyCallForwardingChanged(Lcom/android/internal/telephony/Phone;)V
@@ -21037,7 +21987,7 @@
 HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->notifyServiceState(Lcom/android/internal/telephony/Phone;)V
 HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->notifySignalStrength(Lcom/android/internal/telephony/Phone;)V
 HSPLcom/android/internal/telephony/DeviceStateMonitor$1;->onAvailable(Landroid/net/Network;)V
-PLcom/android/internal/telephony/DeviceStateMonitor$1;->onLost(Landroid/net/Network;)V
+HPLcom/android/internal/telephony/DeviceStateMonitor$1;->onLost(Landroid/net/Network;)V
 HSPLcom/android/internal/telephony/DeviceStateMonitor$2;->onDisplayChanged(I)V
 HSPLcom/android/internal/telephony/DeviceStateMonitor$3;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
 HSPLcom/android/internal/telephony/DeviceStateMonitor;-><init>(Lcom/android/internal/telephony/Phone;)V
@@ -21054,12 +22004,15 @@
 HSPLcom/android/internal/telephony/ExponentialBackoff;-><init>(JJILandroid/os/Looper;Ljava/lang/Runnable;)V
 HSPLcom/android/internal/telephony/ExponentialBackoff;->stop()V
 HSPLcom/android/internal/telephony/GlobalSettingsHelper;->getSettingName(Landroid/content/Context;Ljava/lang/String;I)Ljava/lang/String;
+HSPLcom/android/internal/telephony/GlobalSettingsHelper;->setInt(Landroid/content/Context;Ljava/lang/String;II)Z
 HSPLcom/android/internal/telephony/GsmAlphabet;->enableCountrySpecificEncodings()V
 HSPLcom/android/internal/telephony/GsmAlphabet;->gsm7BitPackedToString([BIIIII)Ljava/lang/String;
 HSPLcom/android/internal/telephony/GsmAlphabet;->gsm8BitUnpackedToString([BIILjava/lang/String;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/GsmCdmaCall;->getConnections()Ljava/util/List;
+HPLcom/android/internal/telephony/GsmCdmaCall;->getPhone()Lcom/android/internal/telephony/Phone;
 HSPLcom/android/internal/telephony/GsmCdmaCallTracker;-><init>(Lcom/android/internal/telephony/GsmCdmaPhone;)V
 HSPLcom/android/internal/telephony/GsmCdmaCallTracker;->dispatchCsCallRadioTech(I)V
+HPLcom/android/internal/telephony/GsmCdmaCallTracker;->getPhone()Lcom/android/internal/telephony/GsmCdmaPhone;
 HSPLcom/android/internal/telephony/GsmCdmaCallTracker;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
 HSPLcom/android/internal/telephony/GsmCdmaCallTracker;->handleMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/GsmCdmaCallTracker;->handlePollCalls(Landroid/os/AsyncResult;)V
@@ -21079,7 +22032,7 @@
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getCallTracker()Lcom/android/internal/telephony/CallTracker;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getCarrierId()I
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getCarrierInfoForImsiEncryption(I)Landroid/telephony/ImsiEncryptionInfo;
-PLcom/android/internal/telephony/GsmCdmaPhone;->getCellLocation(Landroid/os/WorkSource;Landroid/os/Message;)V
+HPLcom/android/internal/telephony/GsmCdmaPhone;->getCellLocation(Landroid/os/WorkSource;Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getCsCallRadioTech(II)I
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getDataActivityState()Lcom/android/internal/telephony/PhoneInternalInterface$DataActivityState;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getDataConnectionState(Ljava/lang/String;)Lcom/android/internal/telephony/PhoneConstants$DataState;
@@ -21092,11 +22045,11 @@
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getGroupIdLevel1()Ljava/lang/String;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getGroupIdLevel2()Ljava/lang/String;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getIccCard()Lcom/android/internal/telephony/IccCard;
-PLcom/android/internal/telephony/GsmCdmaPhone;->getIccPhoneBookInterfaceManager()Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;
+HPLcom/android/internal/telephony/GsmCdmaPhone;->getIccPhoneBookInterfaceManager()Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getIccRecordsLoaded()Z
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getIccSerialNumber()Ljava/lang/String;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getIccSmsInterfaceManager()Lcom/android/internal/telephony/IccSmsInterfaceManager;
-PLcom/android/internal/telephony/GsmCdmaPhone;->getImei()Ljava/lang/String;
+HPLcom/android/internal/telephony/GsmCdmaPhone;->getImei()Ljava/lang/String;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getIsimRecords()Lcom/android/internal/telephony/uicc/IsimRecords;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getLine1AlphaTag()Ljava/lang/String;
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->getLine1Number()Ljava/lang/String;
@@ -21132,6 +22085,7 @@
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->notifyCallForwardingIndicator()V
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->notifyLocationChanged(Landroid/telephony/CellLocation;)V
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->notifyPhoneStateChanged()V
+HSPLcom/android/internal/telephony/GsmCdmaPhone;->notifyPreciseCallStateChanged()V
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->notifyServiceStateChanged(Landroid/telephony/ServiceState;)V
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->onUpdateIccAvailability()V
 HSPLcom/android/internal/telephony/GsmCdmaPhone;->phoneObjectUpdater(I)V
@@ -21166,15 +22120,15 @@
 HSPLcom/android/internal/telephony/HardwareConfig;->assignSim(Ljava/lang/String;ILjava/lang/String;)V
 HSPLcom/android/internal/telephony/HardwareConfig;->toString()Ljava/lang/String;
 HSPLcom/android/internal/telephony/ICarrierConfigLoader$Stub$Proxy;->getConfigForSubId(ILjava/lang/String;)Landroid/os/PersistableBundle;
-PLcom/android/internal/telephony/ICarrierConfigLoader$Stub$Proxy;->getDefaultCarrierServicePackageName()Ljava/lang/String;
+HPLcom/android/internal/telephony/ICarrierConfigLoader$Stub$Proxy;->getDefaultCarrierServicePackageName()Ljava/lang/String;
 HSPLcom/android/internal/telephony/ICarrierConfigLoader$Stub;-><init>()V
 HSPLcom/android/internal/telephony/ICarrierConfigLoader$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ICarrierConfigLoader;
 HSPLcom/android/internal/telephony/ICarrierConfigLoader$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
-PLcom/android/internal/telephony/IIccPhoneBook$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLcom/android/internal/telephony/IIccPhoneBook$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 PLcom/android/internal/telephony/IMms$Stub$Proxy;->getAutoPersisting()Z
 HSPLcom/android/internal/telephony/IMms$Stub;-><init>()V
 HSPLcom/android/internal/telephony/IMms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IMms;
-PLcom/android/internal/telephony/IMms$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HPLcom/android/internal/telephony/IMms$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/telephony/IOnSubscriptionsChangedListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLcom/android/internal/telephony/IOnSubscriptionsChangedListener$Stub$Proxy;->onSubscriptionsChanged()V
 HSPLcom/android/internal/telephony/IOnSubscriptionsChangedListener$Stub;-><init>()V
@@ -21207,6 +22161,7 @@
 HSPLcom/android/internal/telephony/IPhoneSubInfo$Stub;-><init>()V
 HSPLcom/android/internal/telephony/IPhoneSubInfo$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneSubInfo;
 HSPLcom/android/internal/telephony/IPhoneSubInfo$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLcom/android/internal/telephony/ISms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ISms;
 HSPLcom/android/internal/telephony/ISms$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/telephony/ISmsImplBase;-><init>()V
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getActiveSubIdList(Z)[I
@@ -21233,6 +22188,8 @@
 HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getDataNetworkTypeForSubscriber(ILjava/lang/String;)I
 HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getDataState()I
 HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getEmergencyNumberList(Ljava/lang/String;)Ljava/util/Map;
+HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getImeiForSlot(ILjava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getImsConfig(II)Landroid/telephony/ims/aidl/IImsConfig;
 HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getLine1NumberForDisplay(ILjava/lang/String;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getMergedSubscriberIds(Ljava/lang/String;)[Ljava/lang/String;
 HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getMmTelFeatureAndListen(ILcom/android/ims/internal/IImsServiceFeatureCallback;)Landroid/telephony/ims/aidl/IImsMmTelFeature;
@@ -21277,25 +22234,26 @@
 HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;->removeOnSubscriptionsChangedListener(Ljava/lang/String;Lcom/android/internal/telephony/IOnSubscriptionsChangedListener;)V
 HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub;-><init>()V
 HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry;
-PLcom/android/internal/telephony/ITelephonyRegistry$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLcom/android/internal/telephony/ITelephonyRegistry$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/telephony/IccCard;->getState()Lcom/android/internal/telephony/IccCardConstants$State;
 HSPLcom/android/internal/telephony/IccCard;->registerForNetworkLocked(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/IccCardConstants$State;-><init>(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/IccCardConstants$State;->values()[Lcom/android/internal/telephony/IccCardConstants$State;
-PLcom/android/internal/telephony/IccPhoneBookInterfaceManager$1;->handleMessage(Landroid/os/Message;)V
-PLcom/android/internal/telephony/IccPhoneBookInterfaceManager$1;->notifyPending(Lcom/android/internal/telephony/IccPhoneBookInterfaceManager$Request;Ljava/lang/Object;)V
-PLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->checkThread()V
-PLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->getAdnRecordsInEf(I)Ljava/util/List;
-PLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->logd(Ljava/lang/String;)V
+HPLcom/android/internal/telephony/IccPhoneBookInterfaceManager$1;->handleMessage(Landroid/os/Message;)V
+HPLcom/android/internal/telephony/IccPhoneBookInterfaceManager$1;->notifyPending(Lcom/android/internal/telephony/IccPhoneBookInterfaceManager$Request;Ljava/lang/Object;)V
+HPLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->checkThread()V
+HPLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->getAdnRecordsInEf(I)Ljava/util/List;
+HPLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->logd(Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->updateIccRecords(Lcom/android/internal/telephony/uicc/IccRecords;)V
-PLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->waitForResult(Lcom/android/internal/telephony/IccPhoneBookInterfaceManager$Request;)V
+HPLcom/android/internal/telephony/IccPhoneBookInterfaceManager;->waitForResult(Lcom/android/internal/telephony/IccPhoneBookInterfaceManager$Request;)V
 HSPLcom/android/internal/telephony/IccProvider;-><init>()V
-PLcom/android/internal/telephony/IccProvider;->getRequestSubId(Landroid/net/Uri;)I
+HPLcom/android/internal/telephony/IccProvider;->getRequestSubId(Landroid/net/Uri;)I
 HSPLcom/android/internal/telephony/IccProvider;->getType(Landroid/net/Uri;)Ljava/lang/String;
-PLcom/android/internal/telephony/IccProvider;->loadFromEf(II)Landroid/database/MatrixCursor;
+HPLcom/android/internal/telephony/IccProvider;->loadFromEf(II)Landroid/database/MatrixCursor;
+HPLcom/android/internal/telephony/IccProvider;->loadRecord(Lcom/android/internal/telephony/uicc/AdnRecord;Landroid/database/MatrixCursor;I)V
 HSPLcom/android/internal/telephony/IccProvider;->onCreate()Z
-PLcom/android/internal/telephony/IccProvider;->query(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
+HPLcom/android/internal/telephony/IccProvider;->query(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
 HSPLcom/android/internal/telephony/IccSmsInterfaceManager$1;->handleMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/IccSmsInterfaceManager$CdmaBroadcastRangeManager;->addRange(IIZ)V
 HSPLcom/android/internal/telephony/IccSmsInterfaceManager$CdmaBroadcastRangeManager;->finishUpdate()Z
@@ -21334,14 +22292,18 @@
 HSPLcom/android/internal/telephony/InboundSmsHandler$IdleState;->processMessage(Landroid/os/Message;)Z
 HSPLcom/android/internal/telephony/InboundSmsHandler$StartupState;->enter()V
 HSPLcom/android/internal/telephony/InboundSmsHandler$StartupState;->processMessage(Landroid/os/Message;)Z
-PLcom/android/internal/telephony/InboundSmsHandler$WaitingState;->enter()V
-PLcom/android/internal/telephony/InboundSmsHandler$WaitingState;->exit()V
-PLcom/android/internal/telephony/InboundSmsHandler$WaitingState;->processMessage(Landroid/os/Message;)Z
+HPLcom/android/internal/telephony/InboundSmsHandler$WaitingState;->enter()V
+HPLcom/android/internal/telephony/InboundSmsHandler$WaitingState;->exit()V
+HPLcom/android/internal/telephony/InboundSmsHandler$WaitingState;->processMessage(Landroid/os/Message;)Z
 HSPLcom/android/internal/telephony/InboundSmsHandler;-><init>(Ljava/lang/String;Landroid/content/Context;Lcom/android/internal/telephony/SmsStorageMonitor;Lcom/android/internal/telephony/Phone;Lcom/android/internal/telephony/CellBroadcastHandler;)V
 HSPLcom/android/internal/telephony/InboundSmsHandler;->addTrackerToRawTable(Lcom/android/internal/telephony/InboundSmsTracker;Z)I
 HSPLcom/android/internal/telephony/InboundSmsHandler;->addTrackerToRawTableAndSendMessage(Lcom/android/internal/telephony/InboundSmsTracker;Z)I
+HSPLcom/android/internal/telephony/InboundSmsHandler;->checkAndHandleDuplicate(Lcom/android/internal/telephony/InboundSmsTracker;)Z
 HSPLcom/android/internal/telephony/InboundSmsHandler;->deleteFromRawTable(Ljava/lang/String;[Ljava/lang/String;I)V
+HPLcom/android/internal/telephony/InboundSmsHandler;->dispatchIntent(Landroid/content/Intent;Ljava/lang/String;ILandroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/UserHandle;)V
 HSPLcom/android/internal/telephony/InboundSmsHandler;->dispatchMessage(Lcom/android/internal/telephony/SmsMessageBase;)I
+HSPLcom/android/internal/telephony/InboundSmsHandler;->dispatchNormalMessage(Lcom/android/internal/telephony/SmsMessageBase;)I
+HPLcom/android/internal/telephony/InboundSmsHandler;->filterSms([[BILcom/android/internal/telephony/InboundSmsTracker;Lcom/android/internal/telephony/InboundSmsHandler$SmsBroadcastReceiver;Z)Z
 HSPLcom/android/internal/telephony/InboundSmsHandler;->getPhone()Lcom/android/internal/telephony/Phone;
 HSPLcom/android/internal/telephony/InboundSmsHandler;->getWakeLockTimeout()I
 HSPLcom/android/internal/telephony/InboundSmsHandler;->log(Ljava/lang/String;)V
@@ -21439,7 +22401,7 @@
 HSPLcom/android/internal/telephony/Phone;->getCarrierActionAgent()Lcom/android/internal/telephony/CarrierActionAgent;
 HSPLcom/android/internal/telephony/Phone;->getCarrierSignalAgent()Lcom/android/internal/telephony/CarrierSignalAgent;
 HSPLcom/android/internal/telephony/Phone;->getContext()Landroid/content/Context;
-PLcom/android/internal/telephony/Phone;->getCurrentUiccAppType()Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+HPLcom/android/internal/telephony/Phone;->getCurrentUiccAppType()Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
 HSPLcom/android/internal/telephony/Phone;->getDataConnectionState()Lcom/android/internal/telephony/PhoneConstants$DataState;
 HSPLcom/android/internal/telephony/Phone;->getDataEnabledSettings()Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;
 HSPLcom/android/internal/telephony/Phone;->getDcTracker(I)Lcom/android/internal/telephony/dataconnection/DcTracker;
@@ -21464,11 +22426,11 @@
 HSPLcom/android/internal/telephony/Phone;->getVtDataUsage(Z)Landroid/net/NetworkStats;
 HSPLcom/android/internal/telephony/Phone;->handleMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/Phone;->hasMatchedTetherApnSetting()Z
-PLcom/android/internal/telephony/Phone;->isConcurrentVoiceAndDataAllowed()Z
+HPLcom/android/internal/telephony/Phone;->isConcurrentVoiceAndDataAllowed()Z
 HSPLcom/android/internal/telephony/Phone;->isDataAllowed(I)Z
 HSPLcom/android/internal/telephony/Phone;->isDataAllowed(ILcom/android/internal/telephony/dataconnection/DataConnectionReasons;)Z
 HSPLcom/android/internal/telephony/Phone;->isImsCapabilityAvailable(II)Z
-PLcom/android/internal/telephony/Phone;->isImsRegistered()Z
+HPLcom/android/internal/telephony/Phone;->isImsRegistered()Z
 HSPLcom/android/internal/telephony/Phone;->isInEcm()Z
 HSPLcom/android/internal/telephony/Phone;->isShuttingDown()Z
 HSPLcom/android/internal/telephony/Phone;->isVideoEnabled()Z
@@ -21491,6 +22453,7 @@
 HSPLcom/android/internal/telephony/Phone;->registerForDisplayInfo(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/Phone;->registerForEcmTimerReset(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/Phone;->registerForEmergencyCallToggle(Landroid/os/Handler;ILjava/lang/Object;)V
+HPLcom/android/internal/telephony/Phone;->registerForHandoverStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/Phone;->registerForInCallVoicePrivacyOff(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/Phone;->registerForInCallVoicePrivacyOn(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/Phone;->registerForIncomingRing(Landroid/os/Handler;ILjava/lang/Object;)V
@@ -21512,6 +22475,7 @@
 HSPLcom/android/internal/telephony/Phone;->requestCellInfoUpdate(Landroid/os/WorkSource;Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/Phone;->sendSubscriptionSettings(Z)V
 HSPLcom/android/internal/telephony/Phone;->setCellInfoMinInterval(I)V
+HPLcom/android/internal/telephony/Phone;->setEchoSuppressionEnabled()V
 HSPLcom/android/internal/telephony/Phone;->setOnPostDialCharacter(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/Phone;->setPreferredNetworkType(ILandroid/os/Message;)V
 HSPLcom/android/internal/telephony/Phone;->setPreferredNetworkTypeIfSimLoaded()V
@@ -21519,7 +22483,12 @@
 HSPLcom/android/internal/telephony/Phone;->setVoiceMessageCount(I)V
 HSPLcom/android/internal/telephony/Phone;->startLceAfterRadioIsAvailable()V
 HSPLcom/android/internal/telephony/Phone;->startMonitoringImsService()V
+HPLcom/android/internal/telephony/Phone;->unregisterForDisconnect(Landroid/os/Handler;)V
+HPLcom/android/internal/telephony/Phone;->unregisterForHandoverStateChanged(Landroid/os/Handler;)V
+HPLcom/android/internal/telephony/Phone;->unregisterForInCallVoicePrivacyOff(Landroid/os/Handler;)V
+HPLcom/android/internal/telephony/Phone;->unregisterForInCallVoicePrivacyOn(Landroid/os/Handler;)V
 HSPLcom/android/internal/telephony/Phone;->unregisterForNewRingingConnection(Landroid/os/Handler;)V
+HPLcom/android/internal/telephony/Phone;->unregisterForPreciseCallStateChanged(Landroid/os/Handler;)V
 HSPLcom/android/internal/telephony/Phone;->unregisterForUnknownConnection(Landroid/os/Handler;)V
 HSPLcom/android/internal/telephony/Phone;->unregisterForVideoCapabilityChanged(Landroid/os/Handler;)V
 HSPLcom/android/internal/telephony/Phone;->updateDataConnectionTracker()V
@@ -21562,9 +22531,9 @@
 HSPLcom/android/internal/telephony/PhoneSubInfoController;->getLine1AlphaTagForSubscriber(ILjava/lang/String;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/PhoneSubInfoController;->getLine1NumberForSubscriber(ILjava/lang/String;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/PhoneSubInfoController;->getSubscriberIdForSubscriber(ILjava/lang/String;)Ljava/lang/String;
-PLcom/android/internal/telephony/PhoneSubInfoController;->getVoiceMailNumberForSubscriber(ILjava/lang/String;)Ljava/lang/String;
+HPLcom/android/internal/telephony/PhoneSubInfoController;->getVoiceMailNumberForSubscriber(ILjava/lang/String;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/PhoneSubInfoController;->lambda$callPhoneMethodForSubIdWithPrivilegedCheck$24$PhoneSubInfoController(Ljava/lang/String;Landroid/content/Context;ILjava/lang/String;Ljava/lang/String;)Z
-PLcom/android/internal/telephony/PhoneSubInfoController;->lambda$getVoiceMailNumberForSubscriber$12$PhoneSubInfoController(Lcom/android/internal/telephony/Phone;)Ljava/lang/String;
+HPLcom/android/internal/telephony/PhoneSubInfoController;->lambda$getVoiceMailNumberForSubscriber$12$PhoneSubInfoController(Lcom/android/internal/telephony/Phone;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/PhoneSwitcher$1;->onAvailable(Landroid/net/Network;)V
 HSPLcom/android/internal/telephony/PhoneSwitcher$3;->onPhoneCapabilityChanged(Landroid/telephony/PhoneCapability;)V
 HSPLcom/android/internal/telephony/PhoneSwitcher$3;->onPreciseCallStateChanged(Landroid/telephony/PreciseCallState;)V
@@ -21612,6 +22581,7 @@
 HSPLcom/android/internal/telephony/RIL;->getCdmaSubscriptionSource(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->getCellInfoList(Landroid/os/Message;Landroid/os/WorkSource;)V
 HSPLcom/android/internal/telephony/RIL;->getCurrentCalls(Landroid/os/Message;)V
+HPLcom/android/internal/telephony/RIL;->getDataCallList(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->getDataRegistrationState(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->getDeviceIdentity(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->getHalVersion()Lcom/android/internal/telephony/HalVersion;
@@ -21626,7 +22596,7 @@
 HSPLcom/android/internal/telephony/RIL;->getRadioCapability(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->getRadioProxy(Landroid/os/Message;)Landroid/hardware/radio/V1_0/IRadio;
 HSPLcom/android/internal/telephony/RIL;->getSignalStrength(Landroid/os/Message;)V
-PLcom/android/internal/telephony/RIL;->getTelephonyRILTimingHistograms()Ljava/util/List;
+HPLcom/android/internal/telephony/RIL;->getTelephonyRILTimingHistograms()Ljava/util/List;
 HSPLcom/android/internal/telephony/RIL;->getVoiceRadioTechnology(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->getVoiceRegistrationState(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->iccCloseLogicalChannel(ILandroid/os/Message;)V
@@ -21644,8 +22614,10 @@
 HSPLcom/android/internal/telephony/RIL;->retToString(ILjava/lang/Object;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/RIL;->riljLog(Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/RIL;->riljLoge(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/RIL;->riljLogv(Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/RIL;->sendAck()V
 HSPLcom/android/internal/telephony/RIL;->sendDeviceState(IZLandroid/os/Message;)V
+HSPLcom/android/internal/telephony/RIL;->sendTerminalResponse(Ljava/lang/String;Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->setCdmaBroadcastConfig([Lcom/android/internal/telephony/cdma/CdmaSmsBroadcastConfigInfo;Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->setCdmaSubscriptionSource(ILandroid/os/Message;)V
 HSPLcom/android/internal/telephony/RIL;->setDataProfile([Landroid/telephony/data/DataProfile;ZLandroid/os/Message;)V
@@ -21708,6 +22680,8 @@
 HSPLcom/android/internal/telephony/RadioIndication;->physicalChannelConfigsIndication(Ljava/util/List;)V
 HSPLcom/android/internal/telephony/RadioIndication;->radioStateChanged(II)V
 HSPLcom/android/internal/telephony/RadioIndication;->rilConnected(I)V
+HSPLcom/android/internal/telephony/RadioIndication;->stkProactiveCommand(ILjava/lang/String;)V
+HSPLcom/android/internal/telephony/RadioIndication;->stkSessionEnd(I)V
 HSPLcom/android/internal/telephony/RadioIndication;->voiceRadioTechChanged(II)V
 HSPLcom/android/internal/telephony/RadioResponse;->convertHalCardStatus(Landroid/hardware/radio/V1_0/CardStatus;)Lcom/android/internal/telephony/uicc/IccCardStatus;
 HSPLcom/android/internal/telephony/RadioResponse;->deactivateDataCallResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;)V
@@ -21715,6 +22689,7 @@
 HSPLcom/android/internal/telephony/RadioResponse;->getCdmaSubscriptionSourceResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;I)V
 HSPLcom/android/internal/telephony/RadioResponse;->getCellInfoListResponse_1_2(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
 HSPLcom/android/internal/telephony/RadioResponse;->getCurrentCallsResponse_1_2(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
+HPLcom/android/internal/telephony/RadioResponse;->getDataCallListResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
 HSPLcom/android/internal/telephony/RadioResponse;->getDataRegistrationStateResponse_1_2(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_2/DataRegStateResult;)V
 HSPLcom/android/internal/telephony/RadioResponse;->getDeviceIdentityResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/RadioResponse;->getFacilityLockForAppResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;I)V
@@ -21741,6 +22716,7 @@
 HSPLcom/android/internal/telephony/RadioResponse;->responseIntArrayList(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
 HSPLcom/android/internal/telephony/RadioResponse;->responseStringArrayList(Lcom/android/internal/telephony/RIL;Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
 HSPLcom/android/internal/telephony/RadioResponse;->sendDeviceStateResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;)V
+HSPLcom/android/internal/telephony/RadioResponse;->sendTerminalResponseToSimResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;)V
 HSPLcom/android/internal/telephony/RadioResponse;->setCdmaBroadcastConfigResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;)V
 HSPLcom/android/internal/telephony/RadioResponse;->setCdmaSubscriptionSourceResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;)V
 HSPLcom/android/internal/telephony/RadioResponse;->setGsmBroadcastActivationResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;)V
@@ -21767,6 +22743,7 @@
 HSPLcom/android/internal/telephony/RetryManager;->getDelayForNextApn(Z)J
 HSPLcom/android/internal/telephony/RetryManager;->getNextApnSetting()Landroid/telephony/data/ApnSetting;
 HSPLcom/android/internal/telephony/RetryManager;->getRetryAfterDisconnectDelay()J
+HSPLcom/android/internal/telephony/RetryManager;->getRetryTimer()I
 HSPLcom/android/internal/telephony/RetryManager;->getWaitingApns()Ljava/util/ArrayList;
 HSPLcom/android/internal/telephony/RetryManager;->log(Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/RetryManager;->parseNonNegativeInt(Ljava/lang/String;Ljava/lang/String;)Landroid/util/Pair;
@@ -21844,7 +22821,7 @@
 HSPLcom/android/internal/telephony/ServiceStateTracker;->registerForSubscriptionInfoReady(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/ServiceStateTracker;->registerForVoiceRegStateOrRatChanged(Landroid/os/Handler;ILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/ServiceStateTracker;->requestAllCellInfo(Landroid/os/WorkSource;Landroid/os/Message;)V
-PLcom/android/internal/telephony/ServiceStateTracker;->requestCellLocation(Landroid/os/WorkSource;Landroid/os/Message;)V
+HPLcom/android/internal/telephony/ServiceStateTracker;->requestCellLocation(Landroid/os/WorkSource;Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/ServiceStateTracker;->resetServiceStateInIwlanMode()V
 HSPLcom/android/internal/telephony/ServiceStateTracker;->setCellInfoMinInterval(I)V
 HSPLcom/android/internal/telephony/ServiceStateTracker;->setPhyCellInfoFromCellIdentity(Landroid/telephony/ServiceState;Landroid/telephony/CellIdentity;)V
@@ -21874,20 +22851,21 @@
 HSPLcom/android/internal/telephony/SmsApplication$SmsApplicationData;->toString()Ljava/lang/String;
 HSPLcom/android/internal/telephony/SmsApplication$SmsPackageMonitor;->onPackageAppeared(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/SmsApplication$SmsPackageMonitor;->onPackageChanged()V
-PLcom/android/internal/telephony/SmsApplication$SmsPackageMonitor;->onPackageDisappeared(Ljava/lang/String;I)V
+HPLcom/android/internal/telephony/SmsApplication$SmsPackageMonitor;->onPackageDisappeared(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/SmsApplication$SmsPackageMonitor;->onPackageModified(Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/SmsApplication;->assignExclusiveSmsPermissionsToSystemApp(Landroid/content/Context;Landroid/content/pm/PackageManager;Landroid/app/AppOpsManager;Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/SmsApplication;->defaultSmsAppChanged(Landroid/content/Context;)V
 HSPLcom/android/internal/telephony/SmsApplication;->getApplication(Landroid/content/Context;ZI)Lcom/android/internal/telephony/SmsApplication$SmsApplicationData;
-PLcom/android/internal/telephony/SmsApplication;->getApplicationCollectionAsUser(Landroid/content/Context;I)Ljava/util/Collection;
+HPLcom/android/internal/telephony/SmsApplication;->getApplicationCollectionAsUser(Landroid/content/Context;I)Ljava/util/Collection;
 HSPLcom/android/internal/telephony/SmsApplication;->getApplicationCollectionInternal(Landroid/content/Context;I)Ljava/util/Collection;
 HSPLcom/android/internal/telephony/SmsApplication;->getApplicationForPackage(Ljava/util/Collection;Ljava/lang/String;)Lcom/android/internal/telephony/SmsApplication$SmsApplicationData;
 HSPLcom/android/internal/telephony/SmsApplication;->getDefaultMmsApplication(Landroid/content/Context;Z)Landroid/content/ComponentName;
+HPLcom/android/internal/telephony/SmsApplication;->getDefaultRespondViaMessageApplication(Landroid/content/Context;Z)Landroid/content/ComponentName;
 HSPLcom/android/internal/telephony/SmsApplication;->getDefaultSendToApplication(Landroid/content/Context;Z)Landroid/content/ComponentName;
 HSPLcom/android/internal/telephony/SmsApplication;->getDefaultSmsApplication(Landroid/content/Context;Z)Landroid/content/ComponentName;
 HSPLcom/android/internal/telephony/SmsApplication;->getDefaultSmsApplicationAsUser(Landroid/content/Context;ZI)Landroid/content/ComponentName;
 HSPLcom/android/internal/telephony/SmsApplication;->initSmsPackageMonitor(Landroid/content/Context;)V
-PLcom/android/internal/telephony/SmsApplication;->isDefaultSmsApplication(Landroid/content/Context;Ljava/lang/String;)Z
+HPLcom/android/internal/telephony/SmsApplication;->isDefaultSmsApplication(Landroid/content/Context;Ljava/lang/String;)Z
 HSPLcom/android/internal/telephony/SmsApplication;->replacePreferredActivity(Landroid/content/pm/PackageManager;Landroid/content/ComponentName;ILjava/lang/String;)V
 HSPLcom/android/internal/telephony/SmsApplication;->tryFixExclusiveSmsAppops(Landroid/content/Context;Lcom/android/internal/telephony/SmsApplication$SmsApplicationData;Z)Z
 HSPLcom/android/internal/telephony/SmsBroadcastUndelivered$1;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
@@ -21898,6 +22876,7 @@
 HSPLcom/android/internal/telephony/SmsDispatchersController;-><init>(Lcom/android/internal/telephony/Phone;Lcom/android/internal/telephony/SmsStorageMonitor;Lcom/android/internal/telephony/SmsUsageMonitor;)V
 HSPLcom/android/internal/telephony/SmsDispatchersController;->handleInService(J)V
 HSPLcom/android/internal/telephony/SmsDispatchersController;->handleMessage(Landroid/os/Message;)V
+HPLcom/android/internal/telephony/SmsDispatchersController;->handlePartialSegmentTimerExpiry(J)V
 HSPLcom/android/internal/telephony/SmsDispatchersController;->reevaluateTimerStatus()V
 HSPLcom/android/internal/telephony/SmsDispatchersController;->resetPartialSegmentWaitTimer()V
 HSPLcom/android/internal/telephony/SmsDispatchersController;->updateImsInfo(Landroid/os/AsyncResult;)V
@@ -21922,7 +22901,7 @@
 HSPLcom/android/internal/telephony/SubscriptionController;->enforceModifyPhoneState(Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/SubscriptionController;->getActiveSubIdArrayList()Ljava/util/ArrayList;
 HSPLcom/android/internal/telephony/SubscriptionController;->getActiveSubIdList(Z)[I
-PLcom/android/internal/telephony/SubscriptionController;->getActiveSubInfoCount(Ljava/lang/String;)I
+HPLcom/android/internal/telephony/SubscriptionController;->getActiveSubInfoCount(Ljava/lang/String;)I
 HSPLcom/android/internal/telephony/SubscriptionController;->getActiveSubInfoCountMax()I
 HSPLcom/android/internal/telephony/SubscriptionController;->getActiveSubscriptionInfo(ILjava/lang/String;)Landroid/telephony/SubscriptionInfo;
 HSPLcom/android/internal/telephony/SubscriptionController;->getActiveSubscriptionInfoForSimSlotIndex(ILjava/lang/String;)Landroid/telephony/SubscriptionInfo;
@@ -22050,8 +23029,8 @@
 HSPLcom/android/internal/telephony/TimeZoneLookupHelper;->getCountryTimeZones(Ljava/lang/String;)Llibcore/timezone/CountryTimeZones;
 HSPLcom/android/internal/telephony/TimeZoneLookupHelper;->lookupByCountry(Ljava/lang/String;J)Lcom/android/internal/telephony/TimeZoneLookupHelper$CountryResult;
 HSPLcom/android/internal/telephony/TimeZoneLookupHelper;->lookupByNitzCountry(Lcom/android/internal/telephony/NitzData;Ljava/lang/String;)Lcom/android/internal/telephony/TimeZoneLookupHelper$OffsetResult;
-PLcom/android/internal/telephony/UiccPhoneBookController;->getAdnRecordsInEfForSubscriber(II)Ljava/util/List;
-PLcom/android/internal/telephony/UiccPhoneBookController;->getIccPhoneBookInterfaceManager(I)Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;
+HPLcom/android/internal/telephony/UiccPhoneBookController;->getAdnRecordsInEfForSubscriber(II)Ljava/util/List;
+HPLcom/android/internal/telephony/UiccPhoneBookController;->getIccPhoneBookInterfaceManager(I)Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;
 HSPLcom/android/internal/telephony/UiccSmsController;->disableCellBroadcastRangeForSubscriber(IIII)Z
 HSPLcom/android/internal/telephony/UiccSmsController;->enableCellBroadcastRangeForSubscriber(IIII)Z
 HSPLcom/android/internal/telephony/UiccSmsController;->getPreferredSmsSubscription()I
@@ -22069,14 +23048,25 @@
 HSPLcom/android/internal/telephony/cat/CatService;-><init>(Lcom/android/internal/telephony/CommandsInterface;Lcom/android/internal/telephony/uicc/UiccCardApplication;Lcom/android/internal/telephony/uicc/IccRecords;Landroid/content/Context;Lcom/android/internal/telephony/uicc/IccFileHandler;Lcom/android/internal/telephony/uicc/UiccProfile;I)V
 HSPLcom/android/internal/telephony/cat/CatService;->getInstance(I)Lcom/android/internal/telephony/cat/AppInterface;
 HSPLcom/android/internal/telephony/cat/CatService;->getInstance(Lcom/android/internal/telephony/CommandsInterface;Landroid/content/Context;Lcom/android/internal/telephony/uicc/UiccProfile;I)Lcom/android/internal/telephony/cat/CatService;
+HSPLcom/android/internal/telephony/cat/CatService;->handleCommand(Lcom/android/internal/telephony/cat/CommandParams;Z)V
 HSPLcom/android/internal/telephony/cat/CatService;->handleMessage(Landroid/os/Message;)V
+HSPLcom/android/internal/telephony/cat/CatService;->handleRilMsg(Lcom/android/internal/telephony/cat/RilMessage;)V
+HSPLcom/android/internal/telephony/cat/CatService;->handleSessionEnd()V
 HSPLcom/android/internal/telephony/cat/CatService;->isStkAppInstalled()Z
+HSPLcom/android/internal/telephony/cat/CatService;->sendTerminalResponse(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/ResultCode;ZILcom/android/internal/telephony/cat/ResponseData;)V
 HSPLcom/android/internal/telephony/cat/CatService;->updateIccAvailability()V
 HSPLcom/android/internal/telephony/cat/CommandParamsFactory;->getInstance(Lcom/android/internal/telephony/cat/RilMessageDecoder;Lcom/android/internal/telephony/uicc/IccFileHandler;)Lcom/android/internal/telephony/cat/CommandParamsFactory;
+HSPLcom/android/internal/telephony/cat/CommandParamsFactory;->make(Lcom/android/internal/telephony/cat/BerTlv;)V
+HSPLcom/android/internal/telephony/cat/CommandParamsFactory;->processCommandDetails(Ljava/util/List;)Lcom/android/internal/telephony/cat/CommandDetails;
 HSPLcom/android/internal/telephony/cat/IconLoader;-><init>(Landroid/os/Looper;Lcom/android/internal/telephony/uicc/IccFileHandler;)V
 HSPLcom/android/internal/telephony/cat/IconLoader;->getInstance(Landroid/os/Handler;Lcom/android/internal/telephony/uicc/IccFileHandler;)Lcom/android/internal/telephony/cat/IconLoader;
+HSPLcom/android/internal/telephony/cat/RilMessageDecoder$StateCmdParamsReady;->processMessage(Landroid/os/Message;)Z
+HSPLcom/android/internal/telephony/cat/RilMessageDecoder$StateStart;->processMessage(Landroid/os/Message;)Z
 HSPLcom/android/internal/telephony/cat/RilMessageDecoder;-><init>(Landroid/os/Handler;Lcom/android/internal/telephony/uicc/IccFileHandler;)V
+HSPLcom/android/internal/telephony/cat/RilMessageDecoder;->decodeMessageParams(Lcom/android/internal/telephony/cat/RilMessage;)Z
 HSPLcom/android/internal/telephony/cat/RilMessageDecoder;->getInstance(Landroid/os/Handler;Lcom/android/internal/telephony/uicc/IccFileHandler;I)Lcom/android/internal/telephony/cat/RilMessageDecoder;
+HSPLcom/android/internal/telephony/cat/RilMessageDecoder;->sendMsgParamsDecoded(Lcom/android/internal/telephony/cat/ResultCode;Lcom/android/internal/telephony/cat/CommandParams;)V
+HSPLcom/android/internal/telephony/cat/RilMessageDecoder;->sendStartDecodingMessageParams(Lcom/android/internal/telephony/cat/RilMessage;)V
 HSPLcom/android/internal/telephony/cdma/CdmaInboundSmsHandler;-><init>(Landroid/content/Context;Lcom/android/internal/telephony/SmsStorageMonitor;Lcom/android/internal/telephony/Phone;Lcom/android/internal/telephony/cdma/CdmaSMSDispatcher;)V
 HSPLcom/android/internal/telephony/cdma/CdmaSMSDispatcher;->getFormat()Ljava/lang/String;
 HSPLcom/android/internal/telephony/cdma/CdmaSmsBroadcastConfigInfo;->getFromServiceCategory()I
@@ -22191,6 +23181,7 @@
 HSPLcom/android/internal/telephony/dataconnection/DataConnection;->isActivating()Z
 HSPLcom/android/internal/telephony/dataconnection/DataConnection;->isActive()Z
 HSPLcom/android/internal/telephony/dataconnection/DataConnection;->isDnsOk([Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/dataconnection/DataConnection;->isInactive()Z
 HSPLcom/android/internal/telephony/dataconnection/DataConnection;->isUnmeteredUseOnly()Z
 HSPLcom/android/internal/telephony/dataconnection/DataConnection;->log(Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/dataconnection/DataConnection;->makeDataConnection(Lcom/android/internal/telephony/Phone;ILcom/android/internal/telephony/dataconnection/DcTracker;Lcom/android/internal/telephony/dataconnection/DataServiceManager;Lcom/android/internal/telephony/dataconnection/DcTesterFailBringUpAll;Lcom/android/internal/telephony/dataconnection/DcController;)Lcom/android/internal/telephony/dataconnection/DataConnection;
@@ -22267,6 +23258,9 @@
 HSPLcom/android/internal/telephony/dataconnection/DcTracker$2;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
 HSPLcom/android/internal/telephony/dataconnection/DcTracker$3;->run()V
 HSPLcom/android/internal/telephony/dataconnection/DcTracker$ApnChangeObserver;->onChange(Z)V
+HPLcom/android/internal/telephony/dataconnection/DcTracker$DataStallRecoveryHandler;->broadcastDataStallDetected(I)V
+HPLcom/android/internal/telephony/dataconnection/DcTracker$DataStallRecoveryHandler;->checkRecovery()Z
+HPLcom/android/internal/telephony/dataconnection/DcTracker$DataStallRecoveryHandler;->doRecovery()V
 HSPLcom/android/internal/telephony/dataconnection/DcTracker$DataStallRecoveryHandler;->isAggressiveRecovery()Z
 HSPLcom/android/internal/telephony/dataconnection/DcTracker$DataStallRecoveryHandler;->isNoRxDataStallDetectionEnabled()Z
 HSPLcom/android/internal/telephony/dataconnection/DcTracker$DataStallRecoveryHandler;->isRecoveryOnBadNetworkEnabled()Z
@@ -22320,7 +23314,7 @@
 HSPLcom/android/internal/telephony/dataconnection/DcTracker;->onApnChanged()V
 HSPLcom/android/internal/telephony/dataconnection/DcTracker;->onDataConnectionAttached()V
 HSPLcom/android/internal/telephony/dataconnection/DcTracker;->onDataEnabledChanged(ZI)V
-PLcom/android/internal/telephony/dataconnection/DcTracker;->onDataReconnect(Landroid/os/Bundle;)V
+HPLcom/android/internal/telephony/dataconnection/DcTracker;->onDataReconnect(Landroid/os/Bundle;)V
 HSPLcom/android/internal/telephony/dataconnection/DcTracker;->onDataRoamingOff()V
 HSPLcom/android/internal/telephony/dataconnection/DcTracker;->onDataServiceBindingChanged(Z)V
 HSPLcom/android/internal/telephony/dataconnection/DcTracker;->onDataSetupComplete(Lcom/android/internal/telephony/dataconnection/ApnContext;ZII)V
@@ -22379,9 +23373,9 @@
 HSPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->getEmergencyNumberListTestMode()Ljava/util/List;
 HSPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->getLabeledEmergencyNumberForEcclist(Ljava/lang/String;)Landroid/telephony/emergency/EmergencyNumber;
 HSPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->handleMessage(Landroid/os/Message;)V
-PLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->isEmergencyNumber(Ljava/lang/String;Z)Z
-PLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->isEmergencyNumberForTest(Ljava/lang/String;)Z
-PLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->isEmergencyNumberFromEccList(Ljava/lang/String;Z)Z
+HPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->isEmergencyNumber(Ljava/lang/String;Z)Z
+HPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->isEmergencyNumberForTest(Ljava/lang/String;)Z
+HPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->isEmergencyNumberFromEccList(Ljava/lang/String;Z)Z
 HSPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->notifyEmergencyNumberList()V
 HSPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->onCarrierConfigChanged()V
 HSPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->updateEmergencyNumberDatabaseCountryChange(Ljava/lang/String;)V
@@ -22400,12 +23394,12 @@
 HSPLcom/android/internal/telephony/euicc/EuiccConnector$ConnectedState$4;->lambda$onComplete$0$EuiccConnector$ConnectedState$4(Lcom/android/internal/telephony/euicc/EuiccConnector$BaseEuiccCommandCallback;Landroid/service/euicc/GetEuiccProfileInfoListResult;)V
 HSPLcom/android/internal/telephony/euicc/EuiccConnector$ConnectedState$4;->onComplete(Landroid/service/euicc/GetEuiccProfileInfoListResult;)V
 HSPLcom/android/internal/telephony/euicc/EuiccConnector$ConnectedState;->enter()V
-PLcom/android/internal/telephony/euicc/EuiccConnector$ConnectedState;->exit()V
+HPLcom/android/internal/telephony/euicc/EuiccConnector$ConnectedState;->exit()V
 HSPLcom/android/internal/telephony/euicc/EuiccConnector$ConnectedState;->processMessage(Landroid/os/Message;)Z
 HSPLcom/android/internal/telephony/euicc/EuiccConnector$DisconnectedState;->enter()V
 HSPLcom/android/internal/telephony/euicc/EuiccConnector$DisconnectedState;->processMessage(Landroid/os/Message;)Z
 HSPLcom/android/internal/telephony/euicc/EuiccConnector$EuiccPackageMonitor;->onPackageModified(Ljava/lang/String;)V
-PLcom/android/internal/telephony/euicc/EuiccConnector$EuiccPackageMonitor;->onPackageUpdateFinished(Ljava/lang/String;I)V
+HPLcom/android/internal/telephony/euicc/EuiccConnector$EuiccPackageMonitor;->onPackageUpdateFinished(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/euicc/EuiccConnector$UnavailableState;->processMessage(Landroid/os/Message;)Z
 HSPLcom/android/internal/telephony/euicc/EuiccConnector;->createBinding()Z
 HSPLcom/android/internal/telephony/euicc/EuiccConnector;->findBestComponent(Landroid/content/pm/PackageManager;Ljava/util/List;)Landroid/content/pm/ComponentInfo;
@@ -22424,6 +23418,8 @@
 HSPLcom/android/internal/telephony/euicc/IEuiccController$Stub;-><init>()V
 HSPLcom/android/internal/telephony/euicc/IEuiccController$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/euicc/IEuiccController;
 HSPLcom/android/internal/telephony/gsm/GsmInboundSmsHandler;-><init>(Landroid/content/Context;Lcom/android/internal/telephony/SmsStorageMonitor;Lcom/android/internal/telephony/Phone;)V
+HPLcom/android/internal/telephony/gsm/GsmInboundSmsHandler;->dispatchMessageRadioSpecific(Lcom/android/internal/telephony/SmsMessageBase;)I
+HPLcom/android/internal/telephony/gsm/GsmInboundSmsHandler;->is3gpp2()Z
 HSPLcom/android/internal/telephony/gsm/GsmSMSDispatcher;-><init>(Lcom/android/internal/telephony/Phone;Lcom/android/internal/telephony/SmsDispatchersController;Lcom/android/internal/telephony/gsm/GsmInboundSmsHandler;)V
 HSPLcom/android/internal/telephony/gsm/GsmSMSDispatcher;->getFormat()Ljava/lang/String;
 HSPLcom/android/internal/telephony/gsm/GsmSMSDispatcher;->getUiccCardApplication()Lcom/android/internal/telephony/uicc/UiccCardApplication;
@@ -22433,13 +23429,18 @@
 HSPLcom/android/internal/telephony/gsm/SimTlv;->getData()[B
 HSPLcom/android/internal/telephony/gsm/SimTlv;->getTag()I
 HSPLcom/android/internal/telephony/gsm/SimTlv;->isValidObject()Z
+HPLcom/android/internal/telephony/gsm/SimTlv;->nextObject()Z
 HSPLcom/android/internal/telephony/gsm/SimTlv;->parseCurrentTlvObject()Z
 HSPLcom/android/internal/telephony/gsm/SmsBroadcastConfigInfo;->toString()Ljava/lang/String;
 HSPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;-><init>(Lcom/android/internal/telephony/uicc/IccFileHandler;Lcom/android/internal/telephony/uicc/AdnRecordCache;)V
-PLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->handleMessage(Landroid/os/Message;)V
-PLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->loadEfFilesFromUsim()Ljava/util/ArrayList;
-PLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->readPbrFileAndWait()V
+HPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->createPbrFile(Ljava/util/ArrayList;)V
+HPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->handleMessage(Landroid/os/Message;)V
+HPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->loadEfFilesFromUsim()Ljava/util/ArrayList;
+HPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->readAdnFileAndWait(I)V
+HPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->readEmailFileAndWait(I)V
+HPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->readPbrFileAndWait()V
 HSPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->reset()V
+HPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->updatePhoneAdnRecord()V
 HSPLcom/android/internal/telephony/ims/-$$Lambda$ImsResolver$SIkPixr-qGLIK-usUJIKu6S5BBs;-><init>()V
 HSPLcom/android/internal/telephony/ims/-$$Lambda$ImsResolver$SIkPixr-qGLIK-usUJIKu6S5BBs;->test(Ljava/lang/Object;)Z
 HSPLcom/android/internal/telephony/ims/-$$Lambda$ImsResolver$VfY5To_kbbTJevLzywTg-_S1JhA;->test(Ljava/lang/Object;)Z
@@ -22457,11 +23458,14 @@
 HSPLcom/android/internal/telephony/ims/ImsResolver$4;->create(Landroid/content/Context;Landroid/content/ComponentName;Lcom/android/internal/telephony/ims/ImsServiceController$ImsServiceControllerCallbacks;)Lcom/android/internal/telephony/ims/ImsServiceController;
 HSPLcom/android/internal/telephony/ims/ImsResolver$4;->getServiceInterface()Ljava/lang/String;
 HSPLcom/android/internal/telephony/ims/ImsResolver$5;->getServiceInterface()Ljava/lang/String;
+HSPLcom/android/internal/telephony/ims/ImsResolver$7;->onComplete(Landroid/content/ComponentName;Ljava/util/Set;)V
 HSPLcom/android/internal/telephony/ims/ImsResolver$ImsServiceInfo;->getSupportedFeatures()Ljava/util/HashSet;
+HSPLcom/android/internal/telephony/ims/ImsResolver$ImsServiceInfo;->replaceFeatures(Ljava/util/Set;)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;-><init>(Landroid/content/Context;Ljava/lang/String;IZ)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->bindImsServiceWithFeatures(Lcom/android/internal/telephony/ims/ImsResolver$ImsServiceInfo;Ljava/util/HashSet;)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->calculateFeaturesToCreate(Lcom/android/internal/telephony/ims/ImsResolver$ImsServiceInfo;)Ljava/util/HashSet;
 HSPLcom/android/internal/telephony/ims/ImsResolver;->carrierConfigChanged(I)V
+HSPLcom/android/internal/telephony/ims/ImsResolver;->dynamicQueryComplete(Landroid/content/ComponentName;Ljava/util/Set;)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->enableIms(I)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->getImsConfig(II)Landroid/telephony/ims/aidl/IImsConfig;
 HSPLcom/android/internal/telephony/ims/ImsResolver;->getImsRegistration(II)Landroid/telephony/ims/aidl/IImsRegistration;
@@ -22475,10 +23479,12 @@
 HSPLcom/android/internal/telephony/ims/ImsResolver;->initPopulateCacheAndStartBind()V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->lambda$new$0$ImsResolver(Landroid/os/Message;)Z
 HSPLcom/android/internal/telephony/ims/ImsResolver;->maybeAddedImsService(Ljava/lang/String;)V
-PLcom/android/internal/telephony/ims/ImsResolver;->maybeRemovedImsService(Ljava/lang/String;)Z
+HPLcom/android/internal/telephony/ims/ImsResolver;->maybeRemovedImsService(Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/ims/ImsResolver;->printFeatures(Ljava/util/Set;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/ims/ImsResolver;->putImsController(IILcom/android/internal/telephony/ims/ImsServiceController;)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->scheduleQueryForFeatures(Lcom/android/internal/telephony/ims/ImsResolver$ImsServiceInfo;I)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->searchForImsServices(Ljava/lang/String;Lcom/android/internal/telephony/ims/ImsResolver$ImsServiceControllerFactory;)Ljava/util/List;
+HSPLcom/android/internal/telephony/ims/ImsResolver;->startDynamicQuery(Lcom/android/internal/telephony/ims/ImsResolver$ImsServiceInfo;)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->unbindImsService(Lcom/android/internal/telephony/ims/ImsResolver$ImsServiceInfo;)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->updateBoundCarrierServices(ILjava/lang/String;)V
 HSPLcom/android/internal/telephony/ims/ImsResolver;->updateImsServiceFeatures(Lcom/android/internal/telephony/ims/ImsResolver$ImsServiceInfo;)V
@@ -22507,6 +23513,7 @@
 HSPLcom/android/internal/telephony/ims/ImsServiceController;->sendImsFeatureStatusChanged(III)V
 HSPLcom/android/internal/telephony/ims/ImsServiceController;->setServiceController(Landroid/os/IBinder;)V
 HSPLcom/android/internal/telephony/ims/ImsServiceController;->startBindToService(Landroid/content/Intent;Lcom/android/internal/telephony/ims/ImsServiceController$ImsServiceConnection;I)Z
+HSPLcom/android/internal/telephony/ims/ImsServiceFeatureQueryManager;->startQuery(Landroid/content/ComponentName;Ljava/lang/String;)Z
 HSPLcom/android/internal/telephony/ims/RcsMessageStoreController;-><init>(Landroid/content/ContentResolver;)V
 HSPLcom/android/internal/telephony/ims/RcsMessageStoreController;->init(Landroid/content/Context;)Lcom/android/internal/telephony/ims/RcsMessageStoreController;
 HSPLcom/android/internal/telephony/imsphone/-$$Lambda$ImsPhoneCallTracker$QlPVd_3u4_verjHUDnkn6zaSe54;-><init>()V
@@ -22538,7 +23545,7 @@
 HSPLcom/android/internal/telephony/imsphone/ImsPhone;->getVtDataUsage(Z)Landroid/net/NetworkStats;
 HSPLcom/android/internal/telephony/imsphone/ImsPhone;->handleMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhone;->isImsCapabilityAvailable(II)Z
-PLcom/android/internal/telephony/imsphone/ImsPhone;->isImsRegistered()Z
+HPLcom/android/internal/telephony/imsphone/ImsPhone;->isImsRegistered()Z
 HSPLcom/android/internal/telephony/imsphone/ImsPhone;->isInEcm()Z
 HSPLcom/android/internal/telephony/imsphone/ImsPhone;->isVideoEnabled()Z
 HSPLcom/android/internal/telephony/imsphone/ImsPhone;->isWifiCallingEnabled()Z
@@ -22554,6 +23561,7 @@
 HSPLcom/android/internal/telephony/imsphone/ImsPhone;->setServiceState(I)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhone;->updateDataServiceState()V
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneBase;-><init>(Ljava/lang/String;Landroid/content/Context;Lcom/android/internal/telephony/PhoneNotifier;Z)V
+HPLcom/android/internal/telephony/imsphone/ImsPhoneCall;->getPhone()Lcom/android/internal/telephony/Phone;
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker$1;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker$3;->connectionReady(Lcom/android/ims/ImsManager;)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker$6;->onRegistered(I)V
@@ -22566,11 +23574,13 @@
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker$9;->sendConfigChangedIntent(ILjava/lang/String;)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker$HoldSwapState;-><init>(Ljava/lang/String;I)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;-><init>(Lcom/android/internal/telephony/imsphone/ImsPhone;Ljava/util/concurrent/Executor;)V
+HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->addReasonCodeRemapping(Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/Integer;)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->cacheCarrierConfiguration(I)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getEcbmInterface()Lcom/android/ims/ImsEcbm;
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getImsRegistrationTech()I
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getMultiEndpointInterface()Lcom/android/ims/ImsMultiEndpoint;
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getPackageUid(Landroid/content/Context;Ljava/lang/String;)I
+HPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getPhone()Lcom/android/internal/telephony/imsphone/ImsPhone;
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getUtInterface()Lcom/android/ims/ImsUtInterface;
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getVtDataUsage(Z)Landroid/net/NetworkStats;
@@ -22589,39 +23599,52 @@
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->updateCarrierConfigCache(Landroid/os/PersistableBundle;)V
 HSPLcom/android/internal/telephony/imsphone/ImsPhoneFactory;->makePhone(Landroid/content/Context;Lcom/android/internal/telephony/PhoneNotifier;Lcom/android/internal/telephony/Phone;)Lcom/android/internal/telephony/imsphone/ImsPhone;
 HSPLcom/android/internal/telephony/metrics/-$$Lambda$TelephonyMetrics$tQOsX1lKb2eTuPp-1rpkeIAEOoY;->test(Ljava/lang/Object;)Z
-PLcom/android/internal/telephony/metrics/InProgressSmsSession;-><init>(I)V
-PLcom/android/internal/telephony/metrics/InProgressSmsSession;->addEvent(JLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;)V
-PLcom/android/internal/telephony/metrics/InProgressSmsSession;->isEventsDropped()Z
+HPLcom/android/internal/telephony/metrics/CallSessionEventBuilder;->build()Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event;
+HPLcom/android/internal/telephony/metrics/CallSessionEventBuilder;->setDelay(I)Lcom/android/internal/telephony/metrics/CallSessionEventBuilder;
+HPLcom/android/internal/telephony/metrics/InProgressCallSession;-><init>(I)V
+HPLcom/android/internal/telephony/metrics/InProgressCallSession;->addEvent(JLcom/android/internal/telephony/metrics/CallSessionEventBuilder;)V
+HPLcom/android/internal/telephony/metrics/InProgressCallSession;->addEvent(Lcom/android/internal/telephony/metrics/CallSessionEventBuilder;)V
+HPLcom/android/internal/telephony/metrics/InProgressCallSession;->containsCsCalls()Z
+HPLcom/android/internal/telephony/metrics/InProgressCallSession;->isEventsDropped()Z
+HPLcom/android/internal/telephony/metrics/InProgressCallSession;->setLastKnownPhoneState(I)V
+HPLcom/android/internal/telephony/metrics/InProgressSmsSession;-><init>(I)V
+HPLcom/android/internal/telephony/metrics/InProgressSmsSession;->addEvent(JLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;)V
+HPLcom/android/internal/telephony/metrics/InProgressSmsSession;->isEventsDropped()Z
 PLcom/android/internal/telephony/metrics/ModemPowerMetrics;->buildProto()Lcom/android/internal/telephony/nano/TelephonyProto$ModemPowerStats;
 PLcom/android/internal/telephony/metrics/ModemPowerMetrics;->getStats()Landroid/os/connectivity/CellularBatteryStats;
-PLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->build()Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;
-PLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->setDelay(I)Lcom/android/internal/telephony/metrics/SmsSessionEventBuilder;
+HPLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->build()Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;
+HPLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->setDelay(I)Lcom/android/internal/telephony/metrics/SmsSessionEventBuilder;
 HSPLcom/android/internal/telephony/metrics/TelephonyEventBuilder;->build()Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;
 HSPLcom/android/internal/telephony/metrics/TelephonyEventBuilder;->setSimStateChange(Landroid/util/SparseArray;)Lcom/android/internal/telephony/metrics/TelephonyEventBuilder;
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;-><init>()V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->addTelephonyEvent(Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->annotateInProgressCallSession(JILcom/android/internal/telephony/metrics/CallSessionEventBuilder;)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->annotateInProgressSmsSession(JILcom/android/internal/telephony/metrics/SmsSessionEventBuilder;)V
-PLcom/android/internal/telephony/metrics/TelephonyMetrics;->buildProto()Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyLog;
-PLcom/android/internal/telephony/metrics/TelephonyMetrics;->convertSmsFormat(Ljava/lang/String;)I
-PLcom/android/internal/telephony/metrics/TelephonyMetrics;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
-PLcom/android/internal/telephony/metrics/TelephonyMetrics;->finishSmsSession(Lcom/android/internal/telephony/metrics/InProgressSmsSession;)Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession;
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->buildProto()Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyLog;
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->convertSmsFormat(Ljava/lang/String;)I
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->finishCallSession(Lcom/android/internal/telephony/metrics/InProgressCallSession;)V
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->finishSmsSession(Lcom/android/internal/telephony/metrics/InProgressSmsSession;)Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession;
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->getInstance()Lcom/android/internal/telephony/metrics/TelephonyMetrics;
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->reset()V
-PLcom/android/internal/telephony/metrics/TelephonyMetrics;->startNewSmsSession(I)Lcom/android/internal/telephony/metrics/InProgressSmsSession;
-PLcom/android/internal/telephony/metrics/TelephonyMetrics;->toPrivacyFuzzedTimeInterval(JJ)I
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->startNewCallSessionIfNeeded(I)Lcom/android/internal/telephony/metrics/InProgressCallSession;
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->startNewSmsSession(I)Lcom/android/internal/telephony/metrics/InProgressSmsSession;
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->toPrivacyFuzzedTimeInterval(JJ)I
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->toServiceStateProto(Landroid/telephony/ServiceState;)Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyServiceState;
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->updateActiveSubscriptionInfoList(Ljava/util/List;)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->updateSimState(II)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeCarrierIdMatchingEvent(IIILjava/lang/String;Ljava/lang/String;)V
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeDataStallEvent(II)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeDataSwitch(ILcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$DataSwitch;)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeImsSetFeatureValue(IIII)V
-PLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeIncomingSmsSessionWithType(IIZLjava/lang/String;[JZZ)V
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeIncomingSmsSession(IZLjava/lang/String;[JZ)V
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeIncomingSmsSessionWithType(IIZLjava/lang/String;[JZZ)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeNITZEvent(IJ)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeOnImsCapabilities(IILandroid/telephony/ims/feature/MmTelFeature$MmTelCapabilities;)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeOnImsConnectionState(IILandroid/telephony/ims/ImsReasonInfo;)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeOnRilSolicitedResponse(IIIILjava/lang/Object;)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeOnSetupDataCallResponse(IIIILandroid/telephony/data/DataCallResponse;)V
+HPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writePhoneState(ILcom/android/internal/telephony/PhoneConstants$State;)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeRilDataCallEvent(IIII)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeRilDeactivateDataCall(IIII)V
 HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeServiceStateChanged(ILandroid/telephony/ServiceState;)V
@@ -22653,24 +23676,27 @@
 HSPLcom/android/internal/telephony/nano/TelephonyProto$RilDataCall;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$RilDataCall;
 HSPLcom/android/internal/telephony/nano/TelephonyProto$RilDataCall;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;->clear()Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;
-PLcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;
+HPLcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;->computeSerializedSize()I
+HPLcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;
+HPLcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
 PLcom/android/internal/telephony/nano/TelephonyProto$SmsSession;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession;
 HSPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event$RilCall;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event$RilCall;
 HSPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event;->clear()Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event;
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event;
 PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession;
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatching;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatchingResult;->computeSerializedSize()I
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatchingResult;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$DataSwitch;->computeSerializedSize()I
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$DataSwitch;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$RilSetupDataCall;->computeSerializedSize()I
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$RilSetupDataCall;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$RilSetupDataCallResponse;->computeSerializedSize()I
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$RilSetupDataCallResponse;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatching;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatchingResult;->computeSerializedSize()I
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatchingResult;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$DataSwitch;->computeSerializedSize()I
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$DataSwitch;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$RilSetupDataCall;->computeSerializedSize()I
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$RilSetupDataCall;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$RilSetupDataCallResponse;->computeSerializedSize()I
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$RilSetupDataCallResponse;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;->clear()Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;->computeSerializedSize()I
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;
-PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;->computeSerializedSize()I
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;
+HPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
 PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyHistogram;->computeSerializedSize()I
 PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyHistogram;->emptyArray()[Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyHistogram;
 PLcom/android/internal/telephony/nano/TelephonyProto$TelephonyHistogram;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
@@ -22693,43 +23719,46 @@
 HSPLcom/android/internal/telephony/protobuf/nano/CodedInputByteBufferNano;->skipField(I)Z
 HSPLcom/android/internal/telephony/protobuf/nano/CodedInputByteBufferNano;->skipRawBytes(I)V
 HSPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->checkNoSpaceLeft()V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->computeInt32Size(II)I
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->computeInt32SizeNoTag(I)I
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->computeMessageSize(ILcom/android/internal/telephony/protobuf/nano/MessageNano;)I
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->computeRawVarint64Size(J)I
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->computeInt32Size(II)I
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->computeInt32SizeNoTag(I)I
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->computeMessageSize(ILcom/android/internal/telephony/protobuf/nano/MessageNano;)I
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->computeRawVarint64Size(J)I
 HSPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->encode(Ljava/lang/CharSequence;Ljava/nio/ByteBuffer;)V
 HSPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->encode(Ljava/lang/CharSequence;[BII)I
 HSPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->encodedLength(Ljava/lang/CharSequence;)I
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeInt32(II)V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeInt32NoTag(I)V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeInt64(IJ)V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeInt64NoTag(J)V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeMessage(ILcom/android/internal/telephony/protobuf/nano/MessageNano;)V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeMessageNoTag(Lcom/android/internal/telephony/protobuf/nano/MessageNano;)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeInt32(II)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeInt32NoTag(I)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeInt64(IJ)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeInt64NoTag(J)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeMessage(ILcom/android/internal/telephony/protobuf/nano/MessageNano;)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeMessageNoTag(Lcom/android/internal/telephony/protobuf/nano/MessageNano;)V
 HSPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeRawByte(B)V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeRawByte(I)V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeRawLittleEndian64(J)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeRawByte(I)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeRawLittleEndian64(J)V
 HSPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeRawVarint32(I)V
 HSPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeRawVarint64(J)V
 HSPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeStringNoTag(Ljava/lang/String;)V
-PLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeTag(II)V
+HPLcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;->writeTag(II)V
 HSPLcom/android/internal/telephony/protobuf/nano/ExtendableMessageNano;->writeTo(Lcom/android/internal/telephony/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/internal/telephony/protobuf/nano/MessageNano;->getCachedSize()I
+HPLcom/android/internal/telephony/protobuf/nano/MessageNano;->getCachedSize()I
 HSPLcom/android/internal/telephony/protobuf/nano/MessageNano;->getSerializedSize()I
 HSPLcom/android/internal/telephony/protobuf/nano/MessageNano;->mergeFrom(Lcom/android/internal/telephony/protobuf/nano/MessageNano;[BII)Lcom/android/internal/telephony/protobuf/nano/MessageNano;
 HSPLcom/android/internal/telephony/protobuf/nano/MessageNano;->messageNanoEquals(Lcom/android/internal/telephony/protobuf/nano/MessageNano;Lcom/android/internal/telephony/protobuf/nano/MessageNano;)Z
 HSPLcom/android/internal/telephony/protobuf/nano/MessageNano;->toByteArray(Lcom/android/internal/telephony/protobuf/nano/MessageNano;[BII)V
 HSPLcom/android/internal/telephony/uicc/AdnRecord$1;-><init>()V
 HSPLcom/android/internal/telephony/uicc/AdnRecord;->getAlphaTag()Ljava/lang/String;
+HPLcom/android/internal/telephony/uicc/AdnRecord;->getEfid()I
 HSPLcom/android/internal/telephony/uicc/AdnRecord;->getNumber()Ljava/lang/String;
+HPLcom/android/internal/telephony/uicc/AdnRecord;->getRecId()I
 HSPLcom/android/internal/telephony/uicc/AdnRecord;->isEmpty()Z
 HSPLcom/android/internal/telephony/uicc/AdnRecord;->parseRecord([B)V
+HSPLcom/android/internal/telephony/uicc/AdnRecord;->toString()Ljava/lang/String;
 HSPLcom/android/internal/telephony/uicc/AdnRecordCache;-><init>(Lcom/android/internal/telephony/uicc/IccFileHandler;)V
 HSPLcom/android/internal/telephony/uicc/AdnRecordCache;->clearWaiters()V
-PLcom/android/internal/telephony/uicc/AdnRecordCache;->extensionEfForEf(I)I
-PLcom/android/internal/telephony/uicc/AdnRecordCache;->getRecordsIfLoaded(I)Ljava/util/ArrayList;
-PLcom/android/internal/telephony/uicc/AdnRecordCache;->handleMessage(Landroid/os/Message;)V
-PLcom/android/internal/telephony/uicc/AdnRecordCache;->requestLoadAllAdnLike(IILandroid/os/Message;)V
+HPLcom/android/internal/telephony/uicc/AdnRecordCache;->extensionEfForEf(I)I
+HPLcom/android/internal/telephony/uicc/AdnRecordCache;->getRecordsIfLoaded(I)Ljava/util/ArrayList;
+HPLcom/android/internal/telephony/uicc/AdnRecordCache;->handleMessage(Landroid/os/Message;)V
+HPLcom/android/internal/telephony/uicc/AdnRecordCache;->requestLoadAllAdnLike(IILandroid/os/Message;)V
 HSPLcom/android/internal/telephony/uicc/AdnRecordCache;->reset()V
 HSPLcom/android/internal/telephony/uicc/AdnRecordLoader;-><init>(Lcom/android/internal/telephony/uicc/IccFileHandler;)V
 HSPLcom/android/internal/telephony/uicc/AdnRecordLoader;->handleMessage(Landroid/os/Message;)V
@@ -22866,6 +23895,7 @@
 HSPLcom/android/internal/telephony/uicc/SIMRecords;->getOperatorNumeric()Ljava/lang/String;
 HSPLcom/android/internal/telephony/uicc/SIMRecords;->getSpnFsm(ZLandroid/os/AsyncResult;)V
 HSPLcom/android/internal/telephony/uicc/SIMRecords;->getVoiceCallForwardingFlag()I
+HSPLcom/android/internal/telephony/uicc/SIMRecords;->getVoiceMailNumber()Ljava/lang/String;
 HSPLcom/android/internal/telephony/uicc/SIMRecords;->getVoiceMessageCount()I
 HSPLcom/android/internal/telephony/uicc/SIMRecords;->handleMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/telephony/uicc/SIMRecords;->loadCallForwardingRecords()V
@@ -22926,6 +23956,7 @@
 HSPLcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules;->hasCarrierPrivilegeRules()Z
 HSPLcom/android/internal/telephony/uicc/UiccController;-><init>(Landroid/content/Context;[Lcom/android/internal/telephony/CommandsInterface;)V
 HSPLcom/android/internal/telephony/uicc/UiccController;->addCardId(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/uicc/UiccController;->addCardLog(Ljava/lang/String;)V
 HSPLcom/android/internal/telephony/uicc/UiccController;->convertToPublicCardId(Ljava/lang/String;)I
 HSPLcom/android/internal/telephony/uicc/UiccController;->getAllUiccCardInfos()Ljava/util/ArrayList;
 HSPLcom/android/internal/telephony/uicc/UiccController;->getCardIdForDefaultEuicc()I
@@ -22972,12 +24003,13 @@
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->getIccStateReason(Lcom/android/internal/telephony/IccCardConstants$State;)Ljava/lang/String;
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->getOperatorBrandOverride()Ljava/lang/String;
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->getPhoneId()I
+HSPLcom/android/internal/telephony/uicc/UiccProfile;->getServiceProviderName()Ljava/lang/String;
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->getState()Lcom/android/internal/telephony/IccCardConstants$State;
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->getUninstalledCarrierPackages()Ljava/util/Set;
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->handleCarrierNameOverride()V
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->handleSimCountryIsoOverride()V
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->hasCarrierPrivilegeRules()Z
-PLcom/android/internal/telephony/uicc/UiccProfile;->hasIccCard()Z
+HPLcom/android/internal/telephony/uicc/UiccProfile;->hasIccCard()Z
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->iccCloseLogicalChannel(ILandroid/os/Message;)V
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->iccOpenLogicalChannel(Ljava/lang/String;ILandroid/os/Message;)V
 HSPLcom/android/internal/telephony/uicc/UiccProfile;->iccTransmitApduLogicalChannel(IIIIIILjava/lang/String;Landroid/os/Message;)V
@@ -23037,6 +24069,7 @@
 PLcom/android/internal/textservice/ITextServicesSessionListener$Stub$Proxy;->onServiceConnected(Lcom/android/internal/textservice/ISpellCheckerSession;)V
 PLcom/android/internal/util/-$$Lambda$DumpUtils$vCLO_0ezRxkpSERUWCFrJ0ph5jg;->test(Ljava/lang/Object;)Z
 PLcom/android/internal/util/-$$Lambda$FunctionalUtils$koCSI8D7Nu5vOJTVTEj0m3leo_U;->run()V
+HSPLcom/android/internal/util/ArrayUtils;->add(Landroid/util/ArraySet;Ljava/lang/Object;)Landroid/util/ArraySet;
 HSPLcom/android/internal/util/ArrayUtils;->add(Ljava/util/ArrayList;Ljava/lang/Object;)Ljava/util/ArrayList;
 HSPLcom/android/internal/util/ArrayUtils;->appendElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
 HSPLcom/android/internal/util/ArrayUtils;->appendElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;Z)[Ljava/lang/Object;
@@ -23067,6 +24100,7 @@
 HSPLcom/android/internal/util/ArrayUtils;->referenceEquals(Ljava/util/ArrayList;Ljava/util/ArrayList;)Z
 HSPLcom/android/internal/util/ArrayUtils;->remove(Ljava/util/ArrayList;Ljava/lang/Object;)Ljava/util/ArrayList;
 HSPLcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->removeInt([II)[I
 HSPLcom/android/internal/util/ArrayUtils;->size(Ljava/util/Collection;)I
 HSPLcom/android/internal/util/ArrayUtils;->total([J)J
 HSPLcom/android/internal/util/ArrayUtils;->trimToSize([Ljava/lang/Object;I)[Ljava/lang/Object;
@@ -23097,11 +24131,14 @@
 HSPLcom/android/internal/util/BitUtils;->packBits([I)J
 HSPLcom/android/internal/util/BitUtils;->toBytes(J)[B
 HSPLcom/android/internal/util/BitUtils;->unpackBits(J)[I
+HPLcom/android/internal/util/CollectionUtils;->addIf(Ljava/util/List;Ljava/util/Collection;Ljava/util/function/Predicate;)V
+HSPLcom/android/internal/util/CollectionUtils;->copyOf(Ljava/util/Set;)Ljava/util/Set;
+HSPLcom/android/internal/util/CollectionUtils;->filter(Ljava/util/Set;Ljava/util/function/Predicate;)Ljava/util/Set;
 HSPLcom/android/internal/util/CollectionUtils;->firstOrNull(Ljava/util/Collection;)Ljava/lang/Object;
 HSPLcom/android/internal/util/CollectionUtils;->firstOrNull(Ljava/util/List;)Ljava/lang/Object;
 HSPLcom/android/internal/util/CollectionUtils;->isEmpty(Ljava/util/Collection;)Z
 HSPLcom/android/internal/util/CollectionUtils;->map(Ljava/util/Set;Ljava/util/function/Function;)Ljava/util/Set;
-PLcom/android/internal/util/CollectionUtils;->singletonOrEmpty(Ljava/lang/Object;)Ljava/util/List;
+HPLcom/android/internal/util/CollectionUtils;->singletonOrEmpty(Ljava/lang/Object;)Ljava/util/List;
 HSPLcom/android/internal/util/CollectionUtils;->size(Ljava/util/Collection;)I
 HSPLcom/android/internal/util/ConcurrentUtils$1$1;->run()V
 HSPLcom/android/internal/util/ConcurrentUtils$1;->newThread(Ljava/lang/Runnable;)Ljava/lang/Thread;
@@ -23112,17 +24149,17 @@
 HPLcom/android/internal/util/DumpUtils;->checkDumpAndUsageStatsPermission(Landroid/content/Context;Ljava/lang/String;Ljava/io/PrintWriter;)Z
 HSPLcom/android/internal/util/DumpUtils;->checkDumpPermission(Landroid/content/Context;Ljava/lang/String;Ljava/io/PrintWriter;)Z
 HPLcom/android/internal/util/DumpUtils;->checkUsageStatsPermission(Landroid/content/Context;Ljava/lang/String;Ljava/io/PrintWriter;)Z
-PLcom/android/internal/util/DumpUtils;->filterRecord(Ljava/lang/String;)Ljava/util/function/Predicate;
+HPLcom/android/internal/util/DumpUtils;->filterRecord(Ljava/lang/String;)Ljava/util/function/Predicate;
 HPLcom/android/internal/util/DumpUtils;->lambda$filterRecord$2(ILjava/lang/String;Landroid/content/ComponentName$WithComponentName;)Z
 HSPLcom/android/internal/util/ExponentiallyBucketedHistogram;-><init>(I)V
 HSPLcom/android/internal/util/ExponentiallyBucketedHistogram;->add(I)V
 HSPLcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/OutputStream;)V
 HSPLcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/OutputStream;ZI)V
-PLcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/Writer;)V
+HPLcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/Writer;)V
 HSPLcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/Writer;ZI)V
 HSPLcom/android/internal/util/FastPrintWriter;->appendLocked(Ljava/lang/String;II)V
 HPLcom/android/internal/util/FastPrintWriter;->appendLocked([CII)V
-PLcom/android/internal/util/FastPrintWriter;->checkError()Z
+HPLcom/android/internal/util/FastPrintWriter;->checkError()Z
 HSPLcom/android/internal/util/FastPrintWriter;->close()V
 HSPLcom/android/internal/util/FastPrintWriter;->flush()V
 HSPLcom/android/internal/util/FastPrintWriter;->flushBytesLocked()V
@@ -23162,9 +24199,9 @@
 HSPLcom/android/internal/util/FileRotator;->writeFile(Ljava/io/File;Lcom/android/internal/util/FileRotator$Writer;)V
 HSPLcom/android/internal/util/FunctionalUtils$RemoteExceptionIgnoringConsumer;->accept(Ljava/lang/Object;)V
 HSPLcom/android/internal/util/FunctionalUtils$ThrowingConsumer;->accept(Ljava/lang/Object;)V
-PLcom/android/internal/util/FunctionalUtils$ThrowingRunnable;->run()V
-PLcom/android/internal/util/FunctionalUtils;->handleExceptions(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;Ljava/util/function/Consumer;)Ljava/lang/Runnable;
-PLcom/android/internal/util/FunctionalUtils;->lambda$handleExceptions$0(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;Ljava/util/function/Consumer;)V
+HPLcom/android/internal/util/FunctionalUtils$ThrowingRunnable;->run()V
+HPLcom/android/internal/util/FunctionalUtils;->handleExceptions(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;Ljava/util/function/Consumer;)Ljava/lang/Runnable;
+HPLcom/android/internal/util/FunctionalUtils;->lambda$handleExceptions$0(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;Ljava/util/function/Consumer;)V
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([III)[I
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([JIJ)[J
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;
@@ -23220,6 +24257,7 @@
 HSPLcom/android/internal/util/Preconditions;->checkArgument(ZLjava/lang/Object;)V
 HSPLcom/android/internal/util/Preconditions;->checkArgument(ZLjava/lang/String;[Ljava/lang/Object;)V
 HSPLcom/android/internal/util/Preconditions;->checkArgumentInRange(IIILjava/lang/String;)I
+HSPLcom/android/internal/util/Preconditions;->checkArgumentInRange(JJJLjava/lang/String;)J
 HSPLcom/android/internal/util/Preconditions;->checkArgumentNonNegative(FLjava/lang/String;)F
 HSPLcom/android/internal/util/Preconditions;->checkArgumentNonnegative(I)I
 HSPLcom/android/internal/util/Preconditions;->checkArgumentNonnegative(ILjava/lang/String;)I
@@ -23249,9 +24287,9 @@
 HSPLcom/android/internal/util/RingBuffer;->clear()V
 HSPLcom/android/internal/util/RingBuffer;->createNewItem()Ljava/lang/Object;
 HSPLcom/android/internal/util/RingBuffer;->getNextSlot()Ljava/lang/Object;
-PLcom/android/internal/util/RingBuffer;->isEmpty()Z
+HPLcom/android/internal/util/RingBuffer;->isEmpty()Z
 HSPLcom/android/internal/util/RingBuffer;->size()I
-PLcom/android/internal/util/RingBuffer;->toArray()[Ljava/lang/Object;
+HPLcom/android/internal/util/RingBuffer;->toArray()[Ljava/lang/Object;
 HSPLcom/android/internal/util/RingBufferIndices;->add()I
 HSPLcom/android/internal/util/ScreenShapeHelper;->getWindowOutsetBottomPx(Landroid/content/res/Resources;)I
 HSPLcom/android/internal/util/ScreenshotHelper;-><init>(Landroid/content/Context;)V
@@ -23314,7 +24352,7 @@
 HSPLcom/android/internal/util/StateMachine;->sendMessage(ILjava/lang/Object;)V
 HSPLcom/android/internal/util/StateMachine;->sendMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/util/StateMachine;->sendMessageAtFrontOfQueue(I)V
-PLcom/android/internal/util/StateMachine;->sendMessageAtFrontOfQueue(IIILjava/lang/Object;)V
+HPLcom/android/internal/util/StateMachine;->sendMessageAtFrontOfQueue(IIILjava/lang/Object;)V
 HSPLcom/android/internal/util/StateMachine;->sendMessageDelayed(IJ)V
 HSPLcom/android/internal/util/StateMachine;->sendMessageDelayed(Landroid/os/Message;J)V
 HSPLcom/android/internal/util/StateMachine;->setDbg(Z)V
@@ -23324,13 +24362,13 @@
 HSPLcom/android/internal/util/StateMachine;->start()V
 HSPLcom/android/internal/util/StateMachine;->transitionTo(Lcom/android/internal/util/IState;)V
 HSPLcom/android/internal/util/StateMachine;->unhandledMessage(Landroid/os/Message;)V
-PLcom/android/internal/util/SyncResultReceiver;->bundleFor(Landroid/os/Parcelable;)Landroid/os/Bundle;
+HPLcom/android/internal/util/SyncResultReceiver;->bundleFor(Landroid/os/Parcelable;)Landroid/os/Bundle;
 HSPLcom/android/internal/util/SyncResultReceiver;->send(ILandroid/os/Bundle;)V
 HSPLcom/android/internal/util/SyncResultReceiver;->waitResult()V
 HSPLcom/android/internal/util/TokenBucket;-><init>(II)V
 HSPLcom/android/internal/util/TokenBucket;-><init>(III)V
-PLcom/android/internal/util/TokenBucket;->get()Z
-PLcom/android/internal/util/TokenBucket;->get(I)I
+HPLcom/android/internal/util/TokenBucket;->get()Z
+HPLcom/android/internal/util/TokenBucket;->get(I)I
 HSPLcom/android/internal/util/VirtualRefBasePtr;-><init>(J)V
 HSPLcom/android/internal/util/VirtualRefBasePtr;->finalize()V
 HSPLcom/android/internal/util/VirtualRefBasePtr;->release()V
@@ -23339,7 +24377,7 @@
 HSPLcom/android/internal/util/WakeupMessage;-><init>(Landroid/content/Context;Landroid/os/Handler;Ljava/lang/String;IIILjava/lang/Object;)V
 HSPLcom/android/internal/util/WakeupMessage;-><init>(Landroid/content/Context;Landroid/os/Handler;Ljava/lang/String;Ljava/lang/Runnable;)V
 HSPLcom/android/internal/util/WakeupMessage;->cancel()V
-PLcom/android/internal/util/WakeupMessage;->onAlarm()V
+HPLcom/android/internal/util/WakeupMessage;->onAlarm()V
 HSPLcom/android/internal/util/WakeupMessage;->schedule(J)V
 HSPLcom/android/internal/util/XmlUtils;->beginDocument(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;)V
 HSPLcom/android/internal/util/XmlUtils;->convertValueToBoolean(Ljava/lang/CharSequence;Z)Z
@@ -23408,8 +24446,11 @@
 PLcom/android/internal/view/BaseIWindow;->dispatchAppVisibility(Z)V
 HSPLcom/android/internal/view/BaseIWindow;->insetsChanged(Landroid/view/InsetsState;)V
 HSPLcom/android/internal/view/IInputConnectionWrapper$MyHandler;->handleMessage(Landroid/os/Message;)V
+HSPLcom/android/internal/view/IInputConnectionWrapper;->beginBatchEdit()V
 HSPLcom/android/internal/view/IInputConnectionWrapper;->closeConnection()V
+HSPLcom/android/internal/view/IInputConnectionWrapper;->commitText(Ljava/lang/CharSequence;I)V
 HSPLcom/android/internal/view/IInputConnectionWrapper;->dispatchMessage(Landroid/os/Message;)V
+HSPLcom/android/internal/view/IInputConnectionWrapper;->endBatchEdit()V
 HSPLcom/android/internal/view/IInputConnectionWrapper;->executeMessage(Landroid/os/Message;)V
 HSPLcom/android/internal/view/IInputConnectionWrapper;->finishComposingText()V
 HSPLcom/android/internal/view/IInputConnectionWrapper;->getInputConnection()Landroid/view/inputmethod/InputConnection;
@@ -23419,12 +24460,21 @@
 HSPLcom/android/internal/view/IInputConnectionWrapper;->isFinished()Z
 HSPLcom/android/internal/view/IInputConnectionWrapper;->obtainMessage(I)Landroid/os/Message;
 HSPLcom/android/internal/view/IInputConnectionWrapper;->obtainMessageIISC(IIIILcom/android/internal/view/IInputContextCallback;)Landroid/os/Message;
+HSPLcom/android/internal/view/IInputConnectionWrapper;->obtainMessageIO(IILjava/lang/Object;)Landroid/os/Message;
 HSPLcom/android/internal/view/IInputConnectionWrapper;->obtainMessageISC(IIILcom/android/internal/view/IInputContextCallback;)Landroid/os/Message;
 HSPLcom/android/internal/view/IInputContext$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->beginBatchEdit()V
+HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->commitText(Ljava/lang/CharSequence;I)V
+HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->deleteSurroundingText(II)V
+HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->endBatchEdit()V
+HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->finishComposingText()V
 HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->getSelectedText(IILcom/android/internal/view/IInputContextCallback;)V
 HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->getTextAfterCursor(IIILcom/android/internal/view/IInputContextCallback;)V
 HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->getTextBeforeCursor(IIILcom/android/internal/view/IInputContextCallback;)V
+HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->sendKeyEvent(Landroid/view/KeyEvent;)V
+HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->setComposingRegion(II)V
+HSPLcom/android/internal/view/IInputContext$Stub$Proxy;->setComposingText(Ljava/lang/CharSequence;I)V
 HSPLcom/android/internal/view/IInputContext$Stub;->asBinder()Landroid/os/IBinder;
 HSPLcom/android/internal/view/IInputContext$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputContext;
 HSPLcom/android/internal/view/IInputContext$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
@@ -23588,15 +24638,18 @@
 HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V
 HSPLcom/android/internal/widget/BackgroundFallback;->hasFallback()Z
 HSPLcom/android/internal/widget/BackgroundFallback;->setDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLcom/android/internal/widget/DialogTitle;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLcom/android/internal/widget/EditableInputConnection;->beginBatchEdit()Z
 HSPLcom/android/internal/widget/EditableInputConnection;->closeConnection()V
+HSPLcom/android/internal/widget/EditableInputConnection;->commitText(Ljava/lang/CharSequence;I)Z
 HSPLcom/android/internal/widget/EditableInputConnection;->endBatchEdit()Z
 HSPLcom/android/internal/widget/EditableInputConnection;->getEditable()Landroid/text/Editable;
 PLcom/android/internal/widget/ICheckCredentialProgressCallback$Stub$Proxy;->onCredentialVerified()V
 HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->getBoolean(Ljava/lang/String;ZI)Z
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->getLong(Ljava/lang/String;JI)J
 HSPLcom/android/internal/widget/ILockSettings$Stub;-><init>()V
 HSPLcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings;
-PLcom/android/internal/widget/ILockSettings$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
+HPLcom/android/internal/widget/ILockSettings$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HSPLcom/android/internal/widget/ILockSettings$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker$1;->onStrongAuthRequiredChanged(II)V
 HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker$H;->handleMessage(Landroid/os/Message;)V
@@ -23623,12 +24676,12 @@
 HSPLcom/android/internal/widget/LockPatternUtils;->isLockPasswordEnabled(II)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->isLockPatternEnabled(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->isOwnerInfoEnabled(I)Z
-PLcom/android/internal/widget/LockPatternUtils;->isPowerButtonInstantlyLocksEverChosen(I)Z
+HPLcom/android/internal/widget/LockPatternUtils;->isPowerButtonInstantlyLocksEverChosen(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->isSeparateProfileChallengeEnabled(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->isTrustUsuallyManaged(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->isVisiblePatternEnabled(I)Z
-PLcom/android/internal/widget/LockPatternUtils;->isVisiblePatternEverChosen(I)Z
+HPLcom/android/internal/widget/LockPatternUtils;->isVisiblePatternEverChosen(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->registerStrongAuthTracker(Lcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;)V
 HSPLcom/android/internal/widget/LockPatternUtils;->savedPasswordExists(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->savedPatternExists(I)Z
@@ -23637,13 +24690,16 @@
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->dismissPopupMenus()V
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->getContext()Landroid/content/Context;
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->getDisplayOptions()I
+HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->getMenu()Landroid/view/Menu;
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->getTitle()Ljava/lang/CharSequence;
+HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->getViewGroup()Landroid/view/ViewGroup;
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->hasIcon()Z
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->isSplit()Z
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->setDefaultNavigationContentDescription(I)V
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->setDisplayOptions(I)V
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->setIcon(I)V
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->setIcon(Landroid/graphics/drawable/Drawable;)V
+HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->setMenuCallbacks(Lcom/android/internal/view/menu/MenuPresenter$Callback;Lcom/android/internal/view/menu/MenuBuilder$Callback;)V
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->setMenuPrepared()V
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->setNavigationIcon(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/widget/ToolbarWidgetWrapper;->setWindowCallback(Landroid/view/Window$Callback;)V
@@ -23717,6 +24773,7 @@
 HSPLcom/android/okhttp/HttpUrl$Builder;->toString()Ljava/lang/String;
 HSPLcom/android/okhttp/HttpUrl;-><init>(Lcom/android/okhttp/HttpUrl$Builder;)V
 HSPLcom/android/okhttp/HttpUrl;->canonicalize(Ljava/lang/String;IILjava/lang/String;ZZZZ)Ljava/lang/String;
+HSPLcom/android/okhttp/HttpUrl;->decodeHexDigit(C)I
 HSPLcom/android/okhttp/HttpUrl;->encodedPassword()Ljava/lang/String;
 HSPLcom/android/okhttp/HttpUrl;->encodedPath()Ljava/lang/String;
 HSPLcom/android/okhttp/HttpUrl;->encodedPathSegments()Ljava/util/List;
@@ -23725,6 +24782,7 @@
 HSPLcom/android/okhttp/HttpUrl;->getChecked(Ljava/lang/String;)Lcom/android/okhttp/HttpUrl;
 HSPLcom/android/okhttp/HttpUrl;->namesAndValuesToQueryString(Ljava/lang/StringBuilder;Ljava/util/List;)V
 HSPLcom/android/okhttp/HttpUrl;->newBuilder()Lcom/android/okhttp/HttpUrl$Builder;
+HSPLcom/android/okhttp/HttpUrl;->percentDecode(Lcom/android/okhttp/okio/Buffer;Ljava/lang/String;IIZ)V
 HSPLcom/android/okhttp/HttpUrl;->percentDecode(Ljava/lang/String;IIZ)Ljava/lang/String;
 HSPLcom/android/okhttp/HttpUrl;->percentDecode(Ljava/util/List;Z)Ljava/util/List;
 HSPLcom/android/okhttp/HttpUrl;->queryStringToNamesAndValues(Ljava/lang/String;)Ljava/util/List;
@@ -23846,11 +24904,16 @@
 HSPLcom/android/okhttp/internal/http/HttpMethod;->permitsRequestBody(Ljava/lang/String;)Z
 HSPLcom/android/okhttp/internal/http/HttpMethod;->requiresRequestBody(Ljava/lang/String;)Z
 HSPLcom/android/okhttp/internal/http/OkHeaders$1;-><init>()V
+HSPLcom/android/okhttp/internal/http/OkHeaders$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLcom/android/okhttp/internal/http/OkHeaders$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
 HSPLcom/android/okhttp/internal/http/OkHeaders;->stringToLong(Ljava/lang/String;)J
+HSPLcom/android/okhttp/internal/http/OkHeaders;->toMultimap(Lcom/android/okhttp/Headers;Ljava/lang/String;)Ljava/util/Map;
 HSPLcom/android/okhttp/internal/http/RealResponseBody;->source()Lcom/android/okhttp/okio/BufferedSource;
 HSPLcom/android/okhttp/internal/http/RequestLine;->get(Lcom/android/okhttp/Request;Ljava/net/Proxy$Type;)Ljava/lang/String;
 HSPLcom/android/okhttp/internal/http/RequestLine;->requestPath(Lcom/android/okhttp/HttpUrl;)Ljava/lang/String;
 HSPLcom/android/okhttp/internal/http/RetryableSink;->close()V
+HSPLcom/android/okhttp/internal/http/RetryableSink;->flush()V
+HSPLcom/android/okhttp/internal/http/RetryableSink;->write(Lcom/android/okhttp/okio/Buffer;J)V
 HSPLcom/android/okhttp/internal/http/RouteSelector;-><init>(Lcom/android/okhttp/Address;Lcom/android/okhttp/internal/RouteDatabase;)V
 HSPLcom/android/okhttp/internal/http/RouteSelector;->next()Lcom/android/okhttp/Route;
 HSPLcom/android/okhttp/internal/http/RouteSelector;->nextInetSocketAddress()Ljava/net/InetSocketAddress;
@@ -23866,6 +24929,7 @@
 HSPLcom/android/okhttp/internal/http/StreamAllocation;->newStream(IIIZZ)Lcom/android/okhttp/internal/http/HttpStream;
 HSPLcom/android/okhttp/internal/http/StreamAllocation;->release(Lcom/android/okhttp/internal/io/RealConnection;)V
 HSPLcom/android/okhttp/internal/http/StreamAllocation;->streamFinished(Lcom/android/okhttp/internal/http/HttpStream;)V
+HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->addRequestProperty(Ljava/lang/String;Ljava/lang/String;)V
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->connect()V
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->disconnect()V
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->execute(Z)Z
@@ -23875,6 +24939,7 @@
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->getOutputStream()Ljava/io/OutputStream;
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->getResponse()Lcom/android/okhttp/internal/http/HttpEngine;
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->getResponseCode()I
+HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->getResponseMessage()Ljava/lang/String;
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->initHttpEngine()V
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->newHttpEngine(Ljava/lang/String;Lcom/android/okhttp/internal/http/StreamAllocation;Lcom/android/okhttp/internal/http/RetryableSink;Lcom/android/okhttp/Response;)Lcom/android/okhttp/internal/http/HttpEngine;
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->responseSourceHeader(Lcom/android/okhttp/Response;)Ljava/lang/String;
@@ -23883,12 +24948,14 @@
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->setReadTimeout(I)V
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->setRequestMethod(Ljava/lang/String;)V
 HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->setRequestProperty(Ljava/lang/String;Ljava/lang/String;)V
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->addRequestProperty(Ljava/lang/String;Ljava/lang/String;)V
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->connect()V
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->disconnect()V
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getHeaderField(Ljava/lang/String;)Ljava/lang/String;
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getInputStream()Ljava/io/InputStream;
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getOutputStream()Ljava/io/OutputStream;
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getResponseCode()I
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getResponseMessage()Ljava/lang/String;
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->setConnectTimeout(I)V
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->setDoOutput(Z)V
 HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->setInstanceFollowRedirects(Z)V
@@ -23927,12 +24994,14 @@
 HSPLcom/android/okhttp/okio/Buffer;->readInt()I
 HSPLcom/android/okhttp/okio/Buffer;->readShort()S
 HSPLcom/android/okhttp/okio/Buffer;->readString(JLjava/nio/charset/Charset;)Ljava/lang/String;
+HSPLcom/android/okhttp/okio/Buffer;->readUtf8()Ljava/lang/String;
 HSPLcom/android/okhttp/okio/Buffer;->readUtf8Line(J)Ljava/lang/String;
 HSPLcom/android/okhttp/okio/Buffer;->skip(J)V
 HSPLcom/android/okhttp/okio/Buffer;->writableSegment(I)Lcom/android/okhttp/okio/Segment;
 HSPLcom/android/okhttp/okio/Buffer;->write(Lcom/android/okhttp/okio/Buffer;J)V
 HSPLcom/android/okhttp/okio/Buffer;->write([BII)Lcom/android/okhttp/okio/Buffer;
 HSPLcom/android/okhttp/okio/Buffer;->writeUtf8(Ljava/lang/String;II)Lcom/android/okhttp/okio/Buffer;
+HSPLcom/android/okhttp/okio/Buffer;->writeUtf8CodePoint(I)Lcom/android/okhttp/okio/Buffer;
 HSPLcom/android/okhttp/okio/ByteString;->of([B)Lcom/android/okhttp/okio/ByteString;
 HSPLcom/android/okhttp/okio/GzipSource;-><init>(Lcom/android/okhttp/okio/Source;)V
 HSPLcom/android/okhttp/okio/GzipSource;->checkEqual(Ljava/lang/String;II)V
@@ -23960,6 +25029,7 @@
 HSPLcom/android/okhttp/okio/RealBufferedSink;->timeout()Lcom/android/okhttp/okio/Timeout;
 HSPLcom/android/okhttp/okio/RealBufferedSink;->write(Lcom/android/okhttp/okio/Buffer;J)V
 HSPLcom/android/okhttp/okio/RealBufferedSink;->writeUtf8(Ljava/lang/String;)Lcom/android/okhttp/okio/BufferedSink;
+HSPLcom/android/okhttp/okio/RealBufferedSource$1;->available()I
 HSPLcom/android/okhttp/okio/RealBufferedSource$1;->close()V
 HSPLcom/android/okhttp/okio/RealBufferedSource$1;->read([BII)I
 HSPLcom/android/okhttp/okio/RealBufferedSource;->buffer()Lcom/android/okhttp/okio/Buffer;
@@ -24077,6 +25147,11 @@
 HSPLcom/android/org/bouncycastle/crypto/CryptoServicesRegistrar;->toDH(Lcom/android/org/bouncycastle/crypto/params/DSAParameters;)Lcom/android/org/bouncycastle/crypto/params/DHParameters;
 HSPLcom/android/org/bouncycastle/crypto/digests/AndroidDigestFactoryBouncyCastle;-><init>()V
 HSPLcom/android/org/bouncycastle/crypto/digests/AndroidDigestFactoryOpenSSL;-><init>()V
+HSPLcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest;->doFinal([BI)I
+HSPLcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest;->getDigestSize()I
+HSPLcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest;->reset()V
+HSPLcom/android/org/bouncycastle/crypto/digests/OpenSSLDigest;->update([BII)V
 HSPLcom/android/org/bouncycastle/crypto/params/DHParameters;-><init>(Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;IILjava/math/BigInteger;Lcom/android/org/bouncycastle/crypto/params/DHValidationParameters;)V
 HSPLcom/android/org/bouncycastle/crypto/params/DSAParameters;-><init>(Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Lcom/android/org/bouncycastle/crypto/params/DSAValidationParameters;)V
 HSPLcom/android/org/bouncycastle/crypto/params/DSAParameters;->getG()Ljava/math/BigInteger;
@@ -24180,7 +25255,7 @@
 HSPLcom/android/org/bouncycastle/jce/provider/BouncyCastleProvider;->setup()V
 HSPLcom/android/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration;-><init>()V
 HSPLcom/android/org/bouncycastle/jce/provider/CertStoreCollectionSpi;-><init>(Ljava/security/cert/CertStoreParameters;)V
-PLcom/android/org/bouncycastle/jce/provider/CertStoreCollectionSpi;->engineGetCertificates(Ljava/security/cert/CertSelector;)Ljava/util/Collection;
+HPLcom/android/org/bouncycastle/jce/provider/CertStoreCollectionSpi;->engineGetCertificates(Ljava/security/cert/CertSelector;)Ljava/util/Collection;
 HSPLcom/android/org/bouncycastle/util/Integers;->valueOf(I)Ljava/lang/Integer;
 HSPLcom/android/org/bouncycastle/util/Properties$1;->run()Ljava/lang/Object;
 HSPLcom/android/org/bouncycastle/util/Properties;->isOverrideSet(Ljava/lang/String;)Z
@@ -24243,7 +25318,7 @@
 HSPLcom/android/org/kxml2/io/KXmlSerializer;->setOutput(Ljava/io/Writer;)V
 HSPLcom/android/org/kxml2/io/KXmlSerializer;->startDocument(Ljava/lang/String;Ljava/lang/Boolean;)V
 HSPLcom/android/org/kxml2/io/KXmlSerializer;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
-PLcom/android/org/kxml2/io/KXmlSerializer;->text(Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
+HPLcom/android/org/kxml2/io/KXmlSerializer;->text(Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
 HSPLcom/android/org/kxml2/io/KXmlSerializer;->writeEscaped(Ljava/lang/String;I)V
 HSPLcom/android/phone/ecc/nano/CodedInputByteBufferNano;->checkLastTagWas(I)V
 HSPLcom/android/phone/ecc/nano/CodedInputByteBufferNano;->readMessage(Lcom/android/phone/ecc/nano/MessageNano;)V
@@ -24261,7 +25336,7 @@
 HSPLcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;->emptyArray()[Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;
 HSPLcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;->mergeFrom(Lcom/android/phone/ecc/nano/CodedInputByteBufferNano;)Lcom/android/phone/ecc/nano/MessageNano;
 HSPLcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;->mergeFrom(Lcom/android/phone/ecc/nano/CodedInputByteBufferNano;)Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;
-PLcom/android/server/AppWidgetBackupBridge;->getWidgetState(Ljava/lang/String;I)[B
+HPLcom/android/server/AppWidgetBackupBridge;->getWidgetState(Ljava/lang/String;I)[B
 HSPLcom/android/server/AppWidgetBackupBridge;->register(Lcom/android/server/WidgetBackupProvider;)V
 PLcom/android/server/BootReceiver$1;->run()V
 PLcom/android/server/BootReceiver;-><init>()V
@@ -24373,6 +25448,7 @@
 PLcom/android/server/connectivity/metrics/nano/IpConnectivityLogClass$WakeupStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/net/BaseNetdEventCallback;-><init>()V
 HSPLcom/android/server/net/BaseNetdEventCallback;->onConnectEvent(Ljava/lang/String;IJI)V
+HPLcom/android/server/net/BaseNetdEventCallback;->onNat64PrefixEvent(IZLjava/lang/String;I)V
 HSPLcom/android/server/net/BaseNetdEventCallback;->onPrivateDnsValidationEvent(ILjava/lang/String;Ljava/lang/String;Z)V
 HSPLcom/android/server/net/BaseNetworkObserver;-><init>()V
 HSPLcom/android/server/net/BaseNetworkObserver;->addressRemoved(Ljava/lang/String;Landroid/net/LinkAddress;)V
@@ -24388,22 +25464,25 @@
 HSPLcom/android/server/sip/SipService;->start(Landroid/content/Context;)V
 HSPLcom/android/server/sip/SipWakeupTimer;-><init>(Landroid/content/Context;Ljava/util/concurrent/Executor;)V
 HSPLcom/android/server/wifi/BaseWifiService;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$AlertReasonCount;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$AlertReasonCount;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$AlertReasonCount;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$AlertReasonCount;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$AlertReasonCount;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$AlertReasonCount;
-PLcom/android/server/wifi/nano/WifiMetricsProto$AlertReasonCount;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$AlertReasonCount;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectToNetworkNotificationAndActionCount;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectToNetworkNotificationAndActionCount;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectToNetworkNotificationAndActionCount;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$ConnectToNetworkNotificationAndActionCount;
-PLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;
-PLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectToNetworkNotificationAndActionCount;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;
-PLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/server/wifi/nano/WifiMetricsProto$DeviceMobilityStatePnoScanStats;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ConnectionEvent;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$DeviceMobilityStatePnoScanStats;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$DeviceMobilityStatePnoScanStats;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$DeviceMobilityStatePnoScanStats;
-PLcom/android/server/wifi/nano/WifiMetricsProto$DeviceMobilityStatePnoScanStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$DeviceMobilityStatePnoScanStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$ExperimentValues;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$ExperimentValues;->computeSerializedSize()I
-PLcom/android/server/wifi/nano/WifiMetricsProto$ExperimentValues;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ExperimentValues;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$ExperimentValues;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$GroupEvent;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$GroupEvent;
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$HistogramBucketInt32;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$HistogramBucketInt32;
 PLcom/android/server/wifi/nano/WifiMetricsProto$Int32Count;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$Int32Count;
@@ -24413,21 +25492,21 @@
 PLcom/android/server/wifi/nano/WifiMetricsProto$LinkProbeStats;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$LinkProbeStats;
 PLcom/android/server/wifi/nano/WifiMetricsProto$LinkProbeStats;->computeSerializedSize()I
 PLcom/android/server/wifi/nano/WifiMetricsProto$LinkProbeStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/server/wifi/nano/WifiMetricsProto$LinkSpeedCount;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$LinkSpeedCount;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$LinkSpeedCount;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$LinkSpeedCount;
-PLcom/android/server/wifi/nano/WifiMetricsProto$LinkSpeedCount;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/server/wifi/nano/WifiMetricsProto$NetworkSelectionExperimentDecisions;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$NetworkSelectionExperimentDecisions;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$LinkSpeedCount;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$NetworkSelectionExperimentDecisions;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$NetworkSelectionExperimentDecisions;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$NetworkSelectionExperimentDecisions;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$NetworkSelectionExperimentDecisions;
-PLcom/android/server/wifi/nano/WifiMetricsProto$NetworkSelectionExperimentDecisions;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/server/wifi/nano/WifiMetricsProto$NumConnectableNetworksBucket;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$NetworkSelectionExperimentDecisions;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$NumConnectableNetworksBucket;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$NumConnectableNetworksBucket;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$NumConnectableNetworksBucket;
-PLcom/android/server/wifi/nano/WifiMetricsProto$NumConnectableNetworksBucket;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$NumConnectableNetworksBucket;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$P2pConnectionEvent;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$P2pConnectionEvent;
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$PasspointProfileTypeCount;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$PasspointProfileTypeCount;
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$PnoScanMetrics;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$PnoScanMetrics;->computeSerializedSize()I
-PLcom/android/server/wifi/nano/WifiMetricsProto$PnoScanMetrics;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$PnoScanMetrics;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$PnoScanMetrics;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 PLcom/android/server/wifi/nano/WifiMetricsProto$RouterFingerPrint;->computeSerializedSize()I
 PLcom/android/server/wifi/nano/WifiMetricsProto$RouterFingerPrint;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HPLcom/android/server/wifi/nano/WifiMetricsProto$RssiPollCount;-><init>()V
@@ -24460,39 +25539,39 @@
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog$DppConfiguratorSuccessStatusHistogramBucket;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog$DppConfiguratorSuccessStatusHistogramBucket;
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog$DppFailureStatusHistogramBucket;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog$DppFailureStatusHistogramBucket;
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog;->computeSerializedSize()I
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiDppLog;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiIsUnusableEvent;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLinkLayerUsageStats;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiLinkLayerUsageStats;->computeSerializedSize()I
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiLinkLayerUsageStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$ScanReturnEntry;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$ScanReturnEntry;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLinkLayerUsageStats;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLinkLayerUsageStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$ScanReturnEntry;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$ScanReturnEntry;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$ScanReturnEntry;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$ScanReturnEntry;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$ScanReturnEntry;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$WifiSystemStateEntry;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$WifiSystemStateEntry;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$ScanReturnEntry;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$WifiSystemStateEntry;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$WifiSystemStateEntry;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$WifiSystemStateEntry;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$WifiSystemStateEntry;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$WifiSystemStateEntry;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog$WifiSystemStateEntry;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog;-><init>()V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$WifiLog;
 HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog;->computeSerializedSize()I
 HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiLog;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkRequestApiLog;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkRequestApiLog;->computeSerializedSize()I
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkRequestApiLog;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkRequestApiLog;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkRequestApiLog;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkSuggestionApiLog;-><init>()V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkSuggestionApiLog;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkSuggestionApiLog;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkSuggestionApiLog;->computeSerializedSize()I
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkSuggestionApiLog;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkSuggestionApiLog;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiNetworkSuggestionApiLog;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiP2pStats;-><init>()V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiP2pStats;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$WifiP2pStats;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiP2pStats;->computeSerializedSize()I
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiP2pStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiP2pStats;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiP2pStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiPowerStats;-><init>()V
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiPowerStats;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$WifiPowerStats;
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiPowerStats;->computeSerializedSize()I
@@ -24509,15 +25588,15 @@
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiRttLog;-><init>()V
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiRttLog;->computeSerializedSize()I
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiRttLog;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiScoreCount;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiScoreCount;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiScoreCount;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiScoreCount;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiScoreCount;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$WifiScoreCount;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiScoreCount;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiScoreCount;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityScoreCount;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityScoreCount;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStats;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStats;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStats;-><init>()V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStats;->computeSerializedSize()I
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStats;->emptyArray()[Lcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStats;
-PLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStatsEntry;-><init>()V
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStatsEntry;->clear()Lcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStatsEntry;
 HPLcom/android/server/wifi/nano/WifiMetricsProto$WifiUsabilityStatsEntry;->computeSerializedSize()I
@@ -24528,23 +25607,27 @@
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiWakeStats;->computeSerializedSize()I
 PLcom/android/server/wifi/nano/WifiMetricsProto$WifiWakeStats;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/android/server/wifi/nano/WifiMetricsProto$WpsMetrics;-><init>()V
-PLcom/android/server/wifi/nano/WifiMetricsProto$WpsMetrics;->computeSerializedSize()I
-PLcom/android/server/wifi/nano/WifiMetricsProto$WpsMetrics;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WpsMetrics;->computeSerializedSize()I
+HPLcom/android/server/wifi/nano/WifiMetricsProto$WpsMetrics;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HPLcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;->computeSerializedSize()I
 PLcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;->mergeFrom(Lcom/android/framework/protobuf/nano/CodedInputByteBufferNano;)Lcom/android/framework/protobuf/nano/MessageNano;
 PLcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;->mergeFrom(Lcom/android/framework/protobuf/nano/CodedInputByteBufferNano;)Lcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;
 PLcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;->parseFrom([B)Lcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;
 HPLcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;->writeTo(Lcom/android/framework/protobuf/nano/CodedOutputByteBufferNano;)V
 HSPLcom/google/android/collect/Lists;->newArrayList()Ljava/util/ArrayList;
+HSPLcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList;
 HSPLcom/google/android/collect/Maps;->newArrayMap()Landroid/util/ArrayMap;
 HSPLcom/google/android/collect/Maps;->newHashMap()Ljava/util/HashMap;
 HSPLcom/google/android/collect/Sets;->newArraySet()Landroid/util/ArraySet;
 HSPLcom/google/android/collect/Sets;->newArraySet([Ljava/lang/Object;)Landroid/util/ArraySet;
 HSPLcom/google/android/collect/Sets;->newHashSet()Ljava/util/HashSet;
 HSPLcom/google/android/collect/Sets;->newHashSet([Ljava/lang/Object;)Ljava/util/HashSet;
+HSPLcom/google/android/gles_jni/EGLConfigImpl;-><init>(J)V
 HSPLcom/google/android/gles_jni/EGLContextImpl;-><init>(J)V
 HSPLcom/google/android/gles_jni/EGLDisplayImpl;-><init>(J)V
 HSPLcom/google/android/gles_jni/EGLImpl;-><init>()V
+HSPLcom/google/android/gles_jni/EGLImpl;->eglCreateContext(Ljavax/microedition/khronos/egl/EGLDisplay;Ljavax/microedition/khronos/egl/EGLConfig;Ljavax/microedition/khronos/egl/EGLContext;[I)Ljavax/microedition/khronos/egl/EGLContext;
+HSPLcom/google/android/gles_jni/EGLImpl;->eglGetDisplay(Ljava/lang/Object;)Ljavax/microedition/khronos/egl/EGLDisplay;
 HSPLcom/google/android/gles_jni/EGLSurfaceImpl;-><init>(J)V
 HPLcom/google/android/rappor/Encoder;-><init>(Ljava/util/Random;Ljava/security/MessageDigest;Ljava/security/MessageDigest;[BLjava/lang/String;IDDDII)V
 HPLcom/google/android/rappor/Encoder;->checkArgument(ZLjava/lang/Object;)V
@@ -24592,6 +25675,7 @@
 HSPLdalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String;
 HSPLdalvik/system/BaseDexClassLoader;->getPackage(Ljava/lang/String;)Ljava/lang/Package;
 HSPLdalvik/system/BaseDexClassLoader;->reportClassLoaderChain()V
+HSPLdalvik/system/BaseDexClassLoader;->toString()Ljava/lang/String;
 HSPLdalvik/system/BlockGuard$1;->onExplicitGc()V
 HSPLdalvik/system/BlockGuard$1;->onNetwork()V
 HSPLdalvik/system/BlockGuard$1;->onReadFromDisk()V
@@ -24615,6 +25699,7 @@
 HSPLdalvik/system/DalvikLogging;->loggerNameToTag(Ljava/lang/String;)Ljava/lang/String;
 HSPLdalvik/system/DelegateLastClassLoader;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Z)V
 HSPLdalvik/system/DelegateLastClassLoader;->loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
+HSPLdalvik/system/DexClassLoader;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V
 HSPLdalvik/system/DexFile;->defineClass(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/Object;Ldalvik/system/DexFile;Ljava/util/List;)Ljava/lang/Class;
 HSPLdalvik/system/DexFile;->finalize()V
 HSPLdalvik/system/DexFile;->getDexFileOptimizationInfo(Ljava/lang/String;Ljava/lang/String;)Ldalvik/system/DexFile$OptimizationInfo;
@@ -24701,6 +25786,7 @@
 HSPLjava/io/BufferedWriter;->write(I)V
 HSPLjava/io/BufferedWriter;->write(Ljava/lang/String;II)V
 HSPLjava/io/ByteArrayInputStream;-><init>([B)V
+HSPLjava/io/ByteArrayInputStream;-><init>([BII)V
 HSPLjava/io/ByteArrayInputStream;->available()I
 HSPLjava/io/ByteArrayInputStream;->close()V
 HSPLjava/io/ByteArrayInputStream;->mark(I)V
@@ -24845,6 +25931,7 @@
 HSPLjava/io/FilterInputStream;->read([BII)I
 HSPLjava/io/FilterInputStream;->reset()V
 HSPLjava/io/FilterInputStream;->skip(J)J
+HSPLjava/io/FilterOutputStream;-><init>(Ljava/io/OutputStream;)V
 HSPLjava/io/FilterOutputStream;->close()V
 HSPLjava/io/FilterOutputStream;->write([B)V
 HSPLjava/io/IOException;-><init>(Ljava/lang/String;)V
@@ -24956,6 +26043,7 @@
 HSPLjava/io/ObjectOutputStream;->writeByte(I)V
 HSPLjava/io/ObjectOutputStream;->writeClassDesc(Ljava/io/ObjectStreamClass;Z)V
 HSPLjava/io/ObjectOutputStream;->writeClassDescriptor(Ljava/io/ObjectStreamClass;)V
+HSPLjava/io/ObjectOutputStream;->writeEnum(Ljava/lang/Enum;Ljava/io/ObjectStreamClass;Z)V
 HSPLjava/io/ObjectOutputStream;->writeInt(I)V
 HSPLjava/io/ObjectOutputStream;->writeLong(J)V
 HSPLjava/io/ObjectOutputStream;->writeNonProxyDesc(Ljava/io/ObjectStreamClass;Z)V
@@ -24969,6 +26057,10 @@
 HSPLjava/io/ObjectOutputStream;->writeTypeString(Ljava/lang/String;)V
 HSPLjava/io/ObjectOutputStream;->writeUTF(Ljava/lang/String;)V
 HSPLjava/io/ObjectStreamClass$2;->run()Ljava/lang/Void;
+HSPLjava/io/ObjectStreamClass$3;->compare(Ljava/io/ObjectStreamClass$MemberSignature;Ljava/io/ObjectStreamClass$MemberSignature;)I
+HSPLjava/io/ObjectStreamClass$3;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLjava/io/ObjectStreamClass$EntryFuture;->get()Ljava/lang/Object;
+HSPLjava/io/ObjectStreamClass$EntryFuture;->getOwner()Ljava/lang/Thread;
 HSPLjava/io/ObjectStreamClass$EntryFuture;->set(Ljava/lang/Object;)Z
 HSPLjava/io/ObjectStreamClass$FieldReflector;-><init>([Ljava/io/ObjectStreamField;)V
 HSPLjava/io/ObjectStreamClass$FieldReflector;->getFields()[Ljava/io/ObjectStreamField;
@@ -25069,7 +26161,8 @@
 HSPLjava/io/PrintWriter;->flush()V
 HSPLjava/io/PrintWriter;->format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;
 HSPLjava/io/PrintWriter;->newLine()V
-PLjava/io/PrintWriter;->print(D)V
+HPLjava/io/PrintWriter;->print(D)V
+HPLjava/io/PrintWriter;->print(F)V
 HSPLjava/io/PrintWriter;->print(I)V
 HSPLjava/io/PrintWriter;->print(J)V
 HSPLjava/io/PrintWriter;->print(Ljava/lang/Object;)V
@@ -25077,6 +26170,7 @@
 HSPLjava/io/PrintWriter;->print(Z)V
 HSPLjava/io/PrintWriter;->printf(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintWriter;
 HSPLjava/io/PrintWriter;->println()V
+HPLjava/io/PrintWriter;->println(F)V
 HSPLjava/io/PrintWriter;->println(I)V
 HSPLjava/io/PrintWriter;->println(J)V
 HSPLjava/io/PrintWriter;->println(Ljava/lang/Object;)V
@@ -25204,6 +26298,7 @@
 HSPLjava/lang/BootClassLoader;->loadClass(Ljava/lang/String;Z)Ljava/lang/Class;
 HSPLjava/lang/Byte;-><init>(B)V
 HSPLjava/lang/Byte;->byteValue()B
+HSPLjava/lang/Byte;->hashCode()I
 HSPLjava/lang/Byte;->toString()Ljava/lang/String;
 HSPLjava/lang/Byte;->toUnsignedInt(B)I
 HSPLjava/lang/Byte;->valueOf(B)Ljava/lang/Byte;
@@ -25217,6 +26312,7 @@
 HSPLjava/lang/Character;->codePointAt(Ljava/lang/CharSequence;I)I
 HSPLjava/lang/Character;->codePointBefore(Ljava/lang/CharSequence;I)I
 HSPLjava/lang/Character;->codePointCount(Ljava/lang/CharSequence;II)I
+HSPLjava/lang/Character;->codePointCountImpl([CII)I
 HSPLjava/lang/Character;->compareTo(Ljava/lang/Object;)I
 HSPLjava/lang/Character;->digit(CI)I
 HSPLjava/lang/Character;->digit(II)I
@@ -25228,6 +26324,7 @@
 HSPLjava/lang/Character;->getNumericValue(I)I
 HSPLjava/lang/Character;->getType(I)I
 HSPLjava/lang/Character;->hashCode()I
+HSPLjava/lang/Character;->isAlphabetic(I)Z
 HSPLjava/lang/Character;->isDigit(C)Z
 HSPLjava/lang/Character;->isDigit(I)Z
 HSPLjava/lang/Character;->isHighSurrogate(C)Z
@@ -25236,9 +26333,13 @@
 HSPLjava/lang/Character;->isLetterOrDigit(C)Z
 HSPLjava/lang/Character;->isLetterOrDigit(I)Z
 HSPLjava/lang/Character;->isLowSurrogate(C)Z
+HSPLjava/lang/Character;->isSupplementaryCodePoint(I)Z
+HSPLjava/lang/Character;->isUpperCase(C)Z
 HSPLjava/lang/Character;->isUpperCase(I)Z
+HSPLjava/lang/Character;->isValidCodePoint(I)Z
 HSPLjava/lang/Character;->isWhitespace(C)Z
 HSPLjava/lang/Character;->isWhitespace(I)Z
+HSPLjava/lang/Character;->offsetByCodePointsImpl([CIIII)I
 HSPLjava/lang/Character;->toChars(I)[C
 HSPLjava/lang/Character;->toChars(I[CI)I
 HSPLjava/lang/Character;->toCodePoint(CC)I
@@ -25263,6 +26364,7 @@
 HSPLjava/lang/Class;->getDeclaredConstructor([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;
 HSPLjava/lang/Class;->getDeclaredMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
 HSPLjava/lang/Class;->getDeclaredMethods()[Ljava/lang/reflect/Method;
+HSPLjava/lang/Class;->getEnumConstants()[Ljava/lang/Object;
 HSPLjava/lang/Class;->getField(Ljava/lang/String;)Ljava/lang/reflect/Field;
 HSPLjava/lang/Class;->getFields()[Ljava/lang/reflect/Field;
 HSPLjava/lang/Class;->getGenericSuperclass()Ljava/lang/reflect/Type;
@@ -25286,7 +26388,10 @@
 HSPLjava/lang/Class;->isAssignableFrom(Ljava/lang/Class;)Z
 HSPLjava/lang/Class;->isEnum()Z
 HSPLjava/lang/Class;->isInstance(Ljava/lang/Object;)Z
+HSPLjava/lang/Class;->isInterface()Z
+HSPLjava/lang/Class;->isLocalClass()Z
 HSPLjava/lang/Class;->isMemberClass()Z
+HSPLjava/lang/Class;->isPrimitive()Z
 HSPLjava/lang/Class;->resolveName(Ljava/lang/String;)Ljava/lang/String;
 HSPLjava/lang/Class;->toString()Ljava/lang/String;
 HSPLjava/lang/ClassCastException;-><init>(Ljava/lang/String;)V
@@ -25327,9 +26432,11 @@
 HSPLjava/lang/Daemons$ReferenceQueueDaemon;->runInternal()V
 HSPLjava/lang/Daemons;->start()V
 HSPLjava/lang/Double;->compare(DD)I
+HSPLjava/lang/Double;->compareTo(Ljava/lang/Object;)I
 HSPLjava/lang/Double;->doubleToLongBits(D)J
 HSPLjava/lang/Double;->doubleValue()D
 HSPLjava/lang/Double;->equals(Ljava/lang/Object;)Z
+HSPLjava/lang/Double;->hashCode()I
 HSPLjava/lang/Double;->isInfinite(D)Z
 HSPLjava/lang/Double;->isNaN(D)Z
 HSPLjava/lang/Double;->longValue()J
@@ -25356,8 +26463,10 @@
 HSPLjava/lang/Exception;-><init>(Ljava/lang/String;Ljava/lang/Throwable;)V
 HSPLjava/lang/Exception;-><init>(Ljava/lang/String;Ljava/lang/Throwable;ZZ)V
 HSPLjava/lang/Exception;-><init>(Ljava/lang/Throwable;)V
+HSPLjava/lang/Float;-><init>(F)V
 HSPLjava/lang/Float;-><init>(Ljava/lang/String;)V
 HSPLjava/lang/Float;->compare(FF)I
+HSPLjava/lang/Float;->compareTo(Ljava/lang/Object;)I
 HSPLjava/lang/Float;->doubleValue()D
 HSPLjava/lang/Float;->equals(Ljava/lang/Object;)Z
 HSPLjava/lang/Float;->floatToIntBits(F)I
@@ -25376,7 +26485,7 @@
 HSPLjava/lang/IllegalStateException;-><init>()V
 HSPLjava/lang/IllegalStateException;-><init>(Ljava/lang/String;)V
 HSPLjava/lang/IllegalStateException;-><init>(Ljava/lang/String;Ljava/lang/Throwable;)V
-PLjava/lang/IllegalStateException;-><init>(Ljava/lang/Throwable;)V
+HPLjava/lang/IllegalStateException;-><init>(Ljava/lang/Throwable;)V
 HSPLjava/lang/InheritableThreadLocal;-><init>()V
 HSPLjava/lang/InheritableThreadLocal;->createMap(Ljava/lang/Thread;Ljava/lang/Object;)V
 HSPLjava/lang/InheritableThreadLocal;->getMap(Ljava/lang/Thread;)Ljava/lang/ThreadLocal$ThreadLocalMap;
@@ -25533,9 +26642,10 @@
 HSPLjava/lang/StackTraceElement;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
 HSPLjava/lang/StackTraceElement;->equals(Ljava/lang/Object;)Z
 HSPLjava/lang/StackTraceElement;->getClassName()Ljava/lang/String;
+HSPLjava/lang/StackTraceElement;->getLineNumber()I
 HSPLjava/lang/StackTraceElement;->getMethodName()Ljava/lang/String;
 HSPLjava/lang/StackTraceElement;->toString()Ljava/lang/String;
-PLjava/lang/StrictMath;->toIntExact(J)I
+HPLjava/lang/StrictMath;->toIntExact(J)I
 HSPLjava/lang/String$CaseInsensitiveComparator;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLjava/lang/String$CaseInsensitiveComparator;->compare(Ljava/lang/String;Ljava/lang/String;)I
 HSPLjava/lang/String;->codePointAt(I)I
@@ -25606,6 +26716,7 @@
 HSPLjava/lang/StringBuffer;->append(Ljava/lang/CharSequence;II)Ljava/lang/AbstractStringBuilder;
 HSPLjava/lang/StringBuffer;->append(Ljava/lang/CharSequence;II)Ljava/lang/StringBuffer;
 HSPLjava/lang/StringBuffer;->append(Ljava/lang/Object;)Ljava/lang/StringBuffer;
+HSPLjava/lang/StringBuffer;->append(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder;
 HSPLjava/lang/StringBuffer;->append(Ljava/lang/String;)Ljava/lang/StringBuffer;
 HSPLjava/lang/StringBuffer;->append(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;
 HSPLjava/lang/StringBuffer;->append(Z)Ljava/lang/StringBuffer;
@@ -25638,6 +26749,7 @@
 HSPLjava/lang/StringBuilder;->append([CII)Ljava/lang/StringBuilder;
 HSPLjava/lang/StringBuilder;->appendCodePoint(I)Ljava/lang/StringBuilder;
 HSPLjava/lang/StringBuilder;->charAt(I)C
+HSPLjava/lang/StringBuilder;->codePointCount(II)I
 HSPLjava/lang/StringBuilder;->delete(II)Ljava/lang/StringBuilder;
 HSPLjava/lang/StringBuilder;->deleteCharAt(I)Ljava/lang/StringBuilder;
 HSPLjava/lang/StringBuilder;->ensureCapacity(I)V
@@ -25648,6 +26760,7 @@
 HSPLjava/lang/StringBuilder;->insert(ILjava/lang/String;)Ljava/lang/StringBuilder;
 HSPLjava/lang/StringBuilder;->lastIndexOf(Ljava/lang/String;I)I
 HSPLjava/lang/StringBuilder;->length()I
+HSPLjava/lang/StringBuilder;->offsetByCodePoints(II)I
 HSPLjava/lang/StringBuilder;->replace(IILjava/lang/String;)Ljava/lang/StringBuilder;
 HSPLjava/lang/StringBuilder;->setCharAt(IC)V
 HSPLjava/lang/StringBuilder;->setLength(I)V
@@ -25726,6 +26839,7 @@
 HSPLjava/lang/Thread;->sleep(J)V
 HSPLjava/lang/Thread;->sleep(JI)V
 HSPLjava/lang/Thread;->start()V
+HSPLjava/lang/Thread;->toString()Ljava/lang/String;
 HSPLjava/lang/ThreadGroup;->activeCount()I
 HSPLjava/lang/ThreadGroup;->add(Ljava/lang/Thread;)V
 HSPLjava/lang/ThreadGroup;->addUnstarted()V
@@ -25798,6 +26912,7 @@
 HSPLjava/lang/invoke/MethodType$ConcurrentWeakInternSet;->add(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/lang/invoke/MethodType$ConcurrentWeakInternSet;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/lang/invoke/MethodType;->equals(Ljava/lang/Object;)Z
+HSPLjava/lang/invoke/MethodType;->genericMethodType(IZ)Ljava/lang/invoke/MethodType;
 HSPLjava/lang/invoke/MethodType;->hashCode()I
 HSPLjava/lang/invoke/MethodType;->insertParameterTypes(I[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
 HSPLjava/lang/invoke/MethodType;->makeImpl(Ljava/lang/Class;[Ljava/lang/Class;Z)Ljava/lang/invoke/MethodType;
@@ -25846,6 +26961,9 @@
 HSPLjava/lang/reflect/Constructor;->getParameterTypes()[Ljava/lang/Class;
 HSPLjava/lang/reflect/Constructor;->newInstance([Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/lang/reflect/Executable;->isAnnotationPresent(Ljava/lang/Class;)Z
+HSPLjava/lang/reflect/Executable;->printModifiersIfNonzero(Ljava/lang/StringBuilder;IZ)V
+HSPLjava/lang/reflect/Executable;->separateWithCommas([Ljava/lang/Class;Ljava/lang/StringBuilder;)V
+HSPLjava/lang/reflect/Executable;->sharedToString(IZ[Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/String;
 HSPLjava/lang/reflect/Field;->getAnnotation(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
 HSPLjava/lang/reflect/Field;->getModifiers()I
 HSPLjava/lang/reflect/Field;->getName()Ljava/lang/String;
@@ -25860,9 +26978,12 @@
 HSPLjava/lang/reflect/Method;->getName()Ljava/lang/String;
 HSPLjava/lang/reflect/Method;->getParameterTypes()[Ljava/lang/Class;
 HSPLjava/lang/reflect/Method;->getReturnType()Ljava/lang/Class;
+HSPLjava/lang/reflect/Method;->specificToStringHeader(Ljava/lang/StringBuilder;)V
+HSPLjava/lang/reflect/Method;->toString()Ljava/lang/String;
 HSPLjava/lang/reflect/Modifier;->isFinal(I)Z
 HSPLjava/lang/reflect/Modifier;->isPublic(I)Z
 HSPLjava/lang/reflect/Modifier;->isStatic(I)Z
+HSPLjava/lang/reflect/Modifier;->toString(I)Ljava/lang/String;
 HSPLjava/lang/reflect/Proxy$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLjava/lang/reflect/Proxy$1;->compare(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)I
 HSPLjava/lang/reflect/Proxy$Key1;->equals(Ljava/lang/Object;)Z
@@ -25914,6 +27035,7 @@
 HSPLjava/math/BigInteger;-><init>(Ljava/lang/String;I)V
 HSPLjava/math/BigInteger;-><init>([B)V
 HSPLjava/math/BigInteger;->abs()Ljava/math/BigInteger;
+HSPLjava/math/BigInteger;->add(Ljava/math/BigInteger;)Ljava/math/BigInteger;
 HSPLjava/math/BigInteger;->bitLength()I
 HSPLjava/math/BigInteger;->compareTo(Ljava/math/BigInteger;)I
 HSPLjava/math/BigInteger;->divide(Ljava/math/BigInteger;)Ljava/math/BigInteger;
@@ -25934,9 +27056,11 @@
 HSPLjava/math/BigInteger;->testBit(I)Z
 HSPLjava/math/BigInteger;->toByteArray()[B
 HSPLjava/math/BigInteger;->toString()Ljava/lang/String;
+HSPLjava/math/BigInteger;->toString(I)Ljava/lang/String;
 HSPLjava/math/BigInteger;->twosComplement()[B
 HSPLjava/math/BigInteger;->valueOf(J)Ljava/math/BigInteger;
 HSPLjava/math/BigInteger;->writeObject(Ljava/io/ObjectOutputStream;)V
+HSPLjava/math/Conversion;->bigInteger2String(Ljava/math/BigInteger;I)Ljava/lang/String;
 HSPLjava/math/MathContext;-><init>(I)V
 HSPLjava/math/MathContext;-><init>(ILjava/math/RoundingMode;)V
 HSPLjava/math/MathContext;->checkValid()V
@@ -25954,6 +27078,7 @@
 HSPLjava/net/AbstractPlainDatagramSocketImpl;->setOption(ILjava/lang/Object;)V
 HSPLjava/net/AbstractPlainSocketImpl;-><init>()V
 HSPLjava/net/AbstractPlainSocketImpl;->acquireFD()Ljava/io/FileDescriptor;
+HSPLjava/net/AbstractPlainSocketImpl;->bind(Ljava/net/InetAddress;I)V
 HSPLjava/net/AbstractPlainSocketImpl;->close()V
 HSPLjava/net/AbstractPlainSocketImpl;->connect(Ljava/net/SocketAddress;I)V
 HSPLjava/net/AbstractPlainSocketImpl;->create(Z)V
@@ -25963,6 +27088,7 @@
 HSPLjava/net/AbstractPlainSocketImpl;->getOption(I)Ljava/lang/Object;
 HSPLjava/net/AbstractPlainSocketImpl;->getOutputStream()Ljava/io/OutputStream;
 HSPLjava/net/AbstractPlainSocketImpl;->isClosedOrPending()Z
+HSPLjava/net/AbstractPlainSocketImpl;->listen(I)V
 HSPLjava/net/AbstractPlainSocketImpl;->releaseFD()V
 HSPLjava/net/AbstractPlainSocketImpl;->setOption(ILjava/lang/Object;)V
 HSPLjava/net/AbstractPlainSocketImpl;->socketClose()V
@@ -26019,8 +27145,11 @@
 HSPLjava/net/HttpCookie$9;-><init>()V
 HSPLjava/net/HttpURLConnection;-><init>(Ljava/net/URL;)V
 HSPLjava/net/HttpURLConnection;->getFollowRedirects()Z
+HSPLjava/net/HttpURLConnection;->setInstanceFollowRedirects(Z)V
 HSPLjava/net/IDN;->toASCII(Ljava/lang/String;)Ljava/lang/String;
 HSPLjava/net/IDN;->toASCII(Ljava/lang/String;I)Ljava/lang/String;
+HSPLjava/net/IDN;->toUnicode(Ljava/lang/String;)Ljava/lang/String;
+HSPLjava/net/IDN;->toUnicode(Ljava/lang/String;I)Ljava/lang/String;
 HSPLjava/net/Inet4Address;-><init>(Ljava/lang/String;[B)V
 HSPLjava/net/Inet4Address;->equals(Ljava/lang/Object;)Z
 HSPLjava/net/Inet4Address;->getAddress()[B
@@ -26061,6 +27190,8 @@
 HSPLjava/net/InetAddress$InetAddressHolder;->init(Ljava/lang/String;I)V
 HSPLjava/net/InetAddress;->clearDnsCache()V
 HSPLjava/net/InetAddress;->getAllByName(Ljava/lang/String;)[Ljava/net/InetAddress;
+HSPLjava/net/InetAddress;->getAllByNameOnNet(Ljava/lang/String;I)[Ljava/net/InetAddress;
+HSPLjava/net/InetAddress;->getByAddress(Ljava/lang/String;[B)Ljava/net/InetAddress;
 HSPLjava/net/InetAddress;->getByAddress(Ljava/lang/String;[BI)Ljava/net/InetAddress;
 HSPLjava/net/InetAddress;->getByAddress([B)Ljava/net/InetAddress;
 HSPLjava/net/InetAddress;->getByName(Ljava/lang/String;)Ljava/net/InetAddress;
@@ -26068,11 +27199,14 @@
 HSPLjava/net/InetAddress;->holder()Ljava/net/InetAddress$InetAddressHolder;
 HSPLjava/net/InetAddress;->parseNumericAddress(Ljava/lang/String;)Ljava/net/InetAddress;
 HSPLjava/net/InetAddress;->toString()Ljava/lang/String;
+HSPLjava/net/InetSocketAddress$InetSocketAddressHolder;->equals(Ljava/lang/Object;)Z
 HSPLjava/net/InetSocketAddress$InetSocketAddressHolder;->getHostString()Ljava/lang/String;
 HSPLjava/net/InetSocketAddress$InetSocketAddressHolder;->toString()Ljava/lang/String;
 HSPLjava/net/InetSocketAddress;-><init>()V
+HSPLjava/net/InetSocketAddress;-><init>(Ljava/lang/String;I)V
 HSPLjava/net/InetSocketAddress;-><init>(Ljava/net/InetAddress;I)V
 HSPLjava/net/InetSocketAddress;->createUnresolved(Ljava/lang/String;I)Ljava/net/InetSocketAddress;
+HSPLjava/net/InetSocketAddress;->equals(Ljava/lang/Object;)Z
 HSPLjava/net/InetSocketAddress;->getAddress()Ljava/net/InetAddress;
 HSPLjava/net/InetSocketAddress;->getHostString()Ljava/lang/String;
 HSPLjava/net/InetSocketAddress;->getPort()I
@@ -26091,10 +27225,12 @@
 HSPLjava/net/PlainDatagramSocketImpl;->send(Ljava/net/DatagramPacket;)V
 HSPLjava/net/PlainDatagramSocketImpl;->socketGetOption(I)Ljava/lang/Object;
 HSPLjava/net/PlainSocketImpl;->getMarkerFD()Ljava/io/FileDescriptor;
+HSPLjava/net/PlainSocketImpl;->socketBind(Ljava/net/InetAddress;I)V
 HSPLjava/net/PlainSocketImpl;->socketClose0(Z)V
 HSPLjava/net/PlainSocketImpl;->socketConnect(Ljava/net/InetAddress;II)V
 HSPLjava/net/PlainSocketImpl;->socketCreate(Z)V
 HSPLjava/net/PlainSocketImpl;->socketGetOption(I)Ljava/lang/Object;
+HSPLjava/net/PlainSocketImpl;->socketListen(I)V
 HSPLjava/net/PlainSocketImpl;->socketSetOption(ILjava/lang/Object;)V
 HSPLjava/net/PlainSocketImpl;->socketSetOption0(ILjava/lang/Object;)V
 HSPLjava/net/ProtocolException;-><init>(Ljava/lang/String;)V
@@ -26107,11 +27243,20 @@
 HSPLjava/net/ProxySelector;->getDefault()Ljava/net/ProxySelector;
 HSPLjava/net/ProxySelector;->setDefault(Ljava/net/ProxySelector;)V
 HSPLjava/net/ResponseCache;->getDefault()Ljava/net/ResponseCache;
+HSPLjava/net/ServerSocket;->bind(Ljava/net/SocketAddress;I)V
+HSPLjava/net/ServerSocket;->createImpl()V
+HSPLjava/net/ServerSocket;->getImpl()Ljava/net/SocketImpl;
+HSPLjava/net/ServerSocket;->isBound()Z
+HSPLjava/net/ServerSocket;->isClosed()Z
+HSPLjava/net/ServerSocket;->setBound()V
+HSPLjava/net/ServerSocket;->setCreated()V
 HSPLjava/net/Socket$2;->run()Ljava/io/InputStream;
 HSPLjava/net/Socket$2;->run()Ljava/lang/Object;
 HSPLjava/net/Socket$3;->run()Ljava/io/OutputStream;
 HSPLjava/net/Socket$3;->run()Ljava/lang/Object;
 HSPLjava/net/Socket;-><init>()V
+HSPLjava/net/Socket;-><init>(Ljava/net/InetAddress;I)V
+HSPLjava/net/Socket;-><init>(Ljava/net/SocketImpl;)V
 HSPLjava/net/Socket;-><init>([Ljava/net/InetAddress;ILjava/net/SocketAddress;Z)V
 HSPLjava/net/Socket;->checkAddress(Ljava/net/InetAddress;Ljava/lang/String;)V
 HSPLjava/net/Socket;->close()V
@@ -26128,6 +27273,7 @@
 HSPLjava/net/Socket;->getOutputStream()Ljava/io/OutputStream;
 HSPLjava/net/Socket;->getPort()I
 HSPLjava/net/Socket;->getRemoteSocketAddress()Ljava/net/SocketAddress;
+HSPLjava/net/Socket;->getReuseAddress()Z
 HSPLjava/net/Socket;->getSoTimeout()I
 HSPLjava/net/Socket;->isBound()Z
 HSPLjava/net/Socket;->isClosed()Z
@@ -26143,6 +27289,7 @@
 HSPLjava/net/SocketException;-><init>(Ljava/lang/String;)V
 HSPLjava/net/SocketImpl;->getFileDescriptor()Ljava/io/FileDescriptor;
 HSPLjava/net/SocketImpl;->getSocket()Ljava/net/Socket;
+HSPLjava/net/SocketImpl;->setServerSocket(Ljava/net/ServerSocket;)V
 HSPLjava/net/SocketImpl;->setSocket(Ljava/net/Socket;)V
 HSPLjava/net/SocketInputStream;->finalize()V
 HSPLjava/net/SocketOutputStream;->finalize()V
@@ -26172,10 +27319,13 @@
 HSPLjava/net/URI;->defineString()V
 HSPLjava/net/URI;->encode(Ljava/lang/String;)Ljava/lang/String;
 HSPLjava/net/URI;->getAuthority()Ljava/lang/String;
+HSPLjava/net/URI;->getFragment()Ljava/lang/String;
 HSPLjava/net/URI;->getHost()Ljava/lang/String;
 HSPLjava/net/URI;->getPath()Ljava/lang/String;
 HSPLjava/net/URI;->getPort()I
+HSPLjava/net/URI;->getQuery()Ljava/lang/String;
 HSPLjava/net/URI;->getScheme()Ljava/lang/String;
+HSPLjava/net/URI;->getUserInfo()Ljava/lang/String;
 HSPLjava/net/URI;->match(CJJ)Z
 HSPLjava/net/URI;->quote(Ljava/lang/String;JJ)Ljava/lang/String;
 HSPLjava/net/URI;->toASCIIString()Ljava/lang/String;
@@ -26193,9 +27343,14 @@
 HSPLjava/net/URL;->set(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLjava/net/URL;->toExternalForm()Ljava/lang/String;
 HSPLjava/net/URL;->toString()Ljava/lang/String;
+HSPLjava/net/URLConnection;->getContentLengthLong()J
+HSPLjava/net/URLConnection;->getContentType()Ljava/lang/String;
+HSPLjava/net/URLConnection;->getHeaderFieldLong(Ljava/lang/String;J)J
 HSPLjava/net/URLConnection;->getURL()Ljava/net/URL;
 HSPLjava/net/URLConnection;->getUseCaches()Z
+HSPLjava/net/URLConnection;->setDoInput(Z)V
 HSPLjava/net/URLConnection;->setDoOutput(Z)V
+HSPLjava/net/URLConnection;->setReadTimeout(I)V
 HSPLjava/net/URLConnection;->setUseCaches(Z)V
 HSPLjava/net/URLDecoder;->decode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLjava/net/URLEncoder;->encode(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
@@ -26316,12 +27471,14 @@
 HSPLjava/nio/DirectByteBuffer;->putInt(I)Ljava/nio/ByteBuffer;
 HSPLjava/nio/DirectByteBuffer;->putLong(J)Ljava/nio/ByteBuffer;
 HSPLjava/nio/DirectByteBuffer;->putShort(S)Ljava/nio/ByteBuffer;
+HSPLjava/nio/DirectByteBuffer;->setAccessible(Z)V
 HSPLjava/nio/DirectByteBuffer;->slice()Ljava/nio/ByteBuffer;
 HSPLjava/nio/FloatBuffer;->limit(I)Ljava/nio/Buffer;
 HSPLjava/nio/FloatBuffer;->position(I)Ljava/nio/Buffer;
 HSPLjava/nio/HeapByteBuffer;->_get(I)B
 HSPLjava/nio/HeapByteBuffer;->_put(IB)V
 HSPLjava/nio/HeapByteBuffer;->asReadOnlyBuffer()Ljava/nio/ByteBuffer;
+HSPLjava/nio/HeapByteBuffer;->asShortBuffer()Ljava/nio/ShortBuffer;
 HSPLjava/nio/HeapByteBuffer;->compact()Ljava/nio/ByteBuffer;
 HSPLjava/nio/HeapByteBuffer;->duplicate()Ljava/nio/ByteBuffer;
 HSPLjava/nio/HeapByteBuffer;->get()B
@@ -26369,6 +27526,7 @@
 HSPLjava/nio/StringCharBuffer;->get(I)C
 HSPLjava/nio/channels/Channels;->newInputStream(Ljava/nio/channels/ReadableByteChannel;)Ljava/io/InputStream;
 HSPLjava/nio/channels/FileChannel$MapMode;-><init>(Ljava/lang/String;)V
+HSPLjava/nio/channels/FileChannel;->tryLock()Ljava/nio/channels/FileLock;
 HSPLjava/nio/channels/FileLock;-><init>(Ljava/nio/channels/FileChannel;JJZ)V
 HSPLjava/nio/channels/FileLock;->acquiredBy()Ljava/nio/channels/Channel;
 HSPLjava/nio/channels/spi/AbstractInterruptibleChannel;->begin()V
@@ -26435,6 +27593,7 @@
 HSPLjava/nio/file/AccessMode;-><init>(Ljava/lang/String;I)V
 HSPLjava/nio/file/FileSystems$DefaultFileSystemHolder;->defaultFileSystem()Ljava/nio/file/FileSystem;
 HSPLjava/nio/file/FileSystems$DefaultFileSystemHolder;->getDefaultProvider()Ljava/nio/file/spi/FileSystemProvider;
+HSPLjava/nio/file/FileSystems;->getDefault()Ljava/nio/file/FileSystem;
 PLjava/nio/file/Files$1;->accept(Ljava/lang/Object;)Z
 PLjava/nio/file/Files$1;->accept(Ljava/nio/file/Path;)Z
 HSPLjava/nio/file/Files$AcceptAllFilter;-><init>()V
@@ -26447,8 +27606,8 @@
 HSPLjava/nio/file/Files;->isRegularFile(Ljava/nio/file/Path;[Ljava/nio/file/LinkOption;)Z
 HSPLjava/nio/file/Files;->newBufferedReader(Ljava/nio/file/Path;)Ljava/io/BufferedReader;
 HSPLjava/nio/file/Files;->newBufferedReader(Ljava/nio/file/Path;Ljava/nio/charset/Charset;)Ljava/io/BufferedReader;
-PLjava/nio/file/Files;->newDirectoryStream(Ljava/nio/file/Path;)Ljava/nio/file/DirectoryStream;
-PLjava/nio/file/Files;->newDirectoryStream(Ljava/nio/file/Path;Ljava/lang/String;)Ljava/nio/file/DirectoryStream;
+HPLjava/nio/file/Files;->newDirectoryStream(Ljava/nio/file/Path;)Ljava/nio/file/DirectoryStream;
+HPLjava/nio/file/Files;->newDirectoryStream(Ljava/nio/file/Path;Ljava/lang/String;)Ljava/nio/file/DirectoryStream;
 HSPLjava/nio/file/Files;->read(Ljava/io/InputStream;I)[B
 HSPLjava/nio/file/Files;->readAllBytes(Ljava/nio/file/Path;)[B
 HSPLjava/nio/file/LinkOption;-><init>(Ljava/lang/String;I)V
@@ -26497,6 +27656,7 @@
 HSPLjava/security/MessageDigest;->digest([BII)I
 HSPLjava/security/MessageDigest;->getDigestLength()I
 HSPLjava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;
+HSPLjava/security/MessageDigest;->getInstance(Ljava/lang/String;Ljava/lang/String;)Ljava/security/MessageDigest;
 HSPLjava/security/MessageDigest;->getInstance(Ljava/lang/String;Ljava/security/Provider;)Ljava/security/MessageDigest;
 HSPLjava/security/MessageDigest;->isEqual([B[B)Z
 HSPLjava/security/MessageDigest;->reset()V
@@ -26575,7 +27735,7 @@
 HSPLjava/security/cert/CertPath;->getType()Ljava/lang/String;
 PLjava/security/cert/CertPathBuilder;->build(Ljava/security/cert/CertPathParameters;)Ljava/security/cert/CertPathBuilderResult;
 PLjava/security/cert/CertPathBuilder;->getInstance(Ljava/lang/String;)Ljava/security/cert/CertPathBuilder;
-PLjava/security/cert/CertPathHelperImpl;->implSetPathToNames(Ljava/security/cert/X509CertSelector;Ljava/util/Set;)V
+HPLjava/security/cert/CertPathHelperImpl;->implSetPathToNames(Ljava/security/cert/X509CertSelector;Ljava/util/Set;)V
 HSPLjava/security/cert/CertPathHelperImpl;->initialize()V
 HSPLjava/security/cert/CertPathValidator;->getInstance(Ljava/lang/String;)Ljava/security/cert/CertPathValidator;
 HSPLjava/security/cert/CertPathValidator;->getRevocationChecker()Ljava/security/cert/CertPathChecker;
@@ -26583,14 +27743,14 @@
 HSPLjava/security/cert/CertStore;->getInstance(Ljava/lang/String;Ljava/security/cert/CertStoreParameters;)Ljava/security/cert/CertStore;
 HSPLjava/security/cert/Certificate;->equals(Ljava/lang/Object;)Z
 HSPLjava/security/cert/Certificate;->hashCode()I
-PLjava/security/cert/CertificateFactory;->generateCertPath(Ljava/io/InputStream;)Ljava/security/cert/CertPath;
+HPLjava/security/cert/CertificateFactory;->generateCertPath(Ljava/io/InputStream;)Ljava/security/cert/CertPath;
 HSPLjava/security/cert/CertificateFactory;->generateCertPath(Ljava/util/List;)Ljava/security/cert/CertPath;
 HSPLjava/security/cert/CertificateFactory;->generateCertificate(Ljava/io/InputStream;)Ljava/security/cert/Certificate;
 HSPLjava/security/cert/CertificateFactory;->getInstance(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;
 HSPLjava/security/cert/CertificateFactorySpi;-><init>()V
 HSPLjava/security/cert/CollectionCertStoreParameters;-><init>(Ljava/util/Collection;)V
 HSPLjava/security/cert/CollectionCertStoreParameters;->clone()Ljava/lang/Object;
-PLjava/security/cert/CollectionCertStoreParameters;->getCollection()Ljava/util/Collection;
+HPLjava/security/cert/CollectionCertStoreParameters;->getCollection()Ljava/util/Collection;
 PLjava/security/cert/PKIXBuilderParameters;-><init>(Ljava/util/Set;Ljava/security/cert/CertSelector;)V
 PLjava/security/cert/PKIXBuilderParameters;->getMaxPathLength()I
 PLjava/security/cert/PKIXCertPathBuilderResult;->getCertPath()Ljava/security/cert/CertPath;
@@ -26598,7 +27758,7 @@
 HSPLjava/security/cert/PKIXCertPathChecker;->clone()Ljava/lang/Object;
 HSPLjava/security/cert/PKIXParameters;-><init>(Ljava/util/Set;)V
 HSPLjava/security/cert/PKIXParameters;->addCertPathChecker(Ljava/security/cert/PKIXCertPathChecker;)V
-PLjava/security/cert/PKIXParameters;->addCertStore(Ljava/security/cert/CertStore;)V
+HPLjava/security/cert/PKIXParameters;->addCertStore(Ljava/security/cert/CertStore;)V
 HSPLjava/security/cert/PKIXParameters;->getCertPathCheckers()Ljava/util/List;
 HSPLjava/security/cert/PKIXParameters;->getCertStores()Ljava/util/List;
 HSPLjava/security/cert/PKIXParameters;->getDate()Ljava/util/Date;
@@ -26631,11 +27791,11 @@
 HSPLjava/security/cert/TrustAnchor;->getTrustedCert()Ljava/security/cert/X509Certificate;
 HSPLjava/security/cert/TrustAnchor;->setNameConstraints([B)V
 HSPLjava/security/cert/X509CertSelector;-><init>()V
-PLjava/security/cert/X509CertSelector;->clone()Ljava/lang/Object;
-PLjava/security/cert/X509CertSelector;->getBasicConstraints()I
-PLjava/security/cert/X509CertSelector;->getCertificate()Ljava/security/cert/X509Certificate;
-PLjava/security/cert/X509CertSelector;->getExtensionObject(Ljava/security/cert/X509Certificate;I)Ljava/security/cert/Extension;
-PLjava/security/cert/X509CertSelector;->getSubject()Ljavax/security/auth/x500/X500Principal;
+HPLjava/security/cert/X509CertSelector;->clone()Ljava/lang/Object;
+HPLjava/security/cert/X509CertSelector;->getBasicConstraints()I
+HPLjava/security/cert/X509CertSelector;->getCertificate()Ljava/security/cert/X509Certificate;
+HPLjava/security/cert/X509CertSelector;->getExtensionObject(Ljava/security/cert/X509Certificate;I)Ljava/security/cert/Extension;
+HPLjava/security/cert/X509CertSelector;->getSubject()Ljavax/security/auth/x500/X500Principal;
 HSPLjava/security/cert/X509CertSelector;->match(Ljava/security/cert/Certificate;)Z
 HSPLjava/security/cert/X509CertSelector;->matchAuthorityKeyID(Ljava/security/cert/X509Certificate;)Z
 HSPLjava/security/cert/X509CertSelector;->matchBasicConstraints(Ljava/security/cert/X509Certificate;)Z
@@ -26648,9 +27808,9 @@
 HSPLjava/security/cert/X509CertSelector;->matchSubjectAlternativeNames(Ljava/security/cert/X509Certificate;)Z
 HSPLjava/security/cert/X509CertSelector;->matchSubjectKeyID(Ljava/security/cert/X509Certificate;)Z
 HSPLjava/security/cert/X509CertSelector;->matchSubjectPublicKeyAlgID(Ljava/security/cert/X509Certificate;)Z
-PLjava/security/cert/X509CertSelector;->setBasicConstraints(I)V
-PLjava/security/cert/X509CertSelector;->setCertificateValid(Ljava/util/Date;)V
-PLjava/security/cert/X509CertSelector;->setPathToNamesInternal(Ljava/util/Set;)V
+HPLjava/security/cert/X509CertSelector;->setBasicConstraints(I)V
+HPLjava/security/cert/X509CertSelector;->setCertificateValid(Ljava/util/Date;)V
+HPLjava/security/cert/X509CertSelector;->setPathToNamesInternal(Ljava/util/Set;)V
 HSPLjava/security/cert/X509CertSelector;->setSubject(Ljavax/security/auth/x500/X500Principal;)V
 HSPLjava/security/cert/X509Certificate;-><init>()V
 HSPLjava/security/spec/DSAParameterSpec;->getG()Ljava/math/BigInteger;
@@ -26686,6 +27846,7 @@
 HSPLjava/text/CalendarBuilder;->set(II)Ljava/text/CalendarBuilder;
 HSPLjava/text/Collator;->getInstance()Ljava/text/Collator;
 HSPLjava/text/Collator;->getInstance(Ljava/util/Locale;)Ljava/text/Collator;
+HSPLjava/text/Collator;->setStrength(I)V
 HSPLjava/text/DateFormat$Field;-><init>(Ljava/lang/String;I)V
 HSPLjava/text/DateFormat;->format(Ljava/lang/Object;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
 HSPLjava/text/DateFormat;->format(Ljava/util/Date;)Ljava/lang/String;
@@ -26706,6 +27867,7 @@
 HSPLjava/text/DateFormatSymbols;->initializeData(Ljava/util/Locale;)V
 HSPLjava/text/DateFormatSymbols;->initializeSupplementaryData(Llibcore/icu/LocaleData;)V
 HSPLjava/text/DecimalFormat;-><init>(Ljava/lang/String;)V
+HSPLjava/text/DecimalFormat;-><init>(Ljava/lang/String;Ljava/text/DecimalFormatSymbols;)V
 HSPLjava/text/DecimalFormat;->clone()Ljava/lang/Object;
 HSPLjava/text/DecimalFormat;->equals(Ljava/lang/Object;)Z
 HSPLjava/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
@@ -26714,6 +27876,7 @@
 HSPLjava/text/DecimalFormat;->getIcuFieldPosition(Ljava/text/FieldPosition;)Ljava/text/FieldPosition;
 HSPLjava/text/DecimalFormat;->getMaximumFractionDigits()I
 HSPLjava/text/DecimalFormat;->getMaximumIntegerDigits()I
+HSPLjava/text/DecimalFormat;->getMinimumFractionDigits()I
 HSPLjava/text/DecimalFormat;->getMinimumIntegerDigits()I
 HSPLjava/text/DecimalFormat;->getNegativePrefix()Ljava/lang/String;
 HSPLjava/text/DecimalFormat;->getNegativeSuffix()Ljava/lang/String;
@@ -26725,6 +27888,7 @@
 HSPLjava/text/DecimalFormat;->setGroupingUsed(Z)V
 HSPLjava/text/DecimalFormat;->setMaximumFractionDigits(I)V
 HSPLjava/text/DecimalFormat;->setMaximumIntegerDigits(I)V
+HSPLjava/text/DecimalFormat;->setMinimumFractionDigits(I)V
 HSPLjava/text/DecimalFormat;->setMinimumIntegerDigits(I)V
 HSPLjava/text/DecimalFormat;->toPattern()Ljava/lang/String;
 HSPLjava/text/DecimalFormat;->updateFieldsFromIcu()V
@@ -26760,6 +27924,7 @@
 HSPLjava/text/Normalizer;->normalize(Ljava/lang/CharSequence;Ljava/text/Normalizer$Form;)Ljava/lang/String;
 HSPLjava/text/NumberFormat;->format(D)Ljava/lang/String;
 HSPLjava/text/NumberFormat;->format(J)Ljava/lang/String;
+HSPLjava/text/NumberFormat;->getInstance(Ljava/util/Locale;)Ljava/text/NumberFormat;
 HSPLjava/text/NumberFormat;->getInstance(Ljava/util/Locale;I)Ljava/text/NumberFormat;
 HSPLjava/text/NumberFormat;->getIntegerInstance()Ljava/text/NumberFormat;
 HSPLjava/text/NumberFormat;->getIntegerInstance(Ljava/util/Locale;)Ljava/text/NumberFormat;
@@ -26795,6 +27960,8 @@
 HSPLjava/text/StringCharacterIterator;-><init>(Ljava/lang/String;III)V
 HSPLjava/text/StringCharacterIterator;->clone()Ljava/lang/Object;
 HSPLjava/text/StringCharacterIterator;->current()C
+HSPLjava/text/StringCharacterIterator;->first()C
+HSPLjava/text/StringCharacterIterator;->getBeginIndex()I
 HSPLjava/text/StringCharacterIterator;->getEndIndex()I
 HSPLjava/text/StringCharacterIterator;->getIndex()I
 HSPLjava/text/StringCharacterIterator;->next()C
@@ -26817,7 +27984,10 @@
 HSPLjava/time/DayOfWeek;->of(I)Ljava/time/DayOfWeek;
 HSPLjava/time/DayOfWeek;->values()[Ljava/time/DayOfWeek;
 HSPLjava/time/Duration;-><init>(JI)V
+HSPLjava/time/Duration;->ofDays(J)Ljava/time/Duration;
 HSPLjava/time/Duration;->ofHours(J)Ljava/time/Duration;
+HSPLjava/time/Duration;->ofMillis(J)Ljava/time/Duration;
+HSPLjava/time/Duration;->ofMinutes(J)Ljava/time/Duration;
 HSPLjava/time/Duration;->ofNanos(J)Ljava/time/Duration;
 HSPLjava/time/Duration;->ofSeconds(J)Ljava/time/Duration;
 HSPLjava/time/Duration;->ofSeconds(JJ)Ljava/time/Duration;
@@ -26825,11 +27995,13 @@
 HSPLjava/time/Instant;-><init>(JI)V
 HSPLjava/time/Instant;->create(JI)Ljava/time/Instant;
 HSPLjava/time/Instant;->from(Ljava/time/temporal/TemporalAccessor;)Ljava/time/Instant;
+HSPLjava/time/Instant;->isSupported(Ljava/time/temporal/TemporalField;)Z
 HSPLjava/time/Instant;->now()Ljava/time/Instant;
 HSPLjava/time/Instant;->ofEpochMilli(J)Ljava/time/Instant;
 HSPLjava/time/Instant;->ofEpochSecond(JJ)Ljava/time/Instant;
 HSPLjava/time/Instant;->parse(Ljava/lang/CharSequence;)Ljava/time/Instant;
 HSPLjava/time/Instant;->plus(JJ)Ljava/time/Instant;
+HSPLjava/time/Instant;->plusMillis(J)Ljava/time/Instant;
 HSPLjava/time/Instant;->toEpochMilli()J
 HSPLjava/time/LocalDate;->atTime(Ljava/time/LocalTime;)Ljava/time/chrono/ChronoLocalDateTime;
 HSPLjava/time/LocalDate;->create(III)Ljava/time/LocalDate;
@@ -26837,7 +28009,7 @@
 HSPLjava/time/LocalDate;->from(Ljava/time/temporal/TemporalAccessor;)Ljava/time/LocalDate;
 HSPLjava/time/LocalDate;->get0(Ljava/time/temporal/TemporalField;)I
 HSPLjava/time/LocalDate;->getChronology()Ljava/time/chrono/Chronology;
-PLjava/time/LocalDate;->getLong(Ljava/time/temporal/TemporalField;)J
+HPLjava/time/LocalDate;->getLong(Ljava/time/temporal/TemporalField;)J
 HSPLjava/time/LocalDate;->isAfter(Ljava/time/chrono/ChronoLocalDate;)Z
 HSPLjava/time/LocalDate;->isSupported(Ljava/time/temporal/TemporalField;)Z
 HSPLjava/time/LocalDate;->minusDays(J)Ljava/time/LocalDate;
@@ -26918,7 +28090,7 @@
 HSPLjava/time/ZoneRegion;->ofId(Ljava/lang/String;Z)Ljava/time/ZoneRegion;
 HSPLjava/time/ZonedDateTime;->create(JILjava/time/ZoneId;)Ljava/time/ZonedDateTime;
 HSPLjava/time/ZonedDateTime;->equals(Ljava/lang/Object;)Z
-PLjava/time/ZonedDateTime;->format(Ljava/time/format/DateTimeFormatter;)Ljava/lang/String;
+HPLjava/time/ZonedDateTime;->format(Ljava/time/format/DateTimeFormatter;)Ljava/lang/String;
 HSPLjava/time/ZonedDateTime;->from(Ljava/time/temporal/TemporalAccessor;)Ljava/time/ZonedDateTime;
 HSPLjava/time/ZonedDateTime;->getDayOfMonth()I
 HSPLjava/time/ZonedDateTime;->getLong(Ljava/time/temporal/TemporalField;)J
@@ -26929,9 +28101,9 @@
 HSPLjava/time/ZonedDateTime;->ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;)Ljava/time/ZonedDateTime;
 HSPLjava/time/ZonedDateTime;->ofLocal(Ljava/time/LocalDateTime;Ljava/time/ZoneId;Ljava/time/ZoneOffset;)Ljava/time/ZonedDateTime;
 HSPLjava/time/ZonedDateTime;->parse(Ljava/lang/CharSequence;)Ljava/time/ZonedDateTime;
-PLjava/time/ZonedDateTime;->parse(Ljava/lang/CharSequence;Ljava/time/format/DateTimeFormatter;)Ljava/time/ZonedDateTime;
+HPLjava/time/ZonedDateTime;->parse(Ljava/lang/CharSequence;Ljava/time/format/DateTimeFormatter;)Ljava/time/ZonedDateTime;
 HSPLjava/time/ZonedDateTime;->plus(Ljava/time/temporal/TemporalAmount;)Ljava/time/ZonedDateTime;
-PLjava/time/ZonedDateTime;->query(Ljava/time/temporal/TemporalQuery;)Ljava/lang/Object;
+HPLjava/time/ZonedDateTime;->query(Ljava/time/temporal/TemporalQuery;)Ljava/lang/Object;
 HSPLjava/time/ZonedDateTime;->toLocalDate()Ljava/time/LocalDate;
 HSPLjava/time/ZonedDateTime;->toLocalDate()Ljava/time/chrono/ChronoLocalDate;
 HSPLjava/time/ZonedDateTime;->toLocalTime()Ljava/time/LocalTime;
@@ -26946,8 +28118,8 @@
 HSPLjava/time/chrono/ChronoLocalDateTime;->toEpochSecond(Ljava/time/ZoneOffset;)J
 HSPLjava/time/chrono/ChronoZonedDateTime;->compareTo(Ljava/lang/Object;)I
 HSPLjava/time/chrono/ChronoZonedDateTime;->compareTo(Ljava/time/chrono/ChronoZonedDateTime;)I
-PLjava/time/chrono/ChronoZonedDateTime;->getChronology()Ljava/time/chrono/Chronology;
-PLjava/time/chrono/ChronoZonedDateTime;->query(Ljava/time/temporal/TemporalQuery;)Ljava/lang/Object;
+HPLjava/time/chrono/ChronoZonedDateTime;->getChronology()Ljava/time/chrono/Chronology;
+HPLjava/time/chrono/ChronoZonedDateTime;->query(Ljava/time/temporal/TemporalQuery;)Ljava/lang/Object;
 HSPLjava/time/chrono/ChronoZonedDateTime;->toEpochSecond()J
 HSPLjava/time/chrono/ChronoZonedDateTime;->toInstant()Ljava/time/Instant;
 HSPLjava/time/chrono/IsoChronology;-><init>()V
@@ -26960,7 +28132,7 @@
 HSPLjava/time/format/-$$Lambda$DateTimeFormatter$GhpE1dbCMFpBqvhZZgrqVYpzk8E;-><init>()V
 HSPLjava/time/format/-$$Lambda$DateTimeFormatter$QqeEAMXK7Qf5gsmaSCLmrVwQ1Ns;-><init>()V
 HSPLjava/time/format/-$$Lambda$DateTimeFormatterBuilder$M-GACNxm6552EiylPRPw4dyNXKo;-><init>()V
-PLjava/time/format/-$$Lambda$DateTimeFormatterBuilder$M-GACNxm6552EiylPRPw4dyNXKo;->queryFrom(Ljava/time/temporal/TemporalAccessor;)Ljava/lang/Object;
+HPLjava/time/format/-$$Lambda$DateTimeFormatterBuilder$M-GACNxm6552EiylPRPw4dyNXKo;->queryFrom(Ljava/time/temporal/TemporalAccessor;)Ljava/lang/Object;
 HSPLjava/time/format/DateTimeFormatter;-><init>(Ljava/time/format/DateTimeFormatterBuilder$CompositePrinterParser;Ljava/util/Locale;Ljava/time/format/DecimalStyle;Ljava/time/format/ResolverStyle;Ljava/util/Set;Ljava/time/chrono/Chronology;Ljava/time/ZoneId;)V
 HSPLjava/time/format/DateTimeFormatter;->formatTo(Ljava/time/temporal/TemporalAccessor;Ljava/lang/Appendable;)V
 HSPLjava/time/format/DateTimeFormatter;->ofPattern(Ljava/lang/String;)Ljava/time/format/DateTimeFormatter;
@@ -26969,25 +28141,25 @@
 HSPLjava/time/format/DateTimeFormatter;->parseUnresolved0(Ljava/lang/CharSequence;Ljava/text/ParsePosition;)Ljava/time/format/DateTimeParseContext;
 HSPLjava/time/format/DateTimeFormatter;->toPrinterParser(Z)Ljava/time/format/DateTimeFormatterBuilder$CompositePrinterParser;
 HSPLjava/time/format/DateTimeFormatterBuilder$2;-><init>()V
-PLjava/time/format/DateTimeFormatterBuilder$CharLiteralPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
+HPLjava/time/format/DateTimeFormatterBuilder$CharLiteralPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
 HSPLjava/time/format/DateTimeFormatterBuilder$CharLiteralPrinterParser;->parse(Ljava/time/format/DateTimeParseContext;Ljava/lang/CharSequence;I)I
 HSPLjava/time/format/DateTimeFormatterBuilder$CompositePrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
 HSPLjava/time/format/DateTimeFormatterBuilder$CompositePrinterParser;->parse(Ljava/time/format/DateTimeParseContext;Ljava/lang/CharSequence;I)I
 HSPLjava/time/format/DateTimeFormatterBuilder$FractionPrinterParser;-><init>(Ljava/time/temporal/TemporalField;IIZ)V
 HSPLjava/time/format/DateTimeFormatterBuilder$FractionPrinterParser;->convertFromFraction(Ljava/math/BigDecimal;)J
-PLjava/time/format/DateTimeFormatterBuilder$FractionPrinterParser;->convertToFraction(J)Ljava/math/BigDecimal;
-PLjava/time/format/DateTimeFormatterBuilder$FractionPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
+HPLjava/time/format/DateTimeFormatterBuilder$FractionPrinterParser;->convertToFraction(J)Ljava/math/BigDecimal;
+HPLjava/time/format/DateTimeFormatterBuilder$FractionPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
 HSPLjava/time/format/DateTimeFormatterBuilder$FractionPrinterParser;->parse(Ljava/time/format/DateTimeParseContext;Ljava/lang/CharSequence;I)I
 HSPLjava/time/format/DateTimeFormatterBuilder$InstantPrinterParser;->parse(Ljava/time/format/DateTimeParseContext;Ljava/lang/CharSequence;I)I
-PLjava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
-PLjava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;->getValue(Ljava/time/format/DateTimePrintContext;J)J
+HPLjava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
+HPLjava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;->getValue(Ljava/time/format/DateTimePrintContext;J)J
 HSPLjava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;->parse(Ljava/time/format/DateTimeParseContext;Ljava/lang/CharSequence;I)I
 HSPLjava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;->setValue(Ljava/time/format/DateTimeParseContext;JII)I
 HSPLjava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;->withFixedWidth()Ljava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;
 HSPLjava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;->withSubsequentWidth(I)Ljava/time/format/DateTimeFormatterBuilder$NumberPrinterParser;
 HSPLjava/time/format/DateTimeFormatterBuilder$OffsetIdPrinterParser;-><init>(Ljava/lang/String;Ljava/lang/String;)V
 HSPLjava/time/format/DateTimeFormatterBuilder$OffsetIdPrinterParser;->checkPattern(Ljava/lang/String;)I
-PLjava/time/format/DateTimeFormatterBuilder$OffsetIdPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
+HPLjava/time/format/DateTimeFormatterBuilder$OffsetIdPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
 HSPLjava/time/format/DateTimeFormatterBuilder$OffsetIdPrinterParser;->parse(Ljava/time/format/DateTimeParseContext;Ljava/lang/CharSequence;I)I
 HSPLjava/time/format/DateTimeFormatterBuilder$OffsetIdPrinterParser;->parseNumber([IILjava/lang/CharSequence;Z)Z
 HSPLjava/time/format/DateTimeFormatterBuilder$PrefixTree;->add0(Ljava/lang/String;Ljava/lang/String;)Z
@@ -27000,7 +28172,7 @@
 HSPLjava/time/format/DateTimeFormatterBuilder$SettingsParser;-><init>(Ljava/lang/String;I)V
 HSPLjava/time/format/DateTimeFormatterBuilder$SettingsParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
 HSPLjava/time/format/DateTimeFormatterBuilder$SettingsParser;->parse(Ljava/time/format/DateTimeParseContext;Ljava/lang/CharSequence;I)I
-PLjava/time/format/DateTimeFormatterBuilder$ZoneIdPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
+HPLjava/time/format/DateTimeFormatterBuilder$ZoneIdPrinterParser;->format(Ljava/time/format/DateTimePrintContext;Ljava/lang/StringBuilder;)Z
 HSPLjava/time/format/DateTimeFormatterBuilder$ZoneIdPrinterParser;->getTree(Ljava/time/format/DateTimeParseContext;)Ljava/time/format/DateTimeFormatterBuilder$PrefixTree;
 HSPLjava/time/format/DateTimeFormatterBuilder$ZoneIdPrinterParser;->parse(Ljava/time/format/DateTimeParseContext;Ljava/lang/CharSequence;I)I
 HSPLjava/time/format/DateTimeFormatterBuilder;-><init>()V
@@ -27055,7 +28227,7 @@
 HSPLjava/time/format/Parsed;->updateCheckConflict(Ljava/time/chrono/ChronoLocalDate;)V
 HSPLjava/time/format/ResolverStyle;-><init>(Ljava/lang/String;I)V
 HSPLjava/time/format/SignStyle;-><init>(Ljava/lang/String;I)V
-PLjava/time/format/SignStyle;->values()[Ljava/time/format/SignStyle;
+HPLjava/time/format/SignStyle;->values()[Ljava/time/format/SignStyle;
 HSPLjava/time/format/TextStyle;-><init>(Ljava/lang/String;III)V
 HSPLjava/time/temporal/-$$Lambda$TemporalQueries$IZUinmsZUz98YXPe0ftAd27ByiE;-><init>()V
 HSPLjava/time/temporal/-$$Lambda$TemporalQueries$JPrXwgedeqexYxypO8VpPKV4l3c;-><init>()V
@@ -27115,6 +28287,7 @@
 HSPLjava/util/-$$Lambda$Comparator$SPB8K9Yj7Pw1mljm7LpasV7zxWw;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLjava/util/AbstractCollection;-><init>()V
 HSPLjava/util/AbstractCollection;->addAll(Ljava/util/Collection;)Z
+HSPLjava/util/AbstractCollection;->clear()V
 HSPLjava/util/AbstractCollection;->contains(Ljava/lang/Object;)Z
 HSPLjava/util/AbstractCollection;->containsAll(Ljava/util/Collection;)Z
 HSPLjava/util/AbstractCollection;->isEmpty()Z
@@ -27124,6 +28297,7 @@
 HSPLjava/util/AbstractCollection;->toArray()[Ljava/lang/Object;
 HSPLjava/util/AbstractCollection;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
 HSPLjava/util/AbstractCollection;->toString()Ljava/lang/String;
+HSPLjava/util/AbstractList$Itr;-><init>(Ljava/util/AbstractList;)V
 HSPLjava/util/AbstractList$Itr;->hasNext()Z
 HSPLjava/util/AbstractList$Itr;->next()Ljava/lang/Object;
 HSPLjava/util/AbstractList$ListItr;->nextIndex()I
@@ -27167,7 +28341,9 @@
 HSPLjava/util/ArrayDeque;->addLast(Ljava/lang/Object;)V
 HSPLjava/util/ArrayDeque;->allocateElements(I)V
 HSPLjava/util/ArrayDeque;->clear()V
+HSPLjava/util/ArrayDeque;->contains(Ljava/lang/Object;)Z
 HSPLjava/util/ArrayDeque;->delete(I)Z
+HSPLjava/util/ArrayDeque;->descendingIterator()Ljava/util/Iterator;
 HSPLjava/util/ArrayDeque;->doubleCapacity()V
 HSPLjava/util/ArrayDeque;->getFirst()Ljava/lang/Object;
 HSPLjava/util/ArrayDeque;->getLast()Ljava/lang/Object;
@@ -27190,7 +28366,7 @@
 HSPLjava/util/ArrayDeque;->removeLast()Ljava/lang/Object;
 HSPLjava/util/ArrayDeque;->size()I
 HSPLjava/util/ArrayDeque;->toArray()[Ljava/lang/Object;
-PLjava/util/ArrayDeque;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
+HPLjava/util/ArrayDeque;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
 HSPLjava/util/ArrayList$ArrayListSpliterator;->characteristics()I
 HSPLjava/util/ArrayList$ArrayListSpliterator;->estimateSize()J
 HSPLjava/util/ArrayList$ArrayListSpliterator;->forEachRemaining(Ljava/util/function/Consumer;)V
@@ -27279,10 +28455,12 @@
 HSPLjava/util/Arrays;->equals([B[B)Z
 HSPLjava/util/Arrays;->equals([F[F)Z
 HSPLjava/util/Arrays;->equals([I[I)Z
+HSPLjava/util/Arrays;->equals([J[J)Z
 HSPLjava/util/Arrays;->equals([Ljava/lang/Object;[Ljava/lang/Object;)Z
 HSPLjava/util/Arrays;->equals([Z[Z)Z
 HSPLjava/util/Arrays;->fill([BB)V
 HSPLjava/util/Arrays;->fill([CC)V
+HSPLjava/util/Arrays;->fill([CIIC)V
 HSPLjava/util/Arrays;->fill([FF)V
 HSPLjava/util/Arrays;->fill([II)V
 HSPLjava/util/Arrays;->fill([IIII)V
@@ -27297,8 +28475,10 @@
 HSPLjava/util/Arrays;->hashCode([J)I
 HSPLjava/util/Arrays;->hashCode([Ljava/lang/Object;)I
 HSPLjava/util/Arrays;->rangeCheck(III)V
+HSPLjava/util/Arrays;->sort([C)V
 HSPLjava/util/Arrays;->sort([F)V
 HSPLjava/util/Arrays;->sort([I)V
+HSPLjava/util/Arrays;->sort([III)V
 HSPLjava/util/Arrays;->sort([J)V
 HSPLjava/util/Arrays;->sort([Ljava/lang/Object;)V
 HSPLjava/util/Arrays;->sort([Ljava/lang/Object;IILjava/util/Comparator;)V
@@ -27378,6 +28558,10 @@
 HSPLjava/util/Collection;->stream()Ljava/util/stream/Stream;
 HSPLjava/util/Collections$1;->hasNext()Z
 HSPLjava/util/Collections$1;->next()Ljava/lang/Object;
+HPLjava/util/Collections$2;->characteristics()I
+HPLjava/util/Collections$2;->estimateSize()J
+HPLjava/util/Collections$2;->forEachRemaining(Ljava/util/function/Consumer;)V
+HPLjava/util/Collections$2;->tryAdvance(Ljava/util/function/Consumer;)Z
 HSPLjava/util/Collections$3;->hasMoreElements()Z
 HSPLjava/util/Collections$3;->nextElement()Ljava/lang/Object;
 HSPLjava/util/Collections$CopiesList;->get(I)Ljava/lang/Object;
@@ -27423,6 +28607,7 @@
 HSPLjava/util/Collections$SingletonList;->get(I)Ljava/lang/Object;
 HSPLjava/util/Collections$SingletonList;->iterator()Ljava/util/Iterator;
 HSPLjava/util/Collections$SingletonList;->size()I
+HPLjava/util/Collections$SingletonList;->spliterator()Ljava/util/Spliterator;
 HSPLjava/util/Collections$SingletonMap;->entrySet()Ljava/util/Set;
 HSPLjava/util/Collections$SingletonMap;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/Collections$SingletonMap;->keySet()Ljava/util/Set;
@@ -27446,7 +28631,9 @@
 HSPLjava/util/Collections$SynchronizedMap;->isEmpty()Z
 HSPLjava/util/Collections$SynchronizedMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/Collections$SynchronizedMap;->remove(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLjava/util/Collections$SynchronizedMap;->size()I
 HSPLjava/util/Collections$SynchronizedMap;->values()Ljava/util/Collection;
+HSPLjava/util/Collections$SynchronizedSet;-><init>(Ljava/util/Set;Ljava/lang/Object;)V
 HSPLjava/util/Collections$SynchronizedSet;->equals(Ljava/lang/Object;)Z
 HSPLjava/util/Collections$UnmodifiableCollection$1;->hasNext()Z
 HSPLjava/util/Collections$UnmodifiableCollection$1;->next()Ljava/lang/Object;
@@ -27531,6 +28718,7 @@
 HSPLjava/util/Comparator;->comparingInt(Ljava/util/function/ToIntFunction;)Ljava/util/Comparator;
 HSPLjava/util/Comparator;->comparingLong(Ljava/util/function/ToLongFunction;)Ljava/util/Comparator;
 HSPLjava/util/Comparator;->nullsLast(Ljava/util/Comparator;)Ljava/util/Comparator;
+HSPLjava/util/Comparator;->reversed()Ljava/util/Comparator;
 HSPLjava/util/Comparator;->thenComparing(Ljava/util/Comparator;)Ljava/util/Comparator;
 HSPLjava/util/Comparator;->thenComparing(Ljava/util/function/Function;)Ljava/util/Comparator;
 HSPLjava/util/Comparator;->thenComparingDouble(Ljava/util/function/ToDoubleFunction;)Ljava/util/Comparator;
@@ -27543,12 +28731,16 @@
 HSPLjava/util/Date;->before(Ljava/util/Date;)Z
 HSPLjava/util/Date;->clone()Ljava/lang/Object;
 HSPLjava/util/Date;->compareTo(Ljava/util/Date;)I
+HSPLjava/util/Date;->from(Ljava/time/Instant;)Ljava/util/Date;
 HSPLjava/util/Date;->getCalendarSystem(J)Lsun/util/calendar/BaseCalendar;
 HSPLjava/util/Date;->getTime()J
 HSPLjava/util/Date;->normalize()Lsun/util/calendar/BaseCalendar$Date;
 HSPLjava/util/Date;->setTime(J)V
 HSPLjava/util/Date;->toString()Ljava/lang/String;
+HSPLjava/util/DualPivotQuicksort;->doSort([CII[CII)V
 HSPLjava/util/DualPivotQuicksort;->doSort([FII[FII)V
+HSPLjava/util/DualPivotQuicksort;->sort([CIIZ)V
+HSPLjava/util/DualPivotQuicksort;->sort([CII[CII)V
 HSPLjava/util/DualPivotQuicksort;->sort([FIIZ)V
 HSPLjava/util/DualPivotQuicksort;->sort([FII[FII)V
 HSPLjava/util/DualPivotQuicksort;->sort([IIIZ)V
@@ -27562,6 +28754,7 @@
 HSPLjava/util/EnumMap$EntryIterator;->next()Ljava/lang/Object;
 HSPLjava/util/EnumMap$EntryIterator;->next()Ljava/util/Map$Entry;
 HSPLjava/util/EnumMap$EntrySet;->iterator()Ljava/util/Iterator;
+HSPLjava/util/EnumMap$EntrySet;->size()I
 HSPLjava/util/EnumMap$EnumMapIterator;->hasNext()Z
 HSPLjava/util/EnumMap$KeyIterator;->next()Ljava/lang/Enum;
 HSPLjava/util/EnumMap$KeyIterator;->next()Ljava/lang/Object;
@@ -27569,6 +28762,7 @@
 HSPLjava/util/EnumMap$KeySet;->iterator()Ljava/util/Iterator;
 HSPLjava/util/EnumMap$KeySet;->size()I
 HSPLjava/util/EnumMap;-><init>(Ljava/lang/Class;)V
+HSPLjava/util/EnumMap;-><init>(Ljava/util/Map;)V
 HSPLjava/util/EnumMap;->clear()V
 HSPLjava/util/EnumMap;->containsKey(Ljava/lang/Object;)Z
 HSPLjava/util/EnumMap;->entrySet()Ljava/util/Set;
@@ -27576,11 +28770,14 @@
 HSPLjava/util/EnumMap;->keySet()Ljava/util/Set;
 HSPLjava/util/EnumMap;->put(Ljava/lang/Enum;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/EnumMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLjava/util/EnumMap;->putAll(Ljava/util/Map;)V
 HSPLjava/util/EnumMap;->remove(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/EnumMap;->size()I
 HSPLjava/util/EnumMap;->typeCheck(Ljava/lang/Enum;)V
 HSPLjava/util/EnumSet;->allOf(Ljava/lang/Class;)Ljava/util/EnumSet;
 HSPLjava/util/EnumSet;->clone()Ljava/util/EnumSet;
+HSPLjava/util/EnumSet;->complementOf(Ljava/util/EnumSet;)Ljava/util/EnumSet;
+HSPLjava/util/EnumSet;->copyOf(Ljava/util/Collection;)Ljava/util/EnumSet;
 HSPLjava/util/EnumSet;->noneOf(Ljava/lang/Class;)Ljava/util/EnumSet;
 HSPLjava/util/EnumSet;->of(Ljava/lang/Enum;)Ljava/util/EnumSet;
 HSPLjava/util/EnumSet;->of(Ljava/lang/Enum;Ljava/lang/Enum;)Ljava/util/EnumSet;
@@ -27650,6 +28847,7 @@
 HSPLjava/util/GregorianCalendar;->computeFields(II)I
 HSPLjava/util/GregorianCalendar;->computeTime()V
 HSPLjava/util/GregorianCalendar;->getFixedDate(Lsun/util/calendar/BaseCalendar;II)J
+HSPLjava/util/GregorianCalendar;->getLeastMaximum(I)I
 HSPLjava/util/GregorianCalendar;->getMaximum(I)I
 HSPLjava/util/GregorianCalendar;->getMinimum(I)I
 HSPLjava/util/GregorianCalendar;->getTimeZone()Ljava/util/TimeZone;
@@ -27669,6 +28867,7 @@
 HSPLjava/util/HashMap$HashIterator;->remove()V
 HSPLjava/util/HashMap$HashMapSpliterator;->estimateSize()J
 HSPLjava/util/HashMap$KeyIterator;->next()Ljava/lang/Object;
+HSPLjava/util/HashMap$KeySet;->contains(Ljava/lang/Object;)Z
 HSPLjava/util/HashMap$KeySet;->iterator()Ljava/util/Iterator;
 HSPLjava/util/HashMap$KeySet;->size()I
 HSPLjava/util/HashMap$KeySpliterator;->characteristics()I
@@ -27682,6 +28881,7 @@
 HSPLjava/util/HashMap$TreeNode;->moveRootToFront([Ljava/util/HashMap$Node;Ljava/util/HashMap$TreeNode;)V
 HSPLjava/util/HashMap$TreeNode;->rotateLeft(Ljava/util/HashMap$TreeNode;Ljava/util/HashMap$TreeNode;)Ljava/util/HashMap$TreeNode;
 HSPLjava/util/HashMap$TreeNode;->rotateRight(Ljava/util/HashMap$TreeNode;Ljava/util/HashMap$TreeNode;)Ljava/util/HashMap$TreeNode;
+HSPLjava/util/HashMap$TreeNode;->split(Ljava/util/HashMap;[Ljava/util/HashMap$Node;II)V
 HSPLjava/util/HashMap$TreeNode;->treeify([Ljava/util/HashMap$Node;)V
 HSPLjava/util/HashMap$ValueIterator;->next()Ljava/lang/Object;
 HSPLjava/util/HashMap$ValueSpliterator;->characteristics()I
@@ -27723,6 +28923,7 @@
 HSPLjava/util/HashMap;->reinitialize()V
 HSPLjava/util/HashMap;->remove(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/HashMap;->removeNode(ILjava/lang/Object;Ljava/lang/Object;ZZ)Ljava/util/HashMap$Node;
+HSPLjava/util/HashMap;->replacementNode(Ljava/util/HashMap$Node;Ljava/util/HashMap$Node;)Ljava/util/HashMap$Node;
 HSPLjava/util/HashMap;->replacementTreeNode(Ljava/util/HashMap$Node;Ljava/util/HashMap$Node;)Ljava/util/HashMap$TreeNode;
 HSPLjava/util/HashMap;->resize()[Ljava/util/HashMap$Node;
 HSPLjava/util/HashMap;->size()I
@@ -27750,6 +28951,7 @@
 HSPLjava/util/Hashtable$HashtableEntry;->clone()Ljava/lang/Object;
 HSPLjava/util/Hashtable$HashtableEntry;->getKey()Ljava/lang/Object;
 HSPLjava/util/Hashtable$HashtableEntry;->getValue()Ljava/lang/Object;
+HPLjava/util/Hashtable$KeySet;->contains(Ljava/lang/Object;)Z
 HSPLjava/util/Hashtable$KeySet;->iterator()Ljava/util/Iterator;
 HSPLjava/util/Hashtable$KeySet;->size()I
 HSPLjava/util/Hashtable$ValueCollection;->iterator()Ljava/util/Iterator;
@@ -27860,6 +29062,7 @@
 HSPLjava/util/LinkedList;->clone()Ljava/lang/Object;
 HSPLjava/util/LinkedList;->contains(Ljava/lang/Object;)Z
 HSPLjava/util/LinkedList;->get(I)Ljava/lang/Object;
+HSPLjava/util/LinkedList;->getFirst()Ljava/lang/Object;
 HSPLjava/util/LinkedList;->getLast()Ljava/lang/Object;
 HSPLjava/util/LinkedList;->indexOf(Ljava/lang/Object;)I
 HSPLjava/util/LinkedList;->linkBefore(Ljava/lang/Object;Ljava/util/LinkedList$Node;)V
@@ -27871,7 +29074,9 @@
 HSPLjava/util/LinkedList;->peek()Ljava/lang/Object;
 HSPLjava/util/LinkedList;->peekLast()Ljava/lang/Object;
 HSPLjava/util/LinkedList;->poll()Ljava/lang/Object;
+HSPLjava/util/LinkedList;->pollLast()Ljava/lang/Object;
 HSPLjava/util/LinkedList;->pop()Ljava/lang/Object;
+HSPLjava/util/LinkedList;->push(Ljava/lang/Object;)V
 HSPLjava/util/LinkedList;->remove()Ljava/lang/Object;
 HSPLjava/util/LinkedList;->remove(I)Ljava/lang/Object;
 HSPLjava/util/LinkedList;->remove(Ljava/lang/Object;)Z
@@ -27879,7 +29084,7 @@
 HSPLjava/util/LinkedList;->removeLast()Ljava/lang/Object;
 HSPLjava/util/LinkedList;->set(ILjava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/LinkedList;->size()I
-PLjava/util/LinkedList;->spliterator()Ljava/util/Spliterator;
+HPLjava/util/LinkedList;->spliterator()Ljava/util/Spliterator;
 HSPLjava/util/LinkedList;->superClone()Ljava/util/LinkedList;
 HSPLjava/util/LinkedList;->toArray()[Ljava/lang/Object;
 HSPLjava/util/LinkedList;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
@@ -27929,6 +29134,7 @@
 HSPLjava/util/Locale;->toLanguageTag()Ljava/lang/String;
 HSPLjava/util/Locale;->toString()Ljava/lang/String;
 HSPLjava/util/Map;->computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;
+HSPLjava/util/Map;->forEach(Ljava/util/function/BiConsumer;)V
 HSPLjava/util/Map;->getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/Map;->putIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/MissingResourceException;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
@@ -27939,6 +29145,7 @@
 HSPLjava/util/Objects;->requireNonNull(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/Objects;->requireNonNull(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;
 HSPLjava/util/Objects;->toString(Ljava/lang/Object;)Ljava/lang/String;
+HSPLjava/util/Objects;->toString(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;
 HSPLjava/util/Observable;-><init>()V
 HSPLjava/util/Observable;->addObserver(Ljava/util/Observer;)V
 HSPLjava/util/Observable;->clearChanged()V
@@ -27968,6 +29175,7 @@
 HSPLjava/util/PriorityQueue;->offer(Ljava/lang/Object;)Z
 HSPLjava/util/PriorityQueue;->peek()Ljava/lang/Object;
 HSPLjava/util/PriorityQueue;->poll()Ljava/lang/Object;
+HSPLjava/util/PriorityQueue;->remove(Ljava/lang/Object;)Z
 HSPLjava/util/PriorityQueue;->removeAt(I)Ljava/lang/Object;
 HSPLjava/util/PriorityQueue;->siftDownComparable(ILjava/lang/Object;)V
 HSPLjava/util/PriorityQueue;->siftDownUsingComparator(ILjava/lang/Object;)V
@@ -28005,6 +29213,7 @@
 HSPLjava/util/RegularEnumSet;->add(Ljava/lang/Enum;)Z
 HSPLjava/util/RegularEnumSet;->add(Ljava/lang/Object;)Z
 HSPLjava/util/RegularEnumSet;->addAll()V
+HSPLjava/util/RegularEnumSet;->complement()V
 HSPLjava/util/RegularEnumSet;->contains(Ljava/lang/Object;)Z
 HSPLjava/util/RegularEnumSet;->isEmpty()Z
 HSPLjava/util/RegularEnumSet;->iterator()Ljava/util/Iterator;
@@ -28046,7 +29255,7 @@
 HSPLjava/util/Spliterators$ArraySpliterator;->forEachRemaining(Ljava/util/function/Consumer;)V
 HSPLjava/util/Spliterators$ArraySpliterator;->tryAdvance(Ljava/util/function/Consumer;)Z
 HSPLjava/util/Spliterators$EmptySpliterator$OfRef;->forEachRemaining(Ljava/util/function/Consumer;)V
-PLjava/util/Spliterators$EmptySpliterator$OfRef;->tryAdvance(Ljava/util/function/Consumer;)Z
+HPLjava/util/Spliterators$EmptySpliterator$OfRef;->tryAdvance(Ljava/util/function/Consumer;)Z
 HSPLjava/util/Spliterators$EmptySpliterator;->characteristics()I
 HSPLjava/util/Spliterators$EmptySpliterator;->estimateSize()J
 HSPLjava/util/Spliterators$IntArraySpliterator;->characteristics()I
@@ -28082,6 +29291,7 @@
 HSPLjava/util/SubList;->size()I
 HSPLjava/util/TaskQueue;->add(Ljava/util/TimerTask;)V
 HSPLjava/util/TaskQueue;->clear()V
+HSPLjava/util/TaskQueue;->fixDown(I)V
 HSPLjava/util/TaskQueue;->fixUp(I)V
 HSPLjava/util/TaskQueue;->getMin()Ljava/util/TimerTask;
 HSPLjava/util/TaskQueue;->isEmpty()Z
@@ -28117,7 +29327,9 @@
 HSPLjava/util/TimerThread;->mainLoop()V
 HSPLjava/util/TimerThread;->run()V
 HSPLjava/util/TreeMap$AscendingSubMap$AscendingEntrySetView;->iterator()Ljava/util/Iterator;
+HSPLjava/util/TreeMap$AscendingSubMap;->comparator()Ljava/util/Comparator;
 HSPLjava/util/TreeMap$AscendingSubMap;->entrySet()Ljava/util/Set;
+HSPLjava/util/TreeMap$AscendingSubMap;->headMap(Ljava/lang/Object;Z)Ljava/util/NavigableMap;
 HSPLjava/util/TreeMap$AscendingSubMap;->keyIterator()Ljava/util/Iterator;
 HSPLjava/util/TreeMap$AscendingSubMap;->subHighest()Ljava/util/TreeMap$TreeMapEntry;
 HSPLjava/util/TreeMap$EntryIterator;->next()Ljava/lang/Object;
@@ -28159,13 +29371,16 @@
 HSPLjava/util/TreeMap;->comparator()Ljava/util/Comparator;
 HSPLjava/util/TreeMap;->containsKey(Ljava/lang/Object;)Z
 HSPLjava/util/TreeMap;->deleteEntry(Ljava/util/TreeMap$TreeMapEntry;)V
+HSPLjava/util/TreeMap;->descendingMap()Ljava/util/NavigableMap;
 HSPLjava/util/TreeMap;->entrySet()Ljava/util/Set;
 HSPLjava/util/TreeMap;->firstKey()Ljava/lang/Object;
 HSPLjava/util/TreeMap;->fixAfterDeletion(Ljava/util/TreeMap$TreeMapEntry;)V
 HSPLjava/util/TreeMap;->fixAfterInsertion(Ljava/util/TreeMap$TreeMapEntry;)V
+HSPLjava/util/TreeMap;->floorKey(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/TreeMap;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/TreeMap;->getCeilingEntry(Ljava/lang/Object;)Ljava/util/TreeMap$TreeMapEntry;
 HSPLjava/util/TreeMap;->getEntry(Ljava/lang/Object;)Ljava/util/TreeMap$TreeMapEntry;
+HSPLjava/util/TreeMap;->getFloorEntry(Ljava/lang/Object;)Ljava/util/TreeMap$TreeMapEntry;
 HSPLjava/util/TreeMap;->getHigherEntry(Ljava/lang/Object;)Ljava/util/TreeMap$TreeMapEntry;
 HSPLjava/util/TreeMap;->getLowerEntry(Ljava/lang/Object;)Ljava/util/TreeMap$TreeMapEntry;
 HSPLjava/util/TreeMap;->headMap(Ljava/lang/Object;Z)Ljava/util/NavigableMap;
@@ -28216,6 +29431,7 @@
 HSPLjava/util/Vector$Itr;->checkForComodification()V
 HSPLjava/util/Vector$Itr;->hasNext()Z
 HSPLjava/util/Vector$Itr;->next()Ljava/lang/Object;
+HPLjava/util/Vector$Itr;->remove()V
 HSPLjava/util/Vector;-><init>()V
 HSPLjava/util/Vector;-><init>(II)V
 HSPLjava/util/Vector;->add(Ljava/lang/Object;)Z
@@ -28232,6 +29448,7 @@
 HSPLjava/util/Vector;->indexOf(Ljava/lang/Object;I)I
 HSPLjava/util/Vector;->isEmpty()Z
 HSPLjava/util/Vector;->iterator()Ljava/util/Iterator;
+HSPLjava/util/Vector;->remove(I)Ljava/lang/Object;
 HSPLjava/util/Vector;->removeAllElements()V
 HSPLjava/util/Vector;->removeElement(Ljava/lang/Object;)Z
 HSPLjava/util/Vector;->removeElementAt(I)V
@@ -28269,6 +29486,7 @@
 HSPLjava/util/WeakHashMap;->transfer([Ljava/util/WeakHashMap$Entry;[Ljava/util/WeakHashMap$Entry;)V
 HSPLjava/util/WeakHashMap;->values()Ljava/util/Collection;
 HSPLjava/util/concurrent/AbstractExecutorService;-><init>()V
+HSPLjava/util/concurrent/AbstractExecutorService;->invokeAll(Ljava/util/Collection;JLjava/util/concurrent/TimeUnit;)Ljava/util/List;
 HSPLjava/util/concurrent/AbstractExecutorService;->newTaskFor(Ljava/lang/Runnable;Ljava/lang/Object;)Ljava/util/concurrent/RunnableFuture;
 HSPLjava/util/concurrent/AbstractExecutorService;->newTaskFor(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/RunnableFuture;
 HSPLjava/util/concurrent/AbstractExecutorService;->submit(Ljava/lang/Runnable;)Ljava/util/concurrent/Future;
@@ -28285,17 +29503,23 @@
 HSPLjava/util/concurrent/ArrayBlockingQueue;->take()Ljava/lang/Object;
 HSPLjava/util/concurrent/CancellationException;-><init>(Ljava/lang/String;)V
 HSPLjava/util/concurrent/CompletableFuture$AltResult;-><init>(Ljava/lang/Throwable;)V
+HSPLjava/util/concurrent/CompletableFuture$Completion;->run()V
 HSPLjava/util/concurrent/CompletableFuture$Signaller;->block()Z
 HSPLjava/util/concurrent/CompletableFuture$Signaller;->isReleasable()Z
 HSPLjava/util/concurrent/CompletableFuture$Signaller;->tryFire(I)Ljava/util/concurrent/CompletableFuture;
 HSPLjava/util/concurrent/CompletableFuture;-><init>()V
 HSPLjava/util/concurrent/CompletableFuture;->complete(Ljava/lang/Object;)Z
+HSPLjava/util/concurrent/CompletableFuture;->completedFuture(Ljava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
 HSPLjava/util/concurrent/CompletableFuture;->get()Ljava/lang/Object;
 HSPLjava/util/concurrent/CompletableFuture;->get(JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;
 HSPLjava/util/concurrent/CompletableFuture;->isDone()Z
+HSPLjava/util/concurrent/CompletableFuture;->newIncompleteFuture()Ljava/util/concurrent/CompletableFuture;
 HSPLjava/util/concurrent/CompletableFuture;->postComplete()V
+HSPLjava/util/concurrent/CompletableFuture;->postFire(Ljava/util/concurrent/CompletableFuture;I)Ljava/util/concurrent/CompletableFuture;
 HSPLjava/util/concurrent/CompletableFuture;->reportGet(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/concurrent/CompletableFuture;->timedGet(J)Ljava/lang/Object;
+HSPLjava/util/concurrent/CompletableFuture;->uniWhenComplete(Ljava/util/concurrent/CompletableFuture;Ljava/util/function/BiConsumer;Ljava/util/concurrent/CompletableFuture$UniWhenComplete;)Z
+HSPLjava/util/concurrent/CompletableFuture;->uniWhenCompleteStage(Ljava/util/concurrent/Executor;Ljava/util/function/BiConsumer;)Ljava/util/concurrent/CompletableFuture;
 HSPLjava/util/concurrent/CompletableFuture;->waitingGet(Z)Ljava/lang/Object;
 HSPLjava/util/concurrent/ConcurrentHashMap$BaseIterator;->hasNext()Z
 HSPLjava/util/concurrent/ConcurrentHashMap$BaseIterator;->remove()V
@@ -28332,6 +29556,7 @@
 HSPLjava/util/concurrent/ConcurrentHashMap;->computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;
 HSPLjava/util/concurrent/ConcurrentHashMap;->containsKey(Ljava/lang/Object;)Z
 HSPLjava/util/concurrent/ConcurrentHashMap;->entrySet()Ljava/util/Set;
+HSPLjava/util/concurrent/ConcurrentHashMap;->fullAddCount(JZ)V
 HSPLjava/util/concurrent/ConcurrentHashMap;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/concurrent/ConcurrentHashMap;->initTable()[Ljava/util/concurrent/ConcurrentHashMap$Node;
 HSPLjava/util/concurrent/ConcurrentHashMap;->isEmpty()Z
@@ -28364,6 +29589,7 @@
 HSPLjava/util/concurrent/ConcurrentLinkedQueue;->isEmpty()Z
 HSPLjava/util/concurrent/ConcurrentLinkedQueue;->iterator()Ljava/util/Iterator;
 HSPLjava/util/concurrent/ConcurrentLinkedQueue;->offer(Ljava/lang/Object;)Z
+HSPLjava/util/concurrent/ConcurrentLinkedQueue;->peek()Ljava/lang/Object;
 HSPLjava/util/concurrent/ConcurrentLinkedQueue;->poll()Ljava/lang/Object;
 HSPLjava/util/concurrent/ConcurrentLinkedQueue;->remove(Ljava/lang/Object;)Z
 HSPLjava/util/concurrent/ConcurrentLinkedQueue;->size()I
@@ -28373,6 +29599,7 @@
 HSPLjava/util/concurrent/ConcurrentSkipListMap$Values;->iterator()Ljava/util/Iterator;
 HSPLjava/util/concurrent/ConcurrentSkipListMap;-><init>()V
 HSPLjava/util/concurrent/ConcurrentSkipListMap;-><init>(Ljava/util/Comparator;)V
+HSPLjava/util/concurrent/ConcurrentSkipListMap;->clear()V
 HSPLjava/util/concurrent/ConcurrentSkipListMap;->doGet(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/concurrent/ConcurrentSkipListMap;->doPut(Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;
 HSPLjava/util/concurrent/ConcurrentSkipListMap;->doRemove(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
@@ -28422,6 +29649,7 @@
 HSPLjava/util/concurrent/Executors$DelegatedExecutorService;->shutdown()V
 HSPLjava/util/concurrent/Executors$DelegatedExecutorService;->shutdownNow()Ljava/util/List;
 HSPLjava/util/concurrent/Executors$DelegatedExecutorService;->submit(Ljava/lang/Runnable;)Ljava/util/concurrent/Future;
+HSPLjava/util/concurrent/Executors$DelegatedExecutorService;->submit(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;
 HSPLjava/util/concurrent/Executors$DelegatedScheduledExecutorService;->schedule(Ljava/lang/Runnable;JLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture;
 HSPLjava/util/concurrent/Executors$FinalizableDelegatedExecutorService;->finalize()V
 HSPLjava/util/concurrent/Executors$RunnableAdapter;->call()Ljava/lang/Object;
@@ -28476,15 +29704,19 @@
 HSPLjava/util/concurrent/LinkedBlockingDeque;->poll(JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;
 HSPLjava/util/concurrent/LinkedBlockingDeque;->pollFirst()Ljava/lang/Object;
 HSPLjava/util/concurrent/LinkedBlockingDeque;->pollFirst(JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;
-PLjava/util/concurrent/LinkedBlockingDeque;->pop()Ljava/lang/Object;
-PLjava/util/concurrent/LinkedBlockingDeque;->remainingCapacity()I
+HPLjava/util/concurrent/LinkedBlockingDeque;->pop()Ljava/lang/Object;
+HPLjava/util/concurrent/LinkedBlockingDeque;->remainingCapacity()I
 HSPLjava/util/concurrent/LinkedBlockingDeque;->removeFirst()Ljava/lang/Object;
 HSPLjava/util/concurrent/LinkedBlockingDeque;->size()I
+HSPLjava/util/concurrent/LinkedBlockingDeque;->take()Ljava/lang/Object;
+HSPLjava/util/concurrent/LinkedBlockingDeque;->takeFirst()Ljava/lang/Object;
 HSPLjava/util/concurrent/LinkedBlockingDeque;->unlinkFirst()Ljava/lang/Object;
 HSPLjava/util/concurrent/LinkedBlockingQueue;-><init>()V
 HSPLjava/util/concurrent/LinkedBlockingQueue;-><init>(I)V
 HSPLjava/util/concurrent/LinkedBlockingQueue;->drainTo(Ljava/util/Collection;)I
 HSPLjava/util/concurrent/LinkedBlockingQueue;->drainTo(Ljava/util/Collection;I)I
+HSPLjava/util/concurrent/LinkedBlockingQueue;->fullyLock()V
+HSPLjava/util/concurrent/LinkedBlockingQueue;->fullyUnlock()V
 HSPLjava/util/concurrent/LinkedBlockingQueue;->offer(Ljava/lang/Object;)Z
 HSPLjava/util/concurrent/LinkedBlockingQueue;->poll()Ljava/lang/Object;
 HSPLjava/util/concurrent/LinkedBlockingQueue;->poll(JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;
@@ -28503,11 +29735,13 @@
 HSPLjava/util/concurrent/PriorityBlockingQueue;->siftDownComparable(ILjava/lang/Object;[Ljava/lang/Object;I)V
 HSPLjava/util/concurrent/PriorityBlockingQueue;->size()I
 HSPLjava/util/concurrent/PriorityBlockingQueue;->take()Ljava/lang/Object;
+HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue$Itr;->hasNext()Z
 HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->add(Ljava/lang/Object;)Z
 HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->add(Ljava/lang/Runnable;)Z
 HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->drainTo(Ljava/util/Collection;)I
 HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->indexOf(Ljava/lang/Object;)I
 HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->isEmpty()Z
+HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->iterator()Ljava/util/Iterator;
 HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->offer(Ljava/lang/Runnable;)Z
 HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->poll(JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;
 HSPLjava/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue;->poll(JLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/RunnableScheduledFuture;
@@ -28596,6 +29830,7 @@
 HSPLjava/util/concurrent/ThreadPoolExecutor;->onShutdown()V
 HSPLjava/util/concurrent/ThreadPoolExecutor;->prestartAllCoreThreads()I
 HSPLjava/util/concurrent/ThreadPoolExecutor;->processWorkerExit(Ljava/util/concurrent/ThreadPoolExecutor$Worker;Z)V
+HSPLjava/util/concurrent/ThreadPoolExecutor;->purge()V
 HSPLjava/util/concurrent/ThreadPoolExecutor;->remove(Ljava/lang/Runnable;)Z
 HSPLjava/util/concurrent/ThreadPoolExecutor;->runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V
 HSPLjava/util/concurrent/ThreadPoolExecutor;->setKeepAliveTime(JLjava/util/concurrent/TimeUnit;)V
@@ -28634,6 +29869,7 @@
 HSPLjava/util/concurrent/TimeUnit$6;->toMinutes(J)J
 HSPLjava/util/concurrent/TimeUnit$6;->toNanos(J)J
 HSPLjava/util/concurrent/TimeUnit$6;->toSeconds(J)J
+HSPLjava/util/concurrent/TimeUnit$7;->toHours(J)J
 HSPLjava/util/concurrent/TimeUnit$7;->toMillis(J)J
 HSPLjava/util/concurrent/TimeUnit$7;->toMinutes(J)J
 HSPLjava/util/concurrent/TimeUnit$7;->toNanos(J)J
@@ -28670,8 +29906,10 @@
 HSPLjava/util/concurrent/atomic/AtomicLong;-><init>(J)V
 HSPLjava/util/concurrent/atomic/AtomicLong;->addAndGet(J)J
 HSPLjava/util/concurrent/atomic/AtomicLong;->compareAndSet(JJ)Z
+HSPLjava/util/concurrent/atomic/AtomicLong;->doubleValue()D
 HSPLjava/util/concurrent/atomic/AtomicLong;->get()J
 HSPLjava/util/concurrent/atomic/AtomicLong;->getAndAdd(J)J
+HSPLjava/util/concurrent/atomic/AtomicLong;->getAndDecrement()J
 HSPLjava/util/concurrent/atomic/AtomicLong;->getAndIncrement()J
 HSPLjava/util/concurrent/atomic/AtomicLong;->getAndSet(J)J
 HSPLjava/util/concurrent/atomic/AtomicLong;->incrementAndGet()J
@@ -28724,6 +29962,7 @@
 HSPLjava/util/concurrent/locks/ReentrantLock$Sync;->nonfairTryAcquire(I)Z
 HSPLjava/util/concurrent/locks/ReentrantLock$Sync;->tryRelease(I)Z
 HSPLjava/util/concurrent/locks/ReentrantLock;-><init>()V
+HSPLjava/util/concurrent/locks/ReentrantLock;-><init>(Z)V
 HSPLjava/util/concurrent/locks/ReentrantLock;->isHeldByCurrentThread()Z
 HSPLjava/util/concurrent/locks/ReentrantLock;->lock()V
 HSPLjava/util/concurrent/locks/ReentrantLock;->lockInterruptibly()V
@@ -28759,7 +29998,7 @@
 HSPLjava/util/function/DoubleUnaryOperator;->andThen(Ljava/util/function/DoubleUnaryOperator;)Ljava/util/function/DoubleUnaryOperator;
 HSPLjava/util/function/DoubleUnaryOperator;->identity()Ljava/util/function/DoubleUnaryOperator;
 HSPLjava/util/function/Function;->identity()Ljava/util/function/Function;
-PLjava/util/function/Predicate;->and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
+HPLjava/util/function/Predicate;->and(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
 HSPLjava/util/function/Predicate;->or(Ljava/util/function/Predicate;)Ljava/util/function/Predicate;
 HSPLjava/util/jar/Attributes$Name;-><init>(Ljava/lang/String;)V
 HSPLjava/util/jar/Attributes$Name;->equals(Ljava/lang/Object;)Z
@@ -28904,6 +30143,7 @@
 HSPLjava/util/regex/Matcher;->hitEnd()Z
 HSPLjava/util/regex/Matcher;->lookingAt()Z
 HSPLjava/util/regex/Matcher;->matches()Z
+HSPLjava/util/regex/Matcher;->region(II)Ljava/util/regex/Matcher;
 HSPLjava/util/regex/Matcher;->replaceAll(Ljava/lang/String;)Ljava/lang/String;
 HSPLjava/util/regex/Matcher;->replaceFirst(Ljava/lang/String;)Ljava/lang/String;
 HSPLjava/util/regex/Matcher;->reset(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;
@@ -29078,6 +30318,7 @@
 HSPLjava/util/stream/ReduceOps$8ReducingSink;->get()Ljava/lang/Long;
 HSPLjava/util/stream/ReduceOps$8ReducingSink;->get()Ljava/lang/Object;
 HSPLjava/util/stream/ReduceOps$Box;->get()Ljava/lang/Object;
+HSPLjava/util/stream/ReduceOps$ReduceOp;-><init>(Ljava/util/stream/StreamShape;)V
 HSPLjava/util/stream/ReduceOps$ReduceOp;->evaluateSequential(Ljava/util/stream/PipelineHelper;Ljava/util/Spliterator;)Ljava/lang/Object;
 HSPLjava/util/stream/ReferencePipeline$2$1;->accept(Ljava/lang/Object;)V
 HSPLjava/util/stream/ReferencePipeline$2$1;->begin(J)V
@@ -29108,6 +30349,7 @@
 HSPLjava/util/stream/ReferencePipeline;->map(Ljava/util/function/Function;)Ljava/util/stream/Stream;
 HSPLjava/util/stream/ReferencePipeline;->mapToInt(Ljava/util/function/ToIntFunction;)Ljava/util/stream/IntStream;
 HSPLjava/util/stream/ReferencePipeline;->max(Ljava/util/Comparator;)Ljava/util/Optional;
+HSPLjava/util/stream/ReferencePipeline;->noneMatch(Ljava/util/function/Predicate;)Z
 HSPLjava/util/stream/ReferencePipeline;->sorted(Ljava/util/Comparator;)Ljava/util/stream/Stream;
 HSPLjava/util/stream/ReferencePipeline;->toArray(Ljava/util/function/IntFunction;)[Ljava/lang/Object;
 HSPLjava/util/stream/Sink$ChainedInt;->begin(J)V
@@ -29142,7 +30384,7 @@
 HSPLjava/util/stream/SpinedBuffer;->count()J
 HSPLjava/util/stream/SpinedBuffer;->ensureCapacity(J)V
 HSPLjava/util/stream/Stream;->concat(Ljava/util/stream/Stream;Ljava/util/stream/Stream;)Ljava/util/stream/Stream;
-PLjava/util/stream/Stream;->empty()Ljava/util/stream/Stream;
+HPLjava/util/stream/Stream;->empty()Ljava/util/stream/Stream;
 HSPLjava/util/stream/Stream;->generate(Ljava/util/function/Supplier;)Ljava/util/stream/Stream;
 HSPLjava/util/stream/Stream;->of([Ljava/lang/Object;)Ljava/util/stream/Stream;
 HSPLjava/util/stream/StreamOpFlag$MaskBuilder;->build()Ljava/util/Map;
@@ -29217,6 +30459,7 @@
 HSPLjava/util/zip/Inflater;->needsInput()Z
 HSPLjava/util/zip/Inflater;->setInput([BII)V
 HSPLjava/util/zip/InflaterInputStream;-><init>(Ljava/io/InputStream;Ljava/util/zip/Inflater;I)V
+HSPLjava/util/zip/InflaterInputStream;->available()I
 HSPLjava/util/zip/InflaterInputStream;->close()V
 HSPLjava/util/zip/InflaterInputStream;->fill()V
 HSPLjava/util/zip/InflaterInputStream;->read()I
@@ -29263,6 +30506,7 @@
 HSPLjavax/crypto/Cipher;->createCipher(Ljava/lang/String;Ljava/security/Provider;)Ljavax/crypto/Cipher;
 HSPLjavax/crypto/Cipher;->doFinal([B)[B
 HSPLjavax/crypto/Cipher;->doFinal([BII)[B
+HSPLjavax/crypto/Cipher;->doFinal([BII[BI)I
 HSPLjavax/crypto/Cipher;->getIV()[B
 HSPLjavax/crypto/Cipher;->getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;
 HSPLjavax/crypto/Cipher;->init(ILjava/security/Key;)V
@@ -29282,10 +30526,13 @@
 HSPLjavax/crypto/Mac;->chooseProvider(Ljava/security/Key;Ljava/security/spec/AlgorithmParameterSpec;)V
 HSPLjavax/crypto/Mac;->doFinal()[B
 HSPLjavax/crypto/Mac;->doFinal([B)[B
+HSPLjavax/crypto/Mac;->doFinal([BI)V
 HSPLjavax/crypto/Mac;->getInstance(Ljava/lang/String;)Ljavax/crypto/Mac;
+HSPLjavax/crypto/Mac;->getMacLength()I
 HSPLjavax/crypto/Mac;->init(Ljava/security/Key;)V
 HSPLjavax/crypto/Mac;->update(B)V
 HSPLjavax/crypto/Mac;->update([B)V
+HSPLjavax/crypto/Mac;->update([BII)V
 HSPLjavax/crypto/MacSpi;-><init>()V
 HSPLjavax/crypto/spec/GCMParameterSpec;-><init>(I[B)V
 HSPLjavax/crypto/spec/GCMParameterSpec;->getIV()[B
@@ -29299,8 +30546,10 @@
 HSPLjavax/crypto/spec/SecretKeySpec;-><init>([BLjava/lang/String;)V
 HSPLjavax/crypto/spec/SecretKeySpec;->getEncoded()[B
 HSPLjavax/crypto/spec/SecretKeySpec;->getFormat()Ljava/lang/String;
+HSPLjavax/microedition/khronos/egl/EGLContext;->getEGL()Ljavax/microedition/khronos/egl/EGL;
 HSPLjavax/net/DefaultSocketFactory;->createSocket()Ljava/net/Socket;
 HSPLjavax/net/DefaultSocketFactory;->createSocket(Ljava/net/InetAddress;I)Ljava/net/Socket;
+HSPLjavax/net/SocketFactory;-><init>()V
 HSPLjavax/net/SocketFactory;->getDefault()Ljavax/net/SocketFactory;
 HSPLjavax/net/ssl/ExtendedSSLSession;-><init>()V
 HSPLjavax/net/ssl/HttpsURLConnection;-><init>(Ljava/net/URL;)V
@@ -29355,6 +30604,7 @@
 HSPLjavax/security/auth/x500/X500Principal;-><init>([B)V
 HSPLjavax/security/auth/x500/X500Principal;->equals(Ljava/lang/Object;)Z
 HSPLjavax/security/auth/x500/X500Principal;->getEncoded()[B
+HSPLjavax/security/auth/x500/X500Principal;->getName(Ljava/lang/String;)Ljava/lang/String;
 HSPLjavax/security/auth/x500/X500Principal;->hashCode()I
 HSPLjavax/security/cert/X509Certificate$1;-><init>()V
 HSPLjavax/security/cert/X509Certificate$1;->run()Ljava/lang/Object;
@@ -29366,6 +30616,7 @@
 HSPLjavax/xml/parsers/DocumentBuilderFactory;->isNamespaceAware()Z
 HSPLjavax/xml/parsers/DocumentBuilderFactory;->isValidating()Z
 HSPLjavax/xml/parsers/DocumentBuilderFactory;->newInstance()Ljavax/xml/parsers/DocumentBuilderFactory;
+HSPLjavax/xml/parsers/SAXParserFactory;->newInstance()Ljavax/xml/parsers/SAXParserFactory;
 HSPLlibcore/icu/DateIntervalFormat;->formatDateRange(JJILjava/lang/String;)Ljava/lang/String;
 HSPLlibcore/icu/DateIntervalFormat;->formatDateRange(Landroid/icu/util/ULocale;Landroid/icu/util/TimeZone;JJI)Ljava/lang/String;
 HSPLlibcore/icu/DateIntervalFormat;->getFormatter(Ljava/lang/String;Landroid/icu/util/ULocale;Landroid/icu/util/TimeZone;)Landroid/icu/text/DateIntervalFormat;
@@ -29383,6 +30634,7 @@
 HSPLlibcore/icu/LocaleData;->initLocaleData(Ljava/util/Locale;)Llibcore/icu/LocaleData;
 HSPLlibcore/icu/LocaleData;->initializePatternSeparator(Llibcore/icu/LocaleData;Ljava/util/Locale;)V
 HSPLlibcore/icu/LocaleData;->mapInvalidAndNullLocales(Ljava/util/Locale;)Ljava/util/Locale;
+HSPLlibcore/icu/RelativeDateTimeFormatter$FormatterCache;-><init>()V
 HSPLlibcore/icu/TimeZoneNames$1;-><init>()V
 HSPLlibcore/icu/TimeZoneNames$ZoneStringsCache;-><init>()V
 HSPLlibcore/internal/StringPool;-><init>()V
@@ -29396,8 +30648,9 @@
 HSPLlibcore/io/BlockGuardOs;->connect(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V
 HSPLlibcore/io/BlockGuardOs;->fchmod(Ljava/io/FileDescriptor;I)V
 HSPLlibcore/io/BlockGuardOs;->fchown(Ljava/io/FileDescriptor;II)V
+HSPLlibcore/io/BlockGuardOs;->fdatasync(Ljava/io/FileDescriptor;)V
 HSPLlibcore/io/BlockGuardOs;->fstat(Ljava/io/FileDescriptor;)Landroid/system/StructStat;
-PLlibcore/io/BlockGuardOs;->fsync(Ljava/io/FileDescriptor;)V
+HPLlibcore/io/BlockGuardOs;->fsync(Ljava/io/FileDescriptor;)V
 HSPLlibcore/io/BlockGuardOs;->ftruncate(Ljava/io/FileDescriptor;J)V
 HSPLlibcore/io/BlockGuardOs;->getxattr(Ljava/lang/String;Ljava/lang/String;)[B
 HSPLlibcore/io/BlockGuardOs;->lseek(Ljava/io/FileDescriptor;JI)J
@@ -29433,7 +30686,7 @@
 HSPLlibcore/io/ForwardingOs;->chmod(Ljava/lang/String;I)V
 HSPLlibcore/io/ForwardingOs;->close(Ljava/io/FileDescriptor;)V
 HSPLlibcore/io/ForwardingOs;->connect(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V
-PLlibcore/io/ForwardingOs;->dup(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;
+HPLlibcore/io/ForwardingOs;->dup(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;
 HSPLlibcore/io/ForwardingOs;->dup2(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;
 HSPLlibcore/io/ForwardingOs;->fcntlInt(Ljava/io/FileDescriptor;II)I
 HSPLlibcore/io/ForwardingOs;->fcntlVoid(Ljava/io/FileDescriptor;I)I
@@ -29485,6 +30738,7 @@
 HSPLlibcore/io/IoBridge;->closeAndSignalBlockedThreads(Ljava/io/FileDescriptor;)V
 HSPLlibcore/io/IoBridge;->connect(Ljava/io/FileDescriptor;Ljava/net/InetAddress;II)V
 HSPLlibcore/io/IoBridge;->connectErrno(Ljava/io/FileDescriptor;Ljava/net/InetAddress;II)V
+HSPLlibcore/io/IoBridge;->createMessageForException(Ljava/io/FileDescriptor;Ljava/net/InetAddress;IILjava/lang/Exception;)Ljava/lang/String;
 HSPLlibcore/io/IoBridge;->getLocalInetSocketAddress(Ljava/io/FileDescriptor;)Ljava/net/InetSocketAddress;
 HSPLlibcore/io/IoBridge;->getSocketOption(Ljava/io/FileDescriptor;I)Ljava/lang/Object;
 HSPLlibcore/io/IoBridge;->getSocketOptionErrno(Ljava/io/FileDescriptor;I)Ljava/lang/Object;
@@ -29545,7 +30799,7 @@
 HSPLlibcore/io/NioBufferIterator;->skip(I)V
 HSPLlibcore/io/Os;->compareAndSetDefault(Llibcore/io/Os;Llibcore/io/Os;)Z
 HSPLlibcore/io/Streams;->readFully(Ljava/io/InputStream;)[B
-PLlibcore/io/Streams;->readFully(Ljava/io/Reader;)Ljava/lang/String;
+HPLlibcore/io/Streams;->readFully(Ljava/io/Reader;)Ljava/lang/String;
 HSPLlibcore/net/InetAddressUtils;->parseNumericAddress(Ljava/lang/String;)Ljava/net/InetAddress;
 HSPLlibcore/net/InetAddressUtils;->parseNumericAddressNoThrow(Ljava/lang/String;)Ljava/net/InetAddress;
 HSPLlibcore/net/InetAddressUtils;->parseNumericAddressNoThrowStripOptionalBrackets(Ljava/lang/String;)Ljava/net/InetAddress;
@@ -29632,7 +30886,7 @@
 HSPLlibcore/util/HexEncoding;->decode([CZ)[B
 HSPLlibcore/util/HexEncoding;->encode([BII)[C
 HSPLlibcore/util/HexEncoding;->encodeToString([B)Ljava/lang/String;
-PLlibcore/util/HexEncoding;->toDigit([CI)I
+HPLlibcore/util/HexEncoding;->toDigit([CI)I
 HSPLlibcore/util/NativeAllocationRegistry$CleanerRunner;->run()V
 HSPLlibcore/util/NativeAllocationRegistry$CleanerThunk;->run()V
 HSPLlibcore/util/NativeAllocationRegistry;-><init>(Ljava/lang/ClassLoader;JJ)V
@@ -29736,6 +30990,8 @@
 HSPLorg/apache/http/conn/ssl/AllowAllHostnameVerifier;-><init>()V
 HSPLorg/apache/http/conn/ssl/BrowserCompatHostnameVerifier;-><init>()V
 HSPLorg/apache/http/conn/ssl/StrictHostnameVerifier;-><init>()V
+HSPLorg/apache/http/params/HttpConnectionParams;->setConnectionTimeout(Lorg/apache/http/params/HttpParams;I)V
+HSPLorg/apache/http/params/HttpConnectionParams;->setSoTimeout(Lorg/apache/http/params/HttpParams;I)V
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->addAttribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->clear()V
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->ensureCapacity(I)V
@@ -29753,7 +31009,9 @@
 HSPLorg/ccil/cowan/tagsoup/Element;->canContain(Lorg/ccil/cowan/tagsoup/Element;)Z
 HSPLorg/ccil/cowan/tagsoup/Element;->clean()V
 HSPLorg/ccil/cowan/tagsoup/Element;->flags()I
+HSPLorg/ccil/cowan/tagsoup/Element;->isPreclosed()Z
 HSPLorg/ccil/cowan/tagsoup/Element;->localName()Ljava/lang/String;
+HSPLorg/ccil/cowan/tagsoup/Element;->model()I
 HSPLorg/ccil/cowan/tagsoup/Element;->name()Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/Element;->namespace()Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/Element;->next()Lorg/ccil/cowan/tagsoup/Element;
@@ -29765,6 +31023,7 @@
 HSPLorg/ccil/cowan/tagsoup/ElementType;->flags()I
 HSPLorg/ccil/cowan/tagsoup/ElementType;->localName()Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/ElementType;->localName(Ljava/lang/String;)Ljava/lang/String;
+HSPLorg/ccil/cowan/tagsoup/ElementType;->model()I
 HSPLorg/ccil/cowan/tagsoup/ElementType;->name()Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/ElementType;->namespace()Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/ElementType;->namespace(Ljava/lang/String;Z)Ljava/lang/String;
@@ -29781,9 +31040,14 @@
 HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V
 HSPLorg/ccil/cowan/tagsoup/Parser;->entity([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->eof([CII)V
+HSPLorg/ccil/cowan/tagsoup/Parser;->etag([CII)V
+HSPLorg/ccil/cowan/tagsoup/Parser;->etag_basic([CII)V
+HSPLorg/ccil/cowan/tagsoup/Parser;->etag_cdata([CII)Z
 HSPLorg/ccil/cowan/tagsoup/Parser;->getEntity()I
 HSPLorg/ccil/cowan/tagsoup/Parser;->getReader(Lorg/xml/sax/InputSource;)Ljava/io/Reader;
+HSPLorg/ccil/cowan/tagsoup/Parser;->gi([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->lookupEntity([CII)I
+HSPLorg/ccil/cowan/tagsoup/Parser;->makeName([CII)Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->pcdata([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V
@@ -29793,6 +31057,7 @@
 HSPLorg/ccil/cowan/tagsoup/Parser;->setContentHandler(Lorg/xml/sax/ContentHandler;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->setProperty(Ljava/lang/String;Ljava/lang/Object;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V
+HSPLorg/ccil/cowan/tagsoup/Parser;->stagc([CII)V
 HSPLorg/ccil/cowan/tagsoup/Schema;-><init>()V
 HSPLorg/ccil/cowan/tagsoup/Schema;->attribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLorg/ccil/cowan/tagsoup/Schema;->elementType(Ljava/lang/String;III)V
@@ -29816,6 +31081,7 @@
 HSPLorg/json/JSONArray;->getString(I)Ljava/lang/String;
 HSPLorg/json/JSONArray;->length()I
 HSPLorg/json/JSONArray;->opt(I)Ljava/lang/Object;
+HSPLorg/json/JSONArray;->optJSONObject(I)Lorg/json/JSONObject;
 HSPLorg/json/JSONArray;->put(J)Lorg/json/JSONArray;
 HSPLorg/json/JSONArray;->put(Ljava/lang/Object;)Lorg/json/JSONArray;
 HSPLorg/json/JSONArray;->toString()Ljava/lang/String;
@@ -29833,9 +31099,13 @@
 HSPLorg/json/JSONObject;->getLong(Ljava/lang/String;)J
 HSPLorg/json/JSONObject;->getString(Ljava/lang/String;)Ljava/lang/String;
 HSPLorg/json/JSONObject;->has(Ljava/lang/String;)Z
+HSPLorg/json/JSONObject;->keys()Ljava/util/Iterator;
 HSPLorg/json/JSONObject;->numberToString(Ljava/lang/Number;)Ljava/lang/String;
 HSPLorg/json/JSONObject;->opt(Ljava/lang/String;)Ljava/lang/Object;
+HSPLorg/json/JSONObject;->optBoolean(Ljava/lang/String;)Z
 HSPLorg/json/JSONObject;->optBoolean(Ljava/lang/String;Z)Z
+HSPLorg/json/JSONObject;->optDouble(Ljava/lang/String;)D
+HSPLorg/json/JSONObject;->optDouble(Ljava/lang/String;D)D
 HSPLorg/json/JSONObject;->optInt(Ljava/lang/String;I)I
 HSPLorg/json/JSONObject;->optJSONObject(Ljava/lang/String;)Lorg/json/JSONObject;
 HSPLorg/json/JSONObject;->optLong(Ljava/lang/String;J)J
@@ -29846,6 +31116,7 @@
 HSPLorg/json/JSONObject;->put(Ljava/lang/String;J)Lorg/json/JSONObject;
 HSPLorg/json/JSONObject;->put(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
 HSPLorg/json/JSONObject;->put(Ljava/lang/String;Z)Lorg/json/JSONObject;
+HSPLorg/json/JSONObject;->putOpt(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
 HSPLorg/json/JSONObject;->toString()Ljava/lang/String;
 HSPLorg/json/JSONObject;->wrap(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLorg/json/JSONObject;->writeTo(Lorg/json/JSONStringer;)V
@@ -29876,10 +31147,10 @@
 HSPLorg/xml/sax/InputSource;->getSystemId()Ljava/lang/String;
 HSPLorg/xmlpull/v1/XmlPullParserFactory;-><init>()V
 HSPLorg/xmlpull/v1/XmlPullParserFactory;->getParserInstance()Lorg/xmlpull/v1/XmlPullParser;
-PLorg/xmlpull/v1/XmlPullParserFactory;->getSerializerInstance()Lorg/xmlpull/v1/XmlSerializer;
+HPLorg/xmlpull/v1/XmlPullParserFactory;->getSerializerInstance()Lorg/xmlpull/v1/XmlSerializer;
 HSPLorg/xmlpull/v1/XmlPullParserFactory;->newInstance()Lorg/xmlpull/v1/XmlPullParserFactory;
 HSPLorg/xmlpull/v1/XmlPullParserFactory;->newPullParser()Lorg/xmlpull/v1/XmlPullParser;
-PLorg/xmlpull/v1/XmlPullParserFactory;->newSerializer()Lorg/xmlpull/v1/XmlSerializer;
+HPLorg/xmlpull/v1/XmlPullParserFactory;->newSerializer()Lorg/xmlpull/v1/XmlSerializer;
 HSPLsun/invoke/util/Wrapper;->forPrimitiveType(Ljava/lang/Class;)Lsun/invoke/util/Wrapper;
 HSPLsun/misc/ASCIICaseInsensitiveComparator;-><init>()V
 HSPLsun/misc/ASCIICaseInsensitiveComparator;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
@@ -29995,6 +31266,7 @@
 HSPLsun/nio/ch/FileChannelImpl;->position(J)Ljava/nio/channels/FileChannel;
 HSPLsun/nio/ch/FileChannelImpl;->read(Ljava/nio/ByteBuffer;)I
 HSPLsun/nio/ch/FileChannelImpl;->size()J
+HSPLsun/nio/ch/FileChannelImpl;->tryLock(JJZ)Ljava/nio/channels/FileLock;
 HSPLsun/nio/ch/FileChannelImpl;->write(Ljava/nio/ByteBuffer;)I
 HSPLsun/nio/ch/FileDispatcherImpl;-><init>()V
 HSPLsun/nio/ch/FileDispatcherImpl;->close(Ljava/io/FileDescriptor;)V
@@ -30099,14 +31371,18 @@
 HSPLsun/nio/fs/UnixException;->rethrowAsIOException(Lsun/nio/fs/UnixPath;Lsun/nio/fs/UnixPath;)V
 HSPLsun/nio/fs/UnixException;->translateToIOException(Ljava/lang/String;Ljava/lang/String;)Ljava/io/IOException;
 HSPLsun/nio/fs/UnixFileAttributeViews$Basic;->readAttributes()Ljava/nio/file/attribute/BasicFileAttributes;
+HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->creationTime()Ljava/nio/file/attribute/FileTime;
 HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->isRegularFile()Z
+HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->lastModifiedTime()Ljava/nio/file/attribute/FileTime;
+HSPLsun/nio/fs/UnixFileAttributes;->creationTime()Ljava/nio/file/attribute/FileTime;
 HSPLsun/nio/fs/UnixFileAttributes;->isRegularFile()Z
+HSPLsun/nio/fs/UnixFileAttributes;->lastModifiedTime()Ljava/nio/file/attribute/FileTime;
 HSPLsun/nio/fs/UnixFileModeAttribute;->toUnixMode(I[Ljava/nio/file/attribute/FileAttribute;)I
 PLsun/nio/fs/UnixFileSystem$3;->matches(Ljava/nio/file/Path;)Z
 HSPLsun/nio/fs/UnixFileSystem;-><init>(Lsun/nio/fs/UnixFileSystemProvider;Ljava/lang/String;)V
-PLsun/nio/fs/UnixFileSystem;->compilePathMatchPattern(Ljava/lang/String;)Ljava/util/regex/Pattern;
+HPLsun/nio/fs/UnixFileSystem;->compilePathMatchPattern(Ljava/lang/String;)Ljava/util/regex/Pattern;
 HSPLsun/nio/fs/UnixFileSystem;->getPath(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path;
-PLsun/nio/fs/UnixFileSystem;->getPathMatcher(Ljava/lang/String;)Ljava/nio/file/PathMatcher;
+HPLsun/nio/fs/UnixFileSystem;->getPathMatcher(Ljava/lang/String;)Ljava/nio/file/PathMatcher;
 HSPLsun/nio/fs/UnixFileSystem;->needToResolveAgainstDefaultDirectory()Z
 HSPLsun/nio/fs/UnixFileSystem;->normalizeJavaPath(Ljava/lang/String;)Ljava/lang/String;
 HSPLsun/nio/fs/UnixFileSystem;->normalizeNativePath([C)[C
@@ -30126,8 +31402,8 @@
 HSPLsun/nio/fs/UnixPath;->checkRead()V
 HSPLsun/nio/fs/UnixPath;->encode(Lsun/nio/fs/UnixFileSystem;Ljava/lang/String;)[B
 HSPLsun/nio/fs/UnixPath;->getByteArrayForSysCalls()[B
-PLsun/nio/fs/UnixPath;->getFileName()Ljava/nio/file/Path;
-PLsun/nio/fs/UnixPath;->getFileName()Lsun/nio/fs/UnixPath;
+HPLsun/nio/fs/UnixPath;->getFileName()Ljava/nio/file/Path;
+HPLsun/nio/fs/UnixPath;->getFileName()Lsun/nio/fs/UnixPath;
 HSPLsun/nio/fs/UnixPath;->getFileSystem()Ljava/nio/file/FileSystem;
 HSPLsun/nio/fs/UnixPath;->getFileSystem()Lsun/nio/fs/UnixFileSystem;
 HSPLsun/nio/fs/UnixPath;->getNameCount()I
@@ -30229,7 +31505,7 @@
 HSPLsun/security/provider/X509Factory;->intern(Ljava/security/cert/X509Certificate;)Lsun/security/x509/X509CertImpl;
 HSPLsun/security/provider/certpath/AdaptableX509CertSelector;->match(Ljava/security/cert/Certificate;)Z
 HSPLsun/security/provider/certpath/AdaptableX509CertSelector;->matchSubjectKeyID(Ljava/security/cert/X509Certificate;)Z
-PLsun/security/provider/certpath/AdaptableX509CertSelector;->setValidityPeriod(Ljava/util/Date;Ljava/util/Date;)V
+HPLsun/security/provider/certpath/AdaptableX509CertSelector;->setValidityPeriod(Ljava/util/Date;Ljava/util/Date;)V
 PLsun/security/provider/certpath/AdjacencyList;->buildList(Ljava/util/List;ILsun/security/provider/certpath/BuildStep;)Z
 HSPLsun/security/provider/certpath/AlgorithmChecker;-><init>(Ljava/security/cert/TrustAnchor;)V
 HSPLsun/security/provider/certpath/AlgorithmChecker;-><init>(Ljava/security/cert/TrustAnchor;Ljava/security/AlgorithmConstraints;)V
@@ -30237,8 +31513,8 @@
 HSPLsun/security/provider/certpath/AlgorithmChecker;->check(Ljava/security/cert/Certificate;Ljava/util/Collection;)V
 HSPLsun/security/provider/certpath/AlgorithmChecker;->checkFingerprint(Ljava/security/cert/X509Certificate;)Z
 HSPLsun/security/provider/certpath/AlgorithmChecker;->init(Z)V
-PLsun/security/provider/certpath/AlgorithmChecker;->isForwardCheckingSupported()Z
-PLsun/security/provider/certpath/AlgorithmChecker;->trySetTrustAnchor(Ljava/security/cert/TrustAnchor;)V
+HPLsun/security/provider/certpath/AlgorithmChecker;->isForwardCheckingSupported()Z
+HPLsun/security/provider/certpath/AlgorithmChecker;->trySetTrustAnchor(Ljava/security/cert/TrustAnchor;)V
 HSPLsun/security/provider/certpath/BasicChecker;-><init>(Ljava/security/cert/TrustAnchor;Ljava/util/Date;Ljava/lang/String;Z)V
 HSPLsun/security/provider/certpath/BasicChecker;->check(Ljava/security/cert/Certificate;Ljava/util/Collection;)V
 HSPLsun/security/provider/certpath/BasicChecker;->init(Z)V
@@ -30305,7 +31581,7 @@
 HSPLsun/security/provider/certpath/PKIX$ValidatorParams;->policyMappingInhibited()Z
 HSPLsun/security/provider/certpath/PKIX$ValidatorParams;->policyQualifiersRejected()Z
 HSPLsun/security/provider/certpath/PKIX$ValidatorParams;->revocationEnabled()Z
-PLsun/security/provider/certpath/PKIX$ValidatorParams;->setCertPath(Ljava/security/cert/CertPath;)V
+HPLsun/security/provider/certpath/PKIX$ValidatorParams;->setCertPath(Ljava/security/cert/CertPath;)V
 HSPLsun/security/provider/certpath/PKIX$ValidatorParams;->sigProvider()Ljava/lang/String;
 HSPLsun/security/provider/certpath/PKIX$ValidatorParams;->targetCertConstraints()Ljava/security/cert/CertSelector;
 HSPLsun/security/provider/certpath/PKIX$ValidatorParams;->trustAnchors()Ljava/util/Set;
@@ -30320,7 +31596,7 @@
 HSPLsun/security/provider/certpath/PolicyChecker;->checkPolicy(Ljava/security/cert/X509Certificate;)V
 HSPLsun/security/provider/certpath/PolicyChecker;->getPolicyTree()Ljava/security/cert/PolicyNode;
 HSPLsun/security/provider/certpath/PolicyChecker;->init(Z)V
-PLsun/security/provider/certpath/PolicyChecker;->isForwardCheckingSupported()Z
+HPLsun/security/provider/certpath/PolicyChecker;->isForwardCheckingSupported()Z
 HSPLsun/security/provider/certpath/PolicyChecker;->mergeExplicitPolicy(ILsun/security/x509/X509CertImpl;Z)I
 HSPLsun/security/provider/certpath/PolicyChecker;->mergeInhibitAnyPolicy(ILsun/security/x509/X509CertImpl;)I
 HSPLsun/security/provider/certpath/PolicyChecker;->mergePolicyMapping(ILsun/security/x509/X509CertImpl;)I
@@ -30331,6 +31607,7 @@
 HSPLsun/security/provider/certpath/PolicyNodeImpl;-><init>(Lsun/security/provider/certpath/PolicyNodeImpl;Lsun/security/provider/certpath/PolicyNodeImpl;)V
 HSPLsun/security/provider/certpath/PolicyNodeImpl;->copyTree()Lsun/security/provider/certpath/PolicyNodeImpl;
 HSPLsun/security/provider/certpath/PolicyNodeImpl;->getChildren()Ljava/util/Iterator;
+HSPLsun/security/provider/certpath/PolicyNodeImpl;->getPolicyNodes(I)Ljava/util/Set;
 HSPLsun/security/provider/certpath/PolicyNodeImpl;->getPolicyNodesExpectedHelper(ILjava/lang/String;Z)Ljava/util/Set;
 HSPLsun/security/provider/certpath/PolicyNodeImpl;->prune(I)V
 HSPLsun/security/provider/certpath/RevocationChecker$1;->run()Lsun/security/provider/certpath/RevocationChecker$RevocationProperties;
@@ -30510,6 +31787,7 @@
 HSPLsun/security/x509/AVA;->isDerString(Lsun/security/util/DerValue;Z)Z
 HSPLsun/security/x509/AVA;->parseString(Ljava/io/Reader;IILjava/lang/StringBuilder;)Lsun/security/util/DerValue;
 HSPLsun/security/x509/AVA;->toRFC2253CanonicalString()Ljava/lang/String;
+HSPLsun/security/x509/AVA;->toRFC2253String(Ljava/util/Map;)Ljava/lang/String;
 HSPLsun/security/x509/AVAKeyword;-><init>(Ljava/lang/String;Lsun/security/util/ObjectIdentifier;ZZ)V
 HSPLsun/security/x509/AVAKeyword;->getKeyword(Lsun/security/util/ObjectIdentifier;ILjava/util/Map;)Ljava/lang/String;
 HSPLsun/security/x509/AVAKeyword;->getOID(Ljava/lang/String;ILjava/util/Map;)Lsun/security/util/ObjectIdentifier;
@@ -30549,7 +31827,7 @@
 HSPLsun/security/x509/CertificatePolicyId;->getIdentifier()Lsun/security/util/ObjectIdentifier;
 HSPLsun/security/x509/CertificateSerialNumber;->get(Ljava/lang/String;)Lsun/security/x509/SerialNumber;
 HSPLsun/security/x509/CertificateValidity;->construct(Lsun/security/util/DerValue;)V
-PLsun/security/x509/CertificateValidity;->get(Ljava/lang/String;)Ljava/util/Date;
+HPLsun/security/x509/CertificateValidity;->get(Ljava/lang/String;)Ljava/util/Date;
 HSPLsun/security/x509/CertificateVersion;->compare(I)I
 HSPLsun/security/x509/CertificateVersion;->construct(Lsun/security/util/DerValue;)V
 HSPLsun/security/x509/CertificateX509Key;->get(Ljava/lang/String;)Ljava/security/PublicKey;
@@ -30577,6 +31855,7 @@
 HSPLsun/security/x509/RDN;-><init>(Ljava/lang/String;Ljava/util/Map;)V
 HSPLsun/security/x509/RDN;-><init>(Lsun/security/util/DerValue;)V
 HSPLsun/security/x509/RDN;->encode(Lsun/security/util/DerOutputStream;)V
+HSPLsun/security/x509/RDN;->toRFC2253String(Ljava/util/Map;)Ljava/lang/String;
 HSPLsun/security/x509/RDN;->toRFC2253String(Z)Ljava/lang/String;
 HSPLsun/security/x509/RDN;->toRFC2253StringInternal(ZLjava/util/Map;)Ljava/lang/String;
 HSPLsun/security/x509/SerialNumber;->getNumber()Ljava/math/BigInteger;
@@ -30595,9 +31874,12 @@
 HSPLsun/security/x509/X500Name;->countQuotes(Ljava/lang/String;II)I
 HSPLsun/security/x509/X500Name;->equals(Ljava/lang/Object;)Z
 HSPLsun/security/x509/X500Name;->escaped(IILjava/lang/String;)Z
+HSPLsun/security/x509/X500Name;->generateRFC2253DN(Ljava/util/Map;)Ljava/lang/String;
 HSPLsun/security/x509/X500Name;->getEncoded()[B
 HSPLsun/security/x509/X500Name;->getEncodedInternal()[B
 HSPLsun/security/x509/X500Name;->getRFC2253CanonicalName()Ljava/lang/String;
+HSPLsun/security/x509/X500Name;->getRFC2253Name()Ljava/lang/String;
+HSPLsun/security/x509/X500Name;->getRFC2253Name(Ljava/util/Map;)Ljava/lang/String;
 HSPLsun/security/x509/X500Name;->hashCode()I
 HSPLsun/security/x509/X500Name;->intern(Lsun/security/util/ObjectIdentifier;)Lsun/security/util/ObjectIdentifier;
 HSPLsun/security/x509/X500Name;->isEmpty()Z
@@ -30612,18 +31894,18 @@
 HSPLsun/security/x509/X509CertImpl;->getExtension(Lsun/security/util/ObjectIdentifier;)Lsun/security/x509/Extension;
 HSPLsun/security/x509/X509CertImpl;->getIssuerX500Principal()Ljavax/security/auth/x500/X500Principal;
 HSPLsun/security/x509/X509CertImpl;->getNameConstraintsExtension()Lsun/security/x509/NameConstraintsExtension;
-PLsun/security/x509/X509CertImpl;->getNotAfter()Ljava/util/Date;
-PLsun/security/x509/X509CertImpl;->getNotBefore()Ljava/util/Date;
+HPLsun/security/x509/X509CertImpl;->getNotAfter()Ljava/util/Date;
+HPLsun/security/x509/X509CertImpl;->getNotBefore()Ljava/util/Date;
 HSPLsun/security/x509/X509CertImpl;->getPolicyConstraintsExtension()Lsun/security/x509/PolicyConstraintsExtension;
 HSPLsun/security/x509/X509CertImpl;->getPolicyMappingsExtension()Lsun/security/x509/PolicyMappingsExtension;
 HSPLsun/security/x509/X509CertImpl;->getPublicKey()Ljava/security/PublicKey;
 HSPLsun/security/x509/X509CertImpl;->getSerialNumberObject()Lsun/security/x509/SerialNumber;
 HSPLsun/security/x509/X509CertImpl;->getSigAlgName()Ljava/lang/String;
-PLsun/security/x509/X509CertImpl;->getSubjectAlternativeNameExtension()Lsun/security/x509/SubjectAlternativeNameExtension;
+HPLsun/security/x509/X509CertImpl;->getSubjectAlternativeNameExtension()Lsun/security/x509/SubjectAlternativeNameExtension;
 HSPLsun/security/x509/X509CertImpl;->getSubjectKeyId()Lsun/security/x509/KeyIdentifier;
 HSPLsun/security/x509/X509CertImpl;->getSubjectKeyIdentifierExtension()Lsun/security/x509/SubjectKeyIdentifierExtension;
 HSPLsun/security/x509/X509CertImpl;->getSubjectX500Principal()Ljavax/security/auth/x500/X500Principal;
-PLsun/security/x509/X509CertImpl;->isSelfSigned(Ljava/security/cert/X509Certificate;Ljava/lang/String;)Z
+HPLsun/security/x509/X509CertImpl;->isSelfSigned(Ljava/security/cert/X509Certificate;Ljava/lang/String;)Z
 HSPLsun/security/x509/X509CertImpl;->parse(Lsun/security/util/DerValue;[B)V
 HSPLsun/security/x509/X509CertImpl;->verify(Ljava/security/PublicKey;)V
 HSPLsun/security/x509/X509CertImpl;->verify(Ljava/security/PublicKey;Ljava/lang/String;)V
@@ -39438,3 +40720,3048 @@
 Lsun/util/logging/PlatformLogger$Level;
 Lsun/util/logging/PlatformLogger$LoggerProxy;
 Lsun/util/logging/PlatformLogger;
+HSPLandroid/accounts/AccountManager$18;->run()V
+HSPLandroid/accounts/AccountManager$BaseFutureTask$1;-><init>(Landroid/accounts/AccountManager;)V
+HSPLandroid/accounts/AccountManager$BaseFutureTask$Response;-><init>(Landroid/accounts/AccountManager$BaseFutureTask;)V
+HSPLandroid/accounts/AccountManager$BaseFutureTask;-><init>(Landroid/accounts/AccountManager;Landroid/os/Handler;)V
+HSPLandroid/accounts/AccountManager$Future2Task;->getResult(JLjava/util/concurrent/TimeUnit;)Ljava/lang/Object;
+HSPLandroid/accounts/AccountManager$Future2Task;-><init>(Landroid/accounts/AccountManager;Landroid/os/Handler;Landroid/accounts/AccountManagerCallback;)V
+HSPLandroid/accounts/AccountManager$Future2Task;->start()Landroid/accounts/AccountManager$Future2Task;
+HSPLandroid/accounts/AccountManager;->access$000(Landroid/accounts/AccountManager;)Landroid/accounts/IAccountManager;
+HSPLandroid/accounts/AccountManager;->access$100(Landroid/accounts/AccountManager;)Landroid/content/Context;
+HSPLandroid/accounts/AccountManager;->access$200(Landroid/accounts/AccountManager;)Ljava/util/HashMap;
+HSPLandroid/accounts/AccountManager;->access$300(Landroid/accounts/AccountManager;)Ljava/util/HashMap;
+HSPLandroid/accounts/AccountManager;->getAccountsByTypeAndFeatures(Ljava/lang/String;[Ljava/lang/String;Landroid/accounts/AccountManagerCallback;Landroid/os/Handler;)Landroid/accounts/AccountManagerFuture;
+HSPLandroid/accounts/AccountManager;->getAccountsByTypeForPackage(Ljava/lang/String;Ljava/lang/String;)[Landroid/accounts/Account;
+HSPLandroid/accounts/AccountManager;->getPassword(Landroid/accounts/Account;)Ljava/lang/String;
+HSPLandroid/accounts/AccountManager;->getUserData(Landroid/accounts/Account;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/accounts/AccountManager;->peekAuthToken(Landroid/accounts/Account;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/accounts/IAccountManager$Stub$Proxy;->getAccountsByFeatures(Landroid/accounts/IAccountManagerResponse;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/accounts/IAccountManager$Stub$Proxy;->getAccountsByTypeForPackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)[Landroid/accounts/Account;
+HSPLandroid/accounts/IAccountManager$Stub$Proxy;->getPassword(Landroid/accounts/Account;)Ljava/lang/String;
+HSPLandroid/accounts/IAccountManager$Stub$Proxy;->getUserData(Landroid/accounts/Account;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/accounts/IAccountManager$Stub$Proxy;->peekAuthToken(Landroid/accounts/Account;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/accounts/IAccountManagerResponse$Stub;-><init>()V
+HSPLandroid/animation/Animator;->isPaused()Z
+HSPLandroid/animation/AnimatorSet$SeekState;->getPlayTime()J
+HSPLandroid/animation/AnimatorSet$SeekState;->setPlayTime(JZ)V
+HSPLandroid/animation/AnimatorSet$SeekState;->updateSeekDirection(Z)V
+HSPLandroid/animation/AnimatorSet;->access$200(Landroid/animation/AnimatorSet;)J
+HSPLandroid/animation/AnimatorSet;->setCurrentPlayTime(J)V
+HSPLandroid/animation/ObjectAnimator;->setAutoCancel(Z)V
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;-><init>(Ljava/lang/String;[I)V
+HSPLandroid/animation/PropertyValuesHolder;->ofInt(Ljava/lang/String;[I)Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/RectEvaluator;-><init>(Landroid/graphics/Rect;)V
+HSPLandroid/app/Activity;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Landroid/app/Instrumentation;Landroid/os/IBinder;ILandroid/app/Application;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Ljava/lang/CharSequence;Landroid/app/Activity;Ljava/lang/String;Landroid/app/Activity$NonConfigurationInstances;Landroid/content/res/Configuration;Ljava/lang/String;Lcom/android/internal/app/IVoiceInteractor;Landroid/view/Window;Landroid/view/ViewRootImpl$ActivityConfigCallback;Landroid/os/IBinder;)V
+HSPLandroid/app/ActivityManager$RunningServiceInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/ActivityManager$RunningServiceInfo;
+HSPLandroid/app/ActivityManager$RunningServiceInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/ActivityManager$RunningServiceInfo;-><init>(Landroid/os/Parcel;Landroid/app/ActivityManager$1;)V
+HSPLandroid/app/ActivityManager$RunningServiceInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/ActivityManager$RunningServiceInfo;->readFromParcel(Landroid/os/Parcel;)V
+HSPLandroid/app/ActivityManager$StackInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/ActivityManager$StackInfo;
+HSPLandroid/app/ActivityManager$StackInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/ActivityManager$StackInfo;-><init>(Landroid/os/Parcel;Landroid/app/ActivityManager$1;)V
+HSPLandroid/app/ActivityManager$StackInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/ActivityManager$StackInfo;->readFromParcel(Landroid/os/Parcel;)V
+HSPLandroid/app/ActivityManager$TaskDescription;->setEnsureNavigationBarContrastWhenTransparent(Z)V
+HSPLandroid/app/ActivityManager$TaskDescription;->setEnsureStatusBarContrastWhenTransparent(Z)V
+HSPLandroid/app/ActivityManager;->getDeviceConfigurationInfo()Landroid/content/pm/ConfigurationInfo;
+HSPLandroid/app/ActivityManager;->getLockTaskModeState()I
+HSPLandroid/app/ActivityManager;->getRunningServices(I)Ljava/util/List;
+HSPLandroid/app/ActivityManager;->getRunningTasks(I)Ljava/util/List;
+HSPLandroid/app/ActivityManager;->getTaskService()Landroid/app/IActivityTaskManager;
+HSPLandroid/app/Activity;->registerRemoteAnimations(Landroid/view/RemoteAnimationDefinition;)V
+HSPLandroid/app/Activity;->setContentView(Landroid/view/View;)V
+HSPLandroid/app/Activity;->setDefaultKeyMode(I)V
+HSPLandroid/app/Activity;->setRequestedOrientation(I)V
+HSPLandroid/app/ActivityThread$ActivityClientRecord;-><init>(Landroid/os/IBinder;Landroid/content/Intent;ILandroid/content/pm/ActivityInfo;Landroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;Ljava/lang/String;Lcom/android/internal/app/IVoiceInteractor;Landroid/os/Bundle;Landroid/os/PersistableBundle;Ljava/util/List;Ljava/util/List;ZLandroid/app/ProfilerInfo;Landroid/app/ClientTransactionHandler;Landroid/os/IBinder;)V
+HSPLandroid/app/ActivityThread$ActivityClientRecord;->isPersistable()Z
+HSPLandroid/app/ActivityThread;->applyPendingProcessState()V
+HSPLandroid/app/ActivityThread;->countLaunchingActivities(I)V
+HSPLandroid/app/ActivityThread;->getHandler()Landroid/os/Handler;
+HSPLandroid/app/ActivityThread;->isLoadedApkResourceDirsUpToDate(Landroid/app/LoadedApk;Landroid/content/pm/ApplicationInfo;)Z
+HSPLandroid/app/ActivityThread;->lambda$attach$1$ActivityThread(Landroid/content/res/Configuration;)V
+HSPLandroid/app/ActivityThread;->relaunchAllActivities(Z)V
+HSPLandroid/app/ActivityTransitionState;->startExitOutTransition(Landroid/app/Activity;Landroid/os/Bundle;)V
+HSPLandroid/app/admin/DevicePolicyManager;->getCameraDisabled(Landroid/content/ComponentName;I)Z
+HSPLandroid/app/admin/DevicePolicyManager;->getDeviceOwnerComponentOnCallingUser()Landroid/content/ComponentName;
+HSPLandroid/app/admin/DevicePolicyManager;->getDeviceOwner()Ljava/lang/String;
+HSPLandroid/app/admin/DevicePolicyManager;->getDeviceOwnerOrganizationName()Ljava/lang/CharSequence;
+HSPLandroid/app/admin/DevicePolicyManager;->getKeyguardDisabledFeatures(Landroid/content/ComponentName;)I
+HSPLandroid/app/admin/DevicePolicyManager;->getProfileOwner()Landroid/content/ComponentName;
+HSPLandroid/app/admin/DevicePolicyManager;->getSystemUpdatePolicy()Landroid/app/admin/SystemUpdatePolicy;
+HSPLandroid/app/admin/DevicePolicyManager;->isAdminActiveAsUser(Landroid/content/ComponentName;I)Z
+HSPLandroid/app/admin/DevicePolicyManager;->isAdminActive(Landroid/content/ComponentName;)Z
+HSPLandroid/app/admin/DevicePolicyManager;->isLogoutEnabled()Z
+HSPLandroid/app/admin/DevicePolicyManager;->isNetworkLoggingEnabled(Landroid/content/ComponentName;)Z
+HSPLandroid/app/admin/DevicePolicyManager;->throwIfParentInstance(Ljava/lang/String;)V
+HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->getCameraDisabled(Landroid/content/ComponentName;I)Z
+HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->getDeviceOwnerOrganizationName()Ljava/lang/CharSequence;
+HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->getProfileOwner(I)Landroid/content/ComponentName;
+HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->getSystemUpdatePolicy()Landroid/app/admin/SystemUpdatePolicy;
+HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->isAdminActive(Landroid/content/ComponentName;I)Z
+HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->isLogoutEnabled()Z
+HSPLandroid/app/admin/IDevicePolicyManager$Stub$Proxy;->isNetworkLoggingEnabled(Landroid/content/ComponentName;Ljava/lang/String;)Z
+HSPLandroid/app/AlarmManager;->set(IJJJLandroid/app/AlarmManager$OnAlarmListener;Landroid/os/Handler;Landroid/os/WorkSource;)V
+HSPLandroid/app/AlarmManager;->set(IJJJLandroid/app/PendingIntent;Landroid/os/WorkSource;)V
+HSPLandroid/app/AlarmManager;->setWindow(IJJLandroid/app/PendingIntent;)V
+HSPLandroid/app/Application;->getProcessName()Ljava/lang/String;
+HSPLandroid/app/ApplicationLoaders;->getCachedNonBootclasspathSystemLib(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/util/List;)Ljava/lang/ClassLoader;
+HSPLandroid/app/ApplicationLoaders;->getSharedLibraryClassLoaderWithSharedLibraries(Ljava/lang/String;IZLjava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/util/List;)Ljava/lang/ClassLoader;
+HSPLandroid/app/ApplicationLoaders;->sharedLibrariesEquals(Ljava/util/List;Ljava/util/List;)Z
+HSPLandroid/app/ApplicationPackageManager;->getSharedSystemSharedLibraryPackageName()Ljava/lang/String;
+HSPLandroid/app/ApplicationPackageManager;->getSystemAvailableFeatures()[Landroid/content/pm/FeatureInfo;
+HSPLandroid/app/ApplicationPackageManager;->getUserBadgedLabel(Ljava/lang/CharSequence;Landroid/os/UserHandle;)Ljava/lang/CharSequence;
+HSPLandroid/app/ApplicationPackageManager;->isManagedProfile(I)Z
+HSPLandroid/app/ApplicationPackageManager;->isSafeMode()Z
+HSPLandroid/app/ApplicationPackageManager;->registerMoveCallback(Landroid/content/pm/PackageManager$MoveCallback;Landroid/os/Handler;)V
+HSPLandroid/app/AppOpsManager$2;-><init>(Landroid/app/AppOpsManager;Landroid/app/AppOpsManager$OnOpActiveChangedListener;)V
+HSPLandroid/app/AppOpsManager$OpEntry$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/AppOpsManager$OpEntry;
+HSPLandroid/app/AppOpsManager$OpEntry$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/AppOpsManager$OpEntry;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/AppOpsManager$PackageOps$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/AppOpsManager$PackageOps;
+HSPLandroid/app/AppOpsManager$PackageOps$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/AppOpsManager$PackageOps;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/AppOpsManager;->access$800(Landroid/os/Parcel;)Landroid/util/LongSparseLongArray;
+HSPLandroid/app/AppOpsManager;->access$900(Landroid/os/Parcel;)Landroid/util/LongSparseArray;
+HSPLandroid/app/AppOpsManager;->checkOpNoThrow(Ljava/lang/String;ILjava/lang/String;)I
+HSPLandroid/app/AppOpsManager;->finishOp(Ljava/lang/String;ILjava/lang/String;)V
+HSPLandroid/app/AppOpsManager;->noteProxyOpNoThrow(Ljava/lang/String;Ljava/lang/String;)I
+HSPLandroid/app/AppOpsManager;->readLongSparseLongArrayFromParcel(Landroid/os/Parcel;)Landroid/util/LongSparseLongArray;
+HSPLandroid/app/AppOpsManager;->readLongSparseStringArrayFromParcel(Landroid/os/Parcel;)Landroid/util/LongSparseArray;
+HSPLandroid/app/AppOpsManager;->startOpNoThrow(Ljava/lang/String;ILjava/lang/String;)I
+HSPLandroid/app/AppOpsManager;->startWatchingActive([ILandroid/app/AppOpsManager$OnOpActiveChangedListener;)V
+HSPLandroid/app/AppOpsManager;->startWatchingMode(Ljava/lang/String;Ljava/lang/String;ILandroid/app/AppOpsManager$OnOpChangedListener;)V
+HSPLandroid/app/AppOpsManager;->startWatchingMode(Ljava/lang/String;Ljava/lang/String;Landroid/app/AppOpsManager$OnOpChangedListener;)V
+HSPLandroid/app/AppOpsManager;->startWatchingNoted([ILandroid/app/AppOpsManager$OnOpNotedListener;)V
+HSPLandroid/app/AppOpsManager;->unsafeCheckOpRaw(Ljava/lang/String;ILjava/lang/String;)I
+HSPLandroid/app/BackStackRecord;->replace(ILandroid/app/Fragment;Ljava/lang/String;)Landroid/app/FragmentTransaction;
+HSPLandroid/app/backup/BackupManager;->checkServiceBinder()V
+HSPLandroid/app/backup/BackupManager;->getCurrentTransport()Ljava/lang/String;
+HSPLandroid/app/backup/BackupManager;->updateTransportAttributes(Landroid/content/ComponentName;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/CharSequence;)V
+HSPLandroid/app/backup/BackupManager;->updateTransportAttributes(Landroid/content/ComponentName;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;)V
+HSPLandroid/app/backup/BackupTransport$TransportImpl;->configurationIntent()Landroid/content/Intent;
+HSPLandroid/app/backup/BackupTransport$TransportImpl;->currentDestinationString()Ljava/lang/String;
+HSPLandroid/app/backup/BackupTransport$TransportImpl;->dataManagementIntentLabel()Ljava/lang/CharSequence;
+HSPLandroid/app/backup/BackupTransport$TransportImpl;->dataManagementIntent()Landroid/content/Intent;
+HSPLandroid/app/backup/BackupTransport$TransportImpl;-><init>(Landroid/app/backup/BackupTransport;)V
+HSPLandroid/app/backup/BackupTransport$TransportImpl;->name()Ljava/lang/String;
+HSPLandroid/app/backup/BackupTransport$TransportImpl;->transportDirName()Ljava/lang/String;
+HSPLandroid/app/backup/BackupTransport;->configurationIntent()Landroid/content/Intent;
+HSPLandroid/app/backup/BackupTransport;->dataManagementIntentLabel()Ljava/lang/CharSequence;
+HSPLandroid/app/backup/BackupTransport;->dataManagementIntent()Landroid/content/Intent;
+HSPLandroid/app/backup/BackupTransport;->getBinder()Landroid/os/IBinder;
+HSPLandroid/app/backup/BackupTransport;-><init>()V
+HSPLandroid/app/backup/IBackupManager$Stub$Proxy;->getCurrentTransport()Ljava/lang/String;
+HSPLandroid/app/backup/IBackupManager$Stub$Proxy;->updateTransportAttributesForUser(ILandroid/content/ComponentName;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/CharSequence;)V
+HSPLandroid/app/ContextImpl$1;->accept(Ljava/io/File;Ljava/lang/String;)Z
+HSPLandroid/app/ContextImpl$1;-><init>(Ljava/lang/String;)V
+HSPLandroid/app/ContextImpl;->createResources(Landroid/os/IBinder;Landroid/app/LoadedApk;Ljava/lang/String;ILandroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
+HSPLandroid/app/ContextImpl;->databaseList()[Ljava/lang/String;
+HSPLandroid/app/ContextImpl;->deleteDatabase(Ljava/lang/String;)Z
+HSPLandroid/app/ContextImpl;->deleteFile(Ljava/lang/String;)Z
+HSPLandroid/app/ContextImpl;->getOuterContext()Landroid/content/Context;
+HSPLandroid/app/ContextImpl;->moveFiles(Ljava/io/File;Ljava/io/File;Ljava/lang/String;)I
+HSPLandroid/app/ContextImpl;->moveSharedPreferencesFrom(Landroid/content/Context;Ljava/lang/String;)Z
+HSPLandroid/app/ContextImpl;->openOrCreateDatabase(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;)Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/app/ContextImpl;->openOrCreateDatabase(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;)Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/app/ContextImpl;->updateDisplay(I)V
+HSPLandroid/app/Dialog;->getLayoutInflater()Landroid/view/LayoutInflater;
+HSPLandroid/app/Dialog;->setContentView(I)V
+HSPLandroid/app/Dialog;->setOnShowListener(Landroid/content/DialogInterface$OnShowListener;)V
+HSPLandroid/app/DownloadManager;->query(Landroid/app/DownloadManager$Query;)Landroid/database/Cursor;
+HSPLandroid/app/DownloadManager;->query(Landroid/app/DownloadManager$Query;[Ljava/lang/String;)Landroid/database/Cursor;
+HSPLandroid/app/FragmentManagerImpl;->registerFragmentLifecycleCallbacks(Landroid/app/FragmentManager$FragmentLifecycleCallbacks;Z)V
+HSPLandroid/app/IActivityManager$Stub$Proxy;->getPackageProcessState(Ljava/lang/String;Ljava/lang/String;)I
+HSPLandroid/app/IActivityManager$Stub$Proxy;->getServices(II)Ljava/util/List;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->getTasks(I)Ljava/util/List;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->getUidForIntentSender(Landroid/content/IIntentSender;)I
+HSPLandroid/app/IActivityManager$Stub$Proxy;->isUserRunning(II)Z
+HSPLandroid/app/IActivityManager$Stub$Proxy;->registerIntentSenderCancelListener(Landroid/content/IIntentSender;Lcom/android/internal/os/IResultReceiver;)V
+HSPLandroid/app/IActivityManager$Stub$Proxy;->registerProcessObserver(Landroid/app/IProcessObserver;)V
+HSPLandroid/app/IActivityManager$Stub$Proxy;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
+HSPLandroid/app/IActivityManager$Stub$Proxy;->registerUidObserver(Landroid/app/IUidObserver;IILjava/lang/String;)V
+HSPLandroid/app/IActivityManager$Stub$Proxy;->setHasTopUi(Z)V
+HSPLandroid/app/IActivityManager$Stub$Proxy;->unregisterIntentSenderCancelListener(Landroid/content/IIntentSender;Lcom/android/internal/os/IResultReceiver;)V
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getDeviceConfigurationInfo()Landroid/content/pm/ConfigurationInfo;
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getFilteredTasks(III)Ljava/util/List;
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getFocusedStackInfo()Landroid/app/ActivityManager$StackInfo;
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getLastResumedActivityUserId()I
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getLockTaskModeState()I
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getRecentTasks(III)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getStackInfo(II)Landroid/app/ActivityManager$StackInfo;
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getTasks(I)Ljava/util/List;
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->keyguardGoingAway(I)V
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->registerRemoteAnimations(Landroid/os/IBinder;Landroid/view/RemoteAnimationDefinition;)V
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->setLockScreenShown(ZZ)V
+HSPLandroid/app/IActivityTaskManager$Stub$Proxy;->setRequestedOrientation(Landroid/os/IBinder;I)V
+HSPLandroid/app/IAlarmManager$Stub$Proxy;->getNextAlarmClock(I)Landroid/app/AlarmManager$AlarmClockInfo;
+HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelAllNotifications(Ljava/lang/String;I)V
+HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannelGroups(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
+HSPLandroid/app/INotificationManager$Stub$Proxy;->getConsolidatedNotificationPolicy()Landroid/app/NotificationManager$Policy;
+HSPLandroid/app/INotificationManager$Stub$Proxy;->getEffectsSuppressor()Landroid/content/ComponentName;
+HSPLandroid/app/INotificationManager$Stub$Proxy;->getZenModeConfig()Landroid/service/notification/ZenModeConfig;
+HSPLandroid/app/INotificationManager$Stub$Proxy;->registerListener(Landroid/service/notification/INotificationListener;Landroid/content/ComponentName;I)V
+HSPLandroid/app/INotificationManager$Stub$Proxy;->requestBindListener(Landroid/content/ComponentName;)V
+HSPLandroid/app/INotificationManager$Stub$Proxy;->setNotificationsShownFromListener(Landroid/service/notification/INotificationListener;[Ljava/lang/String;)V
+HSPLandroid/app/INotificationManager$Stub$Proxy;->setPrivateNotificationsAllowed(Z)V
+HSPLandroid/app/INotificationManager$Stub$Proxy;->shouldHideSilentStatusIcons(Ljava/lang/String;)Z
+HSPLandroid/app/IProcessObserver$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/app/IProcessObserver$Stub;-><init>()V
+HSPLandroid/app/IProcessObserver$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/ITaskStackListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/app/ITaskStackListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/IUidObserver$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->getHeightHint(I)I
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->getWallpaperInfo(I)Landroid/app/WallpaperInfo;
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->getWallpaper(Ljava/lang/String;Landroid/app/IWallpaperManagerCallback;ILandroid/os/Bundle;I)Landroid/os/ParcelFileDescriptor;
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->getWidthHint(I)I
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->isWallpaperSupported(Ljava/lang/String;)Z
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->registerWallpaperColorsCallback(Landroid/app/IWallpaperManagerCallback;II)V
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->setInAmbientMode(ZJ)V
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->setLockWallpaperCallback(Landroid/app/IWallpaperManagerCallback;)Z
+HSPLandroid/app/IWallpaperManager$Stub$Proxy;->unregisterWallpaperColorsCallback(Landroid/app/IWallpaperManagerCallback;II)V
+HSPLandroid/app/IWallpaperManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IWallpaperManager;
+HSPLandroid/app/IWallpaperManagerCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/app/IWallpaperManagerCallback$Stub;-><init>()V
+HSPLandroid/app/IWallpaperManagerCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/job/IJobScheduler$Stub$Proxy;->scheduleAsPackage(Landroid/app/job/JobInfo;Ljava/lang/String;ILjava/lang/String;)I
+HSPLandroid/app/job/JobInfo$Builder;->setRequiresBatteryNotLow(Z)Landroid/app/job/JobInfo$Builder;
+HSPLandroid/app/job/JobInfo;->getNetworkType()I
+HSPLandroid/app/job/JobInfo;->isRequireCharging()Z
+HSPLandroid/app/job/JobInfo;->isRequireDeviceIdle()Z
+HSPLandroid/app/KeyguardManager;->setPrivateNotificationsAllowed(Z)V
+HSPLandroid/app/LoadedApk;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
+HSPLandroid/app/LoadedApk;->getOverlayDirs()[Ljava/lang/String;
+HSPLandroid/app/LoadedApk;->getResDir()Ljava/lang/String;
+HSPLandroid/app/LoadedApk;->getSplitClassLoader(Ljava/lang/String;)Ljava/lang/ClassLoader;
+HSPLandroid/app/LoadedApk;->getSplitPaths(Ljava/lang/String;)[Ljava/lang/String;
+HSPLandroid/app/Notification$Action;->access$1900(Landroid/app/Notification$Action;)[Landroid/app/RemoteInput;
+HSPLandroid/app/Notification$Builder;->access$2500(Landroid/app/Notification$Builder;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/app/Notification$Builder;->access$300(Landroid/app/Notification$Builder;)Landroid/app/Notification;
+HSPLandroid/app/Notification$Builder;->applyStandardTemplate(ILandroid/app/Notification$StandardTemplateParams;Landroid/app/Notification$TemplateBindResult;)Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->applyStandardTemplate(ILandroid/app/Notification$TemplateBindResult;)Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->applyStandardTemplateWithActions(ILandroid/app/Notification$StandardTemplateParams;Landroid/app/Notification$TemplateBindResult;)Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->applyStandardTemplateWithActions(ILandroid/app/Notification$TemplateBindResult;)Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->bindActivePermissions(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindAlertedIcon(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindExpandButton(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindHeaderAppName(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindHeaderChronometerAndTime(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindHeaderText(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindHeaderTextSecondary(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindLargeIconAndReply(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;Landroid/app/Notification$TemplateBindResult;)V
+HSPLandroid/app/Notification$Builder;->bindLargeIcon(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)Z
+HSPLandroid/app/Notification$Builder;->bindNotificationHeader(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindProfileBadge(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->bindReplyIcon(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)Z
+HSPLandroid/app/Notification$Builder;->bindSmallIcon(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->calculateMarginEnd(ZZ)I
+HSPLandroid/app/Notification$Builder;->createBigContentView()Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->createContentView()Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->createContentView(Z)Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->createSummaryText()Ljava/lang/CharSequence;
+HSPLandroid/app/Notification$Builder;->ensureColors(Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->filterOutContextualActions(Ljava/util/List;)Ljava/util/List;
+HSPLandroid/app/Notification$Builder;->findReplyAction()Landroid/app/Notification$Action;
+HSPLandroid/app/Notification$Builder;->generateActionButton(Landroid/app/Notification$Action;ZLandroid/app/Notification$StandardTemplateParams;)Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->getActionLayoutResource()I
+HSPLandroid/app/Notification$Builder;->getBackgroundColor(Landroid/app/Notification$StandardTemplateParams;)I
+HSPLandroid/app/Notification$Builder;->getBaseLayoutResource()I
+HSPLandroid/app/Notification$Builder;->getBigBaseLayoutResource()I
+HSPLandroid/app/Notification$Builder;->getHeadsUpStatusBarText(Z)Ljava/lang/CharSequence;
+HSPLandroid/app/Notification$Builder;->getNeutralColor(Landroid/app/Notification$StandardTemplateParams;)I
+HSPLandroid/app/Notification$Builder;->getPrimaryTextColor(Landroid/app/Notification$StandardTemplateParams;)I
+HSPLandroid/app/Notification$Builder;->getProfileBadgeDrawable()Landroid/graphics/drawable/Drawable;
+HSPLandroid/app/Notification$Builder;->getProfileBadge()Landroid/graphics/Bitmap;
+HSPLandroid/app/Notification$Builder;->getRawColor(Landroid/app/Notification$StandardTemplateParams;)I
+HSPLandroid/app/Notification$Builder;->getSecondaryTextColor(Landroid/app/Notification$StandardTemplateParams;)I
+HSPLandroid/app/Notification$Builder;->handleProgressBar(Landroid/widget/RemoteViews;Landroid/os/Bundle;Landroid/app/Notification$StandardTemplateParams;)Z
+HSPLandroid/app/Notification$Builder;->hasForegroundColor()Z
+HSPLandroid/app/Notification$Builder;->hasValidRemoteInput(Landroid/app/Notification$Action;)Z
+HSPLandroid/app/Notification$Builder;->isColorized(Landroid/app/Notification$StandardTemplateParams;)Z
+HSPLandroid/app/Notification$Builder;->isLegacy()Z
+HSPLandroid/app/Notification$Builder;->loadHeaderAppName()Ljava/lang/String;
+HSPLandroid/app/Notification$Builder;->makeHeaderExpanded(Landroid/widget/RemoteViews;)V
+HSPLandroid/app/Notification$Builder;->makeLowPriorityContentView(Z)Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->makeNotificationHeader(Landroid/app/Notification$StandardTemplateParams;)Landroid/widget/RemoteViews;
+HSPLandroid/app/Notification$Builder;->processLargeLegacyIcon(Landroid/graphics/drawable/Icon;Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->processLegacyText(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/app/Notification$Builder;->processSmallIconColor(Landroid/graphics/drawable/Icon;Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->processTextSpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/app/Notification$BuilderRemoteViews;-><init>(Landroid/content/pm/ApplicationInfo;I)V
+HSPLandroid/app/Notification$Builder;->resetNotificationHeader(Landroid/widget/RemoteViews;)V
+HSPLandroid/app/Notification$Builder;->resetStandardTemplate(Landroid/widget/RemoteViews;)V
+HSPLandroid/app/Notification$Builder;->resetStandardTemplateWithActions(Landroid/widget/RemoteViews;)V
+HSPLandroid/app/Notification$Builder;->resolveContrastColor(Landroid/app/Notification$StandardTemplateParams;)I
+HSPLandroid/app/Notification$Builder;->resolveNeutralColor()I
+HSPLandroid/app/Notification$Builder;->setContentMinHeight(Landroid/widget/RemoteViews;Z)V
+HSPLandroid/app/Notification$Builder;->setTextViewColorPrimary(Landroid/widget/RemoteViews;ILandroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->setTextViewColorSecondary(Landroid/widget/RemoteViews;ILandroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$Builder;->showsTimeOrChronometer()Z
+HSPLandroid/app/Notification$Builder;->textColorsNeedInversion()Z
+HSPLandroid/app/Notification$Builder;->updateBackgroundColor(Landroid/widget/RemoteViews;Landroid/app/Notification$StandardTemplateParams;)V
+HSPLandroid/app/Notification$StandardTemplateParams;->disallowColorization()Landroid/app/Notification$StandardTemplateParams;
+HSPLandroid/app/Notification$StandardTemplateParams;->fillTextsFrom(Landroid/app/Notification$Builder;)Landroid/app/Notification$StandardTemplateParams;
+HSPLandroid/app/Notification$StandardTemplateParams;->forceDefaultColor()Landroid/app/Notification$StandardTemplateParams;
+HSPLandroid/app/Notification$StandardTemplateParams;->reset()Landroid/app/Notification$StandardTemplateParams;
+HSPLandroid/app/Notification$StandardTemplateParams;->summaryText(Ljava/lang/CharSequence;)Landroid/app/Notification$StandardTemplateParams;
+HSPLandroid/app/Notification;->access$1300(Landroid/app/Notification;)Landroid/graphics/drawable/Icon;
+HSPLandroid/app/Notification;->access$1602(Landroid/app/Notification;Z)Z
+HSPLandroid/app/Notification;->access$1800(Landroid/app/Notification;)Z
+HSPLandroid/app/Notification;->access$2000(Landroid/app/Notification;)J
+HSPLandroid/app/Notification;->access$2100(Landroid/app/Notification;)Landroid/graphics/drawable/Icon;
+HSPLandroid/app/NotificationChannel;->enableVibration(Z)V
+HSPLandroid/app/NotificationChannel;->setGroup(Ljava/lang/String;)V
+HSPLandroid/app/Notification;->getShortcutId()Ljava/lang/String;
+HSPLandroid/app/Notification;->hasLargeIcon()Z
+HSPLandroid/app/Notification;->isMediaNotification()Z
+HSPLandroid/app/NotificationManager;->cancelAll()V
+HSPLandroid/app/NotificationManager;->getCurrentInterruptionFilter()I
+HSPLandroid/app/NotificationManager;->getEffectsSuppressor()Landroid/content/ComponentName;
+HSPLandroid/app/NotificationManager;->getZenModeConfig()Landroid/service/notification/ZenModeConfig;
+HSPLandroid/app/NotificationManager;->shouldHideSilentStatusBarIcons()Z
+HSPLandroid/app/NotificationManager;->zenModeToInterruptionFilter(I)I
+HSPLandroid/app/Notification;->showsChronometer()Z
+HSPLandroid/app/Notification;->showsTime()Z
+HSPLandroid/app/PendingIntent$1;-><init>(Landroid/app/PendingIntent;)V
+HSPLandroid/app/PendingIntent;->getTarget()Landroid/content/IIntentSender;
+HSPLandroid/app/PendingIntent;->getTargetPackage()Ljava/lang/String;
+HSPLandroid/app/PendingIntent;->registerCancelListener(Landroid/app/PendingIntent$CancelListener;)V
+HSPLandroid/app/PendingIntent;->unregisterCancelListener(Landroid/app/PendingIntent$CancelListener;)V
+HSPLandroid/app/prediction/AppPredictionManager;->createAppPredictionSession(Landroid/app/prediction/AppPredictionContext;)Landroid/app/prediction/AppPredictor;
+HSPLandroid/app/prediction/AppPredictionManager;-><init>(Landroid/content/Context;)V
+HSPLandroid/app/prediction/IPredictionManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/prediction/IPredictionManager;
+HSPLandroid/app/RemoteAction$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/RemoteAction;
+HSPLandroid/app/RemoteAction$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/servertransaction/LaunchActivityItem;->postExecute(Landroid/app/ClientTransactionHandler;Landroid/os/IBinder;Landroid/app/servertransaction/PendingTransactionActions;)V
+HSPLandroid/app/servertransaction/LaunchActivityItem;->setValues(Landroid/app/servertransaction/LaunchActivityItem;Landroid/content/Intent;ILandroid/content/pm/ActivityInfo;Landroid/content/res/Configuration;Landroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;Ljava/lang/String;Lcom/android/internal/app/IVoiceInteractor;ILandroid/os/Bundle;Landroid/os/PersistableBundle;Ljava/util/List;Ljava/util/List;ZLandroid/app/ProfilerInfo;Landroid/os/IBinder;)V
+HSPLandroid/app/Service;->stopSelfResult(I)Z
+HSPLandroid/app/StatsManager;->addConfig(J[B)V
+HSPLandroid/app/StatsManager;->getReports(J)[B
+HSPLandroid/app/StatsManager;->setFetchReportsOperation(Landroid/app/PendingIntent;J)V
+HSPLandroid/app/StatsManager;->setPullerCallback(ILandroid/os/IStatsPullerCallback;)V
+HSPLandroid/app/StatusBarManager;->disable(I)V
+HSPLandroid/app/SystemServiceRegistry$103;->createService(Landroid/app/ContextImpl;)Landroid/app/prediction/AppPredictionManager;
+HSPLandroid/app/SystemServiceRegistry$103;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$15;->createService()Landroid/os/IBinder;
+HSPLandroid/app/SystemServiceRegistry$15;->createService()Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$34;->createService(Landroid/app/ContextImpl;)Landroid/net/nsd/NsdManager;
+HSPLandroid/app/SystemServiceRegistry$34;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$39;->createService(Landroid/app/ContextImpl;)Landroid/hardware/SensorPrivacyManager;
+HSPLandroid/app/SystemServiceRegistry$39;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$86;->createService()Landroid/service/persistentdata/PersistentDataBlockManager;
+HSPLandroid/app/SystemServiceRegistry$86;->createService()Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$88;->createService(Landroid/app/ContextImpl;)Landroid/media/projection/MediaProjectionManager;
+HSPLandroid/app/SystemServiceRegistry$88;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$95;->createService(Landroid/app/ContextImpl;)Landroid/content/om/OverlayManager;
+HSPLandroid/app/SystemServiceRegistry$95;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$98;->createService(Landroid/app/ContextImpl;)Landroid/hardware/location/ContextHubManager;
+HSPLandroid/app/SystemServiceRegistry$98;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/trust/IStrongAuthTracker$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/trust/ITrustListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/app/trust/ITrustListener$Stub;-><init>()V
+HSPLandroid/app/trust/ITrustListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/app/trust/ITrustManager$Stub$Proxy;->clearAllBiometricRecognized(Landroid/hardware/biometrics/BiometricSourceType;)V
+HSPLandroid/app/trust/ITrustManager$Stub$Proxy;->isDeviceSecure(I)Z
+HSPLandroid/app/trust/ITrustManager$Stub$Proxy;->isTrustUsuallyManaged(I)Z
+HSPLandroid/app/trust/ITrustManager$Stub$Proxy;->registerTrustListener(Landroid/app/trust/ITrustListener;)V
+HSPLandroid/app/trust/ITrustManager$Stub$Proxy;->reportKeyguardShowingChanged()V
+HSPLandroid/app/trust/TrustManager$2;->handleMessage(Landroid/os/Message;)V
+HSPLandroid/app/trust/TrustManager;->access$000(Landroid/app/trust/TrustManager;)Landroid/os/Handler;
+HSPLandroid/app/trust/TrustManager;->clearAllBiometricRecognized(Landroid/hardware/biometrics/BiometricSourceType;)V
+HSPLandroid/app/trust/TrustManager;->isTrustUsuallyManaged(I)Z
+HSPLandroid/app/trust/TrustManager;->registerTrustListener(Landroid/app/trust/TrustManager$TrustListener;)V
+HSPLandroid/app/trust/TrustManager;->reportKeyguardShowingChanged()V
+HSPLandroid/app/usage/IUsageStatsManager$Stub$Proxy;->isAppInactive(Ljava/lang/String;I)Z
+HSPLandroid/app/usage/IUsageStatsManager$Stub$Proxy;->queryEvents(JJLjava/lang/String;)Landroid/app/usage/UsageEvents;
+HSPLandroid/app/usage/UsageEvents$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageEvents;
+HSPLandroid/app/usage/UsageEvents$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/usage/UsageEvents$Event;->getClassName()Ljava/lang/String;
+HSPLandroid/app/usage/UsageEvents$Event;->getConfiguration()Landroid/content/res/Configuration;
+HSPLandroid/app/usage/UsageEvents$Event;->getEventType()I
+HSPLandroid/app/usage/UsageEvents$Event;->getPackageName()Ljava/lang/String;
+HSPLandroid/app/usage/UsageEvents$Event;->getTimeStamp()J
+HSPLandroid/app/usage/UsageEvents$Event;-><init>()V
+HSPLandroid/app/usage/UsageEvents;->getNextEvent(Landroid/app/usage/UsageEvents$Event;)Z
+HSPLandroid/app/usage/UsageEvents;->hasNextEvent()Z
+HSPLandroid/app/usage/UsageEvents;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V
+HSPLandroid/app/usage/UsageStats;->getLastTimeStamp()J
+HSPLandroid/app/usage/UsageStatsManager;->isAppInactive(Ljava/lang/String;)Z
+HSPLandroid/app/usage/UsageStatsManager;->queryAndAggregateUsageStats(JJ)Ljava/util/Map;
+HSPLandroid/app/usage/UsageStatsManager;->queryEvents(JJ)Landroid/app/usage/UsageEvents;
+HSPLandroid/app/WallpaperColors;->getColorHints()I
+HSPLandroid/app/WallpaperInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/WallpaperInfo;
+HSPLandroid/app/WallpaperInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/WallpaperManager$Globals;->access$200(Landroid/app/WallpaperManager$Globals;)Landroid/app/IWallpaperManager;
+HSPLandroid/app/WallpaperManager$Globals;->addOnColorsChangedListener(Landroid/app/WallpaperManager$OnColorsChangedListener;Landroid/os/Handler;II)V
+HSPLandroid/app/WallpaperManager$Globals;->lambda$onWallpaperColorsChanged$1$WallpaperManager$Globals(Landroid/util/Pair;Landroid/app/WallpaperColors;II)V
+HSPLandroid/app/WallpaperManager$Globals;->lambda$removeOnColorsChangedListener$0(Landroid/app/WallpaperManager$OnColorsChangedListener;Landroid/util/Pair;)Z
+HSPLandroid/app/WallpaperManager$Globals;->onWallpaperColorsChanged(Landroid/app/WallpaperColors;II)V
+HSPLandroid/app/WallpaperManager$Globals;->removeOnColorsChangedListener(Landroid/app/WallpaperManager$OnColorsChangedListener;II)V
+HSPLandroid/app/WallpaperManager;->access$100()Landroid/app/WallpaperManager$Globals;
+HSPLandroid/app/WallpaperManager;->addOnColorsChangedListener(Landroid/app/WallpaperManager$OnColorsChangedListener;Landroid/os/Handler;I)V
+HSPLandroid/app/WallpaperManager;->addOnColorsChangedListener(Landroid/app/WallpaperManager$OnColorsChangedListener;Landroid/os/Handler;)V
+HSPLandroid/app/WallpaperManager;->getDesiredMinimumHeight()I
+HSPLandroid/app/WallpaperManager;->getDesiredMinimumWidth()I
+HSPLandroid/app/WallpaperManager;->getInstance(Landroid/content/Context;)Landroid/app/WallpaperManager;
+HSPLandroid/app/WallpaperManager;->getWallpaperInfo(I)Landroid/app/WallpaperInfo;
+HSPLandroid/app/WallpaperManager;->getWallpaperInfo()Landroid/app/WallpaperInfo;
+HSPLandroid/app/WallpaperManager;->isWallpaperSupported()Z
+HSPLandroid/app/WallpaperManager;->removeOnColorsChangedListener(Landroid/app/WallpaperManager$OnColorsChangedListener;I)V
+HSPLandroid/app/WallpaperManager;->removeOnColorsChangedListener(Landroid/app/WallpaperManager$OnColorsChangedListener;)V
+HSPLandroid/app/WallpaperManager;->setWallpaperOffsets(Landroid/os/IBinder;FF)V
+HSPLandroid/app/WallpaperManager;->setWallpaperOffsetSteps(FF)V
+HSPLandroid/appwidget/AppWidgetManager;->getInstalledProvidersForProfile(ILandroid/os/UserHandle;Ljava/lang/String;)Ljava/util/List;
+HSPLandroid/appwidget/AppWidgetManager;->getInstalledProvidersForProfile(Landroid/os/UserHandle;)Ljava/util/List;
+HSPLandroid/bluetooth/BluetoothA2dp$1;->getServiceInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothA2dp;
+HSPLandroid/bluetooth/BluetoothA2dp$1;->getServiceInterface(Landroid/os/IBinder;)Ljava/lang/Object;
+HSPLandroid/bluetooth/BluetoothAdapter;->enableBLE()Z
+HSPLandroid/bluetooth/BluetoothAdapter;->getAddress()Ljava/lang/String;
+HSPLandroid/bluetooth/BluetoothAdapter;->getBluetoothLeScanner()Landroid/bluetooth/le/BluetoothLeScanner;
+HSPLandroid/bluetooth/BluetoothAdapter;->getBluetoothManager()Landroid/bluetooth/IBluetoothManager;
+HSPLandroid/bluetooth/BluetoothAdapter;->getConnectionState()I
+HSPLandroid/bluetooth/BluetoothAdapter;->getLeAccess()Z
+HSPLandroid/bluetooth/BluetoothAdapter;->getLeState()I
+HSPLandroid/bluetooth/BluetoothAdapter;->getRemoteDevice(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;
+HSPLandroid/bluetooth/BluetoothAdapter;->isBleScanAlwaysAvailable()Z
+HSPLandroid/bluetooth/BluetoothAdapter;->isLeEnabled()Z
+HSPLandroid/bluetooth/BluetoothAdapter;->isOffloadedFilteringSupported()Z
+HSPLandroid/bluetooth/BluetoothAdapter;->listenUsingInsecureL2capOn(I)Landroid/bluetooth/BluetoothServerSocket;
+HSPLandroid/bluetooth/BluetoothAdapter;->listenUsingInsecureRfcommOn(I)Landroid/bluetooth/BluetoothServerSocket;
+HSPLandroid/bluetooth/BluetoothAdapter;->listenUsingL2capOn(I)Landroid/bluetooth/BluetoothServerSocket;
+HSPLandroid/bluetooth/BluetoothAdapter;->listenUsingL2capOn(IZZ)Landroid/bluetooth/BluetoothServerSocket;
+HSPLandroid/bluetooth/BluetoothAdapter;->listenUsingRfcommOn(I)Landroid/bluetooth/BluetoothServerSocket;
+HSPLandroid/bluetooth/BluetoothAdapter;->listenUsingRfcommOn(IZZ)Landroid/bluetooth/BluetoothServerSocket;
+HSPLandroid/bluetooth/BluetoothClass;-><init>(I)V
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getBitsPerSample()I
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getChannelMode()I
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getCodecPriority()I
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getCodecSpecific1()J
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getCodecSpecific2()J
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getCodecSpecific3()J
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getCodecSpecific4()J
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getCodecType()I
+HSPLandroid/bluetooth/BluetoothCodecConfig;->getSampleRate()I
+HSPLandroid/bluetooth/BluetoothCodecConfig;-><init>(IIIIIJJJJ)V
+HSPLandroid/bluetooth/BluetoothDevice;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/bluetooth/BluetoothHeadset;->isInbandRingingSupported(Landroid/content/Context;)Z
+HSPLandroid/bluetooth/BluetoothInputStream;-><init>(Landroid/bluetooth/BluetoothSocket;)V
+HSPLandroid/bluetooth/BluetoothManager;->getAdapter()Landroid/bluetooth/BluetoothAdapter;
+HSPLandroid/bluetooth/BluetoothOutputStream;-><init>(Landroid/bluetooth/BluetoothSocket;)V
+HSPLandroid/bluetooth/BluetoothPbap;->access$000(Ljava/lang/String;)V
+HSPLandroid/bluetooth/BluetoothPbap;->log(Ljava/lang/String;)V
+HSPLandroid/bluetooth/BluetoothProfileConnector;->access$000(Landroid/bluetooth/BluetoothProfileConnector;)Z
+HSPLandroid/bluetooth/BluetoothProfileConnector;->access$200(Landroid/bluetooth/BluetoothProfileConnector;Ljava/lang/String;)V
+HSPLandroid/bluetooth/BluetoothProfileConnector;->access$302(Landroid/bluetooth/BluetoothProfileConnector;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/bluetooth/BluetoothProfileConnector;->access$400(Landroid/bluetooth/BluetoothProfileConnector;)Landroid/bluetooth/BluetoothProfile$ServiceListener;
+HSPLandroid/bluetooth/BluetoothProfileConnector;->access$500(Landroid/bluetooth/BluetoothProfileConnector;)I
+HSPLandroid/bluetooth/BluetoothProfileConnector;->access$600(Landroid/bluetooth/BluetoothProfileConnector;)Landroid/bluetooth/BluetoothProfile;
+HSPLandroid/bluetooth/BluetoothProfileConnector;->connect(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
+HSPLandroid/bluetooth/BluetoothProfileConnector;->doBind()Z
+HSPLandroid/bluetooth/BluetoothProfileConnector;->getService()Ljava/lang/Object;
+HSPLandroid/bluetooth/BluetoothProfileConnector;->logDebug(Ljava/lang/String;)V
+HSPLandroid/bluetooth/BluetoothServerSocket;->accept(I)Landroid/bluetooth/BluetoothSocket;
+HSPLandroid/bluetooth/BluetoothServerSocket;->accept()Landroid/bluetooth/BluetoothSocket;
+HSPLandroid/bluetooth/BluetoothServerSocket;->getChannel()I
+HSPLandroid/bluetooth/BluetoothServerSocket;-><init>(IZZI)V
+HSPLandroid/bluetooth/BluetoothServerSocket;-><init>(IZZIZZ)V
+HSPLandroid/bluetooth/BluetoothServerSocket;->setChannel(I)V
+HSPLandroid/bluetooth/BluetoothSocket;->accept(I)Landroid/bluetooth/BluetoothSocket;
+HSPLandroid/bluetooth/BluetoothSocket;->bindListen()I
+HSPLandroid/bluetooth/BluetoothSocket;->getPort()I
+HSPLandroid/bluetooth/BluetoothSocket;->getSecurityFlags()I
+HSPLandroid/bluetooth/BluetoothSocket;-><init>(IIZZLandroid/bluetooth/BluetoothDevice;ILandroid/os/ParcelUuid;)V
+HSPLandroid/bluetooth/BluetoothSocket;-><init>(IIZZLandroid/bluetooth/BluetoothDevice;ILandroid/os/ParcelUuid;ZZ)V
+HSPLandroid/bluetooth/BluetoothSocket;->readAll(Ljava/io/InputStream;[B)I
+HSPLandroid/bluetooth/BluetoothSocket;->readInt(Ljava/io/InputStream;)I
+HSPLandroid/bluetooth/BluetoothSocket;->setExcludeSdp(Z)V
+HSPLandroid/bluetooth/BluetoothSocket;->waitSocketSignal(Ljava/io/InputStream;)Ljava/lang/String;
+HSPLandroid/bluetooth/BluetoothUuid;->getServiceIdentifierFromParcelUuid(Landroid/os/ParcelUuid;)I
+HSPLandroid/bluetooth/BluetoothUuid;->is16BitUuid(Landroid/os/ParcelUuid;)Z
+HSPLandroid/bluetooth/BluetoothUuid;->parseUuidFrom([B)Landroid/os/ParcelUuid;
+HSPLandroid/bluetooth/BluetoothUuid;->uuidToBytes(Landroid/os/ParcelUuid;)[B
+HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->getAdapterConnectionState()I
+HSPLandroid/bluetooth/IBluetooth$Stub$Proxy;->isOffloadedFilteringSupported()Z
+HSPLandroid/bluetooth/IBluetooth$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetooth$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/bluetooth/IBluetoothA2dp$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/bluetooth/IBluetoothA2dp$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothA2dp;
+HSPLandroid/bluetooth/IBluetoothA2dp$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothA2dp$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/bluetooth/IBluetoothAvrcpTarget$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLandroid/bluetooth/IBluetoothCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/bluetooth/IBluetoothCallback$Stub$Proxy;->onBluetoothStateChange(II)V
+HSPLandroid/bluetooth/IBluetoothCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothCallback;
+HSPLandroid/bluetooth/IBluetoothGatt$Stub$Proxy;->registerScanner(Landroid/bluetooth/le/IScannerCallback;Landroid/os/WorkSource;)V
+HSPLandroid/bluetooth/IBluetoothGatt$Stub$Proxy;->startScan(ILandroid/bluetooth/le/ScanSettings;Ljava/util/List;Ljava/util/List;Ljava/lang/String;)V
+HSPLandroid/bluetooth/IBluetoothGatt$Stub$Proxy;->stopScan(I)V
+HSPLandroid/bluetooth/IBluetoothGatt$Stub$Proxy;->unregisterScanner(I)V
+HSPLandroid/bluetooth/IBluetoothGatt$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothGatt$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/bluetooth/IBluetoothHeadset$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothHeadset$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/bluetooth/IBluetoothHeadsetPhone$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHeadsetPhone;
+HSPLandroid/bluetooth/IBluetoothHidDevice$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHidDevice;
+HSPLandroid/bluetooth/IBluetoothHidDevice$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothHidDevice$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/bluetooth/IBluetoothHidHost$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHidHost;
+HSPLandroid/bluetooth/IBluetoothHidHost$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothHidHost$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/bluetooth/IBluetoothManager$Stub$Proxy;->getAddress()Ljava/lang/String;
+HSPLandroid/bluetooth/IBluetoothManager$Stub$Proxy;->getBluetoothGatt()Landroid/bluetooth/IBluetoothGatt;
+HSPLandroid/bluetooth/IBluetoothManager$Stub$Proxy;->isBleScanAlwaysAvailable()Z
+HSPLandroid/bluetooth/IBluetoothManager$Stub$Proxy;->updateBleAppCount(Landroid/os/IBinder;ZLjava/lang/String;)I
+HSPLandroid/bluetooth/IBluetoothMap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothMap;
+HSPLandroid/bluetooth/IBluetoothMap$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothMap$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/bluetooth/IBluetoothPan$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothPan;
+HSPLandroid/bluetooth/IBluetoothPan$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothPbap$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothSap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothSap;
+HSPLandroid/bluetooth/IBluetoothSap$Stub;-><init>()V
+HSPLandroid/bluetooth/IBluetoothSap$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/bluetooth/IBluetoothSocketManager$Stub$Proxy;->createSocketChannel(ILjava/lang/String;Landroid/os/ParcelUuid;II)Landroid/os/ParcelFileDescriptor;
+HSPLandroid/bluetooth/IBluetoothSocketManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/bluetooth/IBluetoothSocketManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothSocketManager;
+HSPLandroid/bluetooth/le/IScannerCallback$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLandroid/bluetooth/le/IScannerCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/bluetooth/le/IScannerCallback$Stub$Proxy;->onScannerRegistered(II)V
+HSPLandroid/bluetooth/le/IScannerCallback$Stub$Proxy;->onScanResult(Landroid/bluetooth/le/ScanResult;)V
+HSPLandroid/bluetooth/le/ScanFilter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/bluetooth/le/ScanFilter;
+HSPLandroid/bluetooth/le/ScanFilter$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/bluetooth/le/ScanFilter$Builder;->setManufacturerData(I[B[B)Landroid/bluetooth/le/ScanFilter$Builder;
+HSPLandroid/bluetooth/le/ScanFilter$Builder;->setServiceData(Landroid/os/ParcelUuid;[B)Landroid/bluetooth/le/ScanFilter$Builder;
+HSPLandroid/bluetooth/le/ScanFilter$Builder;->setServiceUuid(Landroid/os/ParcelUuid;)Landroid/bluetooth/le/ScanFilter$Builder;
+HSPLandroid/bluetooth/le/ScanFilter;->getDeviceAddress()Ljava/lang/String;
+HSPLandroid/bluetooth/le/ScanFilter;->getDeviceName()Ljava/lang/String;
+HSPLandroid/bluetooth/le/ScanFilter;->getManufacturerData()[B
+HSPLandroid/bluetooth/le/ScanFilter;->getManufacturerDataMask()[B
+HSPLandroid/bluetooth/le/ScanFilter;->getManufacturerId()I
+HSPLandroid/bluetooth/le/ScanFilter;->getServiceData()[B
+HSPLandroid/bluetooth/le/ScanFilter;->getServiceDataMask()[B
+HSPLandroid/bluetooth/le/ScanFilter;->getServiceDataUuid()Landroid/os/ParcelUuid;
+HSPLandroid/bluetooth/le/ScanFilter;->getServiceSolicitationUuid()Landroid/os/ParcelUuid;
+HSPLandroid/bluetooth/le/ScanFilter;->getServiceUuid()Landroid/os/ParcelUuid;
+HSPLandroid/bluetooth/le/ScanFilter;->getServiceUuidMask()Landroid/os/ParcelUuid;
+HSPLandroid/bluetooth/le/ScanFilter;->matches(Landroid/bluetooth/le/ScanResult;)Z
+HSPLandroid/bluetooth/le/ScanFilter;->matchesPartialData([B[B[B)Z
+HSPLandroid/bluetooth/le/ScanFilter;->matchesServiceUuid(Ljava/util/UUID;Ljava/util/UUID;Ljava/util/UUID;)Z
+HSPLandroid/bluetooth/le/ScanFilter;->matchesServiceUuids(Landroid/os/ParcelUuid;Landroid/os/ParcelUuid;Ljava/util/List;)Z
+HSPLandroid/bluetooth/le/ScanFilter;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/bluetooth/le/ScanRecord;->extractBytes([BII)[B
+HSPLandroid/bluetooth/le/ScanRecord;->getBytes()[B
+HSPLandroid/bluetooth/le/ScanRecord;->getManufacturerSpecificData(I)[B
+HSPLandroid/bluetooth/le/ScanRecord;->getServiceData(Landroid/os/ParcelUuid;)[B
+HSPLandroid/bluetooth/le/ScanRecord;->getServiceUuids()Ljava/util/List;
+HSPLandroid/bluetooth/le/ScanRecord;-><init>(Ljava/util/List;Ljava/util/List;Landroid/util/SparseArray;Ljava/util/Map;IILjava/lang/String;[B)V
+HSPLandroid/bluetooth/le/ScanRecord;->parseFromBytes([B)Landroid/bluetooth/le/ScanRecord;
+HSPLandroid/bluetooth/le/ScanRecord;->parseServiceUuid([BIIILjava/util/List;)I
+HSPLandroid/bluetooth/le/ScanResult$1;->createFromParcel(Landroid/os/Parcel;)Landroid/bluetooth/le/ScanResult;
+HSPLandroid/bluetooth/le/ScanResult$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/bluetooth/le/ScanResult;->getDevice()Landroid/bluetooth/BluetoothDevice;
+HSPLandroid/bluetooth/le/ScanResult;->getRssi()I
+HSPLandroid/bluetooth/le/ScanResult;->getScanRecord()Landroid/bluetooth/le/ScanRecord;
+HSPLandroid/bluetooth/le/ScanResult;->getTimestampNanos()J
+HSPLandroid/bluetooth/le/ScanResult;-><init>(Landroid/bluetooth/BluetoothDevice;IIIIIIILandroid/bluetooth/le/ScanRecord;J)V
+HSPLandroid/bluetooth/le/ScanResult;-><init>(Landroid/os/Parcel;Landroid/bluetooth/le/ScanResult$1;)V
+HSPLandroid/bluetooth/le/ScanResult;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/bluetooth/le/ScanResult;->readFromParcel(Landroid/os/Parcel;)V
+HSPLandroid/bluetooth/le/ScanResult;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/bluetooth/le/ScanSettings$1;->createFromParcel(Landroid/os/Parcel;)Landroid/bluetooth/le/ScanSettings;
+HSPLandroid/bluetooth/le/ScanSettings$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/bluetooth/le/ScanSettings$Builder;->build()Landroid/bluetooth/le/ScanSettings;
+HSPLandroid/bluetooth/le/ScanSettings$Builder;-><init>()V
+HSPLandroid/bluetooth/le/ScanSettings$Builder;->isValidCallbackType(I)Z
+HSPLandroid/bluetooth/le/ScanSettings$Builder;->setCallbackType(I)Landroid/bluetooth/le/ScanSettings$Builder;
+HSPLandroid/bluetooth/le/ScanSettings$Builder;->setMatchMode(I)Landroid/bluetooth/le/ScanSettings$Builder;
+HSPLandroid/bluetooth/le/ScanSettings$Builder;->setNumOfMatches(I)Landroid/bluetooth/le/ScanSettings$Builder;
+HSPLandroid/bluetooth/le/ScanSettings$Builder;->setReportDelay(J)Landroid/bluetooth/le/ScanSettings$Builder;
+HSPLandroid/bluetooth/le/ScanSettings$Builder;->setScanMode(I)Landroid/bluetooth/le/ScanSettings$Builder;
+HSPLandroid/bluetooth/le/ScanSettings;->getCallbackType()I
+HSPLandroid/bluetooth/le/ScanSettings;->getLegacy()Z
+HSPLandroid/bluetooth/le/ScanSettings;->getMatchMode()I
+HSPLandroid/bluetooth/le/ScanSettings;->getReportDelayMillis()J
+HSPLandroid/bluetooth/le/ScanSettings;->getScanMode()I
+HSPLandroid/bluetooth/le/ScanSettings;-><init>(IIIJIIZILandroid/bluetooth/le/ScanSettings$1;)V
+HSPLandroid/bluetooth/le/ScanSettings;-><init>(IIIJIIZI)V
+HSPLandroid/bluetooth/le/ScanSettings;-><init>(Landroid/os/Parcel;Landroid/bluetooth/le/ScanSettings$1;)V
+HSPLandroid/bluetooth/le/ScanSettings;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/bluetooth/le/ScanSettings;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/-$$Lambda$AbstractThreadedSyncAdapter$ISyncAdapterImpl$L6ZtOCe8gjKwJj0908ytPlrD8Rc;->accept(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;-><init>(Landroid/content/AbstractThreadedSyncAdapter;Landroid/content/AbstractThreadedSyncAdapter$1;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;-><init>(Landroid/content/AbstractThreadedSyncAdapter;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->lambda$onUnsyncableAccount$0(Ljava/lang/Object;Landroid/content/ISyncAdapterUnsyncableAccountCallback;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->onUnsyncableAccount(Landroid/content/ISyncAdapterUnsyncableAccountCallback;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->startSync(Landroid/content/ISyncContext;Ljava/lang/String;Landroid/accounts/Account;Landroid/os/Bundle;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter$SyncThread;-><init>(Landroid/content/AbstractThreadedSyncAdapter;Ljava/lang/String;Landroid/content/SyncContext;Ljava/lang/String;Landroid/accounts/Account;Landroid/os/Bundle;Landroid/content/AbstractThreadedSyncAdapter$1;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter$SyncThread;-><init>(Landroid/content/AbstractThreadedSyncAdapter;Ljava/lang/String;Landroid/content/SyncContext;Ljava/lang/String;Landroid/accounts/Account;Landroid/os/Bundle;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter$SyncThread;->isCanceled()Z
+HSPLandroid/content/AbstractThreadedSyncAdapter$SyncThread;->run()V
+HSPLandroid/content/AbstractThreadedSyncAdapter;->access$100()Z
+HSPLandroid/content/AbstractThreadedSyncAdapter;->access$1200(Landroid/content/AbstractThreadedSyncAdapter;Landroid/content/ISyncAdapterUnsyncableAccountCallback;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter;->access$1300(Landroid/content/AbstractThreadedSyncAdapter;)Landroid/content/Context;
+HSPLandroid/content/AbstractThreadedSyncAdapter;->access$200(Landroid/content/AbstractThreadedSyncAdapter;Landroid/accounts/Account;)Landroid/accounts/Account;
+HSPLandroid/content/AbstractThreadedSyncAdapter;->access$300(Landroid/content/AbstractThreadedSyncAdapter;)Ljava/lang/Object;
+HSPLandroid/content/AbstractThreadedSyncAdapter;->access$400(Landroid/content/AbstractThreadedSyncAdapter;)Ljava/util/HashMap;
+HSPLandroid/content/AbstractThreadedSyncAdapter;->access$500(Landroid/content/AbstractThreadedSyncAdapter;)Z
+HSPLandroid/content/AbstractThreadedSyncAdapter;->access$600(Landroid/content/AbstractThreadedSyncAdapter;)Ljava/util/concurrent/atomic/AtomicInteger;
+HSPLandroid/content/AbstractThreadedSyncAdapter;->getContext()Landroid/content/Context;
+HSPLandroid/content/AbstractThreadedSyncAdapter;->getSyncAdapterBinder()Landroid/os/IBinder;
+HSPLandroid/content/AbstractThreadedSyncAdapter;->handleOnUnsyncableAccount(Landroid/content/ISyncAdapterUnsyncableAccountCallback;)V
+HSPLandroid/content/AbstractThreadedSyncAdapter;-><init>(Landroid/content/Context;ZZ)V
+HSPLandroid/content/AbstractThreadedSyncAdapter;->onUnsyncableAccount()Z
+HSPLandroid/content/AbstractThreadedSyncAdapter;->toSyncKey(Landroid/accounts/Account;)Landroid/accounts/Account;
+HSPLandroid/content/ComponentName;-><init>(Ljava/lang/String;Landroid/os/Parcel;)V
+HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;
+HSPLandroid/content/ContentProvider;->call(Ljava/lang/String;Ljava/lang/String;Landroid/os/Bundle;)Landroid/os/Bundle;
+HSPLandroid/content/ContentProviderClient$CursorWrapperInner;->close()V
+HSPLandroid/content/ContentProviderClient$CursorWrapperInner;->finalize()V
+HSPLandroid/content/ContentProviderClient;->getLocalContentProvider()Landroid/content/ContentProvider;
+HSPLandroid/content/ContentProvider;->coerceToLocalContentProvider(Landroid/content/IContentProvider;)Landroid/content/ContentProvider;
+HSPLandroid/content/ContentProvider;->onCallingPackageChanged()V
+HSPLandroid/content/ContentResolver;->acquireUnstableContentProviderClient(Ljava/lang/String;)Landroid/content/ContentProviderClient;
+HSPLandroid/content/ContentResolver;->acquireUnstableProvider(Ljava/lang/String;)Landroid/content/IContentProvider;
+HSPLandroid/content/ContentResolver;->addPeriodicSync(Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;J)V
+HSPLandroid/content/ContentResolver;->getContentService()Landroid/content/IContentService;
+HSPLandroid/content/ContentResolver;->getMasterSyncAutomatically()Z
+HSPLandroid/content/ContentResolver;->getSyncAutomatically(Landroid/accounts/Account;Ljava/lang/String;)Z
+HSPLandroid/content/ContentResolver;->invalidPeriodicExtras(Landroid/os/Bundle;)Z
+HSPLandroid/content/ContentResolver;->removePeriodicSync(Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;)V
+HSPLandroid/content/ContentResolver;->requestSyncAsUser(Landroid/accounts/Account;Ljava/lang/String;ILandroid/os/Bundle;)V
+HSPLandroid/content/ContentResolver;->requestSync(Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;)V
+HSPLandroid/content/ContentResolver;->setIsSyncable(Landroid/accounts/Account;Ljava/lang/String;I)V
+HSPLandroid/content/ContentResolver;->setSyncAutomaticallyAsUser(Landroid/accounts/Account;Ljava/lang/String;ZI)V
+HSPLandroid/content/ContentResolver;->setSyncAutomatically(Landroid/accounts/Account;Ljava/lang/String;Z)V
+HSPLandroid/content/ContentResolver;->validateSyncExtrasBundle(Landroid/os/Bundle;)V
+HSPLandroid/content/ContentValues;->getAsByteArray(Ljava/lang/String;)[B
+HSPLandroid/content/ContentValues;->valueSet()Ljava/util/Set;
+HSPLandroid/content/Context;->registerComponentCallbacks(Landroid/content/ComponentCallbacks;)V
+HSPLandroid/content/ContextWrapper;->databaseList()[Ljava/lang/String;
+HSPLandroid/content/ContextWrapper;->deleteDatabase(Ljava/lang/String;)Z
+HSPLandroid/content/ContextWrapper;->deleteFile(Ljava/lang/String;)Z
+HSPLandroid/content/ContextWrapper;->getThemeResId()I
+HSPLandroid/content/ContextWrapper;->moveSharedPreferencesFrom(Landroid/content/Context;Ljava/lang/String;)Z
+HSPLandroid/content/ContextWrapper;->openOrCreateDatabase(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;)Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/content/ContextWrapper;->updateDisplay(I)V
+HSPLandroid/content/IClipboard$Stub$Proxy;->addPrimaryClipChangedListener(Landroid/content/IOnPrimaryClipChangedListener;Ljava/lang/String;I)V
+HSPLandroid/content/IContentService$Stub$Proxy;->addPeriodicSync(Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;J)V
+HSPLandroid/content/IContentService$Stub$Proxy;->getMasterSyncAutomatically()Z
+HSPLandroid/content/IContentService$Stub$Proxy;->getSyncAutomatically(Landroid/accounts/Account;Ljava/lang/String;)Z
+HSPLandroid/content/IContentService$Stub$Proxy;->removePeriodicSync(Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;)V
+HSPLandroid/content/IContentService$Stub$Proxy;->setIsSyncable(Landroid/accounts/Account;Ljava/lang/String;I)V
+HSPLandroid/content/IContentService$Stub$Proxy;->setSyncAutomaticallyAsUser(Landroid/accounts/Account;Ljava/lang/String;ZI)V
+HSPLandroid/content/IContentService$Stub$Proxy;->syncAsUser(Landroid/content/SyncRequest;ILjava/lang/String;)V
+HSPLandroid/content/IIntentReceiver$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/content/IntentFilter;->matchAction(Ljava/lang/String;)Z
+HSPLandroid/content/Intent;->putExtras(Landroid/content/Intent;)Landroid/content/Intent;
+HSPLandroid/content/ISyncAdapter$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/content/ISyncAdapter$Stub;-><init>()V
+HSPLandroid/content/ISyncAdapter$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub$Proxy;->onUnsyncableAccountDone(Z)V
+HSPLandroid/content/ISyncAdapterUnsyncableAccountCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/ISyncAdapterUnsyncableAccountCallback;
+HSPLandroid/content/ISyncContext$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/content/ISyncContext$Stub$Proxy;->onFinished(Landroid/content/SyncResult;)V
+HSPLandroid/content/ISyncContext$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/ISyncContext;
+HSPLandroid/content/om/OverlayManager;-><init>(Landroid/content/Context;Landroid/content/om/IOverlayManager;)V
+HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Ljava/util/List;)V
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->addOnAppsChangedListener(Ljava/lang/String;Landroid/content/pm/IOnAppsChangedListener;)V
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->getAllSessions(Ljava/lang/String;)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->getLauncherActivities(Ljava/lang/String;Ljava/lang/String;Landroid/os/UserHandle;)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->getShortcutConfigActivities(Ljava/lang/String;Ljava/lang/String;Landroid/os/UserHandle;)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->getShortcuts(Ljava/lang/String;JLjava/lang/String;Ljava/util/List;Landroid/content/ComponentName;ILandroid/os/UserHandle;)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->hasShortcutHostPermission(Ljava/lang/String;)Z
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->isActivityEnabled(Ljava/lang/String;Landroid/content/ComponentName;Landroid/os/UserHandle;)Z
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->isPackageEnabled(Ljava/lang/String;Ljava/lang/String;Landroid/os/UserHandle;)Z
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->resolveActivity(Ljava/lang/String;Landroid/content/ComponentName;Landroid/os/UserHandle;)Landroid/content/pm/ActivityInfo;
+HSPLandroid/content/pm/ILauncherApps$Stub$Proxy;->shouldHideFromSuggestions(Ljava/lang/String;Landroid/os/UserHandle;)Z
+HSPLandroid/content/pm/IOnAppsChangedListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/content/pm/IOnAppsChangedListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/content/pm/IPackageInstaller$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/content/pm/IPackageInstaller$Stub$Proxy;->registerCallback(Landroid/content/pm/IPackageInstallerCallback;I)V
+HSPLandroid/content/pm/IPackageInstaller$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageInstaller;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->addOnPermissionsChangeListener(Landroid/content/pm/IOnPermissionsChangeListener;)V
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInstaller()Landroid/content/pm/IPackageInstaller;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesHoldingPermissions([Ljava/lang/String;II)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getServicesSystemSharedLibraryPackageName()Ljava/lang/String;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getSharedSystemSharedLibraryPackageName()Ljava/lang/String;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getSystemAvailableFeatures()Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->isSafeMode()Z
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->registerMoveCallback(Landroid/content/pm/IPackageMoveObserver;)V
+HSPLandroid/content/pm/IPackageMoveObserver$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/content/pm/IPackageMoveObserver$Stub;-><init>()V
+HSPLandroid/content/pm/LauncherApps$1;->onPackageChanged(Landroid/os/UserHandle;Ljava/lang/String;)V
+HSPLandroid/content/pm/LauncherApps$1;->onShortcutChanged(Landroid/os/UserHandle;Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
+HSPLandroid/content/pm/LauncherApps;->access$100(Landroid/content/pm/LauncherApps;)Ljava/util/List;
+HSPLandroid/content/pm/LauncherApps;->addCallbackLocked(Landroid/content/pm/LauncherApps$Callback;Landroid/os/Handler;)V
+HSPLandroid/content/pm/LauncherApps;->convertToActivityList(Landroid/content/pm/ParceledListSlice;Landroid/os/UserHandle;)Ljava/util/List;
+HSPLandroid/content/pm/LauncherApps;->findCallbackLocked(Landroid/content/pm/LauncherApps$Callback;)I
+HSPLandroid/content/pm/LauncherApps;->getActivityList(Ljava/lang/String;Landroid/os/UserHandle;)Ljava/util/List;
+HSPLandroid/content/pm/LauncherApps;->getAllPackageInstallerSessions()Ljava/util/List;
+HSPLandroid/content/pm/LauncherApps;->getShortcutConfigActivityList(Ljava/lang/String;Landroid/os/UserHandle;)Ljava/util/List;
+HSPLandroid/content/pm/LauncherApps;->getShortcuts(Landroid/content/pm/LauncherApps$ShortcutQuery;Landroid/os/UserHandle;)Ljava/util/List;
+HSPLandroid/content/pm/LauncherApps;->hasShortcutHostPermission()Z
+HSPLandroid/content/pm/LauncherApps;->isActivityEnabled(Landroid/content/ComponentName;Landroid/os/UserHandle;)Z
+HSPLandroid/content/pm/LauncherApps;->isPackageEnabled(Ljava/lang/String;Landroid/os/UserHandle;)Z
+HSPLandroid/content/pm/LauncherApps;->logErrorForInvalidProfileAccess(Landroid/os/UserHandle;)V
+HSPLandroid/content/pm/LauncherApps;->maybeUpdateDisabledMessage(Ljava/util/List;)Ljava/util/List;
+HSPLandroid/content/pm/LauncherApps;->registerCallback(Landroid/content/pm/LauncherApps$Callback;Landroid/os/Handler;)V
+HSPLandroid/content/pm/LauncherApps;->registerCallback(Landroid/content/pm/LauncherApps$Callback;)V
+HSPLandroid/content/pm/LauncherApps;->removeCallbackLocked(Landroid/content/pm/LauncherApps$Callback;)V
+HSPLandroid/content/pm/LauncherApps;->resolveActivity(Landroid/content/Intent;Landroid/os/UserHandle;)Landroid/content/pm/LauncherActivityInfo;
+HSPLandroid/content/pm/LauncherApps;->shouldHideFromSuggestions(Ljava/lang/String;Landroid/os/UserHandle;)Z
+HSPLandroid/content/pm/PackageInfo;-><init>()V
+HSPLandroid/content/pm/PackageInstaller$SessionCallback;-><init>()V
+HSPLandroid/content/pm/PackageInstaller;->registerSessionCallback(Landroid/content/pm/PackageInstaller$SessionCallback;)V
+HSPLandroid/content/pm/PackageManager;->getPackageArchiveInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;
+HSPLandroid/content/pm/PackageParser$CallbackImpl;->getOverlayPaths(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
+HSPLandroid/content/pm/PackageParser$CallbackImpl;->hasFeature(Ljava/lang/String;)Z
+HSPLandroid/content/pm/PackageParser$CallbackImpl;-><init>(Landroid/content/pm/PackageManager;)V
+HSPLandroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;)Landroid/content/pm/PackageInfo;
+HSPLandroid/content/pm/ParceledListSlice;-><init>(Ljava/util/List;)V
+HSPLandroid/content/pm/ServiceInfo$1;->newArray(I)[Landroid/content/pm/ServiceInfo;
+HSPLandroid/content/pm/ServiceInfo$1;->newArray(I)[Ljava/lang/Object;
+HSPLandroid/content/pm/ShortcutInfo;->getActivity()Landroid/content/ComponentName;
+HSPLandroid/content/pm/ShortcutInfo;->getDisabledReasonForRestoreIssue(Landroid/content/Context;I)Ljava/lang/String;
+HSPLandroid/content/pm/ShortcutInfo;->getDisabledReason()I
+HSPLandroid/content/pm/ShortcutInfo;->getPackage()Ljava/lang/String;
+HSPLandroid/content/pm/ShortcutInfo;->getUserHandle()Landroid/os/UserHandle;
+HSPLandroid/content/pm/ShortcutInfo;->hasFlags(I)Z
+HSPLandroid/content/pm/ShortcutInfo;->isDeclaredInManifest()Z
+HSPLandroid/content/pm/ShortcutInfo;->isDynamic()Z
+HSPLandroid/content/pm/ShortcutInfo;->isEnabled()Z
+HSPLandroid/content/res/ApkAssets;->close()V
+HSPLandroid/content/res/AssetFileDescriptor;-><init>(Landroid/os/ParcelFileDescriptor;JJ)V
+HSPLandroid/content/res/AssetManager;->isUpToDate()Z
+HSPLandroid/content/res/AssetManager;->openFd(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;
+HSPLandroid/content/res/ComplexColor;-><init>()V
+HSPLandroid/content/res/Configuration;->isOtherSeqNewer(Landroid/content/res/Configuration;)Z
+HSPLandroid/content/res/ConstantState;-><init>()V
+HSPLandroid/content/res/GradientColor;->access$000(Landroid/content/res/GradientColor;)I
+HSPLandroid/content/res/GradientColor;->canApplyTheme()Z
+HSPLandroid/content/res/GradientColor;->createFromXmlInner(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)Landroid/content/res/GradientColor;
+HSPLandroid/content/res/GradientColor;->getConstantState()Landroid/content/res/ConstantState;
+HSPLandroid/content/res/GradientColor;->getDefaultColor()I
+HSPLandroid/content/res/GradientColor;->getShader()Landroid/graphics/Shader;
+HSPLandroid/content/res/GradientColor;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
+HSPLandroid/content/res/GradientColor;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
+HSPLandroid/content/res/GradientColor;-><init>()V
+HSPLandroid/content/res/GradientColor;->onColorsChange()V
+HSPLandroid/content/res/GradientColor;->parseTileMode(I)Landroid/graphics/Shader$TileMode;
+HSPLandroid/content/res/GradientColor;->updateRootElementState(Landroid/content/res/TypedArray;)V
+HSPLandroid/content/res/GradientColor;->validateXmlContent()V
+HSPLandroid/content/res/Resources;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/ResourcesImpl;->loadColorOrXmlDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILjava/lang/String;)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/res/StringBlock;->close()V
+HSPLandroid/content/res/TypedArray;->getThemeAttributeId(II)I
+HSPLandroid/content/SyncContext;-><init>(Landroid/content/ISyncContext;)V
+HSPLandroid/content/SyncContext;->onFinished(Landroid/content/SyncResult;)V
+HSPLandroid/content/SyncRequest$Builder;->access$1000(Landroid/content/SyncRequest$Builder;)Z
+HSPLandroid/content/SyncRequest$Builder;->access$100(Landroid/content/SyncRequest$Builder;)J
+HSPLandroid/content/SyncRequest$Builder;->access$200(Landroid/content/SyncRequest$Builder;)J
+HSPLandroid/content/SyncRequest$Builder;->access$300(Landroid/content/SyncRequest$Builder;)Landroid/accounts/Account;
+HSPLandroid/content/SyncRequest$Builder;->access$400(Landroid/content/SyncRequest$Builder;)Ljava/lang/String;
+HSPLandroid/content/SyncRequest$Builder;->access$500(Landroid/content/SyncRequest$Builder;)I
+HSPLandroid/content/SyncRequest$Builder;->access$600(Landroid/content/SyncRequest$Builder;)I
+HSPLandroid/content/SyncRequest$Builder;->access$700(Landroid/content/SyncRequest$Builder;)Z
+HSPLandroid/content/SyncRequest$Builder;->access$800(Landroid/content/SyncRequest$Builder;)Landroid/os/Bundle;
+HSPLandroid/content/SyncRequest$Builder;->access$900(Landroid/content/SyncRequest$Builder;)Landroid/os/Bundle;
+HSPLandroid/content/SyncRequest$Builder;->build()Landroid/content/SyncRequest;
+HSPLandroid/content/SyncRequest$Builder;-><init>()V
+HSPLandroid/content/SyncRequest$Builder;->setExtras(Landroid/os/Bundle;)Landroid/content/SyncRequest$Builder;
+HSPLandroid/content/SyncRequest$Builder;->setSyncAdapter(Landroid/accounts/Account;Ljava/lang/String;)Landroid/content/SyncRequest$Builder;
+HSPLandroid/content/SyncRequest$Builder;->setupInterval(JJ)V
+HSPLandroid/content/SyncRequest$Builder;->syncOnce()Landroid/content/SyncRequest$Builder;
+HSPLandroid/content/SyncRequest;-><init>(Landroid/content/SyncRequest$Builder;)V
+HSPLandroid/content/SyncRequest;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/SyncResult;-><init>()V
+HSPLandroid/content/SyncResult;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/SyncStats;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/database/AbstractCursor$SelfContentObserver;-><init>(Landroid/database/AbstractCursor;)V
+HSPLandroid/database/AbstractCursor;->getExtras()Landroid/os/Bundle;
+HSPLandroid/database/AbstractCursor;->setNotificationUris(Landroid/content/ContentResolver;Ljava/util/List;IZ)V
+HSPLandroid/database/AbstractWindowedCursor;->setWindow(Landroid/database/CursorWindow;)V
+HSPLandroid/database/CrossProcessCursorWrapper;->getWindow()Landroid/database/CursorWindow;
+HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;)V
+HSPLandroid/database/CursorWindow;-><init>(Z)V
+HSPLandroid/database/CursorWindow;->putBlob([BII)Z
+HSPLandroid/database/CursorWindow;->putDouble(DII)Z
+HSPLandroid/database/CursorWrapper;->getExtras()Landroid/os/Bundle;
+HSPLandroid/database/CursorWrapper;->getWantsAllOnMoveCalls()Z
+HSPLandroid/database/CursorWrapper;->getWrappedCursor()Landroid/database/Cursor;
+HSPLandroid/database/DatabaseUtils;->queryNumEntries(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;)J
+HSPLandroid/database/DatabaseUtils;->queryNumEntries(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)J
+HSPLandroid/database/DatabaseUtils;->stringForQuery(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/DatabaseUtils;->stringForQuery(Landroid/database/sqlite/SQLiteStatement;[Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/MatrixCursor;->getBlob(I)[B
+HSPLandroid/database/MatrixCursor;->getDouble(I)D
+HSPLandroid/database/sqlite/SQLiteCursor;->setWindow(Landroid/database/CursorWindow;)V
+HSPLandroid/database/sqlite/SQLiteDatabase$1;->accept(Ljava/io/File;)Z
+HSPLandroid/database/sqlite/SQLiteDatabase$1;-><init>(Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;->addOpenFlags(I)Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;->build()Landroid/database/sqlite/SQLiteDatabase$OpenParams;
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;-><init>(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)V
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->access$000(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)I
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->access$100(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Landroid/database/sqlite/SQLiteDatabase$CursorFactory;
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->access$200(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Landroid/database/DatabaseErrorHandler;
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->access$300(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)I
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->access$400(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)I
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->access$600(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->access$700(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$1;)V
+HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionNonExclusive()V
+HSPLandroid/database/sqlite/SQLiteDatabase;->deleteDatabase(Ljava/io/File;)Z
+HSPLandroid/database/sqlite/SQLiteDatabase;->deleteDatabase(Ljava/io/File;Z)Z
+HSPLandroid/database/sqlite/SQLiteDatabase;->getMaximumSize()J
+HSPLandroid/database/sqlite/SQLiteDatabase;->getPageSize()J
+HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadDefaultConnectionFlags(Z)I
+HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->releaseMemory()I
+HSPLandroid/database/sqlite/SQLiteGlobal;->releaseMemory()I
+HSPLandroid/database/sqlite/SQLiteOpenHelper;->setOpenParamsBuilder(Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;)V
+HSPLandroid/database/sqlite/SQLiteOpenHelper;->setOpenParams(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)V
+HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteProgram;->getBindArgs()[Ljava/lang/Object;
+HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I
+HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteProgram;->getSql()Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->query(Landroid/database/sqlite/SQLiteDatabase;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteSession;->executeForString(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForString()Ljava/lang/String;
+HSPLandroid/graphics/-$$Lambda$ColorSpace$Rgb$8EkhO2jIf14tuA3BvrmYJMa7YXM;->applyAsDouble(D)D
+HSPLandroid/graphics/BaseCanvas;->drawBitmap(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Matrix;Landroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/RectF;Landroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(FFFFFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/Bitmap;->checkRecycled(Ljava/lang/String;)V
+HSPLandroid/graphics/Bitmap;->createBitmap(Landroid/graphics/Bitmap;IIII)Landroid/graphics/Bitmap;
+HSPLandroid/graphics/Bitmap;->createBitmap(Landroid/graphics/Bitmap;)Landroid/graphics/Bitmap;
+HSPLandroid/graphics/Bitmap;->extractAlpha(Landroid/graphics/Paint;[I)Landroid/graphics/Bitmap;
+HSPLandroid/graphics/BitmapFactory$Options;->nativeColorSpace(Landroid/graphics/BitmapFactory$Options;)J
+HSPLandroid/graphics/BitmapFactory$Options;->nativeInBitmap(Landroid/graphics/BitmapFactory$Options;)J
+HSPLandroid/graphics/BitmapFactory;->decodeFileDescriptor(Ljava/io/FileDescriptor;)Landroid/graphics/Bitmap;
+HSPLandroid/graphics/BitmapFactory;->decodeFileDescriptor(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
+HSPLandroid/graphics/Bitmap;->getNativeInstance()J
+HSPLandroid/graphics/Bitmap;->noteHardwareBitmapSlowCall()V
+HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;
+HSPLandroid/graphics/BlendModeColorFilter;->createNativeInstance()J
+HSPLandroid/graphics/BlendModeColorFilter;->getColor()I
+HSPLandroid/graphics/BlendModeColorFilter;->getMode()Landroid/graphics/BlendMode;
+HSPLandroid/graphics/BlendModeColorFilter;-><init>(ILandroid/graphics/BlendMode;)V
+HSPLandroid/graphics/BlendMode;->fromValue(I)Landroid/graphics/BlendMode;
+HSPLandroid/graphics/BlendMode;->getXfermode()Landroid/graphics/Xfermode;
+HSPLandroid/graphics/Canvas;->checkValidSaveFlags(I)V
+HSPLandroid/graphics/Canvas;->clipOutPath(Landroid/graphics/Path;)Z
+HSPLandroid/graphics/Canvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Matrix;Landroid/graphics/Paint;)V
+HSPLandroid/graphics/Canvas;->getClipBounds()Landroid/graphics/Rect;
+HSPLandroid/graphics/Canvas;->saveLayer(FFFFLandroid/graphics/Paint;I)I
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I
+HSPLandroid/graphics/ColorFilter;->discardNativeInstance()V
+HSPLandroid/graphics/ColorFilter;-><init>()V
+HSPLandroid/graphics/Color;->luminance(I)F
+HSPLandroid/graphics/ColorMatrixColorFilter;-><init>([F)V
+HSPLandroid/graphics/ColorMatrixColorFilter;->setColorMatrixArray([F)V
+HSPLandroid/graphics/ColorMatrix;->set([F)V
+HSPLandroid/graphics/ColorSpace$Rgb;->clamp(D)D
+HSPLandroid/graphics/ColorSpace$Rgb;->getEotf()Ljava/util/function/DoubleUnaryOperator;
+HSPLandroid/graphics/ColorSpace$Rgb;->lambda$8EkhO2jIf14tuA3BvrmYJMa7YXM(Landroid/graphics/ColorSpace$Rgb;D)D
+HSPLandroid/graphics/CornerPathEffect;-><init>(F)V
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable$ChildDrawable;-><init>(I)V
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->addLayer(ILandroid/graphics/drawable/AdaptiveIconDrawable$ChildDrawable;)V
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->createChildDrawable(Landroid/graphics/drawable/Drawable;)Landroid/graphics/drawable/AdaptiveIconDrawable$ChildDrawable;
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->getBackground()Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->getExtraInsetFraction()F
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->getForeground()Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->getIconMask()Landroid/graphics/Path;
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;-><init>(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/graphics/drawable/AdaptiveIconDrawable;->mutate()Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->newDrawable()Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->access$200(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;)Landroid/animation/Animator$AnimatorListener;
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->access$300(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->addPendingAction(I)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->createRTAnimatorForRootGroup([Landroid/animation/PropertyValuesHolder;Landroid/animation/ObjectAnimator;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;J)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->invalidateOwningView()V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->isRunning()Z
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->reset()V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->transferPendingActions(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->useLastSeenTarget()Z
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->access$1700(JFF)J
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->access$700(Landroid/graphics/drawable/AnimatedVectorDrawable;)Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->clearAnimationCallbacks()V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->ensureAnimatorSet()V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->fallbackOntoUI()V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->forceAnimationOnUI()V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/content/res/Resources;Landroid/graphics/drawable/AnimatedVectorDrawable$1;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->registerAnimationCallback(Landroid/graphics/drawable/Animatable2$AnimationCallback;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->removeAnimatorSetListener()V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->reset()V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
+HSPLandroid/graphics/drawable/BitmapDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
+HSPLandroid/graphics/drawable/ColorDrawable;-><init>()V
+HSPLandroid/graphics/drawable/ColorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/graphics/drawable/Drawable$ConstantState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/Drawable;->clearMutated()V
+HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->getChildCount()I
+HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->growArray(II)V
+HSPLandroid/graphics/drawable/DrawableContainer;->getAlpha()I
+HSPLandroid/graphics/drawable/Drawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
+HSPLandroid/graphics/drawable/Drawable;->mutate()Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/Drawable;->parseBlendMode(ILandroid/graphics/BlendMode;)Landroid/graphics/BlendMode;
+HSPLandroid/graphics/drawable/Drawable;->setTintMode(Landroid/graphics/PorterDuff$Mode;)V
+HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;
+HSPLandroid/graphics/drawable/DrawableWrapper;->getOpacity()I
+HSPLandroid/graphics/drawable/DrawableWrapper;-><init>(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/graphics/drawable/DrawableWrapper;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
+HSPLandroid/graphics/drawable/DrawableWrapper;->onLevelChange(I)Z
+HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->getAngleFromOrientation(Landroid/graphics/drawable/GradientDrawable$Orientation;)I
+HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->updateGradientStateOrientation()V
+HSPLandroid/graphics/drawable/Icon;->loadDrawableAsUser(Landroid/content/Context;I)Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/Icon;->sameAs(Landroid/graphics/drawable/Icon;)Z
+HSPLandroid/graphics/drawable/Icon;->setTintMode(Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/drawable/Icon;
+HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->newDrawable()Landroid/graphics/drawable/Drawable;
+HSPLandroid/graphics/drawable/NinePatchDrawable;-><init>()V
+HSPLandroid/graphics/drawable/NinePatchDrawable;->setAlpha(I)V
+HSPLandroid/graphics/drawable/RippleDrawable;->setForceSoftware(Z)V
+HSPLandroid/graphics/drawable/RotateDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
+HSPLandroid/graphics/drawable/ShapeDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/graphics/drawable/shapes/Shape;->clone()Landroid/graphics/drawable/shapes/Shape;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getProperty(Ljava/lang/String;)Landroid/util/Property;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup$2;->setValue(Landroid/graphics/drawable/VectorDrawable$VGroup;F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup$2;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup$3;->setValue(Landroid/graphics/drawable/VectorDrawable$VGroup;F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup$3;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup$4;->setValue(Landroid/graphics/drawable/VectorDrawable$VGroup;F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup$4;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup$5;->setValue(Landroid/graphics/drawable/VectorDrawable$VGroup;F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup$5;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setScaleX(F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setScaleY(F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTranslateX(F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTranslateY(F)V
+HSPLandroid/graphics/drawable/VectorDrawable$VPath$1;->set(Landroid/graphics/drawable/VectorDrawable$VPath;Landroid/util/PathParser$PathData;)V
+HSPLandroid/graphics/drawable/VectorDrawable$VPath$1;->set(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroid/graphics/drawable/VectorDrawable$VPath;->setPathData(Landroid/util/PathParser$PathData;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->access$2900(JF)V
+HSPLandroid/graphics/drawable/VectorDrawable;->access$3100(JF)V
+HSPLandroid/graphics/drawable/VectorDrawable;->access$3300(JF)V
+HSPLandroid/graphics/drawable/VectorDrawable;->access$3500(JF)V
+HSPLandroid/graphics/drawable/VectorDrawable;->access$3600(JJ)V
+HSPLandroid/graphics/drawable/VectorDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V
+HSPLandroid/graphics/HardwareRenderer;->buildLayer(Landroid/graphics/RenderNode;)V
+HSPLandroid/graphics/HardwareRenderer;->overrideProperty(Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/graphics/HardwareRenderer;->setContextPriority(I)V
+HSPLandroid/graphics/HardwareRenderer;->setFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
+HSPLandroid/graphics/MaskFilter;->finalize()V
+HSPLandroid/graphics/Matrix;->ni()J
+HSPLandroid/graphics/Matrix;->postRotate(FFF)Z
+HSPLandroid/graphics/Paint;->clearShadowLayer()V
+HSPLandroid/graphics/Paint;->getFontMetrics()Landroid/graphics/Paint$FontMetrics;
+HSPLandroid/graphics/Paint;->setARGB(IIII)V
+HSPLandroid/graphics/Paint;->setFontFeatureSettings(Ljava/lang/String;)V
+HSPLandroid/graphics/Paint;->setStrokeMiter(F)V
+HSPLandroid/graphics/Path;->addCircle(FFFLandroid/graphics/Path$Direction;)V
+HSPLandroid/graphics/Path;->addPath(Landroid/graphics/Path;)V
+HSPLandroid/graphics/Path;->addRoundRect(FFFFFFLandroid/graphics/Path$Direction;)V
+HSPLandroid/graphics/Path;->arcTo(Landroid/graphics/RectF;FF)V
+HSPLandroid/graphics/PathEffect;-><init>()V
+HSPLandroid/graphics/PathMeasure;->finalize()V
+HSPLandroid/graphics/PathMeasure;->getLength()F
+HSPLandroid/graphics/PathMeasure;->getPosTan(F[F[F)Z
+HSPLandroid/graphics/PathMeasure;-><init>(Landroid/graphics/Path;Z)V
+HSPLandroid/graphics/PathMeasure;-><init>()V
+HSPLandroid/graphics/PathMeasure;->setPath(Landroid/graphics/Path;Z)V
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
+HSPLandroid/graphics/Path;->quadTo(FFFF)V
+HSPLandroid/graphics/Path;->readOnlyNI()J
+HSPLandroid/graphics/Path;->rLineTo(FF)V
+HSPLandroid/graphics/PointF;->set(Landroid/graphics/PointF;)V
+HSPLandroid/graphics/Point;->readFromParcel(Landroid/os/Parcel;)V
+HSPLandroid/graphics/RectF;->offsetTo(FF)V
+HSPLandroid/graphics/Rect;->inset(II)V
+HSPLandroid/graphics/Rect;->offsetTo(II)V
+HSPLandroid/graphics/Rect;->setIntersect(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z
+HSPLandroid/graphics/Region;->getBounds()Landroid/graphics/Rect;
+HSPLandroid/graphics/Region;-><init>(IIII)V
+HSPLandroid/graphics/RegionIterator;-><init>(Landroid/graphics/Region;)V
+HSPLandroid/graphics/RegionIterator;->next(Landroid/graphics/Rect;)Z
+HSPLandroid/graphics/Region;->ni()J
+HSPLandroid/graphics/Region;->setPath(Landroid/graphics/Path;Landroid/graphics/Region;)Z
+HSPLandroid/graphics/RenderNode$CompositePositionUpdateListener;-><init>([Landroid/graphics/RenderNode$PositionUpdateListener;)V
+HSPLandroid/graphics/RenderNode$CompositePositionUpdateListener;->positionChanged(JIIII)V
+HSPLandroid/graphics/RenderNode$CompositePositionUpdateListener;->positionLost(J)V
+HSPLandroid/graphics/RenderNode$CompositePositionUpdateListener;->without(Landroid/graphics/RenderNode$PositionUpdateListener;)Landroid/graphics/RenderNode$CompositePositionUpdateListener;
+HSPLandroid/graphics/RenderNode;->removePositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
+HSPLandroid/graphics/Typeface;->create(Landroid/graphics/Typeface;IZ)Landroid/graphics/Typeface;
+HSPLandroid/graphics/Typeface;->createWeightStyle(Landroid/graphics/Typeface;IZ)Landroid/graphics/Typeface;
+HSPLandroid/hardware/biometrics/BiometricManager;->registerEnabledOnKeyguardCallback(Landroid/hardware/biometrics/IBiometricEnabledOnKeyguardCallback;)V
+HSPLandroid/hardware/biometrics/BiometricSourceType;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/hardware/biometrics/IBiometricEnabledOnKeyguardCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/biometrics/IBiometricEnabledOnKeyguardCallback$Stub;-><init>()V
+HSPLandroid/hardware/biometrics/IBiometricEnabledOnKeyguardCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/hardware/biometrics/IBiometricServiceLockoutResetCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/biometrics/IBiometricServiceLockoutResetCallback$Stub;-><init>()V
+HSPLandroid/hardware/Camera$CameraInfo;-><init>()V
+HSPLandroid/hardware/camera2/CameraManager;->registerTorchCallback(Landroid/hardware/camera2/CameraManager$TorchCallback;Landroid/os/Handler;)V
+HSPLandroid/hardware/camera2/marshal/impl/MarshalQueryableBoolean;->createMarshaler(Landroid/hardware/camera2/utils/TypeReference;I)Landroid/hardware/camera2/marshal/Marshaler;
+HSPLandroid/hardware/display/AmbientDisplayConfiguration;->boolSettingDefaultOn(Ljava/lang/String;I)Z
+HSPLandroid/hardware/display/AmbientDisplayConfiguration;->boolSetting(Ljava/lang/String;II)Z
+HSPLandroid/hardware/display/AmbientDisplayConfiguration;->tapGestureEnabled(I)Z
+HSPLandroid/hardware/display/DisplayManager;->getStableDisplaySize()Landroid/graphics/Point;
+HSPLandroid/hardware/display/DisplayManagerGlobal;->getStableDisplaySize()Landroid/graphics/Point;
+HSPLandroid/hardware/display/IDisplayManager$Stub$Proxy;->getStableDisplaySize()Landroid/graphics/Point;
+HSPLandroid/hardware/fingerprint/FingerprintManager$1;-><init>(Landroid/hardware/fingerprint/FingerprintManager;Landroid/os/PowerManager;Landroid/hardware/fingerprint/FingerprintManager$LockoutResetCallback;)V
+HSPLandroid/hardware/fingerprint/FingerprintManager;->addLockoutResetCallback(Landroid/hardware/fingerprint/FingerprintManager$LockoutResetCallback;)V
+HSPLandroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;->addLockoutResetCallback(Landroid/hardware/biometrics/IBiometricServiceLockoutResetCallback;)V
+HSPLandroid/hardware/input/IInputManager$Stub$Proxy;->hasKeys(II[I[Z)Z
+HSPLandroid/hardware/input/InputManager;->deviceHasKeys(I[I)[Z
+HSPLandroid/hardware/ISensorPrivacyListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/ISensorPrivacyListener$Stub;-><init>()V
+HSPLandroid/hardware/ISensorPrivacyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ISensorPrivacyManager;
+HSPLandroid/hardware/location/ContextHubInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/location/ContextHubInfo;
+HSPLandroid/hardware/location/ContextHubInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/hardware/location/ContextHubInfo;->getMaxPacketLengthBytes()I
+HSPLandroid/hardware/location/ContextHubInfo;-><init>(Landroid/os/Parcel;Landroid/hardware/location/ContextHubInfo$1;)V
+HSPLandroid/hardware/location/ContextHubInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/hardware/location/ContextHubManager;->access$000(Landroid/hardware/location/ContextHubManager;)Landroid/hardware/location/ContextHubManager$Callback;
+HSPLandroid/hardware/location/ContextHubManager;->access$100(Landroid/hardware/location/ContextHubManager;)Landroid/os/Handler;
+HSPLandroid/hardware/location/ContextHubManager;->access$200(Landroid/hardware/location/ContextHubManager;)Landroid/hardware/location/ContextHubManager$ICallback;
+HSPLandroid/hardware/location/ContextHubManager;->access$300(Landroid/hardware/location/ContextHubManager;IILandroid/hardware/location/ContextHubMessage;)V
+HSPLandroid/hardware/location/ContextHubManager;->createClientCallback(Landroid/hardware/location/ContextHubClient;Landroid/hardware/location/ContextHubClientCallback;Ljava/util/concurrent/Executor;)Landroid/hardware/location/IContextHubClientCallback;
+HSPLandroid/hardware/location/ContextHubManager;->createClient(Landroid/hardware/location/ContextHubInfo;Landroid/hardware/location/ContextHubClientCallback;)Landroid/hardware/location/ContextHubClient;
+HSPLandroid/hardware/location/ContextHubManager;->createClient(Landroid/hardware/location/ContextHubInfo;Landroid/hardware/location/ContextHubClientCallback;Ljava/util/concurrent/Executor;)Landroid/hardware/location/ContextHubClient;
+HSPLandroid/hardware/location/ContextHubManager;->createQueryCallback(Landroid/hardware/location/ContextHubTransaction;)Landroid/hardware/location/IContextHubTransactionCallback;
+HSPLandroid/hardware/location/ContextHubManager;->findNanoAppOnHub(ILandroid/hardware/location/NanoAppFilter;)[I
+HSPLandroid/hardware/location/ContextHubManager;->getContextHubHandles()[I
+HSPLandroid/hardware/location/ContextHubManager;->getContextHubInfo(I)Landroid/hardware/location/ContextHubInfo;
+HSPLandroid/hardware/location/ContextHubManager;->getContextHubs()Ljava/util/List;
+HSPLandroid/hardware/location/ContextHubManager;->getNanoAppInstanceInfo(I)Landroid/hardware/location/NanoAppInstanceInfo;
+HSPLandroid/hardware/location/ContextHubManager;-><init>(Landroid/content/Context;Landroid/os/Looper;)V
+HSPLandroid/hardware/location/ContextHubManager;->invokeOnMessageReceiptCallback(IILandroid/hardware/location/ContextHubMessage;)V
+HSPLandroid/hardware/location/ContextHubManager;->queryNanoApps(Landroid/hardware/location/ContextHubInfo;)Landroid/hardware/location/ContextHubTransaction;
+HSPLandroid/hardware/location/ContextHubManager;->registerCallback(Landroid/hardware/location/ContextHubManager$Callback;)I
+HSPLandroid/hardware/location/ContextHubManager;->registerCallback(Landroid/hardware/location/ContextHubManager$Callback;Landroid/os/Handler;)I
+HSPLandroid/hardware/location/ContextHubManager;->sendMessage(IILandroid/hardware/location/ContextHubMessage;)I
+HSPLandroid/hardware/location/IActivityRecognitionHardware$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IActivityRecognitionHardware;
+HSPLandroid/hardware/location/IContextHubCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/location/IContextHubCallback$Stub;-><init>()V
+HSPLandroid/hardware/location/IContextHubCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/hardware/location/IContextHubClientCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService;
+HSPLandroid/hardware/location/IContextHubTransactionCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/location/IContextHubTransactionCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/hardware/location/MemoryRegion$1;->newArray(I)[Landroid/hardware/location/MemoryRegion;
+HSPLandroid/hardware/location/MemoryRegion$1;->newArray(I)[Ljava/lang/Object;
+HSPLandroid/hardware/location/NanoAppInstanceInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/location/NanoAppInstanceInfo;
+HSPLandroid/hardware/location/NanoAppInstanceInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/hardware/location/NanoAppInstanceInfo;-><init>(Landroid/os/Parcel;Landroid/hardware/location/NanoAppInstanceInfo$1;)V
+HSPLandroid/hardware/location/NanoAppInstanceInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/hardware/location/NanoAppMessage;->getMessageType()I
+HSPLandroid/hardware/location/NanoAppMessage;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/location/NanoAppState;
+HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/hardware/location/NanoAppState;->getNanoAppId()J
+HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;Landroid/hardware/location/NanoAppState$1;)V
+HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/hardware/radio/deprecated/V1_0/IOemHook;->asInterface(Landroid/os/IHwBinder;)Landroid/hardware/radio/deprecated/V1_0/IOemHook;
+HSPLandroid/hardware/radio/deprecated/V1_0/IOemHookIndication$Stub;->asBinder()Landroid/os/IHwBinder;
+HSPLandroid/hardware/radio/deprecated/V1_0/IOemHookIndication$Stub;->onTransact(ILandroid/os/HwParcel;Landroid/os/HwParcel;I)V
+HSPLandroid/hardware/radio/deprecated/V1_0/IOemHookResponse$Stub;->asBinder()Landroid/os/IHwBinder;
+HSPLandroid/hardware/radio/V1_0/CardStatus;-><init>()V
+HSPLandroid/hardware/radio/V1_0/CardStatus;->readFromParcel(Landroid/os/HwParcel;)V
+HSPLandroid/hardware/radio/V1_0/CdmaBroadcastSmsConfigInfo;->toString()Ljava/lang/String;
+HSPLandroid/hardware/radio/V1_0/CdmaSignalStrength;-><init>()V
+HSPLandroid/hardware/radio/V1_0/CdmaSignalStrength;->readEmbeddedFromParcel(Landroid/os/HwParcel;Landroid/os/HwBlob;J)V
+HSPLandroid/hardware/radio/V1_0/CellIdentityLte;-><init>()V
+HSPLandroid/hardware/radio/V1_0/CellIdentityLte;->toString()Ljava/lang/String;
+HSPLandroid/hardware/radio/V1_0/CellInfoType;->toString(I)Ljava/lang/String;
+HSPLandroid/hardware/radio/V1_0/DataProfileInfo;->writeToParcel(Landroid/os/HwParcel;)V
+HSPLandroid/hardware/radio/V1_0/DataRegStateResult;-><init>()V
+HSPLandroid/hardware/radio/V1_0/DataRegStateResult;->readEmbeddedFromParcel(Landroid/os/HwParcel;Landroid/os/HwBlob;J)V
+HSPLandroid/hardware/radio/V1_0/DataRegStateResult;->readFromParcel(Landroid/os/HwParcel;)V
+HSPLandroid/hardware/radio/V1_0/DataRegStateResult;->toString()Ljava/lang/String;
+HSPLandroid/hardware/radio/V1_0/EvdoSignalStrength;-><init>()V
+HSPLandroid/hardware/radio/V1_0/EvdoSignalStrength;->readEmbeddedFromParcel(Landroid/os/HwParcel;Landroid/os/HwBlob;J)V
+HSPLandroid/hardware/radio/V1_0/GsmSignalStrength;-><init>()V
+HSPLandroid/hardware/radio/V1_0/GsmSignalStrength;->readEmbeddedFromParcel(Landroid/os/HwParcel;Landroid/os/HwBlob;J)V
+HSPLandroid/hardware/radio/V1_0/IccIo;->writeToParcel(Landroid/os/HwParcel;)V
+HSPLandroid/hardware/radio/V1_0/LteSignalStrength;-><init>()V
+HSPLandroid/hardware/radio/V1_0/RegState;->toString(I)Ljava/lang/String;
+HSPLandroid/hardware/radio/V1_0/SetupDataCallResult;->toString()Ljava/lang/String;
+HSPLandroid/hardware/radio/V1_0/TdScdmaSignalStrength;-><init>()V
+HSPLandroid/hardware/radio/V1_0/TdScdmaSignalStrength;->readEmbeddedFromParcel(Landroid/os/HwParcel;Landroid/os/HwBlob;J)V
+HSPLandroid/hardware/radio/V1_0/VoiceRegStateResult;-><init>()V
+HSPLandroid/hardware/radio/V1_0/VoiceRegStateResult;->readEmbeddedFromParcel(Landroid/os/HwParcel;Landroid/os/HwBlob;J)V
+HSPLandroid/hardware/radio/V1_0/VoiceRegStateResult;->readFromParcel(Landroid/os/HwParcel;)V
+HSPLandroid/hardware/radio/V1_0/VoiceRegStateResult;->toString()Ljava/lang/String;
+HSPLandroid/hardware/radio/V1_1/IRadio;->asInterface(Landroid/os/IHwBinder;)Landroid/hardware/radio/V1_1/IRadio;
+HSPLandroid/hardware/radio/V1_1/IRadio;->getService(Ljava/lang/String;Z)Landroid/hardware/radio/V1_1/IRadio;
+HSPLandroid/hardware/radio/V1_2/IRadio;->getService(Ljava/lang/String;Z)Landroid/hardware/radio/V1_2/IRadio;
+HSPLandroid/hardware/Sensor;->getFifoMaxEventCount()I
+HSPLandroid/hardware/SensorManager;->getDelay(I)I
+HSPLandroid/hardware/SensorManager;-><init>()V
+HSPLandroid/hardware/SensorManager;->registerListener(Landroid/hardware/SensorEventListener;Landroid/hardware/Sensor;IILandroid/os/Handler;)Z
+HSPLandroid/hardware/SensorPrivacyManager;->addSensorPrivacyListener(Landroid/hardware/SensorPrivacyManager$OnSensorPrivacyChangedListener;)V
+HSPLandroid/hardware/SensorPrivacyManager;->getInstance(Landroid/content/Context;)Landroid/hardware/SensorPrivacyManager;
+HSPLandroid/hardware/SensorPrivacyManager;-><init>(Landroid/content/Context;Landroid/hardware/ISensorPrivacyManager;)V
+HSPLandroid/hardware/SensorPrivacyManager;->isSensorPrivacyEnabled()Z
+HSPLandroid/hardware/TriggerEventListener;-><init>()V
+HSPLandroid/icu/impl/CacheValue$NullValue;->isNull()Z
+HSPLandroid/icu/impl/coll/CollationData;->getCE32FromContexts(I)I
+HSPLandroid/icu/impl/coll/CollationData;->getCE32(I)I
+HSPLandroid/icu/impl/coll/CollationIterator$CEBuffer;->append(J)V
+HSPLandroid/icu/impl/coll/CollationIterator$CEBuffer;->getCEs()[J
+HSPLandroid/icu/impl/coll/CollationIterator$CEBuffer;->get(I)J
+HSPLandroid/icu/impl/coll/CollationIterator$CEBuffer;->incLength()V
+HSPLandroid/icu/impl/coll/CollationIterator$CEBuffer;-><init>()V
+HSPLandroid/icu/impl/coll/CollationIterator$CEBuffer;->set(IJ)J
+HSPLandroid/icu/impl/coll/CollationSettings;->dontCheckFCD()Z
+HSPLandroid/icu/impl/coll/CollationSettings;->getAlternateHandling()Z
+HSPLandroid/icu/impl/coll/CollationSettings;->getStrength(I)I
+HSPLandroid/icu/impl/coll/CollationSettings;->hasReordering()Z
+HSPLandroid/icu/impl/coll/CollationSettings;->isNumeric()Z
+HSPLandroid/icu/impl/coll/SharedObject$Reference;->readOnly()Landroid/icu/impl/coll/SharedObject;
+HSPLandroid/icu/impl/JavaTimeZone;->freeze()Landroid/icu/util/TimeZone;
+HSPLandroid/icu/impl/JavaTimeZone;-><init>(Ljava/util/TimeZone;Ljava/lang/String;)V
+HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/number/NumberStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/number/NumberStringBuilder;Landroid/icu/impl/number/NumberStringBuilder;ZZLandroid/icu/impl/number/Modifier$Parameters;)V
+HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/number/NumberStringBuilder;Landroid/icu/impl/number/NumberStringBuilder;ZZ)V
+HSPLandroid/icu/impl/number/MicroProps;->clone()Ljava/lang/Object;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;-><init>(Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/text/PluralRules;Landroid/icu/impl/number/MicroPropsGenerator;)V
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/StandardPlural;->orOtherFromString(Ljava/lang/CharSequence;)Landroid/icu/impl/StandardPlural;
+HSPLandroid/icu/impl/Trie2_32;->getFromU16SingleLead(C)I
+HSPLandroid/icu/impl/Trie2_32;->get(I)I
+HSPLandroid/icu/impl/UCharacterProperty;->getProperty(I)I
+HSPLandroid/icu/impl/UCharacterProperty;->getType(I)I
+HSPLandroid/icu/impl/UResource$Key;->contentEquals(Ljava/lang/CharSequence;)Z
+HSPLandroid/icu/impl/UResource$Key;->regionMatches(ILjava/lang/CharSequence;I)Z
+HSPLandroid/icu/lang/UCharacter;->getType(I)I
+HSPLandroid/icu/text/AlphabeticIndex$1;-><init>(Landroid/icu/text/AlphabeticIndex;)V
+HSPLandroid/icu/text/AlphabeticIndex$Bucket;->access$1400(Landroid/icu/text/AlphabeticIndex$Bucket;)I
+HSPLandroid/icu/text/AlphabeticIndex$Bucket;->access$1402(Landroid/icu/text/AlphabeticIndex$Bucket;I)I
+HSPLandroid/icu/text/AlphabeticIndex$Bucket;->access$800(Landroid/icu/text/AlphabeticIndex$Bucket;)Ljava/lang/String;
+HSPLandroid/icu/text/AlphabeticIndex$Bucket;->access$900(Landroid/icu/text/AlphabeticIndex$Bucket;)Landroid/icu/text/AlphabeticIndex$Bucket;
+HSPLandroid/icu/text/AlphabeticIndex$Bucket;->getLabel()Ljava/lang/String;
+HSPLandroid/icu/text/AlphabeticIndex$Bucket;-><init>(Ljava/lang/String;Ljava/lang/String;Landroid/icu/text/AlphabeticIndex$Bucket$LabelType;Landroid/icu/text/AlphabeticIndex$1;)V
+HSPLandroid/icu/text/AlphabeticIndex$Bucket;-><init>(Ljava/lang/String;Ljava/lang/String;Landroid/icu/text/AlphabeticIndex$Bucket$LabelType;)V
+HSPLandroid/icu/text/AlphabeticIndex$BucketList;->access$200(Landroid/icu/text/AlphabeticIndex$BucketList;)I
+HSPLandroid/icu/text/AlphabeticIndex$BucketList;->access$300(Landroid/icu/text/AlphabeticIndex$BucketList;Ljava/lang/CharSequence;Landroid/icu/text/Collator;)I
+HSPLandroid/icu/text/AlphabeticIndex$BucketList;->access$400(Landroid/icu/text/AlphabeticIndex$BucketList;)Ljava/util/List;
+HSPLandroid/icu/text/AlphabeticIndex$BucketList;->getBucketCount()I
+HSPLandroid/icu/text/AlphabeticIndex$BucketList;->getBucketIndex(Ljava/lang/CharSequence;Landroid/icu/text/Collator;)I
+HSPLandroid/icu/text/AlphabeticIndex$BucketList;-><init>(Ljava/util/ArrayList;Ljava/util/ArrayList;Landroid/icu/text/AlphabeticIndex$1;)V
+HSPLandroid/icu/text/AlphabeticIndex$BucketList;-><init>(Ljava/util/ArrayList;Ljava/util/ArrayList;)V
+HSPLandroid/icu/text/AlphabeticIndex$ImmutableIndex;->getBucket(I)Landroid/icu/text/AlphabeticIndex$Bucket;
+HSPLandroid/icu/text/AlphabeticIndex$ImmutableIndex;->getBucketIndex(Ljava/lang/CharSequence;)I
+HSPLandroid/icu/text/AlphabeticIndex$ImmutableIndex;-><init>(Landroid/icu/text/AlphabeticIndex$BucketList;Landroid/icu/text/Collator;Landroid/icu/text/AlphabeticIndex$1;)V
+HSPLandroid/icu/text/AlphabeticIndex$ImmutableIndex;-><init>(Landroid/icu/text/AlphabeticIndex$BucketList;Landroid/icu/text/Collator;)V
+HSPLandroid/icu/text/BreakIterator;->getSentenceInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/BreakIterator;
+HSPLandroid/icu/text/Collator;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
+HSPLandroid/icu/text/DateFormat;->format(Ljava/lang/Object;Ljava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
+HSPLandroid/icu/text/DateFormat;->getInstanceForSkeleton(Ljava/lang/String;Landroid/icu/util/ULocale;)Landroid/icu/text/DateFormat;
+HSPLandroid/icu/text/DateFormat;->getInstanceForSkeleton(Ljava/lang/String;Ljava/util/Locale;)Landroid/icu/text/DateFormat;
+HSPLandroid/icu/text/DateFormat;->getPatternInstance(Ljava/lang/String;Landroid/icu/util/ULocale;)Landroid/icu/text/DateFormat;
+HSPLandroid/icu/text/DateTimePatternGenerator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/DateTimePatternGenerator;
+HSPLandroid/icu/text/DisplayContext;->type()Landroid/icu/text/DisplayContext$Type;
+HSPLandroid/icu/text/NumberFormat;->getInstance(Landroid/icu/util/ULocale;I)Landroid/icu/text/NumberFormat;
+HSPLandroid/icu/text/NumberFormat;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/NumberFormat;
+HSPLandroid/icu/text/PluralRules$Factory;->getDefaultFactory()Landroid/icu/impl/PluralRulesLoader;
+HSPLandroid/icu/text/PluralRules;->forLocale(Landroid/icu/util/ULocale;)Landroid/icu/text/PluralRules;
+HSPLandroid/icu/text/RuleBasedCollator$CollationBuffer;-><init>(Landroid/icu/impl/coll/CollationData;Landroid/icu/text/RuleBasedCollator$1;)V
+HSPLandroid/icu/text/RuleBasedCollator$CollationBuffer;-><init>(Landroid/icu/impl/coll/CollationData;)V
+HSPLandroid/icu/text/RuleBasedCollator$FCDUTF16NFDIterator;-><init>()V
+HSPLandroid/icu/text/RuleBasedCollator$NFDIterator;-><init>()V
+HSPLandroid/icu/text/RuleBasedCollator$UTF16NFDIterator;-><init>()V
+HSPLandroid/icu/text/RuleBasedCollator;->freeze()Landroid/icu/text/Collator;
+HSPLandroid/icu/text/RuleBasedCollator;->getCollationBuffer()Landroid/icu/text/RuleBasedCollator$CollationBuffer;
+HSPLandroid/icu/text/RuleBasedCollator;->internalAddContractions(ILandroid/icu/text/UnicodeSet;)V
+HSPLandroid/icu/text/RuleBasedCollator;->internalGetCEs(Ljava/lang/CharSequence;)[J
+HSPLandroid/icu/text/RuleBasedCollator;->isAlternateHandlingShifted()Z
+HSPLandroid/icu/text/RuleBasedCollator;->isFrozen()Z
+HSPLandroid/icu/text/RuleBasedCollator;->releaseCollationBuffer(Landroid/icu/text/RuleBasedCollator$CollationBuffer;)V
+HSPLandroid/icu/text/SimpleDateFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DateFormatSymbols;Landroid/icu/util/Calendar;Landroid/icu/text/NumberFormat;Landroid/icu/util/ULocale;ZLjava/lang/String;)V
+HSPLandroid/icu/text/SimpleDateFormat;-><init>(Ljava/lang/String;Landroid/icu/util/ULocale;)V
+HSPLandroid/icu/text/UFieldPosition;->getCountVisibleFractionDigits()I
+HSPLandroid/icu/text/UFieldPosition;->getFractionDigits()J
+HSPLandroid/icu/text/UFieldPosition;-><init>(Ljava/text/Format$Field;I)V
+HSPLandroid/icu/text/UnicodeSet$UnicodeSetIterator2;->hasNext()Z
+HSPLandroid/icu/text/UnicodeSet$UnicodeSetIterator2;-><init>(Landroid/icu/text/UnicodeSet;)V
+HSPLandroid/icu/text/UnicodeSet$UnicodeSetIterator2;->next()Ljava/lang/Object;
+HSPLandroid/icu/text/UnicodeSet$UnicodeSetIterator2;->next()Ljava/lang/String;
+HSPLandroid/icu/text/UnicodeSet;->access$400(Landroid/icu/text/UnicodeSet;)I
+HSPLandroid/icu/text/UnicodeSet;->access$500(Landroid/icu/text/UnicodeSet;)[I
+HSPLandroid/icu/text/UnicodeSet;->add(Ljava/lang/CharSequence;)Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/text/UnicodeSet;->addString(Ljava/lang/CharSequence;)V
+HSPLandroid/icu/text/UnicodeSet;->checkFrozen()V
+HSPLandroid/icu/text/UnicodeSet;-><init>(Ljava/lang/String;I)V
+HSPLandroid/icu/text/UnicodeSet;->isEmpty()Z
+HSPLandroid/icu/text/UnicodeSet;->iterator()Ljava/util/Iterator;
+HSPLandroid/icu/text/UTF16$StringComparator;-><init>(ZZI)V
+HSPLandroid/icu/text/UTF16$StringComparator;->setCodePointCompare(Z)V
+HSPLandroid/icu/text/UTF16;->_charAt(Ljava/lang/CharSequence;IC)I
+HSPLandroid/icu/text/UTF16;->getLeadSurrogate(I)C
+HSPLandroid/icu/text/UTF16;->getTrailSurrogate(I)C
+HSPLandroid/icu/text/UTF16;->hasMoreCodePointsThan(Ljava/lang/String;I)Z
+HSPLandroid/icu/util/BytesTrie$Result;->hasNext()Z
+HSPLandroid/icu/util/BytesTrie$Result;->hasValue()Z
+HSPLandroid/icu/util/CharsTrie$Entry;-><init>(Landroid/icu/util/CharsTrie$1;)V
+HSPLandroid/icu/util/CharsTrie$Entry;-><init>()V
+HSPLandroid/icu/util/CharsTrie$Iterator;->branchNext(II)I
+HSPLandroid/icu/util/CharsTrie$Iterator;->hasNext()Z
+HSPLandroid/icu/util/CharsTrie$Iterator;-><init>(Ljava/lang/CharSequence;IIILandroid/icu/util/CharsTrie$1;)V
+HSPLandroid/icu/util/CharsTrie$Iterator;-><init>(Ljava/lang/CharSequence;III)V
+HSPLandroid/icu/util/CharsTrie$Iterator;->next()Landroid/icu/util/CharsTrie$Entry;
+HSPLandroid/icu/util/TimeZone;-><init>()V
+HSPLandroid/icu/util/TimeZone;->setID(Ljava/lang/String;)V
+HSPLandroid/location/IGnssStatusListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/location/IGnssStatusListener$Stub;-><init>()V
+HSPLandroid/location/ILocationListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/location/ILocationManager$Stub$Proxy;->getAllProviders()Ljava/util/List;
+HSPLandroid/location/ILocationManager$Stub$Proxy;->getExtraLocationControllerPackage()Ljava/lang/String;
+HSPLandroid/location/ILocationManager$Stub$Proxy;->getLastLocation(Landroid/location/LocationRequest;Ljava/lang/String;)Landroid/location/Location;
+HSPLandroid/location/ILocationManager$Stub$Proxy;->getProviderProperties(Ljava/lang/String;)Lcom/android/internal/location/ProviderProperties;
+HSPLandroid/location/ILocationManager$Stub$Proxy;->isProviderEnabledForUser(Ljava/lang/String;I)Z
+HSPLandroid/location/ILocationManager$Stub$Proxy;->locationCallbackFinished(Landroid/location/ILocationListener;)V
+HSPLandroid/location/ILocationManager$Stub$Proxy;->registerGnssStatusCallback(Landroid/location/IGnssStatusListener;Ljava/lang/String;)Z
+HSPLandroid/location/ILocationManager$Stub$Proxy;->setExtraLocationControllerPackageEnabled(Z)V
+HSPLandroid/location/ILocationManager$Stub$Proxy;->setExtraLocationControllerPackage(Ljava/lang/String;)V
+HSPLandroid/location/Location;->getVerticalAccuracyMeters()F
+HSPLandroid/location/Location;->hasAltitude()Z
+HSPLandroid/location/Location;->hasBearingAccuracy()Z
+HSPLandroid/location/Location;->hasElapsedRealtimeUncertaintyNanos()Z
+HSPLandroid/location/Location;->hasSpeedAccuracy()Z
+HSPLandroid/location/Location;->hasVerticalAccuracy()Z
+HSPLandroid/location/LocationManager$GnssStatusListenerTransport$GnssHandler;-><init>(Landroid/location/LocationManager$GnssStatusListenerTransport;Landroid/os/Handler;)V
+HSPLandroid/location/LocationManager$GnssStatusListenerTransport;-><init>(Landroid/location/LocationManager;Landroid/location/GpsStatus$Listener;Landroid/os/Handler;)V
+HSPLandroid/location/LocationManager;->addGpsStatusListener(Landroid/location/GpsStatus$Listener;)Z
+HSPLandroid/location/LocationManager;->checkProvider(Ljava/lang/String;)V
+HSPLandroid/location/LocationManager;->getAllProviders()Ljava/util/List;
+HSPLandroid/location/LocationManager;->getExtraLocationControllerPackage()Ljava/lang/String;
+HSPLandroid/location/LocationManager;->getLastKnownLocation(Ljava/lang/String;)Landroid/location/Location;
+HSPLandroid/location/LocationManager;->removeGpsStatusListener(Landroid/location/GpsStatus$Listener;)V
+HSPLandroid/location/LocationManager;->setLocationControllerExtraPackageEnabled(Z)V
+HSPLandroid/location/LocationManager;->setLocationControllerExtraPackage(Ljava/lang/String;)V
+HSPLandroid/location/LocationRequest;->setHideFromAppOps(Z)V
+HSPLandroid/location/LocationRequest;->setLocationSettingsIgnored(Z)Landroid/location/LocationRequest;
+HSPLandroid/location/LocationRequest;->setWorkSource(Landroid/os/WorkSource;)V
+HSPLandroid/location/Location;->setProvider(Ljava/lang/String;)V
+HSPLandroid/location/Location;->toString()Ljava/lang/String;
+HSPLandroid/media/AudioDeviceInfo;->getProductName()Ljava/lang/CharSequence;
+HSPLandroid/media/AudioManager;->getLastAudibleStreamVolume(I)I
+HSPLandroid/media/AudioManager;->getService()Landroid/media/IAudioService;
+HSPLandroid/media/AudioManager;->getStreamMinVolumeInt(I)I
+HSPLandroid/media/AudioManager;->isStreamAffectedByMute(I)Z
+HSPLandroid/media/AudioManager;->setVolumeController(Landroid/media/IVolumeController;)V
+HSPLandroid/media/AudioManager;->setVolumePolicy(Landroid/media/VolumePolicy;)V
+HSPLandroid/media/AudioPort;->name()Ljava/lang/String;
+HSPLandroid/media/AudioSystem;->streamToString(I)Ljava/lang/String;
+HSPLandroid/media/browse/MediaBrowser$1;-><init>(Landroid/media/browse/MediaBrowser;)V
+HSPLandroid/media/browse/MediaBrowser$1;->run()V
+HSPLandroid/media/browse/MediaBrowser$2;-><init>(Landroid/media/browse/MediaBrowser;)V
+HSPLandroid/media/browse/MediaBrowser$2;->run()V
+HSPLandroid/media/browse/MediaBrowser$6;-><init>(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserServiceCallbacks;Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)V
+HSPLandroid/media/browse/MediaBrowser$6;->run()V
+HSPLandroid/media/browse/MediaBrowser$7;-><init>(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/media/browse/MediaBrowser$7;->run()V
+HSPLandroid/media/browse/MediaBrowser$8;-><init>(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserServiceCallbacks;Ljava/lang/String;Landroid/os/Bundle;Landroid/content/pm/ParceledListSlice;)V
+HSPLandroid/media/browse/MediaBrowser$8;->run()V
+HSPLandroid/media/browse/MediaBrowser$ConnectionCallback;-><init>()V
+HSPLandroid/media/browse/MediaBrowser$MediaItem$1;->createFromParcel(Landroid/os/Parcel;)Landroid/media/browse/MediaBrowser$MediaItem;
+HSPLandroid/media/browse/MediaBrowser$MediaItem$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/media/browse/MediaBrowser$MediaItem;->getDescription()Landroid/media/MediaDescription;
+HSPLandroid/media/browse/MediaBrowser$MediaItem;->getMediaId()Ljava/lang/String;
+HSPLandroid/media/browse/MediaBrowser$MediaItem;-><init>(Landroid/os/Parcel;Landroid/media/browse/MediaBrowser$1;)V
+HSPLandroid/media/browse/MediaBrowser$MediaItem;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/media/browse/MediaBrowser$MediaItem;->isBrowsable()Z
+HSPLandroid/media/browse/MediaBrowser$MediaItem;->toString()Ljava/lang/String;
+HSPLandroid/media/browse/MediaBrowser$MediaServiceConnection$1;-><init>(Landroid/media/browse/MediaBrowser$MediaServiceConnection;Landroid/content/ComponentName;Landroid/os/IBinder;)V
+HSPLandroid/media/browse/MediaBrowser$MediaServiceConnection$1;->run()V
+HSPLandroid/media/browse/MediaBrowser$MediaServiceConnection;->access$1600(Landroid/media/browse/MediaBrowser$MediaServiceConnection;Ljava/lang/String;)Z
+HSPLandroid/media/browse/MediaBrowser$MediaServiceConnection;-><init>(Landroid/media/browse/MediaBrowser;Landroid/media/browse/MediaBrowser$1;)V
+HSPLandroid/media/browse/MediaBrowser$MediaServiceConnection;-><init>(Landroid/media/browse/MediaBrowser;)V
+HSPLandroid/media/browse/MediaBrowser$MediaServiceConnection;->isCurrent(Ljava/lang/String;)Z
+HSPLandroid/media/browse/MediaBrowser$MediaServiceConnection;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
+HSPLandroid/media/browse/MediaBrowser$MediaServiceConnection;->postOrRun(Ljava/lang/Runnable;)V
+HSPLandroid/media/browse/MediaBrowser$ServiceCallbacks;-><init>(Landroid/media/browse/MediaBrowser;)V
+HSPLandroid/media/browse/MediaBrowser$ServiceCallbacks;->onConnectFailed()V
+HSPLandroid/media/browse/MediaBrowser$ServiceCallbacks;->onConnect(Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)V
+HSPLandroid/media/browse/MediaBrowser$ServiceCallbacks;->onLoadChildrenWithOptions(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;Landroid/os/Bundle;)V
+HSPLandroid/media/browse/MediaBrowser$SubscriptionCallback;-><init>()V
+HSPLandroid/media/browse/MediaBrowser$Subscription;->getCallback(Landroid/content/Context;Landroid/os/Bundle;)Landroid/media/browse/MediaBrowser$SubscriptionCallback;
+HSPLandroid/media/browse/MediaBrowser$Subscription;->getCallbacks()Ljava/util/List;
+HSPLandroid/media/browse/MediaBrowser$Subscription;->getOptionsList()Ljava/util/List;
+HSPLandroid/media/browse/MediaBrowser$Subscription;-><init>()V
+HSPLandroid/media/browse/MediaBrowser$Subscription;->isEmpty()Z
+HSPLandroid/media/browse/MediaBrowser$Subscription;->putCallback(Landroid/content/Context;Landroid/os/Bundle;Landroid/media/browse/MediaBrowser$SubscriptionCallback;)V
+HSPLandroid/media/browse/MediaBrowser;->access$000(Landroid/media/browse/MediaBrowser;)I
+HSPLandroid/media/browse/MediaBrowser;->access$002(Landroid/media/browse/MediaBrowser;I)I
+HSPLandroid/media/browse/MediaBrowser;->access$100(Landroid/media/browse/MediaBrowser;)Landroid/service/media/IMediaBrowserService;
+HSPLandroid/media/browse/MediaBrowser;->access$102(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserService;)Landroid/service/media/IMediaBrowserService;
+HSPLandroid/media/browse/MediaBrowser;->access$1102(Landroid/media/browse/MediaBrowser;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/media/browse/MediaBrowser;->access$1202(Landroid/media/browse/MediaBrowser;Landroid/media/session/MediaSession$Token;)Landroid/media/session/MediaSession$Token;
+HSPLandroid/media/browse/MediaBrowser;->access$1302(Landroid/media/browse/MediaBrowser;Landroid/os/Bundle;)Landroid/os/Bundle;
+HSPLandroid/media/browse/MediaBrowser;->access$1400(Landroid/media/browse/MediaBrowser;)Landroid/util/ArrayMap;
+HSPLandroid/media/browse/MediaBrowser;->access$1700(Landroid/media/browse/MediaBrowser;)Landroid/media/browse/MediaBrowser$ServiceCallbacks;
+HSPLandroid/media/browse/MediaBrowser;->access$1800(Landroid/media/browse/MediaBrowser;)Landroid/os/Bundle;
+HSPLandroid/media/browse/MediaBrowser;->access$1900(Landroid/media/browse/MediaBrowser;)Landroid/os/Handler;
+HSPLandroid/media/browse/MediaBrowser;->access$2000(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserServiceCallbacks;Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)V
+HSPLandroid/media/browse/MediaBrowser;->access$200(Landroid/media/browse/MediaBrowser;)Landroid/service/media/IMediaBrowserServiceCallbacks;
+HSPLandroid/media/browse/MediaBrowser;->access$202(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserServiceCallbacks;)Landroid/service/media/IMediaBrowserServiceCallbacks;
+HSPLandroid/media/browse/MediaBrowser;->access$2100(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/media/browse/MediaBrowser;->access$2200(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserServiceCallbacks;Ljava/lang/String;Landroid/content/pm/ParceledListSlice;Landroid/os/Bundle;)V
+HSPLandroid/media/browse/MediaBrowser;->access$300(Landroid/media/browse/MediaBrowser;)Landroid/content/ComponentName;
+HSPLandroid/media/browse/MediaBrowser;->access$400(Landroid/media/browse/MediaBrowser;)Landroid/media/browse/MediaBrowser$MediaServiceConnection;
+HSPLandroid/media/browse/MediaBrowser;->access$402(Landroid/media/browse/MediaBrowser;Landroid/media/browse/MediaBrowser$MediaServiceConnection;)Landroid/media/browse/MediaBrowser$MediaServiceConnection;
+HSPLandroid/media/browse/MediaBrowser;->access$600(Landroid/media/browse/MediaBrowser;)Landroid/content/Context;
+HSPLandroid/media/browse/MediaBrowser;->access$700(Landroid/media/browse/MediaBrowser;)V
+HSPLandroid/media/browse/MediaBrowser;->access$800(Landroid/media/browse/MediaBrowser;)Landroid/media/browse/MediaBrowser$ConnectionCallback;
+HSPLandroid/media/browse/MediaBrowser;->access$900(Landroid/media/browse/MediaBrowser;Landroid/service/media/IMediaBrowserServiceCallbacks;Ljava/lang/String;)Z
+HSPLandroid/media/browse/MediaBrowser;->connect()V
+HSPLandroid/media/browse/MediaBrowser;->disconnect()V
+HSPLandroid/media/browse/MediaBrowser;->forceCloseConnection()V
+HSPLandroid/media/browse/MediaBrowser;->getNewServiceCallbacks()Landroid/media/browse/MediaBrowser$ServiceCallbacks;
+HSPLandroid/media/browse/MediaBrowser;->getRoot()Ljava/lang/String;
+HSPLandroid/media/browse/MediaBrowser;-><init>(Landroid/content/Context;Landroid/content/ComponentName;Landroid/media/browse/MediaBrowser$ConnectionCallback;Landroid/os/Bundle;)V
+HSPLandroid/media/browse/MediaBrowser;->isConnected()Z
+HSPLandroid/media/browse/MediaBrowser;->isCurrent(Landroid/service/media/IMediaBrowserServiceCallbacks;Ljava/lang/String;)Z
+HSPLandroid/media/browse/MediaBrowser;->onConnectionFailed(Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/media/browse/MediaBrowser;->onLoadChildren(Landroid/service/media/IMediaBrowserServiceCallbacks;Ljava/lang/String;Landroid/content/pm/ParceledListSlice;Landroid/os/Bundle;)V
+HSPLandroid/media/browse/MediaBrowser;->onServiceConnected(Landroid/service/media/IMediaBrowserServiceCallbacks;Ljava/lang/String;Landroid/media/session/MediaSession$Token;Landroid/os/Bundle;)V
+HSPLandroid/media/browse/MediaBrowser;->subscribeInternal(Ljava/lang/String;Landroid/os/Bundle;Landroid/media/browse/MediaBrowser$SubscriptionCallback;)V
+HSPLandroid/media/browse/MediaBrowser;->subscribe(Ljava/lang/String;Landroid/media/browse/MediaBrowser$SubscriptionCallback;)V
+HSPLandroid/media/browse/MediaBrowser;->unsubscribeInternal(Ljava/lang/String;Landroid/media/browse/MediaBrowser$SubscriptionCallback;)V
+HSPLandroid/media/browse/MediaBrowser;->unsubscribe(Ljava/lang/String;)V
+HSPLandroid/media/browse/MediaBrowserUtils;->areSameOptions(Landroid/os/Bundle;Landroid/os/Bundle;)Z
+HSPLandroid/media/IAudioService$Stub$Proxy;->getLastAudibleStreamVolume(I)I
+HSPLandroid/media/IAudioService$Stub$Proxy;->getStreamMinVolume(I)I
+HSPLandroid/media/IAudioService$Stub$Proxy;->isStreamAffectedByMute(I)Z
+HSPLandroid/media/IAudioService$Stub$Proxy;->setRingtonePlayer(Landroid/media/IRingtonePlayer;)V
+HSPLandroid/media/IAudioService$Stub$Proxy;->setVolumeController(Landroid/media/IVolumeController;)V
+HSPLandroid/media/IAudioService$Stub$Proxy;->setVolumePolicy(Landroid/media/VolumePolicy;)V
+HSPLandroid/media/IMediaRouterService$Stub$Proxy;->registerClientGroupId(Landroid/media/IMediaRouterClient;Ljava/lang/String;)V
+HSPLandroid/media/IRemoteVolumeController$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/IRemoteVolumeController$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/media/IRingtonePlayer$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/IRingtonePlayer$Stub;-><init>()V
+HSPLandroid/media/IVolumeController$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/IVolumeController$Stub;-><init>()V
+HSPLandroid/media/IVolumeController$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/media/MediaDescription;->getMediaId()Ljava/lang/String;
+HSPLandroid/media/MediaDescription;->getTitle()Ljava/lang/CharSequence;
+HSPLandroid/media/MediaDescription;->toString()Ljava/lang/String;
+HSPLandroid/media/MediaRouter$Static;->setRouterGroupId(Ljava/lang/String;)V
+HSPLandroid/media/MediaRouter$VolumeCallback;-><init>()V
+HSPLandroid/media/MediaRouter;->setRouterGroupId(Ljava/lang/String;)V
+HSPLandroid/media/projection/IMediaProjectionManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/projection/IMediaProjectionManager;
+HSPLandroid/media/projection/IMediaProjectionWatcherCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/projection/IMediaProjectionWatcherCallback$Stub;-><init>()V
+HSPLandroid/media/projection/MediaProjectionManager;->addCallback(Landroid/media/projection/MediaProjectionManager$Callback;Landroid/os/Handler;)V
+HSPLandroid/media/projection/MediaProjectionManager;->getActiveProjectionInfo()Landroid/media/projection/MediaProjectionInfo;
+HSPLandroid/media/projection/MediaProjectionManager;-><init>(Landroid/content/Context;)V
+HSPLandroid/media/session/IActiveSessionsListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/session/IActiveSessionsListener$Stub;-><init>()V
+HSPLandroid/media/session/IActiveSessionsListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/media/session/ICallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/session/ICallback$Stub;-><init>()V
+HSPLandroid/media/session/ICallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/media/session/ISessionController$Stub$Proxy;->getMetadata()Landroid/media/MediaMetadata;
+HSPLandroid/media/session/ISessionController$Stub$Proxy;->getPackageName()Ljava/lang/String;
+HSPLandroid/media/session/ISessionController$Stub$Proxy;->getPlaybackState()Landroid/media/session/PlaybackState;
+HSPLandroid/media/session/ISessionController$Stub$Proxy;->getQueue()Landroid/content/pm/ParceledListSlice;
+HSPLandroid/media/session/ISessionController$Stub$Proxy;->getVolumeAttributes()Landroid/media/session/MediaController$PlaybackInfo;
+HSPLandroid/media/session/ISessionController$Stub$Proxy;->registerCallback(Ljava/lang/String;Landroid/media/session/ISessionControllerCallback;)V
+HSPLandroid/media/session/ISessionController$Stub$Proxy;->unregisterCallback(Landroid/media/session/ISessionControllerCallback;)V
+HSPLandroid/media/session/ISessionControllerCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/media/session/ISessionControllerCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/media/session/ISessionManager$Stub$Proxy;->addSessionsListener(Landroid/media/session/IActiveSessionsListener;Landroid/content/ComponentName;I)V
+HSPLandroid/media/session/ISessionManager$Stub$Proxy;->registerRemoteVolumeController(Landroid/media/IRemoteVolumeController;)V
+HSPLandroid/media/session/ISessionManager$Stub$Proxy;->removeSessionsListener(Landroid/media/session/IActiveSessionsListener;)V
+HSPLandroid/media/session/ISessionManager$Stub$Proxy;->setCallback(Landroid/media/session/ICallback;)V
+HSPLandroid/media/session/MediaController$CallbackStub;->onMetadataChanged(Landroid/media/MediaMetadata;)V
+HSPLandroid/media/session/MediaController$CallbackStub;->onPlaybackStateChanged(Landroid/media/session/PlaybackState;)V
+HSPLandroid/media/session/MediaController$CallbackStub;->onQueueTitleChanged(Ljava/lang/CharSequence;)V
+HSPLandroid/media/session/MediaController$CallbackStub;->onSessionDestroyed()V
+HSPLandroid/media/session/MediaController$MessageHandler;->access$102(Landroid/media/session/MediaController$MessageHandler;Z)Z
+HSPLandroid/media/session/MediaController$MessageHandler;->access$200(Landroid/media/session/MediaController$MessageHandler;)Landroid/media/session/MediaController$Callback;
+HSPLandroid/media/session/MediaController$MessageHandler;->handleMessage(Landroid/os/Message;)V
+HSPLandroid/media/session/MediaController$MessageHandler;-><init>(Landroid/os/Looper;Landroid/media/session/MediaController$Callback;)V
+HSPLandroid/media/session/MediaController$MessageHandler;->post(ILjava/lang/Object;Landroid/os/Bundle;)V
+HSPLandroid/media/session/MediaController;->access$600(Landroid/media/session/MediaController;ILjava/lang/Object;Landroid/os/Bundle;)V
+HSPLandroid/media/session/MediaController;->addCallbackLocked(Landroid/media/session/MediaController$Callback;Landroid/os/Handler;)V
+HSPLandroid/media/session/MediaController;->getHandlerForCallbackLocked(Landroid/media/session/MediaController$Callback;)Landroid/media/session/MediaController$MessageHandler;
+HSPLandroid/media/session/MediaController;->getMetadata()Landroid/media/MediaMetadata;
+HSPLandroid/media/session/MediaController;->getPackageName()Ljava/lang/String;
+HSPLandroid/media/session/MediaController;->getPlaybackInfo()Landroid/media/session/MediaController$PlaybackInfo;
+HSPLandroid/media/session/MediaController;->getPlaybackState()Landroid/media/session/PlaybackState;
+HSPLandroid/media/session/MediaController;->getQueue()Ljava/util/List;
+HSPLandroid/media/session/MediaController;->getTransportControls()Landroid/media/session/MediaController$TransportControls;
+HSPLandroid/media/session/MediaController;->postMessage(ILjava/lang/Object;Landroid/os/Bundle;)V
+HSPLandroid/media/session/MediaController;->registerCallback(Landroid/media/session/MediaController$Callback;Landroid/os/Handler;)V
+HSPLandroid/media/session/MediaController;->removeCallbackLocked(Landroid/media/session/MediaController$Callback;)Z
+HSPLandroid/media/session/MediaController;->unregisterCallback(Landroid/media/session/MediaController$Callback;)V
+HSPLandroid/media/session/MediaSession$Token;->equals(Ljava/lang/Object;)Z
+HSPLandroid/media/session/MediaSession$Token;->hashCode()I
+HSPLandroid/media/session/MediaSessionManager$CallbackImpl$4;-><init>(Landroid/media/session/MediaSessionManager$CallbackImpl;Landroid/content/ComponentName;)V
+HSPLandroid/media/session/MediaSessionManager$CallbackImpl$4;->run()V
+HSPLandroid/media/session/MediaSessionManager$CallbackImpl;->access$900(Landroid/media/session/MediaSessionManager$CallbackImpl;)Landroid/media/session/MediaSessionManager$Callback;
+HSPLandroid/media/session/MediaSessionManager$CallbackImpl;-><init>(Landroid/media/session/MediaSessionManager$Callback;Landroid/os/Handler;)V
+HSPLandroid/media/session/MediaSessionManager$CallbackImpl;->onAddressedPlayerChangedToMediaButtonReceiver(Landroid/content/ComponentName;)V
+HSPLandroid/media/session/MediaSessionManager$Callback;-><init>()V
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper$1$1;-><init>(Landroid/media/session/MediaSessionManager$SessionsChangedWrapper$1;Ljava/util/List;)V
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper$1$1;->run()V
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper$1;-><init>(Landroid/media/session/MediaSessionManager$SessionsChangedWrapper;)V
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper$1;->onActiveSessionsChanged(Ljava/util/List;)V
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper;->access$000(Landroid/media/session/MediaSessionManager$SessionsChangedWrapper;)Landroid/media/session/IActiveSessionsListener$Stub;
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper;->access$100(Landroid/media/session/MediaSessionManager$SessionsChangedWrapper;)V
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper;->access$200(Landroid/media/session/MediaSessionManager$SessionsChangedWrapper;)Landroid/os/Handler;
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper;->access$300(Landroid/media/session/MediaSessionManager$SessionsChangedWrapper;)Landroid/content/Context;
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper;->access$400(Landroid/media/session/MediaSessionManager$SessionsChangedWrapper;)Landroid/media/session/MediaSessionManager$OnActiveSessionsChangedListener;
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper;-><init>(Landroid/content/Context;Landroid/media/session/MediaSessionManager$OnActiveSessionsChangedListener;Landroid/os/Handler;)V
+HSPLandroid/media/session/MediaSessionManager$SessionsChangedWrapper;->release()V
+HSPLandroid/media/session/MediaSessionManager;->addOnActiveSessionsChangedListener(Landroid/media/session/MediaSessionManager$OnActiveSessionsChangedListener;Landroid/content/ComponentName;ILandroid/os/Handler;)V
+HSPLandroid/media/session/MediaSessionManager;->addOnActiveSessionsChangedListener(Landroid/media/session/MediaSessionManager$OnActiveSessionsChangedListener;Landroid/content/ComponentName;Landroid/os/Handler;)V
+HSPLandroid/media/session/MediaSessionManager;->registerRemoteVolumeController(Landroid/media/IRemoteVolumeController;)V
+HSPLandroid/media/session/MediaSessionManager;->removeOnActiveSessionsChangedListener(Landroid/media/session/MediaSessionManager$OnActiveSessionsChangedListener;)V
+HSPLandroid/media/session/MediaSessionManager;->setCallback(Landroid/media/session/MediaSessionManager$Callback;Landroid/os/Handler;)V
+HSPLandroid/media/SoundPool$Builder;-><init>()V
+HSPLandroid/media/SoundPool$Builder;->setMaxStreams(I)Landroid/media/SoundPool$Builder;
+HSPLandroid/media/SoundPool;->load(Landroid/content/Context;II)I
+HSPLandroid/media/VolumePolicy;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/metrics/LogMaker;->deserialize([Ljava/lang/Object;)V
+HSPLandroid/metrics/LogMaker;->getCategory()I
+HSPLandroid/metrics/LogMaker;->getCounterBucket()J
+HSPLandroid/metrics/LogMaker;->getCounterName()Ljava/lang/String;
+HSPLandroid/metrics/LogMaker;->getCounterValue()I
+HSPLandroid/metrics/LogMaker;->getSubtype()I
+HSPLandroid/metrics/LogMaker;->getTimestamp()J
+HSPLandroid/metrics/LogMaker;-><init>([Ljava/lang/Object;)V
+HSPLandroid/metrics/LogMaker;->isLongCounterBucket()Z
+HSPLandroid/metrics/LogMaker;->setProcessId(I)Landroid/metrics/LogMaker;
+HSPLandroid/metrics/LogMaker;->setTimestamp(J)Landroid/metrics/LogMaker;
+HSPLandroid/metrics/LogMaker;->setUid(I)Landroid/metrics/LogMaker;
+HSPLandroid/net/apf/ApfCapabilities$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/apf/ApfCapabilities;
+HSPLandroid/net/apf/ApfCapabilities$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/net/apf/ApfCapabilities;->getApfDrop8023Frames()Z
+HSPLandroid/net/apf/ApfCapabilities;->getApfEtherTypeBlackList()[I
+HSPLandroid/net/apf/ApfCapabilities;->hasDataAccess()Z
+HSPLandroid/net/apf/ApfCapabilities;-><init>(Landroid/os/Parcel;Landroid/net/apf/ApfCapabilities$1;)V
+HSPLandroid/net/apf/ApfCapabilities;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/net/apf/ApfCapabilities;->toString()Ljava/lang/String;
+HSPLandroid/net/ConnectivityManager;->getDefaultNetworkCapabilitiesForUser(I)[Landroid/net/NetworkCapabilities;
+HSPLandroid/net/ConnectivityManager;->getInstanceOrNull()Landroid/net/ConnectivityManager;
+HSPLandroid/net/ConnectivityManager;->reportNetworkConnectivity(Landroid/net/Network;Z)V
+HSPLandroid/net/ConnectivityManager;->shouldAvoidBadWifi()Z
+HSPLandroid/net/ConnectivityMetricsEvent;-><init>()V
+HSPLandroid/net/ConnectivityMetricsEvent;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/net/IConnectivityManager$Stub$Proxy;->getDefaultNetworkCapabilitiesForUser(I)[Landroid/net/NetworkCapabilities;
+HSPLandroid/net/IConnectivityManager$Stub$Proxy;->getVpnConfig(I)Lcom/android/internal/net/VpnConfig;
+HSPLandroid/net/IConnectivityManager$Stub$Proxy;->reportNetworkConnectivity(Landroid/net/Network;Z)V
+HSPLandroid/net/IConnectivityManager$Stub$Proxy;->shouldAvoidBadWifi()Z
+HSPLandroid/net/INetworkScoreCache$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/net/INetworkScoreService$Stub$Proxy;->getActiveScorerPackage()Ljava/lang/String;
+HSPLandroid/net/INetworkScoreService$Stub$Proxy;->updateScores([Landroid/net/ScoredNetwork;)Z
+HSPLandroid/net/INetworkStatsService$Stub$Proxy;->getTotalStats(I)J
+HSPLandroid/net/IpPrefix;->contains(Ljava/net/InetAddress;)Z
+HSPLandroid/net/LinkAddress;->equals(Ljava/lang/Object;)Z
+HSPLandroid/net/LinkProperties;->hasIpv4AddressOnInterface(Ljava/lang/String;)Z
+HSPLandroid/net/LinkProperties;->hasIpv6DnsServer()Z
+HSPLandroid/net/LinkProperties;->isIpv4Provisioned()Z
+HSPLandroid/net/LinkProperties;->isIpv6Provisioned()Z
+HSPLandroid/net/LinkProperties;->isProvisioned()Z
+HSPLandroid/net/LinkProperties;->isReachable(Ljava/net/InetAddress;)Z
+HSPLandroid/net/LinkProperties;->setTcpBufferSizes(Ljava/lang/String;)V
+HSPLandroid/net/LocalSocket;->createConnectedLocalSocket(Landroid/net/LocalSocketImpl;I)Landroid/net/LocalSocket;
+HSPLandroid/net/LocalSocket;->createConnectedLocalSocket(Ljava/io/FileDescriptor;)Landroid/net/LocalSocket;
+HSPLandroid/net/LocalSocketImpl;-><init>(Ljava/io/FileDescriptor;)V
+HSPLandroid/net/LocalSocket;-><init>(Landroid/net/LocalSocketImpl;I)V
+HSPLandroid/net/metrics/ApfProgramEvent;->flagsFor(ZZ)I
+HSPLandroid/net/metrics/IpConnectivityLog;-><init>()V
+HSPLandroid/net/metrics/IpConnectivityLog;->log(Landroid/net/metrics/IpConnectivityLog$Event;)Z
+HSPLandroid/net/metrics/IpConnectivityLog;->log(Landroid/net/Network;[ILandroid/net/metrics/IpConnectivityLog$Event;)Z
+HSPLandroid/net/metrics/IpConnectivityLog;->log(Ljava/lang/String;Landroid/net/metrics/IpConnectivityLog$Event;)Z
+HSPLandroid/net/metrics/IpConnectivityLog;->makeEv(Landroid/net/metrics/IpConnectivityLog$Event;)Landroid/net/ConnectivityMetricsEvent;
+HSPLandroid/net/NetworkCapabilities$1;->newArray(I)[Landroid/net/NetworkCapabilities;
+HSPLandroid/net/NetworkCapabilities$1;->newArray(I)[Ljava/lang/Object;
+HSPLandroid/net/NetworkCapabilities;->equalsTransportTypes(Landroid/net/NetworkCapabilities;)Z
+HSPLandroid/net/NetworkCapabilities;->setUids(Ljava/util/Set;)Landroid/net/NetworkCapabilities;
+HSPLandroid/net/NetworkInfo;->isAvailable()Z
+HSPLandroid/net/Network;-><init>(IZ)V
+HSPLandroid/net/Network;-><init>(Landroid/net/Network;)V
+HSPLandroid/net/NetworkKey;-><init>(Landroid/net/WifiKey;)V
+HSPLandroid/net/Network;->lambda$maybeInitUrlConnectionFactory$0$Network(Ljava/lang/String;)Ljava/util/List;
+HSPLandroid/net/Network;->maybeInitUrlConnectionFactory()V
+HSPLandroid/net/Network;->openConnection(Ljava/net/URL;Ljava/net/Proxy;)Ljava/net/URLConnection;
+HSPLandroid/net/Network;->openConnection(Ljava/net/URL;)Ljava/net/URLConnection;
+HSPLandroid/net/NetworkRequest$Builder;->setUids(Ljava/util/Set;)Landroid/net/NetworkRequest$Builder;
+HSPLandroid/net/NetworkScoreManager;->updateScores([Landroid/net/ScoredNetwork;)Z
+HSPLandroid/net/NetworkUtils;->protectFromVpn(Ljava/io/FileDescriptor;)Z
+HSPLandroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager;
+HSPLandroid/net/nsd/NsdManager;->access$000(Landroid/net/nsd/NsdManager;)Lcom/android/internal/util/AsyncChannel;
+HSPLandroid/net/nsd/NsdManager;->access$100(Landroid/net/nsd/NsdManager;)Ljava/util/concurrent/CountDownLatch;
+HSPLandroid/net/nsd/NsdManager;->getMessenger()Landroid/os/Messenger;
+HSPLandroid/net/nsd/NsdManager;-><init>(Landroid/content/Context;Landroid/net/nsd/INsdManager;)V
+HSPLandroid/net/nsd/NsdManager;->init()V
+HSPLandroid/net/RouteInfo;->getGateway()Ljava/net/InetAddress;
+HSPLandroid/net/RouteInfo;->getInterface()Ljava/lang/String;
+HSPLandroid/net/RouteInfo;->hasGateway()Z
+HSPLandroid/net/RouteInfo;->matches(Ljava/net/InetAddress;)Z
+HSPLandroid/net/ScoredNetwork;->calculateBadge(I)I
+HSPLandroid/net/ScoredNetwork;-><init>(Landroid/net/NetworkKey;Landroid/net/RssiCurve;ZLandroid/os/Bundle;)V
+HSPLandroid/net/ScoredNetwork;-><init>(Landroid/net/NetworkKey;Landroid/net/RssiCurve;Z)V
+HSPLandroid/net/ScoredNetwork;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/net/StaticIpConfiguration;->getDnsServers()Ljava/util/List;
+HSPLandroid/net/StaticIpConfiguration;->getDomains()Ljava/lang/String;
+HSPLandroid/net/StaticIpConfiguration;->getGateway()Ljava/net/InetAddress;
+HSPLandroid/net/StaticIpConfiguration;->getIpAddress()Landroid/net/LinkAddress;
+HSPLandroid/net/StaticIpConfiguration;->getRoutes(Ljava/lang/String;)Ljava/util/List;
+HSPLandroid/net/StaticIpConfiguration;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/net/TrafficStats;->clearThreadStatsUid()V
+HSPLandroid/net/TrafficStats;->getMobileRxBytes()J
+HSPLandroid/net/TrafficStats;->getMobileTxBytes()J
+HSPLandroid/net/TrafficStats;->getThreadStatsTag()I
+HSPLandroid/net/TrafficStats;->getTotalRxBytes()J
+HSPLandroid/net/TrafficStats;->setThreadStatsUid(I)V
+HSPLandroid/net/TrafficStats;->tagSocket(Ljava/net/Socket;)V
+HSPLandroid/net/Uri$AbstractPart;->getDecoded()Ljava/lang/String;
+HSPLandroid/net/Uri$HierarchicalUri;->getFragment()Ljava/lang/String;
+HSPLandroid/net/Uri$Part;->fromEncoded(Ljava/lang/String;)Landroid/net/Uri$Part;
+HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I
+HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I
+HSPLandroid/net/Uri$StringUri;->getEncodedFragment()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->getFragmentPart()Landroid/net/Uri$Part;
+HSPLandroid/net/Uri$StringUri;->parseFragment()Ljava/lang/String;
+HSPLandroid/net/wifi/ISoftApCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/net/wifi/ISoftApCallback$Stub;-><init>()V
+HSPLandroid/net/wifi/ISoftApCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/net/wifi/ITrafficStateCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/net/wifi/ITrafficStateCallback$Stub;-><init>()V
+HSPLandroid/net/wifi/ITrafficStateCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->acquireMulticastLock(Landroid/os/IBinder;Ljava/lang/String;)V
+HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->acquireWifiLock(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/WorkSource;)Z
+HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->getWifiApConfiguration()Landroid/net/wifi/WifiConfiguration;
+HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->registerSoftApCallback(Landroid/os/IBinder;Landroid/net/wifi/ISoftApCallback;I)V
+HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->registerTrafficStateCallback(Landroid/os/IBinder;Landroid/net/wifi/ITrafficStateCallback;I)V
+HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->releaseMulticastLock(Ljava/lang/String;)V
+HSPLandroid/net/wifi/IWifiManager$Stub$Proxy;->releaseWifiLock(Landroid/os/IBinder;)Z
+HSPLandroid/net/wifi/ScanResult;->is80211mcResponder()Z
+HSPLandroid/net/wifi/WifiInfo;->getIpAddress()I
+HSPLandroid/net/wifi/WifiInfo;->getMacAddress()Ljava/lang/String;
+HSPLandroid/net/wifi/WifiManager$WifiLock;->acquire()V
+HSPLandroid/net/wifi/WifiManager$WifiLock;->finalize()V
+HSPLandroid/net/wifi/WifiManager$WifiLock;->release()V
+HSPLandroid/net/wifi/WifiManager;->access$000(Landroid/net/wifi/WifiManager;)Z
+HSPLandroid/net/wifi/WifiManager;->access$800(Landroid/net/wifi/WifiManager;)I
+HSPLandroid/net/wifi/WifiManager;->access$808(Landroid/net/wifi/WifiManager;)I
+HSPLandroid/net/wifi/WifiManager;->access$810(Landroid/net/wifi/WifiManager;)I
+HSPLandroid/net/wifi/WifiManager;->createMulticastLock(Ljava/lang/String;)Landroid/net/wifi/WifiManager$MulticastLock;
+HSPLandroid/net/wifi/WifiManager;->registerSoftApCallback(Landroid/net/wifi/WifiManager$SoftApCallback;Landroid/os/Handler;)V
+HSPLandroid/net/wifi/WifiManager;->registerTrafficStateCallback(Landroid/net/wifi/WifiManager$TrafficStateCallback;Landroid/os/Handler;)V
+HSPLandroid/net/wifi/WifiNetworkAgentSpecifier$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/wifi/WifiNetworkAgentSpecifier;
+HSPLandroid/net/wifi/WifiNetworkAgentSpecifier$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/net/wifi/WifiNetworkScoreCache$CacheListener;->post(Ljava/util/List;)V
+HSPLandroid/net/wifi/WifiNetworkScoreCache;->registerListener(Landroid/net/wifi/WifiNetworkScoreCache$CacheListener;)V
+HSPLandroid/nfc/INfcAdapter$Stub;-><init>()V
+HSPLandroid/nfc/INfcAdapter$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/nfc/INfcCardEmulation$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/nfc/INfcCardEmulation$Stub;-><init>()V
+HSPLandroid/nfc/INfcFCardEmulation$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/nfc/INfcFCardEmulation$Stub;-><init>()V
+HSPLandroid/nfc/INfcTag$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/nfc/INfcTag$Stub;-><init>()V
+HSPLandroid/os/BaseBundle;->getDouble(Ljava/lang/String;)D
+HSPLandroid/os/BaseBundle;->getDouble(Ljava/lang/String;D)D
+HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;)F
+HSPLandroid/os/BaseBundle;-><init>(Landroid/os/Parcel;I)V
+HSPLandroid/os/BaseBundle;->putDouble(Ljava/lang/String;D)V
+HSPLandroid/os/Bundle;->getFloat(Ljava/lang/String;)F
+HSPLandroid/os/Bundle;->maybePrefillHasFds()V
+HSPLandroid/os/DropBoxManager$Entry;->getTimeMillis()J
+HSPLandroid/os/DropBoxManager;->getNextEntry(Ljava/lang/String;J)Landroid/os/DropBoxManager$Entry;
+HSPLandroid/os/Environment;->getExternalStoragePublicDirectory(Ljava/lang/String;)Ljava/io/File;
+HSPLandroid/os/Environment;->throwIfUserRequired()V
+HSPLandroid/os/FileUtils;->listFilesOrEmpty(Ljava/io/File;Ljava/io/FilenameFilter;)[Ljava/io/File;
+HSPLandroid/os/FileUtils;->listOrEmpty(Ljava/io/File;)[Ljava/lang/String;
+HSPLandroid/os/GraphicsEnvironment;->checkAngleWhitelist(Landroid/content/Context;Landroid/os/Bundle;Ljava/lang/String;)Z
+HSPLandroid/os/GraphicsEnvironment;->chooseDriverInternal(Landroid/content/Context;Landroid/os/Bundle;)Ljava/lang/String;
+HSPLandroid/os/GraphicsEnvironment;->shouldUseAngle(Landroid/content/Context;Landroid/os/Bundle;Ljava/lang/String;)Z
+HSPLandroid/os/Handler;->getPostMessage(Ljava/lang/Runnable;Ljava/lang/Object;)Landroid/os/Message;
+HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;Ljava/lang/Object;J)Z
+HSPLandroid/os/IPowerManager$Stub$Proxy;->getLastShutdownReason()I
+HSPLandroid/os/IPowerManager$Stub$Proxy;->getPowerSaveState(I)Landroid/os/PowerSaveState;
+HSPLandroid/os/IPowerManager$Stub$Proxy;->isLightDeviceIdleMode()Z
+HSPLandroid/os/IPowerManager$Stub$Proxy;->setDozeAfterScreenOff(Z)V
+HSPLandroid/os/IStatsManager$Stub$Proxy;->addConfiguration(J[BLjava/lang/String;)V
+HSPLandroid/os/IStatsManager$Stub$Proxy;->getData(JLjava/lang/String;)[B
+HSPLandroid/os/IStatsManager$Stub$Proxy;->registerPullerCallback(ILandroid/os/IStatsPullerCallback;Ljava/lang/String;)V
+HSPLandroid/os/IStatsManager$Stub$Proxy;->setDataFetchOperation(JLandroid/os/IBinder;Ljava/lang/String;)V
+HSPLandroid/os/IThermalEventListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/os/IUserManager$Stub$Proxy;->getProfileParent(I)Landroid/content/pm/UserInfo;
+HSPLandroid/os/IUserManager$Stub$Proxy;->getUserAccount(I)Ljava/lang/String;
+HSPLandroid/os/IUserManager$Stub$Proxy;->getUserHandle(I)I
+HSPLandroid/os/IUserManager$Stub$Proxy;->getUserIcon(I)Landroid/os/ParcelFileDescriptor;
+HSPLandroid/os/IUserManager$Stub$Proxy;->isQuietModeEnabled(I)Z
+HSPLandroid/os/IUserManager$Stub$Proxy;->isUserRunning(I)Z
+HSPLandroid/os/LocaleList;->toLanguageTags()Ljava/lang/String;
+HSPLandroid/os/Message;->getWhen()J
+HSPLandroid/os/MessageQueue;->addOnFileDescriptorEventListener(Ljava/io/FileDescriptor;ILandroid/os/MessageQueue$OnFileDescriptorEventListener;)V
+HSPLandroid/os/MessageQueue;->dispatchEvents(II)I
+HSPLandroid/os/MessageQueue;->removeOnFileDescriptorEventListener(Ljava/io/FileDescriptor;)V
+HSPLandroid/os/MessageQueue;->updateOnFileDescriptorEventListenerLocked(Ljava/io/FileDescriptor;ILandroid/os/MessageQueue$OnFileDescriptorEventListener;)V
+HSPLandroid/os/Message;->setAsynchronous(Z)V
+HSPLandroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
+HSPLandroid/os/Message;->setTarget(Landroid/os/Handler;)V
+HSPLandroid/os/Parcel;->createTypedArrayMap(Landroid/os/Parcelable$Creator;)Landroid/util/ArrayMap;
+HSPLandroid/os/ParcelFileDescriptor$AutoCloseInputStream;->read()I
+HSPLandroid/os/Parcel;->hasFileDescriptors()Z
+HSPLandroid/os/Parcel;->readCharSequenceList()Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->readFileDescriptor()Landroid/os/ParcelFileDescriptor;
+HSPLandroid/os/ParcelUuid;->getUuid()Ljava/util/UUID;
+HSPLandroid/os/ParcelUuid;-><init>(Ljava/util/UUID;)V
+HSPLandroid/os/ParcelUuid;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/os/Parcel;->writeFileDescriptor(Ljava/io/FileDescriptor;)V
+HSPLandroid/os/PersistableBundle;->toString()Ljava/lang/String;
+HSPLandroid/os/PowerManager;->getDefaultScreenBrightnessForVrSetting()I
+HSPLandroid/os/PowerManager;->getLastShutdownReason()I
+HSPLandroid/os/PowerManager;->getMaximumScreenBrightnessForVrSetting()I
+HSPLandroid/os/PowerManager;->getMinimumScreenBrightnessForVrSetting()I
+HSPLandroid/os/PowerManager;->setDozeAfterScreenOff(Z)V
+HSPLandroid/os/PowerSaveState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/PowerSaveState;
+HSPLandroid/os/PowerSaveState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/PowerSaveState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/os/StatFs;->getBlockCountLong()J
+HSPLandroid/os/storage/DiskInfo$1;->newArray(I)[Landroid/os/storage/DiskInfo;
+HSPLandroid/os/storage/DiskInfo$1;->newArray(I)[Ljava/lang/Object;
+HSPLandroid/os/storage/IStorageEventListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/os/storage/IStorageManager$Stub$Proxy;->getDisks()[Landroid/os/storage/DiskInfo;
+HSPLandroid/os/storage/IStorageManager$Stub$Proxy;->getVolumeRecords(I)[Landroid/os/storage/VolumeRecord;
+HSPLandroid/os/storage/IStorageManager$Stub$Proxy;->registerListener(Landroid/os/storage/IStorageEventListener;)V
+HSPLandroid/os/storage/StorageManager;->getDisks()Ljava/util/List;
+HSPLandroid/os/storage/StorageManager;->getVolumeRecords()Ljava/util/List;
+HSPLandroid/os/storage/VolumeRecord$1;->newArray(I)[Landroid/os/storage/VolumeRecord;
+HSPLandroid/os/storage/VolumeRecord$1;->newArray(I)[Ljava/lang/Object;
+HSPLandroid/os/Temperature$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/Temperature;
+HSPLandroid/os/Temperature$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/Temperature;-><init>(FILjava/lang/String;I)V
+HSPLandroid/os/Temperature;->isValidStatus(I)Z
+HSPLandroid/os/Temperature;->isValidType(I)Z
+HSPLandroid/os/Trace;->beginAsyncSection(Ljava/lang/String;I)V
+HSPLandroid/os/UserManager;->canAddMoreUsers()Z
+HSPLandroid/os/UserManager;->canSwitchUsers()Z
+HSPLandroid/os/UserManager;->getUserAccount(I)Ljava/lang/String;
+HSPLandroid/os/UserManager;->getUserCount()I
+HSPLandroid/os/UserManager;->getUserIcon(I)Landroid/graphics/Bitmap;
+HSPLandroid/os/UserManager;->isGuestUserEphemeral()Z
+HSPLandroid/os/UserManager;->isGuestUser(I)Z
+HSPLandroid/os/UserManager;->isGuestUser()Z
+HSPLandroid/os/WorkSource$WorkChain;->addNode(ILjava/lang/String;)Landroid/os/WorkSource$WorkChain;
+HSPLandroid/os/WorkSource$WorkChain;-><init>()V
+HSPLandroid/os/WorkSource$WorkChain;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/os/WorkSource;->createWorkChain()Landroid/os/WorkSource$WorkChain;
+HSPLandroid/os/WorkSource;->hashCode()I
+HSPLandroid/os/WorkSource;-><init>()V
+HSPLandroid/provider/ContactsContract$CommonDataKinds$Email;->getTypeLabel(Landroid/content/res/Resources;ILjava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/provider/ContactsContract$CommonDataKinds$Email;->getTypeLabelResource(I)I
+HSPLandroid/provider/DeviceConfig;->addOnPropertiesChangedListener(Ljava/lang/String;Ljava/util/concurrent/Executor;Landroid/provider/DeviceConfig$OnPropertiesChangedListener;)V
+HSPLandroid/provider/Settings$Secure;->isLocationProviderEnabled(Landroid/content/ContentResolver;Ljava/lang/String;)Z
+HSPLandroid/provider/Settings$System;->canWrite(Landroid/content/Context;)Z
+HSPLandroid/provider/Settings$System;->getFloatForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)F
+HSPLandroid/provider/Settings$System;->getFloat(Landroid/content/ContentResolver;Ljava/lang/String;)F
+HSPLandroid/provider/Settings;->isCallingPackageAllowedToWriteSettings(Landroid/content/Context;ILjava/lang/String;Z)Z
+HSPLandroid/security/keymaster/KeymasterArguments;-><init>()V
+HSPLandroid/security/keystore/KeyGenParameterSpec;->getBlockModes()[Ljava/lang/String;
+HSPLandroid/security/keystore/KeyGenParameterSpec;->getBoundToSpecificSecureUserId()J
+HSPLandroid/security/keystore/KeyGenParameterSpec;->getEncryptionPaddings()[Ljava/lang/String;
+HSPLandroid/security/keystore/KeyGenParameterSpec;->getKeySize()I
+HSPLandroid/security/keystore/KeyGenParameterSpec;->getKeystoreAlias()Ljava/lang/String;
+HSPLandroid/security/keystore/KeyGenParameterSpec;->getPurposes()I
+HSPLandroid/security/keystore/KeyGenParameterSpec;->getSignaturePaddings()[Ljava/lang/String;
+HSPLandroid/security/keystore/KeyGenParameterSpec;->getUserAuthenticationValidityDurationSeconds()I
+HSPLandroid/security/keystore/KeyGenParameterSpec;-><init>(Ljava/lang/String;IILjava/security/spec/AlgorithmParameterSpec;Ljavax/security/auth/x500/X500Principal;Ljava/math/BigInteger;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;I[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ZZIZ[BZZZZZZ)V
+HSPLandroid/security/keystore/KeyGenParameterSpec;->isDigestsSpecified()Z
+HSPLandroid/security/keystore/KeyGenParameterSpec;->isRandomizedEncryptionRequired()Z
+HSPLandroid/security/keystore/KeyGenParameterSpec;->isUnlockedDeviceRequired()Z
+HSPLandroid/security/keystore/KeyGenParameterSpec;->isUserAuthenticationRequired()Z
+HSPLandroid/security/keystore/KeyGenParameterSpec;->isUserConfirmationRequired()Z
+HSPLandroid/security/keystore/KeyGenParameterSpec;->isUserPresenceRequired()Z
+HSPLandroid/security/keystore/recovery/RecoveryController;->getInstance(Landroid/content/Context;)Landroid/security/keystore/recovery/RecoveryController;
+HSPLandroid/security/keystore/recovery/RecoveryController;->getRecoverySecretTypes()[I
+HSPLandroid/security/keystore/recovery/RecoveryController;-><init>(Lcom/android/internal/widget/ILockSettings;Landroid/security/KeyStore;)V
+HSPLandroid/security/keystore/recovery/RecoveryController;->initRecoveryService(Ljava/lang/String;[B[B)V
+HSPLandroid/security/keystore/recovery/RecoveryController;->setRecoverySecretTypes([I)V
+HSPLandroid/security/keystore/recovery/RecoveryController;->setServerParams([B)V
+HSPLandroid/security/keystore/recovery/RecoveryController;->setSnapshotCreatedPendingIntent(Landroid/app/PendingIntent;)V
+HSPLandroid/service/dreams/IDreamManager$Stub$Proxy;->forceAmbientDisplayEnabled(Z)V
+HSPLandroid/service/euicc/GetEuiccProfileInfoListResult;->getResult()I
+HSPLandroid/service/gatekeeper/IGateKeeperService$Stub$Proxy;->getSecureUserId(I)J
+HSPLandroid/service/media/IMediaBrowserService$Stub$Proxy;->addSubscriptionDeprecated(Ljava/lang/String;Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/service/media/IMediaBrowserService$Stub$Proxy;->addSubscription(Ljava/lang/String;Landroid/os/IBinder;Landroid/os/Bundle;Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/service/media/IMediaBrowserService$Stub$Proxy;->connect(Ljava/lang/String;Landroid/os/Bundle;Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/service/media/IMediaBrowserService$Stub$Proxy;->disconnect(Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/service/media/IMediaBrowserService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/service/media/IMediaBrowserService$Stub$Proxy;->removeSubscriptionDeprecated(Ljava/lang/String;Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/service/media/IMediaBrowserService$Stub$Proxy;->removeSubscription(Ljava/lang/String;Landroid/os/IBinder;Landroid/service/media/IMediaBrowserServiceCallbacks;)V
+HSPLandroid/service/media/IMediaBrowserService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserService;
+HSPLandroid/service/media/IMediaBrowserServiceCallbacks$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/service/media/IMediaBrowserServiceCallbacks$Stub;-><init>()V
+HSPLandroid/service/media/IMediaBrowserServiceCallbacks$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/service/notification/INotificationListener$Stub;-><init>()V
+HSPLandroid/service/notification/NotificationListenerService$MyHandler;-><init>(Landroid/service/notification/NotificationListenerService;Landroid/os/Looper;)V
+HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;-><init>(Landroid/service/notification/NotificationListenerService;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->canBubble()Z
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->canShowBadge()Z
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getKey()Ljava/lang/String;
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getLastAudiblyAlertedMillis()J
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getOverrideGroupKey()Ljava/lang/String;
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getRank()I
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getSmartActions()Ljava/util/List;
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getSmartReplies()Ljava/util/List;
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getSnoozeCriteria()Ljava/util/List;
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getSuppressedVisualEffects()I
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getUserSentiment()I
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->getVisibilityOverride()I
+HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->isAmbient()Z
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->isSuspended()Z
+HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/NotificationListenerService$RankingMap;
+HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;Landroid/service/notification/NotificationListenerService$1;)V
+HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V
+HSPLandroid/service/notification/NotificationListenerService;->attachBaseContext(Landroid/content/Context;)V
+HSPLandroid/service/notification/NotificationListenerService;->getCurrentRanking()Landroid/service/notification/NotificationListenerService$RankingMap;
+HSPLandroid/service/notification/NotificationListenerService;->getNotificationInterface()Landroid/app/INotificationManager;
+HSPLandroid/service/notification/NotificationListenerService;->onBind(Landroid/content/Intent;)Landroid/os/IBinder;
+HSPLandroid/service/notification/NotificationListenerService;->onListenerConnected()V
+HSPLandroid/service/notification/NotificationListenerService;->onNotificationPosted(Landroid/service/notification/StatusBarNotification;Landroid/service/notification/NotificationListenerService$RankingMap;)V
+HSPLandroid/service/notification/NotificationListenerService;->onNotificationRemoved(Landroid/service/notification/StatusBarNotification;Landroid/service/notification/NotificationListenerService$RankingMap;)V
+HSPLandroid/service/notification/NotificationListenerService;->onNotificationRemoved(Landroid/service/notification/StatusBarNotification;)V
+HSPLandroid/service/notification/NotificationListenerService;->registerAsSystemService(Landroid/content/Context;Landroid/content/ComponentName;I)V
+HSPLandroid/service/notification/NotificationListenerService;->requestRebind(Landroid/content/ComponentName;)V
+HSPLandroid/service/notification/NotificationListenerService;->setNotificationsShown([Ljava/lang/String;)V
+HSPLandroid/service/notification/NotificationRankingUpdate;->getRankingMap()Landroid/service/notification/NotificationListenerService$RankingMap;
+HSPLandroid/service/notification/StatusBarNotification;->getPackageContext(Landroid/content/Context;)Landroid/content/Context;
+HSPLandroid/service/notification/StatusBarNotification;->isClearable()Z
+HSPLandroid/service/notification/ZenModeConfig$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/ZenModeConfig;
+HSPLandroid/service/notification/ZenModeConfig$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/service/notification/ZenModeConfig;->getDescription(Landroid/content/Context;ZLandroid/service/notification/ZenModeConfig;Z)Ljava/lang/String;
+HSPLandroid/service/notification/ZenModeConfig;->isZenOverridingRinger(ILandroid/app/NotificationManager$Policy;)Z
+HSPLandroid/service/persistentdata/IPersistentDataBlockService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/persistentdata/IPersistentDataBlockService;
+HSPLandroid/service/persistentdata/PersistentDataBlockManager;->getMaximumDataBlockSize()J
+HSPLandroid/service/persistentdata/PersistentDataBlockManager;-><init>(Landroid/service/persistentdata/IPersistentDataBlockService;)V
+HSPLandroid/service/persistentdata/PersistentDataBlockManager;->read()[B
+HSPLandroid/service/persistentdata/PersistentDataBlockManager;->write([B)I
+HSPLandroid/service/textclassifier/TextClassifierService;->getDefaultTextClassifierImplementation(Landroid/content/Context;)Landroid/view/textclassifier/TextClassifier;
+HSPLandroid/service/wallpaper/IWallpaperService$Stub;-><init>()V
+HSPLandroid/system/NetlinkSocketAddress;-><init>(II)V
+HSPLandroid/system/Os;->bind(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V
+HSPLandroid/system/Os;->connect(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V
+HSPLandroid/system/Os;->connect(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V
+HSPLandroid/system/Os;->getsockname(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;
+HSPLandroid/system/Os;->prctl(IJJJJ)I
+HSPLandroid/system/Os;->sendto(Ljava/io/FileDescriptor;[BIIILjava/net/SocketAddress;)I
+HSPLandroid/system/Os;->setsockoptIfreq(Ljava/io/FileDescriptor;IILjava/lang/String;)V
+HSPLandroid/system/Os;->setsockoptInt(Ljava/io/FileDescriptor;III)V
+HSPLandroid/system/PacketSocketAddress;-><init>(I[B)V
+HSPLandroid/system/PacketSocketAddress;-><init>(SISB[B)V
+HSPLandroid/system/PacketSocketAddress;-><init>(SI)V
+HSPLandroid/system/StructGroupReq;-><init>(ILjava/net/InetAddress;)V
+HSPLandroid/system/StructTimeval;-><init>(JJ)V
+HSPLandroid/telecom/TelecomManager;->getTelecomService()Lcom/android/internal/telecom/ITelecomService;
+HSPLandroid/telecom/TelecomManager;->isServiceConnected()Z
+HSPLandroid/telecom/TelecomManager;->setUserSelectedOutgoingPhoneAccount(Landroid/telecom/PhoneAccountHandle;)V
+HSPLandroid/telephony/CellIdentity$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/CellIdentity;
+HSPLandroid/telephony/CellIdentity$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/telephony/CellIdentity;->getOperatorAlphaLong()Ljava/lang/CharSequence;
+HSPLandroid/telephony/CellIdentity;->getOperatorAlphaShort()Ljava/lang/CharSequence;
+HSPLandroid/telephony/CellIdentity;->inRangeOrUnavailable(III)I
+HSPLandroid/telephony/CellIdentityLte;->createFromParcelBody(Landroid/os/Parcel;)Landroid/telephony/CellIdentityLte;
+HSPLandroid/telephony/CellIdentityLte;->getCi()I
+HSPLandroid/telephony/CellIdentityLte;->getMnc()I
+HSPLandroid/telephony/CellIdentityLte;->getPci()I
+HSPLandroid/telephony/CellIdentityLte;->getTac()I
+HSPLandroid/telephony/CellIdentityLte;-><init>(IIIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/telephony/CellIdentityLte;-><init>(Landroid/hardware/radio/V1_0/CellIdentityLte;)V
+HSPLandroid/telephony/CellIdentity;->setOperatorAlphaLong(Ljava/lang/String;)V
+HSPLandroid/telephony/CellIdentity;->setOperatorAlphaShort(Ljava/lang/String;)V
+HSPLandroid/telephony/CellInfo;->create(Landroid/hardware/radio/V1_0/CellInfo;)Landroid/telephony/CellInfo;
+HSPLandroid/telephony/CellInfo;-><init>(Landroid/hardware/radio/V1_0/CellInfo;)V
+HSPLandroid/telephony/CellInfoLte;->getCellIdentity()Landroid/telephony/CellIdentityLte;
+HSPLandroid/telephony/CellInfoLte;->getCellSignalStrength()Landroid/telephony/CellSignalStrengthLte;
+HSPLandroid/telephony/CellInfoLte;-><init>(Landroid/hardware/radio/V1_0/CellInfo;)V
+HSPLandroid/telephony/CellSignalStrengthCdma;-><init>(Landroid/hardware/radio/V1_0/CdmaSignalStrength;Landroid/hardware/radio/V1_0/EvdoSignalStrength;)V
+HSPLandroid/telephony/CellSignalStrength;->getRssiDbmFromAsu(I)I
+HSPLandroid/telephony/CellSignalStrengthGsm;-><init>(Landroid/hardware/radio/V1_0/GsmSignalStrength;)V
+HSPLandroid/telephony/CellSignalStrengthGsm;->setDefaultValues()V
+HSPLandroid/telephony/CellSignalStrengthLte;->getTimingAdvance()I
+HSPLandroid/telephony/CellSignalStrengthTdscdma;-><init>(Landroid/hardware/radio/V1_0/TdScdmaSignalStrength;)V
+HSPLandroid/telephony/CellSignalStrengthTdscdma;->setDefaultValues()V
+HSPLandroid/telephony/data/ApnSetting$Builder;->build()Landroid/telephony/data/ApnSetting;
+HSPLandroid/telephony/data/ApnSetting;->getApnTypes()Ljava/util/List;
+HSPLandroid/telephony/DataSpecificRegistrationInfo;-><init>(IZZZLandroid/telephony/LteVopsSupportInfo;Z)V
+HSPLandroid/telephony/DataSpecificRegistrationInfo;-><init>(Landroid/telephony/DataSpecificRegistrationInfo;)V
+HSPLandroid/telephony/emergency/EmergencyNumber;->compareTo(Landroid/telephony/emergency/EmergencyNumber;)I
+HSPLandroid/telephony/emergency/EmergencyNumber;->getCountryIso()Ljava/lang/String;
+HSPLandroid/telephony/emergency/EmergencyNumber;->getEmergencyCallRouting()I
+HSPLandroid/telephony/emergency/EmergencyNumber;->getEmergencyNumberSourceBitmask()I
+HSPLandroid/telephony/emergency/EmergencyNumber;->getEmergencyServiceCategoryBitmask()I
+HSPLandroid/telephony/emergency/EmergencyNumber;->getEmergencyUrns()Ljava/util/List;
+HSPLandroid/telephony/emergency/EmergencyNumber;->getMnc()Ljava/lang/String;
+HSPLandroid/telephony/emergency/EmergencyNumber;->getNumber()Ljava/lang/String;
+HSPLandroid/telephony/emergency/EmergencyNumber;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/util/List;II)V
+HSPLandroid/telephony/emergency/EmergencyNumber;->mergeSameEmergencyNumbers(Landroid/telephony/emergency/EmergencyNumber;Landroid/telephony/emergency/EmergencyNumber;)Landroid/telephony/emergency/EmergencyNumber;
+HSPLandroid/telephony/IccOpenLogicalChannelResponse;-><init>(II[B)V
+HSPLandroid/telephony/IccOpenLogicalChannelResponse;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/telephony/ims/aidl/IImsConfig$Stub;-><init>()V
+HSPLandroid/telephony/ims/feature/ImsFeature;->initialize(Landroid/content/Context;I)V
+HSPLandroid/telephony/ims/feature/MmTelFeature;->getBinder()Landroid/telephony/ims/aidl/IImsMmTelFeature;
+HSPLandroid/telephony/ims/feature/MmTelFeature;->getSmsImplementation()Landroid/telephony/ims/stub/ImsSmsImplBase;
+HSPLandroid/telephony/ims/stub/ImsConfigImplBase$ImsConfigStub;-><init>(Landroid/telephony/ims/stub/ImsConfigImplBase;)V
+HSPLandroid/telephony/ims/stub/ImsConfigImplBase;-><init>()V
+HSPLandroid/telephony/ims/stub/ImsRegistrationImplBase;->getBinder()Landroid/telephony/ims/aidl/IImsRegistration;
+HSPLandroid/telephony/ims/stub/ImsSmsImplBase;->onReady()V
+HSPLandroid/telephony/LocationAccessPolicy$LocationPermissionQuery$Builder;->setLogAsInfo(Z)Landroid/telephony/LocationAccessPolicy$LocationPermissionQuery$Builder;
+HSPLandroid/telephony/LocationAccessPolicy;->logError(Landroid/content/Context;Landroid/telephony/LocationAccessPolicy$LocationPermissionQuery;Ljava/lang/String;)V
+HSPLandroid/telephony/NetworkRegistrationInfo$Builder;->build()Landroid/telephony/NetworkRegistrationInfo;
+HSPLandroid/telephony/NetworkRegistrationInfo$Builder;-><init>()V
+HSPLandroid/telephony/NetworkRegistrationInfo$Builder;->setDomain(I)Landroid/telephony/NetworkRegistrationInfo$Builder;
+HSPLandroid/telephony/NetworkRegistrationInfo$Builder;->setRegistrationState(I)Landroid/telephony/NetworkRegistrationInfo$Builder;
+HSPLandroid/telephony/NetworkRegistrationInfo$Builder;->setTransportType(I)Landroid/telephony/NetworkRegistrationInfo$Builder;
+HSPLandroid/telephony/NetworkRegistrationInfo;->getCellIdentity()Landroid/telephony/CellIdentity;
+HSPLandroid/telephony/NetworkRegistrationInfo;->getDomain()I
+HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(IIIIIZLjava/util/List;Landroid/telephony/CellIdentity;IZZZLandroid/telephony/LteVopsSupportInfo;Z)V
+HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(IIIIIZLjava/util/List;Landroid/telephony/CellIdentity;Landroid/telephony/NetworkRegistrationInfo$1;)V
+HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/telephony/NetworkRegistrationInfo;)V
+HSPLandroid/telephony/NetworkRegistrationInfo;->updateNrState(Landroid/telephony/DataSpecificRegistrationInfo;)V
+HSPLandroid/telephony/PhoneNumberUtils;->charToBCD(CI)I
+HSPLandroid/telephony/PhoneNumberUtils;->isEmergencyNumberInternal(ILjava/lang/String;Ljava/lang/String;Z)Z
+HSPLandroid/telephony/PhoneNumberUtils;->networkPortionToCalledPartyBCD(Ljava/lang/String;)[B
+HSPLandroid/telephony/PhoneNumberUtils;->numberToCalledPartyBCDHelper(Ljava/lang/String;ZI)[B
+HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->lambda$onActiveDataSubIdChanged$52(Landroid/telephony/PhoneStateListener;I)V
+HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->lambda$onActiveDataSubIdChanged$53$PhoneStateListener$IPhoneStateListenerStub(Landroid/telephony/PhoneStateListener;I)V
+HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->lambda$onCarrierNetworkChange$40(Landroid/telephony/PhoneStateListener;Z)V
+HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->lambda$onCarrierNetworkChange$41$PhoneStateListener$IPhoneStateListenerStub(Landroid/telephony/PhoneStateListener;Z)V
+HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->onActiveDataSubIdChanged(I)V
+HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub;->onCarrierNetworkChange(Z)V
+HSPLandroid/telephony/PhoneStateListener;->onCallStateChanged(ILjava/lang/String;)V
+HSPLandroid/telephony/ServiceState;->bearerBitmapHasCdma(I)Z
+HSPLandroid/telephony/ServiceState;->getChannelNumber()I
+HSPLandroid/telephony/ServiceState;->getNetworkRegistrationInfoListForDomain(I)Ljava/util/List;
+HSPLandroid/telephony/ServiceState;->getNetworkRegistrationInfoList()Ljava/util/List;
+HSPLandroid/telephony/ServiceState;->getOperatorAlphaShort()Ljava/lang/String;
+HSPLandroid/telephony/ServiceState;->init()V
+HSPLandroid/telephony/ServiceState;->networkBitmaskHasAccessNetworkType(II)Z
+HSPLandroid/telephony/ServiceState;->networkTypeToAccessNetworkType(I)I
+HSPLandroid/telephony/ServiceState;->setIwlanPreferred(Z)V
+HSPLandroid/telephony/ServiceState;->setOperatorAlphaLongRaw(Ljava/lang/String;)V
+HSPLandroid/telephony/ServiceState;->setOperatorAlphaShortRaw(Ljava/lang/String;)V
+HSPLandroid/telephony/SignalStrength;-><init>(Landroid/hardware/radio/V1_0/SignalStrength;)V
+HSPLandroid/telephony/SignalStrength;-><init>(Landroid/telephony/CellSignalStrengthCdma;Landroid/telephony/CellSignalStrengthGsm;Landroid/telephony/CellSignalStrengthWcdma;Landroid/telephony/CellSignalStrengthTdscdma;Landroid/telephony/CellSignalStrengthLte;Landroid/telephony/CellSignalStrengthNr;)V
+HSPLandroid/telephony/SubscriptionInfo;->equals(Ljava/lang/Object;)Z
+HSPLandroid/telephony/SubscriptionInfo;->getDataRoaming()I
+HSPLandroid/telephony/SubscriptionInfo;-><init>(ILjava/lang/String;ILjava/lang/CharSequence;Ljava/lang/CharSequence;IILjava/lang/String;ILandroid/graphics/Bitmap;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z[Landroid/telephony/UiccAccessRule;Ljava/lang/String;IZLjava/lang/String;ZIIILjava/lang/String;)V
+HSPLandroid/telephony/SubscriptionManager;->isUsableSubscriptionId(I)Z
+HSPLandroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getGroupIdLevel1(I)Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getITelephony()Lcom/android/internal/telephony/ITelephony;
+HSPLandroid/telephony/TelephonyManager;->getLine1AlphaTag(I)Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getLine1AlphaTag()Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getNetworkOperator(I)Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getNetworkType(I)I
+HSPLandroid/telephony/TelephonyManager;->getOpPackageName()Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getPhoneAccountHandleForSubscriptionId(I)Landroid/telecom/PhoneAccountHandle;
+HSPLandroid/telephony/TelephonyManager;->getSimSerialNumber(I)Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getSimSerialNumber()Ljava/lang/String;
+HSPLandroid/telephony/TelephonyManager;->getSubId()I
+HSPLandroid/telephony/TelephonyManager;->getSubscriberInfo()Lcom/android/internal/telephony/IPhoneSubInfo;
+HSPLandroid/telephony/VisualVoicemailSmsFilterSettings$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/VisualVoicemailSmsFilterSettings;
+HSPLandroid/telephony/VisualVoicemailSmsFilterSettings$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/telephony/VisualVoicemailSmsFilterSettings;-><init>(Landroid/telephony/VisualVoicemailSmsFilterSettings$Builder;Landroid/telephony/VisualVoicemailSmsFilterSettings$1;)V
+HSPLandroid/telephony/VisualVoicemailSmsFilterSettings;-><init>(Landroid/telephony/VisualVoicemailSmsFilterSettings$Builder;)V
+HSPLandroid/telephony/VoiceSpecificRegistrationInfo;-><init>(Landroid/telephony/VoiceSpecificRegistrationInfo;)V
+HSPLandroid/text/format/DateFormat;->hasSeconds(Ljava/lang/CharSequence;)Z
+HSPLandroid/text/format/DateUtils;->getRelativeTimeSpanString(JJJI)Ljava/lang/CharSequence;
+HSPLandroid/text/format/DateUtils;->getRelativeTimeSpanString(JJJ)Ljava/lang/CharSequence;
+HSPLandroid/text/InputFilter$LengthFilter;->filter(Ljava/lang/CharSequence;IILandroid/text/Spanned;II)Ljava/lang/CharSequence;
+HSPLandroid/text/InputFilter$LengthFilter;-><init>(I)V
+HSPLandroid/text/StaticLayout$Builder;->setAlignment(Landroid/text/Layout$Alignment;)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setBreakStrategy(I)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setEllipsizedWidth(I)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setEllipsize(Landroid/text/TextUtils$TruncateAt;)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setHyphenationFrequency(I)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setIncludePad(Z)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setIndents([I[I)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setLineSpacing(FF)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setMaxLines(I)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setTextDirection(Landroid/text/TextDirectionHeuristic;)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout$Builder;->setUseLineSpacingFromFallbacks(Z)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;)Ljava/lang/CharSequence;
+HSPLandroid/text/TextUtils;->emptyIfNull(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/transition/Transition;->addTarget(I)Landroid/transition/Transition;
+HSPLandroid/transition/Transition;->setInterpolator(Landroid/animation/TimeInterpolator;)Landroid/transition/Transition;
+HSPLandroid/transition/TransitionSet;->setDuration(J)Landroid/transition/TransitionSet;
+HSPLandroid/transition/TransitionSet;->setInterpolator(Landroid/animation/TimeInterpolator;)Landroid/transition/TransitionSet;
+HSPLandroid/transition/Visibility;-><init>()V
+HSPLandroid/util/ArrayMap;->containsValue(Ljava/lang/Object;)Z
+HSPLandroid/util/ArraySet;->removeAll(Landroid/util/ArraySet;)Z
+HSPLandroid/util/EventLog$Event;->getProcessId()I
+HSPLandroid/util/EventLog$Event;->getTag()I
+HSPLandroid/util/EventLog$Event;->getTimeNanos()J
+HSPLandroid/util/FloatProperty;->set(Ljava/lang/Object;Ljava/lang/Float;)V
+HSPLandroid/util/FloatProperty;->set(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroid/util/IntProperty;-><init>(Ljava/lang/String;)V
+HSPLandroid/util/IntProperty;->set(Ljava/lang/Object;Ljava/lang/Integer;)V
+HSPLandroid/util/IntProperty;->set(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLandroid/util/LongSparseArray;->indexOfValue(Ljava/lang/Object;)I
+HSPLandroid/util/MathUtils;->constrain(FFF)F
+HSPLandroid/util/MathUtils;->fitRect(Landroid/graphics/Rect;I)V
+HSPLandroid/util/PathParser$PathData;->setPathData(Landroid/util/PathParser$PathData;)V
+HSPLandroid/util/PathParser;->access$300(JJ)V
+HSPLandroid/util/Range;->clamp(Ljava/lang/Comparable;)Ljava/lang/Comparable;
+HSPLandroid/util/StatsLogInternal;->write(ILandroid/os/WorkSource;IZZZ)V
+HSPLandroid/view/accessibility/AccessibilityManager;->getServiceLocked()Landroid/view/accessibility/IAccessibilityManager;
+HSPLandroid/view/accessibility/AccessibilityManager;->setPictureInPictureActionReplacingConnection(Landroid/view/accessibility/IAccessibilityInteractionConnection;)V
+HSPLandroid/view/accessibility/IAccessibilityInteractionConnection$Stub;-><init>()V
+HSPLandroid/view/accessibility/IAccessibilityManager$Stub$Proxy;->setPictureInPictureActionReplacingConnection(Landroid/view/accessibility/IAccessibilityInteractionConnection;)V
+HSPLandroid/view/animation/BaseInterpolator;-><init>()V
+HSPLandroid/view/animation/OvershootInterpolator;-><init>(F)V
+HSPLandroid/view/animation/PathInterpolator;-><init>(Landroid/graphics/Path;)V
+HSPLandroid/view/CompositionSamplingListener;-><init>(Ljava/util/concurrent/Executor;)V
+HSPLandroid/view/DisplayAddress$Physical$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/DisplayAddress$Physical;
+HSPLandroid/view/DisplayAddress$Physical$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/view/DisplayAddress$Physical;-><init>(JLandroid/view/DisplayAddress$1;)V
+HSPLandroid/view/DisplayAddress$Physical;-><init>(J)V
+HSPLandroid/view/DisplayAddress;-><init>()V
+HSPLandroid/view/Display;->getAppVsyncOffsetNanos()J
+HSPLandroid/view/Display;->getCurrentSizeRange(Landroid/graphics/Point;Landroid/graphics/Point;)V
+HSPLandroid/view/Display;->getPresentationDeadlineNanos()J
+HSPLandroid/view/Display;->updateDisplayInfoLocked()V
+HSPLandroid/view/GestureDetector;->recordGestureClassification(I)V
+HSPLandroid/view/GestureExclusionTracker;->computeChangedRects()Ljava/util/List;
+HSPLandroid/view/GestureExclusionTracker;->updateRectsForView(Landroid/view/View;)V
+HSPLandroid/view/IDockedStackListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/view/IDockedStackListener$Stub;-><init>()V
+HSPLandroid/view/IDockedStackListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/view/InputDevice$MotionRange;->getAxis()I
+HSPLandroid/view/InputDevice$MotionRange;->getSource()I
+HSPLandroid/view/InputDevice;->getMotionRanges()Ljava/util/List;
+HSPLandroid/view/InputDevice;->getSources()I
+HSPLandroid/view/InputDevice;->hasKeys([I)[Z
+HSPLandroid/view/inputmethod/InputMethodSubtype;->isAuxiliary()Z
+HSPLandroid/view/InsetsController;->calculateInsets(ZZLandroid/view/DisplayCutout;Landroid/graphics/Rect;Landroid/graphics/Rect;I)Landroid/view/WindowInsets;
+HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Z)Landroid/graphics/Insets;
+HSPLandroid/view/InsetsSource;->isVisible()Z
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;ZZLandroid/view/DisplayCutout;Landroid/graphics/Rect;Landroid/graphics/Rect;ILandroid/util/SparseIntArray;)Landroid/view/WindowInsets;
+HSPLandroid/view/InsetsState;->processSourceAsPublicType(Landroid/view/InsetsSource;[Landroid/graphics/Insets;Landroid/util/SparseIntArray;[ZLandroid/graphics/Insets;I)V
+HSPLandroid/view/InsetsState;->processSource(Landroid/view/InsetsSource;Landroid/graphics/Rect;Z[Landroid/graphics/Insets;Landroid/util/SparseIntArray;[Z)V
+HSPLandroid/view/InsetsState;->toPublicType(I)I
+HSPLandroid/view/IPinnedStackController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IPinnedStackController;
+HSPLandroid/view/IPinnedStackListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/view/IPinnedStackListener$Stub;-><init>()V
+HSPLandroid/view/IPinnedStackListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/view/IRotationWatcher$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/view/IRotationWatcher$Stub;-><init>()V
+HSPLandroid/view/IWallpaperVisibilityListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLandroid/view/IWallpaperVisibilityListener$Stub;-><init>()V
+HSPLandroid/view/IWallpaperVisibilityListener$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLandroid/view/IWindowManager$Stub$Proxy;->createInputConsumer(Landroid/os/IBinder;Ljava/lang/String;ILandroid/view/InputChannel;)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->destroyInputConsumer(Ljava/lang/String;I)Z
+HSPLandroid/view/IWindowManager$Stub$Proxy;->freezeRotation(I)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->getDockedStackSide()I
+HSPLandroid/view/IWindowManager$Stub$Proxy;->getInitialDisplaySize(ILandroid/graphics/Point;)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->getStableInsets(ILandroid/graphics/Rect;)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->registerDockedStackListener(Landroid/view/IDockedStackListener;)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->registerPinnedStackListener(ILandroid/view/IPinnedStackListener;)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->registerShortcutKey(JLcom/android/internal/policy/IShortcutService;)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->registerWallpaperVisibilityListener(Landroid/view/IWallpaperVisibilityListener;I)Z
+HSPLandroid/view/IWindowManager$Stub$Proxy;->setDockedStackDividerTouchRegion(Landroid/graphics/Rect;)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->setNavBarVirtualKeyHapticFeedbackEnabled(Z)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->setShelfHeight(ZI)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->statusBarVisibilityChanged(II)V
+HSPLandroid/view/IWindowManager$Stub$Proxy;->watchRotation(Landroid/view/IRotationWatcher;I)I
+HSPLandroid/view/IWindowSession$Stub$Proxy;->reportSystemGestureExclusionChanged(Landroid/view/IWindow;Ljava/util/List;)V
+HSPLandroid/view/IWindowSession$Stub$Proxy;->setWallpaperPosition(Landroid/os/IBinder;FFFF)V
+HSPLandroid/view/LayoutInflater;->createView(Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
+HSPLandroid/view/RemoteAnimationAdapter;-><init>(Landroid/view/IRemoteAnimationRunner;JJ)V
+HSPLandroid/view/RemoteAnimationAdapter;-><init>(Landroid/view/IRemoteAnimationRunner;JJZ)V
+HSPLandroid/view/RemoteAnimationAdapter;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/view/SurfaceControl$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/SurfaceControl;
+HSPLandroid/view/SurfaceControl$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/view/SurfaceControl$Transaction;->deferTransactionUntilSurface(Landroid/view/SurfaceControl;Landroid/view/Surface;J)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl;->access$2700(JJJJ)V
+HSPLandroid/view/SurfaceControl;->access$800(Landroid/view/SurfaceControl;)V
+HSPLandroid/view/SurfaceControl;->checkNotReleased()V
+HSPLandroid/view/SurfaceControl;-><init>(Landroid/os/Parcel;Landroid/view/SurfaceControl$1;)V
+HSPLandroid/view/SurfaceControl;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/view/textclassifier/ConfigParser;->getBoolean(Ljava/lang/String;Z)Z
+HSPLandroid/view/textclassifier/ConfigParser;->getInt(Ljava/lang/String;I)I
+HSPLandroid/view/textclassifier/ConfigParser;->getLegacySettings()Landroid/util/KeyValueListParser;
+HSPLandroid/view/textclassifier/TextClassificationManager;->getApplicationContext()Landroid/content/Context;
+HSPLandroid/view/textclassifier/TextClassificationManager;->getTextClassifier(I)Landroid/view/textclassifier/TextClassifier;
+HSPLandroid/view/textclassifier/TextClassificationManager;->lambda$getSettings$2$TextClassificationManager()Ljava/lang/String;
+HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
+HSPLandroid/view/View$10;->setValue(Landroid/view/View;F)V
+HSPLandroid/view/View$10;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/view/View$1;-><init>(Landroid/view/View;)V
+HSPLandroid/view/View$1;->positionChanged(JIIII)V
+HSPLandroid/view/View$7;->get(Landroid/view/View;)Ljava/lang/Float;
+HSPLandroid/view/View$7;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/view/View$8;->get(Landroid/view/View;)Ljava/lang/Float;
+HSPLandroid/view/View$8;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/view/View$8;->setValue(Landroid/view/View;F)V
+HSPLandroid/view/View$8;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/view/View$ListenerInfo;->access$1200(Landroid/view/View$ListenerInfo;)Ljava/util/List;
+HSPLandroid/view/View$ListenerInfo;->access$1202(Landroid/view/View$ListenerInfo;Ljava/util/List;)Ljava/util/List;
+HSPLandroid/view/View$TransformationInfo;->access$2300(Landroid/view/View$TransformationInfo;)F
+HSPLandroid/view/View$TransformationInfo;->access$2302(Landroid/view/View$TransformationInfo;F)F
+HSPLandroid/view/View;->canReceivePointerEvents()Z
+HSPLandroid/view/View;->checkForLongClick(JFFI)V
+HSPLandroid/view/ViewConfiguration;->getScrollBarFadeDuration()I
+HSPLandroid/view/ViewConfiguration;->getScrollDefaultDelay()I
+HSPLandroid/view/ViewConfiguration;->getScrollFriction()F
+HSPLandroid/view/View;->forceHasOverlappingRendering(Z)V
+HSPLandroid/view/View;->getClipBounds()Landroid/graphics/Rect;
+HSPLandroid/view/View;->getLocalVisibleRect(Landroid/graphics/Rect;)Z
+HSPLandroid/view/View;->getSystemGestureExclusionRects()Ljava/util/List;
+HSPLandroid/view/ViewGroup;->addTransientView(Landroid/view/View;I)V
+HSPLandroid/view/ViewGroup;->getTransientViewCount()I
+HSPLandroid/view/ViewGroup;->getTransientView(I)Landroid/view/View;
+HSPLandroid/view/ViewGroup;->removeTransientView(Landroid/view/View;)V
+HSPLandroid/view/View;->initScrollCache()V
+HSPLandroid/view/View;->isPaddingRelative()Z
+HSPLandroid/view/View;->isVerticalFadingEdgeEnabled()Z
+HSPLandroid/view/View;->postUpdateSystemGestureExclusionRects()V
+HSPLandroid/view/ViewPropertyAnimator;->withLayer()Landroid/view/ViewPropertyAnimator;
+HSPLandroid/view/ViewRootImpl;->getView()Landroid/view/View;
+HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
+HSPLandroid/view/ViewRootImpl;->systemGestureExclusionChanged()V
+HSPLandroid/view/ViewRootImpl;->updateSystemGestureExclusionRectsForView(Landroid/view/View;)V
+HSPLandroid/view/View;->setAccessibilityPaneTitle(Ljava/lang/CharSequence;)V
+HSPLandroid/view/View;->setAlphaInternal(F)V
+HSPLandroid/view/View;->setForceDarkAllowed(Z)V
+HSPLandroid/view/View;->setHapticFeedbackEnabled(Z)V
+HSPLandroid/view/View;->setSystemGestureExclusionRects(Ljava/util/List;)V
+HSPLandroid/view/View;->setVerticalFadingEdgeEnabled(Z)V
+HSPLandroid/view/ViewStub;->setVisibilityAsync(I)Ljava/lang/Runnable;
+HSPLandroid/view/ViewTreeObserver;->dispatchOnSystemGestureExclusionRectsChanged(Ljava/util/List;)V
+HSPLandroid/view/View;->updateSystemGestureExclusionRects()V
+HSPLandroid/view/WindowInsets$Type;->compatSystemInsets()I
+HSPLandroid/view/WindowInsets;->assignCompatInsets([Landroid/graphics/Insets;Landroid/graphics/Rect;)V
+HSPLandroid/view/WindowInsets;->getMandatorySystemGestureInsets()Landroid/graphics/Insets;
+HSPLandroid/view/WindowInsets;->getStableInsets()Landroid/graphics/Insets;
+HSPLandroid/view/WindowInsets;->getStableInsetTop()I
+HSPLandroid/view/WindowInsets;->getTappableElementInsets()Landroid/graphics/Insets;
+HSPLandroid/view/WindowManager$LayoutParams;-><init>(IIIIIII)V
+HSPLandroid/view/WindowManager$LayoutParams;-><init>(IIIII)V
+HSPLandroid/view/Window;->setOnWindowDismissedCallback(Landroid/view/Window$OnWindowDismissedCallback;)V
+HSPLandroid/view/Window;->setWindowControllerCallback(Landroid/view/Window$WindowControllerCallback;)V
+HSPLandroid/widget/AbsSeekBar;->setThumbTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/widget/AbsSeekBar;->updateGestureExclusionRects()V
+HSPLandroid/widget/ActionMenuPresenter$2;->onViewAttachedToWindow(Landroid/view/View;)V
+HSPLandroid/widget/Button;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
+HSPLandroid/widget/ImageView;->access$002(Landroid/widget/ImageView;Landroid/net/Uri;)Landroid/net/Uri;
+HSPLandroid/widget/ImageView;->access$102(Landroid/widget/ImageView;I)I
+HSPLandroid/widget/ImageView;->setImageIconAsync(Landroid/graphics/drawable/Icon;)Ljava/lang/Runnable;
+HSPLandroid/widget/ImageView;->setImageLevel(I)V
+HSPLandroid/widget/ProgressBar$1;->get(Landroid/widget/ProgressBar;)Ljava/lang/Float;
+HSPLandroid/widget/ProgressBar$1;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/widget/ProgressBar$1;->setValue(Landroid/widget/ProgressBar;F)V
+HSPLandroid/widget/ProgressBar$1;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/widget/ProgressBar;->access$700(Landroid/widget/ProgressBar;IF)V
+HSPLandroid/widget/ProgressBar;->access$800(Landroid/widget/ProgressBar;)F
+HSPLandroid/widget/ProgressBar;->access$802(Landroid/widget/ProgressBar;F)F
+HSPLandroid/widget/ProgressBar;->applyProgressBackgroundTint()V
+HSPLandroid/widget/ProgressBar;->getTintTarget(IZ)Landroid/graphics/drawable/Drawable;
+HSPLandroid/widget/ProgressBar;->setProgressBackgroundTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/widget/ProgressBar;->setProgress(IZ)V
+HSPLandroid/widget/ProgressBar;->setProgressTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$MarginLayoutParams;)V
+HSPLandroid/widget/RelativeLayout$LayoutParams;->removeRule(I)V
+HSPLandroid/widget/RelativeLayout;->generateLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Landroid/view/ViewGroup$LayoutParams;
+HSPLandroid/widget/RelativeLayout;->getGravity()I
+HSPLandroid/widget/RemoteViews$1;->apply(Landroid/view/View;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)V
+HSPLandroid/widget/RemoteViews$Action;->initActionAsync(Landroid/widget/RemoteViews$ViewTree;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)Landroid/widget/RemoteViews$Action;
+HSPLandroid/widget/RemoteViews$Action;-><init>(Landroid/widget/RemoteViews$1;)V
+HSPLandroid/widget/RemoteViews$Action;-><init>()V
+HSPLandroid/widget/RemoteViews$BitmapCache;-><init>()V
+HSPLandroid/widget/RemoteViews$LayoutParamAction;->apply(Landroid/view/View;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)V
+HSPLandroid/widget/RemoteViews$LayoutParamAction;-><init>(III)V
+HSPLandroid/widget/RemoteViews$LayoutParamAction;->resolveDimenPixelOffset(Landroid/view/View;I)I
+HSPLandroid/widget/RemoteViews$ReflectionAction;->initActionAsync(Landroid/widget/RemoteViews$ViewTree;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)Landroid/widget/RemoteViews$Action;
+HSPLandroid/widget/RemoteViews$ReflectionAction;-><init>(Landroid/widget/RemoteViews;ILjava/lang/String;ILjava/lang/Object;)V
+HSPLandroid/widget/RemoteViews$RemoteResponse;->access$500(Landroid/widget/RemoteViews$RemoteResponse;)Landroid/app/PendingIntent;
+HSPLandroid/widget/RemoteViews$RuntimeAction;-><init>(Landroid/widget/RemoteViews$1;)V
+HSPLandroid/widget/RemoteViews$RuntimeAction;-><init>()V
+HSPLandroid/widget/RemoteViews$SetDrawableTint;->apply(Landroid/view/View;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)V
+HSPLandroid/widget/RemoteViews$SetDrawableTint;-><init>(Landroid/widget/RemoteViews;IZILandroid/graphics/PorterDuff$Mode;)V
+HSPLandroid/widget/RemoteViews$SetOnClickResponse;->apply(Landroid/view/View;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnClickHandler;)V
+HSPLandroid/widget/RemoteViews;->access$1100(Landroid/widget/RemoteViews;Landroid/widget/RemoteViews;)V
+HSPLandroid/widget/RemoteViews;->access$1500(Landroid/widget/RemoteViews;Landroid/content/Context;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnViewAppliedListener;Landroid/widget/RemoteViews$OnClickHandler;)Landroid/widget/RemoteViews$AsyncApplyTask;
+HSPLandroid/widget/RemoteViews;->access$2400(Landroid/widget/RemoteViews;Landroid/content/Context;Landroid/widget/RemoteViews;Landroid/view/ViewGroup;)Landroid/view/View;
+HSPLandroid/widget/RemoteViews;->access$2600(Landroid/widget/RemoteViews;)Ljava/util/ArrayList;
+HSPLandroid/widget/RemoteViews;->access$700(Landroid/widget/RemoteViews;Landroid/view/View;Ljava/lang/String;Ljava/lang/Class;Z)Ljava/lang/invoke/MethodHandle;
+HSPLandroid/widget/RemoteViews;->access$900()Landroid/widget/RemoteViews$Action;
+HSPLandroid/widget/RemoteViews;->addAction(Landroid/widget/RemoteViews$Action;)V
+HSPLandroid/widget/RemoteViews;->addView(ILandroid/widget/RemoteViews;)V
+HSPLandroid/widget/RemoteViews;->applyAsync(Landroid/content/Context;Landroid/view/ViewGroup;Ljava/util/concurrent/Executor;Landroid/widget/RemoteViews$OnViewAppliedListener;Landroid/widget/RemoteViews$OnClickHandler;)Landroid/os/CancellationSignal;
+HSPLandroid/widget/RemoteViews;->configureRemoteViewsAsChild(Landroid/widget/RemoteViews;)V
+HSPLandroid/widget/RemoteViews;->getAsyncApplyTask(Landroid/content/Context;Landroid/view/ViewGroup;Landroid/widget/RemoteViews$OnViewAppliedListener;Landroid/widget/RemoteViews$OnClickHandler;)Landroid/widget/RemoteViews$AsyncApplyTask;
+HSPLandroid/widget/RemoteViews;->getRemoteViewsToApply(Landroid/content/Context;)Landroid/widget/RemoteViews;
+HSPLandroid/widget/RemoteViews;->hasLandscapeAndPortraitLayouts()Z
+HSPLandroid/widget/RemoteViews;->inflateView(Landroid/content/Context;Landroid/widget/RemoteViews;Landroid/view/ViewGroup;)Landroid/view/View;
+HSPLandroid/widget/RemoteViews;-><init>(Landroid/content/pm/ApplicationInfo;I)V
+HSPLandroid/widget/RemoteViews;->removeAllViews(I)V
+HSPLandroid/widget/RemoteViews;->setBoolean(ILjava/lang/String;Z)V
+HSPLandroid/widget/RemoteViews;->setDrawableTint(IZILandroid/graphics/PorterDuff$Mode;)V
+HSPLandroid/widget/RemoteViews;->setIcon(ILjava/lang/String;Landroid/graphics/drawable/Icon;)V
+HSPLandroid/widget/RemoteViews;->setImageViewIcon(ILandroid/graphics/drawable/Icon;)V
+HSPLandroid/widget/RemoteViews;->setIntTag(III)V
+HSPLandroid/widget/RemoteViews;->setLong(ILjava/lang/String;J)V
+HSPLandroid/widget/RemoteViews;->setRemoteInputs(I[Landroid/app/RemoteInput;)V
+HSPLandroid/widget/RemoteViews;->setTextColor(II)V
+HSPLandroid/widget/RemoteViews;->setViewLayoutMarginBottomDimen(II)V
+HSPLandroid/widget/RemoteViews;->setViewLayoutMarginEnd(II)V
+HSPLandroid/widget/RemoteViews;->setViewLayoutWidth(II)V
+HSPLandroid/widget/RemoteViews;->startTaskOnExecutor(Landroid/widget/RemoteViews$AsyncApplyTask;Ljava/util/concurrent/Executor;)Landroid/os/CancellationSignal;
+HSPLandroid/widget/SeekBar;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
+HSPLandroid/widget/SeekBar;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
+HSPLandroid/widget/SeekBar;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+HSPLandroid/widget/TextView;->getCompoundDrawablePadding()I
+HSPLandroid/widget/TextView;->getCompoundDrawables()[Landroid/graphics/drawable/Drawable;
+HSPLandroid/widget/TextView;->getCompoundDrawablesRelative()[Landroid/graphics/drawable/Drawable;
+HSPLandroid/widget/TextView;->setCompoundDrawablesRelativeWithIntrinsicBounds(IIII)V
+HSPLandroid/widget/TextView;->setFontFeatureSettings(Ljava/lang/String;)V
+HSPLandroid/widget/TextView;->setLineHeight(I)V
+HSPLandroid/widget/TextView;->setMarqueeRepeatLimit(I)V
+HSPLandroid/widget/Toolbar;->setTitle(I)V
+HSPLandroid/widget/ViewAnimator;->getDisplayedChild()I
+HSPLcom/android/internal/app/AssistUtils;->activeServiceSupportsLaunchFromKeyguard()Z
+HSPLcom/android/internal/app/AssistUtils;->getActiveServiceComponentName()Landroid/content/ComponentName;
+HSPLcom/android/internal/app/AssistUtils;->onLockscreenShown()V
+HSPLcom/android/internal/app/AssistUtils;->registerVoiceInteractionSessionListener(Lcom/android/internal/app/IVoiceInteractionSessionListener;)V
+HSPLcom/android/internal/app/IAppOpsActiveCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/app/IAppOpsActiveCallback$Stub;-><init>()V
+HSPLcom/android/internal/app/IAppOpsNotedCallback$Stub;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/app/IAppOpsNotedCallback$Stub;-><init>()V
+HSPLcom/android/internal/app/IAppOpsNotedCallback$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperationRaw(IILjava/lang/String;)I
+HSPLcom/android/internal/app/IAppOpsService$Stub$Proxy;->finishOperation(Landroid/os/IBinder;IILjava/lang/String;)V
+HSPLcom/android/internal/app/IAppOpsService$Stub$Proxy;->getPackagesForOps([I)Ljava/util/List;
+HSPLcom/android/internal/app/IAppOpsService$Stub$Proxy;->getToken(Landroid/os/IBinder;)Landroid/os/IBinder;
+HSPLcom/android/internal/app/IAppOpsService$Stub$Proxy;->startOperation(Landroid/os/IBinder;IILjava/lang/String;Z)I
+HSPLcom/android/internal/app/IAppOpsService$Stub$Proxy;->startWatchingActive([ILcom/android/internal/app/IAppOpsActiveCallback;)V
+HSPLcom/android/internal/app/IAppOpsService$Stub$Proxy;->startWatchingModeWithFlags(ILjava/lang/String;ILcom/android/internal/app/IAppOpsCallback;)V
+HSPLcom/android/internal/app/IAppOpsService$Stub$Proxy;->startWatchingNoted([ILcom/android/internal/app/IAppOpsNotedCallback;)V
+HSPLcom/android/internal/app/IBatteryStats$Stub$Proxy;->noteBleScanResults(Landroid/os/WorkSource;I)V
+HSPLcom/android/internal/app/IBatteryStats$Stub$Proxy;->noteBleScanStarted(Landroid/os/WorkSource;Z)V
+HSPLcom/android/internal/app/IBatteryStats$Stub$Proxy;->noteBleScanStopped(Landroid/os/WorkSource;Z)V
+HSPLcom/android/internal/app/IBatteryStats$Stub$Proxy;->noteResetBleScan()V
+HSPLcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->activeServiceSupportsLaunchFromKeyguard()Z
+HSPLcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->getActiveServiceComponentName()Landroid/content/ComponentName;
+HSPLcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->onLockscreenShown()V
+HSPLcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->registerVoiceInteractionSessionListener(Lcom/android/internal/app/IVoiceInteractionSessionListener;)V
+HSPLcom/android/internal/app/IVoiceInteractionSessionListener$Stub;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/app/IVoiceInteractionSessionListener$Stub;-><init>()V
+HSPLcom/android/internal/appwidget/IAppWidgetService$Stub$Proxy;->getInstalledProvidersForProfile(IILjava/lang/String;)Landroid/content/pm/ParceledListSlice;
+HSPLcom/android/internal/appwidget/IAppWidgetService$Stub$Proxy;->startListening(Lcom/android/internal/appwidget/IAppWidgetHost;Ljava/lang/String;I[I)Landroid/content/pm/ParceledListSlice;
+HSPLcom/android/internal/appwidget/IAppWidgetService$Stub$Proxy;->stopListening(Ljava/lang/String;I)V
+HSPLcom/android/internal/backup/IBackupTransport$Stub;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
+HSPLcom/android/internal/backup/IBackupTransport$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLcom/android/internal/graphics/SfVsyncFrameCallbackProvider;-><init>()V
+HSPLcom/android/internal/location/ILocationProviderManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProviderManager;
+HSPLcom/android/internal/location/ProviderRequest$1;->createFromParcel(Landroid/os/Parcel;)Lcom/android/internal/location/ProviderRequest;
+HSPLcom/android/internal/location/ProviderRequest$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLcom/android/internal/logging/MetricsLogger;->visibility(IZ)V
+HSPLcom/android/internal/os/IDropBoxManagerService$Stub$Proxy;->getNextEntry(Ljava/lang/String;JLjava/lang/String;)Landroid/os/DropBoxManager$Entry;
+HSPLcom/android/internal/os/Zygote;->disableExecuteOnly(I)V
+HSPLcom/android/internal/os/Zygote;->forkAndSpecialize(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;I)I
+HSPLcom/android/internal/policy/DecorView;->calculateBarColor(IIIIIIZ)I
+HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor()I
+HSPLcom/android/internal/policy/DecorView;->drawLegacyNavigationBarBackground(Landroid/graphics/RecordingCanvas;)V
+HSPLcom/android/internal/policy/DecorView;->getBackground()Landroid/graphics/drawable/Drawable;
+HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V
+HSPLcom/android/internal/policy/DividerSnapAlgorithm;->getMiddleTarget()Lcom/android/internal/policy/DividerSnapAlgorithm$SnapTarget;
+HSPLcom/android/internal/policy/DividerSnapAlgorithm;-><init>(Landroid/content/res/Resources;IIIZLandroid/graphics/Rect;I)V
+HSPLcom/android/internal/policy/IKeyguardDrawnCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardDrawnCallback;
+HSPLcom/android/internal/policy/IKeyguardService$Stub;-><init>()V
+HSPLcom/android/internal/policy/IKeyguardService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback;
+HSPLcom/android/internal/policy/IShortcutService$Stub;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/policy/IShortcutService$Stub;-><init>()V
+HSPLcom/android/internal/policy/PhoneWindow;->getTransitionBackgroundFadeDuration()J
+HSPLcom/android/internal/policy/ScreenDecorationsUtils;->supportsRoundedCornersOnWindows(Landroid/content/res/Resources;)Z
+HSPLcom/android/internal/statusbar/IStatusBar$Stub;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/statusbar/IStatusBar$Stub;-><init>()V
+HSPLcom/android/internal/statusbar/IStatusBar$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
+HSPLcom/android/internal/statusbar/StatusBarIcon;->clone()Lcom/android/internal/statusbar/StatusBarIcon;
+HSPLcom/android/internal/telecom/ITelecomService$Stub$Proxy;->setUserSelectedOutgoingPhoneAccount(Landroid/telecom/PhoneAccountHandle;)V
+HSPLcom/android/internal/telephony/CarrierKeyDownloadManager;->handleAlarmOrConfigChange()V
+HSPLcom/android/internal/telephony/CarrierKeyDownloadManager;->handleMessage(Landroid/os/Message;)V
+HSPLcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;->access$300(Lcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;)I
+HSPLcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;->access$400(Lcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;)I
+HSPLcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;->access$500(Lcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;)I
+HSPLcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;->access$700(Lcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;->imsiPrefixMatch(Ljava/lang/String;Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/CarrierResolver;->isPreferApnUserEdited(Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/CarrierResolver;->logd(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/cdma/EriManager$EriFile;-><init>(Lcom/android/internal/telephony/cdma/EriManager;)V
+HSPLcom/android/internal/telephony/cdma/EriManager;-><init>(Lcom/android/internal/telephony/Phone;I)V
+HSPLcom/android/internal/telephony/CellularNetworkService$CellularNetworkServiceProvider;->convertHalCellIdentityToCellIdentity(Landroid/hardware/radio/V1_0/CellIdentity;)Landroid/telephony/CellIdentity;
+HSPLcom/android/internal/telephony/CommandException;-><init>(Lcom/android/internal/telephony/CommandException$Error;)V
+HSPLcom/android/internal/telephony/dataconnection/ApnContext;->log(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/dataconnection/ApnContext;->logl(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/dataconnection/ApnContext;->releaseNetwork(Landroid/net/NetworkRequest;I)V
+HSPLcom/android/internal/telephony/dataconnection/ApnContext;->requestNetwork(Landroid/net/NetworkRequest;ILandroid/os/Message;)V
+HSPLcom/android/internal/telephony/dataconnection/ApnSettingUtils;->isMeteredApnType(ILcom/android/internal/telephony/Phone;)Z
+HSPLcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;-><init>(Lcom/android/internal/telephony/dataconnection/ApnContext;IILandroid/os/Message;III)V
+HSPLcom/android/internal/telephony/dataconnection/DataConnection;->bringUp(Lcom/android/internal/telephony/dataconnection/ApnContext;IILandroid/os/Message;III)V
+HSPLcom/android/internal/telephony/dataconnection/DataConnectionReasons$DataDisallowedReasonType;->isHardReason()Z
+HSPLcom/android/internal/telephony/dataconnection/DataConnectionReasons;->add(Lcom/android/internal/telephony/dataconnection/DataConnectionReasons$DataDisallowedReasonType;)V
+HSPLcom/android/internal/telephony/dataconnection/DataConnectionReasons;->containsHardDisallowedReasons()Z
+HSPLcom/android/internal/telephony/dataconnection/DataConnectionReasons;->contains(Lcom/android/internal/telephony/dataconnection/DataConnectionReasons$DataDisallowedReasonType;)Z
+HSPLcom/android/internal/telephony/dataconnection/DataConnectionReasons;->containsOnly(Lcom/android/internal/telephony/dataconnection/DataConnectionReasons$DataDisallowedReasonType;)Z
+HSPLcom/android/internal/telephony/dataconnection/DataConnection;->setHandoverState(I)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->access$000(Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;)I
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->access$002(Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;I)I
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->access$100(Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;)Lcom/android/internal/telephony/Phone;
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->access$200(Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->access$302(Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;Lcom/android/internal/telephony/dataconnection/DataEnabledOverride;)Lcom/android/internal/telephony/dataconnection/DataEnabledOverride;
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->access$400(Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;)Lcom/android/internal/telephony/dataconnection/DataEnabledOverride;
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->access$500(Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->access$600(Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;I)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->getDataEnabledOverride()Lcom/android/internal/telephony/dataconnection/DataEnabledOverride;
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->isDataEnabled(I)Z
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->localLog(Ljava/lang/String;Z)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->log(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->notifyDataEnabledOverrideChanged()V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->registerForDataEnabledOverrideChanged(Landroid/os/Handler;I)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->setDataRoamingEnabled(Z)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->updateDataEnabledAndNotify(I)V
+HSPLcom/android/internal/telephony/dataconnection/DataEnabledSettings;->updatePhoneStateListener()V
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->isDataAllowed(Lcom/android/internal/telephony/dataconnection/ApnContext;ILcom/android/internal/telephony/dataconnection/DataConnectionReasons;)Z
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->log(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->onDataEnabledOverrideRulesChanged()V
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->releaseNetwork(Landroid/net/NetworkRequest;I)V
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->requestNetwork(Landroid/net/NetworkRequest;ILandroid/os/Message;)V
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->requestTypeToString(I)Ljava/lang/String;
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->setupDataOnAllConnectableApns(Ljava/lang/String;Lcom/android/internal/telephony/dataconnection/DcTracker$RetryFailures;)V
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->setupDataOnConnectableApn(Lcom/android/internal/telephony/dataconnection/ApnContext;Ljava/lang/String;Lcom/android/internal/telephony/dataconnection/DcTracker$RetryFailures;)V
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->shouldAutoAttach()Z
+HSPLcom/android/internal/telephony/dataconnection/DcTracker;->shouldCleanUpConnection(Lcom/android/internal/telephony/dataconnection/ApnContext;Z)Z
+HSPLcom/android/internal/telephony/dataconnection/TelephonyNetworkFactory;->logl(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/dataconnection/TransportManager;->isAnyApnPreferredOnIwlan()Z
+HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->notifyEmergencyNumberList(Lcom/android/internal/telephony/Phone;)V
+HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->notifyOemHookRawEventForSubscriber(Lcom/android/internal/telephony/Phone;[B)V
+HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->notifyRadioPowerStateChanged(Lcom/android/internal/telephony/Phone;I)V
+HSPLcom/android/internal/telephony/DefaultPhoneNotifier;->notifyUserMobileDataStateChanged(Lcom/android/internal/telephony/Phone;Z)V
+HSPLcom/android/internal/telephony/emergency/EmergencyNumberTracker;->writeUpdatedEmergencyNumberListMetrics(Ljava/util/List;)V
+HSPLcom/android/internal/telephony/euicc/EuiccConnector;->findBestComponent(Landroid/content/pm/PackageManager;)Landroid/content/pm/ComponentInfo;
+HSPLcom/android/internal/telephony/GlobalSettingsHelper;->setBoolean(Landroid/content/Context;Ljava/lang/String;IZ)Z
+HSPLcom/android/internal/telephony/gsm/GsmSMSDispatcher;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;I[BZ)Lcom/android/internal/telephony/SmsMessageBase$SubmitPduBase;
+HSPLcom/android/internal/telephony/gsm/GsmSMSDispatcher;->sendSms(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+HSPLcom/android/internal/telephony/gsm/GsmSMSDispatcher;->shouldBlockSmsForEcbm()Z
+HSPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->access$200(Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/gsm/UsimPhoneBookManager;->log(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/IccCardConstants$State;->intToState(I)Lcom/android/internal/telephony/IccCardConstants$State;
+HSPLcom/android/internal/telephony/IccSmsInterfaceManager;->filterDestAddress(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/IccSmsInterfaceManager;->sendDataInternal(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;Z)V
+HSPLcom/android/internal/telephony/IccSmsInterfaceManager;->sendDataWithSelfPermissions(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;Z)V
+HSPLcom/android/internal/telephony/ims/ImsResolver$5;->create(Landroid/content/Context;Landroid/content/ComponentName;Lcom/android/internal/telephony/ims/ImsServiceController$ImsServiceControllerCallbacks;)Lcom/android/internal/telephony/ims/ImsServiceController;
+HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->isInEmergencyCall()Z
+HSPLcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->sendImsServiceStateIntent(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/imsphone/ImsPhone;->isInEmergencyCall()Z
+HSPLcom/android/internal/telephony/imsphone/ImsPhone;->notifyForVideoCapabilityChanged(Z)V
+HSPLcom/android/internal/telephony/imsphone/ImsPhone;->updateRoamingState(Landroid/telephony/ServiceState;)V
+HSPLcom/android/internal/telephony/ims/RcsEventQueryHelper;-><init>(Landroid/content/ContentResolver;)V
+HSPLcom/android/internal/telephony/ims/RcsMessageQueryHelper;-><init>(Landroid/content/ContentResolver;)V
+HSPLcom/android/internal/telephony/ims/RcsMessageStoreController;-><init>(Landroid/content/Context;)V
+HSPLcom/android/internal/telephony/ims/RcsMessageStoreUtil;-><init>(Landroid/content/ContentResolver;)V
+HSPLcom/android/internal/telephony/ims/RcsParticipantQueryHelper;-><init>(Landroid/content/ContentResolver;)V
+HSPLcom/android/internal/telephony/ims/RcsThreadQueryHelper;-><init>(Landroid/content/ContentResolver;Lcom/android/internal/telephony/ims/RcsParticipantQueryHelper;)V
+HSPLcom/android/internal/telephony/ImsSmsDispatcher;->isAvailable()Z
+HSPLcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;->getIccSerialNumberForSubscriber(ILjava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;->getLine1AlphaTagForSubscriber(ILjava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getLine1AlphaTagForDisplay(ILjava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->getNetworkTypeForSubscriber(ILjava/lang/String;)I
+HSPLcom/android/internal/telephony/ITelephony$Stub$Proxy;->isDataEnabled(I)Z
+HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;->notifyDataConnectionForSubscriber(IIIZLjava/lang/String;Ljava/lang/String;Landroid/net/LinkProperties;Landroid/net/NetworkCapabilities;IZ)V
+HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;->notifyEmergencyNumberList(II)V
+HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;->notifyOemHookRawEventForSubscriber(II[B)V
+HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;->notifyOtaspChanged(II)V
+HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;->notifyRadioPowerStateChanged(III)V
+HSPLcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;->notifyUserMobileDataStateChangedForPhoneId(IIZ)V
+HSPLcom/android/internal/telephony/metrics/InProgressSmsSession;->addEvent(Lcom/android/internal/telephony/metrics/SmsSessionEventBuilder;)V
+HSPLcom/android/internal/telephony/metrics/InProgressSmsSession;->decreaseExpectedResponse()V
+HSPLcom/android/internal/telephony/metrics/InProgressSmsSession;->getNumExpectedResponses()I
+HSPLcom/android/internal/telephony/metrics/InProgressSmsSession;->increaseExpectedResponse()V
+HSPLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;-><init>(I)V
+HSPLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->setErrorCode(I)Lcom/android/internal/telephony/metrics/SmsSessionEventBuilder;
+HSPLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->setFormat(I)Lcom/android/internal/telephony/metrics/SmsSessionEventBuilder;
+HSPLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->setRilErrno(I)Lcom/android/internal/telephony/metrics/SmsSessionEventBuilder;
+HSPLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->setRilRequestId(I)Lcom/android/internal/telephony/metrics/SmsSessionEventBuilder;
+HSPLcom/android/internal/telephony/metrics/SmsSessionEventBuilder;->setTech(I)Lcom/android/internal/telephony/metrics/SmsSessionEventBuilder;
+HSPLcom/android/internal/telephony/metrics/TelephonyEventBuilder;-><init>(I)V
+HSPLcom/android/internal/telephony/metrics/TelephonyEventBuilder;-><init>(JI)V
+HSPLcom/android/internal/telephony/metrics/TelephonyEventBuilder;->setCarrierIdMatching(Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatching;)Lcom/android/internal/telephony/metrics/TelephonyEventBuilder;
+HSPLcom/android/internal/telephony/metrics/TelephonyEventBuilder;->setUpdatedEmergencyNumber(Lcom/android/internal/telephony/nano/TelephonyProto$EmergencyNumberInfo;)Lcom/android/internal/telephony/metrics/TelephonyEventBuilder;
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->convertEmergencyNumberToEmergencyNumberInfo(Landroid/telephony/emergency/EmergencyNumber;)Lcom/android/internal/telephony/nano/TelephonyProto$EmergencyNumberInfo;
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->finishSmsSessionIfNeeded(Lcom/android/internal/telephony/metrics/InProgressSmsSession;)V
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->lambda$convertEmergencyNumberToEmergencyNumberInfo$1(I)[Ljava/lang/String;
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->logv(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->startNewSmsSessionIfNeeded(I)Lcom/android/internal/telephony/metrics/InProgressSmsSession;
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeCarrierIdMatchingEvent(IIILjava/lang/String;Ljava/lang/String;Lcom/android/internal/telephony/CarrierResolver$CarrierMatchingRule;)V
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeEmergencyNumberUpdateEvent(ILandroid/telephony/emergency/EmergencyNumber;)V
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeOnSmsSolicitedResponse(IIILcom/android/internal/telephony/SmsResponse;)V
+HSPLcom/android/internal/telephony/metrics/TelephonyMetrics;->writeRilSendSms(IIII)V
+HSPLcom/android/internal/telephony/MultiSimSettingController;->handleMessage(Landroid/os/Message;)V
+HSPLcom/android/internal/telephony/MultiSimSettingController;->init(Landroid/content/Context;Lcom/android/internal/telephony/SubscriptionController;)Lcom/android/internal/telephony/MultiSimSettingController;
+HSPLcom/android/internal/telephony/MultiSimSettingController;-><init>(Landroid/content/Context;Lcom/android/internal/telephony/SubscriptionController;)V
+HSPLcom/android/internal/telephony/MultiSimSettingController;->lambda$updatePrimarySubListAndGetChangeType$3(Landroid/telephony/SubscriptionInfo;)Z
+HSPLcom/android/internal/telephony/MultiSimSettingController;->lambda$updatePrimarySubListAndGetChangeType$4(Landroid/telephony/SubscriptionInfo;)Ljava/lang/Integer;
+HSPLcom/android/internal/telephony/MultiSimSettingController;->log(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/MultiSimSettingController;->notifyAllSubscriptionLoaded()V
+HSPLcom/android/internal/telephony/MultiSimSettingController;->notifyDefaultDataSubChanged()V
+HSPLcom/android/internal/telephony/MultiSimSettingController;->notifySubscriptionInfoChanged()V
+HSPLcom/android/internal/telephony/MultiSimSettingController;->updateDefaults(Z)V
+HSPLcom/android/internal/telephony/MultiSimSettingController;->updatePrimarySubListAndGetChangeType(Ljava/util/List;Z)I
+HSPLcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;-><init>()V
+HSPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatching;->clear()Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatching;
+HSPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatching;-><init>()V
+HSPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatchingResult;->clear()Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatchingResult;
+HSPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent$CarrierIdMatchingResult;-><init>()V
+HSPLcom/android/internal/telephony/nano/TelephonyProto$TelephonyEvent;-><init>()V
+HSPLcom/android/internal/telephony/OemHookIndication;->oemHookRaw(ILjava/util/ArrayList;)V
+HSPLcom/android/internal/telephony/PhoneFactory;->getSmsController()Lcom/android/internal/telephony/SmsController;
+HSPLcom/android/internal/telephony/PhoneFactory;->getSubscriptionInfoUpdater()Lcom/android/internal/telephony/SubscriptionInfoUpdater;
+HSPLcom/android/internal/telephony/Phone;->notifySmsSent(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/Phone;->notifyUserMobileDataStateChanged(Z)V
+HSPLcom/android/internal/telephony/PhoneSubInfoController;->callPhoneMethodForSubIdWithPrivilegedCheck(ILjava/lang/String;Lcom/android/internal/telephony/PhoneSubInfoController$CallPhoneMethodHelper;)Ljava/lang/Object;
+HSPLcom/android/internal/telephony/PhoneSubInfoController;->getIsimIst(I)Ljava/lang/String;
+HSPLcom/android/internal/telephony/PhoneSubInfoController;->lambda$callPhoneMethodForSubIdWithPrivilegedCheck$25$PhoneSubInfoController(Ljava/lang/String;Landroid/content/Context;ILjava/lang/String;Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/PhoneSubInfoController;->lambda$callPhoneMethodForSubIdWithReadPhoneNumberCheck$27(Landroid/content/Context;ILjava/lang/String;Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/PhoneSubInfoController;->lambda$callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck$24(Landroid/content/Context;ILjava/lang/String;Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/PhoneSubInfoController;->lambda$getIsimIst$17(Lcom/android/internal/telephony/Phone;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/PhoneSwitcher;->getInstance()Lcom/android/internal/telephony/PhoneSwitcher;
+HSPLcom/android/internal/telephony/PhoneSwitcher;->isEmergencyNetworkRequest(Landroid/net/NetworkRequest;)Z
+HSPLcom/android/internal/telephony/PhoneSwitcher;->isEmergency()Z
+HSPLcom/android/internal/telephony/PhoneSwitcher;->isInEmergencyCallbackMode()Z
+HSPLcom/android/internal/telephony/PhoneSwitcher;->sendRilCommands(I)V
+HSPLcom/android/internal/telephony/protobuf/nano/ExtendableMessageNano;-><init>()V
+HSPLcom/android/internal/telephony/protobuf/nano/MessageNano;-><init>()V
+HSPLcom/android/internal/telephony/ProxyController;->getSmsController()Lcom/android/internal/telephony/SmsController;
+HSPLcom/android/internal/telephony/RadioIndication;->currentSignalStrength(ILandroid/hardware/radio/V1_0/SignalStrength;)V
+HSPLcom/android/internal/telephony/RadioResponse;->getCellInfoListResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
+HSPLcom/android/internal/telephony/RadioResponse;->getCurrentCallsResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
+HSPLcom/android/internal/telephony/RadioResponse;->getDataRegistrationStateResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/DataRegStateResult;)V
+HSPLcom/android/internal/telephony/RadioResponse;->getIccCardStatusResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/CardStatus;)V
+HSPLcom/android/internal/telephony/RadioResponse;->getSignalStrengthResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/SignalStrength;)V
+HSPLcom/android/internal/telephony/RadioResponse;->getVoiceRegistrationStateResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/VoiceRegStateResult;)V
+HSPLcom/android/internal/telephony/RadioResponse;->responseCellInfoList(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
+HSPLcom/android/internal/telephony/RadioResponse;->responseCurrentCalls(Landroid/hardware/radio/V1_0/RadioResponseInfo;Ljava/util/ArrayList;)V
+HSPLcom/android/internal/telephony/RadioResponse;->responseIccCardStatus(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/CardStatus;)V
+HSPLcom/android/internal/telephony/RadioResponse;->responseLceStatus(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/LceStatusInfo;)V
+HSPLcom/android/internal/telephony/RadioResponse;->responseSignalStrength(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/SignalStrength;)V
+HSPLcom/android/internal/telephony/RadioResponse;->responseSms(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/SendSmsResult;)V
+HSPLcom/android/internal/telephony/RadioResponse;->sendImsSmsResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/SendSmsResult;)V
+HSPLcom/android/internal/telephony/RadioResponse;->sendMessageResponse(Landroid/os/Message;Ljava/lang/Object;)V
+HSPLcom/android/internal/telephony/RadioResponse;->startLceServiceResponse(Landroid/hardware/radio/V1_0/RadioResponseInfo;Landroid/hardware/radio/V1_0/LceStatusInfo;)V
+HSPLcom/android/internal/telephony/RIL;->arrayListToPrimitiveArray(Ljava/util/ArrayList;)[B
+HSPLcom/android/internal/telephony/RIL;->constructGsmSendSmsRilRequest(Ljava/lang/String;Ljava/lang/String;)Landroid/hardware/radio/V1_0/GsmSmsMessage;
+HSPLcom/android/internal/telephony/RIL;->convertHalCellInfoList(Ljava/util/ArrayList;)Ljava/util/ArrayList;
+HSPLcom/android/internal/telephony/RIL;->getModemStatus(Landroid/os/Message;)V
+HSPLcom/android/internal/telephony/RIL;->obtainRequest(ILandroid/os/Message;Landroid/os/WorkSource;)Lcom/android/internal/telephony/RILRequest;
+HSPLcom/android/internal/telephony/RIL;->sendImsGsmSms(Ljava/lang/String;Ljava/lang/String;IILandroid/os/Message;)V
+HSPLcom/android/internal/telephony/RIL;->unsljLogvRet(ILjava/lang/Object;)V
+HSPLcom/android/internal/telephony/ServiceStateTracker;->filterOperatorNameByPattern(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/ServiceStateTracker;->getCarrierNameDisplayBitmask(Landroid/telephony/ServiceState;)I
+HSPLcom/android/internal/telephony/ServiceStateTracker;->getCombinedRegState(Landroid/telephony/ServiceState;)I
+HSPLcom/android/internal/telephony/ServiceStateTracker;->getOperatorBrandOverride()Ljava/lang/String;
+HSPLcom/android/internal/telephony/ServiceStateTracker;->getOperatorNameFromEri()Ljava/lang/String;
+HSPLcom/android/internal/telephony/ServiceStateTracker;->getServiceProviderName()Ljava/lang/String;
+HSPLcom/android/internal/telephony/ServiceStateTracker;->modemTriggeredPollState()V
+HSPLcom/android/internal/telephony/ServiceStateTracker;->notifySpnDisplayUpdate(Lcom/android/internal/telephony/cdnr/CarrierDisplayNameData;)V
+HSPLcom/android/internal/telephony/ServiceStateTracker;->processIwlanRegistrationInfo()V
+HSPLcom/android/internal/telephony/ServiceStateTracker;->updateNrStateFromPhysicalChannelConfigs(Ljava/util/List;Landroid/telephony/ServiceState;)Z
+HSPLcom/android/internal/telephony/ServiceStateTracker;->updateOperatorNameForCellIdentity(Landroid/telephony/CellIdentity;)V
+HSPLcom/android/internal/telephony/ServiceStateTracker;->updateOperatorNameForCellInfo(Ljava/util/List;)V
+HSPLcom/android/internal/telephony/ServiceStateTracker;->updateOperatorNameForServiceState(Landroid/telephony/ServiceState;)V
+HSPLcom/android/internal/telephony/ServiceStateTracker;->updateOperatorNamePattern(Landroid/os/PersistableBundle;)V
+HSPLcom/android/internal/telephony/ServiceStateTracker;->updateSpnDisplayLegacy()V
+HSPLcom/android/internal/telephony/SMSDispatcher;->checkDestination(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)Z
+HSPLcom/android/internal/telephony/SMSDispatcher;->getCarrierAppPackageName()Ljava/lang/String;
+HSPLcom/android/internal/telephony/SMSDispatcher;->getSmsTracker(Ljava/lang/String;Ljava/util/HashMap;Landroid/app/PendingIntent;Landroid/app/PendingIntent;Ljava/lang/String;Landroid/net/Uri;ZLjava/lang/String;ZZZ)Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;
+HSPLcom/android/internal/telephony/SMSDispatcher;->getSmsTracker(Ljava/lang/String;Ljava/util/HashMap;Landroid/app/PendingIntent;Landroid/app/PendingIntent;Ljava/lang/String;Ljava/util/concurrent/atomic/AtomicInteger;Ljava/util/concurrent/atomic/AtomicBoolean;Landroid/net/Uri;Lcom/android/internal/telephony/SmsHeader;ZLjava/lang/String;ZZIIZ)Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;
+HSPLcom/android/internal/telephony/SMSDispatcher;->getSmsTrackerMap(Ljava/lang/String;Ljava/lang/String;I[BLcom/android/internal/telephony/SmsMessageBase$SubmitPduBase;)Ljava/util/HashMap;
+HSPLcom/android/internal/telephony/SMSDispatcher;->getSubId()I
+HSPLcom/android/internal/telephony/SMSDispatcher;->handleMessage(Landroid/os/Message;)V
+HSPLcom/android/internal/telephony/SMSDispatcher;->handleSendComplete(Landroid/os/AsyncResult;)V
+HSPLcom/android/internal/telephony/SMSDispatcher;->isIms()Z
+HSPLcom/android/internal/telephony/SmsDispatchersController;->getUsageMonitor()Lcom/android/internal/telephony/SmsUsageMonitor;
+HSPLcom/android/internal/telephony/SmsDispatchersController;->isCdmaFormat(Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/SmsDispatchersController;->isCdmaMo()Z
+HSPLcom/android/internal/telephony/SmsDispatchersController;->isIms()Z
+HSPLcom/android/internal/telephony/SmsDispatchersController;->sendData(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;Z)V
+HSPLcom/android/internal/telephony/SMSDispatcher;->sendData(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;Z)V
+HSPLcom/android/internal/telephony/SMSDispatcher;->sendRawPdu(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+HSPLcom/android/internal/telephony/SMSDispatcher;->sendSmsByCarrierApp(ZLcom/android/internal/telephony/SMSDispatcher$SmsTracker;)Z
+HSPLcom/android/internal/telephony/SMSDispatcher;->sendSubmitPdu(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+HSPLcom/android/internal/telephony/SmsUsageMonitor;->check(Ljava/lang/String;I)Z
+HSPLcom/android/internal/telephony/SmsUsageMonitor;->isUnderLimit(Ljava/util/ArrayList;I)Z
+HSPLcom/android/internal/telephony/SmsUsageMonitor;->removeExpiredTimestamps()V
+HSPLcom/android/internal/telephony/SubscriptionController;->clearSlotIndexForSubInfoRecords()V
+HSPLcom/android/internal/telephony/SubscriptionController;->getDataEnabledOverrideRules(I)Ljava/lang/String;
+HSPLcom/android/internal/telephony/SubscriptionController;->getOptionalStringFromCursor(Landroid/database/Cursor;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/SubscriptionController;->getSubInfoUsingSlotIndexPrivileged(I)Ljava/util/List;
+HSPLcom/android/internal/telephony/SubscriptionController;->getSubscriptionInfo(I)Landroid/telephony/SubscriptionInfo;
+HSPLcom/android/internal/telephony/SubscriptionController;->getSubscriptionProperty(ILjava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/SubscriptionController;->logd(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/SubscriptionController;->notifySubInfoReady()V
+HSPLcom/android/internal/telephony/SubscriptionController;->sendDefaultChangedBroadcast(I)V
+HSPLcom/android/internal/telephony/SubscriptionController;->setAssociatedPlmns([Ljava/lang/String;[Ljava/lang/String;I)V
+HSPLcom/android/internal/telephony/SubscriptionController;->setDisplayNumber(Ljava/lang/String;I)I
+HSPLcom/android/internal/telephony/SubscriptionController;->setImsi(Ljava/lang/String;I)I
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->getDefaultCarrierServicePackageName()Ljava/lang/String;
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->isCarrierServicePackage(ILjava/lang/String;)Z
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->lambda$handleMessage$0(Z)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->lambda$updateEmbeddedSubscriptions$4$SubscriptionInfoUpdater(Ljava/util/List;Lcom/android/internal/telephony/SubscriptionInfoUpdater$UpdateEmbeddedSubsCallback;)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->lambda$updateEmbeddedSubscriptions$5$SubscriptionInfoUpdater(Ljava/util/List;Lcom/android/internal/telephony/SubscriptionInfoUpdater$UpdateEmbeddedSubsCallback;)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->lambda$updateSubscriptionByCarrierConfigAndNotifyComplete$6$SubscriptionInfoUpdater(ILjava/lang/String;Landroid/os/PersistableBundle;Landroid/os/Message;)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->lambda$updateSubscriptionInfoByIccId$3(Z)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->logd(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->loge(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->setSubInfoInitialized()V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->updateEmbeddedSubscriptionsCache(Landroid/service/euicc/GetEuiccProfileInfoListResult;)Z
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->updateEmbeddedSubscriptions(Ljava/util/List;Lcom/android/internal/telephony/SubscriptionInfoUpdater$UpdateEmbeddedSubsCallback;)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->updateInternalIccState(Ljava/lang/String;Ljava/lang/String;IZ)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->updateSubscriptionByCarrierConfigAndNotifyComplete(ILjava/lang/String;Landroid/os/PersistableBundle;Landroid/os/Message;)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->updateSubscriptionByCarrierConfig(ILjava/lang/String;Landroid/os/PersistableBundle;)V
+HSPLcom/android/internal/telephony/SubscriptionInfoUpdater;->updateSubscriptionInfoByIccId(IZ)V
+HSPLcom/android/internal/telephony/TelephonyComponentFactory;->makeEriManager(Lcom/android/internal/telephony/Phone;I)Lcom/android/internal/telephony/cdma/EriManager;
+HSPLcom/android/internal/telephony/TelephonyPermissions;->checkCallingOrSelfReadPhoneStateNoThrow(Landroid/content/Context;ILjava/lang/String;Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/TelephonyPermissions;->checkCarrierPrivilegeForAnySubId(Landroid/content/Context;Ljava/util/function/Supplier;I)Z
+HSPLcom/android/internal/telephony/TelephonyPermissions;->checkReadDeviceIdentifiers(Landroid/content/Context;Ljava/util/function/Supplier;IIILjava/lang/String;Ljava/lang/String;)Z
+HSPLcom/android/internal/telephony/uicc/AdnRecord;->getEmails()[Ljava/lang/String;
+HSPLcom/android/internal/telephony/uicc/IccRecords;->getEhplmns()[Ljava/lang/String;
+HSPLcom/android/internal/telephony/uicc/IccRecords;->getHomePlmns()[Ljava/lang/String;
+HSPLcom/android/internal/telephony/uicc/IccRecords;->getPlmnsFromHplmnActRecord()[Ljava/lang/String;
+HSPLcom/android/internal/telephony/uicc/IccRecords;->getServiceProviderDisplayInformation()[Ljava/lang/String;
+HSPLcom/android/internal/telephony/uicc/SIMRecords;->getCarrierNameDisplayCondition()I
+HSPLcom/android/internal/telephony/uicc/UiccCard;->iccOpenLogicalChannel(Ljava/lang/String;ILandroid/os/Message;)V
+HSPLcom/android/internal/telephony/uicc/UiccController;->getSlotIdFromPhoneId(I)I
+HSPLcom/android/internal/telephony/uicc/UiccController;->updateInternalIccState(Landroid/content/Context;Lcom/android/internal/telephony/IccCardConstants$State;Ljava/lang/String;IZ)V
+HSPLcom/android/internal/telephony/uicc/UiccPkcs15;->access$000(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/uicc/UiccPkcs15;->access$100(Lcom/android/internal/telephony/uicc/UiccPkcs15;)I
+HSPLcom/android/internal/telephony/uicc/UiccPkcs15;->access$200(Lcom/android/internal/telephony/uicc/UiccPkcs15;)Lcom/android/internal/telephony/uicc/UiccProfile;
+HSPLcom/android/internal/telephony/uicc/UiccPkcs15;->log(Ljava/lang/String;)V
+HSPLcom/android/internal/telephony/uicc/UiccPkcs15;->parseAcrf(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/internal/telephony/uicc/UiccProfile;->updateCarrierNameForSubscription(Lcom/android/internal/telephony/SubscriptionController;II)V
+HSPLcom/android/internal/telephony/util/NotificationChannelController;->getChannel(Ljava/lang/String;Landroid/content/Context;)Landroid/app/NotificationChannel;
+HSPLcom/android/internal/telephony/util/NotificationChannelController;->migrateCallFowardNotificationChannel(Landroid/content/Context;Landroid/app/NotificationChannel;)V
+HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/lang/String;)[Ljava/lang/String;
+HSPLcom/android/internal/util/AsyncChannel;-><init>()V
+HSPLcom/android/internal/util/BitUtils;->maskedEquals(Ljava/util/UUID;Ljava/util/UUID;Ljava/util/UUID;)Z
+HSPLcom/android/internal/util/BitUtils;->uint16(S)I
+HSPLcom/android/internal/util/BitUtils;->uint32(I)J
+HSPLcom/android/internal/util/BitUtils;->uint8(B)I
+HSPLcom/android/internal/util/GrowingArrayUtils;->append([FIF)[F
+HSPLcom/android/internal/util/LatencyTracker;->isEnabled(Landroid/content/Context;)Z
+HSPLcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/internal/util/StateMachine;->getHandler()Landroid/os/Handler;
+HSPLcom/android/internal/util/StateMachine;->getName()Ljava/lang/String;
+HSPLcom/android/internal/view/InputBindResult;->getActivityViewToScreenMatrix()Landroid/graphics/Matrix;
+HSPLcom/android/internal/view/RotationPolicy;->areAllRotationsAllowed(Landroid/content/Context;)Z
+HSPLcom/android/internal/view/RotationPolicy;->getRotationLockOrientation(Landroid/content/Context;)I
+HSPLcom/android/internal/view/RotationPolicy;->registerRotationPolicyListener(Landroid/content/Context;Lcom/android/internal/view/RotationPolicy$RotationPolicyListener;I)V
+HSPLcom/android/internal/view/RotationPolicy;->setRotationLockAtAngle(Landroid/content/Context;ZI)V
+HSPLcom/android/internal/view/RotationPolicy;->setRotationLock(ZI)V
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->checkVoldPassword(I)Z
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->getRecoverySecretTypes()[I
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->getString(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->initRecoveryServiceWithSigFile(Ljava/lang/String;[B[B)V
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->registerStrongAuthTracker(Landroid/app/trust/IStrongAuthTracker;)V
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->setBoolean(Ljava/lang/String;ZI)V
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->setRecoverySecretTypes([I)V
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->setServerParams([B)V
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->setSnapshotCreatedPendingIntent(Landroid/app/PendingIntent;)V
+HSPLcom/android/internal/widget/ILockSettings$Stub$Proxy;->userPresent(I)V
+HSPLcom/android/internal/widget/LockPatternUtils;->checkVoldPassword(I)Z
+HSPLcom/android/internal/widget/LockPatternUtils;->getActivePasswordQuality(I)I
+HSPLcom/android/internal/widget/LockPatternUtils;->getDeviceOwnerInfo()Ljava/lang/String;
+HSPLcom/android/internal/widget/LockPatternUtils;->getUserManager()Landroid/os/UserManager;
+HSPLcom/android/internal/widget/LockPatternUtils;->isLockPatternEnabled(II)Z
+HSPLcom/android/internal/widget/LockPatternUtils;->isLockScreenDisabled(I)Z
+HSPLcom/android/internal/widget/LockPatternUtils;->userPresent(I)V
+HSPLcom/android/okhttp/Headers$Builder;->access$000(Lcom/android/okhttp/Headers$Builder;)Ljava/util/List;
+HSPLcom/android/okhttp/Headers$Builder;->build()Lcom/android/okhttp/Headers;
+HSPLcom/android/okhttp/Headers$Builder;->get(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/okhttp/Headers;->get(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/okhttp/Headers;->get([Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/okhttp/Headers;-><init>(Lcom/android/okhttp/Headers$Builder;Lcom/android/okhttp/Headers$1;)V
+HSPLcom/android/okhttp/Headers;-><init>(Lcom/android/okhttp/Headers$Builder;)V
+HSPLcom/android/okhttp/HttpHandler$CleartextURLFilter;->checkURLPermitted(Ljava/net/URL;)V
+HSPLcom/android/okhttp/HttpUrl;->url()Ljava/net/URL;
+HSPLcom/android/okhttp/internal/http/Http1xStream$AbstractSource;->timeout()Lcom/android/okhttp/okio/Timeout;
+HSPLcom/android/okhttp/internal/http/Http1xStream$ChunkedSink;->close()V
+HSPLcom/android/okhttp/internal/http/Http1xStream$ChunkedSink;->flush()V
+HSPLcom/android/okhttp/internal/http/Http1xStream$ChunkedSink;-><init>(Lcom/android/okhttp/internal/http/Http1xStream;Lcom/android/okhttp/internal/http/Http1xStream$1;)V
+HSPLcom/android/okhttp/internal/http/Http1xStream$ChunkedSink;-><init>(Lcom/android/okhttp/internal/http/Http1xStream;)V
+HSPLcom/android/okhttp/internal/http/Http1xStream$ChunkedSink;->write(Lcom/android/okhttp/okio/Buffer;J)V
+HSPLcom/android/okhttp/internal/http/Http1xStream;->access$300(Lcom/android/okhttp/internal/http/Http1xStream;)Lcom/android/okhttp/okio/BufferedSink;
+HSPLcom/android/okhttp/internal/http/Http1xStream;->access$400(Lcom/android/okhttp/internal/http/Http1xStream;Lcom/android/okhttp/okio/ForwardingTimeout;)V
+HSPLcom/android/okhttp/internal/http/Http1xStream;->access$502(Lcom/android/okhttp/internal/http/Http1xStream;I)I
+HSPLcom/android/okhttp/internal/http/Http1xStream;->createRequestBody(Lcom/android/okhttp/Request;J)Lcom/android/okhttp/okio/Sink;
+HSPLcom/android/okhttp/internal/http/Http1xStream;->detachTimeout(Lcom/android/okhttp/okio/ForwardingTimeout;)V
+HSPLcom/android/okhttp/internal/http/Http1xStream;->newChunkedSink()Lcom/android/okhttp/okio/Sink;
+HSPLcom/android/okhttp/internal/http/HttpEngine;->getResponse()Lcom/android/okhttp/Response;
+HSPLcom/android/okhttp/internal/http/StatusLine;->get(Lcom/android/okhttp/Response;)Lcom/android/okhttp/internal/http/StatusLine;
+HSPLcom/android/okhttp/internal/http/StatusLine;-><init>(Lcom/android/okhttp/Protocol;ILjava/lang/String;)V
+HSPLcom/android/okhttp/internal/http/StatusLine;->toString()Ljava/lang/String;
+HSPLcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;->getContentEncoding()Ljava/lang/String;
+HSPLcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;->getContentLength()I
+HSPLcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;->getContentType()Ljava/lang/String;
+HSPLcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;->getHeaderFields()Ljava/util/Map;
+HSPLcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;->getRequestProperties()Ljava/util/Map;
+HSPLcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;->getRequestProperty(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;->getURL()Ljava/net/URL;
+HSPLcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;->setChunkedStreamingMode(I)V
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getContentEncoding()Ljava/lang/String;
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getContentLength()I
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getContentType()Ljava/lang/String;
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getHeaderFields()Ljava/util/Map;
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getRequestProperties()Ljava/util/Map;
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getRequestProperty(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->getURL()Ljava/net/URL;
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->setChunkedStreamingMode(I)V
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->setHostnameVerifier(Ljavax/net/ssl/HostnameVerifier;)V
+HSPLcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->setSSLSocketFactory(Ljavax/net/ssl/SSLSocketFactory;)V
+HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->getHeaderFields()Ljava/util/Map;
+HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->getRequestProperties()Ljava/util/Map;
+HSPLcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->getRequestProperty(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/okhttp/internal/OptionalMethod;->getMethod(Ljava/lang/Class;)Ljava/lang/reflect/Method;
+HSPLcom/android/okhttp/internal/OptionalMethod;->getPublicMethod(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
+HSPLcom/android/okhttp/internal/OptionalMethod;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/okhttp/internal/OptionalMethod;->invokeOptional(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/okhttp/internal/OptionalMethod;->invokeOptionalWithoutCheckedException(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/okhttp/internal/OptionalMethod;->invokeWithoutCheckedException(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+HSPLcom/android/okhttp/internal/OptionalMethod;->isSupported(Ljava/lang/Object;)Z
+HSPLcom/android/okhttp/internal/Platform;->concatLengthPrefixed(Ljava/util/List;)[B
+HSPLcom/android/okhttp/internal/Util;->discard(Lcom/android/okhttp/okio/Source;ILjava/util/concurrent/TimeUnit;)Z
+HSPLcom/android/okhttp/internal/Util;->skipAll(Lcom/android/okhttp/okio/Source;ILjava/util/concurrent/TimeUnit;)Z
+HSPLcom/android/okhttp/OkHttpClient;->getDefaultSSLSocketFactory()Ljavax/net/ssl/SSLSocketFactory;
+HSPLcom/android/okhttp/OkHttpClient;->setDns(Lcom/android/okhttp/Dns;)Lcom/android/okhttp/OkHttpClient;
+HSPLcom/android/okhttp/OkHttpClient;->setSocketFactory(Ljavax/net/SocketFactory;)Lcom/android/okhttp/OkHttpClient;
+HSPLcom/android/okhttp/okio/Buffer;->completeSegmentByteCount()J
+HSPLcom/android/okhttp/okio/Buffer;-><init>()V
+HSPLcom/android/okhttp/okio/Buffer;->readByteArray()[B
+HSPLcom/android/okhttp/okio/Buffer;->readByteArray(J)[B
+HSPLcom/android/okhttp/okio/Buffer;->readFully([B)V
+HSPLcom/android/okhttp/okio/Buffer;->size()J
+HSPLcom/android/okhttp/okio/Buffer;->writeByte(I)Lcom/android/okhttp/okio/Buffer;
+HSPLcom/android/okhttp/okio/Buffer;->writeHexadecimalUnsignedLong(J)Lcom/android/okhttp/okio/Buffer;
+HSPLcom/android/okhttp/okio/Buffer;->writeUtf8(Ljava/lang/String;)Lcom/android/okhttp/okio/Buffer;
+HSPLcom/android/okhttp/okio/ForwardingTimeout;->clearDeadline()Lcom/android/okhttp/okio/Timeout;
+HSPLcom/android/okhttp/okio/ForwardingTimeout;->deadlineNanoTime(J)Lcom/android/okhttp/okio/Timeout;
+HSPLcom/android/okhttp/okio/ForwardingTimeout;->delegate()Lcom/android/okhttp/okio/Timeout;
+HSPLcom/android/okhttp/okio/ForwardingTimeout;->hasDeadline()Z
+HSPLcom/android/okhttp/okio/ForwardingTimeout;-><init>(Lcom/android/okhttp/okio/Timeout;)V
+HSPLcom/android/okhttp/okio/ForwardingTimeout;->setDelegate(Lcom/android/okhttp/okio/Timeout;)Lcom/android/okhttp/okio/ForwardingTimeout;
+HSPLcom/android/okhttp/okio/RealBufferedSink;->emitCompleteSegments()Lcom/android/okhttp/okio/BufferedSink;
+HSPLcom/android/okhttp/okio/RealBufferedSink;->emit()Lcom/android/okhttp/okio/BufferedSink;
+HSPLcom/android/okhttp/okio/RealBufferedSink;->writeHexadecimalUnsignedLong(J)Lcom/android/okhttp/okio/BufferedSink;
+HSPLcom/android/okhttp/okio/RealBufferedSource$1;->read()I
+HSPLcom/android/okhttp/okio/RealBufferedSource;->access$000(Lcom/android/okhttp/okio/RealBufferedSource;)Z
+HSPLcom/android/okhttp/okio/Timeout;->deadlineNanoTime()J
+HSPLcom/android/okhttp/okio/Timeout;->deadlineNanoTime(J)Lcom/android/okhttp/okio/Timeout;
+HSPLcom/android/okhttp/okio/Timeout;-><init>()V
+HSPLcom/android/okhttp/OkUrlFactories;->open(Lcom/android/okhttp/OkUrlFactory;Ljava/net/URL;Ljava/net/Proxy;)Ljava/net/HttpURLConnection;
+HSPLcom/android/okhttp/OkUrlFactory;->client()Lcom/android/okhttp/OkHttpClient;
+HSPLcom/android/okhttp/Protocol;->toString()Ljava/lang/String;
+HSPLcom/android/okhttp/Request;->header(Ljava/lang/String;)Ljava/lang/String;
+HSPLcom/android/okhttp/Response;->code()I
+HSPLcom/android/okhttp/Response;->message()Ljava/lang/String;
+HSPLcom/android/okhttp/Response;->protocol()Lcom/android/okhttp/Protocol;
+HSPLcom/android/server/NetworkManagementSocketTagger;->getThreadSocketStatsTag()I
+HSPLcom/android/server/NetworkManagementSocketTagger;->setThreadSocketStatsUid(I)I
+HSPLdalvik/system/BlockGuard;->getVmPolicy()Ldalvik/system/BlockGuard$VmPolicy;
+HSPLdalvik/system/SocketTagger;->tag(Ljava/net/Socket;)V
+HSPLjava/io/DataInputStream;->readDouble()D
+HSPLjava/io/DataOutputStream;->incCount(I)V
+HSPLjava/io/DataOutputStream;->writeDouble(D)V
+HSPLjava/io/DataOutputStream;->writeShort(I)V
+HSPLjava/io/File;->deleteOnExit()V
+HSPLjava/io/FileDescriptor;->getInt$()I
+HSPLjava/io/File;->isInvalid()Z
+HSPLjava/io/File;->setExecutable(ZZ)Z
+HSPLjava/io/File;->setReadable(ZZ)Z
+HSPLjava/io/FilterOutputStream;->flush()V
+HSPLjava/io/IOException;-><init>()V
+HSPLjava/io/RandomAccessFile;->write(I)V
+HSPLjava/io/RandomAccessFile;->writeLong(J)V
+HSPLjava/io/SequenceInputStream;->available()I
+HSPLjava/io/SequenceInputStream;->close()V
+HSPLjava/io/SequenceInputStream;->read([BII)I
+HSPLjava/io/StringWriter;->append(C)Ljava/io/StringWriter;
+HSPLjava/io/StringWriter;->append(C)Ljava/io/Writer;
+HSPLjava/io/UnixFileSystem;->setPermission(Ljava/io/File;IZZ)Z
+HSPLjava/lang/AssertionError;-><init>(Ljava/lang/Object;)V
+HSPLjava/lang/AssertionError;-><init>(Ljava/lang/String;)V
+HSPLjava/lang/Byte;->compare(BB)I
+HSPLjava/lang/Byte;->compareTo(Ljava/lang/Byte;)I
+HSPLjava/lang/Byte;->compareTo(Ljava/lang/Object;)I
+HSPLjava/lang/Byte;->parseByte(Ljava/lang/String;)B
+HSPLjava/lang/Byte;->parseByte(Ljava/lang/String;I)B
+HSPLjava/lang/Class;->getInstanceMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
+HSPLjava/lang/Class;->getPackageName$()Ljava/lang/String;
+HSPLjava/lang/Class;->getProtectionDomain()Ljava/security/ProtectionDomain;
+HSPLjava/lang/Daemons$FinalizerWatchdogDaemon;->sleepForMillis(J)Z
+HSPLjava/lang/Double;->floatValue()F
+HSPLjava/lang/Error;-><init>(Ljava/lang/String;)V
+HSPLjava/lang/Float;->compareTo(Ljava/lang/Float;)I
+HSPLjava/lang/IllegalMonitorStateException;-><init>(Ljava/lang/String;)V
+HSPLjava/lang/InstantiationException;-><init>(Ljava/lang/String;)V
+HSPLjava/lang/Integer;->byteValue()B
+HSPLjava/lang/Integer;->toUnsignedLong(I)J
+HSPLjava/lang/invoke/MethodHandleImpl;-><init>(JILjava/lang/invoke/MethodType;)V
+HSPLjava/lang/invoke/MethodHandle;-><init>(JILjava/lang/invoke/MethodType;)V
+HSPLjava/lang/invoke/MethodHandles$Lookup;->checkReturnType(Ljava/lang/reflect/Method;Ljava/lang/invoke/MethodType;)V
+HSPLjava/lang/invoke/MethodHandles$Lookup;->createMethodHandle(Ljava/lang/reflect/Method;ILjava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;
+HSPLjava/lang/invoke/MethodHandles$Lookup;->findVirtual(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;
+HSPLjava/lang/invoke/MethodHandle;->type()Ljava/lang/invoke/MethodType;
+HSPLjava/lang/invoke/MethodType;->changeReturnType(Ljava/lang/Class;)Ljava/lang/invoke/MethodType;
+HSPLjava/lang/invoke/MethodType;->dropParameterTypes(II)Ljava/lang/invoke/MethodType;
+HSPLjava/lang/invoke/MethodType;->ptypes()[Ljava/lang/Class;
+HSPLjava/lang/invoke/MethodType;->returnType()Ljava/lang/Class;
+HSPLjava/lang/invoke/MethodType;->rtype()Ljava/lang/Class;
+HSPLjava/lang/Iterable;->forEach(Ljava/util/function/Consumer;)V
+HSPLjava/lang/Long;->valueOf(Ljava/lang/String;I)Ljava/lang/Long;
+HSPLjava/lang/Math;->subtractExact(JJ)J
+HSPLjava/lang/reflect/Executable;->getArtMethod()J
+HSPLjava/lang/reflect/Executable;->getDeclaringClassInternal()Ljava/lang/Class;
+HSPLjava/lang/reflect/Executable;->isSynthetic()Z
+HSPLjava/lang/reflect/Executable;->isVarArgs()Z
+HSPLjava/lang/ReflectiveOperationException;-><init>(Ljava/lang/String;)V
+HSPLjava/lang/reflect/Method;->getDeclaringClass()Ljava/lang/Class;
+HSPLjava/lang/reflect/Method;->isSynthetic()Z
+HSPLjava/lang/reflect/Method;->isVarArgs()Z
+HSPLjava/lang/Short;->shortValue()S
+HSPLjava/lang/StackTraceElement;->getFileName()Ljava/lang/String;
+HSPLjava/lang/StringBuffer;->substring(II)Ljava/lang/String;
+HSPLjava/lang/StringBuffer;->substring(I)Ljava/lang/String;
+HSPLjava/lang/System;->getSecurityManager()Ljava/lang/SecurityManager;
+HSPLjava/lang/Thread;->getUncaughtExceptionPreHandler()Ljava/lang/Thread$UncaughtExceptionHandler;
+HSPLjava/lang/ThreadLocal$ThreadLocalMap;->getEntryAfterMiss(Ljava/lang/ThreadLocal;ILjava/lang/ThreadLocal$ThreadLocalMap$Entry;)Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+HSPLjava/lang/ThreadLocal$ThreadLocalMap;->getEntry(Ljava/lang/ThreadLocal;)Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
+HSPLjava/lang/ThreadLocal$ThreadLocalMap;->nextIndex(II)I
+HSPLjava/lang/ThreadLocal;->access$400(Ljava/lang/ThreadLocal;)I
+HSPLjava/math/BigInteger;-><init>(Ljava/math/BigInt;)V
+HSPLjava/math/BigInteger;->mod(Ljava/math/BigInteger;)Ljava/math/BigInteger;
+HSPLjava/math/BigInteger;->setBigInt(Ljava/math/BigInt;)V
+HSPLjava/math/BigInt;->hasNativeBignum()Z
+HSPLjava/math/BigInt;-><init>()V
+HSPLjava/math/BigInt;->modulus(Ljava/math/BigInt;Ljava/math/BigInt;)Ljava/math/BigInt;
+HSPLjava/math/BigInt;->newBigInt()Ljava/math/BigInt;
+HSPLjava/net/AbstractPlainDatagramSocketImpl;->joinGroup(Ljava/net/SocketAddress;Ljava/net/NetworkInterface;)V
+HSPLjava/net/AbstractPlainDatagramSocketImpl;->leaveGroup(Ljava/net/SocketAddress;Ljava/net/NetworkInterface;)V
+HSPLjava/net/AbstractPlainSocketImpl;->getTimeout()I
+HSPLjava/net/AbstractPlainSocketImpl;->isConnectionReset()Z
+HSPLjava/net/DatagramPacket;-><init>([BIILjava/net/SocketAddress;)V
+HSPLjava/net/DatagramPacket;-><init>([BILjava/net/SocketAddress;)V
+HSPLjava/net/DatagramPacket;->setSocketAddress(Ljava/net/SocketAddress;)V
+HSPLjava/net/DatagramSocket;->setReuseAddress(Z)V
+HSPLjava/net/HttpURLConnection;->setChunkedStreamingMode(I)V
+HSPLjava/net/Inet6Address$Inet6AddressHolder;->isIPv4CompatibleAddress()Z
+HSPLjava/net/Inet6AddressImpl;->getHostByAddr0([B)Ljava/lang/String;
+HSPLjava/net/Inet6AddressImpl;->getHostByAddr([B)Ljava/lang/String;
+HSPLjava/net/Inet6Address;->isIPv4CompatibleAddress()Z
+HSPLjava/net/InetAddress$1;->getHostByAddr([B)Ljava/lang/String;
+HSPLjava/net/InetAddress;->getHostFromNameService(Ljava/net/InetAddress;)Ljava/lang/String;
+HSPLjava/net/InetAddress;->getHostName()Ljava/lang/String;
+HSPLjava/net/InetSocketAddress$InetSocketAddressHolder;->access$600(Ljava/net/InetSocketAddress$InetSocketAddressHolder;)Ljava/lang/String;
+HSPLjava/net/InetSocketAddress$InetSocketAddressHolder;->access$800(Ljava/net/InetSocketAddress$InetSocketAddressHolder;)Z
+HSPLjava/net/InetSocketAddress$InetSocketAddressHolder;->getHostName()Ljava/lang/String;
+HSPLjava/net/InetSocketAddress$InetSocketAddressHolder;->isUnresolved()Z
+HSPLjava/net/InetSocketAddress;->getHostName()Ljava/lang/String;
+HSPLjava/net/InetSocketAddress;-><init>(I)V
+HSPLjava/net/InetSocketAddress;->isUnresolved()Z
+HSPLjava/net/InterfaceAddress;->getAddress()Ljava/net/InetAddress;
+HSPLjava/net/MulticastSocket;-><init>(I)V
+HSPLjava/net/MulticastSocket;-><init>(Ljava/net/SocketAddress;)V
+HSPLjava/net/MulticastSocket;->joinGroup(Ljava/net/SocketAddress;Ljava/net/NetworkInterface;)V
+HSPLjava/net/MulticastSocket;->leaveGroup(Ljava/net/SocketAddress;Ljava/net/NetworkInterface;)V
+HSPLjava/net/MulticastSocket;->setNetworkInterface(Ljava/net/NetworkInterface;)V
+HSPLjava/net/MulticastSocket;->setTimeToLive(I)V
+HSPLjava/net/NetworkInterface$1checkedAddresses;->hasMoreElements()Z
+HSPLjava/net/NetworkInterface$1checkedAddresses;-><init>(Ljava/net/NetworkInterface;)V
+HSPLjava/net/NetworkInterface$1checkedAddresses;->nextElement()Ljava/lang/Object;
+HSPLjava/net/NetworkInterface$1checkedAddresses;->nextElement()Ljava/net/InetAddress;
+HSPLjava/net/NetworkInterface;->access$000(Ljava/net/NetworkInterface;)[Ljava/net/InetAddress;
+HSPLjava/net/NetworkInterface;->getByName(Ljava/lang/String;)Ljava/net/NetworkInterface;
+HSPLjava/net/NetworkInterface;->getFlags()I
+HSPLjava/net/NetworkInterface;->getHardwareAddress()[B
+HSPLjava/net/NetworkInterface;->getIndex()I
+HSPLjava/net/NetworkInterface;->getInetAddresses()Ljava/util/Enumeration;
+HSPLjava/net/NetworkInterface;->getInterfaceAddresses()Ljava/util/List;
+HSPLjava/net/NetworkInterface;->getMTU()I
+HSPLjava/net/NetworkInterface;->getName()Ljava/lang/String;
+HSPLjava/net/NetworkInterface;->getNetworkInterfaces()Ljava/util/Enumeration;
+HSPLjava/net/NetworkInterface;->isLoopback()Z
+HSPLjava/net/NetworkInterface;->isPointToPoint()Z
+HSPLjava/net/NetworkInterface;->isUp()Z
+HSPLjava/net/NetworkInterface;->isVirtual()Z
+HSPLjava/net/NetworkInterface;->supportsMulticast()Z
+HSPLjava/net/PlainDatagramSocketImpl;->join(Ljava/net/InetAddress;Ljava/net/NetworkInterface;)V
+HSPLjava/net/PlainDatagramSocketImpl;->leave(Ljava/net/InetAddress;Ljava/net/NetworkInterface;)V
+HSPLjava/net/PlainDatagramSocketImpl;->makeGroupReq(Ljava/net/InetAddress;Ljava/net/NetworkInterface;)Landroid/system/StructGroupReq;
+HSPLjava/net/PlainDatagramSocketImpl;->setTimeToLive(I)V
+HSPLjava/net/PlainDatagramSocketImpl;->socketSetOption0(ILjava/lang/Object;)V
+HSPLjava/net/PlainDatagramSocketImpl;->socketSetOption(ILjava/lang/Object;)V
+HSPLjava/net/SocketAddress;-><init>()V
+HSPLjava/net/SocketInputStream;->read([BII)I
+HSPLjava/net/SocketInputStream;->read([BIII)I
+HSPLjava/net/SocketInputStream;->socketRead(Ljava/io/FileDescriptor;[BIII)I
+HSPLjava/net/SocketOutputStream;->socketWrite([BII)V
+HSPLjava/net/SocketOutputStream;->write([BII)V
+HSPLjava/net/UnknownHostException;-><init>(Ljava/lang/String;)V
+HSPLjava/net/URI$Parser;->charAt(I)C
+HSPLjava/net/URI$Parser;-><init>(Ljava/net/URI;Ljava/lang/String;)V
+HSPLjava/net/URI$Parser;->scanEscape(IIC)I
+HSPLjava/net/URI;->access$002(Ljava/net/URI;Ljava/lang/String;)Ljava/lang/String;
+HSPLjava/net/URI;->access$100()J
+HSPLjava/net/URI;->access$200()J
+HSPLjava/net/URI;->access$300(CJJ)Z
+HSPLjava/net/URI;->hashCode()I
+HSPLjava/net/URI;->hashIgnoringCase(ILjava/lang/String;)I
+HSPLjava/net/URI;->hash(ILjava/lang/String;)I
+HSPLjava/net/URI;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+HSPLjava/net/URI;->isAbsolute()Z
+HSPLjava/net/URI;->isOpaque()Z
+HSPLjava/net/URI;->toLower(C)I
+HSPLjava/net/URI;->toURL()Ljava/net/URL;
+HSPLjava/net/URLConnection;->getContentEncoding()Ljava/lang/String;
+HSPLjava/net/URLConnection;->getContentLength()I
+HSPLjava/nio/Bits;->getFloatB(Ljava/nio/ByteBuffer;I)F
+HSPLjava/nio/Bits;->getFloat(Ljava/nio/ByteBuffer;IZ)F
+HSPLjava/nio/Bits;->getIntB(Ljava/nio/ByteBuffer;I)I
+HSPLjava/nio/Bits;->getInt(Ljava/nio/ByteBuffer;IZ)I
+HSPLjava/nio/Bits;->makeInt(BBBB)I
+HSPLjava/nio/Bits;->putFloatB(Ljava/nio/ByteBuffer;IF)V
+HSPLjava/nio/Bits;->putFloat(Ljava/nio/ByteBuffer;IFZ)V
+HSPLjava/nio/Bits;->putLong(Ljava/nio/ByteBuffer;IJZ)V
+HSPLjava/nio/Buffer;->nextGetIndex()I
+HSPLjava/nio/Buffer;->nextGetIndex(I)I
+HSPLjava/nio/Buffer;->nextPutIndex(I)I
+HSPLjava/nio/ByteBufferAsIntBuffer;->get()I
+HSPLjava/nio/ByteBufferAsIntBuffer;->get(I)I
+HSPLjava/nio/ByteBufferAsIntBuffer;->put([III)Ljava/nio/IntBuffer;
+HSPLjava/nio/ByteBufferAsLongBuffer;->put([JII)Ljava/nio/LongBuffer;
+HSPLjava/nio/ByteBufferAsShortBuffer;->put([SII)Ljava/nio/ShortBuffer;
+HSPLjava/nio/ByteBuffer;->compareTo(Ljava/lang/Object;)I
+HSPLjava/nio/ByteBuffer;->equals(BB)Z
+HSPLjava/nio/ByteBuffer;->equals(Ljava/lang/Object;)Z
+HSPLjava/nio/channels/FileChannel;->lock()Ljava/nio/channels/FileLock;
+HSPLjava/nio/channels/FileLock;->position()J
+HSPLjava/nio/channels/FileLock;->size()J
+HSPLjava/nio/channels/spi/AbstractInterruptibleChannel;->isOpen()Z
+HSPLjava/nio/DirectByteBuffer;->getFloat()F
+HSPLjava/nio/DirectByteBuffer;->getFloat(J)F
+HSPLjava/nio/DirectByteBuffer;->getLong()J
+HSPLjava/nio/DirectByteBuffer;->getLong(J)J
+HSPLjava/nio/DirectByteBuffer;->ix(I)J
+HSPLjava/nio/HeapByteBuffer;->asIntBuffer()Ljava/nio/IntBuffer;
+HSPLjava/nio/HeapByteBuffer;->asLongBuffer()Ljava/nio/LongBuffer;
+HSPLjava/nio/HeapByteBuffer;->getFloat()F
+HSPLjava/nio/HeapByteBuffer;->getIntUnchecked(I)I
+HSPLjava/nio/HeapByteBuffer;->getUnchecked(I[III)V
+HSPLjava/nio/HeapByteBuffer;->getUnchecked(I[JII)V
+HSPLjava/nio/HeapByteBuffer;->getUnchecked(I[SII)V
+HSPLjava/nio/HeapByteBuffer;->ix(I)I
+HSPLjava/nio/HeapByteBuffer;->putFloat(F)Ljava/nio/ByteBuffer;
+HSPLjava/nio/HeapByteBuffer;->putLong(IJ)Ljava/nio/ByteBuffer;
+HSPLjava/nio/HeapByteBuffer;->putUnchecked(I[III)V
+HSPLjava/nio/HeapByteBuffer;->putUnchecked(I[JII)V
+HSPLjava/nio/HeapByteBuffer;->putUnchecked(I[SII)V
+HSPLjava/nio/IntBuffer;->put([I)Ljava/nio/IntBuffer;
+HSPLjava/nio/LongBuffer;->put([J)Ljava/nio/LongBuffer;
+HSPLjava/nio/ShortBuffer;->put([S)Ljava/nio/ShortBuffer;
+HSPLjava/security/GeneralSecurityException;-><init>(Ljava/lang/Throwable;)V
+HSPLjava/security/InvalidAlgorithmParameterException;-><init>(Ljava/lang/Throwable;)V
+HSPLjava/security/KeyFactory;->getInstance(Ljava/lang/String;Ljava/security/Provider;)Ljava/security/KeyFactory;
+HSPLjava/security/KeyFactory;-><init>(Ljava/security/KeyFactorySpi;Ljava/security/Provider;Ljava/lang/String;)V
+HSPLjava/security/MessageDigest;->getAlgorithm()Ljava/lang/String;
+HSPLjava/security/MessageDigest;-><init>(Ljava/lang/String;)V
+HSPLjava/security/Provider$Service;->getProvider()Ljava/security/Provider;
+HSPLjava/security/spec/ECParameterSpec;->getCurveName()Ljava/lang/String;
+HSPLjava/security/spec/ECParameterSpec;->getGenerator()Ljava/security/spec/ECPoint;
+HSPLjava/security/spec/ECPoint;->getAffineX()Ljava/math/BigInteger;
+HSPLjava/security/spec/ECPoint;->getAffineY()Ljava/math/BigInteger;
+HSPLjava/security/spec/ECPublicKeySpec;->getParams()Ljava/security/spec/ECParameterSpec;
+HSPLjava/security/spec/ECPublicKeySpec;->getW()Ljava/security/spec/ECPoint;
+HSPLjava/security/spec/ECPublicKeySpec;-><init>(Ljava/security/spec/ECPoint;Ljava/security/spec/ECParameterSpec;)V
+HSPLjava/security/spec/EllipticCurve;->getA()Ljava/math/BigInteger;
+HSPLjava/security/spec/EllipticCurve;->getB()Ljava/math/BigInteger;
+HSPLjava/text/DateFormat;->getDateTimeInstance(II)Ljava/text/DateFormat;
+HSPLjava/text/DecimalFormat;->initPattern(Ljava/lang/String;)V
+HSPLjava/text/DecimalFormat;-><init>()V
+HSPLjava/text/DecimalFormatSymbols;->getInstance(Ljava/util/Locale;)Ljava/text/DecimalFormatSymbols;
+HSPLjava/text/FieldPosition;-><init>(I)V
+HSPLjava/text/FieldPosition;-><init>(Ljava/text/Format$Field;I)V
+HSPLjava/text/Format;-><init>()V
+HSPLjava/text/NumberFormat;-><init>()V
+HSPLjava/text/SimpleDateFormat;->isDigit(C)Z
+HSPLjava/text/SimpleDateFormat;->subParseNumericZone(Ljava/lang/String;IIIZLjava/text/CalendarBuilder;)I
+HSPLjava/time/Duration;->between(Ljava/time/temporal/Temporal;Ljava/time/temporal/Temporal;)Ljava/time/Duration;
+HSPLjava/time/Duration;->compareTo(Ljava/time/Duration;)I
+HSPLjava/time/Duration;->getNano()I
+HSPLjava/time/Duration;->getSeconds()J
+HSPLjava/time/Duration;->isNegative()Z
+HSPLjava/time/Duration;->minus(Ljava/time/Duration;)Ljava/time/Duration;
+HSPLjava/time/Duration;->plus(JJ)Ljava/time/Duration;
+HSPLjava/time/Duration;->subtractFrom(Ljava/time/temporal/Temporal;)Ljava/time/temporal/Temporal;
+HSPLjava/time/Duration;->toString()Ljava/lang/String;
+HSPLjava/time/Instant;->compareTo(Ljava/time/Instant;)I
+HSPLjava/time/Instant;->isBefore(Ljava/time/Instant;)Z
+HSPLjava/time/Instant;->minus(JLjava/time/temporal/TemporalUnit;)Ljava/time/Instant;
+HSPLjava/time/Instant;->minus(JLjava/time/temporal/TemporalUnit;)Ljava/time/temporal/Temporal;
+HSPLjava/time/Instant;->minus(Ljava/time/temporal/TemporalAmount;)Ljava/time/Instant;
+HSPLjava/time/Instant;->nanosUntil(Ljava/time/Instant;)J
+HSPLjava/time/Instant;->plus(JLjava/time/temporal/TemporalUnit;)Ljava/time/Instant;
+HSPLjava/time/Instant;->plusSeconds(J)Ljava/time/Instant;
+HSPLjava/time/Instant;->until(Ljava/time/temporal/Temporal;Ljava/time/temporal/TemporalUnit;)J
+HSPLjava/util/AbstractList$Itr;->checkForComodification()V
+HSPLjava/util/AbstractList$ListItr;->hasPrevious()Z
+HSPLjava/util/AbstractList$ListItr;->previousIndex()I
+HSPLjava/util/AbstractList$ListItr;->previous()Ljava/lang/Object;
+HSPLjava/util/AbstractList;->indexOf(Ljava/lang/Object;)I
+HSPLjava/util/AbstractMap$2;-><init>(Ljava/util/AbstractMap;)V
+HSPLjava/util/AbstractMap$2;->iterator()Ljava/util/Iterator;
+HSPLjava/util/AbstractMap$SimpleImmutableEntry;-><init>(Ljava/util/Map$Entry;)V
+HSPLjava/util/AbstractMap;->values()Ljava/util/Collection;
+HSPLjava/util/ArrayList$Itr;-><init>(Ljava/util/ArrayList;)V
+HSPLjava/util/Arrays;->deepToString([Ljava/lang/Object;)Ljava/lang/String;
+HSPLjava/util/Arrays;->deepToString([Ljava/lang/Object;Ljava/lang/StringBuilder;Ljava/util/Set;)V
+HSPLjava/util/Arrays;->fill([DD)V
+HSPLjava/util/Arrays;->fill([ZIIZ)V
+HSPLjava/util/Arrays;->sort([Ljava/lang/Object;II)V
+HSPLjava/util/Arrays;->toString([F)Ljava/lang/String;
+HSPLjava/util/BitSet;->checkInvariants()V
+HSPLjava/util/BitSet;->clear(II)V
+HSPLjava/util/BitSet;->recalculateWordsInUse()V
+HSPLjava/util/BitSet;->wordIndex(I)I
+HSPLjava/util/Calendar;->after(Ljava/lang/Object;)Z
+HSPLjava/util/Calendar;->before(Ljava/lang/Object;)Z
+HSPLjava/util/Calendar;->compareTo(J)I
+HSPLjava/util/Calendar;->compareTo(Ljava/util/Calendar;)I
+HSPLjava/util/Calendar;->getMillisOf(Ljava/util/Calendar;)J
+HSPLjava/util/Collections$EmptyList;->listIterator()Ljava/util/ListIterator;
+HSPLjava/util/Collections$EmptyList;->sort(Ljava/util/Comparator;)V
+HSPLjava/util/Collections$EmptyMap;->keySet()Ljava/util/Set;
+HSPLjava/util/Collections$SynchronizedMap;->containsValue(Ljava/lang/Object;)Z
+HSPLjava/util/Collections$SynchronizedMap;->keySet()Ljava/util/Set;
+HSPLjava/util/Collections$UnmodifiableMap;->toString()Ljava/lang/String;
+HSPLjava/util/Collections;->emptyListIterator()Ljava/util/ListIterator;
+HSPLjava/util/Collections;->frequency(Ljava/util/Collection;Ljava/lang/Object;)I
+HSPLjava/util/Collection;->spliterator()Ljava/util/Spliterator;
+HSPLjava/util/Collection;->stream()Ljava/util/stream/Stream;
+HSPLjava/util/concurrent/AbstractExecutorService;->submit(Ljava/lang/Runnable;Ljava/lang/Object;)Ljava/util/concurrent/Future;
+HSPLjava/util/concurrent/ArrayBlockingQueue;->add(Ljava/lang/Object;)Z
+HSPLjava/util/concurrent/atomic/AtomicBoolean;->lazySet(Z)V
+HSPLjava/util/concurrent/atomic/AtomicLong;->decrementAndGet()J
+HSPLjava/util/concurrent/ConcurrentHashMap$BaseIterator;-><init>([Ljava/util/concurrent/ConcurrentHashMap$Node;IIILjava/util/concurrent/ConcurrentHashMap;)V
+HSPLjava/util/concurrent/ConcurrentHashMap$EntrySetView;->removeIf(Ljava/util/function/Predicate;)Z
+HSPLjava/util/concurrent/ConcurrentHashMap$Traverser;-><init>([Ljava/util/concurrent/ConcurrentHashMap$Node;III)V
+HSPLjava/util/concurrent/ConcurrentHashMap;-><init>(Ljava/util/Map;)V
+HSPLjava/util/concurrent/ConcurrentHashMap;->putAll(Ljava/util/Map;)V
+HSPLjava/util/concurrent/ConcurrentHashMap;->removeEntryIf(Ljava/util/function/Predicate;)Z
+HSPLjava/util/concurrent/ConcurrentHashMap;->remove(Ljava/lang/Object;Ljava/lang/Object;)Z
+HSPLjava/util/concurrent/Executors$RunnableAdapter;-><init>(Ljava/lang/Runnable;Ljava/lang/Object;)V
+HSPLjava/util/concurrent/LinkedBlockingQueue;->clear()V
+HSPLjava/util/concurrent/locks/AbstractQueuedSynchronizer;->acquireShared(I)V
+HSPLjava/util/concurrent/locks/AbstractQueuedSynchronizer;->getState()I
+HSPLjava/util/concurrent/locks/AbstractQueuedSynchronizer;->release(I)Z
+HSPLjava/util/concurrent/locks/AbstractQueuedSynchronizer;->tryAcquireSharedNanos(IJ)Z
+HSPLjava/util/concurrent/Semaphore$Sync;->getPermits()I
+HSPLjava/util/concurrent/Semaphore;->acquireUninterruptibly()V
+HSPLjava/util/concurrent/Semaphore;->availablePermits()I
+HSPLjava/util/concurrent/Semaphore;->tryAcquire(JLjava/util/concurrent/TimeUnit;)Z
+HSPLjava/util/concurrent/ThreadPoolExecutor$DiscardPolicy;-><init>()V
+HSPLjava/util/concurrent/ThreadPoolExecutor;->getMaximumPoolSize()I
+HSPLjava/util/concurrent/ThreadPoolExecutor;->setThreadFactory(Ljava/util/concurrent/ThreadFactory;)V
+HSPLjava/util/concurrent/TimeUnit$2;->convert(JLjava/util/concurrent/TimeUnit;)J
+HSPLjava/util/concurrent/TimeUnit$2;->toSeconds(J)J
+HSPLjava/util/concurrent/TimeUnit$5;->toMicros(J)J
+HSPLjava/util/concurrent/TimeUnit$7;->toMicros(J)J
+HSPLjava/util/concurrent/TimeUnit;->x(JJJ)J
+HSPLjava/util/Date;->after(Ljava/util/Date;)Z
+HSPLjava/util/Date;->getCalendarSystem(I)Lsun/util/calendar/BaseCalendar;
+HSPLjava/util/Date;->getCalendarSystem(Lsun/util/calendar/BaseCalendar$Date;)Lsun/util/calendar/BaseCalendar;
+HSPLjava/util/Date;->getMillisOf(Ljava/util/Date;)J
+HSPLjava/util/Date;->getTimeImpl()J
+HSPLjava/util/Date;-><init>(IIIIII)V
+HSPLjava/util/Date;->normalize(Lsun/util/calendar/BaseCalendar$Date;)Lsun/util/calendar/BaseCalendar$Date;
+HSPLjava/util/Formatter$FormatSpecifier;->print(Ljava/math/BigInteger;Ljava/util/Locale;)V
+HSPLjava/util/Formatter$FormatSpecifier;->trailingSign(Ljava/lang/StringBuilder;Z)Ljava/lang/StringBuilder;
+HSPLjava/util/Formatter;->access$000(Ljava/util/Formatter;)Ljava/lang/Appendable;
+HSPLjava/util/function/-$$Lambda$DoubleUnaryOperator$EzzlhUGRoL66wVBCG-_euZgC-CA;->applyAsDouble(D)D
+HSPLjava/util/function/DoubleUnaryOperator;->lambda$andThen$1(Ljava/util/function/DoubleUnaryOperator;Ljava/util/function/DoubleUnaryOperator;D)D
+HSPLjava/util/HashMap$Node;-><init>(ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Node;)V
+HSPLjava/util/HashMap$TreeNode;-><init>(ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Node;)V
+HSPLjava/util/HashMap$TreeNode;->putTreeVal(Ljava/util/HashMap;[Ljava/util/HashMap$Node;ILjava/lang/Object;Ljava/lang/Object;)Ljava/util/HashMap$TreeNode;
+HSPLjava/util/HashMap;->newTreeNode(ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Node;)Ljava/util/HashMap$TreeNode;
+HSPLjava/util/HashSet;-><init>(IFZ)V
+HSPLjava/util/IdentityHashMap$KeySet;->size()I
+HSPLjava/util/IdentityHashMap;->size()I
+HSPLjava/util/Iterator;->forEachRemaining(Ljava/util/function/Consumer;)V
+HSPLjava/util/LinkedHashMap$LinkedEntrySet;->spliterator()Ljava/util/Spliterator;
+HSPLjava/util/LinkedHashMap$LinkedHashMapEntry;-><init>(ILjava/lang/Object;Ljava/lang/Object;Ljava/util/HashMap$Node;)V
+HSPLjava/util/LinkedHashMap$LinkedKeySet;->contains(Ljava/lang/Object;)Z
+HSPLjava/util/LinkedHashMap;-><init>(IF)V
+HSPLjava/util/LinkedHashSet;-><init>(IF)V
+HSPLjava/util/Map;->forEach(Ljava/util/function/BiConsumer;)V
+HSPLjava/util/Map;->getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLjava/util/PriorityQueue;->comparator()Ljava/util/Comparator;
+HSPLjava/util/PriorityQueue;->contains(Ljava/lang/Object;)Z
+HSPLjava/util/PriorityQueue;->indexOf(Ljava/lang/Object;)I
+HSPLjava/util/PriorityQueue;->initElementsFromCollection(Ljava/util/Collection;)V
+HSPLjava/util/PriorityQueue;-><init>(Ljava/util/Collection;)V
+HSPLjava/util/PriorityQueue;->siftDown(ILjava/lang/Object;)V
+HSPLjava/util/regex/Matcher;->regionEnd()I
+HSPLjava/util/regex/Matcher;->regionStart()I
+HSPLjava/util/Spliterators$IteratorSpliterator;-><init>(Ljava/util/Collection;I)V
+HSPLjava/util/Spliterators;->spliterator(Ljava/util/Collection;I)Ljava/util/Spliterator;
+HSPLjava/util/stream/AbstractPipeline;-><init>(Ljava/util/Spliterator;IZ)V
+HSPLjava/util/stream/ReduceOps$1;-><init>(Ljava/util/stream/StreamShape;Ljava/util/function/BinaryOperator;Ljava/util/function/BiFunction;Ljava/lang/Object;)V
+HSPLjava/util/stream/ReduceOps$1;->makeSink()Ljava/util/stream/ReduceOps$1ReducingSink;
+HSPLjava/util/stream/ReduceOps$1;->makeSink()Ljava/util/stream/ReduceOps$AccumulatingSink;
+HSPLjava/util/stream/ReduceOps$1ReducingSink;->begin(J)V
+HSPLjava/util/stream/ReduceOps$1ReducingSink;-><init>(Ljava/lang/Object;Ljava/util/function/BiFunction;Ljava/util/function/BinaryOperator;)V
+HSPLjava/util/stream/ReduceOps$Box;-><init>()V
+HSPLjava/util/stream/ReduceOps;->makeRef(Ljava/lang/Object;Ljava/util/function/BiFunction;Ljava/util/function/BinaryOperator;)Ljava/util/stream/TerminalOp;
+HSPLjava/util/stream/ReferencePipeline$Head;-><init>(Ljava/util/Spliterator;IZ)V
+HSPLjava/util/stream/ReferencePipeline;-><init>(Ljava/util/Spliterator;IZ)V
+HSPLjava/util/stream/ReferencePipeline;->reduce(Ljava/lang/Object;Ljava/util/function/BinaryOperator;)Ljava/lang/Object;
+HSPLjava/util/stream/StreamOpFlag;->fromCharacteristics(Ljava/util/Spliterator;)I
+HSPLjava/util/stream/StreamSupport;->stream(Ljava/util/Spliterator;Z)Ljava/util/stream/Stream;
+HSPLjava/util/TaskQueue;-><init>()V
+HSPLjava/util/Timer$1;-><init>(Ljava/util/Timer;)V
+HSPLjava/util/Timer;-><init>(Ljava/lang/String;Z)V
+HSPLjava/util/Timer;->scheduleAtFixedRate(Ljava/util/TimerTask;JJ)V
+HSPLjava/util/TimerThread;-><init>(Ljava/util/TaskQueue;)V
+HSPLjava/util/TreeMap$KeySet;->comparator()Ljava/util/Comparator;
+HSPLjava/util/TreeMap$KeySet;->size()I
+HSPLjava/util/TreeMap;->addAllForTreeSet(Ljava/util/SortedSet;Ljava/lang/Object;)V
+HSPLjava/util/TreeMap;->buildFromSorted(ILjava/util/Iterator;Ljava/io/ObjectInputStream;Ljava/lang/Object;)V
+HSPLjava/util/TreeMap;->computeRedLevel(I)I
+HSPLjava/util/TreeMap;->exportEntry(Ljava/util/TreeMap$TreeMapEntry;)Ljava/util/Map$Entry;
+HSPLjava/util/TreeMap;->getLastEntry()Ljava/util/TreeMap$TreeMapEntry;
+HSPLjava/util/TreeMap;->lastEntry()Ljava/util/Map$Entry;
+HSPLjava/util/TreeMap;->putAll(Ljava/util/Map;)V
+HSPLjava/util/TreeMap;->subMap(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/SortedMap;
+HSPLjava/util/TreeSet;-><init>(Ljava/util/SortedSet;)V
+HSPLjava/util/Vector;->ensureCapacityHelper(I)V
+HSPLjava/util/Vector;->insertElementAt(Ljava/lang/Object;I)V
+HSPLjava/util/Vector;->setElementAt(Ljava/lang/Object;I)V
+HSPLjava/util/zip/Adler32;->update([BII)V
+HSPLjava/util/zip/Adler32;->update(I)V
+HSPLjava/util/zip/ZipFile$ZipEntryIterator;->hasMoreElements()Z
+HSPLjava/util/zip/ZipFile$ZipEntryIterator;->hasNext()Z
+HSPLjava/util/zip/ZipFile$ZipEntryIterator;-><init>(Ljava/util/zip/ZipFile;)V
+HSPLjava/util/zip/ZipFile$ZipEntryIterator;->nextElement()Ljava/lang/Object;
+HSPLjava/util/zip/ZipFile$ZipEntryIterator;->nextElement()Ljava/util/zip/ZipEntry;
+HSPLjava/util/zip/ZipFile$ZipEntryIterator;->next()Ljava/util/zip/ZipEntry;
+HSPLjava/util/zip/ZipFile;->access$1000(JJ)V
+HSPLjava/util/zip/ZipFile;->access$200(Ljava/util/zip/ZipFile;)V
+HSPLjava/util/zip/ZipFile;->access$300(Ljava/util/zip/ZipFile;)I
+HSPLjava/util/zip/ZipFile;->access$400(Ljava/util/zip/ZipFile;)J
+HSPLjava/util/zip/ZipFile;->access$500(JI)J
+HSPLjava/util/zip/ZipFile;->access$900(Ljava/util/zip/ZipFile;Ljava/lang/String;J)Ljava/util/zip/ZipEntry;
+HSPLjava/util/zip/ZipFile;->entries()Ljava/util/Enumeration;
+HSPLjava/util/zip/ZipFile;-><init>(Ljava/io/File;I)V
+HSPLjava/util/zip/ZipFile;-><init>(Ljava/io/File;)V
+HSPLjavax/crypto/JceSecurity;->access$000()Ljava/net/URL;
+HSPLjavax/crypto/JceSecurity;->getCodeBase(Ljava/lang/Class;)Ljava/net/URL;
+HSPLjavax/crypto/JceSecurity;->getInstance(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)Lsun/security/jca/GetInstance$Instance;
+HSPLjavax/crypto/JceSecurity;->getVerificationResult(Ljava/security/Provider;)Ljava/lang/Exception;
+HSPLjavax/crypto/JceSecurity;->verifyProviderJar(Ljava/net/URL;)V
+HSPLjavax/crypto/KeyGenerator;->getInstance(Ljava/lang/String;Ljava/lang/String;)Ljavax/crypto/KeyGenerator;
+HSPLjavax/crypto/KeyGenerator;->init(Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)V
+HSPLjavax/crypto/KeyGenerator;->init(Ljava/security/spec/AlgorithmParameterSpec;)V
+HSPLjavax/crypto/KeyGenerator;-><init>(Ljavax/crypto/KeyGeneratorSpi;Ljava/security/Provider;Ljava/lang/String;)V
+HSPLjavax/crypto/Mac;->reset()V
+HSPLjavax/crypto/spec/SecretKeySpec;->getAlgorithm()Ljava/lang/String;
+HSPLlibcore/icu/DateUtilsBridge;->icuTimeZone(Ljava/util/TimeZone;)Landroid/icu/util/TimeZone;
+HSPLlibcore/io/BlockGuardOs;->connect(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V
+HSPLlibcore/io/BlockGuardOs;->isUdpSocket(Ljava/io/FileDescriptor;)Z
+HSPLlibcore/io/BlockGuardOs;->sendto(Ljava/io/FileDescriptor;[BIIILjava/net/SocketAddress;)I
+HSPLlibcore/io/ForwardingOs;->connect(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V
+HSPLlibcore/io/ForwardingOs;->prctl(IJJJJ)I
+HSPLlibcore/io/ForwardingOs;->recvfrom(Ljava/io/FileDescriptor;[BIIILjava/net/InetSocketAddress;)I
+HSPLlibcore/io/ForwardingOs;->sendto(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;I)I
+HSPLlibcore/io/ForwardingOs;->sendto(Ljava/io/FileDescriptor;[BIIILjava/net/SocketAddress;)I
+HSPLlibcore/io/ForwardingOs;->setsockoptByte(Ljava/io/FileDescriptor;III)V
+HSPLlibcore/io/ForwardingOs;->setsockoptGroupReq(Ljava/io/FileDescriptor;IILandroid/system/StructGroupReq;)V
+HSPLlibcore/io/ForwardingOs;->setsockoptIfreq(Ljava/io/FileDescriptor;IILjava/lang/String;)V
+HSPLlibcore/io/ForwardingOs;->setsockoptIpMreqn(Ljava/io/FileDescriptor;III)V
+HSPLlibcore/io/Linux;->sendto(Ljava/io/FileDescriptor;[BIIILjava/net/SocketAddress;)I
+HSPLlibcore/util/ZoneInfo;->access$500(JI)I
+HSPLlibcore/util/ZoneInfo;->access$600(JI)I
+HSPLlibcore/util/ZoneInfo;->checked32BitAdd(JI)I
+HSPLlibcore/util/ZoneInfo;->checked32BitSubtract(JI)I
+HSPLorg/json/JSONArray;-><init>(Ljava/util/Collection;)V
+HSPLorg/json/JSONObject;->length()I
+HSPLorg/json/JSONTokener;->skipToEndOfLine()V
+HSPLsun/misc/FloatingDecimal;->appendTo(DLjava/lang/Appendable;)V
+HSPLsun/misc/FloatingDecimal;->getBinaryToASCIIConverter(D)Lsun/misc/FloatingDecimal$BinaryToASCIIConverter;
+HSPLsun/misc/FloatingDecimal;->parseDouble(Ljava/lang/String;)D
+HSPLsun/misc/FloatingDecimal;->parseFloat(Ljava/lang/String;)F
+HSPLsun/misc/FloatingDecimal;->toJavaFormatString(D)Ljava/lang/String;
+HSPLsun/nio/ch/FileChannelImpl;->release(Lsun/nio/ch/FileLockImpl;)V
+HSPLsun/nio/ch/FileLockImpl;->release()V
+HSPLsun/nio/ch/SharedFileLockTable;->remove(Ljava/nio/channels/FileLock;)V
+HSPLsun/nio/fs/NativeBuffer$Deallocator;->run()V
+HSPLsun/nio/fs/NativeBuffer;->access$000()Lsun/misc/Unsafe;
+HSPLsun/security/jca/GetInstance$Instance;-><init>(Ljava/security/Provider;Ljava/lang/Object;Lsun/security/jca/GetInstance$1;)V
+HSPLsun/security/jca/GetInstance$Instance;-><init>(Ljava/security/Provider;Ljava/lang/Object;)V
+HSPLsun/security/jca/GetInstance;->getInstance(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Ljava/security/Provider;)Lsun/security/jca/GetInstance$Instance;
+HSPLsun/security/jca/GetInstance;->getInstance(Ljava/security/Provider$Service;Ljava/lang/Class;)Lsun/security/jca/GetInstance$Instance;
+HSPLsun/util/calendar/BaseCalendar$Date;->setNormalizedDate(III)Lsun/util/calendar/BaseCalendar$Date;
+HSPLjava/util/Iterator;->forEachRemaining(Ljava/util/function/Consumer;)V
+HSPLjava/lang/Iterable;->forEach(Ljava/util/function/Consumer;)V
+HSPLjava/util/Map;->forEach(Ljava/util/function/BiConsumer;)V
+HSPLjava/util/Collection;->spliterator()Ljava/util/Spliterator;
+HSPLjava/util/Collection;->stream()Ljava/util/stream/Stream;
+HSPLandroid/os/Trace;->endAsyncSection(Ljava/lang/String;I)V
+HSPLjava/util/Map;->getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/bluetooth/le/ScanFilter;-><init>(Ljava/lang/String;Ljava/lang/String;Landroid/os/ParcelUuid;Landroid/os/ParcelUuid;Landroid/os/ParcelUuid;Landroid/os/ParcelUuid;Landroid/os/ParcelUuid;[B[BI[B[B)V
+HSPLjava/nio/ByteBuffer;->array()Ljava/lang/Object;
+HSPLjava/nio/NIOAccess;->getBaseArray(Ljava/nio/Buffer;)Ljava/lang/Object;
+HSPLjava/nio/NIOAccess;->getBaseArrayOffset(Ljava/nio/Buffer;)I
+HSPLandroid/graphics/drawable/RotateDrawable;->draw(Landroid/graphics/Canvas;)V
+HSPLandroid/graphics/Bitmap;->checkHardware(Ljava/lang/String;)V
+HSPLandroid/graphics/Bitmap;->copyPixelsToBuffer(Ljava/nio/Buffer;)V
+HSPLandroid/graphics/Bitmap;->getDensity()I
+HSPLandroid/accounts/AccountManager;->setAuthToken(Landroid/accounts/Account;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/accounts/AccountManager;->setUserData(Landroid/accounts/Account;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/accounts/IAccountManager$Stub$Proxy;->setAuthToken(Landroid/accounts/Account;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/accounts/IAccountManager$Stub$Proxy;->setUserData(Landroid/accounts/Account;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onNetwork()V
+HSPLjava/util/Arrays$ArrayList;-><init>([Ljava/lang/Object;)V
+HSPLjava/util/regex/Matcher;-><init>(Ljava/util/regex/Pattern;Ljava/lang/CharSequence;)V
+HSPLjava/util/Map;->getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
diff --git a/config/dirty-image-objects b/config/dirty-image-objects
index 9e2230b..ec2568d 100644
--- a/config/dirty-image-objects
+++ b/config/dirty-image-objects
@@ -28,147 +28,359 @@
 # Then, grep for lines containing "Private dirty object" from the output.
 # This particular file was generated by dumping systemserver and systemui.
 #
+android.accounts.Account
+android.accounts.OnAccountsUpdateListener
+android.animation.LayoutTransition
+android.app.ActivityManager
+android.app.ActivityManager$OnUidImportanceListener
+android.app.ActivityTaskManager
+android.app.ActivityThread
+android.app.admin.DevicePolicyManager
+android.app.AlarmManager
+android.app.Application
+android.app.AppOpsManager
+android.app.backup.BackupManager
+android.app.ContextImpl
+android.app.INotificationManager
+android.app.Notification$BigPictureStyle
+android.app.Notification$BigTextStyle
+android.app.Notification$InboxStyle
+android.app.NotificationChannel
+android.app.NotificationChannelGroup
+android.app.NotificationManager
+android.app.PendingIntent
+android.app.PendingIntent$OnFinished
+android.app.QueuedWork
+android.app.ResourcesManager
+android.app.WallpaperManager
+android.app.WindowConfiguration
+android.bluetooth.BluetoothAdapter
+android.bluetooth.BluetoothDevice
+android.bluetooth.BluetoothProfile
+android.bluetooth.IBluetoothA2dp
+android.bluetooth.IBluetoothHeadsetPhone
+android.bluetooth.IBluetoothHidDevice
+android.bluetooth.IBluetoothHidHost
+android.bluetooth.IBluetoothMap
+android.bluetooth.IBluetoothPan
+android.bluetooth.IBluetoothPbap
+android.bluetooth.IBluetoothSap
+android.content.ClipboardManager$OnPrimaryClipChangedListener
+android.content.ComponentName
+android.content.ContentProvider$PipeDataWriter
+android.content.ContentResolver
+android.content.Context
+android.content.Intent
+android.content.pm.PackageManager$OnPermissionsChangedListener
+android.content.pm.VersionedPackage
+android.content.res.Configuration
+android.content.SharedPreferences$OnSharedPreferenceChangeListener
+android.database.CursorWindow
+android.database.sqlite.SQLiteCompatibilityWalFlags
+android.database.sqlite.SQLiteDatabase$CursorFactory
+android.database.sqlite.SQLiteGlobal
+android.database.sqlite.SQLiteTransactionListener
+android.ddm.DdmHandleAppName
+android.graphics.Bitmap
+android.graphics.Canvas
+android.graphics.drawable.AdaptiveIconDrawable
+android.graphics.drawable.ColorDrawable
+android.graphics.drawable.GradientDrawable
+android.graphics.drawable.Icon
+android.graphics.drawable.InsetDrawable
+android.graphics.drawable.RippleDrawable
+android.graphics.drawable.VectorDrawable$VGroup
+android.graphics.ImageDecoder
+android.graphics.Rect
+android.graphics.TemporaryBuffer
+android.hardware.biometrics.BiometricSourceType
+android.hardware.display.ColorDisplayManager$ColorDisplayManagerInternal
+android.hardware.display.DisplayManagerGlobal
+android.hardware.display.NightDisplayListener$Callback
+android.hardware.input.InputManager
+android.hardware.input.InputManager$InputDeviceListener
+android.hardware.SensorPrivacyManager
+android.hardware.SystemSensorManager
+android.icu.impl.OlsonTimeZone
+android.icu.text.BreakIterator
+android.icu.text.Collator
+android.icu.text.DateFormat$BooleanAttribute
+android.icu.text.DateTimePatternGenerator$DTPGflags
+android.icu.text.PluralRules$Operand
+android.icu.util.TimeZone
+android.location.GpsStatus$Listener
+android.location.LocationListener
+android.media.AudioManager
+android.media.MediaRouter
+android.media.PlayerBase
+android.media.session.MediaSessionManager
+android.net.apf.ApfCapabilities
+android.net.ConnectivityManager
+android.net.ConnectivityManager$OnNetworkActiveListener
+android.net.ConnectivityThread$Singleton
+android.net.IpConfiguration$IpAssignment
+android.net.IpConfiguration$ProxySettings
+android.net.IpPrefix
+android.net.LinkAddress
+android.net.LinkProperties
+android.net.Network
+android.net.NetworkCapabilities
+android.net.NetworkInfo
+android.net.NetworkInfo$State
+android.net.NetworkRequest
+android.net.NetworkRequest$Type
+android.net.RouteInfo
+android.net.StringNetworkSpecifier
+android.net.TrafficStats
+android.net.UidRange
+android.net.Uri$HierarchicalUri
+android.net.Uri$StringUri
+android.net.wifi.WifiManager
+android.net.wifi.WifiManager$SoftApCallback
+android.os.AsyncResult
+android.os.AsyncTask
+android.os.BinderProxy
+android.os.Bundle
+android.os.DeadObjectException
+android.os.Environment
+android.os.FileObserver
+android.os.Handler
+android.os.IDeviceIdleController
+android.os.LocaleList
+android.os.Looper
+android.os.Message
+android.os.ParcelUuid
+android.os.Process
+android.os.RecoverySystem
+android.os.ServiceManager
+android.os.storage.StorageManager
+android.os.StrictMode
+android.os.Trace
+android.os.WorkSource
+android.os.WorkSource$WorkChain
+android.permission.PermissionManager
+android.provider.FontsContract
+android.provider.Settings$SettingNotFoundException
+android.renderscript.RenderScriptCacheDir
+android.security.IKeyChainService
+android.security.keystore.AndroidKeyStoreProvider
+android.security.net.config.ApplicationConfig
+android.security.net.config.SystemCertificateSource$NoPreloadHolder
+android.telecom.PhoneAccountHandle
+android.telephony.AnomalyReporter
+android.telephony.CellSignalStrengthCdma
+android.telephony.CellSignalStrengthGsm
+android.telephony.CellSignalStrengthLte
+android.telephony.CellSignalStrengthNr
+android.telephony.CellSignalStrengthTdscdma
+android.telephony.CellSignalStrengthWcdma
+android.telephony.DataSpecificRegistrationInfo
+android.telephony.emergency.EmergencyNumber
+android.telephony.ims.ImsMmTelManager$CapabilityCallback$CapabilityBinder
+android.telephony.ims.ImsMmTelManager$RegistrationCallback$RegistrationBinder
+android.telephony.ims.ImsReasonInfo
+android.telephony.ims.ProvisioningManager$Callback$CallbackBinder
+android.telephony.ModemActivityInfo
+android.telephony.ModemInfo
+android.telephony.NetworkRegistrationInfo
+android.telephony.NetworkService
+android.telephony.TelephonyManager
+android.telephony.VoiceSpecificRegistrationInfo
+android.text.format.DateFormat
+android.text.method.SingleLineTransformationMethod
+android.text.Selection$MemoryTextWatcher
+android.text.SpanWatcher
+android.text.style.AlignmentSpan
+android.text.style.CharacterStyle
+android.text.style.LeadingMarginSpan
+android.text.style.LineBackgroundSpan
+android.text.style.LineHeightSpan
+android.text.style.MetricAffectingSpan
+android.text.style.ReplacementSpan
+android.text.style.SuggestionSpan
+android.text.style.TabStopSpan
+android.text.TextUtils
+android.text.TextWatcher
+android.transition.ChangeClipBounds
+android.transition.ChangeImageTransform
+android.transition.ChangeTransform
+android.util.ArrayMap
+android.util.ArraySet
+android.util.DisplayMetrics
+android.util.EventLog
+android.util.Log
+android.util.Patterns
+android.view.AbsSavedState$1
+android.view.accessibility.AccessibilityManager
+android.view.accessibility.AccessibilityManager$AccessibilityServicesStateChangeListener
+android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
+android.view.accessibility.AccessibilityNodeIdManager
+android.view.autofill.AutofillManager
+android.view.autofill.Helper
+android.view.Choreographer
+android.view.inputmethod.InputMethodManager
+android.view.IWindowManager
+android.view.PointerIcon
+android.view.RemoteAnimationAdapter
+android.view.ThreadedRenderer
+android.view.View
+android.view.View$OnHoverListener
+android.view.ViewRootImpl
+android.view.ViewStub
+android.view.ViewStub$OnInflateListener
+android.view.ViewTreeObserver
+android.view.WindowManager$LayoutParams
+android.view.WindowManagerGlobal
+android.widget.ActionMenuPresenter$OverflowMenuButton
+android.widget.ActionMenuView
+android.widget.Button
+android.widget.CheckBox
+android.widget.FrameLayout
+android.widget.ImageButton
+android.widget.ImageView
+android.widget.LinearLayout
+android.widget.RelativeLayout
+android.widget.SeekBar
+android.widget.Space
+android.widget.TextView
+android.widget.Toolbar
+byte[]
+com.android.ims.ImsManager
+com.android.internal.logging.MetricsLogger
+com.android.internal.os.BackgroundThread
+com.android.internal.os.BinderInternal
+com.android.internal.os.BinderInternal$BinderProxyLimitListener
+com.android.internal.os.RuntimeInit
+com.android.internal.os.SomeArgs
+com.android.internal.policy.DecorView
+com.android.internal.statusbar.IStatusBarService
+com.android.internal.telephony.AppSmsManager
+com.android.internal.telephony.CallerInfoAsyncQuery$OnQueryCompleteListener
+com.android.internal.telephony.CarrierActionAgent
+com.android.internal.telephony.cat.CatService
+com.android.internal.telephony.cat.IconLoader
+com.android.internal.telephony.cat.RilMessageDecoder
+com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager
+com.android.internal.telephony.cdma.EriManager
+com.android.internal.telephony.CellularNetworkValidator
+com.android.internal.telephony.CommandException
+com.android.internal.telephony.dataconnection.DataConnection$DcActivatingState
+com.android.internal.telephony.dataconnection.DataConnection$DcActiveState
+com.android.internal.telephony.dataconnection.DataConnection$DcInactiveState
+com.android.internal.telephony.dataconnection.DataEnabledSettings
+com.android.internal.telephony.dataconnection.DcTracker
+com.android.internal.telephony.euicc.EuiccCardController
+com.android.internal.telephony.euicc.EuiccController
+com.android.internal.telephony.GsmAlphabet
+com.android.internal.telephony.GsmCdmaCallTracker
+com.android.internal.telephony.GsmCdmaPhone
+com.android.internal.telephony.IccPhoneBookInterfaceManager
+com.android.internal.telephony.IccSmsInterfaceManager
+com.android.internal.telephony.ims.ImsResolver
+com.android.internal.telephony.imsphone.ImsExternalCallTracker
+com.android.internal.telephony.imsphone.ImsPhone
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker
+com.android.internal.telephony.ims.RcsMessageStoreController
+com.android.internal.telephony.IntentBroadcaster
+com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
+com.android.internal.telephony.metrics.TelephonyMetrics
+com.android.internal.telephony.MultiSimSettingController
+com.android.internal.telephony.nano.CarrierIdProto$CarrierAttribute
+com.android.internal.telephony.nano.CarrierIdProto$CarrierId
+com.android.internal.telephony.nano.TelephonyProto$RilDataCall
+com.android.internal.telephony.nano.TelephonyProto$SmsSession$Event
+com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event$RilCall
+com.android.internal.telephony.NitzStateMachine
+com.android.internal.telephony.PhoneConfigurationManager
+com.android.internal.telephony.PhoneFactory
+com.android.internal.telephony.PhoneSwitcher
+com.android.internal.telephony.ProxyController
+com.android.internal.telephony.RadioConfig
+com.android.internal.telephony.RIL
+com.android.internal.telephony.RILRequest
+com.android.internal.telephony.RilWakelockInfo
+com.android.internal.telephony.ServiceStateTracker
+com.android.internal.telephony.SimActivationTracker
+com.android.internal.telephony.SmsApplication
+com.android.internal.telephony.SmsBroadcastUndelivered
+com.android.internal.telephony.SmsStorageMonitor
+com.android.internal.telephony.SmsUsageMonitor
+com.android.internal.telephony.SubscriptionController
+com.android.internal.telephony.SubscriptionInfoUpdater
+com.android.internal.telephony.TelephonyComponentFactory
+com.android.internal.telephony.TelephonyDevController
+com.android.internal.telephony.TelephonyTester
+com.android.internal.telephony.uicc.AdnRecordCache
+com.android.internal.telephony.uicc.UiccCardApplication
+com.android.internal.telephony.uicc.UiccController
+com.android.internal.telephony.uicc.UiccProfile
+com.android.internal.telephony.uicc.UiccStateChangedLauncher
+com.android.internal.telephony.uicc.UsimFileHandler
+com.android.internal.telephony.uicc.VoiceMailConstants
+com.android.internal.util.LatencyTracker
+com.android.internal.util.StateMachine$SmHandler
+com.android.okhttp.OkHttpClient
+com.android.okhttp.okio.AsyncTimeout
+com.android.okhttp.okio.SegmentPool
+com.android.phone.ecc.nano.ProtobufEccData$CountryInfo
+com.android.phone.ecc.nano.ProtobufEccData$EccInfo
+com.android.server.sip.SipWakeupTimer
+com.android.server.SystemConfig
+dalvik.system.BaseDexClassLoader
+dalvik.system.BlockGuard
+dalvik.system.CloseGuard
+dalvik.system.RuntimeHooks
+dalvik.system.SocketTagger
+java.io.BufferedReader
+java.lang.AssertionError
+java.lang.Boolean
+java.lang.Byte
+java.lang.Character
+java.lang.CharSequence
+java.lang.Class
+java.lang.IllegalAccessException
+java.lang.IllegalStateException
+java.lang.NoSuchMethodException
+java.lang.NullPointerException
+java.lang.Object
+java.lang.Object[]
+java.lang.ref.FinalizerReference
+java.lang.Runnable
+java.lang.SecurityException
+java.lang.Short
+java.lang.String[]
 java.lang.System
-java.net.Inet4Address
 java.lang.Thread
 java.lang.Throwable
-java.util.Collections
-javax.net.ssl.SSLContext
+java.lang.UnsatisfiedLinkError
+java.net.Inet6Address
+java.net.Socket
+java.net.SocketException
+java.nio.Bits
 java.nio.charset.Charset
+java.security.interfaces.RSAPrivateKey
 java.security.Provider
-javax.net.ssl.HttpsURLConnection
-javax.net.ssl.SSLSocketFactory
-java.util.TimeZone
+java.util.Collections
+java.util.concurrent.Executor
+java.util.GregorianCalendar
 java.util.Locale
-java.util.function.ToIntFunction
-sun.misc.FormattedFloatingDecimal
-java.util.stream.IntStream
-android.icu.util.TimeZone
-org.apache.harmony.luni.internal.util.TimezoneGetter
-dalvik.system.SocketTagger
-dalvik.system.CloseGuard
-java.lang.ref.FinalizerReference
-com.android.org.conscrypt.ct.CTLogStoreImpl
-com.android.org.conscrypt.SSLParametersImpl
-com.android.org.conscrypt.OpenSSLContextImpl
-com.android.org.conscrypt.SSLParametersImpl$AliasChooser
-com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
-com.android.org.conscrypt.NativeCrypto$SSLHandshakeCallbacks
-com.android.okhttp.OkHttpClient
-com.android.okhttp.okio.SegmentPool
-com.android.okhttp.okio.AsyncTimeout
-com.android.okhttp.HttpUrl
-android.os.StrictMode
-com.android.internal.os.BinderInternal
-android.os.storage.StorageManager
-android.os.Trace
-android.app.ActivityManager
-android.media.MediaRouter
-android.os.Environment
-android.view.ThreadedRenderer
-android.media.AudioManager
-android.app.AlarmManager
-android.telephony.TelephonyManager
-android.bluetooth.BluetoothAdapter
-com.android.internal.os.SomeArgs
-android.os.LocaleList
-android.view.WindowManagerGlobal
-android.media.AudioSystem
-android.ddm.DdmHandleAppName
-android.provider.Settings
-android.view.ViewRootImpl
-android.net.ConnectivityManager
-android.app.ActivityThread
-android.os.BaseBundle
-android.util.ArraySet
-android.view.View
-android.os.ServiceManager
-android.view.ViewTreeObserver
-android.hardware.input.InputManager
-android.os.UEventObserver
-android.app.NotificationManager
-android.hardware.display.DisplayManagerGlobal
-android.os.Binder
-android.app.AppOpsManager
-android.content.ContentResolver
-android.app.backup.BackupManager
-android.util.ArrayMap
-android.os.Looper
-android.graphics.Bitmap
-android.view.textservice.TextServicesManager
-com.android.internal.inputmethod.InputMethodUtils
-android.app.QueuedWork
-android.graphics.TemporaryBuffer
-android.widget.ImageView
-android.database.sqlite.SQLiteGlobal
-android.view.autofill.Helper
-android.text.method.SingleLineTransformationMethod
-com.android.internal.os.RuntimeInit
-android.view.inputmethod.InputMethodManager
-android.hardware.SystemSensorManager
-android.database.CursorWindow
-android.text.TextUtils
-android.media.PlayerBase
-android.app.ResourcesManager
-android.os.Message
-android.view.accessibility.AccessibilityManager
-android.app.Notification
-android.provider.ContactsContract$ContactNameColumns
-android.provider.CalendarContract$EventsColumns
-android.provider.CalendarContract$CalendarColumns
-android.provider.CalendarContract$SyncColumns
-android.provider.ContactsContract$ContactsColumns
-android.content.pm.PackageManager$OnPermissionsChangedListener
-android.net.IpConfiguration$ProxySettings
-android.provider.ContactsContract$ContactOptionsColumns
-android.net.wifi.SupplicantState
-android.provider.ContactsContract$ContactStatusColumns
-android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
-android.provider.CalendarContract$CalendarSyncColumns
-android.bluetooth.BluetoothProfile$ServiceListener
-android.provider.ContactsContract$ContactCounts
-android.net.IpConfiguration$IpAssignment
-android.text.TextWatcher
-android.graphics.Bitmap$CompressFormat
-android.location.LocationListener
-sun.security.jca.Providers
-java.lang.CharSequence
-android.icu.util.ULocale
-dalvik.system.BaseDexClassLoader
-android.icu.text.BreakIterator
+java.util.Locale$NoImagePreloadHolder
+java.util.Scanner
+java.util.Set
+java.util.TimeZone
+javax.net.SocketFactory
+javax.net.ssl.HttpsURLConnection
+javax.net.ssl.HttpsURLConnection$NoPreloadHolder
+javax.net.ssl.SSLContext
+javax.net.ssl.SSLSessionContext
+javax.net.ssl.SSLSocketFactory
+libcore.io.Libcore
+libcore.io.Memory
 libcore.net.NetworkSecurityPolicy
-android.icu.text.UnicodeSet
-com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
-android.app.SearchManager
-android.os.Build
-android.app.ContextImpl
-android.app.WallpaperManager
-android.security.net.config.ApplicationConfig
-android.animation.LayoutTransition
-android.widget.TextView
-com.android.internal.logging.MetricsLogger
-android.renderscript.RenderScriptCacheDir
-android.os.Process
-android.os.Handler
-android.content.Context
-android.graphics.drawable.AdaptiveIconDrawable
-android.provider.FontsContract
-android.text.style.SuggestionSpan
-android.graphics.drawable.VectorDrawable$VGroup
-android.view.ViewStub
-android.text.style.MetricAffectingSpan
-android.content.SharedPreferences$OnSharedPreferenceChangeListener
-android.app.PendingIntent
-android.text.SpanWatcher
-android.widget.FrameLayout
-android.net.NetworkRequest$Type
-android.net.NetworkInfo$State
-android.graphics.drawable.GradientDrawable
-android.text.style.AlignmentSpan
-android.widget.LinearLayout
-android.text.style.CharacterStyle
-android.view.View$OnApplyWindowInsetsListener
-android.view.MenuItem
-android.text.style.ReplacementSpan
-android.graphics.drawable.Icon
-android.widget.Button
+libcore.timezone.TimeZoneFinder
+org.apache.http.params.HttpParams
+sun.misc.Cleaner
+sun.nio.ch.FileChannelImpl
+sun.nio.ch.FileChannelImpl$Unmapper
+sun.nio.fs.UnixChannelFactory
+sun.security.jca.Providers
diff --git a/config/hiddenapi-greylist-max-p.txt b/config/hiddenapi-greylist-max-p.txt
index 141e8e6..25d45b0 100644
--- a/config/hiddenapi-greylist-max-p.txt
+++ b/config/hiddenapi-greylist-max-p.txt
@@ -70,6 +70,8 @@
 Lcom/android/internal/R$styleable;->Searchable:[I
 Lcom/android/internal/R$styleable;->SearchableActionKey:[I
 Lcom/android/internal/telephony/IPhoneSubInfo$Stub;-><init>()V
+Lcom/android/internal/telephony/ITelephony;->getDataActivity()I
+Lcom/android/internal/telephony/ITelephony;->getDataState()I
 Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallForwardingChanged(Z)V
 Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCellLocation(Landroid/os/Bundle;)V
 Lcom/android/internal/telephony/ITelephonyRegistry;->notifyDataActivity(I)V
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 10f25ea..c30a6f4 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -581,6 +581,7 @@
 Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager;
 Landroid/service/dreams/IDreamManager;->getDreamComponents()[Landroid/content/ComponentName;
 Landroid/service/euicc/IEuiccService$Stub;-><init>()V
+Landroid/service/media/IMediaBrowserServiceCallbacks$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/media/IMediaBrowserServiceCallbacks;
 Landroid/service/notification/INotificationListener$Stub;-><init>()V
 Landroid/service/persistentdata/IPersistentDataBlockService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/persistentdata/IPersistentDataBlockService;
 Landroid/service/vr/IVrManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/vr/IVrManager;
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 91cb47b..03e3b82 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -1105,7 +1105,6 @@
 android.database.sqlite.SQLiteDatabaseConfiguration
 android.database.sqlite.SQLiteDatabaseCorruptException
 android.database.sqlite.SQLiteDatabaseLockedException
-android.database.sqlite.SQLiteDebug$Consts
 android.database.sqlite.SQLiteDebug$DbStats
 android.database.sqlite.SQLiteDebug$PagerStats
 android.database.sqlite.SQLiteDebug
@@ -2697,6 +2696,7 @@
 android.os.-$$Lambda$Trace$2zLZ-Lc2kAXsVjw_nLYeNhqmGq0
 android.os.-$$Lambda$q1UvBdLgHRZVzc68BxdksTmbuCw
 android.os.AsyncResult
+android.os.AsyncTask
 android.os.AsyncTask$1
 android.os.AsyncTask$2
 android.os.AsyncTask$3
diff --git a/config/preloaded-classes-blacklist b/config/preloaded-classes-blacklist
index b5f9950..f05edee 100644
--- a/config/preloaded-classes-blacklist
+++ b/config/preloaded-classes-blacklist
@@ -1,6 +1,5 @@
 android.content.AsyncTaskLoader$LoadTask
 android.net.ConnectivityThread$Singleton
-android.os.AsyncTask
 android.os.FileObserver
 android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
 android.widget.Magnifier
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index cebe6e12..4aafa53 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -644,6 +644,32 @@
         }
     }
 
+    @Override
+    public Context createDisplayContext(Display display) {
+        final Context context = super.createDisplayContext(display);
+        final int displayId = display.getDisplayId();
+        setDefaultTokenInternal(context, displayId);
+        return context;
+    }
+
+    private void setDefaultTokenInternal(Context context, int displayId) {
+        final WindowManagerImpl wm = (WindowManagerImpl) context.getSystemService(WINDOW_SERVICE);
+        final IAccessibilityServiceConnection connection =
+                AccessibilityInteractionClient.getInstance().getConnection(mConnectionId);
+        IBinder token = null;
+        if (connection != null) {
+            synchronized (mLock) {
+                try {
+                    token = connection.getOverlayWindowToken(displayId);
+                } catch (RemoteException re) {
+                    Log.w(LOG_TAG, "Failed to get window token", re);
+                    re.rethrowFromSystemServer();
+                }
+            }
+            wm.setDefaultToken(token);
+        }
+    }
+
     /**
      * Returns the magnification controller, which may be used to query and
      * modify the state of display magnification.
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 8c38fe4..c8e0132 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -96,4 +96,6 @@
     void sendGesture(int sequence, in ParceledListSlice gestureSteps);
 
     boolean isFingerprintGestureDetectionAvailable();
+
+    IBinder getOverlayWindowToken(int displayid);
 }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index c08ed26..f655c89 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2330,7 +2330,7 @@
      * calling {@link VoiceInteractor#notifyDirectActionsChanged()}.
      *
      * <p>To get the voice interactor you need to call {@link #getVoiceInteractor()}
-     * which would return non <code>null<c/ode> only if there is an ongoing voice
+     * which would return non <code>null</code> only if there is an ongoing voice
      * interaction session. You an also detect when the voice interactor is no
      * longer valid because the voice interaction session that is backing is finished
      * by calling {@link VoiceInteractor#registerOnDestroyedCallback(Executor, Runnable)}.
@@ -2339,7 +2339,7 @@
      * before {@link #onStop()} is being called.
      *
      * <p>You should pass to the callback the currently supported direct actions which
-     * cannot be <code>null</code> or contain <code>null</null> elements.
+     * cannot be <code>null</code> or contain <code>null</code> elements.
      *
      * <p>You should return the action list as soon as possible to ensure the consumer,
      * for example the assistant, is as responsive as possible which would improve user
@@ -2682,12 +2682,6 @@
         enterPictureInPictureMode(new PictureInPictureParams.Builder().build());
     }
 
-    /** @removed */
-    @Deprecated
-    public boolean enterPictureInPictureMode(@NonNull PictureInPictureArgs args) {
-        return enterPictureInPictureMode(PictureInPictureArgs.convert(args));
-    }
-
     /**
      * Puts the activity in picture-in-picture mode if possible in the current system state. The
      * set parameters in {@param params} will be combined with the parameters from prior calls to
@@ -2724,12 +2718,6 @@
         }
     }
 
-    /** @removed */
-    @Deprecated
-    public void setPictureInPictureArgs(@NonNull PictureInPictureArgs args) {
-        setPictureInPictureParams(PictureInPictureArgs.convert(args));
-    }
-
     /**
      * Updates the properties of the picture-in-picture activity, or sets it to be used later when
      * {@link #enterPictureInPictureMode()} is called.
@@ -3681,7 +3669,7 @@
             ActivityTaskManager.getService().onBackPressedOnTaskRoot(mToken,
                     new IRequestFinishCallback.Stub() {
                         public void requestFinish() {
-                            finishAfterTransition();
+                            mHandler.post(() -> finishAfterTransition());
                         }
                     });
         } catch (RemoteException e) {
@@ -8566,8 +8554,7 @@
 
     /** Log a lifecycle event for current user id and component class. */
     private void writeEventLog(int event, String reason) {
-        EventLog.writeEvent(event, UserHandle.myUserId(), getComponentName().getClassName(),
-                reason);
+        EventLog.writeEvent(event, mIdent, getComponentName().getClassName(), reason);
     }
 
     class HostCallbacks extends FragmentHostCallback<Activity> {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 17368b7..cb99a3a 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -925,7 +925,7 @@
      * (which tends to consume a lot more RAM).
      * @hide
      */
-    @UnsupportedAppUsage
+    @TestApi
     static public boolean isHighEndGfx() {
         return !isLowRamDeviceStatic()
                 && !RoSystemProperties.CONFIG_AVOID_GFX_ACCEL
@@ -1822,7 +1822,8 @@
      * @hide
      */
     public static class TaskSnapshot implements Parcelable {
-
+        // Identifier of this snapshot
+        private final long mId;
         // Top activity in task when snapshot was taken
         private final ComponentName mTopActivityComponent;
         private final GraphicBuffer mSnapshot;
@@ -1841,10 +1842,12 @@
         // Must be one of the named color spaces, otherwise, always use SRGB color space.
         private final ColorSpace mColorSpace;
 
-        public TaskSnapshot(@NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
+        public TaskSnapshot(long id,
+                @NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
                 @NonNull ColorSpace colorSpace, int orientation, Rect contentInsets,
                 boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode,
                 int systemUiVisibility, boolean isTranslucent) {
+            mId = id;
             mTopActivityComponent = topActivityComponent;
             mSnapshot = snapshot;
             mColorSpace = colorSpace.getId() < 0
@@ -1860,6 +1863,7 @@
         }
 
         private TaskSnapshot(Parcel source) {
+            mId = source.readLong();
             mTopActivityComponent = ComponentName.readFromParcel(source);
             mSnapshot = source.readParcelable(null /* classLoader */);
             int colorSpaceId = source.readInt();
@@ -1877,6 +1881,13 @@
         }
 
         /**
+         * @return Identifier of this snapshot.
+         */
+        public long getId() {
+            return mId;
+        }
+
+        /**
          * @return The top activity component for the task at the point this snapshot was taken.
          */
         public ComponentName getTopActivityComponent() {
@@ -1970,6 +1981,7 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
+            dest.writeLong(mId);
             ComponentName.writeToParcel(mTopActivityComponent, dest);
             dest.writeParcelable(mSnapshot, 0);
             dest.writeInt(mColorSpace.getId());
@@ -1988,6 +2000,7 @@
             final int width = mSnapshot != null ? mSnapshot.getWidth() : 0;
             final int height = mSnapshot != null ? mSnapshot.getHeight() : 0;
             return "TaskSnapshot{"
+                    + " mId=" + mId
                     + " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
                     + " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
                     + " mColorSpace=" + mColorSpace.toString()
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 500a04f..69e7118 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -26,6 +26,7 @@
 import android.content.pm.ActivityPresentationInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.UserInfo;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.TransactionTooLargeException;
@@ -52,6 +53,12 @@
      */
     public abstract String checkContentProviderAccess(String authority, int userId);
 
+    /**
+     * Verify that calling UID has access to the given provider.
+     */
+    public abstract int checkContentProviderUriPermission(Uri uri, int userId,
+            int callingUid, int modeFlags);
+
     // Called by the power manager.
     public abstract void onWakefulnessChanged(int wakefulness);
 
@@ -168,20 +175,13 @@
     public abstract boolean isUidActive(int uid);
 
     /**
-     * Returns a list that contains the memory stats for currently running processes.
+     * Returns a list of running processes along with corresponding uids, pids and their oom score.
      *
      * Only processes managed by ActivityManagerService are included.
      */
     public abstract List<ProcessMemoryState> getMemoryStateForProcesses();
 
     /**
-     * Returns a list that contains the memory high-water mark for currently running processes.
-     *
-     * Only processes managed by ActivityManagerService are included.
-     */
-    public abstract List<ProcessMemoryHighWaterMark> getMemoryHighWaterMarkForProcesses();
-
-    /**
      * Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as
      * needed.
      */
@@ -278,7 +278,7 @@
             String resolvedType, boolean fgRequired, String callingPackage, int userId,
             boolean allowBackgroundActivityStarts) throws TransactionTooLargeException;
 
-    public abstract void disconnectActivityFromServices(Object connectionHolder);
+    public abstract void disconnectActivityFromServices(Object connectionHolder, Object conns);
     public abstract void cleanUpServices(int userId, ComponentName component, Intent baseIntent);
     public abstract ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId);
     public abstract void ensureBootCompleted();
@@ -286,7 +286,6 @@
     public abstract boolean isActivityStartsLoggingEnabled();
     /** Returns true if the background activity starts is enabled. */
     public abstract boolean isBackgroundActivityStartsEnabled();
-    public abstract boolean isPackageNameWhitelistedForBgActivityStarts(String packageName);
     public abstract void reportCurKeyguardUsageEvent(boolean keyguardShowing);
 
     /** Input dispatch timeout to a window, start the ANR process. */
@@ -319,7 +318,7 @@
 
     /** Starts a given process. */
     public abstract void startProcess(String processName, ApplicationInfo info,
-            boolean knownToBeDead, String hostingType, ComponentName hostingName);
+            boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);
 
     /** Starts up the starting activity process for debugging if needed.
      * This function needs to be called synchronously from WindowManager context so the caller
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1e982bc..2b4d4f8b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -113,6 +113,7 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.permission.IPermissionManager;
 import android.provider.BlockedNumberContract;
 import android.provider.CalendarContract;
 import android.provider.CallLog;
@@ -189,7 +190,6 @@
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
-import java.nio.file.Files;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -288,6 +288,7 @@
 
     @UnsupportedAppUsage
     static volatile IPackageManager sPackageManager;
+    private static volatile IPermissionManager sPermissionManager;
 
     @UnsupportedAppUsage
     final ApplicationThread mAppThread = new ApplicationThread();
@@ -790,6 +791,8 @@
         @Nullable
         ContentCaptureOptions contentCaptureOptions;
 
+        long[] disabledCompatChanges;
+
         @Override
         public String toString() {
             return "AppBindData{appInfo=" + appInfo + "}";
@@ -1002,7 +1005,7 @@
                 boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                 CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                 String buildSerial, AutofillOptions autofillOptions,
-                ContentCaptureOptions contentCaptureOptions) {
+                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {
             if (services != null) {
                 if (false) {
                     // Test code to make sure the app could see the passed-in services.
@@ -1050,6 +1053,7 @@
             data.buildSerial = buildSerial;
             data.autofillOptions = autofillOptions;
             data.contentCaptureOptions = contentCaptureOptions;
+            data.disabledCompatChanges = disabledCompatChanges;
             sendMessage(H.BIND_APPLICATION, data);
         }
 
@@ -1871,7 +1875,10 @@
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case CREATE_SERVICE:
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
+                    if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                                ("serviceCreate: " + String.valueOf(msg.obj)));
+                    }
                     handleCreateService((CreateServiceData)msg.obj);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
@@ -1887,7 +1894,10 @@
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case SERVICE_ARGS:
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
+                    if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                                ("serviceStart: " + String.valueOf(msg.obj)));
+                    }
                     handleServiceArgs((ServiceArgsData)msg.obj);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
@@ -2080,7 +2090,7 @@
         @Override
         public final boolean queueIdle() {
             doGcIfNeeded();
-            nPurgePendingResources();
+            purgePendingResources();
             return false;
         }
     }
@@ -2088,9 +2098,7 @@
     final class PurgeIdler implements MessageQueue.IdleHandler {
         @Override
         public boolean queueIdle() {
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "purgePendingResources");
-            nPurgePendingResources();
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+            purgePendingResources();
             return false;
         }
     }
@@ -2133,16 +2141,23 @@
     @UnsupportedAppUsage
     public static IPackageManager getPackageManager() {
         if (sPackageManager != null) {
-            //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
             return sPackageManager;
         }
-        IBinder b = ServiceManager.getService("package");
-        //Slog.v("PackageManager", "default service binder = " + b);
+        final IBinder b = ServiceManager.getService("package");
         sPackageManager = IPackageManager.Stub.asInterface(b);
-        //Slog.v("PackageManager", "default service = " + sPackageManager);
         return sPackageManager;
     }
 
+    /** Returns the permission manager */
+    public static IPermissionManager getPermissionManager() {
+        if (sPermissionManager != null) {
+            return sPermissionManager;
+        }
+        final IBinder b = ServiceManager.getService("permissionmgr");
+        sPermissionManager = IPermissionManager.Stub.asInterface(b);
+        return sPermissionManager;
+    }
+
     private Configuration mMainThreadConfig = new Configuration();
 
     Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
@@ -2460,13 +2475,17 @@
     }
 
     void doGcIfNeeded() {
+        doGcIfNeeded("bg");
+    }
+
+    void doGcIfNeeded(String reason) {
         mGcIdlerScheduled = false;
         final long now = SystemClock.uptimeMillis();
         //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
         //        + "m now=" + now);
         if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
             //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
-            BinderInternal.forceGc("bg");
+            BinderInternal.forceGc(reason);
         }
     }
 
@@ -5564,15 +5583,9 @@
 
     private void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
 
-        int configDiff = 0;
+        int configDiff;
+        boolean equivalent;
 
-        // This flag tracks whether the new configuration is fundamentally equivalent to the
-        // existing configuration. This is necessary to determine whether non-activity
-        // callbacks should receive notice when the only changes are related to non-public fields.
-        // We do not gate calling {@link #performActivityConfigurationChanged} based on this flag
-        // as that method uses the same check on the activity config override as well.
-        final boolean equivalent = config != null && mConfiguration != null
-                && (0 == mConfiguration.diffPublicOnly(config));
         final Theme systemTheme = getSystemContext().getTheme();
         final Theme systemUiTheme = getSystemUiContext().getTheme();
 
@@ -5590,6 +5603,13 @@
                 return;
             }
 
+            // This flag tracks whether the new configuration is fundamentally equivalent to the
+            // existing configuration. This is necessary to determine whether non-activity callbacks
+            // should receive notice when the only changes are related to non-public fields.
+            // We do not gate calling {@link #performActivityConfigurationChanged} based on this
+            // flag as that method uses the same check on the activity config override as well.
+            equivalent = mConfiguration != null && (0 == mConfiguration.diffPublicOnly(config));
+
             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
                     + config);
 
@@ -6005,6 +6025,16 @@
 
         WindowManagerGlobal.getInstance().trimMemory(level);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
+        if (SystemProperties.getInt("debug.am.run_gc_trim_level", Integer.MAX_VALUE) <= level) {
+            unscheduleGcIdler();
+            doGcIfNeeded("tm");
+        }
+        if (SystemProperties.getInt("debug.am.run_mallopt_trim_level", Integer.MAX_VALUE)
+                <= level) {
+            unschedulePurgeIdler();
+            purgePendingResources();
+        }
     }
 
     private void setupGraphicsSupport(Context context) {
@@ -6117,10 +6147,10 @@
         if (data.trackAllocation) {
             DdmVmInternal.enableRecentAllocations(true);
         }
-
         // Note when this process has started.
         Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
 
+        AppCompatCallbacks.install(data.disabledCompatChanges);
         mBoundApplication = data;
         mConfiguration = new Configuration(data.config);
         mCompatConfiguration = new Configuration(data.config);
@@ -6299,7 +6329,8 @@
         final InstrumentationInfo ii;
         if (data.instrumentationName != null) {
             try {
-                ii = new ApplicationPackageManager(null, getPackageManager())
+                ii = new ApplicationPackageManager(
+                        null, getPackageManager(), getPermissionManager())
                         .getInstrumentationInfo(data.instrumentationName, 0);
             } catch (PackageManager.NameNotFoundException e) {
                 throw new RuntimeException(
@@ -7274,24 +7305,6 @@
                 super.remove(path);
             }
         }
-
-        @Override
-        public void rename(String oldPath, String newPath) throws ErrnoException {
-            try {
-                super.rename(oldPath, newPath);
-            } catch (ErrnoException e) {
-                if (e.errno == OsConstants.EXDEV) {
-                    Log.v(TAG, "Recovering failed rename " + oldPath + " to " + newPath);
-                    try {
-                        Files.move(new File(oldPath).toPath(), new File(newPath).toPath());
-                    } catch (IOException e2) {
-                        throw e;
-                    }
-                } else {
-                    throw e;
-                }
-            }
-        }
     }
 
     public static void main(String[] args) {
@@ -7345,6 +7358,12 @@
         throw new RuntimeException("Main thread loop unexpectedly exited");
     }
 
+    private void purgePendingResources() {
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "purgePendingResources");
+        nPurgePendingResources();
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+    }
+
     // ------------------ Regular JNI ------------------------
     private native void nPurgePendingResources();
     private native void nDumpGraphicsInfo(FileDescriptor fd);
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 3bf659b..755f047 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -120,6 +120,7 @@
 
         mActivityTaskManager = ActivityTaskManager.getService();
         mSurfaceView = new SurfaceView(context);
+        mSurfaceView.setUseAlpha();
         mSurfaceView.setAlpha(0f);
         mSurfaceCallback = new SurfaceCallback();
         mSurfaceView.getHolder().addCallback(mSurfaceCallback);
diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java
new file mode 100644
index 0000000..17697db
--- /dev/null
+++ b/core/java/android/app/AppCompatCallbacks.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.compat.Compatibility;
+import android.os.Process;
+import android.util.Log;
+
+import java.util.Arrays;
+
+/**
+ * App process implementation of the {@link Compatibility} API.
+ *
+ * @hide
+ */
+public final class AppCompatCallbacks extends Compatibility.Callbacks {
+
+    private static final String TAG = "Compatibility";
+
+    private final long[] mDisabledChanges;
+
+    /**
+     * Install this class into the current process.
+     *
+     * @param disabledChanges Set of compatibility changes that are disabled for this process.
+     */
+    public static void install(long[] disabledChanges) {
+        Compatibility.setCallbacks(new AppCompatCallbacks(disabledChanges));
+    }
+
+    private AppCompatCallbacks(long[] disabledChanges) {
+        mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length);
+        Arrays.sort(mDisabledChanges);
+    }
+
+    protected void reportChange(long changeId) {
+        Log.d(TAG, "Compat change reported: " + changeId + "; UID " + Process.myUid());
+        // TODO log via StatsLog
+    }
+
+    protected boolean isChangeEnabled(long changeId) {
+        if (Arrays.binarySearch(mDisabledChanges, changeId) < 0) {
+            // Not present in the disabled array
+            reportChange(changeId);
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/core/java/android/app/AppGlobals.java b/core/java/android/app/AppGlobals.java
index 1f737b6..8312327 100644
--- a/core/java/android/app/AppGlobals.java
+++ b/core/java/android/app/AppGlobals.java
@@ -18,6 +18,7 @@
 
 import android.annotation.UnsupportedAppUsage;
 import android.content.pm.IPackageManager;
+import android.permission.IPermissionManager;
 
 /**
  * Special private access for certain globals related to a process.
@@ -52,6 +53,14 @@
     }
 
     /**
+     * Return the raw interface to the permission manager.
+     * @return The permission manager.
+     */
+    public static IPermissionManager getPermissionManager() {
+        return ActivityThread.getPermissionManager();
+    }
+
+    /**
      * Gets the value of an integer core setting.
      *
      * @param key The setting key.
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 2fdec3b..fb72e65 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -240,7 +240,8 @@
     public @interface UidState {}
 
     /**
-     * Uid state: The UID is a foreground persistent app.
+     * Uid state: The UID is a foreground persistent app. The lower the UID
+     * state the more important the UID is for the user.
      * @hide
      */
     @TestApi
@@ -248,7 +249,8 @@
     public static final int UID_STATE_PERSISTENT = 100;
 
     /**
-     * Uid state: The UID is top foreground app.
+     * Uid state: The UID is top foreground app. The lower the UID
+     * state the more important the UID is for the user.
      * @hide
      */
     @TestApi
@@ -257,6 +259,7 @@
 
     /**
      * Uid state: The UID is running a foreground service of location type.
+     * The lower the UID state the more important the UID is for the user.
      * @hide
      */
     @TestApi
@@ -264,7 +267,8 @@
     public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
 
     /**
-     * Uid state: The UID is running a foreground service.
+     * Uid state: The UID is running a foreground service. The lower the UID
+     * state the more important the UID is for the user.
      * @hide
      */
     @TestApi
@@ -279,7 +283,8 @@
     public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
 
     /**
-     * Uid state: The UID is a foreground app.
+     * Uid state: The UID is a foreground app. The lower the UID
+     * state the more important the UID is for the user.
      * @hide
      */
     @TestApi
@@ -287,7 +292,8 @@
     public static final int UID_STATE_FOREGROUND = 500;
 
     /**
-     * Uid state: The UID is a background app.
+     * Uid state: The UID is a background app. The lower the UID
+     * state the more important the UID is for the user.
      * @hide
      */
     @TestApi
@@ -295,7 +301,8 @@
     public static final int UID_STATE_BACKGROUND = 600;
 
     /**
-     * Uid state: The UID is a cached app.
+     * Uid state: The UID is a cached app. The lower the UID
+     * state the more important the UID is for the user.
      * @hide
      */
     @TestApi
@@ -2507,7 +2514,7 @@
         }
 
         /**
-         * @return The duration of the operation in milliseconds.
+         * @return The duration of the operation in milliseconds. The duration is in wall time.
          */
         public long getDuration() {
             return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
@@ -2515,7 +2522,7 @@
 
         /**
          * Return the duration in milliseconds the app accessed this op while
-         * in the foreground.
+         * in the foreground. The duration is in wall time.
          *
          * @param flags The flags which are any combination of
          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
@@ -2534,7 +2541,7 @@
 
         /**
          * Return the duration in milliseconds the app accessed this op while
-         * in the background.
+         * in the background. The duration is in wall time.
          *
          * @param flags The flags which are any combination of
          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
@@ -2553,7 +2560,7 @@
 
         /**
          * Return the duration in milliseconds the app accessed this op for
-         * a given range of UID states.
+         * a given range of UID states. The duration is in wall time.
          *
          * @param fromUidState The UID state for which to query. Could be one of
          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
@@ -3120,6 +3127,15 @@
             return mHistoricalUidOps.get(uid);
         }
 
+        /** @hide */
+        public void clearHistory(int uid, @NonNull String packageName) {
+            HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
+            historicalUidOps.clearHistory(packageName);
+            if (historicalUidOps.isEmpty()) {
+                mHistoricalUidOps.remove(uid);
+            }
+        }
+
         @Override
         public int describeContents() {
             return 0;
@@ -3397,6 +3413,12 @@
             return mHistoricalPackageOps.get(packageName);
         }
 
+        private void clearHistory(@NonNull String packageName) {
+            if (mHistoricalPackageOps != null) {
+                mHistoricalPackageOps.remove(packageName);
+            }
+        }
+
         @Override
         public int describeContents() {
             return 0;
@@ -3953,6 +3975,7 @@
 
         /**
          * Gets the total duration the app op was accessed (performed) in the foreground.
+         * The duration is in wall time.
          *
          * @param flags The flags which are any combination of
          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
@@ -3971,6 +3994,7 @@
 
         /**
          * Gets the total duration the app op was accessed (performed) in the background.
+         * The duration is in wall time.
          *
          * @param flags The flags which are any combination of
          * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
@@ -3989,7 +4013,7 @@
 
         /**
          * Gets the total duration the app op was accessed (performed) for a given
-         * range of UID states.
+         * range of UID states. The duration is in wall time.
          *
          * @param fromUidState The UID state from which to query. Could be one of
          * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 6761aab..0478ac8 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -34,7 +34,6 @@
 import android.content.pm.ChangedPackages;
 import android.content.pm.ComponentInfo;
 import android.content.pm.FeatureInfo;
-import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.IPackageManager;
@@ -82,6 +81,8 @@
 import android.os.UserManager;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.permission.IOnPermissionsChangeListener;
+import android.permission.IPermissionManager;
 import android.provider.Settings;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -320,30 +321,60 @@
     }
 
     @Override
-    public PermissionInfo getPermissionInfo(String name, int flags)
+    @SuppressWarnings("unchecked")
+    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
+        try {
+            final ParceledListSlice<PermissionGroupInfo> parceledList =
+                    mPermissionManager.getAllPermissionGroups(flags);
+            if (parceledList == null) {
+                return Collections.emptyList();
+            }
+            return parceledList.getList();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
+    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags)
             throws NameNotFoundException {
         try {
-            PermissionInfo pi = mPM.getPermissionInfo(name,
-                    mContext.getOpPackageName(), flags);
+            final PermissionGroupInfo pgi =
+                    mPermissionManager.getPermissionGroupInfo(groupName, flags);
+            if (pgi != null) {
+                return pgi;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        throw new NameNotFoundException(groupName);
+    }
+
+    @Override
+    public PermissionInfo getPermissionInfo(String permName, int flags)
+            throws NameNotFoundException {
+        try {
+            final String packageName = mContext.getOpPackageName();
+            final PermissionInfo pi =
+                    mPermissionManager.getPermissionInfo(permName, packageName, flags);
             if (pi != null) {
                 return pi;
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
-
-        throw new NameNotFoundException(name);
+        throw new NameNotFoundException(permName);
     }
 
     @Override
     @SuppressWarnings("unchecked")
-    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
+    public List<PermissionInfo> queryPermissionsByGroup(String groupName, int flags)
             throws NameNotFoundException {
         try {
-            ParceledListSlice<PermissionInfo> parceledList =
-                    mPM.queryPermissionsByGroup(group, flags);
+            final ParceledListSlice<PermissionInfo> parceledList =
+                    mPermissionManager.queryPermissionsByGroup(groupName, flags);
             if (parceledList != null) {
-                List<PermissionInfo> pi = parceledList.getList();
+                final List<PermissionInfo> pi = parceledList.getList();
                 if (pi != null) {
                     return pi;
                 }
@@ -351,8 +382,7 @@
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
-
-        throw new NameNotFoundException(group);
+        throw new NameNotFoundException(groupName);
     }
 
     @Override
@@ -368,36 +398,6 @@
     }
 
     @Override
-    public PermissionGroupInfo getPermissionGroupInfo(String name,
-            int flags) throws NameNotFoundException {
-        try {
-            PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
-            if (pgi != null) {
-                return pgi;
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
-        throw new NameNotFoundException(name);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
-        try {
-            ParceledListSlice<PermissionGroupInfo> parceledList =
-                    mPM.getAllPermissionGroups(flags);
-            if (parceledList == null) {
-                return Collections.emptyList();
-            }
-            return parceledList.getList();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    @Override
     public ApplicationInfo getApplicationInfo(String packageName, int flags)
             throws NameNotFoundException {
         return getApplicationInfoAsUser(packageName, flags, getUserId());
@@ -626,7 +626,7 @@
     @Override
     public int checkPermission(String permName, String pkgName) {
         try {
-            return mPM.checkPermission(permName, pkgName, getUserId());
+            return mPermissionManager.checkPermission(permName, pkgName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -635,7 +635,7 @@
     @Override
     public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
         try {
-            return mPM.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
+            return mPermissionManager.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -661,7 +661,7 @@
     @Override
     public boolean addPermission(PermissionInfo info) {
         try {
-            return mPM.addPermission(info);
+            return mPermissionManager.addPermission(info, false);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -670,7 +670,7 @@
     @Override
     public boolean addPermissionAsync(PermissionInfo info) {
         try {
-            return mPM.addPermissionAsync(info);
+            return mPermissionManager.addPermission(info, true);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -679,7 +679,7 @@
     @Override
     public void removePermission(String name) {
         try {
-            mPM.removePermission(name);
+            mPermissionManager.removePermission(name);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -707,46 +707,47 @@
     }
 
     @Override
-    public void revokeRuntimePermission(String packageName, String permissionName,
-            UserHandle user) {
+    public void revokeRuntimePermission(String packageName, String permName, UserHandle user) {
         if (DEBUG_TRACE_GRANTS
-                && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
+                && shouldTraceGrant(packageName, permName, user.getIdentifier())) {
             Log.i(TAG, "App " + mContext.getPackageName() + " is revoking "
-                    + permissionName + " for user " + user.getIdentifier(), new RuntimeException());
+                    + permName + " for user " + user.getIdentifier(), new RuntimeException());
         }
         try {
-            mPM.revokeRuntimePermission(packageName, permissionName, user.getIdentifier());
+            mPermissionManager
+                    .revokeRuntimePermission(packageName, permName, user.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     @Override
-    public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
+    public int getPermissionFlags(String permName, String packageName, UserHandle user) {
         try {
-            return mPM.getPermissionFlags(permissionName, packageName, user.getIdentifier());
+            return mPermissionManager
+                    .getPermissionFlags(permName, packageName, user.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     @Override
-    public void updatePermissionFlags(String permissionName, String packageName,
+    public void updatePermissionFlags(String permName, String packageName,
             int flagMask, int flagValues, UserHandle user) {
         if (DEBUG_TRACE_GRANTS
-                && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
+                && shouldTraceGrant(packageName, permName, user.getIdentifier())) {
             Log.i(TAG, "App " + mContext.getPackageName() + " is updating flags for "
-                    + permissionName + " for user " + user.getIdentifier() + ": "
+                    + permName + " for user " + user.getIdentifier() + ": "
                     + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", flagMask)
                     + " := " + DebugUtils.flagsToString(
                             PackageManager.class, "FLAG_PERMISSION_", flagValues),
                     new RuntimeException());
         }
         try {
-            mPM.updatePermissionFlags(permissionName, packageName, flagMask,
-                    flagValues,
-                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q,
-                    user.getIdentifier());
+            final boolean checkAdjustPolicyFlagPermission =
+                    mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q;
+            mPermissionManager.updatePermissionFlags(permName, packageName, flagMask,
+                    flagValues, checkAdjustPolicyFlagPermission, user.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -754,10 +755,11 @@
 
     @Override
     public @NonNull Set<String> getWhitelistedRestrictedPermissions(
-            @NonNull String packageName, @PermissionWhitelistFlags int whitelistFlags) {
+            @NonNull String packageName, @PermissionWhitelistFlags int flags) {
         try {
-            final List<String> whitelist = mPM.getWhitelistedRestrictedPermissions(
-                    packageName, whitelistFlags, getUserId());
+            final int userId = getUserId();
+            final List<String> whitelist = mPermissionManager
+                    .getWhitelistedRestrictedPermissions(packageName, flags, userId);
             if (whitelist != null) {
                 return new ArraySet<>(whitelist);
             }
@@ -769,10 +771,11 @@
 
     @Override
     public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
-            @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+            @NonNull String permName, @PermissionWhitelistFlags int flags) {
         try {
-            return mPM.addWhitelistedRestrictedPermission(packageName, permission,
-                    whitelistFlags, getUserId());
+            final int userId = getUserId();
+            return mPermissionManager
+                    .addWhitelistedRestrictedPermission(packageName, permName, flags, userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -780,10 +783,11 @@
 
     @Override
     public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
-            @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+            @NonNull String permName, @PermissionWhitelistFlags int flags) {
         try {
-            return mPM.removeWhitelistedRestrictedPermission(packageName, permission,
-                    whitelistFlags, getUserId());
+            final int userId = getUserId();
+            return mPermissionManager
+                    .removeWhitelistedRestrictedPermission(packageName, permName, flags, userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -791,10 +795,11 @@
 
     @Override
     @UnsupportedAppUsage
-    public boolean shouldShowRequestPermissionRationale(String permission) {
+    public boolean shouldShowRequestPermissionRationale(String permName) {
         try {
-            return mPM.shouldShowRequestPermissionRationale(permission,
-                    mContext.getPackageName(), getUserId());
+            final String packageName = mContext.getPackageName();
+            return mPermissionManager
+                    .shouldShowRequestPermissionRationale(permName, packageName, getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1050,6 +1055,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     @Override
     public boolean setInstantAppCookie(@NonNull byte[] cookie) {
         try {
@@ -1622,7 +1628,7 @@
             OnPermissionsChangeListenerDelegate delegate =
                     new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
             try {
-                mPM.addOnPermissionsChangeListener(delegate);
+                mPermissionManager.addOnPermissionsChangeListener(delegate);
                 mPermissionListeners.put(listener, delegate);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
@@ -1636,7 +1642,7 @@
             IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
             if (delegate != null) {
                 try {
-                    mPM.removeOnPermissionsChangeListener(delegate);
+                    mPermissionManager.removeOnPermissionsChangeListener(delegate);
                     mPermissionListeners.remove(listener);
                 } catch (RemoteException e) {
                     throw e.rethrowFromSystemServer();
@@ -1654,10 +1660,11 @@
     }
 
     @UnsupportedAppUsage
-    protected ApplicationPackageManager(ContextImpl context,
-                              IPackageManager pm) {
+    protected ApplicationPackageManager(ContextImpl context, IPackageManager pm,
+            IPermissionManager permissionManager) {
         mContext = context;
         mPM = pm;
+        mPermissionManager = permissionManager;
     }
 
     /**
@@ -2043,7 +2050,7 @@
     @Override
     public String getDefaultBrowserPackageNameAsUser(int userId) {
         try {
-            return mPM.getDefaultBrowserPackageName(userId);
+            return mPermissionManager.getDefaultBrowser(userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2052,7 +2059,7 @@
     @Override
     public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
         try {
-            return mPM.setDefaultBrowserPackageName(packageName, userId);
+            return mPermissionManager.setDefaultBrowser(packageName, userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2787,12 +2794,11 @@
     public Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo,
             @Nullable ApplicationInfo appInfo) {
         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
-            Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
-            if (bitmap == null) {
-                return UserIcons.getDefaultUserIcon(
-                        mContext.getResources(), itemInfo.showUserIcon, /* light= */ false);
-            }
-            return new BitmapDrawable(bitmap);
+            // Indicates itemInfo is for a different user (e.g. a profile's parent), so use a 
+            // generic user icon (users generally lack permission to view each other's actual icons)
+            int targetUserId = itemInfo.showUserIcon;
+            return UserIcons.getDefaultUserIcon(
+                    mContext.getResources(), targetUserId, /* light= */ false);
         }
         Drawable dr = null;
         if (itemInfo.packageName != null) {
@@ -2930,6 +2936,7 @@
     private final ContextImpl mContext;
     @UnsupportedAppUsage
     private final IPackageManager mPM;
+    private final IPermissionManager mPermissionManager;
 
     /** Assume locked until we hear otherwise */
     private volatile boolean mUserUnlocked = false;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 41a4fba..ef23d5e 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -68,6 +68,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
+import android.permission.IPermissionManager;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -297,10 +298,11 @@
             return mPackageManager;
         }
 
-        IPackageManager pm = ActivityThread.getPackageManager();
-        if (pm != null) {
+        final IPackageManager pm = ActivityThread.getPackageManager();
+        final IPermissionManager permissionManager = ActivityThread.getPermissionManager();
+        if (pm != null && permissionManager != null) {
             // Doesn't matter if we make more than one instance.
-            return (mPackageManager = new ApplicationPackageManager(this, pm));
+            return (mPackageManager = new ApplicationPackageManager(this, pm, permissionManager));
         }
 
         return null;
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 26720fc..2957309 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -386,15 +386,6 @@
      */
     void resizePinnedStack(in Rect pinnedBounds, in Rect tempPinnedTaskBounds);
 
-    /**
-     * Updates override configuration applied to specific display.
-     * @param values Update values for display configuration. If null is passed it will request the
-     *               Window Manager to compute new config for the specified display.
-     * @param displayId Id of the display to apply the config to.
-     * @throws RemoteException
-     * @return Returns true if the configuration was updated.
-     */
-    boolean updateDisplayOverrideConfiguration(in Configuration values, int displayId);
     void dismissKeyguard(in IBinder token, in IKeyguardDismissCallback callback,
             in CharSequence message);
 
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 66c4383..cfa065b 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -73,7 +73,7 @@
             boolean restrictedBackupMode, boolean persistent, in Configuration config,
             in CompatibilityInfo compatInfo, in Map services,
             in Bundle coreSettings, in String buildSerial, in AutofillOptions autofillOptions,
-            in ContentCaptureOptions contentCaptureOptions);
+            in ContentCaptureOptions contentCaptureOptions, in long[] disabledCompatChanges);
     void runIsolatedEntryPoint(in String entryPoint, in String[] entryPointArgs);
     void scheduleExit();
     void scheduleServiceArgs(IBinder token, in ParceledListSlice args);
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index e57738f..ac8b604 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -53,7 +53,7 @@
     void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
             in Notification notification, int userId);
     @UnsupportedAppUsage
-    void cancelNotificationWithTag(String pkg, String tag, int id, int userId);
+    void cancelNotificationWithTag(String pkg, String opPkg, String tag, int id, int userId);
 
     void setShowBadge(String pkg, int uid, boolean showBadge);
     boolean canShowBadge(String pkg, int uid);
@@ -108,6 +108,8 @@
     ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int userId);
     boolean isPackagePaused(String pkg);
 
+    void silenceNotificationSound();
+
     // TODO: Remove this when callers have been migrated to the equivalent
     // INotificationListener method.
     @UnsupportedAppUsage
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 3f6880f..650147b 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -177,4 +177,12 @@
      * @param displayId the id of the display on which contents are drawn.
      */
     void onSingleTaskDisplayDrawn(int displayId);
+
+    /**
+     * Called when a task is reparented to a stack on a different display.
+     *
+     * @param taskId id of the task which was moved to a different display.
+     * @param newDisplayId id of the new display.
+     */
+    void onTaskDisplayChanged(int taskId, int newDisplayId);
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index efaf7c0..5aa1f8f 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3386,11 +3386,7 @@
          */
         private int mCachedContrastColor = COLOR_INVALID;
         private int mCachedContrastColorIsFor = COLOR_INVALID;
-        /**
-         * Caches a ambient version of {@link #mCachedAmbientColorIsFor}.
-         */
-        private int mCachedAmbientColor = COLOR_INVALID;
-        private int mCachedAmbientColorIsFor = COLOR_INVALID;
+
         /**
          * A neutral color color that can be used for icons.
          */
@@ -5445,22 +5441,9 @@
          */
         @UnsupportedAppUsage
         public RemoteViews makePublicContentView() {
-            return makePublicView(false /* ambient */);
-        }
-
-        /**
-         * Construct a RemoteViews for the display in public contexts like on the lockscreen.
-         *
-         * @hide
-         */
-        public RemoteViews makePublicAmbientNotification() {
-            return makePublicView(true /* ambient */);
-        }
-
-        private RemoteViews makePublicView(boolean ambient) {
             if (mN.publicVersion != null) {
                 final Builder builder = recoverBuilder(mContext, mN.publicVersion);
-                return ambient ? builder.makeAmbientNotification() : builder.createContentView();
+                return builder.createContentView();
             }
             Bundle savedBundle = mN.extras;
             Style style = mStyle;
@@ -8118,8 +8101,7 @@
          */
         @Override
         public RemoteViews makeHeadsUpContentView(boolean increasedHeight) {
-            RemoteViews expanded = makeMediaBigContentView();
-            return expanded != null ? expanded : makeMediaContentView();
+            return makeMediaContentView();
         }
 
         /** @hide */
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 69ec831..3effd11 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -15,8 +15,6 @@
  */
 package android.app;
 
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -86,6 +84,7 @@
     private static final String ATT_GROUP = "group";
     private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system";
     private static final String ATT_ALLOW_BUBBLE = "can_bubble";
+    private static final String ATT_ORIG_IMP = "orig_imp";
     private static final String DELIMITER = ",";
 
     /**
@@ -151,6 +150,7 @@
     private String mName;
     private String mDesc;
     private int mImportance = DEFAULT_IMPORTANCE;
+    private int mOriginalImportance = DEFAULT_IMPORTANCE;
     private boolean mBypassDnd;
     private int mLockscreenVisibility = DEFAULT_VISIBILITY;
     private Uri mSound = Settings.System.DEFAULT_NOTIFICATION_URI;
@@ -234,6 +234,7 @@
         mBlockableSystem = in.readBoolean();
         mAllowBubbles = in.readBoolean();
         mImportanceLockedByOEM = in.readBoolean();
+        mOriginalImportance = in.readInt();
     }
 
     @Override
@@ -288,6 +289,7 @@
         dest.writeBoolean(mBlockableSystem);
         dest.writeBoolean(mAllowBubbles);
         dest.writeBoolean(mImportanceLockedByOEM);
+        dest.writeInt(mOriginalImportance);
     }
 
     /**
@@ -307,6 +309,7 @@
     /**
      * @hide
      */
+    @TestApi
     public void setFgServiceShown(boolean shown) {
         mFgServiceShown = shown;
     }
@@ -314,6 +317,7 @@
     /**
      * @hide
      */
+    @TestApi
     public void setDeleted(boolean deleted) {
         mDeleted = deleted;
     }
@@ -322,6 +326,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @TestApi
     public void setBlockableSystem(boolean blockableSystem) {
         mBlockableSystem = blockableSystem;
     }
@@ -641,6 +646,7 @@
     /**
      * @hide
      */
+    @TestApi
     public boolean isBlockableSystem() {
         return mBlockableSystem;
     }
@@ -678,6 +684,22 @@
     }
 
     /**
+     * @hide
+     */
+    @TestApi
+    public int getOriginalImportance() {
+        return mOriginalImportance;
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public void setOriginalImportance(int importance) {
+        mOriginalImportance = importance;
+    }
+
+    /**
      * 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()
@@ -729,6 +751,7 @@
         setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false));
         setBlockableSystem(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false));
         setAllowBubbles(safeBool(parser, ATT_ALLOW_BUBBLE, DEFAULT_ALLOW_BUBBLE));
+        setOriginalImportance(safeInt(parser, ATT_ORIG_IMP, DEFAULT_IMPORTANCE));
     }
 
     @Nullable
@@ -850,6 +873,9 @@
         if (canBubble() != DEFAULT_ALLOW_BUBBLE) {
             out.attribute(null, ATT_ALLOW_BUBBLE, Boolean.toString(canBubble()));
         }
+        if (getOriginalImportance() != DEFAULT_IMPORTANCE) {
+            out.attribute(null, ATT_ORIG_IMP, Integer.toString(getOriginalImportance()));
+        }
 
         // mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of
         // truth and so aren't written to this xml file
@@ -896,6 +922,7 @@
         record.put(ATT_GROUP, getGroup());
         record.put(ATT_BLOCKABLE_SYSTEM, isBlockableSystem());
         record.put(ATT_ALLOW_BUBBLE, canBubble());
+        // TODO: original importance
         return record;
     }
 
@@ -1005,7 +1032,8 @@
                 && Objects.equals(getGroup(), that.getGroup())
                 && Objects.equals(getAudioAttributes(), that.getAudioAttributes())
                 && mImportanceLockedByOEM == that.mImportanceLockedByOEM
-                && mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp;
+                && mImportanceLockedDefaultApp == that.mImportanceLockedDefaultApp
+                && mOriginalImportance == that.mOriginalImportance;
     }
 
     @Override
@@ -1015,7 +1043,7 @@
                 getUserLockedFields(),
                 isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(),
                 getAudioAttributes(), isBlockableSystem(), mAllowBubbles,
-                mImportanceLockedByOEM, mImportanceLockedDefaultApp);
+                mImportanceLockedByOEM, mImportanceLockedDefaultApp, mOriginalImportance);
         result = 31 * result + Arrays.hashCode(mVibration);
         return result;
     }
@@ -1045,6 +1073,7 @@
                 + ", mAllowBubbles=" + mAllowBubbles
                 + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
                 + ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
+                + ", mOriginalImp=" + mOriginalImportance
                 + '}';
         pw.println(prefix + output);
     }
@@ -1073,6 +1102,7 @@
                 + ", mAllowBubbles=" + mAllowBubbles
                 + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
                 + ", mImportanceLockedDefaultApp=" + mImportanceLockedDefaultApp
+                + ", mOriginalImp=" + mOriginalImportance
                 + '}';
     }
 
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index dd39376..316cab8 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -171,6 +171,78 @@
             "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED";
 
     /**
+     * Intent that is broadcast when the status of an {@link AutomaticZenRule} has changed.
+     *
+     * <p>Use this to know whether you need to continue monitor to device state in order to
+     * provide up-to-date states (with {@link #setAutomaticZenRuleState(String, Condition)}) for
+     * this rule.</p>
+     *
+     * Input: nothing
+     * Output: {@link #EXTRA_AUTOMATIC_ZEN_RULE_ID}
+     * Output: {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS}
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED =
+            "android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED";
+
+    /**
+     * Integer extra for {@link #ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED} containing the state of
+     * the {@link AutomaticZenRule}.
+     *
+     * <p>
+     *     The value will be one of {@link #AUTOMATIC_RULE_STATUS_ENABLED},
+     *     {@link #AUTOMATIC_RULE_STATUS_DISABLED}, {@link #AUTOMATIC_RULE_STATUS_REMOVED},
+     *     {@link #AUTOMATIC_RULE_STATUS_UNKNOWN}.
+     * </p>
+     */
+    public static final String EXTRA_AUTOMATIC_ZEN_RULE_STATUS =
+            "android.app.extra.AUTOMATIC_ZEN_RULE_STATUS";
+
+    /**
+     * String extra for {@link #ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED} containing the id of the
+     * {@link AutomaticZenRule} (see {@link #addAutomaticZenRule(AutomaticZenRule)}) that has
+     * changed.
+     */
+    public static final String EXTRA_AUTOMATIC_ZEN_RULE_ID =
+            "android.app.extra.AUTOMATIC_ZEN_RULE_ID";
+
+    /** @hide */
+    @IntDef(prefix = { "AUTOMATIC_RULE_STATUS" }, value = {
+            AUTOMATIC_RULE_STATUS_ENABLED, AUTOMATIC_RULE_STATUS_DISABLED,
+            AUTOMATIC_RULE_STATUS_REMOVED, AUTOMATIC_RULE_STATUS_UNKNOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AutomaticZenRuleStatus {}
+
+    /**
+     * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the current status of the
+     * rule is unknown at your target sdk version, and you should continue to provide state changes
+     * via {@link #setAutomaticZenRuleState(String, Condition)}.
+     */
+    public static final int AUTOMATIC_RULE_STATUS_UNKNOWN = -1;
+
+    /**
+     * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule currently
+     * exists and is enabled. You should continue to provide state changes via
+     * {@link #setAutomaticZenRuleState(String, Condition)}.
+     */
+    public static final int AUTOMATIC_RULE_STATUS_ENABLED = 1;
+
+    /**
+     * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule currently
+     * exists but is disabled. You do not need to continue to provide state changes via
+     * {@link #setAutomaticZenRuleState(String, Condition)} until the rule is reenabled.
+     */
+    public static final int AUTOMATIC_RULE_STATUS_DISABLED = 2;
+
+    /**
+     * Constant value for {@link #EXTRA_AUTOMATIC_ZEN_RULE_STATUS} - the given rule has been
+     * deleted. Further calls to {@link #setAutomaticZenRuleState(String, Condition)} will be
+     * ignored.
+     */
+    public static final int AUTOMATIC_RULE_STATUS_REMOVED = 3;
+
+    /**
      * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
      * This broadcast is only sent to registered receivers.
      *
@@ -466,7 +538,7 @@
      * @param notification A {@link Notification} object describing what to
      *        show the user. Must not be null.
      */
-    public void notifyAsPackage(@NonNull String targetPackage, @NonNull String tag, int id,
+    public void notifyAsPackage(@NonNull String targetPackage, @Nullable String tag, int id,
             @NonNull Notification notification) {
         INotificationManager service = getService();
         String sender = mContext.getPackageName();
@@ -532,9 +604,13 @@
     }
 
     /**
-     * Cancel a previously shown notification.  If it's transient, the view
-     * will be hidden.  If it's persistent, it will be removed from the status
-     * bar.
+     * Cancels a previously posted notification.
+     *
+     *  <p>If the notification does not currently represent a
+     *  {@link Service#startForeground(int, Notification) foreground service}, it will be
+     *  removed from the UI and live
+     *  {@link android.service.notification.NotificationListenerService notification listeners}
+     *  will be informed so they can remove the notification from their UIs.</p>
      */
     public void cancel(int id)
     {
@@ -542,16 +618,49 @@
     }
 
     /**
-     * Cancel a previously shown notification.  If it's transient, the view
-     * will be hidden.  If it's persistent, it will be removed from the status
-     * bar.
+     * Cancels a previously posted notification.
+     *
+     *  <p>If the notification does not currently represent a
+     *  {@link Service#startForeground(int, Notification) foreground service}, it will be
+     *  removed from the UI and live
+     *  {@link android.service.notification.NotificationListenerService notification listeners}
+     *  will be informed so they can remove the notification from their UIs.</p>
      */
-    public void cancel(String tag, int id)
+    public void cancel(@Nullable String tag, int id)
     {
         cancelAsUser(tag, id, mContext.getUser());
     }
 
     /**
+     * Cancels a previously posted notification.
+     *
+     * <p>If the notification does not currently represent a
+     * {@link Service#startForeground(int, Notification) foreground service}, it will be
+     * removed from the UI and live
+     * {@link android.service.notification.NotificationListenerService notification listeners}
+     * will be informed so they can remove the notification from their UIs.</p>
+     *
+     * <p>This method may be used by {@link #getNotificationDelegate() a notification delegate} to
+     * cancel notifications that they have posted via {@link #notifyAsPackage(String, String, int,
+     * Notification)}.</p>
+     *
+     * @param targetPackage The package to cancel the notification as. If this package is not your
+     *                      package, you can only cancel notifications you posted with
+     *                      {@link #notifyAsPackage(String, String, int, Notification).
+     * @param tag A string identifier for this notification.  May be {@code null}.
+     * @param id An identifier for this notification.
+     */
+    public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
+        INotificationManager service = getService();
+        try {
+            service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
+                    tag, id, mContext.getUser().getIdentifier());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * @hide
      */
     @UnsupportedAppUsage
@@ -561,7 +670,8 @@
         String pkg = mContext.getPackageName();
         if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
         try {
-            service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
+            service.cancelNotificationWithTag(
+                    pkg, mContext.getOpPackageName(), tag, id, user.getIdentifier());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1095,6 +1205,25 @@
     }
 
     /**
+     * Silences the current notification sound, if ones currently playing.
+     * <p>
+     * It is intended to handle use-cases such as silencing a ringing call
+     * when the user presses the volume button during ringing.
+     * <p>
+     * If this method is called prior to when the notification begins playing, the sound will not be
+     * silenced.  As such it is not intended as a means to avoid playing of a sound.
+     * @hide
+     */
+    public void silenceNotificationSound() {
+        INotificationManager service = getService();
+        try {
+            service.silenceNotificationSound();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns whether notifications from this package are temporarily hidden. This
      * could be done because the package was marked as distracting to the user via
      * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the
diff --git a/core/java/android/app/PictureInPictureArgs.java b/core/java/android/app/PictureInPictureArgs.java
deleted file mode 100644
index 3ee5173..0000000
--- a/core/java/android/app/PictureInPictureArgs.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app;
-
-import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
-import android.graphics.Rect;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Rational;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** @removed */
-@Deprecated
-public final class PictureInPictureArgs implements Parcelable {
-
-    /**
-     * Builder class for {@link PictureInPictureArgs} objects.
-     */
-    public static class Builder {
-
-        @Nullable
-        private Rational mAspectRatio;
-
-        @Nullable
-        private List<RemoteAction> mUserActions;
-
-        @Nullable
-        private Rect mSourceRectHint;
-
-        /**
-         * Sets the aspect ratio.  This aspect ratio is defined as the desired width / height, and
-         * does not change upon device rotation.
-         *
-         * @param aspectRatio the new aspect ratio for the activity in picture-in-picture, must be
-         * between 2.39:1 and 1:2.39 (inclusive).
-         *
-         * @return this builder instance.
-         */
-        public Builder setAspectRatio(Rational aspectRatio) {
-            mAspectRatio = aspectRatio;
-            return this;
-        }
-
-        /**
-         * Sets the user actions.  If there are more than
-         * {@link Activity#getMaxNumPictureInPictureActions()} actions, then the input list
-         * will be truncated to that number.
-         *
-         * @param actions the new actions to show in the picture-in-picture menu.
-         *
-         * @return this builder instance.
-         *
-         * @see RemoteAction
-         */
-        public Builder setActions(List<RemoteAction> actions) {
-            if (mUserActions != null) {
-                mUserActions = null;
-            }
-            if (actions != null) {
-                mUserActions = new ArrayList<>(actions);
-            }
-            return this;
-        }
-
-        /**
-         * Sets the source bounds hint. These bounds are only used when an activity first enters
-         * picture-in-picture, and describe the bounds in window coordinates of activity entering
-         * picture-in-picture that will be visible following the transition. For the best effect,
-         * these bounds should also match the aspect ratio in the arguments.
-         *
-         * @param launchBounds window-coordinate bounds indicating the area of the activity that
-         * will still be visible following the transition into picture-in-picture (eg. the video
-         * view bounds in a video player)
-         *
-         * @return this builder instance.
-         */
-        public Builder setSourceRectHint(Rect launchBounds) {
-            if (launchBounds == null) {
-                mSourceRectHint = null;
-            } else {
-                mSourceRectHint = new Rect(launchBounds);
-            }
-            return this;
-        }
-
-        public PictureInPictureArgs build() {
-            PictureInPictureArgs args = new PictureInPictureArgs(mAspectRatio, mUserActions,
-                    mSourceRectHint);
-            return args;
-        }
-    }
-
-    /**
-     * The expected aspect ratio of the picture-in-picture.
-     */
-    @Nullable
-    private Rational mAspectRatio;
-
-    /**
-     * The set of actions that are associated with this activity when in picture-in-picture.
-     */
-    @Nullable
-    private List<RemoteAction> mUserActions;
-
-    /**
-     * The source bounds hint used when entering picture-in-picture, relative to the window bounds.
-     * We can use this internally for the transition into picture-in-picture to ensure that a
-     * particular source rect is visible throughout the whole transition.
-     */
-    @Nullable
-    private Rect mSourceRectHint;
-
-    /**
-     * The content insets that are used with the source hint rect for the transition into PiP where
-     * the insets are removed at the beginning of the transition.
-     */
-    @Nullable
-    private Rect mSourceRectHintInsets;
-
-    /**
-     * @hide
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public PictureInPictureArgs() {
-    }
-
-    /**
-     * @hide
-     */
-    @Deprecated
-    public PictureInPictureArgs(float aspectRatio, List<RemoteAction> actions) {
-        setAspectRatio(aspectRatio);
-        setActions(actions);
-    }
-
-    private PictureInPictureArgs(Parcel in) {
-        if (in.readInt() != 0) {
-            mAspectRatio = new Rational(in.readInt(), in.readInt());
-        }
-        if (in.readInt() != 0) {
-            mUserActions = new ArrayList<>();
-            in.readParcelableList(mUserActions, RemoteAction.class.getClassLoader());
-        }
-        if (in.readInt() != 0) {
-            mSourceRectHint = Rect.CREATOR.createFromParcel(in);
-        }
-    }
-
-    private PictureInPictureArgs(Rational aspectRatio, List<RemoteAction> actions,
-            Rect sourceRectHint) {
-        mAspectRatio = aspectRatio;
-        mUserActions = actions;
-        mSourceRectHint = sourceRectHint;
-    }
-
-    /**
-     * @hide
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public void setAspectRatio(float aspectRatio) {
-        // Temporary workaround
-        mAspectRatio = new Rational((int) (aspectRatio * 1000000000), 1000000000);
-    }
-
-    /**
-     * @hide
-     */
-    @Deprecated
-    @UnsupportedAppUsage
-    public void setActions(List<RemoteAction> actions) {
-        if (mUserActions != null) {
-            mUserActions = null;
-        }
-        if (actions != null) {
-            mUserActions = new ArrayList<>(actions);
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @Deprecated
-    public void setSourceRectHint(Rect launchBounds) {
-        if (launchBounds == null) {
-            mSourceRectHint = null;
-        } else {
-            mSourceRectHint = new Rect(launchBounds);
-        }
-    }
-
-    /**
-     * Copies the set parameters from the other picture-in-picture args.
-     * @hide
-     */
-    public void copyOnlySet(PictureInPictureArgs otherArgs) {
-        if (otherArgs.hasSetAspectRatio()) {
-            mAspectRatio = otherArgs.mAspectRatio;
-        }
-        if (otherArgs.hasSetActions()) {
-            mUserActions = otherArgs.mUserActions;
-        }
-        if (otherArgs.hasSourceBoundsHint()) {
-            mSourceRectHint = new Rect(otherArgs.getSourceRectHint());
-        }
-    }
-
-    /**
-     * @return the aspect ratio. If none is set, return 0.
-     * @hide
-     */
-    public float getAspectRatio() {
-        if (mAspectRatio != null) {
-            return mAspectRatio.floatValue();
-        }
-        return 0f;
-    }
-
-    /** {@hide} */
-    public Rational getAspectRatioRational() {
-        return mAspectRatio;
-    }
-
-    /**
-     * @return whether the aspect ratio is set.
-     * @hide
-     */
-    public boolean hasSetAspectRatio() {
-        return mAspectRatio != null;
-    }
-
-    /**
-     * @return the set of user actions.
-     * @hide
-     */
-    public List<RemoteAction> getActions() {
-        return mUserActions;
-    }
-
-    /**
-     * @return whether the user actions are set.
-     * @hide
-     */
-    public boolean hasSetActions() {
-        return mUserActions != null;
-    }
-
-    /**
-     * Truncates the set of actions to the given {@param size}.
-     * @hide
-     */
-    public void truncateActions(int size) {
-        if (hasSetActions()) {
-            mUserActions = mUserActions.subList(0, Math.min(mUserActions.size(), size));
-        }
-    }
-
-    /**
-     * Sets the insets to be used with the source rect hint bounds.
-     * @hide
-     */
-    @Deprecated
-    public void setSourceRectHintInsets(Rect insets) {
-        if (insets == null) {
-            mSourceRectHintInsets = null;
-        } else {
-            mSourceRectHintInsets = new Rect(insets);
-        }
-    }
-
-    /**
-     * @return the source rect hint
-     * @hide
-     */
-    public Rect getSourceRectHint() {
-        return mSourceRectHint;
-    }
-
-    /**
-     * @return the source rect hint insets.
-     * @hide
-     */
-    public Rect getSourceRectHintInsets() {
-        return mSourceRectHintInsets;
-    }
-
-    /**
-     * @return whether there are launch bounds set
-     * @hide
-     */
-    public boolean hasSourceBoundsHint() {
-        return mSourceRectHint != null && !mSourceRectHint.isEmpty();
-    }
-
-    /**
-     * @return whether there are source rect hint insets set
-     * @hide
-     */
-    public boolean hasSourceBoundsHintInsets() {
-        return mSourceRectHintInsets != null;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        if (mAspectRatio != null) {
-            out.writeInt(1);
-            out.writeInt(mAspectRatio.getNumerator());
-            out.writeInt(mAspectRatio.getDenominator());
-        } else {
-            out.writeInt(0);
-        }
-        if (mUserActions != null) {
-            out.writeInt(1);
-            out.writeParcelableList(mUserActions, 0);
-        } else {
-            out.writeInt(0);
-        }
-        if (mSourceRectHint != null) {
-            out.writeInt(1);
-            mSourceRectHint.writeToParcel(out, 0);
-        } else {
-            out.writeInt(0);
-        }
-    }
-
-    public static final @android.annotation.NonNull Creator<PictureInPictureArgs> CREATOR =
-            new Creator<PictureInPictureArgs>() {
-                public PictureInPictureArgs createFromParcel(Parcel in) {
-                    return new PictureInPictureArgs(in);
-                }
-                public PictureInPictureArgs[] newArray(int size) {
-                    return new PictureInPictureArgs[size];
-                }
-            };
-
-    public static PictureInPictureArgs convert(PictureInPictureParams params) {
-        return new PictureInPictureArgs(params.getAspectRatioRational(), params.getActions(),
-                params.getSourceRectHint());
-    }
-
-    public static PictureInPictureParams convert(PictureInPictureArgs args) {
-        return new PictureInPictureParams(args.getAspectRatioRational(), args.getActions(),
-                args.getSourceRectHint());
-    }
-}
diff --git a/core/java/android/app/ProcessMemoryHighWaterMark.java b/core/java/android/app/ProcessMemoryHighWaterMark.java
deleted file mode 100644
index d1cae94..0000000
--- a/core/java/android/app/ProcessMemoryHighWaterMark.java
+++ /dev/null
@@ -1,67 +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.app;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * The memory high-water mark value for a process.
- * {@hide}
- */
-public final class ProcessMemoryHighWaterMark implements Parcelable {
-    public final int uid;
-    public final String processName;
-    public final long rssHighWaterMarkInBytes;
-
-    public ProcessMemoryHighWaterMark(int uid, String processName, long rssHighWaterMarkInBytes) {
-        this.uid = uid;
-        this.processName = processName;
-        this.rssHighWaterMarkInBytes = rssHighWaterMarkInBytes;
-    }
-
-    private ProcessMemoryHighWaterMark(Parcel in) {
-        uid = in.readInt();
-        processName = in.readString();
-        rssHighWaterMarkInBytes = in.readLong();
-    }
-
-    public static final @android.annotation.NonNull Creator<ProcessMemoryHighWaterMark> CREATOR =
-            new Creator<ProcessMemoryHighWaterMark>() {
-                @Override
-                public ProcessMemoryHighWaterMark createFromParcel(Parcel in) {
-                    return new ProcessMemoryHighWaterMark(in);
-                }
-
-                @Override
-                public ProcessMemoryHighWaterMark[] newArray(int size) {
-                    return new ProcessMemoryHighWaterMark[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeInt(uid);
-        parcel.writeString(processName);
-        parcel.writeLong(rssHighWaterMarkInBytes);
-    }
-}
diff --git a/core/java/android/app/ProcessMemoryState.java b/core/java/android/app/ProcessMemoryState.java
index e28d79c..24914a6 100644
--- a/core/java/android/app/ProcessMemoryState.java
+++ b/core/java/android/app/ProcessMemoryState.java
@@ -20,44 +20,27 @@
 import android.os.Parcelable;
 
 /**
- * The memory stats for a process.
+ * State (oom score) for processes known to activity manager.
  * {@hide}
  */
 public final class ProcessMemoryState implements Parcelable {
     public final int uid;
+    public final int pid;
     public final String processName;
     public final int oomScore;
-    public final long pgfault;
-    public final long pgmajfault;
-    public final long rssInBytes;
-    public final long cacheInBytes;
-    public final long swapInBytes;
-    public final long startTimeNanos;
 
-    public ProcessMemoryState(int uid, String processName, int oomScore, long pgfault,
-                              long pgmajfault, long rssInBytes, long cacheInBytes,
-                              long swapInBytes, long startTimeNanos) {
+    public ProcessMemoryState(int uid, int pid, String processName, int oomScore) {
         this.uid = uid;
+        this.pid = pid;
         this.processName = processName;
         this.oomScore = oomScore;
-        this.pgfault = pgfault;
-        this.pgmajfault = pgmajfault;
-        this.rssInBytes = rssInBytes;
-        this.cacheInBytes = cacheInBytes;
-        this.swapInBytes = swapInBytes;
-        this.startTimeNanos = startTimeNanos;
     }
 
     private ProcessMemoryState(Parcel in) {
         uid = in.readInt();
+        pid = in.readInt();
         processName = in.readString();
         oomScore = in.readInt();
-        pgfault = in.readLong();
-        pgmajfault = in.readLong();
-        rssInBytes = in.readLong();
-        cacheInBytes = in.readLong();
-        swapInBytes = in.readLong();
-        startTimeNanos = in.readLong();
     }
 
     public static final @android.annotation.NonNull Creator<ProcessMemoryState> CREATOR = new Creator<ProcessMemoryState>() {
@@ -80,13 +63,8 @@
     @Override
     public void writeToParcel(Parcel parcel, int i) {
         parcel.writeInt(uid);
+        parcel.writeInt(pid);
         parcel.writeString(processName);
         parcel.writeInt(oomScore);
-        parcel.writeLong(pgfault);
-        parcel.writeLong(pgmajfault);
-        parcel.writeLong(rssInBytes);
-        parcel.writeLong(cacheInBytes);
-        parcel.writeLong(swapInBytes);
-        parcel.writeLong(startTimeNanos);
     }
 }
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index 0f8976f..9162626 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.content.SharedPreferences;
@@ -25,6 +26,7 @@
 import android.system.Os;
 import android.system.StructStat;
 import android.system.StructTimespec;
+import android.util.ArraySet;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
@@ -92,6 +94,10 @@
     private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =
             new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
 
+    @GuardedBy("mLock")
+    private final WeakHashMap<OnSharedPreferencesClearListener, Object> mClearListeners =
+            new WeakHashMap<>();
+
     /** Current memory state (always increasing) */
     @GuardedBy("this")
     private long mCurrentMemoryStateGeneration;
@@ -252,6 +258,28 @@
         }
     }
 
+    @Override
+    public void registerOnSharedPreferencesClearListener(
+            @NonNull OnSharedPreferencesClearListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null.");
+        }
+        synchronized (mLock) {
+            mClearListeners.put(listener, CONTENT);
+        }
+    }
+
+    @Override
+    public void unregisterOnSharedPreferencesClearListener(
+            @NonNull OnSharedPreferencesClearListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null.");
+        }
+        synchronized (mLock) {
+            mClearListeners.remove(listener);
+        }
+    }
+
     @GuardedBy("mLock")
     private void awaitLoadedLocked() {
         if (!mLoaded) {
@@ -361,7 +389,9 @@
     private static class MemoryCommitResult {
         final long memoryStateGeneration;
         @Nullable final List<String> keysModified;
+        @Nullable final Set<String> keysCleared;
         @Nullable final Set<OnSharedPreferenceChangeListener> listeners;
+        @Nullable final Set<OnSharedPreferencesClearListener> clearListeners;
         final Map<String, Object> mapToWriteToDisk;
         final CountDownLatch writtenToDiskLatch = new CountDownLatch(1);
 
@@ -371,10 +401,14 @@
 
         private MemoryCommitResult(long memoryStateGeneration, @Nullable List<String> keysModified,
                 @Nullable Set<OnSharedPreferenceChangeListener> listeners,
+                @Nullable Set<String> keysCleared,
+                @Nullable Set<OnSharedPreferencesClearListener> clearListeners,
                 Map<String, Object> mapToWriteToDisk) {
             this.memoryStateGeneration = memoryStateGeneration;
             this.keysModified = keysModified;
             this.listeners = listeners;
+            this.keysCleared = keysCleared;
+            this.clearListeners = clearListeners;
             this.mapToWriteToDisk = mapToWriteToDisk;
         }
 
@@ -492,13 +526,16 @@
             // SharedPreferences instance back, which has the
             // changes reflected in memory.
             notifyListeners(mcr);
+            notifyClearListeners(mcr);
         }
 
         // Returns true if any changes were made
         private MemoryCommitResult commitToMemory() {
             long memoryStateGeneration;
             List<String> keysModified = null;
+            Set<String> keysCleared = null;
             Set<OnSharedPreferenceChangeListener> listeners = null;
+            Set<OnSharedPreferencesClearListener> clearListeners = null;
             Map<String, Object> mapToWriteToDisk;
 
             synchronized (SharedPreferencesImpl.this.mLock) {
@@ -520,12 +557,20 @@
                     keysModified = new ArrayList<String>();
                     listeners = new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
                 }
+                boolean hasClearListeners = !mClearListeners.isEmpty();
+                if (hasClearListeners) {
+                    keysCleared = new ArraySet<>();
+                    clearListeners = new HashSet<>(mClearListeners.keySet());
+                }
 
                 synchronized (mEditorLock) {
                     boolean changesMade = false;
 
                     if (mClear) {
                         if (!mapToWriteToDisk.isEmpty()) {
+                            if (hasClearListeners) {
+                                keysCleared.addAll(mapToWriteToDisk.keySet());
+                            }
                             changesMade = true;
                             mapToWriteToDisk.clear();
                         }
@@ -569,7 +614,7 @@
                 }
             }
             return new MemoryCommitResult(memoryStateGeneration, keysModified, listeners,
-                    mapToWriteToDisk);
+                    keysCleared, clearListeners, mapToWriteToDisk);
         }
 
         @Override
@@ -596,6 +641,7 @@
                 }
             }
             notifyListeners(mcr);
+            notifyClearListeners(mcr);
             return mcr.writeToDiskResult;
         }
 
@@ -618,6 +664,24 @@
                 ActivityThread.sMainThreadHandler.post(() -> notifyListeners(mcr));
             }
         }
+
+        private void notifyClearListeners(final MemoryCommitResult mcr) {
+            if (mcr.clearListeners == null || mcr.keysCleared == null
+                    || mcr.keysCleared.isEmpty()) {
+                return;
+            }
+            if (Looper.myLooper() == Looper.getMainLooper()) {
+                for (OnSharedPreferencesClearListener listener : mcr.clearListeners) {
+                    if (listener != null) {
+                        listener.onSharedPreferencesClear(SharedPreferencesImpl.this,
+                                mcr.keysCleared);
+                    }
+                }
+            } else {
+                // Run this function on the main thread.
+                ActivityThread.sMainThreadHandler.post(() -> notifyClearListeners(mcr));
+            }
+        }
     }
 
     /**
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index d32b6b5..cfe2cf0 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -172,7 +172,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccCardManager;
 import android.telephony.euicc.EuiccManager;
-import android.telephony.ims.RcsManager;
+import android.telephony.ims.RcsMessageManager;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
@@ -614,11 +614,11 @@
                 return new SubscriptionManager(ctx.getOuterContext());
             }});
 
-        registerService(Context.TELEPHONY_RCS_SERVICE, RcsManager.class,
-                new CachedServiceFetcher<RcsManager>() {
+        registerService(Context.TELEPHONY_RCS_MESSAGE_SERVICE, RcsMessageManager.class,
+                new CachedServiceFetcher<RcsMessageManager>() {
                     @Override
-                    public RcsManager createService(ContextImpl ctx) {
-                        return new RcsManager(ctx.getOuterContext());
+                    public RcsMessageManager createService(ContextImpl ctx) {
+                        return new RcsMessageManager(ctx.getOuterContext());
                     }
                 });
 
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 36daf32..b63feb5 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -26,6 +26,7 @@
 /**
  * Classes interested in observing only a subset of changes using ITaskStackListener can extend
  * this class to avoid having to implement all the methods.
+ *
  * @hide
  */
 public abstract class TaskStackListener extends ITaskStackListener.Stub {
@@ -177,4 +178,8 @@
     @Override
     public void onSingleTaskDisplayDrawn(int displayId) throws RemoteException {
     }
+
+    @Override
+    public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException {
+    }
 }
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index dc07df8..4f8b60b 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -20,7 +20,6 @@
 import android.accessibilityservice.IAccessibilityServiceClient;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.pm.IPackageManager;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.hardware.input.InputManager;
@@ -31,6 +30,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.permission.IPermissionManager;
 import android.util.Log;
 import android.view.IWindowManager;
 import android.view.InputEvent;
@@ -69,8 +69,8 @@
     private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager.Stub
             .asInterface(ServiceManager.getService(Service.ACCESSIBILITY_SERVICE));
 
-    private final IPackageManager mPackageManager = IPackageManager.Stub
-            .asInterface(ServiceManager.getService("package"));
+    private final IPermissionManager mPermissionManager = IPermissionManager.Stub
+            .asInterface(ServiceManager.getService("permissionmgr"));
 
     private final IActivityManager mActivityManager = IActivityManager.Stub
             .asInterface(ServiceManager.getService("activity"));
@@ -273,7 +273,7 @@
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            mPackageManager.grantRuntimePermission(packageName, permission, userId);
+            mPermissionManager.grantRuntimePermission(packageName, permission, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -289,7 +289,7 @@
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            mPackageManager.revokeRuntimePermission(packageName, permission, userId);
+            mPermissionManager.revokeRuntimePermission(packageName, permission, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index affc8b9..c400316 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -338,6 +338,11 @@
         mDisplayWindowingMode = windowingMode;
     }
 
+    /** @hide */
+    @WindowingMode
+    public int getDisplayWindowingMode() {
+        return mDisplayWindowingMode;
+    }
 
     public void setActivityType(@ActivityType int activityType) {
         if (mActivityType == activityType) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 3f7b291..5624ba5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -16,6 +16,8 @@
 
 package android.app.admin;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.Manifest.permission;
 import android.annotation.CallbackExecutor;
 import android.annotation.ColorInt;
@@ -88,6 +90,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.Preconditions;
 import com.android.org.conscrypt.TrustedCertificateStore;
 
@@ -383,7 +386,8 @@
      * <li>{@link #EXTRA_PROVISIONING_ORGANIZATION_NAME}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_USE_MOBILE_DATA}, optional </li>
-     * <li>{@link #EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS}, optional</li>
+     * <li>{@link #EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS}, optional - when not used for
+     * cloud enrollment, NFC or QR provisioning</li>
      * </ul>
      *
      * @hide
@@ -423,7 +427,6 @@
      * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_LOGO_URI}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_MAIN_COLOR}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS}, optional</li>
      * </ul>
      *
      * <p>When device owner provisioning has completed, an intent of the type
@@ -1149,11 +1152,15 @@
      * A boolean extra indicating if the education screens from the provisioning flow should be
      * skipped. If unspecified, defaults to {@code false}.
      *
+     * <p>This extra can be set in the following ways:
+     * <ul>
+     * <li>By the admin app when performing the admin-integrated
+     * provisioning flow as a result of the {@link #ACTION_GET_PROVISIONING_MODE} activity</li>
+     * <li>With intent action {@link #ACTION_PROVISION_MANAGED_DEVICE}</li>
+     * </ul>
+     *
      * <p>If the education screens are skipped, it is the admin application's responsibility
      * to display its own user education screens.
-     *
-     * <p>It can be used when provisioning a fully managed device via
-     * {@link #ACTION_PROVISION_MANAGED_DEVICE}.
      */
     public static final String EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS =
             "android.app.extra.PROVISIONING_SKIP_EDUCATION_SCREENS";
@@ -2263,6 +2270,10 @@
      *     <li>{@link #PROVISIONING_MODE_MANAGED_PROFILE}</li>
      * </ul>
      *
+     * <p>If performing fully-managed device provisioning and the admin app desires to show its
+     * own education screens, the target activity can additionally return
+     * {@link #EXTRA_PROVISIONING_SKIP_EDUCATION_SCREENS} set to <code>true</code>.
+     *
      * <p>The target activity may also return the account that needs to be migrated from primary
      * user to managed profile in case of a profile owner provisioning in
      * {@link #EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE} as result.
@@ -6055,30 +6066,6 @@
 
     /**
      * @hide
-     * @deprecated Do not use
-     * @removed
-     */
-    @Deprecated
-    @SystemApi
-    @SuppressLint("Doclava125")
-    public @Nullable String getDeviceInitializerApp() {
-        return null;
-    }
-
-    /**
-     * @hide
-     * @deprecated Do not use
-     * @removed
-     */
-    @Deprecated
-    @SystemApi
-    @SuppressLint("Doclava125")
-    public @Nullable ComponentName getDeviceInitializerComponent() {
-        return null;
-    }
-
-    /**
-     * @hide
      * @deprecated Use #ACTION_SET_PROFILE_OWNER
      * Sets the given component as an active admin and registers the package as the profile
      * owner for this user. The package must already be installed and there shouldn't be
@@ -6392,6 +6379,7 @@
     /**
      * @hide
      */
+    @UnsupportedAppUsage
     public @Nullable ComponentName getProfileOwnerAsUser(final int userId) {
         if (mService != null) {
             try {
@@ -7382,60 +7370,6 @@
     }
 
     /**
-     * Called by a device owner to create a user with the specified name. The UserHandle returned
-     * by this method should not be persisted as user handles are recycled as users are removed and
-     * created. If you need to persist an identifier for this user, use
-     * {@link UserManager#getSerialNumberForUser}.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param name the user's name
-     * @see UserHandle
-     * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
-     *         user could not be created.
-     *
-     * @deprecated From {@link android.os.Build.VERSION_CODES#M}
-     * @removed From {@link android.os.Build.VERSION_CODES#N}
-     */
-    @Deprecated
-    public @Nullable UserHandle createUser(@NonNull ComponentName admin, String name) {
-        return null;
-    }
-
-    /**
-     * Called by a device owner to create a user with the specified name. The UserHandle returned
-     * by this method should not be persisted as user handles are recycled as users are removed and
-     * created. If you need to persist an identifier for this user, use
-     * {@link UserManager#getSerialNumberForUser}.  The new user will be started in the background
-     * immediately.
-     *
-     * <p> profileOwnerComponent is the {@link DeviceAdminReceiver} to be the profile owner as well
-     * as registered as an active admin on the new user.  The profile owner package will be
-     * installed on the new user if it already is installed on the device.
-     *
-     * <p>If the optionalInitializeData is not null, then the extras will be passed to the
-     * profileOwnerComponent when onEnable is called.
-     *
-     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
-     * @param name the user's name
-     * @param ownerName the human readable name of the organisation associated with this DPM.
-     * @param profileOwnerComponent The {@link DeviceAdminReceiver} that will be an active admin on
-     *      the user.
-     * @param adminExtras Extras that will be passed to onEnable of the admin receiver
-     *      on the new user.
-     * @see UserHandle
-     * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the
-     *         user could not be created.
-     *
-     * @deprecated From {@link android.os.Build.VERSION_CODES#M}
-     * @removed From {@link android.os.Build.VERSION_CODES#N}
-     */
-    @Deprecated
-    public @Nullable UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name,
-            String ownerName, @NonNull ComponentName profileOwnerComponent, Bundle adminExtras) {
-        return null;
-    }
-
-    /**
       * Flag used by {@link #createAndManageUser} to skip setup wizard after creating a new user.
       */
     public static final int SKIP_SETUP_WIZARD = 0x0001;
@@ -8809,6 +8743,11 @@
             mService.setPermissionGrantState(admin, mContext.getPackageName(), packageName,
                     permission, grantState, new RemoteCallback((b) -> result.complete(b != null)));
 
+            // Timeout
+            BackgroundThread.getHandler().sendMessageDelayed(
+                    obtainMessage(CompletableFuture::complete, result, false),
+                    20_000);
+
             return result.get();
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index a8f89df..8b3b3a2 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -481,25 +481,6 @@
     }
 
     /**
-     * @deprecated replaced by {@link #getEstimatedNetworkDownloadBytes()} and
-     *             {@link #getEstimatedNetworkUploadBytes()}.
-     * @removed
-     */
-    @Deprecated
-    public @BytesLong long getEstimatedNetworkBytes() {
-        if (networkDownloadBytes == NETWORK_BYTES_UNKNOWN
-                && networkUploadBytes == NETWORK_BYTES_UNKNOWN) {
-            return NETWORK_BYTES_UNKNOWN;
-        } else if (networkDownloadBytes == NETWORK_BYTES_UNKNOWN) {
-            return networkUploadBytes;
-        } else if (networkUploadBytes == NETWORK_BYTES_UNKNOWN) {
-            return networkDownloadBytes;
-        } else {
-            return networkDownloadBytes + networkUploadBytes;
-        }
-    }
-
-    /**
      * Return the estimated size of download traffic that will be performed by
      * this job, in bytes.
      *
@@ -1178,16 +1159,6 @@
         }
 
         /**
-         * @deprecated replaced by
-         *             {@link #setEstimatedNetworkBytes(long, long)}.
-         * @removed
-         */
-        @Deprecated
-        public Builder setEstimatedNetworkBytes(@BytesLong long networkBytes) {
-            return setEstimatedNetworkBytes(networkBytes, NETWORK_BYTES_UNKNOWN);
-        }
-
-        /**
          * Set the estimated size of network traffic that will be performed by
          * this job, in bytes.
          * <p>
@@ -1497,15 +1468,6 @@
         }
 
         /**
-         * @removed
-         * @deprecated replaced with {@link #setPrefetch(boolean)}
-         */
-        @Deprecated
-        public Builder setIsPrefetch(boolean isPrefetch) {
-            return setPrefetch(isPrefetch);
-        }
-
-        /**
          * Setting this to true indicates that this job is designed to prefetch
          * content that will make a material improvement to the experience of
          * the specific user of this device. For example, fetching top headlines
diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java
index a055ab4..c6631fa 100644
--- a/core/java/android/app/job/JobWorkItem.java
+++ b/core/java/android/app/job/JobWorkItem.java
@@ -55,15 +55,6 @@
     }
 
     /**
-     * @deprecated replaced by {@link #JobWorkItem(Intent, long, long)}
-     * @removed
-     */
-    @Deprecated
-    public JobWorkItem(Intent intent, @BytesLong long networkBytes) {
-        this(intent, networkBytes, NETWORK_BYTES_UNKNOWN);
-    }
-
-    /**
      * Create a new piece of work, which can be submitted to
      * {@link JobScheduler#enqueue JobScheduler.enqueue}.
      * <p>
@@ -90,25 +81,6 @@
     }
 
     /**
-     * @deprecated replaced by {@link #getEstimatedNetworkDownloadBytes()} and
-     *             {@link #getEstimatedNetworkUploadBytes()}.
-     * @removed
-     */
-    @Deprecated
-    public @BytesLong long getEstimatedNetworkBytes() {
-        if (mNetworkDownloadBytes == NETWORK_BYTES_UNKNOWN
-                && mNetworkUploadBytes == NETWORK_BYTES_UNKNOWN) {
-            return NETWORK_BYTES_UNKNOWN;
-        } else if (mNetworkDownloadBytes == NETWORK_BYTES_UNKNOWN) {
-            return mNetworkUploadBytes;
-        } else if (mNetworkUploadBytes == NETWORK_BYTES_UNKNOWN) {
-            return mNetworkDownloadBytes;
-        } else {
-            return mNetworkDownloadBytes + mNetworkUploadBytes;
-        }
-    }
-
-    /**
      * Return the estimated size of download traffic that will be performed by
      * this job, in bytes.
      *
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index 4b1796a..bb04a2e 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -53,7 +53,8 @@
  * the availability of roles. Instead, they should always query if the role is available using
  * {@link #isRoleAvailable(String)} before trying to do anything with it. Some predefined role names
  * are available as constants in this class, and a list of possibly available roles can be found in
- * the AndroidX Libraries.
+ * the <a href="{@docRoot}reference/androidx/core/role/package-summary.html">AndroidX Role
+ * library</a>.
  * <p>
  * There can be multiple applications qualifying for a role, but only a subset of them can become
  * role holders. To qualify for a role, an application must meet certain requirements, including
diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java
index 2d18838..bb775fc 100644
--- a/core/java/android/app/servertransaction/NewIntentItem.java
+++ b/core/java/android/app/servertransaction/NewIntentItem.java
@@ -17,6 +17,7 @@
 package android.app.servertransaction;
 
 import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
+import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
 
 import android.annotation.UnsupportedAppUsage;
 import android.app.ClientTransactionHandler;
@@ -38,10 +39,11 @@
 
     @UnsupportedAppUsage
     private List<ReferrerIntent> mIntents;
+    private boolean mResume;
 
     @Override
     public int getPostExecutionState() {
-        return ON_RESUME;
+        return mResume ? ON_RESUME : UNDEFINED;
     }
 
     @Override
@@ -58,12 +60,13 @@
     private NewIntentItem() {}
 
     /** Obtain an instance initialized with provided params. */
-    public static NewIntentItem obtain(List<ReferrerIntent> intents) {
+    public static NewIntentItem obtain(List<ReferrerIntent> intents, boolean resume) {
         NewIntentItem instance = ObjectPool.obtain(NewIntentItem.class);
         if (instance == null) {
             instance = new NewIntentItem();
         }
         instance.mIntents = intents;
+        instance.mResume = resume;
 
         return instance;
     }
@@ -71,6 +74,7 @@
     @Override
     public void recycle() {
         mIntents = null;
+        mResume = false;
         ObjectPool.recycle(this);
     }
 
@@ -80,11 +84,13 @@
     /** Write to Parcel. */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBoolean(mResume);
         dest.writeTypedList(mIntents, flags);
     }
 
     /** Read from Parcel. */
     private NewIntentItem(Parcel in) {
+        mResume = in.readBoolean();
         mIntents = in.createTypedArrayList(ReferrerIntent.CREATOR);
     }
 
@@ -108,18 +114,19 @@
             return false;
         }
         final NewIntentItem other = (NewIntentItem) o;
-        return Objects.equals(mIntents, other.mIntents);
+        return mResume == other.mResume && Objects.equals(mIntents, other.mIntents);
     }
 
     @Override
     public int hashCode() {
         int result = 17;
+        result = 31 * result + (mResume ? 1 : 0);
         result = 31 * result + mIntents.hashCode();
         return result;
     }
 
     @Override
     public String toString() {
-        return "NewIntentItem{intents=" + mIntents + "}";
+        return "NewIntentItem{intents=" + mIntents + ",resume=" + mResume + "}";
     }
 }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 31bbd16..39d63de 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1028,7 +1028,8 @@
      */
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     @AdapterState
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getState()} instead to determine "
+            + "whether you can use BLE & BT classic.")
     public int getLeState() {
         int state = BluetoothAdapter.STATE_OFF;
 
@@ -1484,7 +1485,8 @@
      * @return true if the scan mode was set, false otherwise
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #ACTION_REQUEST_DISCOVERABLE}, which "
+            + "shows UI that confirms the user wants to go into discoverable mode.")
     public boolean setScanMode(@ScanMode int mode, int duration) {
         if (getState() != STATE_ON) {
             return false;
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 388161d..c616044 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1051,7 +1051,7 @@
      * @return the Bluetooth alias, or null if no alias or there was a problem
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.")
     public String getAlias() {
         final IBluetooth service = sService;
         if (service == null) {
@@ -1100,7 +1100,7 @@
      * @see #getAlias()
      * @see #getName()
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getName()} instead.")
     public String getAliasName() {
         String name = getAlias();
         if (name == null) {
@@ -1975,7 +1975,8 @@
      * permissions.
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use "
+            + "{@link #createInsecureRfcommSocketToServiceRecord} instead.")
     public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
         if (!isBluetoothEnabled()) {
             Log.e(TAG, "Bluetooth is not enabled");
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 9862a63..672174f 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -280,6 +280,7 @@
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
      * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
      */
+    public static final int STATE_AUDIO_CONNECTED = 12;
 
     /**
      * Intent used to broadcast the headset's indicator status
@@ -322,8 +323,6 @@
     public static final String EXTRA_HF_INDICATORS_IND_VALUE =
             "android.bluetooth.headset.extra.HF_INDICATORS_IND_VALUE";
 
-    public static final int STATE_AUDIO_CONNECTED = 12;
-
     private static final int MESSAGE_HEADSET_SERVICE_CONNECTED = 100;
     private static final int MESSAGE_HEADSET_SERVICE_DISCONNECTED = 101;
 
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 60fb6fb..a812c32 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -22,6 +22,7 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Binder;
 import android.os.IBinder;
@@ -83,6 +84,7 @@
      *
      * @hide
      */
+    @UnsupportedAppUsage
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_ACTIVE_DEVICE_CHANGED =
             "android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED";
@@ -303,6 +305,7 @@
      * @return false on immediate error, true otherwise
      * @hide
      */
+    @UnsupportedAppUsage
     public boolean setActiveDevice(@Nullable BluetoothDevice device) {
         if (DBG) log("setActiveDevice(" + device + ")");
         final IBluetoothHearingAid service = getService();
@@ -331,6 +334,7 @@
      * is not active, it will be null on that position. Returns empty list on error.
      * @hide
      */
+    @UnsupportedAppUsage
     @RequiresPermission(Manifest.permission.BLUETOOTH)
     public List<BluetoothDevice> getActiveDevices() {
         if (VDBG) log("getActiveDevices()");
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index c06b837..3a23808 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -77,7 +77,8 @@
 
     private static final String TAG = "BluetoothServerSocket";
     private static final boolean DBG = false;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use public {@link BluetoothServerSocket} API "
+            + "instead.")
     /*package*/ final BluetoothSocket mSocket;
     private Handler mHandler;
     private int mMessage;
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 3a1e2f5..a6e3153 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -131,7 +131,7 @@
     private boolean mExcludeSdp = false; /* when true no SPP SDP record will be created */
     private boolean mAuthMitm = false;   /* when true Man-in-the-middle protection will be enabled*/
     private boolean mMin16DigitPin = false; /* Minimum 16 digit pin for sec mode 2 connections */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link BluetoothSocket} public API instead.")
     private ParcelFileDescriptor mPfd;
     @UnsupportedAppUsage
     private LocalSocket mSocket;
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 88e2c22..fdef2a1 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -892,12 +892,6 @@
         mItems.add(item);
     }
 
-    /** @removed use #addItem(ContentResolver, Item) instead */
-    @Deprecated
-    public void addItem(Item item, ContentResolver resolver) {
-        addItem(resolver, item);
-    }
-
     /**
      * Add a new Item to the overall ClipData container.
      * <p> Unlike {@link #addItem(Item)}, this method will update the list of available MIME types
diff --git a/core/java/android/content/ContentInterface.java b/core/java/android/content/ContentInterface.java
index d41d8d9..197de97 100644
--- a/core/java/android/content/ContentInterface.java
+++ b/core/java/android/content/ContentInterface.java
@@ -56,6 +56,9 @@
     public boolean refresh(@NonNull Uri uri, @Nullable Bundle args,
             @Nullable CancellationSignal cancellationSignal) throws RemoteException;
 
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+            throws RemoteException;
+
     public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
             throws RemoteException;
 
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 7cdd268..3c79991 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -28,6 +28,7 @@
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.app.AppOpsManager;
+import android.content.pm.PackageManager;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
 import android.content.res.AssetFileDescriptor;
@@ -582,6 +583,22 @@
             }
         }
 
+        @Override
+        public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+            uri = validateIncomingUri(uri);
+            uri = maybeGetUriWithoutUserId(uri);
+            Trace.traceBegin(TRACE_TAG_DATABASE, "checkUriPermission");
+            final String original = setCallingPackage(callingPkg);
+            try {
+                return mInterface.checkUriPermission(uri, uid, modeFlags);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            } finally {
+                setCallingPackage(original);
+                Trace.traceEnd(TRACE_TAG_DATABASE);
+            }
+        }
+
         private void enforceFilePermission(String callingPkg, Uri uri, String mode,
                 IBinder callerToken) throws FileNotFoundException, SecurityException {
             if (mode != null && mode.indexOf('w') != -1) {
@@ -1416,6 +1433,12 @@
         return false;
     }
 
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+        return PackageManager.PERMISSION_DENIED;
+    }
+
     /**
      * @hide
      * Implementation when a caller has performed an insert on the content
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 93bf518..8a4330e 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -307,6 +307,25 @@
         }
     }
 
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+            throws RemoteException {
+        Preconditions.checkNotNull(uri, "uri");
+
+        beforeRemote();
+        try {
+            return mContentProvider.checkUriPermission(mPackageName, uri, uid, modeFlags);
+        } catch (DeadObjectException e) {
+            if (!mStable) {
+                mContentResolver.unstableProviderDied(mContentProvider);
+            }
+            throw e;
+        } finally {
+            afterRemote();
+        }
+    }
+
     /** See {@link ContentProvider#insert ContentProvider.insert} */
     @Override
     public @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues initialValues)
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 9948338..cd735d4 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -363,6 +363,19 @@
                     reply.writeInt(out ? 0 : -1);
                     return true;
                 }
+
+                case CHECK_URI_PERMISSION_TRANSACTION: {
+                    data.enforceInterface(IContentProvider.descriptor);
+                    String callingPkg = data.readString();
+                    Uri uri = Uri.CREATOR.createFromParcel(data);
+                    int uid = data.readInt();
+                    int modeFlags = data.readInt();
+
+                    int out = checkUriPermission(callingPkg, uri, uid, modeFlags);
+                    reply.writeNoException();
+                    reply.writeInt(out);
+                    return true;
+                }
             }
         } catch (Exception e) {
             DatabaseUtils.writeExceptionToParcel(reply, e);
@@ -800,6 +813,29 @@
         }
     }
 
+    @Override
+    public int checkUriPermission(String callingPkg, Uri url, int uid, int modeFlags)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IContentProvider.descriptor);
+
+            data.writeString(callingPkg);
+            url.writeToParcel(data, 0);
+            data.writeInt(uid);
+            data.writeInt(modeFlags);
+
+            mRemote.transact(IContentProvider.CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
+
+            DatabaseUtils.readExceptionFromParcel(reply);
+            return reply.readInt();
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+
     @UnsupportedAppUsage
     private IBinder mRemote;
 }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0a1bc85..9c86359 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -31,6 +31,7 @@
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.UriGrantsManager;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
@@ -1146,6 +1147,24 @@
         }
     }
 
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+        Preconditions.checkNotNull(uri, "uri");
+
+        try {
+            if (mWrapped != null) return mWrapped.checkUriPermission(uri, uid, modeFlags);
+        } catch (RemoteException e) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+
+        try (ContentProviderClient client = acquireUnstableContentProviderClient(uri)) {
+            return client.checkUriPermission(uri, uid, modeFlags);
+        } catch (RemoteException e) {
+            return PackageManager.PERMISSION_DENIED;
+        }
+    }
+
     /**
      * Open a stream on to the content associated with a content URI.  If there
      * is no data associated with the URI, FileNotFoundException is thrown.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 941eda8..7a013f1 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -234,7 +234,9 @@
             BIND_ALLOW_OOM_MANAGEMENT,
             BIND_WAIVE_PRIORITY,
             BIND_IMPORTANT,
-            BIND_ADJUST_WITH_ACTIVITY
+            BIND_ADJUST_WITH_ACTIVITY,
+            BIND_NOT_PERCEPTIBLE,
+            BIND_INCLUDE_CAPABILITIES
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface BindServiceFlags {}
@@ -329,26 +331,25 @@
     public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
 
     /**
+     * Flag for {@link #bindService}: If binding from an app that is visible or user-perceptible,
+     * lower the target service's importance to below the perceptible level. This allows
+     * the system to (temporarily) expunge the bound process from memory to make room for more
+     * important user-perceptible processes.
+     */
+    public static final int BIND_NOT_PERCEPTIBLE = 0x00000100;
+
+    /**
      * Flag for {@link #bindService}: If binding from an app that has specific capabilities
      * due to its foreground state such as an activity or foreground service, then this flag will
      * allow the bound app to get the same capabilities, as long as it has the required permissions
      * as well.
      */
-    public static final int BIND_INCLUDE_CAPABILITIES = 0x00001000;
+    public static final int BIND_INCLUDE_CAPABILITIES = 0x000001000;
 
     /***********    Public flags above this line ***********/
     /***********    Hidden flags below this line ***********/
 
     /**
-     * Flag for {@link #bindService}: If binding from something better than perceptible,
-     * still set the adjust below perceptible. This would be used for bound services that can
-     * afford to be evicted when under extreme memory pressure, but should be restarted as soon
-     * as possible.
-     * @hide
-     */
-    public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x00040000;
-
-    /**
      * Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust
      * the scheduling policy for IMEs (and any other out-of-process user-visible components that
      * work closely with the top app) so that UI hosted in such services can have the same
@@ -473,7 +474,7 @@
      */
     public static final int BIND_REDUCTION_FLAGS =
             Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_WAIVE_PRIORITY
-                    | Context.BIND_ADJUST_BELOW_PERCEPTIBLE | Context.BIND_NOT_VISIBLE;
+                    | Context.BIND_NOT_PERCEPTIBLE | Context.BIND_NOT_VISIBLE;
 
     /** @hide */
     @IntDef(flag = true, prefix = { "RECEIVER_VISIBLE_" }, value = {
@@ -3066,7 +3067,7 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(trackingBug = 136728678)
     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
             Handler handler, UserHandle user) {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
@@ -4126,6 +4127,7 @@
      * @see #getSystemService(String)
      * @hide
      */
+    @TestApi
     @SystemApi
     public static final String PERMISSION_SERVICE = "permission";
 
@@ -4663,10 +4665,10 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve an
-     * {@link android.telephony.ims.RcsManager}.
+     * {@link android.telephony.ims.RcsMessageManager}.
      * @hide
      */
-    public static final String TELEPHONY_RCS_SERVICE = "ircs";
+    public static final String TELEPHONY_RCS_MESSAGE_SERVICE = "ircsmessage";
 
      /**
      * Use with {@link #getSystemService(String)} to retrieve an
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 0427c2f..fade0ab 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -16,6 +16,7 @@
 
 package android.content;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.content.res.AssetFileDescriptor;
@@ -82,6 +83,9 @@
     public Bundle call(String callingPkg, String authority, String method,
             @Nullable String arg, @Nullable Bundle extras) throws RemoteException;
 
+    public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags)
+            throws RemoteException;
+
     public ICancellationSignal createCancellationSignal() throws RemoteException;
 
     public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException;
@@ -116,4 +120,5 @@
     static final int CANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 24;
     static final int UNCANONICALIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 25;
     static final int REFRESH_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 26;
+    static final int CHECK_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 27;
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index be75f6e..2a17800 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3335,7 +3335,10 @@
      *
      * @deprecated Apps that redirect outgoing calls should use the
      * {@link android.telecom.CallRedirectionService} API.  Apps that perform call screening
-     * should use the {@link android.telecom.CallScreeningService} API.
+     * should use the {@link android.telecom.CallScreeningService} API.  Apps which need to be
+     * notified of basic call state should use
+     * {@link android.telephony.PhoneStateListener#onCallStateChanged(int, String)} to determine
+     * when a new outgoing call is placed.
      */
     @Deprecated
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/core/java/android/content/LoggingContentInterface.java b/core/java/android/content/LoggingContentInterface.java
index 83c0c91..1df1c4f 100644
--- a/core/java/android/content/LoggingContentInterface.java
+++ b/core/java/android/content/LoggingContentInterface.java
@@ -165,6 +165,19 @@
     }
 
     @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags)
+            throws RemoteException {
+        try (Logger l = new Logger("checkUriPermission", uri, uid, modeFlags)) {
+            try {
+                return l.setResult(delegate.checkUriPermission(uri, uid, modeFlags));
+            } catch (Exception res) {
+                l.setResult(res);
+                throw res;
+            }
+        }
+    }
+
+    @Override
     public @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues initialValues)
             throws RemoteException {
         try (Logger l = new Logger("insert", uri, initialValues)) {
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index 877dfee..9d87e25 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -16,6 +16,7 @@
 
 package android.content;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 
 import java.util.Map;
@@ -58,7 +59,9 @@
          * <p>This callback will be run on your main thread.
          *
          * <p><em>Note: This callback will not be triggered when preferences are cleared via
-         * {@link Editor#clear()}.</em>
+         * {@link Editor#clear()}. However, from {@link android.os.Build.VERSION_CODES#R Android R}
+         * onwards, you can use {@link OnSharedPreferencesClearListener} to register for
+         * {@link Editor#clear()} callbacks.</em>
          *
          * @param sharedPreferences The {@link SharedPreferences} that received
          *            the change.
@@ -67,7 +70,23 @@
          */
         void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);
     }
-    
+
+    /**
+     * Interface definition for a callback to be invoked when shared preferences are cleared.
+     */
+    public interface OnSharedPreferencesClearListener {
+        /**
+         * Called when shared preferences are cleared via {@link Editor#clear()}.
+         *
+         * <p>This callback will be run on your main thread.
+         *
+         * @param sharedPreferences The {@link SharedPreferences} that received the change.
+         * @param keys The set of keys that were cleared.
+         */
+        void onSharedPreferencesClear(@NonNull SharedPreferences sharedPreferences,
+                @NonNull Set<String> keys);
+    }
+
     /**
      * Interface used for modifying values in a {@link SharedPreferences}
      * object.  All changes you make in an editor are batched, and not copied
@@ -378,12 +397,43 @@
      * @see #unregisterOnSharedPreferenceChangeListener
      */
     void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);
-    
+
     /**
      * Unregisters a previous callback.
-     * 
+     *
      * @param listener The callback that should be unregistered.
      * @see #registerOnSharedPreferenceChangeListener
      */
     void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);
+
+    /**
+     * Registers a callback to be invoked when preferences are cleared via {@link Editor#clear()}.
+     *
+     * <p class="caution"><strong>Caution:</strong> The preference manager does
+     * not currently store a strong reference to the listener. You must store a
+     * strong reference to the listener, or it will be susceptible to garbage
+     * collection. We recommend you keep a reference to the listener in the
+     * instance data of an object that will exist as long as you need the
+     * listener.</p>
+     *
+     * @param listener The callback that will run.
+     * @see #unregisterOnSharedPreferencesClearListener
+     */
+    default void registerOnSharedPreferencesClearListener(
+            @NonNull OnSharedPreferencesClearListener listener) {
+        throw new UnsupportedOperationException(
+                "registerOnSharedPreferencesClearListener not implemented");
+    }
+
+    /**
+     * Unregisters a previous callback for {@link Editor#clear()}.
+     *
+     * @param listener The callback that should be unregistered.
+     * @see #registerOnSharedPreferencesClearListener
+     */
+    default void unregisterOnSharedPreferencesClearListener(
+            @NonNull OnSharedPreferencesClearListener listener) {
+        throw new UnsupportedOperationException(
+                "unregisterOnSharedPreferencesClearListener not implemented");
+    }
 }
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
index 1838bab..f39fc66 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.UnsupportedAppUsage;
 import android.annotation.UserIdInt;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -169,6 +170,7 @@
      * The state of this OverlayInfo as defined by the STATE_* constants in this class.
      * @hide
      */
+    @UnsupportedAppUsage
     public final @State int state;
 
     /**
diff --git a/core/java/android/content/om/TEST_MAPPING b/core/java/android/content/om/TEST_MAPPING
new file mode 100644
index 0000000..d35dfdb
--- /dev/null
+++ b/core/java/android/content/om/TEST_MAPPING
@@ -0,0 +1,26 @@
+{
+  "presubmit": [
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.om"
+        }
+      ]
+    },
+    {
+      "name": "OverlayDeviceTests"
+    },
+    {
+      "name": "OverlayHostTests"
+    },
+    {
+      "name": "CtsAppSecurityHostTestCases",
+      "options": [
+        {
+          "include-filter": "android.appsecurity.cts.OverlayHostTest"
+        }
+      ]
+    }
+  ]
+}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 9bc5f80..d0a61eb 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -614,10 +614,10 @@
 
     /**
      * Value for {@link #privateFlags}: whether this app is pre-installed on the
-     * google partition of the system image.
+     * system_ext partition of the system image.
      * @hide
      */
-    public static final int PRIVATE_FLAG_PRODUCT_SERVICES = 1 << 21;
+    public static final int PRIVATE_FLAG_SYSTEM_EXT = 1 << 21;
 
     /**
      * Indicates whether this package requires access to non-SDK APIs.
@@ -713,7 +713,7 @@
             PRIVATE_FLAG_USE_EMBEDDED_DEX,
             PRIVATE_FLAG_PRIVILEGED,
             PRIVATE_FLAG_PRODUCT,
-            PRIVATE_FLAG_PRODUCT_SERVICES,
+            PRIVATE_FLAG_SYSTEM_EXT,
             PRIVATE_FLAG_PROFILEABLE_BY_SHELL,
             PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
             PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY,
@@ -783,8 +783,7 @@
      */
     public float minAspectRatio;
 
-    /** @removed */
-    @Deprecated
+    /** @hide */
     public String volumeUuid;
 
     /**
@@ -2047,8 +2046,8 @@
     }
 
     /** @hide */
-    public boolean isProductServices() {
-        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+    public boolean isSystemExt() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     /** @hide */
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index 29612c2..10f0df7 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -79,10 +79,6 @@
      */
     public boolean directBootAware = false;
 
-    /** @removed */
-    @Deprecated
-    public boolean encryptionAware = false;
-
     public ComponentInfo() {
     }
 
@@ -94,7 +90,7 @@
         descriptionRes = orig.descriptionRes;
         enabled = orig.enabled;
         exported = orig.exported;
-        encryptionAware = directBootAware = orig.directBootAware;
+        directBootAware = orig.directBootAware;
     }
 
     /** @hide */
@@ -226,7 +222,7 @@
         descriptionRes = source.readInt();
         enabled = (source.readInt() != 0);
         exported = (source.readInt() != 0);
-        encryptionAware = directBootAware = (source.readInt() != 0);
+        directBootAware = (source.readInt() != 0);
     }
 
     /**
diff --git a/core/java/android/content/pm/IOnPermissionsChangeListener.aidl b/core/java/android/content/pm/IOnPermissionsChangeListener.aidl
deleted file mode 100644
index 7791b50..0000000
--- a/core/java/android/content/pm/IOnPermissionsChangeListener.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- */
-
-package android.content.pm;
-
-/**
- * Listener for changes in the permissions for installed packages.
- * {@hide}
- */
-oneway interface IOnPermissionsChangeListener {
-    void onPermissionsChanged(int uid);
-}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index a7eecd7..c6beee2 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -32,7 +32,6 @@
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.IPackageStatsObserver;
-import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IntentFilterVerificationInfo;
 import android.content.pm.InstrumentationInfo;
 import android.content.pm.KeySet;
@@ -78,15 +77,6 @@
     @UnsupportedAppUsage
     String[] canonicalToCurrentPackageNames(in String[] names);
 
-    PermissionInfo getPermissionInfo(String name, String packageName, int flags);
-
-    ParceledListSlice queryPermissionsByGroup(String group, int flags);
-
-    @UnsupportedAppUsage
-    PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
-
-    ParceledListSlice getAllPermissionGroups(int flags);
-
     @UnsupportedAppUsage
     ApplicationInfo getApplicationInfo(String packageName, int flags ,int userId);
 
@@ -105,43 +95,6 @@
     @UnsupportedAppUsage
     ProviderInfo getProviderInfo(in ComponentName className, int flags, int userId);
 
-    @UnsupportedAppUsage
-    int checkPermission(String permName, String pkgName, int userId);
-
-    int checkUidPermission(String permName, int uid);
-
-    @UnsupportedAppUsage
-    boolean addPermission(in PermissionInfo info);
-
-    @UnsupportedAppUsage
-    void removePermission(String name);
-
-    @UnsupportedAppUsage
-    void grantRuntimePermission(String packageName, String permissionName, int userId);
-
-    void revokeRuntimePermission(String packageName, String permissionName, int userId);
-
-    void resetRuntimePermissions();
-
-    int getPermissionFlags(String permissionName, String packageName, int userId);
-
-    void updatePermissionFlags(String permissionName, String packageName, int flagMask,
-            int flagValues, boolean checkAdjustPolicyFlagPermission, int userId);
-
-    void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);
-
-    List<String> getWhitelistedRestrictedPermissions(String packageName, int flags,
-            int userId);
-
-    boolean addWhitelistedRestrictedPermission(String packageName, String permission,
-            int whitelistFlags, int userId);
-
-    boolean removeWhitelistedRestrictedPermission(String packageName, String permission,
-            int whitelistFlags, int userId);
-
-    boolean shouldShowRequestPermissionRationale(String permissionName,
-            String packageName, int userId);
-
     boolean isProtectedBroadcast(String actionName);
 
     @UnsupportedAppUsage
@@ -171,9 +124,6 @@
     boolean isUidPrivileged(int uid);
 
     @UnsupportedAppUsage
-    String[] getAppOpPermissionPackages(String permissionName);
-
-    @UnsupportedAppUsage
     ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId);
 
     ResolveInfo findPersistentPreferredActivity(in Intent intent, int userId);
@@ -626,9 +576,6 @@
     int movePackage(in String packageName, in String volumeUuid);
     int movePrimaryStorage(in String volumeUuid);
 
-    @UnsupportedAppUsage
-    boolean addPermissionAsync(in PermissionInfo info);
-
     boolean setInstallLocation(int loc);
     @UnsupportedAppUsage
     int getInstallLocation();
@@ -645,18 +592,12 @@
     ParceledListSlice getIntentFilterVerifications(String packageName);
     ParceledListSlice getAllIntentFilters(String packageName);
 
-    boolean setDefaultBrowserPackageName(String packageName, int userId);
-    String getDefaultBrowserPackageName(int userId);
-
     VerifierDeviceIdentity getVerifierDeviceIdentity();
 
     boolean isFirstBoot();
     boolean isOnlyCoreApps();
     boolean isDeviceUpgrading();
 
-    void setPermissionEnforced(String permission, boolean enforced);
-    boolean isPermissionEnforced(String permission);
-
     /** Reflects current DeviceStorageMonitorService state */
     @UnsupportedAppUsage
     boolean isStorageLow();
@@ -680,19 +621,6 @@
     boolean isPackageSignedByKeySet(String packageName, in KeySet ks);
     boolean isPackageSignedByKeySetExactly(String packageName, in KeySet ks);
 
-    void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
-    void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
-    void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
-    void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId);
-    void grantDefaultPermissionsToEnabledTelephonyDataServices(
-            in String[] packageNames, int userId);
-    void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
-            in String[] packageNames, int userId);
-    void grantDefaultPermissionsToActiveLuiApp(in String packageName, int userId);
-    void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
-
-    boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId);
-
     @UnsupportedAppUsage
     String getPermissionControllerPackageName();
 
@@ -772,4 +700,41 @@
     void setRuntimePermissionsVersion(int version, int userId);
 
     void notifyPackagesReplacedReceived(in String[] packages);
+
+    //------------------------------------------------------------------------
+    //
+    // The following binder interfaces have been moved to IPermissionManager
+    //
+    //------------------------------------------------------------------------
+
+    //------------------------------------------------------------------------
+    // We need to keep these in IPackageManager for app compatibility
+    //------------------------------------------------------------------------
+    @UnsupportedAppUsage
+    String[] getAppOpPermissionPackages(String permissionName);
+
+    @UnsupportedAppUsage
+    PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
+
+    @UnsupportedAppUsage
+    boolean addPermission(in PermissionInfo info);
+
+    @UnsupportedAppUsage
+    boolean addPermissionAsync(in PermissionInfo info);
+
+    @UnsupportedAppUsage
+    void removePermission(String name);
+
+    @UnsupportedAppUsage
+    int checkPermission(String permName, String pkgName, int userId);
+
+    @UnsupportedAppUsage
+    void grantRuntimePermission(String packageName, String permissionName, int userId);
+
+    //------------------------------------------------------------------------
+    // We need to keep these in IPackageManager for convenience in splitting
+    // out the permission manager. This should be cleaned up, but, will require
+    // a large change that modifies many repos.
+    //------------------------------------------------------------------------
+    int checkUidPermission(String permName, int uid);
 }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3cecd7f..1099d8b 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1565,7 +1565,7 @@
         }
 
         /** {@hide} */
-        @SystemApi
+        @SystemApi @TestApi
         public void setRequestDowngrade(boolean requestDowngrade) {
             if (requestDowngrade) {
                 installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE;
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 081c5ad..d0ab8f7 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -159,7 +159,7 @@
     public Bundle metaData;
 
     /**
-     * If different of UserHandle.USER_NULL, The icon of this item will be the one of that user.
+     * If different of UserHandle.USER_NULL, The icon of this item will represent that user.
      * @hide
      */
     public int showUserIcon;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index cb939f0..4d8a0c4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -105,6 +105,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public interface OnPermissionsChangedListener {
 
         /**
@@ -727,6 +728,7 @@
             INSTALL_ENABLE_ROLLBACK,
             INSTALL_ALLOW_DOWNGRADE,
             INSTALL_STAGED,
+            INSTALL_DRY_RUN,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface InstallFlags {}
@@ -904,6 +906,14 @@
      */
     public static final int INSTALL_STAGED = 0x00200000;
 
+    /**
+     * Flag parameter for {@link #installPackage} to indicate that package should only be verified
+     * but not installed.
+     *
+     * @hide
+     */
+    public static final int INSTALL_DRY_RUN = 0x00800000;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
             DONT_KILL_APP
@@ -3561,7 +3571,7 @@
     /**
      * Retrieve all of the information we know about a particular permission.
      *
-     * @param permissionName The fully qualified name (i.e. com.google.permission.LOGIN)
+     * @param permName 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
@@ -3569,7 +3579,7 @@
      * @throws NameNotFoundException if a package with the given name cannot be
      *             found on the system.
      */
-    public abstract PermissionInfo getPermissionInfo(@NonNull String permissionName,
+    public abstract PermissionInfo getPermissionInfo(@NonNull String permName,
             @PermissionInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3610,7 +3620,7 @@
      * Retrieve all of the information we know about a particular group of
      * permissions.
      *
-     * @param permissionName The fully qualified name (i.e.
+     * @param permName 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.
@@ -3620,7 +3630,7 @@
      *             found on the system.
      */
     @NonNull
-    public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permissionName,
+    public abstract PermissionGroupInfo getPermissionGroupInfo(@NonNull String permName,
             @PermissionGroupInfoFlags int flags) throws NameNotFoundException;
 
     /**
@@ -3848,7 +3858,7 @@
      * Check whether a particular package has been granted a particular
      * permission.
      *
-     * @param permissionName The name of the permission you are checking for.
+     * @param permName 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
@@ -3860,7 +3870,7 @@
      */
     @CheckResult
     @PermissionResult
-    public abstract int checkPermission(@NonNull String permissionName,
+    public abstract int checkPermission(@NonNull String permName,
             @NonNull String packageName);
 
     /**
@@ -3870,13 +3880,13 @@
      * permissions, hence the only way for an app to get such a permission
      * is by a policy change.
      *
-     * @param permissionName The name of the permission you are checking for.
+     * @param permName 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 permissionName,
+    public abstract boolean isPermissionRevokedByPolicy(@NonNull String permName,
             @NonNull String packageName);
 
     /**
@@ -3939,14 +3949,14 @@
      * -- you are only allowed to remove permissions that you are allowed
      * to add.
      *
-     * @param permissionName The name of the permission to remove.
+     * @param permName 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(@NonNull String permissionName);
+    public abstract void removePermission(@NonNull String permName);
 
     /**
      * Permission flags set when granting or revoking a permission.
@@ -3988,7 +3998,7 @@
      * </p>
      *
      * @param packageName The package to which to grant the permission.
-     * @param permissionName The permission name to grant.
+     * @param permName The permission name to grant.
      * @param user The user for which to grant the permission.
      *
      * @see #revokeRuntimePermission(String, String, android.os.UserHandle)
@@ -3999,7 +4009,7 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
     public abstract void grantRuntimePermission(@NonNull String packageName,
-            @NonNull String permissionName, @NonNull UserHandle user);
+            @NonNull String permName, @NonNull UserHandle user);
 
     /**
      * Revoke a runtime permission that was previously granted by {@link
@@ -4015,7 +4025,7 @@
      * </p>
      *
      * @param packageName The package from which to revoke the permission.
-     * @param permissionName The permission name to revoke.
+     * @param permName The permission name to revoke.
      * @param user The user for which to revoke the permission.
      *
      * @see #grantRuntimePermission(String, String, android.os.UserHandle)
@@ -4026,12 +4036,12 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
     public abstract void revokeRuntimePermission(@NonNull String packageName,
-            @NonNull String permissionName, @NonNull UserHandle user);
+            @NonNull String permName, @NonNull UserHandle user);
 
     /**
      * Gets the state flags associated with a permission.
      *
-     * @param permissionName The permission for which to get the flags.
+     * @param permName The permission for which to get the flags.
      * @param packageName The package name for which to get the flags.
      * @param user The user for which to get permission flags.
      * @return The permission flags.
@@ -4046,14 +4056,14 @@
             android.Manifest.permission.GET_RUNTIME_PERMISSIONS
     })
     @PermissionFlags
-    public abstract int getPermissionFlags(@NonNull String permissionName,
+    public abstract int getPermissionFlags(@NonNull String permName,
             @NonNull String packageName, @NonNull UserHandle user);
 
     /**
      * Updates the flags associated with a permission by replacing the flags in
      * the specified mask with the provided flag values.
      *
-     * @param permissionName The permission for which to update the flags.
+     * @param permName The permission for which to update the flags.
      * @param packageName The package name for which to update the flags.
      * @param flagMask The flags which to replace.
      * @param flagValues The flags with which to replace.
@@ -4067,7 +4077,7 @@
             android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
             android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
     })
-    public abstract void updatePermissionFlags(@NonNull String permissionName,
+    public abstract void updatePermissionFlags(@NonNull String permName,
             @NonNull String packageName, @PermissionFlags int flagMask,
             @PermissionFlags int flagValues, @NonNull UserHandle user);
 
@@ -4154,7 +4164,7 @@
      * provided ones.
      *
      * @param packageName The app for which to get whitelisted permissions.
-     * @param permission The whitelisted permission to add.
+     * @param permName The whitelisted permission to add.
      * @param whitelistFlags The whitelists to which to add. Passing multiple flags
      * updates all specified whitelists.
      * @return Whether the permission was added to the whitelist.
@@ -4170,7 +4180,7 @@
     @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
             conditional = true)
     public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
-            @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+            @NonNull String permName, @PermissionWhitelistFlags int whitelistFlags) {
         return false;
     }
 
@@ -4208,7 +4218,7 @@
      * provided ones.
      *
      * @param packageName The app for which to get whitelisted permissions.
-     * @param permission The whitelisted permission to remove.
+     * @param permName The whitelisted permission to remove.
      * @param whitelistFlags The whitelists from which to remove. Passing multiple flags
      * updates all specified whitelists.
      * @return Whether the permission was removed from the whitelist.
@@ -4224,7 +4234,7 @@
     @RequiresPermission(value = Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS,
         conditional = true)
     public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
-        @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+            @NonNull String permName, @PermissionWhitelistFlags int whitelistFlags) {
         return false;
     }
 
@@ -4234,13 +4244,13 @@
      * which the permission is requested does not clearly communicate to the user
      * what would be the benefit from grating this permission.
      *
-     * @param permissionName A permission your app wants to request.
+     * @param permName A permission your app wants to request.
      * @return Whether you can show permission rationale UI.
      *
      * @hide
      */
     @UnsupportedAppUsage
-    public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permissionName);
+    public abstract boolean shouldShowRequestPermissionRationale(@NonNull String permName);
 
     /**
      * Returns an {@link android.content.Intent} suitable for passing to
@@ -6404,6 +6414,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
     public abstract void addOnPermissionsChangeListener(
             @NonNull OnPermissionsChangedListener listener);
@@ -6416,6 +6427,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
     public abstract void removeOnPermissionsChangeListener(
             @NonNull OnPermissionsChangedListener listener);
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 666508a..2f198ac 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -32,13 +32,10 @@
 import android.util.ArraySet;
 import android.util.SparseArray;
 
-import com.android.internal.util.function.TriFunction;
-
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
-import java.util.function.BiFunction;
 import java.util.function.Consumer;
 
 /**
@@ -86,165 +83,6 @@
         void onPackageRemoved(@NonNull String packageName, int uid);
     }
 
-    /** Interface to override permission checks via composition */
-    public interface CheckPermissionDelegate {
-        /**
-         * Allows overriding check permission behavior.
-         *
-         * @param permName The permission to check.
-         * @param pkgName The package for which to check.
-         * @param userId The user for which to check.
-         * @param superImpl The super implementation.
-         * @return The check permission result.
-         */
-        int checkPermission(String permName, String pkgName, int userId,
-                TriFunction<String, String, Integer, Integer> superImpl);
-
-        /**
-         * Allows overriding check UID permission behavior.
-         *
-         * @param permName The permission to check.
-         * @param uid The UID for which to check.
-         * @param superImpl The super implementation.
-         * @return The check permission result.
-         */
-        int checkUidPermission(String permName, int uid,
-                BiFunction<String, Integer, Integer> superImpl);
-    }
-
-    /**
-     * Provider for package names.
-     */
-    public interface PackagesProvider {
-
-        /**
-         * Gets the packages for a given user.
-         * @param userId The user id.
-         * @return The package names.
-         */
-        public String[] getPackages(int userId);
-    }
-
-    /**
-     * Provider for package names.
-     */
-    public interface SyncAdapterPackagesProvider {
-
-        /**
-         * Gets the sync adapter packages for given authority and user.
-         * @param authority The authority.
-         * @param userId The user id.
-         * @return The package names.
-         */
-        public String[] getPackages(String authority, int userId);
-    }
-
-    /**
-     * Provider for default browser
-     */
-    public interface DefaultBrowserProvider {
-
-        /**
-         * Get the package name of the default browser.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default browser, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultBrowser(@UserIdInt int userId);
-
-        /**
-         * Set the package name of the default browser.
-         *
-         * @param packageName package name of the default browser, or {@code null} to remove
-         * @param userId the user id
-         *
-         * @return whether the default browser was successfully set.
-         */
-        boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId);
-
-        /**
-         * Set the package name of the default browser asynchronously.
-         *
-         * @param packageName package name of the default browser, or {@code null} to remove
-         * @param userId the user id
-         */
-        void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId);
-    }
-
-    /**
-     * Provider for default dialer
-     */
-    public interface DefaultDialerProvider {
-
-        /**
-         * Get the package name of the default dialer.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default dialer, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultDialer(@UserIdInt int userId);
-    }
-
-    /**
-     * Provider for default home
-     */
-    public interface DefaultHomeProvider {
-
-        /**
-         * Get the package name of the default home.
-         *
-         * @param userId the user id
-         *
-         * @return the package name of the default home, or {@code null} if none
-         */
-        @Nullable
-        String getDefaultHome(@UserIdInt int userId);
-
-        /**
-         * Set the package name of the default home.
-         *
-         * @param packageName package name of the default home, or {@code null} to remove
-         * @param userId the user id
-         * @param callback the callback made after the default home as been updated
-         */
-        void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
-                @NonNull Consumer<Boolean> callback);
-    }
-
-    /**
-     * Sets the location provider packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setLocationPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Set the location extra packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract  void setLocationExtraPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the voice interaction packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the Use Open Wifi packages provider.
-     * @param provider The packages provider.
-     */
-    public abstract void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
-
-    /**
-     * Sets the sync adapter packages provider.
-     * @param provider The provider.
-     */
-    public abstract void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider);
-
     /**
      * Called when the package for the default SMS handler changed
      *
@@ -262,14 +100,6 @@
     public void onDefaultSimCallManagerAppChanged(String packageName, int userId) {}
 
     /**
-     * Requests granting of the default permissions to the current default Use Open Wifi app.
-     * @param packageName The default use open wifi package name.
-     * @param userId The user for which to grant the permissions.
-     */
-    public abstract void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName,
-            int userId);
-
-    /**
      * Sets a list of apps to keep in PM's internal data structures and as APKs even if no user has
      * currently installed it. The apps are not preloaded.
      * @param packageList List of package names to keep cached.
@@ -464,26 +294,6 @@
     public abstract boolean wasPackageEverLaunched(String packageName, int userId);
 
     /**
-     * Grants a runtime permission
-     * @param packageName The package name.
-     * @param name The name of the permission.
-     * @param userId The userId for which to grant the permission.
-     * @param overridePolicy If true, grant this permission even if it is fixed by policy.
-     */
-    public abstract void grantRuntimePermission(String packageName, String name, int userId,
-            boolean overridePolicy);
-
-    /**
-     * Revokes a runtime permission
-     * @param packageName The package name.
-     * @param name The name of the permission.
-     * @param userId The userId for which to revoke the permission.
-     * @param overridePolicy If true, revoke this permission even if it is fixed by policy.
-     */
-    public abstract void revokeRuntimePermission(String packageName, String name, int userId,
-            boolean overridePolicy);
-
-    /**
      * Retrieve the official name associated with a uid. This name is
      * guaranteed to never change, though it is possible for the underlying
      * uid to be changed. That is, if you are storing information about
@@ -668,6 +478,12 @@
     public abstract @Nullable PackageParser.Package getPackage(@NonNull String packageName);
 
     /**
+     * Returns a package for the given UID. If the UID is part of a shared user ID, one
+     * of the packages will be chosen to be returned.
+     */
+    public abstract @Nullable PackageParser.Package getPackage(int uid);
+
+    /**
      * Returns a list without a change observer.
      *
      * @see #getPackageList(PackageListObserver)
@@ -740,18 +556,15 @@
      * @see #canAccessInstantApps
      */
     public abstract boolean filterAppAccess(
-            @Nullable PackageParser.Package pkg, int callingUid, int userId);
+            @NonNull PackageParser.Package pkg, int callingUid, int userId);
 
-    /*
-     * NOTE: The following methods are temporary until permissions are extracted from
-     * the package manager into a component specifically for handling permissions.
+    /**
+     * Returns whether or not access to the application should be filtered.
+     *
+     * @see #filterAppAccess(android.content.pm.PackageParser.Package, int, int)
      */
-    /** Returns the flags for the given permission. */
-    public abstract @Nullable int getPermissionFlagsTEMP(@NonNull String permName,
-            @NonNull String packageName, int userId);
-    /** Updates the flags for the given permission. */
-    public abstract void updatePermissionFlagsTEMP(@NonNull String permName,
-            @NonNull String packageName, int flagMask, int flagValues, int userId);
+    public abstract boolean filterAppAccess(
+            @NonNull String packageName, int callingUid, int userId);
 
     /** Returns whether the given package was signed by the platform */
     public abstract boolean isPlatformSigned(String pkg);
@@ -782,20 +595,6 @@
             @PackageParser.SigningDetails.CertCapabilities int capability);
 
     /**
-     * Get the delegate to influence permission checking.
-     *
-     * @return The delegate instance or null to clear.
-     */
-    public abstract @Nullable CheckPermissionDelegate getCheckPermissionDelegate();
-
-    /**
-     * Set a delegate to influence permission checking.
-     *
-     * @param delegate A delegate instance or null to clear.
-     */
-    public abstract void setCheckPermissionDelegate(@Nullable CheckPermissionDelegate delegate);
-
-    /**
      * Get appIds of all available apps which specified android:sharedUserId in the manifest.
      *
      * @return a SparseArray mapping from appId to it's sharedUserId.
@@ -940,27 +739,6 @@
     public abstract String removeLegacyDefaultBrowserPackageName(int userId);
 
     /**
-     * Sets the default browser provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider);
-
-    /**
-     * Sets the default dialer provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider);
-
-    /**
-     * Sets the default home provider.
-     *
-     * @param provider the provider
-     */
-    public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);
-
-    /**
      * Returns {@code true} if given {@code packageName} is an apex package.
      */
     public abstract boolean isApexPackage(String packageName);
@@ -978,15 +756,6 @@
             IntentSender intentSender);
 
     /**
-     * Whether default permission grants have been performed for a user
-     * since the device booted.
-     *
-     * @param userId The user id.
-     * @return true if default permissions
-     */
-    public abstract boolean wereDefaultPermissionsGrantedSinceBoot(int userId);
-
-    /**
      * Get fingerprint of build that updated the runtime permissions for a user.
      *
      * @param userId The user to update
@@ -994,4 +763,44 @@
      */
     public abstract void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
             @UserIdInt int userId);
+
+    /**
+     * Migrates legacy obb data to its new location.
+     */
+    public abstract void migrateLegacyObbData();
+
+    /**
+     * Writes all package manager settings to disk. If {@code async} is {@code true}, the
+     * settings are written at some point in the future. Otherwise, the call blocks until
+     * the settings have been written.
+     */
+    public abstract void writeSettings(boolean async);
+
+    /**
+     * Writes all permission settings for the given set of users to disk. If {@code async}
+     * is {@code true}, the settings are written at some point in the future. Otherwise,
+     * the call blocks until the settings have been written.
+     */
+    public abstract void writePermissionSettings(@NonNull @UserIdInt int[] userIds, boolean async);
+
+    /**
+     * Returns the target SDK for the given UID. Will return {@code 0} if there is no
+     * package associated with the UID or if the package has not been installed for
+     * the user. Will return the highest target SDK if the UID references packages with
+     * a shared user id.
+     */
+    public abstract int getTargetSdk(int uid);
+
+    /**
+     * Returns {@code true} if the caller is the installer of record for the given package.
+     * Otherwise, {@code false}.
+     */
+    public abstract boolean isCallerInstallerOfRecord(
+            @NonNull PackageParser.Package pkg, int callingUid);
+
+    /** Returns whether or not default runtime permissions are granted for the given user */
+    public abstract boolean areDefaultRuntimePermissionsGranted(@UserIdInt int userId);
+
+    /** Sets the enforcement of reading external storage */
+    public abstract void setReadExternalStorageEnforced(boolean enforced);
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 43f3fbc..e690a7f 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -254,6 +254,8 @@
 
     /** @hide */
     public static final String APK_FILE_EXTENSION = ".apk";
+    /** @hide */
+    public static final String APEX_FILE_EXTENSION = ".apex";
 
     /** @hide */
     public static class NewPermissionInfo {
@@ -4288,7 +4290,7 @@
         a.info.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
         a.info.resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
         a.info.lockTaskLaunchMode = 0;
-        a.info.encryptionAware = a.info.directBootAware = false;
+        a.info.directBootAware = false;
         a.info.rotationAnimation = ROTATION_ANIMATION_UNSPECIFIED;
         a.info.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
         if (hardwareAccelerated) {
@@ -4492,7 +4494,7 @@
             a.info.lockTaskLaunchMode =
                     sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
 
-            a.info.encryptionAware = a.info.directBootAware = sa.getBoolean(
+            a.info.directBootAware = sa.getBoolean(
                     R.styleable.AndroidManifestActivity_directBootAware,
                     false);
 
@@ -4524,7 +4526,7 @@
                 a.info.flags |= ActivityInfo.FLAG_SINGLE_USER;
             }
 
-            a.info.encryptionAware = a.info.directBootAware = sa.getBoolean(
+            a.info.directBootAware = sa.getBoolean(
                     R.styleable.AndroidManifestActivity_directBootAware,
                     false);
         }
@@ -4920,7 +4922,7 @@
         info.minAspectRatio = target.info.minAspectRatio;
         info.requestedVrComponent = target.info.requestedVrComponent;
 
-        info.encryptionAware = info.directBootAware = target.info.directBootAware;
+        info.directBootAware = target.info.directBootAware;
 
         Activity a = new Activity(cachedArgs.mActivityAliasArgs, info);
         if (outError[0] != null) {
@@ -5131,7 +5133,7 @@
             p.info.flags |= ProviderInfo.FLAG_SINGLE_USER;
         }
 
-        p.info.encryptionAware = p.info.directBootAware = sa.getBoolean(
+        p.info.directBootAware = sa.getBoolean(
                 R.styleable.AndroidManifestProvider_directBootAware,
                 false);
         if (p.info.directBootAware) {
@@ -5451,7 +5453,7 @@
             s.info.flags |= ServiceInfo.FLAG_SINGLE_USER;
         }
 
-        s.info.encryptionAware = s.info.directBootAware = sa.getBoolean(
+        s.info.directBootAware = sa.getBoolean(
                 R.styleable.AndroidManifestService_directBootAware,
                 false);
         if (s.info.directBootAware) {
@@ -6897,8 +6899,8 @@
         }
 
         /** @hide */
-        public boolean isProductServices() {
-            return applicationInfo.isProductServices();
+        public boolean isSystemExt() {
+            return applicationInfo.isSystemExt();
         }
 
         /** @hide */
@@ -8391,12 +8393,13 @@
     public static PackageInfo generatePackageInfoFromApex(ApexInfo apexInfo, int flags)
             throws PackageParserException {
         PackageParser pp = new PackageParser();
-        File apexFile = new File(apexInfo.packagePath);
+        File apexFile = new File(apexInfo.modulePath);
         final Package p = pp.parsePackage(apexFile, flags, false);
         PackageUserState state = new PackageUserState();
         PackageInfo pi = generatePackageInfo(p, EmptyArray.INT, flags, 0, 0,
                 Collections.emptySet(), state);
         pi.applicationInfo.sourceDir = apexFile.getPath();
+        pi.applicationInfo.publicSourceDir = apexFile.getPath();
         if (apexInfo.isFactory) {
             pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
         } else {
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index b0b1874..23fbefb 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -17,7 +17,6 @@
 package android.content.pm;
 
 import android.Manifest;
-import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -177,8 +176,7 @@
         mContext.registerReceiver(mUserRemovedReceiver, userFilter);
     }
 
-    @VisibleForTesting
-    protected void handlePackageEvent(Intent intent, int userId) {
+    private void handlePackageEvent(Intent intent, int userId) {
         // Don't regenerate the services map when the package is removed or its
         // ASEC container unmounted as a step in replacement.  The subsequent
         // _ADDED / _AVAILABLE call will regenerate the map in the final state.
@@ -240,9 +238,6 @@
 
     public void invalidateCache(int userId) {
         synchronized (mServicesLock) {
-            if (DEBUG) {
-                Slog.d(TAG, "invalidating cache for " + userId + " " + mInterfaceName);
-            }
             final UserServices<V> user = findOrCreateUserLocked(userId);
             user.services = null;
             onServicesChangedLocked(userId);
@@ -472,48 +467,34 @@
      *                    or null to assume that everything is affected.
      * @param userId the user for whom to update the services map.
      */
-    private void generateServicesMap(@Nullable int[] changedUids, int userId) {
+    private void generateServicesMap(int[] changedUids, int userId) {
         if (DEBUG) {
             Slog.d(TAG, "generateServicesMap() for " + userId + ", changed UIDs = "
                     + Arrays.toString(changedUids));
         }
 
+        final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<>();
+        final List<ResolveInfo> resolveInfos = queryIntentServices(userId);
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            try {
+                ServiceInfo<V> info = parseServiceInfo(resolveInfo);
+                if (info == null) {
+                    Log.w(TAG, "Unable to load service info " + resolveInfo.toString());
+                    continue;
+                }
+                serviceInfos.add(info);
+            } catch (XmlPullParserException | IOException e) {
+                Log.w(TAG, "Unable to load service info " + resolveInfo.toString(), e);
+            }
+        }
+
         synchronized (mServicesLock) {
             final UserServices<V> user = findOrCreateUserLocked(userId);
-            final boolean cacheInvalid = user.services == null;
-            if (cacheInvalid) {
+            final boolean firstScan = user.services == null;
+            if (firstScan) {
                 user.services = Maps.newHashMap();
             }
 
-            final ArrayList<ServiceInfo<V>> serviceInfos = new ArrayList<>();
-            final List<ResolveInfo> resolveInfos = queryIntentServices(userId);
-
-            for (ResolveInfo resolveInfo : resolveInfos) {
-                try {
-                    // when changedUids == null, we want to do a rescan of everything, this means
-                    // it's the initial scan, and containsUid will trivially return true
-                    // when changedUids != null, we got here because a package changed, but
-                    // invalidateCache could have been called (thus user.services == null), and we
-                    // should query from PackageManager again
-                    if (!cacheInvalid
-                            && !containsUid(
-                                    changedUids, resolveInfo.serviceInfo.applicationInfo.uid)) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "Skipping parseServiceInfo for " + resolveInfo);
-                        }
-                        continue;
-                    }
-                    ServiceInfo<V> info = parseServiceInfo(resolveInfo);
-                    if (info == null) {
-                        Log.w(TAG, "Unable to load service info " + resolveInfo.toString());
-                        continue;
-                    }
-                    serviceInfos.add(info);
-                } catch (XmlPullParserException | IOException e) {
-                    Log.w(TAG, "Unable to load service info " + resolveInfo.toString(), e);
-                }
-            }
-
             StringBuilder changes = new StringBuilder();
             boolean changed = false;
             for (ServiceInfo<V> info : serviceInfos) {
@@ -534,7 +515,7 @@
                     changed = true;
                     user.services.put(info.type, info);
                     user.persistentServices.put(info.type, info.uid);
-                    if (!(user.mPersistentServicesFileDidNotExist && cacheInvalid)) {
+                    if (!(user.mPersistentServicesFileDidNotExist && firstScan)) {
                         notifyListener(info.type, userId, false /* removed */);
                     }
                 } else if (previousUid == info.uid) {
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 1734182..4d3e1f7 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -75,10 +75,6 @@
      */
     public boolean isInstantAppAvailable;
 
-    /** @removed */
-    @Deprecated
-    public boolean instantAppAvailable;
-
     /**
      * The IntentFilter that was matched for this ResolveInfo.
      */
@@ -378,7 +374,6 @@
         targetUserId = orig.targetUserId;
         handleAllWebDataURI = orig.handleAllWebDataURI;
         isInstantAppAvailable = orig.isInstantAppAvailable;
-        instantAppAvailable = isInstantAppAvailable;
     }
 
     public String toString() {
@@ -490,7 +485,7 @@
         noResourceId = source.readInt() != 0;
         iconResourceId = source.readInt();
         handleAllWebDataURI = source.readInt() != 0;
-        instantAppAvailable = isInstantAppAvailable = source.readInt() != 0;
+        isInstantAppAvailable = source.readInt() != 0;
     }
 
     public static class DisplayNameComparator
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 2b1b32e..7865d75 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -19,7 +19,6 @@
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 
@@ -232,7 +231,7 @@
         if (isManagedProfile() || isGuest() || isRestricted()) {
             return false;
         }
-        if (UserManager.isSplitSystemUser()) {
+        if (UserManager.isSplitSystemUser() || UserManager.isHeadlessSystemUserMode()) {
             return id != UserHandle.USER_SYSTEM;
         } else {
             return id == UserHandle.USER_SYSTEM;
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index e5ef67b..2420a61 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -1157,8 +1157,11 @@
             }
         }
 
-        if (mObject != 0) {
-            nativeDestroy(mObject);
+        synchronized (this) {
+            if (mObject != 0) {
+                nativeDestroy(mObject);
+                mObject = 0;
+            }
         }
     }
 
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index a99a0b5..f3b7553 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -32,8 +32,8 @@
 import android.view.WindowManager.LayoutParams;
 
 /**
- * CompatibilityInfo class keeps the information about compatibility mode that the application is
- * running under.
+ * CompatibilityInfo class keeps the information about the screen compatibility mode that the
+ * application is running under.
  * 
  *  {@hide} 
  */
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 794be9e..b72544c 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -856,7 +856,8 @@
             stack.push(id);
             try {
                 if (file.endsWith(".xml")) {
-                    if (file.startsWith("res/color/")) {
+                    final String typeName = getResourceTypeName(id);
+                    if (typeName != null && typeName.equals("color")) {
                         dr = loadColorOrXmlDrawable(wrapper, value, id, density, file);
                     } else {
                         dr = loadXmlDrawable(wrapper, value, id, density, file);
diff --git a/core/java/android/content/rollback/IRollbackManager.aidl b/core/java/android/content/rollback/IRollbackManager.aidl
index db9fcb6..8c2a65f 100644
--- a/core/java/android/content/rollback/IRollbackManager.aidl
+++ b/core/java/android/content/rollback/IRollbackManager.aidl
@@ -24,15 +24,15 @@
 interface IRollbackManager {
 
     ParceledListSlice getAvailableRollbacks();
-    ParceledListSlice getRecentlyExecutedRollbacks();
+    ParceledListSlice getRecentlyCommittedRollbacks();
 
     void commitRollback(int rollbackId, in ParceledListSlice causePackages,
             String callerPackageName, in IntentSender statusReceiver);
 
     // Exposed for use from the system server only. Callback from the package
-    // manager during the install flow when user data can be restored for a given
+    // manager during the install flow when user data can be backed up and restored for a given
     // package.
-    void restoreUserData(String packageName, in int[] userIds, int appId, long ceDataInode,
+    void snapshotAndRestoreUserData(String packageName, in int[] userIds, int appId, long ceDataInode,
             String seInfo, int token);
 
     // Exposed for test purposes only.
@@ -51,4 +51,7 @@
     // Used by the staging manager to notify the RollbackManager of the apk
     // session for a staged session.
     void notifyStagedApkSession(int originalSessionId, int apkSessionId);
+
+    // For test purposes only.
+    void blockRollbackManager(long millis);
 }
diff --git a/core/java/android/content/rollback/RollbackManager.java b/core/java/android/content/rollback/RollbackManager.java
index 9a10a0c..73b8a48 100644
--- a/core/java/android/content/rollback/RollbackManager.java
+++ b/core/java/android/content/rollback/RollbackManager.java
@@ -114,7 +114,7 @@
     })
     public @NonNull List<RollbackInfo> getRecentlyCommittedRollbacks() {
         try {
-            return mBinder.getRecentlyExecutedRollbacks().getList();
+            return mBinder.getRecentlyCommittedRollbacks().getList();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -250,4 +250,25 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Block the RollbackManager for a specified amount of time.
+     * This API is meant to facilitate testing of race conditions in
+     * RollbackManager. Blocks RollbackManager from processing anything for
+     * the given number of milliseconds.
+     *
+     * @param millis number of milliseconds to block the RollbackManager for
+     * @throws SecurityException if the caller does not have appropriate permissions.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS)
+    @TestApi
+    public void blockRollbackManager(long millis) {
+        try {
+            mBinder.blockRollbackManager(millis);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 3844794..f722275 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -19,8 +19,8 @@
 import android.database.Cursor;
 import android.database.CursorWindow;
 import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDebug.Consts;
 import android.database.sqlite.SQLiteDebug.DbStats;
+import android.database.sqlite.SQLiteDebug.NoPreloadHolder;
 import android.os.CancellationSignal;
 import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
@@ -214,7 +214,7 @@
         try {
             mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags,
                     mConfiguration.label,
-                    SQLiteDebug.Consts.DEBUG_SQL_STATEMENTS, SQLiteDebug.Consts.DEBUG_SQL_TIME,
+                    NoPreloadHolder.DEBUG_SQL_STATEMENTS, NoPreloadHolder.DEBUG_SQL_TIME,
                     mConfiguration.lookasideSlotSize, mConfiguration.lookasideSlotCount);
         } finally {
             mRecentOperations.endOperation(cookie);
@@ -1500,7 +1500,7 @@
                 operation.mFinished = true;
                 final long execTime = operation.mEndTime - operation.mStartTime;
                 mPool.onStatementExecuted(execTime);
-                return SQLiteDebug.Consts.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery(
+                return NoPreloadHolder.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery(
                         execTime);
             }
             return false;
@@ -1608,7 +1608,7 @@
             if (mSql != null) {
                 msg.append(", sql=\"").append(trimSqlForDisplay(mSql)).append("\"");
             }
-            final boolean dumpDetails = allowDetailedLog && Consts.DEBUG_LOG_DETAILED
+            final boolean dumpDetails = allowDetailedLog && NoPreloadHolder.DEBUG_LOG_DETAILED
                     && mBindArgs != null && mBindArgs.size() != 0;
             if (dumpDetails) {
                 msg.append(", bindArgs=[");
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index 4fc7f5d..a231a92 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -39,7 +39,7 @@
      *
      * {@hide}
      */
-    public static final class Consts {
+    public static final class NoPreloadHolder {
         /**
          * Controls the printing of informational SQL log messages.
          *
@@ -103,8 +103,9 @@
      */
     public static boolean shouldLogSlowQuery(long elapsedTimeMillis) {
         final int slowQueryMillis = Math.min(
-                SystemProperties.getInt(Consts.SLOW_QUERY_THRESHOLD_PROP, Integer.MAX_VALUE),
-                SystemProperties.getInt(Consts.SLOW_QUERY_THRESHOLD_UID_PROP,
+                SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_PROP,
+                        Integer.MAX_VALUE),
+                SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_UID_PROP,
                         Integer.MAX_VALUE));
         return elapsedTimeMillis >= slowQueryMillis;
     }
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index 3523e95..48d8867 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -30,11 +30,14 @@
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
+
 import libcore.util.EmptyArray;
 
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
@@ -49,14 +52,11 @@
 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|GROUP_CONCAT)\\((.+)\\)");
 
     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 = "";
@@ -65,7 +65,12 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     private boolean mDistinct;
     private SQLiteDatabase.CursorFactory mFactory;
-    private boolean mStrict;
+
+    private static final int STRICT_PARENTHESES = 1 << 0;
+    private static final int STRICT_COLUMNS = 1 << 1;
+    private static final int STRICT_GRAMMAR = 1 << 2;
+
+    private int mStrictFlags;
 
     public SQLiteQueryBuilder() {
         mDistinct = false;
@@ -209,13 +214,14 @@
     }
 
     /** {@hide} */
+    @Deprecated
     public void setProjectionAggregationAllowed(boolean projectionAggregationAllowed) {
-        mProjectionAggregationAllowed = projectionAggregationAllowed;
     }
 
     /** {@hide} */
+    @Deprecated
     public boolean isProjectionAggregationAllowed() {
-        return mProjectionAggregationAllowed;
+        return true;
     }
 
     /**
@@ -258,8 +264,12 @@
      * </ul>
      * By default, this value is false.
      */
-    public void setStrict(boolean flag) {
-        mStrict = flag;
+    public void setStrict(boolean strict) {
+        if (strict) {
+            mStrictFlags |= STRICT_PARENTHESES;
+        } else {
+            mStrictFlags &= ~STRICT_PARENTHESES;
+        }
     }
 
     /**
@@ -267,7 +277,67 @@
      * {@link #setStrict(boolean)}.
      */
     public boolean isStrict() {
-        return mStrict;
+        return (mStrictFlags & STRICT_PARENTHESES) != 0;
+    }
+
+    /**
+     * When enabled, verify that all projections and {@link ContentValues} only
+     * contain valid columns as defined by {@link #setProjectionMap(Map)}.
+     * <p>
+     * This enforcement applies to {@link #insert}, {@link #query}, and
+     * {@link #update} operations. Any enforcement failures will throw an
+     * {@link IllegalArgumentException}.
+     */
+    public void setStrictColumns(boolean strictColumns) {
+        if (strictColumns) {
+            mStrictFlags |= STRICT_COLUMNS;
+        } else {
+            mStrictFlags &= ~STRICT_COLUMNS;
+        }
+    }
+
+    /**
+     * Get if the query is marked as strict, as last configured by
+     * {@link #setStrictColumns(boolean)}.
+     */
+    public boolean isStrictColumns() {
+        return (mStrictFlags & STRICT_COLUMNS) != 0;
+    }
+
+    /**
+     * When enabled, verify that all untrusted SQL conforms to a restricted SQL
+     * grammar. Here are the restrictions applied:
+     * <ul>
+     * <li>In {@code WHERE} and {@code HAVING} clauses: subqueries, raising, and
+     * windowing terms are rejected.
+     * <li>In {@code GROUP BY} clauses: only valid columns are allowed.
+     * <li>In {@code ORDER BY} clauses: only valid columns, collation, and
+     * ordering terms are allowed.
+     * <li>In {@code LIMIT} clauses: only numerical values and offset terms are
+     * allowed.
+     * </ul>
+     * All column references must be valid as defined by
+     * {@link #setProjectionMap(Map)}.
+     * <p>
+     * This enforcement applies to {@link #query}, {@link #update} and
+     * {@link #delete} operations. This enforcement does not apply to trusted
+     * inputs, such as those provided by {@link #appendWhere}. Any enforcement
+     * failures will throw an {@link IllegalArgumentException}.
+     */
+    public void setStrictGrammar(boolean strictGrammar) {
+        if (strictGrammar) {
+            mStrictFlags |= STRICT_GRAMMAR;
+        } else {
+            mStrictFlags &= ~STRICT_GRAMMAR;
+        }
+    }
+
+    /**
+     * Get if the query is marked as strict, as last configured by
+     * {@link #setStrictGrammar(boolean)}.
+     */
+    public boolean isStrictGrammar() {
+        return (mStrictFlags & STRICT_GRAMMAR) != 0;
     }
 
     /**
@@ -303,9 +373,6 @@
             throw new IllegalArgumentException(
                     "HAVING clauses are only permitted when using a groupBy clause");
         }
-        if (!TextUtils.isEmpty(limit) && !sLimitPattern.matcher(limit).matches()) {
-            throw new IllegalArgumentException("invalid LIMIT clauses:" + limit);
-        }
 
         StringBuilder query = new StringBuilder(120);
 
@@ -479,7 +546,13 @@
                 projectionIn, selection, groupBy, having,
                 sortOrder, limit);
 
-        if (mStrict && selection != null && selection.length() > 0) {
+        if (isStrictColumns()) {
+            enforceStrictColumns(projectionIn);
+        }
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, groupBy, having, sortOrder, limit);
+        }
+        if (isStrict()) {
             // Validate the user-supplied selection to detect syntactic anomalies
             // in the selection string that could indicate a SQL injection attempt.
             // The idea is to ensure that the selection clause is a valid SQL expression
@@ -497,7 +570,7 @@
 
             // Execute wrapped query for extra protection
             final String wrappedSql = buildQuery(projectionIn, wrap(selection), groupBy,
-                    having, sortOrder, limit);
+                    wrap(having), sortOrder, limit);
             sql = wrappedSql;
         } else {
             // Execute unwrapped query
@@ -519,6 +592,40 @@
     }
 
     /**
+     * Perform an insert by combining all current settings and the
+     * information passed into this method.
+     *
+     * @param db the database to insert on
+     * @return the row ID of the newly inserted row, or -1 if an error occurred
+     */
+    public long insert(@NonNull SQLiteDatabase db, @NonNull ContentValues values) {
+        Objects.requireNonNull(mTables, "No tables defined");
+        Objects.requireNonNull(db, "No database defined");
+        Objects.requireNonNull(values, "No values defined");
+
+        if (isStrictColumns()) {
+            enforceStrictColumns(values);
+        }
+
+        final String sql = buildInsert(values);
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        final int valuesLength = rawValues.size();
+        final Object[] sqlArgs = new Object[valuesLength];
+        for (int i = 0; i < sqlArgs.length; i++) {
+            sqlArgs[i] = rawValues.valueAt(i);
+        }
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Build.IS_DEBUGGABLE) {
+                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
+            } else {
+                Log.d(TAG, sql);
+            }
+        }
+        return db.executeSql(sql, sqlArgs);
+    }
+
+    /**
      * Perform an update by combining all current settings and the
      * information passed into this method.
      *
@@ -541,7 +648,13 @@
         final String sql;
         final String unwrappedSql = buildUpdate(values, selection);
 
-        if (mStrict) {
+        if (isStrictColumns()) {
+            enforceStrictColumns(values);
+        }
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, null, null, null, null);
+        }
+        if (isStrict()) {
             // Validate the user-supplied selection to detect syntactic anomalies
             // in the selection string that could indicate a SQL injection attempt.
             // The idea is to ensure that the selection clause is a valid SQL expression
@@ -610,7 +723,10 @@
         final String sql;
         final String unwrappedSql = buildDelete(selection);
 
-        if (mStrict) {
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, null, null, null, null);
+        }
+        if (isStrict()) {
             // Validate the user-supplied selection to detect syntactic anomalies
             // in the selection string that could indicate a SQL injection attempt.
             // The idea is to ensure that the selection clause is a valid SQL expression
@@ -645,6 +761,81 @@
         return db.executeSql(sql, sqlArgs);
     }
 
+    private void enforceStrictColumns(@Nullable String[] projection) {
+        Objects.requireNonNull(mProjectionMap, "No projection map defined");
+
+        computeProjection(projection);
+    }
+
+    private void enforceStrictColumns(@NonNull ContentValues values) {
+        Objects.requireNonNull(mProjectionMap, "No projection map defined");
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        for (int i = 0; i < rawValues.size(); i++) {
+            final String column = rawValues.keyAt(i);
+            if (!mProjectionMap.containsKey(column)) {
+                throw new IllegalArgumentException("Invalid column " + column);
+            }
+        }
+    }
+
+    private void enforceStrictGrammar(@Nullable String selection, @Nullable String groupBy,
+            @Nullable String having, @Nullable String sortOrder, @Nullable String limit) {
+        SQLiteTokenizer.tokenize(selection, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarWhereHaving);
+        SQLiteTokenizer.tokenize(groupBy, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarGroupBy);
+        SQLiteTokenizer.tokenize(having, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarWhereHaving);
+        SQLiteTokenizer.tokenize(sortOrder, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarOrderBy);
+        SQLiteTokenizer.tokenize(limit, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictGrammarLimit);
+    }
+
+    private void enforceStrictGrammarWhereHaving(@NonNull String token) {
+        if (isTableOrColumn(token)) return;
+        if (SQLiteTokenizer.isFunction(token)) return;
+        if (SQLiteTokenizer.isType(token)) return;
+
+        // NOTE: we explicitly don't allow SELECT subqueries, since they could
+        // leak data that should have been filtered by the trusted where clause
+        switch (token.toUpperCase(Locale.US)) {
+            case "AND": case "AS": case "BETWEEN": case "BINARY":
+            case "CASE": case "CAST": case "COLLATE": case "DISTINCT":
+            case "ELSE": case "END": case "ESCAPE": case "EXISTS":
+            case "GLOB": case "IN": case "IS": case "ISNULL":
+            case "LIKE": case "MATCH": case "NOCASE": case "NOT":
+            case "NOTNULL": case "NULL": case "OR": case "REGEXP":
+            case "RTRIM": case "THEN": case "WHEN":
+                return;
+        }
+        throw new IllegalArgumentException("Invalid token " + token);
+    }
+
+    private void enforceStrictGrammarGroupBy(@NonNull String token) {
+        if (isTableOrColumn(token)) return;
+        throw new IllegalArgumentException("Invalid token " + token);
+    }
+
+    private void enforceStrictGrammarOrderBy(@NonNull String token) {
+        if (isTableOrColumn(token)) return;
+        switch (token.toUpperCase(Locale.US)) {
+            case "COLLATE": case "ASC": case "DESC":
+            case "BINARY": case "RTRIM": case "NOCASE":
+                return;
+        }
+        throw new IllegalArgumentException("Invalid token " + token);
+    }
+
+    private void enforceStrictGrammarLimit(@NonNull String token) {
+        switch (token.toUpperCase(Locale.US)) {
+            case "OFFSET":
+                return;
+        }
+        throw new IllegalArgumentException("Invalid token " + token);
+    }
+
     /**
      * Construct a {@code SELECT} statement suitable for use in a group of
      * {@code SELECT} statements that will be joined through {@code UNION} operators
@@ -698,6 +889,35 @@
     }
 
     /** {@hide} */
+    public String buildInsert(ContentValues values) {
+        if (values == null || values.isEmpty()) {
+            throw new IllegalArgumentException("Empty values");
+        }
+
+        StringBuilder sql = new StringBuilder(120);
+        sql.append("INSERT INTO ");
+        sql.append(SQLiteDatabase.findEditTable(mTables));
+        sql.append(" (");
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        for (int i = 0; i < rawValues.size(); i++) {
+            if (i > 0) {
+                sql.append(',');
+            }
+            sql.append(rawValues.keyAt(i));
+        }
+        sql.append(") VALUES (");
+        for (int i = 0; i < rawValues.size(); i++) {
+            if (i > 0) {
+                sql.append(',');
+            }
+            sql.append('?');
+        }
+        sql.append(")");
+        return sql.toString();
+    }
+
+    /** {@hide} */
     public String buildUpdate(ContentValues values, String selection) {
         if (values == null || values.isEmpty()) {
             throw new IllegalArgumentException("Empty values");
@@ -705,7 +925,7 @@
 
         StringBuilder sql = new StringBuilder(120);
         sql.append("UPDATE ");
-        sql.append(mTables);
+        sql.append(SQLiteDatabase.findEditTable(mTables));
         sql.append(" SET ");
 
         final ArrayMap<String, Object> rawValues = values.getValues();
@@ -726,7 +946,7 @@
     public String buildDelete(String selection) {
         StringBuilder sql = new StringBuilder(120);
         sql.append("DELETE FROM ");
-        sql.append(mTables);
+        sql.append(SQLiteDatabase.findEditTable(mTables));
 
         final String where = computeWhere(selection);
         appendClause(sql, " WHERE ", where);
@@ -868,65 +1088,13 @@
 
     /** {@hide} */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
-    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] = maybeWithOperator(operator, column);
-                        continue;
-                    }
-
-                    if (!mStrict &&
-                            ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {
-                        /* A column alias already exist */
-                        projection[i] = maybeWithOperator(operator, userColumn);
-                        continue;
-                    }
-
-                    // If greylist is configured, we might be willing to let
-                    // this custom column bypass our strict checks.
-                    if (mProjectionGreylist != null) {
-                        boolean match = false;
-                        for (Pattern p : mProjectionGreylist) {
-                            if (p.matcher(userColumn).matches()) {
-                                match = true;
-                                break;
-                            }
-                        }
-
-                        if (match) {
-                            Log.w(TAG, "Allowing abusive custom column: " + userColumn);
-                            projection[i] = maybeWithOperator(operator, userColumn);
-                            continue;
-                        }
-                    }
-
-                    throw new IllegalArgumentException("Invalid column "
-                            + projectionIn[i]);
-                }
-                return projection;
-            } else {
-                return projectionIn;
+    public @Nullable String[] computeProjection(@Nullable String[] projectionIn) {
+        if (!ArrayUtils.isEmpty(projectionIn)) {
+            String[] projectionOut = new String[projectionIn.length];
+            for (int i = 0; i < projectionIn.length; i++) {
+                projectionOut[i] = computeSingleProjectionOrThrow(projectionIn[i]);
             }
+            return projectionOut;
         } else if (mProjectionMap != null) {
             // Return all columns in projection map.
             Set<Entry<String, String>> entrySet = mProjectionMap.entrySet();
@@ -948,6 +1116,69 @@
         return null;
     }
 
+    private @NonNull String computeSingleProjectionOrThrow(@NonNull String userColumn) {
+        final String column = computeSingleProjection(userColumn);
+        if (column != null) {
+            return column;
+        } else {
+            throw new IllegalArgumentException("Invalid column " + userColumn);
+        }
+    }
+
+    private @Nullable String computeSingleProjection(@NonNull String userColumn) {
+        // When no mapping provided, anything goes
+        if (mProjectionMap == null) {
+            return userColumn;
+        }
+
+        String operator = null;
+        String column = mProjectionMap.get(userColumn);
+
+        // When no direct match found, look for aggregation
+        if (column == null) {
+            final Matcher matcher = sAggregationPattern.matcher(userColumn);
+            if (matcher.matches()) {
+                operator = matcher.group(1);
+                userColumn = matcher.group(2);
+                column = mProjectionMap.get(userColumn);
+            }
+        }
+
+        if (column != null) {
+            return maybeWithOperator(operator, column);
+        }
+
+        if (mStrictFlags == 0 &&
+                (userColumn.contains(" AS ") || userColumn.contains(" as "))) {
+            /* A column alias already exist */
+            return maybeWithOperator(operator, userColumn);
+        }
+
+        // If greylist is configured, we might be willing to let
+        // this custom column bypass our strict checks.
+        if (mProjectionGreylist != null) {
+            boolean match = false;
+            for (Pattern p : mProjectionGreylist) {
+                if (p.matcher(userColumn).matches()) {
+                    match = true;
+                    break;
+                }
+            }
+
+            if (match) {
+                Log.w(TAG, "Allowing abusive custom column: " + userColumn);
+                return maybeWithOperator(operator, userColumn);
+            }
+        }
+
+        return null;
+    }
+
+    private boolean isTableOrColumn(String token) {
+        if (mTables.equals(token)) return true;
+        return computeSingleProjection(token) != null;
+    }
+
     /** {@hide} */
     public @Nullable String computeWhere(@Nullable String selection) {
         final boolean hasInternal = !TextUtils.isEmpty(mWhereClause);
diff --git a/core/java/android/database/sqlite/SQLiteTokenizer.java b/core/java/android/database/sqlite/SQLiteTokenizer.java
new file mode 100644
index 0000000..7e7c3fb
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteTokenizer.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.sqlite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Consumer;
+
+/**
+ * SQL Tokenizer specialized to extract tokens from SQL (snippets).
+ * <p>
+ * Based on sqlite3GetToken() in tokenzie.c in SQLite.
+ * <p>
+ * Source for v3.8.6 (which android uses): http://www.sqlite.org/src/artifact/ae45399d6252b4d7
+ * (Latest source as of now: http://www.sqlite.org/src/artifact/78c8085bc7af1922)
+ * <p>
+ * Also draft spec: http://www.sqlite.org/draft/tokenreq.html
+ *
+ * @hide
+ */
+public class SQLiteTokenizer {
+    private static boolean isAlpha(char ch) {
+        return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || (ch == '_');
+    }
+
+    private static boolean isNum(char ch) {
+        return ('0' <= ch && ch <= '9');
+    }
+
+    private static boolean isAlNum(char ch) {
+        return isAlpha(ch) || isNum(ch);
+    }
+
+    private static boolean isAnyOf(char ch, String set) {
+        return set.indexOf(ch) >= 0;
+    }
+
+    private static IllegalArgumentException genException(String message, String sql) {
+        throw new IllegalArgumentException(message + " in '" + sql + "'");
+    }
+
+    private static char peek(String s, int index) {
+        return index < s.length() ? s.charAt(index) : '\0';
+    }
+
+    public static final int OPTION_NONE = 0;
+
+    /**
+     * Require that SQL contains only tokens; any comments or values will result
+     * in an exception.
+     */
+    public static final int OPTION_TOKEN_ONLY = 1 << 0;
+
+    /**
+     * Tokenize the given SQL, returning the list of each encountered token.
+     *
+     * @throws IllegalArgumentException if invalid SQL is encountered.
+     */
+    public static List<String> tokenize(@Nullable String sql, int options) {
+        final ArrayList<String> res = new ArrayList<>();
+        tokenize(sql, options, res::add);
+        return res;
+    }
+
+    /**
+     * Tokenize the given SQL, sending each encountered token to the given
+     * {@link Consumer}.
+     *
+     * @throws IllegalArgumentException if invalid SQL is encountered.
+     */
+    public static void tokenize(@Nullable String sql, int options, Consumer<String> checker) {
+        if (sql == null) {
+            return;
+        }
+        int pos = 0;
+        final int len = sql.length();
+        while (pos < len) {
+            final char ch = peek(sql, pos);
+
+            // Regular token.
+            if (isAlpha(ch)) {
+                final int start = pos;
+                pos++;
+                while (isAlNum(peek(sql, pos))) {
+                    pos++;
+                }
+                final int end = pos;
+
+                final String token = sql.substring(start, end);
+                checker.accept(token);
+
+                continue;
+            }
+
+            // Handle quoted tokens
+            if (isAnyOf(ch, "'\"`")) {
+                final int quoteStart = pos;
+                pos++;
+
+                for (;;) {
+                    pos = sql.indexOf(ch, pos);
+                    if (pos < 0) {
+                        throw genException("Unterminated quote", sql);
+                    }
+                    if (peek(sql, pos + 1) != ch) {
+                        break;
+                    }
+                    // Quoted quote char -- e.g. "abc""def" is a single string.
+                    pos += 2;
+                }
+                final int quoteEnd = pos;
+                pos++;
+
+                if (ch != '\'') {
+                    // Extract the token
+                    final String tokenUnquoted = sql.substring(quoteStart + 1, quoteEnd);
+
+                    final String token;
+
+                    // Unquote if needed. i.e. "aa""bb" -> aa"bb
+                    if (tokenUnquoted.indexOf(ch) >= 0) {
+                        token = tokenUnquoted.replaceAll(
+                                String.valueOf(ch) + ch, String.valueOf(ch));
+                    } else {
+                        token = tokenUnquoted;
+                    }
+                    checker.accept(token);
+                } else {
+                    if ((options &= OPTION_TOKEN_ONLY) != 0) {
+                        throw genException("Non-token detected", sql);
+                    }
+                }
+                continue;
+            }
+            // Handle tokens enclosed in [...]
+            if (ch == '[') {
+                final int quoteStart = pos;
+                pos++;
+
+                pos = sql.indexOf(']', pos);
+                if (pos < 0) {
+                    throw genException("Unterminated quote", sql);
+                }
+                final int quoteEnd = pos;
+                pos++;
+
+                final String token = sql.substring(quoteStart + 1, quoteEnd);
+
+                checker.accept(token);
+                continue;
+            }
+            if ((options &= OPTION_TOKEN_ONLY) != 0) {
+                throw genException("Non-token detected", sql);
+            }
+
+            // Detect comments.
+            if (ch == '-' && peek(sql, pos + 1) == '-') {
+                pos += 2;
+                pos = sql.indexOf('\n', pos);
+                if (pos < 0) {
+                    // We disallow strings ending in an inline comment.
+                    throw genException("Unterminated comment", sql);
+                }
+                pos++;
+
+                continue;
+            }
+            if (ch == '/' && peek(sql, pos + 1) == '*') {
+                pos += 2;
+                pos = sql.indexOf("*/", pos);
+                if (pos < 0) {
+                    throw genException("Unterminated comment", sql);
+                }
+                pos += 2;
+
+                continue;
+            }
+
+            // Semicolon is never allowed.
+            if (ch == ';') {
+                throw genException("Semicolon is not allowed", sql);
+            }
+
+            // For this purpose, we can simply ignore other characters.
+            // (Note it doesn't handle the X'' literal properly and reports this X as a token,
+            // but that should be fine...)
+            pos++;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/lang_keywords.html">SQLite reserved
+     * keyword</a>.
+     */
+    public static boolean isKeyword(@NonNull String token) {
+        switch (token.toUpperCase(Locale.US)) {
+            case "ABORT": case "ACTION": case "ADD": case "AFTER":
+            case "ALL": case "ALTER": case "ANALYZE": case "AND":
+            case "AS": case "ASC": case "ATTACH": case "AUTOINCREMENT":
+            case "BEFORE": case "BEGIN": case "BETWEEN": case "BINARY":
+            case "BY": case "CASCADE": case "CASE": case "CAST":
+            case "CHECK": case "COLLATE": case "COLUMN": case "COMMIT":
+            case "CONFLICT": case "CONSTRAINT": case "CREATE": case "CROSS":
+            case "CURRENT": case "CURRENT_DATE": case "CURRENT_TIME": case "CURRENT_TIMESTAMP":
+            case "DATABASE": case "DEFAULT": case "DEFERRABLE": case "DEFERRED":
+            case "DELETE": case "DESC": case "DETACH": case "DISTINCT":
+            case "DO": case "DROP": case "EACH": case "ELSE":
+            case "END": case "ESCAPE": case "EXCEPT": case "EXCLUDE":
+            case "EXCLUSIVE": case "EXISTS": case "EXPLAIN": case "FAIL":
+            case "FILTER": case "FOLLOWING": case "FOR": case "FOREIGN":
+            case "FROM": case "FULL": case "GLOB": case "GROUP":
+            case "GROUPS": case "HAVING": case "IF": case "IGNORE":
+            case "IMMEDIATE": case "IN": case "INDEX": case "INDEXED":
+            case "INITIALLY": case "INNER": case "INSERT": case "INSTEAD":
+            case "INTERSECT": case "INTO": case "IS": case "ISNULL":
+            case "JOIN": case "KEY": case "LEFT": case "LIKE":
+            case "LIMIT": case "MATCH": case "NATURAL": case "NO":
+            case "NOCASE": case "NOT": case "NOTHING": case "NOTNULL":
+            case "NULL": case "OF": case "OFFSET": case "ON":
+            case "OR": case "ORDER": case "OTHERS": case "OUTER":
+            case "OVER": case "PARTITION": case "PLAN": case "PRAGMA":
+            case "PRECEDING": case "PRIMARY": case "QUERY": case "RAISE":
+            case "RANGE": case "RECURSIVE": case "REFERENCES": case "REGEXP":
+            case "REINDEX": case "RELEASE": case "RENAME": case "REPLACE":
+            case "RESTRICT": case "RIGHT": case "ROLLBACK": case "ROW":
+            case "ROWS": case "RTRIM": case "SAVEPOINT": case "SELECT":
+            case "SET": case "TABLE": case "TEMP": case "TEMPORARY":
+            case "THEN": case "TIES": case "TO": case "TRANSACTION":
+            case "TRIGGER": case "UNBOUNDED": case "UNION": case "UNIQUE":
+            case "UPDATE": case "USING": case "VACUUM": case "VALUES":
+            case "VIEW": case "VIRTUAL": case "WHEN": case "WHERE":
+            case "WINDOW": case "WITH": case "WITHOUT":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/lang_corefunc.html">SQLite reserved
+     * function</a>.
+     */
+    public static boolean isFunction(@NonNull String token) {
+        switch (token.toLowerCase(Locale.US)) {
+            case "abs": case "avg": case "char": case "coalesce":
+            case "count": case "glob": case "group_concat": case "hex":
+            case "ifnull": case "instr": case "length": case "like":
+            case "likelihood": case "likely": case "lower": case "ltrim":
+            case "max": case "min": case "nullif": case "random":
+            case "randomblob": case "replace": case "round": case "rtrim":
+            case "substr": case "sum": case "total": case "trim":
+            case "typeof": case "unicode": case "unlikely": case "upper":
+            case "zeroblob":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/datatype3.html">SQLite reserved type</a>.
+     */
+    public static boolean isType(@NonNull String token) {
+        switch (token.toUpperCase(Locale.US)) {
+            case "INT": case "INTEGER": case "TINYINT": case "SMALLINT":
+            case "MEDIUMINT": case "BIGINT": case "INT2": case "INT8":
+            case "CHARACTER": case "VARCHAR": case "NCHAR": case "NVARCHAR":
+            case "TEXT": case "CLOB": case "BLOB": case "REAL":
+            case "DOUBLE": case "FLOAT": case "NUMERIC": case "DECIMAL":
+            case "BOOLEAN": case "DATE": case "DATETIME":
+                return true;
+            default:
+                return false;
+        }
+    }
+}
diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java
index c569e05..5b25f5a 100644
--- a/core/java/android/hardware/HardwareBuffer.java
+++ b/core/java/android/hardware/HardwareBuffer.java
@@ -310,18 +310,6 @@
         return nGetUsage(mNativeObject);
     }
 
-    /** @removed replaced by {@link #close()} */
-    @Deprecated
-    public void destroy() {
-        close();
-    }
-
-    /** @removed replaced by {@link #isClosed()} */
-    @Deprecated
-    public boolean isDestroyed() {
-        return isClosed();
-    }
-
     /**
      * Destroys this buffer immediately. Calling this method frees up any
      * underlying native resources. After calling this method, this buffer
diff --git a/core/java/android/hardware/SensorAdditionalInfo.java b/core/java/android/hardware/SensorAdditionalInfo.java
index 5ff627f..12edc5e 100644
--- a/core/java/android/hardware/SensorAdditionalInfo.java
+++ b/core/java/android/hardware/SensorAdditionalInfo.java
@@ -119,12 +119,50 @@
     public static final int TYPE_VEC3_CALIBRATION = 0x10002;
 
     /**
-     * Sensor placement. Describes location and installation angle of the sensor device.
+     * Sensor placement.
      *
-     * Payload:
-     *     floatValues[0..11]: First 3 rows of homogeneous matrix in row major order that describes
-     *     the location and orientation of the sensor. Origin of reference will be the mobile device
-     *     geometric sensor. Reference frame is defined as the same as Android sensor frame.
+     * Provides the orientation and location of the sensor element in terms of the
+     * Android coordinate system. This data is given as a 3x4 matrix consisting of a 3x3 rotation
+     * matrix (R) concatenated with a 3x1 location vector (t). The rotation matrix provides the
+     * orientation of the Android device coordinate frame relative to the local coordinate frame of
+     * the sensor. Note that assuming the axes conventions of the sensor are the same as Android,
+     * this is the inverse of the matrix applied to raw samples read from the sensor to convert them
+     * into the Android representation. The location vector represents the translation from the
+     * origin of the Android sensor coordinate system to the geometric center of the sensor,
+     * specified in millimeters (mm).
+     * <p>
+     * <b>Payload</b>:
+     *     <code>floatValues[0..11]</code>: 3x4 matrix in row major order [R; t]
+     * </p>
+     * <p>
+     * <b>Example</b>:
+     *     This raw buffer: <code>{0, 1, 0, 0, -1, 0, 0, 10, 0, 0, 1, -2.5}</code><br>
+     *     Corresponds to this 3x4 matrix:
+     *     <table>
+     *      <thead>
+     *       <tr><td colspan="3">Orientation</td><td>Location</tr>
+     *      </thead>
+     *      <tbody>
+     *       <tr><td>0</td><td>1</td><td>0</td><td>0</td></tr>
+     *       <tr><td>-1</td><td>0</td><td>0</td><td>10</td></tr>
+     *       <tr><td>0</td><td>0</td><td>1</td><td>-2.5</td></tr>
+     *      </tbody>
+     *     </table>
+     *     The sensor is oriented such that:
+     *     <ul>
+     *        <li>The device X axis corresponds to the sensor's local -Y axis
+     *        <li>The device Y axis corresponds to the sensor's local X axis
+     *        <li>The device Z axis and sensor's local Z axis are equivalent
+     *     </ul>
+     *     In other words, if viewing the origin of the Android coordinate system from the positive
+     *     Z direction, the device coordinate frame is to be rotated 90° counter-clockwise about the
+     *     Z axis to align with the sensor's local coordinate frame. Equivalently, a vector in the
+     *     Android coordinate frame may be multiplied with R to rotate it 90° clockwise (270°
+     *     counter-clockwise), yielding its representation in the sensor's coordinate frame.
+     *     Relative to the origin of the Android coordinate system, the physical center of the
+     *     sensor is located 10mm in the positive Y direction, and 2.5mm in the negative Z
+     *     direction.
+     * </p>
      */
     public static final int TYPE_SENSOR_PLACEMENT = 0x10003;
 
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 3250428..524a0c4 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -943,12 +943,6 @@
     /** @hide */
     protected abstract void destroyDirectChannelImpl(SensorDirectChannel channel);
 
-    /** @removed */
-    @Deprecated
-    public int configureDirectChannel(SensorDirectChannel channel, Sensor sensor, int rateLevel) {
-        return configureDirectChannelImpl(channel, sensor, rateLevel);
-    }
-
     /** @hide */
     protected abstract int configureDirectChannelImpl(
             SensorDirectChannel channel, Sensor s, int rate);
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 6c497d4..af66dc1 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -104,9 +104,17 @@
      */
     @RequiresPermission(USE_BIOMETRIC)
     public @BiometricError int canAuthenticate() {
+        return canAuthenticate(mContext.getUserId());
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public @BiometricError int canAuthenticate(int userId) {
         if (mService != null) {
             try {
-                return mService.canAuthenticate(mContext.getOpPackageName());
+                return mService.canAuthenticate(mContext.getOpPackageName(), userId);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
index d22e7e2..62d727c 100644
--- a/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
@@ -22,5 +22,5 @@
  * @hide
  */
 oneway interface IBiometricEnabledOnKeyguardCallback {
-    void onChanged(in BiometricSourceType type, boolean enabled);
+    void onChanged(in BiometricSourceType type, boolean enabled, int userId);
 }
\ No newline at end of file
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 90d4921..18c14cb 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -40,7 +40,7 @@
     void cancelAuthentication(IBinder token, String opPackageName);
 
     // Checks if biometrics can be used.
-    int canAuthenticate(String opPackageName);
+    int canAuthenticate(String opPackageName, int userId);
 
     // Register callback for when keyguard biometric eligibility changes.
     void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback);
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 48588e6..1b31792 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -760,14 +760,20 @@
      * </ul>
      * <p>For devices at the LIMITED level or above:</p>
      * <ul>
-     * <li>For YUV_420_888 burst capture use case, this list will always include (<code>min</code>, <code>max</code>)
-     * and (<code>max</code>, <code>max</code>) where <code>min</code> &lt;= 15 and <code>max</code> = the maximum output frame rate of the
+     * <li>For devices that advertise NIR color filter arrangement in
+     * {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT android.sensor.info.colorFilterArrangement}, this list will always include
+     * (<code>max</code>, <code>max</code>) where <code>max</code> = the maximum output frame rate of the maximum YUV_420_888
+     * output size.</li>
+     * <li>For devices advertising any color filter arrangement other than NIR, or devices not
+     * advertising color filter arrangement, this list will always include (<code>min</code>, <code>max</code>) and
+     * (<code>max</code>, <code>max</code>) where <code>min</code> &lt;= 15 and <code>max</code> = the maximum output frame rate of the
      * maximum YUV_420_888 output size.</li>
      * </ul>
      * <p><b>Units</b>: Frames per second (FPS)</p>
      * <p>This key is available on all devices.</p>
      *
      * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE
+     * @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
      */
     @PublicKey
     @NonNull
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index f662b61..c8276b2 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -857,8 +857,10 @@
      *
      * @param cameraId a non-{@code null} camera identifier
      * @return {@code true} if cameraId is a hidden physical camera device
+     *
+     * @hide
      */
-    private boolean isHiddenPhysicalCamera(String cameraId) {
+    public static boolean isHiddenPhysicalCamera(String cameraId) {
         try {
             ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
             // If no camera service, no support
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 04e8cf4..5ac13d8 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -925,14 +925,14 @@
      * case, when the application configures a RAW stream, the camera device will make sure
      * the active physical camera will remain active to ensure consistent RAW output
      * behavior, and not switch to other physical cameras.</p>
-     * <p>To maintain backward compatibility, the capture request and result metadata tags
-     * required for basic camera functionalities will be solely based on the
-     * logical camera capabiltity. Other request and result metadata tags, on the other
-     * hand, will be based on current active physical camera. For example, the physical
-     * cameras' sensor sensitivity and lens capability could be different from each other.
-     * So when the application manually controls sensor exposure time/gain, or does manual
-     * focus control, it must checks the current active physical camera's exposure, gain,
-     * and focus distance range.</p>
+     * <p>The capture request and result metadata tags required for backward compatible camera
+     * functionalities will be solely based on the logical camera capabiltity. On the other
+     * hand, the use of manual capture controls (sensor or post-processing) with a
+     * logical camera may result in unexpected behavior when the HAL decides to switch
+     * between physical cameras with different characteristics under the hood. For example,
+     * when the application manually sets exposure time and sensitivity while zooming in,
+     * the brightness of the camera images may suddenly change because HAL switches from one
+     * physical camera to the other.</p>
      *
      * @see CameraCharacteristics#LENS_DISTORTION
      * @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index 3494a7f..eb33137 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -25,6 +25,7 @@
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.camera2.utils.SurfaceUtils;
 import android.os.Handler;
+import android.os.ConditionVariable;
 import android.util.Range;
 import android.view.Surface;
 
@@ -51,6 +52,7 @@
         extends CameraConstrainedHighSpeedCaptureSession implements CameraCaptureSessionCore {
     private final CameraCharacteristics mCharacteristics;
     private final CameraCaptureSessionImpl mSessionImpl;
+    private final ConditionVariable mInitialized = new ConditionVariable();
 
     /**
      * Create a new CameraCaptureSession.
@@ -68,6 +70,7 @@
         CameraCaptureSession.StateCallback wrapperCallback = new WrapperCallback(callback);
         mSessionImpl = new CameraCaptureSessionImpl(id, /*input*/null, wrapperCallback,
                 stateExecutor, deviceImpl, deviceStateExecutor, configureSuccess);
+        mInitialized.open();
     }
 
     @Override
@@ -321,11 +324,13 @@
 
         @Override
         public void onConfigured(CameraCaptureSession session) {
+            mInitialized.block();
             mCallback.onConfigured(CameraConstrainedHighSpeedCaptureSessionImpl.this);
         }
 
         @Override
         public void onConfigureFailed(CameraCaptureSession session) {
+            mInitialized.block();
             mCallback.onConfigureFailed(CameraConstrainedHighSpeedCaptureSessionImpl.this);
         }
 
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index d44b6b5..6eaf54b 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -28,6 +28,7 @@
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraCharacteristics.Key;
 import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
 import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.hardware.camera2.utils.HashCodeHelpers;
@@ -661,6 +662,7 @@
         private List<Integer> mCapabilities;
         private int mHwLevel, mCameraId;
         private StreamConfigurationMap mStreamConfigMap;
+        private boolean mIsHiddenPhysicalCamera;
 
         private final Size kPreviewSizeBound = new Size(1920, 1088);
 
@@ -680,6 +682,8 @@
             mCapabilities = capabilities;
             mStreamConfigMap = sm;
             mHwLevel = hwLevel;
+            mIsHiddenPhysicalCamera =
+                    CameraManager.isHiddenPhysicalCamera(Integer.toString(mCameraId));
         }
 
         /**
@@ -893,8 +897,10 @@
             Size recordingMaxSize = new Size(0, 0);
             Size previewMaxSize = new Size(0, 0);
             Size vgaSize = new Size(640, 480);
-            if (isExternalCamera()) {
-                recordingMaxSize = getMaxExternalRecordingSize();
+            // For external camera, or hidden physical camera, CamcorderProfile may not be
+            // available, so get maximum recording size using stream configuration map.
+            if (isExternalCamera() || mIsHiddenPhysicalCamera) {
+                recordingMaxSize = getMaxCameraRecordingSize();
             } else {
                 recordingMaxSize = getMaxRecordingSize();
             }
@@ -1123,12 +1129,12 @@
         }
 
         /**
-         * Return the maximum supported video size for external cameras using data from
+         * Return the maximum supported video size for cameras using data from
          * the stream configuration map.
          *
          * @return Maximum supported video size.
          */
-        private @NonNull Size getMaxExternalRecordingSize() {
+        private @NonNull Size getMaxCameraRecordingSize() {
             final Size FULLHD = new Size(1920, 1080);
 
             Size[] videoSizeArr = mStreamConfigMap.getOutputSizes(
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index c45b8ed..3e995b6 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -48,7 +48,8 @@
         return pulseOnNotificationEnabled(user)
                 || pulseOnLongPressEnabled(user)
                 || alwaysOnEnabled(user)
-                || wakeScreenGestureEnabled(user)
+                || wakeLockScreenGestureEnabled(user)
+                || wakeDisplayGestureEnabled(user)
                 || pickupGestureEnabled(user)
                 || tapGestureEnabled(user)
                 || doubleTapGestureEnabled(user);
@@ -105,8 +106,14 @@
     }
 
     /** {@hide} */
-    public boolean wakeScreenGestureEnabled(int user) {
-        return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_SCREEN_GESTURE, user)
+    public boolean wakeLockScreenGestureEnabled(int user) {
+        return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, user)
+                && wakeScreenGestureAvailable();
+    }
+
+    /** {@hide} */
+    public boolean wakeDisplayGestureEnabled(int user) {
+        return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE, user)
                 && wakeScreenGestureAvailable();
     }
 
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 8596af10..12b285a 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -262,7 +262,7 @@
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
-    public void enroll(byte[] token, CancellationSignal cancel,
+    public void enroll(int userId, byte[] token, CancellationSignal cancel,
             EnrollmentCallback callback, int[] disabledFeatures) {
         if (callback == null) {
             throw new IllegalArgumentException("Must supply an enrollment callback");
@@ -281,7 +281,7 @@
             try {
                 mEnrollmentCallback = callback;
                 Trace.beginSection("FaceManager#enroll");
-                mService.enroll(mToken, token, mServiceReceiver,
+                mService.enroll(userId, mToken, token, mServiceReceiver,
                         mContext.getOpPackageName(), disabledFeatures);
             } catch (RemoteException e) {
                 Log.w(TAG, "Remote exception in enroll: ", e);
@@ -339,12 +339,13 @@
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
-    public void setFeature(int feature, boolean enabled, byte[] token,
+    public void setFeature(int userId, int feature, boolean enabled, byte[] token,
             SetFeatureCallback callback) {
         if (mService != null) {
             try {
                 mSetFeatureCallback = callback;
-                mService.setFeature(feature, enabled, token, mServiceReceiver);
+                mService.setFeature(userId, feature, enabled, token, mServiceReceiver,
+                        mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -355,11 +356,11 @@
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
-    public void getFeature(int feature, GetFeatureCallback callback) {
+    public void getFeature(int userId, int feature, GetFeatureCallback callback) {
         if (mService != null) {
             try {
                 mGetFeatureCallback = callback;
-                mService.getFeature(feature, mServiceReceiver);
+                mService.getFeature(userId, feature, mServiceReceiver, mContext.getOpPackageName());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -414,7 +415,8 @@
             try {
                 mRemovalCallback = callback;
                 mRemovalFace = face;
-                mService.remove(mToken, face.getBiometricId(), userId, mServiceReceiver);
+                mService.remove(mToken, face.getBiometricId(), userId, mServiceReceiver,
+                        mContext.getOpPackageName());
             } catch (RemoteException e) {
                 Log.w(TAG, "Remote exception in remove: ", e);
                 if (callback != null) {
@@ -637,7 +639,7 @@
             }
         }
         Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode);
-        return null;
+        return "";
     }
 
     /**
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 601be75..b6a0afb 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -50,14 +50,15 @@
             int callingUid, int callingPid, int callingUserId, boolean fromClient);
 
     // Start face enrollment
-    void enroll(IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
+    void enroll(int userId, IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
             String opPackageName, in int [] disabledFeatures);
 
     // Cancel enrollment in progress
     void cancelEnrollment(IBinder token);
 
     // Any errors resulting from this call will be returned to the listener
-    void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver);
+    void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver,
+            String opPackageName);
 
     // Rename the face specified by faceId to the given name
     void rename(int faceId, String name);
@@ -98,10 +99,10 @@
     // Enumerate all faces
     void enumerate(IBinder token, int userId, IFaceServiceReceiver receiver);
 
-    void setFeature(int feature, boolean enabled, in byte [] token,
-            IFaceServiceReceiver receiver);
+    void setFeature(int userId, int feature, boolean enabled, in byte [] token,
+            IFaceServiceReceiver receiver, String opPackageName);
 
-    void getFeature(int feature, IFaceServiceReceiver receiver);
+    void getFeature(int userId, int feature, IFaceServiceReceiver receiver, String opPackageName);
 
     void userActivity();
 }
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index d05ba79..972ae2a 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -35,8 +35,10 @@
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -61,7 +63,31 @@
 
     private static final int INVALID_PHYSICAL_ADDRESS = 0xFFFF;
 
-    private int mPhysicalAddress = INVALID_PHYSICAL_ADDRESS;
+    /**
+     * A cache of the current device's physical address. When device's HDMI out port
+     * is not connected to any device, it is set to {@link #INVALID_PHYSICAL_ADDRESS}.
+     *
+     * <p>Otherwise it is updated by the {@link ClientHotplugEventListener} registered
+     * with {@link com.android.server.hdmi.HdmiControlService} by the
+     * {@link #addHotplugEventListener(HotplugEventListener)} and the address is from
+     * {@link com.android.server.hdmi.HdmiControlService#getPortInfo()}
+     */
+    @GuardedBy("mLock")
+    private int mLocalPhysicalAddress = INVALID_PHYSICAL_ADDRESS;
+
+    private void setLocalPhysicalAddress(int physicalAddress) {
+        synchronized (mLock) {
+            mLocalPhysicalAddress = physicalAddress;
+        }
+    }
+
+    private int getLocalPhysicalAddress() {
+        synchronized (mLock) {
+            return mLocalPhysicalAddress;
+        }
+    }
+
+    private final Object mLock = new Object();
 
     /**
      * Broadcast Action: Display OSD message.
@@ -318,6 +344,37 @@
         mHasSwitchDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
         mIsSwitchDevice = SystemProperties.getBoolean(
             PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH, false);
+        addHotplugEventListener(new ClientHotplugEventListener());
+    }
+
+    private final class ClientHotplugEventListener implements HotplugEventListener {
+
+        @Override
+        public void onReceived(HdmiHotplugEvent event) {
+            List<HdmiPortInfo> ports = new ArrayList<>();
+            try {
+                ports = mService.getPortInfo();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            if (ports.isEmpty()) {
+                Log.e(TAG, "Can't find port info, not updating connected status. "
+                        + "Hotplug event:" + event);
+                return;
+            }
+            // If the HDMI OUT port is plugged or unplugged, update the mLocalPhysicalAddress
+            for (HdmiPortInfo port : ports) {
+                if (port.getId() == event.getPort()) {
+                    if (port.getType() == HdmiPortInfo.PORT_OUTPUT) {
+                        setLocalPhysicalAddress(
+                                event.isConnected()
+                                ? port.getAddress()
+                                : INVALID_PHYSICAL_ADDRESS);
+                    }
+                    break;
+                }
+            }
+        }
     }
 
     private static boolean hasDeviceType(int[] types, int type) {
@@ -616,15 +673,7 @@
      */
     @SystemApi
     public int getPhysicalAddress() {
-        if (mPhysicalAddress != INVALID_PHYSICAL_ADDRESS) {
-            return mPhysicalAddress;
-        }
-        try {
-            mPhysicalAddress = mService.getPhysicalAddress();
-            return mPhysicalAddress;
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        return getLocalPhysicalAddress();
     }
 
     /**
@@ -641,15 +690,15 @@
     @SystemApi
     public boolean isDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) {
         Preconditions.checkNotNull(targetDevice);
-        mPhysicalAddress = getPhysicalAddress();
-        if (mPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
+        int physicalAddress = getLocalPhysicalAddress();
+        if (physicalAddress == INVALID_PHYSICAL_ADDRESS) {
             return false;
         }
         int targetPhysicalAddress = targetDevice.getPhysicalAddress();
         if (targetPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
             return false;
         }
-        return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, mPhysicalAddress)
+        return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, physicalAddress)
             != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE;
     }
 
@@ -662,15 +711,15 @@
     @SystemApi
     public boolean isRemoteDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) {
         Preconditions.checkNotNull(targetDevice);
-        mPhysicalAddress = getPhysicalAddress();
-        if (mPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
+        int physicalAddress = getLocalPhysicalAddress();
+        if (physicalAddress == INVALID_PHYSICAL_ADDRESS) {
             return false;
         }
         int targetPhysicalAddress = targetDevice.getPhysicalAddress();
         if (targetPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
             return false;
         }
-        return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, mPhysicalAddress)
+        return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, physicalAddress)
             != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE;
     }
 
diff --git a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
index df231e6..f13326b 100644
--- a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
+++ b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java
@@ -73,8 +73,12 @@
     }
 
     /**
-     * Performs the feature 'one touch play' from playback device to turn on display
-     * and switch the input.
+     * Performs the feature 'one touch play' from playback device to turn on display and claim
+     * to be the streaming source.
+     *
+     * <p>Client side is responsible to send out intent to choose whichever internal
+     * source on the current device it would like to switch to. Otherwise the current
+     * device will remain on the current input.
      *
      * @param callback {@link OneTouchPlayCallback} object to get informed
      *         of the result
diff --git a/core/java/android/hardware/hdmi/HdmiPortInfo.java b/core/java/android/hardware/hdmi/HdmiPortInfo.java
index f17cfba..f53f458 100644
--- a/core/java/android/hardware/hdmi/HdmiPortInfo.java
+++ b/core/java/android/hardware/hdmi/HdmiPortInfo.java
@@ -166,6 +166,7 @@
     public String toString() {
         StringBuffer s = new StringBuffer();
         s.append("port_id: ").append(mId).append(", ");
+        s.append("type: ").append((mType == PORT_INPUT) ? "HDMI_IN" : "HDMI_OUT").append(", ");
         s.append("address: ").append(String.format("0x%04x", mAddress)).append(", ");
         s.append("cec: ").append(mCecSupported).append(", ");
         s.append("arc: ").append(mArcSupported).append(", ");
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 71297c1..1a5cdd9 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -52,6 +52,8 @@
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
 
+    private final Object mLock = new Object();
+
     /**
      * UsbDevice should only be instantiated by UsbService implementation
      * @hide
@@ -62,13 +64,23 @@
 
     /* package */ boolean open(String name, ParcelFileDescriptor pfd, @NonNull Context context) {
         mContext = context.getApplicationContext();
-        boolean wasOpened = native_open(name, pfd.getFileDescriptor());
 
-        if (wasOpened) {
-            mCloseGuard.open("close");
+        synchronized (mLock) {
+            boolean wasOpened = native_open(name, pfd.getFileDescriptor());
+
+            if (wasOpened) {
+                mCloseGuard.open("close");
+            }
+
+            return wasOpened;
         }
+    }
 
-        return wasOpened;
+    /***
+     * @return If this connection is currently open and usable.
+     */
+    boolean isOpen() {
+        return mNativeContext != 0;
     }
 
     /**
@@ -81,15 +93,32 @@
     }
 
     /**
+     * Cancel a request which relates to this connection.
+     *
+     * @return true if the request was successfully cancelled.
+     */
+    /* package */ boolean cancelRequest(UsbRequest request) {
+        synchronized (mLock) {
+            if (!isOpen()) {
+                return false;
+            }
+
+            return request.cancelIfOpen();
+        }
+    }
+
+    /**
      * Releases all system resources related to the device.
      * Once the object is closed it cannot be used again.
      * The client must call {@link UsbManager#openDevice} again
      * to retrieve a new instance to reestablish communication with the device.
      */
     public void close() {
-        if (mNativeContext != 0) {
-            native_close();
-            mCloseGuard.close();
+        synchronized (mLock) {
+            if (isOpen()) {
+                native_close();
+                mCloseGuard.close();
+            }
         }
     }
 
diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
index 7abf3e9..cc4ba08 100644
--- a/core/java/android/hardware/usb/UsbRequest.java
+++ b/core/java/android/hardware/usb/UsbRequest.java
@@ -362,6 +362,30 @@
      * @return true if cancelling succeeded
      */
     public boolean cancel() {
+        if (mConnection == null) {
+            return false;
+        }
+
+        return mConnection.cancelRequest(this);
+    }
+
+    /**
+     * Cancels a pending queue operation (for use when the UsbDeviceConnection associated
+     * with this request is synchronized). This ensures we don't have a race where the
+     * device is closed and then the request is canceled which would lead to a
+     * use-after-free because the cancel operation uses the device connection
+     * information freed in the when UsbDeviceConnection is closed.<br/>
+     *
+     * This method assumes the connected is not closed while this method is executed.
+     *
+     * @return true if cancelling succeeded.
+     */
+    /* package */ boolean cancelIfOpen() {
+        if (mNativeContext == 0 || (mConnection != null && !mConnection.isOpen())) {
+            Log.w(TAG,
+                    "Detected attempt to cancel a request on a connection which isn't open");
+            return false;
+        }
         return native_cancel();
     }
 
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index fbfbfc0..111a8c4 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -655,7 +655,7 @@
      * {@hide}
      */
     @Deprecated
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
+    @UnsupportedAppUsage
     public static final int TYPE_WIFI_P2P    = 13;
 
     /**
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 7a85dcb..0b1a845 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -34,6 +34,7 @@
 import android.annotation.Nullable;
 import android.os.CancellationSignal;
 import android.os.Looper;
+import android.os.MessageQueue;
 import android.system.ErrnoException;
 import android.util.Log;
 
@@ -466,10 +467,20 @@
     private void registerFDListener(@NonNull Executor executor,
             @NonNull FileDescriptor queryfd, @NonNull Callback<? super byte[]> answerCallback,
             @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
-        Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener(
+        final MessageQueue mainThreadMessageQueue = Looper.getMainLooper().getQueue();
+        mainThreadMessageQueue.addOnFileDescriptorEventListener(
                 queryfd,
                 FD_EVENTS,
                 (fd, events) -> {
+                    // b/134310704
+                    // Unregister fd event listener before resNetworkResult is called to prevent
+                    // race condition caused by fd reused.
+                    // For example when querying v4 and v6, it's possible that the first query ends
+                    // and the fd is closed before the second request starts, which might return
+                    // the same fd for the second request. By that time, the looper must have
+                    // unregistered the fd, otherwise another event listener can't be registered.
+                    mainThreadMessageQueue.removeOnFileDescriptorEventListener(fd);
+
                     executor.execute(() -> {
                         DnsResponse resp = null;
                         ErrnoException exception = null;
@@ -490,7 +501,11 @@
                         }
                         answerCallback.onAnswer(resp.answerbuf, resp.rcode);
                     });
-                    // Unregister this fd listener
+
+                    // The file descriptor has already been unregistered, so it does not really
+                    // matter what is returned here. In spirit 0 (meaning "unregister this FD")
+                    // is still the closest to what the looper needs to do. When returning 0,
+                    // Looper knows to ignore the fd if it has already been unregistered.
                     return 0;
                 });
     }
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 41efc50..9994f9f 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -66,9 +66,9 @@
     /** Force update of ifaces. */
     void forceUpdateIfaces(
          in Network[] defaultNetworks,
-         in VpnInfo[] vpnArray,
          in NetworkState[] networkStates,
-         in String activeIface);
+         in String activeIface,
+         in VpnInfo[] vpnInfos);
     /** Force update of statistics. */
     @UnsupportedAppUsage
     void forceUpdate();
diff --git a/core/java/android/net/IpSecConfig.java b/core/java/android/net/IpSecConfig.java
index a64014f..575c5ed 100644
--- a/core/java/android/net/IpSecConfig.java
+++ b/core/java/android/net/IpSecConfig.java
@@ -15,6 +15,7 @@
  */
 package android.net;
 
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -333,25 +334,25 @@
                 }
             };
 
-    @VisibleForTesting
-    /** Equals method used for testing */
-    public static boolean equals(IpSecConfig lhs, IpSecConfig rhs) {
-        if (lhs == null || rhs == null) return (lhs == rhs);
-        return (lhs.mMode == rhs.mMode
-                && lhs.mSourceAddress.equals(rhs.mSourceAddress)
-                && lhs.mDestinationAddress.equals(rhs.mDestinationAddress)
-                && ((lhs.mNetwork != null && lhs.mNetwork.equals(rhs.mNetwork))
-                        || (lhs.mNetwork == rhs.mNetwork))
-                && lhs.mEncapType == rhs.mEncapType
-                && lhs.mEncapSocketResourceId == rhs.mEncapSocketResourceId
-                && lhs.mEncapRemotePort == rhs.mEncapRemotePort
-                && lhs.mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
-                && lhs.mSpiResourceId == rhs.mSpiResourceId
-                && IpSecAlgorithm.equals(lhs.mEncryption, rhs.mEncryption)
-                && IpSecAlgorithm.equals(lhs.mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
-                && IpSecAlgorithm.equals(lhs.mAuthentication, rhs.mAuthentication)
-                && lhs.mMarkValue == rhs.mMarkValue
-                && lhs.mMarkMask == rhs.mMarkMask
-                && lhs.mXfrmInterfaceId == rhs.mXfrmInterfaceId);
+    @Override
+    public boolean equals(@Nullable Object other) {
+        if (!(other instanceof IpSecConfig)) return false;
+        final IpSecConfig rhs = (IpSecConfig) other;
+        return (mMode == rhs.mMode
+                && mSourceAddress.equals(rhs.mSourceAddress)
+                && mDestinationAddress.equals(rhs.mDestinationAddress)
+                && ((mNetwork != null && mNetwork.equals(rhs.mNetwork))
+                        || (mNetwork == rhs.mNetwork))
+                && mEncapType == rhs.mEncapType
+                && mEncapSocketResourceId == rhs.mEncapSocketResourceId
+                && mEncapRemotePort == rhs.mEncapRemotePort
+                && mNattKeepaliveInterval == rhs.mNattKeepaliveInterval
+                && mSpiResourceId == rhs.mSpiResourceId
+                && IpSecAlgorithm.equals(mEncryption, rhs.mEncryption)
+                && IpSecAlgorithm.equals(mAuthenticatedEncryption, rhs.mAuthenticatedEncryption)
+                && IpSecAlgorithm.equals(mAuthentication, rhs.mAuthentication)
+                && mMarkValue == rhs.mMarkValue
+                && mMarkMask == rhs.mMarkMask
+                && mXfrmInterfaceId == rhs.mXfrmInterfaceId);
     }
 }
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index 36111f2..44a0a4f 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -151,15 +151,13 @@
     }
 
     /**
-     * Equals method used for testing
-     *
-     * @hide
+     * Standard equals.
      */
-    @VisibleForTesting
-    public static boolean equals(IpSecTransform lhs, IpSecTransform rhs) {
-        if (lhs == null || rhs == null) return (lhs == rhs);
-        return IpSecConfig.equals(lhs.getConfig(), rhs.getConfig())
-                && lhs.mResourceId == rhs.mResourceId;
+    public boolean equals(Object other) {
+        if (this == other) return true;
+        if (!(other instanceof IpSecTransform)) return false;
+        final IpSecTransform rhs = (IpSecTransform) other;
+        return getConfig().equals(rhs.getConfig()) && mResourceId == rhs.mResourceId;
     }
 
     /**
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/core/java/android/net/NattKeepalivePacketData.java
new file mode 100644
index 0000000..a77c244
--- /dev/null
+++ b/core/java/android/net/NattKeepalivePacketData.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
+import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
+
+import android.net.SocketKeepalive.InvalidPacketException;
+import android.net.util.IpUtils;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.system.OsConstants;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/** @hide */
+public final class NattKeepalivePacketData extends KeepalivePacketData implements Parcelable {
+    // This should only be constructed via static factory methods, such as
+    // nattKeepalivePacket
+    private NattKeepalivePacketData(InetAddress srcAddress, int srcPort,
+            InetAddress dstAddress, int dstPort, byte[] data) throws
+            InvalidPacketException {
+        super(srcAddress, srcPort, dstAddress, dstPort, data);
+    }
+
+    /**
+     * Factory method to create Nat-T keepalive packet structure.
+     */
+    public static NattKeepalivePacketData nattKeepalivePacket(
+            InetAddress srcAddress, int srcPort, InetAddress dstAddress, int dstPort)
+            throws InvalidPacketException {
+
+        if (!(srcAddress instanceof Inet4Address) || !(dstAddress instanceof Inet4Address)) {
+            throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
+        }
+
+        if (dstPort != NattSocketKeepalive.NATT_PORT) {
+            throw new InvalidPacketException(ERROR_INVALID_PORT);
+        }
+
+        int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1;
+        ByteBuffer buf = ByteBuffer.allocate(length);
+        buf.order(ByteOrder.BIG_ENDIAN);
+        buf.putShort((short) 0x4500);             // IP version and TOS
+        buf.putShort((short) length);
+        buf.putInt(0);                            // ID, flags, offset
+        buf.put((byte) 64);                       // TTL
+        buf.put((byte) OsConstants.IPPROTO_UDP);
+        int ipChecksumOffset = buf.position();
+        buf.putShort((short) 0);                  // IP checksum
+        buf.put(srcAddress.getAddress());
+        buf.put(dstAddress.getAddress());
+        buf.putShort((short) srcPort);
+        buf.putShort((short) dstPort);
+        buf.putShort((short) (length - 20));      // UDP length
+        int udpChecksumOffset = buf.position();
+        buf.putShort((short) 0);                  // UDP checksum
+        buf.put((byte) 0xff);                     // NAT-T keepalive
+        buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
+        buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_LENGTH));
+
+        return new NattKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
+    }
+
+    /** Parcelable Implementation */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Write to parcel */
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(srcAddress.getHostAddress());
+        out.writeString(dstAddress.getHostAddress());
+        out.writeInt(srcPort);
+        out.writeInt(dstPort);
+    }
+
+    /** Parcelable Creator */
+    public static final Parcelable.Creator<NattKeepalivePacketData> CREATOR =
+            new Parcelable.Creator<NattKeepalivePacketData>() {
+                public NattKeepalivePacketData createFromParcel(Parcel in) {
+                    final InetAddress srcAddress =
+                            InetAddresses.parseNumericAddress(in.readString());
+                    final InetAddress dstAddress =
+                            InetAddresses.parseNumericAddress(in.readString());
+                    final int srcPort = in.readInt();
+                    final int dstPort = in.readInt();
+                    try {
+                        return NattKeepalivePacketData.nattKeepalivePacket(srcAddress, srcPort,
+                                    dstAddress, dstPort);
+                    } catch (InvalidPacketException e) {
+                        throw new IllegalArgumentException(
+                                "Invalid NAT-T keepalive data: " + e.error);
+                    }
+                }
+
+                public NattKeepalivePacketData[] newArray(int size) {
+                    return new NattKeepalivePacketData[size];
+                }
+            };
+}
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 49b4e56..43ea589 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -433,7 +433,32 @@
      * {@link #saveAcceptUnvalidated} to respect the user's choice.
      */
     public void explicitlySelected(boolean acceptUnvalidated) {
-        queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED, acceptUnvalidated ? 1 : 0, 0);
+        explicitlySelected(true /* explicitlySelected */, acceptUnvalidated);
+    }
+
+    /**
+     * Called by the bearer to indicate whether the network was manually selected by the user.
+     * This should be called before the NetworkInfo is marked CONNECTED so that this
+     * Network can be given special treatment at that time.
+     *
+     * If {@code explicitlySelected} is {@code true}, and {@code acceptUnvalidated} is {@code true},
+     * then the system will switch to this network. If {@code explicitlySelected} is {@code true}
+     * and {@code acceptUnvalidated} is {@code false}, and the  network cannot be validated, the
+     * system will ask the user whether to switch to this network.  If the user confirms and selects
+     * "don't ask again", then the system will call {@link #saveAcceptUnvalidated} to persist the
+     * user's choice. Thus, if the transport ever calls this method with {@code explicitlySelected}
+     * set to {@code true} and {@code acceptUnvalidated} set to {@code false}, it must also
+     * implement {@link #saveAcceptUnvalidated} to respect the user's choice.
+     *
+     * If  {@code explicitlySelected} is {@code false} and {@code acceptUnvalidated} is
+     * {@code true}, the system will interpret this as the user having accepted partial connectivity
+     * on this network. Thus, the system will switch to the network and consider it validated even
+     * if it only provides partial connectivity, but the network is not otherwise treated specially.
+     */
+    public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) {
+        queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED,
+                explicitlySelected ? 1 : 0,
+                acceptUnvalidated ? 1 : 0);
     }
 
     /**
@@ -510,7 +535,6 @@
      * override this method.
      */
     protected void addKeepalivePacketFilter(Message msg) {
-        onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
     }
 
     /**
@@ -519,7 +543,6 @@
      * must override this method.
      */
     protected void removeKeepalivePacketFilter(Message msg) {
-        onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
     }
 
     /**
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index bb344e2..6c7aa13 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -23,7 +23,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
-import android.util.Slog;
 import android.util.SparseBooleanArray;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -34,10 +33,10 @@
 import java.io.CharArrayWriter;
 import java.io.PrintWriter;
 import java.util.Arrays;
-import java.util.function.Predicate;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Objects;
+import java.util.function.Predicate;
 
 /**
  * Collection of active network statistics. Can contain summary details across
@@ -996,8 +995,8 @@
             return;
         }
         filter(e -> (limitUid == UID_ALL || limitUid == e.uid)
-            && (limitTag == TAG_ALL || limitTag == e.tag)
-            && (limitIfaces == INTERFACES_ALL
+                && (limitTag == TAG_ALL || limitTag == e.tag)
+                && (limitIfaces == INTERFACES_ALL
                     || ArrayUtils.contains(limitIfaces, e.iface)));
     }
 
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index ae421a4..87c7118 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -48,6 +48,7 @@
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -481,17 +482,39 @@
      * For example, given an incoming template matching B, and the currently
      * active merge set [A,B], we'd return a new template that primarily matches
      * A, but also matches B.
+     * TODO: remove and use {@link #normalize(NetworkTemplate, List)}.
      */
     @UnsupportedAppUsage
     public static NetworkTemplate normalize(NetworkTemplate template, String[] merged) {
-        if (template.isMatchRuleMobile() && ArrayUtils.contains(merged, template.mSubscriberId)) {
-            // Requested template subscriber is part of the merge group; return
-            // a template that matches all merged subscribers.
-            return new NetworkTemplate(template.mMatchRule, merged[0], merged,
-                    template.mNetworkId);
-        } else {
-            return template;
+        return normalize(template, Arrays.<String[]>asList(merged));
+    }
+
+    /**
+     * Examine the given template and normalize if it refers to a "merged"
+     * mobile subscriber. We pick the "lowest" merged subscriber as the primary
+     * for key purposes, and expand the template to match all other merged
+     * subscribers.
+     *
+     * There can be multiple merged subscriberIds for multi-SIM devices.
+     *
+     * <p>
+     * For example, given an incoming template matching B, and the currently
+     * active merge set [A,B], we'd return a new template that primarily matches
+     * A, but also matches B.
+     */
+    public static NetworkTemplate normalize(NetworkTemplate template, List<String[]> mergedList) {
+        if (!template.isMatchRuleMobile()) return template;
+
+        for (String[] merged : mergedList) {
+            if (ArrayUtils.contains(merged, template.mSubscriberId)) {
+                // Requested template subscriber is part of the merge group; return
+                // a template that matches all merged subscribers.
+                return new NetworkTemplate(template.mMatchRule, merged[0], merged,
+                        template.mNetworkId);
+            }
         }
+
+        return template;
     }
 
     @UnsupportedAppUsage
diff --git a/core/java/android/net/SocketKeepalive.java b/core/java/android/net/SocketKeepalive.java
index 46eddde..ec73866 100644
--- a/core/java/android/net/SocketKeepalive.java
+++ b/core/java/android/net/SocketKeepalive.java
@@ -44,9 +44,11 @@
  * {@link SocketKeepalive.Callback#onStopped} if the operation was successful or
  * {@link SocketKeepalive.Callback#onError} if an error occurred.
  *
- * The device SHOULD support keepalive offload. If it does not, it MUST reply with
+ * For cellular, the device MUST support at least 1 keepalive slot.
+ *
+ * For WiFi, the device SHOULD support keepalive offload. If it does not, it MUST reply with
  * {@link SocketKeepalive.Callback#onError} with {@code ERROR_UNSUPPORTED} to any keepalive offload
- * request. If it does, it MUST support at least 3 concurrent keepalive slots per transport.
+ * request. If it does, it MUST support at least 3 concurrent keepalive slots.
  */
 public abstract class SocketKeepalive implements AutoCloseable {
     static final String TAG = "SocketKeepalive";
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 8cf182b4..44d977a 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1983,13 +1983,9 @@
      */
     static abstract class AbstractPart {
 
-        /**
-         * Enum which indicates which representation of a given part we have.
-         */
-        static class Representation {
-            static final int ENCODED = 1;
-            static final int DECODED = 2;
-        }
+        // Possible values of mCanonicalRepresentation.
+        static final int REPRESENTATION_ENCODED = 1;
+        static final int REPRESENTATION_DECODED = 2;
 
         volatile String encoded;
         volatile String decoded;
@@ -1997,11 +1993,11 @@
 
         AbstractPart(String encoded, String decoded) {
             if (encoded != NOT_CACHED) {
-                this.mCanonicalRepresentation = Representation.ENCODED;
+                this.mCanonicalRepresentation = REPRESENTATION_ENCODED;
                 this.encoded = encoded;
                 this.decoded = NOT_CACHED;
             } else if (decoded != NOT_CACHED) {
-                this.mCanonicalRepresentation = Representation.DECODED;
+                this.mCanonicalRepresentation = REPRESENTATION_DECODED;
                 this.encoded = NOT_CACHED;
                 this.decoded = decoded;
             } else {
@@ -2019,9 +2015,9 @@
 
         final void writeTo(Parcel parcel) {
             final String canonicalValue;
-            if (mCanonicalRepresentation == Representation.ENCODED) {
+            if (mCanonicalRepresentation == REPRESENTATION_ENCODED) {
                 canonicalValue = encoded;
-            } else if (mCanonicalRepresentation == Representation.DECODED) {
+            } else if (mCanonicalRepresentation == REPRESENTATION_DECODED) {
                 canonicalValue = decoded;
             } else {
                 throw new IllegalArgumentException("Unknown representation: "
@@ -2066,9 +2062,9 @@
             int representation = parcel.readInt();
             String value = parcel.readString();
             switch (representation) {
-                case Representation.ENCODED:
+                case REPRESENTATION_ENCODED:
                     return fromEncoded(value);
-                case Representation.DECODED:
+                case REPRESENTATION_DECODED:
                     return fromDecoded(value);
                 default:
                     throw new IllegalArgumentException("Unknown representation: "
@@ -2254,9 +2250,9 @@
         static PathPart readFrom(Parcel parcel) {
             int representation = parcel.readInt();
             switch (representation) {
-                case Representation.ENCODED:
+                case REPRESENTATION_ENCODED:
                     return fromEncoded(parcel.readString());
-                case Representation.DECODED:
+                case REPRESENTATION_DECODED:
                     return fromDecoded(parcel.readString());
                 default:
                     throw new IllegalArgumentException("Unknown representation: " + representation);
diff --git a/core/java/android/net/util/KeepaliveUtils.java b/core/java/android/net/util/KeepaliveUtils.java
index 569fed1..bfc4563 100644
--- a/core/java/android/net/util/KeepaliveUtils.java
+++ b/core/java/android/net/util/KeepaliveUtils.java
@@ -34,9 +34,6 @@
 
     public static final String TAG = "KeepaliveUtils";
 
-    // Minimum supported keepalive count per transport if the network supports keepalive.
-    public static final int MIN_SUPPORTED_KEEPALIVE_COUNT = 3;
-
     public static class KeepaliveDeviceConfigurationException extends AndroidRuntimeException {
         public KeepaliveDeviceConfigurationException(final String msg) {
             super(msg);
@@ -84,10 +81,7 @@
                 throw new KeepaliveDeviceConfigurationException("Invalid transport " + transport);
             }
 
-            // Customized values should be either 0 to indicate the network doesn't support
-            // keepalive offload, or a positive value that is at least
-            // MIN_SUPPORTED_KEEPALIVE_COUNT if supported.
-            if (supported != 0 && supported < MIN_SUPPORTED_KEEPALIVE_COUNT) {
+            if (supported < 0) {
                 throw new KeepaliveDeviceConfigurationException(
                         "Invalid supported count " + supported + " for "
                                 + NetworkCapabilities.transportNameOf(transport));
diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
index 1364d8c..489a292 100644
--- a/core/java/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -69,7 +69,10 @@
      */
     @NonNull
     public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex) {
-        return new PacketSocketAddress((short) protocol, ifIndex);
+        return new PacketSocketAddress(
+                protocol /* sll_protocol */,
+                ifIndex /* sll_ifindex */,
+                null /* sll_addr */);
     }
 
     /**
@@ -77,7 +80,10 @@
      */
     @NonNull
     public static SocketAddress makePacketSocketAddress(int ifIndex, @NonNull byte[] hwAddr) {
-        return new PacketSocketAddress(ifIndex, hwAddr);
+        return new PacketSocketAddress(
+                0 /* sll_protocol */,
+                ifIndex /* sll_ifindex */,
+                hwAddr /* sll_addr */);
     }
 
     /**
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index ecd16dd..caa6a43 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1554,7 +1554,10 @@
         }
     }
 
-    public final static class HistoryItem implements Parcelable {
+    /**
+     * Battery history record.
+     */
+    public static final class HistoryItem {
         public HistoryItem next;
 
         // The time of this event in milliseconds, as per SystemClock.elapsedRealtime().
@@ -1789,16 +1792,10 @@
         public HistoryItem() {
         }
 
-        public HistoryItem(long time, Parcel src) {
-            this.time = time;
-            numReadInts = 2;
+        public HistoryItem(Parcel src) {
             readFromParcel(src);
         }
 
-        public int describeContents() {
-            return 0;
-        }
-
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeLong(time);
             int bat = (((int)cmd)&0xff)
@@ -1835,6 +1832,7 @@
 
         public void readFromParcel(Parcel src) {
             int start = src.dataPosition();
+            time = src.readLong();
             int bat = src.readInt();
             cmd = (byte)(bat&0xff);
             batteryLevel = (byte)((bat>>8)&0xff);
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 9f4118e..b3125d8 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1191,7 +1191,7 @@
         ArrayList<Partition> partitions = new ArrayList();
 
         String[] names = new String[] {
-            "bootimage", "odm", "product", "product_services", Partition.PARTITION_NAME_SYSTEM,
+            "bootimage", "odm", "product", "system_ext", Partition.PARTITION_NAME_SYSTEM,
             "vendor"
         };
         for (String name : names) {
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 3716b3e..3462d1f 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -25,6 +26,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
 import android.provider.MediaStore;
@@ -52,7 +54,7 @@
     private static final String ENV_ODM_ROOT = "ODM_ROOT";
     private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT";
     private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT";
-    private static final String ENV_PRODUCT_SERVICES_ROOT = "PRODUCT_SERVICES_ROOT";
+    private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT";
 
     /** {@hide} */
     public static final String DIR_ANDROID = "Android";
@@ -75,8 +77,8 @@
     private static final File DIR_ODM_ROOT = getDirectory(ENV_ODM_ROOT, "/odm");
     private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
     private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product");
-    private static final File DIR_PRODUCT_SERVICES_ROOT = getDirectory(ENV_PRODUCT_SERVICES_ROOT,
-                                                           "/product_services");
+    private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT,
+                                                           "/system_ext");
 
     @UnsupportedAppUsage
     private static UserEnvironment sCurrentUser;
@@ -220,11 +222,26 @@
      * Return root directory of the "product_services" partition holding middleware
      * services if any. If present, the partition is mounted read-only.
      *
+     * @deprecated This directory is not guaranteed to exist.
+     *             Its name is changed to "system_ext" because the partition's purpose is changed.
+     *             {@link #getSystemExtDirectory()}
      * @hide
      */
     @SystemApi
+    @Deprecated
     public static @NonNull File getProductServicesDirectory() {
-        return DIR_PRODUCT_SERVICES_ROOT;
+        return getDirectory("PRODUCT_SERVICES_ROOT", "/product_services");
+    }
+
+    /**
+     * Return root directory of the "system_ext" partition holding system partition's extension
+     * If present, the partition is mounted read-only.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static @NonNull File getSystemExtDirectory() {
+        return DIR_SYSTEM_EXT_ROOT;
     }
 
     /**
@@ -1159,11 +1176,36 @@
      */
     public static boolean isExternalStorageLegacy(@NonNull File path) {
         final Context context = AppGlobals.getInitialApplication();
+        final int uid = context.getApplicationInfo().uid;
+        if (Process.isIsolated(uid)) {
+            return false;
+        }
+
+        final PackageManager packageManager = context.getPackageManager();
+        if (packageManager.isInstantApp()) {
+            return false;
+        }
+
+        if (packageManager.checkPermission(Manifest.permission.WRITE_MEDIA_STORAGE,
+                context.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
+            return true;
+        }
+
+        if (packageManager.checkPermission(Manifest.permission.INSTALL_PACKAGES,
+                context.getPackageName()) == PackageManager.PERMISSION_GRANTED) {
+            return true;
+        }
         final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+        final String[] packagesForUid = packageManager.getPackagesForUid(uid);
+        for (String packageName : packagesForUid) {
+            if (appOps.checkOpNoThrow(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
+                    uid, packageName) == AppOpsManager.MODE_ALLOWED) {
+                return true;
+            }
+        }
 
         return appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE,
-                context.getApplicationInfo().uid,
-                context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED;
+                uid, context.getOpPackageName()) == AppOpsManager.MODE_ALLOWED;
     }
 
     static File getDirectory(String variableName, String defaultPath) {
diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java
index b93bef8..37ca868 100644
--- a/core/java/android/os/ExternalVibration.java
+++ b/core/java/android/os/ExternalVibration.java
@@ -114,6 +114,24 @@
         return true;
     }
 
+    /**
+     * Links a recipient to death against this external vibration token
+     */
+    public void linkToDeath(IBinder.DeathRecipient recipient) {
+        try {
+            mToken.linkToDeath(recipient, 0);
+        } catch (RemoteException e) {
+            return;
+        }
+    }
+
+    /**
+     * Unlinks a recipient to death against this external vibration token
+     */
+    public void unlinkToDeath(IBinder.DeathRecipient recipient) {
+        mToken.unlinkToDeath(recipient, 0);
+    }
+
     @Override
     public boolean equals(Object o) {
         if (o == null || !(o instanceof ExternalVibration)) {
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 24a1477..ce1942c 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -33,11 +33,13 @@
 
 import dalvik.system.VMRuntime;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -62,6 +64,7 @@
     private static final String SYSTEM_DRIVER_VERSION_NAME = "";
     private static final long SYSTEM_DRIVER_VERSION_CODE = 0;
     private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+    private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1";
     private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time";
     private static final String METADATA_DRIVER_BUILD_TIME = "com.android.gamedriver.build_time";
     private static final String ANGLE_RULES_FILE = "a4a_rules.json";
@@ -71,16 +74,19 @@
             "android.app.action.ANGLE_FOR_ANDROID_TOAST_MESSAGE";
     private static final String INTENT_KEY_A4A_TOAST_MESSAGE = "A4A Toast Message";
     private static final String GAME_DRIVER_WHITELIST_ALL = "*";
+    private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
     private static final int VULKAN_1_0 = 0x00400000;
     private static final int VULKAN_1_1 = 0x00401000;
 
     // GAME_DRIVER_ALL_APPS
     // 0: Default (Invalid values fallback to default as well)
     // 1: All apps use Game Driver
-    // 2: All apps use system graphics driver
+    // 2: All apps use Prerelease Driver
+    // 3: All apps use system graphics driver
     private static final int GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT = 0;
-    private static final int GAME_DRIVER_GLOBAL_OPT_IN_ALL = 1;
-    private static final int GAME_DRIVER_GLOBAL_OPT_IN_NONE = 2;
+    private static final int GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER = 1;
+    private static final int GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2;
+    private static final int GAME_DRIVER_GLOBAL_OPT_IN_OFF = 3;
 
     private ClassLoader mClassLoader;
     private String mLayerPath;
@@ -114,65 +120,6 @@
     public static native void hintActivityLaunch();
 
     /**
-     * Allow to query whether an application will use Game Driver.
-     */
-    public static boolean shouldUseGameDriver(Context context, Bundle coreSettings,
-            ApplicationInfo applicationInfo) {
-        final String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
-        if (driverPackageName == null || driverPackageName.isEmpty()) {
-            return false;
-        }
-
-        // To minimize risk of driver updates crippling the device beyond user repair, never use an
-        // updated driver for privileged or non-updated system apps. Presumably pre-installed apps
-        // were tested thoroughly with the pre-installed driver.
-        if (applicationInfo.isPrivilegedApp() || (applicationInfo.isSystemApp()
-                && !applicationInfo.isUpdatedSystemApp())) {
-            if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
-            return false;
-        }
-        final ContentResolver contentResolver = context.getContentResolver();
-        final String packageName = applicationInfo.packageName;
-        final int globalOptIn;
-        if (coreSettings != null) {
-            globalOptIn = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
-        } else {
-            globalOptIn = Settings.Global.getInt(contentResolver,
-                    Settings.Global.GAME_DRIVER_ALL_APPS, 0);
-        }
-        if (globalOptIn == GAME_DRIVER_GLOBAL_OPT_IN_ALL) {
-            return true;
-        }
-        if (globalOptIn == GAME_DRIVER_GLOBAL_OPT_IN_NONE) {
-            return false;
-        }
-
-        // GAME_DRIVER_OPT_OUT_APPS has higher priority than GAME_DRIVER_OPT_IN_APPS
-        if (getGlobalSettingsString(contentResolver, coreSettings,
-                Settings.Global.GAME_DRIVER_OPT_OUT_APPS).contains(packageName)) {
-            return false;
-        }
-        final boolean isOptIn = getGlobalSettingsString(contentResolver, coreSettings,
-                Settings.Global.GAME_DRIVER_OPT_IN_APPS).contains(packageName);
-        final List<String> whitelist = getGlobalSettingsString(contentResolver, coreSettings,
-                Settings.Global.GAME_DRIVER_WHITELIST);
-        if (!isOptIn && whitelist.indexOf(GAME_DRIVER_WHITELIST_ALL) != 0
-                && !whitelist.contains(packageName)) {
-            return false;
-        }
-
-        // If the application is not opted-in, then check whether it's on the blacklist,
-        // terminate early if it's on the blacklist and fallback to system driver.
-        if (!isOptIn
-                && getGlobalSettingsString(contentResolver, coreSettings,
-                                       Settings.Global.GAME_DRIVER_BLACKLIST)
-                        .contains(packageName)) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
      * Query to determine if ANGLE should be used
      */
     public static boolean shouldUseAngle(Context context, Bundle coreSettings,
@@ -742,12 +689,102 @@
     }
 
     /**
+     * Return the driver package name to use. Return null for system driver.
+     */
+    private static String chooseDriverInternal(Context context, Bundle coreSettings) {
+        final String gameDriver = SystemProperties.get(PROPERTY_GFX_DRIVER);
+        final boolean hasGameDriver = gameDriver != null && !gameDriver.isEmpty();
+
+        final String prereleaseDriver = SystemProperties.get(PROPERTY_GFX_DRIVER_PRERELEASE);
+        final boolean hasPrereleaseDriver = prereleaseDriver != null && !prereleaseDriver.isEmpty();
+
+        if (!hasGameDriver && !hasPrereleaseDriver) {
+            if (DEBUG) Log.v(TAG, "Neither Game Driver nor prerelease driver is supported.");
+            return null;
+        }
+
+        // To minimize risk of driver updates crippling the device beyond user repair, never use an
+        // updated driver for privileged or non-updated system apps. Presumably pre-installed apps
+        // were tested thoroughly with the pre-installed driver.
+        final ApplicationInfo ai = context.getApplicationInfo();
+        if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
+            if (DEBUG) Log.v(TAG, "Ignoring driver package for privileged/non-updated system app.");
+            return null;
+        }
+
+        // Priority for Game Driver settings global on confliction (Higher priority comes first):
+        // 1. GAME_DRIVER_ALL_APPS
+        // 2. GAME_DRIVER_OPT_OUT_APPS
+        // 3. GAME_DRIVER_PRERELEASE_OPT_IN_APPS
+        // 4. GAME_DRIVER_OPT_IN_APPS
+        // 5. GAME_DRIVER_BLACKLIST
+        // 6. GAME_DRIVER_WHITELIST
+        switch (coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0)) {
+            case GAME_DRIVER_GLOBAL_OPT_IN_OFF:
+                if (DEBUG) Log.v(TAG, "Game Driver is turned off on this device.");
+                return null;
+            case GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER:
+                if (DEBUG) Log.v(TAG, "All apps opt in to use Game Driver.");
+                return hasGameDriver ? gameDriver : null;
+            case GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER:
+                if (DEBUG) Log.v(TAG, "All apps opt in to use prerelease driver.");
+                return hasPrereleaseDriver ? prereleaseDriver : null;
+            case GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT:
+            default:
+                break;
+        }
+
+        final String appPackageName = ai.packageName;
+        if (getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_OPT_OUT_APPS)
+                        .contains(appPackageName)) {
+            if (DEBUG) Log.v(TAG, "App opts out for Game Driver.");
+            return null;
+        }
+
+        if (getGlobalSettingsString(
+                    null, coreSettings, Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS)
+                        .contains(appPackageName)) {
+            if (DEBUG) Log.v(TAG, "App opts in for prerelease Game Driver.");
+            return hasPrereleaseDriver ? prereleaseDriver : null;
+        }
+
+        // Early return here since the rest logic is only for Game Driver.
+        if (!hasGameDriver) {
+            if (DEBUG) Log.v(TAG, "Game Driver is not supported on the device.");
+            return null;
+        }
+
+        final boolean isOptIn =
+                getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
+                        .contains(appPackageName);
+        final List<String> whitelist =
+                getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_WHITELIST);
+        if (!isOptIn && whitelist.indexOf(GAME_DRIVER_WHITELIST_ALL) != 0
+                && !whitelist.contains(appPackageName)) {
+            if (DEBUG) Log.v(TAG, "App is not on the whitelist for Game Driver.");
+            return null;
+        }
+
+        // If the application is not opted-in, then check whether it's on the blacklist,
+        // terminate early if it's on the blacklist and fallback to system driver.
+        if (!isOptIn
+                && getGlobalSettingsString(
+                        null, coreSettings, Settings.Global.GAME_DRIVER_BLACKLIST)
+                           .contains(appPackageName)) {
+            if (DEBUG) Log.v(TAG, "App is on the blacklist for Game Driver.");
+            return null;
+        }
+
+        return gameDriver;
+    }
+
+    /**
      * Choose whether the current process should use the builtin or an updated driver.
      */
     private static boolean chooseDriver(
             Context context, Bundle coreSettings, PackageManager pm, String packageName) {
-        final String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
-        if (driverPackageName == null || driverPackageName.isEmpty()) {
+        final String driverPackageName = chooseDriverInternal(context, coreSettings);
+        if (driverPackageName == null) {
             return false;
         }
 
@@ -770,10 +807,6 @@
             return false;
         }
 
-        if (!shouldUseGameDriver(context, coreSettings, context.getApplicationInfo())) {
-            return false;
-        }
-
         final String abi = chooseAbi(driverAppInfo);
         if (abi == null) {
             if (DEBUG) {
@@ -792,10 +825,7 @@
           .append("!/lib/")
           .append(abi);
         final String paths = sb.toString();
-
-        final String sphalLibraries =
-                coreSettings.getString(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES);
-
+        final String sphalLibraries = getSphalLibraries(context, driverPackageName);
         if (DEBUG) {
             Log.v(TAG,
                     "gfx driver package search path: " + paths
@@ -832,6 +862,29 @@
         return null;
     }
 
+    private static String getSphalLibraries(Context context, String driverPackageName) {
+        try {
+            final Context driverContext =
+                    context.createPackageContext(driverPackageName, Context.CONTEXT_RESTRICTED);
+            final BufferedReader reader = new BufferedReader(new InputStreamReader(
+                    driverContext.getAssets().open(GAME_DRIVER_SPHAL_LIBRARIES_FILENAME)));
+            final ArrayList<String> assetStrings = new ArrayList<>();
+            for (String assetString; (assetString = reader.readLine()) != null;) {
+                assetStrings.add(assetString);
+            }
+            return String.join(":", assetStrings);
+        } catch (PackageManager.NameNotFoundException e) {
+            if (DEBUG) {
+                Log.w(TAG, "Driver package '" + driverPackageName + "' not installed");
+            }
+        } catch (IOException e) {
+            if (DEBUG) {
+                Log.w(TAG, "Failed to load '" + GAME_DRIVER_SPHAL_LIBRARIES_FILENAME + "'");
+            }
+        }
+        return "";
+    }
+
     private static native int getCanLoadSystemLibraries();
     private static native void setLayerPaths(ClassLoader classLoader, String layerPaths);
     private static native void setDebugLayers(String layers);
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 7f60b9c..1351380 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -246,27 +246,6 @@
      **/
 
     /**
-     * Return global network statistics summarized at an interface level,
-     * without any UID-level granularity.
-     */
-    NetworkStats getNetworkStatsSummaryDev();
-    NetworkStats getNetworkStatsSummaryXt();
-
-    /**
-     * Return detailed network statistics with UID-level granularity,
-     * including interface and tag details.
-     */
-    NetworkStats getNetworkStatsDetail();
-
-    /**
-     * Return detailed network statistics for the requested UID and interfaces,
-     * including interface and tag details.
-     * @param uid UID to obtain statistics for, or {@link NetworkStats#UID_ALL}.
-     * @param ifaces Interfaces to obtain statistics for, or {@link NetworkStats#INTERFACES_ALL}.
-     */
-    NetworkStats getNetworkStatsUidDetail(int uid, in String[] ifaces);
-
-    /**
      * Return summary of network statistics all tethering interfaces.
      */
     NetworkStats getNetworkStatsTethering(int how);
diff --git a/core/java/android/os/IServiceManager.java b/core/java/android/os/IServiceManager.java
deleted file mode 100644
index bc0690d..0000000
--- a/core/java/android/os/IServiceManager.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.annotation.UnsupportedAppUsage;
-
-/**
- * Basic interface for finding and publishing system services.
- *
- * An implementation of this interface is usually published as the
- * global context object, which can be retrieved via
- * BinderNative.getContextObject().  An easy way to retrieve this
- * is with the static method BnServiceManager.getDefault().
- *
- * @hide
- */
-public interface IServiceManager extends IInterface
-{
-    /**
-     * Retrieve an existing service called @a name from the
-     * service manager.  Blocks for a few seconds waiting for it to be
-     * published if it does not already exist.
-     */
-    @UnsupportedAppUsage
-    IBinder getService(String name) throws RemoteException;
-
-    /**
-     * Retrieve an existing service called @a name from the
-     * service manager.  Non-blocking.
-     */
-    @UnsupportedAppUsage
-    IBinder checkService(String name) throws RemoteException;
-
-    /**
-     * Place a new @a service called @a name into the service
-     * manager.
-     */
-    void addService(String name, IBinder service, boolean allowIsolated, int dumpFlags)
-            throws RemoteException;
-
-    /**
-     * Return a list of all currently running services.
-     */
-    String[] listServices(int dumpFlags) throws RemoteException;
-
-    /**
-     * Assign a permission controller to the service manager.  After set, this
-     * interface is checked before any services are added.
-     */
-    void setPermissionController(IPermissionController controller)
-            throws RemoteException;
-
-    static final String descriptor = "android.os.IServiceManager";
-
-    int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
-    int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
-    int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
-    int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
-    int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
-    int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5;
-
-    /*
-     * Must update values in IServiceManager.h
-     */
-    /* Allows services to dump sections according to priorities. */
-    int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
-    int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
-    int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
-    /**
-     * Services are by default registered with a DEFAULT dump priority. DEFAULT priority has the
-     * same priority as NORMAL priority but the services are not called with dump priority
-     * arguments.
-     */
-    int DUMP_FLAG_PRIORITY_DEFAULT = 1 << 3;
-    int DUMP_FLAG_PRIORITY_ALL = DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
-            | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PRIORITY_DEFAULT;
-    /* Allows services to dump sections in protobuf format. */
-    int DUMP_FLAG_PROTO = 1 << 4;
-
-}
diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl
index e8b3ca6..1456ff7 100644
--- a/core/java/android/os/IVibratorService.aidl
+++ b/core/java/android/os/IVibratorService.aidl
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.media.AudioAttributes;
 import android.os.VibrationEffect;
 
 /** {@hide} */
@@ -23,8 +24,8 @@
 {
     boolean hasVibrator();
     boolean hasAmplitudeControl();
-    void vibrate(int uid, String opPkg, in VibrationEffect effect, int usageHint, String reason,
-            IBinder token);
+    void vibrate(int uid, String opPkg, in VibrationEffect effect, in AudioAttributes attributes,
+            String reason, IBinder token);
     void cancelVibrate(IBinder token);
 }
 
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index fe2e948..dbe3c93 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -2996,65 +2996,67 @@
             return null;
         }
         Parcelable.Creator<?> creator;
+        HashMap<String, Parcelable.Creator<?>> map;
         synchronized (mCreators) {
-            HashMap<String,Parcelable.Creator<?>> map = mCreators.get(loader);
+            map = mCreators.get(loader);
             if (map == null) {
                 map = new HashMap<>();
                 mCreators.put(loader, map);
             }
             creator = map.get(name);
-            if (creator == null) {
-                try {
-                    // If loader == null, explicitly emulate Class.forName(String) "caller
-                    // classloader" behavior.
-                    ClassLoader parcelableClassLoader =
-                            (loader == null ? getClass().getClassLoader() : loader);
-                    // Avoid initializing the Parcelable class until we know it implements
-                    // Parcelable and has the necessary CREATOR field. http://b/1171613.
-                    Class<?> parcelableClass = Class.forName(name, false /* initialize */,
-                            parcelableClassLoader);
-                    if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
-                        throw new BadParcelableException("Parcelable protocol requires subclassing "
-                                + "from Parcelable on class " + name);
-                    }
-                    Field f = parcelableClass.getField("CREATOR");
-                    if ((f.getModifiers() & Modifier.STATIC) == 0) {
-                        throw new BadParcelableException("Parcelable protocol requires "
-                                + "the CREATOR object to be static on class " + name);
-                    }
-                    Class<?> creatorType = f.getType();
-                    if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {
-                        // Fail before calling Field.get(), not after, to avoid initializing
-                        // parcelableClass unnecessarily.
-                        throw new BadParcelableException("Parcelable protocol requires a "
-                                + "Parcelable.Creator object called "
-                                + "CREATOR on class " + name);
-                    }
-                    creator = (Parcelable.Creator<?>) f.get(null);
-                }
-                catch (IllegalAccessException e) {
-                    Log.e(TAG, "Illegal access when unmarshalling: " + name, e);
-                    throw new BadParcelableException(
-                            "IllegalAccessException when unmarshalling: " + name);
-                }
-                catch (ClassNotFoundException e) {
-                    Log.e(TAG, "Class not found when unmarshalling: " + name, e);
-                    throw new BadParcelableException(
-                            "ClassNotFoundException when unmarshalling: " + name);
-                }
-                catch (NoSuchFieldException e) {
-                    throw new BadParcelableException("Parcelable protocol requires a "
-                            + "Parcelable.Creator object called "
-                            + "CREATOR on class " + name);
-                }
-                if (creator == null) {
-                    throw new BadParcelableException("Parcelable protocol requires a "
-                            + "non-null Parcelable.Creator object called "
-                            + "CREATOR on class " + name);
-                }
+        }
+        if (creator != null) {
+            return creator;
+        }
 
-                map.put(name, creator);
+        try {
+            // If loader == null, explicitly emulate Class.forName(String) "caller
+            // classloader" behavior.
+            ClassLoader parcelableClassLoader =
+                    (loader == null ? getClass().getClassLoader() : loader);
+            // Avoid initializing the Parcelable class until we know it implements
+            // Parcelable and has the necessary CREATOR field. http://b/1171613.
+            Class<?> parcelableClass = Class.forName(name, false /* initialize */,
+                    parcelableClassLoader);
+            if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
+                throw new BadParcelableException("Parcelable protocol requires subclassing "
+                        + "from Parcelable on class " + name);
             }
+            Field f = parcelableClass.getField("CREATOR");
+            if ((f.getModifiers() & Modifier.STATIC) == 0) {
+                throw new BadParcelableException("Parcelable protocol requires "
+                        + "the CREATOR object to be static on class " + name);
+            }
+            Class<?> creatorType = f.getType();
+            if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {
+                // Fail before calling Field.get(), not after, to avoid initializing
+                // parcelableClass unnecessarily.
+                throw new BadParcelableException("Parcelable protocol requires a "
+                        + "Parcelable.Creator object called "
+                        + "CREATOR on class " + name);
+            }
+            creator = (Parcelable.Creator<?>) f.get(null);
+        } catch (IllegalAccessException e) {
+            Log.e(TAG, "Illegal access when unmarshalling: " + name, e);
+            throw new BadParcelableException(
+                    "IllegalAccessException when unmarshalling: " + name);
+        } catch (ClassNotFoundException e) {
+            Log.e(TAG, "Class not found when unmarshalling: " + name, e);
+            throw new BadParcelableException(
+                    "ClassNotFoundException when unmarshalling: " + name);
+        } catch (NoSuchFieldException e) {
+            throw new BadParcelableException("Parcelable protocol requires a "
+                    + "Parcelable.Creator object called "
+                    + "CREATOR on class " + name);
+        }
+        if (creator == null) {
+            throw new BadParcelableException("Parcelable protocol requires a "
+                    + "non-null Parcelable.Creator object called "
+                    + "CREATOR on class " + name);
+        }
+
+        synchronized (mCreators) {
+            map.put(name, creator);
         }
 
         return creator;
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 2fff595..535d887 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -1289,20 +1289,6 @@
         }
     }
 
-    /**
-     * Returns whether the screen brightness is currently boosted to maximum, caused by a call
-     * to {@link #boostScreenBrightness(long)}.
-     * @return {@code True} if the screen brightness is currently boosted. {@code False} otherwise.
-     *
-     * @deprecated This call is rarely used and will be phased out soon.
-     * @hide
-     * @removed
-     */
-    @SystemApi @Deprecated
-    public boolean isScreenBrightnessBoosted() {
-        return false;
-    }
-
    /**
      * Returns true if the specified wake lock level is supported.
      *
@@ -2031,18 +2017,6 @@
     public static final String EXTRA_POWER_SAVE_MODE = "mode";
 
     /**
-     * Intent that is broadcast when the state of {@link #isScreenBrightnessBoosted()} has changed.
-     * This broadcast is only sent to registered receivers.
-     *
-     * @deprecated This intent is rarely used and will be phased out soon.
-     * @hide
-     * @removed
-     **/
-    @SystemApi @Deprecated
-    public static final String ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED
-            = "android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED";
-
-    /**
      * Constant for PreIdleTimeout normal mode (default mode, not short nor extend timeout) .
      * @hide
      */
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e50ab6c..b535e8d 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -511,7 +511,7 @@
      * @param appDataDir null-ok the data directory of the app.
      * @param invokeWith null-ok the command to invoke with.
      * @param packageName null-ok the name of the package this process belongs to.
-     * @param useSystemGraphicsDriver whether the process uses system graphics driver.
+     * @param isTopApp whether the process starts for high priority application.
      *
      * @param zygoteArgs Additional arguments to supply to the zygote process.
      * @return An object that describes the result of the attempt to start the process.
@@ -531,13 +531,12 @@
                                            @Nullable String appDataDir,
                                            @Nullable String invokeWith,
                                            @Nullable String packageName,
-                                           boolean useSystemGraphicsDriver,
+                                           boolean isTopApp,
                                            @Nullable String[] zygoteArgs) {
         return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, packageName,
-                    /*useUsapPool=*/ true,
-                    useSystemGraphicsDriver, zygoteArgs);
+                    /*useUsapPool=*/ true, isTopApp, zygoteArgs);
     }
 
     /** @hide */
@@ -553,13 +552,11 @@
                                                   @Nullable String appDataDir,
                                                   @Nullable String invokeWith,
                                                   @Nullable String packageName,
-                                                  boolean useSystemGraphicsDriver,
                                                   @Nullable String[] zygoteArgs) {
         return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, packageName,
-                    /*useUsapPool=*/ false,
-                    useSystemGraphicsDriver, zygoteArgs);
+                    /*useUsapPool=*/ false, /*isTopApp=*/ false, zygoteArgs);
     }
 
     /**
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 1b41694..48fc2a6 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -30,8 +30,9 @@
 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.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
@@ -39,8 +40,6 @@
 import android.view.Display;
 import android.view.WindowManager;
 
-import com.android.internal.content.PackageHelper;
-
 import libcore.io.Streams;
 
 import java.io.ByteArrayInputStream;
@@ -59,10 +58,12 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
@@ -90,11 +91,14 @@
     private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500;
 
     private static final long DEFAULT_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 30000L; // 30 s
-
     private static final long MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 5000L; // 5 s
-
     private static final long MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 60000L; // 60 s
 
+    private static final long DEFAULT_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS =
+            45000L; // 45 s
+    private static final long MIN_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS = 15000L; // 15 s
+    private static final long MAX_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS = 90000L; // 90 s
+
     /** Used to communicate with recovery.  See bootable/recovery/recovery.cpp. */
     private static final File RECOVERY_DIR = new File("/cache/recovery");
     private static final File LOG_FILE = new File(RECOVERY_DIR, "log");
@@ -102,9 +106,14 @@
     private static final String LAST_PREFIX = "last_";
     private static final String ACTION_EUICC_FACTORY_RESET =
             "com.android.internal.action.EUICC_FACTORY_RESET";
+    private static final String ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS =
+            "com.android.internal.action.EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS";
 
-    /** used in {@link #wipeEuiccData} as package name of callback intent */
-    private static final String PACKAGE_NAME_WIPING_EUICC_DATA_CALLBACK = "android";
+    /**
+     * Used in {@link #wipeEuiccData} & {@link #removeEuiccInvisibleSubs} as package name of
+     * callback intent.
+     */
+    private static final String PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK = "android";
 
     /**
      * The recovery image uses this file to identify the location (i.e. blocks)
@@ -757,8 +766,11 @@
         // Block until the ordered broadcast has completed.
         condition.block();
 
+        EuiccManager euiccManager = context.getSystemService(EuiccManager.class);
         if (wipeEuicc) {
-            wipeEuiccData(context, PACKAGE_NAME_WIPING_EUICC_DATA_CALLBACK);
+            wipeEuiccData(context, PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK);
+        } else {
+            removeEuiccInvisibleSubs(context, euiccManager);
         }
 
         String shutdownArg = null;
@@ -854,22 +866,139 @@
         return false;
     }
 
+    private static void removeEuiccInvisibleSubs(
+            Context context, EuiccManager euiccManager) {
+        ContentResolver cr = context.getContentResolver();
+        if (Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) == 0) {
+            // If the eUICC isn't provisioned, there's no need to remove euicc invisible profiles,
+            // as there's nothing to be removed.
+            Log.i(TAG, "Skip removing eUICC invisible profiles as it is not provisioned.");
+            return;
+        } else if (euiccManager == null || !euiccManager.isEnabled()) {
+            Log.i(TAG, "Skip removing eUICC invisible profiles as eUICC manager is not available.");
+            return;
+        }
+        SubscriptionManager subscriptionManager =
+                context.getSystemService(SubscriptionManager.class);
+        List<SubscriptionInfo> availableSubs =
+                subscriptionManager.getAvailableSubscriptionInfoList();
+        if (availableSubs == null || availableSubs.isEmpty()) {
+            Log.i(TAG, "Skip removing eUICC invisible profiles as no available profiles found.");
+            return;
+        }
+        List<SubscriptionInfo> invisibleSubs = new ArrayList<>();
+        for (SubscriptionInfo sub : availableSubs) {
+            if (sub.isEmbedded() && !subscriptionManager.isSubscriptionVisible(sub)) {
+                invisibleSubs.add(sub);
+            }
+        }
+        removeEuiccInvisibleSubs(context, invisibleSubs, euiccManager);
+    }
+
+    private static boolean removeEuiccInvisibleSubs(
+            Context context, List<SubscriptionInfo> subscriptionInfos, EuiccManager euiccManager) {
+        if (subscriptionInfos == null || subscriptionInfos.isEmpty()) {
+            Log.i(TAG, "There are no eUICC invisible profiles needed to be removed.");
+            return true;
+        }
+        CountDownLatch removeSubsLatch = new CountDownLatch(subscriptionInfos.size());
+        final AtomicInteger removedSubsCount = new AtomicInteger(0);
+
+        BroadcastReceiver removeEuiccSubsReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS.equals(intent.getAction())) {
+                    if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+                        int detailedCode = intent.getIntExtra(
+                                EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
+                        Log.e(TAG, "Error removing euicc opportunistic profile, Detailed code = "
+                                + detailedCode);
+                    } else {
+                        Log.e(TAG, "Successfully remove euicc opportunistic profile.");
+                        removedSubsCount.incrementAndGet();
+                    }
+                    removeSubsLatch.countDown();
+                }
+            }
+        };
+
+        Intent intent = new Intent(ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS);
+        intent.setPackage(PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK);
+        PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser(
+                context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM);
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS);
+        HandlerThread euiccHandlerThread =
+                new HandlerThread("euiccRemovingSubsReceiverThread");
+        euiccHandlerThread.start();
+        Handler euiccHandler = new Handler(euiccHandlerThread.getLooper());
+        context.getApplicationContext()
+                .registerReceiver(
+                        removeEuiccSubsReceiver, intentFilter, null, euiccHandler);
+        for (SubscriptionInfo subscriptionInfo : subscriptionInfos) {
+            Log.i(
+                    TAG,
+                    "Remove invisible subscription " + subscriptionInfo.getSubscriptionId()
+                            + " from card " + subscriptionInfo.getCardId());
+            euiccManager.createForCardId(subscriptionInfo.getCardId())
+                    .deleteSubscription(subscriptionInfo.getSubscriptionId(), callbackIntent);
+        }
+        try {
+            long waitingTimeMillis = Settings.Global.getLong(
+                    context.getContentResolver(),
+                    Settings.Global.EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS,
+                    DEFAULT_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS);
+            if (waitingTimeMillis < MIN_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS) {
+                waitingTimeMillis = MIN_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS;
+            } else if (waitingTimeMillis > MAX_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS) {
+                waitingTimeMillis = MAX_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS;
+            }
+            if (!removeSubsLatch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)) {
+                Log.e(TAG, "Timeout removing invisible euicc profiles.");
+                return false;
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            Log.e(TAG, "Removing invisible euicc profiles interrupted", e);
+            return false;
+        } finally {
+            context.getApplicationContext().unregisterReceiver(removeEuiccSubsReceiver);
+            if (euiccHandlerThread != null) {
+                euiccHandlerThread.quit();
+            }
+        }
+        return removedSubsCount.get() == subscriptionInfos.size();
+    }
+
     /** {@hide} */
     public static void rebootPromptAndWipeUserData(Context context, String reason)
             throws IOException {
         boolean checkpointing = false;
+        boolean needReboot = false;
+        IVold vold = null;
+        try {
+            vold = IVold.Stub.asInterface(ServiceManager.checkService("vold"));
+            if (vold != null) {
+                checkpointing = vold.needsCheckpoint();
+            } else  {
+                Log.w(TAG, "Failed to get vold");
+            }
+        } catch (Exception e) {
+            Log.w(TAG, "Failed to check for checkpointing");
+        }
 
         // 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;
+        if (checkpointing) {
+            try {
+                vold.abortChanges("rescueparty", false);
+                Log.i(TAG, "Rescue Party requested wipe. Aborting update");
+            } catch (Exception e) {
+                Log.i(TAG, "Rescue Party requested wipe. Rebooting instead.");
+                PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+                pm.reboot("rescueparty");
             }
-        } catch (RemoteException e) {
-            Log.i(TAG, "Failed to handle with checkpointing. Continuing with wipe.");
+            return;
         }
 
         String reasonArg = null;
diff --git a/core/java/android/os/RedactingFileDescriptor.java b/core/java/android/os/RedactingFileDescriptor.java
index 4e5eaac..a1ed214 100644
--- a/core/java/android/os/RedactingFileDescriptor.java
+++ b/core/java/android/os/RedactingFileDescriptor.java
@@ -35,7 +35,7 @@
 
 /**
  * Variant of {@link FileDescriptor} that allows its creator to specify regions
- * that should be redacted (appearing as zeros to the reader).
+ * that should be redacted.
  *
  * @hide
  */
@@ -44,13 +44,16 @@
     private static final boolean DEBUG = true;
 
     private volatile long[] mRedactRanges;
+    private volatile long[] mFreeOffsets;
 
     private FileDescriptor mInner = null;
     private ParcelFileDescriptor mOuter = null;
 
-    private RedactingFileDescriptor(Context context, File file, int mode, long[] redactRanges)
+    private RedactingFileDescriptor(
+            Context context, File file, int mode, long[] redactRanges, long[] freeOffsets)
             throws IOException {
         mRedactRanges = checkRangesArgument(redactRanges);
+        mFreeOffsets = freeOffsets;
 
         try {
             try {
@@ -88,13 +91,17 @@
      *
      * @param file The underlying file to open.
      * @param mode The {@link ParcelFileDescriptor} mode to open with.
-     * @param redactRanges List of file offsets that should be redacted, stored
+     * @param redactRanges List of file ranges that should be redacted, stored
      *            as {@code [start1, end1, start2, end2, ...]}. Start values are
      *            inclusive and end values are exclusive.
+     * @param freePositions List of file offsets at which the four byte value 'free' should be
+     *            written instead of zeros within parts of the file covered by {@code redactRanges}.
+     *            Non-redacted bytes will not be modified even if covered by a 'free'. This is
+     *            useful for overwriting boxes in ISOBMFF files with padding data.
      */
     public static ParcelFileDescriptor open(Context context, File file, int mode,
-            long[] redactRanges) throws IOException {
-        return new RedactingFileDescriptor(context, file, mode, redactRanges).mOuter;
+            long[] redactRanges, long[] freePositions) throws IOException {
+        return new RedactingFileDescriptor(context, file, mode, redactRanges, freePositions).mOuter;
     }
 
     /**
@@ -169,6 +176,15 @@
                 for (long j = start; j < end; j++) {
                     data[(int) (j - offset)] = 0;
                 }
+                // Overwrite data at 'free' offsets within the redaction ranges.
+                for (long freeOffset : mFreeOffsets) {
+                    final long freeEnd = freeOffset + 4;
+                    final long redactFreeStart = Math.max(freeOffset, start);
+                    final long redactFreeEnd = Math.min(freeEnd, end);
+                    for (long j = redactFreeStart; j < redactFreeEnd; j++) {
+                        data[(int) (j - offset)] = (byte) "free".charAt((int) (j - freeOffset));
+                    }
+                }
             }
             return n;
         }
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index b7c026c..7991cd4 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -17,102 +17,40 @@
 package android.os;
 
 import android.annotation.UnsupportedAppUsage;
-import java.util.ArrayList;
-
 
 /**
  * Native implementation of the service manager.  Most clients will only
- * care about getDefault() and possibly asInterface().
+ * care about asInterface().
+ *
  * @hide
  */
-public abstract class ServiceManagerNative extends Binder implements IServiceManager
-{
+public final class ServiceManagerNative {
+    private ServiceManagerNative() {}
+
     /**
      * Cast a Binder object into a service manager interface, generating
      * a proxy if needed.
+     *
+     * TODO: delete this method and have clients use
+     *     IServiceManager.Stub.asInterface instead
      */
     @UnsupportedAppUsage
-    static public IServiceManager asInterface(IBinder obj)
-    {
+    public static IServiceManager asInterface(IBinder obj) {
         if (obj == null) {
             return null;
         }
-        IServiceManager in =
-            (IServiceManager)obj.queryLocalInterface(descriptor);
-        if (in != null) {
-            return in;
-        }
 
+        // ServiceManager is never local
         return new ServiceManagerProxy(obj);
     }
-
-    public ServiceManagerNative()
-    {
-        attachInterface(this, descriptor);
-    }
-
-    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-    {
-        try {
-            switch (code) {
-                case IServiceManager.GET_SERVICE_TRANSACTION: {
-                    data.enforceInterface(IServiceManager.descriptor);
-                    String name = data.readString();
-                    IBinder service = getService(name);
-                    reply.writeStrongBinder(service);
-                    return true;
-                }
-
-                case IServiceManager.CHECK_SERVICE_TRANSACTION: {
-                    data.enforceInterface(IServiceManager.descriptor);
-                    String name = data.readString();
-                    IBinder service = checkService(name);
-                    reply.writeStrongBinder(service);
-                    return true;
-                }
-
-                case IServiceManager.ADD_SERVICE_TRANSACTION: {
-                    data.enforceInterface(IServiceManager.descriptor);
-                    String name = data.readString();
-                    IBinder service = data.readStrongBinder();
-                    boolean allowIsolated = data.readInt() != 0;
-                    int dumpPriority = data.readInt();
-                    addService(name, service, allowIsolated, dumpPriority);
-                    return true;
-                }
-
-                case IServiceManager.LIST_SERVICES_TRANSACTION: {
-                    data.enforceInterface(IServiceManager.descriptor);
-                    int dumpPriority = data.readInt();
-                    String[] list = listServices(dumpPriority);
-                    reply.writeStringArray(list);
-                    return true;
-                }
-
-                case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
-                    data.enforceInterface(IServiceManager.descriptor);
-                    IPermissionController controller =
-                            IPermissionController.Stub.asInterface(
-                                    data.readStrongBinder());
-                    setPermissionController(controller);
-                    return true;
-                }
-            }
-        } catch (RemoteException e) {
-        }
-
-        return false;
-    }
-
-    public IBinder asBinder()
-    {
-        return this;
-    }
 }
 
+// This class should be deleted and replaced with IServiceManager.Stub whenever
+// mRemote is no longer used
 class ServiceManagerProxy implements IServiceManager {
     public ServiceManagerProxy(IBinder remote) {
         mRemote = remote;
+        mServiceManager = IServiceManager.Stub.asInterface(remote);
     }
 
     public IBinder asBinder() {
@@ -121,84 +59,30 @@
 
     @UnsupportedAppUsage
     public IBinder getService(String name) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IServiceManager.descriptor);
-        data.writeString(name);
-        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
-        IBinder binder = reply.readStrongBinder();
-        reply.recycle();
-        data.recycle();
-        return binder;
+        // Same as checkService (old versions of servicemanager had both methods).
+        return mServiceManager.checkService(name);
     }
 
     public IBinder checkService(String name) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IServiceManager.descriptor);
-        data.writeString(name);
-        mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
-        IBinder binder = reply.readStrongBinder();
-        reply.recycle();
-        data.recycle();
-        return binder;
+        return mServiceManager.checkService(name);
     }
 
     public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
             throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IServiceManager.descriptor);
-        data.writeString(name);
-        data.writeStrongBinder(service);
-        data.writeInt(allowIsolated ? 1 : 0);
-        data.writeInt(dumpPriority);
-        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
-        reply.recycle();
-        data.recycle();
+        mServiceManager.addService(name, service, allowIsolated, dumpPriority);
     }
 
     public String[] listServices(int dumpPriority) throws RemoteException {
-        ArrayList<String> services = new ArrayList<String>();
-        int n = 0;
-        while (true) {
-            Parcel data = Parcel.obtain();
-            Parcel reply = Parcel.obtain();
-            data.writeInterfaceToken(IServiceManager.descriptor);
-            data.writeInt(n);
-            data.writeInt(dumpPriority);
-            n++;
-            try {
-                boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
-                if (!res) {
-                    break;
-                }
-            } catch (RuntimeException e) {
-                // The result code that is returned by the C++ code can
-                // cause the call to throw an exception back instead of
-                // returning a nice result...  so eat it here and go on.
-                break;
-            }
-            services.add(reply.readString());
-            reply.recycle();
-            data.recycle();
-        }
-        String[] array = new String[services.size()];
-        services.toArray(array);
-        return array;
+        return mServiceManager.listServices(dumpPriority);
     }
 
-    public void setPermissionController(IPermissionController controller)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        Parcel reply = Parcel.obtain();
-        data.writeInterfaceToken(IServiceManager.descriptor);
-        data.writeStrongBinder(controller.asBinder());
-        mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
-        reply.recycle();
-        data.recycle();
-    }
-
+    /**
+     * Same as mServiceManager but used by apps.
+     *
+     * Once this can be removed, ServiceManagerProxy should be removed entirely.
+     */
     @UnsupportedAppUsage
     private IBinder mRemote;
+
+    private IServiceManager mServiceManager;
 }
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index 64effb8..a510e42 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -177,14 +177,6 @@
     native public static long uptimeMillis();
 
     /**
-     * @removed
-     */
-    @Deprecated
-    public static @NonNull Clock uptimeMillisClock() {
-        return uptimeClock();
-    }
-
-    /**
      * Return {@link Clock} that starts at system boot, not counting time spent
      * in deep sleep.
      *
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 4af514a..a5188e7 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -77,16 +77,12 @@
             return;
         }
         try {
-            mService.vibrate(uid, opPkg, effect, usageForAttributes(attributes), reason, mToken);
+            mService.vibrate(uid, opPkg, effect, attributes, reason, mToken);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to vibrate.", e);
         }
     }
 
-    private static int usageForAttributes(AudioAttributes attributes) {
-        return attributes != null ? attributes.getUsage() : AudioAttributes.USAGE_UNKNOWN;
-    }
-
     @Override
     public void cancel() {
         if (mService == null) {
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index 5cf3b97..29af17a 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -21,6 +21,8 @@
 import android.os.IUpdateEngineCallback;
 import android.os.RemoteException;
 
+import java.io.FileDescriptor;
+
 /**
  * UpdateEngine handles calls to the update engine which takes care of A/B OTA
  * updates. It wraps up the update engine Binder APIs and exposes them as
@@ -312,6 +314,22 @@
     }
 
     /**
+     * Applies the payload passed as file descriptor {@code fd} instead of
+     * using the {@code file://} scheme.
+     *
+     * <p>See {@link #applyPayload(String)} for {@code offset}, {@code size} and
+     * {@code headerKeyValuePairs} parameters.
+     */
+    public void applyPayload(FileDescriptor fd, long offset, long size,
+            String[] headerKeyValuePairs) {
+        try {
+            mUpdateEngine.applyPayloadFd(fd, offset, size, headerKeyValuePairs);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Permanently cancels an in-progress update.
      *
      * <p>See {@link #resetStatus} to undo a finshed update (only available
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index b121234..d70ba99 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -68,6 +68,7 @@
     public static final @NonNull UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);
 
     /** @hide An undefined user id */
+    @UnsupportedAppUsage
     public static final @UserIdInt int USER_NULL = -10000;
 
     /**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 9c9829f..a7fa96b 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1283,6 +1283,16 @@
     }
 
     /**
+     * @hide
+     * @return Whether the device is running in a headless system user mode. It means the headless
+     * user (system user) runs system services and system UI, but is not associated with any real
+     * person. Secondary users can be created to be associated with real person.
+     */
+    public static boolean isHeadlessSystemUserMode() {
+        return RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER;
+    }
+
+    /**
      * @deprecated use {@link #getUserSwitchability()} instead.
      *
      * @removed
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 035061b..702b41b 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -330,18 +330,25 @@
     @TestApi
     @Nullable
     public static VibrationEffect get(Uri uri, Context context) {
+        final ContentResolver cr = context.getContentResolver();
+        Uri uncanonicalUri = cr.uncanonicalize(uri);
+        if (uncanonicalUri == null) {
+            // If we already had an uncanonical URI, it's possible we'll get null back here. In
+            // this case, just use the URI as passed in since it wasn't canonicalized in the first
+            // place.
+            uncanonicalUri = uri;
+        }
         String[] uris = context.getResources().getStringArray(
                 com.android.internal.R.array.config_ringtoneEffectUris);
         for (int i = 0; i < uris.length && i < RINGTONES.length; i++) {
             if (uris[i] == null) {
                 continue;
             }
-            ContentResolver cr = context.getContentResolver();
             Uri mappedUri = cr.uncanonicalize(Uri.parse(uris[i]));
             if (mappedUri == null) {
                 continue;
             }
-            if (mappedUri.equals(uri)) {
+            if (mappedUri.equals(uncanonicalUri)) {
                 return get(RINGTONES[i]);
             }
         }
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 8f10061..cdd0d45 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -81,7 +81,7 @@
      * not be used if the devices has a DeviceConfig profile pushed to it that contains a value for
      * this key.
      */
-    private static final String USAP_POOL_ENABLED_DEFAULT = "true";
+    private static final String USAP_POOL_ENABLED_DEFAULT = "false";
 
     /**
      * The name of the socket used to communicate with the primary zygote.
@@ -307,7 +307,7 @@
      * @param invokeWith null-ok the command to invoke with.
      * @param packageName null-ok the name of the package this process belongs to.
      * @param zygoteArgs Additional arguments to supply to the zygote process.
-     * @param useSystemGraphicsDriver whether the process uses system graphics driver.
+     * @param isTopApp Whether the process starts for high priority application.
      *
      * @return An object that describes the result of the attempt to start the process.
      * @throws RuntimeException on fatal start failure
@@ -324,7 +324,7 @@
                                                   @Nullable String invokeWith,
                                                   @Nullable String packageName,
                                                   boolean useUsapPool,
-                                                  boolean useSystemGraphicsDriver,
+                                                  boolean isTopApp,
                                                   @Nullable String[] zygoteArgs) {
         // TODO (chriswailes): Is there a better place to check this value?
         if (fetchUsapPoolEnabledPropWithMinInterval()) {
@@ -335,7 +335,7 @@
             return startViaZygote(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
-                    packageName, useUsapPool, useSystemGraphicsDriver, zygoteArgs);
+                    packageName, useUsapPool, isTopApp, zygoteArgs);
         } catch (ZygoteStartFailedEx ex) {
             Log.e(LOG_TAG,
                     "Starting VM process through Zygote failed");
@@ -407,7 +407,7 @@
          */
         String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
 
-        if (useUsapPool && mUsapPoolEnabled && isValidUsapCommand(args)) {
+        if (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {
             try {
                 return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
             } catch (IOException ex) {
@@ -498,13 +498,19 @@
      * @param args  Zygote/USAP command arguments
      * @return  True if the command can be passed to a USAP; false otherwise
      */
-    private static boolean isValidUsapCommand(ArrayList<String> args) {
+    private static boolean canAttemptUsap(ArrayList<String> args) {
         for (String flag : args) {
             for (String badFlag : INVALID_USAP_FLAGS) {
                 if (flag.startsWith(badFlag)) {
                     return false;
                 }
             }
+            if (flag.startsWith("--nice-name=")) {
+                // Check if the wrap property is set, usap would ignore it.
+                if (Zygote.getWrapProperty(flag.substring(12)) != null) {
+                    return false;
+                }
+            }
         }
 
         return true;
@@ -528,6 +534,7 @@
      * @param startChildZygote Start a sub-zygote. This creates a new zygote process
      * that has its state cloned from this zygote process.
      * @param packageName null-ok the name of the package this process belongs to.
+     * @param isTopApp Whether the process starts for high priority application.
      * @param extraArgs Additional arguments to supply to the zygote process.
      * @return An object that describes the result of the attempt to start the process.
      * @throws ZygoteStartFailedEx if process start failed for any reason
@@ -546,7 +553,7 @@
                                                       boolean startChildZygote,
                                                       @Nullable String packageName,
                                                       boolean useUsapPool,
-                                                      boolean useSystemGraphicsDriver,
+                                                      boolean isTopApp,
                                                       @Nullable String[] extraArgs)
                                                       throws ZygoteStartFailedEx {
         ArrayList<String> argsForZygote = new ArrayList<>();
@@ -618,6 +625,10 @@
             argsForZygote.add("--package-name=" + packageName);
         }
 
+        if (isTopApp) {
+            argsForZygote.add(Zygote.START_AS_TOP_APP_ARG);
+        }
+
         argsForZygote.add(processClass);
 
         if (extraArgs != null) {
@@ -628,7 +639,7 @@
             // The USAP pool can not be used if the application will not use the systems graphics
             // driver.  If that driver is requested use the Zygote application start path.
             return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
-                                              useUsapPool && useSystemGraphicsDriver,
+                                              useUsapPool,
                                               argsForZygote);
         }
     }
@@ -660,16 +671,6 @@
     private boolean fetchUsapPoolEnabledPropWithMinInterval() {
         final long currentTimestamp = SystemClock.elapsedRealtime();
 
-        if (SystemProperties.get("dalvik.vm.boot-image", "").endsWith("apex.art")) {
-            // TODO(b/119800099): In jitzygote mode, we want to start using USAP processes
-            // only once the boot classpath has been compiled. There is currently no callback
-            // from the runtime to notify the zygote about end of compilation, so for now just
-            // arbitrarily start USAP processes 15 seconds after boot.
-            if (currentTimestamp <= 15000) {
-                return false;
-            }
-        }
-
         if (mIsFirstPropCheck
                 || (currentTimestamp - mLastPropCheckTimestamp >= Zygote.PROPERTY_CHECK_INTERVAL)) {
             mIsFirstPropCheck = false;
@@ -1137,8 +1138,7 @@
                     gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
                     abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
                     true /* startChildZygote */, null /* packageName */,
-                    false /* useUsapPool */, false /*useSystemGraphicsDriver*/,
-                    extraArgs);
+                    false /* useUsapPool */, false /* isTopApp */, extraArgs);
         } catch (ZygoteStartFailedEx ex) {
             throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
         }
diff --git a/core/java/android/permission/IOnPermissionsChangeListener.aidl b/core/java/android/permission/IOnPermissionsChangeListener.aidl
new file mode 100644
index 0000000..cc52a72
--- /dev/null
+++ b/core/java/android/permission/IOnPermissionsChangeListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package android.permission;
+
+/**
+ * Listener for changes in the permissions for installed packages.
+ * {@hide}
+ */
+oneway interface IOnPermissionsChangeListener {
+    void onPermissionsChanged(int uid);
+}
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
new file mode 100644
index 0000000..9fa5f16
--- /dev/null
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -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.
+ */
+
+package android.permission;
+
+import android.content.pm.ParceledListSlice;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.permission.IOnPermissionsChangeListener;
+
+/**
+ * Interface to communicate directly with the permission manager service.
+ * @see PermissionManager
+ * @hide
+ */
+interface IPermissionManager {
+    String[] getAppOpPermissionPackages(String permName);
+
+    ParceledListSlice getAllPermissionGroups(int flags);
+
+    PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags);
+
+    PermissionInfo getPermissionInfo(String permName, String packageName, int flags);
+
+    ParceledListSlice queryPermissionsByGroup(String groupName, int flags);
+
+    boolean addPermission(in PermissionInfo info, boolean async);
+
+    void removePermission(String name);
+
+    int getPermissionFlags(String permName, String packageName, int userId);
+
+    void updatePermissionFlags(String permName, String packageName, int flagMask,
+            int flagValues, boolean checkAdjustPolicyFlagPermission, int userId);
+
+    void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId);
+
+    int checkPermission(String permName, String pkgName, int userId);
+
+    int checkUidPermission(String permName, int uid);
+
+    void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
+
+    void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener);
+
+    List<String> getWhitelistedRestrictedPermissions(String packageName,
+            int flags, int userId);
+
+    boolean addWhitelistedRestrictedPermission(String packageName, String permName,
+            int flags, int userId);
+
+    boolean removeWhitelistedRestrictedPermission(String packageName, String permName,
+            int flags, int userId);
+
+    void grantRuntimePermission(String packageName, String permName, int userId);
+
+    void revokeRuntimePermission(String packageName, String permName, int userId);
+
+    void resetRuntimePermissions();
+
+    boolean setDefaultBrowser(String packageName, int userId);
+
+    String getDefaultBrowser(int userId);
+
+    void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId);
+
+    void grantDefaultPermissionsToEnabledImsServices(in String[] packageNames, int userId);
+
+    void grantDefaultPermissionsToEnabledTelephonyDataServices(
+            in String[] packageNames, int userId);
+
+    void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+            in String[] packageNames, int userId);
+
+    void grantDefaultPermissionsToActiveLuiApp(in String packageName, int userId);
+
+    void revokeDefaultPermissionsFromLuiApps(in String[] packageNames, int userId);
+
+    void setPermissionEnforced(String permName, boolean enforced);
+
+    boolean isPermissionEnforced(String permName);
+
+    boolean shouldShowRequestPermissionRationale(String permName,
+            String packageName, int userId);
+
+    boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId);
+}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index e15659d..42816c0 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -39,9 +39,18 @@
  *
  * @hide
  */
+@TestApi
 @SystemApi
 @SystemService(Context.PERMISSION_SERVICE)
 public final class PermissionManager {
+    /** @hide */
+    public static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
+            "permissions revoked";
+    /** @hide */
+    public static final String KILL_APP_REASON_GIDS_CHANGED =
+            "permission grant or revoke changed gids";
+
+
     /**
      * {@link android.content.pm.PackageParser} needs access without having a {@link Context}.
      *
@@ -140,12 +149,13 @@
             if (o == null || getClass() != o.getClass()) return false;
             SplitPermissionInfo that = (SplitPermissionInfo) o;
             return mTargetSdk == that.mTargetSdk
-                    && Objects.equals(mSplitPerm, that.mSplitPerm);
+                    && mSplitPerm.equals(that.mSplitPerm)
+                    && mNewPerms.equals(that.mNewPerms);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(mSplitPerm, mTargetSdk);
+            return Objects.hash(mSplitPerm, mNewPerms, mTargetSdk);
         }
 
         /**
diff --git a/core/java/android/permission/PermissionManagerInternal.java b/core/java/android/permission/PermissionManagerInternal.java
index 7167431..3134ec0 100644
--- a/core/java/android/permission/PermissionManagerInternal.java
+++ b/core/java/android/permission/PermissionManagerInternal.java
@@ -21,6 +21,10 @@
 import android.annotation.UserIdInt;
 import android.os.UserHandle;
 
+import com.android.internal.util.function.TriFunction;
+
+import java.util.function.BiFunction;
+
 /**
  * Internal interfaces to be used by other components within the system server.
  *
@@ -46,6 +50,33 @@
                 @UserIdInt int userId);
     }
 
+    /** Interface to override permission checks via composition */
+    public interface CheckPermissionDelegate {
+        /**
+         * Checks whether the given package has been granted the specified permission.
+         *
+         * @return If the package has the permission, PERMISSION_GRANTED is
+         * returned.  If it does not have the permission, PERMISSION_DENIED
+         * is returned.
+         *
+         * @see android.content.pm.PackageManager#checkPermission(String, String)
+         */
+        int checkPermission(String permName, String pkgName, int userId,
+                TriFunction<String, String, Integer, Integer> superImpl);
+
+        /**
+        /**
+         * Checks whether the given uid has been granted the specified permission.
+         *
+         * @return If the package has the permission, PERMISSION_GRANTED is
+         * returned.  If it does not have the permission, PERMISSION_DENIED
+         * is returned.
+         *
+         */
+        int checkUidPermission(String permName, int uid,
+                BiFunction<String, Integer, Integer> superImpl);
+    }
+
     /**
      * Get the state of the runtime permissions as xml file.
      *
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index ea397cc..d0401e3 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -48,6 +48,8 @@
 
 /**
  * Device level configuration parameters which can be tuned by a separate configuration service.
+ * Namespaces that end in "_native" such as {@link #NAMESPACE_NETD_NATIVE} are intended to be used
+ * by native code and should be pushed to system properties to make them accessible.
  *
  * @hide
  */
@@ -291,6 +293,15 @@
     public static final String NAMESPACE_SETTINGS_UI = "settings_ui";
 
     /**
+     * Namespace for window manager related features. The names to access the properties in this
+     * namespace should be defined in {@link WindowManager}.
+     *
+     * @hide
+     */
+    @TestApi
+    public static final String NAMESPACE_WINDOW_MANAGER = "android:window_manager";
+
+    /**
      * List of namespaces which can be read without READ_DEVICE_CONFIG permission
      *
      * @hide
@@ -307,11 +318,45 @@
     @TestApi
     public static final String NAMESPACE_PRIVACY = "privacy";
 
+    /**
+     * Interface for accessing keys belonging to {@link #NAMESPACE_WINDOW_MANAGER}.
+     * @hide
+     */
+    @TestApi
+    public interface WindowManager {
+
+        /**
+         * Key for accessing the system gesture exclusion limit (an integer in dp).
+         *
+         * @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER
+         * @hide
+         */
+        @TestApi
+        String KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP = "system_gesture_exclusion_limit_dp";
+
+        /**
+         * Key for controlling whether system gestures are implicitly excluded by windows requesting
+         * sticky immersive mode from apps that are targeting an SDK prior to Q.
+         *
+         * @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER
+         * @hide
+         */
+        @TestApi
+        String KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE =
+                "system_gestures_excluded_by_pre_q_sticky_immersive";
+
+        /**
+         * Key for controlling which packages are explicitly blocked from running at refresh rates
+         * higher than 90hz.
+         *
+         * @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER
+         * @hide
+         */
+        String KEY_HIGH_REFRESH_RATE_BLACKLIST = "high_refresh_rate_blacklist";
+    }
+
     private static final Object sLock = new Object();
     @GuardedBy("sLock")
-    private static ArrayMap<OnPropertyChangedListener, Pair<String, Executor>> sSingleListeners =
-            new ArrayMap<>();
-    @GuardedBy("sLock")
     private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =
             new ArrayMap<>();
     @GuardedBy("sLock")
@@ -510,48 +555,6 @@
      * This listener will be called whenever properties in the specified namespace change. Callbacks
      * will be made on the specified executor. Future calls to this method with the same listener
      * will replace the old namespace and executor. Remove the listener entirely by calling
-     * {@link #removeOnPropertyChangedListener(OnPropertyChangedListener)}.
-     *
-     * @param namespace                 The namespace containing properties to monitor.
-     * @param executor                  The executor which will be used to run callbacks.
-     * @param onPropertyChangedListener The listener to add.
-     * @hide
-     * @see #removeOnPropertyChangedListener(OnPropertyChangedListener)
-     * @removed
-     */
-    @SystemApi
-    @TestApi
-    @RequiresPermission(READ_DEVICE_CONFIG)
-    public static void addOnPropertyChangedListener(
-            @NonNull String namespace,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull OnPropertyChangedListener onPropertyChangedListener) {
-        enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(),
-                namespace);
-        synchronized (sLock) {
-            Pair<String, Executor> oldNamespace = sSingleListeners.get(onPropertyChangedListener);
-            if (oldNamespace == null) {
-                // Brand new listener, add it to the list.
-                sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
-                incrementNamespace(namespace);
-            } else if (namespace.equals(oldNamespace.first)) {
-                // Listener is already registered for this namespace, update executor just in case.
-                sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
-            } else {
-                // Update this listener from an old namespace to the new one.
-                decrementNamespace(sSingleListeners.get(onPropertyChangedListener).first);
-                sSingleListeners.put(onPropertyChangedListener, new Pair<>(namespace, executor));
-                incrementNamespace(namespace);
-            }
-        }
-    }
-
-    /**
-     * Add a listener for property changes.
-     * <p>
-     * This listener will be called whenever properties in the specified namespace change. Callbacks
-     * will be made on the specified executor. Future calls to this method with the same listener
-     * will replace the old namespace and executor. Remove the listener entirely by calling
      * {@link #removeOnPropertiesChangedListener(OnPropertiesChangedListener)}.
      *
      * @param namespace                   The namespace containing properties to monitor.
@@ -591,28 +594,6 @@
      * Remove a listener for property changes. The listener will receive no further notification of
      * property changes.
      *
-     * @param onPropertyChangedListener The listener to remove.
-     * @hide
-     * @see #addOnPropertyChangedListener(String, Executor, OnPropertyChangedListener)
-     * @removed
-     */
-    @SystemApi
-    @TestApi
-    public static void removeOnPropertyChangedListener(
-            @NonNull OnPropertyChangedListener onPropertyChangedListener) {
-        Preconditions.checkNotNull(onPropertyChangedListener);
-        synchronized (sLock) {
-            if (sSingleListeners.containsKey(onPropertyChangedListener)) {
-                decrementNamespace(sSingleListeners.get(onPropertyChangedListener).first);
-                sSingleListeners.remove(onPropertyChangedListener);
-            }
-        }
-    }
-
-    /**
-     * Remove a listener for property changes. The listener will receive no further notification of
-     * property changes.
-     *
      * @param onPropertiesChangedListener The listener to remove.
      * @hide
      * @see #addOnPropertiesChangedListener(String, Executor, OnPropertiesChangedListener)
@@ -709,7 +690,6 @@
             return;
         }
         synchronized (sLock) {
-            // OnPropertiesChangedListeners
             for (int i = 0; i < sListeners.size(); i++) {
                 if (namespace.equals(sListeners.valueAt(i).first)) {
                     final int j = i;
@@ -725,23 +705,9 @@
                     });
                 }
             }
-            // OnPropertyChangedListeners
-            for (int i = 0; i < sSingleListeners.size(); i++) {
-                if (namespace.equals(sSingleListeners.valueAt(i).first)) {
-                    final int j = i;
-                    sSingleListeners.valueAt(i).second.execute(new Runnable() {
-                        @Override
-                        public void run() {
-                            sSingleListeners.keyAt(j).onPropertyChanged(namespace, name, value);
-                        }
-
-                    });
-                }
-            }
         }
     }
 
-
     /**
      * Enforces READ_DEVICE_CONFIG permission if namespace is not one of public namespaces.
      * @hide
@@ -756,29 +722,6 @@
         }
     }
 
-
-    /**
-     * Interface for monitoring single property changes.
-     * <p>
-     * Override {@link #onPropertyChanged(String, String, String)} to handle callbacks for changes.
-     *
-     * @hide
-     * @removed
-     */
-    @SystemApi
-    @TestApi
-    public interface OnPropertyChangedListener {
-        /**
-         * Called when a property has changed.
-         *
-         * @param namespace The namespace containing the property which has changed.
-         * @param name      The name of the property which has changed.
-         * @param value     The new value of the property which has changed.
-         */
-        void onPropertyChanged(@NonNull String namespace, @NonNull String name,
-                @Nullable String value);
-    }
-
     /**
      * Interface for monitoring changes to properties.
      * <p>
diff --git a/core/java/android/provider/OWNERS b/core/java/android/provider/OWNERS
new file mode 100644
index 0000000..8b7d6ad
--- /dev/null
+++ b/core/java/android/provider/OWNERS
@@ -0,0 +1,4 @@
+per-file DeviceConfig.java = svetoslavganov@google.com
+per-file DeviceConfig.java = hackbod@google.com
+
+
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 64827bd..5308cd3 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -42,6 +42,7 @@
 import android.app.ActivityThread;
 import android.app.AppOpsManager;
 import android.app.Application;
+import android.app.AutomaticZenRule;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.SearchManager;
@@ -88,7 +89,7 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.MemoryIntArray;
-import android.view.inputmethod.InputMethodSystemProperty;
+import android.view.Display;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.widget.ILockSettings;
@@ -1312,7 +1313,17 @@
             "android.settings.NOTIFICATION_POLICY_ACCESS_DETAIL_SETTINGS";
 
     /**
-     * @hide
+     * Activity Action: Show the automatic do not disturb rule listing page
+     * <p>
+     *     Users can add, enable, disable, and remove automatic do not disturb rules from this
+     *     screen. See {@link NotificationManager#addAutomaticZenRule(AutomaticZenRule)} for more
+     *     details.
+     * </p>
+     * <p>
+     *     Input: Nothing
+     *     Output: Nothing
+     * </p>
+     *
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_CONDITION_PROVIDER_SETTINGS
@@ -4073,7 +4084,7 @@
          * preference, this rotation value will be used. Must be one of the
          * {@link android.view.Surface#ROTATION_0 Surface rotation constants}.
          *
-         * @see android.view.Display#getRotation
+         * @see Display#getRotation
          */
         public static final String USER_ROTATION = "user_rotation";
 
@@ -6321,13 +6332,15 @@
                 "lock_screen_allow_remote_input";
 
         /**
-         * Indicates which clock face to show on lock screen and AOD.
+         * Indicates which clock face to show on lock screen and AOD formatted as a serialized
+         * {@link org.json.JSONObject} with the format:
+         *     {"clock": id, "_applied_timestamp": timestamp}
          * @hide
          */
         public static final String LOCK_SCREEN_CUSTOM_CLOCK_FACE = "lock_screen_custom_clock_face";
 
         private static final Validator LOCK_SCREEN_CUSTOM_CLOCK_FACE_VALIDATOR =
-                ANY_STRING_VALIDATOR;
+                SettingsValidators.JSON_OBJECT_VALIDATOR;
 
         /**
          * Indicates which clock face to show on lock screen and AOD while docked.
@@ -7731,12 +7744,21 @@
         private static final Validator DOZE_TAP_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
 
         /**
-         * Gesture that wakes up the display, showing the ambient version of the status bar.
+         * Gesture that wakes up the display, showing some version of the lock screen.
          * @hide
          */
-        public static final String DOZE_WAKE_SCREEN_GESTURE = "doze_wake_screen_gesture";
+        public static final String DOZE_WAKE_LOCK_SCREEN_GESTURE = "doze_wake_screen_gesture";
 
-        private static final Validator DOZE_WAKE_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
+        private static final Validator DOZE_WAKE_LOCK_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
+
+        /**
+         * Gesture that wakes up the display, toggling between {@link Display.STATE_OFF} and
+         * {@link Display.STATE_DOZE}.
+         * @hide
+         */
+        public static final String DOZE_WAKE_DISPLAY_GESTURE = "doze_wake_display_gesture";
+
+        private static final Validator DOZE_WAKE_DISPLAY_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
 
         /**
          * Gesture that skips media.
@@ -7752,10 +7774,30 @@
          */
         public static final String SKIP_GESTURE_COUNT = "skip_gesture_count";
 
+        /**
+         * Count of non-gesture interaction.
+         * @hide
+         */
+        public static final String SKIP_TOUCH_COUNT = "skip_touch_count";
+
         private static final Validator SKIP_GESTURE_COUNT_VALIDATOR =
                 NON_NEGATIVE_INTEGER_VALIDATOR;
 
         /**
+         * Direction to advance media for skip gesture
+         * @hide
+         */
+        public static final String SKIP_DIRECTION = "skip_gesture_direction";
+
+        /**
+         * Only used if FeatureFlag "settings_skip_direction_mutable" is enabled.
+         * If feature flag is disabled, should assume SKIP_DIRECTION = 0.
+         *      0 / false = right to left to advance to next
+         *      1 / true = left to right to advance to next
+         */
+        private static final Validator SKIP_DIRECTION_VALIDATOR = BOOLEAN_VALIDATOR;
+
+        /**
          * Gesture that silences sound (alarms, notification, calls).
          * @hide
          */
@@ -7782,11 +7824,22 @@
         public static final String SILENCE_CALL_GESTURE_COUNT = "silence_call_gesture_count";
 
         /**
-         * Count of successful silence notification gestures.
+         * Count of non-gesture interaction.
          * @hide
          */
-        public static final String SILENCE_NOTIFICATION_GESTURE_COUNT =
-                "silence_notification_gesture_count";
+        public static final String SILENCE_ALARMS_TOUCH_COUNT = "silence_alarms_touch_count";
+
+        /**
+         * Count of non-gesture interaction.
+         * @hide
+         */
+        public static final String SILENCE_TIMER_TOUCH_COUNT = "silence_timer_touch_count";
+
+        /**
+         * Count of non-gesture interaction.
+         * @hide
+         */
+        public static final String SILENCE_CALL_TOUCH_COUNT = "silence_call_touch_count";
 
         private static final Validator SILENCE_GESTURE_COUNT_VALIDATOR =
                 NON_NEGATIVE_INTEGER_VALIDATOR;
@@ -8250,6 +8303,16 @@
                 BOOLEAN_VALIDATOR;
 
         /**
+         * Whether or not media is shown automatically when bypassing as a heads up.
+         * @hide
+         */
+        public static final String SHOW_MEDIA_WHEN_BYPASSING =
+                "show_media_when_bypassing";
+
+        private static final Validator SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR =
+                BOOLEAN_VALIDATOR;
+
+        /**
          * Whether or not face unlock requires attention. This is a cached value, the source of
          * truth is obtained through the HAL.
          * @hide
@@ -8943,10 +9006,12 @@
             DOZE_PICK_UP_GESTURE,
             DOZE_DOUBLE_TAP_GESTURE,
             DOZE_TAP_SCREEN_GESTURE,
-            DOZE_WAKE_SCREEN_GESTURE,
+            DOZE_WAKE_LOCK_SCREEN_GESTURE,
+            DOZE_WAKE_DISPLAY_GESTURE,
             NFC_PAYMENT_DEFAULT_COMPONENT,
             AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
             FACE_UNLOCK_KEYGUARD_ENABLED,
+            SHOW_MEDIA_WHEN_BYPASSING,
             FACE_UNLOCK_DISMISSES_KEYGUARD,
             FACE_UNLOCK_APP_ENABLED,
             FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
@@ -8987,15 +9052,19 @@
             UI_NIGHT_MODE,
             LOCK_SCREEN_WHEN_TRUST_LOST,
             SKIP_GESTURE,
+            SKIP_DIRECTION,
             SILENCE_GESTURE,
             THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
             NAVIGATION_MODE,
             AWARE_ENABLED,
             SKIP_GESTURE_COUNT,
+            SKIP_TOUCH_COUNT,
             SILENCE_ALARMS_GESTURE_COUNT,
-            SILENCE_NOTIFICATION_GESTURE_COUNT,
             SILENCE_CALL_GESTURE_COUNT,
             SILENCE_TIMER_GESTURE_COUNT,
+            SILENCE_ALARMS_TOUCH_COUNT,
+            SILENCE_CALL_TOUCH_COUNT,
+            SILENCE_TIMER_TOUCH_COUNT,
             DARK_MODE_DIALOG_SEEN,
             GLOBAL_ACTIONS_PANEL_ENABLED,
             AWARE_LOCK_ENABLED
@@ -9114,13 +9183,15 @@
             VALIDATORS.put(DOZE_PICK_UP_GESTURE, DOZE_PICK_UP_GESTURE_VALIDATOR);
             VALIDATORS.put(DOZE_DOUBLE_TAP_GESTURE, DOZE_DOUBLE_TAP_GESTURE_VALIDATOR);
             VALIDATORS.put(DOZE_TAP_SCREEN_GESTURE, DOZE_TAP_SCREEN_GESTURE_VALIDATOR);
-            VALIDATORS.put(DOZE_WAKE_SCREEN_GESTURE, DOZE_WAKE_SCREEN_GESTURE_VALIDATOR);
+            VALIDATORS.put(DOZE_WAKE_LOCK_SCREEN_GESTURE, DOZE_WAKE_LOCK_SCREEN_GESTURE_VALIDATOR);
+            VALIDATORS.put(DOZE_WAKE_DISPLAY_GESTURE, DOZE_WAKE_DISPLAY_GESTURE_VALIDATOR);
             VALIDATORS.put(NFC_PAYMENT_DEFAULT_COMPONENT, NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR);
             VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
                     AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);
             VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR);
             VALIDATORS.put(FACE_UNLOCK_DISMISSES_KEYGUARD,
                     FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR);
+            VALIDATORS.put(SHOW_MEDIA_WHEN_BYPASSING, SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR);
             VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR);
             VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
                     FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR);
@@ -9173,16 +9244,21 @@
             VALIDATORS.put(LOCK_SCREEN_CUSTOM_CLOCK_FACE, LOCK_SCREEN_CUSTOM_CLOCK_FACE_VALIDATOR);
             VALIDATORS.put(LOCK_SCREEN_WHEN_TRUST_LOST, LOCK_SCREEN_WHEN_TRUST_LOST_VALIDATOR);
             VALIDATORS.put(SKIP_GESTURE, SKIP_GESTURE_VALIDATOR);
+            VALIDATORS.put(SKIP_DIRECTION, SKIP_DIRECTION_VALIDATOR);
+            VALIDATORS.put(SKIP_DIRECTION, SKIP_DIRECTION_VALIDATOR);
             VALIDATORS.put(SILENCE_GESTURE, SILENCE_GESTURE_VALIDATOR);
             VALIDATORS.put(THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
                     THEME_CUSTOMIZATION_OVERLAY_PACKAGES_VALIDATOR);
             VALIDATORS.put(NAVIGATION_MODE, NAVIGATION_MODE_VALIDATOR);
             VALIDATORS.put(AWARE_ENABLED, AWARE_ENABLED_VALIDATOR);
             VALIDATORS.put(SKIP_GESTURE_COUNT, SKIP_GESTURE_COUNT_VALIDATOR);
+            VALIDATORS.put(SKIP_TOUCH_COUNT, SKIP_GESTURE_COUNT_VALIDATOR);
             VALIDATORS.put(SILENCE_ALARMS_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
             VALIDATORS.put(SILENCE_TIMER_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
             VALIDATORS.put(SILENCE_CALL_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
-            VALIDATORS.put(SILENCE_NOTIFICATION_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
+            VALIDATORS.put(SILENCE_ALARMS_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
+            VALIDATORS.put(SILENCE_TIMER_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
+            VALIDATORS.put(SILENCE_CALL_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
             VALIDATORS.put(ODI_CAPTIONS_ENABLED, ODI_CAPTIONS_ENABLED_VALIDATOR);
             VALIDATORS.put(DARK_MODE_DIALOG_SEEN, BOOLEAN_VALIDATOR);
             VALIDATORS.put(UI_NIGHT_MODE, UI_NIGHT_MODE_VALIDATOR);
@@ -9221,13 +9297,6 @@
             CLONE_TO_MANAGED_PROFILE.add(LOCATION_MODE);
             CLONE_TO_MANAGED_PROFILE.add(LOCATION_PROVIDERS_ALLOWED);
             CLONE_TO_MANAGED_PROFILE.add(SHOW_IME_WITH_HARD_KEYBOARD);
-            if (!InputMethodSystemProperty.PER_PROFILE_IME_ENABLED) {
-                CLONE_TO_MANAGED_PROFILE.add(DEFAULT_INPUT_METHOD);
-                CLONE_TO_MANAGED_PROFILE.add(ENABLED_INPUT_METHODS);
-                CLONE_TO_MANAGED_PROFILE.add(SELECTED_INPUT_METHOD_SUBTYPE);
-                CLONE_TO_MANAGED_PROFILE.add(SELECTED_SPELL_CHECKER);
-                CLONE_TO_MANAGED_PROFILE.add(SELECTED_SPELL_CHECKER_SUBTYPE);
-            }
         }
 
         /** @hide */
@@ -11644,16 +11713,6 @@
                 = "activity_starts_logging_enabled";
 
         /**
-         * Feature flag to enable or disable the background activity starts.
-         * When disabled, apps aren't allowed to start activities unless they're in the foreground.
-         * Type: int (0 for false, 1 for true)
-         * Default: 1
-         * @hide
-         */
-        public static final String BACKGROUND_ACTIVITY_STARTS_ENABLED =
-                "background_activity_starts_enabled";
-
-        /**
          * @hide
          * @see com.android.server.appbinding.AppBindingConstants
          */
@@ -12670,6 +12729,14 @@
         public static final String GAME_DRIVER_OPT_IN_APPS = "game_driver_opt_in_apps";
 
         /**
+         * List of Apps selected to use prerelease Game Driver.
+         * i.e. <pkg1>,<pkg2>,...,<pkgN>
+         * @hide
+         */
+        public static final String GAME_DRIVER_PRERELEASE_OPT_IN_APPS =
+                "game_driver_prerelease_opt_in_apps";
+
+        /**
          * List of Apps selected not to use Game Driver.
          * i.e. <pkg1>,<pkg2>,...,<pkgN>
          * @hide
@@ -13546,6 +13613,16 @@
                 "location_settings_link_to_permissions_enabled";
 
         /**
+         * Flag to set the waiting time for removing invisible euicc profiles inside System >
+         * Settings.
+         * Type: long
+         *
+         * @hide
+         */
+        public static final String EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS =
+                "euicc_removing_invisible_profiles_timeout_millis";
+
+        /**
          * Flag to set the waiting time for euicc factory reset inside System > Settings
          * Type: long
          *
@@ -13574,39 +13651,6 @@
                 "location_global_kill_switch";
 
         /**
-         * If set to 1, the device identifier check will be relaxed to the previous READ_PHONE_STATE
-         * permission check for 3P apps.
-         *
-         * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
-         *
-         * @hide
-         */
-        public static final String PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED =
-                "privileged_device_identifier_3p_check_relaxed";
-
-        /**
-         * If set to 1, the device identifier check will be relaxed to the previous READ_PHONE_STATE
-         * permission check for preloaded non-privileged apps.
-         *
-         * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
-         *
-         * @hide
-         */
-        public static final String PRIVILEGED_DEVICE_IDENTIFIER_NON_PRIV_CHECK_RELAXED =
-                "privileged_device_identifier_non_priv_check_relaxed";
-
-        /**
-         * If set to 1, the device identifier check will be relaxed to the previous READ_PHONE_STATE
-         * permission check for preloaded privileged apps.
-         *
-         * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
-         *
-         * @hide
-         */
-        public static final String PRIVILEGED_DEVICE_IDENTIFIER_PRIV_CHECK_RELAXED =
-                "privileged_device_identifier_priv_check_relaxed";
-
-        /**
          * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored
          * and restoring to lower version of platform API will be skipped.
          *
@@ -15413,4 +15457,4 @@
         }
         return packages[0];
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index c65e773..1cd2d62 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -224,13 +224,21 @@
          */
         public static final int TYPE_CONTEXT_COMMITTED = 4;
 
+        /**
+         * A dataset selector was shown.
+         *
+         * <p>This event is fired whenever the autofill UI was presented to the user.</p>
+         */
+        public static final int TYPE_DATASETS_SHOWN = 5;
+
         /** @hide */
         @IntDef(prefix = { "TYPE_" }, value = {
                 TYPE_DATASET_SELECTED,
                 TYPE_DATASET_AUTHENTICATION_SELECTED,
                 TYPE_AUTHENTICATION_SELECTED,
                 TYPE_SAVE_SHOWN,
-                TYPE_CONTEXT_COMMITTED
+                TYPE_CONTEXT_COMMITTED,
+                TYPE_DATASETS_SHOWN
         })
         @Retention(RetentionPolicy.SOURCE)
         @interface EventIds{}
@@ -473,7 +481,7 @@
                 @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
                 @Nullable AutofillId[] detectedFieldIds,
                 @Nullable FieldClassification[] detectedFieldClassifications) {
-            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_CONTEXT_COMMITTED,
+            mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_DATASETS_SHOWN,
                     "eventType");
             mDatasetId = datasetId;
             mClientState = clientState;
diff --git a/core/java/android/service/gatekeeper/GateKeeperResponse.aidl b/core/java/android/service/gatekeeper/GateKeeperResponse.aidl
deleted file mode 100644
index 966606e..0000000
--- a/core/java/android/service/gatekeeper/GateKeeperResponse.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-package android.service.gatekeeper;
-
-/**
- * Response object for a GateKeeper verification request.
- * @hide
- */
-parcelable GateKeeperResponse;
-
diff --git a/core/java/android/service/gatekeeper/IGateKeeperService.aidl b/core/java/android/service/gatekeeper/IGateKeeperService.aidl
deleted file mode 100644
index abc6466..0000000
--- a/core/java/android/service/gatekeeper/IGateKeeperService.aidl
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.
- */
-
-package android.service.gatekeeper;
-
-import android.service.gatekeeper.GateKeeperResponse;
-
-/**
- * Interface for communication with GateKeeper, the
- * secure password storage daemon.
- *
- * This must be kept manually in sync with system/core/gatekeeperd
- * until AIDL can generate both C++ and Java bindings.
- *
- * @hide
- */
-interface IGateKeeperService {
-    /**
-     * Enrolls a password, returning the handle to the enrollment to be stored locally.
-     * @param uid The Android user ID associated to this enrollment
-     * @param currentPasswordHandle The previously enrolled handle, or null if none
-     * @param currentPassword The previously enrolled plaintext password, or null if none.
-     *                        If provided, must verify against the currentPasswordHandle.
-     * @param desiredPassword The new desired password, for which a handle will be returned
-     *                        upon success.
-     * @return an EnrollResponse or null on failure
-     */
-    GateKeeperResponse enroll(int uid, in byte[] currentPasswordHandle, in byte[] currentPassword,
-            in byte[] desiredPassword);
-
-    /**
-     * Verifies an enrolled handle against a provided, plaintext blob.
-     * @param uid The Android user ID associated to this enrollment
-     * @param enrolledPasswordHandle The handle against which the provided password will be
-     *                               verified.
-     * @param The plaintext blob to verify against enrolledPassword.
-     * @return a VerifyResponse, or null on failure.
-     */
-    GateKeeperResponse verify(int uid, in byte[] enrolledPasswordHandle, in byte[] providedPassword);
-
-    /**
-     * Verifies an enrolled handle against a provided, plaintext blob.
-     * @param uid The Android user ID associated to this enrollment
-     * @param challenge a challenge to authenticate agaisnt the device credential. If successful
-     *                  authentication occurs, this value will be written to the returned
-     *                  authentication attestation.
-     * @param enrolledPasswordHandle The handle against which the provided password will be
-     *                               verified.
-     * @param The plaintext blob to verify against enrolledPassword.
-     * @return a VerifyResponse with an attestation, or null on failure.
-     */
-    GateKeeperResponse verifyChallenge(int uid, long challenge, in byte[] enrolledPasswordHandle,
-            in byte[] providedPassword);
-
-    /**
-     * Retrieves the secure identifier for the user with the provided Android ID,
-     * or 0 if none is found.
-     * @param uid the Android user id
-     */
-    long getSecureUserId(int uid);
-
-    /**
-     * Clears secure user id associated with the provided Android ID.
-     * Must be called when password is set to NONE.
-     * @param uid the Android user id.
-     */
-    void clearSecureUserId(int uid);
-
-    /**
-     * Notifies gatekeeper that device setup has been completed and any potentially still existing
-     * state from before a factory reset can be cleaned up (if it has not been already).
-     */
-    void reportDeviceSetupComplete();
-}
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 45480cb..7d3b13b 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -77,6 +77,7 @@
 
     private Provider mProvider;
     private INotificationManager mNoMan;
+    boolean mIsConnected;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
@@ -179,7 +180,7 @@
         try {
             noMan.requestUnbindProvider(mProvider);
             // Disable future messages.
-            mProvider = null;
+            mIsConnected = false;
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
         }
@@ -233,16 +234,16 @@
      */
     @TestApi
     public boolean isBound() {
-        if (mProvider == null) {
+        if (!mIsConnected) {
             Log.w(TAG, "Condition provider service not yet bound.");
-            return false;
         }
-        return true;
+        return mIsConnected;
     }
 
     private final class Provider extends IConditionProvider.Stub {
         @Override
         public void onConnected() {
+            mIsConnected = true;
             mHandler.obtainMessage(H.ON_CONNECTED).sendToTarget();
         }
 
@@ -265,7 +266,7 @@
         @Override
         public void handleMessage(Message msg) {
             String name = null;
-            if (!isBound()) {
+            if (!mIsConnected) {
                 return;
             }
             try {
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 3ec21e3..b44c9d5 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -42,7 +42,6 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -53,7 +52,6 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.Log;
 import android.widget.RemoteViews;
 
@@ -64,8 +62,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * A service that receives calls from the system when new notifications are
@@ -1201,20 +1199,25 @@
         }
     }
 
-    /** Convert new-style Icons to legacy representations for pre-M clients. */
-    private void createLegacyIconExtras(Notification n) {
-        Icon smallIcon = n.getSmallIcon();
-        Icon largeIcon = n.getLargeIcon();
-        if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) {
-            n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId());
-            n.icon = smallIcon.getResId();
-        }
-        if (largeIcon != null) {
-            Drawable d = largeIcon.loadDrawable(getContext());
-            if (d != null && d instanceof BitmapDrawable) {
-                final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap();
-                n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits);
-                n.largeIcon = largeIconBits;
+    /**
+     * Convert new-style Icons to legacy representations for pre-M clients.
+     * @hide
+     */
+    public final void createLegacyIconExtras(Notification n) {
+        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.M) {
+            Icon smallIcon = n.getSmallIcon();
+            Icon largeIcon = n.getLargeIcon();
+            if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) {
+                n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId());
+                n.icon = smallIcon.getResId();
+            }
+            if (largeIcon != null) {
+                Drawable d = largeIcon.loadDrawable(getContext());
+                if (d != null && d instanceof BitmapDrawable) {
+                    final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap();
+                    n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits);
+                    n.largeIcon = largeIconBits;
+                }
             }
         }
     }
@@ -1442,7 +1445,7 @@
      */
     @GuardedBy("mLock")
     public final void applyUpdateLocked(NotificationRankingUpdate update) {
-        mRankingMap = new RankingMap(update);
+        mRankingMap = update.getRankingMap();
     }
 
     /** @hide */
@@ -1480,14 +1483,14 @@
          */
         public static final int USER_SENTIMENT_POSITIVE = 1;
 
-        /** @hide */
+       /** @hide */
         @IntDef(prefix = { "USER_SENTIMENT_" }, value = {
                 USER_SENTIMENT_NEGATIVE, USER_SENTIMENT_NEUTRAL, USER_SENTIMENT_POSITIVE
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface UserSentiment {}
 
-        private String mKey;
+        private @NonNull String mKey;
         private int mRank = -1;
         private boolean mIsAmbient;
         private boolean mMatchesInterruptionFilter;
@@ -1512,7 +1515,70 @@
         private ArrayList<CharSequence> mSmartReplies;
         private boolean mCanBubble;
 
-        public Ranking() {}
+        private static final int PARCEL_VERSION = 2;
+
+        public Ranking() { }
+
+        // You can parcel it, but it's not Parcelable
+        /** @hide */
+        @VisibleForTesting
+        public void writeToParcel(Parcel out, int flags) {
+            final long start = out.dataPosition();
+            out.writeInt(PARCEL_VERSION);
+            out.writeString(mKey);
+            out.writeInt(mRank);
+            out.writeBoolean(mIsAmbient);
+            out.writeBoolean(mMatchesInterruptionFilter);
+            out.writeInt(mVisibilityOverride);
+            out.writeInt(mSuppressedVisualEffects);
+            out.writeInt(mImportance);
+            out.writeCharSequence(mImportanceExplanation);
+            out.writeString(mOverrideGroupKey);
+            out.writeParcelable(mChannel, flags);
+            out.writeStringList(mOverridePeople);
+            out.writeTypedList(mSnoozeCriteria, flags);
+            out.writeBoolean(mShowBadge);
+            out.writeInt(mUserSentiment);
+            out.writeBoolean(mHidden);
+            out.writeLong(mLastAudiblyAlertedMs);
+            out.writeBoolean(mNoisy);
+            out.writeTypedList(mSmartActions, flags);
+            out.writeCharSequenceList(mSmartReplies);
+            out.writeBoolean(mCanBubble);
+        }
+
+        /** @hide */
+        @VisibleForTesting
+        public Ranking(Parcel in) {
+            final ClassLoader cl = getClass().getClassLoader();
+
+            final int version = in.readInt();
+            if (version != PARCEL_VERSION) {
+                throw new IllegalArgumentException("malformed Ranking parcel: " + in + " version "
+                        + version + ", expected " + PARCEL_VERSION);
+            }
+            mKey = in.readString();
+            mRank = in.readInt();
+            mIsAmbient = in.readBoolean();
+            mMatchesInterruptionFilter = in.readBoolean();
+            mVisibilityOverride = in.readInt();
+            mSuppressedVisualEffects = in.readInt();
+            mImportance = in.readInt();
+            mImportanceExplanation = in.readCharSequence(); // may be null
+            mOverrideGroupKey = in.readString(); // may be null
+            mChannel = (NotificationChannel) in.readParcelable(cl); // may be null
+            mOverridePeople = in.createStringArrayList();
+            mSnoozeCriteria = in.createTypedArrayList(SnoozeCriterion.CREATOR);
+            mShowBadge = in.readBoolean();
+            mUserSentiment = in.readInt();
+            mHidden = in.readBoolean();
+            mLastAudiblyAlertedMs = in.readLong();
+            mNoisy = in.readBoolean();
+            mSmartActions = in.createTypedArrayList(Notification.Action.CREATOR);
+            mSmartReplies = in.readCharSequenceList();
+            mCanBubble = in.readBoolean();
+        }
+
 
         /**
          * Returns the key of the notification this Ranking applies to.
@@ -1737,6 +1803,31 @@
         }
 
         /**
+         * @hide
+         */
+        public void populate(Ranking other) {
+            populate(other.mKey,
+                    other.mRank,
+                    other.mMatchesInterruptionFilter,
+                    other.mVisibilityOverride,
+                    other.mSuppressedVisualEffects,
+                    other.mImportance,
+                    other.mImportanceExplanation,
+                    other.mOverrideGroupKey,
+                    other.mChannel,
+                    other.mOverridePeople,
+                    other.mSnoozeCriteria,
+                    other.mShowBadge,
+                    other.mUserSentiment,
+                    other.mHidden,
+                    other.mLastAudiblyAlertedMs,
+                    other.mNoisy,
+                    other.mSmartActions,
+                    other.mSmartReplies,
+                    other.mCanBubble);
+        }
+
+        /**
          * {@hide}
          */
         public static String importanceToString(int importance) {
@@ -1758,6 +1849,35 @@
                     return "UNKNOWN(" + String.valueOf(importance) + ")";
             }
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Ranking other = (Ranking) o;
+            return Objects.equals(mKey, other.mKey)
+                    && Objects.equals(mRank, other.mRank)
+                    && Objects.equals(mMatchesInterruptionFilter, other.mMatchesInterruptionFilter)
+                    && Objects.equals(mVisibilityOverride, other.mVisibilityOverride)
+                    && Objects.equals(mSuppressedVisualEffects, other.mSuppressedVisualEffects)
+                    && Objects.equals(mImportance, other.mImportance)
+                    && Objects.equals(mImportanceExplanation, other.mImportanceExplanation)
+                    && Objects.equals(mOverrideGroupKey, other.mOverrideGroupKey)
+                    && Objects.equals(mChannel, other.mChannel)
+                    && Objects.equals(mOverridePeople, other.mOverridePeople)
+                    && Objects.equals(mSnoozeCriteria, other.mSnoozeCriteria)
+                    && Objects.equals(mShowBadge, other.mShowBadge)
+                    && Objects.equals(mUserSentiment, other.mUserSentiment)
+                    && Objects.equals(mHidden, other.mHidden)
+                    && Objects.equals(mLastAudiblyAlertedMs, other.mLastAudiblyAlertedMs)
+                    && Objects.equals(mNoisy, other.mNoisy)
+                    // Action.equals() doesn't exist so let's just compare list lengths
+                    && ((mSmartActions == null ? 0 : mSmartActions.size())
+                        == (other.mSmartActions == null ? 0 : other.mSmartActions.size()))
+                    && Objects.equals(mSmartReplies, other.mSmartReplies)
+                    && Objects.equals(mCanBubble, other.mCanBubble);
+        }
     }
 
     /**
@@ -1769,30 +1889,74 @@
      * notifications active at the time of retrieval.
      */
     public static class RankingMap implements Parcelable {
-        private final NotificationRankingUpdate mRankingUpdate;
-        private ArrayMap<String,Integer> mRanks;
-        private ArraySet<Object> mIntercepted;
-        private ArrayMap<String, Integer> mVisibilityOverrides;
-        private ArrayMap<String, Integer> mSuppressedVisualEffects;
-        private ArrayMap<String, Integer> mImportance;
-        private ArrayMap<String, String> mImportanceExplanation;
-        private ArrayMap<String, String> mOverrideGroupKeys;
-        private ArrayMap<String, NotificationChannel> mChannels;
-        private ArrayMap<String, ArrayList<String>> mOverridePeople;
-        private ArrayMap<String, ArrayList<SnoozeCriterion>> mSnoozeCriteria;
-        private ArrayMap<String, Boolean> mShowBadge;
-        private ArrayMap<String, Integer> mUserSentiment;
-        private ArrayMap<String, Boolean> mHidden;
-        private ArrayMap<String, Long> mLastAudiblyAlerted;
-        private ArrayMap<String, Boolean> mNoisy;
-        private ArrayMap<String, ArrayList<Notification.Action>> mSmartActions;
-        private ArrayMap<String, ArrayList<CharSequence>> mSmartReplies;
-        private boolean[] mCanBubble;
+        private ArrayList<String> mOrderedKeys = new ArrayList<>();
+        // Note: all String keys should be intern'd as pointers into mOrderedKeys
+        private ArrayMap<String, Ranking> mRankings = new ArrayMap<>();
 
-        private RankingMap(NotificationRankingUpdate rankingUpdate) {
-            mRankingUpdate = rankingUpdate;
+        /**
+         * @hide
+         */
+        public RankingMap(Ranking[] rankings) {
+            for (int i = 0; i < rankings.length; i++) {
+                final String key = rankings[i].getKey();
+                mOrderedKeys.add(key);
+                mRankings.put(key, rankings[i]);
+            }
         }
 
+        // -- parcelable interface --
+
+        private RankingMap(Parcel in) {
+            final ClassLoader cl = getClass().getClassLoader();
+            final int count = in.readInt();
+            mOrderedKeys.ensureCapacity(count);
+            mRankings.ensureCapacity(count);
+            for (int i = 0; i < count; i++) {
+                final Ranking r = new Ranking(in);
+                final String key = r.getKey();
+                mOrderedKeys.add(key);
+                mRankings.put(key, r);
+            }
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            RankingMap other = (RankingMap) o;
+
+            return mOrderedKeys.equals(other.mOrderedKeys)
+                    && mRankings.equals(other.mRankings);
+
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            final int count = mOrderedKeys.size();
+            out.writeInt(count);
+            for (int i = 0; i < count; i++) {
+                mRankings.get(mOrderedKeys.get(i)).writeToParcel(out, flags);
+            }
+        }
+
+        public static final @android.annotation.NonNull Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
+            @Override
+            public RankingMap createFromParcel(Parcel source) {
+                return new RankingMap(source);
+            }
+
+            @Override
+            public RankingMap[] newArray(int size) {
+                return new RankingMap[size];
+            }
+        };
+
         /**
          * Request the list of notification keys in their current ranking
          * order.
@@ -1800,7 +1964,7 @@
          * @return An array of active notification keys, in their ranking order.
          */
         public String[] getOrderedKeys() {
-            return mRankingUpdate.getOrderedKeys();
+            return mOrderedKeys.toArray(new String[0]);
         }
 
         /**
@@ -1808,381 +1972,26 @@
          * with the given key.
          *
          * @return true if a valid key has been passed and outRanking has
-         *     been populated; false otherwise
+         * been populated; false otherwise
          */
         public boolean getRanking(String key, Ranking outRanking) {
-            int rank = getRank(key);
-            outRanking.populate(key, rank, !isIntercepted(key),
-                    getVisibilityOverride(key), getSuppressedVisualEffects(key),
-                    getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key),
-                    getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
-                    getShowBadge(key), getUserSentiment(key), getHidden(key),
-                    getLastAudiblyAlerted(key), getNoisy(key), getSmartActions(key),
-                    getSmartReplies(key), canBubble(key));
-            return rank >= 0;
-        }
-
-        private int getRank(String key) {
-            synchronized (this) {
-                if (mRanks == null) {
-                    buildRanksLocked();
-                }
+            if (mRankings.containsKey(key)) {
+                outRanking.populate(mRankings.get(key));
+                return true;
             }
-            Integer rank = mRanks.get(key);
-            return rank != null ? rank : -1;
+            return false;
         }
 
-        private boolean isIntercepted(String key) {
-            synchronized (this) {
-                if (mIntercepted == null) {
-                    buildInterceptedSetLocked();
-                }
-            }
-            return mIntercepted.contains(key);
+        /**
+         * Get a reference to the actual Ranking object corresponding to the key.
+         * Used only by unit tests.
+         *
+         * @hide
+         */
+        @VisibleForTesting
+        public Ranking getRawRankingObject(String key) {
+            return mRankings.get(key);
         }
-
-        private int getVisibilityOverride(String key) {
-            synchronized (this) {
-                if (mVisibilityOverrides == null) {
-                    buildVisibilityOverridesLocked();
-                }
-            }
-            Integer override = mVisibilityOverrides.get(key);
-            if (override == null) {
-                return Ranking.VISIBILITY_NO_OVERRIDE;
-            }
-            return override.intValue();
-        }
-
-        private int getSuppressedVisualEffects(String key) {
-            synchronized (this) {
-                if (mSuppressedVisualEffects == null) {
-                    buildSuppressedVisualEffectsLocked();
-                }
-            }
-            Integer suppressed = mSuppressedVisualEffects.get(key);
-            if (suppressed == null) {
-                return 0;
-            }
-            return suppressed.intValue();
-        }
-
-        private int getImportance(String key) {
-            synchronized (this) {
-                if (mImportance == null) {
-                    buildImportanceLocked();
-                }
-            }
-            Integer importance = mImportance.get(key);
-            if (importance == null) {
-                return NotificationManager.IMPORTANCE_DEFAULT;
-            }
-            return importance.intValue();
-        }
-
-        private String getImportanceExplanation(String key) {
-            synchronized (this) {
-                if (mImportanceExplanation == null) {
-                    buildImportanceExplanationLocked();
-                }
-            }
-            return mImportanceExplanation.get(key);
-        }
-
-        private String getOverrideGroupKey(String key) {
-            synchronized (this) {
-                if (mOverrideGroupKeys == null) {
-                    buildOverrideGroupKeys();
-                }
-            }
-            return mOverrideGroupKeys.get(key);
-        }
-
-        private NotificationChannel getChannel(String key) {
-            synchronized (this) {
-                if (mChannels == null) {
-                    buildChannelsLocked();
-                }
-            }
-            return mChannels.get(key);
-        }
-
-        private ArrayList<String> getOverridePeople(String key) {
-            synchronized (this) {
-                if (mOverridePeople == null) {
-                    buildOverridePeopleLocked();
-                }
-            }
-            return mOverridePeople.get(key);
-        }
-
-        private ArrayList<SnoozeCriterion> getSnoozeCriteria(String key) {
-            synchronized (this) {
-                if (mSnoozeCriteria == null) {
-                    buildSnoozeCriteriaLocked();
-                }
-            }
-            return mSnoozeCriteria.get(key);
-        }
-
-        private boolean getShowBadge(String key) {
-            synchronized (this) {
-                if (mShowBadge == null) {
-                    buildShowBadgeLocked();
-                }
-            }
-            Boolean showBadge = mShowBadge.get(key);
-            return showBadge == null ? false : showBadge.booleanValue();
-        }
-
-        private int getUserSentiment(String key) {
-            synchronized (this) {
-                if (mUserSentiment == null) {
-                    buildUserSentimentLocked();
-                }
-            }
-            Integer userSentiment = mUserSentiment.get(key);
-            return userSentiment == null
-                    ? Ranking.USER_SENTIMENT_NEUTRAL : userSentiment.intValue();
-        }
-
-        private boolean getHidden(String key) {
-            synchronized (this) {
-                if (mHidden == null) {
-                    buildHiddenLocked();
-                }
-            }
-            Boolean hidden = mHidden.get(key);
-            return hidden == null ? false : hidden.booleanValue();
-        }
-
-        private long getLastAudiblyAlerted(String key) {
-            synchronized (this) {
-                if (mLastAudiblyAlerted == null) {
-                    buildLastAudiblyAlertedLocked();
-                }
-            }
-            Long lastAudibleAlerted = mLastAudiblyAlerted.get(key);
-            return lastAudibleAlerted == null ? -1 : lastAudibleAlerted.longValue();
-        }
-
-        private boolean getNoisy(String key) {
-            synchronized (this) {
-                if (mNoisy == null) {
-                    buildNoisyLocked();
-                }
-            }
-            Boolean noisy = mNoisy.get(key);
-            return noisy == null ? false : noisy.booleanValue();
-        }
-
-        private ArrayList<Notification.Action> getSmartActions(String key) {
-            synchronized (this) {
-                if (mSmartActions == null) {
-                    buildSmartActions();
-                }
-            }
-            return mSmartActions.get(key);
-        }
-
-        private ArrayList<CharSequence> getSmartReplies(String key) {
-            synchronized (this) {
-                if (mSmartReplies == null) {
-                    buildSmartReplies();
-                }
-            }
-            return mSmartReplies.get(key);
-        }
-
-        private boolean canBubble(String key) {
-            synchronized (this) {
-                if (mRanks == null) {
-                    buildRanksLocked();
-                }
-                if (mCanBubble == null) {
-                    mCanBubble = mRankingUpdate.getCanBubble();
-                }
-            }
-            int keyIndex = mRanks.getOrDefault(key, -1);
-            return keyIndex >= 0 ? mCanBubble[keyIndex] : false;
-        }
-
-        // Locked by 'this'
-        private void buildRanksLocked() {
-            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
-            mRanks = new ArrayMap<>(orderedKeys.length);
-            for (int i = 0; i < orderedKeys.length; i++) {
-                String key = orderedKeys[i];
-                mRanks.put(key, i);
-            }
-        }
-
-        // Locked by 'this'
-        private void buildInterceptedSetLocked() {
-            String[] dndInterceptedKeys = mRankingUpdate.getInterceptedKeys();
-            mIntercepted = new ArraySet<>(dndInterceptedKeys.length);
-            Collections.addAll(mIntercepted, dndInterceptedKeys);
-        }
-
-        private ArrayMap<String, Integer> buildIntMapFromBundle(Bundle bundle) {
-            ArrayMap<String, Integer> newMap = new ArrayMap<>(bundle.size());
-            for (String key : bundle.keySet()) {
-                newMap.put(key, bundle.getInt(key));
-            }
-            return newMap;
-        }
-
-        private ArrayMap<String, String> buildStringMapFromBundle(Bundle bundle) {
-            ArrayMap<String, String> newMap = new ArrayMap<>(bundle.size());
-            for (String key : bundle.keySet()) {
-                newMap.put(key, bundle.getString(key));
-            }
-            return newMap;
-        }
-
-        private ArrayMap<String, Boolean> buildBooleanMapFromBundle(Bundle bundle) {
-            ArrayMap<String, Boolean> newMap = new ArrayMap<>(bundle.size());
-            for (String key : bundle.keySet()) {
-                newMap.put(key, bundle.getBoolean(key));
-            }
-            return newMap;
-        }
-
-        private ArrayMap<String, Long> buildLongMapFromBundle(Bundle bundle) {
-            ArrayMap<String, Long> newMap = new ArrayMap<>(bundle.size());
-            for (String key : bundle.keySet()) {
-                newMap.put(key, bundle.getLong(key));
-            }
-            return newMap;
-        }
-
-        // Locked by 'this'
-        private void buildVisibilityOverridesLocked() {
-            mVisibilityOverrides = buildIntMapFromBundle(mRankingUpdate.getVisibilityOverrides());
-        }
-
-        // Locked by 'this'
-        private void buildSuppressedVisualEffectsLocked() {
-            mSuppressedVisualEffects =
-                buildIntMapFromBundle(mRankingUpdate.getSuppressedVisualEffects());
-        }
-
-        // Locked by 'this'
-        private void buildImportanceLocked() {
-            String[] orderedKeys = mRankingUpdate.getOrderedKeys();
-            int[] importance = mRankingUpdate.getImportance();
-            mImportance = new ArrayMap<>(orderedKeys.length);
-            for (int i = 0; i < orderedKeys.length; i++) {
-                String key = orderedKeys[i];
-                mImportance.put(key, importance[i]);
-            }
-        }
-
-        // Locked by 'this'
-        private void buildImportanceExplanationLocked() {
-            mImportanceExplanation =
-                buildStringMapFromBundle(mRankingUpdate.getImportanceExplanation());
-        }
-
-        // Locked by 'this'
-        private void buildOverrideGroupKeys() {
-            mOverrideGroupKeys = buildStringMapFromBundle(mRankingUpdate.getOverrideGroupKeys());
-        }
-
-        // Locked by 'this'
-        private void buildChannelsLocked() {
-            Bundle channels = mRankingUpdate.getChannels();
-            mChannels = new ArrayMap<>(channels.size());
-            for (String key : channels.keySet()) {
-                mChannels.put(key, channels.getParcelable(key));
-            }
-        }
-
-        // Locked by 'this'
-        private void buildOverridePeopleLocked() {
-            Bundle overridePeople = mRankingUpdate.getOverridePeople();
-            mOverridePeople = new ArrayMap<>(overridePeople.size());
-            for (String key : overridePeople.keySet()) {
-                mOverridePeople.put(key, overridePeople.getStringArrayList(key));
-            }
-        }
-
-        // Locked by 'this'
-        private void buildSnoozeCriteriaLocked() {
-            Bundle snoozeCriteria = mRankingUpdate.getSnoozeCriteria();
-            mSnoozeCriteria = new ArrayMap<>(snoozeCriteria.size());
-            for (String key : snoozeCriteria.keySet()) {
-                mSnoozeCriteria.put(key, snoozeCriteria.getParcelableArrayList(key));
-            }
-        }
-
-        // Locked by 'this'
-        private void buildShowBadgeLocked() {
-            mShowBadge = buildBooleanMapFromBundle(mRankingUpdate.getShowBadge());
-        }
-
-        // Locked by 'this'
-        private void buildUserSentimentLocked() {
-            mUserSentiment = buildIntMapFromBundle(mRankingUpdate.getUserSentiment());
-        }
-
-        // Locked by 'this'
-        private void buildHiddenLocked() {
-            mHidden = buildBooleanMapFromBundle(mRankingUpdate.getHidden());
-        }
-
-        // Locked by 'this'
-        private void buildLastAudiblyAlertedLocked() {
-            mLastAudiblyAlerted = buildLongMapFromBundle(mRankingUpdate.getLastAudiblyAlerted());
-        }
-
-        // Locked by 'this'
-        private void buildNoisyLocked() {
-            mNoisy = buildBooleanMapFromBundle(mRankingUpdate.getNoisy());
-        }
-
-        // Locked by 'this'
-        private void buildSmartActions() {
-            Bundle smartActions = mRankingUpdate.getSmartActions();
-            mSmartActions = new ArrayMap<>(smartActions.size());
-            for (String key : smartActions.keySet()) {
-                mSmartActions.put(key, smartActions.getParcelableArrayList(key));
-            }
-        }
-
-        // Locked by 'this'
-        private void buildSmartReplies() {
-            Bundle smartReplies = mRankingUpdate.getSmartReplies();
-            mSmartReplies = new ArrayMap<>(smartReplies.size());
-            for (String key : smartReplies.keySet()) {
-                mSmartReplies.put(key, smartReplies.getCharSequenceArrayList(key));
-            }
-        }
-
-        // ----------- Parcelable
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeParcelable(mRankingUpdate, flags);
-        }
-
-        public static final @android.annotation.NonNull Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
-            @Override
-            public RankingMap createFromParcel(Parcel source) {
-                NotificationRankingUpdate rankingUpdate = source.readParcelable(null);
-                return new RankingMap(rankingUpdate);
-            }
-
-            @Override
-            public RankingMap[] newArray(int size) {
-                return new RankingMap[size];
-            }
-        };
     }
 
     private final class MyHandler extends Handler {
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index c5c70f8..675c5cd 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -15,7 +15,6 @@
  */
 package android.service.notification;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -23,73 +22,18 @@
  * @hide
  */
 public class NotificationRankingUpdate implements Parcelable {
-    // TODO: Support incremental updates.
-    private final String[] mKeys;
-    private final String[] mInterceptedKeys;
-    private final Bundle mVisibilityOverrides;
-    private final Bundle mSuppressedVisualEffects;
-    private final int[] mImportance;
-    private final Bundle mImportanceExplanation;
-    private final Bundle mOverrideGroupKeys;
-    private final Bundle mChannels;
-    private final Bundle mOverridePeople;
-    private final Bundle mSnoozeCriteria;
-    private final Bundle mShowBadge;
-    private final Bundle mUserSentiment;
-    private final Bundle mHidden;
-    private final Bundle mSmartActions;
-    private final Bundle mSmartReplies;
-    private final Bundle mLastAudiblyAlerted;
-    private final Bundle mNoisy;
-    private final boolean[] mCanBubble;
+    private final NotificationListenerService.RankingMap mRankingMap;
 
-    public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
-            Bundle visibilityOverrides, Bundle suppressedVisualEffects,
-            int[] importance, Bundle explanation, Bundle overrideGroupKeys,
-            Bundle channels, Bundle overridePeople, Bundle snoozeCriteria,
-            Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions,
-            Bundle smartReplies, Bundle lastAudiblyAlerted, Bundle noisy, boolean[] canBubble) {
-        mKeys = keys;
-        mInterceptedKeys = interceptedKeys;
-        mVisibilityOverrides = visibilityOverrides;
-        mSuppressedVisualEffects = suppressedVisualEffects;
-        mImportance = importance;
-        mImportanceExplanation = explanation;
-        mOverrideGroupKeys = overrideGroupKeys;
-        mChannels = channels;
-        mOverridePeople = overridePeople;
-        mSnoozeCriteria = snoozeCriteria;
-        mShowBadge = showBadge;
-        mUserSentiment = userSentiment;
-        mHidden = hidden;
-        mSmartActions = smartActions;
-        mSmartReplies = smartReplies;
-        mLastAudiblyAlerted = lastAudiblyAlerted;
-        mNoisy = noisy;
-        mCanBubble = canBubble;
+    public NotificationRankingUpdate(NotificationListenerService.Ranking[] rankings) {
+        mRankingMap = new NotificationListenerService.RankingMap(rankings);
     }
 
     public NotificationRankingUpdate(Parcel in) {
-        mKeys = in.readStringArray();
-        mInterceptedKeys = in.readStringArray();
-        mVisibilityOverrides = in.readBundle();
-        mSuppressedVisualEffects = in.readBundle();
-        mImportance = new int[mKeys.length];
-        in.readIntArray(mImportance);
-        mImportanceExplanation = in.readBundle();
-        mOverrideGroupKeys = in.readBundle();
-        mChannels = in.readBundle();
-        mOverridePeople = in.readBundle();
-        mSnoozeCriteria = in.readBundle();
-        mShowBadge = in.readBundle();
-        mUserSentiment = in.readBundle();
-        mHidden = in.readBundle();
-        mSmartActions = in.readBundle();
-        mSmartReplies = in.readBundle();
-        mLastAudiblyAlerted = in.readBundle();
-        mNoisy = in.readBundle();
-        mCanBubble = new boolean[mKeys.length];
-        in.readBooleanArray(mCanBubble);
+        mRankingMap = in.readParcelable(getClass().getClassLoader());
+    }
+
+    public NotificationListenerService.RankingMap getRankingMap() {
+        return mRankingMap;
     }
 
     @Override
@@ -98,25 +42,17 @@
     }
 
     @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        NotificationRankingUpdate other = (NotificationRankingUpdate) o;
+        return mRankingMap.equals(other.mRankingMap);
+    }
+
+    @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeStringArray(mKeys);
-        out.writeStringArray(mInterceptedKeys);
-        out.writeBundle(mVisibilityOverrides);
-        out.writeBundle(mSuppressedVisualEffects);
-        out.writeIntArray(mImportance);
-        out.writeBundle(mImportanceExplanation);
-        out.writeBundle(mOverrideGroupKeys);
-        out.writeBundle(mChannels);
-        out.writeBundle(mOverridePeople);
-        out.writeBundle(mSnoozeCriteria);
-        out.writeBundle(mShowBadge);
-        out.writeBundle(mUserSentiment);
-        out.writeBundle(mHidden);
-        out.writeBundle(mSmartActions);
-        out.writeBundle(mSmartReplies);
-        out.writeBundle(mLastAudiblyAlerted);
-        out.writeBundle(mNoisy);
-        out.writeBooleanArray(mCanBubble);
+        out.writeParcelable(mRankingMap, flags);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<NotificationRankingUpdate> CREATOR
@@ -129,76 +65,4 @@
             return new NotificationRankingUpdate[size];
         }
     };
-
-    public String[] getOrderedKeys() {
-        return mKeys;
-    }
-
-    public String[] getInterceptedKeys() {
-        return mInterceptedKeys;
-    }
-
-    public Bundle getVisibilityOverrides() {
-        return mVisibilityOverrides;
-    }
-
-    public Bundle getSuppressedVisualEffects() {
-        return mSuppressedVisualEffects;
-    }
-
-    public int[] getImportance() {
-        return mImportance;
-    }
-
-    public Bundle getImportanceExplanation() {
-        return mImportanceExplanation;
-    }
-
-    public Bundle getOverrideGroupKeys() {
-        return mOverrideGroupKeys;
-    }
-
-    public Bundle getChannels() {
-        return mChannels;
-    }
-
-    public Bundle getOverridePeople() {
-        return mOverridePeople;
-    }
-
-    public Bundle getSnoozeCriteria() {
-        return mSnoozeCriteria;
-    }
-
-    public Bundle getShowBadge() {
-        return mShowBadge;
-    }
-
-    public Bundle getUserSentiment() {
-        return mUserSentiment;
-    }
-
-    public Bundle getHidden() {
-        return mHidden;
-    }
-
-    public Bundle getSmartActions() {
-        return mSmartActions;
-    }
-
-    public Bundle getSmartReplies() {
-        return mSmartReplies;
-    }
-
-    public Bundle getLastAudiblyAlerted() {
-        return mLastAudiblyAlerted;
-    }
-
-    public Bundle getNoisy() {
-        return mNoisy;
-    }
-
-    public boolean[] getCanBubble() {
-        return mCanBubble;
-    }
 }
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 8512a0b..905c781 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -20,6 +20,7 @@
 import android.annotation.UnsupportedAppUsage;
 import android.app.Notification;
 import android.app.NotificationManager;
+import android.app.Person;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -32,6 +33,8 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
+import java.util.ArrayList;
+
 /**
  * Class encapsulating a Notification. Sent by the NotificationManagerService to clients including
  * the status bar and any {@link android.service.notification.NotificationListenerService}s.
@@ -166,6 +169,7 @@
 
     /**
      * Returns true if application asked that this notification be part of a group.
+     *
      * @hide
      */
     public boolean isAppGroup() {
@@ -203,18 +207,16 @@
         return 0;
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<StatusBarNotification> CREATOR
-            = new Parcelable.Creator<StatusBarNotification>()
-    {
-        public StatusBarNotification createFromParcel(Parcel parcel)
-        {
-            return new StatusBarNotification(parcel);
-        }
+    public static final @android.annotation.NonNull
+            Parcelable.Creator<StatusBarNotification> CREATOR =
+            new Parcelable.Creator<StatusBarNotification>() {
+                public StatusBarNotification createFromParcel(Parcel parcel) {
+                    return new StatusBarNotification(parcel);
+                }
 
-        public StatusBarNotification[] newArray(int size)
-        {
-            return new StatusBarNotification[size];
-        }
+            public StatusBarNotification[] newArray(int size) {
+                return new StatusBarNotification[size];
+            }
     };
 
     /**
@@ -243,14 +245,16 @@
                 this.key, this.notification);
     }
 
-    /** Convenience method to check the notification's flags for
+    /**
+     * Convenience method to check the notification's flags for
      * {@link Notification#FLAG_ONGOING_EVENT}.
      */
     public boolean isOngoing() {
         return (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0;
     }
 
-    /** Convenience method to check the notification's flags for
+    /**
+     * Convenience method to check the notification's flags for
      * either {@link Notification#FLAG_ONGOING_EVENT} or
      * {@link Notification#FLAG_NO_CLEAR}.
      */
@@ -274,13 +278,15 @@
         return pkg;
     }
 
-    /** The id supplied to {@link android.app.NotificationManager#notify(int,Notification)}. */
+    /** The id supplied to {@link android.app.NotificationManager#notify(int, Notification)}. */
     public int getId() {
         return id;
     }
 
-    /** The tag supplied to {@link android.app.NotificationManager#notify(int,Notification)},
-     * or null if no tag was specified. */
+    /**
+     * The tag supplied to {@link android.app.NotificationManager#notify(int, Notification)},
+     * or null if no tag was specified.
+     */
     public String getTag() {
         return tag;
     }
@@ -307,8 +313,10 @@
         return initialPid;
     }
 
-    /** The {@link android.app.Notification} supplied to
-     * {@link android.app.NotificationManager#notify(int,Notification)}. */
+    /**
+     * The {@link android.app.Notification} supplied to
+     * {@link android.app.NotificationManager#notify(int, Notification)}.
+     */
     public Notification getNotification() {
         return notification;
     }
@@ -320,7 +328,8 @@
         return user;
     }
 
-    /** The time (in {@link System#currentTimeMillis} time) the notification was posted,
+    /**
+     * The time (in {@link System#currentTimeMillis} time) the notification was posted,
      * which may be different than {@link android.app.Notification#when}.
      */
     public long getPostTime() {
@@ -343,6 +352,7 @@
 
     /**
      * The ID passed to setGroup(), or the override, or null.
+     *
      * @hide
      */
     public String getGroup() {
@@ -398,10 +408,11 @@
 
     /**
      * Returns a LogMaker that contains all basic information of the notification.
+     *
      * @hide
      */
     public LogMaker getLogMaker() {
-        return new LogMaker(MetricsEvent.VIEW_UNKNOWN).setPackageName(getPackageName())
+        LogMaker logMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN).setPackageName(getPackageName())
                 .addTaggedData(MetricsEvent.NOTIFICATION_ID, getId())
                 .addTaggedData(MetricsEvent.NOTIFICATION_TAG, getTag())
                 .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag())
@@ -410,6 +421,21 @@
                         getNotification().isGroupSummary() ? 1 : 0)
                 .addTaggedData(MetricsProto.MetricsEvent.FIELD_NOTIFICATION_CATEGORY,
                         getNotification().category);
+        if (getNotification().extras != null) {
+            // Log the style used, if present.  We only log the hash here, as notification log
+            // events are frequent, while there are few styles (hence low chance of collisions).
+            String template = getNotification().extras.getString(Notification.EXTRA_TEMPLATE);
+            if (template != null && !template.isEmpty()) {
+                logMaker.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_STYLE,
+                        template.hashCode());
+            }
+            ArrayList<Person> people = getNotification().extras.getParcelableArrayList(
+                    Notification.EXTRA_PEOPLE_LIST);
+            if (people != null && !people.isEmpty()) {
+                logMaker.addTaggedData(MetricsEvent.FIELD_NOTIFICATION_PEOPLE, people.size());
+            }
+        }
+        return logMaker;
     }
 
     private String getGroupLogTag() {
@@ -433,6 +459,6 @@
         }
         String hash = Integer.toHexString(logTag.hashCode());
         return logTag.substring(0, MAX_LOG_TAG_LENGTH - hash.length() - 1) + "-"
-            + hash;
+                + hash;
     }
 }
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index cb7d41b..bfab580 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1820,7 +1820,7 @@
             if (modified != to.modified) {
                 d.addLine(item, "modified", modified, to.modified);
             }
-            if (pkg != to.pkg) {
+            if (!Objects.equals(pkg, to.pkg)) {
                 d.addLine(item, "pkg", pkg, to.pkg);
             }
         }
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index d645e3f..60dbf84 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -105,7 +105,7 @@
 
     static final String TAG = "WallpaperService";
     static final boolean DEBUG = false;
-    
+
     private static final int DO_ATTACH = 10;
     private static final int DO_DETACH = 20;
     private static final int DO_SET_DESIRED_SIZE = 30;
@@ -126,7 +126,7 @@
 
     private final ArrayList<Engine> mActiveEngines
             = new ArrayList<Engine>();
-    
+
     static final class WallpaperCommand {
         String action;
         int x;
@@ -145,7 +145,7 @@
      */
     public class Engine {
         IWallpaperEngineWrapper mIWallpaperEngine;
-        
+
         // Copies from mIWallpaperEngine.
         HandlerCaller mCaller;
         IWallpaperConnection mConnection;
@@ -155,7 +155,7 @@
         boolean mVisible;
         boolean mReportedVisible;
         boolean mDestroyed;
-        
+
         // Current window state.
         boolean mCreated;
         boolean mSurfaceCreated;
@@ -258,7 +258,7 @@
                 }
                 super.setFixedSize(width, height);
             }
-            
+
             public void setKeepScreenOn(boolean screenOn) {
                 throw new UnsupportedOperationException(
                         "Wallpapers do not support keep screen on");
@@ -403,14 +403,14 @@
            mClockFunction = clockFunction;
            mHandler = handler;
         }
-        
+
         /**
          * Provides access to the surface in which this wallpaper is drawn.
          */
         public SurfaceHolder getSurfaceHolder() {
             return mSurfaceHolder;
         }
-        
+
         /**
          * Convenience for {@link WallpaperManager#getDesiredMinimumWidth()
          * WallpaperManager.getDesiredMinimumWidth()}, returning the width
@@ -419,7 +419,7 @@
         public int getDesiredMinimumWidth() {
             return mIWallpaperEngine.mReqWidth;
         }
-        
+
         /**
          * Convenience for {@link WallpaperManager#getDesiredMinimumHeight()
          * WallpaperManager.getDesiredMinimumHeight()}, returning the height
@@ -437,7 +437,7 @@
         public boolean isVisible() {
             return mReportedVisible;
         }
-        
+
         /**
          * Returns true if this engine is running in preview mode -- that is,
          * it is being shown to the user before they select it as the actual
@@ -456,7 +456,7 @@
         public boolean isInAmbientMode() {
             return mIsInAmbientMode;
         }
-        
+
         /**
          * Control whether this wallpaper will receive raw touch events
          * from the window manager as the user interacts with the window
@@ -557,7 +557,7 @@
          * {@link WallpaperManager#sendWallpaperCommand}.
          * The default implementation does nothing, and always returns null
          * as the result.
-         * 
+         *
          * @param action The name of the command to perform.  This tells you
          * what to do and how to interpret the rest of the arguments.
          * @param x Generic integer parameter.
@@ -794,7 +794,7 @@
                     }
 
                     mLayout.format = mFormat;
-                    
+
                     mCurWindowFlags = mWindowFlags;
                     mLayout.flags = mWindowFlags
                             | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
@@ -1020,7 +1020,7 @@
                         mIsCreating = false;
                         mSurfaceCreated = true;
                         if (redrawNeeded) {
-                            mSession.finishDrawing(mWindow);
+                            mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
                         }
                         mIWallpaperEngine.reportShown();
                     }
@@ -1045,7 +1045,7 @@
             mSurfaceHolder.setSizeFromLayout();
             mInitializing = true;
             mSession = WindowManagerGlobal.getWindowSession();
-            
+
             mWindow.setSession(mSession);
 
             mLayout.packageName = getPackageName();
@@ -1149,7 +1149,7 @@
                 }
             }
         }
-        
+
         void doOffsetsChanged(boolean always) {
             if (mDestroyed) {
                 return;
@@ -1187,7 +1187,7 @@
                     mOffsetsChanged = true;
                 }
             }
-            
+
             if (sync) {
                 try {
                     if (DEBUG) Log.v(TAG, "Reporting offsets change complete");
@@ -1196,7 +1196,7 @@
                 }
             }
         }
-        
+
         void doCommand(WallpaperCommand cmd) {
             Bundle result;
             if (!mDestroyed) {
@@ -1213,7 +1213,7 @@
                 }
             }
         }
-        
+
         void reportSurfaceDestroyed() {
             if (mSurfaceCreated) {
                 mSurfaceCreated = false;
@@ -1229,12 +1229,12 @@
                 onSurfaceDestroyed(mSurfaceHolder);
             }
         }
-        
+
         void detach() {
             if (mDestroyed) {
                 return;
             }
-            
+
             mDestroyed = true;
 
             if (mIWallpaperEngine.mDisplayManager != null) {
@@ -1246,9 +1246,9 @@
                 if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
                 onVisibilityChanged(false);
             }
-            
+
             reportSurfaceDestroyed();
-            
+
             if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
             onDestroy();
 
@@ -1256,18 +1256,18 @@
                 try {
                     if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
                             + mSurfaceHolder.getSurface() + " of: " + this);
-                    
+
                     if (mInputEventReceiver != null) {
                         mInputEventReceiver.dispose();
                         mInputEventReceiver = null;
                     }
-                    
+
                     mSession.remove(mWindow);
                 } catch (RemoteException e) {
                 }
                 mSurfaceHolder.mSurface.release();
                 mCreated = false;
-                
+
                 // Dispose the input channel after removing the window so the Window Manager
                 // doesn't interpret the input channel being closed as an abnormal termination.
                 if (mInputChannel != null) {
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index bf0ef94..2c2c295 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1122,6 +1122,9 @@
             if (limit > lineEnd) {
                 limit = lineEnd;
             }
+            if (limit == start) {
+                continue;
+            }
             level[limit - lineStart - 1] =
                     (byte) ((runs[i + 1] >>> RUN_LEVEL_SHIFT) & RUN_LEVEL_MASK);
         }
@@ -1220,8 +1223,8 @@
     }
 
     /**
-     * Computes in linear time the results of calling
-     * #getHorizontal for all offsets on a line.
+     * Computes in linear time the results of calling #getHorizontal for all offsets on a line.
+     *
      * @param line The line giving the offsets we compute information for
      * @param clamped Whether to clamp the results to the width of the layout
      * @param primary Whether the results should be the primary or the secondary horizontal
@@ -1257,7 +1260,7 @@
         TextLine.recycle(tl);
 
         if (clamped) {
-            for (int offset = 0; offset <= wid.length; ++offset) {
+            for (int offset = 0; offset < wid.length; ++offset) {
                 if (wid[offset] > mWidth) {
                     wid[offset] = mWidth;
                 }
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 50e7ec3..df54209 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -67,6 +67,14 @@
  *  create <code>http://example.com</code> when the clickable URL link is
  *  created.
  *
+ *  <p class="note"><b>Note:</b> When using {@link #MAP_ADDRESSES} or {@link #ALL}
+ *  to match street addresses on API level {@link android.os.Build.VERSION_CODES#O_MR1}
+ *  and earlier, methods in this class may throw
+ *  {@link android.util.AndroidRuntimeException} or other exceptions if the
+ *  device's WebView implementation is currently being updated, because
+ *  {@link android.webkit.WebView#findAddress} is required to match street
+ *  addresses.
+ *
  * @see MatchFilter
  * @see TransformFilter
  */
@@ -95,10 +103,11 @@
 
     /**
      *  Bit field indicating that street addresses should be matched in methods that
-     *  take an options mask. Note that this uses the
-     *  {@link android.webkit.WebView#findAddress(String) findAddress()} method in
-     *  {@link android.webkit.WebView} for finding addresses, which has various
-     *  limitations and has been deprecated.
+     *  take an options mask. Note that this should be avoided, as it uses the
+     *  {@link android.webkit.WebView#findAddress(String)} method, which has various
+     *  limitations and has been deprecated: see the documentation for
+     *  {@link android.webkit.WebView#findAddress(String)} for more information.
+     *
      *  @deprecated use {@link android.view.textclassifier.TextClassifier#generateLinks(
      *  TextLinks.Request)} instead and avoid it even when targeting API levels where no alternative
      *  is available.
diff --git a/core/java/android/util/ByteStringUtils.java b/core/java/android/util/ByteStringUtils.java
deleted file mode 100644
index e4798f0..0000000
--- a/core/java/android/util/ByteStringUtils.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import libcore.util.HexEncoding;
-
-/**
- * A utility class for common byte array to hex string operations and vise versa.
- *
- * @hide
- */
-public final class ByteStringUtils {
-
-    private ByteStringUtils() {
-    /* hide constructor */
-    }
-
-    /**
-     * Returns the hex encoded string representation of bytes.
-     * @param bytes Byte array to encode.
-     * @return Hex encoded string representation of bytes.
-     */
-    public static String toHexString(byte[] bytes) {
-        if (bytes == null || bytes.length == 0 || bytes.length % 2 != 0) {
-            return null;
-        }
-
-        return HexEncoding.encodeToString(bytes, true /* upperCase */);
-    }
-
-    /**
-     * Returns the decoded byte array representation of str.
-     * @param str Hex encoded string to decode.
-     * @return Decoded byte array representation of str.
-     */
-    public static byte[] fromHexToByteArray(String str) {
-        if (str == null || str.length() == 0 || str.length() % 2 != 0) {
-            return null;
-        }
-
-        return HexEncoding.decode(str, false /* allowSingleChar */);
-    }
-}
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 1bcfc05..7c7223c 100755
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -157,6 +157,14 @@
     public static final int DENSITY_440 = 440;
 
     /**
+     * Intermediate density for screens that sit somewhere between
+     * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi).
+     * This is not a density that applications should target, instead relying
+     * on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
+     */
+    public static final int DENSITY_450 = 450;
+
+    /**
      * Standard quantized DPI for extra-extra-high-density screens.
      */
     public static final int DENSITY_XXHIGH = 480;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index edc8c8f..5a9ab38 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -55,6 +55,7 @@
         DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
         DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
         DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
+        DEFAULT_FLAGS.put("settings_skip_direction_mutable", "true");
     }
 
     /**
diff --git a/core/java/android/util/TimingsTraceLog.java b/core/java/android/util/TimingsTraceLog.java
index 3e6f09b..5370645 100644
--- a/core/java/android/util/TimingsTraceLog.java
+++ b/core/java/android/util/TimingsTraceLog.java
@@ -16,31 +16,58 @@
 
 package android.util;
 
+import android.annotation.NonNull;
 import android.os.Build;
 import android.os.SystemClock;
 import android.os.Trace;
 
-import java.util.ArrayDeque;
-import java.util.Deque;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * Helper class for reporting boot and shutdown timing metrics.
- * <p>Note: This class is not thread-safe. Use a separate copy for other threads</p>
+ *
+ * <p><b>NOTE:</b> This class is not thread-safe. Use a separate copy for other threads.
+ *
  * @hide
  */
 public class TimingsTraceLog {
     // Debug boot time for every step if it's non-user build.
     private static final boolean DEBUG_BOOT_TIME = !Build.IS_USER;
-    private final Deque<Pair<String, Long>> mStartTimes =
-            DEBUG_BOOT_TIME ? new ArrayDeque<>() : null;
+
+    // Maximum number of nested calls that are stored
+    private static final int MAX_NESTED_CALLS = 10;
+
+    private final String[] mStartNames;
+    private final long[] mStartTimes;
+
     private final String mTag;
-    private long mTraceTag;
-    private long mThreadId;
+    private final long mTraceTag;
+    private final long mThreadId;
+    private final int mMaxNestedCalls;
+
+    private int mCurrentLevel = -1;
 
     public TimingsTraceLog(String tag, long traceTag) {
+        this(tag, traceTag, DEBUG_BOOT_TIME ? MAX_NESTED_CALLS : -1);
+    }
+
+    @VisibleForTesting
+    public TimingsTraceLog(String tag, long traceTag, int maxNestedCalls) {
         mTag = tag;
         mTraceTag = traceTag;
         mThreadId = Thread.currentThread().getId();
+        mMaxNestedCalls = maxNestedCalls;
+        if (maxNestedCalls > 0) {
+            mStartNames = new String[maxNestedCalls];
+            mStartTimes = new long[maxNestedCalls];
+        } else {
+            mStartNames = null;
+            mStartTimes = null;
+        }
     }
 
     /**
@@ -50,27 +77,41 @@
     public void traceBegin(String name) {
         assertSameThread();
         Trace.traceBegin(mTraceTag, name);
-        if (DEBUG_BOOT_TIME) {
-            mStartTimes.push(Pair.create(name, SystemClock.elapsedRealtime()));
+
+        if (!DEBUG_BOOT_TIME) return;
+
+        if (mCurrentLevel + 1 >= mMaxNestedCalls) {
+            Slog.w(mTag, "not tracing duration of '" + name + "' because already reached "
+                    + mMaxNestedCalls + " levels");
+            return;
         }
+
+        mCurrentLevel++;
+        mStartNames[mCurrentLevel] = name;
+        mStartTimes[mCurrentLevel] = SystemClock.elapsedRealtime();
     }
 
     /**
      * End tracing previously {@link #traceBegin(String) started} section.
-     * Also {@link #logDuration logs} the duration.
+     *
+     * <p>Also {@link #logDuration logs} the duration.
      */
     public void traceEnd() {
         assertSameThread();
         Trace.traceEnd(mTraceTag);
-        if (!DEBUG_BOOT_TIME) {
-            return;
-        }
-        if (mStartTimes.peek() == null) {
+
+        if (!DEBUG_BOOT_TIME) return;
+
+        if (mCurrentLevel < 0) {
             Slog.w(mTag, "traceEnd called more times than traceBegin");
             return;
         }
-        Pair<String, Long> event = mStartTimes.pop();
-        logDuration(event.first, (SystemClock.elapsedRealtime() - event.second));
+
+        final String name = mStartNames[mCurrentLevel];
+        final long duration = SystemClock.elapsedRealtime() - mStartTimes[mCurrentLevel];
+        mCurrentLevel--;
+
+        logDuration(name, duration);
     }
 
     private void assertSameThread() {
@@ -83,9 +124,27 @@
     }
 
     /**
-     * Log the duration so it can be parsed by external tools for performance reporting
+     * Logs a duration so it can be parsed by external tools for performance reporting.
      */
     public void logDuration(String name, long timeMs) {
         Slog.d(mTag, name + " took to complete: " + timeMs + "ms");
     }
+
+    /**
+     * Gets the names of the traces that {@link #traceBegin(String) have begun} but
+     * {@link #traceEnd() have not finished} yet.
+     *
+     * <p><b>NOTE:</b> this method is expensive and it should not be used in "production" - it
+     * should only be used for debugging purposes during development (and/or guarded by
+     * static {@code DEBUG} constants that are {@code false}).
+     */
+    @NonNull
+    public final List<String> getUnfinishedTracesForDebug() {
+        if (mStartTimes == null || mCurrentLevel < 0) return Collections.emptyList();
+        final ArrayList<String> list = new ArrayList<>(mCurrentLevel + 1);
+        for (int i = 0; i <= mCurrentLevel; i++) {
+            list.add(mStartNames[i]);
+        }
+        return list;
+    }
 }
diff --git a/core/java/android/util/proto/ProtoInputStream.java b/core/java/android/util/proto/ProtoInputStream.java
index c290dff..24e7d2b 100644
--- a/core/java/android/util/proto/ProtoInputStream.java
+++ b/core/java/android/util/proto/ProtoInputStream.java
@@ -253,12 +253,14 @@
     }
 
     /**
-     * Attempt to guess the next field. If there is a match, the field data will be ready to read.
-     * If there is no match, nextField will need to be called to get the field number
+     * Reads the tag of the next field from the stream. If previous field value was not read, its
+     * data will be skipped over. If {@code fieldId} matches the next field ID, the field data will
+     * be ready to read. If it does not match, {@link #nextField()} or {@link #nextField(long)} will
+     * need to be called again before the field data can be read.
      *
      * @return true if fieldId matches the next field, false if not
      */
-    public boolean isNextField(long fieldId) throws IOException {
+    public boolean nextField(long fieldId) throws IOException {
         if (nextField() == (int) fieldId) {
             return true;
         }
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 4b92968..203b087 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -38,7 +38,6 @@
 import android.text.style.ClickableSpan;
 import android.util.LongSparseArray;
 import android.util.Slog;
-import android.view.View.AttachInfo;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeIdManager;
@@ -903,38 +902,6 @@
                 }
             }
         }
-
-        if (spec != null) {
-            AttachInfo attachInfo = mViewRootImpl.mAttachInfo;
-            if (attachInfo.mDisplay == null) {
-                return;
-            }
-
-            final float scale = attachInfo.mApplicationScale * spec.scale;
-
-            Rect visibleWinFrame = mTempRect1;
-            visibleWinFrame.left = (int) (attachInfo.mWindowLeft * scale + spec.offsetX);
-            visibleWinFrame.top = (int) (attachInfo.mWindowTop * scale + spec.offsetY);
-            visibleWinFrame.right = (int) (visibleWinFrame.left + mViewRootImpl.mWidth * scale);
-            visibleWinFrame.bottom = (int) (visibleWinFrame.top + mViewRootImpl.mHeight * scale);
-
-            attachInfo.mDisplay.getRealSize(mTempPoint);
-            final int displayWidth = mTempPoint.x;
-            final int displayHeight = mTempPoint.y;
-
-            Rect visibleDisplayFrame = mTempRect2;
-            visibleDisplayFrame.set(0, 0, displayWidth, displayHeight);
-
-            if (!visibleWinFrame.intersect(visibleDisplayFrame)) {
-                // If there's no intersection with display, set visibleWinFrame empty.
-                visibleDisplayFrame.setEmpty();
-            }
-
-            if (!visibleWinFrame.intersects(boundsInScreen.left, boundsInScreen.top,
-                    boundsInScreen.right, boundsInScreen.bottom)) {
-                info.setVisibleToUser(false);
-            }
-        }
     }
 
     private boolean shouldApplyAppScaleAndMagnificationSpec(float appScale,
@@ -948,8 +915,10 @@
         try {
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
             adjustBoundsInScreenIfNeeded(infos);
-            applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
+            // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
+            // then impact the visibility result, we need to adjust visibility before apply scale.
             adjustIsVisibleToUserIfNeeded(infos, interactiveRegion);
+            applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
             callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
             if (infos != null) {
                 infos.clear();
@@ -967,8 +936,10 @@
         try {
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
             adjustBoundsInScreenIfNeeded(info);
-            applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
+            // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
+            // then impact the visibility result, we need to adjust visibility before apply scale.
             adjustIsVisibleToUserIfNeeded(info, interactiveRegion);
+            applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
             callback.setFindAccessibilityNodeInfoResult(info, interactionId);
         } catch (RemoteException re) {
                 /* ignore - the other side will time out */
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index c64386e..e95b5ca 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import static android.view.DisplayEventReceiver.CONFIG_CHANGED_EVENT_SUPPRESS;
 import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP;
 import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER;
 
@@ -910,7 +911,7 @@
         private int mFrame;
 
         public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
-            super(looper, vsyncSource);
+            super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS);
         }
 
         // TODO(b/116025192): physicalDisplayId is ignored because SF only emits VSYNC events for
diff --git a/core/java/android/view/CompositionSamplingListener.java b/core/java/android/view/CompositionSamplingListener.java
index e4309a6..368445c 100644
--- a/core/java/android/view/CompositionSamplingListener.java
+++ b/core/java/android/view/CompositionSamplingListener.java
@@ -17,7 +17,6 @@
 package android.view;
 
 import android.graphics.Rect;
-import android.os.IBinder;
 
 import com.android.internal.util.Preconditions;
 
@@ -58,11 +57,12 @@
      * Registers a sampling listener.
      */
     public static void register(CompositionSamplingListener listener,
-            int displayId, IBinder stopLayer, Rect samplingArea) {
+            int displayId, SurfaceControl stopLayer, Rect samplingArea) {
         Preconditions.checkArgument(displayId == Display.DEFAULT_DISPLAY,
                 "default display only for now");
-        nativeRegister(listener.mNativeListener, stopLayer, samplingArea.left, samplingArea.top,
-                samplingArea.right, samplingArea.bottom);
+        long nativeStopLayerObject = stopLayer != null ? stopLayer.mNativeObject : 0;
+        nativeRegister(listener.mNativeListener, nativeStopLayerObject, samplingArea.left,
+                samplingArea.top, samplingArea.right, samplingArea.bottom);
     }
 
     /**
@@ -84,7 +84,7 @@
 
     private static native long nativeCreate(CompositionSamplingListener thiz);
     private static native void nativeDestroy(long ptr);
-    private static native void nativeRegister(long ptr, IBinder stopLayer,
+    private static native void nativeRegister(long ptr, long stopLayerObject,
             int samplingAreaLeft, int top, int right, int bottom);
     private static native void nativeUnregister(long ptr);
 }
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 715181f..797c128 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -319,18 +319,23 @@
             sortedBounds[i] = ZERO_RECT;
         }
         if (safeInsets != null && boundingRects != null) {
+            // There is at most one non-functional area per short edge of the device, but none
+            // on the long edges, so either a) safeInsets.top and safeInsets.bottom is 0, or
+            // b) safeInsets.left and safeInset.right is 0.
+            final boolean topBottomInset = safeInsets.top > 0 || safeInsets.bottom > 0;
             for (Rect bound : boundingRects) {
-                // There is at most one non-functional area per short edge of the device, but none
-                // on the long edges, so either safeInsets.right or safeInsets.bottom must be 0.
-                // TODO(b/117199965): Refine the logic to handle edge cases.
-                if (bound.left == 0) {
-                    sortedBounds[BOUNDS_POSITION_LEFT] = bound;
-                } else if (bound.top == 0) {
-                    sortedBounds[BOUNDS_POSITION_TOP] = bound;
-                } else if (safeInsets.right > 0) {
-                    sortedBounds[BOUNDS_POSITION_RIGHT] = bound;
-                } else if (safeInsets.bottom > 0) {
-                    sortedBounds[BOUNDS_POSITION_BOTTOM] = bound;
+                if (topBottomInset) {
+                    if (bound.top == 0) {
+                        sortedBounds[BOUNDS_POSITION_TOP] = bound;
+                    } else {
+                        sortedBounds[BOUNDS_POSITION_BOTTOM] = bound;
+                    }
+                } else {
+                    if (bound.left == 0) {
+                        sortedBounds[BOUNDS_POSITION_LEFT] = bound;
+                    } else {
+                        sortedBounds[BOUNDS_POSITION_RIGHT] = bound;
+                    }
                 }
             }
         }
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index 60daddd..91acc46 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -53,6 +53,20 @@
      */
     public static final int VSYNC_SOURCE_SURFACE_FLINGER = 1;
 
+    /**
+     * Specifies to suppress config changed events from being generated from Surface Flinger.
+     * <p>
+     * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h
+     */
+    public static final int CONFIG_CHANGED_EVENT_SUPPRESS = 0;
+
+    /**
+     * Specifies to generate config changed events from Surface Flinger.
+     * <p>
+     * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h
+     */
+    public static final int CONFIG_CHANGED_EVENT_DISPATCH = 1;
+
     private static final String TAG = "DisplayEventReceiver";
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -65,7 +79,7 @@
     private MessageQueue mMessageQueue;
 
     private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver,
-            MessageQueue messageQueue, int vsyncSource);
+            MessageQueue messageQueue, int vsyncSource, int configChanged);
     private static native void nativeDispose(long receiverPtr);
     @FastNative
     private static native void nativeScheduleVsync(long receiverPtr);
@@ -77,7 +91,7 @@
      */
     @UnsupportedAppUsage
     public DisplayEventReceiver(Looper looper) {
-        this(looper, VSYNC_SOURCE_APP);
+        this(looper, VSYNC_SOURCE_APP, CONFIG_CHANGED_EVENT_SUPPRESS);
     }
 
     /**
@@ -85,15 +99,17 @@
      *
      * @param looper The looper to use when invoking callbacks.
      * @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values.
+     * @param configChanged Whether to dispatch config changed events. Must be one of the
+     * CONFIG_CHANGED_EVENT_* values.
      */
-    public DisplayEventReceiver(Looper looper, int vsyncSource) {
+    public DisplayEventReceiver(Looper looper, int vsyncSource, int configChanged) {
         if (looper == null) {
             throw new IllegalArgumentException("looper must not be null");
         }
 
         mMessageQueue = looper.getQueue();
         mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
-                vsyncSource);
+                vsyncSource, configChanged);
 
         mCloseGuard.open("dispose");
     }
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index caab00c..f73f28a 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -2,15 +2,15 @@
 **
 ** Copyright 2006, The Android Open Source Project
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this 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, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
@@ -31,6 +31,7 @@
 import android.view.InsetsState;
 import android.view.Surface;
 import android.view.SurfaceControl;
+import android.view.Transaction;
 
 import java.util.List;
 
@@ -57,7 +58,7 @@
      * position should be ignored) and surface of the window.  The surface
      * will be invalid if the window is currently hidden, else you can use it
      * to draw the window's contents.
-     * 
+     *
      * @param window The window being modified.
      * @param seq Ordering sequence number.
      * @param attrs If non-null, new attributes to apply to the window.
@@ -147,8 +148,15 @@
      */
     void getDisplayFrame(IWindow window, out Rect outDisplayFrame);
 
+    /**
+     * Called when the client has finished drawing the surface, if needed.
+     *
+     * @param postDrawTransaction transaction filled by the client that can be
+     * used to synchronize any post draw transactions with the server. Transaction
+     * is null if there is no sync required.
+     */
     @UnsupportedAppUsage
-    void finishDrawing(IWindow window);
+    void finishDrawing(IWindow window, in Transaction postDrawTransaction);
 
     @UnsupportedAppUsage
     void setInTouchMode(boolean showFocus);
@@ -300,5 +308,11 @@
     /**
      * Called when the system gesture exclusion has changed.
      */
-    void reportSystemGestureExclusionChanged(IWindow window, in List<Rect> exclusionRects);
+    oneway void reportSystemGestureExclusionChanged(IWindow window, in List<Rect> exclusionRects);
+
+    /**
+    * Request the server to call setInputWindowInfo on a given Surface, and return
+    * an input channel where the client can receive input.
+    */
+    void blessInputSurface(int displayId, in SurfaceControl surface, out InputChannel outInputChannel);
 }
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java
index ecb727c..831e9ee 100644
--- a/core/java/android/view/InputChannel.java
+++ b/core/java/android/view/InputChannel.java
@@ -55,6 +55,7 @@
     private static native InputChannel[] nativeOpenInputChannelPair(String name);
 
     private native void nativeDispose(boolean finalized);
+    private native void nativeRelease();
     private native void nativeTransferTo(InputChannel other);
     private native void nativeReadFromParcel(Parcel parcel);
     private native void nativeWriteToParcel(Parcel parcel);
@@ -120,6 +121,14 @@
     }
 
     /**
+     * Release the Java objects hold over the native InputChannel. If other references
+     * still exist in native-land, then the channel may continue to exist.
+     */
+    public void release() {
+        nativeRelease();
+    }
+
+    /**
      * 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
      * as an out parameter in a binder call.
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 16a6412..10a9aaa 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -109,10 +109,10 @@
      * bounds of a parent window. That is the window should receive touch events outside its
      * window but be limited to its stack bounds, such as in the case of split screen.
      */
-    public WeakReference<IBinder> touchableRegionCropHandle = new WeakReference<>(null);
+    public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null);
 
     /**
-     * Replace {@link touchableRegion} with the bounds of {@link touchableRegionCropHandle}. If
+     * Replace {@link touchableRegion} with the bounds of {@link touchableRegionSurfaceControl}. If
      * the handle is {@code null}, the bounds of the surface associated with this window is used
      * as the touchable region.
      */
@@ -164,8 +164,6 @@
      * Crop the window touchable region to the bounds of the surface provided.
      */
     public void setTouchableRegionCrop(@Nullable SurfaceControl bounds) {
-        if (bounds != null) {
-            touchableRegionCropHandle = new WeakReference<>(bounds.getHandle());
-        }
+        touchableRegionSurfaceControl = new WeakReference<>(bounds);
     }
 }
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 87dd5b4..60db6a5 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1934,12 +1934,13 @@
     public static final boolean isWakeKey(int keyCode) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_BACK:
+            case KeyEvent.KEYCODE_CAMERA:
             case KeyEvent.KEYCODE_MENU:
-            case KeyEvent.KEYCODE_WAKEUP:
             case KeyEvent.KEYCODE_PAIRING:
             case KeyEvent.KEYCODE_STEM_1:
             case KeyEvent.KEYCODE_STEM_2:
             case KeyEvent.KEYCODE_STEM_3:
+            case KeyEvent.KEYCODE_WAKEUP:
                 return true;
         }
         return false;
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index cb64ab1..17f07b5 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -21,6 +21,7 @@
 import android.annotation.UnsupportedAppUsage;
 import android.content.res.CompatibilityInfo.Translator;
 import android.graphics.Canvas;
+import android.graphics.ColorSpace;
 import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
 import android.graphics.RecordingCanvas;
@@ -80,7 +81,8 @@
     private static native long nativeGetNextFrameNumber(long nativeObject);
     private static native int nativeSetScalingMode(long nativeObject, int scalingMode);
     private static native int nativeForceScopedDisconnect(long nativeObject);
-    private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer);
+    private static native int nativeAttachAndQueueBufferWithColorSpace(long nativeObject,
+            GraphicBuffer buffer, int colorSpaceId);
 
     private static native int nativeSetSharedBufferModeEnabled(long nativeObject, boolean enabled);
     private static native int nativeSetAutoRefreshEnabled(long nativeObject, boolean enabled);
@@ -699,18 +701,35 @@
     }
 
     /**
+     * Transfer ownership of buffer with a color space and present it on the Surface.
+     * The supported color spaces are SRGB and Display P3, other color spaces will be
+     * treated as SRGB.
+     * @hide
+     */
+    public void attachAndQueueBufferWithColorSpace(GraphicBuffer buffer, ColorSpace colorSpace) {
+        synchronized (mLock) {
+            checkNotReleasedLocked();
+            if (colorSpace == null) {
+                colorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
+            }
+            int err = nativeAttachAndQueueBufferWithColorSpace(mNativeObject, buffer,
+                    colorSpace.getId());
+            if (err != 0) {
+                throw new RuntimeException(
+                        "Failed to attach and queue buffer to Surface (bad object?), "
+                        + "native error: " + err);
+            }
+        }
+    }
+
+    /**
+     * Deprecated, use attachAndQueueBufferWithColorSpace instead.
      * Transfer ownership of buffer and present it on the Surface.
+     * The color space of the buffer is treated as SRGB.
      * @hide
      */
     public void attachAndQueueBuffer(GraphicBuffer buffer) {
-        synchronized (mLock) {
-            checkNotReleasedLocked();
-            int err = nativeAttachAndQueueBuffer(mNativeObject, buffer);
-            if (err != 0) {
-                throw new RuntimeException(
-                        "Failed to attach and queue buffer to Surface (bad object?)");
-            }
-        }
+        attachAndQueueBufferWithColorSpace(buffer, ColorSpace.get(ColorSpace.Named.SRGB));
     }
 
     /**
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 63e1485..522ad64 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -84,14 +84,13 @@
     private static native long nativeCopyFromSurfaceControl(long nativeObject);
     private static native void nativeWriteToParcel(long nativeObject, Parcel out);
     private static native void nativeRelease(long nativeObject);
-    private static native void nativeDestroy(long nativeObject);
     private static native void nativeDisconnect(long nativeObject);
 
     private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
             Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
             boolean captureSecureLayers);
     private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken,
-            IBinder layerHandleToken, Rect sourceCrop, float frameScale, IBinder[] excludeLayers);
+            long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects);
 
     private static native long nativeCreateTransaction();
     private static native long nativeGetNativeTransactionFinalizer();
@@ -103,7 +102,7 @@
 
     private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder);
     private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject,
-            IBinder relativeTo, int zorder);
+            long relativeToObject, int zorder);
     private static native void nativeSetPosition(long transactionObj, long nativeObject,
             float x, float y);
     private static native void nativeSetGeometryAppliesWithResize(long transactionObj,
@@ -173,18 +172,17 @@
     private static native void nativeSetDisplayPowerMode(
             IBinder displayToken, int mode);
     private static native void nativeDeferTransactionUntil(long transactionObj, long nativeObject,
-            IBinder handle, long frame);
+            long barrierObject, long frame);
     private static native void nativeDeferTransactionUntilSurface(long transactionObj,
             long nativeObject,
             long surfaceObject, long frame);
     private static native void nativeReparentChildren(long transactionObj, long nativeObject,
-            IBinder handle);
+            long newParentObject);
     private static native void nativeReparent(long transactionObj, long nativeObject,
             long newParentNativeObject);
     private static native void nativeSeverChildren(long transactionObj, long nativeObject);
     private static native void nativeSetOverrideScalingMode(long transactionObj, long nativeObject,
             int scalingMode);
-    private static native IBinder nativeGetHandle(long nativeObject);
     private static native boolean nativeGetTransformToDisplayInverse(long nativeObject);
 
     private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
@@ -200,6 +198,8 @@
     private static native boolean nativeGetDisplayBrightnessSupport(IBinder displayToken);
     private static native boolean nativeSetDisplayBrightness(IBinder displayToken,
             float brightness);
+    private static native long nativeReadTransactionFromParcel(Parcel in);
+    private static native void nativeWriteTransactionToParcel(long nativeObject, Parcel out);
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
     private String mName;
@@ -930,19 +930,6 @@
     }
 
     /**
-     * Release the local resources like {@link #release} but also
-     * remove the Surface from the screen.
-     * @hide
-     */
-    public void remove() {
-        if (mNativeObject != 0) {
-            nativeDestroy(mNativeObject);
-            mNativeObject = 0;
-        }
-        mCloseGuard.close();
-    }
-
-    /**
      * Disconnect any client still connected to the surface.
      * @hide
      */
@@ -1021,9 +1008,9 @@
     /**
      * @hide
      */
-    public void deferTransactionUntil(IBinder handle, long frame) {
+    public void deferTransactionUntil(SurfaceControl barrier, long frame) {
         synchronized(SurfaceControl.class) {
-            sGlobalTransaction.deferTransactionUntil(this, handle, frame);
+            sGlobalTransaction.deferTransactionUntil(this, barrier, frame);
         }
     }
 
@@ -1039,9 +1026,9 @@
     /**
      * @hide
      */
-    public void reparentChildren(IBinder newParentHandle) {
+    public void reparentChildren(SurfaceControl newParent) {
         synchronized(SurfaceControl.class) {
-            sGlobalTransaction.reparentChildren(this, newParentHandle);
+            sGlobalTransaction.reparentChildren(this, newParent);
         }
     }
 
@@ -1076,13 +1063,6 @@
     /**
      * @hide
      */
-    public IBinder getHandle() {
-        return nativeGetHandle(mNativeObject);
-    }
-
-    /**
-     * @hide
-     */
     public static void setAnimationTransaction() {
         synchronized (SurfaceControl.class) {
             sGlobalTransaction.setAnimationTransaction();
@@ -1866,7 +1846,8 @@
         final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
                 height, useIdentityTransform, rotation);
         try {
-            consumer.attachAndQueueBuffer(buffer.getGraphicBuffer());
+            consumer.attachAndQueueBufferWithColorSpace(buffer.getGraphicBuffer(),
+                    buffer.getColorSpace());
         } catch (RuntimeException e) {
             Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
         }
@@ -1987,7 +1968,7 @@
     /**
      * Captures a layer and its children and returns a {@link GraphicBuffer} with the content.
      *
-     * @param layerHandleToken The root layer to capture.
+     * @param layer            The root layer to capture.
      * @param sourceCrop       The portion of the root surface to capture; caller may pass in 'new
      *                         Rect()' or null if no cropping is desired.
      * @param frameScale       The desired scale of the returned buffer; the raw
@@ -1996,20 +1977,25 @@
      * @return Returns a GraphicBuffer that contains the layer capture.
      * @hide
      */
-    public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
+    public static ScreenshotGraphicBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
             float frameScale) {
         final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
-        return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, null);
+        return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, null);
     }
 
     /**
      * Like {@link captureLayers} but with an array of layer handles to exclude.
      * @hide
      */
-    public static ScreenshotGraphicBuffer captureLayersExcluding(IBinder layerHandleToken,
-            Rect sourceCrop, float frameScale, IBinder[] exclude) {
+    public static ScreenshotGraphicBuffer captureLayersExcluding(SurfaceControl layer,
+            Rect sourceCrop, float frameScale, SurfaceControl[] exclude) {
         final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
-        return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, exclude);
+        long[] nativeExcludeObjects = new long[exclude.length];
+        for (int i = 0; i < exclude.length; i++) {
+            nativeExcludeObjects[i] = exclude[i].mNativeObject;
+        }
+        return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale,
+                nativeExcludeObjects);
     }
 
     /**
@@ -2061,10 +2047,10 @@
         return nativeSetDisplayBrightness(displayToken, brightness);
     }
 
-    /**
+     /**
      * An atomic set of changes to a set of SurfaceControl.
      */
-    public static class Transaction implements Closeable {
+    public static class Transaction implements Closeable, Parcelable {
         /**
          * @hide
          */
@@ -2089,6 +2075,10 @@
                 = sRegistry.registerNativeAllocation(this, mNativeObject);
         }
 
+        private Transaction(Parcel in) {
+            readFromParcel(in);
+        }
+
         /**
          * Apply the transaction, clearing it's state, and making it usable
          * as a new transaction.
@@ -2222,8 +2212,7 @@
          */
         public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) {
             sc.checkNotReleased();
-            nativeSetRelativeLayer(mNativeObject, sc.mNativeObject,
-                    relativeTo.getHandle(), z);
+            nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, relativeTo.mNativeObject, z);
             return this;
         }
 
@@ -2410,13 +2399,14 @@
          * @hide
          */
         @UnsupportedAppUsage
-        public Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle,
+        public Transaction deferTransactionUntil(SurfaceControl sc, SurfaceControl barrier,
                 long frameNumber) {
             if (frameNumber < 0) {
                 return this;
             }
             sc.checkNotReleased();
-            nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, handle, frameNumber);
+            nativeDeferTransactionUntil(mNativeObject, sc.mNativeObject, barrier.mNativeObject,
+                    frameNumber);
             return this;
         }
 
@@ -2438,9 +2428,9 @@
         /**
          * @hide
          */
-        public Transaction reparentChildren(SurfaceControl sc, IBinder newParentHandle) {
+        public Transaction reparentChildren(SurfaceControl sc, SurfaceControl newParent) {
             sc.checkNotReleased();
-            nativeReparentChildren(mNativeObject, sc.mNativeObject, newParentHandle);
+            nativeReparentChildren(mNativeObject, sc.mNativeObject, newParent.mNativeObject);
             return this;
         }
 
@@ -2605,7 +2595,7 @@
             return this;
         }
 
-        /** flag the transaction as an animation 
+        /** flag the transaction as an animation
          * @hide
          */
         public Transaction setAnimationTransaction() {
@@ -2686,5 +2676,47 @@
             sc.release();
             return this;
         }
+
+        /**
+         * Writes the transaction to parcel, clearing the transaction as if it had been applied so
+         * it can be used to store future transactions. It's the responsibility of the parcel
+         * reader to apply the original transaction.
+         *
+         * @param dest parcel to write the transaction to
+         * @param flags
+         */
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
+            if (mNativeObject == 0) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+            }
+            nativeWriteTransactionToParcel(mNativeObject, dest);
+        }
+
+        private void readFromParcel(Parcel in) {
+            mNativeObject = 0;
+            if (in.readInt() != 0) {
+                mNativeObject = nativeReadTransactionFromParcel(in);
+                mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject);
+            }
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final @NonNull Creator<Transaction> CREATOR = new Creator<Transaction>() {
+                    @Override
+                    public Transaction createFromParcel(Parcel in) {
+                        return new Transaction(in);
+                    }
+                    @Override
+                    public Transaction[] newArray(int size) {
+                        return new Transaction[size];
+                    }
+                };
     }
 }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 3535447..9cc6b28 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -23,11 +23,9 @@
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.CompatibilityInfo.Translator;
-import android.content.res.Configuration;
 import android.graphics.BlendMode;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.HardwareRenderer;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
@@ -101,10 +99,10 @@
 public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {
     private static final String TAG = "SurfaceView";
     private static final boolean DEBUG = false;
+    private static final boolean DEBUG_POSITION = false;
 
     @UnsupportedAppUsage
-    final ArrayList<SurfaceHolder.Callback> mCallbacks
-            = new ArrayList<SurfaceHolder.Callback>();
+    final ArrayList<SurfaceHolder.Callback> mCallbacks = new ArrayList<>();
 
     final int[] mLocation = new int[2];
 
@@ -127,8 +125,8 @@
     // we need to preserve the old one until the new one has drawn.
     SurfaceControl mDeferredDestroySurfaceControl;
     SurfaceControl mBackgroundControl;
+    final Object mSurfaceControlLock = new Object();
     final Rect mTmpRect = new Rect();
-    final Configuration mConfiguration = new Configuration();
 
     Paint mRoundedViewportPaint;
 
@@ -138,25 +136,16 @@
     boolean mIsCreating = false;
     private volatile boolean mRtHandlingPositionUpdates = false;
 
-    private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener
-            = new ViewTreeObserver.OnScrollChangedListener() {
-                    @Override
-                    public void onScrollChanged() {
-                        updateSurface();
-                    }
-            };
+    private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener =
+            this::updateSurface;
 
     @UnsupportedAppUsage
-    private final ViewTreeObserver.OnPreDrawListener mDrawListener =
-            new ViewTreeObserver.OnPreDrawListener() {
-                @Override
-                public boolean onPreDraw() {
-                    // reposition ourselves where the surface is
-                    mHaveFrame = getWidth() > 0 && getHeight() > 0;
-                    updateSurface();
-                    return true;
-                }
-            };
+    private final ViewTreeObserver.OnPreDrawListener mDrawListener = () -> {
+        // reposition ourselves where the surface is
+        mHaveFrame = getWidth() > 0 && getHeight() > 0;
+        updateSurface();
+        return true;
+    };
 
     boolean mRequestedVisible = false;
     boolean mWindowVisibility = false;
@@ -174,6 +163,9 @@
     @UnsupportedAppUsage
     int mRequestedFormat = PixelFormat.RGB_565;
 
+    boolean mUseAlpha = false;
+    float mSurfaceAlpha = 1f;
+
     @UnsupportedAppUsage
     boolean mHaveFrame = false;
     boolean mSurfaceCreated = false;
@@ -191,7 +183,6 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     final Rect mSurfaceFrame = new Rect();
     int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
-    private Translator mTranslator;
 
     private boolean mGlobalListenersAdded;
     private boolean mAttachedToWindow;
@@ -201,29 +192,7 @@
     private int mPendingReportDraws;
 
     private SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction();
-
-    /**
-     * A callback which reflects an alpha value of this view onto the underlying surfaces.
-     *
-     * <p class="note"><strong>Note:</strong> This doesn't have to be defined as a member variable,
-     * but can be defined as an inline lambda when calling ViewRootImpl#registerRtFrameCallback().
-     * However when we do so, the callback is triggered only for a few times and stops working for
-     * some reason. It's suspected that there is a problem around garbage collection, and until
-     * the cause is fixed, we will keep this callback in a member variable.</p>
-    */
-    private HardwareRenderer.FrameDrawingCallback mSetSurfaceAlphaCallback = frame -> {
-        final ViewRootImpl viewRoot = getViewRootImpl();
-        if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
-            // In this case, the alpha value is reflected on the screen in #updateSurface() later.
-            return;
-        }
-
-        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-        t.setAlpha(mSurfaceControl, getAlpha());
-        t.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface, frame);
-        t.setEarlyWakeup();
-        t.apply();
-    };
+    private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
 
     public SurfaceView(Context context) {
         this(context, null);
@@ -312,15 +281,150 @@
         updateSurface();
     }
 
+    /**
+     * Make alpha value of this view reflect onto the surface. This can only be called from at most
+     * one SurfaceView within a view tree.
+     *
+     * <p class="note"><strong>Note:</strong> Alpha value of the view is ignored and the underlying
+     * surface is rendered opaque by default.</p>
+     *
+     * @hide
+     */
+    public void setUseAlpha() {
+        if (!mUseAlpha) {
+            mUseAlpha = true;
+            updateSurfaceAlpha();
+        }
+    }
+
     @Override
     public void setAlpha(float alpha) {
+        // Sets the opacity of the view to a value, where 0 means the view is completely transparent
+        // and 1 means the view is completely opaque.
+        //
+        // Note: Alpha value of this view is ignored by default. To enable alpha blending, you need
+        // to call setUseAlpha() as well.
+        // This view doesn't support translucent opacity if the view is located z-below, since the
+        // logic to punch a hole in the view hierarchy cannot handle such case. See also
+        // #clearSurfaceViewPort(Canvas)
+        if (DEBUG) {
+            Log.d(TAG, System.identityHashCode(this)
+                    + " setAlpha: mUseAlpha = " + mUseAlpha + " alpha=" + alpha);
+        }
         super.setAlpha(alpha);
-        final ViewRootImpl viewRoot = getViewRootImpl();
-        if (viewRoot == null) {
+        updateSurfaceAlpha();
+    }
+
+    private float getFixedAlpha() {
+        // Compute alpha value to be set on the underlying surface.
+        final float alpha = getAlpha();
+        return mUseAlpha && (mSubLayer > 0 || alpha == 0f) ? alpha : 1f;
+    }
+
+    private void updateSurfaceAlpha() {
+        if (!mUseAlpha) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurfaceAlpha: setUseAlpha() is not called, ignored.");
+            }
             return;
         }
-        viewRoot.registerRtFrameCallback(mSetSurfaceAlphaCallback);
-        invalidate();
+        final float viewAlpha = getAlpha();
+        if (mSubLayer < 0 && 0f < viewAlpha && viewAlpha < 1f) {
+            Log.w(TAG, System.identityHashCode(this)
+                    + " updateSurfaceAlpha:"
+                    + " translucent color is not supported for a surface placed z-below.");
+        }
+        if (!mHaveFrame) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurfaceAlpha: has no surface.");
+            }
+            return;
+        }
+        final ViewRootImpl viewRoot = getViewRootImpl();
+        if (viewRoot == null) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurfaceAlpha: ViewRootImpl not available.");
+            }
+            return;
+        }
+        if (mSurfaceControl == null) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + "updateSurfaceAlpha:"
+                        + " surface is not yet created, or already released.");
+            }
+            return;
+        }
+        final Surface parent = viewRoot.mSurface;
+        if (parent == null || !parent.isValid()) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurfaceAlpha: ViewRootImpl has no valid surface");
+            }
+            return;
+        }
+        final float alpha = getFixedAlpha();
+        if (alpha != mSurfaceAlpha) {
+            if (isHardwareAccelerated()) {
+                /*
+                 * Schedule a callback that reflects an alpha value onto the underlying surfaces.
+                 * This gets called on a RenderThread worker thread, so members accessed here must
+                 * be protected by a lock.
+                 */
+                viewRoot.registerRtFrameCallback(frame -> {
+                    try {
+                        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+                        synchronized (mSurfaceControlLock) {
+                            if (!parent.isValid()) {
+                                if (DEBUG) {
+                                    Log.d(TAG, System.identityHashCode(this)
+                                            + " updateSurfaceAlpha RT:"
+                                            + " ViewRootImpl has no valid surface");
+                                }
+                                return;
+                            }
+                            if (mSurfaceControl == null) {
+                                if (DEBUG) {
+                                    Log.d(TAG, System.identityHashCode(this)
+                                            + "updateSurfaceAlpha RT:"
+                                            + " mSurfaceControl has already released");
+                                }
+                                return;
+                            }
+                            if (DEBUG) {
+                                Log.d(TAG, System.identityHashCode(this)
+                                        + " updateSurfaceAlpha RT: set alpha=" + alpha);
+                            }
+                            t.setAlpha(mSurfaceControl, alpha);
+                            t.deferTransactionUntilSurface(mSurfaceControl, parent, frame);
+                        }
+                        // It's possible that mSurfaceControl is released in the UI thread before
+                        // the transaction completes. If that happens, an exception is thrown, which
+                        // must be caught immediately.
+                        t.apply();
+                    } catch (Exception e) {
+                        Log.e(TAG, System.identityHashCode(this)
+                                + "updateSurfaceAlpha RT: Exception during surface transaction", e);
+                    }
+                });
+                damageInParent();
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, System.identityHashCode(this)
+                            + " updateSurfaceAlpha: set alpha=" + alpha);
+                }
+                SurfaceControl.openTransaction();
+                try {
+                    mSurfaceControl.setAlpha(alpha);
+                } finally {
+                    SurfaceControl.closeTransaction();
+                }
+            }
+            mSurfaceAlpha = alpha;
+        }
     }
 
     private void performDrawFinished() {
@@ -373,11 +477,7 @@
         mRequestedVisible = false;
 
         updateSurface();
-        if (mSurfaceControl != null) {
-            mSurfaceControl.remove();
-        }
-        mSurfaceControl = null;
-
+        releaseSurfaces();
         mHaveFrame = false;
 
         super.onDetachedFromWindow();
@@ -546,15 +646,6 @@
         }
     }
 
-    private Rect getParentSurfaceInsets() {
-        final ViewRootImpl root = getViewRootImpl();
-        if (root == null) {
-            return null;
-        } else {
-            return root.mWindowAttributes.surfaceInsets;
-        }
-    }
-
     private void updateBackgroundVisibilityInTransaction(SurfaceControl viewRoot) {
         if (mBackgroundControl == null) {
             return;
@@ -568,29 +659,40 @@
     }
 
     private void releaseSurfaces() {
-        if (mSurfaceControl != null) {
-            mSurfaceControl.remove();
-            mSurfaceControl = null;
+        synchronized (mSurfaceControlLock) {
+            if (mSurfaceControl != null) {
+                mTmpTransaction.remove(mSurfaceControl);
+                mSurfaceControl = null;
+            }
+            if (mBackgroundControl != null) {
+                mTmpTransaction.remove(mBackgroundControl);
+                mBackgroundControl = null;
+            }
+            mTmpTransaction.apply();
         }
-        if (mBackgroundControl != null) {
-            mBackgroundControl.remove();
-            mBackgroundControl = null;
-        }
+        mSurfaceAlpha = 1f;
     }
 
     /** @hide */
     protected void updateSurface() {
         if (!mHaveFrame) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this) + " updateSurface: has no frame");
+            }
             return;
         }
         ViewRootImpl viewRoot = getViewRootImpl();
         if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
+            if (DEBUG) {
+                Log.d(TAG, System.identityHashCode(this)
+                        + " updateSurface: no valid surface");
+            }
             return;
         }
 
-        mTranslator = viewRoot.mTranslator;
-        if (mTranslator != null) {
-            mSurface.setCompatibilityTranslator(mTranslator);
+        final Translator translator = viewRoot.mTranslator;
+        if (translator != null) {
+            mSurface.setCompatibilityTranslator(translator);
         }
 
         int myWidth = mRequestedWidth;
@@ -598,20 +700,25 @@
         int myHeight = mRequestedHeight;
         if (myHeight <= 0) myHeight = getHeight();
 
+        final float alpha = getFixedAlpha();
         final boolean formatChanged = mFormat != mRequestedFormat;
         final boolean visibleChanged = mVisible != mRequestedVisible;
+        final boolean alphaChanged = mSurfaceAlpha != alpha;
         final boolean creating = (mSurfaceControl == null || formatChanged || visibleChanged)
                 && mRequestedVisible;
         final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
         final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
         boolean redrawNeeded = false;
 
-        if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) {
+        if (creating || formatChanged || sizeChanged || visibleChanged || (mUseAlpha
+                && alphaChanged) || windowVisibleChanged) {
             getLocationInWindow(mLocation);
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                     + "Changes: creating=" + creating
                     + " format=" + formatChanged + " size=" + sizeChanged
+                    + " visible=" + visibleChanged + " alpha=" + alphaChanged
+                    + " mUseAlpha=" + mUseAlpha
                     + " visible=" + visibleChanged
                     + " left=" + (mWindowSpaceLeft != mLocation[0])
                     + " top=" + (mWindowSpaceTop != mLocation[1]));
@@ -629,11 +736,11 @@
                 mScreenRect.top = mWindowSpaceTop;
                 mScreenRect.right = mWindowSpaceLeft + getWidth();
                 mScreenRect.bottom = mWindowSpaceTop + getHeight();
-                if (mTranslator != null) {
-                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
+                if (translator != null) {
+                    translator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
-                final Rect surfaceInsets = getParentSurfaceInsets();
+                final Rect surfaceInsets = viewRoot.mWindowAttributes.surfaceInsets;
                 mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
 
                 if (creating) {
@@ -682,13 +789,10 @@
                             mSurfaceControl.hide();
                         }
                         updateBackgroundVisibilityInTransaction(viewRoot.getSurfaceControl());
-
-                        // Alpha value change is handled in setAlpha() directly using a local
-                        // transaction. However it can happen that setAlpha() is called while
-                        // local transactions cannot be applied, so the value is stored in a View
-                        // but not yet reflected on the Surface.
-                        mSurfaceControl.setAlpha(getAlpha());
-                        mBackgroundControl.setAlpha(getAlpha());
+                        if (mUseAlpha) {
+                            mSurfaceControl.setAlpha(alpha);
+                            mSurfaceAlpha = alpha;
+                        }
 
                         // While creating the surface, we will set it's initial
                         // geometry. Outside of that though, we should generally
@@ -723,11 +827,11 @@
 
                     mSurfaceFrame.left = 0;
                     mSurfaceFrame.top = 0;
-                    if (mTranslator == null) {
+                    if (translator == null) {
                         mSurfaceFrame.right = mSurfaceWidth;
                         mSurfaceFrame.bottom = mSurfaceHeight;
                     } else {
-                        float appInvertedScale = mTranslator.applicationInvertedScale;
+                        float appInvertedScale = translator.applicationInvertedScale;
                         mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
                         mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
                     }
@@ -745,7 +849,7 @@
                 try {
                     redrawNeeded |= visible && !mDrawFinished;
 
-                    SurfaceHolder.Callback callbacks[] = null;
+                    SurfaceHolder.Callback[] callbacks = null;
 
                     final boolean surfaceChanged = creating;
                     if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
@@ -831,7 +935,6 @@
                     mIsCreating = false;
                     if (mSurfaceControl != null && !mSurfaceCreated) {
                         mSurface.release();
-
                         releaseSurfaces();
                     }
                 }
@@ -861,8 +964,8 @@
                 mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
                         mWindowSpaceLeft + mLocation[0], mWindowSpaceTop + mLocation[1]);
 
-                if (mTranslator != null) {
-                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
+                if (translator != null) {
+                    translator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
                 if (mSurfaceControl == null) {
@@ -871,10 +974,13 @@
 
                 if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
                     try {
-                        if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
-                                "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                                mScreenRect.left, mScreenRect.top,
-                                mScreenRect.right, mScreenRect.bottom));
+                        if (DEBUG_POSITION) {
+                            Log.d(TAG, String.format("%d updateSurfacePosition UI, "
+                                            + "position = [%d, %d, %d, %d]",
+                                    System.identityHashCode(this),
+                                    mScreenRect.left, mScreenRect.top,
+                                    mScreenRect.right, mScreenRect.bottom));
+                        }
                         setParentSpaceRectangle(mScreenRect, -1);
                     } catch (Exception ex) {
                         Log.e(TAG, "Exception configuring surface", ex);
@@ -891,13 +997,11 @@
         }
 
         if (mDeferredDestroySurfaceControl != null) {
-            mDeferredDestroySurfaceControl.remove();
+            mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
             mDeferredDestroySurfaceControl = null;
         }
 
-        runOnUiThread(() -> {
-            performDrawFinished();
-        });
+        runOnUiThread(this::performDrawFinished);
     }
 
     /**
@@ -927,7 +1031,6 @@
         if (mViewVisibility) {
             mRtTransaction.show(surface);
         }
-
     }
 
     private void setParentSpaceRectangle(Rect position, long frameNumber) {
@@ -968,10 +1071,10 @@
                 return;
             }
             try {
-                if (DEBUG) {
+                if (DEBUG_POSITION) {
                     Log.d(TAG, String.format(
                             "%d updateSurfacePosition RenderWorker, frameNr = %d, "
-                                    + "postion = [%d, %d, %d, %d]",
+                                    + "position = [%d, %d, %d, %d]",
                             System.identityHashCode(this), frameNumber,
                             left, top, right, bottom));
                 }
@@ -1007,7 +1110,7 @@
     };
 
     private SurfaceHolder.Callback[] getSurfaceCallbacks() {
-        SurfaceHolder.Callback callbacks[];
+        SurfaceHolder.Callback[] callbacks;
         synchronized (mCallbacks) {
             callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
             mCallbacks.toArray(callbacks);
@@ -1077,7 +1180,7 @@
             synchronized (mCallbacks) {
                 // This is a linear search, but in practice we'll
                 // have only a couple callbacks, so it doesn't matter.
-                if (mCallbacks.contains(callback) == false) {
+                if (!mCallbacks.contains(callback)) {
                     mCallbacks.add(callback);
                 }
             }
diff --git a/core/java/android/view/TEST_MAPPING b/core/java/android/view/TEST_MAPPING
index 87d428a..4ea4310 100644
--- a/core/java/android/view/TEST_MAPPING
+++ b/core/java/android/view/TEST_MAPPING
@@ -1,10 +1,12 @@
 {
   "presubmit": [
     {
-      "name": "CtsUiRenderingTestCases"
-    },
-    {
       "name": "CtsAccelerationTestCases"
     }
+  ],
+  "imports": [
+    {
+      "path": "cts/tests/tests/uirendering"
+    }
   ]
 }
\ No newline at end of file
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 3d3d5dc..a01e15e 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.HardwareRenderer;
@@ -35,6 +36,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 
 /**
  * Threaded renderer that proxies the rendering to a render thread. Most calls
@@ -286,9 +288,6 @@
     // applied as translation when updating the root render node.
     private int mInsetTop, mInsetLeft;
 
-    // Whether the surface has insets. Used to protect opacity.
-    private boolean mHasInsets;
-
     // Light properties specified by the theme.
     private final float mLightY;
     private final float mLightZ;
@@ -300,7 +299,8 @@
     private boolean mEnabled;
     private boolean mRequested = true;
 
-    private FrameDrawingCallback mNextRtFrameCallback;
+    @Nullable
+    private ArrayList<FrameDrawingCallback> mNextRtFrameCallbacks;
 
     ThreadedRenderer(Context context, boolean translucent, String name) {
         super();
@@ -441,8 +441,11 @@
      *
      * @param callback The callback to register.
      */
-    void registerRtFrameCallback(FrameDrawingCallback callback) {
-        mNextRtFrameCallback = callback;
+    void registerRtFrameCallback(@NonNull FrameDrawingCallback callback) {
+        if (mNextRtFrameCallbacks == null) {
+            mNextRtFrameCallbacks = new ArrayList<>();
+        }
+        mNextRtFrameCallbacks.add(callback);
     }
 
     /**
@@ -474,7 +477,6 @@
 
         if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
                 || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
-            mHasInsets = true;
             mInsetLeft = surfaceInsets.left;
             mInsetTop = surfaceInsets.top;
             mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
@@ -483,7 +485,6 @@
             // If the surface has insets, it can't be opaque.
             setOpaque(false);
         } else {
-            mHasInsets = false;
             mInsetLeft = 0;
             mInsetTop = 0;
             mSurfaceWidth = width;
@@ -583,10 +584,14 @@
         // Consume and set the frame callback after we dispatch draw to the view above, but before
         // onPostDraw below which may reset the callback for the next frame.  This ensures that
         // updates to the frame callback during scroll handling will also apply in this frame.
-        final FrameDrawingCallback callback = mNextRtFrameCallback;
-        mNextRtFrameCallback = null;
-        if (callback != null) {
-            setFrameCallback(callback);
+        if (mNextRtFrameCallbacks != null) {
+            final ArrayList<FrameDrawingCallback> frameCallbacks = mNextRtFrameCallbacks;
+            mNextRtFrameCallbacks = null;
+            setFrameCallback(frame -> {
+                for (int i = 0; i < frameCallbacks.size(); ++i) {
+                    frameCallbacks.get(i).onFrameDraw(frame);
+                }
+            });
         }
 
         if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {
diff --git a/core/java/android/view/Transaction.aidl b/core/java/android/view/Transaction.aidl
new file mode 100644
index 0000000..8d24b43
--- /dev/null
+++ b/core/java/android/view/Transaction.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.SurfaceControl;
+
+parcelable Transaction;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1d8b910..69884dc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8273,6 +8273,8 @@
         event.setPackageName(getContext().getPackageName());
         event.setEnabled(isEnabled());
         event.setContentDescription(mContentDescription);
+        event.setScrollX(getScrollX());
+        event.setScrollY(getScrollY());
 
         switch (event.getEventType()) {
             case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
@@ -9497,6 +9499,12 @@
         mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
     }
 
+    /** @hide */
+    protected boolean getNotifiedContentCaptureAppeared() {
+        return (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0;
+    }
+
+
     /**
      * Sets the (optional) {@link ContentCaptureSession} associated with this view.
      *
@@ -15579,7 +15587,8 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     void setFlags(int flags, int mask) {
-        final boolean accessibilityEnabled = AccessibilityManager.getInstance(mContext).isEnabled();
+        final boolean accessibilityEnabled =
+                AccessibilityManager.getInstance(mContext).isEnabled();
         final boolean oldIncludeForAccessibility = accessibilityEnabled && includeForAccessibility();
 
         int old = mViewFlags;
@@ -15794,14 +15803,19 @@
         if (accessibilityEnabled) {
             // If we're an accessibility pane and the visibility changed, we already have sent
             // a state change, so we really don't need to report other changes.
-            // Accessibility Services aren't concerned with changes between GONE and INVISIBLE.
-            boolean visibilityChanged = !isAccessibilityPane() && ((changed & VISIBILITY_MASK) != 0)
-                    && ((old & VISIBILITY_MASK) == VISIBLE || newVisibility == VISIBLE);
-            if (oldIncludeForAccessibility != includeForAccessibility() || visibilityChanged) {
-                notifySubtreeAccessibilityStateChangedIfNeeded();
-            } else if ((changed & ENABLED_MASK) != 0 || (changed & FOCUSABLE) != 0
+            if (isAccessibilityPane()) {
+                changed &= ~VISIBILITY_MASK;
+            }
+            if ((changed & FOCUSABLE) != 0 || (changed & VISIBILITY_MASK) != 0
                     || (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0
                     || (changed & CONTEXT_CLICKABLE) != 0) {
+                if (oldIncludeForAccessibility != includeForAccessibility()) {
+                    notifySubtreeAccessibilityStateChangedIfNeeded();
+                } else {
+                    notifyViewAccessibilityStateChangedIfNeeded(
+                            AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+                }
+            } else if ((changed & ENABLED_MASK) != 0) {
                 notifyViewAccessibilityStateChangedIfNeeded(
                         AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
             }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e071120..613ddcf 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -609,10 +609,13 @@
     }
 
     private String mTag = TAG;
-
     public ViewRootImpl(Context context, Display display) {
+        this(context, display, WindowManagerGlobal.getWindowSession());
+    }
+
+    public ViewRootImpl(Context context, Display display, IWindowSession session) {
         mContext = context;
-        mWindowSession = WindowManagerGlobal.getWindowSession();
+        mWindowSession = session;
         mDisplay = display;
         mBasePackageName = context.getBasePackageName();
         mThread = Thread.currentThread();
@@ -1129,9 +1132,15 @@
      *
      * @param callback The callback to register.
      */
-    public void registerRtFrameCallback(FrameDrawingCallback callback) {
+    public void registerRtFrameCallback(@NonNull FrameDrawingCallback callback) {
         if (mAttachInfo.mThreadedRenderer != null) {
-            mAttachInfo.mThreadedRenderer.registerRtFrameCallback(callback);
+            mAttachInfo.mThreadedRenderer.registerRtFrameCallback(frame -> {
+                try {
+                    callback.onFrameDraw(frame);
+                } catch (Exception e) {
+                    Log.e(TAG, "Exception while executing onFrameDraw", e);
+                }
+            });
         }
     }
 
@@ -1546,6 +1555,7 @@
     }
 
     void setWindowStopped(boolean stopped) {
+        checkThread();
         if (mStopped != stopped) {
             mStopped = stopped;
             final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer;
@@ -1567,7 +1577,7 @@
             }
 
             if (mStopped) {
-                if (mSurfaceHolder != null) {
+                if (mSurfaceHolder != null && mSurface.isValid()) {
                     notifySurfaceDestroyed();
                 }
                 destroySurface();
@@ -1630,7 +1640,7 @@
         mSurfaceSession = null;
 
         if (mBoundsSurfaceControl != null) {
-            mBoundsSurfaceControl.remove();
+            mTransaction.remove(mBoundsSurfaceControl).apply();
             mBoundsSurface.release();
             mBoundsSurfaceControl = null;
         }
@@ -2233,6 +2243,8 @@
 
         final boolean isViewVisible = viewVisibility == View.VISIBLE;
         final boolean windowRelayoutWasForced = mForceNextWindowRelayout;
+        boolean surfaceSizeChanged = false;
+
         if (mFirst || windowShouldResize || insetsChanged ||
                 viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
             mForceNextWindowRelayout = false;
@@ -2311,7 +2323,7 @@
                 final boolean cutoutChanged = !mPendingDisplayCutout.equals(
                         mAttachInfo.mDisplayCutout);
                 final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
-                final boolean surfaceSizeChanged = (relayoutResult
+                surfaceSizeChanged = (relayoutResult
                         & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
                 surfaceChanged |= surfaceSizeChanged;
                 final boolean alwaysConsumeSystemBarsChanged =
@@ -2594,7 +2606,7 @@
             maybeHandleWindowMove(frame);
         }
 
-        if (surfaceChanged) {
+        if (surfaceSizeChanged) {
             updateBoundsSurface();
         }
 
@@ -3435,7 +3447,7 @@
     private void reportDrawFinished() {
         try {
             mDrawsNeededToReport = 0;
-            mWindowSession.finishDrawing(mWindow);
+            mWindowSession.finishDrawing(mWindow, null /* postDrawTransaction */);
         } catch (RemoteException e) {
             // Have fun!
         }
@@ -4617,6 +4629,7 @@
                         final int displayId = args.argi3;
                         MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
                         final boolean displayChanged = mDisplay.getDisplayId() != displayId;
+                        boolean configChanged = false;
 
                         if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) {
                             // If configuration changed - notify about that and, maybe,
@@ -4624,6 +4637,7 @@
                             performConfigurationChange(mergedConfiguration, false /* force */,
                                     displayChanged
                                             ? displayId : INVALID_DISPLAY /* same display */);
+                            configChanged = true;
                         } else if (displayChanged) {
                             // Moved to display without config change - report last applied one.
                             onMovedToDisplay(displayId, mLastConfigurationFromResources);
@@ -4654,7 +4668,7 @@
                             reportNextDraw();
                         }
 
-                        if (mView != null && framesChanged) {
+                        if (mView != null && (framesChanged || configChanged)) {
                             forceLayout(mView);
                         }
                         requestLayout();
@@ -7323,7 +7337,8 @@
                         try {
                             if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
                                     & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
-                                mWindowSession.finishDrawing(mWindow);
+                                mWindowSession.finishDrawing(
+                                        mWindow, null /* postDrawTransaction */);
                             }
                         } catch (RemoteException e) {
                         }
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index c50a3aa..9a5f4c9 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -1074,7 +1074,7 @@
      * be called manually if you are forcing the drawing on a View or a hierarchy of Views
      * that are not attached to a Window or in the GONE state.
      *
-     * @return True if the current draw should be canceled and resceduled, false otherwise.
+     * @return True if the current draw should be canceled and rescheduled, false otherwise.
      */
     @SuppressWarnings("unchecked")
     public final boolean dispatchOnPreDraw() {
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
index 74fc15a..57dfc62 100644
--- a/core/java/android/view/WindowInfo.java
+++ b/core/java/android/view/WindowInfo.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -44,12 +44,13 @@
     public IBinder parentToken;
     public IBinder activityToken;
     public boolean focused;
-    public final Rect boundsInScreen = new Rect();
+    public Region regionInScreen = new Region();
     public List<IBinder> childTokens;
     public CharSequence title;
     public long accessibilityIdOfAnchor = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
     public boolean inPictureInPicture;
     public boolean hasFlagWatchOutsideTouch;
+    public int displayId = Display.INVALID_DISPLAY;
 
     private WindowInfo() {
         /* do nothing - hide constructor */
@@ -65,13 +66,14 @@
 
     public static WindowInfo obtain(WindowInfo other) {
         WindowInfo window = obtain();
+        window.displayId = other.displayId;
         window.type = other.type;
         window.layer = other.layer;
         window.token = other.token;
         window.parentToken = other.parentToken;
         window.activityToken = other.activityToken;
         window.focused = other.focused;
-        window.boundsInScreen.set(other.boundsInScreen);
+        window.regionInScreen.set(other.regionInScreen);
         window.title = other.title;
         window.accessibilityIdOfAnchor = other.accessibilityIdOfAnchor;
         window.inPictureInPicture = other.inPictureInPicture;
@@ -100,13 +102,14 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(displayId);
         parcel.writeInt(type);
         parcel.writeInt(layer);
         parcel.writeStrongBinder(token);
         parcel.writeStrongBinder(parentToken);
         parcel.writeStrongBinder(activityToken);
         parcel.writeInt(focused ? 1 : 0);
-        boundsInScreen.writeToParcel(parcel, flags);
+        regionInScreen.writeToParcel(parcel, flags);
         parcel.writeCharSequence(title);
         parcel.writeLong(accessibilityIdOfAnchor);
         parcel.writeInt(inPictureInPicture ? 1 : 0);
@@ -125,10 +128,12 @@
         StringBuilder builder = new StringBuilder();
         builder.append("WindowInfo[");
         builder.append("title=").append(title);
+        builder.append(", displayId=").append(displayId);
         builder.append(", type=").append(type);
         builder.append(", layer=").append(layer);
         builder.append(", token=").append(token);
-        builder.append(", bounds=").append(boundsInScreen);
+        builder.append(", region=").append(regionInScreen);
+        builder.append(", bounds=").append(regionInScreen.getBounds());
         builder.append(", parent=").append(parentToken);
         builder.append(", focused=").append(focused);
         builder.append(", children=").append(childTokens);
@@ -140,13 +145,14 @@
     }
 
     private void initFromParcel(Parcel parcel) {
+        displayId = parcel.readInt();
         type = parcel.readInt();
         layer = parcel.readInt();
         token = parcel.readStrongBinder();
         parentToken = parcel.readStrongBinder();
         activityToken = parcel.readStrongBinder();
         focused = (parcel.readInt() == 1);
-        boundsInScreen.readFromParcel(parcel);
+        regionInScreen = Region.CREATOR.createFromParcel(parcel);
         title = parcel.readCharSequence();
         accessibilityIdOfAnchor = parcel.readLong();
         inPictureInPicture = (parcel.readInt() == 1);
@@ -162,13 +168,14 @@
     }
 
     private void clear() {
+        displayId = Display.INVALID_DISPLAY;
         type = 0;
         layer = 0;
         token = null;
         parentToken = null;
         activityToken = null;
         focused = false;
-        boundsInScreen.setEmpty();
+        regionInScreen.setEmpty();
         if (childTokens != null) {
             childTokens.clear();
         }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 1f89de8..2e5a750 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -319,6 +319,12 @@
     int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER = 0x4;
 
     /**
+     * Transition flag: Keyguard is going away with subtle animation.
+     * @hide
+     */
+    int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION = 0x8;
+
+    /**
      * @hide
      */
     @IntDef(flag = true, prefix = { "TRANSIT_FLAG_" }, value = {
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 8a111cf..379acbe 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -636,13 +636,21 @@
     }
 
     public void setStoppedState(IBinder token, boolean stopped) {
+        ArrayList<ViewRootImpl> nonCurrentThreadRoots = null;
         synchronized (mLock) {
             int count = mViews.size();
             for (int i = count - 1; i >= 0; i--) {
                 if (token == null || mParams.get(i).token == token) {
                     ViewRootImpl root = mRoots.get(i);
                     // Client might remove the view by "stopped" event.
-                    root.setWindowStopped(stopped);
+                    if (root.mThread == Thread.currentThread()) {
+                        root.setWindowStopped(stopped);
+                    } else {
+                        if (nonCurrentThreadRoots == null) {
+                            nonCurrentThreadRoots = new ArrayList<>();
+                        }
+                        nonCurrentThreadRoots.add(root);
+                    }
                     // Recursively forward stopped state to View's attached
                     // to this Window rather than the root application token,
                     // e.g. PopupWindow's.
@@ -650,6 +658,16 @@
                 }
             }
         }
+
+        // Update the stopped state synchronously to ensure the surface won't be used after server
+        // side has destroyed it. This operation should be outside the lock to avoid any potential
+        // paths from setWindowStopped to WindowManagerGlobal which may cause deadlocks.
+        if (nonCurrentThreadRoots != null) {
+            for (int i = nonCurrentThreadRoots.size() - 1; i >= 0; i--) {
+                ViewRootImpl root = nonCurrentThreadRoots.get(i);
+                root.mHandler.runWithScissors(() -> root.setWindowStopped(stopped), 0);
+            }
+        }
     }
 
     public void reportNewConfiguration(Configuration config) {
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 46a59f0..a22f5a5 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -38,10 +38,11 @@
     int FLAG_INTERACTIVE = 0x20000000;
     int FLAG_PASS_TO_USER = 0x40000000;
 
-    // Flags for IActivityManager.keyguardGoingAway()
+    // Flags for IActivityTaskManager.keyguardGoingAway()
     int KEYGUARD_GOING_AWAY_FLAG_TO_SHADE = 1 << 0;
     int KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS = 1 << 1;
     int KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER = 1 << 2;
+    int KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS = 1 << 3;
 
     // Flags used for indicating whether the internal and/or external input devices
     // of some type are available.
diff --git a/core/java/android/view/WindowlessViewRoot.java b/core/java/android/view/WindowlessViewRoot.java
new file mode 100644
index 0000000..75057a2
--- /dev/null
+++ b/core/java/android/view/WindowlessViewRoot.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.view;
+
+import android.content.res.Resources;
+import android.content.Context;
+import android.view.SurfaceControl;
+import android.view.View;
+
+/**
+ * Utility class for adding a view hierarchy to a SurfaceControl.
+ *
+ * See WindowlessWmTest for example usage.
+ * @hide
+ */
+public class WindowlessViewRoot {
+    ViewRootImpl mViewRoot;
+    WindowlessWindowManager mWm;
+    public WindowlessViewRoot(Context c, Display d, SurfaceControl rootSurface) {
+        mWm = new WindowlessWindowManager(c.getResources().getConfiguration(), rootSurface);
+        mViewRoot = new ViewRootImpl(c, d, mWm);
+    }
+
+    public void addView(View view, WindowManager.LayoutParams attrs) {
+        mViewRoot.setView(view, attrs, null);
+    }
+}
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
new file mode 100644
index 0000000..dfeb4b5
--- /dev/null
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.MergedConfiguration;
+import android.util.Log;
+import android.view.IWindowSession;
+import android.view.SurfaceControl;
+import android.view.SurfaceSession;
+
+import java.util.HashMap;
+
+/**
+* A simplistic implementation of IWindowSession. Rather than managing Surfaces
+* as children of the display, it manages Surfaces as children of a given root.
+*
+* By parcelling the root surface, the app can offer another app content for embedding.
+* @hide
+*/
+class WindowlessWindowManager extends IWindowSession.Default {
+    private final static String TAG = "WindowlessWindowManager";
+
+    /**
+     * Used to store SurfaceControl we've built for clients to
+     * reconfigure them if relayout is called.
+     */
+    final HashMap<IBinder, SurfaceControl> mScForWindow = new HashMap<IBinder, SurfaceControl>();
+    final SurfaceSession mSurfaceSession = new SurfaceSession();
+    final SurfaceControl mRootSurface;
+    final Configuration mConfiguration;
+    IWindowSession mRealWm;
+
+    private int mForceHeight = -1;
+    private int mForceWidth = -1;
+
+    WindowlessWindowManager(Configuration c, SurfaceControl rootSurface) {
+        mRootSurface = rootSurface;
+        mConfiguration = new Configuration(c);
+        mRealWm = WindowManagerGlobal.getWindowSession();
+    }
+
+    public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
+            int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
+            Rect outStableInsets, Rect outOutsets,
+            DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
+            InsetsState outInsetsState) {
+        final SurfaceControl.Builder b = new SurfaceControl.Builder(mSurfaceSession)
+            .setParent(mRootSurface)
+            .setName(attrs.getTitle().toString());
+        final SurfaceControl sc = b.build();
+        synchronized (this) {
+            mScForWindow.put(window.asBinder(), sc);
+        }
+
+        if ((attrs.inputFeatures &
+                WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
+            try {
+                mRealWm.blessInputSurface(displayId, sc, outInputChannel);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to bless surface: " + e);
+            }
+        }
+
+        return WindowManagerGlobal.ADD_OKAY | WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
+    }
+
+    @Override
+    public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
+            int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber,
+            Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets,
+            Rect outStableInsets, Rect outsets, Rect outBackdropFrame,
+            DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
+            SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
+        SurfaceControl sc = null;
+        synchronized (this) {
+            sc = mScForWindow.get(window.asBinder());
+        }
+        if (sc == null) {
+            throw new IllegalArgumentException(
+                    "Invalid window token (never added or removed already)");
+        }
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        t.show(sc).setBufferSize(sc, requestedWidth, requestedHeight).apply();
+        outSurfaceControl.copyFrom(sc);
+        outFrame.set(0, 0, requestedWidth, requestedHeight);
+
+        mergedConfiguration.setConfiguration(mConfiguration, mConfiguration);
+
+        return 0;
+    }
+}
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 985effb..fd09a87 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -622,6 +622,10 @@
     /**
      * Change type for {@link #TYPE_WINDOWS_CHANGED} event:
      * The window's bounds changed.
+     * <p>
+     * Starting in {@link android.os.Build.VERSION_CODES#R R}, this event implies the window's
+     * region changed. It's also possible that region changed but bounds doesn't.
+     * </p>
      */
     public static final int WINDOWS_CHANGE_BOUNDS = 0x00000008;
 
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 882e6fd..2e9d881 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -184,7 +184,7 @@
 
     boolean mIsTouchExplorationEnabled;
 
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768939)
+    @UnsupportedAppUsage(trackingBug = 123768939L)
     boolean mIsHighTextContrastEnabled;
 
     AccessibilityPolicy mAccessibilityPolicy;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeIdManager.java b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
index 0f5e950..d78dadd 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
@@ -16,12 +16,11 @@
 
 package android.view.accessibility;
 
-import android.util.SparseArray;
 import android.view.View;
 
 /** @hide */
 public final class AccessibilityNodeIdManager {
-    private SparseArray<View> mIdsToViews = new SparseArray<>();
+    private WeakSparseArray<View> mIdsToViews = new WeakSparseArray<View>();
     private static AccessibilityNodeIdManager sIdManager;
 
     /**
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 5b3dbb1..d474b4d 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -1688,6 +1688,11 @@
      * 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>
+     * When magnification is enabled, the bounds in parent are also scaled up by magnification
+     * scale. For example, it returns Rect(20, 20, 200, 200) for original bounds
+     * Rect(10, 10, 100, 100), when the magnification scale is 2.
+     * <p/>
      *
      * @param outBounds The output node bounds.
      * @deprecated Use {@link #getBoundsInScreen(Rect)} instead.
@@ -1725,6 +1730,12 @@
 
     /**
      * Gets the node bounds in screen coordinates.
+     * <p>
+     * When magnification is enabled, the bounds in screen are scaled up by magnification scale
+     * and the positions are also adjusted according to the offset of magnification viewport.
+     * For example, it returns Rect(-180, -180, 0, 0) for original bounds Rect(10, 10, 100, 100),
+     * when the magnification scale is 2 and offsets for X and Y are both 200.
+     * <p/>
      *
      * @param outBounds The output node bounds.
      */
@@ -1861,6 +1872,12 @@
 
     /**
      * Gets whether this node is visible to the user.
+     * <p>
+     * Between {@link Build.VERSION_CODES#JELLY_BEAN API 16} and
+     * {@link Build.VERSION_CODES#Q API 29}, this method may incorrectly return false when
+     * magnification is enabled. On other versions, a node is considered visible even if it is not
+     * on the screen because magnification is active.
+     * </p>
      *
      * @return Whether the node is visible to the user.
      */
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index b382a18..42275a3 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -90,13 +90,13 @@
     int mItemCount = UNDEFINED;
     int mFromIndex = UNDEFINED;
     int mToIndex = UNDEFINED;
-    int mScrollX = UNDEFINED;
-    int mScrollY = UNDEFINED;
+    int mScrollX = 0;
+    int mScrollY = 0;
 
     int mScrollDeltaX = UNDEFINED;
     int mScrollDeltaY = UNDEFINED;
-    int mMaxScrollX = UNDEFINED;
-    int mMaxScrollY = UNDEFINED;
+    int mMaxScrollX = 0;
+    int mMaxScrollY = 0;
 
     int mAddedCount= UNDEFINED;
     int mRemovedCount = UNDEFINED;
@@ -878,10 +878,10 @@
         mItemCount = UNDEFINED;
         mFromIndex = UNDEFINED;
         mToIndex = UNDEFINED;
-        mScrollX = UNDEFINED;
-        mScrollY = UNDEFINED;
-        mMaxScrollX = UNDEFINED;
-        mMaxScrollY = UNDEFINED;
+        mScrollX = 0;
+        mScrollY = 0;
+        mMaxScrollX = 0;
+        mMaxScrollY = 0;
         mAddedCount = UNDEFINED;
         mRemovedCount = UNDEFINED;
         mClassName = null;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index b474c13..6a3af34 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -16,14 +16,17 @@
 
 package android.view.accessibility;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.util.LongArray;
 import android.util.Pools.SynchronizedPool;
+import android.view.Display;
 import android.view.accessibility.AccessibilityEvent.WindowsChangeTypes;
 
 import java.util.Objects;
@@ -100,12 +103,13 @@
     private static AtomicInteger sNumInstancesInUse;
 
     // Data.
+    private int mDisplayId = Display.INVALID_DISPLAY;
     private int mType = UNDEFINED_WINDOW_ID;
     private int mLayer = UNDEFINED_WINDOW_ID;
     private int mBooleanProperties;
     private int mId = UNDEFINED_WINDOW_ID;
     private int mParentId = UNDEFINED_WINDOW_ID;
-    private final Rect mBoundsInScreen = new Rect();
+    private Region mRegionInScreen = new Region();
     private LongArray mChildIds;
     private CharSequence mTitle;
     private long mAnchorId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
@@ -303,23 +307,33 @@
     }
 
     /**
-     * Gets the bounds of this window in the screen.
+     * Gets the touchable region of this window in the screen.
+     *
+     * @param outRegion The out window region.
+     */
+    public void getRegionInScreen(@NonNull Region outRegion) {
+        outRegion.set(mRegionInScreen);
+    }
+
+    /**
+     * Sets the touchable region of this window in the screen.
+     *
+     * @param region The window region.
+     *
+     * @hide
+     */
+    public void setRegionInScreen(Region region) {
+        mRegionInScreen.set(region);
+    }
+
+    /**
+     * Gets the bounds of this window in the screen. This is equivalent to get the bounds of the
+     * Region from {@link #getRegionInScreen(Region)}.
      *
      * @param outBounds The out window bounds.
      */
     public void getBoundsInScreen(Rect outBounds) {
-        outBounds.set(mBoundsInScreen);
-    }
-
-    /**
-     * Sets the bounds of this window in the screen.
-     *
-     * @param bounds The out window bounds.
-     *
-     * @hide
-     */
-    public void setBoundsInScreen(Rect bounds) {
-        mBoundsInScreen.set(bounds);
+        outBounds.set(mRegionInScreen.getBounds());
     }
 
     /**
@@ -428,6 +442,27 @@
     }
 
     /**
+     * Sets the display Id.
+     *
+     * @param displayId The display id.
+     *
+     * @hide
+     */
+    public void setDisplayId(int displayId) {
+        mDisplayId = displayId;
+    }
+
+    /**
+     * Returns the ID of the display this window is on, for use with
+     * {@link android.hardware.display.DisplayManager#getDisplay(int)}.
+     *
+     * @return The logical display id.
+     */
+    public int getDisplayId() {
+        return mDisplayId;
+    }
+
+    /**
      * Returns a cached instance if such is available or a new one is
      * created.
      *
@@ -493,12 +528,13 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mDisplayId);
         parcel.writeInt(mType);
         parcel.writeInt(mLayer);
         parcel.writeInt(mBooleanProperties);
         parcel.writeInt(mId);
         parcel.writeInt(mParentId);
-        mBoundsInScreen.writeToParcel(parcel, flags);
+        mRegionInScreen.writeToParcel(parcel, flags);
         parcel.writeCharSequence(mTitle);
         parcel.writeLong(mAnchorId);
 
@@ -522,12 +558,13 @@
      * @param other The other instance.
      */
     private void init(AccessibilityWindowInfo other) {
+        mDisplayId = other.mDisplayId;
         mType = other.mType;
         mLayer = other.mLayer;
         mBooleanProperties = other.mBooleanProperties;
         mId = other.mId;
         mParentId = other.mParentId;
-        mBoundsInScreen.set(other.mBoundsInScreen);
+        mRegionInScreen.set(other.mRegionInScreen);
         mTitle = other.mTitle;
         mAnchorId = other.mAnchorId;
 
@@ -543,12 +580,13 @@
     }
 
     private void initFromParcel(Parcel parcel) {
+        mDisplayId = parcel.readInt();
         mType = parcel.readInt();
         mLayer = parcel.readInt();
         mBooleanProperties = parcel.readInt();
         mId = parcel.readInt();
         mParentId = parcel.readInt();
-        mBoundsInScreen.readFromParcel(parcel);
+        mRegionInScreen = Region.CREATOR.createFromParcel(parcel);
         mTitle = parcel.readCharSequence();
         mAnchorId = parcel.readLong();
 
@@ -591,10 +629,12 @@
         StringBuilder builder = new StringBuilder();
         builder.append("AccessibilityWindowInfo[");
         builder.append("title=").append(mTitle);
+        builder.append(", displayId=").append(mDisplayId);
         builder.append(", id=").append(mId);
         builder.append(", type=").append(typeToString(mType));
         builder.append(", layer=").append(mLayer);
-        builder.append(", bounds=").append(mBoundsInScreen);
+        builder.append(", region=").append(mRegionInScreen);
+        builder.append(", bounds=").append(mRegionInScreen.getBounds());
         builder.append(", focused=").append(isFocused());
         builder.append(", active=").append(isActive());
         builder.append(", pictureInPicture=").append(isInPictureInPictureMode());
@@ -628,12 +668,13 @@
      * Clears the internal state.
      */
     private void clear() {
+        mDisplayId = Display.INVALID_DISPLAY;
         mType = UNDEFINED_WINDOW_ID;
         mLayer = UNDEFINED_WINDOW_ID;
         mBooleanProperties = 0;
         mId = UNDEFINED_WINDOW_ID;
         mParentId = UNDEFINED_WINDOW_ID;
-        mBoundsInScreen.setEmpty();
+        mRegionInScreen.setEmpty();
         mChildIds = null;
         mConnectionId = UNDEFINED_WINDOW_ID;
         mAnchorId = AccessibilityNodeInfo.UNDEFINED_NODE_ID;
@@ -689,45 +730,6 @@
     }
 
     /**
-     * Checks whether this window changed. The argument should be
-     * another state of the same window, which is have the same id
-     * and type as they never change.
-     *
-     * @param other The new state.
-     * @return Whether something changed.
-     *
-     * @hide
-     */
-    public boolean changed(AccessibilityWindowInfo other) {
-        if (other.mId != mId) {
-            throw new IllegalArgumentException("Not same window.");
-        }
-        if (other.mType != mType) {
-            throw new IllegalArgumentException("Not same type.");
-        }
-        if (!mBoundsInScreen.equals(other.mBoundsInScreen)) {
-            return true;
-        }
-        if (mLayer != other.mLayer) {
-            return true;
-        }
-        if (mBooleanProperties != other.mBooleanProperties) {
-            return true;
-        }
-        if (mParentId != other.mParentId) {
-            return true;
-        }
-        if (mChildIds == null) {
-            if (other.mChildIds != null) {
-                return true;
-            }
-        } else if (!mChildIds.equals(other.mChildIds)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
      * Reports how this window differs from a possibly different state of the same window. The
      * argument must have the same id and type as neither of those properties may change.
      *
@@ -749,8 +751,7 @@
         if (!TextUtils.equals(mTitle, other.mTitle)) {
             changes |= AccessibilityEvent.WINDOWS_CHANGE_TITLE;
         }
-
-        if (!mBoundsInScreen.equals(other.mBoundsInScreen)) {
+        if (!mRegionInScreen.equals(other.mRegionInScreen)) {
             changes |= AccessibilityEvent.WINDOWS_CHANGE_BOUNDS;
         }
         if (mLayer != other.mLayer) {
@@ -778,6 +779,7 @@
         if (!Objects.equals(mChildIds, other.mChildIds)) {
             changes |= AccessibilityEvent.WINDOWS_CHANGE_CHILDREN;
         }
+        //TODO(b/1338122): Add DISPLAY_CHANGED type for multi-display
         return changes;
     }
 
diff --git a/core/java/android/view/accessibility/WeakSparseArray.java b/core/java/android/view/accessibility/WeakSparseArray.java
new file mode 100644
index 0000000..04a4cc7
--- /dev/null
+++ b/core/java/android/view/accessibility/WeakSparseArray.java
@@ -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 android.view.accessibility;
+
+import android.util.SparseArray;
+
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+
+final class WeakSparseArray<E> {
+
+    private final ReferenceQueue<E> mRefQueue = new ReferenceQueue<>();
+    private final SparseArray<WeakReferenceWithId<E>> mSparseArray = new SparseArray<>();
+
+    public void append(int key, E value) {
+        removeUnreachableValues();
+        mSparseArray.append(key, new WeakReferenceWithId(value, mRefQueue, key));
+    }
+
+    public void remove(int key) {
+        removeUnreachableValues();
+        mSparseArray.remove(key);
+    }
+
+    public E get(int key) {
+        removeUnreachableValues();
+        WeakReferenceWithId<E> ref = mSparseArray.get(key);
+        return ref != null ? ref.get() : null;
+    }
+
+    private void removeUnreachableValues() {
+        for (Reference ref = mRefQueue.poll(); ref != null; ref = mRefQueue.poll()) {
+            mSparseArray.remove(((WeakReferenceWithId) ref).mId);
+        }
+    }
+
+    private static class WeakReferenceWithId<E> extends WeakReference<E> {
+
+        final int mId;
+
+        WeakReferenceWithId(E referent, ReferenceQueue<? super E> q, int id) {
+            super(referent, q);
+            mId = id;
+        }
+    }
+}
+
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index c5a5f73..cee7943 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -428,14 +428,16 @@
         }
 
         final int flushFrequencyMs;
-        if (reason == FLUSH_REASON_IDLE_TIMEOUT) {
-            flushFrequencyMs = mManager.mOptions.idleFlushingFrequencyMs;
-        } else if (reason == FLUSH_REASON_TEXT_CHANGE_TIMEOUT) {
+        if (reason == FLUSH_REASON_TEXT_CHANGE_TIMEOUT) {
             flushFrequencyMs = mManager.mOptions.textChangeFlushingFrequencyMs;
         } else {
-            Log.e(TAG, "handleScheduleFlush(" + getDebugState(reason) + "): not called with a "
-                    + "timeout reason.");
-            return;
+            if (reason != FLUSH_REASON_IDLE_TIMEOUT) {
+                if (sDebug) {
+                    Log.d(TAG, "handleScheduleFlush(" + getDebugState(reason) + "): not a timeout "
+                            + "reason because mDirectServiceInterface is not ready yet");
+                }
+            }
+            flushFrequencyMs = mManager.mOptions.idleFlushingFrequencyMs;
         }
 
         mNextFlush = System.currentTimeMillis() + flushFrequencyMs;
diff --git a/core/java/android/view/inputmethod/InputMethodSystemProperty.java b/core/java/android/view/inputmethod/InputMethodSystemProperty.java
index 7c79d44..e20c2fd 100644
--- a/core/java/android/view/inputmethod/InputMethodSystemProperty.java
+++ b/core/java/android/view/inputmethod/InputMethodSystemProperty.java
@@ -41,17 +41,6 @@
      */
     private static final String PROP_DEBUG_MULTI_CLIENT_IME = "persist.debug.multi_client_ime";
 
-    /**
-     * System property key for debugging purpose. The value must be empty, "1", or "0".
-     *
-     * <p>Values 'y', 'yes', '1', 'true' or 'on' are considered true.</p>
-     *
-     * <p>To set, run "adb root && adb shell setprop persist.debug.per_profile_ime 1".</p>
-     *
-     * <p>This value will be ignored when {@link Build#IS_DEBUGGABLE} returns {@code false}.</p>
-     */
-    private static final String PROP_DEBUG_PER_PROFILE_IME = "persist.debug.per_profile_ime";
-
     @Nullable
     private static ComponentName getMultiClientImeComponentName() {
         if (Build.IS_DEBUGGABLE) {
@@ -88,19 +77,4 @@
      * @hide
      */
     public static final boolean MULTI_CLIENT_IME_ENABLED = (sMultiClientImeComponentName != null);
-
-    /**
-     * {@code true} when per-profile IME is enabled.
-     * @hide
-     */
-    public static final boolean PER_PROFILE_IME_ENABLED;
-    static {
-        if (MULTI_CLIENT_IME_ENABLED) {
-            PER_PROFILE_IME_ENABLED = true;
-        } else if (Build.IS_DEBUGGABLE) {
-            PER_PROFILE_IME_ENABLED = SystemProperties.getBoolean(PROP_DEBUG_PER_PROFILE_IME, true);
-        } else {
-            PER_PROFILE_IME_ENABLED = true;
-        }
-    }
 }
diff --git a/core/java/android/view/textclassifier/ActionsModelParamsSupplier.java b/core/java/android/view/textclassifier/ActionsModelParamsSupplier.java
index 6b90588..3164567 100644
--- a/core/java/android/view/textclassifier/ActionsModelParamsSupplier.java
+++ b/core/java/android/view/textclassifier/ActionsModelParamsSupplier.java
@@ -60,7 +60,9 @@
     private boolean mParsed = true;
 
     public ActionsModelParamsSupplier(Context context, @Nullable Runnable onChangedListener) {
-        mAppContext = Preconditions.checkNotNull(context).getApplicationContext();
+        final Context appContext = Preconditions.checkNotNull(context).getApplicationContext();
+        // Some contexts don't have an app context.
+        mAppContext = appContext != null ? appContext : context;
         mOnChangedListener = onChangedListener == null ? () -> {} : onChangedListener;
         mSettingsObserver = new SettingsObserver(mAppContext, () -> {
             synchronized (mLock) {
diff --git a/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java b/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
index 9c268f2..3ed48f6 100644
--- a/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
+++ b/core/java/android/view/textclassifier/ActionsSuggestionsHelper.java
@@ -19,7 +19,9 @@
 import android.annotation.Nullable;
 import android.app.Person;
 import android.app.RemoteAction;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Pair;
@@ -200,10 +202,12 @@
         if (remoteAction == null) {
             return null;
         }
+        Intent actionIntent = ExtrasUtils.getActionIntent(conversationAction.getExtras());
+        ComponentName componentName = actionIntent.getComponent();
+        // Action without a component name will be considered as from the same app.
+        String packageName = componentName == null ? null : componentName.getPackageName();
         return new Pair<>(
-                conversationAction.getAction().getTitle().toString(),
-                ExtrasUtils.getActionIntent(
-                        conversationAction.getExtras()).getComponent().getPackageName());
+                conversationAction.getAction().getTitle().toString(), packageName);
     }
 
     private static final class PersonEncoder {
diff --git a/core/java/android/view/textclassifier/ConversationActions.java b/core/java/android/view/textclassifier/ConversationActions.java
index aeb99b8..f7f503a 100644
--- a/core/java/android/view/textclassifier/ConversationActions.java
+++ b/core/java/android/view/textclassifier/ConversationActions.java
@@ -21,10 +21,12 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringDef;
+import android.annotation.UserIdInt;
 import android.app.Person;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.text.SpannedString;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -316,6 +318,8 @@
         private final List<String> mHints;
         @Nullable
         private String mCallingPackageName;
+        @UserIdInt
+        private int mUserId = UserHandle.USER_NULL;
         @NonNull
         private Bundle mExtras;
 
@@ -340,6 +344,7 @@
             List<String> hints = new ArrayList<>();
             in.readStringList(hints);
             String callingPackageName = in.readString();
+            int userId = in.readInt();
             Bundle extras = in.readBundle();
             Request request = new Request(
                     conversation,
@@ -348,6 +353,7 @@
                     hints,
                     extras);
             request.setCallingPackageName(callingPackageName);
+            request.setUserId(userId);
             return request;
         }
 
@@ -358,6 +364,7 @@
             parcel.writeInt(mMaxSuggestions);
             parcel.writeStringList(mHints);
             parcel.writeString(mCallingPackageName);
+            parcel.writeInt(mUserId);
             parcel.writeBundle(mExtras);
         }
 
@@ -428,6 +435,25 @@
         }
 
         /**
+         * Sets the id of the user that sent this request.
+         * <p>
+         * Package-private for SystemTextClassifier's use.
+         * @hide
+         */
+        void setUserId(@UserIdInt int userId) {
+            mUserId = userId;
+        }
+
+        /**
+         * Returns the id of the user that sent this request.
+         * @hide
+         */
+        @UserIdInt
+        public int getUserId() {
+            return mUserId;
+        }
+
+        /**
          * Returns the extended data related to this request.
          *
          * <p><b>NOTE: </b>Do not modify this bundle.
diff --git a/core/java/android/view/textclassifier/SelectionEvent.java b/core/java/android/view/textclassifier/SelectionEvent.java
index 9ae0c65..80c728f 100644
--- a/core/java/android/view/textclassifier/SelectionEvent.java
+++ b/core/java/android/view/textclassifier/SelectionEvent.java
@@ -19,8 +19,10 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.view.textclassifier.TextClassifier.EntityType;
 import android.view.textclassifier.TextClassifier.WidgetType;
 
@@ -120,13 +122,14 @@
 
     private final int mAbsoluteStart;
     private final int mAbsoluteEnd;
-    private final @EntityType String mEntityType;
 
+    private @EntityType String mEntityType;
     private @EventType int mEventType;
     private String mPackageName = "";
     private String mWidgetType = TextClassifier.WIDGET_TYPE_UNKNOWN;
     private @InvocationMethod int mInvocationMethod;
     @Nullable private String mWidgetVersion;
+    private @UserIdInt int mUserId = UserHandle.USER_NULL;
     @Nullable private String mResultId;
     private long mEventTime;
     private long mDurationSinceSessionStart;
@@ -158,6 +161,7 @@
         mEntityType = in.readString();
         mWidgetVersion = in.readInt() > 0 ? in.readString() : null;
         mPackageName = in.readString();
+        mUserId = in.readInt();
         mWidgetType = in.readString();
         mInvocationMethod = in.readInt();
         mResultId = in.readString();
@@ -184,6 +188,7 @@
             dest.writeString(mWidgetVersion);
         }
         dest.writeString(mPackageName);
+        dest.writeInt(mUserId);
         dest.writeString(mWidgetType);
         dest.writeInt(mInvocationMethod);
         dest.writeString(mResultId);
@@ -392,6 +397,10 @@
         return mEntityType;
     }
 
+    void setEntityType(@EntityType String entityType) {
+        mEntityType = Preconditions.checkNotNull(entityType);
+    }
+
     /**
      * Returns the package name of the app that this event originated in.
      */
@@ -401,6 +410,15 @@
     }
 
     /**
+     * Returns the id of this event's user.
+     * @hide
+     */
+    @UserIdInt
+    public int getUserId() {
+        return mUserId;
+    }
+
+    /**
      * Returns the type of widget that was involved in triggering this event.
      */
     @WidgetType
@@ -426,6 +444,7 @@
         mPackageName = context.getPackageName();
         mWidgetType = context.getWidgetType();
         mWidgetVersion = context.getWidgetVersion();
+        mUserId = context.getUserId();
     }
 
     /**
@@ -612,7 +631,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
-                mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod, mResultId,
+                mWidgetVersion, mPackageName, mUserId, mWidgetType, mInvocationMethod, mResultId,
                 mEventTime, mDurationSinceSessionStart, mDurationSincePreviousEvent,
                 mEventIndex, mSessionId, mStart, mEnd, mSmartStart, mSmartEnd);
     }
@@ -633,6 +652,7 @@
                 && Objects.equals(mEntityType, other.mEntityType)
                 && Objects.equals(mWidgetVersion, other.mWidgetVersion)
                 && Objects.equals(mPackageName, other.mPackageName)
+                && mUserId == other.mUserId
                 && Objects.equals(mWidgetType, other.mWidgetType)
                 && mInvocationMethod == other.mInvocationMethod
                 && Objects.equals(mResultId, other.mResultId)
@@ -652,12 +672,12 @@
         return String.format(Locale.US,
                 "SelectionEvent {absoluteStart=%d, absoluteEnd=%d, eventType=%d, entityType=%s, "
                         + "widgetVersion=%s, packageName=%s, widgetType=%s, invocationMethod=%s, "
-                        + "resultId=%s, eventTime=%d, durationSinceSessionStart=%d, "
+                        + "userId=%d, resultId=%s, eventTime=%d, durationSinceSessionStart=%d, "
                         + "durationSincePreviousEvent=%d, eventIndex=%d,"
                         + "sessionId=%s, start=%d, end=%d, smartStart=%d, smartEnd=%d}",
                 mAbsoluteStart, mAbsoluteEnd, mEventType, mEntityType,
                 mWidgetVersion, mPackageName, mWidgetType, mInvocationMethod,
-                mResultId, mEventTime, mDurationSinceSessionStart,
+                mUserId, mResultId, mEventTime, mDurationSinceSessionStart,
                 mDurationSincePreviousEvent, mEventIndex,
                 mSessionId, mStart, mEnd, mSmartStart, mSmartEnd);
     }
diff --git a/core/java/android/view/textclassifier/SystemTextClassifier.java b/core/java/android/view/textclassifier/SystemTextClassifier.java
index 8f8766e..b5f972a 100644
--- a/core/java/android/view/textclassifier/SystemTextClassifier.java
+++ b/core/java/android/view/textclassifier/SystemTextClassifier.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.annotation.WorkerThread;
 import android.content.Context;
 import android.os.Bundle;
@@ -50,6 +51,10 @@
     private final TextClassificationConstants mSettings;
     private final TextClassifier mFallback;
     private final String mPackageName;
+    // NOTE: Always set this before sending a request to the manager service otherwise the manager
+    // service will throw a remote exception.
+    @UserIdInt
+    private final int mUserId;
     private TextClassificationSessionId mSessionId;
 
     public SystemTextClassifier(Context context, TextClassificationConstants settings)
@@ -60,6 +65,7 @@
         mFallback = context.getSystemService(TextClassificationManager.class)
                 .getTextClassifier(TextClassifier.LOCAL);
         mPackageName = Preconditions.checkNotNull(context.getOpPackageName());
+        mUserId = context.getUserId();
     }
 
     /**
@@ -72,6 +78,7 @@
         Utils.checkMainThread();
         try {
             request.setCallingPackageName(mPackageName);
+            request.setUserId(mUserId);
             final BlockingCallback<TextSelection> callback =
                     new BlockingCallback<>("textselection");
             mManagerService.onSuggestSelection(mSessionId, request, callback);
@@ -95,6 +102,7 @@
         Utils.checkMainThread();
         try {
             request.setCallingPackageName(mPackageName);
+            request.setUserId(mUserId);
             final BlockingCallback<TextClassification> callback =
                     new BlockingCallback<>("textclassification");
             mManagerService.onClassifyText(mSessionId, request, callback);
@@ -123,6 +131,7 @@
 
         try {
             request.setCallingPackageName(mPackageName);
+            request.setUserId(mUserId);
             final BlockingCallback<TextLinks> callback =
                     new BlockingCallback<>("textlinks");
             mManagerService.onGenerateLinks(mSessionId, request, callback);
@@ -167,6 +176,7 @@
 
         try {
             request.setCallingPackageName(mPackageName);
+            request.setUserId(mUserId);
             final BlockingCallback<TextLanguage> callback =
                     new BlockingCallback<>("textlanguage");
             mManagerService.onDetectLanguage(mSessionId, request, callback);
@@ -187,6 +197,7 @@
 
         try {
             request.setCallingPackageName(mPackageName);
+            request.setUserId(mUserId);
             final BlockingCallback<ConversationActions> callback =
                     new BlockingCallback<>("conversation-actions");
             mManagerService.onSuggestConversationActions(mSessionId, request, callback);
@@ -228,6 +239,7 @@
         printWriter.printPair("mFallback", mFallback);
         printWriter.printPair("mPackageName", mPackageName);
         printWriter.printPair("mSessionId", mSessionId);
+        printWriter.printPair("mUserId", mUserId);
         printWriter.decreaseIndent();
         printWriter.println();
     }
@@ -243,6 +255,7 @@
             @NonNull TextClassificationSessionId sessionId) {
         mSessionId = Preconditions.checkNotNull(sessionId);
         try {
+            classificationContext.setUserId(mUserId);
             mManagerService.onCreateTextClassificationSession(classificationContext, mSessionId);
         } catch (RemoteException e) {
             Log.e(LOG_TAG, "Error starting a new classification session.", e);
diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java
index 6321051..93f7103 100644
--- a/core/java/android/view/textclassifier/TextClassification.java
+++ b/core/java/android/view/textclassifier/TextClassification.java
@@ -21,6 +21,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.PendingIntent;
 import android.app.RemoteAction;
 import android.content.Context;
@@ -35,6 +36,7 @@
 import android.os.LocaleList;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.text.SpannedString;
 import android.util.ArrayMap;
 import android.view.View.OnClickListener;
@@ -551,6 +553,8 @@
         @Nullable private final ZonedDateTime mReferenceTime;
         @NonNull private final Bundle mExtras;
         @Nullable private String mCallingPackageName;
+        @UserIdInt
+        private int mUserId = UserHandle.USER_NULL;
 
         private Request(
                 CharSequence text,
@@ -631,6 +635,25 @@
         }
 
         /**
+         * Sets the id of the user that sent this request.
+         * <p>
+         * Package-private for SystemTextClassifier's use.
+         * @hide
+         */
+        void setUserId(@UserIdInt int userId) {
+            mUserId = userId;
+        }
+
+        /**
+         * Returns the id of the user that sent this request.
+         * @hide
+         */
+        @UserIdInt
+        public int getUserId() {
+            return mUserId;
+        }
+
+        /**
          * Returns the extended data.
          *
          * <p><b>NOTE: </b>Do not modify this bundle.
@@ -730,6 +753,7 @@
             dest.writeParcelable(mDefaultLocales, flags);
             dest.writeString(mReferenceTime == null ? null : mReferenceTime.toString());
             dest.writeString(mCallingPackageName);
+            dest.writeInt(mUserId);
             dest.writeBundle(mExtras);
         }
 
@@ -742,11 +766,13 @@
             final ZonedDateTime referenceTime = referenceTimeString == null
                     ? null : ZonedDateTime.parse(referenceTimeString);
             final String callingPackageName = in.readString();
+            final int userId = in.readInt();
             final Bundle extras = in.readBundle();
 
             final Request request = new Request(text, startIndex, endIndex,
                     defaultLocales, referenceTime, extras);
             request.setCallingPackageName(callingPackageName);
+            request.setUserId(userId);
             return request;
         }
 
diff --git a/core/java/android/view/textclassifier/TextClassificationContext.java b/core/java/android/view/textclassifier/TextClassificationContext.java
index 3bf8e9b..e4baaac 100644
--- a/core/java/android/view/textclassifier/TextClassificationContext.java
+++ b/core/java/android/view/textclassifier/TextClassificationContext.java
@@ -18,8 +18,10 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.view.textclassifier.TextClassifier.WidgetType;
 
 import com.android.internal.util.Preconditions;
@@ -35,6 +37,8 @@
     private final String mPackageName;
     private final String mWidgetType;
     @Nullable private final String mWidgetVersion;
+    @UserIdInt
+    private int mUserId = UserHandle.USER_NULL;
 
     private TextClassificationContext(
             String packageName,
@@ -54,6 +58,25 @@
     }
 
     /**
+     * Sets the id of this context's user.
+     * <p>
+     * Package-private for SystemTextClassifier's use.
+     * @hide
+     */
+    void setUserId(@UserIdInt int userId) {
+        mUserId = userId;
+    }
+
+    /**
+     * Returns the id of this context's user.
+     * @hide
+     */
+    @UserIdInt
+    public int getUserId() {
+        return mUserId;
+    }
+
+    /**
      * Returns the widget type for this classification context.
      */
     @NonNull
@@ -75,8 +98,8 @@
     @Override
     public String toString() {
         return String.format(Locale.US, "TextClassificationContext{"
-                + "packageName=%s, widgetType=%s, widgetVersion=%s}",
-                mPackageName, mWidgetType, mWidgetVersion);
+                + "packageName=%s, widgetType=%s, widgetVersion=%s, userId=%d}",
+                mPackageName, mWidgetType, mWidgetVersion, mUserId);
     }
 
     /**
@@ -133,12 +156,14 @@
         parcel.writeString(mPackageName);
         parcel.writeString(mWidgetType);
         parcel.writeString(mWidgetVersion);
+        parcel.writeInt(mUserId);
     }
 
     private TextClassificationContext(Parcel in) {
         mPackageName = in.readString();
         mWidgetType = in.readString();
         mWidgetVersion = in.readString();
+        mUserId = in.readInt();
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<TextClassificationContext> CREATOR =
diff --git a/core/java/android/view/textclassifier/TextClassificationSession.java b/core/java/android/view/textclassifier/TextClassificationSession.java
index db0202a..cd2806a 100644
--- a/core/java/android/view/textclassifier/TextClassificationSession.java
+++ b/core/java/android/view/textclassifier/TextClassificationSession.java
@@ -163,6 +163,11 @@
                 case SelectionEvent.EVENT_AUTO_SELECTION:
                     mSmartEvent = event;
                     break;
+                case SelectionEvent.ACTION_ABANDON:
+                    if (mPrevEvent != null) {
+                        event.setEntityType(mPrevEvent.getEntityType());
+                    }
+                    break;
                 case SelectionEvent.EVENT_SELECTION_MODIFIED:
                     if (mPrevEvent != null
                             && mPrevEvent.getAbsoluteStart() == event.getAbsoluteStart()
diff --git a/core/java/android/view/textclassifier/TextLanguage.java b/core/java/android/view/textclassifier/TextLanguage.java
index 6c75ffb..cc9109e 100644
--- a/core/java/android/view/textclassifier/TextLanguage.java
+++ b/core/java/android/view/textclassifier/TextLanguage.java
@@ -20,10 +20,12 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.icu.util.ULocale;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.util.ArrayMap;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -226,6 +228,8 @@
         private final CharSequence mText;
         private final Bundle mExtra;
         @Nullable private String mCallingPackageName;
+        @UserIdInt
+        private int mUserId = UserHandle.USER_NULL;
 
         private Request(CharSequence text, Bundle bundle) {
             mText = text;
@@ -260,6 +264,25 @@
         }
 
         /**
+         * Sets the id of the user that sent this request.
+         * <p>
+         * Package-private for SystemTextClassifier's use.
+         * @hide
+         */
+        void setUserId(@UserIdInt int userId) {
+            mUserId = userId;
+        }
+
+        /**
+         * Returns the id of the user that sent this request.
+         * @hide
+         */
+        @UserIdInt
+        public int getUserId() {
+            return mUserId;
+        }
+
+        /**
          * Returns a bundle containing non-structured extra information about this request.
          *
          * <p><b>NOTE: </b>Do not modify this bundle.
@@ -278,16 +301,19 @@
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeCharSequence(mText);
             dest.writeString(mCallingPackageName);
+            dest.writeInt(mUserId);
             dest.writeBundle(mExtra);
         }
 
         private static Request readFromParcel(Parcel in) {
             final CharSequence text = in.readCharSequence();
             final String callingPackageName = in.readString();
+            final int userId = in.readInt();
             final Bundle extra = in.readBundle();
 
             final Request request = new Request(text, extra);
             request.setCallingPackageName(callingPackageName);
+            request.setUserId(userId);
             return request;
         }
 
diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java
index f3e0dc1..bbb7f07 100644
--- a/core/java/android/view/textclassifier/TextLinks.java
+++ b/core/java/android/view/textclassifier/TextLinks.java
@@ -20,11 +20,13 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.content.Context;
 import android.os.Bundle;
 import android.os.LocaleList;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.text.Spannable;
 import android.text.method.MovementMethod;
 import android.text.style.ClickableSpan;
@@ -339,6 +341,8 @@
         private final boolean mLegacyFallback;
         @Nullable private String mCallingPackageName;
         private final Bundle mExtras;
+        @UserIdInt
+        private int mUserId = UserHandle.USER_NULL;
 
         private Request(
                 CharSequence text,
@@ -410,6 +414,25 @@
         }
 
         /**
+         * Sets the id of the user that sent this request.
+         * <p>
+         * Package-private for SystemTextClassifier's use.
+         * @hide
+         */
+        void setUserId(@UserIdInt int userId) {
+            mUserId = userId;
+        }
+
+        /**
+         * Returns the id of the user that sent this request.
+         * @hide
+         */
+        @UserIdInt
+        public int getUserId() {
+            return mUserId;
+        }
+
+        /**
          * Returns the extended data.
          *
          * <p><b>NOTE: </b>Do not modify this bundle.
@@ -509,6 +532,7 @@
             dest.writeParcelable(mDefaultLocales, flags);
             dest.writeParcelable(mEntityConfig, flags);
             dest.writeString(mCallingPackageName);
+            dest.writeInt(mUserId);
             dest.writeBundle(mExtras);
         }
 
@@ -517,11 +541,13 @@
             final LocaleList defaultLocales = in.readParcelable(null);
             final EntityConfig entityConfig = in.readParcelable(null);
             final String callingPackageName = in.readString();
+            final int userId = in.readInt();
             final Bundle extras = in.readBundle();
 
             final Request request = new Request(text, defaultLocales, entityConfig,
                     /* legacyFallback= */ true, extras);
             request.setCallingPackageName(callingPackageName);
+            request.setUserId(userId);
             return request;
         }
 
diff --git a/core/java/android/view/textclassifier/TextSelection.java b/core/java/android/view/textclassifier/TextSelection.java
index 75c27bd..0c89749 100644
--- a/core/java/android/view/textclassifier/TextSelection.java
+++ b/core/java/android/view/textclassifier/TextSelection.java
@@ -20,10 +20,12 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.os.Bundle;
 import android.os.LocaleList;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.text.SpannedString;
 import android.util.ArrayMap;
 import android.view.textclassifier.TextClassifier.EntityType;
@@ -211,6 +213,8 @@
         private final boolean mDarkLaunchAllowed;
         private final Bundle mExtras;
         @Nullable private String mCallingPackageName;
+        @UserIdInt
+        private int mUserId = UserHandle.USER_NULL;
 
         private Request(
                 CharSequence text,
@@ -292,6 +296,25 @@
         }
 
         /**
+         * Sets the id of the user that sent this request.
+         * <p>
+         * Package-private for SystemTextClassifier's use.
+         * @hide
+         */
+        void setUserId(@UserIdInt int userId) {
+            mUserId = userId;
+        }
+
+        /**
+         * Returns the id of the user that sent this request.
+         * @hide
+         */
+        @UserIdInt
+        public int getUserId() {
+            return mUserId;
+        }
+
+        /**
          * Returns the extended data.
          *
          * <p><b>NOTE: </b>Do not modify this bundle.
@@ -394,6 +417,7 @@
             dest.writeInt(mEndIndex);
             dest.writeParcelable(mDefaultLocales, flags);
             dest.writeString(mCallingPackageName);
+            dest.writeInt(mUserId);
             dest.writeBundle(mExtras);
         }
 
@@ -403,11 +427,13 @@
             final int endIndex = in.readInt();
             final LocaleList defaultLocales = in.readParcelable(null);
             final String callingPackageName = in.readString();
+            final int userId = in.readInt();
             final Bundle extras = in.readBundle();
 
             final Request request = new Request(text, startIndex, endIndex, defaultLocales,
                     /* darkLaunchAllowed= */ false, extras);
             request.setCallingPackageName(callingPackageName);
+            request.setUserId(userId);
             return request;
         }
 
diff --git a/core/java/android/view/textclassifier/intent/LabeledIntent.java b/core/java/android/view/textclassifier/intent/LabeledIntent.java
index b4bc8d3..30fc20e 100644
--- a/core/java/android/view/textclassifier/intent/LabeledIntent.java
+++ b/core/java/android/view/textclassifier/intent/LabeledIntent.java
@@ -118,14 +118,16 @@
             return null;
         }
         Intent resolvedIntent = new Intent(intent);
-        resolvedIntent.setComponent(new ComponentName(packageName, className));
         resolvedIntent.putExtra(
                 TextClassifier.EXTRA_FROM_TEXT_CLASSIFIER,
                 getFromTextClassifierExtra(textLanguagesBundle));
-
         boolean shouldShowIcon = false;
         Icon icon = null;
         if (!"android".equals(packageName)) {
+            // We only set the component name when the package name is not resolved to "android"
+            // to workaround a bug that explicit intent with component name == ResolverActivity
+            // can't be launched on keyguard.
+            resolvedIntent.setComponent(new ComponentName(packageName, className));
             if (resolveInfo.activityInfo.getIconResource() != 0) {
                 icon = Icon.createWithResource(
                         packageName, resolveInfo.activityInfo.getIconResource());
diff --git a/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java b/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java
index b530ddf..157c435 100644
--- a/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java
+++ b/core/java/android/view/textclassifier/logging/SmartSelectionEventTracker.java
@@ -27,6 +27,7 @@
 import android.view.textclassifier.TextClassifier;
 import android.view.textclassifier.TextSelection;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.Preconditions;
@@ -100,7 +101,7 @@
     private boolean mSmartSelectionTriggered;
     private String mModelName;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(trackingBug = 136637107)
     public SmartSelectionEventTracker(@NonNull Context context, @WidgetType int widgetType) {
         mWidgetType = widgetType;
         mWidgetVersion = null;
@@ -119,7 +120,7 @@
      *
      * @param event the selection event
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(trackingBug = 136637107)
     public void logEvent(@NonNull SelectionEvent event) {
         Preconditions.checkNotNull(event);
 
@@ -443,7 +444,7 @@
          *
          * @param start  the word index of the selected word
          */
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(trackingBug = 136637107)
         public static SelectionEvent selectionStarted(int start) {
             return new SelectionEvent(
                     start, start + 1, EventType.SELECTION_STARTED,
@@ -457,7 +458,7 @@
          * @param start  the start word (inclusive) index of the selection
          * @param end  the end word (exclusive) index of the selection
          */
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(trackingBug = 136637107)
         public static SelectionEvent selectionModified(int start, int end) {
             return new SelectionEvent(
                     start, end, EventType.SELECTION_MODIFIED,
@@ -473,7 +474,7 @@
          * @param classification  the TextClassification object returned by the TextClassifier that
          *      classified the selected text
          */
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(trackingBug = 136637107)
         public static SelectionEvent selectionModified(
                 int start, int end, @NonNull TextClassification classification) {
             final String entityType = classification.getEntityCount() > 0
@@ -493,7 +494,7 @@
          * @param selection  the TextSelection object returned by the TextClassifier for the
          *      specified selection
          */
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(trackingBug = 136637107)
         public static SelectionEvent selectionModified(
                 int start, int end, @NonNull TextSelection selection) {
             final boolean smartSelection = getSourceClassifier(selection.getId())
@@ -522,7 +523,7 @@
          * @param end  the end word (exclusive) index of the selection
          * @param actionType  the action that was performed on the selection
          */
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(trackingBug = 136637107)
         public static SelectionEvent selectionAction(
                 int start, int end, @ActionType int actionType) {
             return new SelectionEvent(
@@ -540,7 +541,7 @@
          * @param classification  the TextClassification object returned by the TextClassifier that
          *      classified the selected text
          */
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(trackingBug = 136637107)
         public static SelectionEvent selectionAction(
                 int start, int end, @ActionType int actionType,
                 @NonNull TextClassification classification) {
@@ -551,10 +552,11 @@
             return new SelectionEvent(start, end, actionType, entityType, versionTag);
         }
 
-        private static String getVersionInfo(String signature) {
-            final int start = signature.indexOf("|");
+        @VisibleForTesting
+        public static String getVersionInfo(String signature) {
+            final int start = signature.indexOf("|") + 1;
             final int end = signature.indexOf("|", start);
-            if (start >= 0 && end >= start) {
+            if (start >= 1 && end >= start) {
                 return signature.substring(start, end);
             }
             return "";
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 26dba45..a35659e 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1606,9 +1606,9 @@
     }
 
     /**
-     * Gets the first substring consisting of the address of a physical
-     * location. Currently, only addresses in the United States are detected,
-     * and consist of:
+     * Gets the first substring which appears to be the address of a physical
+     * location. Only addresses in the United States can be detected, which
+     * must consist of:
      * <ul>
      *   <li>a house number</li>
      *   <li>a street name</li>
@@ -1624,9 +1624,17 @@
      * or abbreviated using USPS standards. The house number may not exceed
      * five digits.
      *
+     * <p class="note"><b>Note:</b> This function is deprecated and should be
+     * avoided on all API levels, as it cannot detect addresses outside of the
+     * United States and has a high rate of false positives. On API level
+     * {@link android.os.Build.VERSION_CODES#O_MR1} and earlier, it also causes
+     * the entire WebView implementation to be loaded and initialized, which
+     * can throw {@link android.util.AndroidRuntimeException} or other exceptions
+     * if the WebView implementation is currently being updated.
+     *
      * @param addr the string to search for addresses
      * @return the address, or if no address is found, {@code null}
-     * @deprecated this method is superseded by {@link TextClassifier#generateLinks(
+     * @deprecated This method is superseded by {@link TextClassifier#generateLinks(
      * android.view.textclassifier.TextLinks.Request)}. Avoid using this method even when targeting
      * API levels where no alternative is available.
      */
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4cb552d..85e9e49 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2553,34 +2553,42 @@
         final boolean isItemEnabled;
         final ViewGroup.LayoutParams lp = view.getLayoutParams();
         if (lp instanceof AbsListView.LayoutParams) {
-            isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled;
+            isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled && isEnabled();
         } else {
             isItemEnabled = false;
         }
 
-        if (!isEnabled() || !isItemEnabled) {
-            info.setEnabled(false);
-            return;
-        }
+        info.setEnabled(isItemEnabled);
 
         if (position == getSelectedItemPosition()) {
             info.setSelected(true);
-            info.addAction(AccessibilityAction.ACTION_CLEAR_SELECTION);
-        } else {
-            info.addAction(AccessibilityAction.ACTION_SELECT);
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_CLEAR_SELECTION);
+        } else  {
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_SELECT);
         }
 
         if (isItemClickable(view)) {
-            info.addAction(AccessibilityAction.ACTION_CLICK);
+            addAccessibilityActionIfEnabled(info, isItemEnabled, AccessibilityAction.ACTION_CLICK);
             info.setClickable(true);
         }
 
         if (isLongClickable()) {
-            info.addAction(AccessibilityAction.ACTION_LONG_CLICK);
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_LONG_CLICK);
             info.setLongClickable(true);
         }
     }
 
+
+    private void addAccessibilityActionIfEnabled(AccessibilityNodeInfo info, boolean enabled,
+            AccessibilityAction action) {
+        if (enabled) {
+            info.addAction(action);
+        }
+    }
+
     private boolean isItemClickable(View view) {
         return !view.hasExplicitFocusable();
     }
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 18c6abb..c3e08fc 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -38,6 +38,11 @@
 import android.view.inspector.InspectableProperty;
 
 import com.android.internal.R;
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 
 /**
@@ -90,6 +95,11 @@
     private float mTouchDownX;
     @UnsupportedAppUsage
     private boolean mIsDragging;
+    private float mTouchThumbOffset = 0.0f;
+
+    private List<Rect> mUserGestureExclusionRects = Collections.emptyList();
+    private final List<Rect> mGestureExclusionRects = new ArrayList<>();
+    private final Rect mThumbRect = new Rect();
 
     public AbsSeekBar(Context context) {
         super(context);
@@ -735,6 +745,27 @@
 
         // Canvas will be translated, so 0,0 is where we start drawing
         thumb.setBounds(left, top, right, bottom);
+        updateGestureExclusionRects();
+    }
+
+    @Override
+    public void setSystemGestureExclusionRects(@NonNull List<Rect> rects) {
+        Preconditions.checkNotNull(rects, "rects must not be null");
+        mUserGestureExclusionRects = rects;
+        updateGestureExclusionRects();
+    }
+
+    private void updateGestureExclusionRects() {
+        final Drawable thumb = mThumb;
+        if (thumb == null) {
+            super.setSystemGestureExclusionRects(mUserGestureExclusionRects);
+            return;
+        }
+        mGestureExclusionRects.clear();
+        thumb.copyBounds(mThumbRect);
+        mGestureExclusionRects.add(mThumbRect);
+        mGestureExclusionRects.addAll(mUserGestureExclusionRects);
+        super.setSystemGestureExclusionRects(mGestureExclusionRects);
     }
 
     /**
@@ -844,6 +875,14 @@
 
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
+                if (mThumb != null) {
+                    final int availableWidth = getWidth() - mPaddingLeft - mPaddingRight;
+                    mTouchThumbOffset = (getProgress() - getMin()) / (float) (getMax()
+                        - getMin()) - (event.getX() - mPaddingLeft) / availableWidth;
+                    if (Math.abs(mTouchThumbOffset * availableWidth) > getThumbOffset()) {
+                        mTouchThumbOffset = 0;
+                    }
+                }
                 if (isInScrollingContainer()) {
                     mTouchDownX = event.getX();
                 } else {
@@ -926,7 +965,8 @@
             } else if (x < mPaddingLeft) {
                 scale = 1.0f;
             } else {
-                scale = (availableWidth - x + mPaddingLeft) / (float) availableWidth;
+                scale = (availableWidth - x + mPaddingLeft) / (float) availableWidth
+                    + mTouchThumbOffset;
                 progress = mTouchProgressOffset;
             }
         } else {
@@ -935,7 +975,7 @@
             } else if (x > width - mPaddingRight) {
                 scale = 1.0f;
             } else {
-                scale = (x - mPaddingLeft) / (float) availableWidth;
+                scale = (x - mPaddingLeft) / (float) availableWidth + mTouchThumbOffset;
                 progress = mTouchProgressOffset;
             }
         }
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 339947a..67a70b4 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -26,12 +26,14 @@
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.text.format.DateUtils;
-import android.text.format.Time;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.RemoteViews.RemoteView;
 
-import java.util.TimeZone;
+import java.time.Clock;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 
 /**
  * This widget display an analogic clock with two hands for hours and
@@ -45,7 +47,7 @@
 @RemoteView
 @Deprecated
 public class AnalogClock extends View {
-    private Time mCalendar;
+    private Clock mClock;
 
     @UnsupportedAppUsage
     private Drawable mHourHand;
@@ -99,7 +101,7 @@
             mMinuteHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
         }
 
-        mCalendar = new Time();
+        mClock = Clock.systemDefaultZone();
 
         mDialWidth = mDial.getIntrinsicWidth();
         mDialHeight = mDial.getIntrinsicHeight();
@@ -132,7 +134,7 @@
         // in the main thread, therefore the receiver can't run before this method returns.
 
         // The time zone may have changed while the receiver wasn't registered, so update the Time
-        mCalendar = new Time();
+        mClock = Clock.systemDefaultZone();
 
         // Make sure we update to the current time
         onTimeChanged();
@@ -241,17 +243,18 @@
     }
 
     private void onTimeChanged() {
-        mCalendar.setToNow();
+        long nowMillis = mClock.millis();
+        LocalDateTime localDateTime = toLocalDateTime(nowMillis, mClock.getZone());
 
-        int hour = mCalendar.hour;
-        int minute = mCalendar.minute;
-        int second = mCalendar.second;
+        int hour = localDateTime.getHour();
+        int minute = localDateTime.getMinute();
+        int second = localDateTime.getSecond();
 
         mMinutes = minute + second / 60.0f;
         mHour = hour + mMinutes / 60.0f;
         mChanged = true;
 
-        updateContentDescription(mCalendar);
+        updateContentDescription(nowMillis);
     }
 
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -259,7 +262,7 @@
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
                 String tz = intent.getStringExtra("time-zone");
-                mCalendar = new Time(TimeZone.getTimeZone(tz).getID());
+                mClock = Clock.system(ZoneId.of(tz));
             }
 
             onTimeChanged();
@@ -268,10 +271,17 @@
         }
     };
 
-    private void updateContentDescription(Time time) {
+    private void updateContentDescription(long timeMillis) {
         final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
-        String contentDescription = DateUtils.formatDateTime(mContext,
-                time.toMillis(false), flags);
+        String contentDescription = DateUtils.formatDateTime(mContext, timeMillis, flags);
         setContentDescription(contentDescription);
     }
+
+    private static LocalDateTime toLocalDateTime(long timeMillis, ZoneId zoneId) {
+        // java.time types like LocalDateTime / Instant can support the full range of "long millis"
+        // with room to spare so we do not need to worry about overflow / underflow and the
+        // resulting exceptions while the input to this class is a long.
+        Instant instant = Instant.ofEpochMilli(timeMillis);
+        return LocalDateTime.ofInstant(instant, zoneId);
+    }
 }
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index c3c2c0d..2bf1ba5 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -50,7 +50,7 @@
  * override {@link #getView(int, View, ViewGroup)}
  * and inflate a view resource.
  * For a code example, see
- * the <a href="https://developer.android.com/samples/CustomChoiceList/index.html">
+ * the <a href="https://github.com/googlesamples/android-CustomChoiceList/#readme">
  * CustomChoiceList</a> sample.
  * </p>
  * <p>
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index 0469dbd..2864ad0 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -20,7 +20,6 @@
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 import static android.text.format.DateUtils.YEAR_IN_MILLIS;
-import static android.text.format.Time.getJulianDay;
 
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
@@ -32,7 +31,6 @@
 import android.content.res.TypedArray;
 import android.database.ContentObserver;
 import android.os.Handler;
-import android.text.format.Time;
 import android.util.AttributeSet;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.inspector.InspectableProperty;
@@ -41,10 +39,14 @@
 import com.android.internal.R;
 
 import java.text.DateFormat;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.temporal.JulianFields;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Date;
-import java.util.TimeZone;
 
 //
 // TODO
@@ -63,8 +65,9 @@
     private static final int SHOW_TIME = 0;
     private static final int SHOW_MONTH_DAY_YEAR = 1;
 
-    Date mTime;
-    long mTimeMillis;
+    private long mTimeMillis;
+    // The LocalDateTime equivalent of mTimeMillis but truncated to minute, i.e. no seconds / nanos.
+    private LocalDateTime mLocalTime;
 
     int mLastDisplay = -1;
     DateFormat mLastFormat;
@@ -128,11 +131,10 @@
 
     @android.view.RemotableViewMethod
     @UnsupportedAppUsage
-    public void setTime(long time) {
-        Time t = new Time();
-        t.set(time);
-        mTimeMillis = t.toMillis(false);
-        mTime = new Date(t.year-1900, t.month, t.monthDay, t.hour, t.minute, 0);
+    public void setTime(long timeMillis) {
+        mTimeMillis = timeMillis;
+        LocalDateTime dateTime = toLocalDateTime(timeMillis, ZoneId.systemDefault());
+        mLocalTime = dateTime.withSecond(0);
         update();
     }
 
@@ -165,7 +167,7 @@
 
     @UnsupportedAppUsage
     void update() {
-        if (mTime == null || getVisibility() == GONE) {
+        if (mLocalTime == null || getVisibility() == GONE) {
             return;
         }
         if (mShowRelativeTime) {
@@ -174,31 +176,27 @@
         }
 
         int display;
-        Date time = mTime;
+        ZoneId zoneId = ZoneId.systemDefault();
 
-        Time t = new Time();
-        t.set(mTimeMillis);
-        t.second = 0;
+        // localTime is the local time for mTimeMillis but at zero seconds past the minute.
+        LocalDateTime localTime = mLocalTime;
+        LocalDateTime localStartOfDay =
+                LocalDateTime.of(localTime.toLocalDate(), LocalTime.MIDNIGHT);
+        LocalDateTime localTomorrowStartOfDay = localStartOfDay.plusDays(1);
+        // now is current local time but at zero seconds past the minute.
+        LocalDateTime localNow = LocalDateTime.now(zoneId).withSecond(0);
 
-        t.hour -= 12;
-        long twelveHoursBefore = t.toMillis(false);
-        t.hour += 12;
-        long twelveHoursAfter = t.toMillis(false);
-        t.hour = 0;
-        t.minute = 0;
-        long midnightBefore = t.toMillis(false);
-        t.monthDay++;
-        long midnightAfter = t.toMillis(false);
-
-        long nowMillis = System.currentTimeMillis();
-        t.set(nowMillis);
-        t.second = 0;
-        nowMillis = t.normalize(false);
+        long twelveHoursBefore = toEpochMillis(localTime.minusHours(12), zoneId);
+        long twelveHoursAfter = toEpochMillis(localTime.plusHours(12), zoneId);
+        long midnightBefore = toEpochMillis(localStartOfDay, zoneId);
+        long midnightAfter = toEpochMillis(localTomorrowStartOfDay, zoneId);
+        long time = toEpochMillis(localTime, zoneId);
+        long now = toEpochMillis(localNow, zoneId);
 
         // Choose the display mode
         choose_display: {
-            if ((nowMillis >= midnightBefore && nowMillis < midnightAfter)
-                    || (nowMillis >= twelveHoursBefore && nowMillis < twelveHoursAfter)) {
+            if ((now >= midnightBefore && now < midnightAfter)
+                    || (now >= twelveHoursBefore && now < twelveHoursAfter)) {
                 display = SHOW_TIME;
                 break choose_display;
             }
@@ -227,7 +225,7 @@
         }
 
         // Set the text
-        String text = format.format(mTime);
+        String text = format.format(new Date(time));
         setText(text);
 
         // Schedule the next update
@@ -236,7 +234,7 @@
             mUpdateTimeMillis = twelveHoursAfter > midnightAfter ? twelveHoursAfter : midnightAfter;
         } else {
             // Currently showing the date
-            if (mTimeMillis < nowMillis) {
+            if (mTimeMillis < now) {
                 // If the time is in the past, don't schedule an update
                 mUpdateTimeMillis = 0;
             } else {
@@ -277,15 +275,18 @@
             millisIncrease = HOUR_IN_MILLIS;
         } else if (duration < YEAR_IN_MILLIS) {
             // In weird cases it can become 0 because of daylight savings
-            TimeZone timeZone = TimeZone.getDefault();
-            count = Math.max(Math.abs(dayDistance(timeZone, mTimeMillis, now)), 1);
+            LocalDateTime localDateTime = mLocalTime;
+            ZoneId zoneId = ZoneId.systemDefault();
+            LocalDateTime localNow = toLocalDateTime(now, zoneId);
+
+            count = Math.max(Math.abs(dayDistance(localDateTime, localNow)), 1);
             result = String.format(getContext().getResources().getQuantityString(past
                             ? com.android.internal.R.plurals.duration_days_shortest
                             : com.android.internal.R.plurals.duration_days_shortest_future,
                             count),
                     count);
             if (past || count != 1) {
-                mUpdateTimeMillis = computeNextMidnight(timeZone);
+                mUpdateTimeMillis = computeNextMidnight(localNow, zoneId);
                 millisIncrease = -1;
             } else {
                 millisIncrease = DAY_IN_MILLIS;
@@ -311,18 +312,13 @@
     }
 
     /**
-     * @param timeZone the timezone we are in
-     * @return the timepoint in millis at UTC at midnight in the current timezone
+     * Returns the epoch millis for the next midnight in the specified timezone.
      */
-    private long computeNextMidnight(TimeZone timeZone) {
-        Calendar c = Calendar.getInstance();
-        c.setTimeZone(timeZone);
-        c.add(Calendar.DAY_OF_MONTH, 1);
-        c.set(Calendar.HOUR_OF_DAY, 0);
-        c.set(Calendar.MINUTE, 0);
-        c.set(Calendar.SECOND, 0);
-        c.set(Calendar.MILLISECOND, 0);
-        return c.getTimeInMillis();
+    private static long computeNextMidnight(LocalDateTime time, ZoneId zoneId) {
+        // This ignores the chance of overflow: it should never happen.
+        LocalDate tomorrow = time.toLocalDate().plusDays(1);
+        LocalDateTime nextMidnight = LocalDateTime.of(tomorrow, LocalTime.MIDNIGHT);
+        return toEpochMillis(nextMidnight, zoneId);
     }
 
     @Override
@@ -340,11 +336,10 @@
                 com.android.internal.R.string.now_string_shortest);
     }
 
-    // Return the date difference for the two times in a given timezone.
-    private static int dayDistance(TimeZone timeZone, long startTime,
-            long endTime) {
-        return getJulianDay(endTime, timeZone.getOffset(endTime) / 1000)
-                - getJulianDay(startTime, timeZone.getOffset(startTime) / 1000);
+    // Return the number of days between the two dates.
+    private static int dayDistance(LocalDateTime start, LocalDateTime end) {
+        return (int) (end.getLong(JulianFields.JULIAN_DAY)
+                - start.getLong(JulianFields.JULIAN_DAY));
     }
 
     private DateFormat getTimeFormat() {
@@ -389,8 +384,11 @@
                         count);
             } else if (duration < YEAR_IN_MILLIS) {
                 // In weird cases it can become 0 because of daylight savings
-                TimeZone timeZone = TimeZone.getDefault();
-                count = Math.max(Math.abs(dayDistance(timeZone, mTimeMillis, now)), 1);
+                LocalDateTime localDateTime = mLocalTime;
+                ZoneId zoneId = ZoneId.systemDefault();
+                LocalDateTime localNow = toLocalDateTime(now, zoneId);
+
+                count = Math.max(Math.abs(dayDistance(localDateTime, localNow)), 1);
                 result = String.format(getContext().getResources().getQuantityString(past
                                 ? com.android.internal.
                                         R.plurals.duration_days_relative
@@ -526,4 +524,17 @@
             }
         }
     }
+
+    private static LocalDateTime toLocalDateTime(long timeMillis, ZoneId zoneId) {
+        // java.time types like LocalDateTime / Instant can support the full range of "long millis"
+        // with room to spare so we do not need to worry about overflow / underflow and the rsulting
+        // exceptions while the input to this class is a long.
+        Instant instant = Instant.ofEpochMilli(timeMillis);
+        return LocalDateTime.ofInstant(instant, zoneId);
+    }
+
+    private static long toEpochMillis(LocalDateTime time, ZoneId zoneId) {
+        Instant instant = time.toInstant(zoneId.getRules().getOffset(time));
+        return instant.toEpochMilli();
+    }
 }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index c9ef038..cac75cfd 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -134,6 +134,7 @@
 import java.text.BreakIterator;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
@@ -5097,6 +5098,12 @@
         void onHandleMoved() {}
 
         public void onDetached() {}
+
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            super.onSizeChanged(w, h, oldw, oldh);
+            setSystemGestureExclusionRects(Collections.singletonList(new Rect(0, 0, w, h)));
+        }
     }
 
     private class InsertionHandleView extends HandleView {
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 5921feb..ec685f5 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -951,8 +951,6 @@
     public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
         super.onInitializeAccessibilityEventInternal(event);
         event.setScrollable(getScrollRange() > 0);
-        event.setScrollX(mScrollX);
-        event.setScrollY(mScrollY);
         event.setMaxScrollX(getScrollRange());
         event.setMaxScrollY(mScrollY);
     }
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 1719015..d3c6972 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -277,7 +277,7 @@
                             mWindowElevation, mWindowCornerRadius,
                             mOverlay != null ? mOverlay : new ColorDrawable(Color.TRANSPARENT),
                             Handler.getMain() /* draw the magnifier on the UI thread */, mLock,
-                            mDestroyLock, mCallback);
+                            mCallback);
                 }
             }
             performPixelCopy(startX, startY, true /* update window position */);
@@ -306,11 +306,9 @@
      */
     public void dismiss() {
         if (mWindow != null) {
-            synchronized (mDestroyLock) {
-                synchronized (mLock) {
-                    mWindow.destroy();
-                    mWindow = null;
-                }
+            synchronized (mLock) {
+                mWindow.destroy();
+                mWindow = null;
             }
             mPrevShowSourceCoords.x = NONEXISTENT_PREVIOUS_CONFIG_VALUE;
             mPrevShowSourceCoords.y = NONEXISTENT_PREVIOUS_CONFIG_VALUE;
@@ -835,24 +833,16 @@
         private int mWindowPositionY;
         private boolean mPendingWindowPositionUpdate;
 
-        // The lock used to synchronize the UI and render threads when a #destroy
-        // is performed on the UI thread and a frame callback on the render thread.
-        // When both mLock and mDestroyLock need to be held at the same time,
-        // mDestroyLock should be acquired before mLock in order to avoid deadlocks.
-        private final Object mDestroyLock;
-
         // The current content of the magnifier. It is mBitmap + mOverlay, only used for testing.
         private Bitmap mCurrentContent;
 
         InternalPopupWindow(final Context context, final Display display,
                 final SurfaceControl parentSurfaceControl, final int width, final int height,
                 final float elevation, final float cornerRadius, final Drawable overlay,
-                final Handler handler, final Object lock, final Object destroyLock,
-                final Callback callback) {
+                final Handler handler, final Object lock, final Callback callback) {
             mDisplay = display;
             mOverlay = overlay;
             mLock = lock;
-            mDestroyLock = destroyLock;
             mCallback = callback;
 
             mContentWidth = width;
@@ -1039,20 +1029,17 @@
         }
 
         /**
-         * Destroys this instance.
+         * Destroys this instance. The method has to be called in a context holding {@link #mLock}.
          */
         public void destroy() {
-            synchronized (mDestroyLock) {
-                mSurface.destroy();
-            }
-            synchronized (mLock) {
-                mRenderer.destroy();
-                mSurfaceControl.remove();
-                mSurfaceSession.kill();
-                mHandler.removeCallbacks(mMagnifierUpdater);
-                if (mBitmap != null) {
-                    mBitmap.recycle();
-                }
+            // Destroy the renderer. This will not proceed until pending frame callbacks complete.
+            mRenderer.destroy();
+            mSurface.destroy();
+            new SurfaceControl.Transaction().remove(mSurfaceControl).apply();
+            mSurfaceSession.kill();
+            mHandler.removeCallbacks(mMagnifierUpdater);
+            if (mBitmap != null) {
+                mBitmap.recycle();
             }
         }
 
@@ -1090,24 +1077,20 @@
                     final int pendingY = mWindowPositionY;
 
                     callback = frame -> {
-                        synchronized (mDestroyLock) {
-                            if (!mSurface.isValid()) {
-                                return;
-                            }
-                            synchronized (mLock) {
-                                // Show or move the window at the content draw frame.
-                                SurfaceControl.openTransaction();
-                                mSurfaceControl.deferTransactionUntil(mSurface, frame);
-                                if (updateWindowPosition) {
-                                    mSurfaceControl.setPosition(pendingX, pendingY);
-                                }
-                                if (firstDraw) {
-                                    mSurfaceControl.setLayer(SURFACE_Z);
-                                    mSurfaceControl.show();
-                                }
-                                SurfaceControl.closeTransaction();
-                            }
+                        if (!mSurface.isValid()) {
+                            return;
                         }
+                        // Show or move the window at the content draw frame.
+                        SurfaceControl.openTransaction();
+                        mSurfaceControl.deferTransactionUntil(mSurface, frame);
+                        if (updateWindowPosition) {
+                            mSurfaceControl.setPosition(pendingX, pendingY);
+                        }
+                        if (firstDraw) {
+                            mSurfaceControl.setLayer(SURFACE_Z);
+                            mSurfaceControl.show();
+                        }
+                        SurfaceControl.closeTransaction();
                     };
                     mRenderer.setLightCenter(mDisplay, pendingX, pendingY);
                 } else {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 564d972..86cec5e 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -206,13 +206,13 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public ApplicationInfo mApplication;
 
     /**
      * The resource ID of the layout file. (Added to the parcel)
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     private final int mLayoutId;
 
     /**
@@ -224,13 +224,13 @@
      * An array of actions to perform on the view tree once it has been
      * inflated
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     private ArrayList<Action> mActions;
 
     /**
      * Maps bitmaps to unique indicies to avoid Bitmap duplication.
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     private BitmapCache mBitmapCache;
 
     /**
@@ -252,7 +252,7 @@
      * RemoteViews.
      */
     private RemoteViews mLandscape = null;
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     private RemoteViews mPortrait = null;
 
     @ApplyFlags
@@ -430,7 +430,7 @@
             // Do nothing
         }
 
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         public int mergeBehavior() {
             return MERGE_REPLACE;
         }
@@ -466,7 +466,7 @@
             // Nothing to visit by default
         }
 
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         int viewId;
     }
 
@@ -499,7 +499,7 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public void mergeRemoteViews(RemoteViews newRv) {
         if (newRv == null) return;
         // We first copy the new RemoteViews, as the process of merging modifies the way the actions
@@ -690,7 +690,7 @@
             return SET_PENDING_INTENT_TEMPLATE_TAG;
         }
 
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         PendingIntent pendingIntentTemplate;
     }
 
@@ -1138,7 +1138,7 @@
 
     private static class BitmapCache {
 
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         ArrayList<Bitmap> mBitmaps;
         int mBitmapMemory = -1;
 
@@ -1190,9 +1190,9 @@
 
     private class BitmapReflectionAction extends Action {
         int bitmapId;
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         Bitmap bitmap;
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         String methodName;
 
         BitmapReflectionAction(int viewId, String methodName, Bitmap bitmap) {
@@ -1258,10 +1258,10 @@
         static final int COLOR_STATE_LIST = 15;
         static final int ICON = 16;
 
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         String methodName;
         int type;
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         Object value;
 
         ReflectionAction(int viewId, String methodName, int type, Object value) {
@@ -1554,7 +1554,7 @@
      * ViewGroup methods that are related to adding Views.
      */
     private class ViewGroupActionAdd extends Action {
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+        @UnsupportedAppUsage
         private RemoteViews mNestedViews;
         private int mIndex;
 
@@ -2469,7 +2469,7 @@
      * Returns an estimate of the bitmap heap memory usage for this RemoteViews.
      */
     /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public int estimateMemoryUsage() {
         return mBitmapCache.getBitmapMemory();
     }
@@ -2517,7 +2517,7 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public void addView(int viewId, RemoteViews nestedView, int index) {
         addAction(new ViewGroupActionAdd(viewId, nestedView, index));
     }
@@ -2994,7 +2994,8 @@
      * @hide
      * @deprecated this appears to have no users outside of UnsupportedAppUsage?
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
+    @Deprecated
     public void setRemoteAdapter(int viewId, ArrayList<RemoteViews> list, int viewTypeCount) {
         addAction(new SetRemoteViewsAdapterList(viewId, list, viewTypeCount));
     }
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 365638f..efc5eb3 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -28,7 +28,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -555,6 +557,12 @@
     }
 
     /**
+     * Config diff flags for which the cache should be reset
+     */
+    private static final int CACHE_RESET_CONFIG_FLAGS = ActivityInfo.CONFIG_FONT_SCALE
+            | ActivityInfo.CONFIG_UI_MODE | ActivityInfo.CONFIG_DENSITY
+            | ActivityInfo.CONFIG_ASSETS_PATHS;
+    /**
      *
      */
     private static class FixedSizeRemoteViewsCache {
@@ -587,7 +595,6 @@
         // farthest items from when we hit the memory limit
         private int mLastRequestedIndex;
 
-
         // The lower and upper bounds of the preloaded range
         private int mPreloadLowerBound;
         private int mPreloadUpperBound;
@@ -602,12 +609,17 @@
         private static final float sMaxCountSlackPercent = 0.75f;
         private static final int sMaxMemoryLimitInBytes = 2 * 1024 * 1024;
 
-        public FixedSizeRemoteViewsCache(int maxCacheSize) {
+        // Configuration for which the cache was created
+        private final Configuration mConfiguration;
+
+        FixedSizeRemoteViewsCache(int maxCacheSize, Configuration configuration) {
             mMaxCount = maxCacheSize;
             mMaxCountSlack = Math.round(sMaxCountSlackPercent * (mMaxCount / 2));
             mPreloadLowerBound = 0;
             mPreloadUpperBound = -1;
             mLastRequestedIndex = -1;
+
+            mConfiguration = new Configuration(configuration);
         }
 
         public void insert(int position, RemoteViews v, long itemId, int[] visibleWindow) {
@@ -852,7 +864,12 @@
                 mAppWidgetId);
 
         synchronized(sCachedRemoteViewsCaches) {
-            if (sCachedRemoteViewsCaches.containsKey(key)) {
+            FixedSizeRemoteViewsCache cache = sCachedRemoteViewsCaches.get(key);
+            Configuration config = context.getResources().getConfiguration();
+            if (cache == null
+                    || (cache.mConfiguration.diff(config) & CACHE_RESET_CONFIG_FLAGS) != 0) {
+                mCache = new FixedSizeRemoteViewsCache(DEFAULT_CACHE_SIZE, config);
+            } else {
                 mCache = sCachedRemoteViewsCaches.get(key);
                 synchronized (mCache.mMetaData) {
                     if (mCache.mMetaData.count > 0) {
@@ -861,8 +878,6 @@
                         mDataReady = true;
                     }
                 }
-            } else {
-                mCache = new FixedSizeRemoteViewsCache(DEFAULT_CACHE_SIZE);
             }
             if (!mDataReady) {
                 requestBindService();
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index a3e89c8..eb93fdf 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1010,8 +1010,6 @@
         super.onInitializeAccessibilityEventInternal(event);
         final boolean scrollable = getScrollRange() > 0;
         event.setScrollable(scrollable);
-        event.setScrollX(mScrollX);
-        event.setScrollY(mScrollY);
         event.setMaxScrollX(mScrollX);
         event.setMaxScrollY(getScrollRange());
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 956f694..a4844ea 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1016,6 +1016,8 @@
          */
         TypedArray a = theme.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.TextViewAppearance, defStyleAttr, defStyleRes);
+        saveAttributeDataForStyleable(context, com.android.internal.R.styleable.TextViewAppearance,
+                attrs, a, defStyleAttr, defStyleRes);
         TypedArray appearance = null;
         int ap = a.getResourceId(
                 com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);
@@ -1023,6 +1025,8 @@
         if (ap != -1) {
             appearance = theme.obtainStyledAttributes(
                     ap, com.android.internal.R.styleable.TextAppearance);
+            saveAttributeDataForStyleable(context, com.android.internal.R.styleable.TextAppearance,
+                    null, appearance, 0, ap);
         }
         if (appearance != null) {
             readTextAppearance(context, appearance, attributes, false /* styleArray */);
@@ -4965,6 +4969,10 @@
      * android.text.util.Linkify#ALL Linkify.ALL} and peers for
      * possible values.
      *
+     * <p class="note"><b>Note:</b>
+     * {@link android.text.util.Linkify#MAP_ADDRESSES Linkify.MAP_ADDRESSES}
+     * is deprecated and should be avoided; see its documentation.
+     *
      * @attr ref android.R.styleable#TextView_autoLink
      */
     @android.view.RemotableViewMethod
@@ -10578,7 +10586,7 @@
         // notifyAppeared was not sent.
 
         // ContentCapture
-        if (isLaidOut() && isImportantForContentCapture()) {
+        if (isLaidOut() && isImportantForContentCapture() && getNotifiedContentCaptureAppeared()) {
             final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class);
             if (cm != null && cm.isContentCaptureEnabled()) {
                 final ContentCaptureSession session = getContentCaptureSession();
@@ -11275,6 +11283,12 @@
     }
 
     @Nullable
+    final TextClassificationManager getTextClassificationManagerForUser() {
+        return getServiceManagerForUser(
+                getContext().getPackageName(), TextClassificationManager.class);
+    }
+
+    @Nullable
     final <T> T getServiceManagerForUser(String packageName, Class<T> managerClazz) {
         if (mTextOperationUser == null) {
             return getContext().getSystemService(managerClazz);
@@ -12389,8 +12403,7 @@
     @NonNull
     public TextClassifier getTextClassifier() {
         if (mTextClassifier == null) {
-            final TextClassificationManager tcm =
-                    mContext.getSystemService(TextClassificationManager.class);
+            final TextClassificationManager tcm = getTextClassificationManagerForUser();
             if (tcm != null) {
                 return tcm.getTextClassifier();
             }
@@ -12406,8 +12419,7 @@
     @NonNull
     TextClassifier getTextClassificationSession() {
         if (mTextClassificationSession == null || mTextClassificationSession.isDestroyed()) {
-            final TextClassificationManager tcm =
-                    mContext.getSystemService(TextClassificationManager.class);
+            final TextClassificationManager tcm = getTextClassificationManagerForUser();
             if (tcm != null) {
                 final String widgetType;
                 if (isTextEditable()) {
diff --git a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
index b9ed963..7af45fc 100644
--- a/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
+++ b/core/java/com/android/internal/app/AccessibilityButtonChooserActivity.java
@@ -15,6 +15,8 @@
  */
 package com.android.internal.app;
 
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -64,8 +66,21 @@
 
         String component = Settings.Secure.getString(getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT);
+
+        if (isGestureNavigateEnabled()) {
+            TextView promptPrologue = findViewById(R.id.accessibility_button_prompt_prologue);
+            promptPrologue.setText(isTouchExploreOn()
+                    ? R.string.accessibility_gesture_3finger_prompt_text
+                    : R.string.accessibility_gesture_prompt_text);
+        }
+
         if (TextUtils.isEmpty(component)) {
             TextView prompt = findViewById(R.id.accessibility_button_prompt);
+            if (isGestureNavigateEnabled()) {
+                prompt.setText(isTouchExploreOn()
+                        ? R.string.accessibility_gesture_3finger_instructional_text
+                        : R.string.accessibility_gesture_instructional_text);
+            }
             prompt.setVisibility(View.VISIBLE);
         }
 
@@ -91,6 +106,16 @@
         });
     }
 
+    private boolean isGestureNavigateEnabled() {
+        return NAV_BAR_MODE_GESTURAL == getResources().getInteger(
+                com.android.internal.R.integer.config_navBarInteractionMode);
+    }
+
+    private boolean isTouchExploreOn() {
+        return ((AccessibilityManager) getSystemService(Context.ACCESSIBILITY_SERVICE))
+                .isTouchExplorationEnabled();
+    }
+
     private static List<AccessibilityButtonTarget> getServiceAccessibilityButtonTargets(
             @NonNull Context context) {
         AccessibilityManager ams = (AccessibilityManager) context.getSystemService(
@@ -177,4 +202,4 @@
             return mDrawable;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 3462e08..0fd05c1 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -559,6 +559,13 @@
         final boolean hasButtonPanel = buttonPanel != null
                 && buttonPanel.getVisibility() != View.GONE;
 
+        if (!parentPanel.isInTouchMode()) {
+            final View content = hasCustomPanel ? customPanel : contentPanel;
+            if (!requestFocusForContent(content)) {
+                requestFocusForDefaultButton();
+            }
+        }
+
         // Only display the text spacer if we don't have buttons.
         if (!hasButtonPanel) {
             if (contentPanel != null) {
@@ -624,6 +631,29 @@
         a.recycle();
     }
 
+    private boolean requestFocusForContent(View content) {
+        if (content != null && content.requestFocus()) {
+            return true;
+        }
+
+        if (mListView != null) {
+            mListView.setSelection(0);
+            return true;
+        }
+
+        return false;
+    }
+
+    private void requestFocusForDefaultButton() {
+        if (mButtonPositive.getVisibility() == View.VISIBLE) {
+            mButtonPositive.requestFocus();
+        } else if (mButtonNegative.getVisibility() == View.VISIBLE) {
+            mButtonNegative.requestFocus();
+        } else if (mButtonNeutral.getVisibility() == View.VISIBLE) {
+            mButtonNeutral.requestFocus();
+        }
+    }
+
     private void setupCustomContent(ViewGroup customPanel) {
         final View customView;
         if (mView != null) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ee99837..00206fc 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -110,6 +110,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.content.PackageMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.ImageUtils;
@@ -125,8 +126,10 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * The Chooser Activity handles intent resolution specifically for sharing intents -
@@ -185,7 +188,6 @@
     private static final int SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
 
     private static final int QUERY_TARGET_SERVICE_LIMIT = 5;
-    private static final int WATCHDOG_TIMEOUT_MILLIS = 5000;
 
     private static final int DEFAULT_SALT_EXPIRATION_DAYS = 7;
     private int mMaxHashSaltDays = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -211,6 +213,8 @@
     private ChooserRowAdapter mChooserRowAdapter;
     private int mChooserRowServiceSpacing;
 
+    private int mCurrAvailableWidth = 0;
+
     /** {@link ChooserActivity#getBaseScore} */
     private static final float CALLER_TARGET_SCORE_BOOST = 900.f;
     /** {@link ChooserActivity#getBaseScore} */
@@ -220,12 +224,7 @@
     private static final int MAX_RANKED_TARGETS = 4;
 
     private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
-
-    private static final int CHOOSER_TARGET_SERVICE_RESULT = 1;
-    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 final Set<ComponentName> mServicesRequested = new HashSet<>();
 
     private static final int MAX_LOG_RANK_POSITION = 12;
 
@@ -255,11 +254,13 @@
     private ContentPreviewCoordinator mPreviewCoord;
 
     private class ContentPreviewCoordinator {
-        private static final int IMAGE_LOAD_TIMEOUT_MILLIS = 300;
         private static final int IMAGE_FADE_IN_MILLIS = 150;
         private static final int IMAGE_LOAD_TIMEOUT = 1;
         private static final int IMAGE_LOAD_INTO_VIEW = 2;
 
+        private final int mImageLoadTimeoutMillis =
+                getResources().getInteger(R.integer.config_shortAnimTime);
+
         private final View mParentView;
         private boolean mHideParentOnFail;
         private boolean mAtLeastOneLoaded = false;
@@ -328,7 +329,7 @@
 
         private void loadUriIntoView(final int imageResourceId, final Uri uri,
                 final int extraImages) {
-            mHandler.sendEmptyMessageDelayed(IMAGE_LOAD_TIMEOUT, IMAGE_LOAD_TIMEOUT_MILLIS);
+            mHandler.sendEmptyMessageDelayed(IMAGE_LOAD_TIMEOUT, mImageLoadTimeoutMillis);
 
             AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
                 final Bitmap bmp = loadThumbnail(uri, new Size(200, 200));
@@ -347,7 +348,7 @@
         private void maybeHideContentPreview() {
             if (!mAtLeastOneLoaded && mHideParentOnFail) {
                 Log.i(TAG, "Hiding image preview area. Timed out waiting for preview to load"
-                        + " within " + IMAGE_LOAD_TIMEOUT_MILLIS + "ms.");
+                        + " within " + mImageLoadTimeoutMillis + "ms.");
                 collapseParentView();
                 if (mChooserRowAdapter != null) {
                     mChooserRowAdapter.hideContentPreview();
@@ -369,7 +370,59 @@
         }
     }
 
-    private final Handler mChooserHandler = new Handler() {
+    private final ChooserHandler mChooserHandler = new ChooserHandler();
+
+    private class ChooserHandler extends Handler {
+        private static final int CHOOSER_TARGET_SERVICE_RESULT = 1;
+        private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT = 2;
+        private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT = 3;
+        private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT = 4;
+        private static final int SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED = 5;
+        private static final int LIST_VIEW_UPDATE_MESSAGE = 6;
+
+        private static final int WATCHDOG_TIMEOUT_MAX_MILLIS = 10000;
+        private static final int WATCHDOG_TIMEOUT_MIN_MILLIS = 3000;
+
+        private boolean mMinTimeoutPassed = false;
+
+        private void removeAllMessages() {
+            removeMessages(LIST_VIEW_UPDATE_MESSAGE);
+            removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT);
+            removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT);
+            removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
+            removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT);
+            removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED);
+        }
+
+        private void restartServiceRequestTimer() {
+            mMinTimeoutPassed = false;
+            removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT);
+            removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT);
+
+            if (DEBUG) {
+                Log.d(TAG, "queryTargets setting watchdog timer for "
+                        + WATCHDOG_TIMEOUT_MIN_MILLIS + "-"
+                        + WATCHDOG_TIMEOUT_MAX_MILLIS + "ms");
+            }
+
+            sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT,
+                    WATCHDOG_TIMEOUT_MIN_MILLIS);
+            sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT,
+                    WATCHDOG_TIMEOUT_MAX_MILLIS);
+        }
+
+        private void maybeStopServiceRequestTimer() {
+            // Set a minimum timeout threshold, to ensure both apis, sharing shortcuts
+            // and older-style direct share services, have had time to load, otherwise
+            // just checking mServiceConnections could force us to end prematurely
+            if (mMinTimeoutPassed && mServiceConnections.isEmpty()) {
+                logDirectShareTargetReceived(
+                        MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_CHOOSER_SERVICE);
+                sendVoiceChoicesIfNeeded();
+                mChooserListAdapter.completeServiceTargetLoading();
+            }
+        }
+
         @Override
         public void handleMessage(Message msg) {
             if (mChooserListAdapter == null || isDestroyed()) {
@@ -393,23 +446,17 @@
                     unbindService(sri.connection);
                     sri.connection.destroy();
                     mServiceConnections.remove(sri.connection);
-                    if (mServiceConnections.isEmpty()) {
-                        logDirectShareTargetReceived(
-                                MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_CHOOSER_SERVICE);
-                        sendVoiceChoicesIfNeeded();
-                    }
+                    maybeStopServiceRequestTimer();
                     break;
 
-                case CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT:
-                    if (DEBUG) {
-                        Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
-                    }
+                case CHOOSER_TARGET_SERVICE_WATCHDOG_MIN_TIMEOUT:
+                    mMinTimeoutPassed = true;
+                    maybeStopServiceRequestTimer();
+                    break;
 
+                case CHOOSER_TARGET_SERVICE_WATCHDOG_MAX_TIMEOUT:
                     unbindRemainingServices();
-                    logDirectShareTargetReceived(
-                            MetricsEvent.ACTION_DIRECT_SHARE_TARGETS_LOADED_CHOOSER_SERVICE);
-                    sendVoiceChoicesIfNeeded();
-                    mChooserListAdapter.completeServiceTargetLoading();
+                    maybeStopServiceRequestTimer();
                     break;
 
                 case LIST_VIEW_UPDATE_MESSAGE:
@@ -669,6 +716,17 @@
                 .getUserInfo(UserHandle.myUserId()).isManagedProfile();
     }
 
+    @Override
+    protected PackageMonitor createPackageMonitor() {
+        return new PackageMonitor() {
+            @Override
+            public void onSomePackagesChanged() {
+                mAdapter.handlePackagesChanged();
+                bindProfileView();
+            }
+        };
+    }
+
     private void onCopyButtonClicked(View v) {
         Intent targetIntent = getTargetIntent();
         if (targetIntent == null) {
@@ -716,18 +774,31 @@
     public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
 
+        adjustPreviewWidth(newConfig.orientation, null);
+    }
+
+    private boolean shouldDisplayLandscape(int orientation) {
+        // Sharesheet fixes the # of items per row and therefore can not correctly lay out
+        // when in the restricted size of multi-window mode. In the future, would be nice
+        // to use minimum dp size requirements instead
+        return orientation == Configuration.ORIENTATION_LANDSCAPE && !isInMultiWindowMode();
+    }
+
+    private void adjustPreviewWidth(int orientation, View parent) {
         int width = -1;
-        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+        if (shouldDisplayLandscape(orientation)) {
             width = getResources().getDimensionPixelSize(R.dimen.chooser_preview_width);
         }
 
-        updateLayoutWidth(R.id.content_preview_text_layout, width);
-        updateLayoutWidth(R.id.content_preview_title_layout, width);
-        updateLayoutWidth(R.id.content_preview_file_layout, width);
+        parent = parent == null ? getWindow().getDecorView() : parent;
+
+        updateLayoutWidth(R.id.content_preview_text_layout, width, parent);
+        updateLayoutWidth(R.id.content_preview_title_layout, width, parent);
+        updateLayoutWidth(R.id.content_preview_file_layout, width, parent);
     }
 
-    private void updateLayoutWidth(int layoutResourceId, int width) {
-        View view = findViewById(layoutResourceId);
+    private void updateLayoutWidth(int layoutResourceId, int width, View parent) {
+        View view = parent.findViewById(layoutResourceId);
         if (view != null && view.getLayoutParams() != null) {
             LayoutParams params = view.getLayoutParams();
             params.width = width;
@@ -740,18 +811,27 @@
             ViewGroup parent) {
         if (convertView != null) return convertView;
 
+        ViewGroup layout = null;
+
         switch (previewType) {
             case CONTENT_PREVIEW_TEXT:
-                return displayTextContentPreview(targetIntent, layoutInflater, parent);
+                layout = displayTextContentPreview(targetIntent, layoutInflater, parent);
+                break;
             case CONTENT_PREVIEW_IMAGE:
-                return displayImageContentPreview(targetIntent, layoutInflater, parent);
+                layout = displayImageContentPreview(targetIntent, layoutInflater, parent);
+                break;
             case CONTENT_PREVIEW_FILE:
-                return displayFileContentPreview(targetIntent, layoutInflater, parent);
+                layout = displayFileContentPreview(targetIntent, layoutInflater, parent);
+                break;
             default:
                 Log.e(TAG, "Unexpected content preview type: " + previewType);
         }
 
-        return null;
+        if (layout != null) {
+            adjustPreviewWidth(getResources().getConfiguration().orientation, layout);
+        }
+
+        return layout;
     }
 
     private ViewGroup displayTextContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
@@ -1043,11 +1123,7 @@
             mRefinementResultReceiver = null;
         }
         unbindRemainingServices();
-        mChooserHandler.removeMessages(LIST_VIEW_UPDATE_MESSAGE);
-        mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
-        mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
-        mChooserHandler.removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT);
-        mChooserHandler.removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED);
+        mChooserHandler.removeAllMessages();
 
         if (mPreviewCoord != null) mPreviewCoord.cancelLoads();
 
@@ -1285,6 +1361,7 @@
         final PackageManager pm = getPackageManager();
         ShortcutManager sm = (ShortcutManager) getSystemService(ShortcutManager.class);
         int targetsToQuery = 0;
+
         for (int i = 0, N = adapter.getDisplayResolveInfoCount(); i < N; i++) {
             final DisplayResolveInfo dri = adapter.getDisplayResolveInfo(i);
             if (adapter.getScore(dri) == 0) {
@@ -1304,6 +1381,12 @@
             if (serviceName != null) {
                 final ComponentName serviceComponent = new ComponentName(
                         ai.packageName, serviceName);
+
+                if (mServicesRequested.contains(serviceComponent)) {
+                    continue;
+                }
+                mServicesRequested.add(serviceComponent);
+
                 final Intent serviceIntent = new Intent(ChooserTargetService.SERVICE_INTERFACE)
                         .setComponent(serviceComponent);
 
@@ -1354,16 +1437,7 @@
             }
         }
 
-        if (DEBUG) {
-            Log.d(TAG, "queryTargets setting watchdog timer for "
-                    + WATCHDOG_TIMEOUT_MILLIS + "ms");
-        }
-        mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
-                WATCHDOG_TIMEOUT_MILLIS);
-
-        if (mServiceConnections.isEmpty()) {
-            sendVoiceChoicesIfNeeded();
-        }
+        mChooserHandler.restartServiceRequestTimer();
     }
 
     private IntentFilter getTargetIntentFilter() {
@@ -1460,7 +1534,11 @@
                 if (driList.get(i).getResolvedComponentName().equals(
                             resultList.get(j).getTargetComponent())) {
                     ShortcutManager.ShareShortcutInfo shareShortcutInfo = resultList.get(j);
-                    ChooserTarget chooserTarget = convertToChooserTarget(shareShortcutInfo);
+                    // Incoming results are ordered but without a score. Create a score
+                    // based on the index in order to be sorted appropriately when joined
+                    // with legacy direct share api results.
+                    float score = Math.max(1.0f - (0.05f * j), 0.0f);
+                    ChooserTarget chooserTarget = convertToChooserTarget(shareShortcutInfo, score);
                     chooserTargets.add(chooserTarget);
                     if (mDirectShareAppTargetCache != null && appTargets != null) {
                         mDirectShareAppTargetCache.put(chooserTarget, appTargets.get(j));
@@ -1471,7 +1549,7 @@
                 continue;
             }
             final Message msg = Message.obtain();
-            msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT;
+            msg.what = ChooserHandler.SHORTCUT_MANAGER_SHARE_TARGET_RESULT;
             msg.obj = new ServiceResultInfo(driList.get(i), chooserTargets, null);
             mChooserHandler.sendMessage(msg);
             resultMessageSent = true;
@@ -1484,7 +1562,7 @@
 
     private void sendShortcutManagerShareTargetResultCompleted() {
         final Message msg = Message.obtain();
-        msg.what = SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED;
+        msg.what = ChooserHandler.SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED;
         mChooserHandler.sendMessage(msg);
     }
 
@@ -1506,7 +1584,8 @@
         return false;
     }
 
-    private ChooserTarget convertToChooserTarget(ShortcutManager.ShareShortcutInfo shareShortcut) {
+    private ChooserTarget convertToChooserTarget(ShortcutManager.ShareShortcutInfo shareShortcut,
+                                                 float score) {
         ShortcutInfo shortcutInfo = shareShortcut.getShortcutInfo();
         Bundle extras = new Bundle();
         extras.putString(Intent.EXTRA_SHORTCUT_ID, shortcutInfo.getId());
@@ -1517,7 +1596,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.
-                1.0f,
+                score,
                 // 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.
@@ -1552,6 +1631,7 @@
             unbindService(conn);
             conn.destroy();
         }
+        mServicesRequested.clear();
         mServiceConnections.clear();
     }
 
@@ -2176,13 +2256,13 @@
             return;
         }
 
-        int availableWidth = right - left - v.getPaddingLeft() - v.getPaddingRight();
+        final int availableWidth = right - left - v.getPaddingLeft() - v.getPaddingRight();
         if (mChooserRowAdapter.consumeLayoutRequest()
                 || mChooserRowAdapter.calculateChooserTargetWidth(availableWidth)
-                || mAdapterView.getAdapter() == null) {
-            if (mAdapterView.getAdapter() == null) {
-                mAdapterView.setAdapter(mChooserRowAdapter);
-            }
+                || mAdapterView.getAdapter() == null
+                || availableWidth != mCurrAvailableWidth) {
+            mCurrAvailableWidth = availableWidth;
+            mAdapterView.setAdapter(mChooserRowAdapter);
 
             getMainThreadHandler().post(() -> {
                 if (mResolverDrawerLayout == null || mChooserRowAdapter == null) {
@@ -2225,9 +2305,9 @@
                     }
                 }
 
-                boolean isPortrait = getResources().getConfiguration().orientation
-                                         == Configuration.ORIENTATION_PORTRAIT;
-                if (directShareHeight != 0 && isSendAction(getTargetIntent()) && isPortrait) {
+                boolean isExpandable = getResources().getConfiguration().orientation
+                        == Configuration.ORIENTATION_PORTRAIT && !isInMultiWindowMode();
+                if (directShareHeight != 0 && isSendAction(getTargetIntent()) && isExpandable) {
                     // make sure to leave room for direct share 4->8 expansion
                     int requiredExpansionHeight =
                             (int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
@@ -2252,17 +2332,18 @@
 
         private static final int MAX_SUGGESTED_APP_TARGETS = 4;
         private static final int MAX_CHOOSER_TARGETS_PER_APP = 2;
-        private static final int MAX_SHORTCUT_TARGETS_PER_APP = 8;
 
         private static final int MAX_SERVICE_TARGETS = 8;
 
+        private final int mMaxShortcutTargetsPerApp =
+                getResources().getInteger(R.integer.config_maxShortcutTargetsPerApp);
+
         private int mNumShortcutResults = 0;
 
         // Reserve spots for incoming direct share targets by adding placeholders
         private ChooserTargetInfo mPlaceHolderTargetInfo = new PlaceHolderTargetInfo();
         private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
         private final List<TargetInfo> mCallerTargets = new ArrayList<>();
-        private boolean mTargetsNeedPruning = false;
 
         private final BaseChooserTargetComparator mBaseTargetComparator
                 = new BaseChooserTargetComparator();
@@ -2331,9 +2412,21 @@
         }
 
         @Override
+        public void handlePackagesChanged() {
+            if (DEBUG) {
+                Log.d(TAG, "clearing queryTargets on package change");
+            }
+            createPlaceHolders();
+            mServicesRequested.clear();
+            notifyDataSetChanged();
+
+            super.handlePackagesChanged();
+        }
+
+        @Override
         public void notifyDataSetChanged() {
             if (!mListViewDataChanged) {
-                mChooserHandler.sendEmptyMessageDelayed(LIST_VIEW_UPDATE_MESSAGE,
+                mChooserHandler.sendEmptyMessageDelayed(ChooserHandler.LIST_VIEW_UPDATE_MESSAGE,
                         LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
                 mListViewDataChanged = true;
             }
@@ -2348,6 +2441,7 @@
 
 
         private void createPlaceHolders() {
+            mNumShortcutResults = 0;
             mServiceTargets.clear();
             for (int i = 0; i < MAX_SERVICE_TARGETS; i++) {
                 mServiceTargets.add(mPlaceHolderTargetInfo);
@@ -2390,16 +2484,6 @@
                 return;
             }
 
-            if (mServiceTargets != null) {
-                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
-                    // set of targets suddenly dropping to zero) and remember to prune later.
-                    mTargetsNeedPruning = true;
-                }
-            }
-
             if (USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS
                         || USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
                 if (DEBUG) {
@@ -2456,7 +2540,7 @@
         }
 
         public int getServiceTargetCount() {
-            if (isSendAction(getTargetIntent())) {
+            if (isSendAction(getTargetIntent()) && !ActivityManager.isLowRamDeviceStatic()) {
                 return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS);
             }
 
@@ -2568,23 +2652,10 @@
                 return;
             }
 
-            if (mTargetsNeedPruning) {
-                // First proper update since we got an onListRebuilt() with (transient) 0 items.
-                // Clear out the target list and rebuild.
-                createPlaceHolders();
-                mTargetsNeedPruning = false;
-
-                // Add back any app-supplied direct share targets that may have been
-                // wiped by this clear
-                if (mCallerChooserTargets != null) {
-                    addServiceResults(null, Lists.newArrayList(mCallerChooserTargets), false);
-                }
-            }
-
             final float baseScore = getBaseScore(origTarget, isShortcutResult);
             Collections.sort(targets, mBaseTargetComparator);
 
-            final int maxTargets = isShortcutResult ? MAX_SHORTCUT_TARGETS_PER_APP
+            final int maxTargets = isShortcutResult ? mMaxShortcutTargetsPerApp
                                        : MAX_CHOOSER_TARGETS_PER_APP;
             float lastScore = 0;
             boolean shouldNotify = false;
@@ -2791,8 +2862,7 @@
 
         private int getMaxTargetsPerRow() {
             int maxTargets = MAX_TARGETS_PER_ROW_PORTRAIT;
-            if (getResources().getConfiguration().orientation
-                    == Configuration.ORIENTATION_LANDSCAPE) {
+            if (shouldDisplayLandscape(getResources().getConfiguration().orientation)) {
                 maxTargets = MAX_TARGETS_PER_ROW_LANDSCAPE;
             }
 
@@ -3178,7 +3248,8 @@
             int orientation = getResources().getConfiguration().orientation;
             boolean canExpandDirectShare =
                     mChooserListAdapter.getNumShortcutResults() > getMaxTargetsPerRow()
-                    && orientation == Configuration.ORIENTATION_PORTRAIT;
+                    && orientation == Configuration.ORIENTATION_PORTRAIT
+                    && !isInMultiWindowMode();
 
             if (mDirectShareViewHolder != null && canExpandDirectShare) {
                 mDirectShareViewHolder.handleScroll(mAdapterView, y, oldy, getMaxTargetsPerRow());
@@ -3425,7 +3496,7 @@
                     mChooserActivity.filterServiceTargets(
                             mOriginalTarget.getResolveInfo().activityInfo.packageName, targets);
                     final Message msg = Message.obtain();
-                    msg.what = CHOOSER_TARGET_SERVICE_RESULT;
+                    msg.what = ChooserHandler.CHOOSER_TARGET_SERVICE_RESULT;
                     msg.obj = new ServiceResultInfo(mOriginalTarget, targets,
                             ChooserTargetServiceConnection.this);
                     mChooserActivity.mChooserHandler.sendMessage(msg);
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 5778544..157e0a7 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -16,252 +16,167 @@
 
 package com.android.internal.app;
 
+import android.animation.ObjectAnimator;
 import android.animation.TimeAnimator;
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
 import android.content.ContentResolver;
 import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.ColorFilter;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.Shader;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.util.Log;
+import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
 import android.view.View;
-import android.widget.FrameLayout;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import com.android.internal.R;
 
 import org.json.JSONObject;
 
+/**
+ * @hide
+ */
 public class PlatLogoActivity extends Activity {
-    FrameLayout layout;
-    TimeAnimator anim;
-    PBackground bg;
+    ImageView mZeroView, mOneView;
+    BackslashDrawable mBackslash;
+    int mClicks;
 
-    private class PBackground extends Drawable {
-        private float maxRadius, radius, x, y, dp;
-        private int[] palette;
-        private int darkest;
-        private float offset;
+    static final Paint sPaint = new Paint();
+    static {
+        sPaint.setStyle(Paint.Style.STROKE);
+        sPaint.setStrokeWidth(4f);
+        sPaint.setStrokeCap(Paint.Cap.SQUARE);
+    }
 
-        public PBackground() {
-            randomizePalette();
+    @Override
+    protected void onPause() {
+        if (mBackslash != null) {
+            mBackslash.stopAnimating();
         }
-
-        /**
-         * set inner radius of "p" logo
-         */
-        public void setRadius(float r) {
-            this.radius = Math.max(48*dp, r);
-        }
-
-        /**
-         * move the "p"
-         */
-        public void setPosition(float x, float y) {
-            this.x = x;
-            this.y = y;
-        }
-
-        /**
-         * for animating the "p"
-         */
-        public void setOffset(float o) {
-            this.offset = o;
-        }
-
-        /**
-         * rough luminance calculation
-         * https://www.w3.org/TR/AERT/#color-contrast
-         */
-        public float lum(int rgb) {
-            return ((Color.red(rgb) * 299f) + (Color.green(rgb) * 587f) + (Color.blue(rgb) * 114f)) / 1000f;
-        }
-
-        /**
-         * create a random evenly-spaced color palette
-         * guaranteed to contrast!
-         */
-        public void randomizePalette() {
-            final int slots = 2 + (int)(Math.random() * 2);
-            float[] color = new float[] { (float) Math.random() * 360f, 1f, 1f };
-            palette = new int[slots];
-            darkest = 0;
-            for (int i=0; i<slots; i++) {
-                palette[i] = Color.HSVToColor(color);
-                color[0] = (color[0] + 360f/slots) % 360f;
-                if (lum(palette[i]) < lum(palette[darkest])) darkest = i;
-            }
-
-            final StringBuilder str = new StringBuilder();
-            for (int c : palette) {
-                str.append(String.format("#%08x ", c));
-            }
-            Log.v("PlatLogoActivity", "color palette: " + str);
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-            if (dp == 0) dp = getResources().getDisplayMetrics().density;
-            final float width = canvas.getWidth();
-            final float height = canvas.getHeight();
-            if (radius == 0) {
-                setPosition(width / 2, height / 2);
-                setRadius(width / 6);
-            }
-            final float inner_w = radius * 0.667f;
-
-            final Paint paint = new Paint();
-            paint.setStrokeCap(Paint.Cap.BUTT);
-            canvas.translate(x, y);
-
-            Path p = new Path();
-            p.moveTo(-radius, height);
-            p.lineTo(-radius, 0);
-            p.arcTo(-radius, -radius, radius, radius, -180, 270, false);
-            p.lineTo(-radius, radius);
-
-            float w = Math.max(canvas.getWidth(), canvas.getHeight())  * 1.414f;
-            paint.setStyle(Paint.Style.FILL);
-
-            int i=0;
-            while (w > radius*2 + inner_w*2) {
-                paint.setColor(0xFF000000 | palette[i % palette.length]);
-                // for a slower but more complete version:
-                // paint.setStrokeWidth(w);
-                // canvas.drawPath(p, paint);
-                canvas.drawOval(-w/2, -w/2, w/2, w/2, paint);
-                w -= inner_w * (1.1f + Math.sin((i/20f + offset) * 3.14159f));
-                i++;
-            }
-
-            // the innermost circle needs to be a constant color to avoid rapid flashing
-            paint.setColor(0xFF000000 | palette[(darkest+1) % palette.length]);
-            canvas.drawOval(-radius, -radius, radius, radius, paint);
-
-            p.reset();
-            p.moveTo(-radius, height);
-            p.lineTo(-radius, 0);
-            p.arcTo(-radius, -radius, radius, radius, -180, 270, false);
-            p.lineTo(-radius + inner_w, radius);
-
-            paint.setStyle(Paint.Style.STROKE);
-            paint.setStrokeWidth(inner_w*2);
-            paint.setColor(palette[darkest]);
-            canvas.drawPath(p, paint);
-            paint.setStrokeWidth(inner_w);
-            paint.setColor(0xFFFFFFFF);
-            canvas.drawPath(p, paint);
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-
-        }
-
-        @Override
-        public void setColorFilter(ColorFilter colorFilter) {
-
-        }
-
-        @Override
-        public int getOpacity() {
-            return 0;
-        }
+        mClicks = 0;
+        super.onPause();
     }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        final float dp = getResources().getDisplayMetrics().density;
 
-        layout = new FrameLayout(this);
-        setContentView(layout);
+        getWindow().getDecorView().setSystemUiVisibility(
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+        getWindow().setNavigationBarColor(0);
+        getWindow().setStatusBarColor(0);
 
-        bg = new PBackground();
-        layout.setBackground(bg);
+        getActionBar().hide();
 
-        final ContentResolver cr = getContentResolver();
+        setContentView(R.layout.platlogo_layout);
 
-        layout.setOnTouchListener(new View.OnTouchListener() {
-            final String TOUCH_STATS = "touch.stats";
+        mBackslash = new BackslashDrawable((int) (50 * dp));
 
-            final PointerCoords pc0 = new PointerCoords();
-            final PointerCoords pc1 = new PointerCoords();
+        mOneView = findViewById(R.id.one);
+        mOneView.setImageDrawable(new OneDrawable());
+        mZeroView = findViewById(R.id.zero);
+        mZeroView.setImageDrawable(new ZeroDrawable());
 
-            double pressure_min, pressure_max;
-            int maxPointers;
-            int tapCount;
+        final ViewGroup root = (ViewGroup) mOneView.getParent();
+        root.setClipChildren(false);
+        root.setBackground(mBackslash);
+        root.getBackground().setAlpha(0x20);
 
+        View.OnTouchListener tl = new View.OnTouchListener() {
+            float mOffsetX, mOffsetY;
+            long mClickTime;
+            ObjectAnimator mRotAnim;
             @Override
             public boolean onTouch(View v, MotionEvent event) {
-                final float pressure = event.getPressure();
+                measureTouchPressure(event);
                 switch (event.getActionMasked()) {
                     case MotionEvent.ACTION_DOWN:
-                        pressure_min = pressure_max = pressure;
-                        // fall through
-                    case MotionEvent.ACTION_MOVE:
-                        if (pressure < pressure_min) pressure_min = pressure;
-                        if (pressure > pressure_max) pressure_max = pressure;
-                        final int pc = event.getPointerCount();
-                        if (pc > maxPointers) maxPointers = pc;
-                        if (pc > 1) {
-                            event.getPointerCoords(0, pc0);
-                            event.getPointerCoords(1, pc1);
-                            bg.setRadius((float) Math.hypot(pc0.x - pc1.x, pc0.y - pc1.y) / 2f);
+                        v.animate().scaleX(1.1f).scaleY(1.1f);
+                        v.getParent().bringChildToFront(v);
+                        mOffsetX = event.getRawX() - v.getX();
+                        mOffsetY = event.getRawY() - v.getY();
+                        long now = System.currentTimeMillis();
+                        if (now - mClickTime < 350) {
+                            mRotAnim = ObjectAnimator.ofFloat(v, View.ROTATION,
+                                    v.getRotation(), v.getRotation() + 3600);
+                            mRotAnim.setDuration(10000);
+                            mRotAnim.start();
+                            mClickTime = 0;
+                        } else {
+                            mClickTime = now;
                         }
                         break;
-                    case MotionEvent.ACTION_CANCEL:
+                    case MotionEvent.ACTION_MOVE:
+                        v.setX(event.getRawX() - mOffsetX);
+                        v.setY(event.getRawY() - mOffsetY);
+                        v.performHapticFeedback(HapticFeedbackConstants.TEXT_HANDLE_MOVE);
+                        break;
                     case MotionEvent.ACTION_UP:
-                        try {
-                            final String touchDataJson = Settings.System.getString(cr, TOUCH_STATS);
-                            final JSONObject touchData = new JSONObject(
-                                    touchDataJson != null ? touchDataJson : "{}");
-                            if (touchData.has("min")) {
-                                pressure_min = Math.min(pressure_min, touchData.getDouble("min"));
-                            }
-                            if (touchData.has("max")) {
-                                pressure_max = Math.max(pressure_max, touchData.getDouble("max"));
-                            }
-                            touchData.put("min", pressure_min);
-                            touchData.put("max", pressure_max);
-                            Settings.System.putString(cr, TOUCH_STATS, touchData.toString());
-                        } catch (Exception e) {
-                            Log.e("PlatLogoActivity", "Can't write touch settings", e);
-                        }
-
-                        if (maxPointers == 1) {
-                            tapCount ++;
-                            if (tapCount < 7) {
-                                bg.randomizePalette();
-                            } else {
-                                launchNextStage();
-                            }
-                        } else {
-                            tapCount = 0;
-                        }
-                        maxPointers = 0;
+                        v.performClick();
+                        // fall through
+                    case MotionEvent.ACTION_CANCEL:
+                        v.animate().scaleX(1f).scaleY(1f);
+                        if (mRotAnim != null) mRotAnim.cancel();
+                        testOverlap();
                         break;
                 }
                 return true;
             }
-        });
+        };
+
+        findViewById(R.id.one).setOnTouchListener(tl);
+        findViewById(R.id.zero).setOnTouchListener(tl);
+        findViewById(R.id.text).setOnTouchListener(tl);
+    }
+
+    private void testOverlap() {
+        final float width = mZeroView.getWidth();
+        final float targetX = mZeroView.getX() + width * .2f;
+        final float targetY = mZeroView.getY() + width * .3f;
+        if (Math.hypot(targetX - mOneView.getX(), targetY - mOneView.getY()) < width * .2f
+                && Math.abs(mOneView.getRotation() % 360 - 315) < 15) {
+            mOneView.animate().x(mZeroView.getX() + width * .2f);
+            mOneView.animate().y(mZeroView.getY() + width * .3f);
+            mOneView.setRotation(mOneView.getRotation() % 360);
+            mOneView.animate().rotation(315);
+            mOneView.performHapticFeedback(HapticFeedbackConstants.CONFIRM);
+
+            mBackslash.startAnimating();
+
+            mClicks++;
+            if (mClicks >= 7) {
+                launchNextStage();
+            }
+        } else {
+            mBackslash.stopAnimating();
+        }
     }
 
     private void launchNextStage() {
         final ContentResolver cr = getContentResolver();
 
-        if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0) == 0) {
+        if (Settings.System.getLong(cr, "egg_mode" /* Settings.System.EGG_MODE */, 0) == 0) {
             // For posterity: the moment this user unlocked the easter egg
             try {
                 Settings.System.putLong(cr,
-                        Settings.System.EGG_MODE,
+                        "egg_mode", // Settings.System.EGG_MODE,
                         System.currentTimeMillis());
             } catch (RuntimeException e) {
-                Log.e("PlatLogoActivity", "Can't write settings", e);
+                Log.e("com.android.internal.app.PlatLogoActivity", "Can't write settings", e);
             }
         }
         try {
@@ -270,36 +185,206 @@
                         | Intent.FLAG_ACTIVITY_CLEAR_TASK)
                     .addCategory("com.android.internal.category.PLATLOGO"));
         } catch (ActivityNotFoundException ex) {
-            Log.e("PlatLogoActivity", "No more eggs.");
+            Log.e("com.android.internal.app.PlatLogoActivity", "No more eggs.");
         }
         finish();
     }
 
+    static final String TOUCH_STATS = "touch.stats";
+    double mPressureMin = 0, mPressureMax = -1;
+
+    private void measureTouchPressure(MotionEvent event) {
+        final float pressure = event.getPressure();
+        switch (event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                if (mPressureMax < 0) {
+                    mPressureMin = mPressureMax = pressure;
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (pressure < mPressureMin) mPressureMin = pressure;
+                if (pressure > mPressureMax) mPressureMax = pressure;
+                break;
+        }
+    }
+
+    private void syncTouchPressure() {
+        try {
+            final String touchDataJson = Settings.System.getString(
+                    getContentResolver(), TOUCH_STATS);
+            final JSONObject touchData = new JSONObject(
+                    touchDataJson != null ? touchDataJson : "{}");
+            if (touchData.has("min")) {
+                mPressureMin = Math.min(mPressureMin, touchData.getDouble("min"));
+            }
+            if (touchData.has("max")) {
+                mPressureMax = Math.max(mPressureMax, touchData.getDouble("max"));
+            }
+            if (mPressureMax >= 0) {
+                touchData.put("min", mPressureMin);
+                touchData.put("max", mPressureMax);
+                Settings.System.putString(getContentResolver(), TOUCH_STATS, touchData.toString());
+            }
+        } catch (Exception e) {
+            Log.e("com.android.internal.app.PlatLogoActivity", "Can't write touch settings", e);
+        }
+    }
+
     @Override
     public void onStart() {
         super.onStart();
-
-        bg.randomizePalette();
-
-        anim = new TimeAnimator();
-        anim.setTimeListener(
-                new TimeAnimator.TimeListener() {
-                    @Override
-                    public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
-                        bg.setOffset((float) totalTime / 60000f);
-                        bg.invalidateSelf();
-                    }
-                });
-
-        anim.start();
+        syncTouchPressure();
     }
 
     @Override
     public void onStop() {
-        if (anim != null) {
-            anim.cancel();
-            anim = null;
-        }
+        syncTouchPressure();
         super.onStop();
     }
+
+    static class ZeroDrawable extends Drawable {
+        int mTintColor;
+
+        @Override
+        public void draw(Canvas canvas) {
+            sPaint.setColor(mTintColor | 0xFF000000);
+
+            canvas.save();
+            canvas.scale(canvas.getWidth() / 24f, canvas.getHeight() / 24f);
+
+            canvas.drawCircle(12f, 12f, 10f, sPaint);
+            canvas.restore();
+        }
+
+        @Override
+        public void setAlpha(int alpha) { }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) { }
+
+        @Override
+        public void setTintList(ColorStateList tint) {
+            mTintColor = tint.getDefaultColor();
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+    }
+
+    static class OneDrawable extends Drawable {
+        int mTintColor;
+
+        @Override
+        public void draw(Canvas canvas) {
+            sPaint.setColor(mTintColor | 0xFF000000);
+
+            canvas.save();
+            canvas.scale(canvas.getWidth() / 24f, canvas.getHeight() / 24f);
+
+            final Path p = new Path();
+            p.moveTo(12f, 21.83f);
+            p.rLineTo(0f, -19.67f);
+            p.rLineTo(-5f, 0f);
+            canvas.drawPath(p, sPaint);
+            canvas.restore();
+        }
+
+        @Override
+        public void setAlpha(int alpha) { }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) { }
+
+        @Override
+        public void setTintList(ColorStateList tint) {
+            mTintColor = tint.getDefaultColor();
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+    }
+
+    private static class BackslashDrawable extends Drawable implements TimeAnimator.TimeListener {
+        Bitmap mTile;
+        Paint mPaint = new Paint();
+        BitmapShader mShader;
+        TimeAnimator mAnimator = new TimeAnimator();
+        Matrix mMatrix = new Matrix();
+
+        public void draw(Canvas canvas) {
+            canvas.drawPaint(mPaint);
+        }
+
+        BackslashDrawable(int width) {
+            mTile = Bitmap.createBitmap(width, width, Bitmap.Config.ALPHA_8);
+            mAnimator.setTimeListener(this);
+
+            final Canvas tileCanvas = new Canvas(mTile);
+            final float w = tileCanvas.getWidth();
+            final float h = tileCanvas.getHeight();
+
+            final Path path = new Path();
+            path.moveTo(0, 0);
+            path.lineTo(w / 2, 0);
+            path.lineTo(w, h / 2);
+            path.lineTo(w, h);
+            path.close();
+
+            path.moveTo(0, h / 2);
+            path.lineTo(w / 2, h);
+            path.lineTo(0, h);
+            path.close();
+
+            final Paint slashPaint = new Paint();
+            slashPaint.setAntiAlias(true);
+            slashPaint.setStyle(Paint.Style.FILL);
+            slashPaint.setColor(0xFF000000);
+            tileCanvas.drawPath(path, slashPaint);
+
+            //mPaint.setColor(0xFF0000FF);
+            mShader = new BitmapShader(mTile, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
+            mPaint.setShader(mShader);
+        }
+
+        public void startAnimating() {
+            if (!mAnimator.isStarted()) {
+                mAnimator.start();
+            }
+        }
+
+        public void stopAnimating() {
+            if (mAnimator.isStarted()) {
+                mAnimator.cancel();
+            }
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+            mPaint.setAlpha(alpha);
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {
+            mPaint.setColorFilter(colorFilter);
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+
+        @Override
+        public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
+            if (mShader != null) {
+                mMatrix.postTranslate(deltaTime / 4f, 0);
+                mShader.setLocalMatrix(mMatrix);
+                invalidateSelf();
+            }
+        }
+    }
 }
+
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 0a01beb..58ce03b 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -29,7 +29,6 @@
 import android.app.VoiceInteractor.PickOptionRequest;
 import android.app.VoiceInteractor.PickOptionRequest.Option;
 import android.app.VoiceInteractor.Prompt;
-import android.app.role.RoleManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -111,7 +110,6 @@
     protected AbsListView mAdapterView;
     private Button mAlwaysButton;
     private Button mOnceButton;
-    private Button mSettingsButton;
     protected View mProfileView;
     private int mIconDpi;
     private int mLastSelected = AbsListView.INVALID_POSITION;
@@ -146,19 +144,11 @@
     /** See {@link #setRetainInOnStop}. */
     private boolean mRetainInOnStop;
 
-    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
-        @Override public void onSomePackagesChanged() {
-            mAdapter.handlePackagesChanged();
-            bindProfileView();
-        }
+    private static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args";
+    private static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
+    private static final String OPEN_LINKS_COMPONENT_KEY = "app_link_state";
 
-        @Override
-        public boolean onPackageChanged(String packageName, int uid, String[] components) {
-            // We care about all package changes, not just the whole package itself which is
-            // default behavior.
-            return true;
-        }
-    };
+    private final PackageMonitor mPackageMonitor = createPackageMonitor();
 
     /**
      * Get the string resource to be used as a label for the link to the resolver activity for an
@@ -208,9 +198,13 @@
 
         // titles for layout that deals with http(s) intents
         public static final int BROWSABLE_TITLE_RES =
-                com.android.internal.R.string.whichGiveAccessToApplication;
-        public static final int BROWSABLE_NAMED_TITLE_RES =
-                com.android.internal.R.string.whichGiveAccessToApplicationNamed;
+                com.android.internal.R.string.whichOpenLinksWith;
+        public static final int BROWSABLE_HOST_TITLE_RES =
+                com.android.internal.R.string.whichOpenHostLinksWith;
+        public static final int BROWSABLE_HOST_APP_TITLE_RES =
+                com.android.internal.R.string.whichOpenHostLinksWithApp;
+        public static final int BROWSABLE_APP_TITLE_RES =
+                com.android.internal.R.string.whichOpenLinksWithApp;
 
         public final String action;
         public final int titleRes;
@@ -234,6 +228,23 @@
         }
     }
 
+    protected PackageMonitor createPackageMonitor() {
+        return new PackageMonitor() {
+            @Override
+            public void onSomePackagesChanged() {
+                mAdapter.handlePackagesChanged();
+                bindProfileView();
+            }
+
+            @Override
+            public boolean onPackageChanged(String packageName, int uid, String[] components) {
+                // We care about all package changes, not just the whole package itself which is
+                // default behavior.
+                return true;
+            }
+        };
+    }
+
     private Intent makeMyIntent() {
         Intent intent = new Intent(getIntent());
         intent.setComponent(null);
@@ -317,9 +328,7 @@
                 ? false
                 : isHttpSchemeAndViewAction(getTargetIntent());
 
-        // We don't want to support Always Use if browsable layout is being used,
-        // as to mitigate Intent Capturing vulnerability
-        mSupportsAlwaysUseOption = supportsAlwaysUseOption && !mUseLayoutForBrowsables;
+        mSupportsAlwaysUseOption = supportsAlwaysUseOption;
 
         if (configureContentView(mIntents, initialIntents, rList)) {
             return;
@@ -398,6 +407,8 @@
                 mSystemWindowInsets.bottom));
         ((ListView) mAdapterView).addFooterView(mFooterSpacer);
 
+        resetButtonBar();
+
         return insets.consumeSystemWindowInsets();
     }
 
@@ -547,10 +558,21 @@
         } else if (isHttpSchemeAndViewAction(intent)) {
             // If the Intent's scheme is http(s) then we need to warn the user that
             // they're giving access for the activity to open URLs from this specific host
-            return named
-                    ? getString(ActionTitle.BROWSABLE_NAMED_TITLE_RES, intent.getData().getHost(),
-                    mAdapter.getFilteredItem().getDisplayLabel())
-                    : getString(ActionTitle.BROWSABLE_TITLE_RES, intent.getData().getHost());
+            String dialogTitle = null;
+            if (named && !mUseLayoutForBrowsables) {
+                dialogTitle = getString(ActionTitle.BROWSABLE_APP_TITLE_RES,
+                        mAdapter.getFilteredItem().getDisplayLabel());
+            } else if (named && mUseLayoutForBrowsables) {
+                dialogTitle = getString(ActionTitle.BROWSABLE_HOST_APP_TITLE_RES,
+                        intent.getData().getHost(),
+                        mAdapter.getFilteredItem().getDisplayLabel());
+            } else if (mAdapter.areAllTargetsBrowsers()) {
+                dialogTitle =  getString(ActionTitle.BROWSABLE_TITLE_RES);
+            } else {
+                dialogTitle = getString(ActionTitle.BROWSABLE_HOST_TITLE_RES,
+                        intent.getData().getHost());
+            }
+            return dialogTitle;
         } else {
             return named
                     ? getString(title.namedTitleRes, mAdapter.getFilteredItem().getDisplayLabel())
@@ -849,6 +871,13 @@
             } else {
                 enabled = true;
             }
+            if (mUseLayoutForBrowsables && !ri.handleAllWebDataURI) {
+                mAlwaysButton.setText(getResources()
+                        .getString(R.string.activity_resolver_set_always));
+            } else {
+                mAlwaysButton.setText(getResources()
+                        .getString(R.string.activity_resolver_use_always));
+            }
         }
         mAlwaysButton.setEnabled(enabled);
     }
@@ -859,26 +888,30 @@
                 ? mAdapter.getFilteredPosition()
                 : mAdapterView.getCheckedItemPosition();
         boolean hasIndexBeenFiltered = !mAdapter.hasFilteredItem();
-        if (id == R.id.button_app_settings) {
-            showSettingsForSelected(which, hasIndexBeenFiltered);
+        ResolveInfo ri = mAdapter.resolveInfoForPosition(which, hasIndexBeenFiltered);
+        if (mUseLayoutForBrowsables
+                && !ri.handleAllWebDataURI && id == R.id.button_always) {
+            showSettingsForSelected(ri);
         } else {
             startSelected(which, id == R.id.button_always, hasIndexBeenFiltered);
         }
     }
 
-    private void showSettingsForSelected(int which, boolean hasIndexBeenFiltered) {
-        ResolveInfo ri = mAdapter.resolveInfoForPosition(which, hasIndexBeenFiltered);
+    private void showSettingsForSelected(ResolveInfo ri) {
         Intent intent = new Intent();
-        // For browsers, we open the Default Browser page
+
+        final String packageName = ri.activityInfo.packageName;
+        Bundle showFragmentArgs = new Bundle();
+        showFragmentArgs.putString(EXTRA_FRAGMENT_ARG_KEY, OPEN_LINKS_COMPONENT_KEY);
+        showFragmentArgs.putString("package", packageName);
+
         // For regular apps, we open the Open by Default page
-        if (ri.handleAllWebDataURI) {
-            intent.setAction(Intent.ACTION_MANAGE_DEFAULT_APP)
-                    .putExtra(Intent.EXTRA_ROLE_NAME, RoleManager.ROLE_BROWSER);
-        } else {
-            intent.setAction(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS)
-                    .setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
-                    .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
-        }
+        intent.setAction(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS)
+                .setData(Uri.fromParts("package", packageName, null))
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
+                .putExtra(EXTRA_FRAGMENT_ARG_KEY, OPEN_LINKS_COMPONENT_KEY)
+                .putExtra(EXTRA_SHOW_FRAGMENT_ARGS, showFragmentArgs);
+
         startActivity(intent);
     }
 
@@ -1325,41 +1358,15 @@
                         R.dimen.resolver_button_bar_spacing) + inset);
 
             mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
-            mSettingsButton = (Button) buttonLayout.findViewById(R.id.button_app_settings);
             mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
 
-            if (mUseLayoutForBrowsables) {
-                resetSettingsOrOnceButtonBar();
-            } else {
-                resetAlwaysOrOnceButtonBar();
-            }
+            resetAlwaysOrOnceButtonBar();
         } else {
             Log.e(TAG, "Layout unexpectedly does not have a button bar");
         }
     }
 
-    private void resetSettingsOrOnceButtonBar() {
-        //unsetting always button
-        mAlwaysButton.setVisibility(View.GONE);
-
-        // When the items load in, if an item was already selected,
-        // enable the buttons
-        if (mAdapterView != null
-                && mAdapterView.getCheckedItemPosition() != ListView.INVALID_POSITION) {
-            mSettingsButton.setEnabled(true);
-            mOnceButton.setEnabled(true);
-        }
-    }
-
     private void resetAlwaysOrOnceButtonBar() {
-        // This check needs to be made because layout with default
-        // doesn't have a settings button
-        if (mSettingsButton != null) {
-            //unsetting always button
-            mSettingsButton.setVisibility(View.GONE);
-            mSettingsButton = null;
-        }
-
         if (useLayoutWithDefault()
                 && mAdapter.getFilteredPosition() != ListView.INVALID_POSITION) {
             setAlwaysButtonEnabled(true, mAdapter.getFilteredPosition(), false);
@@ -1619,6 +1626,7 @@
         private DisplayResolveInfo mOtherProfile;
         private ResolverListController mResolverListController;
         private int mPlaceholderCount;
+        private boolean mAllTargetsAreBrowsers = false;
 
         protected final LayoutInflater mInflater;
 
@@ -1694,6 +1702,14 @@
         }
 
         /**
+          * @return true if all items in the display list are defined as browsers by
+          *         ResolveInfo.handleAllWebDataURI
+          */
+        public boolean areAllTargetsBrowsers() {
+            return mAllTargetsAreBrowsers;
+        }
+
+        /**
          * Rebuild the list of resolvers. In some cases some parts will need some asynchronous work
          * to complete.
          *
@@ -1705,6 +1721,7 @@
             mOtherProfile = null;
             mLastChosen = null;
             mLastChosenPosition = -1;
+            mAllTargetsAreBrowsers = false;
             mDisplayList.clear();
             if (mBaseResolveList != null) {
                 currentResolveList = mUnfilteredResolveList = new ArrayList<>();
@@ -1805,6 +1822,8 @@
         private void processSortedList(List<ResolvedComponentInfo> sortedComponents) {
             int N;
             if (sortedComponents != null && (N = sortedComponents.size()) != 0) {
+                mAllTargetsAreBrowsers = mUseLayoutForBrowsables;
+
                 // First put the initial items at the top.
                 if (mInitialIntents != null) {
                     for (int i = 0; i < mInitialIntents.length; i++) {
@@ -1834,6 +1853,8 @@
                             ri.noResourceId = true;
                             ri.icon = 0;
                         }
+                        mAllTargetsAreBrowsers &= ri.handleAllWebDataURI;
+
                         addResolveInfo(new DisplayResolveInfo(ii, ri,
                                 ri.loadLabel(getPackageManager()), null, ii));
                     }
@@ -1843,6 +1864,8 @@
                 for (ResolvedComponentInfo rci : sortedComponents) {
                     final ResolveInfo ri = rci.getResolveInfoAt(0);
                     if (ri != null) {
+                        mAllTargetsAreBrowsers &= ri.handleAllWebDataURI;
+
                         ResolveInfoPresentationGetter pg = makePresentationGetter(ri);
                         addResolveInfoWithAlternates(rci, pg.getSubLabel(), pg.getLabel());
                     }
@@ -2145,14 +2168,8 @@
             final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
             if (!useLayoutWithDefault()
                     && (!hasValidSelection || mLastSelected != checkedPos)
-                    && (mAlwaysButton != null || mSettingsButton != null)) {
-                if (mSettingsButton != null) {
-                    // this implies that the layout for browsables is being used
-                    mSettingsButton.setEnabled(true);
-                } else {
-                    // this implies that mAlwaysButton != null
-                    setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
-                }
+                    && mAlwaysButton != null) {
+                setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
                 mOnceButton.setEnabled(hasValidSelection);
                 if (hasValidSelection) {
                     mAdapterView.smoothScrollToPosition(checkedPos);
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
index d9fd3b5..3003ce8 100644
--- a/core/java/com/android/internal/colorextraction/ColorExtractor.java
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -53,11 +53,13 @@
     protected WallpaperColors mLockColors;
 
     public ColorExtractor(Context context) {
-        this(context, new Tonal(context), true /* immediately */);
+        this(context, new Tonal(context), true /* immediately */,
+                context.getSystemService(WallpaperManager.class));
     }
 
     @VisibleForTesting
-    public ColorExtractor(Context context, ExtractionType extractionType, boolean immediately) {
+    public ColorExtractor(Context context, ExtractionType extractionType, boolean immediately,
+            WallpaperManager wallpaperManager) {
         mContext = context;
         mExtractionType = extractionType;
 
@@ -71,14 +73,8 @@
         }
 
         mOnColorsChangedListeners = new ArrayList<>();
-
-        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
-        if (wallpaperManager == null) {
-            Log.w(TAG, "Can't listen to color changes!");
-        } else {
-            wallpaperManager.addOnColorsChangedListener(this, null /* handler */);
-            initExtractColors(wallpaperManager, immediately);
-        }
+        wallpaperManager.addOnColorsChangedListener(this, null /* handler */);
+        initExtractColors(wallpaperManager, immediately);
     }
 
     private void initExtractColors(WallpaperManager wallpaperManager, boolean immediately) {
@@ -110,7 +106,7 @@
         }
     }
 
-    private void extractWallpaperColors() {
+    protected void extractWallpaperColors() {
         GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
         GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
         extractInto(mSystemColors,
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 1b0a458..ee4666f 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -113,7 +113,7 @@
      */
     public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
 
-    // Flags related to Assistant Handles
+    // Flags related to Assistant
 
     /**
      * (String) Which behavior mode for the Assistant Handles to use.
@@ -127,6 +127,26 @@
             "assist_handles_show_and_go_duration_ms";
 
     /**
+     * (long) How long, in milliseconds, to wait before showing the Assist Handles temporarily when
+     * performing a short delayed show.
+     */
+    public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS =
+            "assist_handles_show_and_go_delayed_short_delay_ms";
+
+    /**
+     * (long) How long, in milliseconds, to wait before showing the Assist Handles temporarily when
+     * performing a long delayed show.
+     */
+    public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS =
+            "assist_handles_show_and_go_delayed_long_delay_ms";
+
+    /**
+     * (long) How long, in milliseconds, to wait before resetting delayed show delay times.
+     */
+    public static final String ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS =
+            "assist_handles_show_and_go_delay_reset_timeout_ms";
+
+    /**
      * (long) How long, in milliseconds, to wait before displaying Assist Handles temporarily after
      * hiding them.
      */
@@ -145,5 +165,122 @@
      */
     public static final String ASSIST_HANDLES_LEARN_COUNT = "assist_handles_learn_count";
 
+    /**
+     * (bool) Whether to suppress handles on lockscreen."
+     */
+    public static final String ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN =
+            "assist_handles_suppress_on_lockscreen";
+
+    /**
+     * (bool) Whether to suppress handles on launcher."
+     */
+    public static final String ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER =
+            "assist_handles_suppress_on_launcher";
+
+    /**
+     * (bool) Whether to suppress handles on apps."
+     */
+    public static final String ASSIST_HANDLES_SUPPRESS_ON_APPS =
+            "assist_handles_suppress_on_apps";
+
+    /**
+     * Allow touch passthrough above assist area during a session.
+     */
+    public static final String ASSIST_TAP_PASSTHROUGH = "assist_tap_passthrough";
+  
+    /**
+     * (bool) Whether to show handles when taught.
+     */
+    public static final String ASSIST_HANDLES_SHOW_WHEN_TAUGHT = "assist_handles_show_when_taught";
+
+    /**
+     * (bool) Whether to use the new BrightLineFalsingManager.
+     */
+    public static final String BRIGHTLINE_FALSING_MANAGER_ENABLED =
+            "brightline_falsing_manager_enabled";
+    /**
+     * (float) Maximum fraction of the screen required to qualify as a real swipe.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_SCREEN_FRACTION_MAX_DISTANCE =
+            "brightline_falsing_distance_screen_fraction_max_distance";
+
+    /**
+     * (float) Multiplier for swipe velocity to convert it to pixels for a fling.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_VELOCITY_TO_DISTANCE =
+            "brightline_falsing_distance_velcoity_to_distance";
+
+    /**
+     * (float) How far, in inches, must a fling travel horizontally to qualify as intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_FLING_THRESHOLD_IN =
+            "brightline_falsing_distance_horizontal_fling_threshold_in";
+
+    /**
+     * (float) Maximum fraction of the screen required to qualify as a real swipe.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_VERTICAL_FLING_THRESHOLD_IN =
+            "brightline_falsing_distance_vertical_fling_threshold_in";
+
+    /**
+     * (float) How far, in inches, must a continuous swipe travel horizontally to be intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_SWIPE_THRESHOLD_IN =
+            "brightline_falsing_distance_horizontal_swipe_threshold_in";
+
+    /**
+     * (float) How far, in inches, must a continuous swipe travel vertically to be intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN =
+            "brightline_falsing_distance_horizontal_swipe_threshold_in";
+
+    /**
+     * (float) Percentage of swipe with the proximity sensor covered that triggers a higher
+     * swipe distance requirement.
+     */
+    public static final String BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD =
+            "brightline_falsing_proximity_percent_covered_threshold";
+
+    /**
+     * (float) Angle, in radians, that a swipe can vary from horizontal and sill be intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DIAGONAL_HORIZONTAL_ANGLE_RANGE =
+            "brightline_falsing_diagonal_horizontal_angle_range";
+
+    /**
+     * (float) Angle, in radians, that a swipe can vary from vertical and sill be intentional.
+     */
+    public static final String BRIGHTLINE_FALSING_DIAGONAL_VERTICAL_ANGLE_RANGE =
+            "brightline_falsing_diagonal_horizontal_angle_range";
+
+    /**
+     * (float) Distance, in inches, that a swipe is allowed to vary in the horizontal direction for
+     * horizontal swipes.
+     */
+    public static final String BRIGHTLINE_FALSING_ZIGZAG_X_PRIMARY_DEVIANCE =
+            "brightline_falsing_zigzag_x_primary_deviance";
+
+    /**
+     * (float) Distance, in inches, that a swipe is allowed to vary in the vertical direction for
+     * vertical swipes.
+     */
+    public static final String BRIGHTLINE_FALSING_ZIGZAG_Y_PRIMARY_DEVIANCE =
+            "brightline_falsing_zigzag_y_primary_deviance";
+
+    /**
+     * (float) Distance, in inches, that a swipe is allowed to vary in the horizontal direction for
+     * horizontal swipes.
+     */
+    public static final String BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE =
+            "brightline_falsing_zigzag_x_secondary_deviance";
+
+    /**
+     * (float) Distance, in inches, that a swipe is allowed to vary in the vertical direction for
+     * vertical swipes.
+     */
+    public static final String BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE =
+            "brightline_falsing_zigzag_y_secondary_deviance";
+
+
     private SystemUiDeviceConfigFlags() { }
 }
diff --git a/core/java/com/android/internal/http/HttpDateTime.java b/core/java/com/android/internal/http/HttpDateTime.java
deleted file mode 100644
index f7706e3..0000000
--- a/core/java/com/android/internal/http/HttpDateTime.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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 com.android.internal.http;
-
-import android.annotation.UnsupportedAppUsage;
-import android.text.format.Time;
-
-import java.util.Calendar;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Helper for parsing an HTTP date.
- */
-public final class HttpDateTime {
-
-    /*
-     * Regular expression for parsing HTTP-date.
-     *
-     * Wdy, DD Mon YYYY HH:MM:SS GMT
-     * RFC 822, updated by RFC 1123
-     *
-     * Weekday, DD-Mon-YY HH:MM:SS GMT
-     * RFC 850, obsoleted by RFC 1036
-     *
-     * Wdy Mon DD HH:MM:SS YYYY
-     * ANSI C's asctime() format
-     *
-     * with following variations
-     *
-     * Wdy, DD-Mon-YYYY HH:MM:SS GMT
-     * Wdy, (SP)D Mon YYYY HH:MM:SS GMT
-     * Wdy,DD Mon YYYY HH:MM:SS GMT
-     * Wdy, DD-Mon-YY HH:MM:SS GMT
-     * Wdy, DD Mon YYYY HH:MM:SS -HHMM
-     * Wdy, DD Mon YYYY HH:MM:SS
-     * Wdy Mon (SP)D HH:MM:SS YYYY
-     * Wdy Mon DD HH:MM:SS YYYY GMT
-     * 
-     * HH can be H if the first digit is zero.
-     * 
-     * Mon can be the full name of the month.
-     */
-    private static final String HTTP_DATE_RFC_REGEXP =
-            "([0-9]{1,2})[- ]([A-Za-z]{3,9})[- ]([0-9]{2,4})[ ]"
-            + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])";
-
-    private static final String HTTP_DATE_ANSIC_REGEXP =
-            "[ ]([A-Za-z]{3,9})[ ]+([0-9]{1,2})[ ]"
-            + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})";
-
-    /**
-     * The compiled version of the HTTP-date regular expressions.
-     */
-    private static final Pattern HTTP_DATE_RFC_PATTERN =
-            Pattern.compile(HTTP_DATE_RFC_REGEXP);
-    private static final Pattern HTTP_DATE_ANSIC_PATTERN =
-            Pattern.compile(HTTP_DATE_ANSIC_REGEXP);
-
-    private static class TimeOfDay {
-        TimeOfDay(int h, int m, int s) {
-            this.hour = h;
-            this.minute = m;
-            this.second = s;
-        }
-        
-        int hour;
-        int minute;
-        int second;
-    }
-
-    @UnsupportedAppUsage
-    public static long parse(String timeString)
-            throws IllegalArgumentException {
-
-        int date = 1;
-        int month = Calendar.JANUARY;
-        int year = 1970;
-        TimeOfDay timeOfDay;
-
-        Matcher rfcMatcher = HTTP_DATE_RFC_PATTERN.matcher(timeString);
-        if (rfcMatcher.find()) {
-            date = getDate(rfcMatcher.group(1));
-            month = getMonth(rfcMatcher.group(2));
-            year = getYear(rfcMatcher.group(3));
-            timeOfDay = getTime(rfcMatcher.group(4));
-        } else {
-            Matcher ansicMatcher = HTTP_DATE_ANSIC_PATTERN.matcher(timeString);
-            if (ansicMatcher.find()) {
-                month = getMonth(ansicMatcher.group(1));
-                date = getDate(ansicMatcher.group(2));
-                timeOfDay = getTime(ansicMatcher.group(3));
-                year = getYear(ansicMatcher.group(4));
-            } else {
-                throw new IllegalArgumentException();
-            }
-        }
-
-        // FIXME: Y2038 BUG!
-        if (year >= 2038) {
-            year = 2038;
-            month = Calendar.JANUARY;
-            date = 1;
-        }
-
-        Time time = new Time(Time.TIMEZONE_UTC);
-        time.set(timeOfDay.second, timeOfDay.minute, timeOfDay.hour, date,
-                month, year);
-        return time.toMillis(false /* use isDst */);
-    }
-
-    private static int getDate(String dateString) {
-        if (dateString.length() == 2) {
-            return (dateString.charAt(0) - '0') * 10
-                    + (dateString.charAt(1) - '0');
-        } else {
-            return (dateString.charAt(0) - '0');
-        }
-    }
-
-    /*
-     * jan = 9 + 0 + 13 = 22
-     * feb = 5 + 4 + 1 = 10
-     * mar = 12 + 0 + 17 = 29
-     * apr = 0 + 15 + 17 = 32
-     * may = 12 + 0 + 24 = 36
-     * jun = 9 + 20 + 13 = 42
-     * jul = 9 + 20 + 11 = 40
-     * aug = 0 + 20 + 6 = 26
-     * sep = 18 + 4 + 15 = 37
-     * oct = 14 + 2 + 19 = 35
-     * nov = 13 + 14 + 21 = 48
-     * dec = 3 + 4 + 2 = 9
-     */
-    private static int getMonth(String monthString) {
-        int hash = Character.toLowerCase(monthString.charAt(0)) +
-                Character.toLowerCase(monthString.charAt(1)) +
-                Character.toLowerCase(monthString.charAt(2)) - 3 * 'a';
-        switch (hash) {
-            case 22:
-                return Calendar.JANUARY;
-            case 10:
-                return Calendar.FEBRUARY;
-            case 29:
-                return Calendar.MARCH;
-            case 32:
-                return Calendar.APRIL;
-            case 36:
-                return Calendar.MAY;
-            case 42:
-                return Calendar.JUNE;
-            case 40:
-                return Calendar.JULY;
-            case 26:
-                return Calendar.AUGUST;
-            case 37:
-                return Calendar.SEPTEMBER;
-            case 35:
-                return Calendar.OCTOBER;
-            case 48:
-                return Calendar.NOVEMBER;
-            case 9:
-                return Calendar.DECEMBER;
-            default:
-                throw new IllegalArgumentException();
-        }
-    }
-
-    private static int getYear(String yearString) {
-        if (yearString.length() == 2) {
-            int year = (yearString.charAt(0) - '0') * 10
-                    + (yearString.charAt(1) - '0');
-            if (year >= 70) {
-                return year + 1900;
-            } else {
-                return year + 2000;
-            }
-        } else if (yearString.length() == 3) {
-            // According to RFC 2822, three digit years should be added to 1900.
-            int year = (yearString.charAt(0) - '0') * 100
-                    + (yearString.charAt(1) - '0') * 10
-                    + (yearString.charAt(2) - '0');
-            return year + 1900;
-        } else if (yearString.length() == 4) {
-             return (yearString.charAt(0) - '0') * 1000
-                    + (yearString.charAt(1) - '0') * 100
-                    + (yearString.charAt(2) - '0') * 10
-                    + (yearString.charAt(3) - '0');
-        } else {
-             return 1970;
-        }
-    }
-
-    private static TimeOfDay getTime(String timeString) {
-        // HH might be H
-        int i = 0;
-        int hour = timeString.charAt(i++) - '0';
-        if (timeString.charAt(i) != ':')
-            hour = hour * 10 + (timeString.charAt(i++) - '0');
-        // Skip ':'
-        i++;
-        
-        int minute = (timeString.charAt(i++) - '0') * 10
-                    + (timeString.charAt(i++) - '0');
-        // Skip ':'
-        i++;
-        
-        int second = (timeString.charAt(i++) - '0') * 10
-                  + (timeString.charAt(i++) - '0');
-
-        return new TimeOfDay(hour, minute, second);        
-    }
-}
diff --git a/core/java/com/android/internal/infra/AndroidFuture.java b/core/java/com/android/internal/infra/AndroidFuture.java
index c7c2924..c8929e9 100644
--- a/core/java/com/android/internal/infra/AndroidFuture.java
+++ b/core/java/com/android/internal/infra/AndroidFuture.java
@@ -115,6 +115,20 @@
         }
     }
 
+    /**
+     * Create a completed future with the given value.
+     *
+     * @param value the value for the completed future
+     * @param <U> the type of the value
+     * @return the completed future
+     */
+    @NonNull
+    public static <U> AndroidFuture<U> completedFuture(U value) {
+        AndroidFuture<U> future = new AndroidFuture<>();
+        future.complete(value);
+        return future;
+    }
+
     @Override
     public boolean complete(@Nullable T value) {
         boolean changed = super.complete(value);
diff --git a/core/java/com/android/internal/infra/ServiceConnector.java b/core/java/com/android/internal/infra/ServiceConnector.java
index 283079a..d6862f0 100644
--- a/core/java/com/android/internal/infra/ServiceConnector.java
+++ b/core/java/com/android/internal/infra/ServiceConnector.java
@@ -228,7 +228,7 @@
         private final int mUserId;
         private final @Nullable Function<IBinder, I> mBinderAsInterface;
 
-        private I mService = null;
+        private volatile I mService = null;
         private boolean mBinding = false;
         private boolean mUnbinding = false;
 
@@ -506,11 +506,12 @@
 
         void unbindJobThread() {
             cancelTimeout();
-            boolean wasBound = isBound();
+            I service = mService;
+            boolean wasBound = service != null;
             if (wasBound) {
-                onServiceConnectionStatusChanged(mService, false);
+                onServiceConnectionStatusChanged(service, false);
                 mContext.unbindService(mServiceConnection);
-                mService.asBinder().unlinkToDeath(this, 0);
+                service.asBinder().unlinkToDeath(this, 0);
                 mService = null;
             }
             mBinding = false;
@@ -543,7 +544,7 @@
         }
 
         @Override
-        public void onServiceConnected(@NonNull ComponentName name, @NonNull IBinder service) {
+        public void onServiceConnected(@NonNull ComponentName name, @NonNull IBinder binder) {
             if (mUnbinding) {
                 Log.i(LOG_TAG, "Ignoring onServiceConnected due to ongoing unbinding: " + this);
                 return;
@@ -551,15 +552,16 @@
             if (DEBUG) {
                 logTrace();
             }
-            mService = binderAsInterface(service);
+            I service = binderAsInterface(binder);
+            mService = service;
             mBinding = false;
             try {
-                service.linkToDeath(ServiceConnector.Impl.this, 0);
+                binder.linkToDeath(ServiceConnector.Impl.this, 0);
             } catch (RemoteException e) {
                 Log.e(LOG_TAG, "onServiceConnected " + name + ": ", e);
             }
+            onServiceConnectionStatusChanged(service, true);
             processQueue();
-            onServiceConnectionStatusChanged(mService, true);
         }
 
         @Override
@@ -568,8 +570,11 @@
                 logTrace();
             }
             mBinding = true;
-            onServiceConnectionStatusChanged(mService, false);
-            mService = null;
+            I service = mService;
+            if (service != null) {
+                onServiceConnectionStatusChanged(service, false);
+                mService = null;
+            }
         }
 
         @Override
diff --git a/core/java/com/android/internal/infra/ThrottledRunnable.java b/core/java/com/android/internal/infra/ThrottledRunnable.java
new file mode 100644
index 0000000..9846fa9
--- /dev/null
+++ b/core/java/com/android/internal/infra/ThrottledRunnable.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os.Handler;
+import android.os.SystemClock;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * A throttled runnable that can wrap around a runnable and throttle calls to its run().
+ *
+ * The throttling logic makes sure that the original runnable will be called only after the
+ * specified interval passes since the last actual call. The first call in a while (after the
+ * specified interval passes since the last actual call) will always result in the original runnable
+ * being called immediately, and then subsequent calls will start to be throttled. It is guaranteed
+ * that any call to this throttled runnable will always result in the original runnable being called
+ * afterwards, within the specified interval.
+ */
+public class ThrottledRunnable implements Runnable {
+
+    @NonNull
+    private final Handler mHandler;
+    private final long mIntervalMillis;
+    @NonNull
+    private final Runnable mRunnable;
+
+    @NonNull
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private long mScheduledUptimeMillis;
+
+    public ThrottledRunnable(@NonNull Handler handler, long intervalMillis,
+            @NonNull Runnable runnable) {
+        mHandler = handler;
+        mIntervalMillis = intervalMillis;
+        mRunnable = runnable;
+    }
+
+    @Override
+    public void run() {
+        synchronized (mLock) {
+            if (mHandler.hasCallbacks(mRunnable)) {
+                // We have a scheduled runnable.
+                return;
+            }
+            long currentUptimeMillis = SystemClock.uptimeMillis();
+            if (mScheduledUptimeMillis == 0
+                    || currentUptimeMillis > mScheduledUptimeMillis + mIntervalMillis) {
+                // First time in a while, schedule immediately.
+                mScheduledUptimeMillis = currentUptimeMillis;
+            } else {
+                // We were scheduled not long ago, so schedule with delay for throttling.
+                mScheduledUptimeMillis = mScheduledUptimeMillis + mIntervalMillis;
+            }
+            mHandler.postAtTime(mRunnable, mScheduledUptimeMillis);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index a35e42e..91ef0b5 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -38,6 +38,7 @@
     public static String CAR_MODE = "CAR_MODE";
     public static String ACCOUNT = "ACCOUNT";
     public static String DEVELOPER = "DEVELOPER";
+    public static String DEVELOPER_IMPORTANT = "DEVELOPER_IMPORTANT";
     public static String UPDATES = "UPDATES";
     public static String NETWORK_STATUS = "NETWORK_STATUS";
     public static String NETWORK_ALERTS = "NETWORK_ALERTS";
@@ -98,6 +99,13 @@
         developer.setBlockableSystem(true);
         channelsList.add(developer);
 
+        final NotificationChannel developerImportant = new NotificationChannel(
+                DEVELOPER_IMPORTANT,
+                context.getString(R.string.notification_channel_developer_important),
+                NotificationManager.IMPORTANCE_HIGH);
+        developer.setBlockableSystem(true);
+        channelsList.add(developerImportant);
+
         final NotificationChannel updates = new NotificationChannel(
                 UPDATES,
                 context.getString(R.string.notification_channel_updates),
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index 24ad751..392f074 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -28,7 +28,6 @@
 
 import java.io.File;
 import java.io.FilenameFilter;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -138,11 +137,12 @@
         if (!dedup.isEmpty()) {
             mFileNumbers.addAll(dedup);
             Collections.sort(mFileNumbers);
+            setActiveFile(mFileNumbers.get(mFileNumbers.size() - 1));
         } else {
             // No file found, default to have file 0.
             mFileNumbers.add(0);
+            setActiveFile(0);
         }
-        createActiveFile();
     }
 
     /**
@@ -157,22 +157,15 @@
         mHistoryBuffer = historyBuffer;
     }
     /**
-     * The highest numbered history file is active file that mHistoryBuffer is backed up into.
-     * If file does not exists, truncate() creates a empty file.
+     * Set the active file that mHistoryBuffer is backed up into.
+     *
+     * @param fileNumber the history file that mHistoryBuffer is backed up into.
      */
-    private void createActiveFile() {
-        final AtomicFile file = getFile(mFileNumbers.get(mFileNumbers.size() - 1));
+    private void setActiveFile(int fileNumber) {
+        mActiveFile = getFile(fileNumber);
         if (DEBUG) {
-            Slog.d(TAG, "activeHistoryFile:" + file.getBaseFile().getPath());
+            Slog.d(TAG, "activeHistoryFile:" + mActiveFile.getBaseFile().getPath());
         }
-        if (!file.exists()) {
-            try {
-                file.truncate();
-            } catch (IOException e) {
-                Slog.e(TAG, "Error creating history file "+ file.getBaseFile().getPath(), e);
-            }
-        }
-        mActiveFile = file;
     }
 
     /**
@@ -189,7 +182,7 @@
      * When {@link #mHistoryBuffer} reaches {@link BatteryStatsImpl.Constants#MAX_HISTORY_BUFFER},
      * create next history file.
      */
-    public void createNextFile() {
+    public void startNextFile() {
         if (mFileNumbers.isEmpty()) {
             Slog.wtf(TAG, "mFileNumbers should never be empty");
             return;
@@ -198,7 +191,7 @@
         // number plus one.
         final int next = mFileNumbers.get(mFileNumbers.size() - 1) + 1;
         mFileNumbers.add(next);
-        createActiveFile();
+        setActiveFile(next);
 
         // if free disk space is less than 100MB, delete oldest history file.
         if (!hasFreeDiskSpace()) {
@@ -224,7 +217,7 @@
         }
         mFileNumbers.clear();
         mFileNumbers.add(0);
-        createActiveFile();
+        setActiveFile(0);
     }
 
     /**
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 81b71af..88d0e85 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -188,6 +188,7 @@
     static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
 
     private static final double MILLISECONDS_IN_HOUR = 3600 * 1000;
+    private static final long MILLISECONDS_IN_YEAR = 365 * 24 * 3600 * 1000L;
 
     private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
     private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
@@ -3477,10 +3478,8 @@
         if (deltaTimeToken < DELTA_TIME_ABS) {
             cur.time += deltaTimeToken;
         } else if (deltaTimeToken == DELTA_TIME_ABS) {
-            cur.time = src.readLong();
-            cur.numReadInts += 2;
-            if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
             cur.readFromParcel(src);
+            if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
             return;
         } else if (deltaTimeToken == DELTA_TIME_INT) {
             int delta = src.readInt();
@@ -3606,8 +3605,8 @@
 
     public void createFakeHistoryEvents(long numEvents) {
         for(long i = 0; i < numEvents; i++) {
-            noteWifiOnLocked();
-            noteWifiOffLocked();
+            noteLongPartialWakelockStart("name1", "historyName1", 1000);
+            noteLongPartialWakelockFinish("name1", "historyName1", 1000);
         }
     }
 
@@ -3683,16 +3682,17 @@
                 Slog.d(TAG, "addHistoryBufferLocked writeHistoryLocked takes ms:"
                         + (SystemClock.uptimeMillis() - start));
             }
-            mBatteryStatsHistory.createNextFile();
+            mBatteryStatsHistory.startNextFile();
             mHistoryBuffer.setDataSize(0);
             mHistoryBuffer.setDataPosition(0);
             mHistoryBuffer.setDataCapacity(mConstants.MAX_HISTORY_BUFFER / 2);
             mHistoryBufferLastPos = -1;
             final long elapsedRealtime = mClocks.elapsedRealtime();
             final long uptime = mClocks.uptimeMillis();
+            HistoryItem newItem = new HistoryItem();
+            newItem.setTo(cur);
             startRecordingHistory(elapsedRealtime, uptime, false);
-
-            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur);
+            addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem);
             return;
         }
 
@@ -3953,25 +3953,11 @@
         addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
     }
 
-    boolean ensureStartClockTime(final long currentTime) {
-        final long ABOUT_ONE_YEAR = 365*24*60*60*1000L;
-        if ((currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR))
-                || (mStartClockTime > currentTime)) {
-            // If the start clock time has changed by more than a year, then presumably
-            // the previous time was completely bogus.  So we are going to figure out a
-            // new time based on how much time has elapsed since we started counting.
-            mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000));
-            return true;
-        }
-        return false;
-    }
-
     public void noteCurrentTimeChangedLocked() {
         final long currentTime = System.currentTimeMillis();
         final long elapsedRealtime = mClocks.elapsedRealtime();
         final long uptime = mClocks.uptimeMillis();
         recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
-        ensureStartClockTime(currentTime);
     }
 
     public void noteProcessStartLocked(String name, int uid) {
@@ -6460,9 +6446,15 @@
 
     @Override public long getStartClockTime() {
         final long currentTime = System.currentTimeMillis();
-        if (ensureStartClockTime(currentTime)) {
+        if ((currentTime > MILLISECONDS_IN_YEAR
+                && mStartClockTime < (currentTime - MILLISECONDS_IN_YEAR))
+                || (mStartClockTime > currentTime)) {
+            // If the start clock time has changed by more than a year, then presumably
+            // the previous time was completely bogus.  So we are going to figure out a
+            // new time based on how much time has elapsed since we started counting.
             recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(),
                     mClocks.uptimeMillis());
+            return currentTime - (mClocks.elapsedRealtime() - (mRealtimeStart / 1000));
         }
         return mStartClockTime;
     }
@@ -13465,9 +13457,8 @@
             return;
         }
         mHistory = mHistoryEnd = mHistoryCache = null;
-        long time;
-        while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
-            HistoryItem rec = new HistoryItem(time, in);
+        while (in.dataAvail() > 0) {
+            HistoryItem rec = new HistoryItem(in);
             addHistoryRecordLocked(rec);
         }
     }
@@ -14019,7 +14010,7 @@
 
         // Pull the clock time.  This may update the time and make a new history entry
         // if we had originally pulled a time before the RTC was set.
-        long startClockTime = getStartClockTime();
+        getStartClockTime();
 
         final long NOW_SYS = mClocks.uptimeMillis() * 1000;
         final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000;
@@ -14043,7 +14034,7 @@
         out.writeInt(mStartCount);
         out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
         out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
-        out.writeLong(startClockTime);
+        out.writeLong(mStartClockTime);
         out.writeString(mStartPlatformVersion);
         out.writeString(mEndPlatformVersion);
         mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
@@ -14755,7 +14746,7 @@
 
         // Pull the clock time.  This may update the time and make a new history entry
         // if we had originally pulled a time before the RTC was set.
-        long startClockTime = getStartClockTime();
+        getStartClockTime();
 
         final long uSecUptime = mClocks.uptimeMillis() * 1000;
         final long uSecRealtime = mClocks.elapsedRealtime() * 1000;
@@ -14768,7 +14759,7 @@
         mBatteryStatsHistory.writeToParcel(out);
 
         out.writeInt(mStartCount);
-        out.writeLong(startClockTime);
+        out.writeLong(mStartClockTime);
         out.writeString(mStartPlatformVersion);
         out.writeString(mEndPlatformVersion);
         out.writeLong(mUptime);
diff --git a/core/java/com/android/internal/os/BinderDeathDispatcher.java b/core/java/com/android/internal/os/BinderDeathDispatcher.java
new file mode 100644
index 0000000..0c93f7f
--- /dev/null
+++ b/core/java/com/android/internal/os/BinderDeathDispatcher.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.NonNull;
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.IInterface;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+/**
+ * Multiplexes multiple binder death recipients on the same binder objects, so that at the native
+ * level, we only need to keep track of one death recipient reference. This will help reduce the
+ * number of JNI strong references.
+ *
+ * test with: atest FrameworksCoreTests:BinderDeathDispatcherTest
+ */
+public class BinderDeathDispatcher<T extends IInterface> {
+    private static final String TAG = "BinderDeathDispatcher";
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final ArrayMap<IBinder, RecipientsInfo> mTargets = new ArrayMap<>();
+
+    @VisibleForTesting
+    class RecipientsInfo implements DeathRecipient {
+        final IBinder mTarget;
+
+        /**
+         * Recipient list. If it's null, {@link #mTarget} has already died, but in that case
+         * this RecipientsInfo instance is removed from {@link #mTargets}.
+         */
+        @GuardedBy("mLock")
+        @Nullable
+        ArraySet<DeathRecipient> mRecipients = new ArraySet<>();
+
+        private RecipientsInfo(IBinder target) {
+            mTarget = target;
+        }
+
+        @Override
+        public void binderDied() {
+            final ArraySet<DeathRecipient> copy;
+            synchronized (mLock) {
+                copy = mRecipients;
+                mRecipients = null;
+
+                // Also remove from the targets.
+                mTargets.remove(mTarget);
+            }
+            if (copy == null) {
+                return;
+            }
+            // Let's call it without holding the lock.
+            final int size = copy.size();
+            for (int i = 0; i < size; i++) {
+                copy.valueAt(i).binderDied();
+            }
+        }
+    }
+
+    /**
+     * Add a {@code recipient} to the death recipient list on {@code target}.
+     *
+     * @return # of recipients in the recipient list, including {@code recipient}. Or, -1
+     * if {@code target} is already dead, in which case recipient's
+     * {@link DeathRecipient#binderDied} won't be called.
+     */
+    public int linkToDeath(@NonNull T target, @NonNull DeathRecipient recipient) {
+        final IBinder ib = target.asBinder();
+        synchronized (mLock) {
+            RecipientsInfo info = mTargets.get(ib);
+            if (info == null) {
+                info = new RecipientsInfo(ib);
+
+                // First recipient; need to link to death.
+                try {
+                    ib.linkToDeath(info, 0);
+                } catch (RemoteException e) {
+                    return -1; // Already dead.
+                }
+                mTargets.put(ib, info);
+            }
+            info.mRecipients.add(recipient);
+            return info.mRecipients.size();
+        }
+    }
+
+    public void unlinkToDeath(@NonNull T target, @NonNull DeathRecipient recipient) {
+        final IBinder ib = target.asBinder();
+
+        synchronized (mLock) {
+            final RecipientsInfo info = mTargets.get(ib);
+            if (info == null) {
+                return;
+            }
+            if (info.mRecipients.remove(recipient) && info.mRecipients.size() == 0) {
+                info.mTarget.unlinkToDeath(info, 0);
+                mTargets.remove(info.mTarget);
+            }
+        }
+    }
+
+    public void dump(PrintWriter pw, String indent) {
+        synchronized (mLock) {
+            pw.print(indent);
+            pw.print("# of watched binders: ");
+            pw.println(mTargets.size());
+
+            pw.print(indent);
+            pw.print("# of death recipients: ");
+            int n = 0;
+            for (RecipientsInfo info : mTargets.values()) {
+                n += info.mRecipients.size();
+            }
+            pw.println(n);
+        }
+    }
+
+    @VisibleForTesting
+    public ArrayMap<IBinder, RecipientsInfo> getTargetsForTest() {
+        return mTargets;
+    }
+}
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 8b25e2d..3ac58e0 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -16,8 +16,13 @@
 package com.android.internal.os;
 
 import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.StrictMode;
 import android.os.SystemClock;
+import android.system.suspend.ISuspendControlService;
+import android.system.suspend.WakeLockInfo;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -58,6 +63,7 @@
 
     private final String[] mProcWakelocksName = new String[3];
     private final long[] mProcWakelocksData = new long[3];
+    private ISuspendControlService mSuspendControlService = null;
 
     /**
      * Reads kernel wakelock stats and updates the staleStats with the new information.
@@ -117,7 +123,52 @@
                 }
             }
         }
-        return parseProcWakelocks(buffer, len, wakeup_sources, staleStats);
+
+        updateVersion(staleStats);
+
+        parseProcWakelocks(buffer, len, wakeup_sources, staleStats);
+
+        if (mSuspendControlService == null) {
+            try {
+                mSuspendControlService = ISuspendControlService.Stub.asInterface(
+                    ServiceManager.getServiceOrThrow("suspend_control"));
+            } catch (ServiceNotFoundException e) {
+                Slog.wtf(TAG, "Required service suspend_control not available", e);
+            }
+        }
+
+        try {
+            WakeLockInfo[] wlStats = mSuspendControlService.getWakeLockStats();
+            getNativeWakelockStats(wlStats, staleStats);
+        } catch (RemoteException e) {
+            Slog.wtf(TAG, "Failed to obtain wakelock stats from ISuspendControlService", e);
+        }
+
+        return removeOldStats(staleStats);
+    }
+
+    /**
+     * Reads native wakelock stats from SystemSuspend and updates staleStats with the new
+     * information.
+     * @param staleStats Existing object to update.
+     * @return the updated stats.
+     */
+    @VisibleForTesting
+    public KernelWakelockStats getNativeWakelockStats(WakeLockInfo[] wlStats,
+                                                      final KernelWakelockStats staleStats) {
+        for (WakeLockInfo info : wlStats) {
+            if (!staleStats.containsKey(info.name)) {
+                staleStats.put(info.name, new KernelWakelockStats.Entry((int) info.activeCount,
+                        info.totalTime, sKernelWakelockUpdateVersion));
+            } else {
+                KernelWakelockStats.Entry kwlStats = staleStats.get(info.name);
+                kwlStats.mCount = (int) info.activeCount;
+                kwlStats.mTotalTime = info.totalTime;
+                kwlStats.mVersion = sKernelWakelockUpdateVersion;
+            }
+        }
+
+        return staleStats;
     }
 
     /**
@@ -138,7 +189,6 @@
         startIndex = endIndex = i + 1;
 
         synchronized(this) {
-            sKernelWakelockUpdateVersion++;
             while (endIndex < len) {
                 for (endIndex=startIndex;
                         endIndex < len && wlBuffer[endIndex] != '\n' && wlBuffer[endIndex] != '\0';
@@ -199,16 +249,35 @@
                 startIndex = endIndex + 1;
             }
 
-            // Don't report old data.
-            Iterator<KernelWakelockStats.Entry> itr = staleStats.values().iterator();
-            while (itr.hasNext()) {
-                if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
-                    itr.remove();
-                }
-            }
-
-            staleStats.kernelWakelockVersion = sKernelWakelockUpdateVersion;
             return staleStats;
         }
     }
+
+    /**
+     * Increments sKernelWakelockUpdateVersion and updates the version in staleStats.
+     * @param staleStats Existing object to update.
+     * @return the updated stats.
+     */
+    @VisibleForTesting
+    public KernelWakelockStats updateVersion(KernelWakelockStats staleStats) {
+        sKernelWakelockUpdateVersion++;
+        staleStats.kernelWakelockVersion = sKernelWakelockUpdateVersion;
+        return staleStats;
+    }
+
+    /**
+     * Removes old stats from staleStats.
+     * @param staleStats Existing object to update.
+     * @return the updated stats.
+     */
+    @VisibleForTesting
+    public KernelWakelockStats removeOldStats(final KernelWakelockStats staleStats) {
+        Iterator<KernelWakelockStats.Entry> itr = staleStats.values().iterator();
+        while (itr.hasNext()) {
+            if (itr.next().mVersion != sKernelWakelockUpdateVersion) {
+                itr.remove();
+            }
+        }
+        return staleStats;
+    }
 }
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index eac150d..1de2e72 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -64,6 +64,19 @@
         return Log.printlns(Log.LOG_ID_CRASH, Log.ERROR, tag, msg, tr);
     }
 
+    public static void logUncaught(String threadName, String processName, int pid, Throwable e) {
+        StringBuilder message = new StringBuilder();
+        // The "FATAL EXCEPTION" string is still used on Android even though
+        // apps can set a custom UncaughtExceptionHandler that renders uncaught
+        // exceptions non-fatal.
+        message.append("FATAL EXCEPTION: ").append(threadName).append("\n");
+        if (processName != null) {
+            message.append("Process: ").append(processName).append(", ");
+        }
+        message.append("PID: ").append(pid);
+        Clog_e(TAG, message.toString(), e);
+    }
+
     /**
      * Logs a message when a thread encounters an uncaught exception. By
      * default, {@link KillApplicationHandler} will terminate this process later,
@@ -85,17 +98,7 @@
             if (mApplicationObject == null && (Process.SYSTEM_UID == Process.myUid())) {
                 Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
             } else {
-                StringBuilder message = new StringBuilder();
-                // The "FATAL EXCEPTION" string is still used on Android even though
-                // apps can set a custom UncaughtExceptionHandler that renders uncaught
-                // exceptions non-fatal.
-                message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
-                final String processName = ActivityThread.currentProcessName();
-                if (processName != null) {
-                    message.append("Process: ").append(processName).append(", ");
-                }
-                message.append("PID: ").append(Process.myPid());
-                Clog_e(TAG, message.toString(), e);
+                logUncaught(t.getName(), ActivityThread.currentProcessName(), Process.myPid(), e);
             }
         }
     }
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 722ca6d..9d4cdc7 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -106,6 +106,14 @@
      */
     public static final int USE_APP_IMAGE_STARTUP_CACHE = 1 << 16;
 
+    /**
+     * When set, application specified signal handlers are not chained (i.e, ignored)
+     * by the runtime.
+     *
+     * Used for debugging only. Usage: set debug.ignoreappsignalhandler to 1.
+     */
+    public static final int DEBUG_IGNORE_APP_SIGNAL_HANDLER = 1 << 17;
+
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
     /** Default external storage should be mounted. */
@@ -130,6 +138,9 @@
     /** Number of bytes sent to the Zygote over USAP pipes or the pool event FD */
     static final int USAP_MANAGEMENT_MESSAGE_BYTES = 8;
 
+    /** Make the new process have top application priority. */
+    public static final String START_AS_TOP_APP_ARG = "--is-top-app";
+
     /**
      * An extraArg passed when a zygote process is forking a child-zygote, specifying a name
      * in the abstract socket namespace. This socket name is what the new child zygote
@@ -172,6 +183,11 @@
      */
     public static final int SOCKET_BUFFER_SIZE = 256;
 
+    /**
+     * @hide for internal use only
+     */
+    private static final int PRIORITY_MAX = -20;
+
     /** a prototype instance for a future List.toArray() */
     static final int[][] INT_ARRAY_2D = new int[0][0];
 
@@ -227,6 +243,7 @@
      * new zygote process.
      * @param instructionSet null-ok the instruction set to use.
      * @param appDataDir null-ok the data directory of the app.
+     * @param isTopApp true if the process is for top (high priority) application.
      *
      * @return 0 if this is the child, pid of the child
      * if this is the parent, or -1 on error.
@@ -234,13 +251,12 @@
     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,
-            int targetSdkVersion) {
+            int targetSdkVersion, boolean isTopApp) {
         ZygoteHooks.preFork();
-        // Resets nice priority for zygote process.
-        resetNicePriority();
+
         int pid = nativeForkAndSpecialize(
                 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
-                fdsToIgnore, startChildZygote, instructionSet, appDataDir);
+                fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp);
         // Enable tracing as soon as possible for the child process.
         if (pid == 0) {
             Zygote.disableExecuteOnly(targetSdkVersion);
@@ -249,6 +265,10 @@
             // Note that this event ends at the end of handleChildProc,
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
         }
+
+        // Set the Java Language thread priority to the default value for new apps.
+        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
+
         ZygoteHooks.postForkCommon();
         return pid;
     }
@@ -256,7 +276,7 @@
     private static native int nativeForkAndSpecialize(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 appDataDir, boolean isTopApp);
 
     /**
      * Specialize an unspecialized app process.  The current VM must have been started
@@ -278,12 +298,13 @@
      * new zygote process.
      * @param instructionSet null-ok  The instruction set to use.
      * @param appDataDir null-ok  The data directory of the app.
+     * @param isTopApp  True if the process is for top (high priority) application.
      */
     private static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, int mountExternal, String seInfo, String niceName,
-            boolean startChildZygote, String instructionSet, String appDataDir) {
+            boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp) {
         nativeSpecializeAppProcess(uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo,
-                                 niceName, startChildZygote, instructionSet, appDataDir);
+                niceName, startChildZygote, instructionSet, appDataDir, isTopApp);
 
         // Enable tracing as soon as possible for the child process.
         Trace.setTracingEnabled(true, runtimeFlags);
@@ -291,6 +312,9 @@
         // Note that this event ends at the end of handleChildProc.
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
 
+        // Set the Java Language thread priority to the default value for new apps.
+        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
+
         /*
          * This is called here (instead of after the fork but before the specialize) to maintain
          * consistancy with the code paths for forkAndSpecialize.
@@ -302,7 +326,7 @@
 
     private static native void nativeSpecializeAppProcess(int uid, int gid, int[] gids,
             int runtimeFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName,
-            boolean startChildZygote, String instructionSet, String appDataDir);
+            boolean startChildZygote, String instructionSet, String appDataDir, boolean isTopApp);
 
     /**
      * Called to do any initialization before starting an application.
@@ -335,15 +359,19 @@
     static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
         ZygoteHooks.preFork();
-        // Resets nice priority for zygote process.
-        resetNicePriority();
+
         int pid = nativeForkSystemServer(
                 uid, gid, gids, runtimeFlags, rlimits,
                 permittedCapabilities, effectiveCapabilities);
+
         // Enable tracing as soon as we enter the system_server.
         if (pid == 0) {
             Trace.setTracingEnabled(true, runtimeFlags);
         }
+
+        // Set the Java Language thread priority to the default value for new apps.
+        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
+
         ZygoteHooks.postForkCommon();
         return pid;
     }
@@ -461,13 +489,16 @@
     /**
      * Fork a new unspecialized app process from the zygote
      *
+     * @param usapPoolSocket  The server socket the USAP will call accept on
      * @param sessionSocketRawFDs  Anonymous session sockets that are currently open
+     * @param isPriorityFork  Value controlling the process priority level until accept is called
      * @return In the Zygote process this function will always return null; in unspecialized app
      *         processes this function will return a Runnable object representing the new
      *         application that is passed up from usapMain.
      */
     static Runnable forkUsap(LocalServerSocket usapPoolSocket,
-                             int[] sessionSocketRawFDs) {
+                             int[] sessionSocketRawFDs,
+                             boolean isPriorityFork) {
         FileDescriptor[] pipeFDs = null;
 
         try {
@@ -477,7 +508,8 @@
         }
 
         int pid =
-                nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(), sessionSocketRawFDs);
+                nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(),
+                               sessionSocketRawFDs, isPriorityFork);
 
         if (pid == 0) {
             IoUtils.closeQuietly(pipeFDs[0]);
@@ -491,8 +523,9 @@
     }
 
     private static native int nativeForkUsap(int readPipeFD,
-                                                 int writePipeFD,
-                                                 int[] sessionSocketRawFDs);
+                                             int writePipeFD,
+                                             int[] sessionSocketRawFDs,
+                                             boolean isPriorityFork);
 
     /**
      * This function is used by unspecialized app processes to wait for specialization requests from
@@ -512,13 +545,18 @@
         Credentials peerCredentials = null;
         ZygoteArguments args = null;
 
-        // Load resources
-        ZygoteInit.nativePreloadGraphicsDriver();
+        // Change the priority to max before calling accept so we can respond to new specialization
+        // requests as quickly as possible.  This will be reverted to the default priority in the
+        // native specialization code.
+        boostUsapPriority();
 
         while (true) {
             try {
                 sessionSocket = usapPoolSocket.accept();
 
+                // Block SIGTERM so we won't be killed if the Zygote flushes the USAP pool.
+                blockSigTerm();
+
                 BufferedReader usapReader =
                         new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
                 usapOutputStream =
@@ -537,86 +575,119 @@
                 } else {
                     Log.e("USAP", "Truncated command received.");
                     IoUtils.closeQuietly(sessionSocket);
+
+                    // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary.
+                    unblockSigTerm();
                 }
             } catch (Exception ex) {
                 Log.e("USAP", ex.getMessage());
                 IoUtils.closeQuietly(sessionSocket);
+
+                // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary.
+                unblockSigTerm();
             }
         }
 
-        setAppProcessName(args, "USAP");
-
-        applyUidSecurityPolicy(args, peerCredentials);
-        applyDebuggerSystemProperty(args);
-
-        int[][] rlimits = null;
-
-        if (args.mRLimits != null) {
-            rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
-        }
-
-        // This must happen before the SELinux policy for this process is
-        // changed when specializing.
         try {
-            // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
-            // Process.ProcessStartResult object.
-            usapOutputStream.writeInt(pid);
-        } catch (IOException ioEx) {
-            Log.e("USAP", "Failed to write response to session socket: " + ioEx.getMessage());
-            System.exit(-1);
-        } finally {
-            IoUtils.closeQuietly(sessionSocket);
+            // SIGTERM is blocked on loop exit.  This prevents a USAP that is specializing from
+            // being killed during a pool flush.
+
+            setAppProcessName(args, "USAP");
+
+            applyUidSecurityPolicy(args, peerCredentials);
+            applyDebuggerSystemProperty(args);
+
+            int[][] rlimits = null;
+
+            if (args.mRLimits != null) {
+                rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
+            }
+
+            // This must happen before the SELinux policy for this process is
+            // changed when specializing.
+            try {
+                // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
+                // Process.ProcessStartResult object.
+                usapOutputStream.writeInt(pid);
+            } catch (IOException ioEx) {
+                Log.e("USAP", "Failed to write response to session socket: "
+                        + ioEx.getMessage());
+                throw new RuntimeException(ioEx);
+            } finally {
+                IoUtils.closeQuietly(sessionSocket);
+
+                try {
+                    // This socket is closed using Os.close due to an issue with the implementation
+                    // of LocalSocketImp.close().  Because the raw FD is created by init and then
+                    // loaded from an environment variable (as opposed to being created by the
+                    // LocalSocketImpl itself) the current implementation will not actually close
+                    // the underlying FD.
+                    //
+                    // See b/130309968 for discussion of this issue.
+                    Os.close(usapPoolSocket.getFileDescriptor());
+                } catch (ErrnoException ex) {
+                    Log.e("USAP", "Failed to close USAP pool socket");
+                    throw new RuntimeException(ex);
+                }
+            }
 
             try {
-                // This socket is closed using Os.close due to an issue with the implementation of
-                // LocalSocketImp.close.  Because the raw FD is created by init and then loaded from
-                // an environment variable (as opposed to being created by the LocalSocketImpl
-                // itself) the current implementation will not actually close the underlying FD.
-                //
-                // See b/130309968 for discussion of this issue.
-                Os.close(usapPoolSocket.getFileDescriptor());
-            } catch (ErrnoException ex) {
-                Log.e("USAP", "Failed to close USAP pool socket");
+                ByteArrayOutputStream buffer =
+                        new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES);
+                DataOutputStream outputStream = new DataOutputStream(buffer);
+
+                // This is written as a long so that the USAP reporting pipe and USAP pool event FD
+                // handlers in ZygoteServer.runSelectLoop can be unified.  These two cases should
+                // both send/receive 8 bytes.
+                outputStream.writeLong(pid);
+                outputStream.flush();
+
+                Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
+            } catch (Exception ex) {
+                Log.e("USAP",
+                        String.format("Failed to write PID (%d) to pipe (%d): %s",
+                                pid, writePipe.getInt$(), ex.getMessage()));
                 throw new RuntimeException(ex);
+            } finally {
+                IoUtils.closeQuietly(writePipe);
             }
-        }
 
-        try {
-            ByteArrayOutputStream buffer =
-                    new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES);
-            DataOutputStream outputStream = new DataOutputStream(buffer);
+            specializeAppProcess(args.mUid, args.mGid, args.mGids,
+                                 args.mRuntimeFlags, rlimits, args.mMountExternal,
+                                 args.mSeInfo, args.mNiceName, args.mStartChildZygote,
+                                 args.mInstructionSet, args.mAppDataDir, args.mIsTopApp);
 
-            // This is written as a long so that the USAP reporting pipe and USAP pool event FD
-            // handlers in ZygoteServer.runSelectLoop can be unified.  These two cases should both
-            // send/receive 8 bytes.
-            outputStream.writeLong(pid);
-            outputStream.flush();
+            disableExecuteOnly(args.mTargetSdkVersion);
 
-            Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
-        } catch (Exception ex) {
-            Log.e("USAP",
-                    String.format("Failed to write PID (%d) to pipe (%d): %s",
-                            pid, writePipe.getInt$(), ex.getMessage()));
-            System.exit(-1);
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
+            return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
+                                         args.mRemainingArgs,
+                                         null /* classLoader */);
         } finally {
-            IoUtils.closeQuietly(writePipe);
+            // Unblock SIGTERM to restore the process to default behavior.
+            unblockSigTerm();
         }
-
-        specializeAppProcess(args.mUid, args.mGid, args.mGids,
-                             args.mRuntimeFlags, rlimits, args.mMountExternal,
-                             args.mSeInfo, args.mNiceName, args.mStartChildZygote,
-                             args.mInstructionSet, args.mAppDataDir);
-
-        disableExecuteOnly(args.mTargetSdkVersion);
-
-        // End of the postFork event.
-        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-
-        return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
-                                     args.mRemainingArgs,
-                                     null /* classLoader */);
     }
 
+    private static void blockSigTerm() {
+        nativeBlockSigTerm();
+    }
+
+    private static native void nativeBlockSigTerm();
+
+    private static void unblockSigTerm() {
+        nativeUnblockSigTerm();
+    }
+
+    private static native void nativeUnblockSigTerm();
+
+    private static void boostUsapPriority() {
+        nativeBoostUsapPriority();
+    }
+
+    private static native void nativeBoostUsapPriority();
+
     static void setAppProcessName(ZygoteArguments args, String loggingTag) {
         if (args.mNiceName != null) {
             Process.setArgV0(args.mNiceName);
@@ -776,17 +847,32 @@
     }
 
     /**
+     * Gets the wrap property if set.
+     *
+     * @param appName the application name to check
+     * @return value of wrap property or null if property not set or
+     * null if app_name is null or null if app_name is empty
+     */
+    public static String getWrapProperty(String appName) {
+        if (appName == null || appName.isEmpty()) {
+            return null;
+        }
+
+        String propertyValue = SystemProperties.get("wrap." + appName);
+        if (propertyValue != null && !propertyValue.isEmpty()) {
+            return propertyValue;
+        }
+        return null;
+    }
+
+    /**
      * Applies invoke-with system properties to the zygote arguments.
      *
      * @param args non-null; zygote args
      */
     static void applyInvokeWithSystemProperty(ZygoteArguments args) {
-        if (args.mInvokeWith == null && args.mNiceName != null) {
-            String property = "wrap." + args.mNiceName;
-            args.mInvokeWith = SystemProperties.get(property);
-            if (args.mInvokeWith != null && args.mInvokeWith.length() == 0) {
-                args.mInvokeWith = null;
-            }
+        if (args.mInvokeWith == null) {
+            args.mInvokeWith = getWrapProperty(args.mNiceName);
         }
     }
 
@@ -873,15 +959,6 @@
     }
 
     /**
-     * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
-     * or nice value 0). This updates both the priority value in java.lang.Thread and
-     * the nice value (setpriority).
-     */
-    static void resetNicePriority() {
-        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
-    }
-
-    /**
      * Executes "/system/bin/sh -c &lt;command&gt;" using the exec() system call.
      * This method throws a runtime exception if exec() failed, otherwise, this
      * method never returns.
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
index bbb62dd..6d40266 100644
--- a/core/java/com/android/internal/os/ZygoteArguments.java
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -205,6 +205,11 @@
     int mHiddenApiAccessStatslogSampleRate = -1;
 
     /**
+     * @see Zygote#START_AS_TOP_APP_ARG
+     */
+    boolean mIsTopApp;
+
+    /**
      * Constructs instance and parses args
      *
      * @param args zygote command-line args
@@ -405,6 +410,8 @@
                 mUsapPoolStatusSpecified = true;
                 mUsapPoolEnabled = Boolean.parseBoolean(getAssignmentValue(arg));
                 expectRuntimeArgs = false;
+            } else if (arg.startsWith(Zygote.START_AS_TOP_APP_ARG)) {
+                mIsTopApp = true;
             } else {
                 break;
             }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 885f522..06a14f0 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -252,7 +252,8 @@
         pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                 parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                 parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
-                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
+                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion,
+                parsedArgs.mIsTopApp);
 
         try {
             if (pid == 0) {
@@ -322,6 +323,7 @@
             Runnable stateChangeCode) {
         try {
             if (zygoteServer.isUsapPoolEnabled()) {
+                Log.i(TAG, "Emptying USAP Pool due to state change.");
                 Zygote.emptyUsapPool();
             }
 
@@ -330,11 +332,13 @@
             if (zygoteServer.isUsapPoolEnabled()) {
                 Runnable fpResult =
                         zygoteServer.fillUsapPool(
-                                new int[]{mSocket.getFileDescriptor().getInt$()});
+                                new int[]{mSocket.getFileDescriptor().getInt$()}, false);
 
                 if (fpResult != null) {
                     zygoteServer.setForkChild();
                     return fpResult;
+                } else {
+                    Log.i(TAG, "Finished refilling USAP Pool after state change.");
                 }
             }
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index f9e868f..244d5da 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -87,7 +87,6 @@
 
     private static final String PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING =
             "ro.zygote.disable_gl_preload";
-    private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
 
     private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
     private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
@@ -203,9 +202,7 @@
     static native void nativePreloadGraphicsDriver();
 
     private static void maybePreloadGraphicsDriver() {
-        String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
-        if (!SystemProperties.getBoolean(PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING, false)
-                && (driverPackageName == null || driverPackageName.isEmpty())) {
+        if (!SystemProperties.getBoolean(PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING, false)) {
             nativePreloadGraphicsDriver();
         }
     }
@@ -818,6 +815,18 @@
         return result;
     }
 
+    /**
+     * This is the entry point for a Zygote process.  It creates the Zygote server, loads resources,
+     * and handles other tasks related to preparing the process for forking into applications.
+     *
+     * This process is started with a nice value of -20 (highest priority).  All paths that flow
+     * into new processes are required to either set the priority to the default value or terminate
+     * before executing any non-system code.  The native side of this occurs in SpecializeCommon,
+     * while the Java Language priority is changed in ZygoteInit.handleSystemServerProcess,
+     * ZygoteConnection.handleChildProc, and Zygote.usapMain.
+     *
+     * @param argv  Command line arguments used to specify the Zygote's configuration.
+     */
     @UnsupportedAppUsage
     public static void main(String argv[]) {
         ZygoteServer zygoteServer = null;
@@ -881,8 +890,6 @@
                 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                         SystemClock.uptimeMillis());
                 bootTimingsTraceLog.traceEnd(); // ZygotePreload
-            } else {
-                Zygote.resetNicePriority();
             }
 
             // Do an initial gc to clean up after startup
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index 1fd6e26..4a21d37 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -66,6 +66,12 @@
     /** The default value used for the USAP_POOL_SIZE_MIN device property */
     private static final String USAP_POOL_SIZE_MIN_DEFAULT = "1";
 
+    /** The default value used for the USAP_REFILL_DELAY_MS device property */
+    private static final String USAP_POOL_REFILL_DELAY_MS_DEFAULT = "3000";
+
+    /** The "not a timestamp" value for the refill delay timestamp mechanism. */
+    private static final int INVALID_TIMESTAMP = -1;
+
     /**
      * Indicates if this Zygote server can support a unspecialized app process pool.  Currently this
      * should only be true for the primary and secondary Zygotes, and not the App Zygotes or the
@@ -131,6 +137,24 @@
      */
     private int mUsapPoolRefillThreshold = 0;
 
+    /**
+     * Number of milliseconds to delay before refilling the pool if it hasn't reached its
+     * minimum value.
+     */
+    private int mUsapPoolRefillDelayMs = -1;
+
+    /**
+     * If and when we should refill the USAP pool.
+     */
+    private UsapPoolRefillAction mUsapPoolRefillAction;
+    private long mUsapPoolRefillTriggerTimestamp;
+
+    private enum UsapPoolRefillAction {
+        DELAYED,
+        IMMEDIATE,
+        NONE
+    }
+
     ZygoteServer() {
         mUsapPoolEventFD = null;
         mZygoteSocket = null;
@@ -267,6 +291,13 @@
                         mUsapPoolSizeMax);
             }
 
+            final String usapPoolRefillDelayMsPropString = Zygote.getConfigurationProperty(
+                    ZygoteConfig.USAP_POOL_REFILL_DELAY_MS, USAP_POOL_REFILL_DELAY_MS_DEFAULT);
+
+            if (!usapPoolRefillDelayMsPropString.isEmpty()) {
+                mUsapPoolRefillDelayMs = Integer.parseInt(usapPoolRefillDelayMsPropString);
+            }
+
             // Sanity check
             if (mUsapPoolSizeMin >= mUsapPoolSizeMax) {
                 Log.w(TAG, "The max size of the USAP pool must be greater than the minimum size."
@@ -293,9 +324,16 @@
         }
     }
 
+    private void fetchUsapPoolPolicyPropsIfUnfetched() {
+        if (mIsFirstPropertyCheck) {
+            mIsFirstPropertyCheck = false;
+            fetchUsapPoolPolicyProps();
+        }
+    }
+
     /**
-     * Checks to see if the current policy says that pool should be refilled, and spawns new USAPs
-     * if necessary.
+     * Refill the USAP Pool to the appropriate level, determined by whether this is a priority
+     * refill event or not.
      *
      * @param sessionSocketRawFDs  Anonymous session sockets that are currently open
      * @return In the Zygote process this function will always return null; in unspecialized app
@@ -303,39 +341,48 @@
      *         application that is passed up from usapMain.
      */
 
-    Runnable fillUsapPool(int[] sessionSocketRawFDs) {
+    Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) {
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillUsapPool");
 
         // Ensure that the pool properties have been fetched.
-        fetchUsapPoolPolicyPropsWithMinInterval();
+        fetchUsapPoolPolicyPropsIfUnfetched();
 
         int usapPoolCount = Zygote.getUsapPoolCount();
-        int numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount;
+        int numUsapsToSpawn;
 
-        if (usapPoolCount < mUsapPoolSizeMin
-                || numUsapsToSpawn >= mUsapPoolRefillThreshold) {
-
-            // Disable some VM functionality and reset some system values
-            // before forking.
-            ZygoteHooks.preFork();
-            Zygote.resetNicePriority();
-
-            while (usapPoolCount++ < mUsapPoolSizeMax) {
-                Runnable caller = Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs);
-
-                if (caller != null) {
-                    return caller;
-                }
-            }
-
-            // Re-enable runtime services for the Zygote.  Services for unspecialized app process
-            // are re-enabled in specializeAppProcess.
-            ZygoteHooks.postForkCommon();
+        if (isPriorityRefill) {
+            // Refill to min
+            numUsapsToSpawn = mUsapPoolSizeMin - usapPoolCount;
 
             Log.i("zygote",
-                    "Filled the USAP pool. New USAPs: " + numUsapsToSpawn);
+                    "Priority USAP Pool refill. New USAPs: " + numUsapsToSpawn);
+        } else {
+            // Refill up to max
+            numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount;
+
+            Log.i("zygote",
+                    "Delayed USAP Pool refill. New USAPs: " + numUsapsToSpawn);
         }
 
+        // Disable some VM functionality and reset some system values
+        // before forking.
+        ZygoteHooks.preFork();
+
+        while (--numUsapsToSpawn >= 0) {
+            Runnable caller =
+                    Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs, isPriorityRefill);
+
+            if (caller != null) {
+                return caller;
+            }
+        }
+
+        // Re-enable runtime services for the Zygote.  Services for unspecialized app process
+        // are re-enabled in specializeAppProcess.
+        ZygoteHooks.postForkCommon();
+
+        resetUsapRefillState();
+
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
         return null;
@@ -358,13 +405,18 @@
         mUsapPoolEnabled = newStatus;
 
         if (newStatus) {
-            return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() });
+            return fillUsapPool(new int[]{ sessionSocket.getFileDescriptor().getInt$() }, false);
         } else {
             Zygote.emptyUsapPool();
             return null;
         }
     }
 
+    void resetUsapRefillState() {
+        mUsapPoolRefillAction = UsapPoolRefillAction.NONE;
+        mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
+    }
+
     /**
      * Runs the zygote process's select loop. Accepts new connections as
      * they happen, and reads commands from connections one spawn-request's
@@ -377,8 +429,11 @@
         socketFDs.add(mZygoteSocket.getFileDescriptor());
         peers.add(null);
 
+        mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
+
         while (true) {
             fetchUsapPoolPolicyPropsWithMinInterval();
+            mUsapPoolRefillAction = UsapPoolRefillAction.NONE;
 
             int[] usapPipeFDs = null;
             StructPollfd[] pollFDs;
@@ -430,140 +485,199 @@
                 }
             }
 
+            int pollTimeoutMs;
+
+            if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) {
+                pollTimeoutMs = -1;
+            } else {
+                long elapsedTimeMs = System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp;
+
+                if (elapsedTimeMs >= mUsapPoolRefillDelayMs) {
+                    // Normalize the poll timeout value when the time between one poll event and the
+                    // next pushes us over the delay value.  This prevents poll receiving a 0
+                    // timeout value, which would result in it returning immediately.
+                    pollTimeoutMs = -1;
+
+                } else if (elapsedTimeMs <= 0) {
+                    // This can occur if the clock used by currentTimeMillis is reset, which is
+                    // possible because it is not guaranteed to be monotonic.  Because we can't tell
+                    // how far back the clock was set the best way to recover is to simply re-start
+                    // the respawn delay countdown.
+                    pollTimeoutMs = mUsapPoolRefillDelayMs;
+
+                } else {
+                    pollTimeoutMs = (int) (mUsapPoolRefillDelayMs - elapsedTimeMs);
+                }
+            }
+
+            int pollReturnValue;
             try {
-                Os.poll(pollFDs, -1);
+                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
             } catch (ErrnoException ex) {
                 throw new RuntimeException("poll failed", ex);
             }
 
-            boolean usapPoolFDRead = false;
+            if (pollReturnValue == 0) {
+                // The poll timeout has been exceeded.  This only occurs when we have finished the
+                // USAP pool refill delay period.
 
-            while (--pollIndex >= 0) {
-                if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
-                    continue;
-                }
+                mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
+                mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;
 
-                if (pollIndex == 0) {
-                    // Zygote server socket
+            } else {
+                boolean usapPoolFDRead = false;
 
-                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
-                    peers.add(newPeer);
-                    socketFDs.add(newPeer.getFileDescriptor());
-
-                } else if (pollIndex < usapPoolEventFDIndex) {
-                    // Session socket accepted from the Zygote server socket
-
-                    try {
-                        ZygoteConnection connection = peers.get(pollIndex);
-                        final Runnable command = connection.processOneCommand(this);
-
-                        // TODO (chriswailes): Is this extra check necessary?
-                        if (mIsForkChild) {
-                            // We're in the child. We should always have a command to run at this
-                            // stage if processOneCommand hasn't called "exec".
-                            if (command == null) {
-                                throw new IllegalStateException("command == null");
-                            }
-
-                            return command;
-                        } else {
-                            // We're in the server - we should never have any commands to run.
-                            if (command != null) {
-                                throw new IllegalStateException("command != null");
-                            }
-
-                            // We don't know whether the remote side of the socket was closed or
-                            // not until we attempt to read from it from processOneCommand. This
-                            // shows up as a regular POLLIN event in our regular processing loop.
-                            if (connection.isClosedByPeer()) {
-                                connection.closeSocket();
-                                peers.remove(pollIndex);
-                                socketFDs.remove(pollIndex);
-                            }
-                        }
-                    } catch (Exception e) {
-                        if (!mIsForkChild) {
-                            // We're in the server so any exception here is one that has taken place
-                            // pre-fork while processing commands or reading / writing from the
-                            // control socket. Make a loud noise about any such exceptions so that
-                            // we know exactly what failed and why.
-
-                            Slog.e(TAG, "Exception executing zygote command: ", e);
-
-                            // Make sure the socket is closed so that the other end knows
-                            // immediately that something has gone wrong and doesn't time out
-                            // waiting for a response.
-                            ZygoteConnection conn = peers.remove(pollIndex);
-                            conn.closeSocket();
-
-                            socketFDs.remove(pollIndex);
-                        } else {
-                            // We're in the child so any exception caught here has happened post
-                            // fork and before we execute ActivityThread.main (or any other main()
-                            // method). Log the details of the exception and bring down the process.
-                            Log.e(TAG, "Caught post-fork exception in child process.", e);
-                            throw e;
-                        }
-                    } finally {
-                        // Reset the child flag, in the event that the child process is a child-
-                        // zygote. The flag will not be consulted this loop pass after the Runnable
-                        // is returned.
-                        mIsForkChild = false;
-                    }
-                } else {
-                    // Either the USAP pool event FD or a USAP reporting pipe.
-
-                    // If this is the event FD the payload will be the number of USAPs removed.
-                    // If this is a reporting pipe FD the payload will be the PID of the USAP
-                    // that was just specialized.
-                    long messagePayload = -1;
-
-                    try {
-                        byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
-                        int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
-
-                        if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
-                            DataInputStream inputStream =
-                                    new DataInputStream(new ByteArrayInputStream(buffer));
-
-                            messagePayload = inputStream.readLong();
-                        } else {
-                            Log.e(TAG, "Incomplete read from USAP management FD of size "
-                                    + readBytes);
-                            continue;
-                        }
-                    } catch (Exception ex) {
-                        if (pollIndex == usapPoolEventFDIndex) {
-                            Log.e(TAG, "Failed to read from USAP pool event FD: "
-                                    + ex.getMessage());
-                        } else {
-                            Log.e(TAG, "Failed to read from USAP reporting pipe: "
-                                    + ex.getMessage());
-                        }
-
+                while (--pollIndex >= 0) {
+                    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                         continue;
                     }
 
-                    if (pollIndex > usapPoolEventFDIndex) {
-                        Zygote.removeUsapTableEntry((int) messagePayload);
-                    }
+                    if (pollIndex == 0) {
+                        // Zygote server socket
 
-                    usapPoolFDRead = true;
+                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
+                        peers.add(newPeer);
+                        socketFDs.add(newPeer.getFileDescriptor());
+
+                    } else if (pollIndex < usapPoolEventFDIndex) {
+                        // Session socket accepted from the Zygote server socket
+
+                        try {
+                            ZygoteConnection connection = peers.get(pollIndex);
+                            final Runnable command = connection.processOneCommand(this);
+
+                            // TODO (chriswailes): Is this extra check necessary?
+                            if (mIsForkChild) {
+                                // We're in the child. We should always have a command to run at
+                                // this stage if processOneCommand hasn't called "exec".
+                                if (command == null) {
+                                    throw new IllegalStateException("command == null");
+                                }
+
+                                return command;
+                            } else {
+                                // We're in the server - we should never have any commands to run.
+                                if (command != null) {
+                                    throw new IllegalStateException("command != null");
+                                }
+
+                                // We don't know whether the remote side of the socket was closed or
+                                // not until we attempt to read from it from processOneCommand. This
+                                // shows up as a regular POLLIN event in our regular processing
+                                // loop.
+                                if (connection.isClosedByPeer()) {
+                                    connection.closeSocket();
+                                    peers.remove(pollIndex);
+                                    socketFDs.remove(pollIndex);
+                                }
+                            }
+                        } catch (Exception e) {
+                            if (!mIsForkChild) {
+                                // We're in the server so any exception here is one that has taken
+                                // place pre-fork while processing commands or reading / writing
+                                // from the control socket. Make a loud noise about any such
+                                // exceptions so that we know exactly what failed and why.
+
+                                Slog.e(TAG, "Exception executing zygote command: ", e);
+
+                                // Make sure the socket is closed so that the other end knows
+                                // immediately that something has gone wrong and doesn't time out
+                                // waiting for a response.
+                                ZygoteConnection conn = peers.remove(pollIndex);
+                                conn.closeSocket();
+
+                                socketFDs.remove(pollIndex);
+                            } else {
+                                // We're in the child so any exception caught here has happened post
+                                // fork and before we execute ActivityThread.main (or any other
+                                // main() method). Log the details of the exception and bring down
+                                // the process.
+                                Log.e(TAG, "Caught post-fork exception in child process.", e);
+                                throw e;
+                            }
+                        } finally {
+                            // Reset the child flag, in the event that the child process is a child-
+                            // zygote. The flag will not be consulted this loop pass after the
+                            // Runnable is returned.
+                            mIsForkChild = false;
+                        }
+
+                    } else {
+                        // Either the USAP pool event FD or a USAP reporting pipe.
+
+                        // If this is the event FD the payload will be the number of USAPs removed.
+                        // If this is a reporting pipe FD the payload will be the PID of the USAP
+                        // that was just specialized.  The `continue` statements below ensure that
+                        // the messagePayload will always be valid if we complete the try block
+                        // without an exception.
+                        long messagePayload;
+
+                        try {
+                            byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
+                            int readBytes =
+                                    Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
+
+                            if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
+                                DataInputStream inputStream =
+                                        new DataInputStream(new ByteArrayInputStream(buffer));
+
+                                messagePayload = inputStream.readLong();
+                            } else {
+                                Log.e(TAG, "Incomplete read from USAP management FD of size "
+                                        + readBytes);
+                                continue;
+                            }
+                        } catch (Exception ex) {
+                            if (pollIndex == usapPoolEventFDIndex) {
+                                Log.e(TAG, "Failed to read from USAP pool event FD: "
+                                        + ex.getMessage());
+                            } else {
+                                Log.e(TAG, "Failed to read from USAP reporting pipe: "
+                                        + ex.getMessage());
+                            }
+
+                            continue;
+                        }
+
+                        if (pollIndex > usapPoolEventFDIndex) {
+                            Zygote.removeUsapTableEntry((int) messagePayload);
+                        }
+
+                        usapPoolFDRead = true;
+                    }
+                }
+
+                if (usapPoolFDRead) {
+                    int usapPoolCount = Zygote.getUsapPoolCount();
+
+                    if (usapPoolCount < mUsapPoolSizeMin) {
+                        // Immediate refill
+                        mUsapPoolRefillAction = UsapPoolRefillAction.IMMEDIATE;
+                    } else if (mUsapPoolSizeMax - usapPoolCount >= mUsapPoolRefillThreshold) {
+                        // Delayed refill
+                        mUsapPoolRefillTriggerTimestamp = System.currentTimeMillis();
+                    }
                 }
             }
 
-            // Check to see if the USAP pool needs to be refilled.
-            if (usapPoolFDRead) {
+            if (mUsapPoolRefillAction != UsapPoolRefillAction.NONE) {
                 int[] sessionSocketRawFDs =
                         socketFDs.subList(1, socketFDs.size())
                                 .stream()
                                 .mapToInt(FileDescriptor::getInt$)
                                 .toArray();
 
-                final Runnable command = fillUsapPool(sessionSocketRawFDs);
+                final boolean isPriorityRefill =
+                        mUsapPoolRefillAction == UsapPoolRefillAction.IMMEDIATE;
+
+                final Runnable command =
+                        fillUsapPool(sessionSocketRawFDs, isPriorityRefill);
 
                 if (command != null) {
                     return command;
+                } else if (isPriorityRefill) {
+                    // Schedule a delayed refill to finish refilling the pool.
+                    mUsapPoolRefillTriggerTimestamp = System.currentTimeMillis();
                 }
             }
         }
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index fa73758..7bfed91 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -380,7 +380,7 @@
         // don't want the navigation bar background be moving around when resizing in docked mode.
         // However, we need it for the transitions into/out of docked mode.
         if (mNavigationBarColor != null && fullscreen) {
-            DecorView.getNavigationBarRect(width, height, stableInsets, systemInsets, mTmpRect);
+            DecorView.getNavigationBarRect(width, height, stableInsets, systemInsets, mTmpRect, 1f);
             mNavigationBarColor.setBounds(mTmpRect);
             mNavigationBarColor.draw(canvas);
         }
diff --git a/core/java/com/android/internal/policy/DecorContext.java b/core/java/com/android/internal/policy/DecorContext.java
index 56a40a3..da1b72f 100644
--- a/core/java/com/android/internal/policy/DecorContext.java
+++ b/core/java/com/android/internal/policy/DecorContext.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.policy;
 
+import android.content.AutofillOptions;
 import android.content.ContentCaptureOptions;
 import android.content.Context;
 import android.content.res.AssetManager;
@@ -98,6 +99,15 @@
     }
 
     @Override
+    public AutofillOptions getAutofillOptions() {
+        Context activityContext = mActivityContext.get();
+        if (activityContext != null) {
+            return activityContext.getAutofillOptions();
+        }
+        return null;
+    }
+
+    @Override
     public ContentCaptureOptions getContentCaptureOptions() {
         Context activityContext = mActivityContext.get();
         if (activityContext != null) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 1a16150..480ff4d 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -84,6 +84,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
+import android.view.ViewRootImpl;
 import android.view.ViewStub;
 import android.view.ViewTreeObserver;
 import android.view.Window;
@@ -262,8 +263,10 @@
     private final int mResizeShadowSize;
     private final Paint mVerticalResizeShadowPaint = new Paint();
     private final Paint mHorizontalResizeShadowPaint = new Paint();
+    private final Paint mLegacyNavigationBarBackgroundPaint = new Paint();
     private Insets mBackgroundInsets = Insets.NONE;
     private Insets mLastBackgroundInsets = Insets.NONE;
+    private boolean mDrawLegacyNavigationBarBackground;
 
     DecorView(Context context, int featureId, PhoneWindow window,
             WindowManager.LayoutParams params) {
@@ -292,6 +295,8 @@
         mResizeShadowSize = context.getResources().getDimensionPixelSize(
                 R.dimen.resize_shadow_size);
         initResizingPaints();
+
+        mLegacyNavigationBarBackgroundPaint.setColor(Color.BLACK);
     }
 
     void setBackgroundFallback(@Nullable Drawable fallbackDrawable) {
@@ -978,14 +983,7 @@
 
     @Override
     public void setBackgroundDrawable(Drawable background) {
-
-        // TODO: This should route through setWindowBackground, but late in the release to make this
-        // change.
-        if (mOriginalBackgroundDrawable != background) {
-            mOriginalBackgroundDrawable = background;
-            updateBackgroundDrawable();
-            drawableChanged();
-        }
+        setWindowBackground(background);
     }
 
     public void setWindowFrame(Drawable drawable) {
@@ -1004,6 +1002,10 @@
     public void onWindowSystemUiVisibilityChanged(int visible) {
         updateColorViews(null /* insets */, true /* animate */);
         updateDecorCaptionStatus(getResources().getConfiguration());
+
+        if (mStatusGuard != null && mStatusGuard.getVisibility() == VISIBLE) {
+            updateStatusGuardColor();
+        }
     }
 
     @Override
@@ -1072,10 +1074,13 @@
     }
 
     public static void getNavigationBarRect(int canvasWidth, int canvasHeight, Rect stableInsets,
-            Rect contentInsets, Rect outRect) {
-        final int bottomInset = getColorViewBottomInset(stableInsets.bottom, contentInsets.bottom);
-        final int leftInset = getColorViewLeftInset(stableInsets.left, contentInsets.left);
-        final int rightInset = getColorViewLeftInset(stableInsets.right, contentInsets.right);
+            Rect contentInsets, Rect outRect, float scale) {
+        final int bottomInset =
+                (int) (getColorViewBottomInset(stableInsets.bottom, contentInsets.bottom) * scale);
+        final int leftInset =
+                (int) (getColorViewLeftInset(stableInsets.left, contentInsets.left) * scale);
+        final int rightInset =
+                (int) (getColorViewLeftInset(stableInsets.right, contentInsets.right) * scale);
         final int size = getNavBarSize(bottomInset, rightInset, leftInset);
         if (isNavBarToRightEdge(bottomInset, rightInset)) {
             outRect.set(canvasWidth - size, 0, canvasWidth, canvasHeight);
@@ -1139,6 +1144,15 @@
                     navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge,
                     0 /* sideInset */, animate && !disallowAnimate,
                     mForceWindowDrawsBarBackgrounds);
+            boolean oldDrawLegacy = mDrawLegacyNavigationBarBackground;
+            mDrawLegacyNavigationBarBackground = mNavigationColorViewState.visible
+                    && (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
+            if (oldDrawLegacy != mDrawLegacyNavigationBarBackground) {
+                ViewRootImpl vri = getViewRootImpl();
+                if (vri != null) {
+                    vri.requestInvalidateRootRenderNode();
+                }
+            }
 
             boolean statusBarNeedsRightInset = navBarToRightEdge
                     && mNavigationColorViewState.present;
@@ -1160,16 +1174,17 @@
         // Note: We don't need to check for IN_SCREEN or INSET_DECOR because unlike the status bar,
         // these flags wouldn't make the window draw behind the navigation bar, unless
         // LAYOUT_HIDE_NAVIGATION was set.
+        boolean hideNavigation = (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
         boolean forceConsumingNavBar = (mForceWindowDrawsBarBackgrounds
                         && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
                         && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
-                        && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
-                || mLastShouldAlwaysConsumeSystemBars;
+                        && !hideNavigation)
+                || (mLastShouldAlwaysConsumeSystemBars && hideNavigation);
 
         boolean consumingNavBar =
                 ((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
                         && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
-                        && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
+                        && !hideNavigation)
                 || forceConsumingNavBar;
 
         // If we didn't request fullscreen layout, but we still got it because of the
@@ -1289,7 +1304,7 @@
             return semiTransparentBarColor;
         } else if ((flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) {
             return Color.BLACK;
-        } else if (scrimTransparent && barColor == Color.TRANSPARENT) {
+        } else if (scrimTransparent && Color.alpha(barColor) == 0) {
             boolean light = (sysuiVis & lightSysuiFlag) != 0;
             return light ? SCRIM_LIGHT : semiTransparentBarColor;
         } else {
@@ -1461,28 +1476,45 @@
                     }
                     final Rect rect = mTempRect;
 
-                    // If the parent doesn't consume the insets, manually
-                    // apply the default system window insets.
-                    mWindow.mContentParent.computeSystemWindowInsets(insets, rect);
-                    final int newMargin = rect.top == 0 ? insets.getSystemWindowInsetTop() : 0;
-                    if (mlp.topMargin != newMargin) {
-                        mlpChanged = true;
-                        mlp.topMargin = insets.getSystemWindowInsetTop();
+                    // Apply the insets that have not been applied by the contentParent yet.
+                    WindowInsets innerInsets =
+                            mWindow.mContentParent.computeSystemWindowInsets(insets, rect);
+                    int newTopMargin = innerInsets.getSystemWindowInsetTop();
+                    int newLeftMargin = innerInsets.getSystemWindowInsetLeft();
+                    int newRightMargin = innerInsets.getSystemWindowInsetRight();
 
-                        if (mStatusGuard == null) {
-                            mStatusGuard = new View(mContext);
-                            mStatusGuard.setBackgroundColor(mContext.getColor(
-                                    R.color.decor_view_status_guard));
-                            addView(mStatusGuard, indexOfChild(mStatusColorViewState.view),
-                                    new LayoutParams(LayoutParams.MATCH_PARENT,
-                                            mlp.topMargin, Gravity.START | Gravity.TOP));
-                        } else {
-                            final LayoutParams lp = (LayoutParams)
-                                    mStatusGuard.getLayoutParams();
-                            if (lp.height != mlp.topMargin) {
-                                lp.height = mlp.topMargin;
-                                mStatusGuard.setLayoutParams(lp);
-                            }
+                    // Must use root window insets for the guard, because the color views consume
+                    // the navigation bar inset if the window does not request LAYOUT_HIDE_NAV - but
+                    // the status guard is attached at the root.
+                    WindowInsets rootInsets = getRootWindowInsets();
+                    int newGuardLeftMargin = rootInsets.getSystemWindowInsetLeft();
+                    int newGuardRightMargin = rootInsets.getSystemWindowInsetRight();
+
+                    if (mlp.topMargin != newTopMargin || mlp.leftMargin != newLeftMargin
+                            || mlp.rightMargin != newRightMargin) {
+                        mlpChanged = true;
+                        mlp.topMargin = newTopMargin;
+                        mlp.leftMargin = newLeftMargin;
+                        mlp.rightMargin = newRightMargin;
+                    }
+
+                    if (newTopMargin > 0 && mStatusGuard == null) {
+                        mStatusGuard = new View(mContext);
+                        mStatusGuard.setVisibility(GONE);
+                        final LayoutParams lp = new LayoutParams(MATCH_PARENT,
+                                mlp.topMargin, Gravity.LEFT | Gravity.TOP);
+                        lp.leftMargin = newGuardLeftMargin;
+                        lp.rightMargin = newGuardRightMargin;
+                        addView(mStatusGuard, indexOfChild(mStatusColorViewState.view), lp);
+                    } else if (mStatusGuard != null) {
+                        final LayoutParams lp = (LayoutParams)
+                                mStatusGuard.getLayoutParams();
+                        if (lp.height != mlp.topMargin || lp.leftMargin != newGuardLeftMargin
+                                || lp.rightMargin != newGuardRightMargin) {
+                            lp.height = mlp.topMargin;
+                            lp.leftMargin = newGuardLeftMargin;
+                            lp.rightMargin = newGuardRightMargin;
+                            mStatusGuard.setLayoutParams(lp);
                         }
                     }
 
@@ -1490,6 +1522,11 @@
                     // always show the status guard above it if we have one.
                     showStatusGuard = mStatusGuard != null;
 
+                    if (showStatusGuard && mStatusGuard.getVisibility() != VISIBLE) {
+                        // If it wasn't previously shown, the color may be stale
+                        updateStatusGuardColor();
+                    }
+
                     // We only need to consume the insets if the action
                     // mode is overlaid on the app content (e.g. it's
                     // sitting in a FrameLayout, see
@@ -1501,7 +1538,7 @@
                     }
                 } else {
                     // reset top margin
-                    if (mlp.topMargin != 0) {
+                    if (mlp.topMargin != 0 || mlp.leftMargin != 0 || mlp.rightMargin != 0) {
                         mlpChanged = true;
                         mlp.topMargin = 0;
                     }
@@ -1512,11 +1549,19 @@
             }
         }
         if (mStatusGuard != null) {
-            mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE);
+            mStatusGuard.setVisibility(showStatusGuard ? VISIBLE : GONE);
         }
         return insets;
     }
 
+    private void updateStatusGuardColor() {
+        boolean lightStatusBar =
+                (getWindowSystemUiVisibility() & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
+        mStatusGuard.setBackgroundColor(lightStatusBar
+                ? mContext.getColor(R.color.decor_view_status_guard_light)
+                : mContext.getColor(R.color.decor_view_status_guard));
+    }
+
     /**
      * Overrides the view outline when the activity enters picture-in-picture to ensure that it has
      * an opaque shadow even if the window background is completely transparent. This only applies
@@ -2275,6 +2320,7 @@
     @Override
     public void onPostDraw(RecordingCanvas canvas) {
         drawResizingShadowIfNeeded(canvas);
+        drawLegacyNavigationBarBackground(canvas);
     }
 
     private void initResizingPaints() {
@@ -2307,6 +2353,18 @@
         canvas.restore();
     }
 
+    private void drawLegacyNavigationBarBackground(RecordingCanvas canvas) {
+        if (!mDrawLegacyNavigationBarBackground) {
+            return;
+        }
+        View v = mNavigationColorViewState.view;
+        if (v == null) {
+            return;
+        }
+        canvas.drawRect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom(),
+                mLegacyNavigationBarBackgroundPaint);
+    }
+
     /** Release the renderer thread which is usually done when the user stops resizing. */
     private void releaseThreadedRenderer() {
         if (mResizingBackgroundDrawable != null && mLastBackgroundDrawableCb != null) {
@@ -2593,6 +2651,7 @@
                                         }
                                         lastActionModeView.killMode();
                                         mFadeAnim = null;
+                                        requestApplyInsets();
                                     }
                                 }
 
diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
index 5b6b619..1afc67b 100644
--- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
@@ -24,8 +24,6 @@
 import android.graphics.Rect;
 import android.util.Size;
 import android.view.Gravity;
-import android.view.ViewConfiguration;
-import android.widget.Scroller;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -180,14 +178,6 @@
         // If we're not flinging along the current edge, find the closest point instead.
         final double distanceVert = Math.hypot(vertPoint.x - x, vertPoint.y - y);
         final double distanceHoriz = Math.hypot(horizPoint.x - x, horizPoint.y - y);
-        // Ensure that we're actually going somewhere
-        if (distanceVert == 0) {
-            return horizPoint;
-        }
-        if (distanceHoriz == 0) {
-            return vertPoint;
-        }
-        // Otherwise use the closest point
         return Math.abs(distanceVert) > Math.abs(distanceHoriz) ? horizPoint : vertPoint;
     }
 
diff --git a/core/java/com/android/internal/policy/ScreenDecorationsUtils.java b/core/java/com/android/internal/policy/ScreenDecorationsUtils.java
index adf7692..52172cf 100644
--- a/core/java/com/android/internal/policy/ScreenDecorationsUtils.java
+++ b/core/java/com/android/internal/policy/ScreenDecorationsUtils.java
@@ -36,13 +36,16 @@
         }
 
         // Radius that should be used in case top or bottom aren't defined.
-        float defaultRadius = resources.getDimension(R.dimen.rounded_corner_radius);
+        float defaultRadius = resources.getDimension(R.dimen.rounded_corner_radius)
+                - resources.getDimension(R.dimen.rounded_corner_radius_adjustment);
 
-        float topRadius = resources.getDimension(R.dimen.rounded_corner_radius_top);
+        float topRadius = resources.getDimension(R.dimen.rounded_corner_radius_top)
+                - resources.getDimension(R.dimen.rounded_corner_radius_top_adjustment);
         if (topRadius == 0f) {
             topRadius = defaultRadius;
         }
-        float bottomRadius = resources.getDimension(R.dimen.rounded_corner_radius_bottom);
+        float bottomRadius = resources.getDimension(R.dimen.rounded_corner_radius_bottom)
+                - resources.getDimension(R.dimen.rounded_corner_radius_bottom_adjustment);
         if (bottomRadius == 0f) {
             bottomRadius = defaultRadius;
         }
diff --git a/core/java/com/android/internal/util/AnnotationValidations.java b/core/java/com/android/internal/util/AnnotationValidations.java
new file mode 100644
index 0000000..c8afdd4
--- /dev/null
+++ b/core/java/com/android/internal/util/AnnotationValidations.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.util;
+
+import static com.android.internal.util.BitUtils.flagsUpTo;
+
+import android.annotation.AppIdInt;
+import android.annotation.ColorInt;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Size;
+import android.annotation.UserIdInt;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.PackageInfoFlags;
+import android.content.pm.PackageManager.PermissionResult;
+import android.os.UserHandle;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Validations for common annotations, e.g. {@link IntRange}, {@link UserIdInt}, etc.
+ *
+ * For usability from generated {@link DataClass} code, all validations are overloads of
+ * {@link #validate} with the following shape:
+ * {@code
+ *      <A extends Annotation> void validate(
+ *              Class<A> cls, A ignored, Object value[, (String, Object)... annotationParams])
+ * }
+ * The ignored {@link Annotation} parameter is used to differentiate between overloads that would
+ * otherwise have the same jvm signature. It's usually null at runtime.
+ */
+public class AnnotationValidations {
+    private AnnotationValidations() {}
+
+    public static void validate(Class<UserIdInt> annotation, UserIdInt ignored, int value) {
+        if ((value != UserHandle.USER_NULL && value < -3)
+                || value > Integer.MAX_VALUE / UserHandle.PER_USER_RANGE) {
+            invalid(annotation, value);
+        }
+    }
+
+    public static void validate(Class<AppIdInt> annotation, AppIdInt ignored, int value) {
+        if (value / UserHandle.PER_USER_RANGE != 0 || value < 0) {
+            invalid(annotation, value);
+        }
+    }
+
+    public static void validate(Class<IntRange> annotation, IntRange ignored, int value,
+            String paramName1, int param1, String paramName2, int param2) {
+        validate(annotation, ignored, value, paramName1, param1);
+        validate(annotation, ignored, value, paramName2, param2);
+    }
+
+    public static void validate(Class<IntRange> annotation, IntRange ignored, int value,
+            String paramName, int param) {
+        switch (paramName) {
+            case "from": if (value < param) invalid(annotation, value, paramName, param); break;
+            case "to": if (value > param) invalid(annotation, value, paramName, param); break;
+        }
+    }
+
+    public static void validate(Class<FloatRange> annotation, FloatRange ignored, float value,
+            String paramName1, float param1, String paramName2, float param2) {
+        validate(annotation, ignored, value, paramName1, param1);
+        validate(annotation, ignored, value, paramName2, param2);
+    }
+
+    public static void validate(Class<FloatRange> annotation, FloatRange ignored, float value,
+            String paramName, float param) {
+        switch (paramName) {
+            case "from": if (value < param) invalid(annotation, value, paramName, param); break;
+            case "to": if (value > param) invalid(annotation, value, paramName, param); break;
+        }
+    }
+
+    public static void validate(Class<NonNull> annotation, NonNull ignored, Object value) {
+        if (value == null) {
+            throw new NullPointerException();
+        }
+    }
+
+    public static void validate(Class<Size> annotation, Size ignored, int value,
+            String paramName1, int param1, String paramName2, int param2) {
+        validate(annotation, ignored, value, paramName1, param1);
+        validate(annotation, ignored, value, paramName2, param2);
+    }
+
+    public static void validate(Class<Size> annotation, Size ignored, int value,
+            String paramName, int param) {
+        switch (paramName) {
+            case "value": {
+                if (param != -1 && value != param) invalid(annotation, value, paramName, param);
+            } break;
+            case "min": {
+                if (value < param) invalid(annotation, value, paramName, param);
+            } break;
+            case "max": {
+                if (value > param) invalid(annotation, value, paramName, param);
+            } break;
+            case "multiple": {
+                if (value % param != 0) invalid(annotation, value, paramName, param);
+            } break;
+        }
+    }
+
+    public static void validate(
+            Class<PermissionResult> annotation, PermissionResult ignored, int value) {
+        validateIntEnum(annotation, value, PackageManager.PERMISSION_GRANTED);
+    }
+
+    public static void validate(
+            Class<PackageInfoFlags> annotation, PackageInfoFlags ignored, int value) {
+        validateIntFlags(annotation, value,
+                flagsUpTo(PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS));
+    }
+
+    public static void validate(
+            Class<Intent.Flags> annotation, Intent.Flags ignored, int value) {
+        validateIntFlags(annotation, value, flagsUpTo(Intent.FLAG_RECEIVER_OFFLOAD));
+    }
+
+
+    @Deprecated
+    public static void validate(Class<? extends Annotation> annotation,
+            Annotation ignored, Object value, Object... params) {}
+    @Deprecated
+    public static void validate(Class<? extends Annotation> annotation,
+            Annotation ignored, Object value) {}
+    @Deprecated
+    public static void validate(Class<? extends Annotation> annotation,
+            Annotation ignored, int value, Object... params) {}
+    public static void validate(Class<? extends Annotation> annotation,
+            Annotation ignored, int value) {
+        if (("android.annotation".equals(annotation.getPackageName$())
+                && annotation.getSimpleName().endsWith("Res"))
+                || ColorInt.class.equals(annotation)) {
+            if (value < 0) {
+                invalid(annotation, value);
+            }
+        }
+    }
+    public static void validate(Class<? extends Annotation> annotation,
+            Annotation ignored, long value) {
+        if ("android.annotation".equals(annotation.getPackageName$())
+                && annotation.getSimpleName().endsWith("Long")) {
+            if (value < 0L) {
+                invalid(annotation, value);
+            }
+        }
+    }
+
+    private static void validateIntEnum(
+            Class<? extends Annotation> annotation, int value, int lastValid) {
+        if (value > lastValid) {
+            invalid(annotation, value);
+        }
+    }
+    private static void validateIntFlags(
+            Class<? extends Annotation> annotation, int value, int validBits) {
+        if ((validBits & value) != validBits) {
+            invalid(annotation, "0x" + Integer.toHexString(value));
+        }
+    }
+
+    private static void invalid(Class<? extends Annotation> annotation, Object value) {
+        invalid("@" + annotation.getSimpleName(), value);
+    }
+
+    private static void invalid(Class<? extends Annotation> annotation, Object value,
+            String paramName, Object param) {
+        String paramPrefix = "value".equals(paramName) ? "" : paramName + " = ";
+        invalid("@" + annotation.getSimpleName() + "(" + paramPrefix + param + ")", value);
+    }
+
+    private static void invalid(String valueKind, Object value) {
+        throw new IllegalStateException("Invalid " + valueKind + ": " + value);
+    }
+}
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index e8691fa..b73ecd1 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -756,4 +756,8 @@
             return String.valueOf(value);
         }
     }
+
+    public static @Nullable <T> T firstOrNull(T[] items) {
+        return items.length > 0 ? items[0] : null;
+    }
 }
diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java
index 6158145..b4bab80 100644
--- a/core/java/com/android/internal/util/BitUtils.java
+++ b/core/java/com/android/internal/util/BitUtils.java
@@ -158,4 +158,18 @@
     public static byte[] toBytes(long l) {
         return ByteBuffer.allocate(8).putLong(l).array();
     }
+
+    /**
+     * 0b01000 -> 0b01111
+     */
+    public static int flagsUpTo(int lastFlag) {
+        return lastFlag <= 0 ? 0 : lastFlag | flagsUpTo(lastFlag >> 1);
+    }
+
+    /**
+     * 0b00010, 0b01000 -> 0b01110
+     */
+    public static int flagsWithin(int firstFlag, int lastFlag) {
+        return (flagsUpTo(lastFlag) & ~flagsUpTo(firstFlag)) | firstFlag;
+    }
 }
diff --git a/core/java/com/android/internal/util/DataClass.java b/core/java/com/android/internal/util/DataClass.java
new file mode 100644
index 0000000..146f546
--- /dev/null
+++ b/core/java/com/android/internal/util/DataClass.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.util;
+
+import static java.lang.annotation.ElementType.*;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.annotation.StringDef;
+import android.os.Parcelable;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Retention(RetentionPolicy.SOURCE)
+@Target(ElementType.TYPE)
+public @interface DataClass {
+
+    /**
+     * Generates {@link Parcelable#writeToParcel}, {@link Parcelable#describeContents} and a
+     * {@link Parcelable.Creator}.
+     *
+     * Can be implicitly requested by adding "implements Parcelable" to class signature
+     *
+     * You can provide custom parceling logic by using a {@link ParcelWith} annotation with a
+     * custom {@link Parcelling} subclass.
+     *
+     * Alternatively, for one-off customizations you can declare methods like:
+     * {@code void parcelFieldName(Parcel dest, int flags)}
+     * {@code static FieldType unparcelFieldName(Parcel in)}
+     */
+    boolean genParcelable() default false;
+
+    /**
+     * Generates a simple "parcelable" .aidl file alongside the original .java file
+     *
+     * If not explicitly requested/suppressed, is on iff {@link #genParcelable} is on
+     */
+    boolean genAidl() default false;
+
+    /**
+     * Generates getters for each field.
+     *
+     * You can request for getter to lazily initialize your field by declaring a method like:
+     * {@code FieldType lazyInitFieldName()}
+     *
+     * You can request for the lazy initialization to be thread safe my marking the field volatile.
+     */
+    boolean genGetters() default true;
+
+    /**
+     * Generates setters for each field.
+     */
+    boolean genSetters() default false;
+
+    /**
+     * Generates a public constructor with each field initialized from a parameter and optionally
+     * some user-defined state validation at the end.
+     *
+     * Uses field {@link Nullable nullability}/default value presence to determine optional
+     * parameters.
+     *
+     * Requesting a {@link #genBuilder} suppresses public constructor generation by default.
+     *
+     * You receive a callback at the end of constructor call by declaring the method:
+     * {@code void onConstructed()}
+     * This is the place to put any custom validation logic.
+     */
+    boolean genConstructor() default true;
+
+    /**
+     * Generates a Builder for your class.
+     *
+     * Uses a package-private constructor under the hood, so same rules hold as for
+     * {@link #genConstructor()}
+     */
+    boolean genBuilder() default false;
+
+    /**
+     * Generates a structural {@link Object#equals} + {@link Object#hashCode}.
+     *
+     * You can customize individual fields' logic by declaring methods like:
+     * {@link boolean fieldNameEquals(ClassName otherInstance)}
+     * {@link boolean fieldNameEquals(FieldType otherValue)}
+     * {@link int fieldNameHashCode()}
+     */
+    boolean genEqualsHashCode() default false;
+
+    /**
+     * Generates a structural {@link Object#toString}.
+     *
+     * You can customize individual fields' logic by declaring methods like:
+     * {@link String fieldNameToString()}
+     */
+    boolean genToString() default false;
+
+    /**
+     * Generates a utility method that takes a {@link PerObjectFieldAction per-field callback}
+     * and calls it once for each field with its name and value.
+     *
+     * If some fields are of primitive types, and additional overload is generated that takes
+     * multiple callbacks, specialized for used primitive types to avoid auto-boxing, e.g.
+     * {@link PerIntFieldAction}.
+     */
+    boolean genForEachField() default false;
+
+    /**
+     * Generates a constructor that copies the given instance of the same class.
+     */
+    boolean genCopyConstructor() default false;
+
+    /**
+     * Generates constant annotations({@link IntDef}/{@link StringDef}) for any constant groups
+     * with common prefix.
+     * The annotation names are based on the common prefix.
+     *
+     * For int constants this additionally generates the corresponding static *ToString method and
+     * uses it in {@link Object#toString}.
+     *
+     * Additionally, any fields you annotate with the generated constants will be automatically
+     * validated in constructor.
+     *
+     * Int constants specified as hex(0x..) are considered to be flags, which is taken into account
+     * for in their *ToString and validation.
+     *
+     * You can optionally override the name of the generated annotation by annotating each constant
+     * with the desired annotation name.
+     *
+     * Unless suppressed, is implied by presence of constants with common prefix.
+     */
+    boolean genConstDefs() default true;
+
+
+    /**
+     * Allows specifying custom parcelling logic based on reusable
+     * {@link Parcelling} implementations
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @Target(FIELD)
+    @interface ParcelWith {
+        Class<? extends Parcelling> value();
+    }
+
+    /**
+     * Allows specifying a singular name for a builder's plural field name e.g. 'name' for 'mNames'
+     * Used for Builder's {@code addName(String name)} methods
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @Target(FIELD)
+    @interface PluralOf {
+        String value();
+    }
+
+    /**
+     * Marks that any annotations following it are applicable to each element of the
+     * collection/array, as opposed to itself.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
+    @interface Each {}
+
+    /**
+     * @deprecated to be used by code generator exclusively
+     * @hide
+     */
+    @Deprecated
+    @Retention(RetentionPolicy.SOURCE)
+    @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, ANNOTATION_TYPE, CONSTRUCTOR, TYPE})
+    @interface Generated {
+        long time();
+        String codegenVersion();
+        String sourceFile();
+        String inputSignatures() default "";
+
+        /**
+         * @deprecated to be used by code generator exclusively
+         * @hide
+         */
+        @Deprecated
+        @Retention(RetentionPolicy.SOURCE)
+        @Target({FIELD, METHOD, ANNOTATION_TYPE, CONSTRUCTOR, TYPE})
+        @interface Member {}
+    }
+
+    /**
+     * Callback used by {@link #genForEachField}.
+     *
+     * @param <THIS> The enclosing data class instance.
+     *              Can be used to try and avoid capturing values from outside of the lambda,
+     *              minimizing allocations.
+     */
+    interface PerObjectFieldAction<THIS> {
+        void acceptObject(THIS self, String fieldName, Object fieldValue);
+    }
+
+    /**
+     * A specialization of {@link PerObjectFieldAction} called exclusively for int fields to avoid
+     * boxing.
+     */
+    interface PerIntFieldAction<THIS> {
+        void acceptInt(THIS self, String fieldName, int fieldValue);
+    }
+}
diff --git a/core/java/com/android/internal/util/Parcelling.java b/core/java/com/android/internal/util/Parcelling.java
new file mode 100644
index 0000000..63530dc
--- /dev/null
+++ b/core/java/com/android/internal/util/Parcelling.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 com.android.internal.util;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.util.ArrayMap;
+
+import java.util.regex.Pattern;
+
+/**
+ * Describes a 2-way parcelling contract of type {@code T} into/out of a {@link Parcel}
+ *
+ * @param <T> the type being [un]parcelled
+ */
+public interface Parcelling<T> {
+
+    /**
+     * Write an item into parcel.
+     */
+    void parcel(T item, Parcel dest, int parcelFlags);
+
+    /**
+     * Read an item from parcel.
+     */
+    T unparcel(Parcel source);
+
+
+    /**
+     * A registry of {@link Parcelling} singletons.
+     */
+    class Cache {
+        private Cache() {}
+
+        private static ArrayMap<Class, Parcelling> sCache = new ArrayMap<>();
+
+        /**
+         * Retrieves an instance of a given {@link Parcelling} class if present.
+         */
+        public static @Nullable <P extends Parcelling<?>> P get(Class<P> clazz) {
+            return (P) sCache.get(clazz);
+        }
+
+        /**
+         * Stores an instance of a given {@link Parcelling}.
+         *
+         * @return the provided parcelling for convenience.
+         */
+        public static <P extends Parcelling<?>> P put(P parcelling) {
+            sCache.put(parcelling.getClass(), parcelling);
+            return parcelling;
+        }
+
+        /**
+         * Produces an instance of a given {@link Parcelling} class, by either retrieving a cached
+         * instance or reflectively creating one.
+         */
+        public static <P extends Parcelling<?>> P getOrCreate(Class<P> clazz) {
+            P cached = get(clazz);
+            if (cached != null) {
+                return cached;
+            } else {
+                try {
+                    return put(clazz.newInstance());
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Common {@link Parcelling} implementations.
+     */
+    interface BuiltIn {
+
+        class ForPattern implements Parcelling<Pattern> {
+
+            @Override
+            public void parcel(Pattern item, Parcel dest, int parcelFlags) {
+                dest.writeString(item == null ? null : item.pattern());
+            }
+
+            @Override
+            public Pattern unparcel(Parcel source) {
+                String s = source.readString();
+                return s == null ? null : Pattern.compile(s);
+            }
+        }
+    }
+}
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
index 6be626a..1fdb1f3 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
@@ -24,6 +24,7 @@
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.BitUtils;
+import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.HeptConsumer;
 import com.android.internal.util.function.HeptFunction;
 import com.android.internal.util.function.HeptPredicate;
@@ -47,6 +48,7 @@
 import com.android.internal.util.function.TriPredicate;
 
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.BiPredicate;
@@ -432,13 +434,15 @@
         if (isConstSupplier()) {
             sb.append(getFuncTypeAsString()).append("(").append(doInvoke()).append(")");
         } else {
-            if (mFunc instanceof PooledLambdaImpl) {
-                sb.append(mFunc);
+            Object func = mFunc;
+            if (func instanceof PooledLambdaImpl) {
+                sb.append(func);
             } else {
-                sb.append(getFuncTypeAsString()).append("@").append(hashCodeHex(mFunc));
+                sb.append(getFuncTypeAsString()).append("@").append(hashCodeHex(func));
             }
             sb.append("(");
-            sb.append(commaSeparateFirstN(mArgs, LambdaType.decodeArgCount(getFlags(MASK_FUNC_TYPE))));
+            sb.append(commaSeparateFirstN(mArgs,
+                    LambdaType.decodeArgCount(getFlags(MASK_FUNC_TYPE))));
             sb.append(")");
         }
         return sb.toString();
@@ -450,11 +454,11 @@
     }
 
     private static String hashCodeHex(Object o) {
-        return Integer.toHexString(o.hashCode());
+        return Integer.toHexString(Objects.hashCode(o));
     }
 
     private String getFuncTypeAsString() {
-        if (isRecycled()) throw new IllegalStateException();
+        if (isRecycled()) return "<recycled>";
         if (isConstSupplier()) return "supplier";
         String name = LambdaType.toString(getFlags(MASK_EXPOSED_AS));
         if (name.endsWith("Consumer")) return "consumer";
@@ -462,7 +466,7 @@
         if (name.endsWith("Predicate")) return "predicate";
         if (name.endsWith("Supplier")) return "supplier";
         if (name.endsWith("Runnable")) return "runnable";
-        throw new IllegalStateException("Don't know the string representation of " + name);
+        return name;
     }
 
     /**
@@ -490,7 +494,7 @@
                             + ", i = " + i
                             + ")");
         }
-        r.mFunc = func;
+        r.mFunc = Preconditions.checkNotNull(func);
         r.setFlags(MASK_FUNC_TYPE, LambdaType.encode(fNumArgs, fReturnType));
         r.setFlags(MASK_EXPOSED_AS, LambdaType.encode(numPlaceholders, fReturnType));
         if (ArrayUtils.size(r.mArgs) < fNumArgs) r.mArgs = new Object[fNumArgs];
@@ -633,6 +637,7 @@
         private static String argCountPrefix(int argCount) {
             switch (argCount) {
                 case MASK_ARG_COUNT: return "";
+                case 0: return "";
                 case 1: return "";
                 case 2: return "Bi";
                 case 3: return "Tri";
@@ -642,7 +647,7 @@
                 case 7: return "Hept";
                 case 8: return "Oct";
                 case 9: return "Nona";
-                default: throw new IllegalArgumentException("" + argCount);
+                default: return "" + argCount + "arg";
             }
         }
 
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index f9cdf3d..dfd6f95 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -49,7 +49,7 @@
             DisplayCutout.ParcelableWrapper displayCutout) {
         if (reportDraw) {
             try {
-                mSession.finishDrawing(this);
+                mSession.finishDrawing(this, null /* postDrawTransaction */);
             } catch (RemoteException e) {
             }
         }
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 64291de..d00108e 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.view.menu;
 
-import com.android.internal.view.menu.MenuPresenter.Callback;
-
 import android.annotation.AttrRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -26,14 +24,14 @@
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.os.Build;
-import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.PopupWindow.OnDismissListener;
 
+import com.android.internal.view.menu.MenuPresenter.Callback;
+
 /**
  * Presents a menu as a small, simple popup anchored to another view.
  */
@@ -114,7 +112,7 @@
      * @param forceShowIcon {@code true} to force icons to be shown, or
      *                  {@code false} for icons to be optionally shown
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @UnsupportedAppUsage
     public void setForceShowIcon(boolean forceShowIcon) {
         mForceShowIcon = forceShowIcon;
         if (mPopup != null) {
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 07f8ee0..dc45f78 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -886,13 +886,13 @@
             return;
         }
 
+        // TODO(b/120484642): This is a location where we still use a String for vold
+        String passwordString = password != null ? new String(password) : null;
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... dummy) {
                 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
                 try {
-                    // TODO(b/120484642): This is a location where we still use a String for vold
-                    String passwordString = password != null ? new String(password) : null;
                     storageManager.changeEncryptionPassword(type, passwordString);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Error changing encryption password", e);
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 2218267..3f6c4d4 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -627,6 +627,13 @@
     }
 
     /**
+     * If there are any cells being drawn.
+     */
+    public boolean isEmpty() {
+        return mPattern.isEmpty();
+    }
+
+    /**
      * Clear the pattern lookup table. Also reset the line fade start times for
      * the next attempt.
      */
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 9fc79cb..364278d 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -194,9 +194,8 @@
     final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>();
     final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>();
 
-    final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppPermissions = new ArrayMap<>();
-    final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppDenyPermissions =
-            new ArrayMap<>();
+    final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>();
+    final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>();
 
     final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();
 
@@ -321,12 +320,20 @@
         return mProductPrivAppDenyPermissions.get(packageName);
     }
 
-    public ArraySet<String> getProductServicesPrivAppPermissions(String packageName) {
-        return mProductServicesPrivAppPermissions.get(packageName);
+    /**
+     * Read from "permission" tags in /system_ext/etc/permissions/*.xml
+     * @return Set of privileged permissions that are explicitly granted.
+     */
+    public ArraySet<String> getSystemExtPrivAppPermissions(String packageName) {
+        return mSystemExtPrivAppPermissions.get(packageName);
     }
 
-    public ArraySet<String> getProductServicesPrivAppDenyPermissions(String packageName) {
-        return mProductServicesPrivAppDenyPermissions.get(packageName);
+    /**
+     * Read from "deny-permission" tags in /system_ext/etc/permissions/*.xml
+     * @return Set of privileged permissions that are explicitly denied.
+     */
+    public ArraySet<String> getSystemExtPrivAppDenyPermissions(String packageName) {
+        return mSystemExtPrivAppDenyPermissions.get(packageName);
     }
 
     public Map<String, Boolean> getOemPermissions(String packageName) {
@@ -398,11 +405,11 @@
         readPermissions(Environment.buildPath(
                 Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL);
 
-        // Allow /product_services to customize all system configs
+        // Allow /system_ext to customize all system configs
         readPermissions(Environment.buildPath(
-                Environment.getProductServicesDirectory(), "etc", "sysconfig"), ALLOW_ALL);
+                Environment.getSystemExtDirectory(), "etc", "sysconfig"), ALLOW_ALL);
         readPermissions(Environment.buildPath(
-                Environment.getProductServicesDirectory(), "etc", "permissions"), ALLOW_ALL);
+                Environment.getSystemExtDirectory(), "etc", "permissions"), ALLOW_ALL);
     }
 
     void readPermissions(File libraryDir, int permissionFlag) {
@@ -848,7 +855,7 @@
                     } break;
                     case "privapp-permissions": {
                         if (allowPrivappPermissions) {
-                            // privapp permissions from system, vendor, product and product_services
+                            // privapp permissions from system, vendor, product and system_ext
                             // partitions are stored separately. This is to prevent xml files in
                             // the vendor partition from granting permissions to priv apps in the
                             // system partition and vice versa.
@@ -858,17 +865,17 @@
                                     Environment.getOdmDirectory().toPath() + "/");
                             boolean product = permFile.toPath().startsWith(
                                     Environment.getProductDirectory().toPath() + "/");
-                            boolean productServices = permFile.toPath().startsWith(
-                                    Environment.getProductServicesDirectory().toPath() + "/");
+                            boolean systemExt = permFile.toPath().startsWith(
+                                    Environment.getSystemExtDirectory().toPath() + "/");
                             if (vendor) {
                                 readPrivAppPermissions(parser, mVendorPrivAppPermissions,
                                         mVendorPrivAppDenyPermissions);
                             } else if (product) {
                                 readPrivAppPermissions(parser, mProductPrivAppPermissions,
                                         mProductPrivAppDenyPermissions);
-                            } else if (productServices) {
-                                readPrivAppPermissions(parser, mProductServicesPrivAppPermissions,
-                                        mProductServicesPrivAppDenyPermissions);
+                            } else if (systemExt) {
+                                readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
+                                        mSystemExtPrivAppDenyPermissions);
                             } else {
                                 readPrivAppPermissions(parser, mPrivAppPermissions,
                                         mPrivAppDenyPermissions);
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 6301db0..d42c43b 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -39,7 +39,13 @@
         "android_graphics_drawable_VectorDrawable.cpp",
         "android_graphics_Picture.cpp",
         "android_nio_utils.cpp",
+        "android_os_SystemClock.cpp",
+        "android_os_SystemProperties.cpp",
+        "android_util_EventLog.cpp",
+        "android_util_Log.cpp",
         "android_util_PathParser.cpp",
+        "android_view_DisplayListCanvas.cpp",
+        "android_view_RenderNode.cpp",
         "android/graphics/Bitmap.cpp",
         "android/graphics/BitmapFactory.cpp",
         "android/graphics/ByteBufferStreamAdaptor.cpp",
@@ -88,10 +94,10 @@
     ],
 
     shared_libs: [
-        "libandroidicu",
         "libbase",
         "libcutils",
         "libharfbuzz_ng",
+        "libhwui",
         "liblog",
         "libminikin",
         "libnativehelper",
@@ -135,18 +141,17 @@
                 "android_database_SQLiteDebug.cpp",
                 "android_view_CompositionSamplingListener.cpp",
                 "android_view_DisplayEventReceiver.cpp",
-                "android_view_DisplayListCanvas.cpp",
                 "android_view_TextureLayer.cpp",
                 "android_view_InputChannel.cpp",
                 "android_view_InputDevice.cpp",
                 "android_view_InputEventReceiver.cpp",
                 "android_view_InputEventSender.cpp",
                 "android_view_InputQueue.cpp",
+                "android_view_FrameMetricsObserver.cpp",
                 "android_view_KeyCharacterMap.cpp",
                 "android_view_KeyEvent.cpp",
                 "android_view_MotionEvent.cpp",
                 "android_view_PointerIcon.cpp",
-                "android_view_RenderNode.cpp",
                 "android_view_RenderNodeAnimator.cpp",
                 "android_view_Surface.cpp",
                 "android_view_SurfaceControl.cpp",
@@ -169,8 +174,6 @@
                 "android_os_Parcel.cpp",
                 "android_os_SELinux.cpp",
                 "android_os_SharedMemory.cpp",
-                "android_os_SystemClock.cpp",
-                "android_os_SystemProperties.cpp",
                 "android_os_Trace.cpp",
                 "android_os_UEventObserver.cpp",
                 "android_os_VintfObject.cpp",
@@ -179,8 +182,6 @@
                 "android_net_NetUtils.cpp",
                 "android_util_AssetManager.cpp",
                 "android_util_Binder.cpp",
-                "android_util_EventLog.cpp",
-                "android_util_Log.cpp",
                 "android_util_StatsLog.cpp",
                 "android_util_MemoryIntArray.cpp",
                 "android_util_Process.cpp",
@@ -266,6 +267,7 @@
             ],
 
             shared_libs: [
+                "libandroidicu",
                 "libbpf_android",
                 "libnetdbpf",
                 "libnetdutils",
@@ -315,7 +317,6 @@
                 "libhwbinder",
                 "libvintf",
                 "libnativewindow",
-                "libhwui",
                 "libdl",
                 "libdl_android",
                 "libstatslog",
@@ -345,7 +346,8 @@
                 "external/vulkan-headers/include",
             ],
             shared_libs: [
-                "libhwui-host",
+                "libicui18n",
+                "libicuuc",
             ],
             static_libs: [
                 "libandroidfw",
@@ -353,5 +355,15 @@
                 "libutils",
             ],
         },
+        linux_glibc: {
+            srcs: [
+                "android_content_res_ApkAssets.cpp",
+                "android_os_MessageQueue.cpp",
+                "android_os_Trace.cpp",
+                "android_util_AssetManager.cpp",
+                "android_util_StringBlock.cpp",
+                "android_util_XmlBlock.cpp",
+            ],
+        },
     },
-}
\ No newline at end of file
+}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 785b7a5..533f403 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -158,6 +158,7 @@
 extern int register_android_graphics_text_LineBreaker(JNIEnv *env);
 extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
 extern int register_android_view_DisplayListCanvas(JNIEnv* env);
+extern int register_android_view_FrameMetricsObserver(JNIEnv* env);
 extern int register_android_view_InputApplicationHandle(JNIEnv* env);
 extern int register_android_view_InputWindowHandle(JNIEnv* env);
 extern int register_android_view_TextureLayer(JNIEnv* env);
@@ -250,6 +251,11 @@
 // Flag to pass to the runtime when using the apex image.
 static const char* kApexImageOption = "-Ximage:/system/framework/apex.art";
 
+// Feature flag name for disabling lock profiling.
+static const char* DISABLE_LOCK_PROFILING = "disable_lock_profiling";
+// Runtime option disabling lock profiling.
+static const char* kLockProfThresholdRuntimeOption = "-Xlockprofthreshold:0";
+
 static AndroidRuntime* gCurRuntime = NULL;
 
 /*
@@ -626,7 +632,7 @@
  *
  * Returns 0 on success.
  */
-int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
+int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool primary_zygote)
 {
     JavaVMInitArgs initArgs;
     char propBuf[PROPERTY_VALUE_MAX];
@@ -698,6 +704,17 @@
         ALOGI("Using default boot image");
     }
 
+    std::string disable_lock_profiling =
+        server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
+                                                             DISABLE_LOCK_PROFILING,
+                                                             /*default_value=*/ "");
+    if (disable_lock_profiling == "true") {
+        addOption(kLockProfThresholdRuntimeOption);
+        ALOGI("Disabling lock profiling: '%s'\n", kLockProfThresholdRuntimeOption);
+    } else {
+        ALOGI("Leaving lock profiling enabled");
+    }
+
     bool checkJni = false;
     property_get("dalvik.vm.checkjni", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
@@ -746,6 +763,10 @@
     addOption("-verbose:gc");
     //addOption("-verbose:class");
 
+    if (primary_zygote) {
+        addOption("-Xprimaryzygote");
+    }
+
     /*
      * The default starting and maximum size of the heap.  Larger
      * values should be specified in a product property override.
@@ -879,20 +900,16 @@
         addOption("-Ximage-compiler-option");
         addOption("--compiler-filter=speed-profile");
     } else {
-        // Make sure there is a preloaded-classes file.
-        if (!hasFile("/system/etc/preloaded-classes")) {
-            ALOGE("Missing preloaded-classes file, /system/etc/preloaded-classes not found: %s\n",
-                  strerror(errno));
-            return -1;
-        }
-        addOption("-Ximage-compiler-option");
-        addOption("--image-classes=/system/etc/preloaded-classes");
+        ALOGE("Missing boot-image.prof file, /system/etc/boot-image.prof not found: %s\n",
+              strerror(errno));
+        return -1;
+    }
 
-        // If there is a dirty-image-objects file, push it.
-        if (hasFile("/system/etc/dirty-image-objects")) {
-            addOption("-Ximage-compiler-option");
-            addOption("--dirty-image-objects=/system/etc/dirty-image-objects");
-        }
+
+    // If there is a dirty-image-objects file, push it.
+    if (hasFile("/system/etc/dirty-image-objects")) {
+        addOption("-Ximage-compiler-option");
+        addOption("--dirty-image-objects=/system/etc/dirty-image-objects");
     }
 
     property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
@@ -1107,6 +1124,8 @@
             className != NULL ? className : "(unknown)", getuid());
 
     static const String8 startSystemServer("start-system-server");
+    // Whether this is the primary zygote, meaning the zygote which will fork system server.
+    bool primary_zygote = false;
 
     /*
      * 'startSystemServer == true' means runtime is obsolete and not run from
@@ -1114,6 +1133,7 @@
      */
     for (size_t i = 0; i < options.size(); ++i) {
         if (options[i] == startSystemServer) {
+            primary_zygote = true;
            /* track our progress through the boot sequence */
            const int LOG_BOOT_PROGRESS_START = 3000;
            LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
@@ -1149,7 +1169,7 @@
     JniInvocation jni_invocation;
     jni_invocation.Init(NULL);
     JNIEnv* env;
-    if (startVm(&mJavaVM, &env, zygote) != 0) {
+    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
         return;
     }
     onVmCreated(env);
@@ -1445,6 +1465,7 @@
     REG_JNI(register_android_view_RenderNode),
     REG_JNI(register_android_view_RenderNodeAnimator),
     REG_JNI(register_android_view_DisplayListCanvas),
+    REG_JNI(register_android_view_FrameMetricsObserver),
     REG_JNI(register_android_view_InputApplicationHandle),
     REG_JNI(register_android_view_InputWindowHandle),
     REG_JNI(register_android_view_TextureLayer),
diff --git a/core/jni/LayoutlibLoader.cpp b/core/jni/LayoutlibLoader.cpp
index b0dbb68..549fd4d 100644
--- a/core/jni/LayoutlibLoader.cpp
+++ b/core/jni/LayoutlibLoader.cpp
@@ -17,7 +17,10 @@
 #include "jni.h"
 #include "core_jni_helpers.h"
 
+#include <sstream>
+#include <iostream>
 #include <unicode/putil.h>
+#include <unordered_map>
 #include <vector>
 
 using namespace std;
@@ -46,6 +49,10 @@
 namespace android {
 
 extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
+extern int register_android_content_AssetManager(JNIEnv* env);
+extern int register_android_content_StringBlock(JNIEnv* env);
+extern int register_android_content_XmlBlock(JNIEnv* env);
+extern int register_android_content_res_ApkAssets(JNIEnv* env);
 extern int register_android_graphics_Canvas(JNIEnv* env);
 extern int register_android_graphics_ColorFilter(JNIEnv* env);
 extern int register_android_graphics_ColorSpace(JNIEnv* env);
@@ -63,7 +70,15 @@
 extern int register_android_graphics_fonts_FontFamily(JNIEnv* env);
 extern int register_android_graphics_text_LineBreaker(JNIEnv* env);
 extern int register_android_graphics_text_MeasuredText(JNIEnv* env);
+extern int register_android_os_MessageQueue(JNIEnv* env);
+extern int register_android_os_SystemClock(JNIEnv* env);
+extern int register_android_os_SystemProperties(JNIEnv* env);
+extern int register_android_os_Trace(JNIEnv* env);
+extern int register_android_util_EventLog(JNIEnv* env);
+extern int register_android_util_Log(JNIEnv* env);
 extern int register_android_util_PathParser(JNIEnv* env);
+extern int register_android_view_RenderNode(JNIEnv* env);
+extern int register_android_view_DisplayListCanvas(JNIEnv* env);
 extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
 extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
 
@@ -72,47 +87,68 @@
     int (*mProc)(JNIEnv*);
 };
 
-static const RegJNIRec gRegJNI[] = {
-    REG_JNI(register_android_animation_PropertyValuesHolder),
-    REG_JNI(register_android_graphics_Bitmap),
-    REG_JNI(register_android_graphics_BitmapFactory),
-    REG_JNI(register_android_graphics_ByteBufferStreamAdaptor),
-    REG_JNI(register_android_graphics_Canvas),
-    REG_JNI(register_android_graphics_ColorFilter),
-    REG_JNI(register_android_graphics_ColorSpace),
-    REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor),
-    REG_JNI(register_android_graphics_DrawFilter),
-    REG_JNI(register_android_graphics_FontFamily),
-    REG_JNI(register_android_graphics_Graphics),
-    REG_JNI(register_android_graphics_ImageDecoder),
-    REG_JNI(register_android_graphics_MaskFilter),
-    REG_JNI(register_android_graphics_Matrix),
-    REG_JNI(register_android_graphics_NinePatch),
-    REG_JNI(register_android_graphics_Paint),
-    REG_JNI(register_android_graphics_Path),
-    REG_JNI(register_android_graphics_PathEffect),
-    REG_JNI(register_android_graphics_PathMeasure),
-    REG_JNI(register_android_graphics_Picture),
-    REG_JNI(register_android_graphics_Region),
-    REG_JNI(register_android_graphics_Shader),
-    REG_JNI(register_android_graphics_Typeface),
-    REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable),
-    REG_JNI(register_android_graphics_drawable_VectorDrawable),
-    REG_JNI(register_android_graphics_fonts_Font),
-    REG_JNI(register_android_graphics_fonts_FontFamily),
-    REG_JNI(register_android_graphics_text_LineBreaker),
-    REG_JNI(register_android_graphics_text_MeasuredText),
-    REG_JNI(register_android_util_PathParser),
-    REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
-    REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper),
+// Map of all possible class names to register to their corresponding JNI registration function pointer
+// The actual list of registered classes will be determined at runtime via the 'native_classes' System property
+static const std::unordered_map<std::string, RegJNIRec>  gRegJNIMap = {
+    {"android.animation.PropertyValuesHolder", REG_JNI(register_android_animation_PropertyValuesHolder)},
+#ifdef __linux__
+    {"android.content.AssetManager", REG_JNI(register_android_content_AssetManager)},
+    {"android.content.StringBlock", REG_JNI(register_android_content_StringBlock)},
+    {"android.content.XmlBlock", REG_JNI(register_android_content_XmlBlock)},
+    {"android.content.res.ApkAssets", REG_JNI(register_android_content_res_ApkAssets)},
+#endif
+    {"android.graphics.Bitmap", REG_JNI(register_android_graphics_Bitmap)},
+    {"android.graphics.BitmapFactory", REG_JNI(register_android_graphics_BitmapFactory)},
+    {"android.graphics.ByteBufferStreamAdaptor", REG_JNI(register_android_graphics_ByteBufferStreamAdaptor)},
+    {"android.graphics.Canvas", REG_JNI(register_android_graphics_Canvas)},
+    {"android.graphics.RenderNode", REG_JNI(register_android_view_RenderNode)},
+    {"android.graphics.ColorFilter", REG_JNI(register_android_graphics_ColorFilter)},
+    {"android.graphics.ColorSpace", REG_JNI(register_android_graphics_ColorSpace)},
+    {"android.graphics.CreateJavaOutputStreamAdaptor", REG_JNI(register_android_graphics_CreateJavaOutputStreamAdaptor)},
+    {"android.graphics.DrawFilter", REG_JNI(register_android_graphics_DrawFilter)},
+    {"android.graphics.FontFamily", REG_JNI(register_android_graphics_FontFamily)},
+    {"android.graphics.Graphics", REG_JNI(register_android_graphics_Graphics)},
+    {"android.graphics.ImageDecoder", REG_JNI(register_android_graphics_ImageDecoder)},
+    {"android.graphics.MaskFilter", REG_JNI(register_android_graphics_MaskFilter)},
+    {"android.graphics.Matrix", REG_JNI(register_android_graphics_Matrix)},
+    {"android.graphics.NinePatch", REG_JNI(register_android_graphics_NinePatch)},
+    {"android.graphics.Paint", REG_JNI(register_android_graphics_Paint)},
+    {"android.graphics.Path", REG_JNI(register_android_graphics_Path)},
+    {"android.graphics.PathEffect", REG_JNI(register_android_graphics_PathEffect)},
+    {"android.graphics.PathMeasure", REG_JNI(register_android_graphics_PathMeasure)},
+    {"android.graphics.Picture", REG_JNI(register_android_graphics_Picture)},
+    {"android.graphics.RecordingCanvas", REG_JNI(register_android_view_DisplayListCanvas)},
+    {"android.graphics.Region", REG_JNI(register_android_graphics_Region)},
+    {"android.graphics.Shader", REG_JNI(register_android_graphics_Shader)},
+    {"android.graphics.Typeface", REG_JNI(register_android_graphics_Typeface)},
+    {"android.graphics.drawable.AnimatedVectorDrawable", REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable)},
+    {"android.graphics.drawable.VectorDrawable", REG_JNI(register_android_graphics_drawable_VectorDrawable)},
+    {"android.graphics.fonts.Font", REG_JNI(register_android_graphics_fonts_Font)},
+    {"android.graphics.fonts.FontFamily", REG_JNI(register_android_graphics_fonts_FontFamily)},
+    {"android.graphics.text.LineBreaker", REG_JNI(register_android_graphics_text_LineBreaker)},
+    {"android.graphics.text.MeasuredText", REG_JNI(register_android_graphics_text_MeasuredText)},
+#ifdef __linux__
+    {"android.os.MessageQueue", REG_JNI(register_android_os_MessageQueue)},
+#endif
+    {"android.os.SystemClock", REG_JNI(register_android_os_SystemClock)},
+    {"android.os.SystemProperties", REG_JNI(register_android_os_SystemProperties)},
+#ifdef __linux__
+    {"android.os.Trace", REG_JNI(register_android_os_Trace)},
+#endif
+    {"android.util.EventLog", REG_JNI(register_android_util_EventLog)},
+    {"android.util.Log", REG_JNI(register_android_util_Log)},
+    {"android.util.PathParser", REG_JNI(register_android_util_PathParser)},
+    {"com.android.internal.util.VirtualRefBasePtr", REG_JNI(register_com_android_internal_util_VirtualRefBasePtr)},
+    {"com.android.internal.view.animation.NativeInterpolatorFactoryHelper", REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper)},
 };
-
 // Vector to store the names of classes that need delegates of their native methods
 static vector<string> classesToDelegate;
 
-static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env) {
-    for (size_t i = 0; i < count; i++) {
-        if (array[i].mProc(env) < 0) {
+static int register_jni_procs(const std::unordered_map<std::string, RegJNIRec>& jniRegMap,
+        const vector<string>& classesToRegister, JNIEnv* env) {
+
+    for (const string& className : classesToRegister) {
+        if (jniRegMap.at(className).mProc(env) < 0) {
             return -1;
         }
     }
@@ -146,12 +182,10 @@
     }
 
     jclass clazz = env->FindClass(className);
-
     return env->RegisterNatives(clazz, gMethods, numMethods);
 }
 
-JNIEnv* AndroidRuntime::getJNIEnv()
-{
+JNIEnv* AndroidRuntime::getJNIEnv() {
     JNIEnv* env;
     if (javaVM->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK)
         return nullptr;
@@ -162,6 +196,25 @@
     return javaVM;
 }
 
+static vector<string> parseCsv(const string& csvString) {
+    vector<string>   result;
+    istringstream stream(csvString);
+    string segment;
+    while(getline(stream, segment, ','))
+    {
+        result.push_back(segment);
+    }
+    return result;
+}
+
+static vector<string> parseCsv(JNIEnv* env, jstring csvJString) {
+    const char* charArray = env->GetStringUTFChars(csvJString, 0);
+    string csvString(charArray);
+    vector<string> result = parseCsv(csvString);
+    env->ReleaseStringUTFChars(csvJString, charArray);
+    return result;
+}
+
 } // namespace android
 
 using namespace android;
@@ -173,32 +226,39 @@
         return JNI_ERR;
     }
 
+    // Configuration is stored as java System properties.
+    // Get a reference to System.getProperty
+    jclass system = FindClassOrDie(env, "java/lang/System");
+    jmethodID getPropertyMethod = GetStaticMethodIDOrDie(env, system, "getProperty",
+                                                         "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+
     // Get the names of classes that have to delegate their native methods
-    jclass createInfo = FindClassOrDie(env, "com/android/tools/layoutlib/create/CreateInfo");
-    jfieldID arrayId = GetStaticFieldIDOrDie(env, createInfo,
-            "DELEGATE_CLASS_NATIVES_TO_NATIVES", "[Ljava/lang/String;");
-    jobjectArray array = (jobjectArray) env->GetStaticObjectField(createInfo, arrayId);
-    jsize size = env->GetArrayLength(array);
+    auto delegateNativesToNativesString =
+            (jstring) env->CallStaticObjectMethod(system,
+                    getPropertyMethod, env->NewStringUTF("delegate_natives_to_natives"),
+                    env->NewStringUTF(""));
+    classesToDelegate = parseCsv(env, delegateNativesToNativesString);
 
-    for (int i=0; i < size; ++i) {
-        jstring string = (jstring) env->GetObjectArrayElement(array, i);
-        const char* charArray = env->GetStringUTFChars(string, 0);
-        std::string className = std::string(charArray);
-        std::replace(className.begin(), className.end(), '.', '/');
-        classesToDelegate.push_back(className);
-        env->ReleaseStringUTFChars(string, charArray);
-    }
+    // Get the names of classes that need to register their native methods
+    auto nativesClassesJString =
+            (jstring) env->CallStaticObjectMethod(system,
+                                                  getPropertyMethod, env->NewStringUTF("native_classes"),
+                                                  env->NewStringUTF(""));
+    vector<string> classesToRegister = parseCsv(env, nativesClassesJString);
 
-    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
+    if (register_jni_procs(gRegJNIMap, classesToRegister, env) < 0) {
         return JNI_ERR;
     }
 
     // Set the location of ICU data
-    jclass bridge = FindClassOrDie(env, "com/android/layoutlib/bridge/Bridge");
-    jstring stringPath = (jstring) env->CallStaticObjectMethod(bridge,
-            GetStaticMethodIDOrDie(env, bridge, "getIcuDataPath", "()Ljava/lang/String;"));
+    auto stringPath = (jstring) env->CallStaticObjectMethod(system,
+        getPropertyMethod, env->NewStringUTF("icu.dir"),
+        env->NewStringUTF(""));
     const char* path = env->GetStringUTFChars(stringPath, 0);
     u_setDataDirectory(path);
     env->ReleaseStringUTFChars(stringPath, path);
+
+
     return JNI_VERSION_1_6;
 }
+
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index 6934d26..06e31a1 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -18,8 +18,9 @@
 
 #include <jni.h>
 #include <android/bitmap.h>
-#include <SkBitmap.h>
-#include <SkImageInfo.h>
+
+class SkBitmap;
+struct SkImageInfo;
 
 namespace android {
 
@@ -34,8 +35,8 @@
 };
 
 jobject createBitmap(JNIEnv* env, Bitmap* bitmap,
-            int bitmapCreateFlags, jbyteArray ninePatchChunk = NULL,
-            jobject ninePatchInsets = NULL, int density = -1);
+            int bitmapCreateFlags, jbyteArray ninePatchChunk = nullptr,
+            jobject ninePatchInsets = nullptr, int density = -1);
 
 
 void toSkBitmap(jlong bitmapHandle, SkBitmap* outBitmap);
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 3e464c6..c74c264 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -23,7 +23,6 @@
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
-#include <gui/GLConsumer.h>
 #include <gui/Surface.h>
 #include <gui/BufferQueue.h>
 
@@ -131,13 +130,6 @@
     return (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
 }
 
-sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz) {
-    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
-    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, thiz));
-    sp<Surface> surfaceTextureClient(surfaceTexture != NULL ? new Surface(producer) : NULL);
-    return surfaceTextureClient;
-}
-
 bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) {
     jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
     return env->IsInstanceOf(thiz, surfaceTextureClass);
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 55abc93..58c5871 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -16,7 +16,6 @@
 
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
-#include "GraphicsJNI.h"
 
 #include <math.h>
 #include <stdio.h>
@@ -33,6 +32,7 @@
 #include <SkBitmap.h>
 
 #include "core_jni_helpers.h"
+#include "android/graphics/Bitmap.h"
 
 #undef LOG_TAG
 #define LOG_TAG "OpenGLUtil"
@@ -43,6 +43,10 @@
 
 namespace android {
 
+static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
+}
+
 static inline
 void mx4transform(float x, float y, float z, float w, const float* pM, float* pDest) {
     pDest[0] = pM[0 + 4 * 0] * x + pM[0 + 4 * 1] * y + pM[0 + 4 * 2] * z + pM[0 + 4 * 3] * w;
@@ -706,7 +710,7 @@
         jlong bitmapPtr)
 {
     SkBitmap nativeBitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&nativeBitmap);
+    bitmap::toSkBitmap(bitmapPtr, &nativeBitmap);
     return getInternalFormat(nativeBitmap.colorType());
 }
 
@@ -714,7 +718,7 @@
         jlong bitmapPtr)
 {
     SkBitmap nativeBitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&nativeBitmap);
+    bitmap::toSkBitmap(bitmapPtr, &nativeBitmap);
     return getType(nativeBitmap.colorType());
 }
 
@@ -723,7 +727,7 @@
         jlong bitmapPtr, jint type, jint border)
 {
     SkBitmap bitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
+    bitmap::toSkBitmap(bitmapPtr, &bitmap);
     SkColorType colorType = bitmap.colorType();
     if (internalformat < 0) {
         internalformat = getInternalFormat(colorType);
@@ -751,7 +755,7 @@
         jlong bitmapPtr, jint format, jint type)
 {
     SkBitmap bitmap;
-    bitmap::toBitmap(bitmapPtr).getSkBitmap(&bitmap);
+    bitmap::toSkBitmap(bitmapPtr, &bitmap);
     SkColorType colorType = bitmap.colorType();
     int internalFormat = getInternalFormat(colorType);
     if (format < 0) {
diff --git a/core/jni/android_app_ActivityThread.cpp b/core/jni/android_app_ActivityThread.cpp
index 93f2525..3a08148 100644
--- a/core/jni/android_app_ActivityThread.cpp
+++ b/core/jni/android_app_ActivityThread.cpp
@@ -15,7 +15,6 @@
  */
 
 #include "jni.h"
-#include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
 
 #include <minikin/Layout.h>
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 719cf74..87adbe8 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -26,6 +26,7 @@
 #include "core_jni_helpers.h"
 #include "android_runtime/android_view_Surface.h"
 #include "android_runtime/android_graphics_SurfaceTexture.h"
+#include "surfacetexture/SurfaceTexture.h"
 
 #include <gui/Surface.h>
 #include <gui/IGraphicBufferProducer.h>
@@ -394,10 +395,17 @@
     return anw;
 }
 
+static sp<ANativeWindow> getSurfaceTextureNativeWindow(JNIEnv* env, jobject thiz) {
+    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, thiz));
+    sp<Surface> surfaceTextureClient(surfaceTexture != NULL ? new Surface(producer) : NULL);
+    return surfaceTextureClient;
+}
+
 static sp<ANativeWindow> getNativeWindowFromTexture(JNIEnv* env, jobject surfaceTexture) {
     sp<ANativeWindow> anw;
     if (surfaceTexture) {
-        anw = android_SurfaceTexture_getNativeWindow(env, surfaceTexture);
+        anw = getSurfaceTextureNativeWindow(env, surfaceTexture);
         if (env->ExceptionCheck()) {
             return NULL;
         }
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index a1d1d4f..98680fa1e 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -23,6 +23,7 @@
 #include <utils/threads.h>
 
 #include <android/graphics/Region.h>
+#include <gui/SurfaceControl.h>
 #include <ui/Region.h>
 
 #include "android_hardware_input_InputWindowHandle.h"
@@ -32,8 +33,9 @@
 namespace android {
 
 struct WeakRefHandleField {
-    jfieldID handle;
+    jfieldID ctrl;
     jmethodID get;
+    jfieldID mNativeObject;
 };
 
 static struct {
@@ -63,7 +65,7 @@
     jfieldID displayId;
     jfieldID portalToDisplayId;
     jfieldID replaceTouchableRegionWithCrop;
-    WeakRefHandleField touchableRegionCropHandle;
+    WeakRefHandleField touchableRegionSurfaceControl;
 } gInputWindowHandleClassInfo;
 
 static Mutex gHandleMutex;
@@ -172,19 +174,27 @@
     mInfo.replaceTouchableRegionWithCrop = env->GetBooleanField(obj,
             gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop);
 
-    jobject handleObj = env->GetObjectField(obj,
-            gInputWindowHandleClassInfo.touchableRegionCropHandle.handle);
-    if (handleObj) {
+    jobject weakSurfaceCtrl = env->GetObjectField(obj,
+            gInputWindowHandleClassInfo.touchableRegionSurfaceControl.ctrl);
+    bool touchableRegionCropHandleSet = false;
+    if (weakSurfaceCtrl) {
         // Promote java weak reference.
-        jobject strongHandleObj = env->CallObjectMethod(handleObj,
-                gInputWindowHandleClassInfo.touchableRegionCropHandle.get);
-        if (strongHandleObj) {
-            mInfo.touchableRegionCropHandle = ibinderForJavaObject(env, strongHandleObj);
-            env->DeleteLocalRef(strongHandleObj);
-        } else {
-            mInfo.touchableRegionCropHandle.clear();
+        jobject strongSurfaceCtrl = env->CallObjectMethod(weakSurfaceCtrl,
+                gInputWindowHandleClassInfo.touchableRegionSurfaceControl.get);
+        if (strongSurfaceCtrl) {
+            jlong mNativeObject = env->GetLongField(strongSurfaceCtrl,
+                    gInputWindowHandleClassInfo.touchableRegionSurfaceControl.mNativeObject);
+            if (mNativeObject) {
+                auto ctrl = reinterpret_cast<SurfaceControl *>(mNativeObject);
+                mInfo.touchableRegionCropHandle = ctrl->getHandle();
+                touchableRegionCropHandleSet = true;
+            }
+            env->DeleteLocalRef(strongSurfaceCtrl);
         }
-        env->DeleteLocalRef(handleObj);
+        env->DeleteLocalRef(weakSurfaceCtrl);
+    }
+    if (!touchableRegionCropHandleSet) {
+        mInfo.touchableRegionCropHandle.clear();
     }
 
     env->DeleteLocalRef(obj);
@@ -340,11 +350,17 @@
     jclass weakRefClazz;
     FIND_CLASS(weakRefClazz, "java/lang/ref/Reference");
 
-    GET_METHOD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.get, weakRefClazz,
+    GET_METHOD_ID(gInputWindowHandleClassInfo.touchableRegionSurfaceControl.get, weakRefClazz,
              "get", "()Ljava/lang/Object;")
 
-    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.handle, clazz,
-            "touchableRegionCropHandle", "Ljava/lang/ref/WeakReference;");
+    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionSurfaceControl.ctrl, clazz,
+            "touchableRegionSurfaceControl", "Ljava/lang/ref/WeakReference;");
+
+    jclass surfaceControlClazz;
+    FIND_CLASS(surfaceControlClazz, "android/view/SurfaceControl");
+    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionSurfaceControl.mNativeObject,
+        surfaceControlClazz, "mNativeObject", "J");
+
     return 0;
 }
 
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index fc2b7f6..686a919 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2242,6 +2242,12 @@
     return AudioSystem::setAllowedCapturePolicy(uid, flags);
 }
 
+static jint
+android_media_AudioSystem_setRttEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
+{
+    return (jint) check_AudioSystem_Command(AudioSystem::setRttEnabled(enabled));
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gMethods[] = {
@@ -2319,6 +2325,7 @@
     {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
                     (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
     {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
+    {"setRttEnabled",       "(Z)I",     (void *)android_media_AudioSystem_setRttEnabled},
 };
 
 static const JNINativeMethod gEventHandlerMethods[] = {
diff --git a/core/jni/android_nio_utils.h b/core/jni/android_nio_utils.h
index aa75dd0..4aaa0a7 100644
--- a/core/jni/android_nio_utils.h
+++ b/core/jni/android_nio_utils.h
@@ -17,7 +17,7 @@
 #ifndef _ANDROID_NIO_UTILS_H_
 #define _ANDROID_NIO_UTILS_H_
 
-#include <android_runtime/AndroidRuntime.h>
+#include <nativehelper/JNIHelp.h>
 
 namespace android {
 
@@ -68,12 +68,12 @@
     AutoBufferPointer() = delete;
     AutoBufferPointer(AutoBufferPointer&) = delete;
     AutoBufferPointer& operator=(AutoBufferPointer&) = delete;
-    static void* operator new(std::size_t);
-    static void* operator new[](std::size_t);
-    static void* operator new(std::size_t, void*);
-    static void* operator new[](std::size_t, void*);
-    static void operator delete(void*, std::size_t);
-    static void operator delete[](void*, std::size_t);
+    static void* operator new(size_t);
+    static void* operator new[](size_t);
+    static void* operator new(size_t, void*);
+    static void* operator new[](size_t, void*);
+    static void operator delete(void*, size_t);
+    static void operator delete[](void*, size_t);
 };
 
 }   /* namespace android */
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 69a7c4d..c3e7a36 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -258,7 +258,7 @@
         } else if (base::StartsWith(name, "[anon:libc_malloc]")) {
             which_heap = HEAP_NATIVE;
         } else if (base::StartsWith(name, "[stack")) {
-            which_heap = HEAP_NATIVE;
+            which_heap = HEAP_STACK;
         } else if (base::EndsWith(name, ".so")) {
             which_heap = HEAP_SO;
             is_swappable = true;
@@ -289,14 +289,14 @@
         } else if (base::EndsWith(name, ".oat")) {
             which_heap = HEAP_OAT;
             is_swappable = true;
-        } else if (base::EndsWith(name, ".art")) {
+        } else if (base::EndsWith(name, ".art") || base::EndsWith(name, ".art]")) {
             which_heap = HEAP_ART;
             // Handle system@framework@boot* and system/framework/boot*
             if ((strstr(name.c_str(), "@boot") != nullptr) ||
                     (strstr(name.c_str(), "/boot"))) {
-                sub_heap = HEAP_DEX_BOOT_VDEX;
+                sub_heap = HEAP_ART_BOOT;
             } else {
-                sub_heap = HEAP_DEX_APP_VDEX;
+                sub_heap = HEAP_ART_APP;
             }
             is_swappable = true;
         } else if (base::StartsWith(name, "/dev/")) {
@@ -575,7 +575,7 @@
     if (outArray != NULL) {
         outLen = MEMINFO_COUNT;
         for (int i = 0; i < outLen; i++) {
-            if (i == MEMINFO_VMALLOC_USED) {
+            if (i == MEMINFO_VMALLOC_USED && mem[i] == 0) {
                 outArray[i] = smi.ReadVmallocInfo() / 1024;
                 continue;
             }
@@ -713,16 +713,20 @@
                                      O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_APPEND,
                                      0666));
     if (fd < 0) {
-        fprintf(stderr, "Can't open %s: %s\n", fileNameChars.c_str(), strerror(errno));
+        PLOG(ERROR) << "Can't open " << fileNameChars.c_str();
         return false;
     }
 
-    return (dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd) == 0);
+    int res = dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd);
+    if (fdatasync(fd.get()) != 0) {
+        PLOG(ERROR) << "Failed flushing trace.";
+    }
+    return res == 0;
 }
 
 static jboolean android_os_Debug_dumpJavaBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
         jint pid, jstring fileName, jint timeoutSecs) {
-    const bool ret =  dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
+    const bool ret = dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
     return ret ? JNI_TRUE : JNI_FALSE;
 }
 
diff --git a/core/jni/android_os_SystemClock.cpp b/core/jni/android_os_SystemClock.cpp
index 1f000d7..b1f6000 100644
--- a/core/jni/android_os_SystemClock.cpp
+++ b/core/jni/android_os_SystemClock.cpp
@@ -29,10 +29,8 @@
 #include "jni.h"
 #include "core_jni_helpers.h"
 
-#include <sys/time.h>
-#include <time.h>
-
 #include <utils/SystemClock.h>
+#include <utils/Timers.h>
 
 namespace android {
 
@@ -49,11 +47,7 @@
  */
 static jlong android_os_SystemClock_currentThreadTimeMillis()
 {
-    struct timespec tm;
-
-    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm);
-
-    return tm.tv_sec * 1000LL + tm.tv_nsec / 1000000;
+    return nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_THREAD));
 }
 
 /*
@@ -61,11 +55,7 @@
  */
 static jlong android_os_SystemClock_currentThreadTimeMicro()
 {
-    struct timespec tm;
-
-    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm);
-
-    return tm.tv_sec * 1000000LL + tm.tv_nsec / 1000;
+    return nanoseconds_to_microseconds(systemTime(SYSTEM_TIME_THREAD));
 }
 
 /*
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index 9ec7517..ab52314 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -19,7 +19,6 @@
 
 #include "android-base/logging.h"
 #include "android-base/properties.h"
-#include "cutils/properties.h"
 #include "utils/misc.h"
 #include <utils/Log.h>
 #include "jni.h"
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index 81428dc..bd82bd9 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -24,26 +24,29 @@
 
 namespace android {
 
-inline static void sanitizeString(char* str, size_t size) {
-    for (size_t i = 0; i < size; i++) {
-        char c = str[i];
-        if (c == '\0' || c == '\n' || c == '|') {
-            str[i] = ' ';
+inline static void sanitizeString(char* str) {
+    while (*str) {
+        char c = *str;
+        if (c == '\n' || c == '|') {
+            *str = ' ';
         }
+        str++;
     }
 }
 
-inline static void getString(JNIEnv* env, jstring jstring, char* outBuffer, jsize maxSize) {
-    jsize size = std::min(env->GetStringLength(jstring), maxSize);
-    env->GetStringUTFRegion(jstring, 0, size, outBuffer);
-    sanitizeString(outBuffer, size);
-    outBuffer[size] = '\0';
-}
-
 template<typename F>
 inline static void withString(JNIEnv* env, jstring jstr, F callback) {
-    std::array<char, 1024> buffer;
-    getString(env, jstr, buffer.data(), buffer.size());
+    // We need to handle the worst case of 1 character -> 4 bytes
+    // So make a buffer of size 4097 and let it hold a string with a maximum length
+    // of 1024. The extra last byte for the null terminator.
+    std::array<char, 4097> buffer;
+    // We have no idea of knowing how much data GetStringUTFRegion wrote, so null it out in
+    // advance so we can have a reliable null terminator
+    memset(buffer.data(), 0, buffer.size());
+    jsize size = std::min(env->GetStringLength(jstr), 1024);
+    env->GetStringUTFRegion(jstr, 0, size, buffer.data());
+    sanitizeString(buffer.data());
+
     callback(buffer.data());
 }
 
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 2b471fe..bf4ffc7 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -18,10 +18,8 @@
 #define LOG_TAG "asset"
 
 #include <inttypes.h>
-#include <linux/capability.h>
 #include <stdio.h>
 #include <sys/stat.h>
-#include <sys/system_properties.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
@@ -163,7 +161,7 @@
       }
 
       // Generic idmap parameters
-      const char* argv[10];
+      const char* argv[11];
       int argc = 0;
       struct stat st;
 
@@ -195,8 +193,8 @@
         argv[argc++] = AssetManager::PRODUCT_OVERLAY_DIR;
       }
 
-      if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) {
-        argv[argc++] = AssetManager::PRODUCT_SERVICES_OVERLAY_DIR;
+      if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) {
+        argv[argc++] = AssetManager::SYSTEM_EXT_OVERLAY_DIR;
       }
 
       if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
@@ -237,8 +235,8 @@
     input_dirs.push_back(AssetManager::PRODUCT_OVERLAY_DIR);
   }
 
-  if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) {
-    input_dirs.push_back(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR);
+  if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) {
+    input_dirs.push_back(AssetManager::SYSTEM_EXT_OVERLAY_DIR);
   }
 
   if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
@@ -399,6 +397,7 @@
   return array_map;
 }
 
+#ifdef __ANDROID__ // Layoutlib does not support parcel
 static jobject ReturnParcelFileDescriptor(JNIEnv* env, std::unique_ptr<Asset> asset,
                                           jlongArray out_offsets) {
   off64_t start_offset, length;
@@ -430,6 +429,15 @@
   }
   return newParcelFileDescriptor(env, file_desc);
 }
+#else
+static jobject ReturnParcelFileDescriptor(JNIEnv* env, std::unique_ptr<Asset> asset,
+                                          jlongArray out_offsets) {
+  jniThrowException(env, "java/lang/UnsupportedOperationException",
+                    "Implement me");
+  // never reached
+  return nullptr;
+}
+#endif
 
 static jint NativeGetGlobalAssetCount(JNIEnv* /*env*/, jobject /*clazz*/) {
   return Asset::getGlobalCount();
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index df98cdc..0afbaa0e 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -99,7 +99,9 @@
 
 static struct error_offsets_t
 {
-    jclass mClass;
+    jclass mError;
+    jclass mOutOfMemory;
+    jclass mStackOverflow;
 } gErrorOffsets;
 
 // ----------------------------------------------------------------------------
@@ -207,6 +209,16 @@
     return vm->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0 ? env : NULL;
 }
 
+static const char* GetErrorTypeName(JNIEnv* env, jthrowable error) {
+  if (env->IsInstanceOf(error, gErrorOffsets.mOutOfMemory)) {
+    return "OutOfMemoryError";
+  }
+  if (env->IsInstanceOf(error, gErrorOffsets.mStackOverflow)) {
+    return "StackOverflowError";
+  }
+  return nullptr;
+}
+
 // Report a java.lang.Error (or subclass). This will terminate the runtime by
 // calling FatalError with a message derived from the given error.
 static void report_java_lang_error_fatal_error(JNIEnv* env, jthrowable error,
@@ -216,7 +228,7 @@
 
     // Try to get the exception string. Sometimes logcat isn't available,
     // so try to add it to the abort message.
-    std::string exc_msg = "(Unknown exception message)";
+    std::string exc_msg;
     {
         ScopedLocalRef<jclass> exc_class(env, env->GetObjectClass(error));
         jmethodID method_id = env->GetMethodID(exc_class.get(), "toString",
@@ -225,15 +237,36 @@
                 env,
                 reinterpret_cast<jstring>(
                         env->CallObjectMethod(error, method_id)));
-        env->ExceptionClear();  // Just for good measure.
+        ScopedLocalRef<jthrowable> new_error(env, nullptr);
+        bool got_jstr = false;
+        if (env->ExceptionCheck()) {
+            new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
+            env->ExceptionClear();
+        }
         if (jstr.get() != nullptr) {
             ScopedUtfChars jstr_utf(env, jstr.get());
             if (jstr_utf.c_str() != nullptr) {
                 exc_msg = jstr_utf.c_str();
+                got_jstr = true;
             } else {
+                new_error = ScopedLocalRef<jthrowable>(env, env->ExceptionOccurred());
                 env->ExceptionClear();
             }
         }
+        if (!got_jstr) {
+            exc_msg = "(Unknown exception message)";
+            const char* orig_type = GetErrorTypeName(env, error);
+            if (orig_type != nullptr) {
+                exc_msg = base::StringPrintf("%s (Error was %s)", exc_msg.c_str(), orig_type);
+            }
+            const char* new_type =
+                new_error == nullptr ? nullptr : GetErrorTypeName(env, new_error.get());
+            if (new_type != nullptr) {
+                exc_msg = base::StringPrintf("%s (toString() error was %s)",
+                                             exc_msg.c_str(),
+                                             new_type);
+            }
+        }
     }
 
     env->Throw(error);
@@ -291,7 +324,7 @@
         ALOGE("%s", msg);
     }
 
-    if (env->IsInstanceOf(excep, gErrorOffsets.mClass)) {
+    if (env->IsInstanceOf(excep, gErrorOffsets.mError)) {
         report_java_lang_error(env, excep, msg);
     }
 }
@@ -1440,10 +1473,13 @@
 
 static int int_register_android_os_BinderProxy(JNIEnv* env)
 {
-    jclass clazz = FindClassOrDie(env, "java/lang/Error");
-    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
+    gErrorOffsets.mError = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Error"));
+    gErrorOffsets.mOutOfMemory =
+        MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/OutOfMemoryError"));
+    gErrorOffsets.mStackOverflow =
+        MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/StackOverflowError"));
 
-    clazz = FindClassOrDie(env, kBinderProxyPathName);
+    jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
     gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
     gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
             "(JJ)Landroid/os/BinderProxy;");
diff --git a/core/jni/android_util_Log.cpp b/core/jni/android_util_Log.cpp
index a6adc88..ad35b7d 100644
--- a/core/jni/android_util_Log.cpp
+++ b/core/jni/android_util_Log.cpp
@@ -20,7 +20,6 @@
 
 #include <android-base/macros.h>
 #include <assert.h>
-#include <cutils/properties.h>
 #include <log/log.h>               // For LOGGER_ENTRY_MAX_PAYLOAD.
 #include <utils/Log.h>
 #include <utils/String8.h>
diff --git a/core/jni/android_view_CompositionSamplingListener.cpp b/core/jni/android_view_CompositionSamplingListener.cpp
index d489ae0..783b0d4 100644
--- a/core/jni/android_view_CompositionSamplingListener.cpp
+++ b/core/jni/android_view_CompositionSamplingListener.cpp
@@ -87,11 +87,11 @@
     listener->decStrong((void*)nativeCreate);
 }
 
-void nativeRegister(JNIEnv* env, jclass clazz, jlong ptr, jobject stopLayerTokenObj,
+void nativeRegister(JNIEnv* env, jclass clazz, jlong ptr, jlong stopLayerObj,
         jint left, jint top, jint right, jint bottom) {
     sp<CompositionSamplingListener> listener = reinterpret_cast<CompositionSamplingListener*>(ptr);
-    sp<IBinder> stopLayerHandle = ibinderForJavaObject(env, stopLayerTokenObj);
-
+    auto stopLayer = reinterpret_cast<SurfaceControl*>(stopLayerObj);
+    sp<IBinder> stopLayerHandle = stopLayer != nullptr ? stopLayer->getHandle() : nullptr;
     if (SurfaceComposerClient::addRegionSamplingListener(
             Rect(left, top, right, bottom), stopLayerHandle, listener) != OK) {
         constexpr auto error_msg = "Couldn't addRegionSamplingListener";
@@ -116,7 +116,7 @@
             (void*)nativeCreate },
     { "nativeDestroy", "(J)V",
             (void*)nativeDestroy },
-    { "nativeRegister", "(JLandroid/os/IBinder;IIII)V",
+    { "nativeRegister", "(JJIIII)V",
             (void*)nativeRegister },
     { "nativeUnregister", "(J)V",
             (void*)nativeUnregister }
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 8d702d1..ba538a8 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -48,7 +48,8 @@
 class NativeDisplayEventReceiver : public DisplayEventDispatcher {
 public:
     NativeDisplayEventReceiver(JNIEnv* env,
-            jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource);
+            jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource,
+            jint configChanged);
 
     void dispose();
 
@@ -68,9 +69,11 @@
 
 
 NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env,
-        jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource) :
+        jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource,
+        jint configChanged) :
         DisplayEventDispatcher(messageQueue->getLooper(),
-                static_cast<ISurfaceComposer::VsyncSource>(vsyncSource)),
+                static_cast<ISurfaceComposer::VsyncSource>(vsyncSource),
+                static_cast<ISurfaceComposer::ConfigChanged>(configChanged)),
         mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
         mMessageQueue(messageQueue) {
     ALOGV("receiver %p ~ Initializing display event receiver.", this);
@@ -136,7 +139,7 @@
 
 
 static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
-        jobject messageQueueObj, jint vsyncSource) {
+        jobject messageQueueObj, jint vsyncSource, jint configChanged) {
     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
     if (messageQueue == NULL) {
         jniThrowRuntimeException(env, "MessageQueue is not initialized.");
@@ -144,7 +147,7 @@
     }
 
     sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
-            receiverWeak, messageQueue, vsyncSource);
+            receiverWeak, messageQueue, vsyncSource, configChanged);
     status_t status = receiver->initialize();
     if (status) {
         String8 message;
@@ -179,7 +182,7 @@
 static const JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
     { "nativeInit",
-            "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;I)J",
+            "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;II)J",
             (void*)nativeInit },
     { "nativeDispose",
             "(J)V",
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 40a133b..9907da5 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -21,9 +21,9 @@
 #include <nativehelper/JNIHelp.h>
 
 #include <android_runtime/AndroidRuntime.h>
-
+#ifdef __ANDROID__ // Layoutlib does not support Looper and device properties
 #include <utils/Looper.h>
-#include <cutils/properties.h>
+#endif
 
 #include <SkBitmap.h>
 #include <SkRegion.h>
@@ -34,7 +34,9 @@
 #include <hwui/Canvas.h>
 #include <hwui/Paint.h>
 #include <minikin/Layout.h>
+#ifdef __ANDROID__ // Layoutlib does not support RenderThread
 #include <renderthread/RenderProxy.h>
+#endif
 
 #include "core_jni_helpers.h"
 
@@ -52,6 +54,7 @@
     return env;
 }
 
+#ifdef __ANDROID__ // Layoutlib does not support GL, Looper
 class InvokeRunnableMessage : public MessageHandler {
 public:
     InvokeRunnableMessage(JNIEnv* env, jobject runnable) {
@@ -87,11 +90,13 @@
     sp<Looper> mLooper;
     sp<InvokeRunnableMessage> mMessage;
 };
+#endif
 
 // ---------------- @FastNative -----------------------------
 
 static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
         jlong canvasPtr, jlong functorPtr, jobject releasedCallback) {
+#ifdef __ANDROID__ // Layoutlib does not support GL
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     Functor* functor = reinterpret_cast<Functor*>(functorPtr);
     sp<GlFunctorReleasedCallbackBridge> bridge;
@@ -99,52 +104,57 @@
         bridge = new GlFunctorReleasedCallbackBridge(env, releasedCallback);
     }
     canvas->callDrawGLFunction(functor, bridge.get());
+#endif
 }
 
 
 // ---------------- @CriticalNative -------------------------
 
-static jlong android_view_DisplayListCanvas_createDisplayListCanvas(jlong renderNodePtr,
+static jlong android_view_DisplayListCanvas_createDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jint width, jint height) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return reinterpret_cast<jlong>(Canvas::create_recording_canvas(width, height, renderNode));
 }
 
-static void android_view_DisplayListCanvas_resetDisplayListCanvas(jlong canvasPtr,
+static void android_view_DisplayListCanvas_resetDisplayListCanvas(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
         jlong renderNodePtr, jint width, jint height) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     canvas->resetRecording(width, height, renderNode);
 }
 
-static jint android_view_DisplayListCanvas_getMaxTextureSize() {
+static jint android_view_DisplayListCanvas_getMaxTextureSize(CRITICAL_JNI_PARAMS) {
+#ifdef __ANDROID__ // Layoutlib does not support RenderProxy (RenderThread)
     return android::uirenderer::renderthread::RenderProxy::maxTextureSize();
+#else
+    return 4096;
+#endif
 }
 
-static void android_view_DisplayListCanvas_insertReorderBarrier(jlong canvasPtr,
+static void android_view_DisplayListCanvas_insertReorderBarrier(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
         jboolean reorderEnable) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     canvas->insertReorderBarrier(reorderEnable);
 }
 
-static jlong android_view_DisplayListCanvas_finishRecording(jlong canvasPtr) {
+static jlong android_view_DisplayListCanvas_finishRecording(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     return reinterpret_cast<jlong>(canvas->finishRecording());
 }
 
-static void android_view_DisplayListCanvas_drawRenderNode(jlong canvasPtr, jlong renderNodePtr) {
+static void android_view_DisplayListCanvas_drawRenderNode(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong renderNodePtr) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     canvas->drawRenderNode(renderNode);
 }
 
-static void android_view_DisplayListCanvas_drawTextureLayer(jlong canvasPtr, jlong layerPtr) {
+static void android_view_DisplayListCanvas_drawTextureLayer(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong layerPtr) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
     canvas->drawLayer(layer);
 }
 
-static void android_view_DisplayListCanvas_drawRoundRectProps(jlong canvasPtr,
+static void android_view_DisplayListCanvas_drawRoundRectProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
         jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr, jlong bottomPropPtr,
         jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
@@ -158,7 +168,7 @@
     canvas->drawRoundRect(leftProp, topProp, rightProp, bottomProp, rxProp, ryProp, paintProp);
 }
 
-static void android_view_DisplayListCanvas_drawCircleProps(jlong canvasPtr,
+static void android_view_DisplayListCanvas_drawCircleProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
         jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
@@ -168,7 +178,7 @@
     canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
 }
 
-static void android_view_DisplayListCanvas_drawWebViewFunctor(jlong canvasPtr, jint functor) {
+static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jint functor) {
     Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
     canvas->drawWebViewFunctor(functor);
 }
diff --git a/core/jni/android_view_FrameMetricsObserver.cpp b/core/jni/android_view_FrameMetricsObserver.cpp
new file mode 100644
index 0000000..febcb55
--- /dev/null
+++ b/core/jni/android_view_FrameMetricsObserver.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_view_FrameMetricsObserver.h"
+
+namespace android {
+
+struct {
+    jfieldID frameMetrics;
+    jfieldID timingDataBuffer;
+    jfieldID messageQueue;
+    jmethodID callback;
+} gFrameMetricsObserverClassInfo;
+
+static JNIEnv* getenv(JavaVM* vm) {
+    JNIEnv* env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
+    }
+    return env;
+}
+
+static jlongArray get_metrics_buffer(JNIEnv* env, jobject observer) {
+    jobject frameMetrics = env->GetObjectField(
+            observer, gFrameMetricsObserverClassInfo.frameMetrics);
+    LOG_ALWAYS_FATAL_IF(frameMetrics == nullptr, "unable to retrieve data sink object");
+    jobject buffer = env->GetObjectField(
+            frameMetrics, gFrameMetricsObserverClassInfo.timingDataBuffer);
+    LOG_ALWAYS_FATAL_IF(buffer == nullptr, "unable to retrieve data sink buffer");
+    return reinterpret_cast<jlongArray>(buffer);
+}
+
+class NotifyHandler : public MessageHandler {
+public:
+    NotifyHandler(JavaVM* vm, FrameMetricsObserverProxy* observer) : mVm(vm), mObserver(observer) {}
+
+    virtual void handleMessage(const Message& message);
+
+private:
+    JavaVM* const mVm;
+    FrameMetricsObserverProxy* const mObserver;
+};
+
+void NotifyHandler::handleMessage(const Message& message) {
+    JNIEnv* env = getenv(mVm);
+
+    jobject target = env->NewLocalRef(mObserver->getObserverReference());
+
+    if (target != nullptr) {
+        jlongArray javaBuffer = get_metrics_buffer(env, target);
+        int dropCount = 0;
+        while (mObserver->getNextBuffer(env, javaBuffer, &dropCount)) {
+            env->CallVoidMethod(target, gFrameMetricsObserverClassInfo.callback, dropCount);
+        }
+        env->DeleteLocalRef(target);
+    }
+
+    mObserver->decStrong(nullptr);
+}
+
+FrameMetricsObserverProxy::FrameMetricsObserverProxy(JavaVM *vm, jobject observer) : mVm(vm) {
+    JNIEnv* env = getenv(mVm);
+
+    mObserverWeak = env->NewWeakGlobalRef(observer);
+    LOG_ALWAYS_FATAL_IF(mObserverWeak == nullptr,
+            "unable to create frame stats observer reference");
+
+    jlongArray buffer = get_metrics_buffer(env, observer);
+    jsize bufferSize = env->GetArrayLength(reinterpret_cast<jarray>(buffer));
+    LOG_ALWAYS_FATAL_IF(bufferSize != kBufferSize,
+            "Mismatched Java/Native FrameMetrics data format.");
+
+    jobject messageQueueLocal = env->GetObjectField(
+            observer, gFrameMetricsObserverClassInfo.messageQueue);
+    mMessageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueLocal);
+    LOG_ALWAYS_FATAL_IF(mMessageQueue == nullptr, "message queue not available");
+
+    mMessageHandler = new NotifyHandler(mVm, this);
+    LOG_ALWAYS_FATAL_IF(mMessageHandler == nullptr,
+            "OOM: unable to allocate NotifyHandler");
+}
+
+FrameMetricsObserverProxy::~FrameMetricsObserverProxy() {
+    JNIEnv* env = getenv(mVm);
+    env->DeleteWeakGlobalRef(mObserverWeak);
+}
+
+bool FrameMetricsObserverProxy::getNextBuffer(JNIEnv* env, jlongArray sink, int* dropCount) {
+    FrameMetricsNotification& elem = mRingBuffer[mNextInQueue];
+
+    if (elem.hasData.load()) {
+        env->SetLongArrayRegion(sink, 0, kBufferSize, elem.buffer);
+        *dropCount = elem.dropCount;
+        mNextInQueue = (mNextInQueue + 1) % kRingSize;
+        elem.hasData = false;
+        return true;
+    }
+
+    return false;
+}
+
+void FrameMetricsObserverProxy::notify(const int64_t* stats) {
+    FrameMetricsNotification& elem = mRingBuffer[mNextFree];
+
+    if (!elem.hasData.load()) {
+        memcpy(elem.buffer, stats, kBufferSize * sizeof(stats[0]));
+
+        elem.dropCount = mDroppedReports;
+        mDroppedReports = 0;
+
+        incStrong(nullptr);
+        mNextFree = (mNextFree + 1) % kRingSize;
+        elem.hasData = true;
+
+        mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage);
+    } else {
+        mDroppedReports++;
+    }
+}
+
+int register_android_view_FrameMetricsObserver(JNIEnv* env) {
+    jclass observerClass = FindClassOrDie(env, "android/view/FrameMetricsObserver");
+    gFrameMetricsObserverClassInfo.frameMetrics = GetFieldIDOrDie(
+            env, observerClass, "mFrameMetrics", "Landroid/view/FrameMetrics;");
+    gFrameMetricsObserverClassInfo.messageQueue = GetFieldIDOrDie(
+            env, observerClass, "mMessageQueue", "Landroid/os/MessageQueue;");
+    gFrameMetricsObserverClassInfo.callback = GetMethodIDOrDie(
+            env, observerClass, "notifyDataAvailable", "(I)V");
+
+    jclass metricsClass = FindClassOrDie(env, "android/view/FrameMetrics");
+    gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie(
+            env, metricsClass, "mTimingData", "[J");
+    return JNI_OK;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/core/jni/android_view_FrameMetricsObserver.h b/core/jni/android_view_FrameMetricsObserver.h
new file mode 100644
index 0000000..647f51c
--- /dev/null
+++ b/core/jni/android_view_FrameMetricsObserver.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni.h"
+#include "core_jni_helpers.h"
+
+#include "android_os_MessageQueue.h"
+
+#include <FrameInfo.h>
+#include <FrameMetricsObserver.h>
+
+namespace android {
+
+/*
+ * Implements JNI layer for hwui frame metrics reporting.
+ */
+class FrameMetricsObserverProxy : public uirenderer::FrameMetricsObserver {
+public:
+    FrameMetricsObserverProxy(JavaVM *vm, jobject observer);
+
+    ~FrameMetricsObserverProxy();
+
+    jweak getObserverReference() {
+        return mObserverWeak;
+    }
+
+    bool getNextBuffer(JNIEnv* env, jlongArray sink, int* dropCount);
+
+    virtual void notify(const int64_t* stats);
+
+private:
+    static const int kBufferSize = static_cast<int>(uirenderer::FrameInfoIndex::NumIndexes);
+    static constexpr int kRingSize = 3;
+
+    class FrameMetricsNotification {
+    public:
+        FrameMetricsNotification() : hasData(false) {}
+
+        std::atomic_bool hasData;
+        int64_t buffer[kBufferSize];
+        int dropCount = 0;
+    };
+
+    JavaVM* const mVm;
+    jweak mObserverWeak;
+
+    sp<MessageQueue> mMessageQueue;
+    sp<MessageHandler> mMessageHandler;
+    Message mMessage;
+
+    int mNextFree = 0;
+    int mNextInQueue = 0;
+    FrameMetricsNotification mRingBuffer[kRingSize];
+
+    int mDroppedReports = 0;
+};
+
+} // namespace android
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 9819d9a..7e3b083 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -175,6 +175,15 @@
     }
 }
 
+static void android_view_InputChannel_nativeRelease(JNIEnv* env, jobject obj, jboolean finalized) {
+    NativeInputChannel* nativeInputChannel =
+            android_view_InputChannel_getNativeInputChannel(env, obj);
+    if (nativeInputChannel) {
+        android_view_InputChannel_setNativeInputChannel(env, obj, NULL);
+        delete nativeInputChannel;
+    }
+}
+
 static void android_view_InputChannel_nativeTransferTo(JNIEnv* env, jobject obj,
         jobject otherObj) {
     if (android_view_InputChannel_getNativeInputChannel(env, otherObj) != NULL) {
@@ -274,6 +283,8 @@
             (void*)android_view_InputChannel_nativeOpenInputChannelPair },
     { "nativeDispose", "(Z)V",
             (void*)android_view_InputChannel_nativeDispose },
+    { "nativeRelease", "()V",
+            (void*)android_view_InputChannel_nativeRelease },
     { "nativeTransferTo", "(Landroid/view/InputChannel;)V",
             (void*)android_view_InputChannel_nativeTransferTo },
     { "nativeReadFromParcel", "(Landroid/os/Parcel;)V",
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 2542286..f90d1cf 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -141,6 +141,7 @@
                 event->getClassification(),
                 event->getXOffset(), event->getYOffset(),
                 event->getXPrecision(), event->getYPrecision(),
+                event->getRawXCursorPosition(), event->getRawYCursorPosition(),
                 event->getDownTime(), event->getHistoricalEventTime(i),
                 event->getPointerCount(), event->getPointerProperties(),
                 event->getHistoricalRawPointerCoords(0, i));
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 50cff5c..8ddbe72 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -375,6 +375,7 @@
     event->initialize(deviceId, source, displayId, action, 0, flags, edgeFlags, metaState,
             buttonState, static_cast<MotionClassification>(classification),
             xOffset, yOffset, xPrecision, yPrecision,
+            AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
             downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
 
     return reinterpret_cast<jlong>(event);
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 43c0bbe..9450bc9 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -16,9 +16,9 @@
 
 #define LOG_TAG "OpenGLRenderer"
 #define ATRACE_TAG ATRACE_TAG_VIEW
-
+#ifdef __ANDROID__ // Layoutlib does not support EGL
 #include <EGL/egl.h>
-
+#endif
 #include "jni.h"
 #include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
@@ -28,7 +28,9 @@
 #include <DamageAccumulator.h>
 #include <Matrix.h>
 #include <RenderNode.h>
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
 #include <renderthread/CanvasContext.h>
+#endif
 #include <TreeInfo.h>
 #include <hwui/Paint.h>
 #include <utils/TraceUtils.h>
@@ -85,7 +87,7 @@
     renderNode->setStagingDisplayList(newData);
 }
 
-static jboolean android_view_RenderNode_isValid(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_isValid(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->isValid();
 }
 
@@ -93,52 +95,52 @@
 // RenderProperties - setters
 // ----------------------------------------------------------------------------
 
-static jboolean android_view_RenderNode_setLayerType(jlong renderNodePtr, jint jlayerType) {
+static jboolean android_view_RenderNode_setLayerType(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint jlayerType) {
     LayerType layerType = static_cast<LayerType>(jlayerType);
     return SET_AND_DIRTY(mutateLayerProperties().setType, layerType, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setLayerPaint(jlong renderNodePtr, jlong paintPtr) {
+static jboolean android_view_RenderNode_setLayerPaint(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong paintPtr) {
     Paint* paint = reinterpret_cast<Paint*>(paintPtr);
     return SET_AND_DIRTY(mutateLayerProperties().setFromPaint, paint, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setStaticMatrix(jlong renderNodePtr, jlong matrixPtr) {
+static jboolean android_view_RenderNode_setStaticMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong matrixPtr) {
     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
     return SET_AND_DIRTY(setStaticMatrix, matrix, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setAnimationMatrix(jlong renderNodePtr, jlong matrixPtr) {
+static jboolean android_view_RenderNode_setAnimationMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong matrixPtr) {
     SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
     return SET_AND_DIRTY(setAnimationMatrix, matrix, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setClipToBounds(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setClipToBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jboolean clipToBounds) {
     return SET_AND_DIRTY(setClipToBounds, clipToBounds, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setClipBounds(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setClipBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jint left, jint top, jint right, jint bottom) {
     android::uirenderer::Rect clipBounds(left, top, right, bottom);
     return SET_AND_DIRTY(setClipBounds, clipBounds, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setClipBoundsEmpty(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_setClipBoundsEmpty(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return SET_AND_DIRTY(setClipBoundsEmpty,, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setProjectBackwards(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setProjectBackwards(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jboolean shouldProject) {
     return SET_AND_DIRTY(setProjectBackwards, shouldProject, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setProjectionReceiver(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setProjectionReceiver(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jboolean shouldRecieve) {
     return SET_AND_DIRTY(setProjectionReceiver, shouldRecieve, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setOutlineRoundRect(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setOutlineRoundRect(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jint left, jint top, jint right, jint bottom, jfloat radius, jfloat alpha) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableOutline().setRoundRect(left, top, right, bottom,
@@ -147,7 +149,7 @@
     return true;
 }
 
-static jboolean android_view_RenderNode_setOutlineConvexPath(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setOutlineConvexPath(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jlong outlinePathPtr, jfloat alpha) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
@@ -156,47 +158,47 @@
     return true;
 }
 
-static jboolean android_view_RenderNode_setOutlineEmpty(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_setOutlineEmpty(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableOutline().setEmpty();
     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
     return true;
 }
 
-static jboolean android_view_RenderNode_setOutlineNone(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_setOutlineNone(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableOutline().setNone();
     renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
     return true;
 }
 
-static jboolean android_view_RenderNode_hasShadow(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_hasShadow(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().hasShadow();
 }
 
-static jboolean android_view_RenderNode_setSpotShadowColor(jlong renderNodePtr, jint shadowColor) {
+static jboolean android_view_RenderNode_setSpotShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint shadowColor) {
     return SET_AND_DIRTY(setSpotShadowColor,
             static_cast<SkColor>(shadowColor), RenderNode::GENERIC);
 }
 
-static jint android_view_RenderNode_getSpotShadowColor(jlong renderNodePtr) {
+static jint android_view_RenderNode_getSpotShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getSpotShadowColor();
 }
 
-static jboolean android_view_RenderNode_setAmbientShadowColor(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setAmbientShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jint shadowColor) {
     return SET_AND_DIRTY(setAmbientShadowColor,
             static_cast<SkColor>(shadowColor), RenderNode::GENERIC);
 }
 
-static jint android_view_RenderNode_getAmbientShadowColor(jlong renderNodePtr) {
+static jint android_view_RenderNode_getAmbientShadowColor(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getAmbientShadowColor();
 }
 
-static jboolean android_view_RenderNode_setClipToOutline(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setClipToOutline(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jboolean clipToOutline) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableOutline().setShouldClip(clipToOutline);
@@ -204,7 +206,7 @@
     return true;
 }
 
-static jboolean android_view_RenderNode_setRevealClip(jlong renderNodePtr, jboolean shouldClip,
+static jboolean android_view_RenderNode_setRevealClip(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jboolean shouldClip,
         jfloat x, jfloat y, jfloat radius) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().mutableRevealClip().set(
@@ -213,106 +215,106 @@
     return true;
 }
 
-static jboolean android_view_RenderNode_setAlpha(jlong renderNodePtr, float alpha) {
+static jboolean android_view_RenderNode_setAlpha(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float alpha) {
     return SET_AND_DIRTY(setAlpha, alpha, RenderNode::ALPHA);
 }
 
-static jboolean android_view_RenderNode_setHasOverlappingRendering(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setHasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         bool hasOverlappingRendering) {
     return SET_AND_DIRTY(setHasOverlappingRendering, hasOverlappingRendering,
             RenderNode::GENERIC);
 }
 
-static void android_view_RenderNode_setUsageHint(jlong renderNodePtr, jint usageHint) {
+static void android_view_RenderNode_setUsageHint(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint usageHint) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->setUsageHint(static_cast<UsageHint>(usageHint));
 }
 
-static jboolean android_view_RenderNode_setElevation(jlong renderNodePtr, float elevation) {
+static jboolean android_view_RenderNode_setElevation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float elevation) {
     return SET_AND_DIRTY(setElevation, elevation, RenderNode::Z);
 }
 
-static jboolean android_view_RenderNode_setTranslationX(jlong renderNodePtr, float tx) {
+static jboolean android_view_RenderNode_setTranslationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float tx) {
     return SET_AND_DIRTY(setTranslationX, tx, RenderNode::TRANSLATION_X | RenderNode::X);
 }
 
-static jboolean android_view_RenderNode_setTranslationY(jlong renderNodePtr, float ty) {
+static jboolean android_view_RenderNode_setTranslationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float ty) {
     return SET_AND_DIRTY(setTranslationY, ty, RenderNode::TRANSLATION_Y | RenderNode::Y);
 }
 
-static jboolean android_view_RenderNode_setTranslationZ(jlong renderNodePtr, float tz) {
+static jboolean android_view_RenderNode_setTranslationZ(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float tz) {
     return SET_AND_DIRTY(setTranslationZ, tz, RenderNode::TRANSLATION_Z | RenderNode::Z);
 }
 
-static jboolean android_view_RenderNode_setRotation(jlong renderNodePtr, float rotation) {
+static jboolean android_view_RenderNode_setRotation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float rotation) {
     return SET_AND_DIRTY(setRotation, rotation, RenderNode::ROTATION);
 }
 
-static jboolean android_view_RenderNode_setRotationX(jlong renderNodePtr, float rx) {
+static jboolean android_view_RenderNode_setRotationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float rx) {
     return SET_AND_DIRTY(setRotationX, rx, RenderNode::ROTATION_X);
 }
 
-static jboolean android_view_RenderNode_setRotationY(jlong renderNodePtr, float ry) {
+static jboolean android_view_RenderNode_setRotationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float ry) {
     return SET_AND_DIRTY(setRotationY, ry, RenderNode::ROTATION_Y);
 }
 
-static jboolean android_view_RenderNode_setScaleX(jlong renderNodePtr, float sx) {
+static jboolean android_view_RenderNode_setScaleX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float sx) {
     return SET_AND_DIRTY(setScaleX, sx, RenderNode::SCALE_X);
 }
 
-static jboolean android_view_RenderNode_setScaleY(jlong renderNodePtr, float sy) {
+static jboolean android_view_RenderNode_setScaleY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float sy) {
     return SET_AND_DIRTY(setScaleY, sy, RenderNode::SCALE_Y);
 }
 
-static jboolean android_view_RenderNode_setPivotX(jlong renderNodePtr, float px) {
+static jboolean android_view_RenderNode_setPivotX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float px) {
     return SET_AND_DIRTY(setPivotX, px, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setPivotY(jlong renderNodePtr, float py) {
+static jboolean android_view_RenderNode_setPivotY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float py) {
     return SET_AND_DIRTY(setPivotY, py, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_resetPivot(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_resetPivot(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return SET_AND_DIRTY(resetPivot, /* void */, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setCameraDistance(jlong renderNodePtr, float distance) {
+static jboolean android_view_RenderNode_setCameraDistance(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, float distance) {
     return SET_AND_DIRTY(setCameraDistance, distance, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_setLeft(jlong renderNodePtr, int left) {
+static jboolean android_view_RenderNode_setLeft(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int left) {
     return SET_AND_DIRTY(setLeft, left, RenderNode::X);
 }
 
-static jboolean android_view_RenderNode_setTop(jlong renderNodePtr, int top) {
+static jboolean android_view_RenderNode_setTop(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int top) {
     return SET_AND_DIRTY(setTop, top, RenderNode::Y);
 }
 
-static jboolean android_view_RenderNode_setRight(jlong renderNodePtr, int right) {
+static jboolean android_view_RenderNode_setRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int right) {
     return SET_AND_DIRTY(setRight, right, RenderNode::X);
 }
 
-static jboolean android_view_RenderNode_setBottom(jlong renderNodePtr, int bottom) {
+static jboolean android_view_RenderNode_setBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, int bottom) {
     return SET_AND_DIRTY(setBottom, bottom, RenderNode::Y);
 }
 
-static jint android_view_RenderNode_getLeft(jlong renderNodePtr) {
+static jint android_view_RenderNode_getLeft(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getLeft();
 }
 
-static jint android_view_RenderNode_getTop(jlong renderNodePtr) {
+static jint android_view_RenderNode_getTop(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getTop();
 }
 
-static jint android_view_RenderNode_getRight(jlong renderNodePtr) {
+static jint android_view_RenderNode_getRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getRight();
 }
 
-static jint android_view_RenderNode_getBottom(jlong renderNodePtr) {
+static jint android_view_RenderNode_getBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getBottom();
 }
 
-static jboolean android_view_RenderNode_setLeftTopRightBottom(jlong renderNodePtr,
+static jboolean android_view_RenderNode_setLeftTopRightBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         int left, int top, int right, int bottom) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     if (renderNode->mutateStagingProperties().setLeftTopRightBottom(left, top, right, bottom)) {
@@ -322,11 +324,11 @@
     return false;
 }
 
-static jboolean android_view_RenderNode_offsetLeftAndRight(jlong renderNodePtr, jint offset) {
+static jboolean android_view_RenderNode_offsetLeftAndRight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint offset) {
     return SET_AND_DIRTY(offsetLeftRight, offset, RenderNode::X);
 }
 
-static jboolean android_view_RenderNode_offsetTopAndBottom(jlong renderNodePtr, jint offset) {
+static jboolean android_view_RenderNode_offsetTopAndBottom(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jint offset) {
     return SET_AND_DIRTY(offsetTopBottom, offset, RenderNode::Y);
 }
 
@@ -334,12 +336,12 @@
 // RenderProperties - getters
 // ----------------------------------------------------------------------------
 
-static jboolean android_view_RenderNode_hasOverlappingRendering(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_hasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().hasOverlappingRendering();
 }
 
-static jboolean android_view_RenderNode_getAnimationMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
+static jboolean android_view_RenderNode_getAnimationMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong outMatrixPtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
 
@@ -352,83 +354,83 @@
     return JNI_FALSE;
 }
 
-static jboolean android_view_RenderNode_getClipToBounds(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_getClipToBounds(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getClipToBounds();
 }
 
-static jboolean android_view_RenderNode_getClipToOutline(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_getClipToOutline(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getOutline().getShouldClip();
 }
 
-static jfloat android_view_RenderNode_getAlpha(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getAlpha(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getAlpha();
 }
 
-static jfloat android_view_RenderNode_getCameraDistance(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getCameraDistance(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getCameraDistance();
 }
 
-static jfloat android_view_RenderNode_getScaleX(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getScaleX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getScaleX();
 }
 
-static jfloat android_view_RenderNode_getScaleY(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getScaleY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getScaleY();
 }
 
-static jfloat android_view_RenderNode_getElevation(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getElevation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getElevation();
 }
 
-static jfloat android_view_RenderNode_getTranslationX(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getTranslationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getTranslationX();
 }
 
-static jfloat android_view_RenderNode_getTranslationY(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getTranslationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getTranslationY();
 }
 
-static jfloat android_view_RenderNode_getTranslationZ(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getTranslationZ(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getTranslationZ();
 }
 
-static jfloat android_view_RenderNode_getRotation(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getRotation(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getRotation();
 }
 
-static jfloat android_view_RenderNode_getRotationX(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getRotationX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getRotationX();
 }
 
-static jfloat android_view_RenderNode_getRotationY(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getRotationY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().getRotationY();
 }
 
-static jboolean android_view_RenderNode_isPivotExplicitlySet(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_isPivotExplicitlySet(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return renderNode->stagingProperties().isPivotExplicitlySet();
 }
 
-static jboolean android_view_RenderNode_hasIdentityMatrix(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_hasIdentityMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().updateMatrix();
     return !renderNode->stagingProperties().hasTransformMatrix();
 }
 
-static jint android_view_RenderNode_getLayerType(jlong renderNodePtr) {
+static jint android_view_RenderNode_getLayerType(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     return static_cast<int>(renderNode->stagingProperties().layerProperties().type());
 }
@@ -437,7 +439,7 @@
 // RenderProperties - computed getters
 // ----------------------------------------------------------------------------
 
-static void android_view_RenderNode_getTransformMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
+static void getTransformMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
 
@@ -451,10 +453,14 @@
     }
 }
 
-static void android_view_RenderNode_getInverseTransformMatrix(jlong renderNodePtr,
+static void android_view_RenderNode_getTransformMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong outMatrixPtr) {
+    getTransformMatrix(renderNodePtr, outMatrixPtr);
+}
+
+static void android_view_RenderNode_getInverseTransformMatrix(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
         jlong outMatrixPtr) {
     // load transform matrix
-    android_view_RenderNode_getTransformMatrix(renderNodePtr, outMatrixPtr);
+    getTransformMatrix(renderNodePtr, outMatrixPtr);
     SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
 
     // return it inverted
@@ -464,35 +470,35 @@
     }
 }
 
-static jfloat android_view_RenderNode_getPivotX(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getPivotX(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().updateMatrix();
     return renderNode->stagingProperties().getPivotX();
 }
 
-static jfloat android_view_RenderNode_getPivotY(jlong renderNodePtr) {
+static jfloat android_view_RenderNode_getPivotY(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
     renderNode->mutateStagingProperties().updateMatrix();
     return renderNode->stagingProperties().getPivotY();
 }
 
-static jint android_view_RenderNode_getWidth(jlong renderNodePtr) {
+static jint android_view_RenderNode_getWidth(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getWidth();
 }
 
-static jint android_view_RenderNode_getHeight(jlong renderNodePtr) {
+static jint android_view_RenderNode_getHeight(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getHeight();
 }
 
-static jboolean android_view_RenderNode_setAllowForceDark(jlong renderNodePtr, jboolean allow) {
+static jboolean android_view_RenderNode_setAllowForceDark(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jboolean allow) {
     return SET_AND_DIRTY(setAllowForceDark, allow, RenderNode::GENERIC);
 }
 
-static jboolean android_view_RenderNode_getAllowForceDark(jlong renderNodePtr) {
+static jboolean android_view_RenderNode_getAllowForceDark(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getAllowForceDark();
 }
 
-static jlong android_view_RenderNode_getUniqueId(jlong renderNodePtr) {
+static jlong android_view_RenderNode_getUniqueId(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
     return reinterpret_cast<RenderNode*>(renderNodePtr)->uniqueId();
 }
 
@@ -558,6 +564,7 @@
             }
             mPreviousPosition = bounds;
 
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
             incStrong(0);
             auto functor = std::bind(
                 std::mem_fn(&PositionListenerTrampoline::doUpdatePositionAsync), this,
@@ -566,6 +573,7 @@
                 (jint) bounds.right, (jint) bounds.bottom);
 
             info.canvasContext.enqueueFrameWork(std::move(functor));
+#endif
         }
 
         virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override {
@@ -584,10 +592,11 @@
                 mWeakRef = nullptr;
                 return;
             }
-
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
             // TODO: Remember why this is synchronous and then make a comment
             env->CallVoidMethod(localref, gPositionListener_PositionLostMethod,
                     info ? info->canvasContext.getFrameNumber() : 0);
+#endif
             env->DeleteLocalRef(localref);
         }
 
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
index c9eac79..ca32b00 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -17,7 +17,6 @@
 #define LOG_TAG "OpenGLRenderer"
 
 #include "jni.h"
-#include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
 #include <android_runtime/AndroidRuntime.h>
 
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index ccadc7d..0d95f99 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -34,7 +34,6 @@
 #include <gui/Surface.h>
 #include <gui/view/Surface.h>
 #include <gui/SurfaceControl.h>
-#include <gui/GLConsumer.h>
 
 #include <ui/Rect.h>
 #include <ui/Region.h>
@@ -75,6 +74,24 @@
     jfieldID bottom;
 } gRectClassInfo;
 
+class JNamedColorSpace {
+public:
+    // ColorSpace.Named.SRGB.ordinal() = 0;
+    static constexpr jint SRGB = 0;
+
+    // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
+    static constexpr jint DISPLAY_P3 = 7;
+};
+
+constexpr ui::Dataspace fromNamedColorSpaceValueToDataspace(const jint colorSpace) {
+    switch (colorSpace) {
+        case JNamedColorSpace::DISPLAY_P3:
+            return ui::Dataspace::DISPLAY_P3;
+        default:
+            return ui::Dataspace::V0_SRGB;
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 // this is just a pointer we use to pass to inc/decStrong
@@ -126,19 +143,6 @@
     return android_view_Surface_createFromSurface(env, surface);
 }
 
-int android_view_Surface_mapPublicFormatToHalFormat(PublicFormat f) {
-    return mapPublicFormatToHalFormat(f);
-}
-
-android_dataspace android_view_Surface_mapPublicFormatToHalDataspace(
-        PublicFormat f) {
-    return mapPublicFormatToHalDataspace(f);
-}
-
-PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
-        int format, android_dataspace dataSpace) {
-    return mapHalFormatDataspaceToPublicFormat(format, dataSpace);
-}
 // ----------------------------------------------------------------------------
 
 static inline bool isSurfaceValid(const sp<Surface>& sur) {
@@ -425,11 +429,12 @@
     return surface->disconnect(-1, IGraphicBufferProducer::DisconnectMode::AllLocal);
 }
 
-static jint nativeAttachAndQueueBuffer(JNIEnv *env, jclass clazz, jlong nativeObject,
-        jobject graphicBuffer) {
+static jint nativeAttachAndQueueBufferWithColorSpace(JNIEnv *env, jclass clazz, jlong nativeObject,
+        jobject graphicBuffer, jint colorSpaceId) {
     Surface* surface = reinterpret_cast<Surface*>(nativeObject);
     sp<GraphicBuffer> bp = graphicBufferForJavaObject(env, graphicBuffer);
-    int err = Surface::attachAndQueueBuffer(surface, bp);
+    int err = Surface::attachAndQueueBufferWithDataspace(surface, bp,
+            fromNamedColorSpaceValueToDataspace(colorSpaceId));
     return err;
 }
 
@@ -485,7 +490,7 @@
 
 static void draw(JNIEnv* env, jclass clazz, jlong rendererPtr) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(rendererPtr);
-    nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
+    nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
     UiFrameInfoBuilder(proxy->frameInfo())
             .setVsync(vsync, vsync)
             .addFlag(FrameInfoFlags::SurfaceCanvas);
@@ -531,7 +536,8 @@
     {"nativeGetNextFrameNumber", "(J)J", (void*)nativeGetNextFrameNumber },
     {"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode },
     {"nativeForceScopedDisconnect", "(J)I", (void*)nativeForceScopedDisconnect},
-    {"nativeAttachAndQueueBuffer", "(JLandroid/graphics/GraphicBuffer;)I", (void*)nativeAttachAndQueueBuffer},
+    {"nativeAttachAndQueueBufferWithColorSpace", "(JLandroid/graphics/GraphicBuffer;I)I",
+            (void*)nativeAttachAndQueueBufferWithColorSpace},
     {"nativeSetSharedBufferModeEnabled", "(JZ)I", (void*)nativeSetSharedBufferModeEnabled},
     {"nativeSetAutoRefreshEnabled", "(JZ)I", (void*)nativeSetAutoRefreshEnabled},
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 986771d..a579229 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -21,10 +21,10 @@
 #include "android_util_Binder.h"
 #include "android_hardware_input_InputWindowHandle.h"
 #include "android/graphics/Bitmap.h"
-#include "android/graphics/GraphicsJNI.h"
 #include "android/graphics/Region.h"
 #include "core_jni_helpers.h"
 
+#include <android_runtime/AndroidRuntime.h>
 #include <android-base/chrono_utils.h>
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedUtfChars.h>
@@ -50,6 +50,14 @@
 
 namespace android {
 
+static void doThrowNPE(JNIEnv* env) {
+    jniThrowNullPointerException(env, NULL);
+}
+
+static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
+    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
+}
+
 static const char* const OutOfResourcesException =
     "android/view/Surface$OutOfResourcesException";
 
@@ -217,12 +225,6 @@
     ctrl->decStrong((void *)nativeCreate);
 }
 
-static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
-    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
-    ctrl->destroy();
-    ctrl->decStrong((void *)nativeCreate);
-}
-
 static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) {
     SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     if (ctrl != NULL) {
@@ -272,11 +274,11 @@
 }
 
 static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
-        jobject layerHandleToken, jobject sourceCropObj, jfloat frameScale,
-        jobjectArray excludeArray) {
+        jlong layerObject, jobject sourceCropObj, jfloat frameScale,
+        jlongArray excludeObjectArray) {
 
-    sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
-    if (layerHandle == NULL) {
+    auto layer = reinterpret_cast<SurfaceControl *>(layerObject);
+    if (layer == NULL) {
         return NULL;
     }
 
@@ -286,19 +288,20 @@
     }
 
     std::unordered_set<sp<IBinder>,ISurfaceComposer::SpHash<IBinder>> excludeHandles;
-    if (excludeArray != NULL) {
-        const jsize len = env->GetArrayLength(excludeArray);
+    if (excludeObjectArray != NULL) {
+        const jsize len = env->GetArrayLength(excludeObjectArray);
         excludeHandles.reserve(len);
 
+        const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr);
         for (jsize i = 0; i < len; i++) {
-            jobject obj = env->GetObjectArrayElement(excludeArray, i);
-            if (obj == nullptr) {
+            auto excludeObject = reinterpret_cast<SurfaceControl *>(objects[i]);
+            if (excludeObject == nullptr) {
                 jniThrowNullPointerException(env, "Exclude layer is null");
                 return NULL;
             }
-            sp<IBinder> excludeHandle = ibinderForJavaObject(env, obj);
-            excludeHandles.emplace(excludeHandle);
+            excludeHandles.emplace(excludeObject->getHandle());
         }
+        env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
     }
 
     sp<GraphicBuffer> buffer;
@@ -308,7 +311,7 @@
         const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
         dataspace = pickDataspaceFromColorMode(colorMode);
     }
-    status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
+    status_t res = ScreenshotClient::captureChildLayers(layer->getHandle(), dataspace,
                                                         ui::PixelFormat::RGBA_8888, sourceCrop,
                                                         excludeHandles, frameScale, &buffer);
     if (res != NO_ERROR) {
@@ -360,15 +363,12 @@
 
 static void nativeSetRelativeLayer(JNIEnv* env, jclass clazz, jlong transactionObj,
         jlong nativeObject,
-        jobject relativeTo, jint zorder) {
+        jlong relativeToObject, jint zorder) {
 
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    sp<IBinder> handle = ibinderForJavaObject(env, relativeTo);
-
-    {
-        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
-        transaction->setRelativeLayer(ctrl, handle, zorder);
-    }
+    auto relative = reinterpret_cast<SurfaceControl *>(relativeToObject);
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->setRelativeLayer(ctrl, relative->getHandle(), zorder);
 }
 
 static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -465,7 +465,7 @@
             env, inputWindow);
     handle->updateInfo();
 
-    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     transaction->setInputWindowInfo(ctrl, *handle->getInfo());
 }
 
@@ -1109,15 +1109,11 @@
 }
 
 static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong transactionObj,
-        jlong nativeObject,
-        jobject handleObject, jlong frameNumber) {
+        jlong nativeObject, jlong barrierObject, jlong frameNumber) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    sp<IBinder> handle = ibinderForJavaObject(env, handleObject);
-
-    {
-        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
-        transaction->deferTransactionUntil_legacy(ctrl, handle, frameNumber);
-    }
+    auto barrier = reinterpret_cast<SurfaceControl *>(barrierObject);
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->deferTransactionUntil_legacy(ctrl, barrier->getHandle(), frameNumber);
 }
 
 static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -1133,15 +1129,12 @@
 
 static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
         jlong nativeObject,
-        jobject newParentObject) {
+        jlong newParentObject) {
 
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    sp<IBinder> handle = ibinderForJavaObject(env, newParentObject);
-
-    {
-        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
-        transaction->reparentChildren(ctrl, handle);
-    }
+    auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject);
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->reparentChildren(ctrl, newParent->getHandle());
 }
 
 static void nativeReparent(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -1149,11 +1142,8 @@
         jlong newParentObject) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
     auto newParent = reinterpret_cast<SurfaceControl *>(newParentObject);
-
-    {
-        auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
-        transaction->reparent(ctrl, newParent != NULL ? newParent->getHandle() : NULL);
-    }
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    transaction->reparent(ctrl, newParent != NULL ? newParent->getHandle() : NULL);
 }
 
 static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -1173,11 +1163,6 @@
     transaction->setOverrideScalingMode(ctrl, scalingMode);
 }
 
-static jobject nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
-    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
-    return javaObjectForIBinder(env, ctrl->getHandle());
-}
-
 static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
     if (token == NULL) return NULL;
@@ -1255,6 +1240,33 @@
     return error == OK ? JNI_TRUE : JNI_FALSE;
 }
 
+static void nativeWriteTransactionToParcel(JNIEnv* env, jclass clazz, jlong nativeObject,
+        jobject parcelObj) {
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (parcel == NULL) {
+        doThrowNPE(env);
+        return;
+    }
+    SurfaceComposerClient::Transaction* const self =
+            reinterpret_cast<SurfaceComposerClient::Transaction *>(nativeObject);
+    if (self != nullptr) {
+        self->writeToParcel(parcel);
+        self->clear();
+    }
+}
+
+static jlong nativeReadTransactionFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj) {
+    Parcel* parcel = parcelForJavaObject(env, parcelObj);
+    if (parcel == NULL) {
+        doThrowNPE(env);
+        return 0;
+    }
+    std::unique_ptr<SurfaceComposerClient::Transaction> transaction =
+            SurfaceComposerClient::Transaction::createFromParcel(parcel);
+
+    return reinterpret_cast<jlong>(transaction.release());
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod sSurfaceControlMethods[] = {
@@ -1268,8 +1280,6 @@
             (void*)nativeWriteToParcel },
     {"nativeRelease", "(J)V",
             (void*)nativeRelease },
-    {"nativeDestroy", "(J)V",
-            (void*)nativeDestroy },
     {"nativeDisconnect", "(J)V",
             (void*)nativeDisconnect },
     {"nativeCreateTransaction", "()J",
@@ -1286,7 +1296,7 @@
             (void*)nativeSetEarlyWakeup },
     {"nativeSetLayer", "(JJI)V",
             (void*)nativeSetLayer },
-    {"nativeSetRelativeLayer", "(JJLandroid/os/IBinder;I)V",
+    {"nativeSetRelativeLayer", "(JJJI)V",
             (void*)nativeSetRelativeLayer },
     {"nativeSetPosition", "(JJFF)V",
             (void*)nativeSetPosition },
@@ -1364,11 +1374,11 @@
             (void*)nativeSetDisplayPowerMode },
     {"nativeGetProtectedContentSupport", "()Z",
             (void*)nativeGetProtectedContentSupport },
-    {"nativeDeferTransactionUntil", "(JJLandroid/os/IBinder;J)V",
+    {"nativeDeferTransactionUntil", "(JJJJ)V",
             (void*)nativeDeferTransactionUntil },
     {"nativeDeferTransactionUntilSurface", "(JJJJ)V",
             (void*)nativeDeferTransactionUntilSurface },
-    {"nativeReparentChildren", "(JJLandroid/os/IBinder;)V",
+    {"nativeReparentChildren", "(JJJ)V",
             (void*)nativeReparentChildren } ,
     {"nativeReparent", "(JJJ)V",
             (void*)nativeReparent },
@@ -1376,15 +1386,13 @@
             (void*)nativeSeverChildren } ,
     {"nativeSetOverrideScalingMode", "(JJI)V",
             (void*)nativeSetOverrideScalingMode },
-    {"nativeGetHandle", "(J)Landroid/os/IBinder;",
-            (void*)nativeGetHandle },
     {"nativeScreenshot",
             "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
             "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
             (void*)nativeScreenshot },
     {"nativeCaptureLayers",
-            "(Landroid/os/IBinder;Landroid/os/IBinder;Landroid/graphics/Rect;"
-            "F[Landroid/os/IBinder;)"
+            "(Landroid/os/IBinder;JLandroid/graphics/Rect;"
+            "F[J)"
             "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
             (void*)nativeCaptureLayers },
     {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
@@ -1409,6 +1417,10 @@
             (void*)nativeGetDisplayBrightnessSupport },
     {"nativeSetDisplayBrightness", "(Landroid/os/IBinder;F)Z",
             (void*)nativeSetDisplayBrightness },
+    {"nativeReadTransactionFromParcel", "(Landroid/os/Parcel;)J",
+            (void*)nativeReadTransactionFromParcel },
+    {"nativeWriteTransactionToParcel", "(JLandroid/os/Parcel;)V",
+            (void*)nativeWriteTransactionToParcel },
 };
 
 int register_android_view_SurfaceControl(JNIEnv* env)
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index f7e9b24..b0443a8 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -25,12 +25,13 @@
 #include <nativehelper/JNIHelp.h>
 #include "core_jni_helpers.h"
 #include <GraphicsJNI.h>
-#include <nativehelper/ScopedPrimitiveArray.h>
 
 #include <gui/BufferItemConsumer.h>
 #include <gui/BufferQueue.h>
 #include <gui/Surface.h>
 
+#include "android_view_FrameMetricsObserver.h"
+
 #include <private/EGL/cache.h>
 
 #include <utils/RefBase.h>
@@ -40,17 +41,10 @@
 #include <android_runtime/android_view_Surface.h>
 #include <system/window.h>
 
-#include "android_os_MessageQueue.h"
-
-#include <Animator.h>
-#include <AnimationContext.h>
 #include <FrameInfo.h>
-#include <FrameMetricsObserver.h>
-#include <IContextFactory.h>
 #include <Picture.h>
 #include <Properties.h>
-#include <PropertyValuesAnimatorSet.h>
-#include <RenderNode.h>
+#include <RootRenderNode.h>
 #include <renderthread/CanvasContext.h>
 #include <renderthread/RenderProxy.h>
 #include <renderthread/RenderTask.h>
@@ -64,13 +58,6 @@
 using namespace android::uirenderer::renderthread;
 
 struct {
-    jfieldID frameMetrics;
-    jfieldID timingDataBuffer;
-    jfieldID messageQueue;
-    jmethodID callback;
-} gFrameMetricsObserverClassInfo;
-
-struct {
     jclass clazz;
     jmethodID invokePictureCapturedCallback;
 } gHardwareRenderer;
@@ -91,56 +78,18 @@
     return env;
 }
 
-class OnFinishedEvent {
+class JvmErrorReporter : public ErrorHandler {
 public:
-    OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
-            : animator(animator), listener(listener) {}
-    sp<BaseRenderNodeAnimator> animator;
-    sp<AnimationListener> listener;
-};
-
-class InvokeAnimationListeners : public MessageHandler {
-public:
-    explicit InvokeAnimationListeners(std::vector<OnFinishedEvent>& events) {
-        mOnFinishedEvents.swap(events);
+    JvmErrorReporter(JNIEnv* env) {
+        env->GetJavaVM(&mVm);
     }
 
-    static void callOnFinished(OnFinishedEvent& event) {
-        event.listener->onAnimationFinished(event.animator.get());
-    }
-
-    virtual void handleMessage(const Message& message) {
-        std::for_each(mOnFinishedEvents.begin(), mOnFinishedEvents.end(), callOnFinished);
-        mOnFinishedEvents.clear();
-    }
-
-private:
-    std::vector<OnFinishedEvent> mOnFinishedEvents;
-};
-
-class FinishAndInvokeListener : public MessageHandler {
-public:
-    explicit FinishAndInvokeListener(PropertyValuesAnimatorSet* anim)
-            : mAnimator(anim) {
-        mListener = anim->getOneShotListener();
-        mRequestId = anim->getRequestId();
-    }
-
-    virtual void handleMessage(const Message& message) {
-        if (mAnimator->getRequestId() == mRequestId) {
-            // Request Id has not changed, meaning there's no animation lifecyle change since the
-            // message is posted, so go ahead and call finish to make sure the PlayState is properly
-            // updated. This is needed because before the next frame comes in from UI thread to
-            // trigger an animation update, there could be reverse/cancel etc. So we need to update
-            // the playstate in time to ensure all the subsequent events get chained properly.
-            mAnimator->end();
-        }
-        mListener->onAnimationFinished(nullptr);
+    virtual void onError(const std::string& message) override {
+        JNIEnv* env = getenv(mVm);
+        jniThrowException(env, "java/lang/IllegalStateException", message.c_str());
     }
 private:
-    sp<PropertyValuesAnimatorSet> mAnimator;
-    sp<AnimationListener> mListener;
-    uint32_t mRequestId;
+    JavaVM* mVm;
 };
 
 class FrameCompleteWrapper : public LightRefBase<FrameCompleteWrapper> {
@@ -175,419 +124,6 @@
     }
 };
 
-class RootRenderNode : public RenderNode, ErrorHandler {
-public:
-    explicit RootRenderNode(JNIEnv* env) : RenderNode() {
-        env->GetJavaVM(&mVm);
-    }
-
-    virtual ~RootRenderNode() {}
-
-    virtual void onError(const std::string& message) override {
-        JNIEnv* env = getenv(mVm);
-        jniThrowException(env, "java/lang/IllegalStateException", message.c_str());
-    }
-
-    virtual void prepareTree(TreeInfo& info) override {
-        info.errorHandler = this;
-
-        for (auto& anim : mRunningVDAnimators) {
-            // Assume that the property change in VD from the animators will not be consumed. Mark
-            // otherwise if the VDs are found in the display list tree. For VDs that are not in
-            // the display list tree, we stop providing animation pulses by 1) removing them from
-            // the animation list, 2) post a delayed message to end them at end time so their
-            // listeners can receive the corresponding callbacks.
-            anim->getVectorDrawable()->setPropertyChangeWillBeConsumed(false);
-            // Mark the VD dirty so it will damage itself during prepareTree.
-            anim->getVectorDrawable()->markDirty();
-        }
-        if (info.mode == TreeInfo::MODE_FULL) {
-            for (auto &anim : mPausedVDAnimators) {
-                anim->getVectorDrawable()->setPropertyChangeWillBeConsumed(false);
-                anim->getVectorDrawable()->markDirty();
-            }
-        }
-        // TODO: This is hacky
-        info.updateWindowPositions = true;
-        RenderNode::prepareTree(info);
-        info.updateWindowPositions = false;
-        info.errorHandler = nullptr;
-    }
-
-    void attachAnimatingNode(RenderNode* animatingNode) {
-        mPendingAnimatingRenderNodes.push_back(animatingNode);
-    }
-
-    void attachPendingVectorDrawableAnimators() {
-        mRunningVDAnimators.insert(mPendingVectorDrawableAnimators.begin(),
-                mPendingVectorDrawableAnimators.end());
-        mPendingVectorDrawableAnimators.clear();
-    }
-
-    void detachAnimators() {
-        // Remove animators from the list and post a delayed message in future to end the animator
-        // For infinite animators, remove the listener so we no longer hold a global ref to the AVD
-        // java object, and therefore the AVD objects in both native and Java can be properly
-        // released.
-        for (auto& anim : mRunningVDAnimators) {
-            detachVectorDrawableAnimator(anim.get());
-            anim->clearOneShotListener();
-        }
-        for (auto& anim : mPausedVDAnimators) {
-            anim->clearOneShotListener();
-        }
-        mRunningVDAnimators.clear();
-        mPausedVDAnimators.clear();
-    }
-
-    // Move all the animators to the paused list, and send a delayed message to notify the finished
-    // listener.
-    void pauseAnimators() {
-        mPausedVDAnimators.insert(mRunningVDAnimators.begin(), mRunningVDAnimators.end());
-        for (auto& anim : mRunningVDAnimators) {
-            detachVectorDrawableAnimator(anim.get());
-        }
-        mRunningVDAnimators.clear();
-    }
-
-    void doAttachAnimatingNodes(AnimationContext* context) {
-        for (size_t i = 0; i < mPendingAnimatingRenderNodes.size(); i++) {
-            RenderNode* node = mPendingAnimatingRenderNodes[i].get();
-            context->addAnimatingRenderNode(*node);
-        }
-        mPendingAnimatingRenderNodes.clear();
-    }
-
-    // Run VectorDrawable animators after prepareTree.
-    void runVectorDrawableAnimators(AnimationContext* context, TreeInfo& info) {
-        // Push staging.
-        if (info.mode == TreeInfo::MODE_FULL) {
-            pushStagingVectorDrawableAnimators(context);
-        }
-
-        // Run the animators in the running list.
-        for (auto it = mRunningVDAnimators.begin(); it != mRunningVDAnimators.end();) {
-            if ((*it)->animate(*context)) {
-                it = mRunningVDAnimators.erase(it);
-            } else {
-                it++;
-            }
-        }
-
-        // Run the animators in paused list during full sync.
-        if (info.mode == TreeInfo::MODE_FULL) {
-            // During full sync we also need to pulse paused animators, in case their targets
-            // have been added back to the display list. All the animators that passed the
-            // scheduled finish time will be removed from the paused list.
-            for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
-                if ((*it)->animate(*context)) {
-                    // Animator has finished, remove from the list.
-                    it = mPausedVDAnimators.erase(it);
-                } else {
-                    it++;
-                }
-            }
-        }
-
-        // Move the animators with a target not in DisplayList to paused list.
-        for (auto it = mRunningVDAnimators.begin(); it != mRunningVDAnimators.end();) {
-            if (!(*it)->getVectorDrawable()->getPropertyChangeWillBeConsumed()) {
-                // Vector Drawable is not in the display list, we should remove this animator from
-                // the list, put it in the paused list, and post a delayed message to end the
-                // animator.
-                detachVectorDrawableAnimator(it->get());
-                mPausedVDAnimators.insert(*it);
-                it = mRunningVDAnimators.erase(it);
-            } else {
-                it++;
-            }
-        }
-
-        // Move the animators with a target in DisplayList from paused list to running list, and
-        // trim paused list.
-        if (info.mode == TreeInfo::MODE_FULL) {
-            // Check whether any paused animator's target is back in Display List. If so, put the
-            // animator back in the running list.
-            for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
-                if ((*it)->getVectorDrawable()->getPropertyChangeWillBeConsumed()) {
-                    mRunningVDAnimators.insert(*it);
-                    it = mPausedVDAnimators.erase(it);
-                } else {
-                    it++;
-                }
-            }
-            // Trim paused VD animators at full sync, so that when Java loses reference to an
-            // animator, we know we won't be requested to animate it any more, then we remove such
-            // animators from the paused list so they can be properly freed. We also remove the
-            // animators from paused list when the time elapsed since start has exceeded duration.
-            trimPausedVDAnimators(context);
-        }
-
-        info.out.hasAnimations |= !mRunningVDAnimators.empty();
-    }
-
-    void trimPausedVDAnimators(AnimationContext* context) {
-        // Trim paused vector drawable animator list.
-        for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
-            // Remove paused VD animator if no one else is referencing it. Note that animators that
-            // have passed scheduled finish time are removed from list when they are being pulsed
-            // before prepare tree.
-            // TODO: this is a bit hacky, need to figure out a better way to track when the paused
-            // animators should be freed.
-            if ((*it)->getStrongCount() == 1) {
-                it = mPausedVDAnimators.erase(it);
-            } else {
-                it++;
-            }
-        }
-    }
-
-    void pushStagingVectorDrawableAnimators(AnimationContext* context) {
-        for (auto& anim : mRunningVDAnimators) {
-            anim->pushStaging(*context);
-        }
-    }
-
-    void destroy() {
-        for (auto& renderNode : mPendingAnimatingRenderNodes) {
-            renderNode->animators().endAllStagingAnimators();
-        }
-        mPendingAnimatingRenderNodes.clear();
-        mPendingVectorDrawableAnimators.clear();
-    }
-
-    void addVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) {
-        mPendingVectorDrawableAnimators.insert(anim);
-    }
-
-private:
-    JavaVM* mVm;
-    std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
-    std::set< sp<PropertyValuesAnimatorSet> > mPendingVectorDrawableAnimators;
-    std::set< sp<PropertyValuesAnimatorSet> > mRunningVDAnimators;
-    // mPausedVDAnimators stores a list of animators that have not yet passed the finish time, but
-    // their VectorDrawable targets are no longer in the DisplayList. We skip these animators when
-    // render thread runs animators independent of UI thread (i.e. RT_ONLY mode). These animators
-    // need to be re-activated once their VD target is added back into DisplayList. Since that could
-    // only happen when we do a full sync, we need to make sure to pulse these paused animators at
-    // full sync. If any animator's VD target is found in DisplayList during a full sync, we move
-    // the animator back to the running list.
-    std::set< sp<PropertyValuesAnimatorSet> > mPausedVDAnimators;
-    void detachVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) {
-        if (anim->isInfinite() || !anim->isRunning()) {
-            // Do not need to post anything if the animation is infinite (i.e. no meaningful
-            // end listener action), or if the animation has already ended.
-            return;
-        }
-        nsecs_t remainingTimeInMs = anim->getRemainingPlayTime();
-        // Post a delayed onFinished event that is scheduled to be handled when the animator ends.
-        if (anim->getOneShotListener()) {
-            // VectorDrawable's oneshot listener is updated when there are user triggered animation
-            // lifecycle changes, such as start(), end(), etc. By using checking and clearing
-            // one shot listener, we ensure the same end listener event gets posted only once.
-            // Therefore no duplicates. Another benefit of using one shot listener is that no
-            // removal is necessary: the end time of animation will not change unless triggered by
-            // user events, in which case the already posted listener's id will become stale, and
-            // the onFinished callback will then be ignored.
-            sp<FinishAndInvokeListener> message
-                    = new FinishAndInvokeListener(anim);
-            auto looper = Looper::getForThread();
-            LOG_ALWAYS_FATAL_IF(looper == nullptr, "Not on a looper thread?");
-            looper->sendMessageDelayed(ms2ns(remainingTimeInMs), message, 0);
-            anim->clearOneShotListener();
-        }
-    }
-};
-
-class AnimationContextBridge : public AnimationContext {
-public:
-    AnimationContextBridge(renderthread::TimeLord& clock, RootRenderNode* rootNode)
-            : AnimationContext(clock), mRootNode(rootNode) {
-    }
-
-    virtual ~AnimationContextBridge() {}
-
-    // Marks the start of a frame, which will update the frame time and move all
-    // next frame animations into the current frame
-    virtual void startFrame(TreeInfo::TraversalMode mode) {
-        if (mode == TreeInfo::MODE_FULL) {
-            mRootNode->doAttachAnimatingNodes(this);
-            mRootNode->attachPendingVectorDrawableAnimators();
-        }
-        AnimationContext::startFrame(mode);
-    }
-
-    // Runs any animations still left in mCurrentFrameAnimations
-    virtual void runRemainingAnimations(TreeInfo& info) {
-        AnimationContext::runRemainingAnimations(info);
-        mRootNode->runVectorDrawableAnimators(this, info);
-    }
-
-    virtual void pauseAnimators() override {
-        mRootNode->pauseAnimators();
-    }
-
-    virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) {
-        listener->onAnimationFinished(animator);
-    }
-
-    virtual void destroy() {
-        AnimationContext::destroy();
-        mRootNode->detachAnimators();
-    }
-
-private:
-    sp<RootRenderNode> mRootNode;
-};
-
-class ContextFactoryImpl : public IContextFactory {
-public:
-    explicit ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {}
-
-    virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) {
-        return new AnimationContextBridge(clock, mRootNode);
-    }
-
-private:
-    RootRenderNode* mRootNode;
-};
-
-class ObserverProxy;
-
-class NotifyHandler : public MessageHandler {
-public:
-    NotifyHandler(JavaVM* vm, ObserverProxy* observer) : mVm(vm), mObserver(observer) {}
-
-    virtual void handleMessage(const Message& message);
-
-private:
-    JavaVM* const mVm;
-    ObserverProxy* const mObserver;
-};
-
-static jlongArray get_metrics_buffer(JNIEnv* env, jobject observer) {
-    jobject frameMetrics = env->GetObjectField(
-            observer, gFrameMetricsObserverClassInfo.frameMetrics);
-    LOG_ALWAYS_FATAL_IF(frameMetrics == nullptr, "unable to retrieve data sink object");
-    jobject buffer = env->GetObjectField(
-            frameMetrics, gFrameMetricsObserverClassInfo.timingDataBuffer);
-    LOG_ALWAYS_FATAL_IF(buffer == nullptr, "unable to retrieve data sink buffer");
-    return reinterpret_cast<jlongArray>(buffer);
-}
-
-/*
- * Implements JNI layer for hwui frame metrics reporting.
- */
-class ObserverProxy : public FrameMetricsObserver {
-public:
-    ObserverProxy(JavaVM *vm, jobject observer) : mVm(vm) {
-        JNIEnv* env = getenv(mVm);
-
-        mObserverWeak = env->NewWeakGlobalRef(observer);
-        LOG_ALWAYS_FATAL_IF(mObserverWeak == nullptr,
-                "unable to create frame stats observer reference");
-
-        jlongArray buffer = get_metrics_buffer(env, observer);
-        jsize bufferSize = env->GetArrayLength(reinterpret_cast<jarray>(buffer));
-        LOG_ALWAYS_FATAL_IF(bufferSize != kBufferSize,
-                "Mismatched Java/Native FrameMetrics data format.");
-
-        jobject messageQueueLocal = env->GetObjectField(
-                observer, gFrameMetricsObserverClassInfo.messageQueue);
-        mMessageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueLocal);
-        LOG_ALWAYS_FATAL_IF(mMessageQueue == nullptr, "message queue not available");
-
-        mMessageHandler = new NotifyHandler(mVm, this);
-        LOG_ALWAYS_FATAL_IF(mMessageHandler == nullptr,
-                "OOM: unable to allocate NotifyHandler");
-    }
-
-    ~ObserverProxy() {
-        JNIEnv* env = getenv(mVm);
-        env->DeleteWeakGlobalRef(mObserverWeak);
-    }
-
-    jweak getObserverReference() {
-        return mObserverWeak;
-    }
-
-    bool getNextBuffer(JNIEnv* env, jlongArray sink, int* dropCount) {
-        FrameMetricsNotification& elem = mRingBuffer[mNextInQueue];
-
-        if (elem.hasData.load()) {
-            env->SetLongArrayRegion(sink, 0, kBufferSize, elem.buffer);
-            *dropCount = elem.dropCount;
-            mNextInQueue = (mNextInQueue + 1) % kRingSize;
-            elem.hasData = false;
-            return true;
-        }
-
-        return false;
-    }
-
-    virtual void notify(const int64_t* stats) {
-        FrameMetricsNotification& elem = mRingBuffer[mNextFree];
-
-        if (!elem.hasData.load()) {
-            memcpy(elem.buffer, stats, kBufferSize * sizeof(stats[0]));
-
-            elem.dropCount = mDroppedReports;
-            mDroppedReports = 0;
-
-            incStrong(nullptr);
-            mNextFree = (mNextFree + 1) % kRingSize;
-            elem.hasData = true;
-
-            mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage);
-        } else {
-            mDroppedReports++;
-        }
-    }
-
-private:
-    static const int kBufferSize = static_cast<int>(FrameInfoIndex::NumIndexes);
-    static constexpr int kRingSize = 3;
-
-    class FrameMetricsNotification {
-    public:
-        FrameMetricsNotification() : hasData(false) {}
-
-        std::atomic_bool hasData;
-        int64_t buffer[kBufferSize];
-        int dropCount = 0;
-    };
-
-    JavaVM* const mVm;
-    jweak mObserverWeak;
-
-    sp<MessageQueue> mMessageQueue;
-    sp<NotifyHandler> mMessageHandler;
-    Message mMessage;
-
-    int mNextFree = 0;
-    int mNextInQueue = 0;
-    FrameMetricsNotification mRingBuffer[kRingSize];
-
-    int mDroppedReports = 0;
-};
-
-void NotifyHandler::handleMessage(const Message& message) {
-    JNIEnv* env = getenv(mVm);
-
-    jobject target = env->NewLocalRef(mObserver->getObserverReference());
-
-    if (target != nullptr) {
-        jlongArray javaBuffer = get_metrics_buffer(env, target);
-        int dropCount = 0;
-        while (mObserver->getNextBuffer(env, javaBuffer, &dropCount)) {
-            env->CallVoidMethod(target, gFrameMetricsObserverClassInfo.callback, dropCount);
-        }
-        env->DeleteLocalRef(target);
-    }
-
-    mObserver->decStrong(nullptr);
-}
-
 static void android_view_ThreadedRenderer_rotateProcessStatsBuffer(JNIEnv* env, jobject clazz) {
     RenderProxy::rotateProcessStatsBuffer();
 }
@@ -604,7 +140,7 @@
 }
 
 static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {
-    RootRenderNode* node = new RootRenderNode(env);
+    RootRenderNode* node = new RootRenderNode(std::make_unique<JvmErrorReporter>(env));
     node->incStrong(0);
     node->setName("RootRenderNode");
     return reinterpret_cast<jlong>(node);
@@ -957,7 +493,7 @@
         // to all 0s.
         proxy.setLightAlpha(0, 0);
         proxy.setLightGeometry((Vector3){0, 0, 0}, 0);
-        nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
+        nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
         UiFrameInfoBuilder(proxy.frameInfo())
                 .setVsync(vsync, vsync)
                 .addFlag(FrameInfoFlags::SurfaceCanvas);
@@ -1053,7 +589,7 @@
     renderthread::RenderProxy* renderProxy =
             reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
 
-    FrameMetricsObserver* observer = new ObserverProxy(vm, fso);
+    FrameMetricsObserver* observer = new FrameMetricsObserverProxy(vm, fso);
     renderProxy->addFrameMetricsObserver(observer);
     return reinterpret_cast<jlong>(observer);
 }
@@ -1172,17 +708,6 @@
 int register_android_view_ThreadedRenderer(JNIEnv* env) {
     env->GetJavaVM(&mJvm);
     RenderThread::setOnStartHook(&attachRenderThreadToJvm);
-    jclass observerClass = FindClassOrDie(env, "android/view/FrameMetricsObserver");
-    gFrameMetricsObserverClassInfo.frameMetrics = GetFieldIDOrDie(
-            env, observerClass, "mFrameMetrics", "Landroid/view/FrameMetrics;");
-    gFrameMetricsObserverClassInfo.messageQueue = GetFieldIDOrDie(
-            env, observerClass, "mMessageQueue", "Landroid/os/MessageQueue;");
-    gFrameMetricsObserverClassInfo.callback = GetMethodIDOrDie(
-            env, observerClass, "notifyDataAvailable", "(I)V");
-
-    jclass metricsClass = FindClassOrDie(env, "android/view/FrameMetrics");
-    gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie(
-            env, metricsClass, "mTimingData", "[J");
 
     jclass hardwareRenderer = FindClassOrDie(env,
             "android/graphics/HardwareRenderer");
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 01654b8..795f7ab 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -163,6 +163,15 @@
  */
 static constexpr int USAP_POOL_SIZE_MAX_LIMIT = 100;
 
+/** The numeric value for the maximum priority a process may possess. */
+static constexpr int PROCESS_PRIORITY_MAX = -20;
+
+/** The numeric value for the minimum priority a process may possess. */
+static constexpr int PROCESS_PRIORITY_MIN = 19;
+
+/** The numeric value for the normal priority a process should have. */
+static constexpr int PROCESS_PRIORITY_DEFAULT = 0;
+
 /**
  * A helper class containing accounting information for USAPs.
  */
@@ -192,7 +201,7 @@
    * PIDs don't match nothing will happen.
    *
    * @param pid The ID of the process who's entry we want to clear.
-   * @return True if the entry was cleared; false otherwise
+   * @return True if the entry was cleared by this call; false otherwise
    */
   bool ClearForPID(int32_t pid) {
     EntryStorage storage = mStorage.load();
@@ -206,14 +215,16 @@
        *   3) It fails and the new value isn't INVALID_ENTRY_VALUE, in which
        *      case the entry has already been cleared and re-used.
        *
-       * In all three cases the goal of the caller has been met and we can
-       * return true.
+       * In all three cases the goal of the caller has been met, but only in
+       * the first case do we need to decrement the pool count.
        */
       if (mStorage.compare_exchange_strong(storage, INVALID_ENTRY_VALUE)) {
         close(storage.read_pipe_fd);
+        return true;
+      } else {
+        return false;
       }
 
-      return true;
     } else {
       return false;
     }
@@ -281,6 +292,7 @@
 static FileDescriptorTable* gOpenFdTable = nullptr;
 
 // Must match values in com.android.internal.os.Zygote.
+// The order of entries here must be kept in sync with ExternalStorageViews array values.
 enum MountExternalKind {
   MOUNT_EXTERNAL_NONE = 0,
   MOUNT_EXTERNAL_DEFAULT = 1,
@@ -289,6 +301,18 @@
   MOUNT_EXTERNAL_LEGACY = 4,
   MOUNT_EXTERNAL_INSTALLER = 5,
   MOUNT_EXTERNAL_FULL = 6,
+  MOUNT_EXTERNAL_COUNT = 7
+};
+
+// The order of entries here must be kept in sync with MountExternalKind enum values.
+static const std::array<const std::string, MOUNT_EXTERNAL_COUNT> ExternalStorageViews = {
+  "",                     // MOUNT_EXTERNAL_NONE
+  "/mnt/runtime/default", // MOUNT_EXTERNAL_DEFAULT
+  "/mnt/runtime/read",    // MOUNT_EXTERNAL_READ
+  "/mnt/runtime/write",   // MOUNT_EXTERNAL_WRITE
+  "/mnt/runtime/write",   // MOUNT_EXTERNAL_LEGACY
+  "/mnt/runtime/write",   // MOUNT_EXTERNAL_INSTALLER
+  "/mnt/runtime/full",    // MOUNT_EXTERNAL_FULL
 };
 
 // Must match values in com.android.internal.os.Zygote.
@@ -325,11 +349,24 @@
     if (WIFEXITED(status)) {
       async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
                             "Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
+
+      // Check to see if the PID is in the USAP pool and remove it if it is.
+      if (RemoveUsapTableEntry(pid)) {
+        ++usaps_removed;
+      }
     } else if (WIFSIGNALED(status)) {
       async_safe_format_log(ANDROID_LOG_INFO, LOG_TAG,
                             "Process %d exited due to signal %d (%s)%s", pid,
                             WTERMSIG(status), strsignal(WTERMSIG(status)),
                             WCOREDUMP(status) ? "; core dumped" : "");
+
+      // If the process exited due to a signal other than SIGTERM, check to see
+      // if the PID is in the USAP pool and remove it if it is.  If the process
+      // was closed by the Zygote using SIGTERM then the USAP pool entry will
+      // have already been removed (see nativeEmptyUsapPool()).
+      if (WTERMSIG(status) != SIGTERM && RemoveUsapTableEntry(pid)) {
+        ++usaps_removed;
+      }
     }
 
     // If the just-crashed process is the system_server, bring down zygote
@@ -340,11 +377,6 @@
                             "Exit zygote because system server (pid %d) has terminated", pid);
       kill(getpid(), SIGKILL);
     }
-
-    // Check to see if the PID is in the USAP pool and remove it if it is.
-    if (RemoveUsapTableEntry(pid)) {
-      ++usaps_removed;
-    }
   }
 
   // Note that we shouldn't consider ECHILD an error because
@@ -577,11 +609,25 @@
   }
 }
 
-static void SetSchedulerPolicy(fail_fn_t fail_fn) {
-  errno = -set_sched_policy(0, SP_DEFAULT);
-  if (errno != 0) {
-    fail_fn(CREATE_ERROR("set_sched_policy(0, SP_DEFAULT) failed: %s", strerror(errno)));
+static void SetSchedulerPolicy(fail_fn_t fail_fn, bool is_top_app) {
+  SchedPolicy policy = is_top_app ? SP_TOP_APP : SP_DEFAULT;
+
+  if (is_top_app && cpusets_enabled()) {
+    errno = -set_cpuset_policy(0, policy);
+    if (errno != 0) {
+      fail_fn(CREATE_ERROR("set_cpuset_policy(0, %d) failed: %s", policy, strerror(errno)));
+    }
   }
+
+  errno = -set_sched_policy(0, policy);
+  if (errno != 0) {
+    fail_fn(CREATE_ERROR("set_sched_policy(0, %d) failed: %s", policy, strerror(errno)));
+  }
+
+  // We are going to lose the permission to set scheduler policy during the specialization, so make
+  // sure that we don't cache the fd of cgroup path that may cause sepolicy violation by writing
+  // value to the cached fd directly when creating new thread.
+  DropTaskProfilesResourceCaching();
 }
 
 static int UnmountTree(const char* path) {
@@ -614,6 +660,23 @@
   return 0;
 }
 
+static void CreateDir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid,
+                      fail_fn_t fail_fn) {
+  if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
+    fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s: %s",
+                         dir.c_str(), strerror(errno)));
+  }
+}
+
+static void BindMount(const std::string& source_dir, const std::string& target_dir,
+                      fail_fn_t fail_fn) {
+  if (TEMP_FAILURE_RETRY(mount(source_dir.c_str(), target_dir.c_str(), nullptr,
+                               MS_BIND | MS_REC, nullptr)) == -1) {
+    fail_fn(CREATE_ERROR("Failed to mount %s to %s: %s",
+                         source_dir.c_str(), target_dir.c_str(), strerror(errno)));
+  }
+}
+
 // Create a private mount namespace and bind mount appropriate emulated
 // storage for the given user.
 static void MountEmulatedStorage(uid_t uid, jint mount_mode,
@@ -622,18 +685,11 @@
   // See storage config details at http://source.android.com/tech/storage/
   ATRACE_CALL();
 
-  String8 storage_source;
-  if (mount_mode == MOUNT_EXTERNAL_DEFAULT) {
-    storage_source = "/mnt/runtime/default";
-  } else if (mount_mode == MOUNT_EXTERNAL_READ) {
-    storage_source = "/mnt/runtime/read";
-  } else if (mount_mode == MOUNT_EXTERNAL_WRITE
-      || mount_mode == MOUNT_EXTERNAL_LEGACY
-      || mount_mode == MOUNT_EXTERNAL_INSTALLER) {
-    storage_source = "/mnt/runtime/write";
-  } else if (mount_mode == MOUNT_EXTERNAL_FULL) {
-    storage_source = "/mnt/runtime/full";
-  } else if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
+  if (mount_mode < 0 || mount_mode >= MOUNT_EXTERNAL_COUNT) {
+    fail_fn(CREATE_ERROR("Unknown mount_mode: %d", mount_mode));
+  }
+
+  if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
     // Sane default of no storage visible
     return;
   }
@@ -648,26 +704,15 @@
     return;
   }
 
-  if (TEMP_FAILURE_RETRY(mount(storage_source.string(), "/storage", nullptr,
-                               MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
-    fail_fn(CREATE_ERROR("Failed to mount %s to /storage: %s",
-                         storage_source.string(),
-                         strerror(errno)));
-  }
+  const std::string& storage_source = ExternalStorageViews[mount_mode];
+
+  BindMount(storage_source, "/storage", fail_fn);
 
   // Mount user-specific symlink helper into place
   userid_t user_id = multiuser_get_user_id(uid);
-  const String8 user_source(String8::format("/mnt/user/%d", user_id));
-  if (fs_prepare_dir(user_source.string(), 0751, 0, 0) == -1) {
-    fail_fn(CREATE_ERROR("fs_prepare_dir failed on %s",
-                         user_source.string()));
-  }
-
-  if (TEMP_FAILURE_RETRY(mount(user_source.string(), "/storage/self",
-                               nullptr, MS_BIND, nullptr)) == -1) {
-    fail_fn(CREATE_ERROR("Failed to mount %s to /storage/self: %s",
-                         user_source.string(), strerror(errno)));
-  }
+  const std::string user_source = StringPrintf("/mnt/user/%d", user_id);
+  CreateDir(user_source, 0751, AID_ROOT, AID_ROOT, fail_fn);
+  BindMount(user_source, "/storage/self", fail_fn);
 }
 
 static bool NeedsNoRandomizeWorkaround() {
@@ -887,7 +932,8 @@
 // Utility routine to fork a process from the zygote.
 static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                         const std::vector<int>& fds_to_close,
-                        const std::vector<int>& fds_to_ignore) {
+                        const std::vector<int>& fds_to_ignore,
+                        bool is_priority_fork) {
   SetSignalHandlers();
 
   // Curry a failure function.
@@ -920,6 +966,12 @@
   pid_t pid = fork();
 
   if (pid == 0) {
+    if (is_priority_fork) {
+      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
+    } else {
+      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
+    }
+
     // The child process.
     PreApplicationInit();
 
@@ -952,7 +1004,7 @@
                              jint mount_external, jstring managed_se_info,
                              jstring managed_nice_name, bool is_system_server,
                              bool is_child_zygote, jstring managed_instruction_set,
-                             jstring managed_app_data_dir) {
+                             jstring managed_app_data_dir, bool is_top_app) {
   const char* process_name = is_system_server ? "system_server" : "zygote";
   auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);
   auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);
@@ -1020,6 +1072,9 @@
   // privileged syscalls used below still need to be accessible in app process.
   SetUpSeccompFilter(uid, is_child_zygote);
 
+  // Must be called before losing the permission to set scheduler policy.
+  SetSchedulerPolicy(fail_fn, is_top_app);
+
   if (setresuid(uid, uid, uid) == -1) {
     fail_fn(CREATE_ERROR("setresuid(%d) failed: %s", uid, strerror(errno)));
   }
@@ -1068,8 +1123,6 @@
 
   SetCapabilities(permitted_capabilities, effective_capabilities, permitted_capabilities, fail_fn);
 
-  SetSchedulerPolicy(fail_fn);
-
   __android_log_close();
   stats_log_close();
 
@@ -1117,6 +1170,9 @@
   env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
                             is_system_server, is_child_zygote, managed_instruction_set);
 
+  // Reset the process priority to the default value.
+  setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);
+
   if (env->ExceptionCheck()) {
     fail_fn("Error calling post fork hooks.");
   }
@@ -1144,6 +1200,7 @@
   /*
    *  Grant the following capabilities to the Bluetooth user:
    *    - CAP_WAKE_ALARM
+   *    - CAP_NET_ADMIN
    *    - CAP_NET_RAW
    *    - CAP_NET_BIND_SERVICE (for DHCP client functionality)
    *    - CAP_SYS_NICE (for setting RT priority for audio-related threads)
@@ -1151,6 +1208,7 @@
 
   if (multiuser_get_app_id(uid) == AID_BLUETOOTH) {
     capabilities |= (1LL << CAP_WAKE_ALARM);
+    capabilities |= (1LL << CAP_NET_ADMIN);
     capabilities |= (1LL << CAP_NET_RAW);
     capabilities |= (1LL << CAP_NET_BIND_SERVICE);
     capabilities |= (1LL << CAP_SYS_NICE);
@@ -1343,7 +1401,7 @@
         jint runtime_flags, jobjectArray rlimits,
         jint mount_external, jstring se_info, jstring nice_name,
         jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
-        jstring instruction_set, jstring app_data_dir) {
+        jstring instruction_set, jstring app_data_dir, jboolean is_top_app) {
     jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
 
     if (UNLIKELY(managed_fds_to_close == nullptr)) {
@@ -1368,13 +1426,14 @@
       fds_to_ignore.push_back(gUsapPoolEventFD);
     }
 
-    pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore);
+    pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
 
     if (pid == 0) {
       SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                        capabilities, capabilities,
                        mount_external, se_info, nice_name, false,
-                       is_child_zygote == JNI_TRUE, instruction_set, app_data_dir);
+                       is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
+                       is_top_app == JNI_TRUE);
     }
     return pid;
 }
@@ -1395,12 +1454,13 @@
 
   pid_t pid = ForkCommon(env, true,
                          fds_to_close,
-                         fds_to_ignore);
+                         fds_to_ignore,
+                         true);
   if (pid == 0) {
       SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                        permitted_capabilities, effective_capabilities,
                        MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
-                       false, nullptr, nullptr);
+                       false, nullptr, nullptr, /* is_top_app= */ false);
   } else if (pid > 0) {
       // The zygote process checks whether the child process has died or not.
       ALOGI("System server process %d has been created", pid);
@@ -1437,13 +1497,15 @@
  * zygote in managed code.
  * @param managed_session_socket_fds  A list of anonymous session sockets that must be ignored by
  * the FD hygiene code and automatically "closed" in the new USAP.
+ * @param is_priority_fork  Controls the nice level assigned to the newly created process
  * @return
  */
 static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env,
                                                           jclass,
                                                           jint read_pipe_fd,
                                                           jint write_pipe_fd,
-                                                          jintArray managed_session_socket_fds) {
+                                                          jintArray managed_session_socket_fds,
+                                                          jboolean is_priority_fork) {
   std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
                    fds_to_ignore(fds_to_close);
 
@@ -1465,7 +1527,8 @@
   fds_to_ignore.push_back(write_pipe_fd);
   fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end());
 
-  pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore);
+  pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore,
+                              is_priority_fork == JNI_TRUE);
 
   if (usap_pid != 0) {
     ++gUsapPoolCount;
@@ -1514,18 +1577,20 @@
  * @param is_child_zygote  If the process is to become a WebViewZygote
  * @param instruction_set  The instruction set expected/requested by the new application
  * @param app_data_dir  Path to the application's data directory
+ * @param is_top_app  If the process is for top (high priority) application
  */
 static void com_android_internal_os_Zygote_nativeSpecializeAppProcess(
     JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
     jint runtime_flags, jobjectArray rlimits,
     jint mount_external, jstring se_info, jstring nice_name,
-    jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir) {
+    jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, jboolean is_top_app) {
   jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
 
   SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                    capabilities, capabilities,
                    mount_external, se_info, nice_name, false,
-                   is_child_zygote == JNI_TRUE, instruction_set, app_data_dir);
+                   is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
+                   is_top_app == JNI_TRUE);
 }
 
 /**
@@ -1651,7 +1716,13 @@
     auto entry_storage = entry.GetValues();
 
     if (entry_storage.has_value()) {
-      kill(entry_storage.value().pid, SIGKILL);
+      kill(entry_storage.value().pid, SIGTERM);
+
+      // Clean up the USAP table entry here.  This avoids a potential race
+      // where a newly created USAP might not be able to find a valid table
+      // entry if signal handler (which would normally do the cleanup) doesn't
+      // run between now and when the new process is created.
+
       close(entry_storage.value().read_pipe_fd);
 
       // Avoid a second atomic load by invalidating instead of clearing.
@@ -1669,9 +1740,23 @@
   return dl_iterate_phdr(DisableExecuteOnly, nullptr) == 0;
 }
 
+static void com_android_internal_os_Zygote_nativeBlockSigTerm(JNIEnv* env, jclass) {
+  auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1);
+  BlockSignal(SIGTERM, fail_fn);
+}
+
+static void com_android_internal_os_Zygote_nativeUnblockSigTerm(JNIEnv* env, jclass) {
+  auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1);
+  UnblockSignal(SIGTERM, fail_fn);
+}
+
+static void com_android_internal_os_Zygote_nativeBoostUsapPriority(JNIEnv* env, jclass) {
+  setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
+}
+
 static const JNINativeMethod gMethods[] = {
     { "nativeForkAndSpecialize",
-      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I",
+      "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z)I",
       (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
     { "nativeForkSystemServer", "(II[II[[IJJ)I",
       (void *) com_android_internal_os_Zygote_nativeForkSystemServer },
@@ -1681,10 +1766,10 @@
       (void *) com_android_internal_os_Zygote_nativePreApplicationInit },
     { "nativeInstallSeccompUidGidFilter", "(II)V",
       (void *) com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter },
-    { "nativeForkUsap", "(II[I)I",
+    { "nativeForkUsap", "(II[IZ)I",
       (void *) com_android_internal_os_Zygote_nativeForkUsap },
     { "nativeSpecializeAppProcess",
-      "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V",
+      "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z)V",
       (void *) com_android_internal_os_Zygote_nativeSpecializeAppProcess },
     { "nativeInitNativeState", "(Z)V",
       (void *) com_android_internal_os_Zygote_nativeInitNativeState },
@@ -1699,7 +1784,13 @@
     { "nativeEmptyUsapPool", "()V",
       (void *) com_android_internal_os_Zygote_nativeEmptyUsapPool },
     { "nativeDisableExecuteOnly", "()Z",
-      (void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly }
+      (void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly },
+    { "nativeBlockSigTerm", "()V",
+      (void* ) com_android_internal_os_Zygote_nativeBlockSigTerm },
+    { "nativeUnblockSigTerm", "()V",
+      (void* ) com_android_internal_os_Zygote_nativeUnblockSigTerm },
+    { "nativeBoostUsapPriority", "()V",
+      (void* ) com_android_internal_os_Zygote_nativeBoostUsapPriority }
 };
 
 int register_com_android_internal_os_Zygote(JNIEnv* env) {
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
index 5cca0fd..c2a5ee43 100644
--- a/core/jni/com_android_internal_os_ZygoteInit.cpp
+++ b/core/jni/com_android_internal_os_ZygoteInit.cpp
@@ -19,7 +19,6 @@
 #include <EGL/egl.h>
 #include <Properties.h>
 #include <ui/GraphicBufferMapper.h>
-#include <vulkan/vulkan.h>
 
 #include "core_jni_helpers.h"
 
@@ -67,9 +66,6 @@
     ScopedSCSExit x;
     if (Properties::peekRenderPipelineType() == RenderPipelineType::SkiaGL) {
         eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    } else {
-        uint32_t count = 0;
-        vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
     }
 }
 
diff --git a/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp b/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
index d20bae2..d629d63 100644
--- a/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
+++ b/core/jni/com_android_internal_util_VirtualRefBasePtr.cpp
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "jni.h"
 #include <nativehelper/JNIHelp.h>
+#include <utils/LightRefBase.h>
 #include "core_jni_helpers.h"
 
 namespace android {
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 940ac22..5aea848 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -30,10 +30,6 @@
 #include <gui/GLConsumer.h>
 #include <gui/Surface.h>
 
-#include <GraphicsJNI.h>
-#include <SkBitmap.h>
-#include <SkPixelRef.h>
-
 #include <ui/ANativeObjectBase.h>
 
 namespace android {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index fa5f931..ea4b252 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -100,8 +100,8 @@
   static const char* kVendorOverlaySubdir = "/system/vendor/overlay-subdir/";
   static const char* kSystemProductOverlayDir = "/system/product/overlay/";
   static const char* kProductOverlayDir = "/product/overlay";
-  static const char* kSystemProductServicesOverlayDir = "/system/product_services/overlay/";
-  static const char* kProductServicesOverlayDir = "/product_services/overlay";
+  static const char* kSystemSystemExtOverlayDir = "/system/system_ext/overlay/";
+  static const char* kSystemExtOverlayDir = "/system_ext/overlay";
   static const char* kSystemOdmOverlayDir = "/system/odm/overlay";
   static const char* kOdmOverlayDir = "/odm/overlay";
   static const char* kSystemOemOverlayDir = "/system/oem/overlay";
@@ -113,8 +113,8 @@
        || android::base::StartsWith(path, kVendorOverlayDir)
        || android::base::StartsWith(path, kSystemProductOverlayDir)
        || android::base::StartsWith(path, kProductOverlayDir)
-       || android::base::StartsWith(path, kSystemProductServicesOverlayDir)
-       || android::base::StartsWith(path, kProductServicesOverlayDir)
+       || android::base::StartsWith(path, kSystemSystemExtOverlayDir)
+       || android::base::StartsWith(path, kSystemExtOverlayDir)
        || android::base::StartsWith(path, kSystemOdmOverlayDir)
        || android::base::StartsWith(path, kOdmOverlayDir)
        || android::base::StartsWith(path, kSystemOemOverlayDir)
@@ -251,7 +251,7 @@
   }
 
   if (!whitelist->IsAllowed(file_path)) {
-    fail_fn(std::string("Not whitelisted : ").append(file_path));
+    fail_fn(android::base::StringPrintf("Not whitelisted (%d): %s", fd, file_path.c_str()));
   }
 
   // File descriptor flags : currently on FD_CLOEXEC. We can set these
diff --git a/core/jni/include/android_runtime/AndroidRuntime.h b/core/jni/include/android_runtime/AndroidRuntime.h
index a19f954..2351272 100644
--- a/core/jni/include/android_runtime/AndroidRuntime.h
+++ b/core/jni/include/android_runtime/AndroidRuntime.h
@@ -131,7 +131,7 @@
                                     const char* runtimeArg,
                                     const char* quotingArg);
     void parseExtraOpts(char* extraOptsBuf, const char* quotingArg);
-    int startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote);
+    int startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool primary_zygote);
 
     Vector<JavaVMOption> mOptions;
     bool mExitWithoutCleanup;
diff --git a/core/jni/include/android_runtime/android_graphics_SurfaceTexture.h b/core/jni/include/android_runtime/android_graphics_SurfaceTexture.h
index 0ad2587..d3ff959 100644
--- a/core/jni/include/android_runtime/android_graphics_SurfaceTexture.h
+++ b/core/jni/include/android_runtime/android_graphics_SurfaceTexture.h
@@ -17,8 +17,6 @@
 #ifndef _ANDROID_GRAPHICS_SURFACETEXTURE_H
 #define _ANDROID_GRAPHICS_SURFACETEXTURE_H
 
-#include <android/native_window.h>
-
 #include "jni.h"
 
 namespace android {
@@ -26,7 +24,6 @@
 class IGraphicBufferProducer;
 class SurfaceTexture;
 
-extern sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz);
 extern bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz);
 
 /* Gets the underlying C++ SurfaceTexture object from a SurfaceTexture Java object. */
diff --git a/core/jni/include/android_runtime/android_view_Surface.h b/core/jni/include/android_runtime/android_view_Surface.h
index 04718cd..637b823 100644
--- a/core/jni/include/android_runtime/android_view_Surface.h
+++ b/core/jni/include/android_runtime/android_view_Surface.h
@@ -18,7 +18,6 @@
 #define _ANDROID_VIEW_SURFACE_H
 
 #include <android/native_window.h>
-#include <system/graphics.h>
 #include <ui/PublicFormat.h>
 
 #include "jni.h"
@@ -46,21 +45,6 @@
 extern jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env,
         const sp<IGraphicBufferProducer>& bufferProducer);
 
-/* Convert from android.graphics.ImageFormat/PixelFormat enums to graphics.h HAL
- * format */
-extern int android_view_Surface_mapPublicFormatToHalFormat(PublicFormat f);
-
-/* Convert from android.graphics.ImageFormat/PixelFormat enums to graphics.h HAL
- * dataspace */
-extern android_dataspace android_view_Surface_mapPublicFormatToHalDataspace(
-        PublicFormat f);
-
-/* Convert from HAL format, dataspace pair to
- * android.graphics.ImageFormat/PixelFormat.
- * For unknown/unspecified pairs, returns PublicFormat::UNKNOWN */
-extern PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
-        int format, android_dataspace dataSpace);
-
 } // namespace android
 
 #endif // _ANDROID_VIEW_SURFACE_H
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 4874c41..c023438 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2053,7 +2053,7 @@
     // OS: P
     WIFI_SCANNING_NEEDED_DIALOG = 1373;
 
-    // OPEN: Settings > System > Gestures > Swipe up gesture
+    // OPEN: Settings > System > Gestures > System navigation
     // CATEGORY: SETTINGS
     // OS: P
     SETTINGS_GESTURE_SWIPE_UP = 1374;
@@ -2374,14 +2374,31 @@
     // Settings > Apps and notifications > Notifications > Gentle notifications
     GENTLE_NOTIFICATIONS_SCREEN = 1715;
 
+    // OPEN: Settings > System > Gestures > Global Actions Panel
+    // CATEGORY: SETTINGS
+    // OS: Q
+    GLOBAL_ACTIONS_PANEL_SETTINGS = 1728;
+
     // OPEN: Settings > Display > Dark Theme
     // CATEGORY: SETTINGS
     // OS: Q
     // Note: Only shows up on first time toggle
     DIALOG_DARK_UI_INFO = 1740;
 
-    // OPEN: Settings > System > Gestures > Global Actions Panel
+    // OPEN: Settings > About phone > Legal information > Google Play system update licenses
     // CATEGORY: SETTINGS
     // OS: Q
-    GLOBAL_ACTIONS_PANEL_SETTINGS = 1800;
+    MODULE_LICENSES_DASHBOARD = 1746;
+
+    // OPEN: Settings > System > Gestures > System navigation > Info icon
+    // CATEGORY: SETTINGS
+    // OS: Q
+    // Note: Info icon is visible only when gesture navigation is not available and disabled
+    SETTINGS_GESTURE_NAV_NOT_AVAILABLE_DLG = 1747;
+
+    // OPEN: Settings > System > Gestures > System navigation > Gear icon
+    // CATEGORY: SETTINGS
+    // OS: Q
+    // Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
+    SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
 }
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 9a9c9d1..7d0629e 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -321,6 +321,14 @@
         (section).args = "incidentcompanion --restricted_image"
     ];
 
+    // System trace as a serialized protobuf.
+    optional bytes system_trace = 3026 [
+        (section).type = SECTION_FILE,
+        (section).args = "/data/misc/perfetto-traces/incident-trace",
+        (privacy).dest = DEST_AUTOMATIC,
+        (section).userdebug_and_eng_only = true
+    ];
+
     // Reserved for OEMs.
     extensions 50000 to 100000;
 }
diff --git a/core/proto/android/os/system_properties.proto b/core/proto/android/os/system_properties.proto
index d06e1a6..7e26952 100644
--- a/core/proto/android/os/system_properties.proto
+++ b/core/proto/android/os/system_properties.proto
@@ -497,8 +497,7 @@
         }
         optional Telephony telephony = 38;
 
-        optional string url_legal = 39;
-        optional string url_legal_android_privacy = 40;
+        reserved 39, 40; // Removed url_legal* props
 
         message Vendor {
             optional string build_date = 1;
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 8f16b41..0070694 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -457,6 +457,9 @@
         optional SettingProto game_driver_sphal_libraries = 16;
         // ANGLE - External package containing ANGLE libraries
         optional SettingProto angle_debug_package = 17;
+        // Game Driver - List of Apps selected to use prerelease Game Driver
+        // i.e. <pkg1>,<pkg2>,...,<pkgN>
+        optional SettingProto game_driver_prerelease_opt_in_apps = 18;
     }
     optional Gpu gpu = 59;
 
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 702ee2f..d5528de 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -198,11 +198,19 @@
         optional SettingProto silence_alarms_count = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto silence_calls_count = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto silence_enabled = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
-        optional SettingProto silence_notification_count = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        // del: silence_notification_count = 5
         optional SettingProto silence_timer_count = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
         optional SettingProto skip_count = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto skip_enabled = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+        optional SettingProto silence_alarms_touch_count = 9 [ (android.privacy).dest =
+            DEST_AUTOMATIC ];
+        optional SettingProto silence_calls_touch_count = 10 [ (android.privacy).dest =
+            DEST_AUTOMATIC ];
+        optional SettingProto silence_timer_touch_count = 11 [ (android.privacy).dest =
+            DEST_AUTOMATIC ];
+        optional SettingProto skip_touch_count = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Gesture gesture = 74;
 
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index a7d4734..7fb6f98 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -591,6 +591,8 @@
         SHOWING_UI = 13;
         NOT_VISIBLE = 14;
         DEAD = 15;
+        NOT_PERCEPTIBLE = 16;
+        INCLUDE_CAPABILITIES = 17;
     }
     repeated Flag flags = 3;
     optional string service_name = 4;
diff --git a/core/proto/android/server/connectivity/Android.bp b/core/proto/android/server/connectivity/Android.bp
index c0ac2cb..4136239 100644
--- a/core/proto/android/server/connectivity/Android.bp
+++ b/core/proto/android/server/connectivity/Android.bp
@@ -21,5 +21,4 @@
         "data_stall_event.proto",
     ],
     sdk_version: "system_current",
-    no_framework_libs: true,
-}
\ No newline at end of file
+}
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 2873379..c534aa4 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -175,6 +175,11 @@
     // is now set to 1, to prevent any batching at this level. Since we now do
     // batching through doze, that is a much better mechanism.
     optional int32 min_ready_jobs_count = 7;
+    // Minimum # of non-ACTIVE jobs for which the JMS will be happy running some work early.
+    optional int32 min_ready_non_active_jobs_count = 29;
+    // Don't batch a non-ACTIVE job if it's been delayed due to force batching attempts for
+    // at least this amount of time.
+    optional int64 max_non_active_job_batch_delay_ms = 30;
     // This is the job execution factor that is considered to be heavy use of
     // the system.
     optional double heavy_use_factor = 8;
@@ -226,15 +231,6 @@
     // will use heartbeats, false will use a rolling window.
     optional bool use_heartbeats = 23;
 
-    message TimeController {
-        option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-        // Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
-        // ready now.
-        optional bool skip_not_ready_jobs = 1;
-    }
-    optional TimeController time_controller = 25;
-
     message QuotaController {
         option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
@@ -299,6 +295,15 @@
     }
     optional QuotaController quota_controller = 24;
 
+    message TimeController {
+        option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+        // Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
+        // ready now.
+        reserved 1; // skip_not_ready_jobs
+    }
+    optional TimeController time_controller = 25;
+
     // Max number of jobs, when screen is ON.
     optional MaxJobCountsPerMemoryTrimLevelProto max_job_counts_screen_on = 26;
 
@@ -307,6 +312,8 @@
 
     // In this time after screen turns on, we increase job concurrency.
     optional int32 screen_off_job_concurrency_increase_delay_ms = 28;
+
+    // Next tag: 31
 }
 
 // Next tag: 4
@@ -833,7 +840,15 @@
 
         optional .android.net.NetworkRequestProto required_network = 18;
 
-        optional int64 total_network_bytes = 19;
+        reserved 19; // total_network_bytes
+
+        // The estimated download bytes of the job. Will have a value of
+        // {@link JobInfo.NETWORK_BYTES_UNKNOWN} if any part of the job download is unknown.
+        optional int64 total_network_download_bytes = 25;
+
+        // The estimated upload bytes of the job. Will have a value of
+        // {@link JobInfo.NETWORK_BYTES_UNKNOWN} if any part of the job upload is unknown.
+        optional int64 total_network_upload_bytes = 26;
 
         optional int64 min_latency_ms = 20;
         optional int64 max_execution_delay_ms = 21;
@@ -852,6 +867,8 @@
 
         optional bool has_early_constraint = 23;
         optional bool has_late_constraint = 24;
+
+        // Next tag: 27
     }
     optional JobInfo job_info = 6;
 
@@ -928,7 +945,15 @@
 
     optional int64 internal_flags = 24;
 
-    // Next tag: 28
+    // Amount of time since this job was first deferred due to standby bucketing policy. Will be
+    // 0 if this job was never deferred.
+    optional int64 time_since_first_deferral_ms = 28;
+
+    // Amount of time since JobScheduler first tried to force batch this job. Will be 0 if there
+    // was no attempt.
+    optional int64 time_since_first_force_batch_attempt_ms = 29;
+
+    // Next tag: 30
 }
 
 // Dump from com.android.server.job.JobConcurrencyManager.
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index e6ae226..7779025 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -45,6 +45,7 @@
     optional bool display_frozen = 6;
     optional int32 rotation = 7;
     optional int32 last_orientation = 8;
+    optional int32 focused_display_id = 9;
 }
 
 /* represents RootWindowContainer object */
diff --git a/core/proto/android/stats/connectivity/Android.bp b/core/proto/android/stats/connectivity/Android.bp
index 5aa4ddb..5d642d38 100644
--- a/core/proto/android/stats/connectivity/Android.bp
+++ b/core/proto/android/stats/connectivity/Android.bp
@@ -21,5 +21,4 @@
         "network_stack.proto",
     ],
     sdk_version: "system_current",
-    no_framework_libs: true,
-}
\ No newline at end of file
+}
diff --git a/core/proto/android/stats/devicepolicy/Android.bp b/core/proto/android/stats/devicepolicy/Android.bp
index 6ae54e2..5fb278a 100644
--- a/core/proto/android/stats/devicepolicy/Android.bp
+++ b/core/proto/android/stats/devicepolicy/Android.bp
@@ -29,5 +29,5 @@
             static_libs: ["libprotobuf-java-nano"],
         }
     },
-    no_framework_libs: true,
+    sdk_version: "core_platform",
 }
diff --git a/core/proto/android/stats/dnsresolver/Android.bp b/core/proto/android/stats/dnsresolver/Android.bp
index 0b5aa86..1e8c763 100644
--- a/core/proto/android/stats/dnsresolver/Android.bp
+++ b/core/proto/android/stats/dnsresolver/Android.bp
@@ -21,5 +21,4 @@
         "dns_resolver.proto",
     ],
     sdk_version: "system_current",
-    no_framework_libs: true,
 }
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
index af6fea0..9eaabfb 100644
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ b/core/proto/android/stats/dnsresolver/dns_resolver.proto
@@ -1,214 +1,217 @@
-/*

- * Copyright (C) 2019 The Android Open Source Project

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT 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.dnsresolver;

-

-enum EventType {

-    EVENT_UNKNOWN = 0;

-    EVENT_GETADDRINFO = 1;

-    EVENT_GETHOSTBYNAME = 2;

-    EVENT_GETHOSTBYADDR = 3;

-    EVENT_RES_NSEND = 4;

-}

-

-// 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_NO_ERROR = 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 {

-    IV_UNKNOWN = 0;

-    IV_IPV4 = 1;

-    IV_IPV6 = 2;

-}

-

-enum TransportType {

-    TT_UNKNOWN = 0;

-    TT_UDP = 1;

-    TT_TCP = 2;

-    TT_DOT = 3;

-}

-

-enum PrivateDnsModes {

-    PDM_UNKNOWN = 0;

-    PDM_OFF = 1;

-    PDM_OPPORTUNISTIC = 2;

-    PDM_STRICT = 3;

-}

-

-enum Transport {

-    // Indicates this network uses a Cellular transport.

-    TRANSPORT_DEFAULT = 0;  // TRANSPORT_CELLULAR

-    // Indicates this network uses a Wi-Fi transport.

-    TRANSPORT_WIFI = 1;

-    // Indicates this network uses a Bluetooth transport.

-    TRANSPORT_BLUETOOTH = 2;

-    // Indicates this network uses an Ethernet transport.

-    TRANSPORT_ETHERNET = 3;

-    // Indicates this network uses a VPN transport.

-    TRANSPORT_VPN = 4;

-    // Indicates this network uses a Wi-Fi Aware transport.

-    TRANSPORT_WIFI_AWARE = 5;

-    // Indicates this network uses a LoWPAN transport.

-    TRANSPORT_LOWPAN = 6;

-}

-

-enum CacheStatus{

-    // the cache can't handle that kind of queries.

-    // or the answer buffer is too small.

-    CS_UNSUPPORTED = 0;

-    // the cache doesn't know about this query.

-    CS_NOTFOUND = 1;

-    // the cache found the answer.

-    CS_FOUND = 2;

-    // Don't do anything on cache.

-    CS_SKIP = 3;

-}

-

-message DnsQueryEvent {

-    optional android.stats.dnsresolver.NsRcode rcode = 1;

-

-    optional android.stats.dnsresolver.NsType type = 2;

-

-    optional android.stats.dnsresolver.CacheStatus cache_hit = 3;

-

-    optional android.stats.dnsresolver.IpVersion ip_version = 4;

-

-    optional android.stats.dnsresolver.TransportType transport = 5;

-

-    // Number of DNS query retry times

-    optional int32 retry_times = 6;

-

-    // Ordinal number of name server.

-    optional int32 dns_server_count = 7;

-

-    // Used only by TCP and DOT. True for new connections.

-    optional bool connected = 8;

-

-    optional int32 latency_micros = 9;

-}

-

-message DnsQueryEvents {

-    repeated DnsQueryEvent dns_query_event = 1;

-}

+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.dnsresolver;
+
+enum EventType {
+    EVENT_UNKNOWN = 0;
+    EVENT_GETADDRINFO = 1;
+    EVENT_GETHOSTBYNAME = 2;
+    EVENT_GETHOSTBYADDR = 3;
+    EVENT_RES_NSEND = 4;
+}
+
+// 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_NO_ERROR = 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;
+    NS_R_INTERNAL_ERROR = 254;
+    NS_R_TIMEOUT = 255;
+}
+
+// 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 {
+    IV_UNKNOWN = 0;
+    IV_IPV4 = 1;
+    IV_IPV6 = 2;
+}
+
+enum Protocol {
+    PROTO_UNKNOWN = 0;
+    PROTO_UDP = 1;
+    PROTO_TCP = 2;
+    PROTO_DOT = 3;
+}
+
+enum PrivateDnsModes {
+    PDM_UNKNOWN = 0;
+    PDM_OFF = 1;
+    PDM_OPPORTUNISTIC = 2;
+    PDM_STRICT = 3;
+}
+
+enum NetworkType {
+    NT_UNKNOWN = 0;
+    // Indicates this network uses a Cellular transport.
+    NT_CELLULAR = 1;
+    // Indicates this network uses a Wi-Fi transport.
+    NT_WIFI = 2;
+    // Indicates this network uses a Bluetooth transport.
+    NT_BLUETOOTH = 3;
+    // Indicates this network uses an Ethernet transport.
+    NT_ETHERNET = 4;
+    // Indicates this network uses a VPN transport.
+    NT_VPN = 5;
+    // Indicates this network uses a Wi-Fi Aware transport.
+    NT_WIFI_AWARE = 6;
+    // Indicates this network uses a LoWPAN transport.
+    NT_LOWPAN = 7;
+}
+
+enum CacheStatus{
+    // the cache can't handle that kind of queries.
+    // or the answer buffer is too small.
+    CS_UNSUPPORTED = 0;
+    // the cache doesn't know about this query.
+    CS_NOTFOUND = 1;
+    // the cache found the answer.
+    CS_FOUND = 2;
+    // Don't do anything on cache.
+    CS_SKIP = 3;
+}
+
+message DnsQueryEvent {
+    optional android.stats.dnsresolver.NsRcode rcode = 1;
+
+    optional android.stats.dnsresolver.NsType type = 2;
+
+    optional android.stats.dnsresolver.CacheStatus cache_hit = 3;
+
+    optional android.stats.dnsresolver.IpVersion ip_version = 4;
+
+    optional android.stats.dnsresolver.Protocol protocol = 5;
+
+    // Number of DNS query retry times
+    optional int32 retry_times = 6;
+
+    // Ordinal number of name server.
+    optional int32 dns_server_index = 7;
+
+    // Used only by TCP and DOT. True for new connections.
+    optional bool connected = 8;
+
+    optional int32 latency_micros = 9;
+}
+
+message DnsQueryEvents {
+    repeated DnsQueryEvent dns_query_event = 1;
+}
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 4e60f8c..3dc74f8 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -16,7 +16,7 @@
 
 android_app {
     name: "framework-res",
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     certificate: "platform",
 
     // Soong special-cases framework-res to install this alongside
@@ -38,6 +38,12 @@
     // Create package-export.apk, which other packages can use to get
     // PRODUCT-agnostic resource data like IDs and type definitions.
     export_package_resources: true,
+
+    dist: {
+        targets: [
+            "simulated_device_launcher",
+        ],
+    },
 }
 
 // This logic can be removed once robolectric's transition to binary resources is complete
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6accab1..40acebc 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -536,6 +536,7 @@
     <protected-broadcast android:name="android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL" />
     <protected-broadcast android:name="android.app.action.NOTIFICATION_POLICY_CHANGED" />
     <protected-broadcast android:name="android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED" />
+    <protected-broadcast android:name="android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED" />
     <protected-broadcast android:name="android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED" />
     <protected-broadcast android:name="android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED" />
     <protected-broadcast android:name="android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED" />
@@ -724,6 +725,10 @@
 
     <!-- Allows an application to send SMS messages.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.SEND_SMS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -734,6 +739,10 @@
 
     <!-- Allows an application to receive SMS messages.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.RECEIVE_SMS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -744,6 +753,10 @@
 
     <!-- Allows an application to read SMS messages.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.READ_SMS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -754,6 +767,10 @@
 
     <!-- Allows an application to receive WAP push messages.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.RECEIVE_WAP_PUSH"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -763,7 +780,11 @@
         android:protectionLevel="dangerous" />
 
     <!-- Allows an application to monitor incoming MMS messages.
-        <p>Protection level: dangerous
+         <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.RECEIVE_MMS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -783,6 +804,11 @@
          when the alert is first received, and to delay presenting the info
          to the user until after the initial alert dialog is dismissed.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
+
          @hide Pending API council approval -->
     <permission android:name="android.permission.READ_CELL_BROADCASTS"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -805,25 +831,35 @@
         android:priority="900" />
 
     <!-- Allows an application to read from external storage.
-     <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
-     granted this permission.</p>
-     <p>This permission is enforced starting in API level 19.  Before API level 19, this
-     permission is not enforced and all apps still have access to read from external storage.
-     You can test your app with the permission enforced by enabling <em>Protect USB
-     storage</em> under Developer options in the Settings app on a device running Android 4.1 or
-     higher.</p>
-     <p>Also starting in API level 19, this permission is <em>not</em> required to
-     read/write files in your application-specific directories returned by
-     {@link android.content.Context#getExternalFilesDir} and
-     {@link android.content.Context#getExternalCacheDir}.
-     <p class="note"><strong>Note:</strong> If <em>both</em> your <a
-     href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
-     minSdkVersion}</a> and <a
-     href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-     targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
-     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.
+      <p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
+      granted this permission.</p>
+      <p>This permission is enforced starting in API level 19.  Before API level 19, this
+      permission is not enforced and all apps still have access to read from external storage.
+      You can test your app with the permission enforced by enabling <em>Protect USB
+      storage</em> under Developer options in the Settings app on a device running Android 4.1 or
+      higher.</p>
+      <p>Also starting in API level 19, this permission is <em>not</em> required to
+      read/write files in your application-specific directories returned by
+      {@link android.content.Context#getExternalFilesDir} and
+      {@link android.content.Context#getExternalCacheDir}.
+      <p class="note"><strong>Note:</strong> If <em>both</em> your <a
+      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+      minSdkVersion}</a> and <a
+      href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+      targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
+      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.
+
+      <p> This is a soft restricted permission which cannot be held by an app it its
+      full form until the installer on record did not whitelist the permission.
+      Specifically, if the permission is whitelisted the holder app can access
+      external storage and the visual and aural media collections while if the
+      permission is not whitelisted the holder app can only access to the visual
+      and aural medial collections. Also the permission is immutably restricted
+      meaning that the whitelist state can be specified only at install time and
+      cannot change until the app is installed. For more details see
+      {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
      -->
     <permission android:name="android.permission.READ_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -845,6 +881,8 @@
          read/write files in your application-specific directories returned by
          {@link android.content.Context#getExternalFilesDir} and
          {@link android.content.Context#getExternalCacheDir}.
+         <p>Is this permission is not whitelisted for an app that targets an API level before
+         {@link android.os.Build.VERSION_CODES#Q} this permission cannot be granted to apps.</p>
     -->
     <permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -909,6 +947,10 @@
          {@link #ACCESS_FINE_LOCATION}. Requesting this permission by itself doesn't give you
          location access.
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -951,6 +993,10 @@
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
          targetSdkVersion}</a> is 16 or higher.</p>
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.READ_CALL_LOG"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -971,6 +1017,10 @@
          href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
          targetSdkVersion}</a> is 16 or higher.</p>
          <p>Protection level: dangerous
+
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
     -->
     <permission android:name="android.permission.WRITE_CALL_LOG"
         android:permissionGroup="android.permission-group.UNDEFINED"
@@ -984,6 +1034,10 @@
          abort the call altogether.
          <p>Protection level: dangerous
 
+         <p> This is a hard restricted permission which cannot be held by an app until
+         the installer on record did not whitelist the permission. For more details see
+         {@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
+
          @deprecated Applications should use {@link android.telecom.CallRedirectionService} instead
          of the {@link android.content.Intent#ACTION_NEW_OUTGOING_CALL} broadcast.
     -->
@@ -1532,7 +1586,7 @@
          recommendations and scores from the NetworkScoreService.
          <p>Not for use by third-party applications. @hide -->
     <permission android:name="android.permission.REQUEST_NETWORK_SCORES"
-        android:protectionLevel="signature|setup" />
+        android:protectionLevel="signature|setup|privileged" />
 
     <!-- Allows network stack services (Connectivity and Wifi) to coordinate
          <p>Not for use by third-party or privileged applications.
@@ -2519,7 +2573,7 @@
     <!-- @SystemApi @TestApi @hide Allows an application to modify config settings.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_DEVICE_CONFIG"
-        android:protectionLevel="signature|configurator"/>
+        android:protectionLevel="signature|verifier|configurator"/>
 
     <!-- @SystemApi @hide Allows an application to read config settings.
     <p>Not for use by third-party applications. -->
@@ -4596,15 +4650,16 @@
                 android:label="@string/managed_profile_label">
         </activity-alias>
         <activity android:name="com.android.internal.app.HeavyWeightSwitcherActivity"
-                android:theme="@style/Theme.DeviceDefault.Light.Dialog"
+                android:theme="@style/Theme.DeviceDefault.System.Dialog.Alert"
                 android:label="@string/heavy_weight_switcher_title"
                 android:finishOnCloseSystemDialogs="true"
                 android:excludeFromRecents="true"
                 android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.PlatLogoActivity"
-                android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"
+                android:theme="@style/Theme.DeviceDefault.DayNight"
                 android:configChanges="orientation|keyboardHidden"
+                android:icon="@drawable/platlogo"
                 android:process=":ui">
         </activity>
         <activity android:name="com.android.internal.app.DisableCarModeActivity"
@@ -4926,6 +4981,7 @@
         <service
                 android:name="com.android.server.autofill.AutofillCompatAccessibilityService"
                 android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
+                android:visibleToInstantApps="true"
                 android:exported="true">
             <meta-data
                     android:name="android.accessibilityservice"
diff --git a/core/res/res/anim/lock_screen_behind_enter_subtle.xml b/core/res/res/anim/lock_screen_behind_enter_subtle.xml
new file mode 100644
index 0000000..f9f69b1
--- /dev/null
+++ b/core/res/res/anim/lock_screen_behind_enter_subtle.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
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:detachWallpaper="true"
+        android:shareInterpolator="false">
+
+   <alpha
+        android:fromAlpha="0.0" android:toAlpha="1.0"
+        android:fillEnabled="true" android:fillBefore="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="80"
+        android:duration="233"/>
+    <translate android:fromYDelta="5%p" android:toYDelta="0"
+            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+            android:interpolator="@interpolator/fast_out_slow_in"
+            android:startOffset="80"
+            android:duration="233" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/drawable-nodpi/android_logotype.xml b/core/res/res/drawable-nodpi/android_logotype.xml
new file mode 100644
index 0000000..bd298e4
--- /dev/null
+++ b/core/res/res/drawable-nodpi/android_logotype.xml
@@ -0,0 +1,42 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="290dp"
+        android:height="64dp"
+        android:viewportWidth="290.0"
+        android:viewportHeight="64.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M21.81,28.91c-7.44,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37s12.45,-5.85,12.45,-13.37   C34.26,34.76,29.24,28.91,21.81,28.91 M20.13,20.55c6.02,0,11.03,3.09,13.37,6.43v-5.6l9.19,0l0,41.78l-6.24,0   c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65C31.17,60.91,26.15,64,20.14,64C8.69,64,0,54.23,0,42.28C0,30.33,8.69,20.55,20.13,20.55"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M53.13,21.39l9.19,0l0,5.68c2.5,-4.18,7.27,-6.52,12.7,-6.52c9.69,0,15.96,6.85,15.96,17.46l0,25.15l-6.24,0   c-1.63,0,-2.95,-1.32,-2.95,-2.95l0,-20.7c0,-6.6,-3.34,-10.61,-8.69,-10.61c-6.1,0,-10.78,4.76,-10.78,13.7l0,20.55l-6.25,0   c-1.63,0,-2.95,-1.32,-2.95,-2.95L53.13,21.39z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M120.06,28.91c-7.43,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37c7.43,0,12.45,-5.85,12.45,-13.37   C132.51,34.76,127.5,28.91,120.06,28.91 M118.39,20.55c6.02,0,11.03,3.09,13.37,6.43l0,-26.49l9.19,0l0,62.66h-6.24   c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65c-2.34,3.34,-7.35,6.43,-13.37,6.43c-11.45,0,-20.14,-9.77,-20.14,-21.72   C98.25,30.33,106.94,20.55,118.39,20.55"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M151.39,21.39l9.19,0v7.44c1.59,-4.76,6.27,-7.86,11.03,-7.86c1.17,0,2.34,0.08,3.59,0.34v9.44c-1.59,-0.5,-2.92,-0.75,-4.59,-0.75   c-5.26,0,-10.03,4.43,-10.03,12.78l0,20.39l-6.24,0c-1.63,0,-2.95,-1.32,-2.95,-2.95L151.39,21.39z"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M199.98,55.48c7.35,0,12.53,-5.77,12.53,-13.2c0,-7.44,-5.18,-13.2,-12.53,-13.2c-7.44,0,-12.62,5.77,-12.62,13.2   C187.37,49.71,192.55,55.48,199.98,55.48 M199.98,64c-12.37,0,-21.89,-9.61,-21.89,-21.72c0,-12.12,9.52,-21.73,21.89,-21.73   c12.37,0,21.89,9.61,21.89,21.73C221.87,54.39,212.35,64,199.98,64"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M229.32,21.39l9.19,0l0,41.78l-6.24,0c-1.63,0,-2.95,-1.32,-2.95,-2.95L229.32,21.39z M233.92,12.28   c-3.34,0,-6.18,-2.76,-6.18,-6.18c0,-3.34,2.84,-6.1,6.18,-6.1c3.43,0,6.1,2.76,6.1,6.1C240.02,9.53,237.34,12.28,233.92,12.28"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M267.87,28.91c-7.43,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37c7.44,0,12.45,-5.85,12.45,-13.37   C280.32,34.76,275.31,28.91,267.87,28.91 M266.2,20.55c6.02,0,11.03,3.09,13.37,6.43l0,-26.49l9.19,0l0,62.66l-6.24,0   c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65c-2.34,3.34,-7.35,6.43,-13.37,6.43c-11.44,0,-20.14,-9.77,-20.14,-21.72S254.76,20.55,266.2,20.55"/>
+</vector>
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index f5bbadc..19a296a 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2018 The Android Open Source Project
+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.
@@ -13,21 +13,15 @@
     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="vector"
-    android:width="640dp"
-    android:height="640dp"
-    android:viewportWidth="64"
-    android:viewportHeight="64">
+<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:name="bg"
-        android:pathData="M 27 43 L 32 43 C 38.075 43 43 38.075 43 32 C 43 25.925 38.075 21 32 21 C 25.925 21 21 25.925 21 32 L 21 64"
-        android:strokeColor="#6823a1"
-        android:strokeWidth="16"/>
+        android:fillColor="#FF000000"
+        android:pathData="M19.45,22.89l-10.250001,-10.249999l-2.6599998,2.6599998l-1.77,-1.7600002l4.43,-4.4300003l12.0199995,12.0199995l-1.7699986,1.7600002z"/>
     <path
-        android:name="fg"
-        android:pathData="M 29 43 L 32 43 C 38.075 43 43 38.075 43 32 C 43 25.925 38.075 21 32 21 C 25.925 21 21 25.925 21 32 L 21 64"
-        android:strokeColor="#ff0000"
-        android:strokeWidth="8"/>
+        android:fillColor="#FF000000"
+        android:pathData="M12,6a6,6 0,1 1,-6 6,6 6,0 0,1 6,-6m0,-2.5A8.5,8.5 0,1 0,20.5 12,8.51 8.51,0 0,0 12,3.5Z"/>
 </vector>
diff --git a/core/res/res/drawable/ic_qs_ui_mode_night.xml b/core/res/res/drawable/ic_qs_ui_mode_night.xml
index 7227827..34b535b 100644
--- a/core/res/res/drawable/ic_qs_ui_mode_night.xml
+++ b/core/res/res/drawable/ic_qs_ui_mode_night.xml
@@ -15,11 +15,11 @@
   ~ limitations under the License
   -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
+        android:width="24dp"
+        android:height="24dp"
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
+        android:fillColor="@android:color/white"
         android:pathData="M12,22C17.52,22 22,17.52 22,12 22,6.48 17.52,2 12,2 6.48,2 2,6.48 2,12 2,17.52 6.48,22 12,22ZM12,3.915c3.889,0 8,4.005 8,8.085 0,4.08 -3.927,7.992 -7.928,7.992z"/>
-</vector>
\ No newline at end of file
+</vector>
diff --git a/core/res/res/drawable/pointer_horizontal_double_arrow_icon.xml b/core/res/res/drawable/pointer_horizontal_double_arrow_icon.xml
index 5a5ad9e..93b3fe5 100644
--- a/core/res/res/drawable/pointer_horizontal_double_arrow_icon.xml
+++ b/core/res/res/drawable/pointer_horizontal_double_arrow_icon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
     android:bitmap="@drawable/pointer_horizontal_double_arrow"
-    android:hotSpotX="11dp"
-    android:hotSpotY="12dp" />
+    android:hotSpotX="12dp"
+    android:hotSpotY="11dp" />
diff --git a/core/res/res/layout-car/car_preference.xml b/core/res/res/layout-car/car_preference.xml
index b138f4d..2f9b465 100644
--- a/core/res/res/layout-car/car_preference.xml
+++ b/core/res/res/layout-car/car_preference.xml
@@ -49,7 +49,6 @@
             android:id="@id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:ellipsize="end"
             android:singleLine="true"
             android:textAppearance="?android:attr/textAppearanceListItem"/>
 
diff --git a/core/res/res/layout-car/car_preference_category.xml b/core/res/res/layout-car/car_preference_category.xml
index b674487..3def511 100644
--- a/core/res/res/layout-car/car_preference_category.xml
+++ b/core/res/res/layout-car/car_preference_category.xml
@@ -56,7 +56,6 @@
             android:id="@id/summary"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:ellipsize="end"
             android:singleLine="true"
             android:textColor="?android:attr/textColorSecondary"/>
 
diff --git a/core/res/res/layout/accessibility_button_chooser.xml b/core/res/res/layout/accessibility_button_chooser.xml
index 480defb..383780a 100644
--- a/core/res/res/layout/accessibility_button_chooser.xml
+++ b/core/res/res/layout/accessibility_button_chooser.xml
@@ -40,6 +40,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:minHeight="56dp"
+            android:id="@+id/accessibility_button_prompt_prologue"
             android:textAppearance="?attr/textAppearanceMedium"
             android:text="@string/accessibility_button_prompt_text"
             android:gravity="start|center_vertical"
diff --git a/core/res/res/layout/heavy_weight_switcher.xml b/core/res/res/layout/heavy_weight_switcher.xml
index dbd8ece..3f568f6 100644
--- a/core/res/res/layout/heavy_weight_switcher.xml
+++ b/core/res/res/layout/heavy_weight_switcher.xml
@@ -15,7 +15,9 @@
 -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:padding="24dp"
+    android:orientation="vertical"
+    android:paddingVertical="24dp"
+    android:paddingHorizontal="16dp"
     android:gravity="center_horizontal"
     android:layout_width="wrap_content" android:layout_height="wrap_content">
 
@@ -23,6 +25,7 @@
         android:layout_width="match_parent" android:layout_height="wrap_content"
         android:layout_weight="0"
         android:paddingBottom="20dp"
+        android:paddingHorizontal="8dp"
         android:textAppearance="?android:attr/textAppearanceLarge"
         android:text="@string/heavy_weight_switcher_title"/>
 
@@ -30,6 +33,7 @@
         android:layout_width="match_parent" android:layout_height="wrap_content"
         android:layout_weight="0"
         android:paddingBottom="16dp"
+        android:paddingHorizontal="8dp"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:text="@string/heavy_weight_switcher_text"/>
 
@@ -37,8 +41,9 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:minHeight="72dp"
+        android:paddingHorizontal="8dp"
         android:orientation="horizontal"
-        android:background="@android:drawable/list_selector_background"
+        android:background="?android:attr/selectableItemBackground"
         android:gravity="center_vertical"
         android:focusable="true" >
     
@@ -68,8 +73,9 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:minHeight="88dp"
+        android:paddingHorizontal="8dp"
         android:orientation="horizontal"
-        android:background="@android:drawable/list_selector_background"
+        android:background="?android:attr/selectableItemBackground"
         android:gravity="center_vertical"
         android:focusable="true" >
     
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 13fef67..575295b 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 
-<FrameLayout
+<com.android.internal.widget.MediaNotificationView
     android:id="@+id/status_bar_latest_event_content"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
@@ -24,8 +24,8 @@
     android:tag="media"
     >
     <ImageView android:id="@+id/right_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
         android:adjustViewBounds="true"
         android:layout_gravity="top|end"
         android:scaleType="centerCrop"
@@ -91,4 +91,4 @@
             android:layout_alignParentBottom="true"
         />
     </LinearLayout>
-</FrameLayout>
+</com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/platlogo_layout.xml b/core/res/res/layout/platlogo_layout.xml
new file mode 100644
index 0000000..4a4ad75
--- /dev/null
+++ b/core/res/res/layout/platlogo_layout.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clipChildren="false"
+    android:background="@android:color/transparent">
+    <ImageView
+        android:id="@+id/text"
+        android:layout_width="400dp"
+        android:layout_height="wrap_content"
+        android:translationY="-100dp"
+        android:adjustViewBounds="true"
+        android:layout_marginBottom="-80dp"
+        android:layout_centerInParent="true"
+        android:src="@drawable/android_logotype"
+        android:tint="?android:attr/textColorPrimary"
+        />
+    <ImageView
+        android:id="@+id/one"
+        android:layout_width="200dp"
+        android:layout_height="200dp"
+        android:layout_marginLeft="24dp"
+        android:layout_below="@id/text"
+        android:layout_alignLeft="@id/text"
+        android:tint="?android:attr/textColorPrimary"
+        />
+    <ImageView
+        android:id="@+id/zero"
+        android:layout_width="200dp"
+        android:layout_height="200dp"
+        android:layout_marginRight="34dp"
+        android:layout_below="@id/text"
+        android:layout_alignRight="@id/text"
+        android:tint="?android:attr/textColorPrimary"
+        />
+</RelativeLayout>
diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml
index aeaccfd..1dd4207 100644
--- a/core/res/res/layout/resolver_list.xml
+++ b/core/res/res/layout/resolver_list.xml
@@ -129,18 +129,6 @@
             android:enabled="false"
             android:text="@string/activity_resolver_use_always"
             android:onClick="onButtonClick" />
-
-        <Button
-            android:id="@+id/button_app_settings"
-            android:layout_width="wrap_content"
-            android:layout_gravity="end"
-            android:maxLines="2"
-            android:minHeight="@dimen/alert_dialog_button_bar_height"
-            style="?attr/buttonBarPositiveButtonStyle"
-            android:layout_height="wrap_content"
-            android:enabled="false"
-            android:text="@string/activity_resolver_app_settings"
-            android:onClick="onButtonClick" />
     </LinearLayout>
 
 </com.android.internal.widget.ResolverDrawerLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index a38c784e..7a0d475 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-oproepe"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-oproepe"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-oproep"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>-WLAN-oproep"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Motormodus"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Rekeningstatus"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Ontwikkelaarboodskappe"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Belangrike ontwikkelaarboodskappe"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Opdaterings"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Netwerkstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Netwerkwaarskuwings"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Beweeg foon na links."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Beweeg foon na regs."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Kyk asseblief meer reguit na jou toestel."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Kan nie jou gesig sien nie Kyk na die foon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Posisioneer jou gesig direk voor die foon."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Te veel beweging. Hou foon stil."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Skryf jou gesig asseblief weer in."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Kan nie meer gesig herken nie. Probeer weer."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Draai jou kop \'n bietjie minder."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Draai jou kop \'n bietjie minder."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Verwyder enigiets wat jou gesig versteek."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Maak die sensor op die skerm se borand skoon."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Maak die bokant van jou skerm skoon, insluitend die swart balk"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Kan nie gesig verifieer nie. Hardeware nie beskikbaar nie."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Maak oop met"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Maak oop met %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Maak oop"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Gee toegang tot oop <xliff:g id="HOST">%1$s</xliff:g>-skakels met"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Gee toegang tot oop <xliff:g id="HOST">%1$s</xliff:g>-skakels met <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Maak <xliff:g id="HOST">%1$s</xliff:g>-skakels oop met"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Maak skakels oop met"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Maak skakels oop met <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Maak <xliff:g id="HOST">%1$s</xliff:g>-skakels oop met <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Verleen toegang"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Redigeer met"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Redigeer met %1$s"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Begin webblaaier?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Aanvaar oproep?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Altyd"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Stel om altyd oop te maak"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Net een keer"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Instellings"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s steun nie werkprofiel nie"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Oorlegger #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", veilig"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Hierdie begin van agtergrondaktiwiteit vanaf <xliff:g id="PACKAGENAME">%1$s</xliff:g> sal in toekomstige Q-bouweergawes geblokkeer word. Sien g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Begin van agtergrondaktiwiteit vanaf <xliff:g id="PACKAGENAME">%1$s</xliff:g> word geblokkeer. Sien g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Het jy die patroon vergeet?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Verkeerde patroon"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Verkeerde wagwoord"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Toeganklikheidskortpad het <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Toeganklikheidskortpad het <xliff:g id="SERVICE_NAME">%1$s</xliff:g> afgeskakel"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Druk en hou albei volumesleutels drie sekondes lank om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruik"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Kies \'n kenmerk om te gebruik wanneer jy op die Toeganklikheid-knoppie tik:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Raak en hou die Toeganklikheid-knoppie om kenmerke te verander."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Kies \'n diens om te gebruik wanneer jy op die toeganklikheidknoppie tik:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Kies \'n diens om te gebruik saam met die toeganklikheidgebaar (swiep met twee vingers op van die onderkant van die skerm af):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Kies \'n diens om te gebruik saam met die toeganklikheidgebaar (swiep met drie vingers op van die onderkant van die skerm af):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Raak en hou die toeganklikheidknoppie om tussen dienste te wissel."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Swiep op met twee vingers en hou om tussen dienste te wissel."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Swiep op met drie vingers en hou om tussen dienste te wissel."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergroting"</string>
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Skakel tans oor na <xliff:g id="NAME">%1$s</xliff:g> …"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 78b46ef..11ab44d 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> የWi-Fi ጥሪ አደራረግ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> የWi-Fi ጥሪ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"የWLAN ጥሪ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> የWLAN ጥሪ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"የመኪና ሁነታ"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"የመለያ ሁኔታ"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"የገንቢ መልዕክቶች"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"አስፈላጊ የገንቢ መልዕክቶች"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"ዝማኔዎች"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"የአውታረ መረብ ሁኔታ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"የአውታረ መረብ ማንቂያዎች"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"የጣት አሻራ አዶ"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"በመልክ መክፈቻ ሃርድዌርን ማስተዳደር"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"መተግበሪያው ጥቅም ላይ እንዲውሉ የፊት ቅንብር ደንቦችን ለማከል እና ለመሰረዝ የሚያስችሉ ስልቶችን እንዲያስጀምር ያስችለዋል።"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"በመልክ መክፈት ሃርድዌርን መጠቀም"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"መተግበሪያው የመልክ መክፈቻ ሃርድዌርን ለማረጋገጥ እንዲጠቀም ያስችለዋል"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"በመልክ መክፈት"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"የእርስዎን ፊት ዳግመኛ ያስመዝግቡ"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"ማንነትን ለይቶ ማወቅን ለማሻሻል፣ እባክዎ የእርስዎን ፊት ዳግም ያስመዝግቡ"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"ትክክለኛ የፊት ውሂብ ማንሳት አልተቻለም። እንደገና ይሞክሩ።"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ስልክን ወደ ግራ ያንቀሳቅሱ።"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ስልክን ወደ ቀኝ ያንቀሳቅሱ።"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"እባክዎ መሣሪያዎን ይበልጥ በቀጥታ ይመልከቱ።"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"የእርስዎን ፊት መመልከት አይችልም። ስልኩ ላይ ይመልከቱ።"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"መልክዎን በቀጥታ ከስልኩ ፊት ያድርጉት።"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"ከልክ በላይ ብዙ እንቅስቃሴ። ስልኩን ቀጥ አድርገው ይያዙት።"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"እባክዎ ፊትዎን እንደገና ያስመዝግቡ"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"ከእንግዲህ ፊትን ለይቶ ማወቅ አይችልም። እንደገና ይሞክሩ።"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ጭንቅላትዎን ትንሽ ብቻ ያዙሩት።"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"ጭንቅላትዎን ትንሽ ብቻ ያዙሩት።"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"የእርስዎን ፊት የሚደብቀውን ሁሉንም ነገር በማስወገድ ላይ"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"በማያ ገጹ ላይኛው ጫፍ ላይ ዳሳሹን ያጽዱ።"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"የማያ ገጽዎን አናት ያጽዱት፣ ጥቁር አሞሌውን ጨምሮ"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"መልክን ማረጋገጥ አይቻልም። ሃርድዌር የለም።"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"በመልክ መክፈትን እንደገና ይሞክሩ።"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"አዲስ የመልክ ውውሂብ ማስቀመጥ አልተቻለም። መጀመሪያ የድሮውን ይሰርዙት።"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"የፊት ሥርዓተ ክወና ተሰርዟል።"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"በመልክ መክፈት በተጠቃሚ ተሰርዟል።"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ከልክ በላይ ብዙ ሙከራዎች። በኋላ ላይ እንደገና ይሞክሩ።"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"በጣም ብዙ ሙከራዎች። በመልክ መክፈት ተሰናክሏል።"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"ፊትን ማረጋገጥ አይቻልም። እንደገና ይሞክሩ።"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"በመልክ መክፈትን አላቀናበሩም።"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"በመልክ መክፈት መስጫ በዚህ መሣሪያ ላይ አይደገፍም።"</string>
     <string name="face_name_template" msgid="7004562145809595384">"ፊት <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"ክፈት በ"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"ክፈት በ%1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"ክፈት"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"የ<xliff:g id="HOST">%1$s</xliff:g> አገናኞችን በዚህ ለመክፈት መዳረሻ ይስጡ፦"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"የ<xliff:g id="HOST">%1$s</xliff:g> አገናኞችን በ<xliff:g id="APPLICATION">%2$s</xliff:g> ለመክፈት መዳረሻ ይስጡ"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> አገናኞችን ክፈት ከዚህ ጋር"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"አገናኞችን ክፈት ከዚህ ጋር"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"አገናኞችን ከ <xliff:g id="APPLICATION">%1$s</xliff:g> ጋር ክፈት"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> አገናኞችን ከ <xliff:g id="APPLICATION">%2$s</xliff:g> ጋር ክፈት"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"መዳረሻ ስጥ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ያርትዑ በ"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"ያርትዑ በ%1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"የመሞከሪያ ጥቅል ሁነታን ለማሰናከል የፋብሪካ ዳግም ቅንብርን ይሞክሩ።"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"በዩኤስቢ ወደብ ውስጥ ፈሳሽ ወይም ፍርስራሽ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"የዩኤስቢ ወደብ በራስ-ሰር ተሰናክሏል። የበለጠ ለመረዳት መታ ያድርጉ።"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"የዩኤስቢ ወደቡን መጠቀም ችግር የለውም"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ስልክ ከእንግዲህ ፈሳሽ ወይም ፍርስራሽ አላገኘም።"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"የሳንካ ሪፖርትን በመውሰድ ላይ…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"የሳንካ ሪፖርት ይጋራ?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"ቀጣዩን አግኝ"</string>
     <string name="find_previous" msgid="2196723669388360506">"ቀዳሚውን አግኝ"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"የስፍራ ጥየቃ ቅፅ<xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"የስፍራ ጥየቃ"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"የአካባቢ ጥየቃ"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">" በ፡<xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>) ተጠየቀ"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"አዎ"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"አይ"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ማሰሺያን አስነሳ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ጥሪ ተቀበል?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ዘወትር"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ሁልጊዜ ክፍት ወደ የሚል ተቀናብሯል"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"አንዴ ብቻ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ቅንብሮች"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s የስራ መገለጫ አይደግፍም"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ተደራቢ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>፦ <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>፣ <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"፣ የተጠበቀ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"ይህ የ<xliff:g id="PACKAGENAME">%1$s</xliff:g> የበስተጀርባ እንቅስቃሴ ጅምር በወደፊት የQ ግንቦች ላይ ይታገዳል። g.co/dev/bgblock ይመልከቱ።"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"የ<xliff:g id="PACKAGENAME">%1$s</xliff:g> የበስተጀርባ እንቅስቃሴ ጅምር ታግዷል። g.co/dev/bgblock ይመልከቱ።"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ስርዓተ ጥለቱን እርሳ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"የተሳሳተ ስርዓተ ጥለት"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"የተሳሳተ ይለፍ ቃል"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"የተደራሽነት አቋራጭ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን አብርቶታል"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"የተደራሽነት አቋራጭ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን አጥፍቶታል"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለመጠቀም ለሦስት ሰከንዶች ሁለቱንም የድምፅ ቁልፎች ተጭነው ይያዙ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"የተደራሽነት አዝራርን መታ በሚያደርጉበት ጊዜ ጥቅም ላይ የሚውለውን ባህሪ ይምረጡ፦"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ባህሪያትን ለመለወጥ የተደራሽነት አዝራሩን ይንኩ እና ይያዙት።"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"የተደራሽነት አዝራርን መታ በሚያደርጉበት ጊዜ ጥቅም ላይ የሚውለውን አገልግሎት ይምረጡ፦"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ከተደራሽነት ጣት ምልክት ጋር የሚጠቀሙበት አአገልግሎት ይምረጡ (በሁለት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ከተደራሽነት ጣት ምልክት ጋር አብረው የሚጠቀሙበት አገልግሎት ይምረጡ (በሶስት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"በአገልግሎቶች መካከል ለመቀያየር የተደራሽነት አዝራሩን ነክተው ይያዙ።"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"በአገልግሎቶች መካከል ለመቀያየር በሁለት ጣቶች ወደ ላይ ጠርገው ይያዙ።"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"በአገልግሎቶች መካከል ለመቀያየር በሶስት ጣቶች ወደ ላይ ጠርገው ይያዙ።"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ማጉላት"</string>
     <string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"ወደ <xliff:g id="NAME">%1$s</xliff:g> በመቀየር ላይ…"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index dfc316c..6edc933 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -135,6 +135,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏الاتصال عبر شبكة Wi-Fi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‏الاتصال عبر Wi-Fi ضمن شبكة <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏مكالمة عبر شبكة WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏مكالمة عبر شبكة WLAN التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"‏شبكة Wi-Fi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -268,6 +269,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"وضع السيارة"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"حالة الحساب"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"رسائل مطوّر البرامج"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"رسائل مطوّر البرامج المُهمة"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"التحديثات"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"حالة الشبكة"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"تنبيهات الشبكة"</string>
@@ -307,7 +309,7 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إلى الصور والوسائط والملفات على جهازك؟"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"الميكروفون"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"تسجيل الصوت"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بتسجيل الصوت؟"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"‏هل تريد السماح لـ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بتسجيل الصوت؟"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"النشاط البدني"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"الوصول إلى بيانات نشاطك البدني"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"‏هل تريد السماح للتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إلى بيانات نشاطك البدني؟"</string>
@@ -319,7 +321,7 @@
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إلى سجلّ مكالماتك الهاتفية؟"</string>
     <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>
+    <string name="permgrouprequest_phone" msgid="9166979577750581037">"‏هل تريد السماح لـ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بإجراء المكالمات الهاتفية وإدارتها؟"</string>
     <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>
@@ -561,15 +563,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"رمز بصمة الإصبع"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"إدارة أجهزة \"فتح القفل بالوجه\""</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"السماح للتطبيق باستدعاء طرق لإضافة نماذج من الوجوه وحذفها"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"استخدام أجهزة \"فتح القفل بالوجه\""</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"السماح للتطبيق باستخدام أجهزة \"فتح القفل بالوجه\" لإجراء المصادقة"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"فتح القفل بالوجه"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"إعادة تسجيل وجهك"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"لتحسين قدرة الجهاز على معرفة وجهك، يُرجى إعادة تسجيل الوجه."</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"تعذّر تسجيل بيانات دقيقة للوجه. حاول مرة أخرى."</string>
@@ -582,7 +580,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"يُرجى نقل الهاتف إلى اليمين."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"يُرجى نقل الهاتف إلى اليسار."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"يُرجى النظر إلى جهازك مباشرة أكثر."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"يتعذّر رؤية وجهك. يُرجى النظر إلى الهاتف."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"ضع وجهك أمام الهاتف مباشرة."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"حركة أكثر من اللازم يُرجى حمل بدون حركة."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"يُرجى إعادة تسجيل وجهك."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"لم يعُد يمكن التعرّف على الوجه. حاول مرة أخرى."</string>
@@ -591,24 +589,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"حرّك رأسك قليلاً نحو الأمام مباشرة."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"حرّك رأسك قليلاً نحو الوسط."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"عليك بإزالة أي شيء يُخفي وجهك."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"نظِّف المستشعر أعلى الشاشة."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"يُرجى تنظيف الجزء العلوي من الشاشة، بما في ذلك الشريط الأسود."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"يتعذّر التحقُّق من الوجه. الجهاز غير مُتاح."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"حاول استخدام \"فتح القفل بالوجه\" مرة أخرى."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"يتعذَّر تخزين بيانات الوجه الجديد. احذف الوجه القديم أولاً."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"تمّ إلغاء عملية مصادقة الوجه."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ألغى المستخدم \"فتح القفل بالوجه\"."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"تمّ إجراء محاولات كثيرة. أعِد المحاولة لاحقًا."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"تم إجراء عدد كبير جدًا من المحاولات. وتم إيقاف \"فتح القفل بالوجه\"."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"يتعذّر التحقق من الوجه. حاول مرة أخرى."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"لم يسبق لك إعداد \"فتح القفل بالوجه\"."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"\"فتح القفل بالوجه\" غير متوفر على هذا الجهاز."</string>
     <string name="face_name_template" msgid="7004562145809595384">"الوجه <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -709,7 +702,7 @@
     <item msgid="1103601433382158155">"فاكس العمل"</item>
     <item msgid="1735177144948329370">"فاكس المنزل"</item>
     <item msgid="603878674477207394">"جهاز نداء"</item>
-    <item msgid="1650824275177931637">"آخر"</item>
+    <item msgid="1650824275177931637">"غير ذلك"</item>
     <item msgid="9192514806975898961">"مخصص"</item>
   </string-array>
   <string-array name="emailAddressTypes">
@@ -1210,7 +1203,7 @@
     <string name="no" msgid="5141531044935541497">"إلغاء"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"تنبيه"</string>
     <string name="loading" msgid="7933681260296021180">"جارٍ التحميل…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"تشغيل"</string>
+    <string name="capital_on" msgid="1544682755514494298">"مفعّلة"</string>
     <string name="capital_off" msgid="6815870386972805832">"إيقاف"</string>
     <string name="whichApplication" msgid="4533185947064773386">"إكمال الإجراء باستخدام"</string>
     <string name="whichApplicationNamed" msgid="8260158865936942783">"‏إكمال الإجراء باستخدام %1$s"</string>
@@ -1218,8 +1211,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"فتح باستخدام"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"‏فتح باستخدام %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"فتح"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"منح إمكانية الوصول لفتح روابط <xliff:g id="HOST">%1$s</xliff:g> باستخدام"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"منح إمكانية الوصول لفتح روابط <xliff:g id="HOST">%1$s</xliff:g> باستخدام <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"فتح روابط <xliff:g id="HOST">%1$s</xliff:g> باستخدام"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"فتح الروابط باستخدام"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"فتح الروابط باستخدام <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"فتح روابط <xliff:g id="HOST">%1$s</xliff:g> باستخدام <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"منح إذن الوصول"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"تعديل باستخدام"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"‏تعديل باستخدام %1$s"</string>
@@ -1454,8 +1449,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"يمكنك إجراء إعادة ضبط على إعدادات المصنع لإيقاف وضع \"مفعِّل اختبار\"."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏السوائل والشوائب في منفذ USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏تمّ إيقاف منفذ USB تلقائيًا. انقُر لمعرفة المزيد من المعلومات."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"‏مسموح باستخدام منفذ USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"لم يَعُد الهاتف يكتشف سوائل أو شوائب."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"جارٍ الحصول على تقرير الخطأ…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"هل تريد مشاركة تقرير الخطأ؟"</string>
@@ -1548,7 +1542,7 @@
     <string name="forward_intent_to_work" msgid="621480743856004612">"أنت تستخدم هذا التطبيق في ملفك الشخصي للعمل"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"طريقة الإرسال"</string>
     <string name="sync_binding_label" msgid="3687969138375092423">"مزامنة"</string>
-    <string name="accessibility_binding_label" msgid="4148120742096474641">"إمكانية الوصول"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"سهولة الاستخدام"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"الخلفية"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"تغيير الخلفية"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"برنامج تلقّي الإشعارات الصوتية"</string>
@@ -1576,7 +1570,7 @@
     <string name="disable_tether_notification_message" msgid="2913366428516852495">"اتصل بالمشرف للحصول على التفاصيل"</string>
     <string name="back_button_label" msgid="2300470004503343439">"رجوع"</string>
     <string name="next_button_label" msgid="1080555104677992408">"التالي"</string>
-    <string name="skip_button_label" msgid="1275362299471631819">"تخطي"</string>
+    <string name="skip_button_label" msgid="1275362299471631819">"التخطي"</string>
     <string name="no_matches" msgid="8129421908915840737">"ليس هناك أي مطابقات"</string>
     <string name="find_on_page" msgid="1946799233822820384">"بحث في الصفحة"</string>
     <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
@@ -1595,7 +1589,7 @@
     <string name="find_next" msgid="5742124618942193978">"بحث عن التطابق التالي"</string>
     <string name="find_previous" msgid="2196723669388360506">"بحث عن التطابق السابق"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"طلب الموقع من <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"طلب الموقع"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"طلب الموقع الجغرافي"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"مطلوب من <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"نعم"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"لا"</string>
@@ -1684,6 +1678,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"تشغيل المتصفح؟"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"هل تريد قبول المكالمة؟"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"دومًا"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ضبط على الفتح دائمًا"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"مرة واحدة فقط"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"الإعدادات"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"‏لا يدعم %1$s الملفات الشخصية للعمل"</string>
@@ -1713,8 +1708,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"المركب #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"‏<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>، <xliff:g id="DPI">%4$d</xliff:g> نقطة لكل بوصة"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"آمن"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‏سيتم حظر بدء نشاط الخلفية هذا من <xliff:g id="PACKAGENAME">%1$s</xliff:g> في إصدارات Q القادمة. اطّلع على g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‏تم حظر بدء نشاط الخلفية من <xliff:g id="PACKAGENAME">%1$s</xliff:g>. اطّلع على g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"نسيت النقش"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"النقش غير صحيح"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"كلمة مرور خاطئة"</string>
@@ -1763,8 +1756,8 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"إزالة"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"هل تريد رفع مستوى الصوت فوق المستوى الموصى به؟\n\nقد يضر سماع صوت عالٍ لفترات طويلة بسمعك."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"هل تريد استخدام اختصار إمكانية الوصول؟"</string>
-    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"عند تشغيل الاختصار، يؤدي الضغط على زرّي مستوى الصوت لمدة 3 ثوانٍ إلى تشغيل ميزة إمكانية الوصول.\n\n ميزة إمكانية الوصول الحالية:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n يمكنك تغيير الميزة من \"الإعدادات\" &gt; \"إمكانية الوصول\"."</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"هل تريد استخدام اختصار \"سهولة الاستخدام\"؟"</string>
+    <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"عند تشغيل الاختصار، يؤدي الضغط على زرّي مستوى الصوت لمدة 3 ثوانٍ إلى تفعيل ميزة \"سهولة الاستخدام\".\n\n ميزة \"سهولة الاستخدام\" الحالية:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n يمكنك تغيير الميزة من \"الإعدادات\" &gt; \"سهولة الاستخدام\"."</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"إيقاف الاختصار"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"استخدام الاختصار"</string>
     <string name="color_inversion_feature_name" msgid="4231186527799958644">"عكس الألوان"</string>
@@ -1772,8 +1765,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"شغَّل اختصار إمكانية الوصول خدمة <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"أوقف اختصار إمكانية الوصول خدمة <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"اضغط مع الاستمرار على مفتاحي مستوى الصوت لمدة 3 ثوانٍ لاستخدام <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"يمكنك اختيار إحدى الميزات لاستخدامها عند النقر على زر إمكانية الوصول:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"لتغيير الميزات، يمكنك لمس زر \"إمكانية الوصول\" مع الاستمرار."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"يمكنك اختيار إحدى الخدمات لاستخدامها عند النقر على زر \"سهولة الاستخدام\":"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"يمكنك اختيار إحدى الخدمات لاستخدامها مع إيماءة \"سهولة الاستخدام\" (مرّر سريعًا إلى الأعلى من أسفل الشاشة باستخدام إصبعين):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"يمكنك اختيار إحدى الخدمات التالية لاستخدامها مع إيماءة \"سهولة الاستخدام\" (مرّر سريعًا إلى الأعلى من أسفل الشاشة باستخدام ثلاثة أصابع):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"للتبديل بين الخدمات، يمكنك النقر والاستمرار على زر \"سهولة الاستخدام\"."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"للتبديل بين الخدمات، يمكنك التمرير سريعًا من أسفل الشاشة إلى أعلاها باستخدام إصبعين مع تثبيتهما."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"للتبديل بين الخدمات، يمكنك التمرير سريعًا من أسفل الشاشة إلى أعلاها باستخدام ثلاثة أصابع مع تثبيت الأصابع."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"التكبير"</string>
     <string name="user_switched" msgid="3768006783166984410">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"جارٍ التبديل إلى <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2046,7 +2043,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"البحث عن تحديث"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"لديك رسائل جديدة"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"‏فتح تطبيق الرسائل القصيرة SMS للعرض"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"ربما تكون بعض الوظائف مُقيّدة."</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"قد تكون بعض الوظائف مُقيّدة."</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"تم قفل الملف الشخصي للعمل."</string>
     <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>
@@ -2129,7 +2126,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"تم العثور على تطبيق ضار"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"يريد تطبيق <xliff:g id="APP_0">%1$s</xliff:g> عرض شرائح تطبيق <xliff:g id="APP_2">%2$s</xliff:g>."</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"تعديل"</string>
-    <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"سيهتز الهاتف عند تلقي المكالمات والإشعارات"</string>
+    <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"سيهتز الهاتف عند تلقّي المكالمات والإشعارات"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"سيتم كتم صوت الهاتف عند تلقي المكالمات والإشعارات"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"تغييرات النظام"</string>
     <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"عدم الإزعاج"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index f971703..3660403 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ৱাই- ফাই কলিং"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ৱাই-ফাই কলিং"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN কল"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN কল"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ৱাই-ফাই"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"গাড়ী ম\'ড"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"একাউণ্টৰ স্থিতি"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"বিকাশকৰ্তাৰ বাৰ্তাসমূহ"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"বিকাশকৰ্তাৰ জৰুৰী বাৰ্তা"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"আপডেটবোৰ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"নেটৱৰ্কৰ স্থিতি"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"নেটৱৰ্ক সম্পৰ্কীয় সতৰ্কবাণী"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"মুখাৱয়বৰদ্বাৰা আনলক হার্ডৱেৰ পৰিচালনা কৰক"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"মুখমণ্ডলৰ টেম্প্লেট যোগ কৰাৰ বা মচাৰ পদ্ধতি কামত লগাবলৈ আহ্বান কৰিবলৈ এপটোক অনুমতি দিয়ে।"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"মুখাৱয়বৰদ্বাৰা আনলক হার্ডৱেৰ ব্যৱহাৰ কৰক"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণৰ বাবে এপ্‌ক মুখাৱয়বৰদ্বাৰা আনলক কৰা হাৰ্ডৱেৰ ব্যৱহাৰ কৰিবলৈ দিয়ে"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"মুখাৱয়বৰদ্বাৰা আনলক কৰা সুবিধা"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"আপোনাৰ মুখমণ্ডল পুনৰ পঞ্জীয়ণ কৰক"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"চিনাক্তকৰণৰ সুবিধাটো উন্নত কৰিবলৈ, অনুগ্ৰহ কৰি আপোনাৰ মুখমণ্ডল পুনৰ পঞ্জীয়ন কৰক"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"সঠিক মুখমণ্ডলৰ ডেটা কেপচাৰ নহ’ল। আকৌ চেষ্টা কৰক।"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ফ’নটো বাওঁফালে নিয়ক।"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ফ’নটো সোঁফালে নিয়ক।"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"আপোনাৰ ডিভাইচটোলৈ অধিক পোনে পোনে চাওক।"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"আপোনাৰ মুখমণ্ডল দেখা নাই। ফ’নটোলৈ চাওক।"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"আপোনাৰ মুখখন পোনপটীয়াকৈ ফ’নটোৰ সন্মুখত ৰাখক।"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"বেছি লৰচৰ কৰি আছে। ফ’নটো স্থিৰকৈ ধৰক।"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"আপোনাৰ মুখমণ্ডল পুনৰ পঞ্জীয়ন কৰক।"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"মুখমণ্ডল আৰু চিনাক্ত কৰিব নোৱাৰি। আকৌ চেষ্টা কৰক।"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"আপোনাৰ মূৰটো সামান্য কমকৈ ঘূৰাওক।"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"আপোনাৰ মূৰটো সামান্য কমকৈ ঘূৰাওক।"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"আপোনাৰ মুখখন ঢাকি ৰখা বস্তুবোৰ আঁতৰাওক।"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"স্ক্ৰীণৰ একেবাৰে ওপৰৰ কাষত থকা ছেন্সৰটো চাফা কৰক।"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"ক’লা বাৰডালকে ধৰি আপোনাৰ স্ক্রীণৰ ওপৰৰ অংশ চাফা কৰক"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"মুখমণ্ডল সত্যাপন কৰিব পৰা নগ’ল। হাৰ্ডৱেৰ নাই।"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"পুনৰ মুখাৱয়বৰদ্বাৰা আনলক কৰি চাওক।"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"নতুন মুখমণ্ডলৰ ডেটা জমা কৰিব পৰা নাই। প্ৰথমে পুৰণি এখন মচক।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"মুখমণ্ডলৰ প্ৰক্ৰিয়া বাতিল কৰা হ’ল।"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ব্যৱহাৰকাৰীয়ে মুখাৱয়বৰদ্বাৰা আনলক কৰাটো বাতিল কৰিছে।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"অত্যধিক ভুল প্ৰয়াস। কিছুসময়ৰ পাছত আকৌ চেষ্টা কৰক।"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"অতি বেছি প্ৰয়াস। মুখাৱয়বৰদ্বাৰা আনলক কৰাটো অক্ষম কৰা হৈছে।"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"মুখমণ্ডল সত্যাপন কৰিব পৰা নগ’ল। আকৌ চেষ্টা কৰক।"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"আপুনি মুখাৱয়বৰদ্বাৰা আনলক কৰাটো ছেট আপ কৰা নাই।"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"এই ডিভাইচটোত মুখাৱয়বৰদ্বাৰা আনলক কৰা সুবিধাটো নচলে।"</string>
     <string name="face_name_template" msgid="7004562145809595384">"মুখমণ্ডল <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"আনলক ক্ষেত্ৰ বিস্তাৰ কৰক।"</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"শ্লাইডৰদ্বাৰা আনলক।"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"আৰ্হিৰদ্বাৰা আনলক।"</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"গৰাকীৰ মুখাৱয়বৰদ্বাৰা আনলক।"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"মুখাৱয়বৰদ্বাৰা আনলক।"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"পিনৰদ্বাৰা আনলক।"</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"ছিম পিন আনলক।"</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"ছিম পিইউকে আনলক।"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"ইয়াৰ জৰিয়তে খোলক"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$sৰ জৰিয়তে খোলক"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"খোলক"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ইয়াৰ দ্বাৰা <xliff:g id="HOST">%1$s</xliff:g> লিংক খুলিবলৈ এক্সেছ দিয়ক"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g>ৰ দ্বাৰা <xliff:g id="HOST">%1$s</xliff:g> লিংক খুলিবলৈ এক্সেছ দিয়ক"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> লিংকসমূহ ইয়াৰ জৰিয়তে খোলক"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"লিংকসমূহ ইয়াৰ জৰিয়তে খোলক"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"লিংকসমূহ <xliff:g id="APPLICATION">%1$s</xliff:g>ৰ জৰিয়তে খোলক"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> লিংকসমূহ <xliff:g id="APPLICATION">%2$s</xliff:g>ৰ জৰিয়তে খোলক"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"এক্সেছ দিয়ক"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ইয়াৰ দ্বাৰা সম্পাদনা কৰক"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$sৰদ্বাৰা সম্পাদনা কৰক"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"টেষ্ট হাৰনেছ ম’ড অক্ষম কৰিবলৈ ফেক্টৰী ৰিছেট কৰক।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএছবি প’ৰ্টত তৰল বা ধূলি-মাকতি আছে"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএছবি প’ৰ্ট স্বয়ংক্ৰিয়ভাৱে অক্ষম কৰা হয়। অধিক জানিবৰ বাবে টিপক।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ইউএছবি প’ৰ্ট ব্যৱহাৰ কৰাত সমস্যা নাই"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ফ’নটোৱে তৰল বা ধূলি-মাকতি আৰু চিনাক্ত নকৰে।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"বাগ সম্পর্কীয় অভিযোগ গ্ৰহণ কৰি থকা হৈছে…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"বাগ সম্পর্কীয় অভিযোগ শ্বেয়াৰ কৰিবনে?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ব্ৰাউজাৰ লঞ্চ কৰিবনে?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"কল স্বীকাৰ কৰিবনে?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"সদায়"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"সদায় খোলক-লৈ ছেট কৰক"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"মাত্ৰ এবাৰ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ছেটিংসমূহ"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$sএ কৰ্মস্থানৰ প্ৰ\'ফাইল সমৰ্থন নকৰে।"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"অ\'ভাৰলে\' #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", সুৰক্ষিত"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>ৰ পৰা নেপথ্যত আৰম্ভ হোৱা এই কাৰ্যকলাপটো ভৱিষ্যতে Q বিল্ডত অৱৰোধ কৰা হ’ব। g.co/dev/bgblock চাওক।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>ৰ পৰা নেপথ্যত আৰম্ভ হোৱা কাৰ্যকলাপ অৱৰোধ কৰা হৈছে। g.co/dev/bgblock চাওক।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"আৰ্হি পাহৰিলেনে"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ভুল আৰ্হি"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ভুল পাছৱৰ্ড"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাটটোৱে <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ক অন কৰিছে"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"দিব্যাংগসকলৰ সুবিধাৰ শ্বৰ্টকাটটোৱে <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ক অফ কৰিছে"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যৱহাৰ কৰিবলৈ দুয়োটা ভলিউম বুটাম তিনি ছেকেণ্ডৰ বাবে হেঁচি ৰাখক"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"আপুনি দিব্যাংগসকলৰ সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলগীয়া কোনো সুবিধা বাছক:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"সুবিধাসমূহ সলনি কৰিবলৈ দিব্যাংগসকলৰ সুবিধাৰ বুটামটো স্পৰ্শ কৰি থাকক।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"আপুনি সাধ্য সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলৈ এটা সেৱা বাছনি কৰক:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"সাধ্য সুবিধা ভংগিমাৰ সৈতে ব্যৱহাৰ কৰিবলৈ এটা সেৱা বাছনি কৰক (দুটা আঙুলিৰে স্ক্রীণখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"সাধ্য সুবিধা ভংগিমাৰ সৈতে ব্যৱহাৰ কৰিবলৈ এটা সেৱা বাছনি কৰক (তিনিটা আঙুলিৰে স্ক্রীণখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"সেৱাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ সাধ্য সুবিধাৰ বুটামটো স্পৰ্শ কৰি ধৰি ৰাখক।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"সেৱাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ দুটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"সেৱাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ তিনিটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"বিবৰ্ধন"</string>
     <string name="user_switched" msgid="3768006783166984410">"বৰ্তমানৰ ব্যৱহাৰকাৰী <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>লৈ সলনি কৰি থকা হৈছে…"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 6eac6fe..e2b3998 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Zəngi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> WiFi Zəngi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Zəngi"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Zəngi"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Avtomobil rejimi"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Hesab statusu"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Developer mesajı"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mühüm developer mesajları"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Güncəlləmələr"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Şəbəkə statusu"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Şəbəkə siqnalları"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Barmaq izi ikonası"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"üz kilidi avadanlığını idarə edin"</string>
     <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>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"üz kilidi avadanlığından istifadə edin"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"İdentifikasiya üçün tətbiqin üz kilidi avadanlığından istifadə etməsinə icazə verir"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Üz kilidi"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Üzünüzü yenidən qeydiyyatdan keçirin"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Tanınmanı təkmilləşdirmək üçün üzünüzü yenidən qeydiyyatdan keçirin"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Dəqiq üz datası əldə edilmədi. Yenidən cəhd edin."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Telefonu sola hərəkət etdirin."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Telefonu sağa hərəkət etdirin."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Birbaşa cihaza baxın."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Üzünüz görünmür. Telefona baxın."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Üzünüzü telefonun qarşısında sabit saxlayın."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Cihaz stabil deyil. Telefonu tərpətməyin."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Üzünüzü yenidən qeydiyyatdan keçirin."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Üzü artıq tanımaq olmur. Yenidən cəhd edin."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Başınızı bir az döndərin."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Başınızı bir az döndərin."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Üzünüzü gizlədən maneələri kənarlaşdırın."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Ekranın yuxarı küncündəki sensoru təmizləyin."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Qara panel daxil olmaqla, ekranın yuxarısını təmizləyin"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Üz doğrulanmadı. Avadanlıq əlçatan deyil."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Üz kilidini yenidən sınayın."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Yeni üz datası saxlanmadı. Əvvəlcə köhnə olanı silin."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Üz əməliyyatı ləğv edildi."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"İstifadəçi üz kilidini ləğv edib."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Həddindən çox cəhd. Sonraya saxlayın."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Həddindən çox cəhd. Üz kilidi deaktiv edildi."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Üz doğrulanmadı. Yenidən cəhd edin."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Üz kilidi quraşdırmamısınız."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Üz kilidi bu cihazda dəstəklənmir."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Üz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Bununla açın"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ilə açın"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Açın"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Bu tətbiqlə <xliff:g id="HOST">%1$s</xliff:g> linklərini açmağa icazə verin:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> ilə <xliff:g id="HOST">%1$s</xliff:g> linklərini açmağa icazə verin"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> linklərini belə açın:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Linkləri belə açın:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Linkləri <xliff:g id="APPLICATION">%1$s</xliff:g> ilə açın"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> linklərini <xliff:g id="APPLICATION">%2$s</xliff:g> ilə açın"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"İcazə verin"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Bununla düzəliş edin:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ilə düzəliş edin"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Test Rejimini deaktiv etmək üçün fabrika ayarlarına sıfırlayın."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB portundan istifadə etmək üçün OK"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon artıq maye və ya nasazlığı aşkarlamayacaq."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Baq hesabatı verilir..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Baq hesabatı paylaşılsın?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Brauzer işə salınsın?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Zəngi qəbul edək?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Həmişə"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"\"Həmişə açıq\" olaraq ayarlayın"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Sadəcə bir dəfə"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Ayarlar"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s iş profilini dəstəkləmir"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Örtük #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", təhlükəsiz"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ünvanından olan bu arxa fon fəaliyyəti növbəti Q versiyalarında blok ediləcək. G.co/dev/bgblock ünvanına baxın."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ünvanından olan arxa fon fəaliyyəti blok edildi. G.co/dev/bgblock ünvanına baxın."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Şablonu unutmuşam"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Model"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifrə"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Əlçatımlıq Qısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini aktiv etdi"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Əlçatımlıq Qısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini deaktiv etdi"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> istifadə etmək üçün hər iki səs düyməsini üç saniyə basıb saxlayın"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Əlçatımlılıq düyməsinə kliklədikdə istifadə etmək üçün funksiya seçin:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funksiyaları dəyişmək üçün Əlçatımlılıq düyməsinə basıb saxlayın."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Əlçatımlılıq düyməsinə toxunduqda istifadə etmək üçün xidmət seçin:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Əlçatımlılıq jestləri (iki barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə etmək üçün xidmət seçin:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Əlçatımlılıq jestləri (üç barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə etmək üçün xidmət seçin:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Xidmətlər arasında keçid etmək üçün əlçatımlılıq düyməsinə basın &amp; saxlayın."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Xidmətlər arasında keçid etmək üçün ekranı iki barmağınızla yuxarı sürüşdürüb saxlayın."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Xidmətlər arasında keçid etmək üçün ekranı üç barmağınızla yuxarı sürüşdürüb saxlayın."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Böyütmə"</string>
     <string name="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> adına keçirilir…"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 8f138d4..821b730 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> pozivanje preko Wi-Fi-ja"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> – pozivanje preko Wi-Fi-ja"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -259,6 +260,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Režim rada u automobilu"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Status naloga"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Poruke za programere"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Važne poruke programera"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status mreže"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Obaveštenja u vezi sa mrežom"</string>
@@ -268,7 +270,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Obaveštenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Režim demonstracije za maloprodajne objekte"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikacija je pokrenuta"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aktivna aplikacija"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacije koje troše bateriju"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi bateriju"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) koriste bateriju"</string>
@@ -552,15 +554,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona otiska prsta"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"upravljanje hardv. za otključavanje licem"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Dozvoljava da aplikacija aktivira metode za dodavanje i brisanje šablona lica radi korišćenja."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"korišćenje hardvera za otključavanje licem"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Dozvoljava da aplikacija koristi hardver za otključavanje licem radi potvrde identiteta"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Otključavanje licem"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Ponovo registrujte lice"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Da biste poboljšali prepoznavanje, ponovo registrujte lice"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Snimanje lica nije uspelo. Probajte ponovo."</string>
@@ -573,7 +571,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Pomerite telefon ulevo."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Pomerite telefon udesno."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Gledajte pravo u uređaj."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Ne vidi se lice. Gledajte u telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Postavite lice direktno ispred telefona"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Mnogo se pomerate. Držite telefon mirno."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Ponovo registrujte lice."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Više ne može da se prepozna lice. Probajte ponovo."</string>
@@ -582,24 +580,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Malo manje pomerite glavu."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Malo manje pomerite glavu."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Uklonite sve što vam zaklanja lice."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Očistite senzor na gornjoj ivici ekrana."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Očistite gornji deo ekrana, uključujući crnu traku"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Provera lica nije uspela. Hardver nije dostupan."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Probajte ponovo otključavanje licem."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Novi podaci o licu nisu sačuvani. Prvo izbrišete prethodne."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Obrada lica je otkazana."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Korisnik je otkazao otključavanje licem"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Probajte ponovo kasnije."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Previše pokušaja. Otključavanje licem je onemogućeno."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Provera lica nije uspela. Probajte ponovo."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Niste podesili otključavanje licem"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Otključavanje licem nije podržano na ovom uređaju"</string>
     <string name="face_name_template" msgid="7004562145809595384">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1158,8 +1151,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Otvorite pomoću"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otvorite pomoću aplikacije %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Otvori"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Dozvolite da se linkovi <xliff:g id="HOST">%1$s</xliff:g> otvaraju pomoću"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Dozvolite da <xliff:g id="APPLICATION">%2$s</xliff:g> otvara linikove <xliff:g id="HOST">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Otvarajte <xliff:g id="HOST">%1$s</xliff:g> linkove pomoću"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Otvaratej linkove pomoću"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Otvarajte linkove pomoću aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Otvarajte <xliff:g id="HOST">%1$s</xliff:g> linkove pomoću aplikacije <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Dozvoli pristup"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Izmenite pomoću"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Izmenite pomoću aplikacije %1$s"</string>
@@ -1388,8 +1383,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Korišćenje USB porta je dozvoljeno"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon više ne otkriva tečnost ili nečistoću."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izveštaj o grešci se generiše…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li da podelite izveštaj o grešci?"</string>
@@ -1615,6 +1609,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Želite li da pokrenete pregledač?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Želite li da prihvatite poziv?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Uvek"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Podesi na „uvek otvaraj“"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo jednom"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Podešavanja"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ne podržava poslovni profil"</string>
@@ -1644,8 +1639,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Postavljeni element br. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>×<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", bezbedno"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ovo pokretanje aktivnosti u pozadini sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> biće blokirano u budućim Q verzijama. Pogledajte g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Pokretanje aktivnosti u pozadini sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> je blokirano. Pogledajte g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravljeni šablon"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan šablon"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna lozinka"</string>
@@ -1700,8 +1693,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izaberite funkciju koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pritisnite i zadržite dugme za pristupačnost da biste menjali funkcije."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Odaberite uslugu koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću dva prsta prevucite nagore od dna ekrana):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Odaberite uslugu koja će se koristiti pomoću pokreta za pristupačnost (pomoću tri prsta prevucite nagore od dna ekrana):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Da biste prelazili sa jedne usluge na drugu, dodirnite i zadržite dugme za pristupačnost."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Da biste prelazili sa jedne usluge na drugu, prevucite nagore pomoću dva prsta i zadržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Da biste prelazili sa jedne usluge na drugu, prevucite nagore pomoću tri prsta i zadržite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index e3a5502..d573202 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-тэлефанія ад <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Wi-Fi-тэлефанія ад аператара \"<xliff:g id="SPN">%s</xliff:g>\""</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Выклік праз WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Выклік праз WLAN ад <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ад <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Рэжым \"У машыне\""</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Стан уліковага запісу"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Паведамленні для распрацоўшчыкаў"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Важныя паведамленні распрацоўшчыка"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Абнаўленні"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Стан сеткі"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Абвесткі сеткі"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Значок адбіткаў пальцаў"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"кіраваць апаратным забеспячэннем для распазнавання твару"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Праграма зможа дадаваць і выдаляць шаблоны твару."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"выкарыстоўваць апаратнае забеспячэнне для распазнавання твару"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Для аўтэнтыфікацыі праграма зможа ўжываць апаратнае забеспячэнне для распазнавання твару"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Распазнаванне твару"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Паўтарыце рэгістрацыю твару"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Каб палепшыць распазнавальнасць, яшчэ раз выканайце рэгістрацыю твару"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Не атрымалася распазнаць твар. Паўтарыце спробу."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Перамясціце тэлефон улева."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Перамясціце тэлефон управа."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Глядзіце прама на экран прылады."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Не відаць твару. Глядзіце на тэлефон."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Трымайце тэлефон прама перад тварам."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Трымайце прыладу нерухома. Трымайце тэлефон роўна."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Паўтарыце рэгістрацыю твару."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Не ўдаецца распазнаць твар. Паўтарыце спробу."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Галава не ў цэнтры."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Вы занадта моцна павярнулі галаву."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Прыміце ўсё, што закрывае ваш твар."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Ачысціце датчык уверсе экрана."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Ачысціце ад бруду верхнюю частку экрана, у тым ліку чорную панэль"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Твар не спраўджаны. Абсталяванне недаступнае."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Выканайце распазнаванне твару паўторна."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Новыя даныя пра твар не захаваны. Спачатку выдаліце старыя."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Распазнаванне твару скасавана."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Распазнаванне твару скасавана карыстальнікам."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Занадта шмат спроб. Паўтарыце спробу пазней."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Занадта шмат спроб. Распазнаванне твару выключана."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Не ўдалося спраўдзіць твар. Паўтарыце спробу."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Вы не наладзілі распазнаванне твару."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"На гэтай прыладзе распазнаванне твару не падтрымліваецца."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Твар <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -901,7 +894,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Разгарнуць вобласць разблакіроўкі."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Разблакiроўка слайда."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Узор разблакiроўкі."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Фэйскантроль"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Распазнаванне твару"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-код разблакiроўкі."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"Разблакіроўка SIM-карты з дапамогай PIN-кода."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"Разблакіроўка SIM-карты з дапамогай PUK-кода."</string>
@@ -959,7 +952,7 @@
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"змяніць дазволы геапазіцыянавання для браўзэра"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Дазваляе прыкладанням змяняць дазволы геалакацыі браўзэра. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб дазваляць адпраўку інфармацыі аб месцазнаходжанні выпадковым вэб-сайтам."</string>
     <string name="save_password_message" msgid="767344687139195790">"Вы хочаце, каб браўзэр запомніў гэты пароль?"</string>
-    <string name="save_password_notnow" msgid="6389675316706699758">"Не цяпер"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Не зараз"</string>
     <string name="save_password_remember" msgid="6491879678996749466">"Запомніць"</string>
     <string name="save_password_never" msgid="8274330296785855105">"Ніколі"</string>
     <string name="open_permission_deny" msgid="7374036708316629800">"У вас няма дазволу на адкрыццё гэтай старонкі."</string>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Адкрыць з дапамогай"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Адкрыць з дапамогай %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Адкрыць"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Адкрываць спасылкі на сэрвіс <xliff:g id="HOST">%1$s</xliff:g> з дапамогай"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Адкрываць спасылкі на сэрвіс <xliff:g id="HOST">%1$s</xliff:g> з дапамогай праграмы \"<xliff:g id="APPLICATION">%2$s</xliff:g>\""</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Адкрываць спасылкі <xliff:g id="HOST">%1$s</xliff:g> з дапамогай"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Адкрываць спасылкі з дапамогай"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Адкрываць спасылкі з дапамогай праграмы \"<xliff:g id="APPLICATION">%1$s</xliff:g>\""</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Адкрываць спасылкі <xliff:g id="HOST">%1$s</xliff:g>з дапамогай праграмы \"<xliff:g id="APPLICATION">%2$s</xliff:g>\""</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Даць доступ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Рэдагаваць з дапамогай"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Рэдагаваць з дапамогай %1$s"</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Каб выключыць тэставы рэжым, скіньце налады да заводскіх значэнняў."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Вадкасць або смецце ў порце USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Порт USB аўтаматычна адключаны. Каб даведацца больш, націсніце тут."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Порт USB можна выкарыстоўваць"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Тэлефон выявіў, што вадкасці і смецця больш няма."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Стварэнне справаздачы пра памылку…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Падзяліцца справаздачай пра памылку?"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запусцiць браўзер?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Прыняць выклік?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Заўсёды"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Прызначыць стандартна для адкрыцця"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Толькі адзін раз"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Налады"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s не падтрымлівае працоўны профіль"</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Оверлей # <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> кр. на цалю"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", бяспечны"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Запуск дзеянняў у фонавым рэжыме з пакета \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" будзе заблакіраваны ў будучых Q-зборках. Глядзіце g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Запуск дзеянняў у фонавым рэжыме з пакета \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" заблакіраваны. Глядзіце g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забылі ключ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Няправільны ўзор"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Няправiльны пароль"</string>
@@ -1724,8 +1717,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў уключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> быў адключаны з дапамогай камбінацыі хуткага доступу для спецыяльных магчымасцей"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Каб карыстацца сэрвісам \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце і ўтрымлівайце на працягу трох секунд абедзве клавішы гучнасці"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Выберыце функцыю для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Каб змяняць функцыі, краніце і ўтрымлівайце кнопку \"Спецыяльныя магчымасці\"."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Выберыце службу для выкарыстання пры націску кнопкі \"Спецыяльныя магчымасці\":"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"З дапамогай жэста спецыяльных магчымасцей (правесці двума пальцамі па экране знізу ўверх) выберыце службу для выкарыстання:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"З дапамогай жэста спецыяльных магчымасцей (правесці трыма пальцамі па экране знізу ўверх) выберыце службу для выкарыстання:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Каб пераключыцца на другую службу, націсніце і ўтрымлівайце кнопку спецыяльных магчымасцей."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Каб пераключыцца на другую службу, правядзіце ўверх двума пальцамі, утрымліваючы іх на экране."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Каб пераключыцца на іншую службу, правядзіце ўверх трыма пальцамі, утрымліваючы іх на экране."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Павелічэнне"</string>
     <string name="user_switched" msgid="3768006783166984410">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Пераход да <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1978,7 +1975,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Праверыць на наяўнасць абнаўленняў"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"У вас ёсць новыя паведамленні"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Праглядзець праз праграму для SMS"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Частка функц. можа быць абмеж."</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Функцыі могуць быць абмежаваныя"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Рабочы профіль заблакіраваны"</string>
     <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>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 0e85554..e073b7d 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Обаждания през Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Обаждания през Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Обаждане през WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Обаждане през WLAN от <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Моторежим"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Състояние на профила"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Съобщения за програмистите"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Важни съобщения за програмисти"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Актуализации"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Състояние на мрежата"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Сигнали за мрежата"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Икона за отпечатък"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"управление на хардуера за отключване с лице"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Разрешава на прил. да извиква методи за добавяне и изтриване на лицеви шаблони за ползване"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"използване на хардуера за отключване с лице"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Разрешава на приложението да използва хардуера за отключване с лице с цел удостоверяване"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Отключване с лице"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Регистрирайте отново лицето си"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"С цел подобряване на разпознаването регистрирайте отново лицето си"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Лицето не бе заснето точно. Опитайте отново."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Преместете телефона наляво."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Преместете телефона надясно."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Моля, гледайте точно към устройството си."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Лицето ви не се вижда. Погледнете към телефона."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Позиционирайте лицето си директно пред телефона."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Твърде много движение. Дръжте телефона неподвижно."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Моля, регистрирайте лицето си отново."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Лицето не бе разпознато. Опитайте отново."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Не завъртайте главата си толкова много."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Не завъртайте главата си толкова много."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Премахнете всичко, което закрива лицето ви."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Изчистете сензора в горния край на екрана."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Почистете горната част на екрана си, включително черната лента"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Лицето не може да се потвърди. Хардуерът не е налице."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Опитайте отново да отключите с лице."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Не може да се запази ново лице. Първо изтрийте старо."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Операцията с лице е анулирана."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Отключването с лице е анулирано от потребителя."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Твърде много опити. Опитайте отново по-късно."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Твърде много опити. Отключването с лице е деактивирано."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Лицето не може да се потвърди. Опитайте отново."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Не сте настроили отключването с лице."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Отключването с лице не се поддържа на това устройство."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Отваряне чрез"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Отваряне чрез %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Отваряне"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Предоставяне на достъп за отваряне на връзките от <xliff:g id="HOST">%1$s</xliff:g> с(ъс)"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Предоставяне на достъп за отваряне на връзките от <xliff:g id="HOST">%1$s</xliff:g> с(ъс) <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Отваряне на връзките от <xliff:g id="HOST">%1$s</xliff:g> посредством"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Отваряне на връзките посредством"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Отваряне на връзките посредством <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Отваряне на връзките от <xliff:g id="HOST">%1$s</xliff:g> посредством <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Даване на достъп"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Редактиране чрез"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Редактиране чрез %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Възстановете фабричните настройки, за да деактивирате режима за тестова среда."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или замърсяване в USB порта"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портът е деактивиран автоматично. Докоснете, за да научите повече."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Можете да използвате USB порта"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефонът вече не открива течности или замърсяване."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Сигналът за програмна грешка се извлича…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели ли сигналът за програмна грешка?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Да се стартира ли браузърът?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Да се приеме ли обаждането?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Винаги"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Задаване винаги да се отваря"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Само веднъж"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Настройки"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s не поддържа служебен потребителски профил"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Наслагване №<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"„<xliff:g id="NAME">%1$s</xliff:g>“: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", защитено"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Стартирането на активност на заден план от <xliff:g id="PACKAGENAME">%1$s</xliff:g> ще бъде блокирано в бъдещите компилации под Q. Разгледайте g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Стартирането на активност на заден план от <xliff:g id="PACKAGENAME">%1$s</xliff:g> е блокирано. Разгледайте g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забравена фигура"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Грешна фигура"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Грешна парола"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Прекият път за достъпност включи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Прекият път за достъпност изключи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"За да използвате <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натиснете двата бутона за силата на звука и ги задръжте за 3 секунди"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изберете функция, която да използвате, когато докоснете бутона за достъпност:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"За да промените функции, докоснете и задръжте бутона за достъпност."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Изберете коя услуга да се използва при докосване на бутона за достъпност:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Изберете коя услуга да се използва с жеста за достъпност (прекарване на два пръста нагоре от долната част на екрана):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Изберете коя услуга да се използва с жеста за достъпност (прекарване на три пръста нагоре от долната част на екрана):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"За превключване между услугите докоснете и задръжте бутона за достъпност."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"За превключване между услугите прекарайте два пръста нагоре и задръжте."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"За превключване между услугите прекарайте три пръста нагоре и задръжте."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ниво на мащаба"</string>
     <string name="user_switched" msgid="3768006783166984410">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Превключва се към <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 8f1cf57..368ff90 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ওয়াই-ফাই কলিং"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi‑Fi কলিং"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN কল"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN কল"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ওয়াই-ফাই"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"গাড়ি মোড"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"অ্যাকাউন্টের স্থিতি"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ডেভেলপার সম্পর্কিত মেসেজ"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"ডেভেলপার সম্পর্কিত গুরুত্বপূর্ণ মেসেজ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"আপডেটগুলি"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"নেটওয়ার্কের স্থিতি"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"নেটওয়ার্ক সক্রান্ত অ্যালার্ট"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"আঙ্গুলের ছাপ আইকন"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"মুখের সাহায্যে আনলক করার হার্ডওয়্যার ম্যানেজ করা"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ব্যবহার করার জন্য ফেস টেম্পলেট যোগ করা এবং মোছার পদ্ধতি গ্রহণ করতে অ্যাপটিকে অনুমতি দেয়৷"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"মুখের সাহায্যে আনলক করার হার্ডওয়্যার ব্যবহার করা"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"অ্যাপকে যাচাইকরণের জন্য মুখের সাহায্যে আনলক করার হার্ডওয়্যার ব্যবহার করতে দেয়"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"মুখের সাহায্যে আনলক"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"আপনার ফেস আবার এনরোল করুন"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"শনাক্তকরণের উন্নতি করতে আপনার ফেস আবার এনরোল করুন"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"মুখের সঠিক ডেটা পাওয়া যায়নি। আবার চেষ্টা করুন।"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ফোনটি বাঁদিকে সরান।"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ফোনটি ডানদিকে সরান।"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"সরাসরি ডিভাইসের দিকে তাকান।"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"আপনার মুখ দেখা যাচ্ছে না। ফোনের দিকে তাকান।"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"আপনার মুখ সরাসরি ফোনের সামনে রাখুন।"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"খুব বেশি নড়ছে। ফোনটি যাতে না কাঁপে সেইভাবে ধরুন।"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"আপনার মুখের ছবি আবার নথিভুক্ত করুন।"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"আর মুখ চিনতে পারবেন না। আবার চেষ্টা করুন।"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"আপনার মাথাটি নিচের দিকে সামান্য নামান।"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"আপনার মাথাটি সামান্য ঘোরান।"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"আপনার ফেসকে আড়াল করে এমন সব কিছু সরিয়ে দিন।"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"স্ক্রিনের উপরের প্রান্তের সেন্সর মুছুন।"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"ব্ল্যাক বার সহ আপনার স্ক্রিনের উপরের অংশ মুছে ফেলুন"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"ফেস যাচাই করা যায়নি। হার্ডওয়্যার উপলভ্য নেই।"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"আবার মুখের সাহায্যে আনলক করার চেষ্টা করুন।"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"নতুন ফেস ডেটা স্টোর করা যায়নি। প্রথমে পুরনোটি মুছে ফেলুন।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ফেস অপারেশন বাতিল করা হয়েছে৷"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ব্যবহারকারী মুখের সাহায্যে আনলক বাতিল করে দিয়েছেন।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"অনেকবার চেষ্টা করা হয়েছে। পরে আবার চেষ্টা করুন।"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"অনেকবার চেষ্টা করেছেন। মুখের সাহায্যে আনলক করার সুবিধা বন্ধ করা হয়েছে।"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"আপনার মুখ যাচাই করা যাচ্ছে না। আবার চেষ্টা করুন।"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"এখনও মুখের সাহায্যে আনলক করার সুবিধা সেট-আপ করেননি।"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"এই ডিভাইসে মুখের সাহায্যে আনলক করার সুবিধাটি কাজ করে না।"</string>
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> ফেস"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"আনলক এলাকা প্রসারিত করুন৷"</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"স্লাইড দিয়ে আনলক৷"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"প্যাটার্ন দিয়ে আনলক৷"</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"মুখের সাহায্যে আনলক করুন৷"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"মুখের সাহায্যে আনলক৷"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"পিন দিয়ে আনলক৷"</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"সিম পিন আনলক।"</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"সিম পিইউকে আনলক।"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"এর মাধ্যমে খুলুন"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s দিয়ে খুলুন"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"খুলুন"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ব্যবহার করে <xliff:g id="HOST">%1$s</xliff:g> লিঙ্ক খুলতে অ্যাক্সেস দিন"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> ব্যবহার করে <xliff:g id="HOST">%1$s</xliff:g> লিঙ্ক খুলতে অ্যাক্সেস দিন"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"এই ব্রাউজারে <xliff:g id="HOST">%1$s</xliff:g> লিঙ্কটি খুলুন"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"এই ব্রাউজারে লিঙ্কটি খুলুন"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g>-এ লিঙ্ক খুলুন"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g>-এ <xliff:g id="HOST">%1$s</xliff:g> লিঙ্কটি খুলুন"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"অ্যাক্সেস দিন"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"এর মাধ্যমে সম্পাদনা করুন"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s দিয়ে সম্পাদনা করুন"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"টেস্ট হারনেস মোড বন্ধ করতে ফ্যাক্টরি রিসেট করুন।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ইউএসবি পোর্টে তরল পদার্থ অথবা ধুলো কণা"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ইউএসবি পোর্ট নিজে থেকে বন্ধ করা হবে। আরও জানতে ট্যাপ করুন।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ইউএসবি পোর্ট ব্যবহার করা যেতে পারে"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ফোন আর তরল পদার্থ এবং ধুলো কণা শনাক্ত করবে না।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ত্রুটির প্রতিবেদন নেওয়া হচ্ছে..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ত্রুটির প্রতিবেদন শেয়ার করবেন?"</string>
@@ -1504,7 +1498,7 @@
     <string name="find_next" msgid="5742124618942193978">"পরবর্তীটি খুঁজুন"</string>
     <string name="find_previous" msgid="2196723669388360506">"পূর্ববর্তীটি খুঁজুন"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> এর থেকে অবস্থানের অনুরোধ"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"অবস্থানের অনুরোধ"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"লোকেশন জানার অনুরোধ"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) এর দ্বারা অনুরোধকৃত"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"হ্যাঁ"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"না"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ব্রাউজার লঞ্চ করতে চান?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"কল গ্রহণ করবেন?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"সবসময়"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"\'সবসময় খোলা থাকবে\' হিসেবে সেট করুন"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"শুধু একবার"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"সেটিংস"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s কর্মস্থলের প্রোফাইল সমর্থন করে না।"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"আচ্ছাদন #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", নিরাপদ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-এর ব্যাকগ্রাউন্ড অ্যাক্টিভিটি ভবিষ্যতে Q বিল্ড ভার্সনে ব্লক করা হবে। g.co/dev/bgblock লিঙ্ক দেখুন।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-এর ব্যাকগ্রাউন্ড অ্যাক্টিভিটি ব্লক করা হয়েছে। g.co/dev/bgblock লিঙ্ক দেখুন।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"প্যাটার্ন ভুলে গেছেন"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ভুল প্যাটার্ন"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ভুল পাসওয়ার্ড"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"অ্যাক্সেসযোগ্যতা শর্টকাট <xliff:g id="SERVICE_NAME">%1$s</xliff:g> কে চালু করেছে"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"অ্যাক্সেসযোগ্যতা শর্টকাট <xliff:g id="SERVICE_NAME">%1$s</xliff:g> কে বন্ধ করেছে"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যবহার করতে ভলিউম কী বোতাম ৩ সেকেন্ডের জন্য চেপে ধরে রাখুন"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"অ্যাক্সেসযোগ্যতা বোতামের সাহায্যে যে বৈশিষ্ট্যটি নিয়ন্ত্রণ করতে চান, সেটি বেছে নিন:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"বৈশিষ্ট্যগুলি পরিবর্তন করতে অ্যাক্সেসযোগ্যতা বোতামটি ট্যাপ করে ধরে রাখুন।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"অ্যাক্সেসিবিলিটি বোতামে ট্যাপ করে ব্যবহার করার জন্য এই পরিষেবাটি বেছে নিন:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"অ্যাক্সেসিবিলিটি জেসচারের সাহায্যে ব্যবহার করার জন্য এই পরিষেবা বেছে নিন (দুটি আঙুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করুন):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"অ্যাক্সেসিবিলিটি জেসচারের সাহায্যে ব্যবহার করার জন্য এই পরিষেবা বেছে নিন (তিনটি আঙ্গুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করুন):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"একটি পরিষেবা থেকে অন্য পরিষেবায় পাল্টাতে অ্যাক্সেসিবিলিটি বোতামটি টাচ করে ধরে রাখুন।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"একটি পরিষেবা থেকে অন্য পরিষেবায় পাল্টাতে, দুটি আঙ্গুল দিয়ে উপরের দিকে সোয়াইপ করে ধরে রাখুন।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"একটি পরিষেবা থেকে অন্য পরিষেবায় পাল্টাতে, তিনটি আঙ্গুল দিয়ে উপরের দিকে সোয়াইপ করে ধরে রাখুন।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"বড় করে দেখা"</string>
     <string name="user_switched" msgid="3768006783166984410">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> নামের ব্যবহারকারীতে যাচ্ছে…"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 5ef243c..ce852b6 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -127,11 +127,12 @@
     <item msgid="3910386316304772394">"Da biste pozivali i slali poruke koristeći WiFi mrežu, prvo zatražite od operatera da postavi tu uslugu. Zatim ponovo uključite pozivanje putem WiFi-ja u Postavkama. (Kôd greške: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
-    <item msgid="7372514042696663278">"Došlo je do problema prilikom registracije pozivanja putem WiFi mreže kod vašeg operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
+    <item msgid="7372514042696663278">"Došlo je do problema prilikom registracije pozivanja putem WiFi mreže kod vašeg mobilnog operatera: <xliff:g id="CODE">%1$s</xliff:g>"</item>
   </string-array>
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Pozivanje putem WiFi-ja"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Pozivanje putem WiFi-ja"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN poziv"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
@@ -258,7 +259,8 @@
     <string name="notification_channel_security" msgid="7345516133431326347">"Sigurnost"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Način rada u automobilu"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Status računa"</string>
-    <string name="notification_channel_developer" msgid="7579606426860206060">"Poruke programera"</string>
+    <string name="notification_channel_developer" msgid="7579606426860206060">"Poruke za programere"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Važne poruke za programere"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status mreže"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Mrežna upozorenja"</string>
@@ -268,7 +270,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Prodajna demonstracija"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Pokrenuta je aplikacija"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Pokrenuta aplikacija"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikacije koje troše bateriju"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> troši bateriju"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Broj aplikacija koje troše bateriju: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
@@ -320,7 +322,7 @@
     <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Stavke koje dodirnete bit će izgovorene naglas, a ekran možete istraživati koristeći pokrete."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Prati tekst koji unosite"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
-    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrolira uvećanje prikaza na ekranu"</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrolira uvećavanje prikaza na ekranu"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolira stepen uvećanja prikaza na ekranu i podešavanje položaja."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Praviti pokrete"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može dodirivati, prevlačiti, hvatati prstima i praviti druge pokrete."</string>
@@ -552,15 +554,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona za otisak prsta"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"upravljanje hardverom za otključavanje licem"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Omogućava aplikaciji korištenje metoda za dodavanje i brisanje šablona lica za upotrebu."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"korištenje hardvera za otključavanje licem"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Omogućava aplikaciji da za autentifikaciju koristi hardver za otključavanje licem"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Otključavanje licem"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Ponovo registrirajte lice"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Ponovo registrirajte lice da poboljšate prepoznavanje"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Lice nije snimljeno precizno. Pokušajte ponovo."</string>
@@ -573,7 +571,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Pomjerite telefon ulijevo."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Pomjerite telefon udesno."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Gledajte direktno u uređaj."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Ne vidi se lice. Gledajte u telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Postavite lice direktno ispred telefona"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Previše pokreta. Držite telefon mirno."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Ponovo registrirajte lice."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Nije više moguće prepoznati lice. Pokušajte opet."</string>
@@ -582,24 +580,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Malo manje zakrenite glavu."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Malo manje zakrenite glavu."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Uklonite prepreke koje blokiraju vaše lice."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Očistite senzor na gornjem rubu ekrana."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Očistite vrh ekrana, uključujući crnu traku"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Nije moguće potvrditi lice. Hardver nije dostupan."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Pokušajte ponovo s otključavanjem licem."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Nije moguće sačuvati nove podatke o licu. Prvo izbrišite stare."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Prepoznavanje lica je otkazano."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Korisnik je otkazao otključavanje licem."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Previše pokušaja. Otključavanje licem je onemogućeno."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nije moguće potvrditi lice. Pokušajte ponovo."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Niste postavili otključavanje licem."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Otključavanje licem nije podržano na ovom uređaju."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -809,7 +802,7 @@
     <string name="quick_contacts_not_available" msgid="746098007828579688">"Nije pronađena aplikacija za pregled ovog kontakta."</string>
     <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Unesite PIN"</string>
     <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Unesite PUK i novi PIN"</string>
-    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK kôd"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novi PIN"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="2644215452200037944"><font size="17">"Dodirnite za unos lozinke"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Unesite lozinku za otključavanje tipkovnice"</string>
@@ -901,7 +894,7 @@
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Otključavanje licem."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Otključavanje pinom."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"Otključavanje Pin-om za Sim."</string>
-    <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"Otključavanje Puk-om za Sim."</string>
+    <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"Otključavanje SIM-a PUK-om"</string>
     <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Otključavanje lozinkom."</string>
     <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Uzorak oblasti."</string>
     <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Oblast za pomjeranje klizača."</string>
@@ -1158,8 +1151,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Otvori koristeći"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otvori koristeći %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Otvori"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Dozvolite pristup za otvaranje linkova hosta <xliff:g id="HOST">%1$s</xliff:g> pomoću"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Dozvolite pristup za otvaranje linkova hosta <xliff:g id="HOST">%1$s</xliff:g> pomoću aplikacije <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Otvaranje <xliff:g id="HOST">%1$s</xliff:g> linkova pomoću"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Otvaranje linkova pomoću"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Otvaranje linkova pomoću aplikacije <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Otvaranje <xliff:g id="HOST">%1$s</xliff:g> linkova pomoću aplikacije <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Dozvoli pristup"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Uredi koristeći"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Uredi koristeći %1$s"</string>
@@ -1390,8 +1385,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Izvršite vraćanje na fabričke postavke da onemogućite način rada okvira za testiranje."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB priključak je sada sigurno koristiti"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon više ne detektira tečnost ili nečistoće."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Prijem izvještaja o grešci..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Podijeliti izvještaj o grešci?"</string>
@@ -1528,7 +1522,7 @@
     <string name="find_next" msgid="5742124618942193978">"Nađi sljedeći"</string>
     <string name="find_previous" msgid="2196723669388360506">"Nađi prethodni"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Korisnik <xliff:g id="NAME">%s</xliff:g> je poslao zahtjev za utvrđivanje lokacije"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Zahtjev za utvrđivanje lokacije"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Zahtjev za lokaciju"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Zahtjev uputio <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Da"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
@@ -1549,7 +1543,7 @@
     <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Povećaj sate"</string>
     <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Smanji sate"</string>
     <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Postavi za poslijepodne (PM)"</string>
-    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Postavi za prijepodne (AM)"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Postavi za prijepodne"</string>
     <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Povećaj mjesece"</string>
     <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Smanji mjesece"</string>
     <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Povećaj dane"</string>
@@ -1617,6 +1611,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Pokretanje preglednika?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prihvatiti poziv?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Uvijek"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Postavi da se uvijek otvara"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo ovaj put"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Postavke"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ne podržava poslovni profil"</string>
@@ -1646,8 +1641,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Nadsloj #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", osigurano"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Pokretanje aktivnosti u pozadini na web lokaciji <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokirat će se u budućim Q verzijama. Pogledajte g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Blokirano je pokretanje aktivnosti u pozadini na web lokaciji <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Pogledajte g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravili ste uzorak?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan uzorak"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna lozinka"</string>
@@ -1702,9 +1695,13 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečica za pristupačnost je uključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečica za pristupačnost je isključila uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pritisnite obje tipke za podešavanje jačine zvuka i držite ih pritisnutim tri sekunde da koristite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Odaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da promijenite funkcije, dodirnite i držite dugme Pristupačnost."</string>
-    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećanje"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Odaberite uslugu koja će se koristiti kada dodirnete dugme za pristupačnost:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Odaberite uslugu koja će se koristiti kada izvedete pokret za pristupačnost (s dva prsta prevucite prema gore s dna ekrana):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Odaberite uslugu koja će se koristiti kada izvedete pokret za pristupačnost (s tri prsta prevucite prema gore s dna ekrana):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Da prebacujete između usluga, dodirnite i zadržite dugme za pristupačnost."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Da prebacujete između usluga, s dva prsta prevucite prema gore i zadržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Da prebacujete između usluga, s tri prsta prevucite prema gore i zadržite."</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Uvećavanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"Odjava korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 2050de3..bbf1736 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Trucades per Wi‑Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Trucades per Wi-Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Trucada per WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Trucada per WLAN (<xliff:g id="SPN">%s</xliff:g>)"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi‑Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Mode de cotxe"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Estat del compte"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Missatges dels desenvolupadors"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Missatges importants per a desenvolupadors"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualitzacions"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estat de la xarxa"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertes de xarxa"</string>
@@ -265,7 +267,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demostració per a botigues"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Connexió USB"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"S\'està executant una aplicació"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplicació en execució"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplicacions que consumeixen bateria"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> està consumint bateria"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacions estan consumint bateria"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona d\'empremta digital"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gestiona el maquinari de desbloqueig facial"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permet que l\'aplicació afegeixi i suprimeixi plantilles de cares que es puguin fer servir."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utilitza el maquinari de desbloqueig facial"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permet que l\'aplicació faci servir el maquinari de desbloqueig facial per a l\'autenticació"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Desbloqueig facial"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Torna a registrar la cara"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Per millorar el reconeixement, torna a registrar la cara"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"No es reconeix la teva cara. Torna-ho a provar."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mou el telèfon cap a l\'esquerra."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mou el telèfon cap a la dreta."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Mira més directament cap al dispositiu."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"No se\'t veu la cara. Mira el telèfon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Posa la cara directament davant del telèfon."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Massa moviment. Subjecta bé el telèfon."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Torna a registrar la teva cara."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ja no es reconeix la teva cara. Torna-ho a provar."</string>
@@ -579,30 +577,25 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Inclina el cap una mica menys."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"No inclinis tant el cap."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Suprimeix qualsevol cosa que amagui la teva cara."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Neteja el sensor de l\'extrem superior."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Neteja la part superior de la pantalla, inclosa la barra negra"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"No es pot verificar la cara. Maquinari no disponible."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Torna a provar el desbloqueig facial."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"No es poden desar dades facials noves. Suprimeix-ne d\'antigues."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"S\'ha cancel·lat el reconeixement facial."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"L\'usuari ha cancel·lat el desbloqueig facial."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Massa intents. Torna-ho a provar més tard."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Massa intents. S\'ha desactivat el desbloqueig facial."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"No es pot verificar la cara. Torna-ho a provar."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"No has configurat el desbloqueig facial"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"El desbloqueig facial no és compatible amb el dispositiu."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="4024817159806482191">"Icona facial"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"llegir la configuració de sincronització"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet que l\'aplicació llegeixi la configuració de sincronització d\'un compte. Per exemple, això pot determinar que l\'aplicació Persones estigui sincronitzada amb un compte."</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Permet que l\'aplicació llegeixi la configuració de sincronització d\'un compte. Per exemple, això pot determinar que l\'aplicació Contactes estigui sincronitzada amb un compte."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"activar o desactivar la sincronització"</string>
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Permet que una aplicació modifiqui la configuració de sincronització d\'un compte. Per exemple, aquesta acció es pot fer servir per activar la sincronització de l\'aplicació Persones amb un compte."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"llegir les estadístiques de sincronització"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Obre amb"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Obre amb %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Obre"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Dona accés per obrir enllaços de <xliff:g id="HOST">%1$s</xliff:g> amb"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Dona accés per obrir enllaços de <xliff:g id="HOST">%1$s</xliff:g> amb <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Obre els enllaços de <xliff:g id="HOST">%1$s</xliff:g> amb"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Obre els enllaços amb"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Obre els enllaços amb <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Obre els enllaços de <xliff:g id="HOST">%1$s</xliff:g> amb <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Dona accés"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edita amb"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edita amb %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Si vols desactivar el mode Agent de prova, restableix les dades de fàbrica."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Hi ha líquid o pols al port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El port USB es desactiva automàticament. Toca per obtenir més informació."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ja pots utilitzar el port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"El telèfon ja no detecta líquids ni pols."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"S\'està creant l\'informe d\'errors…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vols compartir l\'informe d\'errors?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vols iniciar el navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vols acceptar la trucada?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Obre sempre"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Només una vegada"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Configuració"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s no admet perfils professionals."</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposa #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segur"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"A les futures compilacions de Q, es bloquejarà aquest inici d\'activitat en segon pla del paquet <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"S\'ha bloquejat l\'inici d\'activitat en segon pla del paquet <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"He oblidat el patró"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patró incorrecte"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contrasenya incorrecta"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"La drecera d\'accessibilitat ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"La drecera d\'accessibilitat ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Mantén premudes les dues tecles de volum durant 3 segons per fer servir <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Tria la funció que s\'utilitzarà quan toquis el botó Accessibilitat:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Per canviar les funcions, toca i mantén premut el botó Accessibilitat."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Tria el servei que s\'utilitzarà quan toquis el botó d\'accessibilitat:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Tria el servei que s\'utilitzarà amb el gest d\'accessibilitat (fes lliscar dos dits cap amunt des de la part inferior de la pantalla)."</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Tria el servei que s\'utilitzarà amb el gest d\'accessibilitat (fes lliscar tres dits cap amunt des de la part inferior de la pantalla)."</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Per canviar de servei, mantén premut el botó d\'accessibilitat."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Per canviar de servei, fes lliscar dos dits i mantén premut."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Per canviar de servei, fes lliscar tres dits i mantén premut."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliació"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"S\'està canviant a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1792,7 +1789,7 @@
     <string name="restr_pin_try_later" msgid="973144472490532377">"Torna-ho a provar més tard"</string>
     <string name="immersive_cling_title" msgid="8394201622932303336">"Mode de pantalla completa"</string>
     <string name="immersive_cling_description" msgid="3482371193207536040">"Per sortir, llisca cap avall des de la part superior."</string>
-    <string name="immersive_cling_positive" msgid="5016839404568297683">"D\'acord"</string>
+    <string name="immersive_cling_positive" msgid="5016839404568297683">"Entesos"</string>
     <string name="done_label" msgid="2093726099505892398">"Fet"</string>
     <string name="hour_picker_description" msgid="6698199186859736512">"Control circular de les hores"</string>
     <string name="minute_picker_description" msgid="8606010966873791190">"Control circular dels minuts"</string>
@@ -1910,7 +1907,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Cerca actualitzacions"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Tens missatges nous"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Obre l\'aplicació d\'SMS per veure\'ls"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Algunes funcions poden limitar-se"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Algunes funcions poden ser limitades"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Perfil professional bloquejat"</string>
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Toca per desbloquejar el perfil"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"S\'ha connectat a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
@@ -2014,7 +2011,7 @@
     <string name="battery_saver_off_notification_summary" msgid="1374222493681267143">"L\'estalvi de bateria s\'ha desactivat. Les funcions ja no estan restringides."</string>
     <string name="battery_saver_off_alternative_notification_summary" msgid="4340727818546508436">"L\'estalvi de bateria s\'ha desactivat. Les funcions ja no estan restringides."</string>
     <string name="mime_type_folder" msgid="7111951698626315204">"Carpeta"</string>
-    <string name="mime_type_apk" msgid="5518003630972506900">"Aplicació per a Android"</string>
+    <string name="mime_type_apk" msgid="5518003630972506900">"Aplicació d\'Android"</string>
     <string name="mime_type_generic" msgid="6833871596845900027">"Fitxer"</string>
     <string name="mime_type_generic_ext" msgid="8450275970061657174">"Fitxer <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
     <string name="mime_type_audio" msgid="6289777657172050926">"Àudio"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 6feb718f..4171a8b 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>: volání přes Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Volání přes Wi-Fi – <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Volání přes WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>: volání přes WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>: Wi-Fi"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Režim Auto"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Stav účtu"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Zprávy pro vývojáře"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Důležité zprávy od vývojářů"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Aktualizace"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stav sítě"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Síťová upozornění"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona otisku prstů"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"správa hardwaru k odemknutí obličejem"</string>
     <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>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"použití hardwaru k odemknutí obličejem"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Umožňuje aplikaci provést ověření pomocí hardwaru k odemknutí obličejem"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Odemknutí obličejem"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Zaznamenejte obličej znovu"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Chcete-li rozpoznání zdokonalit, zaznamenejte obličej znovu"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Obličej se nepodařilo zachytit. Zkuste to znovu."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Přesuňte telefon vlevo."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Přesuňte telefon vpravo."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Dívejte se přímo na zařízení."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Obličej není vidět. Podívejte se na telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Umístěte obličej přímo před telefon."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Příliš mnoho pohybu. Držte telefon nehybně."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Zaznamenejte obličej znovu."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Obličej už nelze rozpoznat. Zkuste to znovu."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Natočte hlavu o něco méně."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Natočte hlavu o něco méně."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Odstraňte vše, co vám zakrývá obličej."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Vyčistěte snímač u horního okraje obrazovky."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Očistěte horní část obrazovky včetně černé části"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Obličej nelze ověřit. Hardware není dostupný."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Zopakujte odemknutí obličejem."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Údaje o novém obličeji nelze uložit. Nejdřív vymažte starý."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operace snímání obličeje byla zrušena."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Odemknutí obličejem zrušil uživatel."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Příliš mnoho pokusů. Zkuste to později."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Příliš mnoho pokusů. Odemknutí obličejem bylo deaktivováno."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Obličej se nepodařilo ověřit. Zkuste to znovu."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Ověření obličejem nemáte nastavené."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Odemknutí obličejem na tomto zařízení není podporováno."</string>
     <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>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Otevřít v aplikaci"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otevřít v aplikaci %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Otevřít"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Udělte přístup k otevírání odkazů <xliff:g id="HOST">%1$s</xliff:g> pomocí aplikace"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Udělte přístup k otevírání odkazů <xliff:g id="HOST">%1$s</xliff:g> pomocí aplikace <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Odkazy <xliff:g id="HOST">%1$s</xliff:g> otevírat pomocí aplikace"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Odkazy otevírat pomocí aplikace"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Odkazy otevírat pomocí aplikace <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Odkazy <xliff:g id="HOST">%1$s</xliff:g> otevírat pomocí aplikace <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Udělit přístup"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Upravit v aplikaci"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Upravit v aplikaci %1$s"</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Chcete-li deaktivovat režim správce testů, restartujte zařízení do továrního nastavení."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Port USB lze bezpečně použít"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon již nedetekuje kapaliny ani nečistoty."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Vytváření zprávy o chybě…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Sdílet zprávu o chybě?"</string>
@@ -1549,7 +1543,7 @@
     <string name="find_next" msgid="5742124618942193978">"Najít další"</string>
     <string name="find_previous" msgid="2196723669388360506">"Najít předchozí"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Požadavek na informace o poloze od uživatele <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Požadavek na informace o poloze"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Žádost o informaci o poloze"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Požadavek od uživatele <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ano"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Přijmout hovor?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Nastavit na Otevírat vždy"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Pouze jednou"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Nastavení"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s pracovní profily nepodporuje."</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Překryvná vrstva č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Zahájení této aktivity na pozadí ze zdroje <xliff:g id="PACKAGENAME">%1$s</xliff:g> bude v budoucích sestaveních Q zablokováno. Další informace: g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Zahájení aktivity na pozadí ze zdroje <xliff:g id="PACKAGENAME">%1$s</xliff:g> bylo zablokováno. Další informace: g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zapomenuté gesto"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávné gesto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávné heslo"</string>
@@ -1724,8 +1717,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Zkratka přístupnosti zapnula službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Zkratka přístupnosti vypnula službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Chcete-li používat službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tři sekundy podržte stisknutá obě tlačítka hlasitosti"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Určete, jakou funkci aktivujete klepnutím na tlačítko Přístupnost:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Chcete-li vybrat jinou funkci, podržte tlačítko Přístupnost."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Určete, jakou službu aktivujete klepnutím na tlačítko Přístupnost:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Určete, jakou službu aktivujete pomocí gesta přístupnosti (přejetí dvěma prsty ze spodní části obrazovky nahoru):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Určete, jakou službu aktivujete pomocí gesta přístupnosti (přejetí třemi prsty ze spodní části obrazovky nahoru):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Chcete-li přepnout mezi službami, podržte tlačítko Přístupnost."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Chcete-li přepnout mezi službami, přejeďte nahoru dvěma prsty a podržte je."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Chcete-li přepnout mezi službami, přejeďte nahoru třemi prsty a podržte je."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zvětšení"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Přepínání na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ffa382b..b6cb874 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-opkald via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>-opkald via Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-opkald"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-opkald via <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi via <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Biltilstand"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Kontostatus"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Udviklermeddelelser"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Vigtige udviklermeddelelser"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Opdateringer"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Netværksstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Netværksunderretninger"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon for fingeraftryk"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"administrere hardware til ansigtslås"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Tillader, at appen kan bruge metoder til at tilføje og slette ansigtsskabeloner."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"bruge hardware til ansigtslås"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Tillader, at appen bruger hardware til ansigtslås til godkendelse"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Ansigtslås"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Registrer dit ansigt igen"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Registrer dit ansigt igen for at forbedre genkendelsen af det"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Der blev ikke registreret ansigtsdata. Prøv igen."</string>
@@ -570,33 +568,28 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Flyt telefonen til venstre."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Flyt telefonen til højre."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Kig mere direkte på din enhed."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Dit ansigt kan ikke registreres. Kig på telefonen."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Sørg for, at dit ansigt er direkte foran telefonen."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Der er for meget bevægelse. Hold telefonen stille."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registrer dit ansigt igen."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ansigtet kan ikke længere genkendes. Prøv igen."</string>
     <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="4581629343077288178">"Sørg for, at hovedet ikke er drejet for meget."</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Sørg for, at hovedet ikke er bøjet for meget."</string>
-    <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Sørg for, at dit hoved ikke er drejet for meget."</string>
+    <string name="face_acquired_pan_too_extreme" msgid="4581629343077288178">"Du skal ikke dreje hovedet så meget."</string>
+    <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Du skal ikke dreje hovedet så meget."</string>
+    <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Du skal ikke dreje hovedet så meget."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Hvis noget skjuler dit ansigt, skal du fjerne det."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Rens sensoren ved skærmens øverste kant."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Rengør toppen af din skærm, inkl. den sorte bjælke"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Ansigt ikke bekræftet. Hardware ikke tilgængelig."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
-    <string name="face_error_no_space" msgid="2712120617457553825">"Der kan ikke gemmes flere nye ansigter. Slet et gammelt."</string>
+    <string name="face_error_timeout" msgid="981512090365729465">"Prøv ansigtslås igen."</string>
+    <string name="face_error_no_space" msgid="2712120617457553825">"Der kan ikke gemmes nye ansigtsdata. Slet et gammelt først."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansigtshandlingen blev annulleret."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Ansigtslås blev annulleret af brugeren."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Du har prøvet for mange gange. Prøv igen senere."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Du har brugt for mange forsøg. Ansigtslås er deaktiveret."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Ansigtet kan ikke genkendes. Prøv igen."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Du har ikke konfigureret ansigtslås."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Ansigtslås understøttes ikke på denne enhed."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Ansigt <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Åbn med"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Åbn med %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Åbn"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Giv adgang til at åbne <xliff:g id="HOST">%1$s</xliff:g>-link med"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Giv adgang til at åbne <xliff:g id="HOST">%1$s</xliff:g>-links med <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Åbn <xliff:g id="HOST">%1$s</xliff:g>-links med"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Åbn links med"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Åbn links med <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Åbn <xliff:g id="HOST">%1$s</xliff:g>-links med <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Giv adgang"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Rediger med"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Rediger med %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Gendan fabriksindstillingerne for at deaktivere tilstanden Testsele."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-porten kan bruges"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonen registrerer ikke længere væske og snavs."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Opretter fejlrapport…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vil du dele fejlrapporten?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte browseren?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vil du besvare opkaldet?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Altid"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Angiv som altid åben"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Kun én gang"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Indstillinger"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s understøtter ikke arbejdsprofil"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlejring nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sikker"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Denne opstart af aktivitet i baggrunden fra <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokeres i fremtidige Q-builds. Se g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Opstart af aktivitet i baggrunden fra <xliff:g id="PACKAGENAME">%1$s</xliff:g> er blokeret. Se g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Glemt mønster"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Forkert mønster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Forkert adgangskode"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Genvejen til hjælpefunktioner aktiverede <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Genvejen til hjælpefunktioner deaktiverede <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Hold begge lydstyrkeknapper nede i tre sekunder for at bruge <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Vælg, hvilken funktion du vil bruge, når du trykker på knappen Hjælpefunktioner:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Tryk på knappen Hjælpefunktioner, og hold fingeren nede for at skifte funktion."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Vælg, hvilken funktion du vil bruge, når du trykker på knappen Hjælpefunktioner:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med to fingre):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med tre fingre):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Du kan skifte mellem funktioner ved at holde knappen Hjælpefunktioner nede."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Du kan skifte mellem funktioner ved at stryge opad med to fingre og holde dem nede."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Du kan skifte mellem funktioner ved at stryge opad med tre fingre og holde dem nede."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Forstørrelse"</string>
     <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Skifter til <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1895,7 +1892,7 @@
     <string name="user_creation_adding" msgid="4482658054622099197">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g> (der findes allerede en bruger med denne konto)?"</string>
     <string name="language_selection_title" msgid="2680677278159281088">"Tilføj et sprog"</string>
     <string name="country_selection_title" msgid="2954859441620215513">"Områdeindstilling"</string>
-    <string name="search_language_hint" msgid="7042102592055108574">"Angiv sprogets navn"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Angiv sprog"</string>
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"Foreslået"</string>
     <string name="language_picker_section_all" msgid="3097279199511617537">"Alle sprog"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"Alle områder"</string>
@@ -1989,7 +1986,7 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Der er registreret en skadelig app"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> anmoder om tilladelse til at vise eksempler fra <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Rediger"</string>
-    <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"Telefonen vil vibrere ved opkald og notifikationer"</string>
+    <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"Telefonen vibrerer ved opkald og notifikationer"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"Der afspilles ikke lyd ved opkald og notifikationer"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"Systemændringer"</string>
     <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"Forstyr ikke"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 5e0ccd0..114d801 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> WLAN-Telefonie"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> WLAN-Telefonie"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-Anruf"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-Anruf"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WLAN"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Automodus"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Kontostatus"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Nachrichten für Entwickler"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Wichtige Nachrichten für Entwickler"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Netzwerkstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Netzwerkwarnungen"</string>
@@ -314,15 +316,15 @@
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Fensterinhalte abrufen"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Die Inhalte eines Fensters, mit dem du interagierst, werden abgerufen."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\"Tippen &amp; Entdecken\" aktivieren"</string>
-    <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Berührte Elemente werden laut vorgelesen und der Bildschirm kann über Gesten erkundet werden."</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Berührte Elemente werden laut vorgelesen und der Bildschirm kann über Touch-Gesten erkundet werden."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Text bei der Eingabe beobachten"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Einschließlich personenbezogener Daten wie Kreditkartennummern und Passwörter."</string>
     <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Displayvergrößerung festlegen"</string>
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Legt die Zoom-Stufe und -Position auf dem Display fest."</string>
-    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Bewegungen möglich"</string>
-    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Tippen, Wischen, Zusammenziehen und andere Bewegungen möglich."</string>
-    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Bewegungen auf dem Fingerabdrucksensor"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"Erfasst Bewegungen auf dem Fingerabdrucksensor des Geräts."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Touch-Gesten möglich"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Tippen, Wischen, Zusammenziehen und andere Touch-Gesten möglich."</string>
+    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Fingerabdrucksensor-Gesten"</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"Erfasst Touch-Gesten auf dem Fingerabdrucksensor des Geräts."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"Statusleiste deaktivieren oder ändern"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Ermöglicht der App, die Statusleiste zu deaktivieren oder Systemsymbole hinzuzufügen oder zu entfernen"</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"Statusleiste darstellen"</string>
@@ -398,9 +400,9 @@
     <string name="permlab_readCallLog" msgid="3478133184624102739">"Anrufliste lesen"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"Diese App kann deine Anrufliste lesen."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"Anrufliste bearbeiten"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, die Anrufliste deines Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so deine Anrufliste löschen oder ändern."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Ermöglicht der App, die Anrufliste deines Fernsehers zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so deine Anrufliste löschen oder ändern."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, die Anrufliste deines Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so deine Anrufliste löschen oder ändern."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, die Anrufliste deines Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so die Einträge in der Anrufliste löschen oder sie ändern."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Ermöglicht der App, die Anrufliste deines Fernsehers zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so die Einträge in der Anrufliste löschen oder sie ändern."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, die Anrufliste deines Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so die Einträge in der Anrufliste löschen oder sie ändern."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"Auf Körpersensoren wie z. B. Pulsmesser zugreifen"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ermöglicht der App, auf Daten von Sensoren zuzugreifen, die deine körperliche Verfassung überwachen, beispielsweise deinen Puls"</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"Kalendertermine und Details lesen"</string>
@@ -427,7 +429,7 @@
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"Diese App kann jederzeit Audio über das Mikrofon aufnehmen."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"Befehle an die SIM senden"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Ermöglicht der App das Senden von Befehlen an die SIM-Karte. Dies ist äußerst risikoreich."</string>
-    <string name="permlab_activityRecognition" msgid="3634590230567608356">"körperlichen Aktivitäten erkennen"</string>
+    <string name="permlab_activityRecognition" msgid="3634590230567608356">"Körperliche Aktivitäten erkennen"</string>
     <string name="permdesc_activityRecognition" msgid="3143453925156552894">"Diese App kann deine körperliche Aktivität erkennen."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"Bilder und Videos aufnehmen"</string>
     <string name="permdesc_camera" msgid="5392231870049240670">"Diese App kann mit der Kamera jederzeit Bilder und Videos aufnehmen."</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingerabdruck-Symbol"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"Face Unlock-Hardware verwalten"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Ermöglicht der App,  Gesichtsvorlagen hinzuzufügen oder zu entfernen."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"Face Unlock-Hardware verwenden"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Ermöglicht der App, zu Authentifizierungszwecken Face Unlock-Hardware zu verwenden"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face Unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Gesicht neu scannen lassen"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Für bessere Erkennung Gesicht neu scannen lassen"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Gesichtsdaten nicht gut erfasst. Erneut versuchen."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Beweg das Smartphone nach links."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Beweg das Smartphone nach rechts."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Bitte sieh direkt auf dein Gerät."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Gesicht wurde nicht erkannt. Blicke aufs Telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Halte dein Gesicht direkt vor dein Smartphone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Zu viel Unruhe. Halte das Smartphone ruhig."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Bitte registriere dein Gesicht noch einmal."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Gesicht wird nicht mehr erkannt. Erneut versuchen."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Neig den Kopf etwas weniger stark."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Neig den Kopf etwas weniger stark."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Entferne alles, was dein Gesicht verdeckt."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Reinige den Sensor am oberen Rand des Bildschirms."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Reinige den oberen Teil deines Bildschirms, einschließlich der schwarzen Leiste"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Gesicht nicht erkannt. Hardware nicht verfügbar."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Face Unlock noch einmal versuchen."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Kein Speicherplatz frei. Bitte erst ein Gesicht löschen."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Gesichtserkennung abgebrochen."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face Unlock vom Nutzer abgebrochen."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Zu viele Versuche, bitte später noch einmal versuchen"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Zu viele Versuche. Face Unlock wurde deaktiviert."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Gesichtsprüfung nicht möglich. Noch mal versuchen."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Face Unlock ist nicht eingerichtet."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face Unlock wird auf diesem Gerät nicht unterstützt."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Gesicht <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -947,7 +940,7 @@
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf deinem Fernseher zu bearbeiten. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf deinem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"Wecker stellen"</string>
-    <string name="permdesc_setAlarm" msgid="316392039157473848">"Ermöglicht der App, einen Alarm in einer installierten Wecker-App einzurichten. Einige Wecker-Apps implementieren diese Funktion möglicherweise nicht."</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Ermöglicht der App, einen Weckruf in einer installierten Wecker-App einzurichten. Einige Wecker-Apps implementieren diese Funktion möglicherweise nicht."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"Mailboxnachrichten hinzufügen"</string>
     <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Ermöglicht der App, Nachrichten zu deinem Mailbox-Posteingang hinzuzufügen"</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Geolokalisierungsberechtigungen des Browsers ändern"</string>
@@ -978,8 +971,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"Anfrage senden"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Sprachsuche"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\"Tippen &amp; Entdecken\" aktivieren?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\" an. Wenn \"Tippen &amp; Entdecken\" aktiviert ist, kannst du Beschreibungen dessen hören oder sehen, was sich unter deinen Fingern befindet, oder Gesten ausführen, um mit dem Tablet zu kommunizieren."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\" an. Wenn \"Tippen &amp; Entdecken\" aktiviert ist, kannst du Beschreibungen dessen hören oder sehen, was sich unter deinen Fingern befindet, oder Gesten ausführen, um mit dem Telefon zu kommunizieren."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\" an. Wenn \"Tippen &amp; Entdecken\" aktiviert ist, kannst du Beschreibungen dessen hören oder sehen, was sich unter deinen Fingern befindet, oder über Touch-Gesten mit dem Tablet kommunizieren."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> fordert die Aktivierung von \"Tippen &amp; Entdecken\" an. Wenn \"Tippen &amp; Entdecken\" aktiviert ist, kannst du Beschreibungen dessen hören oder sehen, was sich unter deinen Fingern befindet, oder über Touch-Gesten mit dem Telefon kommunizieren."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Vor 1 Monat"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Vor mehr als 1 Monat"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Öffnen mit"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Mit %1$s öffnen"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Öffnen"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Zugriff zum Öffnen von <xliff:g id="HOST">%1$s</xliff:g>-Links erlauben"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Zugriff zum Öffnen von <xliff:g id="HOST">%1$s</xliff:g>-Links mit <xliff:g id="APPLICATION">%2$s</xliff:g> erlauben"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Links von <xliff:g id="HOST">%1$s</xliff:g> öffnen mit"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Links öffnen mit"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Links mit <xliff:g id="APPLICATION">%1$s</xliff:g> öffnen"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Links von <xliff:g id="HOST">%1$s</xliff:g> mit <xliff:g id="APPLICATION">%2$s</xliff:g> öffnen"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Zugriff erlauben"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Bearbeiten mit"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Mit %1$s bearbeiten"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Setz das Gerät auf die Werkseinstellungen zurück, um den Test-Harnischmodus zu deaktivieren."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Flüssigkeiten oder Fremdkörper im USB-Port"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Der USB-Port wird automatisch deaktiviert. Für weitere Informationen tippen."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-Port kann wieder verwendet werden"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Das Smartphone erkennt keine Flüssigkeiten oder Fremdkörper mehr."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Fehlerbericht wird abgerufen…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Fehlerbericht teilen?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Anruf annehmen?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Immer"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Auf \"Immer geöffnet\" festlegen"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Nur diesmal"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Einstellungen"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"Das Arbeitsprofil wird von %1$s nicht unterstützt."</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay-Nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sicher"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Der Start dieser Hintergrundaktivität aus <xliff:g id="PACKAGENAME">%1$s</xliff:g> wird in künftigen Q-Builds blockiert. Weitere Informationen findest du unter g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Der Start der Hintergrundaktivität aus <xliff:g id="PACKAGENAME">%1$s</xliff:g> wurde blockiert. Weitere Informationen findest du unter g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Muster vergessen"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Falsches Muster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Falsches Passwort"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> wurde durch die Bedienungshilfenverknüpfung aktiviert"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> wurde durch die Bedienungshilfenverknüpfung deaktiviert"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Halten Sie beide Lautstärketasten drei Sekunden lang gedrückt, um <xliff:g id="SERVICE_NAME">%1$s</xliff:g> zu verwenden"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Wähle eine Funktion aus, die verwendet wird, wenn du auf die Schaltfläche für die Bedienungshilfen tippst:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Um die Funktionen zu ändern, halte die Schaltfläche für die Bedienungshilfen gedrückt."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Wähle den Dienst aus, der verwendet werden soll, wenn du auf die Schaltfläche für die Bedienungshilfen tippst:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Wähle den Dienst aus, der mit der Touch-Geste für die Bedienungshilfen verwendet werden soll (mit zwei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Wähle den Dienst aus, der mit der Touch-Geste für die Bedienungshilfen verwendet werden soll (mit drei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Wenn du zwischen den Diensten wechseln möchtest, halte die Schaltfläche für die Bedienungshilfen gedrückt."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Wenn du zwischen den Diensten wechseln möchtest, wische mit zwei Fingern nach oben und halte sie gedrückt."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Wenn du zwischen den Diensten wechseln möchtest, wische mit drei Fingern nach oben und halte sie gedrückt."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergrößerung"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Wechseln zu <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 192388d..44357ff 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Κλήση Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Κλήση Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Κλήση μέσω WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Κλήση μέσω WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Λειτουργία αυτοκινήτου"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Κατάσταση λογαριασμού"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Μηνύματα προγραμματιστή"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Σημαντικά μηνύματα προγραμματιστή"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ενημερώσεις"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Κατάσταση δικτύου"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Ειδοποιήσεις δικτύου"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Μετακινήστε το τηλέφωνο στα αριστερά."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Μετακινήστε το τηλέφωνο στα δεξιά."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Κοιτάξτε απευθείας τη συσκευή σας."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Δεν εντοπίστηκε το πρόσωπό σας. Δείτε το τηλέφωνο."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Στρέψτε το πρόσωπό σάς απευθείας στο τηλέφωνο."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Πάρα πολλή κίνηση. Κρατήστε σταθερό το τηλέφωνο."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Καταχωρίστε ξανά το πρόσωπό σας."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Αδύνατη η αναγνώριση του προσώπου. Επανάληψη."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Στρέψτε λιγότερο το κεφάλι σας."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Στρέψτε λιγότερο το κεφάλι σας."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Απομακρύνετε οτιδήποτε κρύβει το πρόσωπό σας."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Καθαρίστε τον αισθητήρα επάνω στην οθόνη."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Καθαρίστε το επάνω μέρος της οθόνης σας, συμπεριλαμβανομένης της μαύρης γραμμής"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Αδύν. επαλήθ. προσώπου. Μη διαθέσιμος εξοπλισμός."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Άνοιγμα με"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Άνοιγμα με %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Άνοιγμα"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Παραχώρηση πρόσβασης για το άνοιγμα συνδέσμων <xliff:g id="HOST">%1$s</xliff:g> με"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Παραχώρηση πρόσβασης για το άνοιγμα συνδέσμων <xliff:g id="HOST">%1$s</xliff:g> με την εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Άνοιγμα συνδέσμων <xliff:g id="HOST">%1$s</xliff:g> με"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Άνοιγμα συνδέσμων με"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Άνοιγμα συνδέσμων με την εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Άνοιγμα συνδέσμων <xliff:g id="HOST">%1$s</xliff:g> με την εφαρμογή <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Παροχή πρόσβασης"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Επεξεργασία με"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Επεξεργασία με %1$s"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Εκκίνηση προγράμματος περιήγησης;"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Αποδοχή κλήσης;"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Πάντα"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Ορισμός ως πάντα ανοικτής"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Μόνο μία φορά"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Ρυθμίσεις"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"Το προφίλ εργασίας δεν υποστηρίζεται από %1$s"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Επικάλυψη #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ασφαλές"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Αυτή η έναρξη δραστηριότητας παρασκηνίου από το <xliff:g id="PACKAGENAME">%1$s</xliff:g> θα αποκλειστεί σε μελλοντικές εκδόσεις του Q. Ανατρέξτε στο g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Η έναρξη δραστηριότητας παρασκηνίου από το <xliff:g id="PACKAGENAME">%1$s</xliff:g> αποκλείστηκε. Ανατρέξτε στο g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Ξεχάσατε το μοτίβο"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Λάθος μοτίβο"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Λανθασμένος κωδικός πρόσβασης"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Η συντόμευση προσβασιμότητας ενεργοποίησε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Η συντόμευση προσβασιμότητας απενεργοποίησε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Πατήστε παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα, ώστε να χρησιμοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού \"Προσβασιμότητα\"."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Για να αλλάξετε λειτουργίες, αγγίξτε παρατεταμένα το κουμπί \"Προσβασιμότητα\"."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Επιλέξτε μια υπηρεσία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού προσβασιμότητας:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Επιλέξτε μια υπηρεσία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με δύο δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Επιλέξτε μια υπηρεσία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με τρία δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Για εναλλαγή μεταξύ υπηρεσιών, αγγίξτε παρατεταμένα το κουμπί προσβασιμότητας."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Για εναλλαγή μεταξύ υπηρεσιών, σύρετε παρατεταμένα με δύο δάχτυλα προς τα επάνω."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Για εναλλαγή μεταξύ υπηρεσιών, σύρετε παρατεταμένα με τρία δάχτυλα προς τα επάνω."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Μεγιστοποίηση"</string>
     <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 84f1faf..cc389f3 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Car mode"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Account status"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Developer messages"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Important developer messages"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Network status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Network alerts"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Move phone to the left."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Move phone to the right."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Please look more directly at your device."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Can’t see your face. Look at the phone."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Position your face directly in front of the phone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Too much motion. Hold phone steady."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Please re-enroll your face."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"No longer able to recognise face. Try again."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Turn your head a little less."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Turn your head a little less."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Remove anything hiding your face."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Clean the sensor at the top edge of the screen."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Clean the top of your screen, including the black bar"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Can’t verify face. Hardware not available."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Open with"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Open with %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Open"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Give access to open <xliff:g id="HOST">%1$s</xliff:g> links with"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Give access to open <xliff:g id="HOST">%1$s</xliff:g> links with <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Open <xliff:g id="HOST">%1$s</xliff:g> links with"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Open links with"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Open links with <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Open <xliff:g id="HOST">%1$s</xliff:g> links with <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Give access"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Set to always open"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Just once"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Settings"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s doesn\'t support work profile"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"This background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> blocked. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choose a service to use when you tap the accessibility button:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"To switch between services, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"To switch between services, swipe up with two fingers and hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"To switch between services, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 19b64c8..0e6d49c 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Car mode"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Account status"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Developer messages"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Important developer messages"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Network status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Network alerts"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Move phone to the left."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Move phone to the right."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Please look more directly at your device."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Can’t see your face. Look at the phone."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Position your face directly in front of the phone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Too much motion. Hold phone steady."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Please re-enroll your face."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"No longer able to recognise face. Try again."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Turn your head a little less."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Turn your head a little less."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Remove anything hiding your face."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Clean the sensor at the top edge of the screen."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Clean the top of your screen, including the black bar"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Can’t verify face. Hardware not available."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Open with"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Open with %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Open"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Give access to open <xliff:g id="HOST">%1$s</xliff:g> links with"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Give access to open <xliff:g id="HOST">%1$s</xliff:g> links with <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Open <xliff:g id="HOST">%1$s</xliff:g> links with"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Open links with"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Open links with <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Open <xliff:g id="HOST">%1$s</xliff:g> links with <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Give access"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Set to always open"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Just once"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Settings"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s doesn\'t support work profile"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"This background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> blocked. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choose a service to use when you tap the accessibility button:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"To switch between services, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"To switch between services, swipe up with two fingers and hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"To switch between services, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 84f1faf..cc389f3 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Car mode"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Account status"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Developer messages"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Important developer messages"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Network status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Network alerts"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Move phone to the left."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Move phone to the right."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Please look more directly at your device."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Can’t see your face. Look at the phone."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Position your face directly in front of the phone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Too much motion. Hold phone steady."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Please re-enroll your face."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"No longer able to recognise face. Try again."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Turn your head a little less."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Turn your head a little less."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Remove anything hiding your face."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Clean the sensor at the top edge of the screen."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Clean the top of your screen, including the black bar"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Can’t verify face. Hardware not available."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Open with"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Open with %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Open"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Give access to open <xliff:g id="HOST">%1$s</xliff:g> links with"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Give access to open <xliff:g id="HOST">%1$s</xliff:g> links with <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Open <xliff:g id="HOST">%1$s</xliff:g> links with"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Open links with"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Open links with <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Open <xliff:g id="HOST">%1$s</xliff:g> links with <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Give access"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Set to always open"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Just once"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Settings"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s doesn\'t support work profile"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"This background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> blocked. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choose a service to use when you tap the accessibility button:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"To switch between services, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"To switch between services, swipe up with two fingers and hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"To switch between services, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 84f1faf..cc389f3 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Car mode"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Account status"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Developer messages"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Important developer messages"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Network status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Network alerts"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Move phone to the left."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Move phone to the right."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Please look more directly at your device."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Can’t see your face. Look at the phone."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Position your face directly in front of the phone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Too much motion. Hold phone steady."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Please re-enroll your face."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"No longer able to recognise face. Try again."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Turn your head a little less."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Turn your head a little less."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Remove anything hiding your face."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Clean the sensor at the top edge of the screen."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Clean the top of your screen, including the black bar"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Can’t verify face. Hardware not available."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Open with"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Open with %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Open"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Give access to open <xliff:g id="HOST">%1$s</xliff:g> links with"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Give access to open <xliff:g id="HOST">%1$s</xliff:g> links with <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Open <xliff:g id="HOST">%1$s</xliff:g> links with"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Open links with"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Open links with <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Open <xliff:g id="HOST">%1$s</xliff:g> links with <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Give access"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Set to always open"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Just once"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Settings"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s doesn\'t support work profile"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"This background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> will be blocked in future Q builds. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Background activity start from <xliff:g id="PACKAGENAME">%1$s</xliff:g> blocked. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Forgot Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Wrong Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Wrong Password"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"To change features, touch &amp; hold the Accessibility button."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choose a service to use when you tap the accessibility button:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"To switch between services, touch &amp; hold the accessibility button."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"To switch between services, swipe up with two fingers and hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"To switch between services, swipe up with three fingers and hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Magnification"</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 0002e13..dade85e 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ Wi-Fi Calling‎‏‎‎‏‎"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ WiFi Calling‎‏‎‎‏‎"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎WLAN Call‎‏‎‎‏‎"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ WLAN Call‎‏‎‎‏‎"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="SPN">%s</xliff:g>‎‏‎‎‏‏‏‎ Wi-Fi‎‏‎‎‏‎"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎Car mode‎‏‎‎‏‎"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎Account status‎‏‎‎‏‎"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎Developer messages‎‏‎‎‏‎"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎Important developer messages‎‏‎‎‏‎"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎Updates‎‏‎‎‏‎"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎Network status‎‏‎‎‏‎"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‎Network alerts‎‏‎‎‏‎"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎Move phone to the left.‎‏‎‎‏‎"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎Move phone to the right.‎‏‎‎‏‎"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎Please look more directly at your device.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎Can’t see your face. Look at the phone.‎‏‎‎‏‎"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎Position your face directly in front of the phone.‎‏‎‎‏‎"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎Too much motion. Hold phone steady.‎‏‎‎‏‎"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎Please re-enroll your face.‎‏‎‎‏‎"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎No longer able to recognize face. Try again.‎‏‎‎‏‎"</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‎Turn your head a little less.‎‏‎‎‏‎"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎Turn your head a little less.‎‏‎‎‏‎"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎Remove anything hiding your face.‎‏‎‎‏‎"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‎‎Clean the sensor at the top edge of the screen.‎‏‎‎‏‎"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎Clean the top of your screen, including the black bar‎‏‎‎‏‎"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‎Can’t verify face. Hardware not available.‎‏‎‎‏‎"</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‏‏‎‎Open with‎‏‎‎‏‎"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎Open with %1$s‎‏‎‎‏‎"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‎‏‎Open‎‏‎‎‏‎"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎Give access to open ‎‏‎‎‏‏‎<xliff:g id="HOST">%1$s</xliff:g>‎‏‎‎‏‏‏‎ links with‎‏‎‎‏‎"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎Give access to open ‎‏‎‎‏‏‎<xliff:g id="HOST">%1$s</xliff:g>‎‏‎‎‏‏‏‎ links with ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‎Open ‎‏‎‎‏‏‎<xliff:g id="HOST">%1$s</xliff:g>‎‏‎‎‏‏‏‎ links with‎‏‎‎‏‎"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎Open links with‎‏‎‎‏‎"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎Open links with ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎Open ‎‏‎‎‏‏‎<xliff:g id="HOST">%1$s</xliff:g>‎‏‎‎‏‏‏‎ links with ‎‏‎‎‏‏‎<xliff:g id="APPLICATION">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎Give access‎‏‎‎‏‎"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‏‏‎Edit with‎‏‎‎‏‎"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‏‎‎Edit with %1$s‎‏‎‎‏‎"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎Launch Browser?‎‏‎‎‏‎"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‎Accept call?‎‏‎‎‏‎"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‎Always‎‏‎‎‏‎"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎Set to always open‎‏‎‎‏‎"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎Just once‎‏‎‎‏‎"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎Settings‎‏‎‎‏‎"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎%1$s doesn\'t support work profile‎‏‎‎‏‎"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‎Overlay #‎‏‎‎‏‏‎<xliff:g id="ID">%1$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎: ‎‏‎‎‏‏‎<xliff:g id="WIDTH">%2$d</xliff:g>‎‏‎‎‏‏‏‎x‎‏‎‎‏‏‎<xliff:g id="HEIGHT">%3$d</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="DPI">%4$d</xliff:g>‎‏‎‎‏‏‏‎ dpi‎‏‎‎‏‎"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎, secure‎‏‎‎‏‎"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎This background activity start from ‎‏‎‎‏‏‎<xliff:g id="PACKAGENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ will be blocked in future Q builds. See g.co/dev/bgblock.‎‏‎‎‏‎"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎Background activity start from ‎‏‎‎‏‏‎<xliff:g id="PACKAGENAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ blocked. See g.co/dev/bgblock.‎‏‎‎‏‎"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎Forgot Pattern‎‏‎‎‏‎"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎Wrong Pattern‎‏‎‎‏‎"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎Wrong Password‎‏‎‎‏‎"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎Accessibility Shortcut turned ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ on‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎Accessibility Shortcut turned ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ off‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎Press and hold both volume keys for three seconds to use ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎Choose a feature to use when you tap the Accessibility button:‎‏‎‎‏‎"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎To change features, touch &amp; hold the Accessibility button.‎‏‎‎‏‎"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‎‎Choose a service to use when you tap the accessibility button:‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‎‎‏‎Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):‎‏‎‎‏‎"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎To switch between services, touch &amp; hold the accessibility button.‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎To switch between services, swipe up with two fingers and hold.‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎To switch between services, swipe up with three fingers and hold.‎‏‎‎‏‎"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‎Magnification‎‏‎‎‏‎"</string>
     <string name="user_switched" msgid="3768006783166984410">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎Current user ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎Switching to ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 07cae0a..3a2ea3e 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -34,7 +34,7 @@
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"Problema de conexión o código incorrecto de MMI."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"La operación está limitada a números de marcación fija."</string>
-    <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"No se puede cambiar la configuración de reenvío de llamadas de tu teléfono mientras usas el servicio de roaming."</string>
+    <string name="mmiErrorWhileRoaming" msgid="762488890299284230">"No se puede cambiar la configuración de desvío de llamadas de tu teléfono mientras usas el servicio de roaming."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"Se ha activado el servicio."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"Se activó el servicio para:"</string>
     <string name="serviceDisabled" msgid="1937553226592516411">"Se ha desactivado el servicio."</string>
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Llamada por Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Llamada por Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Llamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Llamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Modo auto"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Estado de la cuenta"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mensajes de programadores"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mensajes importantes de desarrolladores"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualizaciones"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estado de la red"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas de red"</string>
@@ -290,7 +292,7 @@
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"enviar y ver mensajes SMS"</string>
     <string name="permgrouprequest_sms" msgid="7168124215838204719">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; envíe y vea SMS?"</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Espacio de almacenamiento"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Almacenamiento"</string>
     <string name="permgroupdesc_storage" msgid="637758554581589203">"acceder a las fotos, el contenido multimedia y los archivos"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; acceda a las fotos, el contenido multimedia y los archivos de tu dispositivo?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Micrófono"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ícono de huella digital"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"administrar el hardware de Desbloqueo facial"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que la app emplee métodos para agregar y borrar plantillas de rostros para su uso."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"usar el hardware de Desbloqueo facial"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permite que la app use el hardware de Desbloqueo facial con fines de autenticación"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Desbloqueo facial"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Vuelve a registrar tu rostro"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Para mejorar el reconocimiento, vuelve a registrar tu rostro"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Datos faciales imprecisos. Vuelve a intentarlo."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mueve el teléfono hacia la izquierda."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mueve el teléfono hacia la derecha."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Mira directamente al dispositivo."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"No se ve tu cara. Mira el teléfono."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Ubica el rostro directamente frente al teléfono."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Te estás moviendo demasiado. No muevas el teléfono"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Vuelve a registrar tu cara."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ya no se reconoce la cara. Vuelve a intentarlo."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Gira la cabeza un poco menos."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Gira la cabeza un poco menos."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Quítate cualquier objeto que te cubra el rostro."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Limpiar sensor del borde superior de la pantalla."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Limpia la parte superior de la pantalla, incluida la barra negra"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"No se verificó el rostro. Hardware no disponible."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Vuelve a probar el Desbloqueo facial."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"No hay espacio para datos faciales nuevos. Borra uno viejo."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Se canceló el reconocimiento facial."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"El usuario canceló el Desbloqueo facial."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Inténtalo de nuevo más tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Demasiados intentos. Se inhabilitó el Desbloqueo facial."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"No se pudo verificar la cara. Vuelve a intentarlo."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"No configuraste el Desbloqueo facial."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"No se admite el Desbloqueo facial en este dispositivo."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Rostro <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -609,7 +602,7 @@
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Permite que la aplicación consulte las estadísticas de sincronización de una cuenta, por ejemplo, el historial de eventos sincronizados y la cantidad de datos sincronizados."</string>
     <string name="permlab_sdcardRead" msgid="1438933556581438863">"ver almacenamiento compartido"</string>
     <string name="permdesc_sdcardRead" msgid="1804941689051236391">"Ver almacenamiento compartido"</string>
-    <string name="permlab_sdcardWrite" msgid="9220937740184960897">"Cambia/borra almac. compartido"</string>
+    <string name="permlab_sdcardWrite" msgid="9220937740184960897">"cambiar o borrar contenido de almacenamiento compartido"</string>
     <string name="permdesc_sdcardWrite" msgid="2834431057338203959">"Editar almacen. compartido"</string>
     <string name="permlab_use_sip" msgid="2052499390128979920">"realizar/recibir llamadas SIP"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"Permite que la aplicación realice y reciba llamadas SIP."</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Abrir con"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Abrir con %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Abrir"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Otorgar acceso para abrir vínculos de <xliff:g id="HOST">%1$s</xliff:g> con"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Otorgar acceso para abrir vínculos de <xliff:g id="HOST">%1$s</xliff:g> con <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Abrir vínculos de <xliff:g id="HOST">%1$s</xliff:g> con"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Abrir vínculos con"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Abrir vínculos con <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Abrir vínculos de <xliff:g id="HOST">%1$s</xliff:g> con <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Otorgar acceso"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Editar con"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editar con %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece la configuración de fábrica para inhabilitar el modo de agente de prueba."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Se puede usar el puerto USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"El teléfono ya no detecta líquidos o suciedad."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Realizando un informe de errores…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Deseas iniciar el navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"¿Aceptar la llamada?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Siempre"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Establecer en \"abrir siempre\""</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Solo una vez"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Configuración"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s no admite perfiles de trabajo."</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segura"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"En las próximas compilaciones de Q, se bloqueará el inicio de la actividad en segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Se bloqueó el inicio de la actividad en segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Olvidaste el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Patrón incorrecto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"El acceso directo de accesibilidad activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"El acceso directo de accesibilidad desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Mantén presionadas ambas teclas de volumen durante tres segundos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Elige una función para usar cuando presionas el botón Accesibilidad:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar funciones, mantén presionado el botón Accesibilidad."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Elige un servicio para usar cuando presiones el botón de accesibilidad:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Elige un servicio para usar cuando realices el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Elige el servicio que se usará cuando realices el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para cambiar de servicio, mantén presionado el botón de accesibilidad."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para cambiar de servicio, desliza dos dedos hacia arriba y mantén presionado."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para cambiar de servicio, desliza tres dedos hacia arriba y mantén presionado."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliación"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 7261eb0..633759b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Llamada por Wi‑Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Llamada por Wi‑Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Llamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Llamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi‑Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Modo de coche"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Estado de la cuenta"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mensajes de desarrolladores"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mensajes importantes para desarrolladores"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualizaciones"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estado de la red"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas de la red"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icono de huella digital"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gestionar el hardware de desbloqueo facial"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que la app use métodos para añadir y suprimir plantillas de caras para su uso."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"Utilizar hardware de desbloqueo facial"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permite que la aplicación utilice el hardware de desbloqueo facial para autenticarte"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Desbloqueo facial"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Volver a registrar la cara"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Para mejorar el reconocimiento, vuelve a registrar tu cara"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Datos faciales no reconocidos. Vuelve a intentarlo."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mueve el teléfono hacia la izquierda."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mueve el teléfono hacia la derecha."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Mira de forma más directa al dispositivo."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"No se detecta tu cara. Mira al teléfono."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Coloca la cara directamente frente al teléfono."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"El teléfono se mueve demasiado. Mantenlo quieto."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Vuelve a registrar tu cara."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"No puede reconocer tu cara. Vuelve a intentarlo."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Gira la cabeza un poco menos."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"No gires tanto la cabeza."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Retira cualquier objeto que te tape la cara."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Limpia el sensor situado en la parte superior."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Limpia la parte superior de la pantalla, incluida la barra de color negro"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"No se puede verificar. Hardware no disponible."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Vuelve a probar el desbloqueo facial."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Para guardar nuevos datos faciales, borra otros antiguos."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Se ha cancelado el reconocimiento facial."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"El usuario ha cancelado el desbloqueo facial."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Inténtalo de nuevo más tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Muchos intentos. Se ha inhabilitado el desbloqueo facial."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"No se ha verificado tu cara. Vuelve a intentarlo."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"No has configurado el desbloqueo facial."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"El desbloqueo facial no está disponible en este dispositivo."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Abrir con"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Abrir con %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Abrir"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Permitir acceso para abrir enlaces de <xliff:g id="HOST">%1$s</xliff:g> con"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Permitir acceso para abrir enlaces de <xliff:g id="HOST">%1$s</xliff:g> con <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Abrir enlaces de <xliff:g id="HOST">%1$s</xliff:g> con"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Abrir enlaces con"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Abrir enlaces con <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Abrir enlaces de <xliff:g id="HOST">%1$s</xliff:g> con <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Permitir acceso"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Editar con"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editar con %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Se ha detectado líquido o suciedad en el puerto USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"El puerto USB se ha inhabilitado automáticamente. Toca para obtener más información."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Se puede utilizar el puerto USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"El teléfono ya no detecta líquidos ni suciedad."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de errores…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"¿Iniciar el navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"¿Aceptar la llamada?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Siempre"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Configurar para que se abra siempre"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Solo una vez"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Ajustes"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s no admite perfiles de trabajo"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"El inicio de la actividad en segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g> se bloqueará en las próximas compilaciones de Q. Accede a g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Se ha bloqueado el inicio de la actividad en segundo plano de <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Accede a g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"¿Has olvidado el patrón?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"El patrón es incorrecto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contraseña incorrecta"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"El acceso directo a accesibilidad ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"El acceso directo a accesibilidad ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Para utilizar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas ambas teclas de volumen durante 3 segundos"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Selecciona la función que se utilizará cuando toques el botón Accesibilidad:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar las funciones, mantén pulsado el botón Accesibilidad."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Selecciona el servicio que se utilizará cuando toques el botón Accesibilidad:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Elige el servicio que se utilizará con el gesto de accesibilidad (desliza dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Elige el servicio que se utilizará con el gesto de accesibilidad (desliza tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para cambiar de un servicio a otro, mantén pulsado el botón de accesibilidad."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para cambiar de un servicio a otro, desliza dos dedos hacia arriba y mantén pulsada la pantalla."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para cambiar de un servicio a otro, desliza tres dedos hacia arriba y mantén pulsada la pantalla."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliar"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 42ce4ef..86843c7 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>: WiFi-kõned"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>: WiFi-kõned"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-kõne"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>: WLAN-kõne"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>: WiFi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Autorežiim"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Konto olek"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Arendaja sõnumid"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Olulised arendajasõnumid"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Värskendused"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Võrgu olek"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Võrguteavitused"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Sõrmejälje ikoon"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"hallata Face Unlocki riistvara"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Lubab rakendusel tühistada meetodid kasutatavate näomallide lisamiseks ja kustutamiseks."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"kasutada Face Unlocki riistvara"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Võimaldab rakendusel autentimiseks kasutada Face Unlocki riistvara"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face Unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Registreerige oma nägu uuesti"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Tuvastamise parandamiseks registreerige oma nägu uuesti"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Näoandmeid ei saanud jäädvustada. Proovige uuesti."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Liigutage telefoni vasakule."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Liigutage telefoni paremale."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Vaadake otse oma seadmesse."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Teie nägu ei ole näha. Vaadake telefoni poole."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Hoidke oma nägu otse telefoni ees."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Liiga palju liikumist. Hoidke telefoni paigal."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registreerige oma nägu uuesti."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Nägu ei õnnestu enam tuvastada. Proovige uuesti."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Pöörake oma pead veidi vähem."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Pöörake oma pead veidi vähem."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Eemaldage kõik, mis varjab teie nägu."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Puhastage ekraani ülaservas olev andur."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Puhastage ekraani ülaosa, sh musta värvi riba"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Nägu ei saa kinnitada. Riistvara pole saadaval."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Proovige Face Unlocki uuesti."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Uue näo andmeid ei saa salvestada. Kustutage enne vanad."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Näotuvastuse toiming tühistati."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Kasutaja tühistas Face Unlocki."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Liiga palju katseid. Proovige hiljem uuesti."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Liiga palju katseid. Face Unlock on keelatud."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nägu ei saa kinnitada. Proovige uuesti."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Face Unlocki ei ole seadistatud."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Seade ei toeta Face Unlocki."</string>
     <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>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Avamine:"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Avamine rakendusega %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Ava"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Juurdepääsu andmine, et avada üksuse <xliff:g id="HOST">%1$s</xliff:g> lingid"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Juurdepääsu andmine, et avada üksuse <xliff:g id="HOST">%1$s</xliff:g> lingid rakendusega <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Ava teenuse <xliff:g id="HOST">%1$s</xliff:g> lingid rakendusega"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Ava lingid rakendusega"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Linkide avamine rakendusega <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Ava teenuse <xliff:g id="HOST">%1$s</xliff:g> lingid rakendusega <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Juudep. andmine"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Muutmine:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Muutmine rakendusega %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Testrakendirežiimi keelamiseks taastage tehaseseaded."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-porti tohib kasutada"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon ei tuvasta enam vedelikku ega mustust."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Veaaruande võtmine …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Kas jagada veaaruannet?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Kas käivitada brauser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Kas vastata kõnele?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Alati"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Määra alati avama"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Ainult üks kord"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Seaded"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ei toeta tööprofiili"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Ülekate nr .<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", turvaline"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"See taustategevuse käivitamine paketist <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokeeritakse tulevaste Q järkude puhul. Vt g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Taustategevuse käivitamine paketist <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokeeriti. Vt g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unustasin mustri"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Vale muster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Vale parool"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Juurdepääsetavuse otsetee lülitas teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> sisse"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Juurdepääsetavuse otsetee lülitas teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> välja"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Valige, millist funktsiooni kasutada, kui vajutate nuppu Juurdepääsetavus:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funktsioonide muutmiseks puudutage pikalt nuppu Juurdepääsetavus."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Valige, millist teenust kasutada, kui puudutate juurdepääsetavuse nuppu:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Valige, millist teenust kasutada koos juurdepääsetavuse liigutusega (pühkige kahe sõrmega ekraanikuval alt üles):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Valige, millist teenust kasutada koos juurdepääsetavuse liigutusega (kolme sõrmega ekraanikuval alt üles pühkimine):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Teenuste vahel vahetamiseks vajutage pikalt juurdepääsetavuse nuppu."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Teenuste vahel vahetamiseks pühkige kahe sõrmega üles ja hoidke."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Teenuste vahel vahetamiseks pühkige kolme sõrmega üles ja hoidke."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Suurendus"</string>
     <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 00e9de9..d25fe8c 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi bidezko deiak"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> operadorearen wifi bidezko deiak"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN bidezko deia"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN bidezko deia"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> wifia"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Auto modua"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Kontuaren egoera"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Garatzaileentzako mezuak"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Garatzaileentzako mezu garrantzitsua"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Eguneratzeak"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Sarearen egoera"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Sarearen alertak"</string>
@@ -373,7 +375,7 @@
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Beren zati batzuk memoria modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Horrela, beste aplikazioek erabilgarri duten memoria murritz daiteke eta tableta motel daiteke."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Beren zati batzuk memorian modu iraunkorrean aktibo uztea baimentzen die aplikazioei. Horrela, beste aplikazioek memoria gutxiago izan lezakete erabilgarri eta telebistak motelago funtziona lezake."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Beren zati batzuk memoria modu iraunkorrean ezartzeko baimena ematen die aplikazioei. Horrela, beste aplikazioek erabilgarri duten memoria murritz daiteke eta telefonoa motel daiteke."</string>
-    <string name="permlab_foregroundService" msgid="3310786367649133115">"Exekutatu zerbitzuak aurreko planoan"</string>
+    <string name="permlab_foregroundService" msgid="3310786367649133115">"Abiarazi zerbitzuak aurreko planoan"</string>
     <string name="permdesc_foregroundService" msgid="6471634326171344622">"Aurreko planoko zerbitzuak erabiltzea baimentzen dio aplikazioari."</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"neurtu aplikazioen biltegiratzeko tokia"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Bere kodea, datuak eta cache-tamainak eskuratzeko baimena ematen die aplikazioei."</string>
@@ -420,7 +422,7 @@
     <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telebistan, aplikazioak erabil ditzan."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telefonoan, aplikazioak erabil ditzan."</string>
     <string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"Atzitu kokapena atzeko planoan"</string>
-    <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Baimen hau ematen bada kokapen zehatz edo gutxi gorabeherakorako sarbideaz gain, atzeko planoan exekutatu bitartean atzitu ahalko du aplikazioak kokapena."</string>
+    <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Baimen hau ematen bada kokapen zehatz edo gutxi gorabeherakorako sarbideaz gain, atzeko planoan abian den bitartean atzitu ahalko du aplikazioak kokapena."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"aldatu audio-ezarpenak"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Audio-ezarpen orokorrak aldatzeko baimena ematen dio; besteak beste, bolumena eta irteerarako zer bozgorailu erabiltzen den."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"grabatu audioa"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Hatz-markaren ikonoa"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"kudeatu aurpegiaren bidez desblokeatzeko hardwarea"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Aurpegi-txantiloiak gehitu eta ezabatzeko metodoei dei egitea baimentzen dio aplikazioari."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"erabili aurpegiaren bidez desblokeatzeko hardwarea"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Autentifikazioa egiteko aurpegiaren bidez desblokeatzeko hardwarea erabiltzeko baimena ematen dio aplikazioari"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Aurpegiaren bidez desblokeatzeko aukera"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Erregistratu aurpegia berriro"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Ezagutzea hobetzeko, erregistratu aurpegia berriro"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Ezin izan dira bildu argazkiaren datu zehatzak. Saiatu berriro."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mugitu telefonoa ezkerretara."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mugitu telefonoa eskuinetara."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Begiratu zuzenago gailuari."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Ez da agertzen aurpegia. Begiratu telefonoari."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Ipini aurrez aurre aurpegia eta telefonoa."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Mugimendu gehiegi dago. Eutsi tinko telefonoari."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Erregistratu berriro aurpegia."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ez dugu ezagutzen aurpegi hori. Saiatu berriro."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Biratu burua pixka bat gutxiago."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Biratu burua pixka bat gutxiago."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Kendu aurpegia estaltzen dizuten gauzak."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Garbitu pantailaren goiko ertzeko sentsorea."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Garbitu pantailaren goialdea, barra beltza barne"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Ezin da egiaztatu aurpegia. Hardwarea ez dago erabilgarri."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Saiatu berriro aurpegiaren bidez desblokeatzen."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Ezin dira gorde aurpegiaren datu berriak. Ezabatu zaharrak."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Utzi da aurpegiaren bidezko eragiketa."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Erabiltzaileak bertan behera utzi du aurpegiaren bidez desblokeatzea."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Saiakera gehiegi egin dituzu. Saiatu berriro geroago."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Saiakera gehiegi egin dira. Aurpegiaren bidez desblokeatzeko aukera desgaitu egin da."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Ezin da egiaztatu aurpegia. Saiatu berriro."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Ez duzu konfiguratu aurpegiaren bidez desblokeatzeko aukera."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Gailu honek ez du onartzen aurpegiaren bidez desblokeatzea."</string>
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> aurpegia"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -621,8 +614,8 @@
     <string name="permdesc_connection_manager" msgid="5925480810356483565">"Telekomunikabideekiko konexioak kudeatzea baimentzen die aplikazioei."</string>
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"erabili pantaila deiak abian direnean"</string>
     <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Erabiltzaileak deiaren pantaila noiz eta nola ikusten duen kontrolatzeko aukera ematen die aplikazioei."</string>
-    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"elkarreragin telefono-zerbitzuekin"</string>
-    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Deiak egiteko eta jasotzeko telefonia-zerbitzuekin elkarreragitea baimentzen die aplikazioei."</string>
+    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"jardun interakzioan telefono-zerbitzuekin"</string>
+    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Deiak egiteko eta jasotzeko telefonia-zerbitzuekin interakzioan aritzea baimentzen die aplikazioei."</string>
     <string name="permlab_control_incall_experience" msgid="9061024437607777619">"eskaini erabiltzaileentzako aukerak deiak abian direnean"</string>
     <string name="permdesc_control_incall_experience" msgid="915159066039828124">"Deiak abian direnean erabiltzeko aukera eskaintzea baimentzen die aplikazioei."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"irakurri sare-erabileraren historia"</string>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Zabaldu desblokeatzeko eremua."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Hatza lerratuta desblokeatzea."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Ereduaren bidez desblokeatzea."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Aurpegiaren bidez desblokeatzea."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Aurpegiaren bidez desblokeatzeko aukera."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN kodearen bidez desblokeatzea."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"SIM txartela desblokeatzeko PIN kodea."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"SIM txartela desblokeatzeko PUK kodea."</string>
@@ -978,8 +971,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"Bidali kontsulta"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Ahozko bilaketa"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\"Arakatu ukituta\" eginbidea gaitu nahi duzu?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> zerbitzuak \"Arakatu ukituta\" eginbidea gaitu nahi du. Eginbide hori aktibatuta dagoenean, hatzaren azpian duzunaren azalpena ikus edo entzun dezakezu, edo tabletarekin elkarrekintzan aritzeko keinuak egin ditzakezu."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> zerbitzuak \"Arakatu ukituta\" eginbidea gaitu nahi du. Eginbide hori aktibatuta dagoenean, hatzaren azpian duzunaren azalpena ikus edo entzun dezakezu, edo telefonoarekin elkarrekintzan aritzeko keinuak egin ditzakezu."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> zerbitzuak \"Arakatu ukituta\" eginbidea gaitu nahi du. Eginbide hori aktibatuta dagoenean, hatzaren azpian duzunaren azalpena ikus edo entzun dezakezu, edo tabletarekin interakzioan aritzeko keinuak egin ditzakezu."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> zerbitzuak \"Arakatu ukituta\" eginbidea gaitu nahi du. Eginbide hori aktibatuta dagoenean, hatzaren azpian duzunaren azalpena ikus edo entzun dezakezu, edo telefonoarekin interakzioan aritzeko keinuak egin ditzakezu."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Duela hilabete"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Duela hilabete baino gutxiago"</string>
     <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Ireki honekin:"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Irekin %1$s aplikazioarekin"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Ireki"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Eman <xliff:g id="HOST">%1$s</xliff:g> estekak irekitzeko baimena aplikazio honi:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Eman <xliff:g id="APPLICATION">%2$s</xliff:g> aplikazioari <xliff:g id="HOST">%1$s</xliff:g> irekitzeko baimena"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Ireki <xliff:g id="HOST">%1$s</xliff:g> ostalariko estekak honekin:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Ireki estekak honekin:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Ireki estekak <xliff:g id="APPLICATION">%1$s</xliff:g> aplikazioarekin"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Ireki <xliff:g id="HOST">%1$s</xliff:g> ostalariko estekak <xliff:g id="APPLICATION">%2$s</xliff:g> aplikazioarekin"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Eman sarbidea"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Editatu honekin:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editatu %1$s aplikazioarekin"</string>
@@ -1160,7 +1155,7 @@
     <string name="use_a_different_app" msgid="8134926230585710243">"Erabili beste aplikazio bat"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Garbitu aplikazio lehenetsia Sistemaren ezarpenak &gt; Aplikazioak &gt; Deskargatutakoak atalean."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Aukeratu ekintza bat"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"Aukeratu USB gailurako aplikazioa"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Aukeratu USB bidezko gailurako aplikazioa"</string>
     <string name="noApplications" msgid="2991814273936504689">"Ez dago ekintza hori egin dezakeen aplikaziorik."</string>
     <string name="aerr_application" msgid="250320989337856518">"Gelditu egin da <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
     <string name="aerr_process" msgid="6201597323218674729">"Gelditu egin da <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
@@ -1182,7 +1177,7 @@
     <string name="wait" msgid="7147118217226317732">"Itxaron"</string>
     <string name="webpage_unresponsive" msgid="3272758351138122503">"Orriak ez du erantzuten.\n\nItxi egin nahi duzu?"</string>
     <string name="launch_warning_title" msgid="1547997780506713581">"Aplikazioa birbideratu da"</string>
-    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioa exekutatzen ari da."</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioa abian da."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioa lehenago abiarazi da."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Eskala"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"Erakutsi beti"</string>
@@ -1208,7 +1203,7 @@
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> prestatzen."</string>
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Aplikazioak abiarazten."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Bertsio-berritzea amaitzen."</string>
-    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> exekutatzen"</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> abian da"</string>
     <string name="heavy_weight_notification_detail" msgid="2304833848484424985">"Sakatu jokora itzultzeko"</string>
     <string name="heavy_weight_switcher_title" msgid="387882830435195342">"Aukeratu joko bat"</string>
     <string name="heavy_weight_switcher_text" msgid="4176781660362912010">"Funtzionamendu hobea izateko, joko hauetako bat baino ezin da egon irekita aldi berean."</string>
@@ -1317,7 +1312,7 @@
     <string name="select_character" msgid="3365550120617701745">"Txertatu karakterea"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"SMS mezuak bidaltzen"</string>
     <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; SMS asko ari da bidaltzen. Mezuak bidaltzen jarrai dezan onartu nahi duzu?"</string>
-    <string name="sms_control_yes" msgid="3663725993855816807">"Onartu"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"Baimendu"</string>
     <string name="sms_control_no" msgid="625438561395534982">"Ukatu"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioak mezu bat bidali nahi du &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; helbidera."</string>
     <string name="sms_short_code_details" msgid="5873295990846059400">"Baliteke horrek mugikorreko kontuan "<b>"gastuak eragitea"</b>"."</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Likidoa edo zikinkeriak daude USB atakan"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ataka automatikoki desgaitu da. Informazio gehiago lortzeko, sakatu hau."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Erabiltzeko moduan dago USB ataka"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonoak ez du hautematen likidorik edo zikinkeriarik."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Akatsen txostena sortzen…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Akatsen txostena partekatu nahi duzu?"</string>
@@ -1447,13 +1441,13 @@
     <string name="ime_action_next" msgid="3138843904009813834">"Hurrengoa"</string>
     <string name="ime_action_done" msgid="8971516117910934605">"Eginda"</string>
     <string name="ime_action_previous" msgid="1443550039250105948">"Atzera"</string>
-    <string name="ime_action_default" msgid="2840921885558045721">"Exekutatu"</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"Abiarazi"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"Markatu zenbakia \n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"Sortu kontaktua\n<xliff:g id="NUMBER">%s</xliff:g> erabilita"</string>
     <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Aplikazio hauetako bat edo gehiago kontua orain eta etorkizunean atzitzeko baimena eskatzen ari dira."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Eskaera onartu nahi duzu?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"Sarbide-eskaera"</string>
-    <string name="allow" msgid="7225948811296386551">"Onartu"</string>
+    <string name="allow" msgid="7225948811296386551">"Baimendu"</string>
     <string name="deny" msgid="2081879885755434506">"Ukatu"</string>
     <string name="permission_request_notification_title" msgid="6486759795926237907">"Baimena eskatu da"</string>
     <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Baimena eskatu da \n<xliff:g id="ACCOUNT">%s</xliff:g> konturako."</string>
@@ -1555,9 +1549,9 @@
     <string name="storage_internal" msgid="3570990907910199483">"Barneko biltegiratze partekatua"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD txartela"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD txartela"</string>
-    <string name="storage_usb_drive" msgid="6261899683292244209">"USB unitatea"</string>
-    <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB unitatea"</string>
-    <string name="storage_usb" msgid="3017954059538517278">"USB memoria"</string>
+    <string name="storage_usb_drive" msgid="6261899683292244209">"USB bidezko unitatea"</string>
+    <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> enpresaren USB bidezko unitatea"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB bidezko memoria"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Editatu"</string>
     <string name="data_usage_warning_title" msgid="6499834033204801605">"Datuen erabileraren abisua"</string>
     <string name="data_usage_warning_body" msgid="7340198905103751676">"<xliff:g id="APP">%s</xliff:g> erabili dituzu"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Arakatzailea abiarazi nahi duzu?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Deia onartu nahi duzu?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Beti"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Ezarri beti irekitzeko"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Behin soilik"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Ezarpenak"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s abiarazleak ez du laneko profil hau onartzen"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"<xliff:g id="ID">%1$d</xliff:g>. gainjartzea"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segurua"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> paketearen atzeko planoko jardueraren abio hau blokeatu egingo da Q bertsioaren etorkizuneko konpilazioetan. Joan g.co/dev/bgblock helbidera."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Blokeatu da <xliff:g id="PACKAGENAME">%1$s</xliff:g> paketearen atzeko planoko jardueraren abioa. Joan g.co/dev/bgblock helbidera."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Eredua ahaztu zaizu"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Eredu okerra"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pasahitz okerra"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Erabilerraztasun-lasterbideak <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu du"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Erabilerraztasun-lasterbideak <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu du"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> erabiltzeko, eduki sakatuta bolumen-tekla biak hiru segundoz"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Eginbideak aldatzeko, eduki sakatuta Erabilerraztasuna botoia."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Aukeratu zer zerbitzu erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Aukeratu zer zerbitzu erabili nahi duzun erabilerraztasun-keinua egitean (hau da, bi hatz pantailaren behealdetik gora pasatzean):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Aukeratu zer zerbitzu erabili nahi duzun erabilerraztasun-keinua egitean (hau da, hiru hatz pantailaren behealdetik gora pasatzean):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Zerbitzu batetik bestera aldatzeko, eduki sakatuta Erabilerraztasuna botoia."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Zerbitzu batetik bestera aldatzeko, pasatu bi hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Zerbitzu batetik bestera aldatzeko, pasatu hiru hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Lupa"</string>
     <string name="user_switched" msgid="3768006783166984410">"Uneko erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> erabiltzailera aldatzen…"</string>
@@ -1851,7 +1848,7 @@
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte"</string>
     <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte (hurrengo alarma)"</string>
-    <string name="zen_mode_forever" msgid="931849471004038757">"Desaktibatu arte"</string>
+    <string name="zen_mode_forever" msgid="931849471004038757">"Zuk desaktibatu arte"</string>
     <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"\"Ez molestatu\" desaktibatzen duzun arte"</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"Tolestu"</string>
@@ -1910,7 +1907,7 @@
     <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"Aplikazioa Android-en bertsio zaharrago baterako sortu zenez, baliteke behar bezala ez funtzionatzea. Bilatu eguneratzerik baden, edo jarri garatzailearekin harremanetan."</string>
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Bilatu eguneratzeak"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Mezu berriak dituzu"</string>
-    <string name="new_sms_notification_content" msgid="7002938807812083463">"Mezuak ikusteko, ireki SMS mezuen aplikazioa"</string>
+    <string name="new_sms_notification_content" msgid="7002938807812083463">"Mezuak ikusteko, ireki SMS mezuetarako aplikazioa"</string>
     <string name="profile_encrypted_title" msgid="4260432497586829134">"Baliteke funtzio batzuk mugatuta egotea"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Blokeatuta dago laneko profila"</string>
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Sakatu profila desblokeatzeko"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d8582ff..48cdafc 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -42,11 +42,11 @@
     <string name="serviceErased" msgid="1288584695297200972">"پاک کردن با موفقیت انجام شد."</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"گذرواژه اشتباه است."</string>
     <string name="mmiComplete" msgid="8232527495411698359">"‏MMI کامل شد."</string>
-    <string name="badPin" msgid="9015277645546710014">"‏پین قدیمی که نوشته‎اید صحیح نیست."</string>
+    <string name="badPin" msgid="9015277645546710014">"این پین قدیمی که نوشتید صحیح نیست."</string>
     <string name="badPuk" msgid="5487257647081132201">"‏PUK که نوشته‌اید صحیح نیست."</string>
     <string name="mismatchPin" msgid="609379054496863419">"‏پین‎هایی که وارد کرده‎اید با یکدیگر مطابقت ندارند."</string>
-    <string name="invalidPin" msgid="3850018445187475377">"یک پین بنویسید که 4 تا 8 رقم باشد."</string>
-    <string name="invalidPuk" msgid="8761456210898036513">"‏یک PUK با 8 رقم یا بیشتر تایپ کنید."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"یک پین بنویسید که ۴ تا ۸ رقم باشد."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"‏یک PUK با ۸ رقم یا بیشتر تایپ کنید."</string>
     <string name="needPuk" msgid="919668385956251611">"‏سیم کارت شما با PUK قفل شده است. کد PUK را برای بازگشایی آن بنویسید."</string>
     <string name="needPuk2" msgid="4526033371987193070">"‏PUK2 را برای بازگشایی قفل سیم کارت بنویسید."</string>
     <string name="enablePin" msgid="209412020907207950">"‏ناموفق بود، قفل سیم/RUIM را فعال کنید."</string>
@@ -73,8 +73,8 @@
     <string name="DndMmi" msgid="1265478932418334331">"مزاحم نشوید"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"پیش‌فرض شناسه تماس‌گیرنده روی محدود است. تماس بعدی: محدود"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"پیش‌فرض شناسه تماس‌گیرنده روی محدود است. تماس بعدی: بدون محدودیت"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"پیش‌فرض شناسه تماس‌گیرنده روی غیر محدود است. تماس بعدی: محدود"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"پیش‌فرض شناسه تماس‌گیرنده روی غیر محدود است. تماس بعدی: بدون محدودیت"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"پیش‌فرض شناسه تماس‌گیرنده روی غیرمحدود است. تماس بعدی: محدود"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"پیش‌فرض شناسه تماس‌گیرنده روی غیرمحدود است. تماس بعدی: بدون محدودیت"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"سرویس دارای مجوز نیست."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"‏شما می‎توانید تنظیم شناسه تماس‌گیرنده را تغییر دهید."</string>
     <string name="RestrictedOnDataTitle" msgid="5221736429761078014">"بدون سرویس داده تلفن همراه"</string>
@@ -103,7 +103,7 @@
     <string name="serviceClassData" msgid="872456782077937893">"داده"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"نمابر"</string>
     <string name="serviceClassSMS" msgid="2015460373701527489">"پیامک"</string>
-    <string name="serviceClassDataAsync" msgid="4523454783498551468">"غیر همگام"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"ناهمگام"</string>
     <string name="serviceClassDataSync" msgid="7530000519646054776">"همگام‌سازی"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"بسته"</string>
     <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏تماس ازطریق Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‏تماس Wi‑Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏تماس ازطریق WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏تماس ازطریق WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -153,7 +154,7 @@
     <string name="fcError" msgid="3327560126588500777">"مشکل در اتصال یا کد ویژگی نامعتبر."</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"تأیید"</string>
     <string name="httpError" msgid="7956392511146698522">"خطایی در شبکه وجود داشت."</string>
-    <string name="httpErrorLookup" msgid="4711687456111963163">"‏URL پیدا نشد."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"نشانی اینترنتی پیدا نشد."</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"‏طرح کلی احراز هویت سایت پشتیبانی نمی‌‎شود."</string>
     <string name="httpErrorAuth" msgid="1435065629438044534">"راستی‌آزمایی ناموفق بود."</string>
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"احراز هویت از طریق سرور پروکسی انجام نشد."</string>
@@ -163,10 +164,10 @@
     <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"این صفحه دارای تعداد بسیار زیادی تغییر مسیر سرور است."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"‏پروتکل پشتیبانی نمی‌‎شود."</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"اتصال امن ایجاد نشد."</string>
-    <string name="httpErrorBadUrl" msgid="3636929722728881972">"‏بدلیل نامعتبر بودن URL، باز کردن صفحه ممکن نیست."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"به‌دلیل نامعتبر بودن نشانی اینترنتی، صفحه باز نمی‌شود."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"دسترسی به فایل انجام نشد."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"فایل درخواستی پیدا نشد."</string>
-    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"درخواست‌های زیادی در حال پردازش است. بعداً دوباره امتحان کنید."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"درخواست‌های زیادی درحال پردازش است. بعداً دوباره امتحان کنید."</string>
     <string name="notification_title" msgid="8967710025036163822">"خطای ورود به سیستم برای <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
     <string name="contentServiceSync" msgid="8353523060269335667">"همگام‌سازی"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="7036196943673524858">"همگام‌سازی نشد"</string>
@@ -209,7 +210,7 @@
     <string name="reboot_to_update_reboot" msgid="6428441000951565185">"در حال راه‌اندازی مجدد…"</string>
     <string name="reboot_to_reset_title" msgid="4142355915340627490">"بازنشانی داده‌های کارخانه"</string>
     <string name="reboot_to_reset_message" msgid="2432077491101416345">"در حال راه‌اندازی مجدد…"</string>
-    <string name="shutdown_progress" msgid="2281079257329981203">"در حال خاموش شدن…"</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"درحال خاموش شدن…"</string>
     <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"رایانهٔ لوحی شما خاموش می‌شود."</string>
     <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"تلویزیون شما خاموش خواهد شد."</string>
     <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"ساعت شما خاموش می‌شود."</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"حالت خودرو"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"وضعیت حساب"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"پیام‌های برنامه‌نویس"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"پیام‌های مهم برنامه‌نویس"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"به‌روزرسانی‌ها"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"وضعیت شبکه"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"هشدارهای شبکه"</string>
@@ -398,7 +400,7 @@
     <string name="permlab_readCallLog" msgid="3478133184624102739">"خواندن گزارش تماس"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"این برنامه می‌تواند سابقه تماس شما را بخواند."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"نوشتن گزارش تماس"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"‏به برنامه اجازه می‌دهد گزارشات تماس رایانهٔ لوحی شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"‏به برنامه اجازه می‌دهد گزارش‌های تماس رایانهٔ لوحی شما، از جمله داده‌هایی درباره تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"‏به برنامه اجازه می‌دهد گزارشات تماس تلویزیون شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب شاید از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"‏به برنامه اجازه می‌دهد گزارشات تماس تلفنی شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"دسترسی به حسگرهای بدن (مانند پایشگرهای ضربان قلب)"</string>
@@ -500,7 +502,7 @@
     <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"به برنامه اجازه می‌دهد تا پیکربندی بلوتوث را در تلویزیون مشاهده کند و اتصالات را با دستگاه‌های مرتبط‌شده ایجاد کند و بپذیرد."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"‏به برنامه اجازه می‎دهد تا پیکربندی بلوتوث در تلفن را مشاهده کند، و اتصالات دستگاه‌های مرتبط را برقرار کرده و بپذیرد."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"کنترل ارتباط راه نزدیک"</string>
-    <string name="permdesc_nfc" msgid="7120611819401789907">"‏به برنامه اجازه می‎دهد تا با تگهای ارتباط میدان نزدیک (NFC)، کارتها و فایل خوان ارتباط برقرار کند."</string>
+    <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_requestPasswordComplexity" msgid="202650535669249674">"درخواست پیچیدگی قفل صفحه"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"نماد اثر انگشت"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"مدیریت سخت‌افزار «بازگشایی با چهره»"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"به برنامه امکان می‌دهد روش‌هایی را برای افزودن و حذف الگوهای چهره جهت استفاده فرابخواند."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"استفاده از سخت‌افزار «بازگشایی با چهره»"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"به برنامه امکان می‌دهد از سخت‌افزار «بازگشایی با چهره» برای احراز هویت استفاده کند"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"بازگشایی با چهره"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"ثبت مجدد چهره"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"برای بهبود تشخیص، لطفاً چهره‌تان را دوباره ثبت کنید"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"داده‌های دقیق چهره ضبط نشد. دوباره امتحان کنید."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"تلفن را به‌سمت چپ حرکت دهید."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"تلفن را به سمت راست حرکت دهید."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"لطفاً مستقیم به دستگاه نگه کنید."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"چهره‌تان دیده نمی‌شود. به تلفن نگاه کنید."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"صورتتان را مستقیماً روبروی تلفن قرار دهید."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"حرکت خیلی زیاد است. تلفن را ثابت نگه‌دارید."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"لطفاً چهره‌تان را مجدداً ثبت کنید."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"دیگر چهره را تشخیص نمی‌دهد. دوباره امتحان کنید."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"سرتان را کمی پایین آورید."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"سرتان را کمی پایین آورید."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"هرچیزی را که حائل چهره‌تان است بردارید."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"حسگر واقع در لبه بالای صفحه را تمیز کنید."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"بالای صفحه و همچنین نوار مشکی را تمیز کنید."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"چهره تأیید نشد. سخت‌افزار در دسترس نیست."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"«بازگشایی با چهره» را دوباره امتحان کنید."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"داده‌ چهره جدید ذخیره نشد. اول داده‌ چهره قدیمی را حذف کنید."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"عملیات شناسایی چهره لغو شد."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"کاربر «بازگشایی با چهره» را لغو کرد."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"تعداد زیادی تلاش ناموفق. بعداً دوباره امتحان کنید."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"تعداد تلاش‌ها بیش‌ازحد مجاز است. «بازگشایی با چهره» غیرفعال است."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"چهره تأیید نشد. دوباره امتحان کنید."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"«بازگشایی با چهره» را راه‌اندازی نکرده‌اید."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"«بازگشایی با چهره» در این دستگاه پشتیبانی نمی‌شود."</string>
     <string name="face_name_template" msgid="7004562145809595384">"چهره <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -664,7 +657,7 @@
     <string name="policylab_watchLogin" msgid="5091404125971980158">"پایش تلاش‌های باز کردن قفل صفحه"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"‏تعداد گذرواژه‎های نادرست تایپ شده را هنگام بازکردن قفل صفحه کنترل می‌کند، و اگر دفعات زیادی گذرواژه نادرست وارد شود رایانهٔ لوحی را قفل می‌کند و همه داده‎های رایانهٔ لوحی را پاک می‌کند."</string>
     <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"بر تعداد گذرواژه‌های نادرست تایپ‌شده در زمان باز کردن قفل صفحه نظارت کنید و اگر تعدا زیادی گذرواژه‌های اشتباه تایپ شده است، تلویزیون را قفل کنید یا همه داده‌های تلویزیون را پاک کنید."</string>
-    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"‏تعداد گذرواژه‎های نادرست تایپ شده را هنگام بازکردن قفل صفحه کنترل می‎کند. اگر دفعات زیادی گذرواژه نادرست وارد شود، تلفن را قفل می‌کند یا همه داده‎های تلفن را پاک می‌کند."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"‏تعداد گذرواژه‎های نادرست تایپ‌شده را هنگام بازکردن قفل صفحه کنترل می‎کند و اگر چندین بار گذرواژه‌های نادرست وارد شود، تلفن را قفل می‌کند یا همه داده‎های تلفن را پاک می‌کند."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"بر تعداد گذرواژه‌های نادرستی که هنگام باز کردن قفل صفحه تایپ شده، نظارت می‌کند، و اگر تعداد گذرواژه‌های تایپ شده نادرست بیش از حد بود، رایانه لوحی را قفل می‌کند یا کلیه داده‌های کاربر را پاک می‌کند."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"بر تعداد گذرواژه‌های نادرستی که هنگام باز کردن قفل صفحه تایپ شده، نظارت می‌کند، و اگر تعداد گذرواژه‌های تایپ شده نادرست بیش از حد بود، تلویزیون را قفل می‌کند یا کلیه داده‌های کاربر را پاک می‌کند."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"بر تعداد گذرواژه‌های نادرستی که هنگام باز کردن قفل صفحه تایپ شده، نظارت می‌کند، و اگر تعداد گذرواژه‌های تایپ شده نادرست بیش از حد بود، تلفن را قفل می‌کند یا کلیه داده‌های کاربر را پاک می‌کند."</string>
@@ -686,7 +679,7 @@
     <string name="policydesc_expirePassword" msgid="5367525762204416046">"تغییر تعداد دفعاتی که گذرواژه، پین یا الگوی قفل صفحه باید تغییر کند."</string>
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"تنظیم رمزگذاری حافظه"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"اطلاعات ذخیره شده برنامه باید رمزگذاری شود."</string>
-    <string name="policylab_disableCamera" msgid="6395301023152297826">"غیر فعال کردن دوربین ها"</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"غیرفعال کردن دوربین‌ها"</string>
     <string name="policydesc_disableCamera" msgid="2306349042834754597">"جلوگیری از استفاده از همه دوربین‌های دستگاه."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"غیرفعال کردن ویژگی‌های قفل صفحه"</string>
     <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"مانع استفاده از برخی ویژگی‌های قفل صفحه می‌شود."</string>
@@ -825,7 +818,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"دوباره امتحان کنید"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"دوباره امتحان کنید"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"باز کردن قفل تمام قابلیت‌ها و داده‌ها"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"‏دفعات تلاش برای Face Unlock از حداکثر مجاز بیشتر شد"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"دفعات تلاش برای «بازگشایی با چهره» از حداکثر مجاز بیشتر شد"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"سیم کارت موجود نیست"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"سیم کارت درون رایانهٔ لوحی نیست."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"سیم‌کارتی در تلویزیون وجود ندارد."</string>
@@ -846,7 +839,7 @@
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"‏سیم کارت با PUK قفل شده است."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"لطفاً به راهنمای کاربر مراجعه کرده یا با مرکز پشتیبانی از مشتریان تماس بگیرید."</string>
     <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"سیم کارت قفل شد."</string>
-    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"بازگشایی قفل سیم کارت..."</string>
+    <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"بازگشایی قفل سیم کارت…"</string>
     <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"‏الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‎اید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"گذرواژهٔ خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کرده‌اید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"‏پین را<xliff:g id="NUMBER_0">%1$d</xliff:g>  بار اشتباه تایپ کرده‎اید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
@@ -858,7 +851,7 @@
     <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از<xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، تلفن به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"شما به اشتباه اقدام به باز کردن قفل <xliff:g id="NUMBER">%d</xliff:g> رایانهٔ لوحی کرده‌اید. رایانهٔ لوحی در حال حاضر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
     <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"<xliff:g id="NUMBER">%d</xliff:g> دفعه به صورت نادرست سعی کرده‌اید قفل تلویزیون را باز کنید. اکنون تلویزیون به تنظیمات پیش‌فرض کارخانه بازنشانی خواهد شد."</string>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. این تلفن در حال حاضر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"به‌اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. این تلفن دیگر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"پس از <xliff:g id="NUMBER">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"الگو را فراموش کرده‌اید؟"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"بازگشایی قفل حساب"</string>
@@ -869,7 +862,7 @@
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ورود به سیستم"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"نام کاربر یا گذرواژه نامعتبر است."</string>
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"‏نام کاربری یا گذرواژهٔ خود را فراموش کردید؟\nاز "<b>"google.com/accounts/recovery"</b>" بازدید کنید."</string>
-    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"در حال بررسی..."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"درحال بررسی…"</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"بازگشایی قفل"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"صدا روشن"</string>
     <string name="lockscreen_sound_off_label" msgid="996822825154319026">"صدا خاموش"</string>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"گسترده کردن منطقه بازگشایی شده."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"باز کردن قفل با کشیدن انگشت روی صفحه."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"باز کردن قفل با الگو."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"باز کردن قفل با چهره."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"بازگشایی با چهره."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"باز کردن قفل با پین."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"قفل پین سیم‌کارت باز شد."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"‏قفل Puk سیم‌کارت باز شد."</string>
@@ -1085,7 +1078,7 @@
     <string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"در بریده‌دان کپی نشد"</string>
     <string name="paste" msgid="5629880836805036433">"جای‌گذاری"</string>
     <string name="paste_as_plain_text" msgid="5427792741908010675">"جای‌گذاری به عنوان متن ساده"</string>
-    <string name="replace" msgid="5781686059063148930">"جایگزین شود..."</string>
+    <string name="replace" msgid="5781686059063148930">"جایگزین شود…"</string>
     <string name="delete" msgid="6098684844021697789">"حذف"</string>
     <string name="copyUrl" msgid="2538211579596067402">"‏کپی URL"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"انتخاب متن"</string>
@@ -1129,7 +1122,7 @@
     <string name="yes" msgid="5362982303337969312">"تأیید"</string>
     <string name="no" msgid="5141531044935541497">"لغو"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"توجه"</string>
-    <string name="loading" msgid="7933681260296021180">"در حال بارکردن…"</string>
+    <string name="loading" msgid="7933681260296021180">"درحال بارکردن…"</string>
     <string name="capital_on" msgid="1544682755514494298">"روشن"</string>
     <string name="capital_off" msgid="6815870386972805832">"خاموش"</string>
     <string name="whichApplication" msgid="4533185947064773386">"تکمیل عملکرد با استفاده از"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"باز کردن با"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"‏باز کردن با %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"باز کردن"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ارائه دسترسی برای باز کردن پیوندهای <xliff:g id="HOST">%1$s</xliff:g> با"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"ارائه دسترسی برای باز کردن پیوندهای <xliff:g id="HOST">%1$s</xliff:g> با<xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"باز کردن پیوندهای <xliff:g id="HOST">%1$s</xliff:g> با"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"باز کردن پیوندها با"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"باز کردن پیوندها با <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"باز کردن پیوندهای <xliff:g id="HOST">%1$s</xliff:g> با <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ارائه دسترسی"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ویرایش با"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"‏ویرایش با %1$s"</string>
@@ -1206,8 +1201,8 @@
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> درحال ارتقا است...."</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"در حال بهینه‌سازی برنامهٔ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"آماده‌سازی <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
-    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"در حال آغاز برنامه‌ها."</string>
-    <string name="android_upgrading_complete" msgid="1405954754112999229">"در حال اتمام راه‌اندازی."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"درحال آغاز کردن برنامه‌ها."</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"درحال اتمام راه‌اندازی."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> در حال اجرا"</string>
     <string name="heavy_weight_notification_detail" msgid="2304833848484424985">"برای برگشت به بازی، ضربه بزنید"</string>
     <string name="heavy_weight_switcher_title" msgid="387882830435195342">"انتخاب بازی"</string>
@@ -1314,8 +1309,8 @@
     <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"‏در حالی که تلویزیون به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> متصل است، ارتباط آن به صورت موقت از Wi-Fi قطع خواهد شد."</string>
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"‏این گوشی به‌طور موقت از Wi-Fi قطع خواهد شد، در حالی که به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> وصل است"</string>
     <string name="select_character" msgid="3365550120617701745">"درج نویسه"</string>
-    <string name="sms_control_title" msgid="7296612781128917719">"ارسال پیامک ها"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; در حال ارسال تعداد زیادی پیامک است. آیا اجازه می‌دهید این برنامه همچنان پیامک ارسال کند؟"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"درحال ارسال پیامک‌ها"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; درحال ارسال تعداد زیادی پیامک است. آیا اجازه می‌دهید این برنامه همچنان پیامک ارسال کند؟"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"مجاز است"</string>
     <string name="sms_control_no" msgid="625438561395534982">"اجازه ندارد"</string>
     <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; مایل است پیامی به &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; ارسال کند."</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"برای غیرفعال کردن «حالت مجموعه داده‌های تست»، بازنشانی کارخانه‌ای کنید."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏مایعات یا خاکروبه در درگاه USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏درگاه USB به‌طور خودکار غیرفعال شده است. برای اطلاعات بیشتر، ضربه بزنید."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"‏می‌توان از درگاه USB استفاده کرد"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"تلفن دیگر وجود مایعات یا خاکروبه را تشخیص نمی‌دهد."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"درحال گرفتن گزارش اشکال…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"گزارش اشکال به اشتراک گذاشته شود؟"</string>
@@ -1468,7 +1462,7 @@
     <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"ارائه‌دهنده وضعیت"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"سرویس رتبه‌بندی اعلان"</string>
     <string name="vpn_title" msgid="19615213552042827">"‏VPN فعال شد"</string>
-    <string name="vpn_title_long" msgid="6400714798049252294">"‏VPN توسط <xliff:g id="APP">%s</xliff:g> فعال شده است"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"‏VPN را <xliff:g id="APP">%s</xliff:g> فعال کرده است"</string>
     <string name="vpn_text" msgid="1610714069627824309">"برای مدیریت شبکه ضربه بزنید."</string>
     <string name="vpn_text_long" msgid="4907843483284977618">"به <xliff:g id="SESSION">%s</xliff:g> متصل شد. برای مدیریت شبکه ضربه بزنید."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"‏در حال اتصال VPN همیشه فعال…"</string>
@@ -1502,13 +1496,13 @@
     <string name="websearch" msgid="4337157977400211589">"جستجوی وب"</string>
     <string name="find_next" msgid="5742124618942193978">"یافتن بعدی"</string>
     <string name="find_previous" msgid="2196723669388360506">"یافتن قبلی"</string>
-    <string name="gpsNotifTicker" msgid="5622683912616496172">"درخواست موقعیت مکانی از <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"درخواست موقعیت مکانی"</string>
-    <string name="gpsNotifMessage" msgid="1374718023224000702">"درخواست شده توسط <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"درخواست مکان از <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"درخواست مکان"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"درخواست‌کننده <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"بله"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"نه"</string>
     <string name="sync_too_many_deletes" msgid="5296321850662746890">"از حد مجاز حذف فراتر رفت"</string>
-    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"‏<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذف شده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. می‎خواهید چه کاری انجام دهید؟"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"‏<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذف‌شده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. می‎خواهید چه کار بکنید؟"</string>
     <string name="sync_really_delete" msgid="2572600103122596243">"حذف موارد"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"واگرد موارد حذف شده"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"اکنون کاری انجام نشود"</string>
@@ -1573,11 +1567,11 @@
     <string name="data_usage_rapid_app_body" msgid="5396680996784142544">"<xliff:g id="APP">%s</xliff:g> بیش از معمول داده مصرف کرده است"</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"گواهی امنیتی"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"این گواهی معتبر است."</string>
-    <string name="issued_to" msgid="454239480274921032">"صادر شده برای:"</string>
+    <string name="issued_to" msgid="454239480274921032">"صادرشده برای:"</string>
     <string name="common_name" msgid="2233209299434172646">"نام معمولی:"</string>
     <string name="org_name" msgid="6973561190762085236">"سازمان:"</string>
     <string name="org_unit" msgid="7265981890422070383">"واحد سازمانی:"</string>
-    <string name="issued_by" msgid="2647584988057481566">"صادر شده توسط:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"صادرکننده:"</string>
     <string name="validity_period" msgid="8818886137545983110">"اعتبار:"</string>
     <string name="issued_on" msgid="5895017404361397232">"صادر شده در:"</string>
     <string name="expires_on" msgid="3676242949915959821">"تاریخ انقضا:"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"مرورگر راه‌اندازی شود؟"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"تماس را می‌پذیرید؟"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"همیشه"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"تنظیم روی همیشه باز شدن"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"فقط این بار"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"تنظیمات"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"‏%1$s از نمایه کاری پشتیبانی نمی‌کند"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"هم‌پوشانی #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"، امن"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‏شروع فعالیت پس‌زمینه<xliff:g id="PACKAGENAME">%1$s</xliff:g> در نسخه‌های Q آینده مسدود خواهد شد. به g.co/dev/bgblock مراجعه کنید."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‏شروع فعالیت پس‌زمینه <xliff:g id="PACKAGENAME">%1$s</xliff:g> مسدود شده است. به g.co/dev/bgblock مراجعه کنید."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"الگو را فراموش کرده‌اید"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"الگوی اشتباه"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"گذرواژه اشتباه"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"«میان‌بر دسترس‌پذیری» <xliff:g id="SERVICE_NAME">%1$s</xliff:g> را روشن کرد"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"«میان‌بر دسترس‌پذیری» <xliff:g id="SERVICE_NAME">%1$s</xliff:g> را خاموش کرد"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"برای استفاده از <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید صدا را فشار دهید و سه ثانیه نگه دارید"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"قابلیتی را انتخاب کنید که هنگام ضربه زدن روی دکمه «دسترس‌پذیری» استفاده می‌شود:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"برای تغییر دادن قابلیت‌ها، دکمه «دسترس‌پذیری» را لمس کنید و نگه‌دارید."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"سرویسی را انتخاب کنید که می‌خواهید هنگام ضربه زدن روی دکمه دسترس‌پذیری استفاده شود:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"سرویسی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با دو انگشت صفحه را از پایین تند به بالا بکشید):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"سرویسی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با سه انگشت صفحه را از پایین تند به بالا بکشید):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"برای جابه‌جایی بین سرویس‌ها، دکمه دسترس‌پذیری را لمس کنید و نگه‌دارید."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"برای جابه‌جایی بین سرویس‌ها، با دو انگشت صفحه را تند به بالا بکشید و نگه‌دارید."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"برای جابه‌جایی بین سرویس‌ها، با سه انگشت صفحه را تند به بالا بکشید و نگه‌دارید."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"درشت‌نمایی"</string>
     <string name="user_switched" msgid="3768006783166984410">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"در حالت تغییر به <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 921788f..cd9a711 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-puhelut (<xliff:g id="SPN">%s</xliff:g>)"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-puhelut"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-puhelu"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-puhelu (<xliff:g id="SPN">%s</xliff:g>)"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Autotila"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Tilin tila"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Kehittäjien viestit"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Tärkeät kehittäjäviestit"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Päivitykset"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Verkon tila"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Verkkoilmoitukset"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Sormenjälkikuvake"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"hallinnoida Face Unlock ‑laitteistoa"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Sallii sovelluksen käyttää menetelmiä, joilla voidaan lisätä tai poistaa kasvomalleja."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"käyttää Face Unlock ‑laitteistoa"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Sallii sovelluksen käyttää Face Unlock ‑laitteistoa todennukseen"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face Unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Lisää kasvot uudelleen"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Lisää kasvosi uudelleen tunnistamisen parantamiseksi"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Tarkan kasvodatan tallennus epäonnistui. Yritä uudelleen."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Siirrä puhelinta vasemmalle."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Siirrä puhelinta oikealle."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Katso suoremmin laitteeseen."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Kasvojasi ei näy. Katso puhelinta."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Aseta kasvosi suoraan puhelimen eteen."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Laite liikkui liikaa. Pidä puhelin vakaana."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Rekisteröi kasvot uudelleen."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ei enää tunnista kasvoja. Yritä uudelleen."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Käännä päätä vähän vähemmän."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Käännä päätä vähän vähemmän."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Poista esteet kasvojesi edestä."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Puhdista näytön yläreunassa oleva anturi."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Puhdista näytön yläreuna, mukaan lukien musta palkki"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Kasvoja ei voi vahvistaa. Laitteisto ei käytettäv."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Yritä käyttää Face Unlockia uudelleen."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Uutta kasvodataa ei voi tallentaa. Poista ensin vanhaa."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Kasvotoiminto peruutettu"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Käyttäjä peruutti Face Unlockin."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Liian monta yritystä. Yritä myöhemmin uudelleen."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Liian monta yritystä. Face Unlock poistettu käytöstä."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Kasvoja ei voi vahvistaa. Yritä uudelleen."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Et ole määrittänyt Face Unlockia."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Tämä laite ei tue Face Unlockia."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Kasvot <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Avaa sovelluksessa"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Avaa sovelluksessa %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Avaa"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Salli linkkien (<xliff:g id="HOST">%1$s</xliff:g>) avaaminen:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Salli linkkien (<xliff:g id="HOST">%1$s</xliff:g>) avaaminen: <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g>-linkit avataan:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Linkit avataan:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> avaa linkit"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> avaa linkit (<xliff:g id="HOST">%1$s</xliff:g>)"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Salli"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Muokkaa sovelluksessa"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Muokkaa sovelluksessa %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Palauta tehdasasetukset, niin voit poistaa testikehystilan käytöstä."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-portin käyttö on sallittu"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Puhelin ei enää havaitse nesteitä eikä likaa."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Luodaan virheraporttia…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Jaetaanko virheraportti?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vastataanko puheluun?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Aina"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Avaa aina"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Vain kerran"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Asetukset"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ei tue työprofiilia"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Peittokuva # <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", suojattu"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Tämä taustatoiminnan käynnistys kohteesta <xliff:g id="PACKAGENAME">%1$s</xliff:g> estetään tulevissa Q-versioissa. Siirry osoitteeseen g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Taustatoiminnan käynnistys kohteesta <xliff:g id="PACKAGENAME">%1$s</xliff:g> estettiin. Siirry osoitteeseen g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Unohtunut kuvio"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Väärä kuvio"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Väärä salasana"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> otettiin käyttöön esteettömyystilan pikanäppäimellä."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> poistettiin käytöstä esteettömyystilan pikanäppäimellä."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Voit käyttää palvelua <xliff:g id="SERVICE_NAME">%1$s</xliff:g> painamalla molempia äänenvoimakkuuspainikkeita kolmen sekunnin ajan"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Valitse toiminto, jonka Esteettömyys-painike aktivoi:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Jos haluat muokata ominaisuuksia, kosketa Esteettömyys-painiketta pitkään."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Valitse palvelu, jonka esteettömyyspainike aktivoi:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Valitse palvelu, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kahdella sormella):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Valitse palvelu, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kolmella sormella):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Vaihda palveluiden välillä painamalla painiketta pitkään."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Vaihda palveluiden välillä pyyhkäisemällä ylös kahdella sormella ja koskettamalla pitkään."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Vaihda palveluiden välillä pyyhkäisemällä ylös kolmella sormella ja koskettamalla pitkään."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Suurennus"</string>
     <string name="user_switched" msgid="3768006783166984410">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Vaihdetaan käyttäjään <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 8f99e3d..2bfef39 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Appels Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Appels Wi-Fi : <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Appel WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Appel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Mode Voiture"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"État du compte"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Messages des concepteurs"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Messages importants à l\'intention des concepteurs"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Mises à jour"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"État du réseau"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertes réseau"</string>
@@ -307,7 +309,7 @@
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à accéder à vos journaux d\'appels?"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Téléphone"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"faire et gérer des appels téléphoniques"</string>
-    <string name="permgrouprequest_phone" msgid="9166979577750581037">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à faire et à gérer les appels téléphoniques?"</string>
+    <string name="permgrouprequest_phone" msgid="9166979577750581037">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à faire et à gérer des appels téléphoniques?"</string>
     <string name="permgrouplab_sensors" msgid="4838614103153567532">"Capteurs corporels"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"accéder aux données des capteurs sur vos signes vitaux"</string>
     <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à accéder aux données des capteurs pour vos signes vitaux?"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icône d\'empreinte digitale"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gérer le matériel de déverrouillage par reconnaissance faciale"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permet à l\'appli d\'employer des méthodes d\'aj. et de suppr. de modèles de reconn. visage."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utiliser le matériel de déverrouillage par reconnaissance faciale"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permet à l\'appli d\'utiliser du matériel de déverr. par reconn faciale pour l\'authentific."</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Déverrouillage par reconnaissance faciale"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Inscrivez votre visage à nouveau"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Pour améliorer la reconnaissance, veuillez enregistrer à nouveau votre visage"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Imposs. capt. données visage précises. Réessayez."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Déplacez le téléphone vers la gauche."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Déplacez le téléphone vers la droite."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Veuillez regarder plus directement votre appareil."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Impossible de voir votre visage. Regardez le tél."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Placez votre visage directement devant le téléphone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Trop de mouvement. Tenez le téléphone immobile."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Veuillez inscrire votre visage à nouveau."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ce visage ne sera plus reconnu. Réessayez."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Tournez un peu moins votre tête."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Tournez un peu moins votre tête."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Retirez tout ce qui pourrait couvrir votre visage."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Nettoyez le capteur dans le haut de l\'écran."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Nettoyez le haut de l\'écran, y compris la barre noire"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Imposs. de vérif. visage. Matériel non accessible."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Réessayez le déverr. par reconnaissance faciale."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Impossible de stocker de nouveaux visages. Supprimez-en un."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Opération de reconnaissance du visage annulée."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Déverr. par reconn. faciale annulé par l\'utilisateur."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Trop de tentatives. Veuillez réessayer plus tard."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Trop de tentatives. Le déverr. par reconnaissance faciale est désactivé."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Impossible de vérifier le visage. Réessayez."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Vous n\'avez pas config. le déverr. par reconn. faciale."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Cet appar. ne prend pas en charge le déverr. par reconn. faciale."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Ouvrir avec"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Ouvrir avec %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Ouvrir"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Accorder l\'accès pour ouvrir les liens de <xliff:g id="HOST">%1$s</xliff:g> avec"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Accorder l\'accès pour ouvrir les liens de <xliff:g id="HOST">%1$s</xliff:g> avec <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Ouvrir les liens <xliff:g id="HOST">%1$s</xliff:g> avec"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Ouvrir les liens avec"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Ouvrir les liens avec <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Ouvrir les liens <xliff:g id="HOST">%1$s</xliff:g> avec <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Accorder l\'accès"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Modifier avec"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Modifier avec %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Effectuez une réinitialisation pour désactiver le mode Logiciel de test."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Liquide ou débris dans le port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Touchez ici pour en savoir plus."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Autorisation d\'utiliser le port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Le téléphone ne détecte plus les liquides ni les débris."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création d\'un rapport de bogue en cours..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bogue?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Définir cette activité comme toujours ouverte"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Une seule fois"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Paramètres"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ne prend pas en charge le profil professionnel"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposition n° <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sécurisé"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ce lancement d\'activité en arrière-plan par <xliff:g id="PACKAGENAME">%1$s</xliff:g> sera bloqué dans les versions futures de Q. Consultez la page g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Le lancement d\'une activité en arrière-plan par <xliff:g id="PACKAGENAME">%1$s</xliff:g> a été bloqué. Consultez la page g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Le raccourci d\'accessibilité a activé la fonction <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Le raccourci d\'accessibilité a désactivé la fonction <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Maintenez enfoncées les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choisissez une fonctionnalité à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pour changer des fonctionnalités, maintenez le doigt sur le bouton d\'accessibilité."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choisissez un service à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choisissez un service à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer deux doigts du bas de l\'écran vers le haut) :"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choisissez un service à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer trois doigts du bas de l\'écran vers le haut) :"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Pour basculer entre les services, maintenez le doigt sur le bouton d\'accessibilité."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Pour basculer entre les services, balayez deux doigts vers le haut et maintenez-les sur l\'écran."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Pour changer de service, balayez trois doigts vers le haut et maintenez-les sur l\'écran."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zoom"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Changement d\'utilisateur (<xliff:g id="NAME">%1$s</xliff:g>) en cours…"</string>
@@ -1910,7 +1907,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Vérifier la présence de mises à jour"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Vous avez de nouveaux messages"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Ouvrez l\'application de messagerie texte pour l\'afficher"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Certaines fonctionnal. sont limitées"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Des fonctionnalités sont limitées"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil professionnel verrouillé"</string>
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Touch. pr déver. profil profess."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connecté à <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index b55f297..041668f 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Appels Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Appels Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Appel WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Appel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Mode Voiture"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"État du compte"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Messages relatifs aux développeurs"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Messages importants relatifs aux développeurs"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Mises à jour"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"État du réseau"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertes réseau"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icône d\'empreinte digitale"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gérer les composants de Face Unlock"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Autorise l\'appli à invoquer des méthodes pour ajouter et supprimer des modèles de visages."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utiliser les composants de Face Unlock"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Autorise l\'application à utiliser les composants de Face Unlock pour l\'authentification"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face Unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Enregistrer à nouveau votre visage"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Pour améliorer la reconnaissance, veuillez enregistrer à nouveau votre visage"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Capture du visage impossible. Réessayez."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Déplacez le téléphone vers la gauche."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Déplacez le téléphone vers la droite."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Veuillez regarder plus directement l\'appareil."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Visage non détecté. Regardez le téléphone."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Placez votre visage en face du téléphone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Trop de mouvement. Ne bougez pas le téléphone."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Veuillez enregistrer à nouveau votre visage."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Impossible de reconnaître le visage. Réessayez."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Tournez un peu moins la tête."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Tournez un peu moins la tête."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Retirez tout ce qui cache votre visage."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Nettoyez le capteur en haut de l\'écran."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Nettoyez la partie supérieure de l\'écran, y compris la barre noire"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Imposs. valider visage. Matériel non disponible."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Réessayez d\'activer Face Unlock."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Impossible stocker nouv. visages. Veuillez en supprimer un."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Opération de reconnaissance faciale annulée."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Face Unlock annulé par l\'utilisateur."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Trop de tentatives. Réessayez plus tard."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Tentatives trop nombreuses. Désactivation de Face Unlock."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Impossible de valider votre visage. Réessayez."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Face Unlock n\'est pas configuré."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face Unlock n\'est pas compatible avec cet appareil."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Visage <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Ouvrir avec"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Ouvrir avec %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Ouvrir"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Autoriser l\'ouverture des liens <xliff:g id="HOST">%1$s</xliff:g> avec"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Autoriser l\'ouverture des liens <xliff:g id="HOST">%1$s</xliff:g> avec <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Ouvrir les liens <xliff:g id="HOST">%1$s</xliff:g> avec"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Ouvrir les liens avec"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Ouvrir les liens avec <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Ouvrir les liens <xliff:g id="HOST">%1$s</xliff:g> avec <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Accorder l\'accès"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Modifier avec"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Modifier avec %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rétablissez la configuration d\'usine pour désactiver le mode Atelier de test."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Présence de liquide ou de saletés dans le port USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Appuyez sur cette notification pour en savoir plus."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Autoriser l\'utilisation du port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Le téléphone ne détecte plus les liquides ni les saletés."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création du rapport de bug…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bug ?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Définir cette activité comme toujours ouverte"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Une seule fois"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Paramètres"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s n\'est pas compatible avec le profil professionnel."</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposition n° <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sécurisé"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Le démarrage de cette activité en arrière-plan de <xliff:g id="PACKAGENAME">%1$s</xliff:g> sera bloqué dans les prochaines builds Q. Consultez g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Le démarrage de l\'activité en arrière-plan de <xliff:g id="PACKAGENAME">%1$s</xliff:g> a été bloqué. Consultez g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"J\'ai oublié le schéma"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Schéma incorrect."</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Mot de passe incorrect."</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Le raccourci d\'accessibilité a activé <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Le raccourci d\'accessibilité a désactivé <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Appuyez de manière prolongée sur les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Choisissez une fonctionnalité à utiliser lorsque vous appuyez sur le bouton Accessibilité :"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pour changer de fonctionnalités, appuyez de manière prolongée sur le bouton Accessibilité."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Choisissez un service à utiliser lorsque vous appuyez sur le bouton Accessibilité :"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Choisissez un service à utiliser avec le geste d\'accessibilité (balayez l\'écran de bas en haut avec deux doigts) :"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Choisissez un service à utiliser avec le geste d\'accessibilité (balayer l\'écran de bas en haut avec trois doigts) :"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Pour changer de service, appuyez de manière prolongée sur le bouton Accessibilité."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Pour changer de service, balayez l\'écran vers le haut avec deux doigts et appuyez de manière prolongée."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Pour changer de service, balayez l\'écran vers le haut avec trois doigts et appuyez de manière prolongée."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Agrandissement"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Chargement du profil de <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1910,7 +1907,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Rechercher une mise à jour"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Vous avez de nouveaux messages"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Ouvrir l\'application de SMS pour afficher le message"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Fonctionnalités peuvent être limitées"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Des fonctions peuvent être limitées"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil professionnel verrouillé"</string>
     <string name="profile_encrypted_message" msgid="6964994232310195874">"Appuyez pour déverrouiller profil pro"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connecté à <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 5e497a0..b3eed4a 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamadas por wifi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chamadas por wifi con <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wifi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Modo coche"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Estado da conta"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mensaxes para programadores"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mensaxes importantes para os programadores"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualizacións"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estado da rede"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas de rede"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona de impresión dixital"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"xestionar o hardware de desbloqueo facial"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que a aplicación invoque métodos para engadir e eliminar modelos faciais de uso."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utilizar o hardware de desbloqueo facial"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permite que a aplicación utilice o hardware de desbloqueo facial para a autenticación"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Desbloqueo facial"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Volve inscribir a túa cara"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Para mellorar o recoñecemento, inscribe de novo a túa cara"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Sen datos faciais exactos. Téntao de novo."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Move o teléfono cara á esquerda."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Move o teléfono cara á dereita."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Mira o dispositivo de forma máis directa."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Non se pode ver a túa cara. Mira o teléfono."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Coloca a cara directamente diante do teléfono."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Demasiado movemento. Non movas o teléfono."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Volve rexistrar a túa cara."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Xa non se pode recoñecer a cara. Téntao de novo."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Xira a cabeza un pouco menos."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Xira a cabeza un pouco menos."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Quita todo o que oculte a túa cara."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Limpa o sensor na parte superior da pantalla."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Limpa a parte superior da pantalla, incluída a barra de cor negra"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Sen verificar a cara. Hardware non dispoñible."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Tenta utilizar o desbloqueo facial de novo."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Para gardar novos datos faciais, elimina os antigos."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Cancelouse a operación relacionada coa cara"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"O usuario cancelou o desbloqueo facial."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiados intentos. Téntao de novo máis tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Demasiados intentos. Desactivouse o desbloqueo facial."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Non se puido verificar a cara. Téntao de novo."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Non configuraches o desbloqueo facial."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Este dispositivo non admite o desbloqueo facial."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Cara <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Abrir con"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Abrir con %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Abrir"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Conceder acceso para abrir ligazóns de <xliff:g id="HOST">%1$s</xliff:g> con"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Conceder acceso para abrir ligazóns de <xliff:g id="HOST">%1$s</xliff:g> con <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Abrir ligazóns de <xliff:g id="HOST">%1$s</xliff:g> con"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Abrir ligazóns con"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Abrir ligazóns con <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Abrir ligazóns de <xliff:g id="HOST">%1$s</xliff:g> con <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Conceder acceso"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Editar con"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editar con %1$s"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Restablece a configuración de fábrica para desactivar o modo de axente de proba."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Pódese utilizar o porto USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"O teléfono xa non detecta líquidos nin residuos."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de erros…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Queres compartir o informe de erros?"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Iniciar o navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Aceptar chamada?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Definir como abrir sempre"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Só unha vez"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Configuración"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s non admite o perfil de traballo"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Superposición n.º <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", segura"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"O inicio desta actividade en segundo plano desde <xliff:g id="PACKAGENAME">%1$s</xliff:g> bloquearase en futuras compilacións de Q. Consulta g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Bloqueouse o inicio da actividade en segundo plano desde <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Consulta g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueciches o padrón"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrón incorrecto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Contrasinal incorrecto"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atallo de accesibilidade activou <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atallo de accesibilidade desactivou <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Mantén premidas as teclas do volume durante tres segudos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolle que función queres utilizar cando toques o botón Accesibilidade:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para cambiar as funcións, mantén premido o botón Accesibilidade."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolle o servizo que queres utilizar cando toques o botón de accesibilidade:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolle o servizo que queres usar co xesto de accesibilidade (pasa dous dedos cara arriba desde a parte inferior da pantalla):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolle o servizo que queres usar co xesto de accesibilidade (pasa tres dedos cara arriba desde a parte inferior da pantalla):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para cambiar de servizo, mantén premido o botón de accesibilidade."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para cambiar de servizo, pasa dous dedos cara arriba e mantén premida a pantalla."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para cambiar de servizo, pasa tres dedos cara arriba pola pantalla e mantén premido."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliación"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1988,7 +1985,7 @@
     <string name="harmful_app_warning_uninstall" msgid="4837672735619532931">"DESINSTALAR"</string>
     <string name="harmful_app_warning_open_anyway" msgid="596432803680914321">"ABRIR IGUALMENTE"</string>
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"Detectouse unha aplicación daniña"</string>
-    <string name="slices_permission_request" msgid="8484943441501672932">"A aplicación <xliff:g id="APP_0">%1$s</xliff:g> quere mostrar partes de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
+    <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> quere mostrar fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"Editar"</string>
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"As chamadas e as notificacións vibrarán"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"As chamadas e as notificacións estarán silenciadas"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index c03db76..1b96172 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ કૉલિંગ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ કૉલિંગ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN કૉલ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN કૉલ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"કાર મોડ"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"એકાઉન્ટ સ્થિતિ"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"વિકાસકર્તા માટેના સંદેશા"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"ડેવલપર માટેના મહત્ત્વપૂર્ણ સંદેશા"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"અપડેટ્સ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"નેટવર્ક સ્થિતિ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"નેટવર્ક ચેતવણીઓ"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ફિંગરપ્રિન્ટ આયકન"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"ફેસ અનલૉકના હાર્ડવેરને મેનેજ કરો"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ઍપને ઉપયોગ માટે ચહેરાના નમૂના ઉમેરવા અને ડિલીટ કરવાની પદ્ધતિને રદ કરવાની મંજૂરી આપે છે."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"ફેસ અનલૉક હાર્ડવેરનો ઉપયોગ કરો"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"ઍપને પ્રમાણીકરણ માટે ફેસ અનલૉકના હાર્ડવેરનો ઉપયોગ કરવાની મંજૂરી આપે છે"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"ફેસ અનલૉક"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"તમારા ચહેરાની ફરી નોંધણી કરાવો"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"ઓળખવાની પ્રક્રિયાને બહેતર બનાવવા માટે કૃપા કરીને તમારા ચહેરાની ફરી નોંધણી કરાવો"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"ચહેરાનો સચોટ ડેટા કૅપ્ચર ન થયો. ફરી પ્રયાસ કરો."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ફોનને ડાબી બાજુ ખસેડો."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ફોનને જમણી બાજુ ખસેડો."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"કૃપા કરીને તમારા ડિવાઇસ તરફ સીધું જુઓ."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"તમારો ચહેરો દેખાતો નથી. ફોનની સામે જુઓ."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"તમારો ચહેરો તમારા ફોનની બિલકુલ સામે રાખો."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"ડિવાઇસ અસ્થિર છે. ફોનને સ્થિર રાખો."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"કૃપા કરીને તમારા ચહેરાની ફરી નોંધણી કરાવો."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"ચહેરો ઓળખી શકાતો નથી. ફરી પ્રયાસ કરો."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"તમારું માથું થોડું ફેરવો."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"તમારું માથું થોડું ઓછું ફેરવો."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"તમારા ચહેરાને છુપાવતી કંઈપણ વસ્તુ દૂર કરો."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"સ્ક્રીનની ટોચની ધાર પરના સેન્સરને સાફ કરો."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"કાળી પટ્ટી સહિત, તમારી સ્ક્રીનની ટોચ સાફ કરો"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"ચહેરો ચકાસી શકાતો નથી. હાર્ડવેર ઉપલબ્ધ નથી."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"ફેસ અનલૉકને ફરી અજમાવો."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"ચહેરાનો નવો ડેટા સ્ટોર કરી શકતાં નથી. પહેલા જૂનો ડિલીટ કરો."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ચહેરા સંબંધિત કાર્યવાહી રદ કરવામાં આવી છે."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"વપરાશકર્તાએ ફેસ અનલૉક રદ કર્યું."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ઘણા બધા પ્રયત્નો. થોડા સમય પછી ફરી પ્રયાસ કરો."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"ઘણા બધા પ્રયાસો. ફેસ અનલૉક બંધ કર્યું."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"ચહેરો ચકાસી શકાતો નથી. ફરી પ્રયાસ કરો."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"તમે ફેસ અનલૉકનું સેટઅપ કર્યું નથી."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"આ ડિવાઇસ પર ફેસ અનલૉક કરવાની સુવિધા નથી."</string>
     <string name="face_name_template" msgid="7004562145809595384">"ચહેરાનું <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"આની સાથે ખોલો"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s સાથે ખોલો"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"ખોલો"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"આના વડે <xliff:g id="HOST">%1$s</xliff:g>ની લિંક ખોલવા માટે ઍક્સેસ આપો"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> વડે <xliff:g id="HOST">%1$s</xliff:g>ની લિંક ખોલવા માટે ઍક્સેસ આપો"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"આના વડે <xliff:g id="HOST">%1$s</xliff:g> લિંક ખોલો"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"આના વડે લિંક ખોલો"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> વડે લિંક ખોલો"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> વડે <xliff:g id="HOST">%1$s</xliff:g> લિંક ખોલો"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ઍક્સેસ આપો"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"આનાથી સંપાદિત કરો"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s સાથે સંપાદિત કરો"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ટેસ્ટ હાર્નેસ મોડ બંધ કરવા માટે ફૅક્ટરી રીસેટ કરો."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB પોર્ટમાં પ્રવાહી કે ધૂળ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB પોર્ટ ઑટોમૅટિક રીતે બંધ કરવામાં આવ્યો છે. વધુ જાણવા માટે ટૅપ કરો."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB પોર્ટનો ઉપયોગ કરવો યોગ્ય છે"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ફોનને હવે કોઈ પ્રવાહી કે ધૂળ હોવાનું જણાયું નથી."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"બગ રિપોર્ટ લઈ રહ્યાં છે…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"બગ રિપોર્ટ શેર કરીએ?"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"બ્રાઉઝર લોન્ચ કરીએ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"કૉલ સ્વીકારીએ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"હંમેશા"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"હંમેશાં ખુલ્લી તરીકે સેટ કરો"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"ફક્ત એક વાર"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"સેટિંગ"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s કાર્ય પ્રોફાઇલનું સમર્થન કરતું નથી"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ઓવરલે કરો"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", સુરક્ષિત"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>માંથી શરૂ થયેલી આ બૅકગ્રાઉન્ડ પ્રવૃત્તિને ભાવિ Q બિલ્ડમાં બ્લૉક કરવામાં આવશે. g.co/dev/bgblock જુઓ."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>માંથી શરૂ થયેલી બૅકગ્રાઉન્ડ પ્રવૃત્તિ બ્લૉક કરી છે. g.co/dev/bgblock જુઓ."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"પૅટર્ન ભૂલી ગયાં"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ખોટી પૅટર્ન"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ખોટો પાસવર્ડ"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ઍક્સેસિબિલિટી શૉર્ટકટે <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ઍક્સેસિબિલિટી શૉર્ટકટે <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>નો ઉપયોગ કરવા માટે બન્ને વૉલ્યૂમ કીને ત્રણ સેકન્ડ સુધી દબાવી રાખો"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"જ્યારે તમે ઍક્સેસિબિલિટી બટન પર ટૅપ કરો, ત્યારે ઉપયોગ કરવાની સુવિધા પસંદ કરો:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"સુવિધાઓ બદલવા માટે, ઍક્સેસિબિલિટી બટન દબાવી રાખો."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"જ્યારે તમે ઍક્સેસિબિલિટી બટન પર ટૅપ કરો, ત્યારે ઉપયોગ કરવાની સેવા પસંદ કરો:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સેવા પસંદ કરો (બે આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સેવા પસંદ કરો (ત્રણ આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"કોઈ એક સેવાથી બીજી સેવા પર સ્વિચ કરવા માટે, ઍક્સેસિબિલિટી બટનને ટચ કરીને દબાવી રાખો."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"કોઈ એક સેવાથી બીજી સેવા પર સ્વિચ કરવા માટે, બે આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"કોઈ એક સેવાથી બીજી સેવા પર સ્વિચ કરવા માટે, ત્રણ આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"વિસ્તૃતીકરણ"</string>
     <string name="user_switched" msgid="3768006783166984410">"વર્તમાન વપરાશકર્તા <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> પર સ્વિચ કરી રહ્યાં છે…"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 4eeb661..9f0df13 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -30,7 +30,7 @@
     <string name="untitled" msgid="4638956954852782576">"&lt;शीर्षक-रहित&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(कोई फ़ोन नंबर नहीं)"</string>
     <string name="unknownName" msgid="6867811765370350269">"अज्ञात"</string>
-    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"वॉयस मेल"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"वॉइसमेल"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"कनेक्‍शन समस्‍या या अमान्‍य MMI कोड."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"कार्रवाई केवल फ़िक्‍स्‍ड डायलिंग नंबर के लिए प्रतिबंधित है."</string>
@@ -97,7 +97,7 @@
     <string name="notification_channel_sim" msgid="4052095493875188564">"सिम की स्थिति"</string>
     <string name="peerTtyModeFull" msgid="6165351790010341421">"पीयर ने टेलीटाइपराइटर (TTY) मोड फ़ुल का अनुरोध किया"</string>
     <string name="peerTtyModeHco" msgid="5728602160669216784">"पीयर ने टेलीटाइपराइटर (TTY) मोड एचसीओ (HCO) का अनुरोध किया"</string>
-    <string name="peerTtyModeVco" msgid="1742404978686538049">"पीयर ने टेलीटाइपराइटर (TTY) मोड वीसीअो (VCO) का अनुरोध किया"</string>
+    <string name="peerTtyModeVco" msgid="1742404978686538049">"पीयर ने टेलीटाइपराइटर (TTY) मोड वीसीओ (VCO) का अनुरोध किया"</string>
     <string name="peerTtyModeOff" msgid="3280819717850602205">"पीयर ने टेलीटाइपराइटर (TTY) मोड बंद का अनुरोध किया"</string>
     <string name="serviceClassVoice" msgid="1258393812335258019">"आवाज़"</string>
     <string name="serviceClassData" msgid="872456782077937893">"डेटा"</string>
@@ -116,7 +116,7 @@
     <string name="roamingText6" msgid="2059440825782871513">"रोमिंग - उपलब्‍ध सिस्‍टम"</string>
     <string name="roamingText7" msgid="7112078724097233605">"रोमिंग - गठबंधन सहयोगी"</string>
     <string name="roamingText8" msgid="5989569778604089291">"रोमिंग - प्रीमियम सहयोगी"</string>
-    <string name="roamingText9" msgid="7969296811355152491">"रोमिंग - पूर्ण सेवा काम की क्षमता"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"रोमिंग - पूरी सेवा काम की क्षमता"</string>
     <string name="roamingText10" msgid="3992906999815316417">"रोमिंग - आंशिक सेवा काम की क्षमता"</string>
     <string name="roamingText11" msgid="4154476854426920970">"रोमिंग बैनर चालू"</string>
     <string name="roamingText12" msgid="1189071119992726320">"रोमिंग बैनर बंद"</string>
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> वाई-फ़ाई कॉलिंग"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"वाई-फ़ाई के ज़रिए कॉल करते समय <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कॉल"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कॉल"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> वाई-फ़ाई"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"कार मोड"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"खाते की स्थिति"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"डेवलपर के संदेश"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"डेवलपर के ज़रूरी मैसेज"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"अपडेट"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"नेटवर्क की स्थिति"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"नेटवर्क संबंधी सूचनाएं"</string>
@@ -334,7 +336,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"शॉर्टकट अनइंस्टॉल करें"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"ऐप्‍लिकेशन को उपयोगकर्ता की रोक के बिना होमस्‍क्रीन शॉर्टकट निकालने की अनुमति देता है."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"किया जाने वाला कॉल (आउटगोइंग) कहीं और भेजें"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"एेप कॉल को किसी और नंबर पर भेजने या कॉल को पूरी तरह रद्द करने के विकल्प के साथ, किए गए कॉल (आउटगोइंग) के नंबर को देख सकता है."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"ऐप कॉल को किसी और नंबर पर भेजने या कॉल को पूरी तरह रद्द करने के विकल्प के साथ, किए गए कॉल (आउटगोइंग) के नंबर को देख सकता है."</string>
     <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"फ़ोन कॉल का जवाब दें"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"ऐप्लिकेशन को किसी इनकमिंग फ़ोन कॉल का जवाब देने देती है."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"मैसेज (एसएमएस) पाएं"</string>
@@ -398,9 +400,9 @@
     <string name="permlab_readCallLog" msgid="3478133184624102739">"कॉल लॉग पढ़ें"</string>
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"यह ऐप्लिकेशन आपका कॉल इतिहास पढ़ सकता है."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"कॉल लॉग लिखें"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टैबलेट के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टीवी के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"एेप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके फ़ोन के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले एेप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"ऐप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टैबलेट के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले ऐप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"ऐप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके टीवी के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले ऐप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ऐप को आने वाला कॉल (इनकमिंग) और किया जाने वाला कॉल (आउटगोइंग) डेटा सहित, आपके फ़ोन के कॉल लॉग को बदलने की अनुमति देता है. धोखा देने वाले ऐप, इसका इस्तेमाल करके आपके कॉल लॉग को मिटा या बदल सकते हैं."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर के लिए बने सेंसर (जैसे हृदय गति मॉनीटर) को एक्सेस करें"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ऐप को आपकी शारीरिक स्‍थिति, जैसे आपकी हृदय गति पर नज़र रखने वाले सेंसर के डेटा तक पहुंचने देती है."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"कैलेंडर इवेंट और विवरण पढ़ें"</string>
@@ -438,7 +440,7 @@
     <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS कॉल सेवा ऐक्‍सेस करें"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"आपके हस्‍तक्षेप के बिना कॉल करने के लिए, ऐप को IMS सेवा का उपयोग करने देती है."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"फ़ोन की स्‍थिति और पहचान पढ़ें"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ऐप्स  को डिवाइस की फ़ोन सुविधाओं तक पहुंचने देता है. यह अनुमति ऐप्स  को फ़ोन नंबर और डिवाइस आईडी, कॉल सक्रिय है या नहीं, और कॉल द्वारा कनेक्ट किया गया दूरस्‍थ नंबर निर्धारित करने देती है."</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ऐप्स को डिवाइस की फ़ोन सुविधाओं तक पहुंचने देता है. यह अनुमति ऐप्स  को फ़ोन नंबर और डिवाइस आईडी, कॉल सक्रिय है या नहीं, और कॉल द्वारा कनेक्ट किया गया दूरस्‍थ नंबर तय करने देती है."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"सिस्टम के माध्यम से कॉल रूट करें"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करने के अनुभव को बेहतर बनाने के लिए ऐप्लिकेशन को सिस्टम के माध्यम से उसके कॉल रूट करने देती है."</string>
     <string name="permlab_callCompanionApp" msgid="3599252979411970473">"सिस्टम के ज़रिए कॉल देखना और नियंत्रित करना."</string>
@@ -481,7 +483,7 @@
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ऐप को वाई-फ़ाई नेटवर्क के बारे में जानकारी, जैसे WI-Fi चालू है या नहीं और कनेक्‍ट किए गए वाई-फ़ाई डिवाइस के नाम, देखने देता है."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"वाई-फ़ाई  से कनेक्‍ट और डिस्‍कनेक्‍ट करें"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"ऐप्स  को वाई-फ़ाई  पहुंच बिंदुओं से कनेक्ट और डिसकनेक्ट करने और वाई-फ़ाई  नेटवर्क के लिए डिवाइस कॉन्फ़िगरेशन में परिवर्तन करने देता है."</string>
-    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"वाई-फ़ाई  मल्‍टीकास्‍ट प्राप्ति को अनुमति दें"</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"वाई-फ़ाई मल्‍टीकास्‍ट पाने को अनुमति दें"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ऐप्स  को वाई-फ़ाई  नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके टैबलेट पर ही नहीं, बल्कि सभी डिवाइस पर भेजे गए पैकेट प्राप्‍त करने देता है. यह गैर-मल्टीकास्ट मोड से ज़्यादा पावर का उपयोग करता है."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"ऐप को मल्‍टीकास्‍ट पतों का उपयोग करके ना केवल आपके टीवी को, बल्‍कि वाई-फ़ाई पर मौजूद सभी डिवाइसों को पैकेट भेजने और प्राप्‍त करने देती है. इसमें गैर-मल्‍टीकास्‍ट मोड की अपेक्षा ज़्यादा पावर का उपयोग होता है."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"ऐप्स  को वाई-फ़ाई  नेटवर्क पर मल्टीकास्ट पते के उपयोग से केवल आपके फ़ोन पर ही नहीं, बल्कि सभी डिवाइस पर भेजे गए पैकेट प्राप्‍त करने देता है. यह गैर-मल्टीकास्ट मोड से ज़्यादा पावर का उपयोग करता है."</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फ़िंगरप्रिंट आइकॉन"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"\'मालिक का चेहरा पहचानकर अनलॉक\' वाला हार्डवेयर प्रबंधित करें"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ऐप्लिकेशन को चेहरे के टेम्पलेट इस्तेमाल के तरीके जोड़ने और मिटाने की मंज़ूरी मिलती है."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"\'मालिक का चेहरा पहचानकर अनलॉक\' वाला हार्डवेयर इस्तेमाल करें"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"ऐप्लिकेशन को \'मालिक का चेहरा पहचानकर अनलॉक\' वाले हार्डवेयर के इस्तेमाल की मंज़ूरी देता है"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"मालिक का चेहरा पहचानकर अनलॉक"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"अपना चेहरा फिर से दर्ज करें"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"कृपया अपना चेहरा फिर से दर्ज करें ताकि आपको बेहतर तरीके से पहचाना जा सके"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"चेहरे से जुड़ा सटीक डेटा कैप्चर नहीं किया जा सका. फिर से कोशिश करें."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"फ़ोन को बाईं ओर घुमाएं."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"फ़ोन को दाईं ओर घुमाएं."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"कृपया अपने डिवाइस की तरफ़ सीधे देखें."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"आपका चेहरा नहीं दिखाई दे रहा. फ़ोन की तरफ़ देखें."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"अपने चेहरे को फोन के ठीक सामने लाएं."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"डिवाइस बहुत ज़्यादा हिल रहा है. फ़ोन को बिना हिलाएं पकड़ें."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"कृपया फिर से अपने चेहरे की पहचान कराएं."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"अब चेहरे की पहचान नहीं कर पा रहा. फिर से कोशिश करें."</string>
@@ -579,30 +577,25 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"अपना सिर थोड़ा कम घुमाएं."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"अपना सिर थोड़ा कम घुमाएं."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"आपके चेहरे को छिपाने वाली सभी चीज़ों को हटाएं."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"स्क्रीन के ऊपरी किनारे पर मौजूद सेंसर को साफ करें."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"अपनी स्क्रीन के सबसे ऊपरी हिस्से को साफ़ करें, जिसमें काले रंग वाला बार भी शामिल है"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"चेहरा नहीं पहचान पा रहे. हार्डवेयर उपलब्ध नहीं है."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"\'मालिक का चेहरा पहचानकर अनलॉक\' फिर से आज़माएं."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"चेहरे का नया डेटा सेव नहीं हो सकता. कोई पुराना डेटा मिटाएं."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"चेहरा पहचानने की कार्रवाई रद्द की गई."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"उपयोगकर्ता ने \'मालिक का चेहरा पहचानकर अनलॉक\' रद्द की."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"कई बार कोशिश की गई. बाद में कोशिश करें."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"कई बार कोशिश की जा चुकी है. \'मालिक का चेहरा पहचानकर अनलॉक\' बंद है."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"चेहरा नहीं पहचान पा रहे. फिर से कोशिश करें."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"आपने \'मालिक का चेहरा पहचानकर अनलॉक\' सेट नहीं की है."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"इस डिवाइस पर \'मालिक का चेहरा पहचानकर अनलॉक\' काम नहीं करती है."</string>
     <string name="face_name_template" msgid="7004562145809595384">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="4024817159806482191">"चेहरे का आइकॉन"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"समन्वयन सेटिंग पढ़ें"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ऐप्स  को किसी खाते की समन्वयन सेटिंग पढ़ने देता है. उदाहरण के लिए, इससे यह निर्धारित किया जा सकता है कि लोग ऐप्स  किसी खाते के साथ समन्‍वयित है या नहीं."</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"ऐप्स  को किसी खाते की समन्वयन सेटिंग पढ़ने देता है. उदाहरण के लिए, इससे यह तय किया जा सकता है कि लोग ऐप्स  किसी खाते के साथ समन्‍वयित है या नहीं."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"समन्‍वयन बंद या चालू टॉगल करें"</string>
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ऐप्स  को किसी खाते की समन्वयन सेटिंग संशोधित करने देता है. उदाहरण के लिए, इसका उपयोग लोग ऐप्स  का समन्‍वयन किसी खाते से सक्षम करने में हो सकता है."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"समन्वयन आंकड़े पढ़ें"</string>
@@ -648,7 +641,7 @@
     <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्र एक्सेस करें"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"ऐप्लिकेशन को DRM प्रमाणपत्रों का प्रावधान और उपयोग करने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यकता नहीं होना चाहिए."</string>
     <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android बीम ट्रांसफ़र की स्थिति पाएं"</string>
-    <string name="permdesc_handoverStatus" msgid="4788144087245714948">"इस एेप को मौजूदा Android बीम ट्रांसफ़र के बारे में जानकारी पाने की अनुमति दें."</string>
+    <string name="permdesc_handoverStatus" msgid="4788144087245714948">"इस ऐप को मौजूदा Android बीम ट्रांसफ़र के बारे में जानकारी पाने की अनुमति दें."</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM प्रमाणपत्रों को निकाल सकता है"</string>
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"ऐप्‍लिकेशन को DRM प्रमाणपत्रों को निकालने देता है. सामान्य ऐप्स के लिए कभी भी आवश्यकता नहीं होनी चाहिए."</string>
     <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी की संदेश सेवा से जुड़ें"</string>
@@ -791,7 +784,7 @@
     <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"हमसफ़र"</string>
     <string name="relationTypeFather" msgid="5228034687082050725">"पिता"</string>
     <string name="relationTypeFriend" msgid="7313106762483391262">"दोस्त"</string>
-    <string name="relationTypeManager" msgid="6365677861610137895">"प्रबंधक"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"मैनेजर"</string>
     <string name="relationTypeMother" msgid="4578571352962758304">"मां"</string>
     <string name="relationTypeParent" msgid="4755635567562925226">"अभिभावक"</string>
     <string name="relationTypePartner" msgid="7266490285120262781">"सहयोगी"</string>
@@ -911,7 +904,7 @@
     <string name="granularity_label_line" msgid="5764267235026120888">"पंक्ति"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"फ़ैक्‍ट्री परीक्षण विफल"</string>
     <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST का काम केवल /system/app में इंस्‍टॉल किए गए पैकेज के लिए ही हो सकता है."</string>
-    <string name="factorytest_no_action" msgid="872991874799998561">"ऐसा कोई पैकेज नहीं मिला था जो FACTORY_TEST कार्रवाई प्रदान करता हो."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"ऐसा कोई पैकेज नहीं मिला था जो FACTORY_TEST कार्रवाई मुहैया करवाता हो."</string>
     <string name="factorytest_reboot" msgid="6320168203050791643">"रीबूट करें"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"\'<xliff:g id="TITLE">%s</xliff:g>\' पर यह पेज दर्शाता है:"</string>
     <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
@@ -999,8 +992,8 @@
     <string name="minutes" msgid="5646001005827034509">"मिनट"</string>
     <string name="second" msgid="3184235808021478">"सेकंड"</string>
     <string name="seconds" msgid="3161515347216589235">"सेकंड"</string>
-    <string name="week" msgid="5617961537173061583">"सप्ताह"</string>
-    <string name="weeks" msgid="6509623834583944518">"सप्ताह"</string>
+    <string name="week" msgid="5617961537173061583">"हफ़्ता"</string>
+    <string name="weeks" msgid="6509623834583944518">"हफ़्ता"</string>
     <string name="year" msgid="4001118221013892076">"वर्ष"</string>
     <string name="years" msgid="6881577717993213522">"वर्ष"</string>
     <string name="now_string_shortest" msgid="8912796667087856402">"अभी"</string>
@@ -1092,7 +1085,7 @@
     <string name="undo" msgid="7905788502491742328">"वापस लाएं"</string>
     <string name="redo" msgid="7759464876566803888">"फिर से करें"</string>
     <string name="autofill" msgid="3035779615680565188">"ऑटोमैटिक भरना"</string>
-    <string name="textSelectionCABTitle" msgid="5236850394370820357">"लेख चयन"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"टेक्स्ट चुनें"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"शब्दकोश में जोड़ें"</string>
     <string name="deleteText" msgid="6979668428458199034">"मिटाएं"</string>
     <string name="inputMethod" msgid="1653630062304567879">"इनपुट विधि"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"इसमें खोलें"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s में खोलें"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"खोलें"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"इससे <xliff:g id="HOST">%1$s</xliff:g> लिंक खोलने का एक्सेस दें"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> से <xliff:g id="HOST">%1$s</xliff:g> लिंक खोलने का एक्सेस दें"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"इसे इस्तेमाल करके <xliff:g id="HOST">%1$s</xliff:g> लिंक खोलें"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"इसे इस्तेमाल करके लिंक खोलें"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> इस्तेमाल करके लिंक खोलें"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> इस्तेमाल करके <xliff:g id="HOST">%1$s</xliff:g> लिंक खोलें"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"एक्सेस दें"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"इसके ज़रिये बदलाव करें"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s की मदद से बदलाव करें"</string>
@@ -1158,7 +1153,7 @@
     <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"चित्र कैप्चर करें"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"इस कार्रवाई के लिए डिफ़ॉल्‍ट के तौर पर इस्तेमाल करें"</string>
     <string name="use_a_different_app" msgid="8134926230585710243">"किसी भिन्न ऐप्स का उपयोग करें"</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"सिस्‍टम सेटिंग और डाउनलोड किए गए एेप में डिफ़ॉल्‍ट साफ़ करें."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"सिस्‍टम सेटिंग और डाउनलोड किए गए ऐप में डिफ़ॉल्‍ट साफ़ करें."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"कोई कार्रवाई चुनें"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB डिवाइस के लिए कोई ऐप्स  चुनें"</string>
     <string name="noApplications" msgid="2991814273936504689">"कोई भी ऐप्स यह कार्यवाही नहीं कर सकता."</string>
@@ -1289,7 +1284,7 @@
     <item msgid="75483255295529161">"वाई-फ़ाई"</item>
     <item msgid="6862614801537202646">"ब्लूटूथ"</item>
     <item msgid="5447331121797802871">"ईथरनेट"</item>
-    <item msgid="8257233890381651999">"VPN"</item>
+    <item msgid="8257233890381651999">"वीपीएन"</item>
   </string-array>
     <string name="network_switch_type_name_unknown" msgid="4552612897806660656">"अज्ञात नेटवर्क प्रकार"</string>
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"वाई-फ़ाई  से कनेक्‍ट नहीं हो सका"</string>
@@ -1334,8 +1329,8 @@
     <string name="sim_added_message" msgid="6599945301141050216">"मोबाइल नेटवर्क की पहुंच पाने लिए अपना डिवाइस फिर से चालू करें."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"फिर से शुरू करें"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"माेबाइल सेवा चालू करें"</string>
-    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"अपना नया सिम चालू करने के लिए मोबाइल और इंटरनेट सेवा देने वाली कंपनी का एेप्लिकेशन डाउनलोड करें"</string>
-    <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"अपना नया सिम चालू करने के लिए <xliff:g id="APP_NAME">%1$s</xliff:g> एेप्लिकेशन डाउनलाेड करें"</string>
+    <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"अपना नया सिम चालू करने के लिए मोबाइल और इंटरनेट सेवा देने वाली कंपनी का ऐप्लिकेशन डाउनलोड करें"</string>
+    <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"अपना नया सिम चालू करने के लिए <xliff:g id="APP_NAME">%1$s</xliff:g> ऐप्लिकेशन डाउनलाेड करें"</string>
     <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"ऐप्लिकेशन डाउनलोड करें"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"नई SIM डाली गई"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"इसे सेट करने के लिए टैप करें"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"टेस्ट हार्नेस मोड बंद करने के लिए फ़ैक्ट्री रीसेट करें."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"यूएसबी पोर्ट में तरल चीज़ या कचरा है"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"यूएसबी पोर्ट अपने आप बंद हो गया है. ज़्यादा जानने के लिए टैप करें."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"यूएसबी पोर्ट का इस्तेमाल करना सुरक्षित है"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"फ़ोन अब तरल चीज़ों या कचरे की पहचान नहीं करता."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"गड़बड़ी की रिपोर्ट ली जा रही है…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"गड़बड़ी की रिपोर्ट शेयर करें?"</string>
@@ -1465,7 +1459,7 @@
     <string name="chooser_wallpaper" msgid="7873476199295190279">"वॉलपेपर बदलें"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"सूचना को सुनने की सुविधा"</string>
     <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR श्रोता"</string>
-    <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति प्रदाता"</string>
+    <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति देने वाली"</string>
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"सूचना रैंकर सेवा"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN सक्रिय"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN को <xliff:g id="APP">%s</xliff:g> द्वारा सक्रिय किया गया है"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"आगे ढूंढें"</string>
     <string name="find_previous" msgid="2196723669388360506">"पिछला ढूंढें"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> ने जगह का अनुरोध किया गया है"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"जगह का अनुरोध किया जा रहा है"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"जगह की जानकारी मांगी जा रही है"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोधित"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"हां"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"नहीं"</string>
@@ -1559,17 +1553,17 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB मेमोरी"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"बदलाव करें"</string>
     <string name="data_usage_warning_title" msgid="6499834033204801605">"डेटा खर्च की चेतावनी"</string>
-    <string name="data_usage_warning_body" msgid="7340198905103751676">"अाप <xliff:g id="APP">%s</xliff:g> डेटा इस्तेमाल कर चुके हैं"</string>
+    <string name="data_usage_warning_body" msgid="7340198905103751676">"आप <xliff:g id="APP">%s</xliff:g> डेटा इस्तेमाल कर चुके हैं"</string>
     <string name="data_usage_mobile_limit_title" msgid="6561099244084267376">"मोबाइल डेटा की सीमा पार हो गई है"</string>
     <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wi-Fi डेटा की सीमा पूरी हो गई"</string>
     <string name="data_usage_limit_body" msgid="2908179506560812973">"आपकी मौजूदा बिलिंग साइकिल के बाकी दिनों के लिए डेटा का इस्तेमाल राेक दिया गया है"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="3171402244827034372">"माेबाइल डेटा की सीमा से ज़्यादा"</string>
     <string name="data_usage_wifi_limit_snoozed_title" msgid="3547771791046344188">"वाई-फ़ाई की सीमा से ज़्यादा डेटा खर्च"</string>
-    <string name="data_usage_limit_snoozed_body" msgid="1671222777207603301">"अाप अपनी तय सीमा से <xliff:g id="SIZE">%s</xliff:g> ज़्यादा डेटा इस्तेमाल कर चुके हैं"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="1671222777207603301">"आप अपनी तय सीमा से <xliff:g id="SIZE">%s</xliff:g> ज़्यादा डेटा इस्तेमाल कर चुके हैं"</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"पृष्ठभूमि डेटा प्रतिबंधित है"</string>
     <string name="data_usage_restricted_body" msgid="469866376337242726">"प्रतिबंध निकालने के लिए टैप करें."</string>
     <string name="data_usage_rapid_title" msgid="1809795402975261331">"माेबाइल डेटा का ज़्यादा इस्तेमाल"</string>
-    <string name="data_usage_rapid_body" msgid="6897825788682442715">"आपके एेप्लिकेशन ने आम तौर पर इस्तेमाल होने वाले डेटा से ज़्यादा डेटा खर्च कर दिया है"</string>
+    <string name="data_usage_rapid_body" msgid="6897825788682442715">"आपके ऐप्लिकेशन ने आम तौर पर इस्तेमाल होने वाले डेटा से ज़्यादा डेटा खर्च कर दिया है"</string>
     <string name="data_usage_rapid_app_body" msgid="5396680996784142544">"<xliff:g id="APP">%s</xliff:g> ने आम तौर पर इस्तेमाल होने वाले डेटा से ज़्यादा डेटा खर्च कर दिया है"</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"सुरक्षा प्रमाणपत्र"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"यह प्रमाणपत्र मान्य है."</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउज़र लॉन्च करें?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"कॉल स्वीकार करें?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"हमेशा"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"\'हमेशा खुला रखें\' पर सेट करें"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"केवल एक बार"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"सेटिंग"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s वर्क प्रोफ़ाइल का समर्थन नहीं करता"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ओवरले #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", सुरक्षित"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"आने वाले Q बिल्ड में <xliff:g id="PACKAGENAME">%1$s</xliff:g> के बैकग्राउंड में गतिविधि शुरू करने पर रोक लगा दी जाएगी. इस बारे में जानने के लिए g.co/dev/bgblock पर जाएं."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> के बैकग्राउंड में गतिविधि शुरू करने पर रोक लगा दी गई है. इस बारे में जानने के लिए g.co/dev/bgblock पर जाएं."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"आकार भूल गए"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"गलत पैटर्न डाला गया है"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"गलत पासवर्ड"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"सुलभता शॉर्टकट ने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू किया"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"सुलभता शॉर्टकट ने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद किया"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> इस्तेमाल करने के लिए आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"सुलभता बटन पर टैप करते समय इस्तेमाल की जाने वाली सुविधा चुनें:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाओं में बदलाव करने के लिए, सुलभता बटन को दबाकर रखें."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"\'सुलभता\' बटन पर टैप करके इस्तेमाल करने के लिए सेवा चुनें:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"सुलभता वाले जेस्चर के साथ इस्तेमाल करने के लिए सेवा चुनें (दो उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"सुलभता वाले जेस्चर के साथ इस्तेमाल करने के लिए सेवा चुनें (तीन उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"एक सेवा से दूसरी सेवा पर जाने के लिए, \'सुलभता\' बटन को कुछ देर दबाकर रखें."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"एक सेवा से दूसरी सेवा पर जाने के लिए, स्क्रीन पर दो उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक स्क्रीन पर उंगलियां रखे रहें."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"एक सेवा से दूसरी सेवा पर जाने के लिए, स्क्रीन पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक स्क्रीन पर उंगलियां रखे रहें."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"बड़ा करना"</string>
     <string name="user_switched" msgid="3768006783166984410">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
@@ -1856,7 +1853,7 @@
     <string name="toolbar_collapse_description" msgid="2821479483960330739">"छोटा करें"</string>
     <string name="zen_mode_feature_name" msgid="5254089399895895004">"परेशान ना करें"</string>
     <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"बंद रहने का समय"</string>
-    <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"सप्ताह की रात"</string>
+    <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"हफ़्ते की रात"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"सप्ताहांत"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इवेंट"</string>
     <string name="zen_mode_default_every_night_name" msgid="3012363838882944175">"सोते समय"</string>
@@ -1989,12 +1986,12 @@
     <string name="harmful_app_warning_title" msgid="8982527462829423432">"नुकसान पहुंचाने वाले ऐप का पता चला"</string>
     <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g>, <xliff:g id="APP_2">%2$s</xliff:g> के हिस्से (स्लाइस) दिखाना चाहता है"</string>
     <string name="screenshot_edit" msgid="7867478911006447565">"बदलाव करें"</string>
-    <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"कॉल अाैर सूचनाअाें के लिए डिवाइस वाइब्रेट हाेगा"</string>
-    <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"कॉल अाैर सूचनाओं के लिए डिवाइस म्यूट रहेगा"</string>
+    <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"कॉल और सूचनाओं के लिए डिवाइस वाइब्रेट हाेगा"</string>
+    <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"कॉल और सूचनाओं के लिए डिवाइस म्यूट रहेगा"</string>
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"सिस्टम में हुए बदलाव"</string>
     <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"परेशान न करें"</string>
     <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"नई सुविधा: परेशान न करें सुविधा चालू होने की वजह से सूचनाएं नहीं दिखाई जा रही हैं"</string>
-    <string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"ज़्यादा जानने अाैर बदलाव करने के लिए टैप करें."</string>
+    <string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"ज़्यादा जानने और बदलाव करने के लिए टैप करें."</string>
     <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"परेशान न करें की सुविधा बदल गई है"</string>
     <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"टैप करके देखें कि किन चीज़ों पर रोक लगाई गई है."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"सिस्टम"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index eb09104..21fdc2f 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi pozivi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi pozivi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Poziv putem WLAN-a"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> poziv putem WLAN-a"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -259,6 +260,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Način rada u automobilu"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Status računa"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Poruke razvojnog programera"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Važne poruke za razvojne programere"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ažuriranja"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Mrežni status"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Mrežna upozorenja"</string>
@@ -552,15 +554,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona otiska prsta"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"Upravljajte hardverom za otključavanje licem"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Aplikaciji omogućuje pozivanje načina za dodavanje i brisanje predložaka lica za upotrebu."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"Koristiti hardver za otključavanje licem"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Aplikaciji omogućuje upotrebu hardvera za otključavanje licem radi autentifikacije"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Otključavanje licem"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Ponovo registrirajte svoje lice"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Za poboljšanje prepoznavanja ponovo registrirajte svoje lice"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Podaci o licu nisu točni. Pokušajte ponovo."</string>
@@ -573,7 +571,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Pomaknite telefon ulijevo."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Pomaknite telefon udesno."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Gledajte izravnije prema uređaju."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Vaše se lice ne vidi. Pogledajte telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Postavite lice izravno ispred telefona."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Previše kretanja. Držite telefon mirno."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Ponovo registrirajte svoje lice."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Lice nije prepoznato. Pokušajte ponovo."</string>
@@ -582,24 +580,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Nagnite glavu malo manje."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Nagnite glavu malo manje."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Uklonite sve što vam zakriva lice."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Očistite senzor na gornjem rubu zaslona."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Očistite vrh zaslona, uključujući crnu traku"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Lice nije potvrđeno. Hardver nije dostupan."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Ponovo pokušajte otključavanje licem."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Podaci o novom licu nisu pohranjeni. Izbrišite neko staro."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Otkazana je radnja s licem."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Otključavanje licem otkazao je korisnik."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Previše pokušaja. Onemogućeno otključavanje licem"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Lice nije potvrđeno. Pokušajte ponovo."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Niste postavili otključavanje licem"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Otključavanje licem nije podržano na ovom uređaju."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1158,8 +1151,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Otvaranje pomoću aplikacije"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otvaranje pomoću aplikacije %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Otvori"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Omogućite pristup za otvaranje <xliff:g id="HOST">%1$s</xliff:g> veza pomoću aplikacije"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Omogućite pristup za otvaranje <xliff:g id="HOST">%1$s</xliff:g> veza pomoću aplikacije <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Otvaranje veza s <xliff:g id="HOST">%1$s</xliff:g> u aplikaciji"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Otvaranje veza u aplikaciji"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Otvaranje veza u aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Otvaranje veza s <xliff:g id="HOST">%1$s</xliff:g> u aplikaciji <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Omogući pristup"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Uređivanje pomoću aplikacije"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Uređivanje pomoću aplikacije %1$s"</string>
@@ -1388,8 +1383,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Vratite na tvorničke postavke da biste onemogućili način testnog okvira."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Možete koristiti USB priključak"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon više ne otkriva tekućinu ili prljavštinu."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izrada izvješća o programskoj pogrešci…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li podijeliti izvješće o programskoj pogrešci?"</string>
@@ -1615,6 +1609,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Pokrenuti preglednik?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prihvatiti poziv?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Uvijek"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Postavi to otvaranje kao zadano"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo jednom"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Postavke"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ne podržava radni profil"</string>
@@ -1644,8 +1639,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Preklapanje br. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sigurno"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Pokretanje aktivnosti u pozadini iz aplikacije <xliff:g id="PACKAGENAME">%1$s</xliff:g> blokirat će se u budućim međuverzijama Q. Pogledajte g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Blokirano je pokretanje aktivnosti u pozadini iz aplikacije <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Pogledajte g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravili ste obrazac"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan obrazac"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna zaporka"</string>
@@ -1700,8 +1693,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Prečac pristupačnosti uključio je uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Prečac pristupačnosti isključio je uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pritisnite i zadržite tipke za glasnoću na tri sekunde da biste koristili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Odaberite značajku koju ćete upotrebljavati kada dodirnete gumb Pristupačnost:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Da biste promijenili značajke, dodirnite i zadržite gumb Pristupačnost."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Odaberite uslugu koju ćete upotrebljavati kad dodirnete gumb pristupačnosti:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Odaberite uslugu koju ćete upotrebljavati uz pokret pristupačnosti (prelazak s dva prsta prema gore od dna zaslona):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Odaberite uslugu koju ćete upotrebljavati uz pokret pristupačnosti (prelazak s tri prsta prema gore od dna zaslona):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Da biste prešli na neku drugu uslugu, dodirnite i zadržite gumb pristupačnosti."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Da biste prešli na neku drugu uslugu, prijeđite s dva prsta prema gore i zadržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Da biste prešli na neku drugu uslugu, prijeđite s tri prsta prema gore i zadržite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Povećavanje"</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 608a121..1198610 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-hívás"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi‑Fi-hívás"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-hívás"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-hívás"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,12 +257,13 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Autós üzemmód"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Fiókállapot"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Fejlesztői üzenetek"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Fontos fejlesztői üzenetek"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Frissítések"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Hálózati állapot"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Hálózati értesítések"</string>
     <string name="notification_channel_network_available" msgid="4531717914138179517">"Van elérhető hálózat"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-állapot"</string>
-    <string name="notification_channel_device_admin" msgid="8353118887482520565">"Rendszergazda általi értesítések"</string>
+    <string name="notification_channel_device_admin" msgid="8353118887482520565">"Értesítések a rendszergazdától"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Értesítések"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kiskereskedelmi bemutató"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB-kapcsolat"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ujjlenyomat ikon"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"arcalapú feloldásra szolgáló hardver kezelése"</string>
     <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>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"arcalapú feloldásra szolgáló hardver használata"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Engedélyezi, hogy az alkalmazás hitelesítésre használja az arcalapú feloldás hardverét"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Arcalapú feloldás"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Rögzítsen újra képet az arcáról"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"A felismerés javítása érdekében rögzítsen újra az arcáról készített képet"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Sikertelen az arc pontos rögzítése. Próbálja újra."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mozgassa a telefont balra."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mozgassa a telefont jobbra."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Szemből nézzen az eszközre."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Nem látszik az arca. Nézzen a telefonra."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"A telefont közvetlenül az arca elé tegye."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Túl sok a mozgás. Tartsa stabilan a telefont."</string>
     <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="7663983770123789694">"Már nem lehet felismerni az arcát. Próbálja újra."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Kicsit kevésbé fordítsa el a fejét."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Kicsit kevésbé fordítsa el a fejét."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Távolítson el mindent, ami takarja az arcát."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Tisztítsa meg a képernyő tetején lévő érzékelőt."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Tisztítsa meg a képernyő tetejét, a fekete sávot is beleértve."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Sikertelen arcellenőrzés. A hardver nem érhető el."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Próbálja újra az arcalapú feloldást."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Nem tárolhatók újabb arcadatok. Törölje valamelyik arcot."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Az arccal kapcsolatos művelet törölve."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Az arcalapú feloldást megszakította a felhasználó."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Túl sok próbálkozás. Próbálja újra később."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Túl sok próbálkozás. Az arcalapú feloldás letiltva."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nem sikerült ellenőrizni az arcát. Próbálja újra."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Nem állította be az arcalapú feloldást."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Az eszköz nem támogatja az arcalapú feloldást"</string>
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> arc"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Megnyitás a következővel:"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Megnyitás a következővel: %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Megnyitás"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Engedély megadása, hogy a(z) <xliff:g id="HOST">%1$s</xliff:g> linkek a következő alkalmazásban nyíljanak meg:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Engedély megadása, hogy a(z) <xliff:g id="HOST">%1$s</xliff:g> linkek a következő alkalmazásban nyíljanak meg: <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g>-linkek megnyitása a következővel:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Linkek megnyitása a következővel:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Linkek megnyitása a következővel: <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g>-linkek megnyitása a következővel: <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Engedély adása"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Szerkesztés a következővel:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Szerkesztés a következővel: %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"A Tesztelési alapkörnyezet mód kikapcsolásához állítsa vissza a gyári beállításokat."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Az USB-port rendben használható"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"A telefon már nem észlel folyadékot vagy szennyeződést."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hibajelentés készítése…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Megosztja a hibajelentést?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Fogadja a hívást?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Mindig"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Megnyitás mindig ezzel"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Csak egyszer"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Beállítások"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"A(z) %1$s nem támogatja a munkaprofilokat."</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"<xliff:g id="ID">%1$d</xliff:g>. fedvény"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> képpont"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", biztonságos"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ez a háttértevékenység-indítás le lesz tiltva a(z) <xliff:g id="PACKAGENAME">%1$s</xliff:g> számára a jövőbeni Q-buildeknél. Lásd: g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"A(z) <xliff:g id="PACKAGENAME">%1$s</xliff:g> számára le van tiltva a háttértevékenységek indítása. Lásd: g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Elfelejtett minta"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Helytelen minta"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Helytelen jelszó"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"A Kisegítő lehetőségek gyorsparancsa bekapcsolta a következő szolgáltatást: <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"A Kisegítő lehetőségek gyorsparancsa kikapcsolta a következő szolgáltatást: <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> használatához tartsa lenyomva három másodpercig a két hangerőgombot"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Válassza ki a Kisegítő lehetőségek gombra koppintáskor használni kívánt funkciót:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"A funkciók módosításához tartsa lenyomva a Kisegítő lehetőségek gombot."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Válassza ki a kisegítő lehetőségek gombra koppintáskor használni kívánt szolgáltatást:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Válassza ki a kisegítő kézmozdulattal használni kívánt szolgáltatást (csúsztassa felfelé két ujját a képernyő aljáról):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Válassza ki a kisegítő kézmozdulattal használni kívánt szolgáltatást (csúsztassa felfelé három ujját a képernyő aljáról):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"A szolgáltatások közötti váltáshoz tartsa lenyomva a kisegítő lehetőségek gombot."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"A szolgáltatások közötti váltáshoz csúsztassa felfelé két ujját, és ne engedje el a képernyőt."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"A szolgáltatások közötti váltáshoz csúsztassa felfelé három ujját, és ne engedje el a képernyőt."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Nagyítás"</string>
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Átváltás erre: <xliff:g id="NAME">%1$s</xliff:g>..."</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index d99afcb9..7165df9 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -104,7 +104,7 @@
     <string name="serviceClassFAX" msgid="5566624998840486475">"Ֆաքս"</string>
     <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
     <string name="serviceClassDataAsync" msgid="4523454783498551468">"Չհամաժամեցված"</string>
-    <string name="serviceClassDataSync" msgid="7530000519646054776">"Համաժամել"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Համաժամացնել"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"Փաթեթ"</string>
     <string name="serviceClassPAD" msgid="3235259085648271037">"Հարթակ"</string>
     <string name="roamingText0" msgid="7170335472198694945">"Ռոումինգի ցուցիչը միացված է"</string>
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-ի միջոցով զանգեր"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Զանգեր Wi-Fi-ի միջոցով"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Զանգ WLAN ցանցով"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ցանցով զանգեր"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -168,8 +169,8 @@
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Չհաջողվեց գտնել հարցվող ֆայլը:"</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Չափից շատ հարցումներ են մշակվում: Փորձեք կրկին ավելի ուշ:"</string>
     <string name="notification_title" msgid="8967710025036163822">"Մուտք գործելու սխալ` <xliff:g id="ACCOUNT">%1$s</xliff:g>-ի համար"</string>
-    <string name="contentServiceSync" msgid="8353523060269335667">"Համաժամեցնել"</string>
-    <string name="contentServiceSyncNotificationTitle" msgid="7036196943673524858">"Չի հաջողվում համաժամեցնել"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Համաժամացնել"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="7036196943673524858">"Չի հաջողվում համաժամացնել"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4884451152168188763">"Հետևյալ ծառայությունից չափազանց շատ տարրեր եք ջնջել՝ <xliff:g id="CONTENT_TYPE">%s</xliff:g>:"</string>
     <string name="low_memory" product="tablet" msgid="6494019234102154896">"Պլանշետի պահոցը լիքն է: Ջնջեք մի քանի ֆայլ` տարածք ազատելու համար:"</string>
     <string name="low_memory" product="watch" msgid="4415914910770005166">"Ժամացույցի ֆայլերի պահեստը լիքն է: Ջնջեք որոշ ֆայլեր՝ տարածք ազատելու համար:"</string>
@@ -255,7 +256,8 @@
     <string name="notification_channel_security" msgid="7345516133431326347">"Անվտանգություն"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Մեքենայի ռեժիմ"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Հաշվի կարգավիճակ"</string>
-    <string name="notification_channel_developer" msgid="7579606426860206060">"Մշակողի հաղորդագրություններ"</string>
+    <string name="notification_channel_developer" msgid="7579606426860206060">"Հաղորդագրություններ ծրագրավորողների համար"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Կարևոր հաղորդագրություններ մշակողից"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Թարմացումներ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Ցանցի կարգավիճակ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Ցանցային զգուշացումներ"</string>
@@ -280,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Թույլատրե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին օգտագործել ձեր կոնտակտները"</string>
     <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="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="1347189607421252902">"Տեղադրության տվյալները հասանելի կլինեն հավելվածին, միայն երբ այն օգտագործելիս լինեք"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;Միշտ&lt;/b&gt; հասանելի դարձնե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին ձեր սարքի տեղադրությունը"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"Տեղադրության տվյալները հասանելի կլինեն հավելվածին, միայն երբ այն օգտագործելիս լինեք"</string>
@@ -344,7 +346,7 @@
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"կարդալ բջջային զեկուցվող հաղորդագրությունները"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Թույլ է տալիս հավելվածին կարդալ ձեր սարքի կողմից ստացված բջջային հեռարձակվող հաղորդագրությունները: Բջջային հեռարձակվող զգուշացումները ուղարկվում են որոշ վայրերում` արտակարգ իրավիճակների մասին ձեզ զգուշացնելու համար: Վնասարար հավելվածները կարող են խանգարել ձեր սարքի արդյունավետությանը կամ շահագործմանը, երբ ստացվում է արտակարգ իրավիճակի մասին բջջային հաղորդում:"</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"կարդալ բաժանորդագրված հոսքերը"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Թույլ է տալիս հավելվածին մանրամասներ ստանալ ընթացիկ համաժամեցված հոսքերի մասին:"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Թույլ է տալիս հավելվածին մանրամասներ ստանալ ընթացիկ համաժամացված հոսքերի մասին:"</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMS հաղորդագրությունների ուղարկում և ընթերցում"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"Թույլ է տալիս հավելվածին ուղարկել SMS հաղորդագրություններ: Այն կարող է անսպասելի ծախսերի պատճառ դառնալ: Վնասարար հավելվածները կարող են ձեր հաշվից գումար ծախսել` ուղարկելով հաղորդագրություններ`  առանց ձեր հաստատման:"</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"կարդալ ձեր տեքստային հաղորդագրությունները (SMS կամ MMS)"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Մատնահետքի պատկերակ"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"կառավարել դեմքով ապակողպման համար սարքը"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Հավելվածին թույլ է տալիս ավելացնել և հեռացնել դեմքի նմուշներ:"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"օգտագործել դեմքով ապակողպման համար սարքը"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Թույլ է տալիս հավելվածին օգտագործել դեմքով ապակողպման համար նախատեսված սարքը"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Դեմքով ապակողպում"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Նորից գրանցեք ձեր դեմքը"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Ճանաչումը լավացնելու համար նորից գրանցեք ձեր դեմքը"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Չհաջողվեց գրանցել դեմքի ճշգրիտ տվյալները։ Կրկնեք։"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Տեղափոխեք հեռախոսը ձախ:"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Տեղափոխեք հեռախոսը աջ:"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Նայեք ուղիղ էկրանին։"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Ձեր դեմքը չի երևում։ Նայեք հեռախոսին։"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Պահեք ձեր դեմքն անմիջապես հեռախոսի էկրանի դիմաց:"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Շատ եք շարժում։ Հեռախոսն անշարժ պահեք։"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Նորից փորձեք։"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Չհաջողվեց ճանաչել դեմքը։ Նորից փորձեք:"</string>
@@ -579,34 +577,29 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Գլուխն ուղիղ պահեք։"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Գլուխն ուղիղ պահեք։"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Հեռացրեք այն ամենը, ինչը թաքցնում է ձեր երեսը:"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Մաքրեք էկրանի վերևի անկյունում գտնվող տվիչը:"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Մաքրեք էկրանի վերևի մասը, ներառյալ սև գոտին"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Չհաջողվեց հաստատել դեմքը։ Սարքն անհասանելի է:"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Նորից փորձեք դեմքով ապակողպումը։"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Չհաջողվեց պահել նոր դեմքը։ Ջնջեք հին տարբերակը։"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Դեմքի ճանաչումը չեղարկվել է։"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Դեմքով ապակողմումը չեղարկվել է օգտատիրոջ կողմից:"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Չափից շատ փորձեր եք կատարել: Փորձեք ավելի ուշ:"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Չափազանց շատ փորձեր են արվել։ Դեմքով ապակողպումն անջատված է:"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Չհաջողվեց հաստատել դեմքը։ Նորից փորձեք։"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Դուք չեք կարգավորել դեմքով ապակողպումը:"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Դեմքով ապակողպումն այս սարքում չի աջակցվում"</string>
     <string name="face_name_template" msgid="7004562145809595384">"Դեմք <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_icon_content_description" msgid="4024817159806482191">"Դեմքի պատկերակ"</string>
-    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"կարդալ համաժամեցման կարգավորումները"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Թույլ է տալիս հավելվածին կարդալ համաժամեցման կարգավորումները հաշվի համար: Օրինակ` այն կարող է որոշել, արդյոք Մարդիկ հավելվածը համաժամեցված է հաշվի հետ:"</string>
-    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"համաժամեցումը փոխարկել միացվածի և անջատվածի"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Թույլ է տալիս հավելվածին փոփոխել համաժամեցման կարգավորումները հաշվի համար: Օրինակ, այն կարող է օգտագործվել` միացնելու Մարդիկ հավելվածի համաժամեցումը հաշվի հետ:"</string>
-    <string name="permlab_readSyncStats" msgid="7396577451360202448">"կարդալ համաժամեցման վիճակագրությունը"</string>
-    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Թույլ է տալիս հավելվածին կարդալ հաշվի համաժամեցման վիճակագրությունը, այդ թվում` համաժամեցման իրադարձությունների պատմությունը և թե որքան տվյալ է համաժամեցված:"</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"կարդալ համաժամացման կարգավորումները"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Թույլ է տալիս հավելվածին կարդալ համաժամացման կարգավորումները հաշվի համար: Օրինակ` այն կարող է որոշել, արդյոք Մարդիկ հավելվածը համաժամացված է հաշվի հետ:"</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"համաժամացումը փոխարկել միացվածի և անջատվածի"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Թույլ է տալիս հավելվածին փոփոխել համաժամացման կարգավորումները հաշվի համար: Օրինակ, այն կարող է օգտագործվել` միացնելու Մարդիկ հավելվածի համաժամացումը հաշվի հետ:"</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"կարդալ համաժամացման վիճակագրությունը"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Թույլ է տալիս հավելվածին կարդալ հաշվի համաժամացման վիճակագրությունը, այդ թվում` համաժամացման իրադարձությունների պատմությունը և թե որքան տվյալ է համաժամացված:"</string>
     <string name="permlab_sdcardRead" msgid="1438933556581438863">"կարդալ ձեր ընդհանուր հիշողության պարունակությունը"</string>
     <string name="permdesc_sdcardRead" msgid="1804941689051236391">"Հավելվածին թույլ է տալիս կարդալ ձեր ընդհանուր հիշողության պարունակությունը:"</string>
     <string name="permlab_sdcardWrite" msgid="9220937740184960897">"փոփոխել կամ ջնջել ձեր ընդհանուր հիշողության բովանդակությունը"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Բացել հետևյալ ծրագրով՝"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Բացել հավելվածով՝ %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Բացել"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Թույլատրեք, որ <xliff:g id="HOST">%1$s</xliff:g> տիրույթը հղումները բացվեն հետևյալ հավելվածում՝"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Թույլատրեք, որ <xliff:g id="HOST">%1$s</xliff:g> տիրույթի հղումները բացվեն <xliff:g id="APPLICATION">%2$s</xliff:g> հավելվածում"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> տեսակի հղումները բացել…"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Հղումները բացել…"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Հղումները բացել <xliff:g id="APPLICATION">%1$s</xliff:g> դիտարկիչում"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> տեսակի հղումները բացել <xliff:g id="APPLICATION">%2$s</xliff:g> դիտարկիչում"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Թույլատրել"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Խմբագրել հետևյալ ծրագրով՝"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Խմբագրել հետևյալով՝ %1$s"</string>
@@ -1157,7 +1152,7 @@
     <string name="whichImageCaptureApplicationNamed" msgid="8619384150737825003">"Լուսանկարել %1$s հավելվածի օգնությամբ"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6390303445371527066">"Լուսանկարել"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Օգտագործել ըստ կանխադրման այս գործողության համար:"</string>
-    <string name="use_a_different_app" msgid="8134926230585710243">"Օգտագործել այլ հավելված"</string>
+    <string name="use_a_different_app" msgid="8134926230585710243">"Ուրիշ հավելված"</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Մաքրել լռելյայնը Համակարգի կարգավորումներ &gt; Ծրագրեր &gt;Ներբեռնված էջից:"</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Ընտրել գործողություն"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Ընտրեք հավելված USB սարքի համար"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB միացքում ջուր կամ աղտ է հայտնաբերվել"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB միացքն ավտոմատ անջատվել է: Հպեք՝ ավելին իմանալու համար:"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB միացքը կարող է օգտագործվել"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Հեռախոսում ջուր կամ աղտ չի հայտնաբերվել:"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Վրիպակի զեկույցի ստեղծում…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Տրամադրե՞լ վրիպակի զեկույցը:"</string>
@@ -1459,7 +1453,7 @@
     <string name="forward_intent_to_owner" msgid="1207197447013960896">"Դուք օգտագործում եք այս հավելվածը ձեր աշխատանքային պրոֆիլից դուրս"</string>
     <string name="forward_intent_to_work" msgid="621480743856004612">"Դուք օգտագործում եք այս հավելվածը ձեր աշխատանքային պրոֆիլում"</string>
     <string name="input_method_binding_label" msgid="1283557179944992649">"Ներածման եղանակը"</string>
-    <string name="sync_binding_label" msgid="3687969138375092423">"Համաժամել"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Համաժամացնել"</string>
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Մատչելիությունը"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Պաստառ"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Փոխել պաստառը"</string>
@@ -1592,7 +1586,8 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Գործարկե՞լ զննարկիչը:"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Ընդունե՞լ զանգը:"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Միշտ"</string>
-    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Միայն մեկ անգամ"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Միշտ բացել"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Միայն այս անգամ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Կարգավորումներ"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s-ը չի աջակցում աշխատանքային պրոֆիլներ"</string>
     <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Գրասալիկ"</string>
@@ -1619,10 +1614,8 @@
     <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ներկառուցված էկրան"</string>
     <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI էկրան"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Վերածածկ #<xliff:g id="ID">%1$d</xliff:g>"</string>
-    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> կմվ"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> կմչ"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", անվտանգ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> հավելվածի գործողությունները ֆոնային ռեժիմում կարգելափակվեն Android Q-ի հաջորդ կառուցումներում։ Մանրամասն տեղեկություններ կարող եք գտնել g.co/dev/bgblock էջում։"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> հավելվածի գործողությունները ֆոնային ռեժիմում արգելափակվեցին։ Մանրամասն տեղեկություններ կարող եք գտնել g.co/dev/bgblock էջում։"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Մոռացել եմ սխեման"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Սխալ սխեմա"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Սխալ գաղտնաբառ"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Մատչելիության դյուրանցումն միացրել է <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Մատչելիության դյուրանցումն անջատել է <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"«<xliff:g id="SERVICE_NAME">%1$s</xliff:g>» ծառայությունն օգտագործելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակները"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Ընտրեք որևէ գործառույթ, որը կօգտագործվի Հատուկ գործառույթներ կոճակին հպելու դեպքում՝"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Գործառույթները փոխելու համար հպեք և պահեք Հատուկ գործառույթներ կոճակը։"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Ընտրեք ծառայությունը, որը կգործարկվի «Հատուկ գործառույթներ» կոճակին հպելու դեպքում՝"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Ընտրեք ծառայությունը, որը կգործարկվի հատուկ գործառույթների ժեստն անելու դեպքում (երկու մատը էկրանի ներքևից սահեցրեք վերև)՝"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Ընտրեք ծառայությունը, որը կգործարկվի հատուկ գործառույթների ժեստն անելու դեպքում (երեք մատը էկրանի ներքևից սահեցրեք վերև)՝"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Մեկ ծառայությունից մյուսին անցնելու համար հպեք «Հատուկ գործառույթներ» կոճակին և պահեք:"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Մեկ ծառայությունից մյուսին անցնելու համար երկու մատը սահեցրեք վերև և պահեք:"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Մեկ ծառայությունից մյուսին անցնելու համար երեք մատը սահեցրեք վերև և պահեք:"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Խոշորացում"</string>
     <string name="user_switched" msgid="3768006783166984410">"Ներկայիս օգտատերը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Փոխարկվում է <xliff:g id="NAME">%1$s</xliff:g>-ին..."</string>
@@ -1910,7 +1907,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Ստուգել նոր տարբերակի առկայությունը"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Դուք ունեք նոր հաղորդագրություններ"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Դիտելու համար բացել SMS հավելվածը"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Որոշ գործառույթներ կարող են չգործել"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Որոշ գործառույթներ կարող են չաշխատել"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Աշխատանքային պրոֆիլը կողպված է"</string>
     <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>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index a3cc652..ca369eb 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -30,7 +30,7 @@
     <string name="untitled" msgid="4638956954852782576">"&lt;Tanpa judul&gt;"</string>
     <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Tidak ada nomor telepon)"</string>
     <string name="unknownName" msgid="6867811765370350269">"Tidak diketahui"</string>
-    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Kotak Pesan"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Pesan suara"</string>
     <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
     <string name="mmiError" msgid="5154499457739052907">"Masalah sambungan atau kode MMI tidak valid."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"Operasi dibatasi untuk nomor panggilan tetap saja."</string>
@@ -84,7 +84,7 @@
     <string name="RestrictedStateContent" msgid="6538703255570997248">"Dinonaktifkan sementara oleh operator"</string>
     <string name="RestrictedStateContentMsimTemplate" msgid="673416791370248176">"Dinonaktifkan sementara oleh operator untuk SIM <xliff:g id="SIMNUMBER">%d</xliff:g>"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="6982395015324165258">"Tidak dapat menjangkau jaringan seluler"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Coba ubah jaringan pilihan. Tap untuk mengubah."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Coba ubah jaringan pilihan. Ketuk untuk mengubah."</string>
     <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"Panggilan darurat tidak tersedia"</string>
     <string name="EmergencyCallWarningSummary" msgid="1899692069750260619">"Tidak dapat melakukan panggilan darurat melalui Wi-Fi"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"Notifikasi"</string>
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Panggilan WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Panggilan WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -187,7 +188,7 @@
     <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Profil kerja tidak tersedia lagi di perangkat ini"</string>
     <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"Terlalu banyak percobaan memasukkan sandi"</string>
     <string name="network_logging_notification_title" msgid="6399790108123704477">"Perangkat ini ada yang mengelola"</string>
-    <string name="network_logging_notification_text" msgid="7930089249949354026">"Organisasi mengelola perangkat ini dan mungkin memantau traffic jaringan. Tap untuk melihat detailnya."</string>
+    <string name="network_logging_notification_text" msgid="7930089249949354026">"Organisasi mengelola perangkat ini dan mungkin memantau traffic jaringan. Ketuk untuk melihat detailnya."</string>
     <string name="factory_reset_warning" msgid="5423253125642394387">"Perangkat akan dihapus"</string>
     <string name="factory_reset_message" msgid="9024647691106150160">"Aplikasi admin tidak dapat digunakan. Perangkat Anda kini akan dihapus.\n\nJika ada pertanyaan, hubungi admin organisasi."</string>
     <string name="printing_disabled_by" msgid="8936832919072486965">"Fitur pencetakan dinonaktifkan oleh <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Mode mobil"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Status akun"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Pesan developer"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Pesan developer penting"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Update"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status jaringan"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Notifikasi jaringan"</string>
@@ -269,7 +271,7 @@
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikasi yang menggunakan baterai"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang menggunakan baterai"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikasi sedang meggunakan baterai"</string>
-    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap untuk melihat detail penggunaan baterai dan data"</string>
+    <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Ketuk untuk melihat detail penggunaan baterai dan data"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
     <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Gerakkan ponsel ke kiri."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Gerakkan ponsel ke kanan."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Lihat langsung ke perangkat."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Tidak dapat melihat wajah Anda. Lihat ke ponsel."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Posisikan wajah Anda langsung di depan ponsel."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Terlalu banyak gerakan. Stabilkan ponsel."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Daftarkan ulang wajah Anda."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Tidak lagi dapat mengenali wajah. Coba lagi."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Putar sedikit kepala Anda."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Putar sedikit kepala Anda."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Singkirkan apa saja yang menutupi wajah Anda."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Bersihkan sensor di tepi atas layar."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Bersihkan bagian atas layar, termasuk kotak hitam"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Tidak dapat memverifikasi wajah. Hardware tidak tersedia."</string>
@@ -584,7 +586,7 @@
     <string name="face_error_canceled" msgid="283945501061931023">"Pemrosesan wajah dibatalkan."</string>
     <string name="face_error_user_canceled" msgid="5317030072349668946">"Face unlock 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="4723594314443097159">"Terlalu banyak percobaan. Face unlock dinonaktifkan."</string>
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Terlalu banyak gagal. Face unlock dinonaktifkan."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Tidak dapat memverifikasi wajah. Coba lagi."</string>
     <string name="face_error_not_enrolled" msgid="4016937174832839540">"Anda belum menyiapkan face unlock."</string>
     <string name="face_error_hw_not_present" msgid="8302690289757559738">"Face unlock tidak didukung di perangkat ini."</string>
@@ -799,7 +801,7 @@
     <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Ketik kode PUK dan PIN baru"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"Kode PUK"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Kode Pin baru"</string>
-    <string name="keyguard_password_entry_touch_hint" msgid="2644215452200037944"><font size="17">"Tap untuk mengetik sandi"</font></string>
+    <string name="keyguard_password_entry_touch_hint" msgid="2644215452200037944"><font size="17">"Ketuk untuk mengetik sandi"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Ketik sandi untuk membuka kunci"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Ketik PIN untuk membuka kunci"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Kode PIN salah."</string>
@@ -911,7 +913,7 @@
     <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Tetap di Halaman ini"</string>
     <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nYakin ingin beranjak dari halaman ini?"</string>
     <string name="save_password_label" msgid="6860261758665825069">"Konfirmasi"</string>
-    <string name="double_tap_toast" msgid="4595046515400268881">"Kiat: Tap dua kali untuk memperbesar dan memperkecil."</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Kiat: Ketuk dua kali untuk memperbesar dan memperkecil."</string>
     <string name="autofill_this_form" msgid="4616758841157816676">"IsiOtomatis"</string>
     <string name="setup_autofill" msgid="7103495070180590814">"Siapkan Pengisian Otomatis"</string>
     <string name="autofill_window_title" msgid="4107745526909284887">"IsiOtomatis dengan <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
@@ -1114,7 +1116,7 @@
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak dapat bekerja"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Penyimpanan tidak cukup untuk sistem. Pastikan Anda memiliki 250 MB ruang kosong, lalu mulai ulang."</string>
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan"</string>
-    <string name="app_running_notification_text" msgid="1197581823314971177">"Tap untuk informasi selengkapnya atau menghentikan aplikasi."</string>
+    <string name="app_running_notification_text" msgid="1197581823314971177">"Ketuk untuk informasi selengkapnya atau menghentikan aplikasi."</string>
     <string name="ok" msgid="5970060430562524910">"Oke"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
     <string name="yes" msgid="5362982303337969312">"Oke"</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Buka dengan"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Buka dengan %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Buka"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Berikan akses untuk membuka link <xliff:g id="HOST">%1$s</xliff:g> dengan"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Berikan akses untuk membuka link <xliff:g id="HOST">%1$s</xliff:g> dengan <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Buka link <xliff:g id="HOST">%1$s</xliff:g> dengan"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Buka link dengan"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Buka link dengan <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Buka link <xliff:g id="HOST">%1$s</xliff:g> dengan <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Berikan akses"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edit dengan"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit dengan %1$s"</string>
@@ -1200,7 +1204,7 @@
     <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulai aplikasi."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Menyelesaikan boot."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> berjalan"</string>
-    <string name="heavy_weight_notification_detail" msgid="2304833848484424985">"Tap untuk kembali ke game"</string>
+    <string name="heavy_weight_notification_detail" msgid="2304833848484424985">"Ketuk untuk kembali ke game"</string>
     <string name="heavy_weight_switcher_title" msgid="387882830435195342">"Pilih game"</string>
     <string name="heavy_weight_switcher_text" msgid="4176781660362912010">"Agar performa tetap maksimal, hanya 1 game yang dapat dibuka sekaligus."</string>
     <string name="old_app_action" msgid="3044685170829526403">"Kembali ke <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
@@ -1208,7 +1212,7 @@
     <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>
     <string name="dump_heap_ready_notification" msgid="1162196579925048701">"Heap dump <xliff:g id="PROC">%1$s</xliff:g> siap"</string>
-    <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Informasi memori dikumpulkan. Tap untuk membagikan."</string>
+    <string name="dump_heap_notification_detail" msgid="3993078784053054141">"Informasi memori dikumpulkan. Ketuk untuk membagikan."</string>
     <string name="dump_heap_title" msgid="5864292264307651673">"Share tumpukan membuang?"</string>
     <string name="dump_heap_text" msgid="8546022920319781701">"Proses <xliff:g id="PROC">%1$s</xliff:g> telah melampaui batas memori <xliff:g id="SIZE">%2$s</xliff:g>. Heap dump tersedia untuk Anda bagikan kepada developernya. Hati-hati, heap dump ini dapat memuat informasi pribadi yang dapat diakses oleh aplikasi."</string>
     <string name="dump_heap_system_text" msgid="3236094872980706024">"Proses <xliff:g id="PROC">%1$s</xliff:g> telah melampaui batas memori sebesar <xliff:g id="SIZE">%2$s</xliff:g>. Heap dump tersedia untuk Anda bagikan. Hati-hati, heap dump ini dapat memuat informasi pribadi sensitif yang dapat diakses oleh proses, yang dapat menyertakan informasi yang Anda ketik."</string>
@@ -1248,7 +1252,7 @@
     <string name="wifi_available_title_connecting" msgid="1139126673968899002">"Menghubungkan ke jaringan Wi-Fi"</string>
     <string name="wifi_available_title_connected" msgid="7542672851522241548">"Terhubung ke jaringan Wi-Fi"</string>
     <string name="wifi_available_title_failed_to_connect" msgid="6861772233582618132">"Tidak dapat menghubungkan ke jaringan Wi‑Fi"</string>
-    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap untuk melihat semua jaringan"</string>
+    <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketuk 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="9099832833531486167">"Sambungkan perangkat ke jaringan Wi-Fi?"</string>
@@ -1265,10 +1269,10 @@
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_no_internet" msgid="5198100389964214865">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> tidak memiliki akses internet"</string>
-    <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Tap untuk melihat opsi"</string>
+    <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"Ketuk untuk melihat opsi"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"Tersambung"</string>
     <string name="network_partial_connectivity" msgid="7774883385494762741">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> memiliki konektivitas terbatas"</string>
-    <string name="network_partial_connectivity_detailed" msgid="1959697814165325217">"Tap untuk tetap menyambungkan"</string>
+    <string name="network_partial_connectivity_detailed" msgid="1959697814165325217">"Ketuk untuk tetap menyambungkan"</string>
     <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>
@@ -1292,7 +1296,7 @@
     <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Memulai Wi-Fi Direct. Opsi ini akan mematikan hotspot/klien Wi-Fi."</string>
     <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Tidak dapat memulai Wi-Fi Direct."</string>
     <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct aktif"</string>
-    <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"Tap untuk setelan"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"Ketuk untuk setelan"</string>
     <string name="accept" msgid="1645267259272829559">"Terima"</string>
     <string name="decline" msgid="2112225451706137894">"Tolak"</string>
     <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Undangan terkirim"</string>
@@ -1329,7 +1333,7 @@
     <string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"Download aplikasi <xliff:g id="APP_NAME">%1$s</xliff:g> untuk mengaktifkan SIM baru"</string>
     <string name="install_carrier_app_notification_button" msgid="3094206295081900849">"Download aplikasi"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"SIM baru dimasukkan"</string>
-    <string name="carrier_app_notification_text" msgid="1132487343346050225">"Tap untuk menyiapkan"</string>
+    <string name="carrier_app_notification_text" msgid="1132487343346050225">"Ketuk untuk menyiapkan"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Setel waktu"</string>
     <string name="date_picker_dialog_title" msgid="5879450659453782278">"Setel tanggal"</string>
     <string name="date_time_set" msgid="5777075614321087758">"Setel"</string>
@@ -1346,17 +1350,17 @@
     <string name="usb_tether_notification_title" msgid="3716143122035802501">"Tethering USB diaktifkan"</string>
     <string name="usb_midi_notification_title" msgid="5356040379749154805">"MIDI via USB diaktifkan"</string>
     <string name="usb_accessory_notification_title" msgid="1785694450621427730">"Aksesori USB tersambung"</string>
-    <string name="usb_notification_message" msgid="3370903770828407960">"Tap untuk opsi lainnya."</string>
-    <string name="usb_power_notification_message" msgid="4647527153291917218">"Mengisi daya perangkat yang terhubung. Tap untuk opsi lainnya."</string>
+    <string name="usb_notification_message" msgid="3370903770828407960">"Ketuk untuk opsi lainnya."</string>
+    <string name="usb_power_notification_message" msgid="4647527153291917218">"Mengisi daya perangkat yang terhubung. Ketuk untuk opsi lainnya."</string>
     <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Aksesori audio analog terdeteksi"</string>
-    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Perangkat yang terpasang tidak kompatibel dengan ponsel ini. Tap untuk mempelajari lebih lanjut."</string>
+    <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Perangkat yang terpasang tidak kompatibel dengan ponsel ini. Ketuk untuk mempelajari lebih lanjut."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Proses debug USB terhubung"</string>
-    <string name="adb_active_notification_message" msgid="7463062450474107752">"Tap untuk menonaktifkan proses debug USB"</string>
+    <string name="adb_active_notification_message" msgid="7463062450474107752">"Ketuk untuk menonaktifkan proses debug USB"</string>
     <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
     <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Mode Tes Otomatis diaktifkan"</string>
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Lakukan reset ke setelan pabrik untuk menonaktifkan Mode Tes Otomatis."</string>
     <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_detected_message" msgid="832337061059487250">"Port USB otomatis dinonaktifkan. Ketuk untuk mempelajari lebih lanjut."</string>
     <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Boleh menggunakan port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Ponsel tidak lagi mendeteksi adanya cairan atau kotoran."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Mengambil laporan bug…"</string>
@@ -1369,24 +1373,24 @@
     <string name="show_ime" msgid="2506087537466597099">"Pertahankan di layar jika keyboard fisik masih aktif"</string>
     <string name="hardware" msgid="194658061510127999">"Tampilkan keyboard virtual"</string>
     <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Mengonfigurasi keyboard fisik"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap untuk memilih bahasa dan tata letak"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ketuk untuk memilih bahasa dan tata letak"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Tampilkan di atas apl lain"</string>
     <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> ditampilkan di atas aplikasi lain"</string>
     <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> ditampilkan di atas aplikasi lain"</string>
-    <string name="alert_windows_notification_message" msgid="8917232109522912560">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, tap untuk membuka setelan dan menonaktifkannya."</string>
+    <string name="alert_windows_notification_message" msgid="8917232109522912560">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, ketuk untuk membuka setelan dan menonaktifkannya."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Nonaktifkan"</string>
     <string name="ext_media_checking_notification_title" msgid="4411133692439308924">"Memeriksa <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="410185170877285434">"Meninjau konten saat ini"</string>
     <string name="ext_media_new_notification_title" msgid="1621805083736634077">"<xliff:g id="NAME">%s</xliff:g> baru"</string>
-    <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Tap untuk menyiapkan"</string>
+    <string name="ext_media_new_notification_message" msgid="3673685270558405087">"Ketuk untuk menyiapkan"</string>
     <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Untuk mentransfer foto dan media"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4179418065210797130">"Masalah pada <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Tap untuk memperbaiki"</string>
+    <string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Ketuk untuk memperbaiki"</string>
     <string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"<xliff:g id="NAME">%s</xliff:g> rusak. Pilih untuk memperbaikinya."</string>
     <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> tidak didukung"</string>
-    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Perangkat tidak mendukung <xliff:g id="NAME">%s</xliff:g> ini. Tap untuk menyiapkan dalam format yang didukung."</string>
+    <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Perangkat tidak mendukung <xliff:g id="NAME">%s</xliff:g> ini. Ketuk untuk menyiapkan dalam format yang didukung."</string>
     <string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Perangkat ini tidak mendukung <xliff:g id="NAME">%s</xliff:g> ini. Pilih untuk menyiapkan dalam format yang didukung."</string>
     <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> tiba-tiba dicabut"</string>
     <string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Keluarkan media sebelum mencabut agar konten tidak hilang"</string>
@@ -1428,7 +1432,7 @@
     <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"Mengizinkan aplikasi meminta penghapusan paket."</string>
     <string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"meminta mengabaikan pengoptimalan baterai"</string>
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"Mengizinkan aplikasi meminta izin untuk mengabaikan pengoptimalan baterai bagi aplikasi tersebut."</string>
-    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Tap dua kali untuk kontrol perbesar/perkecil"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Ketuk dua kali untuk kontrol perbesar/perkecil"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Tidak dapat menambahkan widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Buka"</string>
     <string name="ime_action_search" msgid="658110271822807811">"Telusuri"</string>
@@ -1459,8 +1463,8 @@
     <string name="notification_ranker_binding_label" msgid="774540592299064747">"Layanan penentu peringkat notifikasi"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN diaktifkan"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"VPN diaktifkan oleh <xliff:g id="APP">%s</xliff:g>"</string>
-    <string name="vpn_text" msgid="1610714069627824309">"Tap untuk mengelola jaringan."</string>
-    <string name="vpn_text_long" msgid="4907843483284977618">"Tersambung ke <xliff:g id="SESSION">%s</xliff:g>. Tap untuk mengelola jaringan."</string>
+    <string name="vpn_text" msgid="1610714069627824309">"Ketuk untuk mengelola jaringan."</string>
+    <string name="vpn_text_long" msgid="4907843483284977618">"Tersambung ke <xliff:g id="SESSION">%s</xliff:g>. Ketuk untuk mengelola jaringan."</string>
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Menyambungkan VPN selalu aktif..."</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"VPN selalu aktif tersambung"</string>
     <string name="vpn_lockdown_disconnected" msgid="735805531187559719">"Terputus dari VPN yang selalu aktif"</string>
@@ -1471,9 +1475,9 @@
     <string name="reset" msgid="2448168080964209908">"Setel ulang"</string>
     <string name="submit" msgid="1602335572089911941">"Kirim"</string>
     <string name="car_mode_disable_notification_title" msgid="5704265646471239078">"Aplikasi mengemudi sedang berjalan"</string>
-    <string name="car_mode_disable_notification_message" msgid="7647248420931129377">"Tap untuk keluar dari aplikasi mengemudi."</string>
+    <string name="car_mode_disable_notification_message" msgid="7647248420931129377">"Ketuk untuk keluar dari aplikasi mengemudi."</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"Tethering (Penambatan) atau hotspot aktif"</string>
-    <string name="tethered_notification_message" msgid="2113628520792055377">"Tap untuk menyiapkan."</string>
+    <string name="tethered_notification_message" msgid="2113628520792055377">"Ketuk untuk menyiapkan."</string>
     <string name="disable_tether_notification_title" msgid="7526977944111313195">"Tethering dinonaktifkan"</string>
     <string name="disable_tether_notification_message" msgid="2913366428516852495">"Hubungi admin untuk mengetahui detailnya"</string>
     <string name="back_button_label" msgid="2300470004503343439">"Kembali"</string>
@@ -1504,10 +1508,10 @@
     <string name="sync_do_nothing" msgid="3743764740430821845">"Jangan lakukan apa pun untuk saat ini"</string>
     <string name="choose_account_label" msgid="5655203089746423927">"Pilih akun"</string>
     <string name="add_account_label" msgid="2935267344849993553">"Tambahkan akun"</string>
-    <string name="add_account_button_label" msgid="3611982894853435874">"Tambah akun"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Tambahkan akun"</string>
     <string name="number_picker_increment_button" msgid="2412072272832284313">"Tambah"</string>
     <string name="number_picker_decrement_button" msgid="476050778386779067">"Kurangi"</string>
-    <string name="number_picker_increment_scroll_mode" msgid="5259126567490114216">"<xliff:g id="VALUE">%s</xliff:g> sentuh &amp; tahan."</string>
+    <string name="number_picker_increment_scroll_mode" msgid="5259126567490114216">"<xliff:g id="VALUE">%s</xliff:g> sentuh lama."</string>
     <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Geser ke atas untuk menambah dan ke bawah untuk mengurangi."</string>
     <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Tambah menit"</string>
     <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Kurangi menit"</string>
@@ -1534,7 +1538,7 @@
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Tidak dapat meluncurkan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Berbagi dengan"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Berbagi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="content_description_sliding_handle" msgid="415975056159262248">"Gagang geser. Sentuh &amp; tahan."</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Gagang geser. Sentuh lama."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Geser untuk membuka kunci."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Navigasi ke beranda"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Navigasi naik"</string>
@@ -1557,7 +1561,7 @@
     <string name="data_usage_wifi_limit_snoozed_title" msgid="3547771791046344188">"Melebihi batas kuota Wi-Fi Anda"</string>
     <string name="data_usage_limit_snoozed_body" msgid="1671222777207603301">"Anda telah menggunakan <xliff:g id="SIZE">%s</xliff:g> melebihi batas yang ditetapkan"</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"Data latar belakang dibatasi"</string>
-    <string name="data_usage_restricted_body" msgid="469866376337242726">"Tap untuk menghapus batasan."</string>
+    <string name="data_usage_restricted_body" msgid="469866376337242726">"Ketuk untuk menghapus batasan."</string>
     <string name="data_usage_rapid_title" msgid="1809795402975261331">"Penggunaan kuota yang tinggi"</string>
     <string name="data_usage_rapid_body" msgid="6897825788682442715">"Aplikasi Anda menggunakan lebih banyak kuota daripada biasanya"</string>
     <string name="data_usage_rapid_app_body" msgid="5396680996784142544">"<xliff:g id="APP">%s</xliff:g> menggunakan lebih banyak kuota daripada biasanya"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Luncurkan Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Terima panggilan?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Selalu"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Setel untuk selalu membuka"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Hanya sekali"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Setelan"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s tidak mendukung profil kerja"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Hamparan #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", aman"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Aktivitas latar belakang yang dimulai dari <xliff:g id="PACKAGENAME">%1$s</xliff:g> akan diblokir di build Q di masa mendatang. Lihat g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Aktivitas latar belakang yang dimulai dari <xliff:g id="PACKAGENAME">%1$s</xliff:g> diblokir. Lihat g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Pola?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pola Salah"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Sandi Salah"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pintasan Aksesibilitas mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pintasan Aksesibilitas menonaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Tekan dan tahan kedua tombol volume selama tiga detik untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pilih fitur yang akan digunakan saat menge-tap tombol Aksesibilitas:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Untuk mengubah fitur, sentuh &amp; tahan tombol Aksesibilitas."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Pilih layanan yang akan digunakan saat mengetuk tombol aksesibilitas:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Pilih layanan yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan dua jari):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Pilih layanan yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan tiga jari):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Sentuh lama tombol aksesibilitas untuk beralih layanan."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Geser dengan dua jari dan tahan untuk beralih layanan."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Geser ke atas dengan tiga jari dan tahan untuk beralih layanan."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pembesaran"</string>
     <string name="user_switched" msgid="3768006783166984410">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Beralih ke <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1765,7 +1772,7 @@
     <string name="reason_unknown" msgid="6048913880184628119">"tak diketahui"</string>
     <string name="reason_service_unavailable" msgid="7824008732243903268">"Layanan cetak tidak diaktifkan"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"Layanan <xliff:g id="NAME">%s</xliff:g> telah terpasang"</string>
-    <string name="print_service_installed_message" msgid="5897362931070459152">"Tap untuk mengaktifkan"</string>
+    <string name="print_service_installed_message" msgid="5897362931070459152">"Ketuk untuk mengaktifkan"</string>
     <string name="restr_pin_enter_admin_pin" msgid="8641662909467236832">"Masukkan PIN admin"</string>
     <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Masukkan PIN"</string>
     <string name="restr_pin_incorrect" msgid="8571512003955077924">"Tidak benar"</string>
@@ -1803,7 +1810,7 @@
     <string name="confirm_battery_saver" msgid="639106420541753635">"Oke"</string>
     <string name="battery_saver_description_with_learn_more" msgid="2108984221113106294">"Penghemat Baterai menonaktifkan atau membatasi aktivitas di latar belakang, beberapa efek visual &amp; fitur lain yang menggunakan banyak daya untuk memperpanjang masa pakai baterai. "<annotation id="url">"Pelajari Lebih Lanjut"</annotation></string>
     <string name="battery_saver_description" msgid="6413346684861241431">"Penghemat Baterai menonaktifkan atau membatasi aktivitas di latar belakang, beberapa efek visual &amp; fitur lain yang menggunakan banyak daya untuk memperpanjang masa pakai baterai."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"Untuk membantu mengurangi penggunaan kuota, Penghemat Kuota Internet mencegah beberapa aplikasi mengirim atau menerima data di latar belakang. Aplikasi yang sedang digunakan dapat mengakses data, tetapi frekuensinya agak lebih jarang. Misalnya saja, gambar hanya akan ditampilkan setelah di-tap."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"Untuk membantu mengurangi penggunaan kuota, Penghemat Kuota Internet mencegah beberapa aplikasi mengirim atau menerima data di latar belakang. Aplikasi yang sedang digunakan dapat mengakses data, tetapi frekuensinya agak lebih jarang. Misalnya saja, gambar hanya akan ditampilkan setelah diketuk."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"Aktifkan Penghemat Kuota?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"Aktifkan"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1900,11 +1907,11 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Periksa apakah ada update"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Ada pesan baru"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Buka aplikasi SMS untuk melihat"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Beberapa fungsi mungkin terbatas"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Beberapa fitur tidak dapat digunakan"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil kerja terkunci"</string>
-    <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap untuk membuka kunci profil kerja"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Ketuk 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="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Ketuk untuk melihat file"</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>
@@ -1984,9 +1991,9 @@
     <string name="notification_channel_system_changes" msgid="5072715579030948646">"Perubahan sistem"</string>
     <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"Jangan Ganggu"</string>
     <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"Baru: Mode Jangan Ganggu menyembunyikan notifikasi"</string>
-    <string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"Tap untuk mempelajari lebih lanjut dan mengubah."</string>
+    <string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"Ketuk untuk mempelajari lebih lanjut dan mengubah."</string>
     <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Jangan Ganggu telah berubah"</string>
-    <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tap untuk memeriksa item yang diblokir."</string>
+    <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Ketuk untuk memeriksa item yang diblokir."</string>
     <string name="notification_app_name_system" msgid="4205032194610042794">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="7751445616365753381">"Setelan"</string>
     <string name="notification_appops_camera_active" msgid="5050283058419699771">"Kamera"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 00637a4..572313a 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi símtöl"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Wi-Fi símtöl með <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-símtal"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-símtal"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Bílastilling"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Staða reiknings"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Skilaboð þróunaraðila"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mikilvæg skilaboð þróunaraðila"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Uppfærslur"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Staða netkerfis"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Viðvaranir netkerfis"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Fingrafaratákn"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"stjórna vélbúnaði andlitsopnunar"</string>
     <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>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"nota vélbúnað andlitsopnunar"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Leyfir forritinu að nota andlitsopnunarvélbúnað til auðkenningar"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Andlitsopnun"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Skráðu andlitið þitt aftur"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Skráðu andlitið þitt til að bæta kennsl"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Nákvæm andlitsgögn fengust ekki. Reyndu aftur."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Færðu símann til vinstri."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Færðu símann til hægri."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Horfðu beint á tækið."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Sé ekki andlit þitt. Horfðu á símann."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Hafðu andlitið beint fyrir framan símann."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Of mikil hreyfing. Haltu símanum stöðugum."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Skráðu nafnið þitt aftur."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Andlit þekkist ekki lengur. Reyndu aftur."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Hallaðu höfðinu aðeins minna."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Snúðu höfðinu aðeins minna."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Fjarlægðu það sem kann að hylja andlitið."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Hreinsaðu skynjarann á efri brún skjásins."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Hreinsaðu efsta hluta skjásins þíns, þ.m.t. svörtu stikuna"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Andlit ekki staðfest. Vélbúnaður er ekki tiltækur."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Prófaðu andlitsopnun aftur."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Ekki er hægt að vista ný andlitsgögn. Eyddu gömlu fyrst."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Hætt við andlitsgreiningu."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Notandi hætti við andlitsopnun."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Of margar tilraunir. Reyndu aftur síðar."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Of margar tilraunir. Slökkt á andlitsopnun."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Ekki tókst að staðfesta andlit. Reyndu aftur."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Þú hefur ekki sett upp andlitsopnun."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Andlitsopnun er ekki studd í þessu tæki."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Andlit <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Opna með"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Opna með %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Opna"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Veita aðgang til að opna <xliff:g id="HOST">%1$s</xliff:g> tengla með"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Veita aðgang til að opna <xliff:g id="HOST">%1$s</xliff:g> tengla með <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Opna <xliff:g id="HOST">%1$s</xliff:g> tengla með"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Opna tengla með"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Opna tengla með <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Opna <xliff:g id="HOST">%1$s</xliff:g> tengla með <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Veita aðgang"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Breyta með"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Breyta með %1$s"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Núllstilltu til að slökkva á stillingu prófunarvangs."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Óhætt að nota USB-tengi"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Síminn greinir ekki lengur vökva eða óhreinindi"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Tekur við villutilkynningu…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Deila villutilkynningu?"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Opna vafra?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Samþykkja símtal?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Alltaf"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Stilla á „Alltaf opið“"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Bara einu sinni"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Stillingar"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s styður ekki vinnusnið"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Yfirlögn #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", öruggur"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Framvegis verður lokað á þessa bakgrunnsvirkni frá <xliff:g id="PACKAGENAME">%1$s</xliff:g> í Q-smíði. Sjá g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Lokað á bakgrunnsvirkni frá <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Sjá g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Man ekki mynstrið"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Rangt mynstur"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Rangt aðgangsorð"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Flýtileið aðgengisstillingar kveikti á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Flýtileið aðgengisstillingar slökkti á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Haltu báðum hljóðstyrkstökkunum inni í þrjár sekúndur til að nota <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Veldu eiginleika sem á að nota þegar ýtt er á aðgengishnappinn:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Haltu fingri á aðgengishnappinum til að breyta eiginleikum."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Veldu þjónustu sem á að nota þegar ýtt er á aðgengishnappinn:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Veldu þjónustu sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með tveimur fingrum):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Veldu þjónustu sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með þremur fingrum):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Til að skipta á milli þjónusta skaltu halda aðgengishnappinum inni."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Til að skipta á milli þjónusta skaltu strjúka upp með tveimur fingrum og halda inni."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Til að skipta á milli þjónusta skaltu strjúka upp með þremur fingrum og halda inni."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Stækkun"</string>
     <string name="user_switched" msgid="3768006783166984410">"Núverandi notandi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 96d44c6..6c579b8 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chiamate Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chiamate Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chiamata WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chiamata WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Modalità automobile"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Stato dell\'account"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Messaggi dello sviluppatore"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Messaggi importanti relativi agli sviluppatori"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Aggiornamenti"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stato della rete"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Avvisi di rete"</string>
@@ -323,7 +325,7 @@
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Consente di toccare, far scorrere, pizzicare ed eseguire altri gesti."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Gesti con sensore di impronte digitali"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"È in grado di rilevare i gesti compiuti con il sensore di impronte digitali dei dispositivi."</string>
-    <string name="permlab_statusBar" msgid="7417192629601890791">"disattivare o modificare la barra di stato"</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"disattivazione o modifica della barra di stato"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Consente all\'applicazione di disattivare la barra di stato o di aggiungere e rimuovere icone di sistema."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"ruolo di barra di stato"</string>
     <string name="permdesc_statusBarService" msgid="716113660795976060">"Consente di visualizzare l\'applicazione nella barra di stato."</string>
@@ -335,7 +337,7 @@
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Consente all\'applicazione di rimuovere le scorciatoie della schermata Home automaticamente."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"reindirizzamento chiamate in uscita"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Consente all\'app di rilevare il numero digitato durante una chiamata in uscita, con la possibilità di reindirizzare la telefonata a un numero diverso o interromperla del tutto."</string>
-    <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"rispondi a telefonate in arrivo"</string>
+    <string name="permlab_answerPhoneCalls" msgid="4077162841226223337">"risposta a telefonate in arrivo"</string>
     <string name="permdesc_answerPhoneCalls" msgid="2901889867993572266">"Consente all\'app di rispondere a una telefonata in arrivo."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"ricezione messaggi di testo (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Consente all\'applicazione di ricevere ed elaborare messaggi SMS. Significa che l\'applicazione potrebbe monitorare o eliminare i messaggi inviati al tuo dispositivo senza mostrarteli."</string>
@@ -345,7 +347,7 @@
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Consente all\'applicazione di leggere i messaggi cell broadcast ricevuti dal dispositivo. Gli avvisi cell broadcast vengono trasmessi in alcune località per avvertire di eventuali situazioni di emergenza. Le applicazioni dannose potrebbero interferire con il rendimento o con il funzionamento del dispositivo quando si riceve un messaggio cell broadcast di emergenza."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"lettura feed sottoscritti"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Consente all\'applicazione di ottenere dettagli sui feed attualmente sincronizzati."</string>
-    <string name="permlab_sendSms" msgid="7544599214260982981">"inviare e visualizzare SMS"</string>
+    <string name="permlab_sendSms" msgid="7544599214260982981">"invio e visualizzazione di SMS"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"Consente all\'applicazione di inviare messaggi SMS. Ciò potrebbe comportare costi imprevisti. Applicazioni dannose potrebbero generare dei costi inviando messaggi senza la tua conferma."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"lettura messaggi di testo personali (SMS o MMS)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="4741697454888074891">"Questa app può leggere tutti i messaggi di testo (SMS) memorizzati sul tablet."</string>
@@ -373,7 +375,7 @@
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Consente all\'applicazione di rendere persistenti in memoria alcune sue parti. Ciò può limitare la memoria disponibile per altre applicazioni, rallentando il tablet."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Consente all\'app di rendere alcune sue parti persistenti nella memoria. Potrebbe così essere limitata la memoria a disposizione di altre app ed essere rallentata la TV."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Consente all\'applicazione di rendere persistenti in memoria alcune sue parti. Ciò può limitare la memoria disponibile per altre applicazioni, rallentando il telefono."</string>
-    <string name="permlab_foregroundService" msgid="3310786367649133115">"esegui servizio in primo piano"</string>
+    <string name="permlab_foregroundService" msgid="3310786367649133115">"esecuzione servizio in primo piano"</string>
     <string name="permdesc_foregroundService" msgid="6471634326171344622">"Consente all\'app di utilizzare i servizi in primo piano."</string>
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"calcolo spazio di archiviazione applicazioni"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Consente all\'applicazione di recuperare il suo codice, i suoi dati e le dimensioni della cache"</string>
@@ -403,7 +405,7 @@
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Consente all\'applicazione di modificare il registro chiamate del telefono, inclusi i dati sulle chiamate in arrivo e in uscita. Le applicazioni dannose potrebbero farne uso per cancellare o modificare il registro chiamate."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"accesso ai sensori (come il cardiofrequenzimetro)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Consente all\'app di accedere ai dati relativi ai sensori che monitorano le tue condizioni fisiche, ad esempio la frequenza cardiaca."</string>
-    <string name="permlab_readCalendar" msgid="6716116972752441641">"Leggi eventi di calendario e dettagli"</string>
+    <string name="permlab_readCalendar" msgid="6716116972752441641">"lettura di eventi di calendario e dettagli"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"Questa app può leggere tutti gli eventi di calendario memorizzati sul tablet e condividere o salvare i dati di calendario."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="8837931557573064315">"Questa app può leggere tutti gli eventi di calendario memorizzati sulla TV e condividere o salvare i dati di calendario."</string>
     <string name="permdesc_readCalendar" product="default" msgid="4373978642145196715">"Questa app può leggere tutti gli eventi di calendario memorizzati sul telefono e condividere o salvare i dati di calendario."</string>
@@ -413,9 +415,9 @@
     <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"Questa app può aggiungere, rimuovere o modificare eventi di calendario sul telefono. Può inviare messaggi che possono sembrare inviati dai proprietari del calendario o modificare eventi senza notificare i proprietari."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesso a comandi aggiuntivi provider di geolocalizz."</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Consente all\'app di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'app di interferire con il funzionamento del GPS o di altre fonti di geolocalizzazione."</string>
-    <string name="permlab_accessFineLocation" msgid="6265109654698562427">"Accesso alla posizione esatta solo in primo piano"</string>
+    <string name="permlab_accessFineLocation" msgid="6265109654698562427">"accesso alla posizione esatta solo in primo piano"</string>
     <string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Questa app può recuperare la tua posizione esatta solo quando è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul telefono affinché l\'app possa usarli. Potrebbe aumentare il consumo della batteria."</string>
-    <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"Accesso alla posizione approssimativa (in base alla rete) solo in primo piano"</string>
+    <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"accesso alla posizione approssimativa (in base alla rete) solo in primo piano"</string>
     <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul tablet affinché l\'app possa usarli."</string>
     <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sulla TV affinché l\'app possa usarli."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul telefono affinché l\'app possa usarli."</string>
@@ -423,7 +425,7 @@
     <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Se concedi l\'autorizzazione insieme all\'accesso alla posizione precisa o approssimativa, l\'app potrà accedere alla posizione mentre viene eseguita in background."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifica impostazioni audio"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Consente all\'applicazione di modificare le impostazioni audio globali, come il volume e quale altoparlante viene utilizzato per l\'uscita."</string>
-    <string name="permlab_recordAudio" msgid="3876049771427466323">"registrare audio"</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"registrazione audio"</string>
     <string name="permdesc_recordAudio" msgid="4245930455135321433">"Questa app può registrare audio tramite il microfono in qualsiasi momento."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"invio di comandi alla SIM"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Consente all\'app di inviare comandi alla SIM. Questo è molto pericoloso."</string>
@@ -435,7 +437,7 @@
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Consente all\'applicazione di controllare la vibrazione."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"chiamata diretta n. telefono"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Consente all\'applicazione di chiamare numeri di telefono senza il tuo intervento. Ciò può comportare chiamate o addebiti imprevisti. Tieni presente che ciò non consente all\'applicazione di chiamare numeri di emergenza. Applicazioni dannose potrebbero generare dei costi effettuando chiamate senza la tua conferma."</string>
-    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"Accesso al servizio di chiamata IMS"</string>
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"accesso al servizio di chiamata IMS"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Consente all\'app di utilizzare il servizio IMS per fare chiamate senza il tuo intervento."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lettura stato e identità telefono"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Consente all\'applicazione di accedere alle funzioni telefoniche del dispositivo. Questa autorizzazione consente all\'applicazione di determinare il numero di telefono e gli ID dei dispositivi, se una chiamata è attiva e il numero remoto connesso da una chiamata."</string>
@@ -443,12 +445,12 @@
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"Consente all\'app di indirizzare le proprie chiamate tramite il sistema al fine di migliorare l\'esperienza di chiamata."</string>
     <string name="permlab_callCompanionApp" msgid="3599252979411970473">"visualizzazione e controllo delle chiamate tramite il sistema."</string>
     <string name="permdesc_callCompanionApp" msgid="4567344683275099090">"Consente all\'app di visualizzare e controllare le chiamate in corso sul dispositivo. Sono incluse informazioni quali i numeri e lo stato relativi alle chiamate."</string>
-    <string name="permlab_acceptHandover" msgid="2661534649736022409">"Continuazione di una chiamata da un\'altra app"</string>
+    <string name="permlab_acceptHandover" msgid="2661534649736022409">"continuazione di una chiamata da un\'altra app"</string>
     <string name="permdesc_acceptHandovers" msgid="4570660484220539698">"Consente all\'app di continuare una chiamata che è stata iniziata in un\'altra app."</string>
     <string name="permlab_readPhoneNumbers" msgid="6108163940932852440">"lettura dei numeri di telefono"</string>
     <string name="permdesc_readPhoneNumbers" msgid="8559488833662272354">"Consente all\'app di accedere ai numeri di telefono del dispositivo."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"disattivazione stand-by del tablet"</string>
-    <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"divieto di attivazione della modalità di sospensione della TV"</string>
+    <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"disattivazione della modalità di sospensione della TV"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"disattivazione stand-by del telefono"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Consente all\'applicazione di impedire lo stand-by del tablet."</string>
     <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"Consente all\'app di impedire l\'attivazione della modalità di sospensione della TV."</string>
@@ -481,7 +483,7 @@
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Consente all\'applicazione di visualizzare informazioni sulle reti Wi-Fi, ad esempio di rilevare se il Wi-Fi è abilitato e il nome dei dispositivi Wi-Fi connessi."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"connessione e disconnessione dal Wi-Fi"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Consente all\'applicazione di connettersi/disconnettersi da punti di accesso Wi-Fi e di apportare modifiche alla configurazione del dispositivo per le reti Wi-Fi."</string>
-    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"consenti ricezione multicast Wi-Fi"</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ricezione multicast Wi-Fi"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Consente all\'applicazione di ricevere pacchetti inviati a tutti i dispositivi su una rete Wi-Fi utilizzando indirizzi multicast, non solo il tuo tablet. Viene consumata più batteria rispetto alla modalità non multicast."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Consente all\'app di ricevere pacchetti inviati a tutti i dispositivi tramite una rete Wi-Fi utilizzando indirizzi multicast, non soltanto la TV. Questa modalità consuma più energia della modalità non multicast."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Consente all\'applicazione di ricevere pacchetti inviati a tutti i dispositivi su una rete Wi-Fi utilizzando indirizzi multicast, non solo il tuo telefono. Viene consumata più batteria rispetto alla modalità non multicast."</string>
@@ -503,21 +505,21 @@
     <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_requestPasswordComplexity" msgid="202650535669249674">"richiedi complessità del blocco schermo"</string>
+    <string name="permlab_requestPasswordComplexity" msgid="202650535669249674">"richiesta di complessità del blocco schermo"</string>
     <string name="permdesc_requestPasswordComplexity" msgid="4730994229754212347">"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>
-    <string name="permlab_useBiometric" msgid="8837753668509919318">"Utilizzo di hardware biometrico"</string>
+    <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>
+    <string name="permlab_manageFingerprint" msgid="5640858826254575638">"gestione di hardware per il riconoscimento delle impronte digitali"</string>
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Consente all\'app di richiamare metodi per aggiungere e rimuovere modelli di impronte digitali da utilizzare."</string>
     <string name="permlab_useFingerprint" msgid="3150478619915124905">"utilizzo di hardware per il riconoscimento delle impronte digitali"</string>
     <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Consente all\'app di utilizzare l\'hardware per il riconoscimento delle impronte digitali per eseguire l\'autenticazione"</string>
-    <string name="permlab_audioWrite" msgid="2661772059799779292">"Modifica della tua raccolta musicale"</string>
+    <string name="permlab_audioWrite" msgid="2661772059799779292">"modifica della tua raccolta musicale"</string>
     <string name="permdesc_audioWrite" msgid="8888544708166230494">"Consente all\'app di modificare la tua raccolta musicale."</string>
-    <string name="permlab_videoWrite" msgid="128769316366746446">"Modifica della tua raccolta di video"</string>
+    <string name="permlab_videoWrite" msgid="128769316366746446">"modifica della tua raccolta di video"</string>
     <string name="permdesc_videoWrite" msgid="5448565757490640841">"Consente all\'app di modificare la tua raccolta di video."</string>
-    <string name="permlab_imagesWrite" msgid="3391306186247235510">"Modifica della tua raccolta di foto"</string>
+    <string name="permlab_imagesWrite" msgid="3391306186247235510">"modifica della tua raccolta di foto"</string>
     <string name="permdesc_imagesWrite" msgid="7073662756617474375">"Consente all\'app di modificare la tua raccolta di foto."</string>
-    <string name="permlab_mediaLocation" msgid="8675148183726247864">"Lettura delle posizioni dalla tua raccolta multimediale"</string>
+    <string name="permlab_mediaLocation" msgid="8675148183726247864">"lettura delle posizioni dalla tua raccolta multimediale"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"Consente all\'app di leggere le posizioni dalla tua raccolta multimediale."</string>
     <string name="biometric_dialog_default_title" msgid="881952973720613213">"Verifica la tua identità"</string>
     <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"Hardware biometrico non disponibile"</string>
@@ -549,9 +551,9 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icona dell\'impronta digitale"</string>
-    <string name="permlab_manageFace" msgid="7262837876352591553">"gestisci l\'hardware per Sblocco col sorriso"</string>
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gestione dell\'hardware per Sblocco col sorriso"</string>
     <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="2565716575739037572">"utilizza l\'hardware per Sblocco col sorriso"</string>
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utilizzo dell\'hardware per Sblocco col sorriso"</string>
     <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Consente all\'app di utilizzare hardware per l\'autenticazione con Sblocco col sorriso"</string>
     <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Sblocco col sorriso"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Registra di nuovo il volto"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Sposta il telefono verso sinistra."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Sposta il telefono verso destra."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Guarda più direttamente verso il dispositivo."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Impossibile vedere il volto. Guarda il telefono."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Posiziona il viso davanti al telefono."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Troppo movimento. Tieni fermo il telefono."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Ripeti l\'acquisizione del volto."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Non è più possibile riconoscere il volto. Riprova."</string>
@@ -575,18 +577,18 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Gira un po\' meno la testa."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Gira un po\' meno la testa."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Rimuovi tutto ciò che ti nasconde il viso."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Pulisci sensore sul bordo superiore dello schermo."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Pulisci la parte superiore dello schermo, inclusa la barra nera"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Imposs. verificare volto. Hardware non disponibile."</string>
-    <string name="face_error_timeout" msgid="981512090365729465">"Riprova lo Sblocco col sorriso."</string>
+    <string name="face_error_timeout" msgid="981512090365729465">"Riprova Sblocco col sorriso."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Imposs. salvare dati nuovi volti. Elimina un volto vecchio."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operazione associata al volto annullata."</string>
     <string name="face_error_user_canceled" msgid="5317030072349668946">"Sblocco col sorriso annullato dall\'utente."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Troppi tentativi. Riprova più tardi."</string>
     <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Troppi tentativi. Sblocco col sorriso disattivato"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Impossibile verificare il volto. Riprova."</string>
-    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Non hai configurato lo Sblocco col sorriso."</string>
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Non hai configurato Sblocco col sorriso."</string>
     <string name="face_error_hw_not_present" msgid="8302690289757559738">"Sblocco col sorriso non supportato su questo dispositivo."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Volto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
@@ -598,21 +600,21 @@
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Consente a un\'applicazione di modificare le impostazioni di sincronizzazione per un account. Ad esempio, può servire per attivare la sincronizzazione dell\'applicazione Persone con un account."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"lettura statistiche di sincronizz."</string>
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Consente a un\'applicazione di leggere le statistiche di sincronizzazione per un account, incluse la cronologia degli eventi di sincronizzazione e la quantità di dati sincronizzati."</string>
-    <string name="permlab_sdcardRead" msgid="1438933556581438863">"leggere i contenuti dell\'archivio condiviso"</string>
+    <string name="permlab_sdcardRead" msgid="1438933556581438863">"lettura dei contenuti dell\'archivio condiviso"</string>
     <string name="permdesc_sdcardRead" msgid="1804941689051236391">"Consente all\'app di leggere i contenuti del tuo archivio condiviso."</string>
-    <string name="permlab_sdcardWrite" msgid="9220937740184960897">"modificare/eliminare i contenuti dell\'archivio condiviso"</string>
+    <string name="permlab_sdcardWrite" msgid="9220937740184960897">"modifica/eliminazione dei contenuti dell\'archivio condiviso"</string>
     <string name="permdesc_sdcardWrite" msgid="2834431057338203959">"Consente all\'app di modificare i contenuti del tuo archivio condiviso."</string>
-    <string name="permlab_use_sip" msgid="2052499390128979920">"fare/ricevere chiamate SIP"</string>
+    <string name="permlab_use_sip" msgid="2052499390128979920">"invio/ricezione di chiamate SIP"</string>
     <string name="permdesc_use_sip" msgid="2297804849860225257">"Consente all\'app di effettuare e ricevere chiamate SIP."</string>
     <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"registrazione di nuove connessioni SIM di telecomunicazione"</string>
     <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"Consente all\'app di registrare nuove connessioni SIM di telecomunicazione."</string>
     <string name="permlab_register_call_provider" msgid="108102120289029841">"registrazione di nuove connessioni di telecomunicazione"</string>
     <string name="permdesc_register_call_provider" msgid="7034310263521081388">"Consente all\'app di registrare nuove connessioni di telecomunicazione."</string>
-    <string name="permlab_connection_manager" msgid="1116193254522105375">"gestisci connessioni di telecomunicazione"</string>
+    <string name="permlab_connection_manager" msgid="1116193254522105375">"gestione di connessioni di telecomunicazione"</string>
     <string name="permdesc_connection_manager" msgid="5925480810356483565">"Consente all\'app di gestire connessioni di telecomunicazione."</string>
     <string name="permlab_bind_incall_service" msgid="6773648341975287125">"interazione con lo schermo durante una chiamata"</string>
     <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Consente all\'app di stabilire quando e come l\'utente vede lo schermo durante una chiamata."</string>
-    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"interagire con i servizi di telefonia"</string>
+    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"interazione con i servizi di telefonia"</string>
     <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Consente all\'app di interagire con i servizi di telefonia per effettuare/ricevere chiamate."</string>
     <string name="permlab_control_incall_experience" msgid="9061024437607777619">"offerta di un\'esperienza utente durante le chiamate"</string>
     <string name="permdesc_control_incall_experience" msgid="915159066039828124">"Consente all\'app di offrire un\'esperienza utente durante le chiamate."</string>
@@ -628,7 +630,7 @@
     <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Consente al titolare di vincolarsi all\'interfaccia di primo livello di un servizio listener di notifica. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
     <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"collegamento a un servizio provider di condizioni"</string>
     <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio provider di condizioni. Non dovrebbe essere mai necessaria per le normali app."</string>
-    <string name="permlab_bindDreamService" msgid="4153646965978563462">"associa a servizio dream"</string>
+    <string name="permlab_bindDreamService" msgid="4153646965978563462">"associazione a servizio dream"</string>
     <string name="permdesc_bindDreamService" msgid="7325825272223347863">"Consente all\'utente di associare l\'interfaccia di primo livello di un servizio dream. Questa impostazione non è mai necessaria per le app normali."</string>
     <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"richiamo dell\'app di configurazione operatore-provider"</string>
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Consente al titolare di richiamare l\'app di configurazione dell\'operatore-provider. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
@@ -644,7 +646,7 @@
     <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Consente a un\'applicazione di rimuovere certificati DRM. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
     <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"associazione a un servizio di messaggi dell\'operatore"</string>
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Consente l\'associazione di un servizio di messaggi dell\'operatore all\'interfaccia principale. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
-    <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"Collegamento a servizi dell\'operatore"</string>
+    <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"associazione a servizi dell\'operatore"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Consente al titolare di collegarsi a servizi dell\'operatore. Non dovrebbe mai essere necessaria per le normali app."</string>
     <string name="permlab_access_notification_policy" msgid="4247510821662059671">"accesso alla funzione Non disturbare"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Consente all\'app di leggere e modificare la configurazione della funzione Non disturbare."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Apri con"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Apri con %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Apri"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Dai l\'accesso per aprire i link di <xliff:g id="HOST">%1$s</xliff:g> con"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Dai l\'accesso per aprire i link di <xliff:g id="HOST">%1$s</xliff:g> con <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Apri i link <xliff:g id="HOST">%1$s</xliff:g> con"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Apri i link con"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Apri i link con <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Apri i link <xliff:g id="HOST">%1$s</xliff:g> con <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Fornisci accesso"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Modifica con"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Modifica con %1$s"</string>
@@ -1426,7 +1430,7 @@
     <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Consente a un\'applicazione di richiedere l\'installazione di pacchetti."</string>
     <string name="permlab_requestDeletePackages" msgid="1703686454657781242">"richiesta di eliminazione dei pacchetti"</string>
     <string name="permdesc_requestDeletePackages" msgid="3406172963097595270">"Consente a un\'applicazione di richiedere l\'eliminazione di pacchetti."</string>
-    <string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"chiedi di ignorare le ottimizzazioni della batteria"</string>
+    <string name="permlab_requestIgnoreBatteryOptimizations" msgid="8021256345643918264">"richiesta di ignorare le ottimizzazioni della batteria"</string>
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="8359147856007447638">"Consente a un\'app di chiedere l\'autorizzazione a ignorare le ottimizzazioni della batteria per quell\'app."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1311810005957319690">"Tocca due volte per il comando dello zoom"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Aggiunta del widget non riuscita."</string>
@@ -1492,8 +1496,8 @@
     <string name="websearch" msgid="4337157977400211589">"Ricerca Web"</string>
     <string name="find_next" msgid="5742124618942193978">"Trova successivo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Trova precedente"</string>
-    <string name="gpsNotifTicker" msgid="5622683912616496172">"Richiesta posizione da <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Richiesta posizione"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"Richiesta di posizione da <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Richiesta di posizione"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Richiesto da <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Sì"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Avviare l\'applicazione Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Accettare la chiamata?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Imposta per aprire sempre"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Solo una volta"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Impostazioni"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s non supporta il profilo di lavoro"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay n. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", opzione sicura"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"L\'avvio di questa attività in background da <xliff:g id="PACKAGENAME">%1$s</xliff:g> verrà bloccato nelle future build Q. Visita la pagina g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Avvio delle attività in background da <xliff:g id="PACKAGENAME">%1$s</xliff:g> bloccato. Visita la pagina g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Sequenza dimenticata"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Sequenza sbagliata"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Password sbagliata"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"La scorciatoia Accessibilità ha attivato <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"La scorciatoia Accessibilità ha disattivato <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Tieni premuti entrambi i tasti del volume per tre secondi per utilizzare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Scegli una funzione da usare quando tocchi il pulsante Accessibilità:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Per cambiare le funzioni, tocca e tieni premuto il pulsante Accessibilità."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Scegli un servizio da usare quando tocchi il pulsante Accessibilità:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Scegli un servizio da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con due dita):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Scegli un servizio da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con tre dita):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Per spostarti tra i servizi, tocca e tieni premuto il pulsante Accessibilità."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Per spostarti tra i servizi, scorri verso l\'alto con due dita e tieni premuto."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Per spostarti tra i servizi, scorri verso l\'alto con tre dita e tieni premuto."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ingrandimento"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1900,7 +1907,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Verifica la presenza di aggiornamenti"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Hai nuovi messaggi"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Apri l\'app SMS per la visualizzazione"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Funzionalità potenzialmente limitate"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Alcune funzionalità sono limitate"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profilo di lavoro bloccato"</string>
     <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>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 78085c7..437b31b 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏שיחות Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‏שיחות Wi-Fi באמצעות <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"שיחה ברשת אלחוטית"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏שיחת WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"מצב נהיגה"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"סטטוס החשבון"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"הודעות למפתחים"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"הודעות חשובות למפתחים"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"עדכונים"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"סטטוס הרשת"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"התראות רשת"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"סמל טביעת אצבע"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"ניהול החומרה לשחרור נעילה על ידי זיהוי פנים"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"מאפשרת לאפליקציה להפעיל שיטות להוספה ומחיקה של תבניות פנים שבהן ייעשה שימוש."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"שימוש בחומרה לשחרור נעילה על ידי זיהוי פנים"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"מאפשרת לאפליקציה להשתמש בחומרה לשחרור נעילה על ידי זיהוי פנים לצורך אימות"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"שחרור נעילה על ידי זיהוי פנים"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"יש לבצע רישום מחדש של הפנים שלך"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"לשיפור הזיהוי יש לבצע רישום מחדש של הפנים שלך"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"לא ניתן היה לקלוט את הפנים במדויק. יש לנסות שוב."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"צריך להזיז את הטלפון שמאלה."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"צריך להזיז את הטלפון ימינה."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"יש להביט ישירות אל המכשיר."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"אי אפשר לראות את הפנים שלך. צריך להביט אל הטלפון."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"עליך למקם את הפנים ישירות מול הטלפון."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"יותר מדי תנועה. יש להחזיק את הטלפון בצורה יציבה."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"יש לרשום מחדש את הפנים."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"כבר לא ניתן לזהות פנים. יש לנסות שוב."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"עליך ליישר קצת את הראש."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"עליך ליישר קצת את הראש."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"יש להסיר כל דבר שמסתיר את הפנים."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"יש לנקות את החיישן שבקצה העליון של המסך."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"עליך לנקות את החלק העליון של המסך, כולל הסרגל השחור"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"לא ניתן לאמת את הפנים. החומרה לא זמינה."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"יש לנסות שוב את שחרור הנעילה על ידי זיהוי פנים."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"לא ניתן לאחסן נתוני פנים. תחילה יש למחוק פנים ישנים."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"פעולת הפנים בוטלה."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"שחרור הנעילה על ידי זיהוי פנים בוטל על ידי המשתמש."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"יותר מדי ניסיונות. יש לנסות שוב מאוחר יותר."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"יותר מדי ניסיונות. שחרור נעילה על ידי זיהוי פנים מושבת."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"לא ניתן לאמת את הפנים. יש לנסות שוב."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"לא הגדרת שחרור נעילה על ידי זיהוי פנים."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"המכשיר הזה לא תומך בשחרור נעילה על ידי זיהוי פנים."</string>
     <string name="face_name_template" msgid="7004562145809595384">"פנים <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"פתח באמצעות"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"‏פתח באמצעות %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"פתח"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"הענקת גישה לפתיחת קישורים של <xliff:g id="HOST">%1$s</xliff:g> באמצעות"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"הענקת גישה לפתיחת קישורים של <xliff:g id="HOST">%1$s</xliff:g> באמצעות <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"פתיחת קישורים של <xliff:g id="HOST">%1$s</xliff:g> באמצעות"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"פתיחת קישורים באמצעות"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"פתיחת קישורים באמצעות <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"פתיחת קישורים של <xliff:g id="HOST">%1$s</xliff:g> באמצעות <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"הענקת גישה"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ערוך באמצעות"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"‏ערוך באמצעות %1$s"</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"כדי להשבית את מצב מסגרת בדיקה צריך לאפס להגדרות היצרן."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏יש נוזלים או חלקיקים ביציאת ה-USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏יציאת ה-USB הושבתה באופן אוטומטי. יש להקיש לקבלת מידע נוסף."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"‏ניתן להשתמש ביציאת ה-USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"הטלפון לא מזהה יותר נוזלים וחלקיקים."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"עיבוד דוח על באג..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"האם לשתף דוח על באג?"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"להפעיל את הדפדפן?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"האם לקבל את השיחה?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"תמיד"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"הגדרה כברירת מחדל לפתיחה"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"רק פעם אחת"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"הגדרות"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"‏%1$s אינו תומך בפרופיל עבודה"</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"שכבת-על #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"‏<xliff:g id="NAME">%1$s</xliff:g>: ‎<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>‎, ‏<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", מאובטח"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‏התחלה זו של פעילות ברקע מ-<xliff:g id="PACKAGENAME">%1$s</xliff:g> תיחסם בגרסאות build עתידיות של Q. ניתן לעיין בכתובת g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‏נחסמה התחלה של פעילות ברקע מ-<xliff:g id="PACKAGENAME">%1$s</xliff:g>. ניתן לעיין בכתובת g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"שכחת את קו ביטול הנעילה?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"קו ביטול נעילה שגוי"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"סיסמה שגויה"</string>
@@ -1724,8 +1717,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל על-ידי קיצור הדרך לנגישות"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת על-ידי קיצור הדרך לנגישות"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"יש ללחוץ לחיצה ארוכה על שני לחצני עוצמת הקול למשך שלוש שניות כדי להשתמש בשירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"בחר תכונה שתופעל כשתלחץ על הלחצן \'נגישות\':"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"כדי להחליף תכונה, יש ללחוץ לחיצה ארוכה על הלחצן \'נגישות\'."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"יש לבחור שירות שיופעל באמצעות הקשה על לחצן הנגישות:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"יש לבחור שירות שיופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שתי אצבעות):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"יש לבחור שירות שיופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שלוש אצבעות):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"כדי לעבור בין שירותים, יש ללחוץ לחיצה ארוכה על לחצן הנגישות."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"כדי לעבור בין שירותים, יש להחליק כלפי מעלה בעזרת שתי אצבעות ולהחזיק."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"כדי לעבור בין שירותים, יש להחליק כלפי מעלה בעזרת שלוש אצבעות ולהחזיק."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"הגדלה"</string>
     <string name="user_switched" msgid="3768006783166984410">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"עובר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index e71bc0a..b558a31 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"運転モード"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"アカウントのステータス"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"デベロッパー メッセージ"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"デベロッパーからの重要なメッセージ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"アップデート"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ネットワークのステータス"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ネットワーク通知"</string>
@@ -265,14 +267,14 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"通知"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"販売店デモ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB 接続"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"アプリを実行しています"</string>
-    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"アプリが電池を消費しています"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"実行中のアプリ"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"電池を消費しているアプリ"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」が電池を使用しています"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリが電池を使用しています"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"タップして電池やデータの使用量を確認"</string>
     <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
     <string name="safeMode" msgid="2788228061547930246">"セーフモード"</string>
-    <string name="android_system_label" msgid="6577375335728551336">"Androidシステム"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android システム"</string>
     <string name="user_owner_label" msgid="8836124313744349203">"個人用プロファイルに切り替える"</string>
     <string name="managed_profile_label" msgid="8947929265267690522">"仕事用プロファイルに切り替える"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"連絡先"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指紋アイコン"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"フェイスアンロック ハードウェアの管理"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"使用する顔テンプレートの追加や削除を行うメソッドの呼び出しをアプリに許可します。"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"フェイスアンロック ハードウェアの使用"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"フェイスアンロック ハードウェアを認証に使用することをアプリに許可します"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"フェイスアンロック"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"顔の再登録"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"認識を改善するには、顔を再登録してください"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"顔を認識できませんでした。もう一度お試しください。"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"スマートフォンを左に動かしてください。"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"スマートフォンを右に動かしてください。"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"もっとまっすぐデバイスに顔を向けてください。"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"顔を確認できません。スマートフォンを見てください。"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"顔をスマートフォンの真正面に向けてください。"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"あまり動かさないでください。安定させてください。"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"顔を登録し直してください。"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"顔を認識できなくなりました。もう一度お試しください。"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"顔の向きを少し戻してください。"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"顔の向きを少し戻してください。"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"顔を隠しているものをすべて外してください"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"画面の上端にあるセンサーの汚れを落としてください。"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"黒いバーを含め、画面の上部をきれいにしてください"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"顔を確認できません。ハードウェアを利用できません。"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"フェイスアンロックをもう一度お試しください。"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"新しい顔データを保存できません。古いデータを削除してください。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"顔の操作をキャンセルしました。"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"フェイスアンロックはユーザーによりキャンセルされました。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"試行回数の上限です。後でもう一度お試しください。"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"試行回数が上限を超えました。フェイスアンロックを無効にしました。"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"顔を確認できません。もう一度お試しください。"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"フェイスアンロックを設定していません。"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"このデバイスでは、フェイスアンロックはご利用いただけません。"</string>
     <string name="face_name_template" msgid="7004562145809595384">"顔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"アプリで開く"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$sで開く"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"開く"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"<xliff:g id="HOST">%1$s</xliff:g> のリンクを開くには、アクセス権を付与してください"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> で <xliff:g id="HOST">%1$s</xliff:g> のリンクを開くには、アクセス権を付与してください"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> のリンクを開くブラウザ / アプリの選択"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"リンクを開くブラウザの選択"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> でリンクを開く"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> で <xliff:g id="HOST">%1$s</xliff:g> のリンクを開く"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"アクセス権を付与"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"編集に使用"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$sで編集"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ポート内の液体やゴミ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ポートが自動的に無効になりました。タップして詳細をご確認ください。"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ポートを安全に使用できます"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"液体やゴミは検出されなくなりました。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"バグレポートを取得しています…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"バグレポートを共有しますか?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"次を検索"</string>
     <string name="find_previous" msgid="2196723669388360506">"前を検索"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g>さんからの現在地情報リクエスト"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"現在地情報へのアクセス許可"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"現在地情報リクエスト"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g>さん(<xliff:g id="SERVICE">%2$s</xliff:g>)からのリクエスト"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"はい"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"いいえ"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"通話を受けますか?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"常時"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"[常に開く] に設定"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"1回のみ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"設定"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$sは仕事用プロファイルをサポートしていません"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"オーバーレイ第<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>、<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"、セキュア"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> からのこのバックグラウンド アクティビティの開始は今後の Q ビルドではブロックされます。g.co/dev/bgblock をご覧ください。"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> からのバックグラウンド アクティビティの開始がブロックされました。g.co/dev/bgblock をご覧ください。"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"パターンを忘れた場合"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"パターンが正しくありません"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"パスワードが正しくありません"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ユーザー補助機能のショートカットにより <xliff:g id="SERVICE_NAME">%1$s</xliff:g> は ON になっています"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ユーザー補助機能のショートカットにより <xliff:g id="SERVICE_NAME">%1$s</xliff:g> は OFF になっています"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を使用するには、音量大と音量小の両方のボタンを 3 秒間長押ししてください"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ユーザー補助機能ボタンをタップした場合に使用する機能を選択してください。"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"機能を変更するには、ユーザー補助機能ボタンを長押ししてください。"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ユーザー補助機能ボタンをタップした場合に使用するサービスを選択してください。"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ユーザー補助操作(2 本の指で画面の下から上にスワイプ)で使用するサービスを選択してください。"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ユーザー補助操作(3 本の指で画面の下から上にスワイプ)で使用するサービスを選択してください。"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"サービスを切り替えるには、ユーザー補助機能ボタンを長押しします。"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"サービスを切り替えるには、2 本の指で上にスワイプしたまま長押しします。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"サービスを切り替えるには、3 本の指で上にスワイプしたまま長押しします。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"拡大"</string>
     <string name="user_switched" msgid="3768006783166984410">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>に切り替えています…"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index d9ae8ea..3570d4c 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi დარეკვა"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi დარეკვა"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ზარი"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ზარი"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"მანქანის რეჟიმი"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ანგარიშის სტატუსი"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"დეველოპერებთან დაკავშირებული შეტყობინებები"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"დეველოპერთა მნიშვნელოვანი შეტყობინებები"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"განახლებები"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ქსელის სტატუსი"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ქსელის გაფრთხილებები"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"თითის ანაბეჭდის ხატულა"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"სახით განბლოკვის აპარატურის მართვა"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"საშუალებას აძლევს აპს, დაამატოს და წაშალოს სახეების შაბლონები."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"სახით განბლოკვის აპარატურის გამოყენება"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"საშუალებას აძლევს აპს, ამოცნობისთვის გამოიყენოს სახით განბლოკვის აპარატურა"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"განბლოკვა სახით"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"დაარეგისტრირეთ თქვენი სახე ხელახლა"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"ამოცნობის გასაუმჯობესებლად, გთხოვთ, ხელახლა დაარეგისტრიროთ თქვენი სახე"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"სახის ზუსტი მონაცემები არ აღიბეჭდა. ცადეთ ხელახლა."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"გადაანაცვლეთ ტელეფონი მარცხნივ."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"გადაანაცვლეთ ტელეფონი მარჯვნივ."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"გთხოვთ, უფრო პირდაპირ შეხედოთ თქვენს მოწყობილობას."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"თქვენი სახე არ ჩანს. შეხედეთ ტელეფონს."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"დაიჭირეთ სახე უშუალოდ ტელეფონის წინ."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"მეტისმეტად მოძრაობთ. მყარად დაიჭირეთ ტელეფონი."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"გთხოვთ, ხელახლა დაარეგისტრიროთ თქვენი სახე."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"სახის ამოცნობა ვეღარ ხერხდება. ცადეთ ხელახლა."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"თავი ცოტა ნაკლებად მიაბრუნეთ."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"თავი ცოტა ნაკლებად მიაბრუნეთ."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"მოაშორეთ ყველაფერი, რაც სახეს გიფარავთ."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"გაწმინდეთ სენსორი ეკრანის ზედა კიდეზე."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"გაწმინდეთ ეკრანის ზედა ნაწილი, შავი ზოლის ჩათვლით."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"სახე ვერ დასტურდება. აპარატი მიუწვდომელია."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"ცადეთ ხელახლა სახით განბლოკვა."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"სახის ახალი მონაცემები ვერ ინახება. ჯერ ძველი წაშალეთ."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"სახის ამოცნობა გაუქმდა."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"განბლოკვა სახით გაუქმდა მომხმარებლის მიერ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"დაფიქსირდა ბევრი მცდელობა. ცადეთ მოგვიანებით."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"მეტისმეტად ბევრი მცდელობა იყო. სახით განბლოკვა გათიშულია."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"სახის დადასტურება ვერ ხერხდება. ცადეთ ხელახლა."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"თქვენ არ დაგიყენებიათ სახით განბლოკვა."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"განბლოკვა სახით ამ მოწყობილობაზე მხარდაჭერილი არ არის."</string>
     <string name="face_name_template" msgid="7004562145809595384">"სახე <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"გახსნა აპით"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s-ით გახსნა"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"გახსნა"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"<xliff:g id="HOST">%1$s</xliff:g> ბმულების შემდეგი აპით გახსნის წვდომის მინიჭება:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="HOST">%1$s</xliff:g> ბმულების <xliff:g id="APPLICATION">%2$s</xliff:g>-ით გახსნის წვდომის მინიჭება"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> ბმულების გახსნა შემდეგით:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"ბმულების გახსნა შემდეგით:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"ბმულების გახსნა <xliff:g id="APPLICATION">%1$s</xliff:g>-ით"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> ბმულების <xliff:g id="APPLICATION">%2$s</xliff:g>-ით გახსნა"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"წვდომის მინიჭება"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"რედაქტირება აპით:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"რედაქტირება %1$s-ით"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"დააბრუნეთ ქარხნული პარამეტრები „გარემო ტესტირებისთვის“ რეჟიმის გასათიშად."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB პორტში აღმოჩენილია სითხე ან ჭუჭყი"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB პორტი ავტომატურად გათიშულია. შეეხეთ დამატებითი ინფორმაციისთვის."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"თანხმობა USB პორტის გამოყენებაზე"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ტელეფონი აღარ აღმოაჩენს სითხეს ან ჭუჭყს."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის შექმნა…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"გსურთ ხარვეზის შესახებ ანგარიშის გაზიარება?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"გსურთ ბრაუზერის გაშვება?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"უპასუხებთ ზარს?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ყოველთვის"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ყოველთვის გახსნის დაყენება"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"მხოლოდ ერთხელ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"პარამეტრები"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s მხარს არ უჭერს სამუშაო პროფილს"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"გადაფარვა #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", დაცული"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-დან ამ ფონური აქტივობის გაშვება დაიბლოკება Q-ის მომდევნო ანაწყობებში. იხილეთ g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-დან ფონური აქტივობის გაშვება დაიბლოკა. იხილეთ g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"დაგავიწყდათ ნიმუში"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"არასწორი ნიმუში"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"არასწორი პაროლი"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"მარტივი წვდომის მალსახმობმა ჩართო <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"მარტივი წვდომის მალსახმობმა გამორთო <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> რომ გამოიყენოთ, დააჭირეთ ხმის ორივე ღილაკზე 3 წამის განმავლობაში"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"აირჩიეთ მარტივი წვდომის ღილაკზე შეხებისას გამოსაყენებელი ფუნქცია:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ფუნქციების შესაცვლელად ხანგრძლივად შეეხეთ მარტივი წვდომის ღილაკს."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"აირჩიეთ მარტივი წვდომის ღილაკზე შეხებისას გამოსაყენებელი სერვისი:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"აირჩიეთ მარტივი წვდომის ჟესტთან (ორი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი სერვისი:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"აირჩიეთ მარტივი წვდომის ჟესტთან (სამი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი სერვისი:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"სერვისების გადასართავად, ხანგრძლივად შეეხეთ მარტივი წვდომის ღილაკს."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"სერვისების გადასართავად, ორი თითით გადაფურცლეთ ზემოთ და დააყოვნეთ."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"სერვისების გადასართავად, სამი თითით გადაფურცლეთ ზემოთ და დააყოვნეთ."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"გადიდება"</string>
     <string name="user_switched" msgid="3768006783166984410">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>-ზე გადართვა…"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index cb43ba0..2ed1e5b 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi қоңыраулары"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi қоңырауы"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN қоңырауы"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN қоңырауы"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Көлік режимі"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Есептік жазба күйі"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Әзірлеуші хабарлары"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Әзірлеушілердің маңызды хабарлары"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Жаңартылған нұсқалар"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Желі күйі"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Желі дабылдары"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Саусақ ізі белгішесі"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"Face Unlock жабдығын басқару"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Қолданбаға пайдаланатын бет үлгілерін енгізу және жою әдістерін шақыруға мүмкіндік береді."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"Face Unlock жабдығын пайдалану"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Аутентификациялау үшін қолданбаға Face Unlock жабдығын пайдалануға рұқсат береді."</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face Unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Бетті қайта тіркеу"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Құрылғы жүзіңізді жақсырақ тануы үшін, бетіңізді қайта тіркеңіз."</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Бет деректері дұрыс алынбады. Әрекетті қайталаңыз."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Телефонды солға жылжытыңыз."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Телефонды оңға жылжытыңыз."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Құрылғының камерасына тура қараңыз."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Бетіңіз көрінбейді. Телефонға қараңыз."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Бетіңізді телефонға тура қаратыңыз."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Қозғалыс тым көп. Телефонды қозғалтпаңыз."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Қайта тіркеліңіз."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Енді бет анықтау мүмкін емес. Әрекетті қайталаңыз."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Басыңызды түзурек ұстаңыз."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Басыңызды кішкене бұрыңыз."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Бетіңізді жауып тұрған нәрсені алып тастаңыз."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Экранның жоғарғы жиегіндегі датчикті тазалаңыз."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Экранның жоғарғы жағын, сонымен қатар қара жолақты өшіріңіз."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Бетті тану мүмкін емес. Жабдық қолжетімді емес."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Face Unlock функциясын қайта қолданып көріңіз."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Жаңа бетті сақтау мүмкін емес. Алдымен ескісін жойыңыз."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Бетті танудан бас тартылды."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Пайдаланушы Face Unlock функциясынан бас тартты."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Тым көп әрекет жасалды. Кейінірек қайталаңыз."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Тым көп әрекет жасалды. Face Unlock функциясы өшірілді."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Бетті тану мүмкін емес. Әрекетті қайталаңыз."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Face Unlock реттелмеді."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Бұл құрылғыда Face Unlock функциясы істемейді."</string>
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> беті"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Басқаша ашу"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s қолданбасымен ашу"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Ашу"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"<xliff:g id="HOST">%1$s</xliff:g> сілтемелерін келесі қолданбамен ашу үшін рұқсат беру:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="HOST">%1$s</xliff:g> сілтемелерін <xliff:g id="APPLICATION">%2$s</xliff:g> қолданбасымен ашу үшін рұқсат беру"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> сілтемелерін келесімен ашу:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Сілтемелерді келесімен ашу:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Сілтемелерді <xliff:g id="APPLICATION">%1$s</xliff:g> браузерімен ашу"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> сілтемелерін <xliff:g id="APPLICATION">%2$s</xliff:g> браузерімен ашу"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Рұқсат беру"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Келесімен өңдеу"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s көмегімен өңдеу"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Сынақ бағдарламасы режимін өшіру үшін зауыттық күйіне қайтарыңыз."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портына сұйықтық немесе қоқыс кірді"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порты автоматты түрде өшірілді. Толығырақ ақпарат алу үшін түртіңіз."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портын пайдалана беруге болады"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефон бұдан былай сұйықтықты немесе қоқысты анықтамайды."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Қате туралы есеп алынуда…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Қате туралы есепті бөлісу керек пе?"</string>
@@ -1504,7 +1498,7 @@
     <string name="find_next" msgid="5742124618942193978">"Келесіні табу"</string>
     <string name="find_previous" msgid="2196723669388360506">"Алдыңғыны табу"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Орын туралы өтініші жіберген <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Орын туралы өтініш"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Орын туралы сұрау"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Өтініш жіберген <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Иә"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Жоқ"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Браузер қосылсын ба?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Қоңырауды қабылдау?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Үнемі"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Әрдайым ашық күйге орнату"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Бір рет қана"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Параметрлер"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s жұмыс профилін қолдамайды"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"№<xliff:g id="ID">%1$d</xliff:g> қабаттама"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", қауіпсіз"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Алдағы Q құрамаларында <xliff:g id="PACKAGENAME">%1$s</xliff:g> сайтындағы фондық әрекеттерге тыйым салынады. g.co/dev/bgblock бетін қараңыз."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> сайтындағы фондық әрекеттерге тыйым салынған. g.co/dev/bgblock бетін қараңыз."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Кескінді ұмытып қалу"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Қате өрнек"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Қате кілтсөз"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Арнайы мүмкіндіктер таңбашасы <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін қосты"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Арнайы мүмкіндіктер таңбашасы <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін өшірді"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін пайдалану үшін дыбыс деңгейін реттейтін екі түймені де 3 секунд басып тұрыңыз"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын мүмкіндікті таңдаңыз:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Мүмкіндіктерді өзгерту үшін \"Арнайы мүмкіндіктер\" түймесін басып тұрыңыз."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын қызметті таңдаңыз:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Арнайы мүмкіндіктер қимылымен пайдаланатын қызметті таңдаңыз (екі саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Арнайы мүмкіндіктер қимылымен пайдаланатын қызметті таңдаңыз (үш саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Бір қызметтен екінші қызметке ауысу үшін арнайы мүмкіндіктер түймесін түртіп, оны ұстап тұрыңыз."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Бір қызметтен екінші қызметке ауысу үшін екі саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Бір қызметтен екінші қызметке ауысу үшін үш саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ұлғайту"</string>
     <string name="user_switched" msgid="3768006783166984410">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ауысу орындалуда…"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index f1a573e..02c6ba8 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ការហៅតាម Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ការហៅ​តាម Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"ការហៅ​តាម WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> ការហៅតាម WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"មុខងារ​រថយន្ត"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ស្ថានភាព​គណនី"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"សារពី​អ្នក​អភិវឌ្ឍន៍"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"សារ​សំខាន់ៗ​ពាក់ព័ន្ធនឹង​អ្នក​អភិវឌ្ឍន៍"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"បច្ចុប្បន្នភាព"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ស្ថានភាព​បណ្តាញ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ការ​ជូនដំណឹង​អំពី​បណ្តាញ"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"រូបតំណាងស្នាមម្រាមដៃ"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"គ្រប់គ្រង​ហាតវែរ​ដោះសោតាមទម្រង់មុខ"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"អនុញ្ញាតឱ្យកម្មវិធីប្រើវិធីសាស្ត្រដើម្បី​បញ្ចូល និងលុបទម្រង់​គំរូ​ផ្ទៃមុខសម្រាប់ប្រើប្រាស់។"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"ប្រើ​ហាតវែរ​ដោះសោ​តាមទម្រង់មុខ"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"អនុញ្ញាត​ឱ្យ​កម្មវិធី​ប្រើ​ហាតវែរ​ដោះសោតាមទម្រង់មុខ​សម្រាប់​ការផ្ទៀងផ្ទាត់"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"ការដោះសោ​តាមទម្រង់មុខ"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"ស្កេន​បញ្ចូល​មុខរបស់អ្នក​ម្ដងទៀត"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"ដើម្បី​ធ្វើឱ្យ​ការសម្គាល់មុខ​ប្រសើរជាងមុន សូមស្កេន​បញ្ចូល​មុខរបស់អ្នក​ម្ដងទៀត"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"មិនអាច​ថត​ទិន្នន័យទម្រង់មុខ​បាន​ត្រឹមត្រូវទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
@@ -570,33 +568,28 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ផ្លាស់ទី​ទូរសព្ទទៅខាងឆ្វេង។"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ផ្លាស់ទីទូរសព្ទទៅខាងស្ដាំ។"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"សូមមើល​ឱ្យចំ​ឧបករណ៍​របស់អ្នក​ជាងមុន។"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"មើលមិនឃើញ​មុខងារ​របស់អ្នកទេ។ សូមសម្លឹងមើល​ទូរសព្ទ។"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"បែរមុខ​របស់អ្នក​ឱ្យចំ​ពីមុខ​ទូរសព្ទ​ផ្ទាល់។"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"មាន​ចលនា​ខ្លាំងពេក។ សូមកាន់​ទូរសព្ទ​ឱ្យនឹង។"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"សូម​​ស្កេន​បញ្ចូល​មុខរបស់អ្នក​ម្ដងទៀត។"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"មិន​អាច​សម្គាល់មុខ​បាន​ទៀតទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
     <string name="face_acquired_too_similar" msgid="1508776858407646460">"ស្រដៀងគ្នា​ពេក សូមផ្លាស់ប្ដូរ​កាយវិការ​របស់អ្នក។"</string>
-    <string name="face_acquired_pan_too_extreme" msgid="4581629343077288178">"ងាកក្បាល​របស់អ្នក​បន្តិចទៀត។"</string>
-    <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ងាកក្បាល​របស់អ្នក​បន្តិចទៀត។"</string>
+    <string name="face_acquired_pan_too_extreme" msgid="4581629343077288178">"ងាកក្បាល​របស់អ្នកតិចជាងមុន​បន្តិច។"</string>
+    <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ងាកក្បាល​របស់អ្នកតិចជាងមុន​បន្តិច។"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"ងាកក្បាល​របស់អ្នក​បន្តិចទៀត។"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"យកអ្វី​ដែលបាំង​មុខ​របស់អ្នកចេញ។"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"សម្អាត​ឧបករណ៍ចាប់សញ្ញា​នៅគែម​ខាងលើ​នៃអេក្រង់។"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"សម្អាតផ្នែកខាង​លើនៃ​អេក្រង់​របស់​អ្នក រួមទាំង​របារខ្មៅ"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"មិនអាច​ផ្ទៀងផ្ទាត់​មុខបានទេ។ មិនមាន​ហាតវែរទេ។"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"សាកល្បង​ដោះសោតាមទម្រង់មុខ​ម្ដងទៀត។"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"មិនអាច​ផ្ទុកទិន្នន័យទម្រង់​មុខថ្មី​បានទេ។ សូមលុបទិន្នន័យទម្រង់​មុខចាស់ជាមុនសិន។"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"បាន​បោះបង់​ប្រតិបត្តិការចាប់​ផ្ទៃមុខ។"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"អ្នកប្រើប្រាស់​បានបោះបង់​ការដោះសោ​តាមទម្រង់មុខ។"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ព្យាយាមចូលច្រើនពេកហើយ។ សូមព្យាយាមម្តងទៀតពេលក្រោយ។"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"ការដោះសោ​តាមទម្រង់មុខត្រូវបាន​បិទ ដោយ​សារ​ព្យាយាម​ច្រើនដង​ពេក។"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"មិន​អាច​ផ្ទៀងផ្ទាត់​មុខ​បាន​ទេ។ សូមព្យាយាមម្ដងទៀត។"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"អ្នក​មិនទាន់​រៀបចំ​ការដោះសោតាមទម្រង់មុខ​នៅឡើយទេ។"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"មិនអាចប្រើ​ការដោះសោតាមទម្រង់មុខ​នៅលើ​ឧបករណ៍​នេះ​បានទេ។"</string>
     <string name="face_name_template" msgid="7004562145809595384">"ផ្ទៃមុខទី <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1079,7 +1072,7 @@
     <string name="Midnight" msgid="5630806906897892201">"កណ្ដាល​អធ្រាត្រ​"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="6876518925844129331">"ជ្រើស​ទាំងអស់"</string>
+    <string name="selectAll" msgid="6876518925844129331">"ជ្រើសរើស​ទាំងអស់"</string>
     <string name="cut" msgid="3092569408438626261">"កាត់"</string>
     <string name="copy" msgid="2681946229533511987">"ចម្លង"</string>
     <string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"មិនអាច​ចម្លងទៅ​អង្គចងចាំទេ"</string>
@@ -1140,8 +1133,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"បើក​ជា​មួយ"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"បើក​ជាមួយ %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"បើក"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ផ្ដល់​សិទ្ធិ​ចូលប្រើ ដើម្បី​បើកតំណ <xliff:g id="HOST">%1$s</xliff:g> តាមរយៈ"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"ផ្ដល់​សិទ្ធិ​ចូល​ប្រើ ដើម្បី​បើកតំណ <xliff:g id="HOST">%1$s</xliff:g> តាមរយៈ <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"បើក​តំណ <xliff:g id="HOST">%1$s</xliff:g> ជាមួយ"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"បើកតំណជាមួយ"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"បើក​តំណជាមួយ <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"បើក​តំណ <xliff:g id="HOST">%1$s</xliff:g> ជាមួយ <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ផ្តល់​សិទ្ធិ​ចូល​ប្រើ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"កែសម្រួល​ជាមួយ"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"កែសម្រួល​ជាមួយ​ %1$s"</string>
@@ -1368,8 +1363,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ធ្វើការកំណត់ដូចដើមឡើងវិញ ដើម្បី​បិទ​មុខងារប្រមូលធ្វើតេស្ត។"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"មានទឹក ឬ​កម្ទេចផ្សេងៗ​នៅក្នុងរន្ធ USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"រន្ធ USB ត្រូវបាន​បិទ​ដោយ​ស្វ័យប្រវត្តិ។ សូមចុច​ដើម្បី​ស្វែងយល់​បន្ថែម។"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"អាច​ប្រើរន្ធ USB បាន"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ទូរសព្ទ​រកមិនឃើញ​ទឹក ឬ​កម្ទេចផ្សេងៗ​ទេ។"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"កំពុងទទួលយករបាយការណ៍កំហុស…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ចែករំលែករបាយការណ៍កំហុសឬ?"</string>
@@ -1594,6 +1588,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ចាប់ផ្ដើម​កម្មវិធី​អ៊ីនធឺណិត?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ទទួល​ការ​ហៅ​?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ជា​និច្ច"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"កំណត់​ឱ្យ​បើក​ជានិច្ច"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"តែ​ម្ដង"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ការកំណត់"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s មិន​គាំទ្រ​ប្រវត្តិរូប​ការងារ"</string>
@@ -1623,8 +1618,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"#<xliff:g id="ID">%1$d</xliff:g> ត្រួត​គ្នា"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", សុវត្ថិភាព"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"មុខងារចាប់ផ្ដើម​សកម្មភាព​នៅផ្ទៃខាងក្រោយ​ពី <xliff:g id="PACKAGENAME">%1$s</xliff:g> នេះ​នឹងត្រូវ​ទប់ស្កាត់​នៅក្នុង​កំណែបង្កើត Q នាពេលអនាគត។ សូមមើល g.co/dev/bgblock ។"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"បានទប់ស្កាត់​មុខងារចាប់ផ្ដើម​សកម្មភាព​នៅផ្ទៃខាងក្រោយ​ពី <xliff:g id="PACKAGENAME">%1$s</xliff:g> ។ សូមមើល g.co/dev/bgblock ។"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ភ្លេច​​លំនាំ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"លំនាំ​មិន​ត្រឹមត្រូវ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ"</string>
@@ -1678,8 +1671,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ផ្លូវកាត់​ភាព​ងាយ​ស្រួល​បាន​បើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ផ្លូវកាត់​ភាព​ងាយ​ស្រួល​បាន​បិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"ចុចគ្រាប់ចុច​កម្រិត​សំឡេងទាំងពីរ​ឱ្យជាប់រយៈពេលបីវិនាទី ដើម្បីប្រើ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ជ្រើសរើស​មុខងារ​ដែលត្រូវ​ប្រើ នៅពេល​ដែល​អ្នកចុច​ប៊ូតុង​ភាពងាយស្រួល៖"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ដើម្បី​ផ្លាស់ប្តូរ​មុខងារ សូម​ចុច​ប៊ូតុង​ភាព​ងាយស្រួល​ឲ្យ​ជាប់។"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ជ្រើសរើស​សេវាកម្ម​ដែលត្រូវ​ប្រើ នៅពេល​ដែល​អ្នក​ចុច​ប៊ូតុង​ភាពងាយស្រួល៖"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ជ្រើសរើស​សេវាកម្ម​ដែលត្រូវប្រើជាមួយចលនា​ភាពងាយស្រួល (អូស​ឡើងលើ​ពី​ផ្នែកខាងក្រោម​នៃ​អេក្រង់​ដោយប្រើ​ម្រាមដៃ​ពីរ)៖"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ជ្រើសរើស​សេវាកម្ម​ដែលត្រូវប្រើជាមួយ​ចលនា​ភាពងាយស្រួល (អូស​ឡើងលើ​ពី​ផ្នែកខាងក្រោម​នៃ​អេក្រង់​ដោយប្រើ​ម្រាមដៃ​បី)៖"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ដើម្បី​ប្ដូរឆ្លាស់​រវាង​សេវាកម្មផ្សេងៗ សូមចុច​ប៊ូតុង​ភាពងាយស្រួល​ឱ្យជាប់។"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ដើម្បី​ប្ដូរឆ្លាស់​រវាង​សេវាកម្មផ្សេងៗ សូមអូស​ឡើងលើ​ដោយប្រើ​ម្រាមដៃ​ពីរ ហើយ​សង្កត់ឱ្យជាប់។"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ដើម្បី​ប្ដូរឆ្លាស់​រវាង​សេវាកម្មផ្សេងៗ សូមអូស​ឡើងលើ​ដោយប្រើ​ម្រាមដៃ​បី ហើយ​សង្កត់ឱ្យជាប់។"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ការ​ពង្រីក"</string>
     <string name="user_switched" msgid="3768006783166984410">"អ្នក​ប្រើ​បច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"កំពុង​ប្ដូរ​ទៅ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index fa42a60..875ecd4 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ಕರೆ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ಕರೆ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"ಕಾರ್ ಮೋಡ್"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ಖಾತೆಯ ಸ್ಥಿತಿ"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ಡೆವಲಪರ್ ಸಂದೇಶಗಳು"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"ಡೆವಲಪರ್ ಅವರಿಗೆ ಸಂಬಂಧಿಸಿದ ಪ್ರಮುಖ ಸಂದೇಶಗಳು"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"ಅಪ್‌ಡೇಟ್‌ಗಳು"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ನೆಟ್‌ವರ್ಕ್ ಸ್ಥಿತಿ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ನೆಟ್‌ವರ್ಕ್ ಎಚ್ಚರಿಕೆಗಳು"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ಫೋನ್ ಅನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ಫೋನ್ ಅನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಹೆಚ್ಚಿನದ್ದನ್ನು ನೇರವಾಗಿ ನೋಡಿ."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"ನಿಮ್ಮ ಮುಖ ಕಾಣಿಸುತ್ತಿಲ್ಲ. ಫೋನ್ ಕಡೆಗೆ ನೋಡಿ."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"ನಿಮ್ಮ ಮುಖವನ್ನು ಫೋನ್‌ಗೆ ನೇರವಾಗಿ ಇರಿಸಿ."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"ತುಂಬಾ ಅಲುಗಾಡುತ್ತಿದೆ ಫೋನ್ ಅನ್ನು ಸ್ಥಿರವಾಗಿ ಹಿಡಿಯಿರಿ."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ನಿಮ್ಮ ಮುಖವನ್ನು ಮರುನೋಂದಣಿ ಮಾಡಿ."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"ಮುಖ ಗುರುತಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ನಿಮ್ಮ ತಲೆಯನ್ನು ಹೆಚ್ಚು ತಿರುಗಿಸಬೇಡಿ."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"ನಿಮ್ಮ ತಲೆಯನ್ನು ಸ್ವಲ್ಪ ಕಡಿಮೆ ತಿರುಗಿಸಿ."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"ನಿಮ್ಮ ಮುಖವನ್ನು ಮರೆಮಾಡುವ ಯಾವುದನ್ನಾದರೂ ತೆಗೆದುಹಾಕಿ."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"ಸ್ಕ್ರೀನ್ ಮೇಲ್ಬಾಗದ ಅಂಚಿನಲ್ಲಿನ ಸೆನ್ಸರ್ ಸ್ವಚ್ಚಗೊಳಿಸಿ."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"ಬ್ಲ್ಯಾಕ್ ಬಾರ್ ಸೇರಿದಂತೆ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಮೇಲ್ಭಾಗವನ್ನು ತೆರವುಗೊಳಿಸಿ"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"ಮುಖ ದೃಢೀಕರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಹಾರ್ಡ್‌ವೇರ್ ಲಭ್ಯವಿಲ್ಲ."</string>
@@ -886,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"ಅನ್‌ಲಾಕ್ ಪ್ರದೇಶವನ್ನು ವಿಸ್ತರಿಸು."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ಸ್ಲೈಡ್ ಅನ್‌ಲಾಕ್."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ಪ್ಯಾಟರ್ನ್ ಅನ್‌ಲಾಕ್."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ಮುಖದ ಅನ್‌ಲಾಕ್."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ಫೇಸ್ ಅನ್‌ಲಾಕ್."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"ಪಿನ್ ಅನ್‌ಲಾಕ್."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"ಸಿಮ್‌ ಪಿನ್‌ ಅನ್‌ಲಾಕ್ ಮಾಡಿ."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"ಸಿಮ್‌ PUK ಅನ್‌ಲಾಕ್ ಮಾಡಿ."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"ಇದರ ಮೂಲಕ ತೆರೆಯಿರಿ"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ಜೊತೆಗೆ ತೆರೆಯಿರಿ"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"ತೆರೆ"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ಮೂಲಕ <xliff:g id="HOST">%1$s</xliff:g> ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಲು ಪ್ರವೇಶವನ್ನು ನೀಡಿ"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> ಮೂಲಕ <xliff:g id="HOST">%1$s</xliff:g> ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಲು ಪ್ರವೇಶವನ್ನು ನೀಡಿ"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"ಇವುಗಳ ಮೂಲಕ <xliff:g id="HOST">%1$s</xliff:g> ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"ಇವುಗಳ ಮೂಲಕ ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> ಮೂಲಕ ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> ಮೂಲಕ <xliff:g id="HOST">%1$s</xliff:g> ಲಿಂಕ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ಪ್ರವೇಶ ಅನುಮತಿಸಿ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ಇವರ ಜೊತೆಗೆ ಎಡಿಟ್ ಮಾಡಿ"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ಜೊತೆಗೆ ಎಡಿಟ್ ಮಾಡಿ"</string>
@@ -1583,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ಬ್ರೌಸರ್ ಪ್ರಾರಂಭಿಸುವುದೇ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ಕರೆ ಸ್ವೀಕರಿಸುವುದೇ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ಯಾವಾಗಲೂ"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ಯಾವಾಗಲೂ ತೆರೆಯುವುದಕ್ಕೆ ಹೊಂದಿಸಿ"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"ಒಮ್ಮೆ ಮಾತ್ರ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ"</string>
@@ -1612,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ಓವರ್‌ಲೇ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ಸುರಕ್ಷಿತ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"ಭವಿಷ್ಯದ Q ಬಿಲ್ಡ್‌ಗಳಲ್ಲಿ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ನಿಂದ ಪ್ರಾರಂಭವಾಗುವ ಈ ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗುತ್ತದೆ. g.co/dev/bgblock ಅನ್ನು ನೋಡಿ."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ನಿಂದ ಪ್ರಾರಂಭವಾಗುವ ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ. g.co/dev/bgblock ಅನ್ನು ನೋಡಿ."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಮರೆತಿರುವಿರಿ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ತಪ್ಪು ಪ್ಯಾಟರ್ನ್"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ತಪ್ಪು ಪಾಸ್‌ವರ್ಡ್"</string>
@@ -1667,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್‌, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಿದೆ"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ಪ್ರವೇಶಿಸುವಿಕೆ ಶಾರ್ಟ್‌ಕಟ್‌, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಫ್ ಮಾಡಿದೆ"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಬಳಸಲು ಎರಡೂ ಧ್ವನಿ ಕೀಗಳನ್ನು ಮೂರು ಸೆಕೆಂಡ್‌ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ನೀವು ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಬಳಸುವುದಕ್ಕಾಗಿ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಆರಿಸಿ:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಬದಲಾಯಿಸಲು, ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಒತ್ತಿಹಿಡಿದುಕೊಳ್ಳಿ."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ನೀವು ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಬಳಸುವುದಕ್ಕಾಗಿ ಸೇವೆಯೊಂದನ್ನು ಆರಿಸಿ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ಪ್ರವೇಶಿಸುವಿಕೆ ಗೆಸ್ಚರ್‌ನೊಂದಿಗೆ ಬಳಸಲು ಸೇವೆಯೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ಪ್ರವೇಶಿಸುವಿಕೆ ಗೆಸ್ಚರ್‌ನೊಂದಿಗೆ ಬಳಸಲು ಸೇವೆಯೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ಸೇವೆಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಅನ್ನು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ಸೇವೆಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ಸೇವೆಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string>
     <string name="user_switched" msgid="3768006783166984410">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರು <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 8bdb19d..9077145 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 통화"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 통화"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 통화"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 통화"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -253,9 +254,10 @@
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"가상 키보드"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"물리적 키보드"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"보안"</string>
-    <string name="notification_channel_car_mode" msgid="3553380307619874564">"운전모드"</string>
+    <string name="notification_channel_car_mode" msgid="3553380307619874564">"운전 모드"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"계정 상태"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"개발자 메시지"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"중요한 개발자 메시지"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"업데이트"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"네트워크 상태"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"네트워크 알림"</string>
@@ -359,8 +361,8 @@
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"앱이 프로필 소유자와 기기 소유자를 설정하도록 허용합니다."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"실행 중인 앱 순서 재지정"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"앱이 사용자의 입력 없이 작업을 포그라운드나 백그라운드로 이동할 수 있도록 허용합니다."</string>
-    <string name="permlab_enableCarMode" msgid="5684504058192921098">"운전모드 사용"</string>
-    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"앱이 운전모드를 사용할 수 있도록 허용합니다."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"운전 모드 사용"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"앱이 운전 모드를 사용할 수 있도록 허용합니다."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"다른 앱 종료"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"앱이 다른 앱의 백그라운드 프로세스를 종료할 수 있도록 허용합니다. 이 경우 다른 앱이 실행 중지될 수 있습니다."</string>
     <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"이 앱은 다른 앱 위에 표시될 수 있음"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"지문 아이콘"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"얼굴인식 잠금해제 하드웨어 관리"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"사용할 얼굴 템플릿의 추가 및 삭제 메서드를 앱에서 호출하도록 허용합니다."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"얼굴인식 잠금해제 하드웨어 사용"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"앱에서 얼굴인식 잠금해제 하드웨어를 인증에 사용하도록 허용합니다."</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"얼굴인식 잠금해제"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"얼굴 재등록 필요"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"인식률을 개선하려면 얼굴을 다시 등록하세요."</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"정확한 얼굴 데이터를 캡처하지 못했습니다. 다시 시도하세요."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"휴대전화를 왼쪽으로 이동하세요."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"휴대전화를 오른쪽으로 이동하세요."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"기기에서 더 똑바로 바라보세요."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"얼굴이 보이지 않습니다. 휴대전화를 바라보세요."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"휴대전화가 얼굴 정면을 향하도록 두세요."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"너무 많이 움직였습니다. 휴대전화를 흔들리지 않게 잡으세요."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"얼굴을 다시 등록해 주세요."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"더 이상 얼굴을 인식할 수 없습니다. 다시 시도하세요."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"고개를 조금 덜 돌려 보세요."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"고개를 조금 덜 돌려 보세요."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"얼굴이 가려지지 않도록 해 주세요."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"화면 상단 가장자리의 센서를 깨끗하게 닦아 주세요."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"검은색 바를 포함한 화면 상단을 청소하세요."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"얼굴을 확인할 수 없습니다. 하드웨어를 사용할 수 없습니다."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"얼굴인식 잠금해제를 다시 시도해 주세요."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"새 얼굴 데이터를 저장할 수 없습니다. 먼저 기존 얼굴 데이터를 삭제하세요."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"얼굴 인식 작업이 취소되었습니다."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"사용자가 얼굴인식 잠금해제를 취소했습니다."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"시도 횟수가 너무 많습니다. 나중에 다시 시도하세요."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"시도 횟수가 너무 많습니다. 얼굴인식 잠금해제가 사용 중지되었습니다."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"얼굴을 확인할 수 없습니다. 다시 시도하세요."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"얼굴인식 잠금해제를 설정하지 않았습니다."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"이 기기에서는 얼굴인식 잠금해제가 지원되지 않습니다."</string>
     <string name="face_name_template" msgid="7004562145809595384">"얼굴 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -910,7 +903,7 @@
     <string name="granularity_label_link" msgid="5815508880782488267">"링크"</string>
     <string name="granularity_label_line" msgid="5764267235026120888">"행"</string>
     <string name="factorytest_failed" msgid="5410270329114212041">"출고 테스트 불합격"</string>
-    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST 작업은 /system/app 디렉토리에 설치된 패키지에 대해서만 지원됩니다."</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST 작업은 /system/app 디렉터리에 설치된 패키지에 대해서만 지원됩니다."</string>
     <string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST 작업을 제공하는 패키지가 없습니다."</string>
     <string name="factorytest_reboot" msgid="6320168203050791643">"다시 부팅"</string>
     <string name="js_dialog_title" msgid="1987483977834603872">"\'<xliff:g id="TITLE">%s</xliff:g>\' 페이지 내용:"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"연결 프로그램"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s(으)로 열기"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"열기"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"다음으로 <xliff:g id="HOST">%1$s</xliff:g> 링크를 열려면 액세스 권한 부여"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g>(으)로 <xliff:g id="HOST">%1$s</xliff:g> 링크를 열려면 액세스 권한 부여"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> 링크를 열 때 사용할 앱"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"링크를 열 때 사용할 앱"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> 앱으로 링크 열기"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> 앱으로 <xliff:g id="HOST">%1$s</xliff:g> 링크 열기"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"권한 부여"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"편집 프로그램:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s(으)로 수정"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"테스트 하네스 모드를 사용 중지하려면 초기화하세요."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 포트에서 액체 또는 이물질 감지됨"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 포트가 자동으로 사용 중지되었습니다. 자세한 내용을 보려면 탭하세요."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB 포트를 사용해도 좋음"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"휴대전화에서 액체나 이물질이 더 이상 감지되지 않습니다."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"버그 보고서 가져오는 중..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"버그 보고서를 공유하시겠습니까?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"브라우저를 실행하시겠습니까?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"통화를 수락하시겠습니까?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"항상"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"항상 열도록 설정"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"한 번만"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"설정"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s에서 직장 프로필을 지원하지 않습니다."</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"<xliff:g id="ID">%1$d</xliff:g>번째 오버레이"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", 보안"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>의 백그라운드 활동 시작은 향후 Q 빌드에서 차단됩니다. g.co/dev/bgblock을 참조하세요."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>의 백그라운드 활동 시작이 차단되었습니다. g.co/dev/bgblock을 참조하세요."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"패턴을 잊음"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"잘못된 패턴"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"잘못된 비밀번호"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"접근성 단축키로 인해 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"접근성 단축키로 인해 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 서비스를 사용하려면 두 볼륨 키를 3초 동안 길게 누르세요"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"접근성 버튼을 탭할 때 사용할 기능을 선택하세요."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"기능을 변경하려면 접근성 버튼을 길게 터치하세요."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"접근성 버튼을 탭했을 때 실행할 서비스를 선택하세요."</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"접근성 동작(두 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 서비스를 선택하세요."</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"접근성 동작(세 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 서비스를 선택하세요."</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"서비스 간에 전환하려면 접근성 버튼을 길게 터치합니다."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"서비스 간에 전환하려면 두 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"서비스 간에 전환하려면 세 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"확대"</string>
     <string name="user_switched" msgid="3768006783166984410">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>(으)로 전환하는 중…"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 4d1d0f4..8cac363 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi аркылуу чалуу"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> аркылуу Wi-Fi менен чалуу"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN аркылуу чалуу"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN аркылуу чалуу"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -254,8 +255,9 @@
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Аппараттык баскычтоп"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"Коопсуздук"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Унаа режими"</string>
-    <string name="notification_channel_account" msgid="7577959168463122027">"Каттоо эсебинин абалы"</string>
+    <string name="notification_channel_account" msgid="7577959168463122027">"Аккаунттун абалы"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Иштеп чыгуучунун билдирүүлөрү"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Иштеп чыгуучулардын маанилүү билдирүүлөрү"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Жаңыртуулар"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Тармактын абалы"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Тармактын эскертүүлөрү"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Манжа изинин сүрөтчөсү"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"жүзүнөн таануу функциясынын аппараттык камсыздоосун башкаруу"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Колдонмого пайдалануу үчүн жүздүн үлгүлөрүн кошуу жана жок кылуу мүмкүндүгүн берет."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"аппараттык камсыздоо үчүн жүзүнөн таанууну колдонуу"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Колдонмо аныктыкты текшерүүдө Жүзүнөн таануу функциясынын аппараттык камсыздоосун колдонот"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Жүзүнөн таануу"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Жүзүңүздү кайра таанытыңыз."</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Мыкты таануу үчүн, жүзүңүздү кайра таанытыңыз"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Жүзүңүз жакшы тартылган жок. Кайра аракет кылыңыз."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Телефонду солго жылдырыңыз."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Телефонду оңго жылдырыңыз."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Түзмөгүңүзгө түз караңыз."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Жүзүңүз көрүнбөй жатат. Телефонду караңыз."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Телефонду жүзүңүздүн маңдайында кармаңыз."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Кыймылдап жибердиңиз. Телефонду түз кармаңыз."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Жүзүңүздү кайра таанытыңыз."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Жүз таанылган жок. Кайра аракет кылыңыз."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Башыңызды бир аз гана эңкейтиңиз."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Башыңызды бир аз гана эңкейтиңиз."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Жүзүңүздү жашырып турган нерселерди алып салыңыз."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Экрандын жогору жагындагы сенсорду тазалаңыз."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Экраныңыздын жогору жагын, анын ичинде тилкени да тазалаңыз"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Жүз ырасталбай жатат. Аппараттык камсыздоо жеткиликсиз."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Жүзүнөн таануу функциясын кайра текшерип көрүңүз."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Жаңы жүздү сактоо мүмкүн эмес. Адегенде эскисин өчүрүңүз."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Жүздүн аныктыгын текшерүү жокко чыгарылды."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Жүзүнөн таануу функциясын колдонуучу өчүрүп салды."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Өтө көп жолу аракет жасадыңыз. Кийинчерээк кайра аракет кылыңыз."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Өтө көп жолу аракет кылдыңыз. Жүзүнөн таануу функциясы өчүрүлдү."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Жүз ырасталбай жатат. Кайра аракет кылыңыз."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Жүзүнөн таануу функциясын жөндөй элексиз."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Жүзүнөн таануу функциясы бул түзмөктө иштебейт."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Жүз <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Төмөнкү менен ачуу"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s менен ачуу"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Ачуу"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Төмөнкү колдонмо менен <xliff:g id="HOST">%1$s</xliff:g> шилтемелерин  ачууга уруксат берүү"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> колдонмосу менен <xliff:g id="HOST">%1$s</xliff:g> шилтемелерин  ачууга уруксат берүү"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> шилтемелерин төмөнкү колдонмодо ачуу:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Шилтемелерди төмөнкү колдонмодо ачуу:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Шилтемелерди <xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосунда ачуу"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> шилтемелерин <xliff:g id="APPLICATION">%2$s</xliff:g> колдонмосунда ачуу"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Мүмкүнчүлүк берүү"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Төмөнкү менен түзөтүү"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s менен түзөтүү"</string>
@@ -1368,8 +1363,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Сыноо программасынын режимин өчүрүү үчүн, баштапкы жөндөөлөргө кайтарыңыз."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB портунда суюктук же урандылар бар"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт автоматтык түрдө өчүрүлдү. Кененирээк маалымат алуу үчүн таптап коюңуз."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портун колдонууга болот"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефон суюктук менен урандыларды аныктаган жок."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Мүчүлүштүк тууралуу кабар алынууда…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Мүчүлүштүк тууралуу баяндама бөлүшүлсүнбү?"</string>
@@ -1505,7 +1499,7 @@
     <string name="find_next" msgid="5742124618942193978">"Кийинкиси"</string>
     <string name="find_previous" msgid="2196723669388360506">"Мурункусу"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> колдонуучусу жайгашкан жердин маалыматын сурады"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Жайгашкан жердин маалыматын суроо"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Каякта экенин билүү"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) сурады"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ооба"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Жок"</string>
@@ -1594,6 +1588,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Серепчи иштетилсинби?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Чалуу кабыл алынсынбы?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Дайыма"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Ар дайым ачылсын деп жөндөө"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Бир жолу гана"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Жөндөөлөр"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s жумуш профилин колдоого албайт"</string>
@@ -1623,8 +1618,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Катмар №<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", корголгон"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> сайтынын фондук режимде иштеши Q курамдарында бөгөттөлүп турат. Төмөнкүгө өтүңүз: g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> сайтынын фондук режимде иштеши бөгөттөлдү. Төмөнкүгө өтүңүз: g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Үлгү унутулду"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Графикалык ачкыч туура эмес"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Сырсөз туура эмес"</string>
@@ -1678,8 +1671,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Атайын мүмкүнчүлүктөр кыска жолу <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүздү"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Атайын мүмкүнчүлүктөр кыска жолу <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын өчүрдү"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын колдонуу үчүн үнүн чоңойтуп/кичирейтүү баскычтарын үч секунд коё бербей басып туруңуз"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган функцияны тандаңыз:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Функцияларды өзгөртүү үчүн Атайын мүмкүнчүлүктөр баскычын басып, кармап туруңуз."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган кызматты тандаңыз:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн кызматты тандаңыз (эки манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Атайын мүмкүнчүлүктөр жаңсоосу аркылуу иштетиле турган кызматты тандаңыз (үч манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Кызматтарды которуштуруу үчүн Атайын мүмкүнчүлүктөр баскычын басып, кармап туруңуз."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Кызматтарды которуштуруу үчүн эки манжаңыз менен өйдө сүрүп, кармап туруңуз."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Башка кызматка которулуу үчүн үч манжаңыз менен экранды өйдө сүрүп, кармап туруңуз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Чоңойтуу"</string>
     <string name="user_switched" msgid="3768006783166984410">"Учурдагы колдонуучу <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string>
@@ -1912,7 +1909,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Жаңыртууну издөө"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Сизге жаңы билдирүүлөр келди"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Көрүү үчүн SMS колдонмосун ачыңыз"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Айрым функциялар чектелиши мүмкүн"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Айрым функциялар иштебеши мүмкүн"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Жумуш профили кулпуланган"</string>
     <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>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index bfc999e..47b0fe4 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Calling"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ການໂທ Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Call"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"ໂໝດຂັບລົດ"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ສະ​ຖາ​ນະ​​ບັນ​ຊີ"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ຂໍ້ຄວາມນັກພັດທະນາ"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"ຂໍ້ຄວາມສຳຄັນຈາກຜູ້ພັດທະນາ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"ອັບເດດ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ສະຖານະເຄືອຂ່າຍ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ແຈ້ງເຕືອນເຄືອຂ່າຍ"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ໄອຄອນລາຍນິ້ວມື"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"ຈັດການຮາດແວປົດລັອກດ້ວຍໜ້າ"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ອະນຸຍາດໃຫ້ແອັບເປີດວິທີການຕ່າງໆເພື່ອເພີ່ມ ແລະ ລຶບແມ່ແບບໃບໜ້າສຳລັບການນຳໃຊ້."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"ໃຊ້ຮາດແວການປົດລັອກໃບໜ້າ"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"ອະນຸຍາດໃຫ້ແອັບໃຊ້ຮາດແວການປົດລັອກດ້ວຍໜ້າເພື່ອພິສູດຢືນຢັນ"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"ປົດລັອກດ້ວຍໜ້າ"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"ລົງທະບຽນໃບໜ້າຂອງທ່ານຄືນໃໝ່"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"ເພື່ອປັບປຸງການຈຳແນກ, ກະລຸນາລົງທະບຽນໃບໜ້າຂອງທ່ານຄືນໃໝ່."</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"ບໍ່ສາມາດບັນທຶກຂໍ້ມູນໃບໜ້າທີ່ຖືກຕ້ອງໄດ້. ກະລຸນາລອງໃໝ່."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ຍ້າຍໂທລະສັບໄປທາງຊ້າຍ."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ຍ້າຍໂທລະສັບໄປທາງຂວາ."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"ກະລຸນາເບິ່ງອຸປະກອນຂອງທ່ານໃຫ້ຊື່ໆ."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"ບໍ່ສາມາດເບິ່ງເຫັນໜ້າຂອງທ່ານໄດ້. ກະລຸນາເບິ່ງໂທລະສັບ."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"ຫັນໜ້າຂອງທ່ານໄປໃສ່ໜ້າໂທລະສັບໂດຍກົງ."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"ເຄື່ອນໄຫວຫຼາຍເກີນໄປ. ກະລຸນາຖືໂທລະສັບໄວ້ຊື່ໆ."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ກະລຸນາລົງທະບຽນອຸປະກອນຂອງທ່ານອີກເທື່ອໜຶ່ງ."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"ບໍ່ສາມາດຈຳແນກໃບໜ້າໄດ້ອີກຕໍ່ໄປ. ກະລຸນາລອງໃໝ່."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ອຽງຫົວຂອງທ່ານໜ້ອຍໜຶ່ງ."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"ອຽງຫົວຂອງທ່ານໜ້ອຍໜຶ່ງ."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"ນຳສິ່ງທີ່ກີດຂວາງໃບໜ້າທ່ານອອກ."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"ທຳຄວາມສະອາດເຊັນເຊີຢູ່ເທິງສຸດຂອງຂອບຈໍ."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"ທຳຄວາມສະອາດສ່ວນເທິງສຸດຂອງໜ້າຈໍທ່ານ, ຮວມທັງແຖບດຳນຳ"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"ບໍ່ສາມາດຢັ້ງຢືນໃບໜ້າໄດ້. ບໍ່ມີຮາດແວໃຫ້ໃຊ້."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"ລອງປົດລັອກດ້ວຍໜ້າອີກເທື່ອໜຶ່ງ."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"ບໍ່ສາມາດບັນທຶກຂໍ້ມູນໃບໜ້າໃໝ່ໄດ້. ກະລຸນາລຶບຂໍ້ມູນເກົ່າອອກກ່ອນ."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ຍົກເລີກການດຳເນີນການກັບໃບໜ້າແລ້ວ."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ຜູ້ໃຊ້ຍົກເລີກການປົດລັອກດ້ວຍໜ້າແລ້ວ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ມີຄວາມພະຍາຍາມຫຼາຍຄັ້ງເກີນໄປ. ກະລຸນາລອງໃໝ່ໃນພາຍຫຼັງ."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"ພະຍາຍາມຫຼາຍເທື່ອເກີນໄປ. ປິດນຳໃຊ້ການປົດລັອກດ້ວຍໜ້າແລ້ວ."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"ບໍ່ສາມາດຢັ້ງຢືນໃບໜ້າໄດ້. ກະລຸນາລອງໃໝ່."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"ທ່ານຍັງບໍ່ໄດ້ຕັ້ງການປົດລັອກດ້ວຍໜ້າເທື່ອ."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"ບໍ່ຮອງຮັບການປົດລັອກດ້ວຍໜ້າຢູ່ອຸປະກອນນີ້."</string>
     <string name="face_name_template" msgid="7004562145809595384">"ໃບໜ້າ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"ເປີດໂດຍໃຊ້"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"ເປີດ​ໂດຍ​ໃຊ້ %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"ເປີດ"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ໃຫ້ສິດອະນຸຍາດເພື່ອເປີດລິ້ງ <xliff:g id="HOST">%1$s</xliff:g> ດ້ວຍ"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"ໃຫ້ສິດອະນຸຍາດເພື່ອເປີດລິ້ງ <xliff:g id="HOST">%1$s</xliff:g> ດ້ວຍ <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"ເປີດລິ້ງ <xliff:g id="HOST">%1$s</xliff:g> ໂດຍໃຊ້"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"ເປີດລິ້ງໂດຍໃຊ້"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"ເປີດລິ້ງໂດຍໃຊ້ <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"ເປີດລິ້ງ <xliff:g id="HOST">%1$s</xliff:g> ໂດຍໃຊ້ <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ໃຫ້ສິດອະນຸຍາດ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"​ແກ້​ໄຂ​ໃນ"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"ແກ້​ໄຂ​ໃນ %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ດຳເນີນການຣີເຊັດເປັນຄ່າຈາກໂຮງງານເພື່ອປິດການນຳໃຊ້ໂໝດ Test Harness."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"ມີຂອງແຫລວ ຫຼື ເສດດິນໃນຜອດ USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"ປິດຜອດ USB ໂດຍອັດຕະໂນມັດແລ້ວ. ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ສາມາດໃຊ້ຜອດ USB ໄດ້"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ໂທລະສັບຈະບໍ່ກວດຫາຂອງແຫລວ ຫຼື ເສດດິນອີກຕໍ່ໄປ."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ກຳລັງຂໍລາຍງານຂໍ້ຜິດພາດ…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ແບ່ງປັນລາຍງານບັນຫາບໍ?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ເປີດໂປຣແກຣມທ່ອງເວັບ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ຮັບການໂທບໍ່?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ທຸກຄັ້ງ"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ຕັ້ງໃຫ້ເປັນເປີດທຸກເທື່ອ"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"ຄັ້ງດຽວ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ການຕັ້ງຄ່າ"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ບໍ່​ຮອງ​ຮັບ​ໂປຣ​ໄຟລ໌​ບ່ອນ​ເຮັດ​ວຽກ​ຂອງ​ທ່ານ"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ການວາງຊ້ອນ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ປອດໄພ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"ການເລີ່ມການເຄື່ອນໄຫວໃນພື້ນຫຼັງນີ້ຈາກ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ຈະຖືກບລັອກໄວ້ໃນ Q ເວີຊັນອະນາຄົດ. ກະລຸນາອ່ານ g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"ບລັອກການເຄື່ອນໄຫວພື້ນຫຼັງຈາກ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ໄວ້ແລ້ວ. ກະລຸນາອ່ານ g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ລືມຮູບແບບປົດລັອກ?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ຮູບແບບຜິດ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ລະຫັດຜ່ານບໍ່ຖືກຕ້ອງ"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> on"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Accessibility Shortcut turned <xliff:g id="SERVICE_NAME">%1$s</xliff:g> off"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"ກົດປຸ່ມສຽງທັງສອງພ້ອມກັນຄ້າງໄວ້ສາມວິນາທີເພື່ອໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ເລືອກຄຸນສົມບັດທີ່ຈະໃຊ້ເມື່ອທ່ານແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງ:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ເພື່ອປ່ຽນຄຸນສົມບັດ, ໃຫ້ແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງຄ້າງໄວ້."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ເລືອກບໍລິການເພື່ອໃຊ້ເມື່ອທ່ານແຕະໃສ່ປຸ່ມການຊ່ວຍເຂົ້າເຖິງ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ເລືອກບໍລິການເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສອງນິ້ວ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ເລືອກບໍລິການເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສາມນິ້ວ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ເພື່ອສະຫຼັບລະຫວ່າງບໍລິການຕ່າງໆ, ໃຫ້ແຕະໃສ່ປຸ່ມການຊ່ວຍເຂົ້າເຖິງຄ້າງໄວ້."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ເພື່ອສະຫຼັບລະຫວ່າງບໍລິການຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສອງນິ້ວຄ້າງໄວ້."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ເພື່ອສະຫຼັບລະຫວ່າງບໍລິການຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສາມນິ້ວຄ້າງໄວ້."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ການຂະຫຍາຍ"</string>
     <string name="user_switched" msgid="3768006783166984410">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"ກຳ​ລັງ​ສະ​ລັບ​​ໄປ​ຫາ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 3deae13..6f8e2df 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“ skambinimas"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“ skambinimas"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN skambutis"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN skambutis"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Automobilio režimas"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Paskyros būsena"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Kūrėjų pranešimai"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Svarbūs kūrėjų pranešimai"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Naujiniai"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Tinklo būsena"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Tinklo įspėjimai"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Piršto antspaudo piktograma"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"tvarkyti Atrakinimo pagal veidą aparatinę įrangą"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Programai leidžiama aktyv. metodus, norint pridėti ir ištrinti naudojamus veidų šablonus."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"naudoti Atrakinimo pagal veidą aparatinę įrangą"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Programai leidžiama naudoti Atrakinimo pagal veidą aparatinę įrangą tapatybei nustatyti"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Atrakinimas pagal veidą"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Pakartotinis veido registravimas"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Kad patobulintumėte atpažinimą, iš naujo užregistruokite veidą"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Neužfiks. tikslūs veido duom. Bandykite dar kartą."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Pasukite telefoną kairėn."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Pasukite telefoną dešinėn."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Žiūrėkite tiesiai į įrenginį."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Nematau jūsų veido. Žiūrėkite į telefoną."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Veidas turi būti prieš telefoną."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Įrenginys per daug judinamas. Nejudink. telefono."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Užregistruokite veidą iš naujo."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Nebegalima atpažinti veido. Bandykite dar kartą."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Nesukite tiek galvos."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Nesukite tiek galvos."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Patraukite viską, kas užstoja jūsų veidą."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Nuvalykite jutiklį, esantį ekrano viršuje."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Išvalykite ekrano viršų, įskaitant juodą juostą"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Nepavyko patv. veido. Aparatinė įranga negalima."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Band. naudoti Atrakinimą pagal veidą dar kartą."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Nepavyko išs. naujų veido duomenų. Pirm. ištrinkite senus."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Veido atpažinimo operacija atšaukta."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Atrakinimą pagal veidą atšaukė naudotojas."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Per daug bandymų. Vėliau bandykite dar kartą."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Per daug bandymų. Atrakinimas pagal veidą išjungtas."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nepavyko patvirtinti veido. Bandykite dar kartą."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Nenustatėte Atrakinimo pagal veidą."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Atrakinimas pagal veidą šiame įrenginyje nepalaikomas."</string>
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g> veidas"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Atidaryti naudojant"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Atidaryti naudojant %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Atidaryti"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Suteikite prieigą atidaryti <xliff:g id="HOST">%1$s</xliff:g> nuorodas naudojant"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Suteikite prieigą atidaryti <xliff:g id="HOST">%1$s</xliff:g> nuorodas naudojant „<xliff:g id="APPLICATION">%2$s</xliff:g>“"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Atidaryti <xliff:g id="HOST">%1$s</xliff:g> nuorodas naudojant"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Atidaryti nuorodas naudojant"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Atidaryti nuorodas naudojant „<xliff:g id="APPLICATION">%1$s</xliff:g>“"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Atidaryti <xliff:g id="HOST">%1$s</xliff:g> nuorodas naudojant „<xliff:g id="APPLICATION">%2$s</xliff:g>“"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Suteikti prieigą"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Redaguoti naudojant"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Redaguoti naudojant %1$s"</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Atkurkite gamyklinius duomenis, kad išjungtumėte testavimo sistemos režimą."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Saugu naudoti USB prievadą"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonas nebeaptinka skysčių ar smulkių dalelių."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Pateikiamas pranešimas apie riktą…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bendrinti pranešimą apie riktą?"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Paleisti naršyklę?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Priimti skambutį?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Visada"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Nustatyti parinktį „Visada atidaryti“"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Tik kartą"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Nustatymai"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s nepalaiko darbo profilio"</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Perdanga nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"„<xliff:g id="NAME">%1$s</xliff:g>“: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> tašk. colyje"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", saugu"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Šios fono veiklos paleidimas iš „<xliff:g id="PACKAGENAME">%1$s</xliff:g>“ bus užblokuotas būsimose Q versijose. Žr. g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Fono veiklos paleidimas iš „<xliff:g id="PACKAGENAME">%1$s</xliff:g>“ užblokuotas. Žr. g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Pamiršau atrakinimo piešinį"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Netinkamas atrakinimo piešinys"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Netinkamas slaptažodis"</string>
@@ -1724,8 +1717,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pritaikymo neįgaliesiems sparčiuoju klavišu buvo įjungta „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pritaikymo neįgaliesiems sparčiuoju klavišu buvo išjungta „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Jei norite naudoti „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite abu garsumo klavišus ir palaikykite tris sekundes"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pasirinkite funkciją, kuri bus naudojama, kai paliesite pritaikymo neįgaliesiems mygtuką:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Jei norite pakeisti funkcijas, palieskite ir palaikykite pritaikymo neįgaliesiems mygtuką."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Pasirinkite paslaugą, kuri bus naudojama, kai paliesite pritaikomumo mygtuką:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Pasirinkite paslaugą, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn dviem pirštais iš ekrano apačios):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Pasirinkite paslaugą, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn trimis pirštais iš ekrano apačios):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Norėdami perjungti paslaugas, palieskite ir palaikykite pritaikomumo mygtuką."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Norėdami perjungti paslaugas, perbraukite aukštyn dviem pirštais ir palaikykite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Norėdami perjungti paslaugas, perbraukite aukštyn trimis pirštais ir palaikykite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Didinimas"</string>
     <string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Perjungiama į <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 77ce855..253ff72 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi zvani"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi zvani"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN zvans"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN zvans"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -259,6 +260,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Automašīnas režīms"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Konta statuss"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Izstrādātāju ziņojumi"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Svarīgi izstrādātāju ziņojumi"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Atjauninājumi"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Tīkla statuss"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Tīkla brīdinājumi"</string>
@@ -552,15 +554,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Pirksta nospieduma ikona"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"pārvaldīt aparatūru, kas paredzēta autorizācijai pēc sejas"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Atļauj lietotnei izsaukt metodes izmantojamo sejas veidņu pievienošanai un dzēšanai."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"lietot aparatūru, kas paredzēta autorizācijai pēc sejas"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Atļauj lietotnei izmantot autentificēšanai aparatūru, ar ko veic autorizāciju pēc sejas"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Autorizācija pēc sejas"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Atkārtoti reģistrējiet seju"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Lai uzlabotu atpazīšanu, lūdzu, atkārtoti reģistrējiet savu seju"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Neizdevās tvert sejas datus. Mēģiniet vēlreiz."</string>
@@ -573,7 +571,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Pārvietojiet tālruni pa kreisi."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Pārvietojiet tālruni pa labi."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Lūdzu, tiešāk skatieties uz savu ierīci."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Jūsu seja nav redzama. Paskatieties uz tālruni."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Novietojiet savu seju tieši pretī tālrunim."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Pārāk daudz kustību. Nekustīgi turiet tālruni."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Lūdzu, atkārtoti reģistrējiet savu seju."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Seju vairs nevar atpazīt. Mēģiniet vēlreiz."</string>
@@ -582,24 +580,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Pagrieziet galvu nedaudz mazāk."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Pagrieziet galvu nedaudz mazāk."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Noņemiet visu, kas aizsedz jūsu seju."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Notīriet sensoru ekrāna augšējā malā."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Notīriet ekrāna augšdaļu, tostarp melno joslu."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Nevar verificēt seju. Aparatūra nav pieejama."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Vēlreiz mēģiniet veikt autorizāciju pēc sejas."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Nevar saglabāt jaunās sejas datus. Dzēsiet kādu no vecajām."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Darbība ar sejas datiem atcelta."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Lietotājs atcēla autorizāciju pēc sejas."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Pārāk daudz mēģinājumu. Vēlāk mēģiniet vēlreiz."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Pārāk daudz mēģinājumu. Autorizācija pēc sejas ir atspējota."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nevar verificēt seju. Mēģiniet vēlreiz."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Autorizācija pēc sejas nav iestatīta."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Autorizācija pēc sejas šajā ierīcē netiek atbalstīta"</string>
     <string name="face_name_template" msgid="7004562145809595384">"Seja <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1158,8 +1151,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Atvērt, izmantojot"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Atvērt, izmantojot %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Atvērt"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Piekļuves piešķiršana, lai atvērtu <xliff:g id="HOST">%1$s</xliff:g> saites lietojumprogrammā"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Piekļuves piešķiršana, lai atvērtu <xliff:g id="HOST">%1$s</xliff:g> saites lietojumprogrammā <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> saišu atvēršana, izmantojot:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Saišu atvēršana, izmantojot:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Saišu atvēršana, izmantojot pārlūku <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> saišu atvēršana, izmantojot pārlūku <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Atļaut piekļuvi"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Rediģēt, izmantojot"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Rediģēt, izmantojot %1$s"</string>
@@ -1388,8 +1383,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Lai atspējotu drošības pārbaudes režīmu, veiciet rūpnīcas datu atiestatīšanu."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB pieslēgvietu drīkst izmantot"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Tālrunī vairs netiek konstatēts šķidrums vai gruži."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Notiek kļūdas pārskata izveide…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vai kopīgot kļūdas pārskatu?"</string>
@@ -1615,6 +1609,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vai palaist pārlūkprogrammu?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vai atbildēt uz zvanu?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Vienmēr"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Iestatīt uz “Vienmēr atvērt”"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Tikai vienreiz"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Iestatījumi"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"Programma %1$s neatbalsta darba profilus"</string>
@@ -1644,8 +1639,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Pārklājums Nr. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", drošs"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Šīs fona darbības sākšana no pakotnes <xliff:g id="PACKAGENAME">%1$s</xliff:g> tiks bloķēta turpmākajās Q versijās. Skatiet rakstu g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Fona darbības sākšana no pakotnes <xliff:g id="PACKAGENAME">%1$s</xliff:g> bloķēta. Skatiet rakstu g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Aizmirsu kombināciju"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nepareiza kombinācija"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nepareiza parole"</string>
@@ -1700,8 +1693,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pieejamības saīsne aktivizēja lietotni <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pieejamības saīsne deaktivizēja lietotni <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma taustiņus un turiet tos trīs sekundes."</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izvēlieties funkciju, ko izmantot, kad pieskaraties pogai Pieejamība."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Lai mainītu funkcijas, pieskarieties pogai Pieejamība un turiet to."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Izvēlieties pakalpojumu, ko izmantot, kad pieskaraties pieejamības pogai."</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Izvēlieties pakalpojumu, ko izmantot ar pieejamības žestu (vilkšana ar diviem pirkstiem augšup no ekrāna apakšdaļas)."</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Izvēlieties pakalpojumu, ko izmantot ar pieejamības žestu (vilkšana ar trīs pirkstiem augšup no ekrāna apakšdaļas)."</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Lai pārslēgtu pakalpojumus, pieskarieties pieejamības pogai un turiet to."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Lai pārslēgtu pakalpojumus, velciet ar diviem pirkstiem augšup un turiet."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Lai pārslēgtu pakalpojumus, velciet ar trīs pirkstiem augšup un turiet."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Palielinājums"</string>
     <string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Notiek pāriešana uz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-mcc313-mnc100/config.xml b/core/res/res/values-mcc313-mnc100/config.xml
new file mode 100644
index 0000000..ccd03f1
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100/config.xml
@@ -0,0 +1,45 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string-array translatable="false" name="config_twoDigitNumberPattern">
+        <item>"0"</item>
+        <item>"00"</item>
+        <item>"*0"</item>
+        <item>"*1"</item>
+        <item>"*2"</item>
+        <item>"*3"</item>
+        <item>"*4"</item>
+        <item>"*5"</item>
+        <item>"*6"</item>
+        <item>"*7"</item>
+        <item>"*8"</item>
+        <item>"*9"</item>
+        <item>"#0"</item>
+        <item>"#1"</item>
+        <item>"#2"</item>
+        <item>"#3"</item>
+        <item>"#4"</item>
+        <item>"#5"</item>
+        <item>"#6"</item>
+        <item>"#7"</item>
+        <item>"#8"</item>
+        <item>"#9"</item>
+    </string-array>
+</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 0d085c8..19c1c85 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Повици преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Повикување преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Повик преку WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Повик преку WLAN на <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Режим на работа во автомобил"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Статус на сметка"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Пораки за програмери"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Важни пораки за програмери"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ажурирања"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Статус на мрежа"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Известувања на мрежа"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Икона за отпечатоци"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"управува со хардвер за „Отклучување со лик“"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Дозволува апликац. да повика начини за додавање и бришење шаблони на лице за користење."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"користи хардвер за „Отклучување со лик“"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Дозволува апликацијата да користи хардвер за „Отклучување со лик“ за проверка"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Отклучување со лик"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Повторно регистрирајте го ликот"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"За да се подобри препознавањето, повторно регистрирајте го ликот"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Не се сними прецизна слика. Обидете се повторно."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Поместете го телефонот налево."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Поместете го телефонот надесно."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Погледнете подиректно во уредот."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Не ви се гледа ликот. Гледајте во телефонот."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Наместете го лицето директно пред телефонот."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Премногу движење. Држете го телефонот стабилно."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Повторно регистрирајте го лицето."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ликот не се препознава. Обидете се повторно."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Не вртете ја главата толку многу."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Не вртете ја главата толку многу."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Отстранете ги работите што ви го покриваат лицето."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Исчистете го сензорот на горниот врв од екранот."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Исчистете го врвот на екранот, вклучувајќи ја црната лента"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Ликот не може да се потврди. Хардвер - недостапен."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
-    <string name="face_error_no_space" msgid="2712120617457553825">"Не зачувува податоци за нов лик. Прво избришете стар."</string>
+    <string name="face_error_timeout" msgid="981512090365729465">"Пробајте „Отклучување со лик“ повторно."</string>
+    <string name="face_error_no_space" msgid="2712120617457553825">"Не се зачуваа податоците за нов лик. Избришете го стариот."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Операцијата со лице се откажа."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"„Отклучувањето со лик“ е откажано од корисникот."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Премногу обиди. Обидете се повторно подоцна."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Премногу обиди. „Отклучувањето со лик“ е оневозможено."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Ликот не може да се потврди. Обидете се повторно."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Не сте поставиле „Отклучување со лик“."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"„Отклучувањето со лик“ не е поддржано на уредов."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Отвори со"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Отвори со %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Отвори"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Дајте пристап да се отвораат линкови на <xliff:g id="HOST">%1$s</xliff:g> со"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Дајте пристап да се отвораат линкови на <xliff:g id="HOST">%1$s</xliff:g> со <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Отворајте врски на <xliff:g id="HOST">%1$s</xliff:g> со"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Отворајте врски со"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Отворајте врски со <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Отворајте врски на <xliff:g id="HOST">%1$s</xliff:g> со <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Дозволи пристап"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Измени со"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Измени со %1$s"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Извршете фабричко ресетирање за да го оневозможите режимот на рамка за тестирање."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистотија во USB-портата"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-портата е автоматски оневозможена. Допрете за да дознаете повеќе."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Во ред е да се користи USB-порта"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефонот веќе не открива течност или нечистотија."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Се зема извештајот за грешки…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели извештајот за грешки?"</string>
@@ -1595,6 +1589,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Стартувај прелистувач?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Прифати повик?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Секогаш"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Поставете на секогаш отворај"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Само еднаш"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Поставки"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s не поддржува работен профил"</string>
@@ -1624,8 +1619,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Прекривка #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="WIDTH">%2$d</xliff:g>х<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безбедно"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ова стартување активност во заднина од <xliff:g id="PACKAGENAME">%1$s</xliff:g> ќе се блокира во идните верзии на Q. Видете g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Блокирано е стартување активност во заднина од <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Видете g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Заборавив шема"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Погрешна шема"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Погрешна лозинка"</string>
@@ -1679,8 +1672,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Кратенката за пристапност ја вклучи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Кратенката за пристапност ја исклучи <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од три секунди за да користите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изберете функција за користење кога ќе го допрете копчето за „Пристапност“."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"За променување функции, допрете го и задржете го копчето за „Пристапност“."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Изберете ја услугата што ќе ја користите кога ќе го допрете копчето за пристапност:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Изберете ја услугата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со два прста):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Изберете ја услугата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со три прста):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"За да се префрлате помеѓу услуги, допрете и задржете го копчето за пристапност."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"За да се префрлате помеѓу услуги, лизгајте нагоре со два прста и задржете."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"За да се префрлате помеѓу услуги, лизгајте нагоре со три прста и задржете."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Зголемување"</string>
     <string name="user_switched" msgid="3768006783166984410">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Се префрла на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index c5d8d4e..b2e9b64 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ കോളിംഗ്"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ കോളിംഗ്"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN കോൾ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN കോൾ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"കാർ മോഡ്"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"അക്കൗണ്ട് നില"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ഡെവലപ്പർ സന്ദേശങ്ങൾ"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"പ്രധാനപ്പെട്ട ഡെവലപ്പർ സന്ദേശങ്ങൾ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"അപ്‌ഡേറ്റുകൾ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"നെറ്റ്‌വർക്ക് നില"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"നെറ്റ്‌വർക്ക് അലേർട്ടുകൾ"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"വിരലടയാള ഐക്കൺ"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഹാർഡ്‌വെയർ മാനേജ് ചെയ്യുക"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ഉപയോഗിക്കാനായി, മുഖത്തിന്റെ ടെംപ്ലേറ്റുകൾ ചേർക്കാനും ഇല്ലാതാക്കാനുമുള്ള രീതികൾ അഭ്യർത്ഥിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഹാർഡ്‌വെയർ ഉപയോഗിക്കുക"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"പരിശോധിച്ചുറപ്പിക്കാൻ മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഹാർഡ്‌വെയർ ഉപയോഗിക്കാൻ അനുവദിക്കുന്നു"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക്"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"നിങ്ങളുടെ മുഖം വീണ്ടും എൻറോൾ ചെയ്യൂ"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"തിരിച്ചറിയൽ മെച്ചപ്പെടുത്താൻ, നിങ്ങളുടെ മുഖം ദയവായി വീണ്ടും എൻറോൾ ചെയ്യൂ"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"കൃത്യ മുഖ ഡാറ്റ എടുക്കാനായില്ല. വീണ്ടും ശ്രമിക്കൂ."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ഫോൺ ഇടത്തോട്ട് നീക്കുക."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ഫോൺ വലത്തോട്ട് നീക്കുക."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"നിങ്ങളുടെ ഉപകരണത്തിന് നേരെ കൂടുതൽ നന്നായി നോക്കുക."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"നിങ്ങളുടെ മുഖം കാണാനാവുന്നില്ല. ഫോണിലേക്ക് നോക്കൂ."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"നിങ്ങളുടെ മുഖം ക്യാമറയ്‌ക്ക് നേരെയാക്കുക."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"വളരെയധികം ചലനം. ഫോൺ അനക്കാതെ നേരെ പിടിക്കുക."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"നിങ്ങളുടെ മുഖം വീണ്ടും എൻറോൾ ചെയ്യുക."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"ഇനി മുഖം തിരിച്ചറിയാനാവില്ല. വീണ്ടും ശ്രമിക്കൂ."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"നിങ്ങളുടെ തല ഇത്ര തിരിക്കേണ്ട."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"നിങ്ങളുടെ തല ഇത്ര തിരിക്കേണ്ട."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"നിങ്ങളുടെ മുഖം മറയ്‌ക്കുന്നത് എല്ലാം നീക്കം ചെയ്യൂ."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"സ്‌ക്രീനിന്റെ മുകളിലെ സെൻസർ വൃത്തിയാക്കുക."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"കറുപ്പ് ബാർ ഉൾപ്പെടെ നിങ്ങളുടെ സ്ക്രീനിന്റെ മുകൾഭാഗം വൃത്തിയാക്കുക"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"മുഖം പരിശോധിക്കാൻ കഴിയില്ല. ഹാർഡ്‌വെയർ ലഭ്യമല്ല."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് വീണ്ടും പരീക്ഷിക്കൂ"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"പുതിയ മുഖ ഡാറ്റ സംഭരിക്കാനാകില്ല. ആദ്യം പഴയത് ഇല്ലാതാക്കുക."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"മുഖത്തിന്റെ പ്രവർത്തനം റദ്ദാക്കി."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ഉപയോക്താവ് മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് റദ്ദാക്കി"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"നിരവധി തവണ ശ്രമിച്ചു. പിന്നീട് വീണ്ടും ശ്രമിക്കുക."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"വളരെയധികം ശ്രമങ്ങൾ. മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"മുഖം പരിശോധിക്കാൻ കഴിയില്ല. വീണ്ടും ശ്രമിക്കൂ."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് സജ്ജീകരിച്ചില്ല."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"മുഖം തിരിച്ചറിഞ്ഞുള്ള അൺലോക്ക് ഈ ഉപകരണം പിന്തുണയ്ക്കുന്നില്ല."</string>
     <string name="face_name_template" msgid="7004562145809595384">"മുഖം <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"ഇത് ഉപയോഗിച്ച് തുറക്കുക"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ഉപയോഗിച്ച് തുറക്കുക"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"തുറക്കുക"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ഇനിപ്പറയുന്നത് ഉപയോഗിച്ച്, <xliff:g id="HOST">%1$s</xliff:g> ലിങ്കുകൾ തുറക്കാൻ ആക്‌സ‌സ് നൽകുക"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> ഉപയോഗിച്ച്, <xliff:g id="HOST">%1$s</xliff:g> ലിങ്കുകൾ തുറക്കാൻ ആക്‌സ‌സ് നൽകുക"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"ഇനിപ്പറയുന്നത് ഉപയോഗിച്ച് <xliff:g id="HOST">%1$s</xliff:g> ലിങ്കുകൾ തുറക്കുക"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"ഇനിപ്പറയുന്നത് ഉപയോഗിച്ച് ലിങ്കുകൾ തുറക്കുക"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> ഉപയോഗിച്ച് ലിങ്കുകൾ തുറക്കുക"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> ലിങ്കുകൾ <xliff:g id="APPLICATION">%2$s</xliff:g> ഉപയോഗിച്ച് തുറക്കുക"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ആക്‌സസ് നൽകുക"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ഇത് ഉപയോഗിച്ച് എഡിറ്റുചെയ്യുക"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ഉപയോഗിച്ച് എഡിറ്റുചെയ്യുക"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"പരിശോധനാ സംവിധാന മോഡ് പ്രവർത്തനരഹിതമാക്കാൻ ഫാക്‌ടറി പുനഃക്രമീകരണം നിർവഹിക്കുക."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB പോർട്ടിൽ ദ്രാവകമോ പൊടിയോ കണ്ടെത്തി"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB പോർട്ടർ സ്വയമേവ പ്രവർത്തനരഹിതമായി. കൂടുതലറിയാൻ ടാപ്പ് ചെയ്യുക."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ഇനി USB പോർട്ട് ഉപയോഗിക്കാം"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"നിലവിൽ ദ്രാവകമോ പൊടിയോ ഉള്ളതായി ഫോൺ കണ്ടെത്തുന്നില്ല."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ബഗ് റിപ്പോർട്ട് പങ്കിടണോ?"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ബ്രൗസർ സമാരംഭിക്കണോ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"കോൾ സ്വീകരിക്കണോ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"എല്ലായ്പ്പോഴും"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"\'എല്ലായ്‌പ്പോഴും തുറക്കുക\' എന്നതിലേക്കാക്കുക"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"ഒരിക്കൽ മാത്രം"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ക്രമീകരണം"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s, ഔദ്യോഗിക പ്രൊഫൈലിനെ പിന്തുണയ്‌ക്കുന്നില്ല"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ഓവർലേ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", സുരക്ഷിതമാക്കുക"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> എന്നതിൽ നിന്ന് ഈ പശ്ചാത്തല ആക്റ്റിവിറ്റി ആരംഭിക്കുന്നത് ഭാവിയിലെ Q ബിൽഡുകളിൽ ബ്ലോക്ക് ചെയ്യപ്പെടും. g.co/dev/bgblock കാണുക."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> എന്നതിൽ നിന്ന് പശ്ചാത്തല ആക്റ്റിവിറ്റി ആരംഭിക്കുന്നത് ബ്ലോക്ക് ചെയ്‌തു. g.co/dev/bgblock കാണുക."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"പാറ്റേൺ മറന്നു"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"പാറ്റേൺ തെറ്റാണ്"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"പാസ്‌വേഡ് തെറ്റാണ്"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ഉപയോഗസഹായിക്കുള്ള കുറുക്കുവഴി <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓൺ ചെയ്തിരിക്കുന്നു"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ഉപയോഗസഹായിക്കുള്ള കുറുക്കുവഴി <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫ് ചെയ്തിരിക്കുന്നു"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഉപയോഗിക്കാൻ, രണ്ട് വോളിയം കീകളും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഉപയോഗിക്കുന്നതിന് ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ഫീച്ചറുകൾ മാറ്റുന്നതിന് ഉപയോഗസഹായി ബട്ടൺ സ്‌പർശിച്ചുപിടിക്കുക."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു സർവീസ് തിരഞ്ഞെടുക്കുക (രണ്ട് വിരലുകളുപയോഗിച്ച് സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു സർവീസ് തിരഞ്ഞെടുക്കുക (മൂന്ന് വിരലുകളുപയോഗിച്ച് സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"സർവീസുകൾക്കിടയിൽ മാറാൻ, ഉപയോഗസഹായി ബട്ടൺ സ്‌പർശിച്ചുപിടിക്കുക."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"സർവീസുകൾക്കിടയിൽ മാറാൻ, രണ്ട് വിരലുകളുപയോഗിച്ച് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"സർവീസുകൾക്കിടയിൽ മാറാൻ, മൂന്ന് വിരലുകളുപയോഗിച്ച് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"മാഗ്നിഫിക്കേഷൻ"</string>
     <string name="user_switched" msgid="3768006783166984410">"നിലവിലെ ഉപയോക്താവ് <xliff:g id="NAME">%1$s</xliff:g> ആണ്."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിലേക്ക് മാറുന്നു…"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 13417f2..a229713 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi дуудлага"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi Дуудлага"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN дуудлага"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN дуудлага"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Машины горим"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Бүртгэлийн төлөв"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Хөгжүүлэгчийн мессеж"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Хөгжүүлэгчийн чухал зурвас"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Шинэчлэлтүүд"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Сүлжээний төлөв"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Сүлжээний сануулга"</string>
@@ -266,7 +268,7 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Жижиглэнгийн жишээ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB холболт"</string>
     <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Апп ажиллаж байна"</string>
-    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апп батерей ашиглаж байна"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апп батарей ашиглаж байна"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> батерей ашиглаж байна"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> апп батерей ашиглаж байна"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батерей, дата ашиглалтын талаар дэлгэрэнгүйг харахын тулд товшино уу"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Хурууны хээний дүрс"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"царайгаар тайлах техник хангамжийг удирдах"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Аппад царайны загварыг ашиглахын тулд нэмэх эсвэл устгах аргыг идэвхжүүлэхийг зөвшөөрдөг."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"царайгаар тайлах техник хангамж ашиглах"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Аппад царайгаар тайлах техник хангамжийг баталгаажуулалтад ашиглахыг зөвшөөрдөг"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Царайгаар тайлах"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Царайгаа дахин бүртгүүлнэ үү"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Танилтыг сайжруулахын тулд царайгаа дахин бүртгүүлнэ үү"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Царайн өгөгдлийг зөв авч чадсангүй. Дахин оролдоно уу."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Утсаа зүүн тийш болгоно уу."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Утсаа баруун тийш болгоно уу."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Төхөөрөмж рүүгээ аль болох эгц харна уу."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Таны царайг харахгүй байна. Утас руу харна уу."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Царайгаа утасны урд эгц байрлуулна уу"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Хэт их хөдөлгөөнтэй байна. Утсаа хөдөлгөөнгүй барина уу."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Нүүрээ дахин бүртгүүлнэ үү."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Царайг таних боломжгүй боллоо. Дахин оролдоно уу."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Толгойгоо арай багаар эргүүлнэ үү."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Толгойгоо арай багаар эргүүлнэ үү."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Таны нүүрийг далдалж буй аливаа зүйлийг хасна уу."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Дэлгэцийн дээд ирмэгт байрлах мэдрэгчийг цэвэрлэнэ үү."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Хар хэсэг зэрэг дэлгэцийнхээ дээд хэсгийг цэвэрлэнэ үү"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Царайг бататгаж чадсангүй. Техник хангамж боломжгүй байна."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Царайгаар тайлахыг дахин оролдоно уу."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Царайн шинэ өгөгдлийг хадгалж чадсангүй. Эхлээд хуучин өгөгдлийг устгана уу."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Царайны үйл ажиллагааг цуцаллаа."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Хэрэглэгч царайгаар тайлахыг цуцалсан."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Хэт олон удаа оролдлоо. Дараа дахин оролдоно уу."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Хэтэрхий олон удаа оролдлоо. Царайгаар тайлахыг идэвхгүй болголоо."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Царайг бататгаж чадсангүй. Дахин оролдоно уу."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Та царайгаар тайлахыг тохируулаагүй байна."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Царайгаар тайлахыг энэ төхөөрөмж дээр дэмждэггүй."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Царай <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Түгжээгүй хэсгийг өргөсгөх."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Тайлах гулсуулалт."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Тайлах хээ."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Нүүрээр тайлах"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Царайгаар тайлах"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Тайлах пин."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"Sim-н пин кодыг тайлна уу."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"Sim-н Puk кодыг тайлна уу."</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Нээх"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ашиглан нээх"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Нээх"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"<xliff:g id="HOST">%1$s</xliff:g>-н холбоосыг дараахаар нээх хандалт өгөх"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="HOST">%1$s</xliff:g>-н холбоосыг <xliff:g id="APPLICATION">%2$s</xliff:g>-р нээх хандалт өгөх"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g>-н холбоосуудыг дараахаар нээх"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Холбоосуудыг дараахаар нээх"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Холбоосуудыг <xliff:g id="APPLICATION">%1$s</xliff:g>-р нээх"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g>-н холбоосуудыг <xliff:g id="APPLICATION">%2$s</xliff:g>-р нээх"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Хандалт өгөх"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Засварлах"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ашиглан засварлах"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Туршилтын цогц горимыг идэвхгүй болгохын тулд үйлдвэрийн төлөвт шинэчилнэ үү."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB порт дээрх шингэн зүйл эсвэл бохирдол"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB портыг автоматаар идэвхгүй болгосон байна. Дэлгэрэнгүй мэдээлэл авахын тулд товшино уу."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB портыг ашиглахад зүгээр"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Утас шингэн зүйл эсвэл бохирдлыг илрүүлсэнгүй."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Алдааны тайланг авч байна..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Алдааны тайланг хуваалцах уу?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Хөтөч ажиллуулах уу?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Дуудлагыг зөвшөөрөх үү?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Байнга"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Тогтмол нээлттэй гэж тохируулах"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Нэг удаа"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Тохиргоо"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ажлын профайлыг дэмждэггүй"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Давхарга #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", найдвартай"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-с эхлэх арын энэ үйл ажиллагааг цаашдын Q боловсруулагдсан программд хориглоно. Та g.co/dev/bgblock холбоосыг харна уу."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>-с эхлэх арын үйл ажиллагааг хориглосон. Та g.co/dev/bgblock холбоосыг харна уу."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Хээг мартсан"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Буруу хээ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Нууц үг буруу"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Хүртээмжийн товчлол <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаасан"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Хүртээмжийн товчлол <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраасан"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г ашиглахын тулд дууны түвшнийг ихэсгэх, багасгах түлхүүрийг 3 секундийн турш зэрэг дарна уу"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Хүртээмжийн товчлуурыг товших үедээ ашиглах онцлогийг сонгоно уу:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Онцлогийг өөрчлөхийн тулд Хүртээмжийн товчлуурыг дараад хүлээнэ үү."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Хандалтын товчлуурыг товшихдоо ашиглах үйлчилгээг сонгоно уу:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Хандалтын зангаатай ашиглах үйлчилгээг сонгоно уу (хоёр хуруугаараа дэлгэцийн доороос дээш шударна уу):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Хандалтын зангаатай ашиглах үйлчилгээг сонгоно уу (гурван хуруугаараа дэлгэцийн доороос дээш шударна уу):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Үйлчилгээнүүд хооронд сэлгэхийн тулд хандалтын товчлуурт хүрээд удаан дарна уу."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Үйлчилгээнүүд хооронд сэлгэхийн тулд хоёр хуруугаараа дээш шудраад удаан дарна уу."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Үйлчилгээнүүд хооронд сэлгэхийн тулд гурван хуруугаараа дээш шудраад удаан дарна уу."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Томруулах"</string>
     <string name="user_switched" msgid="3768006783166984410">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> руу сэлгэж байна…"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index f4ef749..a86caa5 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय कॉलिंग"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय कॉलिंग"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कॉल"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कॉल"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय"</string>
@@ -218,7 +219,7 @@
     <string name="reboot_safemode_title" msgid="7054509914500140361">"सुरक्षित मोडमध्ये रीबूट करा"</string>
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"तुम्ही सुरक्षित मोडमध्ये रीबूट करू इच्छिता? हे तुम्ही इंस्टॉल केलेले सर्व तृतीय पक्ष अॅप्लिकेशन अक्षम करेल. तुम्ही पुन्हा रीबूट करता तेव्हा ते पुनर्संचयित केले जातील."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"अलीकडील"</string>
-    <string name="no_recent_tasks" msgid="8794906658732193473">"अलीकडील कोणतेही अॅप्स नाहीत."</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"अलीकडील कोणतेही अ‍ॅप्स नाहीत."</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"टॅबलेट पर्याय"</string>
     <string name="global_actions" product="tv" msgid="7240386462508182976">"टीव्ही पर्याय"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"फोन पर्याय"</string>
@@ -255,7 +256,8 @@
     <string name="notification_channel_security" msgid="7345516133431326347">"सुरक्षितता"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"कार मोड"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"खाते स्थिती"</string>
-    <string name="notification_channel_developer" msgid="7579606426860206060">"विकसक मेसेज"</string>
+    <string name="notification_channel_developer" msgid="7579606426860206060">"डेव्हलपर मेसेज"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"महत्त्वाचा डेव्हलपर मेसेज"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"अपडेट"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"नेटवर्क स्थिती"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"नेटवर्क सूचना"</string>
@@ -266,7 +268,7 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"रीटेल डेमो"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्‍शन"</string>
     <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"APP चालत आहे"</string>
-    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"अॅप्‍समुळे बॅटरी संपत आहे"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"बॅटरी लवकर संपवणारी अॅप्‍स"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> बॅटरी वापरत आहे"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> अॅप्‍स बॅटरी वापरत आहेत"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बॅटरी आणि डेटा वापराच्‍या तपशीलांसाठी टॅप करा"</string>
@@ -277,21 +279,21 @@
     <string name="managed_profile_label" msgid="8947929265267690522">"कार्य प्रोफाइलवर स्विच करा"</string>
     <string name="permgrouplab_contacts" msgid="3657758145679177612">"संपर्क"</string>
     <string name="permgroupdesc_contacts" msgid="6951499528303668046">"आपल्या संपर्कांवर प्रवेश"</string>
-    <string name="permgrouprequest_contacts" msgid="6032805601881764300">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमचे संपर्क अॅक्सेस करू द्यायचे?"</string>
+    <string name="permgrouprequest_contacts" msgid="6032805601881764300">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमचे संपर्क अ‍ॅक्सेस करू द्यायचे?"</string>
     <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="1347189607421252902">"तुम्ही अ‍ॅप वापरत असताना अ‍ॅपला फक्त स्थानाचा अॅक्सेस असेल"</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="1347189607421252902">"तुम्ही अ‍ॅप वापरत असताना अ‍ॅपला फक्त स्थानाचा अ‍ॅक्सेस असेल"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला &lt;b&gt;प्रत्येक वेळी&lt;/b&gt; या डिव्हाइसच्या स्थानाचा अ‍ॅक्सेस द्यायचा?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"अ‍ॅप सध्या फक्त तुम्ही अ‍ॅप वापरत असतानाच स्थान अ‍ॅक्सेस करू शकते"</string>
     <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>
+    <string name="permgrouprequest_calendar" msgid="289900767793189421">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमचे कॅलेंडर अ‍ॅक्सेस करू द्यायचे?"</string>
     <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS मेसेज पाठवणे आणि पाहणे हे"</string>
     <string name="permgrouprequest_sms" msgid="7168124215838204719">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला एसएमएस पाठवू आणि पाहू द्यायचे?"</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"स्टोरेज"</string>
-    <string name="permgroupdesc_storage" msgid="637758554581589203">"तुमच्या डिव्हाइस वरील फोटो, मीडिया आणि फायलींमध्‍ये अॅक्सेस"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"तुमच्या डिव्हाइस वरील फोटो, मीडिया आणि फायलींमध्‍ये अ‍ॅक्सेस"</string>
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमच्या डिव्हाइसवरील फोटो, मीडिया आणि फायली अ‍ॅक्सेस करू द्यायचे?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"मायक्रोफोन"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ऑडिओ रेकॉर्ड"</string>
@@ -304,13 +306,13 @@
     <string name="permgrouprequest_camera" msgid="1299833592069671756">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला फोटो घेऊ आणि व्हिडिओ रेकॉर्ड करू द्यायचे?"</string>
     <string name="permgrouplab_calllog" msgid="8798646184930388160">"कॉल लॉग"</string>
     <string name="permgroupdesc_calllog" msgid="3006237336748283775">"फोन कॉल लॉग वाचा आणि लिहा"</string>
-    <string name="permgrouprequest_calllog" msgid="8487355309583773267">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमचे फोन कॉल लॉग अॅक्सेस करण्याची अनुमती द्यायची का?"</string>
+    <string name="permgrouprequest_calllog" msgid="8487355309583773267">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला तुमचे फोन कॉल लॉग अ‍ॅक्सेस करण्याची अनुमती द्यायची का?"</string>
     <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>
     <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="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="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडोमधील आशय पुन्हा मिळवा"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"तुम्ही वापरत असलेल्‍या विंडोमधील आशय तपासा."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श करून अन्वेषण चालू करा"</string>
@@ -353,15 +355,15 @@
     <string name="permdesc_readSms" product="default" msgid="6826832415656437652">"हा अ‍ॅप तुमच्या फोनवर स्टोअर केलेले सर्व SMS (मजकूर) मेसेज वाचू शकतो."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"मजकूर मेसेज मिळवा (WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP मेसेज प्राप्त करण्यास आणि त्यावर प्रक्रिया करण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी तुम्हाला पाठविलेले मेसेज तुम्हाला न दर्शविता त्यांचे परीक्षण करण्याची आणि ते हटविण्याची क्षमता समाविष्ट करते."</string>
-    <string name="permlab_getTasks" msgid="6466095396623933906">"चालणारे अॅप्स पुनर्प्राप्त करा"</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"चालणारे अ‍ॅप्स पुनर्प्राप्त करा"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"सध्या आणि अलीकडे चालणार्‍या कार्यांविषयी माहिती पुनर्प्राप्त करण्यासाठी अ‍ॅप ला अनुमती देते. हे डिव्हाइसवर कोणते अ‍ॅप्लिकेशन वापरले जात आहेत त्याविषयी माहिती शोधण्यासाठी अ‍ॅप ला अनुमती देऊ शकतात."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"प्रोफाईल आणि डिव्हाइस मालक व्यवस्थापित करा"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"प्रोफाईल मालक आणि डिव्हाइस मालक सेट करण्याची अॅप्सना अनुमती द्या."</string>
-    <string name="permlab_reorderTasks" msgid="2018575526934422779">"चालणारे अॅप्स पुनर्क्रमित करा"</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"चालणारे अ‍ॅप्स पुनर्क्रमित करा"</string>
     <string name="permdesc_reorderTasks" msgid="7734217754877439351">"समोर आणि पार्श्वभूमीवर कार्ये हलविण्यासाठी अ‍ॅप ला अनुमती देते. अ‍ॅप हे आपल्या इनपुटशिवाय करू शकतो."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"कार मोड सुरू करा"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"कार मोड सक्षम करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
-    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"अन्य अॅप्स बंद करा"</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"अन्य अ‍ॅप्स बंद करा"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"अन्य अ‍ॅप्सच्या पार्श्वभूमी प्रक्रिया समाप्त करण्यासाठी अ‍ॅप ला अनुमती देते. यामुळे अन्य अ‍ॅप्स चालणे थांबू शकते."</string>
     <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"हा अ‍ॅप इतर अ‍ॅप्सच्या शीर्षस्थानी दिसू शकतो."</string>
     <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"हे अ‍ॅप इतर अ‍ॅप्सच्या शीर्षस्थानी किंवा स्क्रीनच्या इतर भागांवर दिसू शकतो. हे सामान्य अ‍ॅप वापरात व्यत्यय आणू शकते किंवा इतर अ‍ॅप्सची डिस्प्ले पद्धत बदलू शकते."</string>
@@ -389,7 +391,7 @@
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"रोचक प्रसारणे पाठविण्यासाठी अ‍ॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो फोनला धीमा किंवा अस्थिर करू शकतो."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"तुमचे संपर्क वाचा"</string>
     <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"तुम्ही कॉल केलेल्या, ईमेल केलेल्या किंवा विशिष्ट लोकांशी अन्य मार्गांनी संवाद प्रस्थापित केलेल्या लोकांच्या फ्रिक्वेन्सीसह, आपल्या टॅब्लेटवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी तुमचा संपर्क डेटा सेव्ह करण्याची अ‍ॅप्स ला अनुमती देते आणि दुर्भावनापूर्ण अ‍ॅप्स आपल्या माहितीशिवाय संपर्क डेटा शेअर करू शकतात."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"तुम्ही विशिष्ट लोकांना इतर मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संप्रेषित केलेल्या फ्रिक्वेन्सीसह, आपल्या टीव्हीवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अॅप्सला अनुमती देतात. ही परवागनी अॅप्सला तुमचा संपर्क डेटा सेव्ह करण्यासाठी अनुमती देते आणि दुर्भावनापूर्ण अॅप्स तुम्हाला न कळविता संपर्क डेटा शेअर करू शकतात."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"तुम्ही विशिष्ट लोकांना इतर मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संप्रेषित केलेल्या फ्रिक्वेन्सीसह, आपल्या टीव्हीवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अ‍ॅप्सला अनुमती देतात. ही परवागनी अ‍ॅप्सला तुमचा संपर्क डेटा सेव्ह करण्यासाठी अनुमती देते आणि दुर्भावनापूर्ण अ‍ॅप्स तुम्हाला न कळविता संपर्क डेटा शेअर करू शकतात."</string>
     <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"तुम्ही कॉल केलेल्या, ईमेल केलेल्या किंवा विशिष्ट लोकांशी अन्य मार्गांनी संवाद प्रस्थापित केलेल्या लोकांच्या फ्रिक्वेन्सीसह, आपल्या फोनवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा वाचण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी तुमचा संपर्क डेटा सेव्ह करण्याची अ‍ॅप्स ला अनुमती देते आणि दुर्भावनापूर्ण अ‍ॅप्स आपल्या माहितीशिवाय संपर्क डेटा शेअर करू शकतात."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"तुमचे संपर्क सुधारित करा"</string>
     <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"तुम्ही विशिष्ट संपर्कांशी अन्य मार्गांनी कॉल केलेल्या, ईमेल केलेल्या किंवा संवाद प्रस्थापित केलेल्या फ्रिक्वेन्सीसह, आपल्या टॅब्लेटवर स्टोअर केलेल्या आपल्या संपर्कांविषयीचा डेटा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. ही परवानगी संपर्क डेटा हटविण्यासाठी अ‍ॅप ला अनुमती देते."</string>
@@ -399,9 +401,9 @@
     <string name="permdesc_readCallLog" msgid="3204122446463552146">"हा अ‍ॅप तुमचा कॉल इतिहास वाचू शकता."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"कॉल लॉग लिहा"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टॅब्लेटचा कॉल लॉग सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टीव्हीचा कॉल लॉग सुधारित करण्यासाठी अॅपला अनुमती देते. दुर्भावनापूर्ण अॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या टीव्हीचा कॉल लॉग सुधारित करण्यासाठी अॅपला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"येणार्‍या आणि केल्या जाणार्‍या कॉलविषयीच्या डेटासह, आपल्या फोनचा कॉल लॉग सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स तुमचा कॉल लॉग मिटवण्यासाठी किंवा सुधारित करण्यासाठी याचा वापर करू शकतात."</string>
-    <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर सेंसर (हृदय गती मॉनिटरसारखे) अॅक्सेस करा"</string>
+    <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर सेंसर (हृदय गती मॉनिटरसारखे) अ‍ॅक्सेस करा"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"हृदय गती सारख्या, आपल्या शारीरिक स्थितीचे नियंत्रण करणार्‍या सेन्सरवरून डेटामध्ये प्रवेश करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_readCalendar" msgid="6716116972752441641">"कॅलेंडर इव्हेंट आणि तपशील वाचा"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4993979255403945892">"हा अ‍ॅप आपल्या टॅब्लेटवर स्टोअर केलेले सर्व कॅलेंडर इव्हेंट वाचू आणि शेअर करू शकतो किंवा तुमचा कॅलेंडर डेटा सेव्ह करू शकतो."</string>
@@ -411,7 +413,7 @@
     <string name="permdesc_writeCalendar" product="tablet" msgid="1675270619903625982">"हा अ‍ॅप आपल्या टॅब्लेटवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="9017809326268135866">"हा अ‍ॅप आपल्या टीव्हीवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="7592791790516943173">"हा अ‍ॅप आपल्या फोनवर कॅलेंडर इव्हेंट जोडू, काढू किंवा बदलू शकतो. हा अ‍ॅप कॅलेंडर मालकांकडून येत आहेत असे वाटणारे मेसेज पाठवू किंवा त्यांच्या मालकांना सूचित केल्याशिवाय इव्हेंट बदलू शकतो."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेश अॅक्सेस करा"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेश अ‍ॅक्सेस करा"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"अ‍ॅपला अतिरिक्त स्‍थान प्रदाता आदेशावर प्रवेश करण्‍याची अनुमती देते. हे कदाचित अ‍ॅपला GPS किंवा इतर स्‍थान स्रोत च्या ऑपरेशनमध्‍ये हस्तक्षेप करण्‍याची अनुमती देऊ शकते."</string>
     <string name="permlab_accessFineLocation" msgid="6265109654698562427">"फक्त फोरग्राउंडमध्ये अचूकपणे अ‍ॅक्सेस करा"</string>
     <string name="permdesc_accessFineLocation" msgid="3520508381065331098">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच तुमचे अचूक स्थान मिळवू शकते. या स्थान सेवा सुरू करणे आणि त्या वापरण्यासाठी अ‍ॅपसाठी तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे, यामुळे बॅटरी वापर वाढू शकतो."</string>
@@ -419,8 +421,8 @@
     <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अ‍ॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टॅबलेटवर उपलब्ध करणे आवश्यक आहे."</string>
     <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अ‍ॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टीव्हीवर उपलब्ध करणे आवश्यक आहे."</string>
     <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"हे अ‍ॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. ते वापरण्याकरता अ‍ॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे."</string>
-    <string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"बॅकग्राउंडमध्ये स्थान अॅक्सेस करू शकतो"</string>
-    <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"याला अंदाजे किंवा अचूक स्थान अॅक्सेस करण्यास अतिरिक्त मंजूरी दिल्यास, बॅकग्राउंडमध्ये चालतांना अ‍ॅप स्थान अॅक्सेस करू शकतो."</string>
+    <string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"बॅकग्राउंडमध्ये स्थान अ‍ॅक्सेस करू शकतो"</string>
+    <string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"याला अंदाजे किंवा अचूक स्थान अ‍ॅक्सेस करण्यास अतिरिक्त मंजूरी दिल्यास, बॅकग्राउंडमध्ये चालतांना अ‍ॅप स्थान अ‍ॅक्सेस करू शकतो."</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"आपल्या ऑडिओ सेटिंग्ज बदला"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"व्हॉल्यूम आणि आउटपुटसाठी कोणता स्पीकर वापरला आहे यासारख्या समग्र ऑडिओ सेटिंग्ज सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ऑडिओ रेकॉर्ड"</string>
@@ -435,10 +437,10 @@
     <string name="permdesc_vibrate" msgid="6284989245902300945">"अ‍ॅप ला व्हायब्रेटर नियंत्रित करण्यासाठी अनुमती देते."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"फोन नंबरवर प्रत्यक्ष कॉल करा"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"आपल्या हस्तक्षेपाशिवाय फोन नंबरवर कॉल करण्यासाठी अ‍ॅप ला अनुमती देते. यामुळे अनपेक्षित शुल्क किंवा कॉल लागू शकतात. लक्षात ठेवा की हे आणीबाणीच्या नंबरवर कॉल करण्यासाठी अ‍ॅप ला अनुमती देत नाही. दुर्भावनापूर्ण अ‍ॅप्स नी आपल्या पुष्टिकरणाशिवाय कॉल केल्यामुळे तुमचे पैसे खर्च होऊ शकतात."</string>
-    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS कॉल सेवा अॅक्सेस करा"</string>
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"IMS कॉल सेवा अ‍ॅक्सेस करा"</string>
     <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"आपल्‍या हस्तक्षेपाशिवाय अ‍ॅपला कॉल करण्‍यासाठी IMS सेवा वापरण्याची अनुमती देते."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"फोन स्थिती आणि ओळख वाचा"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"डिव्हाइस च्या फोन वैशिष्ट्यांवर अॅक्सेस करण्यास अॅपला अनुमती देते. ही परवानगी कॉल अॅक्टिव्हेट असला किंवा नसला तरीही, फोन नंबर आणि डिव्हाइस आयडी आणि कॉलद्वारे कनेक्ट केलेला रिमोट नंबर निर्धारित करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"डिव्हाइस च्या फोन वैशिष्ट्यांवर अ‍ॅक्सेस करण्यास अॅपला अनुमती देते. ही परवानगी कॉल अॅक्टिव्हेट असला किंवा नसला तरीही, फोन नंबर आणि डिव्हाइस आयडी आणि कॉलद्वारे कनेक्ट केलेला रिमोट नंबर निर्धारित करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_manageOwnCalls" msgid="1503034913274622244">"प्रणालीच्या माध्यमातून कॉल रूट करा"</string>
     <string name="permdesc_manageOwnCalls" msgid="6552974537554717418">"कॉल करण्याचा अनुभव सुधारण्यासाठी अॅपला त्याचे कॉल प्रणालीच्या माध्यमातून रूट करू देते."</string>
     <string name="permlab_callCompanionApp" msgid="3599252979411970473">"सिस्टम वापरून कॉल पाहा आणि नियंत्रण ठेवा."</string>
@@ -480,12 +482,12 @@
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"वाय-फाय कनेक्शन पहा"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"वाय-फाय सक्षम केले आहे किंवा नाही आणि कनेक्ट केलेल्या वाय-फाय डीव्हाइसचे नाव यासारख्या, वाय-फाय नेटवर्किंग विषयीची माहिती पाहण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"वाय-फाय वरून कनेक्ट करा आणि डिस्कनेक्ट करा"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"वाय-फाय अॅक्सेस बिंदूंवर कनेक्ट करण्यासाठी आणि त्यावरून डिस्कनेक्ट करण्यासाठी आणि वाय-फाय नेटवर्कसाठी डिव्हाइस कॉंफिगरेशनमध्ये बदल करण्यासाठी अॅपला अनुमती देते."</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"वाय-फाय अ‍ॅक्सेस बिंदूंवर कनेक्ट करण्यासाठी आणि त्यावरून डिस्कनेक्ट करण्यासाठी आणि वाय-फाय नेटवर्कसाठी डिव्हाइस कॉंफिगरेशनमध्ये बदल करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"वाय-फाय मल्‍टिकास्‍ट रिसेप्‍शनला अनुमती द्या"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"मल्टिकास्ट पत्ते वापरून फक्त तुमच्या टॅब्लेटवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डीव्हाइसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अ‍ॅप ला अनुमती देते. हे मल्टिकास्टखेरिज इतर मोडसाठी अधिक पॉवर वापरते."</string>
     <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"केवळ तुमचा टीव्ही न वापरता, एकाधिक पत्ते वापरून एका वाय-फाय नेटवकवरील सर्व डीव्हाइसवर पाठविलेली पॅकेट प्राप्त करण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"मल्टिकास्ट पत्ते वापरून फक्त तुमच्या फोनवर नाही, तर वाय-फाय नेटवर्कवरील सर्व डीव्हाइसवर पाठविलेले पॅकेट प्राप्त करण्यासाठी अ‍ॅप ला अनुमती देते. हे मल्टिकास्टखेरिज इतर मोडसाठी अधिक पॉवर वापरते."</string>
-    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ब्लूटूथ सेटिंग्ज अॅक्सेस करा"</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ब्लूटूथ सेटिंग्ज अ‍ॅक्सेस करा"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"स्थानिक ब्लूटूथ टॅबलेट कॉंफिगर करण्याकरिता आणि दूरस्थ डिव्हाइस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"स्थानिक ब्लूटूथ टीव्ही कॉंफिगर करण्यासाठी आणि दूरस्थ डीव्हाइससह शोधण्यासाठी आणि जोडण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"स्थानिक ब्लूटूथ फोन कॉंफिगर करण्याकरिता आणि दूरस्थ डिव्हाइस शोधण्यासाठी आणि त्यासह जोडण्यासाठी अ‍ॅप ला अनुमती देते."</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फिंगरप्रिंट आयकन"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"फेस अनलॉक हार्डवेअर व्यवस्थापित करा"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"अॅपला वापरासाठी चेहरा टेम्पलेट जोडण्याच्या आणि हटवण्याच्या पद्धती जारी करू देते."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"फेस अनलॉक हार्डवेअर वापरा"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"अ‍ॅपला ऑथेंटिकेशनसाठी फेस अनलॉक हार्डवेअर वापरण्याची अनुमती देते"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"फेस अनलॉक"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"तुमच्या चेहऱ्याची पुन्हा नोंदणी करा"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"ओळखण्यामध्ये सुधारणा करण्यासाठी, कृपया तुमच्या चेहऱ्याची पुन्हा नोंदणी करा"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"अचूक फेस डेटा कॅप्चर करता आला नाही. पुन्हा करा."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"फोन डावीकडे हलवा."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"फोन उजवीकडे हलवा."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"कृपया तुमच्या डिव्हाइसकडे थेट पाहा"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"तुमचा चेहरा दिसत नाही. फोनकडे पहा."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"तुमचा चेहरा थेट फोन समोर आणा."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"खूप हलत आहे. फोन स्थिर धरून ठेवा."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"कृपया तुमच्या चेहऱ्याची पुन्हा नोंदणी करा."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"चेहरा ओळखू शकत नाही. पुन्हा प्रयत्न करा."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"तुमचे डोके थोडे कमी फिरवा."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"तुमचे डोके थोडे कमी फिरवा."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"तुमचा चहेरा लपवणारे काहीही काढून टाका."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"स्क्रीनच्या वरील उजव्या कडेवरील सेन्सर साफ करा."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"ब्लॅक बार सह तुमच्या स्क्रीनची वरची बाजू साफ करा"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"चेहरा पडताळू शकत नाही. हार्डवेअर उपलब्ध नाही."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"फेस अनलॉकचा पुन्हा प्रयत्न करा."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"नवीन फेस डेटा स्टोअर करू शकत नाही. आधी जुना हटवा."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"चेहरा ऑपरेशन रद्द केले गेले."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"वापरकर्त्याने फेस अनलॉक रद्द केले आहे."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"खूप जास्त प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"बरेच प्रयत्न. फेस अनलॉक बंद केले आहे."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"चेहरा पडताळणी करू शकत नाही. पुन्हा प्रयत्न करा."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"तुम्ही फेस अनलॉक सेट केले नाही."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"या डिव्हाइसवर फेस अनलॉकला सपोर्ट नाही."</string>
     <string name="face_name_template" msgid="7004562145809595384">"चेहरा <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -630,7 +623,7 @@
     <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"नेटवर्क धोरण व्यवस्थापित करा"</string>
     <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"नेटवर्क धोरणे व्यवस्थापित करण्यासाठी आणि अ‍ॅप-विशिष्ट नियम परिभाषित करण्यासाठी अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"नेटवर्क वापर हिशोब सुधारित करा"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"अॅप्स वर नेटवर्क वापराचा हिशोब कसा घेतला जातो हे सुधारित करण्यासाठी अॅप्स ला अनुमती देते. सामान्य अॅप्सद्वारे वापरण्यासाठी नाही."</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"अ‍ॅप्स वर नेटवर्क वापराचा हिशोब कसा घेतला जातो हे सुधारित करण्यासाठी अ‍ॅप्स ला अनुमती देते. सामान्य अ‍ॅप्सद्वारे वापरण्यासाठी नाही."</string>
     <string name="permlab_accessNotifications" msgid="7673416487873432268">"प्रवेश सूचना"</string>
     <string name="permdesc_accessNotifications" msgid="458457742683431387">"अनुप्रयोगाला इतर अ‍ॅप्‍सद्वारे पोस्‍ट केलेल्‍यांसह पुनर्प्राप्त करण्‍याची, तपासण्‍याची आणि सूचना साफ करण्‍याची अनुमती देते."</string>
     <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"सूचना ऐकणार्‍या सेवेशी प्रतिबद्ध"</string>
@@ -645,17 +638,17 @@
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"अनु्प्रयोगाला नेटवर्क स्‍थितींवरील निरीक्षणे ऐकण्‍यासाठी अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
     <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डिव्हाइस कॅलिब्रेशन बदला"</string>
     <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. सामान्य अ‍ॅप्स साठी कधीही आवश्यक नसते."</string>
-    <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्रे अॅक्सेस करा"</string>
+    <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्रे अ‍ॅक्सेस करा"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यकता नसते."</string>
     <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android बीम स्थानांतरण स्थिती प्राप्त करा"</string>
     <string name="permdesc_handoverStatus" msgid="4788144087245714948">"वर्तमान Android बीम स्थानांतरणांविषयी माहिती प्राप्त करण्यासाठी या अनुप्रयोगास अनुमती देते"</string>
     <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"DRM प्रमाणपत्रे काढा"</string>
-    <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"DRM प्रमाणपत्रे काढण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यकता नसते."</string>
+    <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"DRM प्रमाणपत्रे काढण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अ‍ॅप्स साठी कधीही आवश्यकता नसते."</string>
     <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"एका वाहक मेसेजिंग सेवेसाठी प्रतिबद्ध"</string>
     <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"वाहक मेसेजिंग सेवेचा शीर्ष-स्तर इंटरफेस बाइंड करण्यासाठी होल्डरला अनुमती देतो. सामान्‍य अ‍ॅप्‍सकरिता हे कधीही आवश्‍यक नसते."</string>
     <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"वाहक सेवांवर प्रतिबद्ध करा"</string>
     <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"वाहक सेवांवर प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्य अॅप्ससाठी कधीही आवश्यकता नसावी."</string>
-    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"व्यत्यय आणू नका अॅक्सेस करा"</string>
+    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"व्यत्यय आणू नका अ‍ॅक्सेस करा"</string>
     <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"व्यत्यय आणू नका कॉन्फिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी अॅपला अनुमती देते."</string>
     <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"व्ह्यू परवानगी वापर सुरू करा"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"धारकास अ‍ॅपसाठी परवानगी वापरणे सुरू करण्याची अनुमती देते. सामान्य अ‍ॅप्ससाठी कधीही आवश्यकता नसते."</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"यासह उघडा"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s सह उघडा"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"उघडा"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"सह <xliff:g id="HOST">%1$s</xliff:g> लिंक उघडण्याचा अ‍ॅक्सेस द्या"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> सह <xliff:g id="HOST">%1$s</xliff:g> लिंक उघडण्याचा अ‍ॅक्सेस द्या"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"वापरून <xliff:g id="HOST">%1$s</xliff:g> लिंक उघडा"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"वापरून लिंक उघडा"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> वापरून लिंक उघडा"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> वापरून <xliff:g id="HOST">%1$s</xliff:g> लिंक उघडा"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"अ‍ॅक्सेस द्या"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"सह संपादित करा"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s सह संपादित करा"</string>
@@ -1161,7 +1156,7 @@
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"डाउनलोड केलेल्या सिस्टम सेटिंग्ज &gt; Apps &gt; मधील डीफॉल्ट साफ करा."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"क्रिया निवडा"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"USB डिव्हाइससाठी अ‍ॅप निवडा"</string>
-    <string name="noApplications" msgid="2991814273936504689">"कोणतेही अॅप्स ही क्रिया करू शकत नाहीत."</string>
+    <string name="noApplications" msgid="2991814273936504689">"कोणतेही अ‍ॅप्स ही क्रिया करू शकत नाहीत."</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> थांबला आहे"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> थांबली आहे"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> थांबतो"</string>
@@ -1206,9 +1201,9 @@
     <string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> श्रेणीसुधारित करत आहे…"</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"<xliff:g id="NUMBER_1">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_0">%1$d</xliff:g> अ‍ॅप ऑप्टिमाइझ करत आहे."</string>
     <string name="android_preparing_apk" msgid="8162599310274079154">"<xliff:g id="APPNAME">%1$s</xliff:g> तयार करत आहे."</string>
-    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"अॅप्स प्रारंभ करत आहे."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"अ‍ॅप्स प्रारंभ करत आहे."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"बूट समाप्त होत आहे."</string>
-    <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> चालत आहे"</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"रन होणारे <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="heavy_weight_notification_detail" msgid="2304833848484424985">"गेमवर परत जाण्यासाठी टॅप करा"</string>
     <string name="heavy_weight_switcher_title" msgid="387882830435195342">"गेम निवडा"</string>
     <string name="heavy_weight_switcher_text" msgid="4176781660362912010">"अधिक चांगल्या कामगिरीसाठी, एकावेळी यापैकी केवळ एक गेम चालू ठेवता येईल."</string>
@@ -1273,7 +1268,7 @@
     <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="5198100389964214865">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला इंटरनेट अॅक्सेस नाही"</string>
+    <string name="wifi_no_internet" msgid="5198100389964214865">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला इंटरनेट अ‍ॅक्सेस नाही"</string>
     <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"पर्यायांसाठी टॅप करा"</string>
     <string name="captive_portal_logged_in_detailed" msgid="8489345381637456021">"कनेक्ट केले"</string>
     <string name="network_partial_connectivity" msgid="7774883385494762741">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> ला मर्यादित कनेक्टिव्हिटी आहे"</string>
@@ -1282,7 +1277,7 @@
     <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"तुमचा हॉटस्पॉट बँड बदलला आहे."</string>
     <string name="wifi_softap_config_change_detailed" msgid="8022936822860678033">"हे डिव्हाइस तुमच्या फक्त ५GHz साठी प्राधान्याला सपोर्ट करत नाही. त्याऐवजी, हे डिव्हाइस ५GHz बँड उपलब्ध असताना वापरेल."</string>
     <string name="network_switch_metered" msgid="4671730921726992671">"<xliff:g id="NETWORK_TYPE">%1$s</xliff:g> वर स्विच केले"</string>
-    <string name="network_switch_metered_detail" msgid="775163331794506615">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेटचा अॅक्सेस नसताना डिव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरते. शुल्क लागू शकते."</string>
+    <string name="network_switch_metered_detail" msgid="775163331794506615">"<xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> कडे इंटरनेटचा अ‍ॅक्सेस नसताना डिव्हाइस <xliff:g id="NEW_NETWORK">%1$s</xliff:g> वापरते. शुल्क लागू शकते."</string>
     <string name="network_switch_metered_toast" msgid="5779283181685974304">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> वरून <xliff:g id="NEW_NETWORK">%2$s</xliff:g> वर स्विच केले"</string>
   <string-array name="network_switch_type_name">
     <item msgid="3979506840912951943">"मोबाइल डेटा"</item>
@@ -1325,14 +1320,14 @@
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"पाठवा"</string>
     <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"रद्द करा"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"माझी वड लक्षात ठेवा"</string>
-    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"तुम्ही हे नंतर सेटिंग्ज आणि अॅप्स मध्ये बदलू शकता"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"तुम्ही हे नंतर सेटिंग्ज आणि अ‍ॅप्स मध्ये बदलू शकता"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"नेहमी अनुमती द्या"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"कधीही अनुमती देऊ नका"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"सिम कार्ड काढले"</string>
     <string name="sim_removed_message" msgid="2333164559970958645">"तुम्ही एक वैध सिम कार्ड घालून प्रारंभ करेपर्यंत मोबाईल नेटवर्क अनुपलब्ध असेल."</string>
     <string name="sim_done_button" msgid="827949989369963775">"पूर्ण झाले"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"सिम कार्ड जोडले"</string>
-    <string name="sim_added_message" msgid="6599945301141050216">"मोबाईल नेटवर्कवर अॅक्सेस करण्यासाठी तुमचे डिव्हाइस रीस्टार्ट करा."</string>
+    <string name="sim_added_message" msgid="6599945301141050216">"मोबाईल नेटवर्कवर अ‍ॅक्सेस करण्यासाठी तुमचे डिव्हाइस रीस्टार्ट करा."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"रीस्टार्ट"</string>
     <string name="install_carrier_app_notification_title" msgid="9056007111024059888">"मोबाइल सेवा अ‍ॅक्टिव्हेट करा"</string>
     <string name="install_carrier_app_notification_text" msgid="3346681446158696001">"तुमचे नवीन सिम अ‍ॅक्टिव्हेट करण्यासाठी वाहकाचे अ‍ॅप डाउनलोड करा"</string>
@@ -1367,13 +1362,12 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"टेस्ट हार्नेस मोड बंद करण्यासाठी फॅक्टरी रीसेट करा."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्ट मध्ये ओलावा किंवा धूळ आहे"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट आपोआप बंद होईल. अधिक जाणून घेण्यासाठी टॅप करा."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB पोर्ट वापरण्यासाठी ठीक आहे"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"फोनला धूळ किंवा ओलावा आढळला नाही."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रीपोर्ट घेत आहे..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग अहवाल शेअर करायचा?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"बग रीपोर्ट शेअर करत आहे..."</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"आपल्या प्रशासकाने या डिव्हाइसचे समस्या निवारण करण्यात मदत करण्यासाठी दोष अहवालाची विनंती केली. अॅप्स आणि डेटा शेअर केले जाऊ शकतात."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="6029609949340992866">"आपल्या प्रशासकाने या डिव्हाइसचे समस्या निवारण करण्यात मदत करण्यासाठी दोष अहवालाची विनंती केली. अ‍ॅप्स आणि डेटा शेअर केले जाऊ शकतात."</string>
     <string name="share_remote_bugreport_action" msgid="6249476773913384948">"शेअर करा"</string>
     <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"नकार द्या"</string>
     <string name="select_input_method" msgid="4653387336791222978">"इनपुट पद्धत निवडा"</string>
@@ -1450,7 +1444,7 @@
     <string name="ime_action_default" msgid="2840921885558045721">"कार्यान्वित करा"</string>
     <string name="dial_number_using" msgid="5789176425167573586">\n"<xliff:g id="NUMBER">%s</xliff:g> वापरून नंबर डायल करा"</string>
     <string name="create_contact_using" msgid="4947405226788104538">\n"<xliff:g id="NUMBER">%s</xliff:g> वापरून संपर्क तयार करा"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"खालील एक किंवा अधिक अॅप्स आपल्या खात्यावर, आता आणि भविष्यात प्रवेश करण्याच्या परवानगीची विनंती करतात."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"खालील एक किंवा अधिक अ‍ॅप्स आपल्या खात्यावर, आता आणि भविष्यात प्रवेश करण्याच्या परवानगीची विनंती करतात."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"तुम्ही या विनंतीस अनुमती देऊ इच्छिता?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"प्रवेश विनंती"</string>
     <string name="allow" msgid="7225948811296386551">"अनुमती द्या"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउझर लाँच करायचा?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"कॉल स्वीकारायचा?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"नेहमी"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"नेहमी उघडावर सेट करा"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"फक्त एकदाच"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"सेटिंग्ज"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s कार्य प्रोफाईलचे समर्थन करीत नाही"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ओव्हरले #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", सुरक्षित"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> पासून सुरू होणारी ही बॅकग्राउंड अ‍ॅक्टिव्हिटी भविष्यातील Q बिल्डमध्ये ब्लॉक केली जाईल. g.co/dev/bgblock पाहा."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> वरून सुरू होणारी बॅकग्राउंड अ‍ॅक्टिव्हिटी ब्लॉक केली आहे. g.co/dev/bgblock पाहा."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"पॅटर्न विसरलात"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"चुकीचा पॅटर्न"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"चुकीचा पासवर्ड"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"प्रवेशयोग्यता शॉर्टकटने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> चालू केली"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"प्रवेशयोग्यता शॉर्टकटने <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केली"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> वापरण्यासाठी दोन्ही व्हॉल्युम की तीन सेकंद दाबा आणि धरून ठेवा"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"तुम्ही प्रवेशयोग्यता बटण दाबल्यावर वापरण्यासाठी वैशिष्ट्य निवडा:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"वैशिष्ट्ये बदलण्यासाठी, प्रवेशयोग्यता बटणाला स्पर्श करा आणि धरून ठेवा."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"तुम्ही अ‍ॅक्सेसिबिलिटी बटण दाबल्यावर वापरण्यासाठी वैशिष्ट्य निवडा:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"अ‍ॅक्सेसिबिलिटी जेश्चर ज्या सोबत वापराचे आहे अशी सेवा निवडा (स्क्रीनच्या खालच्या बाजूने दोन बोटांनी स्वाइप करा):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"अ‍ॅक्सेसिबिलिटी जेश्चर ज्या सोबत वापराचे आहे अशी सेवा निवडा (स्क्रीनच्या खालच्या बाजूने तीन बोटांनी स्वाइप करा):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"सेवांदरम्यान स्विच करण्यासाठी, अ‍ॅक्सेसिबिलिटी बटणाला स्पर्श करा आणि धरून ठेवा."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"सेवांदरम्यान स्विच करण्यासाठी, दोन बोटांनी वरच्या दिशेला स्वाइप करा आणि धरून ठेवा."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"सेवांदरम्यान स्विच करण्यासाठी, तीन बोटांनी वरच्या दिशेला स्वाइप करा आणि धरून ठेवा."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"मोठे करणे"</string>
     <string name="user_switched" msgid="3768006783166984410">"वर्तमान वापरकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> वर स्विच करत आहे…"</string>
@@ -1814,7 +1811,7 @@
     <string name="confirm_battery_saver" msgid="639106420541753635">"ओके"</string>
     <string name="battery_saver_description_with_learn_more" msgid="2108984221113106294">"बॅटरी सेव्‍हर हे वैशिष्ट्य बॅटरीचे आयुष्य वाढवण्‍यासाठी बॅकग्राउंड अ‍ॅक्टिव्हिटी, काही व्हिज्युअल इफेक्ट आणि इतर हाय-पॉवर वैशिष्ट्ये बंद किंवा मर्यादित करते. "<annotation id="url">"अधिक जाणून घ्या"</annotation></string>
     <string name="battery_saver_description" msgid="6413346684861241431">"बॅटरी लाइफ वाढवण्यासाठी बॅटरी सेव्हर बॅकग्राउंड अ‍ॅक्टिव्हिटी, काही व्हिज्युअल इफेक्ट आणि इतर हाय-पॉवर वैशिष्ट्ये बंद किंवा मर्यादित करतो."</string>
-    <string name="data_saver_description" msgid="6015391409098303235">"डेटा सर्व्हर डेटाचा वापर कमी करण्यात मदत करण्यासाठी काही अ‍ॅप्सना पार्श्वभूमीमध्ये डेटा पाठवण्यास किंवा  मिळवण्यास प्रतिबंध करतो. तुम्ही सध्या वापरत असलेले अ‍ॅप डेटा अॅक्सेस करू शकते, पण तसे खूप कमी वेळा होते. याचाच अर्थ असा की, तुम्ही इमेजवर टॅप करेपर्यंत त्या डिस्प्ले होणार नाहीत असा असू शकतो."</string>
+    <string name="data_saver_description" msgid="6015391409098303235">"डेटा सर्व्हर डेटाचा वापर कमी करण्यात मदत करण्यासाठी काही अ‍ॅप्सना पार्श्वभूमीमध्ये डेटा पाठवण्यास किंवा  मिळवण्यास प्रतिबंध करतो. तुम्ही सध्या वापरत असलेले अ‍ॅप डेटा अ‍ॅक्सेस करू शकते, पण तसे खूप कमी वेळा होते. याचाच अर्थ असा की, तुम्ही इमेजवर टॅप करेपर्यंत त्या डिस्प्ले होणार नाहीत असा असू शकतो."</string>
     <string name="data_saver_enable_title" msgid="4674073932722787417">"डेटा सेव्हर चालू करायचा?"</string>
     <string name="data_saver_enable_button" msgid="7147735965247211818">"चालू करा"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
@@ -1860,7 +1857,7 @@
     <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"आठवड्याची शेवटची रात्र"</string>
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"आठवड्याच्या शेवटी"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इव्‍हेंट"</string>
-    <string name="zen_mode_default_every_night_name" msgid="3012363838882944175">"निष्क्रिय आहे"</string>
+    <string name="zen_mode_default_every_night_name" msgid="3012363838882944175">"झोपताना"</string>
     <string name="muted_by" msgid="5942954724562097128">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> काही ध्‍वनी म्‍यूट करत आहे"</string>
     <string name="system_error_wipe_data" msgid="6608165524785354962">"आपल्‍या डिव्‍हाइसमध्‍ये अंतर्गत समस्‍या आहे आणि तुमचा फॅक्‍टरी डेटा रीसेट होईपर्यंत ती अस्‍थिर असू शकते."</string>
     <string name="system_error_manufacturer" msgid="8086872414744210668">"आपल्‍या डिव्‍हाइसमध्‍ये अंतर्गत समस्‍या आहे. तपशीलांसाठी आपल्‍या निर्मात्याशी संपर्क साधा."</string>
@@ -2038,5 +2035,5 @@
       <item quantity="one"><xliff:g id="FILE_NAME_0">%s</xliff:g> + <xliff:g id="COUNT_1">%d</xliff:g> फाइल</item>
     </plurals>
     <string name="chooser_no_direct_share_targets" msgid="997970693708458895">"थेट शेअर करणे उपलब्ध नाही"</string>
-    <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"अॅप्स सूची"</string>
+    <string name="chooser_all_apps_button_label" msgid="3631524352936289457">"अ‍ॅप्स सूची"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 2961f37..c18e078 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Panggilan Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Panggilan WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Panggilan WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Mod kereta"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Status akaun"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mesej pembangun"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mesej penting berkaitan pembangun"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Kemas kini"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status rangkaian"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Makluman rangkaian"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon cap jari"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"urus perkakasan wajah buka kunci"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Membenarkan apl menggunakan kaedah untuk menambahkan dan memadamkan templat wajah untuk digunakan."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"gunakan perkakasan wajah buka kunci"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Membenarkan apl menggunakan perkakasan wajah buka kunci untuk pengesahan"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Wajah buka kunci"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Daftarkan semula wajah anda"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Untuk meningkatkan pengecaman, sila daftarkan semula wajah anda"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Gagal menangkap data wajah dgn tepat. Cuba lagi."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Alihkan telefon ke kiri."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Alihkan telefon ke kanan."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Sila lihat terus pada peranti anda."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Gagal mengesan wajah anda. Lihat telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Letakkan wajah anda betul-betul di depan telefon."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Terlalu bnyk gerakan. Pegang telefon dgn stabil."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Sila daftarkan semula wajah anda."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Tidak lagi dapat mengecam wajah. Cuba lagi."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Pusingkan kepala anda kurang sedikit."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Pusingkan kepala anda kurang sedikit."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Alih keluar apa saja yang melindungi wajah anda."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Bersihkan penderia di tepi bahagian atas skrin."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Bersihkan bahagian atas skrin anda, termasuk bar hitam"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Tdk dpt sahkan wajah. Perkakasan tidak tersedia."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Cuba wajah buka kunci sekali lagi."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Tdk dpt menyimpan data wajah baharu. Padamkan yg lama dahulu."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Pengendalian wajah dibatalkan."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Wajah buka kunci dibatalkan oleh pengguna."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Terlalu banyak percubaan. Cuba sebentar lagi."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Terlalu banyak percubaan. Wajah buka kunci dilumpuhkan."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Tidak dapat mengesahkan wajah. Cuba lagi."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Anda belum menyediakan wajah buka kunci."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Wajah buka kunci tidak disokong pada peranti ini."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Wajah <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Buka dengan"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Buka dengan %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Buka"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Berikan akses untuk membuka pautan <xliff:g id="HOST">%1$s</xliff:g> dengan"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Berikan akses untuk membuka pautan <xliff:g id="HOST">%1$s</xliff:g> dengan <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Buka pautan <xliff:g id="HOST">%1$s</xliff:g> dengan"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Buka pautan dengan"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Buka pautan dengan <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Buka pautan <xliff:g id="HOST">%1$s</xliff:g> dengan <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Berikan akses"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edit dengan"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit dengan %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Laksanakan tetapan semula kilang untuk melumpuhkan Mod Abah-abah Ujian."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"OK untuk menggunakan port USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon tidak lagi mengesan cecair atau serpihan."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Mengambil laporan pepijat…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Kongsi laporan pepijat?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancarkan Penyemak Imbas?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Terima panggilan?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sentiasa"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Tetapkan agar sentiasa dibuka"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Hanya sekali"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Tetapan"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s tidak menyokong profil kerja"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Tindih #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", selamat"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Permulaan aktiviti latar belakang daripada <xliff:g id="PACKAGENAME">%1$s</xliff:g> ini akan disekat dalam binaan Q pada masa hadapan. Lihat g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Permulaan aktiviti latar belakang daripada <xliff:g id="PACKAGENAME">%1$s</xliff:g> disekat. Lihat g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Corak"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Corak Salah"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Kata Laluan Salah"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Pintasan kebolehaksesan menghidupkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Pintasan Kebolehaksesan mematikan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Tekan dan tahan kedua-dua kekunci kelantangan selama tiga saat untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pilih ciri yang hendak digunakan apabila anda mengetik butang Kebolehaksesan:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Untuk menukar ciri, sentuh &amp; tahan butang Kebolehaksesan."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Pilih perkhidmatan yang hendak digunakan apabila anda mengetik butang kebolehaksesan:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Pilih perkhidmatan untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan dua jari):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Pilih perkhidmatan untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan tiga jari):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Untuk beralih antara perkhidmatan, sentuh &amp; tahan butang kebolehaksesan."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Untuk beralih antara perkhidmatan, leret ke atas menggunakan dua jari dan tahan."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Untuk beralih antara perkhidmatan, leret ke atas menggunakan tiga jari dan tahan."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pembesaran"</string>
     <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Bertukar kepada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f59301a..55e7b01 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi ခေါ်ဆိုမှု"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>Wi-Fi ခေါ်ဆိုမှု"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ခေါ်ဆိုမှု"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ခေါ်ဆိုမှု"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -198,7 +199,7 @@
     <string name="silent_mode" msgid="7167703389802618663">"အသံတိတ်စနစ်"</string>
     <string name="turn_on_radio" msgid="3912793092339962371">"wirelessအားဖွင့်မည်"</string>
     <string name="turn_off_radio" msgid="8198784949987062346">"wirelessအားပိတ်မည်"</string>
-    <string name="screen_lock" msgid="799094655496098153">"ဖုန်းမျက်နှာပြင်အား သော့ချရန်"</string>
+    <string name="screen_lock" msgid="799094655496098153">"ဖန်သားပြင် လော့ခ်ချခြင်း"</string>
     <string name="power_off" msgid="4266614107412865048">"စက်ပိတ်ပါ"</string>
     <string name="silent_mode_silent" msgid="319298163018473078">"ဖုန်းမြည်သံပိတ်ထားသည်"</string>
     <string name="silent_mode_vibrate" msgid="7072043388581551395">"တုန်ခါခြင်း ဖုန်းမြည်သံ"</string>
@@ -222,7 +223,7 @@
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Tabletဆိုင်ရာရွေးချယ်မှုများ"</string>
     <string name="global_actions" product="tv" msgid="7240386462508182976">"တီဗွီ ရွေးချယ်စရာများ"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"ဖုန်းဆိုင်ရာရွေးချယ်မှုများ"</string>
-    <string name="global_action_lock" msgid="2844945191792119712">"ဖုန်းမျက်နှာပြင်အား သော့ချရန်"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"ဖန်သားပြင် လော့ခ်ချခြင်း"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"ပါဝါပိတ်ရန်"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"အရေးပေါ်"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"အမှားရှာဖွေပြင်ဆင်မှုမှတ်တမ်း"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"ကားမုဒ်"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"အကောင့် အခြေအနေ"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ဆော့ဖ်ဝဲအင်ဂျင်နီယာ မက်ဆေ့ဂျ်များ"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"အရေးကြီး ဆော့ဖ်ဝဲအင်ဂျင်နီယာ မက်ဆေ့ဂျ်များ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"အပ်ဒိတ်များ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ကွန်ရက် အခြေအနေ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ကွန်ရက် သတိပေးချက်များ"</string>
@@ -295,7 +297,7 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင့်ဖုန်းရှိ ဓာတ်ပုံများ၊ မီဒီယာနှင့် ဖိုင်များ ဝင်သုံးခွင့်ပေးလိုပါသလား။"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"မိုက်ခရိုဖုန်း"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"အသံဖမ်းခြင်း"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား အသံဖမ်းယူခွင့် ပေးလိုပါသလား။"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ကို အသံဖမ်းယူခွင့် ပေးလိုပါသလား။"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"ကိုယ်လက်လှုပ်ရှားမှု"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ဝင်ကြည့်ရန်"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ဝင်ကြည့်ခွင့် ပေးလိုပါသလား။"</string>
@@ -307,7 +309,7 @@
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင်၏ခေါ်ဆိုထားသော မှတ်တမ်းများကို သုံးခွင့်ပေးလိုပါသလား။"</string>
     <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>
+    <string name="permgrouprequest_phone" msgid="9166979577750581037">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ကို ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ခွင့်နှင့် စီမံခွင့်ပေးလိုပါသလား။"</string>
     <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>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ဖုန်းကို ဘယ်ဘက်သို့ရွှေ့ပါ။"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ဖုန်းကို ညာဘက်သို့ ရွှေ့ပါ။"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"သင့်စက်ပစ္စည်းကို တည့်တည့်ကြည့်ပါ။"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"သင့်မျက်နှာကို မမြင်ရပါ။ ဖုန်းကိုကြည့်ပါ။"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"မျက်နှာကို ဖုန်းရှေ့တွင် တည့်အောင်ထားပါ။"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"လှုပ်လွန်းသည်။ ဖုန်းကို ငြိမ်ငြိမ်ကိုင်ပါ။"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"သင့်မျက်နှာကို ပြန်စာရင်းသွင်းပါ။"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"မျက်နှာ မမှတ်သားနိုင်တော့ပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ခေါင်းကို သိပ်မလှည့်ပါနှင့်။"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"ခေါင်းကို သိပ်မလှည့်ပါနှင့်။"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"သင့်မျက်နှာကို ကွယ်နေသည့်အရာအားလုံး ဖယ်ပါ။"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"မျက်နှာပြင်ထိပ်ရှိ အာရုံခံဆင်ဆာကို သန့်ရှင်းပါ။"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"အနက်ရောင်ဘားအပါအဝင် ဖန်သားပြင်ထိပ်ကို သန့်ရှင်းရေး လုပ်ပါ"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"မျက်နှာကို အတည်ပြု၍ မရပါ။ ဟာ့ဒ်ဝဲ မရနိုင်ပါ။"</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"...ဖြင့် ဖွင့်မည်"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ဖြင့် ဖွင့်မည်"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"ဖွင့်ပါ"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"<xliff:g id="HOST">%1$s</xliff:g> လင့်ခ်များကို အ​ောက်ပါဖြင့် ဖွင့်ခွင့်ပေးပါ-"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="HOST">%1$s</xliff:g> လင့်ခ်များကို <xliff:g id="APPLICATION">%2$s</xliff:g> ဖြင့် ဖွင့်ခွင့်ပေးပါ"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> လင့်ခ်များကို အောက်ပါဖြင့် ဖွင့်ရန်−"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"လင့်ခ်များကို အောက်ပါဖြင့် ဖွင့်ရန်−"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"လင့်ခ်ကို <xliff:g id="APPLICATION">%1$s</xliff:g> ဖြင့် ဖွင့်ရန်"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> လင့်ခ်များကို <xliff:g id="APPLICATION">%2$s</xliff:g> ဖြင့် ဖွင့်ရန်"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ဖွင့်ခွင့်ပေးရန်"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"...နှင့် တည်းဖြတ်ရန်"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s နှင့် တည်းဖြတ်ရန်"</string>
@@ -1494,7 +1498,7 @@
     <string name="find_next" msgid="5742124618942193978">"နောက်တစ်ခု ရှာဖွေရန်"</string>
     <string name="find_previous" msgid="2196723669388360506">"အရင်တစ်ခု ရှာဖွေရန်"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g>မှ တည်နေရာအား တောင်းခံသည်"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"တည်နေရာအား တောင်းခံသည်"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"တည်နေရာ တောင်းခံခြင်း"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)မှတောင်းခံသည်"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Yes"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
@@ -1583,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ဘရောက်ဇာ ဖွင့်မည်လား။"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ဖုန်းခေါ်ဆိုမှုကို လက်ခံမလား?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"အမြဲတမ်း"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"အမြဲဖွင့်မည်အဖြစ် သတ်မှတ်ရန်"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"တစ်ခါတည်း"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ဆက်တင်များ"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s က အလုပ်ပရိုဖိုင်ကို မပံ့ပိုးပါ။"</string>
@@ -1612,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"အပေါ်မှ ထပ်သောအရာ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g>  dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", လုံခြုံသော"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> မှစတင်သော ဤနောက်ခံလုပ်ဆောင်ချက်ကို အနာဂတ် Q တည်ဆောက်ပုံများတွင် ပိတ်ထားပါမည်။ g.co/dev/bgblock ကိုကြည့်ပါ။"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> မှစတင်သော နောက်ခံလုပ်ဆောင်ချက်ကို ပိတ်ထားသည်။ g.co/dev/bgblock ကိုကြည့်ပါ။"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ပုံဖော်မှုအား မေ့လျော့ခြင်း"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ပုံဆွဲအမှား"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"စကားဝှက်အမှား"</string>
@@ -1667,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်သည် <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို ဖွင့်လိုက်ပါသည်"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"အများသုံးစွဲနိုင်မှု ဖြတ်လမ်းလင့်ခ်သည် <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို ပိတ်လိုက်ပါသည်"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို သုံးရန် အသံအတိုးအလျှော့ ခလုတ်နှစ်ခုလုံးကို သုံးစက္ကန့်ကြာ ဖိထားပါ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"အများသုံးစွဲနိုင်မှု ခလုတ်ကို တို့သည့်အခါ အသုံးပြုမည့် ဝန်ဆောင်မှုကို ရွေးချယ်ပါ−"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ဝန်ဆောင်မှုများကို ပြောင်းလဲရန် အများသုံးစွဲနိုင်မှု ခလုတ်ကို တို့၍ ထိထားပါ။"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"အများသုံးစွဲနိုင်မှု ခလုတ်ကို တို့သည့်အခါ အသုံးပြုမည့် ဝန်ဆောင်မှုကို ရွေးချယ်ပါ−"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"အများသုံးစွဲနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (မျက်နှာပြင်အောက်ခြေမှနေ၍ လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"အများသုံးစွဲနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (မျက်နှာပြင်အောက်ခြေမှနေ၍ လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် အများသုံးစွဲနိုင်မှုခလုတ်ကို ဖိထားပါ။"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ။"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ။"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ချဲ့ခြင်း"</string>
     <string name="user_switched" msgid="3768006783166984410">"လက်ရှိအသုံးပြုနေသူ <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>သို့ ပြောင်းနေ…"</string>
@@ -1888,7 +1895,7 @@
     <string name="country_selection_title" msgid="2954859441620215513">"ဒေသရွေးချယ်မှု"</string>
     <string name="search_language_hint" msgid="7042102592055108574">"ဘာသာစကားအမည် ထည့်ပါ"</string>
     <string name="language_picker_section_suggested" msgid="8414489646861640885">"အကြံပြုထားသည်"</string>
-    <string name="language_picker_section_all" msgid="3097279199511617537">"ဘာသာစကားများအားလုံး"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"ဘာသာစကားအားလုံး"</string>
     <string name="region_picker_section_all" msgid="8966316787153001779">"ဒေသအားလုံး"</string>
     <string name="locale_search_menu" msgid="2560710726687249178">"ရှာဖွေရန်"</string>
     <string name="app_suspended_title" msgid="2075071241147969611">"အက်ပ်ကို မရရှိနိုင်ပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 11cc95f..a589389 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi-anrop"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi-anrop"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-anrop"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN-anrop"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Bilmodus"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Kontostatus"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Utviklermeldinger"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Viktige utviklermeldinger"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Oppdateringer"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Nettverksstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Nettverksvarsler"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon for fingeravtrykk"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"administrere maskinvare for Ansiktslås"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Lar appen bruke metoder for å legge til og slette ansiktmaler for bruk."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"bruke maskinvare for Ansiktslås"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Lar appen bruke maskinvare for Ansiktslås til autentisering"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Ansiktslås"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Registrer ansiktet ditt på nytt"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"For å forbedre gjenkjennelse, registrer ansiktet ditt på nytt"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Kunne ikke ta opp nøyaktige ansiktsdata Prøv igjen"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Flytt telefonen til venstre."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Flytt telefonen til høyre."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Se mer direkte på enheten din."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Kan ikke se ansiktet ditt. Se på telefonen."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Hold ansiktet ditt rett foran telefonen."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"For mye bevegelse. Hold telefonen stødig."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registrer ansiktet ditt på nytt."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Kan ikke gjenkjenne ansiktet lenger. Prøv igjen."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Vri hodet ditt litt mindre."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Vri hodet ditt litt mindre."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Fjern alt som skjuler ansiktet ditt."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Rengjør sensoren på toppkanten av skjermen."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Rengjør den øverste delen av skjermen, inkludert den svarte linjen"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Kan ikke bekrefte ansikt. Utilgjengelig maskinvare."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Prøv Ansiktslås igjen."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Kan ikke lagre nye ansiktsdata. Slett gamle data først."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansikt-operasjonen ble avbrutt."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Ansiktslås ble avbrutt av brukeren."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"For mange forsøk. Prøv igjen senere."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"For mange forsøk. Ansiktslås er slått av."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Kan ikke bekrefte ansiktet. Prøv igjen."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Du har ikke konfigurert Ansiktslås."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Ansiktslås støttes ikke på denne enheten"</string>
     <string name="face_name_template" msgid="7004562145809595384">"Ansikt <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Vis opplåsingsfeltet."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Opplåsning ved å dra med fingeren."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Mønsteropplåsning."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ansiktsopplåsning."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ansiktslås"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN-opplåsning."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"PIN-opplåsing for SIM-kort."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"PUK-opplåsing for SIM-kort."</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Åpne med"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Åpne med %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Åpne"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Gi tilgang til å åpne <xliff:g id="HOST">%1$s</xliff:g>-linker med"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Gi tilgang til å åpne <xliff:g id="HOST">%1$s</xliff:g>-linker med <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Åpne <xliff:g id="HOST">%1$s</xliff:g>-linker med"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Åpne linker med"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Åpne linker med <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Åpne <xliff:g id="HOST">%1$s</xliff:g>-linker med <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Gi tilgang"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Rediger med"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Rediger med %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Tilbakestill enheten til fabrikkstandard for å slå av Testrammeverk-modus."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Trygt å bruke USB-porten"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonen oppdager ikke væsker eller rusk lenger."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Kjører feilrapport …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vil du dele feilrapporten?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte nettleseren?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vil du besvare anropet?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Alltid"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Angi som alltid åpen"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Bare én gang"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Innstillinger"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s støtter ikke arbeidsprofiler"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlegg #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", sikker"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Denne bakgrunnsaktiviteten som starter fra <xliff:g id="PACKAGENAME">%1$s</xliff:g>, blir blokkert i fremtidige Q-delversjoner. Se g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Bakgrunnsaktivitet som starter fra <xliff:g id="PACKAGENAME">%1$s</xliff:g>, er blokkert. Se g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Har du glemt mønsteret?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Feil mønster"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Feil passord"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Snarveien for tilgjengelighet slo på <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Snarveien for tilgjengelighet slo av <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Trykk og hold inne begge volumtastene i tre sekunder for å bruke <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Velg en funksjon du vil bruke når du trykker på Tilgjengelighet-knappen:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"For å endre funksjoner, trykk på og hold inne Tilgjengelighet-knappen."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Velg en tjeneste du vil bruke når du trykker på Tilgjengelighet-knappen:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Velg en tjeneste du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med to fingre):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Velg en tjeneste du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med tre fingre):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"For å bytte mellom tjenester, trykk og hold på Tilgjengelighet-knappen."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"For å bytte mellom tjenester, sveip opp med to fingre og hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"For å bytte mellom tjenester, sveip opp med tre fingre og hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Forstørring"</string>
     <string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Bytter til <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1907,7 +1904,7 @@
     <string name="work_mode_off_message" msgid="5130856710614337649">"Jobbappene dine samt varsler, data og andre funksjoner i jobbprofilen din blir slått på"</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Slå på"</string>
     <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"Denne appen er utviklet for en eldre versjon av Android og fungerer kanskje ikke som den skal. Prøv å se etter oppdateringer, eller kontakt utvikleren."</string>
-    <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Se etter oppdatering"</string>
+    <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Se etter oppdateringer"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Du har nye meldinger"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Åpne SMS-appen for å se"</string>
     <string name="profile_encrypted_title" msgid="4260432497586829134">"Enkelte funksjoner kan begrenses"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index db9ca87..89e75b4 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi कलिङ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi कलिङ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN कल"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN कल"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"कार मोड"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"खाताको स्थिति"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"विकासकर्ताका सन्देशहरू"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"विकासकर्तासम्बन्धी महत्त्वपूर्ण सन्देशहरू"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"अद्यावधिकहरू"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"नेटवर्कको स्थिति"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"नेटवर्कका अलर्टहरू"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"फिंगरप्रिन्ट आइकन"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"फेस अनलकको हार्डवेयर व्यवस्थित गर्नुहोस्"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"अनुप्रयोगलाई प्रयोगका लागि अनुहार टेम्प्लेट थप्न र मेटाउने तरिका आह्वान गर्न अनुमति दिन्छ।"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"फेस अनलकको हार्डवेयर प्रयोग गर्नुहोस्"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"अनुप्रयोगलाई प्रमाणीकरणका लागि फेस अनलकको हार्डवेयर प्रयोग गर्न अनुमति दिन्छ"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"फेस अनलक"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"आफ्नो अनुहार पुनः दर्ता गर्नुहोस्"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"अनुहार पहिचानको गुणस्तर सुधार गर्न कृपया आफ्नो अनुहार पुनः दर्ता गर्नुहोस्"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"अनुहारको सटीक डेटा खिच्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"फोन बायाँतिर सार्नुहोस्।"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"फोन दायाँतिर सार्नुहोस्।"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"कृपया अझ सीधा गरी आफ्नो स्क्रिनमा हेर्नुहोस्।"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"तपाईंको अनुहार देखिएन। फोनमा हेर्नुहोस्।"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"आफ्नो अनुहार फोनको सीधा अगाडि पार्नुहोस्।"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"अत्यधिक हल्लियो। फोन स्थिर राख्नुहोस्।"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"कृपया आफ्नो अनुहार पुनः दर्ता गर्नुहोस्।"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"अब उप्रान्त अनुहार पहिचान गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"आफ्नो टाउको अलि थोरै घुमाउनुहोस्।"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"आफ्नो टाउको अलि थोरै घुमाउनुहोस्।"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"तपाईंको अनुहार लुकाउने सबै कुरा लुकाउनुहोस्।"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"स्क्रिनको शीर्ष कुनामा रहेको सेन्सर सफा गर्नुहोस्।"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"कालो रङको पट्टीलगायत आफ्नो स्क्रिनको माथिल्लो भाग सफा गर्नुहोस्"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"अनुहार पुष्टि गर्न सकिएन। हार्डवेयर उपलब्ध छैन।"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"फेरि फेस अनलक प्रयोग गरी हेर्नुहोस्।"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"अनुहारसम्बन्धी नयाँ डेटा भण्डारण गर्न सकिएन। पहिले कुनै पुरानो डेटा मेटाउनुहोस्।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"अनुहार पहिचान रद्द गरियो।"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"प्रयोगकर्ताले फेस अनलकको कार्य रद्द गर्नुभयो।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"धेरैपटक प्रयासहरू भए। पछि फेरि प्रयास गर्नुहोस्‌।"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"अत्यधिक प्रयासहरू भए। फेस अनलक असक्षम पारियो।"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"अनुहार पुष्टि गर्न सकिएन। फेरि प्रयास गर्नुहोस्।"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"तपाईंले फेस अनलक सुविधा सेट अप गर्नुभएको छैन।"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"यस यन्त्रमा फेस अनलक सुविधा प्रयोग गर्न मिल्दैन।"</string>
     <string name="face_name_template" msgid="7004562145809595384">"अनुहार <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1142,8 +1135,10 @@
     <!-- no translation found for whichViewApplicationNamed (2286418824011249620) -->
     <skip />
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"खोल्नुहोस्"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"निम्नमार्फत <xliff:g id="HOST">%1$s</xliff:g>का लिंकहरू खोल्न पहुँच दिनुहोस्‌"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g>मार्फत <xliff:g id="HOST">%1$s</xliff:g>का लिंकहरू खोल्न पहुँच दिनुहोस्‌"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"निम्नमार्फत <xliff:g id="HOST">%1$s</xliff:g> का लिंकहरू खोल्नुहोस्"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"निम्नमार्फत लिंकहरू खोल्नुहोस्"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> मार्फत लिंकहरू खोल्नुहोस्"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> मार्फत <xliff:g id="HOST">%1$s</xliff:g> का लिंकहरू खोल्नुहोस्"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"पहुँच दिनुहोस्"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"सँग सम्पादन गर्नुहोस्"</string>
     <!-- String.format failed for translation -->
@@ -1372,8 +1367,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"परीक्षण प्याकेज मोड असक्षम पार्न फ्याक्ट्री रिसेट गर्नुहोस्।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB पोर्टमा तरल पदार्थ वा धुलो भएको कुरा पत्ता लाग्यो"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB पोर्ट स्वतः असक्षम पारियो। थप जान्न ट्याप गर्नुहोस्।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB पोर्ट प्रयोग गर्दा हुन्छ"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"फोनले अब उप्रान्त तरल पदार्थ वा धुलो नभएको पत्ता लगायो"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रिपोर्ट लिँदै..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग रिपोर्टलाई साझेदारी गर्ने हो?"</string>
@@ -1509,7 +1503,7 @@
     <string name="find_next" msgid="5742124618942193978">"अर्को भेटाउनुहोस्"</string>
     <string name="find_previous" msgid="2196723669388360506">"अघिल्लो फेला पार्नुहोस्"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> बाट स्थान अनुरोध"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"स्थान अनुरोध"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"स्थानसम्बन्धी अनुरोध"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) द्वारा अनुरोध गरिएको"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"हो"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"होइन"</string>
@@ -1598,6 +1592,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउजर सुरु गर्ने हो?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"कल स्वीकार गर्नुहुन्छ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"सधैँ"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"सधैँ खुला राख्ने गरी सेट गर्नुहोस्"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"एक पटक मात्र"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"सेटिङहरू"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s  कार्य प्रोफाइल समर्थन गर्दैन"</string>
@@ -1627,8 +1622,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"आवरण #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", सुरक्षित"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"यो पृष्ठभूमिमा चल्ने क्रियाकलापलाई <xliff:g id="PACKAGENAME">%1$s</xliff:g> बाट भविष्यका Q build हरूमा रोक लगाइने छ। g.co/dev/bgblock हेर्नुहोस्।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> माथि रोक लगाएपछि पृष्ठभूमिको क्रियाकलाप सुरु हुन्छ। g.co/dev/bgblock हेर्नुहोस्।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ढाँचा बिर्सनु भयो"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"गलत ढाँचा"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"गलत पासवर्ड"</string>
@@ -1682,8 +1675,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"पहुँचको सर्टकटले <xliff:g id="SERVICE_NAME">%1$s</xliff:g> लाई सक्रिय पार्‍यो"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"पहुँचको सर्टकटले <xliff:g id="SERVICE_NAME">%1$s</xliff:g> लाई निष्क्रिय पार्‍यो"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> प्रयोग गर्न दुवै भोल्युम कुञ्जीहरूलाई तीन सेकेन्डसम्म थिचिराख्नुहोस्"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"तपाईंले पहुँच सम्बन्धी बटनलाई ट्याप गर्दा प्रयोग गर्नुपर्ने सुविधा रोज्नुहोस्:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"सुविधाहरूलाई बदल्न, पहुँच सम्बन्धी बटनलाई छोएर थिची राख्नुहोस्।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"तपाईंले पहुँचसम्बन्धी बटन ट्याप गर्दा प्रयोग गर्नु पर्ने सुविधा रोज्नुहोस्:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"पहुँचसम्बन्धी इसारासँगै प्रयोग गर्नु पर्ने कुनै सेवा छनौट गर्नुहोस् (दुईवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"पहुँचसम्बन्धी इसारासँगै प्रयोग गर्नु पर्ने कुनै सेवा छनौट गर्नुहोस् (तीनवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"एउटा सेवाबाट अर्को सेवामा जान पहुँचसम्बन्धी बटनमा छोइराख्नुहोस्।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"एउटा सेवाबाट अर्को सेवामा जान दुईवटा औँलाले माथितिर स्वाइप गरी थिचिराख्नुहोस्।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"एउटा सेवाबाट अर्को सेवामा जान तीनवटा औँलाले माथितिर स्वाइप गरी थिचिराख्नुहोस्।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"म्याग्निफिकेसन"</string>
     <string name="user_switched" msgid="3768006783166984410">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> मा स्विच गर्दै..."</string>
@@ -1973,7 +1970,7 @@
     <string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"तटीय क्षेत्र र नदीछेउका ठाउँहरू छाडी उच्च सतहमा अवस्थित कुनै अझ सुरक्षित ठाउँमा जानुहोस्।"</string>
     <string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"शान्त रहनुहोस् र नजिकै आश्रयस्थल खोज्नुहोस्।"</string>
     <string name="etws_primary_default_message_test" msgid="2709597093560037455">"आपतकालीन सन्देशहरूको परीक्षण"</string>
-    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"जवाफ दिनुहोस्"</string>
+    <string name="notification_reply_button_accessibility" msgid="3621714652387814344">"जवाफ दिनु…"</string>
     <string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
     <string name="mmcc_authentication_reject" msgid="5767701075994754356">"SIM मार्फत भ्वाइस कल गर्न मिल्दैन"</string>
     <string name="mmcc_imsi_unknown_in_hlr" msgid="5316658473301462825">"SIM मार्फत भ्वाइस कल गर्ने प्रावधान छैन"</string>
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index 8ba2c60..93975a9 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -87,5 +87,7 @@
 
     <style name="Theme.DeviceDefault.Resolver" parent="Theme.DeviceDefault.ResolverCommon">
         <item name="windowLightNavigationBar">false</item>
+        <item name="colorBackgroundFloating">@android:color/GM2_grey_800</item>
+        <item name="textColorSecondary">@android:color/resolver_text_color_secondary_dark</item>
     </style>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b583c73..4194eb1 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Bellen via wifi van <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Bellen via wifi met <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Bellen via WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Bellen via WLAN van <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wifi van <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Automodus"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Accountstatus"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Ontwikkelaarsberichten"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Belangrijke ontwikkelaarsberichten"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Updates"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Netwerkstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Netwerkmeldingen"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Vingerafdruk-pictogram"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"hardware voor ontgrendelen via gezichtsherkenning beheren"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Hiermee kan de app methoden aanroepen om gezichtstemplates toe te voegen en te verwijderen voor gebruik."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"hardware voor ontgrendelen via gezichtsherkenning gebruiken"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Hiermee kan de app hardware voor ontgrendelen via gezichtsherkenning gebruiken voor verificatie"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Ontgrendelen via gezichtsherkenning"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Je gezicht opnieuw registreren"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Registreer je gezicht opnieuw om de herkenning te verbeteren"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Geen accurate gegevens. Probeer het nog eens."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Beweeg je telefoon meer naar links."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Beweeg je telefoon meer naar rechts."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Kijk rechter naar je apparaat."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Je gezicht is niet te zien. Kijk naar de telefoon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Houd je gezicht recht voor de telefoon."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Te veel beweging. Houd je telefoon stil."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registreer je gezicht opnieuw."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Herkent gezicht niet meer. Probeer het nog eens."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Draai je hoofd iets minder."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Draai je hoofd iets minder."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Zorg dat je gezicht volledig zichtbaar is."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Maak de sensor bovenaan het scherm schoon."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Reinig de bovenkant van je scherm, inclusief de zwarte balk"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Kan gezicht niet verifiëren. Hardware niet beschikbaar."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Probeer ontgrendelen via gezichtsherkenning opnieuw."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Kan nieuwe gezichten niet opslaan. Verwijder eerst een oude."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Bewerking voor gezichtsherkenning geannuleerd."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Ontgrendelen via gezichtsherkenning geannuleerd door gebruiker."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Te veel pogingen. Probeer het later opnieuw."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Te veel pogingen. Ontgrendelen via gezichtsherkenning uitgeschakeld."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Kan gezicht niet verifiëren. Probeer het nog eens."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Je hebt ontgrendelen via gezichtsherkenning niet ingesteld."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Ontgrendelen via gezichtsherkenning wordt niet ondersteund op dit apparaat."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Gezicht <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Openen met"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Openen met %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Openen"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Toegang verlenen om links naar <xliff:g id="HOST">%1$s</xliff:g> te openen met"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Toegang verlenen om links naar <xliff:g id="HOST">%1$s</xliff:g> te openen met <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Links van <xliff:g id="HOST">%1$s</xliff:g> openen met"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Links openen met"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Links openen met <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Links van <xliff:g id="HOST">%1$s</xliff:g> openen met <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Toegang geven"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Bewerken met"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Bewerken met %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Reset de fabrieksinstellingen om de test harness-modus uit te schakelen."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-poort kan worden gebruikt"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"De telefoon detecteert geen vloeistof of vuil meer."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Bugrapport genereren…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bugrapport delen?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Gesprek accepteren?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Altijd"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Instellen op altijd openen"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Één keer"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Instellingen"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ondersteunt werkprofielen niet"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", beveiligd"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Het starten van deze achtergrondactiviteit voor <xliff:g id="PACKAGENAME">%1$s</xliff:g> wordt geblokkeerd in toekomstige Q-builds. Ga naar g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Starten van achtergrondactiviteit voor <xliff:g id="PACKAGENAME">%1$s</xliff:g> is geblokkeerd. Ga naar g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Patroon vergeten"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Onjuist patroon"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Onjuist wachtwoord"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"\'Snelle link voor toegankelijkheid\' heeft <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ingeschakeld"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"\'Snelle link voor toegankelijkheid\' heeft <xliff:g id="SERVICE_NAME">%1$s</xliff:g> uitgeschakeld"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Houd beide volumetoetsen drie seconden ingedrukt om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruiken"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Kies een functie om te gebruiken wanneer je op de knop Toegankelijkheid tikt:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Als je functies wilt wijzigen, tik je op de knop Toegankelijkheid en houd je deze vast."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Kies een service om te gebruiken wanneer je op de toegankelijkheidsknop tikt:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Kies een service om te gebruiken met het toegankelijkheidsgebaar (veeg met twee vingers omhoog vanaf de onderkant van het scherm):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Kies een service om te gebruiken met het toegankelijkheidsgebaar (veeg met drie vingers omhoog vanaf de onderkant van het scherm):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Tik op de toegankelijkheidsknop en houd deze vast om tussen services te schakelen."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Veeg met twee vingers omhoog en houd vast om tussen services te schakelen."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Veeg met drie vingers omhoog en houd vast om tussen services te schakelen."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Vergroting"</string>
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1910,7 +1907,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Controleren op update"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Je hebt nieuwe berichten"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Open je sms-app om ze te bekijken"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Functionaliteit kan zijn beperkt"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Functionaliteit kan beperkt zijn"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Werkprofiel vergrendeld"</string>
     <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>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 112f974..0f3472c 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ୱାଇ-ଫାଇ କଲିଂ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ୱାଇଫାଇ କଲିଂ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN କଲ୍‍"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN କଲ୍‍"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ୱାଇ-ଫାଇ"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"କାର୍ ମୋଡ୍"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ଆକାଉଣ୍ଟର ସ୍ଥିତି"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ଡେଭଲପରଙ୍କ ମେସେଜ୍‍"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"ଗୁରୁତ୍ଵପୂର୍ଣ୍ଣ ଡେଭେଲପର୍ ମେସେଜ୍‌ଗୁଡ଼ିକ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"ଅପଡେଟ୍‍"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ନେଟୱର୍କ ସ୍ଥିତି"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ନେଟୱର୍କ ଅଲର୍ଟ"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ଆଇକନ୍"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"ଫେସ୍ ଅନ୍‌ଲକ୍ ହାର୍ଡୱେର୍ ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ବ୍ୟବହାର ପାଇଁ ଆପ୍‍କୁ ଫେସିଆଲ୍‍ ଟେମ୍ପଲେଟ୍‍ ଯୋଡିବା ଓ ଡିଲିଟ୍‍ ର ପଦ୍ଧତି ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ।"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"ଫେସ୍ ଅନ୍‌ଲକ୍ ହାର୍ଡୱେର୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"ପ୍ରାମାଣିକତା ପାଇଁ ଫେସ୍ ଅନ୍‌ଲକ୍ ହାର୍ଡୱେର୍‌ର ବ୍ୟବହାର ପାଇଁ ଆପ୍‍କୁ ଅନୁମତି ଦିଅନ୍ତୁ।"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"ଫେସ୍ ଅନ୍‌ଲକ୍"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"ଆପଣଙ୍କର ମୁହଁ ପୁଣି-ଏନ୍‍ରୋଲ୍ କରନ୍ତୁ"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"ଚିହ୍ନଟକରଣକୁ ଉନ୍ନତ କରିବା ପାଇଁ, ଦୟାକରି ଆପଣଙ୍କର ମୁହଁ ପୁଣି-ଏନ୍‍ରୋଲ୍ କରନ୍ତୁ।"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"ମୁହଁର ଡାଟା କ୍ୟାପଚର୍ ହେଲାନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ବାମ ପଟକୁ ଫୋନ୍ ଘୁଞ୍ଚାନ୍ତୁ।"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ଡାହାଣ ପଟକୁ ଫୋନ୍ ଘୁଞ୍ଚାନ୍ତୁ।"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"ଦୟାକରି ଆପଣଙ୍କ ଡିଭାଇସ୍‌କୁ ସିଧାସଳଖ ଦେଖନ୍ତୁ।"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"ଆପଣଙ୍କର ମୁହଁ ଦେଖି ପାରୁନାହିଁ। ଫୋନ୍‌କୁ ଦେଖନ୍ତୁ।"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"ଆପଣଙ୍କ ମୁହଁକୁ ଫୋନ୍ ସାମ୍ନାରେ ସିଧାସଳଖ ରଖନ୍ତୁ।"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"ଅତ୍ୟଧିକ ଅସ୍ଥିର। ଫୋନ୍‍କୁ ସ୍ଥିର ଭାବେ ଧରନ୍ତୁ।"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ଦୟାକରି ଆପଣଙ୍କର ମୁହଁ ପୁଣି-ଏନ୍‍ରୋଲ୍ କରନ୍ତୁ।"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"ଆଉ ମୁହଁ ଚିହ୍ନଟ କରିହେଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ଆପଣଙ୍କର ମୁଣ୍ଡକୁ ଟିକିଏ ବୁଲାନ୍ତୁ।"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"ଆପଣଙ୍କର ମୁଣ୍ଡକୁ ଟିକିଏ ବୁଲାନ୍ତୁ।"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"ଆପଣଙ୍କର ମୁହଁ ଲୁଚାଉଥିବା ଜିନିଷକୁ କାଢ଼ି ଦିଅନ୍ତୁ।"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"ସ୍କ୍ରିନ୍‍ର ଉପର ପ୍ରାନ୍ତରେ ଥିବା ସେନ୍ସର୍‍କୁ ଖାଲି କରନ୍ତୁ।"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"କଳା ବାର୍ ସମେତ ଆପଣଙ୍କ ସ୍କ୍ରିନ୍‌ର ଶୀର୍ଷକୁ ସଫା କରନ୍ତୁ"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"ମୁହଁ ଚିହ୍ନଟ କରିପାରିଲା ନାହିଁ। ହାର୍ଡୱେୟାର୍ ଉପଲବ୍ଧ ନାହିଁ।"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"ଫେସ୍ ଅନ୍‌ଲକ୍ ପୁଣି ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"ନୂଆ ମୁହଁ ଡାଟା ଷ୍ଟୋର୍ ହେବ ନାହିଁ। ପ୍ରଥମେ ପୁରୁଣାକୁ ଡିଲିଟ୍ କରନ୍ତୁ।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ଫେସ୍‍ର ଅପରେଶନ୍‍ କ୍ୟାନ୍ସଲ୍‍ ହୋ‍ଇଗଲା"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ଦ୍ୱାରା ଫେସ୍ ଅନଲକ୍ ବାତିଲ୍ କରାଯାଇଛି।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ବାରମ୍ବାର ଚେଷ୍ଟା। ପରେ ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"ଅତ୍ୟଧିକ ପ୍ରଚେଷ୍ଟା. ଫେସ୍ ଅନ୍‌ଲକ୍ ଅକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"ମୁହଁ ଚିହ୍ନଟ କରିପାରିଲା ନାହିଁ। ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"ଆପଣ ଫେସ୍ ଅନ୍‌ଲକ୍ ସେଟ୍ ଅପ୍ କରିନାହାଁନ୍ତି"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"ଏହି ଡିଭାଇସ୍‌ରେ ଫେସ୍ ଅନ୍‌ଲକ୍ ସମର୍ଥିତ ନୁହେଁ।"</string>
     <string name="face_name_template" msgid="7004562145809595384">"<xliff:g id="FACEID">%d</xliff:g>ଙ୍କ ଫେସ୍‍"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"ସହିତ ଖୋଲନ୍ତୁ"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ସହିତ ଖୋଲନ୍ତୁ"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"ଖୋଲନ୍ତୁ"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ଏହା ସହିତ ଲିଙ୍କ ଥିବା <xliff:g id="HOST">%1$s</xliff:g> ଖୋଲିବା ପାଇଁ ଆକ୍ସେସ୍ ଦିଅନ୍ତୁ"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> ସହିତ ଲିଙ୍କ ଥିବା <xliff:g id="HOST">%1$s</xliff:g> ଖୋଲିବା ପାଇଁ ଆକ୍ସେସ୍ ଦିଅନ୍ତୁ"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"ଏଥିରେ <xliff:g id="HOST">%1$s</xliff:g> ଲିଙ୍କ୍‍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"ଏଥିରେ ଲିଙ୍କ୍‍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> ମାଧ୍ୟମରେ ଲିଙ୍କ୍‍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> ମାଧ୍ୟମରେ <xliff:g id="HOST">%1$s</xliff:g> ଲିଙ୍କ୍‍ଗୁଡ଼ିକ ଖୋଲନ୍ତୁ"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ଆକ୍ସେସ୍‌ ଦିଅନ୍ତୁ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ସହିତ ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$sରେ ସଂଶୋଧନ କରନ୍ତୁ"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ଟେଷ୍ଟ ହାର୍‌ନେସ୍ ମୋଡ୍ ଅକ୍ଷମ କରିବାକୁ ଏକ ଫ୍ୟାକ୍ଟରୀ ରିସେଟ୍ କରନ୍ତୁ।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ପୋର୍ଟରେ ତରଳ ପଦାର୍ଥ ବା ଧୂଳି"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ପୋର୍ଟ ସ୍ୱଚାଳିତ ଭାବେ ଅକ୍ଷମ ହୋଇଛି। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ପୋର୍ଟ ବ୍ୟବହାର କରିବା ପାଇଁ ଠିକ୍ ଅଟେ"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ଫୋନ୍ ଆଉ ତରଳ ପଦାର୍ଥ କିମ୍ବା ଧୂଳିର ଚିହ୍ନଟ କରୁନାହିଁ।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ବଗ୍ ରିପୋର୍ଟ ନିଆଯାଉଛି…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ବଗ୍‍ ରିପୋର୍ଟ ସେୟାର୍‌ କରିବେ?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ବ୍ରାଉଜର୍‍ ଲଞ୍ଚ କରିବେ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"କଲ୍‍ ସ୍ୱୀକାର କରିବେ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ସର୍ବଦା"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"\'ସର୍ବଦା ଖୋଲା\' ଭାବରେ ସେଟ୍ କରନ୍ତୁ"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"ଥରେ ମାତ୍ର"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ସେଟିଂସ୍"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ୱର୍କ ପ୍ରୋଫାଇଲ୍‌କୁ ସପୋର୍ଟ କରୁନାହିଁ"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ପ୍ରାୟତଃ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ସୁରକ୍ଷିତ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ଠାରୁ ଆରମ୍ଭ ହୋଇଥିବା ପୃଷ୍ଠଭୂମି କାର୍ଯ୍ୟକଳାପ ଆଗାମୀ Q ବିଲ୍ଡରେ ବ୍ଲକ୍ କରାଯିବ। g.co/dev/bgblock ଦେଖନ୍ତୁ।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>ଠାରୁ ଆରମ୍ଭ ହୋଇଥିବା ପୃଷ୍ଠଭୂମି କାର୍ଯ୍ୟକଳାପ ବ୍ଲକ୍ କରାଯାଇଛି। g.co/dev/bgblock ଦେଖନ୍ତୁ।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ପାଟର୍ନ ଭୁଲି ଯାଇଛନ୍ତି"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ଭୁଲ ପାଟର୍ନ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ଭୁଲ ପାସ୍‌ୱର୍ଡ"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ଆକ୍ସେସିବିଲିଟୀ ଶର୍ଟକଟ୍‍ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଅନ୍‍ କରାଯାଇଛି"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ଆକ୍ସେସିବିଲିଟୀ ଶର୍ଟକଟ୍‍ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଅଫ୍‍ କରାଯାଇଛି"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବ୍ୟବହାର କରିବାକୁ ତିନି ସେକେଣ୍ଡ ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ୍‍ କୀ ଦବାଇ ଧରି ରଖନ୍ତୁ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ଆପଣ ଆକ୍ସେସବିଲିଟି ବଟନ୍‍ ଟାପ୍‍ କରିବା ବେଳେ ଏକ ବୈଶିଷ୍ଟ୍ୟ ବ୍ୟବହାର କରିବାକୁ ବାଛନ୍ତୁ:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ବୈଶିଷ୍ଟ୍ୟ ବଦଳାଇବାକୁ, ଆକ୍ସେସବିଲିଟି ବଟନ୍‍ ସ୍ପର୍ଶ କରନ୍ତୁ ଓ ଧରିରଖନ୍ତୁ।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ଆପଣ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ଟାପ୍ କରିବା ସମୟରେ ଏକ ସେବା ବ୍ୟବହାର କରିବା ପାଇଁ ବାଛନ୍ତୁ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଏକ ସେବା ବାଛନ୍ତୁ (ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନ୍‍ର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଏକ ସେବା ବାଛନ୍ତୁ (ତିନିଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନ୍‍ର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ସେବାଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବା ପାଇଁ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ସ୍ପର୍ଶ କରନ୍ତୁ ଓ ଧରି ରଖନ୍ତୁ।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ସେବାଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବା ପାଇଁ ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ସେବାଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବା ପାଇଁ ତିନିଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ମ୍ୟାଗ୍ନିଫିକେସନ୍‍"</string>
     <string name="user_switched" msgid="3768006783166984410">"ବର୍ତ୍ତମାନର ୟୁଜର୍‌ ହେଉଛନ୍ତି <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ରେ ସୁଇଚ୍ କରନ୍ତୁ…"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index fcdc900..8245546 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ Calling"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ਕਾਲ"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ਕਾਲ"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"ਕਾਰ ਮੋਡ"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ਖਾਤੇ ਦੀ ਸਥਿਤੀ"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ਵਿਕਾਸਕਾਰ ਸੁਨੇਹੇ"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"ਮਹੱਤਵਪੂਰਨ ਵਿਕਾਸਕਾਰ ਸੁਨੇਹੇ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"ਅੱਪਡੇਟ"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ਨੈੱਟਵਰਕ ਅਵਸਥਾ"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ਨੈੱਟਵਰਕ ਸੁਚੇਤਨਾਵਾਂ"</string>
@@ -265,7 +267,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"ਸੁਚੇਤਨਾਵਾਂ"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"ਪ੍ਰਚੂਨ ਸਟੋਰਾਂ ਲਈ ਡੈਮੋ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB ਕਨੈਕਸ਼ਨ"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"ਐਪ ਚੱਲ ਰਹੀ ਹੈ"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"ਚੱਲ ਰਹੀ ਐਪ"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ਬੈਟਰੀ ਦੀ ਖਪਤ ਕਰਨ ਵਾਲੀਆਂ ਐਪਾਂ"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ਐਪਾਂ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਤੀਕ"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"ਚਿਹਰਾ ਅਣਲਾਕ ਹਾਰਡਵੇਅਰ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ਐਪ ਨੂੰ ਵਰਤਣ ਲਈ ਚਿਹਰਾ ਟੈਮਪਲੇਟ ਸ਼ਾਮਲ ਕਰਨ ਜਾਂ ਮਿਟਾਉਣ ਦੀਆਂ ਵਿਧੀਆਂ ਦੀ ਬੇਨਤੀ ਕਰਨ ਦਿੰਦੀ ਹੈ।"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"ਚਿਹਰਾ ਅਣਲਾਕ ਹਾਰਡਵੇਅਰ ਵਰਤੋ"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"ਐਪ ਨੂੰ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚਿਹਰਾ ਅਣਲਾਕ ਹਾਰਡਵੇਅਰ ਵਰਤਣ ਦਿੰਦੀ ਹੈ"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"ਚਿਹਰਾ ਅਣਲਾਕ"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"ਆਪਣਾ ਚਿਹਰਾ ਮੁੜ-ਦਰਜ ਕਰੋ"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"ਪਛਾਣ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਚਿਹਰੇ ਨੂੰ ਮੁੜ-ਦਰਜ ਕਰੋ"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"ਸਟੀਕ ਚਿਹਰਾ ਡਾਟਾ ਕੈਪਚਰ ਨਹੀਂ ਹੋਇਆ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ਫ਼ੋਨ ਨੂੰ ਖੱਬੇ ਪਾਸੇ ਲਿਜਾਓ।"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ਫ਼ੋਨ ਨੂੰ ਸੱਜੇ ਪਾਸੇ ਲਿਜਾਓ।"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"ਕਿਰਪਾ ਕਰਕੇ ਸਿੱਧਾ ਆਪਣੇ ਡੀਵਾਈਸ ਵੱਲ ਦੇਖੋ।"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"ਤੁਹਾਡਾ ਚਿਹਰਾ ਨਹੀਂ ਦਿਸ ਰਿਹਾ। ਫ਼ੋਨ ਵੱਲ ਦੇਖੋ।"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"ਆਪਣਾ ਚਿਹਰਾ ਫ਼ੋਨ ਦੇ ਬਿਲਕੁਲ ਸਾਹਮਣੇ ਰੱਖੋ।"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਹਿਲਜੁਲ। ਫ਼ੋਨ ਨੂੰ ਸਥਿਰ ਰੱਖੋ।"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ਕਿਰਪਾ ਕਰਕੇ ਆਪਣਾ ਚਿਹਰਾ ਦੁਬਾਰਾ ਦਰਜ ਕਰੋ।"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"ਹੁਣ ਚਿਹਰਾ ਪਛਾਣਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ਆਪਣਾ ਸਿਰ ਥੋੜਾ ਜਿਹਾ ਝੁਕਾਓ।"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"ਆਪਣਾ ਸਿਰ ਥੋੜਾ ਜਿਹਾ ਝੁਕਾਓ।"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"ਤੁਹਾਡਾ ਚਿਹਰਾ ਲੁਕਾਉਣ ਵਾਲੀ ਕੋਈ ਵੀ ਚੀਜ਼ ਹਟਾਓ।"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"ਸਕ੍ਰੀਨ ਦੇ ਸਿਖਰਲੇ ਕਿਨਾਰੇ ਦਾ ਸੈਂਸਰ ਸਾਫ਼ ਕਰੋ।"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"ਕਾਲੀ ਪੱਟੀ ਸਮੇਤ, ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਸਿਖਰ ਨੂੰ ਸਾਫ਼ ਕਰੋ"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"ਚਿਹਰੇ ਦੀ ਪੁਸ਼ਟੀ ਨਹੀਂ ਹੋ ਸਕੀ। ਹਾਰਡਵੇਅਰ ਉਪਲਬਧ ਨਹੀਂ।"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"ਚਿਹਰਾ ਅਣਲਾਕ ਦੁਬਾਰਾ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"ਨਵਾਂ ਚਿਹਰਾ ਡਾਟਾ ਸਟੋਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ। ਪਹਿਲਾਂ ਪੁਰਾਣਾ ਹਟਾਓ।"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ਚਿਹਰਾ ਪਛਾਣਨ ਦੀ ਪ੍ਰਕਿਰਿਆ ਰੱਦ ਕੀਤੀ ਗਈ।"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ਵਰਤੋਂਕਾਰ ਨੇ ਚਿਹਰਾ ਅਣਲਾਕ ਰੱਦ ਕੀਤਾ।"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ਹੱਦੋਂ ਵੱਧ ਕੋਸ਼ਿਸ਼ਾਂ। ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ। ਚਿਹਰਾ ਅਣਲਾਕ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"ਚਿਹਰੇ ਦੀ ਪੁਸ਼ਟੀ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ। ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"ਤੁਸੀਂ ਚਿਹਰਾ ਅਣਲਾਕ ਸੈੱਟਅੱਪ ਨਹੀਂ ਕੀਤਾ ਹੈ।"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਚਿਹਰਾ ਅਣਲਾਕ ਦੀ ਸੁਵਿਧਾ ਨਹੀਂ ਹੈ।"</string>
     <string name="face_name_template" msgid="7004562145809595384">"ਚਿਹਰਾ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"ਨਾਲ ਖੋਲ੍ਹੋ"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ਨਾਲ ਖੋਲ੍ਹੋ"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"ਖੋਲ੍ਹੋ"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ਇਸ ਨਾਲ <xliff:g id="HOST">%1$s</xliff:g> ਲਿੰਕਾਂ ਨੂੰ ਖੋਲ੍ਹਣ ਦੀ ਪਹੁੰਚ ਦਿਓ"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> ਨਾਲ <xliff:g id="HOST">%1$s</xliff:g> ਲਿੰਕਾਂ ਨੂੰ ਖੋਲ੍ਹਣ ਦੀ ਪਹੁੰਚ ਦਿਓ"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> ਲਿੰਕਾਂ ਨੂੰ ਇਸ ਨਾਲ ਖੋਲ੍ਹੋ"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"ਲਿੰਕਾਂ ਨੂੰ ਇਸ ਨਾਲ ਖੋਲ੍ਹੋ"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"ਲਿੰਕਾਂ ਨੂੰ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਖੋਲ੍ਹੋ"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> ਲਿੰਕਾਂ ਨੂੰ <xliff:g id="APPLICATION">%2$s</xliff:g> ਨਾਲ ਖੋਲ੍ਹੋ"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ਪਹੁੰਚ ਦਿਓ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"ਇਸ ਨਾਲ ਸੰਪਾਦਨ ਕਰੋ"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ਨਾਲ ਸੰਪਾਦਨ ਕਰੋ"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਬੰਦ ਕਰਨ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ।"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB ਪੋਰਟ ਵਿੱਚ ਪਾਣੀ ਜਾਂ ਧੂੜ-ਮਿੱਟੀ"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB ਪੋਰਟ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB ਪੋਰਟ ਵਰਤਣ ਲਈ ਠੀਕ ਹੈ"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ਫ਼ੋਨ ਹੁਣ ਪਾਣੀ ਜਾਂ ਧੂੜ-ਮਿੱਟੀ ਦਾ ਪਤਾ ਨਹੀਂ ਲਗਾਉਂਦਾ ਹੈ।"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ਕੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"ਕੀ ਬ੍ਰਾਊਜ਼ਰ ਲਾਂਚ ਕਰਨਾ ਹੈ?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ਕੀ ਕਾਲ ਸਵੀਕਾਰ ਕਰਨੀ ਹੈ?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ਹਮੇਸ਼ਾਂ"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ਹਮੇਸ਼ਾਂ ਖੁੱਲ੍ਹਾ \'ਤੇ ਸੈੱਟ ਕਰੋ"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"ਕੇਵਲ ਇੱਕ ਵਾਰ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"ਓਵਰਲੇ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ਸੁਰੱਖਿਅਤ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"ਇਹ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ <xliff:g id="PACKAGENAME">%1$s</xliff:g> ਤੋਂ ਸ਼ੁਰੂ ਹੋ ਕੇ ਭਵਿੱਖ ਦੇ Q ਬਿਲਡ ਵਿੱਚ ਬਲਾਕ ਕੀਤੀ ਜਾਵੇਗੀ। g.co/dev/bgblock ਦੇਖੋ।"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> ਬਲਾਕ ਕਰਕੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ ਸ਼ੁਰੂ ਕੀਤੀ ਗਈ। g.co/dev/bgblock ਦੇਖੋ।"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ਪੈਟਰਨ ਭੁੱਲ ਗਏ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ਗ਼ਲਤ ਪੈਟਰਨ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"ਗਲਤ ਪਾਸਵਰਡ"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਨੇ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਬਦਲਣ ਲਈ, ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ।"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ \'ਤੇ ਟੈਪ ਕਰਕੇ ਵਰਤਣ ਲਈ ਕੋਈ ਸੇਵਾ ਚੁਣੋ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਸੇਵਾ ਚੁਣੋ (ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਸੇਵਾ ਚੁਣੋ (ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"ਸੇਵਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ \'ਤੇ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"ਸੇਵਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"ਸੇਵਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
     <string name="user_switched" msgid="3768006783166984410">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> ਤੇ ਸਵਿਚ ਕਰ ਰਿਹਾ ਹੈ…"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 120d256..054a456 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g>, połączenia przez Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g>, połączenia przez Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Połączenie przez WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g>, połączenie przez WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>, Wi-Fi"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Tryb samochodowy"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Stan konta"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Komunikaty dla programistów"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Ważne komunikaty dla programistów"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Aktualizacje"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stan sieci"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alerty dotyczące sieci"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona odcisku palca"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"zarządzanie sprzętem do rozpoznawania twarzy"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Zezwala na aktywowanie przez aplikację metody dodawania i usuwania szablonów twarzy."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"używanie sprzętu do rozpoznawania twarzy"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Zezwala na używanie przez aplikację sprzętu do rozpoznawania twarzy w uwierzytelniania"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Rozpoznanie twarzy"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Zarejestruj swoją twarz ponownie"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Aby poprawić rozpoznawanie, ponownie zarejestruj swoją twarz"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Nie udało się zarejestrować danych twarzy. Spróbuj ponownie."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Przesuń telefon w lewo."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Przesuń telefon w prawo."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Patrz prosto na urządzenie."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Nie widzę Twojej twarzy. Spójrz na telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Ustaw twarz dokładnie na wprost telefonu."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Telefon się porusza. Trzymaj go nieruchomo."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Zarejestruj swoją twarz ponownie."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Nie można już rozpoznać twarzy. Spróbuj ponownie."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Trochę mniej obróć głowę."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Trochę mniej obróć głowę."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Usuń wszystko, co zasłania Ci twarz."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Wyczyść czujnik na górnej krawędzi ekranu."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Wyczyść górną krawędź ekranu, w tym czarny pasek"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Nie można zweryfikować twarzy. Sprzęt niedostępny."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Spróbuj rozpoznania twarzy ponownie."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Nie można przechowywać nowych danych twarzy. Usuń stare."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Analiza twarzy została anulowana."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Użytkownik anulował rozpoznanie twarzy."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Zbyt wiele prób. Spróbuj ponownie później."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Zbyt wiele prób. Rozpoznanie twarzy zostało wyłączone."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nie można zweryfikować twarzy. Spróbuj ponownie."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Rozpoznanie twarzy nie jest skonfigurowane."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"To urządzenie nie obsługuje rozpoznania twarzy."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Twarz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Otwórz w aplikacji"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otwórz w aplikacji %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Otwórz"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Przyznaj uprawnienia do otwierania linków z <xliff:g id="HOST">%1$s</xliff:g> w:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Przyznaj uprawnienia do otwierania linków z <xliff:g id="HOST">%1$s</xliff:g> w aplikacji <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Otwieraj linki z: <xliff:g id="HOST">%1$s</xliff:g> w"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Otwieraj linki w"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Otwieraj linki w aplikacji <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Otwieraj linki z: <xliff:g id="HOST">%1$s</xliff:g> w aplikacji <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Udziel uprawnień"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Edytuj w aplikacji"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edytuj w aplikacji %1$s"</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Przywróć ustawienia fabryczne, by wyłączyć tryb jarzma testowego."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Możesz używać portu USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon nie wykrywa już wilgoci ani zanieczyszczeń."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Zgłaszam błąd…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Udostępnić raport o błędzie?"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Uruchomić przeglądarkę?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Odebrać połączenie?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Zawsze"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Zawsze otwieraj"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Tylko raz"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Ustawienia"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s nie obsługuje profilu do pracy"</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Nakładka nr <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", bezpieczny"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Rozpoczęcie tej aktywności w tle przez pakiet <xliff:g id="PACKAGENAME">%1$s</xliff:g> zostanie zablokowane w przyszłych kompilacjach Q. Patrz g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Rozpoczęcie aktywności w tle przez pakiet <xliff:g id="PACKAGENAME">%1$s</xliff:g> zostało zablokowane. Patrz g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nie pamiętam wzoru"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nieprawidłowy wzór"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nieprawidłowe hasło"</string>
@@ -1719,13 +1712,17 @@
     <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Gdy skrót jest włączony, jednoczesne naciśnięcie przez trzy sekundy obu klawiszy sterowania głośnością uruchomi funkcję ułatwień dostępu.\n\nBieżąca funkcja ułatwień dostępu:\n<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\nFunkcję możesz zmienić, wybierając Ustawienia &gt; Ułatwienia dostępu."</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Wyłącz skrót"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Użyj skrótu"</string>
-    <string name="color_inversion_feature_name" msgid="4231186527799958644">"Inwersja kolorów"</string>
+    <string name="color_inversion_feature_name" msgid="4231186527799958644">"Odwrócenie kolorów"</string>
     <string name="color_correction_feature_name" msgid="6779391426096954933">"Korekcja kolorów"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Skrót ułatwień dostępu wyłączył usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Skrót ułatwień dostępu wyłączył usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Naciśnij i przytrzymaj oba przyciski głośności przez trzy sekundy, by użyć usługi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Wybierz funkcję używaną po kliknięciu przycisku ułatwień dostępu."</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Aby zmienić funkcje, kliknij i przytrzymaj przycisk ułatwień dostępu."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Wybierz usługę używaną po kliknięciu przycisku ułatwień dostępu:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Wybierz usługę używaną w przypadku gestu ułatwień dostępu (przesunięcie dwoma palcami z dołu ekranu w górę):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Wybierz usługę, której chcesz używać w połączeniu z gestami ułatwień dostępu (przesuń trzema palcami z dołu ekranu w górę):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Aby przełączać usługi, naciśnij i przytrzymaj przycisk ułatwień dostępu."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Aby przełączać usługi, przesuń dwoma palcami w górę i przytrzymaj."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Aby przełączyć usługi, przesuń trzema palcami w górę i przytrzymaj."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Powiększenie"</string>
     <string name="user_switched" msgid="3768006783166984410">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Przełączam na użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 4dedb69..742fa81 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Modo carro"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Status da conta"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mensagens do desenvolvedor"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mensagens importantes do desenvolvedor"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Atualizações"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status de rede"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas de rede"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ícone de impressão digital"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gerenciar hardware de desbloqueio facial"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que o app execute métodos para adicionar e excluir modelos de rosto para uso."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"usar hardware de desbloqueio facial"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permite que o app use o hardware de desbloqueio facial para autenticação"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Desbloqueio facial"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Registre seu rosto novamente"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Para melhorar o reconhecimento, registre seu rosto novamente"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Dados precisos não capturados. Tente novamente."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mova o smartphone para a esquerda."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mova o smartphone para a direita."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Olhe mais diretamente para o dispositivo."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Não é possível ver o rosto. Olhe para o telefone."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Deixe o rosto diretamente na frente do smartphone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Muito movimento. Não mova o smartphone."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registre seu rosto novamente."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"O rosto não é mais reconhecido. Tente novamente."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Incline a cabeça um pouco menos."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Incline a cabeça um pouco menos."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Remova tudo que esteja ocultando seu rosto."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Limpe o sensor na borda superior da tela."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Limpe a parte superior da tela, inclusive a barra preta"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Impossível verificar rosto. Hardware indisponível."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Tente usar o desbloqueio facial novamente."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Não é possível salvar dados faciais. Exclua dados antigos."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operação facial cancelada."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Desbloqueio facial cancelado pelo usuário."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Excesso de tentativas. Tente novamente mais tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Muitas tentativas. Desbloqueio facial desativado."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Não é possível verificar o rosto. Tente novamente."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"O desbloqueio facial não foi configurado."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"O desbloqueio facial não é compatível com este dispositivo."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Abrir com"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Abrir com %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Abrir"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Conceder acesso para abrir links de <xliff:g id="HOST">%1$s</xliff:g> com"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Conceder acesso para abrir links de <xliff:g id="HOST">%1$s</xliff:g> com o app <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Abrir links do domínio <xliff:g id="HOST">%1$s</xliff:g> com"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Abrir links com"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Abrir links com <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Abrir links do domínio <xliff:g id="HOST">%1$s</xliff:g> com <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Conceder acesso"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Editar com"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editar com %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro usar a porta USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Não há mais líquidos ou detritos detectados no smartphone."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"Localizar próximo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Localizar anterior"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitação de local de <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitação de local"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Pedido de localização"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Sim"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Não"</string>
@@ -1592,13 +1586,14 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Abrir Navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Aceitar chamada?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Definir como \"Sempre abrir\""</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Só uma vez"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Configurações"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s não aceita perfis de trabalho"</string>
     <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
     <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefone"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes da dock"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes na base"</string>
     <string name="default_audio_route_name_hdmi" msgid="1486254205617081251">"HDMI"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Fones de ouvido"</string>
     <string name="default_audio_route_name_usb" msgid="1234984851352637769">"USB"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição nº <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Esse início de atividade em segundo plano a partir de <xliff:g id="PACKAGENAME">%1$s</xliff:g> será bloqueado nas versões futuras do Android Q. Acesse g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"O início da atividade em segundo plano a partir de <xliff:g id="PACKAGENAME">%1$s</xliff:g> foi bloqueado. Acesse g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueci o padrão"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atalho de acessibilidade ativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atalho de acessibilidade desativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha um recurso a ser usado quando você toca no botão Acessibilidade:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar os recursos, mantenha o botão Acessibilidade pressionado."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolha um serviço a ser usado quando você toca no botão Acessibilidade:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para alternar entre serviços, toque no botão de acessibilidade e mantenha-o pressionado."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para alternar entre serviços, deslize de baixo para cima na tela com dois dedos sem soltar."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para alternar entre serviços, deslize de baixo para cima na tela com três dedos sem soltar."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Alternando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 7283db2..85fb7fd 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamadas Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chamadas Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Modo automóvel"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Estado da conta"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mensagens do programador"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mensagens importantes relativas a programadores"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Atualizações"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Estado da rede"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas da rede"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ícone de impressão digital"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gerir hardware de Desbloqueio Através do Rosto"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite à aplicação invocar métodos para adicionar e eliminar modelos faciais para uso."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"utilizar hardware de Desbloqueio Através do Rosto"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permite que a aplicação utilize hardware de Desbloqueio Através do Rosto para autenticação"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Desbloqueio Através do Rosto"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Volte a inscrever o seu rosto"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Para melhorar o reconhecimento, volte a inscrever o seu rosto."</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Imp. capt. dados rosto precisos. Tente novamente."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mova o telemóvel para a esquerda."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mova o telemóvel para a direita."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Olhe mais diretamente para o dispositivo."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Não é possível ver o seu rosto. Olhe p/ telemóvel."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Posicione o rosto em frente ao telemóvel."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Demasiado movimento. Mantenha o telemóvel firme."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Volte a inscrever o rosto."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Impossível reconhecer o rosto. Tente novamente."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Rode a cabeça um pouco menos."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Rode a cabeça um pouco menos."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Remova tudo o que esteja a ocultar o seu rosto."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Limpe o sensor na extremidade superior do ecrã."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Limpe a parte superior do ecrã, incluindo a barra preta."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Não pode validar o rosto. Hardware não disponível."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Experimente de novo o Desbloqueio Através do Rosto"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Não pode guardar novos dados de rostos. Elimine um antigo."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operação de rosto cancelada."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Desbloqueio Através do Rosto cancelado pelo utilizador"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Demasiadas tentativas. Tente novamente mais tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Demasiadas tentativas. O Desbloqueio Através do Rosto está desativado."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Não é possível validar o rosto. Tente novamente."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Não configurou o Desbloqueio Através do Rosto."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Desbloqueio Através do Rosto não suportado neste dispositivo."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Abrir com"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Abrir com %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Abrir"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Conceda acesso para abrir links de <xliff:g id="HOST">%1$s</xliff:g> com"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Conceda acesso para abrir links de <xliff:g id="HOST">%1$s</xliff:g> com a aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Abra os links de <xliff:g id="HOST">%1$s</xliff:g> com:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Abra os links com:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Abra os links com a aplicação <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Abra os links de <xliff:g id="HOST">%1$s</xliff:g> com a aplicação <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Conceder acesso"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Editar com"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editar com %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Efetue uma reposição de dados de fábrica para desativar o Modo de estrutura de teste."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Líquido ou resíduos na porta USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"A porta USB é automaticamente desativada. Toque para saber mais."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro utilizar a porta USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"O telemóvel já não deteta líquidos nem resíduos."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"A criar relatório de erro…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Pretende partilhar o relatório de erro?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Iniciar Navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Aceitar chamada?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Definir como abrir sempre"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Apenas uma vez"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Definições"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s não suporta o perfil de trabalho"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppp"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", protegido"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Este início da atividade em segundo plano do pacote <xliff:g id="PACKAGENAME">%1$s</xliff:g> será bloqueado em compilações futuras do Q. Aceda a g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Início da atividade em segundo plano do pacote <xliff:g id="PACKAGENAME">%1$s</xliff:g> bloqueado. Aceda a g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueceu-se da Sequência"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão Incorreto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Palavra-passe Incorreta"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O Atalho de acessibilidade ativou o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O Atalho de acessibilidade desativou o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Prima sem soltar as teclas de volume durante três segundos para utilizar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha uma funcionalidade para utilizar quando tocar no botão Acessibilidade:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar as funcionalidades, toque sem soltar no botão Acessibilidade."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolha o serviço a utilizar quando tocar no botão de acessibilidade:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha o serviço a utilizar com o gesto de acessibilidade (deslize rapidamente com dois dedos para cima a partir da parte inferior do ecrã):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha o serviço a utilizar com o gesto de acessibilidade (deslize rapidamente com três dedos para cima a partir da parte inferior do ecrã):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para alternar entre serviços, toque sem soltar no botão de acessibilidade."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para alternar entre serviços, deslize rapidamente com dois dedos para cima sem soltar."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para alternar entre serviços, deslize rapidamente com três dedos para cima sem soltar."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"A mudar para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 4dedb69..742fa81 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Chamada no Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Chamada por WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Chamada por WLAN de <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Modo carro"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Status da conta"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mensagens do desenvolvedor"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mensagens importantes do desenvolvedor"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Atualizações"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status de rede"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alertas de rede"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ícone de impressão digital"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"gerenciar hardware de desbloqueio facial"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite que o app execute métodos para adicionar e excluir modelos de rosto para uso."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"usar hardware de desbloqueio facial"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permite que o app use o hardware de desbloqueio facial para autenticação"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Desbloqueio facial"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Registre seu rosto novamente"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Para melhorar o reconhecimento, registre seu rosto novamente"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Dados precisos não capturados. Tente novamente."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mova o smartphone para a esquerda."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mova o smartphone para a direita."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Olhe mais diretamente para o dispositivo."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Não é possível ver o rosto. Olhe para o telefone."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Deixe o rosto diretamente na frente do smartphone."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Muito movimento. Não mova o smartphone."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registre seu rosto novamente."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"O rosto não é mais reconhecido. Tente novamente."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Incline a cabeça um pouco menos."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Incline a cabeça um pouco menos."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Remova tudo que esteja ocultando seu rosto."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Limpe o sensor na borda superior da tela."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Limpe a parte superior da tela, inclusive a barra preta"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Impossível verificar rosto. Hardware indisponível."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Tente usar o desbloqueio facial novamente."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Não é possível salvar dados faciais. Exclua dados antigos."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operação facial cancelada."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Desbloqueio facial cancelado pelo usuário."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Excesso de tentativas. Tente novamente mais tarde."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Muitas tentativas. Desbloqueio facial desativado."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Não é possível verificar o rosto. Tente novamente."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"O desbloqueio facial não foi configurado."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"O desbloqueio facial não é compatível com este dispositivo."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Rosto <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Abrir com"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Abrir com %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Abrir"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Conceder acesso para abrir links de <xliff:g id="HOST">%1$s</xliff:g> com"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Conceder acesso para abrir links de <xliff:g id="HOST">%1$s</xliff:g> com o app <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Abrir links do domínio <xliff:g id="HOST">%1$s</xliff:g> com"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Abrir links com"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Abrir links com <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Abrir links do domínio <xliff:g id="HOST">%1$s</xliff:g> com <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Conceder acesso"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Editar com"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editar com %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"É seguro usar a porta USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Não há mais líquidos ou detritos detectados no smartphone."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"Localizar próximo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Localizar anterior"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Solicitação de local de <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Solicitação de local"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Pedido de localização"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Solicitado por <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Sim"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Não"</string>
@@ -1592,13 +1586,14 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Abrir Navegador?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Aceitar chamada?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Definir como \"Sempre abrir\""</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Só uma vez"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Configurações"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s não aceita perfis de trabalho"</string>
     <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
     <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
     <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefone"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes da dock"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes na base"</string>
     <string name="default_audio_route_name_hdmi" msgid="1486254205617081251">"HDMI"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Fones de ouvido"</string>
     <string name="default_audio_route_name_usb" msgid="1234984851352637769">"USB"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Sobreposição nº <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", seguro"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Esse início de atividade em segundo plano a partir de <xliff:g id="PACKAGENAME">%1$s</xliff:g> será bloqueado nas versões futuras do Android Q. Acesse g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"O início da atividade em segundo plano a partir de <xliff:g id="PACKAGENAME">%1$s</xliff:g> foi bloqueado. Acesse g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Esqueci o padrão"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Padrão incorreto"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Senha incorreta"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"O atalho de acessibilidade ativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"O atalho de acessibilidade desativou o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Escolha um recurso a ser usado quando você toca no botão Acessibilidade:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Para alterar os recursos, mantenha o botão Acessibilidade pressionado."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Escolha um serviço a ser usado quando você toca no botão Acessibilidade:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Escolha um serviço a ser usado com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para alternar entre serviços, toque no botão de acessibilidade e mantenha-o pressionado."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para alternar entre serviços, deslize de baixo para cima na tela com dois dedos sem soltar."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para alternar entre serviços, deslize de baixo para cima na tela com três dedos sem soltar."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ampliação"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Alternando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 3c2e03e..2f464e9 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Apelare prin Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Apelare prin Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Apel WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Apel WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -259,6 +260,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Mod Mașină"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Starea contului"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mesaje pentru dezvoltatori"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mesaje importante pentru dezvoltatori"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Actualizări"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Starea rețelei"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Alerte privind rețeaua"</string>
@@ -552,15 +554,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Pictograma amprentă"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"să gestioneze hardware de deblocare facială"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Permite aplicației să invoce metode pentru a adăuga și a șterge șabloane faciale pentru utilizare."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"să folosească hardware de deblocare facială"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Permite aplicației să folosească hardware de deblocare facială pentru autentificare"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Deblocare facială"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Reînregistrați-vă chipul"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Pentru a îmbunătăți recunoașterea, reînregistrați-vă chipul"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Nu s-a putut fotografia fața cu precizie. Încercați din nou."</string>
@@ -573,7 +571,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Mutați telefonul spre stânga."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Mutați telefonul spre dreapta."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Priviți mai direct spre dispozitiv."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Nu vi se vede fața. Uitați-vă la telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Stați cu capul direct în fața telefonului."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Prea multă mișcare. Țineți telefonul nemișcat."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Reînregistrați-vă chipul."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Nu se mai poate recunoaște fața. Încercați din nou."</string>
@@ -582,24 +580,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Întoarceți capul mai puțin."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Întoarceți capul mai puțin."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Eliminați orice vă ascunde chipul."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Curățați senzorul de la marginea de sus a ecranului."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Curățați partea de sus a ecranului, inclusiv bara neagră"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Nu se poate confirma fața. Hardware-ul nu este disponibil."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Încercați din nou deblocarea facială."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Nu se pot stoca date faciale noi. Ștergeți întâi unele vechi."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operațiunea privind chipul a fost anulată."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Deblocarea facială este anulată de utilizator."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Prea multe încercări. Reîncercați mai târziu."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Prea multe încercări. Deblocarea facială este dezactivată."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nu se poate confirma fața. Încercați din nou."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Nu ați configurat deblocarea facială."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Deblocarea facială nu este acceptată pe dispozitiv."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Chip <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1158,8 +1151,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Deschideți cu"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Deschideți cu %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Deschideți"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Permiteți accesul pentru a deschide linkurile <xliff:g id="HOST">%1$s</xliff:g> cu"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Permiteți accesul pentru a deschide linkurile <xliff:g id="HOST">%1$s</xliff:g> cu <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Deschideți linkurile <xliff:g id="HOST">%1$s</xliff:g> cu"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Deschideți linkurile cu"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Deschideți linkurile cu <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Deschideți linkurile <xliff:g id="HOST">%1$s</xliff:g> cu <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Permiteți accesul"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Editați cu"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editați cu %1$s"</string>
@@ -1388,8 +1383,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Reveniți la setările din fabrică pentru a dezactiva modul Set de testare."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Portul USB poate fi folosit"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefonul nu mai detectează lichide sau reziduuri."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Se creează un raport de eroare…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Trimiteți raportul de eroare?"</string>
@@ -1615,6 +1609,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Lansați browserul?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Acceptați apelul?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Întotdeauna"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Schimbați la „Deschideți întotdeauna”"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Numai o dată"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Setări"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s nu acceptă profilul de serviciu"</string>
@@ -1644,8 +1639,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Suprapunerea <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", securizat"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Începerea activității în fundal de la <xliff:g id="PACKAGENAME">%1$s</xliff:g> va fi blocată în versiunile Q viitoare. Consultați g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Începerea activității din fundal de la <xliff:g id="PACKAGENAME">%1$s</xliff:g> este blocată. Consultați g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Model uitat"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Model greșit"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Parolă greșită"</string>
@@ -1700,8 +1693,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Comanda rapidă de accesibilitate a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Comanda rapidă de accesibilitate a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Apăsați ambele butoane de volum timp de trei secunde pentru a folosi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Alegeți o funcție pe care să o folosiți când atingeți butonul Accesibilitate:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Pentru a schimba funcțiile, atingeți lung butonul Accesibilitate."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Alegeți un serviciu pe care să îl folosiți când atingeți butonul de accesibilitate:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Alegeți un serviciu pe care să îl folosiți cu gestul de accesibilitate (glisați în sus cu două degete din partea de jos a ecranului):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Alegeți un serviciu pe care să îl folosiți cu gestul de accesibilitate (glisați în sus cu trei degete din partea de jos a ecranului):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Pentru a comuta între servicii, atingeți lung butonul de accesibilitate."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Pentru a schimba între servicii, glisați în sus cu două degete și țineți lung."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Pentru a schimba între servicii, glisați în sus cu trei degete și țineți lung."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Mărire"</string>
     <string name="user_switched" msgid="3768006783166984410">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Se comută la <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 936f463..c4b61b2 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Звонки по Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Звонок по Wi-Fi через оператора \"<xliff:g id="SPN">%s</xliff:g>\""</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Вызов WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> Вызов WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Режим \"В авто\""</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Статус аккаунта"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Сообщения для разработчиков"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Важные сообщения от разработчика"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Обновления"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Статус сети"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Оповещения сети"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Значок отпечатка пальца"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"Управление аппаратным обеспечением для функции \"Фейсконтроль\""</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Приложение сможет добавлять и удалять шаблоны лиц."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"Использование аппаратного обеспечения для функции \"Фейсконтроль\""</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Приложение сможет использовать для аутентификации аппаратное обеспечение Фейсконтроля."</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Фейсконтроль"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Зарегистрируйте лицо ещё раз"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Чтобы улучшить распознавание лица, зарегистрируйте его ещё раз"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Не удалось собрать данные. Повторите попытку."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Переместите телефон влево."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Переместите телефон вправо."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Смотрите прямо на устройство."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Вашего лица не видно. Смотрите на телефон."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Держите телефон прямо перед лицом."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Не перемещайте устройство. Держите его неподвижно."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Повторите попытку."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Не удалось распознать лицо. Повторите попытку."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Держите голову ровнее."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Держите голову ровнее."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Ваше лицо плохо видно."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Очистите сканер в верхней части экрана."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Протрите верхнюю часть экрана (в том числе черную панель)."</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Не удалось распознать лицо. Сканер недоступен."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Попробуйте воспользоваться функцией ещё раз."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Недостаточно места. Удалите старые данные для распознавания."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Распознавание отменено"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Фейсконтроль: операция отменена пользователем."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Слишком много попыток. Повторите позже."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Слишком много попыток. Функция \"Фейсконтроль\" отключена."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Не удалось распознать лицо. Повторите попытку."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Вы не настроили фейсконтроль."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Это устройство не поддерживает функцию \"Фейсконтроль\"."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Лицо <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Открыть с помощью приложения:"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Открыть с помощью приложения \"%1$s\""</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Открыть"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Предоставьте доступ, чтобы открывать ссылки <xliff:g id="HOST">%1$s</xliff:g> в приложении"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Предоставьте доступ, чтобы открывать ссылки <xliff:g id="HOST">%1$s</xliff:g> в приложении <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Открывать ссылки вида <xliff:g id="HOST">%1$s</xliff:g> с помощью:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Открывать ссылки с помощью:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Открывать ссылки в браузере <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Открывать ссылки вида <xliff:g id="HOST">%1$s</xliff:g> в браузере <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Открыть доступ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Редактировать с помощью приложения:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Редактировать с помощью приложения \"%1$s\""</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Чтобы отключить тестовый режим, сбросьте настройки до заводских."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"В USB-порт попала вода или грязь"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт был автоматически отключен. Нажмите, чтобы узнать подробности."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB-порт можно использовать"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Вода или грязь внутри не обнаружена."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Подготовка отчета об ошибке"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Разрешить доступ к информации об ошибке?"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустить браузер?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Ответить?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Всегда"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Всегда открывать"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Только сейчас"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Настройки"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s не поддерживает рабочие профили"</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Наложение № <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> х <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> тчк/дюйм"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безопасный"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Действия приложения \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" в фоновом режиме будут блокироваться в следующих сборках Android Q. Подробную информацию можно найти на странице g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Действие приложения \"<xliff:g id="PACKAGENAME">%1$s</xliff:g>\" в фоновом режиме заблокировано. Подробную информацию можно найти на странице g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Забыли графический ключ?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Неправильный графический ключ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Неправильный пароль"</string>
@@ -1724,8 +1717,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Сервис <xliff:g id="SERVICE_NAME">%1$s</xliff:g> включен"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Сервис <xliff:g id="SERVICE_NAME">%1$s</xliff:g> отключен"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Чтобы использовать сервис \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", нажмите и удерживайте обе клавиши громкости в течение трех секунд."</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Выберите функцию, которая запускается при нажатии кнопки специальных возможностей:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Чтобы изменить функцию, удерживайте кнопку специальных возможностей."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Выберите сервис, который будет запускаться при нажатии кнопки специальных возможностей:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Выберите сервис, который будет запускаться жестом для доступа к специальным возможностям (провести по экрану снизу вверх двумя пальцами):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Выберите сервис, который будет запускаться жестом для доступа к специальным возможностям (провести по экрану снизу вверх тремя пальцами):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Для переключения между сервисами нажмите и удерживайте кнопку специальных возможностей."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Для переключения между сервисами проведите по экрану снизу вверх двумя пальцами и задержите их."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Для переключения между сервисами проведите по экрану снизу вверх тремя пальцами и задержите их."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Увеличение"</string>
     <string name="user_switched" msgid="3768006783166984410">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Смена профиля на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index fc7f3ea..ddeb94b 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi ඇමතුම්"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> WiFi ඇමතුම"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN ඇමතුම"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN ඇමතුම්"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"මෝටර් රථ ආකාරය"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ගිණුම් තත්ත්වය"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"සංවර්ධක පණිවුඩ"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"වැදගත් සංවර්ධක පණිවුඩ"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"යාවත්කාලීන කිරීම්"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"ජාල තත්ත්වය"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"ජාල ඇඟවීම්"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"දුරකථනය වමට ගෙන යන්න."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"දුරකථනය දකුණට ගෙන යන්න."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"ඔබේ උපාංගය වෙත තවත් ඍජුව බලන්න."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"ඔබේ මුහුණ දැකිය නොහැක. දුරකථනය වෙත බලන්න."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"ඔබේ මුහුණ දුරකථනයට සෘජුවම ඉදිරියෙන් ස්ථානගත කරන්න."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"චලනය ඉතා වැඩියි. දුරකථනය ස්ථිරව අල්ලා සිටින්න."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"ඔබේ මුහුණ යළි ලියාපදිංචි කරන්න."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"තවදුරටත් මුහුණ හඳුනාගත නොහැක. නැවත උත්සාහ කරන්න."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"ඔබේ හිස ටිකක් අඩුවෙන් කරකවන්න."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"ඔබේ හිස ටිකක් අඩුවෙන් කරකවන්න."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"ඔබේ මුහුණ සඟවන කිසිවක් ඉවත් කරන්න."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"තිරයේ ඉහළ කෙළවරේ සංවේදකය පිරිසිදු කරන්න."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"කලු තීරුව ඇතුළුව, ඔබේ තිරයෙහි මුදුන පිරිසිදු කරන්න"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"මුහුණ සත්‍යාපනය කළ නොහැක. දෘඩාංගය නොමැත."</string>
@@ -1131,8 +1133,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"සමඟ විවෘත කරන්න"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s සමඟ විවෘත කරන්න"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"විවෘත කරන්න"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"මේවා මඟින් <xliff:g id="HOST">%1$s</xliff:g> සබැඳි විවෘත කිරීමට ප්‍රවේශය දෙන්න"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> මඟින් <xliff:g id="HOST">%1$s</xliff:g> සබැඳි විවෘත කිරීමට ප්‍රවේශය දෙන්න"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"සමග <xliff:g id="HOST">%1$s</xliff:g> සබැඳි විවෘත කරන්න"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"සමඟ සබැඳි විවෘත කරන්න"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> සමඟ සබැඳි විවෘත කරන්න"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="APPLICATION">%2$s</xliff:g> සමග <xliff:g id="HOST">%1$s</xliff:g> සබැඳි විවෘත කරන්න"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ප්‍රවේශය දෙන්න"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"සමඟ සංස්කරණය කරන්න"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s සමඟ සංස්කරණය කරන්න"</string>
@@ -1584,6 +1588,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"බ්‍රවුසරය දියත් කරන්නද?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"ඇමතුම පිළිගන්නවාද?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"සැම විටම"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"සැම විට විවෘත ලෙස සකසන්න"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"එක් වාරයයි"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"සැකසීම්"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s කාර්යාල පැතිකඩ සඳහා සහාය ලබනොදේ."</string>
@@ -1613,8 +1618,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"උඩැතිරිය #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ආරක්‍ෂිත"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> සිට ඇරඹෙන මෙම පසුබිම් ක්‍රියාකාරකම අනාගත Q නිමැවුම්වල අවහිර කෙරේ. g.co/dev/bgblock බලන්න."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> සිට ඇරඹෙන පසුබිම් ක්‍රියාකාරකම අවහිරයි. g.co/dev/bgblock බලන්න."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"රටාව අමතකයි"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"වැරදි රටාවකි"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"වැරදි මුරපදය"</string>
@@ -1668,8 +1671,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ප්‍රවේශ්‍යතා කෙටි මග <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාත්මක කරන ලදී"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ප්‍රවේශ්‍යතා කෙටි මග <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාවිරහිත කරන ලදී"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> භාවිත කිරීමට හඬ පරිමා යතුරු දෙකම තත්පර තුනකට ඔබාගෙන සිටින්න"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ඔබ ප්‍රවේශ්‍යතා බොත්තම තට්ටු කරන විට භාවිතා කිරීමට අංගයක් තෝරාගන්න:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"අංග වෙනස් කිරීමට ප්‍රවේශ්‍යතා බොත්තම ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ඔබ ප්‍රවේශ්‍යතා බොත්තම තට්ටු කරන විට භාවිතයට සේවාවක් තෝරා ගන්න:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ප්‍රවේශ්‍යතා ඉංගිතය සමඟ භාවිතයට සේවාවක් තෝරා ගන්න (ඇඟිලි දෙකක් සමඟින් තිරයේ පහළින් උඩට ස්වයිප් කරන්න):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ප්‍රවේශ්‍යතා ඉංගිතය සමඟ භාවිතයට සේවාවක් තෝරා ගන්න (ඇඟිලි තුනක් සමඟින් තිරයේ පහළින් උඩට ස්වයිප් කරන්න):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"සේවා අතර මාරු වීමට, ප්‍රවේශ්‍යතා බොත්තම ස්පර්ශ කර අල්ලා සිටින්න."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"සේවා අතර මාරු වීමට, ඇඟිලි දෙකක් සමඟින් උඩට ස්වයිප් කර අල්ලා සිටින්න."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"සේවා අතර මාරු වීමට, ඇඟිලි තුනක් සමඟින් උඩට ස්වයිප් කර අල්ලා සිටින්න."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"විශාලනය"</string>
     <string name="user_switched" msgid="3768006783166984410">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> වෙත මාරු කරමින්…"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 3a8136d..4d19308 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> volanie cez Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Volanie cez Wi‑Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Volanie cez WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> volanie cez WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Režim v aute"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Stav účtu"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Správy pre vývojárov"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Dôležité správy súvisiace s vývojármi"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Aktualizácie"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stav siete"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Upozornenia týkajúce sa siete"</string>
@@ -272,7 +274,7 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Predajná ukážka"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"Pripojenie USB"</string>
     <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Aplikácia je spustená"</string>
-    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikácie spotrebúvajú batériu"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Aplikácie spotrebúvajúce batériu"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> používa batériu"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Aplikácie (<xliff:g id="NUMBER">%1$d</xliff:g>) používajú batériu"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
@@ -301,7 +303,7 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; používať fotky, médiá a súbory v zariadení?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofón"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"nahrávanie zvuku"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; zaznamenávať zvuk?"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Chcete povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; nahrávať zvuk?"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Fyzická aktivita"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"prístup k vašej fyzickej aktivite"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; prístup k vašej fyzickej aktivite?"</string>
@@ -430,7 +432,7 @@
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"meniť nastavenia zvuku"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Umožňuje aplikácii upraviť globálne nastavenia zvuku, ako je hlasitosť, alebo určiť, z ktorého reproduktora bude zvuk vychádzať."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"nahrávať zvuk"</string>
-    <string name="permdesc_recordAudio" msgid="4245930455135321433">"Táto aplikácia môže kedykoľvek zaznamenávať zvuk pomocou mikrofónu."</string>
+    <string name="permdesc_recordAudio" msgid="4245930455135321433">"Táto aplikácia môže kedykoľvek nahrávať zvuk pomocou mikrofónu."</string>
     <string name="permlab_sim_communication" msgid="2935852302216852065">"posielanie príkazov do SIM karty"</string>
     <string name="permdesc_sim_communication" msgid="5725159654279639498">"Umožňuje aplikácii odosielať príkazy na SIM kartu. Toto je veľmi nebezpečné povolenie."</string>
     <string name="permlab_activityRecognition" msgid="3634590230567608356">"rozpoznávanie fyzickej aktivity"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona odtlačku prsta"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"spravovať hardvér odomknutia tvárou"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Umožňuje aplikácii vyvolať metódy, ktoré pridávajú a odstraňujú šablóny tvárí."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"používať hardvér Odomknutia tvárou"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Umožňuje aplikácii používať na overenie totožnosti hardvér Odomknutia tvárou"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Odomknutie tvárou"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Znova zaregistrujte svoju tvár"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Znova zaregistrujte svoju tvár, aby sa zlepšilo rozpoznávanie"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Nepodarilo sa nasnímať presné údaje o tvári. Skúste to znova."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Posuňte telefón doľava."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Posuňte telefón doprava."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Pozrite sa priamejšie na zariadenie."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Nie je vidieť vašu tvár. Pozrite sa na telefón."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Umiestnite svoju tvár priamo pred telefón."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Priveľa pohybu. Nehýbte telefónom."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Znova zaregistrujte svoju tvár."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Tvár už nie je možné rozpoznať. Skúste to znova."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Otočte hlavu o niečo menej."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Otočte hlavu o niečo menej."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Odstráňte všetko, čo vám zakrýva tvár."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Vyčistite senzor v hornom okraji obrazovky."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Vyčistite hornú časť obrazovky vrátane čierneho panela"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Tvár sa nedá overiť. Hardvér nie je k dispozícii."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Skúste znova použiť odomknutie tvárou."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Nové údaje o tvári sa nedajú uložiť. Najprv odstráňte jeden zo starých záznamov."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Operácia týkajúca sa tváre bola zrušená"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Odomknutie tvárou zrušil používateľ."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Príliš veľa pokusov. Skúste to znova neskôr."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Príliš veľa pokusov. Odomknutie tvárou bolo zakázané."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Nedá sa overiť tvár. Skúste to znova."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Nenastavili ste odomknutie tvárou."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Toto zariadenie nepodporuje odomknutie tvárou."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Tvár <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Otvoriť v aplikácii"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otvoriť v aplikácii %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Otvoriť"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Udeľte prístup na otváranie odkazov <xliff:g id="HOST">%1$s</xliff:g> pomocou aplikácie"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Udeľte prístup na otváranie odkazov <xliff:g id="HOST">%1$s</xliff:g> pomocou aplikácie <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Otvárajte odkazy z webu <xliff:g id="HOST">%1$s</xliff:g> v prehliadači alebo aplikácii"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Otvárajte odkazy v prehliadači"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Otvárajte odkazy v prehliadači <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Otvárajte odkazy z webu <xliff:g id="HOST">%1$s</xliff:g> v prehliadači <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Udeliť prístup"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Upraviť pomocou"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Upraviť v aplikácii %1$s"</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Ak chcete zakázať režim správcu testov, obnovte výrobné nastavenia."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Tekutina alebo nečistoty v porte USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Port USB je automaticky deaktivovaný. Ďalšie informácie zobrazíte klepnutím."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Port USB môžete použiť"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefón už nerozpoznáva tekutinu ani nečistoty."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Preberá sa hlásenie chyby…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Chcete zdieľať hlásenie chyby?"</string>
@@ -1549,7 +1543,7 @@
     <string name="find_next" msgid="5742124618942193978">"Nájsť ďalšiu"</string>
     <string name="find_previous" msgid="2196723669388360506">"Nájsť predchádzajúcu"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Žiadosť o informácie o polohe od používateľa <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Žiadosť o informácie o polohe"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Žiadosť o informácie o polohe"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Žiadosť od používateľa <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Áno"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Nie"</string>
@@ -1590,7 +1584,7 @@
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Aplikáciu <xliff:g id="APPLICATION_NAME">%s</xliff:g> nie je možné spustiť"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Zdieľať s"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Zdieľať s aplikáciou <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
-    <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvné tlačidlo. Dotknite sa a podržte."</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvník. Pridržte."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Posunom odomknúť."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Prejsť na plochu"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"Prejsť na"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Spustiť prehliadač?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Prijať hovor?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Nastaviť na Vždy otvárať"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Len raz"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Nastavenia"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"Spúšťač %1$s nepodporuje pracovné profily"</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Prekrytie č. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", zabezpečené"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Toto spustenie aktivity na pozadí v režime <xliff:g id="PACKAGENAME">%1$s</xliff:g> bude blokované v budúcich zostavách Q. Pozrite si informácie na g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Spustenie aktivity na pozadí v režime <xliff:g id="PACKAGENAME">%1$s</xliff:g> je blokované. Pozrite si informácie na g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nepamätám si vzor"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Nesprávny vzor"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nesprávne heslo"</string>
@@ -1724,8 +1717,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Skratka dostupnosti zapla službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Skratka dostupnosti vypla službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Ak chcete používať službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, pridržte tri sekundy oba klávesy hlasitosti"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Klepnutím na tlačidlo dostupnosti vyberte požadovanú funkciu:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ak chcete zmeniť funkcie, klepnite na tlačidlo dostupnosti a podržte ho"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Vyberte službu, ktorú chcete používať po klepnutí na tlačidlo dostupnosti:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Vyberte službu, ktorú chcete používať s daným gestom dostupnosti (potiahnutím dvoma prstami z dolnej časti obrazovky smerom nahor):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Vyberte službu aktivovanú daným gestom dostupnosti (potiahnutie troma prstami z dolnej časti obrazovky nahor):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Služby prepnete pridržaním tlačidla dostupnosti."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Služby prepnete potiahnutím dvoma prstami smerom nahor a pridržaním."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Služby prepnete potiahnutím troma prstami nahor a pridržaním."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Priblíženie"</string>
     <string name="user_switched" msgid="3768006783166984410">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 84e63cc..b2b3109 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Klicanje prek Wi-Fi-ja operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Klicanje prek Wi‑Fi-ja pri operaterju <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Klic prek omrežja WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Klic prek omrežja WLAN operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Način za avtomobil"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Stanje računa"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Sporočila razvijalcev"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Pomembna sporočila razvijalcem"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Posodobitve"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Stanje omrežja"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Opozorila omrežja"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona prstnih odtisov"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"upravljanje strojne opreme za odklepanje z obrazom"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Aplikaciji omogoča sprožanje načinov za dodajanje in brisanje predlog z obrazi za uporabo."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"uporaba strojne opreme za odklepanje z obrazom"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Aplikaciji omogoča uporabo strojne opreme za odklepanje z obrazom za preverj. pristnosti"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Odklepanje z obrazom"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Znova prijavite obraz"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Za izboljšanje prepoznavanja znova prijavite svoj obraz"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Točnih podatkov o obrazu ni bilo mogoče zajeti. Poskusite znova."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Telefon premaknite v levo."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Telefon premaknite v desno."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Glejte bolj naravnost v napravo."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Obraz ni viden. Poglejte v telefon."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Obraz nastavite naravnost pred telefon."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Preveč se premikate. Držite telefon pri miru."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Znova prijavite svoj obraz."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Obraza ni več mogoče prepoznati. Poskusite znova."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Malce manj nagnite glavo."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Glejte malce bolj naravnost."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Umaknite vse, kar vam morda zakriva obraz."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Očistite tipalo na zgornjem robu zaslona."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Očistite vrhnji del zaslona, vključno s črno vrstico"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Obraza ni mogoče preveriti. Str. opr. ni na voljo."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Znova izvedite odklepanje z obrazom."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Novega obraza ni mogoče shraniti. Najprej izbrišite starega."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Dejanje z obrazom je bilo preklicano."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Odklepanje z obrazom je preklical uporabnik."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Preveč poskusov. Poskusite znova pozneje."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Preveč poskusov. Odklepanje z obrazom je onemogočeno."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Obraza ni mogoče preveriti. Poskusite znova."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Odklepanja z obrazom niste nastavili."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Ta naprava ne podpira odklepanja z obrazom."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Obraz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Odpiranje z aplikacijo"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Odpiranje z aplikacijo %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Odpiranje"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Omogočanje dostopa za odpiranje povezav <xliff:g id="HOST">%1$s</xliff:g> z aplikacijo"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Omogočanje dostopa za odpiranje povezav <xliff:g id="HOST">%1$s</xliff:g> z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Odpiranje povezav <xliff:g id="HOST">%1$s</xliff:g> z"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Odpiranje povezav z"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Odpiranje povezav z aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Odpiranje povezav <xliff:g id="HOST">%1$s</xliff:g> z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Omogoči dostop"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Urejanje z aplikacijo"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Urejanje z aplikacijo %1$s"</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Če želite onemogočiti način preizkusnega ogrodja, ponastavite napravo na tovarniške nastavitve."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Vrata USB so varna za uporabo"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon ne zaznava več tekočine ali umazanije."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Zajemanje poročila o napakah …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite poslati poročilo o napakah?"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Ali želite odpreti brskalnik?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Ali želite sprejeti klic?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Vedno"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Nastavi na »vedno odpri«"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo tokrat"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Nastavitve"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ne podpira delovnega profila"</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Prekrivanje #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> pik na palec"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", varen"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ta zagon dejavnosti v ozadju za paket <xliff:g id="PACKAGENAME">%1$s</xliff:g> bo blokiran v prihodnjih različicah Androida Q. Za več informacij obiščite g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Zagon dejavnosti v ozadju za paket <xliff:g id="PACKAGENAME">%1$s</xliff:g> je bil blokiran. Za več informacij obiščite g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Pozabljen vzorec"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Napačen vzorec"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Napačno geslo"</string>
@@ -1724,8 +1717,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Bližnjica funkcij za ljudi s posebnimi potrebami je vklopila <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Bližnjica funkcij za ljudi s posebnimi potrebami je izklopila <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Za uporabo storitve <xliff:g id="SERVICE_NAME">%1$s</xliff:g> pritisnite obe tipki za glasnost in ju pridržite tri sekunde"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Izberite funkcijo, ki jo želite uporabljati, ko se dotaknete gumba »Dostopnost«:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Če želite spremeniti funkcije, se dotaknite gumba »Dostopnost« in ga pridržite."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Izberite storitev, ki jo želite uporabljati, ko se dotaknete gumba za funkcije za ljudi s posebnimi potrebami:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Izberite storitev, ki jo želite zagnati s potezo za ljudi s posebnimi potrebami (vlečenje z dvema prstoma z dna zaslona navzgor):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Izberite storitev, ki jo želite zagnati s potezo za ljudi s posebnimi potrebami (vlečenje s tremi prsti z dna zaslona navzgor):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Če želite preklopiti med storitvami, pridržite gumb za funkcije za ljudi s posebnimi potrebami."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Če želite preklopiti med storitvami, z dvema prstoma povlecite navzgor in pridržite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Če želite preklopiti med storitvami, s tremi prsti povlecite navzgor in pridržite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Povečava"</string>
     <string name="user_switched" msgid="3768006783166984410">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Preklop na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 202d090..afed336 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Telefonatë me Wi-Fi në <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Telefonatat me WiFi me <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Telefonatë me WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Telefonatë me WLAN në <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi në <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Modaliteti \"në makinë\""</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Statusi i llogarisë"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mesazhet e zhvilluesit"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mesazhe të rëndësishme të zhvilluesit"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Përditësimet"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Statusi i rrjetit"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Sinjalizimet e rrjetit"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona e gjurmës së gishtit"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"menaxho harduerin për shkyçjen me fytyrën"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Lejon aplikacionin të aktivizojë mënyra për shtim e fshirje të shablloneve të përdorura."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"përdor harduerin e shkyçjes me fytyrën"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Lejon aplikacionin të përdorë harduerin e shkyçjes me fytyrën për procesin e vërtetimit"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Shkyçja me fytyrë"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Regjistro përsëri fytyrën tënde"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Për të përmirësuar njohjen, regjistro përsëri fytyrën tënde"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"S\'mund të regjistroheshin të dhëna të sakta të fytyrës. Provo përsëri."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Lëvize telefonin majtas."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Lëvize telefonin djathtas"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Shiko më drejt në pajisjen tënde."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Fytyra jote nuk shfaqet. Shiko te telefoni."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Pozicionoje fytyrën tënde direkt përpara telefonit."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Ka shumë lëvizje. Mbaje telefonin të palëvizur."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Regjistroje përsëri fytyrën tënde."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Fytyra nuk mund të njihet më. Provo përsëri."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Ktheje kokën pak më pak."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Ktheje kokën pak më pak."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Hiq gjithçka që fsheh fytyrën tënde."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Pastro sensorin në anën e sipërme të ekranit."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Pastro kreun e ekranit, duke përfshirë shiritin e zi"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Fytyra s\'mund të verifikohet. Hardueri nuk ofrohet."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Provo përsëri shkyçjen me fytyrën."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"S\'mund të ruhen të dhëna të reja fytyre. Fshi një të vjetër në fillim."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Veprimi me fytyrën u anulua."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Shkyçja me fytyrë u anulua nga përdoruesi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Shumë përpjekje. Provo sërish më vonë."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Shumë përpjekje. Shkyçja me fytyrë u çaktivizua."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Fytyra nuk mund të verifikohet. Provo përsëri."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Nuk e ke konfiguruar shkyçjen me fytyrë."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Shkyçja me fytyrë nuk mbështetet në këtë pajisje"</string>
     <string name="face_name_template" msgid="7004562145809595384">"Fytyra <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Hap me"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Hap me %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Hap"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Jep qasje për të hapur lidhjet e <xliff:g id="HOST">%1$s</xliff:g> me"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Jep qasje për të hapur lidhjet e <xliff:g id="HOST">%1$s</xliff:g> me <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Hapi lidhjet e <xliff:g id="HOST">%1$s</xliff:g> me"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Hapi lidhjet me"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Hapi lidhjet me <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Hapi lidhjet e <xliff:g id="HOST">%1$s</xliff:g> me <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Jep qasje"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Redakto me"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Redakto me %1$s"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Kryej një rivendosje në cilësimet e fabrikës për të çaktivizuar \"Modalitetin e lidhjes së testimit\"."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Në rregulloj për përdorimin e portës USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefoni nuk i dallon më lëngjet apo papastërtitë."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Po merret raporti i defekteve në kod…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Të ndahet raporti i defektit në kod?"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Të hapet shfletuesi?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Dëshiron ta pranosh telefonatën?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Gjithmonë"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Caktoje si gjithmonë të hapur"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Vetëm një herë"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Cilësimet"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s nuk e mbështet profilin e punës"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Mbivendosja #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> ppi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", i sigurt"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Kjo nisje e aktivitetit në sfond nga <xliff:g id="PACKAGENAME">%1$s</xliff:g> do të bllokohet në ndërtimet e ardhshme të Q. Shiko g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Nisja e aktivitetit në sfond nga <xliff:g id="PACKAGENAME">%1$s</xliff:g> u bllokua. Shiko g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Harrova motivin"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Motivi është i gabuar"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Fjalëkalim i gabuar"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Shkurtorja e qasshmërisë e aktivizoi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Shkurtorja e qasshmërisë e çaktivizoi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Shtyp dhe mbaj shtypur të dy butonat e volumit për tre sekonda për të përdorur <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Zgjidh një funksion për ta përdorur kur troket butonin e \"Qasshmërisë\":"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Për të ndryshuar funksionet, prek dhe mbaj butonin e \"Qasshmërisë\"."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Zgjidh një shërbim për ta përdorur kur troket butonin e qasshmërisë:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Zgjidh një shërbim për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me dy gishta):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Zgjidh një shërbim për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me tre gishta):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Për të kaluar mes shërbimeve, prek dhe mbaj prekur butonin e qasshmërisë."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Për të kaluar mes pajisjeve, rrëshqit shpejt lart me dy gishta dhe mbaje prekur."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Për të kaluar mes pajisjeve, rrëshqit shpejt lart me tre gishta dhe mbaje prekur."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Zmadhimi"</string>
     <string name="user_switched" msgid="3768006783166984410">"Emri i përdoruesit aktual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Po kalon në <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 812af02..110b31d 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -132,6 +132,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> позивање преко Wi-Fi-ја"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> – позивање преко Wi-Fi-ја"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN позив"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN позив"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -259,6 +260,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Режим рада у аутомобилу"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Статус налога"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Поруке за програмере"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Важне поруке програмера"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Ажурирања"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Статус мреже"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Обавештења у вези са мрежом"</string>
@@ -268,7 +270,7 @@
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Обавештења"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Режим демонстрације за малопродајне објекте"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB веза"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Апликација је покренута"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Активна апликација"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Апликације које троше батерију"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи батерију"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) користе батерију"</string>
@@ -552,15 +554,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Икона отиска прста"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"управљање хардв. за откључавање лицем"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Дозвољава да апликација активира методе за додавање и брисање шаблона лица ради коришћења."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"коришћење хардвера за откључавање лицем"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Дозвољава да апликација користи хардвер за откључавање лицем ради потврде идентитета"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Откључавање лицем"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Поново региструјте лице"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Да бисте побољшали препознавање, поново региструјте лице"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Снимање лица није успело. Пробајте поново."</string>
@@ -573,7 +571,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Померите телефон улево."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Померите телефон удесно."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Гледајте право у уређај."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Не види се лице. Гледајте у телефон."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Поставите лице директно испред телефона"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Много се померате. Држите телефон мирно."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Поново региструјте лице."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Више не може да се препозна лице. Пробајте поново."</string>
@@ -582,24 +580,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Мало мање померите главу."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Мало мање померите главу."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Уклоните све што вам заклања лице."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Очистите сензор на горњој ивици екрана."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Очистите горњи део екрана, укључујући црну траку"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Провера лица није успела. Хардвер није доступан."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Пробајте поново откључавање лицем."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Нови подаци о лицу нису сачувани. Прво избришете претходне."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Обрада лица је отказана."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Корисник је отказао откључавање лицем"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Превише покушаја. Пробајте поново касније."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Превише покушаја. Откључавање лицем је онемогућено."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Провера лица није успела. Пробајте поново."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Нисте подесили откључавање лицем"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Откључавање лицем није подржано на овом уређају"</string>
     <string name="face_name_template" msgid="7004562145809595384">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1158,8 +1151,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Отворите помоћу"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Отворите помоћу апликације %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Отвори"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Дозволите да се линкови <xliff:g id="HOST">%1$s</xliff:g> отварају помоћу"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Дозволите да <xliff:g id="APPLICATION">%2$s</xliff:g> отвара линикове <xliff:g id="HOST">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Отварајте <xliff:g id="HOST">%1$s</xliff:g> линкове помоћу"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Отваратеј линкове помоћу"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Отварајте линкове помоћу апликације <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Отварајте <xliff:g id="HOST">%1$s</xliff:g> линкове помоћу апликације <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Дозволи приступ"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Измените помоћу"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Измените помоћу апликације %1$s"</string>
@@ -1388,8 +1383,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Течност или нечистоћа у USB порту"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB порт је аутоматски искључен. Додирните да бисте сазнали више."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Коришћење USB порта је дозвољено"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефон више не открива течност или нечистоћу."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Извештај о грешци се генерише…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Желите ли да поделите извештај о грешци?"</string>
@@ -1615,6 +1609,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Желите ли да покренете прегледач?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Желите ли да прихватите позив?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Увек"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Подеси на „увек отварај“"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Само једном"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Подешавања"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s не подржава пословни профил"</string>
@@ -1644,8 +1639,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Постављени елемент бр. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>×<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безбедно"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Ово покретање активности у позадини са <xliff:g id="PACKAGENAME">%1$s</xliff:g> биће блокирано у будућим Q верзијама. Погледајте g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Покретање активности у позадини са <xliff:g id="PACKAGENAME">%1$s</xliff:g> је блокирано. Погледајте g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Заборављени шаблон"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Погрешан шаблон"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Погрешна лозинка"</string>
@@ -1700,8 +1693,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Пречица за приступачност је укључила услугу <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Пречица за приступачност је искључила услугу <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Притисните и задржите оба тастера за јачину звука три секунде да бисте користили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Изаберите функцију која ће се користити када додирнете дугме за приступачност:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Притисните и задржите дугме за приступачност да бисте мењали функције."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Одаберите услугу која ће се користити када додирнете дугме за приступачност:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу два прста превуците нагоре од дна екрана):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Одаберите услугу која ће се користити помоћу покрета за приступачност (помоћу три прста превуците нагоре од дна екрана):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Да бисте прелазили са једне услуге на другу, додирните и задржите дугме за приступачност."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Да бисте прелазили са једне услуге на другу, превуците нагоре помоћу два прста и задржите."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Да бисте прелазили са једне услуге на другу, превуците нагоре помоћу три прста и задржите."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Увећање"</string>
     <string name="user_switched" msgid="3768006783166984410">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index b3e95f9..bc1752e 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Wi-Fi-samtal via <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Wi-Fi-samtal med <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN-samtal"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"WLAN-samtal via <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi via <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Billäge"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Kontostatus"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Meddelanden till utvecklare"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Viktiga meddelanden till utvecklare"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Uppdateringar"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Nätverksstatus"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Nätverksvarningar"</string>
@@ -295,7 +297,7 @@
     <string name="permgrouprequest_storage" msgid="7885942926944299560">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomst till foton, mediefiler och andra filer på enheten?"</string>
     <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
     <string name="permgroupdesc_microphone" msgid="4988812113943554584">"spela in ljud"</string>
-    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>n&lt;/b&gt; behörighet att spela in ljud?"</string>
+    <string name="permgrouprequest_microphone" msgid="9167492350681916038">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; behörighet att spela in ljud?"</string>
     <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"Fysiska aktivitet"</string>
     <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"åtkomst till data om fysisk aktivitet"</string>
     <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"Vill du ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to åtkomst till data om fysisk aktivitet?"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikon för fingeravtryck"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"hantera maskinvara för ansiktslås"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Tillåter att appen anropar metoder för att lägga till och radera ansiktsmallar."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"använd maskinvara för ansiktslås"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Tillåter att appen använder maskinvara för ansiktslås vid autentisering"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Ansiktslås"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Registrera ansiktet på nytt"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Gör om registreringen av ansiktet så att ansiktsigenkänningen ska fungera bättre"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Det gick inte att fånga ansiktsdata. Försök igen."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Flytta mobilen åt vänster."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Flytta mobilen åt höger."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Titta rakt på enheten."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Ansiktet syns inte. Titta på mobilen."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Ha ansiktet direkt framför telefonen."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"För mycket rörelse. Håll mobilen stilla."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Registrera ansiktet på nytt."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ansiktet kan inte längre kännas igen. Försök igen."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Vrid mindre på huvudet."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Vrid mindre på huvudet."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Ta bort allt som täcker ansiktet."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Rengör sensorn på skärmens överkant."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Rengör skärmens överkant, inklusive det svarta fältet"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Ansiktsverifiering går ej. Otillgänglig maskinvara."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Försök att använda ansiktslåset igen."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Kan inte lagra ny ansiktsdata. Radera först gammal data."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Ansiktsåtgärden har avbrutits."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Ansiktslås 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>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"För många försök. Ansiktslås har inaktiverats."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Det gick inte att verifiera ansiktet. Försök igen."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Du har inte konfigurerat ansiktslås."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Ansiktslås stöds inte på den här enheten."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Ansikte <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Expandera upplåsningsytan."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Lås upp genom att dra."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Lås upp med grafiskt lösenord."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Lås upp med Ansiktslås."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Ansiktslås."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Lås upp med PIN-kod."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"Lås upp med SIM-kortets pinkod."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"Lås upp med SIM-kortets PUK-kod."</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Öppna med"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Öppna med %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Öppna"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Tillåt att länkar från <xliff:g id="HOST">%1$s</xliff:g> öppnas med"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Tillåt att länkar från <xliff:g id="HOST">%1$s</xliff:g> öppnas med <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Öppna länkar på <xliff:g id="HOST">%1$s</xliff:g> med"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Öppna länkar med"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Öppna länkar med <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Öppna länkar på <xliff:g id="HOST">%1$s</xliff:g> med <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Ge åtkomst"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Redigera med"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Redigera med %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Inaktivera testverktygsläget genom att göra en återställning till standardinställningarna."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Nu kan du använda USB-porten"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Mobilen känner inte längre av någon vätska eller smuts."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Felrapporten överförs …"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vill du dela felrapporten?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"Sök nästa"</string>
     <string name="find_previous" msgid="2196723669388360506">"Sök föregående"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Positionsförfrågan från <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Positionsförfrågan"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Platsförfrågan"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Begärt av <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Nej"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Vill du öppna webbläsaren?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Vill du ta emot samtal?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Alltid"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Ställ in på att alltid öppnas"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Bara en gång"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Inställningar"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s har inte stöd för arbetsprofil"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Överlagring #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g> x <xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", säker"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Denna bakgrundsaktivitet som startar från <xliff:g id="PACKAGENAME">%1$s</xliff:g> blockeras i framtida Q-versioner. Läs mer på g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Start av bakgrundsaktivitet från <xliff:g id="PACKAGENAME">%1$s</xliff:g> blockerades. Läs mer på g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Har du glömt ditt grafiska lösenord?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Fel grafiskt lösenord"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Fel lösenord"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiverades av Aktivera tillgänglighet snabbt"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> inaktiverades av Aktivera tillgänglighet snabbt"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Tryck och håll båda volymknapparna i tre sekunder för att använda <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Välj en funktion som ska användas när du trycker på tillgänglighetsknappen:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Tryck länge på tillgänglighetsknappen för att ändra funktioner."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Välj en tjänst som ska användas när du trycker på tillgänglighetsknappen:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Välj en tjänst som ska användas med tillgänglighetsrörelsen (svepa uppåt med två fingrar från skärmens nederkant):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Välj en tjänst som ska användas med tillgänglighetsrörelsen (svepa uppåt med tre fingrar från skärmens nederkant):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Byt mellan tjänster genom att trycka länge på tillgänglighetsknappen."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Byt mellan tjänster genom att svepa uppåt med två fingrar och hålla kvar dem."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Byt mellan tjänster genom att svepa uppåt med tre fingrar och hålla kvar dem."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Förstoring"</string>
     <string name="user_switched" msgid="3768006783166984410">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Byter till <xliff:g id="NAME">%1$s</xliff:g> …"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index b18543e..92510ea 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Kupiga Simu Kupitia Wi-Fi ya <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Kupiga Simu Kupitia WiFi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Simu ya WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Simu ya WLAN ya <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ya <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Hali ya gari"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Hali ya akaunti"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Ujumbe wa wasanidi programu"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Ujumbe muhimu kwa wasanidi programu"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Taarifa"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Hali ya mtandao"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Arifa za mtandao"</string>
@@ -307,7 +309,7 @@
     <string name="permgrouprequest_calllog" msgid="8487355309583773267">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie rekodi zako za nambari za simu?"</string>
     <string name="permgrouplab_phone" msgid="5229115638567440675">"Simu"</string>
     <string name="permgroupdesc_phone" msgid="6234224354060641055">"piga na udhibiti simu"</string>
-    <string name="permgrouprequest_phone" msgid="9166979577750581037">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ipige na kudhibiti simu?"</string>
+    <string name="permgrouprequest_phone" msgid="9166979577750581037">"Ungependa kuruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; kupiga na kudhibiti simu?"</string>
     <string name="permgrouplab_sensors" msgid="4838614103153567532">"Vihisi vya mwili"</string>
     <string name="permgroupdesc_sensors" msgid="7147968539346634043">"fikia data ya kitambuzi kuhusu alama zako muhimu"</string>
     <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie data ya vitambuzi kuhusu viashiria muhimu vya mwili wako?"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Aikoni ya kitambulisho"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"dhibiti maunzi ya kufungua kwa uso"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Huruhusu programu iombe njia za kuongeza na kufuta violezo vya uso vitakavyotumiwa."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"tumia maunzi ya kufungua kwa uso"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Huruhusu programu itumie maunzi ya kufungua kwa uso ili kuthibitisha"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Kufungua kwa uso"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Sajili uso wako tena"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Ili kuimarisha utambuzi, tafadhali sajili uso wako tena"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Imeshindwa kunasa data sahihi ya uso. Jaribu tena."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Sogeza simu upande wa kushoto."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Sogeza simu upande wa kulia."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Tafadhali angalia kifaa chako moja kwa moja."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Imeshindwa kuona uso wako. Angalia simu."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Weka uso wako moja kwa moja mbele ya simu."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Inatikisika sana. Ishike simu iwe thabiti."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Tafadhali sajili uso wako tena."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Haiwezi tena kutambua uso. Jaribu tena."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Geuza kichwa chako kidogo."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Geuza kichwa chako kidogo."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Ondoa kitu chochote kinachoficha uso wako."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Safisha kitambuzi kwenye ukingo wa juu wa skrini."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Safisha sehemu ya juu ya skrini yako, ikiwa ni pamoja na upau mweusi"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Imeshindwa kuthibitisha uso. Maunzi hayapatikani."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Jaribu kufungua kwa uso tena."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Imeshindwa kuhifadhi data ya uso mpya. Futa wa kale kwanza."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Utendaji wa kitambulisho umeghairiwa."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Kufungua kwa uso kumeghairiwa na mtumiaji."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Umejaribu mara nyingi mno. Jaribu tena baadaye."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Umejaribu mara nyingi mno. Kipengele cha kufungua kwa uso kimezimwa."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Imeshindwa kuthibitisha uso. Jaribu tena."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Hujaweka mipangilio ya kufungua kwa uso."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Kufungua kwa uso hakutumiki kwenye kifaa hiki."</string>
     <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>
@@ -691,9 +684,9 @@
     <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Kuzima baadhi ya vipengele vya kufunga skrini"</string>
     <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Zuia matumizi ya baadhi ya vipengele vya kufunga skrini."</string>
   <string-array name="phoneTypes">
-    <item msgid="8901098336658710359">"Nyumbani"</item>
+    <item msgid="8901098336658710359">"Ya nyumbani"</item>
     <item msgid="869923650527136615">"Simu ya mkononi"</item>
-    <item msgid="7897544654242874543">"Kazi"</item>
+    <item msgid="7897544654242874543">"Ya kazini"</item>
     <item msgid="1103601433382158155">"Pepesi ya Kazini"</item>
     <item msgid="1735177144948329370">"Pepesi ya Nyumbani"</item>
     <item msgid="603878674477207394">"Kurasa anwani"</item>
@@ -734,9 +727,9 @@
     <item msgid="1648797903785279353">"Jabber"</item>
   </string-array>
     <string name="phoneTypeCustom" msgid="1644738059053355820">"Maalum"</string>
-    <string name="phoneTypeHome" msgid="2570923463033985887">"Nyumbani"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Ya nyumbani"</string>
     <string name="phoneTypeMobile" msgid="6501463557754751037">"Simu ya mkononi"</string>
-    <string name="phoneTypeWork" msgid="8863939667059911633">"Kazi"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Ya kazini"</string>
     <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Pepesi ya Kazini"</string>
     <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Pepesi ya Nyumbani"</string>
     <string name="phoneTypePager" msgid="7582359955394921732">"Peja"</string>
@@ -825,7 +818,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Jaribu tena"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Jaribu tena"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"Fungua kifaa ili upate data na vipengele vyote"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Majaribio ya Juu ya Kufungua Uso yamezidishwa"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Umepitisha idadi ya juu ya mara ambazo unaweza kujaribu Kufungua kwa Uso"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Hakuna SIM kadi"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Hakuna SIM kadi katika kompyuta ndogo."</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Hakuna SIM kadi katika runinga."</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Fungua ukitumia"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Fungua ukitumia %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Fungua"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Ipe <xliff:g id="HOST">%1$s</xliff:g> ruhusa ya kufungua viungo kwa kutumia"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Ipe <xliff:g id="HOST">%1$s</xliff:g> ruhusa ya kufungua viungo kwa kutumia <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Fungua viungo vya <xliff:g id="HOST">%1$s</xliff:g> ukitumia"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Fungua viungo ukitumia"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Fungua viungo ukitumia <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Fungua viungo vya <xliff:g id="HOST">%1$s</xliff:g> ukitumia <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Idhinisha ufikiaji"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Badilisha kwa"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Badilisha kwa %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rejesha mipangilio iliyotoka nayo kiwandani ili uzime hali ya Muunganisho wa Majaribio."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ni sawa kutumia mlango wa USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Simu haitambui tena unyevu au uchafu."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Inatayarisha ripoti ya hitilafu…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Ungependa kushiriki ripoti ya hitilafu?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"Pata ifuatayo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Pata iliyotangulia"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Ombi la mahali kutoka <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Ombi la mahali"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Ombi la kutambua mahali"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Imeombwa na <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ndiyo"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Hapana"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Zindua Kivinjari?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Kubali simu?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Kila mara"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Weka ifunguke kila wakati"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Mara moja tu"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Mipangilio"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s haitumii wasifu wa kazini"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Uwekeleaji #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", salama"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Itazuia shughuli hii ya chinichini inayoanzia <xliff:g id="PACKAGENAME">%1$s</xliff:g> katika miundo ya baadaye ya Q. Angalia g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Imezuia shughuli za chinichini zinazoanzia <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Angalia g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Umesahau Ruwaza"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Mchoro huo si sahihi"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Nenosiri Lisilo sahihi"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Njia ya mkato ya zana za walio na matatizo ya kuona au kusikia imewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Njia ya mkato ya zana za walio na matatizo ya kuona au kusikia imezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Bonyeza na ushikilie vitufe vyote viwili vya sauti kwa sekunde tatu ili utumie <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Chagua kipengele utakachotumia, ukigusa kitufe cha Ufikivu:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ili kubadilisha vipengele, gusa na ushikilie kitufe cha Ufikivu."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Chagua huduma ya kutumia unapogusa kitufe cha ufikivu:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Chagua huduma ya kutumia pamoja na ishara ya ufikivu (telezesha vidole viwili kutoka chini kwenda juu kwenye skrini):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Chagua huduma ya kutumia pamoja na ishara ya ufikivu (telezesha kutoka chini kwenda juu kwenye skrini kwa vidole vitatu):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Ili ubadilishe kati ya huduma, gusa na ushikilie kitufe cha ufikivu."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Ili ubadilishe kati ya huduma, telezesha vidole viwili juu na ushikilie."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Ili ubadilishe kati ya huduma, telezesha vidole vitatu juu na ushikilie."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ukuzaji"</string>
     <string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Inabadili kwenda <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1910,7 +1907,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Angalia masasisho"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Una ujumbe mpya"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Fungua programu ya SMS ili uweze kuangalia"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Huenda ikadhibiti baadhi ya vipengele"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Huenda baadhi ya vipengele vinadhibitiwa"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Wasifu wa kazini umefungwa"</string>
     <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>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 3215fec..8ddcfe6 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> வைஃபை அழைப்பு"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> வைஃபை அழைப்பு"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN அழைப்பு"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN அழைப்பு"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> வைஃபை"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"கார் பயன்முறை"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"கணக்கின் நிலை"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"டெவெலப்பர் செய்திகள்"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"டெவெலப்பருக்கான முக்கிய தகவல்கள்"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"புதுப்பிப்புகள்"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"நெட்வொர்க்கின் நிலை"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"நெட்வொர்க் விழிப்பூட்டல்கள்"</string>
@@ -266,7 +268,7 @@
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"விற்பனையாளர் டெமோ"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB இணைப்பு"</string>
     <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"ஆப்ஸ் இயங்குகிறது"</string>
-    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"பேட்டரியைப் பயன்படுத்தும் பயன்பாடுகள்"</string>
+    <string name="notification_channel_foreground_service" msgid="3931987440602669158">"பேட்டரியைப் பயன்படுத்தும் ஆப்ஸ்"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் பேட்டரியைப் பயன்படுத்துகிறது"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பேட்டரியைப் பயன்படுத்துகின்றன"</string>
     <string name="foreground_service_tap_for_details" msgid="372046743534354644">"பேட்டரி மற்றும் டேட்டா உபயோக விவரங்களைக் காண, தட்டவும்"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"கைரேகை ஐகான்"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"\'முகம் காட்டித் திறத்தலுக்கான\' வன்பொருளை நிர்வகித்தல்"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"உபயோகிப்பதற்காக முக டெம்ப்ளேட்டுகளை சேர்க்கும்/நீக்கும் முறைகளை இயக்க, ஆப்ஸை அனுமதிக்கும்."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"’முகம் காட்டித் திறத்தல்’ அம்சத்திற்கான வன்பொருளைப் பயன்படுத்துதல்"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"அடையாளம் காண \'முகம் காட்டித் திறத்தலுக்கான\' வன்பொருளைப் பயன்படுத்த ஆப்ஸை அனுமதிக்கும்"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"முகம் காட்டித் திறத்தல்"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"முகத்தை மீண்டும் பதிவுசெய்யவும்"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"அடையாளத்தை மேம்படுத்த முகத்தை மீண்டும் பதிவுசெய்யவும்"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"முகம் தெளிவாகப் பதிவாகவில்லை. மீண்டும் முயலவும்."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"மொபைலை இடப்புறம் நகர்த்தவும்."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"மொபைலை வலப்புறம் நகர்த்தவும்."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"முழுமுகம் தெரியுமாறு நேராகப் பார்க்கவும்."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"முகம் சரியாகத் தெரியவில்லை. மொபைலைப் பார்க்கவும்."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"முகத்தை மொபைலுக்கு நேராக வைக்கவும்."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"அதிகமாக அசைகிறது. மொபைலை அசைக்காமல் பிடிக்கவும்."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"உங்கள் முகத்தை மீண்டும் பதிவுசெய்யுங்கள்."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"முகத்தைக் கண்டறிய இயலவில்லை. மீண்டும் முயலவும்."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"தலையை லேசாகத் திருப்பவும்."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"உங்கள் தலையைச் சற்றுத் திருப்பவும்."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"உங்கள் முகத்தை மறைக்கும் அனைத்தையும் நீக்குக."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"திரையின் மேல்முனையிலுள்ள சென்சாரைச் சுத்தம் செய்க."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"திரையையும் அதிலுள்ள கருப்புப் பட்டியையும் சுத்தம் செய்யவும்"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"முகத்தைச் சரிபார்க்க இயலவில்லை. வன்பொருள் இல்லை."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"\'முகம் காட்டித் திறத்தலை\' மீண்டும் முயலவும்."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"புதிய முகங்களைச் சேர்க்க இயலவில்லை. பழையது ஒன்றை நீக்கவும்."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"முக அங்கீகாரச் செயல்பாடு ரத்துசெய்யப்பட்டது."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"\'முகம் காட்டித் திறத்தல்\' பயனரால் ரத்துசெய்யப்பட்டது."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"பலமுறை முயன்றுவிட்டீர்கள். பிறகு முயலவும்."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"பலமுறை முயன்றுவிட்டீர்கள். \'முகம் காட்டித் திறத்தல்’ முடக்கப்பட்டது."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"முகத்தைச் சரிபார்க்க இயலவில்லை. மீண்டும் முயலவும்."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"’முகம் காட்டித் திறத்தலை’ நீங்கள் அமைக்கவில்லை."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"இந்த சாதனத்தில் ’முகம் காட்டித் திறத்தல்’ ஆதரிக்கப்படவில்லை."</string>
     <string name="face_name_template" msgid="7004562145809595384">"முகம் <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"திறப்பதற்கான பகுதியை விவரிக்கவும்."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"ஸ்லைடு மூலம் திறத்தல்."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"வடிவம் மூலம் திறத்தல்."</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"முகத்தால் திறத்தல்."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"முகம் காட்டித் திறத்தல்."</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin மூலம் திறத்தல்."</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"சிம்மைத் திறக்கும் பின்."</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"சிம்மைத் திறக்கும் Puk."</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"இதன்மூலம் திற"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s மூலம் திற"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"திற"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"மூலம் <xliff:g id="HOST">%1$s</xliff:g> இணைப்புகளைத் திறப்பதற்கான அணுகலை வழங்குதல்"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> மூலம் <xliff:g id="HOST">%1$s</xliff:g> இணைப்புகளைத் திறப்பதற்கான அணுகலை வழங்குதல்"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> இணைப்புகளை இதன் மூலம் திற:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"இணைப்புகளை இதன் மூலம் திற:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"இணைப்புகளை <xliff:g id="APPLICATION">%1$s</xliff:g> ஆப்ஸில் திறத்தல்"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> இணைப்புகளை <xliff:g id="APPLICATION">%2$s</xliff:g> ஆப்ஸில் திறத்தல்"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"அணுகலை வழங்கு"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"இதன் மூலம் திருத்து"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s மூலம் திருத்து"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"’தன்னியக்க சோதனைப்\' பயன்முறையை முடக்க ஆரம்பநிலைக்கு மீட்டமைக்கவும்."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB போர்ட்டில் சேதம் உள்ளது"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB போர்ட் தானாகவே முடக்கப்பட்டது மேலும் அறிய, தட்டவும்."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB போர்ட்டைப் பயன்படுத்தலாம்"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"மொபைலில் எந்தச் சேதாரமும் கண்டறியப்படவில்லை."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"பிழை அறிக்கையை எடுக்கிறது…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"பிழை அறிக்கையைப் பகிரவா?"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"உலாவியைத் துவக்கவா?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"அழைப்பை ஏற்கவா?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"எப்போதும்"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"எப்போதும் திறக்குமாறு அமைத்தல்"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"இப்போது மட்டும்"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"அமைப்புகள்"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s பணிக் கணக்கை ஆதரிக்காது"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"மேலோட்ட #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", பாதுகாப்பானது"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>மின் \'பின்னணிச் செயல்பாடுத் தொடக்கம்\' இனிவரும் Q பதிப்புகளில் தடுக்கப்படும். g.co/dev/bgblock என்ற இணைப்பைப் பார்க்கவும்."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g>மில் \'பின்னணிச் செயல்பாட்டுத் தொடக்கம்\' தடுக்கப்பட்டுள்ளது. g.co/dev/bgblock என்ற இணைப்பைப் பார்க்கவும்."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"வடிவத்தை மறந்துவிட்டீர்களா"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"தவறான வடிவம்"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"தவறான கடவுச்சொல்"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"அணுகல்தன்மை ஷார்ட்கட்டானது <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐ இயக்கியது"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"அணுகல்தன்மை ஷார்ட்கட்டானது <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐ முடக்கியது"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐப் பயன்படுத்த 3 விநாடிகளுக்கு இரண்டு ஒலியளவு பட்டன்களையும் அழுத்திப் பிடிக்கவும்"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"அணுகல்தன்மை பட்டனைத் தட்டி, பயன்படுத்துவதற்கான அம்சத்தைத் தேர்ந்தெடுக்கவும்:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"அம்சங்களை மாற்ற, அணுகல்தன்மை பட்டனைத் தொட்டுப் பிடித்திருக்கவும்."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"அணுகல்தன்மை பட்டனுக்கான சேவையைத் தேர்வுசெய்யவும்:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"அணுகல்தன்மை சைகைக்கான சேவையைத் தேர்வுசெய்யவும் (இரண்டு விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"அணுகல்தன்மை சைகைக்கான சேவையைத் தேர்வுசெய்யவும் (மூன்று விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"சேவைகளுக்கு இடையே மாற அணுகல்தன்மை பட்டனைத் தொட்டுப் பிடிக்கவும்."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"சேவைகளுக்கு இடையே மாற இரண்டு விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"சேவைகளுக்கு இடையே மாற மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடிக்கவும்."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"பெரிதாக்கல்"</string>
     <string name="user_switched" msgid="3768006783166984410">"நடப்பு பயனர் <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>க்கு மாறுகிறது…"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 908f10d..649e17c 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi కాలింగ్"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi కాలింగ్"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN కాల్"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN కాల్"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -253,15 +254,16 @@
     <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"వర్చువల్ కీబోర్డ్"</string>
     <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"భౌతిక కీబోర్డ్"</string>
     <string name="notification_channel_security" msgid="7345516133431326347">"భద్రత"</string>
-    <string name="notification_channel_car_mode" msgid="3553380307619874564">"కారు మోడ్"</string>
+    <string name="notification_channel_car_mode" msgid="3553380307619874564">"కార్‌ మోడ్"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"ఖాతా స్థితి"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"డెవలపర్ సందేశాలు"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"ముఖ్యమైన డెవలపర్ సందేశాలు"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"అప్‌డేట్‌లు"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"నెట్‌వర్క్ స్థితి"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"నెట్‌వర్క్ హెచ్చరికలు"</string>
     <string name="notification_channel_network_available" msgid="4531717914138179517">"నెట్‌వర్క్ అందుబాటులో ఉంది"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN స్థితి"</string>
-    <string name="notification_channel_device_admin" msgid="8353118887482520565">"మీ IT నిర్వాహకులు నుండి వచ్చే హెచ్చరికలు"</string>
+    <string name="notification_channel_device_admin" msgid="8353118887482520565">"మీ IT నిర్వాహకుల నుండి వచ్చే హెచ్చరికలు"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"హెచ్చరికలు"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"రిటైల్ డెమో"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB కనెక్షన్"</string>
@@ -280,7 +282,7 @@
     <string name="permgrouprequest_contacts" msgid="6032805601881764300">"మీ పరిచయాలను యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని అనుమతించాలా?"</string>
     <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="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="1347189607421252902">"మీరు యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే స్థానానికి యాప్ యాక్సెస్ కలిగి ఉంటుంది"</string>
     <string name="permgroupbackgroundrequest_location" msgid="5039063878675613235">"ఈ పరికర స్థానాన్ని &lt;b&gt;అన్ని సమయాలలో&lt;/b&gt; యాక్సెస్ చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను అనుమతించాలా?"</string>
     <string name="permgroupbackgroundrequestdetail_location" msgid="4597006851453417387">"యాప్ ప్రస్తుతం మీరు ఆ యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే స్థానాన్ని యాక్సెస్ చేయగలుగుతుంది"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"వేలిముద్ర చిహ్నం"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"ముఖంతో అన్‌లాక్ చేయగల హార్డ్‌వేర్ నిర్వహణ"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"వినియోగం కోసం ముఖ టెంప్లేట్‌లను జోడించే మరియు తొలగించే పద్ధతులను అమలు చేయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"ముఖంతో అన్‌లాక్ చేయగల హార్డ్‌వేర్ వినియోగం"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"ప్రమాణీకరణ కోసం ముఖంతో అన్‌లాక్ చేయగల హార్డ్‌వేర్‌ను ఉపయోగించడానికి యాప్‌ను అనుమతిస్తుంది"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"ముఖంతో అన్‌లాక్"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"మీ ముఖాన్ని తిరిగి నమోదు చేయండి"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"గుర్తింపును మెరుగుపరచడానికి, దయచేసి మీ ముఖంను తిరిగి నమోదు చేసుకోండి"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"ముఖం డేటా సరిగ్గా రాలేదు. మళ్లీ ప్రయత్నించండి."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"ఫోన్‌ను ఎడమవైపునకు జరపండి."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"ఫోన్‌ను కుడివైపునకు జరపండి."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"దయచేసి మీ పరికరం వైపు మరింత నేరుగా చూడండి."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"మీ ముఖం కనిపించడం లేదు. ఫోన్ వైపు చూడండి."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"మీ ముఖాన్ని ఫోన్‌కు ఎదురుగా ఉంచండి."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"బాగా కదుపుతున్నారు. ఫోన్‌ను స్థిరంగా పట్టుకోండి"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"దయచేసి మీ ముఖాన్ని మళ్లీ నమోదు చేయండి."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"ఇక ముఖం గుర్తించలేదు. మళ్లీ ప్రయత్నించండి."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"మీ తలను ఇంకాస్త తక్కువ తిప్పండి."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"మీ తలను ఎడమ/కుడి వైపుగా ఇంకాస్త తిప్పండి."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"మీ ముఖానికి అడ్డుగా ఉన్నవాటిని తీసివేస్తుంది."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"స్క్రీన్ ఎగువన ఉన్న సెన్సార్‌ను శుభ్రం చేస్తుంది."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"నల్లని పట్టీతో సహా మీ స్క్రీన్ పైభాగం అంతటినీ శుభ్రంగా తుడవండి"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"ముఖం ధృవీకరించలేరు. హార్డ్‌వేర్ అందుబాటులో లేదు."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"ముఖంతో అన్‌లాక్‌ను మళ్లీ ప్రయత్నించండి."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"కొత్త ముఖం డేటాను నిల్వ చేయడం కాదు. మొదట పాతది తొలిగించండి."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ముఖ కార్యకలాపం రద్దయింది."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ముఖంతో అన్‌లాక్‌ను వినియోగదారు రద్దు చేశారు."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"చాలా ఎక్కువ ప్రయత్నాలు చేసారు. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"అనేకసార్లు ప్రయత్నించారు. ముఖంతో అన్‌లాక్ నిలిపివేయబడింది."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"ముఖం ధృవీకరించలేకపోయింది. మళ్లీ ప్రయత్నించండి."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"మీరు ముఖంతో అన్‌లాక్‌ను సెటప్ చేయలేదు."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"ఈ పరికరంలో ముఖంతో అన్‌లాక్‌ను ఉపయోగించడానికి మద్దతు లేదు."</string>
     <string name="face_name_template" msgid="7004562145809595384">"ముఖ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"దీనితో తెరువు"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$sతో తెరువు"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"తెరువు"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"<xliff:g id="HOST">%1$s</xliff:g> లింక్‌లను తెరవడానికి యాక్సెస్ ఇవ్వండి"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g>తో <xliff:g id="HOST">%1$s</xliff:g> లింక్‌లను తెరవడానికి యాక్సెస్ ఇవ్వండి"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"దీనితో <xliff:g id="HOST">%1$s</xliff:g> లింక్‌లను తెరవండి"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"దీనితో లింక్‌లను తెరవండి"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g>తో లింక్‌లను తెరవండి"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> లింక్‌లను <xliff:g id="APPLICATION">%2$s</xliff:g>తో తెరవండి"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"యాక్సెస్ ఇవ్వండి"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"దీనితో సవరించు"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$sతో సవరించు"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"పరీక్ష నియంత్రణ మోడ్‌ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్‍‌ను అమలు చేయండి."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB పోర్ట్‌లో ద్రవ లేదా వ్యర్థ పదార్థాలు ఉన్నాయి"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB పోర్ట్ ఆటోమేటిక్‌గా నిలిపివేయబడింది. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB పోర్ట్‌ను ఉపయోగించడం సురక్షితం"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"ఫోన్ ఇకపై ద్రవ లేదా వ్యర్థ పదార్థాలను గుర్తించదు."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"బగ్ నివేదికను తీస్తోంది…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"బగ్ నివేదికను భాగస్వామ్యం చేయాలా?"</string>
@@ -1593,7 +1587,8 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"బ్రౌజర్‌ను ప్రారంభించాలా?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"కాల్‌ను ఆమోదించాలా?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ఎల్లప్పుడూ"</string>
-    <string name="activity_resolver_use_once" msgid="2404644797149173758">"ఒకసారి"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ఎల్లప్పుడూ తెరవడానికి సెట్ చేయి"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"ఒకసారి మాత్రమే"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"సెట్టింగ్‌లు"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s కార్యాలయ ప్రొఫైల్‌కు మద్దతు ఇవ్వదు"</string>
     <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"టాబ్లెట్"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"అతివ్యాప్తి #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", సురక్షితం"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> నుండి ప్రారంభం అయ్యే నేపథ్య కార్యకలాపం భవిష్యత్తు Q బిల్డ్‌లలో బ్లాక్ చేయబడుతుంది. See g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> నుండి ప్రారంభం అయ్యే నేపథ్య కార్యకలాపం బ్లాక్ చేయబడింది. See g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"నమూనాను మర్చిపోయాను"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"ఆకృతి తప్పు"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"పాస్‌వర్డ్ తప్పు"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"యాక్సెస్ సామర్థ్య షార్ట్‌కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"యాక్సెస్ సామర్థ్య షార్ట్‌కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ని ఉపయోగించడానికి వాల్యూమ్ కీలు రెండింటినీ 3 సెకన్లు నొక్కి ఉంచండి"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"యాక్సెస్ సామర్థ్య బటన్‌ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్‌ను ఎంచుకోండి:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"ఫీచర్లను మార్చడానికి, యాక్సెస్ సామర్థ్య బటన్‌ను నొక్కి &amp; పట్టుకోండి."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"యాక్సెసిబిలిటీ బటన్‌ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్‌ను ఎంచుకోండి:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక సేవను ఎంచుకోండి (రెండు చేతి వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక సేవను ఎంచుకోండి (మూడు చేతి వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"సేవల మధ్య మారడానికి, యాక్సెసిబిలిటీ బటన్‌ను నొక్కి &amp; పట్టుకోండి."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"సేవల మధ్య మారడానికి, రెండు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"సేవల మధ్య మారడానికి, మూడు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"మాగ్నిఫికేషన్"</string>
     <string name="user_switched" msgid="3768006783166984410">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g>కి మారుస్తోంది…"</string>
diff --git a/core/res/res/values-television/themes_device_defaults.xml b/core/res/res/values-television/themes_device_defaults.xml
index fdd0624..cb3d328 100644
--- a/core/res/res/values-television/themes_device_defaults.xml
+++ b/core/res/res/values-television/themes_device_defaults.xml
@@ -27,6 +27,9 @@
     </style>
 
     <!-- TV always use dark mode -->
+    <style name="Theme.DeviceDefault.System" parent="Theme.DeviceDefault" />
+    <style name="Theme.DeviceDefault.System.Dialog" parent="Theme.DeviceDefault.Dialog" />
+    <style name="Theme.DeviceDefault.System.Dialog.Alert" parent="Theme.DeviceDefault.Dialog.Alert" />
     <style name="Theme.DeviceDefault.Autofill.Light" parent="Theme.DeviceDefault.Autofill"/>
     <style name="Theme.DeviceDefault.Light.Autofill.Save" parent="Theme.DeviceDefault.Autofill.Save"/>
 
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index fb00cee..4e69430 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"การโทรผ่าน Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"การโทรผ่าน Wi-Fi ของ <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"การโทรผ่าน WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"การโทรผ่าน WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"โหมดรถยนต์"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"สถานะบัญชี"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ข้อความสำหรับนักพัฒนาซอฟต์แวร์"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"ข้อความสำคัญสำหรับนักพัฒนาซอฟต์แวร์"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"การอัปเดต"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"สถานะเครือข่าย"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"การแจ้งเตือนเครือข่าย"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"ไอคอนลายนิ้วมือ"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"จัดการฮาร์ดแวร์ Face Unlock"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"อนุญาตให้แอปเรียกใช้วิธีเพิ่มและลบเทมเพลตใบหน้าสำหรับการใช้งาน"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"ใช้ฮาร์ดแวร์ Face Unlock"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"อนุญาตให้แอปใช้ฮาร์ดแวร์ Face Unlock เพื่อตรวจสอบสิทธิ์"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face Unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"ลงทะเบียนใบหน้าอีกครั้ง"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"โปรดลงทะเบียนใบหน้าอีกครั้งเพื่อปรับปรุงการจดจำ"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"บันทึกข้อมูลใบหน้าที่ถูกต้องไม่ได้ ลองอีกครั้ง"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"เลื่อนโทรศัพท์ไปทางซ้าย"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"เลื่อนโทรศัพท์ไปทางขวา"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"โปรดมองตรงมาที่อุปกรณ์"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"ไม่เห็นหน้า มองที่โทรศัพท์"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"หันหน้าให้ตรงกับโทรศัพท์"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"มีการเคลื่อนไหวมากเกินไป ถือโทรศัพท์นิ่งๆ"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"โปรดลงทะเบียนใบหน้าอีกครั้ง"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"จำใบหน้าไม่ได้แล้ว ลองอีกครั้ง"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"จัดตำแหน่งศีรษะให้ตรง"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"จัดตำแหน่งศีรษะให้ตรง"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"เอาสิ่งที่ปิดบังใบหน้าออก"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"ทำความสะอาดเซ็นเซอร์ที่ขอบด้านบนของหน้าจอ"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"ทำความสะอาดด้านบนของหน้าจอ รวมถึงแถบสีดำ"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"ยืนยันใบหน้าไม่ได้ ฮาร์ดแวร์ไม่พร้อมใช้งาน"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"ลองใช้ Face Unlock อีกครั้ง"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"จัดเก็บข้อมูลใบหน้าใหม่ไม่ได้ ลบข้อมูลเก่าออกไปก่อน"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"ยกเลิกการดำเนินการกับใบหน้าแล้ว"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"ผู้ใช้ยกเลิกการใช้ Face Unlock"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"ดำเนินการหลายครั้งเกินไป ลองอีกครั้งในภายหลัง"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"ลองหลายครั้งเกินไป ปิดใช้ Face Unlock แล้ว"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"ยืนยันใบหน้าไม่ได้ ลองอีกครั้ง"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"คุณยังไม่ได้ตั้งค่า Face Unlock"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"อุปกรณ์นี้ไม่รองรับ Face Unlock"</string>
     <string name="face_name_template" msgid="7004562145809595384">"ใบหน้า <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"เปิดด้วย"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"เปิดด้วย %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"เปิด"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"ให้สิทธิ์ในการเปิดลิงก์ของ <xliff:g id="HOST">%1$s</xliff:g> โดยใช้"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"ให้สิทธิ์ในการเปิดลิงก์ของ <xliff:g id="HOST">%1$s</xliff:g> โดยใช้ <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"เปิดลิงก์ <xliff:g id="HOST">%1$s</xliff:g> ด้วย"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"เปิดลิงก์ด้วย"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"เปิดลิงก์ด้วย <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"เปิดลิงก์ <xliff:g id="HOST">%1$s</xliff:g> ด้วย <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"ให้สิทธิ์"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"แก้ไขด้วย"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"แก้ไขด้วย %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อปิดใช้โหมดโปรแกรมทดสอบอัตโนมัติ"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"มีของเหลวหรือฝุ่นละอองในพอร์ต USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"พอร์ต USB ปิดใช้โดยอัตโนมัติ แตะเพื่อดูข้อมูลเพิ่มเติม"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"ใช้พอร์ต USB ได้แล้ว"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"โทรศัพท์ไม่ได้ตรวจจับของเหลวและฝุ่นละอองแล้ว"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"กำลังสร้างรายงานข้อบกพร่อง…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"แชร์รายงานข้อบกพร่องไหม"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"เปิดเบราว์เซอร์หรือไม่"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"รับสายหรือไม่"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ทุกครั้ง"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ตั้งค่าให้เปิดทุกครั้ง"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"เฉพาะครั้งนี้"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"การตั้งค่า"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ไม่สนับสนุนโปรไฟล์งาน"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"การวางซ้อน #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ปลอดภัย"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"การเริ่มกิจกรรมในเบื้องหลังจาก <xliff:g id="PACKAGENAME">%1$s</xliff:g> นี้จะถูกบล็อกในบิวด์ Q ในอนาคต โปรดดู g.co/dev/bgblock"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"บล็อกการเริ่มกิจกรรมในเบื้องหลังจาก <xliff:g id="PACKAGENAME">%1$s</xliff:g> แล้ว โปรดดู g.co/dev/bgblock"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ลืมรูปแบบใช่หรือไม่"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"รูปแบบไม่ถูกต้อง"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"รหัสผ่านไม่ถูกต้อง"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ทางลัดการเข้าถึงเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ทางลัดการเข้าถึงปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้ 3 วินาทีเพื่อใช้ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"เลือกฟีเจอร์ที่จะใช้เมื่อคุณแตะปุ่ม \"การช่วยเหลือพิเศษ\":"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"หากต้องการเปลี่ยนฟีเจอร์ ให้แตะปุ่ม \"การช่วยเหลือพิเศษ\" ค้างไว้"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"เลือกบริการที่จะใช้เมื่อคุณแตะปุ่มการช่วยเหลือพิเศษ:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"เลือกบริการที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 2 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"เลือกบริการที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 3 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"หากต้องการสลับระหว่างบริการ ให้แตะปุ่มการช่วยเหลือพิเศษค้างไว้"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"หากต้องการสลับระหว่างบริการ ให้ใช้ 2 นิ้วเลื่อนขึ้นค้างไว้"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"หากต้องการสลับระหว่างบริการ ให้ใช้ 3 นิ้วเลื่อนขึ้นค้างไว้"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"การขยาย"</string>
     <string name="user_switched" msgid="3768006783166984410">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"กำลังเปลี่ยนเป็น <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 73439bb..6843528 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Pagtawag Gamit ang Wi-Fi ng <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Pagtawag Gamit ang WiFi ng <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Pagtawag Gamit ang WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Pagtawag Gamit ang WLAN ng <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ng <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Car mode"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Status ng account"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Mga mensahe ng developer"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Mahahalagang mensahe mula sa developer"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Mga Update"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Status ng network"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Mga alerto sa network"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Icon ng fingerprint"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"pamahalaan ang hardware ng face unlock"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Pumapayag na mag-invoke ang app ng paraang magdagdag at mag-delete ng template ng mukha."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"gamitin ang hardware ng face unlock"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Pinapayagan ang app na gamitin ang hardware ng face unlock para sa pag-authenticate"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Face unlock"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"I-enroll ulit ang iyong mukha"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Para mapahusay ang pagkilala, paki-enroll ulit ang iyong mukha"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Hindi makakuha ng tamang face data. Subukang muli."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Igalaw ang telepono pakaliwa."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Igalaw ang telepono pakanan."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Tumingin nang mas direkta sa iyong device."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Hindi makita ang mukha mo. Tumingin sa telepono."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Itapat ang mukha mo sa mismong harap ng telepono."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Masyadong magalaw. Hawakang mabuti ang telepono."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Paki-enroll muli ang iyong mukha."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Hindi na makilala ang mukha. Subukang muli."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Huwag masyadong tumingala o yumuko."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Huwag masyadong lumingon."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Alisin ang anumang humaharang sa iyong mukha."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Linisinin ang sensor sa itaas na gilid ng screen."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Linisin ang itaas ng iyong screen, kasama ang itim na bar"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Di ma-verify ang mukha. Di available ang hardware."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Subukan ulit ang face unlock."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Hindi ma-store ang data ng mukha. Mag-delete muna ng iba."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Nakansela ang operation kaugnay ng mukha."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Kinansela ng user ang face unlock."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Masyadong maraming pagsubok. Subukang muli mamaya."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Masyadong maraming pagsubok. Na-disable ang face unlock."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Hindi ma-verify ang mukha. Subukang muli."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Hindi mo pa nase-set up ang face unlock."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Hindi sinusuportahan ang face unlock sa device na ito."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Mukha <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Buksan gamit ang"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Buksan gamit ang %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Buksan"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Magbigay ng access para buksan ang mga link ng <xliff:g id="HOST">%1$s</xliff:g> sa"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Magbigay ng access para buksan ang mga link ng <xliff:g id="HOST">%1$s</xliff:g> sa <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Buksan ang mga link ng <xliff:g id="HOST">%1$s</xliff:g> gamit ang"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Buksan ang mga link gamit ang"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Buksan ang mga link gamit ang <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Buksan ang mga link ng <xliff:g id="HOST">%1$s</xliff:g> gamit ang <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Bigyan ng access"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"I-edit gamit ang"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"I-edit gamit ang %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Mag-factory reset para i-disable ang Test Harness Mode."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Ayos na gamitin ang USB port"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Hindi na nakaka-detect ang telepono ng liquid o debris."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Kinukuha ang ulat ng bug…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Gusto mo bang ibahagi ang ulat ng bug?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Ilunsad ang Browser?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Tanggapin ang tawag?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Palagi"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Itakda sa palaging buksan"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Isang beses lang"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Mga Setting"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"Hindi sinusuportahan ng %1$s ang profile sa trabaho"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlay #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", secure"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Iba-block ang pagsisimula ng aktibidad sa background na ito mula sa <xliff:g id="PACKAGENAME">%1$s</xliff:g> sa mga Q build sa hinaharap. Tingnan ang g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Na-block ang pagsisimula ng aktibidad sa background mula sa <xliff:g id="PACKAGENAME">%1$s</xliff:g>. Tingnan ang g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Nakalimutan ang Pattern"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Maling Pattern"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Maling Password"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Na-on ng Shortcut sa Accessibility ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Na-off ng Shortcut sa Accessibility ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Pindutin nang matagal ang parehong volume key sa loob ng tatlong segundo para magamit ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Pumili ng feature na gagamitin kapag na-tap mo ang button ng Pagiging Accessible:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Upang baguhin ang mga feature, pindutin nang matagal ang button ng Pagiging Naa-access."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Pumili ng serbisyong gagamitin kapag na-tap mo ang button ng pagiging accessible:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Pumili ng serbisyong gagamitin sa galaw ng pagiging accessible (pag-swipe pataas mula sa ibaba ng screen gamit ang dalawang daliri):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Pumili ng serbisyong gagamitin sa galaw ng pagiging accessible (pag-swipe pataas mula sa ibaba ng screen gamit ang tatlong daliri):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Para magpalipat-lipat sa mga serbisyo, pindutin nang matagal ang button ng pagiging accessible."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Para magpalipat-lipat sa mga serbisyo, mag-swipe pataas gamit ang dalawang daliri at i-hold."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Para magpalipat-lipat sa mga serbisyo, mag-swipe pataas gamit ang tatlong daliri at i-hold."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Pag-magnify"</string>
     <string name="user_switched" msgid="3768006783166984410">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Lumilipat kay <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index e1fa7da..3592df9 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Kablosuz Çağrı"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Kablosuz Arama"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN Üzerinden Çağrı"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN Üzerinden Çağrı"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Kablosuz"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Araç modu"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Hesap durumu"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Geliştirici mesajları"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Önemli geliştirici mesajları"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Güncellemeler"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Ağ durumu"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Ağ uyarıları"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Parmak izi simgesi"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"yüz tanıma kilidi donanımı yönet"</string>
     <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>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"yüz tanıma kilidi donanımını kullan"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Uygulamanın yüz tanıma kilidi donanımı kullanmasına izin verir"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Yüz tanıma kilidi"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Yüzünüzü yeniden kaydedin"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Daha iyi tanınmasını sağlamak için lütfen yüzünüzü yeniden kaydedin"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Doğru yüz verileri yakalanamadı. Tekrar deneyin."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Telefonu sola hareket ettirin."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Telefonu sağa hareket ettirin."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Lütfen cihazınıza daha doğrudan bakın."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Yüzünüz görülmüyor. Telefona bakın."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Yüzünüz telefonun tam karşısına gelmelidir."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Çok fazla hareket ediyorsunuz. Telefonu sabit tutun."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Lütfen yüzünüzü yeniden kaydedin."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Yüz artık tanınamıyor. Tekrar deneyin."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Başınızı biraz daha az çevirin."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Başınızı biraz daha az çevirin."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Yüzünüzün görünmesini engelleyen şeyleri kaldırın."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Ekranın üst kenarındaki sensörü temizleyin."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Siyah çubuk da dahil olmak üzere ekranınızın üst kısmını temizleyin"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Yüz doğrulanamıyor. Donanım kullanılamıyor."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Yüz tanıma kilidini yeniden deneyin."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Yeni yüz verisi depolanamıyor. Önce eski bir tanesini silin."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Yüz işlemi iptal edildi."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Yüz tanıma kilidi kullanıcı tarafından iptal edildi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Çok fazla deneme yapıldı. Daha sonra tekrar deneyin."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Çok fazla deneme yapıldı. Yüz tanıma kilidi devredışı."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Yüz doğrulanamıyor. Tekrar deneyin."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Yüz tanıma kilidi ayarlamadınız."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Bu cihazda yüz tanıma kilidi desteklenmiyor"</string>
     <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>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Şununla aç:"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s ile aç"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Aç"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Şununla <xliff:g id="HOST">%1$s</xliff:g> bağlantılarını açma izni verin"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> uygulamasıyla <xliff:g id="HOST">%1$s</xliff:g> bağlantılarını açma izni verin"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> bağlantılarını şununla aç:"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Bağlantıları şununla aç:"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Bağlantıları <xliff:g id="APPLICATION">%1$s</xliff:g> ile aç"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> bağlantılarını <xliff:g id="APPLICATION">%2$s</xliff:g> ile aç"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Erişim ver"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Şununla düzenle:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s ile düzenle"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Test Bandı Modu\'nu devre dışı bırakmak için cihazı fabrika ayarlarına sıfırlayın."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB bağlantı noktasını kullanabilirsiniz"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon artık sıvıları veya tozları algılamıyor."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hata raporu alınıyor…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Hata raporu paylaşılsın mı?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Tarayıcı Başlatılsın mı?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Çağrı kabul edilsin mi?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Her zaman"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Her zaman açılmak üzere ayarla"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Yalnızca bir defa"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Ayarlar"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s, iş profilini desteklemiyor"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Yer Paylaşımı No. <xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", güvenli"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> paketinden bu arka plan etkinliği başlangıcı, ilerideki Q derlemelerinde engellenecek. g.co/dev/bgblock adresini ziyaret edin."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> paketinden arka plan etkinliği başlangıcı engellendi. g.co/dev/bgblock adresini ziyaret edin."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Deseni Unuttunuz mu?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Yanlış Desen"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Yanlış Şifre"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Erişilebilirlik Kısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini açtı"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Erişilebilirlik Kısayolu <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kapattı"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kullanmak için her iki ses tuşunu basılı tutun"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak üzere bir özellik seçin:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Özellikleri değiştirmek için Erişilebilirlik düğmesine dokunup basılı tutun."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak üzere bir hizmet seçin:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Erişilebilirlik hareketiyle (iki parmakla ekranın altından yukarı kaydırma) kullanılacak bir hizmet seçin:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Erişilebilirlik hareketiyle (üç parmakla ekranın altından yukarı kaydırma) kullanılacak bir hizmet seçin:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Hizmetler arasında geçiş yapmak erişilebilirlik düğmesine dokunup basılı tutun."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Hizmetler arasında geçiş yapmak için iki parmakla yukarı kaydırıp basılı tutun."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Hizmetler arasında geçiş yapmak için üç parmakla yukarı kaydırıp basılı tutun."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Büyütme"</string>
     <string name="user_switched" msgid="3768006783166984410">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string>
@@ -1910,7 +1907,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Güncellemeleri denetle"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Yeni mesajlarınız var"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Görüntülemek için SMS uygulamasını açın"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Bazı işlevler sınırlı olabilir"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Bazı işlevler sınırlanabilir"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"İş profili kilitlendi"</string>
     <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>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 26de583..347c81f 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -133,6 +133,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Виклики <xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Дзвінок від абонента <xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Виклик через WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Виклик <xliff:g id="SPN">%s</xliff:g> через WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
@@ -262,6 +263,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Режим автомобіля"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Статус облікового запису"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Повідомлення для розробників"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Важливі повідомлення для розробників"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Оновлення"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Статус мережі"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Сповіщення мережі"</string>
@@ -555,15 +557,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Значок відбитка пальця"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"керувати апаратним забезпечення для Фейсконтролю"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Додаток може активувати способи додавання й видалення шаблонів облич."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"використовувати апаратне забезпечення для Фейсконтролю"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Додаток може використовувати апаратне забезпечення для Фейсконтролю"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Фейсконтроль"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Повторно проскануйте обличчя"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Повторно проскануйте обличчя для ефективнішого розпізнавання"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Не вдалося чітко зняти обличчя. Повторіть спробу."</string>
@@ -576,7 +574,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Тримайте телефон лівіше."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Тримайте телефон правіше."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Дивіться просто на пристрій."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Обличчя не видно. Дивіться на телефон."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Тримайте телефон просто перед обличчям."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Забагато рухів. Тримайте телефон нерухомо."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Повторно проскануйте обличчя."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Розпізнати обличчя вже не вдається. Повторіть спробу."</string>
@@ -585,24 +583,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Трохи перемістіть обличчя."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Трохи поверніть обличчя."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Приберіть об’єкти, які затуляють ваше обличчя."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Очистьте датчик угорі екрана."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Очистьте верхню частину екрана, зокрема чорну панель"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Не вдається перевірити обличчя. Апаратне забезпечення недоступне."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Скористайтеся Фейсконтролем ще раз."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Не вдається зберегти нові дані про обличчя. Видаліть старі."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Дію з обличчям скасовано."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Користувач скасував Фейсконтроль."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Забагато спроб. Повторіть пізніше."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Забагато спроб. Фейсконтроль вимкнено."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Не вдається перевірити обличчя. Повторіть спробу."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Ви не налаштували Фейсконтроль"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"На цьому пристрої не підтримується Фейсконтроль."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Обличчя <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1178,8 +1171,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Відкрити за допомогою"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Відкрити за допомогою %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Відкрити"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Дозвольте відкривати посилання на сайт <xliff:g id="HOST">%1$s</xliff:g> у додатку"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Дозвольте відкривати посилання на сайт <xliff:g id="HOST">%1$s</xliff:g> у додатку <xliff:g id="APPLICATION">%2$s</xliff:g>."</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Відкривати посилання <xliff:g id="HOST">%1$s</xliff:g> за допомогою"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Відкривати посилання за допомогою"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Відкривати посилання за допомогою додатка <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Відкривати посилання <xliff:g id="HOST">%1$s</xliff:g> за допомогою додатка <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Дозволити"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Редагувати за допомогою"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Редагувати за допомогою %1$s"</string>
@@ -1410,8 +1405,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Щоб вимкнути режим автоматизованого тестування, відновіть заводські налаштування."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Рідина або сміття в USB-порту"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB-порт автоматично вимкнено. Торкніться, щоб дізнатися більше."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Можна використовувати USB-порт"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Телефон уже не виявляє рідини або сміття."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Створюється повідомлення про помилку…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Надіслати звіт про помилку?"</string>
@@ -1638,6 +1632,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустити веб-переглядач?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Прийняти виклик?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Завжди"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Вибрати додаток для відкривання посилань"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Лише цього разу"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Налаштування"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s не підтримує робочий профіль"</string>
@@ -1667,8 +1662,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Накладання №<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>х<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", безпечний"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Фонову активність пакета <xliff:g id="PACKAGENAME">%1$s</xliff:g> буде заблоковано в майбутніх складаннях Q. Докладніше: g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Фонову активність додатка <xliff:g id="PACKAGENAME">%1$s</xliff:g> заблоковано. Докладніше: g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Не пам’ятаю ключ"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Неправильний ключ"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Неправильний пароль"</string>
@@ -1724,8 +1717,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Ярлик спеціальних можливостей увімкнув <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Ярлик спеціальних можливостей вимкнув <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Щоб скористатися службою <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, утримуйте обидві клавіші гучності впродовж трьох секунд"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Виберіть функцію для кнопки спеціальних можливостей:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Щоб змінити функцію, натисніть і втримуйте кнопку спеціальних можливостей."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Виберіть сервіс для кнопки спеціальних можливостей:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Виберіть сервіс для жесту спеціальних можливостей (проведення двома пальцями знизу вгору):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Виберіть сервіс для жесту спеціальних можливостей (проведення трьома пальцями знизу вгору):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Щоб переключитися між сервісами, натисніть і утримуйте кнопку спеціальних можливостей."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Щоб переключитися між сервісами, проведіть двома пальцями вгору й утримуйте екран."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Щоб переключитися між сервісами, проведіть трьома пальцями вгору й утримуйте екран."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Збільшення"</string>
     <string name="user_switched" msgid="3768006783166984410">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Перехід в обліковий запис \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -2074,7 +2071,7 @@
     <string name="notification_appops_overlay_active" msgid="633813008357934729">"показ поверх інших додатків на екрані"</string>
     <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>
+    <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"Режим енергозбереження активовано для збільшення часу роботи акумулятора"</string>
     <string name="battery_saver_notification_channel_name" msgid="2083316159716201806">"Режим енергозбереження"</string>
     <string name="battery_saver_sticky_disabled_notification_title" msgid="6376147579378764641">"Режим енергозбереження не ввімкнеться, доки рівень заряду знову не знизиться"</string>
     <string name="battery_saver_sticky_disabled_notification_summary" msgid="8090192609249817945">"Акумулятор заряджено достатньо. Режим енергозбереження буде знову ввімкнено, коли рівень заряду знизиться."</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 78d4a58..3fd6fe7 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -88,7 +88,7 @@
     <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"ہنگامی کالنگ دستیاب نہیں ہے"</string>
     <string name="EmergencyCallWarningSummary" msgid="1899692069750260619">"‏Wi‑Fi کے ذریعے ہنگامی کالز نہیں کر سکتے"</string>
     <string name="notification_channel_network_alert" msgid="4427736684338074967">"الرٹس"</string>
-    <string name="notification_channel_call_forward" msgid="2419697808481833249">"کال آگے منتقل کرنا"</string>
+    <string name="notification_channel_call_forward" msgid="2419697808481833249">"کال فارورڈنگ"</string>
     <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"ہنگامی کال بیک وضع"</string>
     <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"موبائل ڈیٹا کی صورت حال"</string>
     <string name="notification_channel_sms" msgid="3441746047346135073">"‏SMS پیغامات"</string>
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"‏<xliff:g id="SPN">%s</xliff:g> Wi-Fi کالنگ"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"‏<xliff:g id="SPN">%s</xliff:g> Wi-Fi کالنگ"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"‏WLAN کال"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"‏<xliff:g id="SPN">%s</xliff:g> WLAN کال"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"کار وضع"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"اکاؤنٹ اسٹیٹس"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"ڈیولپر کے پیغامات"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"اہم ڈیولپر پیغامات"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"اپ ڈیٹس"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"نیٹ ورک اسٹیٹس"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"نیٹ ورک الرٹس"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"فنگر پرنٹ آئیکن"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"چہرے کے ذریعے غیر مقفل کرنے والے ہارڈ ویئر کا نظم کریں"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"ایپ کو چہرے کی تمثیلات شامل اور حذف کرنے کے طریقوں کو کالعدم قرار دینے کی اجازت دیتا ہے۔"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"چہرے کے ذریعے غیر مقفل کرنے والا ہارڈ ویئر استعمال کریں"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"ایپ کو تصدیق کے لیے چہرے کے ذریعے غیر مقفل کرنے کا ہارڈ ویئر استعمال کرنے کی اجازت دیتی ہے"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"چہرے کے ذریعے غیر مقفل کریں"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"اپنے چہرے کو دوبارہ مندرج کریں"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"شناخت کو بہتر بنانے کے لیے براہ کرم اپنے چہرے کو دوبارہ مندرج کریں"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"چہرے کا درست ڈيٹا کیپچر نہیں ہو سکا۔ پھر آزمائيں۔"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"فون کو بائیں جانب لے جائيں۔"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"فون کو دائیں جانب لے جائیں۔"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"براہ کرم اپنے آلہ کی طرف چہرے کو سیدھا رکھیں۔"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"آپ کا چہرہ دکھائی نہیں دے رہا۔ فون کی طرف دیکھیں۔"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"اپنے چہرے کو براہ راست فون کے سامنے رکھیں۔"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"کافی حرکت ہو رہی ہے۔ فون کو مضبوطی سے پکڑیں۔"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"براہ کرم اپنے چہرے کو دوبارہ مندرج کریں۔"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"اب چہرے کی شناخت نہیں کر سکتے۔ پھر آزمائيں۔"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"اپنا سر تھوڑا کم کریں۔"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"اپنا سر تھوڑا کم کریں۔"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"آپ کے چہرہ کو چھپانے والی ہر چیز کو ہٹائیں۔"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"اسکرین کے بالائی کنارے پر سنسر کو صاف کریں۔"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"سیاہ بار سمیت، اپنی اسکرین کے اوپری حصے کو صاف کریں"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"چہرے کی توثیق نہیں کی جا سکی۔ ہارڈ ویئر دستیاب نہیں ہے۔"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"چہرے کے ذریعے غیر مقفل کرنے کو دوبارہ آزمائیں۔"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"چہرے کا نیا ڈیٹا اسٹور نہیں کر سکتے۔ پہلے پرانا حذف کریں۔"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"چہرے پر ہونے والی کارروائی منسوخ ہو گئی۔"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"صارف نے چہرے کے ذریعے غیر مقفل کرنے کو منسوخ کر دیا۔"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"کافی زیادہ کوششیں کی گئیں۔ دوبارہ کوشش کریں۔"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"کافی زیادہ کوششیں۔ چہرے کے ذریعے غیر مقفل کرنا غیر فعال کر دیا گیا۔"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"چہرے کی توثیق نہیں کی جا سکی۔ پھر آزمائيں۔"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"آپ نے بذریعہ چہرہ غیر مقفل کرنے کو سیٹ نہیں کیا ہے۔"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"اس آلہ پر چہرے کے ذریعے غیر مقفل کرنا تعاون یافتہ نہیں ہے۔"</string>
     <string name="face_name_template" msgid="7004562145809595384">"چہرہ <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"اس کے ساتھ کھولیں"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"‏%1$s کے ساتھ کھولیں"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"کھولیں"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"اس کے ساتھ <xliff:g id="HOST">%1$s</xliff:g> لنکس کو کھولنے کے لیے رسائی ديں"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="APPLICATION">%2$s</xliff:g> کے ساتھ <xliff:g id="HOST">%1$s</xliff:g> لنکس کو کھولنے کے لیے رسائی ديں"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> لنکس کے ساتھ کھولیں"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"لنکس کے ساتھ کھولیں"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"<xliff:g id="APPLICATION">%1$s</xliff:g> کے ذریعے لنکس کھولیں"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> لنکس کو <xliff:g id="APPLICATION">%2$s</xliff:g> کے ذریعے کھولیں"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"رسائی دیں"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"اس کے ساتھ ترمیم کریں"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"‏%1$s کے ساتھ ترمیم کریں"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"ٹیسٹ ہارنیس موڈ غیر فعال کرنے کے لیے فیکٹری ری سیٹ کریں۔"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"‏USB پورٹ میں سیال یا دھول ہے"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"‏USB پورٹ خودکار طور پر غیر فعال کر دیا گیا۔ مزید جاننے کیلئے تھپتھپائیں۔"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"‏USB پورٹ کا استعمال ٹھیک ہے"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"فون مزید سیال یا دھول کا پتہ نہیں لگاتا۔"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"بگ رپورٹ لی جا رہی ہے…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"بگ رپورٹ کا اشتراک کریں؟"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"براؤزر شروع کریں؟"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"کال قبول کریں؟"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"ہمیشہ"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"ہمیشہ کھلا ہوا ہونے پر سیٹ کریں"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"بس ایک مرتبہ"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"ترتیبات"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"‏%1$s دفتری پروفائل کا تعاون نہیں کرتا ہے"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"‏اوور لے ‎#<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"، محفوظ"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"‏<xliff:g id="PACKAGENAME">%1$s</xliff:g> سے شروع ہونے والی پس منظر کی اس سرگرمی کو مستقبل کے Q بلڈز میں مسدود کر دیا جائے گا۔ g.co/dev/bgblock ملاحظہ کریں۔"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"‏<xliff:g id="PACKAGENAME">%1$s</xliff:g> سے شروع ہونے والی پس منظر کی سرگرمی کو مسدود کر دیا گیا ہے۔ g.co/dev/bgblock ملاحظہ کریں۔"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"پیٹرن بھول گئے"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"غلط پیٹرن"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"غلط پاس ورڈ"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"ایکسیسبیلٹی شارٹ کٹ نے <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آن کر دیا"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"ایکسیسبیلٹی شارٹ کٹ نے <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آف کر دیا"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> کا استعمال کرنے کے لیے 3 سیکنڈ تک والیوم کی دونوں کلیدوں کو چھوئیں اور دبائے رکھیں"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"ایکسیسبیلٹی بٹن پر تھپتھپانے وقت استعمال کرنے کیلئے ایک خصوصیت چنیں:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"خصوصیات تبدیل کرنے کیلئے، ایکسیسبیلٹی بٹن ٹچ کریں اور دبائے رکھیں۔"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"ایکسیسبیلٹی بٹن پر تھپتھپانے وقت استعمال کرنے کیلئے ایک سروس چنیں:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک سروس چنیں (دو انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک سروس چنیں (تین انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"سروسز کے مابین سوئچ کرنے کے لیے، ایکسیسبیلٹی بٹن کو ٹچ کرکے ہولڈ کریں۔"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"سروسز کے مابین سوئچ کرنے کے لیے، دو انگلیوں سے اوپر سوائپ کرکے ہولڈ کریں۔"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"سروسز کے مابین سوئچ کرنے کے لیے، تین انگلیوں سے اوپر سوائپ کرکے ہولڈ کریں۔"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"میگنیفکیشن"</string>
     <string name="user_switched" msgid="3768006783166984410">"موجودہ صارف <xliff:g id="NAME">%1$s</xliff:g>۔"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> پر سوئچ کیا جا رہا ہے…"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index a192c76..85ebe00 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi chaqiruv"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi chaqiruv"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN chaqiruv"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN chaqiruv"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -255,17 +256,18 @@
     <string name="notification_channel_security" msgid="7345516133431326347">"Xavfsizlik"</string>
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Avtomobil rejimi"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Hisob holati"</string>
-    <string name="notification_channel_developer" msgid="7579606426860206060">"Dasturchi xabarlari"</string>
+    <string name="notification_channel_developer" msgid="7579606426860206060">"Dasturchilar uchun xabarlar"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Dasturchidan muhim xabarlar"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Yangilanishlar"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Tarmoq holati"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Tarmoqqa oid bildirgilar"</string>
     <string name="notification_channel_network_available" msgid="4531717914138179517">"Tarmoq mavjud"</string>
     <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN holati"</string>
-    <string name="notification_channel_device_admin" msgid="8353118887482520565">"IT administrator xabarlari"</string>
+    <string name="notification_channel_device_admin" msgid="8353118887482520565">"Administratordan xabarlar"</string>
     <string name="notification_channel_alerts" msgid="4496839309318519037">"Ogohlantirishlar"</string>
     <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo rejim"</string>
     <string name="notification_channel_usb" msgid="9006850475328924681">"USB orqali ulanish"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Ilova ishlamoqda"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Ilova faol"</string>
     <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Batareya quvvatini sarflayotgan ilovalar"</string>
     <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi batareya quvvatini sarflamoqda"</string>
     <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ta ilova batareya quvvatini sarflamoqda"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Barmoq izi belgisi"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"yuz bilan ochish qurilmasini boshqarish"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Ilova foydalanish uchun yuz namunalarini qo‘shish va o‘chirish usullarini tatbiq qilishi mumkin."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"yuz bilan ochish qurilmasidan foydalanish"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Haqiqiylikni tekshirish uchun yuz bilan ochishdan foydalanish imkonini beradi"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Yuz bilan ochish"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Yuzingizni yana qayd qiling"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Yuzingiz yanada yaxshiroq aniqlanishi uchun uni yana bir marta qayd qiling"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Yuz ravshan suratga olinmadi. Qaytadan urining."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Telefonni chapga suring."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Telefonni oʻngga suring."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Qurilmaga tik qarang."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Yuzingiz koʻrinmayapti. Telefonga qarang."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Telefoningizga yuzingizni tik tuting."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Ortiqcha harakatlanmoqda. Qimirlatmasdan ushlang."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Yuzingizni qaytadan qayd qildiring."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Yuz tanilmadi. Qaytadan urining."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Boshingizni asta buring."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Boshingizni asta buring."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Yuzingizni berkitayotgan narsalarni olib tashlang."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Ekranning tepasidagi sensorni tozalang."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Ekranning yuqori qismini, shuningdek, qora panelni ham tozalang"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Yuzingiz tasdiqlanmadi. Qurilma ishlamayapti."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Yana yuz bilan ochishga urining."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Yuzga oid axborot saqlanmadi. Avval eskilari tozalansin."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Yuzni aniqlash bekor qilindi."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Yuz bilan ochishni foydalanuvchi bekor qildi."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Juda ko‘p urinildi. Keyinroq qaytadan urining."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Juda koʻp urinildi. Yuz bilan ochish faolsizlantirildi."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Yuzingiz tasdiqlanmadi. Qaytadan urining."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Hali yuz bilan ochishni sozlamagansiz"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Yuz bilan ochish bu qurilmada ishlamaydi"</string>
     <string name="face_name_template" msgid="7004562145809595384">"Yuz <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Ochish…"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"%1$s bilan ochish"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Ochish"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"<xliff:g id="HOST">%1$s</xliff:g> havolalarini ushbu ilova bilan ochishga ruxsat bering:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"<xliff:g id="HOST">%1$s</xliff:g> havolalarini <xliff:g id="APPLICATION">%2$s</xliff:g> bilan ochishga ruxsat bering"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> havolalarini quyidagi orqali ochish"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Havolalarni quyidagi orqali ochish"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Havolalarni <xliff:g id="APPLICATION">%1$s</xliff:g> orqali ochish"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"<xliff:g id="HOST">%1$s</xliff:g> havolalarini <xliff:g id="APPLICATION">%2$s</xliff:g> orqali ochish"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Ruxsat berish"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Tahrirlash…"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"“%1$s” yordamida tahrirlash"</string>
@@ -1367,8 +1362,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string>
     <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>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB portdan foydalanish mumkin"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Telefon endi suyuqlik yoki turli parchalarni aniqlay olmaydi."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Xatoliklar hisoboti olinmoqda…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Xatoliklar hisoboti yuborilsinmi?"</string>
@@ -1504,7 +1498,7 @@
     <string name="find_next" msgid="5742124618942193978">"Keyingisini topish"</string>
     <string name="find_previous" msgid="2196723669388360506">"Oldingisini topish"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g>dan manzil haqida so‘rov"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Manzil so‘rovi"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Joylashuv axboroti talabi"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>) tomonidan so‘raldi"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Ha"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Yo‘q"</string>
@@ -1593,6 +1587,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Brauzer ishga tushirilsinmi?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Qo‘ng‘iroqni qabul qilasizmi?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Har doim"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Doim ochish"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Faqat hozir"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Sozlamalar"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"“%1$s” ishchi profilni qo‘llab-quvvatlamaydi"</string>
@@ -1622,8 +1617,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Tasvir uzatish #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", xavfsiz"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Keyingi Android Q nashrlarida fondagi ushbu <xliff:g id="PACKAGENAME">%1$s</xliff:g> jarayoni bloklanadi. g.co/dev/bgblock bilan tanishing."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Fondagi <xliff:g id="PACKAGENAME">%1$s</xliff:g> jarayoni bloklandi. g.co/dev/bgblock bilan tanishing."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Grafik kalit esimdan chiqdi"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Grafik kalit xato"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Parol noto‘g‘ri"</string>
@@ -1677,8 +1670,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmati yoqildi"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmati o‘chirib qo‘yildi"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatidan foydalanish uchun ikkala ovoz balandligi tugmalarini uzoq bosib turing"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Maxsus imkoniyatlar tugmasi bosilganda ishga tushadigan funksiyani tanlang:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Funksiyalarni o‘zgartirish uchun Maxsus imkoniyatlar tugmasini bosib turing."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Maxsus imkoniyatlar tugmasi bosilganda ishga tushadigan xizmatni tanlang:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Maxsus imkoniyatlar ishorasi bilan ishga tushadigan xizmatni tanlang (2 barmoq bilan ekranning pastidan tepaga surib tortilganda):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Maxsus imkoniyatlar ishorasi bilan ishga tushadigan xizmatni tanlang (3 barmoq bilan ekranning pastidan tepaga surib tortilganda):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Xizmatlar orasida almashish uchun maxsus imkoniyatlar tugmasini bosib turing."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Xizmatlarni almashtirish uchun 2 barmoq bilan tepaga suring va bosib turing."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Xizmatlarni almashtirish uchun 3 barmoq bilan tepaga suring va bosib turing."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Kattalashtirish"</string>
     <string name="user_switched" msgid="3768006783166984410">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Quyidagi foydalanuvchiga o‘tilmoqda: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1911,7 +1908,7 @@
     <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Yangilanish borligini tekshirish"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Sizga yangi SMS keldi"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Ko‘rish uchun SMS ilovasini oching"</string>
-    <string name="profile_encrypted_title" msgid="4260432497586829134">"Ayrim funksiyalar cheklanishi mumkin"</string>
+    <string name="profile_encrypted_title" msgid="4260432497586829134">"Ayrim funksiyalar ishlamasligi mumkin"</string>
     <string name="profile_encrypted_detail" msgid="3700965619978314974">"Ishchi profil yopiq"</string>
     <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>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index b4e1559..78c4290 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"Gọi qua Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"Gọi qua Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Cuộc gọi qua WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"Cuộc gọi qua WLAN <xliff:g id="SPN">%s</xliff:g>"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Chế độ trên ô tô"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Trạng thái tài khoản"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Thông báo liên quan đến nhà phát triển"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Thông báo quan trọng liên quan đến nhà phát triển"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Cập nhật"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Trạng thái mạng"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Cảnh báo mạng"</string>
@@ -519,7 +521,7 @@
     <string name="permdesc_imagesWrite" msgid="7073662756617474375">"Cho phép ứng dụng này sửa đổi bộ sưu tập ảnh của bạn."</string>
     <string name="permlab_mediaLocation" msgid="8675148183726247864">"đọc vị trí từ bộ sưu tập phương tiện"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"Cho phép ứng dụng này đọc vị trí từ bộ sưu tập phương tiện của bạn."</string>
-    <string name="biometric_dialog_default_title" msgid="881952973720613213">"Hãy xác minh đó là bạn"</string>
+    <string name="biometric_dialog_default_title" msgid="881952973720613213">"Xác minh danh tính của bạn"</string>
     <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"Không có phần cứng sinh trắc học"</string>
     <string name="biometric_error_user_canceled" msgid="2260175018114348727">"Đã hủy xác thực"</string>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Không nhận dạng được"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Biểu tượng vân tay"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"quản lý phần cứng mở khóa bằng khuôn mặt"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Cho phép ứng dụng gọi ra các phương pháp để thêm và xóa mẫu khuôn mặt sử dụng."</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"sử dụng phần cứng mở khóa bằng khuôn mặt"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"Cho phép ứng dụng dùng phần cứng mở khóa bằng khuôn mặt để tiến hành xác thực"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"Mở khóa bằng khuôn mặt"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"Đăng ký lại khuôn mặt của bạn"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"Để cải thiện khả năng nhận dạng, hãy đăng ký lại khuôn mặt của bạn"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"Không thể ghi lại đúng dữ liệu mặt. Hãy thử lại."</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Đưa điện thoại sang bên trái."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Đưa điện thoại sang bên phải."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Vui lòng nhìn thẳng vào thiết bị."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Không thấy khuôn mặt bạn. Hãy nhìn vào điện thoại."</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Hướng thẳng khuôn mặt về phía trước điện thoại."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Thiết bị di chuyển quá nhiều. Giữ yên thiết bị."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Vui lòng đăng ký lại khuôn mặt của bạn."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Không nhận ra khuôn mặt. Hãy thử lại."</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Hãy bớt di chuyển đầu."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Hãy bớt di chuyển đầu."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Hãy loại bỏ mọi thứ che khuất khuôn mặt bạn."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Hãy lau sạch cảm biến ở cạnh trên của màn hình."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Vệ sinh phần đầu màn hình, bao gồm cả thanh màu đen"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Không thể xác minh khuôn mặt. Phần cứng không có sẵn."</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"Thử lại thao tác mở khóa bằng khuôn mặt."</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"Không lưu được dữ liệu khuôn mặt mới. Hãy xóa dữ liệu cũ trước."</string>
     <string name="face_error_canceled" msgid="283945501061931023">"Đã hủy thao tác dùng khuôn mặt."</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"Người dùng đã hủy thao tác mở khóa bằng khuôn mặt."</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"Bạn đã thử quá nhiều lần. Hãy thử lại sau."</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"Quá nhiều lần thử. Đã tắt tính năng mở khóa bằng khuôn mặt."</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"Không thể xác minh khuôn mặt. Hãy thử lại."</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"Bạn chưa thiết lập tính năng mở khóa bằng khuôn mặt."</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"Thiết bị này không hỗ trợ tính năng mở khóa bằng khuôn mặt."</string>
     <string name="face_name_template" msgid="7004562145809595384">"Khuôn mặt <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -692,7 +685,7 @@
     <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Ngăn sử dụng một số tính năng của phương thức khóa màn hình."</string>
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Nhà riêng"</item>
-    <item msgid="869923650527136615">"Di Động"</item>
+    <item msgid="869923650527136615">"Di động"</item>
     <item msgid="7897544654242874543">"Cơ quan"</item>
     <item msgid="1103601433382158155">"Số fax cơ quan"</item>
     <item msgid="1735177144948329370">"Số fax nhà riêng"</item>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Mở bằng"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Mở bằng %1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Mở"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Cấp quyền truy cập để mở đường dẫn liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Cấp quyền truy cập để mở đường dẫn liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Mở đường dẫn liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Mở đường dẫn liên kết bằng"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Mở đường dẫn liên kết bằng <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Mở đường dẫn liên kết <xliff:g id="HOST">%1$s</xliff:g> bằng <xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Cấp quyền truy cập"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Chỉnh sửa bằng"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Chỉnh sửa bằng %1$s"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Khôi phục cài đặt gốc để tắt Chế độ khai thác kiểm thử."</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Có chất lỏng hoặc mảnh vỡ trong cổng USB"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Cổng USB đã tự động tắt. Nhấn để tìm hiểu thêm."</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Có thể sử dụng cổng USB"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Điện thoại không còn phát hiện chất lỏng hay mảnh vỡ nữa."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Đang thu thập báo cáo lỗi…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Chia sẻ báo cáo lỗi?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"Tìm kết quả phù hợp tiếp theo"</string>
     <string name="find_previous" msgid="2196723669388360506">"Tìm kết quả phù hợp trước"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"Yêu cầu vị trí từ <xliff:g id="NAME">%s</xliff:g>"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"Yêu cầu vị trí"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Yêu cầu truy cập vị trí"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"Được yêu cầu bởi <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"Có"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"Không"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Chạy trình duyệt?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Chấp nhận cuộc gọi?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Luôn chọn"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Đặt thành luôn mở"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Chỉ một lần"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Cài đặt"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s không hỗ trợ hồ sơ công việc"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Lớp phủ #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", an toàn"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Tính năng bắt đầu hoạt động trong nền từ <xliff:g id="PACKAGENAME">%1$s</xliff:g> này sẽ bị chặn ở các bản dựng Q trong tương lai. Hãy xem trang g.co/dev/bgblock để biết thêm chi tiết."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Tính năng bắt đầu hoạt động trong nền từ <xliff:g id="PACKAGENAME">%1$s</xliff:g> đã bị chặn. Hãy xem trang g.co/dev/bgblock để biết thêm chi tiết."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Đã quên hình"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Hình không chính xác"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Mật khẩu sai"</string>
@@ -1667,7 +1660,7 @@
     <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
     <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Xóa"</string>
     <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Bạn tăng âm lượng lên quá mức khuyên dùng?\n\nViệc nghe ở mức âm lượng cao trong thời gian dài có thể gây tổn thương thính giác của bạn."</string>
-    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Sử dụng phím tắt trợ năng?"</string>
+    <string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Sử dụng phím tắt Hỗ trợ tiếp cận?"</string>
     <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Khi phím tắt được bật, nhấn cả hai nút âm lượng trong 3 giây sẽ bắt đầu một tính năng trợ năng.\n\n Tính năng trợ năng hiện tại:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Bạn có thể thay đổi tính năng trong Cài đặt &gt; Trợ năng."</string>
     <string name="disable_accessibility_shortcut" msgid="627625354248453445">"Tắt phím tắt"</string>
     <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"Sử dụng phím tắt"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Đã bật phím tắt trợ năng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Đã tắt phím tắt trợ năng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Nhấn và giữ đồng thời cả hai phím âm lượng trong 3 giây để sử dụng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Chọn tính năng sẽ sử dụng khi bạn nhấn nút Hỗ trợ tiếp cận:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Để thay đổi các tính năng, hãy chạm và giữ nút Hỗ trợ tiếp cận."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Chọn dịch vụ sẽ sử dụng khi bạn nhấn vào nút hỗ trợ tiếp cận:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Chọn dịch vụ sẽ sử dụng với cử chỉ hỗ trợ tiếp cận (vuốt lên từ cuối màn hình bằng 2 ngón tay):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Chọn dịch vụ sẽ sử dụng với cử chỉ hỗ trợ tiếp cận (vuốt lên từ cuối màn hình bằng 3 ngón tay):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Để chuyển đổi giữa các dịch vụ, hãy chạm và giữ nút hỗ trợ tiếp cận."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Để chuyển đổi giữa các dịch vụ, hãy vuốt lên và giữ bằng 2 ngón tay."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Để chuyển đổi giữa các dịch vụ, hãy vuốt lên và giữ bằng 3 ngón tay."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Phóng to"</string>
     <string name="user_switched" msgid="3768006783166984410">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Đang chuyển sang <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index bfba312..8c50344 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -132,6 +132,8 @@
 
     <!-- Use a dark theme for watches. -->
     <style name="Theme.DeviceDefault.System" />
+    <style name="Theme.DeviceDefault.System.Dialog" parent="Theme.DeviceDefault.Dialog" />
+    <style name="Theme.DeviceDefault.System.Dialog.Alert" parent="Theme.DeviceDefault.Dialog.Alert" />
 
     <!-- DeviceDefault style for input methods, which is used by the
          {@link android.inputmethodservice.InputMethodService} class.-->
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index da239b9..1012337 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> WLAN 通话"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> WLAN 通话"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通话"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通话"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WLAN"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"车载模式"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"帐号状态"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"开发者消息"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"重要开发者消息"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"更新"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"网络状态"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"网络提醒"</string>
@@ -519,7 +521,7 @@
     <string name="permdesc_imagesWrite" msgid="7073662756617474375">"允许该应用修改您的照片收藏。"</string>
     <string name="permlab_mediaLocation" msgid="8675148183726247864">"从您的媒体收藏中读取位置信息"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"允许该应用从您的媒体收藏中读取位置信息。"</string>
-    <string name="biometric_dialog_default_title" msgid="881952973720613213">"验证是您本人"</string>
+    <string name="biometric_dialog_default_title" msgid="881952973720613213">"验证您的身份"</string>
     <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"生物识别硬件无法使用"</string>
     <string name="biometric_error_user_canceled" msgid="2260175018114348727">"身份验证已取消"</string>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"无法识别"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指纹图标"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"管理人脸解锁硬件"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"允许该应用调用方法来添加和删除可用的人脸模板。"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"使用人脸解锁硬件"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"允许该应用使用人脸解锁硬件进行身份验证"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"人脸解锁"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"重新注册您的面孔"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"要提升识别精确度,请重新注册您的面孔"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"无法捕获准确的人脸数据,请重试。"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"请将手机向左移动。"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"请将手机向右移动。"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"请直视您的设备。"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"看不清您的脸部,请直视手机。"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"请将你的面部正对手机。"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"摄像头过于晃动。请将手机拿稳。"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"请重新注册您的面孔。"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"已无法识别人脸,请重试。"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"请将您的头稍微上下倾斜。"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"请将您的头稍微左右旋转。"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"请移除所有遮挡您面部的物体。"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"请将屏幕顶部边缘的传感器擦拭干净。"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"请将屏幕顶部(包括黑色条栏)清理干净"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"无法验证人脸。硬件无法使用。"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"请重新尝试人脸解锁。"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"无法存储新的人脸数据。请先删除旧的人脸数据。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"面孔处理操作已取消。"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"用户已取消人脸解锁。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"尝试次数过多,请稍后重试。"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"尝试次数过多,人脸解锁已停用。"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"无法验证人脸,请重试。"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"您尚未设置人脸解锁。"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"此设备不支持人脸解锁。"</string>
     <string name="face_name_template" msgid="7004562145809595384">"面孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -668,8 +661,8 @@
     <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"监控在解锁屏幕时输错密码的次数,并在输错次数过多时锁定平板电脑或清空此用户的所有数据。"</string>
     <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"监控在解锁屏幕时输错密码的次数,并在输错次数过多时锁定电视或清空此用户的所有数据。"</string>
     <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"监控在解锁屏幕时输错密码的次数,并在输错次数过多时锁定手机或清空此用户的所有数据。"</string>
-    <string name="policylab_resetPassword" msgid="4934707632423915395">"更改锁屏密码"</string>
-    <string name="policydesc_resetPassword" msgid="1278323891710619128">"更改锁屏密码。"</string>
+    <string name="policylab_resetPassword" msgid="4934707632423915395">"更改锁屏方式"</string>
+    <string name="policydesc_resetPassword" msgid="1278323891710619128">"更改锁屏方式。"</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"锁定屏幕"</string>
     <string name="policydesc_forceLock" msgid="1141797588403827138">"控制屏幕锁定的方式和时间。"</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"清除所有数据"</string>
@@ -863,7 +856,7 @@
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"忘记了图案?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"帐号解锁"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"图案尝试次数过多"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"要解除锁定,请使用您的Google帐号登录。"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"要解除锁定,请使用您的 Google 帐号登录。"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"用户名(电子邮件)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"密码"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"登录"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"打开方式"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"使用%1$s打开"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"打开"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"授权使用以下应用打开 <xliff:g id="HOST">%1$s</xliff:g> 链接:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"授权使用<xliff:g id="APPLICATION">%2$s</xliff:g>打开 <xliff:g id="HOST">%1$s</xliff:g> 链接"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"<xliff:g id="HOST">%1$s</xliff:g> 链接打开方式"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"链接打开方式"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"使用<xliff:g id="APPLICATION">%1$s</xliff:g>打开链接"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"使用<xliff:g id="APPLICATION">%2$s</xliff:g>打开 <xliff:g id="HOST">%1$s</xliff:g> 链接"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"授予访问权限"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"编辑方式"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"使用%1$s编辑"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"恢复出厂设置以停用自动化测试框架模式。"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 端口中有液体或碎屑"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 端口已自动停用。点按即可了解详情。"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"允许使用 USB 端口"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手机不再检测到液体或碎屑。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在生成错误报告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享错误报告吗?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"下一条结果"</string>
     <string name="find_previous" msgid="2196723669388360506">"上一条结果"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"来自<xliff:g id="NAME">%s</xliff:g>的定位请求"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"定位请求"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"位置信息请求"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"请求人:<xliff:g id="NAME">%1$s</xliff:g>(<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"是"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"否"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"要启动浏览器吗?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"要接听电话吗?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"始终"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"设置为始终打开"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"仅此一次"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"设置"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s不支持工作资料"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"叠加视图 #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">",安全"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> 的这类后台活动启动程序会在日后的 Android Q 版本中遭到屏蔽。请参阅 g.co/dev/bgblock。"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"已屏蔽 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 的后台活动启动程序。请参阅 g.co/dev/bgblock。"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘记了图案"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"图案错误"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"密码错误"</string>
@@ -1645,7 +1638,7 @@
     <string name="kg_invalid_puk" msgid="3638289409676051243">"请重新输入正确的PUK码。如果尝试错误次数过多,SIM卡将永久停用。"</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 码不匹配"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"图案尝试次数过多"</string>
-    <string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的Google帐号。"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"要解锁,请登录您的 Google 帐号。"</string>
     <string name="kg_login_username_hint" msgid="5718534272070920364">"用户名(电子邮件地址)"</string>
     <string name="kg_login_password_hint" msgid="9057289103827298549">"密码"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"登录"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"无障碍快捷方式已开启<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"无障碍快捷方式已关闭<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"同时按住两个音量键 3 秒钟即可使用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"选择按下“无障碍”按钮时要使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"要更改指定的功能,请触摸并按住“无障碍”按钮。"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"选择按“无障碍”按钮后要使用的服务:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"选择要搭配无障碍手势(用两指从屏幕底部向上滑动)使用的服务:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"选择要搭配无障碍手势(用三指从屏幕底部向上滑动)使用的服务:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"要在多项服务之间切换,请轻触并按住“无障碍”按钮。"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"要在多项服务之间切换,请用两指向上滑动并按住。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"要在多项服务之间切换,请用三指向上滑动并按住。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大功能"</string>
     <string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 1da26f0..884772e 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"車用模式"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"帳戶狀態"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"開發人員訊息"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"重要開發人員訊息"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"更新"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"網絡狀態"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"網絡通知"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指紋圖示"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"管理臉孔解鎖硬件"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"允許應用程式調用方法,以加入和刪除可用的臉孔範本。"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"使用臉孔解鎖硬件"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"允許應用程式使用臉孔解鎖硬件來驗證"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"臉孔解鎖"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"重新註冊臉孔"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"如要提高識別能力,請重新註冊您的臉孔"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"無法擷取準確的臉容資料。請再試一次。"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"請將手機向左移。"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"請將手機向右移。"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"請以更直視的角度看著裝置。"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"看不到您的臉。請看著手機。"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"將手機對準您的臉孔正面。"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"裝置不夠穩定。請拿穩手機。"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"請重新註冊臉孔。"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"無法再識別臉孔。請再試一次。"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"減少頭部上下轉動幅度。"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"減少頭部左右轉動幅度。"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"移除遮住您臉孔的任何東西。"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"請清潔螢幕頂部邊緣的感應器。"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"請清理螢幕頂部,包括黑色列"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"無法驗證臉孔,硬件無法使用。"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"請再次嘗試「臉孔解鎖」。"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"無法儲存新的臉容資料,請先刪除舊資料。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"臉孔操作已取消。"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"使用者已取消「臉孔解鎖」。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"嘗試次數過多,請稍後再試。"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"嘗試次數過多,「臉孔解鎖」已停用。"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"無法驗證臉孔。請再試一次。"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"您尚未設定「臉孔解鎖」。"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"此裝置不支援「臉孔解鎖」。"</string>
     <string name="face_name_template" msgid="7004562145809595384">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -825,7 +818,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"再試一次"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"再試一次"</string>
     <string name="lockscreen_storage_locked" msgid="9167551160010625200">"解鎖即可使用所有功能和資料"</string>
-    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超過臉容解鎖嘗試次數上限"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"已超過臉孔解鎖嘗試次數上限"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"找不到 SIM 卡"</string>
     <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"平板電腦中沒有 SIM 卡。"</string>
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"電視沒有 SIM 卡。"</string>
@@ -895,7 +888,7 @@
     <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"展開解鎖區域。"</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"滑動解鎖。"</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"圖案解鎖。"</string>
-    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"臉容解鎖。"</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"臉孔解鎖。"</string>
     <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"PIN 解鎖。"</string>
     <string name="keyguard_accessibility_sim_pin_unlock" msgid="9149698847116962307">"SIM 卡 PIN 碼解鎖。"</string>
     <string name="keyguard_accessibility_sim_puk_unlock" msgid="9106899279724723341">"SIM 卡 PUK 解鎖。"</string>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"選擇開啟方式"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"使用 %1$s 開啟"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"開啟"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"授予存取權以透過以下應用程式開啟 <xliff:g id="HOST">%1$s</xliff:g> 連結:"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"授予存取權以透過<xliff:g id="APPLICATION">%2$s</xliff:g>開啟 <xliff:g id="HOST">%1$s</xliff:g> 連結"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"開啟 <xliff:g id="HOST">%1$s</xliff:g> 連結的方式"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"開啟連結的方式"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"使用 <xliff:g id="APPLICATION">%1$s</xliff:g> 開啟連結"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"使用 <xliff:g id="APPLICATION">%2$s</xliff:g> 開啟 <xliff:g id="HOST">%1$s</xliff:g> 連結"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"授予存取權"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"使用以下選擇器編輯:"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"使用 %1$s 編輯"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"請將裝置回復原廠設定,以停用測試工具模式。"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或碎片"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"USB 連接埠已自動停用。輕按即可瞭解詳情。"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"USB 連接埠可安全使用"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機不再偵測到液體或碎片。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在取得錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"要啟動「瀏覽器」嗎?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"接聽電話嗎?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"一律採用"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"設為一律開啟"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"只此一次"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"設定"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s 不支援公司檔案"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"重疊效果 #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"(安全)"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"在日後的 Q 版本中,系統將會封鎖這個由 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 啟動的背景活動。請瀏覽 g.co/dev/bgblock。"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"已封鎖 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 啟動的背景活動。請瀏覽 g.co/dev/bgblock。"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘記圖案"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"圖形不對"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"密碼錯誤"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"無障礙功能快速鍵已啟用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"無障礙功能快速鍵已停用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"㩒住兩個音量鍵 3 秒就可以用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"請選擇輕按「無障礙功能」按鈕時使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"如要變更功能,可按住「無障礙功能」按鈕。"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"請選擇輕按無障礙功能按鈕時使用的服務:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"請選擇透過無障礙手勢 (使用兩隻手指從螢幕底部向上滑動) 使用的服務:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"請選擇透過無障礙手勢 (使用三隻手指從螢幕底部向上滑動) 使用的服務:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"如要在服務之間切換,請按住無障礙功能按鈕。"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"如要在服務之間切換,請使用兩隻手指向上滑動並按住。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"如要在服務之間切換,請使用三隻手指向上滑動並按住。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大"</string>
     <string name="user_switched" msgid="3768006783166984410">"目前的使用者是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 2e1a697..580a1dc 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi 通話"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN 通話"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"車用模式"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"帳戶狀態"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"開發人員的訊息"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"重要開發人員訊息"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"更新"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"網路狀態"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"網路警示"</string>
@@ -549,15 +551,11 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"指紋圖示"</string>
-    <!-- no translation found for permlab_manageFace (7262837876352591553) -->
-    <skip />
+    <string name="permlab_manageFace" msgid="7262837876352591553">"管理人臉解鎖硬體"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"允許應用程式呼叫方法來新增及移除可用的臉孔範本。"</string>
-    <!-- no translation found for permlab_useFaceAuthentication (2565716575739037572) -->
-    <skip />
-    <!-- no translation found for permdesc_useFaceAuthentication (4712947955047607722) -->
-    <skip />
-    <!-- no translation found for face_recalibrate_notification_name (1913676850645544352) -->
-    <skip />
+    <string name="permlab_useFaceAuthentication" msgid="2565716575739037572">"使用人臉解鎖硬體"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="4712947955047607722">"允許應用程式使用人臉解鎖硬體進行驗證"</string>
+    <string name="face_recalibrate_notification_name" msgid="1913676850645544352">"人臉解鎖"</string>
     <string name="face_recalibrate_notification_title" msgid="4087620069451499365">"請重新註冊你的臉孔"</string>
     <string name="face_recalibrate_notification_content" msgid="5530308842361499835">"為提升辨識精準度,請重新註冊你的臉孔"</string>
     <string name="face_acquired_insufficient" msgid="2767330364802375742">"無法擷取精準臉孔資料,請再試一次。"</string>
@@ -570,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"請將手機向左移動。"</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"請將手機向右移動。"</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"請儘可能直視裝置正面。"</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"無法偵測你的臉孔,請直視手機。"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"將你的臉孔正對手機。"</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"鏡頭過度晃動,請拿穩手機。"</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"請重新註冊你的臉孔。"</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"已無法辨識臉孔,請再試一次。"</string>
@@ -579,24 +577,19 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"請將你的頭部稍微向上或向下傾斜。"</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"請將你的頭部稍微向左或向右旋轉。"</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"請移除任何會遮住臉孔的物體。"</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"請清除螢幕頂端感應器的髒汙。"</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"請清理螢幕頂端,包括黑色橫列"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"相關硬體無法使用,因此無法驗證臉孔。"</string>
-    <!-- no translation found for face_error_timeout (981512090365729465) -->
-    <skip />
+    <string name="face_error_timeout" msgid="981512090365729465">"請重新進行人臉解鎖。"</string>
     <string name="face_error_no_space" msgid="2712120617457553825">"無法儲存新的臉孔資料,請先刪除舊的資料。"</string>
     <string name="face_error_canceled" msgid="283945501061931023">"臉孔處理作業已取消。"</string>
-    <!-- no translation found for face_error_user_canceled (5317030072349668946) -->
-    <skip />
+    <string name="face_error_user_canceled" msgid="5317030072349668946">"使用者已取消人臉解鎖作業。"</string>
     <string name="face_error_lockout" msgid="3407426963155388504">"嘗試次數過多,請稍後再試。"</string>
-    <!-- no translation found for face_error_lockout_permanent (4723594314443097159) -->
-    <skip />
+    <string name="face_error_lockout_permanent" msgid="4723594314443097159">"嘗試次數過多,因此系統已停用人臉解鎖功能。"</string>
     <string name="face_error_unable_to_process" msgid="4940944939691171539">"無法驗證臉孔,請再試一次。"</string>
-    <!-- no translation found for face_error_not_enrolled (4016937174832839540) -->
-    <skip />
-    <!-- no translation found for face_error_hw_not_present (8302690289757559738) -->
-    <skip />
+    <string name="face_error_not_enrolled" msgid="4016937174832839540">"你尚未設定人臉解鎖功能。"</string>
+    <string name="face_error_hw_not_present" msgid="8302690289757559738">"這個裝置不支援人臉解鎖功能。"</string>
     <string name="face_name_template" msgid="7004562145809595384">"臉孔 <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
   </string-array>
@@ -1138,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"選擇開啟工具"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"透過 %1$s 開啟"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"開啟"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"授權系統使用以下應用程式開啟 <xliff:g id="HOST">%1$s</xliff:g> 連結"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"授權系統使用「<xliff:g id="APPLICATION">%2$s</xliff:g>」開啟 <xliff:g id="HOST">%1$s</xliff:g> 連結"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"開啟 <xliff:g id="HOST">%1$s</xliff:g> 連結時使用的瀏覽器/應用程式"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"開啟連結時使用的瀏覽器"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"使用「<xliff:g id="APPLICATION">%1$s</xliff:g>」開啟連結"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"使用「<xliff:g id="APPLICATION">%2$s</xliff:g>」開啟 <xliff:g id="HOST">%1$s</xliff:g> 連結"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"授予存取權"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"選擇編輯工具"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"使用 %1$s 編輯"</string>
@@ -1366,8 +1361,7 @@
     <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"恢復原廠設定以停用測試控管工具模式。"</string>
     <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"USB 連接埠中有液體或灰塵"</string>
     <string name="usb_contaminant_detected_message" msgid="832337061059487250">"系統已自動停用 USB 連接埠。輕觸即可瞭解詳情。"</string>
-    <!-- no translation found for usb_contaminant_not_detected_title (7708281124088684821) -->
-    <skip />
+    <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"現在可以使用 USB 連接埠"</string>
     <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"手機目前無法偵測液體或灰塵。"</string>
     <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string>
     <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string>
@@ -1503,7 +1497,7 @@
     <string name="find_next" msgid="5742124618942193978">"尋找下一個項目"</string>
     <string name="find_previous" msgid="2196723669388360506">"尋找上一個項目"</string>
     <string name="gpsNotifTicker" msgid="5622683912616496172">"<xliff:g id="NAME">%s</xliff:g> 的地點要求"</string>
-    <string name="gpsNotifTitle" msgid="5446858717157416839">"位置要求"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"位置資訊要求"</string>
     <string name="gpsNotifMessage" msgid="1374718023224000702">"要求者:<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
     <string name="gpsVerifYes" msgid="2346566072867213563">"是"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"否"</string>
@@ -1592,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"啟動「瀏覽器」嗎?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"接聽電話嗎?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"一律採用"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"設為一律開啟"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"僅限一次"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"設定"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s 不支援工作設定檔"</string>
@@ -1621,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"第 <xliff:g id="ID">%1$d</xliff:g> 個重疊效果"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>:<xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>,<xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"(安全)"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"<xliff:g id="PACKAGENAME">%1$s</xliff:g> 的這類背景活動啟動程序會在日後的 Android Q 版本遭到封鎖。請前往 g.co/dev/bgblock 查看詳情。"</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"已封鎖 <xliff:g id="PACKAGENAME">%1$s</xliff:g> 的背景活動啟動程序。請前往 g.co/dev/bgblock 查看詳情。"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"忘記圖案"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"圖案錯誤"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"密碼錯誤"</string>
@@ -1676,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"無障礙捷徑啟用了「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"無障礙捷徑停用了「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"同時按住調低及調高音量鍵三秒即可使用「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"輕觸 [無障礙設定] 按鈕後,選擇你想使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"如要變更指派的功能,請按住 [無障礙設定] 按鈕。"</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"選擇輕觸無障礙按鈕後要使用的服務:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"選擇要搭配無障礙手勢 (用兩指從螢幕底部向上滑動) 使用的服務:"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"選擇要搭配無障礙手勢 (用三指從螢幕底部向上滑動) 使用的服務:"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"如要切換不同的服務,請輕觸並按住無障礙按鈕。"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"如要切換不同的服務,請用兩指向上滑動並按住。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"如要切換不同的服務,請用三指向上滑動並按住。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"放大"</string>
     <string name="user_switched" msgid="3768006783166984410">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="2871009331809089783">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ecb1cdc..c4f8823 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -131,6 +131,7 @@
     <!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
     <skip />
     <string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ukushaya kwe-Wi-Fi"</string>
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> Ukushaya kwe-Wi-Fi"</string>
     <string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"Ikholi ye-WLAN"</string>
     <string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> ikholi ye-WLAN"</string>
     <string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
@@ -256,6 +257,7 @@
     <string name="notification_channel_car_mode" msgid="3553380307619874564">"Imodi yemoto"</string>
     <string name="notification_channel_account" msgid="7577959168463122027">"Isimo se-akhawunti"</string>
     <string name="notification_channel_developer" msgid="7579606426860206060">"Imilayezo yonjiniyela"</string>
+    <string name="notification_channel_developer_important" msgid="5251192042281632002">"Imilayezo ebalulekile kanjiniyela"</string>
     <string name="notification_channel_updates" msgid="4794517569035110397">"Izibuyekezo"</string>
     <string name="notification_channel_network_status" msgid="5025648583129035447">"Isimo senethiwekhi"</string>
     <string name="notification_channel_network_alerts" msgid="2895141221414156525">"Izexwayiso zenethiwekhi"</string>
@@ -566,7 +568,7 @@
     <string name="face_acquired_too_right" msgid="3667075962661863218">"Hambisa ifoni ngakwesokunxele."</string>
     <string name="face_acquired_too_left" msgid="3148242963894703424">"Hambisa ifoni ngakwesokudla."</string>
     <string name="face_acquired_poor_gaze" msgid="5606479370806754905">"Sicela ubheke ngokuqondile kakhulu kudivayisi yakho."</string>
-    <string name="face_acquired_not_detected" msgid="4885504661626728809">"Ayikwazi ukubona ubuso bakho. Bheka ifoni"</string>
+    <string name="face_acquired_not_detected" msgid="1879714205006680222">"Beka ubuso bakho ngqo phambi kwefoni."</string>
     <string name="face_acquired_too_much_motion" msgid="3149332171102108851">"Ukunyakaza okuningi kakhulu. Bamba ifoni iqine."</string>
     <string name="face_acquired_recalibrate" msgid="8077949502893707539">"Sicela uphinde ubhalise ubuso bakho."</string>
     <string name="face_acquired_too_different" msgid="7663983770123789694">"Ayisakwazi ukubona ubuso. Zama futhi."</string>
@@ -575,7 +577,7 @@
     <string name="face_acquired_tilt_too_extreme" msgid="4019954263012496468">"Jikisa ikhanda lakho kancane."</string>
     <string name="face_acquired_roll_too_extreme" msgid="6312973147689664409">"Jikisa ikhanda lakho kancane."</string>
     <string name="face_acquired_obscured" msgid="5357207702967893283">"Susa noma yini efihle ubuso bakho."</string>
-    <string name="face_acquired_sensor_dirty" msgid="2535761002815565222">"Hlanza inzwa kunqenqema oluphezulu lwesikrini."</string>
+    <string name="face_acquired_sensor_dirty" msgid="7905138627046865579">"Hlanza okuphezulu kwesikrini sakho, kufaka phakathi ibha emnyama"</string>
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="396883585636963908">"Ayikwazi ukuqinisekisa ubuso. Izingxenyekazi zekhompyutha azitholakali."</string>
@@ -1129,8 +1131,10 @@
     <string name="whichViewApplication" msgid="3272778576700572102">"Vula nge-"</string>
     <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Vula nge-%1$s"</string>
     <string name="whichViewApplicationLabel" msgid="2666774233008808473">"Kuvuliwe"</string>
-    <string name="whichGiveAccessToApplication" msgid="8279395245414707442">"Nika ukufinyelela kuzixhumanisi ezivulekile ze-<xliff:g id="HOST">%1$s</xliff:g> nge-"</string>
-    <string name="whichGiveAccessToApplicationNamed" msgid="7992388824107710849">"Nika ukufinyelela kuzixhumanisi ze-<xliff:g id="HOST">%1$s</xliff:g> ezivulekile nge-<xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWith" msgid="3788174881117226583">"Vula izixhumanisi ze-<xliff:g id="HOST">%1$s</xliff:g> nge"</string>
+    <string name="whichOpenLinksWith" msgid="6392123355599572804">"Vula izixhumanisi nge"</string>
+    <string name="whichOpenLinksWithApp" msgid="8225991685366651614">"Vula izixhumanisi nge-<xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
+    <string name="whichOpenHostLinksWithApp" msgid="3464470639011045589">"Vula izixhumanisi ze-<xliff:g id="HOST">%1$s</xliff:g> nge-<xliff:g id="APPLICATION">%2$s</xliff:g>"</string>
     <string name="whichGiveAccessToApplicationLabel" msgid="6142688895536868827">"Nikeza ukufinyel"</string>
     <string name="whichEditApplication" msgid="144727838241402655">"Hlela nge-"</string>
     <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Hlela nge-%1$s"</string>
@@ -1582,6 +1586,7 @@
     <string name="launchBrowserDefault" msgid="2057951947297614725">"Qala Isiphequluli?"</string>
     <string name="SetupCallDefault" msgid="5834948469253758575">"Amukela ucingo?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Njalo"</string>
+    <string name="activity_resolver_set_always" msgid="1422574191056490585">"Setha ukuthi kuhlale kuvuliwe"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Kanye nje"</string>
     <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Izilungiselelo"</string>
     <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ayisekeli iphrofayela yomsebenzi"</string>
@@ -1611,8 +1616,6 @@
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Isendlalelo #<xliff:g id="ID">%1$d</xliff:g>"</string>
     <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", kuphephile"</string>
-    <string name="activity_starter_block_bg_activity_starts_permissive" msgid="6995473033438879646">"Lesi siqalo somsebenzi ongemuva kusukela ku-<xliff:g id="PACKAGENAME">%1$s</xliff:g> sizovinjelwa ekwakhiweni okuzayo kwe-Q. Bona i-g.co/dev/bgblock."</string>
-    <string name="activity_starter_block_bg_activity_starts_enforcing" msgid="3317816771072146229">"Umsebenzi ongemuva oqala kusukela ku-<xliff:g id="PACKAGENAME">%1$s</xliff:g> uvinjelwe. Bona i-g.co/dev/bgblock."</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Ukhohlwe iphethini?"</string>
     <string name="kg_wrong_pattern" msgid="1850806070801358830">"Iphatheni engalungile"</string>
     <string name="kg_wrong_password" msgid="2333281762128113157">"Iphasiwedi engalungile"</string>
@@ -1666,8 +1669,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"Isinqamuleli sokufinyelela sivule i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"Isinqamuleli sokufinyelela sivale i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="8376923232350078434">"Cindezela uphinde ubambe bobabili okhiye bevolumu ngamasekhondi amathathu ukuze usebenzise i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
-    <string name="accessibility_button_prompt_text" msgid="4234556536456854251">"Khetha isici ozosisebenzisa uma uthepha inkinobho yokufinyelela:"</string>
-    <string name="accessibility_button_instructional_text" msgid="6942300463612999993">"Ukuze ushintshe izici, thinta uphinde ubambe inkinobho yokufinyelela."</string>
+    <string name="accessibility_button_prompt_text" msgid="1176658502969738564">"Khetha isevisi ozoyisebenzisa uma uthepha inkinobho yokufinyeleleka:"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="8259145549733019401">"Khetha isevisi ezosetshenziswa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela ngaphansi kwesikrini ngeminwe emibili):"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="1041435574275047665">"Khetha isevisi ozoyisebenzisa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela ngaphansi kwesikrini ngeminwe emithathu):"</string>
+    <string name="accessibility_button_instructional_text" msgid="7003212763213614833">"Ukuze ushintshe phakathi kwamasevisi, thinta uphinde ubambe inkinobho yokufinyeleleka."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="5261788874937410950">"Ukuze ushintshe phakathi kwamasevisi, swayiphela phezulu ngeminwe emibili uphinde ubambe."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="4969448938984394550">"Ukuze ushintshe phakathi kwamasevisi, swayiphela phezulu ngeminwe emithathu uphinde ubambe."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1227146738764986237">"Ukukhuliswa"</string>
     <string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="2871009331809089783">"Ishintshela ku-<xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 041ba02..0c9ae85 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1560,7 +1560,8 @@
         <flag name="email" value="0x02" />
         <!-- Match phone numbers. -->
         <flag name="phone" value="0x04" />
-        <!-- Match map addresses. -->
+        <!-- Match map addresses.
+             Deprecated: see {@link android.text.util.Linkify#MAP_ADDRESSES}. -->
         <flag name="map" value="0x08" />
         <!-- Match all patterns (equivalent to web|email|phone|map). -->
         <flag name="all" value="0x0f" />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 8dfb969..be6cdcf 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -326,6 +326,8 @@
              grantable in its full form to apps that meet special criteria
              per platform policy. Otherwise, a weaker form of the permission
              would be granted. The weak grant depends on the permission.
+             <p>What weak grant means is described in the documentation of
+             the permissions.
         -->
         <flag name="softRestricted" value="0x8" />
         <!-- This permission is restricted immutably which means that its
@@ -1313,7 +1315,11 @@
          it will yield the baseIntent to any activity that it launches in the same task. This
          continues until an activity is encountered which has this attribute set to false. False
          is the default. This attribute set to true also permits activity's use of the
-         TaskDescription to change labels, colors and icons in the recent task list. -->
+         TaskDescription to change labels, colors and icons in the recent task list.
+
+         <p>NOTE: Setting this flag to <code>true</code> will not change the affinity of the task,
+         which is used for intent resolution during activity launch. The task's root activity will
+         always define its affinity. -->
     <attr name="relinquishTaskIdentity" format="boolean" />
 
     <!-- Indicate that it is okay for this activity be resumed while the previous
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 048f341..1dcd389 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -79,6 +79,7 @@
 
     <drawable name="input_method_fullscreen_background">#fff9f9f9</drawable>
     <color name="decor_view_status_guard">#ff000000</color>
+    <color name="decor_view_status_guard_light">#ffffffff</color>
 
     <!-- For date picker widget -->
     <drawable name="selected_day_background">#ff0092f4</drawable>
@@ -218,4 +219,9 @@
     <color name="chooser_row_divider">@color/list_divider_color_light</color>
     <color name="chooser_gradient_background">@color/loading_gradient_background_color_light</color>
     <color name="chooser_gradient_highlight">@color/loading_gradient_highlight_color_light</color>
+
+    <color name="GM2_grey_800">#ff3C4043</color>
+
+    <!-- Resolver/Chooser -->
+    <color name="resolver_text_color_secondary_dark">#ffC4C6C6</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6a8d391..3b12753 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -364,7 +364,7 @@
          overridden by the device to present the capability of creating socket keepalives. -->
     <!-- An Array of "[NetworkCapabilities.TRANSPORT_*],[supported keepalives] -->
     <string-array translatable="false" name="config_networkSupportedKeepaliveCount">
-        <item>0,3</item>
+        <item>0,1</item>
         <item>1,3</item>
     </string-array>
 
@@ -1115,6 +1115,22 @@
          regularly selected color mode will be used if this value is negative. -->
     <integer name="config_accessibilityColorMode">-1</integer>
 
+    <!-- The following two arrays specify which color space to use for display composition when a
+         certain color mode is active.
+         Composition color spaces are defined in android.view.Display.COLOR_MODE_xxx, and color
+         modes are defined in ColorDisplayManager.COLOR_MODE_xxx and
+         ColorDisplayManager.VENDOR_COLOR_MODE_xxx.
+         The color space COLOR_MODE_DEFAULT (0) lets the system select the most appropriate
+         composition color space for currently displayed content. Other values (e.g.,
+         COLOR_MODE_SRGB) override system selection; these other color spaces must be supported by
+         the device for for display composition.
+         If a color mode does not have a corresponding color space specified in this array, the
+         currently set composition color space will not be modified.-->
+    <integer-array name="config_displayCompositionColorModes">
+    </integer-array>
+    <integer-array name="config_displayCompositionColorSpaces">
+    </integer-array>
+
     <!-- Indicate whether to allow the device to suspend when the screen is off
          due to the proximity sensor.  This resource should only be set to true
          if the sensor HAL correctly handles the proximity sensor as a wake-up source.
@@ -2283,7 +2299,7 @@
          effectively and terminate the dream.  Use -1 to disable this safety feature.  -->
     <integer name="config_dreamsBatteryLevelDrainCutoff">5</integer>
     <!-- Limit of how long the device can remain unlocked due to attention checking.  -->
-    <integer name="config_attentionMaximumExtension">240000</integer> <!-- 4 minutes -->
+    <integer name="config_attentionMaximumExtension">330000</integer> <!-- 5 minutes and 30 sec.-->
     <!-- How long we should wait until we give up on receiving an attention API callback.  -->
     <integer name="config_attentionApiTimeout">2000</integer> <!-- 2 seconds -->
 
@@ -2787,6 +2803,9 @@
          screen. -->
     <bool name="config_lowRamTaskSnapshotsAndRecents">false</bool>
 
+    <!-- The amount to scale fullscreen snapshots for Overview and snapshot starting windows. -->
+    <item name="config_fullTaskSnapshotScale" format="float" type="dimen">1.0</item>
+
     <!-- Determines whether recent tasks are provided to the user. Default device has recents
          property. If this is false, then the following recents config flags are ignored. -->
     <bool name="config_hasRecents">true</bool>
@@ -2986,6 +3005,14 @@
          empty string is passed in -->
     <string name="config_wlan_data_service_package" translatable="false"></string>
 
+    <!-- Cellular data service class name to bind to by default. If none is specified in an overlay, an
+         empty string is passed in -->
+    <string name="config_wwan_data_service_class" translatable="false"></string>
+
+    <!-- IWLAN data service class name to bind to by default. If none is specified in an overlay, an
+         empty string is passed in -->
+    <string name="config_wlan_data_service_class" translatable="false"></string>
+
     <bool name="config_networkSamplingWakesDevice">true</bool>
 
     <!--From SmsMessage-->
@@ -3279,7 +3306,8 @@
          various workspace stacks.
          0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
          1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
-         opaque.
+             opaque.
+         2 - Nav bar is never forced opaque.
          -->
     <integer name="config_navBarOpacityMode">0</integer>
 
@@ -3422,18 +3450,6 @@
          TODO: move to input HAL once ready. -->
     <string name="config_doubleTouchGestureEnableFile"></string>
 
-    <!-- Controls how we deal with externally connected physical keyboards.
-         0 - When using this device, it is not clear for users to recognize when the physical
-             keyboard is (should be) connected and when it is (should be) disconnected.  Most of
-             phones and tablets with Bluetooth keyboard would fall into this category because the
-             connected Bluetooth keyboard may or may not be nearby the host device.
-         1 - When using this device, it is clear for users to recognize when the physical
-             keyboard is (should be) connected and when it is (should be) disconnected.
-             Devices with wired USB keyboard is one clear example.  Some 2-in-1 convertible
-             tablets with dedicated keyboards may have the same affordance to wired USB keyboard.
-    -->
-    <integer name="config_externalHardKeyboardBehavior">0</integer>
-
     <!-- Package of the unbundled tv remote service which can connect to tv
          remote provider -->
     <string name="config_tvRemoteServicePackage" translatable="false"></string>
@@ -3783,9 +3799,11 @@
     <integer name="config_stableDeviceDisplayWidth">-1</integer>
     <integer name="config_stableDeviceDisplayHeight">-1</integer>
 
-    <!-- Decide whether to display 'No service' on status bar instead of 'Emergency calls only'
-         when SIM is unready. -->
-    <bool name="config_display_no_service_when_sim_unready">false</bool>
+    <!-- List of countries in which we display 'No service' on status bar
+         instead of 'Emergency calls only' when SIM is unready. -->
+    <string-array translatable="false" name="config_display_no_service_when_sim_unready">
+        <item>"DE"</item>
+    </string-array>
 
     <!-- Class names of device specific services inheriting com.android.server.SystemService. The
          classes are instantiated in the order of the array. -->
@@ -3834,13 +3852,21 @@
     <!-- Cellular network service package name to bind to by default. -->
     <string name="config_wwan_network_service_package" translatable="false">com.android.phone</string>
 
+    <!-- Cellular network service class name to bind to by default.-->
+    <string name="config_wwan_network_service_class" translatable="false"></string>
+
     <!-- IWLAN network service package name to bind to by default. If none is specified in an overlay, an
          empty string is passed in -->
     <string name="config_wlan_network_service_package" translatable="false"></string>
 
+    <!-- IWLAN network service class name to bind to by default. If none is specified in an overlay, an
+         empty string is passed in -->
+    <string name="config_wlan_network_service_class" translatable="false"></string>
     <!-- Telephony qualified networks service package name to bind to by default. -->
     <string name="config_qualified_networks_service_package" translatable="false"></string>
 
+    <!-- Telephony qualified networks service class name to bind to by default. -->
+    <string name="config_qualified_networks_service_class" translatable="false"></string>
     <!-- Wear devices: Controls the radios affected by Activity Mode. -->
     <string-array name="config_wearActivityModeRadios">
         <item>"wifi"</item>
@@ -3902,6 +3928,10 @@
          {@see android.view.Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS} -->
     <string name="config_secondaryHomeComponent" translatable="false">com.android.launcher3/com.android.launcher3.SecondaryDisplayLauncher</string>
 
+    <!-- Force secondary home launcher specified in config_secondaryHomeComponent always. If this is
+         not set, secondary home launcher can be replaced by user. -->
+    <bool name ="config_useSystemProvidedLauncherForSecondary">false</bool>
+
     <!-- If device supports corner radius on windows.
          This should be turned off on low-end devices to improve animation performance. -->
     <bool name="config_supportsRoundedCornersOnWindows">true</bool>
@@ -4013,16 +4043,62 @@
     </array>
 
     <!-- See DisplayWhiteBalanceController.
-         The ambient brightness threshold (in lux) beneath which we fall back to a fixed ambient
-         color temperature. -->
-    <item name="config_displayWhiteBalanceLowLightAmbientBrightnessThreshold" format="float" type="dimen">10.0</item>
+         A float array containing a list of ambient brightnesses, in Lux. This array,
+         together with config_displayWhiteBalanceLowLightAmbientBiases, is used to generate a
+         lookup table used in DisplayWhiteBalanceController. This lookup table is used to map
+         ambient brightness readings to a bias, where the bias is used to linearly interpolate
+         between ambient color temperature and
+         config_displayWhiteBalanceLowLightAmbientColorTemperature.
+         This table is optional. If used, this array must,
+         1) Contain at least two entries
+         2) Be the same length as config_displayWhiteBalanceLowLightAmbientBiases. -->
+    <array name ="config_displayWhiteBalanceLowLightAmbientBrightnesses">
+        <item>10.0</item>
+        <item>10.0</item>
+    </array>
 
     <!-- See DisplayWhiteBalanceController.
-         The ambient color temperature (in cct) to which we fall back when the ambient brightness
-         drops beneath a certain threshold. -->
+         An array containing a list of biases. See
+         config_displayWhiteBalanceLowLightAmbientBrightnesses for additional details.
+         This array must be in the range of [0.0, 1.0]. -->
+    <array name ="config_displayWhiteBalanceLowLightAmbientBiases">
+        <item>0.0</item>
+        <item>1.0</item>
+    </array>
+
+    <!-- See DisplayWhiteBalanceController.
+         The ambient color temperature (in cct) to which we interpolate towards using the
+         the look up table generated by config_displayWhiteBalanceLowLightAmbientBrightnesses
+         and config_displayWhiteBalanceLowLightAmbientBiases. -->
     <item name="config_displayWhiteBalanceLowLightAmbientColorTemperature" format="float" type="dimen">6500.0</item>
 
     <!-- See DisplayWhiteBalanceController.
+         A float array containing a list of ambient brightnesses, in Lux. This array,
+         together with config_displayWhiteBalanceHighLightAmbientBiases, is used to generate a
+         lookup table used in DisplayWhiteBalanceController. This lookup table is used to map
+         ambient brightness readings to a bias, where the bias is used to linearly interpolate
+         between ambient color temperature and
+         config_displayWhiteBalanceHighLightAmbientColorTemperature.
+         This table is optional. If used, this array must,
+         1) Contain at least two entries
+         2) Be the same length as config_displayWhiteBalanceHighLightAmbientBiases. -->
+    <array name ="config_displayWhiteBalanceHighLightAmbientBrightnesses">
+    </array>
+
+    <!-- See DisplayWhiteBalanceController.
+         An array containing a list of biases. See
+         config_displayWhiteBalanceHighLightAmbientBrightnesses for additional details.
+         This array must be in the range of [0.0, 1.0]. -->
+    <array name ="config_displayWhiteBalanceHighLightAmbientBiases">
+    </array>
+
+    <!-- See DisplayWhiteBalanceController.
+         The ambient color temperature (in cct) to which we interpolate towards using the
+         the look up table generated by config_displayWhiteBalanceHighLightAmbientBrightnesses
+         and config_displayWhiteBalanceHighLightAmbientBiases. -->
+    <item name="config_displayWhiteBalanceHighLightAmbientColorTemperature" format="float" type="dimen">8000.0</item>
+
+    <!-- See DisplayWhiteBalanceController.
          A float array containing a list of ambient color temperatures, in Kelvin. This array,
          together with config_displayWhiteBalanceDisplayColorTemperatures, is used to generate a
          lookup table used in DisplayWhiteBalanceController. This lookup table is used to map
@@ -4056,6 +4132,15 @@
         M9,10l-2,0l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0z
     </string>
 
+    <!-- X path for SignalDrawable as defined on a 24x24 canvas. -->
+    <string name="config_signalXPath" translatable="false">
+        M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09-2.08L20.59,22L22,20.59l-2.08-2.09   L22,16.41z
+    </string>
+    <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that
+         should be cut out to display config_signalXPath.-->
+    <item name="config_signalCutoutWidthFraction" format="float" type="dimen">11</item>
+    <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item>
+
     <!-- A dual tone battery meter draws the perimeter path twice - once to define the shape
      and a second time clipped to the fill level to indicate charge -->
     <bool name="config_batterymeterDualTone">false</bool>
@@ -4064,6 +4149,28 @@
          for higher refresh rates to be automatically used out of the box -->
     <integer name="config_defaultPeakRefreshRate">60</integer>
 
+    <!-- The display uses different gamma curves for different refresh rates. It's hard for panel
+         vendor to tune the curves to have exact same brightness for different refresh rate. So
+         flicker could be observed at switch time. The issue is worse at the gamma lower end.
+         In addition, human eyes are more sensitive to the flicker at darker environment.
+         To prevent flicker, we only support higher refresh rates if the display brightness is above
+         a threshold. And the darker environment could have higher threshold.
+         For example, no higher refresh rate if
+             display brightness <= disp0 && ambient brightness <= amb0
+             || display brightness <= disp1 && ambient brightness <= amb1 -->
+    <integer-array translatable="false" name="config_brightnessThresholdsOfPeakRefreshRate">
+         <!--
+           <item>disp0</item>
+           <item>disp1</item>
+        -->
+    </integer-array>
+    <integer-array translatable="false" name="config_ambientThresholdsOfPeakRefreshRate">
+         <!--
+           <item>amb0</item>
+           <item>amb1</item>
+        -->
+    </integer-array>
+
     <!-- 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" />
@@ -4138,4 +4245,23 @@
          one bar higher than they actually are -->
     <bool name="config_inflateSignalStrength">false</bool>
 
+    <!-- Trigger a warning for notifications with RemoteView objects that are larger in bytes than
+    this value (default 1MB)-->
+    <integer name="config_notificationWarnRemoteViewSizeBytes">1000000</integer>
+
+    <!-- Strip notification RemoteView objects that are larger in bytes than this value (also log)
+    (default 2MB) -->
+    <integer name="config_notificationStripRemoteViewSizeBytes">2000000</integer>
+
+    <!-- Sharesheet: define a max number of targets per application for new shortcuts-based direct share introduced in Q -->
+    <integer name="config_maxShortcutTargetsPerApp">3</integer>
+
+    <!-- The package name for the vendor implementation of ACTION_FACTORY_RESET. For some vendors,
+    the default implementation of ACTION_FACTORY_RESET does not work, so it is needed to re-route
+    this intent to this package. This is being used in MasterClearReceiver.java. -->
+    <string name="config_factoryResetPackage" translatable="false"></string>
+
+    <!-- The list of packages to automatically opt out of refresh rates higher than 60hz because
+         of known compatibility issues. -->
+    <string-array name="config_highRefreshRateBlacklist"></string-array>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 5363ef9..6653879 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -90,6 +90,24 @@
         orientation. If zero, the value of rounded_corner_radius is used. -->
     <dimen name="rounded_corner_radius_bottom">0dp</dimen>
 
+    <!-- Default adjustment for the software rounded corners since corners are not perfectly
+        round. This value is used when retrieving the "radius" of the rounded corner in cases
+        where the exact bezier curve cannot be retrieved.  This value will be subtracted from
+        rounded_corner_radius to more accurately provide a "radius" for the rounded corner. -->
+    <dimen name="rounded_corner_radius_adjustment">0px</dimen>
+    <!-- Top adjustment for the software rounded corners since corners are not perfectly
+        round.  This value is used when retrieving the "radius" of the top rounded corner in cases
+        where the exact bezier curve cannot be retrieved.  This value will be subtracted from
+        rounded_corner_radius_top to more accurately provide a "radius" for the top rounded corners.
+         -->
+    <dimen name="rounded_corner_radius_top_adjustment">0px</dimen>
+    <!-- Bottom adjustment for the software rounded corners since corners are not perfectly
+        round.  This value is used when retrieving the "radius" of the bottom rounded corner in
+        cases where the exact bezier curve cannot be retrieved.  This value will be subtracted from
+        rounded_corner_radius_bottom to more accurately provide a "radius" for the bottom rounded
+        corners. -->
+    <dimen name="rounded_corner_radius_bottom_adjustment">0px</dimen>
+
     <!-- Width of the window of the divider bar used to resize docked stacks. -->
     <dimen name="docked_stack_divider_thickness">48dp</dimen>
 
@@ -261,7 +279,7 @@
     <dimen name="notification_expand_button_padding_top">1dp</dimen>
 
     <!-- Height of a small notification in the status bar -->
-    <dimen name="notification_min_height">92dp</dimen>
+    <dimen name="notification_min_height">106dp</dimen>
 
     <!-- The width of the big icons in notifications. -->
     <dimen name="notification_large_icon_width">64dp</dimen>
diff --git a/core/res/res/values/dimens_car.xml b/core/res/res/values/dimens_car.xml
index 12a9ea2..bd4c484 100644
--- a/core/res/res/values/dimens_car.xml
+++ b/core/res/res/values/dimens_car.xml
@@ -147,5 +147,6 @@
     <dimen name="action_bar_margin_end">@*android:dimen/car_margin</dimen>
     <!-- Space between a button and another button or screen edge -->
     <dimen name="action_bar_button_margin">@*android:dimen/car_padding_4</dimen>
+    <dimen name="action_bar_button_max_width">268dp</dimen>
     <dimen name="action_bar_toggle_internal_padding">@*android:dimen/car_padding_3</dimen>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fe49a31..913001c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -252,12 +252,15 @@
         <item>@string/wfcSpnFormat_wifi</item>
         <item>@string/wfcSpnFormat_wifi_calling_wo_hyphen</item>
         <item>@string/wfcSpnFormat_vowifi</item>
+        <item>@string/wfcSpnFormat_spn_wifi_calling_vo_hyphen</item>
     </string-array>
 
     <!-- Spn during Wi-Fi Calling: "<operator>" -->
     <string name="wfcSpnFormat_spn"><xliff:g id="spn" example="Operator">%s</xliff:g></string>
     <!-- Spn during Wi-Fi Calling: "<operator> Wi-Fi Calling" -->
     <string name="wfcSpnFormat_spn_wifi_calling"><xliff:g id="spn" example="Operator">%s</xliff:g> Wi-Fi Calling</string>
+    <!-- Spn during Wi-Fi Calling: "<operator> WiFi Calling" -->
+    <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen"><xliff:g id="spn" example="Operator">%s</xliff:g> WiFi Calling</string>
     <!-- Spn during Wi-Fi Calling: "WLAN Call" -->
     <string name="wfcSpnFormat_wlan_call">WLAN Call</string>
     <!-- Spn during Wi-Fi Calling: "<operator> WLAN Call" -->
@@ -618,6 +621,9 @@
     <!-- Text shown when viewing channel settings for notifications related to developers -->
     <string name="notification_channel_developer">Developer messages</string>
 
+    <!-- Text shown when viewing channel settings for high importance notifications related to developers [CHAR LIMIT=60]-->
+    <string name="notification_channel_developer_important">Important developer messages</string>
+
     <!-- Text shown when viewing channel settings for notifications related to system updates -->
     <string name="notification_channel_updates">Updates</string>
 
@@ -1535,7 +1541,7 @@
     <!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
     <string name="face_acquired_poor_gaze">Please look more directly at your device.</string>
     <!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
-    <string name="face_acquired_not_detected">Can\u2019t see your face. Look at the phone.</string>
+    <string name="face_acquired_not_detected">Position your face directly in front of the phone.</string>
     <!-- Message shown during face acquisition when the device is not steady [CHAR LIMIT=50] -->
     <string name="face_acquired_too_much_motion">Too much motion. Hold phone steady.</string>
     <!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=50] -->
@@ -1552,8 +1558,8 @@
     <string name="face_acquired_roll_too_extreme">Turn your head a little less.</string>
     <!-- Message shown during acquisition when the user's face is obscured [CHAR LIMIT=50] -->
     <string name="face_acquired_obscured">Remove anything hiding your face.</string>
-    <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=50] -->
-    <string name="face_acquired_sensor_dirty">Clean the sensor at the top edge of the screen.</string>
+    <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=100] -->
+    <string name="face_acquired_sensor_dirty">Clean the top of your screen, including the black bar</string>
     <!-- Array containing custom messages shown during face acquisition from vendor.  Vendor is expected to add and translate these strings -->
     <string-array name="face_acquired_vendor">
     </string-array>
@@ -3071,12 +3077,20 @@
     <string name="whichViewApplicationNamed">Open with %1$s</string>
     <!-- Label for a link to a intent resolver dialog to view something -->
     <string name="whichViewApplicationLabel">Open</string>
-    <!-- Title of intent resolver dialog when selecting a viewer application that opens URI
+    <!-- Title of intent resolver dialog when selecting a browser/application that opens specific URIs
          [CHAR LIMIT=128]. -->
-    <string name="whichGiveAccessToApplication">Give access to open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with</string>
+    <string name="whichOpenHostLinksWith">Open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with</string>
+    <!-- Title of intent resolver dialog when selecting a browser that opens URI
+         [CHAR LIMIT=128]. -->
+    <string name="whichOpenLinksWith">Open links with</string>
+    <!-- Title of intent resolver dialog when defaulting to a specific browser that opens URI
+         [CHAR LIMIT=128]. -->
+    <string name="whichOpenLinksWithApp">Open links with <xliff:g id="application" example="Chrome">%1$s</xliff:g></string>
+    <!-- Title of intent resolver dialog when defaulting to a specific browser that opens URI
+         [CHAR LIMIT=128]. -->
+    <string name="whichOpenHostLinksWithApp">Open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with <xliff:g id="application" example="Chrome">%2$s</xliff:g></string>
     <!-- Title of intent resolver dialog when selecting a viewer application that opens URI
          and a previously used application is known [CHAR LIMIT=128]. -->
-    <string name="whichGiveAccessToApplicationNamed">Give access to open <xliff:g id="host" example="mail.google.com">%1$s</xliff:g> links with <xliff:g id="application" example="Gmail">%2$s</xliff:g></string>
     <!-- Label for a link to an intent resolver dialog to open URI [CHAR LIMIT=18] -->
     <string name="whichGiveAccessToApplicationLabel">Give access</string>
     <!-- Title of intent resolver dialog when selecting an editor application to run. -->
@@ -4209,6 +4223,10 @@
     <string name="activity_resolver_use_always">Always</string>
 
     <!-- Title for a button to choose the currently selected activity
+         as the default in the activity resolver. [CHAR LIMIT=50] -->
+    <string name="activity_resolver_set_always">Set to always open</string>
+
+    <!-- Title for a button to choose the currently selected activity
          from the activity resolver to use just this once. [CHAR LIMIT=25] -->
     <string name="activity_resolver_use_once">Just once</string>
 
@@ -4305,13 +4323,6 @@
     <!-- Title text to append when the display is secure.  [CHAR LIMIT=30] -->
     <string name="display_manager_overlay_display_secure_suffix">, secure</string>
 
-    <!-- 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 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 g.co/dev/bgblock. </string>
-
     <!-- Keyguard strings -->
     <!-- Message shown in pattern unlock after some number of unsuccessful attempts -->
     <string name="kg_forgot_pattern_button_text">Forgot Pattern</string>
@@ -4495,10 +4506,18 @@
         <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g></string>
 
     <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button in the navigation bar. -->
-    <string name="accessibility_button_prompt_text">Choose a feature to use when you tap the Accessibility button:</string>
+    <string name="accessibility_button_prompt_text">Choose a service to use when you tap the accessibility button:</string>
+    <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button when gesture navigation is enabled [CHAR LIMIT=none] -->
+    <string name="accessibility_gesture_prompt_text">Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):</string>
+    <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button when gesture navigation and TalkBack is enabled [CHAR LIMIT=none] -->
+    <string name="accessibility_gesture_3finger_prompt_text">Choose a service to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):</string>
 
     <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button in the navigation bar. -->
-    <string name="accessibility_button_instructional_text">To change features, touch &amp; hold the Accessibility button.</string>
+    <string name="accessibility_button_instructional_text">To switch between services, touch &amp; hold the accessibility button.</string>
+    <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button when gesture navigation is enabled. [CHAR LIMIT=none] -->
+    <string name="accessibility_gesture_instructional_text">To switch between services, swipe up with two fingers and hold.</string>
+    <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button when gesture navigation and TalkBack is enabled. [CHAR LIMIT=none] -->
+    <string name="accessibility_gesture_3finger_instructional_text">To switch between services, swipe up with three fingers and hold.</string>
 
     <!-- Text used to describe system navigation features, shown within a UI allowing a user to assign system magnification features to the Accessibility button in the navigation bar. -->
     <string name="accessibility_magnification_chooser_text">Magnification</string>
diff --git a/core/res/res/values/styles_car.xml b/core/res/res/values/styles_car.xml
index d2f5cbb..ca3ba93 100644
--- a/core/res/res/values/styles_car.xml
+++ b/core/res/res/values/styles_car.xml
@@ -87,6 +87,11 @@
     </style>
 
     <!-- Action bar -->
+    <style name="ActionBarTitle" parent="@style/Widget.DeviceDefault.TextView">
+        <item name="android:singleLine">true</item>
+        <item name="android:textAppearance">?attr/textAppearanceLarge</item>
+    </style>
+
     <style name="ActionBarButton"
            parent="@style/Widget.DeviceDefault.Button.Borderless.Colored">
         <item name="android:textAppearance">@style/ActionBarButtonTextAppearance</item>
@@ -94,11 +99,11 @@
         <item name="android:paddingStart">@*android:dimen/car_padding_3</item>
         <item name="android:paddingEnd">@*android:dimen/car_padding_3</item>
         <item name="android:drawablePadding">@*android:dimen/car_padding_2</item>
+        <item name="android:maxWidth">@*android:dimen/action_bar_button_max_width</item>
     </style>
 
     <style name="ActionBarButtonTextAppearance"
            parent="@style/TextAppearance.DeviceDefault.Widget.Button.Borderless.Colored">
-        <item name="android:singleLine">true</item>
         <item name="android:textAllCaps">false</item>
     </style>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ff5845f..d91bbd0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -299,9 +299,14 @@
   <java-symbol type="bool" name="config_dynamic_bind_ims" />
   <java-symbol type="string" name="config_wwan_network_service_package" />
   <java-symbol type="string" name="config_wlan_network_service_package" />
+  <java-symbol type="string" name="config_wwan_network_service_class" />
+  <java-symbol type="string" name="config_wlan_network_service_class" />
   <java-symbol type="string" name="config_wwan_data_service_package" />
   <java-symbol type="string" name="config_wlan_data_service_package" />
+  <java-symbol type="string" name="config_wwan_data_service_class" />
+  <java-symbol type="string" name="config_wlan_data_service_class" />
   <java-symbol type="string" name="config_qualified_networks_service_package" />
+  <java-symbol type="string" name="config_qualified_networks_service_class" />
   <java-symbol type="bool" name="config_networkSamplingWakesDevice" />
   <java-symbol type="bool" name="config_showMenuShortcutsWhenKeyboardPresent" />
   <java-symbol type="bool" name="config_sip_wifi_only" />
@@ -355,6 +360,7 @@
   <java-symbol type="bool" name="config_enableMultiUserUI"/>
   <java-symbol type="bool" name="config_enableNewAutoSelectNetworkUI"/>
   <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
+  <java-symbol type="dimen" name="config_fullTaskSnapshotScale" />
   <java-symbol type="bool" name="config_lowRamTaskSnapshotsAndRecents" />
   <java-symbol type="bool" name="config_hasRecents" />
   <java-symbol type="string" name="config_recentsComponentName" />
@@ -766,8 +772,6 @@
   <java-symbol type="string" name="display_manager_hdmi_display_name" />
   <java-symbol type="string" name="display_manager_overlay_display_name" />
   <java-symbol type="string" name="display_manager_overlay_display_secure_suffix" />
-  <java-symbol type="string" name="activity_starter_block_bg_activity_starts_permissive" />
-  <java-symbol type="string" name="activity_starter_block_bg_activity_starts_enforcing" />
   <java-symbol type="string" name="display_manager_overlay_display_title" />
   <java-symbol type="string" name="double_tap_toast" />
   <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" />
@@ -1964,6 +1968,7 @@
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
   <java-symbol type="color" name="config_defaultNotificationColor" />
   <java-symbol type="color" name="decor_view_status_guard" />
+  <java-symbol type="color" name="decor_view_status_guard_light" />
   <java-symbol type="drawable" name="ic_notification_ime_default" />
   <java-symbol type="drawable" name="ic_menu_refresh" />
   <java-symbol type="drawable" name="ic_settings" />
@@ -2011,7 +2016,6 @@
   <java-symbol type="integer" name="config_defaultNotificationLedOff" />
   <java-symbol type="integer" name="config_defaultNotificationLedOn" />
   <java-symbol type="integer" name="config_deskDockKeepsScreenOn" />
-  <java-symbol type="integer" name="config_externalHardKeyboardBehavior" />
   <java-symbol type="integer" name="config_lightSensorWarmupTime" />
   <java-symbol type="integer" name="config_lowBatteryCloseWarningBump" />
   <java-symbol type="integer" name="config_lowBatteryWarningLevel" />
@@ -2238,7 +2242,6 @@
   <java-symbol type="id" name="resolver_list" />
   <java-symbol type="id" name="button_once" />
   <java-symbol type="id" name="button_always" />
-  <java-symbol type="id" name="button_app_settings" />
   <java-symbol type="integer" name="config_globalActionsKeyTimeout" />
   <java-symbol type="integer" name="config_screenshotChordKeyTimeout" />
   <java-symbol type="integer" name="config_maxResolverActivityColumns" />
@@ -2269,6 +2272,7 @@
   <java-symbol type="anim" name="lock_screen_behind_enter" />
   <java-symbol type="anim" name="lock_screen_behind_enter_wallpaper" />
   <java-symbol type="anim" name="lock_screen_behind_enter_fade_in" />
+  <java-symbol type="anim" name="lock_screen_behind_enter_subtle" />
   <java-symbol type="anim" name="lock_screen_wallpaper_exit" />
   <java-symbol type="anim" name="launch_task_behind_source" />
   <java-symbol type="anim" name="wallpaper_open_exit" />
@@ -2619,14 +2623,17 @@
   <java-symbol type="bool" name="config_use_voip_mode_for_ims" />
   <java-symbol type="attr" name="touchscreenBlocksFocus" />
   <java-symbol type="layout" name="resolver_list_with_default" />
-  <java-symbol type="string" name="activity_resolver_app_settings" />
+  <java-symbol type="string" name="activity_resolver_set_always" />
+  <java-symbol type="string" name="activity_resolver_use_always" />
   <java-symbol type="string" name="whichApplicationNamed" />
   <java-symbol type="string" name="whichApplicationLabel" />
   <java-symbol type="string" name="whichViewApplication" />
   <java-symbol type="string" name="whichViewApplicationNamed" />
   <java-symbol type="string" name="whichViewApplicationLabel" />
-  <java-symbol type="string" name="whichGiveAccessToApplication" />
-  <java-symbol type="string" name="whichGiveAccessToApplicationNamed" />
+  <java-symbol type="string" name="whichOpenHostLinksWith" />
+  <java-symbol type="string" name="whichOpenHostLinksWithApp" />
+  <java-symbol type="string" name="whichOpenLinksWith" />
+  <java-symbol type="string" name="whichOpenLinksWithApp" />
   <java-symbol type="string" name="whichGiveAccessToApplicationLabel" />
   <java-symbol type="string" name="whichEditApplication" />
   <java-symbol type="string" name="whichEditApplicationNamed" />
@@ -2808,6 +2815,7 @@
   <java-symbol type="layout" name="chooser_grid_preview_file" />
   <java-symbol type="id" name="chooser_row_text_option" />
   <java-symbol type="dimen" name="chooser_row_text_option_translate" />
+  <java-symbol type="integer" name="config_maxShortcutTargetsPerApp" />
   <java-symbol type="layout" name="resolve_grid_item" />
   <java-symbol type="id" name="day_picker_view_pager" />
   <java-symbol type="layout" name="day_picker_content_material" />
@@ -3188,6 +3196,8 @@
   <java-symbol type="array" name="config_nightDisplayColorTemperatureCoefficientsNative" />
   <java-symbol type="array" name="config_availableColorModes" />
   <java-symbol type="integer" name="config_accessibilityColorMode" />
+  <java-symbol type="array" name="config_displayCompositionColorModes" />
+  <java-symbol type="array" name="config_displayCompositionColorSpaces" />
   <java-symbol type="bool" name="config_displayWhiteBalanceAvailable" />
   <java-symbol type="bool" name="config_displayWhiteBalanceEnabledDefault" />
   <java-symbol type="integer" name="config_displayWhiteBalanceColorTemperatureMin" />
@@ -3261,6 +3271,9 @@
   <java-symbol type="string" name="config_batterymeterBoltPath" />
   <java-symbol type="string" name="config_batterymeterPowersavePath" />
   <java-symbol type="bool" name="config_batterymeterDualTone" />
+  <java-symbol type="string" name="config_signalXPath" />
+  <java-symbol type="dimen" name="config_signalCutoutWidthFraction" />
+  <java-symbol type="dimen" name="config_signalCutoutHeightFraction" />
 
   <java-symbol type="bool" name="config_debugEnableAutomaticSystemServerHeapDumps" />
   <java-symbol type="integer" name="config_debugSystemServerPssThresholdBytes" />
@@ -3282,9 +3295,16 @@
   <java-symbol type="layout" name="accessibility_button_chooser_item" />
   <java-symbol type="id" name="accessibility_button_chooser_grid" />
   <java-symbol type="id" name="accessibility_button_prompt" />
+  <java-symbol type="id" name="accessibility_button_prompt_prologue" />
   <java-symbol type="id" name="accessibility_button_target_icon" />
   <java-symbol type="id" name="accessibility_button_target_label" />
   <java-symbol type="string" name="accessibility_magnification_chooser_text" />
+
+  <java-symbol type="string" name="accessibility_gesture_prompt_text" />
+  <java-symbol type="string" name="accessibility_gesture_3finger_prompt_text" />
+  <java-symbol type="string" name="accessibility_gesture_instructional_text" />
+  <java-symbol type="string" name="accessibility_gesture_3finger_instructional_text" />
+
   <java-symbol type="drawable" name="ic_accessibility_magnification" />
 
   <!-- com.android.internal.widget.RecyclerView -->
@@ -3419,6 +3439,7 @@
   <java-symbol type="string" name="notification_channel_car_mode" />
   <java-symbol type="string" name="notification_channel_account" />
   <java-symbol type="string" name="notification_channel_developer" />
+  <java-symbol type="string" name="notification_channel_developer_important" />
   <java-symbol type="string" name="notification_channel_updates" />
   <java-symbol type="string" name="notification_channel_network_status" />
   <java-symbol type="string" name="notification_channel_network_alerts" />
@@ -3538,7 +3559,7 @@
 
   <java-symbol type="integer" name="config_stableDeviceDisplayWidth" />
   <java-symbol type="integer" name="config_stableDeviceDisplayHeight" />
-  <java-symbol type="bool" name="config_display_no_service_when_sim_unready" />
+  <java-symbol type="array" name="config_display_no_service_when_sim_unready" />
 
   <java-symbol type="layout" name="slice_grid" />
   <java-symbol type="layout" name="slice_message_local" />
@@ -3689,12 +3710,16 @@
   <java-symbol type="dimen" name="rounded_corner_radius" />
   <java-symbol type="dimen" name="rounded_corner_radius_top" />
   <java-symbol type="dimen" name="rounded_corner_radius_bottom" />
+  <java-symbol type="dimen" name="rounded_corner_radius_adjustment" />
+  <java-symbol type="dimen" name="rounded_corner_radius_top_adjustment" />
+  <java-symbol type="dimen" name="rounded_corner_radius_bottom_adjustment" />
   <java-symbol type="bool" name="config_supportsRoundedCornersOnWindows" />
 
   <java-symbol type="string" name="config_defaultModuleMetadataProvider" />
 
   <!-- For Secondary Launcher -->
   <java-symbol type="string" name="config_secondaryHomeComponent" />
+  <java-symbol type="bool" name="config_useSystemProvidedLauncherForSecondary" />
 
   <java-symbol type="string" name="battery_saver_notification_channel_name" />
   <java-symbol type="string" name="battery_saver_sticky_disabled_notification_title" />
@@ -3737,8 +3762,12 @@
   <java-symbol type="array" name="config_displayWhiteBalanceBaseThresholds" />
   <java-symbol type="array" name="config_displayWhiteBalanceIncreaseThresholds" />
   <java-symbol type="array" name="config_displayWhiteBalanceDecreaseThresholds" />
-  <java-symbol type="dimen" name="config_displayWhiteBalanceLowLightAmbientBrightnessThreshold" />
+  <java-symbol type="array" name="config_displayWhiteBalanceLowLightAmbientBrightnesses" />
+  <java-symbol type="array" name="config_displayWhiteBalanceLowLightAmbientBiases" />
   <java-symbol type="dimen" name="config_displayWhiteBalanceLowLightAmbientColorTemperature" />
+  <java-symbol type="array" name="config_displayWhiteBalanceHighLightAmbientBrightnesses" />
+  <java-symbol type="array" name="config_displayWhiteBalanceHighLightAmbientBiases" />
+  <java-symbol type="dimen" name="config_displayWhiteBalanceHighLightAmbientColorTemperature" />
   <java-symbol type="array" name="config_displayWhiteBalanceAmbientColorTemperatures" />
   <java-symbol type="array" name="config_displayWhiteBalanceDisplayColorTemperatures" />
   <java-symbol type="drawable" name="ic_action_open" />
@@ -3766,11 +3795,14 @@
 
   <!-- For high refresh rate displays -->
   <java-symbol type="integer" name="config_defaultPeakRefreshRate" />
+  <java-symbol type="array" name="config_brightnessThresholdsOfPeakRefreshRate" />
+  <java-symbol type="array" name="config_ambientThresholdsOfPeakRefreshRate" />
 
   <!-- For Auto-Brightness -->
   <java-symbol type="string" name="config_displayLightSensorType" />
 
   <java-symbol type="drawable" name="iconfactory_adaptive_icon_drawable_wrapper"/>
+  <java-symbol type="dimen" name="notification_min_height" />
   <java-symbol type="dimen" name="resolver_icon_size"/>
   <java-symbol type="dimen" name="resolver_badge_size"/>
   <java-symbol type="dimen" name="resolver_button_bar_spacing"/>
@@ -3793,7 +3825,19 @@
   <java-symbol type="string" name="chooser_all_apps_button_label" />
   <java-symbol type="anim" name="resolver_launch_anim" />
   <java-symbol type="style" name="Animation.DeviceDefault.Activity.Resolver" />
-  
+
+  <java-symbol type="color" name="decor_view_status_guard_light" />
+
   <java-symbol type="string" name="config_defaultSupervisionProfileOwnerComponent" />
   <java-symbol type="bool" name="config_inflateSignalStrength" />
+
+  <java-symbol type="drawable" name="android_logotype" />
+  <java-symbol type="layout" name="platlogo_layout" />
+
+  <java-symbol type="integer" name="config_notificationWarnRemoteViewSizeBytes" />
+  <java-symbol type="integer" name="config_notificationStripRemoteViewSizeBytes" />
+
+  <java-symbol type="string" name="config_factoryResetPackage" />
+  <java-symbol type="array" name="config_highRefreshRateBlacklist" />
+
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 6289262..0c52029 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1704,6 +1704,8 @@
 
     <!-- DeviceDefault theme for the default system theme.  -->
     <style name="Theme.DeviceDefault.System" parent="Theme.DeviceDefault.Light.DarkActionBar" />
+    <style name="Theme.DeviceDefault.System.Dialog" parent="Theme.DeviceDefault.Light.Dialog" />
+    <style name="Theme.DeviceDefault.System.Dialog.Alert" parent="Theme.DeviceDefault.Light.Dialog.Alert" />
 
     <style name="ThemeOverlay.DeviceDefault" />
 
diff --git a/core/tests/benchmarks/src/android/text/format/AndroidTimeVsOthersBenchmark.java b/core/tests/benchmarks/src/android/text/format/AndroidTimeVsOthersBenchmark.java
new file mode 100644
index 0000000..ea24400
--- /dev/null
+++ b/core/tests/benchmarks/src/android/text/format/AndroidTimeVsOthersBenchmark.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.format;
+
+import com.google.caliper.Benchmark;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+
+public class AndroidTimeVsOthersBenchmark {
+
+    private static final String[] TIMEZONE_IDS = {
+            "Europe/London",
+            "America/Los_Angeles",
+            "Asia/Shanghai",
+    };
+
+    @Benchmark
+    public void toMillis_androidTime(int reps) {
+        long answer = 0;
+        for (int i = 0; i < reps; i++) {
+            String timezoneId = TIMEZONE_IDS[i % TIMEZONE_IDS.length];
+            Time time = new Time(timezoneId);
+            time.set(1, 2, 3, 4, 5, 2010);
+            answer = time.toMillis(false);
+        }
+        // System.out.println(answer);
+    }
+
+    @Benchmark
+    public void toMillis_javaTime(int reps) {
+        long answer = 0;
+        for (int i = 0; i < reps; i++) {
+            String timezoneId = TIMEZONE_IDS[i % TIMEZONE_IDS.length];
+            LocalDateTime time = LocalDateTime.of(2010, 5 + 1, 4, 3, 2, 1);
+            ZoneOffset offset = ZoneId.of(timezoneId).getRules().getOffset(time);
+            answer = time.toInstant(offset).toEpochMilli();
+        }
+        // System.out.println(answer);
+    }
+
+    @Benchmark
+    public void toMillis_javaUtil(int reps) {
+        long answer = 0;
+        for (int i = 0; i < reps; i++) {
+            String timezoneId = TIMEZONE_IDS[i % TIMEZONE_IDS.length];
+            java.util.TimeZone timeZone = java.util.TimeZone.getTimeZone(timezoneId);
+            java.util.Calendar calendar = new java.util.GregorianCalendar(timeZone);
+            calendar.set(2010, 5, 4, 3, 2, 1);
+            calendar.set(java.util.Calendar.MILLISECOND, 0);
+            answer = calendar.getTimeInMillis();
+        }
+        // System.out.println(answer);
+    }
+
+    @Benchmark
+    public void toMillis_androidIucUtil(int reps) {
+        long answer = 0;
+        for (int i = 0; i < reps; i++) {
+            String timezoneId = TIMEZONE_IDS[i % TIMEZONE_IDS.length];
+            android.icu.util.TimeZone timeZone =
+                    android.icu.util.TimeZone.getTimeZone(timezoneId);
+            android.icu.util.Calendar calendar = new android.icu.util.GregorianCalendar(timeZone);
+            calendar.set(2010, 5, 4, 3, 2, 1);
+            calendar.set(android.icu.util.Calendar.MILLISECOND, 0);
+            answer = calendar.getTimeInMillis();
+        }
+        // System.out.println(answer);
+    }
+}
diff --git a/core/tests/coretests/res/values/overlayable_icons_test.xml b/core/tests/coretests/res/values/overlayable_icons_test.xml
deleted file mode 100644
index 285db50..0000000
--- a/core/tests/coretests/res/values/overlayable_icons_test.xml
+++ /dev/null
@@ -1,84 +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.
--->
-<resources>
-  <!-- overlayable_icons references all of the drawables in this package
-       that are being overlayed by resource overlays. If you remove/rename
-       any of these resources, you must also change the resource overlay icons.-->
-  <array name="overlayable_icons">
-    <item>@*android:drawable/ic_audio_alarm</item>
-    <item>@*android:drawable/ic_audio_alarm_mute</item>
-    <item>@*android:drawable/ic_battery_80_24dp</item>
-    <item>@*android:drawable/ic_bluetooth_share_icon</item>
-    <item>@*android:drawable/ic_bt_headphones_a2dp</item>
-    <item>@*android:drawable/ic_bt_headset_hfp</item>
-    <item>@*android:drawable/ic_bt_hearing_aid</item>
-    <item>@*android:drawable/ic_bt_laptop</item>
-    <item>@*android:drawable/ic_bt_misc_hid</item>
-    <item>@*android:drawable/ic_bt_network_pan</item>
-    <item>@*android:drawable/ic_bt_pointing_hid</item>
-    <item>@*android:drawable/ic_corp_badge</item>
-    <item>@*android:drawable/ic_expand_more</item>
-    <item>@*android:drawable/ic_faster_emergency</item>
-    <item>@*android:drawable/ic_file_copy</item>
-    <item>@*android:drawable/ic_lock</item>
-    <item>@*android:drawable/ic_lock_bugreport</item>
-    <item>@*android:drawable/ic_lock_open</item>
-    <item>@*android:drawable/ic_lock_power_off</item>
-    <item>@*android:drawable/ic_lockscreen_ime</item>
-    <item>@*android:drawable/ic_mode_edit</item>
-    <item>@*android:drawable/ic_notifications_alerted</item>
-    <item>@*android:drawable/ic_phone</item>
-    <item>@*android:drawable/ic_qs_airplane</item>
-    <item>@*android:drawable/ic_qs_auto_rotate</item>
-    <item>@*android:drawable/ic_qs_battery_saver</item>
-    <item>@*android:drawable/ic_qs_bluetooth</item>
-    <item>@*android:drawable/ic_qs_dnd</item>
-    <item>@*android:drawable/ic_qs_flashlight</item>
-    <item>@*android:drawable/ic_qs_night_display_on</item>
-    <item>@*android:drawable/ic_restart</item>
-    <item>@*android:drawable/ic_screenshot</item>
-    <item>@*android:drawable/ic_settings_bluetooth</item>
-    <item>@*android:drawable/ic_signal_cellular_0_4_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_0_5_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_1_4_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_1_5_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_2_4_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_2_5_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_3_4_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_3_5_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_4_4_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_4_5_bar</item>
-    <item>@*android:drawable/ic_signal_cellular_5_5_bar</item>
-    <item>@*android:drawable/ic_signal_location</item>
-    <item>@*android:drawable/ic_wifi_signal_0</item>
-    <item>@*android:drawable/ic_wifi_signal_1</item>
-    <item>@*android:drawable/ic_wifi_signal_2</item>
-    <item>@*android:drawable/ic_wifi_signal_3</item>
-    <item>@*android:drawable/ic_wifi_signal_4</item>
-    <item>@*android:drawable/perm_group_activity_recognition</item>
-    <item>@*android:drawable/perm_group_calendar</item>
-    <item>@*android:drawable/perm_group_call_log</item>
-    <item>@*android:drawable/perm_group_camera</item>
-    <item>@*android:drawable/perm_group_contacts</item>
-    <item>@*android:drawable/perm_group_location</item>
-    <item>@*android:drawable/perm_group_microphone</item>
-    <item>@*android:drawable/perm_group_phone_calls</item>
-    <item>@*android:drawable/perm_group_sensors</item>
-    <item>@*android:drawable/perm_group_sms</item>
-    <item>@*android:drawable/perm_group_storage</item>
-    <item>@*android:drawable/perm_group_visual</item>
-  </array>
-</resources>
diff --git a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
index 4b0ed65..95da532 100644
--- a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
+++ b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
@@ -90,7 +90,7 @@
         private boolean mAllow3rdPartyOnInternal = true;
 
         public MockedApplicationPackageManager() {
-            super(null, null);
+            super(null, null, null);
         }
 
         public void setForceAllowOnExternal(boolean forceAllowOnExternal) {
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 711eaa7..c50cbe3 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -19,6 +19,8 @@
 import static android.content.Intent.ACTION_EDIT;
 import static android.content.Intent.ACTION_VIEW;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
@@ -31,6 +33,7 @@
 import android.app.servertransaction.ActivityRelaunchItem;
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.ClientTransactionItem;
+import android.app.servertransaction.NewIntentItem;
 import android.app.servertransaction.ResumeActivityItem;
 import android.app.servertransaction.StopActivityItem;
 import android.content.Intent;
@@ -45,9 +48,13 @@
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.content.ReferrerIntent;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
 /**
@@ -307,6 +314,24 @@
         assertEquals(400, activity.mConfig.smallestScreenWidthDp);
     }
 
+    @Test
+    public void testResumeAfterNewIntent() {
+        final Activity activity = mActivityTestRule.launchActivity(new Intent());
+        final ActivityThread activityThread = activity.getActivityThread();
+        final ArrayList<ReferrerIntent> rIntents = new ArrayList<>();
+        rIntents.add(new ReferrerIntent(new Intent(), "android.app.activity"));
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            activityThread.executeTransaction(newNewIntentTransaction(activity, rIntents, false));
+        });
+        assertThat(activity.isResumed()).isFalse();
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            activityThread.executeTransaction(newNewIntentTransaction(activity, rIntents, true));
+        });
+        assertThat(activity.isResumed()).isTrue();
+    }
+
     /**
      * Calls {@link ActivityThread#handleActivityConfigurationChanged(IBinder, Configuration, int)}
      * to try to push activity configuration to the activity for the given sequence number.
@@ -386,6 +411,16 @@
         return transaction;
     }
 
+    private static ClientTransaction newNewIntentTransaction(Activity activity,
+            List<ReferrerIntent> intents, boolean resume) {
+        final NewIntentItem item = NewIntentItem.obtain(intents, resume);
+
+        final ClientTransaction transaction = newTransaction(activity);
+        transaction.addCallback(item);
+
+        return transaction;
+    }
+
     private static ClientTransaction newTransaction(Activity activity) {
         final IApplicationThread appThread = activity.getActivityThread().getApplicationThread();
         return ClientTransaction.obtain(appThread, activity.getActivityToken());
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index 1e49c0a..37d21f0 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -214,15 +214,15 @@
 
     @Test
     public void testRecycleNewIntentItem() {
-        NewIntentItem emptyItem = NewIntentItem.obtain(null);
-        NewIntentItem item = NewIntentItem.obtain(referrerIntentList());
+        NewIntentItem emptyItem = NewIntentItem.obtain(null, false);
+        NewIntentItem item = NewIntentItem.obtain(referrerIntentList(), false);
         assertNotSame(item, emptyItem);
         assertFalse(item.equals(emptyItem));
 
         item.recycle();
         assertEquals(item, emptyItem);
 
-        NewIntentItem item2 = NewIntentItem.obtain(referrerIntentList());
+        NewIntentItem item2 = NewIntentItem.obtain(referrerIntentList(), false);
         assertSame(item, item2);
         assertFalse(item2.equals(emptyItem));
     }
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index 36ed88f..51da0c8 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -128,7 +128,7 @@
     @Test
     public void testNewIntent() {
         // Write to parcel
-        NewIntentItem item = NewIntentItem.obtain(referrerIntentList());
+        NewIntentItem item = NewIntentItem.obtain(referrerIntentList(), false);
         writeAndPrepareForReading(item);
 
         // Read from parcel and assert
@@ -416,7 +416,8 @@
                 IUiAutomationConnection iUiAutomationConnection, int i, boolean b, boolean b1,
                 boolean b2, boolean b3, Configuration configuration,
                 CompatibilityInfo compatibilityInfo, Map map, Bundle bundle1, String s1,
-                AutofillOptions ao, ContentCaptureOptions co) throws RemoteException {
+                AutofillOptions ao, ContentCaptureOptions co, long[] disableCompatChanges)
+                throws RemoteException {
         }
 
         @Override
diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java
index 2f442c3..b1a54dc 100644
--- a/core/tests/coretests/src/android/content/ContextTest.java
+++ b/core/tests/coretests/src/android/content/ContextTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 
 import android.app.ActivityThread;
+import android.os.UserHandle;
 import android.view.WindowManager;
 
 import androidx.test.InstrumentationRegistry;
@@ -58,4 +59,32 @@
         assertEquals(defaultDisplayContext.getDisplay().getDisplayId(),
                 defaultDisplayContext.getDisplayId());
     }
+
+    @Test(expected = NullPointerException.class)
+    public void testStartActivityAsUserNullIntentNullUser() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        testContext.startActivityAsUser(null, null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testStartActivityAsUserNullIntentNonNullUser() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        testContext.startActivityAsUser(null, new UserHandle(UserHandle.USER_ALL));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testStartActivityAsUserNonNullIntentNullUser() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        testContext.startActivityAsUser(new Intent(), null);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testStartActivityAsUserNonNullIntentNonNullUser() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        testContext.startActivityAsUser(new Intent(), new UserHandle(UserHandle.USER_ALL));
+    }
 }
diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
index 71d9a46..58c43ac2 100644
--- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java
+++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
@@ -498,14 +498,14 @@
 
     @Test
     public void testApexPackageInfoGeneration() throws Exception {
-        String apexPackageName = "com.android.tzdata.apex";
-        File apexFile = copyRawResourceToFile(apexPackageName,
+        String apexModuleName = "com.android.tzdata.apex";
+        File apexFile = copyRawResourceToFile(apexModuleName,
                 R.raw.com_android_tzdata);
         ApexInfo apexInfo = new ApexInfo();
         apexInfo.isActive = true;
         apexInfo.isFactory = false;
-        apexInfo.packageName = apexPackageName;
-        apexInfo.packagePath = apexFile.getPath();
+        apexInfo.moduleName = apexModuleName;
+        apexInfo.modulePath = apexFile.getPath();
         apexInfo.versionCode = 191000070;
         int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;
         PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexInfo, flags);
diff --git a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
index c8150b1..365e97d 100644
--- a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
@@ -16,7 +16,6 @@
 
 package android.content.pm;
 
-import android.content.Intent;
 import android.content.res.Resources;
 import android.os.FileUtils;
 import android.os.Parcel;
@@ -190,36 +189,6 @@
         assertEquals(0, cache.getPersistentServicesSize(u1));
     }
 
-    /**
-     * Check that an optimization to skip a call to PackageManager handles an invalidated cache.
-     *
-     * We added an optimization in generateServicesMap to only query PackageManager for packages
-     * that have been changed, because if a package is unchanged, we have already cached the
-     * services info for it, so we can save a query to PackageManager (and save some memory).
-     * However, if invalidateCache was called, we cannot optimize, and must do a full query.
-     * The initial optimization was buggy because it failed to check for an invalidated cache, and
-     * only scanned the changed packages, given in the ACTION_PACKAGE_CHANGED intent (b/122912184).
-     */
-    public void testParseServiceInfoOptimizationHandlesInvalidatedCache() {
-        TestServicesCache cache = new TestServicesCache();
-        cache.addServiceForQuerying(U0, r1, newServiceInfo(t1, UID1));
-        cache.addServiceForQuerying(U0, r2, newServiceInfo(t2, UID2));
-        assertEquals(2, cache.getAllServicesSize(U0));
-
-        // simulate the client of the cache invalidating it
-        cache.invalidateCache(U0);
-
-        // there should be 0 services (userServices.services == null ) at this point, but we don't
-        // call getAllServicesSize since that would force a full scan of packages,
-        // instead we trigger a package change in a package that is in the list of services
-        Intent intent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
-        intent.putExtra(Intent.EXTRA_UID, UID1);
-        cache.handlePackageEvent(intent, U0);
-
-        // check that the optimization does a full query and caches both services
-        assertEquals(2, cache.getAllServicesSize(U0));
-    }
-
     private static RegisteredServicesCache.ServiceInfo<TestServiceType> newServiceInfo(
             TestServiceType type, int uid) {
         final ComponentInfo info = new ComponentInfo();
@@ -297,11 +266,6 @@
                 map = new HashMap<>();
                 mServices.put(userId, map);
             }
-            // in actual cases, resolveInfo should always have a serviceInfo, since we specifically
-            // query for intent services
-            resolveInfo.serviceInfo = new android.content.pm.ServiceInfo();
-            resolveInfo.serviceInfo.applicationInfo =
-                new ApplicationInfo(serviceInfo.componentInfo.applicationInfo);
             map.put(resolveInfo, serviceInfo);
         }
 
@@ -340,11 +304,6 @@
         public void onUserRemoved(int userId) {
             super.onUserRemoved(userId);
         }
-
-        @Override
-        public void handlePackageEvent(Intent intent, int userId) {
-            super.handlePackageEvent(intent, userId);
-        }
     }
 
     static class TestSerializer implements XmlSerializerAndParser<TestServiceType> {
diff --git a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
index 1ca879c..49849ee 100644
--- a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
+++ b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
@@ -36,12 +36,12 @@
 
 import com.android.frameworks.coretests.R;
 
-import libcore.testing.io.TestIoUtils;
-
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 
 import java.io.File;
@@ -60,21 +60,14 @@
     private static final String APK_FILE_EXTENSION = ".apk";
     private static final String DEX_METADATA_FILE_EXTENSION = ".dm";
 
+    @Rule
+    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+
     private File mTmpDir = null;
 
     @Before
-    public void setUp() {
-        mTmpDir = TestIoUtils.createTemporaryDirectory("DexMetadataHelperTest");
-    }
-
-    @After
-    public void tearDown() {
-        if (mTmpDir != null) {
-            File[] files = mTmpDir.listFiles();
-            for (File f : files) {
-                f.delete();
-            }
-        }
+    public void setUp() throws IOException {
+        mTmpDir = mTemporaryFolder.newFolder("DexMetadataHelperTest");
     }
 
     private File createDexMetadataFile(String apkFileName) throws IOException {
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteTokenizerTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteTokenizerTest.java
new file mode 100644
index 0000000..a9d1482
--- /dev/null
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteTokenizerTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.sqlite;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class SQLiteTokenizerTest {
+    private List<String> getTokens(String sql) {
+        return SQLiteTokenizer.tokenize(sql, SQLiteTokenizer.OPTION_NONE);
+    }
+
+    private void checkTokens(String sql, String spaceSeparatedExpectedTokens) {
+        final List<String> expected = spaceSeparatedExpectedTokens == null
+                ? new ArrayList<>()
+                : Arrays.asList(spaceSeparatedExpectedTokens.split(" +"));
+
+        assertEquals(expected, getTokens(sql));
+    }
+
+    private void assertInvalidSql(String sql, String message) {
+        try {
+            getTokens(sql);
+            fail("Didn't throw InvalidSqlException");
+        } catch (IllegalArgumentException e) {
+            assertTrue("Expected " + e.getMessage() + " to contain " + message,
+                    e.getMessage().contains(message));
+        }
+    }
+
+    @Test
+    public void testWhitespaces() {
+        checkTokens("  select  \t\r\n a\n\n  ", "select a");
+        checkTokens("a b", "a b");
+    }
+
+    @Test
+    public void testComment() {
+        checkTokens("--\n", null);
+        checkTokens("a--\n", "a");
+        checkTokens("a--abcdef\n", "a");
+        checkTokens("a--abcdef\nx", "a x");
+        checkTokens("a--\nx", "a x");
+        assertInvalidSql("a--abcdef", "Unterminated comment");
+        assertInvalidSql("a--abcdef\ndef--", "Unterminated comment");
+
+        checkTokens("/**/", null);
+        assertInvalidSql("/*", "Unterminated comment");
+        assertInvalidSql("/*/", "Unterminated comment");
+        assertInvalidSql("/*\n* /*a", "Unterminated comment");
+        checkTokens("a/**/", "a");
+        checkTokens("/**/b", "b");
+        checkTokens("a/**/b", "a b");
+        checkTokens("a/* -- \n* /* **/b", "a b");
+    }
+
+    @Test
+    public void testStrings() {
+        assertInvalidSql("'", "Unterminated quote");
+        assertInvalidSql("a'", "Unterminated quote");
+        assertInvalidSql("a'''", "Unterminated quote");
+        assertInvalidSql("a''' ", "Unterminated quote");
+        checkTokens("''", null);
+        checkTokens("''''", null);
+        checkTokens("a''''b", "a b");
+        checkTokens("a' '' 'b", "a b");
+        checkTokens("'abc'", null);
+        checkTokens("'abc\ndef'", null);
+        checkTokens("a'abc\ndef'", "a");
+        checkTokens("'abc\ndef'b", "b");
+        checkTokens("a'abc\ndef'b", "a b");
+        checkTokens("a'''abc\nd''ef'''b", "a b");
+    }
+
+    @Test
+    public void testDoubleQuotes() {
+        assertInvalidSql("\"", "Unterminated quote");
+        assertInvalidSql("a\"", "Unterminated quote");
+        assertInvalidSql("a\"\"\"", "Unterminated quote");
+        assertInvalidSql("a\"\"\" ", "Unterminated quote");
+        checkTokens("\"\"", "");
+        checkTokens("\"\"\"\"", "\"");
+        checkTokens("a\"\"\"\"b", "a \" b");
+        checkTokens("a\"\t\"\"\t\"b", "a  \t\"\t  b");
+        checkTokens("\"abc\"", "abc");
+        checkTokens("\"abc\ndef\"", "abc\ndef");
+        checkTokens("a\"abc\ndef\"", "a abc\ndef");
+        checkTokens("\"abc\ndef\"b", "abc\ndef b");
+        checkTokens("a\"abc\ndef\"b", "a abc\ndef b");
+        checkTokens("a\"\"\"abc\nd\"\"ef\"\"\"b", "a \"abc\nd\"ef\" b");
+    }
+
+    @Test
+    public void testBackQuotes() {
+        assertInvalidSql("`", "Unterminated quote");
+        assertInvalidSql("a`", "Unterminated quote");
+        assertInvalidSql("a```", "Unterminated quote");
+        assertInvalidSql("a``` ", "Unterminated quote");
+        checkTokens("``", "");
+        checkTokens("````", "`");
+        checkTokens("a````b", "a ` b");
+        checkTokens("a`\t``\t`b", "a  \t`\t  b");
+        checkTokens("`abc`", "abc");
+        checkTokens("`abc\ndef`", "abc\ndef");
+        checkTokens("a`abc\ndef`", "a abc\ndef");
+        checkTokens("`abc\ndef`b", "abc\ndef b");
+        checkTokens("a`abc\ndef`b", "a abc\ndef b");
+        checkTokens("a```abc\nd``ef```b", "a `abc\nd`ef` b");
+    }
+
+    @Test
+    public void testBrackets() {
+        assertInvalidSql("[", "Unterminated quote");
+        assertInvalidSql("a[", "Unterminated quote");
+        assertInvalidSql("a[ ", "Unterminated quote");
+        assertInvalidSql("a[[ ", "Unterminated quote");
+        checkTokens("[]", "");
+        checkTokens("[[]", "[");
+        checkTokens("a[[]b", "a [ b");
+        checkTokens("a[\t[\t]b", "a  \t[\t  b");
+        checkTokens("[abc]", "abc");
+        checkTokens("[abc\ndef]", "abc\ndef");
+        checkTokens("a[abc\ndef]", "a abc\ndef");
+        checkTokens("[abc\ndef]b", "abc\ndef b");
+        checkTokens("a[abc\ndef]b", "a abc\ndef b");
+        checkTokens("a[[abc\nd[ef[]b", "a [abc\nd[ef[ b");
+    }
+
+    @Test
+    public void testSemicolons() {
+        assertInvalidSql(";", "Semicolon is not allowed");
+        assertInvalidSql("  ;", "Semicolon is not allowed");
+        assertInvalidSql(";  ", "Semicolon is not allowed");
+        assertInvalidSql("-;-", "Semicolon is not allowed");
+        checkTokens("--;\n", null);
+        checkTokens("/*;*/", null);
+        checkTokens("';'", null);
+        checkTokens("[;]", ";");
+        checkTokens("`;`", ";");
+    }
+
+    @Test
+    public void testTokens() {
+        checkTokens("a,abc,a00b,_1,_123,abcdef", "a abc a00b _1 _123 abcdef");
+        checkTokens("a--\nabc/**/a00b''_1'''ABC'''`_123`abc[d]\"e\"f",
+                "a abc a00b _1 _123 abc d e f");
+    }
+}
diff --git a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
index d5163e1..eff4826 100644
--- a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
+++ b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
@@ -64,7 +64,7 @@
     @Test
     public void testSingleByte() throws Exception {
         final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
-                new long[] { 10, 11 }).getFileDescriptor();
+                new long[] { 10, 11 }, new long[] {}).getFileDescriptor();
 
         final byte[] buf = new byte[1_000];
         assertEquals(buf.length, Os.read(fd, buf, 0, buf.length));
@@ -80,7 +80,7 @@
     @Test
     public void testRanges() throws Exception {
         final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
-                new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+                new long[] { 100, 200, 300, 400 }, new long[] {}).getFileDescriptor();
 
         final byte[] buf = new byte[10];
         assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 90));
@@ -102,7 +102,7 @@
     @Test
     public void testEntireFile() throws Exception {
         final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
-                new long[] { 0, 5_000_000 }).getFileDescriptor();
+                new long[] { 0, 5_000_000 }, new long[] {}).getFileDescriptor();
 
         try (FileInputStream in = new FileInputStream(fd)) {
             int val;
@@ -115,7 +115,7 @@
     @Test
     public void testReadWrite() throws Exception {
         final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
-                new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+                new long[] { 100, 200, 300, 400 }, new long[] {}).getFileDescriptor();
 
         // Redacted at first
         final byte[] buf = new byte[10];
@@ -168,4 +168,76 @@
         assertArrayEquals(new long[] { 100, 200 },
                 removeRange(new long[] { 100, 200 }, 150, 150));
     }
+
+    @Test
+    public void testFreeAtStart() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 10 }, new long[] {1}).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, (byte) 'f', (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0, 0, 0 },
+                buf);
+    }
+
+    @Test
+    public void testFreeAtOffset() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 10 }, new long[] {3}).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, 0, 0, (byte) 'f', (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0 },
+                buf);
+    }
+
+    @Test
+    public void testFreeAcrossRedactionStart() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 10 }, new long[] {0}).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0, 0, 0, 0 },
+                buf);
+    }
+
+    @Test
+    public void testFreeAcrossRedactionEnd() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 3 }, new long[] {2}).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, 0, (byte) 'f', 64, 64, 64, 64, 64, 64, 64 },
+                buf);
+    }
+
+    @Test
+    public void testFreeOutsideRedaction() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 8 }, new long[] { 8 }).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, 0, 0, 0, 0, 0, 0, 0, 64, 64 },
+                buf);
+    }
+
+    @Test
+    public void testFreeMultipleRedactions() throws Exception {
+        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+                new long[] { 1, 2, 3, 4 }, new long[] { 0 }).getFileDescriptor();
+
+        final byte[] buf = new byte[10];
+        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
+        assertArrayEquals(
+                new byte[] { 64, (byte) 'r', 64, (byte) 'e', 64, 64, 64, 64, 64, 64 },
+                buf);
+    }
 }
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index 7a4fa3a..23fabce 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -17,7 +17,6 @@
 package android.provider;
 
 import static android.provider.DeviceConfig.OnPropertiesChangedListener;
-import static android.provider.DeviceConfig.OnPropertyChangedListener;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -394,31 +393,6 @@
         }
     }
 
-    @Test
-    public void testOnPropertyChangedListener() throws InterruptedException {
-        CountDownLatch countDownLatch = new CountDownLatch(1);
-
-        OnPropertyChangedListener changeListener = (namespace, name, value) -> {
-            assertThat(namespace).isEqualTo(sNamespace);
-            assertThat(name).isEqualTo(sKey);
-            assertThat(value).isEqualTo(sValue);
-            countDownLatch.countDown();
-        };
-
-        try {
-            DeviceConfig.addOnPropertyChangedListener(sNamespace,
-                    ActivityThread.currentApplication().getMainExecutor(), changeListener);
-            DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
-            assertThat(countDownLatch.await(
-                    WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
-        } catch (InterruptedException e) {
-            Assert.fail(e.getMessage());
-        } finally {
-            DeviceConfig.removeOnPropertyChangedListener(changeListener);
-        }
-
-    }
-
     private static boolean deleteViaContentProvider(String namespace, String key) {
         ContentResolver resolver = InstrumentationRegistry.getContext().getContentResolver();
         String compositeName = namespace + "/" + key;
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index fda37c8..88bda9d 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.AVERAGE_TIME_TO_DISCHARGE,
-                    Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
                     Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
                     Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME,
                     Settings.Global.BROADCAST_BG_CONSTANTS,
@@ -265,6 +264,7 @@
                     Settings.Global.EUICC_PROVISIONED,
                     Settings.Global.EUICC_SUPPORTED_COUNTRIES,
                     Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
+                    Settings.Global.EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS,
                     Settings.Global.FANCY_IME_ANIMATIONS,
                     Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
                     Settings.Global.FORCED_APP_STANDBY_ENABLED,
@@ -398,9 +398,6 @@
                     Settings.Global.POWER_MANAGER_CONSTANTS,
                     Settings.Global.PREFERRED_NETWORK_MODE,
                     Settings.Global.PRIVATE_DNS_DEFAULT_MODE,
-                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_NON_PRIV_CHECK_RELAXED,
-                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_PRIV_CHECK_RELAXED,
-                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED,
                     Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
                     Settings.Global.RADIO_BLUETOOTH,
                     Settings.Global.RADIO_CELL,
@@ -496,6 +493,7 @@
                     Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST,
                     Settings.Global.GAME_DRIVER_ALL_APPS,
                     Settings.Global.GAME_DRIVER_OPT_IN_APPS,
+                    Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS,
                     Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
                     Settings.Global.GAME_DRIVER_BLACKLISTS,
                     Settings.Global.GAME_DRIVER_BLACKLIST,
diff --git a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
index 0f32a82..6161108 100644
--- a/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
+++ b/core/tests/coretests/src/android/service/notification/StatusBarNotificationTest.java
@@ -24,6 +24,7 @@
 
 import android.app.ActivityManager;
 import android.app.Notification;
+import android.app.Person;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
@@ -87,6 +88,9 @@
         assertEquals(0,
                 logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY));
         assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CATEGORY));
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_STYLE));
+        assertNull(logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_PEOPLE));
+
     }
 
     /** Verify that modifying the returned logMaker won't leave stale data behind for
@@ -159,6 +163,24 @@
                 sbn.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
     }
 
+    @Test
+    public void testLogMakerWithPerson() {
+        Notification.Builder builder = getNotificationBuilder(GROUP_ID_1, CHANNEL_ID)
+                .addPerson(new Person.Builder().build());
+        final LogMaker logMaker = getNotification(PKG, builder).getLogMaker();
+        assertEquals(1,
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_PEOPLE));
+    }
+
+    @Test
+    public void testLogMakerWithStyle() {
+        Notification.Builder builder = getNotificationBuilder(GROUP_ID_1, CHANNEL_ID)
+                .setStyle(new Notification.MessagingStyle(new Person.Builder().build()));
+        final LogMaker logMaker = getNotification(PKG, builder).getLogMaker();
+        assertEquals("android.app.Notification$MessagingStyle".hashCode(),
+                logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_STYLE));
+    }
+
     private StatusBarNotification getNotification(String pkg, String group, String channelId) {
         return getNotification(pkg, getNotificationBuilder(group, channelId));
     }
diff --git a/core/tests/coretests/src/android/text/LayoutTest.java b/core/tests/coretests/src/android/text/LayoutTest.java
index 990161a..93a6b15 100644
--- a/core/tests/coretests/src/android/text/LayoutTest.java
+++ b/core/tests/coretests/src/android/text/LayoutTest.java
@@ -743,6 +743,9 @@
         assertPrimaryIsTrailingPrevious(
                 RTL + LRI + RTL + LTR + PDI + RTL,
                 new boolean[]{false, false, true, false, false, false, false});
+        assertPrimaryIsTrailingPrevious(
+                "",
+                new boolean[]{false});
     }
 }
 
diff --git a/core/tests/coretests/src/android/util/TimingsTraceLogTest.java b/core/tests/coretests/src/android/util/TimingsTraceLogTest.java
deleted file mode 100644
index 77d0552..0000000
--- a/core/tests/coretests/src/android/util/TimingsTraceLogTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-import static org.junit.Assert.assertTrue;
-
-import android.os.Trace;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for {@link TimingsTraceLog}.
- * <p>Usage: bit FrameworksCoreTests:android.util.TimingsTraceLogTest
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TimingsTraceLogTest {
-
-    @Test
-    public void testDifferentThreads() throws Exception {
-        TimingsTraceLog log = new TimingsTraceLog("TEST", Trace.TRACE_TAG_APP);
-        // Should be able to log on the same thread
-        log.traceBegin("test");
-        log.traceEnd();
-        final List<String> errors = new ArrayList<>();
-        // Calling from a different thread should fail
-        Thread t = new Thread(() -> {
-            try {
-                log.traceBegin("test");
-                errors.add("traceBegin should fail on a different thread");
-            } catch (IllegalStateException expected) {
-            }
-            try {
-                log.traceEnd();
-                errors.add("traceEnd should fail on a different thread");
-            } catch (IllegalStateException expected) {
-            }
-            // Verify that creating a new log will work
-            TimingsTraceLog log2 = new TimingsTraceLog("TEST", Trace.TRACE_TAG_APP);
-            log2.traceBegin("test");
-            log2.traceEnd();
-
-        });
-        t.start();
-        t.join();
-        assertTrue(errors.toString(), errors.isEmpty());
-    }
-
-}
diff --git a/core/tests/coretests/src/android/view/CompositionSamplingListenerTest.java b/core/tests/coretests/src/android/view/CompositionSamplingListenerTest.java
index 75a2e8a..729a555 100644
--- a/core/tests/coretests/src/android/view/CompositionSamplingListenerTest.java
+++ b/core/tests/coretests/src/android/view/CompositionSamplingListenerTest.java
@@ -19,7 +19,6 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.graphics.Rect;
-import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -35,7 +34,7 @@
 
     @Test
     public void testRegisterUnregister() {
-        CompositionSamplingListener.register(mListener, DEFAULT_DISPLAY, new Binder(),
+        CompositionSamplingListener.register(mListener, DEFAULT_DISPLAY, new SurfaceControl(),
                 new Rect(1, 1, 10, 10));
         CompositionSamplingListener.unregister(mListener);
     }
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index 182fe78..d5a0dfa 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -104,8 +104,8 @@
 
     @Test
     public void testExtractBoundsFromList_top_and_bottom() {
-        Rect safeInsets = new Rect(0, 1, 0, 10);
-        Rect boundTop = new Rect(80, 0, 120, 10);
+        Rect safeInsets = new Rect(0, 10, 0, 10);
+        Rect boundTop = new Rect(0, 0, 120, 10);
         Rect boundBottom = new Rect(80, 190, 120, 200);
         assertThat(extractBoundsFromList(safeInsets,
                 Arrays.asList(new Rect[]{boundTop, boundBottom})),
diff --git a/core/tests/coretests/src/android/view/ViewRootSurfaceCallbackTest.java b/core/tests/coretests/src/android/view/ViewRootSurfaceCallbackTest.java
new file mode 100644
index 0000000..94917cf
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewRootSurfaceCallbackTest.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 android.view;
+
+import static android.os.Process.myTid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.os.HandlerThread;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+public class ViewRootSurfaceCallbackTest implements SurfaceHolder.Callback2 {
+    private static final String TAG = ViewRootSurfaceCallbackTest.class.getSimpleName();
+    private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(3);
+
+    @Rule
+    public ActivityTestRule<Activity> mActivityRule = new ActivityTestRule<>(Activity.class);
+
+    private final CompletableFuture<Integer> mTidOfSurfaceCreated = new CompletableFuture<>();
+    private final CompletableFuture<Integer> mTidOfSurfaceDestroyed = new CompletableFuture<>();
+
+    private boolean mDuplicatedSurfaceDestroyed;
+
+    /**
+     * Verifies that the calling thread of {@link SurfaceHolder.Callback2} should be the same as the
+     * thread that created the view root.
+     */
+    @Test
+    public void testCallingTidOfSurfaceCallback() throws Exception {
+        final Activity activity = mActivityRule.getActivity();
+        activity.setTurnScreenOn(true);
+        activity.setShowWhenLocked(true);
+
+        // Create a dialog that runs on another thread and let it handle surface by itself.
+        final HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        thread.getThreadHandler().runWithScissors(() -> {
+            final AlertDialog dialog = new AlertDialog.Builder(activity)
+                    .setTitle(TAG).setMessage(TAG).create();
+            dialog.getWindow().takeSurface(this);
+            dialog.show();
+        }, TIMEOUT_MS);
+        final int attachedTid = thread.getThreadId();
+
+        assertEquals(attachedTid,
+                mTidOfSurfaceCreated.get(TIMEOUT_MS, TimeUnit.MILLISECONDS).intValue());
+
+        // Make the activity invisible.
+        activity.moveTaskToBack(true /* nonRoot */);
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+
+        assertEquals(attachedTid,
+                mTidOfSurfaceDestroyed.get(TIMEOUT_MS, TimeUnit.MILLISECONDS).intValue());
+        assertFalse("surfaceDestroyed should not be called twice", mDuplicatedSurfaceDestroyed);
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+        mTidOfSurfaceCreated.complete(myTid());
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        if  (!mTidOfSurfaceDestroyed.isDone()) {
+            mTidOfSurfaceDestroyed.complete(myTid());
+        } else {
+            mDuplicatedSurfaceDestroyed = true;
+        }
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+    }
+
+    @Override
+    public void surfaceRedrawNeeded(SurfaceHolder holder) {
+    }
+}
diff --git a/core/tests/coretests/src/android/view/WindowInfoTest.java b/core/tests/coretests/src/android/view/WindowInfoTest.java
new file mode 100644
index 0000000..05e8bd8
--- /dev/null
+++ b/core/tests/coretests/src/android/view/WindowInfoTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+
+import android.os.IBinder;
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+/**
+ * Class for testing {@link WindowInfo}.
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowInfoTest {
+
+    @SmallTest
+    @Test
+    public void testObtain() {
+        WindowInfo w1 = WindowInfo.obtain();
+        assertNotNull(w1);
+        initTestWindowInfo(w1);
+
+        WindowInfo w2 = WindowInfo.obtain(w1);
+
+        assertNotSame(w1, w2);
+        areWindowsEqual(w1, w2);
+    }
+
+    @SmallTest
+    @Test
+    public void testParceling() {
+        Parcel parcel = Parcel.obtain();
+        WindowInfo w1 = WindowInfo.obtain();
+        initTestWindowInfo(w1);
+        w1.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        WindowInfo w2 = WindowInfo.CREATOR.createFromParcel(parcel);
+
+        assertNotSame(w1, w2);
+        areWindowsEqual(w1, w2);
+        parcel.recycle();
+    }
+
+    @SmallTest
+    @Test
+    public void testDefaultValues() {
+        WindowInfo w = WindowInfo.obtain();
+
+        assertEquals(0, w.type);
+        assertEquals(0, w.layer);
+        assertEquals(AccessibilityNodeInfo.UNDEFINED_NODE_ID, w.accessibilityIdOfAnchor);
+        assertEquals(Display.INVALID_DISPLAY, w.displayId);
+        assertNull(w.title);
+        assertNull(w.token);
+        assertNull(w.childTokens);
+        assertNull(w.parentToken);
+        assertNull(w.activityToken);
+        assertFalse(w.focused);
+        assertFalse(w.inPictureInPicture);
+        assertFalse(w.hasFlagWatchOutsideTouch);
+        assertTrue(w.regionInScreen.isEmpty());
+    }
+
+    @SmallTest
+    @Test
+    public void testRecycle() {
+        WindowInfo w = WindowInfo.obtain();
+        w.recycle();
+
+        try {
+            w.recycle();
+            fail("Expected IllegalStateException");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+    }
+
+    private boolean areWindowsEqual(WindowInfo w1, WindowInfo w2) {
+        boolean equality = w1.toString().contentEquals(w2.toString());
+        equality &= w1.token == w2.token;
+        equality &= w1.childTokens.equals(w2.childTokens);
+        equality &= w1.parentToken == w2.parentToken;
+        equality &= w1.activityToken == w2.activityToken;
+        equality &= w1.regionInScreen.equals(w2.regionInScreen);
+        return equality;
+    }
+
+    private void initTestWindowInfo(WindowInfo windowInfo) {
+        windowInfo.type = 1;
+        windowInfo.displayId = 2;
+        windowInfo.layer = 3;
+        windowInfo.accessibilityIdOfAnchor = 4L;
+        windowInfo.title = "title";
+        windowInfo.token = mock(IBinder.class);
+        windowInfo.childTokens = new ArrayList<>();
+        windowInfo.childTokens.add(mock(IBinder.class));
+        windowInfo.parentToken = mock(IBinder.class);
+        windowInfo.activityToken = mock(IBinder.class);
+        windowInfo.focused = true;
+        windowInfo.inPictureInPicture = true;
+        windowInfo.hasFlagWatchOutsideTouch = true;
+        windowInfo.regionInScreen.set(0, 0, 1080, 1080);
+    }
+}
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index 683d16b..adaae5c 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -21,6 +21,7 @@
 import android.content.pm.ParceledListSlice;
 import android.graphics.Region;
 import android.os.Bundle;
+import android.os.IBinder;
 
 import java.util.List;
 
@@ -134,4 +135,8 @@
     public boolean isFingerprintGestureDetectionAvailable() {
         return false;
     }
+
+    public IBinder getOverlayWindowToken(int displayId) {
+        return null;
+    }
 }
diff --git a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
index db5f82a..80bce26 100644
--- a/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/ActionsSuggestionsHelperTest.java
@@ -208,6 +208,36 @@
         assertThat(conversationActions.get(2).getAction()).isNull();
     }
 
+    @Test
+    public void testDeduplicateActions_nullComponent() {
+        Bundle phoneExtras = new Bundle();
+        Intent phoneIntent = new Intent(Intent.ACTION_DIAL);
+        ExtrasUtils.putActionIntent(phoneExtras, phoneIntent);
+        PendingIntent pendingIntent = PendingIntent.getActivity(
+                InstrumentationRegistry.getTargetContext(),
+                0,
+                phoneIntent,
+                0);
+        Icon icon = Icon.createWithData(new byte[0], 0, 0);
+        ConversationAction action =
+                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+                        .setAction(new RemoteAction(icon, "label", "1", pendingIntent))
+                        .setExtras(phoneExtras)
+                        .build();
+        ConversationAction actionWithSameLabel =
+                new ConversationAction.Builder(ConversationAction.TYPE_CALL_PHONE)
+                        .setAction(new RemoteAction(
+                                icon, "label", "2", pendingIntent))
+                        .setExtras(phoneExtras)
+                        .build();
+
+        List<ConversationAction> conversationActions =
+                ActionsSuggestionsHelper.removeActionsWithDuplicates(
+                        Arrays.asList(action, actionWithSameLabel));
+
+        assertThat(conversationActions).isEmpty();
+    }
+
     public void createLabeledIntentResult_null() {
         ActionsSuggestionsModel.ActionSuggestion nativeSuggestion =
                 new ActionsSuggestionsModel.ActionSuggestion(
diff --git a/core/tests/coretests/src/android/view/textclassifier/logging/SmartSelectionEventTrackerTest.java b/core/tests/coretests/src/android/view/textclassifier/logging/SmartSelectionEventTrackerTest.java
new file mode 100644
index 0000000..321a7f2
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/logging/SmartSelectionEventTrackerTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.textclassifier.logging;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.truth.Truth;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SmartSelectionEventTrackerTest {
+
+    @Test
+    public void getVersionInfo_valid() {
+        String signature = "a|702|b";
+        String versionInfo = SmartSelectionEventTracker.SelectionEvent.getVersionInfo(signature);
+        Truth.assertThat(versionInfo).isEqualTo("702");
+    }
+
+    @Test
+    public void getVersionInfo_invalid() {
+        String signature = "|702";
+        String versionInfo = SmartSelectionEventTracker.SelectionEvent.getVersionInfo(signature);
+        Truth.assertThat(versionInfo).isEmpty();
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
index 267a9c8..c3ef1c8 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java
@@ -76,6 +76,7 @@
 import android.view.textclassifier.TextClassifier;
 import android.view.textclassifier.TextLinks;
 import android.view.textclassifier.TextLinksParams;
+import android.view.textclassifier.TextSelection;
 import android.widget.espresso.CustomViewActions.RelativeCoordinatesProvider;
 
 import androidx.test.InstrumentationRegistry;
@@ -1020,6 +1021,50 @@
     }
 
     @Test
+    public void testSelectionMetricsLogger_abandonEventIncludesEntityType() throws Throwable {
+        final List<SelectionEvent> selectionEvents = new ArrayList<>();
+        final TextClassifier classifier = new TextClassifier() {
+            @Override
+            public void onSelectionEvent(SelectionEvent event) {
+                selectionEvents.add(event);
+            }
+
+            @Override
+            public TextSelection suggestSelection(TextSelection.Request request) {
+                return new TextSelection.Builder(request.getStartIndex(), request.getEndIndex())
+                        .setEntityType(TextClassifier.TYPE_PHONE, 1)
+                        .build();
+            }
+        };
+        final TextView textView = mActivity.findViewById(R.id.textview);
+        mActivityRule.runOnUiThread(() -> textView.setTextClassifier(classifier));
+        mInstrumentation.waitForIdleSync();
+        final String text = "My number is 987654321";
+
+        onView(withId(R.id.textview)).perform(replaceText(text));
+        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('9')));
+        sleepForFloatingToolbarPopup();
+        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(0));
+        mInstrumentation.waitForIdleSync();
+
+        // Abandon event is logged 100ms later. See SelectionActionModeHelper.SelectionTracker
+        final long abandonDelay = 100;
+        final long pollInterval = 10;
+        long waitTime = 0;
+        SelectionEvent lastEvent;
+        do {
+            lastEvent = selectionEvents.get(selectionEvents.size() - 1);
+            if (lastEvent.getEventType() == SelectionEvent.ACTION_ABANDON) {
+                break;
+            }
+            Thread.sleep(pollInterval);
+            waitTime += pollInterval;
+        } while (waitTime < abandonDelay * 10);
+        assertEquals(SelectionEvent.ACTION_ABANDON, lastEvent.getEventType());
+        assertEquals(TextClassifier.TYPE_PHONE, lastEvent.getEntityType());
+    }
+
+    @Test
     public void testPastePlainText_menuAction() {
         initializeClipboardWithText(TextStyle.STYLED);
 
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index aadfcbc..abee1da2 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -71,7 +71,7 @@
 import com.android.internal.accessibility.AccessibilityShortcutController.FrameworkObjectProvider;
 import com.android.internal.util.test.FakeSettingsProvider;
 
-import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -136,6 +136,7 @@
 
         mContentResolver = new MockContentResolver(mContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        FakeSettingsProvider.clearSettingsProvider();
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
 
         when(mAccessibilityManagerService.getInstalledAccessibilityServiceList(anyInt()))
@@ -193,8 +194,9 @@
         when(mTextToSpeech.getVoice()).thenReturn(mVoice);
     }
 
-    @After
-    public void tearDown() {
+    @AfterClass
+    public static void cleanUpSettingsProvider() {
+        FakeSettingsProvider.clearSettingsProvider();
     }
 
     @Test
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryTest.java
index cc0ddb7..cd61011 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHistoryTest.java
@@ -22,25 +22,28 @@
 
 import android.content.Context;
 import android.os.Parcel;
+import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
 
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 /**
  * Test BatteryStatsHistory.
  */
 @RunWith(AndroidJUnit4.class)
 public class BatteryStatsHistoryTest {
+    private static final String TAG = "BatteryStatsHistoryTest";
     private static final int MAX_HISTORY_FILES = 32;
     private final BatteryStatsImpl mBatteryStatsImpl = new MockBatteryStatsImpl();
     private final Parcel mHistoryBuffer = Parcel.obtain();
@@ -53,6 +56,12 @@
         Context context = InstrumentationRegistry.getContext();
         mSystemDir = context.getDataDir();
         mHistoryDir = new File(mSystemDir, BatteryStatsHistory.HISTORY_DIR);
+        String[] files = mHistoryDir.list();
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                new File(mHistoryDir, files[i]).delete();
+            }
+        }
         mHistoryDir.delete();
     }
 
@@ -60,28 +69,32 @@
     public void testConstruct() {
         BatteryStatsHistory history =
                 new BatteryStatsHistory(mBatteryStatsImpl, mSystemDir, mHistoryBuffer);
+        createActiveFile(history);
         verifyFileNumbers(history, Arrays.asList(0));
         verifyActiveFile(history, "0.bin");
     }
 
     @Test
-    public void testCreateNextFile() {
+    public void testStartNextFile() {
         BatteryStatsHistory history =
                 new BatteryStatsHistory(mBatteryStatsImpl, mSystemDir, mHistoryBuffer);
 
         List<Integer> fileList = new ArrayList<>();
         fileList.add(0);
+        createActiveFile(history);
 
         // create file 1 to 31.
         for (int i = 1; i < MAX_HISTORY_FILES; i++) {
             fileList.add(i);
-            history.createNextFile();
+            history.startNextFile();
+            createActiveFile(history);
             verifyFileNumbers(history, fileList);
             verifyActiveFile(history, i + ".bin");
         }
 
         // create file 32
-        history.createNextFile();
+        history.startNextFile();
+        createActiveFile(history);
         fileList.add(32);
         fileList.remove(0);
         // verify file 0 is deleted.
@@ -90,7 +103,8 @@
         verifyActiveFile(history, "32.bin");
 
         // create file 33
-        history.createNextFile();
+        history.startNextFile();
+        createActiveFile(history);
         // verify file 1 is deleted
         fileList.add(33);
         fileList.remove(0);
@@ -108,6 +122,7 @@
         verifyActiveFile(history2, "33.bin");
 
         history2.resetAllFiles();
+        createActiveFile(history2);
         // verify all existing files are deleted.
         for (int i = 2; i < 33; ++i) {
             verifyFileDeleted(i + ".bin");
@@ -118,7 +133,8 @@
         verifyActiveFile(history2, "0.bin");
 
         // create file 1.
-        history2.createNextFile();
+        history2.startNextFile();
+        createActiveFile(history2);
         verifyFileNumbers(history2, Arrays.asList(0, 1));
         verifyActiveFile(history2, "1.bin");
     }
@@ -142,4 +158,13 @@
     private void verifyFileDeleted(String file) {
         assertFalse(new File(mHistoryDir, file).exists());
     }
+
+    private void createActiveFile(BatteryStatsHistory history) {
+        final File file = history.getActiveFile().getBaseFile();
+        try {
+            file.createNewFile();
+        } catch (IOException e) {
+            Log.e(TAG, "Error creating history file " + file.getPath(), e);
+        }
+    }
 }
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
new file mode 100644
index 0000000..5914887
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.DeadObjectException;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileDescriptor;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class BinderDeathDispatcherTest {
+    private static class MyTarget implements IInterface, IBinder {
+        public boolean isAlive = true;
+        public DeathRecipient mRecipient;
+
+        @Override
+        public String getInterfaceDescriptor() throws RemoteException {
+            return null;
+        }
+
+        @Override
+        public boolean pingBinder() {
+            return false;
+        }
+
+        @Override
+        public boolean isBinderAlive() {
+            return isAlive;
+        }
+
+        @Override
+        public IInterface queryLocalInterface(String descriptor) {
+            return null;
+        }
+
+        @Override
+        public void dump(FileDescriptor fd, String[] args) throws RemoteException {
+
+        }
+
+        @Override
+        public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
+
+        }
+
+        @Override
+        public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+                String[] args, ShellCallback shellCallback, ResultReceiver resultReceiver)
+                throws RemoteException {
+
+        }
+
+        @Override
+        public boolean transact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            return false;
+        }
+
+        @Override
+        public void linkToDeath(DeathRecipient recipient, int flags) throws RemoteException {
+            // In any situation, a single binder object should only have at most one death
+            // recipient.
+            assertThat(mRecipient).isNull();
+
+            if (!isAlive) {
+                throw new DeadObjectException();
+            }
+
+            mRecipient = recipient;
+        }
+
+        @Override
+        public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
+            if (!isAlive) {
+                return false;
+            }
+            assertThat(mRecipient).isSameAs(recipient);
+            mRecipient = null;
+            return true;
+        }
+
+        @Override
+        public IBinder asBinder() {
+            return this;
+        }
+
+        public void die() {
+            isAlive = false;
+            if (mRecipient != null) {
+                mRecipient.binderDied();
+            }
+            mRecipient = null;
+        }
+
+        public boolean hasDeathRecipient() {
+            return mRecipient != null;
+        }
+    }
+
+    @Test
+    public void testRegisterAndUnregister() {
+        BinderDeathDispatcher<MyTarget> d = new BinderDeathDispatcher<>();
+
+        MyTarget t1 = new MyTarget();
+        MyTarget t2 = new MyTarget();
+        MyTarget t3 = new MyTarget();
+
+        DeathRecipient r1 = mock(DeathRecipient.class);
+        DeathRecipient r2 = mock(DeathRecipient.class);
+        DeathRecipient r3 = mock(DeathRecipient.class);
+        DeathRecipient r4 = mock(DeathRecipient.class);
+        DeathRecipient r5 = mock(DeathRecipient.class);
+
+        // Start hooking up.
+
+        // Link 3 recipients to t1 -- only one real recipient will be set.
+        assertThat(d.linkToDeath(t1, r1)).isEqualTo(1);
+        assertThat(d.getTargetsForTest().size()).isEqualTo(1);
+
+        assertThat(d.linkToDeath(t1, r2)).isEqualTo(2);
+        assertThat(d.linkToDeath(t1, r3)).isEqualTo(3);
+        assertThat(d.getTargetsForTest().size()).isEqualTo(1);
+
+        // Unlink two -- the real recipient is still set.
+        d.unlinkToDeath(t1, r1);
+        d.unlinkToDeath(t1, r2);
+
+        assertThat(t1.hasDeathRecipient()).isTrue();
+        assertThat(d.getTargetsForTest().size()).isEqualTo(1);
+
+        // Unlink the last one. The real recipient is also unlinked.
+        d.unlinkToDeath(t1, r3);
+        assertThat(t1.hasDeathRecipient()).isFalse();
+        assertThat(d.getTargetsForTest().size()).isEqualTo(0);
+
+        // Set recipients to t1, t2 and t3. t3 has two.
+        assertThat(d.linkToDeath(t1, r1)).isEqualTo(1);
+        assertThat(d.linkToDeath(t2, r1)).isEqualTo(1);
+        assertThat(d.linkToDeath(t3, r1)).isEqualTo(1);
+        assertThat(d.linkToDeath(t3, r2)).isEqualTo(2);
+
+
+        // They should all have a real recipient.
+        assertThat(t1.hasDeathRecipient()).isTrue();
+        assertThat(t2.hasDeathRecipient()).isTrue();
+        assertThat(t3.hasDeathRecipient()).isTrue();
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(3);
+
+        // Unlink r1 from t3. t3 still has r2, so it should still have a real recipient.
+        d.unlinkToDeath(t3, r1);
+        assertThat(t1.hasDeathRecipient()).isTrue();
+        assertThat(t2.hasDeathRecipient()).isTrue();
+        assertThat(t3.hasDeathRecipient()).isTrue();
+        assertThat(d.getTargetsForTest().size()).isEqualTo(3);
+
+        // Unlink r2 from t3. Now t3 has no real recipient.
+        d.unlinkToDeath(t3, r2);
+        assertThat(t3.hasDeathRecipient()).isFalse();
+        assertThat(d.getTargetsForTest().size()).isEqualTo(2);
+    }
+
+    @Test
+    public void testRegisterAndKill() {
+        BinderDeathDispatcher<MyTarget> d = new BinderDeathDispatcher<>();
+
+        MyTarget t1 = new MyTarget();
+        MyTarget t2 = new MyTarget();
+        MyTarget t3 = new MyTarget();
+
+        DeathRecipient r1 = mock(DeathRecipient.class);
+        DeathRecipient r2 = mock(DeathRecipient.class);
+        DeathRecipient r3 = mock(DeathRecipient.class);
+        DeathRecipient r4 = mock(DeathRecipient.class);
+        DeathRecipient r5 = mock(DeathRecipient.class);
+
+        // Hook them up.
+
+        d.linkToDeath(t1, r1);
+        d.linkToDeath(t1, r2);
+        d.linkToDeath(t1, r3);
+
+        // r4 is linked then unlinked. It shouldn't be notified.
+        d.linkToDeath(t1, r4);
+        d.unlinkToDeath(t1, r4);
+
+        d.linkToDeath(t2, r1);
+
+        d.linkToDeath(t3, r3);
+        d.linkToDeath(t3, r5);
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(3);
+
+        // Kill the targets.
+
+        t1.die();
+        verify(r1, times(1)).binderDied();
+        verify(r2, times(1)).binderDied();
+        verify(r3, times(1)).binderDied();
+        verify(r4, times(0)).binderDied();
+        verify(r5, times(0)).binderDied();
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(2);
+
+        reset(r1, r2, r3, r4, r5);
+
+        t2.die();
+        verify(r1, times(1)).binderDied();
+        verify(r2, times(0)).binderDied();
+        verify(r3, times(0)).binderDied();
+        verify(r4, times(0)).binderDied();
+        verify(r5, times(0)).binderDied();
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(1);
+
+        reset(r1, r2, r3, r4, r5);
+
+        t3.die();
+        verify(r1, times(0)).binderDied();
+        verify(r2, times(0)).binderDied();
+        verify(r3, times(1)).binderDied();
+        verify(r4, times(0)).binderDied();
+        verify(r5, times(1)).binderDied();
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(0);
+
+        // Try to register to a dead object -> should return -1.
+        assertThat(d.linkToDeath(t1, r1)).isEqualTo(-1);
+
+        assertThat(d.getTargetsForTest().size()).isEqualTo(0);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
index 78b6843..008085e 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
@@ -22,6 +22,8 @@
 
 import java.nio.charset.Charset;
 
+import android.system.suspend.WakeLockInfo;
+
 public class KernelWakelockReaderTest extends TestCase {
     /**
      * Helper class that builds the mock Kernel module file /d/wakeup_sources.
@@ -58,6 +60,39 @@
         }
     }
 
+    /**
+     * Helper method to create WakeLockInfo object.
+     * @param totalTime is time in microseconds.
+     * @return the created WakeLockInfo object.
+     */
+    private WakeLockInfo createWakeLockInfo(String name, int activeCount, long totalTime) {
+        WakeLockInfo info = new WakeLockInfo();
+        info.name = name;
+        info.pid = 1;
+        info.activeCount = activeCount;
+        info.isActive = true;
+        info.activeSince = 0;
+        info.lastChange = 0;
+        info.maxTime = 0;
+        info.totalTime = totalTime;
+        return info;
+    }
+
+    /**
+     * Helper method for KernelWakeLockReader::readKernelWakelockStats(...)
+     * @param staleStats existing stats to update.
+     * @param buffer representation of mock kernel module file /d/wakeup_sources.
+     * @param wlStats mock WakeLockInfo list returned from ISuspendControlService.
+     * @return the updated stats.
+     */
+    private KernelWakelockStats readKernelWakelockStats(KernelWakelockStats staleStats,
+                                                        byte[] buffer, WakeLockInfo[] wlStats) {
+        mReader.updateVersion(staleStats);
+        mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats);
+        mReader.getNativeWakelockStats(wlStats, staleStats);
+        return mReader.removeOldStats(staleStats);
+    }
+
     private KernelWakelockReader mReader;
 
     @Override
@@ -66,18 +101,22 @@
         mReader = new KernelWakelockReader();
     }
 
+// ------------------------- Kernel Wakelock Stats Test ------------------------
     @SmallTest
     public void testParseEmptyFile() throws Exception {
         KernelWakelockStats staleStats = mReader.parseProcWakelocks(new byte[0], 0, true,
                 new KernelWakelockStats());
+
         assertTrue(staleStats.isEmpty());
     }
 
     @SmallTest
     public void testOnlyHeader() throws Exception {
         byte[] buffer = new ProcFileBuilder().getBytes();
+
         KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true,
                 new KernelWakelockStats());
+
         assertTrue(staleStats.isEmpty());
     }
 
@@ -86,9 +125,12 @@
         byte[] buffer = new ProcFileBuilder()
                 .addLine("Wakelock", 34, 123) // Milliseconds
                 .getBytes();
+
         KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true,
                 new KernelWakelockStats());
+
         assertEquals(1, staleStats.size());
+
         assertTrue(staleStats.containsKey("Wakelock"));
 
         KernelWakelockStats.Entry entry = staleStats.get("Wakelock");
@@ -102,9 +144,12 @@
                 .addLine("Wakelock", 1, 10)
                 .addLine("Fakelock", 2, 20)
                 .getBytes();
+
         KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true,
                 new KernelWakelockStats());
+
         assertEquals(2, staleStats.size());
+
         assertTrue(staleStats.containsKey("Wakelock"));
         assertTrue(staleStats.containsKey("Fakelock"));
     }
@@ -115,8 +160,10 @@
                 .addLine("Wakelock", 1, 10) // Milliseconds
                 .addLine("Wakelock", 1, 10) // Milliseconds
                 .getBytes();
+
         KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true,
                 new KernelWakelockStats());
+
         assertEquals(1, staleStats.size());
         assertTrue(staleStats.containsKey("Wakelock"));
 
@@ -127,12 +174,14 @@
 
     @SmallTest
     public void testWakelocksBecomeStale() throws Exception {
+        KernelWakelockStats staleStats = new KernelWakelockStats();
+
         byte[] buffer = new ProcFileBuilder()
                 .addLine("Fakelock", 3, 30)
                 .getBytes();
-        KernelWakelockStats staleStats = new KernelWakelockStats();
 
-        staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats);
+        readKernelWakelockStats(staleStats, buffer, new WakeLockInfo[0]);
+
         assertEquals(1, staleStats.size());
         assertTrue(staleStats.containsKey("Fakelock"));
 
@@ -140,9 +189,228 @@
                 .addLine("Wakelock", 1, 10)
                 .getBytes();
 
-        staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats);
+        readKernelWakelockStats(staleStats, buffer, new WakeLockInfo[0]);
+
         assertEquals(1, staleStats.size());
         assertTrue(staleStats.containsKey("Wakelock"));
         assertFalse(staleStats.containsKey("Fakelock"));
     }
+
+// -------------------- Native (SystemSuspend) Wakelock Stats Test -------------------
+    @SmallTest
+    public void testEmptyWakeLockInfoList() {
+        KernelWakelockStats staleStats = mReader.getNativeWakelockStats(new WakeLockInfo[0],
+                new KernelWakelockStats());
+
+        assertTrue(staleStats.isEmpty());
+    }
+
+    @SmallTest
+    public void testOneWakeLockInfo() {
+        WakeLockInfo[] wlStats = new WakeLockInfo[1];
+        wlStats[0] = createWakeLockInfo("WakeLock", 20, 10000);
+
+        KernelWakelockStats staleStats = mReader.getNativeWakelockStats(wlStats,
+                new KernelWakelockStats());
+
+        assertEquals(1, staleStats.size());
+
+        assertTrue(staleStats.containsKey("WakeLock"));
+
+        KernelWakelockStats.Entry entry = staleStats.get("WakeLock");
+        assertEquals(20, entry.mCount);
+        assertEquals(10000, entry.mTotalTime);
+    }
+
+    @SmallTest
+    public void testTwoWakeLockInfos() {
+        WakeLockInfo[] wlStats = new WakeLockInfo[2];
+        wlStats[0] = createWakeLockInfo("WakeLock1", 10, 1000);
+        wlStats[1] = createWakeLockInfo("WakeLock2", 20, 2000);
+
+        KernelWakelockStats staleStats = mReader.getNativeWakelockStats(wlStats,
+                new KernelWakelockStats());
+
+        assertEquals(2, staleStats.size());
+
+        assertTrue(staleStats.containsKey("WakeLock1"));
+        assertTrue(staleStats.containsKey("WakeLock2"));
+
+        KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
+        assertEquals(10, entry1.mCount);
+        assertEquals(1000, entry1.mTotalTime);
+
+        KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
+        assertEquals(20, entry2.mCount);
+        assertEquals(2000, entry2.mTotalTime);
+    }
+
+    @SmallTest
+    public void testWakeLockInfosBecomeStale() {
+        WakeLockInfo[] wlStats = new WakeLockInfo[1];
+        wlStats[0] = createWakeLockInfo("WakeLock1", 10, 1000);
+
+        KernelWakelockStats staleStats = new KernelWakelockStats();
+
+        readKernelWakelockStats(staleStats, new byte[0], wlStats);
+
+        assertEquals(1, staleStats.size());
+
+        assertTrue(staleStats.containsKey("WakeLock1"));
+        KernelWakelockStats.Entry entry = staleStats.get("WakeLock1");
+        assertEquals(10, entry.mCount);
+        assertEquals(1000, entry.mTotalTime);
+
+        wlStats[0] = createWakeLockInfo("WakeLock2", 20, 2000);
+
+        readKernelWakelockStats(staleStats, new byte[0], wlStats);
+
+        assertEquals(1, staleStats.size());
+
+        assertFalse(staleStats.containsKey("WakeLock1"));
+        assertTrue(staleStats.containsKey("WakeLock2"));
+        entry = staleStats.get("WakeLock2");
+        assertEquals(20, entry.mCount);
+        assertEquals(2000, entry.mTotalTime);
+    }
+
+// -------------------- Aggregate  Wakelock Stats Tests --------------------
+    @SmallTest
+    public void testAggregateStatsEmpty() throws Exception {
+        KernelWakelockStats staleStats = new KernelWakelockStats();
+
+        byte[] buffer = new byte[0];
+        WakeLockInfo[] wlStats = new WakeLockInfo[0];
+
+        readKernelWakelockStats(staleStats, buffer, wlStats);
+
+        assertTrue(staleStats.isEmpty());
+    }
+
+    @SmallTest
+    public void testAggregateStatsNoNativeWakelocks() throws Exception {
+        KernelWakelockStats staleStats = new KernelWakelockStats();
+
+        byte[] buffer = new ProcFileBuilder()
+                .addLine("Wakelock", 34, 123) // Milliseconds
+                .getBytes();
+        WakeLockInfo[] wlStats = new WakeLockInfo[0];
+
+        readKernelWakelockStats(staleStats, buffer, wlStats);
+
+        assertEquals(1, staleStats.size());
+
+        assertTrue(staleStats.containsKey("Wakelock"));
+
+        KernelWakelockStats.Entry entry = staleStats.get("Wakelock");
+        assertEquals(34, entry.mCount);
+        assertEquals(1000 * 123, entry.mTotalTime);  // Microseconds
+    }
+
+    @SmallTest
+    public void testAggregateStatsNoKernelWakelocks() throws Exception {
+        KernelWakelockStats staleStats = new KernelWakelockStats();
+
+        byte[] buffer = new byte[0];
+        WakeLockInfo[] wlStats = new WakeLockInfo[1];
+        wlStats[0] = createWakeLockInfo("WakeLock", 10, 1000);
+
+        readKernelWakelockStats(staleStats, buffer, wlStats);
+
+        assertEquals(1, staleStats.size());
+
+        assertTrue(staleStats.containsKey("WakeLock"));
+
+        KernelWakelockStats.Entry entry = staleStats.get("WakeLock");
+        assertEquals(10, entry.mCount);
+        assertEquals(1000, entry.mTotalTime);
+    }
+
+    @SmallTest
+    public void testAggregateStatsBothKernelAndNativeWakelocks() throws Exception {
+        KernelWakelockStats staleStats = new KernelWakelockStats();
+
+        byte[] buffer = new ProcFileBuilder()
+                .addLine("WakeLock1", 34, 123)  // Milliseconds
+                .getBytes();
+        WakeLockInfo[] wlStats = new WakeLockInfo[1];
+        wlStats[0] = createWakeLockInfo("WakeLock2", 10, 1000);
+
+        readKernelWakelockStats(staleStats, buffer, wlStats);
+
+        assertEquals(2, staleStats.size());
+
+        assertTrue(staleStats.containsKey("WakeLock1"));
+        KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
+        assertEquals(34, entry1.mCount);
+        assertEquals(123 * 1000, entry1.mTotalTime);  // Microseconds
+
+        assertTrue(staleStats.containsKey("WakeLock2"));
+        KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
+        assertEquals(10, entry2.mCount);
+        assertEquals(1000, entry2.mTotalTime);
+    }
+
+    @SmallTest
+    public void testAggregateStatsUpdate() throws Exception {
+        KernelWakelockStats staleStats = new KernelWakelockStats();
+
+        byte[] buffer = new ProcFileBuilder()
+                .addLine("WakeLock1", 34, 123)  // Milliseconds
+                .addLine("WakeLock2", 46, 345)  // Milliseconds
+                .getBytes();
+        WakeLockInfo[] wlStats = new WakeLockInfo[2];
+        wlStats[0] = createWakeLockInfo("WakeLock3", 10, 1000);
+        wlStats[1] = createWakeLockInfo("WakeLock4", 20, 2000);
+
+        readKernelWakelockStats(staleStats, buffer, wlStats);
+
+        assertEquals(4, staleStats.size());
+
+        assertTrue(staleStats.containsKey("WakeLock1"));
+        assertTrue(staleStats.containsKey("WakeLock2"));
+        assertTrue(staleStats.containsKey("WakeLock3"));
+        assertTrue(staleStats.containsKey("WakeLock4"));
+
+        KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
+        assertEquals(34, entry1.mCount);
+        assertEquals(123 * 1000, entry1.mTotalTime); // Microseconds
+
+        KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
+        assertEquals(46, entry2.mCount);
+        assertEquals(345 * 1000, entry2.mTotalTime); // Microseconds
+
+        KernelWakelockStats.Entry entry3 = staleStats.get("WakeLock3");
+        assertEquals(10, entry3.mCount);
+        assertEquals(1000, entry3.mTotalTime);
+
+        KernelWakelockStats.Entry entry4 = staleStats.get("WakeLock4");
+        assertEquals(20, entry4.mCount);
+        assertEquals(2000, entry4.mTotalTime);
+
+        buffer = new ProcFileBuilder()
+                .addLine("WakeLock1", 45, 789)  // Milliseconds
+                .addLine("WakeLock1", 56, 123)  // Milliseconds
+                .getBytes();
+        wlStats = new WakeLockInfo[1];
+        wlStats[0] = createWakeLockInfo("WakeLock4", 40, 4000);
+
+        readKernelWakelockStats(staleStats, buffer, wlStats);
+
+        assertEquals(2, staleStats.size());
+
+        assertTrue(staleStats.containsKey("WakeLock1"));
+        assertTrue(staleStats.containsKey("WakeLock4"));
+
+        assertFalse(staleStats.containsKey("WakeLock2"));
+        assertFalse(staleStats.containsKey("WakeLock3"));
+
+        entry1 = staleStats.get("WakeLock1");
+        assertEquals(45 + 56, entry1.mCount);
+        assertEquals((789 + 123) * 1000, entry1.mTotalTime);  // Microseconds
+
+        entry2 = staleStats.get("WakeLock4");
+        assertEquals(40, entry2.mCount);
+        assertEquals(4000, entry4.mTotalTime);
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/policy/DecorViewTest.java b/core/tests/coretests/src/com/android/internal/policy/DecorViewTest.java
new file mode 100644
index 0000000..f66717e
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/policy/DecorViewTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.policy;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+public class DecorViewTest {
+
+    private Context mContext;
+    private DecorView mDecorView;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        PhoneWindow phoneWindow = new PhoneWindow(mContext);
+        mDecorView = (DecorView) phoneWindow.getDecorView();
+    }
+
+    @Test
+    public void setBackgroundDrawableSameAsSetWindowBackground() {
+        Drawable bitmapDrawable = mContext.getResources()
+                .getDrawable(R.drawable.test16x12, mContext.getTheme());
+        int w = 16;
+        int h = 12;
+        Bitmap expectedBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+
+        mDecorView.setWindowBackground(bitmapDrawable);
+        Canvas testCanvas = new Canvas(expectedBitmap);
+        mDecorView.draw(testCanvas);
+        testCanvas.release();
+
+        Drawable expectedBackground = mDecorView.getBackground();
+
+        mDecorView.setBackgroundDrawable(bitmapDrawable);
+        Bitmap resultBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+        Canvas resCanvas = new Canvas(resultBitmap);
+        mDecorView.draw(resCanvas);
+        resCanvas.release();
+
+        // Check that the drawable is the same.
+        assertThat(mDecorView.getBackground()).isEqualTo(expectedBackground);
+        assertThat(mDecorView.getBackground()).isEqualTo(bitmapDrawable);
+
+        // Check that canvas is the same.
+        int[] expPixels = new int[w * h];
+        int[] resPixels = new int[w * h];
+        resultBitmap.getPixels(resPixels, 0, w, 0, 0, w, h);
+        expectedBitmap.getPixels(expPixels, 0, w, 0, 0, w, h);
+        assertThat(Arrays.toString(expPixels)).isEqualTo(Arrays.toString(resPixels));
+    }
+}
diff --git a/core/tests/mockingcoretests/src/android/util/TimingsTraceLogTest.java b/core/tests/mockingcoretests/src/android/util/TimingsTraceLogTest.java
new file mode 100644
index 0000000..5dc44d2
--- /dev/null
+++ b/core/tests/mockingcoretests/src/android/util/TimingsTraceLogTest.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.util;
+
+import static android.os.Trace.TRACE_TAG_APP;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.contains;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.matches;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+
+import android.os.Trace;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.dx.mockito.inline.extended.MockedVoidMethod;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoSession;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link TimingsTraceLog}.
+ *
+ * <p>Usage: {@code atest FrameworksMockingCoreTests:android.util.TimingsTraceLogTest}
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TimingsTraceLogTest {
+
+    private static final String TAG = "TEST";
+
+    private MockitoSession mSession;
+
+    @Before
+    public final void startMockSession() {
+        mSession = mockitoSession()
+                .spyStatic(Slog.class)
+                .spyStatic(Trace.class)
+                .startMocking();
+    }
+
+    @After
+    public final void finishMockSession() {
+        mSession.finishMocking();
+    }
+
+    @Test
+    public void testDifferentThreads() throws Exception {
+        TimingsTraceLog log = new TimingsTraceLog(TAG, TRACE_TAG_APP);
+        // Should be able to log on the same thread
+        log.traceBegin("test");
+        log.traceEnd();
+        final List<String> errors = new ArrayList<>();
+        // Calling from a different thread should fail
+        Thread t = new Thread(() -> {
+            try {
+                log.traceBegin("test");
+                errors.add("traceBegin should fail on a different thread");
+            } catch (IllegalStateException expected) {
+            }
+            try {
+                log.traceEnd();
+                errors.add("traceEnd should fail on a different thread");
+            } catch (IllegalStateException expected) {
+            }
+            // Verify that creating a new log will work
+            TimingsTraceLog log2 = new TimingsTraceLog(TAG, TRACE_TAG_APP);
+            log2.traceBegin("test");
+            log2.traceEnd();
+
+        });
+        t.start();
+        t.join();
+        assertThat(errors).isEmpty();
+    }
+
+    @Test
+    public void testGetUnfinishedTracesForDebug() {
+        TimingsTraceLog log = new TimingsTraceLog("TEST", Trace.TRACE_TAG_APP);
+        assertThat(log.getUnfinishedTracesForDebug()).isEmpty();
+
+        log.traceBegin("One");
+        assertThat(log.getUnfinishedTracesForDebug()).containsExactly("One").inOrder();
+
+        log.traceBegin("Two");
+        assertThat(log.getUnfinishedTracesForDebug()).containsExactly("One", "Two").inOrder();
+
+        log.traceEnd();
+        assertThat(log.getUnfinishedTracesForDebug()).containsExactly("One").inOrder();
+
+        log.traceEnd();
+        assertThat(log.getUnfinishedTracesForDebug()).isEmpty();
+    }
+
+    @Test
+    public void testLogDuration() throws Exception {
+        TimingsTraceLog log = new TimingsTraceLog(TAG, TRACE_TAG_APP, 10);
+        log.logDuration("logro", 42);
+        verify((MockedVoidMethod) () -> Slog.d(eq(TAG), contains("logro took to complete: 42ms")));
+    }
+
+    @Test
+    public void testOneLevel() throws Exception {
+        TimingsTraceLog log = new TimingsTraceLog(TAG, TRACE_TAG_APP, 10);
+        log.traceBegin("test");
+        log.traceEnd();
+
+        verify((MockedVoidMethod) () -> Trace.traceBegin(TRACE_TAG_APP, "test"));
+        verify((MockedVoidMethod) () -> Trace.traceEnd(TRACE_TAG_APP));
+        verify((MockedVoidMethod) () -> Slog.d(eq(TAG), matches("test took to complete: \\dms")));
+    }
+
+    @Test
+    public void testMultipleLevels() throws Exception {
+        TimingsTraceLog log = new TimingsTraceLog(TAG, Trace.TRACE_TAG_APP, 10);
+        log.traceBegin("L1");
+        log.traceBegin("L2");
+        log.traceEnd();
+        log.traceEnd();
+
+        verify((MockedVoidMethod) () -> Trace.traceBegin(TRACE_TAG_APP, "L1"));
+        verify((MockedVoidMethod) () -> Trace.traceBegin(TRACE_TAG_APP, "L2"));
+        verify((MockedVoidMethod) () -> Trace.traceEnd(TRACE_TAG_APP), times(2)); // L1 and L2
+
+        verify((MockedVoidMethod) () -> Slog.d(eq(TAG), matches("L2 took to complete: \\d+ms")));
+        verify((MockedVoidMethod) () -> Slog.d(eq(TAG), matches("L1 took to complete: \\d+ms")));
+    }
+
+    @Test
+    public void testTooManyLevels() throws Exception {
+        TimingsTraceLog log = new TimingsTraceLog(TAG, Trace.TRACE_TAG_APP, 2);
+
+        log.traceBegin("L1"); // ok
+        log.traceBegin("L2"); // ok
+        log.traceBegin("L3"); // logging ignored ( > 2)
+
+        log.traceEnd();
+        log.traceEnd();
+        log.traceEnd();
+
+        verify((MockedVoidMethod) () -> Trace.traceBegin(TRACE_TAG_APP, "L1"));
+        verify((MockedVoidMethod) () -> Trace.traceBegin(TRACE_TAG_APP, "L2"));
+        verify((MockedVoidMethod) () -> Trace.traceBegin(TRACE_TAG_APP, "L3"));
+        verify((MockedVoidMethod) () -> Trace.traceEnd(TRACE_TAG_APP), times(3));
+
+        verify((MockedVoidMethod) () -> Slog.d(eq(TAG), matches("L2 took to complete: \\d+ms")));
+        verify((MockedVoidMethod) () -> Slog.d(eq(TAG), matches("L1 took to complete: \\d+ms")));
+        verify((MockedVoidMethod) () -> Slog.d(eq(TAG), matches("L3 took to complete: \\d+ms")),
+                never());
+
+        verify((MockedVoidMethod) () -> Slog.w(TAG, "not tracing duration of 'L3' "
+                + "because already reached 2 levels"));
+    }
+
+    @Test
+    public void testEndNoBegin() throws Exception {
+        TimingsTraceLog log = new TimingsTraceLog(TAG, TRACE_TAG_APP);
+        log.traceEnd();
+        verify((MockedVoidMethod) () -> Trace.traceEnd(TRACE_TAG_APP));
+        verify((MockedVoidMethod) () -> Slog.d(eq(TAG), anyString()), never());
+        verify((MockedVoidMethod) () -> Slog.w(TAG, "traceEnd called more times than traceBegin"));
+    }
+}
diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp
new file mode 100644
index 0000000..f13885e
--- /dev/null
+++ b/core/tests/utiltests/Android.bp
@@ -0,0 +1,38 @@
+//########################################################################
+// Build FrameworksUtilTests package
+//########################################################################
+
+android_test {
+    name: "FrameworksUtilTests",
+
+    // We only want this apk build for tests.
+
+    // Include all test java files.
+    srcs: ["src/**/*.java"] + ["src/android/util/IRemoteMemoryIntArray.aidl"],
+
+    jni_libs: [
+        "libmemoryintarraytest",
+        "libcutils",
+        "libc++",
+    ],
+
+    static_libs: [
+        "androidx.test.rules",
+        "frameworks-base-testutils",
+        "mockito-target-minus-junit4",
+        "androidx.test.ext.junit",
+    ],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
+
+    platform_apis: true,
+
+    certificate: "platform",
+
+    test_suites: ["device-tests"],
+
+}
diff --git a/core/tests/utiltests/Android.mk b/core/tests/utiltests/Android.mk
deleted file mode 100644
index 9ef73e9..0000000
--- a/core/tests/utiltests/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#########################################################################
-# Build FrameworksUtilTests package
-#########################################################################
-
-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_SRC_FILES += src/android/util/IRemoteMemoryIntArray.aidl
-
-LOCAL_JNI_SHARED_LIBRARIES := libmemoryintarraytest libcutils libc++
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.rules \
-    frameworks-base-testutils \
-    mockito-target-minus-junit4 \
-    androidx.test.ext.junit
-
-LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
-
-LOCAL_PACKAGE_NAME := FrameworksUtilTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_CERTIFICATE := platform
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
-
diff --git a/data/etc/car/com.android.car.developeroptions.xml b/data/etc/car/com.android.car.developeroptions.xml
index 76c8c62..5f5e908 100644
--- a/data/etc/car/com.android.car.developeroptions.xml
+++ b/data/etc/car/com.android.car.developeroptions.xml
@@ -42,6 +42,7 @@
         <permission name="android.permission.PACKAGE_USAGE_STATS"/>
         <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
         <permission name="android.permission.REBOOT"/>
+        <permission name="android.permission.REQUEST_NETWORK_SCORES"/>
         <permission name="android.permission.SET_TIME"/>
         <permission name="android.permission.STATUS_BAR"/>
         <permission name="android.permission.TETHER_PRIVILEGED"/>
diff --git a/data/etc/com.android.settings.xml b/data/etc/com.android.settings.xml
index 3e53a38..72be9f5 100644
--- a/data/etc/com.android.settings.xml
+++ b/data/etc/com.android.settings.xml
@@ -41,6 +41,7 @@
         <permission name="android.permission.PACKAGE_USAGE_STATS"/>
         <permission name="android.permission.READ_SEARCH_INDEXABLES"/>
         <permission name="android.permission.REBOOT"/>
+        <permission name="android.permission.REQUEST_NETWORK_SCORES"/>
         <permission name="android.permission.SET_TIME"/>
         <permission name="android.permission.STATUS_BAR"/>
         <permission name="android.permission.TETHER_PRIVILEGED"/>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index a4337cc8..1d735af 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -44,6 +44,7 @@
         <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.REAL_GET_TASKS"/>
+        <permission name="android.permission.REQUEST_NETWORK_SCORES"/>
         <permission name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"/>
         <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
         <permission name="android.permission.START_ACTIVITY_AS_CALLER"/>
@@ -54,6 +55,7 @@
         <permission name="android.permission.TETHER_PRIVILEGED"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
         <permission name="android.permission.USE_RESERVED_DISK"/>
+        <permission name="android.permission.WATCH_APPOPS"/>
         <permission name="android.permission.WRITE_DREAM_STATE"/>
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index e24f26c1..054f68b 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -17,8 +17,12 @@
 
 <!--
 This XML file declares which system apps should be exempted from the hidden API blacklisting, i.e.
-which apps should be allowed to access the entire private API. Only apps NOT signed with the
-platform cert need to be included, as apps signed with the platform cert are exempted by default.
+which apps should be allowed to access the entire private API.
+
+Only apps NOT signed with the platform cert need to be included, as apps signed with the platform
+cert are exempted by default.
+
+Do NOT include any apps that are updatable via Play Store!
 -->
 
 <config>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a640122..89e26da 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -151,6 +151,7 @@
         <permission name="android.permission.SET_TIME"/>
         <permission name="android.permission.SET_TIME_ZONE"/>
         <permission name="android.permission.SHUTDOWN"/>
+        <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
         <permission name="android.permission.STATUS_BAR"/>
         <permission name="android.permission.STOP_APP_SWITCHES"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
@@ -185,6 +186,7 @@
         <permission name="android.permission.ACCESS_CACHE_FILESYSTEM"/>
         <permission name="android.permission.CLEAR_APP_CACHE"/>
         <permission name="android.permission.CONNECTIVITY_INTERNAL"/>
+        <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
         <permission name="android.permission.UPDATE_DEVICE_STATS"/>
     </privapp-permissions>
@@ -267,6 +269,8 @@
         <permission name="android.permission.INSTALL_PACKAGES"/>
         <!-- Needed for test only -->
         <permission name="android.permission.INTERACT_ACROSS_PROFILES"/>
+        <!-- Permission required to test onPermissionsChangedListener -->
+        <permission name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"/>
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
         <permission name="android.permission.LOCAL_MAC_ADDRESS"/>
         <permission name="android.permission.MANAGE_ACCESSIBILITY"/>
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 8699cb4..5150043 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -408,6 +408,8 @@
 key 523   POUND
 key 580   APP_SWITCH
 key 582   VOICE_ASSIST
+# Linux KEY_ASSISTANT
+key 583   ASSIST
 
 # Keys defined by HID usages
 key usage 0x0c006F BRIGHTNESS_UP
diff --git a/data/keyboards/Vendor_045e_Product_028e.kl b/data/keyboards/Vendor_045e_Product_028e.kl
index 301601a..e4f48f9 100644
--- a/data/keyboards/Vendor_045e_Product_028e.kl
+++ b/data/keyboards/Vendor_045e_Product_028e.kl
@@ -22,9 +22,7 @@
 key 308   BUTTON_Y
 key 310   BUTTON_L1
 key 311   BUTTON_R1
-key 314   BACK
-key 315   BUTTON_START
-key 316   HOME
+
 key 317   BUTTON_THUMBL
 key 318   BUTTON_THUMBR
 
@@ -44,3 +42,14 @@
 # Hat.
 axis 0x10 HAT_X
 axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+
+# Button labeled as "BACK" (left-pointing triangle)
+key 314   BUTTON_SELECT
+
+# The branded "X" button in the center of the controller
+key 316   BUTTON_MODE
+
+# Button labeled as "START" (right-pointing triangle)
+key 315   BUTTON_START
diff --git a/data/keyboards/Vendor_045e_Product_02d1.kl b/data/keyboards/Vendor_045e_Product_02d1.kl
index 5d1637b..0867670 100644
--- a/data/keyboards/Vendor_045e_Product_02d1.kl
+++ b/data/keyboards/Vendor_045e_Product_02d1.kl
@@ -13,20 +13,22 @@
 # limitations under the License.
 
 #
-# XBox One USB Controller
+# XBox One Controller - Model 1537 - USB
 #
 
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
 key 304   BUTTON_A
 key 305   BUTTON_B
 key 307   BUTTON_X
 key 308   BUTTON_Y
+
 key 310   BUTTON_L1
 key 311   BUTTON_R1
-key 314   BACK
-key 315   BUTTON_START
-key 316   HOME
-key 317   BUTTON_THUMBL
-key 318   BUTTON_THUMBR
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
 
 # Left and right stick.
 # The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
@@ -37,10 +39,19 @@
 axis 0x03 Z flat 4096
 axis 0x04 RZ flat 4096
 
-# Triggers.
-axis 0x02 LTRIGGER
-axis 0x05 RTRIGGER
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
 
 # Hat.
 axis 0x10 HAT_X
 axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 314   BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315   BUTTON_START
+
+# Xbox key
+key 316   BUTTON_MODE
diff --git a/data/keyboards/Vendor_045e_Product_02e3.kl b/data/keyboards/Vendor_045e_Product_02e3.kl
new file mode 100644
index 0000000..0a6e7d7
--- /dev/null
+++ b/data/keyboards/Vendor_045e_Product_02e3.kl
@@ -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.
+
+#
+# Microsoft X-Box One Elite Pad - Model 1698 - USB
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 0x130   BUTTON_A
+key 0x131   BUTTON_B
+key 0x133   BUTTON_X
+key 0x134   BUTTON_Y
+
+key 0x136   BUTTON_L1
+key 0x137   BUTTON_R1
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Left stick
+axis 0x00 X
+axis 0x01 Y
+# Right stick
+axis 0x03 Z
+axis 0x04 RZ
+
+key 0x13d   BUTTON_THUMBL
+key 0x13e   BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+
+# Two overlapping rectangles
+key 0x13a   BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 0x13b   BUTTON_START
+
+# Xbox key
+key 0x13c   BUTTON_MODE
diff --git a/data/keyboards/Vendor_045e_Product_02ea.kl b/data/keyboards/Vendor_045e_Product_02ea.kl
new file mode 100644
index 0000000..3b46db2
--- /dev/null
+++ b/data/keyboards/Vendor_045e_Product_02ea.kl
@@ -0,0 +1,57 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# XBox One Controller - Model 1708 - USB
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Left and right stick.
+# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick actually
+# settles in a flat range of +/- 4096 or so.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x03 Z flat 4096
+axis 0x04 RZ flat 4096
+
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 314   BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315   BUTTON_START
+
+# Xbox key
+key 316   BUTTON_MODE
diff --git a/data/keyboards/Vendor_045e_Product_02fd.kl b/data/keyboards/Vendor_045e_Product_02fd.kl
new file mode 100644
index 0000000..512f7e1
--- /dev/null
+++ b/data/keyboards/Vendor_045e_Product_02fd.kl
@@ -0,0 +1,57 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# XBox One Controller - Model 1708 - Bluetooth
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+
+# Triggers.
+axis 0x0a LTRIGGER
+axis 0x09 RTRIGGER
+
+# Left and right stick.
+# The reported value for flat is 128 out of a range from -32767 to 32768, which is absurd.
+# This confuses applications that rely on the flat value because the joystick actually
+# settles in a flat range of +/- 4096 or so.
+axis 0x00 X flat 4096
+axis 0x01 Y flat 4096
+axis 0x02 Z flat 4096
+axis 0x05 RZ flat 4096
+
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 158   BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315   BUTTON_START
+
+# Xbox key
+key 172   BUTTON_MODE
diff --git a/data/keyboards/Vendor_057e_Product_2009.kl b/data/keyboards/Vendor_057e_Product_2009.kl
new file mode 100644
index 0000000..b36e946
--- /dev/null
+++ b/data/keyboards/Vendor_057e_Product_2009.kl
@@ -0,0 +1,68 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Nintendo Switch Pro Controller - HAC-013 - Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Button labeled as "Y" but should really produce keycode "X"
+key 0x132    BUTTON_X
+# Button labeled as "B" but should really produce keycode "A"
+key 0x130    BUTTON_A
+# Button labeled as "A" but should really produce keycode "B"
+key 0x131    BUTTON_B
+# Button labeled as "X" but should really product keycode "Y"
+key 0x133    BUTTON_Y
+
+# Button labeled as "L"
+key 0x134    BUTTON_L1
+# Button labeled as "R"
+key 0x135    BUTTON_R1
+
+# No LT / RT axes on this controller. Instead, there are keys.
+# Trigger labeled as "ZL"
+key 0x136    BUTTON_L2
+# Trigger labeled as "ZR"
+key 0x137    BUTTON_R2
+
+# Left Analog Stick
+axis 0x00    X
+axis 0x01    Y
+# Right Analog Stick
+axis 0x03    Z
+axis 0x04    RZ
+
+# Left stick click (generates linux BTN_SELECT)
+key 0x13a    BUTTON_THUMBL
+# Right stick click (generates linux BTN_START)
+key 0x13b    BUTTON_THUMBR
+
+# Hat
+axis 0x10    HAT_X
+axis 0x11    HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Minus
+key 0x138    BUTTON_SELECT
+# Plus
+key 0x139    BUTTON_START
+
+# Circle
+key 0x13d    BUTTON_MODE
+
+# Home key
+key 0x13c    HOME
diff --git a/data/keyboards/Vendor_0e6f_Product_02a4.kl b/data/keyboards/Vendor_0e6f_Product_02a4.kl
new file mode 100644
index 0000000..9ffae33
--- /dev/null
+++ b/data/keyboards/Vendor_0e6f_Product_02a4.kl
@@ -0,0 +1,54 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# PDP Wired Controller for Xbox One - Stealth Series
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+
+# Triggers.
+axis 0x02 LTRIGGER
+axis 0x05 RTRIGGER
+
+# Left and right stick.
+axis 0x00 X
+axis 0x01 Y
+axis 0x03 Z
+axis 0x04 RZ
+
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Two overlapping rectangles
+key 314    BUTTON_SELECT
+# Hamburger - 3 parallel lines
+key 315    BUTTON_START
+
+# Xbox key
+key 316    BUTTON_MODE
diff --git a/data/sounds/AudioTv.mk b/data/sounds/AudioTv.mk
index d0006b7..2a31e4c 100644
--- a/data/sounds/AudioTv.mk
+++ b/data/sounds/AudioTv.mk
@@ -15,6 +15,7 @@
 LOCAL_PATH := frameworks/base/data/sounds
 
 PRODUCT_COPY_FILES += \
+    $(LOCAL_PATH)/Alarm_Beep_01.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/alarms/Alarm_Beep_02.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressDelete_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressDelete.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressInvalid_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressInvalid.ogg \
     $(LOCAL_PATH)/effects/ogg/KeypressReturn_120_48k.ogg:$(TARGET_COPY_OUT_PRODUCT)/media/audio/ui/KeypressReturn.ogg \
diff --git a/graphics/java/android/graphics/PointF.java b/graphics/java/android/graphics/PointF.java
index f1f48ad..ed9df14 100644
--- a/graphics/java/android/graphics/PointF.java
+++ b/graphics/java/android/graphics/PointF.java
@@ -38,6 +38,18 @@
         this.x = p.x;
         this.y = p.y;
     }
+
+    /**
+     * Create a new PointF initialized with the values in the specified
+     * PointF (which is left unmodified).
+     *
+     * @param p The point whose values are copied into the new
+     *          point.
+     */
+    public PointF(@NonNull PointF p) {
+        this.x = p.x;
+        this.y = p.y;
+    }
     
     /**
      * Set the point's x and y coordinates
diff --git a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
index 35021a6..20cd825 100644
--- a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
@@ -25,6 +25,7 @@
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.util.MathUtils;
 
 /**
@@ -136,6 +137,12 @@
     }
 
     @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+        mColorDrawable.setBounds(bounds);
+    }
+
+    @Override
     protected boolean onStateChange(int[] state) {
         if (mState.mColor != null) {
             int color = mState.mColor.getColorForState(state, mState.mColor.getDefaultColor());
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 32f2fc2..b9945cc 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1757,7 +1757,7 @@
         }
 
         int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
-        st.mAngle = angle % 360;
+        st.mAngle = ((angle % 360) + 360) % 360; // offset negative angle measures
 
         final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
         if (tv != null) {
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index f3a1b0e..760d554 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -139,9 +139,12 @@
         final ChildDrawable[] r = new ChildDrawable[length];
         for (int i = 0; i < length; i++) {
             r[i] = new ChildDrawable(mLayerState.mDensity);
-            r[i].mDrawable = layers[i];
-            layers[i].setCallback(this);
-            mLayerState.mChildrenChangingConfigurations |= layers[i].getChangingConfigurations();
+            Drawable child = layers[i];
+            r[i].mDrawable = child;
+            if (child != null) {
+                child.setCallback(this);
+                mLayerState.mChildrenChangingConfigurations |= child.getChangingConfigurations();
+            }
         }
         mLayerState.mNumChildren = length;
         mLayerState.mChildren = r;
@@ -416,7 +419,8 @@
         final ChildDrawable[] layers = mLayerState.mChildren;
         final int N = mLayerState.mNumChildren;
         for (int i = 0; i < N; i++) {
-            if (layers[i].mDrawable.isProjected()) {
+            Drawable childDrawable = layers[i].mDrawable;
+            if (childDrawable != null && childDrawable.isProjected()) {
                 return true;
             }
         }
diff --git a/graphics/proto/Android.bp b/graphics/proto/Android.bp
index 1d06348..ddced59 100644
--- a/graphics/proto/Android.bp
+++ b/graphics/proto/Android.bp
@@ -5,7 +5,6 @@
         type: "lite",
     },
     srcs: ["game_driver.proto"],
-    no_framework_libs: true,
     jarjar_rules: "jarjar-rules.txt",
     sdk_version: "28",
 }
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 646aa13..ee8cc40 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -584,7 +584,7 @@
         }
         KeyCharacteristics characteristics = result.getKeyCharacteristics();
         if (characteristics == null) {
-            Log.e(TAG, "generateKeyInternal got empty key cheractariestics " + error);
+            Log.e(TAG, "generateKeyInternal got empty key characteristics " + error);
             return SYSTEM_ERROR;
         }
         outCharacteristics.shallowCopyFrom(characteristics);
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 61e3230..9f4a619 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -134,7 +134,7 @@
   }
 
   if (entry.method == kCompressDeflated) {
-    LOG(WARNING) << kResourcesArsc << " in APK '" << path << "' is compressed.";
+    ANDROID_LOG(WARNING) << kResourcesArsc << " in APK '" << path << "' is compressed.";
   }
 
   // Open the resource table via mmap unless it is compressed. This logic is taken care of by Open.
@@ -216,7 +216,7 @@
     return false;
   }
 
-  ::ZipString name;
+  std::string name;
   ::ZipEntry entry;
 
   // We need to hold back directories because many paths will contain them and we want to only
@@ -225,7 +225,7 @@
 
   int32_t result;
   while ((result = ::Next(cookie, &entry, &name)) == 0) {
-    StringPiece full_file_path(reinterpret_cast<const char*>(name.name), name.name_length);
+    StringPiece full_file_path(name);
     StringPiece leaf_file_path = full_file_path.substr(root_path_full.size());
 
     if (!leaf_file_path.empty()) {
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 4755cb8..f7c8337 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -74,7 +74,7 @@
 const char* AssetManager::IDMAP_BIN = "/system/bin/idmap";
 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::SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
 const char* AssetManager::ODM_OVERLAY_DIR = "/odm/overlay";
 const char* AssetManager::OEM_OVERLAY_DIR = "/oem/overlay";
 const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme";
@@ -575,7 +575,7 @@
                         mZipSet.setZipResourceTableAsset(ap.path, ass);
                 }
             }
-            
+
             if (nextEntryIdx == 0 && ass != NULL) {
                 // If this is the first resource table in the asset
                 // manager, then we are going to cache it so that we
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index d20aeca..01caf01 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -22,10 +22,10 @@
 #include <iterator>
 #include <map>
 #include <set>
-#include <sstream>
 
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
+#include "androidfw/Util.h"
 #include "utils/ByteOrder.h"
 #include "utils/Trace.h"
 
@@ -35,12 +35,6 @@
 #endif
 #endif
 
-#ifdef __ANDROID__
-#define ANDROID_LOG(x) LOG(x)
-#else
-#define ANDROID_LOG(x) std::stringstream()
-#endif
-
 #include "androidfw/ResourceUtils.h"
 
 namespace android {
diff --git a/libs/androidfw/DisplayEventDispatcher.cpp b/libs/androidfw/DisplayEventDispatcher.cpp
index 6606148..d8a3f426 100644
--- a/libs/androidfw/DisplayEventDispatcher.cpp
+++ b/libs/androidfw/DisplayEventDispatcher.cpp
@@ -34,8 +34,9 @@
 static const size_t EVENT_BUFFER_SIZE = 100;
 
 DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper,
-        ISurfaceComposer::VsyncSource vsyncSource) :
-        mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false) {
+        ISurfaceComposer::VsyncSource vsyncSource,
+        ISurfaceComposer::ConfigChanged configChanged) :
+        mLooper(looper), mReceiver(vsyncSource, configChanged), mWaitingForVsync(false) {
     ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
 }
 
diff --git a/libs/androidfw/PosixUtils.cpp b/libs/androidfw/PosixUtils.cpp
index df0dd7c..f1ab149 100644
--- a/libs/androidfw/PosixUtils.cpp
+++ b/libs/androidfw/PosixUtils.cpp
@@ -64,6 +64,9 @@
     return nullptr;
   }
 
+  auto gid = getgid();
+  auto uid = getuid();
+
   char const** argv0 = (char const**)malloc(sizeof(char*) * (argv.size() + 1));
   for (size_t i = 0; i < argv.size(); i++) {
     argv0[i] = argv[i].c_str();
@@ -75,6 +78,16 @@
       PLOG(ERROR) << "fork";
       return nullptr;
     case 0: // child
+      if (setgid(gid) != 0) {
+        PLOG(ERROR) << "setgid";
+        exit(1);
+      }
+
+      if (setuid(uid) != 0) {
+        PLOG(ERROR) << "setuid";
+        exit(1);
+      }
+
       close(stdout[0]);
       if (dup2(stdout[1], STDOUT_FILENO) == -1) {
         abort();
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index ee5f778..e77ac3d 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -39,7 +39,7 @@
 class _ZipEntryRO {
 public:
     ZipEntry entry;
-    ZipString name;
+    std::string_view name;
     void *cookie;
 
     _ZipEntryRO() : cookie(NULL) {}
@@ -96,7 +96,7 @@
 {
     _ZipEntryRO* data = new _ZipEntryRO;
 
-    data->name = ZipString(entryName);
+    data->name = entryName;
 
     const int32_t error = FindEntry(mHandle, entryName, &(data->entry));
     if (error) {
@@ -194,14 +194,14 @@
     const
 {
     const _ZipEntryRO* zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
-    const uint16_t requiredSize = zipEntry->name.name_length + 1;
+    const uint16_t requiredSize = zipEntry->name.length() + 1;
 
     if (bufLen < requiredSize) {
         ALOGW("Buffer too short, requires %d bytes for entry name", requiredSize);
         return requiredSize;
     }
 
-    memcpy(buffer, zipEntry->name.name, requiredSize - 1);
+    memcpy(buffer, zipEntry->name.data(), requiredSize - 1);
     buffer[requiredSize - 1] = '\0';
 
     return 0;
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index 66fba26b..ce0985b 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -61,7 +61,7 @@
     static const char* IDMAP_BIN;
     static const char* VENDOR_OVERLAY_DIR;
     static const char* PRODUCT_OVERLAY_DIR;
-    static const char* PRODUCT_SERVICES_OVERLAY_DIR;
+    static const char* SYSTEM_EXT_OVERLAY_DIR;
     static const char* ODM_OVERLAY_DIR;
     static const char* OEM_OVERLAY_DIR;
     /*
diff --git a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
index 5381c01..8bc2520 100644
--- a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
+++ b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
@@ -23,7 +23,8 @@
 class DisplayEventDispatcher : public LooperCallback {
 public:
     explicit DisplayEventDispatcher(const sp<Looper>& looper,
-            ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);
+            ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp,
+            ISurfaceComposer::ConfigChanged configChanged = ISurfaceComposer::eConfigChangedSuppress);
 
     status_t initialize();
     void dispose();
diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h
index aa1466f..9a3646b 100644
--- a/libs/androidfw/include/androidfw/Util.h
+++ b/libs/androidfw/include/androidfw/Util.h
@@ -19,12 +19,19 @@
 
 #include <cstdlib>
 #include <memory>
+#include <sstream>
 #include <vector>
 
 #include "android-base/macros.h"
 
 #include "androidfw/StringPiece.h"
 
+#ifdef __ANDROID__
+#define ANDROID_LOG(x) LOG(x)
+#else
+#define ANDROID_LOG(x) std::stringstream()
+#endif
+
 namespace android {
 namespace util {
 
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 47f22d6..0d837f2 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -33,11 +33,6 @@
     include_dirs: [
         "external/skia/include/private",
         "external/skia/src/core",
-        "external/skia/src/effects",
-        "external/skia/src/image",
-        "external/skia/src/utils",
-        "external/skia/src/gpu",
-        "external/skia/src/shaders",
     ],
 
     product_variables: {
@@ -47,34 +42,69 @@
             },
         },
     },
+
+    target: {
+        android: {
+            include_dirs: [
+                "external/skia/src/effects",
+                "external/skia/src/image",
+                "external/skia/src/utils",
+                "external/skia/src/gpu",
+                "external/skia/src/shaders",
+            ],
+        },
+        host: {
+            include_dirs: [
+                "external/vulkan-headers/include",
+                "frameworks/native/libs/math/include",
+                "frameworks/native/libs/ui/include",
+            ],
+            cflags: [
+                "-Wno-unused-variable",
+            ],
+        }
+    }
 }
 
 cc_defaults {
     name: "hwui_static_deps",
     shared_libs: [
-        "liblog",
-        "libcutils",
         "libbase",
-        "libstatslog",
-        "libutils",
-        "libEGL",
-        "libGLESv1_CM",
-        "libGLESv2",
-        "libGLESv3",
-        "libvulkan",
-        "libui",
-        "libgui",
-        "libprotobuf-cpp-lite",
         "libharfbuzz_ng",
-        "libft2",
         "libminikin",
-        "libandroidfw",
-        "libcrypto",
-        "libsync",
     ],
-    static_libs: [
-        "libEGL_blobCache",
-    ],
+
+    target: {
+        android: {
+            shared_libs: [
+                "liblog",
+                "libcutils",
+                "libstatslog",
+                "libutils",
+                "libEGL",
+                "libGLESv1_CM",
+                "libGLESv2",
+                "libGLESv3",
+                "libvulkan",
+                "libui",
+                "libgui",
+                "libprotobuf-cpp-lite",
+                "libft2",
+                "libandroidfw",
+                "libcrypto",
+                "libsync",
+            ],
+            static_libs: [
+                "libEGL_blobCache",
+            ],
+        },
+        host: {
+            static_libs: [
+                "libandroidfw",
+                "libutils",
+            ],
+        }
+    }
 }
 
 cc_defaults {
@@ -92,28 +122,6 @@
     ],
 }
 
-cc_defaults {
-    name: "hwui_debug",
-    cflags: ["-include debug/wrap_gles.h"],
-    srcs: [
-        "debug/wrap_gles.cpp",
-        "debug/DefaultGlesDriver.cpp",
-        "debug/GlesErrorCheckWrapper.cpp",
-        "debug/GlesDriver.cpp",
-        "debug/FatalBaseDriver.cpp",
-        "debug/NullGlesDriver.cpp",
-        "debug/NullSkiaInterface.cpp",
-    ],
-    include_dirs: ["frameworks/native/opengl/libs/GLES2"],
-}
-
-cc_defaults {
-    name: "hwui_enable_opengl_validation",
-    defaults: ["hwui_debug"],
-    cflags: ["-DDEBUG_OPENGL=3"],
-    include_dirs: ["frameworks/native/opengl/libs/GLES2"],
-}
-
 // Build libhwui with PGO by default.
 // Location of PGO profile data is defined in build/soong/cc/pgo.go
 // and is separate from hwui.
@@ -153,6 +161,13 @@
     whole_static_libs: ["libskia"],
 
     srcs: [
+        "pipeline/skia/SkiaDisplayList.cpp",
+        "pipeline/skia/SkiaRecordingCanvas.cpp",
+        "pipeline/skia/RenderNodeDrawable.cpp",
+        "pipeline/skia/ReorderBarrierDrawables.cpp",
+        "renderthread/Frame.cpp",
+        "renderthread/RenderTask.cpp",
+        "renderthread/TimeLord.cpp",
         "hwui/AnimatedImageDrawable.cpp",
         "hwui/AnimatedImageThread.cpp",
         "hwui/Bitmap.cpp",
@@ -161,114 +176,112 @@
         "hwui/MinikinUtils.cpp",
         "hwui/PaintImpl.cpp",
         "hwui/Typeface.cpp",
-        "pipeline/skia/GLFunctorDrawable.cpp",
-        "pipeline/skia/LayerDrawable.cpp",
-        "pipeline/skia/RenderNodeDrawable.cpp",
-        "pipeline/skia/ReorderBarrierDrawables.cpp",
-        "pipeline/skia/ShaderCache.cpp",
-        "pipeline/skia/SkiaDisplayList.cpp",
-        "pipeline/skia/SkiaMemoryTracer.cpp",
-        "pipeline/skia/SkiaOpenGLPipeline.cpp",
-        "pipeline/skia/SkiaPipeline.cpp",
-        "pipeline/skia/SkiaProfileRenderer.cpp",
-        "pipeline/skia/SkiaRecordingCanvas.cpp",
-        "pipeline/skia/SkiaVulkanPipeline.cpp",
-        "pipeline/skia/VectorDrawableAtlas.cpp",
-        "pipeline/skia/VkFunctorDrawable.cpp",
-        "pipeline/skia/VkInteropFunctorDrawable.cpp",
-        "renderstate/RenderState.cpp",
-        "renderthread/CacheManager.cpp",
-        "renderthread/CanvasContext.cpp",
-        "renderthread/DrawFrameTask.cpp",
-        "renderthread/EglManager.cpp",
-        "renderthread/ReliableSurface.cpp",
-        "renderthread/VulkanManager.cpp",
-        "renderthread/VulkanSurface.cpp",
-        "renderthread/RenderProxy.cpp",
-        "renderthread/RenderTask.cpp",
-        "renderthread/RenderThread.cpp",
-        "renderthread/TimeLord.cpp",
-        "renderthread/Frame.cpp",
-        "service/GraphicsStatsService.cpp",
-        "surfacetexture/EGLConsumer.cpp",
-        "surfacetexture/ImageConsumer.cpp",
-        "surfacetexture/SurfaceTexture.cpp",
-        "thread/CommonPool.cpp",
         "utils/Blur.cpp",
         "utils/Color.cpp",
-        "utils/GLUtils.cpp",
         "utils/LinearAllocator.cpp",
-        "utils/StringUtils.cpp",
         "utils/VectorDrawableUtils.cpp",
         "AnimationContext.cpp",
         "Animator.cpp",
         "AnimatorManager.cpp",
         "CanvasTransform.cpp",
         "DamageAccumulator.cpp",
-        "DeferredLayerUpdater.cpp",
-        "DeviceInfo.cpp",
-        "FrameInfo.cpp",
-        "FrameInfoVisualizer.cpp",
-        "GpuMemoryTracker.cpp",
-        "HardwareBitmapUploader.cpp",
-        "HWUIProperties.sysprop",
         "Interpolator.cpp",
-        "JankTracker.cpp",
-        "Layer.cpp",
-        "LayerUpdateQueue.cpp",
+        "LightingInfo.cpp",
         "Matrix.cpp",
         "PathParser.cpp",
-        "ProfileData.cpp",
-        "ProfileDataContainer.cpp",
         "Properties.cpp",
         "PropertyValuesAnimatorSet.cpp",
         "PropertyValuesHolder.cpp",
-        "Readback.cpp",
         "RecordingCanvas.cpp",
         "RenderNode.cpp",
         "RenderProperties.cpp",
+        "RootRenderNode.cpp",
         "SkiaCanvas.cpp",
-        "TreeInfo.cpp",
-        "WebViewFunctorManager.cpp",
         "VectorDrawable.cpp",
-        "protos/graphicsstats.proto",
     ],
 
-    // Allow implicit fallthroughs in HardwareBitmapUploader.cpp until they are fixed.
-    cflags: ["-Wno-implicit-fallthrough"],
-
     proto: {
         export_proto_headers: true,
     },
 
     export_include_dirs: ["."],
+
+    target: {
+        android: {
+
+            srcs: [
+                "pipeline/skia/GLFunctorDrawable.cpp",
+                "pipeline/skia/LayerDrawable.cpp",
+                "pipeline/skia/ShaderCache.cpp",
+                "pipeline/skia/SkiaMemoryTracer.cpp",
+                "pipeline/skia/SkiaOpenGLPipeline.cpp",
+                "pipeline/skia/SkiaPipeline.cpp",
+                "pipeline/skia/SkiaProfileRenderer.cpp",
+                "pipeline/skia/SkiaVulkanPipeline.cpp",
+                "pipeline/skia/VectorDrawableAtlas.cpp",
+                "pipeline/skia/VkFunctorDrawable.cpp",
+                "pipeline/skia/VkInteropFunctorDrawable.cpp",
+                "renderstate/RenderState.cpp",
+                "renderthread/CacheManager.cpp",
+                "renderthread/CanvasContext.cpp",
+                "renderthread/DrawFrameTask.cpp",
+                "renderthread/EglManager.cpp",
+                "renderthread/ReliableSurface.cpp",
+                "renderthread/VulkanManager.cpp",
+                "renderthread/VulkanSurface.cpp",
+                "renderthread/RenderProxy.cpp",
+                "renderthread/RenderThread.cpp",
+                "service/GraphicsStatsService.cpp",
+                "surfacetexture/EGLConsumer.cpp",
+                "surfacetexture/ImageConsumer.cpp",
+                "surfacetexture/SurfaceTexture.cpp",
+                "thread/CommonPool.cpp",
+                "utils/GLUtils.cpp",
+                "utils/StringUtils.cpp",
+                "DeferredLayerUpdater.cpp",
+                "DeviceInfo.cpp",
+                "FrameInfo.cpp",
+                "FrameInfoVisualizer.cpp",
+                "GpuMemoryTracker.cpp",
+                "HardwareBitmapUploader.cpp",
+                "HWUIProperties.sysprop",
+                "JankTracker.cpp",
+                "Layer.cpp",
+                "LayerUpdateQueue.cpp",
+                "ProfileData.cpp",
+                "ProfileDataContainer.cpp",
+                "Readback.cpp",
+                "TreeInfo.cpp",
+                "WebViewFunctorManager.cpp",
+                "protos/graphicsstats.proto",
+            ],
+
+            // Allow implicit fallthroughs in HardwareBitmapUploader.cpp until they are fixed.
+            cflags: ["-Wno-implicit-fallthrough"],
+        },
+        host: {
+            srcs: [
+                "utils/HostColorSpace.cpp",
+            ],
+            export_static_lib_headers: [
+                "libarect",
+            ],
+        }
+    }
 }
 
 cc_library {
     name: "libhwui",
+    host_supported: true,
     defaults: [
         "libhwui_defaults",
-
-        // Enables fine-grained GLES error checking
-        // If enabled, every GLES call is wrapped & error checked
-        // Has moderate overhead
-        //"hwui_enable_opengl_validation",
     ],
 }
 
-// ------------------------
-// static library null gpu
-// ------------------------
-
 cc_library_static {
-    name: "libhwui_static_debug",
+    name: "libhwui_static",
     defaults: [
         "libhwui_defaults",
-        "hwui_debug",
-    ],
-    cflags: ["-DHWUI_NULL_GPU"],
-    srcs: [
-        "debug/nullegl.cpp",
     ],
 }
 
@@ -296,15 +309,11 @@
 
     static_libs: [
         "libgmock",
-        "libhwui_static_debug",
+        "libhwui_static",
     ],
     shared_libs: [
         "libmemunreachable",
     ],
-    cflags: [
-        "-include debug/wrap_gles.h",
-        "-DHWUI_NULL_GPU",
-    ],
 
     srcs: [
         "tests/unit/main.cpp",
@@ -348,8 +357,7 @@
     name: "hwuimacro",
     defaults: ["hwui_test_defaults"],
 
-    // set to libhwui_static_debug to skip actual GL commands
-    whole_static_libs: ["libhwui"],
+    static_libs: ["libhwui"],
     shared_libs: [
         "libmemunreachable",
     ],
@@ -368,12 +376,7 @@
     name: "hwuimicro",
     defaults: ["hwui_test_defaults"],
 
-    cflags: [
-        "-include debug/wrap_gles.h",
-        "-DHWUI_NULL_GPU",
-    ],
-
-    whole_static_libs: ["libhwui_static_debug"],
+    static_libs: ["libhwui_static"],
     shared_libs: [
         "libmemunreachable",
     ],
@@ -398,59 +401,3 @@
         "hwuimacro",
     ]
 }
-
-cc_library_host_shared {
-    name: "libhwui-host",
-
-    defaults: [
-        "skia_deps",
-    ],
-    whole_static_libs: ["libskia"],
-
-    srcs: [
-        "hwui/AnimatedImageDrawable.cpp",
-        "hwui/AnimatedImageThread.cpp",
-        "hwui/Bitmap.cpp",
-        "hwui/Canvas.cpp",
-        "hwui/Typeface.cpp",
-        "hwui/MinikinSkia.cpp",
-        "hwui/MinikinUtils.cpp",
-        "hwui/PaintImpl.cpp",
-        "utils/Blur.cpp",
-        "utils/LinearAllocator.cpp",
-        "utils/VectorDrawableUtils.cpp",
-        "Animator.cpp",
-        "Interpolator.cpp",
-        "Matrix.cpp",
-        "PathParser.cpp",
-        "Properties.cpp",
-        "PropertyValuesAnimatorSet.cpp",
-        "PropertyValuesHolder.cpp",
-        "SkiaCanvas.cpp",
-        "VectorDrawable.cpp",
-    ],
-    include_dirs: [
-        "external/skia/include/private",
-        "external/skia/src/core",
-        "external/vulkan-headers/include",
-        "system/core/base/include",
-    ],
-    cpp_std: "experimental",
-    cflags: [
-        "-Wno-unused-parameter",
-        "-Wno-unused-variable",
-    ],
-    shared_libs: [
-        "libbase",
-        "libharfbuzz_ng",
-        "libminikin",
-    ],
-    static_libs: [
-        "libandroidfw",
-        "libutils",
-    ],
-    export_include_dirs: ["."],
-    export_static_lib_headers: [
-        "libarect",
-    ],
-}
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 93b9dec..74cf1fd 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -155,11 +155,9 @@
         RenderNode* oldTarget = mTarget;
         mTarget = mStagingTarget;
         mStagingTarget = nullptr;
-#ifdef __ANDROID__ // Layoutlib does not support RenderNode
         if (oldTarget && oldTarget != mTarget) {
             oldTarget->onAnimatorTargetChanged(this);
         }
-#endif
     }
 
     if (!mHasStartValue) {
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index cca0032..2d2df52 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -137,20 +137,28 @@
     mapRect(frame->matrix4, frame->pendingDirty, &mHead->pendingDirty);
 }
 
-static inline void mapRect(const RenderProperties& props, const SkRect& in, SkRect* out) {
-    if (in.isEmpty()) return;
-    const SkMatrix* transform = props.getTransformMatrix();
-    SkRect temp(in);
+static inline void applyMatrix(const SkMatrix* transform, SkRect* rect) {
     if (transform && !transform->isIdentity()) {
         if (CC_LIKELY(!transform->hasPerspective())) {
-            transform->mapRect(&temp);
+            transform->mapRect(rect);
         } else {
             // Don't attempt to calculate damage for a perspective transform
             // as the numbers this works with can break the perspective
             // calculations. Just give up and expand to DIRTY_MIN/DIRTY_MAX
-            temp.set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
+            rect->set(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX);
         }
     }
+}
+
+static inline void mapRect(const RenderProperties& props, const SkRect& in, SkRect* out) {
+    if (in.isEmpty()) return;
+    SkRect temp(in);
+    applyMatrix(props.getTransformMatrix(), &temp);
+    if (props.getStaticMatrix()) {
+        applyMatrix(props.getStaticMatrix(), &temp);
+    } else if (props.getAnimationMatrix()) {
+        applyMatrix(props.getAnimationMatrix(), &temp);
+    }
     temp.offset(props.getLeft(), props.getTop());
     out->join(temp);
 }
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 3bee301..f300703 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -15,6 +15,9 @@
  */
 #include "DeferredLayerUpdater.h"
 
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
 #include "renderstate/RenderState.h"
 #include "utils/PaintUtils.h"
 
@@ -38,6 +41,16 @@
     destroyLayer();
 }
 
+void DeferredLayerUpdater::setSurfaceTexture(const sp<SurfaceTexture>& consumer) {
+    if (consumer.get() != mSurfaceTexture.get()) {
+        mSurfaceTexture = consumer;
+
+        GLenum target = consumer->getCurrentTextureTarget();
+        LOG_ALWAYS_FATAL_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES,
+                            "set unsupported SurfaceTexture with target %x", target);
+    }
+}
+
 void DeferredLayerUpdater::onContextDestroyed() {
     destroyLayer();
 }
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index a91c111..1491f99 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -24,9 +24,6 @@
 #include <system/graphics.h>
 #include <utils/StrongPointer.h>
 
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
 #include "renderstate/RenderState.h"
 #include "surfacetexture/SurfaceTexture.h"
 #include "Layer.h"
@@ -67,15 +64,7 @@
         return false;
     }
 
-    ANDROID_API void setSurfaceTexture(const sp<SurfaceTexture>& consumer) {
-        if (consumer.get() != mSurfaceTexture.get()) {
-            mSurfaceTexture = consumer;
-
-            GLenum target = consumer->getCurrentTextureTarget();
-            LOG_ALWAYS_FATAL_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES,
-                                "set unsupported SurfaceTexture with target %x", target);
-        }
-    }
+    ANDROID_API void setSurfaceTexture(const sp<SurfaceTexture>& consumer);
 
     ANDROID_API void updateTexImage() { mUpdateTexImage = true; }
 
diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h
index 0aab58c..b75192f 100644
--- a/libs/hwui/FrameInfo.h
+++ b/libs/hwui/FrameInfo.h
@@ -100,15 +100,15 @@
 public:
     void importUiThreadInfo(int64_t* info);
 
-    void markSyncStart() { set(FrameInfoIndex::SyncStart) = systemTime(CLOCK_MONOTONIC); }
+    void markSyncStart() { set(FrameInfoIndex::SyncStart) = systemTime(SYSTEM_TIME_MONOTONIC); }
 
     void markIssueDrawCommandsStart() {
-        set(FrameInfoIndex::IssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC);
+        set(FrameInfoIndex::IssueDrawCommandsStart) = systemTime(SYSTEM_TIME_MONOTONIC);
     }
 
-    void markSwapBuffers() { set(FrameInfoIndex::SwapBuffers) = systemTime(CLOCK_MONOTONIC); }
+    void markSwapBuffers() { set(FrameInfoIndex::SwapBuffers) = systemTime(SYSTEM_TIME_MONOTONIC); }
 
-    void markFrameCompleted() { set(FrameInfoIndex::FrameCompleted) = systemTime(CLOCK_MONOTONIC); }
+    void markFrameCompleted() { set(FrameInfoIndex::FrameCompleted) = systemTime(SYSTEM_TIME_MONOTONIC); }
 
     void addFlag(int frameInfoFlag) {
         set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag);
diff --git a/libs/hwui/LightingInfo.cpp b/libs/hwui/LightingInfo.cpp
new file mode 100644
index 0000000..83bb255
--- /dev/null
+++ b/libs/hwui/LightingInfo.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "LightingInfo.h"
+
+#include <float.h>
+
+namespace android {
+namespace uirenderer {
+
+float LightingInfo::mLightRadius = 0;
+uint8_t LightingInfo::mAmbientShadowAlpha = 0;
+uint8_t LightingInfo::mSpotShadowAlpha = 0;
+
+Vector3 LightingInfo::mLightCenter = {FLT_MIN, FLT_MIN, FLT_MIN};
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/LightingInfo.h b/libs/hwui/LightingInfo.h
new file mode 100644
index 0000000..3112eb3
--- /dev/null
+++ b/libs/hwui/LightingInfo.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "Lighting.h"
+#include "Properties.h"
+
+namespace android {
+namespace uirenderer {
+
+class LightingInfo {
+public:
+
+    static float getLightRadius() {
+        if (CC_UNLIKELY(Properties::overrideLightRadius > 0)) {
+            return Properties::overrideLightRadius;
+        }
+        return mLightRadius;
+    }
+
+    static uint8_t getAmbientShadowAlpha() {
+        if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
+            return Properties::overrideAmbientShadowStrength;
+        }
+        return mAmbientShadowAlpha;
+    }
+
+    static uint8_t getSpotShadowAlpha() {
+        if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
+            return Properties::overrideSpotShadowStrength;
+        }
+        return mSpotShadowAlpha;
+    }
+
+    static Vector3 getLightCenter() {
+        if (CC_UNLIKELY(Properties::overrideLightPosY > 0 || Properties::overrideLightPosZ > 0)) {
+            Vector3 adjustedLightCenter = mLightCenter;
+            if (CC_UNLIKELY(Properties::overrideLightPosY > 0)) {
+                // negated since this shifts up
+                adjustedLightCenter.y = -Properties::overrideLightPosY;
+            }
+            if (CC_UNLIKELY(Properties::overrideLightPosZ > 0)) {
+                adjustedLightCenter.z = Properties::overrideLightPosZ;
+            }
+            return adjustedLightCenter;
+        }
+        return mLightCenter;
+    }
+
+    static Vector3 getLightCenterRaw() {
+        return mLightCenter;
+    }
+
+    static void setLightCenterRaw(const Vector3& lightCenter) {
+        mLightCenter = lightCenter;
+    }
+
+    static void updateLighting(const LightGeometry& lightGeometry, const LightInfo& lightInfo) {
+        mLightRadius = lightGeometry.radius;
+        mAmbientShadowAlpha = lightInfo.ambientShadowAlpha;
+        mSpotShadowAlpha = lightInfo.spotShadowAlpha;
+        mLightCenter = lightGeometry.center;
+    }
+private:
+    static float mLightRadius;
+    static uint8_t mAmbientShadowAlpha;
+    static uint8_t mSpotShadowAlpha;
+    static Vector3 mLightCenter;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/ProfileData.cpp b/libs/hwui/ProfileData.cpp
index 70ca4e3..c7f9232 100644
--- a/libs/hwui/ProfileData.cpp
+++ b/libs/hwui/ProfileData.cpp
@@ -143,7 +143,7 @@
     mSlowFrameCounts.fill(0);
     mTotalFrameCount = 0;
     mJankFrameCount = 0;
-    mStatStartTime = systemTime(CLOCK_MONOTONIC);
+    mStatStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
 }
 
 void ProfileData::reportFrame(int64_t duration) {
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 1253beb..4e7df88 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -191,14 +191,14 @@
 }
 
 void Properties::overrideRenderPipelineType(RenderPipelineType type) {
-#if !defined(HWUI_GLES_WRAP_ENABLED)
     // If we're doing actual rendering then we can't change the renderer after it's been set.
     // Unit tests can freely change this as often as it wants, though, as there's no actual
     // GL rendering happening
     if (sRenderPipelineType != RenderPipelineType::NotInitialized) {
+        LOG_ALWAYS_FATAL_IF(sRenderPipelineType != type,
+                "Trying to change pipeline but it's already set");
         return;
     }
-#endif
     sRenderPipelineType = type;
 }
 
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index e58fbbe..c8eb1ca 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -274,7 +274,12 @@
     }
     sk_sp<SkDrawable> drawable;
     SkMatrix matrix = SkMatrix::I();
-    void draw(SkCanvas* c, const SkMatrix&) const { c->drawDrawable(drawable.get(), &matrix); }
+    // It is important that we call drawable->draw(c) here instead of c->drawDrawable(drawable).
+    // Drawables are mutable and in cases, like RenderNodeDrawable, are not expected to produce the
+    // same content if retained outside the duration of the frame. Therefore we resolve
+    // them now and do not allow the canvas to take a reference to the drawable and potentially
+    // keep it alive for longer than the frames duration (e.g. SKP serialization).
+    void draw(SkCanvas* c, const SkMatrix&) const { drawable->draw(c, &matrix); }
 };
 struct DrawPicture final : Op {
     static const auto kType = Type::DrawPicture;
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 7269bca..16ec877 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -29,7 +29,6 @@
 #include "SkPaint.h"
 #include "SkPath.h"
 #include "SkRect.h"
-#include "SkTDArray.h"
 #include "SkTemplates.h"
 
 #include <vector>
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index e0ed3e4..8aee8f5 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -20,8 +20,12 @@
 #include "Debug.h"
 #include "TreeInfo.h"
 #include "VectorDrawable.h"
-#include "renderstate/RenderState.h"
+#ifdef __ANDROID__
 #include "renderthread/CanvasContext.h"
+#else
+#include "DamageAccumulator.h"
+#include "pipeline/skia/SkiaDisplayList.h"
+#endif
 #include "utils/FatVector.h"
 #include "utils/MathUtils.h"
 #include "utils/StringUtils.h"
@@ -161,6 +165,7 @@
 }
 
 void RenderNode::pushLayerUpdate(TreeInfo& info) {
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext and Layers
     LayerType layerType = properties().effectiveLayerType();
     // If we are not a layer OR we cannot be rendered (eg, view was detached)
     // we need to destroy any Layers we may have had previously
@@ -189,6 +194,7 @@
     // That might be us, so tell CanvasContext that this layer is in the
     // tree and should not be destroyed.
     info.canvasContext.markLayerInUse(this);
+#endif
 }
 
 /**
@@ -264,6 +270,12 @@
 }
 
 void RenderNode::pushStagingPropertiesChanges(TreeInfo& info) {
+    if (mPositionListenerDirty) {
+        mPositionListener = std::move(mStagingPositionListener);
+        mStagingPositionListener = nullptr;
+        mPositionListenerDirty = false;
+    }
+
     // Push the animators first so that setupStartValueIfNecessary() is called
     // before properties() is trampled by stagingProperties(), as they are
     // required by some animators.
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 23e7a0e..c6db7f1 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -188,11 +188,9 @@
         virtual void onPositionLost(RenderNode& node, const TreeInfo* info) = 0;
     };
 
-    // Note this is not thread safe, this needs to be called
-    // before the RenderNode is used for drawing.
-    // RenderNode takes ownership of the pointer
     ANDROID_API void setPositionListener(PositionListener* listener) {
-        mPositionListener = listener;
+        mStagingPositionListener = listener;
+        mPositionListenerDirty = true;
     }
 
     // This is only modified in MODE_FULL, so it can be safely accessed
@@ -275,6 +273,8 @@
     // mDisplayList, not mStagingDisplayList.
     uint32_t mParentCount;
 
+    bool mPositionListenerDirty = false;
+    sp<PositionListener> mStagingPositionListener;
     sp<PositionListener> mPositionListener;
 
     UsageHint mUsageHint = UsageHint::Unknown;
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index e6710cc..e979448 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -526,9 +526,13 @@
     }
 
     bool fitsOnLayer() const {
+#ifdef __ANDROID__ // Layoutlib does not support device info
         const DeviceInfo* deviceInfo = DeviceInfo::get();
         return mPrimitiveFields.mWidth <= deviceInfo->maxTextureSize() &&
                mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize();
+#else
+        return mPrimitiveFields.mWidth <= 4096 && mPrimitiveFields.mHeight <= 4096;
+#endif
     }
 
     bool promotedToLayer() const {
diff --git a/libs/hwui/RootRenderNode.cpp b/libs/hwui/RootRenderNode.cpp
new file mode 100644
index 0000000..ddbbf58
--- /dev/null
+++ b/libs/hwui/RootRenderNode.cpp
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "RootRenderNode.h"
+
+#ifdef __ANDROID__ // Layoutlib does not support Looper (windows)
+#include <utils/Looper.h>
+#endif
+
+namespace android::uirenderer {
+
+#ifdef __ANDROID__ // Layoutlib does not support Looper
+class FinishAndInvokeListener : public MessageHandler {
+public:
+    explicit FinishAndInvokeListener(PropertyValuesAnimatorSet* anim) : mAnimator(anim) {
+        mListener = anim->getOneShotListener();
+        mRequestId = anim->getRequestId();
+    }
+
+    virtual void handleMessage(const Message& message) {
+        if (mAnimator->getRequestId() == mRequestId) {
+            // Request Id has not changed, meaning there's no animation lifecyle change since the
+            // message is posted, so go ahead and call finish to make sure the PlayState is properly
+            // updated. This is needed because before the next frame comes in from UI thread to
+            // trigger an animation update, there could be reverse/cancel etc. So we need to update
+            // the playstate in time to ensure all the subsequent events get chained properly.
+            mAnimator->end();
+        }
+        mListener->onAnimationFinished(nullptr);
+    }
+
+private:
+    sp<PropertyValuesAnimatorSet> mAnimator;
+    sp<AnimationListener> mListener;
+    uint32_t mRequestId;
+};
+
+void RootRenderNode::prepareTree(TreeInfo& info) {
+    info.errorHandler = mErrorHandler.get();
+
+    for (auto& anim : mRunningVDAnimators) {
+        // Assume that the property change in VD from the animators will not be consumed. Mark
+        // otherwise if the VDs are found in the display list tree. For VDs that are not in
+        // the display list tree, we stop providing animation pulses by 1) removing them from
+        // the animation list, 2) post a delayed message to end them at end time so their
+        // listeners can receive the corresponding callbacks.
+        anim->getVectorDrawable()->setPropertyChangeWillBeConsumed(false);
+        // Mark the VD dirty so it will damage itself during prepareTree.
+        anim->getVectorDrawable()->markDirty();
+    }
+    if (info.mode == TreeInfo::MODE_FULL) {
+        for (auto& anim : mPausedVDAnimators) {
+            anim->getVectorDrawable()->setPropertyChangeWillBeConsumed(false);
+            anim->getVectorDrawable()->markDirty();
+        }
+    }
+    // TODO: This is hacky
+    info.updateWindowPositions = true;
+    RenderNode::prepareTree(info);
+    info.updateWindowPositions = false;
+    info.errorHandler = nullptr;
+}
+
+void RootRenderNode::attachAnimatingNode(RenderNode* animatingNode) {
+    mPendingAnimatingRenderNodes.push_back(animatingNode);
+}
+
+void RootRenderNode::attachPendingVectorDrawableAnimators() {
+    mRunningVDAnimators.insert(mPendingVectorDrawableAnimators.begin(),
+                               mPendingVectorDrawableAnimators.end());
+    mPendingVectorDrawableAnimators.clear();
+}
+
+void RootRenderNode::detachAnimators() {
+    // Remove animators from the list and post a delayed message in future to end the animator
+    // For infinite animators, remove the listener so we no longer hold a global ref to the AVD
+    // java object, and therefore the AVD objects in both native and Java can be properly
+    // released.
+    for (auto& anim : mRunningVDAnimators) {
+        detachVectorDrawableAnimator(anim.get());
+        anim->clearOneShotListener();
+    }
+    for (auto& anim : mPausedVDAnimators) {
+        anim->clearOneShotListener();
+    }
+    mRunningVDAnimators.clear();
+    mPausedVDAnimators.clear();
+}
+
+// Move all the animators to the paused list, and send a delayed message to notify the finished
+// listener.
+void RootRenderNode::pauseAnimators() {
+    mPausedVDAnimators.insert(mRunningVDAnimators.begin(), mRunningVDAnimators.end());
+    for (auto& anim : mRunningVDAnimators) {
+        detachVectorDrawableAnimator(anim.get());
+    }
+    mRunningVDAnimators.clear();
+}
+
+void RootRenderNode::doAttachAnimatingNodes(AnimationContext* context) {
+    for (size_t i = 0; i < mPendingAnimatingRenderNodes.size(); i++) {
+        RenderNode* node = mPendingAnimatingRenderNodes[i].get();
+        context->addAnimatingRenderNode(*node);
+    }
+    mPendingAnimatingRenderNodes.clear();
+}
+
+// Run VectorDrawable animators after prepareTree.
+void RootRenderNode::runVectorDrawableAnimators(AnimationContext* context, TreeInfo& info) {
+    // Push staging.
+    if (info.mode == TreeInfo::MODE_FULL) {
+        pushStagingVectorDrawableAnimators(context);
+    }
+
+    // Run the animators in the running list.
+    for (auto it = mRunningVDAnimators.begin(); it != mRunningVDAnimators.end();) {
+        if ((*it)->animate(*context)) {
+            it = mRunningVDAnimators.erase(it);
+        } else {
+            it++;
+        }
+    }
+
+    // Run the animators in paused list during full sync.
+    if (info.mode == TreeInfo::MODE_FULL) {
+        // During full sync we also need to pulse paused animators, in case their targets
+        // have been added back to the display list. All the animators that passed the
+        // scheduled finish time will be removed from the paused list.
+        for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
+            if ((*it)->animate(*context)) {
+                // Animator has finished, remove from the list.
+                it = mPausedVDAnimators.erase(it);
+            } else {
+                it++;
+            }
+        }
+    }
+
+    // Move the animators with a target not in DisplayList to paused list.
+    for (auto it = mRunningVDAnimators.begin(); it != mRunningVDAnimators.end();) {
+        if (!(*it)->getVectorDrawable()->getPropertyChangeWillBeConsumed()) {
+            // Vector Drawable is not in the display list, we should remove this animator from
+            // the list, put it in the paused list, and post a delayed message to end the
+            // animator.
+            detachVectorDrawableAnimator(it->get());
+            mPausedVDAnimators.insert(*it);
+            it = mRunningVDAnimators.erase(it);
+        } else {
+            it++;
+        }
+    }
+
+    // Move the animators with a target in DisplayList from paused list to running list, and
+    // trim paused list.
+    if (info.mode == TreeInfo::MODE_FULL) {
+        // Check whether any paused animator's target is back in Display List. If so, put the
+        // animator back in the running list.
+        for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
+            if ((*it)->getVectorDrawable()->getPropertyChangeWillBeConsumed()) {
+                mRunningVDAnimators.insert(*it);
+                it = mPausedVDAnimators.erase(it);
+            } else {
+                it++;
+            }
+        }
+        // Trim paused VD animators at full sync, so that when Java loses reference to an
+        // animator, we know we won't be requested to animate it any more, then we remove such
+        // animators from the paused list so they can be properly freed. We also remove the
+        // animators from paused list when the time elapsed since start has exceeded duration.
+        trimPausedVDAnimators(context);
+    }
+
+    info.out.hasAnimations |= !mRunningVDAnimators.empty();
+}
+
+void RootRenderNode::trimPausedVDAnimators(AnimationContext* context) {
+    // Trim paused vector drawable animator list.
+    for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
+        // Remove paused VD animator if no one else is referencing it. Note that animators that
+        // have passed scheduled finish time are removed from list when they are being pulsed
+        // before prepare tree.
+        // TODO: this is a bit hacky, need to figure out a better way to track when the paused
+        // animators should be freed.
+        if ((*it)->getStrongCount() == 1) {
+            it = mPausedVDAnimators.erase(it);
+        } else {
+            it++;
+        }
+    }
+}
+
+void RootRenderNode::pushStagingVectorDrawableAnimators(AnimationContext* context) {
+    for (auto& anim : mRunningVDAnimators) {
+        anim->pushStaging(*context);
+    }
+}
+
+void RootRenderNode::destroy() {
+    for (auto& renderNode : mPendingAnimatingRenderNodes) {
+        renderNode->animators().endAllStagingAnimators();
+    }
+    mPendingAnimatingRenderNodes.clear();
+    mPendingVectorDrawableAnimators.clear();
+}
+
+void RootRenderNode::addVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) {
+    mPendingVectorDrawableAnimators.insert(anim);
+}
+
+void RootRenderNode::detachVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) {
+    if (anim->isInfinite() || !anim->isRunning()) {
+        // Do not need to post anything if the animation is infinite (i.e. no meaningful
+        // end listener action), or if the animation has already ended.
+        return;
+    }
+    nsecs_t remainingTimeInMs = anim->getRemainingPlayTime();
+    // Post a delayed onFinished event that is scheduled to be handled when the animator ends.
+    if (anim->getOneShotListener()) {
+        // VectorDrawable's oneshot listener is updated when there are user triggered animation
+        // lifecycle changes, such as start(), end(), etc. By using checking and clearing
+        // one shot listener, we ensure the same end listener event gets posted only once.
+        // Therefore no duplicates. Another benefit of using one shot listener is that no
+        // removal is necessary: the end time of animation will not change unless triggered by
+        // user events, in which case the already posted listener's id will become stale, and
+        // the onFinished callback will then be ignored.
+        sp<FinishAndInvokeListener> message = new FinishAndInvokeListener(anim);
+        auto looper = Looper::getForThread();
+        LOG_ALWAYS_FATAL_IF(looper == nullptr, "Not on a looper thread?");
+        looper->sendMessageDelayed(ms2ns(remainingTimeInMs), message, 0);
+        anim->clearOneShotListener();
+    }
+}
+
+class AnimationContextBridge : public AnimationContext {
+public:
+    AnimationContextBridge(renderthread::TimeLord& clock, RootRenderNode* rootNode)
+            : AnimationContext(clock), mRootNode(rootNode) {}
+
+    virtual ~AnimationContextBridge() {}
+
+    // Marks the start of a frame, which will update the frame time and move all
+    // next frame animations into the current frame
+    virtual void startFrame(TreeInfo::TraversalMode mode) {
+        if (mode == TreeInfo::MODE_FULL) {
+            mRootNode->doAttachAnimatingNodes(this);
+            mRootNode->attachPendingVectorDrawableAnimators();
+        }
+        AnimationContext::startFrame(mode);
+    }
+
+    // Runs any animations still left in mCurrentFrameAnimations
+    virtual void runRemainingAnimations(TreeInfo& info) {
+        AnimationContext::runRemainingAnimations(info);
+        mRootNode->runVectorDrawableAnimators(this, info);
+    }
+
+    virtual void pauseAnimators() override { mRootNode->pauseAnimators(); }
+
+    virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) {
+        listener->onAnimationFinished(animator);
+    }
+
+    virtual void destroy() {
+        AnimationContext::destroy();
+        mRootNode->detachAnimators();
+    }
+
+private:
+    sp<RootRenderNode> mRootNode;
+};
+
+AnimationContext* ContextFactoryImpl::createAnimationContext(renderthread::TimeLord& clock) {
+    return new AnimationContextBridge(clock, mRootNode);
+}
+#else
+
+void RootRenderNode::prepareTree(TreeInfo& info) {
+    info.errorHandler = mErrorHandler.get();
+    info.updateWindowPositions = true;
+    RenderNode::prepareTree(info);
+    info.updateWindowPositions = false;
+    info.errorHandler = nullptr;
+}
+
+void RootRenderNode::attachAnimatingNode(RenderNode* animatingNode) { }
+
+void RootRenderNode::destroy() { }
+
+void RootRenderNode::addVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) { }
+
+#endif
+
+}  // namespace android::uirenderer
diff --git a/libs/hwui/RootRenderNode.h b/libs/hwui/RootRenderNode.h
new file mode 100644
index 0000000..12de4ec
--- /dev/null
+++ b/libs/hwui/RootRenderNode.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <set>
+#include <vector>
+
+#include "AnimationContext.h"
+#include "Animator.h"
+#include <IContextFactory.h>
+#include "PropertyValuesAnimatorSet.h"
+#include "RenderNode.h"
+
+namespace android::uirenderer {
+
+class ANDROID_API RootRenderNode : public RenderNode {
+public:
+    ANDROID_API explicit RootRenderNode(std::unique_ptr<ErrorHandler> errorHandler)
+            : RenderNode(), mErrorHandler(std::move(errorHandler)) {}
+
+    ANDROID_API virtual ~RootRenderNode() {}
+
+    virtual void prepareTree(TreeInfo& info) override;
+
+    ANDROID_API void attachAnimatingNode(RenderNode* animatingNode);
+
+    void attachPendingVectorDrawableAnimators();
+
+    void detachAnimators();
+
+    void pauseAnimators();
+
+    void doAttachAnimatingNodes(AnimationContext* context);
+
+    // Run VectorDrawable animators after prepareTree.
+    void runVectorDrawableAnimators(AnimationContext* context, TreeInfo& info);
+
+    void trimPausedVDAnimators(AnimationContext* context);
+
+    void pushStagingVectorDrawableAnimators(AnimationContext* context);
+
+    ANDROID_API void destroy();
+
+    ANDROID_API void addVectorDrawableAnimator(PropertyValuesAnimatorSet* anim);
+
+private:
+    const std::unique_ptr<ErrorHandler> mErrorHandler;
+    std::vector<sp<RenderNode> > mPendingAnimatingRenderNodes;
+    std::set<sp<PropertyValuesAnimatorSet> > mPendingVectorDrawableAnimators;
+    std::set<sp<PropertyValuesAnimatorSet> > mRunningVDAnimators;
+    // mPausedVDAnimators stores a list of animators that have not yet passed the finish time, but
+    // their VectorDrawable targets are no longer in the DisplayList. We skip these animators when
+    // render thread runs animators independent of UI thread (i.e. RT_ONLY mode). These animators
+    // need to be re-activated once their VD target is added back into DisplayList. Since that could
+    // only happen when we do a full sync, we need to make sure to pulse these paused animators at
+    // full sync. If any animator's VD target is found in DisplayList during a full sync, we move
+    // the animator back to the running list.
+    std::set<sp<PropertyValuesAnimatorSet> > mPausedVDAnimators;
+
+    void detachVectorDrawableAnimator(PropertyValuesAnimatorSet* anim);
+};
+
+#ifdef __ANDROID__ // Layoutlib does not support Animations
+class ANDROID_API ContextFactoryImpl : public IContextFactory {
+public:
+    ANDROID_API explicit ContextFactoryImpl(RootRenderNode* rootNode) : mRootNode(rootNode) {}
+
+    ANDROID_API virtual AnimationContext* createAnimationContext(
+            renderthread::TimeLord& clock) override;
+
+private:
+    RootRenderNode* mRootNode;
+};
+#endif
+
+}  // namespace android::uirenderer
diff --git a/libs/hwui/TEST_MAPPING b/libs/hwui/TEST_MAPPING
index d9f2acb..b1719a9 100644
--- a/libs/hwui/TEST_MAPPING
+++ b/libs/hwui/TEST_MAPPING
@@ -1,13 +1,15 @@
 {
   "presubmit": [
     {
-      "name": "CtsUiRenderingTestCases"
-    },
-    {
       "name": "CtsGraphicsTestCases"
     },
     {
       "name": "CtsAccelerationTestCases"
     }
+  ],
+  "imports": [
+    {
+      "path": "cts/tests/tests/uirendering"
+    }
   ]
 }
\ No newline at end of file
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index 7e8d12f..f2481f8 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -40,7 +40,6 @@
 public:
     virtual void onError(const std::string& message) = 0;
 
-protected:
     virtual ~ErrorHandler() = default;
 };
 
diff --git a/libs/hwui/debug/DefaultGlesDriver.cpp b/libs/hwui/debug/DefaultGlesDriver.cpp
deleted file mode 100644
index 46ab200..0000000
--- a/libs/hwui/debug/DefaultGlesDriver.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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 "DefaultGlesDriver.h"
-
-#include "gles_undefine.h"
-
-#include <EGL/egl.h>
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-// Generate the proxy
-#define API_ENTRY(x) DefaultGlesDriver::x##_
-#define CALL_GL_API(x, ...) x(__VA_ARGS__);
-#define CALL_GL_API_RETURN(x, ...) return x(__VA_ARGS__);
-
-#include "gles_stubs.in"
-
-#undef API_ENTRY
-#undef CALL_GL_API
-#undef CALL_GL_API_RETURN
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/DefaultGlesDriver.h b/libs/hwui/debug/DefaultGlesDriver.h
deleted file mode 100644
index 8027ea2..0000000
--- a/libs/hwui/debug/DefaultGlesDriver.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "GlesDriver.h"
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-class DefaultGlesDriver : public GlesDriver {
-public:
-#define GL_ENTRY(ret, api, ...) virtual ret api##_(__VA_ARGS__) override;
-#include "gles_decls.in"
-#undef GL_ENTRY
-};
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/FatalBaseDriver.cpp b/libs/hwui/debug/FatalBaseDriver.cpp
deleted file mode 100644
index ed0f831..0000000
--- a/libs/hwui/debug/FatalBaseDriver.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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 "FatalBaseDriver.h"
-
-#include <log/log.h>
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-// Generate the proxy
-#define API_ENTRY(x) FatalBaseDriver::x##_
-#define CALL_GL_API(x, ...) LOG_ALWAYS_FATAL("Not Implemented");
-#define CALL_GL_API_RETURN(x, ...)       \
-    LOG_ALWAYS_FATAL("Not Implemented"); \
-    return static_cast<decltype(x(__VA_ARGS__))>(0);
-
-#include "gles_stubs.in"
-
-#undef API_ENTRY
-#undef CALL_GL_API
-#undef CALL_GL_API_RETURN
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/FatalBaseDriver.h b/libs/hwui/debug/FatalBaseDriver.h
deleted file mode 100644
index 45353d0..0000000
--- a/libs/hwui/debug/FatalBaseDriver.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "GlesDriver.h"
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-// A base driver that implements all the pure virtuals in the form of
-// LOG_ALWAYS_FATALS. Suitable for selective-override implementations
-// where only a known subset of methods need to be overridden
-class FatalBaseDriver : public GlesDriver {
-public:
-#define GL_ENTRY(ret, api, ...) virtual ret api##_(__VA_ARGS__) override;
-#include "gles_decls.in"
-#undef GL_ENTRY
-};
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/GlesDriver.cpp b/libs/hwui/debug/GlesDriver.cpp
deleted file mode 100644
index 98f06b0..0000000
--- a/libs/hwui/debug/GlesDriver.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 "GlesDriver.h"
-#include "DefaultGlesDriver.h"
-#include "GlesErrorCheckWrapper.h"
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-static DefaultGlesDriver sDefaultDriver;
-
-static std::unique_ptr<GlesDriver> sGlesDriver(new GlesErrorCheckWrapper(sDefaultDriver));
-
-GlesDriver* GlesDriver::get() {
-    return sGlesDriver.get();
-}
-
-std::unique_ptr<GlesDriver> GlesDriver::replace(std::unique_ptr<GlesDriver>&& driver) {
-    std::unique_ptr<GlesDriver> ret = std::move(sGlesDriver);
-    sGlesDriver = std::move(driver);
-    return ret;
-}
-
-sk_sp<const GrGLInterface> GlesDriver::getSkiaInterface() {
-    sk_sp<const GrGLInterface> skiaInterface(GrGLCreateNativeInterface());
-    return skiaInterface;
-}
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/GlesDriver.h b/libs/hwui/debug/GlesDriver.h
deleted file mode 100644
index 1c77c1a..0000000
--- a/libs/hwui/debug/GlesDriver.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#ifndef HWUI_GLES_WRAP_ENABLED
-#error Wrapping wasn't enabled, can't use this!
-#endif
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <GLES3/gl3.h>
-#include <GLES3/gl31.h>
-#include <GLES3/gl32.h>
-
-#include <gl/GrGLInterface.h>
-#include <memory>
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-// All the gl methods on GlesDriver have a trailing underscore
-// This is to avoid collision with gles_redefine/gles_undefine
-class GlesDriver {
-public:
-    virtual ~GlesDriver() {}
-    virtual sk_sp<const GrGLInterface> getSkiaInterface();
-
-#define GL_ENTRY(ret, api, ...) virtual ret api##_(__VA_ARGS__) = 0;
-#include "gles_decls.in"
-#undef GL_ENTRY
-
-    static GlesDriver* get();
-    static std::unique_ptr<GlesDriver> replace(std::unique_ptr<GlesDriver>&& driver);
-};
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/GlesErrorCheckWrapper.cpp b/libs/hwui/debug/GlesErrorCheckWrapper.cpp
deleted file mode 100644
index 8d11c19..0000000
--- a/libs/hwui/debug/GlesErrorCheckWrapper.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 "GlesErrorCheckWrapper.h"
-
-#include <log/log.h>
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-void GlesErrorCheckWrapper::assertNoErrors(const char* apicall) {
-    GLenum status = GL_NO_ERROR;
-    GLenum lastError = GL_NO_ERROR;
-    const char* lastErrorName = nullptr;
-    while ((status = mBase.glGetError_()) != GL_NO_ERROR) {
-        lastError = status;
-        switch (status) {
-            case GL_INVALID_ENUM:
-                ALOGE("GL error:  GL_INVALID_ENUM");
-                lastErrorName = "GL_INVALID_ENUM";
-                break;
-            case GL_INVALID_VALUE:
-                ALOGE("GL error:  GL_INVALID_VALUE");
-                lastErrorName = "GL_INVALID_VALUE";
-                break;
-            case GL_INVALID_OPERATION:
-                ALOGE("GL error:  GL_INVALID_OPERATION");
-                lastErrorName = "GL_INVALID_OPERATION";
-                break;
-            case GL_OUT_OF_MEMORY:
-                ALOGE("GL error:  Out of memory!");
-                lastErrorName = "GL_OUT_OF_MEMORY";
-                break;
-            default:
-                ALOGE("GL error: 0x%x", status);
-                lastErrorName = "UNKNOWN";
-        }
-    }
-    LOG_ALWAYS_FATAL_IF(lastError != GL_NO_ERROR, "%s error! %s (0x%x)", apicall, lastErrorName,
-                        lastError);
-}
-
-#define API_ENTRY(x) GlesErrorCheckWrapper::x##_
-#define CALL_GL_API(x, ...)  \
-    mBase.x##_(__VA_ARGS__); \
-    assertNoErrors(#x)
-
-#define CALL_GL_API_RETURN(x, ...)      \
-    auto ret = mBase.x##_(__VA_ARGS__); \
-    assertNoErrors(#x);                 \
-    return ret
-
-#include "gles_stubs.in"
-
-#undef API_ENTRY
-#undef CALL_GL_API
-#undef CALL_GL_API_RETURN
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/GlesErrorCheckWrapper.h b/libs/hwui/debug/GlesErrorCheckWrapper.h
deleted file mode 100644
index 791400b..0000000
--- a/libs/hwui/debug/GlesErrorCheckWrapper.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "GlesDriver.h"
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-class GlesErrorCheckWrapper : public GlesDriver {
-public:
-    explicit GlesErrorCheckWrapper(GlesDriver& base) : mBase(base) {}
-
-#define GL_ENTRY(ret, api, ...) virtual ret api##_(__VA_ARGS__) override;
-#include "gles_decls.in"
-#undef GL_ENTRY
-
-private:
-    void assertNoErrors(const char* apicall);
-
-    GlesDriver& mBase;
-};
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/MockGlesDriver.h b/libs/hwui/debug/MockGlesDriver.h
deleted file mode 100644
index e48ca19..0000000
--- a/libs/hwui/debug/MockGlesDriver.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "FatalBaseDriver.h"
-
-#include <gmock/gmock.h>
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-class MockGlesDriver : public FatalBaseDriver {
-public:
-    MOCK_METHOD2(glBindBuffer_, void(GLenum target, GLuint buffer));
-    MOCK_METHOD4(glBufferData_,
-                 void(GLenum target, GLsizeiptr size, const void* data, GLenum usage));
-    MOCK_METHOD2(glGenBuffers_, void(GLsizei n, GLuint* buffers));
-};
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/NullGlesDriver.cpp b/libs/hwui/debug/NullGlesDriver.cpp
deleted file mode 100644
index f27adf0..0000000
--- a/libs/hwui/debug/NullGlesDriver.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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 <debug/NullGlesDriver.h>
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-extern const GrGLInterface* CreateNullSkiaInterface();
-
-sk_sp<const GrGLInterface> NullGlesDriver::getSkiaInterface() {
-    sk_sp<const GrGLInterface> skiaInterface(CreateNullSkiaInterface());
-    return skiaInterface;
-}
-
-struct {
-    GLboolean scissorEnabled;
-} gState;
-
-static void nullglGenCommon(GLsizei n, GLuint* buffers) {
-    static GLuint nextId = 0;
-    int i;
-    for (i = 0; i < n; i++) {
-        buffers[i] = ++nextId;
-    }
-}
-
-void NullGlesDriver::glGenBuffers_(GLsizei n, GLuint* buffers) {
-    nullglGenCommon(n, buffers);
-}
-
-void NullGlesDriver::glGenFramebuffers_(GLsizei n, GLuint* framebuffers) {
-    nullglGenCommon(n, framebuffers);
-}
-
-void NullGlesDriver::glGenRenderbuffers_(GLsizei n, GLuint* renderbuffers) {
-    nullglGenCommon(n, renderbuffers);
-}
-
-void NullGlesDriver::glGenTextures_(GLsizei n, GLuint* textures) {
-    nullglGenCommon(n, textures);
-}
-
-GLuint NullGlesDriver::glCreateProgram_(void) {
-    static GLuint nextProgram = 0;
-    return ++nextProgram;
-}
-
-GLuint NullGlesDriver::glCreateShader_(GLenum type) {
-    static GLuint nextShader = 0;
-    return ++nextShader;
-}
-
-void NullGlesDriver::glGetProgramiv_(GLuint program, GLenum pname, GLint* params) {
-    switch (pname) {
-        case GL_DELETE_STATUS:
-        case GL_LINK_STATUS:
-        case GL_VALIDATE_STATUS:
-            *params = GL_TRUE;
-            break;
-        case GL_INFO_LOG_LENGTH:
-            *params = 16;
-            break;
-    }
-}
-
-void NullGlesDriver::glGetProgramInfoLog_(GLuint program, GLsizei bufSize, GLsizei* length,
-                                          GLchar* infoLog) {
-    *length = snprintf(infoLog, bufSize, "success");
-    if (*length >= bufSize) {
-        *length = bufSize - 1;
-    }
-}
-
-void NullGlesDriver::glGetShaderiv_(GLuint shader, GLenum pname, GLint* params) {
-    switch (pname) {
-        case GL_COMPILE_STATUS:
-        case GL_DELETE_STATUS:
-            *params = GL_TRUE;
-    }
-}
-
-void NullGlesDriver::glGetShaderInfoLog_(GLuint shader, GLsizei bufSize, GLsizei* length,
-                                         GLchar* infoLog) {
-    *length = snprintf(infoLog, bufSize, "success");
-    if (*length >= bufSize) {
-        *length = bufSize - 1;
-    }
-}
-
-void setBooleanState(GLenum cap, GLboolean value) {
-    switch (cap) {
-        case GL_SCISSOR_TEST:
-            gState.scissorEnabled = value;
-            break;
-    }
-}
-
-void NullGlesDriver::glEnable_(GLenum cap) {
-    setBooleanState(cap, GL_TRUE);
-}
-
-void NullGlesDriver::glDisable_(GLenum cap) {
-    setBooleanState(cap, GL_FALSE);
-}
-
-GLboolean NullGlesDriver::glIsEnabled_(GLenum cap) {
-    switch (cap) {
-        case GL_SCISSOR_TEST:
-            return gState.scissorEnabled;
-        default:
-            return GL_FALSE;
-    }
-}
-
-void NullGlesDriver::glGetIntegerv_(GLenum pname, GLint* data) {
-    switch (pname) {
-        case GL_MAX_TEXTURE_SIZE:
-            *data = 2048;
-            break;
-        case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
-            *data = 4;
-            break;
-        default:
-            *data = 0;
-    }
-}
-
-GLenum NullGlesDriver::glCheckFramebufferStatus_(GLenum target) {
-    switch (target) {
-        case GL_FRAMEBUFFER:
-            return GL_FRAMEBUFFER_COMPLETE;
-        default:
-            return 0;  // error case
-    }
-}
-
-static const char* getString(GLenum name) {
-    switch (name) {
-        case GL_VENDOR:
-            return "android";
-        case GL_RENDERER:
-            return "null";
-        case GL_VERSION:
-            return "OpenGL ES 2.0 rev1";
-        case GL_SHADING_LANGUAGE_VERSION:
-            return "OpenGL ES GLSL ES 2.0 rev1";
-        case GL_EXTENSIONS:
-        default:
-            return "";
-    }
-}
-
-const GLubyte* NullGlesDriver::glGetString_(GLenum name) {
-    return (GLubyte*)getString(name);
-}
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/NullGlesDriver.h b/libs/hwui/debug/NullGlesDriver.h
deleted file mode 100644
index 1a27dbc..0000000
--- a/libs/hwui/debug/NullGlesDriver.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "FatalBaseDriver.h"
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-class NullGlesDriver : public FatalBaseDriver {
-public:
-    virtual sk_sp<const GrGLInterface> getSkiaInterface() override;
-
-    virtual void glGenBuffers_(GLsizei n, GLuint* buffers) override;
-    virtual void glGenFramebuffers_(GLsizei n, GLuint* framebuffers) override;
-    virtual void glGenRenderbuffers_(GLsizei n, GLuint* renderbuffers) override;
-    virtual void glGenTextures_(GLsizei n, GLuint* textures) override;
-    virtual GLuint glCreateProgram_(void) override;
-    virtual GLuint glCreateShader_(GLenum type) override;
-    virtual void glGetProgramiv_(GLuint program, GLenum pname, GLint* params) override;
-    virtual void glGetProgramInfoLog_(GLuint program, GLsizei bufSize, GLsizei* length,
-                                      GLchar* infoLog) override;
-    virtual void glGetShaderiv_(GLuint shader, GLenum pname, GLint* params) override;
-    virtual void glGetShaderInfoLog_(GLuint shader, GLsizei bufSize, GLsizei* length,
-                                     GLchar* infoLog) override;
-    virtual void glEnable_(GLenum cap) override;
-    virtual void glDisable_(GLenum cap) override;
-    virtual GLboolean glIsEnabled_(GLenum cap) override;
-    virtual void glGetIntegerv_(GLenum pname, GLint* data) override;
-    virtual const GLubyte* glGetString_(GLenum name) override;
-    virtual GLenum glCheckFramebufferStatus_(GLenum target) override;
-
-    virtual void glActiveTexture_(GLenum texture) override {}
-    virtual void glAttachShader_(GLuint program, GLuint shader) override {}
-    virtual void glBindAttribLocation_(GLuint program, GLuint index, const GLchar* name) override {}
-    virtual void glBindBuffer_(GLenum target, GLuint buffer) override {}
-    virtual void glBindFramebuffer_(GLenum target, GLuint framebuffer) override {}
-    virtual void glBindRenderbuffer_(GLenum target, GLuint renderbuffer) override {}
-    virtual void glBindTexture_(GLenum target, GLuint texture) override {}
-    virtual void glBlendColor_(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) override {}
-    virtual void glBlendEquation_(GLenum mode) override {}
-    virtual void glBlendEquationSeparate_(GLenum modeRGB, GLenum modeAlpha) override {}
-    virtual void glBlendFunc_(GLenum sfactor, GLenum dfactor) override {}
-    virtual void glBlendFuncSeparate_(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha,
-                                      GLenum dfactorAlpha) override {}
-    virtual void glBufferData_(GLenum target, GLsizeiptr size, const void* data,
-                               GLenum usage) override {}
-    virtual void glBufferSubData_(GLenum target, GLintptr offset, GLsizeiptr size,
-                                  const void* data) override {}
-    virtual void glClear_(GLbitfield mask) override {}
-    virtual void glClearColor_(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) override {}
-    virtual void glClearDepthf_(GLfloat d) override {}
-    virtual void glClearStencil_(GLint s) override {}
-    virtual void glColorMask_(GLboolean red, GLboolean green, GLboolean blue,
-                              GLboolean alpha) override {}
-    virtual void glCompileShader_(GLuint shader) override {}
-    virtual void glCompressedTexImage2D_(GLenum target, GLint level, GLenum internalformat,
-                                         GLsizei width, GLsizei height, GLint border,
-                                         GLsizei imageSize, const void* data) override {}
-    virtual void glCompressedTexSubImage2D_(GLenum target, GLint level, GLint xoffset,
-                                            GLint yoffset, GLsizei width, GLsizei height,
-                                            GLenum format, GLsizei imageSize,
-                                            const void* data) override {}
-    virtual void glCopyTexImage2D_(GLenum target, GLint level, GLenum internalformat, GLint x,
-                                   GLint y, GLsizei width, GLsizei height, GLint border) override {}
-    virtual void glCopyTexSubImage2D_(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                                      GLint x, GLint y, GLsizei width, GLsizei height) override {}
-    virtual void glCullFace_(GLenum mode) override {}
-    virtual void glDeleteBuffers_(GLsizei n, const GLuint* buffers) override {}
-    virtual void glDeleteFramebuffers_(GLsizei n, const GLuint* framebuffers) override {}
-    virtual void glDeleteProgram_(GLuint program) override {}
-    virtual void glDeleteRenderbuffers_(GLsizei n, const GLuint* renderbuffers) override {}
-    virtual void glDeleteShader_(GLuint shader) override {}
-    virtual void glDeleteTextures_(GLsizei n, const GLuint* textures) override {}
-    virtual void glDepthFunc_(GLenum func) override {}
-    virtual void glDepthMask_(GLboolean flag) override {}
-    virtual void glDepthRangef_(GLfloat n, GLfloat f) override {}
-    virtual void glDetachShader_(GLuint program, GLuint shader) override {}
-    virtual void glDisableVertexAttribArray_(GLuint index) override {}
-    virtual void glDrawArrays_(GLenum mode, GLint first, GLsizei count) override {}
-    virtual void glDrawElements_(GLenum mode, GLsizei count, GLenum type,
-                                 const void* indices) override {}
-    virtual void glEnableVertexAttribArray_(GLuint index) override {}
-    virtual void glFinish_(void) override {}
-    virtual void glFlush_(void) override {}
-    virtual void glFramebufferRenderbuffer_(GLenum target, GLenum attachment,
-                                            GLenum renderbuffertarget,
-                                            GLuint renderbuffer) override {}
-    virtual void glFramebufferTexture2D_(GLenum target, GLenum attachment, GLenum textarget,
-                                         GLuint texture, GLint level) override {}
-    virtual void glFrontFace_(GLenum mode) override {}
-    virtual void glGenerateMipmap_(GLenum target) override {}
-    virtual GLint glGetAttribLocation_(GLuint program, const GLchar* name) override { return 1; }
-    virtual GLenum glGetError_(void) override { return GL_NO_ERROR; }
-    virtual GLint glGetUniformLocation_(GLuint program, const GLchar* name) override { return 2; }
-    virtual void glHint_(GLenum target, GLenum mode) override {}
-    virtual void glLineWidth_(GLfloat width) override {}
-    virtual void glLinkProgram_(GLuint program) override {}
-    virtual void glPixelStorei_(GLenum pname, GLint param) override {}
-    virtual void glPolygonOffset_(GLfloat factor, GLfloat units) override {}
-    virtual void glReadPixels_(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
-                               GLenum type, void* pixels) override {}
-    virtual void glReleaseShaderCompiler_(void) override {}
-    virtual void glRenderbufferStorage_(GLenum target, GLenum internalformat, GLsizei width,
-                                        GLsizei height) override {}
-    virtual void glSampleCoverage_(GLfloat value, GLboolean invert) override {}
-    virtual void glScissor_(GLint x, GLint y, GLsizei width, GLsizei height) override {}
-    virtual void glShaderBinary_(GLsizei count, const GLuint* shaders, GLenum binaryformat,
-                                 const void* binary, GLsizei length) override {}
-    virtual void glShaderSource_(GLuint shader, GLsizei count, const GLchar* const* string,
-                                 const GLint* length) override {}
-    virtual void glStencilFunc_(GLenum func, GLint ref, GLuint mask) override {}
-    virtual void glStencilFuncSeparate_(GLenum face, GLenum func, GLint ref, GLuint mask) override {
-    }
-    virtual void glStencilMask_(GLuint mask) override {}
-    virtual void glStencilMaskSeparate_(GLenum face, GLuint mask) override {}
-    virtual void glStencilOp_(GLenum fail, GLenum zfail, GLenum zpass) override {}
-    virtual void glStencilOpSeparate_(GLenum face, GLenum sfail, GLenum dpfail,
-                                      GLenum dppass) override {}
-    virtual void glTexImage2D_(GLenum target, GLint level, GLint internalformat, GLsizei width,
-                               GLsizei height, GLint border, GLenum format, GLenum type,
-                               const void* pixels) override {}
-    virtual void glTexParameterf_(GLenum target, GLenum pname, GLfloat param) override {}
-    virtual void glTexParameterfv_(GLenum target, GLenum pname, const GLfloat* params) override {}
-    virtual void glTexParameteri_(GLenum target, GLenum pname, GLint param) override {}
-    virtual void glTexParameteriv_(GLenum target, GLenum pname, const GLint* params) override {}
-    virtual void glTexSubImage2D_(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                                  GLsizei width, GLsizei height, GLenum format, GLenum type,
-                                  const void* pixels) override {}
-    virtual void glUniform1f_(GLint location, GLfloat v0) override {}
-    virtual void glUniform1fv_(GLint location, GLsizei count, const GLfloat* value) override {}
-    virtual void glUniform1i_(GLint location, GLint v0) override {}
-    virtual void glUniform1iv_(GLint location, GLsizei count, const GLint* value) override {}
-    virtual void glUniform2f_(GLint location, GLfloat v0, GLfloat v1) override {}
-    virtual void glUniform2fv_(GLint location, GLsizei count, const GLfloat* value) override {}
-    virtual void glUniform2i_(GLint location, GLint v0, GLint v1) override {}
-    virtual void glUniform2iv_(GLint location, GLsizei count, const GLint* value) override {}
-    virtual void glUniform3f_(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) override {}
-    virtual void glUniform3fv_(GLint location, GLsizei count, const GLfloat* value) override {}
-    virtual void glUniform3i_(GLint location, GLint v0, GLint v1, GLint v2) override {}
-    virtual void glUniform3iv_(GLint location, GLsizei count, const GLint* value) override {}
-    virtual void glUniform4f_(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
-                              GLfloat v3) override {}
-    virtual void glUniform4fv_(GLint location, GLsizei count, const GLfloat* value) override {}
-    virtual void glUniform4i_(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) override {}
-    virtual void glUniform4iv_(GLint location, GLsizei count, const GLint* value) override {}
-    virtual void glUniformMatrix2fv_(GLint location, GLsizei count, GLboolean transpose,
-                                     const GLfloat* value) override {}
-    virtual void glUniformMatrix3fv_(GLint location, GLsizei count, GLboolean transpose,
-                                     const GLfloat* value) override {}
-    virtual void glUniformMatrix4fv_(GLint location, GLsizei count, GLboolean transpose,
-                                     const GLfloat* value) override {}
-    virtual void glUseProgram_(GLuint program) override {}
-    virtual void glValidateProgram_(GLuint program) override {}
-    virtual void glVertexAttrib1f_(GLuint index, GLfloat x) override {}
-    virtual void glVertexAttrib1fv_(GLuint index, const GLfloat* v) override {}
-    virtual void glVertexAttrib2f_(GLuint index, GLfloat x, GLfloat y) override {}
-    virtual void glVertexAttrib2fv_(GLuint index, const GLfloat* v) override {}
-    virtual void glVertexAttrib3f_(GLuint index, GLfloat x, GLfloat y, GLfloat z) override {}
-    virtual void glVertexAttrib3fv_(GLuint index, const GLfloat* v) override {}
-    virtual void glVertexAttrib4f_(GLuint index, GLfloat x, GLfloat y, GLfloat z,
-                                   GLfloat w) override {}
-    virtual void glVertexAttrib4fv_(GLuint index, const GLfloat* v) override {}
-    virtual void glVertexAttribPointer_(GLuint index, GLint size, GLenum type, GLboolean normalized,
-                                        GLsizei stride, const void* pointer) override {}
-    virtual void glViewport_(GLint x, GLint y, GLsizei width, GLsizei height) override {}
-
-    // gles2 ext
-    virtual void glInsertEventMarkerEXT_(GLsizei length, const GLchar* marker) override {}
-    virtual void glPushGroupMarkerEXT_(GLsizei length, const GLchar* marker) override {}
-    virtual void glPopGroupMarkerEXT_(void) override {}
-    virtual void glDiscardFramebufferEXT_(GLenum target, GLsizei numAttachments,
-                                          const GLenum* attachments) override {}
-    virtual void glEGLImageTargetTexture2DOES_(GLenum target, GLeglImageOES image) override {}
-
-    // GLES3
-    virtual void* glMapBufferRange_(GLenum target, GLintptr offset, GLsizeiptr length,
-                                    GLbitfield access) override {
-        return 0;
-    }
-
-    virtual GLboolean glUnmapBuffer_(GLenum target) override { return GL_FALSE; }
-};
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/NullSkiaInterface.cpp b/libs/hwui/debug/NullSkiaInterface.cpp
deleted file mode 100644
index d141b9c..0000000
--- a/libs/hwui/debug/NullSkiaInterface.cpp
+++ /dev/null
@@ -1,1402 +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.
- */
-
-// TODO: Remove this file. This has been temporarily copied from Skia (where this class is
-// deprecated). The NullGlesDriver should be constructing a GrGLInterface that calls *its*
-// GL functions!
-
-#include "GrNonAtomicRef.h"
-#include "SkMutex.h"
-#include "SkTDArray.h"
-#include "SkTo.h"
-#include "gl/GrGLDefines.h"
-#include "gl/GrGLInterface.h"
-
-#include <type_traits>
-
-// added to suppress 'no previous prototype' warning and because this code is duplicated in
-// SkNullGLContext.cpp
-namespace {
-
-class GLObject : public GrNonAtomicRef<GLObject> {
-public:
-    GLObject(GrGLuint id) : fID(id) {}
-    virtual ~GLObject() {}
-
-    GrGLuint id() const { return fID; }
-
-private:
-    GrGLuint fID;
-};
-
-// This class maintains a sparsely populated array of object pointers.
-template<typename T> class TGLObjectManager {
-   static_assert(std::is_convertible<T*, GLObject*>::value, "T must be a subclass of GLObject");
-
-public:
-    TGLObjectManager() : fFreeListHead(kFreeListEnd) {
-        *fGLObjects.append() = nullptr; // 0 is not a valid GL object id.
-    }
-
-    ~TGLObjectManager() {
-        // nullptr out the entries that are really free list links rather than ptrs before deleting.
-        intptr_t curr = fFreeListHead;
-        while (kFreeListEnd != curr) {
-            intptr_t next = reinterpret_cast<intptr_t>(fGLObjects[SkToS32(curr)]);
-            fGLObjects[SkToS32(curr)] = nullptr;
-            curr = next;
-        }
-
-        fGLObjects.safeUnrefAll();
-    }
-
-    T* lookUp(GrGLuint id) {
-        T* object = fGLObjects[id];
-        SkASSERT(object && object->id() == id);
-        return object;
-    }
-
-    T* create() {
-        GrGLuint id;
-        T* object;
-
-        if (kFreeListEnd == fFreeListHead) {
-            // no free slots - create a new one
-            id = fGLObjects.count();
-            object = new T(id);
-            *fGLObjects.append() = object;
-        } else {
-            // grab the head of the free list and advance the head to the next free slot.
-            id = static_cast<GrGLuint>(fFreeListHead);
-            fFreeListHead = reinterpret_cast<intptr_t>(fGLObjects[id]);
-
-            object = new T(id);
-            fGLObjects[id] = object;
-        }
-
-        return object;
-    }
-
-    void free(T* object) {
-        SkASSERT(object);
-        SkASSERT(fGLObjects.count() > 0);
-
-        GrGLuint id = object->id();
-        object->unref();
-
-        fGLObjects[id] = reinterpret_cast<T*>(fFreeListHead);
-        fFreeListHead = id;
-    }
-
-private:
-    static const intptr_t kFreeListEnd = -1;
-    // Index of the first entry of fGLObjects in the free list. Free slots in fGLObjects are indices
-    // to the next free slot. The last free slot has a value of kFreeListEnd.
-    intptr_t        fFreeListHead;
-    SkTDArray<T*>   fGLObjects;
-};
-
-class Buffer : public GLObject {
-public:
-    Buffer(GrGLuint id) : INHERITED(id), fDataPtr(nullptr), fSize(0), fMapped(false) {}
-    ~Buffer() { delete[] fDataPtr; }
-
-    void allocate(GrGLsizeiptr size, const GrGLchar* dataPtr) {
-        if (fDataPtr) {
-            SkASSERT(0 != fSize);
-            delete[] fDataPtr;
-        }
-
-        fSize = size;
-        fDataPtr = new char[size];
-    }
-
-    GrGLchar* dataPtr()          { return fDataPtr; }
-    GrGLsizeiptr size() const    { return fSize; }
-
-    void setMapped(bool mapped)  { fMapped = mapped; }
-    bool mapped() const          { return fMapped; }
-
-private:
-    GrGLchar*    fDataPtr;
-    GrGLsizeiptr fSize;         // size in bytes
-    bool         fMapped;
-
-    typedef GLObject INHERITED;
-};
-
-class FramebufferAttachment : public GLObject {
-public:
-    int numSamples() const { return fNumSamples; }
-
-protected:
-    FramebufferAttachment(int id) : INHERITED(id), fNumSamples(1) {}
-
-    int fNumSamples;
-
-    typedef GLObject INHERITED;
-};
-
-class Renderbuffer : public FramebufferAttachment {
-public:
-    Renderbuffer(int id) : INHERITED(id) {}
-    void setNumSamples(int numSamples) { fNumSamples = numSamples; }
-
-private:
-    typedef FramebufferAttachment INHERITED;
-};
-
-class Texture : public FramebufferAttachment {
-public:
-    Texture() : INHERITED(1) {}
-
-private:
-    typedef FramebufferAttachment INHERITED;
-};
-
-class Framebuffer : public GLObject {
-public:
-    Framebuffer(int id) : INHERITED(id) {}
-
-    void setAttachment(GrGLenum attachmentPoint, const FramebufferAttachment* attachment) {
-        switch (attachmentPoint) {
-            default:
-                SK_ABORT("Invalid framebuffer attachment.");
-                break;
-            case GR_GL_STENCIL_ATTACHMENT:
-                fAttachments[(int)AttachmentPoint::kStencil].reset(SkRef(attachment));
-                break;
-            case GR_GL_DEPTH_ATTACHMENT:
-                fAttachments[(int)AttachmentPoint::kDepth].reset(SkRef(attachment));
-                break;
-            case GR_GL_COLOR_ATTACHMENT0:
-                fAttachments[(int)AttachmentPoint::kColor].reset(SkRef(attachment));
-                break;
-        }
-    }
-
-    void notifyAttachmentDeleteWhileBound(const FramebufferAttachment* deleted) {
-        for (auto& attachment : fAttachments) {
-            if (attachment.get() == deleted) {
-                attachment.reset(nullptr);
-            }
-        }
-    }
-
-    int numSamples() const {
-        int numSamples = 0;
-        for (auto& attachment : fAttachments) {
-            if (!attachment) {
-                continue;
-            }
-            if (numSamples) {
-                GrAlwaysAssert(attachment->numSamples() == numSamples);
-                continue;
-            }
-            numSamples = attachment->numSamples();
-        }
-        GrAlwaysAssert(numSamples);
-        return numSamples;
-    }
-
-private:
-    enum AttachmentPoint {
-        kStencil,
-        kDepth,
-        kColor
-    };
-    constexpr int static kNumAttachmentPoints = 1 + (int)AttachmentPoint::kColor;
-
-    sk_sp<const FramebufferAttachment> fAttachments[kNumAttachmentPoints];
-
-    typedef GLObject INHERITED;
-};
-
-class TestInterface : public GrGLInterface {
-public:
-    virtual GrGLvoid activeTexture(GrGLenum texture) {}
-    virtual GrGLvoid attachShader(GrGLuint program, GrGLuint shader) {}
-    virtual GrGLvoid beginQuery(GrGLenum target, GrGLuint id) {}
-    virtual GrGLvoid bindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {}
-    virtual GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) {}
-    virtual GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint framebuffer) {}
-    virtual GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) {}
-    virtual GrGLvoid bindSampler(GrGLuint unit, GrGLuint sampler) {}
-    virtual GrGLvoid bindTexture(GrGLenum target, GrGLuint texture) {}
-    virtual GrGLvoid bindFragDataLocation(GrGLuint program, GrGLuint colorNumber, const GrGLchar* name) {}
-    virtual GrGLvoid bindFragDataLocationIndexed(GrGLuint program, GrGLuint colorNumber, GrGLuint index, const GrGLchar * name) {}
-    virtual GrGLvoid bindVertexArray(GrGLuint array) {}
-    virtual GrGLvoid blendBarrier() {}
-    virtual GrGLvoid blendColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
-    virtual GrGLvoid blendEquation(GrGLenum mode) {}
-    virtual GrGLvoid blendFunc(GrGLenum sfactor, GrGLenum dfactor) {}
-    virtual GrGLvoid blitFramebuffer(GrGLint srcX0, GrGLint srcY0, GrGLint srcX1, GrGLint srcY1, GrGLint dstX0, GrGLint dstY0, GrGLint dstX1, GrGLint dstY1, GrGLbitfield mask, GrGLenum filter) {}
-    virtual GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data, GrGLenum usage) {}
-    virtual GrGLvoid bufferSubData(GrGLenum target, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid* data) {}
-    virtual GrGLenum checkFramebufferStatus(GrGLenum target) { return GR_GL_FRAMEBUFFER_COMPLETE; }
-    virtual GrGLvoid clear(GrGLbitfield mask) {}
-    virtual GrGLvoid clearColor(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha) {}
-    virtual GrGLvoid clearStencil(GrGLint s) {}
-    virtual GrGLvoid colorMask(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha) {}
-    virtual GrGLvoid compileShader(GrGLuint shader) {}
-    virtual GrGLvoid compressedTexImage2D(GrGLenum target, GrGLint level, GrGLenum internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid* data) {}
-    virtual GrGLvoid compressedTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLsizei imageSize, const GrGLvoid* data) {}
-    virtual GrGLvoid copyTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLuint createProgram() { return 0; }
-    virtual GrGLuint createShader(GrGLenum type) { return 0; }
-    virtual GrGLvoid cullFace(GrGLenum mode) {}
-    virtual GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* buffers) {}
-    virtual GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint *framebuffers) {}
-    virtual GrGLvoid deleteProgram(GrGLuint program) {}
-    virtual GrGLvoid deleteQueries(GrGLsizei n, const GrGLuint *ids) {}
-    virtual GrGLvoid deleteRenderbuffers(GrGLsizei n, const GrGLuint *renderbuffers) {}
-    virtual GrGLvoid deleteSamplers(GrGLsizei n, const GrGLuint* samplers) {}
-    virtual GrGLvoid deleteShader(GrGLuint shader) {}
-    virtual GrGLvoid deleteTextures(GrGLsizei n, const GrGLuint* textures) {}
-    virtual GrGLvoid deleteVertexArrays(GrGLsizei n, const GrGLuint *arrays) {}
-    virtual GrGLvoid depthMask(GrGLboolean flag) {}
-    virtual GrGLvoid disable(GrGLenum cap) {}
-    virtual GrGLvoid disableVertexAttribArray(GrGLuint index) {}
-    virtual GrGLvoid drawArrays(GrGLenum mode, GrGLint first, GrGLsizei count) {}
-    virtual GrGLvoid drawArraysInstanced(GrGLenum mode, GrGLint first, GrGLsizei count, GrGLsizei primcount) {}
-    virtual GrGLvoid drawArraysIndirect(GrGLenum mode, const GrGLvoid* indirect) {}
-    virtual GrGLvoid drawBuffer(GrGLenum mode) {}
-    virtual GrGLvoid drawBuffers(GrGLsizei n, const GrGLenum* bufs) {}
-    virtual GrGLvoid drawElements(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
-    virtual GrGLvoid drawElementsInstanced(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid *indices, GrGLsizei primcount) {}
-    virtual GrGLvoid drawElementsIndirect(GrGLenum mode, GrGLenum type, const GrGLvoid* indirect) {}
-    virtual GrGLvoid drawRangeElements(GrGLenum mode, GrGLuint start, GrGLuint end, GrGLsizei count, GrGLenum type, const GrGLvoid* indices) {}
-    virtual GrGLvoid enable(GrGLenum cap) {}
-    virtual GrGLvoid enableVertexAttribArray(GrGLuint index) {}
-    virtual GrGLvoid endQuery(GrGLenum target) {}
-    virtual GrGLvoid finish() {}
-    virtual GrGLvoid flush() {}
-    virtual GrGLvoid flushMappedBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length) {}
-    virtual GrGLvoid framebufferRenderbuffer(GrGLenum target, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {}
-    virtual GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
-    virtual GrGLvoid framebufferTexture2DMultisample(GrGLenum target, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level, GrGLsizei samples) {}
-    virtual GrGLvoid frontFace(GrGLenum mode) {}
-    virtual GrGLvoid genBuffers(GrGLsizei n, GrGLuint* buffers) {}
-    virtual GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) {}
-    virtual GrGLvoid generateMipmap(GrGLenum target) {}
-    virtual GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) {}
-    virtual GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) {}
-    virtual GrGLvoid genSamplers(GrGLsizei n, GrGLuint *samplers) {}
-    virtual GrGLvoid genTextures(GrGLsizei n, GrGLuint* textures) {}
-    virtual GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) {}
-    virtual GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {}
-    virtual GrGLenum getError() { return GR_GL_NO_ERROR; }
-    virtual GrGLvoid getFramebufferAttachmentParameteriv(GrGLenum target, GrGLenum attachment, GrGLenum pname, GrGLint* params) {}
-    virtual GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) {}
-    virtual GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) {}
-    virtual GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, char* infolog) {}
-    virtual GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) {}
-    virtual GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) {}
-    virtual GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) {}
-    virtual GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) {}
-    virtual GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) {}
-    virtual GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) {}
-    virtual GrGLvoid getRenderbufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) {}
-    virtual GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length, char* infolog) {}
-    virtual GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) {}
-    virtual GrGLvoid getShaderPrecisionFormat(GrGLenum shadertype, GrGLenum precisiontype, GrGLint *range, GrGLint *precision) {}
-    virtual const GrGLubyte*  getString(GrGLenum name) { return nullptr; }
-    virtual const GrGLubyte* getStringi(GrGLenum name, GrGLuint index) { return nullptr; }
-    virtual GrGLvoid getTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params) {}
-    virtual GrGLint getUniformLocation(GrGLuint program, const char* name) { return 0; }
-    virtual GrGLvoid insertEventMarker(GrGLsizei length, const char* marker) {}
-    virtual GrGLvoid invalidateBufferData(GrGLuint buffer) {}
-    virtual GrGLvoid invalidateBufferSubData(GrGLuint buffer, GrGLintptr offset, GrGLsizeiptr length) {}
-    virtual GrGLvoid invalidateFramebuffer(GrGLenum target, GrGLsizei numAttachments,  const GrGLenum *attachments) {}
-    virtual GrGLvoid invalidateSubFramebuffer(GrGLenum target, GrGLsizei numAttachments, const GrGLenum *attachments, GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid invalidateTexImage(GrGLuint texture, GrGLint level) {}
-    virtual GrGLvoid invalidateTexSubImage(GrGLuint texture, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint zoffset, GrGLsizei width, GrGLsizei height, GrGLsizei depth) {}
-    virtual GrGLboolean isTexture(GrGLuint texture) { return GR_GL_FALSE; }
-    virtual GrGLvoid lineWidth(GrGLfloat width) {}
-    virtual GrGLvoid linkProgram(GrGLuint program) {}
-    virtual GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) { return nullptr; }
-    virtual GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length, GrGLbitfield access) { return nullptr; }
-    virtual GrGLvoid* mapBufferSubData(GrGLuint target, GrGLintptr offset, GrGLsizeiptr size, GrGLenum access) { return nullptr; }
-    virtual GrGLvoid* mapTexSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLenum access) { return nullptr; }
-    virtual GrGLvoid pixelStorei(GrGLenum pname, GrGLint param) {}
-    virtual GrGLvoid polygonMode(GrGLenum face, GrGLenum mode) {}
-    virtual GrGLvoid popGroupMarker() {}
-    virtual GrGLvoid pushGroupMarker(GrGLsizei length, const char* marker) {}
-    virtual GrGLvoid queryCounter(GrGLuint id, GrGLenum target) {}
-    virtual GrGLvoid rasterSamples(GrGLuint samples, GrGLboolean fixedsamplelocations) {}
-    virtual GrGLvoid readBuffer(GrGLenum src) {}
-    virtual GrGLvoid readPixels(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels) {}
-    virtual GrGLvoid renderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid renderbufferStorageMultisample(GrGLenum target, GrGLsizei samples, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid resolveMultisampleFramebuffer() {}
-    virtual GrGLvoid samplerParameteri(GrGLuint sampler, GrGLenum pname, GrGLint param) {}
-    virtual GrGLvoid samplerParameteriv(GrGLuint sampler, GrGLenum pname, const GrGLint* param) {}
-    virtual GrGLvoid scissor(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid bindUniformLocation(GrGLuint program, GrGLint location, const char* name) {}
-    virtual GrGLvoid shaderSource(GrGLuint shader, GrGLsizei count, const char* const * str, const GrGLint* length) {}
-    virtual GrGLvoid stencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {}
-    virtual GrGLvoid stencilFuncSeparate(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask) {}
-    virtual GrGLvoid stencilMask(GrGLuint mask) {}
-    virtual GrGLvoid stencilMaskSeparate(GrGLenum face, GrGLuint mask) {}
-    virtual GrGLvoid stencilOp(GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
-    virtual GrGLvoid stencilOpSeparate(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass) {}
-    virtual GrGLvoid texBuffer(GrGLenum target, GrGLenum internalformat, GrGLuint buffer) {}
-    virtual GrGLvoid texImage2D(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
-    virtual GrGLvoid texParameterf(GrGLenum target, GrGLenum pname, GrGLfloat param) {}
-    virtual GrGLvoid texParameterfv(GrGLenum target, GrGLenum pname, const GrGLfloat* params) {}
-    virtual GrGLvoid texParameteri(GrGLenum target, GrGLenum pname, GrGLint param) {}
-    virtual GrGLvoid texParameteriv(GrGLenum target, GrGLenum pname, const GrGLint* params) {}
-    virtual GrGLvoid texStorage2D(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid discardFramebuffer(GrGLenum target, GrGLsizei numAttachments, const GrGLenum* attachments) {}
-    virtual GrGLvoid texSubImage2D(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels) {}
-    virtual GrGLvoid textureBarrier() {}
-    virtual GrGLvoid uniform1f(GrGLint location, GrGLfloat v0) {}
-    virtual GrGLvoid uniform1i(GrGLint location, GrGLint v0) {}
-    virtual GrGLvoid uniform1fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
-    virtual GrGLvoid uniform1iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
-    virtual GrGLvoid uniform2f(GrGLint location, GrGLfloat v0, GrGLfloat v1) {}
-    virtual GrGLvoid uniform2i(GrGLint location, GrGLint v0, GrGLint v1) {}
-    virtual GrGLvoid uniform2fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
-    virtual GrGLvoid uniform2iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
-    virtual GrGLvoid uniform3f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2) {}
-    virtual GrGLvoid uniform3i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2) {}
-    virtual GrGLvoid uniform3fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
-    virtual GrGLvoid uniform3iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
-    virtual GrGLvoid uniform4f(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3) {}
-    virtual GrGLvoid uniform4i(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3) {}
-    virtual GrGLvoid uniform4fv(GrGLint location, GrGLsizei count, const GrGLfloat* v) {}
-    virtual GrGLvoid uniform4iv(GrGLint location, GrGLsizei count, const GrGLint* v) {}
-    virtual GrGLvoid uniformMatrix2fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
-    virtual GrGLvoid uniformMatrix3fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
-    virtual GrGLvoid uniformMatrix4fv(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value) {}
-    virtual GrGLboolean unmapBuffer(GrGLenum target) { return GR_GL_TRUE; }
-    virtual GrGLvoid unmapBufferSubData(const GrGLvoid* mem) {}
-    virtual GrGLvoid unmapTexSubImage2D(const GrGLvoid* mem) {}
-    virtual GrGLvoid useProgram(GrGLuint program) {}
-    virtual GrGLvoid vertexAttrib1f(GrGLuint indx, const GrGLfloat value) {}
-    virtual GrGLvoid vertexAttrib2fv(GrGLuint indx, const GrGLfloat* values) {}
-    virtual GrGLvoid vertexAttrib3fv(GrGLuint indx, const GrGLfloat* values) {}
-    virtual GrGLvoid vertexAttrib4fv(GrGLuint indx, const GrGLfloat* values) {}
-    virtual GrGLvoid vertexAttribDivisor(GrGLuint index, GrGLuint divisor) {}
-    virtual GrGLvoid vertexAttribIPointer(GrGLuint indx, GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* ptr) {}
-    virtual GrGLvoid vertexAttribPointer(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr) {}
-    virtual GrGLvoid viewport(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid matrixLoadf(GrGLenum matrixMode, const GrGLfloat* m) {}
-    virtual GrGLvoid matrixLoadIdentity(GrGLenum) {}
-    virtual GrGLvoid pathCommands(GrGLuint path, GrGLsizei numCommands, const GrGLubyte *commands, GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords) {}
-    virtual GrGLvoid pathParameteri(GrGLuint path, GrGLenum pname, GrGLint value) {}
-    virtual GrGLvoid pathParameterf(GrGLuint path, GrGLenum pname, GrGLfloat value) {}
-    virtual GrGLuint genPaths(GrGLsizei range) { return 0; }
-    virtual GrGLvoid deletePaths(GrGLuint path, GrGLsizei range) {}
-    virtual GrGLboolean isPath(GrGLuint path) { return true; }
-    virtual GrGLvoid pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {}
-    virtual GrGLvoid stencilFillPath(GrGLuint path, GrGLenum fillMode, GrGLuint mask) {}
-    virtual GrGLvoid stencilStrokePath(GrGLuint path, GrGLint reference, GrGLuint mask) {}
-    virtual GrGLvoid stencilFillPathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum transformType, const GrGLfloat *transformValues) {}
-    virtual GrGLvoid stencilStrokePathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum transformType, const GrGLfloat *transformValues) {}
-    virtual GrGLvoid coverFillPath(GrGLuint path, GrGLenum coverMode) {}
-    virtual GrGLvoid coverStrokePath(GrGLuint name, GrGLenum coverMode) {}
-    virtual GrGLvoid coverFillPathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues) {}
-    virtual GrGLvoid coverStrokePathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transformValues) {}
-    virtual GrGLvoid stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode) {}
-    virtual GrGLvoid stencilThenCoverStrokePath(GrGLuint path, GrGLint reference, GrGLuint mask, GrGLenum coverMode) {}
-    virtual GrGLvoid stencilThenCoverFillPathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues) {}
-    virtual GrGLvoid stencilThenCoverStrokePathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues) {}
-    virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint location, GrGLenum genMode, GrGLint components,const GrGLfloat *coeffs) {}
-    virtual GrGLvoid bindFragmentInputLocation(GrGLuint program, GrGLint location, const GrGLchar* name) {}
-    virtual GrGLint getProgramResourceLocation(GrGLuint program, GrGLenum programInterface, const GrGLchar *name) { return 0; }
-    virtual GrGLvoid coverageModulation(GrGLenum components) {}
-    virtual GrGLvoid multiDrawArraysIndirect(GrGLenum mode, const GrGLvoid *indirect, GrGLsizei drawcount, GrGLsizei stride) {}
-    virtual GrGLvoid multiDrawElementsIndirect(GrGLenum mode, GrGLenum type, const GrGLvoid *indirect, GrGLsizei drawcount, GrGLsizei stride) {}
-    virtual GrGLuint64 getTextureHandle(GrGLuint texture) { return 0; }
-    virtual GrGLuint64 getTextureSamplerHandle(GrGLuint texture, GrGLuint sampler) { return 0; }
-    virtual GrGLvoid makeTextureHandleResident(GrGLuint64 handle) {}
-    virtual GrGLvoid makeTextureHandleNonResident(GrGLuint64 handle) {}
-    virtual GrGLuint64 getImageHandle(GrGLuint texture, GrGLint level, GrGLboolean layered, GrGLint layer, GrGLint format) { return 0; }
-    virtual GrGLvoid makeImageHandleResident(GrGLuint64 handle, GrGLenum access) {}
-    virtual GrGLvoid makeImageHandleNonResident(GrGLuint64 handle) {}
-    virtual GrGLboolean isTextureHandleResident(GrGLuint64 handle) { return GR_GL_FALSE; }
-    virtual GrGLboolean isImageHandleResident(GrGLuint64 handle) { return GR_GL_FALSE; }
-    virtual GrGLvoid uniformHandleui64(GrGLint location, GrGLuint64 v0) {}
-    virtual GrGLvoid uniformHandleui64v(GrGLint location, GrGLsizei count, const GrGLuint64 *value) {}
-    virtual GrGLvoid programUniformHandleui64(GrGLuint program, GrGLint location, GrGLuint64 v0) {}
-    virtual GrGLvoid programUniformHandleui64v(GrGLuint program, GrGLint location, GrGLsizei count, const GrGLuint64 *value) {}
-    virtual GrGLvoid textureParameteri(GrGLuint texture, GrGLenum target, GrGLenum pname, GrGLint param) {}
-    virtual GrGLvoid textureParameteriv(GrGLuint texture, GrGLenum target, GrGLenum pname, const GrGLint *param) {}
-    virtual GrGLvoid textureParameterf(GrGLuint texture, GrGLenum target, GrGLenum pname, float param) {}
-    virtual GrGLvoid textureParameterfv(GrGLuint texture, GrGLenum target, GrGLenum pname, const float *param) {}
-    virtual GrGLvoid textureImage1D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint GrGLinternalformat, GrGLsizei width, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid *pixels) {}
-    virtual GrGLvoid textureImage2D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint GrGLinternalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid *pixels) {}
-    virtual GrGLvoid textureSubImage1D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLsizei width, GrGLenum format, GrGLenum type, const GrGLvoid *pixels) {}
-    virtual GrGLvoid textureSubImage2D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid *pixels) {}
-    virtual GrGLvoid copyTextureImage1D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLenum GrGLinternalformat, GrGLint x, GrGLint y, GrGLsizei width, GrGLint border) {}
-    virtual GrGLvoid copyTextureImage2D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLenum GrGLinternalformat, GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLint border) {}
-    virtual GrGLvoid copyTextureSubImage1D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint x, GrGLint y, GrGLsizei width) {}
-    virtual GrGLvoid copyTextureSubImage2D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid getTextureImage(GrGLuint texture, GrGLenum target, GrGLint level, GrGLenum format, GrGLenum type, GrGLvoid *pixels) {}
-    virtual GrGLvoid getTextureParameterfv(GrGLuint texture, GrGLenum target, GrGLenum pname, float *params) {}
-    virtual GrGLvoid getTextureParameteriv(GrGLuint texture, GrGLenum target, GrGLenum pname, GrGLint *params) {}
-    virtual GrGLvoid getTextureLevelParameterfv(GrGLuint texture, GrGLenum target, GrGLint level, GrGLenum pname, float *params) {}
-    virtual GrGLvoid getTextureLevelParameteriv(GrGLuint texture, GrGLenum target, GrGLint level, GrGLenum pname, GrGLint *params) {}
-    virtual GrGLvoid textureImage3D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint GrGLinternalformat, GrGLsizei width, GrGLsizei height, GrGLsizei depth, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid *pixels) {}
-    virtual GrGLvoid textureSubImage3D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint zoffset, GrGLsizei width, GrGLsizei height, GrGLsizei depth, GrGLenum format, GrGLenum type, const GrGLvoid *pixels) {}
-    virtual GrGLvoid copyTextureSubImage3D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint zoffset, GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid compressedTextureImage3D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLenum GrGLinternalformat, GrGLsizei width, GrGLsizei height, GrGLsizei depth, GrGLint border, GrGLsizei imageSize, const GrGLvoid *data) {}
-    virtual GrGLvoid compressedTextureImage2D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLenum GrGLinternalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLsizei imageSize, const GrGLvoid *data) {}
-    virtual GrGLvoid compressedTextureImage1D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLenum GrGLinternalformat, GrGLsizei width, GrGLint border, GrGLsizei imageSize, const GrGLvoid *data) {}
-    virtual GrGLvoid compressedTextureSubImage3D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLint zoffset, GrGLsizei width, GrGLsizei height, GrGLsizei depth, GrGLenum format, GrGLsizei imageSize, const GrGLvoid *data) {}
-    virtual GrGLvoid compressedTextureSubImage2D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLsizei imageSize, const GrGLvoid *data) {}
-    virtual GrGLvoid compressedTextureSubImage1D(GrGLuint texture, GrGLenum target, GrGLint level, GrGLint xoffset, GrGLsizei width, GrGLenum format, GrGLsizei imageSize, const GrGLvoid *data) {}
-    virtual GrGLvoid getCompressedTextureImage(GrGLuint texture, GrGLenum target, GrGLint level, GrGLvoid *img) {}
-    virtual GrGLvoid namedBufferData(GrGLuint buffer, GrGLsizeiptr size, const GrGLvoid *data, GrGLenum usage) {}
-    virtual GrGLvoid namedBufferSubData(GrGLuint buffer, GrGLintptr offset, GrGLsizeiptr size, const GrGLvoid *data) {}
-    virtual GrGLvoid* mapNamedBuffer(GrGLuint buffer, GrGLenum access) { return nullptr; }
-    virtual GrGLboolean unmapNamedBuffer(GrGLuint buffer) { return GR_GL_FALSE; }
-    virtual GrGLvoid getNamedBufferParameteriv(GrGLuint buffer, GrGLenum pname, GrGLint *params) {}
-    virtual GrGLvoid getNamedBufferPointerv(GrGLuint buffer, GrGLenum pname, GrGLvoid* *params) {}
-    virtual GrGLvoid getNamedBufferSubData(GrGLuint buffer, GrGLintptr offset, GrGLsizeiptr size, GrGLvoid *data) {}
-    virtual GrGLvoid programUniform1f(GrGLuint program, GrGLint location, float v0) {}
-    virtual GrGLvoid programUniform2f(GrGLuint program, GrGLint location, float v0, float v1) {}
-    virtual GrGLvoid programUniform3f(GrGLuint program, GrGLint location, float v0, float v1, float v2) {}
-    virtual GrGLvoid programUniform4f(GrGLuint program, GrGLint location, float v0, float v1, float v2, float v3) {}
-    virtual GrGLvoid programUniform1i(GrGLuint program, GrGLint location, GrGLint v0) {}
-    virtual GrGLvoid programUniform2i(GrGLuint program, GrGLint location, GrGLint v0, GrGLint v1) {}
-    virtual GrGLvoid programUniform3i(GrGLuint program, GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2) {}
-    virtual GrGLvoid programUniform4i(GrGLuint program, GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3) {}
-    virtual GrGLvoid programUniform1fv(GrGLuint program, GrGLint location, GrGLsizei count, const float *value) {}
-    virtual GrGLvoid programUniform2fv(GrGLuint program, GrGLint location, GrGLsizei count, const float *value) {}
-    virtual GrGLvoid programUniform3fv(GrGLuint program, GrGLint location, GrGLsizei count, const float *value) {}
-    virtual GrGLvoid programUniform4fv(GrGLuint program, GrGLint location, GrGLsizei count, const float *value) {}
-    virtual GrGLvoid programUniform1iv(GrGLuint program, GrGLint location, GrGLsizei count, const GrGLint *value) {}
-    virtual GrGLvoid programUniform2iv(GrGLuint program, GrGLint location, GrGLsizei count, const GrGLint *value) {}
-    virtual GrGLvoid programUniform3iv(GrGLuint program, GrGLint location, GrGLsizei count, const GrGLint *value) {}
-    virtual GrGLvoid programUniform4iv(GrGLuint program, GrGLint location, GrGLsizei count, const GrGLint *value) {}
-    virtual GrGLvoid programUniformMatrix2fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid programUniformMatrix3fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid programUniformMatrix4fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid programUniformMatrix2x3fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid programUniformMatrix3x2fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid programUniformMatrix2x4fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid programUniformMatrix4x2fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid programUniformMatrix3x4fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid programUniformMatrix4x3fv(GrGLuint program, GrGLint location, GrGLsizei count, GrGLboolean transpose, const float *value) {}
-    virtual GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLinternalformat, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLvoid getNamedRenderbufferParameteriv(GrGLuint renderbuffer, GrGLenum pname, GrGLint *params) {}
-    virtual GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsizei samples, GrGLenum GrGLinternalformat, GrGLsizei width, GrGLsizei height) {}
-    virtual GrGLenum checkNamedFramebufferStatus(GrGLuint framebuffer, GrGLenum target) { return GR_GL_FRAMEBUFFER_COMPLETE; }
-    virtual GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
-    virtual GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level) {}
-    virtual GrGLvoid namedFramebufferTexture3D(GrGLuint framebuffer, GrGLenum attachment, GrGLenum textarget, GrGLuint texture, GrGLint level, GrGLint zoffset) {}
-    virtual GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachment, GrGLenum renderbuffertarget, GrGLuint renderbuffer) {}
-    virtual GrGLvoid getNamedFramebufferAttachmentParameteriv(GrGLuint framebuffer, GrGLenum attachment, GrGLenum pname, GrGLint *params) {}
-    virtual GrGLvoid generateTextureMipmap(GrGLuint texture, GrGLenum target) {}
-    virtual GrGLvoid framebufferDrawBuffer(GrGLuint framebuffer, GrGLenum mode) {}
-    virtual GrGLvoid framebufferDrawBuffers(GrGLuint framebuffer, GrGLsizei n, const GrGLenum *bufs) {}
-    virtual GrGLvoid framebufferReadBuffer(GrGLuint framebuffer, GrGLenum mode) {}
-    virtual GrGLvoid getFramebufferParameteriv(GrGLuint framebuffer, GrGLenum pname, GrGLint *param) {}
-    virtual GrGLvoid namedCopyBufferSubData(GrGLuint readBuffer, GrGLuint writeBuffer, GrGLintptr readOffset, GrGLintptr writeOffset, GrGLsizeiptr size) {}
-    virtual GrGLvoid vertexArrayVertexOffset(GrGLuint vaobj, GrGLuint buffer, GrGLint size, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayColorOffset(GrGLuint vaobj, GrGLuint buffer, GrGLint size, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayEdgeFlagOffset(GrGLuint vaobj, GrGLuint buffer, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayIndexOffset(GrGLuint vaobj, GrGLuint buffer, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayNormalOffset(GrGLuint vaobj, GrGLuint buffer, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayTexCoordOffset(GrGLuint vaobj, GrGLuint buffer, GrGLint size, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayMultiTexCoordOffset(GrGLuint vaobj, GrGLuint buffer, GrGLenum texunit, GrGLint size, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayFogCoordOffset(GrGLuint vaobj, GrGLuint buffer, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArraySecondaryColorOffset(GrGLuint vaobj, GrGLuint buffer, GrGLint size, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayVertexAttribOffset(GrGLuint vaobj, GrGLuint buffer, GrGLuint index, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid vertexArrayVertexAttribIOffset(GrGLuint vaobj, GrGLuint buffer, GrGLuint index, GrGLint size, GrGLenum type, GrGLsizei stride, GrGLintptr offset) {}
-    virtual GrGLvoid enableVertexArray(GrGLuint vaobj, GrGLenum array) {}
-    virtual GrGLvoid disableVertexArray(GrGLuint vaobj, GrGLenum array) {}
-    virtual GrGLvoid enableVertexArrayAttrib(GrGLuint vaobj, GrGLuint index) {}
-    virtual GrGLvoid disableVertexArrayAttrib(GrGLuint vaobj, GrGLuint index) {}
-    virtual GrGLvoid getVertexArrayIntegerv(GrGLuint vaobj, GrGLenum pname, GrGLint *param) {}
-    virtual GrGLvoid getVertexArrayPointerv(GrGLuint vaobj, GrGLenum pname, GrGLvoid **param) {}
-    virtual GrGLvoid getVertexArrayIntegeri_v(GrGLuint vaobj, GrGLuint index, GrGLenum pname, GrGLint *param) {}
-    virtual GrGLvoid getVertexArrayPointeri_v(GrGLuint vaobj, GrGLuint index, GrGLenum pname, GrGLvoid **param) {}
-    virtual GrGLvoid* mapNamedBufferRange(GrGLuint buffer, GrGLintptr offset, GrGLsizeiptr length, GrGLbitfield access) { return nullptr; }
-    virtual GrGLvoid flushMappedNamedBufferRange(GrGLuint buffer, GrGLintptr offset, GrGLsizeiptr length) {}
-    virtual GrGLvoid textureBuffer(GrGLuint texture, GrGLenum target, GrGLenum internalformat, GrGLuint buffer) {}
-    virtual GrGLsync fenceSync(GrGLenum condition, GrGLbitfield flags) { return nullptr;  }
-    virtual GrGLboolean isSync(GrGLsync) { return false;  }
-    virtual GrGLenum clientWaitSync(GrGLsync sync, GrGLbitfield flags, GrGLuint64 timeout) { return GR_GL_WAIT_FAILED;  }
-    virtual GrGLvoid waitSync(GrGLsync sync, GrGLbitfield flags, GrGLuint64 timeout) {}
-    virtual GrGLvoid deleteSync(GrGLsync sync) {}
-    virtual GrGLvoid debugMessageControl(GrGLenum source, GrGLenum type, GrGLenum severity, GrGLsizei count, const GrGLuint* ids, GrGLboolean enabled) {}
-    virtual GrGLvoid debugMessageInsert(GrGLenum source, GrGLenum type, GrGLuint id, GrGLenum severity, GrGLsizei length,  const GrGLchar* buf) {}
-    virtual GrGLvoid debugMessageCallback(GRGLDEBUGPROC callback, const GrGLvoid* userParam) {}
-    virtual GrGLuint getDebugMessageLog(GrGLuint count, GrGLsizei bufSize, GrGLenum* sources, GrGLenum* types, GrGLuint* ids, GrGLenum* severities, GrGLsizei* lengths,  GrGLchar* messageLog) { return 0; }
-    virtual GrGLvoid pushDebugGroup(GrGLenum source, GrGLuint id, GrGLsizei length,  const GrGLchar * message) {}
-    virtual GrGLvoid popDebugGroup() {}
-    virtual GrGLvoid objectLabel(GrGLenum identifier, GrGLuint name, GrGLsizei length, const GrGLchar *label) {}
-    virtual GrGLvoid getInternalformativ(GrGLenum target, GrGLenum internalformat, GrGLenum pname, GrGLsizei bufSize, GrGLint *params) {}
-    virtual GrGLvoid programBinary(GrGLuint program, GrGLenum binaryFormat, void *binary, GrGLsizei length) {}
-    virtual GrGLvoid getProgramBinary(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length, GrGLenum *binaryFormat, void *binary) {}
-    virtual GrGLvoid programParameteri(GrGLuint program, GrGLenum pname, GrGLint value) {}
-
-protected:
-    // This must be called by leaf class
-    void init(GrGLStandard standard) {
-        fStandard = standard;
-        fExtensions.init(standard, fFunctions.fGetString, fFunctions.fGetStringi,
-                         fFunctions.fGetIntegerv, nullptr, GR_EGL_NO_DISPLAY);
-    }
-    TestInterface();
-};
-
-template <typename R, typename... A>
-GrGLFunction<R GR_GL_FUNCTION_TYPE(A...)> bind_to_member(TestInterface* interface,
-                                                         R (TestInterface::*member)(A...)) {
-    return [interface, member](A... a) -> R { return (interface->*member)(a...); };
-}
-
-TestInterface::TestInterface() {
-    fFunctions.fActiveTexture = bind_to_member(this, &TestInterface::activeTexture);
-    fFunctions.fAttachShader = bind_to_member(this, &TestInterface::attachShader);
-    fFunctions.fBeginQuery = bind_to_member(this, &TestInterface::beginQuery);
-    fFunctions.fBindAttribLocation = bind_to_member(this, &TestInterface::bindAttribLocation);
-    fFunctions.fBindBuffer = bind_to_member(this, &TestInterface::bindBuffer);
-    fFunctions.fBindFramebuffer = bind_to_member(this, &TestInterface::bindFramebuffer);
-    fFunctions.fBindRenderbuffer = bind_to_member(this, &TestInterface::bindRenderbuffer);
-    fFunctions.fBindSampler = bind_to_member(this, &TestInterface::bindSampler);
-    fFunctions.fBindTexture = bind_to_member(this, &TestInterface::bindTexture);
-    fFunctions.fBindFragDataLocation = bind_to_member(this, &TestInterface::bindFragDataLocation);
-    fFunctions.fBindFragDataLocationIndexed = bind_to_member(this, &TestInterface::bindFragDataLocationIndexed);
-    fFunctions.fBindVertexArray = bind_to_member(this, &TestInterface::bindVertexArray);
-    fFunctions.fBlendBarrier = bind_to_member(this, &TestInterface::blendBarrier);
-    fFunctions.fBlendColor = bind_to_member(this, &TestInterface::blendColor);
-    fFunctions.fBlendEquation = bind_to_member(this, &TestInterface::blendEquation);
-    fFunctions.fBlendFunc = bind_to_member(this, &TestInterface::blendFunc);
-    fFunctions.fBlitFramebuffer = bind_to_member(this, &TestInterface::blitFramebuffer);
-    fFunctions.fBufferData = bind_to_member(this, &TestInterface::bufferData);
-    fFunctions.fBufferSubData = bind_to_member(this, &TestInterface::bufferSubData);
-    fFunctions.fCheckFramebufferStatus = bind_to_member(this, &TestInterface::checkFramebufferStatus);
-    fFunctions.fClear = bind_to_member(this, &TestInterface::clear);
-    fFunctions.fClearColor = bind_to_member(this, &TestInterface::clearColor);
-    fFunctions.fClearStencil = bind_to_member(this, &TestInterface::clearStencil);
-    fFunctions.fColorMask = bind_to_member(this, &TestInterface::colorMask);
-    fFunctions.fCompileShader = bind_to_member(this, &TestInterface::compileShader);
-    fFunctions.fCompressedTexImage2D = bind_to_member(this, &TestInterface::compressedTexImage2D);
-    fFunctions.fCompressedTexSubImage2D = bind_to_member(this, &TestInterface::compressedTexSubImage2D);
-    fFunctions.fCopyTexSubImage2D = bind_to_member(this, &TestInterface::copyTexSubImage2D);
-    fFunctions.fCreateProgram = bind_to_member(this, &TestInterface::createProgram);
-    fFunctions.fCreateShader = bind_to_member(this, &TestInterface::createShader);
-    fFunctions.fCullFace = bind_to_member(this, &TestInterface::cullFace);
-    fFunctions.fDeleteBuffers = bind_to_member(this, &TestInterface::deleteBuffers);
-    fFunctions.fDeleteFramebuffers = bind_to_member(this, &TestInterface::deleteFramebuffers);
-    fFunctions.fDeleteProgram = bind_to_member(this, &TestInterface::deleteProgram);
-    fFunctions.fDeleteQueries = bind_to_member(this, &TestInterface::deleteQueries);
-    fFunctions.fDeleteRenderbuffers = bind_to_member(this, &TestInterface::deleteRenderbuffers);
-    fFunctions.fDeleteSamplers = bind_to_member(this, &TestInterface::deleteSamplers);
-    fFunctions.fDeleteShader = bind_to_member(this, &TestInterface::deleteShader);
-    fFunctions.fDeleteTextures = bind_to_member(this, &TestInterface::deleteTextures);
-    fFunctions.fDeleteVertexArrays = bind_to_member(this, &TestInterface::deleteVertexArrays);
-    fFunctions.fDepthMask = bind_to_member(this, &TestInterface::depthMask);
-    fFunctions.fDisable = bind_to_member(this, &TestInterface::disable);
-    fFunctions.fDisableVertexAttribArray = bind_to_member(this, &TestInterface::disableVertexAttribArray);
-    fFunctions.fDrawArrays = bind_to_member(this, &TestInterface::drawArrays);
-    fFunctions.fDrawArraysInstanced = bind_to_member(this, &TestInterface::drawArraysInstanced);
-    fFunctions.fDrawArraysIndirect = bind_to_member(this, &TestInterface::drawArraysIndirect);
-    fFunctions.fDrawBuffer = bind_to_member(this, &TestInterface::drawBuffer);
-    fFunctions.fDrawBuffers = bind_to_member(this, &TestInterface::drawBuffers);
-    fFunctions.fDrawElements = bind_to_member(this, &TestInterface::drawElements);
-    fFunctions.fDrawElementsInstanced = bind_to_member(this, &TestInterface::drawElementsInstanced);
-    fFunctions.fDrawElementsIndirect = bind_to_member(this, &TestInterface::drawElementsIndirect);
-    fFunctions.fDrawRangeElements = bind_to_member(this, &TestInterface::drawRangeElements);
-    fFunctions.fEnable = bind_to_member(this, &TestInterface::enable);
-    fFunctions.fEnableVertexAttribArray = bind_to_member(this, &TestInterface::enableVertexAttribArray);
-    fFunctions.fEndQuery = bind_to_member(this, &TestInterface::endQuery);
-    fFunctions.fFinish = bind_to_member(this, &TestInterface::finish);
-    fFunctions.fFlush = bind_to_member(this, &TestInterface::flush);
-    fFunctions.fFlushMappedBufferRange = bind_to_member(this, &TestInterface::flushMappedBufferRange);
-    fFunctions.fFramebufferRenderbuffer = bind_to_member(this, &TestInterface::framebufferRenderbuffer);
-    fFunctions.fFramebufferTexture2D = bind_to_member(this, &TestInterface::framebufferTexture2D);
-    fFunctions.fFramebufferTexture2DMultisample = bind_to_member(this, &TestInterface::framebufferTexture2DMultisample);
-    fFunctions.fFrontFace = bind_to_member(this, &TestInterface::frontFace);
-    fFunctions.fGenBuffers = bind_to_member(this, &TestInterface::genBuffers);
-    fFunctions.fGenFramebuffers = bind_to_member(this, &TestInterface::genFramebuffers);
-    fFunctions.fGenerateMipmap = bind_to_member(this, &TestInterface::generateMipmap);
-    fFunctions.fGenQueries = bind_to_member(this, &TestInterface::genQueries);
-    fFunctions.fGenRenderbuffers = bind_to_member(this, &TestInterface::genRenderbuffers);
-    fFunctions.fGenSamplers = bind_to_member(this, &TestInterface::genSamplers);
-    fFunctions.fGenTextures = bind_to_member(this, &TestInterface::genTextures);
-    fFunctions.fGenVertexArrays = bind_to_member(this, &TestInterface::genVertexArrays);
-    fFunctions.fGetBufferParameteriv = bind_to_member(this, &TestInterface::getBufferParameteriv);
-    fFunctions.fGetError = bind_to_member(this, &TestInterface::getError);
-    fFunctions.fGetFramebufferAttachmentParameteriv = bind_to_member(this, &TestInterface::getFramebufferAttachmentParameteriv);
-    fFunctions.fGetIntegerv = bind_to_member(this, &TestInterface::getIntegerv);
-    fFunctions.fGetMultisamplefv = bind_to_member(this, &TestInterface::getMultisamplefv);
-    fFunctions.fGetProgramInfoLog = bind_to_member(this, &TestInterface::getProgramInfoLog);
-    fFunctions.fGetProgramiv = bind_to_member(this, &TestInterface::getProgramiv);
-    fFunctions.fGetQueryiv = bind_to_member(this, &TestInterface::getQueryiv);
-    fFunctions.fGetQueryObjecti64v = bind_to_member(this, &TestInterface::getQueryObjecti64v);
-    fFunctions.fGetQueryObjectiv = bind_to_member(this, &TestInterface::getQueryObjectiv);
-    fFunctions.fGetQueryObjectui64v = bind_to_member(this, &TestInterface::getQueryObjectui64v);
-    fFunctions.fGetQueryObjectuiv = bind_to_member(this, &TestInterface::getQueryObjectuiv);
-    fFunctions.fGetRenderbufferParameteriv = bind_to_member(this, &TestInterface::getRenderbufferParameteriv);
-    fFunctions.fGetShaderInfoLog = bind_to_member(this, &TestInterface::getShaderInfoLog);
-    fFunctions.fGetShaderiv = bind_to_member(this, &TestInterface::getShaderiv);
-    fFunctions.fGetShaderPrecisionFormat = bind_to_member(this, &TestInterface::getShaderPrecisionFormat);
-    fFunctions.fGetString = bind_to_member(this, &TestInterface::getString);
-    fFunctions.fGetStringi = bind_to_member(this, &TestInterface::getStringi);
-    fFunctions.fGetTexLevelParameteriv = bind_to_member(this, &TestInterface::getTexLevelParameteriv);
-    fFunctions.fGetUniformLocation = bind_to_member(this, &TestInterface::getUniformLocation);
-    fFunctions.fInsertEventMarker = bind_to_member(this, &TestInterface::insertEventMarker);
-    fFunctions.fInvalidateBufferData = bind_to_member(this, &TestInterface::invalidateBufferData);
-    fFunctions.fInvalidateBufferSubData = bind_to_member(this, &TestInterface::invalidateBufferSubData);
-    fFunctions.fInvalidateFramebuffer = bind_to_member(this, &TestInterface::invalidateFramebuffer);
-    fFunctions.fInvalidateSubFramebuffer = bind_to_member(this, &TestInterface::invalidateSubFramebuffer);
-    fFunctions.fInvalidateTexImage = bind_to_member(this, &TestInterface::invalidateTexImage);
-    fFunctions.fInvalidateTexSubImage = bind_to_member(this, &TestInterface::invalidateTexSubImage);
-    fFunctions.fIsTexture = bind_to_member(this, &TestInterface::isTexture);
-    fFunctions.fLineWidth = bind_to_member(this, &TestInterface::lineWidth);
-    fFunctions.fLinkProgram = bind_to_member(this, &TestInterface::linkProgram);
-    fFunctions.fMapBuffer = bind_to_member(this, &TestInterface::mapBuffer);
-    fFunctions.fMapBufferRange = bind_to_member(this, &TestInterface::mapBufferRange);
-    fFunctions.fMapBufferSubData = bind_to_member(this, &TestInterface::mapBufferSubData);
-    fFunctions.fMapTexSubImage2D = bind_to_member(this, &TestInterface::mapTexSubImage2D);
-    fFunctions.fPixelStorei = bind_to_member(this, &TestInterface::pixelStorei);
-    fFunctions.fPolygonMode = bind_to_member(this, &TestInterface::polygonMode);
-    fFunctions.fPopGroupMarker = bind_to_member(this, &TestInterface::popGroupMarker);
-    fFunctions.fPushGroupMarker = bind_to_member(this, &TestInterface::pushGroupMarker);
-    fFunctions.fQueryCounter = bind_to_member(this, &TestInterface::queryCounter);
-    fFunctions.fReadBuffer = bind_to_member(this, &TestInterface::readBuffer);
-    fFunctions.fReadPixels = bind_to_member(this, &TestInterface::readPixels);
-    fFunctions.fRenderbufferStorage = bind_to_member(this, &TestInterface::renderbufferStorage);
-    fFunctions.fRenderbufferStorageMultisample = bind_to_member(this, &TestInterface::renderbufferStorageMultisample);
-    fFunctions.fResolveMultisampleFramebuffer = bind_to_member(this, &TestInterface::resolveMultisampleFramebuffer);
-    fFunctions.fScissor = bind_to_member(this, &TestInterface::scissor);
-    fFunctions.fBindUniformLocation = bind_to_member(this, &TestInterface::bindUniformLocation);
-    fFunctions.fSamplerParameteri = bind_to_member(this, &TestInterface::samplerParameteri);
-    fFunctions.fSamplerParameteriv = bind_to_member(this, &TestInterface::samplerParameteriv);
-    fFunctions.fShaderSource = bind_to_member(this, &TestInterface::shaderSource);
-    fFunctions.fStencilFunc = bind_to_member(this, &TestInterface::stencilFunc);
-    fFunctions.fStencilFuncSeparate = bind_to_member(this, &TestInterface::stencilFuncSeparate);
-    fFunctions.fStencilMask = bind_to_member(this, &TestInterface::stencilMask);
-    fFunctions.fStencilMaskSeparate = bind_to_member(this, &TestInterface::stencilMaskSeparate);
-    fFunctions.fStencilOp = bind_to_member(this, &TestInterface::stencilOp);
-    fFunctions.fStencilOpSeparate = bind_to_member(this, &TestInterface::stencilOpSeparate);
-    fFunctions.fTexBuffer = bind_to_member(this, &TestInterface::texBuffer);
-    fFunctions.fTexImage2D = bind_to_member(this, &TestInterface::texImage2D);
-    fFunctions.fTexParameterf = bind_to_member(this, &TestInterface::texParameterf);
-    fFunctions.fTexParameterfv = bind_to_member(this, &TestInterface::texParameterfv);
-    fFunctions.fTexParameteri = bind_to_member(this, &TestInterface::texParameteri);
-    fFunctions.fTexParameteriv = bind_to_member(this, &TestInterface::texParameteriv);
-    fFunctions.fTexStorage2D = bind_to_member(this, &TestInterface::texStorage2D);
-    fFunctions.fDiscardFramebuffer = bind_to_member(this, &TestInterface::discardFramebuffer);
-    fFunctions.fTexSubImage2D = bind_to_member(this, &TestInterface::texSubImage2D);
-    fFunctions.fTextureBarrier = bind_to_member(this, &TestInterface::textureBarrier);
-    fFunctions.fUniform1f = bind_to_member(this, &TestInterface::uniform1f);
-    fFunctions.fUniform1i = bind_to_member(this, &TestInterface::uniform1i);
-    fFunctions.fUniform1fv = bind_to_member(this, &TestInterface::uniform1fv);
-    fFunctions.fUniform1iv = bind_to_member(this, &TestInterface::uniform1iv);
-    fFunctions.fUniform2f = bind_to_member(this, &TestInterface::uniform2f);
-    fFunctions.fUniform2i = bind_to_member(this, &TestInterface::uniform2i);
-    fFunctions.fUniform2fv = bind_to_member(this, &TestInterface::uniform2fv);
-    fFunctions.fUniform2iv = bind_to_member(this, &TestInterface::uniform2iv);
-    fFunctions.fUniform3f = bind_to_member(this, &TestInterface::uniform3f);
-    fFunctions.fUniform3i = bind_to_member(this, &TestInterface::uniform3i);
-    fFunctions.fUniform3fv = bind_to_member(this, &TestInterface::uniform3fv);
-    fFunctions.fUniform3iv = bind_to_member(this, &TestInterface::uniform3iv);
-    fFunctions.fUniform4f = bind_to_member(this, &TestInterface::uniform4f);
-    fFunctions.fUniform4i = bind_to_member(this, &TestInterface::uniform4i);
-    fFunctions.fUniform4fv = bind_to_member(this, &TestInterface::uniform4fv);
-    fFunctions.fUniform4iv = bind_to_member(this, &TestInterface::uniform4iv);
-    fFunctions.fUniformMatrix2fv = bind_to_member(this, &TestInterface::uniformMatrix2fv);
-    fFunctions.fUniformMatrix3fv = bind_to_member(this, &TestInterface::uniformMatrix3fv);
-    fFunctions.fUniformMatrix4fv = bind_to_member(this, &TestInterface::uniformMatrix4fv);
-    fFunctions.fUnmapBuffer = bind_to_member(this, &TestInterface::unmapBuffer);
-    fFunctions.fUnmapBufferSubData = bind_to_member(this, &TestInterface::unmapBufferSubData);
-    fFunctions.fUnmapTexSubImage2D = bind_to_member(this, &TestInterface::unmapTexSubImage2D);
-    fFunctions.fUseProgram = bind_to_member(this, &TestInterface::useProgram);
-    fFunctions.fVertexAttrib1f = bind_to_member(this, &TestInterface::vertexAttrib1f);
-    fFunctions.fVertexAttrib2fv = bind_to_member(this, &TestInterface::vertexAttrib2fv);
-    fFunctions.fVertexAttrib3fv = bind_to_member(this, &TestInterface::vertexAttrib3fv);
-    fFunctions.fVertexAttrib4fv = bind_to_member(this, &TestInterface::vertexAttrib4fv);
-    fFunctions.fVertexAttribDivisor = bind_to_member(this, &TestInterface::vertexAttribDivisor);
-    fFunctions.fVertexAttribIPointer = bind_to_member(this, &TestInterface::vertexAttribIPointer);
-    fFunctions.fVertexAttribPointer = bind_to_member(this, &TestInterface::vertexAttribPointer);
-    fFunctions.fViewport = bind_to_member(this, &TestInterface::viewport);
-    fFunctions.fMatrixLoadf = bind_to_member(this, &TestInterface::matrixLoadf);
-    fFunctions.fMatrixLoadIdentity = bind_to_member(this, &TestInterface::matrixLoadIdentity);
-    fFunctions.fPathCommands = bind_to_member(this, &TestInterface::pathCommands);
-    fFunctions.fPathParameteri = bind_to_member(this, &TestInterface::pathParameteri);
-    fFunctions.fPathParameterf = bind_to_member(this, &TestInterface::pathParameterf);
-    fFunctions.fGenPaths = bind_to_member(this, &TestInterface::genPaths);
-    fFunctions.fDeletePaths = bind_to_member(this, &TestInterface::deletePaths);
-    fFunctions.fIsPath = bind_to_member(this, &TestInterface::isPath);
-    fFunctions.fPathStencilFunc = bind_to_member(this, &TestInterface::pathStencilFunc);
-    fFunctions.fStencilFillPath = bind_to_member(this, &TestInterface::stencilFillPath);
-    fFunctions.fStencilStrokePath = bind_to_member(this, &TestInterface::stencilStrokePath);
-    fFunctions.fStencilFillPathInstanced = bind_to_member(this, &TestInterface::stencilFillPathInstanced);
-    fFunctions.fStencilStrokePathInstanced = bind_to_member(this, &TestInterface::stencilStrokePathInstanced);
-    fFunctions.fCoverFillPath = bind_to_member(this, &TestInterface::coverFillPath);
-    fFunctions.fCoverStrokePath = bind_to_member(this, &TestInterface::coverStrokePath);
-    fFunctions.fCoverFillPathInstanced = bind_to_member(this, &TestInterface::coverFillPathInstanced);
-    fFunctions.fCoverStrokePathInstanced = bind_to_member(this, &TestInterface::coverStrokePathInstanced);
-    fFunctions.fStencilThenCoverFillPath = bind_to_member(this, &TestInterface::stencilThenCoverFillPath);
-    fFunctions.fStencilThenCoverStrokePath = bind_to_member(this, &TestInterface::stencilThenCoverStrokePath);
-    fFunctions.fStencilThenCoverFillPathInstanced = bind_to_member(this, &TestInterface::stencilThenCoverFillPathInstanced);
-    fFunctions.fStencilThenCoverStrokePathInstanced = bind_to_member(this, &TestInterface::stencilThenCoverStrokePathInstanced);
-    fFunctions.fProgramPathFragmentInputGen = bind_to_member(this, &TestInterface::programPathFragmentInputGen);
-    fFunctions.fBindFragmentInputLocation = bind_to_member(this, &TestInterface::bindFragmentInputLocation);
-    fFunctions.fGetProgramResourceLocation = bind_to_member(this, &TestInterface::getProgramResourceLocation);
-    fFunctions.fCoverageModulation = bind_to_member(this, &TestInterface::coverageModulation);
-    fFunctions.fMultiDrawArraysIndirect = bind_to_member(this, &TestInterface::multiDrawArraysIndirect);
-    fFunctions.fMultiDrawElementsIndirect = bind_to_member(this, &TestInterface::multiDrawElementsIndirect);
-    fFunctions.fFenceSync = bind_to_member(this, &TestInterface::fenceSync);
-    fFunctions.fIsSync = bind_to_member(this, &TestInterface::isSync);
-    fFunctions.fClientWaitSync = bind_to_member(this, &TestInterface::clientWaitSync);
-    fFunctions.fWaitSync = bind_to_member(this, &TestInterface::waitSync);
-    fFunctions.fDeleteSync = bind_to_member(this, &TestInterface::deleteSync);
-    fFunctions.fDebugMessageControl = bind_to_member(this, &TestInterface::debugMessageControl);
-    fFunctions.fDebugMessageInsert = bind_to_member(this, &TestInterface::debugMessageInsert);
-    fFunctions.fDebugMessageCallback = bind_to_member(this, &TestInterface::debugMessageCallback);
-    fFunctions.fGetDebugMessageLog = bind_to_member(this, &TestInterface::getDebugMessageLog);
-    fFunctions.fPushDebugGroup = bind_to_member(this, &TestInterface::pushDebugGroup);
-    fFunctions.fPopDebugGroup = bind_to_member(this, &TestInterface::popDebugGroup);
-    fFunctions.fObjectLabel = bind_to_member(this, &TestInterface::objectLabel);
-    fFunctions.fGetInternalformativ = bind_to_member(this, &TestInterface::getInternalformativ);
-    fFunctions.fProgramBinary = bind_to_member(this, &TestInterface::programBinary);
-    fFunctions.fGetProgramBinary = bind_to_member(this, &TestInterface::getProgramBinary);
-    fFunctions.fProgramParameteri = bind_to_member(this, &TestInterface::programParameteri);
-}
-
-/** Null interface implementation */
-class NullInterface : public TestInterface {
-public:
-    NullInterface(bool enableNVPR)
-        : fCurrDrawFramebuffer(0)
-        , fCurrReadFramebuffer(0)
-        , fCurrRenderbuffer(0)
-        , fCurrProgramID(0)
-        , fCurrShaderID(0)
-        , fCurrGenericID(0)
-        , fCurrUniformLocation(0)
-        , fCurrPathID(0) {
-        memset(fBoundBuffers, 0, sizeof(fBoundBuffers));
-        fAdvertisedExtensions.push_back("GL_ARB_framebuffer_object");
-        fAdvertisedExtensions.push_back("GL_ARB_blend_func_extended");
-        fAdvertisedExtensions.push_back("GL_ARB_timer_query");
-        fAdvertisedExtensions.push_back("GL_ARB_draw_buffers");
-        fAdvertisedExtensions.push_back("GL_ARB_occlusion_query");
-        fAdvertisedExtensions.push_back("GL_EXT_stencil_wrap");
-        if (enableNVPR) {
-            fAdvertisedExtensions.push_back("GL_NV_path_rendering");
-            fAdvertisedExtensions.push_back("GL_ARB_program_interface_query");
-        }
-        fAdvertisedExtensions.push_back(nullptr);
-
-        this->init(kGL_GrGLStandard);
-    }
-
-    GrGLenum checkFramebufferStatus(GrGLenum target) override {
-        return GR_GL_FRAMEBUFFER_COMPLETE;
-    }
-
-    GrGLvoid genBuffers(GrGLsizei n, GrGLuint* ids) override {
-        for (int i = 0; i < n; ++i) {
-            Buffer* buffer = fBufferManager.create();
-            ids[i] = buffer->id();
-        }
-    }
-
-    GrGLvoid bufferData(GrGLenum target, GrGLsizeiptr size, const GrGLvoid* data,
-                        GrGLenum usage) override {
-        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
-        if (id > 0) {
-            Buffer* buffer = fBufferManager.lookUp(id);
-            buffer->allocate(size, (const GrGLchar*) data);
-        }
-    }
-
-    GrGLuint createProgram() override {
-        return ++fCurrProgramID;
-    }
-
-    GrGLuint createShader(GrGLenum type) override {
-        return ++fCurrShaderID;
-    }
-
-    GrGLvoid bindBuffer(GrGLenum target, GrGLuint buffer) override {
-        fBoundBuffers[GetBufferIndex(target)] = buffer;
-    }
-
-   // deleting a bound buffer has the side effect of binding 0
-   GrGLvoid deleteBuffers(GrGLsizei n, const GrGLuint* ids) override {
-        // First potentially unbind the buffers.
-        for (int buffIdx = 0; buffIdx < kNumBufferTargets; ++buffIdx) {
-            if (!fBoundBuffers[buffIdx]) {
-                continue;
-            }
-            for (int i = 0; i < n; ++i) {
-                if (ids[i] == fBoundBuffers[buffIdx]) {
-                    fBoundBuffers[buffIdx] = 0;
-                    break;
-                }
-            }
-        }
-
-        // Then actually "delete" the buffers.
-        for (int i = 0; i < n; ++i) {
-            if (ids[i] > 0) {
-                Buffer* buffer = fBufferManager.lookUp(ids[i]);
-                fBufferManager.free(buffer);
-            }
-        }
-    }
-
-    GrGLvoid genFramebuffers(GrGLsizei n, GrGLuint *framebuffers) override {
-        for (int i = 0; i < n; ++i) {
-            Framebuffer* framebuffer = fFramebufferManager.create();
-            framebuffers[i] = framebuffer->id();
-        }
-    }
-
-    GrGLvoid bindFramebuffer(GrGLenum target, GrGLuint framebuffer) override {
-        SkASSERT(GR_GL_FRAMEBUFFER == target || GR_GL_DRAW_FRAMEBUFFER == target ||
-                 GR_GL_READ_FRAMEBUFFER == target);
-        if (GR_GL_READ_FRAMEBUFFER != target) {
-            fCurrDrawFramebuffer = framebuffer;
-        }
-        if (GR_GL_DRAW_FRAMEBUFFER != target) {
-            fCurrReadFramebuffer = framebuffer;
-        }
-    }
-
-    GrGLvoid deleteFramebuffers(GrGLsizei n, const GrGLuint* ids) override {
-        for (int i = 0; i < n; ++i) {
-            if (ids[i] == fCurrDrawFramebuffer) {
-                fCurrDrawFramebuffer = 0;
-            }
-            if (ids[i] == fCurrReadFramebuffer) {
-                fCurrReadFramebuffer = 0;
-            }
-
-            if (ids[i] > 0) {
-                Framebuffer* framebuffer = fFramebufferManager.lookUp(ids[i]);
-                fFramebufferManager.free(framebuffer);
-            }
-        }
-    }
-
-    GrGLvoid genQueries(GrGLsizei n, GrGLuint *ids) override { this->genGenericIds(n, ids); }
-
-    GrGLvoid genRenderbuffers(GrGLsizei n, GrGLuint *renderbuffers) override {
-        for (int i = 0; i < n; ++i) {
-            Renderbuffer* renderbuffer = fRenderbufferManager.create();
-            renderbuffers[i] = renderbuffer->id();
-        }
-    }
-
-    GrGLvoid bindRenderbuffer(GrGLenum target, GrGLuint renderbuffer) override {
-        SkASSERT(GR_GL_RENDERBUFFER == target);
-        fCurrRenderbuffer = renderbuffer;
-    }
-
-    GrGLvoid deleteRenderbuffers(GrGLsizei n, const GrGLuint* ids) override {
-        for (int i = 0; i < n; ++i) {
-            if (ids[i] <= 0) {
-                continue;
-            }
-            if (ids[i] == fCurrRenderbuffer) {
-                fCurrRenderbuffer = 0;
-            }
-            Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(ids[i]);
-
-            if (fCurrDrawFramebuffer) {
-                Framebuffer* drawFramebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer);
-                drawFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer);
-            }
-            if (fCurrReadFramebuffer) {
-                Framebuffer* readFramebuffer = fFramebufferManager.lookUp(fCurrReadFramebuffer);
-                readFramebuffer->notifyAttachmentDeleteWhileBound(renderbuffer);
-            }
-
-            fRenderbufferManager.free(renderbuffer);
-        }
-    }
-
-    GrGLvoid renderbufferStorage(GrGLenum target, GrGLenum internalformat, GrGLsizei width,
-                                 GrGLsizei height) override {
-        GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
-        GrAlwaysAssert(fCurrRenderbuffer);
-        Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer);
-        renderbuffer->setNumSamples(1);
-    }
-
-    GrGLvoid renderbufferStorageMultisample(GrGLenum target, GrGLsizei samples,
-                                            GrGLenum internalformat, GrGLsizei width,
-                                            GrGLsizei height) override {
-        GrAlwaysAssert(GR_GL_RENDERBUFFER == target);
-        GrAlwaysAssert(samples > 0);
-        GrAlwaysAssert(fCurrRenderbuffer);
-        Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer);
-        renderbuffer->setNumSamples(samples);
-    }
-
-    GrGLvoid namedRenderbufferStorage(GrGLuint renderbuffer, GrGLenum GrGLinternalformat,
-                                      GrGLsizei width, GrGLsizei height) override {
-        SK_ABORT("Not implemented");
-    }
-
-    GrGLvoid namedRenderbufferStorageMultisample(GrGLuint renderbuffer, GrGLsizei samples,
-                                                 GrGLenum GrGLinternalformat, GrGLsizei width,
-                                                 GrGLsizei height) override {
-        SK_ABORT("Not implemented");
-    }
-
-    GrGLvoid framebufferRenderbuffer(GrGLenum target, GrGLenum attachment,
-                                     GrGLenum renderbuffertarget,
-                                     GrGLuint renderBufferID) override {
-        GrGLuint id = this->getBoundFramebufferID(target);
-        GrAlwaysAssert(id);
-        Framebuffer* framebuffer = fFramebufferManager.lookUp(id);
-
-        GrAlwaysAssert(GR_GL_RENDERBUFFER == renderbuffertarget);
-        if (!renderBufferID && !fCurrRenderbuffer) {
-           return;
-        }
-        GrAlwaysAssert(fCurrRenderbuffer);
-        Renderbuffer* renderbuffer = fRenderbufferManager.lookUp(fCurrRenderbuffer);
-
-        framebuffer->setAttachment(attachment, renderbuffer);
-    }
-
-    GrGLvoid namedFramebufferRenderbuffer(GrGLuint framebuffer, GrGLenum attachment,
-                                          GrGLenum renderbuffertarget,
-                                          GrGLuint renderbuffer) override {
-        SK_ABORT("Not implemented");
-    }
-
-    GrGLvoid genSamplers(GrGLsizei n, GrGLuint* samplers) override {
-        this->genGenericIds(n, samplers);
-    }
-
-    GrGLvoid genTextures(GrGLsizei n, GrGLuint *textures) override {
-        this->genGenericIds(n, textures);
-    }
-
-    GrGLvoid framebufferTexture2D(GrGLenum target, GrGLenum attachment, GrGLenum textarget,
-                                  GrGLuint textureID, GrGLint level) override {
-        GrGLuint id = this->getBoundFramebufferID(target);
-        GrAlwaysAssert(id);
-        Framebuffer* framebuffer = fFramebufferManager.lookUp(id);
-        framebuffer->setAttachment(attachment, this->getSingleTextureObject());
-    }
-
-    GrGLvoid framebufferTexture2DMultisample(GrGLenum target, GrGLenum attachment,
-                                             GrGLenum textarget, GrGLuint texture, GrGLint level,
-                                             GrGLsizei samples) override {
-        SK_ABORT("Not implemented");
-    }
-
-    GrGLvoid namedFramebufferTexture1D(GrGLuint framebuffer, GrGLenum attachment,
-                                       GrGLenum textarget, GrGLuint texture,
-                                       GrGLint level) override {
-        SK_ABORT("Not implemented");
-    }
-
-    GrGLvoid namedFramebufferTexture2D(GrGLuint framebuffer, GrGLenum attachment,
-                                       GrGLenum textarget, GrGLuint texture,
-                                       GrGLint level) override {
-        SK_ABORT("Not implemented");
-    }
-
-    GrGLvoid namedFramebufferTexture3D(GrGLuint framebuffer, GrGLenum attachment,
-                                       GrGLenum textarget, GrGLuint texture, GrGLint level,
-                                       GrGLint zoffset) override {
-        SK_ABORT("Not implemented");
-    }
-
-    GrGLvoid genVertexArrays(GrGLsizei n, GrGLuint *arrays) override {
-        this->genGenericIds(n, arrays);
-    }
-
-    GrGLenum getError() override { return GR_GL_NO_ERROR; }
-
-    GrGLvoid getIntegerv(GrGLenum pname, GrGLint* params) override {
-        // TODO: remove from Ganesh the #defines for gets we don't use.
-        // We would like to minimize gets overall due to performance issues
-        switch (pname) {
-            case GR_GL_CONTEXT_PROFILE_MASK:
-                *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
-                break;
-            case GR_GL_STENCIL_BITS:
-                *params = 8;
-                break;
-            case GR_GL_SAMPLES: {
-                GrAlwaysAssert(fCurrDrawFramebuffer);
-                Framebuffer* framebuffer = fFramebufferManager.lookUp(fCurrDrawFramebuffer);
-                *params = framebuffer->numSamples();
-                break;
-            }
-            case GR_GL_FRAMEBUFFER_BINDING:
-                *params = 0;
-                break;
-            case GR_GL_VIEWPORT:
-                params[0] = 0;
-                params[1] = 0;
-                params[2] = 800;
-                params[3] = 600;
-                break;
-            case GR_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
-            case GR_GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS:
-            case GR_GL_MAX_TEXTURE_IMAGE_UNITS:
-            case GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
-                *params = 8;
-                break;
-            case GR_GL_MAX_TEXTURE_COORDS:
-                *params = 8;
-                break;
-            case GR_GL_MAX_VERTEX_UNIFORM_VECTORS:
-                *params = kDefaultMaxVertexUniformVectors;
-                break;
-            case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS:
-                *params = kDefaultMaxFragmentUniformVectors;
-                break;
-            case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
-                *params = 16 * 4;
-                break;
-            case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS:
-                *params = 0;
-                break;
-            case GR_GL_COMPRESSED_TEXTURE_FORMATS:
-                break;
-            case GR_GL_MAX_TEXTURE_SIZE:
-                *params = 8192;
-                break;
-            case GR_GL_MAX_RENDERBUFFER_SIZE:
-                *params = 8192;
-                break;
-            case GR_GL_MAX_SAMPLES:
-                *params = 32;
-                break;
-            case GR_GL_MAX_VERTEX_ATTRIBS:
-                *params = kDefaultMaxVertexAttribs;
-                break;
-            case GR_GL_MAX_VARYING_VECTORS:
-                *params = kDefaultMaxVaryingVectors;
-                break;
-            case GR_GL_NUM_EXTENSIONS: {
-                GrGLint i = 0;
-                while (fAdvertisedExtensions[i++]);
-                *params = i;
-                break;
-            }
-            default:
-                SK_ABORT("Unexpected pname to GetIntegerv");
-        }
-    }
-
-    GrGLvoid getProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) override {
-        this->getShaderOrProgramiv(program, pname, params);
-    }
-
-    GrGLvoid getProgramInfoLog(GrGLuint program, GrGLsizei bufsize, GrGLsizei* length,
-                               char* infolog) override {
-        this->getInfoLog(program, bufsize, length, infolog);
-    }
-
-    GrGLvoid getMultisamplefv(GrGLenum pname, GrGLuint index, GrGLfloat* val) override {
-        val[0] = val[1] = 0.5f;
-    }
-
-    GrGLvoid getQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) override {
-        switch (pname) {
-            case GR_GL_CURRENT_QUERY:
-                *params = 0;
-                break;
-            case GR_GL_QUERY_COUNTER_BITS:
-                *params = 32;
-                break;
-            default:
-                SK_ABORT("Unexpected pname passed GetQueryiv.");
-        }
-    }
-
-    GrGLvoid getQueryObjecti64v(GrGLuint id, GrGLenum pname, GrGLint64 *params) override {
-        this->queryResult(id, pname, params);
-    }
-
-    GrGLvoid getQueryObjectiv(GrGLuint id, GrGLenum pname, GrGLint *params) override {
-        this->queryResult(id, pname, params);
-    }
-
-    GrGLvoid getQueryObjectui64v(GrGLuint id, GrGLenum pname, GrGLuint64 *params) override {
-        this->queryResult(id, pname, params);
-    }
-
-    GrGLvoid getQueryObjectuiv(GrGLuint id, GrGLenum pname, GrGLuint *params) override {
-        this->queryResult(id, pname, params);
-    }
-
-    GrGLvoid getShaderiv(GrGLuint shader, GrGLenum pname, GrGLint* params) override {
-        this->getShaderOrProgramiv(shader, pname, params);
-    }
-
-    GrGLvoid getShaderInfoLog(GrGLuint shader, GrGLsizei bufsize, GrGLsizei* length,
-                              char* infolog) override {
-        this->getInfoLog(shader, bufsize, length, infolog);
-    }
-
-    const GrGLubyte* getString(GrGLenum name) override {
-        switch (name) {
-            case GR_GL_EXTENSIONS:
-                return CombinedExtensionString();
-            case GR_GL_VERSION:
-                return (const GrGLubyte*)"4.0 Null GL";
-            case GR_GL_SHADING_LANGUAGE_VERSION:
-                return (const GrGLubyte*)"4.20.8 Null GLSL";
-            case GR_GL_VENDOR:
-                return (const GrGLubyte*)"Null Vendor";
-            case GR_GL_RENDERER:
-                return (const GrGLubyte*)"The Null (Non-)Renderer";
-            default:
-                SK_ABORT("Unexpected name passed to GetString");
-                return nullptr;
-        }
-    }
-
-    const GrGLubyte* getStringi(GrGLenum name, GrGLuint i) override {
-        switch (name) {
-            case GR_GL_EXTENSIONS: {
-                GrGLint count;
-                this->getIntegerv(GR_GL_NUM_EXTENSIONS, &count);
-                if ((GrGLint)i <= count) {
-                    return (const GrGLubyte*) fAdvertisedExtensions[i];
-                } else {
-                    return nullptr;
-                }
-            }
-            default:
-                SK_ABORT("Unexpected name passed to GetStringi");
-                return nullptr;
-        }
-    }
-
-    GrGLint getUniformLocation(GrGLuint program, const char* name) override {
-        return ++fCurrUniformLocation;
-    }
-
-    GrGLvoid* mapBufferRange(GrGLenum target, GrGLintptr offset, GrGLsizeiptr length,
-                             GrGLbitfield access) override {
-        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
-        if (id > 0) {
-            // We just ignore the offset and length here.
-            Buffer* buffer = fBufferManager.lookUp(id);
-            SkASSERT(!buffer->mapped());
-            buffer->setMapped(true);
-            return buffer->dataPtr();
-        }
-        return nullptr;
-    }
-
-    GrGLvoid* mapBuffer(GrGLenum target, GrGLenum access) override {
-        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
-        if (id > 0) {
-            Buffer* buffer = fBufferManager.lookUp(id);
-            SkASSERT(!buffer->mapped());
-            buffer->setMapped(true);
-            return buffer->dataPtr();
-        }
-
-        SkASSERT(false);
-        return nullptr;            // no buffer bound to target
-    }
-
-    GrGLboolean unmapBuffer(GrGLenum target) override {
-        GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
-        if (id > 0) {
-            Buffer* buffer = fBufferManager.lookUp(id);
-            SkASSERT(buffer->mapped());
-            buffer->setMapped(false);
-            return GR_GL_TRUE;
-        }
-
-        GrAlwaysAssert(false);
-        return GR_GL_FALSE; // GR_GL_INVALID_OPERATION;
-    }
-
-    GrGLvoid getBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) override {
-        switch (pname) {
-            case GR_GL_BUFFER_MAPPED: {
-                *params = GR_GL_FALSE;
-                GrGLuint id = fBoundBuffers[GetBufferIndex(target)];
-                if (id > 0) {
-                    Buffer* buffer = fBufferManager.lookUp(id);
-                    if (buffer->mapped()) {
-                        *params = GR_GL_TRUE;
-                    }
-                }
-                break; }
-            default:
-                SK_ABORT("Unexpected pname to GetBufferParamateriv");
-                break;
-        }
-    }
-
-    // NV_path_rendering
-    GrGLuint genPaths(GrGLsizei range) override {
-        return ++fCurrPathID;
-    }
-
-
-private:
-    inline int static GetBufferIndex(GrGLenum glTarget) {
-        switch (glTarget) {
-            default:                           SK_ABORT("Unexpected GL target to GetBufferIndex");
-            case GR_GL_ARRAY_BUFFER:           return 0;
-            case GR_GL_ELEMENT_ARRAY_BUFFER:   return 1;
-            case GR_GL_TEXTURE_BUFFER:         return 2;
-            case GR_GL_DRAW_INDIRECT_BUFFER:   return 3;
-            case GR_GL_PIXEL_PACK_BUFFER:      return 4;
-            case GR_GL_PIXEL_UNPACK_BUFFER:    return 5;
-        }
-    }
-    constexpr int static kNumBufferTargets = 6;
-
-    TGLObjectManager<Buffer>         fBufferManager;
-    GrGLuint                         fBoundBuffers[kNumBufferTargets];
-    TGLObjectManager<Framebuffer>    fFramebufferManager;
-    GrGLuint                         fCurrDrawFramebuffer;
-    GrGLuint                         fCurrReadFramebuffer;
-    TGLObjectManager<Renderbuffer>   fRenderbufferManager;
-    GrGLuint                         fCurrRenderbuffer;
-    GrGLuint                         fCurrProgramID;
-    GrGLuint                         fCurrShaderID;
-    GrGLuint                         fCurrGenericID;
-    GrGLuint                         fCurrUniformLocation;
-    GrGLuint                         fCurrPathID;
-    sk_sp<const Texture>             fSingleTextureObject;
-    SkTArray<const char*>            fAdvertisedExtensions;
-
-    // the OpenGLES 2.0 spec says this must be >= 128
-    static const GrGLint kDefaultMaxVertexUniformVectors = 128;
-
-    // the OpenGLES 2.0 spec says this must be >=16
-    static const GrGLint kDefaultMaxFragmentUniformVectors = 16;
-
-    // the OpenGLES 2.0 spec says this must be >= 8
-    static const GrGLint kDefaultMaxVertexAttribs = 8;
-
-    // the OpenGLES 2.0 spec says this must be >= 8
-    static const GrGLint kDefaultMaxVaryingVectors = 8;
-
-    GrGLuint getBoundFramebufferID(GrGLenum target) {
-        switch (target) {
-            case GR_GL_FRAMEBUFFER:
-            case GR_GL_DRAW_FRAMEBUFFER:
-                return fCurrDrawFramebuffer;
-            case GR_GL_READ_FRAMEBUFFER:
-                return fCurrReadFramebuffer;
-            default:
-                SK_ABORT("Invalid framebuffer target.");
-                return 0;
-        }
-    }
-
-    const Texture* getSingleTextureObject() {
-        // We currently only use FramebufferAttachment objects for a sample count, and all textures
-        // in Skia have one sample, so there is no need as of yet to track individual textures. This
-        // also works around a bug in chromium's cc_unittests where they send us texture IDs that
-        // were generated by cc::TestGLES2Interface.
-        if (!fSingleTextureObject) {
-            fSingleTextureObject.reset(new Texture);
-        }
-        return fSingleTextureObject.get();
-    }
-
-    const GrGLubyte* CombinedExtensionString() {
-        static SkString gExtString;
-        static SkMutex gMutex;
-        gMutex.acquire();
-        if (0 == gExtString.size()) {
-            int i = 0;
-            while (fAdvertisedExtensions[i]) {
-                if (i > 0) {
-                    gExtString.append(" ");
-                }
-                gExtString.append(fAdvertisedExtensions[i]);
-                ++i;
-            }
-        }
-        gMutex.release();
-        return (const GrGLubyte*) gExtString.c_str();
-    }
-
-    GrGLvoid genGenericIds(GrGLsizei n, GrGLuint* ids) {
-        for (int i = 0; i < n; ++i) {
-            ids[i] = ++fCurrGenericID;
-        }
-    }
-
-    GrGLvoid getInfoLog(GrGLuint object, GrGLsizei bufsize, GrGLsizei* length,
-                        char* infolog) {
-        if (length) {
-            *length = 0;
-        }
-        if (bufsize > 0) {
-            *infolog = 0;
-        }
-    }
-
-    GrGLvoid getShaderOrProgramiv(GrGLuint object,  GrGLenum pname, GrGLint* params) {
-        switch (pname) {
-            case GR_GL_LINK_STATUS:  // fallthru
-            case GR_GL_COMPILE_STATUS:
-                *params = GR_GL_TRUE;
-                break;
-            case GR_GL_INFO_LOG_LENGTH: // fallthru
-            case GL_PROGRAM_BINARY_LENGTH:
-                *params = 0;
-                break;
-                // we don't expect any other pnames
-            default:
-                SK_ABORT("Unexpected pname to GetProgramiv");
-                break;
-        }
-    }
-
-    template <typename T>
-    void queryResult(GrGLenum GLtarget, GrGLenum pname, T *params) {
-        switch (pname) {
-            case GR_GL_QUERY_RESULT_AVAILABLE:
-                *params = GR_GL_TRUE;
-                break;
-            case GR_GL_QUERY_RESULT:
-                *params = 0;
-                break;
-            default:
-                SK_ABORT("Unexpected pname passed to GetQueryObject.");
-                break;
-        }
-    }
-
-    typedef TestInterface INHERITED;
-};
-
-}  // anonymous namespace
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-const GrGLInterface* CreateNullSkiaInterface() { return new NullInterface(false); }
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/ScopedReplaceDriver.h b/libs/hwui/debug/ScopedReplaceDriver.h
deleted file mode 100644
index 110196f..0000000
--- a/libs/hwui/debug/ScopedReplaceDriver.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.
- */
-
-#pragma once
-
-#include "GlesDriver.h"
-
-namespace android {
-namespace uirenderer {
-namespace debug {
-
-template <typename Driver>
-class ScopedReplaceDriver {
-public:
-    ScopedReplaceDriver() {
-        std::unique_ptr<Driver> glDriver = std::make_unique<Driver>();
-        mCurrentDriver = glDriver.get();
-        mOldDriver = GlesDriver::replace(std::move(glDriver));
-    }
-
-    Driver& get() { return *mCurrentDriver; }
-
-    ~ScopedReplaceDriver() { GlesDriver::replace(std::move(mOldDriver)); }
-
-private:
-    std::unique_ptr<GlesDriver> mOldDriver;
-    Driver* mCurrentDriver;
-};
-
-}  // namespace debug
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/debug/gles_decls.in b/libs/hwui/debug/gles_decls.in
deleted file mode 100644
index 3900959..0000000
--- a/libs/hwui/debug/gles_decls.in
+++ /dev/null
@@ -1,543 +0,0 @@
-GL_ENTRY(void, glActiveTexture, GLenum texture)
-GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader)
-GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar *name)
-GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
-GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer)
-GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer)
-GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
-GL_ENTRY(void, glBlendColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-GL_ENTRY(void, glBlendEquation, GLenum mode)
-GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha)
-GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
-GL_ENTRY(void, glBlendFuncSeparate, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
-GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage)
-GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
-GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target)
-GL_ENTRY(void, glClear, GLbitfield mask)
-GL_ENTRY(void, glClearColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-GL_ENTRY(void, glClearDepthf, GLfloat d)
-GL_ENTRY(void, glClearStencil, GLint s)
-GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
-GL_ENTRY(void, glCompileShader, GLuint shader)
-GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data)
-GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data)
-GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
-GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(GLuint, glCreateProgram, void)
-GL_ENTRY(GLuint, glCreateShader, GLenum type)
-GL_ENTRY(void, glCullFace, GLenum mode)
-GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint *buffers)
-GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint *framebuffers)
-GL_ENTRY(void, glDeleteProgram, GLuint program)
-GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint *renderbuffers)
-GL_ENTRY(void, glDeleteShader, GLuint shader)
-GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures)
-GL_ENTRY(void, glDepthFunc, GLenum func)
-GL_ENTRY(void, glDepthMask, GLboolean flag)
-GL_ENTRY(void, glDepthRangef, GLfloat n, GLfloat f)
-GL_ENTRY(void, glDetachShader, GLuint program, GLuint shader)
-GL_ENTRY(void, glDisable, GLenum cap)
-GL_ENTRY(void, glDisableVertexAttribArray, GLuint index)
-GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count)
-GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const void *indices)
-GL_ENTRY(void, glEnable, GLenum cap)
-GL_ENTRY(void, glEnableVertexAttribArray, GLuint index)
-GL_ENTRY(void, glFinish, void)
-GL_ENTRY(void, glFlush, void)
-GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
-GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
-GL_ENTRY(void, glFrontFace, GLenum mode)
-GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint *buffers)
-GL_ENTRY(void, glGenerateMipmap, GLenum target)
-GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint *framebuffers)
-GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint *renderbuffers)
-GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures)
-GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
-GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
-GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders)
-GL_ENTRY(GLint, glGetAttribLocation, GLuint program, const GLchar *name)
-GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *data)
-GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(GLenum, glGetError, void)
-GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat *data)
-GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint *data)
-GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
-GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
-GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision)
-GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source)
-GL_ENTRY(const GLubyte *, glGetString, GLenum name)
-GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat *params)
-GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint *params)
-GL_ENTRY(GLint, glGetUniformLocation, GLuint program, const GLchar *name)
-GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void **pointer)
-GL_ENTRY(void, glHint, GLenum target, GLenum mode)
-GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer)
-GL_ENTRY(GLboolean, glIsEnabled, GLenum cap)
-GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer)
-GL_ENTRY(GLboolean, glIsProgram, GLuint program)
-GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer)
-GL_ENTRY(GLboolean, glIsShader, GLuint shader)
-GL_ENTRY(GLboolean, glIsTexture, GLuint texture)
-GL_ENTRY(void, glLineWidth, GLfloat width)
-GL_ENTRY(void, glLinkProgram, GLuint program)
-GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param)
-GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
-GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels)
-GL_ENTRY(void, glReleaseShaderCompiler, void)
-GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glSampleCoverage, GLfloat value, GLboolean invert)
-GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glShaderBinary, GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length)
-GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length)
-GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
-GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask)
-GL_ENTRY(void, glStencilMask, GLuint mask)
-GL_ENTRY(void, glStencilMaskSeparate, GLenum face, GLuint mask)
-GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass)
-GL_ENTRY(void, glStencilOpSeparate, GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
-GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)
-GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param)
-GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params)
-GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param)
-GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint *params)
-GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
-GL_ENTRY(void, glUniform1f, GLint location, GLfloat v0)
-GL_ENTRY(void, glUniform1fv, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glUniform1i, GLint location, GLint v0)
-GL_ENTRY(void, glUniform1iv, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glUniform2f, GLint location, GLfloat v0, GLfloat v1)
-GL_ENTRY(void, glUniform2fv, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glUniform2i, GLint location, GLint v0, GLint v1)
-GL_ENTRY(void, glUniform2iv, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glUniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
-GL_ENTRY(void, glUniform3fv, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glUniform3i, GLint location, GLint v0, GLint v1, GLint v2)
-GL_ENTRY(void, glUniform3iv, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glUniform4f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
-GL_ENTRY(void, glUniform4fv, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glUniform4i, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
-GL_ENTRY(void, glUniform4iv, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUseProgram, GLuint program)
-GL_ENTRY(void, glValidateProgram, GLuint program)
-GL_ENTRY(void, glVertexAttrib1f, GLuint index, GLfloat x)
-GL_ENTRY(void, glVertexAttrib1fv, GLuint index, const GLfloat *v)
-GL_ENTRY(void, glVertexAttrib2f, GLuint index, GLfloat x, GLfloat y)
-GL_ENTRY(void, glVertexAttrib2fv, GLuint index, const GLfloat *v)
-GL_ENTRY(void, glVertexAttrib3f, GLuint index, GLfloat x, GLfloat y, GLfloat z)
-GL_ENTRY(void, glVertexAttrib3fv, GLuint index, const GLfloat *v)
-GL_ENTRY(void, glVertexAttrib4f, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-GL_ENTRY(void, glVertexAttrib4fv, GLuint index, const GLfloat *v)
-GL_ENTRY(void, glVertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
-GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glReadBuffer, GLenum src)
-GL_ENTRY(void, glDrawRangeElements, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices)
-GL_ENTRY(void, glTexImage3D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)
-GL_ENTRY(void, glTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
-GL_ENTRY(void, glCopyTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glCompressedTexImage3D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
-GL_ENTRY(void, glCompressedTexSubImage3D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
-GL_ENTRY(void, glGenQueries, GLsizei n, GLuint *ids)
-GL_ENTRY(void, glDeleteQueries, GLsizei n, const GLuint *ids)
-GL_ENTRY(GLboolean, glIsQuery, GLuint id)
-GL_ENTRY(void, glBeginQuery, GLenum target, GLuint id)
-GL_ENTRY(void, glEndQuery, GLenum target)
-GL_ENTRY(void, glGetQueryiv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetQueryObjectuiv, GLuint id, GLenum pname, GLuint *params)
-GL_ENTRY(GLboolean, glUnmapBuffer, GLenum target)
-GL_ENTRY(void, glGetBufferPointerv, GLenum target, GLenum pname, void **params)
-GL_ENTRY(void, glDrawBuffers, GLsizei n, const GLenum *bufs)
-GL_ENTRY(void, glUniformMatrix2x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUniformMatrix3x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUniformMatrix2x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUniformMatrix4x2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUniformMatrix3x4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUniformMatrix4x3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glBlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
-GL_ENTRY(void, glRenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glFramebufferTextureLayer, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
-GL_ENTRY(void *, glMapBufferRange, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
-GL_ENTRY(void, glFlushMappedBufferRange, GLenum target, GLintptr offset, GLsizeiptr length)
-GL_ENTRY(void, glBindVertexArray, GLuint array)
-GL_ENTRY(void, glDeleteVertexArrays, GLsizei n, const GLuint *arrays)
-GL_ENTRY(void, glGenVertexArrays, GLsizei n, GLuint *arrays)
-GL_ENTRY(GLboolean, glIsVertexArray, GLuint array)
-GL_ENTRY(void, glGetIntegeri_v, GLenum target, GLuint index, GLint *data)
-GL_ENTRY(void, glBeginTransformFeedback, GLenum primitiveMode)
-GL_ENTRY(void, glEndTransformFeedback, void)
-GL_ENTRY(void, glBindBufferRange, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
-GL_ENTRY(void, glBindBufferBase, GLenum target, GLuint index, GLuint buffer)
-GL_ENTRY(void, glTransformFeedbackVaryings, GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode)
-GL_ENTRY(void, glGetTransformFeedbackVarying, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name)
-GL_ENTRY(void, glVertexAttribIPointer, GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
-GL_ENTRY(void, glGetVertexAttribIiv, GLuint index, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetVertexAttribIuiv, GLuint index, GLenum pname, GLuint *params)
-GL_ENTRY(void, glVertexAttribI4i, GLuint index, GLint x, GLint y, GLint z, GLint w)
-GL_ENTRY(void, glVertexAttribI4ui, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
-GL_ENTRY(void, glVertexAttribI4iv, GLuint index, const GLint *v)
-GL_ENTRY(void, glVertexAttribI4uiv, GLuint index, const GLuint *v)
-GL_ENTRY(void, glGetUniformuiv, GLuint program, GLint location, GLuint *params)
-GL_ENTRY(GLint, glGetFragDataLocation, GLuint program, const GLchar *name)
-GL_ENTRY(void, glUniform1ui, GLint location, GLuint v0)
-GL_ENTRY(void, glUniform2ui, GLint location, GLuint v0, GLuint v1)
-GL_ENTRY(void, glUniform3ui, GLint location, GLuint v0, GLuint v1, GLuint v2)
-GL_ENTRY(void, glUniform4ui, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
-GL_ENTRY(void, glUniform1uiv, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glUniform2uiv, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glUniform3uiv, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glUniform4uiv, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glClearBufferiv, GLenum buffer, GLint drawbuffer, const GLint *value)
-GL_ENTRY(void, glClearBufferuiv, GLenum buffer, GLint drawbuffer, const GLuint *value)
-GL_ENTRY(void, glClearBufferfv, GLenum buffer, GLint drawbuffer, const GLfloat *value)
-GL_ENTRY(void, glClearBufferfi, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
-GL_ENTRY(const GLubyte *, glGetStringi, GLenum name, GLuint index)
-GL_ENTRY(void, glCopyBufferSubData, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
-GL_ENTRY(void, glGetUniformIndices, GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices)
-GL_ENTRY(void, glGetActiveUniformsiv, GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params)
-GL_ENTRY(GLuint, glGetUniformBlockIndex, GLuint program, const GLchar *uniformBlockName)
-GL_ENTRY(void, glGetActiveUniformBlockiv, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetActiveUniformBlockName, GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName)
-GL_ENTRY(void, glUniformBlockBinding, GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
-GL_ENTRY(void, glDrawArraysInstanced, GLenum mode, GLint first, GLsizei count, GLsizei instancecount)
-GL_ENTRY(void, glDrawElementsInstanced, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount)
-GL_ENTRY(GLsync, glFenceSync, GLenum condition, GLbitfield flags)
-GL_ENTRY(GLboolean, glIsSync, GLsync sync)
-GL_ENTRY(void, glDeleteSync, GLsync sync)
-GL_ENTRY(GLenum, glClientWaitSync, GLsync sync, GLbitfield flags, GLuint64 timeout)
-GL_ENTRY(void, glWaitSync, GLsync sync, GLbitfield flags, GLuint64 timeout)
-GL_ENTRY(void, glGetInteger64v, GLenum pname, GLint64 *data)
-GL_ENTRY(void, glGetSynciv, GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
-GL_ENTRY(void, glGetInteger64i_v, GLenum target, GLuint index, GLint64 *data)
-GL_ENTRY(void, glGetBufferParameteri64v, GLenum target, GLenum pname, GLint64 *params)
-GL_ENTRY(void, glGenSamplers, GLsizei count, GLuint *samplers)
-GL_ENTRY(void, glDeleteSamplers, GLsizei count, const GLuint *samplers)
-GL_ENTRY(GLboolean, glIsSampler, GLuint sampler)
-GL_ENTRY(void, glBindSampler, GLuint unit, GLuint sampler)
-GL_ENTRY(void, glSamplerParameteri, GLuint sampler, GLenum pname, GLint param)
-GL_ENTRY(void, glSamplerParameteriv, GLuint sampler, GLenum pname, const GLint *param)
-GL_ENTRY(void, glSamplerParameterf, GLuint sampler, GLenum pname, GLfloat param)
-GL_ENTRY(void, glSamplerParameterfv, GLuint sampler, GLenum pname, const GLfloat *param)
-GL_ENTRY(void, glGetSamplerParameteriv, GLuint sampler, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetSamplerParameterfv, GLuint sampler, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glVertexAttribDivisor, GLuint index, GLuint divisor)
-GL_ENTRY(void, glBindTransformFeedback, GLenum target, GLuint id)
-GL_ENTRY(void, glDeleteTransformFeedbacks, GLsizei n, const GLuint *ids)
-GL_ENTRY(void, glGenTransformFeedbacks, GLsizei n, GLuint *ids)
-GL_ENTRY(GLboolean, glIsTransformFeedback, GLuint id)
-GL_ENTRY(void, glPauseTransformFeedback, void)
-GL_ENTRY(void, glResumeTransformFeedback, void)
-GL_ENTRY(void, glGetProgramBinary, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
-GL_ENTRY(void, glProgramBinary, GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
-GL_ENTRY(void, glProgramParameteri, GLuint program, GLenum pname, GLint value)
-GL_ENTRY(void, glInvalidateFramebuffer, GLenum target, GLsizei numAttachments, const GLenum *attachments)
-GL_ENTRY(void, glInvalidateSubFramebuffer, GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glTexStorage2D, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glTexStorage3D, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
-GL_ENTRY(void, glGetInternalformativ, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params)
-GL_ENTRY(void, glDispatchCompute, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
-GL_ENTRY(void, glDispatchComputeIndirect, GLintptr indirect)
-GL_ENTRY(void, glDrawArraysIndirect, GLenum mode, const void *indirect)
-GL_ENTRY(void, glDrawElementsIndirect, GLenum mode, GLenum type, const void *indirect)
-GL_ENTRY(void, glFramebufferParameteri, GLenum target, GLenum pname, GLint param)
-GL_ENTRY(void, glGetFramebufferParameteriv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetProgramInterfaceiv, GLuint program, GLenum programInterface, GLenum pname, GLint *params)
-GL_ENTRY(GLuint, glGetProgramResourceIndex, GLuint program, GLenum programInterface, const GLchar *name)
-GL_ENTRY(void, glGetProgramResourceName, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name)
-GL_ENTRY(void, glGetProgramResourceiv, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params)
-GL_ENTRY(GLint, glGetProgramResourceLocation, GLuint program, GLenum programInterface, const GLchar *name)
-GL_ENTRY(void, glUseProgramStages, GLuint pipeline, GLbitfield stages, GLuint program)
-GL_ENTRY(void, glActiveShaderProgram, GLuint pipeline, GLuint program)
-GL_ENTRY(GLuint, glCreateShaderProgramv, GLenum type, GLsizei count, const GLchar *const*strings)
-GL_ENTRY(void, glBindProgramPipeline, GLuint pipeline)
-GL_ENTRY(void, glDeleteProgramPipelines, GLsizei n, const GLuint *pipelines)
-GL_ENTRY(void, glGenProgramPipelines, GLsizei n, GLuint *pipelines)
-GL_ENTRY(GLboolean, glIsProgramPipeline, GLuint pipeline)
-GL_ENTRY(void, glGetProgramPipelineiv, GLuint pipeline, GLenum pname, GLint *params)
-GL_ENTRY(void, glProgramUniform1i, GLuint program, GLint location, GLint v0)
-GL_ENTRY(void, glProgramUniform2i, GLuint program, GLint location, GLint v0, GLint v1)
-GL_ENTRY(void, glProgramUniform3i, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
-GL_ENTRY(void, glProgramUniform4i, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
-GL_ENTRY(void, glProgramUniform1ui, GLuint program, GLint location, GLuint v0)
-GL_ENTRY(void, glProgramUniform2ui, GLuint program, GLint location, GLuint v0, GLuint v1)
-GL_ENTRY(void, glProgramUniform3ui, GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
-GL_ENTRY(void, glProgramUniform4ui, GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
-GL_ENTRY(void, glProgramUniform1f, GLuint program, GLint location, GLfloat v0)
-GL_ENTRY(void, glProgramUniform2f, GLuint program, GLint location, GLfloat v0, GLfloat v1)
-GL_ENTRY(void, glProgramUniform3f, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
-GL_ENTRY(void, glProgramUniform4f, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
-GL_ENTRY(void, glProgramUniform1iv, GLuint program, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glProgramUniform2iv, GLuint program, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glProgramUniform3iv, GLuint program, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glProgramUniform4iv, GLuint program, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glProgramUniform1uiv, GLuint program, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glProgramUniform2uiv, GLuint program, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glProgramUniform3uiv, GLuint program, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glProgramUniform4uiv, GLuint program, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glProgramUniform1fv, GLuint program, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glProgramUniform2fv, GLuint program, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glProgramUniform3fv, GLuint program, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glProgramUniform4fv, GLuint program, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix2x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix3x2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix2x4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix4x2fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix3x4fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix4x3fv, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glValidateProgramPipeline, GLuint pipeline)
-GL_ENTRY(void, glGetProgramPipelineInfoLog, GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
-GL_ENTRY(void, glBindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)
-GL_ENTRY(void, glGetBooleani_v, GLenum target, GLuint index, GLboolean *data)
-GL_ENTRY(void, glMemoryBarrier, GLbitfield barriers)
-GL_ENTRY(void, glMemoryBarrierByRegion, GLbitfield barriers)
-GL_ENTRY(void, glTexStorage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)
-GL_ENTRY(void, glGetMultisamplefv, GLenum pname, GLuint index, GLfloat *val)
-GL_ENTRY(void, glSampleMaski, GLuint maskNumber, GLbitfield mask)
-GL_ENTRY(void, glGetTexLevelParameteriv, GLenum target, GLint level, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetTexLevelParameterfv, GLenum target, GLint level, GLenum pname, GLfloat *params)
-GL_ENTRY(void, glBindVertexBuffer, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
-GL_ENTRY(void, glVertexAttribFormat, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)
-GL_ENTRY(void, glVertexAttribIFormat, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)
-GL_ENTRY(void, glVertexAttribBinding, GLuint attribindex, GLuint bindingindex)
-GL_ENTRY(void, glVertexBindingDivisor, GLuint bindingindex, GLuint divisor)
-GL_ENTRY(void, glBlendBarrier, void)
-GL_ENTRY(void, glCopyImageSubData, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
-GL_ENTRY(void, glDebugMessageControl, GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled)
-GL_ENTRY(void, glDebugMessageInsert, GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf)
-GL_ENTRY(void, glDebugMessageCallback, GLDEBUGPROC callback, const void *userParam)
-GL_ENTRY(GLuint, glGetDebugMessageLog, GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog)
-GL_ENTRY(void, glPushDebugGroup, GLenum source, GLuint id, GLsizei length, const GLchar *message)
-GL_ENTRY(void, glPopDebugGroup, void)
-GL_ENTRY(void, glObjectLabel, GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
-GL_ENTRY(void, glGetObjectLabel, GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
-GL_ENTRY(void, glObjectPtrLabel, const void *ptr, GLsizei length, const GLchar *label)
-GL_ENTRY(void, glGetObjectPtrLabel, const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)
-GL_ENTRY(void, glGetPointerv, GLenum pname, void **params)
-GL_ENTRY(void, glEnablei, GLenum target, GLuint index)
-GL_ENTRY(void, glDisablei, GLenum target, GLuint index)
-GL_ENTRY(void, glBlendEquationi, GLuint buf, GLenum mode)
-GL_ENTRY(void, glBlendEquationSeparatei, GLuint buf, GLenum modeRGB, GLenum modeAlpha)
-GL_ENTRY(void, glBlendFunci, GLuint buf, GLenum src, GLenum dst)
-GL_ENTRY(void, glBlendFuncSeparatei, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-GL_ENTRY(void, glColorMaski, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
-GL_ENTRY(GLboolean, glIsEnabledi, GLenum target, GLuint index)
-GL_ENTRY(void, glDrawElementsBaseVertex, GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex)
-GL_ENTRY(void, glDrawRangeElementsBaseVertex, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex)
-GL_ENTRY(void, glDrawElementsInstancedBaseVertex, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex)
-GL_ENTRY(void, glFramebufferTexture, GLenum target, GLenum attachment, GLuint texture, GLint level)
-GL_ENTRY(void, glPrimitiveBoundingBox, GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW)
-GL_ENTRY(GLenum, glGetGraphicsResetStatus, void)
-GL_ENTRY(void, glReadnPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data)
-GL_ENTRY(void, glGetnUniformfv, GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
-GL_ENTRY(void, glGetnUniformiv, GLuint program, GLint location, GLsizei bufSize, GLint *params)
-GL_ENTRY(void, glGetnUniformuiv, GLuint program, GLint location, GLsizei bufSize, GLuint *params)
-GL_ENTRY(void, glMinSampleShading, GLfloat value)
-GL_ENTRY(void, glPatchParameteri, GLenum pname, GLint value)
-GL_ENTRY(void, glTexParameterIiv, GLenum target, GLenum pname, const GLint *params)
-GL_ENTRY(void, glTexParameterIuiv, GLenum target, GLenum pname, const GLuint *params)
-GL_ENTRY(void, glGetTexParameterIiv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetTexParameterIuiv, GLenum target, GLenum pname, GLuint *params)
-GL_ENTRY(void, glSamplerParameterIiv, GLuint sampler, GLenum pname, const GLint *param)
-GL_ENTRY(void, glSamplerParameterIuiv, GLuint sampler, GLenum pname, const GLuint *param)
-GL_ENTRY(void, glGetSamplerParameterIiv, GLuint sampler, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetSamplerParameterIuiv, GLuint sampler, GLenum pname, GLuint *params)
-GL_ENTRY(void, glTexBuffer, GLenum target, GLenum internalformat, GLuint buffer)
-GL_ENTRY(void, glTexBufferRange, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)
-GL_ENTRY(void, glTexStorage3DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)
-GL_ENTRY(void, glBlendBarrierKHR, void)
-GL_ENTRY(void, glDebugMessageControlKHR, GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled)
-GL_ENTRY(void, glDebugMessageInsertKHR, GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf)
-GL_ENTRY(void, glDebugMessageCallbackKHR, GLDEBUGPROCKHR callback, const void *userParam)
-GL_ENTRY(GLuint, glGetDebugMessageLogKHR, GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog)
-GL_ENTRY(void, glPushDebugGroupKHR, GLenum source, GLuint id, GLsizei length, const GLchar *message)
-GL_ENTRY(void, glPopDebugGroupKHR, void)
-GL_ENTRY(void, glObjectLabelKHR, GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
-GL_ENTRY(void, glGetObjectLabelKHR, GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
-GL_ENTRY(void, glObjectPtrLabelKHR, const void *ptr, GLsizei length, const GLchar *label)
-GL_ENTRY(void, glGetObjectPtrLabelKHR, const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)
-GL_ENTRY(void, glGetPointervKHR, GLenum pname, void **params)
-GL_ENTRY(GLenum, glGetGraphicsResetStatusKHR, void)
-GL_ENTRY(void, glReadnPixelsKHR, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data)
-GL_ENTRY(void, glGetnUniformfvKHR, GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
-GL_ENTRY(void, glGetnUniformivKHR, GLuint program, GLint location, GLsizei bufSize, GLint *params)
-GL_ENTRY(void, glGetnUniformuivKHR, GLuint program, GLint location, GLsizei bufSize, GLuint *params)
-GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image)
-GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image)
-GL_ENTRY(void, glCopyImageSubDataOES, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
-GL_ENTRY(void, glEnableiOES, GLenum target, GLuint index)
-GL_ENTRY(void, glDisableiOES, GLenum target, GLuint index)
-GL_ENTRY(void, glBlendEquationiOES, GLuint buf, GLenum mode)
-GL_ENTRY(void, glBlendEquationSeparateiOES, GLuint buf, GLenum modeRGB, GLenum modeAlpha)
-GL_ENTRY(void, glBlendFunciOES, GLuint buf, GLenum src, GLenum dst)
-GL_ENTRY(void, glBlendFuncSeparateiOES, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-GL_ENTRY(void, glColorMaskiOES, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
-GL_ENTRY(GLboolean, glIsEnablediOES, GLenum target, GLuint index)
-GL_ENTRY(void, glDrawElementsBaseVertexOES, GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex)
-GL_ENTRY(void, glDrawRangeElementsBaseVertexOES, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex)
-GL_ENTRY(void, glDrawElementsInstancedBaseVertexOES, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex)
-GL_ENTRY(void, glFramebufferTextureOES, GLenum target, GLenum attachment, GLuint texture, GLint level)
-GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
-GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const void *binary, GLint length)
-GL_ENTRY(void *, glMapBufferOES, GLenum target, GLenum access)
-GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target)
-GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void **params)
-GL_ENTRY(void, glPrimitiveBoundingBoxOES, GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW)
-GL_ENTRY(void, glMinSampleShadingOES, GLfloat value)
-GL_ENTRY(void, glPatchParameteriOES, GLenum pname, GLint value)
-GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)
-GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
-GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
-GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)
-GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
-GL_ENTRY(void, glTexParameterIivOES, GLenum target, GLenum pname, const GLint *params)
-GL_ENTRY(void, glTexParameterIuivOES, GLenum target, GLenum pname, const GLuint *params)
-GL_ENTRY(void, glGetTexParameterIivOES, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetTexParameterIuivOES, GLenum target, GLenum pname, GLuint *params)
-GL_ENTRY(void, glSamplerParameterIivOES, GLuint sampler, GLenum pname, const GLint *param)
-GL_ENTRY(void, glSamplerParameterIuivOES, GLuint sampler, GLenum pname, const GLuint *param)
-GL_ENTRY(void, glGetSamplerParameterIivOES, GLuint sampler, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetSamplerParameterIuivOES, GLuint sampler, GLenum pname, GLuint *params)
-GL_ENTRY(void, glTexBufferOES, GLenum target, GLenum internalformat, GLuint buffer)
-GL_ENTRY(void, glTexBufferRangeOES, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)
-GL_ENTRY(void, glTexStorage3DMultisampleOES, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)
-GL_ENTRY(void, glTextureViewOES, GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers)
-GL_ENTRY(void, glBindVertexArrayOES, GLuint array)
-GL_ENTRY(void, glDeleteVertexArraysOES, GLsizei n, const GLuint *arrays)
-GL_ENTRY(void, glGenVertexArraysOES, GLsizei n, GLuint *arrays)
-GL_ENTRY(GLboolean, glIsVertexArrayOES, GLuint array)
-GL_ENTRY(void, glDrawArraysInstancedBaseInstanceEXT, GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance)
-GL_ENTRY(void, glDrawElementsInstancedBaseInstanceEXT, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance)
-GL_ENTRY(void, glDrawElementsInstancedBaseVertexBaseInstanceEXT, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance)
-GL_ENTRY(void, glBindFragDataLocationIndexedEXT, GLuint program, GLuint colorNumber, GLuint index, const GLchar *name)
-GL_ENTRY(void, glBindFragDataLocationEXT, GLuint program, GLuint color, const GLchar *name)
-GL_ENTRY(GLint, glGetProgramResourceLocationIndexEXT, GLuint program, GLenum programInterface, const GLchar *name)
-GL_ENTRY(GLint, glGetFragDataIndexEXT, GLuint program, const GLchar *name)
-GL_ENTRY(void, glBufferStorageEXT, GLenum target, GLsizeiptr size, const void *data, GLbitfield flags)
-GL_ENTRY(void, glCopyImageSubDataEXT, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
-GL_ENTRY(void, glLabelObjectEXT, GLenum type, GLuint object, GLsizei length, const GLchar *label)
-GL_ENTRY(void, glGetObjectLabelEXT, GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label)
-GL_ENTRY(void, glInsertEventMarkerEXT, GLsizei length, const GLchar *marker)
-GL_ENTRY(void, glPushGroupMarkerEXT, GLsizei length, const GLchar *marker)
-GL_ENTRY(void, glPopGroupMarkerEXT, void)
-GL_ENTRY(void, glDiscardFramebufferEXT, GLenum target, GLsizei numAttachments, const GLenum *attachments)
-GL_ENTRY(void, glGenQueriesEXT, GLsizei n, GLuint *ids)
-GL_ENTRY(void, glDeleteQueriesEXT, GLsizei n, const GLuint *ids)
-GL_ENTRY(GLboolean, glIsQueryEXT, GLuint id)
-GL_ENTRY(void, glBeginQueryEXT, GLenum target, GLuint id)
-GL_ENTRY(void, glEndQueryEXT, GLenum target)
-GL_ENTRY(void, glQueryCounterEXT, GLuint id, GLenum target)
-GL_ENTRY(void, glGetQueryivEXT, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetQueryObjectivEXT, GLuint id, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetQueryObjectuivEXT, GLuint id, GLenum pname, GLuint *params)
-GL_ENTRY(void, glGetQueryObjecti64vEXT, GLuint id, GLenum pname, GLint64 *params)
-GL_ENTRY(void, glGetQueryObjectui64vEXT, GLuint id, GLenum pname, GLuint64 *params)
-GL_ENTRY(void, glDrawBuffersEXT, GLsizei n, const GLenum *bufs)
-GL_ENTRY(void, glEnableiEXT, GLenum target, GLuint index)
-GL_ENTRY(void, glDisableiEXT, GLenum target, GLuint index)
-GL_ENTRY(void, glBlendEquationiEXT, GLuint buf, GLenum mode)
-GL_ENTRY(void, glBlendEquationSeparateiEXT, GLuint buf, GLenum modeRGB, GLenum modeAlpha)
-GL_ENTRY(void, glBlendFunciEXT, GLuint buf, GLenum src, GLenum dst)
-GL_ENTRY(void, glBlendFuncSeparateiEXT, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-GL_ENTRY(void, glColorMaskiEXT, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
-GL_ENTRY(GLboolean, glIsEnablediEXT, GLenum target, GLuint index)
-GL_ENTRY(void, glDrawElementsBaseVertexEXT, GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex)
-GL_ENTRY(void, glDrawRangeElementsBaseVertexEXT, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex)
-GL_ENTRY(void, glDrawElementsInstancedBaseVertexEXT, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex)
-GL_ENTRY(void, glMultiDrawElementsBaseVertexEXT, GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex)
-GL_ENTRY(void, glDrawArraysInstancedEXT, GLenum mode, GLint start, GLsizei count, GLsizei primcount)
-GL_ENTRY(void, glDrawElementsInstancedEXT, GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount)
-GL_ENTRY(void, glFramebufferTextureEXT, GLenum target, GLenum attachment, GLuint texture, GLint level)
-GL_ENTRY(void, glVertexAttribDivisorEXT, GLuint index, GLuint divisor)
-GL_ENTRY(void *, glMapBufferRangeEXT, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
-GL_ENTRY(void, glFlushMappedBufferRangeEXT, GLenum target, GLintptr offset, GLsizeiptr length)
-GL_ENTRY(void, glMultiDrawArraysEXT, GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount)
-GL_ENTRY(void, glMultiDrawElementsEXT, GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount)
-GL_ENTRY(void, glMultiDrawArraysIndirectEXT, GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride)
-GL_ENTRY(void, glMultiDrawElementsIndirectEXT, GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride)
-GL_ENTRY(void, glRenderbufferStorageMultisampleEXT, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glFramebufferTexture2DMultisampleEXT, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
-GL_ENTRY(void, glReadBufferIndexedEXT, GLenum src, GLint index)
-GL_ENTRY(void, glDrawBuffersIndexedEXT, GLint n, const GLenum *location, const GLint *indices)
-GL_ENTRY(void, glGetIntegeri_vEXT, GLenum target, GLuint index, GLint *data)
-GL_ENTRY(void, glPrimitiveBoundingBoxEXT, GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW)
-GL_ENTRY(void, glRasterSamplesEXT, GLuint samples, GLboolean fixedsamplelocations)
-GL_ENTRY(GLenum, glGetGraphicsResetStatusEXT, void)
-GL_ENTRY(void, glReadnPixelsEXT, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data)
-GL_ENTRY(void, glGetnUniformfvEXT, GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
-GL_ENTRY(void, glGetnUniformivEXT, GLuint program, GLint location, GLsizei bufSize, GLint *params)
-GL_ENTRY(void, glActiveShaderProgramEXT, GLuint pipeline, GLuint program)
-GL_ENTRY(void, glBindProgramPipelineEXT, GLuint pipeline)
-GL_ENTRY(GLuint, glCreateShaderProgramvEXT, GLenum type, GLsizei count, const GLchar **strings)
-GL_ENTRY(void, glDeleteProgramPipelinesEXT, GLsizei n, const GLuint *pipelines)
-GL_ENTRY(void, glGenProgramPipelinesEXT, GLsizei n, GLuint *pipelines)
-GL_ENTRY(void, glGetProgramPipelineInfoLogEXT, GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
-GL_ENTRY(void, glGetProgramPipelineivEXT, GLuint pipeline, GLenum pname, GLint *params)
-GL_ENTRY(GLboolean, glIsProgramPipelineEXT, GLuint pipeline)
-GL_ENTRY(void, glProgramParameteriEXT, GLuint program, GLenum pname, GLint value)
-GL_ENTRY(void, glProgramUniform1fEXT, GLuint program, GLint location, GLfloat v0)
-GL_ENTRY(void, glProgramUniform1fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glProgramUniform1iEXT, GLuint program, GLint location, GLint v0)
-GL_ENTRY(void, glProgramUniform1ivEXT, GLuint program, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glProgramUniform2fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1)
-GL_ENTRY(void, glProgramUniform2fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glProgramUniform2iEXT, GLuint program, GLint location, GLint v0, GLint v1)
-GL_ENTRY(void, glProgramUniform2ivEXT, GLuint program, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glProgramUniform3fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
-GL_ENTRY(void, glProgramUniform3fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glProgramUniform3iEXT, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
-GL_ENTRY(void, glProgramUniform3ivEXT, GLuint program, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glProgramUniform4fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
-GL_ENTRY(void, glProgramUniform4fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value)
-GL_ENTRY(void, glProgramUniform4iEXT, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
-GL_ENTRY(void, glProgramUniform4ivEXT, GLuint program, GLint location, GLsizei count, const GLint *value)
-GL_ENTRY(void, glProgramUniformMatrix2fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix3fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glUseProgramStagesEXT, GLuint pipeline, GLbitfield stages, GLuint program)
-GL_ENTRY(void, glValidateProgramPipelineEXT, GLuint pipeline)
-GL_ENTRY(void, glProgramUniform1uiEXT, GLuint program, GLint location, GLuint v0)
-GL_ENTRY(void, glProgramUniform2uiEXT, GLuint program, GLint location, GLuint v0, GLuint v1)
-GL_ENTRY(void, glProgramUniform3uiEXT, GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
-GL_ENTRY(void, glProgramUniform4uiEXT, GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
-GL_ENTRY(void, glProgramUniform1uivEXT, GLuint program, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glProgramUniform2uivEXT, GLuint program, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glProgramUniform3uivEXT, GLuint program, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glProgramUniform4uivEXT, GLuint program, GLint location, GLsizei count, const GLuint *value)
-GL_ENTRY(void, glProgramUniformMatrix2x3fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix3x2fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix2x4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix4x2fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix3x4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glProgramUniformMatrix4x3fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
-GL_ENTRY(void, glTexPageCommitmentEXT, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit)
-GL_ENTRY(void, glPatchParameteriEXT, GLenum pname, GLint value)
-GL_ENTRY(void, glTexParameterIivEXT, GLenum target, GLenum pname, const GLint *params)
-GL_ENTRY(void, glTexParameterIuivEXT, GLenum target, GLenum pname, const GLuint *params)
-GL_ENTRY(void, glGetTexParameterIivEXT, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetTexParameterIuivEXT, GLenum target, GLenum pname, GLuint *params)
-GL_ENTRY(void, glSamplerParameterIivEXT, GLuint sampler, GLenum pname, const GLint *param)
-GL_ENTRY(void, glSamplerParameterIuivEXT, GLuint sampler, GLenum pname, const GLuint *param)
-GL_ENTRY(void, glGetSamplerParameterIivEXT, GLuint sampler, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetSamplerParameterIuivEXT, GLuint sampler, GLenum pname, GLuint *params)
-GL_ENTRY(void, glTexBufferEXT, GLenum target, GLenum internalformat, GLuint buffer)
-GL_ENTRY(void, glTexBufferRangeEXT, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)
-GL_ENTRY(void, glTexStorage1DEXT, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
-GL_ENTRY(void, glTexStorage2DEXT, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glTexStorage3DEXT, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
-GL_ENTRY(void, glTextureStorage1DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
-GL_ENTRY(void, glTextureStorage2DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
-GL_ENTRY(void, glTextureStorage3DEXT, GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
-GL_ENTRY(void, glTextureViewEXT, GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers)
diff --git a/libs/hwui/debug/gles_redefine.h b/libs/hwui/debug/gles_redefine.h
deleted file mode 100644
index 49b5069..0000000
--- a/libs/hwui/debug/gles_redefine.h
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * 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.
- */
-
-#define glActiveShaderProgram wrap_glActiveShaderProgram
-#define glActiveShaderProgramEXT wrap_glActiveShaderProgramEXT
-#define glActiveTexture wrap_glActiveTexture
-#define glAlphaFunc wrap_glAlphaFunc
-#define glAlphaFuncQCOM wrap_glAlphaFuncQCOM
-#define glAlphaFuncx wrap_glAlphaFuncx
-#define glAlphaFuncxOES wrap_glAlphaFuncxOES
-#define glApplyFramebufferAttachmentCMAAINTEL wrap_glApplyFramebufferAttachmentCMAAINTEL
-#define glAttachShader wrap_glAttachShader
-#define glBeginConditionalRenderNV wrap_glBeginConditionalRenderNV
-#define glBeginPerfMonitorAMD wrap_glBeginPerfMonitorAMD
-#define glBeginPerfQueryINTEL wrap_glBeginPerfQueryINTEL
-#define glBeginQuery wrap_glBeginQuery
-#define glBeginQueryEXT wrap_glBeginQueryEXT
-#define glBeginTransformFeedback wrap_glBeginTransformFeedback
-#define glBindAttribLocation wrap_glBindAttribLocation
-#define glBindBuffer wrap_glBindBuffer
-#define glBindBufferBase wrap_glBindBufferBase
-#define glBindBufferRange wrap_glBindBufferRange
-#define glBindFragDataLocationEXT wrap_glBindFragDataLocationEXT
-#define glBindFragDataLocationIndexedEXT wrap_glBindFragDataLocationIndexedEXT
-#define glBindFramebuffer wrap_glBindFramebuffer
-#define glBindFramebufferOES wrap_glBindFramebufferOES
-#define glBindImageTexture wrap_glBindImageTexture
-#define glBindProgramPipeline wrap_glBindProgramPipeline
-#define glBindProgramPipelineEXT wrap_glBindProgramPipelineEXT
-#define glBindRenderbuffer wrap_glBindRenderbuffer
-#define glBindRenderbufferOES wrap_glBindRenderbufferOES
-#define glBindSampler wrap_glBindSampler
-#define glBindTexture wrap_glBindTexture
-#define glBindTransformFeedback wrap_glBindTransformFeedback
-#define glBindVertexArray wrap_glBindVertexArray
-#define glBindVertexArrayOES wrap_glBindVertexArrayOES
-#define glBindVertexBuffer wrap_glBindVertexBuffer
-#define glBlendBarrier wrap_glBlendBarrier
-#define glBlendBarrierKHR wrap_glBlendBarrierKHR
-#define glBlendBarrierNV wrap_glBlendBarrierNV
-#define glBlendColor wrap_glBlendColor
-#define glBlendEquation wrap_glBlendEquation
-#define glBlendEquationOES wrap_glBlendEquationOES
-#define glBlendEquationSeparate wrap_glBlendEquationSeparate
-#define glBlendEquationSeparateOES wrap_glBlendEquationSeparateOES
-#define glBlendEquationSeparatei wrap_glBlendEquationSeparatei
-#define glBlendEquationSeparateiEXT wrap_glBlendEquationSeparateiEXT
-#define glBlendEquationSeparateiOES wrap_glBlendEquationSeparateiOES
-#define glBlendEquationi wrap_glBlendEquationi
-#define glBlendEquationiEXT wrap_glBlendEquationiEXT
-#define glBlendEquationiOES wrap_glBlendEquationiOES
-#define glBlendFunc wrap_glBlendFunc
-#define glBlendFuncSeparate wrap_glBlendFuncSeparate
-#define glBlendFuncSeparateOES wrap_glBlendFuncSeparateOES
-#define glBlendFuncSeparatei wrap_glBlendFuncSeparatei
-#define glBlendFuncSeparateiEXT wrap_glBlendFuncSeparateiEXT
-#define glBlendFuncSeparateiOES wrap_glBlendFuncSeparateiOES
-#define glBlendFunci wrap_glBlendFunci
-#define glBlendFunciEXT wrap_glBlendFunciEXT
-#define glBlendFunciOES wrap_glBlendFunciOES
-#define glBlendParameteriNV wrap_glBlendParameteriNV
-#define glBlitFramebuffer wrap_glBlitFramebuffer
-#define glBlitFramebufferANGLE wrap_glBlitFramebufferANGLE
-#define glBlitFramebufferNV wrap_glBlitFramebufferNV
-#define glBufferData wrap_glBufferData
-#define glBufferStorageEXT wrap_glBufferStorageEXT
-#define glBufferSubData wrap_glBufferSubData
-#define glCheckFramebufferStatus wrap_glCheckFramebufferStatus
-#define glCheckFramebufferStatusOES wrap_glCheckFramebufferStatusOES
-#define glClear wrap_glClear
-#define glClearBufferfi wrap_glClearBufferfi
-#define glClearBufferfv wrap_glClearBufferfv
-#define glClearBufferiv wrap_glClearBufferiv
-#define glClearBufferuiv wrap_glClearBufferuiv
-#define glClearColor wrap_glClearColor
-#define glClearColorx wrap_glClearColorx
-#define glClearColorxOES wrap_glClearColorxOES
-#define glClearDepthf wrap_glClearDepthf
-#define glClearDepthfOES wrap_glClearDepthfOES
-#define glClearDepthx wrap_glClearDepthx
-#define glClearDepthxOES wrap_glClearDepthxOES
-#define glClearStencil wrap_glClearStencil
-#define glClientActiveTexture wrap_glClientActiveTexture
-#define glClientWaitSync wrap_glClientWaitSync
-#define glClientWaitSyncAPPLE wrap_glClientWaitSyncAPPLE
-#define glClipPlanef wrap_glClipPlanef
-#define glClipPlanefIMG wrap_glClipPlanefIMG
-#define glClipPlanefOES wrap_glClipPlanefOES
-#define glClipPlanex wrap_glClipPlanex
-#define glClipPlanexIMG wrap_glClipPlanexIMG
-#define glClipPlanexOES wrap_glClipPlanexOES
-#define glColor4f wrap_glColor4f
-#define glColor4ub wrap_glColor4ub
-#define glColor4x wrap_glColor4x
-#define glColor4xOES wrap_glColor4xOES
-#define glColorMask wrap_glColorMask
-#define glColorMaski wrap_glColorMaski
-#define glColorMaskiEXT wrap_glColorMaskiEXT
-#define glColorMaskiOES wrap_glColorMaskiOES
-#define glColorPointer wrap_glColorPointer
-#define glCompileShader wrap_glCompileShader
-#define glCompressedTexImage2D wrap_glCompressedTexImage2D
-#define glCompressedTexImage3D wrap_glCompressedTexImage3D
-#define glCompressedTexImage3DOES wrap_glCompressedTexImage3DOES
-#define glCompressedTexSubImage2D wrap_glCompressedTexSubImage2D
-#define glCompressedTexSubImage3D wrap_glCompressedTexSubImage3D
-#define glCompressedTexSubImage3DOES wrap_glCompressedTexSubImage3DOES
-#define glCopyBufferSubData wrap_glCopyBufferSubData
-#define glCopyBufferSubDataNV wrap_glCopyBufferSubDataNV
-#define glCopyImageSubData wrap_glCopyImageSubData
-#define glCopyImageSubDataEXT wrap_glCopyImageSubDataEXT
-#define glCopyImageSubDataOES wrap_glCopyImageSubDataOES
-#define glCopyPathNV wrap_glCopyPathNV
-#define glCopyTexImage2D wrap_glCopyTexImage2D
-#define glCopyTexSubImage2D wrap_glCopyTexSubImage2D
-#define glCopyTexSubImage3D wrap_glCopyTexSubImage3D
-#define glCopyTexSubImage3DOES wrap_glCopyTexSubImage3DOES
-#define glCopyTextureLevelsAPPLE wrap_glCopyTextureLevelsAPPLE
-#define glCoverFillPathInstancedNV wrap_glCoverFillPathInstancedNV
-#define glCoverFillPathNV wrap_glCoverFillPathNV
-#define glCoverStrokePathInstancedNV wrap_glCoverStrokePathInstancedNV
-#define glCoverStrokePathNV wrap_glCoverStrokePathNV
-#define glCoverageMaskNV wrap_glCoverageMaskNV
-#define glCoverageModulationNV wrap_glCoverageModulationNV
-#define glCoverageModulationTableNV wrap_glCoverageModulationTableNV
-#define glCoverageOperationNV wrap_glCoverageOperationNV
-#define glCreatePerfQueryINTEL wrap_glCreatePerfQueryINTEL
-#define glCreateProgram wrap_glCreateProgram
-#define glCreateShader wrap_glCreateShader
-#define glCreateShaderProgramv wrap_glCreateShaderProgramv
-#define glCreateShaderProgramvEXT wrap_glCreateShaderProgramvEXT
-#define glCullFace wrap_glCullFace
-#define glCurrentPaletteMatrixOES wrap_glCurrentPaletteMatrixOES
-#define glDebugMessageCallback wrap_glDebugMessageCallback
-#define glDebugMessageCallbackKHR wrap_glDebugMessageCallbackKHR
-#define glDebugMessageControl wrap_glDebugMessageControl
-#define glDebugMessageControlKHR wrap_glDebugMessageControlKHR
-#define glDebugMessageInsert wrap_glDebugMessageInsert
-#define glDebugMessageInsertKHR wrap_glDebugMessageInsertKHR
-#define glDeleteBuffers wrap_glDeleteBuffers
-#define glDeleteFencesNV wrap_glDeleteFencesNV
-#define glDeleteFramebuffers wrap_glDeleteFramebuffers
-#define glDeleteFramebuffersOES wrap_glDeleteFramebuffersOES
-#define glDeletePathsNV wrap_glDeletePathsNV
-#define glDeletePerfMonitorsAMD wrap_glDeletePerfMonitorsAMD
-#define glDeletePerfQueryINTEL wrap_glDeletePerfQueryINTEL
-#define glDeleteProgram wrap_glDeleteProgram
-#define glDeleteProgramPipelines wrap_glDeleteProgramPipelines
-#define glDeleteProgramPipelinesEXT wrap_glDeleteProgramPipelinesEXT
-#define glDeleteQueries wrap_glDeleteQueries
-#define glDeleteQueriesEXT wrap_glDeleteQueriesEXT
-#define glDeleteRenderbuffers wrap_glDeleteRenderbuffers
-#define glDeleteRenderbuffersOES wrap_glDeleteRenderbuffersOES
-#define glDeleteSamplers wrap_glDeleteSamplers
-#define glDeleteShader wrap_glDeleteShader
-#define glDeleteSync wrap_glDeleteSync
-#define glDeleteSyncAPPLE wrap_glDeleteSyncAPPLE
-#define glDeleteTextures wrap_glDeleteTextures
-#define glDeleteTransformFeedbacks wrap_glDeleteTransformFeedbacks
-#define glDeleteVertexArrays wrap_glDeleteVertexArrays
-#define glDeleteVertexArraysOES wrap_glDeleteVertexArraysOES
-#define glDepthFunc wrap_glDepthFunc
-#define glDepthMask wrap_glDepthMask
-#define glDepthRangeArrayfvNV wrap_glDepthRangeArrayfvNV
-#define glDepthRangeIndexedfNV wrap_glDepthRangeIndexedfNV
-#define glDepthRangef wrap_glDepthRangef
-#define glDepthRangefOES wrap_glDepthRangefOES
-#define glDepthRangex wrap_glDepthRangex
-#define glDepthRangexOES wrap_glDepthRangexOES
-#define glDetachShader wrap_glDetachShader
-#define glDisable wrap_glDisable
-#define glDisableClientState wrap_glDisableClientState
-#define glDisableDriverControlQCOM wrap_glDisableDriverControlQCOM
-#define glDisableVertexAttribArray wrap_glDisableVertexAttribArray
-#define glDisablei wrap_glDisablei
-#define glDisableiEXT wrap_glDisableiEXT
-#define glDisableiNV wrap_glDisableiNV
-#define glDisableiOES wrap_glDisableiOES
-#define glDiscardFramebufferEXT wrap_glDiscardFramebufferEXT
-#define glDispatchCompute wrap_glDispatchCompute
-#define glDispatchComputeIndirect wrap_glDispatchComputeIndirect
-#define glDrawArrays wrap_glDrawArrays
-#define glDrawArraysIndirect wrap_glDrawArraysIndirect
-#define glDrawArraysInstanced wrap_glDrawArraysInstanced
-#define glDrawArraysInstancedANGLE wrap_glDrawArraysInstancedANGLE
-#define glDrawArraysInstancedBaseInstanceEXT wrap_glDrawArraysInstancedBaseInstanceEXT
-#define glDrawArraysInstancedEXT wrap_glDrawArraysInstancedEXT
-#define glDrawArraysInstancedNV wrap_glDrawArraysInstancedNV
-#define glDrawBuffers wrap_glDrawBuffers
-#define glDrawBuffersEXT wrap_glDrawBuffersEXT
-#define glDrawBuffersIndexedEXT wrap_glDrawBuffersIndexedEXT
-#define glDrawBuffersNV wrap_glDrawBuffersNV
-#define glDrawElements wrap_glDrawElements
-#define glDrawElementsBaseVertex wrap_glDrawElementsBaseVertex
-#define glDrawElementsBaseVertexEXT wrap_glDrawElementsBaseVertexEXT
-#define glDrawElementsBaseVertexOES wrap_glDrawElementsBaseVertexOES
-#define glDrawElementsIndirect wrap_glDrawElementsIndirect
-#define glDrawElementsInstanced wrap_glDrawElementsInstanced
-#define glDrawElementsInstancedANGLE wrap_glDrawElementsInstancedANGLE
-#define glDrawElementsInstancedBaseInstanceEXT wrap_glDrawElementsInstancedBaseInstanceEXT
-#define glDrawElementsInstancedBaseVertex wrap_glDrawElementsInstancedBaseVertex
-#define glDrawElementsInstancedBaseVertexBaseInstanceEXT \
-    wrap_glDrawElementsInstancedBaseVertexBaseInstanceEXT
-#define glDrawElementsInstancedBaseVertexEXT wrap_glDrawElementsInstancedBaseVertexEXT
-#define glDrawElementsInstancedBaseVertexOES wrap_glDrawElementsInstancedBaseVertexOES
-#define glDrawElementsInstancedEXT wrap_glDrawElementsInstancedEXT
-#define glDrawElementsInstancedNV wrap_glDrawElementsInstancedNV
-#define glDrawRangeElements wrap_glDrawRangeElements
-#define glDrawRangeElementsBaseVertex wrap_glDrawRangeElementsBaseVertex
-#define glDrawRangeElementsBaseVertexEXT wrap_glDrawRangeElementsBaseVertexEXT
-#define glDrawRangeElementsBaseVertexOES wrap_glDrawRangeElementsBaseVertexOES
-#define glDrawTexfOES wrap_glDrawTexfOES
-#define glDrawTexfvOES wrap_glDrawTexfvOES
-#define glDrawTexiOES wrap_glDrawTexiOES
-#define glDrawTexivOES wrap_glDrawTexivOES
-#define glDrawTexsOES wrap_glDrawTexsOES
-#define glDrawTexsvOES wrap_glDrawTexsvOES
-#define glDrawTexxOES wrap_glDrawTexxOES
-#define glDrawTexxvOES wrap_glDrawTexxvOES
-#define glEGLImageTargetRenderbufferStorageOES wrap_glEGLImageTargetRenderbufferStorageOES
-#define glEGLImageTargetTexture2DOES wrap_glEGLImageTargetTexture2DOES
-#define glEnable wrap_glEnable
-#define glEnableClientState wrap_glEnableClientState
-#define glEnableDriverControlQCOM wrap_glEnableDriverControlQCOM
-#define glEnableVertexAttribArray wrap_glEnableVertexAttribArray
-#define glEnablei wrap_glEnablei
-#define glEnableiEXT wrap_glEnableiEXT
-#define glEnableiNV wrap_glEnableiNV
-#define glEnableiOES wrap_glEnableiOES
-#define glEndConditionalRenderNV wrap_glEndConditionalRenderNV
-#define glEndPerfMonitorAMD wrap_glEndPerfMonitorAMD
-#define glEndPerfQueryINTEL wrap_glEndPerfQueryINTEL
-#define glEndQuery wrap_glEndQuery
-#define glEndQueryEXT wrap_glEndQueryEXT
-#define glEndTilingQCOM wrap_glEndTilingQCOM
-#define glEndTransformFeedback wrap_glEndTransformFeedback
-#define glExtGetBufferPointervQCOM wrap_glExtGetBufferPointervQCOM
-#define glExtGetBuffersQCOM wrap_glExtGetBuffersQCOM
-#define glExtGetFramebuffersQCOM wrap_glExtGetFramebuffersQCOM
-#define glExtGetProgramBinarySourceQCOM wrap_glExtGetProgramBinarySourceQCOM
-#define glExtGetProgramsQCOM wrap_glExtGetProgramsQCOM
-#define glExtGetRenderbuffersQCOM wrap_glExtGetRenderbuffersQCOM
-#define glExtGetShadersQCOM wrap_glExtGetShadersQCOM
-#define glExtGetTexLevelParameterivQCOM wrap_glExtGetTexLevelParameterivQCOM
-#define glExtGetTexSubImageQCOM wrap_glExtGetTexSubImageQCOM
-#define glExtGetTexturesQCOM wrap_glExtGetTexturesQCOM
-#define glExtIsProgramBinaryQCOM wrap_glExtIsProgramBinaryQCOM
-#define glExtTexObjectStateOverrideiQCOM wrap_glExtTexObjectStateOverrideiQCOM
-#define glFenceSync wrap_glFenceSync
-#define glFenceSyncAPPLE wrap_glFenceSyncAPPLE
-#define glFinish wrap_glFinish
-#define glFinishFenceNV wrap_glFinishFenceNV
-#define glFlush wrap_glFlush
-#define glFlushMappedBufferRange wrap_glFlushMappedBufferRange
-#define glFlushMappedBufferRangeEXT wrap_glFlushMappedBufferRangeEXT
-#define glFogf wrap_glFogf
-#define glFogfv wrap_glFogfv
-#define glFogx wrap_glFogx
-#define glFogxOES wrap_glFogxOES
-#define glFogxv wrap_glFogxv
-#define glFogxvOES wrap_glFogxvOES
-#define glFragmentCoverageColorNV wrap_glFragmentCoverageColorNV
-#define glFramebufferParameteri wrap_glFramebufferParameteri
-#define glFramebufferRenderbuffer wrap_glFramebufferRenderbuffer
-#define glFramebufferRenderbufferOES wrap_glFramebufferRenderbufferOES
-#define glFramebufferSampleLocationsfvNV wrap_glFramebufferSampleLocationsfvNV
-#define glFramebufferTexture wrap_glFramebufferTexture
-#define glFramebufferTexture2D wrap_glFramebufferTexture2D
-#define glFramebufferTexture2DMultisampleEXT wrap_glFramebufferTexture2DMultisampleEXT
-#define glFramebufferTexture2DMultisampleIMG wrap_glFramebufferTexture2DMultisampleIMG
-#define glFramebufferTexture2DOES wrap_glFramebufferTexture2DOES
-#define glFramebufferTexture3DOES wrap_glFramebufferTexture3DOES
-#define glFramebufferTextureEXT wrap_glFramebufferTextureEXT
-#define glFramebufferTextureLayer wrap_glFramebufferTextureLayer
-#define glFramebufferTextureMultisampleMultiviewOVR wrap_glFramebufferTextureMultisampleMultiviewOVR
-#define glFramebufferTextureMultiviewOVR wrap_glFramebufferTextureMultiviewOVR
-#define glFramebufferTextureOES wrap_glFramebufferTextureOES
-#define glFrontFace wrap_glFrontFace
-#define glFrustumf wrap_glFrustumf
-#define glFrustumfOES wrap_glFrustumfOES
-#define glFrustumx wrap_glFrustumx
-#define glFrustumxOES wrap_glFrustumxOES
-#define glGenBuffers wrap_glGenBuffers
-#define glGenFencesNV wrap_glGenFencesNV
-#define glGenFramebuffers wrap_glGenFramebuffers
-#define glGenFramebuffersOES wrap_glGenFramebuffersOES
-#define glGenPathsNV wrap_glGenPathsNV
-#define glGenPerfMonitorsAMD wrap_glGenPerfMonitorsAMD
-#define glGenProgramPipelines wrap_glGenProgramPipelines
-#define glGenProgramPipelinesEXT wrap_glGenProgramPipelinesEXT
-#define glGenQueries wrap_glGenQueries
-#define glGenQueriesEXT wrap_glGenQueriesEXT
-#define glGenRenderbuffers wrap_glGenRenderbuffers
-#define glGenRenderbuffersOES wrap_glGenRenderbuffersOES
-#define glGenSamplers wrap_glGenSamplers
-#define glGenTextures wrap_glGenTextures
-#define glGenTransformFeedbacks wrap_glGenTransformFeedbacks
-#define glGenVertexArrays wrap_glGenVertexArrays
-#define glGenVertexArraysOES wrap_glGenVertexArraysOES
-#define glGenerateMipmap wrap_glGenerateMipmap
-#define glGenerateMipmapOES wrap_glGenerateMipmapOES
-#define glGetActiveAttrib wrap_glGetActiveAttrib
-#define glGetActiveUniform wrap_glGetActiveUniform
-#define glGetActiveUniformBlockName wrap_glGetActiveUniformBlockName
-#define glGetActiveUniformBlockiv wrap_glGetActiveUniformBlockiv
-#define glGetActiveUniformsiv wrap_glGetActiveUniformsiv
-#define glGetAttachedShaders wrap_glGetAttachedShaders
-#define glGetAttribLocation wrap_glGetAttribLocation
-#define glGetBooleani_v wrap_glGetBooleani_v
-#define glGetBooleanv wrap_glGetBooleanv
-#define glGetBufferParameteri64v wrap_glGetBufferParameteri64v
-#define glGetBufferParameteriv wrap_glGetBufferParameteriv
-#define glGetBufferPointerv wrap_glGetBufferPointerv
-#define glGetBufferPointervOES wrap_glGetBufferPointervOES
-#define glGetClipPlanef wrap_glGetClipPlanef
-#define glGetClipPlanefOES wrap_glGetClipPlanefOES
-#define glGetClipPlanex wrap_glGetClipPlanex
-#define glGetClipPlanexOES wrap_glGetClipPlanexOES
-#define glGetCoverageModulationTableNV wrap_glGetCoverageModulationTableNV
-#define glGetDebugMessageLog wrap_glGetDebugMessageLog
-#define glGetDebugMessageLogKHR wrap_glGetDebugMessageLogKHR
-#define glGetDriverControlStringQCOM wrap_glGetDriverControlStringQCOM
-#define glGetDriverControlsQCOM wrap_glGetDriverControlsQCOM
-#define glGetError wrap_glGetError
-#define glGetFenceivNV wrap_glGetFenceivNV
-#define glGetFirstPerfQueryIdINTEL wrap_glGetFirstPerfQueryIdINTEL
-#define glGetFixedv wrap_glGetFixedv
-#define glGetFixedvOES wrap_glGetFixedvOES
-#define glGetFloati_vNV wrap_glGetFloati_vNV
-#define glGetFloatv wrap_glGetFloatv
-#define glGetFragDataIndexEXT wrap_glGetFragDataIndexEXT
-#define glGetFragDataLocation wrap_glGetFragDataLocation
-#define glGetFramebufferAttachmentParameteriv wrap_glGetFramebufferAttachmentParameteriv
-#define glGetFramebufferAttachmentParameterivOES wrap_glGetFramebufferAttachmentParameterivOES
-#define glGetFramebufferParameteriv wrap_glGetFramebufferParameteriv
-#define glGetGraphicsResetStatus wrap_glGetGraphicsResetStatus
-#define glGetGraphicsResetStatusEXT wrap_glGetGraphicsResetStatusEXT
-#define glGetGraphicsResetStatusKHR wrap_glGetGraphicsResetStatusKHR
-#define glGetImageHandleNV wrap_glGetImageHandleNV
-#define glGetInteger64i_v wrap_glGetInteger64i_v
-#define glGetInteger64v wrap_glGetInteger64v
-#define glGetInteger64vAPPLE wrap_glGetInteger64vAPPLE
-#define glGetIntegeri_v wrap_glGetIntegeri_v
-#define glGetIntegeri_vEXT wrap_glGetIntegeri_vEXT
-#define glGetIntegerv wrap_glGetIntegerv
-#define glGetInternalformatSampleivNV wrap_glGetInternalformatSampleivNV
-#define glGetInternalformativ wrap_glGetInternalformativ
-#define glGetLightfv wrap_glGetLightfv
-#define glGetLightxv wrap_glGetLightxv
-#define glGetLightxvOES wrap_glGetLightxvOES
-#define glGetMaterialfv wrap_glGetMaterialfv
-#define glGetMaterialxv wrap_glGetMaterialxv
-#define glGetMaterialxvOES wrap_glGetMaterialxvOES
-#define glGetMultisamplefv wrap_glGetMultisamplefv
-#define glGetNextPerfQueryIdINTEL wrap_glGetNextPerfQueryIdINTEL
-#define glGetObjectLabel wrap_glGetObjectLabel
-#define glGetObjectLabelEXT wrap_glGetObjectLabelEXT
-#define glGetObjectLabelKHR wrap_glGetObjectLabelKHR
-#define glGetObjectPtrLabel wrap_glGetObjectPtrLabel
-#define glGetObjectPtrLabelKHR wrap_glGetObjectPtrLabelKHR
-#define glGetPathCommandsNV wrap_glGetPathCommandsNV
-#define glGetPathCoordsNV wrap_glGetPathCoordsNV
-#define glGetPathDashArrayNV wrap_glGetPathDashArrayNV
-#define glGetPathLengthNV wrap_glGetPathLengthNV
-#define glGetPathMetricRangeNV wrap_glGetPathMetricRangeNV
-#define glGetPathMetricsNV wrap_glGetPathMetricsNV
-#define glGetPathParameterfvNV wrap_glGetPathParameterfvNV
-#define glGetPathParameterivNV wrap_glGetPathParameterivNV
-#define glGetPathSpacingNV wrap_glGetPathSpacingNV
-#define glGetPerfCounterInfoINTEL wrap_glGetPerfCounterInfoINTEL
-#define glGetPerfMonitorCounterDataAMD wrap_glGetPerfMonitorCounterDataAMD
-#define glGetPerfMonitorCounterInfoAMD wrap_glGetPerfMonitorCounterInfoAMD
-#define glGetPerfMonitorCounterStringAMD wrap_glGetPerfMonitorCounterStringAMD
-#define glGetPerfMonitorCountersAMD wrap_glGetPerfMonitorCountersAMD
-#define glGetPerfMonitorGroupStringAMD wrap_glGetPerfMonitorGroupStringAMD
-#define glGetPerfMonitorGroupsAMD wrap_glGetPerfMonitorGroupsAMD
-#define glGetPerfQueryDataINTEL wrap_glGetPerfQueryDataINTEL
-#define glGetPerfQueryIdByNameINTEL wrap_glGetPerfQueryIdByNameINTEL
-#define glGetPerfQueryInfoINTEL wrap_glGetPerfQueryInfoINTEL
-#define glGetPointerv wrap_glGetPointerv
-#define glGetPointervKHR wrap_glGetPointervKHR
-#define glGetProgramBinary wrap_glGetProgramBinary
-#define glGetProgramBinaryOES wrap_glGetProgramBinaryOES
-#define glGetProgramInfoLog wrap_glGetProgramInfoLog
-#define glGetProgramInterfaceiv wrap_glGetProgramInterfaceiv
-#define glGetProgramPipelineInfoLog wrap_glGetProgramPipelineInfoLog
-#define glGetProgramPipelineInfoLogEXT wrap_glGetProgramPipelineInfoLogEXT
-#define glGetProgramPipelineiv wrap_glGetProgramPipelineiv
-#define glGetProgramPipelineivEXT wrap_glGetProgramPipelineivEXT
-#define glGetProgramResourceIndex wrap_glGetProgramResourceIndex
-#define glGetProgramResourceLocation wrap_glGetProgramResourceLocation
-#define glGetProgramResourceLocationIndexEXT wrap_glGetProgramResourceLocationIndexEXT
-#define glGetProgramResourceName wrap_glGetProgramResourceName
-#define glGetProgramResourcefvNV wrap_glGetProgramResourcefvNV
-#define glGetProgramResourceiv wrap_glGetProgramResourceiv
-#define glGetProgramiv wrap_glGetProgramiv
-#define glGetQueryObjecti64vEXT wrap_glGetQueryObjecti64vEXT
-#define glGetQueryObjectivEXT wrap_glGetQueryObjectivEXT
-#define glGetQueryObjectui64vEXT wrap_glGetQueryObjectui64vEXT
-#define glGetQueryObjectuiv wrap_glGetQueryObjectuiv
-#define glGetQueryObjectuivEXT wrap_glGetQueryObjectuivEXT
-#define glGetQueryiv wrap_glGetQueryiv
-#define glGetQueryivEXT wrap_glGetQueryivEXT
-#define glGetRenderbufferParameteriv wrap_glGetRenderbufferParameteriv
-#define glGetRenderbufferParameterivOES wrap_glGetRenderbufferParameterivOES
-#define glGetSamplerParameterIiv wrap_glGetSamplerParameterIiv
-#define glGetSamplerParameterIivEXT wrap_glGetSamplerParameterIivEXT
-#define glGetSamplerParameterIivOES wrap_glGetSamplerParameterIivOES
-#define glGetSamplerParameterIuiv wrap_glGetSamplerParameterIuiv
-#define glGetSamplerParameterIuivEXT wrap_glGetSamplerParameterIuivEXT
-#define glGetSamplerParameterIuivOES wrap_glGetSamplerParameterIuivOES
-#define glGetSamplerParameterfv wrap_glGetSamplerParameterfv
-#define glGetSamplerParameteriv wrap_glGetSamplerParameteriv
-#define glGetShaderInfoLog wrap_glGetShaderInfoLog
-#define glGetShaderPrecisionFormat wrap_glGetShaderPrecisionFormat
-#define glGetShaderSource wrap_glGetShaderSource
-#define glGetShaderiv wrap_glGetShaderiv
-#define glGetString wrap_glGetString
-#define glGetStringi wrap_glGetStringi
-#define glGetSynciv wrap_glGetSynciv
-#define glGetSyncivAPPLE wrap_glGetSyncivAPPLE
-#define glGetTexEnvfv wrap_glGetTexEnvfv
-#define glGetTexEnviv wrap_glGetTexEnviv
-#define glGetTexEnvxv wrap_glGetTexEnvxv
-#define glGetTexEnvxvOES wrap_glGetTexEnvxvOES
-#define glGetTexGenfvOES wrap_glGetTexGenfvOES
-#define glGetTexGenivOES wrap_glGetTexGenivOES
-#define glGetTexGenxvOES wrap_glGetTexGenxvOES
-#define glGetTexLevelParameterfv wrap_glGetTexLevelParameterfv
-#define glGetTexLevelParameteriv wrap_glGetTexLevelParameteriv
-#define glGetTexParameterIiv wrap_glGetTexParameterIiv
-#define glGetTexParameterIivEXT wrap_glGetTexParameterIivEXT
-#define glGetTexParameterIivOES wrap_glGetTexParameterIivOES
-#define glGetTexParameterIuiv wrap_glGetTexParameterIuiv
-#define glGetTexParameterIuivEXT wrap_glGetTexParameterIuivEXT
-#define glGetTexParameterIuivOES wrap_glGetTexParameterIuivOES
-#define glGetTexParameterfv wrap_glGetTexParameterfv
-#define glGetTexParameteriv wrap_glGetTexParameteriv
-#define glGetTexParameterxv wrap_glGetTexParameterxv
-#define glGetTexParameterxvOES wrap_glGetTexParameterxvOES
-#define glGetTextureHandleNV wrap_glGetTextureHandleNV
-#define glGetTextureSamplerHandleNV wrap_glGetTextureSamplerHandleNV
-#define glGetTransformFeedbackVarying wrap_glGetTransformFeedbackVarying
-#define glGetTranslatedShaderSourceANGLE wrap_glGetTranslatedShaderSourceANGLE
-#define glGetUniformBlockIndex wrap_glGetUniformBlockIndex
-#define glGetUniformIndices wrap_glGetUniformIndices
-#define glGetUniformLocation wrap_glGetUniformLocation
-#define glGetUniformfv wrap_glGetUniformfv
-#define glGetUniformiv wrap_glGetUniformiv
-#define glGetUniformuiv wrap_glGetUniformuiv
-#define glGetVertexAttribIiv wrap_glGetVertexAttribIiv
-#define glGetVertexAttribIuiv wrap_glGetVertexAttribIuiv
-#define glGetVertexAttribPointerv wrap_glGetVertexAttribPointerv
-#define glGetVertexAttribfv wrap_glGetVertexAttribfv
-#define glGetVertexAttribiv wrap_glGetVertexAttribiv
-#define glGetnUniformfv wrap_glGetnUniformfv
-#define glGetnUniformfvEXT wrap_glGetnUniformfvEXT
-#define glGetnUniformfvKHR wrap_glGetnUniformfvKHR
-#define glGetnUniformiv wrap_glGetnUniformiv
-#define glGetnUniformivEXT wrap_glGetnUniformivEXT
-#define glGetnUniformivKHR wrap_glGetnUniformivKHR
-#define glGetnUniformuiv wrap_glGetnUniformuiv
-#define glGetnUniformuivKHR wrap_glGetnUniformuivKHR
-#define glHint wrap_glHint
-#define glInsertEventMarkerEXT wrap_glInsertEventMarkerEXT
-#define glInterpolatePathsNV wrap_glInterpolatePathsNV
-#define glInvalidateFramebuffer wrap_glInvalidateFramebuffer
-#define glInvalidateSubFramebuffer wrap_glInvalidateSubFramebuffer
-#define glIsBuffer wrap_glIsBuffer
-#define glIsEnabled wrap_glIsEnabled
-#define glIsEnabledi wrap_glIsEnabledi
-#define glIsEnablediEXT wrap_glIsEnablediEXT
-#define glIsEnablediNV wrap_glIsEnablediNV
-#define glIsEnablediOES wrap_glIsEnablediOES
-#define glIsFenceNV wrap_glIsFenceNV
-#define glIsFramebuffer wrap_glIsFramebuffer
-#define glIsFramebufferOES wrap_glIsFramebufferOES
-#define glIsImageHandleResidentNV wrap_glIsImageHandleResidentNV
-#define glIsPathNV wrap_glIsPathNV
-#define glIsPointInFillPathNV wrap_glIsPointInFillPathNV
-#define glIsPointInStrokePathNV wrap_glIsPointInStrokePathNV
-#define glIsProgram wrap_glIsProgram
-#define glIsProgramPipeline wrap_glIsProgramPipeline
-#define glIsProgramPipelineEXT wrap_glIsProgramPipelineEXT
-#define glIsQuery wrap_glIsQuery
-#define glIsQueryEXT wrap_glIsQueryEXT
-#define glIsRenderbuffer wrap_glIsRenderbuffer
-#define glIsRenderbufferOES wrap_glIsRenderbufferOES
-#define glIsSampler wrap_glIsSampler
-#define glIsShader wrap_glIsShader
-#define glIsSync wrap_glIsSync
-#define glIsSyncAPPLE wrap_glIsSyncAPPLE
-#define glIsTexture wrap_glIsTexture
-#define glIsTextureHandleResidentNV wrap_glIsTextureHandleResidentNV
-#define glIsTransformFeedback wrap_glIsTransformFeedback
-#define glIsVertexArray wrap_glIsVertexArray
-#define glIsVertexArrayOES wrap_glIsVertexArrayOES
-#define glLabelObjectEXT wrap_glLabelObjectEXT
-#define glLightModelf wrap_glLightModelf
-#define glLightModelfv wrap_glLightModelfv
-#define glLightModelx wrap_glLightModelx
-#define glLightModelxOES wrap_glLightModelxOES
-#define glLightModelxv wrap_glLightModelxv
-#define glLightModelxvOES wrap_glLightModelxvOES
-#define glLightf wrap_glLightf
-#define glLightfv wrap_glLightfv
-#define glLightx wrap_glLightx
-#define glLightxOES wrap_glLightxOES
-#define glLightxv wrap_glLightxv
-#define glLightxvOES wrap_glLightxvOES
-#define glLineWidth wrap_glLineWidth
-#define glLineWidthx wrap_glLineWidthx
-#define glLineWidthxOES wrap_glLineWidthxOES
-#define glLinkProgram wrap_glLinkProgram
-#define glLoadIdentity wrap_glLoadIdentity
-#define glLoadMatrixf wrap_glLoadMatrixf
-#define glLoadMatrixx wrap_glLoadMatrixx
-#define glLoadMatrixxOES wrap_glLoadMatrixxOES
-#define glLoadPaletteFromModelViewMatrixOES wrap_glLoadPaletteFromModelViewMatrixOES
-#define glLogicOp wrap_glLogicOp
-#define glMakeImageHandleNonResidentNV wrap_glMakeImageHandleNonResidentNV
-#define glMakeImageHandleResidentNV wrap_glMakeImageHandleResidentNV
-#define glMakeTextureHandleNonResidentNV wrap_glMakeTextureHandleNonResidentNV
-#define glMakeTextureHandleResidentNV wrap_glMakeTextureHandleResidentNV
-#define glMapBufferOES wrap_glMapBufferOES
-#define glMapBufferRange wrap_glMapBufferRange
-#define glMapBufferRangeEXT wrap_glMapBufferRangeEXT
-#define glMaterialf wrap_glMaterialf
-#define glMaterialfv wrap_glMaterialfv
-#define glMaterialx wrap_glMaterialx
-#define glMaterialxOES wrap_glMaterialxOES
-#define glMaterialxv wrap_glMaterialxv
-#define glMaterialxvOES wrap_glMaterialxvOES
-#define glMatrixIndexPointerOES wrap_glMatrixIndexPointerOES
-#define glMatrixLoad3x2fNV wrap_glMatrixLoad3x2fNV
-#define glMatrixLoad3x3fNV wrap_glMatrixLoad3x3fNV
-#define glMatrixLoadTranspose3x3fNV wrap_glMatrixLoadTranspose3x3fNV
-#define glMatrixMode wrap_glMatrixMode
-#define glMatrixMult3x2fNV wrap_glMatrixMult3x2fNV
-#define glMatrixMult3x3fNV wrap_glMatrixMult3x3fNV
-#define glMatrixMultTranspose3x3fNV wrap_glMatrixMultTranspose3x3fNV
-#define glMemoryBarrier wrap_glMemoryBarrier
-#define glMemoryBarrierByRegion wrap_glMemoryBarrierByRegion
-#define glMinSampleShading wrap_glMinSampleShading
-#define glMinSampleShadingOES wrap_glMinSampleShadingOES
-#define glMultMatrixf wrap_glMultMatrixf
-#define glMultMatrixx wrap_glMultMatrixx
-#define glMultMatrixxOES wrap_glMultMatrixxOES
-#define glMultiDrawArraysEXT wrap_glMultiDrawArraysEXT
-#define glMultiDrawArraysIndirectEXT wrap_glMultiDrawArraysIndirectEXT
-#define glMultiDrawElementsBaseVertexEXT wrap_glMultiDrawElementsBaseVertexEXT
-#define glMultiDrawElementsBaseVertexOES wrap_glMultiDrawElementsBaseVertexOES
-#define glMultiDrawElementsEXT wrap_glMultiDrawElementsEXT
-#define glMultiDrawElementsIndirectEXT wrap_glMultiDrawElementsIndirectEXT
-#define glMultiTexCoord4f wrap_glMultiTexCoord4f
-#define glMultiTexCoord4x wrap_glMultiTexCoord4x
-#define glMultiTexCoord4xOES wrap_glMultiTexCoord4xOES
-#define glNamedFramebufferSampleLocationsfvNV wrap_glNamedFramebufferSampleLocationsfvNV
-#define glNormal3f wrap_glNormal3f
-#define glNormal3x wrap_glNormal3x
-#define glNormal3xOES wrap_glNormal3xOES
-#define glNormalPointer wrap_glNormalPointer
-#define glObjectLabel wrap_glObjectLabel
-#define glObjectLabelKHR wrap_glObjectLabelKHR
-#define glObjectPtrLabel wrap_glObjectPtrLabel
-#define glObjectPtrLabelKHR wrap_glObjectPtrLabelKHR
-#define glOrthof wrap_glOrthof
-#define glOrthofOES wrap_glOrthofOES
-#define glOrthox wrap_glOrthox
-#define glOrthoxOES wrap_glOrthoxOES
-#define glPatchParameteri wrap_glPatchParameteri
-#define glPatchParameteriEXT wrap_glPatchParameteriEXT
-#define glPatchParameteriOES wrap_glPatchParameteriOES
-#define glPathCommandsNV wrap_glPathCommandsNV
-#define glPathCoordsNV wrap_glPathCoordsNV
-#define glPathCoverDepthFuncNV wrap_glPathCoverDepthFuncNV
-#define glPathDashArrayNV wrap_glPathDashArrayNV
-#define glPathGlyphIndexArrayNV wrap_glPathGlyphIndexArrayNV
-#define glPathGlyphIndexRangeNV wrap_glPathGlyphIndexRangeNV
-#define glPathGlyphRangeNV wrap_glPathGlyphRangeNV
-#define glPathGlyphsNV wrap_glPathGlyphsNV
-#define glPathMemoryGlyphIndexArrayNV wrap_glPathMemoryGlyphIndexArrayNV
-#define glPathParameterfNV wrap_glPathParameterfNV
-#define glPathParameterfvNV wrap_glPathParameterfvNV
-#define glPathParameteriNV wrap_glPathParameteriNV
-#define glPathParameterivNV wrap_glPathParameterivNV
-#define glPathStencilDepthOffsetNV wrap_glPathStencilDepthOffsetNV
-#define glPathStencilFuncNV wrap_glPathStencilFuncNV
-#define glPathStringNV wrap_glPathStringNV
-#define glPathSubCommandsNV wrap_glPathSubCommandsNV
-#define glPathSubCoordsNV wrap_glPathSubCoordsNV
-#define glPauseTransformFeedback wrap_glPauseTransformFeedback
-#define glPixelStorei wrap_glPixelStorei
-#define glPointAlongPathNV wrap_glPointAlongPathNV
-#define glPointParameterf wrap_glPointParameterf
-#define glPointParameterfv wrap_glPointParameterfv
-#define glPointParameterx wrap_glPointParameterx
-#define glPointParameterxOES wrap_glPointParameterxOES
-#define glPointParameterxv wrap_glPointParameterxv
-#define glPointParameterxvOES wrap_glPointParameterxvOES
-#define glPointSize wrap_glPointSize
-#define glPointSizePointerOES wrap_glPointSizePointerOES
-#define glPointSizex wrap_glPointSizex
-#define glPointSizexOES wrap_glPointSizexOES
-#define glPolygonModeNV wrap_glPolygonModeNV
-#define glPolygonOffset wrap_glPolygonOffset
-#define glPolygonOffsetx wrap_glPolygonOffsetx
-#define glPolygonOffsetxOES wrap_glPolygonOffsetxOES
-#define glPopDebugGroup wrap_glPopDebugGroup
-#define glPopDebugGroupKHR wrap_glPopDebugGroupKHR
-#define glPopGroupMarkerEXT wrap_glPopGroupMarkerEXT
-#define glPopMatrix wrap_glPopMatrix
-#define glPrimitiveBoundingBox wrap_glPrimitiveBoundingBox
-#define glPrimitiveBoundingBoxEXT wrap_glPrimitiveBoundingBoxEXT
-#define glPrimitiveBoundingBoxOES wrap_glPrimitiveBoundingBoxOES
-#define glProgramBinary wrap_glProgramBinary
-#define glProgramBinaryOES wrap_glProgramBinaryOES
-#define glProgramParameteri wrap_glProgramParameteri
-#define glProgramParameteriEXT wrap_glProgramParameteriEXT
-#define glProgramPathFragmentInputGenNV wrap_glProgramPathFragmentInputGenNV
-#define glProgramUniform1f wrap_glProgramUniform1f
-#define glProgramUniform1fEXT wrap_glProgramUniform1fEXT
-#define glProgramUniform1fv wrap_glProgramUniform1fv
-#define glProgramUniform1fvEXT wrap_glProgramUniform1fvEXT
-#define glProgramUniform1i wrap_glProgramUniform1i
-#define glProgramUniform1iEXT wrap_glProgramUniform1iEXT
-#define glProgramUniform1iv wrap_glProgramUniform1iv
-#define glProgramUniform1ivEXT wrap_glProgramUniform1ivEXT
-#define glProgramUniform1ui wrap_glProgramUniform1ui
-#define glProgramUniform1uiEXT wrap_glProgramUniform1uiEXT
-#define glProgramUniform1uiv wrap_glProgramUniform1uiv
-#define glProgramUniform1uivEXT wrap_glProgramUniform1uivEXT
-#define glProgramUniform2f wrap_glProgramUniform2f
-#define glProgramUniform2fEXT wrap_glProgramUniform2fEXT
-#define glProgramUniform2fv wrap_glProgramUniform2fv
-#define glProgramUniform2fvEXT wrap_glProgramUniform2fvEXT
-#define glProgramUniform2i wrap_glProgramUniform2i
-#define glProgramUniform2iEXT wrap_glProgramUniform2iEXT
-#define glProgramUniform2iv wrap_glProgramUniform2iv
-#define glProgramUniform2ivEXT wrap_glProgramUniform2ivEXT
-#define glProgramUniform2ui wrap_glProgramUniform2ui
-#define glProgramUniform2uiEXT wrap_glProgramUniform2uiEXT
-#define glProgramUniform2uiv wrap_glProgramUniform2uiv
-#define glProgramUniform2uivEXT wrap_glProgramUniform2uivEXT
-#define glProgramUniform3f wrap_glProgramUniform3f
-#define glProgramUniform3fEXT wrap_glProgramUniform3fEXT
-#define glProgramUniform3fv wrap_glProgramUniform3fv
-#define glProgramUniform3fvEXT wrap_glProgramUniform3fvEXT
-#define glProgramUniform3i wrap_glProgramUniform3i
-#define glProgramUniform3iEXT wrap_glProgramUniform3iEXT
-#define glProgramUniform3iv wrap_glProgramUniform3iv
-#define glProgramUniform3ivEXT wrap_glProgramUniform3ivEXT
-#define glProgramUniform3ui wrap_glProgramUniform3ui
-#define glProgramUniform3uiEXT wrap_glProgramUniform3uiEXT
-#define glProgramUniform3uiv wrap_glProgramUniform3uiv
-#define glProgramUniform3uivEXT wrap_glProgramUniform3uivEXT
-#define glProgramUniform4f wrap_glProgramUniform4f
-#define glProgramUniform4fEXT wrap_glProgramUniform4fEXT
-#define glProgramUniform4fv wrap_glProgramUniform4fv
-#define glProgramUniform4fvEXT wrap_glProgramUniform4fvEXT
-#define glProgramUniform4i wrap_glProgramUniform4i
-#define glProgramUniform4iEXT wrap_glProgramUniform4iEXT
-#define glProgramUniform4iv wrap_glProgramUniform4iv
-#define glProgramUniform4ivEXT wrap_glProgramUniform4ivEXT
-#define glProgramUniform4ui wrap_glProgramUniform4ui
-#define glProgramUniform4uiEXT wrap_glProgramUniform4uiEXT
-#define glProgramUniform4uiv wrap_glProgramUniform4uiv
-#define glProgramUniform4uivEXT wrap_glProgramUniform4uivEXT
-#define glProgramUniformHandleui64NV wrap_glProgramUniformHandleui64NV
-#define glProgramUniformHandleui64vNV wrap_glProgramUniformHandleui64vNV
-#define glProgramUniformMatrix2fv wrap_glProgramUniformMatrix2fv
-#define glProgramUniformMatrix2fvEXT wrap_glProgramUniformMatrix2fvEXT
-#define glProgramUniformMatrix2x3fv wrap_glProgramUniformMatrix2x3fv
-#define glProgramUniformMatrix2x3fvEXT wrap_glProgramUniformMatrix2x3fvEXT
-#define glProgramUniformMatrix2x4fv wrap_glProgramUniformMatrix2x4fv
-#define glProgramUniformMatrix2x4fvEXT wrap_glProgramUniformMatrix2x4fvEXT
-#define glProgramUniformMatrix3fv wrap_glProgramUniformMatrix3fv
-#define glProgramUniformMatrix3fvEXT wrap_glProgramUniformMatrix3fvEXT
-#define glProgramUniformMatrix3x2fv wrap_glProgramUniformMatrix3x2fv
-#define glProgramUniformMatrix3x2fvEXT wrap_glProgramUniformMatrix3x2fvEXT
-#define glProgramUniformMatrix3x4fv wrap_glProgramUniformMatrix3x4fv
-#define glProgramUniformMatrix3x4fvEXT wrap_glProgramUniformMatrix3x4fvEXT
-#define glProgramUniformMatrix4fv wrap_glProgramUniformMatrix4fv
-#define glProgramUniformMatrix4fvEXT wrap_glProgramUniformMatrix4fvEXT
-#define glProgramUniformMatrix4x2fv wrap_glProgramUniformMatrix4x2fv
-#define glProgramUniformMatrix4x2fvEXT wrap_glProgramUniformMatrix4x2fvEXT
-#define glProgramUniformMatrix4x3fv wrap_glProgramUniformMatrix4x3fv
-#define glProgramUniformMatrix4x3fvEXT wrap_glProgramUniformMatrix4x3fvEXT
-#define glPushDebugGroup wrap_glPushDebugGroup
-#define glPushDebugGroupKHR wrap_glPushDebugGroupKHR
-#define glPushGroupMarkerEXT wrap_glPushGroupMarkerEXT
-#define glPushMatrix wrap_glPushMatrix
-#define glQueryCounterEXT wrap_glQueryCounterEXT
-#define glQueryMatrixxOES wrap_glQueryMatrixxOES
-#define glRasterSamplesEXT wrap_glRasterSamplesEXT
-#define glReadBuffer wrap_glReadBuffer
-#define glReadBufferIndexedEXT wrap_glReadBufferIndexedEXT
-#define glReadBufferNV wrap_glReadBufferNV
-#define glReadPixels wrap_glReadPixels
-#define glReadnPixels wrap_glReadnPixels
-#define glReadnPixelsEXT wrap_glReadnPixelsEXT
-#define glReadnPixelsKHR wrap_glReadnPixelsKHR
-#define glReleaseShaderCompiler wrap_glReleaseShaderCompiler
-#define glRenderbufferStorage wrap_glRenderbufferStorage
-#define glRenderbufferStorageMultisample wrap_glRenderbufferStorageMultisample
-#define glRenderbufferStorageMultisampleANGLE wrap_glRenderbufferStorageMultisampleANGLE
-#define glRenderbufferStorageMultisampleAPPLE wrap_glRenderbufferStorageMultisampleAPPLE
-#define glRenderbufferStorageMultisampleEXT wrap_glRenderbufferStorageMultisampleEXT
-#define glRenderbufferStorageMultisampleIMG wrap_glRenderbufferStorageMultisampleIMG
-#define glRenderbufferStorageMultisampleNV wrap_glRenderbufferStorageMultisampleNV
-#define glRenderbufferStorageOES wrap_glRenderbufferStorageOES
-#define glResolveDepthValuesNV wrap_glResolveDepthValuesNV
-#define glResolveMultisampleFramebufferAPPLE wrap_glResolveMultisampleFramebufferAPPLE
-#define glResumeTransformFeedback wrap_glResumeTransformFeedback
-#define glRotatef wrap_glRotatef
-#define glRotatex wrap_glRotatex
-#define glRotatexOES wrap_glRotatexOES
-#define glSampleCoverage wrap_glSampleCoverage
-#define glSampleCoveragex wrap_glSampleCoveragex
-#define glSampleCoveragexOES wrap_glSampleCoveragexOES
-#define glSampleMaski wrap_glSampleMaski
-#define glSamplerParameterIiv wrap_glSamplerParameterIiv
-#define glSamplerParameterIivEXT wrap_glSamplerParameterIivEXT
-#define glSamplerParameterIivOES wrap_glSamplerParameterIivOES
-#define glSamplerParameterIuiv wrap_glSamplerParameterIuiv
-#define glSamplerParameterIuivEXT wrap_glSamplerParameterIuivEXT
-#define glSamplerParameterIuivOES wrap_glSamplerParameterIuivOES
-#define glSamplerParameterf wrap_glSamplerParameterf
-#define glSamplerParameterfv wrap_glSamplerParameterfv
-#define glSamplerParameteri wrap_glSamplerParameteri
-#define glSamplerParameteriv wrap_glSamplerParameteriv
-#define glScalef wrap_glScalef
-#define glScalex wrap_glScalex
-#define glScalexOES wrap_glScalexOES
-#define glScissor wrap_glScissor
-#define glScissorArrayvNV wrap_glScissorArrayvNV
-#define glScissorIndexedNV wrap_glScissorIndexedNV
-#define glScissorIndexedvNV wrap_glScissorIndexedvNV
-#define glSelectPerfMonitorCountersAMD wrap_glSelectPerfMonitorCountersAMD
-#define glSetFenceNV wrap_glSetFenceNV
-#define glShadeModel wrap_glShadeModel
-#define glShaderBinary wrap_glShaderBinary
-#define glShaderSource wrap_glShaderSource
-#define glStartTilingQCOM wrap_glStartTilingQCOM
-#define glStencilFillPathInstancedNV wrap_glStencilFillPathInstancedNV
-#define glStencilFillPathNV wrap_glStencilFillPathNV
-#define glStencilFunc wrap_glStencilFunc
-#define glStencilFuncSeparate wrap_glStencilFuncSeparate
-#define glStencilMask wrap_glStencilMask
-#define glStencilMaskSeparate wrap_glStencilMaskSeparate
-#define glStencilOp wrap_glStencilOp
-#define glStencilOpSeparate wrap_glStencilOpSeparate
-#define glStencilStrokePathInstancedNV wrap_glStencilStrokePathInstancedNV
-#define glStencilStrokePathNV wrap_glStencilStrokePathNV
-#define glStencilThenCoverFillPathInstancedNV wrap_glStencilThenCoverFillPathInstancedNV
-#define glStencilThenCoverFillPathNV wrap_glStencilThenCoverFillPathNV
-#define glStencilThenCoverStrokePathInstancedNV wrap_glStencilThenCoverStrokePathInstancedNV
-#define glStencilThenCoverStrokePathNV wrap_glStencilThenCoverStrokePathNV
-#define glSubpixelPrecisionBiasNV wrap_glSubpixelPrecisionBiasNV
-#define glTestFenceNV wrap_glTestFenceNV
-#define glTexBuffer wrap_glTexBuffer
-#define glTexBufferEXT wrap_glTexBufferEXT
-#define glTexBufferOES wrap_glTexBufferOES
-#define glTexBufferRange wrap_glTexBufferRange
-#define glTexBufferRangeEXT wrap_glTexBufferRangeEXT
-#define glTexBufferRangeOES wrap_glTexBufferRangeOES
-#define glTexCoordPointer wrap_glTexCoordPointer
-#define glTexEnvf wrap_glTexEnvf
-#define glTexEnvfv wrap_glTexEnvfv
-#define glTexEnvi wrap_glTexEnvi
-#define glTexEnviv wrap_glTexEnviv
-#define glTexEnvx wrap_glTexEnvx
-#define glTexEnvxOES wrap_glTexEnvxOES
-#define glTexEnvxv wrap_glTexEnvxv
-#define glTexEnvxvOES wrap_glTexEnvxvOES
-#define glTexGenfOES wrap_glTexGenfOES
-#define glTexGenfvOES wrap_glTexGenfvOES
-#define glTexGeniOES wrap_glTexGeniOES
-#define glTexGenivOES wrap_glTexGenivOES
-#define glTexGenxOES wrap_glTexGenxOES
-#define glTexGenxvOES wrap_glTexGenxvOES
-#define glTexImage2D wrap_glTexImage2D
-#define glTexImage3D wrap_glTexImage3D
-#define glTexImage3DOES wrap_glTexImage3DOES
-#define glTexPageCommitmentEXT wrap_glTexPageCommitmentEXT
-#define glTexParameterIiv wrap_glTexParameterIiv
-#define glTexParameterIivEXT wrap_glTexParameterIivEXT
-#define glTexParameterIivOES wrap_glTexParameterIivOES
-#define glTexParameterIuiv wrap_glTexParameterIuiv
-#define glTexParameterIuivEXT wrap_glTexParameterIuivEXT
-#define glTexParameterIuivOES wrap_glTexParameterIuivOES
-#define glTexParameterf wrap_glTexParameterf
-#define glTexParameterfv wrap_glTexParameterfv
-#define glTexParameteri wrap_glTexParameteri
-#define glTexParameteriv wrap_glTexParameteriv
-#define glTexParameterx wrap_glTexParameterx
-#define glTexParameterxOES wrap_glTexParameterxOES
-#define glTexParameterxv wrap_glTexParameterxv
-#define glTexParameterxvOES wrap_glTexParameterxvOES
-#define glTexStorage1DEXT wrap_glTexStorage1DEXT
-#define glTexStorage2D wrap_glTexStorage2D
-#define glTexStorage2DEXT wrap_glTexStorage2DEXT
-#define glTexStorage2DMultisample wrap_glTexStorage2DMultisample
-#define glTexStorage3D wrap_glTexStorage3D
-#define glTexStorage3DEXT wrap_glTexStorage3DEXT
-#define glTexStorage3DMultisample wrap_glTexStorage3DMultisample
-#define glTexStorage3DMultisampleOES wrap_glTexStorage3DMultisampleOES
-#define glTexSubImage2D wrap_glTexSubImage2D
-#define glTexSubImage3D wrap_glTexSubImage3D
-#define glTexSubImage3DOES wrap_glTexSubImage3DOES
-#define glTextureStorage1DEXT wrap_glTextureStorage1DEXT
-#define glTextureStorage2DEXT wrap_glTextureStorage2DEXT
-#define glTextureStorage3DEXT wrap_glTextureStorage3DEXT
-#define glTextureViewEXT wrap_glTextureViewEXT
-#define glTextureViewOES wrap_glTextureViewOES
-#define glTransformFeedbackVaryings wrap_glTransformFeedbackVaryings
-#define glTransformPathNV wrap_glTransformPathNV
-#define glTranslatef wrap_glTranslatef
-#define glTranslatex wrap_glTranslatex
-#define glTranslatexOES wrap_glTranslatexOES
-#define glUniform1f wrap_glUniform1f
-#define glUniform1fv wrap_glUniform1fv
-#define glUniform1i wrap_glUniform1i
-#define glUniform1iv wrap_glUniform1iv
-#define glUniform1ui wrap_glUniform1ui
-#define glUniform1uiv wrap_glUniform1uiv
-#define glUniform2f wrap_glUniform2f
-#define glUniform2fv wrap_glUniform2fv
-#define glUniform2i wrap_glUniform2i
-#define glUniform2iv wrap_glUniform2iv
-#define glUniform2ui wrap_glUniform2ui
-#define glUniform2uiv wrap_glUniform2uiv
-#define glUniform3f wrap_glUniform3f
-#define glUniform3fv wrap_glUniform3fv
-#define glUniform3i wrap_glUniform3i
-#define glUniform3iv wrap_glUniform3iv
-#define glUniform3ui wrap_glUniform3ui
-#define glUniform3uiv wrap_glUniform3uiv
-#define glUniform4f wrap_glUniform4f
-#define glUniform4fv wrap_glUniform4fv
-#define glUniform4i wrap_glUniform4i
-#define glUniform4iv wrap_glUniform4iv
-#define glUniform4ui wrap_glUniform4ui
-#define glUniform4uiv wrap_glUniform4uiv
-#define glUniformBlockBinding wrap_glUniformBlockBinding
-#define glUniformHandleui64NV wrap_glUniformHandleui64NV
-#define glUniformHandleui64vNV wrap_glUniformHandleui64vNV
-#define glUniformMatrix2fv wrap_glUniformMatrix2fv
-#define glUniformMatrix2x3fv wrap_glUniformMatrix2x3fv
-#define glUniformMatrix2x3fvNV wrap_glUniformMatrix2x3fvNV
-#define glUniformMatrix2x4fv wrap_glUniformMatrix2x4fv
-#define glUniformMatrix2x4fvNV wrap_glUniformMatrix2x4fvNV
-#define glUniformMatrix3fv wrap_glUniformMatrix3fv
-#define glUniformMatrix3x2fv wrap_glUniformMatrix3x2fv
-#define glUniformMatrix3x2fvNV wrap_glUniformMatrix3x2fvNV
-#define glUniformMatrix3x4fv wrap_glUniformMatrix3x4fv
-#define glUniformMatrix3x4fvNV wrap_glUniformMatrix3x4fvNV
-#define glUniformMatrix4fv wrap_glUniformMatrix4fv
-#define glUniformMatrix4x2fv wrap_glUniformMatrix4x2fv
-#define glUniformMatrix4x2fvNV wrap_glUniformMatrix4x2fvNV
-#define glUniformMatrix4x3fv wrap_glUniformMatrix4x3fv
-#define glUniformMatrix4x3fvNV wrap_glUniformMatrix4x3fvNV
-#define glUnmapBuffer wrap_glUnmapBuffer
-#define glUnmapBufferOES wrap_glUnmapBufferOES
-#define glUseProgram wrap_glUseProgram
-#define glUseProgramStages wrap_glUseProgramStages
-#define glUseProgramStagesEXT wrap_glUseProgramStagesEXT
-#define glValidateProgram wrap_glValidateProgram
-#define glValidateProgramPipeline wrap_glValidateProgramPipeline
-#define glValidateProgramPipelineEXT wrap_glValidateProgramPipelineEXT
-#define glVertexAttrib1f wrap_glVertexAttrib1f
-#define glVertexAttrib1fv wrap_glVertexAttrib1fv
-#define glVertexAttrib2f wrap_glVertexAttrib2f
-#define glVertexAttrib2fv wrap_glVertexAttrib2fv
-#define glVertexAttrib3f wrap_glVertexAttrib3f
-#define glVertexAttrib3fv wrap_glVertexAttrib3fv
-#define glVertexAttrib4f wrap_glVertexAttrib4f
-#define glVertexAttrib4fv wrap_glVertexAttrib4fv
-#define glVertexAttribBinding wrap_glVertexAttribBinding
-#define glVertexAttribDivisor wrap_glVertexAttribDivisor
-#define glVertexAttribDivisorANGLE wrap_glVertexAttribDivisorANGLE
-#define glVertexAttribDivisorEXT wrap_glVertexAttribDivisorEXT
-#define glVertexAttribDivisorNV wrap_glVertexAttribDivisorNV
-#define glVertexAttribFormat wrap_glVertexAttribFormat
-#define glVertexAttribI4i wrap_glVertexAttribI4i
-#define glVertexAttribI4iv wrap_glVertexAttribI4iv
-#define glVertexAttribI4ui wrap_glVertexAttribI4ui
-#define glVertexAttribI4uiv wrap_glVertexAttribI4uiv
-#define glVertexAttribIFormat wrap_glVertexAttribIFormat
-#define glVertexAttribIPointer wrap_glVertexAttribIPointer
-#define glVertexAttribPointer wrap_glVertexAttribPointer
-#define glVertexBindingDivisor wrap_glVertexBindingDivisor
-#define glVertexPointer wrap_glVertexPointer
-#define glViewport wrap_glViewport
-#define glViewportArrayvNV wrap_glViewportArrayvNV
-#define glViewportIndexedfNV wrap_glViewportIndexedfNV
-#define glViewportIndexedfvNV wrap_glViewportIndexedfvNV
-#define glWaitSync wrap_glWaitSync
-#define glWaitSyncAPPLE wrap_glWaitSyncAPPLE
-#define glWeightPathsNV wrap_glWeightPathsNV
-#define glWeightPointerOES wrap_glWeightPointerOES
\ No newline at end of file
diff --git a/libs/hwui/debug/gles_stubs.in b/libs/hwui/debug/gles_stubs.in
deleted file mode 100644
index 7cba0c1..0000000
--- a/libs/hwui/debug/gles_stubs.in
+++ /dev/null
@@ -1,1629 +0,0 @@
-void API_ENTRY(glActiveTexture)(GLenum texture) {
-    CALL_GL_API(glActiveTexture, texture);
-}
-void API_ENTRY(glAttachShader)(GLuint program, GLuint shader) {
-    CALL_GL_API(glAttachShader, program, shader);
-}
-void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const GLchar *name) {
-    CALL_GL_API(glBindAttribLocation, program, index, name);
-}
-void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
-    CALL_GL_API(glBindBuffer, target, buffer);
-}
-void API_ENTRY(glBindFramebuffer)(GLenum target, GLuint framebuffer) {
-    CALL_GL_API(glBindFramebuffer, target, framebuffer);
-}
-void API_ENTRY(glBindRenderbuffer)(GLenum target, GLuint renderbuffer) {
-    CALL_GL_API(glBindRenderbuffer, target, renderbuffer);
-}
-void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
-    CALL_GL_API(glBindTexture, target, texture);
-}
-void API_ENTRY(glBlendColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
-    CALL_GL_API(glBlendColor, red, green, blue, alpha);
-}
-void API_ENTRY(glBlendEquation)(GLenum mode) {
-    CALL_GL_API(glBlendEquation, mode);
-}
-void API_ENTRY(glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha) {
-    CALL_GL_API(glBlendEquationSeparate, modeRGB, modeAlpha);
-}
-void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
-    CALL_GL_API(glBlendFunc, sfactor, dfactor);
-}
-void API_ENTRY(glBlendFuncSeparate)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
-    CALL_GL_API(glBlendFuncSeparate, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
-}
-void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const void *data, GLenum usage) {
-    CALL_GL_API(glBufferData, target, size, data, usage);
-}
-void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data) {
-    CALL_GL_API(glBufferSubData, target, offset, size, data);
-}
-GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target) {
-    CALL_GL_API_RETURN(glCheckFramebufferStatus, target);
-}
-void API_ENTRY(glClear)(GLbitfield mask) {
-    CALL_GL_API(glClear, mask);
-}
-void API_ENTRY(glClearColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
-    CALL_GL_API(glClearColor, red, green, blue, alpha);
-}
-void API_ENTRY(glClearDepthf)(GLfloat d) {
-    CALL_GL_API(glClearDepthf, d);
-}
-void API_ENTRY(glClearStencil)(GLint s) {
-    CALL_GL_API(glClearStencil, s);
-}
-void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
-    CALL_GL_API(glColorMask, red, green, blue, alpha);
-}
-void API_ENTRY(glCompileShader)(GLuint shader) {
-    CALL_GL_API(glCompileShader, shader);
-}
-void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) {
-    CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
-}
-void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) {
-    CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
-}
-void API_ENTRY(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
-    CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y, width, height, border);
-}
-void API_ENTRY(glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
-    CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height);
-}
-GLuint API_ENTRY(glCreateProgram)(void) {
-    CALL_GL_API_RETURN(glCreateProgram);
-}
-GLuint API_ENTRY(glCreateShader)(GLenum type) {
-    CALL_GL_API_RETURN(glCreateShader, type);
-}
-void API_ENTRY(glCullFace)(GLenum mode) {
-    CALL_GL_API(glCullFace, mode);
-}
-void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint *buffers) {
-    CALL_GL_API(glDeleteBuffers, n, buffers);
-}
-void API_ENTRY(glDeleteFramebuffers)(GLsizei n, const GLuint *framebuffers) {
-    CALL_GL_API(glDeleteFramebuffers, n, framebuffers);
-}
-void API_ENTRY(glDeleteProgram)(GLuint program) {
-    CALL_GL_API(glDeleteProgram, program);
-}
-void API_ENTRY(glDeleteRenderbuffers)(GLsizei n, const GLuint *renderbuffers) {
-    CALL_GL_API(glDeleteRenderbuffers, n, renderbuffers);
-}
-void API_ENTRY(glDeleteShader)(GLuint shader) {
-    CALL_GL_API(glDeleteShader, shader);
-}
-void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint *textures) {
-    CALL_GL_API(glDeleteTextures, n, textures);
-}
-void API_ENTRY(glDepthFunc)(GLenum func) {
-    CALL_GL_API(glDepthFunc, func);
-}
-void API_ENTRY(glDepthMask)(GLboolean flag) {
-    CALL_GL_API(glDepthMask, flag);
-}
-void API_ENTRY(glDepthRangef)(GLfloat n, GLfloat f) {
-    CALL_GL_API(glDepthRangef, n, f);
-}
-void API_ENTRY(glDetachShader)(GLuint program, GLuint shader) {
-    CALL_GL_API(glDetachShader, program, shader);
-}
-void API_ENTRY(glDisable)(GLenum cap) {
-    CALL_GL_API(glDisable, cap);
-}
-void API_ENTRY(glDisableVertexAttribArray)(GLuint index) {
-    CALL_GL_API(glDisableVertexAttribArray, index);
-}
-void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
-    CALL_GL_API(glDrawArrays, mode, first, count);
-}
-void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const void *indices) {
-    CALL_GL_API(glDrawElements, mode, count, type, indices);
-}
-void API_ENTRY(glEnable)(GLenum cap) {
-    CALL_GL_API(glEnable, cap);
-}
-void API_ENTRY(glEnableVertexAttribArray)(GLuint index) {
-    CALL_GL_API(glEnableVertexAttribArray, index);
-}
-void API_ENTRY(glFinish)(void) {
-    CALL_GL_API(glFinish);
-}
-void API_ENTRY(glFlush)(void) {
-    CALL_GL_API(glFlush);
-}
-void API_ENTRY(glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
-    CALL_GL_API(glFramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer);
-}
-void API_ENTRY(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
-    CALL_GL_API(glFramebufferTexture2D, target, attachment, textarget, texture, level);
-}
-void API_ENTRY(glFrontFace)(GLenum mode) {
-    CALL_GL_API(glFrontFace, mode);
-}
-void API_ENTRY(glGenBuffers)(GLsizei n, GLuint *buffers) {
-    CALL_GL_API(glGenBuffers, n, buffers);
-}
-void API_ENTRY(glGenerateMipmap)(GLenum target) {
-    CALL_GL_API(glGenerateMipmap, target);
-}
-void API_ENTRY(glGenFramebuffers)(GLsizei n, GLuint *framebuffers) {
-    CALL_GL_API(glGenFramebuffers, n, framebuffers);
-}
-void API_ENTRY(glGenRenderbuffers)(GLsizei n, GLuint *renderbuffers) {
-    CALL_GL_API(glGenRenderbuffers, n, renderbuffers);
-}
-void API_ENTRY(glGenTextures)(GLsizei n, GLuint *textures) {
-    CALL_GL_API(glGenTextures, n, textures);
-}
-void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {
-    CALL_GL_API(glGetActiveAttrib, program, index, bufSize, length, size, type, name);
-}
-void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) {
-    CALL_GL_API(glGetActiveUniform, program, index, bufSize, length, size, type, name);
-}
-void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders) {
-    CALL_GL_API(glGetAttachedShaders, program, maxCount, count, shaders);
-}
-GLint API_ENTRY(glGetAttribLocation)(GLuint program, const GLchar *name) {
-    CALL_GL_API_RETURN(glGetAttribLocation, program, name);
-}
-void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *data) {
-    CALL_GL_API(glGetBooleanv, pname, data);
-}
-void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetBufferParameteriv, target, pname, params);
-}
-GLenum API_ENTRY(glGetError)(void) {
-    CALL_GL_API_RETURN(glGetError);
-}
-void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *data) {
-    CALL_GL_API(glGetFloatv, pname, data);
-}
-void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
-}
-void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *data) {
-    CALL_GL_API(glGetIntegerv, pname, data);
-}
-void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetProgramiv, program, pname, params);
-}
-void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
-    CALL_GL_API(glGetProgramInfoLog, program, bufSize, length, infoLog);
-}
-void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetRenderbufferParameteriv, target, pname, params);
-}
-void API_ENTRY(glGetShaderiv)(GLuint shader, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetShaderiv, shader, pname, params);
-}
-void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
-    CALL_GL_API(glGetShaderInfoLog, shader, bufSize, length, infoLog);
-}
-void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) {
-    CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
-}
-void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) {
-    CALL_GL_API(glGetShaderSource, shader, bufSize, length, source);
-}
-const GLubyte * API_ENTRY(glGetString)(GLenum name) {
-    CALL_GL_API_RETURN(glGetString, name);
-}
-void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetTexParameterfv, target, pname, params);
-}
-void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetTexParameteriv, target, pname, params);
-}
-void API_ENTRY(glGetUniformfv)(GLuint program, GLint location, GLfloat *params) {
-    CALL_GL_API(glGetUniformfv, program, location, params);
-}
-void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint *params) {
-    CALL_GL_API(glGetUniformiv, program, location, params);
-}
-GLint API_ENTRY(glGetUniformLocation)(GLuint program, const GLchar *name) {
-    CALL_GL_API_RETURN(glGetUniformLocation, program, name);
-}
-void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetVertexAttribfv, index, pname, params);
-}
-void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetVertexAttribiv, index, pname, params);
-}
-void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, void **pointer) {
-    CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
-}
-void API_ENTRY(glHint)(GLenum target, GLenum mode) {
-    CALL_GL_API(glHint, target, mode);
-}
-GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
-    CALL_GL_API_RETURN(glIsBuffer, buffer);
-}
-GLboolean API_ENTRY(glIsEnabled)(GLenum cap) {
-    CALL_GL_API_RETURN(glIsEnabled, cap);
-}
-GLboolean API_ENTRY(glIsFramebuffer)(GLuint framebuffer) {
-    CALL_GL_API_RETURN(glIsFramebuffer, framebuffer);
-}
-GLboolean API_ENTRY(glIsProgram)(GLuint program) {
-    CALL_GL_API_RETURN(glIsProgram, program);
-}
-GLboolean API_ENTRY(glIsRenderbuffer)(GLuint renderbuffer) {
-    CALL_GL_API_RETURN(glIsRenderbuffer, renderbuffer);
-}
-GLboolean API_ENTRY(glIsShader)(GLuint shader) {
-    CALL_GL_API_RETURN(glIsShader, shader);
-}
-GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
-    CALL_GL_API_RETURN(glIsTexture, texture);
-}
-void API_ENTRY(glLineWidth)(GLfloat width) {
-    CALL_GL_API(glLineWidth, width);
-}
-void API_ENTRY(glLinkProgram)(GLuint program) {
-    CALL_GL_API(glLinkProgram, program);
-}
-void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
-    CALL_GL_API(glPixelStorei, pname, param);
-}
-void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
-    CALL_GL_API(glPolygonOffset, factor, units);
-}
-void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) {
-    CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
-}
-void API_ENTRY(glReleaseShaderCompiler)(void) {
-    CALL_GL_API(glReleaseShaderCompiler);
-}
-void API_ENTRY(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
-    CALL_GL_API(glRenderbufferStorage, target, internalformat, width, height);
-}
-void API_ENTRY(glSampleCoverage)(GLfloat value, GLboolean invert) {
-    CALL_GL_API(glSampleCoverage, value, invert);
-}
-void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
-    CALL_GL_API(glScissor, x, y, width, height);
-}
-void API_ENTRY(glShaderBinary)(GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length) {
-    CALL_GL_API(glShaderBinary, count, shaders, binaryformat, binary, length);
-}
-void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) {
-    CALL_GL_API(glShaderSource, shader, count, string, length);
-}
-void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
-    CALL_GL_API(glStencilFunc, func, ref, mask);
-}
-void API_ENTRY(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask) {
-    CALL_GL_API(glStencilFuncSeparate, face, func, ref, mask);
-}
-void API_ENTRY(glStencilMask)(GLuint mask) {
-    CALL_GL_API(glStencilMask, mask);
-}
-void API_ENTRY(glStencilMaskSeparate)(GLenum face, GLuint mask) {
-    CALL_GL_API(glStencilMaskSeparate, face, mask);
-}
-void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
-    CALL_GL_API(glStencilOp, fail, zfail, zpass);
-}
-void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
-    CALL_GL_API(glStencilOpSeparate, face, sfail, dpfail, dppass);
-}
-void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {
-    CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
-}
-void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
-    CALL_GL_API(glTexParameterf, target, pname, param);
-}
-void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) {
-    CALL_GL_API(glTexParameterfv, target, pname, params);
-}
-void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
-    CALL_GL_API(glTexParameteri, target, pname, param);
-}
-void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) {
-    CALL_GL_API(glTexParameteriv, target, pname, params);
-}
-void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) {
-    CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-void API_ENTRY(glUniform1f)(GLint location, GLfloat v0) {
-    CALL_GL_API(glUniform1f, location, v0);
-}
-void API_ENTRY(glUniform1fv)(GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glUniform1fv, location, count, value);
-}
-void API_ENTRY(glUniform1i)(GLint location, GLint v0) {
-    CALL_GL_API(glUniform1i, location, v0);
-}
-void API_ENTRY(glUniform1iv)(GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glUniform1iv, location, count, value);
-}
-void API_ENTRY(glUniform2f)(GLint location, GLfloat v0, GLfloat v1) {
-    CALL_GL_API(glUniform2f, location, v0, v1);
-}
-void API_ENTRY(glUniform2fv)(GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glUniform2fv, location, count, value);
-}
-void API_ENTRY(glUniform2i)(GLint location, GLint v0, GLint v1) {
-    CALL_GL_API(glUniform2i, location, v0, v1);
-}
-void API_ENTRY(glUniform2iv)(GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glUniform2iv, location, count, value);
-}
-void API_ENTRY(glUniform3f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
-    CALL_GL_API(glUniform3f, location, v0, v1, v2);
-}
-void API_ENTRY(glUniform3fv)(GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glUniform3fv, location, count, value);
-}
-void API_ENTRY(glUniform3i)(GLint location, GLint v0, GLint v1, GLint v2) {
-    CALL_GL_API(glUniform3i, location, v0, v1, v2);
-}
-void API_ENTRY(glUniform3iv)(GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glUniform3iv, location, count, value);
-}
-void API_ENTRY(glUniform4f)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
-    CALL_GL_API(glUniform4f, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glUniform4fv)(GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glUniform4fv, location, count, value);
-}
-void API_ENTRY(glUniform4i)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
-    CALL_GL_API(glUniform4i, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glUniform4iv)(GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glUniform4iv, location, count, value);
-}
-void API_ENTRY(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix2fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix3fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix4fv, location, count, transpose, value);
-}
-void API_ENTRY(glUseProgram)(GLuint program) {
-    CALL_GL_API(glUseProgram, program);
-}
-void API_ENTRY(glValidateProgram)(GLuint program) {
-    CALL_GL_API(glValidateProgram, program);
-}
-void API_ENTRY(glVertexAttrib1f)(GLuint index, GLfloat x) {
-    CALL_GL_API(glVertexAttrib1f, index, x);
-}
-void API_ENTRY(glVertexAttrib1fv)(GLuint index, const GLfloat *v) {
-    CALL_GL_API(glVertexAttrib1fv, index, v);
-}
-void API_ENTRY(glVertexAttrib2f)(GLuint index, GLfloat x, GLfloat y) {
-    CALL_GL_API(glVertexAttrib2f, index, x, y);
-}
-void API_ENTRY(glVertexAttrib2fv)(GLuint index, const GLfloat *v) {
-    CALL_GL_API(glVertexAttrib2fv, index, v);
-}
-void API_ENTRY(glVertexAttrib3f)(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
-    CALL_GL_API(glVertexAttrib3f, index, x, y, z);
-}
-void API_ENTRY(glVertexAttrib3fv)(GLuint index, const GLfloat *v) {
-    CALL_GL_API(glVertexAttrib3fv, index, v);
-}
-void API_ENTRY(glVertexAttrib4f)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
-    CALL_GL_API(glVertexAttrib4f, index, x, y, z, w);
-}
-void API_ENTRY(glVertexAttrib4fv)(GLuint index, const GLfloat *v) {
-    CALL_GL_API(glVertexAttrib4fv, index, v);
-}
-void API_ENTRY(glVertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) {
-    CALL_GL_API(glVertexAttribPointer, index, size, type, normalized, stride, pointer);
-}
-void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
-    CALL_GL_API(glViewport, x, y, width, height);
-}
-void API_ENTRY(glReadBuffer)(GLenum src) {
-    CALL_GL_API(glReadBuffer, src);
-}
-void API_ENTRY(glDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {
-    CALL_GL_API(glDrawRangeElements, mode, start, end, count, type, indices);
-}
-void API_ENTRY(glTexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {
-    CALL_GL_API(glTexImage3D, target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-void API_ENTRY(glTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) {
-    CALL_GL_API(glTexSubImage3D, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
-}
-void API_ENTRY(glCopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
-    CALL_GL_API(glCopyTexSubImage3D, target, level, xoffset, yoffset, zoffset, x, y, width, height);
-}
-void API_ENTRY(glCompressedTexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {
-    CALL_GL_API(glCompressedTexImage3D, target, level, internalformat, width, height, depth, border, imageSize, data);
-}
-void API_ENTRY(glCompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {
-    CALL_GL_API(glCompressedTexSubImage3D, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
-}
-void API_ENTRY(glGenQueries)(GLsizei n, GLuint *ids) {
-    CALL_GL_API(glGenQueries, n, ids);
-}
-void API_ENTRY(glDeleteQueries)(GLsizei n, const GLuint *ids) {
-    CALL_GL_API(glDeleteQueries, n, ids);
-}
-GLboolean API_ENTRY(glIsQuery)(GLuint id) {
-    CALL_GL_API_RETURN(glIsQuery, id);
-}
-void API_ENTRY(glBeginQuery)(GLenum target, GLuint id) {
-    CALL_GL_API(glBeginQuery, target, id);
-}
-void API_ENTRY(glEndQuery)(GLenum target) {
-    CALL_GL_API(glEndQuery, target);
-}
-void API_ENTRY(glGetQueryiv)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetQueryiv, target, pname, params);
-}
-void API_ENTRY(glGetQueryObjectuiv)(GLuint id, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetQueryObjectuiv, id, pname, params);
-}
-GLboolean API_ENTRY(glUnmapBuffer)(GLenum target) {
-    CALL_GL_API_RETURN(glUnmapBuffer, target);
-}
-void API_ENTRY(glGetBufferPointerv)(GLenum target, GLenum pname, void **params) {
-    CALL_GL_API(glGetBufferPointerv, target, pname, params);
-}
-void API_ENTRY(glDrawBuffers)(GLsizei n, const GLenum *bufs) {
-    CALL_GL_API(glDrawBuffers, n, bufs);
-}
-void API_ENTRY(glUniformMatrix2x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix2x3fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix3x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix3x2fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix2x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix2x4fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix4x2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix4x2fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix3x4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix3x4fv, location, count, transpose, value);
-}
-void API_ENTRY(glUniformMatrix4x3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glUniformMatrix4x3fv, location, count, transpose, value);
-}
-void API_ENTRY(glBlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
-    CALL_GL_API(glBlitFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-}
-void API_ENTRY(glRenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
-    CALL_GL_API(glRenderbufferStorageMultisample, target, samples, internalformat, width, height);
-}
-void API_ENTRY(glFramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
-    CALL_GL_API(glFramebufferTextureLayer, target, attachment, texture, level, layer);
-}
-void * API_ENTRY(glMapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
-    CALL_GL_API_RETURN(glMapBufferRange, target, offset, length, access);
-}
-void API_ENTRY(glFlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length) {
-    CALL_GL_API(glFlushMappedBufferRange, target, offset, length);
-}
-void API_ENTRY(glBindVertexArray)(GLuint array) {
-    CALL_GL_API(glBindVertexArray, array);
-}
-void API_ENTRY(glDeleteVertexArrays)(GLsizei n, const GLuint *arrays) {
-    CALL_GL_API(glDeleteVertexArrays, n, arrays);
-}
-void API_ENTRY(glGenVertexArrays)(GLsizei n, GLuint *arrays) {
-    CALL_GL_API(glGenVertexArrays, n, arrays);
-}
-GLboolean API_ENTRY(glIsVertexArray)(GLuint array) {
-    CALL_GL_API_RETURN(glIsVertexArray, array);
-}
-void API_ENTRY(glGetIntegeri_v)(GLenum target, GLuint index, GLint *data) {
-    CALL_GL_API(glGetIntegeri_v, target, index, data);
-}
-void API_ENTRY(glBeginTransformFeedback)(GLenum primitiveMode) {
-    CALL_GL_API(glBeginTransformFeedback, primitiveMode);
-}
-void API_ENTRY(glEndTransformFeedback)(void) {
-    CALL_GL_API(glEndTransformFeedback);
-}
-void API_ENTRY(glBindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) {
-    CALL_GL_API(glBindBufferRange, target, index, buffer, offset, size);
-}
-void API_ENTRY(glBindBufferBase)(GLenum target, GLuint index, GLuint buffer) {
-    CALL_GL_API(glBindBufferBase, target, index, buffer);
-}
-void API_ENTRY(glTransformFeedbackVaryings)(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode) {
-    CALL_GL_API(glTransformFeedbackVaryings, program, count, varyings, bufferMode);
-}
-void API_ENTRY(glGetTransformFeedbackVarying)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) {
-    CALL_GL_API(glGetTransformFeedbackVarying, program, index, bufSize, length, size, type, name);
-}
-void API_ENTRY(glVertexAttribIPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer) {
-    CALL_GL_API(glVertexAttribIPointer, index, size, type, stride, pointer);
-}
-void API_ENTRY(glGetVertexAttribIiv)(GLuint index, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetVertexAttribIiv, index, pname, params);
-}
-void API_ENTRY(glGetVertexAttribIuiv)(GLuint index, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetVertexAttribIuiv, index, pname, params);
-}
-void API_ENTRY(glVertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w) {
-    CALL_GL_API(glVertexAttribI4i, index, x, y, z, w);
-}
-void API_ENTRY(glVertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) {
-    CALL_GL_API(glVertexAttribI4ui, index, x, y, z, w);
-}
-void API_ENTRY(glVertexAttribI4iv)(GLuint index, const GLint *v) {
-    CALL_GL_API(glVertexAttribI4iv, index, v);
-}
-void API_ENTRY(glVertexAttribI4uiv)(GLuint index, const GLuint *v) {
-    CALL_GL_API(glVertexAttribI4uiv, index, v);
-}
-void API_ENTRY(glGetUniformuiv)(GLuint program, GLint location, GLuint *params) {
-    CALL_GL_API(glGetUniformuiv, program, location, params);
-}
-GLint API_ENTRY(glGetFragDataLocation)(GLuint program, const GLchar *name) {
-    CALL_GL_API_RETURN(glGetFragDataLocation, program, name);
-}
-void API_ENTRY(glUniform1ui)(GLint location, GLuint v0) {
-    CALL_GL_API(glUniform1ui, location, v0);
-}
-void API_ENTRY(glUniform2ui)(GLint location, GLuint v0, GLuint v1) {
-    CALL_GL_API(glUniform2ui, location, v0, v1);
-}
-void API_ENTRY(glUniform3ui)(GLint location, GLuint v0, GLuint v1, GLuint v2) {
-    CALL_GL_API(glUniform3ui, location, v0, v1, v2);
-}
-void API_ENTRY(glUniform4ui)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
-    CALL_GL_API(glUniform4ui, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glUniform1uiv)(GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glUniform1uiv, location, count, value);
-}
-void API_ENTRY(glUniform2uiv)(GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glUniform2uiv, location, count, value);
-}
-void API_ENTRY(glUniform3uiv)(GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glUniform3uiv, location, count, value);
-}
-void API_ENTRY(glUniform4uiv)(GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glUniform4uiv, location, count, value);
-}
-void API_ENTRY(glClearBufferiv)(GLenum buffer, GLint drawbuffer, const GLint *value) {
-    CALL_GL_API(glClearBufferiv, buffer, drawbuffer, value);
-}
-void API_ENTRY(glClearBufferuiv)(GLenum buffer, GLint drawbuffer, const GLuint *value) {
-    CALL_GL_API(glClearBufferuiv, buffer, drawbuffer, value);
-}
-void API_ENTRY(glClearBufferfv)(GLenum buffer, GLint drawbuffer, const GLfloat *value) {
-    CALL_GL_API(glClearBufferfv, buffer, drawbuffer, value);
-}
-void API_ENTRY(glClearBufferfi)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
-    CALL_GL_API(glClearBufferfi, buffer, drawbuffer, depth, stencil);
-}
-const GLubyte * API_ENTRY(glGetStringi)(GLenum name, GLuint index) {
-    CALL_GL_API_RETURN(glGetStringi, name, index);
-}
-void API_ENTRY(glCopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
-    CALL_GL_API(glCopyBufferSubData, readTarget, writeTarget, readOffset, writeOffset, size);
-}
-void API_ENTRY(glGetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices) {
-    CALL_GL_API(glGetUniformIndices, program, uniformCount, uniformNames, uniformIndices);
-}
-void API_ENTRY(glGetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetActiveUniformsiv, program, uniformCount, uniformIndices, pname, params);
-}
-GLuint API_ENTRY(glGetUniformBlockIndex)(GLuint program, const GLchar *uniformBlockName) {
-    CALL_GL_API_RETURN(glGetUniformBlockIndex, program, uniformBlockName);
-}
-void API_ENTRY(glGetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetActiveUniformBlockiv, program, uniformBlockIndex, pname, params);
-}
-void API_ENTRY(glGetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) {
-    CALL_GL_API(glGetActiveUniformBlockName, program, uniformBlockIndex, bufSize, length, uniformBlockName);
-}
-void API_ENTRY(glUniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
-    CALL_GL_API(glUniformBlockBinding, program, uniformBlockIndex, uniformBlockBinding);
-}
-void API_ENTRY(glDrawArraysInstanced)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) {
-    CALL_GL_API(glDrawArraysInstanced, mode, first, count, instancecount);
-}
-void API_ENTRY(glDrawElementsInstanced)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount) {
-    CALL_GL_API(glDrawElementsInstanced, mode, count, type, indices, instancecount);
-}
-GLsync API_ENTRY(glFenceSync)(GLenum condition, GLbitfield flags) {
-    CALL_GL_API_RETURN(glFenceSync, condition, flags);
-}
-GLboolean API_ENTRY(glIsSync)(GLsync sync) {
-    CALL_GL_API_RETURN(glIsSync, sync);
-}
-void API_ENTRY(glDeleteSync)(GLsync sync) {
-    CALL_GL_API(glDeleteSync, sync);
-}
-GLenum API_ENTRY(glClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout) {
-    CALL_GL_API_RETURN(glClientWaitSync, sync, flags, timeout);
-}
-void API_ENTRY(glWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout) {
-    CALL_GL_API(glWaitSync, sync, flags, timeout);
-}
-void API_ENTRY(glGetInteger64v)(GLenum pname, GLint64 *data) {
-    CALL_GL_API(glGetInteger64v, pname, data);
-}
-void API_ENTRY(glGetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
-    CALL_GL_API(glGetSynciv, sync, pname, bufSize, length, values);
-}
-void API_ENTRY(glGetInteger64i_v)(GLenum target, GLuint index, GLint64 *data) {
-    CALL_GL_API(glGetInteger64i_v, target, index, data);
-}
-void API_ENTRY(glGetBufferParameteri64v)(GLenum target, GLenum pname, GLint64 *params) {
-    CALL_GL_API(glGetBufferParameteri64v, target, pname, params);
-}
-void API_ENTRY(glGenSamplers)(GLsizei count, GLuint *samplers) {
-    CALL_GL_API(glGenSamplers, count, samplers);
-}
-void API_ENTRY(glDeleteSamplers)(GLsizei count, const GLuint *samplers) {
-    CALL_GL_API(glDeleteSamplers, count, samplers);
-}
-GLboolean API_ENTRY(glIsSampler)(GLuint sampler) {
-    CALL_GL_API_RETURN(glIsSampler, sampler);
-}
-void API_ENTRY(glBindSampler)(GLuint unit, GLuint sampler) {
-    CALL_GL_API(glBindSampler, unit, sampler);
-}
-void API_ENTRY(glSamplerParameteri)(GLuint sampler, GLenum pname, GLint param) {
-    CALL_GL_API(glSamplerParameteri, sampler, pname, param);
-}
-void API_ENTRY(glSamplerParameteriv)(GLuint sampler, GLenum pname, const GLint *param) {
-    CALL_GL_API(glSamplerParameteriv, sampler, pname, param);
-}
-void API_ENTRY(glSamplerParameterf)(GLuint sampler, GLenum pname, GLfloat param) {
-    CALL_GL_API(glSamplerParameterf, sampler, pname, param);
-}
-void API_ENTRY(glSamplerParameterfv)(GLuint sampler, GLenum pname, const GLfloat *param) {
-    CALL_GL_API(glSamplerParameterfv, sampler, pname, param);
-}
-void API_ENTRY(glGetSamplerParameteriv)(GLuint sampler, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetSamplerParameteriv, sampler, pname, params);
-}
-void API_ENTRY(glGetSamplerParameterfv)(GLuint sampler, GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetSamplerParameterfv, sampler, pname, params);
-}
-void API_ENTRY(glVertexAttribDivisor)(GLuint index, GLuint divisor) {
-    CALL_GL_API(glVertexAttribDivisor, index, divisor);
-}
-void API_ENTRY(glBindTransformFeedback)(GLenum target, GLuint id) {
-    CALL_GL_API(glBindTransformFeedback, target, id);
-}
-void API_ENTRY(glDeleteTransformFeedbacks)(GLsizei n, const GLuint *ids) {
-    CALL_GL_API(glDeleteTransformFeedbacks, n, ids);
-}
-void API_ENTRY(glGenTransformFeedbacks)(GLsizei n, GLuint *ids) {
-    CALL_GL_API(glGenTransformFeedbacks, n, ids);
-}
-GLboolean API_ENTRY(glIsTransformFeedback)(GLuint id) {
-    CALL_GL_API_RETURN(glIsTransformFeedback, id);
-}
-void API_ENTRY(glPauseTransformFeedback)(void) {
-    CALL_GL_API(glPauseTransformFeedback);
-}
-void API_ENTRY(glResumeTransformFeedback)(void) {
-    CALL_GL_API(glResumeTransformFeedback);
-}
-void API_ENTRY(glGetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) {
-    CALL_GL_API(glGetProgramBinary, program, bufSize, length, binaryFormat, binary);
-}
-void API_ENTRY(glProgramBinary)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length) {
-    CALL_GL_API(glProgramBinary, program, binaryFormat, binary, length);
-}
-void API_ENTRY(glProgramParameteri)(GLuint program, GLenum pname, GLint value) {
-    CALL_GL_API(glProgramParameteri, program, pname, value);
-}
-void API_ENTRY(glInvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
-    CALL_GL_API(glInvalidateFramebuffer, target, numAttachments, attachments);
-}
-void API_ENTRY(glInvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height) {
-    CALL_GL_API(glInvalidateSubFramebuffer, target, numAttachments, attachments, x, y, width, height);
-}
-void API_ENTRY(glTexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
-    CALL_GL_API(glTexStorage2D, target, levels, internalformat, width, height);
-}
-void API_ENTRY(glTexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
-    CALL_GL_API(glTexStorage3D, target, levels, internalformat, width, height, depth);
-}
-void API_ENTRY(glGetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) {
-    CALL_GL_API(glGetInternalformativ, target, internalformat, pname, bufSize, params);
-}
-void API_ENTRY(glDispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) {
-    CALL_GL_API(glDispatchCompute, num_groups_x, num_groups_y, num_groups_z);
-}
-void API_ENTRY(glDispatchComputeIndirect)(GLintptr indirect) {
-    CALL_GL_API(glDispatchComputeIndirect, indirect);
-}
-void API_ENTRY(glDrawArraysIndirect)(GLenum mode, const void *indirect) {
-    CALL_GL_API(glDrawArraysIndirect, mode, indirect);
-}
-void API_ENTRY(glDrawElementsIndirect)(GLenum mode, GLenum type, const void *indirect) {
-    CALL_GL_API(glDrawElementsIndirect, mode, type, indirect);
-}
-void API_ENTRY(glFramebufferParameteri)(GLenum target, GLenum pname, GLint param) {
-    CALL_GL_API(glFramebufferParameteri, target, pname, param);
-}
-void API_ENTRY(glGetFramebufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetFramebufferParameteriv, target, pname, params);
-}
-void API_ENTRY(glGetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetProgramInterfaceiv, program, programInterface, pname, params);
-}
-GLuint API_ENTRY(glGetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar *name) {
-    CALL_GL_API_RETURN(glGetProgramResourceIndex, program, programInterface, name);
-}
-void API_ENTRY(glGetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) {
-    CALL_GL_API(glGetProgramResourceName, program, programInterface, index, bufSize, length, name);
-}
-void API_ENTRY(glGetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params) {
-    CALL_GL_API(glGetProgramResourceiv, program, programInterface, index, propCount, props, bufSize, length, params);
-}
-GLint API_ENTRY(glGetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar *name) {
-    CALL_GL_API_RETURN(glGetProgramResourceLocation, program, programInterface, name);
-}
-void API_ENTRY(glUseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program) {
-    CALL_GL_API(glUseProgramStages, pipeline, stages, program);
-}
-void API_ENTRY(glActiveShaderProgram)(GLuint pipeline, GLuint program) {
-    CALL_GL_API(glActiveShaderProgram, pipeline, program);
-}
-GLuint API_ENTRY(glCreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const*strings) {
-    CALL_GL_API_RETURN(glCreateShaderProgramv, type, count, strings);
-}
-void API_ENTRY(glBindProgramPipeline)(GLuint pipeline) {
-    CALL_GL_API(glBindProgramPipeline, pipeline);
-}
-void API_ENTRY(glDeleteProgramPipelines)(GLsizei n, const GLuint *pipelines) {
-    CALL_GL_API(glDeleteProgramPipelines, n, pipelines);
-}
-void API_ENTRY(glGenProgramPipelines)(GLsizei n, GLuint *pipelines) {
-    CALL_GL_API(glGenProgramPipelines, n, pipelines);
-}
-GLboolean API_ENTRY(glIsProgramPipeline)(GLuint pipeline) {
-    CALL_GL_API_RETURN(glIsProgramPipeline, pipeline);
-}
-void API_ENTRY(glGetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetProgramPipelineiv, pipeline, pname, params);
-}
-void API_ENTRY(glProgramUniform1i)(GLuint program, GLint location, GLint v0) {
-    CALL_GL_API(glProgramUniform1i, program, location, v0);
-}
-void API_ENTRY(glProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1) {
-    CALL_GL_API(glProgramUniform2i, program, location, v0, v1);
-}
-void API_ENTRY(glProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) {
-    CALL_GL_API(glProgramUniform3i, program, location, v0, v1, v2);
-}
-void API_ENTRY(glProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
-    CALL_GL_API(glProgramUniform4i, program, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glProgramUniform1ui)(GLuint program, GLint location, GLuint v0) {
-    CALL_GL_API(glProgramUniform1ui, program, location, v0);
-}
-void API_ENTRY(glProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1) {
-    CALL_GL_API(glProgramUniform2ui, program, location, v0, v1);
-}
-void API_ENTRY(glProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) {
-    CALL_GL_API(glProgramUniform3ui, program, location, v0, v1, v2);
-}
-void API_ENTRY(glProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
-    CALL_GL_API(glProgramUniform4ui, program, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glProgramUniform1f)(GLuint program, GLint location, GLfloat v0) {
-    CALL_GL_API(glProgramUniform1f, program, location, v0);
-}
-void API_ENTRY(glProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1) {
-    CALL_GL_API(glProgramUniform2f, program, location, v0, v1);
-}
-void API_ENTRY(glProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
-    CALL_GL_API(glProgramUniform3f, program, location, v0, v1, v2);
-}
-void API_ENTRY(glProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
-    CALL_GL_API(glProgramUniform4f, program, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glProgramUniform1iv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glProgramUniform2iv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glProgramUniform3iv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glProgramUniform4iv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glProgramUniform1uiv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glProgramUniform2uiv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glProgramUniform3uiv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glProgramUniform4uiv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glProgramUniform1fv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glProgramUniform2fv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glProgramUniform3fv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glProgramUniform4fv, program, location, count, value);
-}
-void API_ENTRY(glProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix2fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix3fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix4fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix2x3fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix3x2fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix2x4fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix4x2fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix3x4fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix4x3fv, program, location, count, transpose, value);
-}
-void API_ENTRY(glValidateProgramPipeline)(GLuint pipeline) {
-    CALL_GL_API(glValidateProgramPipeline, pipeline);
-}
-void API_ENTRY(glGetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
-    CALL_GL_API(glGetProgramPipelineInfoLog, pipeline, bufSize, length, infoLog);
-}
-void API_ENTRY(glBindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) {
-    CALL_GL_API(glBindImageTexture, unit, texture, level, layered, layer, access, format);
-}
-void API_ENTRY(glGetBooleani_v)(GLenum target, GLuint index, GLboolean *data) {
-    CALL_GL_API(glGetBooleani_v, target, index, data);
-}
-void API_ENTRY(glMemoryBarrier)(GLbitfield barriers) {
-    CALL_GL_API(glMemoryBarrier, barriers);
-}
-void API_ENTRY(glMemoryBarrierByRegion)(GLbitfield barriers) {
-    CALL_GL_API(glMemoryBarrierByRegion, barriers);
-}
-void API_ENTRY(glTexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
-    CALL_GL_API(glTexStorage2DMultisample, target, samples, internalformat, width, height, fixedsamplelocations);
-}
-void API_ENTRY(glGetMultisamplefv)(GLenum pname, GLuint index, GLfloat *val) {
-    CALL_GL_API(glGetMultisamplefv, pname, index, val);
-}
-void API_ENTRY(glSampleMaski)(GLuint maskNumber, GLbitfield mask) {
-    CALL_GL_API(glSampleMaski, maskNumber, mask);
-}
-void API_ENTRY(glGetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetTexLevelParameteriv, target, level, pname, params);
-}
-void API_ENTRY(glGetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params) {
-    CALL_GL_API(glGetTexLevelParameterfv, target, level, pname, params);
-}
-void API_ENTRY(glBindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) {
-    CALL_GL_API(glBindVertexBuffer, bindingindex, buffer, offset, stride);
-}
-void API_ENTRY(glVertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) {
-    CALL_GL_API(glVertexAttribFormat, attribindex, size, type, normalized, relativeoffset);
-}
-void API_ENTRY(glVertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) {
-    CALL_GL_API(glVertexAttribIFormat, attribindex, size, type, relativeoffset);
-}
-void API_ENTRY(glVertexAttribBinding)(GLuint attribindex, GLuint bindingindex) {
-    CALL_GL_API(glVertexAttribBinding, attribindex, bindingindex);
-}
-void API_ENTRY(glVertexBindingDivisor)(GLuint bindingindex, GLuint divisor) {
-    CALL_GL_API(glVertexBindingDivisor, bindingindex, divisor);
-}
-void API_ENTRY(glBlendBarrier)(void) {
-    CALL_GL_API(glBlendBarrier);
-}
-void API_ENTRY(glCopyImageSubData)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) {
-    CALL_GL_API(glCopyImageSubData, srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);
-}
-void API_ENTRY(glDebugMessageControl)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled) {
-    CALL_GL_API(glDebugMessageControl, source, type, severity, count, ids, enabled);
-}
-void API_ENTRY(glDebugMessageInsert)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf) {
-    CALL_GL_API(glDebugMessageInsert, source, type, id, severity, length, buf);
-}
-void API_ENTRY(glDebugMessageCallback)(GLDEBUGPROC callback, const void *userParam) {
-    CALL_GL_API(glDebugMessageCallback, callback, userParam);
-}
-GLuint API_ENTRY(glGetDebugMessageLog)(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog) {
-    CALL_GL_API_RETURN(glGetDebugMessageLog, count, bufSize, sources, types, ids, severities, lengths, messageLog);
-}
-void API_ENTRY(glPushDebugGroup)(GLenum source, GLuint id, GLsizei length, const GLchar *message) {
-    CALL_GL_API(glPushDebugGroup, source, id, length, message);
-}
-void API_ENTRY(glPopDebugGroup)(void) {
-    CALL_GL_API(glPopDebugGroup);
-}
-void API_ENTRY(glObjectLabel)(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) {
-    CALL_GL_API(glObjectLabel, identifier, name, length, label);
-}
-void API_ENTRY(glGetObjectLabel)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label) {
-    CALL_GL_API(glGetObjectLabel, identifier, name, bufSize, length, label);
-}
-void API_ENTRY(glObjectPtrLabel)(const void *ptr, GLsizei length, const GLchar *label) {
-    CALL_GL_API(glObjectPtrLabel, ptr, length, label);
-}
-void API_ENTRY(glGetObjectPtrLabel)(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) {
-    CALL_GL_API(glGetObjectPtrLabel, ptr, bufSize, length, label);
-}
-void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
-    CALL_GL_API(glGetPointerv, pname, params);
-}
-void API_ENTRY(glEnablei)(GLenum target, GLuint index) {
-    CALL_GL_API(glEnablei, target, index);
-}
-void API_ENTRY(glDisablei)(GLenum target, GLuint index) {
-    CALL_GL_API(glDisablei, target, index);
-}
-void API_ENTRY(glBlendEquationi)(GLuint buf, GLenum mode) {
-    CALL_GL_API(glBlendEquationi, buf, mode);
-}
-void API_ENTRY(glBlendEquationSeparatei)(GLuint buf, GLenum modeRGB, GLenum modeAlpha) {
-    CALL_GL_API(glBlendEquationSeparatei, buf, modeRGB, modeAlpha);
-}
-void API_ENTRY(glBlendFunci)(GLuint buf, GLenum src, GLenum dst) {
-    CALL_GL_API(glBlendFunci, buf, src, dst);
-}
-void API_ENTRY(glBlendFuncSeparatei)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
-    CALL_GL_API(glBlendFuncSeparatei, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-void API_ENTRY(glColorMaski)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
-    CALL_GL_API(glColorMaski, index, r, g, b, a);
-}
-GLboolean API_ENTRY(glIsEnabledi)(GLenum target, GLuint index) {
-    CALL_GL_API_RETURN(glIsEnabledi, target, index);
-}
-void API_ENTRY(glDrawElementsBaseVertex)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex) {
-    CALL_GL_API(glDrawElementsBaseVertex, mode, count, type, indices, basevertex);
-}
-void API_ENTRY(glDrawRangeElementsBaseVertex)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex) {
-    CALL_GL_API(glDrawRangeElementsBaseVertex, mode, start, end, count, type, indices, basevertex);
-}
-void API_ENTRY(glDrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex) {
-    CALL_GL_API(glDrawElementsInstancedBaseVertex, mode, count, type, indices, instancecount, basevertex);
-}
-void API_ENTRY(glFramebufferTexture)(GLenum target, GLenum attachment, GLuint texture, GLint level) {
-    CALL_GL_API(glFramebufferTexture, target, attachment, texture, level);
-}
-void API_ENTRY(glPrimitiveBoundingBox)(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW) {
-    CALL_GL_API(glPrimitiveBoundingBox, minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
-}
-GLenum API_ENTRY(glGetGraphicsResetStatus)(void) {
-    CALL_GL_API_RETURN(glGetGraphicsResetStatus);
-}
-void API_ENTRY(glReadnPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data) {
-    CALL_GL_API(glReadnPixels, x, y, width, height, format, type, bufSize, data);
-}
-void API_ENTRY(glGetnUniformfv)(GLuint program, GLint location, GLsizei bufSize, GLfloat *params) {
-    CALL_GL_API(glGetnUniformfv, program, location, bufSize, params);
-}
-void API_ENTRY(glGetnUniformiv)(GLuint program, GLint location, GLsizei bufSize, GLint *params) {
-    CALL_GL_API(glGetnUniformiv, program, location, bufSize, params);
-}
-void API_ENTRY(glGetnUniformuiv)(GLuint program, GLint location, GLsizei bufSize, GLuint *params) {
-    CALL_GL_API(glGetnUniformuiv, program, location, bufSize, params);
-}
-void API_ENTRY(glMinSampleShading)(GLfloat value) {
-    CALL_GL_API(glMinSampleShading, value);
-}
-void API_ENTRY(glPatchParameteri)(GLenum pname, GLint value) {
-    CALL_GL_API(glPatchParameteri, pname, value);
-}
-void API_ENTRY(glTexParameterIiv)(GLenum target, GLenum pname, const GLint *params) {
-    CALL_GL_API(glTexParameterIiv, target, pname, params);
-}
-void API_ENTRY(glTexParameterIuiv)(GLenum target, GLenum pname, const GLuint *params) {
-    CALL_GL_API(glTexParameterIuiv, target, pname, params);
-}
-void API_ENTRY(glGetTexParameterIiv)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetTexParameterIiv, target, pname, params);
-}
-void API_ENTRY(glGetTexParameterIuiv)(GLenum target, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetTexParameterIuiv, target, pname, params);
-}
-void API_ENTRY(glSamplerParameterIiv)(GLuint sampler, GLenum pname, const GLint *param) {
-    CALL_GL_API(glSamplerParameterIiv, sampler, pname, param);
-}
-void API_ENTRY(glSamplerParameterIuiv)(GLuint sampler, GLenum pname, const GLuint *param) {
-    CALL_GL_API(glSamplerParameterIuiv, sampler, pname, param);
-}
-void API_ENTRY(glGetSamplerParameterIiv)(GLuint sampler, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetSamplerParameterIiv, sampler, pname, params);
-}
-void API_ENTRY(glGetSamplerParameterIuiv)(GLuint sampler, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetSamplerParameterIuiv, sampler, pname, params);
-}
-void API_ENTRY(glTexBuffer)(GLenum target, GLenum internalformat, GLuint buffer) {
-    CALL_GL_API(glTexBuffer, target, internalformat, buffer);
-}
-void API_ENTRY(glTexBufferRange)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) {
-    CALL_GL_API(glTexBufferRange, target, internalformat, buffer, offset, size);
-}
-void API_ENTRY(glTexStorage3DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) {
-    CALL_GL_API(glTexStorage3DMultisample, target, samples, internalformat, width, height, depth, fixedsamplelocations);
-}
-void API_ENTRY(glBlendBarrierKHR)(void) {
-    CALL_GL_API(glBlendBarrierKHR);
-}
-void API_ENTRY(glDebugMessageControlKHR)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled) {
-    CALL_GL_API(glDebugMessageControlKHR, source, type, severity, count, ids, enabled);
-}
-void API_ENTRY(glDebugMessageInsertKHR)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf) {
-    CALL_GL_API(glDebugMessageInsertKHR, source, type, id, severity, length, buf);
-}
-void API_ENTRY(glDebugMessageCallbackKHR)(GLDEBUGPROCKHR callback, const void *userParam) {
-    CALL_GL_API(glDebugMessageCallbackKHR, callback, userParam);
-}
-GLuint API_ENTRY(glGetDebugMessageLogKHR)(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog) {
-    CALL_GL_API_RETURN(glGetDebugMessageLogKHR, count, bufSize, sources, types, ids, severities, lengths, messageLog);
-}
-void API_ENTRY(glPushDebugGroupKHR)(GLenum source, GLuint id, GLsizei length, const GLchar *message) {
-    CALL_GL_API(glPushDebugGroupKHR, source, id, length, message);
-}
-void API_ENTRY(glPopDebugGroupKHR)(void) {
-    CALL_GL_API(glPopDebugGroupKHR);
-}
-void API_ENTRY(glObjectLabelKHR)(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) {
-    CALL_GL_API(glObjectLabelKHR, identifier, name, length, label);
-}
-void API_ENTRY(glGetObjectLabelKHR)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label) {
-    CALL_GL_API(glGetObjectLabelKHR, identifier, name, bufSize, length, label);
-}
-void API_ENTRY(glObjectPtrLabelKHR)(const void *ptr, GLsizei length, const GLchar *label) {
-    CALL_GL_API(glObjectPtrLabelKHR, ptr, length, label);
-}
-void API_ENTRY(glGetObjectPtrLabelKHR)(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) {
-    CALL_GL_API(glGetObjectPtrLabelKHR, ptr, bufSize, length, label);
-}
-void API_ENTRY(glGetPointervKHR)(GLenum pname, void **params) {
-    CALL_GL_API(glGetPointervKHR, pname, params);
-}
-GLenum API_ENTRY(glGetGraphicsResetStatusKHR)(void) {
-    CALL_GL_API_RETURN(glGetGraphicsResetStatusKHR);
-}
-void API_ENTRY(glReadnPixelsKHR)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data) {
-    CALL_GL_API(glReadnPixelsKHR, x, y, width, height, format, type, bufSize, data);
-}
-void API_ENTRY(glGetnUniformfvKHR)(GLuint program, GLint location, GLsizei bufSize, GLfloat *params) {
-    CALL_GL_API(glGetnUniformfvKHR, program, location, bufSize, params);
-}
-void API_ENTRY(glGetnUniformivKHR)(GLuint program, GLint location, GLsizei bufSize, GLint *params) {
-    CALL_GL_API(glGetnUniformivKHR, program, location, bufSize, params);
-}
-void API_ENTRY(glGetnUniformuivKHR)(GLuint program, GLint location, GLsizei bufSize, GLuint *params) {
-    CALL_GL_API(glGetnUniformuivKHR, program, location, bufSize, params);
-}
-void API_ENTRY(glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image) {
-    CALL_GL_API(glEGLImageTargetTexture2DOES, target, image);
-}
-void API_ENTRY(glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
-    CALL_GL_API(glEGLImageTargetRenderbufferStorageOES, target, image);
-}
-void API_ENTRY(glCopyImageSubDataOES)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) {
-    CALL_GL_API(glCopyImageSubDataOES, srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);
-}
-void API_ENTRY(glEnableiOES)(GLenum target, GLuint index) {
-    CALL_GL_API(glEnableiOES, target, index);
-}
-void API_ENTRY(glDisableiOES)(GLenum target, GLuint index) {
-    CALL_GL_API(glDisableiOES, target, index);
-}
-void API_ENTRY(glBlendEquationiOES)(GLuint buf, GLenum mode) {
-    CALL_GL_API(glBlendEquationiOES, buf, mode);
-}
-void API_ENTRY(glBlendEquationSeparateiOES)(GLuint buf, GLenum modeRGB, GLenum modeAlpha) {
-    CALL_GL_API(glBlendEquationSeparateiOES, buf, modeRGB, modeAlpha);
-}
-void API_ENTRY(glBlendFunciOES)(GLuint buf, GLenum src, GLenum dst) {
-    CALL_GL_API(glBlendFunciOES, buf, src, dst);
-}
-void API_ENTRY(glBlendFuncSeparateiOES)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
-    CALL_GL_API(glBlendFuncSeparateiOES, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-void API_ENTRY(glColorMaskiOES)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
-    CALL_GL_API(glColorMaskiOES, index, r, g, b, a);
-}
-GLboolean API_ENTRY(glIsEnablediOES)(GLenum target, GLuint index) {
-    CALL_GL_API_RETURN(glIsEnablediOES, target, index);
-}
-void API_ENTRY(glDrawElementsBaseVertexOES)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex) {
-    CALL_GL_API(glDrawElementsBaseVertexOES, mode, count, type, indices, basevertex);
-}
-void API_ENTRY(glDrawRangeElementsBaseVertexOES)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex) {
-    CALL_GL_API(glDrawRangeElementsBaseVertexOES, mode, start, end, count, type, indices, basevertex);
-}
-void API_ENTRY(glDrawElementsInstancedBaseVertexOES)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex) {
-    CALL_GL_API(glDrawElementsInstancedBaseVertexOES, mode, count, type, indices, instancecount, basevertex);
-}
-void API_ENTRY(glFramebufferTextureOES)(GLenum target, GLenum attachment, GLuint texture, GLint level) {
-    CALL_GL_API(glFramebufferTextureOES, target, attachment, texture, level);
-}
-void API_ENTRY(glGetProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) {
-    CALL_GL_API(glGetProgramBinaryOES, program, bufSize, length, binaryFormat, binary);
-}
-void API_ENTRY(glProgramBinaryOES)(GLuint program, GLenum binaryFormat, const void *binary, GLint length) {
-    CALL_GL_API(glProgramBinaryOES, program, binaryFormat, binary, length);
-}
-void * API_ENTRY(glMapBufferOES)(GLenum target, GLenum access) {
-    CALL_GL_API_RETURN(glMapBufferOES, target, access);
-}
-GLboolean API_ENTRY(glUnmapBufferOES)(GLenum target) {
-    CALL_GL_API_RETURN(glUnmapBufferOES, target);
-}
-void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, void **params) {
-    CALL_GL_API(glGetBufferPointervOES, target, pname, params);
-}
-void API_ENTRY(glPrimitiveBoundingBoxOES)(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW) {
-    CALL_GL_API(glPrimitiveBoundingBoxOES, minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
-}
-void API_ENTRY(glMinSampleShadingOES)(GLfloat value) {
-    CALL_GL_API(glMinSampleShadingOES, value);
-}
-void API_ENTRY(glPatchParameteriOES)(GLenum pname, GLint value) {
-    CALL_GL_API(glPatchParameteriOES, pname, value);
-}
-void API_ENTRY(glTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {
-    CALL_GL_API(glTexImage3DOES, target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-void API_ENTRY(glTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) {
-    CALL_GL_API(glTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
-}
-void API_ENTRY(glCopyTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
-    CALL_GL_API(glCopyTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, x, y, width, height);
-}
-void API_ENTRY(glCompressedTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {
-    CALL_GL_API(glCompressedTexImage3DOES, target, level, internalformat, width, height, depth, border, imageSize, data);
-}
-void API_ENTRY(glCompressedTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {
-    CALL_GL_API(glCompressedTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
-}
-void API_ENTRY(glFramebufferTexture3DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
-    CALL_GL_API(glFramebufferTexture3DOES, target, attachment, textarget, texture, level, zoffset);
-}
-void API_ENTRY(glTexParameterIivOES)(GLenum target, GLenum pname, const GLint *params) {
-    CALL_GL_API(glTexParameterIivOES, target, pname, params);
-}
-void API_ENTRY(glTexParameterIuivOES)(GLenum target, GLenum pname, const GLuint *params) {
-    CALL_GL_API(glTexParameterIuivOES, target, pname, params);
-}
-void API_ENTRY(glGetTexParameterIivOES)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetTexParameterIivOES, target, pname, params);
-}
-void API_ENTRY(glGetTexParameterIuivOES)(GLenum target, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetTexParameterIuivOES, target, pname, params);
-}
-void API_ENTRY(glSamplerParameterIivOES)(GLuint sampler, GLenum pname, const GLint *param) {
-    CALL_GL_API(glSamplerParameterIivOES, sampler, pname, param);
-}
-void API_ENTRY(glSamplerParameterIuivOES)(GLuint sampler, GLenum pname, const GLuint *param) {
-    CALL_GL_API(glSamplerParameterIuivOES, sampler, pname, param);
-}
-void API_ENTRY(glGetSamplerParameterIivOES)(GLuint sampler, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetSamplerParameterIivOES, sampler, pname, params);
-}
-void API_ENTRY(glGetSamplerParameterIuivOES)(GLuint sampler, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetSamplerParameterIuivOES, sampler, pname, params);
-}
-void API_ENTRY(glTexBufferOES)(GLenum target, GLenum internalformat, GLuint buffer) {
-    CALL_GL_API(glTexBufferOES, target, internalformat, buffer);
-}
-void API_ENTRY(glTexBufferRangeOES)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) {
-    CALL_GL_API(glTexBufferRangeOES, target, internalformat, buffer, offset, size);
-}
-void API_ENTRY(glTexStorage3DMultisampleOES)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) {
-    CALL_GL_API(glTexStorage3DMultisampleOES, target, samples, internalformat, width, height, depth, fixedsamplelocations);
-}
-void API_ENTRY(glTextureViewOES)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) {
-    CALL_GL_API(glTextureViewOES, texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);
-}
-void API_ENTRY(glBindVertexArrayOES)(GLuint array) {
-    CALL_GL_API(glBindVertexArrayOES, array);
-}
-void API_ENTRY(glDeleteVertexArraysOES)(GLsizei n, const GLuint *arrays) {
-    CALL_GL_API(glDeleteVertexArraysOES, n, arrays);
-}
-void API_ENTRY(glGenVertexArraysOES)(GLsizei n, GLuint *arrays) {
-    CALL_GL_API(glGenVertexArraysOES, n, arrays);
-}
-GLboolean API_ENTRY(glIsVertexArrayOES)(GLuint array) {
-    CALL_GL_API_RETURN(glIsVertexArrayOES, array);
-}
-void API_ENTRY(glDrawArraysInstancedBaseInstanceEXT)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance) {
-    CALL_GL_API(glDrawArraysInstancedBaseInstanceEXT, mode, first, count, instancecount, baseinstance);
-}
-void API_ENTRY(glDrawElementsInstancedBaseInstanceEXT)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance) {
-    CALL_GL_API(glDrawElementsInstancedBaseInstanceEXT, mode, count, type, indices, instancecount, baseinstance);
-}
-void API_ENTRY(glDrawElementsInstancedBaseVertexBaseInstanceEXT)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) {
-    CALL_GL_API(glDrawElementsInstancedBaseVertexBaseInstanceEXT, mode, count, type, indices, instancecount, basevertex, baseinstance);
-}
-void API_ENTRY(glBindFragDataLocationIndexedEXT)(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name) {
-    CALL_GL_API(glBindFragDataLocationIndexedEXT, program, colorNumber, index, name);
-}
-void API_ENTRY(glBindFragDataLocationEXT)(GLuint program, GLuint color, const GLchar *name) {
-    CALL_GL_API(glBindFragDataLocationEXT, program, color, name);
-}
-GLint API_ENTRY(glGetProgramResourceLocationIndexEXT)(GLuint program, GLenum programInterface, const GLchar *name) {
-    CALL_GL_API_RETURN(glGetProgramResourceLocationIndexEXT, program, programInterface, name);
-}
-GLint API_ENTRY(glGetFragDataIndexEXT)(GLuint program, const GLchar *name) {
-    CALL_GL_API_RETURN(glGetFragDataIndexEXT, program, name);
-}
-void API_ENTRY(glBufferStorageEXT)(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags) {
-    CALL_GL_API(glBufferStorageEXT, target, size, data, flags);
-}
-void API_ENTRY(glCopyImageSubDataEXT)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) {
-    CALL_GL_API(glCopyImageSubDataEXT, srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);
-}
-void API_ENTRY(glLabelObjectEXT)(GLenum type, GLuint object, GLsizei length, const GLchar *label) {
-    CALL_GL_API(glLabelObjectEXT, type, object, length, label);
-}
-void API_ENTRY(glGetObjectLabelEXT)(GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label) {
-    CALL_GL_API(glGetObjectLabelEXT, type, object, bufSize, length, label);
-}
-void API_ENTRY(glInsertEventMarkerEXT)(GLsizei length, const GLchar *marker) {
-    CALL_GL_API(glInsertEventMarkerEXT, length, marker);
-}
-void API_ENTRY(glPushGroupMarkerEXT)(GLsizei length, const GLchar *marker) {
-    CALL_GL_API(glPushGroupMarkerEXT, length, marker);
-}
-void API_ENTRY(glPopGroupMarkerEXT)(void) {
-    CALL_GL_API(glPopGroupMarkerEXT);
-}
-void API_ENTRY(glDiscardFramebufferEXT)(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
-    CALL_GL_API(glDiscardFramebufferEXT, target, numAttachments, attachments);
-}
-void API_ENTRY(glGenQueriesEXT)(GLsizei n, GLuint *ids) {
-    CALL_GL_API(glGenQueriesEXT, n, ids);
-}
-void API_ENTRY(glDeleteQueriesEXT)(GLsizei n, const GLuint *ids) {
-    CALL_GL_API(glDeleteQueriesEXT, n, ids);
-}
-GLboolean API_ENTRY(glIsQueryEXT)(GLuint id) {
-    CALL_GL_API_RETURN(glIsQueryEXT, id);
-}
-void API_ENTRY(glBeginQueryEXT)(GLenum target, GLuint id) {
-    CALL_GL_API(glBeginQueryEXT, target, id);
-}
-void API_ENTRY(glEndQueryEXT)(GLenum target) {
-    CALL_GL_API(glEndQueryEXT, target);
-}
-void API_ENTRY(glQueryCounterEXT)(GLuint id, GLenum target) {
-    CALL_GL_API(glQueryCounterEXT, id, target);
-}
-void API_ENTRY(glGetQueryivEXT)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetQueryivEXT, target, pname, params);
-}
-void API_ENTRY(glGetQueryObjectivEXT)(GLuint id, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetQueryObjectivEXT, id, pname, params);
-}
-void API_ENTRY(glGetQueryObjectuivEXT)(GLuint id, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetQueryObjectuivEXT, id, pname, params);
-}
-void API_ENTRY(glGetQueryObjecti64vEXT)(GLuint id, GLenum pname, GLint64 *params) {
-    CALL_GL_API(glGetQueryObjecti64vEXT, id, pname, params);
-}
-void API_ENTRY(glGetQueryObjectui64vEXT)(GLuint id, GLenum pname, GLuint64 *params) {
-    CALL_GL_API(glGetQueryObjectui64vEXT, id, pname, params);
-}
-void API_ENTRY(glDrawBuffersEXT)(GLsizei n, const GLenum *bufs) {
-    CALL_GL_API(glDrawBuffersEXT, n, bufs);
-}
-void API_ENTRY(glEnableiEXT)(GLenum target, GLuint index) {
-    CALL_GL_API(glEnableiEXT, target, index);
-}
-void API_ENTRY(glDisableiEXT)(GLenum target, GLuint index) {
-    CALL_GL_API(glDisableiEXT, target, index);
-}
-void API_ENTRY(glBlendEquationiEXT)(GLuint buf, GLenum mode) {
-    CALL_GL_API(glBlendEquationiEXT, buf, mode);
-}
-void API_ENTRY(glBlendEquationSeparateiEXT)(GLuint buf, GLenum modeRGB, GLenum modeAlpha) {
-    CALL_GL_API(glBlendEquationSeparateiEXT, buf, modeRGB, modeAlpha);
-}
-void API_ENTRY(glBlendFunciEXT)(GLuint buf, GLenum src, GLenum dst) {
-    CALL_GL_API(glBlendFunciEXT, buf, src, dst);
-}
-void API_ENTRY(glBlendFuncSeparateiEXT)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
-    CALL_GL_API(glBlendFuncSeparateiEXT, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-void API_ENTRY(glColorMaskiEXT)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
-    CALL_GL_API(glColorMaskiEXT, index, r, g, b, a);
-}
-GLboolean API_ENTRY(glIsEnablediEXT)(GLenum target, GLuint index) {
-    CALL_GL_API_RETURN(glIsEnablediEXT, target, index);
-}
-void API_ENTRY(glDrawElementsBaseVertexEXT)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex) {
-    CALL_GL_API(glDrawElementsBaseVertexEXT, mode, count, type, indices, basevertex);
-}
-void API_ENTRY(glDrawRangeElementsBaseVertexEXT)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex) {
-    CALL_GL_API(glDrawRangeElementsBaseVertexEXT, mode, start, end, count, type, indices, basevertex);
-}
-void API_ENTRY(glDrawElementsInstancedBaseVertexEXT)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex) {
-    CALL_GL_API(glDrawElementsInstancedBaseVertexEXT, mode, count, type, indices, instancecount, basevertex);
-}
-void API_ENTRY(glMultiDrawElementsBaseVertexEXT)(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex) {
-    CALL_GL_API(glMultiDrawElementsBaseVertexEXT, mode, count, type, indices, primcount, basevertex);
-}
-void API_ENTRY(glDrawArraysInstancedEXT)(GLenum mode, GLint start, GLsizei count, GLsizei primcount) {
-    CALL_GL_API(glDrawArraysInstancedEXT, mode, start, count, primcount);
-}
-void API_ENTRY(glDrawElementsInstancedEXT)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount) {
-    CALL_GL_API(glDrawElementsInstancedEXT, mode, count, type, indices, primcount);
-}
-void API_ENTRY(glFramebufferTextureEXT)(GLenum target, GLenum attachment, GLuint texture, GLint level) {
-    CALL_GL_API(glFramebufferTextureEXT, target, attachment, texture, level);
-}
-void API_ENTRY(glVertexAttribDivisorEXT)(GLuint index, GLuint divisor) {
-    CALL_GL_API(glVertexAttribDivisorEXT, index, divisor);
-}
-void * API_ENTRY(glMapBufferRangeEXT)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
-    CALL_GL_API_RETURN(glMapBufferRangeEXT, target, offset, length, access);
-}
-void API_ENTRY(glFlushMappedBufferRangeEXT)(GLenum target, GLintptr offset, GLsizeiptr length) {
-    CALL_GL_API(glFlushMappedBufferRangeEXT, target, offset, length);
-}
-void API_ENTRY(glMultiDrawArraysEXT)(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) {
-    CALL_GL_API(glMultiDrawArraysEXT, mode, first, count, primcount);
-}
-void API_ENTRY(glMultiDrawElementsEXT)(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount) {
-    CALL_GL_API(glMultiDrawElementsEXT, mode, count, type, indices, primcount);
-}
-void API_ENTRY(glMultiDrawArraysIndirectEXT)(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride) {
-    CALL_GL_API(glMultiDrawArraysIndirectEXT, mode, indirect, drawcount, stride);
-}
-void API_ENTRY(glMultiDrawElementsIndirectEXT)(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride) {
-    CALL_GL_API(glMultiDrawElementsIndirectEXT, mode, type, indirect, drawcount, stride);
-}
-void API_ENTRY(glRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
-    CALL_GL_API(glRenderbufferStorageMultisampleEXT, target, samples, internalformat, width, height);
-}
-void API_ENTRY(glFramebufferTexture2DMultisampleEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
-    CALL_GL_API(glFramebufferTexture2DMultisampleEXT, target, attachment, textarget, texture, level, samples);
-}
-void API_ENTRY(glReadBufferIndexedEXT)(GLenum src, GLint index) {
-    CALL_GL_API(glReadBufferIndexedEXT, src, index);
-}
-void API_ENTRY(glDrawBuffersIndexedEXT)(GLint n, const GLenum *location, const GLint *indices) {
-    CALL_GL_API(glDrawBuffersIndexedEXT, n, location, indices);
-}
-void API_ENTRY(glGetIntegeri_vEXT)(GLenum target, GLuint index, GLint *data) {
-    CALL_GL_API(glGetIntegeri_vEXT, target, index, data);
-}
-void API_ENTRY(glPrimitiveBoundingBoxEXT)(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW) {
-    CALL_GL_API(glPrimitiveBoundingBoxEXT, minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
-}
-void API_ENTRY(glRasterSamplesEXT)(GLuint samples, GLboolean fixedsamplelocations) {
-    CALL_GL_API(glRasterSamplesEXT, samples, fixedsamplelocations);
-}
-GLenum API_ENTRY(glGetGraphicsResetStatusEXT)(void) {
-    CALL_GL_API_RETURN(glGetGraphicsResetStatusEXT);
-}
-void API_ENTRY(glReadnPixelsEXT)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data) {
-    CALL_GL_API(glReadnPixelsEXT, x, y, width, height, format, type, bufSize, data);
-}
-void API_ENTRY(glGetnUniformfvEXT)(GLuint program, GLint location, GLsizei bufSize, GLfloat *params) {
-    CALL_GL_API(glGetnUniformfvEXT, program, location, bufSize, params);
-}
-void API_ENTRY(glGetnUniformivEXT)(GLuint program, GLint location, GLsizei bufSize, GLint *params) {
-    CALL_GL_API(glGetnUniformivEXT, program, location, bufSize, params);
-}
-void API_ENTRY(glActiveShaderProgramEXT)(GLuint pipeline, GLuint program) {
-    CALL_GL_API(glActiveShaderProgramEXT, pipeline, program);
-}
-void API_ENTRY(glBindProgramPipelineEXT)(GLuint pipeline) {
-    CALL_GL_API(glBindProgramPipelineEXT, pipeline);
-}
-GLuint API_ENTRY(glCreateShaderProgramvEXT)(GLenum type, GLsizei count, const GLchar **strings) {
-    CALL_GL_API_RETURN(glCreateShaderProgramvEXT, type, count, strings);
-}
-void API_ENTRY(glDeleteProgramPipelinesEXT)(GLsizei n, const GLuint *pipelines) {
-    CALL_GL_API(glDeleteProgramPipelinesEXT, n, pipelines);
-}
-void API_ENTRY(glGenProgramPipelinesEXT)(GLsizei n, GLuint *pipelines) {
-    CALL_GL_API(glGenProgramPipelinesEXT, n, pipelines);
-}
-void API_ENTRY(glGetProgramPipelineInfoLogEXT)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog) {
-    CALL_GL_API(glGetProgramPipelineInfoLogEXT, pipeline, bufSize, length, infoLog);
-}
-void API_ENTRY(glGetProgramPipelineivEXT)(GLuint pipeline, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetProgramPipelineivEXT, pipeline, pname, params);
-}
-GLboolean API_ENTRY(glIsProgramPipelineEXT)(GLuint pipeline) {
-    CALL_GL_API_RETURN(glIsProgramPipelineEXT, pipeline);
-}
-void API_ENTRY(glProgramParameteriEXT)(GLuint program, GLenum pname, GLint value) {
-    CALL_GL_API(glProgramParameteriEXT, program, pname, value);
-}
-void API_ENTRY(glProgramUniform1fEXT)(GLuint program, GLint location, GLfloat v0) {
-    CALL_GL_API(glProgramUniform1fEXT, program, location, v0);
-}
-void API_ENTRY(glProgramUniform1fvEXT)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glProgramUniform1fvEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform1iEXT)(GLuint program, GLint location, GLint v0) {
-    CALL_GL_API(glProgramUniform1iEXT, program, location, v0);
-}
-void API_ENTRY(glProgramUniform1ivEXT)(GLuint program, GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glProgramUniform1ivEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform2fEXT)(GLuint program, GLint location, GLfloat v0, GLfloat v1) {
-    CALL_GL_API(glProgramUniform2fEXT, program, location, v0, v1);
-}
-void API_ENTRY(glProgramUniform2fvEXT)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glProgramUniform2fvEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform2iEXT)(GLuint program, GLint location, GLint v0, GLint v1) {
-    CALL_GL_API(glProgramUniform2iEXT, program, location, v0, v1);
-}
-void API_ENTRY(glProgramUniform2ivEXT)(GLuint program, GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glProgramUniform2ivEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform3fEXT)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
-    CALL_GL_API(glProgramUniform3fEXT, program, location, v0, v1, v2);
-}
-void API_ENTRY(glProgramUniform3fvEXT)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glProgramUniform3fvEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform3iEXT)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) {
-    CALL_GL_API(glProgramUniform3iEXT, program, location, v0, v1, v2);
-}
-void API_ENTRY(glProgramUniform3ivEXT)(GLuint program, GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glProgramUniform3ivEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform4fEXT)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
-    CALL_GL_API(glProgramUniform4fEXT, program, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glProgramUniform4fvEXT)(GLuint program, GLint location, GLsizei count, const GLfloat *value) {
-    CALL_GL_API(glProgramUniform4fvEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform4iEXT)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
-    CALL_GL_API(glProgramUniform4iEXT, program, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glProgramUniform4ivEXT)(GLuint program, GLint location, GLsizei count, const GLint *value) {
-    CALL_GL_API(glProgramUniform4ivEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniformMatrix2fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix2fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix3fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix3fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix4fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix4fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glUseProgramStagesEXT)(GLuint pipeline, GLbitfield stages, GLuint program) {
-    CALL_GL_API(glUseProgramStagesEXT, pipeline, stages, program);
-}
-void API_ENTRY(glValidateProgramPipelineEXT)(GLuint pipeline) {
-    CALL_GL_API(glValidateProgramPipelineEXT, pipeline);
-}
-void API_ENTRY(glProgramUniform1uiEXT)(GLuint program, GLint location, GLuint v0) {
-    CALL_GL_API(glProgramUniform1uiEXT, program, location, v0);
-}
-void API_ENTRY(glProgramUniform2uiEXT)(GLuint program, GLint location, GLuint v0, GLuint v1) {
-    CALL_GL_API(glProgramUniform2uiEXT, program, location, v0, v1);
-}
-void API_ENTRY(glProgramUniform3uiEXT)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) {
-    CALL_GL_API(glProgramUniform3uiEXT, program, location, v0, v1, v2);
-}
-void API_ENTRY(glProgramUniform4uiEXT)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
-    CALL_GL_API(glProgramUniform4uiEXT, program, location, v0, v1, v2, v3);
-}
-void API_ENTRY(glProgramUniform1uivEXT)(GLuint program, GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glProgramUniform1uivEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform2uivEXT)(GLuint program, GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glProgramUniform2uivEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform3uivEXT)(GLuint program, GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glProgramUniform3uivEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniform4uivEXT)(GLuint program, GLint location, GLsizei count, const GLuint *value) {
-    CALL_GL_API(glProgramUniform4uivEXT, program, location, count, value);
-}
-void API_ENTRY(glProgramUniformMatrix2x3fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix2x3fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix3x2fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix3x2fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix2x4fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix2x4fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix4x2fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix4x2fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix3x4fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix3x4fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glProgramUniformMatrix4x3fvEXT)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
-    CALL_GL_API(glProgramUniformMatrix4x3fvEXT, program, location, count, transpose, value);
-}
-void API_ENTRY(glTexPageCommitmentEXT)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit) {
-    CALL_GL_API(glTexPageCommitmentEXT, target, level, xoffset, yoffset, zoffset, width, height, depth, commit);
-}
-void API_ENTRY(glPatchParameteriEXT)(GLenum pname, GLint value) {
-    CALL_GL_API(glPatchParameteriEXT, pname, value);
-}
-void API_ENTRY(glTexParameterIivEXT)(GLenum target, GLenum pname, const GLint *params) {
-    CALL_GL_API(glTexParameterIivEXT, target, pname, params);
-}
-void API_ENTRY(glTexParameterIuivEXT)(GLenum target, GLenum pname, const GLuint *params) {
-    CALL_GL_API(glTexParameterIuivEXT, target, pname, params);
-}
-void API_ENTRY(glGetTexParameterIivEXT)(GLenum target, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetTexParameterIivEXT, target, pname, params);
-}
-void API_ENTRY(glGetTexParameterIuivEXT)(GLenum target, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetTexParameterIuivEXT, target, pname, params);
-}
-void API_ENTRY(glSamplerParameterIivEXT)(GLuint sampler, GLenum pname, const GLint *param) {
-    CALL_GL_API(glSamplerParameterIivEXT, sampler, pname, param);
-}
-void API_ENTRY(glSamplerParameterIuivEXT)(GLuint sampler, GLenum pname, const GLuint *param) {
-    CALL_GL_API(glSamplerParameterIuivEXT, sampler, pname, param);
-}
-void API_ENTRY(glGetSamplerParameterIivEXT)(GLuint sampler, GLenum pname, GLint *params) {
-    CALL_GL_API(glGetSamplerParameterIivEXT, sampler, pname, params);
-}
-void API_ENTRY(glGetSamplerParameterIuivEXT)(GLuint sampler, GLenum pname, GLuint *params) {
-    CALL_GL_API(glGetSamplerParameterIuivEXT, sampler, pname, params);
-}
-void API_ENTRY(glTexBufferEXT)(GLenum target, GLenum internalformat, GLuint buffer) {
-    CALL_GL_API(glTexBufferEXT, target, internalformat, buffer);
-}
-void API_ENTRY(glTexBufferRangeEXT)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) {
-    CALL_GL_API(glTexBufferRangeEXT, target, internalformat, buffer, offset, size);
-}
-void API_ENTRY(glTexStorage1DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
-    CALL_GL_API(glTexStorage1DEXT, target, levels, internalformat, width);
-}
-void API_ENTRY(glTexStorage2DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
-    CALL_GL_API(glTexStorage2DEXT, target, levels, internalformat, width, height);
-}
-void API_ENTRY(glTexStorage3DEXT)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
-    CALL_GL_API(glTexStorage3DEXT, target, levels, internalformat, width, height, depth);
-}
-void API_ENTRY(glTextureStorage1DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) {
-    CALL_GL_API(glTextureStorage1DEXT, texture, target, levels, internalformat, width);
-}
-void API_ENTRY(glTextureStorage2DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) {
-    CALL_GL_API(glTextureStorage2DEXT, texture, target, levels, internalformat, width, height);
-}
-void API_ENTRY(glTextureStorage3DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) {
-    CALL_GL_API(glTextureStorage3DEXT, texture, target, levels, internalformat, width, height, depth);
-}
-void API_ENTRY(glTextureViewEXT)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) {
-    CALL_GL_API(glTextureViewEXT, texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);
-}
diff --git a/libs/hwui/debug/gles_undefine.h b/libs/hwui/debug/gles_undefine.h
deleted file mode 100644
index e43829d..0000000
--- a/libs/hwui/debug/gles_undefine.h
+++ /dev/null
@@ -1,913 +0,0 @@
-/*
- * 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.
- */
-
-#undef glActiveShaderProgram
-#undef glActiveShaderProgramEXT
-#undef glActiveTexture
-#undef glAlphaFunc
-#undef glAlphaFuncQCOM
-#undef glAlphaFuncx
-#undef glAlphaFuncxOES
-#undef glApplyFramebufferAttachmentCMAAINTEL
-#undef glAttachShader
-#undef glBeginConditionalRenderNV
-#undef glBeginPerfMonitorAMD
-#undef glBeginPerfQueryINTEL
-#undef glBeginQuery
-#undef glBeginQueryEXT
-#undef glBeginTransformFeedback
-#undef glBindAttribLocation
-#undef glBindBuffer
-#undef glBindBufferBase
-#undef glBindBufferRange
-#undef glBindFragDataLocationEXT
-#undef glBindFragDataLocationIndexedEXT
-#undef glBindFramebuffer
-#undef glBindFramebufferOES
-#undef glBindImageTexture
-#undef glBindProgramPipeline
-#undef glBindProgramPipelineEXT
-#undef glBindRenderbuffer
-#undef glBindRenderbufferOES
-#undef glBindSampler
-#undef glBindTexture
-#undef glBindTransformFeedback
-#undef glBindVertexArray
-#undef glBindVertexArrayOES
-#undef glBindVertexBuffer
-#undef glBlendBarrier
-#undef glBlendBarrierKHR
-#undef glBlendBarrierNV
-#undef glBlendColor
-#undef glBlendEquation
-#undef glBlendEquationOES
-#undef glBlendEquationSeparate
-#undef glBlendEquationSeparateOES
-#undef glBlendEquationSeparatei
-#undef glBlendEquationSeparateiEXT
-#undef glBlendEquationSeparateiOES
-#undef glBlendEquationi
-#undef glBlendEquationiEXT
-#undef glBlendEquationiOES
-#undef glBlendFunc
-#undef glBlendFuncSeparate
-#undef glBlendFuncSeparateOES
-#undef glBlendFuncSeparatei
-#undef glBlendFuncSeparateiEXT
-#undef glBlendFuncSeparateiOES
-#undef glBlendFunci
-#undef glBlendFunciEXT
-#undef glBlendFunciOES
-#undef glBlendParameteriNV
-#undef glBlitFramebuffer
-#undef glBlitFramebufferANGLE
-#undef glBlitFramebufferNV
-#undef glBufferData
-#undef glBufferStorageEXT
-#undef glBufferSubData
-#undef glCheckFramebufferStatus
-#undef glCheckFramebufferStatusOES
-#undef glClear
-#undef glClearBufferfi
-#undef glClearBufferfv
-#undef glClearBufferiv
-#undef glClearBufferuiv
-#undef glClearColor
-#undef glClearColorx
-#undef glClearColorxOES
-#undef glClearDepthf
-#undef glClearDepthfOES
-#undef glClearDepthx
-#undef glClearDepthxOES
-#undef glClearStencil
-#undef glClientActiveTexture
-#undef glClientWaitSync
-#undef glClientWaitSyncAPPLE
-#undef glClipPlanef
-#undef glClipPlanefIMG
-#undef glClipPlanefOES
-#undef glClipPlanex
-#undef glClipPlanexIMG
-#undef glClipPlanexOES
-#undef glColor4f
-#undef glColor4ub
-#undef glColor4x
-#undef glColor4xOES
-#undef glColorMask
-#undef glColorMaski
-#undef glColorMaskiEXT
-#undef glColorMaskiOES
-#undef glColorPointer
-#undef glCompileShader
-#undef glCompressedTexImage2D
-#undef glCompressedTexImage3D
-#undef glCompressedTexImage3DOES
-#undef glCompressedTexSubImage2D
-#undef glCompressedTexSubImage3D
-#undef glCompressedTexSubImage3DOES
-#undef glCopyBufferSubData
-#undef glCopyBufferSubDataNV
-#undef glCopyImageSubData
-#undef glCopyImageSubDataEXT
-#undef glCopyImageSubDataOES
-#undef glCopyPathNV
-#undef glCopyTexImage2D
-#undef glCopyTexSubImage2D
-#undef glCopyTexSubImage3D
-#undef glCopyTexSubImage3DOES
-#undef glCopyTextureLevelsAPPLE
-#undef glCoverFillPathInstancedNV
-#undef glCoverFillPathNV
-#undef glCoverStrokePathInstancedNV
-#undef glCoverStrokePathNV
-#undef glCoverageMaskNV
-#undef glCoverageModulationNV
-#undef glCoverageModulationTableNV
-#undef glCoverageOperationNV
-#undef glCreatePerfQueryINTEL
-#undef glCreateProgram
-#undef glCreateShader
-#undef glCreateShaderProgramv
-#undef glCreateShaderProgramvEXT
-#undef glCullFace
-#undef glCurrentPaletteMatrixOES
-#undef glDebugMessageCallback
-#undef glDebugMessageCallbackKHR
-#undef glDebugMessageControl
-#undef glDebugMessageControlKHR
-#undef glDebugMessageInsert
-#undef glDebugMessageInsertKHR
-#undef glDeleteBuffers
-#undef glDeleteFencesNV
-#undef glDeleteFramebuffers
-#undef glDeleteFramebuffersOES
-#undef glDeletePathsNV
-#undef glDeletePerfMonitorsAMD
-#undef glDeletePerfQueryINTEL
-#undef glDeleteProgram
-#undef glDeleteProgramPipelines
-#undef glDeleteProgramPipelinesEXT
-#undef glDeleteQueries
-#undef glDeleteQueriesEXT
-#undef glDeleteRenderbuffers
-#undef glDeleteRenderbuffersOES
-#undef glDeleteSamplers
-#undef glDeleteShader
-#undef glDeleteSync
-#undef glDeleteSyncAPPLE
-#undef glDeleteTextures
-#undef glDeleteTransformFeedbacks
-#undef glDeleteVertexArrays
-#undef glDeleteVertexArraysOES
-#undef glDepthFunc
-#undef glDepthMask
-#undef glDepthRangeArrayfvNV
-#undef glDepthRangeIndexedfNV
-#undef glDepthRangef
-#undef glDepthRangefOES
-#undef glDepthRangex
-#undef glDepthRangexOES
-#undef glDetachShader
-#undef glDisable
-#undef glDisableClientState
-#undef glDisableDriverControlQCOM
-#undef glDisableVertexAttribArray
-#undef glDisablei
-#undef glDisableiEXT
-#undef glDisableiNV
-#undef glDisableiOES
-#undef glDiscardFramebufferEXT
-#undef glDispatchCompute
-#undef glDispatchComputeIndirect
-#undef glDrawArrays
-#undef glDrawArraysIndirect
-#undef glDrawArraysInstanced
-#undef glDrawArraysInstancedANGLE
-#undef glDrawArraysInstancedBaseInstanceEXT
-#undef glDrawArraysInstancedEXT
-#undef glDrawArraysInstancedNV
-#undef glDrawBuffers
-#undef glDrawBuffersEXT
-#undef glDrawBuffersIndexedEXT
-#undef glDrawBuffersNV
-#undef glDrawElements
-#undef glDrawElementsBaseVertex
-#undef glDrawElementsBaseVertexEXT
-#undef glDrawElementsBaseVertexOES
-#undef glDrawElementsIndirect
-#undef glDrawElementsInstanced
-#undef glDrawElementsInstancedANGLE
-#undef glDrawElementsInstancedBaseInstanceEXT
-#undef glDrawElementsInstancedBaseVertex
-#undef glDrawElementsInstancedBaseVertexBaseInstanceEXT
-#undef glDrawElementsInstancedBaseVertexEXT
-#undef glDrawElementsInstancedBaseVertexOES
-#undef glDrawElementsInstancedEXT
-#undef glDrawElementsInstancedNV
-#undef glDrawRangeElements
-#undef glDrawRangeElementsBaseVertex
-#undef glDrawRangeElementsBaseVertexEXT
-#undef glDrawRangeElementsBaseVertexOES
-#undef glDrawTexfOES
-#undef glDrawTexfvOES
-#undef glDrawTexiOES
-#undef glDrawTexivOES
-#undef glDrawTexsOES
-#undef glDrawTexsvOES
-#undef glDrawTexxOES
-#undef glDrawTexxvOES
-#undef glEGLImageTargetRenderbufferStorageOES
-#undef glEGLImageTargetTexture2DOES
-#undef glEnable
-#undef glEnableClientState
-#undef glEnableDriverControlQCOM
-#undef glEnableVertexAttribArray
-#undef glEnablei
-#undef glEnableiEXT
-#undef glEnableiNV
-#undef glEnableiOES
-#undef glEndConditionalRenderNV
-#undef glEndPerfMonitorAMD
-#undef glEndPerfQueryINTEL
-#undef glEndQuery
-#undef glEndQueryEXT
-#undef glEndTilingQCOM
-#undef glEndTransformFeedback
-#undef glExtGetBufferPointervQCOM
-#undef glExtGetBuffersQCOM
-#undef glExtGetFramebuffersQCOM
-#undef glExtGetProgramBinarySourceQCOM
-#undef glExtGetProgramsQCOM
-#undef glExtGetRenderbuffersQCOM
-#undef glExtGetShadersQCOM
-#undef glExtGetTexLevelParameterivQCOM
-#undef glExtGetTexSubImageQCOM
-#undef glExtGetTexturesQCOM
-#undef glExtIsProgramBinaryQCOM
-#undef glExtTexObjectStateOverrideiQCOM
-#undef glFenceSync
-#undef glFenceSyncAPPLE
-#undef glFinish
-#undef glFinishFenceNV
-#undef glFlush
-#undef glFlushMappedBufferRange
-#undef glFlushMappedBufferRangeEXT
-#undef glFogf
-#undef glFogfv
-#undef glFogx
-#undef glFogxOES
-#undef glFogxv
-#undef glFogxvOES
-#undef glFragmentCoverageColorNV
-#undef glFramebufferParameteri
-#undef glFramebufferRenderbuffer
-#undef glFramebufferRenderbufferOES
-#undef glFramebufferSampleLocationsfvNV
-#undef glFramebufferTexture
-#undef glFramebufferTexture2D
-#undef glFramebufferTexture2DMultisampleEXT
-#undef glFramebufferTexture2DMultisampleIMG
-#undef glFramebufferTexture2DOES
-#undef glFramebufferTexture3DOES
-#undef glFramebufferTextureEXT
-#undef glFramebufferTextureLayer
-#undef glFramebufferTextureMultisampleMultiviewOVR
-#undef glFramebufferTextureMultiviewOVR
-#undef glFramebufferTextureOES
-#undef glFrontFace
-#undef glFrustumf
-#undef glFrustumfOES
-#undef glFrustumx
-#undef glFrustumxOES
-#undef glGenBuffers
-#undef glGenFencesNV
-#undef glGenFramebuffers
-#undef glGenFramebuffersOES
-#undef glGenPathsNV
-#undef glGenPerfMonitorsAMD
-#undef glGenProgramPipelines
-#undef glGenProgramPipelinesEXT
-#undef glGenQueries
-#undef glGenQueriesEXT
-#undef glGenRenderbuffers
-#undef glGenRenderbuffersOES
-#undef glGenSamplers
-#undef glGenTextures
-#undef glGenTransformFeedbacks
-#undef glGenVertexArrays
-#undef glGenVertexArraysOES
-#undef glGenerateMipmap
-#undef glGenerateMipmapOES
-#undef glGetActiveAttrib
-#undef glGetActiveUniform
-#undef glGetActiveUniformBlockName
-#undef glGetActiveUniformBlockiv
-#undef glGetActiveUniformsiv
-#undef glGetAttachedShaders
-#undef glGetAttribLocation
-#undef glGetBooleani_v
-#undef glGetBooleanv
-#undef glGetBufferParameteri64v
-#undef glGetBufferParameteriv
-#undef glGetBufferPointerv
-#undef glGetBufferPointervOES
-#undef glGetClipPlanef
-#undef glGetClipPlanefOES
-#undef glGetClipPlanex
-#undef glGetClipPlanexOES
-#undef glGetCoverageModulationTableNV
-#undef glGetDebugMessageLog
-#undef glGetDebugMessageLogKHR
-#undef glGetDriverControlStringQCOM
-#undef glGetDriverControlsQCOM
-#undef glGetError
-#undef glGetFenceivNV
-#undef glGetFirstPerfQueryIdINTEL
-#undef glGetFixedv
-#undef glGetFixedvOES
-#undef glGetFloati_vNV
-#undef glGetFloatv
-#undef glGetFragDataIndexEXT
-#undef glGetFragDataLocation
-#undef glGetFramebufferAttachmentParameteriv
-#undef glGetFramebufferAttachmentParameterivOES
-#undef glGetFramebufferParameteriv
-#undef glGetGraphicsResetStatus
-#undef glGetGraphicsResetStatusEXT
-#undef glGetGraphicsResetStatusKHR
-#undef glGetImageHandleNV
-#undef glGetInteger64i_v
-#undef glGetInteger64v
-#undef glGetInteger64vAPPLE
-#undef glGetIntegeri_v
-#undef glGetIntegeri_vEXT
-#undef glGetIntegerv
-#undef glGetInternalformatSampleivNV
-#undef glGetInternalformativ
-#undef glGetLightfv
-#undef glGetLightxv
-#undef glGetLightxvOES
-#undef glGetMaterialfv
-#undef glGetMaterialxv
-#undef glGetMaterialxvOES
-#undef glGetMultisamplefv
-#undef glGetNextPerfQueryIdINTEL
-#undef glGetObjectLabel
-#undef glGetObjectLabelEXT
-#undef glGetObjectLabelKHR
-#undef glGetObjectPtrLabel
-#undef glGetObjectPtrLabelKHR
-#undef glGetPathCommandsNV
-#undef glGetPathCoordsNV
-#undef glGetPathDashArrayNV
-#undef glGetPathLengthNV
-#undef glGetPathMetricRangeNV
-#undef glGetPathMetricsNV
-#undef glGetPathParameterfvNV
-#undef glGetPathParameterivNV
-#undef glGetPathSpacingNV
-#undef glGetPerfCounterInfoINTEL
-#undef glGetPerfMonitorCounterDataAMD
-#undef glGetPerfMonitorCounterInfoAMD
-#undef glGetPerfMonitorCounterStringAMD
-#undef glGetPerfMonitorCountersAMD
-#undef glGetPerfMonitorGroupStringAMD
-#undef glGetPerfMonitorGroupsAMD
-#undef glGetPerfQueryDataINTEL
-#undef glGetPerfQueryIdByNameINTEL
-#undef glGetPerfQueryInfoINTEL
-#undef glGetPointerv
-#undef glGetPointervKHR
-#undef glGetProgramBinary
-#undef glGetProgramBinaryOES
-#undef glGetProgramInfoLog
-#undef glGetProgramInterfaceiv
-#undef glGetProgramPipelineInfoLog
-#undef glGetProgramPipelineInfoLogEXT
-#undef glGetProgramPipelineiv
-#undef glGetProgramPipelineivEXT
-#undef glGetProgramResourceIndex
-#undef glGetProgramResourceLocation
-#undef glGetProgramResourceLocationIndexEXT
-#undef glGetProgramResourceName
-#undef glGetProgramResourcefvNV
-#undef glGetProgramResourceiv
-#undef glGetProgramiv
-#undef glGetQueryObjecti64vEXT
-#undef glGetQueryObjectivEXT
-#undef glGetQueryObjectui64vEXT
-#undef glGetQueryObjectuiv
-#undef glGetQueryObjectuivEXT
-#undef glGetQueryiv
-#undef glGetQueryivEXT
-#undef glGetRenderbufferParameteriv
-#undef glGetRenderbufferParameterivOES
-#undef glGetSamplerParameterIiv
-#undef glGetSamplerParameterIivEXT
-#undef glGetSamplerParameterIivOES
-#undef glGetSamplerParameterIuiv
-#undef glGetSamplerParameterIuivEXT
-#undef glGetSamplerParameterIuivOES
-#undef glGetSamplerParameterfv
-#undef glGetSamplerParameteriv
-#undef glGetShaderInfoLog
-#undef glGetShaderPrecisionFormat
-#undef glGetShaderSource
-#undef glGetShaderiv
-#undef glGetString
-#undef glGetStringi
-#undef glGetSynciv
-#undef glGetSyncivAPPLE
-#undef glGetTexEnvfv
-#undef glGetTexEnviv
-#undef glGetTexEnvxv
-#undef glGetTexEnvxvOES
-#undef glGetTexGenfvOES
-#undef glGetTexGenivOES
-#undef glGetTexGenxvOES
-#undef glGetTexLevelParameterfv
-#undef glGetTexLevelParameteriv
-#undef glGetTexParameterIiv
-#undef glGetTexParameterIivEXT
-#undef glGetTexParameterIivOES
-#undef glGetTexParameterIuiv
-#undef glGetTexParameterIuivEXT
-#undef glGetTexParameterIuivOES
-#undef glGetTexParameterfv
-#undef glGetTexParameteriv
-#undef glGetTexParameterxv
-#undef glGetTexParameterxvOES
-#undef glGetTextureHandleNV
-#undef glGetTextureSamplerHandleNV
-#undef glGetTransformFeedbackVarying
-#undef glGetTranslatedShaderSourceANGLE
-#undef glGetUniformBlockIndex
-#undef glGetUniformIndices
-#undef glGetUniformLocation
-#undef glGetUniformfv
-#undef glGetUniformiv
-#undef glGetUniformuiv
-#undef glGetVertexAttribIiv
-#undef glGetVertexAttribIuiv
-#undef glGetVertexAttribPointerv
-#undef glGetVertexAttribfv
-#undef glGetVertexAttribiv
-#undef glGetnUniformfv
-#undef glGetnUniformfvEXT
-#undef glGetnUniformfvKHR
-#undef glGetnUniformiv
-#undef glGetnUniformivEXT
-#undef glGetnUniformivKHR
-#undef glGetnUniformuiv
-#undef glGetnUniformuivKHR
-#undef glHint
-#undef glInsertEventMarkerEXT
-#undef glInterpolatePathsNV
-#undef glInvalidateFramebuffer
-#undef glInvalidateSubFramebuffer
-#undef glIsBuffer
-#undef glIsEnabled
-#undef glIsEnabledi
-#undef glIsEnablediEXT
-#undef glIsEnablediNV
-#undef glIsEnablediOES
-#undef glIsFenceNV
-#undef glIsFramebuffer
-#undef glIsFramebufferOES
-#undef glIsImageHandleResidentNV
-#undef glIsPathNV
-#undef glIsPointInFillPathNV
-#undef glIsPointInStrokePathNV
-#undef glIsProgram
-#undef glIsProgramPipeline
-#undef glIsProgramPipelineEXT
-#undef glIsQuery
-#undef glIsQueryEXT
-#undef glIsRenderbuffer
-#undef glIsRenderbufferOES
-#undef glIsSampler
-#undef glIsShader
-#undef glIsSync
-#undef glIsSyncAPPLE
-#undef glIsTexture
-#undef glIsTextureHandleResidentNV
-#undef glIsTransformFeedback
-#undef glIsVertexArray
-#undef glIsVertexArrayOES
-#undef glLabelObjectEXT
-#undef glLightModelf
-#undef glLightModelfv
-#undef glLightModelx
-#undef glLightModelxOES
-#undef glLightModelxv
-#undef glLightModelxvOES
-#undef glLightf
-#undef glLightfv
-#undef glLightx
-#undef glLightxOES
-#undef glLightxv
-#undef glLightxvOES
-#undef glLineWidth
-#undef glLineWidthx
-#undef glLineWidthxOES
-#undef glLinkProgram
-#undef glLoadIdentity
-#undef glLoadMatrixf
-#undef glLoadMatrixx
-#undef glLoadMatrixxOES
-#undef glLoadPaletteFromModelViewMatrixOES
-#undef glLogicOp
-#undef glMakeImageHandleNonResidentNV
-#undef glMakeImageHandleResidentNV
-#undef glMakeTextureHandleNonResidentNV
-#undef glMakeTextureHandleResidentNV
-#undef glMapBufferOES
-#undef glMapBufferRange
-#undef glMapBufferRangeEXT
-#undef glMaterialf
-#undef glMaterialfv
-#undef glMaterialx
-#undef glMaterialxOES
-#undef glMaterialxv
-#undef glMaterialxvOES
-#undef glMatrixIndexPointerOES
-#undef glMatrixLoad3x2fNV
-#undef glMatrixLoad3x3fNV
-#undef glMatrixLoadTranspose3x3fNV
-#undef glMatrixMode
-#undef glMatrixMult3x2fNV
-#undef glMatrixMult3x3fNV
-#undef glMatrixMultTranspose3x3fNV
-#undef glMemoryBarrier
-#undef glMemoryBarrierByRegion
-#undef glMinSampleShading
-#undef glMinSampleShadingOES
-#undef glMultMatrixf
-#undef glMultMatrixx
-#undef glMultMatrixxOES
-#undef glMultiDrawArraysEXT
-#undef glMultiDrawArraysIndirectEXT
-#undef glMultiDrawElementsBaseVertexEXT
-#undef glMultiDrawElementsBaseVertexOES
-#undef glMultiDrawElementsEXT
-#undef glMultiDrawElementsIndirectEXT
-#undef glMultiTexCoord4f
-#undef glMultiTexCoord4x
-#undef glMultiTexCoord4xOES
-#undef glNamedFramebufferSampleLocationsfvNV
-#undef glNormal3f
-#undef glNormal3x
-#undef glNormal3xOES
-#undef glNormalPointer
-#undef glObjectLabel
-#undef glObjectLabelKHR
-#undef glObjectPtrLabel
-#undef glObjectPtrLabelKHR
-#undef glOrthof
-#undef glOrthofOES
-#undef glOrthox
-#undef glOrthoxOES
-#undef glPatchParameteri
-#undef glPatchParameteriEXT
-#undef glPatchParameteriOES
-#undef glPathCommandsNV
-#undef glPathCoordsNV
-#undef glPathCoverDepthFuncNV
-#undef glPathDashArrayNV
-#undef glPathGlyphIndexArrayNV
-#undef glPathGlyphIndexRangeNV
-#undef glPathGlyphRangeNV
-#undef glPathGlyphsNV
-#undef glPathMemoryGlyphIndexArrayNV
-#undef glPathParameterfNV
-#undef glPathParameterfvNV
-#undef glPathParameteriNV
-#undef glPathParameterivNV
-#undef glPathStencilDepthOffsetNV
-#undef glPathStencilFuncNV
-#undef glPathStringNV
-#undef glPathSubCommandsNV
-#undef glPathSubCoordsNV
-#undef glPauseTransformFeedback
-#undef glPixelStorei
-#undef glPointAlongPathNV
-#undef glPointParameterf
-#undef glPointParameterfv
-#undef glPointParameterx
-#undef glPointParameterxOES
-#undef glPointParameterxv
-#undef glPointParameterxvOES
-#undef glPointSize
-#undef glPointSizePointerOES
-#undef glPointSizex
-#undef glPointSizexOES
-#undef glPolygonModeNV
-#undef glPolygonOffset
-#undef glPolygonOffsetx
-#undef glPolygonOffsetxOES
-#undef glPopDebugGroup
-#undef glPopDebugGroupKHR
-#undef glPopGroupMarkerEXT
-#undef glPopMatrix
-#undef glPrimitiveBoundingBox
-#undef glPrimitiveBoundingBoxEXT
-#undef glPrimitiveBoundingBoxOES
-#undef glProgramBinary
-#undef glProgramBinaryOES
-#undef glProgramParameteri
-#undef glProgramParameteriEXT
-#undef glProgramPathFragmentInputGenNV
-#undef glProgramUniform1f
-#undef glProgramUniform1fEXT
-#undef glProgramUniform1fv
-#undef glProgramUniform1fvEXT
-#undef glProgramUniform1i
-#undef glProgramUniform1iEXT
-#undef glProgramUniform1iv
-#undef glProgramUniform1ivEXT
-#undef glProgramUniform1ui
-#undef glProgramUniform1uiEXT
-#undef glProgramUniform1uiv
-#undef glProgramUniform1uivEXT
-#undef glProgramUniform2f
-#undef glProgramUniform2fEXT
-#undef glProgramUniform2fv
-#undef glProgramUniform2fvEXT
-#undef glProgramUniform2i
-#undef glProgramUniform2iEXT
-#undef glProgramUniform2iv
-#undef glProgramUniform2ivEXT
-#undef glProgramUniform2ui
-#undef glProgramUniform2uiEXT
-#undef glProgramUniform2uiv
-#undef glProgramUniform2uivEXT
-#undef glProgramUniform3f
-#undef glProgramUniform3fEXT
-#undef glProgramUniform3fv
-#undef glProgramUniform3fvEXT
-#undef glProgramUniform3i
-#undef glProgramUniform3iEXT
-#undef glProgramUniform3iv
-#undef glProgramUniform3ivEXT
-#undef glProgramUniform3ui
-#undef glProgramUniform3uiEXT
-#undef glProgramUniform3uiv
-#undef glProgramUniform3uivEXT
-#undef glProgramUniform4f
-#undef glProgramUniform4fEXT
-#undef glProgramUniform4fv
-#undef glProgramUniform4fvEXT
-#undef glProgramUniform4i
-#undef glProgramUniform4iEXT
-#undef glProgramUniform4iv
-#undef glProgramUniform4ivEXT
-#undef glProgramUniform4ui
-#undef glProgramUniform4uiEXT
-#undef glProgramUniform4uiv
-#undef glProgramUniform4uivEXT
-#undef glProgramUniformHandleui64NV
-#undef glProgramUniformHandleui64vNV
-#undef glProgramUniformMatrix2fv
-#undef glProgramUniformMatrix2fvEXT
-#undef glProgramUniformMatrix2x3fv
-#undef glProgramUniformMatrix2x3fvEXT
-#undef glProgramUniformMatrix2x4fv
-#undef glProgramUniformMatrix2x4fvEXT
-#undef glProgramUniformMatrix3fv
-#undef glProgramUniformMatrix3fvEXT
-#undef glProgramUniformMatrix3x2fv
-#undef glProgramUniformMatrix3x2fvEXT
-#undef glProgramUniformMatrix3x4fv
-#undef glProgramUniformMatrix3x4fvEXT
-#undef glProgramUniformMatrix4fv
-#undef glProgramUniformMatrix4fvEXT
-#undef glProgramUniformMatrix4x2fv
-#undef glProgramUniformMatrix4x2fvEXT
-#undef glProgramUniformMatrix4x3fv
-#undef glProgramUniformMatrix4x3fvEXT
-#undef glPushDebugGroup
-#undef glPushDebugGroupKHR
-#undef glPushGroupMarkerEXT
-#undef glPushMatrix
-#undef glQueryCounterEXT
-#undef glQueryMatrixxOES
-#undef glRasterSamplesEXT
-#undef glReadBuffer
-#undef glReadBufferIndexedEXT
-#undef glReadBufferNV
-#undef glReadPixels
-#undef glReadnPixels
-#undef glReadnPixelsEXT
-#undef glReadnPixelsKHR
-#undef glReleaseShaderCompiler
-#undef glRenderbufferStorage
-#undef glRenderbufferStorageMultisample
-#undef glRenderbufferStorageMultisampleANGLE
-#undef glRenderbufferStorageMultisampleAPPLE
-#undef glRenderbufferStorageMultisampleEXT
-#undef glRenderbufferStorageMultisampleIMG
-#undef glRenderbufferStorageMultisampleNV
-#undef glRenderbufferStorageOES
-#undef glResolveDepthValuesNV
-#undef glResolveMultisampleFramebufferAPPLE
-#undef glResumeTransformFeedback
-#undef glRotatef
-#undef glRotatex
-#undef glRotatexOES
-#undef glSampleCoverage
-#undef glSampleCoveragex
-#undef glSampleCoveragexOES
-#undef glSampleMaski
-#undef glSamplerParameterIiv
-#undef glSamplerParameterIivEXT
-#undef glSamplerParameterIivOES
-#undef glSamplerParameterIuiv
-#undef glSamplerParameterIuivEXT
-#undef glSamplerParameterIuivOES
-#undef glSamplerParameterf
-#undef glSamplerParameterfv
-#undef glSamplerParameteri
-#undef glSamplerParameteriv
-#undef glScalef
-#undef glScalex
-#undef glScalexOES
-#undef glScissor
-#undef glScissorArrayvNV
-#undef glScissorIndexedNV
-#undef glScissorIndexedvNV
-#undef glSelectPerfMonitorCountersAMD
-#undef glSetFenceNV
-#undef glShadeModel
-#undef glShaderBinary
-#undef glShaderSource
-#undef glStartTilingQCOM
-#undef glStencilFillPathInstancedNV
-#undef glStencilFillPathNV
-#undef glStencilFunc
-#undef glStencilFuncSeparate
-#undef glStencilMask
-#undef glStencilMaskSeparate
-#undef glStencilOp
-#undef glStencilOpSeparate
-#undef glStencilStrokePathInstancedNV
-#undef glStencilStrokePathNV
-#undef glStencilThenCoverFillPathInstancedNV
-#undef glStencilThenCoverFillPathNV
-#undef glStencilThenCoverStrokePathInstancedNV
-#undef glStencilThenCoverStrokePathNV
-#undef glSubpixelPrecisionBiasNV
-#undef glTestFenceNV
-#undef glTexBuffer
-#undef glTexBufferEXT
-#undef glTexBufferOES
-#undef glTexBufferRange
-#undef glTexBufferRangeEXT
-#undef glTexBufferRangeOES
-#undef glTexCoordPointer
-#undef glTexEnvf
-#undef glTexEnvfv
-#undef glTexEnvi
-#undef glTexEnviv
-#undef glTexEnvx
-#undef glTexEnvxOES
-#undef glTexEnvxv
-#undef glTexEnvxvOES
-#undef glTexGenfOES
-#undef glTexGenfvOES
-#undef glTexGeniOES
-#undef glTexGenivOES
-#undef glTexGenxOES
-#undef glTexGenxvOES
-#undef glTexImage2D
-#undef glTexImage3D
-#undef glTexImage3DOES
-#undef glTexPageCommitmentEXT
-#undef glTexParameterIiv
-#undef glTexParameterIivEXT
-#undef glTexParameterIivOES
-#undef glTexParameterIuiv
-#undef glTexParameterIuivEXT
-#undef glTexParameterIuivOES
-#undef glTexParameterf
-#undef glTexParameterfv
-#undef glTexParameteri
-#undef glTexParameteriv
-#undef glTexParameterx
-#undef glTexParameterxOES
-#undef glTexParameterxv
-#undef glTexParameterxvOES
-#undef glTexStorage1DEXT
-#undef glTexStorage2D
-#undef glTexStorage2DEXT
-#undef glTexStorage2DMultisample
-#undef glTexStorage3D
-#undef glTexStorage3DEXT
-#undef glTexStorage3DMultisample
-#undef glTexStorage3DMultisampleOES
-#undef glTexSubImage2D
-#undef glTexSubImage3D
-#undef glTexSubImage3DOES
-#undef glTextureStorage1DEXT
-#undef glTextureStorage2DEXT
-#undef glTextureStorage3DEXT
-#undef glTextureViewEXT
-#undef glTextureViewOES
-#undef glTransformFeedbackVaryings
-#undef glTransformPathNV
-#undef glTranslatef
-#undef glTranslatex
-#undef glTranslatexOES
-#undef glUniform1f
-#undef glUniform1fv
-#undef glUniform1i
-#undef glUniform1iv
-#undef glUniform1ui
-#undef glUniform1uiv
-#undef glUniform2f
-#undef glUniform2fv
-#undef glUniform2i
-#undef glUniform2iv
-#undef glUniform2ui
-#undef glUniform2uiv
-#undef glUniform3f
-#undef glUniform3fv
-#undef glUniform3i
-#undef glUniform3iv
-#undef glUniform3ui
-#undef glUniform3uiv
-#undef glUniform4f
-#undef glUniform4fv
-#undef glUniform4i
-#undef glUniform4iv
-#undef glUniform4ui
-#undef glUniform4uiv
-#undef glUniformBlockBinding
-#undef glUniformHandleui64NV
-#undef glUniformHandleui64vNV
-#undef glUniformMatrix2fv
-#undef glUniformMatrix2x3fv
-#undef glUniformMatrix2x3fvNV
-#undef glUniformMatrix2x4fv
-#undef glUniformMatrix2x4fvNV
-#undef glUniformMatrix3fv
-#undef glUniformMatrix3x2fv
-#undef glUniformMatrix3x2fvNV
-#undef glUniformMatrix3x4fv
-#undef glUniformMatrix3x4fvNV
-#undef glUniformMatrix4fv
-#undef glUniformMatrix4x2fv
-#undef glUniformMatrix4x2fvNV
-#undef glUniformMatrix4x3fv
-#undef glUniformMatrix4x3fvNV
-#undef glUnmapBuffer
-#undef glUnmapBufferOES
-#undef glUseProgram
-#undef glUseProgramStages
-#undef glUseProgramStagesEXT
-#undef glValidateProgram
-#undef glValidateProgramPipeline
-#undef glValidateProgramPipelineEXT
-#undef glVertexAttrib1f
-#undef glVertexAttrib1fv
-#undef glVertexAttrib2f
-#undef glVertexAttrib2fv
-#undef glVertexAttrib3f
-#undef glVertexAttrib3fv
-#undef glVertexAttrib4f
-#undef glVertexAttrib4fv
-#undef glVertexAttribBinding
-#undef glVertexAttribDivisor
-#undef glVertexAttribDivisorANGLE
-#undef glVertexAttribDivisorEXT
-#undef glVertexAttribDivisorNV
-#undef glVertexAttribFormat
-#undef glVertexAttribI4i
-#undef glVertexAttribI4iv
-#undef glVertexAttribI4ui
-#undef glVertexAttribI4uiv
-#undef glVertexAttribIFormat
-#undef glVertexAttribIPointer
-#undef glVertexAttribPointer
-#undef glVertexBindingDivisor
-#undef glVertexPointer
-#undef glViewport
-#undef glViewportArrayvNV
-#undef glViewportIndexedfNV
-#undef glViewportIndexedfvNV
-#undef glWaitSync
-#undef glWaitSyncAPPLE
-#undef glWeightPathsNV
-#undef glWeightPointerOES
diff --git a/libs/hwui/debug/nullegl.cpp b/libs/hwui/debug/nullegl.cpp
deleted file mode 100644
index ca47f8f..0000000
--- a/libs/hwui/debug/nullegl.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.
- */
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-static EGLDisplay gDisplay = (EGLDisplay)1;
-static EGLSyncKHR gFence = (EGLSyncKHR)1;
-
-typedef struct {
-    EGLSurface surface;
-    EGLContext context;
-} ThreadState;
-
-static pthread_key_t ThreadStateKey;
-static pthread_once_t ThreadStateSetupOnce = PTHREAD_ONCE_INIT;
-
-static void destroyThreadState(void* state) {
-    free(state);
-}
-
-static void makeThreadState() {
-    pthread_key_create(&ThreadStateKey, destroyThreadState);
-}
-
-ThreadState* getThreadState() {
-    ThreadState* ptr;
-    pthread_once(&ThreadStateSetupOnce, makeThreadState);
-    if ((ptr = (ThreadState*)pthread_getspecific(ThreadStateKey)) == NULL) {
-        ptr = (ThreadState*)calloc(1, sizeof(ThreadState));
-        ptr->context = EGL_NO_CONTEXT;
-        ptr->surface = EGL_NO_SURFACE;
-        pthread_setspecific(ThreadStateKey, ptr);
-    }
-    return ptr;
-}
-
-EGLint eglGetError(void) {
-    return EGL_SUCCESS;
-}
-
-EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) {
-    return gDisplay;
-}
-
-EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) {
-    return EGL_TRUE;
-}
-
-EGLBoolean eglTerminate(EGLDisplay dpy) {
-    return EGL_TRUE;
-}
-
-const char* eglQueryString(EGLDisplay dpy, EGLint name) {
-    if (name == EGL_EXTENSIONS) {
-        return "EGL_KHR_swap_buffers_with_damage";
-    }
-    return "";
-}
-
-EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs,
-                           EGLint config_size, EGLint* num_config) {
-    memset(configs, 9, sizeof(EGLConfig) * config_size);
-    *num_config = config_size;
-    return EGL_TRUE;
-}
-
-EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win,
-                                  const EGLint* attrib_list) {
-    return (EGLSurface)malloc(sizeof(void*));
-}
-
-EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) {
-    return (EGLSurface)malloc(sizeof(void*));
-}
-
-EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) {
-    free(surface);
-    return EGL_TRUE;
-}
-
-EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value) {
-    *value = 1000;
-    return EGL_TRUE;
-}
-
-EGLBoolean eglReleaseThread(void) {
-    return EGL_TRUE;
-}
-
-EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) {
-    return EGL_TRUE;
-}
-
-EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) {
-    return EGL_TRUE;
-}
-
-EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context,
-                            const EGLint* attrib_list) {
-    return (EGLContext)malloc(sizeof(void*));
-}
-EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) {
-    free(ctx);
-    return EGL_TRUE;
-}
-
-EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) {
-    ThreadState* state = getThreadState();
-    state->surface = draw;
-    state->context = ctx;
-    return EGL_TRUE;
-}
-
-EGLContext eglGetCurrentContext(void) {
-    return getThreadState()->context;
-}
-
-EGLSurface eglGetCurrentSurface(EGLint readdraw) {
-    return getThreadState()->surface;
-}
-
-EGLDisplay eglGetCurrentDisplay(void) {
-    return gDisplay;
-}
-
-EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
-    return EGL_TRUE;
-}
-
-EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, EGLint* rects,
-                                       EGLint rectCount) {
-    return EGL_TRUE;
-}
-
-EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
-                              EGLClientBuffer buffer, const EGLint* attrib_list) {
-    return (EGLImageKHR)malloc(sizeof(EGLImageKHR));
-}
-
-EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) {
-    return gFence;
-}
-
-EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) {
-    return EGL_TRUE;
-}
-
-EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) {
-    return EGL_CONDITION_SATISFIED_KHR;
-}
-
-EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) {
-    free(image);
-    return EGL_TRUE;
-}
-
-void eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {}
diff --git a/libs/hwui/debug/wrap_gles.cpp b/libs/hwui/debug/wrap_gles.cpp
deleted file mode 100644
index 8dc946e..0000000
--- a/libs/hwui/debug/wrap_gles.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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 "GlesDriver.h"
-
-using namespace android::uirenderer::debug;
-
-#undef API_ENTRY
-#undef CALL_GL_API
-#undef CALL_GL_API_RETURN
-
-#define API_ENTRY(x) x
-#define CALL_GL_API(api, ...) GlesDriver::get()->api##_(__VA_ARGS__)
-#define CALL_GL_API_RETURN(api, ...) return GlesDriver::get()->api##_(__VA_ARGS__)
-
-#include "gles_stubs.in"
-
-#undef API_ENTRY
-#undef CALL_GL_API
-#undef CALL_GL_API_RETURN
diff --git a/libs/hwui/debug/wrap_gles.h b/libs/hwui/debug/wrap_gles.h
deleted file mode 100644
index 3da6e80..0000000
--- a/libs/hwui/debug/wrap_gles.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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'ing this file is bad, bad things should be compile errors
-#ifdef HWUI_GLES_WRAP_ENABLED
-#error wrap_gles.h should only be used as an auto-included header, don't directly #include it
-#endif
-#define HWUI_GLES_WRAP_ENABLED
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <GLES3/gl3.h>
-#include <GLES3/gl31.h>
-#include <GLES3/gl32.h>
-
-// constant used by the NULL GPU implementation as well as HWUI's unit tests
-constexpr int NULL_GPU_MAX_TEXTURE_SIZE = 2048;
-
-// Generate stubs that route all the calls to our function table
-#include "gles_redefine.h"
-
-#define GL_ENTRY(ret, api, ...) ret api(__VA_ARGS__);
-
-#include "gles_decls.in"
-#undef GL_ENTRY
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp
index 7677f9c..4544bea 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.cpp
+++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp
@@ -24,12 +24,6 @@
 
 #include <optional>
 
-#ifdef __APPLE__
-    // macOS SDK 10.10 does not support CLOCK_MONOTONIC, which is not an issue since
-    // the value of the argument is not used in the host definition of systemTime
-#define CLOCK_MONOTONIC
-#endif
-
 namespace android {
 
 AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImage, size_t bytesUsed)
@@ -70,7 +64,7 @@
 // Only called on the RenderThread while UI thread is locked.
 bool AnimatedImageDrawable::isDirty(nsecs_t* outDelay) {
     *outDelay = 0;
-    const nsecs_t currentTime = systemTime(CLOCK_MONOTONIC);
+    const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
     const nsecs_t lastWallTime = mLastWallTime;
 
     mLastWallTime = currentTime;
@@ -250,7 +244,7 @@
 
     bool update = false;
     {
-        const nsecs_t currentTime = systemTime(CLOCK_MONOTONIC);
+        const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
         std::unique_lock lock{mSwapLock};
         // mLastWallTime starts off at 0. If it is still 0, just update it to
         // the current time and avoid updating
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index e2ddb91..a48c860 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -30,11 +30,7 @@
 namespace android {
 
 Canvas* Canvas::create_recording_canvas(int width, int height, uirenderer::RenderNode* renderNode) {
-#ifdef __ANDROID__ // Layoutlib does not support recording canvas
     return new uirenderer::skiapipeline::SkiaRecordingCanvas(renderNode, width, height);
-#else
-    return NULL;
-#endif
 }
 
 static inline void drawStroke(SkScalar left, SkScalar right, SkScalar top, SkScalar thickness,
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index eed1942..96b17e1 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -33,21 +33,47 @@
     }
 }
 
-// This is a less-strict matrix.isTranslate() that will still report being translate-only
-// on imperceptibly small scaleX & scaleY values.
-static bool isBasicallyTranslate(const SkMatrix& matrix) {
-    if (!matrix.isScaleTranslate()) return false;
-    return MathUtils::isOne(matrix.getScaleX()) && MathUtils::isOne(matrix.getScaleY());
-}
-
-static bool shouldFilter(const SkMatrix& matrix) {
-    if (!matrix.isScaleTranslate()) return true;
-
-    // We only care about meaningful scale here
-    bool noScale = MathUtils::isOne(matrix.getScaleX()) && MathUtils::isOne(matrix.getScaleY());
-    bool pixelAligned =
-            SkScalarIsInt(matrix.getTranslateX()) && SkScalarIsInt(matrix.getTranslateY());
-    return !(noScale && pixelAligned);
+// Disable filtering when there is no scaling in screen coordinates and the corners have the same
+// fraction (for translate) or zero fraction (for any other rect-to-rect transform).
+static bool shouldFilterRect(const SkMatrix& matrix, const SkRect& srcRect, const SkRect& dstRect) {
+    if (!matrix.rectStaysRect()) return true;
+    SkRect dstDevRect = matrix.mapRect(dstRect);
+    float dstW, dstH;
+    bool requiresIntegerTranslate = false;
+    if (MathUtils::isZero(matrix.getScaleX()) && MathUtils::isZero(matrix.getScaleY())) {
+        // Has a 90 or 270 degree rotation, although total matrix may also have scale factors
+        // in m10 and m01. Those scalings are automatically handled by mapRect so comparing
+        // dimensions is sufficient, but swap width and height comparison.
+        dstW = dstDevRect.height();
+        dstH = dstDevRect.width();
+        requiresIntegerTranslate = true;
+    } else {
+        // Handle H/V flips or 180 rotation matrices. Axes may have been mirrored, but
+        // dimensions are still safe to compare directly.
+        dstW = dstDevRect.width();
+        dstH = dstDevRect.height();
+        requiresIntegerTranslate =
+                matrix.getScaleX() < -NON_ZERO_EPSILON || matrix.getScaleY() < -NON_ZERO_EPSILON;
+    }
+    if (!(MathUtils::areEqual(dstW, srcRect.width()) &&
+          MathUtils::areEqual(dstH, srcRect.height()))) {
+        return true;
+    }
+    if (requiresIntegerTranslate) {
+        // Device rect and source rect should be integer aligned to ensure there's no difference
+        // in how nearest-neighbor sampling is resolved.
+        return !(MathUtils::isZero(SkScalarFraction(srcRect.x())) &&
+                 MathUtils::isZero(SkScalarFraction(srcRect.y())) &&
+                 MathUtils::isZero(SkScalarFraction(dstDevRect.x())) &&
+                 MathUtils::isZero(SkScalarFraction(dstDevRect.y())));
+    } else {
+        // As long as src and device rects are translated by the same fractional amount,
+        // filtering won't be needed
+        return !(MathUtils::areEqual(SkScalarFraction(srcRect.x()),
+                                     SkScalarFraction(dstDevRect.x())) &&
+                 MathUtils::areEqual(SkScalarFraction(srcRect.y()),
+                                     SkScalarFraction(dstDevRect.y())));
+    }
 }
 
 bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer,
@@ -114,24 +140,21 @@
                 skiaDestRect = SkRect::MakeIWH(layerWidth, layerHeight);
             }
             matrixInv.mapRect(&skiaDestRect);
-            // If (matrix is identity or an integer translation) and (src/dst buffers size match),
+            // If (matrix is a rect-to-rect transform)
+            // and (src/dst buffers size match in screen coordinates)
+            // and (src/dst corners align fractionally),
             // then use nearest neighbor, otherwise use bilerp sampling.
-            // Integer translation is defined as when src rect and dst rect align fractionally.
             // Skia TextureOp has the above logic build-in, but not NonAAFillRectOp. TextureOp works
             // only for SrcOver blending and without color filter (readback uses Src blending).
-            bool isIntegerTranslate =
-                    isBasicallyTranslate(totalMatrix) &&
-                    SkScalarFraction(skiaDestRect.fLeft + totalMatrix[SkMatrix::kMTransX]) ==
-                            SkScalarFraction(skiaSrcRect.fLeft) &&
-                    SkScalarFraction(skiaDestRect.fTop + totalMatrix[SkMatrix::kMTransY]) ==
-                            SkScalarFraction(skiaSrcRect.fTop);
-            if (layer->getForceFilter() || !isIntegerTranslate) {
+            if (layer->getForceFilter() ||
+                shouldFilterRect(totalMatrix, skiaSrcRect, skiaDestRect)) {
                 paint.setFilterQuality(kLow_SkFilterQuality);
             }
             canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, &paint,
                                   SkCanvas::kFast_SrcRectConstraint);
         } else {
-            if (layer->getForceFilter() || shouldFilter(totalMatrix)) {
+            SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height());
+            if (layer->getForceFilter() || shouldFilterRect(totalMatrix, imageRect, imageRect)) {
                 paint.setFilterQuality(kLow_SkFilterQuality);
             }
             canvas->drawImage(layerImage.get(), 0, 0, &paint);
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index e65fe3a..9c84634 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -18,7 +18,6 @@
 #include <SkPaintFilterCanvas.h>
 #include "RenderNode.h"
 #include "SkiaDisplayList.h"
-#include "SkiaPipeline.h"
 #include "utils/TraceUtils.h"
 
 #include <optional>
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 0a3c8f4..3b8caeb 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -17,7 +17,7 @@
 #include "ReorderBarrierDrawables.h"
 #include "RenderNode.h"
 #include "SkiaDisplayList.h"
-#include "SkiaPipeline.h"
+#include "LightingInfo.h"
 
 #include <SkPathOps.h>
 #include <SkShadowUtils.h>
@@ -27,7 +27,7 @@
 namespace skiapipeline {
 
 StartReorderBarrierDrawable::StartReorderBarrierDrawable(SkiaDisplayList* data)
-        : mEndChildIndex(0), mBeginChildIndex(data->mChildNodes.size()), mDisplayList(data) {}
+        : mEndChildIndex(-1), mBeginChildIndex(data->mChildNodes.size()), mDisplayList(data) {}
 
 void StartReorderBarrierDrawable::onDraw(SkCanvas* canvas) {
     if (mChildren.empty()) {
@@ -139,8 +139,8 @@
         return;
     }
 
-    float ambientAlpha = (SkiaPipeline::getAmbientShadowAlpha() / 255.f) * casterAlpha;
-    float spotAlpha = (SkiaPipeline::getSpotShadowAlpha() / 255.f) * casterAlpha;
+    float ambientAlpha = (LightingInfo::getAmbientShadowAlpha() / 255.f) * casterAlpha;
+    float spotAlpha = (LightingInfo::getSpotShadowAlpha() / 255.f) * casterAlpha;
 
     const RevealClip& revealClip = casterProperties.getRevealClip();
     const SkPath* revealClipPath = revealClip.getPath();
@@ -192,7 +192,7 @@
         casterPath = &tmpPath;
     }
 
-    const Vector3 lightPos = SkiaPipeline::getLightCenter();
+    const Vector3 lightPos = LightingInfo::getLightCenter();
     SkPoint3 skiaLightPos = SkPoint3::Make(lightPos.x, lightPos.y, lightPos.z);
     SkPoint3 zParams;
     if (shadowMatrix.hasPerspective()) {
@@ -206,7 +206,7 @@
     SkColor ambientColor = multiplyAlpha(casterProperties.getAmbientShadowColor(), ambientAlpha);
     SkColor spotColor = multiplyAlpha(casterProperties.getSpotShadowColor(), spotAlpha);
     SkShadowUtils::DrawShadow(
-            canvas, *casterPath, zParams, skiaLightPos, SkiaPipeline::getLightRadius(),
+            canvas, *casterPath, zParams, skiaLightPos, LightingInfo::getLightRadius(),
             ambientColor, spotColor,
             casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
 }
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 780ac20..c7d5f31 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -17,9 +17,15 @@
 #include "SkiaDisplayList.h"
 
 #include "DumpOpsCanvas.h"
+#ifdef __ANDROID__ // Layoutlib does not support SkiaPipeline
 #include "SkiaPipeline.h"
+#else
+#include "DamageAccumulator.h"
+#endif
 #include "VectorDrawable.h"
+#ifdef __ANDROID__
 #include "renderthread/CanvasContext.h"
+#endif
 
 #include <SkImagePriv.h>
 #include <SkPathOps.h>
@@ -81,6 +87,7 @@
     // If the prepare tree is triggered by the UI thread and no previous call to
     // pinImages has failed then we must pin all mutable images in the GPU cache
     // until the next UI thread draw.
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
     if (info.prepareTextures && !info.canvasContext.pinImages(mMutableImages)) {
         // In the event that pinning failed we prevent future pinImage calls for the
         // remainder of this tree traversal and also unpin any currently pinned images
@@ -88,6 +95,7 @@
         info.prepareTextures = false;
         info.canvasContext.unpinImages();
     }
+#endif
 
     bool hasBackwardProjectedNodesHere = false;
     bool hasBackwardProjectedNodesSubtree = false;
@@ -141,10 +149,12 @@
             const SkRect& bounds = vectorDrawable->properties().getBounds();
             if (intersects(info.screenSize, totalMatrix, bounds)) {
                 isDirty = true;
+#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
                 static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline())
                         ->getVectorDrawables()
                         ->push_back(vectorDrawable);
                 vectorDrawable->setPropertyChangeWillBeConsumed(true);
+#endif
             }
         }
     }
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 8092b1d..e7efe2f 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -18,6 +18,7 @@
 
 #include "DeferredLayerUpdater.h"
 #include "LayerDrawable.h"
+#include "LightingInfo.h"
 #include "SkiaPipeline.h"
 #include "SkiaProfileRenderer.h"
 #include "hwui/Bitmap.h"
@@ -99,7 +100,7 @@
             mRenderThread.getGrContext(), backendRT, this->getSurfaceOrigin(), colorType,
             mSurfaceColorSpace, &props));
 
-    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
+    LightingInfo::updateLighting(lightGeometry, lightInfo);
     renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface,
                 SkMatrix::I());
     layerUpdateQueue->clear();
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 0668281..530926b 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -19,13 +19,17 @@
 #include <SkImageEncoder.h>
 #include <SkImageInfo.h>
 #include <SkImagePriv.h>
+#include <SkMultiPictureDocument.h>
 #include <SkOverdrawCanvas.h>
 #include <SkOverdrawColorFilter.h>
 #include <SkPicture.h>
 #include <SkPictureRecorder.h>
+#include <SkSerialProcs.h>
+#include "LightingInfo.h"
 #include "TreeInfo.h"
 #include "VectorDrawable.h"
 #include "thread/CommonPool.h"
+#include "tools/SkSharingProc.h"
 #include "utils/TraceUtils.h"
 
 #include <unistd.h>
@@ -38,12 +42,6 @@
 namespace uirenderer {
 namespace skiapipeline {
 
-float SkiaPipeline::mLightRadius = 0;
-uint8_t SkiaPipeline::mAmbientShadowAlpha = 0;
-uint8_t SkiaPipeline::mSpotShadowAlpha = 0;
-
-Vector3 SkiaPipeline::mLightCenter = {FLT_MIN, FLT_MIN, FLT_MIN};
-
 SkiaPipeline::SkiaPipeline(RenderThread& thread) : mRenderThread(thread) {
     mVectorDrawables.reserve(30);
 }
@@ -84,7 +82,7 @@
 void SkiaPipeline::renderLayers(const LightGeometry& lightGeometry,
                                 LayerUpdateQueue* layerUpdateQueue, bool opaque,
                                 const LightInfo& lightInfo) {
-    updateLighting(lightGeometry, lightInfo);
+    LightingInfo::updateLighting(lightGeometry, lightInfo);
     ATRACE_NAME("draw layers");
     renderVectorDrawableCache();
     renderLayersImpl(*layerUpdateQueue, opaque);
@@ -104,7 +102,7 @@
             SkASSERT(layerNode->getLayerSurface());
             SkiaDisplayList* displayList = (SkiaDisplayList*)layerNode->getDisplayList();
             if (!displayList || displayList->isEmpty()) {
-                SkDEBUGF(("%p drawLayers(%s) : missing drawable", layerNode, layerNode->getName()));
+                ALOGE("%p drawLayers(%s) : missing drawable", layerNode, layerNode->getName());
                 return;
             }
 
@@ -117,9 +115,13 @@
 
             layerCanvas->androidFramework_setDeviceClipRestriction(layerDamage.toSkIRect());
 
-            auto savedLightCenter = mLightCenter;
+            // TODO: put localized light center calculation and storage to a drawable related code.
+            // It does not seem right to store something localized in a global state
+            const Vector3 savedLightCenter(LightingInfo::getLightCenterRaw());
+            Vector3 transformedLightCenter(savedLightCenter);
             // map current light center into RenderNode's coordinate space
-            layerNode->getSkiaLayer()->inverseTransformInWindow.mapPoint3d(mLightCenter);
+            layerNode->getSkiaLayer()->inverseTransformInWindow.mapPoint3d(transformedLightCenter);
+            LightingInfo::setLightCenterRaw(transformedLightCenter);
 
             const RenderProperties& properties = layerNode->properties();
             const SkRect bounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight());
@@ -136,7 +138,7 @@
             RenderNodeDrawable root(layerNode, layerCanvas, false);
             root.forceDraw(layerCanvas);
             layerCanvas->restoreToCount(saveCount);
-            mLightCenter = savedLightCenter;
+            LightingInfo::setLightCenterRaw(savedLightCenter);
 
             // cache the current context so that we can defer flushing it until
             // either all the layers have been rendered or the context changes
@@ -234,58 +236,137 @@
         if (stream.isValid()) {
             stream.write(data->data(), data->size());
             stream.flush();
-            SkDebugf("SKP Captured Drawing Output (%d bytes) for frame. %s", stream.bytesWritten(),
+            ALOGD("SKP Captured Drawing Output (%zu bytes) for frame. %s", stream.bytesWritten(),
                      filename.c_str());
         }
     });
 }
 
-SkCanvas* SkiaPipeline::tryCapture(SkSurface* surface) {
-    if (CC_UNLIKELY(Properties::skpCaptureEnabled)) {
+// Note multiple SkiaPipeline instances may be loaded if more than one app is visible.
+// Each instance may observe the filename changing and try to record to a file of the same name.
+// Only the first one will succeed. There is no scope available here where we could coordinate
+// to cause this function to return true for only one of the instances.
+bool SkiaPipeline::shouldStartNewFileCapture() {
+    // Don't start a new file based capture if one is currently ongoing.
+    if (mCaptureMode != CaptureMode::None) { return false; }
+
+    // A new capture is started when the filename property changes.
+    // Read the filename property.
+    std::string prop = base::GetProperty(PROPERTY_CAPTURE_SKP_FILENAME, "0");
+    // if the filename property changed to a valid value
+    if (prop[0] != '0' && mCapturedFile != prop) {
+        // remember this new filename
+        mCapturedFile = prop;
+        // and get a property indicating how many frames to capture.
+        mCaptureSequence = base::GetIntProperty(PROPERTY_CAPTURE_SKP_FRAMES, 1);
         if (mCaptureSequence <= 0) {
-            std::string prop = base::GetProperty(PROPERTY_CAPTURE_SKP_FILENAME, "0");
-            if (prop[0] != '0' && mCapturedFile != prop) {
-                mCapturedFile = prop;
-                mCaptureSequence = base::GetIntProperty(PROPERTY_CAPTURE_SKP_FRAMES, 1);
-            }
+            return false;
+        } else if (mCaptureSequence == 1) {
+            mCaptureMode = CaptureMode::SingleFrameSKP;
+        } else {
+            mCaptureMode = CaptureMode::MultiFrameSKP;
         }
-        if (mCaptureSequence > 0 || mPictureCapturedCallback) {
-            mRecorder.reset(new SkPictureRecorder());
-            SkCanvas* pictureCanvas =
-                    mRecorder->beginRecording(surface->width(), surface->height(), nullptr,
-                                              SkPictureRecorder::kPlaybackDrawPicture_RecordFlag);
-            mNwayCanvas = std::make_unique<SkNWayCanvas>(surface->width(), surface->height());
-            mNwayCanvas->addCanvas(surface->getCanvas());
-            mNwayCanvas->addCanvas(pictureCanvas);
-            return mNwayCanvas.get();
+        return true;
+    }
+    return false;
+}
+
+// performs the first-frame work of a multi frame SKP capture. Returns true if successful.
+bool SkiaPipeline::setupMultiFrameCapture() {
+    ALOGD("Set up multi-frame capture, frames = %d", mCaptureSequence);
+    // We own this stream and need to hold it until close() finishes.
+    auto stream = std::make_unique<SkFILEWStream>(mCapturedFile.c_str());
+    if (stream->isValid()) {
+        mOpenMultiPicStream = std::move(stream);
+        mSerialContext.reset(new SkSharingSerialContext());
+        SkSerialProcs procs;
+        procs.fImageProc = SkSharingSerialContext::serializeImage;
+        procs.fImageCtx = mSerialContext.get();
+        // SkDocuments don't take owership of the streams they write.
+        // we need to keep it until after mMultiPic.close()
+        // procs is passed as a pointer, but just as a method of having an optional default.
+        // procs doesn't need to outlive this Make call.
+        mMultiPic = SkMakeMultiPictureDocument(mOpenMultiPicStream.get(), &procs);
+        return true;
+    } else {
+        ALOGE("Could not open \"%s\" for writing.", mCapturedFile.c_str());
+        mCaptureSequence = 0;
+        mCaptureMode = CaptureMode::None;
+        return false;
+    }
+}
+
+SkCanvas* SkiaPipeline::tryCapture(SkSurface* surface) {
+    if (CC_LIKELY(!Properties::skpCaptureEnabled)) {
+        return surface->getCanvas(); // Bail out early when capture is not turned on.
+    }
+    // Note that shouldStartNewFileCapture tells us if this is the *first* frame of a capture.
+    if (shouldStartNewFileCapture() && mCaptureMode == CaptureMode::MultiFrameSKP) {
+        if (!setupMultiFrameCapture()) {
+            return surface->getCanvas();
         }
     }
-    return surface->getCanvas();
+
+    // Create a canvas pointer, fill it depending on what kind of capture is requested (if any)
+    SkCanvas* pictureCanvas = nullptr;
+    switch (mCaptureMode) {
+        case CaptureMode::CallbackAPI:
+        case CaptureMode::SingleFrameSKP:
+            mRecorder.reset(new SkPictureRecorder());
+            pictureCanvas = mRecorder->beginRecording(surface->width(), surface->height());
+            break;
+        case CaptureMode::MultiFrameSKP:
+            // If a multi frame recording is active, initialize recording for a single frame of a
+            // multi frame file.
+            pictureCanvas = mMultiPic->beginPage(surface->width(), surface->height());
+            break;
+        case CaptureMode::None:
+            // Returning here in the non-capture case means we can count on pictureCanvas being
+            // non-null below.
+            return surface->getCanvas();
+    }
+
+    // Setting up an nway canvas is common to any kind of capture.
+    mNwayCanvas = std::make_unique<SkNWayCanvas>(surface->width(), surface->height());
+    mNwayCanvas->addCanvas(surface->getCanvas());
+    mNwayCanvas->addCanvas(pictureCanvas);
+    return mNwayCanvas.get();
 }
 
 void SkiaPipeline::endCapture(SkSurface* surface) {
+    if (CC_LIKELY(mCaptureMode == CaptureMode::None)) { return; }
     mNwayCanvas.reset();
-    if (CC_UNLIKELY(mRecorder.get())) {
-        ATRACE_CALL();
+    ATRACE_CALL();
+    if (mCaptureSequence > 0 && mCaptureMode == CaptureMode::MultiFrameSKP) {
+        mMultiPic->endPage();
+        mCaptureSequence--;
+        if (mCaptureSequence == 0) {
+            mCaptureMode = CaptureMode::None;
+            // Pass mMultiPic and mOpenMultiPicStream to a background thread, which will handle
+            // the heavyweight serialization work and destroy them. mOpenMultiPicStream is released
+            // to a bare pointer because keeping it in a smart pointer makes the lambda
+            // non-copyable. The lambda is only called once, so this is safe.
+            SkFILEWStream* stream = mOpenMultiPicStream.release();
+            CommonPool::post([doc = std::move(mMultiPic), stream]{
+                ALOGD("Finalizing multi frame SKP");
+                doc->close();
+                delete stream;
+                ALOGD("Multi frame SKP complete.");
+            });
+        }
+    } else {
         sk_sp<SkPicture> picture = mRecorder->finishRecordingAsPicture();
         if (picture->approximateOpCount() > 0) {
-            if (mCaptureSequence > 0) {
-                ATRACE_BEGIN("picture->serialize");
-                auto data = picture->serialize();
-                ATRACE_END();
-
-                // offload saving to file in a different thread
-                if (1 == mCaptureSequence) {
-                    savePictureAsync(data, mCapturedFile);
-                } else {
-                    savePictureAsync(data, mCapturedFile + "_" + std::to_string(mCaptureSequence));
-                }
-                mCaptureSequence--;
-            }
             if (mPictureCapturedCallback) {
                 std::invoke(mPictureCapturedCallback, std::move(picture));
+            } else {
+                // single frame skp to file
+                auto data = picture->serialize();
+                savePictureAsync(data, mCapturedFile);
+                mCaptureSequence = 0;
             }
         }
+        mCaptureMode = CaptureMode::None;
         mRecorder.reset();
     }
 }
@@ -306,7 +387,6 @@
 
     // initialize the canvas for the current frame, that might be a recording canvas if SKP
     // capture is enabled.
-    std::unique_ptr<SkPictureRecorder> recorder;
     SkCanvas* canvas = tryCapture(surface.get());
 
     renderFrameImpl(layers, clip, nodes, opaque, contentDrawBounds, canvas, preTransform);
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 41d8646..37b559f 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -17,12 +17,15 @@
 #pragma once
 
 #include <SkSurface.h>
+#include <SkDocument.h>
+#include <SkMultiPictureDocument.h>
 #include "Lighting.h"
 #include "hwui/AnimatedImageDrawable.h"
 #include "renderthread/CanvasContext.h"
 #include "renderthread/IRenderPipeline.h"
 
 class SkPictureRecorder;
+struct SkSharingSerialContext;
 
 namespace android {
 namespace uirenderer {
@@ -60,52 +63,12 @@
 
     void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque);
 
-    static float getLightRadius() {
-        if (CC_UNLIKELY(Properties::overrideLightRadius > 0)) {
-            return Properties::overrideLightRadius;
-        }
-        return mLightRadius;
-    }
-
-    static uint8_t getAmbientShadowAlpha() {
-        if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
-            return Properties::overrideAmbientShadowStrength;
-        }
-        return mAmbientShadowAlpha;
-    }
-
-    static uint8_t getSpotShadowAlpha() {
-        if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
-            return Properties::overrideSpotShadowStrength;
-        }
-        return mSpotShadowAlpha;
-    }
-
-    static Vector3 getLightCenter() {
-        if (CC_UNLIKELY(Properties::overrideLightPosY > 0 || Properties::overrideLightPosZ > 0)) {
-            Vector3 adjustedLightCenter = mLightCenter;
-            if (CC_UNLIKELY(Properties::overrideLightPosY > 0)) {
-                // negated since this shifts up
-                adjustedLightCenter.y = -Properties::overrideLightPosY;
-            }
-            if (CC_UNLIKELY(Properties::overrideLightPosZ > 0)) {
-                adjustedLightCenter.z = Properties::overrideLightPosZ;
-            }
-            return adjustedLightCenter;
-        }
-        return mLightCenter;
-    }
-
-    static void updateLighting(const LightGeometry& lightGeometry, const LightInfo& lightInfo) {
-        mLightRadius = lightGeometry.radius;
-        mAmbientShadowAlpha = lightInfo.ambientShadowAlpha;
-        mSpotShadowAlpha = lightInfo.spotShadowAlpha;
-        mLightCenter = lightGeometry.center;
-    }
-
+    // Sets the recording callback to the provided function and the recording mode
+    // to CallbackAPI
     void setPictureCapturedCallback(
             const std::function<void(sk_sp<SkPicture>&&)>& callback) override {
         mPictureCapturedCallback = callback;
+        mCaptureMode = callback ? CaptureMode::CallbackAPI : CaptureMode::None;
     }
 
 protected:
@@ -135,8 +98,18 @@
      */
     void renderVectorDrawableCache();
 
+    // Called every frame. Normally returns early with screen canvas.
+    // But when capture is enabled, returns an nwaycanvas where commands are also recorded.
     SkCanvas* tryCapture(SkSurface* surface);
+    // Called at the end of every frame, closes the recording if necessary.
     void endCapture(SkSurface* surface);
+    // Determine if a new file-based capture should be started.
+    // If so, sets mCapturedFile and mCaptureSequence and returns true.
+    // Should be called every frame when capture is enabled.
+    // sets mCaptureMode.
+    bool shouldStartNewFileCapture();
+    // Set up a multi frame capture.
+    bool setupMultiFrameCapture();
 
     std::vector<sk_sp<SkImage>> mPinnedImages;
 
@@ -146,28 +119,47 @@
     std::vector<VectorDrawableRoot*> mVectorDrawables;
 
     // Block of properties used only for debugging to record a SkPicture and save it in a file.
+    // There are three possible ways of recording drawing commands.
+    enum class CaptureMode {
+        // return to this mode when capture stops.
+        None,
+        // A mode where every frame is recorded into an SkPicture and sent to a provided callback,
+        // until that callback is cleared
+        CallbackAPI,
+        // A mode where a finite number of frames are recorded to a file with
+        // SkMultiPictureDocument
+        MultiFrameSKP,
+        // A mode which records a single frame to a normal SKP file.
+        SingleFrameSKP,
+    };
+  CaptureMode mCaptureMode = CaptureMode::None;
+
     /**
-     * mCapturedFile is used to enforce we don't capture more than once for a given name (cause
-     * permissions don't allow to reset a property from render thread).
+     * mCapturedFile - the filename to write a recorded SKP to in either MultiFrameSKP or
+     * SingleFrameSKP mode.
      */
     std::string mCapturedFile;
     /**
-     *  mCaptureSequence counts how many frames are left to take in the sequence.
+     * mCaptureSequence counts down how many frames are left to take in the sequence. Applicable
+     * only to MultiFrameSKP or SingleFrameSKP mode.
      */
     int mCaptureSequence = 0;
 
+    // Multi frame serialization stream and writer used when serializing more than one frame.
+    std::unique_ptr<SkFILEWStream> mOpenMultiPicStream;
+    sk_sp<SkDocument> mMultiPic;
+    std::unique_ptr<SkSharingSerialContext> mSerialContext;
+
     /**
-     *  mRecorder holds the current picture recorder. We could store it on the stack to support
-     *  parallel tryCapture calls (not really needed).
+     * mRecorder holds the current picture recorder when serializing in either SingleFrameSKP or
+     * CallbackAPI modes.
      */
     std::unique_ptr<SkPictureRecorder> mRecorder;
     std::unique_ptr<SkNWayCanvas> mNwayCanvas;
-    std::function<void(sk_sp<SkPicture>&&)> mPictureCapturedCallback;
 
-    static float mLightRadius;
-    static uint8_t mAmbientShadowAlpha;
-    static uint8_t mSpotShadowAlpha;
-    static Vector3 mLightCenter;
+    // Set by setPictureCapturedCallback and when set, CallbackAPI mode recording is ongoing.
+    // Not used in other recording modes.
+    std::function<void(sk_sp<SkPicture>&&)> mPictureCapturedCallback;
 };
 
 } /* namespace skiapipeline */
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 16c8b89..38ef131 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -18,14 +18,18 @@
 
 #include <SkImagePriv.h>
 #include "CanvasTransform.h"
+#ifdef __ANDROID__ // Layoutlib does not support Layers
 #include "Layer.h"
 #include "LayerDrawable.h"
+#endif
 #include "NinePatchUtils.h"
 #include "RenderNode.h"
 #include "pipeline/skia/AnimatedDrawables.h"
+#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
 #include "pipeline/skia/GLFunctorDrawable.h"
 #include "pipeline/skia/VkFunctorDrawable.h"
 #include "pipeline/skia/VkInteropFunctorDrawable.h"
+#endif
 
 namespace android {
 namespace uirenderer {
@@ -102,13 +106,16 @@
 }
 
 void SkiaRecordingCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) {
+#ifdef __ANDROID__ // Layoutlib does not support Layers
     if (layerUpdater != nullptr) {
         // Create a ref-counted drawable, which is kept alive by sk_sp in SkLiteDL.
         sk_sp<SkDrawable> drawable(new LayerDrawable(layerUpdater));
         drawDrawable(drawable.get());
     }
+#endif
 }
 
+
 void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
     // Record the child node. Drawable dtor will be invoked when mChildNodes deque is cleared.
     mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas(), true, mCurrentBarrier);
@@ -125,8 +132,10 @@
     }
 }
 
+
 void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
                                              uirenderer::GlFunctorLifecycleListener* listener) {
+#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
     FunctorDrawable* functorDrawable;
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
         functorDrawable = mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(
@@ -137,9 +146,11 @@
     }
     mDisplayList->mChildFunctors.push_back(functorDrawable);
     drawDrawable(functorDrawable);
+#endif
 }
 
 void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
+#ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc.
     FunctorDrawable* functorDrawable;
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
         functorDrawable = mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
@@ -148,6 +159,7 @@
     }
     mDisplayList->mChildFunctors.push_back(functorDrawable);
     drawDrawable(functorDrawable);
+#endif
 }
 
 void SkiaRecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index e8cb219..ad7c706 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -19,6 +19,7 @@
 #include "DeferredLayerUpdater.h"
 #include "Readback.h"
 #include "ShaderCache.h"
+#include "LightingInfo.h"
 #include "SkiaPipeline.h"
 #include "SkiaProfileRenderer.h"
 #include "VkInteropFunctorDrawable.h"
@@ -69,7 +70,7 @@
     if (backBuffer.get() == nullptr) {
         return false;
     }
-    SkiaPipeline::updateLighting(lightGeometry, lightInfo);
+    LightingInfo::updateLighting(lightGeometry, lightInfo);
     renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer,
                 mVkSurface->getCurrentPreTransform());
     ShaderCache::get().onVkFrameFlushed(mRenderThread.getGrContext());
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f326ce8..550c27d 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -19,7 +19,6 @@
 
 #include "../Properties.h"
 #include "AnimationContext.h"
-#include "EglManager.h"
 #include "Frame.h"
 #include "LayerUpdateQueue.h"
 #include "Properties.h"
@@ -33,8 +32,6 @@
 #include "utils/TimeUtils.h"
 #include "utils/TraceUtils.h"
 
-#include <cutils/properties.h>
-#include <private/hwui/DrawGlInfo.h>
 #include <strings.h>
 
 #include <fcntl.h>
@@ -463,7 +460,7 @@
         }
         SwapHistory& swap = mSwapHistory.next();
         swap.damage = windowDirty;
-        swap.swapCompletedTime = systemTime(CLOCK_MONOTONIC);
+        swap.swapCompletedTime = systemTime(SYSTEM_TIME_MONOTONIC);
         swap.vsyncTime = mRenderThread.timeLord().latestVsync();
         if (mNativeSurface.get()) {
             int durationUs;
@@ -549,7 +546,7 @@
     UiFrameInfoBuilder(frameInfo).addFlag(FrameInfoFlags::RTAnimation).setVsync(vsync, vsync);
 
     TreeInfo info(TreeInfo::MODE_RT_ONLY, *this);
-    prepareTree(info, frameInfo, systemTime(CLOCK_MONOTONIC), node);
+    prepareTree(info, frameInfo, systemTime(SYSTEM_TIME_MONOTONIC), node);
     if (info.out.canDrawThisFrame) {
         draw();
     } else {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 982c087..0910828 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -29,7 +29,6 @@
 #include "renderthread/RenderTask.h"
 #include "renderthread/RenderThread.h"
 
-#include <EGL/egl.h>
 #include <SkBitmap.h>
 #include <SkRect.h>
 #include <SkSize.h>
@@ -55,7 +54,6 @@
 
 namespace renderthread {
 
-class EglManager;
 class Frame;
 
 // This per-renderer class manages the bridge between the global EGL context
@@ -216,8 +214,9 @@
 
     SkRect computeDirtyRect(const Frame& frame, SkRect* dirty);
 
-    EGLint mLastFrameWidth = 0;
-    EGLint mLastFrameHeight = 0;
+    // The same type as Frame.mWidth and Frame.mHeight
+    int32_t mLastFrameWidth = 0;
+    int32_t mLastFrameHeight = 0;
 
     RenderThread& mRenderThread;
     sp<ReliableSurface> mNativeSurface;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 91dc3bc..1e59338 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -69,7 +69,7 @@
     LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
 
     mSyncResult = SyncResult::OK;
-    mSyncQueued = systemTime(CLOCK_MONOTONIC);
+    mSyncQueued = systemTime(SYSTEM_TIME_MONOTONIC);
     postAndWait();
 
     return mSyncResult;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 1a1b9da..40fbdff 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -16,25 +16,22 @@
 
 #include "RenderProxy.h"
 
+#include <gui/Surface.h>
+
 #include "DeferredLayerUpdater.h"
 #include "DisplayList.h"
 #include "Properties.h"
 #include "Readback.h"
 #include "Rect.h"
 #include "WebViewFunctorManager.h"
-#include "pipeline/skia/SkiaOpenGLPipeline.h"
 #include "pipeline/skia/VectorDrawableAtlas.h"
-#include "renderstate/RenderState.h"
 #include "renderthread/CanvasContext.h"
-#include "renderthread/EglManager.h"
 #include "renderthread/RenderTask.h"
 #include "renderthread/RenderThread.h"
 #include "utils/Macros.h"
 #include "utils/TimeUtils.h"
 #include "utils/TraceUtils.h"
 
-#include <ui/GraphicBuffer.h>
-
 namespace android {
 namespace uirenderer {
 namespace renderthread {
@@ -339,7 +336,7 @@
     };
     nsecs_t lastVsync = renderThread->timeLord().latestVsync();
     nsecs_t estimatedNextVsync = lastVsync + renderThread->timeLord().frameIntervalNanos();
-    nsecs_t timeToNextVsync = estimatedNextVsync - systemTime(CLOCK_MONOTONIC);
+    nsecs_t timeToNextVsync = estimatedNextVsync - systemTime(SYSTEM_TIME_MONOTONIC);
     // We expect the UI thread to take 4ms and for RT to be active from VSYNC+4ms to
     // VSYNC+12ms or so, so aim for the gap during which RT is expected to
     // be idle
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index a0f08cb..c3eb6ed 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -19,7 +19,6 @@
 
 #include <SkBitmap.h>
 #include <cutils/compiler.h>
-#include <gui/Surface.h>
 #include <utils/Functor.h>
 
 #include "../FrameMetricsObserver.h"
@@ -30,6 +29,7 @@
 
 namespace android {
 class GraphicBuffer;
+class Surface;
 
 namespace uirenderer {
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 41cb8fd..ee1a7ce 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -31,10 +31,6 @@
 #include "utils/TimeUtils.h"
 #include "utils/TraceUtils.h"
 
-#ifdef HWUI_GLES_WRAP_ENABLED
-#include "debug/GlesDriver.h"
-#endif
-
 #include <GrContextOptions.h>
 #include <gl/GrGLInterface.h>
 
@@ -107,7 +103,7 @@
                                            [this]() { mRenderThread->drainDisplayEventQueue(); });
     }
 
-    virtual nsecs_t latestVsyncEvent() override { return systemTime(CLOCK_MONOTONIC); }
+    virtual nsecs_t latestVsyncEvent() override { return systemTime(SYSTEM_TIME_MONOTONIC); }
 
 private:
     RenderThread* mRenderThread;
@@ -156,7 +152,9 @@
     LOG_ALWAYS_FATAL_IF(mVsyncSource, "Initializing a second DisplayEventReceiver?");
 
     if (!Properties::isolatedProcess) {
-        auto receiver = std::make_unique<DisplayEventReceiver>();
+        auto receiver = std::make_unique<DisplayEventReceiver>(
+            ISurfaceComposer::eVsyncSourceApp,
+            ISurfaceComposer::eConfigChangedDispatch);
         status_t status = receiver->initCheck();
         LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
                             "Initialization of DisplayEventReceiver "
@@ -197,12 +195,7 @@
     }
     mEglManager->initialize();
 
-#ifdef HWUI_GLES_WRAP_ENABLED
-    debug::GlesDriver* driver = debug::GlesDriver::get();
-    sk_sp<const GrGLInterface> glInterface(driver->getSkiaInterface());
-#else
     sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
-#endif
     LOG_ALWAYS_FATAL_IF(!glInterface.get());
 
     GrContextOptions options;
diff --git a/libs/hwui/renderthread/TimeLord.cpp b/libs/hwui/renderthread/TimeLord.cpp
index b82c5d1..784068f 100644
--- a/libs/hwui/renderthread/TimeLord.cpp
+++ b/libs/hwui/renderthread/TimeLord.cpp
@@ -31,7 +31,7 @@
 
 nsecs_t TimeLord::computeFrameTimeNanos() {
     // Logic copied from Choreographer.java
-    nsecs_t now = systemTime(CLOCK_MONOTONIC);
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
     nsecs_t jitterNanos = now - mFrameTimeNanos;
     if (jitterNanos >= mFrameIntervalNanos) {
         nsecs_t lastFrameOffset = jitterNanos % mFrameIntervalNanos;
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 46c3f2f..280f7d3 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -145,12 +145,6 @@
     GET_INST_PROC(GetPhysicalDeviceImageFormatProperties2);
     GET_INST_PROC(CreateDevice);
     GET_INST_PROC(EnumerateDeviceExtensionProperties);
-    GET_INST_PROC(CreateAndroidSurfaceKHR);
-    GET_INST_PROC(DestroySurfaceKHR);
-    GET_INST_PROC(GetPhysicalDeviceSurfaceSupportKHR);
-    GET_INST_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
-    GET_INST_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
-    GET_INST_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
 
     uint32_t gpuCount;
     LOG_ALWAYS_FATAL_IF(mEnumeratePhysicalDevices(mInstance, &gpuCount, nullptr));
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index dd3c6d0..ec217c0 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -107,14 +107,6 @@
         FNPTR_TYPE fPtr;
     };
 
-    // WSI interface functions
-    VkPtr<PFN_vkCreateAndroidSurfaceKHR> mCreateAndroidSurfaceKHR;
-    VkPtr<PFN_vkDestroySurfaceKHR> mDestroySurfaceKHR;
-    VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> mGetPhysicalDeviceSurfaceSupportKHR;
-    VkPtr<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR> mGetPhysicalDeviceSurfaceCapabilitiesKHR;
-    VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> mGetPhysicalDeviceSurfaceFormatsKHR;
-    VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> mGetPhysicalDeviceSurfacePresentModesKHR;
-
     // Instance Functions
     VkPtr<PFN_vkEnumerateInstanceVersion> mEnumerateInstanceVersion;
     VkPtr<PFN_vkEnumerateInstanceExtensionProperties> mEnumerateInstanceExtensionProperties;
diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp
index b2cc23e..bbffb35 100644
--- a/libs/hwui/renderthread/VulkanSurface.cpp
+++ b/libs/hwui/renderthread/VulkanSurface.cpp
@@ -27,15 +27,6 @@
 namespace uirenderer {
 namespace renderthread {
 
-static bool IsTransformSupported(int transform) {
-    // For now, only support pure rotations, not flip or flip-and-rotate, until we have
-    // more time to test them and build sample code. As far as I know we never actually
-    // use anything besides pure rotations anyway.
-    return transform == 0 || transform == NATIVE_WINDOW_TRANSFORM_ROT_90 ||
-           transform == NATIVE_WINDOW_TRANSFORM_ROT_180 ||
-           transform == NATIVE_WINDOW_TRANSFORM_ROT_270;
-}
-
 static int InvertTransform(int transform) {
     switch (transform) {
         case NATIVE_WINDOW_TRANSFORM_ROT_90:
@@ -49,21 +40,6 @@
     }
 }
 
-static int ConvertVkTransformToNative(VkSurfaceTransformFlagsKHR transform) {
-    switch (transform) {
-        case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
-            return NATIVE_WINDOW_TRANSFORM_ROT_270;
-        case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
-            return NATIVE_WINDOW_TRANSFORM_ROT_180;
-        case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
-            return NATIVE_WINDOW_TRANSFORM_ROT_90;
-        case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
-        case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
-        default:
-            return 0;
-    }
-}
-
 static SkMatrix GetPreTransformMatrix(SkISize windowSize, int transform) {
     const int width = windowSize.width();
     const int height = windowSize.height();
@@ -83,180 +59,157 @@
     return SkMatrix::I();
 }
 
-void VulkanSurface::ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
-                                                  const SkISize& maxSize) {
-    SkISize& windowSize = windowInfo->size;
-
-    // clamp width & height to handle currentExtent of -1 and  protect us from broken hints
-    if (windowSize.width() < minSize.width() || windowSize.width() > maxSize.width() ||
-        windowSize.height() < minSize.height() || windowSize.height() > maxSize.height()) {
-        int width = std::min(maxSize.width(), std::max(minSize.width(), windowSize.width()));
-        int height = std::min(maxSize.height(), std::max(minSize.height(), windowSize.height()));
-        ALOGE("Invalid Window Dimensions [%d, %d]; clamping to [%d, %d]", windowSize.width(),
-              windowSize.height(), width, height);
-        windowSize.set(width, height);
-    }
-
-    windowInfo->actualSize = windowSize;
-    if (windowInfo->transform & HAL_TRANSFORM_ROT_90) {
-        windowInfo->actualSize.set(windowSize.height(), windowSize.width());
-    }
-
-    windowInfo->preTransform = GetPreTransformMatrix(windowInfo->size, windowInfo->transform);
-}
-
-static bool ResetNativeWindow(ANativeWindow* window) {
-    // -- Reset the native window --
-    // The native window might have been used previously, and had its properties
-    // changed from defaults. That will affect the answer we get for queries
-    // like MIN_UNDEQUEUED_BUFFERS. Reset to a known/default state before we
-    // attempt such queries.
+static bool ConnectAndSetWindowDefaults(ANativeWindow* window) {
+    ATRACE_CALL();
 
     int err = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
     if (err != 0) {
-        ALOGW("native_window_api_connect failed: %s (%d)", strerror(-err), err);
+        ALOGE("native_window_api_connect failed: %s (%d)", strerror(-err), err);
         return false;
     }
 
     // this will match what we do on GL so pick that here.
     err = window->setSwapInterval(window, 1);
     if (err != 0) {
-        ALOGW("native_window->setSwapInterval(1) failed: %s (%d)", strerror(-err), err);
+        ALOGE("native_window->setSwapInterval(1) failed: %s (%d)", strerror(-err), err);
         return false;
     }
 
     err = native_window_set_shared_buffer_mode(window, false);
     if (err != 0) {
-        ALOGW("native_window_set_shared_buffer_mode(false) failed: %s (%d)", strerror(-err), err);
+        ALOGE("native_window_set_shared_buffer_mode(false) failed: %s (%d)", strerror(-err), err);
         return false;
     }
 
     err = native_window_set_auto_refresh(window, false);
     if (err != 0) {
-        ALOGW("native_window_set_auto_refresh(false) failed: %s (%d)", strerror(-err), err);
+        ALOGE("native_window_set_auto_refresh(false) failed: %s (%d)", strerror(-err), err);
+        return false;
+    }
+
+    err = native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_FREEZE);
+    if (err != 0) {
+        ALOGE("native_window_set_scaling_mode(NATIVE_WINDOW_SCALING_MODE_FREEZE) failed: %s (%d)",
+              strerror(-err), err);
+        return false;
+    }
+
+    // Let consumer drive the size of the buffers.
+    err = native_window_set_buffers_dimensions(window, 0, 0);
+    if (err != 0) {
+        ALOGE("native_window_set_buffers_dimensions(0,0) failed: %s (%d)", strerror(-err), err);
+        return false;
+    }
+
+    // Enable auto prerotation, so when buffer size is driven by the consumer
+    // and the transform hint specifies a 90 or 270 degree rotation, the width
+    // and height used for buffer pre-allocation and dequeueBuffer will be
+    // additionally swapped.
+    err = native_window_set_auto_prerotation(window, true);
+    if (err != 0) {
+        ALOGE("VulkanSurface::UpdateWindow() native_window_set_auto_prerotation failed: %s (%d)",
+              strerror(-err), err);
         return false;
     }
 
     return true;
 }
 
-class VkSurfaceAutoDeleter {
-public:
-    VkSurfaceAutoDeleter(VkInstance instance, VkSurfaceKHR surface,
-                         PFN_vkDestroySurfaceKHR destroySurfaceKHR)
-            : mInstance(instance), mSurface(surface), mDestroySurfaceKHR(destroySurfaceKHR) {}
-    ~VkSurfaceAutoDeleter() { destroy(); }
-
-    void destroy() {
-        if (mSurface != VK_NULL_HANDLE) {
-            mDestroySurfaceKHR(mInstance, mSurface, nullptr);
-            mSurface = VK_NULL_HANDLE;
-        }
-    }
-
-private:
-    VkInstance mInstance;
-    VkSurfaceKHR mSurface;
-    PFN_vkDestroySurfaceKHR mDestroySurfaceKHR;
-};
-
 VulkanSurface* VulkanSurface::Create(ANativeWindow* window, ColorMode colorMode,
                                      SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
                                      GrContext* grContext, const VulkanManager& vkManager,
                                      uint32_t extraBuffers) {
-    VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
-    memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
-    surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
-    surfaceCreateInfo.pNext = nullptr;
-    surfaceCreateInfo.flags = 0;
-    surfaceCreateInfo.window = window;
-
-    VkSurfaceKHR vkSurface = VK_NULL_HANDLE;
-    VkResult res = vkManager.mCreateAndroidSurfaceKHR(vkManager.mInstance, &surfaceCreateInfo,
-                                                      nullptr, &vkSurface);
-    if (VK_SUCCESS != res) {
-        ALOGE("VulkanSurface::Create() vkCreateAndroidSurfaceKHR failed (%d)", res);
+    // Connect and set native window to default configurations.
+    if (!ConnectAndSetWindowDefaults(window)) {
         return nullptr;
     }
 
-    VkSurfaceAutoDeleter vkSurfaceDeleter(vkManager.mInstance, vkSurface,
-                                          vkManager.mDestroySurfaceKHR);
-
-    SkDEBUGCODE(VkBool32 supported; res = vkManager.mGetPhysicalDeviceSurfaceSupportKHR(
-                                            vkManager.mPhysicalDevice, vkManager.mPresentQueueIndex,
-                                            vkSurface, &supported);
-                // All physical devices and queue families on Android must be capable of
-                // presentation with any native window.
-                SkASSERT(VK_SUCCESS == res && supported););
-
-    // check for capabilities
-    VkSurfaceCapabilitiesKHR caps;
-    res = vkManager.mGetPhysicalDeviceSurfaceCapabilitiesKHR(vkManager.mPhysicalDevice, vkSurface,
-                                                             &caps);
-    if (VK_SUCCESS != res) {
-        ALOGE("VulkanSurface::Create() vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed (%d)", res);
-        return nullptr;
-    }
-
-    LOG_ALWAYS_FATAL_IF(0 == (caps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR));
-
-    /*
-     * We must destroy the VK Surface before attempting to update the window as doing so after
-     * will cause the native window to be modified in unexpected ways.
-     */
-    vkSurfaceDeleter.destroy();
-
-    /*
-     * Populate Window Info struct
-     */
+    // Initialize WindowInfo struct.
     WindowInfo windowInfo;
+    if (!InitializeWindowInfoStruct(window, colorMode, colorType, colorSpace, vkManager,
+                                    extraBuffers, &windowInfo)) {
+        return nullptr;
+    }
 
-    windowInfo.transform = ConvertVkTransformToNative(caps.supportedTransforms);
-    windowInfo.size = SkISize::Make(caps.currentExtent.width, caps.currentExtent.height);
+    // Now we attempt to modify the window.
+    if (!UpdateWindow(window, windowInfo)) {
+        return nullptr;
+    }
 
-    const SkISize minSize = SkISize::Make(caps.minImageExtent.width, caps.minImageExtent.height);
-    const SkISize maxSize = SkISize::Make(caps.maxImageExtent.width, caps.maxImageExtent.height);
-    ComputeWindowSizeAndTransform(&windowInfo, minSize, maxSize);
+    return new VulkanSurface(window, windowInfo, grContext);
+}
+
+bool VulkanSurface::InitializeWindowInfoStruct(ANativeWindow* window, ColorMode colorMode,
+                                               SkColorType colorType,
+                                               sk_sp<SkColorSpace> colorSpace,
+                                               const VulkanManager& vkManager,
+                                               uint32_t extraBuffers, WindowInfo* outWindowInfo) {
+    ATRACE_CALL();
+
+    int width, height;
+    int err = window->query(window, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
+    if (err != 0 || width < 0) {
+        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, width);
+        return false;
+    }
+    err = window->query(window, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
+    if (err != 0 || height < 0) {
+        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, height);
+        return false;
+    }
+    outWindowInfo->size = SkISize::Make(width, height);
 
     int query_value;
-    int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
+    err = window->query(window, NATIVE_WINDOW_TRANSFORM_HINT, &query_value);
     if (err != 0 || query_value < 0) {
         ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
-        return nullptr;
+        return false;
     }
-    auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
+    outWindowInfo->transform = query_value;
 
-    windowInfo.bufferCount = min_undequeued_buffers +
-                             std::max(sTargetBufferCount + extraBuffers, caps.minImageCount);
-    if (caps.maxImageCount > 0 && windowInfo.bufferCount > caps.maxImageCount) {
+    outWindowInfo->actualSize = outWindowInfo->size;
+    if (outWindowInfo->transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+        outWindowInfo->actualSize.set(outWindowInfo->size.height(), outWindowInfo->size.width());
+    }
+
+    outWindowInfo->preTransform =
+            GetPreTransformMatrix(outWindowInfo->size, outWindowInfo->transform);
+
+    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 false;
+    }
+    outWindowInfo->bufferCount =
+            static_cast<uint32_t>(query_value) + sTargetBufferCount + extraBuffers;
+
+    err = window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT, &query_value);
+    if (err != 0 || query_value < 0) {
+        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
+        return false;
+    }
+    if (outWindowInfo->bufferCount > static_cast<uint32_t>(query_value)) {
         // Application must settle for fewer images than desired:
-        windowInfo.bufferCount = caps.maxImageCount;
+        outWindowInfo->bufferCount = static_cast<uint32_t>(query_value);
     }
 
-    // Currently Skia requires the images to be color attachments and support all transfer
-    // operations.
-    VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
-                                   VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
-                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-    LOG_ALWAYS_FATAL_IF((caps.supportedUsageFlags & usageFlags) != usageFlags);
-
-    windowInfo.dataspace = HAL_DATASPACE_V0_SRGB;
+    outWindowInfo->dataspace = HAL_DATASPACE_V0_SRGB;
     if (colorMode == ColorMode::WideColorGamut) {
         skcms_Matrix3x3 surfaceGamut;
         LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&surfaceGamut),
                             "Could not get gamut matrix from color space");
         if (memcmp(&surfaceGamut, &SkNamedGamut::kSRGB, sizeof(surfaceGamut)) == 0) {
-            windowInfo.dataspace = HAL_DATASPACE_V0_SCRGB;
+            outWindowInfo->dataspace = HAL_DATASPACE_V0_SCRGB;
         } else if (memcmp(&surfaceGamut, &SkNamedGamut::kDCIP3, sizeof(surfaceGamut)) == 0) {
-            windowInfo.dataspace = HAL_DATASPACE_DISPLAY_P3;
+            outWindowInfo->dataspace = HAL_DATASPACE_DISPLAY_P3;
         } else {
             LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
         }
     }
 
-    windowInfo.pixelFormat = ColorTypeToPixelFormat(colorType);
+    outWindowInfo->pixelFormat = ColorTypeToPixelFormat(colorType);
     VkFormat vkPixelFormat = VK_FORMAT_R8G8B8A8_UNORM;
-    if (windowInfo.pixelFormat == PIXEL_FORMAT_RGBA_FP16) {
+    if (outWindowInfo->pixelFormat == PIXEL_FORMAT_RGBA_FP16) {
         vkPixelFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
     }
 
@@ -275,7 +228,10 @@
     imageFormatInfo.format = vkPixelFormat;
     imageFormatInfo.type = VK_IMAGE_TYPE_2D;
     imageFormatInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
-    imageFormatInfo.usage = usageFlags;
+    // Currently Skia requires the images to be color attachments and support all transfer
+    // operations.
+    imageFormatInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
+                            VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
     imageFormatInfo.flags = 0;
 
     VkAndroidHardwareBufferUsageANDROID hwbUsage;
@@ -286,35 +242,27 @@
     imgFormProps.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
     imgFormProps.pNext = &hwbUsage;
 
-    res = vkManager.mGetPhysicalDeviceImageFormatProperties2(vkManager.mPhysicalDevice,
-                                                             &imageFormatInfo, &imgFormProps);
+    VkResult res = vkManager.mGetPhysicalDeviceImageFormatProperties2(
+            vkManager.mPhysicalDevice, &imageFormatInfo, &imgFormProps);
     if (VK_SUCCESS != res) {
         ALOGE("Failed to query GetPhysicalDeviceImageFormatProperties2");
-        return nullptr;
+        return false;
     }
 
     uint64_t consumerUsage;
-    native_window_get_consumer_usage(window, &consumerUsage);
-    windowInfo.windowUsageFlags = consumerUsage | hwbUsage.androidHardwareBufferUsage;
-
-    /*
-     * Now we attempt to modify the window!
-     */
-    if (!UpdateWindow(window, windowInfo)) {
-        return nullptr;
+    err = native_window_get_consumer_usage(window, &consumerUsage);
+    if (err != 0) {
+        ALOGE("native_window_get_consumer_usage failed: %s (%d)", strerror(-err), err);
+        return false;
     }
+    outWindowInfo->windowUsageFlags = consumerUsage | hwbUsage.androidHardwareBufferUsage;
 
-    return new VulkanSurface(window, windowInfo, minSize, maxSize, grContext);
+    return true;
 }
 
 bool VulkanSurface::UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo) {
     ATRACE_CALL();
 
-    if (!ResetNativeWindow(window)) {
-        return false;
-    }
-
-    // -- Configure the native window --
     int err = native_window_set_buffers_format(window, windowInfo.pixelFormat);
     if (err != 0) {
         ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_format(%d) failed: %s (%d)",
@@ -330,15 +278,6 @@
         return false;
     }
 
-    const SkISize& size = windowInfo.actualSize;
-    err = native_window_set_buffers_dimensions(window, size.width(), size.height());
-    if (err != 0) {
-        ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffers_dimensions(%d,%d) "
-              "failed: %s (%d)",
-              size.width(), size.height(), strerror(-err), err);
-        return false;
-    }
-
     // native_window_set_buffers_transform() expects the transform the app is requesting that
     // the compositor perform during composition. With native windows, pre-transform works by
     // rendering with the same transform the compositor is applying (as in Vulkan), but
@@ -353,16 +292,6 @@
         return false;
     }
 
-    // Vulkan defaults to NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW, but this is different than
-    // HWUI's expectation
-    err = native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_FREEZE);
-    if (err != 0) {
-        ALOGE("VulkanSurface::UpdateWindow() native_window_set_scaling_mode(SCALE_TO_WINDOW) "
-              "failed: %s (%d)",
-              strerror(-err), err);
-        return false;
-    }
-
     err = native_window_set_buffer_count(window, windowInfo.bufferCount);
     if (err != 0) {
         ALOGE("VulkanSurface::UpdateWindow() native_window_set_buffer_count(%zu) failed: %s (%d)",
@@ -377,16 +306,12 @@
         return false;
     }
 
-    return err == 0;
+    return true;
 }
 
 VulkanSurface::VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo,
-                             SkISize minWindowSize, SkISize maxWindowSize, GrContext* grContext)
-        : mNativeWindow(window)
-        , mWindowInfo(windowInfo)
-        , mGrContext(grContext)
-        , mMinWindowSize(minWindowSize)
-        , mMaxWindowSize(maxWindowSize) {}
+                             GrContext* grContext)
+        : mNativeWindow(window), mWindowInfo(windowInfo), mGrContext(grContext) {}
 
 VulkanSurface::~VulkanSurface() {
     releaseBuffers();
@@ -429,58 +354,51 @@
     // value at the end of the function if everything dequeued correctly.
     mCurrentBufferInfo = nullptr;
 
-    // check if the native window has been resized or rotated and update accordingly
-    SkISize newSize = SkISize::MakeEmpty();
+    // Query the transform hint synced from the initial Surface connect or last queueBuffer. The
+    // auto prerotation on the buffer is based on the same transform hint in use by the producer.
     int transformHint = 0;
-    mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &newSize.fWidth);
-    mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_HEIGHT, &newSize.fHeight);
-    mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
-    if (newSize != mWindowInfo.actualSize || transformHint != mWindowInfo.transform) {
-        WindowInfo newWindowInfo = mWindowInfo;
-        newWindowInfo.size = newSize;
-        newWindowInfo.transform = IsTransformSupported(transformHint) ? transformHint : 0;
-        ComputeWindowSizeAndTransform(&newWindowInfo, mMinWindowSize, mMaxWindowSize);
+    int err =
+            mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
 
-        int err = 0;
-        if (newWindowInfo.actualSize != mWindowInfo.actualSize) {
-            // reset the native buffers and update the window
-            err = native_window_set_buffers_dimensions(mNativeWindow.get(),
-                                                       newWindowInfo.actualSize.width(),
-                                                       newWindowInfo.actualSize.height());
-            if (err != 0) {
-                ALOGE("native_window_set_buffers_dimensions(%d,%d) failed: %s (%d)",
-                      newWindowInfo.actualSize.width(), newWindowInfo.actualSize.height(),
-                      strerror(-err), err);
-                return nullptr;
-            }
-            // reset the NativeBufferInfo (including SkSurface) associated with the old buffers. The
-            // new NativeBufferInfo storage will be populated lazily as we dequeue each new buffer.
-            releaseBuffers();
-            // TODO should we ask the nativewindow to allocate buffers?
-        }
-
-        if (newWindowInfo.transform != mWindowInfo.transform) {
-            err = native_window_set_buffers_transform(mNativeWindow.get(),
-                                                      InvertTransform(newWindowInfo.transform));
-            if (err != 0) {
-                ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)",
-                      newWindowInfo.transform, strerror(-err), err);
-                newWindowInfo.transform = mWindowInfo.transform;
-                ComputeWindowSizeAndTransform(&newWindowInfo, mMinWindowSize, mMaxWindowSize);
-            }
-        }
-
-        mWindowInfo = newWindowInfo;
-    }
-
+    // Since auto pre-rotation is enabled, dequeueBuffer to get the consumer driven buffer size
+    // from ANativeWindowBuffer.
     ANativeWindowBuffer* buffer;
     int fence_fd;
-    int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fence_fd);
+    err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fence_fd);
     if (err != 0) {
         ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), err);
         return nullptr;
     }
 
+    SkISize actualSize = SkISize::Make(buffer->width, buffer->height);
+    if (actualSize != mWindowInfo.actualSize || transformHint != mWindowInfo.transform) {
+        if (actualSize != mWindowInfo.actualSize) {
+            // reset the NativeBufferInfo (including SkSurface) associated with the old buffers. The
+            // new NativeBufferInfo storage will be populated lazily as we dequeue each new buffer.
+            mWindowInfo.actualSize = actualSize;
+            releaseBuffers();
+        }
+
+        if (transformHint != mWindowInfo.transform) {
+            err = native_window_set_buffers_transform(mNativeWindow.get(),
+                                                      InvertTransform(transformHint));
+            if (err != 0) {
+                ALOGE("native_window_set_buffers_transform(%d) failed: %s (%d)", transformHint,
+                      strerror(-err), err);
+                mNativeWindow->cancelBuffer(mNativeWindow.get(), buffer, fence_fd);
+                return nullptr;
+            }
+            mWindowInfo.transform = transformHint;
+        }
+
+        mWindowInfo.size = actualSize;
+        if (mWindowInfo.transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+            mWindowInfo.size.set(actualSize.height(), actualSize.width());
+        }
+
+        mWindowInfo.preTransform = GetPreTransformMatrix(mWindowInfo.size, mWindowInfo.transform);
+    }
+
     uint32_t idx;
     for (idx = 0; idx < mWindowInfo.bufferCount; idx++) {
         if (mNativeBuffers[idx].buffer.get() == buffer) {
diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h
index b7af596..5717bb3 100644
--- a/libs/hwui/renderthread/VulkanSurface.h
+++ b/libs/hwui/renderthread/VulkanSurface.h
@@ -17,6 +17,7 @@
 
 #include <system/graphics.h>
 #include <system/window.h>
+#include <ui/BufferQueueDefs.h>
 #include <vulkan/vulkan.h>
 
 #include <SkRefCnt.h>
@@ -101,11 +102,12 @@
         SkMatrix preTransform;
     };
 
-    VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, SkISize minWindowSize,
-                  SkISize maxWindowSize, GrContext* grContext);
+    VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, GrContext* grContext);
+    static bool InitializeWindowInfoStruct(ANativeWindow* window, ColorMode colorMode,
+                                           SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
+                                           const VulkanManager& vkManager, uint32_t extraBuffers,
+                                           WindowInfo* outWindowInfo);
     static bool UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo);
-    static void ComputeWindowSizeAndTransform(WindowInfo* windowInfo, const SkISize& minSize,
-                                              const SkISize& maxSize);
     void releaseBuffers();
 
     // TODO: Just use a vector?
@@ -117,11 +119,8 @@
 
     uint32_t mPresentCount = 0;
     NativeBufferInfo* mCurrentBufferInfo = nullptr;
-
-    const SkISize mMinWindowSize;
-    const SkISize mMaxWindowSize;
 };
 
 } /* namespace renderthread */
 } /* namespace uirenderer */
-} /* namespace android */
\ No newline at end of file
+} /* namespace android */
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 9c845f0..22d5abb 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -146,7 +146,7 @@
     }
     for (int i = 0; i < warmupFrameCount; i++) {
         testContext.waitForVsync();
-        nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
+        nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
         UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
         proxy->syncAndDrawFrame();
     }
@@ -161,10 +161,10 @@
 
     ModifiedMovingAverage<double> avgMs(opts.reportFrametimeWeight);
 
-    nsecs_t start = systemTime(CLOCK_MONOTONIC);
+    nsecs_t start = systemTime(SYSTEM_TIME_MONOTONIC);
     for (int i = 0; i < opts.count; i++) {
         testContext.waitForVsync();
-        nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
+        nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
         {
             ATRACE_NAME("UI-Draw Frame");
             UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
@@ -173,7 +173,7 @@
         }
         if (opts.reportFrametimeWeight) {
             proxy->fence();
-            nsecs_t done = systemTime(CLOCK_MONOTONIC);
+            nsecs_t done = systemTime(SYSTEM_TIME_MONOTONIC);
             avgMs.add((done - vsync) / 1000000.0);
             if (i % 10 == 9) {
                 printf("Average frametime %.3fms\n", avgMs.average());
@@ -181,7 +181,7 @@
         }
     }
     proxy->fence();
-    nsecs_t end = systemTime(CLOCK_MONOTONIC);
+    nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
 
     if (reporter) {
         outputBenchmarkReport(info, opts, reporter, proxy.get(), (end - start) / (double)s2ns(1));
diff --git a/libs/hwui/tests/microbench/main.cpp b/libs/hwui/tests/microbench/main.cpp
index b5abf5b..9c4d2596 100644
--- a/libs/hwui/tests/microbench/main.cpp
+++ b/libs/hwui/tests/microbench/main.cpp
@@ -14,9 +14,6 @@
  * limitations under the License.
  */
 
-#include "debug/GlesDriver.h"
-#include "debug/NullGlesDriver.h"
-
 #include "hwui/Typeface.h"
 
 #include <benchmark/benchmark.h>
@@ -24,10 +21,8 @@
 #include <memory>
 
 using namespace android;
-using namespace android::uirenderer;
 
 int main(int argc, char** argv) {
-    debug::GlesDriver::replace(std::make_unique<debug::NullGlesDriver>());
     benchmark::Initialize(&argc, argv);
     Typeface::setRobotoTypefaceForTest();
     benchmark::RunSpecifiedBenchmarks();
diff --git a/libs/hwui/tests/scripts/skp-capture.sh b/libs/hwui/tests/scripts/skp-capture.sh
index 54fa229..aad31fc 100755
--- a/libs/hwui/tests/scripts/skp-capture.sh
+++ b/libs/hwui/tests/scripts/skp-capture.sh
@@ -4,6 +4,12 @@
 #
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+#
+# Before this can be used, the device must be rooted and the filesystem must be writable by Skia
+# - These steps are necessary once after flashing to enable capture -
+# adb root
+# adb remount
+# adb reboot
 
 if [ -z "$1" ]; then
     printf 'Usage:\n    skp-capture.sh PACKAGE_NAME OPTIONAL_FRAME_COUNT\n\n'
@@ -20,8 +26,8 @@
         exit 2
     fi
 fi
-phase1_timeout_seconds=15
-phase2_timeout_seconds=60
+phase1_timeout_seconds=60
+phase2_timeout_seconds=300
 package="$1"
 filename="$(date '+%H%M%S').skp"
 remote_path="/data/data/${package}/cache/${filename}"
@@ -29,11 +35,14 @@
 local_path="${local_path_prefix}.skp"
 enable_capture_key='debug.hwui.capture_skp_enabled'
 enable_capture_value=$(adb shell "getprop '${enable_capture_key}'")
-#printf 'captureflag=' "$enable_capture_value" '\n'
+
+# TODO(nifong): check if filesystem is writable here with "avbctl get-verity"
+# result will either start with "verity is disabled" or "verity is enabled"
+
 if [ -z "$enable_capture_value" ]; then
-    printf 'Capture SKP property need to be enabled first. Please use\n'
-    printf "\"adb shell setprop debug.hwui.capture_skp_enabled true\" and then restart\n"
-    printf "the process.\n\n"
+    printf 'debug.hwui.capture_skp_enabled was found to be disabled, enabling it now.\n'
+    printf " restart the process you want to capture on the device, then retry this script.\n\n"
+    adb shell "setprop '${enable_capture_key}' true"
     exit 1
 fi
 if [ ! -z "$2" ]; then
@@ -57,33 +66,17 @@
     printf '   %s' "$*"
     printf '\n=====================\n'
 }
-banner '...WAITING...'
-adb_test_exist() {
-    test '0' = "$(adb shell "test -e \"$1\"; echo \$?")";
-}
-timeout=$(( $(date +%s) + $phase1_timeout_seconds))
-while ! adb_test_exist "$remote_path"; do
-    spin 0.05
-    if [ $(date +%s) -gt $timeout ] ; then
-        printf '\bTimed out.\n'
-        adb shell "setprop '${filename_key}' ''"
-        exit 3
-    fi
-done
-printf '\b'
-
-#read -n1 -r -p "Press any key to continue..." key
-
-banner '...SAVING...'
+banner '...WAITING FOR APP INTERACTION...'
+# Waiting for nonzero file is an indication that the pipeline has both opened the file and written
+# the header. With multiple frames this does not occur until the last frame has been recorded,
+# so we continue to show the "waiting for app interaction" message as long as the app still requires
+# interaction to draw more frames.
 adb_test_file_nonzero() {
     # grab first byte of `du` output
     X="$(adb shell "du \"$1\" 2> /dev/null | dd bs=1 count=1 2> /dev/null")"
     test "$X" && test "$X" -ne 0
 }
-#adb_filesize() {
-#    adb shell "wc -c \"$1\"" 2> /dev/null | awk '{print $1}'
-#}
-timeout=$(( $(date +%s) + $phase2_timeout_seconds))
+timeout=$(( $(date +%s) + $phase1_timeout_seconds))
 while ! adb_test_file_nonzero "$remote_path"; do
     spin 0.05
     if [ $(date +%s) -gt $timeout ] ; then
@@ -94,8 +87,37 @@
 done
 printf '\b'
 
+# Disable further capturing
 adb shell "setprop '${filename_key}' ''"
 
+banner '...SAVING...'
+# return the size of a file in bytes
+adb_filesize() {
+    adb shell "wc -c \"$1\"" 2> /dev/null | awk '{print $1}'
+}
+timeout=$(( $(date +%s) + $phase2_timeout_seconds))
+last_size='0' # output of last size check command
+unstable=true # false once the file size stops changing
+counter=0 # used to perform size check only 1/sec though we update spinner 20/sec
+# loop until the file size is unchanged for 1 second.
+while [ $unstable != 0 ] ; do
+    spin 0.05
+    counter=$(( $counter+1 ))
+    if ! (( $counter % 20)) ; then
+        new_size=$(adb_filesize "$remote_path")
+        unstable=$(($(adb_filesize "$remote_path") != last_size))
+        last_size=$new_size
+    fi
+    if [ $(date +%s) -gt $timeout ] ; then
+        printf '\bTimed out.\n'
+        adb shell "setprop '${filename_key}' ''"
+        exit 3
+    fi
+done
+printf '\b'
+
+printf "SKP file serialized: %s\n" $(echo $last_size | numfmt --to=iec)
+
 i=0; while [ $i -lt 10 ]; do spin 0.10; i=$(($i + 1)); done; echo
 
 adb pull "$remote_path" "$local_path"
@@ -105,12 +127,4 @@
 fi
 adb shell rm "$remote_path"
 printf '\nSKP saved to file:\n    %s\n\n'  "$local_path"
-if [ ! -z "$2" ]; then
-    bridge="_"
-    adb shell "setprop 'debug.hwui.capture_skp_frames' ''"
-    for i in $(seq 2 $2); do
-        adb pull "${remote_path}_${i}" "${local_path_prefix}_${i}.skp"
-        adb shell rm "${remote_path}_${i}"
-    done
-fi
 
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index c813cd9..e70378b 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -1096,10 +1096,8 @@
         int getDrawCounter() { return mDrawCounter; }
 
         virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
-            // expect to draw 2 RenderNodeDrawable, 1 StartReorderBarrierDrawable,
-            // 1 EndReorderBarrierDrawable
-            mDrawCounter++;
-            SkCanvas::onDrawDrawable(drawable, matrix);
+            // Do not expect this to be called. See RecordingCanvas.cpp DrawDrawable for context.
+            EXPECT_TRUE(false);
         }
 
         virtual void didTranslate(SkScalar dx, SkScalar dy) override {
@@ -1159,8 +1157,8 @@
     // create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
     ShadowTestCanvas canvas(CANVAS_WIDTH, CANVAS_HEIGHT);
     RenderNodeDrawable drawable(parent.get(), &canvas, false);
-    canvas.drawDrawable(&drawable);
-    EXPECT_EQ(9, canvas.getDrawCounter());
+    drawable.draw(&canvas);
+    EXPECT_EQ(5, canvas.getDrawCounter());
 }
 
 // Draw a vector drawable twice but with different bounds and verify correct bounds are used.
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index a671bda..7b76bd8 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -29,6 +29,7 @@
 #include "pipeline/skia/SkiaRecordingCanvas.h"
 #include "pipeline/skia/SkiaUtils.h"
 #include "renderthread/CanvasContext.h"
+#include "tests/common/TestContext.h"
 #include "tests/common/TestUtils.h"
 
 #include <gui/BufferItemConsumer.h>
@@ -424,17 +425,9 @@
     EXPECT_EQ(1, surface->canvas()->mDrawCounter);
 }
 
-static sp<Surface> createDummySurface() {
-    sp<IGraphicBufferProducer> producer;
-    sp<IGraphicBufferConsumer> consumer;
-    BufferQueue::createBufferQueue(&producer, &consumer);
-    producer->setMaxDequeuedBufferCount(1);
-    producer->setAsyncMode(true);
-    return new Surface(producer);
-}
-
 RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) {
-    auto surface = createDummySurface();
+    test::TestContext context;
+    auto surface = context.surface();
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     EXPECT_FALSE(pipeline->isSurfaceReady());
     EXPECT_TRUE(pipeline->setSurface(surface.get(), SwapBehavior::kSwap_default, ColorMode::SRGB, 0));
diff --git a/libs/hwui/tests/unit/main.cpp b/libs/hwui/tests/unit/main.cpp
index 83d888c..402cb58 100644
--- a/libs/hwui/tests/unit/main.cpp
+++ b/libs/hwui/tests/unit/main.cpp
@@ -18,8 +18,6 @@
 #include "gtest/gtest.h"
 
 #include "Properties.h"
-#include "debug/GlesDriver.h"
-#include "debug/NullGlesDriver.h"
 #include "hwui/Typeface.h"
 #include "tests/common/LeakChecker.h"
 
@@ -65,7 +63,6 @@
     }
 
     // Replace the default GLES driver
-    debug::GlesDriver::replace(std::make_unique<debug::NullGlesDriver>());
     Properties::isolatedProcess = true;
 
     // Run the tests
diff --git a/libs/hwui/thread/WorkQueue.h b/libs/hwui/thread/WorkQueue.h
index 42f8503..46b8bc0 100644
--- a/libs/hwui/thread/WorkQueue.h
+++ b/libs/hwui/thread/WorkQueue.h
@@ -31,7 +31,7 @@
 namespace android::uirenderer {
 
 struct MonotonicClock {
-    static nsecs_t now() { return systemTime(CLOCK_MONOTONIC); }
+    static nsecs_t now() { return systemTime(SYSTEM_TIME_MONOTONIC); }
 };
 
 class WorkQueue {
diff --git a/libs/hwui/utils/GLUtils.cpp b/libs/hwui/utils/GLUtils.cpp
index c694e93..6189762 100644
--- a/libs/hwui/utils/GLUtils.cpp
+++ b/libs/hwui/utils/GLUtils.cpp
@@ -21,19 +21,10 @@
 
 #include "GLUtils.h"
 
-#if DEBUG_OPENGL >= DEBUG_LEVEL_HIGH && !defined(HWUI_GLES_WRAP_ENABLED)
-#error Setting DEBUG_OPENGL to HIGH requires setting HWUI_ENABLE_OPENGL_VALIDATION to true in the Android.mk!
-#endif
-
 namespace android {
 namespace uirenderer {
 
 bool GLUtils::dumpGLErrors() {
-#if DEBUG_OPENGL >= DEBUG_LEVEL_HIGH
-    // If DEBUG_LEVEL_HIGH is set then every GLES call is already wrapped
-    // and asserts that there was no error. So this can just return success.
-    return false;
-#else
     bool errorObserved = false;
     GLenum status = GL_NO_ERROR;
     while ((status = glGetError()) != GL_NO_ERROR) {
@@ -56,7 +47,6 @@
         }
     }
     return errorObserved;
-#endif
 }
 
 const char* GLUtils::getGLFramebufferError() {
diff --git a/libs/hwui/utils/HostColorSpace.cpp b/libs/hwui/utils/HostColorSpace.cpp
new file mode 100644
index 0000000..77a6820
--- /dev/null
+++ b/libs/hwui/utils/HostColorSpace.cpp
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 is copied from framework/native/libs/ui in order not to include libui in host build
+
+#include <ui/ColorSpace.h>
+
+using namespace std::placeholders;
+
+namespace android {
+
+static constexpr float linearResponse(float v) {
+    return v;
+}
+
+static constexpr float rcpResponse(float x, const ColorSpace::TransferParameters& p) {
+    return x >= p.d * p.c ? (std::pow(x, 1.0f / p.g) - p.b) / p.a : x / p.c;
+}
+
+static constexpr float response(float x, const ColorSpace::TransferParameters& p) {
+    return x >= p.d ? std::pow(p.a * x + p.b, p.g) : p.c * x;
+}
+
+static constexpr float rcpFullResponse(float x, const ColorSpace::TransferParameters& p) {
+    return x >= p.d * p.c ? (std::pow(x - p.e, 1.0f / p.g) - p.b) / p.a : (x - p.f) / p.c;
+}
+
+static constexpr float fullResponse(float x, const ColorSpace::TransferParameters& p) {
+    return x >= p.d ? std::pow(p.a * x + p.b, p.g) + p.e : p.c * x + p.f;
+}
+
+static float absRcpResponse(float x, float g,float a, float b, float c, float d) {
+    float xx = std::abs(x);
+    return std::copysign(xx >= d * c ? (std::pow(xx, 1.0f / g) - b) / a : xx / c, x);
+}
+
+static float absResponse(float x, float g, float a, float b, float c, float d) {
+   float xx = std::abs(x);
+   return std::copysign(xx >= d ? std::pow(a * xx + b, g) : c * xx, x);
+}
+
+static float safePow(float x, float e) {
+    return powf(x < 0.0f ? 0.0f : x, e);
+}
+
+static ColorSpace::transfer_function toOETF(const ColorSpace::TransferParameters& parameters) {
+    if (parameters.e == 0.0f && parameters.f == 0.0f) {
+        return std::bind(rcpResponse, _1, parameters);
+    }
+    return std::bind(rcpFullResponse, _1, parameters);
+}
+
+static ColorSpace::transfer_function toEOTF( const ColorSpace::TransferParameters& parameters) {
+    if (parameters.e == 0.0f && parameters.f == 0.0f) {
+        return std::bind(response, _1, parameters);
+    }
+    return std::bind(fullResponse, _1, parameters);
+}
+
+static ColorSpace::transfer_function toOETF(float gamma) {
+    if (gamma == 1.0f) {
+        return linearResponse;
+    }
+    return std::bind(safePow, _1, 1.0f / gamma);
+}
+
+static ColorSpace::transfer_function toEOTF(float gamma) {
+    if (gamma == 1.0f) {
+        return linearResponse;
+    }
+    return std::bind(safePow, _1, gamma);
+}
+
+static constexpr std::array<float2, 3> computePrimaries(const mat3& rgbToXYZ) {
+    float3 r(rgbToXYZ * float3{1, 0, 0});
+    float3 g(rgbToXYZ * float3{0, 1, 0});
+    float3 b(rgbToXYZ * float3{0, 0, 1});
+
+    return {{r.xy / dot(r, float3{1}),
+             g.xy / dot(g, float3{1}),
+             b.xy / dot(b, float3{1})}};
+}
+
+static constexpr float2 computeWhitePoint(const mat3& rgbToXYZ) {
+    float3 w(rgbToXYZ * float3{1});
+    return w.xy / dot(w, float3{1});
+}
+
+ColorSpace::ColorSpace(
+        const std::string& name,
+        const mat3& rgbToXYZ,
+        transfer_function OETF,
+        transfer_function EOTF,
+        clamping_function clamper) noexcept
+        : mName(name)
+        , mRGBtoXYZ(rgbToXYZ)
+        , mXYZtoRGB(inverse(rgbToXYZ))
+        , mOETF(std::move(OETF))
+        , mEOTF(std::move(EOTF))
+        , mClamper(std::move(clamper))
+        , mPrimaries(computePrimaries(rgbToXYZ))
+        , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
+}
+
+ColorSpace::ColorSpace(
+        const std::string& name,
+        const mat3& rgbToXYZ,
+        const TransferParameters parameters,
+        clamping_function clamper) noexcept
+        : mName(name)
+        , mRGBtoXYZ(rgbToXYZ)
+        , mXYZtoRGB(inverse(rgbToXYZ))
+        , mParameters(parameters)
+        , mOETF(toOETF(mParameters))
+        , mEOTF(toEOTF(mParameters))
+        , mClamper(std::move(clamper))
+        , mPrimaries(computePrimaries(rgbToXYZ))
+        , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
+}
+
+ColorSpace::ColorSpace(
+        const std::string& name,
+        const mat3& rgbToXYZ,
+        float gamma,
+        clamping_function clamper) noexcept
+        : mName(name)
+        , mRGBtoXYZ(rgbToXYZ)
+        , mXYZtoRGB(inverse(rgbToXYZ))
+        , mParameters({gamma, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f})
+        , mOETF(toOETF(gamma))
+        , mEOTF(toEOTF(gamma))
+        , mClamper(std::move(clamper))
+        , mPrimaries(computePrimaries(rgbToXYZ))
+        , mWhitePoint(computeWhitePoint(rgbToXYZ)) {
+}
+
+ColorSpace::ColorSpace(
+        const std::string& name,
+        const std::array<float2, 3>& primaries,
+        const float2& whitePoint,
+        transfer_function OETF,
+        transfer_function EOTF,
+        clamping_function clamper) noexcept
+        : mName(name)
+        , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
+        , mXYZtoRGB(inverse(mRGBtoXYZ))
+        , mOETF(std::move(OETF))
+        , mEOTF(std::move(EOTF))
+        , mClamper(std::move(clamper))
+        , mPrimaries(primaries)
+        , mWhitePoint(whitePoint) {
+}
+
+ColorSpace::ColorSpace(
+        const std::string& name,
+        const std::array<float2, 3>& primaries,
+        const float2& whitePoint,
+        const TransferParameters parameters,
+        clamping_function clamper) noexcept
+        : mName(name)
+        , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
+        , mXYZtoRGB(inverse(mRGBtoXYZ))
+        , mParameters(parameters)
+        , mOETF(toOETF(mParameters))
+        , mEOTF(toEOTF(mParameters))
+        , mClamper(std::move(clamper))
+        , mPrimaries(primaries)
+        , mWhitePoint(whitePoint) {
+}
+
+ColorSpace::ColorSpace(
+        const std::string& name,
+        const std::array<float2, 3>& primaries,
+        const float2& whitePoint,
+        float gamma,
+        clamping_function clamper) noexcept
+        : mName(name)
+        , mRGBtoXYZ(computeXYZMatrix(primaries, whitePoint))
+        , mXYZtoRGB(inverse(mRGBtoXYZ))
+        , mParameters({gamma, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f})
+        , mOETF(toOETF(gamma))
+        , mEOTF(toEOTF(gamma))
+        , mClamper(std::move(clamper))
+        , mPrimaries(primaries)
+        , mWhitePoint(whitePoint) {
+}
+
+constexpr mat3 ColorSpace::computeXYZMatrix(
+        const std::array<float2, 3>& primaries, const float2& whitePoint) {
+    const float2& R = primaries[0];
+    const float2& G = primaries[1];
+    const float2& B = primaries[2];
+    const float2& W = whitePoint;
+
+    float oneRxRy = (1 - R.x) / R.y;
+    float oneGxGy = (1 - G.x) / G.y;
+    float oneBxBy = (1 - B.x) / B.y;
+    float oneWxWy = (1 - W.x) / W.y;
+
+    float RxRy = R.x / R.y;
+    float GxGy = G.x / G.y;
+    float BxBy = B.x / B.y;
+    float WxWy = W.x / W.y;
+
+    float BY =
+            ((oneWxWy - oneRxRy) * (GxGy - RxRy) - (WxWy - RxRy) * (oneGxGy - oneRxRy)) /
+            ((oneBxBy - oneRxRy) * (GxGy - RxRy) - (BxBy - RxRy) * (oneGxGy - oneRxRy));
+    float GY = (WxWy - RxRy - BY * (BxBy - RxRy)) / (GxGy - RxRy);
+    float RY = 1 - GY - BY;
+
+    float RYRy = RY / R.y;
+    float GYGy = GY / G.y;
+    float BYBy = BY / B.y;
+
+    return {
+        float3{RYRy * R.x, RY, RYRy * (1 - R.x - R.y)},
+        float3{GYGy * G.x, GY, GYGy * (1 - G.x - G.y)},
+        float3{BYBy * B.x, BY, BYBy * (1 - B.x - B.y)}
+    };
+}
+
+const ColorSpace ColorSpace::sRGB() {
+    return {
+        "sRGB IEC61966-2.1",
+        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+        {0.3127f, 0.3290f},
+        {2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f, 0.0f, 0.0f}
+    };
+}
+
+const ColorSpace ColorSpace::linearSRGB() {
+    return {
+        "sRGB IEC61966-2.1 (Linear)",
+        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+        {0.3127f, 0.3290f}
+    };
+}
+
+const ColorSpace ColorSpace::extendedSRGB() {
+    return {
+        "scRGB-nl IEC 61966-2-2:2003",
+        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+        {0.3127f, 0.3290f},
+        std::bind(absRcpResponse, _1, 2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f),
+        std::bind(absResponse,    _1, 2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.04045f),
+        std::bind(clamp<float>, _1, -0.799f, 2.399f)
+    };
+}
+
+const ColorSpace ColorSpace::linearExtendedSRGB() {
+    return {
+        "scRGB IEC 61966-2-2:2003",
+        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+        {0.3127f, 0.3290f},
+        1.0f,
+        std::bind(clamp<float>, _1, -0.5f, 7.499f)
+    };
+}
+
+const ColorSpace ColorSpace::NTSC() {
+    return {
+        "NTSC (1953)",
+        {{float2{0.67f, 0.33f}, {0.21f, 0.71f}, {0.14f, 0.08f}}},
+        {0.310f, 0.316f},
+        {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
+    };
+}
+
+const ColorSpace ColorSpace::BT709() {
+    return {
+        "Rec. ITU-R BT.709-5",
+        {{float2{0.640f, 0.330f}, {0.300f, 0.600f}, {0.150f, 0.060f}}},
+        {0.3127f, 0.3290f},
+        {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
+    };
+}
+
+const ColorSpace ColorSpace::BT2020() {
+    return {
+        "Rec. ITU-R BT.2020-1",
+        {{float2{0.708f, 0.292f}, {0.170f, 0.797f}, {0.131f, 0.046f}}},
+        {0.3127f, 0.3290f},
+        {1 / 0.45f, 1 / 1.099f, 0.099f / 1.099f, 1 / 4.5f, 0.081f, 0.0f, 0.0f}
+    };
+}
+
+const ColorSpace ColorSpace::AdobeRGB() {
+    return {
+        "Adobe RGB (1998)",
+        {{float2{0.64f, 0.33f}, {0.21f, 0.71f}, {0.15f, 0.06f}}},
+        {0.3127f, 0.3290f},
+        2.2f
+    };
+}
+
+const ColorSpace ColorSpace::ProPhotoRGB() {
+    return {
+        "ROMM RGB ISO 22028-2:2013",
+        {{float2{0.7347f, 0.2653f}, {0.1596f, 0.8404f}, {0.0366f, 0.0001f}}},
+        {0.34567f, 0.35850f},
+        {1.8f, 1.0f, 0.0f, 1 / 16.0f, 0.031248f, 0.0f, 0.0f}
+    };
+}
+
+const ColorSpace ColorSpace::DisplayP3() {
+    return {
+        "Display P3",
+        {{float2{0.680f, 0.320f}, {0.265f, 0.690f}, {0.150f, 0.060f}}},
+        {0.3127f, 0.3290f},
+        {2.4f, 1 / 1.055f, 0.055f / 1.055f, 1 / 12.92f, 0.039f, 0.0f, 0.0f}
+    };
+}
+
+const ColorSpace ColorSpace::DCIP3() {
+    return {
+        "SMPTE RP 431-2-2007 DCI (P3)",
+        {{float2{0.680f, 0.320f}, {0.265f, 0.690f}, {0.150f, 0.060f}}},
+        {0.314f, 0.351f},
+        2.6f
+    };
+}
+
+const ColorSpace ColorSpace::ACES() {
+    return {
+        "SMPTE ST 2065-1:2012 ACES",
+        {{float2{0.73470f, 0.26530f}, {0.0f, 1.0f}, {0.00010f, -0.0770f}}},
+        {0.32168f, 0.33767f},
+        1.0f,
+        std::bind(clamp<float>, _1, -65504.0f, 65504.0f)
+    };
+}
+
+const ColorSpace ColorSpace::ACEScg() {
+    return {
+        "Academy S-2014-004 ACEScg",
+        {{float2{0.713f, 0.293f}, {0.165f, 0.830f}, {0.128f, 0.044f}}},
+        {0.32168f, 0.33767f},
+        1.0f,
+        std::bind(clamp<float>, _1, -65504.0f, 65504.0f)
+    };
+}
+
+std::unique_ptr<float3[]> ColorSpace::createLUT(uint32_t size, const ColorSpace& src,
+                                                const ColorSpace& dst) {
+    size = clamp(size, 2u, 256u);
+    float m = 1.0f / float(size - 1);
+
+    std::unique_ptr<float3[]> lut(new float3[size * size * size]);
+    float3* data = lut.get();
+
+    ColorSpaceConnector connector(src, dst);
+
+    for (uint32_t z = 0; z < size; z++) {
+        for (int32_t y = int32_t(size - 1); y >= 0; y--) {
+            for (uint32_t x = 0; x < size; x++) {
+                *data++ = connector.transform({x * m, y * m, z * m});
+            }
+        }
+    }
+
+    return lut;
+}
+
+static const float2 ILLUMINANT_D50_XY = {0.34567f, 0.35850f};
+static const float3 ILLUMINANT_D50_XYZ = {0.964212f, 1.0f, 0.825188f};
+static const mat3 BRADFORD = mat3{
+    float3{ 0.8951f, -0.7502f,  0.0389f},
+    float3{ 0.2664f,  1.7135f, -0.0685f},
+    float3{-0.1614f,  0.0367f,  1.0296f}
+};
+
+static mat3 adaptation(const mat3& matrix, const float3& srcWhitePoint, const float3& dstWhitePoint) {
+    float3 srcLMS = matrix * srcWhitePoint;
+    float3 dstLMS = matrix * dstWhitePoint;
+    return inverse(matrix) * mat3{dstLMS / srcLMS} * matrix;
+}
+
+ColorSpaceConnector::ColorSpaceConnector(
+        const ColorSpace& src,
+        const ColorSpace& dst) noexcept
+        : mSource(src)
+        , mDestination(dst) {
+
+    if (all(lessThan(abs(src.getWhitePoint() - dst.getWhitePoint()), float2{1e-3f}))) {
+        mTransform = dst.getXYZtoRGB() * src.getRGBtoXYZ();
+    } else {
+        mat3 rgbToXYZ(src.getRGBtoXYZ());
+        mat3 xyzToRGB(dst.getXYZtoRGB());
+
+        float3 srcXYZ = ColorSpace::XYZ(float3{src.getWhitePoint(), 1});
+        float3 dstXYZ = ColorSpace::XYZ(float3{dst.getWhitePoint(), 1});
+
+        if (any(greaterThan(abs(src.getWhitePoint() - ILLUMINANT_D50_XY), float2{1e-3f}))) {
+            rgbToXYZ = adaptation(BRADFORD, srcXYZ, ILLUMINANT_D50_XYZ) * src.getRGBtoXYZ();
+        }
+
+        if (any(greaterThan(abs(dst.getWhitePoint() - ILLUMINANT_D50_XY), float2{1e-3f}))) {
+            xyzToRGB = inverse(adaptation(BRADFORD, dstXYZ, ILLUMINANT_D50_XYZ) * dst.getRGBtoXYZ());
+        }
+
+        mTransform = xyzToRGB * rgbToXYZ;
+    }
+}
+
+}; // namespace android
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 1bdfe87..1cc246b 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -48,6 +48,7 @@
 import android.util.Log;
 
 import com.android.internal.location.ProviderProperties;
+import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -190,19 +191,6 @@
     public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
 
     /**
-     * Broadcast intent action when {@link android.provider.Settings.Secure#LOCATION_MODE} is
-     * about to be changed through Settings app or Quick Settings.
-     * For use with the {@link android.provider.Settings.Secure#LOCATION_MODE} API.
-     * If you're interacting with {@link #isProviderEnabled(String)}, use
-     * {@link #PROVIDERS_CHANGED_ACTION} instead.
-     *
-     * @deprecated Do not use.
-     * @hide
-     */
-    @Deprecated
-    public static final String MODE_CHANGING_ACTION = "com.android.settings.location.MODE_CHANGING";
-
-    /**
      * Broadcast intent action indicating that a high power location requests
      * has either started or stopped being active.  The current state of
      * active location requests should be read from AppOpsManager using
@@ -215,17 +203,10 @@
 
     /**
      * Broadcast intent action for Settings app to inject a footer at the bottom of location
-     * settings.
+     * settings. This is for use only by apps that are included in the system image.
      *
-     * <p>This broadcast is used for two things:
-     * <ol>
-     *     <li>For receivers to inject a footer with provided text. This is for use only by apps
-     *         that are included in the system image. </li>
-     *     <li>For receivers to know their footer is injected under location settings.</li>
-     * </ol>
-     *
-     * <p>To inject a footer to location settings, you must declare a broadcast receiver of
-     * {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} in the manifest as so:
+     * <p>To inject a footer to location settings, you must declare a broadcast receiver for
+     * this action in the manifest:
      * <pre>
      *     &lt;receiver android:name="com.example.android.footer.MyFooterInjector"&gt;
      *         &lt;intent-filter&gt;
@@ -237,10 +218,8 @@
      *     &lt;/receiver&gt;
      * </pre>
      *
-     * <p>On entering location settings, Settings app will send a
-     * {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast to receivers whose footer is successfully
-     * injected. On leaving location settings, the footer becomes not visible to users. Settings app
-     * will send a {@link #SETTINGS_FOOTER_REMOVED_ACTION} broadcast to those receivers.
+     * <p>This broadcast receiver will never actually be invoked. See also
+     * {#METADATA_SETTINGS_FOOTER_STRING}.
      *
      * @hide
      */
@@ -248,16 +227,6 @@
             "com.android.settings.location.DISPLAYED_FOOTER";
 
     /**
-     * Broadcast intent action when location settings footer is not visible to users.
-     *
-     * <p>See {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} for more detail on how to use.
-     *
-     * @hide
-     */
-    public static final String SETTINGS_FOOTER_REMOVED_ACTION =
-            "com.android.settings.location.REMOVED_FOOTER";
-
-    /**
      * Metadata name for {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast
      * receivers to specify a string resource id as location settings footer text. This is for use
      * only by apps that are included in the system image.
@@ -2298,18 +2267,19 @@
     }
 
     /**
-     * Sends additional commands to a location provider.
-     * Can be used to support provider specific extensions to the Location Manager API
+     * Sends additional commands to a location provider. Can be used to support provider specific
+     * extensions to the Location Manager API.
      *
      * @param provider name of the location provider.
-     * @param command name of the command to send to the provider.
-     * @param extras optional arguments for the command (or null).
-     * The provider may optionally fill the extras Bundle with results from the command.
-     *
-     * @return true if the command succeeds.
+     * @param command  name of the command to send to the provider.
+     * @param extras   optional arguments for the command (or null).
+     * @return true always
      */
     public boolean sendExtraCommand(
             @NonNull String provider, @NonNull String command, @Nullable Bundle extras) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+        Preconditions.checkArgument(command != null, "invalid null command");
+
         try {
             return mService.sendExtraCommand(provider, command, extras);
         } catch (RemoteException e) {
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
index 7823971..274e0e4 100644
--- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -40,127 +40,116 @@
  */
 public class GnssMetrics {
 
-  private static final String TAG = GnssMetrics.class.getSimpleName();
+    private static final String TAG = GnssMetrics.class.getSimpleName();
 
-  /* Constant which indicates GPS signal quality is as yet unknown */
-  public static final int GPS_SIGNAL_QUALITY_UNKNOWN =
-          ServerLocationProtoEnums.GPS_SIGNAL_QUALITY_UNKNOWN; // -1
+    /* Constant which indicates GPS signal quality is as yet unknown */
+    private static final int GPS_SIGNAL_QUALITY_UNKNOWN =
+            ServerLocationProtoEnums.GPS_SIGNAL_QUALITY_UNKNOWN; // -1
 
-  /* Constant which indicates GPS signal quality is poor */
-  public static final int GPS_SIGNAL_QUALITY_POOR =
-      ServerLocationProtoEnums.GPS_SIGNAL_QUALITY_POOR; // 0
+    /* Constant which indicates GPS signal quality is poor */
+    private static final int GPS_SIGNAL_QUALITY_POOR =
+            ServerLocationProtoEnums.GPS_SIGNAL_QUALITY_POOR; // 0
 
-  /* Constant which indicates GPS signal quality is good */
-  public static final int GPS_SIGNAL_QUALITY_GOOD =
-      ServerLocationProtoEnums.GPS_SIGNAL_QUALITY_GOOD; // 1
+    /* Constant which indicates GPS signal quality is good */
+    private static final int GPS_SIGNAL_QUALITY_GOOD =
+            ServerLocationProtoEnums.GPS_SIGNAL_QUALITY_GOOD; // 1
 
-  /* Number of GPS signal quality levels */
-  public static final int NUM_GPS_SIGNAL_QUALITY_LEVELS = GPS_SIGNAL_QUALITY_GOOD + 1;
+    /* Number of GPS signal quality levels */
+    public static final int NUM_GPS_SIGNAL_QUALITY_LEVELS = GPS_SIGNAL_QUALITY_GOOD + 1;
 
-  /** Default time between location fixes (in millisecs) */
-  private static final int DEFAULT_TIME_BETWEEN_FIXES_MILLISECS = 1000;
+    /** Default time between location fixes (in millisecs) */
+    private static final int DEFAULT_TIME_BETWEEN_FIXES_MILLISECS = 1000;
 
-  /* The time since boot when logging started */
-  private String logStartInElapsedRealTime;
+    /* The time since boot when logging started */
+    private String mLogStartInElapsedRealTime;
 
-  /* GNSS power metrics */
-  private GnssPowerMetrics mGnssPowerMetrics;
+    /* GNSS power metrics */
+    private GnssPowerMetrics mGnssPowerMetrics;
+
+    /* A boolean array indicating whether the constellation types have been used in fix. */
+    private boolean[] mConstellationTypes;
+    /** Location failure statistics */
+    private Statistics mLocationFailureStatistics;
+    /** Time to first fix statistics */
+    private Statistics mTimeToFirstFixSecStatistics;
+    /** Position accuracy statistics */
+    private Statistics mPositionAccuracyMeterStatistics;
+    /** Top 4 average CN0 statistics */
+    private Statistics mTopFourAverageCn0Statistics;
+
+    public GnssMetrics(IBatteryStats stats) {
+        mGnssPowerMetrics = new GnssPowerMetrics(stats);
+        mLocationFailureStatistics = new Statistics();
+        mTimeToFirstFixSecStatistics = new Statistics();
+        mPositionAccuracyMeterStatistics = new Statistics();
+        mTopFourAverageCn0Statistics = new Statistics();
+        reset();
+    }
 
     /**
-     * A boolean array indicating whether the constellation types have been used in fix.
+     * Logs the status of a location report received from the HAL
      */
-    private boolean[] mConstellationTypes;
-
-  /** Constructor */
-  public GnssMetrics(IBatteryStats stats) {
-    mGnssPowerMetrics = new GnssPowerMetrics(stats);
-    locationFailureStatistics = new Statistics();
-    timeToFirstFixSecStatistics = new Statistics();
-    positionAccuracyMeterStatistics = new Statistics();
-    topFourAverageCn0Statistics = new Statistics();
-    reset();
-  }
-
-  /**
-   * Logs the status of a location report received from the HAL
-   *
-   * @param isSuccessful
-   */
-  public void logReceivedLocationStatus(boolean isSuccessful) {
-    if (!isSuccessful) {
-      locationFailureStatistics.addItem(1.0);
-      return;
+    public void logReceivedLocationStatus(boolean isSuccessful) {
+        if (!isSuccessful) {
+            mLocationFailureStatistics.addItem(1.0);
+            return;
+        }
+        mLocationFailureStatistics.addItem(0.0);
     }
-    locationFailureStatistics.addItem(0.0);
-    return;
-  }
 
-  /**
-   * Logs missed reports
-   *
-   * @param desiredTimeBetweenFixesMilliSeconds
-   * @param actualTimeBetweenFixesMilliSeconds
-   */
-  public void logMissedReports(int desiredTimeBetweenFixesMilliSeconds,
-      int actualTimeBetweenFixesMilliSeconds) {
-    int numReportMissed = (actualTimeBetweenFixesMilliSeconds /
-        Math.max(DEFAULT_TIME_BETWEEN_FIXES_MILLISECS, desiredTimeBetweenFixesMilliSeconds)) - 1;
-    if (numReportMissed > 0) {
-      for (int i = 0; i < numReportMissed; i++) {
-        locationFailureStatistics.addItem(1.0);
-      }
+    /**
+     * Logs missed reports
+     */
+    public void logMissedReports(int desiredTimeBetweenFixesMilliSeconds,
+            int actualTimeBetweenFixesMilliSeconds) {
+        int numReportMissed = (actualTimeBetweenFixesMilliSeconds / Math.max(
+                DEFAULT_TIME_BETWEEN_FIXES_MILLISECS, desiredTimeBetweenFixesMilliSeconds)) - 1;
+        if (numReportMissed > 0) {
+            for (int i = 0; i < numReportMissed; i++) {
+                mLocationFailureStatistics.addItem(1.0);
+            }
+        }
     }
-    return;
-  }
 
-  /**
-   * Logs time to first fix
-   *
-   * @param timeToFirstFixMilliSeconds
-   */
-  public void logTimeToFirstFixMilliSecs(int timeToFirstFixMilliSeconds) {
-    timeToFirstFixSecStatistics.addItem((double) (timeToFirstFixMilliSeconds/1000));
-    return;
-  }
-
-  /**
-   * Logs position accuracy
-   *
-   * @param positionAccuracyMeters
-   */
-  public void logPositionAccuracyMeters(float positionAccuracyMeters) {
-    positionAccuracyMeterStatistics.addItem((double) positionAccuracyMeters);
-    return;
-  }
-
-  /*
-  * Logs CN0 when at least 4 SVs are available
-  *
-  */
-  public void logCn0(float[] cn0s, int numSv) {
-    if (numSv == 0 || cn0s == null || cn0s.length == 0 || cn0s.length < numSv) {
-      if (numSv == 0) {
-         mGnssPowerMetrics.reportSignalQuality(null, 0);
-      }
-      return;
+    /**
+     * Logs time to first fix
+     */
+    public void logTimeToFirstFixMilliSecs(int timeToFirstFixMilliSeconds) {
+        mTimeToFirstFixSecStatistics.addItem((double) (timeToFirstFixMilliSeconds / 1000));
     }
-    float[] cn0Array = Arrays.copyOf(cn0s, numSv);
-    Arrays.sort(cn0Array);
-    mGnssPowerMetrics.reportSignalQuality(cn0Array, numSv);
-    if (numSv < 4) {
-      return;
-    }
-    if (cn0Array[numSv - 4] > 0.0) {
-      double top4AvgCn0 = 0.0;
-      for (int i = numSv - 4; i < numSv; i++) {
-        top4AvgCn0 += (double) cn0Array[i];
-      }
-      top4AvgCn0 /= 4;
-      topFourAverageCn0Statistics.addItem(top4AvgCn0);
-    }
-    return;
-  }
 
+    /**
+     * Logs position accuracy
+     */
+    public void logPositionAccuracyMeters(float positionAccuracyMeters) {
+        mPositionAccuracyMeterStatistics.addItem((double) positionAccuracyMeters);
+    }
+
+    /**
+     * Logs CN0 when at least 4 SVs are available
+     */
+    public void logCn0(float[] cn0s, int numSv) {
+        if (numSv == 0 || cn0s == null || cn0s.length == 0 || cn0s.length < numSv) {
+            if (numSv == 0) {
+                mGnssPowerMetrics.reportSignalQuality(null, 0);
+            }
+            return;
+        }
+        float[] cn0Array = Arrays.copyOf(cn0s, numSv);
+        Arrays.sort(cn0Array);
+        mGnssPowerMetrics.reportSignalQuality(cn0Array, numSv);
+        if (numSv < 4) {
+            return;
+        }
+        if (cn0Array[numSv - 4] > 0.0) {
+            double top4AvgCn0 = 0.0;
+            for (int i = numSv - 4; i < numSv; i++) {
+                top4AvgCn0 += (double) cn0Array[i];
+            }
+            top4AvgCn0 /= 4;
+            mTopFourAverageCn0Statistics.addItem(top4AvgCn0);
+        }
+    }
 
     /**
      * Logs that a constellation type has been observed.
@@ -173,82 +162,82 @@
         mConstellationTypes[constellationType] = true;
     }
 
-  /**
-   * Dumps GNSS metrics as a proto string
-   * @return
-   */
-  public String dumpGnssMetricsAsProtoString() {
-    GnssLog msg = new GnssLog();
-    if (locationFailureStatistics.getCount() > 0) {
-      msg.numLocationReportProcessed = locationFailureStatistics.getCount();
-      msg.percentageLocationFailure = (int) (100.0 * locationFailureStatistics.getMean());
+    /**
+     * Dumps GNSS metrics as a proto string
+     */
+    public String dumpGnssMetricsAsProtoString() {
+        GnssLog msg = new GnssLog();
+        if (mLocationFailureStatistics.getCount() > 0) {
+            msg.numLocationReportProcessed = mLocationFailureStatistics.getCount();
+            msg.percentageLocationFailure = (int) (100.0 * mLocationFailureStatistics.getMean());
+        }
+        if (mTimeToFirstFixSecStatistics.getCount() > 0) {
+            msg.numTimeToFirstFixProcessed = mTimeToFirstFixSecStatistics.getCount();
+            msg.meanTimeToFirstFixSecs = (int) mTimeToFirstFixSecStatistics.getMean();
+            msg.standardDeviationTimeToFirstFixSecs =
+                    (int) mTimeToFirstFixSecStatistics.getStandardDeviation();
+        }
+        if (mPositionAccuracyMeterStatistics.getCount() > 0) {
+            msg.numPositionAccuracyProcessed = mPositionAccuracyMeterStatistics.getCount();
+            msg.meanPositionAccuracyMeters = (int) mPositionAccuracyMeterStatistics.getMean();
+            msg.standardDeviationPositionAccuracyMeters =
+                    (int) mPositionAccuracyMeterStatistics.getStandardDeviation();
+        }
+        if (mTopFourAverageCn0Statistics.getCount() > 0) {
+            msg.numTopFourAverageCn0Processed = mTopFourAverageCn0Statistics.getCount();
+            msg.meanTopFourAverageCn0DbHz = mTopFourAverageCn0Statistics.getMean();
+            msg.standardDeviationTopFourAverageCn0DbHz =
+                    mTopFourAverageCn0Statistics.getStandardDeviation();
+        }
+        msg.powerMetrics = mGnssPowerMetrics.buildProto();
+        msg.hardwareRevision = SystemProperties.get("ro.boot.revision", "");
+        String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT);
+        reset();
+        return s;
     }
-    if (timeToFirstFixSecStatistics.getCount() > 0) {
-      msg.numTimeToFirstFixProcessed = timeToFirstFixSecStatistics.getCount();
-      msg.meanTimeToFirstFixSecs = (int) timeToFirstFixSecStatistics.getMean();
-      msg.standardDeviationTimeToFirstFixSecs
-          = (int) timeToFirstFixSecStatistics.getStandardDeviation();
-    }
-    if (positionAccuracyMeterStatistics.getCount() > 0) {
-      msg.numPositionAccuracyProcessed = positionAccuracyMeterStatistics.getCount();
-      msg.meanPositionAccuracyMeters = (int) positionAccuracyMeterStatistics.getMean();
-      msg.standardDeviationPositionAccuracyMeters
-          = (int) positionAccuracyMeterStatistics.getStandardDeviation();
-    }
-    if (topFourAverageCn0Statistics.getCount() > 0) {
-      msg.numTopFourAverageCn0Processed = topFourAverageCn0Statistics.getCount();
-      msg.meanTopFourAverageCn0DbHz = topFourAverageCn0Statistics.getMean();
-      msg.standardDeviationTopFourAverageCn0DbHz
-          = topFourAverageCn0Statistics.getStandardDeviation();
-    }
-    msg.powerMetrics = mGnssPowerMetrics.buildProto();
-    msg.hardwareRevision = SystemProperties.get("ro.boot.revision", "");
-    String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT);
-    reset();
-    return s;
-  }
 
-  /**
-   * Dumps GNSS Metrics as text
-   *
-   * @return GNSS Metrics
-   */
-  public String dumpGnssMetricsAsText() {
-    StringBuilder s = new StringBuilder();
-    s.append("GNSS_KPI_START").append('\n');
-    s.append("  KPI logging start time: ").append(logStartInElapsedRealTime).append("\n");
-    s.append("  KPI logging end time: ");
-    TimeUtils.formatDuration(SystemClock.elapsedRealtimeNanos() / 1000000L, s);
-    s.append("\n");
-    s.append("  Number of location reports: ").append(
-        locationFailureStatistics.getCount()).append("\n");
-    if (locationFailureStatistics.getCount() > 0) {
-      s.append("  Percentage location failure: ").append(
-          100.0 * locationFailureStatistics.getMean()).append("\n");
-    }
-    s.append("  Number of TTFF reports: ").append(
-        timeToFirstFixSecStatistics.getCount()).append("\n");
-    if (timeToFirstFixSecStatistics.getCount() > 0) {
-      s.append("  TTFF mean (sec): ").append(timeToFirstFixSecStatistics.getMean()).append("\n");
-      s.append("  TTFF standard deviation (sec): ").append(
-          timeToFirstFixSecStatistics.getStandardDeviation()).append("\n");
-    }
-    s.append("  Number of position accuracy reports: ").append(
-        positionAccuracyMeterStatistics.getCount()).append("\n");
-    if (positionAccuracyMeterStatistics.getCount() > 0) {
-      s.append("  Position accuracy mean (m): ").append(
-          positionAccuracyMeterStatistics.getMean()).append("\n");
-      s.append("  Position accuracy standard deviation (m): ").append(
-          positionAccuracyMeterStatistics.getStandardDeviation()).append("\n");
-    }
-    s.append("  Number of CN0 reports: ").append(
-        topFourAverageCn0Statistics.getCount()).append("\n");
-    if (topFourAverageCn0Statistics.getCount() > 0) {
-      s.append("  Top 4 Avg CN0 mean (dB-Hz): ").append(
-          topFourAverageCn0Statistics.getMean()).append("\n");
-      s.append("  Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
-          topFourAverageCn0Statistics.getStandardDeviation()).append("\n");
-    }
+    /**
+     * Dumps GNSS Metrics as text
+     *
+     * @return GNSS Metrics
+     */
+    public String dumpGnssMetricsAsText() {
+        StringBuilder s = new StringBuilder();
+        s.append("GNSS_KPI_START").append('\n');
+        s.append("  KPI logging start time: ").append(mLogStartInElapsedRealTime).append("\n");
+        s.append("  KPI logging end time: ");
+        TimeUtils.formatDuration(SystemClock.elapsedRealtimeNanos() / 1000000L, s);
+        s.append("\n");
+        s.append("  Number of location reports: ").append(
+                mLocationFailureStatistics.getCount()).append("\n");
+        if (mLocationFailureStatistics.getCount() > 0) {
+            s.append("  Percentage location failure: ").append(
+                    100.0 * mLocationFailureStatistics.getMean()).append("\n");
+        }
+        s.append("  Number of TTFF reports: ").append(
+                mTimeToFirstFixSecStatistics.getCount()).append("\n");
+        if (mTimeToFirstFixSecStatistics.getCount() > 0) {
+            s.append("  TTFF mean (sec): ").append(mTimeToFirstFixSecStatistics.getMean()).append(
+                    "\n");
+            s.append("  TTFF standard deviation (sec): ").append(
+                    mTimeToFirstFixSecStatistics.getStandardDeviation()).append("\n");
+        }
+        s.append("  Number of position accuracy reports: ").append(
+                mPositionAccuracyMeterStatistics.getCount()).append("\n");
+        if (mPositionAccuracyMeterStatistics.getCount() > 0) {
+            s.append("  Position accuracy mean (m): ").append(
+                    mPositionAccuracyMeterStatistics.getMean()).append("\n");
+            s.append("  Position accuracy standard deviation (m): ").append(
+                    mPositionAccuracyMeterStatistics.getStandardDeviation()).append("\n");
+        }
+        s.append("  Number of CN0 reports: ").append(
+                mTopFourAverageCn0Statistics.getCount()).append("\n");
+        if (mTopFourAverageCn0Statistics.getCount() > 0) {
+            s.append("  Top 4 Avg CN0 mean (dB-Hz): ").append(
+                    mTopFourAverageCn0Statistics.getMean()).append("\n");
+            s.append("  Top 4 Avg CN0 standard deviation (dB-Hz): ").append(
+                    mTopFourAverageCn0Statistics.getStandardDeviation()).append("\n");
+        }
         s.append("  Used-in-fix constellation types: ");
         for (int i = 0; i < mConstellationTypes.length; i++) {
             if (mConstellationTypes[i]) {
@@ -256,199 +245,193 @@
             }
         }
         s.append("\n");
-    s.append("GNSS_KPI_END").append("\n");
-    GpsBatteryStats stats = mGnssPowerMetrics.getGpsBatteryStats();
-    if (stats != null) {
-      s.append("Power Metrics").append("\n");
-      s.append("  Time on battery (min): "
-          + stats.getLoggingDurationMs() / ((double) DateUtils.MINUTE_IN_MILLIS)).append("\n");
-      long[] t = stats.getTimeInGpsSignalQualityLevel();
-      if (t != null && t.length == NUM_GPS_SIGNAL_QUALITY_LEVELS) {
-        s.append("  Amount of time (while on battery) Top 4 Avg CN0 > " +
-            Double.toString(GnssPowerMetrics.POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ) +
-            " dB-Hz (min): ").append(t[1] / ((double) DateUtils.MINUTE_IN_MILLIS)).append("\n");
-        s.append("  Amount of time (while on battery) Top 4 Avg CN0 <= " +
-            Double.toString(GnssPowerMetrics.POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ) +
-            " dB-Hz (min): ").append(t[0] / ((double) DateUtils.MINUTE_IN_MILLIS)).append("\n");
-      }
-      s.append("  Energy consumed while on battery (mAh): ").append(
-          stats.getEnergyConsumedMaMs() / ((double) DateUtils.HOUR_IN_MILLIS)).append("\n");
-    }
-    s.append("Hardware Version: " + SystemProperties.get("ro.boot.revision", "")).append("\n");
-    return s.toString();
-  }
-
-   /** Class for storing statistics */
-  private class Statistics {
-
-    /** Resets statistics */
-    public void reset() {
-      count = 0;
-      sum = 0.0;
-      sumSquare = 0.0;
+        s.append("GNSS_KPI_END").append("\n");
+        GpsBatteryStats stats = mGnssPowerMetrics.getGpsBatteryStats();
+        if (stats != null) {
+            s.append("Power Metrics").append("\n");
+            s.append("  Time on battery (min): ").append(
+                    stats.getLoggingDurationMs() / ((double) DateUtils.MINUTE_IN_MILLIS)).append(
+                    "\n");
+            long[] t = stats.getTimeInGpsSignalQualityLevel();
+            if (t != null && t.length == NUM_GPS_SIGNAL_QUALITY_LEVELS) {
+                s.append("  Amount of time (while on battery) Top 4 Avg CN0 > "
+                        + GnssPowerMetrics.POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ
+                        + " dB-Hz (min): ").append(
+                        t[1] / ((double) DateUtils.MINUTE_IN_MILLIS)).append("\n");
+                s.append("  Amount of time (while on battery) Top 4 Avg CN0 <= "
+                        + GnssPowerMetrics.POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ
+                        + " dB-Hz (min): ").append(
+                        t[0] / ((double) DateUtils.MINUTE_IN_MILLIS)).append("\n");
+            }
+            s.append("  Energy consumed while on battery (mAh): ").append(
+                    stats.getEnergyConsumedMaMs() / ((double) DateUtils.HOUR_IN_MILLIS)).append(
+                    "\n");
+        }
+        s.append("Hardware Version: ").append(SystemProperties.get("ro.boot.revision", "")).append(
+                "\n");
+        return s.toString();
     }
 
-    /** Adds an item */
-    public void addItem(double item) {
-      count++;
-      sum += item;
-      sumSquare += item * item;
-    }
-
-    /** Returns number of items added */
-    public int getCount() {
-      return count;
-    }
-
-    /** Returns mean */
-    public double getMean() {
-      return sum/count;
-    }
-
-    /** Returns standard deviation */
-    public double getStandardDeviation() {
-      double m = sum/count;
-      m = m * m;
-      double v = sumSquare/count;
-      if (v > m) {
-        return Math.sqrt(v - m);
-      }
-      return 0;
-    }
-
-    private int count;
-    private double sum;
-    private double sumSquare;
-  }
-
-  /** Location failure statistics */
-  private Statistics locationFailureStatistics;
-
-  /** Time to first fix statistics */
-  private Statistics timeToFirstFixSecStatistics;
-
-  /** Position accuracy statistics */
-  private Statistics positionAccuracyMeterStatistics;
-
-  /** Top 4 average CN0 statistics */
-  private Statistics topFourAverageCn0Statistics;
-
-  /**
-   * Resets GNSS metrics
-   */
-  private void reset() {
-    StringBuilder s = new StringBuilder();
-    TimeUtils.formatDuration(SystemClock.elapsedRealtimeNanos() / 1000000L, s);
-    logStartInElapsedRealTime = s.toString();
-    locationFailureStatistics.reset();
-    timeToFirstFixSecStatistics.reset();
-    positionAccuracyMeterStatistics.reset();
-    topFourAverageCn0Statistics.reset();
+    private void reset() {
+        StringBuilder s = new StringBuilder();
+        TimeUtils.formatDuration(SystemClock.elapsedRealtimeNanos() / 1000000L, s);
+        mLogStartInElapsedRealTime = s.toString();
+        mLocationFailureStatistics.reset();
+        mTimeToFirstFixSecStatistics.reset();
+        mPositionAccuracyMeterStatistics.reset();
+        mTopFourAverageCn0Statistics.reset();
         resetConstellationTypes();
-    return;
-  }
+    }
 
     /** Resets {@link #mConstellationTypes} as an all-false boolean array. */
     public void resetConstellationTypes() {
         mConstellationTypes = new boolean[GnssStatus.CONSTELLATION_COUNT];
     }
 
-  /* Class for handling GNSS power related metrics */
-  private class GnssPowerMetrics {
+    /** Class for storing statistics */
+    private class Statistics {
 
-    /* Threshold for Top Four Average CN0 below which GNSS signal quality is declared poor */
-    public static final double POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ = 20.0;
+        private int mCount;
+        private double mSum;
+        private double mSumSquare;
 
-    /* Minimum change in Top Four Average CN0 needed to trigger a report */
-    private static final double REPORTING_THRESHOLD_DB_HZ = 1.0;
-
-    /* BatteryStats API */
-    private final IBatteryStats mBatteryStats;
-
-    /* Last reported Top Four Average CN0 */
-    private double mLastAverageCn0;
-
-    /* Last reported signal quality bin (based on Top Four Average CN0) */
-    private int mLastSignalLevel;
-
-    public GnssPowerMetrics(IBatteryStats stats) {
-      mBatteryStats = stats;
-      // Used to initialize the variable to a very small value (unachievable in practice) so that
-      // the first CNO report will trigger an update to BatteryStats
-      mLastAverageCn0 = -100.0;
-      mLastSignalLevel = GPS_SIGNAL_QUALITY_UNKNOWN;
-    }
-
-    /**
-     * Builds power metrics proto buf. This is included in the gnss proto buf.
-     * @return PowerMetrics
-     */
-    public PowerMetrics buildProto() {
-      PowerMetrics p = new PowerMetrics();
-      GpsBatteryStats stats = mGnssPowerMetrics.getGpsBatteryStats();
-      if (stats != null) {
-        p.loggingDurationMs = stats.getLoggingDurationMs();
-        p.energyConsumedMah = stats.getEnergyConsumedMaMs() / ((double) DateUtils.HOUR_IN_MILLIS);
-        long[] t = stats.getTimeInGpsSignalQualityLevel();
-        p.timeInSignalQualityLevelMs = new long[t.length];
-        for (int i = 0; i < t.length; i++) {
-          p.timeInSignalQualityLevelMs[i] = t[i];
+        /** Resets statistics */
+        public void reset() {
+            mCount = 0;
+            mSum = 0.0;
+            mSumSquare = 0.0;
         }
-      }
-      return p;
-    }
 
-    /**
-     * Returns the GPS power stats
-     * @return GpsBatteryStats
-     */
-    public GpsBatteryStats getGpsBatteryStats() {
-      try {
-        return mBatteryStats.getGpsBatteryStats();
-      } catch (Exception e) {
-        Log.w(TAG, "Exception", e);
-        return null;
-      }
-    }
-
-    /**
-     * Reports signal quality to BatteryStats. Signal quality is based on Top four average CN0. If
-     * the number of SVs seen is less than 4, then signal quality is the average CN0.
-     * Changes are reported only if the average CN0 changes by more than REPORTING_THRESHOLD_DB_HZ.
-     */
-    public void reportSignalQuality(float[] ascendingCN0Array, int numSv) {
-      double avgCn0 = 0.0;
-      if (numSv > 0) {
-        for (int i = Math.max(0, numSv - 4); i < numSv; i++) {
-          avgCn0 += (double) ascendingCN0Array[i];
+        /** Adds an item */
+        public void addItem(double item) {
+            mCount++;
+            mSum += item;
+            mSumSquare += item * item;
         }
-        avgCn0 /= Math.min(numSv, 4);
-      }
-      if (Math.abs(avgCn0 - mLastAverageCn0) < REPORTING_THRESHOLD_DB_HZ) {
-        return;
-      }
-      int signalLevel = getSignalLevel(avgCn0);
-      if (signalLevel != mLastSignalLevel) {
-        StatsLog.write(StatsLog.GPS_SIGNAL_QUALITY_CHANGED, signalLevel);
-        mLastSignalLevel = signalLevel;
-      }
-      try {
-        mBatteryStats.noteGpsSignalQuality(signalLevel);
-        mLastAverageCn0 = avgCn0;
-      } catch (Exception e) {
-        Log.w(TAG, "Exception", e);
-      }
-      return;
+
+        /** Returns number of items added */
+        public int getCount() {
+            return mCount;
+        }
+
+        /** Returns mean */
+        public double getMean() {
+            return mSum / mCount;
+        }
+
+        /** Returns standard deviation */
+        public double getStandardDeviation() {
+            double m = mSum / mCount;
+            m = m * m;
+            double v = mSumSquare / mCount;
+            if (v > m) {
+                return Math.sqrt(v - m);
+            }
+            return 0;
+        }
     }
 
-    /**
-     * Obtains signal level based on CN0
-     */
-    private int getSignalLevel(double cn0) {
-      if (cn0 > POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ) {
-        return GnssMetrics.GPS_SIGNAL_QUALITY_GOOD;
-      }
-      return GnssMetrics.GPS_SIGNAL_QUALITY_POOR;
+    /* Class for handling GNSS power related metrics */
+    private class GnssPowerMetrics {
+
+        /* Threshold for Top Four Average CN0 below which GNSS signal quality is declared poor */
+        public static final double POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ = 20.0;
+
+        /* Minimum change in Top Four Average CN0 needed to trigger a report */
+        private static final double REPORTING_THRESHOLD_DB_HZ = 1.0;
+
+        /* BatteryStats API */
+        private final IBatteryStats mBatteryStats;
+
+        /* Last reported Top Four Average CN0 */
+        private double mLastAverageCn0;
+
+        /* Last reported signal quality bin (based on Top Four Average CN0) */
+        private int mLastSignalLevel;
+
+        private GnssPowerMetrics(IBatteryStats stats) {
+            mBatteryStats = stats;
+            // Used to initialize the variable to a very small value (unachievable in practice)
+          // so that
+            // the first CNO report will trigger an update to BatteryStats
+            mLastAverageCn0 = -100.0;
+            mLastSignalLevel = GPS_SIGNAL_QUALITY_UNKNOWN;
+        }
+
+        /**
+         * Builds power metrics proto buf. This is included in the gnss proto buf.
+         *
+         * @return PowerMetrics
+         */
+        public PowerMetrics buildProto() {
+            PowerMetrics p = new PowerMetrics();
+            GpsBatteryStats stats = mGnssPowerMetrics.getGpsBatteryStats();
+            if (stats != null) {
+                p.loggingDurationMs = stats.getLoggingDurationMs();
+                p.energyConsumedMah =
+                        stats.getEnergyConsumedMaMs() / ((double) DateUtils.HOUR_IN_MILLIS);
+                long[] t = stats.getTimeInGpsSignalQualityLevel();
+                p.timeInSignalQualityLevelMs = new long[t.length];
+                for (int i = 0; i < t.length; i++) {
+                    p.timeInSignalQualityLevelMs[i] = t[i];
+                }
+            }
+            return p;
+        }
+
+        /**
+         * Returns the GPS power stats
+         *
+         * @return GpsBatteryStats
+         */
+        public GpsBatteryStats getGpsBatteryStats() {
+            try {
+                return mBatteryStats.getGpsBatteryStats();
+            } catch (Exception e) {
+                Log.w(TAG, "Exception", e);
+                return null;
+            }
+        }
+
+        /**
+         * Reports signal quality to BatteryStats. Signal quality is based on Top four average CN0.
+         * If
+         * the number of SVs seen is less than 4, then signal quality is the average CN0.
+         * Changes are reported only if the average CN0 changes by more than
+         * REPORTING_THRESHOLD_DB_HZ.
+         */
+        public void reportSignalQuality(float[] ascendingCN0Array, int numSv) {
+            double avgCn0 = 0.0;
+            if (numSv > 0) {
+                for (int i = Math.max(0, numSv - 4); i < numSv; i++) {
+                    avgCn0 += (double) ascendingCN0Array[i];
+                }
+                avgCn0 /= Math.min(numSv, 4);
+            }
+            if (Math.abs(avgCn0 - mLastAverageCn0) < REPORTING_THRESHOLD_DB_HZ) {
+                return;
+            }
+            int signalLevel = getSignalLevel(avgCn0);
+            if (signalLevel != mLastSignalLevel) {
+                StatsLog.write(StatsLog.GPS_SIGNAL_QUALITY_CHANGED, signalLevel);
+                mLastSignalLevel = signalLevel;
+            }
+            try {
+                mBatteryStats.noteGpsSignalQuality(signalLevel);
+                mLastAverageCn0 = avgCn0;
+            } catch (Exception e) {
+                Log.w(TAG, "Exception", e);
+            }
+        }
+
+        /**
+         * Obtains signal level based on CN0
+         */
+        private int getSignalLevel(double cn0) {
+            if (cn0 > POOR_TOP_FOUR_AVG_CN0_THRESHOLD_DB_HZ) {
+                return GnssMetrics.GPS_SIGNAL_QUALITY_GOOD;
+            }
+            return GnssMetrics.GPS_SIGNAL_QUALITY_POOR;
+        }
     }
-  }
 }
diff --git a/media/Android.bp b/media/Android.bp
index 70dacb2..29064ad 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -27,12 +27,14 @@
     installable: true,
 
     // Make sure that the implementaion only relies on SDK or system APIs.
-    no_framework_libs: true,
+    sdk_version: "core_platform",
     libs: [
         // The order matters. android_system_* library should come later.
         "framework_media_annotation",
         "android_system_stubs_current",
     ],
+
+    plugins: ["java_api_finder"],
 }
 
 filegroup {
diff --git a/media/apex/java/android/media/Media2Utils.java b/media/apex/java/android/media/Media2Utils.java
index 5fd6191..a87e967 100644
--- a/media/apex/java/android/media/Media2Utils.java
+++ b/media/apex/java/android/media/Media2Utils.java
@@ -75,5 +75,4 @@
         Log.v(TAG, "storeCookies: cookieHandler: " + cookieHandler + " Cookies: " + cookies);
 
     }
-
 }
diff --git a/media/apex/java/android/media/MediaController2.java b/media/apex/java/android/media/MediaController2.java
index 9848f1a..c3dd3fe 100644
--- a/media/apex/java/android/media/MediaController2.java
+++ b/media/apex/java/android/media/MediaController2.java
@@ -46,14 +46,14 @@
 import java.util.concurrent.Executor;
 
 /**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ *
  * Allows an app to interact with an active {@link MediaSession2} or a
  * {@link MediaSession2Service} which would provide {@link MediaSession2}. Media buttons and other
  * commands can be sent to the session.
- * <p>
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
- * for consistent behavior across all devices.
  */
 public class MediaController2 implements AutoCloseable {
     static final String TAG = "MediaController2";
@@ -100,7 +100,7 @@
      * @param callback controller callback to receive changes in.
      */
     MediaController2(@NonNull Context context, @NonNull Session2Token token,
-            @Nullable Bundle connectionHints, @NonNull Executor executor,
+            @NonNull Bundle connectionHints, @NonNull Executor executor,
             @NonNull ControllerCallback callback) {
         if (context == null) {
             throw new IllegalArgumentException("context shouldn't be null");
@@ -259,7 +259,16 @@
         Session2CommandGroup allowedCommands =
                 connectionResult.getParcelable(KEY_ALLOWED_COMMANDS);
         boolean playbackActive = connectionResult.getBoolean(KEY_PLAYBACK_ACTIVE);
+
         Bundle tokenExtras = connectionResult.getBundle(KEY_TOKEN_EXTRAS);
+        if (tokenExtras == null) {
+            Log.w(TAG, "extras shouldn't be null.");
+            tokenExtras = Bundle.EMPTY;
+        } else if (MediaSession2.hasCustomParcelable(tokenExtras)) {
+            Log.w(TAG, "extras contain custom parcelable. Ignoring.");
+            tokenExtras = Bundle.EMPTY;
+        }
+
         if (DEBUG) {
             Log.d(TAG, "notifyConnected sessionBinder=" + sessionBinder
                     + ", allowedCommands=" + allowedCommands);
@@ -343,7 +352,7 @@
         }
     }
 
-    private Bundle createConnectionRequest(@Nullable Bundle connectionHints) {
+    private Bundle createConnectionRequest(@NonNull Bundle connectionHints) {
         Bundle connectionRequest = new Bundle();
         connectionRequest.putString(KEY_PACKAGE_NAME, mContext.getPackageName());
         connectionRequest.putInt(KEY_PID, Process.myPid());
@@ -351,7 +360,7 @@
         return connectionRequest;
     }
 
-    private boolean requestConnectToSession(@Nullable Bundle connectionHints) {
+    private boolean requestConnectToSession(@NonNull Bundle connectionHints) {
         Session2Link sessionBinder = mSessionToken.getSessionLink();
         Bundle connectionRequest = createConnectionRequest(connectionHints);
         try {
@@ -396,6 +405,11 @@
     }
 
     /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
      * Builder for {@link MediaController2}.
      * <p>
      * Any incoming event from the {@link MediaSession2} will be handled on the callback
@@ -430,6 +444,9 @@
          * <p>
          * {@code connectionHints} is a session-specific argument to send to the session when
          * connecting. The contents of this bundle may affect the connection result.
+         * <p>
+         * An {@link IllegalArgumentException} will be thrown if the bundle contains any
+         * non-framework Parcelable objects.
          *
          * @param connectionHints a bundle which contains the connection hints
          * @return The Builder to allow chaining
@@ -439,6 +456,10 @@
             if (connectionHints == null) {
                 throw new IllegalArgumentException("connectionHints shouldn't be null");
             }
+            if (MediaSession2.hasCustomParcelable(connectionHints)) {
+                throw new IllegalArgumentException("connectionHints shouldn't contain any custom "
+                        + "parcelables");
+            }
             mConnectionHints = new Bundle(connectionHints);
             return this;
         }
@@ -477,15 +498,21 @@
             if (mCallback == null) {
                 mCallback = new ControllerCallback() {};
             }
+            if (mConnectionHints == null) {
+                mConnectionHints = Bundle.EMPTY;
+            }
             return new MediaController2(
                     mContext, mToken, mConnectionHints, mCallbackExecutor, mCallback);
         }
     }
 
     /**
-     * Interface for listening to change in activeness of the {@link MediaSession2}.
-     * <p>
      * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Interface for listening to change in activeness of the {@link MediaSession2}.
      */
     public abstract static class ControllerCallback {
         /**
diff --git a/media/apex/java/android/media/MediaSession2.java b/media/apex/java/android/media/MediaSession2.java
index 0819118..081e76a 100644
--- a/media/apex/java/android/media/MediaSession2.java
+++ b/media/apex/java/android/media/MediaSession2.java
@@ -34,8 +34,10 @@
 import android.content.Intent;
 import android.media.session.MediaSessionManager;
 import android.media.session.MediaSessionManager.RemoteUserInfo;
+import android.os.BadParcelableException;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Parcel;
 import android.os.Process;
 import android.os.ResultReceiver;
 import android.util.ArrayMap;
@@ -50,13 +52,13 @@
 import java.util.concurrent.Executor;
 
 /**
- * Allows a media app to expose its transport controls and playback information in a process to
- * other processes including the Android framework and other apps.
- * <p>
  * This API is not generally intended for third party application developers.
  * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
- * for consistent behavior across all devices.
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * Allows a media app to expose its transport controls and playback information in a process to
+ * other processes including the Android framework and other apps.
  */
 public class MediaSession2 implements AutoCloseable {
     static final String TAG = "MediaSession2";
@@ -97,7 +99,7 @@
 
     MediaSession2(@NonNull Context context, @NonNull String id, PendingIntent sessionActivity,
             @NonNull Executor callbackExecutor, @NonNull SessionCallback callback,
-            Bundle tokenExtras) {
+            @NonNull Bundle tokenExtras) {
         synchronized (MediaSession2.class) {
             if (SESSION_ID_LIST.contains(id)) {
                 throw new IllegalStateException("Session ID must be unique. ID=" + id);
@@ -276,6 +278,35 @@
         return controllers;
     }
 
+    /**
+     * Returns whether the given bundle includes non-framework Parcelables.
+     */
+    static boolean hasCustomParcelable(@Nullable Bundle bundle) {
+        if (bundle == null) {
+            return false;
+        }
+
+        // Try writing the bundle to parcel, and read it with framework classloader.
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            parcel.writeBundle(bundle);
+            parcel.setDataPosition(0);
+            Bundle out = parcel.readBundle(null);
+
+            // Calling Bundle#size() will trigger Bundle#unparcel().
+            out.size();
+        } catch (BadParcelableException e) {
+            Log.d(TAG, "Custom parcelable in bundle.", e);
+            return true;
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+        return false;
+    }
+
     boolean isClosed() {
         synchronized (mLock) {
             return mClosed;
@@ -309,11 +340,21 @@
         String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);
 
         RemoteUserInfo remoteUserInfo = new RemoteUserInfo(callingPkg, callingPid, callingUid);
+
+        Bundle connectionHints = connectionRequest.getBundle(KEY_CONNECTION_HINTS);
+        if (connectionHints == null) {
+            Log.w(TAG, "connectionHints shouldn't be null.");
+            connectionHints = Bundle.EMPTY;
+        } else if (hasCustomParcelable(connectionHints)) {
+            Log.w(TAG, "connectionHints contain custom parcelable. Ignoring.");
+            connectionHints = Bundle.EMPTY;
+        }
+
         final ControllerInfo controllerInfo = new ControllerInfo(
                 remoteUserInfo,
                 mSessionManager.isTrustedForMediaControl(remoteUserInfo),
                 controller,
-                connectionRequest.getBundle(KEY_CONNECTION_HINTS));
+                connectionHints);
         mCallbackExecutor.execute(() -> {
             boolean connected = false;
             try {
@@ -440,6 +481,11 @@
     }
 
     /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
      * Builder for {@link MediaSession2}.
      * <p>
      * Any incoming event from the {@link MediaController2} will be handled on the callback
@@ -516,7 +562,8 @@
 
         /**
          * Set extras for the session token. If null or not set, {@link Session2Token#getExtras()}
-         * will return {@link Bundle#EMPTY}.
+         * will return an empty {@link Bundle}. An {@link IllegalArgumentException} will be thrown
+         * if the bundle contains any non-framework Parcelable objects.
          *
          * @return The Builder to allow chaining
          * @see Session2Token#getExtras()
@@ -526,7 +573,11 @@
             if (extras == null) {
                 throw new NullPointerException("extras shouldn't be null");
             }
-            mExtras = extras;
+            if (hasCustomParcelable(extras)) {
+                throw new IllegalArgumentException(
+                        "extras shouldn't contain any custom parcelables");
+            }
+            mExtras = new Bundle(extras);
             return this;
         }
 
@@ -548,6 +599,9 @@
             if (mId == null) {
                 mId = "";
             }
+            if (mExtras == null) {
+                mExtras = Bundle.EMPTY;
+            }
             MediaSession2 session2 = new MediaSession2(mContext, mId, mSessionActivity,
                     mCallbackExecutor, mCallback, mExtras);
 
@@ -567,9 +621,12 @@
     }
 
     /**
-     * Information of a controller.
-     * <p>
      * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Information of a controller.
      */
     public static final class ControllerInfo {
         private final RemoteUserInfo mRemoteUserInfo;
@@ -596,7 +653,7 @@
          *                        connection result.
          */
         ControllerInfo(@NonNull RemoteUserInfo remoteUserInfo, boolean trusted,
-                @Nullable Controller2Link controllerBinder, @Nullable Bundle connectionHints) {
+                @Nullable Controller2Link controllerBinder, @NonNull Bundle connectionHints) {
             mRemoteUserInfo = remoteUserInfo;
             mIsTrusted = trusted;
             mControllerBinder = controllerBinder;
@@ -629,11 +686,11 @@
         }
 
         /**
-         * @return connection hints sent from controller, or {@link Bundle#EMPTY} if none.
+         * @return connection hints sent from controller.
          */
         @NonNull
         public Bundle getConnectionHints() {
-            return mConnectionHints == null ? Bundle.EMPTY : new Bundle(mConnectionHints);
+            return new Bundle(mConnectionHints);
         }
 
         /**
@@ -758,9 +815,12 @@
     }
 
     /**
-     * Callback to be called for all incoming commands from {@link MediaController2}s.
-     * <p>
      * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Callback to be called for all incoming commands from {@link MediaController2}s.
      */
     public abstract static class SessionCallback {
         /**
diff --git a/media/apex/java/android/media/MediaSession2Service.java b/media/apex/java/android/media/MediaSession2Service.java
index b8bf384..f6fd509 100644
--- a/media/apex/java/android/media/MediaSession2Service.java
+++ b/media/apex/java/android/media/MediaSession2Service.java
@@ -44,12 +44,12 @@
 import java.util.Map;
 
 /**
- * Service containing {@link MediaSession2}.
- * <p>
  * This API is not generally intended for third party application developers.
  * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
- * for consistent behavior across all devices.
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * Service containing {@link MediaSession2}.
  */
 public abstract class MediaSession2Service extends Service {
     /**
@@ -287,6 +287,11 @@
     }
 
     /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
      * Returned by {@link #onUpdateNotification(MediaSession2)} for making session service
      * foreground service to keep playback running in the background. It's highly recommended to
      * show media style notification here.
@@ -378,12 +383,22 @@
                                 callingPkg,
                                 pid == 0 ? connectionRequest.getInt(KEY_PID) : pid,
                                 uid);
+
+                        Bundle connectionHints = connectionRequest.getBundle(KEY_CONNECTION_HINTS);
+                        if (connectionHints == null) {
+                            Log.w(TAG, "connectionHints shouldn't be null.");
+                            connectionHints = Bundle.EMPTY;
+                        } else if (MediaSession2.hasCustomParcelable(connectionHints)) {
+                            Log.w(TAG, "connectionHints contain custom parcelable. Ignoring.");
+                            connectionHints = Bundle.EMPTY;
+                        }
+
                         final ControllerInfo controllerInfo = new ControllerInfo(
                                 remoteUserInfo,
                                 service.getMediaSessionManager()
                                         .isTrustedForMediaControl(remoteUserInfo),
                                 caller,
-                                connectionRequest.getBundle(KEY_CONNECTION_HINTS));
+                                connectionHints);
 
                         if (DEBUG) {
                             Log.d(TAG, "Handling incoming connection request from the"
diff --git a/media/apex/java/android/media/Session2Command.java b/media/apex/java/android/media/Session2Command.java
index 7c752e1..26f4568 100644
--- a/media/apex/java/android/media/Session2Command.java
+++ b/media/apex/java/android/media/Session2Command.java
@@ -26,6 +26,11 @@
 import java.util.Objects;
 
 /**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
  * Define a command that a {@link MediaController2} can send to a {@link MediaSession2}.
  * <p>
  * If {@link #getCommandCode()} isn't {@link #COMMAND_CODE_CUSTOM}), it's predefined command.
@@ -35,11 +40,6 @@
  * Refer to the
  * <a href="{@docRoot}reference/androidx/media2/SessionCommand2.html">AndroidX SessionCommand</a>
  * class for the list of valid commands.
- * <p>
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
- * for consistent behavior across all devices.
  */
 public final class Session2Command implements Parcelable {
     /**
@@ -162,6 +162,11 @@
     }
 
     /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
      * Contains the result of {@link Session2Command}.
      */
     public static final class Result {
diff --git a/media/apex/java/android/media/Session2CommandGroup.java b/media/apex/java/android/media/Session2CommandGroup.java
index 06ae873..0ee5f62 100644
--- a/media/apex/java/android/media/Session2CommandGroup.java
+++ b/media/apex/java/android/media/Session2CommandGroup.java
@@ -28,13 +28,12 @@
 import java.util.Set;
 
 /**
- * A set of {@link Session2Command} which represents a command group.
- * <p>
  * This API is not generally intended for third party application developers.
  * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
- * for consistent behavior across all devices.
- * </p>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * A set of {@link Session2Command} which represents a command group.
  */
 public final class Session2CommandGroup implements Parcelable {
     private static final String TAG = "Session2CommandGroup";
@@ -131,6 +130,11 @@
     }
 
     /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
      * Builds a {@link Session2CommandGroup} object.
      */
     public static final class Builder {
diff --git a/media/apex/java/android/media/Session2Token.java b/media/apex/java/android/media/Session2Token.java
index d7cb978..6eb76b1 100644
--- a/media/apex/java/android/media/Session2Token.java
+++ b/media/apex/java/android/media/Session2Token.java
@@ -36,13 +36,13 @@
 import java.util.Objects;
 
 /**
- * Represents an ongoing {@link MediaSession2} or a {@link MediaSession2Service}.
- * If it's representing a session service, it may not be ongoing.
- * <p>
  * This API is not generally intended for third party application developers.
  * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
- * for consistent behavior across all devices.
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * Represents an ongoing {@link MediaSession2} or a {@link MediaSession2Service}.
+ * If it's representing a session service, it may not be ongoing.
  * <p>
  * This may be passed to apps by the session owner to allow them to create a
  * {@link MediaController2} to communicate with the session.
@@ -118,11 +118,11 @@
         mUid = uid;
         mType = TYPE_SESSION_SERVICE;
         mSessionLink = null;
-        mExtras = null;
+        mExtras = Bundle.EMPTY;
     }
 
     Session2Token(int uid, int type, String packageName, Session2Link sessionLink,
-            Bundle tokenExtras) {
+            @NonNull Bundle tokenExtras) {
         mUid = uid;
         mType = type;
         mPackageName = packageName;
@@ -139,7 +139,16 @@
         mServiceName = in.readString();
         mSessionLink = in.readParcelable(null);
         mComponentName = ComponentName.unflattenFromString(in.readString());
-        mExtras = in.readBundle();
+
+        Bundle extras = in.readBundle();
+        if (extras == null) {
+            Log.w(TAG, "extras shouldn't be null.");
+            extras = Bundle.EMPTY;
+        } else if (MediaSession2.hasCustomParcelable(extras)) {
+            Log.w(TAG, "extras contain custom parcelable. Ignoring.");
+            extras = Bundle.EMPTY;
+        }
+        mExtras = extras;
     }
 
     @Override
@@ -220,7 +229,7 @@
      */
     @NonNull
     public Bundle getExtras() {
-        return mExtras == null ? Bundle.EMPTY : mExtras;
+        return new Bundle(mExtras);
     }
 
     Session2Link getSessionLink() {
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index ce9b07d..0254c97 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -1788,6 +1788,9 @@
      * @hide
      */
     public int getPortId() {
+        if (mNativeRecorderInJavaObj == 0) {
+            return 0;
+        }
         return native_getPortId();
     }
 
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 987db8b..53bc65d 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -24,7 +24,6 @@
 import android.content.pm.PackageManager;
 import android.media.audiofx.AudioEffect;
 import android.media.audiopolicy.AudioMix;
-import android.os.Build;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -981,6 +980,8 @@
     public static native boolean getMasterMono();
     /** @hide enables or disables the master mono mode. */
     public static native int setMasterMono(boolean mono);
+    /** @hide enables or disables the RTT mode. */
+    public static native int setRttEnabled(boolean enabled);
 
     /** @hide returns master balance value in range -1.f -> 1.f, where 0.f is dead center. */
     @TestApi
@@ -990,9 +991,9 @@
     public static native int setMasterBalance(float balance);
 
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 112561552)
+    @UnsupportedAppUsage(trackingBug = 134049522)
     public static native int getPrimaryOutputSamplingRate();
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 112561552)
+    @UnsupportedAppUsage(trackingBug = 134049522)
     public static native int getPrimaryOutputFrameCount();
     @UnsupportedAppUsage
     public static native int getOutputLatency(int stream);
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 5645ba5..7ae6a02 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -367,6 +367,8 @@
     public static final String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
     /** Type is int. */
     public static final String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
+    /** Type is int. */
+    public static final String TAG_THUMBNAIL_ORIENTATION = "ThumbnailOrientation";
     /** Type is int. DNG Specification 1.4.0.0. Section 4 */
     public static final String TAG_DNG_VERSION = "DNGVersion";
     /** Type is int. DNG Specification 1.4.0.0. Section 4 */
@@ -1155,7 +1157,7 @@
             new ExifTag(TAG_MAKE, 271, IFD_FORMAT_STRING),
             new ExifTag(TAG_MODEL, 272, IFD_FORMAT_STRING),
             new ExifTag(TAG_STRIP_OFFSETS, 273, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
-            new ExifTag(TAG_ORIENTATION, 274, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_THUMBNAIL_ORIENTATION, 274, IFD_FORMAT_USHORT),
             new ExifTag(TAG_SAMPLES_PER_PIXEL, 277, IFD_FORMAT_USHORT),
             new ExifTag(TAG_ROWS_PER_STRIP, 278, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
             new ExifTag(TAG_STRIP_BYTE_COUNTS, 279, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
diff --git a/media/java/android/media/IMediaRoute2Provider.aidl b/media/java/android/media/IMediaRoute2Provider.aidl
index 4bd5710..f132cef 100644
--- a/media/java/android/media/IMediaRoute2Provider.aidl
+++ b/media/java/android/media/IMediaRoute2Provider.aidl
@@ -23,7 +23,8 @@
  * {@hide}
  */
 oneway interface IMediaRoute2Provider {
-    void registerClient(IMediaRoute2ProviderClient client);
-    void selectRoute(IMediaRoute2ProviderClient client, int uid, String id);
-    void notifyControlRequestSent(IMediaRoute2ProviderClient client, String id, in Intent request);
+    void setClient(IMediaRoute2ProviderClient client);
+    void selectRoute(String packageName, String id);
+    void unselectRoute(String packageName, String id);
+    void notifyControlRequestSent(String id, in Intent request);
 }
diff --git a/media/java/android/media/IMediaRoute2ProviderClient.aidl b/media/java/android/media/IMediaRoute2ProviderClient.aidl
index e849e19..8d08beb 100644
--- a/media/java/android/media/IMediaRoute2ProviderClient.aidl
+++ b/media/java/android/media/IMediaRoute2ProviderClient.aidl
@@ -22,6 +22,5 @@
  * @hide
  */
 oneway interface IMediaRoute2ProviderClient {
-    void notifyRouteSelected(int uid, String routeId);
     void notifyProviderInfoUpdated(in MediaRoute2ProviderInfo info);
 }
diff --git a/media/java/android/media/IMediaRouter2Manager.aidl b/media/java/android/media/IMediaRouter2Manager.aidl
index 86bab87..b059bd3c 100644
--- a/media/java/android/media/IMediaRouter2Manager.aidl
+++ b/media/java/android/media/IMediaRouter2Manager.aidl
@@ -17,12 +17,13 @@
 package android.media;
 
 import android.media.MediaRoute2ProviderInfo;
+import android.media.MediaRoute2Info;
 
 /**
  * {@hide}
  */
 oneway interface IMediaRouter2Manager {
-    void notifyRouteSelected(int uid, String routeId);
-    void notifyControlCategoriesChanged(int uid, in List<String> categories);
+    void notifyRouteSelected(String packageName, in MediaRoute2Info route);
+    void notifyControlCategoriesChanged(String packageName, in List<String> categories);
     void notifyProviderInfosUpdated(in List<MediaRoute2ProviderInfo> providers);
 }
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index b148921..08266a5 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -45,11 +45,25 @@
     void registerClient2AsUser(IMediaRouter2Client client, String packageName, int userId);
     void unregisterClient2(IMediaRouter2Client client);
     void sendControlRequest(IMediaRouter2Client client, in MediaRoute2Info route, in Intent request);
+    /**
+     * Changes the selected route of the client.
+     *
+     * @param client the client that changes it's selected route
+     * @param route the route to be selected
+     */
+    void selectRoute2(IMediaRouter2Client client, in @nullable MediaRoute2Info route);
     void setControlCategories(IMediaRouter2Client client, in List<String> categories);
 
     void registerManagerAsUser(IMediaRouter2Manager manager,
             String packageName, int userId);
     void unregisterManager(IMediaRouter2Manager manager);
-    void setRemoteRoute(IMediaRouter2Manager manager,
-            int uid, String routeId, boolean explicit);
+    /**
+     * Changes the selected route of an application.
+     *
+     * @param manager the manager that calls the method
+     * @param packageName the package name of the client that will change the selected route
+     * @param route the route to be selected
+     */
+    void selectClientRoute2(IMediaRouter2Manager manager, String packageName,
+            in @nullable MediaRoute2Info route);
 }
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 56e8e85..510ee44 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -644,6 +644,16 @@
  <p>
  Also since {@link android.os.Build.VERSION_CODES#M}, you can change the output Surface
  dynamically using {@link #setOutputSurface setOutputSurface}.
+ <p>
+ When rendering output to a Surface, the Surface may be configured to drop excessive frames (that
+ are not consumed by the Surface in a timely manner). Or it may be configured to not drop excessive
+ frames. In the latter mode if the Surface is not consuming output frames fast enough, it will
+ eventually block the decoder. Prior to {@link android.os.Build.VERSION_CODES#Q} the exact behavior
+ was undefined, with the exception that View surfaces (SuerfaceView or TextureView) always dropped
+ excessive frames. Since {@link android.os.Build.VERSION_CODES#Q} the default behavior is to drop
+ excessive frames. Applications can opt out of this behavior for non-View surfaces (such as
+ ImageReader or SurfaceTexture) by targeting SDK {@link android.os.Build.VERSION_CODES#Q} and
+ setting the key {@code "allow-frame-drop"} to {@code 0} in their configure format.
 
  <h4>Transformations When Rendering onto Surface</h4>
 
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 112ce1d..0346010 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -67,16 +67,16 @@
      */
     public void setDataSource(String path) throws IllegalArgumentException {
         if (path == null) {
-            throw new IllegalArgumentException();
+            throw new IllegalArgumentException("null path");
         }
 
         try (FileInputStream is = new FileInputStream(path)) {
             FileDescriptor fd = is.getFD();
             setDataSource(fd, 0, 0x7ffffffffffffffL);
         } catch (FileNotFoundException fileEx) {
-            throw new IllegalArgumentException();
+            throw new IllegalArgumentException(path + " does not exist");
         } catch (IOException ioEx) {
-            throw new IllegalArgumentException();
+            throw new IllegalArgumentException("couldn't open " + path);
         }
     }
 
@@ -155,7 +155,7 @@
     public void setDataSource(Context context, Uri uri)
         throws IllegalArgumentException, SecurityException {
         if (uri == null) {
-            throw new IllegalArgumentException();
+            throw new IllegalArgumentException("null uri");
         }
 
         String scheme = uri.getScheme();
@@ -170,14 +170,14 @@
             try {
                 fd = resolver.openAssetFileDescriptor(uri, "r");
             } catch(FileNotFoundException e) {
-                throw new IllegalArgumentException();
+                throw new IllegalArgumentException("could not access " + uri);
             }
             if (fd == null) {
-                throw new IllegalArgumentException();
+                throw new IllegalArgumentException("got null FileDescriptor for " + uri);
             }
             FileDescriptor descriptor = fd.getFileDescriptor();
             if (!descriptor.valid()) {
-                throw new IllegalArgumentException();
+                throw new IllegalArgumentException("got invalid FileDescriptor for " + uri);
             }
             // Note: using getDeclaredLength so that our behavior is the same
             // as previous versions when the content provider is returning
@@ -800,7 +800,7 @@
      */
     public static final int METADATA_KEY_YEAR            = 8;
     /**
-     * The metadata key to retrieve the playback duration of the data source.
+     * The metadata key to retrieve the playback duration (in ms) of the data source.
      */
     public static final int METADATA_KEY_DURATION        = 9;
     /**
@@ -869,7 +869,7 @@
      * This key retrieves the location information, if available.
      * The location should be specified according to ISO-6709 standard, under
      * a mp4/3gp box "@xyz". Location with longitude of -90 degrees and latitude
-     * of 180 degrees will be retrieved as "-90.0000+180.0000", for instance.
+     * of 180 degrees will be retrieved as "+180.0000-90.0000/", for instance.
      */
     public static final int METADATA_KEY_LOCATION        = 23;
     /**
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 63b22df..bf7da23 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -720,7 +720,7 @@
 
     /**
      * Sets the width and height of the video to be captured.  Must be called
-     * after setVideoSource(). Call this after setOutFormat() but before
+     * after setVideoSource(). Call this after setOutputFormat() but before
      * prepare().
      *
      * @param width the width of the video to be captured
@@ -733,7 +733,7 @@
 
     /**
      * Sets the frame rate of the video to be captured.  Must be called
-     * after setVideoSource(). Call this after setOutFormat() but before
+     * after setVideoSource(). Call this after setOutputFormat() but before
      * prepare().
      *
      * @param rate the number of frames per second of video to capture
@@ -748,7 +748,7 @@
 
     /**
      * Sets the maximum duration (in ms) of the recording session.
-     * Call this after setOutFormat() but before prepare().
+     * Call this after setOutputFormat() but before prepare().
      * After recording reaches the specified duration, a notification
      * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
      * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_DURATION_REACHED}
@@ -769,7 +769,7 @@
 
     /**
      * Sets the maximum filesize (in bytes) of the recording session.
-     * Call this after setOutFormat() but before prepare().
+     * Call this after setOutputFormat() but before prepare().
      * After recording reaches the specified filesize, a notification
      * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
      * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}
@@ -1624,6 +1624,9 @@
      * @hide
      */
     public int getPortId() {
+        if (mNativeContext == 0) {
+            return 0;
+        }
         return native_getPortId();
     }
 
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 03b49d9..5dcbb05 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -23,6 +23,11 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
 /**
  * Describes the properties of a route.
  * @hide
@@ -43,44 +48,92 @@
 
     @NonNull
     final String mId;
+    @Nullable
+    final String mProviderId;
     @NonNull
     final String mName;
     @Nullable
     final String mDescription;
     @Nullable
+    final String mClientPackageName;
+    @NonNull
+    final List<String> mSupportedCategories;
+    @Nullable
     final Bundle mExtras;
 
     MediaRoute2Info(@NonNull Builder builder) {
         mId = builder.mId;
+        mProviderId = builder.mProviderId;
         mName = builder.mName;
         mDescription = builder.mDescription;
+        mClientPackageName = builder.mClientPackageName;
+        mSupportedCategories = builder.mSupportedCategories;
         mExtras = builder.mExtras;
     }
 
     MediaRoute2Info(@NonNull Parcel in) {
         mId = in.readString();
+        mProviderId = in.readString();
         mName = in.readString();
         mDescription = in.readString();
+        mClientPackageName = in.readString();
+        mSupportedCategories = in.createStringArrayList();
         mExtras = in.readBundle();
     }
 
     /**
-     * Returns true if the route info has all of the required field
+     * Returns true if the route info has all of the required field.
+     * A route info only obtained from {@link com.android.server.media.MediaRouterService}
+     * is valid.
      * @hide
      */
     //TODO: Reconsider the validity of a route info when fields are added.
     public boolean isValid() {
-        if (TextUtils.isEmpty(getId()) || TextUtils.isEmpty(getName())) {
+        if (TextUtils.isEmpty(getId()) || TextUtils.isEmpty(getName())
+                || TextUtils.isEmpty(getProviderId())) {
             return false;
         }
         return true;
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof MediaRoute2Info)) {
+            return false;
+        }
+        MediaRoute2Info other = (MediaRoute2Info) obj;
+        return Objects.equals(mId, other.mId)
+                && Objects.equals(mProviderId, other.mProviderId)
+                && Objects.equals(mName, other.mName)
+                && Objects.equals(mDescription, other.mDescription)
+                && Objects.equals(mClientPackageName, other.mClientPackageName)
+                && Objects.equals(mSupportedCategories, other.mSupportedCategories)
+                //TODO: This will be evaluated as false in most cases. Try not to.
+                && Objects.equals(mExtras, other.mExtras);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mId, mName, mDescription, mSupportedCategories);
+    }
+
     @NonNull
     public String getId() {
         return mId;
     }
 
+    /**
+     * Gets the provider id of the route.
+     * @hide
+     */
+    @Nullable
+    public String getProviderId() {
+        return mProviderId;
+    }
+
     @NonNull
     public String getName() {
         return mName;
@@ -91,11 +144,48 @@
         return mDescription;
     }
 
+    /**
+     * Gets the package name of the client that uses the route.
+     * Returns null if no clients use this.
+     * @hide
+     */
+    @Nullable
+    public String getClientPackageName() {
+        return mClientPackageName;
+    }
+
+    /**
+     * Gets the supported categories of the route.
+     */
+    @NonNull
+    public List<String> getSupportedCategories() {
+        return mSupportedCategories;
+    }
+
     @Nullable
     public Bundle getExtras() {
         return mExtras;
     }
 
+    //TODO: Move this if we re-define control category / selector things.
+    /**
+     * Returns true if the route supports at least one of the specified control categories
+     *
+     * @param controlCategories the list of control categories to consider
+     * @return true if the route supports at least one category
+     */
+    public boolean supportsControlCategory(@NonNull Collection<String> controlCategories) {
+        Objects.requireNonNull(controlCategories, "control categories must not be null");
+        for (String controlCategory : controlCategories) {
+            for (String supportedCategory : getSupportedCategories()) {
+                if (TextUtils.equals(controlCategory, supportedCategory)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -104,8 +194,11 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(mId);
+        dest.writeString(mProviderId);
         dest.writeString(mName);
         dest.writeString(mDescription);
+        dest.writeString(mClientPackageName);
+        dest.writeStringList(mSupportedCategories);
         dest.writeBundle(mExtras);
     }
 
@@ -115,6 +208,8 @@
                 .append("MediaRouteInfo{ ")
                 .append("id=").append(getId())
                 .append(", name=").append(getName())
+                .append(", description=").append(getDescription())
+                .append(", providerId=").append(getProviderId())
                 .append(" }");
         return result.toString();
     }
@@ -124,8 +219,11 @@
      */
     public static final class Builder {
         String mId;
+        String mProviderId;
         String mName;
         String mDescription;
+        String mClientPackageName;
+        List<String> mSupportedCategories;
         Bundle mExtras;
 
         public Builder(@NonNull String id, @NonNull String name) {
@@ -137,6 +235,7 @@
             }
             setId(id);
             setName(name);
+            mSupportedCategories = new ArrayList<>();
         }
 
         public Builder(@NonNull MediaRoute2Info routeInfo) {
@@ -145,8 +244,16 @@
             }
 
             setId(routeInfo.mId);
+            if (!TextUtils.isEmpty(routeInfo.mProviderId)) {
+                setProviderId(routeInfo.mProviderId);
+            }
             setName(routeInfo.mName);
             mDescription = routeInfo.mDescription;
+            setClientPackageName(routeInfo.mClientPackageName);
+            setSupportedCategories(routeInfo.mSupportedCategories);
+            if (routeInfo.mExtras != null) {
+                mExtras = new Bundle(routeInfo.mExtras);
+            }
         }
 
         /**
@@ -162,6 +269,19 @@
         }
 
         /**
+         * Sets the provider id of the route.
+         * @hide
+         */
+        @NonNull
+        public Builder setProviderId(@NonNull String providerId) {
+            if (TextUtils.isEmpty(providerId)) {
+                throw new IllegalArgumentException("id must not be null or empty");
+            }
+            mProviderId = providerId;
+            return this;
+        }
+
+        /**
          * Sets the user-visible name of the route.
          */
         @NonNull
@@ -183,6 +303,57 @@
         }
 
         /**
+         * Sets the package name of the app using the route.
+         */
+        @NonNull
+        public Builder setClientPackageName(@Nullable String packageName) {
+            mClientPackageName = packageName;
+            return this;
+        }
+
+        /**
+         * Sets the supported categories of the route.
+         */
+        @NonNull
+        public Builder setSupportedCategories(@NonNull Collection<String> categories) {
+            mSupportedCategories = new ArrayList<>();
+            return addSupportedCategories(categories);
+        }
+
+        /**
+         * Adds supported categories for the route.
+         */
+        @NonNull
+        public Builder addSupportedCategories(@NonNull Collection<String> categories) {
+            Objects.requireNonNull(categories, "categories must not be null");
+            for (String category: categories) {
+                addSupportedCategory(category);
+            }
+            return this;
+        }
+
+        /**
+         * Add a supported category for the route.
+         */
+        @NonNull
+        public Builder addSupportedCategory(@NonNull String category) {
+            if (TextUtils.isEmpty(category)) {
+                throw new IllegalArgumentException("category must not be null or empty");
+            }
+            mSupportedCategories.add(category);
+            return this;
+        }
+
+        /**
+         * Sets a bundle of extras for the route.
+         */
+        @NonNull
+        public Builder setExtras(@Nullable Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
          * Builds the {@link MediaRoute2Info media route info}.
          */
         @NonNull
diff --git a/media/java/android/media/MediaRoute2ProviderInfo.java b/media/java/android/media/MediaRoute2ProviderInfo.java
index 57d82d4..8541f32 100644
--- a/media/java/android/media/MediaRoute2ProviderInfo.java
+++ b/media/java/android/media/MediaRoute2ProviderInfo.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 
 import java.util.Arrays;
@@ -82,8 +83,11 @@
         return true;
     }
 
+    /**
+     * @hide
+     */
     @Nullable
-    String getUniqueId() {
+    public String getUniqueId() {
         return mUniqueId;
     }
 
@@ -149,9 +153,21 @@
          * {@link com.android.server.media.MediaRouterService} and used to identify providers.
          * The id set by {@link MediaRoute2ProviderService} will be ignored.
          * </p>
+         * @hide
          */
         public Builder setUniqueId(@Nullable String uniqueId) {
+            if (TextUtils.equals(mUniqueId, uniqueId)) {
+                return this;
+            }
             mUniqueId = uniqueId;
+            final int count = mRoutes.size();
+            for (int i = 0; i < count; i++) {
+                MediaRoute2Info route = mRoutes.valueAt(i);
+                mRoutes.setValueAt(i, new MediaRoute2Info.Builder(route)
+                        .setProviderId(mUniqueId)
+                        .build());
+            }
+
             return this;
         }
 
@@ -164,7 +180,12 @@
             if (mRoutes.containsValue(route)) {
                 throw new IllegalArgumentException("route descriptor already added");
             }
-            mRoutes.put(route.getId(), route);
+            if (mUniqueId != null) {
+                mRoutes.put(route.getId(),
+                        new MediaRoute2Info.Builder(route).setProviderId(mUniqueId).build());
+            } else {
+                mRoutes.put(route.getId(), route);
+            }
             return this;
         }
 
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index 30e0ef1..b89b0b1 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -36,7 +36,6 @@
 
     private final Handler mHandler;
     private ProviderStub mStub;
-    //TODO: Should allow multiple clients
     private IMediaRoute2ProviderClient mClient;
     private MediaRoute2ProviderInfo mProviderInfo;
 
@@ -46,6 +45,7 @@
 
     @Override
     public IBinder onBind(Intent intent) {
+        //TODO: Allow binding from media router service only?
         if (SERVICE_INTERFACE.equals(intent.getAction())) {
             if (mStub == null) {
                 mStub = new ProviderStub();
@@ -58,49 +58,37 @@
     /**
      * 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
+     * @param packageName the package name of the application that selected the route
+     * @param routeId the id of the route being selected
      */
-    public abstract void onSelect(int uid, String routeId);
+    public abstract void onSelectRoute(String packageName, String routeId);
 
     /**
-     * Called when sendControlRequest is called on a route of the provider.
+     * Called when unselectRoute is called on a route of the provider.
      *
-     * @param routeId The id of the target route
-     * @param request The media control request intent
+     * @param packageName the package name of the application that has selected the route.
+     * @param routeId the id of the route being unselected
+     */
+    public abstract void onUnselectRoute(String packageName, String routeId);
+
+    /**
+     * Called when sendControlRequest is called on a route of the provider
+     *
+     * @param routeId the id of the target route
+     * @param request the media control request intent
      */
     //TODO: Discuss what to use for request (e.g., Intent? Request class?)
     public abstract void onControlRequest(String routeId, Intent request);
 
     /**
-     * Updates provider info from selected route and application.
-     *
-     * TODO: When provider descriptor is defined, this should update the descriptor correctly.
-     *
-     * @param uid
-     * @param routeId
-     */
-    public void updateProvider(int uid, String routeId) {
-        if (mClient != null) {
-            try {
-                //TODO: After publishState() is fully implemented, delete this.
-                mClient.notifyRouteSelected(uid, routeId);
-            } catch (RemoteException ex) {
-                Log.d(TAG, "Failed to update provider");
-            }
-        }
-        publishState();
-    }
-
-    /**
-     * Updates provider info and publish routes
+     * Updates provider info and publishes routes
      */
     public final void setProviderInfo(MediaRoute2ProviderInfo info) {
         mProviderInfo = info;
         publishState();
     }
 
-    void registerClient(IMediaRoute2ProviderClient client) {
+    void setClient(IMediaRoute2ProviderClient client) {
         mClient = client;
         publishState();
     }
@@ -120,20 +108,25 @@
         ProviderStub() { }
 
         @Override
-        public void registerClient(IMediaRoute2ProviderClient client) {
-            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::registerClient,
+        public void setClient(IMediaRoute2ProviderClient client) {
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setClient,
                     MediaRoute2ProviderService.this, client));
         }
 
         @Override
-        public void selectRoute(IMediaRoute2ProviderClient client, int uid, String id) {
-            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelect,
-                    MediaRoute2ProviderService.this, uid, id));
+        public void selectRoute(String packageName, String id) {
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute,
+                    MediaRoute2ProviderService.this, packageName, id));
         }
 
         @Override
-        public void notifyControlRequestSent(IMediaRoute2ProviderClient client, String id,
-                Intent request) {
+        public void unselectRoute(String packageName, String id) {
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onUnselectRoute,
+                    MediaRoute2ProviderService.this, packageName, id));
+        }
+
+        @Override
+        public void notifyControlRequestSent(String id, Intent request) {
             mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onControlRequest,
                     MediaRoute2ProviderService.this, id, request));
         }
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index d37a832..a69b105 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -18,6 +18,7 @@
 
 import android.annotation.MainThread;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Looper;
@@ -169,6 +170,22 @@
     }
 
     /**
+     * Selects the specified route.
+     *
+     * @param route The route to select.
+     */
+    //TODO: add a parameter for category (e.g. mirroring/casting)
+    public void selectRoute(@Nullable MediaRoute2Info route) {
+        if (mClient != null) {
+            try {
+                mMediaRouterService.selectRoute2(mClient, route);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to select route.", ex);
+            }
+        }
+    }
+
+    /**
      * Sends a media control request to be performed asynchronously by the route's destination.
      * @param route the route that will receive the control request
      * @param request the media control request
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 5fcb684..85105e0 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -20,6 +20,7 @@
 
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.os.Handler;
 import android.os.RemoteException;
@@ -37,6 +38,9 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Executor;
 
 /**
@@ -57,10 +61,15 @@
     final Handler mHandler;
 
     @GuardedBy("sLock")
-    final ArrayList<CallbackRecord> mCallbacks = new ArrayList<>();
+    final List<CallbackRecord> mCallbacks = new CopyOnWriteArrayList<>();
 
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
     @NonNull
-    private List<MediaRoute2ProviderInfo> mProviders = Collections.emptyList();
+    List<MediaRoute2ProviderInfo> mProviders = Collections.emptyList();
+    @NonNull
+    List<MediaRoute2Info> mRoutes = Collections.emptyList();
+    @NonNull
+    ConcurrentMap<String, List<String>> mControlCategoryMap = new ConcurrentHashMap<>();
 
     /**
      * Gets an instance of media router manager that controls media route of other applications.
@@ -93,17 +102,12 @@
     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");
-        }
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(callback, "callback must not be null");
 
         synchronized (sLock) {
-            final int index = findCallbackRecord(callback);
-            if (index >= 0) {
-                Log.w(TAG, "Ignore adding the same callback twice.");
+            if (findCallbackRecordIndex(callback) >= 0) {
+                Log.w(TAG, "Ignoring to add the same callback twice.");
                 return;
             }
             if (mCallbacks.size() == 0) {
@@ -116,7 +120,9 @@
                     Log.e(TAG, "Unable to register media router manager.", ex);
                 }
             }
-            mCallbacks.add(new CallbackRecord(executor, callback));
+            CallbackRecord record = new CallbackRecord(executor, callback);
+            mCallbacks.add(record);
+            record.notifyRoutes();
         }
     }
 
@@ -131,7 +137,7 @@
         }
 
         synchronized (sLock) {
-            final int index = findCallbackRecord(callback);
+            final int index = findCallbackRecordIndex(callback);
             if (index < 0) {
                 Log.w(TAG, "Ignore removing unknown callback. " + callback);
                 return;
@@ -148,7 +154,7 @@
         }
     }
 
-    private int findCallbackRecord(Callback callback) {
+    private int findCallbackRecordIndex(Callback callback) {
         final int count = mCallbacks.size();
         for (int i = 0; i < count; i++) {
             if (mCallbacks.get(i).mCallback == callback) {
@@ -158,16 +164,38 @@
         return -1;
     }
 
+    //TODO: Use cache not to create array. For now, it's unclear when to purge the cache.
+    //Do this when we finalize how to set control categories.
     /**
-     * Selects media route for the specified application uid.
+     * Gets available routes for an application.
      *
-     * @param uid The uid of the application that should change it's media route.
-     * @param routeId The id of the route to select
+     * @param packageName the package name of the application
      */
-    public void selectRoute(int uid, String routeId) {
+    @NonNull
+    public List<MediaRoute2Info> getAvailableRoutes(@NonNull String packageName) {
+        List<String> controlCategories = mControlCategoryMap.get(packageName);
+        if (controlCategories == null) {
+            return Collections.emptyList();
+        }
+        List<MediaRoute2Info> routes = new ArrayList<>();
+        for (MediaRoute2Info route : mRoutes) {
+            if (route.supportsControlCategory(controlCategories)) {
+                routes.add(route);
+            }
+        }
+        return routes;
+    }
+
+    /**
+     * Selects media route for the specified package name.
+     *
+     * @param packageName the package name of the application that should change it's media route
+     * @param route the route to be selected
+     */
+    public void selectRoute(@NonNull String packageName, @NonNull MediaRoute2Info route) {
         if (mClient != null) {
             try {
-                mMediaRouterService.setRemoteRoute(mClient, uid, routeId, /* explicit= */true);
+                mMediaRouterService.selectClientRoute2(mClient, packageName, route);
             } catch (RemoteException ex) {
                 Log.e(TAG, "Unable to select media route", ex);
             }
@@ -175,14 +203,14 @@
     }
 
     /**
-     * Unselects media route for the specified application uid.
+     * Unselects media route for the specified package name.
      *
-     * @param uid The uid of the application that should stop routing.
+     * @param packageName the package name of the application that should stop routing
      */
-    public void unselectRoute(int uid) {
+    public void unselectRoute(@NonNull String packageName) {
         if (mClient != null) {
             try {
-                mMediaRouterService.setRemoteRoute(mClient, uid, null, /* explicit= */ true);
+                mMediaRouterService.selectClientRoute2(mClient, packageName, null);
             } catch (RemoteException ex) {
                 Log.e(TAG, "Unable to select media route", ex);
             }
@@ -220,15 +248,18 @@
                 if (prevRoute == null) {
                     notifyRouteAdded(routeInfo);
                 } else {
-                    //TODO: Notify only it's really changed.
-                    notifyRouteChanged(routeInfo);
+                    if (!Objects.equals(prevRoute, routeInfo)) {
+                        notifyRouteChanged(routeInfo);
+                    }
                     updatedRouteIds.add(routeInfo.getId());
                 }
             }
             final Collection<MediaRoute2Info> prevRoutes = prevProvider.getRoutes();
 
             for (MediaRoute2Info prevRoute : prevRoutes) {
-                notifyRouteRemoved(prevRoute);
+                if (!updatedRouteIds.contains(prevRoute.getId())) {
+                    notifyRouteRemoved(prevRoute);
+                }
             }
         } else {
             for (MediaRoute2Info routeInfo: routes) {
@@ -258,72 +289,79 @@
         }
     }
 
+    void notifyRouteListChanged() {
+        for (CallbackRecord record: mCallbacks) {
+            record.mExecutor.execute(
+                    () -> record.mCallback.onRouteListChanged(mRoutes));
+        }
+    }
+
     void notifyProviderInfosUpdated(List<MediaRoute2ProviderInfo> providers) {
         if (providers == null) {
             Log.w(TAG, "Providers info is null.");
             return;
         }
 
+        ArrayList<MediaRoute2Info> routes = new ArrayList<>();
+
         for (MediaRoute2ProviderInfo provider : providers) {
             updateProvider(provider);
+            //TODO: Should we do this in updateProvider()?
+            routes.addAll(provider.getRoutes());
         }
-        //TODO: Call notifyProviderRemoved for removed providers.
+        //TODO: Call notifyRouteRemoved for the routes of the removed providers.
 
-        //TODO: Filter invalid providers.
+        //TODO: Filter invalid providers and invalid routes.
         mProviders = providers;
+        mRoutes = routes;
+
+        //TODO: Call this when only the list is modified.
+        notifyRouteListChanged();
     }
 
-    void notifyRouteSelected(int uid, String routeId) {
+    void notifyRouteSelected(String packageName, MediaRoute2Info route) {
         for (CallbackRecord record : mCallbacks) {
-            record.mExecutor.execute(() -> record.mCallback.onRouteSelected(uid, routeId));
+            record.mExecutor.execute(() -> record.mCallback.onRouteSelected(packageName, route));
         }
     }
 
-    void notifyControlCategoriesChanged(int uid, List<String> categories) {
-        for (CallbackRecord record : mCallbacks) {
-            record.mExecutor.execute(
-                    () -> record.mCallback.onControlCategoriesChanged(uid, categories));
-        }
+    void updateControlCategories(String packageName, List<String> categories) {
+        mControlCategoryMap.put(packageName, categories);
     }
 
     /**
      * Interface for receiving events about media routing changes.
      */
-    public abstract static class Callback {
+    public static class Callback {
         /**
          * Called when a route is added.
          */
-        public void onRouteAdded(MediaRoute2Info routeInfo) {}
+        public void onRouteAdded(@NonNull MediaRoute2Info routeInfo) {}
 
         /**
          * Called when a route is changed.
          */
-        public void onRouteChanged(MediaRoute2Info routeInfo) {}
+        public void onRouteChanged(@NonNull MediaRoute2Info routeInfo) {}
 
         /**
          * Called when a route is removed.
          */
-        public void onRouteRemoved(MediaRoute2Info routeInfo) {}
+        public void onRouteRemoved(@NonNull MediaRoute2Info routeInfo) {}
 
         /**
-         * Called when a route is selected for some application uid.
-         * @param uid
-         * @param routeId
+         * Called when a route is selected for an application.
+         *
+         * @param packageName the package name of the application
+         * @param route the selected route of the application.
+         *              It is null if the application has no selected route.
          */
-        public abstract void onRouteSelected(int uid, String routeId);
+        public void onRouteSelected(@NonNull String packageName, @Nullable MediaRoute2Info route) {}
 
         /**
-         * 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
+         * Called when the list of routes are changed.
+         * A client may refresh available routes for each application.
          */
-        public abstract void onControlCategoriesChanged(int uid, List<String> categories);
-
-        /**
-         * Called when the provider updates its information
-         * @param info the changed provider information
-         */
-        public void onProviderInfoUpdated(MediaRoute2ProviderInfo info) {}
+        public void onRouteListChanged(@NonNull List<MediaRoute2Info> routes) {}
     }
 
     final class CallbackRecord {
@@ -334,19 +372,28 @@
             mExecutor = executor;
             mCallback = callback;
         }
+
+        void notifyRoutes() {
+            for (MediaRoute2ProviderInfo provider : mProviders) {
+                for (MediaRoute2Info routeInfo : provider.getRoutes()) {
+                    mExecutor.execute(
+                            () -> mCallback.onRouteAdded(routeInfo));
+                }
+            }
+        }
     }
 
     class Client extends IMediaRouter2Manager.Stub {
         @Override
-        public void notifyRouteSelected(int uid, String routeId) {
+        public void notifyRouteSelected(String packageName, MediaRoute2Info route) {
             mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyRouteSelected,
-                    MediaRouter2Manager.this, uid, routeId));
+                    MediaRouter2Manager.this, packageName, route));
         }
 
         @Override
-        public void notifyControlCategoriesChanged(int uid, List<String> categories) {
-            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyControlCategoriesChanged,
-                    MediaRouter2Manager.this, uid, categories));
+        public void notifyControlCategoriesChanged(String packageName, List<String> categories) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::updateControlCategories,
+                    MediaRouter2Manager.this, packageName, categories));
         }
 
         @Override
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 534d63b..fb581b5 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -356,19 +356,21 @@
                 return ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
             }
 
-            // Fall back to middle of video
             final int width = Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_WIDTH));
             final int height = Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_HEIGHT));
-            final long duration = Long.parseLong(mmr.extractMetadata(METADATA_KEY_DURATION));
+            // Fall back to middle of video
+            // Note: METADATA_KEY_DURATION unit is in ms, not us.
+            final long thumbnailTimeUs =
+                    Long.parseLong(mmr.extractMetadata(METADATA_KEY_DURATION)) * 1000 / 2;
 
             // If we're okay with something larger than native format, just
             // return a frame without up-scaling it
             if (size.getWidth() > width && size.getHeight() > height) {
                 return Objects.requireNonNull(
-                        mmr.getFrameAtTime(duration / 2, OPTION_CLOSEST_SYNC));
+                        mmr.getFrameAtTime(thumbnailTimeUs, OPTION_CLOSEST_SYNC));
             } else {
                 return Objects.requireNonNull(
-                        mmr.getScaledFrameAtTime(duration / 2, OPTION_CLOSEST_SYNC,
+                        mmr.getScaledFrameAtTime(thumbnailTimeUs, OPTION_CLOSEST_SYNC,
                         size.getWidth(), size.getHeight()));
             }
         } catch (RuntimeException e) {
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index a67a37e..01e6ed5 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -62,7 +62,8 @@
     // For PhoneWindowManager to precheck media keys
     boolean isGlobalPriorityActive();
 
-    void setCallback(in ICallback callback);
+    void registerCallback(in ICallback callback);
+    void unregisterCallback(in ICallback callback);
     void setOnVolumeKeyLongPressListener(in IOnVolumeKeyLongPressListener listener);
     void setOnMediaKeyListener(in IOnMediaKeyListener listener);
 
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index c1c7fca..1fc4f7d 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -414,7 +414,7 @@
     /**
      * Gets the additional session information which was set when the session was created.
      *
-     * @return The additional session information, or {@link Bundle#EMPTY} if not set.
+     * @return The additional session information, or an empty {@link Bundle} if not set.
      */
     @NonNull
     public Bundle getSessionInfo() {
@@ -430,6 +430,10 @@
         }
 
         if (mSessionInfo == null) {
+            Log.w(TAG, "sessionInfo shouldn't be null.");
+            mSessionInfo = Bundle.EMPTY;
+        } else if (MediaSession.hasCustomParcelable(mSessionInfo)) {
+            Log.w(TAG, "sessionInfo contains custom parcelable. Ignoring.");
             mSessionInfo = Bundle.EMPTY;
         }
         return new Bundle(mSessionInfo);
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index c4085f8..e11715f 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -32,6 +32,7 @@
 import android.media.VolumeProvider;
 import android.media.session.MediaSessionManager.RemoteUserInfo;
 import android.net.Uri;
+import android.os.BadParcelableException;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -168,6 +169,8 @@
      * @param sessionInfo A bundle for additional information about this session.
      *                    Controllers can get this information by calling
      *                    {@link MediaController#getSessionInfo()}.
+     *                    An {@link IllegalArgumentException} will be thrown if this contains
+     *                    any non-framework Parcelable objects.
      */
     public MediaSession(@NonNull Context context, @NonNull String tag,
             @Nullable Bundle sessionInfo) {
@@ -177,6 +180,11 @@
         if (TextUtils.isEmpty(tag)) {
             throw new IllegalArgumentException("tag cannot be null or empty");
         }
+        if (hasCustomParcelable(sessionInfo)) {
+            throw new IllegalArgumentException("sessionInfo shouldn't contain any custom "
+                    + "parcelables");
+        }
+
         mMaxBitmapSize = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize);
         mCbStub = new CallbackStub(this);
@@ -600,6 +608,35 @@
         return false;
     }
 
+    /**
+     * Returns whether the given bundle includes non-framework Parcelables.
+     */
+    static boolean hasCustomParcelable(@Nullable Bundle bundle) {
+        if (bundle == null) {
+            return false;
+        }
+
+        // Try writing the bundle to parcel, and read it with framework classloader.
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            parcel.writeBundle(bundle);
+            parcel.setDataPosition(0);
+            Bundle out = parcel.readBundle(null);
+
+            // Calling Bundle#size() will trigger Bundle#unparcel().
+            out.size();
+        } catch (BadParcelableException e) {
+            Log.d(TAG, "Custom parcelable in bundle.", e);
+            return true;
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+        return false;
+    }
+
     void dispatchPrepare(RemoteUserInfo caller) {
         postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null);
     }
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 569d11e..1f2283c 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -46,7 +46,9 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -72,6 +74,7 @@
      * @hide
      */
     public static final int RESULT_MEDIA_KEY_HANDLED = 1;
+    private final ISessionManager mService;
 
     private final Object mLock = new Object();
     @GuardedBy("mLock")
@@ -80,13 +83,21 @@
     @GuardedBy("mLock")
     private final ArrayMap<OnSession2TokensChangedListener, Session2TokensChangedWrapper>
             mSession2TokensListeners = new ArrayMap<>();
-    private final ISessionManager mService;
+    @GuardedBy("mLock")
+    private final CallbackStub mCbStub = new CallbackStub();
+    @GuardedBy("mLock")
+    private final Map<Callback, Handler> mCallbacks = new HashMap<>();
+    @GuardedBy("mLock")
+    private MediaSession.Token mCurMediaButtonSession;
+    @GuardedBy("mLock")
+    private ComponentName mCurMediaButtonReceiver;
 
     private Context mContext;
-
-    private CallbackImpl mCallback;
     private OnVolumeKeyLongPressListenerImpl mOnVolumeKeyLongPressListener;
     private OnMediaKeyListenerImpl mOnMediaKeyListener;
+    // TODO: Remove mLegacyCallback once Bluetooth app stop calling setCallback() method.
+    @GuardedBy("mLock")
+    private Callback mLegacyCallback;
 
     /**
      * @hide
@@ -119,6 +130,11 @@
     }
 
     /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
      * Notifies that a new {@link MediaSession2} with type {@link Session2Token#TYPE_SESSION} is
      * created.
      * <p>
@@ -192,6 +208,11 @@
     }
 
     /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
      * Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the
      * current user.
      * <p>
@@ -335,12 +356,12 @@
     }
 
     /**
-     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
-     * <p>
      * This API is not generally intended for third party application developers.
      * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
-     * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
-     * for consistent behavior across all devices.
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
      *
      * @param listener The listener to add
      */
@@ -350,12 +371,12 @@
     }
 
     /**
-     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
-     * <p>
      * This API is not generally intended for third party application developers.
      * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
-     * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
-     * for consistent behavior across all devices.
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
      *
      * @param listener The listener to add
      * @param handler The handler to call listener on.
@@ -366,12 +387,12 @@
     }
 
     /**
-     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
-     * <p>
      * This API is not generally intended for third party application developers.
      * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
-     * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
-     * for consistent behavior across all devices.
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
      *
      * @param userId The userId to listen for changes on
      * @param listener The listener to add
@@ -402,6 +423,11 @@
     }
 
     /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
      * Removes the {@link OnSession2TokensChangedListener} to stop receiving session token updates.
      *
      * @param listener The listener to remove.
@@ -737,18 +763,71 @@
      *            if the callback should be invoked on the calling thread's looper.
      * @hide
      */
+    // TODO: Remove this method once Bluetooth app stop calling it.
     public void setCallback(@Nullable Callback callback, @Nullable Handler handler) {
         synchronized (mLock) {
+            if (mLegacyCallback != null) {
+                unregisterCallback(mLegacyCallback);
+            }
+            mLegacyCallback = callback;
+            if (callback != null) {
+                registerCallback(callback, handler);
+            }
+        }
+    }
+
+    /**
+     * Register a {@link Callback}.
+     *
+     * @param callback A {@link Callback}.
+     * @param handler The handler on which the callback should be invoked, or {@code null}
+     *            if the callback should be invoked on the calling thread's looper.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void registerCallback(@NonNull Callback callback, @Nullable Handler handler) {
+        if (callback == null) {
+            throw new NullPointerException("callback shouldn't be null");
+        }
+        synchronized (mLock) {
             try {
-                if (callback == null) {
-                    mCallback = null;
-                    mService.setCallback(null);
-                } else {
-                    if (handler == null) {
-                        handler = new Handler();
-                    }
-                    mCallback = new CallbackImpl(callback, handler);
-                    mService.setCallback(mCallback);
+                if (handler == null) {
+                    handler = new Handler();
+                }
+                mCallbacks.put(callback, handler);
+                if (mCurMediaButtonSession != null) {
+                    handler.post(() -> callback.onAddressedPlayerChanged(mCurMediaButtonSession));
+                } else if (mCurMediaButtonReceiver != null) {
+                    handler.post(() -> callback.onAddressedPlayerChanged(mCurMediaButtonReceiver));
+                }
+
+                if (mCallbacks.size() == 1) {
+                    mService.registerCallback(mCbStub);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to set media key callback", e);
+            }
+        }
+    }
+
+    /**
+     * Unregister a {@link Callback}.
+     *
+     * @param callback A {@link Callback}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void unregisterCallback(@NonNull Callback callback) {
+        if (callback == null) {
+            throw new NullPointerException("callback shouldn't be null");
+        }
+        synchronized (mLock) {
+            try {
+                mCallbacks.remove(callback);
+                if (mCallbacks.size() == 0) {
+                    mService.unregisterCallback(mCbStub);
                 }
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to set media key callback", e);
@@ -765,13 +844,13 @@
     }
 
     /**
-     * Listens for changes to the {@link #getSession2Tokens()}. This can be added
-     * using {@link #addOnSession2TokensChangedListener(OnSession2TokensChangedListener, Handler)}.
-     * <p>
      * This API is not generally intended for third party application developers.
      * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
-     * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
-     * for consistent behavior across all devices.
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Listens for changes to the {@link #getSession2Tokens()}. This can be added
+     * using {@link #addOnSession2TokensChangedListener(OnSession2TokensChangedListener, Handler)}.
      */
     public interface OnSession2TokensChangedListener {
         /**
@@ -820,6 +899,7 @@
      * receive media key events.
      * @hide
      */
+    @SystemApi
     public static abstract class Callback {
         /**
          * Called when a media key event is dispatched to the media session
@@ -846,7 +926,7 @@
         /**
          * Called when the addressed player is changed to a media session.
          * <p>One of the {@ #onAddressedPlayerChanged} will be also called immediately after
-         * {@link #setCallback} if the addressed player exists.
+         * {@link #registerCallback} if the addressed player exists.
          *
          * @param sessionToken The media session's token.
          */
@@ -855,7 +935,7 @@
         /**
          * Called when the addressed player is changed to the media button receiver.
          * <p>One of the {@ #onAddressedPlayerChanged} will be also called immediately after
-         * {@link #setCallback} if the addressed player exists.
+         * {@link #registerCallback} if the addressed player exists.
          *
          * @param mediaButtonReceiver The media button receiver.
          */
@@ -1061,56 +1141,52 @@
         }
     }
 
-    private static final class CallbackImpl extends ICallback.Stub {
-        private final Callback mCallback;
-        private final Handler mHandler;
-
-        public CallbackImpl(@NonNull Callback callback, @NonNull Handler handler) {
-            mCallback = callback;
-            mHandler = handler;
-        }
+    private final class CallbackStub extends ICallback.Stub {
 
         @Override
         public void onMediaKeyEventDispatchedToMediaSession(KeyEvent event,
                 MediaSession.Token sessionToken) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mCallback.onMediaKeyEventDispatched(event, sessionToken);
+            synchronized (mLock) {
+                for (Map.Entry<Callback, Handler> e : mCallbacks.entrySet()) {
+                    e.getValue().post(
+                            () -> e.getKey().onMediaKeyEventDispatched(event, sessionToken));
                 }
-            });
+            }
         }
 
         @Override
         public void onMediaKeyEventDispatchedToMediaButtonReceiver(KeyEvent event,
                 ComponentName mediaButtonReceiver) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mCallback.onMediaKeyEventDispatched(event, mediaButtonReceiver);
+            synchronized (mLock) {
+                for (Map.Entry<Callback, Handler> e : mCallbacks.entrySet()) {
+                    e.getValue().post(
+                            () -> e.getKey().onMediaKeyEventDispatched(event, mediaButtonReceiver));
                 }
-            });
+            }
         }
 
         @Override
         public void onAddressedPlayerChangedToMediaSession(MediaSession.Token sessionToken) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mCallback.onAddressedPlayerChanged(sessionToken);
+            synchronized (mLock) {
+                mCurMediaButtonSession = sessionToken;
+                mCurMediaButtonReceiver = null;
+                for (Map.Entry<Callback, Handler> e : mCallbacks.entrySet()) {
+                    e.getValue().post(() -> e.getKey().onAddressedPlayerChanged(sessionToken));
                 }
-            });
+            }
         }
 
         @Override
         public void onAddressedPlayerChangedToMediaButtonReceiver(
                 ComponentName mediaButtonReceiver) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mCallback.onAddressedPlayerChanged(mediaButtonReceiver);
+            synchronized (mLock) {
+                mCurMediaButtonSession = null;
+                mCurMediaButtonReceiver = mediaButtonReceiver;
+                for (Map.Entry<Callback, Handler> e : mCallbacks.entrySet()) {
+                    e.getValue().post(() -> e.getKey().onAddressedPlayerChanged(
+                            mediaButtonReceiver));
                 }
-            });
+            }
         }
     }
 }
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index 06bd692..e09eeb8 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -277,28 +277,36 @@
     @Override
     public boolean equals(Object o) {
         if (this == o) {
-          return true;
+            return true;
         }
 
         if (!(o instanceof TvTrackInfo)) {
-          return false;
+            return false;
         }
 
         TvTrackInfo obj = (TvTrackInfo) o;
-        return TextUtils.equals(mId, obj.mId)
-                && mType == obj.mType
-                && TextUtils.equals(mLanguage, obj.mLanguage)
-                && TextUtils.equals(mDescription, obj.mDescription)
-                && mEncrypted == obj.mEncrypted
-                && Objects.equals(mExtra, obj.mExtra)
-                && (mType == TYPE_AUDIO
-                        ? mAudioChannelCount == obj.mAudioChannelCount
-                        && mAudioSampleRate == obj.mAudioSampleRate
-                        : (mType == TYPE_VIDEO
-                                ? mVideoWidth == obj.mVideoWidth
-                                && mVideoHeight == obj.mVideoHeight
-                                && mVideoFrameRate == obj.mVideoFrameRate
-                                && mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio : true));
+
+        if (!TextUtils.equals(mId, obj.mId) || mType != obj.mType
+                || !TextUtils.equals(mLanguage, obj.mLanguage)
+                || !TextUtils.equals(mDescription, obj.mDescription)
+                || !Objects.equals(mExtra, obj.mExtra)) {
+            return false;
+        }
+
+        switch (mType) {
+            case TYPE_AUDIO:
+                return mAudioChannelCount == obj.mAudioChannelCount
+                        && mAudioSampleRate == obj.mAudioSampleRate;
+
+            case TYPE_VIDEO:
+                return mVideoWidth == obj.mVideoWidth
+                        && mVideoHeight == obj.mVideoHeight
+                        && mVideoFrameRate == obj.mVideoFrameRate
+                        && mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio
+                        && mVideoActiveFormatDescription == obj.mVideoActiveFormatDescription;
+        }
+
+        return true;
     }
 
     @Override
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 4ac6d35..16ba63b 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -25,6 +25,7 @@
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
+import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.RemoteException;
@@ -47,6 +48,7 @@
 import com.google.android.collect.Sets;
 
 import java.io.File;
+import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
@@ -799,6 +801,54 @@
     }
 
     @VisibleForNative
+    private boolean getThumbnailInfo(int handle, long[] outLongs) {
+        MtpStorageManager.MtpObject obj = mManager.getObject(handle);
+        if (obj == null) {
+            return false;
+        }
+
+        String path = obj.getPath().toString();
+        switch (obj.getFormat()) {
+            case MtpConstants.FORMAT_HEIF:
+            case MtpConstants.FORMAT_EXIF_JPEG:
+            case MtpConstants.FORMAT_JFIF:
+                try {
+                    ExifInterface exif = new ExifInterface(path);
+                    long[] thumbOffsetAndSize = exif.getThumbnailRange();
+                    outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0;
+                    outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0);
+                    outLongs[2] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_Y_DIMENSION, 0);
+                    return true;
+                } catch (IOException e) {
+                    // ignore and fall through
+                }
+        }
+        return false;
+    }
+
+    @VisibleForNative
+    private byte[] getThumbnailData(int handle) {
+        MtpStorageManager.MtpObject obj = mManager.getObject(handle);
+        if (obj == null) {
+            return null;
+        }
+
+        String path = obj.getPath().toString();
+        switch (obj.getFormat()) {
+            case MtpConstants.FORMAT_HEIF:
+            case MtpConstants.FORMAT_EXIF_JPEG:
+            case MtpConstants.FORMAT_JFIF:
+                try {
+                    ExifInterface exif = new ExifInterface(path);
+                    return exif.getThumbnail();
+                } catch (IOException e) {
+                    // ignore and fall through
+                }
+        }
+        return null;
+    }
+
+    @VisibleForNative
     private int beginDeleteObject(int handle) {
         MtpStorageManager.MtpObject obj = mManager.getObject(handle);
         if (obj == null) {
diff --git a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
index 8238b8c..7e3f2f8 100644
--- a/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
+++ b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
@@ -19,7 +19,9 @@
      *         the playback of the media app.
      * @param extra Extras returned by the media service.
      */
+    @UnsupportedAppUsage
     void onConnect(String root, in MediaSession.Token session, in Bundle extras);
+    @UnsupportedAppUsage
     void onConnectFailed();
     void onLoadChildren(String mediaId, in ParceledListSlice list);
     void onLoadChildrenWithOptions(String mediaId, in ParceledListSlice list,
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 04545e8..c49b1e4 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -47,7 +47,6 @@
         "libstagefright_foundation",
         "libcamera_client",
         "libmtp",
-        "libexif",
         "libpiex",
         "libprocessgroup",
         "libandroidfw",
@@ -149,7 +148,6 @@
         "libhidlbase",
         "libhidlmemory",
         "libhidltransport",
-        "libhwbinder_noltopgo",
         "libbinderthreadstate",
 
         // MediaPlayer2 implementation
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 7168b2d..0a02156 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -360,10 +360,8 @@
           __FUNCTION__, width, height, format, maxImages);
 
     PublicFormat publicFormat = static_cast<PublicFormat>(format);
-    nativeFormat = android_view_Surface_mapPublicFormatToHalFormat(
-        publicFormat);
-    nativeDataspace = android_view_Surface_mapPublicFormatToHalDataspace(
-        publicFormat);
+    nativeFormat = mapPublicFormatToHalFormat(publicFormat);
+    nativeDataspace = mapPublicFormatToHalDataspace(publicFormat);
 
     jclass clazz = env->GetObjectClass(thiz);
     if (clazz == NULL) {
@@ -418,11 +416,13 @@
     if (res != OK) {
         jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                           "Failed to set buffer consumer default format 0x%x", nativeFormat);
+        return;
     }
     res = bufferConsumer->setDefaultBufferDataSpace(nativeDataspace);
     if (res != OK) {
         jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
                           "Failed to set buffer consumer default dataSpace 0x%x", nativeDataspace);
+        return;
     }
 }
 
@@ -706,7 +706,7 @@
     // and we don't set them here.
 }
 
-static void Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx,
+static bool Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx,
         int32_t writerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) {
     ALOGV("%s", __FUNCTION__);
 
@@ -715,7 +715,9 @@
     if (res != OK) {
         jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException",
                              "Pixel format: 0x%x is unsupported", buffer->flexFormat);
+        return false;
     }
+    return true;
 }
 
 static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
@@ -729,8 +731,7 @@
     jobject byteBuffer = NULL;
 
     PublicFormat publicReaderFormat = static_cast<PublicFormat>(readerFormat);
-    int halReaderFormat = android_view_Surface_mapPublicFormatToHalFormat(
-        publicReaderFormat);
+    int halReaderFormat = mapPublicFormatToHalFormat(publicReaderFormat);
 
     if (isFormatOpaque(halReaderFormat) && numPlanes > 0) {
         String8 msg;
@@ -759,8 +760,10 @@
     }
     // Create all SurfacePlanes
     for (int i = 0; i < numPlanes; i++) {
-        Image_getLockedImageInfo(env, &lockedImg, i, halReaderFormat,
-                &pData, &dataSize, &pixelStride, &rowStride);
+        if (!Image_getLockedImageInfo(env, &lockedImg, i, halReaderFormat,
+                &pData, &dataSize, &pixelStride, &rowStride)) {
+            return NULL;
+        }
         byteBuffer = env->NewDirectByteBuffer(pData, dataSize);
         if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) {
             jniThrowException(env, "java/lang/IllegalStateException",
@@ -796,8 +799,7 @@
         return static_cast<jint>(PublicFormat::PRIVATE);
     } else {
         BufferItem* buffer = Image_getBufferItem(env, thiz);
-        int readerHalFormat = android_view_Surface_mapPublicFormatToHalFormat(
-                static_cast<PublicFormat>(readerFormat));
+        int readerHalFormat = mapPublicFormatToHalFormat(static_cast<PublicFormat>(readerFormat));
         int32_t fmt = applyFormatOverrides(
                 buffer->mGraphicBuffer->getPixelFormat(), readerHalFormat);
         // Override the image format to HAL_PIXEL_FORMAT_YCbCr_420_888 if the actual format is
@@ -808,8 +810,7 @@
         if (isPossiblyYUV(fmt)) {
             fmt = HAL_PIXEL_FORMAT_YCbCr_420_888;
         }
-        PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat(
-                fmt, buffer->mDataSpace);
+        PublicFormat publicFmt = mapHalFormatDataspaceToPublicFormat(fmt, buffer->mDataSpace);
         return static_cast<jint>(publicFmt);
     }
 }
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index cfcba76..6d8b966 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -777,6 +777,7 @@
         status_t res = buffer->unlock();
         if (res != OK) {
             jniThrowRuntimeException(env, "unlock buffer failed");
+            return;
         }
         ALOGV("Successfully unlocked the image");
     }
@@ -819,8 +820,8 @@
     }
 
     // ImageWriter doesn't support data space yet, assuming it is unknown.
-    PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat(
-            buffer->getPixelFormat(), HAL_DATASPACE_UNKNOWN);
+    PublicFormat publicFmt = mapHalFormatDataspaceToPublicFormat(buffer->getPixelFormat(),
+                                                                 HAL_DATASPACE_UNKNOWN);
     return static_cast<jint>(publicFmt);
 }
 
@@ -872,7 +873,7 @@
     // and we don't set them here.
 }
 
-static void Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx,
+static bool Image_getLockedImageInfo(JNIEnv* env, LockedImage* buffer, int idx,
         int32_t writerFormat, uint8_t **base, uint32_t *size, int *pixelStride, int *rowStride) {
     ALOGV("%s", __FUNCTION__);
 
@@ -880,8 +881,10 @@
             pixelStride, rowStride);
     if (res != OK) {
         jniThrowExceptionFmt(env, "java/lang/UnsupportedOperationException",
-                             "Pixel format: 0x%x is unsupported", buffer->flexFormat);
+                             "Pixel format: 0x%x is unsupported", writerFormat);
+        return false;
     }
+    return true;
 }
 
 static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
@@ -918,10 +921,12 @@
 
     // Create all SurfacePlanes
     PublicFormat publicWriterFormat = static_cast<PublicFormat>(writerFormat);
-    writerFormat = android_view_Surface_mapPublicFormatToHalFormat(publicWriterFormat);
+    writerFormat = mapPublicFormatToHalFormat(publicWriterFormat);
     for (int i = 0; i < numPlanes; i++) {
-        Image_getLockedImageInfo(env, &lockedImg, i, writerFormat,
-                &pData, &dataSize, &pixelStride, &rowStride);
+        if (!Image_getLockedImageInfo(env, &lockedImg, i, writerFormat,
+                &pData, &dataSize, &pixelStride, &rowStride)) {
+            return NULL;
+        }
         byteBuffer = env->NewDirectByteBuffer(pData, dataSize);
         if ((byteBuffer == NULL) && (env->ExceptionCheck() == false)) {
             jniThrowException(env, "java/lang/IllegalStateException",
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 150b6f9..8d420e2 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -211,21 +211,22 @@
 }
 
 void JMediaCodec::release() {
-    if (mCodec != NULL) {
-        mCodec->release();
-        mCodec.clear();
-        mInitStatus = NO_INIT;
-    }
+    std::call_once(mReleaseFlag, [this] {
+        if (mCodec != NULL) {
+            mCodec->release();
+            mInitStatus = NO_INIT;
+        }
 
-    if (mLooper != NULL) {
-        mLooper->unregisterHandler(id());
-        mLooper->stop();
-        mLooper.clear();
-    }
+        if (mLooper != NULL) {
+            mLooper->unregisterHandler(id());
+            mLooper->stop();
+            mLooper.clear();
+        }
+    });
 }
 
 JMediaCodec::~JMediaCodec() {
-    if (mCodec != NULL || mLooper != NULL) {
+    if (mLooper != NULL) {
         /* MediaCodec and looper should have been released explicitly already
          * in setMediaCodec() (see comments in setMediaCodec()).
          *
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index de08550..dfe30a3 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -17,6 +17,8 @@
 #ifndef _ANDROID_MEDIA_MEDIACODEC_H_
 #define _ANDROID_MEDIA_MEDIACODEC_H_
 
+#include <mutex>
+
 #include "jni.h"
 
 #include <media/MediaAnalyticsItem.h>
@@ -156,6 +158,7 @@
     sp<ALooper> mLooper;
     sp<MediaCodec> mCodec;
     AString mNameAtCreation;
+    std::once_flag mReleaseFlag;
 
     sp<AMessage> mCallbackNotification;
     sp<AMessage> mOnFrameRenderedNotification;
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index a480784..3809bc4 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -501,15 +501,7 @@
         return NULL;
     }
 
-    int colorFormat = getColorFormat(env, params);
 
-    std::vector<sp<IMemory> > frames;
-    status_t err = retriever->getFrameAtIndex(&frames, frameIndex, numFrames, colorFormat);
-    if (err != OK || frames.size() == 0) {
-        jniThrowException(env,
-                "java/lang/IllegalStateException", "No frames from retriever");
-        return NULL;
-    }
     jobject arrayList = env->NewObject(fields.arrayListClazz, fields.arrayListInit);
     if (arrayList == NULL) {
         jniThrowException(env,
@@ -517,18 +509,29 @@
         return NULL;
     }
 
+    int colorFormat = getColorFormat(env, params);
     SkColorType outColorType = setOutColorType(env, colorFormat, params);
-
-    for (size_t i = 0; i < frames.size(); i++) {
-        if (frames[i] == NULL || frames[i]->pointer() == NULL) {
+    size_t i = 0;
+    for (; i < numFrames; i++) {
+        sp<IMemory> frame = retriever->getFrameAtIndex(frameIndex + i, colorFormat);
+        if (frame == NULL || frame->pointer() == NULL) {
             ALOGE("video frame at index %zu is a NULL pointer", frameIndex + i);
-            continue;
+            break;
         }
-        VideoFrame *videoFrame = static_cast<VideoFrame *>(frames[i]->pointer());
+        VideoFrame *videoFrame = static_cast<VideoFrame *>(frame->pointer());
         jobject bitmapObj = getBitmapFromVideoFrame(env, videoFrame, -1, -1, outColorType);
         env->CallBooleanMethod(arrayList, fields.arrayListAdd, bitmapObj);
         env->DeleteLocalRef(bitmapObj);
     }
+
+    if (i == 0) {
+        env->DeleteLocalRef(arrayList);
+
+        jniThrowException(env,
+                "java/lang/IllegalStateException", "No frames from retriever");
+        return NULL;
+    }
+
     return arrayList;
 }
 
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 1f89d86..0a3b47b 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -30,13 +30,6 @@
 #include "src/piex_types.h"
 #include "src/piex.h"
 
-extern "C" {
-#include "libexif/exif-content.h"
-#include "libexif/exif-data.h"
-#include "libexif/exif-tag.h"
-#include "libexif/exif-utils.h"
-}
-
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/Log.h>
 #include <jni.h>
@@ -70,6 +63,8 @@
 static jmethodID method_getObjectPropertyList;
 static jmethodID method_getObjectInfo;
 static jmethodID method_getObjectFilePath;
+static jmethodID method_getThumbnailInfo;
+static jmethodID method_getThumbnailData;
 static jmethodID method_beginDeleteObject;
 static jmethodID method_endDeleteObject;
 static jmethodID method_beginMoveObject;
@@ -219,7 +214,7 @@
         return; // Already threw.
     }
     mIntBuffer = (jintArray)env->NewGlobalRef(intArray);
-    jlongArray longArray = env->NewLongArray(2);
+    jlongArray longArray = env->NewLongArray(3);
     if (!longArray) {
         return; // Already threw.
     }
@@ -780,57 +775,6 @@
     return result;
 }
 
-static void foreachentry(ExifEntry *entry, void* /* user */) {
-    char buf[1024];
-    ALOGI("entry %x, format %d, size %d: %s",
-            entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf)));
-}
-
-static void foreachcontent(ExifContent *content, void *user) {
-    ALOGI("content %d", exif_content_get_ifd(content));
-    exif_content_foreach_entry(content, foreachentry, user);
-}
-
-static long getLongFromExifEntry(ExifEntry *e) {
-    ExifByteOrder o = exif_data_get_byte_order(e->parent->parent);
-    return exif_get_long(e->data, o);
-}
-
-static ExifData *getExifFromExtractor(const char *path) {
-    std::unique_ptr<uint8_t[]> exifBuf;
-    ExifData *exifdata = NULL;
-
-    FILE *fp = fopen (path, "rb");
-    if (!fp) {
-        ALOGE("failed to open file");
-        return NULL;
-    }
-
-    sp<NuMediaExtractor> extractor = new NuMediaExtractor();
-    fseek(fp, 0L, SEEK_END);
-    if (extractor->setDataSource(fileno(fp), 0, ftell(fp)) != OK) {
-        ALOGE("failed to setDataSource");
-        fclose(fp);
-        return NULL;
-    }
-
-    off64_t offset;
-    size_t size;
-    if (extractor->getExifOffsetSize(&offset, &size) != OK) {
-        fclose(fp);
-        return NULL;
-    }
-
-    exifBuf.reset(new uint8_t[size]);
-    fseek(fp, offset, SEEK_SET);
-    if (fread(exifBuf.get(), 1, size, fp) == size) {
-        exifdata = exif_data_new_from_data(exifBuf.get(), size);
-    }
-
-    fclose(fp);
-    return exifdata;
-}
-
 MtpResponseCode MtpDatabase::getObjectInfo(MtpObjectHandle handle,
                                              MtpObjectInfo& info) {
     MtpStringBuffer path;
@@ -877,26 +821,23 @@
         case MTP_FORMAT_EXIF_JPEG:
         case MTP_FORMAT_HEIF:
         case MTP_FORMAT_JFIF: {
-            ExifData *exifdata;
-            if (info.mFormat == MTP_FORMAT_HEIF) {
-                exifdata = getExifFromExtractor(path);
-            } else {
-                exifdata = exif_data_new_from_file(path);
-            }
-            if (exifdata) {
-                if ((false)) {
-                    exif_data_foreach_content(exifdata, foreachcontent, NULL);
-                }
+            env = AndroidRuntime::getJNIEnv();
+            if (env->CallBooleanMethod(
+                    mDatabase, method_getThumbnailInfo, (jint)handle, mLongBuffer)) {
 
-                ExifEntry *w = exif_content_get_entry(
-                        exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_X_DIMENSION);
-                ExifEntry *h = exif_content_get_entry(
-                        exifdata->ifd[EXIF_IFD_EXIF], EXIF_TAG_PIXEL_Y_DIMENSION);
-                info.mThumbCompressedSize = exifdata->data ? exifdata->size : 0;
-                info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
-                info.mImagePixWidth = w ? getLongFromExifEntry(w) : 0;
-                info.mImagePixHeight = h ? getLongFromExifEntry(h) : 0;
-                exif_data_unref(exifdata);
+                jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
+                jlong size = longValues[0];
+                jlong w = longValues[1];
+                jlong h = longValues[2];
+                if (size > 0 && size <= UINT32_MAX &&
+                        w > 0 && w <= UINT32_MAX &&
+                        h > 0 && h <= UINT32_MAX) {
+                    info.mThumbCompressedSize = size;
+                    info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
+                    info.mImagePixWidth = w;
+                    info.mImagePixHeight = h;
+                }
+                env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
             }
             break;
         }
@@ -941,22 +882,19 @@
             case MTP_FORMAT_EXIF_JPEG:
             case MTP_FORMAT_HEIF:
             case MTP_FORMAT_JFIF: {
-                ExifData *exifdata;
-                if (format == MTP_FORMAT_HEIF) {
-                    exifdata = getExifFromExtractor(path);
-                } else {
-                    exifdata = exif_data_new_from_file(path);
+                JNIEnv* env = AndroidRuntime::getJNIEnv();
+                jbyteArray thumbData = (jbyteArray) env->CallObjectMethod(
+                        mDatabase, method_getThumbnailData, (jint)handle);
+                if (thumbData == NULL) {
+                    return nullptr;
                 }
-                if (exifdata) {
-                    if (exifdata->data) {
-                        result = malloc(exifdata->size);
-                        if (result) {
-                            memcpy(result, exifdata->data, exifdata->size);
-                            outThumbSize = exifdata->size;
-                        }
-                    }
-                    exif_data_unref(exifdata);
+                jsize thumbSize = env->GetArrayLength(thumbData);
+                result = malloc(thumbSize);
+                if (result) {
+                    env->GetByteArrayRegion(thumbData, 0, thumbSize, (jbyte*)result);
+                    outThumbSize = thumbSize;
                 }
+                env->DeleteLocalRef(thumbData);
                 break;
             }
 
@@ -1389,6 +1327,8 @@
     GET_METHOD_ID(getObjectPropertyList, clazz, "(IIIII)Landroid/mtp/MtpPropertyList;");
     GET_METHOD_ID(getObjectInfo, clazz, "(I[I[C[J)Z");
     GET_METHOD_ID(getObjectFilePath, clazz, "(I[C[J)I");
+    GET_METHOD_ID(getThumbnailInfo, clazz, "(I[J)Z");
+    GET_METHOD_ID(getThumbnailData, clazz, "(I)[B");
     GET_METHOD_ID(beginDeleteObject, clazz, "(I)I");
     GET_METHOD_ID(endDeleteObject, clazz, "(IZ)V");
     GET_METHOD_ID(beginMoveObject, clazz, "(III)I");
diff --git a/media/proto/Android.bp b/media/proto/Android.bp
index 74fd525..2dc0d57 100644
--- a/media/proto/Android.bp
+++ b/media/proto/Android.bp
@@ -5,7 +5,6 @@
         type: "lite",
     },
     srcs: ["mediaplayer2.proto"],
-    no_framework_libs: true,
     jarjar_rules: "jarjar-rules.txt",
     sdk_version: "28",
 }
diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
index 21cb93d..1267aa8 100644
--- a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
+++ b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
@@ -32,19 +32,35 @@
     public static final String ROUTE_NAME1 = "Sample Route 1";
     public static final String ROUTE_ID2 = "route_id2";
     public static final String ROUTE_NAME2 = "Sample Route 2";
+
+    public static final String ROUTE_ID_SPECIAL_CATEGORY = "route_special_category";
+    public static final String ROUTE_NAME_SPECIAL_CATEGORY = "Special Category Route";
+
     public static final String ACTION_REMOVE_ROUTE =
             "com.android.mediarouteprovider.action_remove_route";
 
+    public static final String CATEGORY_SAMPLE =
+            "com.android.mediarouteprovider.CATEGORY_SAMPLE";
+    public static final String CATEGORY_SPECIAL =
+            "com.android.mediarouteprovider.CATEGORY_SPECIAL";
+
     Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
 
     private void initializeRoutes() {
         MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1)
+                .addSupportedCategory(CATEGORY_SAMPLE)
                 .build();
         MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2)
+                .addSupportedCategory(CATEGORY_SAMPLE)
                 .build();
-
+        MediaRoute2Info routeSpecial =
+                new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_CATEGORY, ROUTE_NAME_SPECIAL_CATEGORY)
+                        .addSupportedCategory(CATEGORY_SAMPLE)
+                        .addSupportedCategory(CATEGORY_SPECIAL)
+                        .build();
         mRoutes.put(route1.getId(), route1);
         mRoutes.put(route2.getId(), route2);
+        mRoutes.put(routeSpecial.getId(), routeSpecial);
     }
 
     @Override
@@ -59,8 +75,26 @@
     }
 
     @Override
-    public void onSelect(int uid, String routeId) {
-        updateProvider(uid, routeId);
+    public void onSelectRoute(String packageName, String routeId) {
+        MediaRoute2Info route = mRoutes.get(routeId);
+        if (route == null) {
+            return;
+        }
+        mRoutes.put(routeId, new MediaRoute2Info.Builder(route)
+                .setClientPackageName(packageName)
+                .build());
+        publishRoutes();
+    }
+
+    @Override
+    public void onUnselectRoute(String packageName, String routeId) {
+        MediaRoute2Info route = mRoutes.get(routeId);
+        if (route == null) {
+            return;
+        }
+        mRoutes.put(routeId, new MediaRoute2Info.Builder(route)
+                .setClientPackageName(null)
+                .build());
         publishRoutes();
     }
 
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 41a76bf..4282a5bc 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -16,8 +16,9 @@
 
 package com.android.mediaroutertest;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.after;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
@@ -30,13 +31,18 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.text.TextUtils;
 
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -47,30 +53,38 @@
 public class MediaRouterManagerTest {
     private static final String TAG = "MediaRouterManagerTest";
 
-    private static final int TARGET_UID = 109992;
-
     // Must be the same as SampleMediaRoute2ProviderService
     public static final String ROUTE_ID1 = "route_id1";
     public static final String ROUTE_NAME1 = "Sample Route 1";
     public static final String ROUTE_ID2 = "route_id2";
     public static final String ROUTE_NAME2 = "Sample Route 2";
+
+    public static final String ROUTE_ID_SPECIAL_CATEGORY = "route_special_category";
+    public static final String ROUTE_NAME_SPECIAL_CATEGORY = "Special Category Route";
+
     public static final String ACTION_REMOVE_ROUTE =
             "com.android.mediarouteprovider.action_remove_route";
 
-    private static final int AWAIT_MS = 1000;
+    public static final String CATEGORY_SAMPLE =
+            "com.android.mediarouteprovider.CATEGORY_SAMPLE";
+    public static final String CATEGORY_SPECIAL =
+            "com.android.mediarouteprovider.CATEGORY_SPECIAL";
+
     private static final int TIMEOUT_MS = 5000;
 
     private Context mContext;
     private MediaRouter2Manager mManager;
     private MediaRouter2 mRouter;
     private Executor mExecutor;
+    private String mPackageName;
 
-    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";
+    private static final List<String> CONTROL_CATEGORIES_ALL = new ArrayList();
+    private static final List<String> CONTROL_CATEGORIES_SPECIAL = new ArrayList();
     static {
-        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_1);
-        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_2);
+        CONTROL_CATEGORIES_ALL.add(CATEGORY_SAMPLE);
+        CONTROL_CATEGORIES_ALL.add(CATEGORY_SPECIAL);
+
+        CONTROL_CATEGORIES_SPECIAL.add(CATEGORY_SPECIAL);
     }
 
     @Before
@@ -81,6 +95,20 @@
         mExecutor = new ThreadPoolExecutor(
             1, 20, 3, TimeUnit.SECONDS,
             new SynchronousQueue<Runnable>());
+        mPackageName = mContext.getPackageName();
+    }
+
+    @Test
+    public void testMediaRoute2Info() {
+        MediaRoute2Info routeInfo1 = new MediaRoute2Info.Builder("id", "name")
+                .build();
+        MediaRoute2Info routeInfo2 = new MediaRoute2Info.Builder(routeInfo1).build();
+
+        MediaRoute2Info routeInfo3 = new MediaRoute2Info.Builder(routeInfo1)
+                .setClientPackageName(mPackageName).build();
+
+        assertEquals(routeInfo1, routeInfo2);
+        assertNotEquals(routeInfo1, routeInfo3);
     }
 
     //TODO: Test onRouteChanged when it's properly implemented.
@@ -96,7 +124,7 @@
         mManager.removeCallback(mockCallback);
     }
 
-    @Test
+    //TODO: Recover this test when media router 2 is finalized.
     public void testRouteRemoved() {
         MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
         mManager.addCallback(mExecutor, mockCallback);
@@ -107,7 +135,7 @@
         // (Control requests shouldn't be used in this way.)
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
                 (Runnable) () -> {
-                    mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, mockRouterCallback);
+                    mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, mockRouterCallback);
                     mRouter.sendControlRequest(
                             new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2).build(),
                             new Intent(ACTION_REMOVE_ROUTE));
@@ -120,27 +148,124 @@
         mManager.removeCallback(mockCallback);
     }
 
+    /**
+     * Tests if we get proper routes for application that has special control category.
+     */
     @Test
-    public void controlCategoryTest() throws Exception {
-        final int uid = android.os.Process.myUid();
-
+    public void testControlCategory() throws Exception {
         MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
         mManager.addCallback(mExecutor, mockCallback);
 
         MediaRouter2.Callback mockRouterCallback = mock(MediaRouter2.Callback.class);
 
-        verify(mockCallback, after(AWAIT_MS).never()).onControlCategoriesChanged(uid,
-                TEST_CONTROL_CATEGORIES);
-
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
-                (Runnable) () -> {
-                    mRouter.addCallback(TEST_CONTROL_CATEGORIES, mExecutor, mockRouterCallback);
+                () -> {
+                    mRouter.addCallback(CONTROL_CATEGORIES_SPECIAL,
+                            mExecutor, mockRouterCallback);
                     mRouter.removeCallback(mockRouterCallback);
                 }
         );
-        verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
-                .onControlCategoriesChanged(uid, TEST_CONTROL_CATEGORIES);
+        verify(mockCallback, timeout(TIMEOUT_MS))
+                .onRouteListChanged(argThat(routes -> routes.size() > 0));
+
+        Map<String, MediaRoute2Info> routes =
+                createRouteMap(mManager.getAvailableRoutes(mPackageName));
+
+        Assert.assertEquals(1, routes.size());
+        Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
 
         mManager.removeCallback(mockCallback);
     }
+
+    @Test
+    public void onRouteSelectedTest() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+
+        MediaRouter2.Callback mockRouterCallback = mock(MediaRouter2.Callback.class);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                () -> {
+                    mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, mockRouterCallback);
+                }
+        );
+
+        MediaRouter2Manager.Callback managerCallback = new MediaRouter2Manager.Callback() {
+            MediaRoute2Info mSelectedRoute = null;
+
+            @Override
+            public void onRouteAdded(MediaRoute2Info routeInfo) {
+                if (mSelectedRoute == null) {
+                    mSelectedRoute = routeInfo;
+                    mManager.selectRoute(mPackageName, mSelectedRoute);
+                }
+            }
+
+            @Override
+            public void onRouteSelected(String packageName, MediaRoute2Info route) {
+                if (TextUtils.equals(packageName, mPackageName)
+                        && mSelectedRoute != null
+                        && route != null
+                        && TextUtils.equals(route.getId(), mSelectedRoute.getId())) {
+                    latch.countDown();
+                }
+            }
+        };
+
+        mManager.addCallback(mExecutor, managerCallback);
+
+        Assert.assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+        mManager.removeCallback(managerCallback);
+    }
+
+    /**
+     * Tests selecting and unselecting routes of a single provider.
+     */
+    @Test
+    public void testSingleProviderSelect() {
+        MediaRouter2Manager.Callback managerCallback = mock(MediaRouter2Manager.Callback.class);
+        MediaRouter2.Callback routerCallback = mock(MediaRouter2.Callback.class);
+
+        mManager.addCallback(mExecutor, managerCallback);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                () -> {
+                    mRouter.addCallback(CONTROL_CATEGORIES_ALL, mExecutor, routerCallback);
+                }
+        );
+        verify(managerCallback, timeout(TIMEOUT_MS))
+                .onRouteListChanged(argThat(routes -> routes.size() > 0));
+
+        Map<String, MediaRoute2Info> routes =
+                createRouteMap(mManager.getAvailableRoutes(mPackageName));
+
+        mManager.selectRoute(mPackageName, routes.get(ROUTE_ID1));
+        verify(managerCallback, timeout(TIMEOUT_MS)
+        )
+                .onRouteChanged(argThat(routeInfo -> TextUtils.equals(ROUTE_ID1, routeInfo.getId())
+                        && TextUtils.equals(routeInfo.getClientPackageName(), mPackageName)));
+
+        mManager.selectRoute(mPackageName, routes.get(ROUTE_ID2));
+        verify(managerCallback, timeout(TIMEOUT_MS))
+                .onRouteChanged(argThat(routeInfo -> TextUtils.equals(ROUTE_ID2, routeInfo.getId())
+                        && TextUtils.equals(routeInfo.getClientPackageName(), mPackageName)));
+
+        mManager.unselectRoute(mPackageName);
+        verify(managerCallback, timeout(TIMEOUT_MS))
+                .onRouteChanged(argThat(routeInfo -> TextUtils.equals(ROUTE_ID2, routeInfo.getId())
+                        && TextUtils.equals(routeInfo.getClientPackageName(), null)));
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                () -> {
+                    mRouter.removeCallback(routerCallback);
+                }
+        );
+        mManager.removeCallback(managerCallback);
+    }
+
+    Map<String, MediaRoute2Info> createRouteMap(List<MediaRoute2Info> routes) {
+        Map<String, MediaRoute2Info> routeMap = new HashMap<>();
+        for (MediaRoute2Info route : routes) {
+            routeMap.put(route.getId(), route);
+        }
+        return routeMap;
+    }
 }
diff --git a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
index d8155a6..a8c9d9e 100644
--- a/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fa/strings.xml
@@ -18,7 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="backup_confirm_title" msgid="827563724209303345">"پشتیبان‌گیری کامل"</string>
     <string name="restore_confirm_title" msgid="5469365809567486602">"بازیابی کامل"</string>
-    <string name="backup_confirm_text" msgid="1878021282758896593">"درخواست پشتیبان گیری کامل از تمام داده‌ها به یک رایانه دسک‌تاپ متصل داده شده است. آیا می‌خواهید این عمل انجام شود؟\n\nاگر شما درخواست تهیهٔ نسخهٔ پشتیبان را نداده‌اید، اجازه‌ ادامه عملیات را ندهید."</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"درخواست پشتیبان گیری کامل از تمام داده‌ها به یک رایانه دسک‌تاپ متصل داده شده است. آیا می‌خواهید این کار انجام شود؟\n\nاگر شما درخواست تهیهٔ نسخهٔ پشتیبان را نداده‌اید، اجازه‌ ادامه عملیات را ندهید."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"پشتیبان‌گیری از داده‌های من"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"نسخهٔ پشتیبان تهیه نشود"</string>
     <string name="restore_confirm_text" msgid="7499866728030461776">"بازیابی کامل تمام داده‌ها از یک رایانه دسک تاپ متصل درخواست شده است. آیا می‌خواهید این اجازه را بدهید؟\n\nاگر خود شما درخواست بازیابی نداده‌اید، اجازه ادامه این عملیات را ندهید. با این کار همه داده‌هایی که اکنون روی دستگاه است جایگزین می‌شود!"</string>
@@ -31,9 +31,9 @@
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"اگر می‌خواهید تمام نسخه پشتیبانی داده را رمزدار کنید، یک گذرواژه در زیر وارد کنید:"</string>
     <string name="backup_enc_password_required" msgid="7889652203371654149">"چون دستگاهتان رمز‌گذاری شده است، باید نسخه پشتیبان خودتان را رمزگذاری کنید. لطفاً گذرواژه‌ای را در زیر وارد کنید:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"اگر داده بازیابی شده رمزگذاری شده است، لطفاً گذرواژه را در زیر وارد کنید:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"شروع پشتیبان‌گیری..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"پشتیبان‌گیری پایان یافت"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"شروع بازیابی..."</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"شروع پشتیبان‌گیری…"</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"پشتیبان‌گیری تمام شد"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"شروع بازیابی…"</string>
     <string name="toast_restore_ended" msgid="1764041639199696132">"بازیابی پایان یافت"</string>
     <string name="toast_timeout" msgid="5276598587087626877">"مهلت عملیات تمام شد"</string>
 </resources>
diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp
deleted file mode 100644
index 1f6c2ae..0000000
--- a/packages/CaptivePortalLogin/Android.bp
+++ /dev/null
@@ -1,43 +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.
-//
-
-java_defaults {
-    name: "CaptivePortalLoginDefaults",
-    srcs: ["src/**/*.java"],
-    sdk_version: "system_current",
-    min_sdk_version: "28",
-    static_libs: [
-        "androidx.legacy_legacy-support-v4",
-        "metrics-constants-protos",
-        "captiveportal-lib",
-    ],
-    manifest: "AndroidManifest.xml",
-}
-
-android_app {
-    name: "CaptivePortalLogin",
-    defaults: ["CaptivePortalLoginDefaults"],
-    certificate: "networkstack",
-}
-
-// Alternative CaptivePortalLogin signed with the platform cert, to use
-// with InProcessNetworkStack.
-android_app {
-    name: "PlatformCaptivePortalLogin",
-    defaults: ["CaptivePortalLoginDefaults"],
-    certificate: "platform",
-    overrides: ["CaptivePortalLogin"],
-}
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
deleted file mode 100644
index 86d6d44..0000000
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.captiveportallogin"
-    android:versionCode="220000000"
-    android:versionName="Q-initial">
-
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
-    <uses-permission android:name="android.permission.NETWORK_BYPASS_PRIVATE_DNS" />
-    <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
-
-    <application android:label="@string/app_name"
-                 android:icon="@drawable/app_icon"
-                 android:usesCleartextTraffic="true"
-                 android:supportsRtl="true" >
-        <activity
-            android:name="com.android.captiveportallogin.CaptivePortalLoginActivity"
-            android:label="@string/action_bar_label"
-            android:theme="@style/AppTheme"
-            android:configChanges="keyboardHidden|orientation|screenSize" >
-            <intent-filter>
-                <action android:name="android.net.conn.CAPTIVE_PORTAL"/>
-                <category android:name="android.intent.category.DEFAULT"/>
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/packages/CaptivePortalLogin/OWNERS b/packages/CaptivePortalLogin/OWNERS
deleted file mode 100644
index d3836d4..0000000
--- a/packages/CaptivePortalLogin/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-set noparent
-
-codewiz@google.com
-jchalard@google.com
-junyulai@google.com
-lorenzo@google.com
-reminv@google.com
-satk@google.com
diff --git a/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png b/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png
deleted file mode 100644
index 08294ce..0000000
--- a/packages/CaptivePortalLogin/assets/quantum_ic_warning_amber_96.png
+++ /dev/null
Binary files differ
diff --git a/packages/CaptivePortalLogin/res/drawable/app_icon.xml b/packages/CaptivePortalLogin/res/drawable/app_icon.xml
deleted file mode 100644
index 456ca83..0000000
--- a/packages/CaptivePortalLogin/res/drawable/app_icon.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background>
-        <color android:color="@*android:color/accent_device_default_light" />
-    </background>
-    <foreground>
-        <inset
-            android:drawable="@drawable/maybe_wifi"
-            android:inset="25%">
-        </inset>
-    </foreground>
-</adaptive-icon>
diff --git a/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml b/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml
deleted file mode 100644
index 207aade..0000000
--- a/packages/CaptivePortalLogin/res/drawable/maybe_wifi.xml
+++ /dev/null
@@ -1,27 +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="26.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="26.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#4DFFFFFF"
-        android:pathData="M19.1,14l-3.4,0l0,-1.5c0,-1.8 0.8,-2.8 1.5,-3.4C18.1,8.3 19.200001,8 20.6,8c1.2,0 2.3,0.3 3.1,0.8l1.9,-2.3C25.1,6.1 20.299999,2.1 13,2.1S0.9,6.1 0.4,6.5L13,22l0,0l0,0l0,0l0,0l6.5,-8.1L19.1,14z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M19.5,17.799999c0,-0.8 0.1,-1.3 0.2,-1.6c0.2,-0.3 0.5,-0.7 1.1,-1.2c0.4,-0.4 0.7,-0.8 1,-1.1s0.4,-0.8 0.4,-1.2c0,-0.5 -0.1,-0.9 -0.4,-1.2c-0.3,-0.3 -0.7,-0.4 -1.2,-0.4c-0.4,0 -0.8,0.1 -1.1,0.3c-0.3,0.2 -0.4,0.6 -0.4,1.1l-1.9,0c0,-1 0.3,-1.7 1,-2.2c0.6,-0.5 1.5,-0.8 2.5,-0.8c1.1,0 2,0.3 2.6,0.8c0.6,0.5 0.9,1.3 0.9,2.3c0,0.7 -0.2,1.3 -0.6,1.8c-0.4,0.6 -0.9,1.1 -1.5,1.6c-0.3,0.3 -0.5,0.5 -0.6,0.7c-0.1,0.2 -0.1,0.6 -0.1,1L19.5,17.700001zM21.4,21l-1.9,0l0,-1.8l1.9,0L21.4,21z"/>
-</vector>
diff --git a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml b/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
deleted file mode 100644
index f095d4e..0000000
--- a/packages/CaptivePortalLogin/res/layout/activity_captive_portal_login.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/container"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity"
-    tools:ignore="MergeRootFrame" >
-
-    <LinearLayout
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
-
-      <FrameLayout
-          android:layout_width="match_parent"
-          android:layout_height="4dp" >
-
-        <!-- Eliminates ProgressBar padding by boxing it into a 4dp high container -->
-        <ProgressBar
-            android:id="@+id/progress_bar"
-            style="@android:style/Widget.Material.Light.ProgressBar.Horizontal"
-            android:indeterminate="false"
-            android:max="100"
-            android:progress="0"
-            android:layout_gravity="center"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-      </FrameLayout>
-
-      <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-            android:id="@+id/swipe_refresh"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent">
-        <WebView
-              android:id="@+id/webview"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"
-              android:layout_alignParentBottom="false"
-              android:layout_alignParentRight="false" />
-      </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
-
-    </LinearLayout>
-</FrameLayout>
diff --git a/packages/CaptivePortalLogin/res/layout/ssl_warning.xml b/packages/CaptivePortalLogin/res/layout/ssl_warning.xml
deleted file mode 100644
index ce05e78..0000000
--- a/packages/CaptivePortalLogin/res/layout/ssl_warning.xml
+++ /dev/null
@@ -1,97 +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="wrap_content"
-    android:orientation="vertical" >
-
-    <!-- ssl error type -->
-    <TextView
-        android:id="@+id/ssl_error_type"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_gravity="start"
-        android:text="SSL_UNKNOWN"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip"
-        android:layout_marginBottom="0dip"
-        android:layout_marginTop="24dip" />
-
-    <!-- Page info: -->
-    <TextView
-        android:id="@+id/page_info"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="@string/page_info"
-        android:textStyle="bold"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <!-- Title: -->
-    <TextView
-        android:id="@+id/title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textStyle="bold"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <!-- Address: -->
-    <TextView
-        android:id="@+id/address_header"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:text="@string/page_info_address"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <TextView
-        android:id="@+id/address"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="24dip"
-        android:layout_marginEnd="24dip" />
-
-    <ScrollView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingStart="4dip"
-        android:paddingEnd="4dip" >
-
-        <!-- certificate view: -->
-        <LinearLayout
-            android:id="@+id/certificate_layout"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:layout_marginBottom="16dip" >
-            <TextView
-                android:id="@+id/ssl_error_msg"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:textAppearance="?android:attr/textAppearanceSmall"
-                android:layout_marginStart="20dip"
-                android:layout_marginEnd="20dip"
-                android:gravity="center_vertical"
-                android:layout_marginBottom="4dip"
-                android:layout_marginTop="16dip" />
-        </LinearLayout>
-
-    </ScrollView>
-
-</LinearLayout>
diff --git a/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml b/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml
deleted file mode 100644
index 1a88c5c..0000000
--- a/packages/CaptivePortalLogin/res/menu/captive_portal_login.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    tools:context="com.android.captiveportallogin.CaptivePortalLoginActivity" >
-    <item
-        android:id="@+id/action_do_not_use_network"
-        android:orderInCategory="100"
-        android:showAsAction="never"
-        android:title="@string/action_do_not_use_network"/>
-    <item
-        android:id="@+id/action_use_network"
-        android:orderInCategory="200"
-        android:showAsAction="never"
-        android:title="@string/action_use_network"/>
-
-</menu>
diff --git a/packages/CaptivePortalLogin/res/values-af/strings.xml b/packages/CaptivePortalLogin/res/values-af/strings.xml
deleted file mode 100644
index 37acf45..0000000
--- a/packages/CaptivePortalLogin/res/values-af/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortal-aanmelding"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gebruik hierdie netwerk nes dit is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Moenie hierdie netwerk gebruik nie"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Meld by netwerk aan"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Meld aan by %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Die netwerk waarby jy probeer aansluit, het sekuriteitkwessies."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Byvoorbeeld, die aanmeldbladsy behoort dalk nie aan die organisasie wat gewys word nie."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Gaan in elk geval deur blaaier voort"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Hierdie sertifikaat is nie van \'n betroubare owerheid nie."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Die naam van die werf stem nie ooreen met die naam op die sertifikaat nie."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Hierdie sertifikaat het verval."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Hierdie sertifikaat is nog nie geldig nie."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Hierdie sertifikaat het \'n ongeldige datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Hierdie sertifikaat is ongeldig."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Onbekende sertifikaatfout."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sekuriteitswaarskuwing"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Bekyk sertifikaat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adres:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Bladsy-inligting"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-am/strings.xml b/packages/CaptivePortalLogin/res/values-am/strings.xml
deleted file mode 100644
index 4e35e19..0000000
--- a/packages/CaptivePortalLogin/res/values-am/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ይህን አውታረ መረብ እንዳለ ተጠቀምበት"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ይህን አውታረ መረብ አትጠቀምበት"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ወደ አውታረ መረብ በመለያ ይግቡ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ወደ %1$s ይግቡ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ለመቀላቀል እየሞከሩ ያሉት አውታረ መረብ የደህንነት ችግሮች አሉበት።"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ለምሳሌ፣ የመግቢያ ገጹ የሚታየው ድርጅት ላይሆን ይችላል።"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ለማንኛውም በአሳሽ በኩል ይቀጥሉ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ይህ የእውቅና ማረጋገጫ ከታማኝ ቦታ አይደለም።"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"የጣቢያው ስም ከእውቅና ማረጋገጫው ስም ጋር አይዛመድም።"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ይህ የእውቅና ማረጋገጫ ጊዜው አልፏል።"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ይህ የእውቅና ማረጋገጫ ገና የሚሰራ አይደለም።"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ይህ የእውቅና ማረጋገጫ ልክ ያልሆነ ቀን ነው ያለው።"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ይህ የእውቅና ማረጋገጫ ልክ ያልሆነ ነው።"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ያልታወቀ የእውቅና ማረጋገጫ ስህተት።"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"የደህንነት ቅንብሮች"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"የእውቅና ማረጋገጫን ይመልከቱ"</string>
-    <string name="ok" msgid="2817931639040794018">"እሺ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"አድራሻ፦"</string>
-    <string name="page_info" msgid="4416941086705172545">"የገጽ መረጃ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ar/strings.xml b/packages/CaptivePortalLogin/res/values-ar/strings.xml
deleted file mode 100644
index 9f3aefa..0000000
--- a/packages/CaptivePortalLogin/res/values-ar/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"استخدام هذه الشبكة كما هي"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"عدم استخدام هذه الشبكة"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"تسجيل الدخول إلى الشبكة"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for action_bar_title (5645564790486983117) -->
-    <skip />
-    <string name="ssl_error_warning" msgid="6653188881418638872">"الشبكة التي تحاول الانضمام إليها بها مشاكل أمنية."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"على سبيل المثال، قد لا تنتمي صفحة تسجيل الدخول إلى المنظمة المعروضة."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"المتابعة على أي حال عبر المتصفح"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"هذه الشهادة ليست من جهة موثوق بها."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"لا يتطابق اسم الموقع مع الاسم على الشهادة."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"انتهت صلاحية هذه الشهادة."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"هذه الشهادة ليست صالحة بعد."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"تشتمل هذه الشهادة على تاريخ غير صالح."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"هذه الشهادة غير صالحة."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"حدث خطأ غير معروف بالشهادة."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"تحذير أمني"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"عرض الشهادة"</string>
-    <string name="ok" msgid="2817931639040794018">"حسنًا"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"العنوان:"</string>
-    <string name="page_info" msgid="4416941086705172545">"معلومات الصفحة"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-as/strings.xml b/packages/CaptivePortalLogin/res/values-as/strings.xml
deleted file mode 100644
index 696483c..0000000
--- a/packages/CaptivePortalLogin/res/values-as/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"এই নেটৱৰ্কটো এইদৰে ব্যৱহাৰ কৰক"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটৱৰ্কটো ব্যৱহাৰ নকৰিব"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"নেটৱৰ্কত ছাইন ইন কৰক"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$st ছাইন ইন কৰক"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"আপুনি সংযোগ কৰিবলৈ চেষ্টা কৰি থকা নেটৱৰ্কটোত সুৰক্ষাজনিত সমস্যা আছে।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"উদাহৰণস্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"তথাপি ব্ৰাউজাৰৰ জৰিয়তে অব্যাহত ৰাখক"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"এই প্ৰমাণপত্ৰখন কোনো বিশ্বাসী কর্তৃপক্ষৰ নহয়।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ৱেবচাইটটোৰ নাম আৰু প্ৰমাণপত্ৰখনত থকা নামটোৰ মিল নাই।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"এই প্ৰমাণপত্ৰখনৰ ম্যাদ উকলি গৈছে।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"এই প্ৰমাণপত্ৰখন এই পর্যন্ত মান্য হোৱা নাই।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"এই প্ৰমাণপত্ৰখনত থকা তাৰিখটো মান্য নহয়।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"এই প্ৰমাণপত্ৰখন মান্য নহয়।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"প্ৰমাণপত্ৰত অজ্ঞাত আসোঁৱাহ।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"সুৰক্ষা সম্পর্কীয় সতৰ্কতা"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"প্ৰমাণপত্ৰ চাওক"</string>
-    <string name="ok" msgid="2817931639040794018">"ঠিক আছে"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ঠিকনা:"</string>
-    <string name="page_info" msgid="4416941086705172545">"পৃষ্ঠাৰ তথ্য"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-az/strings.xml b/packages/CaptivePortalLogin/res/values-az/strings.xml
deleted file mode 100644
index f002544..0000000
--- a/packages/CaptivePortalLogin/res/values-az/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bu şəbəkəni olduğu kimi istifadə edin"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu şəbəkəni istifadə etməyin"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Şəbəkəyə daxil olun"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Daxil olun: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Qoşulmaq istədiyiniz şəbəkənin təhlükəsizlik problemləri var."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Məsələn, giriş səhifəsi göstərilən təşkilata aid olmaya bilər."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Hər bir halda brazuer ilə davam edin"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Bu sertifikat etibarlı orqan tərəfindən verilməyib."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Saytın adı sertifikatdakı ada uyğun deyil."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Bu sertifikatın müddəti bitib."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Bu sertifikat hələ etibarlı deyil."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Bu sertifikatın tarixi yanlışdır."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Bu sertifikat etibarsızdır."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Bilinməyən sertifikat xətası."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Təhlükəsizlik xəbərdarlığı"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Sertifikata baxın"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Ünvan:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Səhifə məlumatı"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml b/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 401548b..0000000
--- a/packages/CaptivePortalLogin/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Koristi ovu mrežu takvu kakva je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne koristi ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijavi me na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijavite se u: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj pokušavate da se pridružite ima bezbednosnih problema."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi preko pregledača"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ovaj sertifikat ne potiče iz pouzdanog izvora."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Naziv sajta se ne podudara sa nazivom na sertifikatu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ovaj sertifikat je istekao."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ovaj sertifikat još uvek nije važeći."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Datum ovog sertifikata je nevažeći."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ovaj sertifikat je nevažeći."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nepoznata greška sertifikata."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Bezbednosno upozorenje"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Prikaži sertifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"Potvrdi"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacije o stranici"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-be/strings.xml b/packages/CaptivePortalLogin/res/values-be/strings.xml
deleted file mode 100644
index 5f2bd90..0000000
--- a/packages/CaptivePortalLogin/res/values-be/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Выкарыстоўваць гэтую сетку як ёсць"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не выкарыстоўваць гэту сетку"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Увайсці ў сетку"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Увайсці ў %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"У сеткі, да якой вы спрабуеце далучыцца, ёсць праблемы з бяспекай."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Напрыклад, старонка ўваходу можа не належаць указанай арганізацыі."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Усё роўна працягнуць праз браўзер"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Гэты сертыфікат не выдадзены давераным цэнтрам."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Назва сайта не адпавядае назве ў сертыфікаце."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Тэрмін дзеяння сертыфіката мінуў."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Гэты сертыфікат яшчэ не дзейнічае."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Гэты сертыфікат мае несапраўдную дату."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Гэты сертыфікат несапраўдны."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Невядомая памылка сертыфіката."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Папярэджанне сістэмы бяспекі"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Прагледзець сертыфікат"</string>
-    <string name="ok" msgid="2817931639040794018">"ОК"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адрас:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Інфармацыя пра старонку"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bg/strings.xml b/packages/CaptivePortalLogin/res/values-bg/strings.xml
deleted file mode 100644
index c5354e8..0000000
--- a/packages/CaptivePortalLogin/res/values-bg/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Директно използване на тази мрежа"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Без използване на тази мрежа"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Вход в мрежата"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Влезте в/ъв %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежата, към която опитвате да се присъедините, има проблеми със сигурността."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Например страницата за вход може да не принадлежи на показаната организация."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Продължаване през браузър въпреки това"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Този сертификат не е от надежден орган."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Името на сайта не съответства на името в сертификата."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Този сертификат е изтекъл."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Този сертификат още не е валиден."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Този сертификат е с невалидна дата."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Този сертификат е невалиден."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Неизвестна грешка в сертификата."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Предупреждение относно сигурността"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Преглед на сертификата"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адрес:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Данни за страницата"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bn/strings.xml b/packages/CaptivePortalLogin/res/values-bn/strings.xml
deleted file mode 100644
index 3fbe2f2..0000000
--- a/packages/CaptivePortalLogin/res/values-bn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে সাইন-ইন করুন"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s তে সাইন-ইন করুন"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন তাতে নিরাপত্তার সমস্যা আছে।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"উদাহরণস্বরূপ, লগ-ইন পৃষ্ঠাটি প্রদর্শিত প্রতিষ্ঠানের অন্তর্গত নাও হতে পারে৷"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"যাই হোক না কেন ব্রাউজারের মাধ্যমে অবিরত রাখুন"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"এই সার্টিফিকেটটি একটি বিশ্বস্ত কর্তৃপক্ষের তরফ থেকে নয়।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"সাইটের নামটি সার্টিফিকেটে লেখা নামের সাথে মিলছে না।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"এই সার্টিফিকেটের মেয়াদ শেষ হয়ে গেছে।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"সার্টিফিকেটটি এখনও সঠিক নয়।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"এই সার্টিফিকেটের তারিখটি সঠিক নয়।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"সার্টিফিকেটটি সঠিক নয়।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"সার্টিফিকেটের সমস্যাটি অজানা।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"নিরাপত্তার সতর্কতা"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"সার্টিফিকেট দেখুন"</string>
-    <string name="ok" msgid="2817931639040794018">"ঠিক আছে"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ঠিকানা:"</string>
-    <string name="page_info" msgid="4416941086705172545">"পৃষ্ঠার তথ্য"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-bs/strings.xml b/packages/CaptivePortalLogin/res/values-bs/strings.xml
deleted file mode 100644
index 83b5067..0000000
--- a/packages/CaptivePortalLogin/res/values-bs/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"Prijava na zaštitnom portalu"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Koristi ovu mrežu kakva jeste"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne koristi ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijava na %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj pokušavate pristupiti ima sigurnosnih problema."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Naprimjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi preko preglednika"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ova potvrda ne potiče iz pouzdanog izvora."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Naziv web lokacije se ne podudara s nazivom na potvrdi."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ova potvrda je istekla."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ova potvrda još uvijek nije važeća."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Ova potvrda sadrži nevažeći datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ova potvrda je nevažeća."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nepoznata greška potvrde."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sigurnosno upozorenje"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Prikaži potvrdu"</string>
-    <string name="ok" msgid="2817931639040794018">"Uredu"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacije o stranici"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ca/strings.xml b/packages/CaptivePortalLogin/res/values-ca/strings.xml
deleted file mode 100644
index 557c3f4..0000000
--- a/packages/CaptivePortalLogin/res/values-ca/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Fes servir aquesta xarxa tal com està."</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No facis servir aquesta xarxa."</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inicia la sessió a la xarxa"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inicia la sessió a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La xarxa a què et vols connectar té problemes de seguretat."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continua igualment mitjançant el navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Aquest certificat no és d\'una autoritat de confiança."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"El nom del lloc web no coincideix amb el que inclou el certificat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Aquest certificat ha caducat."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Aquest certificat encara no és vàlid."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Aquest certificat té una data no vàlida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Aquest certificat no és vàlid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"S\'ha produït un error desconegut de certificat."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertiment de seguretat"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Mostra el certificat"</string>
-    <string name="ok" msgid="2817931639040794018">"D\'acord"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adreça:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informació de la pàgina"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-cs/strings.xml b/packages/CaptivePortalLogin/res/values-cs/strings.xml
deleted file mode 100644
index 0328c76..0000000
--- a/packages/CaptivePortalLogin/res/values-cs/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Použít tuto síť tak, jak je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Tuto síť nepoužívat"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Přihlásit se k síti"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Přihlaste se k síti %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Síť, ke které se pokoušíte připojit, má bezpečnostní problémy."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Například přihlašovací stránka nemusí patřit do zobrazované organizace."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Přesto pokračovat prostřednictvím prohlížeče"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Tento certifikát nepochází od důvěryhodné autority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Název webu se neshoduje s názvem uvedeným v certifikátu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Platnost certifikátu vypršela."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Tento certifikát ještě není platný."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Datum tohoto certifikátu není platné."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Tento certifikát je neplatný."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Neznámá chyba certifikátu."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Bezpečnostní upozornění"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Zobrazit certifikát"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informace o stránce"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-da/strings.xml b/packages/CaptivePortalLogin/res/values-da/strings.xml
deleted file mode 100644
index b9cf7fe9..0000000
--- a/packages/CaptivePortalLogin/res/values-da/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"Login til captive portal"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Brug dette netværk, som det er"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Brug ikke dette netværk"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Log ind på netværk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Log ind på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Der er sikkerhedsproblemer på det netværk, du forsøger at logge ind på."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det er f.eks. ikke sikkert, at loginsiden tilhører den anførte organisation."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsæt alligevel via browseren"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Dette certifikat stammer ikke fra en pålidelig kilde."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Navnet på websitet stemmer ikke overens med navnet på certifikatet."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Dette certifikat er udløbet."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Dette certifikat er ikke gyldigt endnu."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Dette certifikat har en ugyldig dato."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Dette certifikat er ugyldigt."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Ukendt certifikatfejl."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sikkerhedsadvarsel"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Se certifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sideoplysninger"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-de/strings.xml b/packages/CaptivePortalLogin/res/values-de/strings.xml
deleted file mode 100644
index 4276bf9..0000000
--- a/packages/CaptivePortalLogin/res/values-de/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Netzwerk im Istzustand verwenden"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Netzwerk nicht verwenden"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Im Netzwerk anmelden"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"In %1$s anmelden"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Im Netzwerk, zu dem du eine Verbindung herstellen möchtest, liegen Sicherheitsprobleme vor."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Beispiel: Die Log-in-Seite gehört eventuell nicht zur angezeigten Organisation."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Trotzdem in einem Browser fortfahren"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Dieses Zertifikat stammt nicht von einer vertrauenswürdigen Stelle."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Der Name der Website stimmt nicht mit dem Namen auf dem Zertifikat überein."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Dieses Zertifikat ist abgelaufen."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Dieses Zertifikat ist noch nicht gültig."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Dieses Zertifikat hat ein ungültiges Datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Dieses Zertifikat ist ungültig."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unbekannter Zertifikatfehler."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sicherheitswarnung"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Zertifikat ansehen"</string>
-    <string name="ok" msgid="2817931639040794018">"Ok"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Seiteninformationen"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-el/strings.xml b/packages/CaptivePortalLogin/res/values-el/strings.xml
deleted file mode 100644
index f4de7c3..0000000
--- a/packages/CaptivePortalLogin/res/values-el/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Χρήση αυτού του δικτύου ως έχει"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Να μη χρησιμοποιείται αυτό το δίκτυο"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Σύνδεση στο δίκτυο"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Συνδεθείτε στο %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Παρουσιάζονται προβλήματα ασφάλειας στο δίκτυο στο οποίο προσπαθείτε να συνδεθείτε."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Για παράδειγμα, η σελίδα σύνδεσης ενδέχεται να μην ανήκει στον οργανισμό που εμφανίζεται."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Συνέχεια ούτως ή άλλως μέσω του προγράμματος περιήγησης"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Αυτό το πιστοποιητικό δεν προέρχεται από αξιόπιστη αρχή."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Το όνομα του ιστοτόπου δεν αντιστοιχεί στο όνομα στο πιστοποιητικό."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Αυτό το πιστοποιητικό έχει λήξει."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Αυτό το πιστοποιητικό δεν είναι έγκυρο ακόμα."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Αυτό το πιστοποιητικό δεν έχει έγκυρη ημερομηνία."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Αυτό το πιστοποιητικό δεν είναι έγκυρο."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Άγνωστο σφάλμα πιστοποιητικού."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Προειδοποίηση ασφαλείας"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Προβολή πιστοποιητικού"</string>
-    <string name="ok" msgid="2817931639040794018">"ΟΚ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Διεύθυνση:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Πληροφορίες σελίδας"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml b/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
deleted file mode 100644
index 9763339..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unknown certificate error."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"View certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Page info"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml b/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml
deleted file mode 100644
index 9763339..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unknown certificate error."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"View certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Page info"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml b/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
deleted file mode 100644
index 9763339..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unknown certificate error."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"View certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Page info"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml b/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
deleted file mode 100644
index 9763339..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Use this network as is"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Do not use this network"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Sign in to network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Sign in to %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"The network that you’re trying to join has security issues."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"For example, the login page might not belong to the organisation shown."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continue anyway via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"This certificate isn\'t from a trusted authority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"The name of the site doesn\'t match the name on the certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"This certificate has expired."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"This certificate isn\'t valid yet."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"This certificate has an invalid date."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"This certificate is invalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Unknown certificate error."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Security warning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"View certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Page info"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml b/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml
deleted file mode 100644
index 8b3ca29..0000000
--- a/packages/CaptivePortalLogin/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎CaptivePortalLogin‎‏‎‎‏‎"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎Use this network as is‎‏‎‎‏‎"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎Do not use this network‎‏‎‎‏‎"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎Sign in to network‎‏‎‎‏‎"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‎Sign in to %1$s‎‏‎‎‏‎"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎The network you’re trying to join has security issues.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎For example, the login page may not belong to the organization shown.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎Continue anyway via browser‎‏‎‎‏‎"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎This certificate isn\'t from a trusted authority.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎The name of the site doesn\'t match the name on the certificate.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎This certificate has expired.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‎‎This certificate isn\'t valid yet.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎This certificate has an invalid date.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎This certificate is invalid.‎‏‎‎‏‎"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎Unknown certificate error.‎‏‎‎‏‎"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎Security warning‎‏‎‎‏‎"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎View certificate‎‏‎‎‏‎"</string>
-    <string name="ok" msgid="2817931639040794018">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‎‎OK‎‏‎‎‏‎"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎Address:‎‏‎‎‏‎"</string>
-    <string name="page_info" msgid="4416941086705172545">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎Page info‎‏‎‎‏‎"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml b/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
deleted file mode 100644
index d7ddaa7..0000000
--- a/packages/CaptivePortalLogin/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta red como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No usar esta red"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Acceder a la red"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Acceder a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La red a la que intentas conectarte tiene problemas de seguridad."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por ejemplo, es posible que la página de acceso no pertenezca a la organización que aparece."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar de todos modos desde el navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Este certificado no proviene de una autoridad confiable."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"El nombre del sitio no coincide con el nombre del certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado venció."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado aún no es válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"La fecha de este certificado no es válida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado no es válido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Error de certificado desconocido"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertencia de seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"Aceptar"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Dirección:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Información de la página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-es/strings.xml b/packages/CaptivePortalLogin/res/values-es/strings.xml
deleted file mode 100644
index e10380f..0000000
--- a/packages/CaptivePortalLogin/res/values-es/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta red tal cual"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"No utilizar esta red"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Iniciar sesión en la red"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inicia sesión en %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La red a la que intentas unirte tiene problemas de seguridad."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por ejemplo, es posible que la página de inicio de sesión no pertenezca a la organización mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar de todos modos a través del navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Este certificado no procede de una entidad de confianza."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"El nombre del sitio web no coincide con el del certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado ha caducado."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado aún no es válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"La fecha de este certificado no es válida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado no es válido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Error de certificado desconocido."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertencia de seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"Aceptar"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Dirección:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Información de la página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-et/strings.xml b/packages/CaptivePortalLogin/res/values-et/strings.xml
deleted file mode 100644
index 2894383..0000000
--- a/packages/CaptivePortalLogin/res/values-et/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Kasuta seda võrku olemasoleval kujul"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ära kasuta seda võrku"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logi võrku sisse"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logige sisse: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Võrgul, millega üritate ühenduse luua, on turvaprobleeme."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Näiteks ei pruugi sisselogimisleht kuuluda kuvatavale organisatsioonile."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jätka siiski brauseris"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"See sertifikaat ei pärine usaldusväärselt asutuselt."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Saidi nimi ei vasta sertifikaadil olevale nimele."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"See sertifikaat on aegunud."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"See sertifikaat pole veel kehtiv."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Sellel sertifikaadil on kehtetu kuupäev."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"See sertifikaat on kehtetu."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Tundmatu sertifikaadiviga."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Turvahoiatus"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Kuva sertifikaat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Aadress:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Lehe teave"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-eu/strings.xml b/packages/CaptivePortalLogin/res/values-eu/strings.xml
deleted file mode 100644
index b7233ab..0000000
--- a/packages/CaptivePortalLogin/res/values-eu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Erabili sare hau bere horretan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ez erabili sare hau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Hasi saioa sarean"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Hasi saioa %1$s sarean"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Erabili nahi duzun sareak segurtasun-arazoak ditu."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jarraitu arakatzailearen bidez, halere"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ziurtagiria ez da autoritate fidagarri batena."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Webgunearen izena ez dator bat ziurtagirian agertzen den izenarekin."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ziurtagiria iraungi da."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ziurtagiriak ez du balio oraindik."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Ziurtagiriaren datak ez du balio."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ziurtagiriak ez du balio."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Errore ezezagun bat gertatu da ziurtagiriarekin."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Segurtasun-abisua"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ikusi ziurtagiria"</string>
-    <string name="ok" msgid="2817931639040794018">"Ados"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Helbidea:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Orriari buruzko informazioa"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fa/strings.xml b/packages/CaptivePortalLogin/res/values-fa/strings.xml
deleted file mode 100644
index db9f7e8..0000000
--- a/packages/CaptivePortalLogin/res/values-fa/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"از این شبکه همانطور که هست استفاده شود"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"از این شبکه استفاده نشود"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ورود به سیستم شبکه"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏ورود به سیستم %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"شبکه‌ای که می‌خواهید به آن بپیوندید مشکلات امنیتی دارد."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"به عنوان مثال، صفحه ورود به سیستم ممکن است متعلق به سازمان نشان داده شده نباشد."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"در هر صورت از طریق مرورگر ادامه یابد"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"این گواهی از یک منبع مورد‌اطمینان صادر نشده است."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"نام سایت با نام موجود در گواهی مطابقت ندارد."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"این گواهی منقضی شده است."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"این گواهی هنوز معتبر نیست."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"تاریخ این گواهی نامعتبر است."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"این گواهی نامعتبر است."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"خطای ناشناخته در گواهی."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"اخطار امنیتی"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"مشاهده گواهی"</string>
-    <string name="ok" msgid="2817931639040794018">"تأیید"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"نشانی:"</string>
-    <string name="page_info" msgid="4416941086705172545">"اطلاعات صفحه"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fi/strings.xml b/packages/CaptivePortalLogin/res/values-fi/strings.xml
deleted file mode 100644
index 1d7fcb0..0000000
--- a/packages/CaptivePortalLogin/res/values-fi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Käytä tätä verkkoa sellaisenaan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Älä käytä tätä verkkoa"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Kirjaudu verkkoon"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Kirjaudu sisään kohteeseen %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Verkossa, johon yrität muodostaa yhteyttä, on turvallisuusongelmia."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Kirjautumissivu ei välttämättä kuulu näytetylle organisaatiolle."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Jatka silti selaimen kautta."</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Varmenteen myöntäjä ei ole luotettava taho."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Sivuston nimi ei vastaa varmenteessa olevaa nimeä."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Varmenne ei ole enää voimassa."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Varmenne ei ole vielä voimassa."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Varmenteen päiväys ei kelpaa."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Varmenne on virheellinen."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Tuntematon varmennevirhe."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Suojausvaroitus"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Näytä varmenne"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Osoite:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sivun tiedot"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml b/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
deleted file mode 100644
index 979e236..0000000
--- a/packages/CaptivePortalLogin/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Connectez-vous au réseau"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Connexion à %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Le réseau que vous essayez de rejoindre présente des problèmes de sécurité."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Par exemple, la page de connexion pourrait ne pas appartenir à l\'organisation représentée."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuer quand même dans un navigateur"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ce certificat ne provient pas d\'une autorité de confiance."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Le nom du site ne correspond pas au nom figurant sur le certificat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ce certificat a expiré."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ce certificat n\'est pas encore valide."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Ce certificat contient une date non valide."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ce certificat n\'est pas valide."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erreur de certificat inconnue."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Avertissement de sécurité"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Afficher le certificat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse :"</string>
-    <string name="page_info" msgid="4416941086705172545">"Renseignements sur la page"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-fr/strings.xml b/packages/CaptivePortalLogin/res/values-fr/strings.xml
deleted file mode 100644
index e348a4d..0000000
--- a/packages/CaptivePortalLogin/res/values-fr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utiliser ce réseau tel quel"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne pas utiliser ce réseau"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Se connecter au réseau"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Se connecter à %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Le réseau que vous essayez de rejoindre présente des problèmes de sécurité."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Par exemple, la page de connexion peut ne pas appartenir à l\'organisation représentée."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuer quand même dans le navigateur"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ce certificat provient d\'une autorité non approuvée."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Le nom du site ne correspond pas au nom indiqué dans le certificat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ce certificat a expiré."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ce certificat n\'est pas encore valide."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"La date de ce certificat n\'est pas valide."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ce certificat n\'est pas valide."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erreur de certificat inconnue."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Avertissement de sécurité"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Afficher le certificat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse :"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informations sur la page"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-gl/strings.xml b/packages/CaptivePortalLogin/res/values-gl/strings.xml
deleted file mode 100644
index 6419516..0000000
--- a/packages/CaptivePortalLogin/res/values-gl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede tal como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inicia sesión na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Iniciar sesión en %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede á que tentas unirte ten problemas de seguranza."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, é posible que a páxina de inicio de sesión non pertenza á organización que se mostra."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar igualmente co navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Este certificado non procede dunha autoridade de confianza."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do sitio non coincide co nome que aparece no certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado caducou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado aínda non é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Este certificado ten unha data non válida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado non é válido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Produciuse un erro descoñecido relacionado co certificado."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Advertencia de seguranza"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"Aceptar"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Enderezo:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Información da páxina"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-gu/strings.xml b/packages/CaptivePortalLogin/res/values-gu/strings.xml
deleted file mode 100644
index aef043f..0000000
--- a/packages/CaptivePortalLogin/res/values-gu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"આ નેટવર્કનો જેમનો તેમ ઉપયોગ કરો"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"આ નેટવર્કનો ઉપયોગ કરશો નહીં"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"નેટવર્ક પર સાઇન ઇન કરો"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sમાં સઇન ઇન કરો"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"તમે જોડાવાનો પ્રયાસ કરી રહ્યાં છો તે નેટવર્કમાં સુરક્ષા સમસ્યાઓ છે."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ઉદાહરણ તરીકે, લોગિન પૃષ્ઠ દર્શાવેલ સંસ્થાનું હોઈ શકતું નથી."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"બ્રાઉઝર મારફતે કોઈપણ રીતે ચાલુ રાખો"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"આ પ્રમાણપત્ર વિશ્વસનીય સત્તાધિકારી તરફથી મળ્યું નથી."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"સાઇટનું નામ એ પ્રમાણપત્ર પર રહેલાં નામ સાથે મેળ ખાતું નથી."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"આ પ્રમાણપત્રની સમયસીમા સમાપ્ત થઈ ગઈ છે."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"આ પ્રમાણપત્ર હજુ માન્ય નથી."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"આ પ્રમાણપત્રમાં અમાન્ય તારીખ છે."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"આ પ્રમાણપત્ર અમાન્ય છે."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"પ્રમાણપત્રમાં અજાણી ભૂલ."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"સુરક્ષા વિશે ચેતવણી"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"પ્રમાણપત્ર જુઓ"</string>
-    <string name="ok" msgid="2817931639040794018">"ઓકે"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"સરનામું:"</string>
-    <string name="page_info" msgid="4416941086705172545">"પેજ વિશે માહિતી"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hi/strings.xml b/packages/CaptivePortalLogin/res/values-hi/strings.xml
deleted file mode 100644
index b8ae82a..0000000
--- a/packages/CaptivePortalLogin/res/values-hi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"इस नेटवर्क का उपयोग जैसा है वैसा ही करें"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"इस नेटवर्क का उपयोग न करें"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क में साइन इन करें"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s में साइन इन करें"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"आप जिस नेटवर्क में शामिल होने का प्रयास कर रहे हैं उसमें सुरक्षा समस्‍याएं हैं."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरण के लिए, हो सकता है कि लॉगिन पृष्‍ठ दिखाए गए संगठन से संबद्ध ना हो."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउज़र के द्वारा फिर जारी रखें"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"यह प्रमाणपत्र किसी भरोसेमंद अधिकारी का नहीं है."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"साइट के नाम का मिलान प्रमाणपत्र में दिए नाम से नहीं हो रहा है."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"इस प्रमाणपत्र की समय-सीमा खत्म हो चुकी है."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"यह प्रमाणपत्र अभी तक मान्य नहीं है."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"इस प्रमाणपत्र की तारीख गलत है."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"यह प्रमाणपत्र अमान्य है."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"प्रमाणपत्र में अनजान गड़बड़ी."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"सुरक्षा चेतावनी"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"प्रमाणपत्र देखें"</string>
-    <string name="ok" msgid="2817931639040794018">"ठीक है"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"पता:"</string>
-    <string name="page_info" msgid="4416941086705172545">"पेज की जानकारी"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hr/strings.xml b/packages/CaptivePortalLogin/res/values-hr/strings.xml
deleted file mode 100644
index f6adcdb..0000000
--- a/packages/CaptivePortalLogin/res/values-hr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Upotrebljavaj ovu mrežu u zatečenom stanju"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne upotrebljavaj ovu mrežu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijava na mrežu"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijavite se na %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mreža kojoj se pokušavate pridružiti ima sigurnosne poteškoće."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na primjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ipak nastavi putem preglednika"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ovaj certifikat ne potječe iz pouzdanog izvora."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Naziv web-lokacije ne podudara se s nazivom na certifikatu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Ovaj je certifikat istekao."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Ovaj certifikat još nije važeći."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Ovaj certifikat ima nevažeći datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ovaj certifikat nije važeći."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nepoznata pogreška certifikata."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sigurnosno upozorenje"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Pregledajte certifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"U redu"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacije o stranici"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hu/strings.xml b/packages/CaptivePortalLogin/res/values-hu/strings.xml
deleted file mode 100644
index ab289d1..0000000
--- a/packages/CaptivePortalLogin/res/values-hu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Hálózat használata jelen állapotában"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne használja ezt a hálózatot"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Bejelentkezés a hálózatba"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Bejelentkezés a következőbe: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Biztonsági problémák vannak azzal a hálózattal, amelyhez csatlakozni szeretne."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Például lehet, hogy a bejelentkezési oldal nem a megjelenített szervezethez tartozik."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Folytatás ennek ellenére böngészőn keresztül"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ez a tanúsítvány nem hiteles tanúsítványkibocsátótól származik."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"A webhely neve nem egyezik a tanúsítványon lévő névvel."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"A tanúsítvány lejárt."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"A tanúsítvány még nem érvényes."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"A tanúsítvány dátuma érvénytelen."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Ez a tanúsítvány érvénytelen."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Ismeretlen tanúsítványhiba."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Biztonsági figyelmeztetés"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Tanúsítvány megtekintése"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Cím:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Oldaladatok"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-hy/strings.xml b/packages/CaptivePortalLogin/res/values-hy/strings.xml
deleted file mode 100644
index d859d90..0000000
--- a/packages/CaptivePortalLogin/res/values-hy/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Օգտագործել այս ցանցն ինչպես կա"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Չօգտագործել այս ցանցը"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Մուտք գործել ցանց"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Մուտք գործել %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Ցանցը, որին փորձում եք միանալ, անվտանգության խնդիրներ ունի:"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Օրինակ՝ մուտքի էջը կարող է ցուցադրված կազմակերպության էջը չլինել:"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Շարունակել այնուամենայնիվ դիտարկիչի միջոցով"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Հավաստագրի աղբյուրը վստահելի չէ:"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Կայքի անունը չի համապատասխանում հավաստագրում նշված անվանը:"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Հավաստագրի ժամկետը լրացել է:"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Հավաստագիրը դեռ վավեր չէ:"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Հավաստագրի ամսաթիվն անվավեր է:"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Հավաստագիրն անվավեր է:"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Հավաստագրի հետ կապված անհայտ սխալ առաջացավ:"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Զգուշացում"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Դիտել հավաստագիրը"</string>
-    <string name="ok" msgid="2817931639040794018">"Եղավ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Հասցե՝"</string>
-    <string name="page_info" msgid="4416941086705172545">"Էջի մասին"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-in/strings.xml b/packages/CaptivePortalLogin/res/values-in/strings.xml
deleted file mode 100644
index 7036318..0000000
--- a/packages/CaptivePortalLogin/res/values-in/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gunakan jaringan ini sebagaimana adanya"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan jaringan ini"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Login ke jaringan"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Login ke %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Jaringan yang ingin Anda masuki mengalami masalah keamanan."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Misalnya, halaman masuk mungkin bukan milik organisasi yang ditampilkan."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Tetap lanjutkan melalui browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Sertifikat ini tidak berasal dari otoritas tepercaya."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Nama situs tidak cocok dengan nama pada sertifikat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Masa berlaku sertifikat ini telah berakhir."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Sertifikat ini belum valid."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Tanggal sertifikat ini tidak valid."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Sertifikat ini tidak valid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Error sertifikat tak dikenal."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Peringatan keamanan"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Lihat sertifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"Oke"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Alamat:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Info halaman"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-is/strings.xml b/packages/CaptivePortalLogin/res/values-is/strings.xml
deleted file mode 100644
index 7c2a5e4..0000000
--- a/packages/CaptivePortalLogin/res/values-is/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Nota þetta net óbreytt"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ekki nota þetta net"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Skrá inn á net"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Skrá inn á %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Öryggisvandamál eru á netinu sem þú ert að reyna að tengjast."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Til dæmis getur verið að innskráningarsíðan tilheyri ekki fyrirtækinu sem birtist."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Halda samt áfram í vafra"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Þetta vottorð er ekki frá traustum aðila."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Nafnið á síðunni passar ekki við nafnið á vottorðinu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Þetta vottorð er útrunnið."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Þetta vottorð hefur ekki enn tekið gildi."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Þetta vottorð er með ógilda dagsetningu."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Þetta vottorð er ógilt."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Óþekkt vottorðsvilla."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Öryggisviðvörun"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Skoða vottorð"</string>
-    <string name="ok" msgid="2817931639040794018">"Í lagi"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Netfang:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Upplýsingar um síðu"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-it/strings.xml b/packages/CaptivePortalLogin/res/values-it/strings.xml
deleted file mode 100644
index 3896cb4..0000000
--- a/packages/CaptivePortalLogin/res/values-it/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizza questa rete così com\'è"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Non utilizzare questa rete"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Accedi alla rete"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Accedi a %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"La rete a cui stai tentando di accedere presenta problemi di sicurezza."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Ad esempio, la pagina di accesso potrebbe non appartenere all\'organizzazione indicata."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continua comunque dal browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Questo certificato non proviene da un\'autorità attendibile."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Il nome del sito non corrisponde al nome nel certificato."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Il certificato è scaduto."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Questo certificato non è ancora valido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Questo certificato presenta una data non valida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Questo certificato non è valido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Errore certificato sconosciuto."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Avviso di sicurezza"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Visualizza certificato"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Indirizzo:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informazioni sulla pagina"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-iw/strings.xml b/packages/CaptivePortalLogin/res/values-iw/strings.xml
deleted file mode 100644
index 4ce98ee..0000000
--- a/packages/CaptivePortalLogin/res/values-iw/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"השתמש ברשת זו כפי שהיא"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"אל תשתמש ברשת זו"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"היכנס לרשת"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏כניסה אל %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"יש בעיות אבטחה ברשת שאליה אתה מנסה להתחבר."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"לדוגמה, ייתכן שדף ההתחברות אינו שייך לארגון המוצג."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"המשך בכל זאת באמצעות דפדפן"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"אישור זה אינו מגיע מרשות אמינה."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"שם האתר לא תואם לשם באישור."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"פג תוקפו של אישור זה."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"אישור זה אינו חוקי עדיין."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"לאישור זה יש תאריך בלתי חוקי."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"אישור זה אינו חוקי."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"שגיאת אישור לא ידועה."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"אזהרת אבטחה"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"הצגת אישור"</string>
-    <string name="ok" msgid="2817931639040794018">"אישור"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"כתובת:"</string>
-    <string name="page_info" msgid="4416941086705172545">"פרטי דף"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ja/strings.xml b/packages/CaptivePortalLogin/res/values-ja/strings.xml
deleted file mode 100644
index bab9026..0000000
--- a/packages/CaptivePortalLogin/res/values-ja/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"このネットワークをそのまま使用する"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"このネットワークを使用しない"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ネットワークにログイン"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s にログイン"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"接続しようとしているネットワークにセキュリティの問題があります。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"たとえば、ログインページが表示されている組織に属していない可能性があります。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ブラウザから続行"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"この証明書は信頼できる認証機関のものではありません。"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"サイト名と証明書上の名前が一致しません。"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"この証明書は有効期限切れです。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"この証明書はまだ有効ではありません。"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"この証明書の日付は無効です。"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"この証明書は無効です。"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"不明な証明書エラーです。"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"セキュリティに関する警告"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"証明書を表示"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"メールアドレス:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ページ情報"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ka/strings.xml b/packages/CaptivePortalLogin/res/values-ka/strings.xml
deleted file mode 100644
index ec820e5..0000000
--- a/packages/CaptivePortalLogin/res/values-ka/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ამ ქსელის გამოყენება, როგორც არის"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ეს ქსელი არ გამოიყენო"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ქსელში შესვლა"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s-ში შესვლა"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ქსელს, რომელზედაც მიერთებას ცდილობთ, უსაფრთხოების პრობლემები აქვს."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"მაგალითად, სისტემაში შესვლის გვერდი შეიძლება არ ეკუთვნოდეს ნაჩვენებ ორგანიზაციას."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ბრაუზერში გაგრძელება"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ეს სერტიფიკატი არ არის გაცემული ნდობით აღჭურვილი ორგანოს მიერ."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"საიტის სახელი არ ემთხვევა სერტიფიკატში მითითებულს."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ეს სერტიფიკატი ვადაგასულია."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ეს სერტიფიკატი ჯერ არ არის ძალაში."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ამ სერტიფიკატში მითითებულია არასწორი თარიღი."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ეს სერტიფიკატი არასწორია."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"წარმოიშვა სერტიფიკატთან დაკავშირებული უცნობი შეცდომა."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"გაფრთხილება უსაფრთხოების შესახებ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"სერტიფიკატის ნახვა"</string>
-    <string name="ok" msgid="2817931639040794018">"კარგი"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"მისამართი:"</string>
-    <string name="page_info" msgid="4416941086705172545">"გვერდის ინფორმაცია"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-kk/strings.xml b/packages/CaptivePortalLogin/res/values-kk/strings.xml
deleted file mode 100644
index a23eafd..0000000
--- a/packages/CaptivePortalLogin/res/values-kk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Осы желіні бар күйінде пайдалану"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Осы желіні пайдаланбау"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Желіге кіру"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s жүйесіне кіру"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Қосылайын деп жатқан желіңіз қауіпсіз болуы мүмкін."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Мысалы, кіру беті көрсетілген ұйымға тиесілі болмауы мүмкін."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Бәрібір браузер арқылы жалғастыру"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Сертификатты сенімді орган бермеген."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Сайттың атауы мен сертификатта көрсетілген атау сәйкес келмейді."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Сертификаттың жарамдылық мерзімі аяқталған."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Сертификат әлі жарамсыз."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Сертификат күні жарамсыз."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Сертификат жарамсыз."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Сертификатқа қатысты белгісіз қате."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Қауіпсіздік туралы ескерту"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Сертификатты көру"</string>
-    <string name="ok" msgid="2817931639040794018">"Жарайды"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Мекенжай:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Бет туралы ақпарат"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-km/strings.xml b/packages/CaptivePortalLogin/res/values-km/strings.xml
deleted file mode 100644
index b4274e9..0000000
--- a/packages/CaptivePortalLogin/res/values-km/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ប្រើ​បណ្ដាញ​នេះ​ជា"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"កុំ​ប្រើ​បណ្ដាញ​នេះ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ចូលទៅបណ្ដាញ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ចូលទៅ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"បណ្តាញដែលអ្នកកំពុងព្យាយាមចូលមានបញ្ហាសុវត្ថិភាព។"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ឧបករណ៍៖ ទំព័រចូលនេះអាចនឹងមិនមែនជាកម្មសិទ្ធិរបស់ស្ថាប័នដែលបានបង្ហាញនេះទេ។"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"យ៉ាងណាក៏ដោយនៅតែបន្តតាមរយៈកម្មវិធីរុករក"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"វិញ្ញាបនបត្រនេះ​មិនបានចេញ​ដោយ​អាជ្ញាធរដែល​គួរ​ឱ្យ​ទុកចិត្ត​ទេ។"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ឈ្មោះ​គេហទំព័រ​នេះ​មិន​ត្រូវនឹង​ឈ្មោះ​នៅលើវិញ្ញាបនបត្រទេ។"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"វិញ្ញាបនបត្រនេះ​ផុត​កំណត់​ហើយ។"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"វិញ្ញាបនបត្រនេះមិន​ទាន់​មាន​សុពលភាពនៅ​ឡើយ​ទេ។"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"វិញ្ញាបនបត្រនេះ​មាន​កាល​បរិច្ឆេទដែលគ្មាន​សុពលភាព។"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"វិញ្ញាបនបត្រនេះគ្មាន​សុពលភាពទេ។"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"មានបញ្ហា​ដោយសារ​មិនស្គាល់វិញ្ញាបនបត្រ។"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ការព្រមានផ្នែកសុវត្ថិភាព"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"មើល​វិញ្ញាបនបត្រ"</string>
-    <string name="ok" msgid="2817931639040794018">"យល់ព្រម"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"អាសយដ្ឋាន៖"</string>
-    <string name="page_info" msgid="4416941086705172545">"ព័ត៌មាន​ទំព័រ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-kn/strings.xml b/packages/CaptivePortalLogin/res/values-kn/strings.xml
deleted file mode 100644
index 731bbcc..0000000
--- a/packages/CaptivePortalLogin/res/values-kn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ಈ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ಹೀಗೆ ಬಳಸಿ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ಈ ನೆಟ್‌ವರ್ಕ್ ಬಳಸಬೇಡಿ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ನೆಟ್‌ವರ್ಕ್‌ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ನೀವು ಸೇರಬೇಕೆಂದಿರುವ ನೆಟ್‌ವರ್ಕ್ ಭದ್ರತೆ ಸಮಸ್ಯೆಗಳನ್ನು ಹೊಂದಿದೆ."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ಉದಾಹರಣೆಗೆ, ಲಾಗಿನ್ ಪುಟವು ತೋರಿಸಲಾಗಿರುವ ಸಂಸ್ಥೆಗೆ ಸಂಬಂಧಿಸಿರುವುದಿಲ್ಲ."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ಹೇಗಾದರೂ ಬ್ರೌಸರ್ ಮೂಲಕ ಮುಂದುವರಿಸಿ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ಈ ಪ್ರಮಾಣಪತ್ರವು ವಿಶ್ವಾಸಾರ್ಹ ಪ್ರಾಧಿಕಾರದಿಂದ ಬಂದಿಲ್ಲ."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ಸೈಟ್‌ನ ಹೆಸರು ಪ್ರಮಾಣಪತ್ರದಲ್ಲಿನ ಹೆಸರಿನ ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ಈ ಪ್ರಮಾಣಪತ್ರದ ಅವಧಿ ಮೀರಿದೆ."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ಈ ಪ್ರಮಾಣಪತ್ರವು ಇನ್ನೂ ಮಾನ್ಯವಾಗಿಲ್ಲ."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ಈ ಪ್ರಮಾಣಪತ್ರವು ಅಮಾನ್ಯವಾದ ದಿನಾಂಕವನ್ನು ಹೊಂದಿದೆ."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ಈ ಪ್ರಮಾಣಪತ್ರವು ಅಮಾನ್ಯವಾಗಿದೆ."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ಪ್ರಮಾಣಪತ್ರದ ಅಜ್ಞಾತ ದೋಷ."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ಭದ್ರತಾ ಎಚ್ಚರಿಕೆ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ಪ್ರಮಾಣಪತ್ರವನ್ನು ವೀಕ್ಷಿಸಿ"</string>
-    <string name="ok" msgid="2817931639040794018">"ಸರಿ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ವಿಳಾಸ:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ಪುಟದ ಮಾಹಿತಿ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ko/strings.xml b/packages/CaptivePortalLogin/res/values-ko/strings.xml
deleted file mode 100644
index 8c2d9d2..0000000
--- a/packages/CaptivePortalLogin/res/values-ko/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"현재 상태로 이 네트워크 사용"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"이 네트워크 사용 안함"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"네트워크에 로그인"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s에 로그인"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"가입하려는 네트워크에 보안 문제가 있습니다."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"예를 들어 로그인 페이지가 표시된 조직에 속하지 않을 수 있습니다."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"브라우저를 통해 계속하기"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"신뢰할 수 있는 인증 기관에서 발급한 인증서가 아닙니다."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"사이트 이름이 인증서상의 이름과 일치하지 않습니다."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"인증서가 만료되었습니다."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"인증서가 아직 유효하지 않습니다."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"인증서의 날짜가 잘못되었습니다."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"인증서가 잘못되었습니다."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"알 수 없는 인증서 오류입니다."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"보안 경고"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"인증서 보기"</string>
-    <string name="ok" msgid="2817931639040794018">"확인"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"주소:"</string>
-    <string name="page_info" msgid="4416941086705172545">"페이지 정보"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ky/strings.xml b/packages/CaptivePortalLogin/res/values-ky/strings.xml
deleted file mode 100644
index 6d663cb..0000000
--- a/packages/CaptivePortalLogin/res/values-ky/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Бул тармак кандай болсо, ошондой колдонулсун"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Бул тармак колдонулбасын"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Тармакка кирүү"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s каттоо эсебине кириңиз"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Кошулайын деген тармагыңызда коопсуздук көйгөйлөрү бар."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Мисалы, каттоо эсебине кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Баары бир серепчи аркылуу улантуу"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Бул тастыктама ишеничтүү мекеме аркылуу берилген эмес."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Сайттын аталышы тастыктаманын аталышына дал келбейт."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Бул тастыктаманын мөөнөтү өтүп кеткен."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Бул тастыктама азырынча жараксыз."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Бул тастыктаманын күнү жараксыз."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Бул тастыктама жараксыз."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Тастыктамага байланыштуу белгисиз ката."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Коопсуздук эскертүүсү"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Тастыктаманы көрүү"</string>
-    <string name="ok" msgid="2817931639040794018">"ЖАРАЙТ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Дарек:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Барак жөнүндө маалымат"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lo/strings.xml b/packages/CaptivePortalLogin/res/values-lo/strings.xml
deleted file mode 100644
index 673bf2c..0000000
--- a/packages/CaptivePortalLogin/res/values-lo/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້​ຕາມ​ທີ່​ມັນ​ເປັນ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ບໍ່​ໃຊ້​ເຄືອ​ຂ່າຍ​ນີ້"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ລົງຊື່ເຂົ້າເຄືອຂ່າຍ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ເຂົ້າສູ່ລະບົບ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ເຄືອ​ຂ່າຍ​ທີ່​ທ່ານ​ກຳ​ລັງ​ເຂົ້າ​ຮ່ວມ​ມີ​ບັນ​ຫາ​ຄວາມ​ປອດ​ໄພ."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ຕົວ​ຢ່າງ, ໜ້າ​ລົງ​ຊື່​ເຂົ້າ​ໃຊ້​ອາດ​ຈະ​ບໍ່​ເປັນ​ຂອງ​ອົງ​ການ​ທີ່​ສະ​ແດງ​ຂຶ້ນ."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ແນວ​ໃດ​ກໍ່​ສືບ​ຕໍ່​ຜ່ານບ​ຣາວ​ເຊີ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ໃບຮັບຮອງນີ້ບໍ່ໄດ້ມາຈາກໜ່ວຍງານທີ່ເຊື່ອຖືໄດ້."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ຊື່ຂອງເວັບໄຊບໍ່ກົງກັບຊື່ຢູ່ໃບຮັບຮອງ."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ໃບຮັບຮອງນີ້ຫມົດອາຍຸແລ້ວ."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ໃບຮັບຮອງນີ້ບໍ່ຖືກຕ້ອງເທື່ອ."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ໃບຮັບຮອງນີ້ມີວັນທີບໍ່ຖືກຕ້ອງ."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ໃບຮັບຮອງນີ້ບໍ່ຖືກຕ້ອງ."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ໃບຮັບຮອງມີຄວາມຜິດພາດທີ່ບໍ່ຮູ້ຈັກ."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ຄຳເຕືອນຄວາມປອດໄພ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ເບິ່ງໃບຮັບຮອງ"</string>
-    <string name="ok" msgid="2817931639040794018">"ຕົກລົງ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ທີ່ຢູ່:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ຂໍ້ມູນໜ້າ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lt/strings.xml b/packages/CaptivePortalLogin/res/values-lt/strings.xml
deleted file mode 100644
index eb4c46c..0000000
--- a/packages/CaptivePortalLogin/res/values-lt/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Naudoti šį tinklą tokį, koks yra"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nenaudoti šio tinklo"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prisijungti prie tinklo"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prisijungimas prie „%1$s“"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Kilo tinklo, prie kurio bandote prisijungti, problemų."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Pavyzdžiui, prisijungimo puslapis gali nepriklausyti rodomai organizacijai."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vis tiek tęsti naudojant naršyklę"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Šį sertifikatą išdavė nepatikima įstaiga."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Svetainės pavadinimas neatitinka sertifikate nurodyto pavadinimo."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Šio sertifikato galiojimo laikas baigėsi."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Šis sertifikatas dar negalioja."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Šio sertifikato data netinkama."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Šis sertifikatas netinkamas."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nežinoma sertifikato klaida."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Saugos įspėjimas"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Žiūrėti sertifikatą"</string>
-    <string name="ok" msgid="2817931639040794018">"Gerai"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresas"</string>
-    <string name="page_info" msgid="4416941086705172545">"Puslapio informacija"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-lv/strings.xml b/packages/CaptivePortalLogin/res/values-lv/strings.xml
deleted file mode 100644
index 5554343..0000000
--- a/packages/CaptivePortalLogin/res/values-lv/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Izmantot tīklu ar pašreizējiem iestatījumiem"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Neizmantot šo tīklu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Pierakstīties tīklā"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Pierakstieties produktā %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Tīklam, kuram mēģināt pievienoties, ir drošības problēmas."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Piemēram, pieteikšanās lapa, iespējams, nepieder norādītajai organizācijai."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Tik un tā turpināt, izmantojot pārlūkprogrammu"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Šo sertifikātu nav izsniegusi uzticama iestāde."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Vietnes nosaukums neatbilst nosaukumam sertifikātā."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Šī sertifikāta derīguma termiņš ir beidzies."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Šis sertifikāts vēl nav derīgs."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Šī sertifikāta datums nav derīgs."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Šis sertifikāts nav derīgs."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nezināma sertifikāta kļūda."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Drošības brīdinājums"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Skatīt sertifikātu"</string>
-    <string name="ok" msgid="2817931639040794018">"Labi"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adrese:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Lapas informācija"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mk/strings.xml b/packages/CaptivePortalLogin/res/values-mk/strings.xml
deleted file mode 100644
index 9a57fca..0000000
--- a/packages/CaptivePortalLogin/res/values-mk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Користи ја мрежата во оваа состојба"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не ја користи мрежата"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Најавете се на мрежа"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Најавете се на %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежата на која се обидувате да се придружите има проблеми со безбедноста."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"На пример, страницата за најавување може да не припаѓа на организацијата што е прикажана."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Сепак продолжи преку прелистувач"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Сертификатов не е од доверлив орган."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Името на сајтот не се совпаѓа со името на сертификатот."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Сертификатов е истечен."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Сертификатов сѐ уште не е важечки."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Сертификатов има неважечки датум."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Сертификатов е неважечки."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Непозната грешка на сертификатот."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Предупредување за безбедност"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Прикажи го сертификатот"</string>
-    <string name="ok" msgid="2817931639040794018">"Во ред"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адреса:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Информации за страницата"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ml/strings.xml b/packages/CaptivePortalLogin/res/values-ml/strings.xml
deleted file mode 100644
index 8fd74d1..0000000
--- a/packages/CaptivePortalLogin/res/values-ml/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ഈ നെറ്റ്‌വർക്ക് മാറ്റമൊന്നും വരുത്താതെ ഉപയോഗിക്കുക"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ഈ നെറ്റ്‌വർക്ക് ഉപയോഗിക്കരുത്"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"നെറ്റ്‌വർക്കിൽ സൈൻ ഇൻ ചെയ്യുക"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യുക"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"നിങ്ങൾ ചേരാൻ ശ്രമിക്കുന്ന നെറ്റ്‌വർക്കിൽ സുരക്ഷാ പ്രശ്‌നങ്ങളുണ്ടായിരിക്കാം."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ഉദാഹരണത്തിന്, കാണിച്ചിരിക്കുന്ന ഓർഗനൈസേഷന്റേതായിരിക്കില്ല ലോഗിൻ പേജ്."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"എന്തായാലും ബ്രൗസർ വഴി തുടരുക"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ഈ സർട്ടിഫിക്കറ്റ്, വിശ്വസനീയ അതോറിറ്റിയിൽ നിന്നുള്ളതല്ല."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"സൈറ്റിന്റെ പേര്, സർട്ടിഫിക്കറ്റിലുള്ള പേരുമായി പൊരുത്തപ്പെടുന്നില്ല."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ഈ സർട്ടിഫിക്കറ്റ് കാലഹരണപ്പെട്ടു."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ഈ സർട്ടിഫിക്കറ്റിന് ഇപ്പോഴും സാധുതയില്ല."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ഈ സർട്ടിഫിക്കറ്റിൽ അസാധുവായ തീയതിയാണുള്ളത്."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ഈ സർട്ടിഫിക്കറ്റ് അസാധുവാണ്."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"അജ്ഞാത സർട്ടിഫിക്കറ്റ് പിശക്."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"സുരക്ഷാ മുന്നറിയിപ്പ്"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"സർട്ടിഫിക്കറ്റ് കാണുക"</string>
-    <string name="ok" msgid="2817931639040794018">"ശരി"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"വിലാസം:"</string>
-    <string name="page_info" msgid="4416941086705172545">"പേജ് വിവരം"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mn/strings.xml b/packages/CaptivePortalLogin/res/values-mn/strings.xml
deleted file mode 100644
index f11f1d6..0000000
--- a/packages/CaptivePortalLogin/res/values-mn/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Энэ сүлжээг ашиглана уу"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Энэ сүлжээг бүү ашиглана уу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Сүлжээнд нэвтэрнэ үү"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s-д нэвтрэх"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Таны нэгдэх гэж буй сүлжээ аюулгүй байдлын асуудалтай байна."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Жишээлбэл нэвтрэх хуудас нь харагдах байгууллагынх биш байж болзошгүй."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ямартаа ч хөтчөөр үргэлжлүүлэх"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Энэ сертификатыг итгэмжлэгдсэн байгууллагаас олгоогүй байна."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Сайтын нэр сертификат дээрх нэртэй таарахгүй байна."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Энэ сертификатын хугацаа дууссан байна."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Энэ сертификат одоогоор хүчингүй байна."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Энэ сертификатын огноо хүчингүй байна."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Энэ сертификат хүчингүй байна."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Сертификатын үл мэдэгдэх алдаа гарлаа."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Аюулгүй байдлын анхааруулга"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Сертификатыг харах"</string>
-    <string name="ok" msgid="2817931639040794018">"ЗА"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Хаяг:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Хуудасны мэдээлэл"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-mr/strings.xml b/packages/CaptivePortalLogin/res/values-mr/strings.xml
deleted file mode 100644
index 0adc92e..0000000
--- a/packages/CaptivePortalLogin/res/values-mr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"हे नेटवर्क जसेच्या तसे वापरा"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"हे नेटवर्क वापरू नका"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"नेटवर्क मध्‍ये साइन इन करा"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sमध्‍ये साइन इन करा"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ज्या नेटवर्कमध्‍ये तुम्ही सामील होण्याचा प्रयत्न करीत आहात त्यात सुरक्षितता समस्या आहेत."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणार्थ, लॉगिन पृष्‍ठ कदाचित दर्शविलेल्या संस्थेच्या मालकीचे नसावे."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ब्राउझरद्वारे तरीही सुरु ठेवा"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"हे प्रमाणपत्र विश्वसनीय संस्थेने दिलेले नाही"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"साइटचे नाव प्रमाणपत्रावरील नावाशी जुळत नाही."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"हे प्रमाणपत्र एक्स्पायर झाले आहे."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"हे प्रमाणपत्र अजून योग्य नाही."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"या प्रमाणपत्राची तारीख चुकीची आहे."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"हे प्रमाणपत्र चुकीचे आहे."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"अज्ञात प्रमाणपत्र एरर."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"सुरक्षितता चेतावणी"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"प्रमाणपत्र पाहा"</string>
-    <string name="ok" msgid="2817931639040794018">"ठीक आहे"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"पत्ता:"</string>
-    <string name="page_info" msgid="4416941086705172545">"पेज माहिती"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ms/strings.xml b/packages/CaptivePortalLogin/res/values-ms/strings.xml
deleted file mode 100644
index cc4957e..0000000
--- a/packages/CaptivePortalLogin/res/values-ms/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gunakan rangkaian ini"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Jangan gunakan rangkaian ini"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Log masuk ke rangkaian"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Log masuk ke %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rangkaian yang anda cuba sertai mempunyai isu keselamatan."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Contohnya, halaman log masuk mungkin bukan milik organisasi yang ditunjukkan."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Teruskan juga melalui penyemak imbas"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Sijil ini bukan daripada pihak berkuasa yang dipercayai."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Nama tapak tidak sepadan dengan nama pada sijil."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Sijil ini telah tamat tempoh."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Sijil ini belum sah."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Sijil ini mempunyai tarikh yang tidak sah."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Sijil ini tidak sah."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Ralat sijil tidak diketahui."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Amaran keselamatan"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Lihat sijil"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Alamat:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Maklumat halaman"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-my/strings.xml b/packages/CaptivePortalLogin/res/values-my/strings.xml
deleted file mode 100644
index 04a07a4..0000000
--- a/packages/CaptivePortalLogin/res/values-my/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ဒီကွန်ရက်ကို လက်ရှိအတိုင်း သုံးရန်"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ဒီကွန်ရက်ကို မသုံးပါနှင့်"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ကွန်ယက်သို့ လက်မှတ်ထိုးဝင်ရန်"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s သို့ လက်မှတ်ထိုးဝင်ပါ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"သင်ချိတ်ဆက်ရန် ကြိုးစားနေသည့် ကွန်ရက်သည် လုံခြုံရေးပြဿနာ ရှိနေသည်။"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ဥပမာ၊ ဝင်ရောက်ရန် စာမျက်နှာသည် ပြသထားသည့် အဖွဲ့အစည်းနှင့် သက်ဆိုင်မှု မရှိနိုင်ပါ။"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ဘရောက်ဇာမှတစ်ဆင့် ဆက်လုပ်ရန်"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ဤအသိအမှတ်ပြုလက်မှတ်သည် ယုံကြည်ရသော စစ်ဆေးရေးအဖွဲ့ထံမှ မဟုတ်ပါ။"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ဝဘ်ဆိုက်အမည်သည် အသိအမှတ်ပြုလက်မှတ်ရှိ အမည်နှင့် မကိုက်ညီပါ။"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ဤအသိအမှတ်ပြုလက်မှတ် သက်တမ်းကုန်နေပါပြီ။"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ဤအသိအမှတ်ပြုလက်မှတ်သည် မမှန်ကန်သေးပါ။"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ဤအသိအမှတ်ပြုလက်မှတ်ရှိ ရက်စွဲ မမှန်ကန်ပါ။"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ဤအသိအမှတ်ပြုလက်မှတ် မမှန်ကန်ပါ။"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"အသိအမှတ်ပြုလက်မှတ်ဆိုင်ရာ အမျိုးအမည်မသိ အမှား။"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"လုံခြုံရေး သတိပေးချက်"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"အသိအမှတ်ပြုလက်မှတ်ကို ကြည့်ရန်"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"လိပ်စာ-"</string>
-    <string name="page_info" msgid="4416941086705172545">"စာမျက်နှာ အချက်အလက်"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-nb/strings.xml b/packages/CaptivePortalLogin/res/values-nb/strings.xml
deleted file mode 100644
index 29ab438..0000000
--- a/packages/CaptivePortalLogin/res/values-nb/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bruk dette nettverket som det er"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ikke bruk dette nettverket"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logg på nettverk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logg på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Nettverket du prøver å logge på, har sikkerhetsproblemer."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det er for eksempel mulig at påloggingssiden kanskje ikke tilhører organisasjonen som vises."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsett likevel via nettleseren"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Sertifikatet er ikke fra en pålitelig myndighet."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Navnet på nettstedet samsvarer ikke med navnet på sertifikatet."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Sertifikatet er utløpt."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Sertifikatet er ikke gyldig ennå."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Dette sertifikatet har en ugyldig dato."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Dette sertifikatet er ugyldig."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Ukjent sertifikatfeil."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Sikkerhetsadvarsel"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Vis sertifikatet"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresse:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sideinformasjon"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ne/strings.xml b/packages/CaptivePortalLogin/res/values-ne/strings.xml
deleted file mode 100644
index 07d7231..0000000
--- a/packages/CaptivePortalLogin/res/values-ne/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"यो सञ्जाल जस्तो छ प्रयोग गर्नुहोस्"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"यो सञ्जाल प्रयोग नगर्नुहोस्"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"सञ्जालमा साइन इन गर्नुहोस्"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s मा साइन इन गर्नुहोस्"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"तपाईँले सामेल हुन प्रयास गरिरहनु भएको नेटवर्कमा सुरक्षा मुद्दाहरू छन्।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"उदाहरणका लागि, लग इन पृष्ठ देखाइएको संस्थाको नहुन सक्छ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"जे भए पनि ब्राउजर मार्फत जारी राख्नुहोस्"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"यो विश्वसनीय प्राधिकरणबाट उपलब्ध गराइएको प्रमाणपत्र होइन।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"प्रमाणपत्रमा भएको नाम साइटमा भएको नामसँग मेल खाँदैन।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"यो प्रमाणपत्रको म्याद समाप्त भयो।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"यो प्रमाणपत्र अझै मान्य छैन।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"यो प्रमाणपत्रमा कुनै अमान्य मिति छ।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"यो प्रमाणपत्र अमान्य छ।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"प्रमाणपत्रसम्बन्धी अज्ञात त्रुटि।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"सुरक्षासम्बन्धी चेतावनी"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"प्रमाणपत्र हेर्नुहोस्‌"</string>
-    <string name="ok" msgid="2817931639040794018">"ठिक छ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ठेगाना:"</string>
-    <string name="page_info" msgid="4416941086705172545">"पृष्ठको जानकारी"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-nl/strings.xml b/packages/CaptivePortalLogin/res/values-nl/strings.xml
deleted file mode 100644
index a4df7b7..0000000
--- a/packages/CaptivePortalLogin/res/values-nl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Dit netwerk in de huidige staat gebruiken"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Dit netwerk niet gebruiken"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Inloggen bij netwerk"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Inloggen bij %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Het netwerk waarmee u verbinding probeert te maken, heeft beveiligingsproblemen."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Zo hoort de weergegeven inlogpagina misschien niet bij de weergegeven organisatie."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Toch doorgaan via browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Dit is geen certificaat van een vertrouwde autoriteit."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"De naam van deze site komt niet overeen met de naam op het certificaat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Dit certificaat is verlopen."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Dit certificaat is nog niet geldig."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Dit certificaat heeft een ongeldige datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Dit certificaat is ongeldig."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Onbekende certificaatfout."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Beveiligingswaarschuwing"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Certificaat weergeven"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adres:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Paginagegevens"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-or/strings.xml b/packages/CaptivePortalLogin/res/values-or/strings.xml
deleted file mode 100644
index f4c5dac..0000000
--- a/packages/CaptivePortalLogin/res/values-or/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ଏହି ନେଟ୍‌ୱର୍କ ଯେପରି ଅଛି, ସେହିପରି ବ୍ୟବହାର କରନ୍ତୁ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ଏହି ନେଟ୍‌ୱର୍କକୁ ବ୍ୟବହାର କରନ୍ତୁ ନାହିଁ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ନେଟ୍‌ୱର୍କରେ ସାଇନ୍‍ ଇନ୍‍ କରନ୍ତୁ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ଆପଣ ଯୋଗ ଦେବାକୁ ଚେଷ୍ଟା କରୁଥିବା ନେଟ୍‌ୱର୍କର ସୁରକ୍ଷା ସମସ୍ୟା ଅଛି।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ଉଦାହରଣସ୍ୱରୂପ, ଲଗଇନ୍‍ ପୃଷ୍ଠା ଦେଖାଯାଇଥିବା ସଂସ୍ଥାର ନହୋଇଥାଇପାରେ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ବ୍ରାଉଜର୍‍ ଜରିଆରେ ଯେମିତିବି ହେଉ ଜାରି ରଖନ୍ତୁ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ଏହି ସାର୍ଟିଫିକେଟ୍‍ ଏକ ବିଶ୍ବସ୍ତ କର୍ତ୍ତୃପକ୍ଷଙ୍କ ଠାରୁ ନୁହେଁ।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ସାଇଟ୍‍ର ନାମ ସାର୍ଟିଫିକେଟ୍‍‍‍‍ର ନାମ ସହ ମିଶୁ ନାହିଁ।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ଏହି ସାର୍ଟିଫିକେଟ୍‍ ସମୟସୀମା ଶେଷ ହୋଇଛି।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ଏହି ସାର୍ଟିଫିକେଟ୍‍ ବର୍ତ୍ତମାନ ପର୍ଯ୍ୟନ୍ତ ବୈଧ ନୁହେଁ।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ଏହି ସାର୍ଟିଫିକେଟ୍‍‍‍‍‍ରେ ଏକ ଅବୈଧ ତାରିଖ ରହିଛି।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ଏହି ସାର୍ଟିଫିକେଟ୍‍ ବୈଧ ନୁହେଁ।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ଅଜଣା ସାର୍ଟିଫିକେଟ୍‍ ତ୍ରୁଟି।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ସୁରକ୍ଷା ଚେତାବନୀ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ସାର୍ଟିଫିକେଟ୍‍ ଦେଖନ୍ତୁ"</string>
-    <string name="ok" msgid="2817931639040794018">"ଠିକ୍‍ ଅଛି"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ଠିକଣା:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ପୃଷ୍ଠା ସୂଚନା"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pa/strings.xml b/packages/CaptivePortalLogin/res/values-pa/strings.xml
deleted file mode 100644
index b0d6187..0000000
--- a/packages/CaptivePortalLogin/res/values-pa/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ਇਸ ਨੈੱਟਵਰਕ ਨੂੰ ਉਵੇਂ ਵਰਤੋ ਜਿਵੇਂ ਇਹ ਹੈ"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ਇਹ ਨੈੱਟਵਰਕ ਨਾ ਵਰਤੋ"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ਨੈੱਟਵਰਕ \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s \'ਤੇ ਸਾਈਨ-ਇਨ ਕਰੋ"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ਤੁਹਾਡੇ ਦੁਆਰਾ ਸ਼ਾਮਿਲ ਹੋਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੇ ਜਾ ਰਹੇ ਨੈੱਟਵਰਕ ਵਿੱਚ ਸੁਰੱਖਿਆ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ।"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗ-ਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ਬ੍ਰਾਊਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ਇਹ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਕਿਸੇ ਭਰੋਸੇਯੋਗ ਅਥਾਰਿਟੀ ਦਾ ਨਹੀਂ ਹੈ।"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ਸਾਈਟ ਦਾ ਨਾਮ ਪ੍ਰਮਾਣ-ਪੱਤਰ \'ਤੇ ਦਿੱਤੇ ਨਾਮ ਨਾਲ ਮੇਲ ਨਹੀਂ ਖਾਂਦਾ ਹੈ।"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ਇਸ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਦੀ ਮਿਆਦ ਸਮਾਪਤ ਹੋ ਗਈ ਹੈ।"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ਇਹ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਹਾਲੇ ਵੈਧ ਨਹੀਂ ਹੈ।"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ਇਸ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਦੀ ਤਾਰੀਖ ਅਵੈਧ ਹੈ।"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ਇਹ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਅਵੈਧ ਹੈ।"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ਅਗਿਆਤ ਪ੍ਰਮਾਣ-ਪੱਤਰ ਗੜਬੜ।"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ਸੁਰੱਖਿਆ ਚਿਤਾਵਨੀ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ਪ੍ਰਮਾਣ-ਪੱਤਰ ਦੇਖੋ"</string>
-    <string name="ok" msgid="2817931639040794018">"ਠੀਕ ਹੈ"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ਪਤਾ:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ਪੰਨੇ ਦੀ ਜਾਣਕਾਰੀ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pl/strings.xml b/packages/CaptivePortalLogin/res/values-pl/strings.xml
deleted file mode 100644
index 178734d..0000000
--- a/packages/CaptivePortalLogin/res/values-pl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Używaj tej sieci tak jak jest"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nie używaj tej sieci"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Zaloguj się do sieci"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Zaloguj się w aplikacji %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"W sieci, z którą próbujesz się połączyć, występują problemy z zabezpieczeniami."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Na przykład strona logowania może nie należeć do wyświetlanej organizacji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Kontynuuj mimo to w przeglądarce"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Certyfikat nie pochodzi od zaufanego urzędu."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Nazwa witryny nie pasuje do nazwy na certyfikacie."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Certyfikat wygasł."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Certyfikat nie jest jeszcze ważny."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Certyfikat ma nieprawidłową datę."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Certyfikat jest nieprawidłowy."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Nieznany błąd certyfikatu."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Ostrzeżenie dotyczące bezpieczeństwa"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Wyświetl certyfikat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adres:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacje o stronie"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
deleted file mode 100644
index 3aa82c4..0000000
--- a/packages/CaptivePortalLogin/res/values-pt-rBR/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Fazer login em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Esse certificado não é de uma autoridade confiável."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do site não corresponde ao nome no certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Esse certificado expirou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Esse certificado ainda não é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"A data desse certificado é inválida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Esse certificado é inválido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erro de certificado desconhecido."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Aviso de segurança"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Endereço:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informações da página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml b/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 72d62a3..0000000
--- a/packages/CaptivePortalLogin/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não utilizar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Início de sessão na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Iniciar sessão em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual está a tentar aceder tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de início de sessão pode não pertencer à entidade apresentada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim através do navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Este certificado não pertence a uma autoridade fidedigna."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do site não corresponde ao nome constante no certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Este certificado expirou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Este certificado ainda não é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Este certificado tem uma data inválida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Este certificado é inválido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erro de certificado desconhecido."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Aviso de segurança"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Endereço:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informações da página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-pt/strings.xml b/packages/CaptivePortalLogin/res/values-pt/strings.xml
deleted file mode 100644
index 3aa82c4..0000000
--- a/packages/CaptivePortalLogin/res/values-pt/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Usar esta rede como está"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Não usar esta rede"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Fazer login na rede"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Fazer login em %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"A rede à qual você está tentando se conectar tem problemas de segurança."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuar mesmo assim pelo navegador"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Esse certificado não é de uma autoridade confiável."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"O nome do site não corresponde ao nome no certificado."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Esse certificado expirou."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Esse certificado ainda não é válido."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"A data desse certificado é inválida."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Esse certificado é inválido."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Erro de certificado desconhecido."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Aviso de segurança"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Ver certificado"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Endereço:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informações da página"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ro/strings.xml b/packages/CaptivePortalLogin/res/values-ro/strings.xml
deleted file mode 100644
index e3fc191..0000000
--- a/packages/CaptivePortalLogin/res/values-ro/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Utilizați această rețea în starea actuală"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Nu utilizați această rețea"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Conectați-vă la rețea"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Conectați-vă la %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rețeaua la care încercați să vă conectați are probleme de securitate."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"De exemplu, este posibil ca pagina de conectare să nu aparțină organizației afișate."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Continuați oricum prin browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Acest certificat nu provine de la o autoritate de încredere."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Numele acestui site nu se potrivește cu numele de pe certificat."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Acest certificat a expirat."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Acest certificat nu este încă valid."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Acest certificat are o dată nevalidă."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Acest certificat este nevalid."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Eroare de certificat necunoscută."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Avertisment de securitate"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Vizualizați certificatul"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresă:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informații despre pagină"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ru/strings.xml b/packages/CaptivePortalLogin/res/values-ru/strings.xml
deleted file mode 100644
index a976f57..0000000
--- a/packages/CaptivePortalLogin/res/values-ru/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Использовать эту сеть"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не использовать эту сеть"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Регистрация в сети"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Войти: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Сеть, к которой вы хотите подключиться, небезопасна."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Например, страница входа в аккаунт может быть фиктивной."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Игнорировать и открыть браузер"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Этот сертификат получен из ненадежных источников."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Название сайта отличается от указанного в сертификате."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Срок действия сертификата истек."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Сертификат ещё не действителен."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Дата сертификата недействительна."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Сертификат недействителен."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Неизвестная ошибка, связанная с сертификатом."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Предупреждение об опасности"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Показать сертификат"</string>
-    <string name="ok" msgid="2817931639040794018">"ОК"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адрес:"</string>
-    <string name="page_info" msgid="4416941086705172545">"О странице"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-si/strings.xml b/packages/CaptivePortalLogin/res/values-si/strings.xml
deleted file mode 100644
index edfe716..0000000
--- a/packages/CaptivePortalLogin/res/values-si/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"මෙම ජාලය ලෙසම භාවිතා කරන්න"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"මෙම ජාලය භාවිතා කරන්න එපා"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ජාලයට පුරනය වන්න"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s වෙත පුරන්න"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"ඔබ සම්බන්ධ වීමට උත්සහ කරන ජාලයේ ආරක්ෂක ගැටළු ඇත."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"උදාහරණයක් ලෙස, පුරනය වන පිටුව පෙන්වා ඇති සංවිධානයට අයිති නැති විය හැක."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"කෙසේ වුවත් බ්‍රවුසරය හරහා ඉදිරියට යන්න"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"මෙම සහතිකය විශ්වාසී අධිකාරියකින් නොවේ."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"අඩවියේ නම සහතිකයේ නමට නොගැළපේ."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"මෙම සහතිකය කල් ඉකුත් වී ඇත."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"මෙම සහතිකය තවම වලංගු නැත."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"මෙම සහතිකයට වලංගු නොවන දිනයක් ඇත."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"මෙම සහතිකය වලංගු නොවේ."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"නොදන්නා සහතික දෝෂයකි."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"ආරක්ෂක අවවාදයයි"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"සහතිකය බලන්න"</string>
-    <string name="ok" msgid="2817931639040794018">"හරි"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ලිපිනය:"</string>
-    <string name="page_info" msgid="4416941086705172545">"පිටු තොරතුරු"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sk/strings.xml b/packages/CaptivePortalLogin/res/values-sk/strings.xml
deleted file mode 100644
index c1100b8..0000000
--- a/packages/CaptivePortalLogin/res/values-sk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Použiť túto sieť tak, ako je"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Túto sieť nepoužívať"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prihlásiť sa do siete"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prihláste sa do služby %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Sieť, ku ktorej sa pokúšate pripojiť, má problémy so zabezpečením"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Napríklad prihlasovacia stránka nemusí patriť uvedenej organizácii."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Pokračovať pomocou prehliadača"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Tento certifikát nepochádza od dôveryhodnej autority."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Názov stránky sa nezhoduje s názvom uvedeným v certifikáte."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Platnosť certifikátu skončila."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Tento certifikát zatiaľ nie je platný."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Tento certifikát má neplatný dátum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Tento certifikát je neplatný."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Neznáma chyba certifikátu."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Bezpečnostné upozornenie"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Zobraziť certifikát"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informácie o stránke"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sl/strings.xml b/packages/CaptivePortalLogin/res/values-sl/strings.xml
deleted file mode 100644
index b254240..0000000
--- a/packages/CaptivePortalLogin/res/values-sl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Uporabljajte to omrežje, »kakršno je«"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ne uporabljajte tega omrežja"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Prijavite se v omrežje"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Prijava v %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Omrežje, ki se mu poskušate pridružiti, ima varnostne težave."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Stran za prijavo na primer morda ne pripada prikazani organizaciji."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vseeno nadaljuj v brskalniku"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Potrdila ni izdal zaupanja vreden overitelj."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Ime spletnega mesta se ne ujema z imenom na potrdilu."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Potrdilo je poteklo."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"To potrdilo še ni veljavno."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"To potrdilo ima neveljaven datum."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"To potrdilo ni veljavno."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Neznana napaka potrdila."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Varnostno opozorilo"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Prikaži potrdilo"</string>
-    <string name="ok" msgid="2817931639040794018">"V redu"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Naslov:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Podatki o strani"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sq/strings.xml b/packages/CaptivePortalLogin/res/values-sq/strings.xml
deleted file mode 100644
index a178c40..0000000
--- a/packages/CaptivePortalLogin/res/values-sq/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Përdore këtë rrjet siç është"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Mos e përdor këtë rrjet"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Identifikohu në rrjet"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Identifikohu në %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Rrjeti në të cilin po përpiqesh të bashkohesh ka probleme sigurie."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"për shembull, faqja e identifikimit mund të mos i përkasë organizatës së shfaqur."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vazhdo gjithsesi nëpërmjet shfletuesit"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Kjo certifikatë nuk është nga një autoritet i besuar."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Emri i sajtit nuk përputhet me emrin në certifikatë."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Kjo certifikatë ka skaduar."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Kjo certifikatë nuk është ende e vlefshme."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Kjo certifikatë ka një datë të pavlefshme."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Kjo certifikatë është e pavlefshme."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Gabim i panjohur i certifikatës."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Paralajmërim për sigurinë"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Shiko certifikatën"</string>
-    <string name="ok" msgid="2817931639040794018">"Në rregull"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adresa:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Informacionet e faqes"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sr/strings.xml b/packages/CaptivePortalLogin/res/values-sr/strings.xml
deleted file mode 100644
index 6b08369..0000000
--- a/packages/CaptivePortalLogin/res/values-sr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Користи ову мрежу такву каква је"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не користи ову мрежу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Пријави ме на мрежу"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Пријавите се у: %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Мрежа којој покушавате да се придружите има безбедносних проблема."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Ипак настави преко прегледача"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Овај сертификат не потиче из поузданог извора."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Назив сајта се не подудара са називом на сертификату."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Овај сертификат је истекао."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Овај сертификат још увек није важећи."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Датум овог сертификата је неважећи."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Овај сертификат је неважећи."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Непозната грешка сертификата."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Безбедносно упозорење"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Прикажи сертификат"</string>
-    <string name="ok" msgid="2817931639040794018">"Потврди"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адреса:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Информације о страници"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sv/strings.xml b/packages/CaptivePortalLogin/res/values-sv/strings.xml
deleted file mode 100644
index 7fe5432..0000000
--- a/packages/CaptivePortalLogin/res/values-sv/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Använd det här nätverket som det är"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Använd inte det här nätverket"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Logga in på nätverket"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Logga in på %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Nätverket du försöker ansluta till har säkerhetsproblem."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Det kan t.ex. hända att inloggningssidan inte tillhör den organisation som visas."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Fortsätt ändå via webbläsaren"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Certifikatet kommer inte från en betrodd utfärdare."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Webbplatsens namn matchar inte namnet på certifikatet."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Det här certifikatet har löpt ut."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Det här certifikatet är inte giltigt än."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Datumet för det här certifikatet är ogiltigt."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Det här certifikatet är ogiltigt."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Okänt certifikatfel."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Säkerhetsvarning"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Visa certifikat"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adress:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sidinformation"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-sw/strings.xml b/packages/CaptivePortalLogin/res/values-sw/strings.xml
deleted file mode 100644
index 297b72d..0000000
--- a/packages/CaptivePortalLogin/res/values-sw/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Tumia mtandao huu jinsi ulivyo"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Usitumie mtandao huu"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ingia katika mtandao"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Ingia katika akaunti ya %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mtandao unaojaribu kujiunga nao una matatizo ya usalama."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Kwa mfano, ukurasa wa kuingia katika akaunti unaweza usiwe unamilikiwa na shirika lililoonyeshwa."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Endelea hata hivyo kupitia kivinjari"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Cheti hiki hakijatoka kwa mamlaka inayoaminika."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Jina la tovuti halilingani na jina lililo katika cheti."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Muda wa kutumia cheti hiki umeisha."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Cheti hiki bado si halali."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Tarehe ya cheti hiki si sahihi."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Cheti hiki si sahihi."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Hitilafu isiyojulikana ya cheti."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Ilani ya usalama"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Angalia cheti"</string>
-    <string name="ok" msgid="2817931639040794018">"Sawa"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Anwani:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Maelezo ya ukurasa"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ta/strings.xml b/packages/CaptivePortalLogin/res/values-ta/strings.xml
deleted file mode 100644
index 4517d15..0000000
--- a/packages/CaptivePortalLogin/res/values-ta/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"இந்த நெட்வொர்க்கைப் பயன்படுத்து"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"இந்த நெட்வொர்க்கைப் பயன்படுத்த வேண்டாம்"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"நெட்வொர்க்கில் உள்நுழையவும்"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s இல் உள்நுழைக"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"நீங்கள் சேர முயற்சிக்கும் நெட்வொர்க்கில் பாதுகாப்புச் சிக்கல்கள் உள்ளன."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"எடுத்துக்காட்டாக, உள்நுழைவுப் பக்கமானது காட்டப்படும் அமைப்பிற்குச் சொந்தமானதாக இல்லாமல் இருக்கலாம்."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"பரவாயில்லை, உலாவி வழியாகத் தொடரவும்"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"இந்தச் சான்றிதழ் நம்பகமான நிறுவனத்தால் அங்கீகரிக்கப்படவில்லை."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"சான்றிதழிலுள்ள பெயருடன் வலைதளத்தின் பெயர் பொருந்தவில்லை."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"இந்தச் சான்றிதழ் காலாவதியாகிவிட்டது."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"இந்தச் சான்றிதழ் இன்னும் செல்லாததாக உள்ளது."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"இந்தச் சான்றிதழில் தவறான தேதி உள்ளது."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"இந்தச் சான்றிதழ் செல்லாதது."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"சான்றிதழில் அறியப்படாத பிழை உள்ளது."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"பாதுகாப்பு எச்சரிக்கை"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"சான்றிதழைக் காட்டு"</string>
-    <string name="ok" msgid="2817931639040794018">"சரி"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"முகவரி:"</string>
-    <string name="page_info" msgid="4416941086705172545">"பக்கத் தகவல்"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-te/strings.xml b/packages/CaptivePortalLogin/res/values-te/strings.xml
deleted file mode 100644
index 9bb4c11..0000000
--- a/packages/CaptivePortalLogin/res/values-te/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ఈ నెట్‌వర్క్‌ని యథావిధిగా ఉపయోగించు"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ఈ నెట్‌వర్క్‌ని ఉపయోగించవద్దు"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"నెట్‌వర్క్‌కి సైన్ ఇన్ చేయండి"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$sకి సైన్ ఇన్ చేయండి"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"మీరు చేరడానికి ప్రయత్నిస్తున్న నెట్‌వర్క్ భద్రతా సమస్యలను కలిగి ఉంది."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ఉదాహరణకు, లాగిన్ పేజీ చూపిన సంస్థకు చెందినది కాకపోవచ్చు."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ఏదేమైనా బ్రౌజర్ ద్వారా కొనసాగించు"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ఈ సర్టిఫికెట్ విశ్వసనీయ అధికార సంస్థ నుండి కాదు."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"సైట్ యొక్క పేరు సర్టిఫికెట్‌లోని పేరుతో సరిపోలలేదు."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ఈ సర్టిఫికెట్ గడువు ముగిసింది."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ఈ సర్టిఫికెట్ ఇప్పటికీ చెల్లదు."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"ఈ సర్టిఫికెట్ చెల్లని తేదీని కలిగి ఉంది."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ఈ సర్టిఫికెట్ చెల్లుబాటు కాదు."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"తెలియని సర్టిఫికెట్ ఎర్రర్."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"భద్రతా హెచ్చరిక"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"సర్టిఫికెట్‌ని చూడండి"</string>
-    <string name="ok" msgid="2817931639040794018">"సరే"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"చిరునామా:"</string>
-    <string name="page_info" msgid="4416941086705172545">"పేజీ సమాచారం"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-th/strings.xml b/packages/CaptivePortalLogin/res/values-th/strings.xml
deleted file mode 100644
index 739b505..0000000
--- a/packages/CaptivePortalLogin/res/values-th/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"ใช้เครือข่ายนี้ตามที่เป็นอยู่"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"ไม่ใช้เครือข่ายนี้"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"ลงชื่อเข้าใช้เครือข่าย"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"ลงชื่อเข้าใช้ %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"เครือข่ายที่คุณพยายามเข้าร่วมมีปัญหาด้านความปลอดภัย"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"ตัวอย่างเช่น หน้าเข้าสู่ระบบอาจไม่ใช่ขององค์กรที่แสดงไว้"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"ดำเนินการต่อผ่านเบราว์เซอร์"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"ใบรับรองนี้ไม่ได้มาจากผู้ออกที่เชื่อถือได้"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"ชื่อเว็บไซต์ไม่ตรงกับในใบรับรอง"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"ใบรับรองนี้หมดอายุแล้ว"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"ใบรับรองนี้ยังใช้งานไม่ได้"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"วันที่ในใบรับรองนี้ไม่ถูกต้อง"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"ใบรับรองนี้ไม่ถูกต้อง"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"ข้อผิดพลาดใบรับรองที่ไม่รู้จัก"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"การแจ้งเตือนเกี่ยวกับความปลอดภัย"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"ดูใบรับรอง"</string>
-    <string name="ok" msgid="2817931639040794018">"ตกลง"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"ที่อยู่:"</string>
-    <string name="page_info" msgid="4416941086705172545">"ข้อมูลหน้าเว็บ"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-tl/strings.xml b/packages/CaptivePortalLogin/res/values-tl/strings.xml
deleted file mode 100644
index 483a589..0000000
--- a/packages/CaptivePortalLogin/res/values-tl/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Gamitin ang network na ito nang walang pagbabago"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Huwag gamitin ang network na ito"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Mag-sign in sa network"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Mag-sign in sa %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"May mga isyu sa seguridad ang network kung saan mo sinusubukang sumali."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Halimbawa, maaaring hindi sa organisasyong ipinapakita ang page sa pag-log in."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Magpatuloy pa rin sa pamamagitan ng browser"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Ang certificate na ito ay mula sa hindi pinagkakatiwalaang awtoridad."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Ang pangalan ng site ay hindi tumutugma sa pangalan sa certificate."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Nag-expire na ang certificate na ito."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Hindi pa valid ang certificate na ito."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"May invalid na petsa ang certificate na ito."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Invalid ang certificate na ito."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Hindi kilalang error sa certificate."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Babala sa seguridad"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Tingnan ang certificate"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Address:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Impormasyon ng page"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-tr/strings.xml b/packages/CaptivePortalLogin/res/values-tr/strings.xml
deleted file mode 100644
index f51cfbd..0000000
--- a/packages/CaptivePortalLogin/res/values-tr/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Bu ağı olduğu gibi kullan"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Bu ağı kullanma"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ağda oturum açın"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s üzerinde oturum açın"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Katılmaya çalıştığınız ağda güvenlik sorunları var."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Örneğin, giriş sayfası, gösterilen kuruluşa ait olmayabilir."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Yine de tarayıcıyla devam et"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Bu sertifika güvenilir bir yetkiliden değil."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Sitenin adı sertifika üzerindeki adla eşleşmiyor."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Bu sertifikanın süresi dolmuş."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Bu sertifika henüz geçerli değil."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Bu sertifikanın tarihi geçersiz."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Bu sertifika geçersiz."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Bilinmeyen sertifika hatası."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Güvenlik uyarısı"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Sertifikayı göster"</string>
-    <string name="ok" msgid="2817931639040794018">"Tamam"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Adres:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sayfa bilgileri"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-uk/strings.xml b/packages/CaptivePortalLogin/res/values-uk/strings.xml
deleted file mode 100644
index c1a5d05..0000000
--- a/packages/CaptivePortalLogin/res/values-uk/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Використовувати цю мережу як є"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Не використовувати цю мережу"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Увійти в мережу"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Увійти в обліковий запис %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"У мережі, до якої ви намагаєтеся під’єднатись, є проблеми з безпекою."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Наприклад, сторінка входу може не належати вказаній організації."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Усе одно продовжити у веб-переглядачі"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Сертифікат видано ненадійним центром сертифікації."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Назва сайту не збігається з назвою в сертифікаті."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Термін дії сертифіката закінчився."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Цей сертифікат ще не дійсний."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Цей сертифікат має недійсну дату."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Цей сертифікат недійсний."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Помилка невідомого сертифіката."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Застереження про небезпеку"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Переглянути сертифікат"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Адреса:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Інформація про сторінку"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-ur/strings.xml b/packages/CaptivePortalLogin/res/values-ur/strings.xml
deleted file mode 100644
index e6f8539..0000000
--- a/packages/CaptivePortalLogin/res/values-ur/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"جوں کا توں اس نیٹ ورک کا استعمال کریں"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"اس نیٹ ورک کا استعمال نہ کریں"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"نیٹ ورک میں سائن ان کریں"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"‏%1$s میں سائن ان کریں"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"جس نیٹ ورک میں آپ شامل ہونے کی کوشش کر رہے ہیں اس میں سیکیورٹی کے مسائل ہیں۔"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"مثال کے طور پر ہو سکتا ہے کہ لاگ ان صفحہ دکھائی گئی تنظیم سے تعلق نہ رکھتا ہو۔"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"یہ سرٹیفکیٹ قابل اعتماد اتھارٹی سے حاصل شدہ نہیں ہے۔"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"سائٹ کا نام سرٹیفکیٹ پر موجود نام سے مماثل نہیں ہے۔"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"اس سرٹیفکیٹ کی میعاد ختم ہو گئی ہے۔"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"یہ سرٹیفکیٹ ابھی تک درست نہیں ہے۔"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"اس سرٹیفکیٹ میں ایک غلط تاریخ ہے۔"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"یہ سرٹیفیکیٹ غلط ہے۔"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"سرٹیفکیٹ کی نامعلوم خرابی۔"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"سیکیورٹی وارننگ"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"سرٹیفکیٹ دیکھیں"</string>
-    <string name="ok" msgid="2817931639040794018">"ٹھیک ہے"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"پتہ:"</string>
-    <string name="page_info" msgid="4416941086705172545">"صفحہ کی معلومات"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-uz/strings.xml b/packages/CaptivePortalLogin/res/values-uz/strings.xml
deleted file mode 100644
index 4009db6a..0000000
--- a/packages/CaptivePortalLogin/res/values-uz/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Ushbu tarmoqdan o‘z holicha foydalanilsin"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ushbu tarmoqdan foydalanilmasin"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Tarmoqqa kirish"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"%1$s hisobiga kirish"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Siz ulanmoqchi bo‘lgan tarmoqda xavfsizlik bilan bog‘liq muammolar mavjud."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Masalan, tizimga kirish sahifasi ko‘rsatilgan tashkilotga tegishli bo‘lmasligi mumkin."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"E’tiborsiz qoldirilsin va brauzer ochilsin"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Bu sertifikat ishonchsiz manbadan olingan."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Sayt nomi sertifikatdagi nomga mos emas."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Bu sertifikat muddati tugagan."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Bu sertifikat hali yaroqli emas."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Bu sertifikatdagi sana xato."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Bu sertifikat yaroqsiz."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Sertifikatga aloqador notanish xato."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Xavfsizlikka oid ogohlantirish"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Sertifikatni ochish"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Manzil:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Sahifa haqida"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-vi/strings.xml b/packages/CaptivePortalLogin/res/values-vi/strings.xml
deleted file mode 100644
index bd4e96a..0000000
--- a/packages/CaptivePortalLogin/res/values-vi/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Sử dụng mạng này"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Không sử dụng mạng này"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Đăng nhập vào mạng"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Đăng nhập vào %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Mạng mà bạn đang cố gắng tham gia có vấn đề về bảo mật."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Ví dụ, trang đăng nhập có thể không thuộc về tổ chức được hiển thị."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Vẫn tiếp tục qua trình duyệt"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Chứng chỉ này không xuất phát từ tổ chức phát hành đáng tin cậy."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Tên của trang web không khớp với tên trên chứng chỉ."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Chứng chỉ này đã hết hạn."</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Chứng chỉ này chưa hợp lệ."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Chứng chỉ này có ngày không hợp lệ."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Chứng chỉ này không hợp lệ."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Lỗi chứng chỉ không xác định."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Cảnh báo bảo mật"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Xem chứng chỉ"</string>
-    <string name="ok" msgid="2817931639040794018">"OK"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Địa chỉ:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Thông tin trang"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 5beaa2e..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"直接使用此网络"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用此网络"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登录到网络"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登录%1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"您尝试加入的网络存在安全问题。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如,登录页面可能并不属于页面上显示的单位。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"仍然通过浏览器继续操作"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"该证书并非来自可信的授权中心。"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"网站的名称与证书上的名称不一致。"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"该证书已过期。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"该证书尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"该证书的日期无效。"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"该证书无效。"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"未知证书错误。"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"安全警告"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"查看证书"</string>
-    <string name="ok" msgid="2817931639040794018">"确定"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"地址:"</string>
-    <string name="page_info" msgid="4416941086705172545">"页面信息"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 7987023..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"依照現況使用這個網絡"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不要使用這個網絡"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登入網絡"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登入「%1$s」"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"您正在嘗試加入的網絡有安全性問題。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如,登入頁面並不屬於所顯示的機構。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"透過瀏覽器繼續"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"此憑證並非由信任的機構發出。"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"網站名稱與憑證上的名稱不符。"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"此憑證已過期。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"此憑證尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"此憑證的日期無效。"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"此憑證無效。"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"不明的憑證錯誤。"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"安全性警告"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"查看憑證"</string>
-    <string name="ok" msgid="2817931639040794018">"確定"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"電郵地址:"</string>
-    <string name="page_info" msgid="4416941086705172545">"頁面資料"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml b/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 9f92f39..0000000
--- a/packages/CaptivePortalLogin/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"依現況使用這個網路"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"不使用這個網路"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"登入網路"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"登入 %1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"你嘗試加入的網路有安全問題。"</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"例如,登入網頁中顯示的機構可能並非該網頁實際隸屬的機構。"</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"透過瀏覽器繼續"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"這個憑證並非來自信任的授權單位。"</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"網站名稱與憑證上的名稱不相符。"</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"這個憑證已過期。"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"這個憑證尚未生效。"</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"這個憑證的日期無效。"</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"這個憑證無效。"</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"不明的憑證錯誤。"</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"安全性警告"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"查看憑證"</string>
-    <string name="ok" msgid="2817931639040794018">"確定"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"地址:"</string>
-    <string name="page_info" msgid="4416941086705172545">"頁面資訊"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values-zu/strings.xml b/packages/CaptivePortalLogin/res/values-zu/strings.xml
deleted file mode 100644
index ebb0f54..0000000
--- a/packages/CaptivePortalLogin/res/values-zu/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="5934709770924185752">"I-CaptivePortalLogin"</string>
-    <string name="action_use_network" msgid="6076184727448466030">"Sebenzisa le nethiwekhi njengoba injalo"</string>
-    <string name="action_do_not_use_network" msgid="4577366536956516683">"Ungasebenzisi le nethiwekhi"</string>
-    <string name="action_bar_label" msgid="917235635415966620">"Ngena ngemvume kunethiwekhi"</string>
-    <string name="action_bar_title" msgid="5645564790486983117">"Ngena ngemvume ku-%1$s"</string>
-    <string name="ssl_error_warning" msgid="6653188881418638872">"Inethiwekhi ozama ukuyijoyina inezinkinga zokuvikela."</string>
-    <string name="ssl_error_example" msgid="647898534624078900">"Isibonelo, ikhasi lokungena ngemvume kungenzeka lingelenhlangano ebonisiwe."</string>
-    <string name="ssl_error_continue" msgid="6492718244923937110">"Qhubeka noma kunjalo ngesiphequluli"</string>
-    <string name="ssl_error_untrusted" msgid="1496280318271264520">"Lesi sitifiketi asisuki kusiphathimandla esithembekile."</string>
-    <string name="ssl_error_mismatch" msgid="3060364165934822383">"Igama lesayithi alifani negama elikusitifiketi."</string>
-    <string name="ssl_error_expired" msgid="1501588340716182495">"Lesi sitifiketi siphelelwe yisikhathi"</string>
-    <string name="ssl_error_not_yet_valid" msgid="8648649030525886924">"Lesi sitifiketi asivumelekile okwamanje."</string>
-    <string name="ssl_error_date_invalid" msgid="88425990680059223">"Lesi sitifiketi sinosuku olungalungile."</string>
-    <string name="ssl_error_invalid" msgid="2540546515565633432">"Lesi sitifiketi asilungile."</string>
-    <string name="ssl_error_unknown" msgid="4405203446079465859">"Iphutha lesitifiketi elingaziwa."</string>
-    <string name="ssl_security_warning_title" msgid="8768539813847504404">"Isexwayiso sokuvikeleka"</string>
-    <string name="ssl_error_view_certificate" msgid="5722652540168339333">"Buka isitifiketi"</string>
-    <string name="ok" msgid="2817931639040794018">"KULUNGILE"</string>
-    <string name="page_info_address" msgid="1261481517455692363">"Ikheli:"</string>
-    <string name="page_info" msgid="4416941086705172545">"Ulwazi lekhasi"</string>
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/dimens.xml b/packages/CaptivePortalLogin/res/values/dimens.xml
deleted file mode 100644
index 55c1e59..0000000
--- a/packages/CaptivePortalLogin/res/values/dimens.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<resources>
-
-    <!-- Default screen margins, per the Android Design guidelines. -->
-    <dimen name="activity_horizontal_margin">16dp</dimen>
-    <dimen name="activity_vertical_margin">16dp</dimen>
-
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/strings.xml b/packages/CaptivePortalLogin/res/values/strings.xml
deleted file mode 100644
index e9698db..0000000
--- a/packages/CaptivePortalLogin/res/values/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <string name="app_name">CaptivePortalLogin</string>
-    <string name="action_use_network">Use this network as is</string>
-    <string name="action_do_not_use_network">Do not use this network</string>
-    <string name="action_bar_label">Sign in to network</string>
-    <string name="action_bar_title">Sign in to %1$s</string>
-    <string name="ssl_error_warning">The network you&#8217;re trying to join has security issues.</string>
-    <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string>
-    <string name="ssl_error_continue">Continue anyway via browser</string>
-    <string name="ssl_error_untrusted">This certificate isn\'t from a trusted authority.</string>
-    <string name="ssl_error_mismatch">The name of the site doesn\'t match the name on the certificate.</string>
-    <string name="ssl_error_expired">This certificate has expired.</string>
-    <string name="ssl_error_not_yet_valid">This certificate isn\'t valid yet.</string>
-    <string name="ssl_error_date_invalid">This certificate has an invalid date.</string>
-    <string name="ssl_error_invalid">This certificate is invalid.</string>
-    <string name="ssl_error_unknown">Unknown certificate error.</string>
-    <string name="ssl_security_warning_title">Security warning</string>
-    <string name="ssl_error_view_certificate">View certificate</string>
-    <string name="ok">OK</string>
-    <string name="page_info_address">Address:</string>
-    <string name="page_info">Page info</string>
-
-</resources>
diff --git a/packages/CaptivePortalLogin/res/values/styles.xml b/packages/CaptivePortalLogin/res/values/styles.xml
deleted file mode 100644
index f6c2339..0000000
--- a/packages/CaptivePortalLogin/res/values/styles.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<resources>
-
-    <!--
-        Base application theme, dependent on API level. This theme is replaced
-        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-    -->
-    <style name="AppBaseTheme" parent="@android:style/Theme.DeviceDefault.Settings">
-        <!--
-            Theme customizations available in newer API levels can go in
-            res/values-vXX/styles.xml, while customizations related to
-            backward-compatibility can go here.
-        -->
-    </style>
-
-    <!-- Application theme. -->
-    <style name="AppTheme" parent="AppBaseTheme">
-        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
-    </style>
-</resources>
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
deleted file mode 100644
index 23fb7b6..0000000
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ /dev/null
@@ -1,710 +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.
- */
-
-package com.android.captiveportallogin;
-
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_PROBE_SPEC;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Application;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.CaptivePortal;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.Proxy;
-import android.net.Uri;
-import android.net.captiveportal.CaptivePortalProbeSpec;
-import android.net.http.SslCertificate;
-import android.net.http.SslError;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.webkit.CookieManager;
-import android.webkit.SslErrorHandler;
-import android.webkit.WebChromeClient;
-import android.webkit.WebResourceRequest;
-import android.webkit.WebSettings;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.LinearLayout;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Objects;
-import java.util.Random;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class CaptivePortalLoginActivity extends Activity {
-    private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int SOCKET_TIMEOUT_MS = 10000;
-    public static final String HTTP_LOCATION_HEADER_NAME = "Location";
-
-    private enum Result {
-        DISMISSED(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_DISMISSED),
-        UNWANTED(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_UNWANTED),
-        WANTED_AS_IS(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_RESULT_WANTED_AS_IS);
-
-        final int metricsEvent;
-        Result(int metricsEvent) { this.metricsEvent = metricsEvent; }
-    };
-
-    private URL mUrl;
-    private CaptivePortalProbeSpec mProbeSpec;
-    private String mUserAgent;
-    private Network mNetwork;
-    private CaptivePortal mCaptivePortal;
-    private NetworkCallback mNetworkCallback;
-    private ConnectivityManager mCm;
-    private WifiManager mWifiManager;
-    private boolean mLaunchBrowser = false;
-    private MyWebViewClient mWebViewClient;
-    private SwipeRefreshLayout mSwipeRefreshLayout;
-    // Ensures that done() happens once exactly, handling concurrent callers with atomic operations.
-    private final AtomicBoolean isDone = new AtomicBoolean(false);
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mCaptivePortal = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
-        logMetricsEvent(MetricsEvent.ACTION_CAPTIVE_PORTAL_LOGIN_ACTIVITY);
-
-        mCm = getSystemService(ConnectivityManager.class);
-        mWifiManager = getSystemService(WifiManager.class);
-        mNetwork = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
-        mUserAgent =
-                getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT);
-        mUrl = getUrl();
-        if (mUrl == null) {
-            // getUrl() failed to parse the url provided in the intent: bail out in a way that
-            // at least provides network access.
-            done(Result.WANTED_AS_IS);
-            return;
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("onCreate for %s", mUrl.toString()));
-        }
-
-        final String spec = getIntent().getStringExtra(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC);
-        try {
-            mProbeSpec = CaptivePortalProbeSpec.parseSpecOrNull(spec);
-        } catch (Exception e) {
-            // Make extra sure that invalid configurations do not cause crashes
-            mProbeSpec = null;
-        }
-
-        mNetworkCallback = new NetworkCallback() {
-            @Override
-            public void onLost(Network lostNetwork) {
-                // If the network disappears while the app is up, exit.
-                if (mNetwork.equals(lostNetwork)) done(Result.UNWANTED);
-            }
-        };
-        mCm.registerNetworkCallback(new NetworkRequest.Builder().build(), mNetworkCallback);
-
-        // If the network has disappeared, exit.
-        final NetworkCapabilities networkCapabilities = mCm.getNetworkCapabilities(mNetwork);
-        if (networkCapabilities == null) {
-            finishAndRemoveTask();
-            return;
-        }
-
-        // Also initializes proxy system properties.
-        mNetwork = mNetwork.getPrivateDnsBypassingCopy();
-        mCm.bindProcessToNetwork(mNetwork);
-
-        // Proxy system properties must be initialized before setContentView is called because
-        // setContentView initializes the WebView logic which in turn reads the system properties.
-        setContentView(R.layout.activity_captive_portal_login);
-
-        getActionBar().setDisplayShowHomeEnabled(false);
-        getActionBar().setElevation(0); // remove shadow
-        getActionBar().setTitle(getHeaderTitle());
-        getActionBar().setSubtitle("");
-
-        final WebView webview = getWebview();
-        webview.clearCache(true);
-        CookieManager.getInstance().setAcceptThirdPartyCookies(webview, true);
-        WebSettings webSettings = webview.getSettings();
-        webSettings.setJavaScriptEnabled(true);
-        webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
-        webSettings.setUseWideViewPort(true);
-        webSettings.setLoadWithOverviewMode(true);
-        webSettings.setSupportZoom(true);
-        webSettings.setBuiltInZoomControls(true);
-        webSettings.setDisplayZoomControls(false);
-        webSettings.setDomStorageEnabled(true);
-        mWebViewClient = new MyWebViewClient();
-        webview.setWebViewClient(mWebViewClient);
-        webview.setWebChromeClient(new MyWebChromeClient());
-        // Start initial page load so WebView finishes loading proxy settings.
-        // Actual load of mUrl is initiated by MyWebViewClient.
-        webview.loadData("", "text/html", null);
-
-        mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
-        mSwipeRefreshLayout.setOnRefreshListener(() -> {
-                webview.reload();
-                mSwipeRefreshLayout.setRefreshing(true);
-            });
-
-    }
-
-    // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
-    private void setWebViewProxy() {
-        // TODO: migrate to androidx WebView proxy setting API as soon as it is finalized
-        try {
-            final Field loadedApkField = Application.class.getDeclaredField("mLoadedApk");
-            final Class<?> loadedApkClass = loadedApkField.getType();
-            final Object loadedApk = loadedApkField.get(getApplication());
-            Field receiversField = loadedApkClass.getDeclaredField("mReceivers");
-            receiversField.setAccessible(true);
-            ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
-            for (Object receiverMap : receivers.values()) {
-                for (Object rec : ((ArrayMap) receiverMap).keySet()) {
-                    Class clazz = rec.getClass();
-                    if (clazz.getName().contains("ProxyChangeListener")) {
-                        Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class,
-                                Intent.class);
-                        Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
-                        onReceiveMethod.invoke(rec, getApplicationContext(), intent);
-                        Log.v(TAG, "Prompting WebView proxy reload.");
-                    }
-                }
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Exception while setting WebView proxy: " + e);
-        }
-    }
-
-    private void done(Result result) {
-        if (isDone.getAndSet(true)) {
-            // isDone was already true: done() already called
-            return;
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("Result %s for %s", result.name(), mUrl.toString()));
-        }
-        logMetricsEvent(result.metricsEvent);
-        switch (result) {
-            case DISMISSED:
-                mCaptivePortal.reportCaptivePortalDismissed();
-                break;
-            case UNWANTED:
-                mCaptivePortal.ignoreNetwork();
-                break;
-            case WANTED_AS_IS:
-                mCaptivePortal.useNetwork();
-                break;
-        }
-        finishAndRemoveTask();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.captive_portal_login, menu);
-        return true;
-    }
-
-    @Override
-    public void onBackPressed() {
-        WebView myWebView = findViewById(R.id.webview);
-        if (myWebView.canGoBack() && mWebViewClient.allowBack()) {
-            myWebView.goBack();
-        } else {
-            super.onBackPressed();
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        final Result result;
-        final String action;
-        final int id = item.getItemId();
-        switch (id) {
-            case R.id.action_use_network:
-                result = Result.WANTED_AS_IS;
-                action = "USE_NETWORK";
-                break;
-            case R.id.action_do_not_use_network:
-                result = Result.UNWANTED;
-                action = "DO_NOT_USE_NETWORK";
-                break;
-            default:
-                return super.onOptionsItemSelected(item);
-        }
-        if (DBG) {
-            Log.d(TAG, String.format("onOptionsItemSelect %s for %s", action, mUrl.toString()));
-        }
-        done(result);
-        return true;
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        final WebView webview = (WebView) findViewById(R.id.webview);
-        if (webview != null) {
-            webview.stopLoading();
-            webview.setWebViewClient(null);
-            webview.setWebChromeClient(null);
-            webview.destroy();
-        }
-        if (mNetworkCallback != null) {
-            // mNetworkCallback is not null if mUrl is not null.
-            mCm.unregisterNetworkCallback(mNetworkCallback);
-        }
-        if (mLaunchBrowser) {
-            // Give time for this network to become default. After 500ms just proceed.
-            for (int i = 0; i < 5; i++) {
-                // TODO: This misses when mNetwork underlies a VPN.
-                if (mNetwork.equals(mCm.getActiveNetwork())) break;
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException e) {
-                }
-            }
-            final String url = mUrl.toString();
-            if (DBG) {
-                Log.d(TAG, "starting activity with intent ACTION_VIEW for " + url);
-            }
-            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
-        }
-    }
-
-    private URL getUrl() {
-        String url = getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
-        if (url == null) {
-            url = mCm.getCaptivePortalServerUrl();
-        }
-        return makeURL(url);
-    }
-
-    private static URL makeURL(String url) {
-        try {
-            return new URL(url);
-        } catch (MalformedURLException e) {
-            Log.e(TAG, "Invalid URL " + url);
-        }
-        return null;
-    }
-
-    private static String host(URL url) {
-        if (url == null) {
-            return null;
-        }
-        return url.getHost();
-    }
-
-    private static String sanitizeURL(URL url) {
-        // In non-Debug build, only show host to avoid leaking private info.
-        return isDebuggable() ? Objects.toString(url) : host(url);
-    }
-
-    private static boolean isDebuggable() {
-        return SystemProperties.getInt("ro.debuggable", 0) == 1;
-    }
-
-    private void testForCaptivePortal() {
-        // TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
-        new Thread(new Runnable() {
-            public void run() {
-                // Give time for captive portal to open.
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                }
-                HttpURLConnection urlConnection = null;
-                int httpResponseCode = 500;
-                String locationHeader = null;
-                try {
-                    urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
-                    urlConnection.setInstanceFollowRedirects(false);
-                    urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
-                    urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
-                    urlConnection.setUseCaches(false);
-                    if (mUserAgent != null) {
-                       urlConnection.setRequestProperty("User-Agent", mUserAgent);
-                    }
-                    // cannot read request header after connection
-                    String requestHeader = urlConnection.getRequestProperties().toString();
-
-                    urlConnection.getInputStream();
-                    httpResponseCode = urlConnection.getResponseCode();
-                    locationHeader = urlConnection.getHeaderField(HTTP_LOCATION_HEADER_NAME);
-                    if (DBG) {
-                        Log.d(TAG, "probe at " + mUrl +
-                                " ret=" + httpResponseCode +
-                                " request=" + requestHeader +
-                                " headers=" + urlConnection.getHeaderFields());
-                    }
-                } catch (IOException e) {
-                } finally {
-                    if (urlConnection != null) urlConnection.disconnect();
-                }
-                if (isDismissed(httpResponseCode, locationHeader, mProbeSpec)) {
-                    done(Result.DISMISSED);
-                }
-            }
-        }).start();
-    }
-
-    private static boolean isDismissed(
-            int httpResponseCode, String locationHeader, CaptivePortalProbeSpec probeSpec) {
-        return (probeSpec != null)
-                ? probeSpec.getResult(httpResponseCode, locationHeader).isSuccessful()
-                : (httpResponseCode == 204);
-    }
-
-    private class MyWebViewClient extends WebViewClient {
-        private static final String INTERNAL_ASSETS = "file:///android_asset/";
-
-        private final String mBrowserBailOutToken = Long.toString(new Random().nextLong());
-        private final String mCertificateOutToken = Long.toString(new Random().nextLong());
-        // How many Android device-independent-pixels per scaled-pixel
-        // dp/sp = (px/sp) / (px/dp) = (1/sp) / (1/dp)
-        private final float mDpPerSp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 1,
-                    getResources().getDisplayMetrics()) /
-                    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
-                    getResources().getDisplayMetrics());
-        private int mPagesLoaded;
-        private String mMainFrameUrl;
-
-        // If we haven't finished cleaning up the history, don't allow going back.
-        public boolean allowBack() {
-            return mPagesLoaded > 1;
-        }
-
-        private String mSslErrorTitle = null;
-        private SslErrorHandler mSslErrorHandler = null;
-        private SslError mSslError = null;
-
-        @Override
-        public void onPageStarted(WebView view, String urlString, Bitmap favicon) {
-            if (urlString.contains(mBrowserBailOutToken)) {
-                mLaunchBrowser = true;
-                done(Result.WANTED_AS_IS);
-                return;
-            }
-            // The first page load is used only to cause the WebView to
-            // fetch the proxy settings.  Don't update the URL bar, and
-            // don't check if the captive portal is still there.
-            if (mPagesLoaded == 0) {
-                return;
-            }
-            final URL url = makeURL(urlString);
-            Log.d(TAG, "onPageStarted: " + sanitizeURL(url));
-            // For internally generated pages, leave URL bar listing prior URL as this is the URL
-            // the page refers to.
-            if (!urlString.startsWith(INTERNAL_ASSETS)) {
-                String subtitle = (url != null) ? getHeaderSubtitle(url) : urlString;
-                getActionBar().setSubtitle(subtitle);
-            }
-            getProgressBar().setVisibility(View.VISIBLE);
-            testForCaptivePortal();
-        }
-
-        @Override
-        public void onPageFinished(WebView view, String url) {
-            mPagesLoaded++;
-            getProgressBar().setVisibility(View.INVISIBLE);
-            mSwipeRefreshLayout.setRefreshing(false);
-            if (mPagesLoaded == 1) {
-                // Now that WebView has loaded at least one page we know it has read in the proxy
-                // settings.  Now prompt the WebView read the Network-specific proxy settings.
-                setWebViewProxy();
-                // Load the real page.
-                view.loadUrl(mUrl.toString());
-                return;
-            } else if (mPagesLoaded == 2) {
-                // Prevent going back to empty first page.
-                // Fix for missing focus, see b/62449959 for details. Remove it once we get a
-                // newer version of WebView (60.x.y).
-                view.requestFocus();
-                view.clearHistory();
-            }
-            testForCaptivePortal();
-        }
-
-        // Convert Android scaled-pixels (sp) to HTML size.
-        private String sp(int sp) {
-            // Convert sp to dp's.
-            float dp = sp * mDpPerSp;
-            // Apply a scale factor to make things look right.
-            dp *= 1.3;
-            // Convert dp's to HTML size.
-            // HTML px's are scaled just like dp's, so just add "px" suffix.
-            return Integer.toString((int)dp) + "px";
-        }
-
-        // Check if webview is trying to load the main frame and record its url.
-        @Override
-        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
-            if (request.isForMainFrame()) {
-                mMainFrameUrl = request.getUrl().toString();
-            }
-            // Be careful that two shouldOverrideUrlLoading methods are overridden, but
-            // shouldOverrideUrlLoading(WebView view, String url) was deprecated in API level 24.
-            // TODO: delete deprecated one ??
-            return shouldOverrideUrlLoading(view, mMainFrameUrl);
-        }
-
-        // A web page consisting of a large broken lock icon to indicate SSL failure.
-
-        @Override
-        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
-            final URL errorUrl = makeURL(error.getUrl());
-            final URL mainFrameUrl = makeURL(mMainFrameUrl);
-            Log.d(TAG, String.format("SSL error: %s, url: %s, certificate: %s",
-                    sslErrorName(error), sanitizeURL(errorUrl), error.getCertificate()));
-            if (errorUrl == null
-                    // Ignore SSL errors from resources by comparing the main frame url with SSL
-                    // error url.
-                    || !errorUrl.equals(mainFrameUrl)) {
-                Log.d(TAG, "onReceivedSslError: mMainFrameUrl = " + mMainFrameUrl);
-                handler.cancel();
-                return;
-            }
-            logMetricsEvent(MetricsEvent.CAPTIVE_PORTAL_LOGIN_ACTIVITY_SSL_ERROR);
-            final String sslErrorPage = makeSslErrorPage();
-            view.loadDataWithBaseURL(INTERNAL_ASSETS, sslErrorPage, "text/HTML", "UTF-8", null);
-            mSslErrorTitle = view.getTitle() == null ? "" : view.getTitle();
-            mSslErrorHandler = handler;
-            mSslError = error;
-        }
-
-        private String makeSslErrorPage() {
-            final String warningMsg = getString(R.string.ssl_error_warning);
-            final String exampleMsg = getString(R.string.ssl_error_example);
-            final String continueMsg = getString(R.string.ssl_error_continue);
-            final String certificateMsg = getString(R.string.ssl_error_view_certificate);
-            return String.join("\n",
-                    "<html>",
-                    "<head>",
-                    "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
-                    "  <style>",
-                    "    body {",
-                    "      background-color:#fafafa;",
-                    "      margin:auto;",
-                    "      width:80%;",
-                    "      margin-top: 96px",
-                    "    }",
-                    "    img {",
-                    "      height:48px;",
-                    "      width:48px;",
-                    "    }",
-                    "    div.warn {",
-                    "      font-size:" + sp(16) + ";",
-                    "      line-height:1.28;",
-                    "      margin-top:16px;",
-                    "      opacity:0.87;",
-                    "    }",
-                    "    div.example {",
-                    "      font-size:" + sp(14) + ";",
-                    "      line-height:1.21905;",
-                    "      margin-top:16px;",
-                    "      opacity:0.54;",
-                    "    }",
-                    "    a {",
-                    "      color:#4285F4;",
-                    "      display:inline-block;",
-                    "      font-size:" + sp(14) + ";",
-                    "      font-weight:bold;",
-                    "      height:48px;",
-                    "      margin-top:24px;",
-                    "      text-decoration:none;",
-                    "      text-transform:uppercase;",
-                    "    }",
-                    "    a.certificate {",
-                    "      margin-top:0px;",
-                    "    }",
-                    "  </style>",
-                    "</head>",
-                    "<body>",
-                    "  <p><img src=quantum_ic_warning_amber_96.png><br>",
-                    "  <div class=warn>" + warningMsg + "</div>",
-                    "  <div class=example>" + exampleMsg + "</div>",
-                    "  <a href=" + mBrowserBailOutToken + ">" + continueMsg + "</a><br>",
-                    "  <a class=certificate href=" + mCertificateOutToken + ">" + certificateMsg +
-                            "</a>",
-                    "</body>",
-                    "</html>");
-        }
-
-        @Override
-        public boolean shouldOverrideUrlLoading (WebView view, String url) {
-            if (url.startsWith("tel:")) {
-                startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(url)));
-                return true;
-            }
-            if (url.contains(mCertificateOutToken) && mSslError != null) {
-                showSslAlertDialog(mSslErrorHandler, mSslError, mSslErrorTitle);
-                return true;
-            }
-            return false;
-        }
-        private void showSslAlertDialog(SslErrorHandler handler, SslError error, String title) {
-            final LayoutInflater factory = LayoutInflater.from(CaptivePortalLoginActivity.this);
-            final View sslWarningView = factory.inflate(R.layout.ssl_warning, null);
-
-            // Set Security certificate
-            setViewSecurityCertificate(sslWarningView.findViewById(R.id.certificate_layout), error);
-            ((TextView) sslWarningView.findViewById(R.id.ssl_error_type))
-                    .setText(sslErrorName(error));
-            ((TextView) sslWarningView.findViewById(R.id.title)).setText(mSslErrorTitle);
-            ((TextView) sslWarningView.findViewById(R.id.address)).setText(error.getUrl());
-
-            AlertDialog sslAlertDialog = new AlertDialog.Builder(CaptivePortalLoginActivity.this)
-                    .setTitle(R.string.ssl_security_warning_title)
-                    .setView(sslWarningView)
-                    .setPositiveButton(R.string.ok, (DialogInterface dialog, int whichButton) -> {
-                        // handler.cancel is called via OnCancelListener.
-                        dialog.cancel();
-                    })
-                    .setOnCancelListener((DialogInterface dialogInterface) -> handler.cancel())
-                    .create();
-            sslAlertDialog.show();
-        }
-
-        private void setViewSecurityCertificate(LinearLayout certificateLayout, SslError error) {
-            ((TextView) certificateLayout.findViewById(R.id.ssl_error_msg))
-                    .setText(sslErrorMessage(error));
-            SslCertificate cert = error.getCertificate();
-            // TODO: call the method directly once inflateCertificateView is @SystemApi
-            try {
-                final View certificateView = (View) SslCertificate.class.getMethod(
-                        "inflateCertificateView", Context.class)
-                        .invoke(cert, CaptivePortalLoginActivity.this);
-                certificateLayout.addView(certificateView);
-            } catch (ReflectiveOperationException | SecurityException e) {
-                Log.e(TAG, "Could not create certificate view", e);
-            }
-        }
-    }
-
-    private class MyWebChromeClient extends WebChromeClient {
-        @Override
-        public void onProgressChanged(WebView view, int newProgress) {
-            getProgressBar().setProgress(newProgress);
-        }
-    }
-
-    private ProgressBar getProgressBar() {
-        return findViewById(R.id.progress_bar);
-    }
-
-    private WebView getWebview() {
-        return findViewById(R.id.webview);
-    }
-
-    private String getHeaderTitle() {
-        NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork);
-        final String ssid = getSsid();
-        if (TextUtils.isEmpty(ssid)
-                || nc == null || !nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
-            return getString(R.string.action_bar_label);
-        }
-        return getString(R.string.action_bar_title, ssid);
-    }
-
-    // TODO: remove once SSID is obtained from NetworkCapabilities
-    private String getSsid() {
-        if (mWifiManager == null) {
-            return null;
-        }
-        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        return removeDoubleQuotes(wifiInfo.getSSID());
-    }
-
-    private static String removeDoubleQuotes(String string) {
-        if (string == null) return null;
-        final int length = string.length();
-        if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {
-            return string.substring(1, length - 1);
-        }
-        return string;
-    }
-
-    private String getHeaderSubtitle(URL url) {
-        String host = host(url);
-        final String https = "https";
-        if (https.equals(url.getProtocol())) {
-            return https + "://" + host;
-        }
-        return host;
-    }
-
-    private void logMetricsEvent(int event) {
-        mCaptivePortal.logEvent(event, getPackageName());
-    }
-
-    private static final SparseArray<String> SSL_ERRORS = new SparseArray<>();
-    static {
-        SSL_ERRORS.put(SslError.SSL_NOTYETVALID,  "SSL_NOTYETVALID");
-        SSL_ERRORS.put(SslError.SSL_EXPIRED,      "SSL_EXPIRED");
-        SSL_ERRORS.put(SslError.SSL_IDMISMATCH,   "SSL_IDMISMATCH");
-        SSL_ERRORS.put(SslError.SSL_UNTRUSTED,    "SSL_UNTRUSTED");
-        SSL_ERRORS.put(SslError.SSL_DATE_INVALID, "SSL_DATE_INVALID");
-        SSL_ERRORS.put(SslError.SSL_INVALID,      "SSL_INVALID");
-    }
-
-    private static String sslErrorName(SslError error) {
-        return SSL_ERRORS.get(error.getPrimaryError(), "UNKNOWN");
-    }
-
-    private static final SparseArray<Integer> SSL_ERROR_MSGS = new SparseArray<>();
-    static {
-        SSL_ERROR_MSGS.put(SslError.SSL_NOTYETVALID,  R.string.ssl_error_not_yet_valid);
-        SSL_ERROR_MSGS.put(SslError.SSL_EXPIRED,      R.string.ssl_error_expired);
-        SSL_ERROR_MSGS.put(SslError.SSL_IDMISMATCH,   R.string.ssl_error_mismatch);
-        SSL_ERROR_MSGS.put(SslError.SSL_UNTRUSTED,    R.string.ssl_error_untrusted);
-        SSL_ERROR_MSGS.put(SslError.SSL_DATE_INVALID, R.string.ssl_error_date_invalid);
-        SSL_ERROR_MSGS.put(SslError.SSL_INVALID,      R.string.ssl_error_invalid);
-    }
-
-    private static Integer sslErrorMessage(SslError error) {
-        return SSL_ERROR_MSGS.get(error.getPrimaryError(), R.string.ssl_error_unknown);
-    }
-}
diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp
index 589623b..61cab73 100644
--- a/packages/CarSystemUI/Android.bp
+++ b/packages/CarSystemUI/Android.bp
@@ -26,8 +26,8 @@
     ],
 
     static_libs: [
-        "CarNotificationLib",
         "SystemUI-core",
+        "CarNotificationLib",
         "SystemUIPluginLib",
         "SystemUISharedLib",
         "SettingsLib",
diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_navigation_bar.xml
index 49d78b6d5..897976f 100644
--- a/packages/CarSystemUI/res/layout/car_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_navigation_bar.xml
@@ -52,7 +52,7 @@
             style="@style/NavigationBarButton"
             systemui:categories="android.intent.category.APP_MAPS"
             systemui:icon="@drawable/car_ic_navigation"
-            systemui:intent="intent:#Intent;component=com.android.car.carlauncher/.CarLauncher;category=android.intent.category.APP_MAPS;launchFlags=0x24000000;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;launchFlags=0x14000000;end"
             systemui:selectedIcon="@drawable/car_ic_navigation_selected"
             systemui:useMoreIcon="false"
         />
diff --git a/packages/CarSystemUI/res/layout/car_volume_item.xml b/packages/CarSystemUI/res/layout/car_volume_item.xml
index 2275ca6..0b42904 100644
--- a/packages/CarSystemUI/res/layout/car_volume_item.xml
+++ b/packages/CarSystemUI/res/layout/car_volume_item.xml
@@ -19,16 +19,18 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
+    android:background="@color/car_volume_dialog_background_color"
+    android:paddingStart="@dimen/car_volume_item_padding_start"
+    android:paddingEnd="@dimen/car_volume_item_padding_end"
     android:minHeight="@dimen/car_volume_item_height">
 
     <!-- Primary Action. -->
     <ImageView
         android:id="@+id/primary_icon"
-        android:layout_width="@dimen/car_primary_icon_size"
+        android:layout_width="@dimen/car_volume_item_icon_size"
         android:layout_centerVertical="true"
-        android:layout_marginStart="@dimen/car_volume_item_margin_horizontal"
         android:layout_alignParentStart="true"
-        android:layout_height="@dimen/car_primary_icon_size"/>
+        android:layout_height="@dimen/car_volume_item_icon_size"/>
 
     <!-- Note: the horizontal padding and offset are set to 0 so that the track and thumb
              aligns with the proper keylines. -->
@@ -61,11 +63,10 @@
         android:background="@color/car_volume_item_divider_color"/>
     <ImageView
         android:id="@+id/supplemental_icon"
-        android:layout_width="@dimen/car_primary_icon_size"
-        android:layout_height="@dimen/car_primary_icon_size"
+        android:layout_width="@dimen/car_volume_item_icon_size"
+        android:layout_height="@dimen/car_volume_item_icon_size"
         android:background="?android:attr/selectableItemBackground"
         android:layout_centerVertical="true"
         android:layout_alignParentEnd="true"
-        android:layout_marginEnd="@dimen/car_volume_item_margin_horizontal"
         android:scaleType="fitCenter"/>
 </RelativeLayout>
diff --git a/packages/CarSystemUI/res/values-night/colors.xml b/packages/CarSystemUI/res/values-night/colors.xml
index dad94a8..a2edd7dc 100644
--- a/packages/CarSystemUI/res/values-night/colors.xml
+++ b/packages/CarSystemUI/res/values-night/colors.xml
@@ -19,6 +19,9 @@
     <color name="status_bar_background_color">#ff000000</color>
     <color name="system_bar_background_opaque">#ff0c1013</color>
 
+    <!-- The background color of the notification shade -->
+    <color name="notification_shade_background_color">#E0000000</color>
+    
     <!-- The color of the ripples on the untinted notifications -->
     <color name="notification_ripple_untinted_color">@color/ripple_material_dark</color>
 </resources>
diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml
index 72914f7..e0ae4566 100644
--- a/packages/CarSystemUI/res/values/colors.xml
+++ b/packages/CarSystemUI/res/values/colors.xml
@@ -32,10 +32,13 @@
     <color name="system_bar_background_opaque">#ff172026</color>
 
     <color name="status_bar_background_color">#33000000</color>
-    <drawable name="system_bar_background">@color/status_bar_background_color</drawable>
+    <drawable name="system_bar_background">@android:color/transparent</drawable>
 
     <!-- The background color of the notification shade -->
-    <color name="notification_shade_background_color">#DD000000</color>
+    <color name="notification_shade_background_color">#D6000000</color>
+
+    <!-- The background color of the car volume dialog -->
+    <color name="car_volume_dialog_background_color">@color/system_bar_background_opaque</color>
 
     <!-- The color of the dividing line between grouped notifications. -->
     <color name="notification_divider_color">@*android:color/notification_action_list</color>
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index d946fbc..467c4a4 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -29,6 +29,9 @@
     <bool name="config_enableRightNavigationBar">false</bool>
     <bool name="config_enableBottomNavigationBar">true</bool>
 
+    <!-- Whether heads-up notifications should be shown when shade is open. -->
+    <bool name="config_enableHeadsUpNotificationWhenNotificationShadeOpen">true</bool>
+
     <bool name="config_hideNavWhenKeyguardBouncerShown">true</bool>
     <bool name="config_enablePersistentDockedActivity">false</bool>
     <string name="config_persistentDockedActivityIntentUri" translatable="false"></string>
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
index 7027ce3..7592bd2 100644
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ b/packages/CarSystemUI/res/values/dimens.xml
@@ -98,8 +98,10 @@
     <dimen name="privacy_dialog_title_padding_start">10dp</dimen>
 
     <!-- Car volume dimens. -->
+    <dimen name="car_volume_item_icon_size">@dimen/car_primary_icon_size</dimen>
     <dimen name="car_volume_item_height">@*android:dimen/car_single_line_list_item_height</dimen>
-    <dimen name="car_volume_item_margin_horizontal">@*android:dimen/car_keyline_1</dimen>
+    <dimen name="car_volume_item_padding_start">@*android:dimen/car_keyline_1</dimen>
+    <dimen name="car_volume_item_padding_end">@*android:dimen/car_keyline_1</dimen>
     <dimen name="car_volume_item_seekbar_margin_vertical">@*android:dimen/car_padding_1</dimen>
     <dimen name="car_volume_item_seekbar_margin_start">@*android:dimen/car_keyline_3</dimen>
     <dimen name="car_volume_item_seekbar_margin_end">@*android:dimen/car_padding_4</dimen>
diff --git a/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
index 769fc52..f9cfafa 100644
--- a/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
+++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
@@ -171,11 +171,6 @@
     }
 
     @Override
-    public void setKeyguardShowing(boolean keyguardShowing) {
-        // No keyguard to show.
-    }
-
-    @Override
     public void animateHeaderSlidingIn(long delay) {
         // No header to animate.
     }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java
index a371a1d8..0421c3b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java
@@ -16,9 +16,11 @@
 
 package com.android.systemui.statusbar.car;
 
+import android.app.ActivityOptions;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
+import android.os.Build;
 import android.os.UserHandle;
 import android.util.AttributeSet;
 import android.view.Display;
@@ -33,9 +35,11 @@
 
 /**
  * CarFacetButton is a ui component designed to be used as a shortcut for an app of a defined
- * category. It can also render a indicator impling that there are more options of apps to launch
+ * category. It can also render a indicator implying that there are more options of apps to launch
  * using this component. This is done with a "More icon" currently an arrow as defined in the layout
  * file. The class is to serve as an example.
+ *
+ * New activity will be launched on the same display as the button is on.
  * Usage example: A button that allows a user to select a music app and indicate that there are
  * other music apps installed.
  */
@@ -111,15 +115,24 @@
             }
 
             setOnClickListener(v -> {
+                ActivityOptions options = ActivityOptions.makeBasic();
+                options.setLaunchDisplayId(mContext.getDisplayId());
                 intent.putExtra(EXTRA_FACET_LAUNCH_PICKER, mSelected);
-                mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+                mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
+                mContext.sendBroadcastAsUser(
+                        new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), UserHandle.CURRENT);
             });
 
-            if (longPressIntentString != null) {
+            if (longPressIntentString != null && (Build.IS_ENG || Build.IS_USERDEBUG)) {
                 final Intent longPressIntent = Intent.parseUri(longPressIntentString,
                         Intent.URI_INTENT_SCHEME);
                 setOnLongClickListener(v -> {
-                    mContext.startActivityAsUser(longPressIntent, UserHandle.CURRENT);
+                    ActivityOptions options = ActivityOptions.makeBasic();
+                    options.setLaunchDisplayId(mContext.getDisplayId());
+                    mContext.startActivityAsUser(longPressIntent, options.toBundle(),
+                            UserHandle.CURRENT);
+                    mContext.sendBroadcastAsUser(
+                            new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), UserHandle.CURRENT);
                     return true;
                 });
             }
@@ -192,9 +205,9 @@
     /**
      * Updates the visual state to let the user know if it's been selected.
      *
-     * @param selected     true if should update the alpha of the icon to selected, false otherwise
+     * @param selected true if should update the alpha of the icon to selected, false otherwise
      * @param showMoreIcon true if the "more icon" should be shown, false otherwise. Note this
-     *                     is ignored if the attribute useMoreIcon is set to false
+     * is ignored if the attribute useMoreIcon is set to false
      */
     public void setSelected(boolean selected, boolean showMoreIcon) {
         mSelected = selected;
@@ -207,7 +220,7 @@
 
     /**
      * @return The id of the display the button is on or Display.INVALID_DISPLAY if it's not yet on
-     *         a display.
+     * a display.
      */
     public int getDisplayId() {
         Display display = getDisplay();
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 095e2e9..05a41e6 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.car;
 
 import android.content.Context;
-import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -75,40 +74,13 @@
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         if (mStatusBarWindowTouchListener != null) {
-            boolean shouldConsumeEvent = shouldConsumeNotificationButtonEvent(ev);
             // Forward touch events to the status bar window so it can drag
             // windows if required (Notification shade)
             mStatusBarWindowTouchListener.onTouch(this, ev);
-            // return true if child views should not receive this event.
-            if (shouldConsumeEvent) {
-                return true;
-            }
         }
         return super.onInterceptTouchEvent(ev);
     }
 
-    /**
-     * If the motion event is over top of the notification button while the notification
-     * panel is open, we need the statusbar touch listeners handle the event instead of the button.
-     * Since the statusbar listener will trigger a close of the notification panel before the
-     * any button click events are fired this will prevent reopening the panel.
-     *
-     * Note: we can't use requestDisallowInterceptTouchEvent because the gesture detector will
-     * always receive the ACTION_DOWN and thus think a longpress happened if no other events are
-     * received
-     *
-     * @return true if the notification button should not receive the event
-     */
-    private boolean shouldConsumeNotificationButtonEvent(MotionEvent ev) {
-        if (mNotificationsButton == null || !mCarStatusBar.isNotificationPanelOpen()) {
-            return false;
-        }
-        Rect notificationButtonLocation = new Rect();
-        mNotificationsButton.getHitRect(notificationButtonLocation);
-        return notificationButtonLocation.contains((int) ev.getX(), (int) ev.getY());
-    }
-
-
     void setStatusBar(CarStatusBar carStatusBar) {
         mCarStatusBar = carStatusBar;
     }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index 8879742..c0dcbbc 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -16,9 +16,11 @@
 
 package com.android.systemui.statusbar.car;
 
+import android.app.ActivityOptions;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
+import android.os.Build;
 import android.os.UserHandle;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -68,13 +70,9 @@
                 R.styleable.CarNavigationButton_unselectedAlpha, mUnselectedAlpha);
         mSelectedIconResourceId = typedArray.getResourceId(
                 R.styleable.CarNavigationButton_selectedIcon, mIconResourceId);
+        mIconResourceId = typedArray.getResourceId(
+                R.styleable.CarNavigationButton_icon, 0);
         typedArray.recycle();
-
-        // ImageView attrs
-        TypedArray a = context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.ImageView);
-        mIconResourceId = a.getResourceId(com.android.internal.R.styleable.ImageView_src, 0);
-        a.recycle();
     }
 
 
@@ -94,9 +92,15 @@
                     try {
                         if (mBroadcastIntent) {
                             mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
+                            mContext.sendBroadcastAsUser(
+                                    new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
+                                    UserHandle.CURRENT);
                             return;
                         }
-                        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+                        ActivityOptions options = ActivityOptions.makeBasic();
+                        options.setLaunchDisplayId(mContext.getDisplayId());
+                        mContext.startActivityAsUser(intent, options.toBundle(),
+                                UserHandle.CURRENT);
                     } catch (Exception e) {
                         Log.e(TAG, "Failed to launch intent", e);
                     }
@@ -107,11 +111,14 @@
         }
 
         try {
-            if (mLongIntent != null) {
+            if (mLongIntent != null && (Build.IS_ENG || Build.IS_USERDEBUG)) {
                 final Intent intent = Intent.parseUri(mLongIntent, Intent.URI_INTENT_SCHEME);
                 setOnLongClickListener(v -> {
                     try {
-                        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+                        ActivityOptions options = ActivityOptions.makeBasic();
+                        options.setLaunchDisplayId(mContext.getDisplayId());
+                        mContext.startActivityAsUser(intent, options.toBundle(),
+                                UserHandle.CURRENT);
                     } catch (Exception e) {
                         Log.e(TAG, "Failed to launch intent", e);
                     }
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 7fbdc2e..b1f9797 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -27,6 +27,7 @@
 import android.car.drivingstate.CarUxRestrictionsManager;
 import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -61,8 +62,9 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.classifier.FalsingLog;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -127,6 +129,7 @@
     private SwitchToGuestTimer mSwitchToGuestTimer;
     private NotificationDataManager mNotificationDataManager;
     private NotificationClickHandlerFactory mNotificationClickHandlerFactory;
+    private ScreenLifecycle mScreenLifecycle;
 
     // The container for the notifications.
     private CarNotificationView mNotificationView;
@@ -163,6 +166,8 @@
     private boolean mIsNotificationCardSwiping;
     // If notification shade is being swiped vertically to close.
     private boolean mIsSwipingVerticallyToClose;
+    // Whether heads-up notifications should be shown when shade is open.
+    private boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
 
     private final CarPowerStateListener mCarPowerStateListener =
             (int state) -> {
@@ -230,6 +235,9 @@
         mPowerManagerHelper.connectToCarService();
 
         mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
+
+        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
+        mScreenLifecycle.addObserver(mScreenObserver);
     }
 
     /**
@@ -315,7 +323,6 @@
     public void showKeyguard() {
         super.showKeyguard();
         updateNavBarForKeyguardContent();
-        dismissKeyguardWhenUserSwitcherNotDisplayed();
     }
 
     /**
@@ -340,7 +347,7 @@
 
         CarSystemUIFactory factory = SystemUIFactory.getInstance();
         mCarFacetButtonController = factory.getCarDependencyComponent()
-            .getCarFacetButtonController();
+                .getCarFacetButtonController();
         mNotificationPanelBackground = getDefaultWallpaper();
         mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
 
@@ -419,14 +426,13 @@
                 }
         );
 
-        mNotificationClickHandlerFactory = new NotificationClickHandlerFactory(
-                mBarService,
-                launchResult -> {
-                    if (launchResult == ActivityManager.START_TASK_TO_FRONT
-                            || launchResult == ActivityManager.START_SUCCESS) {
-                        animateCollapsePanels();
-                    }
-                });
+        mNotificationClickHandlerFactory = new NotificationClickHandlerFactory(mBarService);
+        mNotificationClickHandlerFactory.registerClickListener((launchResult, alertEntry) -> {
+            if (launchResult == ActivityManager.START_TASK_TO_FRONT
+                    || launchResult == ActivityManager.START_SUCCESS) {
+                animateCollapsePanels();
+            }
+        });
         Car car = Car.createCar(mContext);
         CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
                 car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
@@ -455,6 +461,8 @@
                     }
                 });
 
+        mEnableHeadsUpNotificationWhenNotificationShadeOpen = mContext.getResources().getBoolean(
+                R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen);
         CarHeadsUpNotificationManager carHeadsUpNotificationManager =
                 new CarSystemUIHeadsUpNotificationManager(mContext,
                         mNotificationClickHandlerFactory, mNotificationDataManager);
@@ -630,13 +638,14 @@
         }
 
         Rect rect = mNotificationView.getClipBounds();
-        if (rect != null) {
+        if (rect != null && rect.bottom != to) {
             float from = rect.bottom;
             animate(from, to, velocity, isClosing);
             return;
         }
 
-        // We will only be here if the shade is being opened programmatically.
+        // We will only be here if the shade is being opened programmatically or via button when
+        // height of the layout was not calculated.
         ViewTreeObserver notificationTreeObserver = mNotificationView.getViewTreeObserver();
         notificationTreeObserver.addOnGlobalLayoutListener(
                 new ViewTreeObserver.OnGlobalLayoutListener() {
@@ -674,11 +683,11 @@
                     mStatusBarWindowController.setPanelVisible(false);
                     mNotificationView.setVisibility(View.INVISIBLE);
                     mNotificationView.setClipBounds(null);
-                    mNotificationViewController.setIsInForeground(false);
+                    mNotificationViewController.onVisibilityChanged(false);
                     // let the status bar know that the panel is closed
                     setPanelExpanded(false);
                 } else {
-                    mNotificationViewController.setIsInForeground(true);
+                    mNotificationViewController.onVisibilityChanged(true);
                     // let the status bar know that the panel is open
                     mNotificationView.setVisibleNotificationsAsSeen();
                     setPanelExpanded(true);
@@ -869,7 +878,7 @@
             KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
         }
 
-        FalsingManagerFactory.getInstance(mContext).dump(pw);
+        Dependency.get(FalsingManager.class).dump(pw);
         FalsingLog.dump(pw);
 
         pw.println("SharedPreferences:");
@@ -917,6 +926,16 @@
                 Log.e(TAG, "Getting StackInfo from activity manager failed", e);
             }
         }
+
+        @Override
+        public void onTaskDisplayChanged(int taskId, int newDisplayId) {
+            try {
+                mCarFacetButtonController.taskChanged(
+                        ActivityTaskManager.getService().getAllStackInfos());
+            } catch (Exception e) {
+                Log.e(TAG, "Getting StackInfo from activity manager failed", e);
+            }
+        }
     }
 
     private void onDrivingStateChanged(CarDrivingStateEvent notUsed) {
@@ -978,6 +997,13 @@
         }
     }
 
+    final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
+        @Override
+        public void onScreenTurnedOn() {
+            dismissKeyguardWhenUserSwitcherNotDisplayed();
+        }
+    };
+
     // We automatically dismiss keyguard unless user switcher is being shown on the keyguard.
     private void dismissKeyguardWhenUserSwitcherNotDisplayed() {
         if (mFullscreenUserSwitcher == null) {
@@ -1000,6 +1026,10 @@
      * Dismisses the keyguard and shows bouncer if authentication is necessary.
      */
     public void dismissKeyguard() {
+        // Don't dismiss keyguard when the screen is off.
+        if (mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF) {
+            return;
+        }
         executeRunnableDismissingKeyguard(null/* runnable */, null /* cancelAction */,
                 true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
     }
@@ -1043,9 +1073,25 @@
             // shade is visible to the user. When the notification shade is completely open then
             // alpha value will be 1.
             float alpha = (float) height / mNotificationView.getHeight();
-            Drawable background = mNotificationView.getBackground();
+            Drawable background = mNotificationView.getBackground().mutate();
 
             background.setAlpha((int) (alpha * 255));
+            mNotificationView.setBackground(background);
+        }
+    }
+
+    @Override
+    public void onConfigChanged(Configuration newConfig) {
+        super.onConfigChanged(newConfig);
+
+        int uiModeNightMask = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK);
+
+        boolean dayNightModeChanged = uiModeNightMask == Configuration.UI_MODE_NIGHT_YES
+                || uiModeNightMask == Configuration.UI_MODE_NIGHT_NO;
+
+        if (dayNightModeChanged) {
+            mNotificationView.setBackgroundColor(
+                    mContext.getColor(R.color.notification_shade_background_color));
         }
     }
 
@@ -1203,13 +1249,6 @@
             setNotificationViewClipBounds((int) event2.getRawY());
             return true;
         }
-
-        @Override
-        public void onLongPress(MotionEvent e) {
-            mClosingVelocity = DEFAULT_FLING_VELOCITY;
-            close();
-            super.onLongPress(e);
-        }
     }
 
     /**
@@ -1258,7 +1297,18 @@
         }
 
         @Override
+        protected void setInternalInsetsInfo(ViewTreeObserver.InternalInsetsInfo info,
+                HeadsUpEntry currentNotification, boolean panelExpanded) {
+            super.setInternalInsetsInfo(info, currentNotification, mPanelExpanded);
+        }
+
+        @Override
         protected void setHeadsUpVisible() {
+            // if the Notifications panel is showing don't show the Heads up
+            if (!mEnableHeadsUpNotificationWhenNotificationShadeOpen && mPanelExpanded) {
+                return;
+            }
+
             super.setHeadsUpVisible();
             if (mHeadsUpPanel.getVisibility() == View.VISIBLE) {
                 mStatusBarWindowController.setHeadsUpShowing(true);
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 94962f7..d0a63f0 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -32,7 +32,9 @@
 import android.content.ServiceConnection;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.graphics.Color;
 import android.graphics.PixelFormat;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.os.Debug;
@@ -245,6 +247,7 @@
         mExpanded = false;
         mWindow = mDialog.getWindow();
         mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+        mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
         mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
                 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
         mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
diff --git a/packages/CarrierDefaultApp/res/values-in/strings.xml b/packages/CarrierDefaultApp/res/values-in/strings.xml
index 01a9c60..f48d31f 100644
--- a/packages/CarrierDefaultApp/res/values-in/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-in/strings.xml
@@ -5,7 +5,7 @@
     <string name="android_system_label" msgid="2797790869522345065">"Operator Seluler"</string>
     <string name="portal_notification_id" msgid="5155057562457079297">"Data seluler telah habis"</string>
     <string name="no_data_notification_id" msgid="668400731803969521">"Data seluler telah dinonaktifkan"</string>
-    <string name="portal_notification_detail" msgid="2295729385924660881">"Tap untuk membuka situs web %s"</string>
+    <string name="portal_notification_detail" msgid="2295729385924660881">"Ketuk untuk membuka situs web %s"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"Hubungi penyedia layanan %s"</string>
     <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"Tidak ada sambungan data seluler"</string>
     <string name="no_mobile_data_connection" msgid="544980465184147010">"Tambahkan paket data atau roaming melalui %s"</string>
diff --git a/packages/EasterEgg/AndroidManifest.xml b/packages/EasterEgg/AndroidManifest.xml
index c7dd40d..7f76a45 100644
--- a/packages/EasterEgg/AndroidManifest.xml
+++ b/packages/EasterEgg/AndroidManifest.xml
@@ -1,40 +1,38 @@
 <?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.egg"
     android:versionCode="1"
     android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="28" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
 
     <application
-        android:icon="@drawable/icon"
+        android:icon="@drawable/q_icon"
         android:label="@string/app_name">
+        <activity android:name=".quares.QuaresActivity"
+            android:icon="@drawable/q_icon"
+            android:label="@string/q_egg_name"
+            android:theme="@style/QuaresTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
 
+                <category android:name="android.intent.category.DEFAULT" />
+                <!-- <category android:name="android.intent.category.LAUNCHER" /> -->
+                <category android:name="com.android.internal.category.PLATLOGO" />
+            </intent-filter>
+        </activity>
         <activity
             android:name=".paint.PaintActivity"
             android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
-            android:label="@string/app_name"
+            android:icon="@drawable/p_icon"
+            android:label="@string/p_egg_name"
             android:theme="@style/AppTheme">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <!--<category android:name="android.intent.category.LAUNCHER" />-->
-                <category android:name="com.android.internal.category.PLATLOGO" />
+
+                <!-- <category android:name="android.intent.category.DEFAULT" /> -->
+                <!-- <category android:name="android.intent.category.LAUNCHER" /> -->
+                <!-- <category android:name="com.android.internal.category.PLATLOGO" /> -->
             </intent-filter>
         </activity>
     </application>
diff --git a/packages/EasterEgg/res/drawable/icon_bg.xml b/packages/EasterEgg/res/drawable/icon_bg.xml
index c1553ce..659f98b 100644
--- a/packages/EasterEgg/res/drawable/icon_bg.xml
+++ b/packages/EasterEgg/res/drawable/icon_bg.xml
@@ -15,4 +15,4 @@
     limitations under the License.
 -->
 <color xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="#C5E1A5" />
\ No newline at end of file
+    android:color="@color/q_clue_text" />
diff --git a/packages/EasterEgg/res/drawable/icon.xml b/packages/EasterEgg/res/drawable/p_icon.xml
similarity index 100%
rename from packages/EasterEgg/res/drawable/icon.xml
rename to packages/EasterEgg/res/drawable/p_icon.xml
diff --git a/packages/EasterEgg/res/drawable/pixel_bg.xml b/packages/EasterEgg/res/drawable/pixel_bg.xml
new file mode 100644
index 0000000..4d4a113
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/pixel_bg.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:exitFadeDuration="100">
+    <item android:state_pressed="true">
+        <shape><solid android:color="@color/red"/></shape>
+    </item>
+    <item android:state_checked="true">
+        <shape><solid android:color="@color/pixel_on"/></shape>
+    </item>
+    <item>
+        <shape><solid android:color="@color/pixel_off"/></shape>
+    </item>
+</selector>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/drawable/q.xml b/packages/EasterEgg/res/drawable/q.xml
new file mode 100644
index 0000000..75baa47
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/q.xml
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+<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="@color/q_icon_fg"
+        android:pathData="M19.45,22.89l-10.250001,-10.249999l-2.6599998,2.6599998l-1.77,-1.7600002l4.43,-4.4300003l12.0199995,12.0199995l-1.7699986,1.7600002z"/>
+    <path
+        android:fillColor="@color/q_icon_fg"
+        android:pathData="M12,6a6,6 0,1 1,-6 6,6 6,0 0,1 6,-6m0,-2.5A8.5,8.5 0,1 0,20.5 12,8.51 8.51,0 0,0 12,3.5Z"/>
+</vector>
diff --git a/packages/EasterEgg/res/drawable/q_icon.xml b/packages/EasterEgg/res/drawable/q_icon.xml
new file mode 100644
index 0000000..ef4b0a3
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/q_icon.xml
@@ -0,0 +1,19 @@
+<!--
+    Copyright (C) 2019 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/icon_bg"/>
+    <foreground android:drawable="@drawable/q_smaller"/>
+</adaptive-icon>
diff --git a/packages/EasterEgg/res/drawable/q_smaller.xml b/packages/EasterEgg/res/drawable/q_smaller.xml
new file mode 100644
index 0000000..c71dff0
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/q_smaller.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.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:insetBottom="5dp"
+        android:insetLeft="5dp"
+        android:insetRight="5dp"
+        android:insetTop="5dp"
+        android:drawable="@drawable/q" />
diff --git a/packages/EasterEgg/res/layout/activity_quares.xml b/packages/EasterEgg/res/layout/activity_quares.xml
new file mode 100644
index 0000000..dcc90f6
--- /dev/null
+++ b/packages/EasterEgg/res/layout/activity_quares.xml
@@ -0,0 +1,46 @@
+<?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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:animateLayoutChanges="true"
+    tools:context="com.android.egg.quares.QuaresActivity">
+
+   <GridLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:alignmentMode="alignBounds"
+        android:id="@+id/grid"
+        />
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/label"
+        android:layout_gravity="center_horizontal|bottom"
+        android:gravity="center"
+        android:textSize="18dp"
+        android:visibility="gone"
+        android:drawablePadding="8dp"
+        android:padding="12dp"
+        android:backgroundTint="@color/q_clue_bg_correct"
+        android:textColor="@color/q_clue_text"
+        android:layout_marginBottom="48dp"
+        android:elevation="30dp"
+        />
+</FrameLayout>
diff --git a/packages/EasterEgg/res/values-night/q_colors.xml b/packages/EasterEgg/res/values-night/q_colors.xml
new file mode 100644
index 0000000..191bd94
--- /dev/null
+++ b/packages/EasterEgg/res/values-night/q_colors.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<resources>
+    <color name="pixel_off">#000000</color>
+    <color name="pixel_on">#FFFFFF</color>
+
+    <color name="q_clue_bg">@color/navy</color>
+    <color name="q_clue_text">@color/tan</color>
+</resources>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/values/q_colors.xml b/packages/EasterEgg/res/values/q_colors.xml
new file mode 100644
index 0000000..5e92c84
--- /dev/null
+++ b/packages/EasterEgg/res/values/q_colors.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<resources>
+    <color name="emerald">#3ddc84</color>
+    <color name="red">#f8c734</color>
+    <color name="navy">#073042</color>
+    <color name="vapor">#d7effe</color>
+    <color name="tan">#eff7cf</color>
+
+    <color name="pixel_off">#FFFFFF</color>
+    <color name="pixel_on">#000000</color>
+
+    <color name="q_clue_bg">@color/tan</color>
+    <color name="q_clue_text">@color/navy</color>
+    <color name="q_clue_bg_correct">@color/emerald</color>
+
+    <color name="q_icon_fg">@color/emerald</color>
+</resources>
diff --git a/packages/EasterEgg/res/values/q_puzzles.xml b/packages/EasterEgg/res/values/q_puzzles.xml
new file mode 100644
index 0000000..7c2eff1
--- /dev/null
+++ b/packages/EasterEgg/res/values/q_puzzles.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string-array name="puzzles">
+
+        <item>q</item>
+        <item>q</item>
+        <item>q</item>
+        <item>q</item>
+        <item>q</item>
+
+        <item>android:drawable/ic_info</item>
+
+        <item>android:drawable/stat_sys_adb</item>
+        <item>android:drawable/stat_sys_battery</item>
+        <item>android:drawable/stat_sys_phone_call</item>
+        <item>android:drawable/stat_sys_certificate_info</item>
+        <item>android:drawable/stat_sys_data_bluetooth</item>
+        <item>android:drawable/stat_sys_data_usb</item>
+        <item>android:drawable/stat_sys_download</item>
+        <item>android:drawable/stat_sys_gps_on</item>
+        <item>android:drawable/stat_sys_phone_call</item>
+        <item>android:drawable/stat_sys_tether_wifi</item>
+        <item>android:drawable/stat_sys_throttled</item>
+        <item>android:drawable/stat_sys_upload</item>
+
+        <item>android:drawable/stat_notify_car_mode</item>
+        <item>android:drawable/stat_notify_chat</item>
+        <item>android:drawable/stat_notify_disk_full</item>
+        <item>android:drawable/stat_notify_email_generic</item>
+        <item>android:drawable/stat_notify_error</item>
+        <item>android:drawable/stat_notify_gmail</item>
+        <item>android:drawable/stat_notify_missed_call</item>
+        <item>android:drawable/stat_notify_mmcc_indication_icn</item>
+        <item>android:drawable/stat_notify_more</item>
+        <item>android:drawable/stat_notify_rssi_in_range</item>
+        <item>android:drawable/stat_notify_sdcard</item>
+        <item>android:drawable/stat_notify_sdcard_prepare</item>
+        <item>android:drawable/stat_notify_sdcard_usb</item>
+        <item>android:drawable/stat_notify_sim_toolkit</item>
+        <item>android:drawable/stat_notify_sync</item>
+        <item>android:drawable/stat_notify_sync_anim0</item>
+        <item>android:drawable/stat_notify_sync_error</item>
+        <item>android:drawable/stat_notify_voicemail</item>
+
+        <item>android:drawable/ic_audio_alarm</item>
+        <item>android:drawable/ic_audio_alarm_mute</item>
+        <item>android:drawable/ic_bluetooth_share_icon</item>
+        <item>android:drawable/ic_bt_headphones_a2dp</item>
+        <item>android:drawable/ic_bt_headset_hfp</item>
+        <item>android:drawable/ic_bt_hearing_aid</item>
+        <item>android:drawable/ic_bt_laptop</item>
+        <item>android:drawable/ic_bt_misc_hid</item>
+        <item>android:drawable/ic_bt_network_pan</item>
+        <item>android:drawable/ic_bt_pointing_hid</item>
+        <item>android:drawable/ic_corp_badge</item>
+        <item>android:drawable/ic_expand_more</item>
+        <item>android:drawable/ic_faster_emergency</item>
+        <item>android:drawable/ic_file_copy</item>
+        <item>android:drawable/ic_info_outline_24</item>
+        <item>android:drawable/ic_lock</item>
+        <item>android:drawable/ic_lock_bugreport</item>
+        <item>android:drawable/ic_lock_open</item>
+        <item>android:drawable/ic_lock_power_off</item>
+        <item>android:drawable/ic_lockscreen_ime</item>
+        <item>android:drawable/ic_mode_edit</item>
+        <item>android:drawable/ic_phone</item>
+        <item>android:drawable/ic_qs_airplane</item>
+        <item>android:drawable/ic_qs_auto_rotate</item>
+        <item>android:drawable/ic_qs_battery_saver</item>
+        <item>android:drawable/ic_qs_bluetooth</item>
+        <item>android:drawable/ic_qs_dnd</item>
+        <item>android:drawable/ic_qs_flashlight</item>
+        <item>android:drawable/ic_qs_night_display_on</item>
+        <item>android:drawable/ic_restart</item>
+        <item>android:drawable/ic_screenshot</item>
+        <item>android:drawable/ic_settings_bluetooth</item>
+        <item>android:drawable/ic_signal_cellular_0_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_0_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_1_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_1_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_2_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_2_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_3_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_3_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_4_4_bar</item>
+        <item>android:drawable/ic_signal_cellular_4_5_bar</item>
+        <item>android:drawable/ic_signal_cellular_5_5_bar</item>
+        <item>android:drawable/ic_signal_location</item>
+        <item>android:drawable/ic_wifi_signal_0</item>
+        <item>android:drawable/ic_wifi_signal_1</item>
+        <item>android:drawable/ic_wifi_signal_2</item>
+        <item>android:drawable/ic_wifi_signal_3</item>
+        <item>android:drawable/ic_wifi_signal_4</item>
+        <item>android:drawable/perm_group_activity_recognition</item>
+        <item>android:drawable/perm_group_calendar</item>
+        <item>android:drawable/perm_group_call_log</item>
+        <item>android:drawable/perm_group_camera</item>
+        <item>android:drawable/perm_group_contacts</item>
+        <item>android:drawable/perm_group_location</item>
+        <item>android:drawable/perm_group_microphone</item>
+        <item>android:drawable/perm_group_phone_calls</item>
+        <item>android:drawable/perm_group_sensors</item>
+        <item>android:drawable/perm_group_sms</item>
+        <item>android:drawable/perm_group_storage</item>
+        <item>android:drawable/perm_group_visual</item>
+
+        <item>com.android.settings:drawable/ic_add_24dp</item>
+        <item>com.android.settings:drawable/ic_airplanemode_active</item>
+        <item>com.android.settings:drawable/ic_android</item>
+        <item>com.android.settings:drawable/ic_apps</item>
+        <item>com.android.settings:drawable/ic_arrow_back</item>
+        <item>com.android.settings:drawable/ic_arrow_down_24dp</item>
+        <item>com.android.settings:drawable/ic_battery_charging_full</item>
+        <item>com.android.settings:drawable/ic_battery_status_bad_24dp</item>
+        <item>com.android.settings:drawable/ic_battery_status_good_24dp</item>
+        <item>com.android.settings:drawable/ic_battery_status_maybe_24dp</item>
+        <item>com.android.settings:drawable/ic_call_24dp</item>
+        <item>com.android.settings:drawable/ic_cancel</item>
+        <item>com.android.settings:drawable/ic_cast_24dp</item>
+        <item>com.android.settings:drawable/ic_chevron_right_24dp</item>
+        <item>com.android.settings:drawable/ic_data_saver</item>
+        <item>com.android.settings:drawable/ic_delete</item>
+        <item>com.android.settings:drawable/ic_devices_other</item>
+        <item>com.android.settings:drawable/ic_devices_other_opaque_black</item>
+        <item>com.android.settings:drawable/ic_do_not_disturb_on_24dp</item>
+        <item>com.android.settings:drawable/ic_eject_24dp</item>
+        <item>com.android.settings:drawable/ic_expand_less</item>
+        <item>com.android.settings:drawable/ic_expand_more_inverse</item>
+        <item>com.android.settings:drawable/ic_folder_vd_theme_24</item>
+        <item>com.android.settings:drawable/ic_friction_lock_closed</item>
+        <item>com.android.settings:drawable/ic_gray_scale_24dp</item>
+        <item>com.android.settings:drawable/ic_headset_24dp</item>
+        <item>com.android.settings:drawable/ic_help</item>
+        <item>com.android.settings:drawable/ic_local_movies</item>
+        <item>com.android.settings:drawable/ic_lock</item>
+        <item>com.android.settings:drawable/ic_media_stream</item>
+        <item>com.android.settings:drawable/ic_network_cell</item>
+        <item>com.android.settings:drawable/ic_notifications</item>
+        <item>com.android.settings:drawable/ic_notifications_off_24dp</item>
+        <item>com.android.settings:drawable/ic_phone_info</item>
+        <item>com.android.settings:drawable/ic_photo_library</item>
+        <item>com.android.settings:drawable/ic_settings_accessibility</item>
+        <item>com.android.settings:drawable/ic_settings_accounts</item>
+        <item>com.android.settings:drawable/ic_settings_backup</item>
+        <item>com.android.settings:drawable/ic_settings_battery_white</item>
+        <item>com.android.settings:drawable/ic_settings_data_usage</item>
+        <item>com.android.settings:drawable/ic_settings_date_time</item>
+        <item>com.android.settings:drawable/ic_settings_delete</item>
+        <item>com.android.settings:drawable/ic_settings_display_white</item>
+        <item>com.android.settings:drawable/ic_settings_home</item>
+        <item>com.android.settings:drawable/ic_settings_location</item>
+        <item>com.android.settings:drawable/ic_settings_night_display</item>
+        <item>com.android.settings:drawable/ic_settings_open</item>
+        <item>com.android.settings:drawable/ic_settings_print</item>
+        <item>com.android.settings:drawable/ic_settings_privacy</item>
+        <item>com.android.settings:drawable/ic_settings_security_white</item>
+        <item>com.android.settings:drawable/ic_settings_sim</item>
+        <item>com.android.settings:drawable/ic_settings_wireless</item>
+        <item>com.android.settings:drawable/ic_storage</item>
+        <item>com.android.settings:drawable/ic_storage_white</item>
+        <item>com.android.settings:drawable/ic_suggestion_night_display</item>
+        <item>com.android.settings:drawable/ic_sync</item>
+        <item>com.android.settings:drawable/ic_system_update</item>
+        <item>com.android.settings:drawable/ic_videogame_vd_theme_24</item>
+        <item>com.android.settings:drawable/ic_volume_ringer_vibrate</item>
+        <item>com.android.settings:drawable/ic_volume_up_24dp</item>
+        <item>com.android.settings:drawable/ic_vpn_key</item>
+        <item>com.android.settings:drawable/ic_wifi_tethering</item>
+
+        <item>com.android.systemui:drawable/ic_alarm</item>
+        <item>com.android.systemui:drawable/ic_alarm_dim</item>
+        <item>com.android.systemui:drawable/ic_arrow_back</item>
+        <item>com.android.systemui:drawable/ic_bluetooth_connected</item>
+        <item>com.android.systemui:drawable/ic_brightness_thumb</item>
+        <item>com.android.systemui:drawable/ic_camera</item>
+        <item>com.android.systemui:drawable/ic_cast</item>
+        <item>com.android.systemui:drawable/ic_cast_connected</item>
+        <item>com.android.systemui:drawable/ic_cast_connected_fill</item>
+        <item>com.android.systemui:drawable/ic_close_white</item>
+        <item>com.android.systemui:drawable/ic_data_saver</item>
+        <item>com.android.systemui:drawable/ic_data_saver_off</item>
+        <item>com.android.systemui:drawable/ic_drag_handle</item>
+        <item>com.android.systemui:drawable/ic_headset</item>
+        <item>com.android.systemui:drawable/ic_headset_mic</item>
+        <item>com.android.systemui:drawable/ic_hotspot</item>
+        <item>com.android.systemui:drawable/ic_invert_colors</item>
+        <item>com.android.systemui:drawable/ic_location</item>
+        <item>com.android.systemui:drawable/ic_lockscreen_ime</item>
+        <item>com.android.systemui:drawable/ic_notifications_alert</item>
+        <item>com.android.systemui:drawable/ic_notifications_silence</item>
+        <item>com.android.systemui:drawable/ic_power_low</item>
+        <item>com.android.systemui:drawable/ic_power_saver</item>
+        <item>com.android.systemui:drawable/ic_qs_bluetooth_connecting</item>
+        <item>com.android.systemui:drawable/ic_qs_bluetooth_on</item>
+        <item>com.android.systemui:drawable/ic_qs_cancel</item>
+        <item>com.android.systemui:drawable/ic_qs_no_sim</item>
+        <item>com.android.systemui:drawable/ic_screenshot_delete</item>
+        <item>com.android.systemui:drawable/ic_settings</item>
+        <item>com.android.systemui:drawable/ic_swap_vert</item>
+        <item>com.android.systemui:drawable/ic_volume_alarm</item>
+        <item>com.android.systemui:drawable/ic_volume_alarm_mute</item>
+        <item>com.android.systemui:drawable/ic_volume_media</item>
+        <item>com.android.systemui:drawable/ic_volume_media_mute</item>
+        <item>com.android.systemui:drawable/ic_volume_ringer</item>
+        <item>com.android.systemui:drawable/ic_volume_ringer_mute</item>
+        <item>com.android.systemui:drawable/ic_volume_ringer_vibrate</item>
+        <item>com.android.systemui:drawable/ic_volume_voice</item>
+        <item>com.android.systemui:drawable/stat_sys_camera</item>
+        <item>com.android.systemui:drawable/stat_sys_managed_profile_status</item>
+        <item>com.android.systemui:drawable/stat_sys_mic_none</item>
+        <item>com.android.systemui:drawable/stat_sys_vpn_ic</item>
+
+    </string-array>
+</resources>
diff --git a/packages/EasterEgg/res/values/strings.xml b/packages/EasterEgg/res/values/strings.xml
index 32dbc97..b95ec6b 100644
--- a/packages/EasterEgg/res/values/strings.xml
+++ b/packages/EasterEgg/res/values/strings.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -15,5 +14,11 @@
     limitations under the License.
 -->
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <string name="app_name" translatable="false">PAINT.APK</string>
+    <string name="app_name" translatable="false">Android Q Easter Egg</string>
+
+    <!-- name of the Q easter egg, a nonogram-style icon puzzle -->
+    <string name="q_egg_name" translatable="false">Icon Quiz</string>
+
+    <!-- name of the P easter egg, a humble paint program -->
+    <string name="p_egg_name" translatable="false">PAINT.APK</string>
 </resources>
diff --git a/packages/EasterEgg/res/values/styles.xml b/packages/EasterEgg/res/values/styles.xml
index 44e2ce5..e576526 100644
--- a/packages/EasterEgg/res/values/styles.xml
+++ b/packages/EasterEgg/res/values/styles.xml
@@ -20,4 +20,16 @@
         <item name="android:windowLightNavigationBar">true</item>
     </style>
 
+    <style name="QuaresTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowShowWallpaper">true</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowFullscreen">true</item>
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
+    </style>
+
 </resources>
diff --git a/packages/EasterEgg/src/com/android/egg/quares/Quare.kt b/packages/EasterEgg/src/com/android/egg/quares/Quare.kt
new file mode 100644
index 0000000..eb77362
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/quares/Quare.kt
@@ -0,0 +1,168 @@
+/*
+ * 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.egg.quares
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
+import android.os.Parcel
+import android.os.Parcelable
+import java.util.ArrayList
+import kotlin.math.abs
+import kotlin.math.round
+
+class Quare(val width: Int, val height: Int, val depth: Int) : Parcelable {
+    private val data: IntArray = IntArray(width * height)
+    private val user: IntArray = data.copyOf()
+
+    private fun loadAndQuantize(bitmap8bpp: Bitmap) {
+        bitmap8bpp.getPixels(data, 0, width, 0, 0, width, height)
+        if (depth == 8) return
+        val s = (255f / depth)
+        for (i in 0 until data.size) {
+            var f = (data[i] ushr 24).toFloat() / s
+            // f = f.pow(0.75f) // gamma adjust for bolder lines
+            f *= 1.25f // brightness adjust for bolder lines
+            f.coerceAtMost(1f)
+            data[i] = (round(f) * s).toInt() shl 24
+        }
+    }
+
+    fun isBlank(): Boolean {
+        return data.sum() == 0
+    }
+
+    fun load(drawable: Drawable) {
+        val resized = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8)
+        val canvas = Canvas(resized)
+        drawable.setBounds(0, 0, width, height)
+        drawable.setTint(0xFF000000.toInt())
+        drawable.draw(canvas)
+        loadAndQuantize(resized)
+        resized.recycle()
+    }
+
+    fun load(context: Context, icon: Icon) {
+        icon.loadDrawable(context)?.let {
+            load(it)
+        }
+    }
+
+    fun bitmap(): Bitmap {
+        return Bitmap.createBitmap(data, width, height, Bitmap.Config.ALPHA_8)
+    }
+
+    fun getUserMark(x: Int, y: Int): Int {
+        return user[y * width + x] ushr 24
+    }
+
+    fun setUserMark(x: Int, y: Int, v: Int) {
+        user[y * width + x] = v shl 24
+    }
+
+    fun getDataAt(x: Int, y: Int): Int {
+        return data[y * width + x] ushr 24
+    }
+
+    fun check(): Boolean {
+        return data.contentEquals(user)
+    }
+
+    fun check(xSel: Int, ySel: Int): Boolean {
+        val xStart = if (xSel < 0) 0 else xSel
+        val xEnd = if (xSel < 0) width - 1 else xSel
+        val yStart = if (ySel < 0) 0 else ySel
+        val yEnd = if (ySel < 0) height - 1 else ySel
+        for (y in yStart..yEnd)
+            for (x in xStart..xEnd)
+                if (getDataAt(x, y) != getUserMark(x, y)) return false
+        return true
+    }
+
+    fun errors(): IntArray {
+        return IntArray(width * height) {
+            abs(data[it] - user[it])
+        }
+    }
+
+    fun getRowClue(y: Int): IntArray {
+        return getClue(-1, y)
+    }
+    fun getColumnClue(x: Int): IntArray {
+        return getClue(x, -1)
+    }
+    fun getClue(xSel: Int, ySel: Int): IntArray {
+        val arr = ArrayList<Int>()
+        var len = 0
+        val xStart = if (xSel < 0) 0 else xSel
+        val xEnd = if (xSel < 0) width - 1 else xSel
+        val yStart = if (ySel < 0) 0 else ySel
+        val yEnd = if (ySel < 0) height - 1 else ySel
+        for (y in yStart..yEnd)
+            for (x in xStart..xEnd)
+                if (getDataAt(x, y) != 0) {
+                    len++
+                } else if (len > 0) {
+                    arr.add(len)
+                    len = 0
+                }
+        if (len > 0) arr.add(len)
+        else if (arr.size == 0) arr.add(0)
+        return arr.toIntArray()
+    }
+
+    fun resetUserMarks() {
+        user.forEachIndexed { index, _ -> user[index] = 0 }
+    }
+
+    // Parcelable interface
+
+    override fun describeContents(): Int {
+        return 0
+    }
+
+    override fun writeToParcel(p: Parcel?, flags: Int) {
+        p?.let {
+            p.writeInt(width)
+            p.writeInt(height)
+            p.writeInt(depth)
+            p.writeIntArray(data)
+            p.writeIntArray(user)
+        }
+    }
+
+    companion object CREATOR : Parcelable.Creator<Quare> {
+        override fun createFromParcel(p: Parcel?): Quare {
+            return p!!.let {
+                Quare(
+                        p.readInt(), // width
+                        p.readInt(), // height
+                        p.readInt()  // depth
+                ).also {
+                    p.readIntArray(it.data)
+                    p.readIntArray(it.user)
+                }
+            }
+        }
+
+        override fun newArray(size: Int): Array<Quare?> {
+            return arrayOfNulls(size)
+        }
+    }
+}
diff --git a/packages/EasterEgg/src/com/android/egg/quares/QuaresActivity.kt b/packages/EasterEgg/src/com/android/egg/quares/QuaresActivity.kt
new file mode 100644
index 0000000..ce439a9
--- /dev/null
+++ b/packages/EasterEgg/src/com/android/egg/quares/QuaresActivity.kt
@@ -0,0 +1,312 @@
+/*
+ * 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.egg.quares
+
+import android.app.Activity
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.graphics.Typeface
+import android.graphics.drawable.Icon
+import android.os.Bundle
+import android.text.StaticLayout
+import android.text.TextPaint
+import android.util.Log
+import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
+import android.widget.Button
+import android.widget.CompoundButton
+import android.widget.GridLayout
+
+import java.util.Random
+
+import com.android.egg.R
+
+const val TAG = "Quares"
+
+class QuaresActivity : Activity() {
+    private var q: Quare = Quare(16, 16, 1)
+    private var resId = 0
+    private var resName = ""
+    private var icon: Icon? = null
+
+    private lateinit var label: Button
+    private lateinit var grid: GridLayout
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        window.decorView.systemUiVisibility =
+                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+
+        actionBar?.hide()
+
+        setContentView(R.layout.activity_quares)
+
+        grid = findViewById(R.id.grid)
+        label = findViewById(R.id.label)
+
+        if (savedInstanceState != null) {
+            Log.v(TAG, "restoring puzzle from state")
+            q = savedInstanceState.getParcelable("q") ?: q
+            resId = savedInstanceState.getInt("resId")
+            resName = savedInstanceState.getString("resName", "")
+            loadPuzzle()
+        }
+
+        label.setOnClickListener { newPuzzle() }
+    }
+
+    override fun onResume() {
+        super.onResume()
+        if (resId == 0) {
+            // lazy init from onCreate
+            newPuzzle()
+        }
+        checkVictory()
+    }
+
+    override fun onSaveInstanceState(outState: Bundle) {
+        super.onSaveInstanceState(outState)
+
+        outState.putParcelable("q", q)
+        outState.putInt("resId", resId)
+        outState.putString("resName", resName)
+    }
+
+    fun newPuzzle() {
+        Log.v(TAG, "new puzzle...")
+
+        q.resetUserMarks()
+        val oldResId = resId
+        resId = android.R.drawable.stat_sys_warning
+        try {
+            for (tries in 0..3) {
+                val ar = resources.obtainTypedArray(R.array.puzzles)
+                val newName = ar.getString(Random().nextInt(ar.length()))
+                if (newName == null) continue
+
+                Log.v(TAG, "Looking for icon " + newName)
+
+                val pkg = getPackageNameForResourceName(newName)
+                val newId = packageManager.getResourcesForApplication(pkg)
+                        .getIdentifier(newName, "drawable", pkg)
+                if (newId == 0) {
+                    Log.v(TAG, "oops, " + newName + " doesn't resolve from pkg " + pkg)
+                } else if (newId != oldResId) {
+                    // got a good one
+                    resId = newId
+                    resName = newName
+                    break
+                }
+            }
+        } catch (e: RuntimeException) {
+            Log.v(TAG, "problem loading puzzle, using fallback", e)
+        }
+        loadPuzzle()
+    }
+
+    fun getPackageNameForResourceName(name: String): String {
+        return if (name.contains(":") && !name.startsWith("android:")) {
+            name.substring(0, name.indexOf(":"))
+        } else {
+            packageName
+        }
+    }
+
+    fun checkVictory() {
+        if (q.check()) {
+            val dp = resources.displayMetrics.density
+
+            val label: Button = findViewById(R.id.label)
+            label.text = resName.replace(Regex("^.*/"), "")
+            val drawable = icon?.loadDrawable(this)?.also {
+                it.setBounds(0, 0, (32 * dp).toInt(), (32 * dp).toInt())
+                it.setTint(label.currentTextColor)
+            }
+            label.setCompoundDrawables(drawable, null, null, null)
+
+            label.visibility = VISIBLE
+        } else {
+            label.visibility = GONE
+        }
+    }
+
+    fun loadPuzzle() {
+        Log.v(TAG, "loading " + resName + " at " + q.width + "x" + q.height)
+
+        val dp = resources.displayMetrics.density
+
+        icon = Icon.createWithResource(getPackageNameForResourceName(resName), resId)
+        q.load(this, icon!!)
+
+        if (q.isBlank()) {
+            // this is a really boring puzzle, let's try again
+            resId = 0
+            resName = ""
+            recreate()
+            return
+        }
+
+        grid.removeAllViews()
+        grid.columnCount = q.width + 1
+        grid.rowCount = q.height + 1
+
+        label.visibility = GONE
+
+        val orientation = resources.configuration.orientation
+
+        // clean this up a bit
+        val minSide = resources.configuration.smallestScreenWidthDp - 25 // ish
+        val size = (minSide / (q.height + 0.5) * dp).toInt()
+
+        val sb = StringBuffer()
+
+        for (j in 0 until grid.rowCount) {
+            for (i in 0 until grid.columnCount) {
+                val tv: View
+                val params = GridLayout.LayoutParams().also {
+                    it.width = size
+                    it.height = size
+                    it.setMargins(1, 1, 1, 1)
+                    it.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, GridLayout.TOP) // UGH
+                }
+                val x = i - 1
+                val y = j - 1
+                if (i > 0 && j > 0) {
+                    if (i == 1 && j > 1) sb.append("\n")
+                    sb.append(if (q.getDataAt(x, y) == 0) " " else "X")
+                    tv = PixelButton(this)
+                    tv.isChecked = q.getUserMark(x, y) != 0
+                    tv.setOnClickListener {
+                        q.setUserMark(x, y, if (tv.isChecked) 0xFF else 0)
+                        val columnCorrect = (grid.getChildAt(i) as? ClueView)?.check(q) ?: false
+                        val rowCorrect = (grid.getChildAt(j*(grid.columnCount)) as? ClueView)
+                                ?.check(q) ?: false
+                        if (columnCorrect && rowCorrect) {
+                            checkVictory()
+                        } else {
+                            label.visibility = GONE
+                        }
+                    }
+                } else if (i == j) { // 0,0
+                    tv = View(this)
+                    tv.visibility = GONE
+                } else {
+                    tv = ClueView(this)
+                    if (j == 0) {
+                        tv.textRotation = 90f
+                        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+                            params.height /= 2
+                            tv.showText = false
+                        } else {
+                            params.height = (96 * dp).toInt()
+                        }
+                        if (x >= 0) {
+                            tv.setColumn(q, x)
+                        }
+                    }
+                    if (i == 0) {
+                        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+                            params.width /= 2
+                            tv.showText = false
+                        } else {
+                            params.width = (96 * dp).toInt()
+                        }
+                        if (y >= 0) {
+                            tv.setRow(q, y)
+                        }
+                    }
+                }
+                grid.addView(tv, params)
+            }
+        }
+
+        Log.v(TAG, "icon: \n" + sb)
+    }
+}
+
+class PixelButton(context: Context) : CompoundButton(context) {
+    init {
+        setBackgroundResource(R.drawable.pixel_bg)
+        isClickable = true
+        isEnabled = true
+    }
+}
+
+class ClueView(context: Context) : View(context) {
+    var row: Int = -1
+    var column: Int = -1
+    var textRotation: Float = 0f
+    var text: CharSequence = ""
+    var showText = true
+    val paint: TextPaint
+    val incorrectColor: Int
+    val correctColor: Int
+
+    init {
+        setBackgroundColor(0)
+        paint = TextPaint().also {
+            it.textSize = 14f * context.resources.displayMetrics.density
+            it.color = context.getColor(R.color.q_clue_text)
+            it.typeface = Typeface.DEFAULT_BOLD
+            it.textAlign = Paint.Align.CENTER
+        }
+        incorrectColor = context.getColor(R.color.q_clue_bg)
+        correctColor = context.getColor(R.color.q_clue_bg_correct)
+    }
+
+    fun setRow(q: Quare, row: Int): Boolean {
+        this.row = row
+        this.column = -1
+        this.textRotation = 0f
+        text = q.getRowClue(row).joinToString("-")
+        return check(q)
+    }
+    fun setColumn(q: Quare, column: Int): Boolean {
+        this.column = column
+        this.row = -1
+        this.textRotation = 90f
+        text = q.getColumnClue(column).joinToString("-")
+        return check(q)
+    }
+    fun check(q: Quare): Boolean {
+        val correct = q.check(column, row)
+        setBackgroundColor(if (correct) correctColor else incorrectColor)
+        return correct
+    }
+
+    override fun onDraw(canvas: Canvas?) {
+        super.onDraw(canvas)
+        if (!showText) return
+        canvas?.let {
+            val x = canvas.width / 2f
+            val y = canvas.height / 2f
+            var textWidth = canvas.width
+            if (textRotation != 0f) {
+                canvas.rotate(textRotation, x, y)
+                textWidth = canvas.height
+            }
+            val textLayout = StaticLayout.Builder.obtain(
+                    text, 0, text.length, paint, textWidth).build()
+            canvas.translate(x, y - textLayout.height / 2)
+            textLayout.draw(canvas)
+        }
+    }
+}
diff --git a/packages/ExtServices/Android.bp b/packages/ExtServices/Android.bp
deleted file mode 100644
index 5730600..0000000
--- a/packages/ExtServices/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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.
-
-android_library {
-    name: "ExtServices-core",
-     srcs: [
-         "src/**/*.java",
-     ],
-     resource_dirs: [
-         "res",
-     ],
-
-     manifest: "AndroidManifest.xml",
-}
-
-android_app {
-    name: "ExtServices",
-    srcs: ["src/**/*.java"],
-    platform_apis: true,
-    certificate: "platform",
-    optimize: {
-        proguard_flags_files: ["proguard.proguard"],
-    },
-    privileged: true,
-    min_sdk_version: "28",
-}
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
deleted file mode 100644
index 8592fc9..0000000
--- a/packages/ExtServices/AndroidManifest.xml
+++ /dev/null
@@ -1,96 +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.
--->
-
-<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="220000000"
-    android:versionName="1"
-    coreApp="true">
-
-    <uses-permission android:name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
-    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
-
-    <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"
-    />
-
-    <application android:label="@string/app_name"
-        android:defaultToDeviceProtectedStorage="true"
-        android:directBootAware="true">
-
-        <service android:name=".storage.CacheQuotaServiceImpl"
-             android:permission="android.permission.BIND_CACHE_QUOTA_SERVICE">
-            <intent-filter>
-                <action android:name="android.app.usage.CacheQuotaService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".resolver.LRResolverRankerService"
-                 android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE">
-            <intent-filter android:priority="-1">
-                <action android:name="android.service.resolver.ResolverRankerService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".notification.Assistant"
-                 android:label="@string/notification_assistant"
-                 android:permission="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"
-                 android:exported="true">
-            <intent-filter>
-                <action android:name="android.service.notification.NotificationAssistantService" />
-            </intent-filter>
-        </service>
-
-        <service android:name=".autofill.AutofillFieldClassificationServiceImpl"
-             android:permission="android.permission.BIND_AUTOFILL_FIELD_CLASSIFICATION_SERVICE">
-            <intent-filter>
-                <action android:name="android.service.autofill.AutofillFieldClassificationService" />
-            </intent-filter>
-            <meta-data
-                android:name="android.autofill.field_classification.default_algorithm"
-                android:resource="@string/autofill_field_classification_default_algorithm" />
-            <meta-data
-                android:name="android.autofill.field_classification.available_algorithms"
-                android:resource="@array/autofill_field_classification_available_algorithms" />
-        </service>
-
-        <service android:name=".sms.FinancialSmsServiceImpl"
-                 android:permission="android.permission.BIND_FINANCIAL_SMS_SERVICE">
-            <intent-filter>
-                <action android:name="android.service.sms.action.FINANCIAL_SERVICE_INTENT" />
-            </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"/>
-
-        <library android:name="android.ext.services"/>
-    </application>
-
-</manifest>
diff --git a/packages/ExtServices/MODULE_LICENSE_APACHE2 b/packages/ExtServices/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/packages/ExtServices/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/packages/ExtServices/NOTICE b/packages/ExtServices/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/packages/ExtServices/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/packages/ExtServices/proguard.proguard b/packages/ExtServices/proguard.proguard
deleted file mode 100644
index e5dfbe1..0000000
--- a/packages/ExtServices/proguard.proguard
+++ /dev/null
@@ -1,7 +0,0 @@
--keepparameternames
--keepattributes Exceptions,InnerClasses,Signature,Deprecated,
-                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-
--keep public class * {
-    public protected *;
-}
diff --git a/packages/ExtServices/res/values/strings.xml b/packages/ExtServices/res/values/strings.xml
deleted file mode 100644
index 58deb11..0000000
--- a/packages/ExtServices/res/values/strings.xml
+++ /dev/null
@@ -1,33 +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.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name">Android Services Library</string>
-
-    <string name="notification_assistant">Android Adaptive Notifications</string>
-
-    <string name="autofill_field_classification_default_algorithm">EDIT_DISTANCE</string>
-    <string-array name="autofill_field_classification_available_algorithms">
-        <item>EDIT_DISTANCE</item>
-        <item>EXACT_MATCH</item>
-    </string-array>
-
-    <!-- Action chip to copy a one time code to the user's clipboard [CHAR LIMIT=NONE]-->
-    <string name="copy_code_desc">Copy \u201c<xliff:g id="code" example="12345">%1$s</xliff:g>\u201c</string>
-    <!-- Toast to display when text is copied to the device clipboard [CHAR LIMIT=64]-->
-    <string name="code_copied_to_clipboard">Code copied</string>
-
-</resources>
diff --git a/packages/ExtServices/src/android/ext/services/Version.java b/packages/ExtServices/src/android/ext/services/Version.java
deleted file mode 100644
index 026cccd..0000000
--- a/packages/ExtServices/src/android/ext/services/Version.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.
- */
-
-package android.ext.services;
-
-/**
- * Class that provides the version of the library.
- */
-public final class Version {
-
-    private Version() {
-        /* do nothing - hide constructor */
-    }
-
-    /**
-     * Gets the version of the library.
-     *
-     * @return The version.
-     */
-    public static int getVersionCode() {
-        return 1;
-    }
-}
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java b/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
deleted file mode 100644
index e379db8..0000000
--- a/packages/ExtServices/src/android/ext/services/autofill/AutofillFieldClassificationServiceImpl.java
+++ /dev/null
@@ -1,95 +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.ext.services.autofill;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.service.autofill.AutofillFieldClassificationService;
-import android.util.Log;
-import android.view.autofill.AutofillValue;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class AutofillFieldClassificationServiceImpl extends AutofillFieldClassificationService {
-
-    private static final String TAG = "AutofillFieldClassificationServiceImpl";
-
-    private static final String DEFAULT_ALGORITHM = REQUIRED_ALGORITHM_EDIT_DISTANCE;
-
-    @Nullable
-    @Override
-    /** @hide */
-    public float[][] onCalculateScores(@NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
-            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
-            @Nullable Map algorithms, @Nullable Map args) {
-        if (ArrayUtils.isEmpty(actualValues) || ArrayUtils.isEmpty(userDataValues)) {
-            Log.w(TAG, "calculateScores(): empty currentvalues (" + actualValues
-                    + ") or userValues (" + userDataValues + ")");
-            return null;
-        }
-
-        return calculateScores(actualValues, userDataValues, categoryIds, defaultAlgorithm,
-                defaultArgs, (HashMap<String, String>) algorithms,
-                (HashMap<String, Bundle>) args);
-    }
-
-    /** @hide */
-    public float[][] calculateScores(@NonNull List<AutofillValue> actualValues,
-            @NonNull List<String> userDataValues, @NonNull List<String> categoryIds,
-            @Nullable String defaultAlgorithm, @Nullable Bundle defaultArgs,
-            @Nullable HashMap<String, String> algorithms,
-            @Nullable HashMap<String, Bundle> args) {
-        final int actualValuesSize = actualValues.size();
-        final int userDataValuesSize = userDataValues.size();
-        final float[][] scores = new float[actualValuesSize][userDataValuesSize];
-
-        for (int j = 0; j < userDataValuesSize; j++) {
-            final String categoryId = categoryIds.get(j);
-            String algorithmName = defaultAlgorithm;
-            Bundle arg = defaultArgs;
-            if (algorithms != null && algorithms.containsKey(categoryId)) {
-                algorithmName = algorithms.get(categoryId);
-            }
-            if (args != null && args.containsKey(categoryId)) {
-                arg = args.get(categoryId);
-            }
-
-            if (algorithmName == null || (!algorithmName.equals(DEFAULT_ALGORITHM)
-                    && !algorithmName.equals(REQUIRED_ALGORITHM_EXACT_MATCH))) {
-                Log.w(TAG, "algorithmName is " + algorithmName + ", defaulting to "
-                        + DEFAULT_ALGORITHM);
-                algorithmName = DEFAULT_ALGORITHM;
-            }
-
-            for (int i = 0; i < actualValuesSize; i++) {
-                if (algorithmName.equals(DEFAULT_ALGORITHM)) {
-                    scores[i][j] = EditDistanceScorer.calculateScore(actualValues.get(i),
-                            userDataValues.get(j));
-                } else {
-                    scores[i][j] = ExactMatch.calculateScore(actualValues.get(i),
-                            userDataValues.get(j), arg);
-                }
-            }
-        }
-        return scores;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java b/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
deleted file mode 100644
index 1962571..0000000
--- a/packages/ExtServices/src/android/ext/services/autofill/EditDistanceScorer.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.autofill;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.view.autofill.AutofillValue;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-final class EditDistanceScorer {
-
-    private static final String TAG = "EditDistanceScorer";
-
-    // TODO(b/70291841): STOPSHIP - set to false before launching
-    private static final boolean DEBUG = true;
-
-    /**
-     * Gets the field classification score of 2 values based on the edit distance between them.
-     *
-     * <p>The score is defined as: @(max_length - edit_distance) / max_length
-     */
-    @VisibleForTesting
-    static float calculateScore(@Nullable AutofillValue actualValue,
-            @Nullable String userDataValue) {
-        if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
-
-        final String actualValueText = actualValue.getTextValue().toString();
-        final int actualValueLength = actualValueText.length();
-        final int userDatalength = userDataValue.length();
-        if (userDatalength == 0) {
-            return (actualValueLength == 0) ? 1 : 0;
-        }
-
-        final int distance = editDistance(actualValueText.toLowerCase(),
-                userDataValue.toLowerCase());
-        final int maxLength = Math.max(actualValueLength, userDatalength);
-        return ((float) maxLength - distance) / maxLength;
-    }
-
-    /**
-     * Computes the edit distance (number of insertions, deletions or substitutions to edit one
-     * string into the other) between two strings. In particular, this will compute the Levenshtein
-     * distance.
-     *
-     * <p>See http://en.wikipedia.org/wiki/Levenshtein_distance for details.
-     *
-     * @param s the first string to compare
-     * @param t the second string to compare
-     * @return the edit distance between the two strings
-     */
-    // Note: copied verbatim from com.android.tools.lint.detector.api.LintUtils.java
-    public static int editDistance(@NonNull String s, @NonNull String t) {
-        return editDistance(s, t, Integer.MAX_VALUE);
-    }
-
-    /**
-     * Computes the edit distance (number of insertions, deletions or substitutions to edit one
-     * string into the other) between two strings. In particular, this will compute the Levenshtein
-     * distance.
-     *
-     * <p>See http://en.wikipedia.org/wiki/Levenshtein_distance for details.
-     *
-     * @param s the first string to compare
-     * @param t the second string to compare
-     * @param max the maximum edit distance that we care about; if for example the string length
-     *     delta is greater than this we don't bother computing the exact edit distance since the
-     *     caller has indicated they're not interested in the result
-     * @return the edit distance between the two strings, or some other value greater than that if
-     *     the edit distance is at least as big as the {@code max} parameter
-     */
-    // Note: copied verbatim from com.android.tools.lint.detector.api.LintUtils.java
-    public static int editDistance(@NonNull String s, @NonNull String t, int max) {
-        if (s.equals(t)) {
-            return 0;
-        }
-
-        if (Math.abs(s.length() - t.length()) > max) {
-            // The string lengths differ more than the allowed edit distance;
-            // no point in even attempting to compute the edit distance (requires
-            // O(n*m) storage and O(n*m) speed, where n and m are the string lengths)
-            return Integer.MAX_VALUE;
-        }
-
-        int m = s.length();
-        int n = t.length();
-        int[][] d = new int[m + 1][n + 1];
-        for (int i = 0; i <= m; i++) {
-            d[i][0] = i;
-        }
-        for (int j = 0; j <= n; j++) {
-            d[0][j] = j;
-        }
-        for (int j = 1; j <= n; j++) {
-            for (int i = 1; i <= m; i++) {
-                if (s.charAt(i - 1) == t.charAt(j - 1)) {
-                    d[i][j] = d[i - 1][j - 1];
-                } else {
-                    int deletion = d[i - 1][j] + 1;
-                    int insertion = d[i][j - 1] + 1;
-                    int substitution = d[i - 1][j - 1] + 1;
-                    d[i][j] = Math.min(deletion, Math.min(insertion, substitution));
-                }
-            }
-        }
-
-        return d[m][n];
-    }
-
-}
diff --git a/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java b/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java
deleted file mode 100644
index 3e55c5c..0000000
--- a/packages/ExtServices/src/android/ext/services/autofill/ExactMatch.java
+++ /dev/null
@@ -1,67 +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.ext.services.autofill;
-
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.view.autofill.AutofillValue;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-final class ExactMatch {
-
-    /**
-     * Gets the field classification score of 2 values based on whether they are an exact match
-     *
-     * @return {@code 1.0} if the two values are an exact match, {@code 0.0} otherwise.
-     */
-    @VisibleForTesting
-    static float calculateScore(@Nullable AutofillValue actualValue,
-            @Nullable String userDataValue, @Nullable Bundle args) {
-        if (actualValue == null || !actualValue.isText() || userDataValue == null) return 0;
-
-        final String actualValueText = actualValue.getTextValue().toString();
-
-        final int suffixLength;
-        if (args != null) {
-            suffixLength = args.getInt("suffix", -1);
-
-            if (suffixLength < 0) {
-                throw new IllegalArgumentException("suffix argument is invalid");
-            }
-
-            final String actualValueSuffix;
-            if (suffixLength < actualValueText.length()) {
-                actualValueSuffix = actualValueText.substring(actualValueText.length()
-                        - suffixLength);
-            } else {
-                actualValueSuffix = actualValueText;
-            }
-
-            final String userDataValueSuffix;
-            if (suffixLength < userDataValue.length()) {
-                userDataValueSuffix = userDataValue.substring(userDataValue.length()
-                        - suffixLength);
-            } else {
-                userDataValueSuffix = userDataValue;
-            }
-
-            return (actualValueSuffix.equalsIgnoreCase(userDataValueSuffix)) ? 1 : 0;
-        } else {
-            return actualValueText.equalsIgnoreCase(userDataValue) ? 1 : 0;
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java b/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
deleted file mode 100644
index 31c9224..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
+++ /dev/null
@@ -1,172 +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.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.ext.services.notification.NotificationCategorizer.Category;
-import android.net.Uri;
-import android.util.ArraySet;
-import android.util.Slog;
-
-import java.util.Set;
-
-public class AgingHelper {
-    private final static String TAG = "AgingHelper";
-    private final boolean DEBUG = false;
-
-    private static final String AGING_ACTION = AgingHelper.class.getSimpleName() + ".EVALUATE";
-    private static final int REQUEST_CODE_AGING = 1;
-    private static final String AGING_SCHEME = "aging";
-    private static final String EXTRA_KEY = "key";
-    private static final String EXTRA_CATEGORY = "category";
-
-    private static final int HOUR_MS = 1000 * 60 * 60;
-    private static final int TWO_HOURS_MS = 2 * HOUR_MS;
-
-    private Context mContext;
-    private NotificationCategorizer mNotificationCategorizer;
-    private AlarmManager mAm;
-    private Callback mCallback;
-
-    // The set of keys we've scheduled alarms for
-    private Set<String> mAging = new ArraySet<>();
-
-    public AgingHelper(Context context, NotificationCategorizer categorizer, Callback callback) {
-        mNotificationCategorizer = categorizer;
-        mContext = context;
-        mAm = mContext.getSystemService(AlarmManager.class);
-        mCallback = callback;
-
-        IntentFilter filter = new IntentFilter(AGING_ACTION);
-        filter.addDataScheme(AGING_SCHEME);
-        mContext.registerReceiver(mBroadcastReceiver, filter);
-    }
-
-    // NAS lifecycle methods
-
-    public void onNotificationSeen(NotificationEntry entry) {
-        // user has strong opinions about this notification. we can't down rank it, so don't bother.
-        if (entry.getChannel().hasUserSetImportance()) {
-            return;
-        }
-
-        @Category int category = mNotificationCategorizer.getCategory(entry);
-
-        // already very low
-        if (category == NotificationCategorizer.CATEGORY_MIN) {
-            return;
-        }
-
-        if (entry.hasSeen()) {
-            if (category == NotificationCategorizer.CATEGORY_ONGOING
-                    || category > NotificationCategorizer.CATEGORY_REMINDER) {
-                scheduleAging(entry.getSbn().getKey(), category, TWO_HOURS_MS);
-            } else {
-                scheduleAging(entry.getSbn().getKey(), category, HOUR_MS);
-            }
-
-            mAging.add(entry.getSbn().getKey());
-        }
-    }
-
-    public void onNotificationPosted(NotificationEntry entry) {
-        cancelAging(entry.getSbn().getKey());
-    }
-
-    public void onNotificationRemoved(String key) {
-        cancelAging(key);
-    }
-
-    public void onDestroy() {
-        mContext.unregisterReceiver(mBroadcastReceiver);
-    }
-
-    // Aging
-
-    private void scheduleAging(String key, @Category int category, long duration) {
-        if (mAging.contains(key)) {
-            // already scheduled. Don't reset aging just because the user saw the noti again.
-            return;
-        }
-        final PendingIntent pi = createPendingIntent(key, category);
-        long time = System.currentTimeMillis() + duration;
-        if (DEBUG) Slog.d(TAG, "Scheduling evaluate for " + key + " in ms: " + duration);
-        mAm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pi);
-    }
-
-    private void cancelAging(String key) {
-        final PendingIntent pi = createPendingIntent(key);
-        mAm.cancel(pi);
-        mAging.remove(key);
-    }
-
-    private Intent createBaseIntent(String key) {
-        return new Intent(AGING_ACTION)
-                .setData(new Uri.Builder().scheme(AGING_SCHEME).appendPath(key).build());
-    }
-
-    private Intent createAgingIntent(String key, @Category int category) {
-        Intent intent = createBaseIntent(key);
-        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
-                .putExtra(EXTRA_CATEGORY, category)
-                .putExtra(EXTRA_KEY, key);
-        return intent;
-    }
-
-    private PendingIntent createPendingIntent(String key, @Category int category) {
-        return PendingIntent.getBroadcast(mContext,
-                REQUEST_CODE_AGING,
-                createAgingIntent(key, category),
-                PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    private PendingIntent createPendingIntent(String key) {
-        return PendingIntent.getBroadcast(mContext,
-                REQUEST_CODE_AGING,
-                createBaseIntent(key),
-                PendingIntent.FLAG_UPDATE_CURRENT);
-    }
-
-    private void demote(String key, @Category int category) {
-        int newImportance = IMPORTANCE_MIN;
-        // TODO: Change "aged" importance based on category
-        mCallback.sendAdjustment(key, newImportance);
-    }
-
-    protected interface Callback {
-        void sendAdjustment(String key, int newImportance);
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (DEBUG) {
-                Slog.d(TAG, "Reposting notification");
-            }
-            if (AGING_ACTION.equals(intent.getAction())) {
-                demote(intent.getStringExtra(EXTRA_KEY), intent.getIntExtra(EXTRA_CATEGORY,
-                        NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-            }
-        }
-    };
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
deleted file mode 100644
index d01878a..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ /dev/null
@@ -1,514 +0,0 @@
-/**
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.service.notification.Adjustment.KEY_IMPORTANCE;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.app.ActivityThread;
-import android.app.INotificationManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.content.Context;
-import android.content.pm.IPackageManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
-import android.service.notification.Adjustment;
-import android.service.notification.NotificationAssistantService;
-import android.service.notification.NotificationStats;
-import android.service.notification.StatusBarNotification;
-import android.util.ArrayMap;
-import android.util.AtomicFile;
-import android.util.Log;
-import android.util.Slog;
-import android.util.Xml;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.XmlUtils;
-
-import libcore.io.IoUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-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
- */
-@SuppressLint("OverrideAbstract")
-public class Assistant extends NotificationAssistantService {
-    private static final String TAG = "ExtAssistant";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final String TAG_ASSISTANT = "assistant";
-    private static final String TAG_IMPRESSION = "impression-set";
-    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 {
-        PREJUDICAL_DISMISSALS.add(REASON_CANCEL);
-        PREJUDICAL_DISMISSALS.add(REASON_LISTENER_CANCEL);
-    }
-
-    private SmartActionsHelper mSmartActionsHelper;
-    private NotificationCategorizer mNotificationCategorizer;
-
-    // key : impressions tracker
-    // TODO: prune deleted channels and apps
-    private final ArrayMap<String, ChannelImpressions> mkeyToImpressions = new ArrayMap<>();
-    // SBN key : entry
-    protected ArrayMap<String, NotificationEntry> mLiveNotifications = new ArrayMap<>();
-
-    private Ranking mFakeRanking = null;
-    private AtomicFile mFile = null;
-    private IPackageManager mPackageManager;
-
-    @VisibleForTesting
-    protected AssistantSettings.Factory mSettingsFactory = AssistantSettings.FACTORY;
-    @VisibleForTesting
-    protected AssistantSettings mSettings;
-    private SmsHelper mSmsHelper;
-
-    public Assistant() {
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        // Contexts are correctly hooked up by the creation step, which is required for the observer
-        // to be hooked up/initialized.
-        mPackageManager = ActivityThread.getPackageManager();
-        mSettings = mSettingsFactory.createAndRegister(mHandler,
-                getApplicationContext().getContentResolver(), getUserId(), this::updateThresholds);
-        mSmartActionsHelper = new SmartActionsHelper(getContext(), mSettings);
-        mNotificationCategorizer = new NotificationCategorizer();
-        mSmsHelper = new SmsHelper(this);
-        mSmsHelper.initialize();
-    }
-
-    @Override
-    public void onDestroy() {
-        // This null check is only for the unit tests as ServiceTestCase.tearDown calls onDestroy
-        // without having first called onCreate.
-        if (mSmsHelper != null) {
-            mSmsHelper.destroy();
-        }
-        super.onDestroy();
-    }
-
-    private void loadFile() {
-        if (DEBUG) Slog.d(TAG, "loadFile");
-        AsyncTask.execute(() -> {
-            InputStream infile = null;
-            try {
-                infile = mFile.openRead();
-                readXml(infile);
-            } catch (FileNotFoundException e) {
-                Log.d(TAG, "File doesn't exist or isn't readable yet");
-            } catch (IOException e) {
-                Log.e(TAG, "Unable to read channel impressions", e);
-            } catch (NumberFormatException | XmlPullParserException e) {
-                Log.e(TAG, "Unable to parse channel impressions", e);
-            } finally {
-                IoUtils.closeQuietly(infile);
-            }
-        });
-    }
-
-    protected void readXml(InputStream stream)
-            throws XmlPullParserException, NumberFormatException, IOException {
-        final XmlPullParser parser = Xml.newPullParser();
-        parser.setInput(stream, StandardCharsets.UTF_8.name());
-        final int outerDepth = parser.getDepth();
-        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
-            if (!TAG_ASSISTANT.equals(parser.getName())) {
-                continue;
-            }
-            final int impressionOuterDepth = parser.getDepth();
-            while (XmlUtils.nextElementWithin(parser, impressionOuterDepth)) {
-                if (!TAG_IMPRESSION.equals(parser.getName())) {
-                    continue;
-                }
-                String key = parser.getAttributeValue(null, ATT_KEY);
-                ChannelImpressions ci = createChannelImpressionsWithThresholds();
-                ci.populateFromXml(parser);
-                synchronized (mkeyToImpressions) {
-                    ci.append(mkeyToImpressions.get(key));
-                    mkeyToImpressions.put(key, ci);
-                }
-            }
-        }
-    }
-
-    private void saveFile() {
-        AsyncTask.execute(() -> {
-            final FileOutputStream stream;
-            try {
-                stream = mFile.startWrite();
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save policy file", e);
-                return;
-            }
-            try {
-                final XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(stream, StandardCharsets.UTF_8.name());
-                writeXml(out);
-                mFile.finishWrite(stream);
-            } catch (IOException e) {
-                Slog.w(TAG, "Failed to save impressions file, restoring backup", e);
-                mFile.failWrite(stream);
-            }
-        });
-    }
-
-    protected void writeXml(XmlSerializer out) throws IOException {
-        out.startDocument(null, true);
-        out.startTag(null, TAG_ASSISTANT);
-        out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
-        synchronized (mkeyToImpressions) {
-            for (Map.Entry<String, ChannelImpressions> entry
-                    : mkeyToImpressions.entrySet()) {
-                // TODO: ensure channel still exists
-                out.startTag(null, TAG_IMPRESSION);
-                out.attribute(null, ATT_KEY, entry.getKey());
-                entry.getValue().writeXml(out);
-                out.endTag(null, TAG_IMPRESSION);
-            }
-        }
-        out.endTag(null, TAG_ASSISTANT);
-        out.endDocument();
-    }
-
-    @Override
-    public Adjustment onNotificationEnqueued(StatusBarNotification sbn) {
-        // we use the version with channel, so this is never called.
-        return null;
-    }
-
-    @Override
-    public Adjustment onNotificationEnqueued(StatusBarNotification sbn,
-            NotificationChannel channel) {
-        if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey() + " on " + channel.getId());
-        if (!isForCurrentUser(sbn)) {
-            return null;
-        }
-        mSingleThreadExecutor.submit(() -> {
-            NotificationEntry entry =
-                    new NotificationEntry(getContext(), 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. */
-    @VisibleForTesting
-    @Nullable
-    Adjustment createEnqueuedNotificationAdjustment(
-            @NonNull NotificationEntry entry,
-            @NonNull ArrayList<Notification.Action> smartActions,
-            @NonNull ArrayList<CharSequence> smartReplies) {
-        Bundle signals = new Bundle();
-
-        if (!smartActions.isEmpty()) {
-            signals.putParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS, smartActions);
-        }
-        if (!smartReplies.isEmpty()) {
-            signals.putCharSequenceArrayList(Adjustment.KEY_TEXT_REPLIES, smartReplies);
-        }
-        if (mSettings.mNewInterruptionModel) {
-            if (mNotificationCategorizer.shouldSilence(entry)) {
-                final int importance = entry.getImportance() < IMPORTANCE_LOW
-                        ? entry.getImportance() : IMPORTANCE_LOW;
-                signals.putInt(KEY_IMPORTANCE, importance);
-            } else {
-                // Even if no change is made, send an identity adjustment for metric logging.
-                signals.putInt(KEY_IMPORTANCE, entry.getImportance());
-            }
-        }
-
-        return new Adjustment(
-                entry.getSbn().getPackageName(),
-                entry.getSbn().getKey(),
-                signals,
-                "",
-                entry.getSbn().getUserId());
-    }
-
-    @Override
-    public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
-        if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
-        try {
-            if (!isForCurrentUser(sbn)) {
-                return;
-            }
-            Ranking ranking = getRanking(sbn.getKey(), rankingMap);
-            if (ranking != null && ranking.getChannel() != null) {
-                NotificationEntry entry = new NotificationEntry(getContext(), mPackageManager,
-                        sbn, ranking.getChannel(), mSmsHelper);
-                String key = getKey(
-                        sbn.getPackageName(), sbn.getUserId(), ranking.getChannel().getId());
-                boolean shouldTriggerBlock;
-                synchronized (mkeyToImpressions) {
-                    ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
-                            createChannelImpressionsWithThresholds());
-                    mkeyToImpressions.put(key, ci);
-                    shouldTriggerBlock = ci.shouldTriggerBlock();
-                }
-                if (ranking.getImportance() > IMPORTANCE_MIN && shouldTriggerBlock) {
-                    adjustNotification(createNegativeAdjustment(
-                            sbn.getPackageName(), sbn.getKey(), sbn.getUserId()));
-                }
-                mLiveNotifications.put(sbn.getKey(), entry);
-            }
-        } catch (Throwable e) {
-            Log.e(TAG, "Error occurred processing post", e);
-        }
-    }
-
-    @Override
-    public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap,
-            NotificationStats stats, int reason) {
-        try {
-            if (!isForCurrentUser(sbn)) {
-                return;
-            }
-
-            boolean updatedImpressions = false;
-            String channelId = mLiveNotifications.remove(sbn.getKey()).getChannel().getId();
-            String key = getKey(sbn.getPackageName(), sbn.getUserId(), channelId);
-            synchronized (mkeyToImpressions) {
-                ChannelImpressions ci = mkeyToImpressions.getOrDefault(key,
-                        createChannelImpressionsWithThresholds());
-                if (stats != null && stats.hasSeen()) {
-                    ci.incrementViews();
-                    updatedImpressions = true;
-                }
-                if (PREJUDICAL_DISMISSALS.contains(reason)) {
-                    if ((!sbn.isAppGroup() || sbn.getNotification().isGroupChild())
-                            && !stats.hasInteracted()
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_AOD
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_PEEK
-                            && stats.getDismissalSurface() != NotificationStats.DISMISSAL_OTHER) {
-                        if (DEBUG) Log.i(TAG, "increment dismissals " + key);
-                        ci.incrementDismissals();
-                        updatedImpressions = true;
-                    } else {
-                        if (DEBUG) Slog.i(TAG, "reset streak " + key);
-                        if (ci.getStreak() > 0) {
-                            updatedImpressions = true;
-                        }
-                        ci.resetStreak();
-                    }
-                }
-                mkeyToImpressions.put(key, ci);
-            }
-            if (updatedImpressions) {
-                saveFile();
-            }
-        } catch (Throwable e) {
-            Slog.e(TAG, "Error occurred processing removal of " + sbn, e);
-        }
-    }
-
-    @Override
-    public void onNotificationSnoozedUntilContext(StatusBarNotification sbn,
-            String snoozeCriterionId) {
-    }
-
-    @Override
-    public void onNotificationsSeen(List<String> keys) {
-    }
-
-    @Override
-    public void onNotificationExpansionChanged(@NonNull String key, boolean isUserAction,
-            boolean isExpanded) {
-        if (DEBUG) {
-            Log.d(TAG, "onNotificationExpansionChanged() called with: key = [" + key
-                    + "], isUserAction = [" + isUserAction + "], isExpanded = [" + isExpanded
-                    + "]");
-        }
-        NotificationEntry entry = mLiveNotifications.get(key);
-
-        if (entry != null) {
-            mSingleThreadExecutor.submit(
-                    () -> mSmartActionsHelper.onNotificationExpansionChanged(entry, isExpanded));
-        }
-    }
-
-    @Override
-    public void onNotificationDirectReplied(@NonNull String key) {
-        if (DEBUG) Log.i(TAG, "onNotificationDirectReplied " + key);
-        mSingleThreadExecutor.submit(() -> mSmartActionsHelper.onNotificationDirectReplied(key));
-    }
-
-    @Override
-    public void onSuggestedReplySent(@NonNull String key, @NonNull CharSequence reply,
-            @Source int source) {
-        if (DEBUG) {
-            Log.d(TAG, "onSuggestedReplySent() called with: key = [" + key + "], reply = [" + reply
-                    + "], source = [" + source + "]");
-        }
-        mSingleThreadExecutor.submit(
-                () -> mSmartActionsHelper.onSuggestedReplySent(key, reply, source));
-    }
-
-    @Override
-    public void onActionInvoked(@NonNull String key, @NonNull Notification.Action action,
-            @Source int source) {
-        if (DEBUG) {
-            Log.d(TAG,
-                    "onActionInvoked() called with: key = [" + key + "], action = [" + action.title
-                            + "], source = [" + source + "]");
-        }
-        mSingleThreadExecutor.submit(
-                () -> mSmartActionsHelper.onActionClicked(key, action, source));
-    }
-
-    @Override
-    public void onListenerConnected() {
-        if (DEBUG) Log.i(TAG, "CONNECTED");
-        try {
-            mFile = new AtomicFile(new File(new File(
-                    Environment.getDataUserCePackageDirectory(
-                            StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()),
-                    "assistant"), "blocking_helper_stats.xml"));
-            loadFile();
-            for (StatusBarNotification sbn : getActiveNotifications()) {
-                onNotificationPosted(sbn);
-            }
-        } catch (Throwable e) {
-            Log.e(TAG, "Error occurred on connection", e);
-        }
-    }
-
-    @Override
-    public void onListenerDisconnected() {
-    }
-
-    private boolean isForCurrentUser(StatusBarNotification sbn) {
-        return sbn != null && sbn.getUserId() == UserHandle.myUserId();
-    }
-
-    protected String getKey(String pkg, int userId, String channelId) {
-        return pkg + "|" + userId + "|" + channelId;
-    }
-
-    private Ranking getRanking(String key, RankingMap rankingMap) {
-        if (mFakeRanking != null) {
-            return mFakeRanking;
-        }
-        Ranking ranking = new Ranking();
-        rankingMap.getRanking(key, ranking);
-        return ranking;
-    }
-
-    private Adjustment createNegativeAdjustment(String packageName, String key, int user) {
-        if (DEBUG) Log.d(TAG, "User probably doesn't want " + key);
-        Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
-        return new Adjustment(packageName, key,  signals, "", user);
-    }
-
-    // for testing
-
-    @VisibleForTesting
-    public void setFile(AtomicFile file) {
-        mFile = file;
-    }
-
-    @VisibleForTesting
-    public void setFakeRanking(Ranking ranking) {
-        mFakeRanking = ranking;
-    }
-
-    @VisibleForTesting
-    public void setNoMan(INotificationManager noMan) {
-        mNoMan = noMan;
-    }
-
-    @VisibleForTesting
-    public void setContext(Context context) {
-        mSystemContext = context;
-    }
-
-    @VisibleForTesting
-    public void setPackageManager(IPackageManager pm) {
-        mPackageManager = pm;
-    }
-
-    @VisibleForTesting
-    public ChannelImpressions getImpressions(String key) {
-        synchronized (mkeyToImpressions) {
-            return mkeyToImpressions.get(key);
-        }
-    }
-
-    @VisibleForTesting
-    public void insertImpressions(String key, ChannelImpressions ci) {
-        synchronized (mkeyToImpressions) {
-            mkeyToImpressions.put(key, ci);
-        }
-    }
-
-    private ChannelImpressions createChannelImpressionsWithThresholds() {
-        ChannelImpressions impressions = new ChannelImpressions();
-        impressions.updateThresholds(mSettings.mDismissToViewRatioLimit, mSettings.mStreakLimit);
-        return impressions;
-    }
-
-    private void updateThresholds() {
-        // Update all existing channel impression objects with any new limits/thresholds.
-        synchronized (mkeyToImpressions) {
-            for (ChannelImpressions channelImpressions: mkeyToImpressions.values()) {
-                channelImpressions.updateThresholds(
-                        mSettings.mDismissToViewRatioLimit, mSettings.mStreakLimit);
-            }
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java b/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
deleted file mode 100644
index 296db46..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/AssistantSettings.java
+++ /dev/null
@@ -1,176 +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.ext.services.notification;
-
-import android.content.ContentResolver;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-
-/**
- * Observes the settings for {@link Assistant}.
- */
-final class AssistantSettings extends ContentObserver {
-    private static final String LOG_TAG = "AssistantSettings";
-    public static Factory FACTORY = AssistantSettings::createAndRegister;
-    private static final boolean DEFAULT_GENERATE_REPLIES = true;
-    private static final boolean DEFAULT_GENERATE_ACTIONS = true;
-    private static final int DEFAULT_NEW_INTERRUPTION_MODEL_INT = 1;
-    private static final int DEFAULT_MAX_MESSAGES_TO_EXTRACT = 5;
-    @VisibleForTesting
-    static final int DEFAULT_MAX_SUGGESTIONS = 3;
-
-    private static final Uri STREAK_LIMIT_URI =
-            Settings.Global.getUriFor(Settings.Global.BLOCKING_HELPER_STREAK_LIMIT);
-    private static final Uri DISMISS_TO_VIEW_RATIO_LIMIT_URI =
-            Settings.Global.getUriFor(
-                    Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT);
-    private static final Uri NOTIFICATION_NEW_INTERRUPTION_MODEL_URI =
-            Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL);
-
-    private final ContentResolver mResolver;
-    private final int mUserId;
-
-    private final Handler mHandler;
-
-    @VisibleForTesting
-    protected final Runnable mOnUpdateRunnable;
-
-    // Actual configuration settings.
-    float mDismissToViewRatioLimit;
-    int mStreakLimit;
-    boolean mGenerateReplies = DEFAULT_GENERATE_REPLIES;
-    boolean mGenerateActions = DEFAULT_GENERATE_ACTIONS;
-    boolean mNewInterruptionModel;
-    int mMaxMessagesToExtract = DEFAULT_MAX_MESSAGES_TO_EXTRACT;
-    int mMaxSuggestions = DEFAULT_MAX_SUGGESTIONS;
-
-    private AssistantSettings(Handler handler, ContentResolver resolver, int userId,
-            Runnable onUpdateRunnable) {
-        super(handler);
-        mHandler = handler;
-        mResolver = resolver;
-        mUserId = userId;
-        mOnUpdateRunnable = onUpdateRunnable;
-    }
-
-    private static AssistantSettings createAndRegister(
-            Handler handler, ContentResolver resolver, int userId, Runnable onUpdateRunnable) {
-        AssistantSettings assistantSettings =
-                new AssistantSettings(handler, resolver, userId, onUpdateRunnable);
-        assistantSettings.register();
-        assistantSettings.registerDeviceConfigs();
-        return assistantSettings;
-    }
-
-    /**
-     * Creates an instance but doesn't register it as an observer.
-     */
-    @VisibleForTesting
-    protected static AssistantSettings createForTesting(
-            Handler handler, ContentResolver resolver, int userId, Runnable onUpdateRunnable) {
-        return new AssistantSettings(handler, resolver, userId, onUpdateRunnable);
-    }
-
-    private void register() {
-        mResolver.registerContentObserver(
-                DISMISS_TO_VIEW_RATIO_LIMIT_URI, false, this, mUserId);
-        mResolver.registerContentObserver(STREAK_LIMIT_URI, false, this, mUserId);
-
-        // Update all uris on creation.
-        update(null);
-    }
-
-    private void registerDeviceConfigs() {
-        DeviceConfig.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                this::postToHandler,
-                (properties) -> onDeviceConfigPropertiesChanged(properties.getNamespace()));
-
-        // Update the fields in this class from the current state of the device config.
-        updateFromDeviceConfigFlags();
-    }
-
-    private void postToHandler(Runnable r) {
-        this.mHandler.post(r);
-    }
-
-    @VisibleForTesting
-    void onDeviceConfigPropertiesChanged(String namespace) {
-        if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) {
-            Log.e(LOG_TAG, "Received update from DeviceConfig for unrelated namespace: "
-                    + namespace);
-            return;
-        }
-
-        updateFromDeviceConfigFlags();
-    }
-
-    private void updateFromDeviceConfigFlags() {
-        mGenerateReplies = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES, DEFAULT_GENERATE_REPLIES);
-
-        mGenerateActions = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS, DEFAULT_GENERATE_ACTIONS);
-
-        mMaxMessagesToExtract = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
-                DEFAULT_MAX_MESSAGES_TO_EXTRACT);
-
-        mMaxSuggestions = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS, DEFAULT_MAX_SUGGESTIONS);
-
-        mOnUpdateRunnable.run();
-    }
-
-    @Override
-    public void onChange(boolean selfChange, Uri uri) {
-        update(uri);
-    }
-
-    private void update(Uri uri) {
-        if (uri == null || DISMISS_TO_VIEW_RATIO_LIMIT_URI.equals(uri)) {
-            mDismissToViewRatioLimit = Settings.Global.getFloat(
-                    mResolver, Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
-                    ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT);
-        }
-        if (uri == null || STREAK_LIMIT_URI.equals(uri)) {
-            mStreakLimit = Settings.Global.getInt(
-                    mResolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
-                    ChannelImpressions.DEFAULT_STREAK_LIMIT);
-        }
-        if (uri == null || NOTIFICATION_NEW_INTERRUPTION_MODEL_URI.equals(uri)) {
-            int mNewInterruptionModelInt = Settings.Secure.getInt(
-                    mResolver, Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL,
-                    DEFAULT_NEW_INTERRUPTION_MODEL_INT);
-            mNewInterruptionModel = mNewInterruptionModelInt == 1;
-        }
-
-        mOnUpdateRunnable.run();
-    }
-
-    public interface Factory {
-        AssistantSettings createAndRegister(Handler handler, ContentResolver resolver, int userId,
-                Runnable onUpdateRunnable);
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java b/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
deleted file mode 100644
index ca3daad..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
-
-public final class ChannelImpressions implements Parcelable {
-    private static final String TAG = "ExtAssistant.CI";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    static final float DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT = .8f;
-    static final int DEFAULT_STREAK_LIMIT = 2;
-    static final String ATT_DISMISSALS = "dismisses";
-    static final String ATT_VIEWS = "views";
-    static final String ATT_STREAK = "streak";
-    static final String ATT_SENT = "sent";
-    static final String ATT_INTERRUPTIVE = "interruptive";
-
-    private int mDismissals = 0;
-    private int mViews = 0;
-    private int mStreak = 0;
-
-    private float mDismissToViewRatioLimit;
-    private int mStreakLimit;
-
-    public ChannelImpressions() {
-        mDismissToViewRatioLimit = DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT;
-        mStreakLimit = DEFAULT_STREAK_LIMIT;
-    }
-
-    protected ChannelImpressions(Parcel in) {
-        mDismissals = in.readInt();
-        mViews = in.readInt();
-        mStreak = in.readInt();
-        mDismissToViewRatioLimit = in.readFloat();
-        mStreakLimit = in.readInt();
-    }
-
-    public int getStreak() {
-        return mStreak;
-    }
-
-    public int getDismissals() {
-        return mDismissals;
-    }
-
-    public int getViews() {
-        return mViews;
-    }
-
-    public void incrementDismissals() {
-        mDismissals++;
-        mStreak++;
-    }
-
-    void updateThresholds(float dismissToViewRatioLimit, int streakLimit) {
-        mDismissToViewRatioLimit = dismissToViewRatioLimit;
-        mStreakLimit = streakLimit;
-    }
-
-    @VisibleForTesting
-    float getDismissToViewRatioLimit() {
-        return mDismissToViewRatioLimit;
-    }
-
-    @VisibleForTesting
-    int getStreakLimit() {
-        return mStreakLimit;
-    }
-
-    public void append(ChannelImpressions additionalImpressions) {
-        if (additionalImpressions != null) {
-            mViews += additionalImpressions.getViews();
-            mStreak += additionalImpressions.getStreak();
-            mDismissals += additionalImpressions.getDismissals();
-        }
-    }
-
-    public void incrementViews() {
-        mViews++;
-    }
-
-    public void resetStreak() {
-        mStreak = 0;
-    }
-
-    public boolean shouldTriggerBlock() {
-        if (getViews() == 0) {
-            return false;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "should trigger? " + getDismissals() + " " + getViews() + " " + getStreak());
-        }
-        return ((float) getDismissals() / getViews()) > mDismissToViewRatioLimit
-                && getStreak() > mStreakLimit;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mDismissals);
-        dest.writeInt(mViews);
-        dest.writeInt(mStreak);
-        dest.writeFloat(mDismissToViewRatioLimit);
-        dest.writeInt(mStreakLimit);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Creator<ChannelImpressions> CREATOR = new Creator<ChannelImpressions>() {
-        @Override
-        public ChannelImpressions createFromParcel(Parcel in) {
-            return new ChannelImpressions(in);
-        }
-
-        @Override
-        public ChannelImpressions[] newArray(int size) {
-            return new ChannelImpressions[size];
-        }
-    };
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ChannelImpressions that = (ChannelImpressions) o;
-
-        if (mDismissals != that.mDismissals) return false;
-        if (mViews != that.mViews) return false;
-        return mStreak == that.mStreak;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = mDismissals;
-        result = 31 * result + mViews;
-        result = 31 * result + mStreak;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder sb = new StringBuilder("ChannelImpressions{");
-        sb.append("mDismissals=").append(mDismissals);
-        sb.append(", mViews=").append(mViews);
-        sb.append(", mStreak=").append(mStreak);
-        sb.append(", thresholds=(").append(mDismissToViewRatioLimit);
-        sb.append(",").append(mStreakLimit);
-        sb.append(")}");
-        return sb.toString();
-    }
-
-    protected void populateFromXml(XmlPullParser parser) {
-        mDismissals = safeInt(parser, ATT_DISMISSALS, 0);
-        mStreak = safeInt(parser, ATT_STREAK, 0);
-        mViews = safeInt(parser, ATT_VIEWS, 0);
-    }
-
-    protected void writeXml(XmlSerializer out) throws IOException {
-        if (mDismissals != 0) {
-            out.attribute(null, ATT_DISMISSALS, String.valueOf(mDismissals));
-        }
-        if (mStreak != 0) {
-            out.attribute(null, ATT_STREAK, String.valueOf(mStreak));
-        }
-        if (mViews != 0) {
-            out.attribute(null, ATT_VIEWS, String.valueOf(mViews));
-        }
-    }
-
-    private static int safeInt(XmlPullParser parser, String att, int defValue) {
-        final String val = parser.getAttributeValue(null, att);
-        return tryParseInt(val, defValue);
-    }
-
-    private static int tryParseInt(String value, int defValue) {
-        if (TextUtils.isEmpty(value)) return defValue;
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
-            return defValue;
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/CopyCodeActivity.java b/packages/ExtServices/src/android/ext/services/notification/CopyCodeActivity.java
deleted file mode 100644
index 6708d4d..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/CopyCodeActivity.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 android.ext.services.notification;
-
-import android.app.Activity;
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.Intent;
-import android.ext.services.R;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.Log;
-import android.widget.Toast;
-
-/**
- * An activity that copies text in the Bundle.
- */
-public class CopyCodeActivity extends Activity {
-    private static final String TAG = "CopyCodeActivity";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        handleIntent();
-        finish();
-    }
-
-    private void handleIntent() {
-        String code = getIntent().getStringExtra(Intent.EXTRA_TEXT);
-        if (TextUtils.isEmpty(code)) {
-            Log.w(TAG, "handleIntent: empty code");
-            return;
-        }
-        ClipboardManager clipboardManager = getSystemService(ClipboardManager.class);
-        ClipData clipData = ClipData.newPlainText(null, code);
-        clipboardManager.setPrimaryClip(clipData);
-        Toast.makeText(getApplicationContext(), R.string.code_copied_to_clipboard,
-                Toast.LENGTH_SHORT).show();
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java b/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java
deleted file mode 100644
index 50cb0ab..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/EntityTypeCounter.java
+++ /dev/null
@@ -1,73 +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.ext.services.notification;
-
-import android.annotation.NonNull;
-import android.util.ArrayMap;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextLinks;
-
-/**
- * Counts the entity types for smart actions. Some entity types are considered the same
- * type, like {@link TextClassifier#TYPE_DATE} and {@link TextClassifier#TYPE_DATE_TIME}.
- */
-class EntityTypeCounter {
-
-    private static final ArrayMap<String, String> ENTITY_TYPE_MAPPING = new ArrayMap<>();
-
-    static {
-        ENTITY_TYPE_MAPPING.put(TextClassifier.TYPE_DATE_TIME, TextClassifier.TYPE_DATE);
-    }
-
-    private final ArrayMap<String, Integer> mEntityTypeCount = new ArrayMap<>();
-
-
-    void increment(@NonNull String entityType) {
-        entityType = convertToBaseEntityType(entityType);
-        if (mEntityTypeCount.containsKey(entityType)) {
-            mEntityTypeCount.put(entityType, mEntityTypeCount.get(entityType) + 1);
-        } else {
-            mEntityTypeCount.put(entityType, 1);
-        }
-    }
-
-    int getCount(@NonNull String entityType) {
-        entityType = convertToBaseEntityType(entityType);
-        return mEntityTypeCount.getOrDefault(entityType, 0);
-    }
-
-    @NonNull
-    private String convertToBaseEntityType(@NonNull String entityType) {
-        return ENTITY_TYPE_MAPPING.getOrDefault(entityType, entityType);
-    }
-
-    /**
-     * Given the links extracted from a piece of text, returns the frequency of each entity
-     * type.
-     */
-    @NonNull
-    static EntityTypeCounter fromTextLinks(@NonNull TextLinks links) {
-        EntityTypeCounter counter = new EntityTypeCounter();
-        for (TextLinks.TextLink link : links.getLinks()) {
-            if (link.getEntityCount() == 0) {
-                continue;
-            }
-            String entityType = link.getEntity(0);
-            counter.increment(entityType);
-        }
-        return counter;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java b/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java
deleted file mode 100644
index f95891c..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/NotificationCategorizer.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import android.annotation.IntDef;
-import android.app.Notification;
-import android.media.AudioAttributes;
-import android.os.Process;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Default categorizer for incoming notifications; used to determine what notifications
- * should be silenced.
- */
-// TODO: stop using @hide methods
-public class NotificationCategorizer {
-
-    protected static final int CATEGORY_MIN = -3;
-    protected static final int CATEGORY_EVERYTHING_ELSE = -2;
-    protected static final int CATEGORY_ONGOING = -1;
-    protected static final int CATEGORY_SYSTEM_LOW = 0;
-    protected static final int CATEGORY_EVENT = 1;
-    protected static final int CATEGORY_REMINDER = 2;
-    protected static final int CATEGORY_SYSTEM = 3;
-    protected static final int CATEGORY_PEOPLE = 4;
-    protected static final int CATEGORY_ALARM = 5;
-    protected static final int CATEGORY_CALL = 6;
-    protected static final int CATEGORY_HIGH = 7;
-
-    /** @hide */
-    @IntDef(prefix = { "CATEGORY_" }, value = {
-            CATEGORY_MIN, CATEGORY_EVERYTHING_ELSE, CATEGORY_ONGOING, CATEGORY_CALL,
-            CATEGORY_SYSTEM_LOW, CATEGORY_EVENT, CATEGORY_REMINDER, CATEGORY_SYSTEM,
-            CATEGORY_PEOPLE, CATEGORY_ALARM, CATEGORY_HIGH
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Category {}
-
-    public boolean shouldSilence(NotificationEntry entry) {
-        return shouldSilence(getCategory(entry));
-    }
-
-    @VisibleForTesting
-    boolean shouldSilence(int category) {
-        return category < CATEGORY_EVENT;
-    }
-
-    public int getCategory(NotificationEntry entry) {
-        if (entry.getChannel() == null) {
-            return CATEGORY_EVERYTHING_ELSE;
-        }
-        if (entry.getChannel().getImportance() == IMPORTANCE_MIN) {
-            return CATEGORY_MIN;
-        }
-        if (entry.isCategory(Notification.CATEGORY_REMINDER)) {
-            return CATEGORY_REMINDER;
-        }
-        if (entry.isCategory(Notification.CATEGORY_EVENT)) {
-            return CATEGORY_EVENT;
-        }
-        if (entry.isCategory(Notification.CATEGORY_ALARM)
-                || entry.isAudioAttributesUsage(AudioAttributes.USAGE_ALARM)) {
-            return CATEGORY_ALARM;
-        }
-        // TODO: check for default phone app
-        if (entry.isCategory(Notification.CATEGORY_CALL)) {
-            return CATEGORY_CALL;
-        }
-        if (entry.involvesPeople()) {
-            return CATEGORY_PEOPLE;
-        }
-        // TODO: is from signature app
-        if (entry.getSbn().getUid() < Process.FIRST_APPLICATION_UID) {
-            if (entry.getImportance() >= IMPORTANCE_DEFAULT) {
-                return CATEGORY_SYSTEM;
-            } else {
-                return CATEGORY_SYSTEM_LOW;
-            }
-        }
-        if (entry.getChannel().getImportance() == IMPORTANCE_HIGH) {
-            return CATEGORY_HIGH;
-        }
-        if (entry.isOngoing()) {
-            return CATEGORY_ONGOING;
-        }
-        return CATEGORY_EVERYTHING_ELSE;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
deleted file mode 100644
index 1ffbac9..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
+++ /dev/null
@@ -1,349 +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.ext.services.notification;
-
-import static android.app.Notification.CATEGORY_MESSAGE;
-import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
-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_MIN;
-import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.Person;
-import android.app.RemoteInput;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Icon;
-import android.media.AudioAttributes;
-import android.media.AudioSystem;
-import android.os.Build;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.service.notification.StatusBarNotification;
-import android.util.Log;
-import android.util.SparseArray;
-
-import java.util.ArrayList;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * Holds data about notifications.
- */
-public class NotificationEntry {
-    static final String TAG = "NotificationEntry";
-
-    // Copied from hidden definitions in Notification.TvExtender
-    private static final String EXTRA_TV_EXTENDER = "android.tv.EXTENSIONS";
-
-    private final Context mContext;
-    private final StatusBarNotification mSbn;
-    private final IPackageManager mPackageManager;
-    private int mTargetSdkVersion = Build.VERSION_CODES.N_MR1;
-    private final boolean mPreChannelsNotification;
-    private final AudioAttributes mAttributes;
-    private final NotificationChannel mChannel;
-    private final int mImportance;
-    private boolean mSeen;
-    private boolean mIsShowActionEventLogged;
-    private final SmsHelper mSmsHelper;
-
-    private final Object mLock = new Object();
-
-    public NotificationEntry(Context applicationContext, IPackageManager packageManager,
-            StatusBarNotification sbn, NotificationChannel channel, SmsHelper smsHelper) {
-        mContext = applicationContext;
-        mSbn = cloneStatusBarNotificationLight(sbn);
-        mChannel = channel;
-        mPackageManager = packageManager;
-        mPreChannelsNotification = isPreChannelsNotification();
-        mAttributes = calculateAudioAttributes();
-        mImportance = calculateInitialImportance();
-        mSmsHelper = smsHelper;
-    }
-
-    /** Adapted from {@code Notification.lightenPayload}. */
-    @SuppressWarnings("nullness")
-    private static void lightenNotificationPayload(Notification notification) {
-        notification.tickerView = null;
-        notification.contentView = null;
-        notification.bigContentView = null;
-        notification.headsUpContentView = null;
-        notification.largeIcon = null;
-        if (notification.extras != null && !notification.extras.isEmpty()) {
-            final Set<String> keyset = notification.extras.keySet();
-            final int keysetSize = keyset.size();
-            final String[] keys = keyset.toArray(new String[keysetSize]);
-            for (int i = 0; i < keysetSize; i++) {
-                final String key = keys[i];
-                if (EXTRA_TV_EXTENDER.equals(key)
-                        || Notification.EXTRA_MESSAGES.equals(key)
-                        || Notification.EXTRA_MESSAGING_PERSON.equals(key)
-                        || Notification.EXTRA_PEOPLE_LIST.equals(key)) {
-                    continue;
-                }
-                final Object obj = notification.extras.get(key);
-                if (obj != null
-                        && (obj instanceof Parcelable
-                        || obj instanceof Parcelable[]
-                        || obj instanceof SparseArray
-                        || obj instanceof ArrayList)) {
-                    notification.extras.remove(key);
-                }
-            }
-        }
-    }
-
-    /** An interpretation of {@code Notification.cloneInto} with heavy=false. */
-    private Notification cloneNotificationLight(Notification notification) {
-        // We can't just use clone() here because the only way to remove the icons is with the
-        // builder, which we can only create with a Context.
-        Notification lightNotification =
-                Notification.Builder.recoverBuilder(mContext, notification)
-                        .setSmallIcon(0)
-                        .setLargeIcon((Icon) null)
-                        .build();
-        lightenNotificationPayload(lightNotification);
-        return lightNotification;
-    }
-
-    /** Adapted from {@code StatusBarNotification.cloneLight}. */
-    public StatusBarNotification cloneStatusBarNotificationLight(StatusBarNotification sbn) {
-        return new StatusBarNotification(
-                sbn.getPackageName(),
-                sbn.getOpPkg(),
-                sbn.getId(),
-                sbn.getTag(),
-                sbn.getUid(),
-                /*initialPid=*/ 0,
-                /*score=*/ 0,
-                cloneNotificationLight(sbn.getNotification()),
-                sbn.getUser(),
-                sbn.getPostTime());
-    }
-
-    private boolean isPreChannelsNotification() {
-        try {
-            ApplicationInfo info = mPackageManager.getApplicationInfo(
-                    mSbn.getPackageName(), PackageManager.MATCH_ALL,
-                    mSbn.getUserId());
-            if (info != null) {
-                mTargetSdkVersion = info.targetSdkVersion;
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Couldn't look up " + mSbn.getPackageName());
-        }
-        if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(getChannel().getId())) {
-            if (mTargetSdkVersion < Build.VERSION_CODES.O) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private AudioAttributes calculateAudioAttributes() {
-        final Notification n = getNotification();
-        AudioAttributes attributes = getChannel().getAudioAttributes();
-        if (attributes == null) {
-            attributes = Notification.AUDIO_ATTRIBUTES_DEFAULT;
-        }
-
-        if (mPreChannelsNotification
-                && (getChannel().getUserLockedFields()
-                & NotificationChannel.USER_LOCKED_SOUND) == 0) {
-            if (n.audioAttributes != null) {
-                // prefer audio attributes to stream type
-                attributes = n.audioAttributes;
-            } else if (n.audioStreamType >= 0
-                    && n.audioStreamType < AudioSystem.getNumStreamTypes()) {
-                // the stream type is valid, use it
-                attributes = new AudioAttributes.Builder()
-                        .setInternalLegacyStreamType(n.audioStreamType)
-                        .build();
-            } else if (n.audioStreamType != AudioSystem.STREAM_DEFAULT) {
-                Log.w(TAG, String.format("Invalid stream type: %d", n.audioStreamType));
-            }
-        }
-        return attributes;
-    }
-
-    private int calculateInitialImportance() {
-        final Notification n = getNotification();
-        int importance = getChannel().getImportance();
-        int requestedImportance = IMPORTANCE_DEFAULT;
-
-        // Migrate notification flags to scores
-        if ((n.flags & Notification.FLAG_HIGH_PRIORITY) != 0) {
-            n.priority = Notification.PRIORITY_MAX;
-        }
-
-        n.priority = clamp(n.priority, Notification.PRIORITY_MIN,
-                Notification.PRIORITY_MAX);
-        switch (n.priority) {
-            case Notification.PRIORITY_MIN:
-                requestedImportance = IMPORTANCE_MIN;
-                break;
-            case Notification.PRIORITY_LOW:
-                requestedImportance = IMPORTANCE_LOW;
-                break;
-            case Notification.PRIORITY_DEFAULT:
-                requestedImportance = IMPORTANCE_DEFAULT;
-                break;
-            case Notification.PRIORITY_HIGH:
-            case Notification.PRIORITY_MAX:
-                requestedImportance = IMPORTANCE_HIGH;
-                break;
-        }
-
-        if (mPreChannelsNotification
-                && (importance == IMPORTANCE_UNSPECIFIED
-                || (getChannel().getUserLockedFields()
-                & USER_LOCKED_IMPORTANCE) == 0)) {
-            if (n.fullScreenIntent != null) {
-                requestedImportance = IMPORTANCE_HIGH;
-            }
-            importance = requestedImportance;
-        }
-
-        return importance;
-    }
-
-    public boolean isCategory(String category) {
-        return Objects.equals(getNotification().category, category);
-    }
-
-    /**
-     * Similar to {@link #isCategory(String)}, but checking the public version of the notification,
-     * if available.
-     */
-    public boolean isPublicVersionCategory(String category) {
-        Notification publicVersion = getNotification().publicVersion;
-        if (publicVersion == null) {
-            return false;
-        }
-        return Objects.equals(publicVersion.category, category);
-    }
-
-    public boolean isAudioAttributesUsage(int usage) {
-        return mAttributes != null && mAttributes.getUsage() == usage;
-    }
-
-    private boolean hasPerson() {
-        // TODO: cache favorite and recent contacts to check contact affinity
-        ArrayList<Person> people = getNotification().extras.getParcelableArrayList(
-                Notification.EXTRA_PEOPLE_LIST);
-        return people != null && !people.isEmpty();
-    }
-
-    protected boolean hasStyle(Class targetStyle) {
-        Class<? extends Notification.Style> style = getNotification().getNotificationStyle();
-        return targetStyle.equals(style);
-    }
-
-    protected boolean isOngoing() {
-        return (getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
-    }
-
-    protected boolean involvesPeople() {
-        return isMessaging()
-                || hasStyle(Notification.InboxStyle.class)
-                || hasPerson()
-                || isDefaultSmsApp();
-    }
-
-    private boolean isDefaultSmsApp() {
-        ComponentName defaultSmsApp = mSmsHelper.getDefaultSmsApplication();
-        if (defaultSmsApp == null) {
-            return false;
-        }
-        return mSbn.getPackageName().equals(defaultSmsApp.getPackageName());
-    }
-
-    protected boolean isMessaging() {
-        return isCategory(CATEGORY_MESSAGE)
-                || isPublicVersionCategory(CATEGORY_MESSAGE)
-                || hasStyle(Notification.MessagingStyle.class);
-    }
-
-    public boolean hasInlineReply() {
-        Notification.Action[] actions = getNotification().actions;
-        if (actions == null) {
-            return false;
-        }
-        for (Notification.Action action : actions) {
-            RemoteInput[] remoteInputs = action.getRemoteInputs();
-            if (remoteInputs == null) {
-                continue;
-            }
-            for (RemoteInput remoteInput : remoteInputs) {
-                if (remoteInput.getAllowFreeFormInput()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public void setSeen() {
-        synchronized (mLock) {
-            mSeen = true;
-        }
-    }
-
-    public void setShowActionEventLogged() {
-        synchronized (mLock) {
-            mIsShowActionEventLogged = true;
-        }
-    }
-
-    public boolean hasSeen() {
-        synchronized (mLock) {
-            return mSeen;
-        }
-    }
-
-    public boolean isShowActionEventLogged() {
-        synchronized (mLock) {
-            return mIsShowActionEventLogged;
-        }
-    }
-
-    public StatusBarNotification getSbn() {
-        return mSbn;
-    }
-
-    public Notification getNotification() {
-        return getSbn().getNotification();
-    }
-
-    public NotificationChannel getChannel() {
-        return mChannel;
-    }
-
-    public int getImportance() {
-        return mImportance;
-    }
-
-    private int clamp(int x, int low, int high) {
-        return (x < low) ? low : ((x > high) ? high : x);
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
deleted file mode 100644
index 93c522e..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ /dev/null
@@ -1,502 +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.ext.services.notification;
-
-import android.annotation.Nullable;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.app.Person;
-import android.app.RemoteAction;
-import android.app.RemoteInput;
-import android.content.Context;
-import android.content.Intent;
-import android.ext.services.R;
-import android.graphics.drawable.Icon;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.Process;
-import android.service.notification.NotificationAssistantService;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.LruCache;
-import android.util.Pair;
-import android.view.textclassifier.ConversationAction;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassificationContext;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextClassifierEvent;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.time.Instant;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.List;
-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";
-    static final String KEY_ACTION_SCORE = "action_score";
-    static final String KEY_TEXT = "text";
-    // If a notification has any of these flags set, it's inelgibile for actions being added.
-    private static final int FLAG_MASK_INELGIBILE_FOR_ACTIONS =
-            Notification.FLAG_ONGOING_EVENT
-                    | Notification.FLAG_FOREGROUND_SERVICE
-                    | Notification.FLAG_GROUP_SUMMARY
-                    | Notification.FLAG_NO_CLEAR;
-    private static final int MAX_RESULT_ID_TO_CACHE = 20;
-
-    private static final List<String> HINTS =
-            Collections.singletonList(ConversationActions.Request.HINT_FOR_NOTIFICATION);
-    private static final ConversationActions EMPTY_CONVERSATION_ACTIONS =
-            new ConversationActions(Collections.emptyList(), null);
-
-    private Context mContext;
-    private TextClassificationManager mTextClassificationManager;
-    private AssistantSettings mSettings;
-    private LruCache<String, Session> mSessionCache = new LruCache<>(MAX_RESULT_ID_TO_CACHE);
-
-    SmartActionsHelper(Context context, AssistantSettings settings) {
-        mContext = context;
-        mTextClassificationManager = mContext.getSystemService(TextClassificationManager.class);
-        mSettings = settings;
-    }
-
-    SmartSuggestions suggest(NotificationEntry entry) {
-        // Whenever suggest() is called on a notification, its previous session is ended.
-        mSessionCache.remove(entry.getSbn().getKey());
-
-        boolean eligibleForReplyAdjustment =
-                mSettings.mGenerateReplies && isEligibleForReplyAdjustment(entry);
-        boolean eligibleForActionAdjustment =
-                mSettings.mGenerateActions && isEligibleForActionAdjustment(entry);
-
-        ConversationActions conversationActionsResult =
-                suggestConversationActions(
-                        entry,
-                        eligibleForReplyAdjustment,
-                        eligibleForActionAdjustment);
-
-        String resultId = conversationActionsResult.getId();
-        List<ConversationAction> conversationActions =
-                conversationActionsResult.getConversationActions();
-
-        ArrayList<CharSequence> replies = new ArrayList<>();
-        Map<CharSequence, Float> repliesScore = new ArrayMap<>();
-        for (ConversationAction conversationAction : conversationActions) {
-            CharSequence textReply = conversationAction.getTextReply();
-            if (TextUtils.isEmpty(textReply)) {
-                continue;
-            }
-            replies.add(textReply);
-            repliesScore.put(textReply, conversationAction.getConfidenceScore());
-        }
-
-        ArrayList<Notification.Action> actions = new ArrayList<>();
-        for (ConversationAction conversationAction : conversationActions) {
-            if (!TextUtils.isEmpty(conversationAction.getTextReply())) {
-                continue;
-            }
-            Notification.Action notificationAction;
-            if (conversationAction.getAction() == null) {
-                notificationAction =
-                        createNotificationActionWithoutRemoteAction(conversationAction);
-            } else {
-                notificationAction = createNotificationActionFromRemoteAction(
-                        conversationAction.getAction(),
-                        conversationAction.getType(),
-                        conversationAction.getConfidenceScore());
-            }
-            if (notificationAction != null) {
-                actions.add(notificationAction);
-            }
-        }
-
-        // Start a new session for logging if necessary.
-        if (!TextUtils.isEmpty(resultId)
-                && !conversationActions.isEmpty()
-                && suggestionsMightBeUsedInNotification(
-                entry, !actions.isEmpty(), !replies.isEmpty())) {
-            mSessionCache.put(entry.getSbn().getKey(), new Session(resultId, repliesScore));
-        }
-
-        return new SmartSuggestions(replies, actions);
-    }
-
-    /**
-     * Creates notification action from ConversationAction that does not come up a RemoteAction.
-     * It could happen because we don't have common intents for some actions, like copying text.
-     */
-    @Nullable
-    private Notification.Action createNotificationActionWithoutRemoteAction(
-            ConversationAction conversationAction) {
-        if (ConversationAction.TYPE_COPY.equals(conversationAction.getType())) {
-            return createCopyCodeAction(conversationAction);
-        }
-        return null;
-    }
-
-    @Nullable
-    private Notification.Action createCopyCodeAction(ConversationAction conversationAction) {
-        Bundle extras = conversationAction.getExtras();
-        if (extras == null) {
-            return null;
-        }
-        Bundle entitiesExtas = extras.getParcelable(ENTITIES_EXTRAS);
-        if (entitiesExtas == null) {
-            return null;
-        }
-        String code = entitiesExtas.getString(KEY_TEXT);
-        if (TextUtils.isEmpty(code)) {
-            return null;
-        }
-        String contentDescription = mContext.getString(R.string.copy_code_desc, code);
-        Intent intent = new Intent(mContext, CopyCodeActivity.class);
-        intent.putExtra(Intent.EXTRA_TEXT, code);
-
-        RemoteAction remoteAction = new RemoteAction(Icon.createWithResource(
-                mContext.getResources(),
-                com.android.internal.R.drawable.ic_menu_copy_material),
-                code,
-                contentDescription,
-                PendingIntent.getActivity(
-                        mContext,
-                        code.hashCode(),
-                        intent,
-                        PendingIntent.FLAG_UPDATE_CURRENT
-                ));
-
-        return createNotificationActionFromRemoteAction(
-                remoteAction,
-                ConversationAction.TYPE_COPY,
-                conversationAction.getConfidenceScore());
-    }
-
-    /**
-     * Returns whether the suggestion might be used in the notifications in SysUI.
-     * <p>
-     * Currently, NAS has no idea if suggestions will actually be used in the notification, and thus
-     * this function tries to make a heuristic. This function tries to optimize the precision,
-     * that means when it is unsure, it will return false. The objective is to avoid false positive,
-     * which could pollute the log and CTR as we are logging click rate of suggestions that could
-     * be never visible to users. On the other hand, it is fine to have false negative because
-     * it would be just like sampling.
-     */
-    private boolean suggestionsMightBeUsedInNotification(
-            NotificationEntry notificationEntry, boolean hasSmartAction, boolean hasSmartReply) {
-        Notification notification = notificationEntry.getNotification();
-        boolean hasAppGeneratedContextualActions = !notification.getContextualActions().isEmpty();
-
-        Pair<RemoteInput, Notification.Action> freeformRemoteInputAndAction =
-                notification.findRemoteInputActionPair(/* requiresFreeform */ true);
-        boolean hasAppGeneratedReplies = false;
-        boolean allowGeneratedReplies = false;
-        if (freeformRemoteInputAndAction != null) {
-            RemoteInput freeformRemoteInput = freeformRemoteInputAndAction.first;
-            Notification.Action actionWithFreeformRemoteInput = freeformRemoteInputAndAction.second;
-            hasAppGeneratedReplies = !ArrayUtils.isEmpty(freeformRemoteInput.getChoices());
-            allowGeneratedReplies = actionWithFreeformRemoteInput.getAllowGeneratedReplies();
-        }
-
-        if (hasAppGeneratedReplies || hasAppGeneratedContextualActions) {
-            return false;
-        }
-        return hasSmartAction && notification.getAllowSystemGeneratedContextualActions()
-                || hasSmartReply && allowGeneratedReplies;
-    }
-
-    private void reportActionsGenerated(
-            String resultId, List<ConversationAction> conversationActions) {
-        if (TextUtils.isEmpty(resultId)) {
-            return;
-        }
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_ACTIONS_GENERATED, resultId)
-                        .setEntityTypes(conversationActions.stream()
-                                .map(ConversationAction::getType)
-                                .toArray(String[]::new))
-                        .build();
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    /**
-     * Adds action adjustments based on the notification contents.
-     */
-    private ConversationActions suggestConversationActions(
-            NotificationEntry entry,
-            boolean includeReplies,
-            boolean includeActions) {
-        if (!includeReplies && !includeActions) {
-            return EMPTY_CONVERSATION_ACTIONS;
-        }
-        List<ConversationActions.Message> messages = extractMessages(entry.getNotification());
-        if (messages.isEmpty()) {
-            return EMPTY_CONVERSATION_ACTIONS;
-        }
-        // Do not generate smart actions if the last message is from the local user.
-        ConversationActions.Message lastMessage = messages.get(messages.size() - 1);
-        if (arePersonsEqual(
-                ConversationActions.Message.PERSON_USER_SELF, lastMessage.getAuthor())) {
-            return EMPTY_CONVERSATION_ACTIONS;
-        }
-
-        TextClassifier.EntityConfig.Builder typeConfigBuilder =
-                new TextClassifier.EntityConfig.Builder();
-        if (!includeReplies) {
-            typeConfigBuilder.setExcludedTypes(
-                    Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY));
-        } else if (!includeActions) {
-            typeConfigBuilder
-                    .setIncludedTypes(
-                            Collections.singletonList(ConversationAction.TYPE_TEXT_REPLY))
-                    .includeTypesFromTextClassifier(false);
-        }
-        ConversationActions.Request request =
-                new ConversationActions.Request.Builder(messages)
-                        .setMaxSuggestions(mSettings.mMaxSuggestions)
-                        .setHints(HINTS)
-                        .setTypeConfig(typeConfigBuilder.build())
-                        .build();
-        ConversationActions conversationActions =
-                getTextClassifier().suggestConversationActions(request);
-        reportActionsGenerated(
-                conversationActions.getId(), conversationActions.getConversationActions());
-        return conversationActions;
-    }
-
-    void onNotificationExpansionChanged(NotificationEntry entry, boolean isExpanded) {
-        if (!isExpanded) {
-            return;
-        }
-        Session session = mSessionCache.get(entry.getSbn().getKey());
-        if (session == null) {
-            return;
-        }
-        // Only report if this is the first time the user sees these suggestions.
-        if (entry.isShowActionEventLogged()) {
-            return;
-        }
-        entry.setShowActionEventLogged();
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_ACTIONS_SHOWN, session.resultId)
-                        .build();
-        // TODO: If possible, report which replies / actions are actually seen by user.
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    void onNotificationDirectReplied(String key) {
-        Session session = mSessionCache.get(key);
-        if (session == null) {
-            return;
-        }
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_MANUAL_REPLY, session.resultId)
-                        .build();
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    void onSuggestedReplySent(String key, CharSequence reply,
-            @NotificationAssistantService.Source int source) {
-        if (source != NotificationAssistantService.SOURCE_FROM_ASSISTANT) {
-            return;
-        }
-        Session session = mSessionCache.get(key);
-        if (session == null) {
-            return;
-        }
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_SMART_ACTION, session.resultId)
-                        .setEntityTypes(ConversationAction.TYPE_TEXT_REPLY)
-                        .setScores(session.repliesScores.getOrDefault(reply, 0f))
-                        .build();
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    void onActionClicked(String key, Notification.Action action,
-            @NotificationAssistantService.Source int source) {
-        if (source != NotificationAssistantService.SOURCE_FROM_ASSISTANT) {
-            return;
-        }
-        Session session = mSessionCache.get(key);
-        if (session == null) {
-            return;
-        }
-        String actionType = action.getExtras().getString(KEY_ACTION_TYPE);
-        if (actionType == null) {
-            return;
-        }
-        TextClassifierEvent textClassifierEvent =
-                createTextClassifierEventBuilder(
-                        TextClassifierEvent.TYPE_SMART_ACTION, session.resultId)
-                        .setEntityTypes(actionType)
-                        .build();
-        getTextClassifier().onTextClassifierEvent(textClassifierEvent);
-    }
-
-    private Notification.Action createNotificationActionFromRemoteAction(
-            RemoteAction remoteAction, String actionType, float score) {
-        Icon icon = remoteAction.shouldShowIcon()
-                ? remoteAction.getIcon()
-                : Icon.createWithResource(mContext, com.android.internal.R.drawable.ic_action_open);
-        Bundle extras = new Bundle();
-        extras.putString(KEY_ACTION_TYPE, actionType);
-        extras.putFloat(KEY_ACTION_SCORE, score);
-        return new Notification.Action.Builder(
-                icon,
-                remoteAction.getTitle(),
-                remoteAction.getActionIntent())
-                .setContextual(true)
-                .addExtras(extras)
-                .build();
-    }
-
-    private TextClassifierEvent.ConversationActionsEvent.Builder createTextClassifierEventBuilder(
-            int eventType, String resultId) {
-        return new TextClassifierEvent.ConversationActionsEvent.Builder(eventType)
-                .setEventContext(
-                        new TextClassificationContext.Builder(
-                                mContext.getPackageName(), TextClassifier.WIDGET_TYPE_NOTIFICATION)
-                        .build())
-                .setResultId(resultId);
-    }
-
-    /**
-     * Returns whether a notification is eligible for action adjustments.
-     *
-     * <p>We exclude system notifications, those that get refreshed frequently, or ones that relate
-     * to fundamental phone functionality where any error would result in a very negative user
-     * experience.
-     */
-    private boolean isEligibleForActionAdjustment(NotificationEntry entry) {
-        Notification notification = entry.getNotification();
-        String pkg = entry.getSbn().getPackageName();
-        if (!Process.myUserHandle().equals(entry.getSbn().getUser())) {
-            return false;
-        }
-        if ((notification.flags & FLAG_MASK_INELGIBILE_FOR_ACTIONS) != 0) {
-            return false;
-        }
-        if (TextUtils.isEmpty(pkg) || pkg.equals("android")) {
-            return false;
-        }
-        // For now, we are only interested in messages.
-        return entry.isMessaging();
-    }
-
-    private boolean isEligibleForReplyAdjustment(NotificationEntry entry) {
-        if (!Process.myUserHandle().equals(entry.getSbn().getUser())) {
-            return false;
-        }
-        String pkg = entry.getSbn().getPackageName();
-        if (TextUtils.isEmpty(pkg) || pkg.equals("android")) {
-            return false;
-        }
-        // For now, we are only interested in messages.
-        if (!entry.isMessaging()) {
-            return false;
-        }
-        // Does not make sense to provide suggested replies if it is not something that can be
-        // replied.
-        if (!entry.hasInlineReply()) {
-            return false;
-        }
-        return true;
-    }
-
-    /** Returns the text most salient for action extraction in a notification. */
-    private List<ConversationActions.Message> extractMessages(Notification notification) {
-        Parcelable[] messages = notification.extras.getParcelableArray(Notification.EXTRA_MESSAGES);
-        if (messages == null || messages.length == 0) {
-            return Collections.singletonList(new ConversationActions.Message.Builder(
-                    ConversationActions.Message.PERSON_USER_OTHERS)
-                    .setText(notification.extras.getCharSequence(Notification.EXTRA_TEXT))
-                    .build());
-        }
-        Person localUser = notification.extras.getParcelable(Notification.EXTRA_MESSAGING_PERSON);
-        Deque<ConversationActions.Message> extractMessages = new ArrayDeque<>();
-        for (int i = messages.length - 1; i >= 0; i--) {
-            Notification.MessagingStyle.Message message =
-                    Notification.MessagingStyle.Message.getMessageFromBundle((Bundle) messages[i]);
-            if (message == null) {
-                continue;
-            }
-            // As per the javadoc of Notification.addMessage, null means local user.
-            Person senderPerson = message.getSenderPerson();
-            if (senderPerson == null) {
-                senderPerson = localUser;
-            }
-            Person author = localUser != null && arePersonsEqual(localUser, senderPerson)
-                    ? ConversationActions.Message.PERSON_USER_SELF : senderPerson;
-            extractMessages.push(new ConversationActions.Message.Builder(author)
-                    .setText(message.getText())
-                    .setReferenceTime(
-                            ZonedDateTime.ofInstant(Instant.ofEpochMilli(message.getTimestamp()),
-                                    ZoneOffset.systemDefault()))
-                    .build());
-            if (extractMessages.size() >= mSettings.mMaxMessagesToExtract) {
-                break;
-            }
-        }
-        return new ArrayList<>(extractMessages);
-    }
-
-    private TextClassifier getTextClassifier() {
-        return mTextClassificationManager.getTextClassifier();
-    }
-
-    private static boolean arePersonsEqual(Person left, Person right) {
-        return Objects.equals(left.getKey(), right.getKey())
-                && Objects.equals(left.getName(), right.getName())
-                && Objects.equals(left.getUri(), right.getUri());
-    }
-
-    static class SmartSuggestions {
-        public final ArrayList<CharSequence> replies;
-        public final ArrayList<Notification.Action> actions;
-
-        SmartSuggestions(
-                ArrayList<CharSequence> replies, ArrayList<Notification.Action> actions) {
-            this.replies = replies;
-            this.actions = actions;
-        }
-    }
-
-    private static class Session {
-        public final String resultId;
-        public final Map<CharSequence, Float> repliesScores;
-
-        Session(String resultId, Map<CharSequence, Float> repliesScores) {
-            this.resultId = resultId;
-            this.repliesScores = repliesScores;
-        }
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java
deleted file mode 100644
index 07be0b8..0000000
--- a/packages/ExtServices/src/android/ext/services/notification/SmsHelper.java
+++ /dev/null
@@ -1,75 +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.ext.services.notification;
-
-import static android.provider.Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL;
-
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.util.Log;
-
-import com.android.internal.telephony.SmsApplication;
-
-/**
- * A helper class for storing and retrieving the default SMS application.
- */
-public class SmsHelper {
-    private static final String TAG = "SmsHelper";
-
-    private final Context mContext;
-    private ComponentName mDefaultSmsApplication;
-    private BroadcastReceiver mBroadcastReceiver;
-
-    SmsHelper(Context context) {
-        mContext = context.getApplicationContext();
-    }
-
-    void initialize() {
-        if (mBroadcastReceiver == null) {
-            mDefaultSmsApplication = SmsApplication.getDefaultSmsApplication(mContext, false);
-            mBroadcastReceiver = new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    if (ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL.equals(intent.getAction())) {
-                        mDefaultSmsApplication =
-                                SmsApplication.getDefaultSmsApplication(mContext, false);
-                    } else {
-                        Log.w(TAG, "Unknown broadcast received: " + intent.getAction());
-                    }
-                }
-            };
-            mContext.registerReceiver(
-                    mBroadcastReceiver,
-                    new IntentFilter(ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL));
-        }
-    }
-
-    void destroy() {
-        if (mBroadcastReceiver != null) {
-            mContext.unregisterReceiver(mBroadcastReceiver);
-            mBroadcastReceiver = null;
-        }
-    }
-
-    @Nullable
-    public ComponentName getDefaultSmsApplication() {
-        return mDefaultSmsApplication;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java b/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
deleted file mode 100644
index 9d7a568..0000000
--- a/packages/ExtServices/src/android/ext/services/resolver/LRResolverRankerService.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.resolver;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Environment;
-import android.os.IBinder;
-import android.os.storage.StorageManager;
-import android.service.resolver.ResolverRankerService;
-import android.service.resolver.ResolverTarget;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A Logistic Regression based {@link android.service.resolver.ResolverRankerService}, to be used
- * in {@link ResolverComparator}.
- */
-public final class LRResolverRankerService extends ResolverRankerService {
-    private static final String TAG = "LRResolverRankerService";
-
-    private static final boolean DEBUG = false;
-
-    private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params";
-    private static final String BIAS_PREF_KEY = "bias";
-    private static final String VERSION_PREF_KEY = "version";
-
-    private static final String LAUNCH_SCORE = "launch";
-    private static final String TIME_SPENT_SCORE = "timeSpent";
-    private static final String RECENCY_SCORE = "recency";
-    private static final String CHOOSER_SCORE = "chooser";
-
-    // parameters for a pre-trained model, to initialize the app ranker. When updating the
-    // pre-trained model, please update these params, as well as initModel().
-    private static final int CURRENT_VERSION = 1;
-    private static final float LEARNING_RATE = 0.0001f;
-    private static final float REGULARIZER_PARAM = 0.0001f;
-
-    private SharedPreferences mParamSharedPref;
-    private ArrayMap<String, Float> mFeatureWeights;
-    private float mBias;
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        initModel();
-        return super.onBind(intent);
-    }
-
-    @Override
-    public void onPredictSharingProbabilities(List<ResolverTarget> targets) {
-        final int size = targets.size();
-        for (int i = 0; i < size; ++i) {
-            ResolverTarget target = targets.get(i);
-            ArrayMap<String, Float> features = getFeatures(target);
-            target.setSelectProbability(predict(features));
-        }
-    }
-
-    @Override
-    public void onTrainRankingModel(List<ResolverTarget> targets, int selectedPosition) {
-        final int size = targets.size();
-        if (selectedPosition < 0 || selectedPosition >= size) {
-            if (DEBUG) {
-                Log.d(TAG, "Invalid Position of Selected App " + selectedPosition);
-            }
-            return;
-        }
-        final ArrayMap<String, Float> positive = getFeatures(targets.get(selectedPosition));
-        final float positiveProbability = targets.get(selectedPosition).getSelectProbability();
-        final int targetSize = targets.size();
-        for (int i = 0; i < targetSize; ++i) {
-            if (i == selectedPosition) {
-                continue;
-            }
-            final ArrayMap<String, Float> negative = getFeatures(targets.get(i));
-            final float negativeProbability = targets.get(i).getSelectProbability();
-            if (negativeProbability > positiveProbability) {
-                update(negative, negativeProbability, false);
-                update(positive, positiveProbability, true);
-            }
-        }
-        commitUpdate();
-    }
-
-    private void initModel() {
-        mParamSharedPref = getParamSharedPref();
-        mFeatureWeights = new ArrayMap<>(4);
-        if (mParamSharedPref == null ||
-                mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) {
-            // Initializing the app ranker to a pre-trained model. When updating the pre-trained
-            // model, please increment CURRENT_VERSION, and update LEARNING_RATE and
-            // REGULARIZER_PARAM.
-            mBias = -1.6568f;
-            mFeatureWeights.put(LAUNCH_SCORE, 2.5543f);
-            mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f);
-            mFeatureWeights.put(RECENCY_SCORE, 0.269f);
-            mFeatureWeights.put(CHOOSER_SCORE, 4.2222f);
-        } else {
-            mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f);
-            mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f));
-            mFeatureWeights.put(
-                    TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f));
-            mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f));
-            mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f));
-        }
-    }
-
-    private ArrayMap<String, Float> getFeatures(ResolverTarget target) {
-        ArrayMap<String, Float> features = new ArrayMap<>(4);
-        features.put(RECENCY_SCORE, target.getRecencyScore());
-        features.put(TIME_SPENT_SCORE, target.getTimeSpentScore());
-        features.put(LAUNCH_SCORE, target.getLaunchScore());
-        features.put(CHOOSER_SCORE, target.getChooserScore());
-        return features;
-    }
-
-    private float predict(ArrayMap<String, Float> target) {
-        if (target == null) {
-            return 0.0f;
-        }
-        final int featureSize = target.size();
-        float sum = 0.0f;
-        for (int i = 0; i < featureSize; i++) {
-            String featureName = target.keyAt(i);
-            float weight = mFeatureWeights.getOrDefault(featureName, 0.0f);
-            sum += weight * target.valueAt(i);
-        }
-        return (float) (1.0 / (1.0 + Math.exp(-mBias - sum)));
-    }
-
-    private void update(ArrayMap<String, Float> target, float predict, boolean isSelected) {
-        if (target == null) {
-            return;
-        }
-        final int featureSize = target.size();
-        float error = isSelected ? 1.0f - predict : -predict;
-        for (int i = 0; i < featureSize; i++) {
-            String featureName = target.keyAt(i);
-            float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f);
-            mBias += LEARNING_RATE * error;
-            currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight +
-                    LEARNING_RATE * error * target.valueAt(i);
-            mFeatureWeights.put(featureName, currentWeight);
-        }
-        if (DEBUG) {
-            Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias);
-        }
-    }
-
-    private void commitUpdate() {
-        try {
-            SharedPreferences.Editor editor = mParamSharedPref.edit();
-            editor.putFloat(BIAS_PREF_KEY, mBias);
-            final int size = mFeatureWeights.size();
-            for (int i = 0; i < size; i++) {
-                editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i));
-            }
-            editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION);
-            editor.apply();
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to commit update" + e);
-        }
-    }
-
-    private SharedPreferences getParamSharedPref() {
-        // The package info in the context isn't initialized in the way it is for normal apps,
-        // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we
-        // build the path manually below using the same policy that appears in ContextImpl.
-        if (DEBUG) {
-            Log.d(TAG, "Context Package Name: " + getPackageName());
-        }
-        final File prefsFile = new File(new File(
-                Environment.getDataUserCePackageDirectory(
-                        StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()),
-                "shared_prefs"),
-                PARAM_SHARED_PREF_NAME + ".xml");
-        return getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
-    }
-}
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/sms/FinancialSmsServiceImpl.java b/packages/ExtServices/src/android/ext/services/sms/FinancialSmsServiceImpl.java
deleted file mode 100644
index 81a63dd..0000000
--- a/packages/ExtServices/src/android/ext/services/sms/FinancialSmsServiceImpl.java
+++ /dev/null
@@ -1,37 +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.ext.services.sms;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.database.CursorWindow;
-import android.os.Bundle;
-import android.service.sms.FinancialSmsService;
-
-/**
- * Service to provide financial apps access to sms messages.
- */
-public class FinancialSmsServiceImpl extends FinancialSmsService {
-
-    private static final String TAG = "FinancialSmsServiceImpl";
-    private static final String KEY_COLUMN_NAMES = "column_names";
-
-    @Nullable
-    @Override
-    public CursorWindow onGetSmsMessages(@NonNull Bundle params) {
-        return null;
-    }
-}
diff --git a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java b/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
deleted file mode 100644
index 862f50b2..0000000
--- a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.storage;
-
-import android.app.usage.CacheQuotaHint;
-import android.app.usage.CacheQuotaService;
-import android.os.Environment;
-import android.os.storage.StorageManager;
-import android.os.storage.VolumeInfo;
-import android.util.ArrayMap;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * CacheQuotaServiceImpl implements the CacheQuotaService with a strategy for populating the quota
- * of {@link CacheQuotaHint}.
- */
-public class CacheQuotaServiceImpl extends CacheQuotaService {
-    private static final double CACHE_RESERVE_RATIO = 0.15;
-
-    @Override
-    public List<CacheQuotaHint> onComputeCacheQuotaHints(List<CacheQuotaHint> requests) {
-        ArrayMap<String, List<CacheQuotaHint>> byUuid = new ArrayMap<>();
-        final int requestCount = requests.size();
-        for (int i = 0; i < requestCount; i++) {
-            CacheQuotaHint request = requests.get(i);
-            String uuid = request.getVolumeUuid();
-            List<CacheQuotaHint> listForUuid = byUuid.get(uuid);
-            if (listForUuid == null) {
-                listForUuid = new ArrayList<>();
-                byUuid.put(uuid, listForUuid);
-            }
-            listForUuid.add(request);
-        }
-
-        List<CacheQuotaHint> processed = new ArrayList<>();
-        byUuid.entrySet().forEach(
-                requestListEntry -> {
-                    // Collapse all usage stats to the same uid.
-                    Map<Integer, List<CacheQuotaHint>> byUid = requestListEntry.getValue()
-                            .stream()
-                            .collect(Collectors.groupingBy(CacheQuotaHint::getUid));
-                    byUid.values().forEach(uidGroupedList -> {
-                        int size = uidGroupedList.size();
-                        if (size < 2) {
-                            return;
-                        }
-                        CacheQuotaHint first = uidGroupedList.get(0);
-                        for (int i = 1; i < size; i++) {
-                            /* Note: We can't use the UsageStats built-in addition function because
-                                     UIDs may span multiple packages and usage stats adding has
-                                     matching package names as a precondition. */
-                            first.getUsageStats().mTotalTimeInForeground +=
-                                    uidGroupedList.get(i).getUsageStats().mTotalTimeInForeground;
-                        }
-                    });
-
-                    // Because the foreground stats have been added to the first element, we need
-                    // a list of only the first values (which contain the merged foreground time).
-                    List<CacheQuotaHint> flattenedRequests =
-                            byUid.values()
-                                 .stream()
-                                 .map(entryList -> entryList.get(0))
-                                 .filter(entry -> entry.getUsageStats().mTotalTimeInForeground != 0)
-                                 .sorted(sCacheQuotaRequestComparator)
-                                 .collect(Collectors.toList());
-
-                    // Because the elements are sorted, we can use the index to also be the sorted
-                    // index for cache quota calculation.
-                    double sum = getSumOfFairShares(flattenedRequests.size());
-                    String uuid = requestListEntry.getKey();
-                    long reservedSize = getReservedCacheSize(uuid);
-                    for (int count = 0; count < flattenedRequests.size(); count++) {
-                        double share = getFairShareForPosition(count) / sum;
-                        CacheQuotaHint entry = flattenedRequests.get(count);
-                        CacheQuotaHint.Builder builder = new CacheQuotaHint.Builder(entry);
-                        builder.setQuota(Math.round(share * reservedSize));
-                        processed.add(builder.build());
-                    }
-                }
-        );
-
-        return processed.stream()
-                .filter(request -> request.getQuota() > 0).collect(Collectors.toList());
-    }
-
-    private double getFairShareForPosition(int position) {
-        double value = 1.0 / Math.log(position + 3) - 0.285;
-        return (value > 0.01) ? value : 0.01;
-    }
-
-    private double getSumOfFairShares(int size) {
-        double sum = 0;
-        for (int i = 0; i < size; i++) {
-            sum += getFairShareForPosition(i);
-        }
-        return sum;
-    }
-
-    private long getReservedCacheSize(String uuid) {
-        // TODO: Revisit the cache size after running more storage tests.
-        // TODO: Figure out how to ensure ExtServices has the permissions to call
-        //       StorageStatsManager, because this is ignoring the cache...
-        StorageManager storageManager = getSystemService(StorageManager.class);
-        long freeBytes = 0;
-        if (uuid == StorageManager.UUID_PRIVATE_INTERNAL) { // regular equals because of null
-            freeBytes = Environment.getDataDirectory().getUsableSpace();
-        } else {
-            final VolumeInfo vol = storageManager.findVolumeByUuid(uuid);
-            freeBytes = vol.getPath().getUsableSpace();
-        }
-        return Math.round(freeBytes * CACHE_RESERVE_RATIO);
-    }
-
-    // Compares based upon foreground time.
-    private static Comparator<CacheQuotaHint> sCacheQuotaRequestComparator =
-            new Comparator<CacheQuotaHint>() {
-        @Override
-        public int compare(CacheQuotaHint o, CacheQuotaHint t1) {
-            long x = t1.getUsageStats().getTotalTimeInForeground();
-            long y = o.getUsageStats().getTotalTimeInForeground();
-            return (x < y) ? -1 : ((x == y) ? 0 : 1);
-        }
-    };
-}
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java b/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
deleted file mode 100644
index 670b419..0000000
--- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImpl.java
+++ /dev/null
@@ -1,125 +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.ext.services.watchdog;
-
-import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.provider.DeviceConfig;
-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;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 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";
-    public static final String PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS =
-            "watchdog_request_timeout_millis";
-    public static final long DEFAULT_REQUEST_TIMEOUT_MILLIS =
-            TimeUnit.HOURS.toMillis(1);
-    // 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<PackageConfig> onGetSupportedPackages() {
-        List<PackageConfig> packages = new ArrayList<>();
-        long requestTimeoutMillis = DeviceConfig.getLong(
-                DeviceConfig.NAMESPACE_ROLLBACK,
-                PROPERTY_WATCHDOG_REQUEST_TIMEOUT_MILLIS,
-                DEFAULT_REQUEST_TIMEOUT_MILLIS);
-        if (requestTimeoutMillis <= 0) {
-            requestTimeoutMillis = DEFAULT_REQUEST_TIMEOUT_MILLIS;
-        }
-        for (ExplicitHealthChecker checker : mSupportedCheckers.values()) {
-            PackageConfig pkg = new PackageConfig(checker.getSupportedPackageName(),
-                    requestTimeoutMillis);
-            packages.add(pkg);
-        }
-        return packages;
-    }
-
-    @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.getSupportedPackageName());
-            }
-        }
-        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
deleted file mode 100644
index a982d52..0000000
--- a/packages/ExtServices/src/android/ext/services/watchdog/ExplicitHealthChecker.java
+++ /dev/null
@@ -1,44 +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.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 name of the package this checker can make requests for.
-     */
-    String getSupportedPackageName();
-}
diff --git a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java b/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
deleted file mode 100644
index 5722e09..0000000
--- a/packages/ExtServices/src/android/ext/services/watchdog/NetworkChecker.java
+++ /dev/null
@@ -1,92 +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.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 getSupportedPackageName() {
-        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/Android.bp b/packages/ExtServices/tests/Android.bp
deleted file mode 100644
index ae60d4e..0000000
--- a/packages/ExtServices/tests/Android.bp
+++ /dev/null
@@ -1,27 +0,0 @@
-android_test {
-    name: "ExtServicesUnitTests",
-
-    // Include all test java files.
-    srcs: ["src/**/*.java"],
-
-    // We only want this apk build for tests.
-    certificate: "platform",
-
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-    ],
-
-    static_libs: [
-        "ExtServices-core",
-        "androidx.test.rules",
-        "compatibility-device-util-axt",
-        "mockito-target-minus-junit4",
-        "androidx.test.espresso.core",
-        "truth-prebuilt",
-        "testables",
-        "testng",
-    ],
-
-    platform_apis: true,
-}
diff --git a/packages/ExtServices/tests/AndroidManifest.xml b/packages/ExtServices/tests/AndroidManifest.xml
deleted file mode 100644
index a08a10e..0000000
--- a/packages/ExtServices/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="android.ext.services.tests.unit">
-
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.ext.services.tests.unit"
-                     android:label="ExtServices Test Cases">
-    </instrumentation>
-
-</manifest>
\ No newline at end of file
diff --git a/packages/ExtServices/tests/AndroidTest.xml b/packages/ExtServices/tests/AndroidTest.xml
deleted file mode 100644
index cd26ebc..0000000
--- a/packages/ExtServices/tests/AndroidTest.xml
+++ /dev/null
@@ -1,29 +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.
--->
-<configuration description="Runs Tests for ExtServices">
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="ExtServicesUnitTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="framework-base-presubmit" />
-    <option name="test-tag" value="ExtServicesUnitTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="android.ext.services.tests.unit" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
deleted file mode 100644
index 6fda4c7..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/AutofillFieldClassificationServiceImplTest.java
+++ /dev/null
@@ -1,118 +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.ext.services.autofill;
-
-import static android.service.autofill.AutofillFieldClassificationService.REQUIRED_ALGORITHM_EXACT_MATCH;
-import static android.view.autofill.AutofillValue.forText;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.os.Bundle;
-import android.view.autofill.AutofillValue;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Contains the base tests that does not rely on the specific algorithm implementation.
- */
-public class AutofillFieldClassificationServiceImplTest {
-
-    private final AutofillFieldClassificationServiceImpl mService =
-            new AutofillFieldClassificationServiceImpl();
-
-    @Test
-    public void testOnCalculateScores_nullActualValues() {
-        assertThat(mService.onCalculateScores(null, null, null, null, null, null, null)).isNull();
-    }
-
-    @Test
-    public void testOnCalculateScores_emptyActualValues() {
-        assertThat(mService.onCalculateScores(Collections.emptyList(), Arrays.asList("whatever"),
-                null, null, null, null, null)).isNull();
-    }
-
-    @Test
-    public void testOnCalculateScores_nullUserDataValues() {
-        assertThat(mService.onCalculateScores(Arrays.asList(AutofillValue.forText("whatever")),
-                null, null, null, null, null, null)).isNull();
-    }
-
-    @Test
-    public void testOnCalculateScores_emptyUserDataValues() {
-        assertThat(mService.onCalculateScores(Arrays.asList(AutofillValue.forText("whatever")),
-                Collections.emptyList(), null, null, null, null, null))
-                .isNull();
-    }
-
-    @Test
-    public void testCalculateScores() {
-        final List<AutofillValue> actualValues = Arrays.asList(forText("A"), forText("b"),
-                forText("dude"));
-        final List<String> userDataValues = Arrays.asList("a", "b", "B", "ab", "c", "dude",
-                "sweet_dude", "dude_sweet");
-        final List<String> categoryIds = Arrays.asList("cat", "cat", "cat", "cat", "cat", "last4",
-                "last4", "last4");
-        final HashMap<String, String> algorithms = new HashMap<>(1);
-        algorithms.put("last4", REQUIRED_ALGORITHM_EXACT_MATCH);
-
-        final Bundle last4Bundle = new Bundle();
-        last4Bundle.putInt("suffix", 4);
-
-        final HashMap<String, Bundle> args = new HashMap<>(1);
-        args.put("last4", last4Bundle);
-
-        final float[][] expectedScores = new float[][] {
-                new float[] { 1F, 0F, 0F, 0.5F, 0F, 0F, 0F, 0F },
-                new float[] { 0F, 1F, 1F, 0.5F, 0F, 0F, 0F, 0F },
-                new float[] { 0F, 0F, 0F, 0F  , 0F, 1F, 1F, 0F }
-        };
-        final float[][] actualScores = mService.onCalculateScores(actualValues, userDataValues,
-                categoryIds, null, null, algorithms, args);
-
-        // Unfortunately, Truth does not have an easy way to compare float matrices and show useful
-        // messages in case of error, so we need to check.
-        assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                toString(expectedScores)).that(actualScores.length).isEqualTo(3);
-        for (int i = 0; i < 3; i++) {
-            assertWithMessage("actual=%s, expected=%s", toString(actualScores),
-                    toString(expectedScores)).that(actualScores[i].length).isEqualTo(8);
-        }
-
-        for (int i = 0; i < actualScores.length; i++) {
-            final float[] line = actualScores[i];
-            for (int j = 0; j < line.length; j++) {
-                float cell = line[j];
-                assertWithMessage("wrong score at [%s, %s]", i, j).that(cell).isWithin(0.01F)
-                        .of(expectedScores[i][j]);
-            }
-        }
-    }
-
-    public static String toString(float[][] matrix) {
-        final StringBuilder string = new StringBuilder("[ ");
-        for (int i = 0; i < matrix.length; i++) {
-            string.append(Arrays.toString(matrix[i])).append(" ");
-        }
-        return string.append(" ]").toString();
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
deleted file mode 100644
index 3d754f7..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/EditDistanceScorerTest.java
+++ /dev/null
@@ -1,85 +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.ext.services.autofill;
-
-import static android.ext.services.autofill.EditDistanceScorer.calculateScore;
-import static android.ext.services.autofill.EditDistanceScorer.editDistance;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.autofill.AutofillValue;
-
-import org.junit.Test;
-
-public class EditDistanceScorerTest {
-
-    @Test
-    public void testCalculateScore_nullValue() {
-        assertFloat(calculateScore(null, "D'OH!"), 0);
-    }
-
-    @Test
-    public void testCalculateScore_nonTextValue() {
-        assertFloat(calculateScore(AutofillValue.forToggle(true), "D'OH!"), 0);
-    }
-
-    @Test
-    public void testCalculateScore_nullUserData() {
-        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), null), 0);
-    }
-
-    @Test
-    public void testCalculateScore_fullMatch() {
-        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), "D'OH!"), 1);
-        assertFloat(calculateScore(AutofillValue.forText(""), ""), 1);
-    }
-
-    @Test
-    public void testCalculateScore_fullMatchMixedCase() {
-        assertFloat(calculateScore(AutofillValue.forText("D'OH!"), "D'oH!"), 1);
-    }
-
-    @Test
-    public void testCalculateScore_mismatchDifferentSizes() {
-        assertFloat(calculateScore(AutofillValue.forText("X"), "Xy"), 0.50F);
-        assertFloat(calculateScore(AutofillValue.forText("Xy"), "X"), 0.50F);
-        assertFloat(calculateScore(AutofillValue.forText("One"), "MoreThanOne"), 0.27F);
-        assertFloat(calculateScore(AutofillValue.forText("MoreThanOne"), "One"), 0.27F);
-        assertFloat(calculateScore(AutofillValue.forText("1600 Amphitheatre Parkway"),
-                "1600 Amphitheatre Pkwy"), 0.88F);
-        assertFloat(calculateScore(AutofillValue.forText("1600 Amphitheatre Pkwy"),
-                "1600 Amphitheatre Parkway"), 0.88F);
-    }
-
-    @Test
-    public void testCalculateScore_partialMatch() {
-        assertFloat(calculateScore(AutofillValue.forText("Dude"), "Dxxx"), 0.25F);
-        assertFloat(calculateScore(AutofillValue.forText("Dude"), "DUxx"), 0.50F);
-        assertFloat(calculateScore(AutofillValue.forText("Dude"), "DUDx"), 0.75F);
-        assertFloat(calculateScore(AutofillValue.forText("Dxxx"), "Dude"), 0.25F);
-        assertFloat(calculateScore(AutofillValue.forText("DUxx"), "Dude"), 0.50F);
-        assertFloat(calculateScore(AutofillValue.forText("DUDx"), "Dude"), 0.75F);
-    }
-
-    @Test
-    public void testEditDistance_maxDistance() {
-        assertFloat(editDistance("testing", "b", 4), Integer.MAX_VALUE);
-    }
-
-    public static void assertFloat(float actualValue, float expectedValue) {
-        assertThat(actualValue).isWithin(0.01F).of(expectedValue);
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java b/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java
deleted file mode 100644
index bf5e160..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/autofill/ExactMatchTest.java
+++ /dev/null
@@ -1,98 +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.ext.services.autofill;
-
-import static android.ext.services.autofill.ExactMatch.calculateScore;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.os.Bundle;
-import android.view.autofill.AutofillValue;
-
-import org.junit.Test;
-
-public class ExactMatchTest {
-
-    private Bundle last4Bundle() {
-        final Bundle bundle = new Bundle();
-        bundle.putInt("suffix", 4);
-        return bundle;
-    }
-
-    @Test
-    public void testCalculateScore_nullValue() {
-        assertFloat(calculateScore(null, "TEST", null), 0);
-    }
-
-    @Test
-    public void testCalculateScore_nonTextValue() {
-        assertFloat(calculateScore(AutofillValue.forToggle(true), "TEST", null), 0);
-    }
-
-    @Test
-    public void testCalculateScore_nullUserData() {
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), null, null), 0);
-    }
-
-    @Test
-    public void testCalculateScore_succeedMatchMixedCases_last4() {
-        final Bundle last4 = last4Bundle();
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "1234 test", last4), 1);
-        assertFloat(calculateScore(AutofillValue.forText("test"), "1234 TEST", last4), 1);
-    }
-
-    @Test
-    public void testCalculateScore_mismatchDifferentSizes_last4() {
-        final Bundle last4 = last4Bundle();
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST1", last4), 0);
-        assertFloat(calculateScore(AutofillValue.forText(""), "TEST", last4), 0);
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "", last4), 0);
-    }
-
-    @Test
-    public void testCalculateScore_match() {
-        final Bundle last4 = last4Bundle();
-        assertFloat(calculateScore(AutofillValue.forText("1234 1234 1234 1234"),
-                "xxxx xxxx xxxx 1234", last4), 1);
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST", null), 1);
-        assertFloat(calculateScore(AutofillValue.forText("TEST 1234"), "1234", last4), 1);
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "test", null), 1);
-    }
-
-    @Test
-    public void testCalculateScore_badBundle() {
-        final Bundle bundle = new Bundle();
-        bundle.putInt("suffix", -2);
-        assertThrows(IllegalArgumentException.class, () -> calculateScore(
-                AutofillValue.forText("TEST"), "TEST", bundle));
-
-        final Bundle largeBundle = new Bundle();
-        largeBundle.putInt("suffix", 10);
-        assertFloat(calculateScore(AutofillValue.forText("TEST"), "TEST", largeBundle), 1);
-
-        final Bundle stringBundle = new Bundle();
-        stringBundle.putString("suffix", "value");
-        assertThrows(IllegalArgumentException.class, () -> calculateScore(
-                AutofillValue.forText("TEST"), "TEST", stringBundle));
-
-    }
-
-    public static void assertFloat(float actualValue, float expectedValue) {
-        assertThat(actualValue).isWithin(0.01F).of(expectedValue);
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java
deleted file mode 100644
index a87d57c..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AgingHelperTest.java
+++ /dev/null
@@ -1,160 +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.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.AlarmManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.PendingIntent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.os.Build;
-import android.os.Process;
-import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
-import android.testing.TestableContext;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class AgingHelperTest {
-    private String mPkg = "pkg";
-    private int mUid = 2018;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getTargetContext(), null);
-
-    @Mock
-    private NotificationCategorizer mCategorizer;
-    @Mock
-    private AlarmManager mAlarmManager;
-    @Mock
-    private IPackageManager mPackageManager;
-    @Mock
-    private AgingHelper.Callback mCallback;
-    @Mock
-    private SmsHelper mSmsHelper;
-
-    private AgingHelper mAgingHelper;
-
-    private StatusBarNotification generateSbn(String channelId) {
-        Notification n = new Notification.Builder(mContext, channelId)
-                .setContentTitle("foo")
-                .build();
-
-        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
-                UserHandle.SYSTEM, null, 0);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mPkg = mContext.getPackageName();
-        mUid = Process.myUid();
-
-        ApplicationInfo info = mock(ApplicationInfo.class);
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
-                .thenReturn(info);
-        info.targetSdkVersion = Build.VERSION_CODES.P;
-
-        mContext.addMockSystemService(AlarmManager.class, mAlarmManager);
-
-        mAgingHelper = new AgingHelper(mContext, mCategorizer, mCallback);
-    }
-
-    @Test
-    public void testNoSnoozingOnPost() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-
-
-        mAgingHelper.onNotificationPosted(entry);
-        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
-    }
-
-    @Test
-    public void testPostResetsSnooze() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-
-
-        mAgingHelper.onNotificationPosted(entry);
-        verify(mAlarmManager, times(1)).cancel(any(PendingIntent.class));
-    }
-
-    @Test
-    public void testSnoozingOnSeen() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        entry.setSeen();
-        when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
-
-        mAgingHelper.onNotificationSeen(entry);
-        verify(mAlarmManager, times(1)).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
-    }
-
-    @Test
-    public void testNoSnoozingOnSeenUserLocked() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        when(mCategorizer.getCategory(entry)).thenReturn(NotificationCategorizer.CATEGORY_PEOPLE);
-
-        mAgingHelper.onNotificationSeen(entry);
-        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
-    }
-
-    @Test
-    public void testNoSnoozingOnSeenAlreadyLow() {
-        NotificationEntry entry = mock(NotificationEntry.class);
-        when(entry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_HIGH));
-        when(entry.getImportance()).thenReturn(IMPORTANCE_MIN);
-
-        mAgingHelper.onNotificationSeen(entry);
-        verify(mAlarmManager, never()).setExactAndAllowWhileIdle(anyInt(), anyLong(), any());
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
deleted file mode 100644
index 5c877de..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
+++ /dev/null
@@ -1,263 +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.ext.services.notification;
-
-import static android.ext.services.notification.AssistantSettings.DEFAULT_MAX_SUGGESTIONS;
-import static android.provider.DeviceConfig.setProperty;
-
-import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.content.ContentResolver;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.support.test.uiautomator.UiDevice;
-import android.testing.TestableContext;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-
-@RunWith(AndroidJUnit4.class)
-public class AssistantSettingsTest {
-    private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
-            "device_config delete " + DeviceConfig.NAMESPACE_SYSTEMUI;
-
-    private static final int USER_ID = 5;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    @Mock Runnable mOnUpdateRunnable;
-
-    private ContentResolver mResolver;
-    private AssistantSettings mAssistantSettings;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mResolver = mContext.getContentResolver();
-        Handler handler = new Handler(Looper.getMainLooper());
-
-        // To bypass real calls to global settings values, set the Settings values here.
-        Settings.Global.putFloat(mResolver,
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT, 0.8f);
-        Settings.Global.putInt(mResolver, Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, 2);
-        Settings.Secure.putInt(mResolver, Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
-
-        mAssistantSettings = AssistantSettings.createForTesting(
-                handler, mResolver, USER_ID, mOnUpdateRunnable);
-    }
-
-    @After
-    public void tearDown() throws IOException {
-        clearDeviceConfig();
-    }
-
-    @Test
-    public void testGenerateRepliesDisabled() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
-                "false",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertFalse(mAssistantSettings.mGenerateReplies);
-    }
-
-    @Test
-    public void testGenerateRepliesEnabled() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
-                "true",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertTrue(mAssistantSettings.mGenerateReplies);
-    }
-
-    @Test
-    public void testGenerateRepliesNullFlag() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
-                "false",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertFalse(mAssistantSettings.mGenerateReplies);
-
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
-                null,
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        // Go back to the default value.
-        assertTrue(mAssistantSettings.mGenerateReplies);
-    }
-
-    @Test
-    public void testGenerateActionsDisabled() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
-                "false",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertFalse(mAssistantSettings.mGenerateActions);
-    }
-
-    @Test
-    public void testGenerateActionsEnabled() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
-                "true",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertTrue(mAssistantSettings.mGenerateActions);
-    }
-
-    @Test
-    public void testGenerateActionsNullFlag() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
-                "false",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertFalse(mAssistantSettings.mGenerateActions);
-
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
-                null,
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        // Go back to the default value.
-        assertTrue(mAssistantSettings.mGenerateActions);
-    }
-
-    @Test
-    public void testMaxMessagesToExtract() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
-                "10",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertEquals(10, mAssistantSettings.mMaxMessagesToExtract);
-    }
-
-    @Test
-    public void testMaxSuggestions() {
-        runWithShellPermissionIdentity(() -> setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS,
-                "5",
-                false /* makeDefault */));
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertEquals(5, mAssistantSettings.mMaxSuggestions);
-    }
-
-    @Test
-    public void testMaxSuggestionsEmpty() {
-        mAssistantSettings.onDeviceConfigPropertiesChanged(DeviceConfig.NAMESPACE_SYSTEMUI);
-
-        assertEquals(DEFAULT_MAX_SUGGESTIONS, mAssistantSettings.mMaxSuggestions);
-    }
-
-    @Test
-    public void testStreakLimit() {
-        verify(mOnUpdateRunnable, never()).run();
-
-        // Update settings value.
-        int newStreakLimit = 4;
-        Settings.Global.putInt(mResolver,
-                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT, newStreakLimit);
-
-        // Notify for the settings value we updated.
-        mAssistantSettings.onChange(false, Settings.Global.getUriFor(
-                Settings.Global.BLOCKING_HELPER_STREAK_LIMIT));
-
-        assertEquals(newStreakLimit, mAssistantSettings.mStreakLimit);
-        verify(mOnUpdateRunnable).run();
-    }
-
-    @Test
-    public void testDismissToViewRatioLimit() {
-        verify(mOnUpdateRunnable, never()).run();
-
-        // Update settings value.
-        float newDismissToViewRatioLimit = 3f;
-        Settings.Global.putFloat(mResolver,
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
-                newDismissToViewRatioLimit);
-
-        // Notify for the settings value we updated.
-        mAssistantSettings.onChange(false, Settings.Global.getUriFor(
-                Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT));
-
-        assertEquals(newDismissToViewRatioLimit, mAssistantSettings.mDismissToViewRatioLimit, 1e-6);
-        verify(mOnUpdateRunnable).run();
-    }
-
-    private static void clearDeviceConfig() throws IOException {
-        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        uiDevice.executeShellCommand(
-                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS);
-        uiDevice.executeShellCommand(
-                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES);
-        uiDevice.executeShellCommand(
-                CLEAR_DEVICE_CONFIG_KEY_CMD + " "
-                + SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT);
-        uiDevice.executeShellCommand(
-                CLEAR_DEVICE_CONFIG_KEY_CMD + " " + SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS);
-    }
-
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
deleted file mode 100644
index 012dcc0..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/**
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.app.NotificationManager.IMPORTANCE_LOW;
-import static android.app.NotificationManager.IMPORTANCE_MIN;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Application;
-import android.app.INotificationManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.os.Build;
-import android.os.UserHandle;
-import android.service.notification.Adjustment;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.Ranking;
-import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.NotificationStats;
-import android.service.notification.StatusBarNotification;
-import android.test.ServiceTestCase;
-import android.testing.TestableContext;
-import android.util.AtomicFile;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.util.FastXmlSerializer;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.util.ArrayList;
-
-public class AssistantTest extends ServiceTestCase<Assistant> {
-
-    private static final String PKG1 = "pkg1";
-    private static final int UID1 = 1;
-    private static final NotificationChannel P1C1 =
-            new NotificationChannel("one", "", IMPORTANCE_LOW);
-    private static final NotificationChannel P1C2 =
-            new NotificationChannel("p1c2", "", IMPORTANCE_DEFAULT);
-    private static final NotificationChannel P1C3 =
-            new NotificationChannel("p1c3", "", IMPORTANCE_MIN);
-    private static final String PKG2 = "pkg2";
-
-    private static final int UID2 = 2;
-    private static final NotificationChannel P2C1 =
-            new NotificationChannel("one", "", IMPORTANCE_LOW);
-
-    @Mock INotificationManager mNoMan;
-    @Mock AtomicFile mFile;
-    @Mock IPackageManager mPackageManager;
-    @Mock SmsHelper mSmsHelper;
-
-    Assistant mAssistant;
-    Application mApplication;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    public AssistantTest() {
-        super(Assistant.class);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        Intent startIntent =
-                new Intent("android.service.notification.NotificationAssistantService");
-        startIntent.setPackage("android.ext.services");
-
-        mApplication = (Application) InstrumentationRegistry.getInstrumentation().
-                getTargetContext().getApplicationContext();
-        // Force the test to use the correct application instead of trying to use a mock application
-        setApplication(mApplication);
-
-        setupService();
-        mAssistant = getService();
-
-        // Override the AssistantSettings factory.
-        mAssistant.mSettingsFactory = AssistantSettings::createForTesting;
-
-        bindService(startIntent);
-
-        mAssistant.mSettings.mDismissToViewRatioLimit = 0.8f;
-        mAssistant.mSettings.mStreakLimit = 2;
-        mAssistant.mSettings.mNewInterruptionModel = true;
-        mAssistant.setNoMan(mNoMan);
-        mAssistant.setFile(mFile);
-        mAssistant.setPackageManager(mPackageManager);
-
-        ApplicationInfo info = mock(ApplicationInfo.class);
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
-                .thenReturn(info);
-        info.targetSdkVersion = Build.VERSION_CODES.P;
-        when(mFile.startWrite()).thenReturn(mock(FileOutputStream.class));
-    }
-
-    private StatusBarNotification generateSbn(String pkg, int uid, NotificationChannel channel,
-            String tag, String groupKey) {
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setContentTitle("foo")
-                .setGroup(groupKey)
-                .build();
-
-        StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, 0, tag, uid, uid, n,
-                UserHandle.SYSTEM, null, 0);
-
-        return sbn;
-    }
-
-    private Ranking generateRanking(StatusBarNotification sbn, NotificationChannel channel) {
-        Ranking mockRanking = mock(Ranking.class);
-        when(mockRanking.getChannel()).thenReturn(channel);
-        when(mockRanking.getImportance()).thenReturn(channel.getImportance());
-        when(mockRanking.getKey()).thenReturn(sbn.getKey());
-        when(mockRanking.getOverrideGroupKey()).thenReturn(null);
-        return mockRanking;
-    }
-
-    private void almostBlockChannel(String pkg, int uid, NotificationChannel channel) {
-        for (int i = 0; i < ChannelImpressions.DEFAULT_STREAK_LIMIT; i++) {
-            dismissBadNotification(pkg, uid, channel, String.valueOf(i));
-        }
-    }
-
-    private void dismissBadNotification(String pkg, int uid, NotificationChannel channel,
-            String tag) {
-        StatusBarNotification sbn = generateSbn(pkg, uid, channel, tag, null);
-        mAssistant.setFakeRanking(generateRanking(sbn, channel));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.setFakeRanking(mock(Ranking.class));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-    }
-
-    @Test
-    public void testNoAdjustmentForInitialPost() throws Exception {
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, null, null);
-
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture());
-        assertEquals(sbn.getKey(), captor.getValue().getKey());
-        assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
-                captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
-    }
-
-    @Test
-    public void testMinCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C3);
-        dismissBadNotification(PKG1, UID1, P1C3, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C3, "new one!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C3));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testGroupChildCanTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", "I HAVE A GROUP");
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group");
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture());
-        assertEquals(sbn.getKey(), captor.getValue().getKey());
-        assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
-                captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
-    }
-
-    @Test
-    public void testGroupSummaryCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", "I HAVE A GROUP");
-        sbn.getNotification().flags |= Notification.FLAG_GROUP_SUMMARY;
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group");
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAodCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_AOD);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testInteractedCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        stats.setExpanded();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAppDismissedCannotTriggerAdjustment() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-        NotificationStats stats = new NotificationStats();
-        stats.setDismissalSurface(NotificationStats.DISMISSAL_SHADE);
-        stats.setSeen();
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), stats, NotificationListenerService.REASON_APP_CANCEL);
-
-        sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testAppSeparation() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG2, UID2, P2C1, "new app!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P2C1));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testChannelSeparation() throws Exception {
-        almostBlockChannel(PKG1, UID1, P1C1);
-        dismissBadNotification(PKG1, UID1, P1C1, "trigger!");
-
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C2, "new app!", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C2));
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
-    }
-
-    @Test
-    public void testReadXml() throws Exception {
-        String key1 = mAssistant.getKey("pkg1", 1, "channel1");
-        int streak1 = 2;
-        int views1 = 5;
-        int dismiss1 = 9;
-
-        int streak1a = 3;
-        int views1a = 10;
-        int dismiss1a = 99;
-        String key1a = mAssistant.getKey("pkg1", 1, "channel1a");
-
-        int streak2 = 7;
-        int views2 = 77;
-        int dismiss2 = 777;
-        String key2 = mAssistant.getKey("pkg2", 2, "channel2");
-
-        String xml = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
-                + "<assistant version=\"1\">\n"
-                + "<impression-set key=\"" + key1 + "\" "
-                + "dismisses=\"" + dismiss1 + "\" views=\"" + views1
-                + "\" streak=\"" + streak1 + "\"/>\n"
-                + "<impression-set key=\"" + key1a + "\" "
-                + "dismisses=\"" + dismiss1a + "\" views=\"" + views1a
-                + "\" streak=\"" + streak1a + "\"/>\n"
-                + "<impression-set key=\"" + key2 + "\" "
-                + "dismisses=\"" + dismiss2 + "\" views=\"" + views2
-                + "\" streak=\"" + streak2 + "\"/>\n"
-                + "</assistant>\n";
-        mAssistant.readXml(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())));
-
-        ChannelImpressions c1 = mAssistant.getImpressions(key1);
-        assertEquals(2, c1.getStreak());
-        assertEquals(5, c1.getViews());
-        assertEquals(9, c1.getDismissals());
-
-        ChannelImpressions c1a = mAssistant.getImpressions(key1a);
-        assertEquals(3, c1a.getStreak());
-        assertEquals(10, c1a.getViews());
-        assertEquals(99, c1a.getDismissals());
-
-        ChannelImpressions c2 = mAssistant.getImpressions(key2);
-        assertEquals(7, c2.getStreak());
-        assertEquals(77, c2.getViews());
-        assertEquals(777, c2.getDismissals());
-    }
-
-    @Test
-    public void testRoundTripXml() throws Exception {
-        String key1 = mAssistant.getKey("pkg1", 1, "channel1");
-        ChannelImpressions ci1 = new ChannelImpressions();
-        String key2 = mAssistant.getKey("pkg1", 1, "channel2");
-        ChannelImpressions ci2 = new ChannelImpressions();
-        for (int i = 0; i < 3; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-        ChannelImpressions ci3 = new ChannelImpressions();
-        String key3 = mAssistant.getKey("pkg3", 3, "channel2");
-        for (int i = 0; i < 9; i++) {
-            ci3.incrementViews();
-            if (i % 3 == 0) {
-                ci3.incrementDismissals();
-            }
-        }
-
-        mAssistant.insertImpressions(key1, ci1);
-        mAssistant.insertImpressions(key2, ci2);
-        mAssistant.insertImpressions(key3, ci3);
-
-        XmlSerializer serializer = new FastXmlSerializer();
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
-        mAssistant.writeXml(serializer);
-
-        Assistant assistant = new Assistant();
-        // onCreate is not invoked, so settings won't be initialised, unless we do it here.
-        assistant.mSettings = mAssistant.mSettings;
-        assistant.readXml(new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray())));
-
-        assertEquals(ci1, assistant.getImpressions(key1));
-        assertEquals(ci2, assistant.getImpressions(key2));
-        assertEquals(ci3, assistant.getImpressions(key3));
-    }
-
-    @Test
-    public void testSettingsProviderUpdate() {
-        // Set up channels
-        String key = mAssistant.getKey("pkg1", 1, "channel1");
-        ChannelImpressions ci = new ChannelImpressions();
-        for (int i = 0; i < 3; i++) {
-            ci.incrementViews();
-            if (i % 2 == 0) {
-                ci.incrementDismissals();
-            }
-        }
-
-        mAssistant.insertImpressions(key, ci);
-
-        // With default values, the blocking helper shouldn't be triggered.
-        assertEquals(false, ci.shouldTriggerBlock());
-
-        // Update settings values.
-        mAssistant.mSettings.mDismissToViewRatioLimit = 0f;
-        mAssistant.mSettings.mStreakLimit = 0;
-
-        // Notify for the settings values we updated.
-        mAssistant.mSettings.mOnUpdateRunnable.run();
-
-        // With the new threshold, the blocking helper should be triggered.
-        assertEquals(true, ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testTrimLiveNotifications() {
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C1, "no", null);
-        mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
-
-        mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
-
-        assertTrue(mAssistant.mLiveNotifications.containsKey(sbn.getKey()));
-
-        mAssistant.onNotificationRemoved(
-                sbn, mock(RankingMap.class), new NotificationStats(), 0);
-
-        assertFalse(mAssistant.mLiveNotifications.containsKey(sbn.getKey()));
-    }
-
-    @Test
-    public void testAssistantNeverIncreasesImportanceWhenSuggestingSilent() throws Exception {
-        StatusBarNotification sbn = generateSbn(PKG1, UID1, P1C3, "min notif!", null);
-        Adjustment adjust = mAssistant.createEnqueuedNotificationAdjustment(
-                new NotificationEntry(mContext, mPackageManager, sbn, P1C3, mSmsHelper),
-                new ArrayList<>(),
-                new ArrayList<>());
-        assertEquals(IMPORTANCE_MIN, adjust.getSignals().getInt(Adjustment.KEY_IMPORTANCE));
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java
deleted file mode 100644
index 3253802..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/ChannelImpressionsTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.notification;
-
-import static android.ext.services.notification.ChannelImpressions.DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT;
-import static android.ext.services.notification.ChannelImpressions.DEFAULT_STREAK_LIMIT;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class ChannelImpressionsTest {
-
-    @Test
-    public void testNoResultNoBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testNoStreakNoBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT - 1; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testNoStreakNoBlock_breakStreak() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-            if (i == DEFAULT_STREAK_LIMIT - 1) {
-                ci.resetStreak();
-            }
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testStreakBlock() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        assertTrue(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testRatio_NoBlockEvenWithStreak() {
-        ChannelImpressions ci = new ChannelImpressions();
-
-        for (int i = 0; i < DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-            ci.incrementViews();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testAppend() {
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.incrementViews();
-        ci.incrementDismissals();
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.incrementViews();
-        ci2.incrementDismissals();
-        ci2.incrementViews();
-
-        ci.append(ci2);
-        assertEquals(3, ci.getViews());
-        assertEquals(2, ci.getDismissals());
-        assertEquals(2, ci.getStreak());
-
-        assertEquals(2, ci2.getViews());
-        assertEquals(1, ci2.getDismissals());
-        assertEquals(1, ci2.getStreak());
-
-        // no crash
-        ci.append(null);
-    }
-
-    @Test
-    public void testUpdateThresholds_streakLimitsCorrectlyApplied() {
-        int updatedStreakLimit = DEFAULT_STREAK_LIMIT + 3;
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.updateThresholds(DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT, updatedStreakLimit);
-
-        for (int i = 0; i <= updatedStreakLimit; i++) {
-            ci.incrementViews();
-            ci.incrementDismissals();
-        }
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.updateThresholds(DEFAULT_DISMISS_TO_VIEW_RATIO_LIMIT, updatedStreakLimit);
-
-        for (int i = 0; i < updatedStreakLimit; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-
-        assertTrue(ci.shouldTriggerBlock());
-        assertFalse(ci2.shouldTriggerBlock());
-    }
-
-    @Test
-    public void testUpdateThresholds_ratioLimitsCorrectlyApplied() {
-        float updatedDismissRatio = .99f;
-        ChannelImpressions ci = new ChannelImpressions();
-        ci.updateThresholds(updatedDismissRatio, DEFAULT_STREAK_LIMIT);
-
-        // N views, N-1 dismissals, which doesn't satisfy the ratio = 1 criteria.
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci.incrementViews();
-            if (i != DEFAULT_STREAK_LIMIT) {
-                ci.incrementDismissals();
-            }
-        }
-
-        ChannelImpressions ci2 = new ChannelImpressions();
-        ci2.updateThresholds(updatedDismissRatio, DEFAULT_STREAK_LIMIT);
-
-        for (int i = 0; i <= DEFAULT_STREAK_LIMIT; i++) {
-            ci2.incrementViews();
-            ci2.incrementDismissals();
-        }
-
-        assertFalse(ci.shouldTriggerBlock());
-        assertTrue(ci2.shouldTriggerBlock());
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java
deleted file mode 100644
index ada61d0..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/EntityTypeCounterTest.java
+++ /dev/null
@@ -1,59 +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.ext.services.notification;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.view.textclassifier.TextClassifier;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class EntityTypeCounterTest {
-    private EntityTypeCounter mCounter;
-
-    @Before
-    public void setup() {
-        mCounter = new EntityTypeCounter();
-    }
-
-    @Test
-    public void testIncrementAndGetCount() {
-        mCounter.increment(TextClassifier.TYPE_URL);
-        mCounter.increment(TextClassifier.TYPE_URL);
-        mCounter.increment(TextClassifier.TYPE_URL);
-
-        mCounter.increment(TextClassifier.TYPE_PHONE);
-        mCounter.increment(TextClassifier.TYPE_PHONE);
-
-        assertThat(mCounter.getCount(TextClassifier.TYPE_URL)).isEqualTo(3);
-        assertThat(mCounter.getCount(TextClassifier.TYPE_PHONE)).isEqualTo(2);
-        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE_TIME)).isEqualTo(0);
-    }
-
-    @Test
-    public void testIncrementAndGetCount_typeDateAndDateTime() {
-        mCounter.increment(TextClassifier.TYPE_DATE_TIME);
-        mCounter.increment(TextClassifier.TYPE_DATE);
-
-        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE_TIME)).isEqualTo(2);
-        assertThat(mCounter.getCount(TextClassifier.TYPE_DATE)).isEqualTo(2);
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
deleted file mode 100644
index ea77d31..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationCategorizerTest.java
+++ /dev/null
@@ -1,202 +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.ext.services.notification;
-
-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_MIN;
-import static android.os.Process.FIRST_APPLICATION_UID;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.os.Process;
-import android.service.notification.StatusBarNotification;
-import android.testing.TestableContext;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class NotificationCategorizerTest {
-    @Mock
-    private NotificationEntry mEntry;
-    @Mock
-    private StatusBarNotification mSbn;
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mEntry.getSbn()).thenReturn(mSbn);
-        when(mSbn.getUid()).thenReturn(Process.myUid());
-        when(mSbn.getPackageName()).thenReturn(mContext.getPackageName());
-    }
-
-    @Test
-    public void testPeopleCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.involvesPeople()).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_PEOPLE, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_PEOPLE));
-    }
-
-    @Test
-    public void testMin() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_MIN));
-        when(mEntry.involvesPeople()).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_MIN, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_MIN));
-    }
-
-    @Test
-    public void testHigh() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_HIGH));
-
-        assertEquals(NotificationCategorizer.CATEGORY_HIGH, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_HIGH));
-    }
-
-    @Test
-    public void testOngoingCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isOngoing()).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_ONGOING, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_ONGOING));
-
-        when(mEntry.isOngoing()).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-    }
-
-    @Test
-    public void testAlarmCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isCategory(Notification.CATEGORY_ALARM)).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_ALARM, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_ALARM));
-
-        when(mEntry.isCategory(Notification.CATEGORY_ALARM)).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-    }
-
-    @Test
-    public void testCallCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isCategory(Notification.CATEGORY_CALL)).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_CALL, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_CALL));
-
-        when(mEntry.isCategory(Notification.CATEGORY_CALL)).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-    }
-
-    @Test
-    public void testReminderCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isCategory(Notification.CATEGORY_REMINDER)).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_REMINDER, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_REMINDER));
-
-        when(mEntry.isCategory(Notification.CATEGORY_REMINDER)).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE));
-    }
-
-    @Test
-    public void testEventCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.isCategory(Notification.CATEGORY_EVENT)).thenReturn(true);
-
-        assertEquals(NotificationCategorizer.CATEGORY_EVENT, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_EVENT));
-
-        when(mEntry.isCategory(Notification.CATEGORY_EVENT)).thenReturn(false);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-    }
-
-    @Test
-    public void testSystemCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_DEFAULT));
-        when(mEntry.getImportance()).thenReturn(IMPORTANCE_DEFAULT);
-        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID - 1);
-
-        assertEquals(NotificationCategorizer.CATEGORY_SYSTEM, nc.getCategory(mEntry));
-        assertFalse(nc.shouldSilence(NotificationCategorizer.CATEGORY_SYSTEM));
-
-        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-    }
-
-    @Test
-    public void testSystemLowCategory() {
-        NotificationCategorizer nc = new NotificationCategorizer();
-
-        when(mEntry.getChannel()).thenReturn(new NotificationChannel("", "", IMPORTANCE_LOW));
-        when(mEntry.getImportance()).thenReturn(IMPORTANCE_LOW);
-        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID - 1);
-
-        assertEquals(NotificationCategorizer.CATEGORY_SYSTEM_LOW, nc.getCategory(mEntry));
-        assertTrue(nc.shouldSilence(NotificationCategorizer.CATEGORY_SYSTEM_LOW));
-
-        when(mSbn.getUid()).thenReturn(FIRST_APPLICATION_UID);
-        assertEquals(NotificationCategorizer.CATEGORY_EVERYTHING_ELSE, nc.getCategory(mEntry));
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java
deleted file mode 100644
index c026079..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/NotificationEntryTest.java
+++ /dev/null
@@ -1,266 +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.ext.services.notification;
-
-import static android.app.Notification.FLAG_CAN_COLORIZE;
-import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
-import static android.app.NotificationManager.IMPORTANCE_HIGH;
-import static android.media.AudioAttributes.USAGE_ALARM;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertNull;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.Person;
-import android.content.ComponentName;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Icon;
-import android.media.AudioAttributes;
-import android.os.Build;
-import android.os.Process;
-import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
-import android.testing.TestableContext;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-@RunWith(AndroidJUnit4.class)
-public class NotificationEntryTest {
-    private String mPkg = "pkg";
-    private int mUid = 2018;
-    @Mock
-    private IPackageManager mPackageManager;
-    @Mock
-    private ApplicationInfo mAppInfo;
-    @Mock
-    private SmsHelper mSmsHelper;
-
-    private static final String DEFAULT_SMS_PACKAGE_NAME = "foo";
-
-    @Rule
-    public final TestableContext mContext =
-            new TestableContext(InstrumentationRegistry.getContext(), null);
-
-    private StatusBarNotification generateSbn(String channelId) {
-        Notification n = new Notification.Builder(mContext, channelId)
-                .setContentTitle("foo")
-                .build();
-
-        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
-                UserHandle.SYSTEM, null, 0);
-    }
-
-    private StatusBarNotification generateSbn(String channelId, String packageName) {
-        Notification n = new Notification.Builder(mContext, channelId)
-                .setContentTitle("foo")
-                .build();
-
-        return new StatusBarNotification(packageName, packageName, 0, "tag", mUid, mUid, n,
-                UserHandle.SYSTEM, null, 0);
-    }
-
-    private StatusBarNotification generateSbn(Notification n) {
-        return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, n,
-                UserHandle.SYSTEM, null, 0);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mPkg = mContext.getPackageName();
-        mUid = Process.myUid();
-        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
-                .thenReturn(mAppInfo);
-        mAppInfo.targetSdkVersion = Build.VERSION_CODES.P;
-        when(mSmsHelper.getDefaultSmsApplication())
-                .thenReturn(new ComponentName(DEFAULT_SMS_PACKAGE_NAME, "bar"));
-    }
-
-    @Test
-    public void testHasPerson() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        ArrayList<Person> people = new ArrayList<>();
-        people.add(new Person.Builder().setKey("mailto:testing@android.com").build());
-        sbn.getNotification().extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, people);
-
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        assertTrue(entry.involvesPeople());
-    }
-
-    @Test
-    public void testNotPerson() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId());
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        assertFalse(entry.involvesPeople());
-    }
-
-    @Test
-    public void testHasPerson_matchesDefaultSmsApp() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId(), DEFAULT_SMS_PACKAGE_NAME);
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        assertTrue(entry.involvesPeople());
-    }
-
-    @Test
-    public void testHasPerson_doesntMatchDefaultSmsApp() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        StatusBarNotification sbn = generateSbn(channel.getId(), "abc");
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, sbn, channel, mSmsHelper);
-        assertFalse(entry.involvesPeople());
-    }
-
-    @Test
-    public void testIsInboxStyle() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setStyle(new Notification.InboxStyle())
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-        assertTrue(entry.hasStyle(Notification.InboxStyle.class));
-    }
-
-    @Test
-    public void testIsMessagingStyle() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setStyle(new Notification.MessagingStyle(""))
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-        assertTrue(entry.hasStyle(Notification.MessagingStyle.class));
-    }
-
-    @Test
-    public void testIsNotPersonStyle() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setStyle(new Notification.BigPictureStyle())
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-        assertFalse(entry.hasStyle(Notification.InboxStyle.class));
-        assertFalse(entry.hasStyle(Notification.MessagingStyle.class));
-    }
-
-    @Test
-    public void testIsAudioAttributes() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        channel.setSound(null, new AudioAttributes.Builder().setUsage(USAGE_ALARM).build());
-
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
-
-        assertTrue(entry.isAudioAttributesUsage(USAGE_ALARM));
-    }
-
-    @Test
-    public void testIsNotAudioAttributes() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper);
-
-        assertFalse(entry.isAudioAttributesUsage(USAGE_ALARM));
-    }
-
-    @Test
-    public void testIsCategory() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setCategory(Notification.CATEGORY_EMAIL)
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-
-        assertTrue(entry.isCategory(Notification.CATEGORY_EMAIL));
-        assertFalse(entry.isCategory(Notification.CATEGORY_MESSAGE));
-    }
-
-    @Test
-    public void testIsOngoing() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setFlag(FLAG_FOREGROUND_SERVICE, true)
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-
-        assertTrue(entry.isOngoing());
-    }
-
-    @Test
-    public void testIsNotOngoing() {
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        Notification n = new Notification.Builder(mContext, channel.getId())
-                .setFlag(FLAG_CAN_COLORIZE, true)
-                .build();
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-
-        assertFalse(entry.isOngoing());
-    }
-
-    @Test
-    public void testShrinkNotification() {
-        Notification n = new Notification.Builder(mContext, "")
-                .setLargeIcon(Icon.createWithResource(
-                        mContext, android.R.drawable.alert_dark_frame))
-                .setSmallIcon(android.R.drawable.sym_def_app_icon)
-                .build();
-        n.largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
-        NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH);
-
-        NotificationEntry entry = new NotificationEntry(
-                mContext, mPackageManager, generateSbn(n), channel, mSmsHelper);
-
-        assertNull(entry.getNotification().getSmallIcon());
-        assertNull(entry.getNotification().getLargeIcon());
-        assertNull(entry.getNotification().largeIcon);
-        assertNull(entry.getNotification().extras.getParcelable(Notification.EXTRA_LARGE_ICON));
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
deleted file mode 100644
index 52b7225..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
+++ /dev/null
@@ -1,566 +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.ext.services.notification;
-
-import static com.google.common.truth.Truth.assertAbout;
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Person;
-import android.app.RemoteInput;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageManager;
-import android.graphics.drawable.Icon;
-import android.os.Bundle;
-import android.os.Process;
-import android.service.notification.NotificationAssistantService;
-import android.service.notification.StatusBarNotification;
-import android.view.textclassifier.ConversationAction;
-import android.view.textclassifier.ConversationActions;
-import android.view.textclassifier.TextClassificationManager;
-import android.view.textclassifier.TextClassifier;
-import android.view.textclassifier.TextClassifierEvent;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.Subject;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.time.Instant;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-import javax.annotation.Nullable;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-@RunWith(AndroidJUnit4.class)
-public class SmartActionsHelperTest {
-    private static final String RESULT_ID = "id";
-    private static final float SCORE = 0.7f;
-    private static final CharSequence SMART_REPLY = "Home";
-    private static final ConversationAction REPLY_ACTION =
-            new ConversationAction.Builder(ConversationAction.TYPE_TEXT_REPLY)
-                    .setTextReply(SMART_REPLY)
-                    .setConfidenceScore(SCORE)
-                    .build();
-    private static final String MESSAGE = "Where are you?";
-
-    @Mock
-    IPackageManager mIPackageManager;
-    @Mock
-    private TextClassifier mTextClassifier;
-    private StatusBarNotification mStatusBarNotification;
-    @Mock
-    private SmsHelper mSmsHelper;
-
-    private SmartActionsHelper mSmartActionsHelper;
-    private Context mContext;
-    private Notification.Builder mNotificationBuilder;
-    private AssistantSettings mSettings;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mContext = InstrumentationRegistry.getTargetContext();
-
-        mContext.getSystemService(TextClassificationManager.class)
-                .setTextClassifier(mTextClassifier);
-        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
-                .thenReturn(new ConversationActions(Arrays.asList(REPLY_ACTION), RESULT_ID));
-
-        mNotificationBuilder = new Notification.Builder(mContext, "channel");
-        mSettings = AssistantSettings.createForTesting(
-                null, null, Process.myUserHandle().getIdentifier(), null);
-        mSettings.mGenerateActions = true;
-        mSettings.mGenerateReplies = true;
-        mSmartActionsHelper = new SmartActionsHelper(mContext, mSettings);
-    }
-
-    private void setStatusBarNotification(Notification n) {
-        mStatusBarNotification = new StatusBarNotification("random.app", "random.app", 0,
-        "tag", Process.myUid(), Process.myPid(), n, Process.myUserHandle(), null, 0);
-    }
-
-    @Test
-    public void testSuggest_notMessageNotification() {
-        Notification notification = mNotificationBuilder.setContentText(MESSAGE).build();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        verify(mTextClassifier, never())
-                .suggestConversationActions(any(ConversationActions.Request.class));
-    }
-
-    @Test
-    public void testSuggest_noInlineReply() {
-        Notification notification =
-                mNotificationBuilder
-                        .setContentText(MESSAGE)
-                        .setCategory(Notification.CATEGORY_MESSAGE)
-                        .build();
-        setStatusBarNotification(notification);
-
-        ConversationActions.Request request = runSuggestAndCaptureRequest();
-
-        // actions are enabled, but replies are not.
-        assertThat(
-                request.getTypeConfig().resolveEntityListModifications(
-                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
-                                ConversationAction.TYPE_OPEN_URL)))
-                .containsExactly(ConversationAction.TYPE_OPEN_URL);
-    }
-
-    @Test
-    public void testSuggest_settingsOff() {
-        mSettings.mGenerateActions = false;
-        mSettings.mGenerateReplies = false;
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        verify(mTextClassifier, never())
-                .suggestConversationActions(any(ConversationActions.Request.class));
-    }
-
-    @Test
-    public void testSuggest_settings_repliesOnActionsOff() {
-        mSettings.mGenerateReplies = true;
-        mSettings.mGenerateActions = false;
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        ConversationActions.Request request = runSuggestAndCaptureRequest();
-
-        // replies are enabled, but actions are not.
-        assertThat(
-                request.getTypeConfig().resolveEntityListModifications(
-                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
-                                ConversationAction.TYPE_OPEN_URL)))
-                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
-    }
-
-    @Test
-    public void testSuggest_settings_repliesOffActionsOn() {
-        mSettings.mGenerateReplies = false;
-        mSettings.mGenerateActions = true;
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        ConversationActions.Request request = runSuggestAndCaptureRequest();
-
-        // actions are enabled, but replies are not.
-        assertThat(
-                request.getTypeConfig().resolveEntityListModifications(
-                        Arrays.asList(ConversationAction.TYPE_TEXT_REPLY,
-                                ConversationAction.TYPE_OPEN_URL)))
-                .containsExactly(ConversationAction.TYPE_OPEN_URL);
-    }
-
-
-    @Test
-    public void testSuggest_nonMessageStyleMessageNotification() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        List<ConversationActions.Message> messages =
-                runSuggestAndCaptureRequest().getConversation();
-
-        assertThat(messages).hasSize(1);
-        MessageSubject.assertThat(messages.get(0)).hasText(MESSAGE);
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier).onTextClassifierEvent(argumentCaptor.capture());
-        TextClassifierEvent textClassifierEvent = argumentCaptor.getValue();
-        assertTextClassifierEvent(textClassifierEvent, TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertThat(textClassifierEvent.getEntityTypes()).asList()
-                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
-    }
-
-    @Test
-    public void testSuggest_messageStyle() {
-        Person me = new Person.Builder().setName("Me").build();
-        Person userA = new Person.Builder().setName("A").build();
-        Person userB = new Person.Builder().setName("B").build();
-        Notification.MessagingStyle style =
-                new Notification.MessagingStyle(me)
-                        .addMessage("firstMessage", 1000, (Person) null)
-                        .addMessage("secondMessage", 2000, me)
-                        .addMessage("thirdMessage", 3000, userA)
-                        .addMessage("fourthMessage", 4000, userB);
-        Notification notification =
-                mNotificationBuilder
-                        .setContentText("You have three new messages")
-                        .setStyle(style)
-                        .setActions(createReplyAction())
-                        .build();
-        setStatusBarNotification(notification);
-
-        List<ConversationActions.Message> messages =
-                runSuggestAndCaptureRequest().getConversation();
-        assertThat(messages).hasSize(4);
-
-        ConversationActions.Message firstMessage = messages.get(0);
-        MessageSubject.assertThat(firstMessage).hasText("firstMessage");
-        MessageSubject.assertThat(firstMessage)
-                .hasPerson(ConversationActions.Message.PERSON_USER_SELF);
-        MessageSubject.assertThat(firstMessage)
-                .hasReferenceTime(createZonedDateTimeFromMsUtc(1000));
-
-        ConversationActions.Message secondMessage = messages.get(1);
-        MessageSubject.assertThat(secondMessage).hasText("secondMessage");
-        MessageSubject.assertThat(secondMessage)
-                .hasPerson(ConversationActions.Message.PERSON_USER_SELF);
-        MessageSubject.assertThat(secondMessage)
-                .hasReferenceTime(createZonedDateTimeFromMsUtc(2000));
-
-        ConversationActions.Message thirdMessage = messages.get(2);
-        MessageSubject.assertThat(thirdMessage).hasText("thirdMessage");
-        MessageSubject.assertThat(thirdMessage).hasPerson(userA);
-        MessageSubject.assertThat(thirdMessage)
-                .hasReferenceTime(createZonedDateTimeFromMsUtc(3000));
-
-        ConversationActions.Message fourthMessage = messages.get(3);
-        MessageSubject.assertThat(fourthMessage).hasText("fourthMessage");
-        MessageSubject.assertThat(fourthMessage).hasPerson(userB);
-        MessageSubject.assertThat(fourthMessage)
-                .hasReferenceTime(createZonedDateTimeFromMsUtc(4000));
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier).onTextClassifierEvent(argumentCaptor.capture());
-        TextClassifierEvent textClassifierEvent = argumentCaptor.getValue();
-        assertTextClassifierEvent(textClassifierEvent, TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertThat(textClassifierEvent.getEntityTypes()).asList()
-                .containsExactly(ConversationAction.TYPE_TEXT_REPLY);
-    }
-
-    @Test
-    public void testSuggest_lastMessageLocalUser() {
-        Person me = new Person.Builder().setName("Me").build();
-        Person userA = new Person.Builder().setName("A").build();
-        Notification.MessagingStyle style =
-                new Notification.MessagingStyle(me)
-                        .addMessage("firstMessage", 1000, userA)
-                        .addMessage("secondMessage", 2000, me);
-        Notification notification =
-                mNotificationBuilder
-                        .setContentText("You have two new messages")
-                        .setStyle(style)
-                        .setActions(createReplyAction())
-                        .build();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        verify(mTextClassifier, never())
-                .suggestConversationActions(any(ConversationActions.Request.class));
-    }
-
-    @Test
-    public void testSuggest_messageStyle_noPerson() {
-        Person me = new Person.Builder().setName("Me").build();
-        Notification.MessagingStyle style =
-                new Notification.MessagingStyle(me).addMessage("message", 1000, (Person) null);
-        Notification notification =
-                mNotificationBuilder
-                        .setContentText("You have one new message")
-                        .setStyle(style)
-                        .setActions(createReplyAction())
-                        .build();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        verify(mTextClassifier, never())
-                .suggestConversationActions(any(ConversationActions.Request.class));
-    }
-
-    @Test
-    public void testOnSuggestedReplySent() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onSuggestedReplySent(mStatusBarNotification.getKey(), SMART_REPLY,
-                NotificationAssistantService.SOURCE_FROM_ASSISTANT);
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
-        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
-        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_SMART_ACTION);
-        float[] scores = events.get(1).getScores();
-        assertThat(scores).hasLength(1);
-        assertThat(scores[0]).isEqualTo(SCORE);
-    }
-
-    @Test
-    public void testOnSuggestedReplySent_anotherNotification() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onSuggestedReplySent(
-                "something_else", MESSAGE, NotificationAssistantService.SOURCE_FROM_ASSISTANT);
-
-        verify(mTextClassifier, never()).onTextClassifierEvent(
-                argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_SMART_ACTION)));
-    }
-
-    @Test
-    public void testOnSuggestedReplySent_missingResultId() {
-        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
-                .thenReturn(new ConversationActions(Collections.singletonList(REPLY_ACTION), null));
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onSuggestedReplySent(mStatusBarNotification.getKey(), SMART_REPLY,
-                NotificationAssistantService.SOURCE_FROM_ASSISTANT);
-
-        verify(mTextClassifier, never()).onTextClassifierEvent(any(TextClassifierEvent.class));
-    }
-
-    @Test
-    public void testOnNotificationDirectReply() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationDirectReplied(mStatusBarNotification.getKey());
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
-        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
-        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_MANUAL_REPLY);
-    }
-
-    @Test
-    public void testOnNotificationExpansionChanged() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
-        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
-        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_ACTIONS_SHOWN);
-    }
-
-    @Test
-    public void testOnNotificationsSeen_notExpanded() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false);
-
-        verify(mTextClassifier, never()).onTextClassifierEvent(
-                argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_ACTIONS_SHOWN)));
-    }
-
-    @Test
-    public void testOnNotifications_expanded() {
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-
-        mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
-
-        ArgumentCaptor<TextClassifierEvent> argumentCaptor =
-                ArgumentCaptor.forClass(TextClassifierEvent.class);
-        verify(mTextClassifier, times(2)).onTextClassifierEvent(argumentCaptor.capture());
-        List<TextClassifierEvent> events = argumentCaptor.getAllValues();
-        assertTextClassifierEvent(events.get(0), TextClassifierEvent.TYPE_ACTIONS_GENERATED);
-        assertTextClassifierEvent(events.get(1), TextClassifierEvent.TYPE_ACTIONS_SHOWN);
-    }
-
-    @Test
-    public void testCopyAction() {
-        Bundle extras = new Bundle();
-        Bundle entitiesExtras = new Bundle();
-        entitiesExtras.putString(SmartActionsHelper.KEY_TEXT, "12345");
-        extras.putParcelable(SmartActionsHelper.ENTITIES_EXTRAS, entitiesExtras);
-        ConversationAction conversationAction =
-                new ConversationAction.Builder(ConversationAction.TYPE_COPY)
-                        .setExtras(extras)
-                        .build();
-        when(mTextClassifier.suggestConversationActions(any(ConversationActions.Request.class)))
-                .thenReturn(
-                        new ConversationActions(
-                                Collections.singletonList(conversationAction), null));
-
-        Notification notification = createMessageNotification();
-        setStatusBarNotification(notification);
-        SmartActionsHelper.SmartSuggestions suggestions =
-                mSmartActionsHelper.suggest(createNotificationEntry());
-
-        assertThat(suggestions.actions).hasSize(1);
-        Notification.Action action = suggestions.actions.get(0);
-        assertThat(action.title).isEqualTo("12345");
-    }
-
-    private ZonedDateTime createZonedDateTimeFromMsUtc(long msUtc) {
-        return ZonedDateTime.ofInstant(Instant.ofEpochMilli(msUtc), ZoneOffset.systemDefault());
-    }
-
-    private ConversationActions.Request runSuggestAndCaptureRequest() {
-        mSmartActionsHelper.suggest(createNotificationEntry());
-
-        ArgumentCaptor<ConversationActions.Request> argumentCaptor =
-                ArgumentCaptor.forClass(ConversationActions.Request.class);
-        verify(mTextClassifier).suggestConversationActions(argumentCaptor.capture());
-        return argumentCaptor.getValue();
-    }
-
-    private Notification.Action createReplyAction() {
-        PendingIntent pendingIntent =
-                PendingIntent.getActivity(mContext, 0, new Intent(mContext, this.getClass()), 0);
-        RemoteInput remoteInput = new RemoteInput.Builder("result")
-                .setAllowFreeFormInput(true)
-                .build();
-        return new Notification.Action.Builder(
-                Icon.createWithResource(mContext.getResources(),
-                        android.R.drawable.stat_sys_warning),
-                "Reply", pendingIntent)
-                .addRemoteInput(remoteInput)
-                .build();
-    }
-
-    private NotificationEntry createNotificationEntry() {
-        NotificationChannel channel =
-                new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
-        return new NotificationEntry(
-                mContext, mIPackageManager, mStatusBarNotification, channel, mSmsHelper);
-    }
-
-    private Notification createMessageNotification() {
-        return mNotificationBuilder
-                .setContentText(MESSAGE)
-                .setCategory(Notification.CATEGORY_MESSAGE)
-                .setActions(createReplyAction())
-                .build();
-    }
-
-    private void assertTextClassifierEvent(
-            TextClassifierEvent textClassifierEvent, int expectedEventType) {
-        assertThat(textClassifierEvent.getEventCategory())
-                .isEqualTo(TextClassifierEvent.CATEGORY_CONVERSATION_ACTIONS);
-        assertThat(textClassifierEvent.getEventContext().getPackageName())
-                .isEqualTo(InstrumentationRegistry.getTargetContext().getPackageName());
-        assertThat(textClassifierEvent.getEventContext().getWidgetType())
-                .isEqualTo(TextClassifier.WIDGET_TYPE_NOTIFICATION);
-        assertThat(textClassifierEvent.getEventType()).isEqualTo(expectedEventType);
-    }
-
-    private static final class MessageSubject
-            extends Subject<MessageSubject, ConversationActions.Message> {
-
-        private static final Subject.Factory<MessageSubject, ConversationActions.Message> FACTORY =
-                new Subject.Factory<MessageSubject, ConversationActions.Message>() {
-                    @Override
-                    public MessageSubject createSubject(
-                            @NonNull FailureMetadata failureMetadata,
-                            @NonNull ConversationActions.Message subject) {
-                        return new MessageSubject(failureMetadata, subject);
-                    }
-                };
-
-        private MessageSubject(
-                FailureMetadata failureMetadata, @Nullable ConversationActions.Message subject) {
-            super(failureMetadata, subject);
-        }
-
-        private void hasText(String text) {
-            if (!Objects.equals(text, getSubject().getText().toString())) {
-                failWithBadResults("has text", text, "has", getSubject().getText());
-            }
-        }
-
-        private void hasPerson(Person person) {
-            if (!Objects.equals(person, getSubject().getAuthor())) {
-                failWithBadResults("has author", person, "has", getSubject().getAuthor());
-            }
-        }
-
-        private void hasReferenceTime(ZonedDateTime referenceTime) {
-            if (!Objects.equals(referenceTime, getSubject().getReferenceTime())) {
-                failWithBadResults(
-                        "has reference time",
-                        referenceTime,
-                        "has",
-                        getSubject().getReferenceTime());
-            }
-        }
-
-        private static MessageSubject assertThat(ConversationActions.Message message) {
-            return assertAbout(FACTORY).that(message);
-        }
-    }
-
-    private final class TextClassifierEventMatcher implements ArgumentMatcher<TextClassifierEvent> {
-
-        private int mType;
-
-        private TextClassifierEventMatcher(int type) {
-            mType = type;
-        }
-
-        @Override
-        public boolean matches(TextClassifierEvent textClassifierEvent) {
-            if (textClassifierEvent == null) {
-                return false;
-            }
-            return mType == textClassifierEvent.getEventType();
-        }
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java
deleted file mode 100644
index 12575a6..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/sms/FinancialSmsServiceImplTest.java
+++ /dev/null
@@ -1,35 +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.ext.services.sms;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Bundle;
-
-import org.junit.Test;
-
-/**
- * Contains the base tests for FinancialSmsServiceImpl.
- */
-public class FinancialSmsServiceImplTest {
-
-    private final FinancialSmsServiceImpl mService = new FinancialSmsServiceImpl();
-
-    @Test
-    public void testOnGetSmsMessages_nullWithNoParamData() {
-        assertThat(mService.onGetSmsMessages(new Bundle())).isNull();
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
deleted file mode 100644
index df4738f..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.ext.services.storage;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-
-import android.app.usage.CacheQuotaHint;
-import android.app.usage.UsageStats;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.os.storage.StorageManager;
-import android.os.storage.VolumeInfo;
-import android.test.ServiceTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-public class CacheQuotaServiceImplTest extends ServiceTestCase<CacheQuotaServiceImpl> {
-    private static final String sTestVolUuid = "uuid";
-    private static final String sSecondTestVolUuid = "otherUuid";
-
-    @Mock private Context mContext;
-    @Mock private File mFile;
-    @Mock private VolumeInfo mVolume;
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS) private StorageManager mStorageManager;
-
-    public CacheQuotaServiceImplTest() {
-        super(CacheQuotaServiceImpl.class);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        MockitoAnnotations.initMocks(this);
-        mContext = Mockito.spy(new ContextWrapper(getSystemContext()));
-        setContext(mContext);
-        when(mContext.getSystemService(Context.STORAGE_SERVICE)).thenReturn(mStorageManager);
-
-        when(mFile.getUsableSpace()).thenReturn(10000L);
-        when(mVolume.getPath()).thenReturn(mFile);
-        when(mStorageManager.findVolumeByUuid(sTestVolUuid)).thenReturn(mVolume);
-        when(mStorageManager.findVolumeByUuid(sSecondTestVolUuid)).thenReturn(mVolume);
-
-        Intent intent = new Intent(getContext(), CacheQuotaServiceImpl.class);
-        startService(intent);
-    }
-
-    @Test
-    public void testNoApps() {
-        CacheQuotaServiceImpl service = getService();
-        assertEquals(service.onComputeCacheQuotaHints(new ArrayList()).size(), 0);
-    }
-
-    @Test
-    public void testOneApp() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        CacheQuotaHint request = makeNewRequest("com.test", sTestVolUuid, 1001, 100L);
-        requests.add(request);
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(1);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500L);
-    }
-
-    @Test
-    public void testTwoAppsOneVolume() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sTestVolUuid, 1002, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        // Note that the sizes are just the cache area split up.
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(883);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500 - 883);
-    }
-
-    @Test
-    public void testTwoAppsTwoVolumes() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sSecondTestVolUuid, 1002, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500);
-    }
-
-    @Test
-    public void testMultipleAppsPerUidIsCollated() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sTestVolUuid, 1001, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(1);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-    }
-
-    @Test
-    public void testTwoAppsTwoVolumesTwoUuidsShouldBESeparate() throws Exception {
-        ArrayList<CacheQuotaHint> requests = new ArrayList<>();
-        requests.add(makeNewRequest("com.test", sTestVolUuid, 1001, 100L));
-        requests.add(makeNewRequest("com.test2", sSecondTestVolUuid, 1001, 99L));
-
-        List<CacheQuotaHint> output = getService().onComputeCacheQuotaHints(requests);
-
-        assertThat(output).hasSize(2);
-        assertThat(output.get(0).getQuota()).isEqualTo(1500);
-        assertThat(output.get(1).getQuota()).isEqualTo(1500);
-    }
-
-    private CacheQuotaHint makeNewRequest(String packageName, String uuid, int uid, long foregroundTime) {
-        UsageStats stats = new UsageStats();
-        stats.mPackageName = packageName;
-        stats.mTotalTimeInForeground = foregroundTime;
-        return new CacheQuotaHint.Builder()
-                .setVolumeUuid(uuid).setUid(uid).setUsageStats(stats).setQuota(-1).build();
-    }
-}
diff --git a/packages/ExtServices/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java
deleted file mode 100644
index a9cb63e..0000000
--- a/packages/ExtServices/tests/src/android/ext/services/watchdog/ExplicitHealthCheckServiceImplTest.java
+++ /dev/null
@@ -1,201 +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.ext.services.watchdog;
-
-import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
-import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
-import static android.service.watchdog.ExplicitHealthCheckService.PackageConfig;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeFalse;
-
-import android.Manifest;
-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.ServiceInfo;
-import android.os.RemoteCallback;
-import android.service.watchdog.ExplicitHealthCheckService;
-import android.service.watchdog.IExplicitHealthCheckService;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ServiceTestRule;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Contains the base tests that does not rely on the specific algorithm implementation.
- */
-public class ExplicitHealthCheckServiceImplTest {
-    private static final String NETWORK_STACK_CONNECTOR_CLASS =
-            "android.net.INetworkStackConnector";
-
-    private final Context mContext = InstrumentationRegistry.getContext();
-    private IExplicitHealthCheckService mService;
-    private String mNetworkStackPackageName;
-
-    @Rule
-    public ServiceTestRule mServiceTestRule;
-
-    @Before
-    public void setUp() throws Exception {
-        InstrumentationRegistry
-                .getInstrumentation()
-                .getUiAutomation()
-                .adoptShellPermissionIdentity(
-                        Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE);
-
-        mServiceTestRule = new ServiceTestRule();
-        mService = IExplicitHealthCheckService.Stub.asInterface(
-                mServiceTestRule.bindService(getExtServiceIntent()));
-        mNetworkStackPackageName = getNetworkStackPackage();
-        assumeFalse(mNetworkStackPackageName == null);
-    }
-
-    @After
-    public void tearDown() {
-        InstrumentationRegistry
-                .getInstrumentation()
-                .getUiAutomation()
-                .dropShellPermissionIdentity();
-    }
-
-    @Test
-    public void testHealthCheckSupportedPackage() throws Exception {
-        List<PackageConfig> supportedPackages = new ArrayList<>();
-        CountDownLatch latch = new CountDownLatch(1);
-
-        mService.getSupportedPackages(new RemoteCallback(result -> {
-            supportedPackages.addAll(result.getParcelableArrayList(EXTRA_SUPPORTED_PACKAGES));
-            latch.countDown();
-        }));
-        latch.await();
-
-        // TODO: Support DeviceConfig changes for the health check timeout
-        assertThat(supportedPackages).hasSize(1);
-        assertThat(supportedPackages.get(0).getPackageName())
-                .isEqualTo(mNetworkStackPackageName);
-        assertThat(supportedPackages.get(0).getHealthCheckTimeoutMillis())
-                .isEqualTo(ExplicitHealthCheckServiceImpl.DEFAULT_REQUEST_TIMEOUT_MILLIS);
-    }
-
-    @Test
-    public void testHealthCheckRequests() throws Exception {
-        List<String> requestedPackages = new ArrayList<>();
-        CountDownLatch latch1 = new CountDownLatch(1);
-        CountDownLatch latch2 = new CountDownLatch(1);
-        CountDownLatch latch3 = new CountDownLatch(1);
-
-        // Initially, no health checks requested
-        mService.getRequestedPackages(new RemoteCallback(result -> {
-            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
-            latch1.countDown();
-        }));
-
-        // Verify that no health checks requested
-        latch1.await();
-        assertThat(requestedPackages).isEmpty();
-
-        // Then request health check
-        mService.request(mNetworkStackPackageName);
-
-        // Verify that health check is requested for network stack
-        mService.getRequestedPackages(new RemoteCallback(result -> {
-            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
-            latch2.countDown();
-        }));
-        latch2.await();
-        assertThat(requestedPackages).hasSize(1);
-        assertThat(requestedPackages.get(0)).isEqualTo(mNetworkStackPackageName);
-
-        // Then cancel health check
-        requestedPackages.clear();
-        mService.cancel(mNetworkStackPackageName);
-
-        // Verify that health check is cancelled for network stack
-        mService.getRequestedPackages(new RemoteCallback(result -> {
-            requestedPackages.addAll(result.getParcelableArrayList(EXTRA_REQUESTED_PACKAGES));
-            latch3.countDown();
-        }));
-        latch3.await();
-        assertThat(requestedPackages).isEmpty();
-    }
-
-    private String getNetworkStackPackage() {
-        Intent intent = new Intent(NETWORK_STACK_CONNECTOR_CLASS);
-        ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
-        if (comp != null) {
-            return comp.getPackageName();
-        } 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.
-            return null;
-        }
-    }
-
-    private Intent getExtServiceIntent() {
-        ComponentName component = getExtServiceComponentNameLocked();
-        if (component == null) {
-            fail("Health check service not found");
-        }
-        Intent intent = new Intent();
-        intent.setComponent(component);
-        return intent;
-    }
-
-    private ComponentName getExtServiceComponentNameLocked() {
-        ServiceInfo serviceInfo = getExtServiceInfoLocked();
-        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)) {
-            return null;
-        }
-        return name;
-    }
-
-    private ServiceInfo getExtServiceInfoLocked() {
-        final String packageName =
-                mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
-        if (packageName == null) {
-            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) {
-            return null;
-        }
-        return resolveInfo.serviceInfo;
-    }
-}
diff --git a/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml b/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
index 96046ad..35de8ef 100644
--- a/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
@@ -19,5 +19,5 @@
     <string name="app_label" msgid="7123375275748530234">"Armazenamento externo"</string>
     <string name="storage_description" msgid="8541974407321172792">"Armazenamento local"</string>
     <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Docs"</string>
 </resources>
diff --git a/packages/InputDevices/res/values-hy/strings.xml b/packages/InputDevices/res/values-hy/strings.xml
index c7523e3..64ddf7a 100644
--- a/packages/InputDevices/res/values-hy/strings.xml
+++ b/packages/InputDevices/res/values-hy/strings.xml
@@ -40,7 +40,7 @@
     <string name="keyboard_layout_hebrew" msgid="7241473985890173812">"Եբրայերեն"</string>
     <string name="keyboard_layout_lithuanian" msgid="6943110873053106534">"Լիտվերեն"</string>
     <string name="keyboard_layout_spanish_latin" msgid="5690539836069535697">"Իսպաներեն (Լատինական)"</string>
-    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"լատիշերեն"</string>
+    <string name="keyboard_layout_latvian" msgid="4405417142306250595">"լատվիերեն"</string>
     <string name="keyboard_layout_persian" msgid="3920643161015888527">"պարսկերեն"</string>
     <string name="keyboard_layout_azerbaijani" msgid="7315895417176467567">"ադրբեջաներեն"</string>
     <string name="keyboard_layout_polish" msgid="1121588624094925325">"լեհերեն"</string>
diff --git a/packages/NetworkPermissionConfig/Android.bp b/packages/NetworkPermissionConfig/Android.bp
deleted file mode 100644
index 6e50459..0000000
--- a/packages/NetworkPermissionConfig/Android.bp
+++ /dev/null
@@ -1,41 +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.
-//
-
-java_defaults {
-    name: "NetworkPermissionConfigDefaults",
-    // TODO: mark app as hasCode=false in manifest once soong stops complaining about apps without
-    // a classes.dex.
-    srcs: ["src/**/*.java"],
-    platform_apis: true,
-    min_sdk_version: "28",
-    privileged: true,
-    manifest: "AndroidManifest.xml",
-}
-
-// Stub APK to define permissions for NetworkStack
-android_app {
-    name: "NetworkPermissionConfig",
-    defaults: ["NetworkPermissionConfigDefaults"],
-    certificate: "networkstack",
-}
-
-// Alternative stub APK signed with platform certificate. To use with InProcessNetworkStack.
-android_app {
-    name: "PlatformNetworkPermissionConfig",
-    defaults: ["NetworkPermissionConfigDefaults"],
-    certificate: "platform",
-    overrides: ["NetworkPermissionConfig"],
-}
diff --git a/packages/NetworkPermissionConfig/AndroidManifest.xml b/packages/NetworkPermissionConfig/AndroidManifest.xml
deleted file mode 100644
index 496fa4d..0000000
--- a/packages/NetworkPermissionConfig/AndroidManifest.xml
+++ /dev/null
@@ -1,40 +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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.networkstack.permissionconfig"
-    android:sharedUserId="android.uid.networkstack"
-    android:versionCode="210000000"
-    android:versionName="Q-initial">
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <!--
-    This package only exists to define the below permissions, and enforce that they are only
-    granted to apps sharing the same signature.
-    Permissions defined here are intended to be used only by the NetworkStack: both
-    NetworkStack and this stub APK are to be signed with a dedicated certificate to ensure
-    that, with the below permissions being signature permissions.
-
-    This APK *must* be installed, even if the NetworkStack app is not installed, because otherwise,
-    any application will be able to define this permission and the system will give that application
-    full access to the network stack.
-     -->
-    <permission android:name="android.permission.MAINLINE_NETWORK_STACK"
-                android:protectionLevel="signature"/>
-
-    <application android:name="com.android.server.NetworkPermissionConfig"/>
-</manifest>
diff --git a/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java b/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
deleted file mode 100644
index c904e23..0000000
--- a/packages/NetworkPermissionConfig/src/com/android/server/NetworkPermissionConfig.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.app.Application;
-
-/**
- * Empty application for NetworkPermissionConfig that only exists because
- * soong builds complain if APKs have no source file.
- */
-public class NetworkPermissionConfig extends Application {
-}
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
deleted file mode 100644
index c013b8c..0000000
--- a/packages/NetworkStack/Android.bp
+++ /dev/null
@@ -1,134 +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.
-//
-
-java_library {
-    name: "captiveportal-lib",
-    srcs: ["common/**/*.java"],
-    libs: [
-        "androidx.annotation_annotation",
-    ],
-    sdk_version: "system_current",
-}
-
-java_defaults {
-    name: "NetworkStackCommon",
-    sdk_version: "system_current",
-    min_sdk_version: "28",
-}
-
-// Library including the network stack, used to compile both variants of the network stack
-android_library {
-    name: "NetworkStackBase",
-    defaults: ["NetworkStackCommon"],
-    srcs: [
-        "src/**/*.java",
-        ":framework-networkstack-shared-srcs",
-        ":services-networkstack-shared-srcs",
-        ":statslog-networkstack-java-gen",
-    ],
-    static_libs: [
-        "androidx.annotation_annotation",
-        "ipmemorystore-client",
-        "netd_aidl_interface-V2-java",
-        "networkstack-aidl-interfaces-V3-java",
-        "datastallprotosnano",
-        "networkstackprotosnano",
-        "captiveportal-lib",
-    ],
-    manifest: "AndroidManifestBase.xml",
-}
-
-cc_library_shared {
-    name: "libnetworkstackutilsjni",
-    srcs: [
-        "jni/network_stack_utils_jni.cpp"
-    ],
-    sdk_version: "current",
-    shared_libs: [
-        "liblog",
-        "libnativehelper_compat_libc++",
-    ],
-
-    // We cannot use plain "libc++" here to link libc++ dynamically because it results in:
-    //   java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
-    // even if "libc++" is added into jni_libs below. Adding "libc++_shared" into jni_libs doesn't
-    // build because soong complains of:
-    //   module NetworkStack missing dependencies: libc++_shared
-    //
-    // So, link libc++ statically. This means that we also need to ensure that all the C++ libraries
-    // we depend on do not dynamically link libc++. This is currently the case, because liblog is
-    // C-only and libnativehelper_compat_libc also uses stl: "c++_static".
-    //
-    // TODO: find a better solution for this in R.
-    stl: "c++_static",
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-unused-parameter",
-    ],
-}
-
-java_defaults {
-    name: "NetworkStackAppCommon",
-    defaults: ["NetworkStackCommon"],
-    privileged: true,
-    static_libs: [
-        "NetworkStackBase",
-    ],
-    jni_libs: [
-        "libnativehelper_compat_libc++",
-        "libnetworkstackutilsjni",
-    ],
-    // Resources already included in NetworkStackBase
-    resource_dirs: [],
-    jarjar_rules: "jarjar-rules-shared.txt",
-    optimize: {
-        proguard_flags_files: ["proguard.flags"],
-    },
-}
-
-// Non-updatable network stack running in the system server process for devices not using the module
-android_app {
-    name: "InProcessNetworkStack",
-    defaults: ["NetworkStackAppCommon"],
-    certificate: "platform",
-    manifest: "AndroidManifest_InProcess.xml",
-    // InProcessNetworkStack is a replacement for NetworkStack
-    overrides: ["NetworkStack"],
-    // The permission configuration *must* be included to ensure security of the device
-    // The InProcessNetworkStack goes together with the PlatformCaptivePortalLogin, which replaces
-    // the default CaptivePortalLogin.
-    required: ["PlatformNetworkPermissionConfig", "PlatformCaptivePortalLogin"],
-}
-
-// Updatable network stack packaged as an application
-android_app {
-    name: "NetworkStack",
-    defaults: ["NetworkStackAppCommon"],
-    certificate: "networkstack",
-    manifest: "AndroidManifest.xml",
-    use_embedded_native_libs: true,
-    // The permission configuration *must* be included to ensure security of the device
-    required: ["NetworkPermissionConfig"],
-}
-
-genrule {
-    name: "statslog-networkstack-java-gen",
-    tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --java $(out) --module network_stack" +
-         " --javaPackage com.android.networkstack.metrics --javaClass NetworkStackStatsLog",
-    out: ["com/android/networkstack/metrics/NetworkStackStatsLog.java"],
-}
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
deleted file mode 100644
index 6166c66..0000000
--- a/packages/NetworkStack/AndroidManifest.xml
+++ /dev/null
@@ -1,56 +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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-  package="com.android.networkstack"
-  android:sharedUserId="android.uid.networkstack"
-  android:versionCode="220000000"
-  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
-        android:extractNativeLibs="false"
-        android:persistent="true">
-        <service android:name="com.android.server.NetworkStackService">
-            <intent-filter>
-                <action android:name="android.net.INetworkStackConnector"/>
-            </intent-filter>
-        </service>
-        <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
-                 android:permission="android.permission.BIND_JOB_SERVICE" >
-        </service>
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/AndroidManifestBase.xml b/packages/NetworkStack/AndroidManifestBase.xml
deleted file mode 100644
index 69a4da4..0000000
--- a/packages/NetworkStack/AndroidManifestBase.xml
+++ /dev/null
@@ -1,29 +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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.networkstack"
-          android:versionCode="11"
-          android:versionName="Q-initial">
-    <application
-        android:label="NetworkStack"
-        android:defaultToDeviceProtectedStorage="true"
-        android:directBootAware="true"
-        android:usesCleartextTraffic="true">
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/AndroidManifest_InProcess.xml b/packages/NetworkStack/AndroidManifest_InProcess.xml
deleted file mode 100644
index 2778a2a..0000000
--- a/packages/NetworkStack/AndroidManifest_InProcess.xml
+++ /dev/null
@@ -1,35 +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.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.networkstack.inprocess"
-          android:sharedUserId="android.uid.system"
-          android:process="system">
-    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
-    <application>
-        <service android:name="com.android.server.NetworkStackService" android:process="system">
-            <intent-filter>
-                <action android:name="android.net.INetworkStackConnector.InProcess"/>
-            </intent-filter>
-        </service>
-        <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
-                 android:process="system"
-                 android:permission="android.permission.BIND_JOB_SERVICE" >
-        </service>
-    </application>
-</manifest>
diff --git a/packages/NetworkStack/OWNERS b/packages/NetworkStack/OWNERS
deleted file mode 100644
index 0e1e65d..0000000
--- a/packages/NetworkStack/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-codewiz@google.com
-jchalard@google.com
-junyulai@google.com
-lorenzo@google.com
-reminv@google.com
-satk@google.com
diff --git a/packages/NetworkStack/TEST_MAPPING b/packages/NetworkStack/TEST_MAPPING
deleted file mode 100644
index fe9731fe..0000000
--- a/packages/NetworkStack/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "NetworkStackTests"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/NetworkStack/common/CaptivePortalProbeResult.java b/packages/NetworkStack/common/CaptivePortalProbeResult.java
deleted file mode 100644
index 48cd48b..0000000
--- a/packages/NetworkStack/common/CaptivePortalProbeResult.java
+++ /dev/null
@@ -1,88 +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.net.captiveportal;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Result of calling isCaptivePortal().
- * @hide
- */
-public final class CaptivePortalProbeResult {
-    public static final int SUCCESS_CODE = 204;
-    public static final int FAILED_CODE = 599;
-    public static final int PORTAL_CODE = 302;
-    // Set partial connectivity http response code to -1 to prevent conflict with the other http
-    // response codes. Besides the default http response code of probe result is set as 599 in
-    // NetworkMonitor#sendParallelHttpProbes(), so response code will be set as -1 only when
-    // NetworkMonitor detects partial connectivity.
-    /**
-     * @hide
-     */
-    public static final int PARTIAL_CODE = -1;
-
-    @NonNull
-    public static final CaptivePortalProbeResult FAILED = new CaptivePortalProbeResult(FAILED_CODE);
-    @NonNull
-    public static final CaptivePortalProbeResult SUCCESS =
-            new CaptivePortalProbeResult(SUCCESS_CODE);
-    public static final CaptivePortalProbeResult PARTIAL =
-            new CaptivePortalProbeResult(PARTIAL_CODE);
-
-    private final int mHttpResponseCode;  // HTTP response code returned from Internet probe.
-    @Nullable
-    public final String redirectUrl;      // Redirect destination returned from Internet probe.
-    @Nullable
-    public final String detectUrl;        // URL where a 204 response code indicates
-                                          // captive portal has been appeased.
-    @Nullable
-    public final CaptivePortalProbeSpec probeSpec;
-
-    public CaptivePortalProbeResult(int httpResponseCode) {
-        this(httpResponseCode, null, null);
-    }
-
-    public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
-            @Nullable String detectUrl) {
-        this(httpResponseCode, redirectUrl, detectUrl, null);
-    }
-
-    public CaptivePortalProbeResult(int httpResponseCode, @Nullable String redirectUrl,
-            @Nullable String detectUrl, @Nullable CaptivePortalProbeSpec probeSpec) {
-        mHttpResponseCode = httpResponseCode;
-        this.redirectUrl = redirectUrl;
-        this.detectUrl = detectUrl;
-        this.probeSpec = probeSpec;
-    }
-
-    public boolean isSuccessful() {
-        return mHttpResponseCode == SUCCESS_CODE;
-    }
-
-    public boolean isPortal() {
-        return !isSuccessful() && (mHttpResponseCode >= 200) && (mHttpResponseCode <= 399);
-    }
-
-    public boolean isFailed() {
-        return !isSuccessful() && !isPortal();
-    }
-
-    public boolean isPartialConnectivity() {
-        return mHttpResponseCode == PARTIAL_CODE;
-    }
-}
diff --git a/packages/NetworkStack/common/CaptivePortalProbeSpec.java b/packages/NetworkStack/common/CaptivePortalProbeSpec.java
deleted file mode 100644
index bf983a5..0000000
--- a/packages/NetworkStack/common/CaptivePortalProbeSpec.java
+++ /dev/null
@@ -1,195 +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.net.captiveportal;
-
-import static android.net.captiveportal.CaptivePortalProbeResult.PORTAL_CODE;
-import static android.net.captiveportal.CaptivePortalProbeResult.SUCCESS_CODE;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-/** @hide */
-public abstract class CaptivePortalProbeSpec {
-    private static final String TAG = CaptivePortalProbeSpec.class.getSimpleName();
-    private static final String REGEX_SEPARATOR = "@@/@@";
-    private static final String SPEC_SEPARATOR = "@@,@@";
-
-    private final String mEncodedSpec;
-    private final URL mUrl;
-
-    CaptivePortalProbeSpec(@NonNull String encodedSpec, @NonNull URL url) {
-        mEncodedSpec = checkNotNull(encodedSpec);
-        mUrl = checkNotNull(url);
-    }
-
-    /**
-     * Parse a {@link CaptivePortalProbeSpec} from a {@link String}.
-     *
-     * <p>The valid format is a URL followed by two regular expressions, each separated by "@@/@@".
-     * @throws MalformedURLException The URL has invalid format for {@link URL#URL(String)}.
-     * @throws ParseException The string is empty, does not match the above format, or a regular
-     * expression is invalid for {@link Pattern#compile(String)}.
-     * @hide
-     */
-    @VisibleForTesting
-    @NonNull
-    public static CaptivePortalProbeSpec parseSpec(@NonNull String spec) throws ParseException,
-            MalformedURLException {
-        if (TextUtils.isEmpty(spec)) {
-            throw new ParseException("Empty probe spec", 0 /* errorOffset */);
-        }
-
-        String[] splits = TextUtils.split(spec, REGEX_SEPARATOR);
-        if (splits.length != 3) {
-            throw new ParseException("Probe spec does not have 3 parts", 0 /* errorOffset */);
-        }
-
-        final int statusRegexPos = splits[0].length() + REGEX_SEPARATOR.length();
-        final int locationRegexPos = statusRegexPos + splits[1].length() + REGEX_SEPARATOR.length();
-        final Pattern statusRegex = parsePatternIfNonEmpty(splits[1], statusRegexPos);
-        final Pattern locationRegex = parsePatternIfNonEmpty(splits[2], locationRegexPos);
-
-        return new RegexMatchProbeSpec(spec, new URL(splits[0]), statusRegex, locationRegex);
-    }
-
-    @Nullable
-    private static Pattern parsePatternIfNonEmpty(@Nullable String pattern, int pos)
-            throws ParseException {
-        if (TextUtils.isEmpty(pattern)) {
-            return null;
-        }
-        try {
-            return Pattern.compile(pattern);
-        } catch (PatternSyntaxException e) {
-            throw new ParseException(
-                    String.format("Invalid status pattern [%s]: %s", pattern, e),
-                    pos /* errorOffset */);
-        }
-    }
-
-    /**
-     * Parse a {@link CaptivePortalProbeSpec} from a {@link String}, or return a fallback spec
-     * based on the status code of the provided URL if the spec cannot be parsed.
-     */
-    @Nullable
-    public static CaptivePortalProbeSpec parseSpecOrNull(@Nullable String spec) {
-        if (spec != null) {
-            try {
-                return parseSpec(spec);
-            } catch (ParseException | MalformedURLException e) {
-                Log.e(TAG, "Invalid probe spec: " + spec, e);
-                // Fall through
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Parse a config String to build an array of {@link CaptivePortalProbeSpec}.
-     *
-     * <p>Each spec is separated by @@,@@ and follows the format for {@link #parseSpec(String)}.
-     * <p>This method does not throw but ignores any entry that could not be parsed.
-     */
-    @NonNull
-    public static Collection<CaptivePortalProbeSpec> parseCaptivePortalProbeSpecs(
-            @NonNull String settingsVal) {
-        List<CaptivePortalProbeSpec> specs = new ArrayList<>();
-        if (settingsVal != null) {
-            for (String spec : TextUtils.split(settingsVal, SPEC_SEPARATOR)) {
-                try {
-                    specs.add(parseSpec(spec));
-                } catch (ParseException | MalformedURLException e) {
-                    Log.e(TAG, "Invalid probe spec: " + spec, e);
-                }
-            }
-        }
-
-        if (specs.isEmpty()) {
-            Log.e(TAG, String.format("could not create any validation spec from %s", settingsVal));
-        }
-        return specs;
-    }
-
-    /**
-     * Get the probe result from HTTP status and location header.
-     */
-    @NonNull
-    public abstract CaptivePortalProbeResult getResult(int status, @Nullable String locationHeader);
-
-    @NonNull
-    public String getEncodedSpec() {
-        return mEncodedSpec;
-    }
-
-    @NonNull
-    public URL getUrl() {
-        return mUrl;
-    }
-
-    /**
-     * Implementation of {@link CaptivePortalProbeSpec} that is based on configurable regular
-     * expressions for the HTTP status code and location header (if any). Matches indicate that
-     * the page is not a portal.
-     * This probe cannot fail: it always returns SUCCESS_CODE or PORTAL_CODE
-     */
-    private static class RegexMatchProbeSpec extends CaptivePortalProbeSpec {
-        @Nullable
-        final Pattern mStatusRegex;
-        @Nullable
-        final Pattern mLocationHeaderRegex;
-
-        RegexMatchProbeSpec(
-                String spec, URL url, Pattern statusRegex, Pattern locationHeaderRegex) {
-            super(spec, url);
-            mStatusRegex = statusRegex;
-            mLocationHeaderRegex = locationHeaderRegex;
-        }
-
-        @Override
-        public CaptivePortalProbeResult getResult(int status, String locationHeader) {
-            final boolean statusMatch = safeMatch(String.valueOf(status), mStatusRegex);
-            final boolean locationMatch = safeMatch(locationHeader, mLocationHeaderRegex);
-            final int returnCode = statusMatch && locationMatch ? SUCCESS_CODE : PORTAL_CODE;
-            return new CaptivePortalProbeResult(
-                    returnCode, locationHeader, getUrl().toString(), this);
-        }
-    }
-
-    private static boolean safeMatch(@Nullable String value, @Nullable Pattern pattern) {
-        // 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/jarjar-rules-shared.txt b/packages/NetworkStack/jarjar-rules-shared.txt
deleted file mode 100644
index 7346b1a..0000000
--- a/packages/NetworkStack/jarjar-rules-shared.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-rule com.android.internal.util.** android.net.networkstack.util.@1
-
-rule android.net.shared.Inet4AddressUtils* android.net.networkstack.shared.Inet4AddressUtils@1
-rule android.net.shared.InetAddressUtils* android.net.networkstack.shared.InetAddressUtils@1
-
-# Ignore DhcpResultsParcelable, but jarjar DhcpResults
-# TODO: move DhcpResults into services.net and delete from here
-rule android.net.DhcpResultsParcelable* @0
-rule android.net.DhcpResults* android.net.networkstack.DhcpResults@1
-rule android.net.LocalLog* android.net.networkstack.LocalLog@1
diff --git a/packages/NetworkStack/jni/network_stack_utils_jni.cpp b/packages/NetworkStack/jni/network_stack_utils_jni.cpp
deleted file mode 100644
index f2ba575..0000000
--- a/packages/NetworkStack/jni/network_stack_utils_jni.cpp
+++ /dev/null
@@ -1,264 +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.
- */
-
-#define LOG_TAG "NetworkStackUtils-JNI"
-
-#include <errno.h>
-#include <jni.h>
-#include <linux/filter.h>
-#include <linux/if_arp.h>
-#include <net/if.h>
-#include <netinet/ether.h>
-#include <netinet/icmp6.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/udp.h>
-#include <stdlib.h>
-
-#include <string>
-
-#include <nativehelper/JNIHelp.h>
-#include <android/log.h>
-
-namespace android {
-constexpr const char NETWORKSTACKUTILS_PKG_NAME[] = "android/net/util/NetworkStackUtils";
-
-static const uint32_t kEtherTypeOffset = offsetof(ether_header, ether_type);
-static const uint32_t kEtherHeaderLen = sizeof(ether_header);
-static const uint32_t kIPv4Protocol = kEtherHeaderLen + offsetof(iphdr, protocol);
-static const uint32_t kIPv4FlagsOffset = kEtherHeaderLen + offsetof(iphdr, frag_off);
-static const uint32_t kIPv6NextHeader = kEtherHeaderLen + offsetof(ip6_hdr, ip6_nxt);
-static const uint32_t kIPv6PayloadStart = kEtherHeaderLen + sizeof(ip6_hdr);
-static const uint32_t kICMPv6TypeOffset = kIPv6PayloadStart + offsetof(icmp6_hdr, icmp6_type);
-static const uint32_t kUDPSrcPortIndirectOffset = kEtherHeaderLen + offsetof(udphdr, source);
-static const uint32_t kUDPDstPortIndirectOffset = kEtherHeaderLen + offsetof(udphdr, dest);
-static const uint16_t kDhcpClientPort = 68;
-
-static bool checkLenAndCopy(JNIEnv* env, const jbyteArray& addr, int len, void* dst) {
-    if (env->GetArrayLength(addr) != len) {
-        return false;
-    }
-    env->GetByteArrayRegion(addr, 0, len, reinterpret_cast<jbyte*>(dst));
-    return true;
-}
-
-static void network_stack_utils_addArpEntry(JNIEnv *env, jobject thiz, jbyteArray ethAddr,
-        jbyteArray ipv4Addr, jstring ifname, jobject javaFd) {
-    arpreq req = {};
-    sockaddr_in& netAddrStruct = *reinterpret_cast<sockaddr_in*>(&req.arp_pa);
-    sockaddr& ethAddrStruct = req.arp_ha;
-
-    ethAddrStruct.sa_family = ARPHRD_ETHER;
-    if (!checkLenAndCopy(env, ethAddr, ETH_ALEN, ethAddrStruct.sa_data)) {
-        jniThrowException(env, "java/io/IOException", "Invalid ethAddr length");
-        return;
-    }
-
-    netAddrStruct.sin_family = AF_INET;
-    if (!checkLenAndCopy(env, ipv4Addr, sizeof(in_addr), &netAddrStruct.sin_addr)) {
-        jniThrowException(env, "java/io/IOException", "Invalid ipv4Addr length");
-        return;
-    }
-
-    int ifLen = env->GetStringLength(ifname);
-    // IFNAMSIZ includes the terminating NULL character
-    if (ifLen >= IFNAMSIZ) {
-        jniThrowException(env, "java/io/IOException", "ifname too long");
-        return;
-    }
-    env->GetStringUTFRegion(ifname, 0, ifLen, req.arp_dev);
-
-    req.arp_flags = ATF_COM;  // Completed entry (ha valid)
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (fd < 0) {
-        jniThrowExceptionFmt(env, "java/io/IOException", "Invalid file descriptor");
-        return;
-    }
-    // See also: man 7 arp
-    if (ioctl(fd, SIOCSARP, &req)) {
-        jniThrowExceptionFmt(env, "java/io/IOException", "ioctl error: %s", strerror(errno));
-        return;
-    }
-}
-
-static void network_stack_utils_attachDhcpFilter(JNIEnv *env, jobject clazz, jobject javaFd) {
-    static sock_filter filter_code[] = {
-        // Check the protocol is UDP.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv4Protocol),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_UDP, 0, 6),
-
-        // Check this is not a fragment.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS, kIPv4FlagsOffset),
-        BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K,   IP_OFFMASK, 4, 0),
-
-        // Get the IP header length.
-        BPF_STMT(BPF_LDX | BPF_B    | BPF_MSH, kEtherHeaderLen),
-
-        // Check the destination port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPDstPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 0, 1),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-static void network_stack_utils_attachRaFilter(JNIEnv *env, jobject clazz, jobject javaFd,
-        jint hardwareAddressType) {
-    if (hardwareAddressType != ARPHRD_ETHER) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "attachRaFilter only supports ARPHRD_ETHER");
-        return;
-    }
-
-    static sock_filter filter_code[] = {
-        // Check IPv6 Next Header is ICMPv6.
-        BPF_STMT(BPF_LD  | BPF_B   | BPF_ABS,  kIPv6NextHeader),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    IPPROTO_ICMPV6, 0, 3),
-
-        // Check ICMPv6 type is Router Advertisement.
-        BPF_STMT(BPF_LD  | BPF_B   | BPF_ABS,  kICMPv6TypeOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    ND_ROUTER_ADVERT, 0, 1),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-// TODO: Move all this filter code into libnetutils.
-static void network_stack_utils_attachControlPacketFilter(
-        JNIEnv *env, jobject clazz, jobject javaFd, jint hardwareAddressType) {
-    if (hardwareAddressType != ARPHRD_ETHER) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "attachControlPacketFilter only supports ARPHRD_ETHER");
-        return;
-    }
-
-    // Capture all:
-    //     - ARPs
-    //     - DHCPv4 packets
-    //     - Router Advertisements & Solicitations
-    //     - Neighbor Advertisements & Solicitations
-    //
-    // tcpdump:
-    //     arp or
-    //     '(ip and udp port 68)' or
-    //     '(icmp6 and ip6[40] >= 133 and ip6[40] <= 136)'
-    static sock_filter filter_code[] = {
-        // Load the link layer next payload field.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS,  kEtherTypeOffset),
-
-        // Accept all ARP.
-        // TODO: Figure out how to better filter ARPs on noisy networks.
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_ARP, 16, 0),
-
-        // If IPv4:
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_IP, 0, 9),
-
-        // Check the protocol is UDP.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv4Protocol),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_UDP, 0, 14),
-
-        // Check this is not a fragment.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_ABS, kIPv4FlagsOffset),
-        BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K,   IP_OFFMASK, 12, 0),
-
-        // Get the IP header length.
-        BPF_STMT(BPF_LDX | BPF_B    | BPF_MSH, kEtherHeaderLen),
-
-        // Check the source port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPSrcPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 8, 0),
-
-        // Check the destination port.
-        BPF_STMT(BPF_LD  | BPF_H    | BPF_IND, kUDPDstPortIndirectOffset),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   kDhcpClientPort, 6, 7),
-
-        // IPv6 ...
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   ETHERTYPE_IPV6, 0, 6),
-        // ... check IPv6 Next Header is ICMPv6 (ignore fragments), ...
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kIPv6NextHeader),
-        BPF_JUMP(BPF_JMP | BPF_JEQ  | BPF_K,   IPPROTO_ICMPV6, 0, 4),
-        // ... and check the ICMPv6 type is one of RS/RA/NS/NA.
-        BPF_STMT(BPF_LD  | BPF_B    | BPF_ABS, kICMPv6TypeOffset),
-        BPF_JUMP(BPF_JMP | BPF_JGE  | BPF_K,   ND_ROUTER_SOLICIT, 0, 2),
-        BPF_JUMP(BPF_JMP | BPF_JGT  | BPF_K,   ND_NEIGHBOR_ADVERT, 1, 0),
-
-        // Accept or reject.
-        BPF_STMT(BPF_RET | BPF_K,              0xffff),
-        BPF_STMT(BPF_RET | BPF_K,              0)
-    };
-    static const sock_fprog filter = {
-        sizeof(filter_code) / sizeof(filter_code[0]),
-        filter_code,
-    };
-
-    int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) {
-        jniThrowExceptionFmt(env, "java/net/SocketException",
-                "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno));
-    }
-}
-
-/*
- * JNI registration.
- */
-static const JNINativeMethod gNetworkStackUtilsMethods[] = {
-    /* name, signature, funcPtr */
-    { "addArpEntry", "([B[BLjava/lang/String;Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_addArpEntry },
-    { "attachDhcpFilter", "(Ljava/io/FileDescriptor;)V", (void*) network_stack_utils_attachDhcpFilter },
-    { "attachRaFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachRaFilter },
-    { "attachControlPacketFilter", "(Ljava/io/FileDescriptor;I)V", (void*) network_stack_utils_attachControlPacketFilter },
-};
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
-        return JNI_ERR;
-    }
-
-    if (jniRegisterNativeMethods(env, NETWORKSTACKUTILS_PKG_NAME,
-            gNetworkStackUtilsMethods, NELEM(gNetworkStackUtilsMethods)) < 0) {
-        return JNI_ERR;
-    }
-
-    return JNI_VERSION_1_6;
-
-}
-}; // namespace android
diff --git a/packages/NetworkStack/proguard.flags b/packages/NetworkStack/proguard.flags
deleted file mode 100644
index c60f6c3..0000000
--- a/packages/NetworkStack/proguard.flags
+++ /dev/null
@@ -1,9 +0,0 @@
--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/res/values-mcc460/config.xml b/packages/NetworkStack/res/values-mcc460/config.xml
deleted file mode 100644
index fd4a848..0000000
--- a/packages/NetworkStack/res/values-mcc460/config.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!-- Network validation URL configuration for devices using a Chinese SIM (MCC 460).
-         The below URLs are often whitelisted by captive portals, so they should not be used in the
-         general case as this could degrade the user experience (portals not detected properly).
-         However in China the default URLs are not accessible in general. The below alternatives
-         should allow users to connect to local networks normally. -->
-    <string name="default_captive_portal_https_url" translatable="false">https://connectivitycheck.gstatic.com/generate_204</string>
-    <string-array name="default_captive_portal_fallback_urls" translatable="false">
-        <item>http://www.googleapis.cn/generate_204</item>
-    </string-array>
-</resources>
diff --git a/packages/NetworkStack/res/values/config.xml b/packages/NetworkStack/res/values/config.xml
deleted file mode 100644
index 478ed6b..0000000
--- a/packages/NetworkStack/res/values/config.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!--
-    OEMs that wish to change the below settings must do so via a runtime resource overlay package
-    and *NOT* by changing this file. This file is part of the NetworkStack mainline module.
-    The overlays must apply to the config_* values, not the default_* values. The default_*
-    values are meant to be the default when no other configuration is specified.
-    -->
-
-    <!-- DNS probe timeout for network validation. Enough for 3 DNS queries 5 seconds apart. -->
-    <integer name="default_captive_portal_dns_probe_timeout">12500</integer>
-
-    <!-- HTTP URL for network validation, to use for detecting captive portals. -->
-    <string name="default_captive_portal_http_url" translatable="false">http://connectivitycheck.gstatic.com/generate_204</string>
-
-    <!-- HTTPS URL for network validation, to use for confirming internet connectivity. -->
-    <string name="default_captive_portal_https_url" translatable="false">https://www.google.com/generate_204</string>
-
-    <!-- List of fallback URLs to use for detecting captive portals. -->
-    <string-array name="default_captive_portal_fallback_urls" translatable="false">
-        <item>http://www.google.com/gen_204</item>
-        <item>http://play.googleapis.com/generate_204</item>
-    </string-array>
-
-    <!-- List of fallback probe specs to use for detecting captive portals.
-         This is an alternative to fallback URLs that provides more flexibility on detection rules.
-         Empty, so unused by default. -->
-    <string-array name="default_captive_portal_fallback_probe_specs" translatable="false">
-    </string-array>
-
-    <!-- Configuration hooks for the above settings.
-         Empty by default but may be overridden by RROs. -->
-    <integer name="config_captive_portal_dns_probe_timeout"></integer>
-    <!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
-    <string name="config_captive_portal_http_url" translatable="false"></string>
-    <!--suppress CheckTagEmptyBody: overlayable resource to use as configuration hook -->
-    <string name="config_captive_portal_https_url" translatable="false"></string>
-    <string-array name="config_captive_portal_fallback_urls" translatable="false">
-    </string-array>
-    <string-array name="config_captive_portal_fallback_probe_specs" translatable="false">
-    </string-array>
-
-    <!-- Customized default DNS Servers address. -->
-    <string-array name="config_default_dns_servers" translatable="false">
-    </string-array>
-</resources>
diff --git a/packages/NetworkStack/res/values/overlayable.xml b/packages/NetworkStack/res/values/overlayable.xml
deleted file mode 100644
index b9d5337..0000000
--- a/packages/NetworkStack/res/values/overlayable.xml
+++ /dev/null
@@ -1,28 +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.
--->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <overlayable name="NetworkStackConfig">
-        <policy type="product|system|vendor">
-            <!-- Configuration values for NetworkMonitor -->
-            <item type="integer" name="config_captive_portal_dns_probe_timeout"/>
-            <item type="string" name="config_captive_portal_http_url"/>
-            <item type="string" name="config_captive_portal_https_url"/>
-            <item type="array" name="config_captive_portal_fallback_urls"/>
-            <!-- Configuration value for DhcpResults -->
-            <item type="array" name="config_default_dns_servers"/>
-        </policy>
-    </overlayable>
-</resources>
diff --git a/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java b/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java
deleted file mode 100644
index 41715b2..0000000
--- a/packages/NetworkStack/src/android/net/NetworkStackIpMemoryStore.java
+++ /dev/null
@@ -1,44 +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;
-
-import android.annotation.NonNull;
-import android.content.Context;
-
-import java.util.concurrent.ExecutionException;
-import java.util.function.Consumer;
-
-/**
- * service used to communicate with the ip memory store service in network stack,
- * which is running in the same module.
- * @see com.android.server.connectivity.ipmemorystore.IpMemoryStoreService
- * @hide
- */
-public class NetworkStackIpMemoryStore extends IpMemoryStoreClient {
-    @NonNull private final IIpMemoryStore mService;
-
-    public NetworkStackIpMemoryStore(@NonNull final Context context,
-            @NonNull final IIpMemoryStore service) {
-        super(context);
-        mService = service;
-    }
-
-    @Override
-    protected void runWhenServiceReady(Consumer<IIpMemoryStore> cb) throws ExecutionException {
-        cb.accept(mService);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/apf/ApfFilter.java b/packages/NetworkStack/src/android/net/apf/ApfFilter.java
deleted file mode 100644
index f054319..0000000
--- a/packages/NetworkStack/src/android/net/apf/ApfFilter.java
+++ /dev/null
@@ -1,1981 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.apf;
-
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ARP;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.ETH_P_IPV6;
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_RAW;
-
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
-
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IpClient.IpClientCallbacksWrapper;
-import android.net.metrics.ApfProgramEvent;
-import android.net.metrics.ApfStats;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.RaEvent;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.HexDump;
-import com.android.internal.util.IndentingPrintWriter;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * For networks that support packet filtering via APF programs, {@code ApfFilter}
- * listens for IPv6 ICMPv6 router advertisements (RAs) and generates APF programs to
- * filter out redundant duplicate ones.
- *
- * Threading model:
- * A collection of RAs we've received is kept in mRas. Generating APF programs uses mRas to
- * know what RAs to filter for, thus generating APF programs is dependent on mRas.
- * mRas can be accessed by multiple threads:
- * - ReceiveThread, which listens for RAs and adds them to mRas, and generates APF programs.
- * - callers of:
- *    - setMulticastFilter(), which can cause an APF program to be generated.
- *    - dump(), which dumps mRas among other things.
- *    - shutdown(), which clears mRas.
- * So access to mRas is synchronized.
- *
- * @hide
- */
-public class ApfFilter {
-
-    // Helper class for specifying functional filter parameters.
-    public static class ApfConfiguration {
-        public ApfCapabilities apfCapabilities;
-        public boolean multicastFilter;
-        public boolean ieee802_3Filter;
-        public int[] ethTypeBlackList;
-    }
-
-    // Enums describing the outcome of receiving an RA packet.
-    private static enum ProcessRaResult {
-        MATCH,          // Received RA matched a known RA
-        DROPPED,        // Received RA ignored due to MAX_RAS
-        PARSE_ERROR,    // Received RA could not be parsed
-        ZERO_LIFETIME,  // Received RA had 0 lifetime
-        UPDATE_NEW_RA,  // APF program updated for new RA
-        UPDATE_EXPIRY   // APF program updated for expiry
-    }
-
-    /**
-     * APF packet counters.
-     *
-     * Packet counters are 32bit big-endian values, and allocated near the end of the APF data
-     * buffer, using negative byte offsets, where -4 is equivalent to maximumApfProgramSize - 4,
-     * the last writable 32bit word.
-     */
-    @VisibleForTesting
-    public static enum Counter {
-        RESERVED_OOB,  // Points to offset 0 from the end of the buffer (out-of-bounds)
-        TOTAL_PACKETS,
-        PASSED_ARP,
-        PASSED_DHCP,
-        PASSED_IPV4,
-        PASSED_IPV6_NON_ICMP,
-        PASSED_IPV4_UNICAST,
-        PASSED_IPV6_ICMP,
-        PASSED_IPV6_UNICAST_NON_ICMP,
-        PASSED_ARP_NON_IPV4,
-        PASSED_ARP_UNKNOWN,
-        PASSED_ARP_UNICAST_REPLY,
-        PASSED_NON_IP_UNICAST,
-        DROPPED_ETH_BROADCAST,
-        DROPPED_RA,
-        DROPPED_GARP_REPLY,
-        DROPPED_ARP_OTHER_HOST,
-        DROPPED_IPV4_L2_BROADCAST,
-        DROPPED_IPV4_BROADCAST_ADDR,
-        DROPPED_IPV4_BROADCAST_NET,
-        DROPPED_IPV4_MULTICAST,
-        DROPPED_IPV6_ROUTER_SOLICITATION,
-        DROPPED_IPV6_MULTICAST_NA,
-        DROPPED_IPV6_MULTICAST,
-        DROPPED_IPV6_MULTICAST_PING,
-        DROPPED_IPV6_NON_ICMP_MULTICAST,
-        DROPPED_802_3_FRAME,
-        DROPPED_ETHERTYPE_BLACKLISTED,
-        DROPPED_ARP_REPLY_SPA_NO_HOST,
-        DROPPED_IPV4_KEEPALIVE_ACK,
-        DROPPED_IPV6_KEEPALIVE_ACK,
-        DROPPED_IPV4_NATT_KEEPALIVE;
-
-        // Returns the negative byte offset from the end of the APF data segment for
-        // a given counter.
-        public int offset() {
-            return - this.ordinal() * 4;  // Currently, all counters are 32bit long.
-        }
-
-        // Returns the total size of the data segment in bytes.
-        public static int totalSize() {
-            return (Counter.class.getEnumConstants().length - 1) * 4;
-        }
-    }
-
-    /**
-     * When APFv4 is supported, loads R1 with the offset of the specified counter.
-     */
-    private void maybeSetupCounter(ApfGenerator gen, Counter c) {
-        if (mApfCapabilities.hasDataAccess()) {
-            gen.addLoadImmediate(Register.R1, c.offset());
-        }
-    }
-
-    // When APFv4 is supported, these point to the trampolines generated by emitEpilogue().
-    // Otherwise, they're just aliases for PASS_LABEL and DROP_LABEL.
-    private final String mCountAndPassLabel;
-    private final String mCountAndDropLabel;
-
-    // Thread to listen for RAs.
-    @VisibleForTesting
-    class ReceiveThread extends Thread {
-        private final byte[] mPacket = new byte[1514];
-        private final FileDescriptor mSocket;
-        private final long mStart = SystemClock.elapsedRealtime();
-
-        private int mReceivedRas = 0;
-        private int mMatchingRas = 0;
-        private int mDroppedRas = 0;
-        private int mParseErrors = 0;
-        private int mZeroLifetimeRas = 0;
-        private int mProgramUpdates = 0;
-
-        private volatile boolean mStopped;
-
-        public ReceiveThread(FileDescriptor socket) {
-            mSocket = socket;
-        }
-
-        public void halt() {
-            mStopped = true;
-            // Interrupts the read() call the thread is blocked in.
-            NetworkStackUtils.closeSocketQuietly(mSocket);
-        }
-
-        @Override
-        public void run() {
-            log("begin monitoring");
-            while (!mStopped) {
-                try {
-                    int length = Os.read(mSocket, mPacket, 0, mPacket.length);
-                    updateStats(processRa(mPacket, length));
-                } catch (IOException|ErrnoException e) {
-                    if (!mStopped) {
-                        Log.e(TAG, "Read error", e);
-                    }
-                }
-            }
-            logStats();
-        }
-
-        private void updateStats(ProcessRaResult result) {
-            mReceivedRas++;
-            switch(result) {
-                case MATCH:
-                    mMatchingRas++;
-                    return;
-                case DROPPED:
-                    mDroppedRas++;
-                    return;
-                case PARSE_ERROR:
-                    mParseErrors++;
-                    return;
-                case ZERO_LIFETIME:
-                    mZeroLifetimeRas++;
-                    return;
-                case UPDATE_EXPIRY:
-                    mMatchingRas++;
-                    mProgramUpdates++;
-                    return;
-                case UPDATE_NEW_RA:
-                    mProgramUpdates++;
-                    return;
-            }
-        }
-
-        private void logStats() {
-            final long nowMs = SystemClock.elapsedRealtime();
-            synchronized (this) {
-                final ApfStats stats = new ApfStats.Builder()
-                        .setReceivedRas(mReceivedRas)
-                        .setMatchingRas(mMatchingRas)
-                        .setDroppedRas(mDroppedRas)
-                        .setParseErrors(mParseErrors)
-                        .setZeroLifetimeRas(mZeroLifetimeRas)
-                        .setProgramUpdates(mProgramUpdates)
-                        .setDurationMs(nowMs - mStart)
-                        .setMaxProgramSize(mApfCapabilities.maximumApfProgramSize)
-                        .setProgramUpdatesAll(mNumProgramUpdates)
-                        .setProgramUpdatesAllowingMulticast(mNumProgramUpdatesAllowingMulticast)
-                        .build();
-                mMetricsLog.log(stats);
-                logApfProgramEventLocked(nowMs / DateUtils.SECOND_IN_MILLIS);
-            }
-        }
-    }
-
-    private static final String TAG = "ApfFilter";
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
-
-    private static final int ETH_HEADER_LEN = 14;
-    private static final int ETH_DEST_ADDR_OFFSET = 0;
-    private static final int ETH_ETHERTYPE_OFFSET = 12;
-    private static final int ETH_TYPE_MIN = 0x0600;
-    private static final int ETH_TYPE_MAX = 0xFFFF;
-    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.
-    private static final int IPV4_FRAGMENT_OFFSET_MASK = 0x1fff;
-    private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9;
-    private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16;
-    private static final int IPV4_ANY_HOST_ADDRESS = 0;
-    private static final int IPV4_BROADCAST_ADDRESS = -1; // 255.255.255.255
-    private static final int IPV4_HEADER_LEN = 20; // Without options
-
-    // Traffic class and Flow label are not byte aligned. Luckily we
-    // don't care about either value so we'll consider bytes 1-3 of the
-    // IPv6 header as don't care.
-    private static final int IPV6_FLOW_LABEL_OFFSET = ETH_HEADER_LEN + 1;
-    private static final int IPV6_FLOW_LABEL_LEN = 3;
-    private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6;
-    private static final int IPV6_SRC_ADDR_OFFSET = ETH_HEADER_LEN + 8;
-    private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24;
-    private static final int IPV6_HEADER_LEN = 40;
-    // The IPv6 all nodes address ff02::1
-    private static final byte[] IPV6_ALL_NODES_ADDRESS =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
-
-    private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-
-    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
-    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 2;
-    private static final int UDP_HEADER_LEN = 8;
-
-    private static final int TCP_HEADER_SIZE_OFFSET = 12;
-
-    private static final int DHCP_CLIENT_PORT = 68;
-    // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT
-    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
-
-    private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
-    private static final byte[] ARP_IPV4_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-    };
-    private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
-    // Opcode: ARP request (0x0001), ARP reply (0x0002)
-    private static final short ARP_OPCODE_REQUEST = 1;
-    private static final short ARP_OPCODE_REPLY = 2;
-    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
-    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
-    // Do not log ApfProgramEvents whose actual lifetimes was less than this.
-    private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2;
-    // Limit on the Black List size to cap on program usage for this
-    // TODO: Select a proper max length
-    private static final int APF_MAX_ETH_TYPE_BLACK_LIST_LEN = 20;
-
-    private final ApfCapabilities mApfCapabilities;
-    private final IpClientCallbacksWrapper mIpClientCallback;
-    private final InterfaceParams mInterfaceParams;
-    private final IpConnectivityLog mMetricsLog;
-
-    @VisibleForTesting
-    byte[] mHardwareAddress;
-    @VisibleForTesting
-    ReceiveThread mReceiveThread;
-    @GuardedBy("this")
-    private long mUniqueCounter;
-    @GuardedBy("this")
-    private boolean mMulticastFilter;
-    @GuardedBy("this")
-    private boolean mInDozeMode;
-    private final boolean mDrop802_3Frames;
-    private final int[] mEthTypeBlackList;
-
-    // Detects doze mode state transitions.
-    private final BroadcastReceiver mDeviceIdleReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) {
-                PowerManager powerManager =
-                        (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-                final boolean deviceIdle = powerManager.isDeviceIdleMode();
-                setDozeMode(deviceIdle);
-            }
-        }
-    };
-    private final Context mContext;
-
-    // Our IPv4 address, if we have just one, otherwise null.
-    @GuardedBy("this")
-    private byte[] mIPv4Address;
-    // The subnet prefix length of our IPv4 network. Only valid if mIPv4Address is not null.
-    @GuardedBy("this")
-    private int mIPv4PrefixLength;
-
-    @VisibleForTesting
-    ApfFilter(Context context, ApfConfiguration config, InterfaceParams ifParams,
-            IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) {
-        mApfCapabilities = config.apfCapabilities;
-        mIpClientCallback = ipClientCallback;
-        mInterfaceParams = ifParams;
-        mMulticastFilter = config.multicastFilter;
-        mDrop802_3Frames = config.ieee802_3Filter;
-        mContext = context;
-
-        if (mApfCapabilities.hasDataAccess()) {
-            mCountAndPassLabel = "countAndPass";
-            mCountAndDropLabel = "countAndDrop";
-        } else {
-            // APFv4 unsupported: turn jumps to the counter trampolines to immediately PASS or DROP,
-            // preserving the original pre-APFv4 behavior.
-            mCountAndPassLabel = ApfGenerator.PASS_LABEL;
-            mCountAndDropLabel = ApfGenerator.DROP_LABEL;
-        }
-
-        // Now fill the black list from the passed array
-        mEthTypeBlackList = filterEthTypeBlackList(config.ethTypeBlackList);
-
-        mMetricsLog = log;
-
-        // TODO: ApfFilter should not generate programs until IpClient sends provisioning success.
-        maybeStartFilter();
-
-        // Listen for doze-mode transition changes to enable/disable the IPv6 multicast filter.
-        mContext.registerReceiver(mDeviceIdleReceiver,
-                new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED));
-    }
-
-    public synchronized void setDataSnapshot(byte[] data) {
-        mDataSnapshot = data;
-    }
-
-    private void log(String s) {
-        Log.d(TAG, "(" + mInterfaceParams.name + "): " + s);
-    }
-
-    @GuardedBy("this")
-    private long getUniqueNumberLocked() {
-        return mUniqueCounter++;
-    }
-
-    @GuardedBy("this")
-    private static int[] filterEthTypeBlackList(int[] ethTypeBlackList) {
-        ArrayList<Integer> bl = new ArrayList<Integer>();
-
-        for (int p : ethTypeBlackList) {
-            // Check if the protocol is a valid ether type
-            if ((p < ETH_TYPE_MIN) || (p > ETH_TYPE_MAX)) {
-                continue;
-            }
-
-            // Check if the protocol is not repeated in the passed array
-            if (bl.contains(p)) {
-                continue;
-            }
-
-            // Check if list reach its max size
-            if (bl.size() == APF_MAX_ETH_TYPE_BLACK_LIST_LEN) {
-                Log.w(TAG, "Passed EthType Black List size too large (" + bl.size() +
-                        ") using top " + APF_MAX_ETH_TYPE_BLACK_LIST_LEN + " protocols");
-                break;
-            }
-
-            // Now add the protocol to the list
-            bl.add(p);
-        }
-
-        return bl.stream().mapToInt(Integer::intValue).toArray();
-    }
-
-    /**
-     * Attempt to start listening for RAs and, if RAs are received, generating and installing
-     * filters to ignore useless RAs.
-     */
-    @VisibleForTesting
-    void maybeStartFilter() {
-        FileDescriptor socket;
-        try {
-            mHardwareAddress = mInterfaceParams.macAddr.toByteArray();
-            synchronized(this) {
-                // Clear the APF memory to reset all counters upon connecting to the first AP
-                // in an SSID. This is limited to APFv4 devices because this large write triggers
-                // a crash on some older devices (b/78905546).
-                if (mApfCapabilities.hasDataAccess()) {
-                    byte[] zeroes = new byte[mApfCapabilities.maximumApfProgramSize];
-                    mIpClientCallback.installPacketFilter(zeroes);
-                }
-
-                // Install basic filters
-                installNewProgramLocked();
-            }
-            socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6);
-            SocketAddress addr = makePacketSocketAddress(
-                    (short) ETH_P_IPV6, mInterfaceParams.index);
-            Os.bind(socket, addr);
-            NetworkStackUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error starting filter", e);
-            return;
-        }
-        mReceiveThread = new ReceiveThread(socket);
-        mReceiveThread.start();
-    }
-
-    // Returns seconds since device boot.
-    @VisibleForTesting
-    protected long currentTimeSeconds() {
-        return SystemClock.elapsedRealtime() / DateUtils.SECOND_IN_MILLIS;
-    }
-
-    public static class InvalidRaException extends Exception {
-        public InvalidRaException(String m) {
-            super(m);
-        }
-    }
-
-    // A class to hold information about an RA.
-    @VisibleForTesting
-    class Ra {
-        // From RFC4861:
-        private static final int ICMP6_RA_HEADER_LEN = 16;
-        private static final int ICMP6_RA_CHECKSUM_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
-        private static final int ICMP6_RA_CHECKSUM_LEN = 2;
-        private static final int ICMP6_RA_OPTION_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
-        private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
-                ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
-        private static final int ICMP6_RA_ROUTER_LIFETIME_LEN = 2;
-        // Prefix information option.
-        private static final int ICMP6_PREFIX_OPTION_TYPE = 3;
-        private static final int ICMP6_PREFIX_OPTION_LEN = 32;
-        private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET = 4;
-        private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN = 4;
-        private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
-        private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN = 4;
-
-        // From RFC6106: Recursive DNS Server option
-        private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
-        // From RFC6106: DNS Search List option
-        private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
-
-        // From RFC4191: Route Information option
-        private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
-        // Above three options all have the same format:
-        private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
-        private static final int ICMP6_4_BYTE_LIFETIME_LEN = 4;
-
-        // Note: mPacket's position() cannot be assumed to be reset.
-        private final ByteBuffer mPacket;
-        // List of binary ranges that include the whole packet except the lifetimes.
-        // Pairs consist of offset and length.
-        private final ArrayList<Pair<Integer, Integer>> mNonLifetimes =
-                new ArrayList<Pair<Integer, Integer>>();
-        // Minimum lifetime in packet
-        long mMinLifetime;
-        // When the packet was last captured, in seconds since Unix Epoch
-        long mLastSeen;
-
-        // For debugging only. Offsets into the packet where PIOs are.
-        private final ArrayList<Integer> mPrefixOptionOffsets = new ArrayList<>();
-
-        // For debugging only. Offsets into the packet where RDNSS options are.
-        private final ArrayList<Integer> mRdnssOptionOffsets = new ArrayList<>();
-
-        // For debugging only. How many times this RA was seen.
-        int seenCount = 0;
-
-        // For debugging only. Returns the hex representation of the last matching packet.
-        String getLastMatchingPacket() {
-            return HexDump.toHexString(mPacket.array(), 0, mPacket.capacity(),
-                    false /* lowercase */);
-        }
-
-        // For debugging only. Returns the string representation of the IPv6 address starting at
-        // position pos in the packet.
-        private String IPv6AddresstoString(int pos) {
-            try {
-                byte[] array = mPacket.array();
-                // Can't just call copyOfRange() and see if it throws, because if it reads past the
-                // end it pads with zeros instead of throwing.
-                if (pos < 0 || pos + 16 > array.length || pos + 16 < pos) {
-                    return "???";
-                }
-                byte[] addressBytes = Arrays.copyOfRange(array, pos, pos + 16);
-                InetAddress address = (Inet6Address) InetAddress.getByAddress(addressBytes);
-                return address.getHostAddress();
-            } catch (UnsupportedOperationException e) {
-                // array() failed. Cannot happen, mPacket is array-backed and read-write.
-                return "???";
-            } catch (ClassCastException|UnknownHostException e) {
-                // Cannot happen.
-                return "???";
-            }
-        }
-
-        // Can't be static because it's in a non-static inner class.
-        // TODO: Make this static once RA is its own class.
-        private void prefixOptionToString(StringBuffer sb, int offset) {
-            String prefix = IPv6AddresstoString(offset + 16);
-            int length = getUint8(mPacket, offset + 2);
-            long valid = getUint32(mPacket, offset + 4);
-            long preferred = getUint32(mPacket, offset + 8);
-            sb.append(String.format("%s/%d %ds/%ds ", prefix, length, valid, preferred));
-        }
-
-        private void rdnssOptionToString(StringBuffer sb, int offset) {
-            int optLen = getUint8(mPacket, offset + 1) * 8;
-            if (optLen < 24) return;  // Malformed or empty.
-            long lifetime = getUint32(mPacket, offset + 4);
-            int numServers = (optLen - 8) / 16;
-            sb.append("DNS ").append(lifetime).append("s");
-            for (int server = 0; server < numServers; server++) {
-                sb.append(" ").append(IPv6AddresstoString(offset + 8 + 16 * server));
-            }
-        }
-
-        public String toString() {
-            try {
-                StringBuffer sb = new StringBuffer();
-                sb.append(String.format("RA %s -> %s %ds ",
-                        IPv6AddresstoString(IPV6_SRC_ADDR_OFFSET),
-                        IPv6AddresstoString(IPV6_DEST_ADDR_OFFSET),
-                        getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET)));
-                for (int i: mPrefixOptionOffsets) {
-                    prefixOptionToString(sb, i);
-                }
-                for (int i: mRdnssOptionOffsets) {
-                    rdnssOptionToString(sb, i);
-                }
-                return sb.toString();
-            } catch (BufferUnderflowException|IndexOutOfBoundsException e) {
-                return "<Malformed RA>";
-            }
-        }
-
-        /**
-         * Add a binary range of the packet that does not include a lifetime to mNonLifetimes.
-         * Assumes mPacket.position() is as far as we've parsed the packet.
-         * @param lastNonLifetimeStart offset within packet of where the last binary range of
-         *                             data not including a lifetime.
-         * @param lifetimeOffset offset from mPacket.position() to the next lifetime data.
-         * @param lifetimeLength length of the next lifetime data.
-         * @return offset within packet of where the next binary range of data not including
-         *         a lifetime. This can be passed into the next invocation of this function
-         *         via {@code lastNonLifetimeStart}.
-         */
-        private int addNonLifetime(int lastNonLifetimeStart, int lifetimeOffset,
-                int lifetimeLength) {
-            lifetimeOffset += mPacket.position();
-            mNonLifetimes.add(new Pair<Integer, Integer>(lastNonLifetimeStart,
-                    lifetimeOffset - lastNonLifetimeStart));
-            return lifetimeOffset + lifetimeLength;
-        }
-
-        private int addNonLifetimeU32(int lastNonLifetimeStart) {
-            return addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_4_BYTE_LIFETIME_OFFSET, ICMP6_4_BYTE_LIFETIME_LEN);
-        }
-
-        // Note that this parses RA and may throw InvalidRaException (from
-        // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException
-        // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with
-        // specifications.
-        Ra(byte[] packet, int length) throws InvalidRaException {
-            if (length < ICMP6_RA_OPTION_OFFSET) {
-                throw new InvalidRaException("Not an ICMP6 router advertisement");
-            }
-
-            mPacket = ByteBuffer.wrap(Arrays.copyOf(packet, length));
-            mLastSeen = currentTimeSeconds();
-
-            // Sanity check packet in case a packet arrives before we attach RA filter
-            // to our packet socket. b/29586253
-            if (getUint16(mPacket, ETH_ETHERTYPE_OFFSET) != ETH_P_IPV6 ||
-                    getUint8(mPacket, IPV6_NEXT_HEADER_OFFSET) != IPPROTO_ICMPV6 ||
-                    getUint8(mPacket, ICMP6_TYPE_OFFSET) != ICMPV6_ROUTER_ADVERTISEMENT) {
-                throw new InvalidRaException("Not an ICMP6 router advertisement");
-            }
-
-
-            RaEvent.Builder builder = new RaEvent.Builder();
-
-            // Ignore the flow label and low 4 bits of traffic class.
-            int lastNonLifetimeStart = addNonLifetime(0,
-                    IPV6_FLOW_LABEL_OFFSET,
-                    IPV6_FLOW_LABEL_LEN);
-
-            // Ignore the checksum.
-            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_RA_CHECKSUM_OFFSET,
-                    ICMP6_RA_CHECKSUM_LEN);
-
-            // Parse router lifetime
-            lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                    ICMP6_RA_ROUTER_LIFETIME_OFFSET,
-                    ICMP6_RA_ROUTER_LIFETIME_LEN);
-            builder.updateRouterLifetime(getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET));
-
-            // Ensures that the RA is not truncated.
-            mPacket.position(ICMP6_RA_OPTION_OFFSET);
-            while (mPacket.hasRemaining()) {
-                final int position = mPacket.position();
-                final int optionType = getUint8(mPacket, position);
-                final int optionLength = getUint8(mPacket, position + 1) * 8;
-                long lifetime;
-                switch (optionType) {
-                    case ICMP6_PREFIX_OPTION_TYPE:
-                        // Parse valid lifetime
-                        lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                                ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
-                                ICMP6_PREFIX_OPTION_VALID_LIFETIME_LEN);
-                        lifetime = getUint32(mPacket,
-                                position + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET);
-                        builder.updatePrefixValidLifetime(lifetime);
-                        // Parse preferred lifetime
-                        lastNonLifetimeStart = addNonLifetime(lastNonLifetimeStart,
-                                ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
-                                ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_LEN);
-                        lifetime = getUint32(mPacket,
-                                position + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET);
-                        builder.updatePrefixPreferredLifetime(lifetime);
-                        mPrefixOptionOffsets.add(position);
-                        break;
-                    // These three options have the same lifetime offset and size, and
-                    // are processed with the same specialized addNonLifetimeU32:
-                    case ICMP6_RDNSS_OPTION_TYPE:
-                        mRdnssOptionOffsets.add(position);
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateRdnssLifetime(lifetime);
-                        break;
-                    case ICMP6_ROUTE_INFO_OPTION_TYPE:
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateRouteInfoLifetime(lifetime);
-                        break;
-                    case ICMP6_DNSSL_OPTION_TYPE:
-                        lastNonLifetimeStart = addNonLifetimeU32(lastNonLifetimeStart);
-                        lifetime = getUint32(mPacket, position + ICMP6_4_BYTE_LIFETIME_OFFSET);
-                        builder.updateDnsslLifetime(lifetime);
-                        break;
-                    default:
-                        // RFC4861 section 4.2 dictates we ignore unknown options for fowards
-                        // compatibility.
-                        break;
-                }
-                if (optionLength <= 0) {
-                    throw new InvalidRaException(String.format(
-                        "Invalid option length opt=%d len=%d", optionType, optionLength));
-                }
-                mPacket.position(position + optionLength);
-            }
-            // Mark non-lifetime bytes since last lifetime.
-            addNonLifetime(lastNonLifetimeStart, 0, 0);
-            mMinLifetime = minLifetime(packet, length);
-            mMetricsLog.log(builder.build());
-        }
-
-        // Ignoring lifetimes (which may change) does {@code packet} match this RA?
-        boolean matches(byte[] packet, int length) {
-            if (length != mPacket.capacity()) return false;
-            byte[] referencePacket = mPacket.array();
-            for (Pair<Integer, Integer> nonLifetime : mNonLifetimes) {
-                for (int i = nonLifetime.first; i < (nonLifetime.first + nonLifetime.second); i++) {
-                    if (packet[i] != referencePacket[i]) return false;
-                }
-            }
-            return true;
-        }
-
-        // What is the minimum of all lifetimes within {@code packet} in seconds?
-        // Precondition: matches(packet, length) already returned true.
-        long minLifetime(byte[] packet, int length) {
-            long minLifetime = Long.MAX_VALUE;
-            // Wrap packet in ByteBuffer so we can read big-endian values easily
-            ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
-            for (int i = 0; (i + 1) < mNonLifetimes.size(); i++) {
-                int offset = mNonLifetimes.get(i).first + mNonLifetimes.get(i).second;
-
-                // The flow label is in mNonLifetimes, but it's not a lifetime.
-                if (offset == IPV6_FLOW_LABEL_OFFSET) {
-                    continue;
-                }
-
-                // The checksum is in mNonLifetimes, but it's not a lifetime.
-                if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
-                    continue;
-                }
-
-                final int lifetimeLength = mNonLifetimes.get(i+1).first - offset;
-                final long optionLifetime;
-                switch (lifetimeLength) {
-                    case 2:
-                        optionLifetime = getUint16(byteBuffer, offset);
-                        break;
-                    case 4:
-                        optionLifetime = getUint32(byteBuffer, offset);
-                        break;
-                    default:
-                        throw new IllegalStateException("bogus lifetime size " + lifetimeLength);
-                }
-                minLifetime = Math.min(minLifetime, optionLifetime);
-            }
-            return minLifetime;
-        }
-
-        // How many seconds does this RA's have to live, taking into account the fact
-        // that we might have seen it a while ago.
-        long currentLifetime() {
-            return mMinLifetime - (currentTimeSeconds() - mLastSeen);
-        }
-
-        boolean isExpired() {
-            // TODO: We may want to handle 0 lifetime RAs differently, if they are common. We'll
-            // have to calculate the filter lifetime specially as a fraction of 0 is still 0.
-            return currentLifetime() <= 0;
-        }
-
-        // Append a filter for this RA to {@code gen}. Jump to DROP_LABEL if it should be dropped.
-        // Jump to the next filter if packet doesn't match this RA.
-        @GuardedBy("ApfFilter.this")
-        long generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            String nextFilterLabel = "Ra" + getUniqueNumberLocked();
-            // Skip if packet is not the right size
-            gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
-            gen.addJumpIfR0NotEquals(mPacket.capacity(), nextFilterLabel);
-            int filterLifetime = (int)(currentLifetime() / FRACTION_OF_LIFETIME_TO_FILTER);
-            // Skip filter if expired
-            gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
-            gen.addJumpIfR0GreaterThan(filterLifetime, nextFilterLabel);
-            for (int i = 0; i < mNonLifetimes.size(); i++) {
-                // Generate code to match the packet bytes
-                Pair<Integer, Integer> nonLifetime = mNonLifetimes.get(i);
-                // Don't generate JNEBS instruction for 0 bytes as it always fails the
-                // ASSERT_FORWARD_IN_PROGRAM(pc + cmp_imm - 1) check where cmp_imm is
-                // the number of bytes to compare. nonLifetime is zero between the
-                // valid and preferred lifetimes in the prefix option.
-                if (nonLifetime.second != 0) {
-                    gen.addLoadImmediate(Register.R0, nonLifetime.first);
-                    gen.addJumpIfBytesNotEqual(Register.R0,
-                            Arrays.copyOfRange(mPacket.array(), nonLifetime.first,
-                                               nonLifetime.first + nonLifetime.second),
-                            nextFilterLabel);
-                }
-                // Generate code to test the lifetimes haven't gone down too far
-                if ((i + 1) < mNonLifetimes.size()) {
-                    Pair<Integer, Integer> nextNonLifetime = mNonLifetimes.get(i + 1);
-                    int offset = nonLifetime.first + nonLifetime.second;
-
-                    // Skip the Flow label.
-                    if (offset == IPV6_FLOW_LABEL_OFFSET) {
-                        continue;
-                    }
-                    // Skip the checksum.
-                    if (offset == ICMP6_RA_CHECKSUM_OFFSET) {
-                        continue;
-                    }
-                    int length = nextNonLifetime.first - offset;
-                    switch (length) {
-                        case 4: gen.addLoad32(Register.R0, offset); break;
-                        case 2: gen.addLoad16(Register.R0, offset); break;
-                        default: throw new IllegalStateException("bogus lifetime size " + length);
-                    }
-                    gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
-                }
-            }
-            maybeSetupCounter(gen, Counter.DROPPED_RA);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-            return filterLifetime;
-        }
-    }
-
-    // TODO: Refactor these subclasses to avoid so much repetition.
-    private abstract static class KeepalivePacket {
-        // Note that the offset starts from IP header.
-        // These must be added ether header length when generating program.
-        static final int IP_HEADER_OFFSET = 0;
-        static final int IPV4_SRC_ADDR_OFFSET = IP_HEADER_OFFSET + 12;
-
-        // Append a filter for this keepalive ack to {@code gen}.
-        // Jump to drop if it matches the keepalive ack.
-        // Jump to the next filter if packet doesn't match the keepalive ack.
-        abstract void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException;
-    }
-
-    // A class to hold NAT-T keepalive ack information.
-    private class NattKeepaliveResponse extends KeepalivePacket {
-        static final int UDP_LENGTH_OFFSET = 4;
-        static final int UDP_HEADER_LEN = 8;
-
-        protected class NattKeepaliveResponseData {
-            public final byte[] srcAddress;
-            public final int srcPort;
-            public final byte[] dstAddress;
-            public final int dstPort;
-
-            NattKeepaliveResponseData(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-                srcAddress = sentKeepalivePacket.dstAddress;
-                srcPort = sentKeepalivePacket.dstPort;
-                dstAddress = sentKeepalivePacket.srcAddress;
-                dstPort = sentKeepalivePacket.srcPort;
-            }
-        }
-
-        protected final NattKeepaliveResponseData mPacket;
-        protected final byte[] mSrcDstAddr;
-        protected final byte[] mPortFingerprint;
-        // NAT-T keepalive packet
-        protected final byte[] mPayload = {(byte) 0xff};
-
-        NattKeepaliveResponse(final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-            mPacket = new NattKeepaliveResponseData(sentKeepalivePacket);
-            mSrcDstAddr = concatArrays(mPacket.srcAddress, mPacket.dstAddress);
-            mPortFingerprint = generatePortFingerprint(mPacket.srcPort, mPacket.dstPort);
-        }
-
-        byte[] generatePortFingerprint(int srcPort, int dstPort) {
-            final ByteBuffer fp = ByteBuffer.allocate(4);
-            fp.order(ByteOrder.BIG_ENDIAN);
-            fp.putShort((short) srcPort);
-            fp.putShort((short) dstPort);
-            return fp.array();
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            final String nextFilterLabel = "natt_keepalive_filter" + getUniqueNumberLocked();
-
-            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
-
-            // A NAT-T keepalive packet contains 1 byte payload with the value 0xff
-            // Check payload length is 1
-            gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addAdd(UDP_HEADER_LEN);
-            gen.addSwap();
-            gen.addLoad16(Register.R0, IPV4_TOTAL_LENGTH_OFFSET);
-            gen.addNeg(Register.R1);
-            gen.addAddR1();
-            gen.addJumpIfR0NotEquals(1, nextFilterLabel);
-
-            // Check that the ports match
-            gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addAdd(ETH_HEADER_LEN);
-            gen.addJumpIfBytesNotEqual(Register.R0, mPortFingerprint, nextFilterLabel);
-
-            // Payload offset = R0 + UDP header length
-            gen.addAdd(UDP_HEADER_LEN);
-            gen.addJumpIfBytesNotEqual(Register.R0, mPayload, nextFilterLabel);
-
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_NATT_KEEPALIVE);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-        }
-
-        public String toString() {
-            try {
-                return String.format("%s -> %s",
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort));
-            } catch (UnknownHostException e) {
-                return "Unknown host";
-            }
-        }
-    }
-
-    // A class to hold TCP keepalive ack information.
-    private abstract static class TcpKeepaliveAck extends KeepalivePacket {
-        protected static class TcpKeepaliveAckData {
-            public final byte[] srcAddress;
-            public final int srcPort;
-            public final byte[] dstAddress;
-            public final int dstPort;
-            public final int seq;
-            public final int ack;
-
-            // Create the characteristics of the ack packet from the sent keepalive packet.
-            TcpKeepaliveAckData(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-                srcAddress = sentKeepalivePacket.dstAddress;
-                srcPort = sentKeepalivePacket.dstPort;
-                dstAddress = sentKeepalivePacket.srcAddress;
-                dstPort = sentKeepalivePacket.srcPort;
-                seq = sentKeepalivePacket.ack;
-                ack = sentKeepalivePacket.seq + 1;
-            }
-        }
-
-        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();
-        }
-
-        public String toString() {
-            try {
-                return String.format("%s -> %s , seq=%d, ack=%d",
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.srcAddress), mPacket.srcPort),
-                        NetworkStackUtils.addressAndPortToString(
-                                InetAddress.getByAddress(mPacket.dstAddress), mPacket.dstPort),
-                        Integer.toUnsignedLong(mPacket.seq),
-                        Integer.toUnsignedLong(mPacket.ack));
-            } catch (UnknownHostException e) {
-                return "Unknown host";
-            }
-        }
-
-        // Append a filter for this keepalive ack to {@code gen}.
-        // Jump to drop if it matches the keepalive ack.
-        // Jump to the next filter if packet doesn't match the keepalive ack.
-        abstract void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException;
-    }
-
-    private class TcpKeepaliveAckV4 extends TcpKeepaliveAck {
-
-        TcpKeepaliveAckV4(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-            this(new TcpKeepaliveAckData(sentKeepalivePacket));
-        }
-        TcpKeepaliveAckV4(final TcpKeepaliveAckData packet) {
-            super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            final String nextFilterLabel = "keepalive_ack" + getUniqueNumberLocked();
-
-            gen.addLoadImmediate(Register.R0, ETH_HEADER_LEN + IPV4_SRC_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, mSrcDstAddr, nextFilterLabel);
-
-            // 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)
-            gen.addLoad8Indexed(Register.R0, ETH_HEADER_LEN + TCP_HEADER_SIZE_OFFSET);
-            // 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 length
-            gen.addAddR1();
-            // 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.addLoadImmediate(Register.R0, ETH_HEADER_LEN);
-            gen.addAddR1();
-            gen.addJumpIfBytesNotEqual(Register.R0, mPortSeqAckFingerprint, nextFilterLabel);
-
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_KEEPALIVE_ACK);
-            gen.addJump(mCountAndDropLabel);
-            gen.defineLabel(nextFilterLabel);
-        }
-    }
-
-    private class TcpKeepaliveAckV6 extends TcpKeepaliveAck {
-        TcpKeepaliveAckV6(final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-            this(new TcpKeepaliveAckData(sentKeepalivePacket));
-        }
-        TcpKeepaliveAckV6(final TcpKeepaliveAckData packet) {
-            super(packet, concatArrays(packet.srcAddress, packet.dstAddress) /* srcDstAddr */);
-        }
-
-        @Override
-        void generateFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-            throw new UnsupportedOperationException("IPv6 TCP Keepalive is not supported yet");
-        }
-    }
-
-    // Maximum number of RAs to filter for.
-    private static final int MAX_RAS = 10;
-
-    @GuardedBy("this")
-    private ArrayList<Ra> mRas = new ArrayList<>();
-    @GuardedBy("this")
-    private SparseArray<KeepalivePacket> mKeepalivePackets = new SparseArray<>();
-
-    // There is always some marginal benefit to updating the installed APF program when an RA is
-    // seen because we can extend the program's lifetime slightly, but there is some cost to
-    // updating the program, so don't bother unless the program is going to expire soon. This
-    // constant defines "soon" in seconds.
-    private static final long MAX_PROGRAM_LIFETIME_WORTH_REFRESHING = 30;
-    // We don't want to filter an RA for it's whole lifetime as it'll be expired by the time we ever
-    // see a refresh.  Using half the lifetime might be a good idea except for the fact that
-    // packets may be dropped, so let's use 6.
-    private static final int FRACTION_OF_LIFETIME_TO_FILTER = 6;
-
-    // When did we last install a filter program? In seconds since Unix Epoch.
-    @GuardedBy("this")
-    private long mLastTimeInstalledProgram;
-    // How long should the last installed filter program live for? In seconds.
-    @GuardedBy("this")
-    private long mLastInstalledProgramMinLifetime;
-    @GuardedBy("this")
-    private ApfProgramEvent.Builder mLastInstallEvent;
-
-    // For debugging only. The last program installed.
-    @GuardedBy("this")
-    private byte[] mLastInstalledProgram;
-
-    /**
-     * For debugging only. Contains the latest APF buffer snapshot captured from the firmware.
-     *
-     * A typical size for this buffer is 4KB. It is present only if the WiFi HAL supports
-     * IWifiStaIface#readApfPacketFilterData(), and the APF interpreter advertised support for
-     * the opcodes to access the data buffer (LDDW and STDW).
-     */
-    @GuardedBy("this") @Nullable
-    private byte[] mDataSnapshot;
-
-    // How many times the program was updated since we started.
-    @GuardedBy("this")
-    private int mNumProgramUpdates = 0;
-    // How many times the program was updated since we started for allowing multicast traffic.
-    @GuardedBy("this")
-    private int mNumProgramUpdatesAllowingMulticast = 0;
-
-    /**
-     * Generate filter code to process ARP packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL and does not fall off the end.
-     * Preconditions:
-     *  - Packet being filtered is ARP
-     */
-    @GuardedBy("this")
-    private void generateArpFilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the ARP filter program does:
-        //
-        // if not ARP IPv4
-        //   pass
-        // if not ARP IPv4 reply or request
-        //   pass
-        // if ARP reply source ip is 0.0.0.0
-        //   drop
-        // if unicast ARP reply
-        //   pass
-        // if interface has no IPv4 address
-        //   if target ip is 0.0.0.0
-        //      drop
-        // else
-        //   if target ip is not the interface ip
-        //      drop
-        // pass
-
-        final String checkTargetIPv4 = "checkTargetIPv4";
-
-        // Pass if not ARP IPv4.
-        gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_ARP_NON_IPV4);
-        gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, mCountAndPassLabel);
-
-        // Pass if unknown ARP opcode.
-        gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
-        gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
-        maybeSetupCounter(gen, Counter.PASSED_ARP_UNKNOWN);
-        gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel);
-
-        // Drop if ARP reply source IP is 0.0.0.0
-        gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET);
-        maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST);
-        gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
-
-        // Pass if unicast reply.
-        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
-        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-
-        // Either a unicast request, a unicast reply, or a broadcast reply.
-        gen.defineLabel(checkTargetIPv4);
-        if (mIPv4Address == null) {
-            // When there is no IPv4 address, drop GARP replies (b/29404209).
-            gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY);
-            gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
-        } else {
-            // When there is an IPv4 address, drop unicast/broadcast requests
-            // and broadcast replies with a different target IPv4 address.
-            gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
-            gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, mCountAndDropLabel);
-        }
-
-        maybeSetupCounter(gen, Counter.PASSED_ARP);
-        gen.addJump(mCountAndPassLabel);
-    }
-
-    /**
-     * Generate filter code to process IPv4 packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL and does not fall off the end.
-     * Preconditions:
-     *  - Packet being filtered is IPv4
-     */
-    @GuardedBy("this")
-    private void generateIPv4FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the IPv4 filter program does:
-        //
-        // if filtering multicast (i.e. multicast lock not held):
-        //   if it's DHCP destined to our MAC:
-        //     pass
-        //   if it's L2 broadcast:
-        //     drop
-        //   if it's IPv4 multicast:
-        //     drop
-        //   if it's IPv4 broadcast:
-        //     drop
-        // if keepalive ack
-        //   drop
-        // pass
-
-        if (mMulticastFilter) {
-            final String skipDhcpv4Filter = "skip_dhcp_v4_filter";
-
-            // Pass DHCP addressed to us.
-            // Check it's UDP.
-            gen.addLoad8(Register.R0, IPV4_PROTOCOL_OFFSET);
-            gen.addJumpIfR0NotEquals(IPPROTO_UDP, skipDhcpv4Filter);
-            // Check it's not a fragment. This matches the BPF filter installed by the DHCP client.
-            gen.addLoad16(Register.R0, IPV4_FRAGMENT_OFFSET_OFFSET);
-            gen.addJumpIfR0AnyBitsSet(IPV4_FRAGMENT_OFFSET_MASK, skipDhcpv4Filter);
-            // Check it's addressed to DHCP client port.
-            gen.addLoadFromMemory(Register.R1, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-            gen.addLoad16Indexed(Register.R0, UDP_DESTINATION_PORT_OFFSET);
-            gen.addJumpIfR0NotEquals(DHCP_CLIENT_PORT, skipDhcpv4Filter);
-            // Check it's DHCP to our MAC address.
-            gen.addLoadImmediate(Register.R0, DHCP_CLIENT_MAC_OFFSET);
-            // NOTE: Relies on R1 containing IPv4 header offset.
-            gen.addAddR1();
-            gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, skipDhcpv4Filter);
-            maybeSetupCounter(gen, Counter.PASSED_DHCP);
-            gen.addJump(mCountAndPassLabel);
-
-            // Drop all multicasts/broadcasts.
-            gen.defineLabel(skipDhcpv4Filter);
-
-            // If IPv4 destination address is in multicast range, drop.
-            gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
-            gen.addAnd(0xf0);
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
-            gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel);
-
-            // If IPv4 broadcast packet, drop regardless of L2 (b/30231088).
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
-            gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET);
-            gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel);
-            if (mIPv4Address != null && mIPv4PrefixLength < 31) {
-                maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
-                int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength);
-                gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
-            }
-
-            // If any TCP keepalive filter matches, drop
-            generateV4KeepaliveFilters(gen);
-
-            // If any NAT-T keepalive filter matches, drop
-            generateV4NattKeepaliveFilters(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);
-            gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-            gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-            maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
-            gen.addJump(mCountAndDropLabel);
-        } else {
-            generateV4KeepaliveFilters(gen);
-            generateV4NattKeepaliveFilters(gen);
-        }
-
-        // Otherwise, pass
-        maybeSetupCounter(gen, Counter.PASSED_IPV4);
-        gen.addJump(mCountAndPassLabel);
-    }
-
-    private void generateKeepaliveFilters(ApfGenerator gen, Class<?> filterType, int proto,
-            int offset, String label) throws IllegalInstructionException {
-        final boolean haveKeepaliveResponses = NetworkStackUtils.any(mKeepalivePackets,
-                ack -> filterType.isInstance(ack));
-
-        // If no keepalive packets of this type
-        if (!haveKeepaliveResponses) return;
-
-        // If not the right proto, skip keepalive filters
-        gen.addLoad8(Register.R0, offset);
-        gen.addJumpIfR0NotEquals(proto, label);
-
-        // Drop Keepalive responses
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket response = mKeepalivePackets.valueAt(i);
-            if (filterType.isInstance(response)) response.generateFilterLocked(gen);
-        }
-
-        gen.defineLabel(label);
-    }
-
-    private void generateV4KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, TcpKeepaliveAckV4.class, IPPROTO_TCP, IPV4_PROTOCOL_OFFSET,
-                "skip_v4_keepalive_filter");
-    }
-
-    private void generateV4NattKeepaliveFilters(ApfGenerator gen)
-            throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, NattKeepaliveResponse.class,
-                IPPROTO_UDP, IPV4_PROTOCOL_OFFSET, "skip_v4_nattkeepalive_filter");
-    }
-
-    /**
-     * Generate filter code to process IPv6 packets. Execution of this code ends in either the
-     * DROP_LABEL or PASS_LABEL, or falls off the end for ICMPv6 packets.
-     * Preconditions:
-     *  - Packet being filtered is IPv6
-     */
-    @GuardedBy("this")
-    private void generateIPv6FilterLocked(ApfGenerator gen) throws IllegalInstructionException {
-        // Here's a basic summary of what the IPv6 filter program does:
-        //
-        // if we're dropping multicast
-        //   if it's not IPCMv6 or it's ICMPv6 but we're in doze mode:
-        //     if it's multicast:
-        //       drop
-        //     pass
-        // if it's ICMPv6 RS to any:
-        //   drop
-        // if it's ICMPv6 NA to ff02::1:
-        //   drop
-        // if keepalive ack
-        //   drop
-
-        gen.addLoad8(Register.R0, IPV6_NEXT_HEADER_OFFSET);
-
-        // Drop multicast if the multicast filter is enabled.
-        if (mMulticastFilter) {
-            final String skipIPv6MulticastFilterLabel = "skipIPv6MulticastFilter";
-            final String dropAllIPv6MulticastsLabel = "dropAllIPv6Multicast";
-
-            // While in doze mode, drop ICMPv6 multicast pings, let the others pass.
-            // While awake, let all ICMPv6 multicasts through.
-            if (mInDozeMode) {
-                // Not ICMPv6? -> Proceed to multicast filtering
-                gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, dropAllIPv6MulticastsLabel);
-
-                // ICMPv6 but not ECHO? -> Skip the multicast filter.
-                // (ICMPv6 ECHO requests will go through the multicast filter below).
-                gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
-                gen.addJumpIfR0NotEquals(ICMPV6_ECHO_REQUEST_TYPE, skipIPv6MulticastFilterLabel);
-            } else {
-                gen.addJumpIfR0Equals(IPPROTO_ICMPV6, skipIPv6MulticastFilterLabel);
-            }
-
-            // Drop all other packets sent to ff00::/8 (multicast prefix).
-            gen.defineLabel(dropAllIPv6MulticastsLabel);
-            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);
-        }
-
-        // If we got this far, the packet is ICMPv6.  Drop some specific types.
-
-        // Add unsolicited multicast neighbor announcements filter
-        String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
-        gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
-        // Drop all router solicitations (b/32833400)
-        maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
-        gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel);
-        // If not neighbor announcements, skip filter.
-        gen.addJumpIfR0NotEquals(ICMPV6_NEIGHBOR_ADVERTISEMENT, skipUnsolicitedMulticastNALabel);
-        // If to ff02::1, drop.
-        // TODO: Drop only if they don't contain the address of on-link neighbours.
-        gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
-        gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
-                skipUnsolicitedMulticastNALabel);
-        maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
-        gen.addJump(mCountAndDropLabel);
-        gen.defineLabel(skipUnsolicitedMulticastNALabel);
-    }
-
-    private void generateV6KeepaliveFilters(ApfGenerator gen) throws IllegalInstructionException {
-        generateKeepaliveFilters(gen, TcpKeepaliveAckV6.class, IPPROTO_TCP, IPV6_NEXT_HEADER_OFFSET,
-                "skip_v6_keepalive_filter");
-    }
-
-    /**
-     * Begin generating an APF program to:
-     * <ul>
-     * <li>Drop/Pass 802.3 frames (based on policy)
-     * <li>Drop packets with EtherType within the Black List
-     * <li>Drop ARP requests not for us, if mIPv4Address is set,
-     * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC,
-     * <li>Drop IPv4 multicast packets, if mMulticastFilter,
-     * <li>Pass all other IPv4 packets,
-     * <li>Drop all broadcast non-IP non-ARP packets.
-     * <li>Pass all non-ICMPv6 IPv6 packets,
-     * <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>
-     */
-    @GuardedBy("this")
-    private ApfGenerator emitPrologueLocked() throws IllegalInstructionException {
-        // This is guaranteed to succeed because of the check in maybeCreate.
-        ApfGenerator gen = new ApfGenerator(mApfCapabilities.apfVersionSupported);
-
-        if (mApfCapabilities.hasDataAccess()) {
-            // Increment TOTAL_PACKETS
-            maybeSetupCounter(gen, Counter.TOTAL_PACKETS);
-            gen.addLoadData(Register.R0, 0);  // load counter
-            gen.addAdd(1);
-            gen.addStoreData(Register.R0, 0);  // write-back counter
-        }
-
-        // Here's a basic summary of what the initial program does:
-        //
-        // if it's a 802.3 Frame (ethtype < 0x0600):
-        //    drop or pass based on configurations
-        // if it has a ether-type that belongs to the black list
-        //    drop
-        // if it's ARP:
-        //   insert ARP filter to drop or pass these appropriately
-        // if it's IPv4:
-        //   insert IPv4 filter to drop or pass these appropriately
-        // if it's not IPv6:
-        //   if it's broadcast:
-        //     drop
-        //   pass
-        // insert IPv6 filter to drop, pass, or fall off the end for ICMPv6 packets
-
-        gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET);
-
-        if (mDrop802_3Frames) {
-            // drop 802.3 frames (ethtype < 0x0600)
-            maybeSetupCounter(gen, Counter.DROPPED_802_3_FRAME);
-            gen.addJumpIfR0LessThan(ETH_TYPE_MIN, mCountAndDropLabel);
-        }
-
-        // Handle ether-type black list
-        maybeSetupCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
-        for (int p : mEthTypeBlackList) {
-            gen.addJumpIfR0Equals(p, mCountAndDropLabel);
-        }
-
-        // Add ARP filters:
-        String skipArpFiltersLabel = "skipArpFilters";
-        gen.addJumpIfR0NotEquals(ETH_P_ARP, skipArpFiltersLabel);
-        generateArpFilterLocked(gen);
-        gen.defineLabel(skipArpFiltersLabel);
-
-        // Add IPv4 filters:
-        String skipIPv4FiltersLabel = "skipIPv4Filters";
-        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
-        // execute the ARP filter, since that filter does not fall through, but either drops or
-        // passes.
-        gen.addJumpIfR0NotEquals(ETH_P_IP, skipIPv4FiltersLabel);
-        generateIPv4FilterLocked(gen);
-        gen.defineLabel(skipIPv4FiltersLabel);
-
-        // Check for IPv6:
-        // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not
-        // execute the ARP or IPv4 filters, since those filters do not fall through, but either
-        // drop or pass.
-        String ipv6FilterLabel = "IPv6Filters";
-        gen.addJumpIfR0Equals(ETH_P_IPV6, ipv6FilterLabel);
-
-        // Drop non-IP non-ARP broadcasts, pass the rest
-        gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST);
-        gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-        maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST);
-        gen.addJump(mCountAndDropLabel);
-
-        // Add IPv6 filters:
-        gen.defineLabel(ipv6FilterLabel);
-        generateIPv6FilterLocked(gen);
-        return gen;
-    }
-
-    /**
-     * Append packet counting epilogue to the APF program.
-     *
-     * Currently, the epilogue consists of two trampolines which count passed and dropped packets
-     * before jumping to the actual PASS and DROP labels.
-     */
-    @GuardedBy("this")
-    private void emitEpilogue(ApfGenerator gen) throws IllegalInstructionException {
-        // If APFv4 is unsupported, no epilogue is necessary: if execution reached this far, it
-        // will just fall-through to the PASS label.
-        if (!mApfCapabilities.hasDataAccess()) return;
-
-        // Execution will reach the bottom of the program if none of the filters match,
-        // which will pass the packet to the application processor.
-        maybeSetupCounter(gen, Counter.PASSED_IPV6_ICMP);
-
-        // Append the count & pass trampoline, which increments the counter at the data address
-        // pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting
-        // the entire sequence inline for every counter.
-        gen.defineLabel(mCountAndPassLabel);
-        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
-        gen.addAdd(1);                     // R0++
-        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
-        gen.addJump(gen.PASS_LABEL);
-
-        // Same as above for the count & drop trampoline.
-        gen.defineLabel(mCountAndDropLabel);
-        gen.addLoadData(Register.R0, 0);   // R0 = *(R1 + 0)
-        gen.addAdd(1);                     // R0++
-        gen.addStoreData(Register.R0, 0);  // *(R1 + 0) = R0
-        gen.addJump(gen.DROP_LABEL);
-    }
-
-    /**
-     * Generate and install a new filter program.
-     */
-    @GuardedBy("this")
-    @VisibleForTesting
-    void installNewProgramLocked() {
-        purgeExpiredRasLocked();
-        ArrayList<Ra> rasToFilter = new ArrayList<>();
-        final byte[] program;
-        long programMinLifetime = Long.MAX_VALUE;
-        long maximumApfProgramSize = mApfCapabilities.maximumApfProgramSize;
-        if (mApfCapabilities.hasDataAccess()) {
-            // Reserve space for the counters.
-            maximumApfProgramSize -= Counter.totalSize();
-        }
-
-        try {
-            // Step 1: Determine how many RA filters we can fit in the program.
-            ApfGenerator gen = emitPrologueLocked();
-
-            // The epilogue normally goes after the RA filters, but add it early to include its
-            // length when estimating the total.
-            emitEpilogue(gen);
-
-            // Can't fit the program even without any RA filters?
-            if (gen.programLengthOverEstimate() > maximumApfProgramSize) {
-                Log.e(TAG, "Program exceeds maximum size " + maximumApfProgramSize);
-                return;
-            }
-
-            for (Ra ra : mRas) {
-                ra.generateFilterLocked(gen);
-                // Stop if we get too big.
-                if (gen.programLengthOverEstimate() > maximumApfProgramSize) break;
-                rasToFilter.add(ra);
-            }
-
-            // Step 2: Actually generate the program
-            gen = emitPrologueLocked();
-            for (Ra ra : rasToFilter) {
-                programMinLifetime = Math.min(programMinLifetime, ra.generateFilterLocked(gen));
-            }
-            emitEpilogue(gen);
-            program = gen.generate();
-        } catch (IllegalInstructionException|IllegalStateException e) {
-            Log.e(TAG, "Failed to generate APF program.", e);
-            return;
-        }
-        final long now = currentTimeSeconds();
-        mLastTimeInstalledProgram = now;
-        mLastInstalledProgramMinLifetime = programMinLifetime;
-        mLastInstalledProgram = program;
-        mNumProgramUpdates++;
-
-        if (VDBG) {
-            hexDump("Installing filter: ", program, program.length);
-        }
-        mIpClientCallback.installPacketFilter(program);
-        logApfProgramEventLocked(now);
-        mLastInstallEvent = new ApfProgramEvent.Builder()
-                .setLifetime(programMinLifetime)
-                .setFilteredRas(rasToFilter.size())
-                .setCurrentRas(mRas.size())
-                .setProgramLength(program.length)
-                .setFlags(mIPv4Address != null, mMulticastFilter);
-    }
-
-    @GuardedBy("this")
-    private void logApfProgramEventLocked(long now) {
-        if (mLastInstallEvent == null) {
-            return;
-        }
-        ApfProgramEvent.Builder ev = mLastInstallEvent;
-        mLastInstallEvent = null;
-        final long actualLifetime = now - mLastTimeInstalledProgram;
-        ev.setActualLifetime(actualLifetime);
-        if (actualLifetime < APF_PROGRAM_EVENT_LIFETIME_THRESHOLD) {
-            return;
-        }
-        mMetricsLog.log(ev.build());
-    }
-
-    /**
-     * Returns {@code true} if a new program should be installed because the current one dies soon.
-     */
-    private boolean shouldInstallnewProgram() {
-        long expiry = mLastTimeInstalledProgram + mLastInstalledProgramMinLifetime;
-        return expiry < currentTimeSeconds() + MAX_PROGRAM_LIFETIME_WORTH_REFRESHING;
-    }
-
-    private void hexDump(String msg, byte[] packet, int length) {
-        log(msg + HexDump.toHexString(packet, 0, length, false /* lowercase */));
-    }
-
-    @GuardedBy("this")
-    private void purgeExpiredRasLocked() {
-        for (int i = 0; i < mRas.size();) {
-            if (mRas.get(i).isExpired()) {
-                log("Expiring " + mRas.get(i));
-                mRas.remove(i);
-            } else {
-                i++;
-            }
-        }
-    }
-
-    /**
-     * Process an RA packet, updating the list of known RAs and installing a new APF program
-     * if the current APF program should be updated.
-     * @return a ProcessRaResult enum describing what action was performed.
-     */
-    @VisibleForTesting
-    synchronized ProcessRaResult processRa(byte[] packet, int length) {
-        if (VDBG) hexDump("Read packet = ", packet, length);
-
-        // Have we seen this RA before?
-        for (int i = 0; i < mRas.size(); i++) {
-            Ra ra = mRas.get(i);
-            if (ra.matches(packet, length)) {
-                if (VDBG) log("matched RA " + ra);
-                // Update lifetimes.
-                ra.mLastSeen = currentTimeSeconds();
-                ra.mMinLifetime = ra.minLifetime(packet, length);
-                ra.seenCount++;
-
-                // Keep mRas in LRU order so as to prioritize generating filters for recently seen
-                // RAs. LRU prioritizes this because RA filters are generated in order from mRas
-                // until the filter program exceeds the maximum filter program size allowed by the
-                // chipset, so RAs appearing earlier in mRas are more likely to make it into the
-                // filter program.
-                // TODO: consider sorting the RAs in order of increasing expiry time as well.
-                // Swap to front of array.
-                mRas.add(0, mRas.remove(i));
-
-                // If the current program doesn't expire for a while, don't update.
-                if (shouldInstallnewProgram()) {
-                    installNewProgramLocked();
-                    return ProcessRaResult.UPDATE_EXPIRY;
-                }
-                return ProcessRaResult.MATCH;
-            }
-        }
-        purgeExpiredRasLocked();
-        // TODO: figure out how to proceed when we've received more then MAX_RAS RAs.
-        if (mRas.size() >= MAX_RAS) {
-            return ProcessRaResult.DROPPED;
-        }
-        final Ra ra;
-        try {
-            ra = new Ra(packet, length);
-        } catch (Exception e) {
-            Log.e(TAG, "Error parsing RA", e);
-            return ProcessRaResult.PARSE_ERROR;
-        }
-        // Ignore 0 lifetime RAs.
-        if (ra.isExpired()) {
-            return ProcessRaResult.ZERO_LIFETIME;
-        }
-        log("Adding " + ra);
-        mRas.add(ra);
-        installNewProgramLocked();
-        return ProcessRaResult.UPDATE_NEW_RA;
-    }
-
-    /**
-     * Create an {@link ApfFilter} if {@code apfCapabilities} indicates support for packet
-     * filtering using APF programs.
-     */
-    public static ApfFilter maybeCreate(Context context, ApfConfiguration config,
-            InterfaceParams ifParams, IpClientCallbacksWrapper ipClientCallback) {
-        if (context == null || config == null || ifParams == null) return null;
-        ApfCapabilities apfCapabilities =  config.apfCapabilities;
-        if (apfCapabilities == null) return null;
-        if (apfCapabilities.apfVersionSupported == 0) return null;
-        if (apfCapabilities.maximumApfProgramSize < 512) {
-            Log.e(TAG, "Unacceptably small APF limit: " + apfCapabilities.maximumApfProgramSize);
-            return null;
-        }
-        // For now only support generating programs for Ethernet frames. If this restriction is
-        // lifted:
-        //   1. the program generator will need its offsets adjusted.
-        //   2. the packet filter attached to our packet socket will need its offset adjusted.
-        if (apfCapabilities.apfPacketFormat != ARPHRD_ETHER) return null;
-        if (!ApfGenerator.supportsVersion(apfCapabilities.apfVersionSupported)) {
-            Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported);
-            return null;
-        }
-
-        return new ApfFilter(context, config, ifParams, ipClientCallback, new IpConnectivityLog());
-    }
-
-    public synchronized void shutdown() {
-        if (mReceiveThread != null) {
-            log("shutting down");
-            mReceiveThread.halt();  // Also closes socket.
-            mReceiveThread = null;
-        }
-        mRas.clear();
-        mContext.unregisterReceiver(mDeviceIdleReceiver);
-    }
-
-    public synchronized void setMulticastFilter(boolean isEnabled) {
-        if (mMulticastFilter == isEnabled) return;
-        mMulticastFilter = isEnabled;
-        if (!isEnabled) {
-            mNumProgramUpdatesAllowingMulticast++;
-        }
-        installNewProgramLocked();
-    }
-
-    @VisibleForTesting
-    public synchronized void setDozeMode(boolean isEnabled) {
-        if (mInDozeMode == isEnabled) return;
-        mInDozeMode = isEnabled;
-        installNewProgramLocked();
-    }
-
-    /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */
-    private static LinkAddress findIPv4LinkAddress(LinkProperties lp) {
-        LinkAddress ipv4Address = null;
-        for (LinkAddress address : lp.getLinkAddresses()) {
-            if (!(address.getAddress() instanceof Inet4Address)) {
-                continue;
-            }
-            if (ipv4Address != null && !ipv4Address.isSameAddressAs(address)) {
-                // More than one IPv4 address, abort.
-                return null;
-            }
-            ipv4Address = address;
-        }
-        return ipv4Address;
-    }
-
-    public synchronized void setLinkProperties(LinkProperties lp) {
-        // NOTE: Do not keep a copy of LinkProperties as it would further duplicate state.
-        final LinkAddress ipv4Address = findIPv4LinkAddress(lp);
-        final byte[] addr = (ipv4Address != null) ? ipv4Address.getAddress().getAddress() : null;
-        final int prefix = (ipv4Address != null) ? ipv4Address.getPrefixLength() : 0;
-        if ((prefix == mIPv4PrefixLength) && Arrays.equals(addr, mIPv4Address)) {
-            return;
-        }
-        mIPv4Address = addr;
-        mIPv4PrefixLength = prefix;
-        installNewProgramLocked();
-    }
-
-    /**
-     * Add TCP keepalive ack packet filter.
-     * This will add a filter to drop acks to the keepalive packet passed as an argument.
-     *
-     * @param slot The index used to access the filter.
-     * @param sentKeepalivePacket The attributes of the sent keepalive packet.
-     */
-    public synchronized void addTcpKeepalivePacketFilter(final int slot,
-            final TcpKeepalivePacketDataParcelable sentKeepalivePacket) {
-        log("Adding keepalive ack(" + slot + ")");
-        if (null != mKeepalivePackets.get(slot)) {
-            throw new IllegalArgumentException("Keepalive slot " + slot + " is occupied");
-        }
-        final int ipVersion = sentKeepalivePacket.srcAddress.length == 4 ? 4 : 6;
-        mKeepalivePackets.put(slot, (ipVersion == 4)
-                ? new TcpKeepaliveAckV4(sentKeepalivePacket)
-                : new TcpKeepaliveAckV6(sentKeepalivePacket));
-        installNewProgramLocked();
-    }
-
-    /**
-     * Add NAT-T keepalive packet filter.
-     * This will add a filter to drop NAT-T keepalive packet which is passed as an argument.
-     *
-     * @param slot The index used to access the filter.
-     * @param sentKeepalivePacket The attributes of the sent keepalive packet.
-     */
-    public synchronized void addNattKeepalivePacketFilter(final int slot,
-            final NattKeepalivePacketDataParcelable sentKeepalivePacket) {
-        log("Adding NAT-T keepalive packet(" + slot + ")");
-        if (null != mKeepalivePackets.get(slot)) {
-            throw new IllegalArgumentException("NAT-T Keepalive slot " + slot + " is occupied");
-        }
-        if (sentKeepalivePacket.srcAddress.length != 4) {
-            throw new IllegalArgumentException("NAT-T keepalive is only supported on IPv4");
-        }
-        mKeepalivePackets.put(slot, new NattKeepaliveResponse(sentKeepalivePacket));
-        installNewProgramLocked();
-    }
-
-    /**
-     * Remove keepalive packet filter.
-     *
-     * @param slot The index used to access the filter.
-     */
-    public synchronized void removeKeepalivePacketFilter(int slot) {
-        log("Removing keepalive packet(" + slot + ")");
-        mKeepalivePackets.remove(slot);
-        installNewProgramLocked();
-    }
-
-    static public long counterValue(byte[] data, Counter counter)
-            throws ArrayIndexOutOfBoundsException {
-        // Follow the same wrap-around addressing scheme of the interpreter.
-        int offset = counter.offset();
-        if (offset < 0) {
-            offset = data.length + offset;
-        }
-
-        // Decode 32bit big-endian integer into a long so we can count up beyond 2^31.
-        long value = 0;
-        for (int i = 0; i < 4; i++) {
-            value = value << 8 | (data[offset] & 0xFF);
-            offset++;
-        }
-        return value;
-    }
-
-    public synchronized void dump(IndentingPrintWriter pw) {
-        pw.println("Capabilities: " + mApfCapabilities);
-        pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED"));
-        pw.println("Multicast: " + (mMulticastFilter ? "DROP" : "ALLOW"));
-        try {
-            pw.println("IPv4 address: " + InetAddress.getByAddress(mIPv4Address).getHostAddress());
-        } catch (UnknownHostException|NullPointerException e) {}
-
-        if (mLastTimeInstalledProgram == 0) {
-            pw.println("No program installed.");
-            return;
-        }
-        pw.println("Program updates: " + mNumProgramUpdates);
-        pw.println(String.format(
-                "Last program length %d, installed %ds ago, lifetime %ds",
-                mLastInstalledProgram.length, currentTimeSeconds() - mLastTimeInstalledProgram,
-                mLastInstalledProgramMinLifetime));
-
-        pw.println("RA filters:");
-        pw.increaseIndent();
-        for (Ra ra: mRas) {
-            pw.println(ra);
-            pw.increaseIndent();
-            pw.println(String.format(
-                    "Seen: %d, last %ds ago", ra.seenCount, currentTimeSeconds() - ra.mLastSeen));
-            if (DBG) {
-                pw.println("Last match:");
-                pw.increaseIndent();
-                pw.println(ra.getLastMatchingPacket());
-                pw.decreaseIndent();
-            }
-            pw.decreaseIndent();
-        }
-        pw.decreaseIndent();
-
-        pw.println("TCP Keepalive filters:");
-        pw.increaseIndent();
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket keepalivePacket = mKeepalivePackets.valueAt(i);
-            if (keepalivePacket instanceof TcpKeepaliveAck) {
-                pw.print("Slot ");
-                pw.print(mKeepalivePackets.keyAt(i));
-                pw.print(": ");
-                pw.println(keepalivePacket);
-            }
-        }
-        pw.decreaseIndent();
-
-        pw.println("NAT-T Keepalive filters:");
-        pw.increaseIndent();
-        for (int i = 0; i < mKeepalivePackets.size(); ++i) {
-            final KeepalivePacket keepalivePacket = mKeepalivePackets.valueAt(i);
-            if (keepalivePacket instanceof NattKeepaliveResponse) {
-                pw.print("Slot ");
-                pw.print(mKeepalivePackets.keyAt(i));
-                pw.print(": ");
-                pw.println(keepalivePacket);
-            }
-        }
-        pw.decreaseIndent();
-
-        if (DBG) {
-            pw.println("Last program:");
-            pw.increaseIndent();
-            pw.println(HexDump.toHexString(mLastInstalledProgram, false /* lowercase */));
-            pw.decreaseIndent();
-        }
-
-        pw.println("APF packet counters: ");
-        pw.increaseIndent();
-        if (!mApfCapabilities.hasDataAccess()) {
-            pw.println("APF counters not supported");
-        } else if (mDataSnapshot == null) {
-            pw.println("No last snapshot.");
-        } else {
-            try {
-                Counter[] counters = Counter.class.getEnumConstants();
-                for (Counter c : Arrays.asList(counters).subList(1, counters.length)) {
-                    long value = counterValue(mDataSnapshot, c);
-                    // Only print non-zero counters
-                    if (value != 0) {
-                        pw.println(c.toString() + ": " + value);
-                    }
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-                pw.println("Uh-oh: " + e);
-            }
-            if (VDBG) {
-                pw.println("Raw data dump: ");
-                pw.println(HexDump.dumpHexString(mDataSnapshot));
-            }
-        }
-        pw.decreaseIndent();
-    }
-
-    // TODO: move to android.net.NetworkUtils
-    @VisibleForTesting
-    public static int ipv4BroadcastAddress(byte[] addrBytes, int prefixLength) {
-        return bytesToBEInt(addrBytes) | (int) (Integer.toUnsignedLong(-1) >>> prefixLength);
-    }
-
-    private static int uint8(byte b) {
-        return b & 0xff;
-    }
-
-    private static int getUint16(ByteBuffer buffer, int position) {
-        return buffer.getShort(position) & 0xffff;
-    }
-
-    private static long getUint32(ByteBuffer buffer, int position) {
-        return Integer.toUnsignedLong(buffer.getInt(position));
-    }
-
-    private static int getUint8(ByteBuffer buffer, int position) {
-        return uint8(buffer.get(position));
-    }
-
-    private static int bytesToBEInt(byte[] bytes) {
-        return (uint8(bytes[0]) << 24)
-                + (uint8(bytes[1]) << 16)
-                + (uint8(bytes[2]) << 8)
-                + (uint8(bytes[3]));
-    }
-
-    private static byte[] concatArrays(final byte[]... arr) {
-        int size = 0;
-        for (byte[] a : arr) {
-            size += a.length;
-        }
-        final byte[] result = new byte[size];
-        int offset = 0;
-        for (byte[] a : arr) {
-            System.arraycopy(a, 0, result, offset, a.length);
-            offset += a.length;
-        }
-        return result;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java b/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
deleted file mode 100644
index 44ce2db..0000000
--- a/packages/NetworkStack/src/android/net/apf/ApfGenerator.java
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.apf;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * APF assembler/generator.  A tool for generating an APF program.
- *
- * Call add*() functions to add instructions to the program, then call
- * {@link generate} to get the APF bytecode for the program.
- *
- * @hide
- */
-public class ApfGenerator {
-    /**
-     * This exception is thrown when an attempt is made to generate an illegal instruction.
-     */
-    public static class IllegalInstructionException extends Exception {
-        IllegalInstructionException(String msg) {
-            super(msg);
-        }
-    }
-    private enum Opcodes {
-        LABEL(-1),
-        LDB(1),    // Load 1 byte from immediate offset, e.g. "ldb R0, [5]"
-        LDH(2),    // Load 2 bytes from immediate offset, e.g. "ldh R0, [5]"
-        LDW(3),    // Load 4 bytes from immediate offset, e.g. "ldw R0, [5]"
-        LDBX(4),   // Load 1 byte from immediate offset plus register, e.g. "ldbx R0, [5]R0"
-        LDHX(5),   // Load 2 byte from immediate offset plus register, e.g. "ldhx R0, [5]R0"
-        LDWX(6),   // Load 4 byte from immediate offset plus register, e.g. "ldwx R0, [5]R0"
-        ADD(7),    // Add, e.g. "add R0,5"
-        MUL(8),    // Multiply, e.g. "mul R0,5"
-        DIV(9),    // Divide, e.g. "div R0,5"
-        AND(10),   // And, e.g. "and R0,5"
-        OR(11),    // Or, e.g. "or R0,5"
-        SH(12),    // Left shift, e.g, "sh R0, 5" or "sh R0, -5" (shifts right)
-        LI(13),    // Load immediate, e.g. "li R0,5" (immediate encoded as signed value)
-        JMP(14),   // Jump, e.g. "jmp label"
-        JEQ(15),   // Compare equal and branch, e.g. "jeq R0,5,label"
-        JNE(16),   // Compare not equal and branch, e.g. "jne R0,5,label"
-        JGT(17),   // Compare greater than and branch, e.g. "jgt R0,5,label"
-        JLT(18),   // Compare less than and branch, e.g. "jlt R0,5,label"
-        JSET(19),  // Compare any bits set and branch, e.g. "jset R0,5,label"
-        JNEBS(20), // Compare not equal byte sequence, e.g. "jnebs R0,5,label,0x1122334455"
-        EXT(21),   // Followed by immediate indicating ExtendedOpcodes.
-        LDDW(22),  // Load 4 bytes from data memory address (register + immediate): "lddw R0, [5]R1"
-        STDW(23);  // Store 4 bytes to data memory address (register + immediate): "stdw R0, [5]R1"
-
-        final int value;
-
-        private Opcodes(int value) {
-            this.value = value;
-        }
-    }
-    // Extended opcodes. Primary opcode is Opcodes.EXT. ExtendedOpcodes are encoded in the immediate
-    // field.
-    private enum ExtendedOpcodes {
-        LDM(0),   // Load from memory, e.g. "ldm R0,5"
-        STM(16),  // Store to memory, e.g. "stm R0,5"
-        NOT(32),  // Not, e.g. "not R0"
-        NEG(33),  // Negate, e.g. "neg R0"
-        SWAP(34), // Swap, e.g. "swap R0,R1"
-        MOVE(35);  // Move, e.g. "move R0,R1"
-
-        final int value;
-
-        private ExtendedOpcodes(int value) {
-            this.value = value;
-        }
-    }
-    public enum Register {
-        R0(0),
-        R1(1);
-
-        final int value;
-
-        private Register(int value) {
-            this.value = value;
-        }
-    }
-    private class Instruction {
-        private final byte mOpcode;   // A "Opcode" value.
-        private final byte mRegister; // A "Register" value.
-        private boolean mHasImm;
-        private byte mImmSize;
-        private boolean mImmSigned;
-        private int mImm;
-        // When mOpcode is a jump:
-        private byte mTargetLabelSize;
-        private String mTargetLabel;
-        // When mOpcode == Opcodes.LABEL:
-        private String mLabel;
-        // When mOpcode == Opcodes.JNEBS:
-        private byte[] mCompareBytes;
-        // Offset in bytes from the beginning of this program. Set by {@link ApfGenerator#generate}.
-        int offset;
-
-        Instruction(Opcodes opcode, Register register) {
-            mOpcode = (byte)opcode.value;
-            mRegister = (byte)register.value;
-        }
-
-        Instruction(Opcodes opcode) {
-            this(opcode, Register.R0);
-        }
-
-        void setImm(int imm, boolean signed) {
-            mHasImm = true;
-            mImm = imm;
-            mImmSigned = signed;
-            mImmSize = calculateImmSize(imm, signed);
-        }
-
-        void setUnsignedImm(int imm) {
-            setImm(imm, false);
-        }
-
-        void setSignedImm(int imm) {
-            setImm(imm, true);
-        }
-
-        void setLabel(String label) throws IllegalInstructionException {
-            if (mLabels.containsKey(label)) {
-                throw new IllegalInstructionException("duplicate label " + label);
-            }
-            if (mOpcode != Opcodes.LABEL.value) {
-                throw new IllegalStateException("adding label to non-label instruction");
-            }
-            mLabel = label;
-            mLabels.put(label, this);
-        }
-
-        void setTargetLabel(String label) {
-            mTargetLabel = label;
-            mTargetLabelSize = 4; // May shrink later on in generate().
-        }
-
-        void setCompareBytes(byte[] bytes) {
-            if (mOpcode != Opcodes.JNEBS.value) {
-                throw new IllegalStateException("adding compare bytes to non-JNEBS instruction");
-            }
-            mCompareBytes = bytes;
-        }
-
-        /**
-         * @return size of instruction in bytes.
-         */
-        int size() {
-            if (mOpcode == Opcodes.LABEL.value) {
-                return 0;
-            }
-            int size = 1;
-            if (mHasImm) {
-                size += generatedImmSize();
-            }
-            if (mTargetLabel != null) {
-                size += generatedImmSize();
-            }
-            if (mCompareBytes != null) {
-                size += mCompareBytes.length;
-            }
-            return size;
-        }
-
-        /**
-         * Resize immediate value field so that it's only as big as required to
-         * contain the offset of the jump destination.
-         * @return {@code true} if shrunk.
-         */
-        boolean shrink() throws IllegalInstructionException {
-            if (mTargetLabel == null) {
-                return false;
-            }
-            int oldSize = size();
-            int oldTargetLabelSize = mTargetLabelSize;
-            mTargetLabelSize = calculateImmSize(calculateTargetLabelOffset(), false);
-            if (mTargetLabelSize > oldTargetLabelSize) {
-                throw new IllegalStateException("instruction grew");
-            }
-            return size() < oldSize;
-        }
-
-        /**
-         * Assemble value for instruction size field.
-         */
-        private byte generateImmSizeField() {
-            byte immSize = generatedImmSize();
-            // Encode size field to fit in 2 bits: 0->0, 1->1, 2->2, 3->4.
-            return immSize == 4 ? 3 : immSize;
-        }
-
-        /**
-         * Assemble first byte of generated instruction.
-         */
-        private byte generateInstructionByte() {
-            byte sizeField = generateImmSizeField();
-            return (byte)((mOpcode << 3) | (sizeField << 1) | mRegister);
-        }
-
-        /**
-         * Write {@code value} at offset {@code writingOffset} into {@code bytecode}.
-         * {@link generatedImmSize} bytes are written. {@code value} is truncated to
-         * {@code generatedImmSize} bytes. {@code value} is treated simply as a
-         * 32-bit value, so unsigned values should be zero extended and the truncation
-         * should simply throw away their zero-ed upper bits, and signed values should
-         * be sign extended and the truncation should simply throw away their signed
-         * upper bits.
-         */
-        private int writeValue(int value, byte[] bytecode, int writingOffset) {
-            for (int i = generatedImmSize() - 1; i >= 0; i--) {
-                bytecode[writingOffset++] = (byte)((value >> (i * 8)) & 255);
-            }
-            return writingOffset;
-        }
-
-        /**
-         * Generate bytecode for this instruction at offset {@link offset}.
-         */
-        void generate(byte[] bytecode) throws IllegalInstructionException {
-            if (mOpcode == Opcodes.LABEL.value) {
-                return;
-            }
-            int writingOffset = offset;
-            bytecode[writingOffset++] = generateInstructionByte();
-            if (mTargetLabel != null) {
-                writingOffset = writeValue(calculateTargetLabelOffset(), bytecode, writingOffset);
-            }
-            if (mHasImm) {
-                writingOffset = writeValue(mImm, bytecode, writingOffset);
-            }
-            if (mCompareBytes != null) {
-                System.arraycopy(mCompareBytes, 0, bytecode, writingOffset, mCompareBytes.length);
-                writingOffset += mCompareBytes.length;
-            }
-            if ((writingOffset - offset) != size()) {
-                throw new IllegalStateException("wrote " + (writingOffset - offset) +
-                        " but should have written " + size());
-            }
-        }
-
-        /**
-         * Calculate the size of either the immediate field or the target label field, if either is
-         * present. Most instructions have either an immediate or a target label field, but for the
-         * instructions that have both, the size of the target label field must be the same as the
-         * size of the immediate field, because there is only one length field in the instruction
-         * byte, hence why this function simply takes the maximum of the two sizes, so neither is
-         * truncated.
-         */
-        private byte generatedImmSize() {
-            return mImmSize > mTargetLabelSize ? mImmSize : mTargetLabelSize;
-        }
-
-        private int calculateTargetLabelOffset() throws IllegalInstructionException {
-            Instruction targetLabelInstruction;
-            if (mTargetLabel == DROP_LABEL) {
-                targetLabelInstruction = mDropLabel;
-            } else if (mTargetLabel == PASS_LABEL) {
-                targetLabelInstruction = mPassLabel;
-            } else {
-                targetLabelInstruction = mLabels.get(mTargetLabel);
-            }
-            if (targetLabelInstruction == null) {
-                throw new IllegalInstructionException("label not found: " + mTargetLabel);
-            }
-            // Calculate distance from end of this instruction to instruction.offset.
-            final int targetLabelOffset = targetLabelInstruction.offset - (offset + size());
-            if (targetLabelOffset < 0) {
-                throw new IllegalInstructionException("backward branches disallowed; label: " +
-                        mTargetLabel);
-            }
-            return targetLabelOffset;
-        }
-
-        private byte calculateImmSize(int imm, boolean signed) {
-            if (imm == 0) {
-                return 0;
-            }
-            if (signed && (imm >= -128 && imm <= 127) ||
-                    !signed && (imm >= 0 && imm <= 255)) {
-                return 1;
-            }
-            if (signed && (imm >= -32768 && imm <= 32767) ||
-                    !signed && (imm >= 0 && imm <= 65535)) {
-                return 2;
-            }
-            return 4;
-        }
-    }
-
-    /**
-     * Jump to this label to terminate the program and indicate the packet
-     * should be dropped.
-     */
-    public static final String DROP_LABEL = "__DROP__";
-
-    /**
-     * Jump to this label to terminate the program and indicate the packet
-     * should be passed to the AP.
-     */
-    public static final String PASS_LABEL = "__PASS__";
-
-    /**
-     * Number of memory slots available for access via APF stores to memory and loads from memory.
-     * The memory slots are numbered 0 to {@code MEMORY_SLOTS} - 1. This must be kept in sync with
-     * the APF interpreter.
-     */
-    public static final int MEMORY_SLOTS = 16;
-
-    /**
-     * Memory slot number that is prefilled with the IPv4 header length.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with
-     * the APF interpreter.
-     */
-    public static final int IPV4_HEADER_SIZE_MEMORY_SLOT = 13;
-
-    /**
-     * Memory slot number that is prefilled with the size of the packet being filtered in bytes.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with the APF interpreter.
-     */
-    public static final int PACKET_SIZE_MEMORY_SLOT = 14;
-
-    /**
-     * Memory slot number that is prefilled with the age of the filter in seconds. The age of the
-     * filter is the time since the filter was installed until now.
-     * Note that this memory slot may be overwritten by a program that
-     * executes stores to this memory slot. This must be kept in sync with the APF interpreter.
-     */
-    public static final int FILTER_AGE_MEMORY_SLOT = 15;
-
-    /**
-     * First memory slot containing prefilled values. Can be used in range comparisons to determine
-     * if memory slot index is within prefilled slots.
-     */
-    public static final int FIRST_PREFILLED_MEMORY_SLOT = IPV4_HEADER_SIZE_MEMORY_SLOT;
-
-    /**
-     * Last memory slot containing prefilled values. Can be used in range comparisons to determine
-     * if memory slot index is within prefilled slots.
-     */
-    public static final int LAST_PREFILLED_MEMORY_SLOT = FILTER_AGE_MEMORY_SLOT;
-
-    // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h
-    private static final int MIN_APF_VERSION = 2;
-
-    private final ArrayList<Instruction> mInstructions = new ArrayList<Instruction>();
-    private final HashMap<String, Instruction> mLabels = new HashMap<String, Instruction>();
-    private final Instruction mDropLabel = new Instruction(Opcodes.LABEL);
-    private final Instruction mPassLabel = new Instruction(Opcodes.LABEL);
-    private final int mVersion;
-    private boolean mGenerated;
-
-    /**
-     * Creates an ApfGenerator instance which is able to emit instructions for the specified
-     * {@code version} of the APF interpreter. Throws {@code IllegalInstructionException} if
-     * the requested version is unsupported.
-     */
-    ApfGenerator(int version) throws IllegalInstructionException {
-        mVersion = version;
-        requireApfVersion(MIN_APF_VERSION);
-    }
-
-    /**
-     * Returns true if the ApfGenerator supports the specified {@code version}, otherwise false.
-     */
-    public static boolean supportsVersion(int version) {
-        return version >= MIN_APF_VERSION;
-    }
-
-    private void requireApfVersion(int minimumVersion) throws IllegalInstructionException {
-        if (mVersion < minimumVersion) {
-            throw new IllegalInstructionException("Requires APF >= " + minimumVersion);
-        }
-    }
-
-    private void addInstruction(Instruction instruction) {
-        if (mGenerated) {
-            throw new IllegalStateException("Program already generated");
-        }
-        mInstructions.add(instruction);
-    }
-
-    /**
-     * Define a label at the current end of the program. Jumps can jump to this label. Labels are
-     * their own separate instructions, though with size 0. This facilitates having labels with
-     * no corresponding code to execute, for example a label at the end of a program. For example
-     * an {@link ApfGenerator} might be passed to a function that adds a filter like so:
-     * <pre>
-     *   load from packet
-     *   compare loaded data, jump if not equal to "next_filter"
-     *   load from packet
-     *   compare loaded data, jump if not equal to "next_filter"
-     *   jump to drop label
-     *   define "next_filter" here
-     * </pre>
-     * In this case "next_filter" may not have any generated code associated with it.
-     */
-    public ApfGenerator defineLabel(String name) throws IllegalInstructionException {
-        Instruction instruction = new Instruction(Opcodes.LABEL);
-        instruction.setLabel(name);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an unconditional jump instruction to the end of the program.
-     */
-    public ApfGenerator addJump(String target) {
-        Instruction instruction = new Instruction(Opcodes.JMP);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load the byte at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad8(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDB, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 16-bits at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad16(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDH, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32-bits at offset {@code offset}
-     * bytes from the beginning of the packet into {@code register}.
-     */
-    public ApfGenerator addLoad32(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDW, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * 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 beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad8Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDBX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 16-bits from the packet into
-     * {@code register}. The offset of the loaded 16-bits from the beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad16Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDHX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32-bits from the packet into
-     * {@code register}. The offset of the loaded 32-bits from the beginning of the packet is
-     * the sum of {@code offset} and the value in register R1.
-     */
-    public ApfGenerator addLoad32Indexed(Register register, int offset) {
-        Instruction instruction = new Instruction(Opcodes.LDWX, register);
-        instruction.setUnsignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to add {@code value} to register R0.
-     */
-    public ApfGenerator addAdd(int value) {
-        Instruction instruction = new Instruction(Opcodes.ADD);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to multiply register R0 by {@code value}.
-     */
-    public ApfGenerator addMul(int value) {
-        Instruction instruction = new Instruction(Opcodes.MUL);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to divide register R0 by {@code value}.
-     */
-    public ApfGenerator addDiv(int value) {
-        Instruction instruction = new Instruction(Opcodes.DIV);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically and register R0 with {@code value}.
-     */
-    public ApfGenerator addAnd(int value) {
-        Instruction instruction = new Instruction(Opcodes.AND);
-        instruction.setUnsignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically or register R0 with {@code value}.
-     */
-    public ApfGenerator addOr(int value) {
-        Instruction instruction = new Instruction(Opcodes.OR);
-        instruction.setUnsignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift left register R0 by {@code value} bits.
-     */
-    public ApfGenerator addLeftShift(int value) {
-        Instruction instruction = new Instruction(Opcodes.SH);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift right register R0 by {@code value}
-     * bits.
-     */
-    public ApfGenerator addRightShift(int value) {
-        Instruction instruction = new Instruction(Opcodes.SH);
-        instruction.setSignedImm(-value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to add register R1 to register R0.
-     */
-    public ApfGenerator addAddR1() {
-        Instruction instruction = new Instruction(Opcodes.ADD, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to multiply register R0 by register R1.
-     */
-    public ApfGenerator addMulR1() {
-        Instruction instruction = new Instruction(Opcodes.MUL, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to divide register R0 by register R1.
-     */
-    public ApfGenerator addDivR1() {
-        Instruction instruction = new Instruction(Opcodes.DIV, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically and register R0 with register R1
-     * and store the result back into register R0.
-     */
-    public ApfGenerator addAndR1() {
-        Instruction instruction = new Instruction(Opcodes.AND, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically or register R0 with register R1
-     * and store the result back into register R0.
-     */
-    public ApfGenerator addOrR1() {
-        Instruction instruction = new Instruction(Opcodes.OR, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to shift register R0 left by the value in
-     * register R1.
-     */
-    public ApfGenerator addLeftShiftR1() {
-        Instruction instruction = new Instruction(Opcodes.SH, Register.R1);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to move {@code value} into {@code register}.
-     */
-    public ApfGenerator addLoadImmediate(Register register, int value) {
-        Instruction instruction = new Instruction(Opcodes.LI, register);
-        instruction.setSignedImm(value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value equals {@code value}.
-     */
-    public ApfGenerator addJumpIfR0Equals(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JEQ);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value does not equal {@code value}.
-     */
-    public ApfGenerator addJumpIfR0NotEquals(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JNE);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is greater than {@code value}.
-     */
-    public ApfGenerator addJumpIfR0GreaterThan(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JGT);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is less than {@code value}.
-     */
-    public ApfGenerator addJumpIfR0LessThan(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JLT);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value has any bits set that are also set in {@code value}.
-     */
-    public ApfGenerator addJumpIfR0AnyBitsSet(int value, String target) {
-        Instruction instruction = new Instruction(Opcodes.JSET);
-        instruction.setUnsignedImm(value);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value equals register R1's value.
-     */
-    public ApfGenerator addJumpIfR0EqualsR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JEQ, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value does not equal register R1's value.
-     */
-    public ApfGenerator addJumpIfR0NotEqualsR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JNE, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is greater than register R1's value.
-     */
-    public ApfGenerator addJumpIfR0GreaterThanR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JGT, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value is less than register R1's value.
-     */
-    public ApfGenerator addJumpIfR0LessThanR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JLT, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if register R0's
-     * value has any bits set that are also set in R1's value.
-     */
-    public ApfGenerator addJumpIfR0AnyBitsSetR1(String target) {
-        Instruction instruction = new Instruction(Opcodes.JSET, Register.R1);
-        instruction.setTargetLabel(target);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to jump to {@code target} if the bytes of the
-     * packet at an offset specified by {@code register} match {@code bytes}.
-     */
-    public ApfGenerator addJumpIfBytesNotEqual(Register register, byte[] bytes, String target)
-            throws IllegalInstructionException {
-        if (register == Register.R1) {
-            throw new IllegalInstructionException("JNEBS fails with R1");
-        }
-        Instruction instruction = new Instruction(Opcodes.JNEBS, register);
-        instruction.setUnsignedImm(bytes.length);
-        instruction.setTargetLabel(target);
-        instruction.setCompareBytes(bytes);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load memory slot {@code slot} into
-     * {@code register}.
-     */
-    public ApfGenerator addLoadFromMemory(Register register, int slot)
-            throws IllegalInstructionException {
-        if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
-            throw new IllegalInstructionException("illegal memory slot number: " + slot);
-        }
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.LDM.value + slot);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to store {@code register} into memory slot
-     * {@code slot}.
-     */
-    public ApfGenerator addStoreToMemory(Register register, int slot)
-            throws IllegalInstructionException {
-        if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
-            throw new IllegalInstructionException("illegal memory slot number: " + slot);
-        }
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.STM.value + slot);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to logically not {@code register}.
-     */
-    public ApfGenerator addNot(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.NOT.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to negate {@code register}.
-     */
-    public ApfGenerator addNeg(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.NEG.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to swap the values in register R0 and register R1.
-     */
-    public ApfGenerator addSwap() {
-        Instruction instruction = new Instruction(Opcodes.EXT);
-        instruction.setUnsignedImm(ExtendedOpcodes.SWAP.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to move the value into
-     * {@code register} from the other register.
-     */
-    public ApfGenerator addMove(Register register) {
-        Instruction instruction = new Instruction(Opcodes.EXT, register);
-        instruction.setUnsignedImm(ExtendedOpcodes.MOVE.value);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to load 32 bits from the data memory into
-     * {@code register}. The source address is computed by adding the signed immediate
-     * @{code offset} to the other register.
-     * Requires APF v3 or greater.
-     */
-    public ApfGenerator addLoadData(Register destinationRegister, int offset)
-            throws IllegalInstructionException {
-        requireApfVersion(3);
-        Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister);
-        instruction.setSignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Add an instruction to the end of the program to store 32 bits from {@code register} into the
-     * data memory. The destination address is computed by adding the signed immediate
-     * @{code offset} to the other register.
-     * Requires APF v3 or greater.
-     */
-    public ApfGenerator addStoreData(Register sourceRegister, int offset)
-            throws IllegalInstructionException {
-        requireApfVersion(3);
-        Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister);
-        instruction.setSignedImm(offset);
-        addInstruction(instruction);
-        return this;
-    }
-
-    /**
-     * Updates instruction offset fields using latest instruction sizes.
-     * @return current program length in bytes.
-     */
-    private int updateInstructionOffsets() {
-        int offset = 0;
-        for (Instruction instruction : mInstructions) {
-            instruction.offset = offset;
-            offset += instruction.size();
-        }
-        return offset;
-    }
-
-    /**
-     * Returns an overestimate of the size of the generated program. {@link #generate} may return
-     * a program that is smaller.
-     */
-    public int programLengthOverEstimate() {
-        return updateInstructionOffsets();
-    }
-
-    /**
-     * Generate the bytecode for the APF program.
-     * @return the bytecode.
-     * @throws IllegalStateException if a label is referenced but not defined.
-     */
-    public byte[] generate() throws IllegalInstructionException {
-        // Enforce that we can only generate once because we cannot unshrink instructions and
-        // PASS/DROP labels may move further away requiring unshrinking if we add further
-        // instructions.
-        if (mGenerated) {
-            throw new IllegalStateException("Can only generate() once!");
-        }
-        mGenerated = true;
-        int total_size;
-        boolean shrunk;
-        // Shrink the immediate value fields of instructions.
-        // As we shrink the instructions some branch offset
-        // fields may shrink also, thereby shrinking the
-        // instructions further. Loop until we've reached the
-        // minimum size. Rarely will this loop more than a few times.
-        // Limit iterations to avoid O(n^2) behavior.
-        int iterations_remaining = 10;
-        do {
-            total_size = updateInstructionOffsets();
-            // Update drop and pass label offsets.
-            mDropLabel.offset = total_size + 1;
-            mPassLabel.offset = total_size;
-            // Limit run-time in aberant circumstances.
-            if (iterations_remaining-- == 0) break;
-            // Attempt to shrink instructions.
-            shrunk = false;
-            for (Instruction instruction : mInstructions) {
-                if (instruction.shrink()) {
-                    shrunk = true;
-                }
-            }
-        } while (shrunk);
-        // Generate bytecode for instructions.
-        byte[] bytecode = new byte[total_size];
-        for (Instruction instruction : mInstructions) {
-            instruction.generate(bytecode);
-        }
-        return bytecode;
-    }
-}
-
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java
deleted file mode 100644
index b2eb4e2..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpAckPacket.java
+++ /dev/null
@@ -1,88 +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.
- */
-
-package android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-ACK packet.
- */
-class DhcpAckPacket extends DhcpPacket {
-
-    /**
-     * The address of the server which sent this packet.
-     */
-    private final Inet4Address mSrcIp;
-
-    DhcpAckPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
-            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
-        mBroadcast = broadcast;
-        mSrcIp = serverAddress;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        String dnsServers = " DNS servers: ";
-
-        for (Inet4Address dnsServer: mDnsServers) {
-            dnsServers += dnsServer.toString() + " ";
-        }
-
-        return s + " ACK: your new IP " + mYourIp +
-                ", netmask " + mSubnetMask +
-                ", gateways " + mGateways + dnsServers +
-                ", lease time " + mLeaseTime;
-    }
-
-    /**
-     * Fills in a packet with the requested ACK parameters.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
-        Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
-            DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated ACK packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_ACK);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-
-        addCommonServerTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-
-    /**
-     * Un-boxes an Integer, returning 0 if a null reference is supplied.
-     */
-    private static final int getInt(Integer v) {
-        if (v == null) {
-            return 0;
-        } else {
-            return v.intValue();
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java b/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
deleted file mode 100644
index ca6c17a..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpClient.java
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_BROADCAST_ADDRESS;
-import static android.net.dhcp.DhcpPacket.DHCP_DNS_SERVER;
-import static android.net.dhcp.DhcpPacket.DHCP_DOMAIN_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_LEASE_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_MTU;
-import static android.net.dhcp.DhcpPacket.DHCP_REBINDING_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_RENEWAL_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_ROUTER;
-import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK;
-import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
-import static android.net.util.NetworkStackUtils.closeSocketQuietly;
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_RAW;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_BROADCAST;
-import static android.system.OsConstants.SO_RCVBUF;
-import static android.system.OsConstants.SO_REUSEADDR;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import android.content.Context;
-import android.net.DhcpResults;
-import android.net.InetAddresses;
-import android.net.TrafficStats;
-import android.net.ip.IpClient;
-import android.net.metrics.DhcpClientEvent;
-import android.net.metrics.DhcpErrorEvent;
-import android.net.metrics.IpConnectivityLog;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SocketUtils;
-import android.os.Message;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.util.HexDump;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.TrafficStatsConstants;
-import com.android.internal.util.WakeupMessage;
-import com.android.networkstack.R;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Random;
-
-/**
- * A DHCPv4 client.
- *
- * Written to behave similarly to the DhcpStateMachine + dhcpcd 5.5.6 combination used in Android
- * 5.1 and below, as configured on Nexus 6. The interface is the same as DhcpStateMachine.
- *
- * TODO:
- *
- * - Exponential backoff when receiving NAKs (not specified by the RFC, but current behaviour).
- * - Support persisting lease state and support INIT-REBOOT. Android 5.1 does this, but it does not
- *   do so correctly: instead of requesting the lease last obtained on a particular network (e.g., a
- *   given SSID), it requests the last-leased IP address on the same interface, causing a delay if
- *   the server NAKs or a timeout if it doesn't.
- *
- * Known differences from current behaviour:
- *
- * - Does not request the "static routes" option.
- * - Does not support BOOTP servers. DHCP has been around since 1993, should be everywhere now.
- * - Requests the "broadcast" option, but does nothing with it.
- * - Rejects invalid subnet masks such as 255.255.255.1 (current code treats that as 255.255.255.0).
- *
- * @hide
- */
-public class DhcpClient extends StateMachine {
-
-    private static final String TAG = "DhcpClient";
-    private static final boolean DBG = true;
-    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 */
-    private static final String EVENT_INITIAL_BOUND = "InitialBoundState";
-    /** Represents transitions from and to DhcpBoundState via DhcpRenewingState */
-    private static final String EVENT_RENEWING_BOUND = "RenewingBoundState";
-
-    // Timers and timeouts.
-    private static final int SECONDS = 1000;
-    private static final int FIRST_TIMEOUT_MS   =   2 * SECONDS;
-    private static final int MAX_TIMEOUT_MS     = 128 * SECONDS;
-
-    // This is not strictly needed, since the client is asynchronous and implements exponential
-    // backoff. It's maintained for backwards compatibility with the previous DHCP code, which was
-    // a blocking operation with a 30-second timeout. We pick 36 seconds so we can send packets at
-    // t=0, t=2, t=6, t=14, t=30, allowing for 10% jitter.
-    private static final int DHCP_TIMEOUT_MS    =  36 * SECONDS;
-
-    // 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;
-
-    /* Notification from DHCP state machine prior to DHCP discovery/renewal */
-    public static final int CMD_PRE_DHCP_ACTION             = PUBLIC_BASE + 3;
-    /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
-     * success/failure */
-    public static final int CMD_POST_DHCP_ACTION            = PUBLIC_BASE + 4;
-    /* Notification from DHCP state machine before quitting */
-    public static final int CMD_ON_QUIT                     = PUBLIC_BASE + 5;
-
-    /* Command from controller to indicate DHCP discovery/renewal can continue
-     * after pre DHCP action is complete */
-    public static final int CMD_PRE_DHCP_ACTION_COMPLETE    = PUBLIC_BASE + 6;
-
-    /* Command and event notification to/from IpManager requesting the setting
-     * (or clearing) of an IPv4 LinkAddress.
-     */
-    public static final int CMD_CLEAR_LINKADDRESS           = PUBLIC_BASE + 7;
-    public static final int CMD_CONFIGURE_LINKADDRESS       = PUBLIC_BASE + 8;
-    public static final int EVENT_LINKADDRESS_CONFIGURED    = PUBLIC_BASE + 9;
-
-    /* Message.arg1 arguments to CMD_POST_DHCP_ACTION notification */
-    public static final int DHCP_SUCCESS = 1;
-    public static final int DHCP_FAILURE = 2;
-
-    // Internal messages.
-    private static final int PRIVATE_BASE         = IpClient.DHCPCLIENT_CMD_BASE + 100;
-    private static final int CMD_KICK             = PRIVATE_BASE + 1;
-    private static final int CMD_RECEIVED_PACKET  = PRIVATE_BASE + 2;
-    private static final int CMD_TIMEOUT          = PRIVATE_BASE + 3;
-    private static final int CMD_RENEW_DHCP       = PRIVATE_BASE + 4;
-    private static final int CMD_REBIND_DHCP      = PRIVATE_BASE + 5;
-    private static final int CMD_EXPIRE_DHCP      = PRIVATE_BASE + 6;
-
-    // For message logging.
-    private static final Class[] sMessageClasses = { DhcpClient.class };
-    private static final SparseArray<String> sMessageNames =
-            MessageUtils.findMessageNames(sMessageClasses);
-
-    // DHCP parameters that we request.
-    /* package */ static final byte[] REQUESTED_PARAMS = new byte[] {
-        DHCP_SUBNET_MASK,
-        DHCP_ROUTER,
-        DHCP_DNS_SERVER,
-        DHCP_DOMAIN_NAME,
-        DHCP_MTU,
-        DHCP_BROADCAST_ADDRESS,  // TODO: currently ignored.
-        DHCP_LEASE_TIME,
-        DHCP_RENEWAL_TIME,
-        DHCP_REBINDING_TIME,
-        DHCP_VENDOR_INFO,
-    };
-
-    // DHCP flag that means "yes, we support unicast."
-    private static final boolean DO_UNICAST   = false;
-
-    // System services / libraries we use.
-    private final Context mContext;
-    private final Random mRandom;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-
-    // Sockets.
-    // - We use a packet socket to receive, because servers send us packets bound for IP addresses
-    //   which we have not yet configured, and the kernel protocol stack drops these.
-    // - We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can
-    //   be off-link as well as on-link).
-    private FileDescriptor mPacketSock;
-    private FileDescriptor mUdpSock;
-    private ReceiveThread mReceiveThread;
-
-    // State variables.
-    private final StateMachine mController;
-    private final WakeupMessage mKickAlarm;
-    private final WakeupMessage mTimeoutAlarm;
-    private final WakeupMessage mRenewAlarm;
-    private final WakeupMessage mRebindAlarm;
-    private final WakeupMessage mExpiryAlarm;
-    private final String mIfaceName;
-
-    private boolean mRegisteredForPreDhcpNotification;
-    private InterfaceParams mIface;
-    // TODO: MacAddress-ify more of this class hierarchy.
-    private byte[] mHwAddr;
-    private SocketAddress mInterfaceBroadcastAddr;
-    private int mTransactionId;
-    private long mTransactionStartMillis;
-    private DhcpResults mDhcpLease;
-    private long mDhcpLeaseExpiry;
-    private DhcpResults mOffer;
-
-    // Milliseconds SystemClock timestamps used to record transition times to DhcpBoundState.
-    private long mLastInitEnterTime;
-    private long mLastBoundExitTime;
-
-    // States.
-    private State mStoppedState = new StoppedState();
-    private State mDhcpState = new DhcpState();
-    private State mDhcpInitState = new DhcpInitState();
-    private State mDhcpSelectingState = new DhcpSelectingState();
-    private State mDhcpRequestingState = new DhcpRequestingState();
-    private State mDhcpHaveLeaseState = new DhcpHaveLeaseState();
-    private State mConfiguringInterfaceState = new ConfiguringInterfaceState();
-    private State mDhcpBoundState = new DhcpBoundState();
-    private State mDhcpRenewingState = new DhcpRenewingState();
-    private State mDhcpRebindingState = new DhcpRebindingState();
-    private State mDhcpInitRebootState = new DhcpInitRebootState();
-    private State mDhcpRebootingState = new DhcpRebootingState();
-    private State mWaitBeforeStartState = new WaitBeforeStartState(mDhcpInitState);
-    private State mWaitBeforeRenewalState = new WaitBeforeRenewalState(mDhcpRenewingState);
-
-    private WakeupMessage makeWakeupMessage(String cmdName, int cmd) {
-        cmdName = DhcpClient.class.getSimpleName() + "." + mIfaceName + "." + cmdName;
-        return new WakeupMessage(mContext, getHandler(), cmdName, cmd);
-    }
-
-    // TODO: Take an InterfaceParams instance instead of an interface name String.
-    private DhcpClient(Context context, StateMachine controller, String iface) {
-        super(TAG, controller.getHandler());
-
-        mContext = context;
-        mController = controller;
-        mIfaceName = iface;
-
-        addState(mStoppedState);
-        addState(mDhcpState);
-            addState(mDhcpInitState, mDhcpState);
-            addState(mWaitBeforeStartState, mDhcpState);
-            addState(mDhcpSelectingState, mDhcpState);
-            addState(mDhcpRequestingState, mDhcpState);
-            addState(mDhcpHaveLeaseState, mDhcpState);
-                addState(mConfiguringInterfaceState, mDhcpHaveLeaseState);
-                addState(mDhcpBoundState, mDhcpHaveLeaseState);
-                addState(mWaitBeforeRenewalState, mDhcpHaveLeaseState);
-                addState(mDhcpRenewingState, mDhcpHaveLeaseState);
-                addState(mDhcpRebindingState, mDhcpHaveLeaseState);
-            addState(mDhcpInitRebootState, mDhcpState);
-            addState(mDhcpRebootingState, mDhcpState);
-
-        setInitialState(mStoppedState);
-
-        mRandom = new Random();
-
-        // Used to schedule packet retransmissions.
-        mKickAlarm = makeWakeupMessage("KICK", CMD_KICK);
-        // Used to time out PacketRetransmittingStates.
-        mTimeoutAlarm = makeWakeupMessage("TIMEOUT", CMD_TIMEOUT);
-        // Used to schedule DHCP reacquisition.
-        mRenewAlarm = makeWakeupMessage("RENEW", CMD_RENEW_DHCP);
-        mRebindAlarm = makeWakeupMessage("REBIND", CMD_REBIND_DHCP);
-        mExpiryAlarm = makeWakeupMessage("EXPIRY", CMD_EXPIRE_DHCP);
-    }
-
-    public void registerForPreDhcpNotification() {
-        mRegisteredForPreDhcpNotification = true;
-    }
-
-    public static DhcpClient makeDhcpClient(
-            Context context, StateMachine controller, InterfaceParams ifParams) {
-        DhcpClient client = new DhcpClient(context, controller, ifParams.name);
-        client.mIface = ifParams;
-        client.start();
-        return client;
-    }
-
-    private boolean initInterface() {
-        if (mIface == null) mIface = InterfaceParams.getByName(mIfaceName);
-        if (mIface == null) {
-            Log.e(TAG, "Can't determine InterfaceParams for " + mIfaceName);
-            return false;
-        }
-
-        mHwAddr = mIface.macAddr.toByteArray();
-        mInterfaceBroadcastAddr = makePacketSocketAddress(mIface.index, DhcpPacket.ETHER_BROADCAST);
-        return true;
-    }
-
-    private void startNewTransaction() {
-        mTransactionId = mRandom.nextInt();
-        mTransactionStartMillis = SystemClock.elapsedRealtime();
-    }
-
-    private boolean initSockets() {
-        return initPacketSocket() && initUdpSocket();
-    }
-
-    private boolean initPacketSocket() {
-        try {
-            mPacketSock = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IP);
-            SocketAddress addr = makePacketSocketAddress((short) ETH_P_IP, mIface.index);
-            Os.bind(mPacketSock, addr);
-            NetworkStackUtils.attachDhcpFilter(mPacketSock);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error creating packet socket", e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean initUdpSocket() {
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_DHCP);
-        try {
-            mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-            SocketUtils.bindSocketToInterface(mUdpSock, mIfaceName);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_BROADCAST, 1);
-            Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_RCVBUF, 0);
-            Os.bind(mUdpSock, IPV4_ADDR_ANY, DhcpPacket.DHCP_CLIENT);
-        } catch(SocketException|ErrnoException e) {
-            Log.e(TAG, "Error creating UDP socket", e);
-            return false;
-        } finally {
-            TrafficStats.setThreadStatsTag(oldTag);
-        }
-        return true;
-    }
-
-    private boolean connectUdpSock(Inet4Address to) {
-        try {
-            Os.connect(mUdpSock, to, DhcpPacket.DHCP_SERVER);
-            return true;
-        } catch (SocketException|ErrnoException e) {
-            Log.e(TAG, "Error connecting UDP socket", e);
-            return false;
-        }
-    }
-
-    private void closeSockets() {
-        closeSocketQuietly(mUdpSock);
-        closeSocketQuietly(mPacketSock);
-    }
-
-    class ReceiveThread extends Thread {
-
-        private final byte[] mPacket = new byte[DhcpPacket.MAX_LENGTH];
-        private volatile boolean mStopped = false;
-
-        public void halt() {
-            mStopped = true;
-            closeSockets();  // Interrupts the read() call the thread is blocked in.
-        }
-
-        @Override
-        public void run() {
-            if (DBG) Log.d(TAG, "Receive thread started");
-            while (!mStopped) {
-                int length = 0;  // Or compiler can't tell it's initialized if a parse error occurs.
-                try {
-                    length = Os.read(mPacketSock, mPacket, 0, mPacket.length);
-                    DhcpPacket packet = null;
-                    packet = DhcpPacket.decodeFullPacket(mPacket, length, DhcpPacket.ENCAP_L2);
-                    if (DBG) Log.d(TAG, "Received packet: " + packet);
-                    sendMessage(CMD_RECEIVED_PACKET, packet);
-                } catch (IOException|ErrnoException e) {
-                    if (!mStopped) {
-                        Log.e(TAG, "Read error", e);
-                        logError(DhcpErrorEvent.RECEIVE_ERROR);
-                    }
-                } catch (DhcpPacket.ParseException e) {
-                    Log.e(TAG, "Can't parse packet: " + e.getMessage());
-                    if (PACKET_DBG) {
-                        Log.d(TAG, HexDump.dumpHexString(mPacket, 0, length));
-                    }
-                    if (e.errorCode == DhcpErrorEvent.DHCP_NO_COOKIE) {
-                        int snetTagId = 0x534e4554;
-                        String bugId = "31850211";
-                        int uid = -1;
-                        String data = DhcpPacket.ParseException.class.getName();
-                        EventLog.writeEvent(snetTagId, bugId, uid, data);
-                    }
-                    logError(e.errorCode);
-                }
-            }
-            if (DBG) Log.d(TAG, "Receive thread stopped");
-        }
-    }
-
-    private short getSecs() {
-        return (short) ((SystemClock.elapsedRealtime() - mTransactionStartMillis) / 1000);
-    }
-
-    private boolean transmitPacket(ByteBuffer buf, String description, int encap, Inet4Address to) {
-        try {
-            if (encap == DhcpPacket.ENCAP_L2) {
-                if (DBG) Log.d(TAG, "Broadcasting " + description);
-                Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
-            } else if (encap == DhcpPacket.ENCAP_BOOTP && to.equals(INADDR_BROADCAST)) {
-                if (DBG) Log.d(TAG, "Broadcasting " + description);
-                // We only send L3-encapped broadcasts in DhcpRebindingState,
-                // where we have an IP address and an unconnected UDP socket.
-                //
-                // N.B.: We only need this codepath because DhcpRequestPacket
-                // hardcodes the source IP address to 0.0.0.0. We could reuse
-                // the packet socket if this ever changes.
-                Os.sendto(mUdpSock, buf, 0, to, DhcpPacket.DHCP_SERVER);
-            } else {
-                // It's safe to call getpeername here, because we only send unicast packets if we
-                // have an IP address, and we connect the UDP socket in DhcpBoundState#enter.
-                if (DBG) Log.d(TAG, String.format("Unicasting %s to %s",
-                        description, Os.getpeername(mUdpSock)));
-                Os.write(mUdpSock, buf);
-            }
-        } catch(ErrnoException|IOException e) {
-            Log.e(TAG, "Can't send packet: ", e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean sendDiscoverPacket() {
-        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
-                DhcpPacket.ENCAP_L2, mTransactionId, getSecs(), mHwAddr,
-                DO_UNICAST, REQUESTED_PARAMS);
-        return transmitPacket(packet, "DHCPDISCOVER", DhcpPacket.ENCAP_L2, INADDR_BROADCAST);
-    }
-
-    private boolean sendRequestPacket(
-            Inet4Address clientAddress, Inet4Address requestedAddress,
-            Inet4Address serverAddress, Inet4Address to) {
-        // TODO: should we use the transaction ID from the server?
-        final int encap = INADDR_ANY.equals(clientAddress)
-                ? DhcpPacket.ENCAP_L2 : DhcpPacket.ENCAP_BOOTP;
-
-        ByteBuffer packet = DhcpPacket.buildRequestPacket(
-                encap, mTransactionId, getSecs(), clientAddress,
-                DO_UNICAST, mHwAddr, requestedAddress,
-                serverAddress, REQUESTED_PARAMS, null);
-        String serverStr = (serverAddress != null) ? serverAddress.getHostAddress() : null;
-        String description = "DHCPREQUEST ciaddr=" + clientAddress.getHostAddress() +
-                             " request=" + requestedAddress.getHostAddress() +
-                             " serverid=" + serverStr;
-        return transmitPacket(packet, description, encap, to);
-    }
-
-    private void scheduleLeaseTimers() {
-        if (mDhcpLeaseExpiry == 0) {
-            Log.d(TAG, "Infinite lease, no timer scheduling needed");
-            return;
-        }
-
-        final long now = SystemClock.elapsedRealtime();
-
-        // TODO: consider getting the renew and rebind timers from T1 and T2.
-        // See also:
-        //     https://tools.ietf.org/html/rfc2131#section-4.4.5
-        //     https://tools.ietf.org/html/rfc1533#section-9.9
-        //     https://tools.ietf.org/html/rfc1533#section-9.10
-        final long remainingDelay = mDhcpLeaseExpiry - now;
-        final long renewDelay = remainingDelay / 2;
-        final long rebindDelay = remainingDelay * 7 / 8;
-        mRenewAlarm.schedule(now + renewDelay);
-        mRebindAlarm.schedule(now + rebindDelay);
-        mExpiryAlarm.schedule(now + remainingDelay);
-        Log.d(TAG, "Scheduling renewal in " + (renewDelay / 1000) + "s");
-        Log.d(TAG, "Scheduling rebind in " + (rebindDelay / 1000) + "s");
-        Log.d(TAG, "Scheduling expiry in " + (remainingDelay / 1000) + "s");
-    }
-
-    private void notifySuccess() {
-        mController.sendMessage(
-                CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
-    }
-
-    private void notifyFailure() {
-        mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null);
-    }
-
-    private void acceptDhcpResults(DhcpResults results, String msg) {
-        mDhcpLease = results;
-        if (mDhcpLease.dnsServers.isEmpty()) {
-            // supplement customized dns servers
-            String[] dnsServersList =
-                    mContext.getResources().getStringArray(R.array.config_default_dns_servers);
-            for (final String dnsServer : dnsServersList) {
-                try {
-                    mDhcpLease.dnsServers.add(InetAddresses.parseNumericAddress(dnsServer));
-                } catch (IllegalArgumentException e) {
-                    Log.e(TAG, "Invalid default DNS server: " + dnsServer, e);
-                }
-            }
-        }
-        mOffer = null;
-        Log.d(TAG, msg + " lease: " + mDhcpLease);
-        notifySuccess();
-    }
-
-    private void clearDhcpState() {
-        mDhcpLease = null;
-        mDhcpLeaseExpiry = 0;
-        mOffer = null;
-    }
-
-    /**
-     * Quit the DhcpStateMachine.
-     *
-     * @hide
-     */
-    public void doQuit() {
-        Log.d(TAG, "doQuit");
-        quit();
-    }
-
-    @Override
-    protected void onQuitting() {
-        Log.d(TAG, "onQuitting");
-        mController.sendMessage(CMD_ON_QUIT);
-    }
-
-    abstract class LoggingState extends State {
-        private long mEnterTimeMs;
-
-        @Override
-        public void enter() {
-            if (STATE_DBG) Log.d(TAG, "Entering state " + getName());
-            mEnterTimeMs = SystemClock.elapsedRealtime();
-        }
-
-        @Override
-        public void exit() {
-            long durationMs = SystemClock.elapsedRealtime() - mEnterTimeMs;
-            logState(getName(), (int) durationMs);
-        }
-
-        private String messageName(int what) {
-            return sMessageNames.get(what, Integer.toString(what));
-        }
-
-        private String messageToString(Message message) {
-            long now = SystemClock.uptimeMillis();
-            return new StringBuilder(" ")
-                    .append(message.getWhen() - now)
-                    .append(messageName(message.what))
-                    .append(" ").append(message.arg1)
-                    .append(" ").append(message.arg2)
-                    .append(" ").append(message.obj)
-                    .toString();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (MSG_DBG) {
-                Log.d(TAG, getName() + messageToString(message));
-            }
-            return NOT_HANDLED;
-        }
-
-        @Override
-        public String getName() {
-            // All DhcpClient's states are inner classes with a well defined name.
-            // Use getSimpleName() and avoid super's getName() creating new String instances.
-            return getClass().getSimpleName();
-        }
-    }
-
-    // Sends CMD_PRE_DHCP_ACTION to the controller, waits for the controller to respond with
-    // CMD_PRE_DHCP_ACTION_COMPLETE, and then transitions to mOtherState.
-    abstract class WaitBeforeOtherState extends LoggingState {
-        protected State mOtherState;
-
-        @Override
-        public void enter() {
-            super.enter();
-            mController.sendMessage(CMD_PRE_DHCP_ACTION);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_PRE_DHCP_ACTION_COMPLETE:
-                    transitionTo(mOtherState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class StoppedState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_START_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        transitionTo(mWaitBeforeStartState);
-                    } else {
-                        transitionTo(mDhcpInitState);
-                    }
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class WaitBeforeStartState extends WaitBeforeOtherState {
-        public WaitBeforeStartState(State otherState) {
-            super();
-            mOtherState = otherState;
-        }
-    }
-
-    class WaitBeforeRenewalState extends WaitBeforeOtherState {
-        public WaitBeforeRenewalState(State otherState) {
-            super();
-            mOtherState = otherState;
-        }
-    }
-
-    class DhcpState extends State {
-        @Override
-        public void enter() {
-            clearDhcpState();
-            if (initInterface() && initSockets()) {
-                mReceiveThread = new ReceiveThread();
-                mReceiveThread.start();
-            } else {
-                notifyFailure();
-                transitionTo(mStoppedState);
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mReceiveThread != null) {
-                mReceiveThread.halt();  // Also closes sockets.
-                mReceiveThread = null;
-            }
-            clearDhcpState();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_STOP_DHCP:
-                    transitionTo(mStoppedState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    public boolean isValidPacket(DhcpPacket packet) {
-        // TODO: check checksum.
-        int xid = packet.getTransactionId();
-        if (xid != mTransactionId) {
-            Log.d(TAG, "Unexpected transaction ID " + xid + ", expected " + mTransactionId);
-            return false;
-        }
-        if (!Arrays.equals(packet.getClientMac(), mHwAddr)) {
-            Log.d(TAG, "MAC addr mismatch: got " +
-                    HexDump.toHexString(packet.getClientMac()) + ", expected " +
-                    HexDump.toHexString(packet.getClientMac()));
-            return false;
-        }
-        return true;
-    }
-
-    public void setDhcpLeaseExpiry(DhcpPacket packet) {
-        long leaseTimeMillis = packet.getLeaseTimeMillis();
-        mDhcpLeaseExpiry =
-                (leaseTimeMillis > 0) ? SystemClock.elapsedRealtime() + leaseTimeMillis : 0;
-    }
-
-    /**
-     * Retransmits packets using jittered exponential backoff with an optional timeout. Packet
-     * transmission is triggered by CMD_KICK, which is sent by an AlarmManager alarm. If a subclass
-     * sets mTimeout to a positive value, then timeout() is called by an AlarmManager alarm mTimeout
-     * milliseconds after entering the state. Kicks and timeouts are cancelled when leaving the
-     * state.
-     *
-     * Concrete subclasses must implement sendPacket, which is called when the alarm fires and a
-     * packet needs to be transmitted, and receivePacket, which is triggered by CMD_RECEIVED_PACKET
-     * sent by the receive thread. They may also set mTimeout and implement timeout.
-     */
-    abstract class PacketRetransmittingState extends LoggingState {
-
-        private int mTimer;
-        protected int mTimeout = 0;
-
-        @Override
-        public void enter() {
-            super.enter();
-            initTimer();
-            maybeInitTimeout();
-            sendMessage(CMD_KICK);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_KICK:
-                    sendPacket();
-                    scheduleKick();
-                    return HANDLED;
-                case CMD_RECEIVED_PACKET:
-                    receivePacket((DhcpPacket) message.obj);
-                    return HANDLED;
-                case CMD_TIMEOUT:
-                    timeout();
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            super.exit();
-            mKickAlarm.cancel();
-            mTimeoutAlarm.cancel();
-        }
-
-        abstract protected boolean sendPacket();
-        abstract protected void receivePacket(DhcpPacket packet);
-        protected void timeout() {}
-
-        protected void initTimer() {
-            mTimer = FIRST_TIMEOUT_MS;
-        }
-
-        protected int jitterTimer(int baseTimer) {
-            int maxJitter = baseTimer / 10;
-            int jitter = mRandom.nextInt(2 * maxJitter) - maxJitter;
-            return baseTimer + jitter;
-        }
-
-        protected void scheduleKick() {
-            long now = SystemClock.elapsedRealtime();
-            long timeout = jitterTimer(mTimer);
-            long alarmTime = now + timeout;
-            mKickAlarm.schedule(alarmTime);
-            mTimer *= 2;
-            if (mTimer > MAX_TIMEOUT_MS) {
-                mTimer = MAX_TIMEOUT_MS;
-            }
-        }
-
-        protected void maybeInitTimeout() {
-            if (mTimeout > 0) {
-                long alarmTime = SystemClock.elapsedRealtime() + mTimeout;
-                mTimeoutAlarm.schedule(alarmTime);
-            }
-        }
-    }
-
-    class DhcpInitState extends PacketRetransmittingState {
-        public DhcpInitState() {
-            super();
-        }
-
-        @Override
-        public void enter() {
-            super.enter();
-            startNewTransaction();
-            mLastInitEnterTime = SystemClock.elapsedRealtime();
-        }
-
-        protected boolean sendPacket() {
-            return sendDiscoverPacket();
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if (!(packet instanceof DhcpOfferPacket)) return;
-            mOffer = packet.toDhcpResults();
-            if (mOffer != null) {
-                Log.d(TAG, "Got pending lease: " + mOffer);
-                transitionTo(mDhcpRequestingState);
-            }
-        }
-    }
-
-    // Not implemented. We request the first offer we receive.
-    class DhcpSelectingState extends LoggingState {
-    }
-
-    class DhcpRequestingState extends PacketRetransmittingState {
-        public DhcpRequestingState() {
-            mTimeout = DHCP_TIMEOUT_MS / 2;
-        }
-
-        protected boolean sendPacket() {
-            return sendRequestPacket(
-                    INADDR_ANY,                                    // ciaddr
-                    (Inet4Address) mOffer.ipAddress.getAddress(),  // DHCP_REQUESTED_IP
-                    (Inet4Address) mOffer.serverAddress,           // DHCP_SERVER_IDENTIFIER
-                    INADDR_BROADCAST);                             // packet destination address
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if ((packet instanceof DhcpAckPacket)) {
-                DhcpResults results = packet.toDhcpResults();
-                if (results != null) {
-                    setDhcpLeaseExpiry(packet);
-                    acceptDhcpResults(results, "Confirmed");
-                    transitionTo(mConfiguringInterfaceState);
-                }
-            } else if (packet instanceof DhcpNakPacket) {
-                // TODO: Wait a while before returning into INIT state.
-                Log.d(TAG, "Received NAK, returning to INIT");
-                mOffer = null;
-                transitionTo(mDhcpInitState);
-            }
-        }
-
-        @Override
-        protected void timeout() {
-            // After sending REQUESTs unsuccessfully for a while, go back to init.
-            transitionTo(mDhcpInitState);
-        }
-    }
-
-    class DhcpHaveLeaseState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_EXPIRE_DHCP:
-                    Log.d(TAG, "Lease expired!");
-                    notifyFailure();
-                    transitionTo(mDhcpInitState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            // Clear any extant alarms.
-            mRenewAlarm.cancel();
-            mRebindAlarm.cancel();
-            mExpiryAlarm.cancel();
-            clearDhcpState();
-            // Tell IpManager to clear the IPv4 address. There is no need to
-            // wait for confirmation since any subsequent packets are sent from
-            // INADDR_ANY anyway (DISCOVER, REQUEST).
-            mController.sendMessage(CMD_CLEAR_LINKADDRESS);
-        }
-    }
-
-    class ConfiguringInterfaceState extends LoggingState {
-        @Override
-        public void enter() {
-            super.enter();
-            mController.sendMessage(CMD_CONFIGURE_LINKADDRESS, mDhcpLease.ipAddress);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case EVENT_LINKADDRESS_CONFIGURED:
-                    transitionTo(mDhcpBoundState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    class DhcpBoundState extends LoggingState {
-        @Override
-        public void enter() {
-            super.enter();
-            if (mDhcpLease.serverAddress != null && !connectUdpSock(mDhcpLease.serverAddress)) {
-                // There's likely no point in going into DhcpInitState here, we'll probably
-                // just repeat the transaction, get the same IP address as before, and fail.
-                //
-                // NOTE: It is observed that connectUdpSock() basically never fails, due to
-                // SO_BINDTODEVICE. Examining the local socket address shows it will happily
-                // return an IPv4 address from another interface, or even return "0.0.0.0".
-                //
-                // TODO: Consider deleting this check, following testing on several kernels.
-                notifyFailure();
-                transitionTo(mStoppedState);
-            }
-
-            scheduleLeaseTimers();
-            logTimeToBoundState();
-        }
-
-        @Override
-        public void exit() {
-            super.exit();
-            mLastBoundExitTime = SystemClock.elapsedRealtime();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            super.processMessage(message);
-            switch (message.what) {
-                case CMD_RENEW_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        transitionTo(mWaitBeforeRenewalState);
-                    } else {
-                        transitionTo(mDhcpRenewingState);
-                    }
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        private void logTimeToBoundState() {
-            long now = SystemClock.elapsedRealtime();
-            if (mLastBoundExitTime > mLastInitEnterTime) {
-                logState(EVENT_RENEWING_BOUND, (int) (now - mLastBoundExitTime));
-            } else {
-                logState(EVENT_INITIAL_BOUND, (int) (now - mLastInitEnterTime));
-            }
-        }
-    }
-
-    abstract class DhcpReacquiringState extends PacketRetransmittingState {
-        protected String mLeaseMsg;
-
-        @Override
-        public void enter() {
-            super.enter();
-            startNewTransaction();
-        }
-
-        abstract protected Inet4Address packetDestination();
-
-        protected boolean sendPacket() {
-            return sendRequestPacket(
-                    (Inet4Address) mDhcpLease.ipAddress.getAddress(),  // ciaddr
-                    INADDR_ANY,                                        // DHCP_REQUESTED_IP
-                    null,                                              // DHCP_SERVER_IDENTIFIER
-                    packetDestination());                              // packet destination address
-        }
-
-        protected void receivePacket(DhcpPacket packet) {
-            if (!isValidPacket(packet)) return;
-            if ((packet instanceof DhcpAckPacket)) {
-                final DhcpResults results = packet.toDhcpResults();
-                if (results != null) {
-                    if (!mDhcpLease.ipAddress.equals(results.ipAddress)) {
-                        Log.d(TAG, "Renewed lease not for our current IP address!");
-                        notifyFailure();
-                        transitionTo(mDhcpInitState);
-                    }
-                    setDhcpLeaseExpiry(packet);
-                    // Updating our notion of DhcpResults here only causes the
-                    // DNS servers and routes to be updated in LinkProperties
-                    // in IpManager and by any overridden relevant handlers of
-                    // the registered IpManager.Callback.  IP address changes
-                    // are not supported here.
-                    acceptDhcpResults(results, mLeaseMsg);
-                    transitionTo(mDhcpBoundState);
-                }
-            } else if (packet instanceof DhcpNakPacket) {
-                Log.d(TAG, "Received NAK, returning to INIT");
-                notifyFailure();
-                transitionTo(mDhcpInitState);
-            }
-        }
-    }
-
-    class DhcpRenewingState extends DhcpReacquiringState {
-        public DhcpRenewingState() {
-            mLeaseMsg = "Renewed";
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (super.processMessage(message) == HANDLED) {
-                return HANDLED;
-            }
-
-            switch (message.what) {
-                case CMD_REBIND_DHCP:
-                    transitionTo(mDhcpRebindingState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        protected Inet4Address packetDestination() {
-            // Not specifying a SERVER_IDENTIFIER option is a violation of RFC 2131, but...
-            // http://b/25343517 . Try to make things work anyway by using broadcast renews.
-            return (mDhcpLease.serverAddress != null) ?
-                    mDhcpLease.serverAddress : INADDR_BROADCAST;
-        }
-    }
-
-    class DhcpRebindingState extends DhcpReacquiringState {
-        public DhcpRebindingState() {
-            mLeaseMsg = "Rebound";
-        }
-
-        @Override
-        public void enter() {
-            super.enter();
-
-            // We need to broadcast and possibly reconnect the socket to a
-            // completely different server.
-            closeSocketQuietly(mUdpSock);
-            if (!initUdpSocket()) {
-                Log.e(TAG, "Failed to recreate UDP socket");
-                transitionTo(mDhcpInitState);
-            }
-        }
-
-        @Override
-        protected Inet4Address packetDestination() {
-            return INADDR_BROADCAST;
-        }
-    }
-
-    class DhcpInitRebootState extends LoggingState {
-    }
-
-    class DhcpRebootingState extends LoggingState {
-    }
-
-    private void logError(int errorCode) {
-        mMetricsLog.log(mIfaceName, new DhcpErrorEvent(errorCode));
-    }
-
-    private void logState(String name, int durationMs) {
-        final DhcpClientEvent event = new DhcpClientEvent.Builder()
-                .setMsg(name)
-                .setDurationMs(durationMs)
-                .build();
-        mMetricsLog.log(mIfaceName, event);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java
deleted file mode 100644
index 7ecdea7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpDeclinePacket.java
+++ /dev/null
@@ -1,61 +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.
- */
-
-package android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-DECLINE packet.
- */
-class DhcpDeclinePacket extends DhcpPacket {
-    /**
-     * Generates a DECLINE packet with the specified parameters.
-     */
-    DhcpDeclinePacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                      Inet4Address nextIp, Inet4Address relayIp,
-                      byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " DECLINE";
-    }
-
-    /**
-     * Fills in a packet with the requested DECLINE attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
-            DHCP_BOOTREQUEST, false);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds optional parameters to the DECLINE packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DECLINE);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        // RFC 2131 says we MUST NOT include our common client TLVs or the parameter request list.
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java
deleted file mode 100644
index 11f2b61..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpDiscoverPacket.java
+++ /dev/null
@@ -1,67 +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.
- */
-
-package android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-DISCOVER packet.
- */
-class DhcpDiscoverPacket extends DhcpPacket {
-    /**
-     * The IP address of the client which sent this packet.
-     */
-    final Inet4Address mSrcIp;
-
-    /**
-     * Generates a DISCOVER packet with the specified parameters.
-     */
-    DhcpDiscoverPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
-            boolean broadcast, Inet4Address srcIp) {
-        super(transId, secs, INADDR_ANY, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
-        mSrcIp = srcIp;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " DISCOVER " +
-                (mBroadcast ? "broadcast " : "unicast ");
-    }
-
-    /**
-     * Fills in a packet with the requested DISCOVER parameters.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        fillInPacket(encap, INADDR_BROADCAST, mSrcIp, destUdp, srcUdp, result, DHCP_BOOTREQUEST,
-                mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds optional parameters to a DISCOVER packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_DISCOVER);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java
deleted file mode 100644
index 7a83466..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpInformPacket.java
+++ /dev/null
@@ -1,62 +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.
- */
-
-package android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the (unused) DHCP-INFORM packet.
- */
-class DhcpInformPacket extends DhcpPacket {
-    /**
-     * Generates an INFORM packet with the specified parameters.
-     */
-    DhcpInformPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                     Inet4Address nextIp, Inet4Address relayIp,
-                     byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " INFORM";
-    }
-
-    /**
-     * Builds an INFORM packet.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result,
-            DHCP_BOOTREQUEST, false);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds additional parameters to the INFORM packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_INFORM);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java b/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java
deleted file mode 100644
index 6849cfa..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpLease.java
+++ /dev/null
@@ -1,153 +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.net.dhcp;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.MacAddress;
-import android.os.SystemClock;
-import android.text.TextUtils;
-
-import com.android.internal.util.HexDump;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * An IPv4 address assignment done through DHCPv4.
- * @hide
- */
-public class DhcpLease {
-    public static final long EXPIRATION_NEVER = Long.MAX_VALUE;
-    public static final String HOSTNAME_NONE = null;
-
-    @Nullable
-    private final byte[] mClientId;
-    @NonNull
-    private final MacAddress mHwAddr;
-    @NonNull
-    private final Inet4Address mNetAddr;
-    /**
-     * Expiration time for the lease, to compare with {@link SystemClock#elapsedRealtime()}.
-     */
-    private final long mExpTime;
-    @Nullable
-    private final String mHostname;
-
-    public DhcpLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address netAddr, long expTime, @Nullable String hostname) {
-        mClientId = (clientId == null ? null : Arrays.copyOf(clientId, clientId.length));
-        mHwAddr = hwAddr;
-        mNetAddr = netAddr;
-        mExpTime = expTime;
-        mHostname = hostname;
-    }
-
-    /**
-     * Get the clientId associated with this lease, if any.
-     *
-     * <p>If the lease is not associated to a clientId, this returns null.
-     */
-    @Nullable
-    public byte[] getClientId() {
-        if (mClientId == null) {
-            return null;
-        }
-        return Arrays.copyOf(mClientId, mClientId.length);
-    }
-
-    @NonNull
-    public MacAddress getHwAddr() {
-        return mHwAddr;
-    }
-
-    @Nullable
-    public String getHostname() {
-        return mHostname;
-    }
-
-    @NonNull
-    public Inet4Address getNetAddr() {
-        return mNetAddr;
-    }
-
-    public long getExpTime() {
-        return mExpTime;
-    }
-
-    /**
-     * Push back the expiration time of this lease. If the provided time is sooner than the original
-     * expiration time, the lease time will not be updated.
-     *
-     * <p>The lease hostname is updated with the provided one if set.
-     * @return A {@link DhcpLease} with expiration time set to max(expTime, currentExpTime)
-     */
-    public DhcpLease renewedLease(long expTime, @Nullable String hostname) {
-        return new DhcpLease(mClientId, mHwAddr, mNetAddr, Math.max(expTime, mExpTime),
-                (hostname == null ? mHostname : hostname));
-    }
-
-    /**
-     * Determine whether this lease matches a client with the specified parameters.
-     * @param clientId clientId of the client if any, or null otherwise.
-     * @param hwAddr Hardware address of the client.
-     */
-    public boolean matchesClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
-        if (mClientId != null) {
-            return Arrays.equals(mClientId, clientId);
-        } else {
-            return clientId == null && mHwAddr.equals(hwAddr);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof DhcpLease)) {
-            return false;
-        }
-        final DhcpLease other = (DhcpLease) obj;
-        return Arrays.equals(mClientId, other.mClientId)
-                && mHwAddr.equals(other.mHwAddr)
-                && mNetAddr.equals(other.mNetAddr)
-                && mExpTime == other.mExpTime
-                && TextUtils.equals(mHostname, other.mHostname);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mClientId, mHwAddr, mNetAddr, mHostname, mExpTime);
-    }
-
-    static String clientIdToString(byte[] bytes) {
-        if (bytes == null) {
-            return "null";
-        }
-        return HexDump.toHexString(bytes);
-    }
-
-    static String inet4AddrToString(@Nullable Inet4Address addr) {
-        return (addr == null) ? "null" : addr.getHostAddress();
-    }
-
-    @Override
-    public String toString() {
-        return String.format("clientId: %s, hwAddr: %s, netAddr: %s, expTime: %d, hostname: %s",
-                clientIdToString(mClientId), mHwAddr.toString(), inet4AddrToString(mNetAddr),
-                mExpTime, mHostname);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java b/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java
deleted file mode 100644
index 0a15cd7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpLeaseRepository.java
+++ /dev/null
@@ -1,546 +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.net.dhcp;
-
-import static android.net.dhcp.DhcpLease.EXPIRATION_NEVER;
-import static android.net.dhcp.DhcpLease.inet4AddrToString;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-import static android.net.shared.Inet4AddressUtils.prefixLengthToV4NetmaskIntHTH;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_BITS;
-
-import static java.lang.Math.min;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.util.SharedLog;
-import android.util.ArrayMap;
-
-import java.net.Inet4Address;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.function.Function;
-
-/**
- * A repository managing IPv4 address assignments through DHCPv4.
- *
- * <p>This class is not thread-safe. All public methods should be called on a common thread or
- * use some synchronization mechanism.
- *
- * <p>Methods are optimized for a small number of allocated leases, assuming that most of the time
- * only 2~10 addresses will be allocated, which is the common case. Managing a large number of
- * addresses is supported but will be slower: some operations have complexity in O(num_leases).
- * @hide
- */
-class DhcpLeaseRepository {
-    public static final byte[] CLIENTID_UNSPEC = null;
-    public static final Inet4Address INETADDR_UNSPEC = null;
-
-    @NonNull
-    private final SharedLog mLog;
-    @NonNull
-    private final Clock mClock;
-
-    @NonNull
-    private IpPrefix mPrefix;
-    @NonNull
-    private Set<Inet4Address> mReservedAddrs;
-    private int mSubnetAddr;
-    private int mSubnetMask;
-    private int mNumAddresses;
-    private long mLeaseTimeMs;
-
-    /**
-     * Next timestamp when committed or declined leases should be checked for expired ones. This
-     * will always be lower than or equal to the time for the first lease to expire: it's OK not to
-     * update this when removing entries, but it must always be updated when adding/updating.
-     */
-    private long mNextExpirationCheck = EXPIRATION_NEVER;
-
-    static class DhcpLeaseException extends Exception {
-        DhcpLeaseException(String message) {
-            super(message);
-        }
-    }
-
-    static class OutOfAddressesException extends DhcpLeaseException {
-        OutOfAddressesException(String message) {
-            super(message);
-        }
-    }
-
-    static class InvalidAddressException extends DhcpLeaseException {
-        InvalidAddressException(String message) {
-            super(message);
-        }
-    }
-
-    static class InvalidSubnetException extends DhcpLeaseException {
-        InvalidSubnetException(String message) {
-            super(message);
-        }
-    }
-
-    /**
-     * Leases by IP address
-     */
-    private final ArrayMap<Inet4Address, DhcpLease> mCommittedLeases = new ArrayMap<>();
-
-    /**
-     * Map address -> expiration timestamp in ms. Addresses are guaranteed to be valid as defined
-     * by {@link #isValidAddress(Inet4Address)}, but are not necessarily otherwise available for
-     * assignment.
-     */
-    private final LinkedHashMap<Inet4Address, Long> mDeclinedAddrs = new LinkedHashMap<>();
-
-    DhcpLeaseRepository(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
-            long leaseTimeMs, @NonNull SharedLog log, @NonNull Clock clock) {
-        updateParams(prefix, reservedAddrs, leaseTimeMs);
-        mLog = log;
-        mClock = clock;
-    }
-
-    public void updateParams(@NonNull IpPrefix prefix, @NonNull Set<Inet4Address> reservedAddrs,
-            long leaseTimeMs) {
-        mPrefix = prefix;
-        mReservedAddrs = Collections.unmodifiableSet(new HashSet<>(reservedAddrs));
-        mSubnetMask = prefixLengthToV4NetmaskIntHTH(prefix.getPrefixLength());
-        mSubnetAddr = inet4AddressToIntHTH((Inet4Address) prefix.getAddress()) & mSubnetMask;
-        mNumAddresses = 1 << (IPV4_ADDR_BITS - prefix.getPrefixLength());
-        mLeaseTimeMs = leaseTimeMs;
-
-        cleanMap(mCommittedLeases);
-        cleanMap(mDeclinedAddrs);
-    }
-
-    /**
-     * From a map keyed by {@link Inet4Address}, remove entries where the key is invalid (as
-     * specified by {@link #isValidAddress(Inet4Address)}), or is a reserved address.
-     */
-    private <T> void cleanMap(Map<Inet4Address, T> map) {
-        final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
-        while (it.hasNext()) {
-            final Inet4Address addr = it.next().getKey();
-            if (!isValidAddress(addr) || mReservedAddrs.contains(addr)) {
-                it.remove();
-            }
-        }
-    }
-
-    /**
-     * Get a DHCP offer, to reply to a DHCPDISCOVER. Follows RFC2131 #4.3.1.
-     *
-     * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
-     * @param relayAddr Internet address of the relay (giaddr), can be {@link Inet4Address#ANY}
-     * @param reqAddr Requested address by the client (option 50), or {@link #INETADDR_UNSPEC}
-     * @param hostname Client-provided hostname, or {@link DhcpLease#HOSTNAME_NONE}
-     * @throws OutOfAddressesException The server does not have any available address
-     * @throws InvalidSubnetException The lease was requested from an unsupported subnet
-     */
-    @NonNull
-    public DhcpLease getOffer(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address relayAddr, @Nullable Inet4Address reqAddr,
-            @Nullable String hostname) throws OutOfAddressesException, InvalidSubnetException {
-        final long currentTime = mClock.elapsedRealtime();
-        final long expTime = currentTime + mLeaseTimeMs;
-
-        removeExpiredLeases(currentTime);
-        checkValidRelayAddr(relayAddr);
-
-        final DhcpLease currentLease = findByClient(clientId, hwAddr);
-        final DhcpLease newLease;
-        if (currentLease != null) {
-            newLease = currentLease.renewedLease(expTime, hostname);
-            mLog.log("Offering extended lease " + newLease);
-            // Do not update lease time in the map: the offer is not committed yet.
-        } else if (reqAddr != null && isValidAddress(reqAddr) && isAvailable(reqAddr)) {
-            newLease = new DhcpLease(clientId, hwAddr, reqAddr, expTime, hostname);
-            mLog.log("Offering requested lease " + newLease);
-        } else {
-            newLease = makeNewOffer(clientId, hwAddr, expTime, hostname);
-            mLog.log("Offering new generated lease " + newLease);
-        }
-        return newLease;
-    }
-
-    private void checkValidRelayAddr(@Nullable Inet4Address relayAddr)
-            throws InvalidSubnetException {
-        // As per #4.3.1, addresses are assigned based on the relay address if present. This
-        // implementation only assigns addresses if the relayAddr is inside our configured subnet.
-        // This also applies when the client requested a specific address for consistency between
-        // requests, and with older behavior.
-        if (isIpAddrOutsidePrefix(mPrefix, relayAddr)) {
-            throw new InvalidSubnetException("Lease requested by relay from outside of subnet");
-        }
-    }
-
-    private static boolean isIpAddrOutsidePrefix(@NonNull IpPrefix prefix,
-            @Nullable Inet4Address addr) {
-        return addr != null && !addr.equals(IPV4_ADDR_ANY) && !prefix.contains(addr);
-    }
-
-    @Nullable
-    private DhcpLease findByClient(@Nullable byte[] clientId, @NonNull MacAddress hwAddr) {
-        for (DhcpLease lease : mCommittedLeases.values()) {
-            if (lease.matchesClient(clientId, hwAddr)) {
-                return lease;
-            }
-        }
-
-        // Note this differs from dnsmasq behavior, which would match by hwAddr if clientId was
-        // given but no lease keyed on clientId matched. This would prevent one interface from
-        // obtaining multiple leases with different clientId.
-        return null;
-    }
-
-    /**
-     * Make a lease conformant to a client DHCPREQUEST or renew the client's existing lease,
-     * commit it to the repository and return it.
-     *
-     * <p>This method always succeeds and commits the lease if it does not throw, and has no side
-     * effects if it throws.
-     *
-     * @param clientId Client identifier option if specified, or {@link #CLIENTID_UNSPEC}
-     * @param reqAddr Requested address by the client (option 50), or {@link #INETADDR_UNSPEC}
-     * @param sidSet Whether the server identifier was set in the request
-     * @return The newly created or renewed lease
-     * @throws InvalidAddressException The client provided an address that conflicts with its
-     *                                 current configuration, or other committed/reserved leases.
-     */
-    @NonNull
-    public DhcpLease requestLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address clientAddr, @NonNull Inet4Address relayAddr,
-            @Nullable Inet4Address reqAddr, boolean sidSet, @Nullable String hostname)
-            throws InvalidAddressException, InvalidSubnetException {
-        final long currentTime = mClock.elapsedRealtime();
-        removeExpiredLeases(currentTime);
-        checkValidRelayAddr(relayAddr);
-        final DhcpLease assignedLease = findByClient(clientId, hwAddr);
-
-        final Inet4Address leaseAddr = reqAddr != null ? reqAddr : clientAddr;
-        if (assignedLease != null) {
-            if (sidSet && reqAddr != null) {
-                // Client in SELECTING state; remove any current lease before creating a new one.
-                mCommittedLeases.remove(assignedLease.getNetAddr());
-            } else if (!assignedLease.getNetAddr().equals(leaseAddr)) {
-                // reqAddr null (RENEWING/REBINDING): client renewing its own lease for clientAddr.
-                // reqAddr set with sid not set (INIT-REBOOT): client verifying configuration.
-                // In both cases, throw if clientAddr or reqAddr does not match the known lease.
-                throw new InvalidAddressException("Incorrect address for client in "
-                        + (reqAddr != null ? "INIT-REBOOT" : "RENEWING/REBINDING"));
-            }
-        }
-
-        // In the init-reboot case, RFC2131 #4.3.2 says that the server must not reply if
-        // assignedLease == null, but dnsmasq will let the client use the requested address if
-        // available, when configured with --dhcp-authoritative. This is preferable to avoid issues
-        // if the server lost the lease DB: the client would not get a reply because the server
-        // does not know their lease.
-        // Similarly in RENEWING/REBINDING state, create a lease when possible if the
-        // client-provided lease is unknown.
-        final DhcpLease lease =
-                checkClientAndMakeLease(clientId, hwAddr, leaseAddr, hostname, currentTime);
-        mLog.logf("DHCPREQUEST assignedLease %s, reqAddr=%s, sidSet=%s: created/renewed lease %s",
-                assignedLease, inet4AddrToString(reqAddr), sidSet, lease);
-        return lease;
-    }
-
-    /**
-     * Check that the client can request the specified address, make or renew the lease if yes, and
-     * commit it.
-     *
-     * <p>This method always succeeds and returns the lease if it does not throw, and has no
-     * side-effect if it throws.
-     *
-     * @return The newly created or renewed, committed lease
-     * @throws InvalidAddressException The client provided an address that conflicts with its
-     *                                 current configuration, or other committed/reserved leases.
-     */
-    private DhcpLease checkClientAndMakeLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address addr, @Nullable String hostname, long currentTime)
-            throws InvalidAddressException {
-        final long expTime = currentTime + mLeaseTimeMs;
-        final DhcpLease currentLease = mCommittedLeases.getOrDefault(addr, null);
-        if (currentLease != null && !currentLease.matchesClient(clientId, hwAddr)) {
-            throw new InvalidAddressException("Address in use");
-        }
-
-        final DhcpLease lease;
-        if (currentLease == null) {
-            if (isValidAddress(addr) && !mReservedAddrs.contains(addr)) {
-                lease = new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            } else {
-                throw new InvalidAddressException("Lease not found and address unavailable");
-            }
-        } else {
-            lease = currentLease.renewedLease(expTime, hostname);
-        }
-        commitLease(lease);
-        return lease;
-    }
-
-    private void commitLease(@NonNull DhcpLease lease) {
-        mCommittedLeases.put(lease.getNetAddr(), lease);
-        maybeUpdateEarliestExpiration(lease.getExpTime());
-    }
-
-    /**
-     * Delete a committed lease from the repository.
-     *
-     * @return true if a lease matching parameters was found.
-     */
-    public boolean releaseLease(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            @NonNull Inet4Address addr) {
-        final DhcpLease currentLease = mCommittedLeases.getOrDefault(addr, null);
-        if (currentLease == null) {
-            mLog.w("Could not release unknown lease for " + inet4AddrToString(addr));
-            return false;
-        }
-        if (currentLease.matchesClient(clientId, hwAddr)) {
-            mCommittedLeases.remove(addr);
-            mLog.log("Released lease " + currentLease);
-            return true;
-        }
-        mLog.w(String.format("Not releasing lease %s: does not match client (cid %s, hwAddr %s)",
-                currentLease, DhcpLease.clientIdToString(clientId), hwAddr));
-        return false;
-    }
-
-    public void markLeaseDeclined(@NonNull Inet4Address addr) {
-        if (mDeclinedAddrs.containsKey(addr) || !isValidAddress(addr)) {
-            mLog.logf("Not marking %s as declined: already declined or not assignable",
-                    inet4AddrToString(addr));
-            return;
-        }
-        final long expTime = mClock.elapsedRealtime() + mLeaseTimeMs;
-        mDeclinedAddrs.put(addr, expTime);
-        mLog.logf("Marked %s as declined expiring %d", inet4AddrToString(addr), expTime);
-        maybeUpdateEarliestExpiration(expTime);
-    }
-
-    /**
-     * Get the list of currently valid committed leases in the repository.
-     */
-    @NonNull
-    public List<DhcpLease> getCommittedLeases() {
-        removeExpiredLeases(mClock.elapsedRealtime());
-        return new ArrayList<>(mCommittedLeases.values());
-    }
-
-    /**
-     * Get the set of addresses that have been marked as declined in the repository.
-     */
-    @NonNull
-    public Set<Inet4Address> getDeclinedAddresses() {
-        removeExpiredLeases(mClock.elapsedRealtime());
-        return new HashSet<>(mDeclinedAddrs.keySet());
-    }
-
-    /**
-     * Given the expiration time of a new committed lease or declined address, update
-     * {@link #mNextExpirationCheck} so it stays lower than or equal to the time for the first lease
-     * to expire.
-     */
-    private void maybeUpdateEarliestExpiration(long expTime) {
-        if (expTime < mNextExpirationCheck) {
-            mNextExpirationCheck = expTime;
-        }
-    }
-
-    /**
-     * Remove expired entries from a map keyed by {@link Inet4Address}.
-     *
-     * @param tag Type of lease in the map, for logging
-     * @param getExpTime Functor returning the expiration time for an object in the map.
-     *                   Must not return null.
-     * @return The lowest expiration time among entries remaining in the map
-     */
-    private <T> long removeExpired(long currentTime, @NonNull Map<Inet4Address, T> map,
-            @NonNull String tag, @NonNull Function<T, Long> getExpTime) {
-        final Iterator<Entry<Inet4Address, T>> it = map.entrySet().iterator();
-        long firstExpiration = EXPIRATION_NEVER;
-        while (it.hasNext()) {
-            final Entry<Inet4Address, T> lease = it.next();
-            final long expTime = getExpTime.apply(lease.getValue());
-            if (expTime <= currentTime) {
-                mLog.logf("Removing expired %s lease for %s (expTime=%s, currentTime=%s)",
-                        tag, lease.getKey(), expTime, currentTime);
-                it.remove();
-            } else {
-                firstExpiration = min(firstExpiration, expTime);
-            }
-        }
-        return firstExpiration;
-    }
-
-    /**
-     * Go through committed and declined leases and remove the expired ones.
-     */
-    private void removeExpiredLeases(long currentTime) {
-        if (currentTime < mNextExpirationCheck) {
-            return;
-        }
-
-        final long commExp = removeExpired(
-                currentTime, mCommittedLeases, "committed", DhcpLease::getExpTime);
-        final long declExp = removeExpired(
-                currentTime, mDeclinedAddrs, "declined", Function.identity());
-
-        mNextExpirationCheck = min(commExp, declExp);
-    }
-
-    private boolean isAvailable(@NonNull Inet4Address addr) {
-        return !mReservedAddrs.contains(addr) && !mCommittedLeases.containsKey(addr);
-    }
-
-    /**
-     * Get the 0-based index of an address in the subnet.
-     *
-     * <p>Given ordering of addresses 5.6.7.8 < 5.6.7.9 < 5.6.8.0, the index on a subnet is defined
-     * so that the first address is 0, the second 1, etc. For example on a /16, 192.168.0.0 -> 0,
-     * 192.168.0.1 -> 1, 192.168.1.0 -> 256
-     *
-     */
-    private int getAddrIndex(int addr) {
-        return addr & ~mSubnetMask;
-    }
-
-    private int getAddrByIndex(int index) {
-        return mSubnetAddr | index;
-    }
-
-    /**
-     * Get a valid address starting from the supplied one.
-     *
-     * <p>This only checks that the address is numerically valid for assignment, not whether it is
-     * already in use. The return value is always inside the configured prefix, even if the supplied
-     * address is not.
-     *
-     * <p>If the provided address is valid, it is returned as-is. Otherwise, the next valid
-     * address (with the ordering in {@link #getAddrIndex(int)}) is returned.
-     */
-    private int getValidAddress(int addr) {
-        final int lastByteMask = 0xff;
-        int addrIndex = getAddrIndex(addr); // 0-based index of the address in the subnet
-
-        // Some OSes do not handle addresses in .255 or .0 correctly: avoid those.
-        final int lastByte = getAddrByIndex(addrIndex) & lastByteMask;
-        if (lastByte == lastByteMask) {
-            // Avoid .255 address, and .0 address that follows
-            addrIndex = (addrIndex + 2) % mNumAddresses;
-        } else if (lastByte == 0) {
-            // Avoid .0 address
-            addrIndex = (addrIndex + 1) % mNumAddresses;
-        }
-
-        // Do not use first or last address of range
-        if (addrIndex == 0 || addrIndex == mNumAddresses - 1) {
-            // Always valid and not end of range since prefixLength is at most 30 in serving params
-            addrIndex = 1;
-        }
-        return getAddrByIndex(addrIndex);
-    }
-
-    /**
-     * Returns whether the address is in the configured subnet and part of the assignable range.
-     */
-    private boolean isValidAddress(Inet4Address addr) {
-        final int intAddr = inet4AddressToIntHTH(addr);
-        return getValidAddress(intAddr) == intAddr;
-    }
-
-    private int getNextAddress(int addr) {
-        final int addrIndex = getAddrIndex(addr);
-        final int nextAddress = getAddrByIndex((addrIndex + 1) % mNumAddresses);
-        return getValidAddress(nextAddress);
-    }
-
-    /**
-     * Calculate a first candidate address for a client by hashing the hardware address.
-     *
-     * <p>This will be a valid address as checked by {@link #getValidAddress(int)}, but may be
-     * in use.
-     *
-     * @return An IPv4 address encoded as 32-bit int
-     */
-    private int getFirstClientAddress(MacAddress hwAddr) {
-        // This follows dnsmasq behavior. Advantages are: clients will often get the same
-        // offers for different DISCOVER even if the lease was not yet accepted or has expired,
-        // and address generation will generally not need to loop through many allocated addresses
-        // until it finds a free one.
-        int hash = 0;
-        for (byte b : hwAddr.toByteArray()) {
-            hash += b + (b << 8) + (b << 16);
-        }
-        // This implementation will not always result in the same IPs as dnsmasq would give out in
-        // Android <= P, because it includes invalid and reserved addresses in mNumAddresses while
-        // the configured ranges for dnsmasq did not.
-        final int addrIndex = hash % mNumAddresses;
-        return getValidAddress(getAddrByIndex(addrIndex));
-    }
-
-    /**
-     * Create a lease that can be offered to respond to a client DISCOVER.
-     *
-     * <p>This method always succeeds and returns the lease if it does not throw. If no non-declined
-     * address is available, it will try to offer the oldest declined address if valid.
-     *
-     * @throws OutOfAddressesException The server has no address left to offer
-     */
-    private DhcpLease makeNewOffer(@Nullable byte[] clientId, @NonNull MacAddress hwAddr,
-            long expTime, @Nullable String hostname) throws OutOfAddressesException {
-        int intAddr = getFirstClientAddress(hwAddr);
-        // Loop until a free address is found, or there are no more addresses.
-        // There is slightly less than this many usable addresses, but some extra looping is OK
-        for (int i = 0; i < mNumAddresses; i++) {
-            final Inet4Address addr = intToInet4AddressHTH(intAddr);
-            if (isAvailable(addr) && !mDeclinedAddrs.containsKey(addr)) {
-                return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            }
-            intAddr = getNextAddress(intAddr);
-        }
-
-        // Try freeing DECLINEd addresses if out of addresses.
-        final Iterator<Inet4Address> it = mDeclinedAddrs.keySet().iterator();
-        while (it.hasNext()) {
-            final Inet4Address addr = it.next();
-            it.remove();
-            mLog.logf("Out of addresses in address pool: dropped declined addr %s",
-                    inet4AddrToString(addr));
-            // isValidAddress() is always verified for entries in mDeclinedAddrs.
-            // However declined addresses may have been requested (typically by the machine that was
-            // already using the address) after being declined.
-            if (isAvailable(addr)) {
-                return new DhcpLease(clientId, hwAddr, addr, expTime, hostname);
-            }
-        }
-
-        throw new OutOfAddressesException("No address available for offer");
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java
deleted file mode 100644
index 1da0b73..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpNakPacket.java
+++ /dev/null
@@ -1,63 +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.
- */
-
-package android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-NAK packet.
- */
-class DhcpNakPacket extends DhcpPacket {
-    /**
-     * Generates a NAK packet with the specified parameters.
-     */
-    DhcpNakPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
-            boolean broadcast) {
-        super(transId, secs, INADDR_ANY /* clientIp */, INADDR_ANY /* yourIp */,
-                INADDR_ANY /* nextIp */, relayIp, clientMac, broadcast);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " NAK, reason " + (mMessage == null ? "(none)" : mMessage);
-    }
-
-    /**
-     * Fills in a packet with the requested NAK attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        // Constructor does not set values for layers <= 3: use empty values
-        Inet4Address destIp = INADDR_ANY;
-        Inet4Address srcIp = INADDR_ANY;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result, DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated NAK packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_NAK);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        addTlv(buffer, DHCP_MESSAGE, mMessage);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java
deleted file mode 100644
index 0eba77e..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpOfferPacket.java
+++ /dev/null
@@ -1,79 +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.
- */
-
-package android.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-OFFER packet.
- */
-class DhcpOfferPacket extends DhcpPacket {
-    /**
-     * The IP address of the server which sent this packet.
-     */
-    private final Inet4Address mSrcIp;
-
-    /**
-     * Generates a OFFER packet with the specified parameters.
-     */
-    DhcpOfferPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
-            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
-        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
-        mSrcIp = serverAddress;
-    }
-
-    public String toString() {
-        String s = super.toString();
-        String dnsServers = ", DNS servers: ";
-
-        if (mDnsServers != null) {
-            for (Inet4Address dnsServer: mDnsServers) {
-                dnsServers += dnsServer + " ";
-            }
-        }
-
-        return s + " OFFER, ip " + mYourIp + ", mask " + mSubnetMask +
-                dnsServers + ", gateways " + mGateways +
-                " lease time " + mLeaseTime + ", domain " + mDomainName;
-    }
-
-    /**
-     * Fills in a packet with the specified OFFER attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        Inet4Address destIp = mBroadcast ? INADDR_BROADCAST : mYourIp;
-        Inet4Address srcIp = mBroadcast ? INADDR_ANY : mSrcIp;
-
-        fillInPacket(encap, destIp, srcIp, destUdp, srcUdp, result,
-            DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the server-generated OFFER packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_OFFER);
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-
-        addCommonServerTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
deleted file mode 100644
index a15d423..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacket.java
+++ /dev/null
@@ -1,1397 +0,0 @@
-package android.net.dhcp;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ALL;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import android.annotation.Nullable;
-import android.net.DhcpResults;
-import android.net.LinkAddress;
-import android.net.metrics.DhcpErrorEvent;
-import android.net.shared.Inet4AddressUtils;
-import android.os.Build;
-import android.os.SystemProperties;
-import android.system.OsConstants;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.UnsupportedEncodingException;
-import java.net.Inet4Address;
-import java.net.UnknownHostException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.ShortBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Defines basic data and operations needed to build and use packets for the
- * DHCP protocol.  Subclasses create the specific packets used at each
- * stage of the negotiation.
- *
- * @hide
- */
-public abstract class DhcpPacket {
-    protected static final String TAG = "DhcpPacket";
-
-    // TODO: use NetworkStackConstants.IPV4_MIN_MTU once this class is moved to the network stack.
-    private static final int IPV4_MIN_MTU = 68;
-
-    // dhcpcd has a minimum lease of 20 seconds, but DhcpStateMachine would refuse to wake up the
-    // CPU for anything shorter than 5 minutes. For sanity's sake, this must be higher than the
-    // DHCP client timeout.
-    public static final int MINIMUM_LEASE = 60;
-    public static final int INFINITE_LEASE = (int) 0xffffffff;
-
-    public static final Inet4Address INADDR_ANY = IPV4_ADDR_ANY;
-    public static final Inet4Address INADDR_BROADCAST = IPV4_ADDR_ALL;
-    public static final byte[] ETHER_BROADCAST = new byte[] {
-            (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            (byte) 0xff, (byte) 0xff, (byte) 0xff,
-    };
-
-    /**
-     * Packet encapsulations.
-     */
-    public static final int ENCAP_L2 = 0;    // EthernetII header included
-    public static final int ENCAP_L3 = 1;    // IP/UDP header included
-    public static final int ENCAP_BOOTP = 2; // BOOTP contents only
-
-    /**
-     * Minimum length of a DHCP packet, excluding options, in the above encapsulations.
-     */
-    public static final int MIN_PACKET_LENGTH_BOOTP = 236;  // See diagram in RFC 2131, section 2.
-    public static final int MIN_PACKET_LENGTH_L3 = MIN_PACKET_LENGTH_BOOTP + 20 + 8;
-    public static final int MIN_PACKET_LENGTH_L2 = MIN_PACKET_LENGTH_L3 + 14;
-
-    public static final int HWADDR_LEN = 16;
-    public static final int MAX_OPTION_LEN = 255;
-
-    /**
-     * The minimum and maximum MTU that we are prepared to use. We set the minimum to the minimum
-     * IPv6 MTU because the IPv6 stack enters unusual codepaths when the link MTU drops below 1280,
-     * and does not recover if the MTU is brought above 1280 again. We set the maximum to 1500
-     * because in general it is risky to assume that the hardware is able to send/receive packets
-     * larger than 1500 bytes even if the network supports it.
-     */
-    private static final int MIN_MTU = 1280;
-    private static final int MAX_MTU = 1500;
-
-    /**
-     * IP layer definitions.
-     */
-    private static final byte IP_TYPE_UDP = (byte) 0x11;
-
-    /**
-     * IP: Version 4, Header Length 20 bytes
-     */
-    private static final byte IP_VERSION_HEADER_LEN = (byte) 0x45;
-
-    /**
-     * IP: Flags 0, Fragment Offset 0, Don't Fragment
-     */
-    private static final short IP_FLAGS_OFFSET = (short) 0x4000;
-
-    /**
-     * IP: TOS
-     */
-    private static final byte IP_TOS_LOWDELAY = (byte) 0x10;
-
-    /**
-     * IP: TTL -- use default 64 from RFC1340
-     */
-    private static final byte IP_TTL = (byte) 0x40;
-
-    /**
-     * The client DHCP port.
-     */
-    static final short DHCP_CLIENT = (short) 68;
-
-    /**
-     * The server DHCP port.
-     */
-    static final short DHCP_SERVER = (short) 67;
-
-    /**
-     * The message op code indicating a request from a client.
-     */
-    protected static final byte DHCP_BOOTREQUEST = (byte) 1;
-
-    /**
-     * The message op code indicating a response from the server.
-     */
-    protected static final byte DHCP_BOOTREPLY = (byte) 2;
-
-    /**
-     * The code type used to identify an Ethernet MAC address in the
-     * Client-ID field.
-     */
-    protected static final byte CLIENT_ID_ETHER = (byte) 1;
-
-    /**
-     * The maximum length of a packet that can be constructed.
-     */
-    protected static final int MAX_LENGTH = 1500;
-
-    /**
-     * The magic cookie that identifies this as a DHCP packet instead of BOOTP.
-     */
-    private static final int DHCP_MAGIC_COOKIE = 0x63825363;
-
-    /**
-     * DHCP Optional Type: DHCP Subnet Mask
-     */
-    protected static final byte DHCP_SUBNET_MASK = 1;
-    protected Inet4Address mSubnetMask;
-
-    /**
-     * DHCP Optional Type: DHCP Router
-     */
-    protected static final byte DHCP_ROUTER = 3;
-    protected List <Inet4Address> mGateways;
-
-    /**
-     * DHCP Optional Type: DHCP DNS Server
-     */
-    protected static final byte DHCP_DNS_SERVER = 6;
-    protected List<Inet4Address> mDnsServers;
-
-    /**
-     * DHCP Optional Type: DHCP Host Name
-     */
-    protected static final byte DHCP_HOST_NAME = 12;
-    protected String mHostName;
-
-    /**
-     * DHCP Optional Type: DHCP DOMAIN NAME
-     */
-    protected static final byte DHCP_DOMAIN_NAME = 15;
-    protected String mDomainName;
-
-    /**
-     * DHCP Optional Type: DHCP Interface MTU
-     */
-    protected static final byte DHCP_MTU = 26;
-    protected Short mMtu;
-
-    /**
-     * DHCP Optional Type: DHCP BROADCAST ADDRESS
-     */
-    protected static final byte DHCP_BROADCAST_ADDRESS = 28;
-    protected Inet4Address mBroadcastAddress;
-
-    /**
-     * DHCP Optional Type: Vendor specific information
-     */
-    protected static final byte DHCP_VENDOR_INFO = 43;
-    protected String mVendorInfo;
-
-    /**
-     * Value of the vendor specific option used to indicate that the network is metered
-     */
-    public static final String VENDOR_INFO_ANDROID_METERED = "ANDROID_METERED";
-
-    /**
-     * DHCP Optional Type: Option overload option
-     */
-    protected static final byte DHCP_OPTION_OVERLOAD = 52;
-
-    /**
-     * Possible values of the option overload option.
-     */
-    private static final byte OPTION_OVERLOAD_FILE = 1;
-    private static final byte OPTION_OVERLOAD_SNAME = 2;
-    private static final byte OPTION_OVERLOAD_BOTH = 3;
-
-    /**
-     * DHCP Optional Type: DHCP Requested IP Address
-     */
-    protected static final byte DHCP_REQUESTED_IP = 50;
-    protected Inet4Address mRequestedIp;
-
-    /**
-     * DHCP Optional Type: DHCP Lease Time
-     */
-    protected static final byte DHCP_LEASE_TIME = 51;
-    protected Integer mLeaseTime;
-
-    /**
-     * DHCP Optional Type: DHCP Message Type
-     */
-    protected static final byte DHCP_MESSAGE_TYPE = 53;
-    // the actual type values
-    protected static final byte DHCP_MESSAGE_TYPE_DISCOVER = 1;
-    protected static final byte DHCP_MESSAGE_TYPE_OFFER = 2;
-    protected static final byte DHCP_MESSAGE_TYPE_REQUEST = 3;
-    protected static final byte DHCP_MESSAGE_TYPE_DECLINE = 4;
-    protected static final byte DHCP_MESSAGE_TYPE_ACK = 5;
-    protected static final byte DHCP_MESSAGE_TYPE_NAK = 6;
-    protected static final byte DHCP_MESSAGE_TYPE_RELEASE = 7;
-    protected static final byte DHCP_MESSAGE_TYPE_INFORM = 8;
-
-    /**
-     * DHCP Optional Type: DHCP Server Identifier
-     */
-    protected static final byte DHCP_SERVER_IDENTIFIER = 54;
-    protected Inet4Address mServerIdentifier;
-
-    /**
-     * DHCP Optional Type: DHCP Parameter List
-     */
-    protected static final byte DHCP_PARAMETER_LIST = 55;
-    protected byte[] mRequestedParams;
-
-    /**
-     * DHCP Optional Type: DHCP MESSAGE
-     */
-    protected static final byte DHCP_MESSAGE = 56;
-    protected String mMessage;
-
-    /**
-     * DHCP Optional Type: Maximum DHCP Message Size
-     */
-    protected static final byte DHCP_MAX_MESSAGE_SIZE = 57;
-    protected Short mMaxMessageSize;
-
-    /**
-     * DHCP Optional Type: DHCP Renewal Time Value
-     */
-    protected static final byte DHCP_RENEWAL_TIME = 58;
-    protected Integer mT1;
-
-    /**
-     * DHCP Optional Type: Rebinding Time Value
-     */
-    protected static final byte DHCP_REBINDING_TIME = 59;
-    protected Integer mT2;
-
-    /**
-     * DHCP Optional Type: Vendor Class Identifier
-     */
-    protected static final byte DHCP_VENDOR_CLASS_ID = 60;
-    protected String mVendorId;
-
-    /**
-     * DHCP Optional Type: DHCP Client Identifier
-     */
-    protected static final byte DHCP_CLIENT_IDENTIFIER = 61;
-    protected byte[] mClientId;
-
-    /**
-     * DHCP zero-length option code: pad
-     */
-    protected static final byte DHCP_OPTION_PAD = 0x00;
-
-    /**
-     * DHCP zero-length option code: end of options
-     */
-    protected static final byte DHCP_OPTION_END = (byte) 0xff;
-
-    /**
-     * The transaction identifier used in this particular DHCP negotiation
-     */
-    protected final int mTransId;
-
-    /**
-     * The seconds field in the BOOTP header. Per RFC, should be nonzero in client requests only.
-     */
-    protected final short mSecs;
-
-    /**
-     * The IP address of the client host.  This address is typically
-     * proposed by the client (from an earlier DHCP negotiation) or
-     * supplied by the server.
-     */
-    protected final Inet4Address mClientIp;
-    protected final Inet4Address mYourIp;
-    private final Inet4Address mNextIp;
-    protected final Inet4Address mRelayIp;
-
-    /**
-     * Does the client request a broadcast response?
-     */
-    protected boolean mBroadcast;
-
-    /**
-     * The six-octet MAC of the client.
-     */
-    protected final byte[] mClientMac;
-
-    /**
-     * The server host name from server.
-     */
-    protected String mServerHostName;
-
-    /**
-     * Asks the packet object to create a ByteBuffer serialization of
-     * the packet for transmission.
-     */
-    public abstract ByteBuffer buildPacket(int encap, short destUdp,
-        short srcUdp);
-
-    /**
-     * Allows the concrete class to fill in packet-type-specific details,
-     * typically optional parameters at the end of the packet.
-     */
-    abstract void finishPacket(ByteBuffer buffer);
-
-    // Set in unit tests, to ensure that the test does not break when run on different devices and
-    // on different releases.
-    static String testOverrideVendorId = null;
-    static String testOverrideHostname = null;
-
-    protected DhcpPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp,
-                         Inet4Address nextIp, Inet4Address relayIp,
-                         byte[] clientMac, boolean broadcast) {
-        mTransId = transId;
-        mSecs = secs;
-        mClientIp = clientIp;
-        mYourIp = yourIp;
-        mNextIp = nextIp;
-        mRelayIp = relayIp;
-        mClientMac = clientMac;
-        mBroadcast = broadcast;
-    }
-
-    /**
-     * Returns the transaction ID.
-     */
-    public int getTransactionId() {
-        return mTransId;
-    }
-
-    /**
-     * Returns the client MAC.
-     */
-    public byte[] getClientMac() {
-        return mClientMac;
-    }
-
-    // TODO: refactor DhcpClient to set clientId when constructing packets and remove
-    // hasExplicitClientId logic
-    /**
-     * Returns whether a client ID was set in the options for this packet.
-     */
-    public boolean hasExplicitClientId() {
-        return mClientId != null;
-    }
-
-    /**
-     * Convenience method to return the client ID if it was set explicitly, or null otherwise.
-     */
-    @Nullable
-    public byte[] getExplicitClientIdOrNull() {
-        return hasExplicitClientId() ? getClientId() : null;
-    }
-
-    /**
-     * Returns the client ID. If not set explicitly, this follows RFC 2132 and creates a client ID
-     * based on the hardware address.
-     */
-    public byte[] getClientId() {
-        final byte[] clientId;
-        if (hasExplicitClientId()) {
-            clientId = Arrays.copyOf(mClientId, mClientId.length);
-        } else {
-            clientId = new byte[mClientMac.length + 1];
-            clientId[0] = CLIENT_ID_ETHER;
-            System.arraycopy(mClientMac, 0, clientId, 1, mClientMac.length);
-        }
-        return clientId;
-    }
-
-    /**
-     * Returns whether a parameter is included in the parameter request list option of this packet.
-     *
-     * <p>If there is no parameter request list option in the packet, false is returned.
-     *
-     * @param paramId ID of the parameter, such as {@link #DHCP_MTU} or {@link #DHCP_HOST_NAME}.
-     */
-    public boolean hasRequestedParam(byte paramId) {
-        if (mRequestedParams == null) {
-            return false;
-        }
-
-        for (byte reqParam : mRequestedParams) {
-            if (reqParam == paramId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Creates a new L3 packet (including IP header) containing the
-     * DHCP udp packet.  This method relies upon the delegated method
-     * finishPacket() to insert the per-packet contents.
-     */
-    protected void fillInPacket(int encap, Inet4Address destIp,
-        Inet4Address srcIp, short destUdp, short srcUdp, ByteBuffer buf,
-        byte requestCode, boolean broadcast) {
-        byte[] destIpArray = destIp.getAddress();
-        byte[] srcIpArray = srcIp.getAddress();
-        int ipHeaderOffset = 0;
-        int ipLengthOffset = 0;
-        int ipChecksumOffset = 0;
-        int endIpHeader = 0;
-        int udpHeaderOffset = 0;
-        int udpLengthOffset = 0;
-        int udpChecksumOffset = 0;
-
-        buf.clear();
-        buf.order(ByteOrder.BIG_ENDIAN);
-
-        if (encap == ENCAP_L2) {
-            buf.put(ETHER_BROADCAST);
-            buf.put(mClientMac);
-            buf.putShort((short) OsConstants.ETH_P_IP);
-        }
-
-        // if a full IP packet needs to be generated, put the IP & UDP
-        // headers in place, and pre-populate with artificial values
-        // needed to seed the IP checksum.
-        if (encap <= ENCAP_L3) {
-            ipHeaderOffset = buf.position();
-            buf.put(IP_VERSION_HEADER_LEN);
-            buf.put(IP_TOS_LOWDELAY);    // tos: IPTOS_LOWDELAY
-            ipLengthOffset = buf.position();
-            buf.putShort((short)0);  // length
-            buf.putShort((short)0);  // id
-            buf.putShort(IP_FLAGS_OFFSET); // ip offset: don't fragment
-            buf.put(IP_TTL);    // TTL: use default 64 from RFC1340
-            buf.put(IP_TYPE_UDP);
-            ipChecksumOffset = buf.position();
-            buf.putShort((short) 0); // checksum
-
-            buf.put(srcIpArray);
-            buf.put(destIpArray);
-            endIpHeader = buf.position();
-
-            // UDP header
-            udpHeaderOffset = buf.position();
-            buf.putShort(srcUdp);
-            buf.putShort(destUdp);
-            udpLengthOffset = buf.position();
-            buf.putShort((short) 0); // length
-            udpChecksumOffset = buf.position();
-            buf.putShort((short) 0); // UDP checksum -- initially zero
-        }
-
-        // DHCP payload
-        buf.put(requestCode);
-        buf.put((byte) 1); // Hardware Type: Ethernet
-        buf.put((byte) mClientMac.length); // Hardware Address Length
-        buf.put((byte) 0); // Hop Count
-        buf.putInt(mTransId);  // Transaction ID
-        buf.putShort(mSecs); // Elapsed Seconds
-
-        if (broadcast) {
-            buf.putShort((short) 0x8000); // Flags
-        } else {
-            buf.putShort((short) 0x0000); // Flags
-        }
-
-        buf.put(mClientIp.getAddress());
-        buf.put(mYourIp.getAddress());
-        buf.put(mNextIp.getAddress());
-        buf.put(mRelayIp.getAddress());
-        buf.put(mClientMac);
-        buf.position(buf.position() +
-                     (HWADDR_LEN - mClientMac.length) // pad addr to 16 bytes
-                     + 64     // empty server host name (64 bytes)
-                     + 128);  // empty boot file name (128 bytes)
-        buf.putInt(DHCP_MAGIC_COOKIE); // magic number
-        finishPacket(buf);
-
-        // round up to an even number of octets
-        if ((buf.position() & 1) == 1) {
-            buf.put((byte) 0);
-        }
-
-        // If an IP packet is being built, the IP & UDP checksums must be
-        // computed.
-        if (encap <= ENCAP_L3) {
-            // fix UDP header: insert length
-            short udpLen = (short)(buf.position() - udpHeaderOffset);
-            buf.putShort(udpLengthOffset, udpLen);
-            // fix UDP header: checksum
-            // checksum for UDP at udpChecksumOffset
-            int udpSeed = 0;
-
-            // apply IPv4 pseudo-header.  Read IP address src and destination
-            // values from the IP header and accumulate checksum.
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 2));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 4));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 6));
-            udpSeed += intAbs(buf.getShort(ipChecksumOffset + 8));
-
-            // accumulate extra data for the pseudo-header
-            udpSeed += IP_TYPE_UDP;
-            udpSeed += udpLen;
-            // and compute UDP checksum
-            buf.putShort(udpChecksumOffset, (short) checksum(buf, udpSeed,
-                                                             udpHeaderOffset,
-                                                             buf.position()));
-            // fix IP header: insert length
-            buf.putShort(ipLengthOffset, (short)(buf.position() - ipHeaderOffset));
-            // fixup IP-header checksum
-            buf.putShort(ipChecksumOffset,
-                         (short) checksum(buf, 0, ipHeaderOffset, endIpHeader));
-        }
-    }
-
-    /**
-     * Converts a signed short value to an unsigned int value.  Needed
-     * because Java does not have unsigned types.
-     */
-    private static int intAbs(short v) {
-        return v & 0xFFFF;
-    }
-
-    /**
-     * Performs an IP checksum (used in IP header and across UDP
-     * payload) on the specified portion of a ByteBuffer.  The seed
-     * allows the checksum to commence with a specified value.
-     */
-    private int checksum(ByteBuffer buf, int seed, int start, int end) {
-        int sum = seed;
-        int bufPosition = buf.position();
-
-        // set position of original ByteBuffer, so that the ShortBuffer
-        // will be correctly initialized
-        buf.position(start);
-        ShortBuffer shortBuf = buf.asShortBuffer();
-
-        // re-set ByteBuffer position
-        buf.position(bufPosition);
-
-        short[] shortArray = new short[(end - start) / 2];
-        shortBuf.get(shortArray);
-
-        for (short s : shortArray) {
-            sum += intAbs(s);
-        }
-
-        start += shortArray.length * 2;
-
-        // see if a singleton byte remains
-        if (end != start) {
-            short b = buf.get(start);
-
-            // make it unsigned
-            if (b < 0) {
-                b += 256;
-            }
-
-            sum += b * 256;
-        }
-
-        sum = ((sum >> 16) & 0xFFFF) + (sum & 0xFFFF);
-        sum = ((sum + ((sum >> 16) & 0xFFFF)) & 0xFFFF);
-        int negated = ~sum;
-        return intAbs((short) negated);
-    }
-
-    /**
-     * Adds an optional parameter containing a single byte value.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, byte value) {
-        buf.put(type);
-        buf.put((byte) 1);
-        buf.put(value);
-    }
-
-    /**
-     * Adds an optional parameter containing an array of bytes.
-     *
-     * <p>This method is a no-op if the payload argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable byte[] payload) {
-        if (payload != null) {
-            if (payload.length > MAX_OPTION_LEN) {
-                throw new IllegalArgumentException("DHCP option too long: "
-                        + payload.length + " vs. " + MAX_OPTION_LEN);
-            }
-            buf.put(type);
-            buf.put((byte) payload.length);
-            buf.put(payload);
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing an IP address.
-     *
-     * <p>This method is a no-op if the address argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Inet4Address addr) {
-        if (addr != null) {
-            addTlv(buf, type, addr.getAddress());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a list of IP addresses.
-     *
-     * <p>This method is a no-op if the addresses argument is null or empty.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable List<Inet4Address> addrs) {
-        if (addrs == null || addrs.size() == 0) return;
-
-        int optionLen = 4 * addrs.size();
-        if (optionLen > MAX_OPTION_LEN) {
-            throw new IllegalArgumentException("DHCP option too long: "
-                    + optionLen + " vs. " + MAX_OPTION_LEN);
-        }
-
-        buf.put(type);
-        buf.put((byte)(optionLen));
-
-        for (Inet4Address addr : addrs) {
-            buf.put(addr.getAddress());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a short integer.
-     *
-     * <p>This method is a no-op if the value argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Short value) {
-        if (value != null) {
-            buf.put(type);
-            buf.put((byte) 2);
-            buf.putShort(value.shortValue());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing a simple integer.
-     *
-     * <p>This method is a no-op if the value argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable Integer value) {
-        if (value != null) {
-            buf.put(type);
-            buf.put((byte) 4);
-            buf.putInt(value.intValue());
-        }
-    }
-
-    /**
-     * Adds an optional parameter containing an ASCII string.
-     *
-     * <p>This method is a no-op if the string argument is null.
-     */
-    protected static void addTlv(ByteBuffer buf, byte type, @Nullable String str) {
-        if (str != null) {
-            try {
-                addTlv(buf, type, str.getBytes("US-ASCII"));
-            } catch (UnsupportedEncodingException e) {
-                throw new IllegalArgumentException("String is not US-ASCII: " + str);
-            }
-        }
-    }
-
-    /**
-     * Adds the special end-of-optional-parameters indicator.
-     */
-    protected static void addTlvEnd(ByteBuffer buf) {
-        buf.put((byte) 0xFF);
-    }
-
-    private String getVendorId() {
-        if (testOverrideVendorId != null) return testOverrideVendorId;
-        return "android-dhcp-" + Build.VERSION.RELEASE;
-    }
-
-    private String getHostname() {
-        if (testOverrideHostname != null) return testOverrideHostname;
-        return SystemProperties.get("net.hostname");
-    }
-
-    /**
-     * Adds common client TLVs.
-     *
-     * TODO: Does this belong here? The alternative would be to modify all the buildXyzPacket
-     * methods to take them.
-     */
-    protected void addCommonClientTlvs(ByteBuffer buf) {
-        addTlv(buf, DHCP_MAX_MESSAGE_SIZE, (short) MAX_LENGTH);
-        addTlv(buf, DHCP_VENDOR_CLASS_ID, getVendorId());
-        final String hn = getHostname();
-        if (!TextUtils.isEmpty(hn)) addTlv(buf, DHCP_HOST_NAME, hn);
-    }
-
-    protected void addCommonServerTlvs(ByteBuffer buf) {
-        addTlv(buf, DHCP_LEASE_TIME, mLeaseTime);
-        if (mLeaseTime != null && mLeaseTime != INFINITE_LEASE) {
-            // The client should renew at 1/2 the lease-expiry interval
-            addTlv(buf, DHCP_RENEWAL_TIME, (int) (Integer.toUnsignedLong(mLeaseTime) / 2));
-            // Default rebinding time is set as below by RFC2131
-            addTlv(buf, DHCP_REBINDING_TIME,
-                    (int) (Integer.toUnsignedLong(mLeaseTime) * 875L / 1000L));
-        }
-        addTlv(buf, DHCP_SUBNET_MASK, mSubnetMask);
-        addTlv(buf, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
-        addTlv(buf, DHCP_ROUTER, mGateways);
-        addTlv(buf, DHCP_DNS_SERVER, mDnsServers);
-        addTlv(buf, DHCP_DOMAIN_NAME, mDomainName);
-        addTlv(buf, DHCP_HOST_NAME, mHostName);
-        addTlv(buf, DHCP_VENDOR_INFO, mVendorInfo);
-        if (mMtu != null && Short.toUnsignedInt(mMtu) >= IPV4_MIN_MTU) {
-            addTlv(buf, DHCP_MTU, mMtu);
-        }
-    }
-
-    /**
-     * Converts a MAC from an array of octets to an ASCII string.
-     */
-    public static String macToString(byte[] mac) {
-        String macAddr = "";
-
-        for (int i = 0; i < mac.length; i++) {
-            String hexString = "0" + Integer.toHexString(mac[i]);
-
-            // substring operation grabs the last 2 digits: this
-            // allows signed bytes to be converted correctly.
-            macAddr += hexString.substring(hexString.length() - 2);
-
-            if (i != (mac.length - 1)) {
-                macAddr += ":";
-            }
-        }
-
-        return macAddr;
-    }
-
-    public String toString() {
-        String macAddr = macToString(mClientMac);
-
-        return macAddr;
-    }
-
-    /**
-     * Reads a four-octet value from a ByteBuffer and construct
-     * an IPv4 address from that value.
-     */
-    private static Inet4Address readIpAddress(ByteBuffer packet) {
-        Inet4Address result = null;
-        byte[] ipAddr = new byte[4];
-        packet.get(ipAddr);
-
-        try {
-            result = (Inet4Address) Inet4Address.getByAddress(ipAddr);
-        } catch (UnknownHostException ex) {
-            // ipAddr is numeric, so this should not be
-            // triggered.  However, if it is, just nullify
-            result = null;
-        }
-
-        return result;
-    }
-
-    /**
-     * Reads a string of specified length from the buffer.
-     */
-    private static String readAsciiString(ByteBuffer buf, int byteCount, boolean nullOk) {
-        byte[] bytes = new byte[byteCount];
-        buf.get(bytes);
-        int length = bytes.length;
-        if (!nullOk) {
-            // Stop at the first null byte. This is because some DHCP options (e.g., the domain
-            // name) are passed to netd via FrameworkListener, which refuses arguments containing
-            // null bytes. We don't do this by default because vendorInfo is an opaque string which
-            // could in theory contain null bytes.
-            for (length = 0; length < bytes.length; length++) {
-                if (bytes[length] == 0) {
-                    break;
-                }
-            }
-        }
-        return new String(bytes, 0, length, StandardCharsets.US_ASCII);
-    }
-
-    private static boolean isPacketToOrFromClient(short udpSrcPort, short udpDstPort) {
-        return (udpSrcPort == DHCP_CLIENT) || (udpDstPort == DHCP_CLIENT);
-    }
-
-    private static boolean isPacketServerToServer(short udpSrcPort, short udpDstPort) {
-        return (udpSrcPort == DHCP_SERVER) && (udpDstPort == DHCP_SERVER);
-    }
-
-    public static class ParseException extends Exception {
-        public final int errorCode;
-        public ParseException(int errorCode, String msg, Object... args) {
-            super(String.format(msg, args));
-            this.errorCode = errorCode;
-        }
-    }
-
-    /**
-     * Creates a concrete DhcpPacket from the supplied ByteBuffer.  The
-     * buffer may have an L2 encapsulation (which is the full EthernetII
-     * format starting with the source-address MAC) or an L3 encapsulation
-     * (which starts with the IP header).
-     * <br>
-     * A subset of the optional parameters are parsed and are stored
-     * in object fields.
-     */
-    @VisibleForTesting
-    static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException
-    {
-        // bootp parameters
-        int transactionId;
-        short secs;
-        Inet4Address clientIp;
-        Inet4Address yourIp;
-        Inet4Address nextIp;
-        Inet4Address relayIp;
-        byte[] clientMac;
-        byte[] clientId = null;
-        List<Inet4Address> dnsServers = new ArrayList<>();
-        List<Inet4Address> gateways = new ArrayList<>();  // aka router
-        Inet4Address serverIdentifier = null;
-        Inet4Address netMask = null;
-        String message = null;
-        String vendorId = null;
-        String vendorInfo = null;
-        byte[] expectedParams = null;
-        String hostName = null;
-        String domainName = null;
-        Inet4Address ipSrc = null;
-        Inet4Address ipDst = null;
-        Inet4Address bcAddr = null;
-        Inet4Address requestedIp = null;
-        String serverHostName;
-        byte optionOverload = 0;
-
-        // The following are all unsigned integers. Internally we store them as signed integers of
-        // the same length because that way we're guaranteed that they can't be out of the range of
-        // the unsigned field in the packet. Callers wanting to pass in an unsigned value will need
-        // to cast it.
-        Short mtu = null;
-        Short maxMessageSize = null;
-        Integer leaseTime = null;
-        Integer T1 = null;
-        Integer T2 = null;
-
-        // dhcp options
-        byte dhcpType = (byte) 0xFF;
-
-        packet.order(ByteOrder.BIG_ENDIAN);
-
-        // check to see if we need to parse L2, IP, and UDP encaps
-        if (pktType == ENCAP_L2) {
-            if (packet.remaining() < MIN_PACKET_LENGTH_L2) {
-                throw new ParseException(DhcpErrorEvent.L2_TOO_SHORT,
-                        "L2 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L2);
-            }
-
-            byte[] l2dst = new byte[6];
-            byte[] l2src = new byte[6];
-
-            packet.get(l2dst);
-            packet.get(l2src);
-
-            short l2type = packet.getShort();
-
-            if (l2type != OsConstants.ETH_P_IP) {
-                throw new ParseException(DhcpErrorEvent.L2_WRONG_ETH_TYPE,
-                        "Unexpected L2 type 0x%04x, expected 0x%04x", l2type, OsConstants.ETH_P_IP);
-            }
-        }
-
-        if (pktType <= ENCAP_L3) {
-            if (packet.remaining() < MIN_PACKET_LENGTH_L3) {
-                throw new ParseException(DhcpErrorEvent.L3_TOO_SHORT,
-                        "L3 packet too short, %d < %d", packet.remaining(), MIN_PACKET_LENGTH_L3);
-            }
-
-            byte ipTypeAndLength = packet.get();
-            int ipVersion = (ipTypeAndLength & 0xf0) >> 4;
-            if (ipVersion != 4) {
-                throw new ParseException(
-                        DhcpErrorEvent.L3_NOT_IPV4, "Invalid IP version %d", ipVersion);
-            }
-
-            // System.out.println("ipType is " + ipType);
-            byte ipDiffServicesField = packet.get();
-            short ipTotalLength = packet.getShort();
-            short ipIdentification = packet.getShort();
-            byte ipFlags = packet.get();
-            byte ipFragOffset = packet.get();
-            byte ipTTL = packet.get();
-            byte ipProto = packet.get();
-            short ipChksm = packet.getShort();
-
-            ipSrc = readIpAddress(packet);
-            ipDst = readIpAddress(packet);
-
-            if (ipProto != IP_TYPE_UDP) {
-                throw new ParseException(
-                        DhcpErrorEvent.L4_NOT_UDP, "Protocol not UDP: %d", ipProto);
-            }
-
-            // Skip options. This cannot cause us to read beyond the end of the buffer because the
-            // IPv4 header cannot be more than (0x0f * 4) = 60 bytes long, and that is less than
-            // MIN_PACKET_LENGTH_L3.
-            int optionWords = ((ipTypeAndLength & 0x0f) - 5);
-            for (int i = 0; i < optionWords; i++) {
-                packet.getInt();
-            }
-
-            // assume UDP
-            short udpSrcPort = packet.getShort();
-            short udpDstPort = packet.getShort();
-            short udpLen = packet.getShort();
-            short udpChkSum = packet.getShort();
-
-            // Only accept packets to or from the well-known client port (expressly permitting
-            // packets from ports other than the well-known server port; http://b/24687559), and
-            // server-to-server packets, e.g. for relays.
-            if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) &&
-                !isPacketServerToServer(udpSrcPort, udpDstPort)) {
-                // This should almost never happen because we use SO_ATTACH_FILTER on the packet
-                // socket to drop packets that don't have the right source ports. However, it's
-                // possible that a packet arrives between when the socket is bound and when the
-                // filter is set. http://b/26696823 .
-                throw new ParseException(DhcpErrorEvent.L4_WRONG_PORT,
-                        "Unexpected UDP ports %d->%d", udpSrcPort, udpDstPort);
-            }
-        }
-
-        // We need to check the length even for ENCAP_L3 because the IPv4 header is variable-length.
-        if (pktType > ENCAP_BOOTP || packet.remaining() < MIN_PACKET_LENGTH_BOOTP) {
-            throw new ParseException(DhcpErrorEvent.BOOTP_TOO_SHORT,
-                        "Invalid type or BOOTP packet too short, %d < %d",
-                        packet.remaining(), MIN_PACKET_LENGTH_BOOTP);
-        }
-
-        byte type = packet.get();
-        byte hwType = packet.get();
-        int addrLen = packet.get() & 0xff;
-        byte hops = packet.get();
-        transactionId = packet.getInt();
-        secs = packet.getShort();
-        short bootpFlags = packet.getShort();
-        boolean broadcast = (bootpFlags & 0x8000) != 0;
-        byte[] ipv4addr = new byte[4];
-
-        try {
-            packet.get(ipv4addr);
-            clientIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            yourIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            nextIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-            packet.get(ipv4addr);
-            relayIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
-        } catch (UnknownHostException ex) {
-            throw new ParseException(DhcpErrorEvent.L3_INVALID_IP,
-                    "Invalid IPv4 address: %s", Arrays.toString(ipv4addr));
-        }
-
-        // Some DHCP servers have been known to announce invalid client hardware address values such
-        // as 0xff. The legacy DHCP client accepted these becuause it does not check the length at
-        // all but only checks that the interface MAC address matches the first bytes of the address
-        // in the packets. We're a bit stricter: if the length is obviously invalid (i.e., bigger
-        // than the size of the field), we fudge it to 6 (Ethernet). http://b/23725795
-        // TODO: evaluate whether to make this test more liberal.
-        if (addrLen > HWADDR_LEN) {
-            addrLen = ETHER_BROADCAST.length;
-        }
-
-        clientMac = new byte[addrLen];
-        packet.get(clientMac);
-
-        // skip over address padding (16 octets allocated)
-        packet.position(packet.position() + (16 - addrLen));
-        serverHostName = readAsciiString(packet, 64, false);
-        packet.position(packet.position() + 128);
-
-        // Ensure this is a DHCP packet with a magic cookie, and not BOOTP. http://b/31850211
-        if (packet.remaining() < 4) {
-            throw new ParseException(DhcpErrorEvent.DHCP_NO_COOKIE, "not a DHCP message");
-        }
-
-        int dhcpMagicCookie = packet.getInt();
-        if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
-            throw new ParseException(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE,
-                    "Bad magic cookie 0x%08x, should be 0x%08x",
-                    dhcpMagicCookie, DHCP_MAGIC_COOKIE);
-        }
-
-        // parse options
-        boolean notFinishedOptions = true;
-
-        while ((packet.position() < packet.limit()) && notFinishedOptions) {
-            final byte optionType = packet.get(); // cannot underflow because position < limit
-            try {
-                if (optionType == DHCP_OPTION_END) {
-                    notFinishedOptions = false;
-                } else if (optionType == DHCP_OPTION_PAD) {
-                    // The pad option doesn't have a length field. Nothing to do.
-                } else {
-                    int optionLen = packet.get() & 0xFF;
-                    int expectedLen = 0;
-
-                    switch(optionType) {
-                        case DHCP_SUBNET_MASK:
-                            netMask = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_ROUTER:
-                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
-                                gateways.add(readIpAddress(packet));
-                            }
-                            break;
-                        case DHCP_DNS_SERVER:
-                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
-                                dnsServers.add(readIpAddress(packet));
-                            }
-                            break;
-                        case DHCP_HOST_NAME:
-                            expectedLen = optionLen;
-                            hostName = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_MTU:
-                            expectedLen = 2;
-                            mtu = packet.getShort();
-                            break;
-                        case DHCP_DOMAIN_NAME:
-                            expectedLen = optionLen;
-                            domainName = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_BROADCAST_ADDRESS:
-                            bcAddr = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_REQUESTED_IP:
-                            requestedIp = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_LEASE_TIME:
-                            leaseTime = Integer.valueOf(packet.getInt());
-                            expectedLen = 4;
-                            break;
-                        case DHCP_MESSAGE_TYPE:
-                            dhcpType = packet.get();
-                            expectedLen = 1;
-                            break;
-                        case DHCP_SERVER_IDENTIFIER:
-                            serverIdentifier = readIpAddress(packet);
-                            expectedLen = 4;
-                            break;
-                        case DHCP_PARAMETER_LIST:
-                            expectedParams = new byte[optionLen];
-                            packet.get(expectedParams);
-                            expectedLen = optionLen;
-                            break;
-                        case DHCP_MESSAGE:
-                            expectedLen = optionLen;
-                            message = readAsciiString(packet, optionLen, false);
-                            break;
-                        case DHCP_MAX_MESSAGE_SIZE:
-                            expectedLen = 2;
-                            maxMessageSize = Short.valueOf(packet.getShort());
-                            break;
-                        case DHCP_RENEWAL_TIME:
-                            expectedLen = 4;
-                            T1 = Integer.valueOf(packet.getInt());
-                            break;
-                        case DHCP_REBINDING_TIME:
-                            expectedLen = 4;
-                            T2 = Integer.valueOf(packet.getInt());
-                            break;
-                        case DHCP_VENDOR_CLASS_ID:
-                            expectedLen = optionLen;
-                            // Embedded nulls are safe as this does not get passed to netd.
-                            vendorId = readAsciiString(packet, optionLen, true);
-                            break;
-                        case DHCP_CLIENT_IDENTIFIER: { // Client identifier
-                            byte[] id = new byte[optionLen];
-                            packet.get(id);
-                            expectedLen = optionLen;
-                        } break;
-                        case DHCP_VENDOR_INFO:
-                            expectedLen = optionLen;
-                            // Embedded nulls are safe as this does not get passed to netd.
-                            vendorInfo = readAsciiString(packet, optionLen, true);
-                            break;
-                        case DHCP_OPTION_OVERLOAD:
-                            expectedLen = 1;
-                            optionOverload = packet.get();
-                            optionOverload &= OPTION_OVERLOAD_BOTH;
-                            break;
-                        default:
-                            // ignore any other parameters
-                            for (int i = 0; i < optionLen; i++) {
-                                expectedLen++;
-                                byte throwaway = packet.get();
-                            }
-                    }
-
-                    if (expectedLen != optionLen) {
-                        final int errorCode = DhcpErrorEvent.errorCodeWithOption(
-                                DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH, optionType);
-                        throw new ParseException(errorCode,
-                                "Invalid length %d for option %d, expected %d",
-                                optionLen, optionType, expectedLen);
-                    }
-                }
-            } catch (BufferUnderflowException e) {
-                final int errorCode = DhcpErrorEvent.errorCodeWithOption(
-                        DhcpErrorEvent.BUFFER_UNDERFLOW, optionType);
-                throw new ParseException(errorCode, "BufferUnderflowException");
-            }
-        }
-
-        DhcpPacket newPacket;
-
-        switch(dhcpType) {
-            case (byte) 0xFF:
-                throw new ParseException(DhcpErrorEvent.DHCP_NO_MSG_TYPE,
-                        "No DHCP message type option");
-            case DHCP_MESSAGE_TYPE_DISCOVER:
-                newPacket = new DhcpDiscoverPacket(transactionId, secs, relayIp, clientMac,
-                        broadcast, ipSrc);
-                break;
-            case DHCP_MESSAGE_TYPE_OFFER:
-                newPacket = new DhcpOfferPacket(
-                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_REQUEST:
-                newPacket = new DhcpRequestPacket(
-                    transactionId, secs, clientIp, relayIp, clientMac, broadcast);
-                break;
-            case DHCP_MESSAGE_TYPE_DECLINE:
-                newPacket = new DhcpDeclinePacket(
-                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
-                    clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_ACK:
-                newPacket = new DhcpAckPacket(
-                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_NAK:
-                newPacket = new DhcpNakPacket(
-                        transactionId, secs, relayIp, clientMac, broadcast);
-                break;
-            case DHCP_MESSAGE_TYPE_RELEASE:
-                if (serverIdentifier == null) {
-                    throw new ParseException(DhcpErrorEvent.MISC_ERROR,
-                            "DHCPRELEASE without server identifier");
-                }
-                newPacket = new DhcpReleasePacket(
-                        transactionId, serverIdentifier, clientIp, relayIp, clientMac);
-                break;
-            case DHCP_MESSAGE_TYPE_INFORM:
-                newPacket = new DhcpInformPacket(
-                    transactionId, secs, clientIp, yourIp, nextIp, relayIp,
-                    clientMac);
-                break;
-            default:
-                throw new ParseException(DhcpErrorEvent.DHCP_UNKNOWN_MSG_TYPE,
-                        "Unimplemented DHCP type %d", dhcpType);
-        }
-
-        newPacket.mBroadcastAddress = bcAddr;
-        newPacket.mClientId = clientId;
-        newPacket.mDnsServers = dnsServers;
-        newPacket.mDomainName = domainName;
-        newPacket.mGateways = gateways;
-        newPacket.mHostName = hostName;
-        newPacket.mLeaseTime = leaseTime;
-        newPacket.mMessage = message;
-        newPacket.mMtu = mtu;
-        newPacket.mRequestedIp = requestedIp;
-        newPacket.mRequestedParams = expectedParams;
-        newPacket.mServerIdentifier = serverIdentifier;
-        newPacket.mSubnetMask = netMask;
-        newPacket.mMaxMessageSize = maxMessageSize;
-        newPacket.mT1 = T1;
-        newPacket.mT2 = T2;
-        newPacket.mVendorId = vendorId;
-        newPacket.mVendorInfo = vendorInfo;
-        if ((optionOverload & OPTION_OVERLOAD_SNAME) == 0) {
-            newPacket.mServerHostName = serverHostName;
-        } else {
-            newPacket.mServerHostName = "";
-        }
-        return newPacket;
-    }
-
-    /**
-     * Parse a packet from an array of bytes, stopping at the given length.
-     */
-    public static DhcpPacket decodeFullPacket(byte[] packet, int length, int pktType)
-            throws ParseException {
-        ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN);
-        try {
-            return decodeFullPacket(buffer, pktType);
-        } catch (ParseException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new ParseException(DhcpErrorEvent.PARSING_ERROR, e.getMessage());
-        }
-    }
-
-    /**
-     *  Construct a DhcpResults object from a DHCP reply packet.
-     */
-    public DhcpResults toDhcpResults() {
-        Inet4Address ipAddress = mYourIp;
-        if (ipAddress.equals(IPV4_ADDR_ANY)) {
-            ipAddress = mClientIp;
-            if (ipAddress.equals(IPV4_ADDR_ANY)) {
-                return null;
-            }
-        }
-
-        int prefixLength;
-        if (mSubnetMask != null) {
-            try {
-                prefixLength = Inet4AddressUtils.netmaskToPrefixLength(mSubnetMask);
-            } catch (IllegalArgumentException e) {
-                // Non-contiguous netmask.
-                return null;
-            }
-        } else {
-            prefixLength = Inet4AddressUtils.getImplicitNetmask(ipAddress);
-        }
-
-        DhcpResults results = new DhcpResults();
-        try {
-            results.ipAddress = new LinkAddress(ipAddress, prefixLength);
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-
-        if (mGateways.size() > 0) {
-            results.gateway = mGateways.get(0);
-        }
-
-        results.dnsServers.addAll(mDnsServers);
-        results.domains = mDomainName;
-        results.serverAddress = mServerIdentifier;
-        results.vendorInfo = mVendorInfo;
-        results.leaseDuration = (mLeaseTime != null) ? mLeaseTime : INFINITE_LEASE;
-        results.mtu = (mMtu != null && MIN_MTU <= mMtu && mMtu <= MAX_MTU) ? mMtu : 0;
-        results.serverHostName = mServerHostName;
-
-        return results;
-    }
-
-    /**
-     * Returns the parsed lease time, in milliseconds, or 0 for infinite.
-     */
-    public long getLeaseTimeMillis() {
-        // dhcpcd treats the lack of a lease time option as an infinite lease.
-        if (mLeaseTime == null || mLeaseTime == INFINITE_LEASE) {
-            return 0;
-        } else if (0 <= mLeaseTime && mLeaseTime < MINIMUM_LEASE) {
-            return MINIMUM_LEASE * 1000;
-        } else {
-            return (mLeaseTime & 0xffffffffL) * 1000;
-        }
-    }
-
-    /**
-     * Builds a DHCP-DISCOVER packet from the required specified
-     * parameters.
-     */
-    public static ByteBuffer buildDiscoverPacket(int encap, int transactionId,
-        short secs, byte[] clientMac, boolean broadcast, byte[] expectedParams) {
-        DhcpPacket pkt = new DhcpDiscoverPacket(transactionId, secs, INADDR_ANY /* relayIp */,
-                clientMac, broadcast, INADDR_ANY /* srcIp */);
-        pkt.mRequestedParams = expectedParams;
-        return pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
-    }
-
-    /**
-     * Builds a DHCP-OFFER packet from the required specified
-     * parameters.
-     */
-    public static ByteBuffer buildOfferPacket(int encap, int transactionId,
-        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp,
-        Inet4Address yourIp, byte[] mac, Integer timeout, Inet4Address netMask,
-        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
-        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
-        short mtu) {
-        DhcpPacket pkt = new DhcpOfferPacket(
-                transactionId, (short) 0, broadcast, serverIpAddr, relayIp,
-                INADDR_ANY /* clientIp */, yourIp, mac);
-        pkt.mGateways = gateways;
-        pkt.mDnsServers = dnsServers;
-        pkt.mLeaseTime = timeout;
-        pkt.mDomainName = domainName;
-        pkt.mHostName = hostname;
-        pkt.mServerIdentifier = dhcpServerIdentifier;
-        pkt.mSubnetMask = netMask;
-        pkt.mBroadcastAddress = bcAddr;
-        pkt.mMtu = mtu;
-        if (metered) {
-            pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED;
-        }
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-ACK packet from the required specified parameters.
-     */
-    public static ByteBuffer buildAckPacket(int encap, int transactionId,
-        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp, Inet4Address yourIp,
-        Inet4Address requestClientIp, byte[] mac, Integer timeout, Inet4Address netMask,
-        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
-        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
-        short mtu) {
-        DhcpPacket pkt = new DhcpAckPacket(
-                transactionId, (short) 0, broadcast, serverIpAddr, relayIp, requestClientIp, yourIp,
-                mac);
-        pkt.mGateways = gateways;
-        pkt.mDnsServers = dnsServers;
-        pkt.mLeaseTime = timeout;
-        pkt.mDomainName = domainName;
-        pkt.mHostName = hostname;
-        pkt.mSubnetMask = netMask;
-        pkt.mServerIdentifier = dhcpServerIdentifier;
-        pkt.mBroadcastAddress = bcAddr;
-        pkt.mMtu = mtu;
-        if (metered) {
-            pkt.mVendorInfo = VENDOR_INFO_ANDROID_METERED;
-        }
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-NAK packet from the required specified parameters.
-     */
-    public static ByteBuffer buildNakPacket(int encap, int transactionId, Inet4Address serverIpAddr,
-            Inet4Address relayIp, byte[] mac, boolean broadcast, String message) {
-        DhcpPacket pkt = new DhcpNakPacket(
-                transactionId, (short) 0, relayIp, mac, broadcast);
-        pkt.mMessage = message;
-        pkt.mServerIdentifier = serverIpAddr;
-        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
-    }
-
-    /**
-     * Builds a DHCP-REQUEST packet from the required specified parameters.
-     */
-    public static ByteBuffer buildRequestPacket(int encap,
-        int transactionId, short secs, Inet4Address clientIp, boolean broadcast,
-        byte[] clientMac, Inet4Address requestedIpAddress,
-        Inet4Address serverIdentifier, byte[] requestedParams, String hostName) {
-        DhcpPacket pkt = new DhcpRequestPacket(transactionId, secs, clientIp,
-                INADDR_ANY /* relayIp */, clientMac, broadcast);
-        pkt.mRequestedIp = requestedIpAddress;
-        pkt.mServerIdentifier = serverIdentifier;
-        pkt.mHostName = hostName;
-        pkt.mRequestedParams = requestedParams;
-        ByteBuffer result = pkt.buildPacket(encap, DHCP_SERVER, DHCP_CLIENT);
-        return result;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java b/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
deleted file mode 100644
index 97d26c7..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpPacketListener.java
+++ /dev/null
@@ -1,88 +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.net.dhcp;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.util.FdEventsReader;
-import android.os.Handler;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-import java.net.Inet4Address;
-import java.net.InetSocketAddress;
-
-/**
- * A {@link FdEventsReader} to receive and parse {@link DhcpPacket}.
- * @hide
- */
-abstract class DhcpPacketListener extends FdEventsReader<DhcpPacketListener.Payload> {
-    static final class Payload {
-        protected final byte[] mBytes = new byte[DhcpPacket.MAX_LENGTH];
-        protected Inet4Address mSrcAddr;
-        protected int mSrcPort;
-    }
-
-    DhcpPacketListener(@NonNull Handler handler) {
-        super(handler, new Payload());
-    }
-
-    @Override
-    protected int recvBufSize(@NonNull Payload buffer) {
-        return buffer.mBytes.length;
-    }
-
-    @Override
-    protected final void handlePacket(@NonNull Payload recvbuf, int length) {
-        if (recvbuf.mSrcAddr == null) {
-            return;
-        }
-
-        try {
-            final DhcpPacket packet = DhcpPacket.decodeFullPacket(recvbuf.mBytes, length,
-                    DhcpPacket.ENCAP_BOOTP);
-            onReceive(packet, recvbuf.mSrcAddr, recvbuf.mSrcPort);
-        } catch (DhcpPacket.ParseException e) {
-            logParseError(recvbuf.mBytes, length, e);
-        }
-    }
-
-    @Override
-    protected int readPacket(@NonNull FileDescriptor fd, @NonNull Payload packetBuffer)
-            throws Exception {
-        final InetSocketAddress addr = new InetSocketAddress(0);
-        final int read = Os.recvfrom(
-                fd, packetBuffer.mBytes, 0, packetBuffer.mBytes.length, 0 /* flags */, addr);
-
-        // Buffers with null srcAddr will be dropped in handlePacket()
-        packetBuffer.mSrcAddr = inet4AddrOrNull(addr);
-        packetBuffer.mSrcPort = addr.getPort();
-        return read;
-    }
-
-    @Nullable
-    private static Inet4Address inet4AddrOrNull(@NonNull InetSocketAddress addr) {
-        return addr.getAddress() instanceof Inet4Address
-                ? (Inet4Address) addr.getAddress()
-                : null;
-    }
-
-    protected abstract void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr,
-            int srcPort);
-    protected abstract void logParseError(@NonNull byte[] packet, int length,
-            @NonNull DhcpPacket.ParseException e);
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java
deleted file mode 100644
index 3958303..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpReleasePacket.java
+++ /dev/null
@@ -1,58 +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.net.dhcp;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * Implements DHCP-RELEASE
- */
-class DhcpReleasePacket extends DhcpPacket {
-
-    final Inet4Address mClientAddr;
-
-    /**
-     * Generates a RELEASE packet with the specified parameters.
-     */
-    public DhcpReleasePacket(int transId, Inet4Address serverId, Inet4Address clientAddr,
-            Inet4Address relayIp, byte[] clientMac) {
-        super(transId, (short)0, clientAddr, INADDR_ANY /* yourIp */, INADDR_ANY /* nextIp */,
-                relayIp, clientMac, false /* broadcast */);
-        mServerIdentifier = serverId;
-        mClientAddr = clientAddr;
-    }
-
-
-    @Override
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-        fillInPacket(encap, mServerIdentifier /* destIp */, mClientIp /* srcIp */, destUdp, srcUdp,
-                result, DHCP_BOOTREPLY, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    @Override
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_RELEASE);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        addCommonClientTlvs(buffer);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java b/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java
deleted file mode 100644
index 231d0457..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpRequestPacket.java
+++ /dev/null
@@ -1,71 +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.
- */
-
-package android.net.dhcp;
-
-import android.util.Log;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the DHCP-REQUEST packet.
- */
-class DhcpRequestPacket extends DhcpPacket {
-    /**
-     * Generates a REQUEST packet with the specified parameters.
-     */
-    DhcpRequestPacket(int transId, short secs, Inet4Address clientIp, Inet4Address relayIp,
-            byte[] clientMac, boolean broadcast) {
-        super(transId, secs, clientIp, INADDR_ANY, INADDR_ANY, relayIp, clientMac, broadcast);
-    }
-
-    public String toString() {
-        String s = super.toString();
-        return s + " REQUEST, desired IP " + mRequestedIp + " from host '"
-            + mHostName + "', param list length "
-            + (mRequestedParams == null ? 0 : mRequestedParams.length);
-    }
-
-    /**
-     * Fills in a packet with the requested REQUEST attributes.
-     */
-    public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) {
-        ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-
-        fillInPacket(encap, INADDR_BROADCAST, INADDR_ANY, destUdp, srcUdp,
-            result, DHCP_BOOTREQUEST, mBroadcast);
-        result.flip();
-        return result;
-    }
-
-    /**
-     * Adds the optional parameters to the client-generated REQUEST packet.
-     */
-    void finishPacket(ByteBuffer buffer) {
-        addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_REQUEST);
-        addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId());
-        if (!INADDR_ANY.equals(mRequestedIp)) {
-            addTlv(buffer, DHCP_REQUESTED_IP, mRequestedIp);
-        }
-        if (!INADDR_ANY.equals(mServerIdentifier)) {
-            addTlv(buffer, DHCP_SERVER_IDENTIFIER, mServerIdentifier);
-        }
-        addCommonClientTlvs(buffer);
-        addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams);
-        addTlvEnd(buffer);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
deleted file mode 100644
index b8ab94c..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java
+++ /dev/null
@@ -1,655 +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.net.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_CLIENT;
-import static android.net.dhcp.DhcpPacket.DHCP_HOST_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_SERVER;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_BROADCAST;
-import static android.system.OsConstants.SO_REUSEADDR;
-
-import static com.android.internal.util.TrafficStatsConstants.TAG_SYSTEM_DHCP_SERVER;
-import static com.android.server.util.NetworkStackConstants.INFINITE_LEASE;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ALL;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import static java.lang.Integer.toUnsignedLong;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.INetworkStackStatusCallback;
-import android.net.MacAddress;
-import android.net.TrafficStats;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SharedLog;
-import android.net.util.SocketUtils;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.HexDump;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-
-/**
- * A DHCPv4 server.
- *
- * <p>This server listens for and responds to packets on a single interface. It considers itself
- * authoritative for all leases on the subnet, which means that DHCP requests for unknown leases of
- * unknown hosts receive a reply instead of being ignored.
- *
- * <p>The server is single-threaded (including send/receive operations): all internal operations are
- * done on the provided {@link Looper}. Public methods are thread-safe and will schedule operations
- * on the looper asynchronously.
- * @hide
- */
-public class DhcpServer extends IDhcpServer.Stub {
-    private static final String REPO_TAG = "Repository";
-
-    // Lease time to transmit to client instead of a negative time in case a lease expired before
-    // the server could send it (if the server process is suspended for example).
-    private static final int EXPIRED_FALLBACK_LEASE_TIME_SECS = 120;
-
-    private static final int CMD_START_DHCP_SERVER = 1;
-    private static final int CMD_STOP_DHCP_SERVER = 2;
-    private static final int CMD_UPDATE_PARAMS = 3;
-
-    @NonNull
-    private final HandlerThread mHandlerThread;
-    @NonNull
-    private final String mIfName;
-    @NonNull
-    private final DhcpLeaseRepository mLeaseRepo;
-    @NonNull
-    private final SharedLog mLog;
-    @NonNull
-    private final Dependencies mDeps;
-    @NonNull
-    private final Clock mClock;
-
-    @Nullable
-    private volatile ServerHandler mHandler;
-
-    // Accessed only on the handler thread
-    @Nullable
-    private DhcpPacketListener mPacketListener;
-    @Nullable
-    private FileDescriptor mSocket;
-    @NonNull
-    private DhcpServingParams mServingParams;
-
-    /**
-     * Clock to be used by DhcpServer to track time for lease expiration.
-     *
-     * <p>The clock should track time as may be measured by clients obtaining a lease. It does not
-     * need to be monotonous across restarts of the server as long as leases are cleared when the
-     * server is stopped.
-     */
-    public static class Clock {
-        /**
-         * @see SystemClock#elapsedRealtime()
-         */
-        public long elapsedRealtime() {
-            return SystemClock.elapsedRealtime();
-        }
-    }
-
-    /**
-     * Dependencies for the DhcpServer. Useful to be mocked in tests.
-     */
-    public interface Dependencies {
-        /**
-         * Send a packet to the specified datagram socket.
-         *
-         * @param fd File descriptor of the socket.
-         * @param buffer Data to be sent.
-         * @param dst Destination address of the packet.
-         */
-        void sendPacket(@NonNull FileDescriptor fd, @NonNull ByteBuffer buffer,
-                @NonNull InetAddress dst) throws ErrnoException, IOException;
-
-        /**
-         * Create a DhcpLeaseRepository for the server.
-         * @param servingParams Parameters used to serve DHCP requests.
-         * @param log Log to be used by the repository.
-         * @param clock Clock that the repository must use to track time.
-         */
-        DhcpLeaseRepository makeLeaseRepository(@NonNull DhcpServingParams servingParams,
-                @NonNull SharedLog log, @NonNull Clock clock);
-
-        /**
-         * Create a packet listener that will send packets to be processed.
-         */
-        DhcpPacketListener makePacketListener();
-
-        /**
-         * Create a clock that the server will use to track time.
-         */
-        Clock makeClock();
-
-        /**
-         * Add an entry to the ARP cache table.
-         * @param fd Datagram socket file descriptor that must use the new entry.
-         */
-        void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr,
-                @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException;
-
-        /**
-         * Verify that the caller is allowed to call public methods on DhcpServer.
-         * @throws SecurityException The caller is not allowed to call public methods on DhcpServer.
-         */
-        void checkCaller() throws SecurityException;
-    }
-
-    private class DependenciesImpl implements Dependencies {
-        @Override
-        public void sendPacket(@NonNull FileDescriptor fd, @NonNull ByteBuffer buffer,
-                @NonNull InetAddress dst) throws ErrnoException, IOException {
-            Os.sendto(fd, buffer, 0, dst, DhcpPacket.DHCP_CLIENT);
-        }
-
-        @Override
-        public DhcpLeaseRepository makeLeaseRepository(@NonNull DhcpServingParams servingParams,
-                @NonNull SharedLog log, @NonNull Clock clock) {
-            return new DhcpLeaseRepository(
-                    DhcpServingParams.makeIpPrefix(servingParams.serverAddr),
-                    servingParams.excludedAddrs,
-                    servingParams.dhcpLeaseTimeSecs * 1000, log.forSubComponent(REPO_TAG), clock);
-        }
-
-        @Override
-        public DhcpPacketListener makePacketListener() {
-            return new PacketListener();
-        }
-
-        @Override
-        public Clock makeClock() {
-            return new Clock();
-        }
-
-        @Override
-        public void addArpEntry(@NonNull Inet4Address ipv4Addr, @NonNull MacAddress ethAddr,
-                @NonNull String ifname, @NonNull FileDescriptor fd) throws IOException {
-            NetworkStackUtils.addArpEntry(ipv4Addr, ethAddr, ifname, fd);
-        }
-
-        @Override
-        public void checkCaller() {
-            checkNetworkStackCallingPermission();
-        }
-    }
-
-    private static class MalformedPacketException extends Exception {
-        MalformedPacketException(String message, Throwable t) {
-            super(message, t);
-        }
-    }
-
-    public DhcpServer(@NonNull String ifName,
-            @NonNull DhcpServingParams params, @NonNull SharedLog log) {
-        this(new HandlerThread(DhcpServer.class.getSimpleName() + "." + ifName),
-                ifName, params, log, null);
-    }
-
-    @VisibleForTesting
-    DhcpServer(@NonNull HandlerThread handlerThread, @NonNull String ifName,
-            @NonNull DhcpServingParams params, @NonNull SharedLog log,
-            @Nullable Dependencies deps) {
-        if (deps == null) {
-            deps = new DependenciesImpl();
-        }
-        mHandlerThread = handlerThread;
-        mIfName = ifName;
-        mServingParams = params;
-        mLog = log;
-        mDeps = deps;
-        mClock = deps.makeClock();
-        mLeaseRepo = deps.makeLeaseRepository(mServingParams, mLog, mClock);
-    }
-
-    /**
-     * Start listening for and responding to packets.
-     *
-     * <p>It is not legal to call this method more than once; in particular the server cannot be
-     * restarted after being stopped.
-     */
-    @Override
-    public void start(@Nullable INetworkStackStatusCallback cb) {
-        mDeps.checkCaller();
-        mHandlerThread.start();
-        mHandler = new ServerHandler(mHandlerThread.getLooper());
-        sendMessage(CMD_START_DHCP_SERVER, cb);
-    }
-
-    /**
-     * Update serving parameters. All subsequently received requests will be handled with the new
-     * parameters, and current leases that are incompatible with the new parameters are dropped.
-     */
-    @Override
-    public void updateParams(@Nullable DhcpServingParamsParcel params,
-            @Nullable INetworkStackStatusCallback cb) throws RemoteException {
-        mDeps.checkCaller();
-        final DhcpServingParams parsedParams;
-        try {
-            // throws InvalidParameterException with null params
-            parsedParams = DhcpServingParams.fromParcelableObject(params);
-        } catch (DhcpServingParams.InvalidParameterException e) {
-            mLog.e("Invalid parameters sent to DhcpServer", e);
-            if (cb != null) {
-                cb.onStatusAvailable(STATUS_INVALID_ARGUMENT);
-            }
-            return;
-        }
-        sendMessage(CMD_UPDATE_PARAMS, new Pair<>(parsedParams, cb));
-    }
-
-    /**
-     * Stop listening for packets.
-     *
-     * <p>As the server is stopped asynchronously, some packets may still be processed shortly after
-     * calling this method.
-     */
-    @Override
-    public void stop(@Nullable INetworkStackStatusCallback cb) {
-        mDeps.checkCaller();
-        sendMessage(CMD_STOP_DHCP_SERVER, cb);
-    }
-
-    private void sendMessage(int what, @Nullable Object obj) {
-        if (mHandler == null) {
-            mLog.e("Attempting to send a command to stopped DhcpServer: " + what);
-            return;
-        }
-        mHandler.sendMessage(mHandler.obtainMessage(what, obj));
-    }
-
-    private class ServerHandler extends Handler {
-        ServerHandler(@NonNull Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            final INetworkStackStatusCallback cb;
-            switch (msg.what) {
-                case CMD_UPDATE_PARAMS:
-                    final Pair<DhcpServingParams, INetworkStackStatusCallback> pair =
-                            (Pair<DhcpServingParams, INetworkStackStatusCallback>) msg.obj;
-                    final DhcpServingParams params = pair.first;
-                    mServingParams = params;
-                    mLeaseRepo.updateParams(
-                            DhcpServingParams.makeIpPrefix(mServingParams.serverAddr),
-                            params.excludedAddrs,
-                            params.dhcpLeaseTimeSecs);
-
-                    cb = pair.second;
-                    break;
-                case CMD_START_DHCP_SERVER:
-                    mPacketListener = mDeps.makePacketListener();
-                    mPacketListener.start();
-                    cb = (INetworkStackStatusCallback) msg.obj;
-                    break;
-                case CMD_STOP_DHCP_SERVER:
-                    if (mPacketListener != null) {
-                        mPacketListener.stop();
-                        mPacketListener = null;
-                    }
-                    mHandlerThread.quitSafely();
-                    cb = (INetworkStackStatusCallback) msg.obj;
-                    break;
-                default:
-                    return;
-            }
-            if (cb != null) {
-                try {
-                    cb.onStatusAvailable(STATUS_SUCCESS);
-                } catch (RemoteException e) {
-                    mLog.e("Could not send status back to caller", e);
-                }
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void processPacket(@NonNull DhcpPacket packet, int srcPort) {
-        final String packetType = packet.getClass().getSimpleName();
-        if (srcPort != DHCP_CLIENT) {
-            mLog.logf("Ignored packet of type %s sent from client port %d", packetType, srcPort);
-            return;
-        }
-
-        mLog.log("Received packet of type " + packetType);
-        final Inet4Address sid = packet.mServerIdentifier;
-        if (sid != null && !sid.equals(mServingParams.serverAddr.getAddress())) {
-            mLog.log("Packet ignored due to wrong server identifier: " + sid);
-            return;
-        }
-
-        try {
-            if (packet instanceof DhcpDiscoverPacket) {
-                processDiscover((DhcpDiscoverPacket) packet);
-            } else if (packet instanceof DhcpRequestPacket) {
-                processRequest((DhcpRequestPacket) packet);
-            } else if (packet instanceof DhcpReleasePacket) {
-                processRelease((DhcpReleasePacket) packet);
-            } else {
-                mLog.e("Unknown packet type: " + packet.getClass().getSimpleName());
-            }
-        } catch (MalformedPacketException e) {
-            // Not an internal error: only logging exception message, not stacktrace
-            mLog.e("Ignored malformed packet: " + e.getMessage());
-        }
-    }
-
-    private void logIgnoredPacketInvalidSubnet(DhcpLeaseRepository.InvalidSubnetException e) {
-        // Not an internal error: only logging exception message, not stacktrace
-        mLog.e("Ignored packet from invalid subnet: " + e.getMessage());
-    }
-
-    private void processDiscover(@NonNull DhcpDiscoverPacket packet)
-            throws MalformedPacketException {
-        final DhcpLease lease;
-        final MacAddress clientMac = getMacAddr(packet);
-        try {
-            lease = mLeaseRepo.getOffer(packet.getExplicitClientIdOrNull(), clientMac,
-                    packet.mRelayIp, packet.mRequestedIp, packet.mHostName);
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) {
-            transmitNak(packet, "Out of addresses to offer");
-            return;
-        } catch (DhcpLeaseRepository.InvalidSubnetException e) {
-            logIgnoredPacketInvalidSubnet(e);
-            return;
-        }
-
-        transmitOffer(packet, lease, clientMac);
-    }
-
-    private void processRequest(@NonNull DhcpRequestPacket packet) throws MalformedPacketException {
-        // If set, packet SID matches with this server's ID as checked in processPacket().
-        final boolean sidSet = packet.mServerIdentifier != null;
-        final DhcpLease lease;
-        final MacAddress clientMac = getMacAddr(packet);
-        try {
-            lease = mLeaseRepo.requestLease(packet.getExplicitClientIdOrNull(), clientMac,
-                    packet.mClientIp, packet.mRelayIp, packet.mRequestedIp, sidSet,
-                    packet.mHostName);
-        } catch (DhcpLeaseRepository.InvalidAddressException e) {
-            transmitNak(packet, "Invalid requested address");
-            return;
-        } catch (DhcpLeaseRepository.InvalidSubnetException e) {
-            logIgnoredPacketInvalidSubnet(e);
-            return;
-        }
-
-        transmitAck(packet, lease, clientMac);
-    }
-
-    private void processRelease(@NonNull DhcpReleasePacket packet)
-            throws MalformedPacketException {
-        final byte[] clientId = packet.getExplicitClientIdOrNull();
-        final MacAddress macAddr = getMacAddr(packet);
-        // Don't care about success (there is no ACK/NAK); logging is already done in the repository
-        mLeaseRepo.releaseLease(clientId, macAddr, packet.mClientIp);
-    }
-
-    private Inet4Address getAckOrOfferDst(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            boolean broadcastFlag) {
-        // Unless relayed or broadcast, send to client IP if already configured on the client, or to
-        // the lease address if the client has no configured address
-        if (!isEmpty(request.mRelayIp)) {
-            return request.mRelayIp;
-        } else if (broadcastFlag) {
-            return IPV4_ADDR_ALL;
-        } else if (!isEmpty(request.mClientIp)) {
-            return request.mClientIp;
-        } else {
-            return lease.getNetAddr();
-        }
-    }
-
-    /**
-     * Determine whether the broadcast flag should be set in the BOOTP packet flags. This does not
-     * apply to NAK responses, which should always have it set.
-     */
-    private static boolean getBroadcastFlag(@NonNull DhcpPacket request, @NonNull DhcpLease lease) {
-        // No broadcast flag if the client already has a configured IP to unicast to. RFC2131 #4.1
-        // has some contradictions regarding broadcast behavior if a client already has an IP
-        // configured and sends a request with both ciaddr (renew/rebind) and the broadcast flag
-        // set. Sending a unicast response to ciaddr matches previous behavior and is more
-        // efficient.
-        // If the client has no configured IP, broadcast if requested by the client or if the lease
-        // address cannot be used to send a unicast reply either.
-        return isEmpty(request.mClientIp) && (request.mBroadcast || isEmpty(lease.getNetAddr()));
-    }
-
-    /**
-     * Get the hostname from a lease if non-empty and requested in the incoming request.
-     * @param request The incoming request.
-     * @return The hostname, or null if not requested or empty.
-     */
-    @Nullable
-    private static String getHostnameIfRequested(@NonNull DhcpPacket request,
-            @NonNull DhcpLease lease) {
-        return request.hasRequestedParam(DHCP_HOST_NAME) && !TextUtils.isEmpty(lease.getHostname())
-                ? lease.getHostname()
-                : null;
-    }
-
-    private boolean transmitOffer(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            @NonNull MacAddress clientMac) {
-        final boolean broadcastFlag = getBroadcastFlag(request, lease);
-        final int timeout = getLeaseTimeout(lease);
-        final Inet4Address prefixMask =
-                getPrefixMaskAsInet4Address(mServingParams.serverAddr.getPrefixLength());
-        final Inet4Address broadcastAddr = getBroadcastAddress(
-                mServingParams.getServerInet4Addr(), mServingParams.serverAddr.getPrefixLength());
-        final String hostname = getHostnameIfRequested(request, lease);
-        final ByteBuffer offerPacket = DhcpPacket.buildOfferPacket(
-                ENCAP_BOOTP, request.mTransId, broadcastFlag, mServingParams.getServerInet4Addr(),
-                request.mRelayIp, lease.getNetAddr(), request.mClientMac, timeout, prefixMask,
-                broadcastAddr, new ArrayList<>(mServingParams.defaultRouters),
-                new ArrayList<>(mServingParams.dnsServers),
-                mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
-                mServingParams.metered, (short) mServingParams.linkMtu);
-
-        return transmitOfferOrAckPacket(offerPacket, request, lease, clientMac, broadcastFlag);
-    }
-
-    private boolean transmitAck(@NonNull DhcpPacket request, @NonNull DhcpLease lease,
-            @NonNull MacAddress clientMac) {
-        // TODO: replace DhcpPacket's build methods with real builders and use common code with
-        // transmitOffer above
-        final boolean broadcastFlag = getBroadcastFlag(request, lease);
-        final int timeout = getLeaseTimeout(lease);
-        final String hostname = getHostnameIfRequested(request, lease);
-        final ByteBuffer ackPacket = DhcpPacket.buildAckPacket(ENCAP_BOOTP, request.mTransId,
-                broadcastFlag, mServingParams.getServerInet4Addr(), request.mRelayIp,
-                lease.getNetAddr(), request.mClientIp, request.mClientMac, timeout,
-                mServingParams.getPrefixMaskAsAddress(), mServingParams.getBroadcastAddress(),
-                new ArrayList<>(mServingParams.defaultRouters),
-                new ArrayList<>(mServingParams.dnsServers),
-                mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
-                mServingParams.metered, (short) mServingParams.linkMtu);
-
-        return transmitOfferOrAckPacket(ackPacket, request, lease, clientMac, broadcastFlag);
-    }
-
-    private boolean transmitNak(DhcpPacket request, String message) {
-        mLog.w("Transmitting NAK: " + message);
-        // Always set broadcast flag for NAK: client may not have a correct IP
-        final ByteBuffer nakPacket = DhcpPacket.buildNakPacket(
-                ENCAP_BOOTP, request.mTransId, mServingParams.getServerInet4Addr(),
-                request.mRelayIp, request.mClientMac, true /* broadcast */, message);
-
-        final Inet4Address dst = isEmpty(request.mRelayIp)
-                ? IPV4_ADDR_ALL
-                : request.mRelayIp;
-        return transmitPacket(nakPacket, DhcpNakPacket.class.getSimpleName(), dst);
-    }
-
-    private boolean transmitOfferOrAckPacket(@NonNull ByteBuffer buf, @NonNull DhcpPacket request,
-            @NonNull DhcpLease lease, @NonNull MacAddress clientMac, boolean broadcastFlag) {
-        mLog.logf("Transmitting %s with lease %s", request.getClass().getSimpleName(), lease);
-        // Client may not yet respond to ARP for the lease address, which may be the destination
-        // address. Add an entry to the ARP cache to save future ARP probes and make sure the
-        // packet reaches its destination.
-        if (!addArpEntry(clientMac, lease.getNetAddr())) {
-            // Logging for error already done
-            return false;
-        }
-        final Inet4Address dst = getAckOrOfferDst(request, lease, broadcastFlag);
-        return transmitPacket(buf, request.getClass().getSimpleName(), dst);
-    }
-
-    private boolean transmitPacket(@NonNull ByteBuffer buf, @NonNull String packetTypeTag,
-            @NonNull Inet4Address dst) {
-        try {
-            mDeps.sendPacket(mSocket, buf, dst);
-        } catch (ErrnoException | IOException e) {
-            mLog.e("Can't send packet " + packetTypeTag, e);
-            return false;
-        }
-        return true;
-    }
-
-    private boolean addArpEntry(@NonNull MacAddress macAddr, @NonNull Inet4Address inetAddr) {
-        try {
-            mDeps.addArpEntry(inetAddr, macAddr, mIfName, mSocket);
-            return true;
-        } catch (IOException e) {
-            mLog.e("Error adding client to ARP table", e);
-            return false;
-        }
-    }
-
-    /**
-     * Get the remaining lease time in seconds, starting from {@link Clock#elapsedRealtime()}.
-     *
-     * <p>This is an unsigned 32-bit integer, so it cannot be read as a standard (signed) Java int.
-     * The return value is only intended to be used to populate the lease time field in a DHCP
-     * response, considering that lease time is an unsigned 32-bit integer field in DHCP packets.
-     *
-     * <p>Lease expiration times are tracked internally with millisecond precision: this method
-     * returns a rounded down value.
-     */
-    private int getLeaseTimeout(@NonNull DhcpLease lease) {
-        final long remainingTimeSecs = (lease.getExpTime() - mClock.elapsedRealtime()) / 1000;
-        if (remainingTimeSecs < 0) {
-            mLog.e("Processing expired lease " + lease);
-            return EXPIRED_FALLBACK_LEASE_TIME_SECS;
-        }
-
-        if (remainingTimeSecs >= toUnsignedLong(INFINITE_LEASE)) {
-            return INFINITE_LEASE;
-        }
-
-        return (int) remainingTimeSecs;
-    }
-
-    /**
-     * Get the client MAC address from a packet.
-     *
-     * @throws MalformedPacketException The address in the packet uses an unsupported format.
-     */
-    @NonNull
-    private MacAddress getMacAddr(@NonNull DhcpPacket packet) throws MalformedPacketException {
-        try {
-            return MacAddress.fromBytes(packet.getClientMac());
-        } catch (IllegalArgumentException e) {
-            final String message = "Invalid MAC address in packet: "
-                    + HexDump.dumpHexString(packet.getClientMac());
-            throw new MalformedPacketException(message, e);
-        }
-    }
-
-    private static boolean isEmpty(@Nullable Inet4Address address) {
-        return address == null || IPV4_ADDR_ANY.equals(address);
-    }
-
-    private class PacketListener extends DhcpPacketListener {
-        PacketListener() {
-            super(mHandler);
-        }
-
-        @Override
-        protected void onReceive(@NonNull DhcpPacket packet, @NonNull Inet4Address srcAddr,
-                int srcPort) {
-            processPacket(packet, srcPort);
-        }
-
-        @Override
-        protected void logError(@NonNull String msg, Exception e) {
-            mLog.e("Error receiving packet: " + msg, e);
-        }
-
-        @Override
-        protected void logParseError(@NonNull byte[] packet, int length,
-                @NonNull DhcpPacket.ParseException e) {
-            mLog.e("Error parsing packet", e);
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            // TODO: have and use an API to set a socket tag without going through the thread tag
-            final int oldTag = TrafficStats.getAndSetThreadStatsTag(TAG_SYSTEM_DHCP_SERVER);
-            try {
-                mSocket = Os.socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-                SocketUtils.bindSocketToInterface(mSocket, mIfName);
-                Os.setsockoptInt(mSocket, SOL_SOCKET, SO_REUSEADDR, 1);
-                Os.setsockoptInt(mSocket, SOL_SOCKET, SO_BROADCAST, 1);
-                Os.bind(mSocket, IPV4_ADDR_ANY, DHCP_SERVER);
-
-                return mSocket;
-            } catch (IOException | ErrnoException e) {
-                mLog.e("Error creating UDP socket", e);
-                DhcpServer.this.stop(null);
-                return null;
-            } finally {
-                TrafficStats.setThreadStatsTag(oldTag);
-            }
-        }
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return this.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
deleted file mode 100644
index 230b693..0000000
--- a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java
+++ /dev/null
@@ -1,377 +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.net.dhcp;
-
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import static com.android.server.util.NetworkStackConstants.INFINITE_LEASE;
-import static com.android.server.util.NetworkStackConstants.IPV4_MAX_MTU;
-import static com.android.server.util.NetworkStackConstants.IPV4_MIN_MTU;
-
-import static java.lang.Integer.toUnsignedLong;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.shared.Inet4AddressUtils;
-import android.util.ArraySet;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Parameters used by the DhcpServer to serve requests.
- *
- * <p>Instances are immutable. Use {@link DhcpServingParams.Builder} to instantiate.
- * @hide
- */
-public class DhcpServingParams {
-    public static final int MTU_UNSET = 0;
-    public static final int MIN_PREFIX_LENGTH = 16;
-    public static final int MAX_PREFIX_LENGTH = 30;
-
-    /** Server inet address and prefix to serve */
-    @NonNull
-    public final LinkAddress serverAddr;
-
-    /**
-     * Default routers to be advertised to DHCP clients. May be empty.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> defaultRouters;
-
-    /**
-     * DNS servers to be advertised to DHCP clients. May be empty.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> dnsServers;
-
-    /**
-     * Excluded addresses that the DHCP server is not allowed to assign to clients.
-     * This set is provided by {@link DhcpServingParams.Builder} and is immutable.
-     */
-    @NonNull
-    public final Set<Inet4Address> excludedAddrs;
-
-    // DHCP uses uint32. Use long for clearer code, and check range when building.
-    public final long dhcpLeaseTimeSecs;
-    public final int linkMtu;
-
-    /**
-     * Indicates whether the DHCP server should send the ANDROID_METERED vendor-specific option.
-     */
-    public final boolean metered;
-
-    /**
-     * Checked exception thrown when some parameters used to build {@link DhcpServingParams} are
-     * missing or invalid.
-     */
-    public static class InvalidParameterException extends Exception {
-        public InvalidParameterException(String message) {
-            super(message);
-        }
-    }
-
-    private DhcpServingParams(@NonNull LinkAddress serverAddr,
-            @NonNull Set<Inet4Address> defaultRouters,
-            @NonNull Set<Inet4Address> dnsServers, @NonNull Set<Inet4Address> excludedAddrs,
-            long dhcpLeaseTimeSecs, int linkMtu, boolean metered) {
-        this.serverAddr = serverAddr;
-        this.defaultRouters = defaultRouters;
-        this.dnsServers = dnsServers;
-        this.excludedAddrs = excludedAddrs;
-        this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
-        this.linkMtu = linkMtu;
-        this.metered = metered;
-    }
-
-    /**
-     * Create parameters from a stable AIDL-compatible parcel.
-     * @throws InvalidParameterException The parameters parcelable is null or invalid.
-     */
-    public static DhcpServingParams fromParcelableObject(@Nullable DhcpServingParamsParcel parcel)
-            throws InvalidParameterException {
-        if (parcel == null) {
-            throw new InvalidParameterException("Null serving parameters");
-        }
-        final LinkAddress serverAddr = new LinkAddress(
-                intToInet4AddressHTH(parcel.serverAddr),
-                parcel.serverAddrPrefixLength);
-        return new Builder()
-                .setServerAddr(serverAddr)
-                .setDefaultRouters(toInet4AddressSet(parcel.defaultRouters))
-                .setDnsServers(toInet4AddressSet(parcel.dnsServers))
-                .setExcludedAddrs(toInet4AddressSet(parcel.excludedAddrs))
-                .setDhcpLeaseTimeSecs(parcel.dhcpLeaseTimeSecs)
-                .setLinkMtu(parcel.linkMtu)
-                .setMetered(parcel.metered)
-                .build();
-    }
-
-    private static Set<Inet4Address> toInet4AddressSet(@Nullable int[] addrs) {
-        if (addrs == null) {
-            return new HashSet<>(0);
-        }
-
-        final HashSet<Inet4Address> res = new HashSet<>();
-        for (int addr : addrs) {
-            res.add(intToInet4AddressHTH(addr));
-        }
-        return res;
-    }
-
-    @NonNull
-    public Inet4Address getServerInet4Addr() {
-        return (Inet4Address) serverAddr.getAddress();
-    }
-
-    /**
-     * Get the served prefix mask as an IPv4 address.
-     *
-     * <p>For example, if the served prefix is 192.168.42.0/24, this will return 255.255.255.0.
-     */
-    @NonNull
-    public Inet4Address getPrefixMaskAsAddress() {
-        return getPrefixMaskAsInet4Address(serverAddr.getPrefixLength());
-    }
-
-    /**
-     * Get the server broadcast address.
-     *
-     * <p>For example, if the server {@link LinkAddress} is 192.168.42.1/24, this will return
-     * 192.168.42.255.
-     */
-    @NonNull
-    public Inet4Address getBroadcastAddress() {
-        return Inet4AddressUtils.getBroadcastAddress(
-                getServerInet4Addr(), serverAddr.getPrefixLength());
-    }
-
-    /**
-     * Utility class to create new instances of {@link DhcpServingParams} while checking validity
-     * of the parameters.
-     */
-    public static class Builder {
-        private LinkAddress mServerAddr;
-        private Set<Inet4Address> mDefaultRouters;
-        private Set<Inet4Address> mDnsServers;
-        private Set<Inet4Address> mExcludedAddrs;
-        private long mDhcpLeaseTimeSecs;
-        private int mLinkMtu = MTU_UNSET;
-        private boolean mMetered;
-
-        /**
-         * Set the server address and served prefix for the DHCP server.
-         *
-         * <p>This parameter is required.
-         */
-        public Builder setServerAddr(@NonNull LinkAddress serverAddr) {
-            this.mServerAddr = serverAddr;
-            return this;
-        }
-
-        /**
-         * Set the default routers to be advertised to DHCP clients.
-         *
-         * <p>Each router must be inside the served prefix. This may be an empty set, but it must
-         * always be set explicitly before building the {@link DhcpServingParams}.
-         */
-        public Builder setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) {
-            this.mDefaultRouters = defaultRouters;
-            return this;
-        }
-
-        /**
-         * Set the default routers to be advertised to DHCP clients.
-         *
-         * <p>Each router must be inside the served prefix. This may be an empty list of routers,
-         * but it must always be set explicitly before building the {@link DhcpServingParams}.
-         */
-        public Builder setDefaultRouters(@NonNull Inet4Address... defaultRouters) {
-            return setDefaultRouters(makeArraySet(defaultRouters));
-        }
-
-        /**
-         * Convenience method to build the parameters with no default router.
-         *
-         * <p>Equivalent to calling {@link #setDefaultRouters(Inet4Address...)} with no address.
-         */
-        public Builder withNoDefaultRouter() {
-            return setDefaultRouters();
-        }
-
-        /**
-         * Set the DNS servers to be advertised to DHCP clients.
-         *
-         * <p>This may be an empty set, but it must always be set explicitly before building the
-         * {@link DhcpServingParams}.
-         */
-        public Builder setDnsServers(@NonNull Set<Inet4Address> dnsServers) {
-            this.mDnsServers = dnsServers;
-            return this;
-        }
-
-        /**
-         * Set the DNS servers to be advertised to DHCP clients.
-         *
-         * <p>This may be an empty list of servers, but it must always be set explicitly before
-         * building the {@link DhcpServingParams}.
-         */
-        public Builder setDnsServers(@NonNull Inet4Address... dnsServers) {
-            return setDnsServers(makeArraySet(dnsServers));
-        }
-
-        /**
-         * Convenience method to build the parameters with no DNS server.
-         *
-         * <p>Equivalent to calling {@link #setDnsServers(Inet4Address...)} with no address.
-         */
-        public Builder withNoDnsServer() {
-            return setDnsServers();
-        }
-
-        /**
-         * Set excluded addresses that the DHCP server is not allowed to assign to clients.
-         *
-         * <p>This parameter is optional. DNS servers and default routers are always excluded
-         * and do not need to be set here.
-         */
-        public Builder setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) {
-            this.mExcludedAddrs = excludedAddrs;
-            return this;
-        }
-
-        /**
-         * Set excluded addresses that the DHCP server is not allowed to assign to clients.
-         *
-         * <p>This parameter is optional. DNS servers and default routers are always excluded
-         * and do not need to be set here.
-         */
-        public Builder setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) {
-            return setExcludedAddrs(makeArraySet(excludedAddrs));
-        }
-
-        /**
-         * Set the lease time for leases assigned by the DHCP server.
-         *
-         * <p>This parameter is required.
-         */
-        public Builder setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) {
-            this.mDhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
-            return this;
-        }
-
-        /**
-         * Set the link MTU to be advertised to DHCP clients.
-         *
-         * <p>If set to {@link #MTU_UNSET}, no MTU will be advertised to clients. This parameter
-         * is optional and defaults to {@link #MTU_UNSET}.
-         */
-        public Builder setLinkMtu(int linkMtu) {
-            this.mLinkMtu = linkMtu;
-            return this;
-        }
-
-        /**
-         * Set whether the DHCP server should send the ANDROID_METERED vendor-specific option.
-         *
-         * <p>If not set, the default value is false.
-         */
-        public Builder setMetered(boolean metered) {
-            this.mMetered = metered;
-            return this;
-        }
-
-        /**
-         * Create a new {@link DhcpServingParams} instance based on parameters set in the builder.
-         *
-         * <p>This method has no side-effects. If it does not throw, a valid
-         * {@link DhcpServingParams} is returned.
-         * @return The constructed parameters.
-         * @throws InvalidParameterException At least one parameter is missing or invalid.
-         */
-        @NonNull
-        public DhcpServingParams build() throws InvalidParameterException {
-            if (mServerAddr == null) {
-                throw new InvalidParameterException("Missing serverAddr");
-            }
-            if (mDefaultRouters == null) {
-                throw new InvalidParameterException("Missing defaultRouters");
-            }
-            if (mDnsServers == null) {
-                // Empty set is OK, but enforce explicitly setting it
-                throw new InvalidParameterException("Missing dnsServers");
-            }
-            if (mDhcpLeaseTimeSecs <= 0 || mDhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) {
-                throw new InvalidParameterException("Invalid lease time: " + mDhcpLeaseTimeSecs);
-            }
-            if (mLinkMtu != MTU_UNSET && (mLinkMtu < IPV4_MIN_MTU || mLinkMtu > IPV4_MAX_MTU)) {
-                throw new InvalidParameterException("Invalid link MTU: " + mLinkMtu);
-            }
-            if (!mServerAddr.isIpv4()) {
-                throw new InvalidParameterException("serverAddr must be IPv4");
-            }
-            if (mServerAddr.getPrefixLength() < MIN_PREFIX_LENGTH
-                    || mServerAddr.getPrefixLength() > MAX_PREFIX_LENGTH) {
-                throw new InvalidParameterException("Prefix length is not in supported range");
-            }
-
-            final IpPrefix prefix = makeIpPrefix(mServerAddr);
-            for (Inet4Address addr : mDefaultRouters) {
-                if (!prefix.contains(addr)) {
-                    throw new InvalidParameterException(String.format(
-                            "Default router %s is not in server prefix %s", addr, mServerAddr));
-                }
-            }
-
-            final Set<Inet4Address> excl = new HashSet<>();
-            if (mExcludedAddrs != null) {
-                excl.addAll(mExcludedAddrs);
-            }
-            excl.add((Inet4Address) mServerAddr.getAddress());
-            excl.addAll(mDefaultRouters);
-            excl.addAll(mDnsServers);
-
-            return new DhcpServingParams(mServerAddr,
-                    Collections.unmodifiableSet(new HashSet<>(mDefaultRouters)),
-                    Collections.unmodifiableSet(new HashSet<>(mDnsServers)),
-                    Collections.unmodifiableSet(excl),
-                    mDhcpLeaseTimeSecs, mLinkMtu, mMetered);
-        }
-    }
-
-    /**
-     * Utility method to create an IpPrefix with the address and prefix length of a LinkAddress.
-     */
-    @NonNull
-    static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) {
-        return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
-    }
-
-    private static <T> ArraySet<T> makeArraySet(T[] elements) {
-        final ArraySet<T> set = new ArraySet<>(elements.length);
-        set.addAll(Arrays.asList(elements));
-        return set;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java b/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
deleted file mode 100644
index eb49218..0000000
--- a/packages/NetworkStack/src/android/net/ip/ConnectivityPacketTracker.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.ip;
-
-import static android.net.util.SocketUtils.makePacketSocketAddress;
-import static android.system.OsConstants.AF_PACKET;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ALL;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOCK_RAW;
-
-import android.net.util.ConnectivityPacketSummary;
-import android.net.util.InterfaceParams;
-import android.net.util.NetworkStackUtils;
-import android.net.util.PacketReader;
-import android.os.Handler;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-
-/**
- * Critical connectivity packet tracking daemon.
- *
- * Tracks ARP, DHCPv4, and IPv6 RS/RA/NS/NA packets.
- *
- * This class's constructor, start() and stop() methods must only be called
- * from the same thread on which the passed in |log| is accessed.
- *
- * Log lines include a hexdump of the packet, which can be decoded via:
- *
- *     echo -n H3XSTR1NG | sed -e 's/\([0-9A-F][0-9A-F]\)/\1 /g' -e 's/^/000000 /'
- *                       | text2pcap - -
- *                       | tcpdump -n -vv -e -r -
- *
- * @hide
- */
-public class ConnectivityPacketTracker {
-    private static final String TAG = ConnectivityPacketTracker.class.getSimpleName();
-    private static final boolean DBG = false;
-    private static final String MARK_START = "--- START ---";
-    private static final String MARK_STOP = "--- STOP ---";
-    private static final String MARK_NAMED_START = "--- START (%s) ---";
-    private static final String MARK_NAMED_STOP = "--- STOP (%s) ---";
-
-    private final String mTag;
-    private final LocalLog mLog;
-    private final PacketReader mPacketListener;
-    private boolean mRunning;
-    private String mDisplayName;
-
-    public ConnectivityPacketTracker(Handler h, InterfaceParams ifParams, LocalLog log) {
-        if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams");
-
-        mTag = TAG + "." + ifParams.name;
-        mLog = log;
-        mPacketListener = new PacketListener(h, ifParams);
-    }
-
-    public void start(String displayName) {
-        mRunning = true;
-        mDisplayName = displayName;
-        mPacketListener.start();
-    }
-
-    public void stop() {
-        mPacketListener.stop();
-        mRunning = false;
-        mDisplayName = null;
-    }
-
-    private final class PacketListener extends PacketReader {
-        private final InterfaceParams mInterface;
-
-        PacketListener(Handler h, InterfaceParams ifParams) {
-            super(h, ifParams.defaultMtu);
-            mInterface = ifParams;
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            FileDescriptor s = null;
-            try {
-                s = Os.socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, 0);
-                NetworkStackUtils.attachControlPacketFilter(s, ARPHRD_ETHER);
-                Os.bind(s, makePacketSocketAddress((short) ETH_P_ALL, mInterface.index));
-            } catch (ErrnoException | IOException e) {
-                logError("Failed to create packet tracking socket: ", e);
-                closeFd(s);
-                return null;
-            }
-            return s;
-        }
-
-        @Override
-        protected void handlePacket(byte[] recvbuf, int length) {
-            final String summary = ConnectivityPacketSummary.summarize(
-                    mInterface.macAddr, recvbuf, length);
-            if (summary == null) return;
-
-            if (DBG) Log.d(mTag, summary);
-            addLogEntry(summary + "\n[" + HexDump.toHexString(recvbuf, 0, length) + "]");
-        }
-
-        @Override
-        protected void onStart() {
-            final String msg = TextUtils.isEmpty(mDisplayName)
-                    ? MARK_START
-                    : String.format(MARK_NAMED_START, mDisplayName);
-            mLog.log(msg);
-        }
-
-        @Override
-        protected void onStop() {
-            String msg = TextUtils.isEmpty(mDisplayName)
-                    ? MARK_STOP
-                    : String.format(MARK_NAMED_STOP, mDisplayName);
-            if (!mRunning) msg += " (packet listener stopped unexpectedly)";
-            mLog.log(msg);
-        }
-
-        @Override
-        protected void logError(String msg, Exception e) {
-            Log.e(mTag, msg, e);
-            addLogEntry(msg + e);
-        }
-
-        private void addLogEntry(String entry) {
-            mLog.log(entry);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpClient.java b/packages/NetworkStack/src/android/net/ip/IpClient.java
deleted file mode 100644
index 266b1b0..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpClient.java
+++ /dev/null
@@ -1,1784 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static android.net.RouteInfo.RTN_UNICAST;
-import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
-
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.DhcpResults;
-import android.net.INetd;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.NetworkStackIpMemoryStore;
-import android.net.ProvisioningConfigurationParcelable;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfCapabilities;
-import android.net.apf.ApfFilter;
-import android.net.dhcp.DhcpClient;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.IpManagerEvent;
-import android.net.shared.InitialConfiguration;
-import android.net.shared.ProvisioningConfiguration;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.IState;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.internal.util.MessageUtils;
-import com.android.internal.util.Preconditions;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.WakeupMessage;
-import com.android.server.NetworkObserverRegistry;
-import com.android.server.NetworkStackService.NetworkStackServiceManager;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-
-/**
- * IpClient
- *
- * This class provides the interface to IP-layer provisioning and maintenance
- * functionality that can be used by transport layers like Wi-Fi, Ethernet,
- * et cetera.
- *
- * [ Lifetime ]
- * IpClient is designed to be instantiated as soon as the interface name is
- * known and can be as long-lived as the class containing it (i.e. declaring
- * it "private final" is okay).
- *
- * @hide
- */
-public class IpClient extends StateMachine {
-    private static final boolean DBG = false;
-
-    // For message logging.
-    private static final Class[] sMessageClasses = { IpClient.class, DhcpClient.class };
-    private static final SparseArray<String> sWhatToString =
-            MessageUtils.findMessageNames(sMessageClasses);
-    // Two static concurrent hashmaps of interface name to logging classes.
-    // One holds StateMachine logs and the other connectivity packet logs.
-    private static final ConcurrentHashMap<String, SharedLog> sSmLogs = new ConcurrentHashMap<>();
-    private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>();
-    private final NetworkStackIpMemoryStore mIpMemoryStore;
-
-    /**
-     * Dump all state machine and connectivity packet logs to the specified writer.
-     * @param skippedIfaces Interfaces for which logs should not be dumped.
-     */
-    public static void dumpAllLogs(PrintWriter writer, Set<String> skippedIfaces) {
-        for (String ifname : sSmLogs.keySet()) {
-            if (skippedIfaces.contains(ifname)) continue;
-
-            writer.println(String.format("--- BEGIN %s ---", ifname));
-
-            final SharedLog smLog = sSmLogs.get(ifname);
-            if (smLog != null) {
-                writer.println("State machine log:");
-                smLog.dump(null, writer, null);
-            }
-
-            writer.println("");
-
-            final LocalLog pktLog = sPktLogs.get(ifname);
-            if (pktLog != null) {
-                writer.println("Connectivity packet log:");
-                pktLog.readOnlyLocalLog().dump(null, writer, null);
-            }
-
-            writer.println(String.format("--- END %s ---", ifname));
-        }
-    }
-
-    // Use a wrapper class to log in order to ensure complete and detailed
-    // logging. This method is lighter weight than annotations/reflection
-    // and has the following benefits:
-    //
-    //     - No invoked method can be forgotten.
-    //       Any new method added to IpClient.Callback must be overridden
-    //       here or it will never be called.
-    //
-    //     - No invoking call site can be forgotten.
-    //       Centralized logging in this way means call sites don't need to
-    //       remember to log, and therefore no call site can be forgotten.
-    //
-    //     - No variation in log format among call sites.
-    //       Encourages logging of any available arguments, and all call sites
-    //       are necessarily logged identically.
-    //
-    // NOTE: Log first because passed objects may or may not be thread-safe and
-    // once passed on to the callback they may be modified by another thread.
-    //
-    // TODO: Find an lighter weight approach.
-    public static class IpClientCallbacksWrapper {
-        private static final String PREFIX = "INVOKE ";
-        private final IIpClientCallbacks mCallback;
-        private final SharedLog mLog;
-
-        @VisibleForTesting
-        protected IpClientCallbacksWrapper(IIpClientCallbacks callback, SharedLog log) {
-            mCallback = callback;
-            mLog = log;
-        }
-
-        private void log(String msg) {
-            mLog.log(PREFIX + msg);
-        }
-
-        private void log(String msg, Throwable e) {
-            mLog.e(PREFIX + msg, e);
-        }
-
-        public void onPreDhcpAction() {
-            log("onPreDhcpAction()");
-            try {
-                mCallback.onPreDhcpAction();
-            } catch (RemoteException e) {
-                log("Failed to call onPreDhcpAction", e);
-            }
-        }
-
-        public void onPostDhcpAction() {
-            log("onPostDhcpAction()");
-            try {
-                mCallback.onPostDhcpAction();
-            } catch (RemoteException e) {
-                log("Failed to call onPostDhcpAction", e);
-            }
-        }
-
-        public void onNewDhcpResults(DhcpResults dhcpResults) {
-            log("onNewDhcpResults({" + dhcpResults + "})");
-            try {
-                mCallback.onNewDhcpResults(toStableParcelable(dhcpResults));
-            } catch (RemoteException e) {
-                log("Failed to call onNewDhcpResults", e);
-            }
-        }
-
-        public void onProvisioningSuccess(LinkProperties newLp) {
-            log("onProvisioningSuccess({" + newLp + "})");
-            try {
-                mCallback.onProvisioningSuccess(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onProvisioningSuccess", e);
-            }
-        }
-
-        public void onProvisioningFailure(LinkProperties newLp) {
-            log("onProvisioningFailure({" + newLp + "})");
-            try {
-                mCallback.onProvisioningFailure(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onProvisioningFailure", e);
-            }
-        }
-
-        public void onLinkPropertiesChange(LinkProperties newLp) {
-            log("onLinkPropertiesChange({" + newLp + "})");
-            try {
-                mCallback.onLinkPropertiesChange(newLp);
-            } catch (RemoteException e) {
-                log("Failed to call onLinkPropertiesChange", e);
-            }
-        }
-
-        public void onReachabilityLost(String logMsg) {
-            log("onReachabilityLost(" + logMsg + ")");
-            try {
-                mCallback.onReachabilityLost(logMsg);
-            } catch (RemoteException e) {
-                log("Failed to call onReachabilityLost", e);
-            }
-        }
-
-        public void onQuit() {
-            log("onQuit()");
-            try {
-                mCallback.onQuit();
-            } catch (RemoteException e) {
-                log("Failed to call onQuit", e);
-            }
-        }
-
-        public void installPacketFilter(byte[] filter) {
-            log("installPacketFilter(byte[" + filter.length + "])");
-            try {
-                mCallback.installPacketFilter(filter);
-            } catch (RemoteException e) {
-                log("Failed to call installPacketFilter", e);
-            }
-        }
-
-        public void startReadPacketFilter() {
-            log("startReadPacketFilter()");
-            try {
-                mCallback.startReadPacketFilter();
-            } catch (RemoteException e) {
-                log("Failed to call startReadPacketFilter", e);
-            }
-        }
-
-        public void setFallbackMulticastFilter(boolean enabled) {
-            log("setFallbackMulticastFilter(" + enabled + ")");
-            try {
-                mCallback.setFallbackMulticastFilter(enabled);
-            } catch (RemoteException e) {
-                log("Failed to call setFallbackMulticastFilter", e);
-            }
-        }
-
-        public void setNeighborDiscoveryOffload(boolean enable) {
-            log("setNeighborDiscoveryOffload(" + enable + ")");
-            try {
-                mCallback.setNeighborDiscoveryOffload(enable);
-            } catch (RemoteException e) {
-                log("Failed to call setNeighborDiscoveryOffload", e);
-            }
-        }
-    }
-
-    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;
-    private static final int CMD_CONFIRM                          = 4;
-    private static final int EVENT_PRE_DHCP_ACTION_COMPLETE       = 5;
-    // Triggered by NetlinkTracker to communicate netlink events.
-    private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 6;
-    private static final int CMD_UPDATE_TCP_BUFFER_SIZES          = 7;
-    private static final int CMD_UPDATE_HTTP_PROXY                = 8;
-    private static final int CMD_SET_MULTICAST_FILTER             = 9;
-    private static final int EVENT_PROVISIONING_TIMEOUT           = 10;
-    private static final int EVENT_DHCPACTION_TIMEOUT             = 11;
-    private static final int EVENT_READ_PACKET_FILTER_COMPLETE    = 12;
-    private static final int CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF = 13;
-    private static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF = 14;
-    private static final int CMD_UPDATE_L2KEY_GROUPHINT = 15;
-
-    // Internal commands to use instead of trying to call transitionTo() inside
-    // a given State's enter() method. Calling transitionTo() from enter/exit
-    // encounters a Log.wtf() that can cause trouble on eng builds.
-    private static final int CMD_JUMP_STARTED_TO_RUNNING          = 100;
-    private static final int CMD_JUMP_RUNNING_TO_STOPPING         = 101;
-    private static final int CMD_JUMP_STOPPING_TO_STOPPED         = 102;
-
-    // IpClient shares a handler with DhcpClient: commands must not overlap
-    public static final int DHCPCLIENT_CMD_BASE = 1000;
-
-    private static final int MAX_LOG_RECORDS = 500;
-    private static final int MAX_PACKET_RECORDS = 100;
-
-    private static final boolean NO_CALLBACKS = false;
-    private static final boolean SEND_CALLBACKS = true;
-
-    // This must match the interface prefix in clatd.c.
-    // TODO: Revert this hack once IpClient and Nat464Xlat work in concert.
-    private static final String CLAT_PREFIX = "v4-";
-
-    private static final int IMMEDIATE_FAILURE_DURATION = 0;
-
-    private static final int PROV_CHANGE_STILL_NOT_PROVISIONED = 1;
-    private static final int PROV_CHANGE_LOST_PROVISIONING = 2;
-    private static final int PROV_CHANGE_GAINED_PROVISIONING = 3;
-    private static final int PROV_CHANGE_STILL_PROVISIONED = 4;
-
-    private final State mStoppedState = new StoppedState();
-    private final State mStoppingState = new StoppingState();
-    private final State mStartedState = new StartedState();
-    private final State mRunningState = new RunningState();
-
-    private final String mTag;
-    private final Context mContext;
-    private final String mInterfaceName;
-    private final String mClatInterfaceName;
-    @VisibleForTesting
-    protected final IpClientCallbacksWrapper mCallback;
-    private final Dependencies mDependencies;
-    private final CountDownLatch mShutdownLatch;
-    private final ConnectivityManager mCm;
-    private final INetd mNetd;
-    private final NetworkObserverRegistry mObserverRegistry;
-    private final IpClientLinkObserver mLinkObserver;
-    private final WakeupMessage mProvisioningTimeoutAlarm;
-    private final WakeupMessage mDhcpActionTimeoutAlarm;
-    private final SharedLog mLog;
-    private final LocalLog mConnectivityPacketLog;
-    private final MessageHandlingLogger mMsgStateLogger;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-    private final InterfaceController mInterfaceCtrl;
-
-    private InterfaceParams mInterfaceParams;
-
-    /**
-     * Non-final member variables accessed only from within our StateMachine.
-     */
-    private LinkProperties mLinkProperties;
-    private android.net.shared.ProvisioningConfiguration mConfiguration;
-    private IpReachabilityMonitor mIpReachabilityMonitor;
-    private DhcpClient mDhcpClient;
-    private DhcpResults mDhcpResults;
-    private String mTcpBufferSizes;
-    private ProxyInfo mHttpProxy;
-    private ApfFilter mApfFilter;
-    private String mL2Key; // The L2 key for this network, for writing into the memory store
-    private String mGroupHint; // The group hint for this network, for writing into the memory store
-    private boolean mMulticastFiltering;
-    private long mStartTimeMillis;
-
-    /**
-     * Reading the snapshot is an asynchronous operation initiated by invoking
-     * Callback.startReadPacketFilter() and completed when the WiFi Service responds with an
-     * EVENT_READ_PACKET_FILTER_COMPLETE message. The mApfDataSnapshotComplete condition variable
-     * signals when a new snapshot is ready.
-     */
-    private final ConditionVariable mApfDataSnapshotComplete = new ConditionVariable();
-
-    public static class Dependencies {
-        /**
-         * Get interface parameters for the specified interface.
-         */
-        public InterfaceParams getInterfaceParams(String ifname) {
-            return InterfaceParams.getByName(ifname);
-        }
-
-        /**
-         * Get a INetd connector.
-         */
-        public INetd getNetd(Context context) {
-            return INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE));
-        }
-    }
-
-    public IpClient(Context context, String ifName, IIpClientCallbacks callback,
-            NetworkObserverRegistry observerRegistry, NetworkStackServiceManager nssManager) {
-        this(context, ifName, callback, observerRegistry, nssManager, new Dependencies());
-    }
-
-    @VisibleForTesting
-    IpClient(Context context, String ifName, IIpClientCallbacks callback,
-            NetworkObserverRegistry observerRegistry, NetworkStackServiceManager nssManager,
-            Dependencies deps) {
-        super(IpClient.class.getSimpleName() + "." + ifName);
-        Preconditions.checkNotNull(ifName);
-        Preconditions.checkNotNull(callback);
-
-        mTag = getName();
-
-        mContext = context;
-        mInterfaceName = ifName;
-        mClatInterfaceName = CLAT_PREFIX + ifName;
-        mDependencies = deps;
-        mShutdownLatch = new CountDownLatch(1);
-        mCm = mContext.getSystemService(ConnectivityManager.class);
-        mObserverRegistry = observerRegistry;
-        mIpMemoryStore =
-                new NetworkStackIpMemoryStore(context, nssManager.getIpMemoryStoreService());
-
-        sSmLogs.putIfAbsent(mInterfaceName, new SharedLog(MAX_LOG_RECORDS, mTag));
-        mLog = sSmLogs.get(mInterfaceName);
-        sPktLogs.putIfAbsent(mInterfaceName, new LocalLog(MAX_PACKET_RECORDS));
-        mConnectivityPacketLog = sPktLogs.get(mInterfaceName);
-        mMsgStateLogger = new MessageHandlingLogger();
-        mCallback = new IpClientCallbacksWrapper(callback, mLog);
-
-        // TODO: Consider creating, constructing, and passing in some kind of
-        // InterfaceController.Dependencies class.
-        mNetd = deps.getNetd(mContext);
-        mInterfaceCtrl = new InterfaceController(mInterfaceName, mNetd, mLog);
-
-        mLinkObserver = new IpClientLinkObserver(
-                mInterfaceName,
-                () -> sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED)) {
-            @Override
-            public void onInterfaceAdded(String iface) {
-                super.onInterfaceAdded(iface);
-                if (mClatInterfaceName.equals(iface)) {
-                    mCallback.setNeighborDiscoveryOffload(false);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceAdded(" + iface + ")";
-                logMsg(msg);
-            }
-
-            @Override
-            public void onInterfaceRemoved(String iface) {
-                super.onInterfaceRemoved(iface);
-                // TODO: Also observe mInterfaceName going down and take some
-                // kind of appropriate action.
-                if (mClatInterfaceName.equals(iface)) {
-                    // TODO: consider sending a message to the IpClient main
-                    // StateMachine thread, in case "NDO enabled" state becomes
-                    // tied to more things that 464xlat operation.
-                    mCallback.setNeighborDiscoveryOffload(true);
-                } else if (!mInterfaceName.equals(iface)) {
-                    return;
-                }
-
-                final String msg = "interfaceRemoved(" + iface + ")";
-                logMsg(msg);
-            }
-
-            private void logMsg(String msg) {
-                Log.d(mTag, msg);
-                getHandler().post(() -> mLog.log("OBSERVED " + msg));
-            }
-        };
-
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-
-        mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
-                mTag + ".EVENT_PROVISIONING_TIMEOUT", EVENT_PROVISIONING_TIMEOUT);
-        mDhcpActionTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
-                mTag + ".EVENT_DHCPACTION_TIMEOUT", EVENT_DHCPACTION_TIMEOUT);
-
-        // Anything the StateMachine may access must have been instantiated
-        // before this point.
-        configureAndStartStateMachine();
-
-        // Anything that may send messages to the StateMachine must only be
-        // configured to do so after the StateMachine has started (above).
-        startStateMachineUpdaters();
-    }
-
-    /**
-     * Make a IIpClient connector to communicate with this IpClient.
-     */
-    public IIpClient makeConnector() {
-        return new IpClientConnector();
-    }
-
-    class IpClientConnector extends IIpClient.Stub {
-        @Override
-        public void completedPreDhcpAction() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.completedPreDhcpAction();
-        }
-        @Override
-        public void confirmConfiguration() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.confirmConfiguration();
-        }
-        @Override
-        public void readPacketFilterComplete(byte[] data) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.readPacketFilterComplete(data);
-        }
-        @Override
-        public void shutdown() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.shutdown();
-        }
-        @Override
-        public void startProvisioning(ProvisioningConfigurationParcelable req) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.startProvisioning(ProvisioningConfiguration.fromStableParcelable(req));
-        }
-        @Override
-        public void stop() {
-            checkNetworkStackCallingPermission();
-            IpClient.this.stop();
-        }
-        @Override
-        public void setL2KeyAndGroupHint(String l2Key, String groupHint) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setL2KeyAndGroupHint(l2Key, groupHint);
-        }
-        @Override
-        public void setTcpBufferSizes(String tcpBufferSizes) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setTcpBufferSizes(tcpBufferSizes);
-        }
-        @Override
-        public void setHttpProxy(ProxyInfo proxyInfo) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setHttpProxy(proxyInfo);
-        }
-        @Override
-        public void setMulticastFilter(boolean enabled) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.setMulticastFilter(enabled);
-        }
-        @Override
-        public void addKeepalivePacketFilter(int slot, TcpKeepalivePacketDataParcelable pkt) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.addKeepalivePacketFilter(slot, pkt);
-        }
-        @Override
-        public void addNattKeepalivePacketFilter(int slot, NattKeepalivePacketDataParcelable pkt) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.addNattKeepalivePacketFilter(slot, pkt);
-        }
-        @Override
-        public void removeKeepalivePacketFilter(int slot) {
-            checkNetworkStackCallingPermission();
-            IpClient.this.removeKeepalivePacketFilter(slot);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-
-    public String getInterfaceName() {
-        return mInterfaceName;
-    }
-
-    private void configureAndStartStateMachine() {
-        // CHECKSTYLE:OFF IndentationCheck
-        addState(mStoppedState);
-        addState(mStartedState);
-            addState(mRunningState, mStartedState);
-        addState(mStoppingState);
-        // CHECKSTYLE:ON IndentationCheck
-
-        setInitialState(mStoppedState);
-
-        super.start();
-    }
-
-    private void startStateMachineUpdaters() {
-        mObserverRegistry.registerObserverForNonblockingCallback(mLinkObserver);
-    }
-
-    private void stopStateMachineUpdaters() {
-        mObserverRegistry.unregisterObserver(mLinkObserver);
-    }
-
-    @Override
-    protected void onQuitting() {
-        mCallback.onQuit();
-        mShutdownLatch.countDown();
-    }
-
-    /**
-     * Shut down this IpClient instance altogether.
-     */
-    public void shutdown() {
-        stop();
-        sendMessage(CMD_TERMINATE_AFTER_STOP);
-    }
-
-    /**
-     * Start provisioning with the provided parameters.
-     */
-    public void startProvisioning(ProvisioningConfiguration req) {
-        if (!req.isValid()) {
-            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
-            return;
-        }
-
-        mInterfaceParams = mDependencies.getInterfaceParams(mInterfaceName);
-        if (mInterfaceParams == null) {
-            logError("Failed to find InterfaceParams for " + mInterfaceName);
-            doImmediateProvisioningFailure(IpManagerEvent.ERROR_INTERFACE_NOT_FOUND);
-            return;
-        }
-
-        mCallback.setNeighborDiscoveryOffload(true);
-        sendMessage(CMD_START, new android.net.shared.ProvisioningConfiguration(req));
-    }
-
-    /**
-     * Stop this IpClient.
-     *
-     * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}.
-     */
-    public void stop() {
-        sendMessage(CMD_STOP);
-    }
-
-    /**
-     * Confirm the provisioning configuration.
-     */
-    public void confirmConfiguration() {
-        sendMessage(CMD_CONFIRM);
-    }
-
-    /**
-     * For clients using {@link ProvisioningConfiguration.Builder#withPreDhcpAction()}, must be
-     * called after {@link IIpClientCallbacks#onPreDhcpAction} to indicate that DHCP is clear to
-     * proceed.
-     */
-    public void completedPreDhcpAction() {
-        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
-    }
-
-    /**
-     * Indicate that packet filter read is complete.
-     */
-    public void readPacketFilterComplete(byte[] data) {
-        sendMessage(EVENT_READ_PACKET_FILTER_COMPLETE, data);
-    }
-
-    /**
-     * Set the TCP buffer sizes to use.
-     *
-     * This may be called, repeatedly, at any time before or after a call to
-     * #startProvisioning(). The setting is cleared upon calling #stop().
-     */
-    public void setTcpBufferSizes(String tcpBufferSizes) {
-        sendMessage(CMD_UPDATE_TCP_BUFFER_SIZES, tcpBufferSizes);
-    }
-
-    /**
-     * Set the L2 key and group hint for storing info into the memory store.
-     */
-    public void setL2KeyAndGroupHint(String l2Key, String groupHint) {
-        sendMessage(CMD_UPDATE_L2KEY_GROUPHINT, new Pair<>(l2Key, groupHint));
-    }
-
-    /**
-     * Set the HTTP Proxy configuration to use.
-     *
-     * This may be called, repeatedly, at any time before or after a call to
-     * #startProvisioning(). The setting is cleared upon calling #stop().
-     */
-    public void setHttpProxy(ProxyInfo proxyInfo) {
-        sendMessage(CMD_UPDATE_HTTP_PROXY, proxyInfo);
-    }
-
-    /**
-     * Enable or disable the multicast filter.  Attempts to use APF to accomplish the filtering,
-     * if not, Callback.setFallbackMulticastFilter() is called.
-     */
-    public void setMulticastFilter(boolean enabled) {
-        sendMessage(CMD_SET_MULTICAST_FILTER, enabled);
-    }
-
-    /**
-     * Called by WifiStateMachine to add TCP keepalive packet filter before setting up
-     * keepalive offload.
-     */
-    public void addKeepalivePacketFilter(int slot, @NonNull TcpKeepalivePacketDataParcelable pkt) {
-        sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, 0 /* Unused */, pkt);
-    }
-
-    /**
-     *  Called by WifiStateMachine to add NATT keepalive packet filter before setting up
-     *  keepalive offload.
-     */
-    public void addNattKeepalivePacketFilter(int slot,
-            @NonNull NattKeepalivePacketDataParcelable pkt) {
-        sendMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF, slot, 0 /* Unused */ , pkt);
-    }
-
-    /**
-     * Called by WifiStateMachine to remove keepalive packet filter after stopping keepalive
-     * offload.
-     */
-    public void removeKeepalivePacketFilter(int slot) {
-        sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF, slot, 0 /* Unused */);
-    }
-
-    /**
-     * Dump logs of this IpClient.
-     */
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        if (args != null && args.length > 0 && DUMP_ARG_CONFIRM.equals(args[0])) {
-            // Execute confirmConfiguration() and take no further action.
-            confirmConfiguration();
-            return;
-        }
-
-        // Thread-unsafe access to mApfFilter but just used for debugging.
-        final ApfFilter apfFilter = mApfFilter;
-        final android.net.shared.ProvisioningConfiguration provisioningConfig = mConfiguration;
-        final ApfCapabilities apfCapabilities = (provisioningConfig != null)
-                ? provisioningConfig.mApfCapabilities : null;
-
-        IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
-        pw.println(mTag + " APF dump:");
-        pw.increaseIndent();
-        if (apfFilter != null) {
-            if (apfCapabilities.hasDataAccess()) {
-                // Request a new snapshot, then wait for it.
-                mApfDataSnapshotComplete.close();
-                mCallback.startReadPacketFilter();
-                if (!mApfDataSnapshotComplete.block(1000)) {
-                    pw.print("TIMEOUT: DUMPING STALE APF SNAPSHOT");
-                }
-            }
-            apfFilter.dump(pw);
-
-        } else {
-            pw.print("No active ApfFilter; ");
-            if (provisioningConfig == null) {
-                pw.println("IpClient not yet started.");
-            } else if (apfCapabilities == null || apfCapabilities.apfVersionSupported == 0) {
-                pw.println("Hardware does not support APF.");
-            } else {
-                pw.println("ApfFilter not yet started, APF capabilities: " + apfCapabilities);
-            }
-        }
-        pw.decreaseIndent();
-        pw.println();
-        pw.println(mTag + " current ProvisioningConfiguration:");
-        pw.increaseIndent();
-        pw.println(Objects.toString(provisioningConfig, "N/A"));
-        pw.decreaseIndent();
-
-        final IpReachabilityMonitor iprm = mIpReachabilityMonitor;
-        if (iprm != null) {
-            pw.println();
-            pw.println(mTag + " current IpReachabilityMonitor state:");
-            pw.increaseIndent();
-            iprm.dump(pw);
-            pw.decreaseIndent();
-        }
-
-        pw.println();
-        pw.println(mTag + " StateMachine dump:");
-        pw.increaseIndent();
-        mLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println(mTag + " connectivity packet log:");
-        pw.println();
-        pw.println("Debug with python and scapy via:");
-        pw.println("shell$ python");
-        pw.println(">>> from scapy import all as scapy");
-        pw.println(">>> scapy.Ether(\"<paste_hex_string>\".decode(\"hex\")).show2()");
-        pw.println();
-
-        pw.increaseIndent();
-        mConnectivityPacketLog.readOnlyLocalLog().dump(fd, pw, args);
-        pw.decreaseIndent();
-    }
-
-
-    /**
-     * Internals.
-     */
-
-    @Override
-    protected String getWhatToString(int what) {
-        return sWhatToString.get(what, "UNKNOWN: " + Integer.toString(what));
-    }
-
-    @Override
-    protected String getLogRecString(Message msg) {
-        final String logLine = String.format(
-                "%s/%d %d %d %s [%s]",
-                mInterfaceName, (mInterfaceParams == null) ? -1 : mInterfaceParams.index,
-                msg.arg1, msg.arg2, Objects.toString(msg.obj), mMsgStateLogger);
-
-        final String richerLogLine = getWhatToString(msg.what) + " " + logLine;
-        mLog.log(richerLogLine);
-        if (DBG) {
-            Log.d(mTag, richerLogLine);
-        }
-
-        mMsgStateLogger.reset();
-        return logLine;
-    }
-
-    @Override
-    protected boolean recordLogRec(Message msg) {
-        // Don't log EVENT_NETLINK_LINKPROPERTIES_CHANGED. They can be noisy,
-        // and we already log any LinkProperties change that results in an
-        // invocation of IpClient.Callback#onLinkPropertiesChange().
-        final boolean shouldLog = (msg.what != EVENT_NETLINK_LINKPROPERTIES_CHANGED);
-        if (!shouldLog) {
-            mMsgStateLogger.reset();
-        }
-        return shouldLog;
-    }
-
-    private void logError(String fmt, Object... args) {
-        final String msg = "ERROR " + String.format(fmt, args);
-        Log.e(mTag, msg);
-        mLog.log(msg);
-    }
-
-    // This needs to be called with care to ensure that our LinkProperties
-    // are in sync with the actual LinkProperties of the interface. For example,
-    // we should only call this if we know for sure that there are no IP addresses
-    // assigned to the interface, etc.
-    private void resetLinkProperties() {
-        mLinkObserver.clearLinkProperties();
-        mConfiguration = null;
-        mDhcpResults = null;
-        mTcpBufferSizes = "";
-        mHttpProxy = null;
-
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-    }
-
-    private void recordMetric(final int type) {
-        // We may record error metrics prior to starting.
-        // Map this to IMMEDIATE_FAILURE_DURATION.
-        final long duration = (mStartTimeMillis > 0)
-                ? (SystemClock.elapsedRealtime() - mStartTimeMillis)
-                : IMMEDIATE_FAILURE_DURATION;
-        mMetricsLog.log(mInterfaceName, new IpManagerEvent(type, duration));
-    }
-
-    // For now: use WifiStateMachine's historical notion of provisioned.
-    @VisibleForTesting
-    static boolean isProvisioned(LinkProperties lp, InitialConfiguration config) {
-        // For historical reasons, we should connect even if all we have is
-        // an IPv4 address and nothing else.
-        if (lp.hasIpv4Address() || lp.isProvisioned()) {
-            return true;
-        }
-        if (config == null) {
-            return false;
-        }
-
-        // When an InitialConfiguration is specified, ignore any difference with previous
-        // properties and instead check if properties observed match the desired properties.
-        return config.isProvisionedBy(lp.getLinkAddresses(), lp.getRoutes());
-    }
-
-    // TODO: Investigate folding all this into the existing static function
-    // LinkProperties.compareProvisioning() or some other single function that
-    // takes two LinkProperties objects and returns a ProvisioningChange
-    // object that is a correct and complete assessment of what changed, taking
-    // account of the asymmetries described in the comments in this function.
-    // Then switch to using it everywhere (IpReachabilityMonitor, etc.).
-    private int compareProvisioning(LinkProperties oldLp, LinkProperties newLp) {
-        int delta;
-        InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null;
-        final boolean wasProvisioned = isProvisioned(oldLp, config);
-        final boolean isProvisioned = isProvisioned(newLp, config);
-
-        if (!wasProvisioned && isProvisioned) {
-            delta = PROV_CHANGE_GAINED_PROVISIONING;
-        } else if (wasProvisioned && isProvisioned) {
-            delta = PROV_CHANGE_STILL_PROVISIONED;
-        } else if (!wasProvisioned && !isProvisioned) {
-            delta = PROV_CHANGE_STILL_NOT_PROVISIONED;
-        } else {
-            // (wasProvisioned && !isProvisioned)
-            //
-            // Note that this is true even if we lose a configuration element
-            // (e.g., a default gateway) that would not be required to advance
-            // into provisioned state. This is intended: if we have a default
-            // router and we lose it, that's a sure sign of a problem, but if
-            // we connect to a network with no IPv4 DNS servers, we consider
-            // that to be a network without DNS servers and connect anyway.
-            //
-            // See the comment below.
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        final boolean lostIPv6 = oldLp.isIpv6Provisioned() && !newLp.isIpv6Provisioned();
-        final boolean lostIPv4Address = oldLp.hasIpv4Address() && !newLp.hasIpv4Address();
-        final boolean lostIPv6Router = oldLp.hasIpv6DefaultRoute() && !newLp.hasIpv6DefaultRoute();
-
-        // If bad wifi avoidance is disabled, then ignore IPv6 loss of
-        // provisioning. Otherwise, when a hotspot that loses Internet
-        // access sends out a 0-lifetime RA to its clients, the clients
-        // will disconnect and then reconnect, avoiding the bad hotspot,
-        // instead of getting stuck on the bad hotspot. http://b/31827713 .
-        //
-        // This is incorrect because if the hotspot then regains Internet
-        // access with a different prefix, TCP connections on the
-        // deprecated addresses will remain stuck.
-        //
-        // Note that we can still be disconnected by IpReachabilityMonitor
-        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
-        // accompanying code in IpReachabilityMonitor) is unreachable.
-        final boolean ignoreIPv6ProvisioningLoss =
-                mConfiguration != null && mConfiguration.mUsingMultinetworkPolicyTracker
-                && mCm.shouldAvoidBadWifi();
-
-        // Additionally:
-        //
-        // Partial configurations (e.g., only an IPv4 address with no DNS
-        // servers and no default route) are accepted as long as DHCPv4
-        // succeeds. On such a network, isProvisioned() will always return
-        // false, because the configuration is not complete, but we want to
-        // connect anyway. It might be a disconnected network such as a
-        // Chromecast or a wireless printer, for example.
-        //
-        // Because on such a network isProvisioned() will always return false,
-        // delta will never be LOST_PROVISIONING. So check for loss of
-        // provisioning here too.
-        if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        // Additionally:
-        //
-        // If the previous link properties had a global IPv6 address and an
-        // IPv6 default route then also consider the loss of that default route
-        // to be a loss of provisioning. See b/27962810.
-        if (oldLp.hasGlobalIpv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        return delta;
-    }
-
-    private void dispatchCallback(int delta, LinkProperties newLp) {
-        switch (delta) {
-            case PROV_CHANGE_GAINED_PROVISIONING:
-                if (DBG) {
-                    Log.d(mTag, "onProvisioningSuccess()");
-                }
-                recordMetric(IpManagerEvent.PROVISIONING_OK);
-                mCallback.onProvisioningSuccess(newLp);
-                break;
-
-            case PROV_CHANGE_LOST_PROVISIONING:
-                if (DBG) {
-                    Log.d(mTag, "onProvisioningFailure()");
-                }
-                recordMetric(IpManagerEvent.PROVISIONING_FAIL);
-                mCallback.onProvisioningFailure(newLp);
-                break;
-
-            default:
-                if (DBG) {
-                    Log.d(mTag, "onLinkPropertiesChange()");
-                }
-                mCallback.onLinkPropertiesChange(newLp);
-                break;
-        }
-    }
-
-    // Updates all IpClient-related state concerned with LinkProperties.
-    // Returns a ProvisioningChange for possibly notifying other interested
-    // parties that are not fronted by IpClient.
-    private int setLinkProperties(LinkProperties newLp) {
-        if (mApfFilter != null) {
-            mApfFilter.setLinkProperties(newLp);
-        }
-        if (mIpReachabilityMonitor != null) {
-            mIpReachabilityMonitor.updateLinkProperties(newLp);
-        }
-
-        int delta = compareProvisioning(mLinkProperties, newLp);
-        mLinkProperties = new LinkProperties(newLp);
-
-        if (delta == PROV_CHANGE_GAINED_PROVISIONING) {
-            // TODO: Add a proper ProvisionedState and cancel the alarm in
-            // its enter() method.
-            mProvisioningTimeoutAlarm.cancel();
-        }
-
-        return delta;
-    }
-
-    private LinkProperties assembleLinkProperties() {
-        // [1] Create a new LinkProperties object to populate.
-        LinkProperties newLp = new LinkProperties();
-        newLp.setInterfaceName(mInterfaceName);
-
-        // [2] Pull in data from netlink:
-        //         - IPv4 addresses
-        //         - IPv6 addresses
-        //         - IPv6 routes
-        //         - IPv6 DNS servers
-        //
-        // N.B.: this is fundamentally race-prone and should be fixed by
-        // changing IpClientLinkObserver from a hybrid edge/level model to an
-        // edge-only model, or by giving IpClient its own netlink socket(s)
-        // so as to track all required information directly.
-        LinkProperties netlinkLinkProperties = mLinkObserver.getLinkProperties();
-        newLp.setLinkAddresses(netlinkLinkProperties.getLinkAddresses());
-        for (RouteInfo route : netlinkLinkProperties.getRoutes()) {
-            newLp.addRoute(route);
-        }
-        addAllReachableDnsServers(newLp, netlinkLinkProperties.getDnsServers());
-
-        // [3] Add in data from DHCPv4, if available.
-        //
-        // mDhcpResults is never shared with any other owner so we don't have
-        // to worry about concurrent modification.
-        if (mDhcpResults != null) {
-            final List<RouteInfo> routes =
-                    mDhcpResults.toStaticIpConfiguration().getRoutes(mInterfaceName);
-            for (RouteInfo route : routes) {
-                newLp.addRoute(route);
-            }
-            addAllReachableDnsServers(newLp, mDhcpResults.dnsServers);
-            newLp.setDomains(mDhcpResults.domains);
-
-            if (mDhcpResults.mtu != 0) {
-                newLp.setMtu(mDhcpResults.mtu);
-            }
-        }
-
-        // [4] Add in TCP buffer sizes and HTTP Proxy config, if available.
-        if (!TextUtils.isEmpty(mTcpBufferSizes)) {
-            newLp.setTcpBufferSizes(mTcpBufferSizes);
-        }
-        if (mHttpProxy != null) {
-            newLp.setHttpProxy(mHttpProxy);
-        }
-
-        // [5] Add data from InitialConfiguration
-        if (mConfiguration != null && mConfiguration.mInitialConfig != null) {
-            InitialConfiguration config = mConfiguration.mInitialConfig;
-            // Add InitialConfiguration routes and dns server addresses once all addresses
-            // specified in the InitialConfiguration have been observed with Netlink.
-            if (config.isProvisionedBy(newLp.getLinkAddresses(), null)) {
-                for (IpPrefix prefix : config.directlyConnectedRoutes) {
-                    newLp.addRoute(new RouteInfo(prefix, null, mInterfaceName, RTN_UNICAST));
-                }
-            }
-            addAllReachableDnsServers(newLp, config.dnsServers);
-        }
-        final LinkProperties oldLp = mLinkProperties;
-        if (DBG) {
-            Log.d(mTag, String.format("Netlink-seen LPs: %s, new LPs: %s; old LPs: %s",
-                    netlinkLinkProperties, newLp, oldLp));
-        }
-
-        // TODO: also learn via netlink routes specified by an InitialConfiguration and specified
-        // from a static IP v4 config instead of manually patching them in in steps [3] and [5].
-        return newLp;
-    }
-
-    private static void addAllReachableDnsServers(
-            LinkProperties lp, Iterable<InetAddress> dnses) {
-        // TODO: Investigate deleting this reachability check.  We should be
-        // able to pass everything down to netd and let netd do evaluation
-        // and RFC6724-style sorting.
-        for (InetAddress dns : dnses) {
-            if (!dns.isAnyLocalAddress() && lp.isReachable(dns)) {
-                lp.addDnsServer(dns);
-            }
-        }
-    }
-
-    // Returns false if we have lost provisioning, true otherwise.
-    private boolean handleLinkPropertiesUpdate(boolean sendCallbacks) {
-        final LinkProperties newLp = assembleLinkProperties();
-        if (Objects.equals(newLp, mLinkProperties)) {
-            return true;
-        }
-        final int delta = setLinkProperties(newLp);
-        // Most of the attributes stored in the memory store are deduced from
-        // the link properties, therefore when the properties update the memory
-        // store record should be updated too.
-        maybeSaveNetworkToIpMemoryStore();
-        if (sendCallbacks) {
-            dispatchCallback(delta, newLp);
-        }
-        return (delta != PROV_CHANGE_LOST_PROVISIONING);
-    }
-
-    private void handleIPv4Success(DhcpResults dhcpResults) {
-        mDhcpResults = new DhcpResults(dhcpResults);
-        final LinkProperties newLp = assembleLinkProperties();
-        final int delta = setLinkProperties(newLp);
-
-        if (DBG) {
-            Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
-        }
-        mCallback.onNewDhcpResults(dhcpResults);
-        maybeSaveNetworkToIpMemoryStore();
-        dispatchCallback(delta, newLp);
-    }
-
-    private void handleIPv4Failure() {
-        // TODO: Investigate deleting this clearIPv4Address() call.
-        //
-        // DhcpClient will send us CMD_CLEAR_LINKADDRESS in all circumstances
-        // that could trigger a call to this function. If we missed handling
-        // that message in StartedState for some reason we would still clear
-        // any addresses upon entry to StoppedState.
-        mInterfaceCtrl.clearIPv4Address();
-        mDhcpResults = null;
-        if (DBG) {
-            Log.d(mTag, "onNewDhcpResults(null)");
-        }
-        mCallback.onNewDhcpResults(null);
-
-        handleProvisioningFailure();
-    }
-
-    private void handleProvisioningFailure() {
-        final LinkProperties newLp = assembleLinkProperties();
-        int delta = setLinkProperties(newLp);
-        // If we've gotten here and we're still not provisioned treat that as
-        // a total loss of provisioning.
-        //
-        // Either (a) static IP configuration failed or (b) DHCPv4 failed AND
-        // there was no usable IPv6 obtained before a non-zero provisioning
-        // timeout expired.
-        //
-        // Regardless: GAME OVER.
-        if (delta == PROV_CHANGE_STILL_NOT_PROVISIONED) {
-            delta = PROV_CHANGE_LOST_PROVISIONING;
-        }
-
-        dispatchCallback(delta, newLp);
-        if (delta == PROV_CHANGE_LOST_PROVISIONING) {
-            transitionTo(mStoppingState);
-        }
-    }
-
-    private void doImmediateProvisioningFailure(int failureType) {
-        logError("onProvisioningFailure(): %s", failureType);
-        recordMetric(failureType);
-        mCallback.onProvisioningFailure(new LinkProperties(mLinkProperties));
-    }
-
-    private boolean startIPv4() {
-        // If we have a StaticIpConfiguration attempt to apply it and
-        // handle the result accordingly.
-        if (mConfiguration.mStaticIpConfig != null) {
-            if (mInterfaceCtrl.setIPv4Address(mConfiguration.mStaticIpConfig.getIpAddress())) {
-                handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
-            } else {
-                return false;
-            }
-        } else {
-            // Start DHCPv4.
-            mDhcpClient = DhcpClient.makeDhcpClient(mContext, IpClient.this, mInterfaceParams);
-            mDhcpClient.registerForPreDhcpNotification();
-            mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
-        }
-
-        return true;
-    }
-
-    private boolean startIPv6() {
-        return mInterfaceCtrl.setIPv6PrivacyExtensions(true)
-                && mInterfaceCtrl.setIPv6AddrGenModeIfSupported(mConfiguration.mIPv6AddrGenMode)
-                && mInterfaceCtrl.enableIPv6();
-    }
-
-    private boolean applyInitialConfig(InitialConfiguration config) {
-        // TODO: also support specifying a static IPv4 configuration in InitialConfiguration.
-        for (LinkAddress addr : findAll(config.ipAddresses, LinkAddress::isIpv6)) {
-            if (!mInterfaceCtrl.addAddress(addr)) return false;
-        }
-
-        return true;
-    }
-
-    private boolean startIpReachabilityMonitor() {
-        try {
-            // TODO: Fetch these parameters from settings, and install a
-            // settings observer to watch for update and re-program these
-            // parameters (Q: is this level of dynamic updatability really
-            // necessary or does reading from settings at startup suffice?).
-            final int numSolicits = 5;
-            final int interSolicitIntervalMs = 750;
-            setNeighborParameters(mNetd, mInterfaceName, numSolicits, interSolicitIntervalMs);
-        } catch (Exception e) {
-            mLog.e("Failed to adjust neighbor parameters", e);
-            // Carry on using the system defaults (currently: 3, 1000);
-        }
-
-        try {
-            mIpReachabilityMonitor = new IpReachabilityMonitor(
-                    mContext,
-                    mInterfaceParams,
-                    getHandler(),
-                    mLog,
-                    new IpReachabilityMonitor.Callback() {
-                        @Override
-                        public void notifyLost(InetAddress ip, String logMsg) {
-                            mCallback.onReachabilityLost(logMsg);
-                        }
-                    },
-                    mConfiguration.mUsingMultinetworkPolicyTracker);
-        } catch (IllegalArgumentException iae) {
-            // Failed to start IpReachabilityMonitor. Log it and call
-            // onProvisioningFailure() immediately.
-            //
-            // See http://b/31038971.
-            logError("IpReachabilityMonitor failure: %s", iae);
-            mIpReachabilityMonitor = null;
-        }
-
-        return (mIpReachabilityMonitor != null);
-    }
-
-    private void stopAllIP() {
-        // We don't need to worry about routes, just addresses, because:
-        //     - disableIpv6() will clear autoconf IPv6 routes as well, and
-        //     - we don't get IPv4 routes from netlink
-        // so we neither react to nor need to wait for changes in either.
-
-        mInterfaceCtrl.disableIPv6();
-        mInterfaceCtrl.clearAllAddresses();
-    }
-
-    private void maybeSaveNetworkToIpMemoryStore() {
-        // TODO : implement this
-    }
-
-    class StoppedState extends State {
-        @Override
-        public void enter() {
-            stopAllIP();
-
-            resetLinkProperties();
-            if (mStartTimeMillis > 0) {
-                // Completed a life-cycle; send a final empty LinkProperties
-                // (cleared in resetLinkProperties() above) and record an event.
-                mCallback.onLinkPropertiesChange(new LinkProperties(mLinkProperties));
-                recordMetric(IpManagerEvent.COMPLETE_LIFECYCLE);
-                mStartTimeMillis = 0;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_TERMINATE_AFTER_STOP:
-                    stopStateMachineUpdaters();
-                    quit();
-                    break;
-
-                case CMD_STOP:
-                    break;
-
-                case CMD_START:
-                    mConfiguration = (android.net.shared.ProvisioningConfiguration) msg.obj;
-                    transitionTo(mStartedState);
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_TCP_BUFFER_SIZES:
-                    mTcpBufferSizes = (String) msg.obj;
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_HTTP_PROXY:
-                    mHttpProxy = (ProxyInfo) msg.obj;
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_L2KEY_GROUPHINT: {
-                    final Pair<String, String> args = (Pair<String, String>) msg.obj;
-                    mL2Key = args.first;
-                    mGroupHint = args.second;
-                    break;
-                }
-
-                case CMD_SET_MULTICAST_FILTER:
-                    mMulticastFiltering = (boolean) msg.obj;
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    // Everything is already stopped.
-                    logError("Unexpected CMD_ON_QUIT (already stopped).");
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    class StoppingState extends State {
-        @Override
-        public void enter() {
-            if (mDhcpClient == null) {
-                // There's no DHCPv4 for which to wait; proceed to stopped.
-                deferMessage(obtainMessage(CMD_JUMP_STOPPING_TO_STOPPED));
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_STOPPING_TO_STOPPED:
-                    transitionTo(mStoppedState);
-                    break;
-
-                case CMD_STOP:
-                    break;
-
-                case DhcpClient.CMD_CLEAR_LINKADDRESS:
-                    mInterfaceCtrl.clearIPv4Address();
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    mDhcpClient = null;
-                    transitionTo(mStoppedState);
-                    break;
-
-                default:
-                    deferMessage(msg);
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    class StartedState extends State {
-        @Override
-        public void enter() {
-            mStartTimeMillis = SystemClock.elapsedRealtime();
-
-            if (mConfiguration.mProvisioningTimeoutMs > 0) {
-                final long alarmTime = SystemClock.elapsedRealtime()
-                        + mConfiguration.mProvisioningTimeoutMs;
-                mProvisioningTimeoutAlarm.schedule(alarmTime);
-            }
-
-            if (readyToProceed()) {
-                deferMessage(obtainMessage(CMD_JUMP_STARTED_TO_RUNNING));
-            } else {
-                // Clear all IPv4 and IPv6 before proceeding to RunningState.
-                // Clean up any leftover state from an abnormal exit from
-                // tethering or during an IpClient restart.
-                stopAllIP();
-            }
-        }
-
-        @Override
-        public void exit() {
-            mProvisioningTimeoutAlarm.cancel();
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_STARTED_TO_RUNNING:
-                    transitionTo(mRunningState);
-                    break;
-
-                case CMD_STOP:
-                    transitionTo(mStoppingState);
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    handleLinkPropertiesUpdate(NO_CALLBACKS);
-                    if (readyToProceed()) {
-                        transitionTo(mRunningState);
-                    }
-                    break;
-
-                case CMD_UPDATE_L2KEY_GROUPHINT: {
-                    final Pair<String, String> args = (Pair<String, String>) msg.obj;
-                    mL2Key = args.first;
-                    mGroupHint = args.second;
-                    // TODO : attributes should be saved to the memory store with
-                    // these new values if they differ from the previous ones.
-                    // If the state machine is in pure StartedState, then the values to input
-                    // are not known yet and should be updated when the LinkProperties are updated.
-                    // If the state machine is in RunningState (which is a child of StartedState)
-                    // then the next NUD check should be used to store the new values to avoid
-                    // inputting current values for what may be a different L3 network.
-                    break;
-                }
-
-                case EVENT_PROVISIONING_TIMEOUT:
-                    handleProvisioningFailure();
-                    break;
-
-                default:
-                    // It's safe to process messages out of order because the
-                    // only message that can both
-                    //     a) be received at this time and
-                    //     b) affect provisioning state
-                    // is EVENT_NETLINK_LINKPROPERTIES_CHANGED (handled above).
-                    deferMessage(msg);
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-
-        private boolean readyToProceed() {
-            return (!mLinkProperties.hasIpv4Address() && !mLinkProperties.hasGlobalIpv6Address());
-        }
-    }
-
-    class RunningState extends State {
-        private ConnectivityPacketTracker mPacketTracker;
-        private boolean mDhcpActionInFlight;
-
-        @Override
-        public void enter() {
-            ApfFilter.ApfConfiguration apfConfig = new ApfFilter.ApfConfiguration();
-            apfConfig.apfCapabilities = mConfiguration.mApfCapabilities;
-            apfConfig.multicastFilter = mMulticastFiltering;
-            // Get the Configuration for ApfFilter from Context
-            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.
-            if (mApfFilter == null) {
-                mCallback.setFallbackMulticastFilter(mMulticastFiltering);
-            }
-
-            mPacketTracker = createPacketTracker();
-            if (mPacketTracker != null) mPacketTracker.start(mConfiguration.mDisplayName);
-
-            if (mConfiguration.mEnableIPv6 && !startIPv6()) {
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV6);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            if (mConfiguration.mEnableIPv4 && !startIPv4()) {
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_STARTING_IPV4);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            final InitialConfiguration config = mConfiguration.mInitialConfig;
-            if ((config != null) && !applyInitialConfig(config)) {
-                // TODO introduce a new IpManagerEvent constant to distinguish this error case.
-                doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING);
-                enqueueJumpToStoppingState();
-                return;
-            }
-
-            if (mConfiguration.mUsingIpReachabilityMonitor && !startIpReachabilityMonitor()) {
-                doImmediateProvisioningFailure(
-                        IpManagerEvent.ERROR_STARTING_IPREACHABILITYMONITOR);
-                enqueueJumpToStoppingState();
-                return;
-            }
-        }
-
-        @Override
-        public void exit() {
-            stopDhcpAction();
-
-            if (mIpReachabilityMonitor != null) {
-                mIpReachabilityMonitor.stop();
-                mIpReachabilityMonitor = null;
-            }
-
-            if (mDhcpClient != null) {
-                mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
-                mDhcpClient.doQuit();
-            }
-
-            if (mPacketTracker != null) {
-                mPacketTracker.stop();
-                mPacketTracker = null;
-            }
-
-            if (mApfFilter != null) {
-                mApfFilter.shutdown();
-                mApfFilter = null;
-            }
-
-            resetLinkProperties();
-        }
-
-        private void enqueueJumpToStoppingState() {
-            deferMessage(obtainMessage(CMD_JUMP_RUNNING_TO_STOPPING));
-        }
-
-        private ConnectivityPacketTracker createPacketTracker() {
-            try {
-                return new ConnectivityPacketTracker(
-                        getHandler(), mInterfaceParams, mConnectivityPacketLog);
-            } catch (IllegalArgumentException e) {
-                return null;
-            }
-        }
-
-        private void ensureDhcpAction() {
-            if (!mDhcpActionInFlight) {
-                mCallback.onPreDhcpAction();
-                mDhcpActionInFlight = true;
-                final long alarmTime = SystemClock.elapsedRealtime()
-                        + mConfiguration.mRequestedPreDhcpActionMs;
-                mDhcpActionTimeoutAlarm.schedule(alarmTime);
-            }
-        }
-
-        private void stopDhcpAction() {
-            mDhcpActionTimeoutAlarm.cancel();
-            if (mDhcpActionInFlight) {
-                mCallback.onPostDhcpAction();
-                mDhcpActionInFlight = false;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_JUMP_RUNNING_TO_STOPPING:
-                case CMD_STOP:
-                    transitionTo(mStoppingState);
-                    break;
-
-                case CMD_START:
-                    logError("ALERT: START received in StartedState. Please fix caller.");
-                    break;
-
-                case CMD_CONFIRM:
-                    // TODO: Possibly introduce a second type of confirmation
-                    // that both probes (a) on-link neighbors and (b) does
-                    // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
-                    // roams.
-                    if (mIpReachabilityMonitor != null) {
-                        mIpReachabilityMonitor.probeAll();
-                    }
-                    break;
-
-                case EVENT_PRE_DHCP_ACTION_COMPLETE:
-                    // It's possible to reach here if, for example, someone
-                    // calls completedPreDhcpAction() after provisioning with
-                    // a static IP configuration.
-                    if (mDhcpClient != null) {
-                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
-                    }
-                    break;
-
-                case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
-                    if (!handleLinkPropertiesUpdate(SEND_CALLBACKS)) {
-                        transitionTo(mStoppingState);
-                    }
-                    break;
-
-                case CMD_UPDATE_TCP_BUFFER_SIZES:
-                    mTcpBufferSizes = (String) msg.obj;
-                    // This cannot possibly change provisioning state.
-                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
-                    break;
-
-                case CMD_UPDATE_HTTP_PROXY:
-                    mHttpProxy = (ProxyInfo) msg.obj;
-                    // This cannot possibly change provisioning state.
-                    handleLinkPropertiesUpdate(SEND_CALLBACKS);
-                    break;
-
-                case CMD_SET_MULTICAST_FILTER: {
-                    mMulticastFiltering = (boolean) msg.obj;
-                    if (mApfFilter != null) {
-                        mApfFilter.setMulticastFilter(mMulticastFiltering);
-                    } else {
-                        mCallback.setFallbackMulticastFilter(mMulticastFiltering);
-                    }
-                    break;
-                }
-
-                case EVENT_READ_PACKET_FILTER_COMPLETE: {
-                    if (mApfFilter != null) {
-                        mApfFilter.setDataSnapshot((byte[]) msg.obj);
-                    }
-                    mApfDataSnapshotComplete.open();
-                    break;
-                }
-
-                case CMD_ADD_KEEPALIVE_PACKET_FILTER_TO_APF: {
-                    final int slot = msg.arg1;
-
-                    if (mApfFilter != null) {
-                        if (msg.obj instanceof NattKeepalivePacketDataParcelable) {
-                            mApfFilter.addNattKeepalivePacketFilter(slot,
-                                    (NattKeepalivePacketDataParcelable) msg.obj);
-                        } else if (msg.obj instanceof TcpKeepalivePacketDataParcelable) {
-                            mApfFilter.addTcpKeepalivePacketFilter(slot,
-                                    (TcpKeepalivePacketDataParcelable) msg.obj);
-                        }
-                    }
-                    break;
-                }
-
-                case CMD_REMOVE_KEEPALIVE_PACKET_FILTER_FROM_APF: {
-                    final int slot = msg.arg1;
-                    if (mApfFilter != null) {
-                        mApfFilter.removeKeepalivePacketFilter(slot);
-                    }
-                    break;
-                }
-
-                case EVENT_DHCPACTION_TIMEOUT:
-                    stopDhcpAction();
-                    break;
-
-                case DhcpClient.CMD_PRE_DHCP_ACTION:
-                    if (mConfiguration.mRequestedPreDhcpActionMs > 0) {
-                        ensureDhcpAction();
-                    } else {
-                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
-                    }
-                    break;
-
-                case DhcpClient.CMD_CLEAR_LINKADDRESS:
-                    mInterfaceCtrl.clearIPv4Address();
-                    break;
-
-                case DhcpClient.CMD_CONFIGURE_LINKADDRESS: {
-                    final LinkAddress ipAddress = (LinkAddress) msg.obj;
-                    if (mInterfaceCtrl.setIPv4Address(ipAddress)) {
-                        mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
-                    } else {
-                        logError("Failed to set IPv4 address.");
-                        dispatchCallback(PROV_CHANGE_LOST_PROVISIONING,
-                                new LinkProperties(mLinkProperties));
-                        transitionTo(mStoppingState);
-                    }
-                    break;
-                }
-
-                // This message is only received when:
-                //
-                //     a) initial address acquisition succeeds,
-                //     b) renew succeeds or is NAK'd,
-                //     c) rebind succeeds or is NAK'd, or
-                //     c) the lease expires,
-                //
-                // but never when initial address acquisition fails. The latter
-                // condition is now governed by the provisioning timeout.
-                case DhcpClient.CMD_POST_DHCP_ACTION:
-                    stopDhcpAction();
-
-                    switch (msg.arg1) {
-                        case DhcpClient.DHCP_SUCCESS:
-                            handleIPv4Success((DhcpResults) msg.obj);
-                            break;
-                        case DhcpClient.DHCP_FAILURE:
-                            handleIPv4Failure();
-                            break;
-                        default:
-                            logError("Unknown CMD_POST_DHCP_ACTION status: %s", msg.arg1);
-                    }
-                    break;
-
-                case DhcpClient.CMD_ON_QUIT:
-                    // DHCPv4 quit early for some reason.
-                    logError("Unexpected CMD_ON_QUIT.");
-                    mDhcpClient = null;
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            mMsgStateLogger.handled(this, getCurrentState());
-            return HANDLED;
-        }
-    }
-
-    private static class MessageHandlingLogger {
-        public String processedInState;
-        public String receivedInState;
-
-        public void reset() {
-            processedInState = null;
-            receivedInState = null;
-        }
-
-        public void handled(State processedIn, IState receivedIn) {
-            processedInState = processedIn.getClass().getSimpleName();
-            receivedInState = receivedIn.getName();
-        }
-
-        public String toString() {
-            return String.format("rcvd_in=%s, proc_in=%s",
-                                 receivedInState, processedInState);
-        }
-    }
-
-    private static void setNeighborParameters(
-            INetd netd, String ifName, int numSolicits, int interSolicitIntervalMs)
-            throws RemoteException, IllegalArgumentException {
-        Preconditions.checkNotNull(netd);
-        Preconditions.checkArgument(!TextUtils.isEmpty(ifName));
-        Preconditions.checkArgument(numSolicits > 0);
-        Preconditions.checkArgument(interSolicitIntervalMs > 0);
-
-        for (int family : new Integer[]{INetd.IPV4, INetd.IPV6}) {
-            netd.setProcSysNet(family, INetd.NEIGH, ifName, "retrans_time_ms",
-                    Integer.toString(interSolicitIntervalMs));
-            netd.setProcSysNet(family, INetd.NEIGH, ifName, "ucast_solicit",
-                    Integer.toString(numSolicits));
-        }
-    }
-
-    // TODO: extract out into CollectionUtils.
-    static <T> boolean any(Iterable<T> coll, Predicate<T> fn) {
-        for (T t : coll) {
-            if (fn.test(t)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    static <T> boolean all(Iterable<T> coll, Predicate<T> fn) {
-        return !any(coll, not(fn));
-    }
-
-    static <T> Predicate<T> not(Predicate<T> fn) {
-        return (t) -> !fn.test(t);
-    }
-
-    static <T> String join(String delimiter, Collection<T> coll) {
-        return coll.stream().map(Object::toString).collect(Collectors.joining(delimiter));
-    }
-
-    static <T> T find(Iterable<T> coll, Predicate<T> fn) {
-        for (T t: coll) {
-            if (fn.test(t)) {
-                return t;
-            }
-        }
-        return null;
-    }
-
-    static <T> List<T> findAll(Collection<T> coll, Predicate<T> fn) {
-        return coll.stream().filter(fn).collect(Collectors.toList());
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java b/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java
deleted file mode 100644
index 8ad99aa0..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpClientLinkObserver.java
+++ /dev/null
@@ -1,378 +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.
- */
-
-package android.net.ip;
-
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.RouteInfo;
-import android.util.Log;
-
-import com.android.server.NetworkObserver;
-
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Keeps track of link configuration received from Netd.
- *
- * An instance of this class is constructed by passing in an interface name and a callback. The
- * owner is then responsible for registering the tracker with NetworkObserverRegistry. When the
- * class receives update notifications, it applies the update to its local LinkProperties, and if
- * something has changed, notifies its owner of the update via the callback.
- *
- * The owner can then call {@code getLinkProperties()} in order to find out
- * what changed. If in the meantime the LinkProperties stored here have changed,
- * this class will return the current LinkProperties. Because each change
- * triggers an update callback after the change is made, the owner may get more
- * callbacks than strictly necessary (some of which may be no-ops), but will not
- * be out of sync once all callbacks have been processed.
- *
- * Threading model:
- *
- * - The owner of this class is expected to create it, register it, and call
- *   getLinkProperties or clearLinkProperties on its thread.
- * - Most of the methods in the class are implementing NetworkObserver and are called
- *   on the handler used to register the observer.
- * - All accesses to mLinkProperties must be synchronized(this). All the other
- *   member variables are immutable once the object is constructed.
- *
- * @hide
- */
-public class IpClientLinkObserver implements NetworkObserver {
-    private final String mTag;
-
-    /**
-     * Callback used by {@link IpClientLinkObserver} to send update notifications.
-     */
-    public interface Callback {
-        /**
-         * Called when some properties of the link were updated.
-         */
-        void update();
-    }
-
-    private final String mInterfaceName;
-    private final Callback mCallback;
-    private final LinkProperties mLinkProperties;
-    private DnsServerRepository mDnsServerRepository;
-
-    private static final boolean DBG = false;
-
-    public IpClientLinkObserver(String iface, Callback callback) {
-        mTag = "NetlinkTracker/" + iface;
-        mInterfaceName = iface;
-        mCallback = callback;
-        mLinkProperties = new LinkProperties();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-        mDnsServerRepository = new DnsServerRepository();
-    }
-
-    private void maybeLog(String operation, String iface, LinkAddress address) {
-        if (DBG) {
-            Log.d(mTag, operation + ": " + address + " on " + iface
-                    + " flags " + address.getFlags() + " scope " + address.getScope());
-        }
-    }
-
-    private void maybeLog(String operation, Object o) {
-        if (DBG) {
-            Log.d(mTag, operation + ": " + o.toString());
-        }
-    }
-
-    @Override
-    public void onInterfaceRemoved(String iface) {
-        maybeLog("interfaceRemoved", iface);
-        if (mInterfaceName.equals(iface)) {
-            // Our interface was removed. Clear our LinkProperties and tell our owner that they are
-            // now empty. Note that from the moment that the interface is removed, any further
-            // interface-specific messages (e.g., RTM_DELADDR) will not reach us, because the netd
-            // code that parses them will not be able to resolve the ifindex to an interface name.
-            clearLinkProperties();
-            mCallback.update();
-        }
-    }
-
-    @Override
-    public void onInterfaceAddressUpdated(LinkAddress address, String iface) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("addressUpdated", iface, address);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.addLinkAddress(address);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceAddressRemoved(LinkAddress address, String iface) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("addressRemoved", iface, address);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.removeLinkAddress(address);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onRouteUpdated(RouteInfo route) {
-        if (mInterfaceName.equals(route.getInterface())) {
-            maybeLog("routeUpdated", route);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.addRoute(route);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onRouteRemoved(RouteInfo route) {
-        if (mInterfaceName.equals(route.getInterface())) {
-            maybeLog("routeRemoved", route);
-            boolean changed;
-            synchronized (this) {
-                changed = mLinkProperties.removeRoute(route);
-            }
-            if (changed) {
-                mCallback.update();
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) {
-        if (mInterfaceName.equals(iface)) {
-            maybeLog("interfaceDnsServerInfo", Arrays.toString(addresses));
-            boolean changed = mDnsServerRepository.addServers(lifetime, addresses);
-            if (changed) {
-                synchronized (this) {
-                    mDnsServerRepository.setDnsServersOn(mLinkProperties);
-                }
-                mCallback.update();
-            }
-        }
-    }
-
-    /**
-     * Returns a copy of this object's LinkProperties.
-     */
-    public synchronized LinkProperties getLinkProperties() {
-        return new LinkProperties(mLinkProperties);
-    }
-
-    /**
-     * Reset this object's LinkProperties.
-     */
-    public synchronized void clearLinkProperties() {
-        // Clear the repository before clearing mLinkProperties. That way, if a clear() happens
-        // while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in
-        // mLinkProperties, as desired.
-        mDnsServerRepository = new DnsServerRepository();
-        mLinkProperties.clear();
-        mLinkProperties.setInterfaceName(mInterfaceName);
-    }
-
-    /**
-     * Tracks DNS server updates received from Netlink.
-     *
-     * The network may announce an arbitrary number of DNS servers in Router Advertisements at any
-     * time. Each announcement has a lifetime; when the lifetime expires, the servers should not be
-     * used any more. In this way, the network can gracefully migrate clients from one set of DNS
-     * servers to another. Announcements can both raise and lower the lifetime, and an announcement
-     * can expire servers by announcing them with a lifetime of zero.
-     *
-     * Typically the system will only use a small number (2 or 3; {@code NUM_CURRENT_SERVERS}) of
-     * DNS servers at any given time. These are referred to as the current servers. In case all the
-     * current servers expire, the class also keeps track of a larger (but limited) number of
-     * servers that are promoted to current servers when the current ones expire. In order to
-     * minimize updates to the rest of the system (and potentially expensive cache flushes) this
-     * class attempts to keep the list of current servers constant where possible. More
-     * specifically, the list of current servers is only updated if a new server is learned and
-     * there are not yet {@code NUM_CURRENT_SERVERS} current servers, or if one or more of the
-     * current servers expires or is pushed out of the set. Therefore, the current servers will not
-     * necessarily be the ones with the highest lifetime, but the ones learned first.
-     *
-     * This is by design: if instead the class always preferred the servers with the highest
-     * lifetime, a (misconfigured?) network where two or more routers announce more than
-     * {@code NUM_CURRENT_SERVERS} unique servers would cause persistent oscillations.
-     *
-     * TODO: Currently servers are only expired when a new DNS update is received.
-     * Update them using timers, or possibly on every notification received by NetlinkTracker.
-     *
-     * Threading model: run by NetlinkTracker. Methods are synchronized(this) just in case netlink
-     * notifications are sent by multiple threads. If future threads use alarms to expire, those
-     * alarms must also be synchronized(this).
-     *
-     */
-    private static class DnsServerRepository {
-
-        /** How many DNS servers we will use. 3 is suggested by RFC 6106. */
-        static final int NUM_CURRENT_SERVERS = 3;
-
-        /** How many DNS servers we'll keep track of, in total. */
-        static final int NUM_SERVERS = 12;
-
-        /** Stores up to {@code NUM_CURRENT_SERVERS} DNS servers we're currently using. */
-        private Set<InetAddress> mCurrentServers;
-
-        public static final String TAG = "DnsServerRepository";
-
-        /**
-         * Stores all the DNS servers we know about, for use when the current servers expire.
-         * Always sorted in order of decreasing expiry. The elements in this list are also the
-         * values of mIndex, and may be elements in mCurrentServers.
-         */
-        private ArrayList<DnsServerEntry> mAllServers;
-
-        /**
-         * Indexes the servers so we can update their lifetimes more quickly in the common case
-         * where servers are not being added, but only being refreshed.
-         */
-        private HashMap<InetAddress, DnsServerEntry> mIndex;
-
-        DnsServerRepository() {
-            mCurrentServers = new HashSet<>();
-            mAllServers = new ArrayList<>(NUM_SERVERS);
-            mIndex = new HashMap<>(NUM_SERVERS);
-        }
-
-        /** Sets the DNS servers of the provided LinkProperties object to the current servers. */
-        public synchronized void setDnsServersOn(LinkProperties lp) {
-            lp.setDnsServers(mCurrentServers);
-        }
-
-        /**
-         * Notifies the class of new DNS server information.
-         * @param lifetime the time in seconds that the DNS servers are valid.
-         * @param addresses the string representations of the IP addresses of DNS servers to use.
-         */
-        public synchronized boolean addServers(long lifetime, String[] addresses) {
-            // The lifetime is actually an unsigned 32-bit number, but Java doesn't have unsigned.
-            // Technically 0xffffffff (the maximum) is special and means "forever", but 2^32 seconds
-            // (136 years) is close enough.
-            long now = System.currentTimeMillis();
-            long expiry = now + 1000 * lifetime;
-
-            // Go through the list of servers. For each one, update the entry if one exists, and
-            // create one if it doesn't.
-            for (String addressString : addresses) {
-                InetAddress address;
-                try {
-                    address = InetAddresses.parseNumericAddress(addressString);
-                } catch (IllegalArgumentException ex) {
-                    continue;
-                }
-
-                if (!updateExistingEntry(address, expiry)) {
-                    // There was no entry for this server. Create one, unless it's already expired
-                    // (i.e., if the lifetime is zero; it cannot be < 0 because it's unsigned).
-                    if (expiry > now) {
-                        DnsServerEntry entry = new DnsServerEntry(address, expiry);
-                        mAllServers.add(entry);
-                        mIndex.put(address, entry);
-                    }
-                }
-            }
-
-            // Sort the servers by expiry.
-            Collections.sort(mAllServers);
-
-            // Prune excess entries and update the current server list.
-            return updateCurrentServers();
-        }
-
-        private synchronized boolean updateExistingEntry(InetAddress address, long expiry) {
-            DnsServerEntry existing = mIndex.get(address);
-            if (existing != null) {
-                existing.expiry = expiry;
-                return true;
-            }
-            return false;
-        }
-
-        private synchronized boolean updateCurrentServers() {
-            long now = System.currentTimeMillis();
-            boolean changed = false;
-
-            // Prune excess or expired entries.
-            for (int i = mAllServers.size() - 1; i >= 0; i--) {
-                if (i >= NUM_SERVERS || mAllServers.get(i).expiry < now) {
-                    DnsServerEntry removed = mAllServers.remove(i);
-                    mIndex.remove(removed.address);
-                    changed |= mCurrentServers.remove(removed.address);
-                } else {
-                    break;
-                }
-            }
-
-            // Add servers to the current set, in order of decreasing lifetime, until it has enough.
-            // Prefer existing servers over new servers in order to minimize updates to the rest of
-            // the system and avoid persistent oscillations.
-            for (DnsServerEntry entry : mAllServers) {
-                if (mCurrentServers.size() < NUM_CURRENT_SERVERS) {
-                    changed |= mCurrentServers.add(entry.address);
-                } else {
-                    break;
-                }
-            }
-            return changed;
-        }
-    }
-
-    /**
-     * Represents a DNS server entry with an expiry time.
-     *
-     * Implements Comparable so DNS server entries can be sorted by lifetime, longest-lived first.
-     * The ordering of entries with the same lifetime is unspecified, because given two servers with
-     * identical lifetimes, we don't care which one we use, and only comparing the lifetime is much
-     * faster than comparing the IP address as well.
-     *
-     * Note: this class has a natural ordering that is inconsistent with equals.
-     */
-    private static class DnsServerEntry implements Comparable<DnsServerEntry> {
-        /** The IP address of the DNS server. */
-        public final InetAddress address;
-        /** The time until which the DNS server may be used. A Java millisecond time as might be
-         * returned by currentTimeMillis(). */
-        public long expiry;
-
-        DnsServerEntry(InetAddress address, long expiry) throws IllegalArgumentException {
-            this.address = address;
-            this.expiry = expiry;
-        }
-
-        public int compareTo(DnsServerEntry other) {
-            return Long.compare(other.expiry, this.expiry);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java b/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
deleted file mode 100644
index 6ae9a2b..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH;
-import static android.net.netlink.NetlinkConstants.hexify;
-import static android.net.netlink.NetlinkConstants.stringForNlMsgType;
-import static android.net.util.SocketUtils.makeNetlinkSocketAddress;
-import static android.system.OsConstants.AF_NETLINK;
-import static android.system.OsConstants.NETLINK_ROUTE;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-
-import android.net.MacAddress;
-import android.net.netlink.NetlinkErrorMessage;
-import android.net.netlink.NetlinkMessage;
-import android.net.netlink.NetlinkSocket;
-import android.net.netlink.RtNetlinkNeighborMessage;
-import android.net.netlink.StructNdMsg;
-import android.net.util.NetworkStackUtils;
-import android.net.util.PacketReader;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.net.InetAddress;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.StringJoiner;
-
-
-/**
- * IpNeighborMonitor.
- *
- * Monitors the kernel rtnetlink neighbor notifications and presents to callers
- * NeighborEvents describing each event. Callers can provide a consumer instance
- * to both filter (e.g. by interface index and IP address) and handle the
- * generated NeighborEvents.
- *
- * @hide
- */
-public class IpNeighborMonitor extends PacketReader {
-    private static final String TAG = IpNeighborMonitor.class.getSimpleName();
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    /**
-     * Make the kernel perform neighbor reachability detection (IPv4 ARP or IPv6 ND)
-     * for the given IP address on the specified interface index.
-     *
-     * @return 0 if the request was successfully passed to the kernel; otherwise return
-     *         a non-zero error code.
-     */
-    public static int startKernelNeighborProbe(int ifIndex, InetAddress ip) {
-        final String msgSnippet = "probing ip=" + ip.getHostAddress() + "%" + ifIndex;
-        if (DBG) { Log.d(TAG, msgSnippet); }
-
-        final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage(
-                1, ip, StructNdMsg.NUD_PROBE, ifIndex, null);
-
-        try {
-            NetlinkSocket.sendOneShotKernelMessage(NETLINK_ROUTE, msg);
-        } catch (ErrnoException e) {
-            Log.e(TAG, "Error " + msgSnippet + ": " + e);
-            return -e.errno;
-        }
-
-        return 0;
-    }
-
-    public static class NeighborEvent {
-        final long elapsedMs;
-        final short msgType;
-        final int ifindex;
-        final InetAddress ip;
-        final short nudState;
-        final MacAddress macAddr;
-
-        public NeighborEvent(long elapsedMs, short msgType, int ifindex, InetAddress ip,
-                short nudState, MacAddress macAddr) {
-            this.elapsedMs = elapsedMs;
-            this.msgType = msgType;
-            this.ifindex = ifindex;
-            this.ip = ip;
-            this.nudState = nudState;
-            this.macAddr = macAddr;
-        }
-
-        boolean isConnected() {
-            return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateConnected(nudState);
-        }
-
-        boolean isValid() {
-            return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateValid(nudState);
-        }
-
-        @Override
-        public String toString() {
-            final StringJoiner j = new StringJoiner(",", "NeighborEvent{", "}");
-            return j.add("@" + elapsedMs)
-                    .add(stringForNlMsgType(msgType))
-                    .add("if=" + ifindex)
-                    .add(ip.getHostAddress())
-                    .add(StructNdMsg.stringForNudState(nudState))
-                    .add("[" + macAddr + "]")
-                    .toString();
-        }
-    }
-
-    public interface NeighborEventConsumer {
-        // Every neighbor event received on the netlink socket is passed in
-        // here. Subclasses should filter for events of interest.
-        public void accept(NeighborEvent event);
-    }
-
-    private final SharedLog mLog;
-    private final NeighborEventConsumer mConsumer;
-
-    public IpNeighborMonitor(Handler h, SharedLog log, NeighborEventConsumer cb) {
-        super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE);
-        mLog = log.forSubComponent(TAG);
-        mConsumer = (cb != null) ? cb : (event) -> { /* discard */ };
-    }
-
-    @Override
-    protected FileDescriptor createFd() {
-        FileDescriptor fd = null;
-
-        try {
-            fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, NETLINK_ROUTE);
-            Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH));
-            NetlinkSocket.connectToKernel(fd);
-
-            if (VDBG) {
-                final SocketAddress nlAddr = Os.getsockname(fd);
-                Log.d(TAG, "bound to sockaddr_nl{" + nlAddr.toString() + "}");
-            }
-        } catch (ErrnoException|SocketException e) {
-            logError("Failed to create rtnetlink socket", e);
-            NetworkStackUtils.closeSocketQuietly(fd);
-            return null;
-        }
-
-        return fd;
-    }
-
-    @Override
-    protected void handlePacket(byte[] recvbuf, int length) {
-        final long whenMs = SystemClock.elapsedRealtime();
-
-        final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length);
-        byteBuffer.order(ByteOrder.nativeOrder());
-
-        parseNetlinkMessageBuffer(byteBuffer, whenMs);
-    }
-
-    private void parseNetlinkMessageBuffer(ByteBuffer byteBuffer, long whenMs) {
-        while (byteBuffer.remaining() > 0) {
-            final int position = byteBuffer.position();
-            final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer);
-            if (nlMsg == null || nlMsg.getHeader() == null) {
-                byteBuffer.position(position);
-                mLog.e("unparsable netlink msg: " + hexify(byteBuffer));
-                break;
-            }
-
-            final int srcPortId = nlMsg.getHeader().nlmsg_pid;
-            if (srcPortId !=  0) {
-                mLog.e("non-kernel source portId: " + Integer.toUnsignedLong(srcPortId));
-                break;
-            }
-
-            if (nlMsg instanceof NetlinkErrorMessage) {
-                mLog.e("netlink error: " + nlMsg);
-                continue;
-            } else if (!(nlMsg instanceof RtNetlinkNeighborMessage)) {
-                mLog.i("non-rtnetlink neighbor msg: " + nlMsg);
-                continue;
-            }
-
-            evaluateRtNetlinkNeighborMessage((RtNetlinkNeighborMessage) nlMsg, whenMs);
-        }
-    }
-
-    private void evaluateRtNetlinkNeighborMessage(
-            RtNetlinkNeighborMessage neighMsg, long whenMs) {
-        final short msgType = neighMsg.getHeader().nlmsg_type;
-        final StructNdMsg ndMsg = neighMsg.getNdHeader();
-        if (ndMsg == null) {
-            mLog.e("RtNetlinkNeighborMessage without ND message header!");
-            return;
-        }
-
-        final int ifindex = ndMsg.ndm_ifindex;
-        final InetAddress destination = neighMsg.getDestination();
-        final short nudState =
-                (msgType == RTM_DELNEIGH)
-                ? StructNdMsg.NUD_NONE
-                : ndMsg.ndm_state;
-
-        final NeighborEvent event = new NeighborEvent(
-                whenMs, msgType, ifindex, destination, nudState,
-                getMacAddress(neighMsg.getLinkLayerAddress()));
-
-        if (VDBG) {
-            Log.d(TAG, neighMsg.toString());
-        }
-        if (DBG) {
-            Log.d(TAG, event.toString());
-        }
-
-        mConsumer.accept(event);
-    }
-
-    private static MacAddress getMacAddress(byte[] linkLayerAddress) {
-        if (linkLayerAddress != null) {
-            try {
-                return MacAddress.fromBytes(linkLayerAddress);
-            } catch (IllegalArgumentException e) {
-                Log.e(TAG, "Failed to parse link-layer address: " + hexify(linkLayerAddress));
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
deleted file mode 100644
index c19a24e..0000000
--- a/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.ip;
-
-import static android.net.metrics.IpReachabilityEvent.NUD_FAILED;
-import static android.net.metrics.IpReachabilityEvent.NUD_FAILED_ORGANIC;
-import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST;
-import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST_ORGANIC;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.RouteInfo;
-import android.net.ip.IpNeighborMonitor.NeighborEvent;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.IpReachabilityEvent;
-import android.net.netlink.StructNdMsg;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.io.PrintWriter;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-
-/**
- * IpReachabilityMonitor.
- *
- * Monitors on-link IP reachability and notifies callers whenever any on-link
- * addresses of interest appear to have become unresponsive.
- *
- * This code does not concern itself with "why" a neighbour might have become
- * unreachable. Instead, it primarily reacts to the kernel's notion of IP
- * reachability for each of the neighbours we know to be critically important
- * to normal network connectivity. As such, it is often "just the messenger":
- * the neighbours about which it warns are already deemed by the kernel to have
- * become unreachable.
- *
- *
- * How it works:
- *
- *   1. The "on-link neighbours of interest" found in a given LinkProperties
- *      instance are added to a "watch list" via #updateLinkProperties().
- *      This usually means all default gateways and any on-link DNS servers.
- *
- *   2. We listen continuously for netlink neighbour messages (RTM_NEWNEIGH,
- *      RTM_DELNEIGH), watching only for neighbours in the watch list.
- *
- *        - A neighbour going into NUD_REACHABLE, NUD_STALE, NUD_DELAY, and
- *          even NUD_PROBE is perfectly normal; we merely record the new state.
- *
- *        - A neighbour's entry may be deleted (RTM_DELNEIGH), for example due
- *          to garbage collection.  This is not necessarily of immediate
- *          concern; we record the neighbour as moving to NUD_NONE.
- *
- *        - A neighbour transitioning to NUD_FAILED (for any reason) is
- *          critically important and is handled as described below in #4.
- *
- *   3. All on-link neighbours in the watch list can be forcibly "probed" by
- *      calling #probeAll(). This should be called whenever it is important to
- *      verify that critical neighbours on the link are still reachable, e.g.
- *      when roaming between BSSIDs.
- *
- *        - The kernel will send unicast ARP requests for IPv4 neighbours and
- *          unicast NS packets for IPv6 neighbours.  The expected replies will
- *          likely be unicast.
- *
- *        - The forced probing is done holding a wakelock. The kernel may,
- *          however, initiate probing of a neighbor on its own, i.e. whenever
- *          a neighbour has expired from NUD_DELAY.
- *
- *        - The kernel sends:
- *
- *              /proc/sys/net/ipv{4,6}/neigh/<ifname>/ucast_solicit
- *
- *          number of probes (usually 3) every:
- *
- *              /proc/sys/net/ipv{4,6}/neigh/<ifname>/retrans_time_ms
- *
- *          number of milliseconds (usually 1000ms). This normally results in
- *          3 unicast packets, 1 per second.
- *
- *        - If no response is received to any of the probe packets, the kernel
- *          marks the neighbour as being in state NUD_FAILED, and the listening
- *          process in #2 will learn of it.
- *
- *   4. We call the supplied Callback#notifyLost() function if the loss of a
- *      neighbour in NUD_FAILED would cause IPv4 or IPv6 configuration to
- *      become incomplete (a loss of provisioning).
- *
- *        - For example, losing all our IPv4 on-link DNS servers (or losing
- *          our only IPv6 default gateway) constitutes a loss of IPv4 (IPv6)
- *          provisioning; Callback#notifyLost() would be called.
- *
- *        - Since it can be non-trivial to reacquire certain IP provisioning
- *          state it may be best for the link to disconnect completely and
- *          reconnect afresh.
- *
- * Accessing an instance of this class from multiple threads is NOT safe.
- *
- * @hide
- */
-public class IpReachabilityMonitor {
-    private static final String TAG = "IpReachabilityMonitor";
-    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
-        // run on the same thread that listens to kernel neighbor updates.
-        //
-        // TODO: refactor to something like notifyProvisioningLost(String msg).
-        public void notifyLost(InetAddress ip, String logMsg);
-    }
-
-    /**
-     * Encapsulates IpReachabilityMonitor depencencies on systems that hinder unit testing.
-     * TODO: consider also wrapping MultinetworkPolicyTracker in this interface.
-     */
-    interface Dependencies {
-        void acquireWakeLock(long durationMs);
-
-        static Dependencies makeDefault(Context context, String iface) {
-            final String lockName = TAG + "." + iface;
-            final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-            final WakeLock lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName);
-
-            return new Dependencies() {
-                public void acquireWakeLock(long durationMs) {
-                    lock.acquire(durationMs);
-                }
-            };
-        }
-    }
-
-    private final InterfaceParams mInterfaceParams;
-    private final IpNeighborMonitor mIpNeighborMonitor;
-    private final SharedLog mLog;
-    private final Callback mCallback;
-    private final Dependencies mDependencies;
-    private final boolean mUsingMultinetworkPolicyTracker;
-    private final ConnectivityManager mCm;
-    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
-    private LinkProperties mLinkProperties = new LinkProperties();
-    private Map<InetAddress, NeighborEvent> mNeighborWatchList = new HashMap<>();
-    // Time in milliseconds of the last forced probe request.
-    private volatile long mLastProbeTimeMs;
-
-    public IpReachabilityMonitor(
-            Context context, InterfaceParams ifParams, Handler h, SharedLog log, Callback callback,
-            boolean usingMultinetworkPolicyTracker) {
-        this(context, ifParams, h, log, callback, usingMultinetworkPolicyTracker,
-                Dependencies.makeDefault(context, ifParams.name));
-    }
-
-    @VisibleForTesting
-    IpReachabilityMonitor(Context context, InterfaceParams ifParams, Handler h, SharedLog log,
-            Callback callback, boolean usingMultinetworkPolicyTracker, Dependencies dependencies) {
-        if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams");
-
-        mInterfaceParams = ifParams;
-        mLog = log.forSubComponent(TAG);
-        mCallback = callback;
-        mUsingMultinetworkPolicyTracker = usingMultinetworkPolicyTracker;
-        mCm = context.getSystemService(ConnectivityManager.class);
-        mDependencies = dependencies;
-
-        mIpNeighborMonitor = new IpNeighborMonitor(h, mLog,
-                (NeighborEvent event) -> {
-                    if (mInterfaceParams.index != event.ifindex) return;
-                    if (!mNeighborWatchList.containsKey(event.ip)) return;
-
-                    final NeighborEvent prev = mNeighborWatchList.put(event.ip, event);
-
-                    // TODO: Consider what to do with other states that are not within
-                    // NeighborEvent#isValid() (i.e. NUD_NONE, NUD_INCOMPLETE).
-                    if (event.nudState == StructNdMsg.NUD_FAILED) {
-                        mLog.w("ALERT neighbor went from: " + prev + " to: " + event);
-                        handleNeighborLost(event);
-                    }
-                });
-        mIpNeighborMonitor.start();
-    }
-
-    public void stop() {
-        mIpNeighborMonitor.stop();
-        clearLinkProperties();
-    }
-
-    public void dump(PrintWriter pw) {
-        if (Looper.myLooper() == mIpNeighborMonitor.getHandler().getLooper()) {
-            pw.println(describeWatchList("\n"));
-            return;
-        }
-
-        final ConditionVariable cv = new ConditionVariable(false);
-        mIpNeighborMonitor.getHandler().post(() -> {
-            pw.println(describeWatchList("\n"));
-            cv.open();
-        });
-
-        if (!cv.block(1000)) {
-            pw.println("Timed out waiting for IpReachabilityMonitor dump");
-        }
-    }
-
-    private String describeWatchList() { return describeWatchList(" "); }
-
-    private String describeWatchList(String sep) {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("iface{" + mInterfaceParams + "}," + sep);
-        sb.append("ntable=[" + sep);
-        String delimiter = "";
-        for (Map.Entry<InetAddress, NeighborEvent> entry : mNeighborWatchList.entrySet()) {
-            sb.append(delimiter).append(entry.getKey().getHostAddress() + "/" + entry.getValue());
-            delimiter = "," + sep;
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    private static boolean isOnLink(List<RouteInfo> routes, InetAddress ip) {
-        for (RouteInfo route : routes) {
-            if (!route.hasGateway() && route.matches(ip)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public void updateLinkProperties(LinkProperties lp) {
-        if (!mInterfaceParams.name.equals(lp.getInterfaceName())) {
-            // TODO: figure out whether / how to cope with interface changes.
-            Log.wtf(TAG, "requested LinkProperties interface '" + lp.getInterfaceName() +
-                    "' does not match: " + mInterfaceParams.name);
-            return;
-        }
-
-        mLinkProperties = new LinkProperties(lp);
-        Map<InetAddress, NeighborEvent> newNeighborWatchList = new HashMap<>();
-
-        final List<RouteInfo> routes = mLinkProperties.getRoutes();
-        for (RouteInfo route : routes) {
-            if (route.hasGateway()) {
-                InetAddress gw = route.getGateway();
-                if (isOnLink(routes, gw)) {
-                    newNeighborWatchList.put(gw, mNeighborWatchList.getOrDefault(gw, null));
-                }
-            }
-        }
-
-        for (InetAddress dns : lp.getDnsServers()) {
-            if (isOnLink(routes, dns)) {
-                newNeighborWatchList.put(dns, mNeighborWatchList.getOrDefault(dns, null));
-            }
-        }
-
-        mNeighborWatchList = newNeighborWatchList;
-        if (DBG) { Log.d(TAG, "watch: " + describeWatchList()); }
-    }
-
-    public void clearLinkProperties() {
-        mLinkProperties.clear();
-        mNeighborWatchList.clear();
-        if (DBG) { Log.d(TAG, "clear: " + describeWatchList()); }
-    }
-
-    private void handleNeighborLost(NeighborEvent event) {
-        final LinkProperties whatIfLp = new LinkProperties(mLinkProperties);
-
-        InetAddress ip = null;
-        for (Map.Entry<InetAddress, NeighborEvent> entry : mNeighborWatchList.entrySet()) {
-            // TODO: Consider using NeighborEvent#isValid() here; it's more
-            // strict but may interact badly if other entries are somehow in
-            // NUD_INCOMPLETE (say, during network attach).
-            if (entry.getValue().nudState != StructNdMsg.NUD_FAILED) continue;
-
-            ip = entry.getKey();
-            for (RouteInfo route : mLinkProperties.getRoutes()) {
-                if (ip.equals(route.getGateway())) {
-                    whatIfLp.removeRoute(route);
-                }
-            }
-
-            if (avoidingBadLinks() || !(ip instanceof Inet6Address)) {
-                // We should do this unconditionally, but alas we cannot: b/31827713.
-                whatIfLp.removeDnsServer(ip);
-            }
-        }
-
-        final boolean lostProvisioning =
-                (mLinkProperties.isIpv4Provisioned() && !whatIfLp.isIpv4Provisioned())
-                || (mLinkProperties.isIpv6Provisioned() && !whatIfLp.isIpv6Provisioned());
-
-        if (lostProvisioning) {
-            final String logMsg = "FAILURE: LOST_PROVISIONING, " + event;
-            Log.w(TAG, logMsg);
-            if (mCallback != null) {
-                // TODO: remove |ip| when the callback signature no longer has
-                // an InetAddress argument.
-                mCallback.notifyLost(ip, logMsg);
-            }
-        }
-        logNudFailed(lostProvisioning);
-    }
-
-    private boolean avoidingBadLinks() {
-        return !mUsingMultinetworkPolicyTracker || mCm.shouldAvoidBadWifi();
-    }
-
-    public void probeAll() {
-        final List<InetAddress> ipProbeList = new ArrayList<>(mNeighborWatchList.keySet());
-
-        if (!ipProbeList.isEmpty()) {
-            // Keep the CPU awake long enough to allow all ARP/ND
-            // probes a reasonable chance at success. See b/23197666.
-            //
-            // The wakelock we use is (by default) refcounted, and this version
-            // of acquire(timeout) queues a release message to keep acquisitions
-            // and releases balanced.
-            mDependencies.acquireWakeLock(getProbeWakeLockDuration());
-        }
-
-        for (InetAddress ip : ipProbeList) {
-            final int rval = IpNeighborMonitor.startKernelNeighborProbe(mInterfaceParams.index, ip);
-            mLog.log(String.format("put neighbor %s into NUD_PROBE state (rval=%d)",
-                     ip.getHostAddress(), rval));
-            logEvent(IpReachabilityEvent.PROBE, rval);
-        }
-        mLastProbeTimeMs = SystemClock.elapsedRealtime();
-    }
-
-    private static long getProbeWakeLockDuration() {
-        // Ideally, this would be computed by examining the values of:
-        //
-        //     /proc/sys/net/ipv[46]/neigh/<ifname>/ucast_solicit
-        //
-        // and:
-        //
-        //     /proc/sys/net/ipv[46]/neigh/<ifname>/retrans_time_ms
-        //
-        // For now, just make some assumptions.
-        final long numUnicastProbes = 3;
-        final long retransTimeMs = 1000;
-        final long gracePeriodMs = 500;
-        return (numUnicastProbes * retransTimeMs) + gracePeriodMs;
-    }
-
-    private void logEvent(int probeType, int errorCode) {
-        int eventType = probeType | (errorCode & 0xff);
-        mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
-    }
-
-    private void logNudFailed(boolean lostProvisioning) {
-        long duration = SystemClock.elapsedRealtime() - mLastProbeTimeMs;
-        boolean isFromProbe = (duration < getProbeWakeLockDuration());
-        int eventType = nudFailureEventType(isFromProbe, lostProvisioning);
-        mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType));
-    }
-
-    /**
-     * Returns the NUD failure event type code corresponding to the given conditions.
-     */
-    private static int nudFailureEventType(boolean isFromProbe, boolean isProvisioningLost) {
-        if (isFromProbe) {
-            return isProvisioningLost ? PROVISIONING_LOST : NUD_FAILED;
-        } else {
-            return isProvisioningLost ? PROVISIONING_LOST_ORGANIC : NUD_FAILED_ORGANIC;
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java b/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java
deleted file mode 100644
index 08c3f60..0000000
--- a/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.util;
-
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_UDP;
-
-import static com.android.server.util.NetworkStackConstants.ARP_HWTYPE_ETHER;
-import static com.android.server.util.NetworkStackConstants.ARP_PAYLOAD_LEN;
-import static com.android.server.util.NetworkStackConstants.ARP_REPLY;
-import static com.android.server.util.NetworkStackConstants.ARP_REQUEST;
-import static com.android.server.util.NetworkStackConstants.DHCP4_CLIENT_PORT;
-import static com.android.server.util.NetworkStackConstants.ETHER_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.ETHER_DST_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ETHER_HEADER_LEN;
-import static com.android.server.util.NetworkStackConstants.ETHER_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_ARP;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV4;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV6;
-import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_OFFSET;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MIN_LENGTH;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MTU;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION;
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV4_DST_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_FLAGS_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_FRAGMENT_MASK;
-import static com.android.server.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV4_IHL_MASK;
-import static com.android.server.util.NetworkStackConstants.IPV4_PROTOCOL_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV4_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV6_ADDR_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV6_HEADER_LEN;
-import static com.android.server.util.NetworkStackConstants.IPV6_PROTOCOL_OFFSET;
-import static com.android.server.util.NetworkStackConstants.IPV6_SRC_ADDR_OFFSET;
-import static com.android.server.util.NetworkStackConstants.UDP_HEADER_LEN;
-
-import android.net.MacAddress;
-import android.net.dhcp.DhcpPacket;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.StringJoiner;
-
-
-/**
- * Critical connectivity packet summarizing class.
- *
- * Outputs short descriptions of ARP, DHCPv4, and IPv6 RS/RA/NS/NA packets.
- *
- * @hide
- */
-public class ConnectivityPacketSummary {
-    private static final String TAG = ConnectivityPacketSummary.class.getSimpleName();
-
-    private final byte[] mHwAddr;
-    private final byte[] mBytes;
-    private final int mLength;
-    private final ByteBuffer mPacket;
-    private final String mSummary;
-
-    public static String summarize(MacAddress hwaddr, byte[] buffer) {
-        return summarize(hwaddr, buffer, buffer.length);
-    }
-
-    // Methods called herein perform some but by no means all error checking.
-    // They may throw runtime exceptions on malformed packets.
-    public static String summarize(MacAddress macAddr, byte[] buffer, int length) {
-        if ((macAddr == null) || (buffer == null)) return null;
-        length = Math.min(length, buffer.length);
-        return (new ConnectivityPacketSummary(macAddr, buffer, length)).toString();
-    }
-
-    private ConnectivityPacketSummary(MacAddress macAddr, byte[] buffer, int length) {
-        mHwAddr = macAddr.toByteArray();
-        mBytes = buffer;
-        mLength = Math.min(length, mBytes.length);
-        mPacket = ByteBuffer.wrap(mBytes, 0, mLength);
-        mPacket.order(ByteOrder.BIG_ENDIAN);
-
-        final StringJoiner sj = new StringJoiner(" ");
-        // TODO: support other link-layers, or even no link-layer header.
-        parseEther(sj);
-        mSummary = sj.toString();
-    }
-
-    public String toString() {
-        return mSummary;
-    }
-
-    private void parseEther(StringJoiner sj) {
-        if (mPacket.remaining() < ETHER_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(ETHER_SRC_ADDR_OFFSET);
-        final ByteBuffer srcMac = (ByteBuffer) mPacket.slice().limit(ETHER_ADDR_LEN);
-        sj.add(ByteBuffer.wrap(mHwAddr).equals(srcMac) ? "TX" : "RX");
-        sj.add(getMacAddressString(srcMac));
-
-        mPacket.position(ETHER_DST_ADDR_OFFSET);
-        final ByteBuffer dstMac = (ByteBuffer) mPacket.slice().limit(ETHER_ADDR_LEN);
-        sj.add(">").add(getMacAddressString(dstMac));
-
-        mPacket.position(ETHER_TYPE_OFFSET);
-        final int etherType = asUint(mPacket.getShort());
-        switch (etherType) {
-            case ETHER_TYPE_ARP:
-                sj.add("arp");
-                parseARP(sj);
-                break;
-            case ETHER_TYPE_IPV4:
-                sj.add("ipv4");
-                parseIPv4(sj);
-                break;
-            case ETHER_TYPE_IPV6:
-                sj.add("ipv6");
-                parseIPv6(sj);
-                break;
-            default:
-                // Unknown ether type.
-                sj.add("ethtype").add(asString(etherType));
-                break;
-        }
-    }
-
-    private void parseARP(StringJoiner sj) {
-        if (mPacket.remaining() < ARP_PAYLOAD_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        if (asUint(mPacket.getShort()) != ARP_HWTYPE_ETHER ||
-            asUint(mPacket.getShort()) != ETHER_TYPE_IPV4 ||
-            asUint(mPacket.get()) != ETHER_ADDR_LEN ||
-            asUint(mPacket.get()) != IPV4_ADDR_LEN) {
-            sj.add("unexpected header");
-            return;
-        }
-
-        final int opCode = asUint(mPacket.getShort());
-
-        final String senderHwAddr = getMacAddressString(mPacket);
-        final String senderIPv4 = getIPv4AddressString(mPacket);
-        getMacAddressString(mPacket);  // target hardware address, unused
-        final String targetIPv4 = getIPv4AddressString(mPacket);
-
-        if (opCode == ARP_REQUEST) {
-            sj.add("who-has").add(targetIPv4);
-        } else if (opCode == ARP_REPLY) {
-            sj.add("reply").add(senderIPv4).add(senderHwAddr);
-        } else {
-            sj.add("unknown opcode").add(asString(opCode));
-        }
-    }
-
-    private void parseIPv4(StringJoiner sj) {
-        if (!mPacket.hasRemaining()) {
-            sj.add("runt");
-            return;
-        }
-
-        final int startOfIpLayer = mPacket.position();
-        final int ipv4HeaderLength = (mPacket.get(startOfIpLayer) & IPV4_IHL_MASK) * 4;
-        if (mPacket.remaining() < ipv4HeaderLength ||
-            mPacket.remaining() < IPV4_HEADER_MIN_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-        final int startOfTransportLayer = startOfIpLayer + ipv4HeaderLength;
-
-        mPacket.position(startOfIpLayer + IPV4_FLAGS_OFFSET);
-        final int flagsAndFragment = asUint(mPacket.getShort());
-        final boolean isFragment = (flagsAndFragment & IPV4_FRAGMENT_MASK) != 0;
-
-        mPacket.position(startOfIpLayer + IPV4_PROTOCOL_OFFSET);
-        final int protocol = asUint(mPacket.get());
-
-        mPacket.position(startOfIpLayer + IPV4_SRC_ADDR_OFFSET);
-        final String srcAddr = getIPv4AddressString(mPacket);
-
-        mPacket.position(startOfIpLayer + IPV4_DST_ADDR_OFFSET);
-        final String dstAddr = getIPv4AddressString(mPacket);
-
-        sj.add(srcAddr).add(">").add(dstAddr);
-
-        mPacket.position(startOfTransportLayer);
-        if (protocol == IPPROTO_UDP) {
-            sj.add("udp");
-            if (isFragment) sj.add("fragment");
-            else parseUDP(sj);
-        } else {
-            sj.add("proto").add(asString(protocol));
-            if (isFragment) sj.add("fragment");
-        }
-    }
-
-    private void parseIPv6(StringJoiner sj) {
-        if (mPacket.remaining() < IPV6_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int startOfIpLayer = mPacket.position();
-
-        mPacket.position(startOfIpLayer + IPV6_PROTOCOL_OFFSET);
-        final int protocol = asUint(mPacket.get());
-
-        mPacket.position(startOfIpLayer + IPV6_SRC_ADDR_OFFSET);
-        final String srcAddr = getIPv6AddressString(mPacket);
-        final String dstAddr = getIPv6AddressString(mPacket);
-
-        sj.add(srcAddr).add(">").add(dstAddr);
-
-        mPacket.position(startOfIpLayer + IPV6_HEADER_LEN);
-        if (protocol == IPPROTO_ICMPV6) {
-            sj.add("icmp6");
-            parseICMPv6(sj);
-        } else {
-            sj.add("proto").add(asString(protocol));
-        }
-    }
-
-    private void parseICMPv6(StringJoiner sj) {
-        if (mPacket.remaining() < ICMPV6_HEADER_MIN_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int icmp6Type = asUint(mPacket.get());
-        final int icmp6Code = asUint(mPacket.get());
-        mPacket.getShort();  // checksum, unused
-
-        switch (icmp6Type) {
-            case ICMPV6_ROUTER_SOLICITATION:
-                sj.add("rs");
-                parseICMPv6RouterSolicitation(sj);
-                break;
-            case ICMPV6_ROUTER_ADVERTISEMENT:
-                sj.add("ra");
-                parseICMPv6RouterAdvertisement(sj);
-                break;
-            case ICMPV6_NEIGHBOR_SOLICITATION:
-                sj.add("ns");
-                parseICMPv6NeighborMessage(sj);
-                break;
-            case ICMPV6_NEIGHBOR_ADVERTISEMENT:
-                sj.add("na");
-                parseICMPv6NeighborMessage(sj);
-                break;
-            default:
-                sj.add("type").add(asString(icmp6Type));
-                sj.add("code").add(asString(icmp6Code));
-                break;
-        }
-    }
-
-    private void parseICMPv6RouterSolicitation(StringJoiner sj) {
-        final int RESERVED = 4;
-        if (mPacket.remaining() < RESERVED) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + RESERVED);
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6RouterAdvertisement(StringJoiner sj) {
-        final int FLAGS_AND_TIMERS = 3 * 4;
-        if (mPacket.remaining() < FLAGS_AND_TIMERS) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + FLAGS_AND_TIMERS);
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6NeighborMessage(StringJoiner sj) {
-        final int RESERVED = 4;
-        final int minReq = RESERVED + IPV6_ADDR_LEN;
-        if (mPacket.remaining() < minReq) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        mPacket.position(mPacket.position() + RESERVED);
-        sj.add(getIPv6AddressString(mPacket));
-        parseICMPv6NeighborDiscoveryOptions(sj);
-    }
-
-    private void parseICMPv6NeighborDiscoveryOptions(StringJoiner sj) {
-        // All ND options are TLV, where T is one byte and L is one byte equal
-        // to the length of T + L + V in units of 8 octets.
-        while (mPacket.remaining() >= ICMPV6_ND_OPTION_MIN_LENGTH) {
-            final int ndType = asUint(mPacket.get());
-            final int ndLength = asUint(mPacket.get());
-            final int ndBytes = ndLength * ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR - 2;
-            if (ndBytes < 0 || ndBytes > mPacket.remaining()) {
-                sj.add("<malformed>");
-                break;
-            }
-            final int position = mPacket.position();
-
-            switch (ndType) {
-                    case ICMPV6_ND_OPTION_SLLA:
-                        sj.add("slla");
-                        sj.add(getMacAddressString(mPacket));
-                        break;
-                    case ICMPV6_ND_OPTION_TLLA:
-                        sj.add("tlla");
-                        sj.add(getMacAddressString(mPacket));
-                        break;
-                    case ICMPV6_ND_OPTION_MTU:
-                        sj.add("mtu");
-                        final short reserved = mPacket.getShort();
-                        sj.add(asString(mPacket.getInt()));
-                        break;
-                    default:
-                        // Skip.
-                        break;
-            }
-
-            mPacket.position(position + ndBytes);
-        }
-    }
-
-    private void parseUDP(StringJoiner sj) {
-        if (mPacket.remaining() < UDP_HEADER_LEN) {
-            sj.add("runt:").add(asString(mPacket.remaining()));
-            return;
-        }
-
-        final int previous = mPacket.position();
-        final int srcPort = asUint(mPacket.getShort());
-        final int dstPort = asUint(mPacket.getShort());
-        sj.add(asString(srcPort)).add(">").add(asString(dstPort));
-
-        mPacket.position(previous + UDP_HEADER_LEN);
-        if (srcPort == DHCP4_CLIENT_PORT || dstPort == DHCP4_CLIENT_PORT) {
-            sj.add("dhcp4");
-            parseDHCPv4(sj);
-        }
-    }
-
-    private void parseDHCPv4(StringJoiner sj) {
-        final DhcpPacket dhcpPacket;
-        try {
-            dhcpPacket = DhcpPacket.decodeFullPacket(mBytes, mLength, DhcpPacket.ENCAP_L2);
-            sj.add(dhcpPacket.toString());
-        } catch (DhcpPacket.ParseException e) {
-            sj.add("parse error: " + e);
-        }
-    }
-
-    private static String getIPv4AddressString(ByteBuffer ipv4) {
-        return getIpAddressString(ipv4, IPV4_ADDR_LEN);
-    }
-
-    private static String getIPv6AddressString(ByteBuffer ipv6) {
-        return getIpAddressString(ipv6, IPV6_ADDR_LEN);
-    }
-
-    private static String getIpAddressString(ByteBuffer ip, int byteLength) {
-        if (ip == null || ip.remaining() < byteLength) return "invalid";
-
-        byte[] bytes = new byte[byteLength];
-        ip.get(bytes, 0, byteLength);
-        try {
-            InetAddress addr = InetAddress.getByAddress(bytes);
-            return addr.getHostAddress();
-        } catch (UnknownHostException uhe) {
-            return "unknown";
-        }
-    }
-
-    private static String getMacAddressString(ByteBuffer mac) {
-        if (mac == null || mac.remaining() < ETHER_ADDR_LEN) return "invalid";
-
-        byte[] bytes = new byte[ETHER_ADDR_LEN];
-        mac.get(bytes, 0, bytes.length);
-        Object[] printableBytes = new Object[bytes.length];
-        int i = 0;
-        for (byte b : bytes) printableBytes[i++] = new Byte(b);
-
-        final String MAC48_FORMAT = "%02x:%02x:%02x:%02x:%02x:%02x";
-        return String.format(MAC48_FORMAT, printableBytes);
-    }
-
-    /**
-     * Convenience method to convert an int to a String.
-     */
-    public static String asString(int i) {
-        return Integer.toString(i);
-    }
-
-    /**
-     * Convenience method to read a byte as an unsigned int.
-     */
-    public static int asUint(byte b) {
-        return (b & 0xff);
-    }
-
-    /**
-     * Convenience method to read a short as an unsigned int.
-     */
-    public static int asUint(short s) {
-        return (s & 0xffff);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/DataStallUtils.java b/packages/NetworkStack/src/android/net/util/DataStallUtils.java
deleted file mode 100644
index b6dbeb1..0000000
--- a/packages/NetworkStack/src/android/net/util/DataStallUtils.java
+++ /dev/null
@@ -1,72 +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.util;
-
-/**
- * Collection of utilities for data stall.
- */
-public class DataStallUtils {
-    /**
-     * Detect data stall via using dns timeout counts.
-     */
-    public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1;
-    // Default configuration values for data stall detection.
-    public static final int DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = 5;
-    public static final int DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS = 60 * 1000;
-    public static final int DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS = 30 * 60 * 1000;
-    /**
-     * The threshold value for the number of consecutive dns timeout events received to be a
-     * signal of data stall. The number of consecutive timeouts needs to be {@code >=} this
-     * threshold to be considered a data stall. Set the value to {@code <= 0} to disable. Note
-     * that the value should be {@code > 0} if the DNS data stall detection is enabled.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD =
-            "data_stall_consecutive_dns_timeout_threshold";
-
-    /**
-     * The minimal time interval in milliseconds for data stall reevaluation.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL =
-            "data_stall_min_evaluate_interval";
-
-    /**
-     * DNS timeouts older than this timeout (in milliseconds) are not considered for detecting
-     * a data stall.
-     *
-     */
-    public static final String CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD =
-            "data_stall_valid_dns_time_threshold";
-
-    /**
-     * Which data stall detection signal to use. This is a bitmask constructed by bitwise-or-ing
-     * (i.e. {@code |}) the DATA_STALL_EVALUATION_TYPE_* values.
-     *
-     * Type: int
-     * Valid values:
-     *   {@link #DATA_STALL_EVALUATION_TYPE_DNS} : Use dns as a signal.
-     */
-    public static final String CONFIG_DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
-    public static final int DEFAULT_DATA_STALL_EVALUATION_TYPES = DATA_STALL_EVALUATION_TYPE_DNS;
-    // The default number of DNS events kept of the log kept for dns signal evaluation. Each event
-    // is represented by a {@link com.android.server.connectivity.NetworkMonitor#DnsResult} objects.
-    // It's also the size of array of {@link com.android.server.connectivity.nano.DnsEvent} kept in
-    // metrics. Note that increasing the size may cause statsd log buffer bust. Need to check the
-    // design in statsd when you try to increase the size.
-    public static final int DEFAULT_DNS_LOG_SIZE = 20;
-}
diff --git a/packages/NetworkStack/src/android/net/util/FdEventsReader.java b/packages/NetworkStack/src/android/net/util/FdEventsReader.java
deleted file mode 100644
index 1380ea7..0000000
--- a/packages/NetworkStack/src/android/net/util/FdEventsReader.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.util;
-
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.system.ErrnoException;
-import android.system.OsConstants;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-
-/**
- * This class encapsulates the mechanics of registering a file descriptor
- * with a thread's Looper and handling read events (and errors).
- *
- * Subclasses MUST implement createFd() and SHOULD override handlePacket(). They MAY override
- * onStop() and onStart().
- *
- * Subclasses can expect a call life-cycle like the following:
- *
- *     [1] when a client calls start(), createFd() is called, followed by the onStart() hook if all
- *         goes well. Implementations may override onStart() for additional initialization.
- *
- *     [2] yield, waiting for read event or error notification:
- *
- *             [a] readPacket() && handlePacket()
- *
- *             [b] if (no error):
- *                     goto 2
- *                 else:
- *                     goto 3
- *
- *     [3] when a client calls stop(), the onStop() hook is called (unless already stopped or never
- *         started). Implementations may override onStop() for additional cleanup.
- *
- * The packet receive buffer is recycled on every read call, so subclasses
- * should make any copies they would like inside their handlePacket()
- * implementation.
- *
- * All public methods MUST only be called from the same thread with which
- * the Handler constructor argument is associated.
- *
- * @param <BufferType> the type of the buffer used to read data.
- * @hide
- */
-public abstract class FdEventsReader<BufferType> {
-    private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
-    private static final int UNREGISTER_THIS_FD = 0;
-
-    @NonNull
-    private final Handler mHandler;
-    @NonNull
-    private final MessageQueue mQueue;
-    @NonNull
-    private final BufferType mBuffer;
-    @Nullable
-    private FileDescriptor mFd;
-    private long mPacketsReceived;
-
-    protected static void closeFd(FileDescriptor fd) {
-        try {
-            SocketUtils.closeSocket(fd);
-        } catch (IOException ignored) {
-        }
-    }
-
-    protected FdEventsReader(@NonNull Handler h, @NonNull BufferType buffer) {
-        mHandler = h;
-        mQueue = mHandler.getLooper().getQueue();
-        mBuffer = buffer;
-    }
-
-    /** Start this FdEventsReader. */
-    public void start() {
-        if (onCorrectThread()) {
-            createAndRegisterFd();
-        } else {
-            mHandler.post(() -> {
-                logError("start() called from off-thread", null);
-                createAndRegisterFd();
-            });
-        }
-    }
-
-    /** Stop this FdEventsReader and destroy the file descriptor. */
-    public void stop() {
-        if (onCorrectThread()) {
-            unregisterAndDestroyFd();
-        } else {
-            mHandler.post(() -> {
-                logError("stop() called from off-thread", null);
-                unregisterAndDestroyFd();
-            });
-        }
-    }
-
-    @NonNull
-    public Handler getHandler() {
-        return mHandler;
-    }
-
-    protected abstract int recvBufSize(@NonNull BufferType buffer);
-
-    /** Returns the size of the receive buffer. */
-    public int recvBufSize() {
-        return recvBufSize(mBuffer);
-    }
-
-    /**
-     * Get the number of successful calls to {@link #readPacket(FileDescriptor, Object)}.
-     *
-     * <p>A call was successful if {@link #readPacket(FileDescriptor, Object)} returned a value > 0.
-     */
-    public final long numPacketsReceived() {
-        return mPacketsReceived;
-    }
-
-    /**
-     * Subclasses MUST create the listening socket here, including setting all desired socket
-     * options, interface or address/port binding, etc. The socket MUST be created nonblocking.
-     */
-    @Nullable
-    protected abstract FileDescriptor createFd();
-
-    /**
-     * Implementations MUST return the bytes read or throw an Exception.
-     *
-     * <p>The caller may throw a {@link ErrnoException} with {@link OsConstants#EAGAIN} or
-     * {@link OsConstants#EINTR}, in which case {@link FdEventsReader} will ignore the buffer
-     * contents and respectively wait for further input or retry the read immediately. For all other
-     * exceptions, the {@link FdEventsReader} will be stopped with no more interactions with this
-     * method.
-     */
-    protected abstract int readPacket(@NonNull FileDescriptor fd, @NonNull BufferType buffer)
-            throws Exception;
-
-    /**
-     * Called by the main loop for every packet.  Any desired copies of
-     * |recvbuf| should be made in here, as the underlying byte array is
-     * reused across all reads.
-     */
-    protected void handlePacket(@NonNull BufferType recvbuf, int length) {}
-
-    /**
-     * Called by the main loop to log errors.  In some cases |e| may be null.
-     */
-    protected void logError(@NonNull String msg, @Nullable Exception e) {}
-
-    /**
-     * Called by start(), if successful, just prior to returning.
-     */
-    protected void onStart() {}
-
-    /**
-     * Called by stop() just prior to returning.
-     */
-    protected void onStop() {}
-
-    private void createAndRegisterFd() {
-        if (mFd != null) return;
-
-        try {
-            mFd = createFd();
-        } catch (Exception e) {
-            logError("Failed to create socket: ", e);
-            closeFd(mFd);
-            mFd = null;
-        }
-
-        if (mFd == null) return;
-
-        mQueue.addOnFileDescriptorEventListener(
-                mFd,
-                FD_EVENTS,
-                (fd, events) -> {
-                    // Always call handleInput() so read/recvfrom are given
-                    // a proper chance to encounter a meaningful errno and
-                    // perhaps log a useful error message.
-                    if (!isRunning() || !handleInput()) {
-                        unregisterAndDestroyFd();
-                        return UNREGISTER_THIS_FD;
-                    }
-                    return FD_EVENTS;
-                });
-        onStart();
-    }
-
-    private boolean isRunning() {
-        return (mFd != null) && mFd.valid();
-    }
-
-    // Keep trying to read until we get EAGAIN/EWOULDBLOCK or some fatal error.
-    private boolean handleInput() {
-        while (isRunning()) {
-            final int bytesRead;
-
-            try {
-                bytesRead = readPacket(mFd, mBuffer);
-                if (bytesRead < 1) {
-                    if (isRunning()) logError("Socket closed, exiting", null);
-                    break;
-                }
-                mPacketsReceived++;
-            } catch (ErrnoException e) {
-                if (e.errno == OsConstants.EAGAIN) {
-                    // We've read everything there is to read this time around.
-                    return true;
-                } else if (e.errno == OsConstants.EINTR) {
-                    continue;
-                } else {
-                    if (isRunning()) logError("readPacket error: ", e);
-                    break;
-                }
-            } catch (Exception e) {
-                if (isRunning()) logError("readPacket error: ", e);
-                break;
-            }
-
-            try {
-                handlePacket(mBuffer, bytesRead);
-            } catch (Exception e) {
-                logError("handlePacket error: ", e);
-                break;
-            }
-        }
-
-        return false;
-    }
-
-    private void unregisterAndDestroyFd() {
-        if (mFd == null) return;
-
-        mQueue.removeOnFileDescriptorEventListener(mFd);
-        closeFd(mFd);
-        mFd = null;
-        onStop();
-    }
-
-    private boolean onCorrectThread() {
-        return (mHandler.getLooper() == Looper.myLooper());
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java b/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
deleted file mode 100644
index 9bf1b96..0000000
--- a/packages/NetworkStack/src/android/net/util/NetworkStackUtils.java
+++ /dev/null
@@ -1,242 +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.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.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.util.List;
-import java.util.function.Predicate;
-
-/**
- * Collection of utilities for the network stack.
- */
-public class NetworkStackUtils {
-    // TODO: Refer to DeviceConfig definition.
-    public static final String NAMESPACE_CONNECTIVITY = "connectivity";
-
-    /**
-     * A list of captive portal detection specifications used in addition to the fallback URLs.
-     * Each spec has the format url@@/@@statusCodeRegex@@/@@contentRegex. Specs are separated
-     * by "@@,@@".
-     */
-    public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS =
-            "captive_portal_fallback_probe_specs";
-
-    /**
-     * A comma separated list of URLs used for captive portal detection in addition to the
-     * fallback HTTP url associated with the CAPTIVE_PORTAL_FALLBACK_URL settings.
-     */
-    public static final String CAPTIVE_PORTAL_OTHER_FALLBACK_URLS =
-            "captive_portal_other_fallback_urls";
-
-    /**
-     * Which User-Agent string to use in the header of the captive portal detection probes.
-     * The User-Agent field is unset when this setting has no value (HttpUrlConnection default).
-     */
-    public static final String CAPTIVE_PORTAL_USER_AGENT = "captive_portal_user_agent";
-
-    /**
-     * Whether to use HTTPS for network validation. This is enabled by default and the setting
-     * needs to be set to 0 to disable it. This setting is a misnomer because captive portals
-     * don't actually use HTTPS, but it's consistent with the other settings.
-     */
-    public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
-
-    /**
-     * The URL used for HTTPS captive portal detection upon a new connection.
-     * A 204 response code from the server is used for validation.
-     */
-    public static final String CAPTIVE_PORTAL_HTTPS_URL = "captive_portal_https_url";
-
-    /**
-     * The URL used for HTTP captive portal detection upon a new connection.
-     * A 204 response code from the server is used for validation.
-     */
-    public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url";
-
-    /**
-     * The URL used for fallback HTTP captive portal detection when previous HTTP
-     * and HTTPS captive portal detection attemps did not return a conclusive answer.
-     */
-    public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
-
-    /**
-     * What to do when connecting a network that presents a captive portal.
-     * Must be one of the CAPTIVE_PORTAL_MODE_* constants above.
-     *
-     * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
-     */
-    public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
-
-    /**
-     * Don't attempt to detect captive portals.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
-
-    /**
-     * When detecting a captive portal, display a notification that
-     * prompts the user to sign in.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
-
-    /**
-     * When detecting a captive portal, immediately disconnect from the
-     * network and do not reconnect to that network in the future.
-     */
-    public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
-
-    static {
-        System.loadLibrary("networkstackutilsjni");
-    }
-
-    /**
-     * @return True if the array is null or 0-length.
-     */
-    public static <T> boolean isEmpty(T[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * Close a socket, ignoring any exception while closing.
-     */
-    public static void closeSocketQuietly(FileDescriptor fd) {
-        try {
-            SocketUtils.closeSocket(fd);
-        } catch (IOException ignored) {
-        }
-    }
-
-    /**
-     * Returns an int array from the given Integer list.
-     */
-    public static int[] convertToIntArray(@NonNull List<Integer> list) {
-        int[] array = new int[list.size()];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        return array;
-    }
-
-    /**
-     * Returns a long array from the given long list.
-     */
-    public static long[] convertToLongArray(@NonNull List<Long> list) {
-        long[] array = new long[list.size()];
-        for (int i = 0; i < list.size(); i++) {
-            array[i] = list.get(i);
-        }
-        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 valid 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;
-    }
-
-    /**
-     * 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.
-     */
-    public static int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
-            int defaultValue) {
-        String value = getDeviceConfigProperty(namespace, name, null /* defaultValue */);
-        try {
-            return (value != null) ? Integer.parseInt(value) : defaultValue;
-        } catch (NumberFormatException e) {
-            return defaultValue;
-        }
-    }
-
-    /**
-     * Attaches a socket filter that accepts DHCP packets to the given socket.
-     */
-    public static native void attachDhcpFilter(FileDescriptor fd) throws SocketException;
-
-    /**
-     * Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket.
-     * @param fd the socket's {@link FileDescriptor}.
-     * @param packetType the hardware address type, one of ARPHRD_*.
-     */
-    public static native void attachRaFilter(FileDescriptor fd, int packetType)
-            throws SocketException;
-
-    /**
-     * Attaches a socket filter that accepts L2-L4 signaling traffic required for IP connectivity.
-     *
-     * This includes: all ARP, ICMPv6 RS/RA/NS/NA messages, and DHCPv4 exchanges.
-     *
-     * @param fd the socket's {@link FileDescriptor}.
-     * @param packetType the hardware address type, one of ARPHRD_*.
-     */
-    public static native void attachControlPacketFilter(FileDescriptor fd, int packetType)
-            throws SocketException;
-
-    /**
-     * Add an entry into the ARP cache.
-     */
-    public static void addArpEntry(Inet4Address ipv4Addr, android.net.MacAddress ethAddr,
-            String ifname, FileDescriptor fd) throws IOException {
-        addArpEntry(ethAddr.toByteArray(), ipv4Addr.getAddress(), ifname, fd);
-    }
-
-    private static native void addArpEntry(byte[] ethAddr, byte[] netAddr, String ifname,
-            FileDescriptor fd) throws IOException;
-
-    /**
-     * Return IP address and port in a string format.
-     */
-    public static String addressAndPortToString(InetAddress address, int port) {
-        return String.format(
-                (address instanceof Inet6Address) ? "[%s]:%d" : "%s:%d",
-                        address.getHostAddress(), port);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/PacketReader.java b/packages/NetworkStack/src/android/net/util/PacketReader.java
deleted file mode 100644
index 4aec6b6..0000000
--- a/packages/NetworkStack/src/android/net/util/PacketReader.java
+++ /dev/null
@@ -1,61 +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.net.util;
-
-import static java.lang.Math.max;
-
-import android.os.Handler;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-
-/**
- * Specialization of {@link FdEventsReader} that reads packets into a byte array.
- *
- * TODO: rename this class to something more correctly descriptive (something
- * like [or less horrible than] FdReadEventsHandler?).
- *
- * @hide
- */
-public abstract class PacketReader extends FdEventsReader<byte[]> {
-
-    public static final int DEFAULT_RECV_BUF_SIZE = 2 * 1024;
-
-    protected PacketReader(Handler h) {
-        this(h, DEFAULT_RECV_BUF_SIZE);
-    }
-
-    protected PacketReader(Handler h, int recvBufSize) {
-        super(h, new byte[max(recvBufSize, DEFAULT_RECV_BUF_SIZE)]);
-    }
-
-    @Override
-    protected final int recvBufSize(byte[] buffer) {
-        return buffer.length;
-    }
-
-    /**
-     * Subclasses MAY override this to change the default read() implementation
-     * in favour of, say, recvfrom().
-     *
-     * Implementations MUST return the bytes read or throw an Exception.
-     */
-    @Override
-    protected int readPacket(FileDescriptor fd, byte[] packetBuffer) throws Exception {
-        return Os.read(fd, packetBuffer, 0, packetBuffer.length);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/SharedLog.java b/packages/NetworkStack/src/android/net/util/SharedLog.java
deleted file mode 100644
index 4fabf10..0000000
--- a/packages/NetworkStack/src/android/net/util/SharedLog.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.StringJoiner;
-
-
-/**
- * Class to centralize logging functionality for tethering.
- *
- * All access to class methods other than dump() must be on the same thread.
- *
- * @hide
- */
-public class SharedLog {
-    private static final int DEFAULT_MAX_RECORDS = 500;
-    private static final String COMPONENT_DELIMITER = ".";
-
-    private enum Category {
-        NONE,
-        ERROR,
-        MARK,
-        WARN,
-    };
-
-    private final LocalLog mLocalLog;
-    // The tag to use for output to the system log. This is not output to the
-    // LocalLog because that would be redundant.
-    private final String mTag;
-    // The component (or subcomponent) of a system that is sharing this log.
-    // This can grow in depth if components call forSubComponent() to obtain
-    // their SharedLog instance. The tag is not included in the component for
-    // brevity.
-    private final String mComponent;
-
-    public SharedLog(String tag) {
-        this(DEFAULT_MAX_RECORDS, tag);
-    }
-
-    public SharedLog(int maxRecords, String tag) {
-        this(new LocalLog(maxRecords), tag, tag);
-    }
-
-    private SharedLog(LocalLog localLog, String tag, String component) {
-        mLocalLog = localLog;
-        mTag = tag;
-        mComponent = component;
-    }
-
-    public String getTag() {
-        return mTag;
-    }
-
-    /**
-     * Create a SharedLog based on this log with an additional component prefix on each logged line.
-     */
-    public SharedLog forSubComponent(String component) {
-        if (!isRootLogInstance()) {
-            component = mComponent + COMPONENT_DELIMITER + component;
-        }
-        return new SharedLog(mLocalLog, mTag, component);
-    }
-
-    /**
-     * Dump the contents of this log.
-     *
-     * <p>This method may be called on any thread.
-     */
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-        mLocalLog.readOnlyLocalLog().dump(fd, writer, args);
-    }
-
-    //////
-    // Methods that both log an entry and emit it to the system log.
-    //////
-
-    /**
-     * Log an error due to an exception. This does not include the exception stacktrace.
-     *
-     * <p>The log entry will be also added to the system log.
-     * @see #e(String, Throwable)
-     */
-    public void e(Exception e) {
-        Log.e(mTag, record(Category.ERROR, e.toString()));
-    }
-
-    /**
-     * Log an error message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void e(String msg) {
-        Log.e(mTag, record(Category.ERROR, msg));
-    }
-
-    /**
-     * Log an error due to an exception, with the exception stacktrace if provided.
-     *
-     * <p>The error and exception message appear in the shared log, but the stacktrace is only
-     * logged in general log output (logcat). The log entry will be also added to the system log.
-     */
-    public void e(@NonNull String msg, @Nullable Throwable exception) {
-        if (exception == null) {
-            e(msg);
-            return;
-        }
-        Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception);
-    }
-
-    /**
-     * Log an informational message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void i(String msg) {
-        Log.i(mTag, record(Category.NONE, msg));
-    }
-
-    /**
-     * Log a warning message.
-     *
-     * <p>The log entry will be also added to the system log.
-     */
-    public void w(String msg) {
-        Log.w(mTag, record(Category.WARN, msg));
-    }
-
-    //////
-    // Methods that only log an entry (and do NOT emit to the system log).
-    //////
-
-    /**
-     * Log a general message to be only included in the in-memory log.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     */
-    public void log(String msg) {
-        record(Category.NONE, msg);
-    }
-
-    /**
-     * Log a general, formatted message to be only included in the in-memory log.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     * @see String#format(String, Object...)
-     */
-    public void logf(String fmt, Object... args) {
-        log(String.format(fmt, args));
-    }
-
-    /**
-     * Log a message with MARK level.
-     *
-     * <p>The log entry will *not* be added to the system log.
-     */
-    public void mark(String msg) {
-        record(Category.MARK, msg);
-    }
-
-    private String record(Category category, String msg) {
-        final String entry = logLine(category, msg);
-        mLocalLog.log(entry);
-        return entry;
-    }
-
-    private String logLine(Category category, String msg) {
-        final StringJoiner sj = new StringJoiner(" ");
-        if (!isRootLogInstance()) sj.add("[" + mComponent + "]");
-        if (category != Category.NONE) sj.add(category.toString());
-        return sj.add(msg).toString();
-    }
-
-    // Check whether this SharedLog instance is nominally the top level in
-    // a potential hierarchy of shared logs (the root of a tree),
-    // or is a subcomponent within the hierarchy.
-    private boolean isRootLogInstance() {
-        return TextUtils.isEmpty(mComponent) || mComponent.equals(mTag);
-    }
-}
diff --git a/packages/NetworkStack/src/android/net/util/Stopwatch.java b/packages/NetworkStack/src/android/net/util/Stopwatch.java
deleted file mode 100644
index c316699..0000000
--- a/packages/NetworkStack/src/android/net/util/Stopwatch.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.util;
-
-import android.os.SystemClock;
-
-
-/**
- * @hide
- */
-public class Stopwatch {
-    private long mStartTimeMs;
-    private long mStopTimeMs;
-
-    public boolean isStarted() {
-        return (mStartTimeMs > 0);
-    }
-
-    public boolean isStopped() {
-        return (mStopTimeMs > 0);
-    }
-
-    public boolean isRunning() {
-        return (isStarted() && !isStopped());
-    }
-
-    /**
-     * Start the Stopwatch.
-     */
-    public Stopwatch start() {
-        if (!isStarted()) {
-            mStartTimeMs = SystemClock.elapsedRealtime();
-        }
-        return this;
-    }
-
-    /**
-     * Stop the Stopwatch.
-     * @return the total time recorded, in milliseconds, or 0 if not started.
-     */
-    public long stop() {
-        if (isRunning()) {
-            mStopTimeMs = SystemClock.elapsedRealtime();
-        }
-        // Return either the delta after having stopped, or 0.
-        return (mStopTimeMs - mStartTimeMs);
-    }
-
-    /**
-     * Return the total time recorded to date, in milliseconds.
-     * If the Stopwatch is not running, returns the same value as stop(),
-     * i.e. either the total time recorded before stopping or 0.
-     */
-    public long lap() {
-        if (isRunning()) {
-            return (SystemClock.elapsedRealtime() - mStartTimeMs);
-        } else {
-            return stop();
-        }
-    }
-
-    /**
-     * Reset the Stopwatch. It will be stopped when this method returns.
-     */
-    public void reset() {
-        mStartTimeMs = 0;
-        mStopTimeMs = 0;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
deleted file mode 100644
index 2523ecd..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallDetectionStats.java
+++ /dev/null
@@ -1,228 +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.networkstack.metrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.util.NetworkStackUtils;
-import android.net.wifi.WifiInfo;
-
-import com.android.internal.util.HexDump;
-import com.android.server.connectivity.nano.CellularData;
-import com.android.server.connectivity.nano.DataStallEventProto;
-import com.android.server.connectivity.nano.DnsEvent;
-import com.android.server.connectivity.nano.WifiData;
-
-import com.google.protobuf.nano.MessageNano;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Class to record the stats of detection level information for data stall.
- *
- * @hide
- */
-public final class DataStallDetectionStats {
-    private static final int UNKNOWN_SIGNAL_STRENGTH = -1;
-    @NonNull
-    final byte[] mCellularInfo;
-    @NonNull
-    final byte[] mWifiInfo;
-    @NonNull
-    final byte[] mDns;
-    final int mEvaluationType;
-    final int mNetworkType;
-
-    public DataStallDetectionStats(@Nullable byte[] cell, @Nullable byte[] wifi,
-                @NonNull int[] returnCode, @NonNull long[] dnsTime, int evalType, int netType) {
-        mCellularInfo = emptyCellDataIfNull(cell);
-        mWifiInfo = emptyWifiInfoIfNull(wifi);
-
-        DnsEvent dns = new DnsEvent();
-        dns.dnsReturnCode = returnCode;
-        dns.dnsTime = dnsTime;
-        mDns = MessageNano.toByteArray(dns);
-        mEvaluationType = evalType;
-        mNetworkType = netType;
-    }
-
-    private byte[] emptyCellDataIfNull(@Nullable byte[] cell) {
-        if (cell != null) return cell;
-
-        CellularData data  = new CellularData();
-        data.ratType = DataStallEventProto.RADIO_TECHNOLOGY_UNKNOWN;
-        data.networkMccmnc = "";
-        data.simMccmnc = "";
-        data.signalStrength = UNKNOWN_SIGNAL_STRENGTH;
-        return MessageNano.toByteArray(data);
-    }
-
-    private byte[] emptyWifiInfoIfNull(@Nullable byte[] wifi) {
-        if (wifi != null) return wifi;
-
-        WifiData data = new WifiData();
-        data.wifiBand = DataStallEventProto.AP_BAND_UNKNOWN;
-        data.signalStrength = UNKNOWN_SIGNAL_STRENGTH;
-        return MessageNano.toByteArray(data);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("type: ").append(mNetworkType)
-          .append(", evaluation type: ")
-          .append(mEvaluationType)
-          .append(", wifi info: ")
-          .append(HexDump.toHexString(mWifiInfo))
-          .append(", cell info: ")
-          .append(HexDump.toHexString(mCellularInfo))
-          .append(", dns: ")
-          .append(HexDump.toHexString(mDns));
-        return sb.toString();
-    }
-
-    @Override
-    public boolean equals(@Nullable final Object o) {
-        if (!(o instanceof DataStallDetectionStats)) return false;
-        final DataStallDetectionStats other = (DataStallDetectionStats) o;
-        return (mNetworkType == other.mNetworkType)
-            && (mEvaluationType == other.mEvaluationType)
-            && Arrays.equals(mWifiInfo, other.mWifiInfo)
-            && Arrays.equals(mCellularInfo, other.mCellularInfo)
-            && Arrays.equals(mDns, other.mDns);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mNetworkType, mEvaluationType, mWifiInfo, mCellularInfo, mDns);
-    }
-
-    /**
-     * Utility to create an instance of {@Link DataStallDetectionStats}
-     *
-     * @hide
-     */
-    public static class Builder {
-        @Nullable
-        private byte[] mCellularInfo;
-        @Nullable
-        private byte[] mWifiInfo;
-        @NonNull
-        private final List<Integer> mDnsReturnCode = new ArrayList<Integer>();
-        @NonNull
-        private final List<Long> mDnsTimeStamp = new ArrayList<Long>();
-        private int mEvaluationType;
-        private int mNetworkType;
-
-        /**
-         * Add a dns event into Builder.
-         *
-         * @param code the return code of the dns event.
-         * @param timeMs the elapsedRealtime in ms that the the dns event was received from netd.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder addDnsEvent(int code, long timeMs) {
-            mDnsReturnCode.add(code);
-            mDnsTimeStamp.add(timeMs);
-            return this;
-        }
-
-        /**
-         * Set the dns evaluation type into Builder.
-         *
-         * @param type the return code of the dns event.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setEvaluationType(int type) {
-            mEvaluationType = type;
-            return this;
-        }
-
-        /**
-         * Set the network type into Builder.
-         *
-         * @param type the network type of the logged network.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setNetworkType(int type) {
-            mNetworkType = type;
-            return this;
-        }
-
-        /**
-         * Set the wifi data into Builder.
-         *
-         * @param info a {@link WifiInfo} of the connected wifi network.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setWiFiData(@Nullable final WifiInfo info) {
-            WifiData data = new WifiData();
-            data.wifiBand = getWifiBand(info);
-            data.signalStrength = (info != null) ? info.getRssi() : UNKNOWN_SIGNAL_STRENGTH;
-            mWifiInfo = MessageNano.toByteArray(data);
-            return this;
-        }
-
-        private static int getWifiBand(@Nullable final WifiInfo info) {
-            if (info == null) return DataStallEventProto.AP_BAND_UNKNOWN;
-
-            int freq = info.getFrequency();
-            // Refer to ScanResult.is5GHz() and ScanResult.is24GHz().
-            if (freq > 4900 && freq < 5900) {
-                return DataStallEventProto.AP_BAND_5GHZ;
-            } else if (freq > 2400 && freq < 2500) {
-                return DataStallEventProto.AP_BAND_2GHZ;
-            } else {
-                return DataStallEventProto.AP_BAND_UNKNOWN;
-            }
-        }
-
-        /**
-         * Set the cellular data into Builder.
-         *
-         * @param radioType the radio technology of the logged cellular network.
-         * @param roaming a boolean indicates if logged cellular network is roaming or not.
-         * @param networkMccmnc the mccmnc of the camped network.
-         * @param simMccmnc the mccmnc of the sim.
-         * @return {@code this} {@link Builder} instance.
-         */
-        public Builder setCellData(int radioType, boolean roaming,
-                @NonNull String networkMccmnc, @NonNull String simMccmnc, int ss) {
-            CellularData data  = new CellularData();
-            data.ratType = radioType;
-            data.isRoaming = roaming;
-            data.networkMccmnc = networkMccmnc;
-            data.simMccmnc = simMccmnc;
-            data.signalStrength = ss;
-            mCellularInfo = MessageNano.toByteArray(data);
-            return this;
-        }
-
-        /**
-         * Create a new {@Link DataStallDetectionStats}.
-         */
-        public DataStallDetectionStats build() {
-            return new DataStallDetectionStats(mCellularInfo, mWifiInfo,
-                    NetworkStackUtils.convertToIntArray(mDnsReturnCode),
-                    NetworkStackUtils.convertToLongArray(mDnsTimeStamp),
-                    mEvaluationType, mNetworkType);
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java b/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
deleted file mode 100644
index 9308901..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/metrics/DataStallStatsUtils.java
+++ /dev/null
@@ -1,73 +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.networkstack.metrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-import com.android.server.connectivity.nano.DataStallEventProto;
-
-/**
- * Collection of utilities for data stall metrics.
- *
- * To see if the logs are properly sent to statsd, execute following command.
- *
- * $ adb shell cmd stats print-logs
- * $ adb logcat | grep statsd  OR $ adb logcat -b stats
- *
- * @hide
- */
-public class DataStallStatsUtils {
-    private static final String TAG = DataStallStatsUtils.class.getSimpleName();
-    private static final boolean DBG = false;
-
-    private static int probeResultToEnum(@Nullable final CaptivePortalProbeResult result) {
-        if (result == null) return DataStallEventProto.INVALID;
-
-        if (result.isSuccessful()) {
-            return DataStallEventProto.VALID;
-        } else if (result.isPortal()) {
-            return DataStallEventProto.PORTAL;
-        } else if (result.isPartialConnectivity()) {
-            return DataStallEventProto.PARTIAL;
-        } else {
-            return DataStallEventProto.INVALID;
-        }
-    }
-
-    /**
-     * Write the metric to {@link StatsLog}.
-     */
-    public static void write(@NonNull final DataStallDetectionStats stats,
-            @NonNull final CaptivePortalProbeResult result) {
-        int validationResult = probeResultToEnum(result);
-        if (DBG) {
-            Log.d(TAG, "write: " + stats + " with result: " + validationResult
-                    + ", dns: " + HexDump.toHexString(stats.mDns));
-        }
-        NetworkStackStatsLog.write(NetworkStackStatsLog.DATA_STALL_EVENT,
-                stats.mEvaluationType,
-                validationResult,
-                stats.mNetworkType,
-                stats.mWifiInfo,
-                stats.mCellularInfo,
-                stats.mDns);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java b/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
deleted file mode 100644
index 4767d55..0000000
--- a/packages/NetworkStack/src/com/android/networkstack/util/DnsUtils.java
+++ /dev/null
@@ -1,130 +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.networkstack.util;
-
-import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP;
-import static android.net.DnsResolver.TYPE_A;
-import static android.net.DnsResolver.TYPE_AAAA;
-
-import android.annotation.NonNull;
-import android.net.DnsResolver;
-import android.net.Network;
-import android.net.TrafficStats;
-import android.util.Log;
-
-import com.android.internal.util.TrafficStatsConstants;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Collection of utilities for dns query.
- */
-public class DnsUtils {
-    // Decide what queries to make depending on what IP addresses are on the system.
-    public static final int TYPE_ADDRCONFIG = -1;
-    private static final String TAG = DnsUtils.class.getSimpleName();
-
-    /**
-     * Return both A and AAAA query results regardless the ip address type of the giving network.
-     * Used for probing in NetworkMonitor.
-     */
-    @NonNull
-    public static InetAddress[] getAllByName(@NonNull final DnsResolver dnsResolver,
-            @NonNull final Network network, @NonNull String host, int timeout)
-            throws UnknownHostException {
-        final List<InetAddress> result = new ArrayList<InetAddress>();
-
-        try {
-            result.addAll(Arrays.asList(
-                    getAllByName(dnsResolver, network, host, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP,
-                    timeout)));
-        } catch (UnknownHostException e) {
-            // Might happen if the host is v4-only, still need to query TYPE_A
-        }
-        try {
-            result.addAll(Arrays.asList(
-                    getAllByName(dnsResolver, network, host, TYPE_A, FLAG_NO_CACHE_LOOKUP,
-                    timeout)));
-        } catch (UnknownHostException e) {
-            // Might happen if the host is v6-only, still need to return AAAA answers
-        }
-        if (result.size() == 0) {
-            throw new UnknownHostException(host);
-        }
-        return result.toArray(new InetAddress[0]);
-    }
-
-    /**
-     * Return dns query result based on the given QueryType(TYPE_A, TYPE_AAAA) or TYPE_ADDRCONFIG.
-     * Used for probing in NetworkMonitor.
-     */
-    @NonNull
-    public static InetAddress[] getAllByName(@NonNull final DnsResolver dnsResolver,
-            @NonNull final Network network, @NonNull final String host, int type, int flag,
-            int timeoutMs) throws UnknownHostException {
-        final CountDownLatch latch = new CountDownLatch(1);
-        final AtomicReference<List<InetAddress>> resultRef = new AtomicReference<>();
-
-        final DnsResolver.Callback<List<InetAddress>> callback =
-                new DnsResolver.Callback<List<InetAddress>>() {
-            @Override
-            public void onAnswer(List<InetAddress> answer, int rcode) {
-                if (rcode == 0) {
-                    resultRef.set(answer);
-                }
-                latch.countDown();
-            }
-
-            @Override
-            public void onError(@NonNull DnsResolver.DnsException e) {
-                Log.d(TAG, "DNS error resolving " + host + ": " + e.getMessage());
-                latch.countDown();
-            }
-        };
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_PROBE);
-
-        if (type == TYPE_ADDRCONFIG) {
-            dnsResolver.query(network, host, flag, r -> r.run(), null /* cancellationSignal */,
-                    callback);
-        } else {
-            dnsResolver.query(network, host, type, flag, r -> r.run(),
-                    null /* cancellationSignal */, callback);
-        }
-
-        TrafficStats.setThreadStatsTag(oldTag);
-
-        try {
-            latch.await(timeoutMs, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-        }
-
-        final List<InetAddress> result = resultRef.get();
-        if (result == null || result.size() == 0) {
-            throw new UnknownHostException(host);
-        }
-
-        return result.toArray(new InetAddress[0]);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkObserver.java b/packages/NetworkStack/src/com/android/server/NetworkObserver.java
deleted file mode 100644
index cccec0b..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkObserver.java
+++ /dev/null
@@ -1,88 +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.server;
-
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-
-/**
- * Observer for network events, to use with {@link NetworkObserverRegistry}.
- */
-public interface NetworkObserver {
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceChanged(java.lang.String, boolean)
-     */
-    default void onInterfaceChanged(String ifName, boolean up) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceRemoved(String)
-     */
-    default void onInterfaceRemoved(String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceAddressUpdated(String, String, int, int)
-     */
-    default void onInterfaceAddressUpdated(LinkAddress address, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceAddressRemoved(String, String, int, int)
-     */
-    default void onInterfaceAddressRemoved(LinkAddress address, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceLinkStateChanged(String, boolean)
-     */
-    default void onInterfaceLinkStateChanged(String ifName, boolean up) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onInterfaceAdded(String)
-     */
-    default void onInterfaceAdded(String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceClassActivityChanged(boolean, int, long, int)
-     */
-    default void onInterfaceClassActivityChanged(
-            boolean isActive, int label, long timestamp, int uid) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener#onQuotaLimitReached(String, String)
-     */
-    default void onQuotaLimitReached(String alertName, String ifName) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onInterfaceDnsServerInfo(String, long, String[])
-     */
-    default void onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onRouteChanged(boolean, String, String, String)
-     */
-    default void onRouteUpdated(RouteInfo route) {}
-
-    /**
-     * @see android.net.INetdUnsolicitedEventListener
-     *          #onRouteChanged(boolean, String, String, String)
-     */
-    default void onRouteRemoved(RouteInfo route) {}
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java b/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
deleted file mode 100644
index afe166b..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkObserverRegistry.java
+++ /dev/null
@@ -1,189 +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.server;
-
-import static android.net.RouteInfo.RTN_UNICAST;
-
-import android.annotation.NonNull;
-import android.net.INetd;
-import android.net.INetdUnsolicitedEventListener;
-import android.net.InetAddresses;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A class for reporting network events to clients.
- *
- * Implements INetdUnsolicitedEventListener and registers with netd, and relays those events to
- * all INetworkManagementEventObserver objects that have registered with it.
- */
-public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub {
-    private static final String TAG = NetworkObserverRegistry.class.getSimpleName();
-
-    /**
-     * Constructs a new NetworkObserverRegistry.
-     *
-     * <p>Only one registry should be used per process since netd will silently ignore multiple
-     * registrations from the same process.
-     */
-    NetworkObserverRegistry() {}
-
-    /**
-     * Start listening for Netd events.
-     *
-     * <p>This should be called before allowing any observer to be registered.
-     */
-    void register(@NonNull INetd netd) throws RemoteException {
-        netd.registerUnsolicitedEventListener(this);
-    }
-
-    private final ConcurrentHashMap<NetworkObserver, Optional<Handler>> mObservers =
-            new ConcurrentHashMap<>();
-
-    /**
-     * Registers the specified observer and start sending callbacks to it.
-     * This method may be called on any thread.
-     */
-    public void registerObserver(@NonNull NetworkObserver observer, @NonNull Handler handler) {
-        if (handler == null) {
-            throw new IllegalArgumentException("handler must be non-null");
-        }
-        mObservers.put(observer, Optional.of(handler));
-    }
-
-    /**
-     * Registers the specified observer, and start sending callbacks to it.
-     *
-     * <p>This method must only be called with callbacks that are nonblocking, such as callbacks
-     * that only send a message to a StateMachine.
-     */
-    public void registerObserverForNonblockingCallback(@NonNull NetworkObserver observer) {
-        mObservers.put(observer, Optional.empty());
-    }
-
-    /**
-     * Unregisters the specified observer and stop sending callbacks to it.
-     * This method may be called on any thread.
-     */
-    public void unregisterObserver(@NonNull NetworkObserver observer) {
-        mObservers.remove(observer);
-    }
-
-    @FunctionalInterface
-    private interface NetworkObserverEventCallback {
-        void sendCallback(NetworkObserver o);
-    }
-
-    private void invokeForAllObservers(@NonNull final NetworkObserverEventCallback callback) {
-        // ConcurrentHashMap#entrySet is weakly consistent: observers that were in the map before
-        // creation will be processed, those added during traversal may or may not.
-        for (Map.Entry<NetworkObserver, Optional<Handler>> entry : mObservers.entrySet()) {
-            final NetworkObserver observer = entry.getKey();
-            final Optional<Handler> handler = entry.getValue();
-            if (handler.isPresent()) {
-                handler.get().post(() -> callback.sendCallback(observer));
-                return;
-            }
-
-            try {
-                callback.sendCallback(observer);
-            } catch (RuntimeException e) {
-                Log.e(TAG, "Error sending callback to observer", e);
-            }
-        }
-    }
-
-    @Override
-    public void onInterfaceClassActivityChanged(boolean isActive,
-            int label, long timestamp, int uid) {
-        invokeForAllObservers(o -> o.onInterfaceClassActivityChanged(
-                isActive, label, timestamp, uid));
-    }
-
-    /**
-     * Notify our observers of a limit reached.
-     */
-    @Override
-    public void onQuotaLimitReached(String alertName, String ifName) {
-        invokeForAllObservers(o -> o.onQuotaLimitReached(alertName, ifName));
-    }
-
-    @Override
-    public void onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers) {
-        invokeForAllObservers(o -> o.onInterfaceDnsServerInfo(ifName, lifetime, servers));
-    }
-
-    @Override
-    public void onInterfaceAddressUpdated(String addr, String ifName, int flags, int scope) {
-        final LinkAddress address = new LinkAddress(addr, flags, scope);
-        invokeForAllObservers(o -> o.onInterfaceAddressUpdated(address, ifName));
-    }
-
-    @Override
-    public void onInterfaceAddressRemoved(String addr,
-            String ifName, int flags, int scope) {
-        final LinkAddress address = new LinkAddress(addr, flags, scope);
-        invokeForAllObservers(o -> o.onInterfaceAddressRemoved(address, ifName));
-    }
-
-    @Override
-    public void onInterfaceAdded(String ifName) {
-        invokeForAllObservers(o -> o.onInterfaceAdded(ifName));
-    }
-
-    @Override
-    public void onInterfaceRemoved(String ifName) {
-        invokeForAllObservers(o -> o.onInterfaceRemoved(ifName));
-    }
-
-    @Override
-    public void onInterfaceChanged(String ifName, boolean up) {
-        invokeForAllObservers(o -> o.onInterfaceChanged(ifName, up));
-    }
-
-    @Override
-    public void onInterfaceLinkStateChanged(String ifName, boolean up) {
-        invokeForAllObservers(o -> o.onInterfaceLinkStateChanged(ifName, up));
-    }
-
-    @Override
-    public void onRouteChanged(boolean updated, String route, String gateway, String ifName) {
-        final RouteInfo processRoute = new RouteInfo(new IpPrefix(route),
-                ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway),
-                ifName, RTN_UNICAST);
-        if (updated) {
-            invokeForAllObservers(o -> o.onRouteUpdated(processRoute));
-        } else {
-            invokeForAllObservers(o -> o.onRouteRemoved(processRoute));
-        }
-    }
-
-    @Override
-    public void onStrictCleartextDetected(int uid, String hex) {}
-
-    @Override
-    public int getInterfaceVersion() {
-        return INetdUnsolicitedEventListener.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
deleted file mode 100644
index 9bf4457..0000000
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ /dev/null
@@ -1,389 +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.server;
-
-import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
-
-import static com.android.server.util.PermissionUtil.checkDumpPermission;
-import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.IIpMemoryStore;
-import android.net.IIpMemoryStoreCallbacks;
-import android.net.INetd;
-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;
-import android.net.dhcp.DhcpServingParamsParcel;
-import android.net.dhcp.IDhcpServerCallbacks;
-import android.net.ip.IIpClientCallbacks;
-import android.net.ip.IpClient;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.SharedLog;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.ArraySet;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.connectivity.NetworkMonitor;
-import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-
-/**
- * Android service used to start the network stack when bound to via an intent.
- *
- * <p>The service returns a binder for the system server to communicate with the network stack.
- */
-public class NetworkStackService extends Service {
-    private static final String TAG = NetworkStackService.class.getSimpleName();
-    private static NetworkStackConnector sConnector;
-
-    /**
-     * Create a binder connector for the system server to communicate with the network stack.
-     *
-     * <p>On platforms where the network stack runs in the system server process, this method may
-     * be called directly instead of obtaining the connector by binding to the service.
-     */
-    public static synchronized IBinder makeConnector(Context context) {
-        if (sConnector == null) {
-            sConnector = new NetworkStackConnector(context);
-        }
-        return sConnector;
-    }
-
-    @NonNull
-    @Override
-    public IBinder onBind(Intent intent) {
-        return makeConnector(this);
-    }
-
-    /**
-     * An interface for internal clients of the network stack service that can return
-     * or create inline instances of the service it manages.
-     */
-    public interface NetworkStackServiceManager {
-        /**
-         * Get an instance of the IpMemoryStoreService.
-         */
-        IIpMemoryStore getIpMemoryStoreService();
-    }
-
-    private static class NetworkStackConnector extends INetworkStackConnector.Stub
-            implements NetworkStackServiceManager {
-        private static final int NUM_VALIDATION_LOG_LINES = 20;
-        private final Context mContext;
-        private final INetd mNetd;
-        private final NetworkObserverRegistry mObserverRegistry;
-        private final ConnectivityManager mCm;
-        @GuardedBy("mIpClients")
-        private final ArrayList<WeakReference<IpClient>> mIpClients = new ArrayList<>();
-        private final IpMemoryStoreService mIpMemoryStoreService;
-
-        private static final int MAX_VALIDATION_LOGS = 10;
-        @GuardedBy("mValidationLogs")
-        private final ArrayDeque<SharedLog> mValidationLogs = new ArrayDeque<>(MAX_VALIDATION_LOGS);
-
-        private static final String DUMPSYS_ARG_VERSION = "version";
-
-        /** Version of the framework AIDL interfaces observed. Should hold only one value. */
-        @GuardedBy("mFrameworkAidlVersions")
-        private final ArraySet<Integer> mFrameworkAidlVersions = new ArraySet<>(1);
-        private final int mNetdAidlVersion;
-
-        private SharedLog addValidationLogs(Network network, String name) {
-            final SharedLog log = new SharedLog(NUM_VALIDATION_LOG_LINES, network + " - " + name);
-            synchronized (mValidationLogs) {
-                while (mValidationLogs.size() >= MAX_VALIDATION_LOGS) {
-                    mValidationLogs.removeLast();
-                }
-                mValidationLogs.addFirst(log);
-            }
-            return log;
-        }
-
-        NetworkStackConnector(Context context) {
-            mContext = context;
-            mNetd = INetd.Stub.asInterface(
-                    (IBinder) context.getSystemService(Context.NETD_SERVICE));
-            mObserverRegistry = new NetworkObserverRegistry();
-            mCm = context.getSystemService(ConnectivityManager.class);
-            mIpMemoryStoreService = new IpMemoryStoreService(context);
-
-            int netdVersion;
-            try {
-                netdVersion = mNetd.getInterfaceVersion();
-            } catch (RemoteException e) {
-                mLog.e("Error obtaining INetd version", e);
-                netdVersion = -1;
-            }
-            mNetdAidlVersion = netdVersion;
-
-            try {
-                mObserverRegistry.register(mNetd);
-            } catch (RemoteException e) {
-                mLog.e("Error registering observer on Netd", e);
-            }
-        }
-
-        private void updateSystemAidlVersion(final int version) {
-            synchronized (mFrameworkAidlVersions) {
-                mFrameworkAidlVersions.add(version);
-            }
-        }
-
-        @NonNull
-        private final SharedLog mLog = new SharedLog(TAG);
-
-        @Override
-        public void makeDhcpServer(@NonNull String ifName, @NonNull DhcpServingParamsParcel params,
-                @NonNull IDhcpServerCallbacks cb) throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final DhcpServer server;
-            try {
-                server = new DhcpServer(
-                        ifName,
-                        DhcpServingParams.fromParcelableObject(params),
-                        mLog.forSubComponent(ifName + ".DHCP"));
-            } catch (DhcpServingParams.InvalidParameterException e) {
-                mLog.e("Invalid DhcpServingParams", e);
-                cb.onDhcpServerCreated(STATUS_INVALID_ARGUMENT, null);
-                return;
-            } catch (Exception e) {
-                mLog.e("Unknown error starting DhcpServer", e);
-                cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
-                return;
-            }
-            cb.onDhcpServerCreated(STATUS_SUCCESS, server);
-        }
-
-        @Override
-        public void makeNetworkMonitor(Network network, String name, INetworkMonitorCallbacks cb)
-                throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final SharedLog log = addValidationLogs(network, name);
-            final NetworkMonitor nm = new NetworkMonitor(mContext, cb, network, log);
-            cb.onNetworkMonitorCreated(new NetworkMonitorImpl(nm));
-        }
-
-        @Override
-        public void makeIpClient(String ifName, IIpClientCallbacks cb) throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            final IpClient ipClient = new IpClient(mContext, ifName, cb, mObserverRegistry, this);
-
-            synchronized (mIpClients) {
-                final Iterator<WeakReference<IpClient>> it = mIpClients.iterator();
-                while (it.hasNext()) {
-                    final IpClient ipc = it.next().get();
-                    if (ipc == null) {
-                        it.remove();
-                    }
-                }
-                mIpClients.add(new WeakReference<>(ipClient));
-            }
-
-            cb.onIpClientCreated(ipClient.makeConnector());
-        }
-
-        @Override
-        public IIpMemoryStore getIpMemoryStoreService() {
-            return mIpMemoryStoreService;
-        }
-
-        @Override
-        public void fetchIpMemoryStore(@NonNull final IIpMemoryStoreCallbacks cb)
-                throws RemoteException {
-            checkNetworkStackCallingPermission();
-            updateSystemAidlVersion(cb.getInterfaceVersion());
-            cb.onIpMemoryStoreFetched(mIpMemoryStoreService);
-        }
-
-        @Override
-        protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
-                @Nullable String[] args) {
-            checkDumpPermission();
-
-            final IndentingPrintWriter pw = new IndentingPrintWriter(fout, "  ");
-            pw.println("NetworkStack version:");
-            dumpVersion(pw);
-            pw.println();
-
-            if (args != null && args.length >= 1 && DUMPSYS_ARG_VERSION.equals(args[0])) {
-                return;
-            }
-
-            pw.println("NetworkStack logs:");
-            mLog.dump(fd, pw, args);
-
-            // Dump full IpClient logs for non-GCed clients
-            pw.println();
-            pw.println("Recently active IpClient logs:");
-            final ArrayList<IpClient> ipClients = new ArrayList<>();
-            final HashSet<String> dumpedIpClientIfaces = new HashSet<>();
-            synchronized (mIpClients) {
-                for (WeakReference<IpClient> ipcRef : mIpClients) {
-                    final IpClient ipc = ipcRef.get();
-                    if (ipc != null) {
-                        ipClients.add(ipc);
-                    }
-                }
-            }
-
-            for (IpClient ipc : ipClients) {
-                pw.println(ipc.getName());
-                pw.increaseIndent();
-                ipc.dump(fd, pw, args);
-                pw.decreaseIndent();
-                dumpedIpClientIfaces.add(ipc.getInterfaceName());
-            }
-
-            // State machine and connectivity metrics logs are kept for GCed IpClients
-            pw.println();
-            pw.println("Other IpClient logs:");
-            IpClient.dumpAllLogs(fout, dumpedIpClientIfaces);
-
-            pw.println();
-            pw.println("Validation logs (most recent first):");
-            synchronized (mValidationLogs) {
-                for (SharedLog p : mValidationLogs) {
-                    pw.println(p.getTag());
-                    pw.increaseIndent();
-                    p.dump(fd, pw, args);
-                    pw.decreaseIndent();
-                }
-            }
-        }
-
-        /**
-         * Dump version information of the module and detected system version.
-         */
-        private void dumpVersion(@NonNull PrintWriter fout) {
-            fout.println("NetworkStackConnector: " + this.VERSION);
-            synchronized (mFrameworkAidlVersions) {
-                fout.println("SystemServer: " + mFrameworkAidlVersions);
-            }
-            fout.println("Netd: " + mNetdAidlVersion);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-
-    private static class NetworkMonitorImpl extends INetworkMonitor.Stub {
-        private final NetworkMonitor mNm;
-
-        NetworkMonitorImpl(NetworkMonitor nm) {
-            mNm = nm;
-        }
-
-        @Override
-        public void start() {
-            checkNetworkStackCallingPermission();
-            mNm.start();
-        }
-
-        @Override
-        public void launchCaptivePortalApp() {
-            checkNetworkStackCallingPermission();
-            mNm.launchCaptivePortalApp();
-        }
-
-        @Override
-        public void notifyCaptivePortalAppFinished(int response) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyCaptivePortalAppFinished(response);
-        }
-
-        @Override
-        public void setAcceptPartialConnectivity() {
-            checkNetworkStackCallingPermission();
-            mNm.setAcceptPartialConnectivity();
-        }
-
-        @Override
-        public void forceReevaluation(int uid) {
-            checkNetworkStackCallingPermission();
-            mNm.forceReevaluation(uid);
-        }
-
-        @Override
-        public void notifyPrivateDnsChanged(PrivateDnsConfigParcel config) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyPrivateDnsSettingsChanged(PrivateDnsConfig.fromParcel(config));
-        }
-
-        @Override
-        public void notifyDnsResponse(int returnCode) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyDnsResponse(returnCode);
-        }
-
-        @Override
-        public void notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkConnected(lp, nc);
-        }
-
-        @Override
-        public void notifyNetworkDisconnected() {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkDisconnected();
-        }
-
-        @Override
-        public void notifyLinkPropertiesChanged(LinkProperties lp) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyLinkPropertiesChanged(lp);
-        }
-
-        @Override
-        public void notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) {
-            checkNetworkStackCallingPermission();
-            mNm.notifyNetworkCapabilitiesChanged(nc);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
deleted file mode 100644
index 4e40ba4..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ /dev/null
@@ -1,2143 +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.
- */
-
-package com.android.server.connectivity;
-
-import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
-import static android.net.CaptivePortal.APP_RETURN_UNWANTED;
-import static android.net.CaptivePortal.APP_RETURN_WANTED_AS_IS;
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_PROBE_SPEC;
-import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL;
-import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.DnsResolver.FLAG_EMPTY;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static android.net.captiveportal.CaptivePortalProbeSpec.parseCaptivePortalProbeSpecs;
-import static android.net.metrics.ValidationProbeEvent.DNS_FAILURE;
-import static android.net.metrics.ValidationProbeEvent.DNS_SUCCESS;
-import static android.net.metrics.ValidationProbeEvent.PROBE_FALLBACK;
-import static android.net.metrics.ValidationProbeEvent.PROBE_PRIVDNS;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_EVALUATION_TYPE;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD;
-import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS;
-import static android.net.util.DataStallUtils.DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_EVALUATION_TYPES;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS;
-import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS;
-import static android.net.util.DataStallUtils.DEFAULT_DNS_LOG_SIZE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTPS_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTP_URL;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_IGNORE;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_PROMPT;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USER_AGENT;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
-import static android.net.util.NetworkStackUtils.NAMESPACE_CONNECTIVITY;
-import static android.net.util.NetworkStackUtils.isEmpty;
-
-import static com.android.networkstack.util.DnsUtils.TYPE_ADDRCONFIG;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.DnsResolver;
-import android.net.INetworkMonitorCallbacks;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.ProxyInfo;
-import android.net.TrafficStats;
-import android.net.Uri;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.net.captiveportal.CaptivePortalProbeSpec;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.NetworkEvent;
-import android.net.metrics.ValidationProbeEvent;
-import android.net.shared.NetworkMonitorUtils;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.NetworkStackUtils;
-import android.net.util.SharedLog;
-import android.net.util.Stopwatch;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.CellSignalStrength;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.annotation.ArrayRes;
-import androidx.annotation.StringRes;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.RingBufferIndices;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.TrafficStatsConstants;
-import com.android.networkstack.R;
-import com.android.networkstack.metrics.DataStallDetectionStats;
-import com.android.networkstack.metrics.DataStallStatsUtils;
-import com.android.networkstack.util.DnsUtils;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-
-/**
- * {@hide}
- */
-public class NetworkMonitor extends StateMachine {
-    private static final String TAG = NetworkMonitor.class.getSimpleName();
-    private static final boolean DBG  = true;
-    private static final boolean VDBG = false;
-    private static final boolean VDBG_STALL = Log.isLoggable(TAG, Log.DEBUG);
-    private static final String DEFAULT_USER_AGENT    = "Mozilla/5.0 (X11; Linux x86_64) "
-                                                      + "AppleWebKit/537.36 (KHTML, like Gecko) "
-                                                      + "Chrome/60.0.3112.32 Safari/537.36";
-
-    @VisibleForTesting
-    static final String CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT =
-            "captive_portal_dns_probe_timeout";
-
-    private static final int SOCKET_TIMEOUT_MS = 10000;
-    private static final int PROBE_TIMEOUT_MS  = 3000;
-
-    enum EvaluationResult {
-        VALIDATED(true),
-        CAPTIVE_PORTAL(false);
-        final boolean mIsValidated;
-        EvaluationResult(boolean isValidated) {
-            this.mIsValidated = isValidated;
-        }
-    }
-
-    enum ValidationStage {
-        FIRST_VALIDATION(true),
-        REVALIDATION(false);
-        final boolean mIsFirstValidation;
-        ValidationStage(boolean isFirstValidation) {
-            this.mIsFirstValidation = isFirstValidation;
-        }
-    }
-
-    /**
-     * ConnectivityService has sent a notification to indicate that network has connected.
-     * Initiates Network Validation.
-     */
-    private static final int CMD_NETWORK_CONNECTED = 1;
-
-    /**
-     * Message to self indicating it's time to evaluate a network's connectivity.
-     * arg1 = Token to ignore old messages.
-     */
-    private static final int CMD_REEVALUATE = 6;
-
-    /**
-     * ConnectivityService has sent a notification to indicate that network has disconnected.
-     */
-    private static final int CMD_NETWORK_DISCONNECTED = 7;
-
-    /**
-     * Force evaluation even if it has succeeded in the past.
-     * arg1 = UID responsible for requesting this reeval.  Will be billed for data.
-     */
-    private static final int CMD_FORCE_REEVALUATION = 8;
-
-    /**
-     * Message to self indicating captive portal app finished.
-     * arg1 = one of: APP_RETURN_DISMISSED,
-     *                APP_RETURN_UNWANTED,
-     *                APP_RETURN_WANTED_AS_IS
-     * obj = mCaptivePortalLoggedInResponseToken as String
-     */
-    private static final int CMD_CAPTIVE_PORTAL_APP_FINISHED = 9;
-
-    /**
-     * Message indicating sign-in app should be launched.
-     * Sent by mLaunchCaptivePortalAppBroadcastReceiver when the
-     * user touches the sign in notification, or sent by
-     * ConnectivityService when the user touches the "sign into
-     * network" button in the wifi access point detail page.
-     */
-    private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = 11;
-
-    /**
-     * Retest network to see if captive portal is still in place.
-     * arg1 = UID responsible for requesting this reeval.  Will be billed for data.
-     *        0 indicates self-initiated, so nobody to blame.
-     */
-    private static final int CMD_CAPTIVE_PORTAL_RECHECK = 12;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor of settings changes to
-     * Private DNS. If a DNS resolution is required, e.g. for DNS-over-TLS in
-     * strict mode, then an event is sent back to ConnectivityService with the
-     * result of the resolution attempt.
-     *
-     * A separate message is used to trigger (re)evaluation of the Private DNS
-     * configuration, so that the message can be handled as needed in different
-     * states, including being ignored until after an ongoing captive portal
-     * validation phase is completed.
-     */
-    private static final int CMD_PRIVATE_DNS_SETTINGS_CHANGED = 13;
-    private static final int CMD_EVALUATE_PRIVATE_DNS = 15;
-
-    /**
-     * Message to self indicating captive portal detection is completed.
-     * obj = CaptivePortalProbeResult for detection result;
-     */
-    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.
-     */
-    private static final int EVENT_DNS_NOTIFICATION = 17;
-
-    /**
-     * ConnectivityService notifies NetworkMonitor that the user accepts partial connectivity and
-     * NetworkMonitor should ignore the https probe.
-     */
-    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;
-    private static final int MAX_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
-    // Before network has been evaluated this many times, ignore repeated reevaluate requests.
-    private static final int IGNORE_REEVALUATE_ATTEMPTS = 5;
-    private int mReevaluateToken = 0;
-    private static final int NO_UID = 0;
-    private static final int INVALID_UID = -1;
-    private int mUidResponsibleForReeval = INVALID_UID;
-    // Stop blaming UID that requested re-evaluation after this many attempts.
-    private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5;
-    // Delay between reevaluations once a captive portal has been found.
-    private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
-    private static final int NETWORK_VALIDATION_RESULT_INVALID = 0;
-    private String mPrivateDnsProviderHostname = "";
-
-    private final Context mContext;
-    private final INetworkMonitorCallbacks mCallback;
-    private final Network mCleartextDnsNetwork;
-    private final Network mNetwork;
-    private final TelephonyManager mTelephonyManager;
-    private final WifiManager mWifiManager;
-    private final ConnectivityManager mCm;
-    private final IpConnectivityLog mMetricsLog;
-    private final Dependencies mDependencies;
-    private final DataStallStatsUtils mDetectionStatsUtils;
-
-    // Configuration values for captive portal detection probes.
-    private final String mCaptivePortalUserAgent;
-    private final URL mCaptivePortalHttpsUrl;
-    private final URL mCaptivePortalHttpUrl;
-    private final URL[] mCaptivePortalFallbackUrls;
-    @Nullable
-    private final CaptivePortalProbeSpec[] mCaptivePortalFallbackSpecs;
-
-    private NetworkCapabilities mNetworkCapabilities;
-    private LinkProperties mLinkProperties;
-
-    @VisibleForTesting
-    protected boolean mIsCaptivePortalCheckEnabled;
-
-    private boolean mUseHttps;
-    // The total number of captive portal detection attempts for this NetworkMonitor instance.
-    private int mValidations = 0;
-
-    // Set if the user explicitly selected "Do not use this network" in captive portal sign-in app.
-    private boolean mUserDoesNotWant = false;
-    // Avoids surfacing "Sign in to network" notification.
-    private boolean mDontDisplaySigninNotification = false;
-
-    private final State mDefaultState = new DefaultState();
-    private final State mValidatedState = new ValidatedState();
-    private final State mMaybeNotifyState = new MaybeNotifyState();
-    private final State mEvaluatingState = new EvaluatingState();
-    private final State mCaptivePortalState = new CaptivePortalState();
-    private final State mEvaluatingPrivateDnsState = new EvaluatingPrivateDnsState();
-    private final State mProbingState = new ProbingState();
-    private final State mWaitingForNextProbeState = new WaitingForNextProbeState();
-
-    private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
-
-    private final SharedLog mValidationLogs;
-
-    private final Stopwatch mEvaluationTimer = new Stopwatch();
-
-    // This variable is set before transitioning to the mCaptivePortalState.
-    private CaptivePortalProbeResult mLastPortalProbeResult = CaptivePortalProbeResult.FAILED;
-
-    // Random generator to select fallback URL index
-    private final Random mRandom;
-    private int mNextFallbackUrlIndex = 0;
-
-
-    private int mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-    private int mEvaluateAttempts = 0;
-    private volatile int mProbeToken = 0;
-    private final int mConsecutiveDnsTimeoutThreshold;
-    private final int mDataStallMinEvaluateTime;
-    private final int mDataStallValidDnsTimeThreshold;
-    private final int mDataStallEvaluationType;
-    private final DnsStallDetector mDnsStallDetector;
-    private long mLastProbeTime;
-    // Set to true if data stall is suspected and reset to false after metrics are sent to statsd.
-    private boolean mCollectDataStallMetrics;
-    private boolean mAcceptPartialConnectivity = false;
-    private final EvaluationState mEvaluationState = new EvaluationState();
-
-    public NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
-            SharedLog validationLog) {
-        this(context, cb, network, new IpConnectivityLog(), validationLog,
-                Dependencies.DEFAULT, new DataStallStatsUtils());
-    }
-
-    @VisibleForTesting
-    protected NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
-            IpConnectivityLog logger, SharedLog validationLogs,
-            Dependencies deps, DataStallStatsUtils detectionStatsUtils) {
-        // Add suffix indicating which NetworkMonitor we're talking about.
-        super(TAG + "/" + network.toString());
-
-        // Logs with a tag of the form given just above, e.g.
-        //     <timestamp>   862  2402 D NetworkMonitor/NetworkAgentInfo [WIFI () - 100]: ...
-        setDbg(VDBG);
-
-        mContext = context;
-        mMetricsLog = logger;
-        mValidationLogs = validationLogs;
-        mCallback = cb;
-        mDependencies = deps;
-        mDetectionStatsUtils = detectionStatsUtils;
-        mNetwork = network;
-        mCleartextDnsNetwork = deps.getPrivateDnsBypassNetwork(network);
-        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
-        // CHECKSTYLE:OFF IndentationCheck
-        addState(mDefaultState);
-        addState(mMaybeNotifyState, mDefaultState);
-            addState(mEvaluatingState, mMaybeNotifyState);
-                addState(mProbingState, mEvaluatingState);
-                addState(mWaitingForNextProbeState, mEvaluatingState);
-            addState(mCaptivePortalState, mMaybeNotifyState);
-        addState(mEvaluatingPrivateDnsState, mDefaultState);
-        addState(mValidatedState, mDefaultState);
-        setInitialState(mDefaultState);
-        // CHECKSTYLE:ON IndentationCheck
-
-        mIsCaptivePortalCheckEnabled = getIsCaptivePortalCheckEnabled();
-        mUseHttps = getUseHttpsValidation();
-        mCaptivePortalUserAgent = getCaptivePortalUserAgent();
-        mCaptivePortalHttpsUrl = makeURL(getCaptivePortalServerHttpsUrl());
-        mCaptivePortalHttpUrl = makeURL(getCaptivePortalServerHttpUrl());
-        mCaptivePortalFallbackUrls = makeCaptivePortalFallbackUrls();
-        mCaptivePortalFallbackSpecs = makeCaptivePortalFallbackProbeSpecs();
-        mRandom = deps.getRandom();
-        // TODO: Evaluate to move data stall configuration to a specific class.
-        mConsecutiveDnsTimeoutThreshold = getConsecutiveDnsTimeoutThreshold();
-        mDnsStallDetector = new DnsStallDetector(mConsecutiveDnsTimeoutThreshold);
-        mDataStallMinEvaluateTime = getDataStallMinEvaluateTime();
-        mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold();
-        mDataStallEvaluationType = getDataStallEvaluationType();
-
-        // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null,
-        // even before notifyNetworkConnected.
-        mLinkProperties = new LinkProperties();
-        mNetworkCapabilities = new NetworkCapabilities(null);
-    }
-
-    /**
-     * ConnectivityService notifies NetworkMonitor that the user already accepted partial
-     * connectivity previously, so NetworkMonitor can validate the network even if it has partial
-     * connectivity.
-     */
-    public void setAcceptPartialConnectivity() {
-        sendMessage(EVENT_ACCEPT_PARTIAL_CONNECTIVITY);
-    }
-
-    /**
-     * Request the NetworkMonitor to reevaluate the network.
-     */
-    public void forceReevaluation(int responsibleUid) {
-        sendMessage(CMD_FORCE_REEVALUATION, responsibleUid, 0);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that there was a DNS query response event.
-     * @param returnCode the DNS return code of the response.
-     */
-    public void notifyDnsResponse(int returnCode) {
-        sendMessage(EVENT_DNS_NOTIFICATION, returnCode);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that private DNS settings have changed.
-     * @param newCfg The new private DNS configuration.
-     */
-    public void notifyPrivateDnsSettingsChanged(PrivateDnsConfig newCfg) {
-        // Cancel any outstanding resolutions.
-        removeMessages(CMD_PRIVATE_DNS_SETTINGS_CHANGED);
-        // Send the update to the proper thread.
-        sendMessage(CMD_PRIVATE_DNS_SETTINGS_CHANGED, newCfg);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that the network is now 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;
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that the network is now disconnected.
-     */
-    public void notifyNetworkDisconnected() {
-        sendMessage(CMD_NETWORK_DISCONNECTED);
-    }
-
-    /**
-     * Send a notification to NetworkMonitor indicating that link properties have changed.
-     */
-    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(final NetworkCapabilities nc) {
-        sendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, new NetworkCapabilities(nc));
-    }
-
-    /**
-     * Request the captive portal application to be launched.
-     */
-    public void launchCaptivePortalApp() {
-        sendMessage(CMD_LAUNCH_CAPTIVE_PORTAL_APP);
-    }
-
-    /**
-     * Notify that the captive portal app was closed with the provided response code.
-     */
-    public void notifyCaptivePortalAppFinished(int response) {
-        sendMessage(CMD_CAPTIVE_PORTAL_APP_FINISHED, response);
-    }
-
-    @Override
-    protected void log(String s) {
-        if (DBG) Log.d(TAG + "/" + mCleartextDnsNetwork.toString(), s);
-    }
-
-    private void validationLog(int probeType, Object url, String msg) {
-        String probeName = ValidationProbeEvent.getProbeName(probeType);
-        validationLog(String.format("%s %s %s", probeName, url, msg));
-    }
-
-    private void validationLog(String s) {
-        if (DBG) log(s);
-        mValidationLogs.log(s);
-    }
-
-    private ValidationStage validationStage() {
-        return 0 == mValidations ? ValidationStage.FIRST_VALIDATION : ValidationStage.REVALIDATION;
-    }
-
-    private boolean isValidationRequired() {
-        return NetworkMonitorUtils.isValidationRequired(mNetworkCapabilities);
-    }
-
-    private boolean isPrivateDnsValidationRequired() {
-        return NetworkMonitorUtils.isPrivateDnsValidationRequired(mNetworkCapabilities);
-    }
-
-    private void notifyNetworkTested(int result, @Nullable String redirectUrl) {
-        try {
-            mCallback.notifyNetworkTested(result, redirectUrl);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error sending network test result", e);
-        }
-    }
-
-    private void showProvisioningNotification(String action) {
-        try {
-            mCallback.showProvisioningNotification(action, mContext.getPackageName());
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error showing provisioning notification", e);
-        }
-    }
-
-    private void hideProvisioningNotification() {
-        try {
-            mCallback.hideProvisioningNotification();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error hiding provisioning notification", e);
-        }
-    }
-
-    // DefaultState is the parent of all States.  It exists only to handle CMD_* messages but
-    // does not entail any real state (hence no enter() or exit() routines).
-    private class DefaultState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_NETWORK_CONNECTED:
-                    updateConnectedNetworkAttributes(message);
-                    logNetworkEvent(NetworkEvent.NETWORK_CONNECTED);
-                    transitionTo(mEvaluatingState);
-                    return HANDLED;
-                case CMD_NETWORK_DISCONNECTED:
-                    logNetworkEvent(NetworkEvent.NETWORK_DISCONNECTED);
-                    quit();
-                    return HANDLED;
-                case CMD_FORCE_REEVALUATION:
-                case CMD_CAPTIVE_PORTAL_RECHECK:
-                    final int dnsCount = mDnsStallDetector.getConsecutiveTimeoutCount();
-                    validationLog("Forcing reevaluation for UID " + message.arg1
-                            + ". Dns signal count: " + dnsCount);
-                    mUidResponsibleForReeval = message.arg1;
-                    transitionTo(mEvaluatingState);
-                    return HANDLED;
-                case CMD_CAPTIVE_PORTAL_APP_FINISHED:
-                    log("CaptivePortal App responded with " + message.arg1);
-
-                    // If the user has seen and acted on a captive portal notification, and the
-                    // captive portal app is now closed, disable HTTPS probes. This avoids the
-                    // following pathological situation:
-                    //
-                    // 1. HTTP probe returns a captive portal, HTTPS probe fails or times out.
-                    // 2. User opens the app and logs into the captive portal.
-                    // 3. HTTP starts working, but HTTPS still doesn't work for some other reason -
-                    //    perhaps due to the network blocking HTTPS?
-                    //
-                    // In this case, we'll fail to validate the network even after the app is
-                    // dismissed. There is now no way to use this network, because the app is now
-                    // gone, so the user cannot select "Use this network as is".
-                    mUseHttps = false;
-
-                    switch (message.arg1) {
-                        case APP_RETURN_DISMISSED:
-                            sendMessage(CMD_FORCE_REEVALUATION, NO_UID, 0);
-                            break;
-                        case APP_RETURN_WANTED_AS_IS:
-                            mDontDisplaySigninNotification = true;
-                            // TODO: Distinguish this from a network that actually validates.
-                            // Displaying the "x" on the system UI icon may still be a good idea.
-                            transitionTo(mEvaluatingPrivateDnsState);
-                            break;
-                        case APP_RETURN_UNWANTED:
-                            mDontDisplaySigninNotification = true;
-                            mUserDoesNotWant = true;
-                            mEvaluationState.reportEvaluationResult(
-                                    NETWORK_VALIDATION_RESULT_INVALID, null);
-                            // TODO: Should teardown network.
-                            mUidResponsibleForReeval = 0;
-                            transitionTo(mEvaluatingState);
-                            break;
-                    }
-                    return HANDLED;
-                case CMD_PRIVATE_DNS_SETTINGS_CHANGED: {
-                    final PrivateDnsConfig cfg = (PrivateDnsConfig) message.obj;
-                    if (!isPrivateDnsValidationRequired() || cfg == null || !cfg.inStrictMode()) {
-                        // No DNS resolution required.
-                        //
-                        // We don't force any validation in opportunistic mode
-                        // here. Opportunistic mode nameservers are validated
-                        // separately within netd.
-                        //
-                        // Reset Private DNS settings state.
-                        mPrivateDnsProviderHostname = "";
-                        break;
-                    }
-
-                    mPrivateDnsProviderHostname = cfg.hostname;
-
-                    // DNS resolutions via Private DNS strict mode block for a
-                    // few seconds (~4.2) checking for any IP addresses to
-                    // arrive and validate. Initiating a (re)evaluation now
-                    // should not significantly alter the validation outcome.
-                    //
-                    // No matter what: enqueue a validation request; one of
-                    // three things can happen with this request:
-                    //     [1] ignored (EvaluatingState or CaptivePortalState)
-                    //     [2] transition to EvaluatingPrivateDnsState
-                    //         (DefaultState and ValidatedState)
-                    //     [3] handled (EvaluatingPrivateDnsState)
-                    //
-                    // The Private DNS configuration to be evaluated will:
-                    //     [1] be skipped (not in strict mode), or
-                    //     [2] validate (huzzah), or
-                    //     [3] encounter some problem (invalid hostname,
-                    //         no resolved IP addresses, IPs unreachable,
-                    //         port 853 unreachable, port 853 is not running a
-                    //         DNS-over-TLS server, et cetera).
-                    sendMessage(CMD_EVALUATE_PRIVATE_DNS);
-                    break;
-                }
-                case EVENT_DNS_NOTIFICATION:
-                    mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1);
-                    break;
-                // Set mAcceptPartialConnectivity to true and if network start evaluating or
-                // re-evaluating and get the result of partial connectivity, ProbingState will
-                // disable HTTPS probe and transition to EvaluatingPrivateDnsState.
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    maybeDisableHttpsProbing(true /* acceptPartial */);
-                    break;
-                case EVENT_LINK_PROPERTIES_CHANGED:
-                    mLinkProperties = (LinkProperties) message.obj;
-                    break;
-                case EVENT_NETWORK_CAPABILITIES_CHANGED:
-                    mNetworkCapabilities = (NetworkCapabilities) message.obj;
-                    break;
-                default:
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-    // Being in the ValidatedState State indicates a Network is:
-    // - Successfully validated, or
-    // - Wanted "as is" by the user, or
-    // - Does not satisfy the default NetworkRequest and so validation has been skipped.
-    private class ValidatedState extends State {
-        @Override
-        public void enter() {
-            maybeLogEvaluationResult(
-                    networkEventType(validationStage(), EvaluationResult.VALIDATED));
-            // If the user has accepted partial connectivity and HTTPS probing is disabled, then
-            // mark the network as validated and partial so that settings can keep informing the
-            // user that the connection is limited.
-            int result = NETWORK_VALIDATION_RESULT_VALID;
-            if (!mUseHttps && mAcceptPartialConnectivity) {
-                result |= NETWORK_VALIDATION_RESULT_PARTIAL;
-            }
-            mEvaluationState.reportEvaluationResult(result, null /* redirectUrl */);
-            mValidations++;
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_NETWORK_CONNECTED:
-                    updateConnectedNetworkAttributes(message);
-                    transitionTo(mValidatedState);
-                    break;
-                case CMD_EVALUATE_PRIVATE_DNS:
-                    transitionTo(mEvaluatingPrivateDnsState);
-                    break;
-                case EVENT_DNS_NOTIFICATION:
-                    mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1);
-                    if (isDataStall()) {
-                        mCollectDataStallMetrics = true;
-                        validationLog("Suspecting data stall, reevaluate");
-                        transitionTo(mEvaluatingState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private void writeDataStallStats(@NonNull final CaptivePortalProbeResult result) {
-        /*
-         * Collect data stall detection level information for each transport type. Collect type
-         * specific information for cellular and wifi only currently. Generate
-         * DataStallDetectionStats for each transport type. E.g., if a network supports both
-         * TRANSPORT_WIFI and TRANSPORT_VPN, two DataStallDetectionStats will be generated.
-         */
-        final int[] transports = mNetworkCapabilities.getTransportTypes();
-
-        for (int i = 0; i < transports.length; i++) {
-            DataStallStatsUtils.write(buildDataStallDetectionStats(transports[i]), result);
-        }
-        mCollectDataStallMetrics = false;
-    }
-
-    @VisibleForTesting
-    protected DataStallDetectionStats buildDataStallDetectionStats(int transport) {
-        final DataStallDetectionStats.Builder stats = new DataStallDetectionStats.Builder();
-        if (VDBG_STALL) log("collectDataStallMetrics: type=" + transport);
-        stats.setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
-        stats.setNetworkType(transport);
-        switch (transport) {
-            case NetworkCapabilities.TRANSPORT_WIFI:
-                // TODO: Update it if status query in dual wifi is supported.
-                final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-                stats.setWiFiData(wifiInfo);
-                break;
-            case NetworkCapabilities.TRANSPORT_CELLULAR:
-                final boolean isRoaming = !mNetworkCapabilities.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-                final SignalStrength ss = mTelephonyManager.getSignalStrength();
-                // TODO(b/120452078): Support multi-sim.
-                stats.setCellData(
-                        mTelephonyManager.getDataNetworkType(),
-                        isRoaming,
-                        mTelephonyManager.getNetworkOperator(),
-                        mTelephonyManager.getSimOperator(),
-                        (ss != null)
-                        ? ss.getLevel() : CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
-                break;
-            default:
-                // No transport type specific information for the other types.
-                break;
-        }
-        addDnsEvents(stats);
-
-        return stats.build();
-    }
-
-    @VisibleForTesting
-    protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) {
-        final int size = mDnsStallDetector.mResultIndices.size();
-        for (int i = 1; i <= DEFAULT_DNS_LOG_SIZE && i <= size; i++) {
-            final int index = mDnsStallDetector.mResultIndices.indexOf(size - i);
-            stats.addDnsEvent(mDnsStallDetector.mDnsEvents[index].mReturnCode,
-                    mDnsStallDetector.mDnsEvents[index].mTimeStamp);
-        }
-    }
-
-
-    // Being in the MaybeNotifyState State indicates the user may have been notified that sign-in
-    // is required.  This State takes care to clear the notification upon exit from the State.
-    private class MaybeNotifyState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_LAUNCH_CAPTIVE_PORTAL_APP:
-                    final Bundle appExtras = new Bundle();
-                    // OneAddressPerFamilyNetwork is not parcelable across processes.
-                    final Network network = new Network(mCleartextDnsNetwork);
-                    appExtras.putParcelable(ConnectivityManager.EXTRA_NETWORK, network);
-                    final CaptivePortalProbeResult probeRes = mLastPortalProbeResult;
-                    appExtras.putString(EXTRA_CAPTIVE_PORTAL_URL, probeRes.detectUrl);
-                    if (probeRes.probeSpec != null) {
-                        final String encodedSpec = probeRes.probeSpec.getEncodedSpec();
-                        appExtras.putString(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC, encodedSpec);
-                    }
-                    appExtras.putString(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
-                            mCaptivePortalUserAgent);
-                    mCm.startCaptivePortalApp(network, appExtras);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mLaunchCaptivePortalAppBroadcastReceiver != null) {
-                mContext.unregisterReceiver(mLaunchCaptivePortalAppBroadcastReceiver);
-                mLaunchCaptivePortalAppBroadcastReceiver = null;
-            }
-            hideProvisioningNotification();
-        }
-    }
-
-    // Being in the EvaluatingState State indicates the Network is being evaluated for internet
-    // connectivity, or that the user has indicated that this network is unwanted.
-    private class EvaluatingState extends State {
-        @Override
-        public void enter() {
-            // If we have already started to track time spent in EvaluatingState
-            // don't reset the timer due simply to, say, commands or events that
-            // cause us to exit and re-enter EvaluatingState.
-            if (!mEvaluationTimer.isStarted()) {
-                mEvaluationTimer.start();
-            }
-            sendMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
-            if (mUidResponsibleForReeval != INVALID_UID) {
-                TrafficStats.setThreadStatsUid(mUidResponsibleForReeval);
-                mUidResponsibleForReeval = INVALID_UID;
-            }
-            mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-            mEvaluateAttempts = 0;
-            // Reset all current probe results to zero, but retain current validation state until
-            // validation succeeds or fails.
-            mEvaluationState.clearProbeResults();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_REEVALUATE:
-                    if (message.arg1 != mReevaluateToken || mUserDoesNotWant) {
-                        return HANDLED;
-                    }
-                    // Don't bother validating networks that don't satisfy the default request.
-                    // This includes:
-                    //  - VPNs which can be considered explicitly desired by the user and the
-                    //    user's desire trumps whether the network validates.
-                    //  - Networks that don't provide Internet access.  It's unclear how to
-                    //    validate such networks.
-                    //  - Untrusted networks.  It's unsafe to prompt the user to sign-in to
-                    //    such networks and the user didn't express interest in connecting to
-                    //    such networks (an app did) so the user may be unhappily surprised when
-                    //    asked to sign-in to a network they didn't want to connect to in the
-                    //    first place.  Validation could be done to adjust the network scores
-                    //    however these networks are app-requested and may not be intended for
-                    //    general usage, in which case general validation may not be an accurate
-                    //    measure of the network's quality.  Only the app knows how to evaluate
-                    //    the network so don't bother validating here.  Furthermore sending HTTP
-                    //    packets over the network may be undesirable, for example an extremely
-                    //    expensive metered network, or unwanted leaking of the User Agent string.
-                    //
-                    // On networks that need to support private DNS in strict mode (e.g., VPNs, but
-                    // not networks that don't provide Internet access), we still need to perform
-                    // private DNS server resolution.
-                    if (!isValidationRequired()) {
-                        if (isPrivateDnsValidationRequired()) {
-                            validationLog("Network would not satisfy default request, "
-                                    + "resolving private DNS");
-                            transitionTo(mEvaluatingPrivateDnsState);
-                        } else {
-                            validationLog("Network would not satisfy default request, "
-                                    + "not validating");
-                            transitionTo(mValidatedState);
-                        }
-                        return HANDLED;
-                    }
-                    mEvaluateAttempts++;
-
-                    transitionTo(mProbingState);
-                    return HANDLED;
-                case CMD_FORCE_REEVALUATION:
-                    // Before IGNORE_REEVALUATE_ATTEMPTS attempts are made,
-                    // ignore any re-evaluation requests. After, restart the
-                    // evaluation process via EvaluatingState#enter.
-                    return (mEvaluateAttempts < IGNORE_REEVALUATE_ATTEMPTS) ? HANDLED : NOT_HANDLED;
-                // Disable HTTPS probe and transition to EvaluatingPrivateDnsState because:
-                // 1. Network is connected and finish the network validation.
-                // 2. NetworkMonitor detects network is partial connectivity and user accepts it.
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    maybeDisableHttpsProbing(true /* acceptPartial */);
-                    transitionTo(mEvaluatingPrivateDnsState);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            TrafficStats.clearThreadStatsUid();
-        }
-    }
-
-    // BroadcastReceiver that waits for a particular Intent and then posts a message.
-    private class CustomIntentReceiver extends BroadcastReceiver {
-        private final int mToken;
-        private final int mWhat;
-        private final String mAction;
-        CustomIntentReceiver(String action, int token, int what) {
-            mToken = token;
-            mWhat = what;
-            mAction = action + "_" + mCleartextDnsNetwork.getNetworkHandle() + "_" + token;
-            mContext.registerReceiver(this, new IntentFilter(mAction));
-        }
-        public PendingIntent getPendingIntent() {
-            final Intent intent = new Intent(mAction);
-            intent.setPackage(mContext.getPackageName());
-            return PendingIntent.getBroadcast(mContext, 0, intent, 0);
-        }
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(mAction)) sendMessage(obtainMessage(mWhat, mToken));
-        }
-    }
-
-    // Being in the CaptivePortalState State indicates a captive portal was detected and the user
-    // has been shown a notification to sign-in.
-    private class CaptivePortalState extends State {
-        private static final String ACTION_LAUNCH_CAPTIVE_PORTAL_APP =
-                "android.net.netmon.launchCaptivePortalApp";
-
-        @Override
-        public void enter() {
-            maybeLogEvaluationResult(
-                    networkEventType(validationStage(), EvaluationResult.CAPTIVE_PORTAL));
-            // Don't annoy user with sign-in notifications.
-            if (mDontDisplaySigninNotification) return;
-            // Create a CustomIntentReceiver that sends us a
-            // CMD_LAUNCH_CAPTIVE_PORTAL_APP message when the user
-            // touches the notification.
-            if (mLaunchCaptivePortalAppBroadcastReceiver == null) {
-                // Wait for result.
-                mLaunchCaptivePortalAppBroadcastReceiver = new CustomIntentReceiver(
-                        ACTION_LAUNCH_CAPTIVE_PORTAL_APP, new Random().nextInt(),
-                        CMD_LAUNCH_CAPTIVE_PORTAL_APP);
-                // Display the sign in notification.
-                // Only do this once for every time we enter MaybeNotifyState. b/122164725
-                showProvisioningNotification(mLaunchCaptivePortalAppBroadcastReceiver.mAction);
-            }
-            // Retest for captive portal occasionally.
-            sendMessageDelayed(CMD_CAPTIVE_PORTAL_RECHECK, 0 /* no UID */,
-                    CAPTIVE_PORTAL_REEVALUATE_DELAY_MS);
-            mValidations++;
-        }
-
-        @Override
-        public void exit() {
-            removeMessages(CMD_CAPTIVE_PORTAL_RECHECK);
-        }
-    }
-
-    private class EvaluatingPrivateDnsState extends State {
-        private int mPrivateDnsReevalDelayMs;
-        private PrivateDnsConfig mPrivateDnsConfig;
-
-        @Override
-        public void enter() {
-            mPrivateDnsReevalDelayMs = INITIAL_REEVALUATE_DELAY_MS;
-            mPrivateDnsConfig = null;
-            sendMessage(CMD_EVALUATE_PRIVATE_DNS);
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_EVALUATE_PRIVATE_DNS:
-                    if (inStrictMode()) {
-                        if (!isStrictModeHostnameResolved()) {
-                            resolveStrictModeHostname();
-
-                            if (isStrictModeHostnameResolved()) {
-                                notifyPrivateDnsConfigResolved();
-                            } else {
-                                handlePrivateDnsEvaluationFailure();
-                                break;
-                            }
-                        }
-
-                        // Look up a one-time hostname, to bypass caching.
-                        //
-                        // Note that this will race with ConnectivityService
-                        // code programming the DNS-over-TLS server IP addresses
-                        // into netd (if invoked, above). If netd doesn't know
-                        // the IP addresses yet, or if the connections to the IP
-                        // addresses haven't yet been validated, netd will block
-                        // for up to a few seconds before failing the lookup.
-                        if (!sendPrivateDnsProbe()) {
-                            handlePrivateDnsEvaluationFailure();
-                            break;
-                        }
-                    }
-
-                    // All good!
-                    transitionTo(mValidatedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        private boolean inStrictMode() {
-            return !TextUtils.isEmpty(mPrivateDnsProviderHostname);
-        }
-
-        private boolean isStrictModeHostnameResolved() {
-            return (mPrivateDnsConfig != null)
-                    && mPrivateDnsConfig.hostname.equals(mPrivateDnsProviderHostname)
-                    && (mPrivateDnsConfig.ips.length > 0);
-        }
-
-        private void resolveStrictModeHostname() {
-            try {
-                // Do a blocking DNS resolution using the network-assigned nameservers.
-                final InetAddress[] ips = DnsUtils.getAllByName(mDependencies.getDnsResolver(),
-                        mCleartextDnsNetwork, mPrivateDnsProviderHostname, getDnsProbeTimeout());
-                mPrivateDnsConfig = new PrivateDnsConfig(mPrivateDnsProviderHostname, ips);
-                validationLog("Strict mode hostname resolved: " + mPrivateDnsConfig);
-            } catch (UnknownHostException uhe) {
-                mPrivateDnsConfig = null;
-                validationLog("Strict mode hostname resolution failed: " + uhe.getMessage());
-            }
-            mEvaluationState.reportProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS,
-                    (mPrivateDnsConfig != null) /* succeeded */);
-        }
-
-        private void notifyPrivateDnsConfigResolved() {
-            try {
-                mCallback.notifyPrivateDnsConfigResolved(mPrivateDnsConfig.toParcel());
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error sending private DNS config resolved notification", e);
-            }
-        }
-
-        private void handlePrivateDnsEvaluationFailure() {
-            mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                    null /* redirectUrl */);
-            // Queue up a re-evaluation with backoff.
-            //
-            // TODO: Consider abandoning this state after a few attempts and
-            // transitioning back to EvaluatingState, to perhaps give ourselves
-            // the opportunity to (re)detect a captive portal or something.
-            //
-            // TODO: distinguish between CMD_EVALUATE_PRIVATE_DNS messages that are caused by server
-            // lookup failures (which should continue to do exponential backoff) and
-            // CMD_EVALUATE_PRIVATE_DNS messages that are caused by user reconfiguration (which
-            // should be processed immediately.
-            sendMessageDelayed(CMD_EVALUATE_PRIVATE_DNS, mPrivateDnsReevalDelayMs);
-            mPrivateDnsReevalDelayMs *= 2;
-            if (mPrivateDnsReevalDelayMs > MAX_REEVALUATE_DELAY_MS) {
-                mPrivateDnsReevalDelayMs = MAX_REEVALUATE_DELAY_MS;
-            }
-        }
-
-        private boolean sendPrivateDnsProbe() {
-            // q.v. system/netd/server/dns/DnsTlsTransport.cpp
-            final String oneTimeHostnameSuffix = "-dnsotls-ds.metric.gstatic.com";
-            final String host = UUID.randomUUID().toString().substring(0, 8)
-                    + oneTimeHostnameSuffix;
-            final Stopwatch watch = new Stopwatch().start();
-            boolean success = false;
-            long time;
-            try {
-                final InetAddress[] ips = mNetwork.getAllByName(host);
-                time = watch.stop();
-                final String strIps = Arrays.toString(ips);
-                success = (ips != null && ips.length > 0);
-                validationLog(PROBE_PRIVDNS, host, String.format("%dms: %s", time, strIps));
-            } catch (UnknownHostException uhe) {
-                time = watch.stop();
-                validationLog(PROBE_PRIVDNS, host,
-                        String.format("%dms - Error: %s", time, uhe.getMessage()));
-            }
-            logValidationProbe(time, PROBE_PRIVDNS, success ? DNS_SUCCESS : DNS_FAILURE);
-            mEvaluationState.reportProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS, success);
-            return success;
-        }
-    }
-
-    private class ProbingState extends State {
-        private Thread mThread;
-
-        @Override
-        public void enter() {
-            if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) {
-                //Don't continue to blame UID forever.
-                TrafficStats.clearThreadStatsUid();
-            }
-
-            final int token = ++mProbeToken;
-            mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0,
-                    isCaptivePortal())));
-            mThread.start();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_PROBE_COMPLETE:
-                    // Ensure that CMD_PROBE_COMPLETE from stale threads are ignored.
-                    if (message.arg1 != mProbeToken) {
-                        return HANDLED;
-                    }
-
-                    final CaptivePortalProbeResult probeResult =
-                            (CaptivePortalProbeResult) message.obj;
-                    mLastProbeTime = SystemClock.elapsedRealtime();
-
-                    if (mCollectDataStallMetrics) {
-                        writeDataStallStats(probeResult);
-                    }
-
-                    if (probeResult.isSuccessful()) {
-                        // Transit EvaluatingPrivateDnsState to get to Validated
-                        // state (even if no Private DNS validation required).
-                        transitionTo(mEvaluatingPrivateDnsState);
-                    } else if (probeResult.isPortal()) {
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                                probeResult.redirectUrl);
-                        mLastPortalProbeResult = probeResult;
-                        transitionTo(mCaptivePortalState);
-                    } else if (probeResult.isPartialConnectivity()) {
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
-                                null /* redirectUrl */);
-                        // Check if disable https probing needed.
-                        maybeDisableHttpsProbing(mAcceptPartialConnectivity);
-                        if (mAcceptPartialConnectivity) {
-                            transitionTo(mEvaluatingPrivateDnsState);
-                        } else {
-                            transitionTo(mWaitingForNextProbeState);
-                        }
-                    } else {
-                        logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
-                        mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
-                                null /* redirectUrl */);
-                        transitionTo(mWaitingForNextProbeState);
-                    }
-                    return HANDLED;
-                case EVENT_DNS_NOTIFICATION:
-                case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
-                    // Leave the event to DefaultState.
-                    return NOT_HANDLED;
-                default:
-                    // Wait for probe result and defer events to next state by default.
-                    deferMessage(message);
-                    return HANDLED;
-            }
-        }
-
-        @Override
-        public void exit() {
-            if (mThread.isAlive()) {
-                mThread.interrupt();
-            }
-            mThread = null;
-        }
-    }
-
-    // Being in the WaitingForNextProbeState indicates that evaluating probes failed and state is
-    // transited from ProbingState. This ensures that the state machine is only in ProbingState
-    // while a probe is in progress, not while waiting to perform the next probe. That allows
-    // ProbingState to defer most messages until the probe is complete, which keeps the code simple
-    // and matches the pre-Q behaviour where probes were a blocking operation performed on the state
-    // machine thread.
-    private class WaitingForNextProbeState extends State {
-        @Override
-        public void enter() {
-            scheduleNextProbe();
-        }
-
-        private void scheduleNextProbe() {
-            final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
-            sendMessageDelayed(msg, mReevaluateDelayMs);
-            mReevaluateDelayMs *= 2;
-            if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) {
-                mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS;
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            return NOT_HANDLED;
-        }
-    }
-
-    // Limits the list of IP addresses returned by getAllByName or tried by openConnection to at
-    // most one per address family. This ensures we only wait up to 20 seconds for TCP connections
-    // to complete, regardless of how many IP addresses a host has.
-    private static class OneAddressPerFamilyNetwork extends Network {
-        OneAddressPerFamilyNetwork(Network network) {
-            // Always bypass Private DNS.
-            super(network.getPrivateDnsBypassingCopy());
-        }
-
-        @Override
-        public InetAddress[] getAllByName(String host) throws UnknownHostException {
-            final List<InetAddress> addrs = Arrays.asList(super.getAllByName(host));
-
-            // Ensure the address family of the first address is tried first.
-            LinkedHashMap<Class, InetAddress> addressByFamily = new LinkedHashMap<>();
-            addressByFamily.put(addrs.get(0).getClass(), addrs.get(0));
-            Collections.shuffle(addrs);
-
-            for (InetAddress addr : addrs) {
-                addressByFamily.put(addr.getClass(), addr);
-            }
-
-            return addressByFamily.values().toArray(new InetAddress[addressByFamily.size()]);
-        }
-    }
-
-    private boolean getIsCaptivePortalCheckEnabled() {
-        String symbol = CAPTIVE_PORTAL_MODE;
-        int defaultValue = CAPTIVE_PORTAL_MODE_PROMPT;
-        int mode = mDependencies.getSetting(mContext, symbol, defaultValue);
-        return mode != CAPTIVE_PORTAL_MODE_IGNORE;
-    }
-
-    private boolean getUseHttpsValidation() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
-    }
-
-    private String getCaptivePortalServerHttpsUrl() {
-        return getSettingFromResource(mContext, R.string.config_captive_portal_https_url,
-                R.string.default_captive_portal_https_url, CAPTIVE_PORTAL_HTTPS_URL);
-    }
-
-    private int getDnsProbeTimeout() {
-        return getIntSetting(mContext, R.integer.config_captive_portal_dns_probe_timeout,
-                CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout);
-    }
-
-    /**
-     * Gets an integer setting from resources or device config
-     *
-     * configResource is used if set, followed by device config if set, followed by defaultResource.
-     * If none of these are set then an exception is thrown.
-     *
-     * TODO: move to a common location such as a ConfigUtils class.
-     * TODO(b/130324939): test that the resources can be overlayed by an RRO package.
-     */
-    @VisibleForTesting
-    int getIntSetting(@NonNull final Context context, @StringRes int configResource,
-            @NonNull String symbol, @StringRes int defaultResource) {
-        final Resources res = context.getResources();
-        try {
-            return res.getInteger(configResource);
-        } catch (Resources.NotFoundException e) {
-            return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                    symbol, res.getInteger(defaultResource));
-        }
-    }
-
-    /**
-     * Get the captive portal server HTTP URL that is configured on the device.
-     *
-     * NetworkMonitor does not use {@link ConnectivityManager#getCaptivePortalServerUrl()} as
-     * it has its own updatable strategies to detect captive portals. The framework only advises
-     * on one URL that can be used, while NetworkMonitor may implement more complex logic.
-     */
-    public String getCaptivePortalServerHttpUrl() {
-        return getSettingFromResource(mContext, R.string.config_captive_portal_http_url,
-                R.string.default_captive_portal_http_url, CAPTIVE_PORTAL_HTTP_URL);
-    }
-
-    private int getConsecutiveDnsTimeoutThreshold() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD,
-                DEFAULT_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD);
-    }
-
-    private int getDataStallMinEvaluateTime() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL,
-                DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS);
-    }
-
-    private int getDataStallValidDnsTimeThreshold() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD,
-                DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS);
-    }
-
-    private int getDataStallEvaluationType() {
-        return mDependencies.getDeviceConfigPropertyInt(NAMESPACE_CONNECTIVITY,
-                CONFIG_DATA_STALL_EVALUATION_TYPE,
-                DEFAULT_DATA_STALL_EVALUATION_TYPES);
-    }
-
-    private URL[] makeCaptivePortalFallbackUrls() {
-        try {
-            final String firstUrl = mDependencies.getSetting(mContext, CAPTIVE_PORTAL_FALLBACK_URL,
-                    null);
-
-            final URL[] settingProviderUrls;
-            if (!TextUtils.isEmpty(firstUrl)) {
-                final String otherUrls = mDependencies.getDeviceConfigProperty(
-                        NAMESPACE_CONNECTIVITY, CAPTIVE_PORTAL_OTHER_FALLBACK_URLS, "");
-                // otherUrls may be empty, but .split() ignores trailing empty strings
-                final String separator = ",";
-                final String[] urls = (firstUrl + separator + otherUrls).split(separator);
-                settingProviderUrls = convertStrings(urls, this::makeURL, new URL[0]);
-            } else {
-                settingProviderUrls = new URL[0];
-            }
-
-            return getArrayConfig(settingProviderUrls, R.array.config_captive_portal_fallback_urls,
-                    R.array.default_captive_portal_fallback_urls, this::makeURL);
-        } catch (Exception e) {
-            // Don't let a misconfiguration bootloop the system.
-            Log.e(TAG, "Error parsing configured fallback URLs", e);
-            return new URL[0];
-        }
-    }
-
-    private CaptivePortalProbeSpec[] makeCaptivePortalFallbackProbeSpecs() {
-        try {
-            final String settingsValue = mDependencies.getDeviceConfigProperty(
-                    NAMESPACE_CONNECTIVITY, CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS, null);
-
-            final CaptivePortalProbeSpec[] emptySpecs = new CaptivePortalProbeSpec[0];
-            final CaptivePortalProbeSpec[] providerValue = TextUtils.isEmpty(settingsValue)
-                    ? emptySpecs
-                    : parseCaptivePortalProbeSpecs(settingsValue).toArray(emptySpecs);
-
-            return getArrayConfig(providerValue, R.array.config_captive_portal_fallback_probe_specs,
-                    R.array.default_captive_portal_fallback_probe_specs,
-                    CaptivePortalProbeSpec::parseSpecOrNull);
-        } catch (Exception e) {
-            // Don't let a misconfiguration bootloop the system.
-            Log.e(TAG, "Error parsing configured fallback probe specs", e);
-            return null;
-        }
-    }
-
-    /**
-     * Read a setting from a resource or the settings provider.
-     *
-     * <p>The configuration resource is prioritized, then the provider value, then the default
-     * resource value.
-     * @param context The context
-     * @param configResource The resource id for the configuration parameter
-     * @param defaultResource The resource id for the default value
-     * @param symbol The symbol in the settings provider
-     * @return The best available value
-     */
-    @NonNull
-    private String getSettingFromResource(@NonNull final Context context,
-            @StringRes int configResource, @StringRes int defaultResource,
-            @NonNull String symbol) {
-        final Resources res = context.getResources();
-        String setting = res.getString(configResource);
-
-        if (!TextUtils.isEmpty(setting)) return setting;
-
-        setting = mDependencies.getSetting(context, symbol, null);
-        if (!TextUtils.isEmpty(setting)) return setting;
-
-        return res.getString(defaultResource);
-    }
-
-    /**
-     * Get an array configuration from resources or the settings provider.
-     *
-     * <p>The configuration resource is prioritized, then the provider values, then the default
-     * resource values.
-     * @param providerValue Values obtained from the setting provider.
-     * @param configResId ID of the configuration resource.
-     * @param defaultResId ID of the default resource.
-     * @param resourceConverter Converter from the resource strings to stored setting class. Null
-     *                          return values are ignored.
-     */
-    private <T> T[] getArrayConfig(@NonNull T[] providerValue, @ArrayRes int configResId,
-            @ArrayRes int defaultResId, @NonNull Function<String, T> resourceConverter) {
-        final Resources res = mContext.getResources();
-        String[] configValue = res.getStringArray(configResId);
-
-        if (configValue.length == 0) {
-            if (providerValue.length > 0) {
-                return providerValue;
-            }
-
-            configValue = res.getStringArray(defaultResId);
-        }
-
-        return convertStrings(configValue, resourceConverter, Arrays.copyOf(providerValue, 0));
-    }
-
-    /**
-     * Convert a String array to an array of some other type using the specified converter.
-     *
-     * <p>Any null value, or value for which the converter throws a {@link RuntimeException}, will
-     * not be added to the output array, so the output array may be smaller than the input.
-     */
-    private <T> T[] convertStrings(
-            @NonNull String[] strings, Function<String, T> converter, T[] emptyArray) {
-        final ArrayList<T> convertedValues = new ArrayList<>(strings.length);
-        for (String configString : strings) {
-            T convertedValue = null;
-            try {
-                convertedValue = converter.apply(configString);
-            } catch (Exception e) {
-                Log.e(TAG, "Error parsing configuration", e);
-                // Fall through
-            }
-            if (convertedValue != null) {
-                convertedValues.add(convertedValue);
-            }
-        }
-        return convertedValues.toArray(emptyArray);
-    }
-
-    private String getCaptivePortalUserAgent() {
-        return mDependencies.getDeviceConfigProperty(NAMESPACE_CONNECTIVITY,
-                CAPTIVE_PORTAL_USER_AGENT, DEFAULT_USER_AGENT);
-    }
-
-    private URL nextFallbackUrl() {
-        if (mCaptivePortalFallbackUrls.length == 0) {
-            return null;
-        }
-        int idx = Math.abs(mNextFallbackUrlIndex) % mCaptivePortalFallbackUrls.length;
-        mNextFallbackUrlIndex += mRandom.nextInt(); // randomly change url without memory.
-        return mCaptivePortalFallbackUrls[idx];
-    }
-
-    private CaptivePortalProbeSpec nextFallbackSpec() {
-        if (isEmpty(mCaptivePortalFallbackSpecs)) {
-            return null;
-        }
-        // Randomly change spec without memory. Also randomize the first attempt.
-        final int idx = Math.abs(mRandom.nextInt()) % mCaptivePortalFallbackSpecs.length;
-        return mCaptivePortalFallbackSpecs[idx];
-    }
-
-    @VisibleForTesting
-    protected CaptivePortalProbeResult isCaptivePortal() {
-        if (!mIsCaptivePortalCheckEnabled) {
-            validationLog("Validation disabled.");
-            return CaptivePortalProbeResult.SUCCESS;
-        }
-
-        URL pacUrl = null;
-        URL httpsUrl = mCaptivePortalHttpsUrl;
-        URL httpUrl = mCaptivePortalHttpUrl;
-
-        // On networks with a PAC instead of fetching a URL that should result in a 204
-        // response, we instead simply fetch the PAC script.  This is done for a few reasons:
-        // 1. At present our PAC code does not yet handle multiple PACs on multiple networks
-        //    until something like https://android-review.googlesource.com/#/c/115180/ lands.
-        //    Network.openConnection() will ignore network-specific PACs and instead fetch
-        //    using NO_PROXY.  If a PAC is in place, the only fetch we know will succeed with
-        //    NO_PROXY is the fetch of the PAC itself.
-        // 2. To proxy the generate_204 fetch through a PAC would require a number of things
-        //    happen before the fetch can commence, namely:
-        //        a) the PAC script be fetched
-        //        b) a PAC script resolver service be fired up and resolve the captive portal
-        //           server.
-        //    Network validation could be delayed until these prerequisities are satisifed or
-        //    could simply be left to race them.  Neither is an optimal solution.
-        // 3. PAC scripts are sometimes used to block or restrict Internet access and may in
-        //    fact block fetching of the generate_204 URL which would lead to false negative
-        //    results for network validation.
-        final ProxyInfo proxyInfo = mLinkProperties.getHttpProxy();
-        if (proxyInfo != null && !Uri.EMPTY.equals(proxyInfo.getPacFileUrl())) {
-            pacUrl = makeURL(proxyInfo.getPacFileUrl().toString());
-            if (pacUrl == null) {
-                return CaptivePortalProbeResult.FAILED;
-            }
-        }
-
-        if ((pacUrl == null) && (httpUrl == null || httpsUrl == null)) {
-            return CaptivePortalProbeResult.FAILED;
-        }
-
-        long startTime = SystemClock.elapsedRealtime();
-
-        final CaptivePortalProbeResult result;
-        if (pacUrl != null) {
-            result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
-        } else if (mUseHttps) {
-            // Probe results are reported inside sendParallelHttpProbes.
-            result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl);
-        } else {
-            result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
-        }
-
-        long endTime = SystemClock.elapsedRealtime();
-
-        sendNetworkConditionsBroadcast(true /* response received */,
-                result.isPortal() /* isCaptivePortal */,
-                startTime, endTime);
-
-        log("isCaptivePortal: isSuccessful()=" + result.isSuccessful()
-                + " isPortal()=" + result.isPortal()
-                + " RedirectUrl=" + result.redirectUrl
-                + " isPartialConnectivity()=" + result.isPartialConnectivity()
-                + " Time=" + (endTime - startTime) + "ms");
-
-        return result;
-    }
-
-    /**
-     * Do a DNS resolution and URL fetch on a known web server to see if we get the data we expect.
-     * @return a CaptivePortalProbeResult inferred from the HTTP response.
-     */
-    private CaptivePortalProbeResult sendDnsAndHttpProbes(ProxyInfo proxy, URL url, int probeType) {
-        // Pre-resolve the captive portal server host so we can log it.
-        // Only do this if HttpURLConnection is about to, to avoid any potentially
-        // unnecessary resolution.
-        final String host = (proxy != null) ? proxy.getHost() : url.getHost();
-        // This method cannot safely report probe results because it might not be running on the
-        // state machine thread. Reporting results here would cause races and potentially send
-        // information to callers that does not make sense because the state machine has already
-        // changed state.
-        sendDnsProbe(host);
-        return sendHttpProbe(url, probeType, null);
-    }
-
-    /** Do a DNS lookup for the given server, or throw UnknownHostException after timeoutMs */
-    @VisibleForTesting
-    protected InetAddress[] sendDnsProbeWithTimeout(String host, int timeoutMs)
-                throws UnknownHostException {
-        return DnsUtils.getAllByName(mDependencies.getDnsResolver(), mCleartextDnsNetwork, host,
-                TYPE_ADDRCONFIG, FLAG_EMPTY, timeoutMs);
-    }
-
-    /** Do a DNS resolution of the given server. */
-    private void sendDnsProbe(String host) {
-        if (TextUtils.isEmpty(host)) {
-            return;
-        }
-
-        final String name = ValidationProbeEvent.getProbeName(ValidationProbeEvent.PROBE_DNS);
-        final Stopwatch watch = new Stopwatch().start();
-        int result;
-        String connectInfo;
-        try {
-            InetAddress[] addresses = sendDnsProbeWithTimeout(host, getDnsProbeTimeout());
-            StringBuffer buffer = new StringBuffer();
-            for (InetAddress address : addresses) {
-                buffer.append(',').append(address.getHostAddress());
-            }
-            result = ValidationProbeEvent.DNS_SUCCESS;
-            connectInfo = "OK " + buffer.substring(1);
-        } catch (UnknownHostException e) {
-            result = ValidationProbeEvent.DNS_FAILURE;
-            connectInfo = "FAIL";
-        }
-        final long latency = watch.stop();
-        validationLog(ValidationProbeEvent.PROBE_DNS, host,
-                String.format("%dms %s", latency, connectInfo));
-        logValidationProbe(latency, ValidationProbeEvent.PROBE_DNS, result);
-    }
-
-    /**
-     * Do a URL fetch on a known web server to see if we get the data we expect.
-     * @return a CaptivePortalProbeResult inferred from the HTTP response.
-     */
-    @VisibleForTesting
-    protected CaptivePortalProbeResult sendHttpProbe(URL url, int probeType,
-            @Nullable CaptivePortalProbeSpec probeSpec) {
-        HttpURLConnection urlConnection = null;
-        int httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-        String redirectUrl = null;
-        final Stopwatch probeTimer = new Stopwatch().start();
-        final int oldTag = TrafficStats.getAndSetThreadStatsTag(
-                TrafficStatsConstants.TAG_SYSTEM_PROBE);
-        try {
-            urlConnection = (HttpURLConnection) mCleartextDnsNetwork.openConnection(url);
-            urlConnection.setInstanceFollowRedirects(probeType == ValidationProbeEvent.PROBE_PAC);
-            urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
-            urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
-            urlConnection.setRequestProperty("Connection", "close");
-            urlConnection.setUseCaches(false);
-            if (mCaptivePortalUserAgent != null) {
-                urlConnection.setRequestProperty("User-Agent", mCaptivePortalUserAgent);
-            }
-            // cannot read request header after connection
-            String requestHeader = urlConnection.getRequestProperties().toString();
-
-            // Time how long it takes to get a response to our request
-            long requestTimestamp = SystemClock.elapsedRealtime();
-
-            httpResponseCode = urlConnection.getResponseCode();
-            redirectUrl = urlConnection.getHeaderField("location");
-
-            // Time how long it takes to get a response to our request
-            long responseTimestamp = SystemClock.elapsedRealtime();
-
-            validationLog(probeType, url, "time=" + (responseTimestamp - requestTimestamp) + "ms"
-                    + " ret=" + httpResponseCode
-                    + " request=" + requestHeader
-                    + " headers=" + urlConnection.getHeaderFields());
-            // NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive
-            // portal.  The only example of this seen so far was a captive portal.  For
-            // the time being go with prior behavior of assuming it's not a captive
-            // portal.  If it is considered a captive portal, a different sign-in URL
-            // is needed (i.e. can't browse a 204).  This could be the result of an HTTP
-            // proxy server.
-            if (httpResponseCode == 200) {
-                long contentLength = urlConnection.getContentLengthLong();
-                if (probeType == ValidationProbeEvent.PROBE_PAC) {
-                    validationLog(
-                            probeType, url, "PAC fetch 200 response interpreted as 204 response.");
-                    httpResponseCode = CaptivePortalProbeResult.SUCCESS_CODE;
-                } else if (contentLength == -1) {
-                    // When no Content-length (default value == -1), attempt to read a byte
-                    // from the response. Do not use available() as it is unreliable.
-                    // See http://b/33498325.
-                    if (urlConnection.getInputStream().read() == -1) {
-                        validationLog(probeType, url,
-                                "Empty 200 response interpreted as failed response.");
-                        httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-                    }
-                } else if (contentLength <= 4) {
-                    // Consider 200 response with "Content-length <= 4" to not be a captive
-                    // portal. There's no point in considering this a captive portal as the
-                    // user cannot sign-in to an empty page. Probably the result of a broken
-                    // transparent proxy. See http://b/9972012 and http://b/122999481.
-                    validationLog(probeType, url, "200 response with Content-length <= 4"
-                            + " interpreted as failed response.");
-                    httpResponseCode = CaptivePortalProbeResult.FAILED_CODE;
-                }
-            }
-        } catch (IOException e) {
-            validationLog(probeType, url, "Probe failed with exception " + e);
-            if (httpResponseCode == CaptivePortalProbeResult.FAILED_CODE) {
-                // TODO: Ping gateway and DNS server and log results.
-            }
-        } finally {
-            if (urlConnection != null) {
-                urlConnection.disconnect();
-            }
-            TrafficStats.setThreadStatsTag(oldTag);
-        }
-        logValidationProbe(probeTimer.stop(), probeType, httpResponseCode);
-
-        if (probeSpec == null) {
-            return new CaptivePortalProbeResult(httpResponseCode, redirectUrl, url.toString());
-        } else {
-            return probeSpec.getResult(httpResponseCode, redirectUrl);
-        }
-    }
-
-    private CaptivePortalProbeResult sendParallelHttpProbes(
-            ProxyInfo proxy, URL httpsUrl, URL httpUrl) {
-        // Number of probes to wait for. If a probe completes with a conclusive answer
-        // it shortcuts the latch immediately by forcing the count to 0.
-        final CountDownLatch latch = new CountDownLatch(2);
-
-        final class ProbeThread extends Thread {
-            private final boolean mIsHttps;
-            private volatile CaptivePortalProbeResult mResult = CaptivePortalProbeResult.FAILED;
-
-            ProbeThread(boolean isHttps) {
-                mIsHttps = isHttps;
-            }
-
-            public CaptivePortalProbeResult result() {
-                return mResult;
-            }
-
-            @Override
-            public void run() {
-                if (mIsHttps) {
-                    mResult =
-                            sendDnsAndHttpProbes(proxy, httpsUrl, ValidationProbeEvent.PROBE_HTTPS);
-                } else {
-                    mResult = sendDnsAndHttpProbes(proxy, httpUrl, ValidationProbeEvent.PROBE_HTTP);
-                }
-                if ((mIsHttps && mResult.isSuccessful()) || (!mIsHttps && mResult.isPortal())) {
-                    // Stop waiting immediately if https succeeds or if http finds a portal.
-                    while (latch.getCount() > 0) {
-                        latch.countDown();
-                    }
-                }
-                // Signal this probe has completed.
-                latch.countDown();
-            }
-        }
-
-        final ProbeThread httpsProbe = new ProbeThread(true);
-        final ProbeThread httpProbe = new ProbeThread(false);
-
-        try {
-            httpsProbe.start();
-            httpProbe.start();
-            latch.await(PROBE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            validationLog("Error: probes wait interrupted!");
-            return CaptivePortalProbeResult.FAILED;
-        }
-
-        final CaptivePortalProbeResult httpsResult = httpsProbe.result();
-        final CaptivePortalProbeResult httpResult = httpProbe.result();
-
-        // Look for a conclusive probe result first.
-        if (httpResult.isPortal()) {
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpResult);
-            return httpResult;
-        }
-        // httpsResult.isPortal() is not expected, but check it nonetheless.
-        if (httpsResult.isPortal() || httpsResult.isSuccessful()) {
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsResult);
-            return httpsResult;
-        }
-        // If a fallback method exists, use it to retry portal detection.
-        // If we have new-style probe specs, use those. Otherwise, use the fallback URLs.
-        final CaptivePortalProbeSpec probeSpec = nextFallbackSpec();
-        final URL fallbackUrl = (probeSpec != null) ? probeSpec.getUrl() : nextFallbackUrl();
-        CaptivePortalProbeResult fallbackProbeResult = null;
-        if (fallbackUrl != null) {
-            fallbackProbeResult = sendHttpProbe(fallbackUrl, PROBE_FALLBACK, probeSpec);
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_FALLBACK, fallbackProbeResult);
-            if (fallbackProbeResult.isPortal()) {
-                return fallbackProbeResult;
-            }
-        }
-        // Otherwise wait until http and https probes completes and use their results.
-        try {
-            httpProbe.join();
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpProbe.result());
-
-            if (httpProbe.result().isPortal()) {
-                return httpProbe.result();
-            }
-
-            httpsProbe.join();
-            reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsProbe.result());
-
-            final boolean isHttpSuccessful =
-                    (httpProbe.result().isSuccessful()
-                    || (fallbackProbeResult != null && fallbackProbeResult.isSuccessful()));
-            if (httpsProbe.result().isFailed() && isHttpSuccessful) {
-                return CaptivePortalProbeResult.PARTIAL;
-            }
-            return httpsProbe.result();
-        } catch (InterruptedException e) {
-            validationLog("Error: http or https probe wait interrupted!");
-            return CaptivePortalProbeResult.FAILED;
-        }
-    }
-
-    private URL makeURL(String url) {
-        if (url != null) {
-            try {
-                return new URL(url);
-            } catch (MalformedURLException e) {
-                validationLog("Bad URL: " + url);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * @param responseReceived - whether or not we received a valid HTTP response to our request.
-     * If false, isCaptivePortal and responseTimestampMs are ignored
-     * TODO: This should be moved to the transports.  The latency could be passed to the transports
-     * along with the captive portal result.  Currently the TYPE_MOBILE broadcasts appear unused so
-     * perhaps this could just be added to the WiFi transport only.
-     */
-    private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal,
-            long requestTimestampMs, long responseTimestampMs) {
-        Intent latencyBroadcast =
-                new Intent(NetworkMonitorUtils.ACTION_NETWORK_CONDITIONS_MEASURED);
-        if (mNetworkCapabilities.hasTransport(TRANSPORT_WIFI)) {
-            if (!mWifiManager.isScanAlwaysAvailable()) {
-                return;
-            }
-
-            WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
-            if (currentWifiInfo != null) {
-                // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not
-                // surrounded by double quotation marks (thus violating the Javadoc), but this
-                // was changed to match the Javadoc in API 17. Since clients may have started
-                // sanitizing the output of this method since API 17 was released, we should
-                // not change it here as it would become impossible to tell whether the SSID is
-                // simply being surrounded by quotes due to the API, or whether those quotes
-                // are actually part of the SSID.
-                latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_SSID,
-                        currentWifiInfo.getSSID());
-                latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_BSSID,
-                        currentWifiInfo.getBSSID());
-            } else {
-                if (VDBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
-                return;
-            }
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_WIFI);
-        } else if (mNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
-            // TODO(b/123893112): Support multi-sim.
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_NETWORK_TYPE,
-                    mTelephonyManager.getNetworkType());
-            final ServiceState dataSs = mTelephonyManager.getServiceState();
-            if (dataSs == null) {
-                logw("failed to retrieve ServiceState");
-                return;
-            }
-            // See if the data sub is registered for PS services on cell.
-            final NetworkRegistrationInfo nri = dataSs.getNetworkRegistrationInfo(
-                    NetworkRegistrationInfo.DOMAIN_PS,
-                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-            latencyBroadcast.putExtra(
-                    NetworkMonitorUtils.EXTRA_CELL_ID,
-                    nri == null ? null : nri.getCellIdentity());
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_CONNECTIVITY_TYPE, TYPE_MOBILE);
-        } else {
-            return;
-        }
-        latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_RESPONSE_RECEIVED,
-                responseReceived);
-        latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_REQUEST_TIMESTAMP_MS,
-                requestTimestampMs);
-
-        if (responseReceived) {
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_IS_CAPTIVE_PORTAL,
-                    isCaptivePortal);
-            latencyBroadcast.putExtra(NetworkMonitorUtils.EXTRA_RESPONSE_TIMESTAMP_MS,
-                    responseTimestampMs);
-        }
-        mContext.sendBroadcastAsUser(latencyBroadcast, UserHandle.CURRENT,
-                NetworkMonitorUtils.PERMISSION_ACCESS_NETWORK_CONDITIONS);
-    }
-
-    private void logNetworkEvent(int evtype) {
-        int[] transports = mNetworkCapabilities.getTransportTypes();
-        mMetricsLog.log(mCleartextDnsNetwork, transports, new NetworkEvent(evtype));
-    }
-
-    private int networkEventType(ValidationStage s, EvaluationResult r) {
-        if (s.mIsFirstValidation) {
-            if (r.mIsValidated) {
-                return NetworkEvent.NETWORK_FIRST_VALIDATION_SUCCESS;
-            } else {
-                return NetworkEvent.NETWORK_FIRST_VALIDATION_PORTAL_FOUND;
-            }
-        } else {
-            if (r.mIsValidated) {
-                return NetworkEvent.NETWORK_REVALIDATION_SUCCESS;
-            } else {
-                return NetworkEvent.NETWORK_REVALIDATION_PORTAL_FOUND;
-            }
-        }
-    }
-
-    private void maybeLogEvaluationResult(int evtype) {
-        if (mEvaluationTimer.isRunning()) {
-            int[] transports = mNetworkCapabilities.getTransportTypes();
-            mMetricsLog.log(mCleartextDnsNetwork, transports,
-                    new NetworkEvent(evtype, mEvaluationTimer.stop()));
-            mEvaluationTimer.reset();
-        }
-    }
-
-    private void logValidationProbe(long durationMs, int probeType, int probeResult) {
-        int[] transports = mNetworkCapabilities.getTransportTypes();
-        boolean isFirstValidation = validationStage().mIsFirstValidation;
-        ValidationProbeEvent ev = new ValidationProbeEvent.Builder()
-                .setProbeType(probeType, isFirstValidation)
-                .setReturnCode(probeResult)
-                .setDurationMs(durationMs)
-                .build();
-        mMetricsLog.log(mCleartextDnsNetwork, transports, ev);
-    }
-
-    @VisibleForTesting
-    static class Dependencies {
-        public Network getPrivateDnsBypassNetwork(Network network) {
-            return new OneAddressPerFamilyNetwork(network);
-        }
-
-        public DnsResolver getDnsResolver() {
-            return DnsResolver.getInstance();
-        }
-
-        public Random getRandom() {
-            return new Random();
-        }
-
-        /**
-         * Get the value of a global integer setting.
-         * @param symbol Name of the setting
-         * @param defaultValue Value to return if the setting is not defined.
-         */
-        public int getSetting(Context context, String symbol, int defaultValue) {
-            return Settings.Global.getInt(context.getContentResolver(), symbol, defaultValue);
-        }
-
-        /**
-         * Get the value of a global String setting.
-         * @param symbol Name of the setting
-         * @param defaultValue Value to return if the setting is not defined.
-         */
-        public String getSetting(Context context, String symbol, String defaultValue) {
-            final String value = Settings.Global.getString(context.getContentResolver(), symbol);
-            return value != null ? value : defaultValue;
-        }
-
-        /**
-         * Look up the value of a property in 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 String getDeviceConfigProperty(@NonNull String namespace, @NonNull String name,
-                @Nullable String defaultValue) {
-            return NetworkStackUtils.getDeviceConfigProperty(namespace, name, defaultValue);
-        }
-
-        /**
-         * Look up the value of a property in 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.
-         */
-        public int getDeviceConfigPropertyInt(@NonNull String namespace, @NonNull String name,
-                int defaultValue) {
-            return NetworkStackUtils.getDeviceConfigPropertyInt(namespace, name, defaultValue);
-        }
-
-        public static final Dependencies DEFAULT = new Dependencies();
-    }
-
-    /**
-     * Methods in this class perform no locking because all accesses are performed on the state
-     * machine's thread. Need to consider the thread safety if it ever could be accessed outside the
-     * state machine.
-     */
-    @VisibleForTesting
-    protected class DnsStallDetector {
-        private int mConsecutiveTimeoutCount = 0;
-        private int mSize;
-        final DnsResult[] mDnsEvents;
-        final RingBufferIndices mResultIndices;
-
-        DnsStallDetector(int size) {
-            mSize = Math.max(DEFAULT_DNS_LOG_SIZE, size);
-            mDnsEvents = new DnsResult[mSize];
-            mResultIndices = new RingBufferIndices(mSize);
-        }
-
-        @VisibleForTesting
-        protected void accumulateConsecutiveDnsTimeoutCount(int code) {
-            final DnsResult result = new DnsResult(code);
-            mDnsEvents[mResultIndices.add()] = result;
-            if (result.isTimeout()) {
-                mConsecutiveTimeoutCount++;
-            } else {
-                // Keep the event in mDnsEvents without clearing it so that there are logs to do the
-                // simulation and analysis.
-                mConsecutiveTimeoutCount = 0;
-            }
-        }
-
-        private boolean isDataStallSuspected(int timeoutCountThreshold, int validTime) {
-            if (timeoutCountThreshold <= 0) {
-                Log.wtf(TAG, "Timeout count threshold should be larger than 0.");
-                return false;
-            }
-
-            // Check if the consecutive timeout count reach the threshold or not.
-            if (mConsecutiveTimeoutCount < timeoutCountThreshold) {
-                return false;
-            }
-
-            // Check if the target dns event index is valid or not.
-            final int firstConsecutiveTimeoutIndex =
-                    mResultIndices.indexOf(mResultIndices.size() - timeoutCountThreshold);
-
-            // If the dns timeout events happened long time ago, the events are meaningless for
-            // data stall evaluation. Thus, check if the first consecutive timeout dns event
-            // considered in the evaluation happened in defined threshold time.
-            final long now = SystemClock.elapsedRealtime();
-            final long firstTimeoutTime = now - mDnsEvents[firstConsecutiveTimeoutIndex].mTimeStamp;
-            return (firstTimeoutTime < validTime);
-        }
-
-        int getConsecutiveTimeoutCount() {
-            return mConsecutiveTimeoutCount;
-        }
-    }
-
-    private static class DnsResult {
-        // TODO: Need to move the DNS return code definition to a specific class once unify DNS
-        // response code is done.
-        private static final int RETURN_CODE_DNS_TIMEOUT = 255;
-
-        private final long mTimeStamp;
-        private final int mReturnCode;
-
-        DnsResult(int code) {
-            mTimeStamp = SystemClock.elapsedRealtime();
-            mReturnCode = code;
-        }
-
-        private boolean isTimeout() {
-            return mReturnCode == RETURN_CODE_DNS_TIMEOUT;
-        }
-    }
-
-
-    @VisibleForTesting
-    protected DnsStallDetector getDnsStallDetector() {
-        return mDnsStallDetector;
-    }
-
-    private boolean dataStallEvaluateTypeEnabled(int type) {
-        return (mDataStallEvaluationType & type) != 0;
-    }
-
-    @VisibleForTesting
-    protected long getLastProbeTime() {
-        return mLastProbeTime;
-    }
-
-    @VisibleForTesting
-    protected boolean isDataStall() {
-        boolean result = false;
-        // Reevaluation will generate traffic. Thus, set a minimal reevaluation timer to limit the
-        // possible traffic cost in metered network.
-        if (!mNetworkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)
-                && (SystemClock.elapsedRealtime() - getLastProbeTime()
-                < mDataStallMinEvaluateTime)) {
-            return false;
-        }
-
-        // Check dns signal. Suspect it may be a data stall if both :
-        // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold.
-        // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms.
-        if (dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) {
-            if (mDnsStallDetector.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold,
-                    mDataStallValidDnsTimeThreshold)) {
-                result = true;
-                logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND);
-            }
-        }
-
-        if (VDBG_STALL) {
-            log("isDataStall: result=" + result + ", consecutive dns timeout count="
-                    + mDnsStallDetector.getConsecutiveTimeoutCount());
-        }
-
-        return result;
-    }
-
-    // Class to keep state of evaluation results and probe results.
-    // The main purpose is to ensure NetworkMonitor can notify ConnectivityService of probe results
-    // as soon as they happen, without triggering any other changes. This requires keeping state on
-    // the most recent evaluation result. Calling reportProbeResult will ensure that the results
-    // reported to ConnectivityService contain the previous evaluation result, and thus won't
-    // trigger a validation or partial connectivity state change.
-    @VisibleForTesting
-    protected class EvaluationState {
-        // The latest validation result for this network. This is a bitmask of
-        // INetworkMonitor.NETWORK_VALIDATION_RESULT_* constants.
-        private int mEvaluationResult = NETWORK_VALIDATION_RESULT_INVALID;
-        // Indicates which probes have completed since clearProbeResults was called.
-        // This is a bitmask of INetworkMonitor.NETWORK_VALIDATION_PROBE_* constants.
-        private int mProbeResults = 0;
-        // The latest redirect URL.
-        private String mRedirectUrl;
-
-        protected void clearProbeResults() {
-            mProbeResults = 0;
-        }
-
-        // Probe result for http probe should be updated from reportHttpProbeResult().
-        protected void reportProbeResult(int probeResult, boolean succeeded) {
-            if (succeeded) {
-                mProbeResults |= probeResult;
-            } else {
-                mProbeResults &= ~probeResult;
-            }
-            notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
-        }
-
-        protected void reportEvaluationResult(int result, @Nullable String redirectUrl) {
-            mEvaluationResult = result;
-            mRedirectUrl = redirectUrl;
-            notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
-        }
-
-        protected int getNetworkTestResult() {
-            return mEvaluationResult | mProbeResults;
-        }
-    }
-
-    @VisibleForTesting
-    protected EvaluationState getEvaluationState() {
-        return mEvaluationState;
-    }
-
-    private void maybeDisableHttpsProbing(boolean acceptPartial) {
-        mAcceptPartialConnectivity = acceptPartial;
-        // Ignore https probe in next validation if user accept partial connectivity on a partial
-        // connectivity network.
-        if (((mEvaluationState.getNetworkTestResult() & NETWORK_VALIDATION_RESULT_PARTIAL) != 0)
-                && mAcceptPartialConnectivity) {
-            mUseHttps = false;
-        }
-    }
-
-    // Report HTTP, HTTP or FALLBACK probe result.
-    @VisibleForTesting
-    protected void reportHttpProbeResult(int probeResult,
-                @NonNull final CaptivePortalProbeResult result) {
-        boolean succeeded = result.isSuccessful();
-        // The success of a HTTP probe does not tell us whether the DNS probe succeeded.
-        // The DNS and HTTP probes run one after the other in sendDnsAndHttpProbes, and that
-        // method cannot report the result of the DNS probe because that it could be running
-        // on a different thread which is racing with the main state machine thread. So, if
-        // an HTTP or HTTPS probe succeeded, assume that the DNS probe succeeded. But if an
-        // HTTP or HTTPS probe failed, don't assume that DNS is not working.
-        // TODO: fix this.
-        if (succeeded) {
-            probeResult |= NETWORK_VALIDATION_PROBE_DNS;
-        }
-        mEvaluationState.reportProbeResult(probeResult, succeeded);
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
deleted file mode 100644
index a538a5b..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java
+++ /dev/null
@@ -1,703 +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.server.connectivity.ipmemorystore;
-
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteCursor;
-import android.database.sqlite.SQLiteCursorDriver;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQuery;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.Status;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringJoiner;
-
-/**
- * Encapsulating class for using the SQLite database backing the memory store.
- *
- * This class groups together the contracts and the SQLite helper used to
- * use the database.
- *
- * @hide
- */
-public class IpMemoryStoreDatabase {
-    private static final String TAG = IpMemoryStoreDatabase.class.getSimpleName();
-    // A pair of NetworkAttributes objects is group-close if the confidence that they are
-    // the same is above this cutoff. See NetworkAttributes and SameL3NetworkResponse.
-    private static final float GROUPCLOSE_CONFIDENCE = 0.5f;
-
-    /**
-     * Contract class for the Network Attributes table.
-     */
-    public static class NetworkAttributesContract {
-        public static final String TABLENAME = "NetworkAttributes";
-
-        public static final String COLNAME_L2KEY = "l2Key";
-        public static final String COLTYPE_L2KEY = "TEXT NOT NULL";
-
-        public static final String COLNAME_EXPIRYDATE = "expiryDate";
-        // Milliseconds since the Epoch, in true Java style
-        public static final String COLTYPE_EXPIRYDATE = "BIGINT";
-
-        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.
-        public static final String COLNAME_GROUPHINT = "groupHint";
-        public static final String COLTYPE_GROUPHINT = "TEXT";
-
-        public static final String COLNAME_DNSADDRESSES = "dnsAddresses";
-        // Stored in marshalled form as is
-        public static final String COLTYPE_DNSADDRESSES = "BLOB";
-
-        public static final String COLNAME_MTU = "mtu";
-        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_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;
-    }
-
-    /**
-     * Contract class for the Private Data table.
-     */
-    public static class PrivateDataContract {
-        public static final String TABLENAME = "PrivateData";
-
-        public static final String COLNAME_L2KEY = "l2Key";
-        public static final String COLTYPE_L2KEY = "TEXT NOT NULL";
-
-        public static final String COLNAME_CLIENT = "client";
-        public static final String COLTYPE_CLIENT = "TEXT NOT NULL";
-
-        public static final String COLNAME_DATANAME = "dataName";
-        public static final String COLTYPE_DATANAME = "TEXT NOT NULL";
-
-        public static final String COLNAME_DATA = "data";
-        public static final String COLTYPE_DATA = "BLOB NOT NULL";
-
-        public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
-                + TABLENAME        + " ("
-                + COLNAME_L2KEY    + " " + COLTYPE_L2KEY    + ", "
-                + COLNAME_CLIENT   + " " + COLTYPE_CLIENT   + ", "
-                + COLNAME_DATANAME + " " + COLTYPE_DATANAME + ", "
-                + COLNAME_DATA     + " " + COLTYPE_DATA     + ", "
-                + "PRIMARY KEY ("
-                + COLNAME_L2KEY    + ", "
-                + COLNAME_CLIENT   + ", "
-                + COLNAME_DATANAME + "))";
-        public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLENAME;
-    }
-
-    // To save memory when the DB is not used, close it after 30s of inactivity. This is
-    // determined manually based on what feels right.
-    private static final long IDLE_CONNECTION_TIMEOUT_MS = 30_000;
-
-    /** The SQLite DB helper */
-    public static class DbHelper extends SQLiteOpenHelper {
-        // Update this whenever changing the schema.
-        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);
-            setIdleConnectionTimeout(IDLE_CONNECTION_TIMEOUT_MS);
-        }
-
-        /** Called when the database is created */
-        @Override
-        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) {
-            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 */
-        @Override
-        public void onDowngrade(@NonNull final SQLiteDatabase db, final int oldVersion,
-                final int newVersion) {
-            // 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
-    private static byte[] encodeAddressList(@NonNull final List<InetAddress> addresses) {
-        final ByteArrayOutputStream os = new ByteArrayOutputStream();
-        for (final InetAddress address : addresses) {
-            final byte[] b = address.getAddress();
-            os.write(b.length);
-            os.write(b, 0, b.length);
-        }
-        return os.toByteArray();
-    }
-
-    @NonNull
-    private static ArrayList<InetAddress> decodeAddressList(@NonNull final byte[] encoded) {
-        final ByteArrayInputStream is = new ByteArrayInputStream(encoded);
-        final ArrayList<InetAddress> addresses = new ArrayList<>();
-        int d = -1;
-        while ((d = is.read()) != -1) {
-            final byte[] bytes = new byte[d];
-            is.read(bytes, 0, d);
-            try {
-                addresses.add(InetAddress.getByAddress(bytes));
-            } catch (UnknownHostException e) { /* Hopefully impossible */ }
-        }
-        return addresses;
-    }
-
-    @NonNull
-    private static ContentValues toContentValues(@Nullable final NetworkAttributes attributes) {
-        final ContentValues values = new ContentValues();
-        if (null == attributes) return values;
-        if (null != attributes.assignedV4Address) {
-            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);
-        }
-        if (null != attributes.dnsAddresses) {
-            values.put(NetworkAttributesContract.COLNAME_DNSADDRESSES,
-                    encodeAddressList(attributes.dnsAddresses));
-        }
-        if (null != attributes.mtu) {
-            values.put(NetworkAttributesContract.COLNAME_MTU, attributes.mtu);
-        }
-        return values;
-    }
-
-    // Convert a NetworkAttributes object to content values to store them in a table compliant
-    // with the contract defined in NetworkAttributesContract.
-    @NonNull
-    private static ContentValues toContentValues(@NonNull final String key,
-            @Nullable final NetworkAttributes attributes, final long expiry) {
-        final ContentValues values = toContentValues(attributes);
-        values.put(NetworkAttributesContract.COLNAME_L2KEY, key);
-        values.put(NetworkAttributesContract.COLNAME_EXPIRYDATE, expiry);
-        return values;
-    }
-
-    // Convert a byte array into content values to store it in a table compliant with the
-    // contract defined in PrivateDataContract.
-    @NonNull
-    private static ContentValues toContentValues(@NonNull final String key,
-            @NonNull final String clientId, @NonNull final String name,
-            @NonNull final byte[] data) {
-        final ContentValues values = new ContentValues();
-        values.put(PrivateDataContract.COLNAME_L2KEY, key);
-        values.put(PrivateDataContract.COLNAME_CLIENT, clientId);
-        values.put(PrivateDataContract.COLNAME_DATANAME, name);
-        values.put(PrivateDataContract.COLNAME_DATA, data);
-        return values;
-    }
-
-    @Nullable
-    private static NetworkAttributes readNetworkAttributesLine(@NonNull final Cursor cursor) {
-        // Make sure the data hasn't expired
-        final long expiry = getLong(cursor, NetworkAttributesContract.COLNAME_EXPIRYDATE, -1L);
-        if (expiry < System.currentTimeMillis()) return null;
-
-        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);
-        final int mtu = getInt(cursor, NetworkAttributesContract.COLNAME_MTU, -1);
-        if (0 != assignedV4AddressInt) {
-            builder.setAssignedV4Address(intToInet4AddressHTH(assignedV4AddressInt));
-        }
-        if (0 != assignedV4AddressExpiry) {
-            builder.setAssignedV4AddressExpiry(assignedV4AddressExpiry);
-        }
-        builder.setGroupHint(groupHint);
-        if (null != dnsAddressesBlob) {
-            builder.setDnsAddresses(decodeAddressList(dnsAddressesBlob));
-        }
-        if (mtu >= 0) {
-            builder.setMtu(mtu);
-        }
-        return builder.build();
-    }
-
-    private static final String[] EXPIRY_COLUMN = new String[] {
-        NetworkAttributesContract.COLNAME_EXPIRYDATE
-    };
-    static final int EXPIRY_ERROR = -1; // Legal values for expiry are positive
-
-    static final String SELECT_L2KEY = NetworkAttributesContract.COLNAME_L2KEY + " = ?";
-
-    // Returns the expiry date of the specified row, or one of the error codes above if the
-    // row is not found or some other error
-    static long getExpiry(@NonNull final SQLiteDatabase db, @NonNull final String key) {
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                EXPIRY_COLUMN, // columns
-                SELECT_L2KEY, // selection
-                new String[] { key }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null // orderBy
-        );
-        // L2KEY is the primary key ; it should not be possible to get more than one
-        // result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return EXPIRY_ERROR;
-        cursor.moveToFirst();
-        final long result = cursor.getLong(0); // index in the EXPIRY_COLUMN array
-        cursor.close();
-        return result;
-    }
-
-    static final int RELEVANCE_ERROR = -1; // Legal values for relevance are positive
-
-    // Returns the relevance of the specified row, or one of the error codes above if the
-    // row is not found or some other error
-    static int getRelevance(@NonNull final SQLiteDatabase db, @NonNull final String key) {
-        final long expiry = getExpiry(db, key);
-        return expiry < 0 ? (int) expiry : RelevanceUtils.computeRelevanceForNow(expiry);
-    }
-
-    // If the attributes are null, this will only write the expiry.
-    // 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);
-        db.beginTransaction();
-        try {
-            // Unfortunately SQLite does not have any way to do INSERT OR UPDATE. Options are
-            // to either insert with on conflict ignore then update (like done here), or to
-            // construct a custom SQL INSERT statement with nested select.
-            final long resultId = db.insertWithOnConflict(NetworkAttributesContract.TABLENAME,
-                    null, cv, SQLiteDatabase.CONFLICT_IGNORE);
-            if (resultId < 0) {
-                db.update(NetworkAttributesContract.TABLENAME, cv, SELECT_L2KEY, new String[]{key});
-            }
-            db.setTransactionSuccessful();
-            return Status.SUCCESS;
-        } catch (SQLiteException e) {
-            // No space left on disk or something
-            Log.e(TAG, "Could not write to the memory store", e);
-        } finally {
-            db.endTransaction();
-        }
-        return Status.ERROR_STORAGE;
-    }
-
-    // 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) {
-        final long res = db.insertWithOnConflict(PrivateDataContract.TABLENAME, null,
-                toContentValues(key, clientId, name, data), SQLiteDatabase.CONFLICT_REPLACE);
-        return (res == -1) ? Status.ERROR_STORAGE : Status.SUCCESS;
-    }
-
-    @Nullable
-    static NetworkAttributes retrieveNetworkAttributes(@NonNull final SQLiteDatabase db,
-            @NonNull final String key) {
-        final Cursor cursor = db.query(NetworkAttributesContract.TABLENAME,
-                null, // columns, null means everything
-                NetworkAttributesContract.COLNAME_L2KEY + " = ?", // selection
-                new String[] { key }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null); // orderBy
-        // L2KEY is the primary key ; it should not be possible to get more than one
-        // result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return null;
-        cursor.moveToFirst();
-        final NetworkAttributes attributes = readNetworkAttributesLine(cursor);
-        cursor.close();
-        return attributes;
-    }
-
-    private static final String[] DATA_COLUMN = new String[] {
-            PrivateDataContract.COLNAME_DATA
-    };
-
-    @Nullable
-    static byte[] retrieveBlob(@NonNull final SQLiteDatabase db, @NonNull final String key,
-            @NonNull final String clientId, @NonNull final String name) {
-        final Cursor cursor = db.query(PrivateDataContract.TABLENAME,
-                DATA_COLUMN, // columns
-                PrivateDataContract.COLNAME_L2KEY + " = ? AND " // selection
-                + PrivateDataContract.COLNAME_CLIENT + " = ? AND "
-                + PrivateDataContract.COLNAME_DATANAME + " = ?",
-                new String[] { key, clientId, name }, // selectionArgs
-                null, // groupBy
-                null, // having
-                null); // orderBy
-        // The query above is querying by (composite) primary key, so it should not be possible to
-        // get more than one result here. 0 results means the key was not found.
-        if (cursor.getCount() != 1) return null;
-        cursor.moveToFirst();
-        final byte[] result = cursor.getBlob(0); // index in the DATA_COLUMN array
-        cursor.close();
-        return result;
-    }
-
-    /**
-     * Wipe all data in tables when network factory reset occurs.
-     */
-    static void wipeDataUponNetworkReset(@NonNull final SQLiteDatabase db) {
-        for (int remainingRetries = 3; remainingRetries > 0; --remainingRetries) {
-            db.beginTransaction();
-            try {
-                db.delete(NetworkAttributesContract.TABLENAME, null, null);
-                db.delete(PrivateDataContract.TABLENAME, null, null);
-                final Cursor cursorNetworkAttributes = db.query(
-                        // table name
-                        NetworkAttributesContract.TABLENAME,
-                        // column name
-                        new String[] { NetworkAttributesContract.COLNAME_L2KEY },
-                        null, // selection
-                        null, // selectionArgs
-                        null, // groupBy
-                        null, // having
-                        null, // orderBy
-                        "1"); // limit
-                if (0 != cursorNetworkAttributes.getCount()) {
-                    cursorNetworkAttributes.close();
-                    continue;
-                }
-                cursorNetworkAttributes.close();
-                final Cursor cursorPrivateData = db.query(
-                        // table name
-                        PrivateDataContract.TABLENAME,
-                        // column name
-                        new String[] { PrivateDataContract.COLNAME_L2KEY },
-                        null, // selection
-                        null, // selectionArgs
-                        null, // groupBy
-                        null, // having
-                        null, // orderBy
-                        "1"); // limit
-                if (0 != cursorPrivateData.getCount()) {
-                    cursorPrivateData.close();
-                    continue;
-                }
-                cursorPrivateData.close();
-                db.setTransactionSuccessful();
-                return;
-            } catch (SQLiteException e) {
-                Log.e(TAG, "Could not wipe the data in database", e);
-            } finally {
-                db.endTransaction();
-            }
-        }
-    }
-
-    /**
-     * The following is a horrible hack that is necessary because the Android SQLite API does not
-     * have a way to query a binary blob. This, almost certainly, is an overlook.
-     *
-     * The Android SQLite API has two family of methods : one for query that returns data, and
-     * one for more general SQL statements that can execute any statement but may not return
-     * anything. All the query methods, however, take only String[] for the arguments.
-     *
-     * In principle it is simple to write a function that will encode the binary blob in the
-     * way SQLite expects it. However, because the API forces the argument to be coerced into a
-     * String, the SQLiteQuery object generated by the default query methods will bind all
-     * arguments as Strings and SQL will *sanitize* them. This works okay for numeric types,
-     * but the format for blobs is x'<hex string>'. Note the presence of quotes, which will
-     * be sanitized, changing the contents of the field, and the query will fail to match the
-     * blob.
-     *
-     * As far as I can tell, there are two possible ways around this problem. The first one
-     * is to put the data in the query string and eschew it being an argument. This would
-     * require doing the sanitizing by hand. The other is to call bindBlob directly on the
-     * generated SQLiteQuery object, which not only is a lot less dangerous than rolling out
-     * sanitizing, but also will do the right thing if the underlying format ever changes.
-     *
-     * But none of the methods that take an SQLiteQuery object can return data ; this *must*
-     * be called with SQLiteDatabase#query. This object is not accessible from outside.
-     * However, there is a #query version that accepts a CursorFactory and this is pretty
-     * straightforward to implement as all the arguments are coming in and the SQLiteCursor
-     * class is public API.
-     * With this, it's possible to intercept the SQLiteQuery object, and assuming the args
-     * are available, to bind them directly and work around the API's oblivious coercion into
-     * Strings.
-     *
-     * This is really sad, but I don't see another way of having this work than this or the
-     * hand-rolled sanitizing, and this is the lesser evil.
-     */
-    private static class CustomCursorFactory implements SQLiteDatabase.CursorFactory {
-        @NonNull
-        private final ArrayList<Object> mArgs;
-        CustomCursorFactory(@NonNull final ArrayList<Object> args) {
-            mArgs = args;
-        }
-        @Override
-        public Cursor newCursor(final SQLiteDatabase db, final SQLiteCursorDriver masterQuery,
-                final String editTable,
-                final SQLiteQuery query) {
-            int index = 1; // bind is 1-indexed
-            for (final Object arg : mArgs) {
-                if (arg instanceof String) {
-                    query.bindString(index++, (String) arg);
-                } else if (arg instanceof Long) {
-                    query.bindLong(index++, (Long) arg);
-                } else if (arg instanceof Integer) {
-                    query.bindLong(index++, Long.valueOf((Integer) arg));
-                } else if (arg instanceof byte[]) {
-                    query.bindBlob(index++, (byte[]) arg);
-                } else {
-                    throw new IllegalStateException("Unsupported type CustomCursorFactory "
-                            + arg.getClass().toString());
-                }
-            }
-            return new SQLiteCursor(masterQuery, editTable, query);
-        }
-    }
-
-    // Returns the l2key of the closest match, if and only if it matches
-    // closely enough (as determined by group-closeness).
-    @Nullable
-    static String findClosestAttributes(@NonNull final SQLiteDatabase db,
-            @NonNull final NetworkAttributes attr) {
-        if (attr.isEmpty()) return null;
-        final ContentValues values = toContentValues(attr);
-
-        // Build the selection and args. To cut down on the number of lines to search, limit
-        // the search to those with at least one argument equals to the requested attributes.
-        // This works only because null attributes match only will not result in group-closeness.
-        final StringJoiner sj = new StringJoiner(" OR ");
-        final ArrayList<Object> args = new ArrayList<>();
-        args.add(System.currentTimeMillis());
-        for (final String field : values.keySet()) {
-            sj.add(field + " = ?");
-            args.add(values.get(field));
-        }
-
-        final String selection = NetworkAttributesContract.COLNAME_EXPIRYDATE + " > ? AND ("
-                + sj.toString() + ")";
-        final Cursor cursor = db.queryWithFactory(new CustomCursorFactory(args),
-                false, // distinct
-                NetworkAttributesContract.TABLENAME,
-                null, // columns, null means everything
-                selection, // selection
-                null, // selectionArgs, horrendously passed to the cursor factory instead
-                null, // groupBy
-                null, // having
-                null, // orderBy
-                null); // limit
-        if (cursor.getCount() <= 0) return null;
-        cursor.moveToFirst();
-        String bestKey = null;
-        float bestMatchConfidence = GROUPCLOSE_CONFIDENCE; // Never return a match worse than this.
-        while (!cursor.isAfterLast()) {
-            final NetworkAttributes read = readNetworkAttributesLine(cursor);
-            final float confidence = read.getNetworkGroupSamenessConfidence(attr);
-            if (confidence > bestMatchConfidence) {
-                bestKey = getString(cursor, NetworkAttributesContract.COLNAME_L2KEY);
-                bestMatchConfidence = confidence;
-            }
-            cursor.moveToNext();
-        }
-        cursor.close();
-        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);
-        return (columnIndex >= 0) ? cursor.getString(columnIndex) : null;
-    }
-    private static byte[] getBlob(final Cursor cursor, final String columnName) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getBlob(columnIndex) : null;
-    }
-    private static int getInt(final Cursor cursor, final String columnName,
-            final int defaultValue) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getInt(columnIndex) : defaultValue;
-    }
-    private static long getLong(final Cursor cursor, final String columnName,
-            final long defaultValue) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return (columnIndex >= 0) ? cursor.getLong(columnIndex) : defaultValue;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
deleted file mode 100644
index 55ab8d4..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java
+++ /dev/null
@@ -1,503 +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.server.connectivity.ipmemorystore;
-
-import static android.net.ipmemorystore.Status.ERROR_DATABASE_CANNOT_BE_OPENED;
-import static android.net.ipmemorystore.Status.ERROR_GENERIC;
-import static android.net.ipmemorystore.Status.ERROR_ILLEGAL_ARGUMENT;
-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;
-import android.content.Context;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.IIpMemoryStore;
-import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-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;
-import android.net.ipmemorystore.SameL3NetworkResponse;
-import android.net.ipmemorystore.Status;
-import android.net.ipmemorystore.StatusParcelable;
-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;
-
-/**
- * Implementation for the IP memory store.
- * This component offers specialized services for network components to store and retrieve
- * knowledge about networks, and provides intelligence that groups level 2 networks together
- * into level 3 networks.
- *
- * @hide
- */
-public class IpMemoryStoreService extends IIpMemoryStore.Stub {
-    private static final String TAG = IpMemoryStoreService.class.getSimpleName();
-    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
-    final SQLiteDatabase mDb;
-    @NonNull
-    final ExecutorService mExecutor;
-
-    /**
-     * Construct an IpMemoryStoreService object.
-     * This constructor will block on disk access to open the database.
-     * @param context the context to access storage with.
-     */
-    public IpMemoryStoreService(@NonNull final Context context) {
-        // Note that constructing the service will access the disk and block
-        // for some time, but it should make no difference to the clients. Because
-        // the interface is one-way, clients fire and forget requests, and the callback
-        // will get called eventually in any case, and the framework will wait for the
-        // service to be created to deliver subsequent requests.
-        // Avoiding this would mean the mDb member can't be final, which means the service would
-        // have to test for nullity, care for failure, and allow for a wait at every single access,
-        // which would make the code a lot more complex and require all methods to possibly block.
-        mContext = context;
-        SQLiteDatabase db;
-        final IpMemoryStoreDatabase.DbHelper helper = new IpMemoryStoreDatabase.DbHelper(context);
-        try {
-            db = helper.getWritableDatabase();
-            if (null == db) Log.e(TAG, "Unexpected null return of getWriteableDatabase");
-        } catch (final SQLException e) {
-            Log.e(TAG, "Can't open the Ip Memory Store database", e);
-            db = null;
-        } catch (final Exception e) {
-            Log.wtf(TAG, "Impossible exception Ip Memory Store database", e);
-            db = null;
-        }
-        mDb = db;
-        // The single thread executor guarantees that all work is executed sequentially on the
-        // same thread, and no two tasks can be active at the same time. This is required to
-        // ensure operations from multiple clients don't interfere with each other (in particular,
-        // operations involving a transaction must not run concurrently with other operations
-        // as the other operations might be taken as part of the transaction). By default, the
-        // single thread executor runs off an unbounded queue.
-        // TODO : investigate replacing this scheme with a scheme where each thread has its own
-        // instance of the database, as it may be faster. It is likely however that IpMemoryStore
-        // operations are mostly IO-bound anyway, and additional contention is unlikely to bring
-        // benefits. Alternatively, a read-write lock might increase throughput.
-        mExecutor = Executors.newSingleThreadExecutor();
-        RegularMaintenanceJobService.schedule(mContext, this);
-    }
-
-    /**
-     * Shutdown the memory store service, cancelling running tasks and dropping queued tasks.
-     *
-     * This is provided to give a way to clean up, and is meant to be available in case of an
-     * emergency shutdown.
-     */
-    public void shutdown() {
-        // By contrast with ExecutorService#shutdown, ExecutorService#shutdownNow tries
-        // to cancel the existing tasks, and does not wait for completion. It does not
-        // 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 */
-    private StatusParcelable makeStatus(final int code) {
-        return new Status(code).toParcelable();
-    }
-
-    /**
-     * Store network attributes for a given L2 key.
-     *
-     * @param l2Key The L2 key for the L2 network. Clients that don't know or care about the L2
-     *              key and only care about grouping can pass a unique ID here like the ones
-     *              generated by {@code java.util.UUID.randomUUID()}, but keep in mind the low
-     *              relevance of such a network will lead to it being evicted soon if it's not
-     *              refreshed. Use findL2Key to try and find a similar L2Key to these attributes.
-     * @param attributes The attributes for this network.
-     * @param listener A listener to inform of the completion of this call, or null if the client
-     *        is not interested in learning about success/failure.
-     * Through the listener, returns the L2 key. This is useful if the L2 key was not specified.
-     * If the call failed, the L2 key will be null.
-     */
-    // Note that while l2Key and attributes are non-null in spirit, they are received from
-    // another process. If the remote process decides to ignore everything and send null, this
-    // process should still not crash.
-    @Override
-    public void storeNetworkAttributes(@Nullable final String l2Key,
-            @Nullable final NetworkAttributesParcelable attributes,
-            @Nullable final IOnStatusListener listener) {
-        // Because the parcelable is 100% mutable, the thread may not see its members initialized.
-        // Therefore either an immutable object is created on this same thread before it's passed
-        // to the executor, or there need to be a write barrier here and a read barrier in the
-        // remote thread.
-        final NetworkAttributes na = null == attributes ? null : new NetworkAttributes(attributes);
-        mExecutor.execute(() -> {
-            try {
-                final int code = storeNetworkAttributesAndBlobSync(l2Key, na,
-                        null /* clientId */, null /* name */, null /* data */);
-                if (null != listener) listener.onComplete(makeStatus(code));
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Store a binary blob associated with an L2 key and a name.
-     *
-     * @param l2Key The L2 key for this network.
-     * @param clientId The ID of the client.
-     * @param name The name of this data.
-     * @param blob The data to store.
-     * @param listener The listener that will be invoked to return the answer, or null if the
-     *        is not interested in learning about success/failure.
-     * Through the listener, returns a status to indicate success or failure.
-     */
-    @Override
-    public void storeBlob(@Nullable final String l2Key, @Nullable final String clientId,
-            @Nullable final String name, @Nullable final Blob blob,
-            @Nullable final IOnStatusListener listener) {
-        final byte[] data = null == blob ? null : blob.data;
-        mExecutor.execute(() -> {
-            try {
-                final int code = storeNetworkAttributesAndBlobSync(l2Key,
-                        null /* NetworkAttributes */, clientId, name, data);
-                if (null != listener) listener.onComplete(makeStatus(code));
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Helper method for storeNetworkAttributes and storeBlob.
-     *
-     * Either attributes or none of clientId, name and data may be null. This will write the
-     * passed data if non-null, and will write attributes if non-null, but in any case it will
-     * bump the relevance up.
-     * Returns a success code from Status.
-     */
-    private int storeNetworkAttributesAndBlobSync(@Nullable final String l2Key,
-            @Nullable final NetworkAttributes attributes,
-            @Nullable final String clientId,
-            @Nullable final String name, @Nullable final byte[] data) {
-        if (null == l2Key) return ERROR_ILLEGAL_ARGUMENT;
-        if (null == attributes && null == data) return ERROR_ILLEGAL_ARGUMENT;
-        if (null != data && (null == clientId || null == name)) return ERROR_ILLEGAL_ARGUMENT;
-        if (null == mDb) return ERROR_DATABASE_CANNOT_BE_OPENED;
-        try {
-            final long oldExpiry = IpMemoryStoreDatabase.getExpiry(mDb, l2Key);
-            final long newExpiry = RelevanceUtils.bumpExpiryDate(
-                    oldExpiry == EXPIRY_ERROR ? System.currentTimeMillis() : oldExpiry);
-            final int errorCode =
-                    IpMemoryStoreDatabase.storeNetworkAttributes(mDb, l2Key, newExpiry, attributes);
-            // If no blob to store, the client is interested in the result of storing the attributes
-            if (null == data) return errorCode;
-            // Otherwise it's interested in the result of storing the blob
-            return IpMemoryStoreDatabase.storeBlob(mDb, l2Key, clientId, name, data);
-        } catch (Exception e) {
-            if (DBG) {
-                Log.e(TAG, "Exception while storing for key {" + l2Key
-                        + "} ; NetworkAttributes {" + (null == attributes ? "null" : attributes)
-                        + "} ; clientId {" + (null == clientId ? "null" : clientId)
-                        + "} ; name {" + (null == name ? "null" : name)
-                        + "} ; data {" + Utils.byteArrayToString(data) + "}", e);
-            }
-        }
-        return ERROR_GENERIC;
-    }
-
-    /**
-     * Returns the best L2 key associated with the attributes.
-     *
-     * This will find a record that would be in the same group as the passed attributes. This is
-     * useful to choose the key for storing a sample or private data when the L2 key is not known.
-     * If multiple records are group-close to these attributes, the closest match is returned.
-     * If multiple records have the same closeness, the one with the smaller (unicode codepoint
-     * order) L2 key is returned.
-     * If no record matches these attributes, null is returned.
-     *
-     * @param attributes The attributes of the network to find.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the L2 key if one matched, or null.
-     */
-    @Override
-    public void findL2Key(@Nullable final NetworkAttributesParcelable attributes,
-            @Nullable final IOnL2KeyResponseListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == attributes) {
-                    listener.onL2KeyResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onL2KeyResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                final String key = IpMemoryStoreDatabase.findClosestAttributes(mDb,
-                        new NetworkAttributes(attributes));
-                listener.onL2KeyResponse(makeStatus(SUCCESS), key);
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Returns whether, to the best of the store's ability to tell, the two specified L2 keys point
-     * to the same L3 network. Group-closeness is used to determine this.
-     *
-     * @param l2Key1 The key for the first network.
-     * @param l2Key2 The key for the second network.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, a SameL3NetworkResponse containing the answer and confidence.
-     */
-    @Override
-    public void isSameNetwork(@Nullable final String l2Key1, @Nullable final String l2Key2,
-            @Nullable final IOnSameL3NetworkResponseListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key1 || null == l2Key2) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_ILLEGAL_ARGUMENT), null);
-                    return;
-                }
-                try {
-                    final NetworkAttributes attr1 =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key1);
-                    final NetworkAttributes attr2 =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key2);
-                    if (null == attr1 || null == attr2) {
-                        listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
-                                new SameL3NetworkResponse(l2Key1, l2Key2,
-                                        -1f /* never connected */).toParcelable());
-                        return;
-                    }
-                    final float confidence = attr1.getNetworkGroupSamenessConfidence(attr2);
-                    listener.onSameL3NetworkResponse(makeStatus(SUCCESS),
-                            new SameL3NetworkResponse(l2Key1, l2Key2, confidence).toParcelable());
-                } catch (Exception e) {
-                    listener.onSameL3NetworkResponse(makeStatus(ERROR_GENERIC), null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Retrieve the network attributes for a key.
-     * If no record is present for this key, this will return null attributes.
-     *
-     * @param l2Key The key of the network to query.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the network attributes and the L2 key associated with
-     *         the query.
-     */
-    @Override
-    public void retrieveNetworkAttributes(@Nullable final String l2Key,
-            @Nullable final IOnNetworkAttributesRetrievedListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key) {
-                    listener.onNetworkAttributesRetrieved(
-                            makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onNetworkAttributesRetrieved(
-                            makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key, null);
-                    return;
-                }
-                try {
-                    final NetworkAttributes attributes =
-                            IpMemoryStoreDatabase.retrieveNetworkAttributes(mDb, l2Key);
-                    listener.onNetworkAttributesRetrieved(makeStatus(SUCCESS), l2Key,
-                            null == attributes ? null : attributes.toParcelable());
-                } catch (final Exception e) {
-                    listener.onNetworkAttributesRetrieved(makeStatus(ERROR_GENERIC), l2Key, null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Retrieve previously stored private data.
-     * If no data was stored for this L2 key and name this will return null.
-     *
-     * @param l2Key The L2 key.
-     * @param clientId The id of the client that stored this data.
-     * @param name The name of the data.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the private data if any or null if none, with the L2 key
-     *         and the name of the data associated with the query.
-     */
-    @Override
-    public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId,
-            @NonNull final String name, @NonNull final IOnBlobRetrievedListener listener) {
-        if (null == listener) return;
-        mExecutor.execute(() -> {
-            try {
-                if (null == l2Key) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_ILLEGAL_ARGUMENT), l2Key, name, null);
-                    return;
-                }
-                if (null == mDb) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_DATABASE_CANNOT_BE_OPENED), l2Key,
-                            name, null);
-                    return;
-                }
-                try {
-                    final Blob b = new Blob();
-                    b.data = IpMemoryStoreDatabase.retrieveBlob(mDb, l2Key, clientId, name);
-                    listener.onBlobRetrieved(makeStatus(SUCCESS), l2Key, name, b);
-                } catch (final Exception e) {
-                    listener.onBlobRetrieved(makeStatus(ERROR_GENERIC), l2Key, name, null);
-                }
-            } catch (final RemoteException e) {
-                // Client at the other end died
-            }
-        });
-    }
-
-    /**
-     * Wipe the data in IpMemoryStore database upon network factory reset.
-     */
-    @Override
-    public void factoryReset() {
-        mExecutor.execute(() -> IpMemoryStoreDatabase.wipeDataUponNetworkReset(mDb));
-    }
-
-    /** 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;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return this.VERSION;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
deleted file mode 100644
index bea7052..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java
+++ /dev/null
@@ -1,145 +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.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 int getInterfaceVersion() {
-                return this.VERSION;
-            }
-
-            @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/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java
deleted file mode 100644
index 38d5544..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java
+++ /dev/null
@@ -1,307 +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.server.connectivity.ipmemorystore;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * A class containing the logic around the relevance value for
- * IP Memory Store.
- *
- * @hide
- */
-public class RelevanceUtils {
-    /**
-     * The relevance is a decaying value that gets lower and lower until it
-     * reaches 0 after some time passes. It follows an exponential decay law,
-     * dropping slowly at first then faster and faster, because a network is
-     * likely to be visited again if it was visited not long ago, and the longer
-     * it hasn't been visited the more likely it is that it won't be visited
-     * again. For example, a network visited on holiday should stay fresh for
-     * the duration of the holiday and persist for a while, but after the venue
-     * hasn't been visited for a while it should quickly be discarded. What
-     * should accelerate forgetting the network is extended periods without
-     * visits, so that occasional venues get discarded but regular visits keep
-     * the network relevant, even if the visits are infrequent.
-     *
-     * This function must be stable by iteration, meaning that adjusting the same value
-     * for different dates iteratively multiple times should give the same result.
-     * Formally, if f is the decay function that associates a relevance x at a date d1
-     * to the value at ulterior date d3, then for any date d2 between d1 and d3 :
-     * f(x, d3 - d1) = f(f(x, d3 - d2), d2 - d1). Intuitively, this property simply
-     * means it should be the same to compute and store back the value after two months,
-     * or to do it once after one month, store it back, and do it again after another
-     * months has passed.
-     * The pair of the relevance and date define the entire curve, so any pair
-     * of values on the curve will define the same curve. Setting one of them to a
-     * constant, so as not to have to store it, means the other one will always suffice
-     * to describe the curve. For example, only storing the date for a known, constant
-     * value of the relevance is an efficient way of remembering this information (and
-     * to compare relevances together, as f is monotonically decreasing).
-     *
-     *** Choosing the function :
-     * Functions of the kind described above are standard exponential decay functions
-     * like the ones that govern atomic decay where the value at any given date can be
-     * computed uniformly from the value at a previous date and the time elapsed since
-     * that date. It is simple to picture this kind of function as one where after a
-     * given period of time called the half-life, the relevance value will have been
-     * halved. Decay of this kind is expressed in function of the previous value by
-     * functions like
-     * f(x, t) = x * F ^ (t / L)
-     * ...where x is the value, t is the elapsed time, L is the half-life (or more
-     * generally the F-th-life) and F the decay factor (typically 0.5, hence why L is
-     * usually called the half-life). The ^ symbol here is used for exponentiation.
-     * Or, starting at a given M for t = 0 :
-     * f(t) = M * F ^ (t / L)
-     *
-     * Because a line in the store needs to become irrelevant at some point but
-     * this class of functions never go to 0, a minimum cutoff has to be chosen to
-     * represent irrelevance. The simpler way of doing this is to simply add this
-     * minimum cutoff to the computation before and removing it after.
-     * Thus the function becomes :
-     * f(x, t) = ((x + K) * F ^ (t / L)) - K
-     * ...where K is the minimum cutoff, L the half-life, and F the factor between
-     * the original x and x after its half-life. Strictly speaking using the word
-     * "half-life" implies that F = 0.5, but the relation works for any value of F.
-     *
-     * It is easy enough to check that this function satisfies the stability
-     * relation that was given above for any value of F, L and K, which become
-     * parameters that can be defined at will.
-     *
-     * relevance
-     *  1.0 |
-     *      |\
-     *      | \
-     *      |  \            (this graph rendered with L = 75 days and K = 1/40)
-     *  0.75|   ',
-     *      |     \
-     *      |      '.
-     *      |        \.
-     *      |          \
-     *  0.5 |           '\
-     *      |             ''.
-     *      |                ''.
-     *      |                   ''.
-     *  0.25|                      '''..
-     *      |                           '''..
-     *      |                                ''''....
-     *      |                                        '''''..........
-     *    0 +-------------------------------------------------------''''''''''----
-     *      0       50       100      150     200      250     300      350     400 days
-     *
-     *** Choosing the parameters
-     * The maximum M is an arbitrary parameter that simply scales the curve.
-     * The tradeoff for M is pretty simple : if the relevance is going to be an
-     * integer, the bigger M is the more precision there is in the relevance.
-     * However, values of M that are easy for humans to read are preferable to
-     * help debugging, and a suitably low value may be enough to ensure there
-     * won't be integer overflows in intermediate computations.
-     * A value of 1_000_000 probably is plenty for precision, while still in the
-     * low range of what ints can represent.
-     *
-     * F and L are parameters to be chosen arbitrarily and have an impact on how
-     * fast the relevance will be decaying at first, keeping in mind that
-     * the 400 days value and the cap stay the same. In simpler words, F and L
-     * define the steepness of the curve.
-     * To keep things simple (and familiar) F is arbitrarily chosen to be 0.5, and
-     * L is set to 200 days visually to achieve the desired effect. Refer to the
-     * illustration above to get a feel of how that feels.
-     *
-     * Moreover, the memory store works on an assumption that the relevance should
-     * be capped, and that an entry with capped relevance should decay in 400 days.
-     * This is on premises that the networks a device will need to remember the
-     * longest should be networks visited about once a year.
-     * For this reason, the relevance is at the maximum M 400 days before expiry :
-     * f(M, 400 days) = 0
-     * From replacing this with the value of the function, K can then be derived
-     * from the values of M, F and L :
-     * (M + K) * F ^ (t / L) - K = 0
-     * K = M * F ^ (400 days / L) / (1 - F ^ (400 days / L))
-     * Replacing with actual values this gives :
-     * K = 1_000_000 * 0.5 ^ (400 / 200) / (1 - 0.5 ^ (400 / 200))
-     *   = 1_000_000 / 3 ≈ 333_333.3
-     * This ensures the function has the desired profile, the desired value at
-     * cap, and the desired value at expiry.
-     *
-     *** Useful relations
-     * Let's define the expiry time for any given relevance x as the interval of
-     * time such as :
-     * f(x, expiry) = 0
-     * which can be rewritten
-     * ((x + K) * F ^ (expiry / L)) = K
-     * ...giving an expression of the expiry in function of the relevance x as
-     * expiry = L * logF(K / (x + K))
-     * Conversely the relevance x can be expressed in function of the expiry as
-     * x = K / F ^ (expiry / L) - K
-     * These relations are useful in utility functions.
-     *
-     *** Bumping things up
-     * The last issue therefore is to decide how to bump up the relevance. The
-     * simple approach is to simply lift up the curve a little bit by a constant
-     * normalized amount, delaying the time of expiry. For example increasing
-     * the relevance by an amount I gives :
-     * x2 = x1 + I
-     * x2 and x1 correspond to two different expiry times expiry2 and expiry1,
-     * and replacing x1 and x2 in the relation above with their expression in
-     * function of the expiry comes :
-     * K / F ^ (expiry2 / L) - K = K / F ^ (expiry1 / L) - K + I
-     * which resolves to :
-     * expiry2 = L * logF(K / (I + K / F ^ (expiry1 / L)))
-     *
-     * In this implementation, the bump is defined as 1/25th of the cap for
-     * the relevance. This means a network will be remembered for the maximum
-     * period of 400 days if connected 25 times in succession not accounting
-     * for decay. Of course decay actually happens so it will take more than 25
-     * connections for any given network to actually reach the cap, but because
-     * decay is slow at first, it is a good estimate of how fast cap happens.
-     *
-     * Specifically, it gives the following four results :
-     * - A network that a device connects to once hits irrelevance about 32.7 days after
-     *   it was first registered if never connected again.
-     * - A network that a device connects to once a day at a fixed hour will hit the cap
-     *   on the 27th connection.
-     * - A network that a device connects to once a week at a fixed hour will hit the cap
-     *   on the 57th connection.
-     * - A network that a device connects to every day for 7 straight days then never again
-     *   expires 144 days after the last connection.
-     * These metrics tend to match pretty well the requirements.
-     */
-
-    // TODO : make these constants configurable at runtime. Don't forget to build it so that
-    // changes will wipe the database, migrate the values, or otherwise make sure the relevance
-    // values are still meaningful.
-
-    // How long, in milliseconds, is a capped relevance valid for, or in other
-    // words how many milliseconds after its relevance was set to RELEVANCE_CAP does
-    // any given line expire. 400 days.
-    @VisibleForTesting
-    public static final long CAPPED_RELEVANCE_LIFETIME_MS = 400L * 24 * 60 * 60 * 1000;
-
-    // The constant that represents a normalized 1.0 value for the relevance. In other words,
-    // the cap for the relevance. This is referred to as M in the explanation above.
-    @VisibleForTesting
-    public static final int CAPPED_RELEVANCE = 1_000_000;
-
-    // The decay factor. After a half-life, the relevance will have decayed by this value.
-    // This is referred to as F in the explanation above.
-    private static final double DECAY_FACTOR = 0.5;
-
-    // The half-life. After this time, the relevance will have decayed by a factor DECAY_FACTOR.
-    // This is referred to as L in the explanation above.
-    private static final long HALF_LIFE_MS = 200L * 24 * 60 * 60 * 1000;
-
-    // The value of the frame change. This is referred to as K in the explanation above.
-    private static final double IRRELEVANCE_FLOOR =
-            CAPPED_RELEVANCE * powF((double) CAPPED_RELEVANCE_LIFETIME_MS / HALF_LIFE_MS)
-            / (1 - powF((double) CAPPED_RELEVANCE_LIFETIME_MS / HALF_LIFE_MS));
-
-    // How much to bump the relevance by every time a line is written to.
-    @VisibleForTesting
-    public static final int RELEVANCE_BUMP = CAPPED_RELEVANCE / 25;
-
-    // Java doesn't include a function for the logarithm in an arbitrary base, so implement it
-    private static final double LOG_DECAY_FACTOR = Math.log(DECAY_FACTOR);
-    private static double logF(final double value) {
-        return Math.log(value) / LOG_DECAY_FACTOR;
-    }
-
-    // Utility function to get a power of the decay factor, to simplify the code.
-    private static double powF(final double value) {
-        return Math.pow(DECAY_FACTOR, value);
-    }
-
-    /**
-     * Compute the value of the relevance now given an expiry date.
-     *
-     * @param expiry the date at which the column in the database expires.
-     * @return the adjusted value of the relevance for this moment in time.
-     */
-    public static int computeRelevanceForNow(final long expiry) {
-        return computeRelevanceForTargetDate(expiry, System.currentTimeMillis());
-    }
-
-    /**
-     * Compute the value of the relevance at a given date from an expiry date.
-     *
-     * Because relevance decays with time, a relevance in the past corresponds to
-     * a different relevance later.
-     *
-     * Relevance is always a positive value. 0 means not relevant at all.
-     *
-     * See the explanation at the top of this file to get the justification for this
-     * computation.
-     *
-     * @param expiry the date at which the column in the database expires.
-     * @param target the target date to adjust the relevance to.
-     * @return the adjusted value of the relevance for the target moment.
-     */
-    public static int computeRelevanceForTargetDate(final long expiry, final long target) {
-        final long delay = expiry - target;
-        if (delay >= CAPPED_RELEVANCE_LIFETIME_MS) return CAPPED_RELEVANCE;
-        if (delay <= 0) return 0;
-        return (int) (IRRELEVANCE_FLOOR / powF((float) delay / HALF_LIFE_MS) - IRRELEVANCE_FLOOR);
-    }
-
-    /**
-     * Compute the expiry duration adjusted up for a new fresh write.
-     *
-     * Every time data is written to the memory store for a given line, the
-     * relevance is bumped up by a certain amount, which will boost the priority
-     * of this line for computation of group attributes, and delay (possibly
-     * indefinitely, if the line is accessed regularly) forgetting the data stored
-     * in that line.
-     * As opposed to bumpExpiryDate, this function uses a duration from now to expiry.
-     *
-     * See the explanation at the top of this file for a justification of this computation.
-     *
-     * @param oldExpiryDuration the old expiry duration in milliseconds from now.
-     * @return the expiry duration representing a bumped up relevance value.
-     */
-    public static long bumpExpiryDuration(final long oldExpiryDuration) {
-        // L * logF(K / (I + K / F ^ (expiry1 / L))), as documented above
-        final double divisionFactor = powF(((double) oldExpiryDuration) / HALF_LIFE_MS);
-        final double oldRelevance = IRRELEVANCE_FLOOR / divisionFactor;
-        final long newDuration =
-                (long) (HALF_LIFE_MS * logF(IRRELEVANCE_FLOOR / (RELEVANCE_BUMP + oldRelevance)));
-        return Math.min(newDuration, CAPPED_RELEVANCE_LIFETIME_MS);
-    }
-
-    /**
-     * Compute the new expiry date adjusted up for a new fresh write.
-     *
-     * Every time data is written to the memory store for a given line, the
-     * relevance is bumped up by a certain amount, which will boost the priority
-     * of this line for computation of group attributes, and delay (possibly
-     * indefinitely, if the line is accessed regularly) forgetting the data stored
-     * in that line.
-     * As opposed to bumpExpiryDuration, this function takes the old timestamp and returns the
-     * new timestamp.
-     *
-     * {@see bumpExpiryDuration}, and keep in mind that the bump depends on when this is called,
-     * because the relevance decays exponentially, therefore bumping up a high relevance (for a
-     * date far in the future) is less potent than bumping up a low relevance (for a date in
-     * a close future).
-     *
-     * @param oldExpiryDate the old date of expiration.
-     * @return the new expiration date after the relevance bump.
-     */
-    public static long bumpExpiryDate(final long oldExpiryDate) {
-        final long now = System.currentTimeMillis();
-        final long newDuration = bumpExpiryDuration(oldExpiryDate - now);
-        return now + newDuration;
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java b/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java
deleted file mode 100644
index 9cbf490..0000000
--- a/packages/NetworkStack/src/com/android/server/connectivity/ipmemorystore/Utils.java
+++ /dev/null
@@ -1,52 +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.server.connectivity.ipmemorystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.ipmemorystore.Blob;
-
-/** {@hide} */
-public class Utils {
-    /** Pretty print */
-    public static String blobToString(@Nullable final Blob blob) {
-        return "Blob : " + byteArrayToString(null == blob ? null : blob.data);
-    }
-
-    /** Pretty print */
-    public static String byteArrayToString(@Nullable final byte[] data) {
-        if (null == data) return "null";
-        final StringBuilder sb = new StringBuilder("[");
-        if (data.length <= 24) {
-            appendByteArray(sb, data, 0, data.length);
-        } else {
-            appendByteArray(sb, data, 0, 16);
-            sb.append("...");
-            appendByteArray(sb, data, data.length - 8, data.length);
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    // Adds the hex representation of the array between the specified indices (inclusive, exclusive)
-    private static void appendByteArray(@NonNull final StringBuilder sb, @NonNull final byte[] ar,
-            final int from, final int to) {
-        for (int i = from; i < to; ++i) {
-            sb.append(String.format("%02X", ar[i]));
-        }
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java b/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java
deleted file mode 100644
index 804765e..0000000
--- a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java
+++ /dev/null
@@ -1,142 +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.server.util;
-
-import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
-
-import java.net.Inet4Address;
-
-/**
- * Network constants used by the network stack.
- */
-public final class NetworkStackConstants {
-
-    /**
-     * IPv4 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc791
-     */
-    public static final int IPV4_ADDR_BITS = 32;
-    public static final int IPV4_MIN_MTU = 68;
-    public static final int IPV4_MAX_MTU = 65_535;
-
-    /**
-     * Ethernet constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc894
-     *     - https://tools.ietf.org/html/rfc2464
-     *     - https://tools.ietf.org/html/rfc7042
-     *     - http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
-     *     - http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml
-     */
-    public static final int ETHER_DST_ADDR_OFFSET = 0;
-    public static final int ETHER_SRC_ADDR_OFFSET = 6;
-    public static final int ETHER_ADDR_LEN = 6;
-    public static final int ETHER_TYPE_OFFSET = 12;
-    public static final int ETHER_TYPE_LENGTH = 2;
-    public static final int ETHER_TYPE_ARP  = 0x0806;
-    public static final int ETHER_TYPE_IPV4 = 0x0800;
-    public static final int ETHER_TYPE_IPV6 = 0x86dd;
-    public static final int ETHER_HEADER_LEN = 14;
-
-    /**
-     * ARP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc826
-     *     - http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
-     */
-    public static final int ARP_PAYLOAD_LEN = 28;  // For Ethernet+IPv4.
-    public static final int ARP_REQUEST = 1;
-    public static final int ARP_REPLY   = 2;
-    public static final int ARP_HWTYPE_RESERVED_LO = 0;
-    public static final int ARP_HWTYPE_ETHER       = 1;
-    public static final int ARP_HWTYPE_RESERVED_HI = 0xffff;
-
-    /**
-     * IPv4 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc791
-     */
-    public static final int IPV4_HEADER_MIN_LEN = 20;
-    public static final int IPV4_IHL_MASK = 0xf;
-    public static final int IPV4_FLAGS_OFFSET = 6;
-    public static final int IPV4_FRAGMENT_MASK = 0x1fff;
-    public static final int IPV4_PROTOCOL_OFFSET = 9;
-    public static final int IPV4_SRC_ADDR_OFFSET = 12;
-    public static final int IPV4_DST_ADDR_OFFSET = 16;
-    public static final int IPV4_ADDR_LEN = 4;
-    public static final Inet4Address IPV4_ADDR_ALL = intToInet4AddressHTH(0xffffffff);
-    public static final Inet4Address IPV4_ADDR_ANY = intToInet4AddressHTH(0x0);
-
-    /**
-     * IPv6 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc2460
-     */
-    public static final int IPV6_ADDR_LEN = 16;
-    public static final int IPV6_HEADER_LEN = 40;
-    public static final int IPV6_PROTOCOL_OFFSET = 6;
-    public static final int IPV6_SRC_ADDR_OFFSET = 8;
-    public static final int IPV6_DST_ADDR_OFFSET = 24;
-
-    /**
-     * ICMPv6 constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc4443
-     *     - https://tools.ietf.org/html/rfc4861
-     */
-    public static final int ICMPV6_HEADER_MIN_LEN = 4;
-    public static final int ICMPV6_ECHO_REPLY_TYPE = 129;
-    public static final int ICMPV6_ECHO_REQUEST_TYPE = 128;
-    public static final int ICMPV6_ROUTER_SOLICITATION    = 133;
-    public static final int ICMPV6_ROUTER_ADVERTISEMENT   = 134;
-    public static final int ICMPV6_NEIGHBOR_SOLICITATION  = 135;
-    public static final int ICMPV6_NEIGHBOR_ADVERTISEMENT = 136;
-    public static final int ICMPV6_ND_OPTION_MIN_LENGTH = 8;
-    public static final int ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR = 8;
-    public static final int ICMPV6_ND_OPTION_SLLA = 1;
-    public static final int ICMPV6_ND_OPTION_TLLA = 2;
-    public static final int ICMPV6_ND_OPTION_MTU  = 5;
-
-    /**
-     * UDP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc768
-     */
-    public static final int UDP_HEADER_LEN = 8;
-
-
-    /**
-     * DHCP constants.
-     *
-     * See also:
-     *     - https://tools.ietf.org/html/rfc2131
-     */
-    public static final int INFINITE_LEASE = 0xffffffff;
-    public static final int DHCP4_CLIENT_PORT = 68;
-
-    private NetworkStackConstants() {
-        throw new UnsupportedOperationException("This class is not to be instantiated");
-    }
-}
diff --git a/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java b/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
deleted file mode 100644
index 6701384..0000000
--- a/packages/NetworkStack/src/com/android/server/util/PermissionUtil.java
+++ /dev/null
@@ -1,84 +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.server.util;
-
-import static android.os.Binder.getCallingPid;
-import static android.os.Binder.getCallingUid;
-
-import android.os.Process;
-import android.os.UserHandle;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Utility class to check calling permissions on the network stack.
- */
-public final class PermissionUtil {
-    private static final AtomicInteger sSystemPid = new AtomicInteger(-1);
-
-    /**
-     * Check that the caller is allowed to communicate with the network stack.
-     * @throws SecurityException The caller is not allowed to communicate with the network stack.
-     */
-    public static void checkNetworkStackCallingPermission() {
-        final int caller = getCallingUid();
-        if (caller == Process.SYSTEM_UID) {
-            checkConsistentSystemPid();
-            return;
-        }
-
-        if (UserHandle.getAppId(caller) != Process.BLUETOOTH_UID) {
-            throw new SecurityException("Invalid caller: " + caller);
-        }
-    }
-
-    private static void checkConsistentSystemPid() {
-        // Apart from the system server process, no process with a system UID should try to
-        // communicate with the network stack. This is to ensure that the network stack does not
-        // need to maintain behavior for clients it was not designed to work with.
-        // Checking that all calls from a system UID originate from the same PID loosely enforces
-        // this restriction as if another system process calls the network stack first, the system
-        // server would lose access to the network stack and cause obvious failures. If the system
-        // server calls the network stack first, other clients would lose access as expected.
-        final int systemPid = getCallingPid();
-        if (sSystemPid.compareAndSet(-1, systemPid)) {
-            // sSystemPid was unset (-1): this was the first call
-            return;
-        }
-
-        if (sSystemPid.get() != systemPid) {
-            throw new SecurityException("Invalid PID for the system server, expected "
-                    + sSystemPid.get() + " but was called from " + systemPid);
-        }
-    }
-
-    /**
-     * Check that the caller is allowed to dump the network stack, e.g. dumpsys.
-     * @throws SecurityException The caller is not allowed to dump the network stack.
-     */
-    public static void checkDumpPermission() {
-        final int caller = getCallingUid();
-        if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID
-                && caller != Process.SHELL_UID) {
-            throw new SecurityException("No dump permissions for caller: " + caller);
-        }
-    }
-
-    private PermissionUtil() {
-        throw new UnsupportedOperationException("This class is not to be instantiated");
-    }
-}
diff --git a/packages/NetworkStack/tests/lib/Android.bp b/packages/NetworkStack/tests/lib/Android.bp
deleted file mode 100644
index f45a81c..0000000
--- a/packages/NetworkStack/tests/lib/Android.bp
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-java_library {
-    name: "net-tests-utils",
-    srcs: [
-        "src/**/*.java",
-        "src/**/*.kt",
-    ],
-    static_libs: [
-        "kotlin-test",
-    ],
-}
diff --git a/packages/NetworkStack/tests/lib/src/com/android/testutils/HandlerUtils.kt b/packages/NetworkStack/tests/lib/src/com/android/testutils/HandlerUtils.kt
deleted file mode 100644
index 3dce5a5..0000000
--- a/packages/NetworkStack/tests/lib/src/com/android/testutils/HandlerUtils.kt
+++ /dev/null
@@ -1,50 +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.testutils
-
-import android.os.ConditionVariable
-import android.os.Handler
-import android.os.HandlerThread
-import java.util.concurrent.Executor
-import kotlin.test.fail
-
-/**
- * Block until the specified Handler or HandlerThread becomes idle, or until timeoutMs has passed.
- */
-fun Handler.waitForIdle(timeoutMs: Long) = waitForIdleHandler(this, timeoutMs)
-fun HandlerThread.waitForIdle(timeoutMs: Long) = waitForIdleHandler(this.threadHandler, timeoutMs)
-fun waitForIdleHandler(handler: HandlerThread, timeoutMs: Long) {
-    waitForIdleHandler(handler.threadHandler, timeoutMs)
-}
-fun waitForIdleHandler(handler: Handler, timeoutMs: Long) {
-    val cv = ConditionVariable(false)
-    handler.post(cv::open)
-    if (!cv.block(timeoutMs)) {
-        fail("Handler did not become idle after ${timeoutMs}ms")
-    }
-}
-
-/**
- * Block until the given Serial Executor becomes idle, or until timeoutMs has passed.
- */
-fun waitForIdleSerialExecutor(executor: Executor, timeoutMs: Long) {
-    val cv = ConditionVariable()
-    executor.execute(cv::open)
-    if (!cv.block(timeoutMs)) {
-        fail("Executor did not become idle after ${timeoutMs}ms")
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/Android.bp b/packages/NetworkStack/tests/unit/Android.bp
deleted file mode 100644
index 48b13b0..0000000
--- a/packages/NetworkStack/tests/unit/Android.bp
+++ /dev/null
@@ -1,102 +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 {
-    name: "NetworkStackTests",
-    certificate: "platform",
-    srcs: ["src/**/*.java"],
-    test_suites: ["device-tests"],
-    resource_dirs: ["res"],
-    static_libs: [
-        "androidx.test.rules",
-        "mockito-target-extended-minus-junit4",
-        "net-tests-utils",
-        "NetworkStackBase",
-        "testables",
-    ],
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-        "android.test.mock",
-    ],
-    jni_libs: [
-        // For mockito extended
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-        // For ApfTest
-        "libbacktrace",
-        "libbase",
-        "libbinder",
-        "libbinderthreadstate",
-        "libc++",
-        "libcgrouprc",
-        "libcrypto",
-        "libcutils",
-        "ld-android",
-        "libdl_android",
-        "libhidl-gen-utils",
-        "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
-        "libjsoncpp",
-        "liblog",
-        "liblzma",
-        "libnativehelper",
-        "libnativehelper_compat_libc++",
-        "libnetworkstacktestsjni",
-        "libnetworkstackutilsjni",
-        "libpackagelistparser",
-        "libpcre2",
-        "libprocessgroup",
-        "libselinux",
-        "libui",
-        "libutils",
-        "libvintf",
-        "libvndksupport",
-        "libtinyxml2",
-        "libunwindstack",
-        "libutilscallstack",
-        "libziparchive",
-        "libz",
-        "netd_aidl_interface-V2-cpp",
-    ],
-}
-
-cc_library_shared {
-    name: "libnetworkstacktestsjni",
-    srcs: [
-        "jni/**/*.cpp"
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    include_dirs: [
-        "hardware/google/apf",
-    ],
-    shared_libs: [
-        "libbinder",
-        "liblog",
-        "libcutils",
-        "libnativehelper",
-        "netd_aidl_interface-V2-cpp",
-    ],
-    static_libs: [
-        "libapf",
-        "libpcap",
-    ],
-}
diff --git a/packages/NetworkStack/tests/unit/AndroidManifest.xml b/packages/NetworkStack/tests/unit/AndroidManifest.xml
deleted file mode 100644
index 5dcf6ff..0000000
--- a/packages/NetworkStack/tests/unit/AndroidManifest.xml
+++ /dev/null
@@ -1,54 +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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.server.networkstack.tests">
-
-    <uses-permission android:name="android.permission.READ_LOGS" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
-    <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
-    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
-    <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
-    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
-    <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
-    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.MANAGE_USERS" />
-    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-    <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
-    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
-    <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
-    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
-    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
-    <uses-permission android:name="android.permission.NETWORK_STACK" />
-
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.android.server.networkstack.tests"
-        android:label="Networking service tests">
-    </instrumentation>
-</manifest>
\ No newline at end of file
diff --git a/packages/NetworkStack/tests/unit/AndroidTest.xml b/packages/NetworkStack/tests/unit/AndroidTest.xml
deleted file mode 100644
index 047bc2e..0000000
--- a/packages/NetworkStack/tests/unit/AndroidTest.xml
+++ /dev/null
@@ -1,29 +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.
--->
-<configuration description="Runs Tests for NetworkStack">
-    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
-        <option name="test-file-name" value="NetworkStackTests.apk" />
-    </target_preparer>
-
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="framework-base-presubmit" />
-    <option name="test-tag" value="NetworkStackTests" />
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.android.server.networkstack.tests" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <option name="hidden-api-checks" value="false"/>
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/packages/NetworkStack/tests/unit/jni/apf_jni.cpp b/packages/NetworkStack/tests/unit/jni/apf_jni.cpp
deleted file mode 100644
index 4222adf..0000000
--- a/packages/NetworkStack/tests/unit/jni/apf_jni.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <jni.h>
-#include <pcap.h>
-#include <stdlib.h>
-#include <string>
-#include <utils/Log.h>
-#include <vector>
-
-#include "apf_interpreter.h"
-#include "nativehelper/scoped_primitive_array.h"
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-// JNI function acting as simply call-through to native APF interpreter.
-static jint com_android_server_ApfTest_apfSimulate(
-        JNIEnv* env, jclass, jbyteArray jprogram, jbyteArray jpacket,
-        jbyteArray jdata, jint filter_age) {
-
-    ScopedByteArrayRO packet(env, jpacket);
-    uint32_t packet_len = (uint32_t)packet.size();
-    uint32_t program_len = env->GetArrayLength(jprogram);
-    uint32_t data_len = jdata ? env->GetArrayLength(jdata) : 0;
-    std::vector<uint8_t> buf(program_len + data_len, 0);
-
-    env->GetByteArrayRegion(jprogram, 0, program_len, reinterpret_cast<jbyte*>(buf.data()));
-    if (jdata) {
-        // Merge program and data into a single buffer.
-        env->GetByteArrayRegion(jdata, 0, data_len,
-                                reinterpret_cast<jbyte*>(buf.data() + program_len));
-    }
-
-    jint result =
-        accept_packet(buf.data(), program_len, program_len + data_len,
-                        reinterpret_cast<const uint8_t*>(packet.get()), packet_len, filter_age);
-
-    if (jdata) {
-        env->SetByteArrayRegion(jdata, 0, data_len,
-                                reinterpret_cast<jbyte*>(buf.data() + program_len));
-    }
-
-    return result;
-}
-
-class ScopedPcap {
-  public:
-    explicit ScopedPcap(pcap_t* pcap) : pcap_ptr(pcap) {}
-    ~ScopedPcap() {
-        pcap_close(pcap_ptr);
-    }
-
-    pcap_t* get() const { return pcap_ptr; };
-  private:
-    pcap_t* const pcap_ptr;
-};
-
-class ScopedFILE {
-  public:
-    explicit ScopedFILE(FILE* fp) : file(fp) {}
-    ~ScopedFILE() {
-        fclose(file);
-    }
-
-    FILE* get() const { return file; };
-  private:
-    FILE* const file;
-};
-
-static void throwException(JNIEnv* env, const std::string& error) {
-    jclass newExcCls = env->FindClass("java/lang/IllegalStateException");
-    if (newExcCls == 0) {
-      abort();
-      return;
-    }
-    env->ThrowNew(newExcCls, error.c_str());
-}
-
-static jstring com_android_server_ApfTest_compileToBpf(JNIEnv* env, jclass, jstring jfilter) {
-    ScopedUtfChars filter(env, jfilter);
-    std::string bpf_string;
-    ScopedPcap pcap(pcap_open_dead(DLT_EN10MB, 65535));
-    if (pcap.get() == NULL) {
-        throwException(env, "pcap_open_dead failed");
-        return NULL;
-    }
-
-    // Compile "filter" to a BPF program
-    bpf_program bpf;
-    if (pcap_compile(pcap.get(), &bpf, filter.c_str(), 0, PCAP_NETMASK_UNKNOWN)) {
-        throwException(env, "pcap_compile failed");
-        return NULL;
-    }
-
-    // Translate BPF program to human-readable format
-    const struct bpf_insn* insn = bpf.bf_insns;
-    for (uint32_t i = 0; i < bpf.bf_len; i++) {
-        bpf_string += bpf_image(insn++, i);
-        bpf_string += "\n";
-    }
-
-    return env->NewStringUTF(bpf_string.c_str());
-}
-
-static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, jstring jfilter,
-        jstring jpcap_filename, jbyteArray japf_program) {
-    ScopedUtfChars filter(env, jfilter);
-    ScopedUtfChars pcap_filename(env, jpcap_filename);
-    ScopedByteArrayRO apf_program(env, japf_program);
-
-    // Open pcap file for BPF filtering
-    ScopedFILE bpf_fp(fopen(pcap_filename.c_str(), "rb"));
-    char pcap_error[PCAP_ERRBUF_SIZE];
-    ScopedPcap bpf_pcap(pcap_fopen_offline(bpf_fp.get(), pcap_error));
-    if (bpf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    // Open pcap file for APF filtering
-    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
-    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
-    if (apf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    // Compile "filter" to a BPF program
-    bpf_program bpf;
-    if (pcap_compile(bpf_pcap.get(), &bpf, filter.c_str(), 0, PCAP_NETMASK_UNKNOWN)) {
-        throwException(env, "pcap_compile failed");
-        return false;
-    }
-
-    // Install BPF filter on bpf_pcap
-    if (pcap_setfilter(bpf_pcap.get(), &bpf)) {
-        throwException(env, "pcap_setfilter failed");
-        return false;
-    }
-
-    while (1) {
-        pcap_pkthdr bpf_header, apf_header;
-        // Run BPF filter to the next matching packet.
-        const uint8_t* bpf_packet = pcap_next(bpf_pcap.get(), &bpf_header);
-
-        // Run APF filter to the next matching packet.
-        const uint8_t* apf_packet;
-        do {
-            apf_packet = pcap_next(apf_pcap.get(), &apf_header);
-        } while (apf_packet != NULL && !accept_packet(
-                reinterpret_cast<uint8_t*>(const_cast<int8_t*>(apf_program.get())),
-                apf_program.size(), 0 /* data_len */,
-                apf_packet, apf_header.len, 0 /* filter_age */));
-
-        // Make sure both filters matched the same packet.
-        if (apf_packet == NULL && bpf_packet == NULL)
-            break;
-        if (apf_packet == NULL || bpf_packet == NULL)
-            return false;
-        if (apf_header.len != bpf_header.len ||
-                apf_header.ts.tv_sec != bpf_header.ts.tv_sec ||
-                apf_header.ts.tv_usec != bpf_header.ts.tv_usec ||
-                memcmp(apf_packet, bpf_packet, apf_header.len))
-            return false;
-    }
-    return true;
-}
-
-static jboolean com_android_server_ApfTest_dropsAllPackets(JNIEnv* env, jclass, jbyteArray jprogram,
-        jbyteArray jdata, jstring jpcap_filename) {
-    ScopedUtfChars pcap_filename(env, jpcap_filename);
-    ScopedByteArrayRO apf_program(env, jprogram);
-    uint32_t apf_program_len = (uint32_t)apf_program.size();
-    uint32_t data_len = env->GetArrayLength(jdata);
-    pcap_pkthdr apf_header;
-    const uint8_t* apf_packet;
-    char pcap_error[PCAP_ERRBUF_SIZE];
-    std::vector<uint8_t> buf(apf_program_len + data_len, 0);
-
-    // Merge program and data into a single buffer.
-    env->GetByteArrayRegion(jprogram, 0, apf_program_len, reinterpret_cast<jbyte*>(buf.data()));
-    env->GetByteArrayRegion(jdata, 0, data_len,
-                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-
-    // Open pcap file
-    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
-    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
-
-    if (apf_pcap.get() == NULL) {
-        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
-        return false;
-    }
-
-    while ((apf_packet = pcap_next(apf_pcap.get(), &apf_header)) != NULL) {
-        int result = accept_packet(buf.data(), apf_program_len,
-                                    apf_program_len + data_len, apf_packet, apf_header.len, 0);
-
-        // Return false once packet passes the filter
-        if (result) {
-            env->SetByteArrayRegion(jdata, 0, data_len,
-                                    reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-            return false;
-         }
-    }
-
-    env->SetByteArrayRegion(jdata, 0, data_len,
-                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
-    return true;
-}
-
-extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
-    JNIEnv *env;
-    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
-        ALOGE("ERROR: GetEnv failed");
-        return -1;
-    }
-
-    static JNINativeMethod gMethods[] = {
-            { "apfSimulate", "([B[B[BI)I",
-                    (void*)com_android_server_ApfTest_apfSimulate },
-            { "compileToBpf", "(Ljava/lang/String;)Ljava/lang/String;",
-                    (void*)com_android_server_ApfTest_compileToBpf },
-            { "compareBpfApf", "(Ljava/lang/String;Ljava/lang/String;[B)Z",
-                    (void*)com_android_server_ApfTest_compareBpfApf },
-            { "dropsAllPackets", "([B[BLjava/lang/String;)Z",
-                    (void*)com_android_server_ApfTest_dropsAllPackets },
-    };
-
-    jniRegisterNativeMethods(env, "android/net/apf/ApfTest",
-            gMethods, ARRAY_SIZE(gMethods));
-
-    return JNI_VERSION_1_6;
-}
diff --git a/packages/NetworkStack/tests/unit/res/raw/apf.pcap b/packages/NetworkStack/tests/unit/res/raw/apf.pcap
deleted file mode 100644
index 963165f..0000000
--- a/packages/NetworkStack/tests/unit/res/raw/apf.pcap
+++ /dev/null
Binary files differ
diff --git a/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap b/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap
deleted file mode 100644
index 6f69c4a..0000000
--- a/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap
+++ /dev/null
Binary files differ
diff --git a/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java
deleted file mode 100644
index 8f2b968..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java
+++ /dev/null
@@ -1,2110 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.apf;
-
-import static android.system.OsConstants.AF_UNIX;
-import static android.system.OsConstants.ARPHRD_ETHER;
-import static android.system.OsConstants.ETH_P_ARP;
-import static android.system.OsConstants.ETH_P_IP;
-import static android.system.OsConstants.ETH_P_IPV6;
-import static android.system.OsConstants.IPPROTO_ICMPV6;
-import static android.system.OsConstants.IPPROTO_TCP;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_STREAM;
-
-import static com.android.internal.util.BitUtils.bytesToBEInt;
-import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
-
-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.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.TcpKeepalivePacketDataParcelable;
-import android.net.apf.ApfFilter.ApfConfiguration;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-import android.net.ip.IIpClientCallbacks;
-import android.net.ip.IpClient.IpClientCallbacksWrapper;
-import android.net.metrics.IpConnectivityLog;
-import android.net.metrics.RaEvent;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.ConditionVariable;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.format.DateUtils;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.HexDump;
-import com.android.server.networkstack.tests.R;
-import com.android.server.util.NetworkStackConstants;
-
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-
-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 java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Tests for APF program generator and interpreter.
- *
- * Build, install and run with:
- *  runtest frameworks-net -c android.net.apf.ApfTest
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ApfTest {
-    private static final int TIMEOUT_MS = 500;
-    private static final int MIN_APF_VERSION = 2;
-
-    @Mock IpConnectivityLog mLog;
-    @Mock Context mContext;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        // Load up native shared library containing APF interpreter exposed via JNI.
-        System.loadLibrary("networkstacktestsjni");
-    }
-
-    private static final String TAG = "ApfTest";
-    // Expected return codes from APF interpreter.
-    private static final int PASS = 1;
-    private static final int DROP = 0;
-    // Interpreter will just accept packets without link layer headers, so pad fake packet to at
-    // least the minimum packet size.
-    private static final int MIN_PKT_SIZE = 15;
-
-    private static final ApfCapabilities MOCK_APF_CAPABILITIES =
-      new ApfCapabilities(2, 1700, ARPHRD_ETHER);
-
-    private static final boolean DROP_MULTICAST = true;
-    private static final boolean ALLOW_MULTICAST = false;
-
-    private static final boolean DROP_802_3_FRAMES = true;
-    private static final boolean ALLOW_802_3_FRAMES = false;
-
-    // Constants for opcode encoding
-    private static final byte LI_OP   = (byte)(13 << 3);
-    private static final byte LDDW_OP = (byte)(22 << 3);
-    private static final byte STDW_OP = (byte)(23 << 3);
-    private static final byte SIZE0   = (byte)(0 << 1);
-    private static final byte SIZE8   = (byte)(1 << 1);
-    private static final byte SIZE16  = (byte)(2 << 1);
-    private static final byte SIZE32  = (byte)(3 << 1);
-    private static final byte R1 = 1;
-
-    private static ApfConfiguration getDefaultConfig() {
-        ApfFilter.ApfConfiguration config = new ApfConfiguration();
-        config.apfCapabilities = MOCK_APF_CAPABILITIES;
-        config.multicastFilter = ALLOW_MULTICAST;
-        config.ieee802_3Filter = ALLOW_802_3_FRAMES;
-        config.ethTypeBlackList = new int[0];
-        return config;
-    }
-
-    private static String label(int code) {
-        switch (code) {
-            case PASS: return "PASS";
-            case DROP: return "DROP";
-            default:   return "UNKNOWN";
-        }
-    }
-
-    private static void assertReturnCodesEqual(int expected, int got) {
-        assertEquals(label(expected), label(got));
-    }
-
-    private void assertVerdict(int expected, byte[] program, byte[] packet, int filterAge) {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, null, filterAge));
-    }
-
-    private void assertVerdict(int expected, byte[] program, byte[] packet) {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, null, 0));
-    }
-
-    private void assertPass(byte[] program, byte[] packet, int filterAge) {
-        assertVerdict(PASS, program, packet, filterAge);
-    }
-
-    private void assertPass(byte[] program, byte[] packet) {
-        assertVerdict(PASS, program, packet);
-    }
-
-    private void assertDrop(byte[] program, byte[] packet, int filterAge) {
-        assertVerdict(DROP, program, packet, filterAge);
-    }
-
-    private void assertDrop(byte[] program, byte[] packet) {
-        assertVerdict(DROP, program, packet);
-    }
-
-    private void assertProgramEquals(byte[] expected, byte[] program) throws AssertionError {
-        // assertArrayEquals() would only print one byte, making debugging difficult.
-        if (!java.util.Arrays.equals(expected, program)) {
-            throw new AssertionError(
-                    "\nexpected: " + HexDump.toHexString(expected) +
-                    "\nactual:   " + HexDump.toHexString(program));
-        }
-    }
-
-    private void assertDataMemoryContents(
-            int expected, byte[] program, byte[] packet, byte[] data, byte[] expected_data)
-            throws IllegalInstructionException, Exception {
-        assertReturnCodesEqual(expected, apfSimulate(program, packet, data, 0 /* filterAge */));
-
-        // assertArrayEquals() would only print one byte, making debugging difficult.
-        if (!java.util.Arrays.equals(expected_data, data)) {
-            throw new Exception(
-                    "\nprogram:     " + HexDump.toHexString(program) +
-                    "\ndata memory: " + HexDump.toHexString(data) +
-                    "\nexpected:    " + HexDump.toHexString(expected_data));
-        }
-    }
-
-    private void assertVerdict(int expected, ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertReturnCodesEqual(expected, apfSimulate(gen.generate(), packet, null,
-              filterAge));
-    }
-
-    private void assertPass(ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertVerdict(PASS, gen, packet, filterAge);
-    }
-
-    private void assertDrop(ApfGenerator gen, byte[] packet, int filterAge)
-            throws IllegalInstructionException {
-        assertVerdict(DROP, gen, packet, filterAge);
-    }
-
-    private void assertPass(ApfGenerator gen)
-            throws IllegalInstructionException {
-        assertVerdict(PASS, gen, new byte[MIN_PKT_SIZE], 0);
-    }
-
-    private void assertDrop(ApfGenerator gen)
-            throws IllegalInstructionException {
-        assertVerdict(DROP, gen, new byte[MIN_PKT_SIZE], 0);
-    }
-
-    /**
-     * Test each instruction by generating a program containing the instruction,
-     * generating bytecode for that program and running it through the
-     * interpreter to verify it functions correctly.
-     */
-    @Test
-    public void testApfInstructions() throws IllegalInstructionException {
-        // Empty program should pass because having the program counter reach the
-        // location immediately after the program indicates the packet should be
-        // passed to the AP.
-        ApfGenerator gen = new ApfGenerator(MIN_APF_VERSION);
-        assertPass(gen);
-
-        // Test jumping to pass label.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJump(gen.PASS_LABEL);
-        byte[] program = gen.generate();
-        assertEquals(1, program.length);
-        assertEquals((14 << 3) | (0 << 1) | 0, program[0]);
-        assertPass(program, new byte[MIN_PKT_SIZE], 0);
-
-        // Test jumping to drop label.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJump(gen.DROP_LABEL);
-        program = gen.generate();
-        assertEquals(2, program.length);
-        assertEquals((14 << 3) | (1 << 1) | 0, program[0]);
-        assertEquals(1, program[1]);
-        assertDrop(program, new byte[15], 15);
-
-        // Test jumping if equal to 0.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if not equal to 0.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if registers equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0EqualsR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if registers not equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test load immediate.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test add.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addAdd(1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test subtract.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addAdd(-1234567890);
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test or.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addOr(1234567890);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test and.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addAnd(123456789);
-        gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test left shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLeftShift(1);
-        gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test right shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addRightShift(1);
-        gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test multiply.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 123456789);
-        gen.addMul(2);
-        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addDiv(2);
-        gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide by zero.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addDiv(0);
-        gen.addJump(gen.DROP_LABEL);
-        assertPass(gen);
-
-        // Test add.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addAddR1();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test subtract.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, -1234567890);
-        gen.addAddR1();
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test or.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addOrR1();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test and.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 123456789);
-        gen.addAndR1();
-        gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test left shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLeftShiftR1();
-        gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test right shift.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, -1);
-        gen.addLeftShiftR1();
-        gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test multiply.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 123456789);
-        gen.addLoadImmediate(Register.R1, 2);
-        gen.addMulR1();
-        gen.addJumpIfR0Equals(123456789 * 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addLoadImmediate(Register.R1, 2);
-        gen.addDivR1();
-        gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test divide by zero.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addDivR1();
-        gen.addJump(gen.DROP_LABEL);
-        assertPass(gen);
-
-        // Test byte load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad8(Register.R0, 1);
-        gen.addJumpIfR0Equals(45, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test out of bounds load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad8(Register.R0, 16);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test half-word load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad16(Register.R0, 1);
-        gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test word load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoad32(Register.R0, 1);
-        gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test byte indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad8Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals(45, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test out of bounds indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 8);
-        gen.addLoad8Indexed(Register.R0, 8);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test half-word indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad16Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test word indexed load.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addLoad32Indexed(Register.R0, 0);
-        gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0);
-
-        // Test jumping if greater than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if less than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThan(0, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThan(1, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if any bits set.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if register greater than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 2);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if register less than.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfR0LessThanR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1);
-        gen.addJumpIfR0LessThanR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jumping if any bits set in register.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertPass(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 3);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test load from memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, 0);
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test store to memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addStoreToMemory(Register.R1, 12);
-        gen.addLoadFromMemory(Register.R0, 12);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test filter age pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen, new byte[MIN_PKT_SIZE], 1234567890);
-
-        // Test packet size pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(MIN_PKT_SIZE, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test IPv4 header size pre-filled memory.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-        gen.addJumpIfR0Equals(20, gen.DROP_LABEL);
-        assertDrop(gen, new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x45}, 0);
-
-        // Test not.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addNot(Register.R0);
-        gen.addJumpIfR0Equals(~1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test negate.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addNeg(Register.R0);
-        gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test move.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addMove(Register.R0);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addMove(Register.R1);
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test swap.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R1, 1234567890);
-        gen.addSwap();
-        gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL);
-        assertDrop(gen);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1234567890);
-        gen.addSwap();
-        gen.addJumpIfR0Equals(0, gen.DROP_LABEL);
-        assertDrop(gen);
-
-        // Test jump if bytes not equal.
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        program = gen.generate();
-        assertEquals(6, program.length);
-        assertEquals((13 << 3) | (1 << 1) | 0, program[0]);
-        assertEquals(1, program[1]);
-        assertEquals(((20 << 3) | (1 << 1) | 0) - 256, program[2]);
-        assertEquals(1, program[3]);
-        assertEquals(1, program[4]);
-        assertEquals(123, program[5]);
-        assertDrop(program, new byte[MIN_PKT_SIZE], 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        byte[] packet123 = {0,123,0,0,0,0,0,0,0,0,0,0,0,0,0};
-        assertPass(gen, packet123, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL);
-        assertDrop(gen, packet123, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,30,4,5}, gen.DROP_LABEL);
-        byte[] packet12345 = {0,1,2,3,4,5,0,0,0,0,0,0,0,0,0};
-        assertDrop(gen, packet12345, 0);
-        gen = new ApfGenerator(MIN_APF_VERSION);
-        gen.addLoadImmediate(Register.R0, 1);
-        gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,3,4,5}, gen.DROP_LABEL);
-        assertPass(gen, packet12345, 0);
-    }
-
-    @Test(expected = ApfGenerator.IllegalInstructionException.class)
-    public void testApfGeneratorWantsV2OrGreater() throws Exception {
-        // The minimum supported APF version is 2.
-        new ApfGenerator(1);
-    }
-
-    @Test
-    public void testApfDataOpcodesWantApfV3() throws IllegalInstructionException, Exception {
-        ApfGenerator gen = new ApfGenerator(MIN_APF_VERSION);
-        try {
-            gen.addStoreData(Register.R0, 0);
-            fail();
-        } catch (IllegalInstructionException expected) {
-            /* pass */
-        }
-        try {
-            gen.addLoadData(Register.R0, 0);
-            fail();
-        } catch (IllegalInstructionException expected) {
-            /* pass */
-        }
-    }
-
-    /**
-     * Test that the generator emits immediates using the shortest possible encoding.
-     */
-    @Test
-    public void testImmediateEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // 0-byte immediate: li R0, 0
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R0, 0);
-        assertProgramEquals(new byte[]{LI_OP | SIZE0}, gen.generate());
-
-        // 1-byte immediate: li R0, 42
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R0, 42);
-        assertProgramEquals(new byte[]{LI_OP | SIZE8, 42}, gen.generate());
-
-        // 2-byte immediate: li R1, 0x1234
-        gen = new ApfGenerator(4);
-        gen.addLoadImmediate(Register.R1, 0x1234);
-        assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, 0x12, 0x34}, gen.generate());
-
-        // 4-byte immediate: li R0, 0x12345678
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 0x12345678);
-        assertProgramEquals(
-                new byte[]{LI_OP | SIZE32, 0x12, 0x34, 0x56, 0x78},
-                gen.generate());
-    }
-
-    /**
-     * Test that the generator emits negative immediates using the shortest possible encoding.
-     */
-    @Test
-    public void testNegativeImmediateEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // 1-byte negative immediate: li R0, -42
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, -42);
-        assertProgramEquals(new byte[]{LI_OP | SIZE8, -42}, gen.generate());
-
-        // 2-byte negative immediate: li R1, -0x1122
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, -0x1122);
-        assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
-                gen.generate());
-
-        // 4-byte negative immediate: li R0, -0x11223344
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, -0x11223344);
-        assertProgramEquals(
-                new byte[]{LI_OP | SIZE32, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBC},
-                gen.generate());
-    }
-
-    /**
-     * Test that the generator correctly emits positive and negative immediates for LDDW/STDW.
-     */
-    @Test
-    public void testLoadStoreDataEncoding() throws IllegalInstructionException {
-        ApfGenerator gen;
-
-        // Load data with no offset: lddw R0, [0 + r1]
-        gen = new ApfGenerator(3);
-        gen.addLoadData(Register.R0, 0);
-        assertProgramEquals(new byte[]{LDDW_OP | SIZE0}, gen.generate());
-
-        // Store data with 8bit negative offset: lddw r0, [-42 + r1]
-        gen = new ApfGenerator(3);
-        gen.addStoreData(Register.R0, -42);
-        assertProgramEquals(new byte[]{STDW_OP | SIZE8, -42}, gen.generate());
-
-        // Store data to R1 with 16bit negative offset: stdw r1, [-0x1122 + r0]
-        gen = new ApfGenerator(3);
-        gen.addStoreData(Register.R1, -0x1122);
-        assertProgramEquals(new byte[]{STDW_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
-                gen.generate());
-
-        // Load data to R1 with 32bit negative offset: lddw r1, [0xDEADBEEF + r0]
-        gen = new ApfGenerator(3);
-        gen.addLoadData(Register.R1, 0xDEADBEEF);
-        assertProgramEquals(
-                new byte[]{LDDW_OP | SIZE32 | R1, (byte)0xDE, (byte)0xAD, (byte)0xBE, (byte)0xEF},
-                gen.generate());
-    }
-
-    /**
-     * Test that the interpreter correctly executes STDW with a negative 8bit offset
-     */
-    @Test
-    public void testApfDataWrite() throws IllegalInstructionException, Exception {
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
-        byte[] expected_data = data.clone();
-
-        // No memory access instructions: should leave the data segment untouched.
-        ApfGenerator gen = new ApfGenerator(3);
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-
-        // Expect value 0x87654321 to be stored starting from address -11 from the end of the
-        // data buffer, in big-endian order.
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 0x87654321);
-        gen.addLoadImmediate(Register.R1, -5);
-        gen.addStoreData(Register.R0, -6);  // -5 + -6 = -11 (offset +5 with data_len=16)
-        expected_data[5] = (byte)0x87;
-        expected_data[6] = (byte)0x65;
-        expected_data[7] = (byte)0x43;
-        expected_data[8] = (byte)0x21;
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    /**
-     * Test that the interpreter correctly executes LDDW with a negative 16bit offset
-     */
-    @Test
-    public void testApfDataRead() throws IllegalInstructionException, Exception {
-        // Program that DROPs if address 10 (-6) contains 0x87654321.
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, 1000);
-        gen.addLoadData(Register.R0, -1006);  // 1000 + -1006 = -6 (offset +10 with data_len=16)
-        gen.addJumpIfR0Equals(0x87654321, gen.DROP_LABEL);
-        byte[] program = gen.generate();
-        byte[] packet = new byte[MIN_PKT_SIZE];
-
-        // Content is incorrect (last byte does not match) -> PASS
-        byte[] data = new byte[16];
-        data[10] = (byte)0x87;
-        data[11] = (byte)0x65;
-        data[12] = (byte)0x43;
-        data[13] = (byte)0x00;  // != 0x21
-        byte[] expected_data = data.clone();
-        assertDataMemoryContents(PASS, program, packet, data, expected_data);
-
-        // Fix the last byte -> conditional jump taken -> DROP
-        data[13] = (byte)0x21;
-        expected_data = data;
-        assertDataMemoryContents(DROP, program, packet, data, expected_data);
-    }
-
-    /**
-     * Test that the interpreter correctly executes LDDW followed by a STDW.
-     * To cover a few more edge cases, LDDW has a 0bit offset, while STDW has a positive 8bit
-     * offset.
-     */
-    @Test
-    public void testApfDataReadModifyWrite() throws IllegalInstructionException, Exception {
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R1, -22);
-        gen.addLoadData(Register.R0, 0);  // Load from address 32 -22 + 0 = 10
-        gen.addAdd(0x78453412);  // 87654321 + 78453412 = FFAA7733
-        gen.addStoreData(Register.R0, 4);  // Write back to address 32 -22 + 4 = 14
-
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = new byte[32];
-        data[10] = (byte)0x87;
-        data[11] = (byte)0x65;
-        data[12] = (byte)0x43;
-        data[13] = (byte)0x21;
-        byte[] expected_data = data.clone();
-        expected_data[14] = (byte)0xFF;
-        expected_data[15] = (byte)0xAA;
-        expected_data[16] = (byte)0x77;
-        expected_data[17] = (byte)0x33;
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    @Test
-    public void testApfDataBoundChecking() throws IllegalInstructionException, Exception {
-        byte[] packet = new byte[MIN_PKT_SIZE];
-        byte[] data = new byte[32];
-        byte[] expected_data = data;
-
-        // Program that DROPs unconditionally. This is our the baseline.
-        ApfGenerator gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 3);
-        gen.addLoadData(Register.R1, 7);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // Same program as before, but this time we're trying to load past the end of the data.
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, 15);  // 20 + 15 > 32
-        gen.addJump(gen.DROP_LABEL);  // Not reached.
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-
-        // Subtracting an immediate should work...
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -4);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // ...and underflowing simply wraps around to the end of the buffer...
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -30);
-        gen.addJump(gen.DROP_LABEL);
-        assertDataMemoryContents(DROP, gen.generate(), packet, data, expected_data);
-
-        // ...but doesn't allow accesses before the start of the buffer
-        gen = new ApfGenerator(3);
-        gen.addLoadImmediate(Register.R0, 20);
-        gen.addLoadData(Register.R1, -1000);
-        gen.addJump(gen.DROP_LABEL);  // Not reached.
-        assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
-    }
-
-    /**
-     * Generate some BPF programs, translate them to APF, then run APF and BPF programs
-     * over packet traces and verify both programs filter out the same packets.
-     */
-    @Test
-    public void testApfAgainstBpf() throws Exception {
-        String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
-                "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
-                "arp or icmp6 or portrange 53-54", "portrange 53-54 or portrange 100-50000",
-                "tcp[tcpflags] & (tcp-ack|tcp-fin) != 0 and (ip[2:2] > 57 or icmp)" };
-        String pcap_filename = stageFile(R.raw.apf);
-        for (String tcpdump_filter : tcpdump_filters) {
-            byte[] apf_program = Bpf2Apf.convert(compileToBpf(tcpdump_filter));
-            assertTrue("Failed to match for filter: " + tcpdump_filter,
-                    compareBpfApf(tcpdump_filter, pcap_filename, apf_program));
-        }
-    }
-
-    /**
-     * Generate APF program, run pcap file though APF filter, then check all the packets in the file
-     * should be dropped.
-     */
-    @Test
-    public void testApfFilterPcapFile() throws Exception {
-        final byte[] MOCK_PCAP_IPV4_ADDR = {(byte) 172, 16, 7, (byte) 151};
-        String pcapFilename = stageFile(R.raw.apfPcap);
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_PCAP_IPV4_ADDR), 16);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        ApfCapabilities MOCK_APF_PCAP_CAPABILITIES = new ApfCapabilities(4, 1700, ARPHRD_ETHER);
-        config.apfCapabilities = MOCK_APF_PCAP_CAPABILITIES;
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        byte[] program = ipClientCallback.getApfProgram();
-        byte[] data = new byte[ApfFilter.Counter.totalSize()];
-        final boolean result;
-
-        result = dropsAllPackets(program, data, pcapFilename);
-        Log.i(TAG, "testApfFilterPcapFile(): Data counters: " + HexDump.toHexString(data, false));
-
-        assertTrue("Failed to drop all packets by filter. \nAPF counters:" +
-            HexDump.toHexString(data, false), result);
-    }
-
-    private class MockIpClientCallback extends IpClientCallbacksWrapper {
-        private final ConditionVariable mGotApfProgram = new ConditionVariable();
-        private byte[] mLastApfProgram;
-
-        MockIpClientCallback() {
-            super(mock(IIpClientCallbacks.class), mock(SharedLog.class));
-        }
-
-        @Override
-        public void installPacketFilter(byte[] filter) {
-            mLastApfProgram = filter;
-            mGotApfProgram.open();
-        }
-
-        public void resetApfProgramWait() {
-            mGotApfProgram.close();
-        }
-
-        public byte[] getApfProgram() {
-            assertTrue(mGotApfProgram.block(TIMEOUT_MS));
-            return mLastApfProgram;
-        }
-
-        public void assertNoProgramUpdate() {
-            assertFalse(mGotApfProgram.block(TIMEOUT_MS));
-        }
-    }
-
-    private static class TestApfFilter extends ApfFilter {
-        public static final byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6};
-
-        private FileDescriptor mWriteSocket;
-        private final long mFixedTimeMs = SystemClock.elapsedRealtime();
-
-        public TestApfFilter(Context context, ApfConfiguration config,
-                IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) throws Exception {
-            super(context, config, InterfaceParams.getByName("lo"), ipClientCallback, log);
-        }
-
-        // Pretend an RA packet has been received and show it to ApfFilter.
-        public void pretendPacketReceived(byte[] packet) throws IOException, ErrnoException {
-            // ApfFilter's ReceiveThread will be waiting to read this.
-            Os.write(mWriteSocket, packet, 0, packet.length);
-        }
-
-        @Override
-        protected long currentTimeSeconds() {
-            return mFixedTimeMs / DateUtils.SECOND_IN_MILLIS;
-        }
-
-        @Override
-        void maybeStartFilter() {
-            mHardwareAddress = MOCK_MAC_ADDR;
-            installNewProgramLocked();
-
-            // Create two sockets, "readSocket" and "mWriteSocket" and connect them together.
-            FileDescriptor readSocket = new FileDescriptor();
-            mWriteSocket = new FileDescriptor();
-            try {
-                Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mWriteSocket, readSocket);
-            } catch (ErrnoException e) {
-                fail();
-                return;
-            }
-            // Now pass readSocket to ReceiveThread as if it was setup to read raw RAs.
-            // This allows us to pretend RA packets have been recieved via pretendPacketReceived().
-            mReceiveThread = new ReceiveThread(readSocket);
-            mReceiveThread.start();
-        }
-
-        @Override
-        public void shutdown() {
-            super.shutdown();
-            IoUtils.closeQuietly(mWriteSocket);
-        }
-    }
-
-    private static final int ETH_HEADER_LEN               = 14;
-    private static final int ETH_DEST_ADDR_OFFSET         = 0;
-    private static final int ETH_ETHERTYPE_OFFSET         = 12;
-    private static final byte[] ETH_BROADCAST_MAC_ADDRESS =
-            {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
-
-    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_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;
-
-    private static final int IPV4_TCP_HEADER_LEN           = 20;
-    private static final int IPV4_TCP_HEADER_OFFSET        = ETH_HEADER_LEN + IPV4_HEADER_LEN;
-    private static final int IPV4_TCP_SRC_PORT_OFFSET      = IPV4_TCP_HEADER_OFFSET + 0;
-    private static final int IPV4_TCP_DEST_PORT_OFFSET     = IPV4_TCP_HEADER_OFFSET + 2;
-    private static final int IPV4_TCP_SEQ_NUM_OFFSET       = IPV4_TCP_HEADER_OFFSET + 4;
-    private static final int IPV4_TCP_ACK_NUM_OFFSET       = IPV4_TCP_HEADER_OFFSET + 8;
-    private static final int IPV4_TCP_HEADER_LENGTH_OFFSET = IPV4_TCP_HEADER_OFFSET + 12;
-    private static final int IPV4_TCP_HEADER_FLAG_OFFSET   = IPV4_TCP_HEADER_OFFSET + 13;
-
-    private static final int IPV4_UDP_HEADER_OFFSET    = ETH_HEADER_LEN + IPV4_HEADER_LEN;;
-    private static final int IPV4_UDP_SRC_PORT_OFFSET  = IPV4_UDP_HEADER_OFFSET + 0;
-    private static final int IPV4_UDP_DEST_PORT_OFFSET = IPV4_UDP_HEADER_OFFSET + 2;
-    private static final int IPV4_UDP_LENGTH_OFFSET    = IPV4_UDP_HEADER_OFFSET + 4;
-    private static final int IPV4_UDP_PAYLOAD_OFFSET   = IPV4_UDP_HEADER_OFFSET + 8;
-    private static final byte[] IPV4_BROADCAST_ADDRESS =
-            {(byte) 255, (byte) 255, (byte) 255, (byte) 255};
-
-    private static final int IPV6_HEADER_LEN             = 40;
-    private static final int IPV6_NEXT_HEADER_OFFSET     = ETH_HEADER_LEN + 6;
-    private static final int IPV6_SRC_ADDR_OFFSET        = ETH_HEADER_LEN + 8;
-    private static final int IPV6_DEST_ADDR_OFFSET       = ETH_HEADER_LEN + 24;
-    private static final int IPV6_TCP_HEADER_OFFSET      = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-    private static final int IPV6_TCP_SRC_PORT_OFFSET    = IPV6_TCP_HEADER_OFFSET + 0;
-    private static final int IPV6_TCP_DEST_PORT_OFFSET   = IPV6_TCP_HEADER_OFFSET + 2;
-    private static final int IPV6_TCP_SEQ_NUM_OFFSET     = IPV6_TCP_HEADER_OFFSET + 4;
-    private static final int IPV6_TCP_ACK_NUM_OFFSET     = IPV6_TCP_HEADER_OFFSET + 8;
-    // The IPv6 all nodes address ff02::1
-    private static final byte[] IPV6_ALL_NODES_ADDRESS   =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
-    private static final byte[] IPV6_ALL_ROUTERS_ADDRESS =
-            { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
-
-    private static final int ICMP6_TYPE_OFFSET           = ETH_HEADER_LEN + IPV6_HEADER_LEN;
-    private static final int ICMP6_ROUTER_SOLICITATION   = 133;
-    private static final int ICMP6_ROUTER_ADVERTISEMENT  = 134;
-    private static final int ICMP6_NEIGHBOR_SOLICITATION = 135;
-    private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136;
-
-    private static final int ICMP6_RA_HEADER_LEN = 16;
-    private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + 6;
-    private static final int ICMP6_RA_CHECKSUM_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + 2;
-    private static final int ICMP6_RA_OPTION_OFFSET =
-            ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN;
-
-    private static final int ICMP6_PREFIX_OPTION_TYPE                      = 3;
-    private static final int ICMP6_PREFIX_OPTION_LEN                       = 32;
-    private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET     = 4;
-    private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8;
-
-    // From RFC6106: Recursive DNS Server option
-    private static final int ICMP6_RDNSS_OPTION_TYPE = 25;
-    // From RFC6106: DNS Search List option
-    private static final int ICMP6_DNSSL_OPTION_TYPE = 31;
-
-    // From RFC4191: Route Information option
-    private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24;
-    // Above three options all have the same format:
-    private static final int ICMP6_4_BYTE_OPTION_LEN      = 8;
-    private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4;
-    private static final int ICMP6_4_BYTE_LIFETIME_LEN    = 4;
-
-    private static final int UDP_HEADER_LEN              = 8;
-    private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 22;
-
-    private static final int DHCP_CLIENT_PORT       = 68;
-    private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 48;
-
-    private static final int ARP_HEADER_OFFSET          = ETH_HEADER_LEN;
-    private static final byte[] ARP_IPV4_REQUEST_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-            0, 1  // Opcode: request (1)
-    };
-    private static final byte[] ARP_IPV4_REPLY_HEADER = {
-            0, 1, // Hardware type: Ethernet (1)
-            8, 0, // Protocol type: IP (0x0800)
-            6,    // Hardware size: 6
-            4,    // Protocol size: 4
-            0, 2  // Opcode: reply (2)
-    };
-    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
-    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
-
-    private static final byte[] MOCK_IPV4_ADDR           = {10, 0, 0, 1};
-    private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19
-    private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1};
-    private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
-    private static final byte[] IPV4_SOURCE_ADDR         = {10, 0, 0, 3};
-    private static final byte[] ANOTHER_IPV4_SOURCE_ADDR = {(byte) 192, 0, 2, 1};
-    private static final byte[] BUG_PROBE_SOURCE_ADDR1   = {0, 0, 1, 2};
-    private static final byte[] BUG_PROBE_SOURCE_ADDR2   = {3, 4, 0, 0};
-    private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
-
-    // Helper to initialize a default apfFilter.
-    private ApfFilter setupApfFilter(
-            IpClientCallbacksWrapper ipClientCallback, ApfConfiguration config) throws Exception {
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        return apfFilter;
-    }
-
-    @Test
-    public void testApfFilterIPv4() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify unicast IPv4 packet is passed
-        put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_IPV4_ADDR);
-        assertPass(program, packet.array());
-
-        // Verify L2 unicast to IPv4 broadcast addresses is dropped (b/30231088)
-        put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-
-        // Verify multicast/broadcast IPv4, not DHCP to us, is dropped
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        assertDrop(program, packet.array());
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte)0x45);
-        assertDrop(program, packet.array());
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte)IPPROTO_UDP);
-        assertDrop(program, packet.array());
-        packet.putShort(UDP_DESTINATION_PORT_OFFSET, (short)DHCP_CLIENT_PORT);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_MULTICAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR);
-        assertDrop(program, packet.array());
-        put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-        assertDrop(program, packet.array());
-
-        // Verify broadcast IPv4 DHCP to us is passed
-        put(packet, DHCP_CLIENT_MAC_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        assertPass(program, packet.array());
-
-        // Verify unicast IPv4 DHCP to us is passed
-        put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR);
-        assertPass(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterIPv6() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty IPv6 packet is passed
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Verify empty ICMPv6 packet is passed
-        packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        assertPass(program, packet.array());
-
-        // Verify empty ICMPv6 NA packet is passed
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_NEIGHBOR_ANNOUNCEMENT);
-        assertPass(program, packet.array());
-
-        // Verify ICMPv6 NA to ff02::1 is dropped
-        put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_NODES_ADDRESS);
-        assertDrop(program, packet.array());
-
-        // Verify ICMPv6 RS to any is dropped
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_SOLICITATION);
-        assertDrop(program, packet.array());
-        put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_ROUTERS_ADDRESS);
-        assertDrop(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterMulticast() throws Exception {
-        final byte[] unicastIpv4Addr   = {(byte)192,0,2,63};
-        final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
-        final byte[] multicastIpv4Addr = {(byte)224,0,0,1};
-        final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb};
-
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24);
-        LinkProperties lp = new LinkProperties();
-        lp.addLinkAddress(link);
-
-        ApfConfiguration config = getDefaultConfig();
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Construct IPv4 and IPv6 multicast packets.
-        ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]);
-        mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(mcastv4packet, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr);
-
-        ByteBuffer mcastv6packet = ByteBuffer.wrap(new byte[100]);
-        mcastv6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP);
-        put(mcastv6packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr);
-
-        // Construct IPv4 broadcast packet.
-        ByteBuffer bcastv4packet1 = ByteBuffer.wrap(new byte[100]);
-        bcastv4packet1.put(ETH_BROADCAST_MAC_ADDRESS);
-        bcastv4packet1.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4packet1, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr);
-
-        ByteBuffer bcastv4packet2 = ByteBuffer.wrap(new byte[100]);
-        bcastv4packet2.put(ETH_BROADCAST_MAC_ADDRESS);
-        bcastv4packet2.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4packet2, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS);
-
-        // Construct IPv4 broadcast with L2 unicast address packet (b/30231088).
-        ByteBuffer bcastv4unicastl2packet = ByteBuffer.wrap(new byte[100]);
-        bcastv4unicastl2packet.put(TestApfFilter.MOCK_MAC_ADDR);
-        bcastv4unicastl2packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        put(bcastv4unicastl2packet, IPV4_DEST_ADDR_OFFSET, broadcastIpv4Addr);
-
-        // Verify initially disabled multicast filter is off
-        assertPass(program, mcastv4packet.array());
-        assertPass(program, mcastv6packet.array());
-        assertPass(program, bcastv4packet1.array());
-        assertPass(program, bcastv4packet2.array());
-        assertPass(program, bcastv4unicastl2packet.array());
-
-        // Turn on multicast filter and verify it works
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.setMulticastFilter(true);
-        program = ipClientCallback.getApfProgram();
-        assertDrop(program, mcastv4packet.array());
-        assertDrop(program, mcastv6packet.array());
-        assertDrop(program, bcastv4packet1.array());
-        assertDrop(program, bcastv4packet2.array());
-        assertDrop(program, bcastv4unicastl2packet.array());
-
-        // Turn off multicast filter and verify it's off
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.setMulticastFilter(false);
-        program = ipClientCallback.getApfProgram();
-        assertPass(program, mcastv4packet.array());
-        assertPass(program, mcastv6packet.array());
-        assertPass(program, bcastv4packet1.array());
-        assertPass(program, bcastv4packet2.array());
-        assertPass(program, bcastv4unicastl2packet.array());
-
-        // Verify it can be initialized to on
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        apfFilter.setLinkProperties(lp);
-        program = ipClientCallback.getApfProgram();
-        assertDrop(program, mcastv4packet.array());
-        assertDrop(program, mcastv6packet.array());
-        assertDrop(program, bcastv4packet1.array());
-        assertDrop(program, bcastv4unicastl2packet.array());
-
-        // Verify that ICMPv6 multicast is not dropped.
-        mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        assertPass(program, mcastv6packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterMulticastPingWhileDozing() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, getDefaultConfig());
-
-        // Construct a multicast ICMPv6 ECHO request.
-        final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb};
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        packet.put(ICMP6_TYPE_OFFSET, (byte)ICMPV6_ECHO_REQUEST_TYPE);
-        put(packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr);
-
-        // Normally, we let multicast pings alone...
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        // ...and even while dozing...
-        apfFilter.setDozeMode(true);
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        // ...but when the multicast filter is also enabled, drop the multicast pings to save power.
-        apfFilter.setMulticastFilter(true);
-        assertDrop(ipClientCallback.getApfProgram(), packet.array());
-
-        // However, we should still let through all other ICMPv6 types.
-        ByteBuffer raPacket = ByteBuffer.wrap(packet.array().clone());
-        raPacket.put(ICMP6_TYPE_OFFSET, (byte) NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT);
-        assertPass(ipClientCallback.getApfProgram(), raPacket.array());
-
-        // Now wake up from doze mode to ensure that we no longer drop the packets.
-        // (The multicast filter is still enabled at this point).
-        apfFilter.setDozeMode(false);
-        assertPass(ipClientCallback.getApfProgram(), packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilter802_3() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, config);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        // Note that eth-type = 0 makes it an IEEE802.3 frame
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify empty packet with IPv4 is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify empty IPv6 packet is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now turn on the filter
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IEEE802.3 frame is dropped
-        // In this case ethtype is used for payload length
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)(100 - 14));
-        assertDrop(program, packet.array());
-
-        // Verify that IPv4 (as example of Ethernet II) frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify that IPv6 (as example of Ethernet II) frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    @Test
-    public void testApfFilterEthTypeBL() throws Exception {
-        final int[] emptyBlackList = {};
-        final int[] ipv4BlackList = {ETH_P_IP};
-        final int[] ipv4Ipv6BlackList = {ETH_P_IP, ETH_P_IPV6};
-
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        ApfFilter apfFilter = setupApfFilter(ipClientCallback, config);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        // Verify empty packet of 100 zero bytes is passed
-        // Note that eth-type = 0 makes it an IEEE802.3 frame
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        assertPass(program, packet.array());
-
-        // Verify empty packet with IPv4 is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertPass(program, packet.array());
-
-        // Verify empty IPv6 packet is passed
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now add IPv4 to the black list
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ethTypeBlackList = ipv4BlackList;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IPv4 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertDrop(program, packet.array());
-
-        // Verify that IPv6 frame will pass
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertPass(program, packet.array());
-
-        // Now let us have both IPv4 and IPv6 in the black list
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.shutdown();
-        config.ethTypeBlackList = ipv4Ipv6BlackList;
-        apfFilter = setupApfFilter(ipClientCallback, config);
-        program = ipClientCallback.getApfProgram();
-
-        // Verify that IPv4 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP);
-        assertDrop(program, packet.array());
-
-        // Verify that IPv6 frame will be dropped
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        assertDrop(program, packet.array());
-
-        apfFilter.shutdown();
-    }
-
-    private byte[] getProgram(MockIpClientCallback cb, ApfFilter filter, LinkProperties lp) {
-        cb.resetApfProgramWait();
-        filter.setLinkProperties(lp);
-        return cb.getApfProgram();
-    }
-
-    private void verifyArpFilter(byte[] program, int filterResult) {
-        // Verify ARP request packet
-        assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR));
-        assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR));
-        assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR));
-
-        // Verify ARP reply packets from different source ip
-        assertDrop(program, arpReply(IPV4_ANY_HOST_ADDR, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(ANOTHER_IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR1, IPV4_ANY_HOST_ADDR));
-        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR2, IPV4_ANY_HOST_ADDR));
-
-        // Verify unicast ARP reply packet is always accepted.
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, MOCK_IPV4_ADDR));
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, ANOTHER_IPV4_ADDR));
-        assertPass(program, arpReply(IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
-
-        // Verify GARP reply packets are always filtered
-        assertDrop(program, garpReply());
-    }
-
-    @Test
-    public void testApfFilterArp() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-
-        // Verify initially ARP request filter is off, and GARP filter is on.
-        verifyArpFilter(ipClientCallback.getApfProgram(), PASS);
-
-        // Inform ApfFilter of our address and verify ARP filtering is on
-        LinkAddress linkAddress = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 24);
-        LinkProperties lp = new LinkProperties();
-        assertTrue(lp.addLinkAddress(linkAddress));
-        verifyArpFilter(getProgram(ipClientCallback, apfFilter, lp), DROP);
-
-        // Inform ApfFilter of loss of IP and verify ARP filtering is off
-        verifyArpFilter(getProgram(ipClientCallback, apfFilter, new LinkProperties()), PASS);
-
-        apfFilter.shutdown();
-    }
-
-    private static byte[] arpReply(byte[] sip, byte[] tip) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
-        put(packet, ARP_SOURCE_IP_ADDRESS_OFFSET, sip);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
-        return packet.array();
-    }
-
-    private static byte[] arpRequestBroadcast(byte[] tip) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REQUEST_HEADER);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
-        return packet.array();
-    }
-
-    private static byte[] garpReply() {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
-        put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, IPV4_ANY_HOST_ADDR);
-        return packet.array();
-    }
-
-    private static final byte[] IPV4_KEEPALIVE_SRC_ADDR = {10, 0, 0, 5};
-    private static final byte[] IPV4_KEEPALIVE_DST_ADDR = {10, 0, 0, 6};
-    private static final byte[] IPV4_ANOTHER_ADDR = {10, 0 , 0, 7};
-    private static final byte[] IPV6_KEEPALIVE_SRC_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf1};
-    private static final byte[] IPV6_KEEPALIVE_DST_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf2};
-    private static final byte[] IPV6_ANOTHER_ADDR =
-            {(byte) 0x24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xfa, (byte) 0xf5};
-
-    @Test
-    public void testApfFilterKeepaliveAck() throws Exception {
-        final MockIpClientCallback cb = new MockIpClientCallback();
-        final ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        byte[] program;
-        final int srcPort = 12345;
-        final int dstPort = 54321;
-        final int seqNum = 2123456789;
-        final int ackNum = 1234567890;
-        final int anotherSrcPort = 23456;
-        final int anotherDstPort = 65432;
-        final int anotherSeqNum = 2123456780;
-        final int anotherAckNum = 1123456789;
-        final int slot1 = 1;
-        final int slot2 = 2;
-        final int window = 14480;
-        final int windowScale = 4;
-
-        // src: 10.0.0.5, port: 12345
-        // dst: 10.0.0.6, port: 54321
-        InetAddress srcAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_SRC_ADDR);
-        InetAddress dstAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_DST_ADDR);
-
-        final TcpKeepalivePacketDataParcelable parcel = new TcpKeepalivePacketDataParcelable();
-        parcel.srcAddress = srcAddr.getAddress();
-        parcel.srcPort = srcPort;
-        parcel.dstAddress = dstAddr.getAddress();
-        parcel.dstPort = dstPort;
-        parcel.seq = seqNum;
-        parcel.ack = ackNum;
-
-        apfFilter.addTcpKeepalivePacketFilter(slot1, parcel);
-        program = cb.getApfProgram();
-
-        // Verify IPv4 keepalive ack packet is dropped
-        // src: 10.0.0.6, port: 54321
-        // dst: 10.0.0.5, port: 12345
-        assertDrop(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-        // Verify IPv4 non-keepalive ack packet from the same source address is passed
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum + 100, seqNum, 0 /* dataLength */));
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 10 /* dataLength */));
-        // Verify IPv4 packet from another address is passed
-        assertPass(program,
-                ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                        anotherDstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-
-        // Remove IPv4 keepalive filter
-        apfFilter.removeKeepalivePacketFilter(slot1);
-
-        try {
-            // src: 2404:0:0:0:0:0:faf1, port: 12345
-            // dst: 2404:0:0:0:0:0:faf2, port: 54321
-            srcAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_SRC_ADDR);
-            dstAddr = InetAddress.getByAddress(IPV6_KEEPALIVE_DST_ADDR);
-
-            final TcpKeepalivePacketDataParcelable ipv6Parcel =
-                    new TcpKeepalivePacketDataParcelable();
-            ipv6Parcel.srcAddress = srcAddr.getAddress();
-            ipv6Parcel.srcPort = srcPort;
-            ipv6Parcel.dstAddress = dstAddr.getAddress();
-            ipv6Parcel.dstPort = dstPort;
-            ipv6Parcel.seq = seqNum;
-            ipv6Parcel.ack = ackNum;
-
-            apfFilter.addTcpKeepalivePacketFilter(slot1, ipv6Parcel);
-            program = cb.getApfProgram();
-
-            // Verify IPv6 keepalive ack packet is dropped
-            // src: 2404:0:0:0:0:0:faf2, port: 54321
-            // dst: 2404:0:0:0:0:0:faf1, port: 12345
-            assertDrop(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1));
-            // Verify IPv6 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum));
-            // Verify IPv6 packet from another address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum));
-
-            // Remove IPv6 keepalive filter
-            apfFilter.removeKeepalivePacketFilter(slot1);
-
-            // Verify multiple filters
-            apfFilter.addTcpKeepalivePacketFilter(slot1, parcel);
-            apfFilter.addTcpKeepalivePacketFilter(slot2, ipv6Parcel);
-            program = cb.getApfProgram();
-
-            // Verify IPv4 keepalive ack packet is dropped
-            // src: 10.0.0.6, port: 54321
-            // dst: 10.0.0.5, port: 12345
-            assertDrop(program,
-                    ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-            // Verify IPv4 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum, 0 /* dataLength */));
-            // Verify IPv4 packet from another address is passed
-            assertPass(program,
-                    ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-
-            // Verify IPv6 keepalive ack packet is dropped
-            // src: 2404:0:0:0:0:0:faf2, port: 54321
-            // dst: 2404:0:0:0:0:0:faf1, port: 12345
-            assertDrop(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum, seqNum + 1));
-            // Verify IPv6 non-keepalive ack packet from the same source address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                            dstPort, srcPort, ackNum + 100, seqNum));
-            // Verify IPv6 packet from another address is passed
-            assertPass(program,
-                    ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, anotherSrcPort,
-                            anotherDstPort, anotherSeqNum, anotherAckNum));
-
-            // Remove keepalive filters
-            apfFilter.removeKeepalivePacketFilter(slot1);
-            apfFilter.removeKeepalivePacketFilter(slot2);
-        } catch (UnsupportedOperationException e) {
-            // TODO: support V6 packets
-        }
-
-        program = cb.getApfProgram();
-
-        // Verify IPv4, IPv6 packets are passed
-        assertPass(program,
-                ipv4Packet(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1, 0 /* dataLength */));
-        assertPass(program,
-                ipv6Packet(IPV6_KEEPALIVE_DST_ADDR, IPV6_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, ackNum, seqNum + 1));
-        assertPass(program,
-                ipv4Packet(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR, srcPort,
-                        dstPort, anotherSeqNum, anotherAckNum, 0 /* dataLength */));
-        assertPass(program,
-                ipv6Packet(IPV6_ANOTHER_ADDR, IPV6_KEEPALIVE_SRC_ADDR, srcPort,
-                        dstPort, anotherSeqNum, anotherAckNum));
-
-        apfFilter.shutdown();
-    }
-
-    private static byte[] ipv4Packet(byte[] sip, byte[] dip, int sport,
-            int dport, int seq, int ack, int dataLength) {
-        final int totalLength = dataLength + IPV4_HEADER_LEN + IPV4_TCP_HEADER_LEN;
-
-        ByteBuffer packet = ByteBuffer.wrap(new byte[totalLength + ETH_HEADER_LEN]);
-
-        // ether type
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IP);
-
-        // IPv4 header
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte) 0x45);
-        packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength);
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte) IPPROTO_TCP);
-        put(packet, IPV4_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV4_DEST_ADDR_OFFSET, dip);
-        packet.putShort(IPV4_TCP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV4_TCP_DEST_PORT_OFFSET, (short) dport);
-        packet.putInt(IPV4_TCP_SEQ_NUM_OFFSET, seq);
-        packet.putInt(IPV4_TCP_ACK_NUM_OFFSET, ack);
-
-        // TCP header length 5(20 bytes), reserved 3 bits, NS=0
-        packet.put(IPV4_TCP_HEADER_LENGTH_OFFSET, (byte) 0x50);
-        // TCP flags: ACK set
-        packet.put(IPV4_TCP_HEADER_FLAG_OFFSET, (byte) 0x10);
-        return packet.array();
-    }
-
-    private static byte[] ipv6Packet(byte[] sip, byte[] tip, int sport,
-            int dport, int seq, int ack) {
-        ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IPV6);
-        put(packet, IPV6_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV6_DEST_ADDR_OFFSET, tip);
-        packet.putShort(IPV6_TCP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV6_TCP_DEST_PORT_OFFSET, (short) dport);
-        packet.putInt(IPV6_TCP_SEQ_NUM_OFFSET, seq);
-        packet.putInt(IPV6_TCP_ACK_NUM_OFFSET, ack);
-        return packet.array();
-    }
-
-    @Test
-    public void testApfFilterNattKeepalivePacket() throws Exception {
-        final MockIpClientCallback cb = new MockIpClientCallback();
-        final ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        final TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        byte[] program;
-        final int srcPort = 1024;
-        final int dstPort = 4500;
-        final int slot1 = 1;
-        // NAT-T keepalive
-        final byte[] kaPayload = {(byte) 0xff};
-        final byte[] nonKaPayload = {(byte) 0xfe};
-
-        // src: 10.0.0.5, port: 1024
-        // dst: 10.0.0.6, port: 4500
-        InetAddress srcAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_SRC_ADDR);
-        InetAddress dstAddr = InetAddress.getByAddress(IPV4_KEEPALIVE_DST_ADDR);
-
-        final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
-        parcel.srcAddress = srcAddr.getAddress();
-        parcel.srcPort = srcPort;
-        parcel.dstAddress = dstAddr.getAddress();
-        parcel.dstPort = dstPort;
-
-        apfFilter.addNattKeepalivePacketFilter(slot1, parcel);
-        program = cb.getApfProgram();
-
-        // Verify IPv4 keepalive packet is dropped
-        // src: 10.0.0.6, port: 4500
-        // dst: 10.0.0.5, port: 1024
-        byte[] pkt = ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR,
-                    IPV4_KEEPALIVE_SRC_ADDR, dstPort, srcPort, 1 /* dataLength */);
-        System.arraycopy(kaPayload, 0, pkt, IPV4_UDP_PAYLOAD_OFFSET, kaPayload.length);
-        assertDrop(program, pkt);
-
-        // Verify a packet with payload length 1 byte but it is not 0xff will pass the filter.
-        System.arraycopy(nonKaPayload, 0, pkt, IPV4_UDP_PAYLOAD_OFFSET, nonKaPayload.length);
-        assertPass(program, pkt);
-
-        // Verify IPv4 non-keepalive response packet from the same source address is passed
-        assertPass(program,
-                ipv4UdpPacket(IPV4_KEEPALIVE_DST_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, 10 /* dataLength */));
-
-        // Verify IPv4 non-keepalive response packet from other source address is passed
-        assertPass(program,
-                ipv4UdpPacket(IPV4_ANOTHER_ADDR, IPV4_KEEPALIVE_SRC_ADDR,
-                        dstPort, srcPort, 10 /* dataLength */));
-
-        apfFilter.removeKeepalivePacketFilter(slot1);
-        apfFilter.shutdown();
-    }
-
-    private static byte[] ipv4UdpPacket(byte[] sip, byte[] dip, int sport,
-            int dport, int dataLength) {
-        final int totalLength = dataLength + IPV4_HEADER_LEN + UDP_HEADER_LEN;
-        final int udpLength = UDP_HEADER_LEN + dataLength;
-        ByteBuffer packet = ByteBuffer.wrap(new byte[totalLength + ETH_HEADER_LEN]);
-
-        // ether type
-        packet.putShort(ETH_ETHERTYPE_OFFSET, (short) ETH_P_IP);
-
-        // IPv4 header
-        packet.put(IPV4_VERSION_IHL_OFFSET, (byte) 0x45);
-        packet.putShort(IPV4_TOTAL_LENGTH_OFFSET, (short) totalLength);
-        packet.put(IPV4_PROTOCOL_OFFSET, (byte) IPPROTO_UDP);
-        put(packet, IPV4_SRC_ADDR_OFFSET, sip);
-        put(packet, IPV4_DEST_ADDR_OFFSET, dip);
-        packet.putShort(IPV4_UDP_SRC_PORT_OFFSET, (short) sport);
-        packet.putShort(IPV4_UDP_DEST_PORT_OFFSET, (short) dport);
-        packet.putShort(IPV4_UDP_LENGTH_OFFSET, (short) udpLength);
-
-        return packet.array();
-    }
-
-    // Verify that the last program pushed to the IpClient.Callback properly filters the
-    // given packet for the given lifetime.
-    private void verifyRaLifetime(byte[] program, ByteBuffer packet, int lifetime) {
-        final int FRACTION_OF_LIFETIME = 6;
-        final int ageLimit = lifetime / FRACTION_OF_LIFETIME;
-
-        // Verify new program should drop RA for 1/6th its lifetime and pass afterwards.
-        assertDrop(program, packet.array());
-        assertDrop(program, packet.array(), ageLimit);
-        assertPass(program, packet.array(), ageLimit + 1);
-        assertPass(program, packet.array(), lifetime);
-        // Verify RA checksum is ignored
-        final short originalChecksum = packet.getShort(ICMP6_RA_CHECKSUM_OFFSET);
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)12345);
-        assertDrop(program, packet.array());
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)-12345);
-        assertDrop(program, packet.array());
-        packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, originalChecksum);
-
-        // Verify other changes to RA make it not match filter
-        final byte originalFirstByte = packet.get(0);
-        packet.put(0, (byte)-1);
-        assertPass(program, packet.array());
-        packet.put(0, (byte)0);
-        assertDrop(program, packet.array());
-        packet.put(0, originalFirstByte);
-    }
-
-    // Test that when ApfFilter is shown the given packet, it generates a program to filter it
-    // for the given lifetime.
-    private void verifyRaLifetime(TestApfFilter apfFilter, MockIpClientCallback ipClientCallback,
-            ByteBuffer packet, int lifetime) throws IOException, ErrnoException {
-        // Verify new program generated if ApfFilter witnesses RA
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.pretendPacketReceived(packet.array());
-        byte[] program = ipClientCallback.getApfProgram();
-        verifyRaLifetime(program, packet, lifetime);
-    }
-
-    private void verifyRaEvent(RaEvent expected) {
-        ArgumentCaptor<IpConnectivityLog.Event> captor =
-                ArgumentCaptor.forClass(IpConnectivityLog.Event.class);
-        verify(mLog, atLeastOnce()).log(captor.capture());
-        RaEvent got = lastRaEvent(captor.getAllValues());
-        if (!raEventEquals(expected, got)) {
-            assertEquals(expected, got);  // fail for printing an assertion error message.
-        }
-    }
-
-    private RaEvent lastRaEvent(List<IpConnectivityLog.Event> events) {
-        RaEvent got = null;
-        for (Parcelable ev : events) {
-            if (ev instanceof RaEvent) {
-                got = (RaEvent) ev;
-            }
-        }
-        return got;
-    }
-
-    private boolean raEventEquals(RaEvent ev1, RaEvent ev2) {
-        return (ev1 != null) && (ev2 != null)
-                && (ev1.routerLifetime == ev2.routerLifetime)
-                && (ev1.prefixValidLifetime == ev2.prefixValidLifetime)
-                && (ev1.prefixPreferredLifetime == ev2.prefixPreferredLifetime)
-                && (ev1.routeInfoLifetime == ev2.routeInfoLifetime)
-                && (ev1.rdnssLifetime == ev2.rdnssLifetime)
-                && (ev1.dnsslLifetime == ev2.dnsslLifetime);
-    }
-
-    private void assertInvalidRa(TestApfFilter apfFilter, MockIpClientCallback ipClientCallback,
-            ByteBuffer packet) throws IOException, ErrnoException {
-        ipClientCallback.resetApfProgramWait();
-        apfFilter.pretendPacketReceived(packet.array());
-        ipClientCallback.assertNoProgramUpdate();
-    }
-
-    @Test
-    public void testApfFilterRa() throws Exception {
-        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
-        byte[] program = ipClientCallback.getApfProgram();
-
-        final int ROUTER_LIFETIME = 1000;
-        final int PREFIX_VALID_LIFETIME = 200;
-        final int PREFIX_PREFERRED_LIFETIME = 100;
-        final int RDNSS_LIFETIME  = 300;
-        final int ROUTE_LIFETIME  = 400;
-        // Note that lifetime of 2000 will be ignored in favor of shorter route lifetime of 1000.
-        final int DNSSL_LIFETIME  = 2000;
-        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET = ETH_HEADER_LEN;
-        // IPv6, traffic class = 0, flow label = 0x12345
-        final int VERSION_TRAFFIC_CLASS_FLOW_LABEL = 0x60012345;
-
-        // Verify RA is passed the first time
-        ByteBuffer basePacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
-        basePacket.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6);
-        basePacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
-                VERSION_TRAFFIC_CLASS_FLOW_LABEL);
-        basePacket.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6);
-        basePacket.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_ADVERTISEMENT);
-        basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)ROUTER_LIFETIME);
-        basePacket.position(IPV6_DEST_ADDR_OFFSET);
-        basePacket.put(IPV6_ALL_NODES_ADDRESS);
-        assertPass(program, basePacket.array());
-
-        verifyRaLifetime(apfFilter, ipClientCallback, basePacket, ROUTER_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, -1));
-
-        ByteBuffer newFlowLabelPacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]);
-        basePacket.clear();
-        newFlowLabelPacket.put(basePacket);
-        // Check that changes are ignored in every byte of the flow label.
-        newFlowLabelPacket.putInt(VERSION_TRAFFIC_CLASS_FLOW_LABEL_OFFSET,
-                VERSION_TRAFFIC_CLASS_FLOW_LABEL + 0x11111);
-
-        // Ensure zero-length options cause the packet to be silently skipped.
-        // Do this before we test other packets. http://b/29586253
-        ByteBuffer zeroLengthOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        zeroLengthOptionPacket.put(basePacket);
-        zeroLengthOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
-        zeroLengthOptionPacket.put((byte)0);
-        assertInvalidRa(apfFilter, ipClientCallback, zeroLengthOptionPacket);
-
-        // Generate several RAs with different options and lifetimes, and verify when
-        // ApfFilter is shown these packets, it generates programs to filter them for the
-        // appropriate lifetime.
-        ByteBuffer prefixOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_LEN]);
-        basePacket.clear();
-        prefixOptionPacket.put(basePacket);
-        prefixOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE);
-        prefixOptionPacket.put((byte)(ICMP6_PREFIX_OPTION_LEN / 8));
-        prefixOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET,
-                PREFIX_PREFERRED_LIFETIME);
-        prefixOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET,
-                PREFIX_VALID_LIFETIME);
-        verifyRaLifetime(
-                apfFilter, ipClientCallback, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
-        verifyRaEvent(new RaEvent(
-                ROUTER_LIFETIME, PREFIX_VALID_LIFETIME, PREFIX_PREFERRED_LIFETIME, -1, -1, -1));
-
-        ByteBuffer rdnssOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        rdnssOptionPacket.put(basePacket);
-        rdnssOptionPacket.put((byte)ICMP6_RDNSS_OPTION_TYPE);
-        rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        rdnssOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, RDNSS_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, rdnssOptionPacket, RDNSS_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, RDNSS_LIFETIME, -1));
-
-        ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        routeInfoOptionPacket.put(basePacket);
-        routeInfoOptionPacket.put((byte)ICMP6_ROUTE_INFO_OPTION_TYPE);
-        routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        routeInfoOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, ROUTE_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, routeInfoOptionPacket, ROUTE_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, ROUTE_LIFETIME, -1, -1));
-
-        ByteBuffer dnsslOptionPacket = ByteBuffer.wrap(
-                new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]);
-        basePacket.clear();
-        dnsslOptionPacket.put(basePacket);
-        dnsslOptionPacket.put((byte)ICMP6_DNSSL_OPTION_TYPE);
-        dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8));
-        dnsslOptionPacket.putInt(
-                ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, DNSSL_LIFETIME);
-        verifyRaLifetime(apfFilter, ipClientCallback, dnsslOptionPacket, ROUTER_LIFETIME);
-        verifyRaEvent(new RaEvent(ROUTER_LIFETIME, -1, -1, -1, -1, DNSSL_LIFETIME));
-
-        // Verify that current program filters all five RAs:
-        program = ipClientCallback.getApfProgram();
-        verifyRaLifetime(program, basePacket, ROUTER_LIFETIME);
-        verifyRaLifetime(program, newFlowLabelPacket, ROUTER_LIFETIME);
-        verifyRaLifetime(program, prefixOptionPacket, PREFIX_PREFERRED_LIFETIME);
-        verifyRaLifetime(program, rdnssOptionPacket, RDNSS_LIFETIME);
-        verifyRaLifetime(program, routeInfoOptionPacket, ROUTE_LIFETIME);
-        verifyRaLifetime(program, dnsslOptionPacket, ROUTER_LIFETIME);
-
-        apfFilter.shutdown();
-    }
-
-    /**
-     * Stage a file for testing, i.e. make it native accessible. Given a resource ID,
-     * copy that resource into the app's data directory and return the path to it.
-     */
-    private String stageFile(int rawId) throws Exception {
-        File file = new File(InstrumentationRegistry.getContext().getFilesDir(), "staged_file");
-        new File(file.getParent()).mkdirs();
-        InputStream in = null;
-        OutputStream out = null;
-        try {
-            in = InstrumentationRegistry.getContext().getResources().openRawResource(rawId);
-            out = new FileOutputStream(file);
-            Streams.copy(in, out);
-        } finally {
-            if (in != null) in.close();
-            if (out != null) out.close();
-        }
-        return file.getAbsolutePath();
-    }
-
-    private static void put(ByteBuffer buffer, int position, byte[] bytes) {
-        final int original = buffer.position();
-        buffer.position(position);
-        buffer.put(bytes);
-        buffer.position(original);
-    }
-
-    @Test
-    public void testRaParsing() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        MockIpClientCallback cb = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        for (int i = 0; i < 1000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                apfFilter.new Ra(packet, packet.length);
-            } catch (ApfFilter.InvalidRaException e) {
-            } catch (Exception e) {
-                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
-            }
-        }
-    }
-
-    @Test
-    public void testRaProcessing() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        MockIpClientCallback cb = new MockIpClientCallback();
-        ApfConfiguration config = getDefaultConfig();
-        config.multicastFilter = DROP_MULTICAST;
-        config.ieee802_3Filter = DROP_802_3_FRAMES;
-        TestApfFilter apfFilter = new TestApfFilter(mContext, config, cb, mLog);
-        for (int i = 0; i < 1000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                apfFilter.processRa(packet, packet.length);
-            } catch (Exception e) {
-                throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
-            }
-        }
-    }
-
-    /**
-     * Call the APF interpreter to run {@code program} on {@code packet} with persistent memory
-     * segment {@data} pretending the filter was installed {@code filter_age} seconds ago.
-     */
-    private native static int apfSimulate(byte[] program, byte[] packet, byte[] data,
-        int filter_age);
-
-    /**
-     * Compile a tcpdump human-readable filter (e.g. "icmp" or "tcp port 54") into a BPF
-     * prorgam and return a human-readable dump of the BPF program identical to "tcpdump -d".
-     */
-    private native static String compileToBpf(String filter);
-
-    /**
-     * Open packet capture file {@code pcap_filename} and filter the packets using tcpdump
-     * human-readable filter (e.g. "icmp" or "tcp port 54") compiled to a BPF program and
-     * at the same time using APF program {@code apf_program}.  Return {@code true} if
-     * both APF and BPF programs filter out exactly the same packets.
-     */
-    private native static boolean compareBpfApf(String filter, String pcap_filename,
-            byte[] apf_program);
-
-
-    /**
-     * Open packet capture file {@code pcapFilename} and run it through APF filter. Then
-     * checks whether all the packets are dropped and populates data[] {@code data} with
-     * the APF counters.
-     */
-    private native static boolean dropsAllPackets(byte[] program, byte[] data, String pcapFilename);
-
-    @Test
-    public void testBroadcastAddress() throws Exception {
-        assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0));
-        assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32));
-        assertEqualsIp("0.0.3.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 22));
-        assertEqualsIp("0.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 8));
-
-        assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 0));
-        assertEqualsIp("10.0.0.1", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 32));
-        assertEqualsIp("10.0.0.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 24));
-        assertEqualsIp("10.0.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 16));
-    }
-
-    public void assertEqualsIp(String expected, int got) throws Exception {
-        int want = bytesToBEInt(InetAddress.getByName(expected).getAddress());
-        assertEquals(want, got);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java b/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java
deleted file mode 100644
index 5d57cde..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.apf;
-
-import android.net.apf.ApfGenerator;
-import android.net.apf.ApfGenerator.IllegalInstructionException;
-import android.net.apf.ApfGenerator.Register;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
-/**
- * BPF to APF translator.
- *
- * Note: This is for testing purposes only and is not guaranteed to support
- *       translation of all BPF programs.
- *
- * Example usage:
- *   javac net/java/android/net/apf/ApfGenerator.java \
- *         tests/servicestests/src/android/net/apf/Bpf2Apf.java
- *   sudo tcpdump -i em1 -d icmp | java -classpath tests/servicestests/src:net/java \
- *                                      android.net.apf.Bpf2Apf
- */
-public class Bpf2Apf {
-    private static int parseImm(String line, String arg) {
-        if (!arg.startsWith("#0x")) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        final long val_long = Long.parseLong(arg.substring(3), 16);
-        if (val_long < 0 || val_long > Long.parseLong("ffffffff", 16)) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        return new Long((val_long << 32) >> 32).intValue();
-    }
-
-    /**
-     * Convert a single line of "tcpdump -d" (human readable BPF program dump) {@code line} into
-     * APF instruction(s) and append them to {@code gen}. Here's an example line:
-     * (001) jeq      #0x86dd          jt 2    jf 7
-     */
-    private static void convertLine(String line, ApfGenerator gen)
-            throws IllegalInstructionException {
-        if (line.indexOf("(") != 0 || line.indexOf(")") != 4 || line.indexOf(" ") != 5) {
-            throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-        int label = Integer.parseInt(line.substring(1, 4));
-        gen.defineLabel(Integer.toString(label));
-        String opcode = line.substring(6, 10).trim();
-        String arg = line.substring(15, Math.min(32, line.length())).trim();
-        switch (opcode) {
-            case "ld":
-            case "ldh":
-            case "ldb":
-            case "ldx":
-            case "ldxb":
-            case "ldxh":
-                Register dest = opcode.contains("x") ? Register.R1 : Register.R0;
-                if (arg.equals("4*([14]&0xf)")) {
-                    if (!opcode.equals("ldxb")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, gen.IPV4_HEADER_SIZE_MEMORY_SLOT);
-                    break;
-                }
-                if (arg.equals("#pktlen")) {
-                    if (!opcode.equals("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, gen.PACKET_SIZE_MEMORY_SLOT);
-                    break;
-                }
-                if (arg.startsWith("#0x")) {
-                    if (!opcode.equals("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadImmediate(dest, parseImm(line, arg));
-                    break;
-                }
-                if (arg.startsWith("M[")) {
-                    if (!opcode.startsWith("ld")) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    int memory_slot = Integer.parseInt(arg.substring(2, arg.length() - 1));
-                    if (memory_slot < 0 || memory_slot >= gen.MEMORY_SLOTS ||
-                            // Disallow use of pre-filled slots as BPF programs might
-                            // wrongfully assume they're initialized to 0.
-                            (memory_slot >= gen.FIRST_PREFILLED_MEMORY_SLOT &&
-                                    memory_slot <= gen.LAST_PREFILLED_MEMORY_SLOT)) {
-                        throw new IllegalArgumentException("Unhandled instruction: " + line);
-                    }
-                    gen.addLoadFromMemory(dest, memory_slot);
-                    break;
-                }
-                if (arg.startsWith("[x + ")) {
-                    int offset = Integer.parseInt(arg.substring(5, arg.length() - 1));
-                    switch (opcode) {
-                        case "ld":
-                        case "ldx":
-                            gen.addLoad32Indexed(dest, offset);
-                            break;
-                        case "ldh":
-                        case "ldxh":
-                            gen.addLoad16Indexed(dest, offset);
-                            break;
-                        case "ldb":
-                        case "ldxb":
-                            gen.addLoad8Indexed(dest, offset);
-                            break;
-                    }
-                } else {
-                    int offset = Integer.parseInt(arg.substring(1, arg.length() - 1));
-                    switch (opcode) {
-                        case "ld":
-                        case "ldx":
-                            gen.addLoad32(dest, offset);
-                            break;
-                        case "ldh":
-                        case "ldxh":
-                            gen.addLoad16(dest, offset);
-                            break;
-                        case "ldb":
-                        case "ldxb":
-                            gen.addLoad8(dest, offset);
-                            break;
-                    }
-                }
-                break;
-            case "st":
-            case "stx":
-                Register src = opcode.contains("x") ? Register.R1 : Register.R0;
-                if (!arg.startsWith("M[")) {
-                    throw new IllegalArgumentException("Unhandled instruction: " + line);
-                }
-                int memory_slot = Integer.parseInt(arg.substring(2, arg.length() - 1));
-                if (memory_slot < 0 || memory_slot >= gen.MEMORY_SLOTS ||
-                        // Disallow overwriting pre-filled slots
-                        (memory_slot >= gen.FIRST_PREFILLED_MEMORY_SLOT &&
-                                memory_slot <= gen.LAST_PREFILLED_MEMORY_SLOT)) {
-                    throw new IllegalArgumentException("Unhandled instruction: " + line);
-                }
-                gen.addStoreToMemory(src, memory_slot);
-                break;
-            case "add":
-            case "and":
-            case "or":
-            case "sub":
-                if (arg.equals("x")) {
-                    switch(opcode) {
-                        case "add":
-                            gen.addAddR1();
-                            break;
-                        case "and":
-                            gen.addAndR1();
-                            break;
-                        case "or":
-                            gen.addOrR1();
-                            break;
-                        case "sub":
-                            gen.addNeg(Register.R1);
-                            gen.addAddR1();
-                            gen.addNeg(Register.R1);
-                            break;
-                    }
-                } else {
-                    int imm = parseImm(line, arg);
-                    switch(opcode) {
-                        case "add":
-                            gen.addAdd(imm);
-                            break;
-                        case "and":
-                            gen.addAnd(imm);
-                            break;
-                        case "or":
-                            gen.addOr(imm);
-                            break;
-                        case "sub":
-                            gen.addAdd(-imm);
-                            break;
-                    }
-                }
-                break;
-            case "jeq":
-            case "jset":
-            case "jgt":
-            case "jge":
-                int val = 0;
-                boolean reg_compare;
-                if (arg.startsWith("x")) {
-                    reg_compare = true;
-                } else {
-                    reg_compare = false;
-                    val = parseImm(line, arg);
-                }
-                int jt_offset = line.indexOf("jt");
-                int jf_offset = line.indexOf("jf");
-                String true_label = line.substring(jt_offset + 2, jf_offset).trim();
-                String false_label = line.substring(jf_offset + 2).trim();
-                boolean true_label_is_fallthrough = Integer.parseInt(true_label) == label + 1;
-                boolean false_label_is_fallthrough = Integer.parseInt(false_label) == label + 1;
-                if (true_label_is_fallthrough && false_label_is_fallthrough)
-                    break;
-                switch (opcode) {
-                    case "jeq":
-                        if (!true_label_is_fallthrough) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0EqualsR1(true_label);
-                            } else {
-                                gen.addJumpIfR0Equals(val, true_label);
-                            }
-                        }
-                        if (!false_label_is_fallthrough) {
-                            if (!true_label_is_fallthrough) {
-                                gen.addJump(false_label);
-                            } else if (reg_compare) {
-                                gen.addJumpIfR0NotEqualsR1(false_label);
-                            } else {
-                                gen.addJumpIfR0NotEquals(val, false_label);
-                            }
-                        }
-                        break;
-                    case "jset":
-                        if (reg_compare) {
-                            gen.addJumpIfR0AnyBitsSetR1(true_label);
-                        } else {
-                            gen.addJumpIfR0AnyBitsSet(val, true_label);
-                        }
-                        if (!false_label_is_fallthrough) {
-                            gen.addJump(false_label);
-                        }
-                        break;
-                    case "jgt":
-                        if (!true_label_is_fallthrough ||
-                                // We have no less-than-or-equal-to register to register
-                                // comparison instruction, so in this case we'll jump
-                                // around an unconditional jump.
-                                (!false_label_is_fallthrough && reg_compare)) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0GreaterThanR1(true_label);
-                            } else {
-                                gen.addJumpIfR0GreaterThan(val, true_label);
-                            }
-                        }
-                        if (!false_label_is_fallthrough) {
-                            if (!true_label_is_fallthrough || reg_compare) {
-                                gen.addJump(false_label);
-                            } else {
-                                gen.addJumpIfR0LessThan(val + 1, false_label);
-                            }
-                        }
-                        break;
-                    case "jge":
-                        if (!false_label_is_fallthrough ||
-                                // We have no greater-than-or-equal-to register to register
-                                // comparison instruction, so in this case we'll jump
-                                // around an unconditional jump.
-                                (!true_label_is_fallthrough && reg_compare)) {
-                            if (reg_compare) {
-                                gen.addJumpIfR0LessThanR1(false_label);
-                            } else {
-                                gen.addJumpIfR0LessThan(val, false_label);
-                            }
-                        }
-                        if (!true_label_is_fallthrough) {
-                            if (!false_label_is_fallthrough || reg_compare) {
-                                gen.addJump(true_label);
-                            } else {
-                                gen.addJumpIfR0GreaterThan(val - 1, true_label);
-                            }
-                        }
-                        break;
-                }
-                break;
-            case "ret":
-                if (arg.equals("#0")) {
-                    gen.addJump(gen.DROP_LABEL);
-                } else {
-                    gen.addJump(gen.PASS_LABEL);
-                }
-                break;
-            case "tax":
-                gen.addMove(Register.R1);
-                break;
-            case "txa":
-                gen.addMove(Register.R0);
-                break;
-            default:
-                throw new IllegalArgumentException("Unhandled instruction: " + line);
-        }
-    }
-
-    /**
-     * Convert the output of "tcpdump -d" (human readable BPF program dump) {@code bpf} into an APF
-     * program and return it.
-     */
-    public static byte[] convert(String bpf) throws IllegalInstructionException {
-        ApfGenerator gen = new ApfGenerator(3);
-        for (String line : bpf.split("\\n")) convertLine(line, gen);
-        return gen.generate();
-    }
-
-    /**
-     * Convert the output of "tcpdump -d" (human readable BPF program dump) piped in stdin into an
-     * APF program and output it via stdout.
-     */
-    public static void main(String[] args) throws Exception {
-        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
-        String line = null;
-        StringBuilder responseData = new StringBuilder();
-        ApfGenerator gen = new ApfGenerator(3);
-        while ((line = in.readLine()) != null) convertLine(line, gen);
-        System.out.write(gen.generate());
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java b/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
deleted file mode 100644
index f948086..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
+++ /dev/null
@@ -1,170 +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.net.captiveportal;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.net.MalformedURLException;
-import java.text.ParseException;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class CaptivePortalProbeSpecTest {
-
-    @Test
-    public void testGetResult_Regex() throws MalformedURLException, ParseException {
-        // 2xx status or 404, with an empty (match everything) location regex
-        CaptivePortalProbeSpec statusRegexSpec = CaptivePortalProbeSpec.parseSpec(
-                "http://www.google.com@@/@@2[0-9]{2}|404@@/@@");
-
-        // 404, or 301/302 redirect to some HTTPS page under google.com
-        CaptivePortalProbeSpec redirectSpec = CaptivePortalProbeSpec.parseSpec(
-                "http://google.com@@/@@404|30[12]@@/@@https://([0-9a-z]+\\.)*google\\.com.*");
-
-        assertSuccess(statusRegexSpec.getResult(200, null));
-        assertSuccess(statusRegexSpec.getResult(299, "qwer"));
-        assertSuccess(statusRegexSpec.getResult(404, null));
-        assertSuccess(statusRegexSpec.getResult(404, ""));
-
-        assertPortal(statusRegexSpec.getResult(300, null));
-        assertPortal(statusRegexSpec.getResult(399, "qwer"));
-        assertPortal(statusRegexSpec.getResult(500, null));
-
-        assertSuccess(redirectSpec.getResult(404, null));
-        assertSuccess(redirectSpec.getResult(404, ""));
-        assertSuccess(redirectSpec.getResult(301, "https://www.google.com"));
-        assertSuccess(redirectSpec.getResult(301, "https://www.google.com/test?q=3"));
-        assertSuccess(redirectSpec.getResult(302, "https://google.com/test?q=3"));
-
-        assertPortal(redirectSpec.getResult(299, "https://google.com/test?q=3"));
-        assertPortal(redirectSpec.getResult(299, ""));
-        assertPortal(redirectSpec.getResult(499, null));
-        assertPortal(redirectSpec.getResult(301, "http://login.portal.example.com/loginpage"));
-        assertPortal(redirectSpec.getResult(302, "http://www.google.com/test?q=3"));
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_Empty() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_Null() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec(null);
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_MissingParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_TooManyParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123@@/@@456@@/@@extra");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_InvalidStatusRegex() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@unmatched(parenthesis@@/@@456");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_InvalidLocationRegex() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("http://google.com/@@/@@123@@/@@unmatched[[]bracket");
-    }
-
-    @Test(expected = MalformedURLException.class)
-    public void testParseSpec_EmptyURL() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("@@/@@123@@/@@123");
-    }
-
-    @Test(expected = ParseException.class)
-    public void testParseSpec_NoParts() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("invalid");
-    }
-
-    @Test(expected = MalformedURLException.class)
-    public void testParseSpec_RegexInvalidUrl() throws MalformedURLException, ParseException {
-        CaptivePortalProbeSpec.parseSpec("notaurl@@/@@123@@/@@123");
-    }
-
-    @Test
-    public void testParseSpecOrNull_UsesSpec() {
-        final String specUrl = "http://google.com/probe";
-        final String redirectUrl = "https://google.com/probe";
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull(
-                specUrl + "@@/@@302@@/@@" + redirectUrl);
-        assertEquals(specUrl, spec.getUrl().toString());
-
-        assertPortal(spec.getResult(302, "http://portal.example.com"));
-        assertSuccess(spec.getResult(302, redirectUrl));
-    }
-
-    @Test
-    public void testParseSpecOrNull_UsesFallback() throws MalformedURLException {
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull(null);
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("");
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("@@/@@ @@/@@ @@/@@");
-        assertNull(spec);
-
-        spec = CaptivePortalProbeSpec.parseSpecOrNull("invalid@@/@@123@@/@@456");
-        assertNull(spec);
-    }
-
-    @Test
-    public void testParseSpecOrUseStatusCodeFallback_EmptySpec() throws MalformedURLException {
-        CaptivePortalProbeSpec spec = CaptivePortalProbeSpec.parseSpecOrNull("");
-        assertNull(spec);
-    }
-
-    private void assertIsStatusSpec(CaptivePortalProbeSpec spec) {
-        assertSuccess(spec.getResult(204, null));
-        assertSuccess(spec.getResult(204, "1234"));
-
-        assertPortal(spec.getResult(200, null));
-        assertPortal(spec.getResult(301, null));
-        assertPortal(spec.getResult(302, "1234"));
-        assertPortal(spec.getResult(399, ""));
-
-        assertFailed(spec.getResult(404, null));
-        assertFailed(spec.getResult(500, "1234"));
-    }
-
-    private void assertPortal(CaptivePortalProbeResult result) {
-        assertTrue(result.isPortal());
-    }
-
-    private void assertSuccess(CaptivePortalProbeResult result) {
-        assertTrue(result.isSuccessful());
-    }
-
-    private void assertFailed(CaptivePortalProbeResult result) {
-        assertTrue(result.isFailed());
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
deleted file mode 100644
index 27d7255..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
+++ /dev/null
@@ -1,544 +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.net.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpLease.HOSTNAME_NONE;
-import static android.net.dhcp.DhcpLeaseRepository.CLIENTID_UNSPEC;
-import static android.net.dhcp.DhcpLeaseRepository.INETADDR_UNSPEC;
-
-import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.IpPrefix;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.util.SharedLog;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static java.lang.String.format;
-
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpLeaseRepositoryTest {
-    private static final Inet4Address TEST_DEF_ROUTER = parseAddr4("192.168.42.247");
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr4("192.168.42.241");
-    private static final Inet4Address TEST_RESERVED_ADDR = parseAddr4("192.168.42.243");
-    private static final MacAddress TEST_MAC_1 = MacAddress.fromBytes(
-            new byte[] { 5, 4, 3, 2, 1, 0 });
-    private static final MacAddress TEST_MAC_2 = MacAddress.fromBytes(
-            new byte[] { 0, 1, 2, 3, 4, 5 });
-    private static final MacAddress TEST_MAC_3 = MacAddress.fromBytes(
-            new byte[] { 0, 1, 2, 3, 4, 6 });
-    private static final Inet4Address TEST_INETADDR_1 = parseAddr4("192.168.42.248");
-    private static final Inet4Address TEST_INETADDR_2 = parseAddr4("192.168.42.249");
-    private static final String TEST_HOSTNAME_1 = "hostname1";
-    private static final String TEST_HOSTNAME_2 = "hostname2";
-    private static final IpPrefix TEST_IP_PREFIX = new IpPrefix(TEST_SERVER_ADDR, 22);
-    private static final long TEST_TIME = 100L;
-    private static final int TEST_LEASE_TIME_MS = 3_600_000;
-    private static final Set<Inet4Address> TEST_EXCL_SET =
-            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
-                TEST_SERVER_ADDR, TEST_DEF_ROUTER, TEST_RESERVED_ADDR)));
-
-    @NonNull
-    private SharedLog mLog;
-    @NonNull @Mock
-    private Clock mClock;
-    @NonNull
-    private DhcpLeaseRepository mRepo;
-
-    private static Inet4Address parseAddr4(String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mLog = new SharedLog("DhcpLeaseRepositoryTest");
-        when(mClock.elapsedRealtime()).thenReturn(TEST_TIME);
-        mRepo = new DhcpLeaseRepository(
-                TEST_IP_PREFIX, TEST_EXCL_SET, TEST_LEASE_TIME_MS, mLog, mClock);
-    }
-
-    /**
-     * Request a number of addresses through offer/request. Useful to test address exhaustion.
-     * @param nAddr Number of addresses to request.
-     */
-    private void requestAddresses(byte nAddr) throws Exception {
-        final HashSet<Inet4Address> addrs = new HashSet<>();
-        byte[] hwAddrBytes = new byte[] { 8, 4, 3, 2, 1, 0 };
-        for (byte i = 0; i < nAddr; i++) {
-            hwAddrBytes[5] = i;
-            MacAddress newMac = MacAddress.fromBytes(hwAddrBytes);
-            final String hostname = "host_" + i;
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, newMac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, hostname);
-
-            assertNotNull(lease);
-            assertEquals(newMac, lease.getHwAddr());
-            assertEquals(hostname, lease.getHostname());
-            assertTrue(format("Duplicate address allocated: %s in %s", lease.getNetAddr(), addrs),
-                    addrs.add(lease.getNetAddr()));
-
-            requestLeaseSelecting(newMac, lease.getNetAddr(), hostname);
-        }
-    }
-
-    @Test
-    public void testAddressExhaustion() throws Exception {
-        // Use a /28 to quickly run out of addresses
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
-        requestAddresses((byte) 11);
-
-        try {
-            mRepo.getOffer(null, TEST_MAC_2,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            fail("Should be out of addresses");
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) {
-            // Expected
-        }
-    }
-
-    @Test
-    public void testUpdateParams_LeaseCleanup() throws Exception {
-        // Inside /28:
-        final Inet4Address reqAddrIn28 = parseAddr4("192.168.42.242");
-        final Inet4Address declinedAddrIn28 = parseAddr4("192.168.42.245");
-
-        // Inside /28, but not available there (first address of the range)
-        final Inet4Address declinedFirstAddrIn28 = parseAddr4("192.168.42.240");
-
-        final DhcpLease reqAddrIn28Lease = requestLeaseSelecting(TEST_MAC_1, reqAddrIn28);
-        mRepo.markLeaseDeclined(declinedAddrIn28);
-        mRepo.markLeaseDeclined(declinedFirstAddrIn28);
-
-        // Inside /22, but outside /28:
-        final Inet4Address reqAddrIn22 = parseAddr4("192.168.42.3");
-        final Inet4Address declinedAddrIn22 = parseAddr4("192.168.42.4");
-
-        final DhcpLease reqAddrIn22Lease = requestLeaseSelecting(TEST_MAC_3, reqAddrIn22);
-        mRepo.markLeaseDeclined(declinedAddrIn22);
-
-        // Address that will be reserved in the updateParams call below
-        final Inet4Address reservedAddr = parseAddr4("192.168.42.244");
-        final DhcpLease reservedAddrLease = requestLeaseSelecting(TEST_MAC_2, reservedAddr);
-
-        // Update from /22 to /28 and add another reserved address
-        Set<Inet4Address> newReserved = new HashSet<>(TEST_EXCL_SET);
-        newReserved.add(reservedAddr);
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), newReserved, TEST_LEASE_TIME_MS);
-
-        assertHasLease(reqAddrIn28Lease);
-        assertDeclined(declinedAddrIn28);
-
-        assertNotDeclined(declinedFirstAddrIn28);
-
-        assertNoLease(reqAddrIn22Lease);
-        assertNotDeclined(declinedAddrIn22);
-
-        assertNoLease(reservedAddrLease);
-    }
-
-    @Test
-    public void testGetOffer_StableAddress() throws Exception {
-        for (final MacAddress macAddr : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-            // Same lease is offered twice
-            final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, macAddr,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            assertEquals(lease, newLease);
-        }
-    }
-
-    @Test
-    public void testUpdateParams_UsesNewPrefix() throws Exception {
-        final IpPrefix newPrefix = new IpPrefix(parseAddr4("192.168.123.0"), 24);
-        mRepo.updateParams(newPrefix, TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertTrue(newPrefix.contains(lease.getNetAddr()));
-    }
-
-    @Test
-    public void testGetOffer_ExistingLease() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1, TEST_HOSTNAME_1);
-
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_ClientIdHasExistingLease() throws Exception {
-        final byte[] clientId = new byte[] { 1, 2 };
-        mRepo.requestLease(clientId, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                IPV4_ADDR_ANY /* relayAddr */, TEST_INETADDR_1 /* reqAddr */, false,
-                TEST_HOSTNAME_1);
-
-        // Different MAC, but same clientId
-        DhcpLease offer = mRepo.getOffer(clientId, TEST_MAC_2,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_DifferentClientId() throws Exception {
-        final byte[] clientId1 = new byte[] { 1, 2 };
-        final byte[] clientId2 = new byte[] { 3, 4 };
-        mRepo.requestLease(clientId1, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                IPV4_ADDR_ANY /* relayAddr */, TEST_INETADDR_1 /* reqAddr */, false,
-                TEST_HOSTNAME_1);
-
-        // Same MAC, different client ID
-        DhcpLease offer = mRepo.getOffer(clientId2, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        // Obtains a different address
-        assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(HOSTNAME_NONE, offer.getHostname());
-        assertEquals(TEST_MAC_1, offer.getHwAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddress() throws Exception {
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_INETADDR_1 /* reqAddr */, TEST_HOSTNAME_1);
-        assertEquals(TEST_INETADDR_1, offer.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, offer.getHostname());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_INETADDR_1 /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(TEST_INETADDR_1, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressReserved() throws Exception {
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                TEST_RESERVED_ADDR /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(TEST_RESERVED_ADDR, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressInvalid() throws Exception {
-        final Inet4Address invalidAddr = parseAddr4("192.168.42.0");
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                invalidAddr /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(invalidAddr, offer.getNetAddr());
-    }
-
-    @Test
-    public void testGetOffer_RequestedAddressOutsideSubnet() throws Exception {
-        final Inet4Address invalidAddr = parseAddr4("192.168.254.2");
-        DhcpLease offer = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* relayAddr */,
-                invalidAddr /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(invalidAddr, offer.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidSubnetException.class)
-    public void testGetOffer_RelayInInvalidSubnet() throws Exception {
-        mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1, parseAddr4("192.168.254.2") /* relayAddr */,
-                INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-    }
-
-    @Test
-    public void testRequestLease_SelectingTwice() throws Exception {
-        final DhcpLease lease1 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1,
-                TEST_HOSTNAME_1);
-
-        // Second request from same client for a different address
-        final DhcpLease lease2 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_2,
-                TEST_HOSTNAME_2);
-
-        assertEquals(TEST_INETADDR_1, lease1.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, lease1.getHostname());
-
-        assertEquals(TEST_INETADDR_2, lease2.getNetAddr());
-        assertEquals(TEST_HOSTNAME_2, lease2.getHostname());
-
-        // First address freed when client requested a different one: another client can request it
-        final DhcpLease lease3 = requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1, HOSTNAME_NONE);
-        assertEquals(TEST_INETADDR_1, lease3.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingInvalid() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, parseAddr4("192.168.254.5"));
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_SelectingReserved() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_RESERVED_ADDR);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidSubnetException.class)
-    public void testRequestLease_SelectingRelayInInvalidSubnet() throws  Exception {
-        mRepo.requestLease(CLIENTID_UNSPEC, TEST_MAC_1, IPV4_ADDR_ANY /* clientAddr */,
-                parseAddr4("192.168.128.1") /* relayAddr */, TEST_INETADDR_1 /* reqAddr */,
-                true /* sidSet */, HOSTNAME_NONE);
-    }
-
-    @Test
-    public void testRequestLease_InitReboot() throws Exception {
-        // Request address once
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-
-        // init-reboot (sidSet == false): verify configuration
-        final DhcpLease lease = requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_1);
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_InitRebootWrongAddr() throws Exception {
-        // Request address once
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-        // init-reboot with different requested address
-        requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_2);
-    }
-
-    @Test
-    public void testRequestLease_InitRebootUnknownAddr() throws Exception {
-        // init-reboot with unknown requested address
-        final DhcpLease lease = requestLeaseInitReboot(TEST_MAC_1, TEST_INETADDR_2);
-        // RFC2131 says we should not reply to accommodate other servers, but since we are
-        // authoritative we allow creating the lease to avoid issues with lost lease DB (same as
-        // dnsmasq behavior)
-        assertEquals(TEST_INETADDR_2, lease.getNetAddr());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_InitRebootWrongSubnet() throws Exception {
-        requestLeaseInitReboot(TEST_MAC_1, parseAddr4("192.168.254.2"));
-    }
-
-    @Test
-    public void testRequestLease_Renewing() throws Exception {
-        requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-
-        final DhcpLease lease = requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test
-    public void testRequestLease_RenewingUnknownAddr() throws Exception {
-        final long newTime = TEST_TIME + 100;
-        when(mClock.elapsedRealtime()).thenReturn(newTime);
-        final DhcpLease lease = requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-        // Allows renewing an unknown address if available
-        assertEquals(TEST_INETADDR_1, lease.getNetAddr());
-        assertEquals(newTime + TEST_LEASE_TIME_MS, lease.getExpTime());
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_RenewingAddrInUse() throws Exception {
-        requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-        requestLeaseRenewing(TEST_MAC_1, TEST_INETADDR_1);
-    }
-
-    @Test(expected = DhcpLeaseRepository.InvalidAddressException.class)
-    public void testRequestLease_RenewingInvalidAddr() throws Exception {
-        requestLeaseRenewing(TEST_MAC_1, parseAddr4("192.168.254.2"));
-    }
-
-    @Test
-    public void testReleaseLease() throws Exception {
-        final DhcpLease lease1 = requestLeaseSelecting(TEST_MAC_1, TEST_INETADDR_1);
-
-        assertHasLease(lease1);
-        assertTrue(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
-        assertNoLease(lease1);
-
-        final DhcpLease lease2 = requestLeaseSelecting(TEST_MAC_2, TEST_INETADDR_1);
-        assertEquals(TEST_INETADDR_1, lease2.getNetAddr());
-    }
-
-    @Test
-    public void testReleaseLease_UnknownLease() {
-        assertFalse(mRepo.releaseLease(CLIENTID_UNSPEC, TEST_MAC_1, TEST_INETADDR_1));
-    }
-
-    @Test
-    public void testReleaseLease_StableOffer() throws Exception {
-        for (MacAddress mac : new MacAddress[] { TEST_MAC_1, TEST_MAC_2, TEST_MAC_3 }) {
-            final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-            requestLeaseSelecting(mac, lease.getNetAddr());
-            mRepo.releaseLease(CLIENTID_UNSPEC, mac, lease.getNetAddr());
-
-            // Same lease is offered after it was released
-            final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, mac,
-                    IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            assertEquals(lease.getNetAddr(), newLease.getNetAddr());
-        }
-    }
-
-    @Test
-    public void testMarkLeaseDeclined() throws Exception {
-        final DhcpLease lease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-
-        mRepo.markLeaseDeclined(lease.getNetAddr());
-
-        // Same lease is not offered again
-        final DhcpLease newLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-        assertNotEquals(lease.getNetAddr(), newLease.getNetAddr());
-    }
-
-    @Test
-    public void testMarkLeaseDeclined_UsedIfOutOfAddresses() throws Exception {
-        // Use a /28 to quickly run out of addresses
-        mRepo.updateParams(new IpPrefix(TEST_SERVER_ADDR, 28), TEST_EXCL_SET, TEST_LEASE_TIME_MS);
-
-        mRepo.markLeaseDeclined(TEST_INETADDR_1);
-        mRepo.markLeaseDeclined(TEST_INETADDR_2);
-
-        // /28 should have 16 addresses, 14 w/o the first/last, 11 w/o excluded addresses
-        requestAddresses((byte) 9);
-
-        // Last 2 addresses: addresses marked declined should be used
-        final DhcpLease firstLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_1,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_1);
-        requestLeaseSelecting(TEST_MAC_1, firstLease.getNetAddr());
-
-        final DhcpLease secondLease = mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_2,
-                IPV4_ADDR_ANY /* relayAddr */, INETADDR_UNSPEC /* reqAddr */, TEST_HOSTNAME_2);
-        requestLeaseSelecting(TEST_MAC_2, secondLease.getNetAddr());
-
-        // Now out of addresses
-        try {
-            mRepo.getOffer(CLIENTID_UNSPEC, TEST_MAC_3, IPV4_ADDR_ANY /* relayAddr */,
-                    INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE);
-            fail("Repository should be out of addresses and throw");
-        } catch (DhcpLeaseRepository.OutOfAddressesException e) { /* expected */ }
-
-        assertEquals(TEST_INETADDR_1, firstLease.getNetAddr());
-        assertEquals(TEST_HOSTNAME_1, firstLease.getHostname());
-        assertEquals(TEST_INETADDR_2, secondLease.getNetAddr());
-        assertEquals(TEST_HOSTNAME_2, secondLease.getHostname());
-    }
-
-    private DhcpLease requestLease(@NonNull MacAddress macAddr, @NonNull Inet4Address clientAddr,
-            @Nullable Inet4Address reqAddr, @Nullable String hostname, boolean sidSet)
-            throws DhcpLeaseRepository.DhcpLeaseException {
-        return mRepo.requestLease(CLIENTID_UNSPEC, macAddr, clientAddr,
-                IPV4_ADDR_ANY /* relayAddr */,
-                reqAddr, sidSet, hostname);
-    }
-
-    /**
-     * Request a lease simulating a client in the SELECTING state.
-     */
-    private DhcpLease requestLeaseSelecting(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr, @Nullable String hostname)
-            throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLease(macAddr, IPV4_ADDR_ANY /* clientAddr */, reqAddr, hostname,
-                true /* sidSet */);
-    }
-
-    /**
-     * Request a lease simulating a client in the SELECTING state.
-     */
-    private DhcpLease requestLeaseSelecting(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLeaseSelecting(macAddr, reqAddr, HOSTNAME_NONE);
-    }
-
-    /**
-     * Request a lease simulating a client in the INIT-REBOOT state.
-     */
-    private DhcpLease requestLeaseInitReboot(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address reqAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        return requestLease(macAddr, IPV4_ADDR_ANY /* clientAddr */, reqAddr, HOSTNAME_NONE,
-                false /* sidSet */);
-    }
-
-    /**
-     * Request a lease simulating a client in the RENEWING state.
-     */
-    private DhcpLease requestLeaseRenewing(@NonNull MacAddress macAddr,
-            @NonNull Inet4Address clientAddr) throws DhcpLeaseRepository.DhcpLeaseException {
-        // Renewing: clientAddr filled in, no reqAddr
-        return requestLease(macAddr, clientAddr, INETADDR_UNSPEC /* reqAddr */, HOSTNAME_NONE,
-                true /* sidSet */);
-    }
-
-    private void assertNoLease(DhcpLease lease) {
-        assertFalse("Leases contain " + lease, mRepo.getCommittedLeases().contains(lease));
-    }
-
-    private void assertHasLease(DhcpLease lease) {
-        assertTrue("Leases do not contain " + lease, mRepo.getCommittedLeases().contains(lease));
-    }
-
-    private void assertNotDeclined(Inet4Address addr) {
-        assertFalse("Address is declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
-    }
-
-    private void assertDeclined(Inet4Address addr) {
-        assertTrue("Address is not declined: " + addr, mRepo.getDeclinedAddresses().contains(addr));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
deleted file mode 100644
index a30d3e4..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
+++ /dev/null
@@ -1,1117 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.dhcp;
-
-import static android.net.dhcp.DhcpPacket.DHCP_BROADCAST_ADDRESS;
-import static android.net.dhcp.DhcpPacket.DHCP_DNS_SERVER;
-import static android.net.dhcp.DhcpPacket.DHCP_DOMAIN_NAME;
-import static android.net.dhcp.DhcpPacket.DHCP_LEASE_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_ACK;
-import static android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_OFFER;
-import static android.net.dhcp.DhcpPacket.DHCP_MTU;
-import static android.net.dhcp.DhcpPacket.DHCP_REBINDING_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_RENEWAL_TIME;
-import static android.net.dhcp.DhcpPacket.DHCP_ROUTER;
-import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK;
-import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.DhcpPacket.ENCAP_L2;
-import static android.net.dhcp.DhcpPacket.ENCAP_L3;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
-import static android.net.dhcp.DhcpPacket.ParseException;
-import static android.net.shared.Inet4AddressUtils.getBroadcastAddress;
-import static android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address;
-
-import static org.junit.Assert.assertEquals;
-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 android.annotation.Nullable;
-import android.net.DhcpResults;
-import android.net.LinkAddress;
-import android.net.NetworkUtils;
-import android.net.metrics.DhcpErrorEvent;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.HexDump;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayOutputStream;
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Random;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpPacketTest {
-
-    private static final Inet4Address SERVER_ADDR = v4Address("192.0.2.1");
-    private static final Inet4Address CLIENT_ADDR = v4Address("192.0.2.234");
-    private static final int PREFIX_LENGTH = 22;
-    private static final Inet4Address NETMASK = getPrefixMaskAsInet4Address(PREFIX_LENGTH);
-    private static final Inet4Address BROADCAST_ADDR = getBroadcastAddress(
-            SERVER_ADDR, PREFIX_LENGTH);
-    private static final String HOSTNAME = "testhostname";
-    private static final short MTU = 1500;
-    // Use our own empty address instead of IPV4_ADDR_ANY or INADDR_ANY to ensure that the code
-    // doesn't use == instead of equals when comparing addresses.
-    private static final Inet4Address ANY = v4Address("0.0.0.0");
-
-    private static final byte[] CLIENT_MAC = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
-
-    private static final Inet4Address v4Address(String addrString) throws IllegalArgumentException {
-        return (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
-    }
-
-    @Before
-    public void setUp() {
-        DhcpPacket.testOverrideVendorId = "android-dhcp-???";
-        DhcpPacket.testOverrideHostname = "android-01234567890abcde";
-    }
-
-    class TestDhcpPacket extends DhcpPacket {
-        private byte mType;
-        // TODO: Make this a map of option numbers to bytes instead.
-        private byte[] mDomainBytes, mVendorInfoBytes, mLeaseTimeBytes, mNetmaskBytes;
-
-        public TestDhcpPacket(byte type, Inet4Address clientIp, Inet4Address yourIp) {
-            super(0xdeadbeef, (short) 0, clientIp, yourIp, INADDR_ANY, INADDR_ANY,
-                  CLIENT_MAC, true);
-            mType = type;
-        }
-
-        public TestDhcpPacket(byte type) {
-            this(type, INADDR_ANY, CLIENT_ADDR);
-        }
-
-        public TestDhcpPacket setDomainBytes(byte[] domainBytes) {
-            mDomainBytes = domainBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setVendorInfoBytes(byte[] vendorInfoBytes) {
-            mVendorInfoBytes = vendorInfoBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setLeaseTimeBytes(byte[] leaseTimeBytes) {
-            mLeaseTimeBytes = leaseTimeBytes;
-            return this;
-        }
-
-        public TestDhcpPacket setNetmaskBytes(byte[] netmaskBytes) {
-            mNetmaskBytes = netmaskBytes;
-            return this;
-        }
-
-        public ByteBuffer buildPacket(int encap, short unusedDestUdp, short unusedSrcUdp) {
-            ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH);
-            fillInPacket(encap, CLIENT_ADDR, SERVER_ADDR,
-                         DHCP_CLIENT, DHCP_SERVER, result, DHCP_BOOTREPLY, false);
-            return result;
-        }
-
-        public void finishPacket(ByteBuffer buffer) {
-            addTlv(buffer, DHCP_MESSAGE_TYPE, mType);
-            if (mDomainBytes != null) {
-                addTlv(buffer, DHCP_DOMAIN_NAME, mDomainBytes);
-            }
-            if (mVendorInfoBytes != null) {
-                addTlv(buffer, DHCP_VENDOR_INFO, mVendorInfoBytes);
-            }
-            if (mLeaseTimeBytes != null) {
-                addTlv(buffer, DHCP_LEASE_TIME, mLeaseTimeBytes);
-            }
-            if (mNetmaskBytes != null) {
-                addTlv(buffer, DHCP_SUBNET_MASK, mNetmaskBytes);
-            }
-            addTlvEnd(buffer);
-        }
-
-        // Convenience method.
-        public ByteBuffer build() {
-            // ENCAP_BOOTP packets don't contain ports, so just pass in 0.
-            ByteBuffer pkt = buildPacket(ENCAP_BOOTP, (short) 0, (short) 0);
-            pkt.flip();
-            return pkt;
-        }
-    }
-
-    private void assertDomainAndVendorInfoParses(
-            String expectedDomain, byte[] domainBytes,
-            String expectedVendorInfo, byte[] vendorInfoBytes) throws Exception {
-        ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER)
-                .setDomainBytes(domainBytes)
-                .setVendorInfoBytes(vendorInfoBytes)
-                .build();
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        assertEquals(expectedDomain, offerPacket.mDomainName);
-        assertEquals(expectedVendorInfo, offerPacket.mVendorInfo);
-    }
-
-    @Test
-    public void testDomainName() throws Exception {
-        byte[] nullByte = new byte[] { 0x00 };
-        byte[] twoNullBytes = new byte[] { 0x00, 0x00 };
-        byte[] nonNullDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l'
-        };
-        byte[] trailingNullDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', (byte) '.', (byte) 'g', (byte) 'l', 0x00
-        };
-        byte[] embeddedNullsDomain = new byte[] {
-            (byte) 'g', (byte) 'o', (byte) 'o', 0x00, 0x00, (byte) 'g', (byte) 'l'
-        };
-        byte[] metered = "ANDROID_METERED".getBytes("US-ASCII");
-
-        byte[] meteredEmbeddedNull = metered.clone();
-        meteredEmbeddedNull[7] = (char) 0;
-
-        byte[] meteredTrailingNull = metered.clone();
-        meteredTrailingNull[meteredTrailingNull.length - 1] = (char) 0;
-
-        assertDomainAndVendorInfoParses("", nullByte, "\u0000", nullByte);
-        assertDomainAndVendorInfoParses("", twoNullBytes, "\u0000\u0000", twoNullBytes);
-        assertDomainAndVendorInfoParses("goo.gl", nonNullDomain, "ANDROID_METERED", metered);
-        assertDomainAndVendorInfoParses("goo", embeddedNullsDomain,
-                                        "ANDROID\u0000METERED", meteredEmbeddedNull);
-        assertDomainAndVendorInfoParses("goo.gl", trailingNullDomain,
-                                        "ANDROID_METERE\u0000", meteredTrailingNull);
-    }
-
-    private void assertLeaseTimeParses(boolean expectValid, Integer rawLeaseTime,
-            long leaseTimeMillis, byte[] leaseTimeBytes) throws Exception {
-        TestDhcpPacket testPacket = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER);
-        if (leaseTimeBytes != null) {
-            testPacket.setLeaseTimeBytes(leaseTimeBytes);
-        }
-        ByteBuffer packet = testPacket.build();
-        DhcpPacket offerPacket = null;
-
-        if (!expectValid) {
-            try {
-                offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-                fail("Invalid packet parsed successfully: " + offerPacket);
-            } catch (ParseException expected) {
-            }
-            return;
-        }
-
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        assertNotNull(offerPacket);
-        assertEquals(rawLeaseTime, offerPacket.mLeaseTime);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();  // Just check this doesn't crash.
-        assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
-    }
-
-    @Test
-    public void testLeaseTime() throws Exception {
-        byte[] noLease = null;
-        byte[] tooShortLease = new byte[] { 0x00, 0x00 };
-        byte[] tooLongLease = new byte[] { 0x00, 0x00, 0x00, 60, 0x01 };
-        byte[] zeroLease = new byte[] { 0x00, 0x00, 0x00, 0x00 };
-        byte[] tenSecondLease = new byte[] { 0x00, 0x00, 0x00, 10 };
-        byte[] oneMinuteLease = new byte[] { 0x00, 0x00, 0x00, 60 };
-        byte[] fiveMinuteLease = new byte[] { 0x00, 0x00, 0x01, 0x2c };
-        byte[] oneDayLease = new byte[] { 0x00, 0x01, 0x51, (byte) 0x80 };
-        byte[] maxIntPlusOneLease = new byte[] { (byte) 0x80, 0x00, 0x00, 0x01 };
-        byte[] infiniteLease = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };
-
-        assertLeaseTimeParses(true, null, 0, noLease);
-        assertLeaseTimeParses(false, null, 0, tooShortLease);
-        assertLeaseTimeParses(false, null, 0, tooLongLease);
-        assertLeaseTimeParses(true, 0, 60 * 1000, zeroLease);
-        assertLeaseTimeParses(true, 10, 60 * 1000, tenSecondLease);
-        assertLeaseTimeParses(true, 60, 60 * 1000, oneMinuteLease);
-        assertLeaseTimeParses(true, 300, 300 * 1000, fiveMinuteLease);
-        assertLeaseTimeParses(true, 86400, 86400 * 1000, oneDayLease);
-        assertLeaseTimeParses(true, -2147483647, 2147483649L * 1000, maxIntPlusOneLease);
-        assertLeaseTimeParses(true, DhcpPacket.INFINITE_LEASE, 0, infiniteLease);
-    }
-
-    private void checkIpAddress(String expected, Inet4Address clientIp, Inet4Address yourIp,
-                                byte[] netmaskBytes) throws Exception {
-        checkIpAddress(expected, DHCP_MESSAGE_TYPE_OFFER, clientIp, yourIp, netmaskBytes);
-        checkIpAddress(expected, DHCP_MESSAGE_TYPE_ACK, clientIp, yourIp, netmaskBytes);
-    }
-
-    private void checkIpAddress(String expected, byte type,
-                                Inet4Address clientIp, Inet4Address yourIp,
-                                byte[] netmaskBytes) throws Exception {
-        ByteBuffer packet = new TestDhcpPacket(type, clientIp, yourIp)
-                .setNetmaskBytes(netmaskBytes)
-                .build();
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
-        DhcpResults results = offerPacket.toDhcpResults();
-
-        if (expected != null) {
-            LinkAddress expectedAddress = new LinkAddress(expected);
-            assertEquals(expectedAddress, results.ipAddress);
-        } else {
-            assertNull(results);
-        }
-    }
-
-    @Test
-    public void testIpAddress() throws Exception {
-        byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 };
-        byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 };
-        byte[] invalidNetmask = new byte[] { (byte) 0xff, (byte) 0xfb, (byte) 0xff, 0x00 };
-        Inet4Address example1 = v4Address("192.0.2.1");
-        Inet4Address example2 = v4Address("192.0.2.43");
-
-        // A packet without any addresses is not valid.
-        checkIpAddress(null, ANY, ANY, slash24Netmask);
-
-        // ClientIP is used iff YourIP is not present.
-        checkIpAddress("192.0.2.1/24", example2, example1, slash24Netmask);
-        checkIpAddress("192.0.2.43/11", example2, ANY, slash11Netmask);
-        checkIpAddress("192.0.2.43/11", ANY, example2, slash11Netmask);
-
-        // Invalid netmasks are ignored.
-        checkIpAddress(null, example2, ANY, invalidNetmask);
-
-        // If there is no netmask, implicit netmasks are used.
-        checkIpAddress("192.0.2.43/24", ANY, example2, null);
-    }
-
-    private void assertDhcpResults(String ipAddress, String gateway, String dnsServersString,
-            String domains, String serverAddress, String serverHostName, String vendorInfo,
-            int leaseDuration, boolean hasMeteredHint, int mtu, DhcpResults dhcpResults)
-                    throws Exception {
-        assertEquals(new LinkAddress(ipAddress), dhcpResults.ipAddress);
-        assertEquals(v4Address(gateway), dhcpResults.gateway);
-
-        String[] dnsServerStrings = dnsServersString.split(",");
-        ArrayList dnsServers = new ArrayList();
-        for (String dnsServerString : dnsServerStrings) {
-            dnsServers.add(v4Address(dnsServerString));
-        }
-        assertEquals(dnsServers, dhcpResults.dnsServers);
-
-        assertEquals(domains, dhcpResults.domains);
-        assertEquals(v4Address(serverAddress), dhcpResults.serverAddress);
-        assertEquals(serverHostName, dhcpResults.serverHostName);
-        assertEquals(vendorInfo, dhcpResults.vendorInfo);
-        assertEquals(leaseDuration, dhcpResults.leaseDuration);
-        assertEquals(hasMeteredHint, dhcpResults.hasMeteredHint());
-        assertEquals(mtu, dhcpResults.mtu);
-    }
-
-    @Test
-    public void testOffer1() throws Exception {
-        // TODO: Turn all of these into golden files. This will probably require using
-        // androidx.test.InstrumentationRegistry for obtaining a Context object
-        // to read such golden files, along with an appropriate Android.mk.
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "451001480000000080118849c0a89003c0a89ff7" +
-            // UDP header.
-            "004300440134dcfa" +
-            // BOOTP header.
-            "02010600c997a63b0000000000000000c0a89ff70000000000000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
-            "3a0400000e103b040000189cff00000000000000000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
-                null, "192.168.144.3", "", null, 7200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testOffer2() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name ("dhcp.android.com" plus invalid "AAAA" after null terminator).
-            "646863702e616e64726f69642e636f6d00000000000000000000000000000000" +
-            "0000000000004141414100000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
-        // CHECKSTYLE:ON Generated code
-
-        assertEquals(337, packet.limit());
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.43.247/24", "192.168.43.1", "192.168.43.1",
-                null, "192.168.43.1", "dhcp.android.com", "ANDROID_METERED", 3600, true, 0,
-                dhcpResults);
-        assertTrue(dhcpResults.hasMeteredHint());
-    }
-
-    @Test
-    public void testBadIpPacket() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadDhcpPacket() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadTruncatedOffer() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File, missing one byte
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "00000000000000000000000000000000000000000000000000000000000000");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.L3_TOO_SHORT, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testBadOfferWithoutACookie() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000"
-            // No options
-            );
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.DHCP_NO_COOKIE, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    @Test
-    public void testOfferWithBadCookie() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Bad cookie
-            "DEADBEEF3501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
-
-        try {
-            DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-        } catch (DhcpPacket.ParseException expected) {
-            assertDhcpErrorCodes(DhcpErrorEvent.DHCP_BAD_MAGIC_COOKIE, expected.errorCode);
-            return;
-        }
-        fail("Dhcp packet parsing should have failed");
-    }
-
-    private void assertDhcpErrorCodes(int expected, int got) {
-        assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
-    }
-
-    @Test
-    public void testTruncatedOfferPackets() throws Exception {
-        final byte[] packet = HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff");
-
-        for (int len = 0; len < packet.length; len++) {
-            try {
-                DhcpPacket.decodeFullPacket(packet, len, ENCAP_L3);
-            } catch (ParseException e) {
-                if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
-                    fail(String.format("bad truncated packet of length %d", len));
-                }
-            }
-        }
-    }
-
-    @Test
-    public void testRandomPackets() throws Exception {
-        final int maxRandomPacketSize = 512;
-        final Random r = new Random();
-        for (int i = 0; i < 10000; i++) {
-            byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
-            r.nextBytes(packet);
-            try {
-                DhcpPacket.decodeFullPacket(packet, packet.length, ENCAP_L3);
-            } catch (ParseException e) {
-                if (e.errorCode == DhcpErrorEvent.PARSING_ERROR) {
-                    fail("bad packet: " + HexDump.toHexString(packet));
-                }
-            }
-        }
-    }
-
-    private byte[] mtuBytes(int mtu) {
-        // 0x1a02: option 26, length 2. 0xff: no more options.
-        if (mtu > Short.MAX_VALUE - Short.MIN_VALUE) {
-            throw new IllegalArgumentException(
-                String.format("Invalid MTU %d, must be 16-bit unsigned", mtu));
-        }
-        String hexString = String.format("1a02%04xff", mtu);
-        return HexDump.hexStringToByteArray(hexString);
-    }
-
-    private void checkMtu(ByteBuffer packet, int expectedMtu, byte[] mtuBytes) throws Exception {
-        if (mtuBytes != null) {
-            packet.position(packet.capacity() - mtuBytes.length);
-            packet.put(mtuBytes);
-            packet.clear();
-        }
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);  // Implicitly checks it's non-null.
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.159.247/20", "192.168.159.254", "8.8.8.8,8.8.4.4",
-                null, "192.168.144.3", "", null, 7200, false, expectedMtu, dhcpResults);
-    }
-
-    @Test
-    public void testMtu() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "451001480000000080118849c0a89003c0a89ff7" +
-            // UDP header.
-            "004300440134dcfa" +
-            // BOOTP header.
-            "02010600c997a63b0000000000000000c0a89ff70000000000000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a89003330400001c200104fffff0000304c0a89ffe06080808080808080404" +
-            "3a0400000e103b040000189cff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        checkMtu(packet, 0, null);
-        checkMtu(packet, 0, mtuBytes(1501));
-        checkMtu(packet, 1500, mtuBytes(1500));
-        checkMtu(packet, 1499, mtuBytes(1499));
-        checkMtu(packet, 1280, mtuBytes(1280));
-        checkMtu(packet, 0, mtuBytes(1279));
-        checkMtu(packet, 0, mtuBytes(576));
-        checkMtu(packet, 0, mtuBytes(68));
-        checkMtu(packet, 0, mtuBytes(Short.MIN_VALUE));
-        checkMtu(packet, 0, mtuBytes(Short.MAX_VALUE + 3));
-        checkMtu(packet, 0, mtuBytes(-1));
-    }
-
-    @Test
-    public void testBadHwaddrLength() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "450001518d0600004011144dc0a82b01c0a82bf7" +
-            // UDP header.
-            "00430044013d9ac7" +
-            // BOOTP header.
-            "02010600dfc23d1f0002000000000000c0a82bf7c0a82b0100000000" +
-            // MAC address.
-            "30766ff2a90c00000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604c0a82b01330400000e103a04000007083b0400000c4e0104ffffff00" +
-            "1c04c0a82bff0304c0a82b010604c0a82b012b0f414e44524f49445f4d455445524544ff"));
-        // CHECKSTYLE:ON Generated code
-        String expectedClientMac = "30766FF2A90C";
-
-        final int hwAddrLenOffset = 20 + 8 + 2;
-        assertEquals(6, packet.get(hwAddrLenOffset));
-
-        // Expect the expected.
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Reduce the hardware address length and verify that it shortens the client MAC.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 5);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(5, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac.substring(0, 10),
-                HexDump.toHexString(offerPacket.getClientMac()));
-
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 3);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(3, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac.substring(0, 6),
-                HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Set the the hardware address length to 0xff and verify that we a) don't treat it as -1
-        // and crash, and b) hardcode it to 6.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) -1);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-
-        // Set the the hardware address length to a positive invalid value (> 16) and verify that we
-        // hardcode it to 6.
-        packet.flip();
-        packet.put(hwAddrLenOffset, (byte) 17);
-        offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertNotNull(offerPacket);
-        assertEquals(6, offerPacket.getClientMac().length);
-        assertEquals(expectedClientMac, HexDump.toHexString(offerPacket.getClientMac()));
-    }
-
-    @Test
-    public void testPadAndOverloadedOptionsOffer() throws Exception {
-        // A packet observed in the real world that is interesting for two reasons:
-        //
-        // 1. It uses pad bytes, which we previously didn't support correctly.
-        // 2. It uses DHCP option overloading, which we don't currently support (but it doesn't
-        //    store any information in the overloaded fields).
-        //
-        // For now, we just check that it parses correctly.
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "b4cef6000000e80462236e300800" +
-            // IP header.
-            "4500014c00000000ff11741701010101ac119876" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "004300440138ae5a" +
-            // BOOTP header.
-            "020106000fa0059f0000000000000000ac1198760000000000000000" +
-            // MAC address.
-            "b4cef600000000000000000000000000" +
-            // Server name.
-            "ff00000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "ff00000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options
-            "638253633501023604010101010104ffff000033040000a8c03401030304ac1101010604ac110101" +
-            "0000000000000000000000000000000000000000000000ff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("172.17.152.118/16", "172.17.1.1", "172.17.1.1",
-                null, "1.1.1.1", "", null, 43200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testBug2111() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // IP header.
-            "4500014c00000000ff119beac3eaf3880a3f5d04" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401387464" +
-            // BOOTP header.
-            "0201060002554812000a0000000000000a3f5d040000000000000000" +
-            // MAC address.
-            "00904c00000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "638253633501023604c00002fe33040000bfc60104fffff00003040a3f50010608c0000201c0000202" +
-            "0f0f646f6d61696e3132332e636f2e756b0000000000ff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L3);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.63.93.4/20", "10.63.80.1", "192.0.2.1,192.0.2.2",
-                "domain123.co.uk", "192.0.2.254", "", null, 49094, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testBug2136() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "bcf5ac000000d0c7890000000800" +
-            // IP header.
-            "4500014c00000000ff119beac3eaf3880a3f5d04" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401387574" +
-            // BOOTP header.
-            "0201060163339a3000050000000000000a209ecd0000000000000000" +
-            // MAC address.
-            "bcf5ac00000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a20ff80330400001c200104fffff00003040a20900106089458413494584135" +
-            "0f0b6c616e63732e61632e756b000000000000000000ff00000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("BCF5AC000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53",
-                "lancs.ac.uk", "10.32.255.128", "", null, 7200, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testUdpServerAnySourcePort() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "9cd917000000001c2e0000000800" +
-            // IP header.
-            "45a00148000040003d115087d18194fb0a0f7af2" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            // NOTE: The server source port is not the canonical port 67.
-            "C29F004401341268" +
-            // BOOTP header.
-            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
-            // MAC address.
-            "9cd91700000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
-            "d18180060f0777766d2e6564751c040a0fffffff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("9CD917000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("10.15.122.242/16", "10.15.200.23",
-                "209.129.128.3,209.129.148.3,209.129.128.6",
-                "wvm.edu", "10.1.105.252", "", null, 86400, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testUdpInvalidDstPort() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "9cd917000000001c2e0000000800" +
-            // IP header.
-            "45a00148000040003d115087d18194fb0a0f7af2" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            // NOTE: The destination port is a non-DHCP port.
-            "0043aaaa01341268" +
-            // BOOTP header.
-            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
-            // MAC address.
-            "9cd91700000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
-            "d18180060f0777766d2e6564751c040a0fffffff000000"));
-        // CHECKSTYLE:ON Generated code
-
-        try {
-            DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-            fail("Packet with invalid dst port did not throw ParseException");
-        } catch (ParseException expected) {}
-    }
-
-    @Test
-    public void testMultipleRouters() throws Exception {
-        // CHECKSTYLE:OFF Generated code
-        final ByteBuffer packet = ByteBuffer.wrap(HexDump.hexStringToByteArray(
-            // Ethernet header.
-            "fc3d93000000" + "081735000000" + "0800" +
-            // IP header.
-            "45000148c2370000ff117ac2c0a8bd02ffffffff" +
-            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
-            "0043004401343beb" +
-            // BOOTP header.
-            "0201060027f518e20000800000000000c0a8bd310000000000000000" +
-            // MAC address.
-            "fc3d9300000000000000000000000000" +
-            // Server name.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // File.
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            "0000000000000000000000000000000000000000000000000000000000000000" +
-            // Options.
-            "638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" +
-            "0308c0a8bd01ffffff0006080808080808080404ff000000000000"));
-        // CHECKSTYLE:ON Generated code
-
-        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
-        assertTrue(offerPacket instanceof DhcpOfferPacket);
-        assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac()));
-        DhcpResults dhcpResults = offerPacket.toDhcpResults();
-        assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4",
-                null, "192.171.189.2", "", null, 28800, false, 0, dhcpResults);
-    }
-
-    @Test
-    public void testDiscoverPacket() throws Exception {
-        short secs = 7;
-        int transactionId = 0xdeadbeef;
-        byte[] hwaddr = {
-                (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a
-        };
-
-        ByteBuffer packet = DhcpPacket.buildDiscoverPacket(
-                DhcpPacket.ENCAP_L2, transactionId, secs, hwaddr,
-                false /* do unicast */, DhcpClient.REQUESTED_PARAMS);
-
-        byte[] headers = new byte[] {
-            // Ethernet header.
-            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
-            (byte) 0x08, (byte) 0x00,
-            // IP header.
-            (byte) 0x45, (byte) 0x10, (byte) 0x01, (byte) 0x56,
-            (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x00,
-            (byte) 0x40, (byte) 0x11, (byte) 0x39, (byte) 0x88,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
-            // UDP header.
-            (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x43,
-            (byte) 0x01, (byte) 0x42, (byte) 0x6a, (byte) 0x4a,
-            // BOOTP.
-            (byte) 0x01, (byte) 0x01, (byte) 0x06, (byte) 0x00,
-            (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
-            (byte) 0x00, (byte) 0x07, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-            (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b,
-            (byte) 0xb1, (byte) 0x7a
-        };
-        byte[] options = new byte[] {
-            // Magic cookie 0x63825363.
-            (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
-            // Message type DISCOVER.
-            (byte) 0x35, (byte) 0x01, (byte) 0x01,
-            // Client identifier Ethernet, da:01:19:5b:b1:7a.
-            (byte) 0x3d, (byte) 0x07,
-                    (byte) 0x01,
-                    (byte) 0xda, (byte) 0x01, (byte) 0x19, (byte) 0x5b, (byte) 0xb1, (byte) 0x7a,
-            // Max message size 1500.
-            (byte) 0x39, (byte) 0x02, (byte) 0x05, (byte) 0xdc,
-            // Version "android-dhcp-???".
-            (byte) 0x3c, (byte) 0x10,
-                    'a', 'n', 'd', 'r', 'o', 'i', 'd', '-', 'd', 'h', 'c', 'p', '-', '?', '?', '?',
-            // Hostname "android-01234567890abcde"
-            (byte) 0x0c, (byte) 0x18,
-                    'a', 'n', 'd', 'r', 'o', 'i', 'd', '-',
-                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e',
-            // Requested parameter list.
-            (byte) 0x37, (byte) 0x0a,
-                DHCP_SUBNET_MASK,
-                DHCP_ROUTER,
-                DHCP_DNS_SERVER,
-                DHCP_DOMAIN_NAME,
-                DHCP_MTU,
-                DHCP_BROADCAST_ADDRESS,
-                DHCP_LEASE_TIME,
-                DHCP_RENEWAL_TIME,
-                DHCP_REBINDING_TIME,
-                DHCP_VENDOR_INFO,
-            // End options.
-            (byte) 0xff,
-            // Our packets are always of even length. TODO: find out why and possibly fix it.
-            (byte) 0x00
-        };
-        byte[] expected = new byte[DhcpPacket.MIN_PACKET_LENGTH_L2 + options.length];
-        assertTrue((expected.length & 1) == 0);
-        System.arraycopy(headers, 0, expected, 0, headers.length);
-        System.arraycopy(options, 0, expected, DhcpPacket.MIN_PACKET_LENGTH_L2, options.length);
-
-        byte[] actual = new byte[packet.limit()];
-        packet.get(actual);
-        String msg =
-                "Expected:\n  " + Arrays.toString(expected) +
-                "\nActual:\n  " + Arrays.toString(actual);
-        assertTrue(msg, Arrays.equals(expected, actual));
-    }
-
-    public void checkBuildOfferPacket(int leaseTimeSecs, @Nullable String hostname)
-            throws Exception {
-        final int renewalTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) / 2);
-        final int rebindingTime = (int) (Integer.toUnsignedLong(leaseTimeSecs) * 875 / 1000);
-        final int transactionId = 0xdeadbeef;
-
-        final ByteBuffer packet = DhcpPacket.buildOfferPacket(
-                DhcpPacket.ENCAP_BOOTP, transactionId, false /* broadcast */,
-                SERVER_ADDR, INADDR_ANY /* relayIp */, CLIENT_ADDR /* yourIp */,
-                CLIENT_MAC, leaseTimeSecs, NETMASK /* netMask */,
-                BROADCAST_ADDR /* bcAddr */, Collections.singletonList(SERVER_ADDR) /* gateways */,
-                Collections.singletonList(SERVER_ADDR) /* dnsServers */,
-                SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, hostname,
-                false /* metered */, MTU);
-
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        // BOOTP headers
-        bos.write(new byte[] {
-                (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x00,
-                (byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
-                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-                // ciaddr
-                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-        });
-        // yiaddr
-        bos.write(CLIENT_ADDR.getAddress());
-        // siaddr
-        bos.write(SERVER_ADDR.getAddress());
-        // giaddr
-        bos.write(INADDR_ANY.getAddress());
-        // chaddr
-        bos.write(CLIENT_MAC);
-
-        // Padding
-        bos.write(new byte[202]);
-
-        // Options
-        bos.write(new byte[]{
-                // Magic cookie 0x63825363.
-                (byte) 0x63, (byte) 0x82, (byte) 0x53, (byte) 0x63,
-                // Message type OFFER.
-                (byte) 0x35, (byte) 0x01, (byte) 0x02,
-        });
-        // Server ID
-        bos.write(new byte[] { (byte) 0x36, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Lease time
-        bos.write(new byte[] { (byte) 0x33, (byte) 0x04 });
-        bos.write(intToByteArray(leaseTimeSecs));
-        if (leaseTimeSecs != INFINITE_LEASE) {
-            // Renewal time
-            bos.write(new byte[]{(byte) 0x3a, (byte) 0x04});
-            bos.write(intToByteArray(renewalTime));
-            // Rebinding time
-            bos.write(new byte[]{(byte) 0x3b, (byte) 0x04});
-            bos.write(intToByteArray(rebindingTime));
-        }
-        // Subnet mask
-        bos.write(new byte[] { (byte) 0x01, (byte) 0x04 });
-        bos.write(NETMASK.getAddress());
-        // Broadcast address
-        bos.write(new byte[] { (byte) 0x1c, (byte) 0x04 });
-        bos.write(BROADCAST_ADDR.getAddress());
-        // Router
-        bos.write(new byte[] { (byte) 0x03, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Nameserver
-        bos.write(new byte[] { (byte) 0x06, (byte) 0x04 });
-        bos.write(SERVER_ADDR.getAddress());
-        // Hostname
-        if (hostname != null) {
-            bos.write(new byte[]{(byte) 0x0c, (byte) hostname.length()});
-            bos.write(hostname.getBytes(Charset.forName("US-ASCII")));
-        }
-        // MTU
-        bos.write(new byte[] { (byte) 0x1a, (byte) 0x02 });
-        bos.write(shortToByteArray(MTU));
-        // End options.
-        bos.write(0xff);
-
-        if ((bos.size() & 1) != 0) {
-            bos.write(0x00);
-        }
-
-        final byte[] expected = bos.toByteArray();
-        final byte[] actual = new byte[packet.limit()];
-        packet.get(actual);
-        final String msg = "Expected:\n  " + HexDump.dumpHexString(expected) +
-                "\nActual:\n  " + HexDump.dumpHexString(actual);
-        assertTrue(msg, Arrays.equals(expected, actual));
-    }
-
-    @Test
-    public void testOfferPacket() throws Exception {
-        checkBuildOfferPacket(3600, HOSTNAME);
-        checkBuildOfferPacket(Integer.MAX_VALUE, HOSTNAME);
-        checkBuildOfferPacket(0x80000000, HOSTNAME);
-        checkBuildOfferPacket(INFINITE_LEASE, HOSTNAME);
-        checkBuildOfferPacket(3600, null);
-    }
-
-    private static byte[] intToByteArray(int val) {
-        return ByteBuffer.allocate(4).putInt(val).array();
-    }
-
-    private static byte[] shortToByteArray(short val) {
-        return ByteBuffer.allocate(2).putShort(val).array();
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java
deleted file mode 100644
index f0e2f1b..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java
+++ /dev/null
@@ -1,333 +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.net.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpPacket.DHCP_CLIENT;
-import static android.net.dhcp.DhcpPacket.DHCP_HOST_NAME;
-import static android.net.dhcp.DhcpPacket.ENCAP_BOOTP;
-import static android.net.dhcp.DhcpPacket.INADDR_ANY;
-import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
-import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.INetworkStackStatusCallback;
-import android.net.LinkAddress;
-import android.net.MacAddress;
-import android.net.dhcp.DhcpLeaseRepository.InvalidAddressException;
-import android.net.dhcp.DhcpLeaseRepository.OutOfAddressesException;
-import android.net.dhcp.DhcpServer.Clock;
-import android.net.dhcp.DhcpServer.Dependencies;
-import android.net.util.SharedLog;
-import android.os.HandlerThread;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidTestingRunner.class)
-@SmallTest
-@RunWithLooper
-public class DhcpServerTest {
-    private static final String TEST_IFACE = "testiface";
-
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
-    private static final LinkAddress TEST_SERVER_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
-    private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124")));
-    private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127")));
-    private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
-    private static final long TEST_LEASE_TIME_SECS = 3600L;
-    private static final int TEST_MTU = 1500;
-    private static final String TEST_HOSTNAME = "testhostname";
-
-    private static final int TEST_TRANSACTION_ID = 123;
-    private static final byte[] TEST_CLIENT_MAC_BYTES = new byte [] { 1, 2, 3, 4, 5, 6 };
-    private static final MacAddress TEST_CLIENT_MAC = MacAddress.fromBytes(TEST_CLIENT_MAC_BYTES);
-    private static final Inet4Address TEST_CLIENT_ADDR = parseAddr("192.168.0.42");
-
-    private static final long TEST_CLOCK_TIME = 1234L;
-    private static final int TEST_LEASE_EXPTIME_SECS = 3600;
-    private static final DhcpLease TEST_LEASE = new DhcpLease(null, TEST_CLIENT_MAC,
-            TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME,
-            null /* hostname */);
-    private static final DhcpLease TEST_LEASE_WITH_HOSTNAME = new DhcpLease(null, TEST_CLIENT_MAC,
-            TEST_CLIENT_ADDR, TEST_LEASE_EXPTIME_SECS * 1000L + TEST_CLOCK_TIME, TEST_HOSTNAME);
-
-    @NonNull @Mock
-    private Dependencies mDeps;
-    @NonNull @Mock
-    private DhcpLeaseRepository mRepository;
-    @NonNull @Mock
-    private Clock mClock;
-    @NonNull @Mock
-    private DhcpPacketListener mPacketListener;
-
-    @NonNull @Captor
-    private ArgumentCaptor<ByteBuffer> mSentPacketCaptor;
-    @NonNull @Captor
-    private ArgumentCaptor<Inet4Address> mResponseDstAddrCaptor;
-
-    @NonNull
-    private HandlerThread mHandlerThread;
-    @NonNull
-    private TestableLooper mLooper;
-    @NonNull
-    private DhcpServer mServer;
-
-    @Nullable
-    private String mPrevShareClassloaderProp;
-
-    private final INetworkStackStatusCallback mAssertSuccessCallback =
-            new INetworkStackStatusCallback.Stub() {
-        @Override
-        public void onStatusAvailable(int statusCode) {
-            assertEquals(STATUS_SUCCESS, statusCode);
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return this.VERSION;
-        }
-    };
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mDeps.makeLeaseRepository(any(), any(), any())).thenReturn(mRepository);
-        when(mDeps.makeClock()).thenReturn(mClock);
-        when(mDeps.makePacketListener()).thenReturn(mPacketListener);
-        doNothing().when(mDeps)
-                .sendPacket(any(), mSentPacketCaptor.capture(), mResponseDstAddrCaptor.capture());
-        when(mClock.elapsedRealtime()).thenReturn(TEST_CLOCK_TIME);
-
-        final DhcpServingParams servingParams = new DhcpServingParams.Builder()
-                .setDefaultRouters(TEST_DEFAULT_ROUTERS)
-                .setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS)
-                .setDnsServers(TEST_DNS_SERVERS)
-                .setServerAddr(TEST_SERVER_LINKADDR)
-                .setLinkMtu(TEST_MTU)
-                .setExcludedAddrs(TEST_EXCLUDED_ADDRS)
-                .build();
-
-        mLooper = TestableLooper.get(this);
-        mHandlerThread = spy(new HandlerThread("TestDhcpServer"));
-        when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
-        mServer = new DhcpServer(mHandlerThread, TEST_IFACE, servingParams,
-                new SharedLog(DhcpServerTest.class.getSimpleName()), mDeps);
-
-        mServer.start(mAssertSuccessCallback);
-        mLooper.processAllMessages();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mServer.stop(mAssertSuccessCallback);
-        mLooper.processMessages(1);
-        verify(mPacketListener, times(1)).stop();
-        verify(mHandlerThread, times(1)).quitSafely();
-    }
-
-    @Test
-    public void testStart() throws Exception {
-        verify(mPacketListener, times(1)).start();
-    }
-
-    @Test
-    public void testDiscover() throws Exception {
-        // TODO: refactor packet construction to eliminate unnecessary/confusing/duplicate fields
-        when(mRepository.getOffer(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* relayAddr */, isNull() /* reqAddr */, isNull() /* hostname */))
-                .thenReturn(TEST_LEASE);
-
-        final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
-                false /* broadcast */, INADDR_ANY /* srcIp */);
-        mServer.processPacket(discover, DHCP_CLIENT);
-
-        assertResponseSentTo(TEST_CLIENT_ADDR);
-        final DhcpOfferPacket packet = assertOffer(getPacket());
-        assertMatchesTestLease(packet);
-    }
-
-    @Test
-    public void testDiscover_OutOfAddresses() throws Exception {
-        when(mRepository.getOffer(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* relayAddr */, isNull() /* reqAddr */, isNull() /* hostname */))
-                .thenThrow(new OutOfAddressesException("Test exception"));
-
-        final DhcpDiscoverPacket discover = new DhcpDiscoverPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES,
-                false /* broadcast */, INADDR_ANY /* srcIp */);
-        mServer.processPacket(discover, DHCP_CLIENT);
-
-        assertResponseSentTo(INADDR_BROADCAST);
-        final DhcpNakPacket packet = assertNak(getPacket());
-        assertMatchesClient(packet);
-    }
-
-    private DhcpRequestPacket makeRequestSelectingPacket() {
-        final DhcpRequestPacket request = new DhcpRequestPacket(TEST_TRANSACTION_ID,
-                (short) 0 /* secs */, INADDR_ANY /* clientIp */, INADDR_ANY /* relayIp */,
-                TEST_CLIENT_MAC_BYTES, false /* broadcast */);
-        request.mServerIdentifier = TEST_SERVER_ADDR;
-        request.mRequestedIp = TEST_CLIENT_ADDR;
-        return request;
-    }
-
-    @Test
-    public void testRequest_Selecting_Ack() throws Exception {
-        when(mRepository.requestLease(isNull() /* clientId */, eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* clientAddr */, eq(INADDR_ANY) /* relayAddr */,
-                eq(TEST_CLIENT_ADDR) /* reqAddr */, eq(true) /* sidSet */, eq(TEST_HOSTNAME)))
-                .thenReturn(TEST_LEASE_WITH_HOSTNAME);
-
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        request.mHostName = TEST_HOSTNAME;
-        request.mRequestedParams = new byte[] { DHCP_HOST_NAME };
-        mServer.processPacket(request, DHCP_CLIENT);
-
-        assertResponseSentTo(TEST_CLIENT_ADDR);
-        final DhcpAckPacket packet = assertAck(getPacket());
-        assertMatchesTestLease(packet, TEST_HOSTNAME);
-    }
-
-    @Test
-    public void testRequest_Selecting_Nak() throws Exception {
-        when(mRepository.requestLease(isNull(), eq(TEST_CLIENT_MAC),
-                eq(INADDR_ANY) /* clientAddr */, eq(INADDR_ANY) /* relayAddr */,
-                eq(TEST_CLIENT_ADDR) /* reqAddr */, eq(true) /* sidSet */, isNull() /* hostname */))
-                .thenThrow(new InvalidAddressException("Test error"));
-
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        mServer.processPacket(request, DHCP_CLIENT);
-
-        assertResponseSentTo(INADDR_BROADCAST);
-        final DhcpNakPacket packet = assertNak(getPacket());
-        assertMatchesClient(packet);
-    }
-
-    @Test
-    public void testRequest_Selecting_WrongClientPort() throws Exception {
-        final DhcpRequestPacket request = makeRequestSelectingPacket();
-        mServer.processPacket(request, 50000);
-
-        verify(mRepository, never())
-                .requestLease(any(), any(), any(), any(), any(), anyBoolean(), any());
-        verify(mDeps, never()).sendPacket(any(), any(), any());
-    }
-
-    @Test
-    public void testRelease() throws Exception {
-        final DhcpReleasePacket release = new DhcpReleasePacket(TEST_TRANSACTION_ID,
-                TEST_SERVER_ADDR, TEST_CLIENT_ADDR,
-                INADDR_ANY /* relayIp */, TEST_CLIENT_MAC_BYTES);
-        mServer.processPacket(release, DHCP_CLIENT);
-
-        verify(mRepository, times(1))
-                .releaseLease(isNull(), eq(TEST_CLIENT_MAC), eq(TEST_CLIENT_ADDR));
-    }
-
-    /* TODO: add more tests once packet construction is refactored, including:
-     *  - usage of giaddr
-     *  - usage of broadcast bit
-     *  - other request states (init-reboot/renewing/rebinding)
-     */
-
-    private void assertMatchesTestLease(@NonNull DhcpPacket packet, @Nullable String hostname) {
-        assertMatchesClient(packet);
-        assertFalse(packet.hasExplicitClientId());
-        assertEquals(TEST_SERVER_ADDR, packet.mServerIdentifier);
-        assertEquals(TEST_CLIENT_ADDR, packet.mYourIp);
-        assertNotNull(packet.mLeaseTime);
-        assertEquals(TEST_LEASE_EXPTIME_SECS, (int) packet.mLeaseTime);
-        assertEquals(hostname, packet.mHostName);
-    }
-
-    private void assertMatchesTestLease(@NonNull DhcpPacket packet) {
-        assertMatchesTestLease(packet, null);
-    }
-
-    private void assertMatchesClient(@NonNull DhcpPacket packet) {
-        assertEquals(TEST_TRANSACTION_ID, packet.mTransId);
-        assertEquals(TEST_CLIENT_MAC, MacAddress.fromBytes(packet.mClientMac));
-    }
-
-    private void assertResponseSentTo(@NonNull Inet4Address addr) {
-        assertEquals(addr, mResponseDstAddrCaptor.getValue());
-    }
-
-    private static DhcpNakPacket assertNak(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpNakPacket);
-        return (DhcpNakPacket) packet;
-    }
-
-    private static DhcpAckPacket assertAck(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpAckPacket);
-        return (DhcpAckPacket) packet;
-    }
-
-    private static DhcpOfferPacket assertOffer(@Nullable DhcpPacket packet) {
-        assertTrue(packet instanceof DhcpOfferPacket);
-        return (DhcpOfferPacket) packet;
-    }
-
-    private DhcpPacket getPacket() throws Exception {
-        verify(mDeps, times(1)).sendPacket(any(), any(), any());
-        return DhcpPacket.decodeFullPacket(mSentPacketCaptor.getValue(), ENCAP_BOOTP);
-    }
-
-    private static Inet4Address parseAddr(@Nullable String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
deleted file mode 100644
index 57a87a4..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
+++ /dev/null
@@ -1,221 +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.net.dhcp;
-
-import static android.net.InetAddresses.parseNumericAddress;
-import static android.net.dhcp.DhcpServingParams.MTU_UNSET;
-import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.LinkAddress;
-import android.net.dhcp.DhcpServingParams.InvalidParameterException;
-import android.net.shared.Inet4AddressUtils;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.lang.reflect.Modifier;
-import java.net.Inet4Address;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class DhcpServingParamsTest {
-    @NonNull
-    private DhcpServingParams.Builder mBuilder;
-
-    private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124")));
-    private static final long TEST_LEASE_TIME_SECS = 3600L;
-    private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127")));
-    private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
-    private static final LinkAddress TEST_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
-    private static final int TEST_MTU = 1500;
-    private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>(
-            Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201")));
-    private static final boolean TEST_METERED = true;
-
-    @Before
-    public void setUp() {
-        mBuilder = new DhcpServingParams.Builder()
-                .setDefaultRouters(TEST_DEFAULT_ROUTERS)
-                .setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS)
-                .setDnsServers(TEST_DNS_SERVERS)
-                .setServerAddr(TEST_LINKADDR)
-                .setLinkMtu(TEST_MTU)
-                .setExcludedAddrs(TEST_EXCLUDED_ADDRS)
-                .setMetered(TEST_METERED);
-    }
-
-    @Test
-    public void testBuild_Immutable() throws InvalidParameterException {
-        final Set<Inet4Address> routers = new HashSet<>(TEST_DEFAULT_ROUTERS);
-        final Set<Inet4Address> dnsServers = new HashSet<>(TEST_DNS_SERVERS);
-        final Set<Inet4Address> excludedAddrs = new HashSet<>(TEST_EXCLUDED_ADDRS);
-
-        final DhcpServingParams params = mBuilder
-                .setDefaultRouters(routers)
-                .setDnsServers(dnsServers)
-                .setExcludedAddrs(excludedAddrs)
-                .build();
-
-        // Modifications to source objects should not affect builder or final parameters
-        final Inet4Address addedAddr = parseAddr("192.168.0.223");
-        routers.add(addedAddr);
-        dnsServers.add(addedAddr);
-        excludedAddrs.add(addedAddr);
-
-        assertEquals(TEST_DEFAULT_ROUTERS, params.defaultRouters);
-        assertEquals(TEST_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs);
-        assertEquals(TEST_DNS_SERVERS, params.dnsServers);
-        assertEquals(TEST_LINKADDR, params.serverAddr);
-        assertEquals(TEST_MTU, params.linkMtu);
-        assertEquals(TEST_METERED, params.metered);
-
-        assertContains(params.excludedAddrs, TEST_EXCLUDED_ADDRS);
-        assertContains(params.excludedAddrs, TEST_DEFAULT_ROUTERS);
-        assertContains(params.excludedAddrs, TEST_DNS_SERVERS);
-        assertContains(params.excludedAddrs, TEST_SERVER_ADDR);
-
-        assertFalse("excludedAddrs should not contain " + addedAddr,
-                params.excludedAddrs.contains(addedAddr));
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_NegativeLeaseTime() throws InvalidParameterException {
-        mBuilder.setDhcpLeaseTimeSecs(-1).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_LeaseTimeTooLarge() throws InvalidParameterException {
-        // Set lease time larger than max value for uint32
-        mBuilder.setDhcpLeaseTimeSecs(1L << 32).build();
-    }
-
-    @Test
-    public void testBuild_InfiniteLeaseTime() throws InvalidParameterException {
-        final long infiniteLeaseTime = 0xffffffffL;
-        final DhcpServingParams params = mBuilder
-                .setDhcpLeaseTimeSecs(infiniteLeaseTime).build();
-        assertEquals(infiniteLeaseTime, params.dhcpLeaseTimeSecs);
-        assertTrue(params.dhcpLeaseTimeSecs > 0L);
-    }
-
-    @Test
-    public void testBuild_UnsetMtu() throws InvalidParameterException {
-        final DhcpServingParams params = mBuilder.setLinkMtu(MTU_UNSET).build();
-        assertEquals(MTU_UNSET, params.linkMtu);
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_MtuTooSmall() throws InvalidParameterException {
-        mBuilder.setLinkMtu(20).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_MtuTooLarge() throws InvalidParameterException {
-        mBuilder.setLinkMtu(65_536).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_IPv6Addr() throws InvalidParameterException {
-        mBuilder.setServerAddr(new LinkAddress(parseNumericAddress("fe80::1111"), 120)).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_PrefixTooLarge() throws InvalidParameterException {
-        mBuilder.setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 15)).build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_PrefixTooSmall() throws InvalidParameterException {
-        mBuilder.setDefaultRouters(parseAddr("192.168.0.254"))
-                .setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 31))
-                .build();
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testBuild_RouterNotInPrefix() throws InvalidParameterException {
-        mBuilder.setDefaultRouters(parseAddr("192.168.254.254")).build();
-    }
-
-    @Test
-    public void testFromParcelableObject() throws InvalidParameterException {
-        final DhcpServingParams params = mBuilder.build();
-        final DhcpServingParamsParcel parcel = new DhcpServingParamsParcel();
-        parcel.defaultRouters = toIntArray(TEST_DEFAULT_ROUTERS);
-        parcel.dhcpLeaseTimeSecs = TEST_LEASE_TIME_SECS;
-        parcel.dnsServers = toIntArray(TEST_DNS_SERVERS);
-        parcel.serverAddr = inet4AddressToIntHTH(TEST_SERVER_ADDR);
-        parcel.serverAddrPrefixLength = TEST_LINKADDR.getPrefixLength();
-        parcel.linkMtu = TEST_MTU;
-        parcel.excludedAddrs = toIntArray(TEST_EXCLUDED_ADDRS);
-        parcel.metered = TEST_METERED;
-        final DhcpServingParams parceled = DhcpServingParams.fromParcelableObject(parcel);
-
-        assertEquals(params.defaultRouters, parceled.defaultRouters);
-        assertEquals(params.dhcpLeaseTimeSecs, parceled.dhcpLeaseTimeSecs);
-        assertEquals(params.dnsServers, parceled.dnsServers);
-        assertEquals(params.serverAddr, parceled.serverAddr);
-        assertEquals(params.linkMtu, parceled.linkMtu);
-        assertEquals(params.excludedAddrs, parceled.excludedAddrs);
-        assertEquals(params.metered, parceled.metered);
-
-        // Ensure that we do not miss any field if added in the future
-        final long numFields = Arrays.stream(DhcpServingParams.class.getDeclaredFields())
-                .filter(f -> !Modifier.isStatic(f.getModifiers()))
-                .count();
-        assertEquals(7, numFields);
-    }
-
-    @Test(expected = InvalidParameterException.class)
-    public void testFromParcelableObject_NullArgument() throws InvalidParameterException {
-        DhcpServingParams.fromParcelableObject(null);
-    }
-
-    private static int[] toIntArray(Collection<Inet4Address> addrs) {
-        return addrs.stream().mapToInt(Inet4AddressUtils::inet4AddressToIntHTH).toArray();
-    }
-
-    private static <T> void assertContains(@NonNull Set<T> set, @NonNull Set<T> subset) {
-        for (final T elem : subset) {
-            assertContains(set, elem);
-        }
-    }
-
-    private static <T> void assertContains(@NonNull Set<T> set, @Nullable T elem) {
-        assertTrue("Set does not contain " + elem, set.contains(elem));
-    }
-
-    @NonNull
-    private static Inet4Address parseAddr(@NonNull String inet4Addr) {
-        return (Inet4Address) parseNumericAddress(inet4Addr);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java
deleted file mode 100644
index 5f80006..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-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.Mockito.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.app.AlarmManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.INetd;
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.MacAddress;
-import android.net.NetworkStackIpMemoryStore;
-import android.net.RouteInfo;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.shared.InitialConfiguration;
-import android.net.shared.ProvisioningConfiguration;
-import android.net.util.InterfaceParams;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.R;
-import com.android.server.NetworkObserver;
-import com.android.server.NetworkObserverRegistry;
-import com.android.server.NetworkStackService;
-
-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 java.net.InetAddress;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for IpClient.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IpClientTest {
-    private static final int DEFAULT_AVOIDBADWIFI_CONFIG_VALUE = 1;
-
-    private static final String VALID = "VALID";
-    private static final String INVALID = "INVALID";
-    private static final String TEST_IFNAME = "test_wlan0";
-    private static final int TEST_IFINDEX = 1001;
-    // See RFC 7042#section-2.1.2 for EUI-48 documentation values.
-    private static final MacAddress TEST_MAC = MacAddress.fromString("00:00:5E:00:53:01");
-    private static final int TEST_TIMEOUT_MS = 400;
-    private static final String TEST_L2KEY = "some l2key";
-    private static final String TEST_GROUPHINT = "some grouphint";
-
-    @Mock private Context mContext;
-    @Mock private ConnectivityManager mCm;
-    @Mock private NetworkObserverRegistry mObserverRegistry;
-    @Mock private INetd mNetd;
-    @Mock private Resources mResources;
-    @Mock private IIpClientCallbacks mCb;
-    @Mock private AlarmManager mAlarm;
-    @Mock private IpClient.Dependencies mDependencies;
-    @Mock private ContentResolver mContentResolver;
-    @Mock private NetworkStackService.NetworkStackServiceManager mNetworkStackServiceManager;
-    @Mock private NetworkStackIpMemoryStore mIpMemoryStore;
-
-    private NetworkObserver mObserver;
-    private InterfaceParams mIfParams;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mContext.getSystemService(eq(Context.ALARM_SERVICE))).thenReturn(mAlarm);
-        when(mContext.getSystemService(eq(ConnectivityManager.class))).thenReturn(mCm);
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mDependencies.getNetd(any())).thenReturn(mNetd);
-        when(mResources.getInteger(R.integer.config_networkAvoidBadWifi))
-                .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE);
-        when(mContext.getContentResolver()).thenReturn(mContentResolver);
-
-        mIfParams = null;
-    }
-
-    private void setTestInterfaceParams(String ifname) {
-        mIfParams = (ifname != null)
-                ? new InterfaceParams(ifname, TEST_IFINDEX, TEST_MAC)
-                : null;
-        when(mDependencies.getInterfaceParams(anyString())).thenReturn(mIfParams);
-    }
-
-    private IpClient makeIpClient(String ifname) throws Exception {
-        setTestInterfaceParams(ifname);
-        final IpClient ipc = new IpClient(mContext, ifname, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(ifname, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(ifname);
-        ArgumentCaptor<NetworkObserver> arg = ArgumentCaptor.forClass(NetworkObserver.class);
-        verify(mObserverRegistry, times(1)).registerObserverForNonblockingCallback(arg.capture());
-        mObserver = arg.getValue();
-        reset(mObserverRegistry);
-        reset(mNetd);
-        // Verify IpClient doesn't call onLinkPropertiesChange() when it starts.
-        verify(mCb, never()).onLinkPropertiesChange(any());
-        reset(mCb);
-        return ipc;
-    }
-
-    private static LinkProperties makeEmptyLinkProperties(String iface) {
-        final LinkProperties empty = new LinkProperties();
-        empty.setInterfaceName(iface);
-        return empty;
-    }
-
-    private void verifyNetworkAttributesStored(final String l2Key,
-            final NetworkAttributes attributes) {
-        // TODO : when storing is implemented, turn this on
-        // verify(mIpMemoryStore).storeNetworkAttributes(eq(l2Key), eq(attributes), any());
-    }
-
-    @Test
-    public void testNullInterfaceNameMostDefinitelyThrows() throws Exception {
-        setTestInterfaceParams(null);
-        try {
-            final IpClient ipc = new IpClient(mContext, null, mCb, mObserverRegistry,
-                    mNetworkStackServiceManager, mDependencies);
-            ipc.shutdown();
-            fail();
-        } catch (NullPointerException npe) {
-            // Phew; null interface names not allowed.
-        }
-    }
-
-    @Test
-    public void testNullCallbackMostDefinitelyThrows() throws Exception {
-        final String ifname = "lo";
-        setTestInterfaceParams(ifname);
-        try {
-            final IpClient ipc = new IpClient(mContext, ifname, null, mObserverRegistry,
-                    mNetworkStackServiceManager, mDependencies);
-            ipc.shutdown();
-            fail();
-        } catch (NullPointerException npe) {
-            // Phew; null callbacks not allowed.
-        }
-    }
-
-    @Test
-    public void testInvalidInterfaceDoesNotThrow() throws Exception {
-        setTestInterfaceParams(TEST_IFNAME);
-        final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        verifyNoMoreInteractions(mIpMemoryStore);
-        ipc.shutdown();
-    }
-
-    @Test
-    public void testInterfaceNotFoundFailsImmediately() throws Exception {
-        setTestInterfaceParams(null);
-        final IpClient ipc = new IpClient(mContext, TEST_IFNAME, mCb, mObserverRegistry,
-                mNetworkStackServiceManager, mDependencies);
-        ipc.startProvisioning(new ProvisioningConfiguration());
-        verify(mCb, times(1)).onProvisioningFailure(any());
-        verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any());
-        ipc.shutdown();
-    }
-
-    @Test
-    public void testDefaultProvisioningConfiguration() throws Exception {
-        final String iface = TEST_IFNAME;
-        final IpClient ipc = makeIpClient(iface);
-
-        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
-                .withoutIPv4()
-                // TODO: mock IpReachabilityMonitor's dependencies (NetworkInterface, PowerManager)
-                // and enable it in this test
-                .withoutIpReachabilityMonitor()
-                .build();
-
-        ipc.startProvisioning(config);
-        verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
-        verify(mCb, never()).onProvisioningFailure(any());
-        verify(mIpMemoryStore, never()).storeNetworkAttributes(any(), any(), any());
-
-        ipc.shutdown();
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
-                .onLinkPropertiesChange(makeEmptyLinkProperties(iface));
-    }
-
-    @Test
-    public void testProvisioningWithInitialConfiguration() throws Exception {
-        final String iface = TEST_IFNAME;
-        final IpClient ipc = makeIpClient(iface);
-        final String l2Key = TEST_L2KEY;
-        final String groupHint = TEST_GROUPHINT;
-
-        String[] addresses = {
-            "fe80::a4be:f92:e1f7:22d1/64",
-            "fe80::f04a:8f6:6a32:d756/64",
-            "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"
-        };
-        String[] prefixes = { "fe80::/64", "fd2c:4e57:8e3c::/64" };
-
-        ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
-                .withoutIPv4()
-                .withoutIpReachabilityMonitor()
-                .withInitialConfiguration(conf(links(addresses), prefixes(prefixes), ips()))
-                .build();
-
-        ipc.startProvisioning(config);
-        verify(mCb, times(1)).setNeighborDiscoveryOffload(true);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).setFallbackMulticastFilter(false);
-        verify(mCb, never()).onProvisioningFailure(any());
-        ipc.setL2KeyAndGroupHint(l2Key, groupHint);
-
-        for (String addr : addresses) {
-            String[] parts = addr.split("/");
-            verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1))
-                    .interfaceAddAddress(iface, parts[0], Integer.parseInt(parts[1]));
-        }
-
-        final int lastAddr = addresses.length - 1;
-
-        // Add N - 1 addresses
-        for (int i = 0; i < lastAddr; i++) {
-            mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[i]), iface);
-            verify(mCb, timeout(TEST_TIMEOUT_MS)).onLinkPropertiesChange(any());
-            reset(mCb);
-        }
-
-        // Add Nth address
-        mObserver.onInterfaceAddressUpdated(new LinkAddress(addresses[lastAddr]), iface);
-        LinkProperties want = linkproperties(links(addresses), routes(prefixes));
-        want.setInterfaceName(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(want);
-        verifyNetworkAttributesStored(l2Key, new NetworkAttributes.Builder()
-                .setGroupHint(groupHint)
-                .build());
-
-        ipc.shutdown();
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false);
-        verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface);
-        verify(mCb, timeout(TEST_TIMEOUT_MS).times(1))
-                .onLinkPropertiesChange(makeEmptyLinkProperties(iface));
-        verifyNoMoreInteractions(mIpMemoryStore);
-    }
-
-    @Test
-    public void testIsProvisioned() throws Exception {
-        InitialConfiguration empty = conf(links(), prefixes());
-        IsProvisionedTestCase[] testcases = {
-            // nothing
-            notProvisionedCase(links(), routes(), dns(), null),
-            notProvisionedCase(links(), routes(), dns(), empty),
-
-            // IPv4
-            provisionedCase(links("192.0.2.12/24"), routes(), dns(), empty),
-
-            // IPv6
-            notProvisionedCase(
-                    links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes(), dns(), empty),
-            notProvisionedCase(
-                    links("fe80::a4be:f92:e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes("fe80::/64", "fd2c:4e57:8e3c::/64"), dns("fd00:1234:5678::1000"), empty),
-            provisionedCase(
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    routes("::/0"),
-                    dns("2001:db8:dead:beef:f00::02"), empty),
-
-            // Initial configuration
-            provisionedCase(
-                    links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                    routes("fe80::/64", "fd2c:4e57:8e3c::/64"),
-                    dns(),
-                    conf(links("fe80::e1f7:22d1/64", "fd2c:4e57:8e3c:0:548d:2db2:4fcf:ef75/64"),
-                        prefixes( "fe80::/64", "fd2c:4e57:8e3c::/64"), ips()))
-        };
-
-        for (IsProvisionedTestCase testcase : testcases) {
-            if (IpClient.isProvisioned(testcase.lp, testcase.config) != testcase.isProvisioned) {
-                fail(testcase.errorMessage());
-            }
-        }
-    }
-
-    static class IsProvisionedTestCase {
-        boolean isProvisioned;
-        LinkProperties lp;
-        InitialConfiguration config;
-
-        String errorMessage() {
-            return String.format("expected %s with config %s to be %s, but was %s",
-                     lp, config, provisioned(isProvisioned), provisioned(!isProvisioned));
-        }
-
-        static String provisioned(boolean isProvisioned) {
-            return isProvisioned ? "provisioned" : "not provisioned";
-        }
-    }
-
-    static IsProvisionedTestCase provisionedCase(Set<LinkAddress> lpAddrs, Set<RouteInfo> lpRoutes,
-            Set<InetAddress> lpDns, InitialConfiguration config) {
-        return provisioningTest(true, lpAddrs, lpRoutes, lpDns, config);
-    }
-
-    static IsProvisionedTestCase notProvisionedCase(Set<LinkAddress> lpAddrs,
-            Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) {
-        return provisioningTest(false, lpAddrs, lpRoutes, lpDns, config);
-    }
-
-    static IsProvisionedTestCase provisioningTest(boolean isProvisioned, Set<LinkAddress> lpAddrs,
-            Set<RouteInfo> lpRoutes, Set<InetAddress> lpDns, InitialConfiguration config) {
-        IsProvisionedTestCase testcase = new IsProvisionedTestCase();
-        testcase.isProvisioned = isProvisioned;
-        testcase.lp = new LinkProperties();
-        testcase.lp.setLinkAddresses(lpAddrs);
-        for (RouteInfo route : lpRoutes) {
-            testcase.lp.addRoute(route);
-        }
-        for (InetAddress dns : lpDns) {
-            testcase.lp.addDnsServer(dns);
-        }
-        testcase.config = config;
-        return testcase;
-    }
-
-    @Test
-    public void testInitialConfigurations() throws Exception {
-        InitialConfigurationTestCase[] testcases = {
-            validConf("valid IPv4 configuration",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("192.0.2.2")),
-            validConf("another valid IPv4 configuration",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns()),
-            validConf("valid IPv6 configurations",
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    prefixes("2001:db8:dead:beef::/64", "fe80::/64"),
-                    dns("2001:db8:dead:beef:f00::02")),
-            validConf("valid IPv6 configurations",
-                    links("fe80::1/64"), prefixes("fe80::/64"), dns()),
-            validConf("valid IPv6/v4 configuration",
-                    links("2001:db8:dead:beef:f00::a0/48", "192.0.2.12/24"),
-                    prefixes("2001:db8:dead:beef::/64", "192.0.2.0/24"),
-                    dns("192.0.2.2", "2001:db8:dead:beef:f00::02")),
-            validConf("valid IPv6 configuration without any GUA.",
-                    links("fd00:1234:5678::1/48"),
-                    prefixes("fd00:1234:5678::/48"),
-                    dns("fd00:1234:5678::1000")),
-
-            invalidConf("empty configuration", links(), prefixes(), dns()),
-            invalidConf("v4 addr and dns not in any prefix",
-                    links("192.0.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")),
-            invalidConf("v4 addr not in any prefix",
-                    links("198.51.2.12/24"), prefixes("198.51.100.0/24"), dns("192.0.2.2")),
-            invalidConf("v4 dns addr not in any prefix",
-                    links("192.0.2.12/24"), prefixes("192.0.2.0/24"), dns("198.51.100.2")),
-            invalidConf("v6 addr not in any prefix",
-                    links("2001:db8:dead:beef:f00::a0/64", "fe80::1/64"),
-                    prefixes("2001:db8:dead:beef::/64"),
-                    dns("2001:db8:dead:beef:f00::02")),
-            invalidConf("v6 dns addr not in any prefix",
-                    links("fe80::1/64"), prefixes("fe80::/64"), dns("2001:db8:dead:beef:f00::02")),
-            invalidConf("default ipv6 route and no GUA",
-                    links("fd01:1111:2222:3333::a0/128"), prefixes("::/0"), dns()),
-            invalidConf("invalid v6 prefix length",
-                    links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/32"),
-                    dns()),
-            invalidConf("another invalid v6 prefix length",
-                    links("2001:db8:dead:beef:f00::a0/128"), prefixes("2001:db8:dead:beef::/72"),
-                    dns())
-        };
-
-        for (InitialConfigurationTestCase testcase : testcases) {
-            if (testcase.config.isValid() != testcase.isValid) {
-                fail(testcase.errorMessage());
-            }
-        }
-    }
-
-    static class InitialConfigurationTestCase {
-        String descr;
-        boolean isValid;
-        InitialConfiguration config;
-        public String errorMessage() {
-            return String.format("%s: expected configuration %s to be %s, but was %s",
-                    descr, config, validString(isValid), validString(!isValid));
-        }
-        static String validString(boolean isValid) {
-            return isValid ? VALID : INVALID;
-        }
-    }
-
-    static InitialConfigurationTestCase validConf(String descr, Set<LinkAddress> links,
-            Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        return confTestCase(descr, true, conf(links, prefixes, dns));
-    }
-
-    static InitialConfigurationTestCase invalidConf(String descr, Set<LinkAddress> links,
-            Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        return confTestCase(descr, false, conf(links, prefixes, dns));
-    }
-
-    static InitialConfigurationTestCase confTestCase(
-            String descr, boolean isValid, InitialConfiguration config) {
-        InitialConfigurationTestCase testcase = new InitialConfigurationTestCase();
-        testcase.descr = descr;
-        testcase.isValid = isValid;
-        testcase.config = config;
-        return testcase;
-    }
-
-    static LinkProperties linkproperties(Set<LinkAddress> addresses, Set<RouteInfo> routes) {
-        LinkProperties lp = new LinkProperties();
-        lp.setLinkAddresses(addresses);
-        for (RouteInfo route : routes) {
-            lp.addRoute(route);
-        }
-        return lp;
-    }
-
-    static InitialConfiguration conf(Set<LinkAddress> links, Set<IpPrefix> prefixes) {
-        return conf(links, prefixes, new HashSet<>());
-    }
-
-    static InitialConfiguration conf(
-            Set<LinkAddress> links, Set<IpPrefix> prefixes, Set<InetAddress> dns) {
-        InitialConfiguration conf = new InitialConfiguration();
-        conf.ipAddresses.addAll(links);
-        conf.directlyConnectedRoutes.addAll(prefixes);
-        conf.dnsServers.addAll(dns);
-        return conf;
-    }
-
-    static Set<RouteInfo> routes(String... routes) {
-        return mapIntoSet(routes, (r) -> new RouteInfo(new IpPrefix(r)));
-    }
-
-    static Set<IpPrefix> prefixes(String... prefixes) {
-        return mapIntoSet(prefixes, IpPrefix::new);
-    }
-
-    static Set<LinkAddress> links(String... addresses) {
-        return mapIntoSet(addresses, LinkAddress::new);
-    }
-
-    static Set<InetAddress> ips(String... addresses) {
-        return mapIntoSet(addresses, InetAddress::getByName);
-    }
-
-    static Set<InetAddress> dns(String... addresses) {
-        return ips(addresses);
-    }
-
-    static <A, B> Set<B> mapIntoSet(A[] in, Fn<A, B> fn) {
-        Set<B> out = new HashSet<>(in.length);
-        for (A item : in) {
-            try {
-                out.add(fn.call(item));
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-        }
-        return out;
-    }
-
-    interface Fn<A,B> {
-        B call(A a) throws Exception;
-    }
-
-    @Test
-    public void testAll() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("bar", "baz");
-        List<String> list4 = Arrays.asList("foo", "bar", "baz");
-
-        assertTrue(InitialConfiguration.all(list1, (x) -> false));
-        assertFalse(InitialConfiguration.all(list2, (x) -> false));
-        assertTrue(InitialConfiguration.all(list3, (x) -> true));
-        assertTrue(InitialConfiguration.all(list2, (x) -> x.charAt(0) == 'f'));
-        assertFalse(InitialConfiguration.all(list4, (x) -> x.charAt(0) == 'f'));
-    }
-
-    @Test
-    public void testAny() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("bar", "baz");
-        List<String> list4 = Arrays.asList("foo", "bar", "baz");
-
-        assertFalse(InitialConfiguration.any(list1, (x) -> true));
-        assertTrue(InitialConfiguration.any(list2, (x) -> true));
-        assertTrue(InitialConfiguration.any(list2, (x) -> x.charAt(0) == 'f'));
-        assertFalse(InitialConfiguration.any(list3, (x) -> x.charAt(0) == 'f'));
-        assertTrue(InitialConfiguration.any(list4, (x) -> x.charAt(0) == 'f'));
-    }
-
-    @Test
-    public void testFindAll() {
-        List<String> list1 = Arrays.asList();
-        List<String> list2 = Arrays.asList("foo");
-        List<String> list3 = Arrays.asList("foo", "bar", "baz");
-
-        assertEquals(list1, IpClient.findAll(list1, (x) -> true));
-        assertEquals(list1, IpClient.findAll(list3, (x) -> false));
-        assertEquals(list3, IpClient.findAll(list3, (x) -> true));
-        assertEquals(list2, IpClient.findAll(list3, (x) -> x.charAt(0) == 'f'));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java b/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java
deleted file mode 100644
index 64b168a..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ip;
-
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.util.InterfaceParams;
-import android.net.util.SharedLog;
-import android.os.Handler;
-import android.os.Looper;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for IpReachabilityMonitor.
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class IpReachabilityMonitorTest {
-
-    @Mock IpReachabilityMonitor.Callback mCallback;
-    @Mock IpReachabilityMonitor.Dependencies mDependencies;
-    @Mock SharedLog mLog;
-    @Mock Context mContext;
-    Handler mHandler;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        when(mLog.forSubComponent(anyString())).thenReturn(mLog);
-        mHandler = new Handler(Looper.getMainLooper());
-    }
-
-    IpReachabilityMonitor makeMonitor() {
-        final InterfaceParams ifParams = new InterfaceParams("fake0", 1, null);
-        return new IpReachabilityMonitor(
-                mContext, ifParams, mHandler, mLog, mCallback, false, mDependencies);
-    }
-
-    @Test
-    public void testNothing() {
-        IpReachabilityMonitor monitor = makeMonitor();
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java b/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java
deleted file mode 100644
index 71be8b3..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.MacAddress;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import libcore.util.HexEncoding;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for ConnectivityPacketSummary.
- *
- * @hide
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ConnectivityPacketSummaryTest {
-    private static final MacAddress MYHWADDR = MacAddress.fromString("80:7a:bf:6f:48:f3");
-
-    private String getSummary(String hexBytes) {
-        hexBytes = hexBytes.replaceAll("\\s+", "");
-        final byte[] bytes = HexEncoding.decode(hexBytes.toCharArray(), false);
-        return ConnectivityPacketSummary.summarize(MYHWADDR, bytes);
-    }
-
-    @Test
-    public void testParseICMPv6DADProbe() {
-        final String packet =
-                // Ethernet
-                "3333FF6F48F3 807ABF6F48F3 86DD" +
-                // IPv6
-                "600000000018 3A FF" +
-                "00000000000000000000000000000000" +
-                "FF0200000000000000000001FF6F48F3" +
-                // ICMPv6
-                "87 00 A8E7" +
-                "00000000" +
-                "FE80000000000000827ABFFFFE6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 33:33:ff:6f:48:f3 ipv6" +
-                " :: > ff02::1:ff6f:48f3 icmp6" +
-                " ns fe80::827a:bfff:fe6f:48f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6RS() {
-        final String packet =
-                // Ethernet
-                "333300000002 807ABF6F48F3 86DD" +
-                // IPv6
-                "600000000010 3A FF" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                "FF020000000000000000000000000002" +
-                // ICMPv6 RS
-                "85 00 6973" +
-                "00000000" +
-                "01 01 807ABF6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 33:33:00:00:00:02 ipv6" +
-                " fe80::827a:bfff:fe6f:48f3 > ff02::2 icmp6" +
-                " rs slla 80:7a:bf:6f:48:f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6RA() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 100E7E263FC1 86DD" +
-                // IPv6
-                "600000000068 3A FF" +
-                "FE80000000000000FA000004FD000001" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                // ICMPv6 RA
-                "86 00 8141" +
-                "40 00 0E10" +
-                "00000000" +
-                "00000000" +
-                "01 01 00005E000265" +
-                "05 01 0000000005DC" +
-                "19 05 000000000E10" +
-                "      20014860486000000000000000008844" +
-                "      20014860486000000000000000008888" +
-                "03 04 40 C0" +
-                "      00278D00" +
-                "      00093A80" +
-                "      00000000" +
-                "      2401FA000004FD000000000000000000";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > fe80::827a:bfff:fe6f:48f3 icmp6" +
-                " ra slla 00:00:5e:00:02:65 mtu 1500";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6NS() {
-        final String packet =
-                // Ethernet
-                  "807ABF6F48F3 100E7E263FC1 86DD" +
-                  // IPv6
-                  "6C0000000020 3A FF" +
-                  "FE80000000000000FA000004FD000001" +
-                  "FF0200000000000000000001FF01C146" +
-                  // ICMPv6 NS
-                  "87 00 8AD4" +
-                  "00000000" +
-                  "2401FA000004FD0015EA6A5C7B01C146" +
-                  "01 01 00005E000265";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > ff02::1:ff01:c146 icmp6" +
-                " ns 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 slla 00:00:5e:00:02:65";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testInvalidICMPv6NDLength() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 100E7E263FC1 86DD" +
-                // IPv6
-                "600000000068 3A FF" +
-                "FE80000000000000FA000004FD000001" +
-                "FE80000000000000827ABFFFFE6F48F3" +
-                // ICMPv6 RA
-                "86 00 8141" +
-                "40 00 0E10" +
-                "00000000" +
-                "00000000" +
-                "01 01 00005E000265" +
-                "00 00 0102030405D6";
-
-        final String expected =
-                "RX 10:0e:7e:26:3f:c1 > 80:7a:bf:6f:48:f3 ipv6" +
-                " fe80::fa00:4:fd00:1 > fe80::827a:bfff:fe6f:48f3 icmp6" +
-                " ra slla 00:00:5e:00:02:65 <malformed>";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseICMPv6NA() {
-        final String packet =
-                // Ethernet
-                "00005E000265 807ABF6F48F3 86DD" +
-                "600000000020 3A FF" +
-                "2401FA000004FD0015EA6A5C7B01C146" +
-                "FE80000000000000FA000004FD000001" +
-                "88 00 E8126" +
-                "0000000" +
-                "2401FA000004FD0015EA6A5C7B01C146" +
-                "02 01 807ABF6F48F3";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > 00:00:5e:00:02:65 ipv6" +
-                " 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 > fe80::fa00:4:fd00:1 icmp6" +
-                " na 2401:fa00:4:fd00:15ea:6a5c:7b01:c146 tlla 80:7a:bf:6f:48:f3";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseARPRequest() {
-        final String packet =
-                // Ethernet
-                  "FFFFFFFFFFFF 807ABF6F48F3 0806" +
-                  // ARP
-                  "0001 0800 06 04" +
-                  // Request
-                  "0001" +
-                  "807ABF6F48F3 64706ADB" +
-                  "000000000000 64706FFD";
-
-        final String expected =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff arp" +
-                " who-has 100.112.111.253";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseARPReply() {
-        final String packet =
-                // Ethernet
-                  "807ABF6F48F3 288A1CA8DFC1 0806" +
-                  // ARP
-                  "0001 0800 06 04" +
-                  // Reply
-                  "0002" +
-                  "288A1CA8DFC1 64706FFD"+
-                  "807ABF6F48F3 64706ADB" +
-                  // Ethernet padding to packet min size.
-                  "0000000000000000000000000000";
-
-        final String expected =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 arp" +
-                " reply 100.112.111.253 28:8a:1c:a8:df:c1";
-
-        assertEquals(expected, getSummary(packet));
-    }
-
-    @Test
-    public void testParseDHCPv4Discover() {
-        final String packet =
-                // Ethernet
-                "FFFFFFFFFFFF 807ABF6F48F3 0800" +
-                // IPv4
-                "451001580000400040113986" +
-                "00000000" +
-                "FFFFFFFF" +
-                // UDP
-                "0044 0043" +
-                "0144 5559" +
-                // DHCPv4
-                "01 01 06 00" +
-                "79F7ACA4" +
-                "0000 0000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 01" +
-                "3D 07 01807ABF6F48F3" +
-                "39 02 05DC" +
-                "3C 12 616E64726F69642D646863702D372E312E32" +
-                "0C 18 616E64726F69642D36623030366333313333393835343139" +
-                "37 0A 01 03 06 0F 1A 1C 33 3A 3B 2B" +
-                "FF" +
-                "00";
-
-        final String expectedPrefix =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff ipv4" +
-                " 0.0.0.0 > 255.255.255.255 udp" +
-                " 68 > 67 dhcp4" +
-                " 80:7a:bf:6f:48:f3 DISCOVER";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Offer() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 288A1CA8DFC1 0800" +
-                // IPv4
-                "4500013D4D2C0000401188CB" +
-                "64706FFD" +
-                "64706ADB" +
-                // UDP
-                "0043 0044" +
-                "0129 371D" +
-                // DHCPv4
-                "02 01 06 01" +
-                "79F7ACA4" +
-                "0000 0000" +
-                "00000000" +
-                "64706ADB" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 02" +
-                "36 04 AC188A0B" +
-                "33 04 00000708" +
-                "01 04 FFFFF000" +
-                "03 04 64706FFE" +
-                "06 08 08080808" +
-                "      08080404" +
-                "FF0001076165313A363636FF";
-
-        final String expectedPrefix =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 ipv4" +
-                " 100.112.111.253 > 100.112.106.219 udp" +
-                " 67 > 68 dhcp4" +
-                " 80:7a:bf:6f:48:f3 OFFER";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Request() {
-        final String packet =
-                // Ethernet
-                "FFFFFFFFFFFF 807ABF6F48F3 0800" +
-                // IPv4
-                "45100164000040004011397A" +
-                "00000000" +
-                "FFFFFFFF" +
-                // UDP
-                "0044 0043" +
-                "0150 E5C7" +
-                // DHCPv4
-                "01 01 06 00" +
-                "79F7ACA4" +
-                "0001 0000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 03" +
-                "3D 07 01807ABF6F48F3" +
-                "32 04 64706ADB" +
-                "36 04 AC188A0B" +
-                "39 02 05DC" +
-                "3C 12 616E64726F69642D646863702D372E312E32" +
-                "0C 18 616E64726F69642D36623030366333313333393835343139" +
-                "37 0A 01 03 06 0F 1A 1C 33 3A 3B 2B" +
-                "FF" +
-                "00";
-
-        final String expectedPrefix =
-                "TX 80:7a:bf:6f:48:f3 > ff:ff:ff:ff:ff:ff ipv4" +
-                " 0.0.0.0 > 255.255.255.255 udp" +
-                " 68 > 67 dhcp4" +
-                " 80:7a:bf:6f:48:f3 REQUEST";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-
-    @Test
-    public void testParseDHCPv4Ack() {
-        final String packet =
-                // Ethernet
-                "807ABF6F48F3 288A1CA8DFC1 0800" +
-                // IPv4
-                "4500013D4D3B0000401188BC" +
-                "64706FFD" +
-                "64706ADB" +
-                // UDP
-                "0043 0044" +
-                "0129 341C" +
-                // DHCPv4
-                "02 01 06 01" +
-                "79F7ACA4" +
-                "0001 0000" +
-                "00000000" +
-                "64706ADB" +
-                "00000000" +
-                "00000000" +
-                "807ABF6F48F300000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "0000000000000000000000000000000000000000000000000000000000000000" +
-                "63 82 53 63" +
-                "35 01 05" +
-                "36 04 AC188A0B" +
-                "33 04 00000708" +
-                "01 04 FFFFF000" +
-                "03 04 64706FFE" +
-                "06 08 08080808" +
-                "      08080404" +
-                "FF0001076165313A363636FF";
-
-        final String expectedPrefix =
-                "RX 28:8a:1c:a8:df:c1 > 80:7a:bf:6f:48:f3 ipv4" +
-                " 100.112.111.253 > 100.112.106.219 udp" +
-                " 67 > 68 dhcp4" +
-                " 80:7a:bf:6f:48:f3 ACK";
-
-        assertTrue(getSummary(packet).startsWith(expectedPrefix));
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java b/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java
deleted file mode 100644
index 289dcad..0000000
--- a/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.util;
-
-import static android.net.util.PacketReader.DEFAULT_RECV_BUF_SIZE;
-import static android.system.OsConstants.AF_INET6;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-import static android.system.OsConstants.SOCK_NONBLOCK;
-import static android.system.OsConstants.SOL_SOCKET;
-import static android.system.OsConstants.SO_SNDTIMEO;
-
-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 android.os.Handler;
-import android.os.HandlerThread;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructTimeval;
-
-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 java.io.FileDescriptor;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketException;
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests for PacketReader.
- *
- * @hide
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class PacketReaderTest {
-    static final InetAddress LOOPBACK6 = Inet6Address.getLoopbackAddress();
-    static final StructTimeval TIMEO = StructTimeval.fromMillis(500);
-
-    protected CountDownLatch mLatch;
-    protected FileDescriptor mLocalSocket;
-    protected InetSocketAddress mLocalSockName;
-    protected byte[] mLastRecvBuf;
-    protected boolean mStopped;
-    protected HandlerThread mHandlerThread;
-    protected PacketReader mReceiver;
-
-    class UdpLoopbackReader extends PacketReader {
-        public UdpLoopbackReader(Handler h) {
-            super(h);
-        }
-
-        @Override
-        protected FileDescriptor createFd() {
-            FileDescriptor s = null;
-            try {
-                s = Os.socket(AF_INET6, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
-                Os.bind(s, LOOPBACK6, 0);
-                mLocalSockName = (InetSocketAddress) Os.getsockname(s);
-                Os.setsockoptTimeval(s, SOL_SOCKET, SO_SNDTIMEO, TIMEO);
-            } catch (ErrnoException|SocketException e) {
-                closeFd(s);
-                fail();
-                return null;
-            }
-
-            mLocalSocket = s;
-            return s;
-        }
-
-        @Override
-        protected void handlePacket(byte[] recvbuf, int length) {
-            mLastRecvBuf = Arrays.copyOf(recvbuf, length);
-            mLatch.countDown();
-        }
-
-        @Override
-        protected void onStart() {
-            mStopped = false;
-            mLatch.countDown();
-        }
-
-        @Override
-        protected void onStop() {
-            mStopped = true;
-            mLatch.countDown();
-        }
-    };
-
-    @Before
-    public void setUp() {
-        resetLatch();
-        mLocalSocket = null;
-        mLocalSockName = null;
-        mLastRecvBuf = null;
-        mStopped = false;
-
-        mHandlerThread = new HandlerThread(PacketReaderTest.class.getSimpleName());
-        mHandlerThread.start();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mReceiver != null) {
-            mHandlerThread.getThreadHandler().post(() -> { mReceiver.stop(); });
-            waitForActivity();
-        }
-        mReceiver = null;
-        mHandlerThread.quit();
-        mHandlerThread = null;
-    }
-
-    void resetLatch() { mLatch = new CountDownLatch(1); }
-
-    void waitForActivity() throws Exception {
-        try {
-            mLatch.await(1000, TimeUnit.MILLISECONDS);
-        } finally {
-            resetLatch();
-        }
-    }
-
-    void sendPacket(byte[] contents) throws Exception {
-        final DatagramSocket sender = new DatagramSocket();
-        sender.connect(mLocalSockName);
-        sender.send(new DatagramPacket(contents, contents.length));
-        sender.close();
-    }
-
-    @Test
-    public void testBasicWorking() throws Exception {
-        final Handler h = mHandlerThread.getThreadHandler();
-        mReceiver = new UdpLoopbackReader(h);
-
-        h.post(() -> { mReceiver.start(); });
-        waitForActivity();
-        assertTrue(mLocalSockName != null);
-        assertEquals(LOOPBACK6, mLocalSockName.getAddress());
-        assertTrue(0 < mLocalSockName.getPort());
-        assertTrue(mLocalSocket != null);
-        assertFalse(mStopped);
-
-        final byte[] one = "one 1".getBytes("UTF-8");
-        sendPacket(one);
-        waitForActivity();
-        assertEquals(1, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(one, mLastRecvBuf));
-        assertFalse(mStopped);
-
-        final byte[] two = "two 2".getBytes("UTF-8");
-        sendPacket(two);
-        waitForActivity();
-        assertEquals(2, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(two, mLastRecvBuf));
-        assertFalse(mStopped);
-
-        mReceiver.stop();
-        waitForActivity();
-        assertEquals(2, mReceiver.numPacketsReceived());
-        assertTrue(Arrays.equals(two, mLastRecvBuf));
-        assertTrue(mStopped);
-        mReceiver = null;
-    }
-
-    class NullPacketReader extends PacketReader {
-        public NullPacketReader(Handler h, int recvbufsize) {
-            super(h, recvbufsize);
-        }
-
-        @Override
-        public FileDescriptor createFd() { return null; }
-    }
-
-    @Test
-    public void testMinimalRecvBufSize() throws Exception {
-        final Handler h = mHandlerThread.getThreadHandler();
-
-        for (int i : new int[]{-1, 0, 1, DEFAULT_RECV_BUF_SIZE-1}) {
-            final PacketReader b = new NullPacketReader(h, i);
-            assertEquals(DEFAULT_RECV_BUF_SIZE, b.recvBufSize());
-        }
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
deleted file mode 100644
index e4c1d17..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ /dev/null
@@ -1,1154 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.connectivity;
-
-import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
-import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_EVALUATION_TYPE;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL;
-import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD;
-import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS;
-import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-
-import static org.junit.Assert.assertArrayEquals;
-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.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.DnsResolver;
-import android.net.INetworkMonitorCallbacks;
-import android.net.InetAddresses;
-import android.net.LinkProperties;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.captiveportal.CaptivePortalProbeResult;
-import android.net.metrics.IpConnectivityLog;
-import android.net.shared.PrivateDnsConfig;
-import android.net.util.SharedLog;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.telephony.CellSignalStrength;
-import android.telephony.TelephonyManager;
-import android.util.ArrayMap;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.networkstack.R;
-import com.android.networkstack.metrics.DataStallDetectionStats;
-import com.android.networkstack.metrics.DataStallStatsUtils;
-import com.android.testutils.HandlerUtilsKt;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-import org.mockito.verification.VerificationWithTimeout;
-
-import java.io.IOException;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.Executor;
-
-import javax.net.ssl.SSLHandshakeException;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class NetworkMonitorTest {
-    private static final String LOCATION_HEADER = "location";
-
-    private @Mock Context mContext;
-    private @Mock Resources mResources;
-    private @Mock IpConnectivityLog mLogger;
-    private @Mock SharedLog mValidationLogger;
-    private @Mock NetworkInfo mNetworkInfo;
-    private @Mock DnsResolver mDnsResolver;
-    private @Mock ConnectivityManager mCm;
-    private @Mock TelephonyManager mTelephony;
-    private @Mock WifiManager mWifi;
-    private @Mock HttpURLConnection mHttpConnection;
-    private @Mock HttpURLConnection mHttpsConnection;
-    private @Mock HttpURLConnection mFallbackConnection;
-    private @Mock HttpURLConnection mOtherFallbackConnection;
-    private @Mock Random mRandom;
-    private @Mock NetworkMonitor.Dependencies mDependencies;
-    private @Mock INetworkMonitorCallbacks mCallbacks;
-    private @Spy Network mCleartextDnsNetwork = new Network(TEST_NETID);
-    private @Mock Network mNetwork;
-    private @Mock DataStallStatsUtils mDataStallStatsUtils;
-    private @Mock WifiInfo mWifiInfo;
-    private @Captor ArgumentCaptor<String> mNetworkTestedRedirectUrlCaptor;
-
-    private HashSet<WrappedNetworkMonitor> mCreatedNetworkMonitors;
-    private HashSet<BroadcastReceiver> mRegisteredReceivers;
-
-    private static final int TEST_NETID = 4242;
-    private static final String TEST_HTTP_URL = "http://www.google.com/gen_204";
-    private static final String TEST_HTTPS_URL = "https://www.google.com/gen_204";
-    private static final String TEST_FALLBACK_URL = "http://fallback.google.com/gen_204";
-    private static final String TEST_OTHER_FALLBACK_URL = "http://otherfallback.google.com/gen_204";
-    private static final String TEST_MCCMNC = "123456";
-
-    private static final int VALIDATION_RESULT_INVALID = 0;
-    private static final int VALIDATION_RESULT_PORTAL = 0;
-    private static final String TEST_REDIRECT_URL = "android.com";
-    private static final int VALIDATION_RESULT_PARTIAL = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_HTTP
-            | NETWORK_VALIDATION_RESULT_PARTIAL;
-    private static final int VALIDATION_RESULT_FALLBACK_PARTIAL = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_FALLBACK
-            | NETWORK_VALIDATION_RESULT_PARTIAL;
-    private static final int VALIDATION_RESULT_VALID = NETWORK_VALIDATION_PROBE_DNS
-            | NETWORK_VALIDATION_PROBE_HTTPS
-            | NETWORK_VALIDATION_RESULT_VALID;
-
-    private static final int RETURN_CODE_DNS_SUCCESS = 0;
-    private static final int RETURN_CODE_DNS_TIMEOUT = 255;
-    private static final int DEFAULT_DNS_TIMEOUT_THRESHOLD = 5;
-
-    private static final int HANDLER_TIMEOUT_MS = 1000;
-
-    private static final LinkProperties TEST_LINK_PROPERTIES = new LinkProperties();
-
-    private static final NetworkCapabilities METERED_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-            .addCapability(NET_CAPABILITY_INTERNET);
-
-    private static final NetworkCapabilities NOT_METERED_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-            .addCapability(NET_CAPABILITY_INTERNET)
-            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-
-    private static final NetworkCapabilities NO_INTERNET_CAPABILITIES = new NetworkCapabilities()
-            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-
-    /**
-     * Fakes DNS responses.
-     *
-     * Allows test methods to configure the IP addresses that will be resolved by
-     * Network#getAllByName and by DnsResolver#query.
-     */
-    class FakeDns {
-        private final ArrayMap<String, List<InetAddress>> mAnswers = new ArrayMap<>();
-        private boolean mNonBypassPrivateDnsWorking = true;
-
-        /** Whether DNS queries on mNonBypassPrivateDnsWorking should succeed. */
-        private void setNonBypassPrivateDnsWorking(boolean working) {
-            mNonBypassPrivateDnsWorking = working;
-        }
-
-        /** Clears all DNS entries. */
-        private synchronized void clearAll() {
-            mAnswers.clear();
-        }
-
-        /** Returns the answer for a given name on the given mock network. */
-        private synchronized List<InetAddress> getAnswer(Object mock, String hostname) {
-            if (mock == mNetwork && !mNonBypassPrivateDnsWorking) {
-                return null;
-            }
-            if (mAnswers.containsKey(hostname)) {
-                return mAnswers.get(hostname);
-            }
-            return mAnswers.get("*");
-        }
-
-        /** Sets the answer for a given name. */
-        private synchronized void setAnswer(String hostname, String[] answer)
-                throws UnknownHostException {
-            if (answer == null) {
-                mAnswers.remove(hostname);
-            } else {
-                List<InetAddress> answerList = new ArrayList<>();
-                for (String addr : answer) {
-                    answerList.add(InetAddresses.parseNumericAddress(addr));
-                }
-                mAnswers.put(hostname, answerList);
-            }
-        }
-
-        /** Simulates a getAllByName call for the specified name on the specified mock network. */
-        private InetAddress[] getAllByName(Object mock, String hostname)
-                throws UnknownHostException {
-            List<InetAddress> answer = getAnswer(mock, hostname);
-            if (answer == null || answer.size() == 0) {
-                throw new UnknownHostException(hostname);
-            }
-            return answer.toArray(new InetAddress[0]);
-        }
-
-        /** Starts mocking DNS queries. */
-        private void startMocking() throws UnknownHostException {
-            // Queries on mNetwork using getAllByName.
-            doAnswer(invocation -> {
-                return getAllByName(invocation.getMock(), invocation.getArgument(0));
-            }).when(mNetwork).getAllByName(any());
-
-            // Queries on mCleartextDnsNetwork using DnsResolver#query.
-            doAnswer(invocation -> {
-                String hostname = (String) invocation.getArgument(1);
-                Executor executor = (Executor) invocation.getArgument(3);
-                DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(5);
-
-                List<InetAddress> answer = getAnswer(invocation.getMock(), hostname);
-                if (answer != null && answer.size() > 0) {
-                    new Handler(Looper.getMainLooper()).post(() -> {
-                        executor.execute(() -> callback.onAnswer(answer, 0));
-                    });
-                }
-                // If no answers, do nothing. sendDnsProbeWithTimeout will time out and throw UHE.
-                return null;
-            }).when(mDnsResolver).query(any(), any(), anyInt(), any(), any(), any());
-
-            // Queries on mCleartextDnsNetwork using using DnsResolver#query with QueryType.
-            doAnswer(invocation -> {
-                String hostname = (String) invocation.getArgument(1);
-                Executor executor = (Executor) invocation.getArgument(4);
-                DnsResolver.Callback<List<InetAddress>> callback = invocation.getArgument(6);
-
-                List<InetAddress> answer = getAnswer(invocation.getMock(), hostname);
-                if (answer != null && answer.size() > 0) {
-                    new Handler(Looper.getMainLooper()).post(() -> {
-                        executor.execute(() -> callback.onAnswer(answer, 0));
-                    });
-                }
-                // If no answers, do nothing. sendDnsProbeWithTimeout will time out and throw UHE.
-                return null;
-            }).when(mDnsResolver).query(any(), any(), anyInt(), anyInt(), any(), any(), any());
-        }
-    }
-
-    private FakeDns mFakeDns;
-
-    @Before
-    public void setUp() throws IOException {
-        MockitoAnnotations.initMocks(this);
-        when(mDependencies.getPrivateDnsBypassNetwork(any())).thenReturn(mCleartextDnsNetwork);
-        when(mDependencies.getDnsResolver()).thenReturn(mDnsResolver);
-        when(mDependencies.getRandom()).thenReturn(mRandom);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt()))
-                .thenReturn(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
-        when(mDependencies.getDeviceConfigPropertyInt(any(), eq(CAPTIVE_PORTAL_USE_HTTPS),
-                anyInt())).thenReturn(1);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_HTTP_URL), any()))
-                .thenReturn(TEST_HTTP_URL);
-        when(mDependencies.getSetting(any(), eq(Settings.Global.CAPTIVE_PORTAL_HTTPS_URL), any()))
-                .thenReturn(TEST_HTTPS_URL);
-
-        doReturn(mCleartextDnsNetwork).when(mNetwork).getPrivateDnsBypassingCopy();
-
-        when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mCm);
-        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephony);
-        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifi);
-        when(mContext.getResources()).thenReturn(mResources);
-
-        when(mResources.getString(anyInt())).thenReturn("");
-        when(mResources.getStringArray(anyInt())).thenReturn(new String[0]);
-
-        when(mNetworkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI);
-        setFallbackUrl(TEST_FALLBACK_URL);
-        setOtherFallbackUrls(TEST_OTHER_FALLBACK_URL);
-        setFallbackSpecs(null); // Test with no fallback spec by default
-        when(mRandom.nextInt()).thenReturn(0);
-
-        // DNS probe timeout should not be defined more than half of HANDLER_TIMEOUT_MS. Otherwise,
-        // it will fail the test because of timeout expired for querying AAAA and A sequentially.
-        when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
-                .thenReturn(200);
-
-        doAnswer((invocation) -> {
-            URL url = invocation.getArgument(0);
-            switch(url.toString()) {
-                case TEST_HTTP_URL:
-                    return mHttpConnection;
-                case TEST_HTTPS_URL:
-                    return mHttpsConnection;
-                case TEST_FALLBACK_URL:
-                    return mFallbackConnection;
-                case TEST_OTHER_FALLBACK_URL:
-                    return mOtherFallbackConnection;
-                default:
-                    fail("URL not mocked: " + url.toString());
-                    return null;
-            }
-        }).when(mCleartextDnsNetwork).openConnection(any());
-        when(mHttpConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
-        when(mHttpsConnection.getRequestProperties()).thenReturn(new ArrayMap<>());
-
-        mFakeDns = new FakeDns();
-        mFakeDns.startMocking();
-        mFakeDns.setAnswer("*", new String[]{"2001:db8::1", "192.0.2.2"});
-
-        when(mContext.registerReceiver(any(BroadcastReceiver.class), any())).then((invocation) -> {
-            mRegisteredReceivers.add(invocation.getArgument(0));
-            return new Intent();
-        });
-
-        doAnswer((invocation) -> {
-            mRegisteredReceivers.remove(invocation.getArgument(0));
-            return null;
-        }).when(mContext).unregisterReceiver(any());
-
-        setMinDataStallEvaluateInterval(500);
-        setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
-        setValidDataStallDnsTimeThreshold(500);
-        setConsecutiveDnsTimeoutThreshold(5);
-
-        mCreatedNetworkMonitors = new HashSet<>();
-        mRegisteredReceivers = new HashSet<>();
-    }
-
-    @After
-    public void tearDown() {
-        mFakeDns.clearAll();
-        assertTrue(mCreatedNetworkMonitors.size() > 0);
-        // Make a local copy of mCreatedNetworkMonitors because during the iteration below,
-        // WrappedNetworkMonitor#onQuitting will delete elements from it on the handler threads.
-        WrappedNetworkMonitor[] networkMonitors = mCreatedNetworkMonitors.toArray(
-                new WrappedNetworkMonitor[0]);
-        for (WrappedNetworkMonitor nm : networkMonitors) {
-            nm.notifyNetworkDisconnected();
-            nm.awaitQuit();
-        }
-        assertEquals("NetworkMonitor still running after disconnect",
-                0, mCreatedNetworkMonitors.size());
-        assertEquals("BroadcastReceiver still registered after disconnect",
-                0, mRegisteredReceivers.size());
-    }
-
-    private class WrappedNetworkMonitor extends NetworkMonitor {
-        private long mProbeTime = 0;
-        private final ConditionVariable mQuitCv = new ConditionVariable(false);
-
-        WrappedNetworkMonitor() {
-            super(mContext, mCallbacks, mNetwork, mLogger, mValidationLogger,
-                    mDependencies, mDataStallStatsUtils);
-        }
-
-        @Override
-        protected long getLastProbeTime() {
-            return mProbeTime;
-        }
-
-        protected void setLastProbeTime(long time) {
-            mProbeTime = time;
-        }
-
-        @Override
-        protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) {
-            generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        }
-
-        @Override
-        protected void onQuitting() {
-            assertTrue(mCreatedNetworkMonitors.remove(this));
-            mQuitCv.open();
-        }
-
-        protected void awaitQuit() {
-            assertTrue("NetworkMonitor did not quit after " + HANDLER_TIMEOUT_MS + "ms",
-                    mQuitCv.block(HANDLER_TIMEOUT_MS));
-        }
-    }
-
-    private WrappedNetworkMonitor makeMonitor(NetworkCapabilities nc) {
-        final WrappedNetworkMonitor nm = new WrappedNetworkMonitor();
-        nm.start();
-        setNetworkCapabilities(nm, nc);
-        HandlerUtilsKt.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS);
-        mCreatedNetworkMonitors.add(nm);
-        return nm;
-    }
-
-    private WrappedNetworkMonitor makeMeteredNetworkMonitor() {
-        final WrappedNetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
-        return nm;
-    }
-
-    private WrappedNetworkMonitor makeNotMeteredNetworkMonitor() {
-        final WrappedNetworkMonitor nm = makeMonitor(NOT_METERED_CAPABILITIES);
-        return nm;
-    }
-
-    private void setNetworkCapabilities(NetworkMonitor nm, NetworkCapabilities nc) {
-        nm.notifyNetworkCapabilitiesChanged(nc);
-        HandlerUtilsKt.waitForIdle(nm.getHandler(), HANDLER_TIMEOUT_MS);
-    }
-
-    @Test
-    public void testGetIntSetting() throws Exception {
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-
-        // No config resource, no device config. Expect to get default resource.
-        doThrow(new Resources.NotFoundException())
-                .when(mResources).getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout));
-        doAnswer(invocation -> {
-            int defaultValue = invocation.getArgument(2);
-            return defaultValue;
-        }).when(mDependencies).getDeviceConfigPropertyInt(any(),
-                eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT),
-                anyInt());
-        when(mResources.getInteger(eq(R.integer.default_captive_portal_dns_probe_timeout)))
-                .thenReturn(42);
-        assertEquals(42, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-
-        // Set device config. Expect to get device config.
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-                eq(NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT), anyInt()))
-                        .thenReturn(1234);
-        assertEquals(1234, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-
-        // Set config resource. Expect to get config resource.
-        when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
-                .thenReturn(5678);
-        assertEquals(5678, wnm.getIntSetting(mContext,
-                R.integer.config_captive_portal_dns_probe_timeout,
-                NetworkMonitor.CONFIG_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT,
-                R.integer.default_captive_portal_dns_probe_timeout));
-    }
-
-    @Test
-    public void testIsCaptivePortal_HttpProbeIsPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_PORTAL);
-    }
-
-    @Test
-    public void testIsCaptivePortal_HttpsProbeIsNotPortal() throws IOException {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 500);
-
-        runNotPortalNetworkTest();
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackProbeIsPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setPortal302(mFallbackConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackProbeIsNotPortal() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 500);
-
-        // Fallback probe did not see portal, HTTPS failed -> inconclusive
-        runFailedNetworkTest();
-    }
-
-    @Test
-    public void testIsCaptivePortal_OtherFallbackProbeIsPortal() throws IOException {
-        // Set all fallback probes but one to invalid URLs to verify they are being skipped
-        setFallbackUrl(TEST_FALLBACK_URL);
-        setOtherFallbackUrls(TEST_FALLBACK_URL + "," + TEST_OTHER_FALLBACK_URL);
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 500);
-        setPortal302(mOtherFallbackConnection);
-
-        // TEST_OTHER_FALLBACK_URL is third
-        when(mRandom.nextInt()).thenReturn(2);
-
-        // First check always uses the first fallback URL: inconclusive
-        final NetworkMonitor monitor = runNetworkTest(VALIDATION_RESULT_INVALID);
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-        verify(mFallbackConnection, times(1)).getResponseCode();
-        verify(mOtherFallbackConnection, never()).getResponseCode();
-
-        // Second check uses the URL chosen by Random
-        final CaptivePortalProbeResult result = monitor.isCaptivePortal();
-        assertTrue(result.isPortal());
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_AllProbesFailed() throws IOException {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 404);
-
-        runFailedNetworkTest();
-        verify(mFallbackConnection, times(1)).getResponseCode();
-        verify(mOtherFallbackConnection, never()).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_InvalidUrlSkipped() throws IOException {
-        setFallbackUrl("invalid");
-        setOtherFallbackUrls("otherinvalid," + TEST_OTHER_FALLBACK_URL + ",yetanotherinvalid");
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setPortal302(mOtherFallbackConnection);
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-        verify(mFallbackConnection, never()).getResponseCode();
-    }
-
-    private void setupFallbackSpec() throws IOException {
-        setFallbackSpecs("http://example.com@@/@@204@@/@@"
-                + "@@,@@"
-                + TEST_OTHER_FALLBACK_URL + "@@/@@30[12]@@/@@https://(www\\.)?google.com/?.*");
-
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-
-        // Use the 2nd fallback spec
-        when(mRandom.nextInt()).thenReturn(1);
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackSpecIsPartial() throws IOException {
-        setupFallbackSpec();
-        set302(mOtherFallbackConnection, "https://www.google.com/test?q=3");
-
-        // HTTPS failed, fallback spec went through -> partial connectivity
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_FALLBACK_PARTIAL);
-        verify(mOtherFallbackConnection, times(1)).getResponseCode();
-        verify(mFallbackConnection, never()).getResponseCode();
-    }
-
-    @Test
-    public void testIsCaptivePortal_FallbackSpecIsPortal() throws IOException {
-        setupFallbackSpec();
-        set302(mOtherFallbackConnection, "http://login.portal.example.com");
-        runPortalNetworkTest(VALIDATION_RESULT_INVALID);
-    }
-
-    @Test
-    public void testIsCaptivePortal_IgnorePortals() throws IOException {
-        setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-
-        runNoValidationNetworkTest();
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDisabled() {
-        setDataStallEvaluationType(0);
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        assertFalse(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsOnNotMeteredNetwork() {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsOnMeteredNetwork() {
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsWithDnsTimeoutCount() {
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertFalse(wrappedMonitor.isDataStall());
-        // Reset consecutive timeout counts.
-        makeDnsSuccessEvent(wrappedMonitor, 1);
-        makeDnsTimeoutEvent(wrappedMonitor, 2);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertTrue(wrappedMonitor.isDataStall());
-
-        // Set the value to larger than the default dns log size.
-        setConsecutiveDnsTimeoutThreshold(51);
-        wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 50);
-        assertFalse(wrappedMonitor.isDataStall());
-
-        makeDnsTimeoutEvent(wrappedMonitor, 1);
-        assertTrue(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testIsDataStall_EvaluationDnsWithDnsTimeThreshold() {
-        // Test dns events happened in valid dns time threshold.
-        WrappedNetworkMonitor wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertFalse(wrappedMonitor.isDataStall());
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        assertTrue(wrappedMonitor.isDataStall());
-
-        // Test dns events happened before valid dns time threshold.
-        setValidDataStallDnsTimeThreshold(0);
-        wrappedMonitor = makeMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100);
-        makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-        assertFalse(wrappedMonitor.isDataStall());
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        assertFalse(wrappedMonitor.isDataStall());
-    }
-
-    @Test
-    public void testBrokenNetworkNotValidated() throws Exception {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 404);
-
-        runFailedNetworkTest();
-    }
-
-    @Test
-    public void testNoInternetCapabilityValidated() throws Exception {
-        runNetworkTest(NO_INTERNET_CAPABILITIES, NETWORK_VALIDATION_RESULT_VALID,
-                getGeneralVerification());
-        verify(mCleartextDnsNetwork, never()).openConnection(any());
-    }
-
-    @Test
-    public void testLaunchCaptivePortalApp() throws Exception {
-        setSslException(mHttpsConnection);
-        setPortal302(mHttpConnection);
-
-        final NetworkMonitor nm = makeMonitor(METERED_CAPABILITIES);
-        nm.notifyNetworkConnected(TEST_LINK_PROPERTIES, METERED_CAPABILITIES);
-
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .showProvisioningNotification(any(), any());
-
-        assertEquals(1, mRegisteredReceivers.size());
-
-        // Check that startCaptivePortalApp sends the expected intent.
-        nm.launchCaptivePortalApp();
-
-        final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
-        final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class);
-        verify(mCm, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .startCaptivePortalApp(networkCaptor.capture(), bundleCaptor.capture());
-        final Bundle bundle = bundleCaptor.getValue();
-        final Network bundleNetwork = bundle.getParcelable(ConnectivityManager.EXTRA_NETWORK);
-        assertEquals(TEST_NETID, bundleNetwork.netId);
-        // network is passed both in bundle and as parameter, as the bundle is opaque to the
-        // framework and only intended for the captive portal app, but the framework needs
-        // the network to identify the right NetworkMonitor.
-        assertEquals(TEST_NETID, networkCaptor.getValue().netId);
-
-        // Have the app report that the captive portal is dismissed, and check that we revalidate.
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-
-        reset(mCallbacks);
-        nm.notifyCaptivePortalAppFinished(APP_RETURN_DISMISSED);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP
-                        | NETWORK_VALIDATION_RESULT_VALID), any());
-        assertEquals(0, mRegisteredReceivers.size());
-    }
-
-    @Test
-    public void testPrivateDnsSuccess() throws Exception {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-        mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::53"});
-
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
-                        eq(null));
-    }
-
-    @Test
-    public void testPrivateDnsResolutionRetryUpdate() throws Exception {
-        // Set a private DNS hostname that doesn't resolve and expect validation to fail.
-        mFakeDns.setAnswer("dns.google", new String[0]);
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
-        wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                        eq(null));
-
-        // Fix DNS and retry, expect validation to succeed.
-        reset(mCallbacks);
-        mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"});
-
-        wnm.forceReevaluation(Process.myUid());
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
-                        eq(null));
-
-        // Change configuration to an invalid DNS name, expect validation to fail.
-        reset(mCallbacks);
-        mFakeDns.setAnswer("dns.bad", new String[0]);
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.bad", new InetAddress[0]));
-        // Strict mode hostname resolve fail. Expect only notification for evaluation fail. No probe
-        // notification.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
-                .notifyNetworkTested(eq(VALIDATION_RESULT_VALID), eq(null));
-
-        // Change configuration back to working again, but make private DNS not work.
-        // Expect validation to fail.
-        reset(mCallbacks);
-        mFakeDns.setNonBypassPrivateDnsWorking(false);
-        wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google",
-                new InetAddress[0]));
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                        eq(null));
-
-        // Make private DNS work again. Expect validation to succeed.
-        reset(mCallbacks);
-        mFakeDns.setNonBypassPrivateDnsWorking(true);
-        wnm.forceReevaluation(Process.myUid());
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
-                .notifyNetworkTested(
-                        eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null));
-    }
-
-    @Test
-    public void testDataStall_StallSuspectedAndSendMetrics() throws IOException {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 5);
-        assertTrue(wrappedMonitor.isDataStall());
-        verify(mDataStallStatsUtils, times(1)).write(makeEmptyDataStallDetectionStats(), any());
-    }
-
-    @Test
-    public void testDataStall_NoStallSuspectedAndSendMetrics() throws IOException {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-        wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000);
-        makeDnsTimeoutEvent(wrappedMonitor, 3);
-        assertFalse(wrappedMonitor.isDataStall());
-        verify(mDataStallStatsUtils, never()).write(makeEmptyDataStallDetectionStats(), any());
-    }
-
-    @Test
-    public void testCollectDataStallMetrics() {
-        WrappedNetworkMonitor wrappedMonitor = makeNotMeteredNetworkMonitor();
-
-        when(mTelephony.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE);
-        when(mTelephony.getNetworkOperator()).thenReturn(TEST_MCCMNC);
-        when(mTelephony.getSimOperator()).thenReturn(TEST_MCCMNC);
-
-        DataStallDetectionStats.Builder stats =
-                new DataStallDetectionStats.Builder()
-                .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS)
-                .setNetworkType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                .setCellData(TelephonyManager.NETWORK_TYPE_LTE /* radioType */,
-                        true /* roaming */,
-                        TEST_MCCMNC /* networkMccmnc */,
-                        TEST_MCCMNC /* simMccmnc */,
-                        CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN /* signalStrength */);
-        generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-
-        assertEquals(wrappedMonitor.buildDataStallDetectionStats(
-                 NetworkCapabilities.TRANSPORT_CELLULAR), stats.build());
-
-        when(mWifi.getConnectionInfo()).thenReturn(mWifiInfo);
-
-        stats = new DataStallDetectionStats.Builder()
-                .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS)
-                .setNetworkType(NetworkCapabilities.TRANSPORT_WIFI)
-                .setWiFiData(mWifiInfo);
-        generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD);
-
-        assertEquals(
-                wrappedMonitor.buildDataStallDetectionStats(NetworkCapabilities.TRANSPORT_WIFI),
-                stats.build());
-    }
-
-    @Test
-    public void testIgnoreHttpsProbe() throws Exception {
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 204);
-        // Expect to send HTTP, HTTPS, FALLBACK probe and evaluation result notifications to CS.
-        final NetworkMonitor nm = runNetworkTest(VALIDATION_RESULT_PARTIAL);
-
-        reset(mCallbacks);
-        nm.setAcceptPartialConnectivity();
-        // Expect to update evaluation result notifications to CS.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_PARTIAL | NETWORK_VALIDATION_RESULT_VALID), eq(null));
-    }
-
-    @Test
-    public void testIsPartialConnectivity() throws IOException {
-        setStatus(mHttpsConnection, 500);
-        setStatus(mHttpConnection, 204);
-        setStatus(mFallbackConnection, 500);
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_PARTIAL);
-
-        reset(mCallbacks);
-        setStatus(mHttpsConnection, 500);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 204);
-        runPartialConnectivityNetworkTest(VALIDATION_RESULT_FALLBACK_PARTIAL);
-    }
-
-    private void assertIpAddressArrayEquals(String[] expected, InetAddress[] actual) {
-        String[] actualStrings = new String[actual.length];
-        for (int i = 0; i < actual.length; i++) {
-            actualStrings[i] = actual[i].getHostAddress();
-        }
-        assertArrayEquals("Array of IP addresses differs", expected, actualStrings);
-    }
-
-    @Test
-    public void testSendDnsProbeWithTimeout() throws Exception {
-        WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
-        final int shortTimeoutMs = 200;
-
-        // Clear the wildcard DNS response created in setUp.
-        mFakeDns.setAnswer("*", null);
-
-        String[] expected = new String[]{"2001:db8::"};
-        mFakeDns.setAnswer("www.google.com", expected);
-        InetAddress[] actual = wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-        assertIpAddressArrayEquals(expected, actual);
-
-        expected = new String[]{"2001:db8::", "192.0.2.1"};
-        mFakeDns.setAnswer("www.googleapis.com", expected);
-        actual = wnm.sendDnsProbeWithTimeout("www.googleapis.com", shortTimeoutMs);
-        assertIpAddressArrayEquals(expected, actual);
-
-        mFakeDns.setAnswer("www.google.com", new String[0]);
-        try {
-            wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-            fail("No DNS results, expected UnknownHostException");
-        } catch (UnknownHostException e) {
-        }
-
-        mFakeDns.setAnswer("www.google.com", null);
-        try {
-            wnm.sendDnsProbeWithTimeout("www.google.com", shortTimeoutMs);
-            fail("DNS query timed out, expected UnknownHostException");
-        } catch (UnknownHostException e) {
-        }
-    }
-
-    @Test
-    public void testNotifyNetwork_WithforceReevaluation() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-        // Verify forceReevalution will not reset the validation result but only probe result until
-        // getting the validation result.
-        reset(mCallbacks);
-        setSslException(mHttpsConnection);
-        setStatus(mHttpConnection, 500);
-        setStatus(mFallbackConnection, 204);
-        nm.forceReevaluation(Process.myUid());
-        final ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class);
-        // Expect to send HTTP, HTTPs, FALLBACK and evaluation results.
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(4))
-            .notifyNetworkTested(intCaptor.capture(), any());
-        List<Integer> intArgs = intCaptor.getAllValues();
-
-        // None of these exact values can be known in advance except for intArgs.get(0) because the
-        // HTTP and HTTPS probes race and the order in which they complete is non-deterministic.
-        // Thus, check only exact value for intArgs.get(0) and only check the validation result for
-        // the rest ones.
-        assertEquals(Integer.valueOf(NETWORK_VALIDATION_PROBE_DNS
-                | NETWORK_VALIDATION_PROBE_FALLBACK | NETWORK_VALIDATION_RESULT_VALID),
-                intArgs.get(0));
-        assertTrue((intArgs.get(1) & NETWORK_VALIDATION_RESULT_VALID) != 0);
-        assertTrue((intArgs.get(2) & NETWORK_VALIDATION_RESULT_VALID) != 0);
-        assertTrue((intArgs.get(3) & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
-        assertTrue((intArgs.get(3) & NETWORK_VALIDATION_RESULT_VALID) == 0);
-    }
-
-    @Test
-    public void testEvaluationState_clearProbeResults() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-        nm.getEvaluationState().clearProbeResults();
-        // Verify probe results are all reset and only evaluation result left.
-        assertEquals(NETWORK_VALIDATION_RESULT_VALID,
-                nm.getEvaluationState().getNetworkTestResult());
-    }
-
-    @Test
-    public void testEvaluationState_reportProbeResult() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-
-        reset(mCallbacks);
-
-        nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.SUCCESS);
-        // Verify result should be appended and notifyNetworkTested callback is triggered once.
-        assertEquals(nm.getEvaluationState().getNetworkTestResult(),
-                VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP), any());
-
-        nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.FAILED);
-        // Verify DNS probe result should not be cleared.
-        assertTrue((nm.getEvaluationState().getNetworkTestResult() & NETWORK_VALIDATION_PROBE_DNS)
-                == NETWORK_VALIDATION_PROBE_DNS);
-    }
-
-    @Test
-    public void testEvaluationState_reportEvaluationResult() throws Exception {
-        final NetworkMonitor nm = runValidatedNetworkTest();
-
-        nm.getEvaluationState().reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
-                null /* redirectUrl */);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS
-                | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
-
-        nm.getEvaluationState().reportEvaluationResult(
-                NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL,
-                null /* redirectUrl */);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
-
-        nm.getEvaluationState().reportEvaluationResult(VALIDATION_RESULT_INVALID,
-                TEST_REDIRECT_URL);
-        verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
-                eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
-                eq(TEST_REDIRECT_URL));
-    }
-
-    private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
-        for (int i = 0; i < count; i++) {
-            wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
-                    RETURN_CODE_DNS_TIMEOUT);
-        }
-    }
-
-    private void makeDnsSuccessEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
-        for (int i = 0; i < count; i++) {
-            wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
-                    RETURN_CODE_DNS_SUCCESS);
-        }
-    }
-
-    private DataStallDetectionStats makeEmptyDataStallDetectionStats() {
-        return new DataStallDetectionStats.Builder().build();
-    }
-
-    private void setDataStallEvaluationType(int type) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_EVALUATION_TYPE), anyInt())).thenReturn(type);
-    }
-
-    private void setMinDataStallEvaluateInterval(int time) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_MIN_EVALUATE_INTERVAL), anyInt())).thenReturn(time);
-    }
-
-    private void setValidDataStallDnsTimeThreshold(int time) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_VALID_DNS_TIME_THRESHOLD), anyInt())).thenReturn(time);
-    }
-
-    private void setConsecutiveDnsTimeoutThreshold(int num) {
-        when(mDependencies.getDeviceConfigPropertyInt(any(),
-            eq(CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD), anyInt())).thenReturn(num);
-    }
-
-    private void setFallbackUrl(String url) {
-        when(mDependencies.getSetting(any(),
-                eq(Settings.Global.CAPTIVE_PORTAL_FALLBACK_URL), any())).thenReturn(url);
-    }
-
-    private void setOtherFallbackUrls(String urls) {
-        when(mDependencies.getDeviceConfigProperty(any(),
-                eq(CAPTIVE_PORTAL_OTHER_FALLBACK_URLS), any())).thenReturn(urls);
-    }
-
-    private void setFallbackSpecs(String specs) {
-        when(mDependencies.getDeviceConfigProperty(any(),
-                eq(CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS), any())).thenReturn(specs);
-    }
-
-    private void setCaptivePortalMode(int mode) {
-        when(mDependencies.getSetting(any(),
-                eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt())).thenReturn(mode);
-    }
-
-    private void runPortalNetworkTest(int result) {
-        // The network test event will be triggered twice with the same result. Expect to capture
-        // the second one with direct url.
-        runPortalNetworkTest(result,
-                (VerificationWithTimeout) timeout(HANDLER_TIMEOUT_MS).times(2));
-    }
-
-    private void runPortalNetworkTest(int result, VerificationWithTimeout mode) {
-        runNetworkTest(result, mode);
-        assertEquals(1, mRegisteredReceivers.size());
-        assertNotNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runNotPortalNetworkTest() {
-        runNetworkTest(VALIDATION_RESULT_VALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runNoValidationNetworkTest() {
-        runNetworkTest(NETWORK_VALIDATION_RESULT_VALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runFailedNetworkTest() {
-        runNetworkTest(VALIDATION_RESULT_INVALID);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private void runPartialConnectivityNetworkTest(int result) {
-        runNetworkTest(result);
-        assertEquals(0, mRegisteredReceivers.size());
-        assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
-    }
-
-    private NetworkMonitor runValidatedNetworkTest() throws Exception {
-        setStatus(mHttpsConnection, 204);
-        setStatus(mHttpConnection, 204);
-        // Expect to send HTTPs and evaluation results.
-        return runNetworkTest(VALIDATION_RESULT_VALID);
-    }
-
-    private NetworkMonitor runNetworkTest(int testResult) {
-        return runNetworkTest(METERED_CAPABILITIES, testResult, getGeneralVerification());
-    }
-
-    private NetworkMonitor runNetworkTest(int testResult, VerificationWithTimeout mode) {
-        return runNetworkTest(METERED_CAPABILITIES, testResult, mode);
-    }
-
-    private NetworkMonitor runNetworkTest(NetworkCapabilities nc, int testResult,
-            VerificationWithTimeout mode) {
-        final NetworkMonitor monitor = makeMonitor(nc);
-        monitor.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
-        try {
-            verify(mCallbacks, mode)
-                    .notifyNetworkTested(eq(testResult), mNetworkTestedRedirectUrlCaptor.capture());
-        } catch (RemoteException e) {
-            fail("Unexpected exception: " + e);
-        }
-        HandlerUtilsKt.waitForIdle(monitor.getHandler(), HANDLER_TIMEOUT_MS);
-
-        return monitor;
-    }
-
-    private void setSslException(HttpURLConnection connection) throws IOException {
-        doThrow(new SSLHandshakeException("Invalid cert")).when(connection).getResponseCode();
-    }
-
-    private void set302(HttpURLConnection connection, String location) throws IOException {
-        setStatus(connection, 302);
-        doReturn(location).when(connection).getHeaderField(LOCATION_HEADER);
-    }
-
-    private void setPortal302(HttpURLConnection connection) throws IOException {
-        set302(connection, "http://login.example.com");
-    }
-
-    private void setStatus(HttpURLConnection connection, int status) throws IOException {
-        doReturn(status).when(connection).getResponseCode();
-    }
-
-    private void generateTimeoutDnsEvent(DataStallDetectionStats.Builder stats, int num) {
-        for (int i = 0; i < num; i++) {
-            stats.addDnsEvent(RETURN_CODE_DNS_TIMEOUT, 123456789 /* timeMs */);
-        }
-    }
-
-    private VerificationWithTimeout getGeneralVerification() {
-        return (VerificationWithTimeout) timeout(HANDLER_TIMEOUT_MS).atLeastOnce();
-    }
-
-}
-
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
deleted file mode 100644
index 64fe3a6..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
+++ /dev/null
@@ -1,756 +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.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;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-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.IOnNetworkAttributesRetrievedListener;
-import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.NetworkAttributesParcelable;
-import android.net.ipmemorystore.SameL3NetworkResponse;
-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;
-
-import androidx.test.InstrumentationRegistry;
-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.MockitoAnnotations;
-
-import java.io.File;
-import java.lang.reflect.Modifier;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-
-/** Unit tests for {@link IpMemoryStoreService}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class IpMemoryStoreServiceTest {
-    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 long LEASE_EXPIRY_NULL = -1L;
-    private static final int MTU_NULL = -1;
-    private static final String[] FAKE_KEYS;
-    private static final byte[] TEST_BLOB_DATA = new byte[] { -3, 6, 8, -9, 12,
-            -128, 0, 89, 112, 91, -34 };
-    static {
-        FAKE_KEYS = new String[FAKE_KEY_COUNT];
-        for (int i = 0; i < FAKE_KEYS.length; ++i) {
-            FAKE_KEYS[i] = "fakeKey" + i;
-        }
-    }
-
-    @Mock
-    private Context mMockContext;
-    @Mock
-    private JobScheduler mMockJobScheduler;
-    private File mDbFile;
-
-    private IpMemoryStoreService mService;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        final Context context = InstrumentationRegistry.getContext();
-        final File dir = context.getFilesDir();
-        mDbFile = new File(dir, "test.db");
-        doReturn(mDbFile).when(mMockContext).getDatabasePath(anyString());
-        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
-    public void tearDown() {
-        mService.shutdown();
-        mDbFile.delete();
-    }
-
-    /** Helper method to build test network attributes */
-    private static NetworkAttributes.Builder buildTestNetworkAttributes(
-            final Inet4Address ipAddress, final long expiry, final String hint,
-            final List<InetAddress> dnsServers, final int mtu) {
-        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
-        if (null != ipAddress) {
-            na.setAssignedV4Address(ipAddress);
-        }
-        if (LEASE_EXPIRY_NULL != expiry) {
-            na.setAssignedV4AddressExpiry(expiry);
-        }
-        if (null != hint) {
-            na.setGroupHint(hint);
-        }
-        if (null != dnsServers) {
-            na.setDnsAddresses(dnsServers);
-        }
-        if (MTU_NULL != mtu) {
-            na.setMtu(mtu);
-        }
-        return na;
-    }
-
-    /** Helper method to make a vanilla IOnStatusListener */
-    private IOnStatusListener onStatus(Consumer<Status> functor) {
-        return new IOnStatusListener() {
-            @Override
-            public void onComplete(final StatusParcelable statusParcelable) throws RemoteException {
-                functor.accept(new Status(statusParcelable));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnBlobRetrievedListener */
-    private interface OnBlobRetrievedListener {
-        void onBlobRetrieved(Status status, String l2Key, String name, byte[] data);
-    }
-    private IOnBlobRetrievedListener onBlobRetrieved(final OnBlobRetrievedListener functor) {
-        return new IOnBlobRetrievedListener() {
-            @Override
-            public void onBlobRetrieved(final StatusParcelable statusParcelable,
-                    final String l2Key, final String name, final Blob blob) throws RemoteException {
-                functor.onBlobRetrieved(new Status(statusParcelable), l2Key, name,
-                        null == blob ? null : blob.data);
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnNetworkAttributesRetrievedListener */
-    private interface OnNetworkAttributesRetrievedListener  {
-        void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attr);
-    }
-    private IOnNetworkAttributesRetrievedListener onNetworkAttributesRetrieved(
-            final OnNetworkAttributesRetrievedListener functor) {
-        return new IOnNetworkAttributesRetrievedListener() {
-            @Override
-            public void onNetworkAttributesRetrieved(final StatusParcelable status,
-                    final String l2Key, final NetworkAttributesParcelable attributes)
-                    throws RemoteException {
-                functor.onNetworkAttributesRetrieved(new Status(status), l2Key,
-                        null == attributes ? null : new NetworkAttributes(attributes));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnSameNetworkResponseListener */
-    private interface OnSameL3NetworkResponseListener {
-        void onSameL3NetworkResponse(Status status, SameL3NetworkResponse answer);
-    }
-    private IOnSameL3NetworkResponseListener onSameResponse(
-            final OnSameL3NetworkResponseListener functor) {
-        return new IOnSameL3NetworkResponseListener() {
-            @Override
-            public void onSameL3NetworkResponse(final StatusParcelable status,
-                    final SameL3NetworkResponseParcelable sameL3Network)
-                    throws RemoteException {
-                functor.onSameL3NetworkResponse(new Status(status),
-                        null == sameL3Network ? null : new SameL3NetworkResponse(sameL3Network));
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    /** Helper method to make an IOnL2KeyResponseListener */
-    private interface OnL2KeyResponseListener {
-        void onL2KeyResponse(Status status, String key);
-    }
-    private IOnL2KeyResponseListener onL2KeyResponse(final OnL2KeyResponseListener functor) {
-        return new IOnL2KeyResponseListener() {
-            @Override
-            public void onL2KeyResponse(final StatusParcelable status, final String key)
-                    throws RemoteException {
-                functor.onL2KeyResponse(new Status(status), key);
-            }
-
-            @Override
-            public IBinder asBinder() {
-                return null;
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-
-    // 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(timeout, TimeUnit.MILLISECONDS)) {
-                fail(timeoutMessage);
-            }
-        } catch (InterruptedException e) {
-            fail("Thread was interrupted");
-        }
-    }
-
-    // Helper method to store network attributes to database
-    private void storeAttributes(final String l2Key, final NetworkAttributes na) {
-        storeAttributes("Did not complete storing attributes", l2Key, na);
-    }
-    private void storeAttributes(final String timeoutMessage, final String l2Key,
-            final NetworkAttributes na) {
-        doLatched(timeoutMessage, latch -> mService.storeNetworkAttributes(l2Key, na.toParcelable(),
-                onStatus(status -> {
-                    assertTrue("Store not successful : " + status.resultCode, status.isSuccess());
-                    latch.countDown();
-                })));
-    }
-
-    // Helper method to store blob data to database
-    private void storeBlobOrFail(final String l2Key, final Blob b, final byte[] data) {
-        storeBlobOrFail("Did not complete storing private data", l2Key, b, data);
-    }
-    private void storeBlobOrFail(final String timeoutMessage, final String l2Key, final Blob b,
-            final byte[] data) {
-        b.data = data;
-        doLatched(timeoutMessage, latch -> mService.storeBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME,
-                b, onStatus(status -> {
-                    assertTrue("Store status not successful : " + status.resultCode,
-                            status.isSuccess());
-                    latch.countDown();
-                })));
-    }
-
-    /** Insert large data that db size will be over threshold for maintenance test usage. */
-    private void insertFakeDataAndOverThreshold() {
-        try {
-            final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                    (Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
-                    "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
-                    219);
-            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,
-                        TEST_BLOB_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 String l2Key = FAKE_KEYS[0];
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"),
-                System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
-        NetworkAttributes attributes = na.build();
-        storeAttributes(l2Key, attributes);
-
-        doLatched("Did not complete retrieving attributes", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + status.resultCode, status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(attributes, attr);
-                            latch.countDown();
-                        })));
-
-        final NetworkAttributes.Builder na2 = new NetworkAttributes.Builder();
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
-        final NetworkAttributes attributes2 = na2.build();
-        storeAttributes("Did not complete storing attributes 2", l2Key, attributes2);
-
-        doLatched("Did not complete retrieving attributes 2", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + 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);
-                            latch.countDown();
-                        })));
-
-        doLatched("Did not complete retrieving attributes 3", latch ->
-                mService.retrieveNetworkAttributes(l2Key + "nonexistent",
-                        onNetworkAttributesRetrieved(
-                                (status, key, attr) -> {
-                                    assertTrue("Retrieve network attributes not successful : "
-                                            + status.resultCode, status.isSuccess());
-                                    assertEquals(l2Key + "nonexistent", key);
-                                    assertNull("Retrieved data not stored", attr);
-                                    latch.countDown();
-                                }
-                        )));
-
-        // 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(5, Arrays.stream(NetworkAttributes.class.getDeclaredFields())
-                .filter(f -> !Modifier.isStatic(f.getModifiers())).count());
-    }
-
-    @Test
-    public void testInvalidAttributes() {
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes("key", null, onStatus(status -> {
-                    assertFalse("Success storing on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        final NetworkAttributes na = new NetworkAttributes.Builder().setMtu(2).build();
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes(null, na.toParcelable(), onStatus(status -> {
-                    assertFalse("Success storing null attributes on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        doLatched("Did not complete storing bad attributes", latch ->
-                mService.storeNetworkAttributes(null, null, onStatus(status -> {
-                    assertFalse("Success storing null attributes on a null key",
-                            status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    latch.countDown();
-                })));
-
-        doLatched("Did not complete retrieving bad attributes", latch ->
-                mService.retrieveNetworkAttributes(null, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertFalse("Success retrieving attributes for a null key",
-                                    status.isSuccess());
-                            assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                            assertNull(key);
-                            assertNull(attr);
-                            latch.countDown();
-                        })));
-    }
-
-    @Test
-    public void testPrivateData() {
-        final String l2Key = FAKE_KEYS[0];
-        final Blob b = new Blob();
-        storeBlobOrFail(l2Key, b, TEST_BLOB_DATA);
-
-        doLatched("Did not complete retrieving private data", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME);
-                            assertTrue(Arrays.equals(b.data, data));
-                            latch.countDown();
-                        })));
-
-        // Most puzzling error message ever
-        doLatched("Did not complete retrieving nothing", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME + "2", onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME + "2");
-                            assertNull(data);
-                            latch.countDown();
-                        })));
-    }
-
-    @Test
-    public void testFindL2Key() throws UnknownHostException {
-        final NetworkAttributes.Builder na = new NetworkAttributes.Builder();
-        na.setGroupHint("hint0");
-        storeAttributes(FAKE_KEYS[0], na.build());
-
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("8D56:9AF1::08EE:20F1")}));
-        na.setMtu(219);
-        storeAttributes(FAKE_KEYS[1], na.build());
-        na.setMtu(null);
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
-        na.setDnsAddresses(Arrays.asList(
-                new InetAddress[] {Inet6Address.getByName("0A1C:2E40:480A::1CA6")}));
-        na.setGroupHint("hint1");
-        storeAttributes(FAKE_KEYS[2], na.build());
-        na.setMtu(219);
-        storeAttributes(FAKE_KEYS[3], na.build());
-        na.setMtu(240);
-        storeAttributes(FAKE_KEYS[4], na.build());
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("5.6.7.8"));
-        storeAttributes(FAKE_KEYS[5], na.build());
-
-        // Matches key 5 exactly
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[5], key);
-                    latch.countDown();
-                })));
-
-        // MTU matches key 4 but v4 address matches key 5. The latter is stronger.
-        na.setMtu(240);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[5], key);
-                    latch.countDown();
-                })));
-
-        // Closest to key 3 (indeed, identical)
-        na.setAssignedV4Address((Inet4Address) Inet4Address.getByName("1.2.3.4"));
-        na.setMtu(219);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // Group hint alone must not be strong enough to override the rest
-        na.setGroupHint("hint0");
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // Still closest to key 3, though confidence is lower
-        na.setGroupHint("hint1");
-        na.setDnsAddresses(null);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[3], key);
-                    latch.countDown();
-                })));
-
-        // But changing the MTU makes this closer to key 4
-        na.setMtu(240);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(FAKE_KEYS[4], key);
-                    latch.countDown();
-                })));
-
-        // MTU alone not strong enough to make this group-close
-        na.setGroupHint(null);
-        na.setDnsAddresses(null);
-        na.setAssignedV4Address(null);
-        doLatched("Did not finish finding L2Key", latch ->
-                mService.findL2Key(na.build().toParcelable(), onL2KeyResponse((status, key) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertNull(key);
-                    latch.countDown();
-                })));
-    }
-
-    private void assertNetworksSameness(final String key1, final String key2, final int sameness) {
-        doLatched("Did not finish evaluating sameness", latch ->
-                mService.isSameNetwork(key1, key2, onSameResponse((status, answer) -> {
-                    assertTrue("Retrieve network sameness not successful : " + status.resultCode,
-                            status.isSuccess());
-                    assertEquals(sameness, answer.getNetworkSameness());
-                    latch.countDown();
-                })));
-    }
-
-    @Test
-    public void testIsSameNetwork() throws UnknownHostException {
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"), LEASE_EXPIRY_NULL,
-                "hint1", Arrays.asList(Inet6Address.getByName("0A1C:2E40:480A::1CA6")),
-                219);
-
-        storeAttributes(FAKE_KEYS[0], na.build());
-        // 0 and 1 have identical attributes
-        storeAttributes(FAKE_KEYS[1], na.build());
-
-        // Hopefully only the MTU being different still means it's the same network
-        na.setMtu(200);
-        storeAttributes(FAKE_KEYS[2], na.build());
-
-        // Hopefully different MTU, assigned V4 address and grouphint make a different network,
-        // even with identical DNS addresses
-        na.setAssignedV4Address(null);
-        na.setGroupHint("hint2");
-        storeAttributes(FAKE_KEYS[3], na.build());
-
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[1], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[1], FAKE_KEYS[2], SameL3NetworkResponse.NETWORK_SAME);
-        assertNetworksSameness(FAKE_KEYS[0], FAKE_KEYS[3], SameL3NetworkResponse.NETWORK_DIFFERENT);
-        assertNetworksSameness(FAKE_KEYS[0], "neverInsertedKey",
-                SameL3NetworkResponse.NETWORK_NEVER_CONNECTED);
-
-        doLatched("Did not finish evaluating sameness", latch ->
-                mService.isSameNetwork(null, null, onSameResponse((status, answer) -> {
-                    assertFalse("Retrieve network sameness suspiciously successful : "
-                            + status.resultCode, status.isSuccess());
-                    assertEquals(Status.ERROR_ILLEGAL_ARGUMENT, status.resultCode);
-                    assertNull(answer);
-                    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());
-    }
-
-    @Test
-    public void testFactoryReset() throws UnknownHostException {
-        final String l2Key = FAKE_KEYS[0];
-
-        // store network attributes
-        final NetworkAttributes.Builder na = buildTestNetworkAttributes(
-                (Inet4Address) Inet4Address.getByName("1.2.3.4"),
-                System.currentTimeMillis() + 7_200_000, "hint1", null, 219);
-        storeAttributes(l2Key, na.build());
-
-        // store private data blob
-        final Blob b = new Blob();
-        storeBlobOrFail(l2Key, b, TEST_BLOB_DATA);
-
-        // wipe all data in Database
-        mService.factoryReset();
-
-        // retrieved network attributes should be null
-        doLatched("Did not complete retrieving attributes", latch ->
-                mService.retrieveNetworkAttributes(l2Key, onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Retrieve network attributes not successful : "
-                                    + status.resultCode, status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertNull(attr);
-                            latch.countDown();
-                        })));
-
-        // retrieved private data blob should be null
-        doLatched("Did not complete retrieving private data", latch ->
-                mService.retrieveBlob(l2Key, TEST_CLIENT_ID, TEST_DATA_NAME, onBlobRetrieved(
-                        (status, key, name, data) -> {
-                            assertTrue("Retrieve blob status not successful : " + status.resultCode,
-                                    status.isSuccess());
-                            assertEquals(l2Key, key);
-                            assertEquals(name, TEST_DATA_NAME);
-                            assertNull(data);
-                            latch.countDown();
-                        })));
-    }
-
-    public void testTasksAreSerial() {
-        final long sleepTimeMs = 1000;
-        final long startTime = System.currentTimeMillis();
-        mService.retrieveNetworkAttributes("somekey", onNetworkAttributesRetrieved(
-                (status, key, attr) -> {
-                    assertTrue("Unexpected status : " + status.resultCode, status.isSuccess());
-                    try {
-                        Thread.sleep(sleepTimeMs);
-                    } catch (InterruptedException e) {
-                        fail("InterruptedException");
-                    }
-                }));
-        doLatched("Serial tasks timing out", latch ->
-                mService.retrieveNetworkAttributes("somekey", onNetworkAttributesRetrieved(
-                        (status, key, attr) -> {
-                            assertTrue("Unexpected status : " + status.resultCode,
-                                    status.isSuccess());
-                            assertTrue(System.currentTimeMillis() >= startTime + sleepTimeMs);
-                        })), DEFAULT_TIMEOUT_MS);
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
deleted file mode 100644
index 3d3aabc..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
+++ /dev/null
@@ -1,149 +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.server.connectivity.ipmemorystore;
-
-import static com.android.server.connectivity.ipmemorystore.RelevanceUtils.CAPPED_RELEVANCE;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** Unit tests for {@link RelevanceUtils}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RelevanceUtilsTests {
-    @Test
-    public void testComputeRelevanceForTargetDate() {
-        final long dayInMillis = 24L * 60 * 60 * 1000;
-        final long base = 1_000_000L; // any given point in time
-        // Relevance when the network expires in 1000 years must be capped
-        assertEquals(CAPPED_RELEVANCE, RelevanceUtils.computeRelevanceForTargetDate(
-                base + 1000L * dayInMillis, base));
-        // Relevance when expiry is before the date must be 0
-        assertEquals(0, RelevanceUtils.computeRelevanceForTargetDate(base - 1, base));
-        // Make sure the relevance for a given target date is higher if the expiry is further
-        // in the future
-        assertTrue(RelevanceUtils.computeRelevanceForTargetDate(base + 100 * dayInMillis, base)
-                < RelevanceUtils.computeRelevanceForTargetDate(base + 150 * dayInMillis, base));
-
-        // Make sure the relevance falls slower as the expiry is closing in. This is to ensure
-        // the decay is indeed logarithmic.
-        final int relevanceAtExpiry = RelevanceUtils.computeRelevanceForTargetDate(base, base);
-        final int relevance50DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 50 * dayInMillis, base);
-        final int relevance100DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 100 * dayInMillis, base);
-        final int relevance150DaysBeforeExpiry =
-                RelevanceUtils.computeRelevanceForTargetDate(base + 150 * dayInMillis, base);
-        assertEquals(0, relevanceAtExpiry);
-        assertTrue(relevance50DaysBeforeExpiry - relevanceAtExpiry
-                < relevance100DaysBeforeExpiry - relevance50DaysBeforeExpiry);
-        assertTrue(relevance100DaysBeforeExpiry - relevance50DaysBeforeExpiry
-                < relevance150DaysBeforeExpiry - relevance100DaysBeforeExpiry);
-    }
-
-    @Test
-    public void testIncreaseRelevance() {
-        long expiry = System.currentTimeMillis();
-
-        final long firstBump = RelevanceUtils.bumpExpiryDate(expiry);
-        // Though a few milliseconds might have elapsed, the first bump should push the duration
-        // to days in the future, so unless this test takes literal days between these two lines,
-        // this should always pass.
-        assertTrue(firstBump > expiry);
-
-        expiry = 0;
-        long lastDifference = Long.MAX_VALUE;
-        // The relevance should be capped in at most this many steps. Otherwise, fail.
-        final int steps = 1000;
-        for (int i = 0; i < steps; ++i) {
-            final long newExpiry = RelevanceUtils.bumpExpiryDuration(expiry);
-            if (newExpiry == expiry) {
-                // The relevance should be capped. Make sure it is, then exit without failure.
-                assertEquals(newExpiry, RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS);
-                return;
-            }
-            // Make sure the new expiry is further in the future than last time.
-            assertTrue(newExpiry > expiry);
-            // Also check that it was not bumped as much as the last bump, because the
-            // decay must be exponential.
-            assertTrue(newExpiry - expiry < lastDifference);
-            lastDifference = newExpiry - expiry;
-            expiry = newExpiry;
-        }
-        fail("Relevance failed to go to the maximum value after " + steps + " bumps");
-    }
-
-    @Test
-    public void testContinuity() {
-        final long expiry = System.currentTimeMillis();
-
-        // Relevance at expiry and after expiry should be the cap.
-        final int relevanceBeforeMaxLifetime = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry - (RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS + 1_000_000));
-        assertEquals(relevanceBeforeMaxLifetime, CAPPED_RELEVANCE);
-        final int relevanceForMaxLifetime = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry - RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS);
-        assertEquals(relevanceForMaxLifetime, CAPPED_RELEVANCE);
-
-        // If the max relevance is reached at the cap lifetime, one millisecond less than this
-        // should be very close. Strictly speaking this is a bit brittle, but it should be
-        // good enough for the purposes of the memory store.
-        final int relevanceForOneMillisecLessThanCap = RelevanceUtils.computeRelevanceForTargetDate(
-                expiry, expiry - RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS + 1);
-        assertTrue(relevanceForOneMillisecLessThanCap <= CAPPED_RELEVANCE);
-        assertTrue(relevanceForOneMillisecLessThanCap >= CAPPED_RELEVANCE - 10);
-
-        // Likewise the relevance one millisecond before expiry should be very close to 0. It's
-        // fine if it rounds down to 0.
-        final int relevanceOneMillisecBeforeExpiry = RelevanceUtils.computeRelevanceForTargetDate(
-                expiry, expiry - 1);
-        assertTrue(relevanceOneMillisecBeforeExpiry <= 10);
-        assertTrue(relevanceOneMillisecBeforeExpiry >= 0);
-
-        final int relevanceAtExpiry = RelevanceUtils.computeRelevanceForTargetDate(expiry, expiry);
-        assertEquals(relevanceAtExpiry, 0);
-        final int relevanceAfterExpiry = RelevanceUtils.computeRelevanceForTargetDate(expiry,
-                expiry + 1_000_000);
-        assertEquals(relevanceAfterExpiry, 0);
-    }
-
-    // testIncreaseRelevance makes sure bumping the expiry continuously always yields a
-    // monotonically increasing date as a side effect, but this tests that the relevance (as
-    // opposed to the expiry date) increases monotonically with increasing periods.
-    @Test
-    public void testMonotonicity() {
-        // Hopefully the relevance is granular enough to give a different value for every one
-        // of this number of steps.
-        final int steps = 40;
-        final long expiry = System.currentTimeMillis();
-
-        int lastRelevance = -1;
-        for (int i = 0; i < steps; ++i) {
-            final long date = expiry - i * (RelevanceUtils.CAPPED_RELEVANCE_LIFETIME_MS / steps);
-            final int relevance = RelevanceUtils.computeRelevanceForTargetDate(expiry, date);
-            assertTrue(relevance > lastRelevance);
-            lastRelevance = relevance;
-        }
-    }
-}
diff --git a/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java
deleted file mode 100644
index b1db051..0000000
--- a/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.util.SharedLog;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintWriter;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class SharedLogTest {
-    private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}";
-    private static final String TIMESTAMP = "HH:MM:SS";
-
-    @Test
-    public void testBasicOperation() {
-        final SharedLog logTop = new SharedLog("top");
-        logTop.mark("first post!");
-
-        final SharedLog logLevel2a = logTop.forSubComponent("twoA");
-        final SharedLog logLevel2b = logTop.forSubComponent("twoB");
-        logLevel2b.e("2b or not 2b");
-        logLevel2b.e("No exception", null);
-        logLevel2b.e("Wait, here's one", new Exception("Test"));
-        logLevel2a.w("second post?");
-
-        final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
-        logTop.log("still logging");
-        logLevel3.log("3 >> 2");
-        logLevel2a.mark("ok: last post");
-
-        final String[] expected = {
-            " - MARK first post!",
-            " - [twoB] ERROR 2b or not 2b",
-            " - [twoB] ERROR No exception",
-            // No stacktrace in shared log, only in logcat
-            " - [twoB] ERROR Wait, here's one: Test",
-            " - [twoA] WARN second post?",
-            " - still logging",
-            " - [twoA.three] 3 >> 2",
-            " - [twoA] MARK ok: last post",
-        };
-        // Verify the logs are all there and in the correct order.
-        verifyLogLines(expected, logTop);
-
-        // In fact, because they all share the same underlying LocalLog,
-        // every subcomponent SharedLog's dump() is identical.
-        verifyLogLines(expected, logLevel2a);
-        verifyLogLines(expected, logLevel2b);
-        verifyLogLines(expected, logLevel3);
-    }
-
-    private static void verifyLogLines(String[] expected, SharedLog log) {
-        final ByteArrayOutputStream ostream = new ByteArrayOutputStream();
-        final PrintWriter pw = new PrintWriter(ostream, true);
-        log.dump(null, pw, null);
-
-        final String dumpOutput = ostream.toString();
-        assertTrue(dumpOutput != null);
-        assertTrue(!"".equals(dumpOutput));
-
-        final String[] lines = dumpOutput.split("\n");
-        assertEquals(expected.length, lines.length);
-
-        for (int i = 0; i < expected.length; i++) {
-            String got = lines[i];
-            String want = expected[i];
-            assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want));
-            assertTrue(String.format("'%s' did not contain a %s timestamp", got, TIMESTAMP),
-                    got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP));
-        }
-    }
-}
diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml
index 0f2f3de..4f0f0f0 100644
--- a/packages/PackageInstaller/res/values-af/strings.xml
+++ b/packages/PackageInstaller/res/values-af/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml
index 4579b62..0acab9e 100644
--- a/packages/PackageInstaller/res/values-am/strings.xml
+++ b/packages/PackageInstaller/res/values-am/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index 389639c..87f89ce 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml
index d65a9c7..c900efd 100644
--- a/packages/PackageInstaller/res/values-as/strings.xml
+++ b/packages/PackageInstaller/res/values-as/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml
index d83ab25..bc36123 100644
--- a/packages/PackageInstaller/res/values-az/strings.xml
+++ b/packages/PackageInstaller/res/values-az/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
index 958117f..8c2fab0 100644
--- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml
index 3fc4cbb..e7cbf06 100644
--- a/packages/PackageInstaller/res/values-be/strings.xml
+++ b/packages/PackageInstaller/res/values-be/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
index d384a5a..12ba3ef 100644
--- a/packages/PackageInstaller/res/values-bg/strings.xml
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml
index d4515d3..8025552 100644
--- a/packages/PackageInstaller/res/values-bn/strings.xml
+++ b/packages/PackageInstaller/res/values-bn/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
index ebf0685..421526b 100644
--- a/packages/PackageInstaller/res/values-bs/strings.xml
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml
index 1490d48..62940fa 100644
--- a/packages/PackageInstaller/res/values-ca/strings.xml
+++ b/packages/PackageInstaller/res/values-ca/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
index 7b57639..e250c7b 100644
--- a/packages/PackageInstaller/res/values-cs/strings.xml
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml
index 271c1f2..ca9f37e 100644
--- a/packages/PackageInstaller/res/values-da/strings.xml
+++ b/packages/PackageInstaller/res/values-da/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
index bfe3f28..7826ceb 100644
--- a/packages/PackageInstaller/res/values-de/strings.xml
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml
index b158bed..2be6207 100644
--- a/packages/PackageInstaller/res/values-el/strings.xml
+++ b/packages/PackageInstaller/res/values-el/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml
index 0c813ee..84cde47 100644
--- a/packages/PackageInstaller/res/values-en-rAU/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml
index 0c813ee..84cde47 100644
--- a/packages/PackageInstaller/res/values-en-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml
index 0c813ee..84cde47 100644
--- a/packages/PackageInstaller/res/values-en-rGB/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml
index 0c813ee..84cde47 100644
--- a/packages/PackageInstaller/res/values-en-rIN/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml
index b5406e4..128cbae 100644
--- a/packages/PackageInstaller/res/values-en-rXC/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
index 5cd1cae..117c9f6 100644
--- a/packages/PackageInstaller/res/values-es-rUS/strings.xml
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
index 592aa74..1049c3c 100644
--- a/packages/PackageInstaller/res/values-es/strings.xml
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml
index c8d74f9..b638780 100644
--- a/packages/PackageInstaller/res/values-et/strings.xml
+++ b/packages/PackageInstaller/res/values-et/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index dbcb2bb..2011013 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml
index d5549ae..d08409e 100644
--- a/packages/PackageInstaller/res/values-fa/strings.xml
+++ b/packages/PackageInstaller/res/values-fa/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml
index ca4894a..d52eddf 100644
--- a/packages/PackageInstaller/res/values-fi/strings.xml
+++ b/packages/PackageInstaller/res/values-fi/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index df55043..365493f 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml
index c90cc6d..b85eb97 100644
--- a/packages/PackageInstaller/res/values-fr/strings.xml
+++ b/packages/PackageInstaller/res/values-fr/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml
index 638bf20..1ad1174 100644
--- a/packages/PackageInstaller/res/values-gl/strings.xml
+++ b/packages/PackageInstaller/res/values-gl/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml
index 09a0230..20fbafe 100644
--- a/packages/PackageInstaller/res/values-gu/strings.xml
+++ b/packages/PackageInstaller/res/values-gu/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
index d3f706f..47f8301 100644
--- a/packages/PackageInstaller/res/values-hi/strings.xml
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
index ba83200..ba5d378 100644
--- a/packages/PackageInstaller/res/values-hr/strings.xml
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml
index 0000d5d..2b951de 100644
--- a/packages/PackageInstaller/res/values-hu/strings.xml
+++ b/packages/PackageInstaller/res/values-hu/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml
index c7418f9..c05040b 100644
--- a/packages/PackageInstaller/res/values-hy/strings.xml
+++ b/packages/PackageInstaller/res/values-hy/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml
index d0a9568..52aa3c0 100644
--- a/packages/PackageInstaller/res/values-in/strings.xml
+++ b/packages/PackageInstaller/res/values-in/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml
index 4675463..82d10d3 100644
--- a/packages/PackageInstaller/res/values-is/strings.xml
+++ b/packages/PackageInstaller/res/values-is/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
index 0eefc41..cee14bc 100644
--- a/packages/PackageInstaller/res/values-it/strings.xml
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml
index e602af6..7cabdd5 100644
--- a/packages/PackageInstaller/res/values-iw/strings.xml
+++ b/packages/PackageInstaller/res/values-iw/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml
index cd4dbef..1ba36e7 100644
--- a/packages/PackageInstaller/res/values-ja/strings.xml
+++ b/packages/PackageInstaller/res/values-ja/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml
index 7a7ae4e..779fa0e 100644
--- a/packages/PackageInstaller/res/values-ka/strings.xml
+++ b/packages/PackageInstaller/res/values-ka/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml
index 8253d5e..3e6d25d 100644
--- a/packages/PackageInstaller/res/values-kk/strings.xml
+++ b/packages/PackageInstaller/res/values-kk/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml
index 9b11355..af7ef0b 100644
--- a/packages/PackageInstaller/res/values-km/strings.xml
+++ b/packages/PackageInstaller/res/values-km/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml
index fdefb4c..19842eb 100644
--- a/packages/PackageInstaller/res/values-kn/strings.xml
+++ b/packages/PackageInstaller/res/values-kn/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml
index 989cbe2..2f11159 100644
--- a/packages/PackageInstaller/res/values-ko/strings.xml
+++ b/packages/PackageInstaller/res/values-ko/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
index ae47ab1..61ff87f 100644
--- a/packages/PackageInstaller/res/values-ky/strings.xml
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml
index 0fb541f..c52f509 100644
--- a/packages/PackageInstaller/res/values-lo/strings.xml
+++ b/packages/PackageInstaller/res/values-lo/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml
index 3e840e9..e88bde45 100644
--- a/packages/PackageInstaller/res/values-lt/strings.xml
+++ b/packages/PackageInstaller/res/values-lt/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml
index a0d49f7..fa14527 100644
--- a/packages/PackageInstaller/res/values-lv/strings.xml
+++ b/packages/PackageInstaller/res/values-lv/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
index 5f38528..c625674 100644
--- a/packages/PackageInstaller/res/values-mk/strings.xml
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml
index 609b2af..c22ead4 100644
--- a/packages/PackageInstaller/res/values-ml/strings.xml
+++ b/packages/PackageInstaller/res/values-ml/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml
index e8265f3..61aba57 100644
--- a/packages/PackageInstaller/res/values-mn/strings.xml
+++ b/packages/PackageInstaller/res/values-mn/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml
index 200c993..56661e8 100644
--- a/packages/PackageInstaller/res/values-mr/strings.xml
+++ b/packages/PackageInstaller/res/values-mr/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -37,7 +37,7 @@
     <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> तुमच्या टीव्हीवर इंस्टॉल केले जाऊ शकत नाही."</string>
     <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> तुमच्या फोनवर इंस्टॉल केले जाऊ शकत नाही."</string>
     <string name="launch" msgid="3952550563999890101">"उघडा"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"अज्ञात स्रोतांकडून मिळवलेल्या अॅप्स इंस्टॉलेशनला तुमचा प्रशासक अनुमती देत नाही"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"अज्ञात स्रोतांकडून मिळवलेल्या अ‍ॅप्स इंस्टॉलेशनला तुमचा प्रशासक अनुमती देत नाही"</string>
     <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"या वापरकर्त्याद्वारे अज्ञात अ‍ॅप्स इंस्टॉल केली जाऊ शकत नाहीत"</string>
     <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"या वापरकर्त्याला अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही"</string>
     <string name="ok" msgid="7871959885003339302">"ओके"</string>
@@ -67,8 +67,8 @@
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल केले"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"अनइंस्टॉल करता आले नाही."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करता आले नाही."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"अॅक्टिव्ह डिव्हाइस प्रशासक अ‍ॅप अनइंस्टॉल करू शकत नाही"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> साठी अॅक्टिव्ह डिव्हाइस प्रशासक अ‍ॅप अनइंस्टॉल करू शकत नाही"</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"अ‍ॅक्टिव्ह डिव्हाइस प्रशासक अ‍ॅप अनइंस्टॉल करू शकत नाही"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> साठी अ‍ॅक्टिव्ह डिव्हाइस प्रशासक अ‍ॅप अनइंस्टॉल करू शकत नाही"</string>
     <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"हे अ‍ॅप काही वापरकर्ते किंवा प्रोफाइलसाठी आवश्यक आहे आणि इतरांसाठी अनइंस्टॉल करण्यात आले"</string>
     <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"तुमच्या प्रोफाइलसाठी हे अ‍ॅप आवश्यक आहे आणि अनइंस्टॉल केले जाऊ शकत नाही."</string>
     <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"तुमच्या डिव्हाइस प्रशासकास हे अ‍ॅप आवश्यक आहे आणि ते अनइंस्टॉल केले जाऊ शकत नाही."</string>
diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml
index 9b70073..17815be 100644
--- a/packages/PackageInstaller/res/values-ms/strings.xml
+++ b/packages/PackageInstaller/res/values-ms/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml
index 96c6892..356c370 100644
--- a/packages/PackageInstaller/res/values-my/strings.xml
+++ b/packages/PackageInstaller/res/values-my/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml
index 739c098..6f2f112 100644
--- a/packages/PackageInstaller/res/values-nb/strings.xml
+++ b/packages/PackageInstaller/res/values-nb/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index d4ddacf..dffaba5 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index 2b1b525..108c86f 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
index c28045b..8c89ce9 100644
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml
index a6de4d0..5a417af 100644
--- a/packages/PackageInstaller/res/values-pa/strings.xml
+++ b/packages/PackageInstaller/res/values-pa/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml
index b08dc55..7b50547 100644
--- a/packages/PackageInstaller/res/values-pl/strings.xml
+++ b/packages/PackageInstaller/res/values-pl/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
index 20e66cb..abeb72d45 100644
--- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
index 252e903..65d1427 100644
--- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml
index 20e66cb..abeb72d45 100644
--- a/packages/PackageInstaller/res/values-pt/strings.xml
+++ b/packages/PackageInstaller/res/values-pt/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml
index f8a1720..9c22fcd 100644
--- a/packages/PackageInstaller/res/values-ro/strings.xml
+++ b/packages/PackageInstaller/res/values-ro/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml
index 38aefc7..a9ae543 100644
--- a/packages/PackageInstaller/res/values-ru/strings.xml
+++ b/packages/PackageInstaller/res/values-ru/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml
index 1de2bc0..5fad69d 100644
--- a/packages/PackageInstaller/res/values-si/strings.xml
+++ b/packages/PackageInstaller/res/values-si/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml
index 2fbecf5..ae914bd 100644
--- a/packages/PackageInstaller/res/values-sk/strings.xml
+++ b/packages/PackageInstaller/res/values-sk/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml
index d535dc0..a0702d6 100644
--- a/packages/PackageInstaller/res/values-sl/strings.xml
+++ b/packages/PackageInstaller/res/values-sl/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml
index 5e0f3c9..0cde28e 100644
--- a/packages/PackageInstaller/res/values-sq/strings.xml
+++ b/packages/PackageInstaller/res/values-sq/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml
index 39a1e45..51995a3 100644
--- a/packages/PackageInstaller/res/values-sr/strings.xml
+++ b/packages/PackageInstaller/res/values-sr/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml
index 87646ea..d0902c3 100644
--- a/packages/PackageInstaller/res/values-sv/strings.xml
+++ b/packages/PackageInstaller/res/values-sv/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml
index 9bcb291..7c1472b 100644
--- a/packages/PackageInstaller/res/values-sw/strings.xml
+++ b/packages/PackageInstaller/res/values-sw/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml
index afa2e9c..a130712 100644
--- a/packages/PackageInstaller/res/values-ta/strings.xml
+++ b/packages/PackageInstaller/res/values-ta/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml
index baa3e54..5cbb268 100644
--- a/packages/PackageInstaller/res/values-te/strings.xml
+++ b/packages/PackageInstaller/res/values-te/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml
index 1f6e10a..9c1f028 100644
--- a/packages/PackageInstaller/res/values-th/strings.xml
+++ b/packages/PackageInstaller/res/values-th/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -72,7 +72,7 @@
     <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"แอปนี้จำเป็นสำหรับผู้ใช้หรือโปรไฟล์บางส่วน และถอนการติดตั้งไปแล้วสำหรับส่วนอื่น"</string>
     <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"แอปนี้จำเป็นสำหรับโปรไฟล์ของคุณและถอนการติดตั้งไม่ได้"</string>
     <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"ผู้ดูแลระบบอุปกรณ์กำหนดให้ใช้แอปนี้และถอนการติดตั้งไม่ได้"</string>
-    <string name="manage_device_administrators" msgid="3092696419363842816">"จัดการแอปผู้ดูแลระบบอุปกรณ์"</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"จัดการแอปดูแลอุปกรณ์"</string>
     <string name="manage_users" msgid="1243995386982560813">"จัดการผู้ใช้"</string>
     <string name="uninstall_failed_msg" msgid="2176744834786696012">"ถอนการติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> ไม่ได้"</string>
     <string name="Parse_error_dlg_text" msgid="1661404001063076789">"พบปัญหาในการแยกวิเคราะห์แพ็กเกจ"</string>
diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml
index dbae647..9fcc064 100644
--- a/packages/PackageInstaller/res/values-tl/strings.xml
+++ b/packages/PackageInstaller/res/values-tl/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml
index b8e0832..c6e2d44 100644
--- a/packages/PackageInstaller/res/values-tr/strings.xml
+++ b/packages/PackageInstaller/res/values-tr/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml
index 5f614e3..4c49bf4 100644
--- a/packages/PackageInstaller/res/values-uk/strings.xml
+++ b/packages/PackageInstaller/res/values-uk/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml
index e11e16a..d8f2c50 100644
--- a/packages/PackageInstaller/res/values-ur/strings.xml
+++ b/packages/PackageInstaller/res/values-ur/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml
index 4e24948..0c1871f 100644
--- a/packages/PackageInstaller/res/values-uz/strings.xml
+++ b/packages/PackageInstaller/res/values-uz/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml
index 7dd5cd9..a1d6f89 100644
--- a/packages/PackageInstaller/res/values-vi/strings.xml
+++ b/packages/PackageInstaller/res/values-vi/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
index 27062f7..6110938 100644
--- a/packages/PackageInstaller/res/values-zh-rCN/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
index 2c52420..128f371 100644
--- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
index f82b89c..507b5d4 100644
--- a/packages/PackageInstaller/res/values-zh-rTW/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml
index c711354..bdcb7e1 100644
--- a/packages/PackageInstaller/res/values-zu/strings.xml
+++ b/packages/PackageInstaller/res/values-zu/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/packages/PackageInstaller/res/values/strings.xml b/packages/PackageInstaller/res/values/strings.xml
index 797656e..3e42706 100644
--- a/packages/PackageInstaller/res/values/strings.xml
+++ b/packages/PackageInstaller/res/values/strings.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -185,9 +185,6 @@
     <!-- Placeholder for an app name when it is unknown [CHAR LIMIT=50] -->
     <string name="app_name_unknown">Unknown</string>
 
-    <!-- Help URL, application permissions [DO NOT TRANSLATE] -->
-    <string name="help_app_permissions" translatable="false"></string>
-
     <!-- Text to show in warning dialog on the tablet when the app source is not trusted [CHAR LIMIT=NONE] -->
     <string name="untrusted_external_source_warning" product="tablet">For your security, your tablet is not allowed to install unknown apps from this source.</string>
 
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index 93f24f7..4f85eea 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -130,18 +130,15 @@
             } else {
                 PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                         PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-                params.installFlags = PackageManager.INSTALL_FULL_APP;
-                params.referrerUri = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER);
-                params.originatingUri = getIntent()
-                        .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
-                params.originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
-                        UID_UNKNOWN);
-                params.installerPackageName =
-                        getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
-                params.installReason = PackageManager.INSTALL_REASON_USER;
-
-                // Whitelist all restricted permissions.
-                params.setWhitelistedRestrictedPermissions(null /*permissions*/);
+                params.setInstallAsInstantApp(false);
+                params.setReferrerUri(getIntent().getParcelableExtra(Intent.EXTRA_REFERRER));
+                params.setOriginatingUri(getIntent()
+                        .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI));
+                params.setOriginatingUid(getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
+                        UID_UNKNOWN));
+                params.setInstallerPackageName(getIntent().getStringExtra(
+                        Intent.EXTRA_INSTALLER_PACKAGE_NAME));
+                params.setInstallReason(PackageManager.INSTALL_REASON_USER);
 
                 File file = new File(mPackageURI.getPath());
                 try {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index 881f4b1..c11e1a0 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -34,6 +34,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.permission.IPermissionManager;
 import android.util.Log;
 
 /**
@@ -45,12 +46,14 @@
 
     private static final String DOWNLOADS_AUTHORITY = "downloads";
     private IPackageManager mIPackageManager;
+    private IPermissionManager mIPermissionManager;
     private boolean mAbortInstall = false;
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mIPackageManager = AppGlobals.getPackageManager();
+        mIPermissionManager = AppGlobals.getPermissionManager();
         Intent intent = getIntent();
         String callingPackage = getCallingPackage();
 
@@ -137,7 +140,7 @@
 
     private boolean declaresAppOpPermission(int uid, String permission) {
         try {
-            final String[] packages = mIPackageManager.getAppOpPermissionPackages(permission);
+            final String[] packages = mIPermissionManager.getAppOpPermissionPackages(permission);
             if (packages == null) {
                 return false;
             }
diff --git a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
index dbc51958..8c208e3 100644
--- a/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
+++ b/packages/SettingsLib/AppPreference/res/layout/preference_app.xml
@@ -61,6 +61,7 @@
             android:id="@android:id/summary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:textDirection="locale"
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:textColor="?android:attr/textColorSecondary"/>
 
diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS
index d879087..a28ba85 100644
--- a/packages/SettingsLib/OWNERS
+++ b/packages/SettingsLib/OWNERS
@@ -1,21 +1,13 @@
 # People who can approve changes for submission
-asapperstein@google.com
-asargent@google.com
-dehboxturtle@google.com
-dhnishi@google.com
-dling@google.com
 dsandler@android.com
+edgarwang@google.com
+emilychuang@google.com
 evanlaird@google.com
-jackqdyulei@google.com
-jmonk@google.com
 leifhendrik@google.com
-mfritze@google.com
-rogerxue@google.com
+rafftsai@google.com
+tmfang@google.com
 virgild@google.com
 zhfan@google.com
 
-# Emergency approvers in case the above are not available
-miket@google.com
-
 # Exempt resource files (because they are in a flat directory and too hard to manage via OWNERS)
 per-file *.xml=*
diff --git a/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml b/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml
index 297ecdb..199845b 100644
--- a/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1604061903696928905">"Tafuta mipangilio"</string>
+    <string name="search_menu" msgid="1604061903696928905">"Tafuta katika mipangilio"</string>
 </resources>
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
index 05c2f24..ca2d1ed 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
@@ -24,6 +24,7 @@
 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY_URI;
 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
+import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE_URI;
 import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL;
 import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY;
 
@@ -168,6 +169,11 @@
         ensureMetadataNotStale(context);
         final PackageManager packageManager = context.getPackageManager();
         if (mMetaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
+            if (mMetaData.containsKey(META_DATA_PREFERENCE_TITLE_URI)) {
+                // If has as uri to provide dynamic summary, skip loading here. UI will later load
+                // at tile binding time.
+                return null;
+            }
             if (mMetaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
                 try {
                     final Resources res =
@@ -211,6 +217,8 @@
         final PackageManager packageManager = context.getPackageManager();
         if (mMetaData != null) {
             if (mMetaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
+                // If has as uri to provide dynamic summary, skip loading here. UI will later load
+                // at tile binding time.
                 return null;
             }
             if (mMetaData.containsKey(META_DATA_PREFERENCE_SUMMARY)) {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index 31925ab..aced5ef 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -162,6 +162,16 @@
 
     /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
+     * to specify the content provider providing the title text that should be displayed for the
+     * preference.
+     *
+     * Title provided by the content provider overrides any static title.
+     */
+    public static final String META_DATA_PREFERENCE_TITLE_URI =
+            "com.android.settings.title_uri";
+
+    /**
+     * Name of the meta-data item that should be set in the AndroidManifest.xml
      * to specify the summary text that should be displayed for the preference.
      */
     public static final String META_DATA_PREFERENCE_SUMMARY = "com.android.settings.summary";
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 0116d0d..4cedc93 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Inligtingruiling"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Draadlose skermsertifisering"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktiveer Wi-Fi-woordryke aanmelding"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Regulering van Wi-Fi-opsporing"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data is altyd aktief"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardewareversnelling vir verbinding"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Wys Bluetooth-toestelle sonder name"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kon nie koppel nie"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Wys opsies vir draadlose skermsertifisering"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Verhoog Wi-Fi-aantekeningvlak, wys per SSID RSSI in Wi‑Fi-kieser"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Verlaag batteryverbruik en verbeter netwerk se werkverrigting"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Beperk"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Onbeperk"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Loggerbuffer se groottes"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index b914b07..3b7abdb 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"አውታረ መረብ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"የWi‑Fi ተጨማሪ ቃላት ምዝግብ ማስታወሻ መያዝ"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"የተንቀሳቃሽ ስልክ ውሂብ ሁልጊዜ ገቢር ነው"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"የሃርድዌር ማቀላጠፊያን በማስተሳሰር ላይ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"የብሉቱዝ መሣሪያዎችን ያለ ስሞች አሳይ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"መገናኘት አልተቻለም"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ አማራጮችን አሳይ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"የWi‑Fi ምዝግብ ማስታወሻ አያያዝ ደረጃ ጨምር፣ በWi‑Fi መምረጫ ውስጥ በአንድ SSID RSSI አሳይ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"የባትሪ መላሸቅን ይቀንሳል እንዲሁም የአውታረ መረብ አፈጻጸም ብቃትን ያሻሽላል"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"የሚለካ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ያልተለካ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"የምዝግብ ማስታወሻ ያዥ መጠኖች"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 0a9edb5..df1ec30 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"الشبكات"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"شهادة عرض شاشة لاسلكي"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‏تفعيل تسجيل Wi‑Fi Verbose"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‏تقييد البحث عن شبكات Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"بيانات الجوّال نشطة دائمًا"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"تسريع الأجهزة للتوصيل"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"عرض أجهزة البلوتوث بدون أسماء"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"تعذّر الاتصال"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"عرض خيارات شهادة عرض شاشة لاسلكي"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"لتقليل استنفاد البطارية وتحسين أداء الشبكة."</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"تفرض تكلفة استخدام"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"بدون قياس"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"أحجام ذاكرة التخزين المؤقت للتسجيل"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index fddfb05..9c25b66 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"নেটৱৰ্কিং"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"বেতাঁৰ ডিছপ্লে’ প্ৰমাণীকৰণ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"ৱাই-ফাই ভাৰ্ব\'ছ লগিং সক্ষম কৰক"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ৱাই-ফাই স্কেনৰ নিয়ন্ত্ৰণ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ম’বাইল ডেটা সদা-সক্ৰিয়"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"টেডাৰিং হাৰ্ডৱেৰ ত্বৰণ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"নামবিহীন ব্লুটুথ ডিভাইচসমূহ দেখুৱাওক"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"সংযোগ কৰিব পৰা নগ\'ল"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"বেতাঁৰ ডিছপ্লে’ প্ৰমাণপত্ৰৰ বাবে বিকল্পসমূহ দেখুৱাওক"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ৱাই-ফাই লগিঙৰ মাত্ৰা বঢ়াওক, Wi‑Fi পিকাৰত প্ৰতি SSID RSSI দেখুৱাওক"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"বেটাৰীৰ খৰচ কমায় আৰু নেটৱৰ্কৰ কাৰ্যক্ষমতা বৃদ্ধি কৰে"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"নিৰিখ-নিৰ্দিষ্ট"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"নিৰিখ অনিৰ্দিষ্ট"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"লগাৰৰ বাফাৰৰ আকাৰ"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 642b81c..3a6d301 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Şəbəkələşmə"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz displey sertifikatlaşması"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Çoxsözlü Girişə icazə verin"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi skanlamasının tənzimlənməsi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil data həmişə aktiv"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Birləşmə üçün avadanlıq akselerasiyası"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth cihazlarını adsız göstərin"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Qoşulmaq mümkün olmadı"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Batareya istifadəsini azaldır &amp; şəbəkə performansını yaxşılaşdırır"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Ödənişli"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Limitsiz"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger bufer ölçüləri"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 4fea77a..a8808fa 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikacija bežičnog ekrana"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljniju evidenciju za Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Usporavanje Wi-Fi skeniranja"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci su uvek aktivni"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje privezivanja"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije uspelo"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Smanjuje potrošnju baterije i poboljšava učinak mreže"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Sa ograničenjem"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez ograničenja"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine bafera podataka u programu za evidentiranje"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 5ba5e82..05d9a5d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Сеткі"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сертыфікацыя бесправаднога экрана"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Уключыць падрабязны журнал Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Рэгуляванне пошуку сетак Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мабільная перадача даных заўсёды актыўная"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратнае паскарэнне ў рэжыме мадэма"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Паказваць прылады Bluetooth без назваў"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не атрымалася падключыцца"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Паказаць опцыі сертыфікацыі бесправаднога экрана"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Пры выбары сеткі Wi-Fi указваць у журнале RSSI для кожнага SSID"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Зніжае расход зараду акумулятара і павышае прадукцыйнасць мабільных сетак"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Сетка з улікам трафіка"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Сетка без уліку трафіка"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Памеры буфера журнала"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 54bbffa..7fa5b06 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Мрежи"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Безжичен дисплей"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"„Многословно“ регистр. на Wi‑Fi: Актив."</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Ограничаване на сканирането за Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Винаги активни мобилни данни"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардуерно ускорение за тетъринга"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показване на устройствата с Bluetooth без имена"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не можа да се установи връзка"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показване на опциите за сертифициране на безжичния дисплей"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"По-подробно регистр. на Wi‑Fi – данни за RSSI на SSID в инстр. за избор на Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Намалява изразходването на батерията и подобрява ефективността на мрежата"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"С отчитане"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Без отчитане"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Размери на регистрац. буфери"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 9f9bf04..13890e0 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -219,7 +219,8 @@
     <string name="mock_location_app_set" msgid="8966420655295102685">"অনুরূপ লোকেশন অ্যাপ্লিকেশান: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="7044075693643009662">"নেটওয়ার্কিং"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ওয়্যারলেস ডিসপ্লে সার্টিফিকেশন"</string>
-    <string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং সক্ষম করুন"</string>
+    <string name="wifi_verbose_logging" msgid="4203729756047242344">"ওয়াই-ফাই ভারবোস লগিং চালু করুন"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ওয়াই-ফাই স্ক্যান থ্রোটলিং"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"মোবাইল ডেটা সব সময় সক্রিয় থাক"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"নামহীন ব্লুটুথ ডিভাইসগুলি দেখুন"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"কানেক্ট করা যায়নি"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ওয়াই-ফাই লগিং স্তর বাড়ান, ওয়াই-ফাই চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ব্যাটারির খরচ কমায় এবং নেটওয়ার্কের পারফর্ম্যান্স উন্নত করে"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"মিটার্ড"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"পরিমাপ করা নয়"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"লগার বাফারের আকারগুলি"</string>
@@ -260,7 +262,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"মক অবস্থানগুলি মঞ্জুর করুন"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"অ্যাট্রিবিউট ইন্সপেকশন দেখা চালু করুন"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ওয়াই-ফাই সক্রিয় থাকার সময়েও (দ্রুত নেটওয়ার্কে পাল্টানোর জন্য) সর্বদা মোবাইল ডেটা সক্রিয় রাখুন।"</string>
-    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন উপলব্ধ থাকলে ব্যবহার করুন"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"টিথারিং হার্ডওয়্যার অ্যাক্সিলারেশন উপলভ্য থাকলে ব্যবহার করুন"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB ডিবাগিং মঞ্জুর করবেন?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB ডিবাগিং কেবলমাত্র বিকাশ করার উদ্দেশ্যে। আপনার কম্পিউটার এবং আপনার ডিভাইসের মধ্যে ডেটা অনুলিপি করতে এটি ব্যবহার করুন, বিজ্ঞপ্তি ছাড়া আপনার ডিভাইসে অ্যাপ্লিকেশানগুলি ইনস্টল করুন এবং ডেটা লগ পড়ুন।"</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"আপনি আগে যে সব কম্পিউটার USB ডিবাগিং এর অ্যাক্সেসের অনুমতি দিয়েছিলেন তা প্রত্যাহার করবেন?"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 91d7581..02b2a8b 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući detaljni zapisnik za WiFi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Reguliranje skeniranja WiFi mreže"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Prijenos podataka na mobilnoj mreži je uvijek aktivan"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzavanje za povezivanje putem mobitela"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije uspjelo"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za certifikaciju bežičnog prikaza"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećani nivo zapisnika za WiFi. Prikaz po SSID RSSI-ju u Biraču WiFi-ja"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Smanjuje potrošnju baterije i poboljšava performanse mreže"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"S naplatom"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Mreža bez naplate"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine međumemorije zapisnika"</string>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 15100bf..59b8c8a 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -233,7 +233,7 @@
   <string-array name="show_non_rect_clip_entries">
     <item msgid="993742912147090253">"Desactivat"</item>
     <item msgid="675719912558941285">"Dibuixa àrea retall no rectangular en blau"</item>
-    <item msgid="1064373276095698656">"Ressalta ordres de dibuix provats en verd"</item>
+    <item msgid="1064373276095698656">"Marca ordres de dibuix provats en verd"</item>
   </string-array>
   <string-array name="track_frame_time_entries">
     <item msgid="2193584639058893150">"Desactivat"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 8a4ab91..afdb105 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -155,7 +155,7 @@
     <string name="tts_settings" msgid="8186971894801348327">"Configuració de text a parla"</string>
     <string name="tts_settings_title" msgid="1237820681016639683">"Sortida de text a parla"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocitat de parla"</string>
-    <string name="tts_default_rate_summary" msgid="4061815292287182801">"Velocitat de lectura del text"</string>
+    <string name="tts_default_rate_summary" msgid="4061815292287182801">"Velocitat a què s\'enuncia el text"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"To"</string>
     <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Afecta el to de la veu sintetitzada"</string>
     <string name="tts_default_lang_title" msgid="8018087612299820556">"Idioma"</string>
@@ -179,7 +179,7 @@
     <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor preferent"</string>
     <string name="tts_general_section_title" msgid="4402572014604490502">"General"</string>
     <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Restableix el to de la veu"</string>
-    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Restableix el to predeterminat amb què es llegeix el text."</string>
+    <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Restableix a predeterminat el to amb què s\'enuncia el text."</string>
   <string-array name="tts_rate_entries">
     <item msgid="6695494874362656215">"Molt lenta"</item>
     <item msgid="4795095314303559268">"Lenta"</item>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Xarxes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificació de pantalla sense fil"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Activa el registre Wi‑Fi detallat"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitació de la cerca de xarxes Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dades mòbils sempre actives"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Acceleració per maquinari per a compartició de xarxa"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostra els dispositius Bluetooth sense el nom"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No s\'ha pogut connectar"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra les opcions per a la certificació de pantalla sense fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Augmenta nivell de registre Wi‑Fi, mostra\'l per SSID RSSI al selector de Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Redueix el consum de bateria i millora el rendiment de la xarxa"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"D\'ús mesurat"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"D\'ús no mesurat"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Mides de la mem. intermèdia del registrador"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 8827c9f..5256399 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Sítě"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikace bezdrát. displeje"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné protokolování Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Přibrždění vyhledávání Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilní data jsou vždy aktivní"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarová akcelerace tetheringu"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Zobrazovat zařízení Bluetooth bez názvů"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nelze se připojit"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobrazit možnosti certifikace bezdrátového displeje"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Snižuje vyčerpávání baterie a vylepšuje výkon sítě"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Měřená"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Neměřená"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávací paměť protokol. nástroje"</string>
@@ -419,7 +421,7 @@
     <item msgid="8934126114226089439">"50 %"</item>
     <item msgid="1286113608943010849">"100 %"</item>
   </string-array>
-    <string name="charge_length_format" msgid="8978516217024434156">"před <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"Před <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="7886337596669190587">"zbývá: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="screen_zoom_summary_small" msgid="5867245310241621570">"Malé"</string>
     <string name="screen_zoom_summary_default" msgid="2247006805614056507">"Výchozí"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 04ef33d..1884f64 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -78,7 +78,7 @@
     <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"Aktivt – venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri. Højre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri"</string>
     <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> batteri"</string>
     <string name="bluetooth_battery_level_untethered" msgid="5974406100211667177">"Venstre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> batteri. Højre: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> batteri"</string>
-    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktivt"</string>
+    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Aktiv"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Medielyd"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Telefonopkald"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverførsel"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Netværk"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificering af trådløs skærm"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivér detaljeret Wi-Fi-logføring"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Begrænsning af Wi-Fi-scanning"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er altid aktiveret"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareacceleration ved netdeling"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Vis Bluetooth-enheder uden navne"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Der kunne ikke oprettes forbindelse"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis valgmuligheder for certificering af trådløs skærm"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øg mængden af Wi‑Fi-logføring. Vis opdelt efter SSID RSSI i Wi‑Fi-vælgeren"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reducerer batteriforbruget og forbedrer netværkets effektivitet"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Forbrugsafregnet"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Ikke forbrugsafregnet"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Størrelser for Logger-buffer"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 92413a7..d8da638 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -153,7 +153,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"Einige Standardeinstellungen festgelegt"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Keine Standardeinstellungen festgelegt"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Sprachausgabe"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Sprachausgabe-Einstellungen"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Sprachausgabe"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Sprechgeschwindigkeit"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Geschwindigkeit, mit der der Text gesprochen wird"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Tonlage"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Netzwerke"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Zertifizierung für kabellose Übertragung"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ausführliche WLAN-Protokollierung aktivieren"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Drosselung der WLAN-Suche"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile Datennutzung immer aktiviert"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwarebeschleunigung für Tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-Geräte ohne Namen anzeigen"</string>
@@ -245,7 +246,8 @@
     <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Hostname des DNS-Anbieters eingeben"</string>
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Verbindung nicht möglich"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string>
-    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"WLAN-Protokollierungsebene erhöhen, in WiFi Picker pro SSID RSSI anzeigen"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"WLAN-Protokollierungsebene erhöhen, pro SSID RSSI in WiFi Picker anzeigen"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Verringert den Akkuverbrauch und verbessert die Netzwerkleistung"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Kostenpflichtig"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Kostenlos"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger-Puffergrößen"</string>
@@ -326,7 +328,7 @@
     <string name="app_process_limit_title" msgid="4280600650253107163">"Limit für Hintergrundprozesse"</string>
     <string name="show_all_anrs" msgid="4924885492787069007">"Absturzmeldungen für Hintergrund-Apps anzeigen"</string>
     <string name="show_all_anrs_summary" msgid="6636514318275139826">"Bei Abstürzen von Hintergrund-Apps \"App reagiert nicht\"-Dialog anzeigen"</string>
-    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Benachrichtigungskanal-Warnungen anzeigen"</string>
+    <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Benachrichtigungskanal- Warnungen anzeigen"</string>
     <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Bei Benachrichtigungen ohne gültigen Kanal wird eine Warnung angezeigt"</string>
     <string name="force_allow_on_external" msgid="3215759785081916381">"Sperrung des externen Speichers für alle Apps aufheben"</string>
     <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Jede App kann, ungeachtet der Manifestwerte, in den externen Speicher geschrieben werden"</string>
@@ -379,12 +381,12 @@
     <string name="power_remaining_settings_home_page" msgid="4845022416859002011">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="6123167166221295462">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="8848256785736335185">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, basierend auf deiner Nutzung"</string>
-    <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>, basierend auf deiner Nutzung (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"Bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
+    <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <!-- no translation found for power_remaining_duration_only_short (9183070574408359726) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Sollte basierend auf deiner Nutzung etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Sollte basierend auf deiner Nutzung etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen"</string>
+    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Bei deinem Nutzungsmuster dürfte der Akku bis ca. <xliff:g id="TIME">%1$s</xliff:g> reichen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Bei deinem Nutzungsmuster dürfte der Akku bis ca. <xliff:g id="TIME">%1$s</xliff:g> reichen"</string>
     <string name="power_discharge_by" msgid="6453537733650125582">"Sollte etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only" msgid="107616694963545745">"Sollte etwa bis <xliff:g id="TIME">%1$s</xliff:g> reichen"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Bis <xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 031cd0d..b1b1be6 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Δικτύωση"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Πιστοποίηση ασύρματης οθόνης"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ενεργοποίηση λεπτομερ. καταγραφής Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Περιορισμός σάρωσης Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Σύνδεση επιτάχυνσης υλικού"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Εμφάνιση συσκευών Bluetooth χωρίς ονόματα"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Δεν ήταν δυνατή η σύνδεση"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Περιορίζει την κατανάλωση της μπαταρίας και βελτιώνει την απόδοση του δικτύου"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Μέτρηση με βάση τη χρήση"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Χωρίς μέτρηση με βάση τη χρήση"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Μέγεθος προσωρινής μνήμης για τη λειτουργία καταγραφής"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 5728800..63463b1 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduces battery drain and improves network performance"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
@@ -406,7 +408,7 @@
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
-    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge at the moment"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 5728800..63463b1 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduces battery drain and improves network performance"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
@@ -406,7 +408,7 @@
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
-    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge at the moment"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 5728800..63463b1 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduces battery drain and improves network performance"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
@@ -406,7 +408,7 @@
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
-    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge at the moment"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 5728800..63463b1 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wireless display certification"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Enable Wi‑Fi verbose logging"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi scan throttling"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobile data always active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Show Bluetooth devices without names"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Couldn\'t connect"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduces battery drain and improves network performance"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Metered"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Unmetered"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger buffer sizes"</string>
@@ -406,7 +408,7 @@
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"charging"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string>
-    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge right now"</string>
+    <string name="battery_info_status_not_charging" msgid="8523453668342598579">"Plugged in, can\'t charge at the moment"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlled by admin"</string>
     <string name="disabled" msgid="9206776641295849915">"Disabled"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 460442b..e5a0bda 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎Networking‎‏‎‎‏‎"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎Wireless display certification‎‏‎‎‏‎"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎Enable Wi‑Fi Verbose Logging‎‏‎‎‏‎"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎Wi‑Fi scan throttling‎‏‎‎‏‎"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎Mobile data always active‎‏‎‎‏‎"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‏‏‎‎Tethering hardware acceleration‎‏‎‎‏‎"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎Show Bluetooth devices without names‎‏‎‎‏‎"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎Couldn\'t connect‎‏‎‎‏‎"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎Show options for wireless display certification‎‏‎‎‏‎"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker‎‏‎‎‏‎"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎Reduces battery drain &amp; improves network performance‎‏‎‎‏‎"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎Metered‎‏‎‎‏‎"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎Unmetered‎‏‎‎‏‎"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎Logger buffer sizes‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index a939050..beb1ac5 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro detallado de Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitación de búsqueda de Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activados"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware de conexión mediante dispositivo portátil"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sin nombre"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No se pudo establecer conexión"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones de certificación de pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar nivel de registro Wi-Fi; mostrar por SSID RSSI en el selector de Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduce el consumo de batería y mejora el rendimiento de la red"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Con uso medido"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Sin tarifa plana"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños de búfer de Logger"</string>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 5e50297..63f6c3e 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -43,7 +43,7 @@
     <item msgid="8937994881315223448">"Conectado a <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</item>
     <item msgid="1330262655415760617">"Suspendida"</item>
     <item msgid="7698638434317271902">"Desconectando de <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
-    <item msgid="197508606402264311">"Desconectada"</item>
+    <item msgid="197508606402264311">"Desconectado"</item>
     <item msgid="8578370891960825148">"Con error"</item>
     <item msgid="5660739516542454527">"Bloqueada"</item>
     <item msgid="1805837518286731242">"Inhabilitando conexión inestable temporalmente..."</item>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 533296c..8baf7a2 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -23,7 +23,7 @@
     <string name="wifi_fail_to_scan" msgid="1265540342578081461">"No se puede buscar redes."</string>
     <string name="wifi_security_none" msgid="7985461072596594400">"Ninguna"</string>
     <string name="wifi_remembered" msgid="4955746899347821096">"Guardado"</string>
-    <string name="wifi_disconnected" msgid="8085419869003922556">"Desconectada"</string>
+    <string name="wifi_disconnected" msgid="8085419869003922556">"Desconectado"</string>
     <string name="wifi_disabled_generic" msgid="4259794910584943386">"Inhabilitado"</string>
     <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Error de configuración de IP"</string>
     <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"No conectado debido a la baja calidad de la red"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificación de pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Habilitar registro de Wi-Fi detallado"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitación de búsqueda de redes Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móviles siempre activos"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración por hardware para conexión compartida"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sin nombre"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"No se ha podido establecer la conexión"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar el nivel de registro de Wi-Fi y mostrar por SSID RSSI en el selector Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduce el consumo de batería y mejora el rendimiento de las redes"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Medida"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"No medida"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaños del búfer para registrar"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index e5e8f56..090b28d 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Võrgundus"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Juhtmeta ekraaniühenduse sertifitseerimine"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Luba WiFi sõnaline logimine"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"WiFi-skannimise ahendamine"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Hoia mobiilne andmeside alati aktiivne"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Ühenduse jagamise riistvaraline kiirendus"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Kuva ilma nimedeta Bluetoothi seadmed"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ühendamine ebaõnnestus"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Juhtmeta ekraaniühenduse sertifitseerimisvalikute kuvamine"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Suurenda WiFi logimistaset, kuva WiFi valijas SSID RSSI järgi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Aeglustab aku tühjenemist ja parandab võrgu toimivust"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Mahupõhine"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Mittemahupõhine"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logija puhvri suurused"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 3c11efd..fd3936d 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Sareak"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Hari gabe bistaratzeko ziurtagiria"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Gaitu wifi-sareetan saioa hasteko modu xehatua"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wifi-sareen bilaketaren muga"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datu-konexioa beti aktibo"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Konexioa partekatzeko hardwarearen azelerazioa"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Erakutsi Bluetooth gailuak izenik gabe"</string>
@@ -245,7 +246,8 @@
     <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Idatzi DNS hornitzailearen ostalari-izena"</string>
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ezin izan da konektatu"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Erakutsi hari gabe bistaratzeko ziurtagiriaren aukerak"</string>
-    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago wifi-sareetan saioa hastean. Erakutsi sarearen identifikatzailea eta seinalearen indarra wifi-sareen hautagailuan."</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago wifi-sareetan saioa hastean. Erakutsi sarearen identifikatzailea eta seinalearen indarra wifi-sareen hautatzailean."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Bateria gutxiago kontsumituko da, eta sarearen errendimendua hobetuko."</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Sare neurtua"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Neurtu gabeko sarea"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Erregistroen buffer-tamainak"</string>
@@ -259,7 +261,7 @@
     <string name="allow_mock_location" msgid="2787962564578664888">"Onartu kokapen faltsuak"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Onartu kokapen faltsuak"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Gaitu ikuspegiaren atributuak ikuskatzeko aukera"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantendu mugikorreko datuak beti aktibo, baita wifi-konexioa aktibo dagoenean ere (sarez bizkor aldatu ahal izateko)"</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantendu datu-konexioa beti aktibo, baita wifi-konexioa aktibo dagoenean ere (sare batetik bestera bizkor aldatu ahal izateko)."</string>
     <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen azelerazioa"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB arazketa onartu?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"USB arazketa garapen-xedeetarako soilik dago diseinatuta. Erabil ezazu ordenagailuaren eta gailuaren artean datuak kopiatzeko, aplikazioak gailuan jakinarazi gabe instalatzeko eta erregistro-datuak irakurtzeko."</string>
@@ -460,7 +462,7 @@
     <string name="alarm_template_far" msgid="3779172822607461675">"data: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="zen_mode_duration_settings_title" msgid="229547412251222757">"Iraupena"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="6478923750878945501">"Galdetu beti"</string>
-    <string name="zen_mode_forever" msgid="2704305038191592967">"Desaktibatu arte"</string>
+    <string name="zen_mode_forever" msgid="2704305038191592967">"Zuk desaktibatu arte"</string>
     <string name="time_unit_just_now" msgid="6363336622778342422">"Oraintxe"</string>
     <string name="media_transfer_this_device_name" msgid="1636276898262571213">"Gailu hau"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 9a3061d..352c276 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"شبکه"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"گواهینامه نمایش بی‌سیم"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‏فعال کردن گزارش‌گیری طولانی Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‏محدود کردن اسکن کردن Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"داده تلفن همراه همیشه فعال باشد"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"شتاب سخت‌افزاری اتصال به اینترنت با تلفن همراه"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"نمایش دستگاه‌های بلوتوث بدون نام"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"متصل نشد"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"نمایش گزینه‌ها برای گواهینامه نمایش بی‌سیم"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏افزایش سطح گزارش‌گیری Wi‑Fi، نمایش به ازای SSID RSSI در انتخاب‌کننده Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"تخلیه باتری راکاهش می‌دهد و عملکرد شبکه را بهبود می‌بخشد"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"محدودشده"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"محدودنشده"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"اندازه‌های حافظه موقت ثبت‌کننده"</string>
@@ -259,7 +261,7 @@
     <string name="allow_mock_location" msgid="2787962564578664888">"مکان‌های کاذب مجاز هستند"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"مکان‌های کاذب مجاز هستند"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"فعال کردن نمایش بازبینی ویژگی"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏داده سلولی همیشه فعال نگه داشته می‌شود، حتی وقتی Wi-Fi فعال است (برای جابه‌جایی سریع شبکه)."</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"‏داده تلفن همراه همیشه فعال نگه داشته می‌شود، حتی وقتی Wi-Fi فعال است (برای جابه‌جایی سریع شبکه)."</string>
     <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"استفاده از شتاب سخت‌افزاری اشتراک‌گذاری اینترنت درصورت دردسترس بودن"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"‏اشکال‌زدایی USB انجام شود؟"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"‏اشکال‌زدایی USB فقط برای اهداف برنامه‌نویسی در نظر گرفته شده است. از آن برای رونوشت‌برداری داده بین رایانه و دستگاهتان، نصب برنامه‌ها در دستگاهتان بدون اعلان و خواندن داده‌های گزارش استفاده کنید."</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index b166cb0..0d522c4 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Yhteysominaisuudet"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Langattoman näytön sertifiointi"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Käytä Wi-Fin laajennettua lokikirjausta"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi-haun rajoitus"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiilidata aina käytössä"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Laitteistokiihdytyksen yhteyden jakaminen"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Näytä nimettömät Bluetooth-laitteet"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ei yhteyttä"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Näytä langattoman näytön sertifiointiin liittyvät asetukset."</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Lisää Wi‑Fin lokikirjaustasoa, näytä SSID RSSI -kohtaisesti Wi‑Fi-valitsimessa."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Vähentää virrankulutusta ja parantaa verkon toimintaa"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Maksullinen"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Maksuton"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Lokipuskurien koot"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 9983337..1dde863 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -153,7 +153,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"Certaines préférences par défaut définies"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"Aucune préférence par défaut définie"</string>
     <string name="tts_settings" msgid="8186971894801348327">"Synthèse vocale"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"Sortie de la synthèse vocale"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"Synthèse vocale"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"Cadence"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"Vitesse à laquelle le texte est énoncé"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"Ton"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Réseautage"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certification de l\'affichage sans fil"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser enreg. données Wi-Fi détaillées"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limiter la recherche de réseaux Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Données cellulaires toujours actives"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afficher les appareils Bluetooth sans nom"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossible de se connecter"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification d\'affichage sans fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler davantage les données Wi-Fi, afficher par SSID RSSI dans sélect. Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Réduit l\'utilisation de la pile et améliore les performances réseau"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Facturé à l\'usage"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Non mesuré"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tailles des mémoires tampons d\'enregistreur"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 79c762e..cf4ee13 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -146,7 +146,7 @@
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Partage connexion Bluetooth"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Partage de connexion"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"Partage de connexion"</string>
-    <string name="managed_user_title" msgid="8109605045406748842">"Toutes applis profession."</string>
+    <string name="managed_user_title" msgid="8109605045406748842">"Toutes les applis professionnelles"</string>
     <string name="user_guest" msgid="8475274842845401871">"Invité"</string>
     <string name="unknown" msgid="1592123443519355854">"Inconnu"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"Utilisateur : <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Mise en réseau"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certification affichage sans fil"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Autoriser l\'enregistrement d\'infos Wi-Fi détaillées"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limiter la recherche Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Données mobiles toujours actives"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afficher les appareils Bluetooth sans nom"</string>
@@ -242,10 +243,11 @@
     <string name="private_dns_mode_off" msgid="8236575187318721684">"Désactivé"</string>
     <string name="private_dns_mode_opportunistic" msgid="8314986739896927399">"Automatique"</string>
     <string name="private_dns_mode_provider" msgid="8354935160639360804">"Nom d\'hôte du fournisseur DNS privé"</string>
-    <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Saisissez le nom d\'hôte du fournisseur DNS"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Indiquez le nom d\'hôte du fournisseur DNS"</string>
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossible de se connecter"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification de l\'affichage sans fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler les infos Wi-Fi, afficher par RSSI de SSID dans l\'outil de sélection Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Réduit la décharge de la batterie et améliore les performances du réseau"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Facturé à l\'usage"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Non facturé à l\'usage"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tailles des tampons de l\'enregistreur"</string>
@@ -383,8 +385,8 @@
     <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Temps restant en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>) : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
     <!-- no translation found for power_remaining_duration_only_short (9183070574408359726) -->
     <skip />
-    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
-    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre utilisation"</string>
+    <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> selon utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+    <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> selon utilisation"</string>
     <string name="power_discharge_by" msgid="6453537733650125582">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
     <string name="power_discharge_by_only" msgid="107616694963545745">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="power_discharge_by_only_short" msgid="1372817269546888804">"Jusqu\'à <xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index f41be39..b998a74 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificado de visualización sen fíos"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Activar rexistro detallado da wifi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitación da busca de wifi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Datos móbiles sempre activados"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleración de hardware para conexión compartida"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sen nomes"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Non se puido conectar"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opcións para o certificado de visualización sen fíos"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta o nivel de rexistro da wifi, móstrao por SSID RSSI no selector de wifi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduce o consumo de batería e mellora o rendemento da rede"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Sen tarifa plana"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Con tarifa plana"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamaño dos búfers do rexistrador"</string>
@@ -400,8 +402,8 @@
     <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"É posible que a tableta se apague en breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"É posible que o dispositivo se apague en breve (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo que queda ata cargar de todo: <xliff:g id="TIME">%1$s</xliff:g>"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ata completar a carga"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Tempo que queda para completar a carga: <xliff:g id="TIME">%1$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"cargando"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index a411a05..cf0e201 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"નેટવર્કિંગ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"વાયરલેસ ડિસ્પ્લે પ્રમાણન"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"વાઇ-ફાઇ વર્બોઝ લૉગિંગ ચાલુ કરો"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"વાઇ-ફાઇ સ્કૅનની ક્ષમતા મર્યાદિત કરવી"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"મોબાઇલ ડેટા હંમેશાં સક્રિય"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ટિથરિંગ માટે હાર્ડવેર ગતિવૃદ્ધિ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"નામ વિનાના બ્લૂટૂથ ઉપકરણો બતાવો"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"કનેક્ટ કરી શકાયું નથી"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"વાઇ-ફાઇ લોગિંગ સ્તર વધારો, વાઇ-ફાઇ પીકરમાં SSID RSSI દીઠ બતાવો"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"બૅટરીનો ચાર્જ ઝડપથી ઓછો થવાનું ટાળે છે અને નેટવર્કની કાર્યક્ષમતામાં સુધારો કરે છે"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"મીટર કરેલ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"મીટર ન કરેલ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"લોગર બફર કદ"</string>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 5ad9b01..3d9a78e 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -76,7 +76,7 @@
     <item msgid="3422726142222090896">"avrcp16"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_titles">
-    <item msgid="7065842274271279580">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
+    <item msgid="7065842274271279580">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="7539690996561263909">"SBC"</item>
     <item msgid="686685526567131661">"AAC"</item>
     <item msgid="5254942598247222737">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ऑडियो"</item>
@@ -86,7 +86,7 @@
     <item msgid="3304843301758635896">"वैकल्पिक कोडेक अक्षम करें"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_summaries">
-    <item msgid="5062108632402595000">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
+    <item msgid="5062108632402595000">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="6898329690939802290">"SBC"</item>
     <item msgid="6839647709301342559">"AAC"</item>
     <item msgid="7848030269621918608">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ऑडियो"</item>
@@ -96,38 +96,38 @@
     <item msgid="741805482892725657">"वैकल्पिक कोडेक अक्षम करें"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_titles">
-    <item msgid="3093023430402746802">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
+    <item msgid="3093023430402746802">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="8895532488906185219">"44.1 kHz"</item>
     <item msgid="2909915718994807056">"48.0 kHz"</item>
     <item msgid="3347287377354164611">"88.2 kHz"</item>
     <item msgid="1234212100239985373">"96.0 kHz"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
-    <item msgid="3214516120190965356">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
+    <item msgid="3214516120190965356">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="4482862757811638365">"44.1 kHz"</item>
     <item msgid="354495328188724404">"48.0 kHz"</item>
     <item msgid="7329816882213695083">"88.2 kHz"</item>
     <item msgid="6967397666254430476">"96.0 kHz"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
-    <item msgid="2684127272582591429">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
+    <item msgid="2684127272582591429">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="5618929009984956469">"16 बिट/नमूना"</item>
     <item msgid="3412640499234627248">"24 बिट/नमूना"</item>
     <item msgid="121583001492929387">"32 बिट/नमूना"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
-    <item msgid="1081159789834584363">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
+    <item msgid="1081159789834584363">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="4726688794884191540">"16 बिट/नमूना"</item>
     <item msgid="305344756485516870">"24 बिट/नमूना"</item>
     <item msgid="244568657919675099">"32 बिट/नमूना"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_titles">
-    <item msgid="5226878858503393706">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
+    <item msgid="5226878858503393706">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="4106832974775067314">"मोनो"</item>
     <item msgid="5571632958424639155">"स्टीरियो"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
-    <item msgid="4118561796005528173">"सिस्टम चयन का उपयोग करें (डिफ़ॉल्ट)"</item>
+    <item msgid="4118561796005528173">"सिस्टम चुनाव का उपयोग करें (डिफ़ॉल्ट)"</item>
     <item msgid="8900559293912978337">"मोनो"</item>
     <item msgid="8883739882299884241">"स्टीरियो"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 2c37efa9..238eba5 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -37,7 +37,7 @@
     <string name="wifi_no_internet" msgid="4663834955626848401">"इंटरनेट नहीं है"</string>
     <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> के द्वारा सहेजा गया"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s के ज़रिए ऑटोमैटिक रूप से कनेक्ट है"</string>
-    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदाता के ज़रिए अपने आप कनेक्ट है"</string>
+    <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग कंपनी के ज़रिए अपने आप कनेक्ट है"</string>
     <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string>
     <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> के ज़रिए कनेक्ट किया गया"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस डिसप्ले सर्टिफ़िकेशन"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाई-फ़ाई वर्बोस लॉगिंग चालू करें"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"वाई-फ़ाई के लिए स्कैन की संख्या कम करें"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा हमेशा चालू"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"हार्डवेयर से तेज़ी लाने के लिए टेदर करें"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"बिना नाम वाले ब्लूटूथ डिवाइस दिखाएं"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"कनेक्‍ट नहीं हो सका"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस डिसप्ले सर्टिफ़िकेशन के विकल्प दिखाएं"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाई-फ़ाई लॉगिंग का स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"बैटरी की खपत कम और नेटवर्क की परफ़ॉर्मेंस बेहतर होती है"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"डेटा इस्तेमाल करने की सीमा तय की गई है"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"डेटा इस्तेमाल करने की सीमा तय नहीं की गई है"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफ़र आकार"</string>
@@ -359,7 +361,7 @@
     <string name="runningservices_settings_summary" msgid="854608995821032748">"इस समय चल रही सेवाओं को देखें और नियंत्रित करें"</string>
     <string name="select_webview_provider_title" msgid="4628592979751918907">"वेबव्यू लागू करें"</string>
     <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"वेबव्यू सेट करें"</string>
-    <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"यह चयन अब मान्य नहीं है. पुनः प्रयास करें."</string>
+    <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"यह चुनाव अब मान्य नहीं है. दोबारा कोशिश करें."</string>
     <string name="convert_to_file_encryption" msgid="3060156730651061223">"फ़ाइल आधारित सुरक्षित करने के तरीके में बदलें"</string>
     <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"रूपांतरित करें..."</string>
     <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"फ़ाइल पहले से एन्क्रिप्ट की हुई है"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ea4a688..6d957dc 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Umrežavanje"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikacija bežičnog prikaza"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogući opširnu prijavu na Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Usporavanje traženja Wi-Fija"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilni podaci uvijek aktivni"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardversko ubrzanje za modemsko povezivanje"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži Bluetooth uređaje bez naziva"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezivanje nije moguće"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za certifikaciju bežičnog prikaza"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećana razina prijave na Wi‑Fi, prikaz po SSID RSSI-ju u Biraču Wi‑Fi-ja"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Smanjuje potrošnju baterije i poboljšava rad mreže"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"S ograničenim prometom"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez ograničenja prometa"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Veličine međuspremnika zapisnika"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index d4fc9a7..39b5da2 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Hálózatok"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Vezeték nélküli kijelző tanúsítványa"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Részletes Wi-Fi-naplózás engedélyezése"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi-Fi-hálózat szabályozása"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"A mobilhálózati kapcsolat mindig aktív"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Internetmegosztás hardveres gyorsítása"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Név nélküli Bluetooth-eszközök megjelenítése"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nem sikerült kapcsolódni"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vezeték nélküli kijelző tanúsítványával kapcsolatos lehetőségek megjelenítése"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-naplózási szint növelése, RSSI/SSID megjelenítése a Wi‑Fi-választóban"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Csökkenti az akkumulátorhasználatot, és javítja a hálózat teljesítményét"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Forgalomkorlátos"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Nem forgalomkorlátos"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Naplózási puffer mérete"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 9ae2fa2..bf58740 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Ցանց"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Անլար էկրանների հավաստագրում"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Միացնել Wi‑Fi մանրամասն գրանցամատյանները"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi-ի որոնման սահմանափակում"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Բջջային ինտերնետը միշտ ակտիվ է"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Սարքակազմի արագացման միացում"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Ցուցադրել Bluetooth սարքերն առանց անունների"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Չհաջողվեց միանալ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ցույց տալ անլար էկրանների հավաստագրման ընտրանքները"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Բարձրացնել մակարդակը, Wi‑Fi ընտրիչում ամեն մի SSID-ի համար ցույց տալ RSSI"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Նվազեցնում է մարտկոցի սպառումը և լավացնում ցանցի աշխատանքը"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Վճարովի թրաֆիկ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Անսահմանափակ թրաֆիկ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Մատյանի բուֆերի չափերը"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 4b4efb3..7fe1ef9 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -41,7 +41,7 @@
     <string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string>
     <string name="connected_via_app" msgid="5571999941988929520">"Tersambung melalui <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string>
-    <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap untuk mendaftar"</string>
+    <string name="tap_to_sign_up" msgid="6449724763052579434">"Ketuk untuk mendaftar"</string>
     <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tersambung, tidak ada internet"</string>
     <string name="wifi_limited_connection" msgid="7717855024753201527">"Koneksi terbatas"</string>
     <string name="wifi_status_no_internet" msgid="5784710974669608361">"Tidak ada internet"</string>
@@ -52,7 +52,7 @@
     <string name="osu_opening_provider" msgid="5488997661548640424">"Membuka <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="2187750899158158934">"Tidak dapat tersambung"</string>
     <string name="osu_completing_sign_up" msgid="9037638564719197082">"Menyelesaikan pendaftaran…"</string>
-    <string name="osu_sign_up_failed" msgid="7296159750352873260">"Tidak dapat menyelesaikan pendaftaran. Tap untuk mencoba lagi."</string>
+    <string name="osu_sign_up_failed" msgid="7296159750352873260">"Tidak dapat menyelesaikan pendaftaran. Ketuk untuk mencoba lagi."</string>
     <string name="osu_sign_up_complete" msgid="8207626049093289203">"Pendaftaran selesai. Menyambungkan…"</string>
     <string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Lambat"</string>
     <string name="speed_label_slow" msgid="813109590815810235">"Lambat"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Jaringan"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Sertifikasi layar nirkabel"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktifkan Pencatatan Log Panjang Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Pembatasan pemindaian Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Kuota selalu aktif"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Akselerasi hardware tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Tampilkan perangkat Bluetooth tanpa nama"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tidak dapat terhubung"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Memperlambat kehabisan baterai &amp; meningkatkan performa jaringan"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Berbayar"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Tidak berbayar"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Ukuran buffer pencatat log"</string>
@@ -291,8 +293,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Kedipkan layar saat apl beroperasi lama pada utas utama"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Lokasi penunjuk"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Hamparan layar menampilkan data sentuhan saat ini"</string>
-    <string name="show_touches" msgid="2642976305235070316">"Tampilkan tap"</string>
-    <string name="show_touches_summary" msgid="6101183132903926324">"Tampilkan masukan visual untuk tap"</string>
+    <string name="show_touches" msgid="2642976305235070316">"Tampilkan ketukan"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Tampilkan masukan untuk ketukan"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Lihat pembaruan permukaan"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Sorot seluruh permukaan jendela saat diperbarui"</string>
     <string name="show_hw_screen_updates" msgid="4117270979975470789">"Tampilkan update tampilan"</string>
@@ -336,7 +338,7 @@
     <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Sandi backup desktop"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Saat ini backup desktop sepenuhnya tidak dilindungi"</string>
-    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Sandi cadangan baru telah disetel"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Sandi baru dan konfirmasinya tidak cocok."</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Gagal menyetel sandi cadangan"</string>
@@ -352,8 +354,8 @@
     <item msgid="5363960654009010371">"Warna yang dioptimalkan untuk konten digital"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="9042996804461901648">"Aplikasi standby"</string>
-    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Tidak aktif. Tap untuk beralih."</string>
-    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktif. Tap untuk beralih."</string>
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Tidak aktif. Ketuk untuk beralih."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktif. Ketuk untuk beralih."</string>
     <string name="standby_bucket_summary" msgid="6567835350910684727">"Status standby aplikasi:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Layanan yang sedang berjalan"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Melihat dan mengontrol layanan yang sedang berjalan"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 8333a59..11d69571 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Netkerfi"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Vottun þráðlausra skjáa"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Kveikja á ítarlegri skráningu Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Hægja á Wi‑Fi leit"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Alltaf kveikt á farsímagögnum"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Vélbúnaðarhröðun fyrir tjóðrun"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Sýna Bluetooth-tæki án heita"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tenging mistókst"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Sýna valkosti fyrir vottun þráðlausra skjáa"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Auka skráningarstig Wi-Fi, sýna RSSI fyrir hvert SSID í Wi-Fi vali"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Dregur úr rafhlöðunotkun og eykur netafköst"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Mæld notkun"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Notkun ekki mæld"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Annálsritastærðir biðminna"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 633b721..68c0f17 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Reti"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificazione display wireless"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Attiva logging dettagliato Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limita ricerca di reti Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dati mobili sempre attivi"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering accelerazione hardware"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostra dispositivi Bluetooth senza nome"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Impossibile collegarsi"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opzioni per la certificazione display wireless"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta livello di logging Wi-Fi, mostra SSID RSSI nel selettore Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Riduce il consumo della batteria e migliora le prestazioni della rete"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"A consumo"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Non a consumo"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Dimensioni buffer logger"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 9352479..ead0bfb 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"תקשורת רשתות"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"‏אישור של תצוגת WiFi"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‏הפעלת רישום מפורט של Wi‑Fi ביומן"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‏ויסות סריקה לנקודות Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"חבילת הגלישה פעילה תמיד"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"שיפור מהירות באמצעות חומרה לצורך שיתוף אינטרנט בין ניידים"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"‏הצגת מכשירי Bluetooth ללא שמות"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"לא ניתן היה להתחבר"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"‏הצג אפשרויות עבור אישור של תצוגת WiFi"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"מפחית את קצב התרוקנות הסוללה ומשפר את ביצועי הרשת"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"נמדדת"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"לא נמדדת"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"גדלי מאגר של יומן רישום"</string>
@@ -407,7 +409,7 @@
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"בטעינה"</string>
     <string name="battery_info_status_discharging" msgid="310932812698268588">"לא בטעינה"</string>
     <string name="battery_info_status_not_charging" msgid="8523453668342598579">"המכשיר מחובר, אבל לא ניתן לטעון עכשיו"</string>
-    <string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
+    <string name="battery_info_status_full" msgid="2824614753861462808">"מלאה"</string>
     <string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"נמצא בשליטת מנהל מערכת"</string>
     <string name="disabled" msgid="9206776641295849915">"מושבת"</string>
     <string name="external_source_trusted" msgid="2707996266575928037">"מורשה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index b032aad..e5d29bf 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ネットワーク"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ワイヤレスディスプレイ認証"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi詳細ログの有効化"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi スキャン スロットリング"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"モバイルデータを常に ON にする"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"テザリング時のハードウェア アクセラレーション"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth デバイスを名前なしで表示"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"接続できませんでした"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ワイヤレスディスプレイ認証のオプションを表示"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fiログレベルを上げて、Wi-Fi選択ツールでSSID RSSIごとに表示します"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"電池の消耗が軽減され、ネットワーク パフォーマンスが改善されます"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"従量制"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"定額制"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ログバッファのサイズ"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 2c1d7c0..8b9b6b6 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ქსელი"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"უსადენო ეკრანის სერტიფიცირება"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi-ს დაწვრილებითი აღრიცხვის ჩართვა"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi სკანირების რეგულირება"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"მობილური ინტერნეტის ყოველთვის გააქტიურება"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ტეტერინგის აპარატურული აჩქარება"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-მოწყობილობების ჩვენება სახელების გარეშე"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"დაკავშირება ვერ მოხერხდა"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"უსადენო ეკრანის სერტიფიცირების ვარიანტების ჩვენება"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-ს აღრიცხვის დონის გაზრდა, Wi‑Fi ამომრჩეველში ყოველ SSID RSSI-ზე ჩვენება"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ამცირებს ბატარეის ხარჯვას და აუმჯობესებს ქსელის მუშაობას"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ლიმიტირებული"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"არალიმიტირებული"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ჟურნალიზაციის ბუფერის ზომები"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 5ae201e..246e3eb 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -220,7 +220,8 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Желі орнату"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сымсыз дисплей сертификаты"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi егжей-тегжейлі журналы"</string>
-    <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік деректер әрқашан қосулы"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi іздеуін шектеу"</string>
+    <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобильдік интернет әрқашан қосулы"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Тетеринг режиміндегі аппараттық жеделдету"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth құрылғыларын атаусыз көрсету"</string>
     <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Абсолютті дыбыс деңгейін өшіру"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Қосылмады"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Сымсыз дисплей сертификаты опцияларын көрсету"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi тіркеу деңгейін арттыру, Wi‑Fi таңдағанда әр SSID RSSI бойынша көрсету"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Батарея зарядының шығынын азайтады және желі жұмысын жақсартады."</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Трафик саналады"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Трафик саналмайды"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Журналға тіркеуші буферінің өлшемдері"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index ed00b68..36cf2d4 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ការភ្ជាប់បណ្ដាញ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"សេចក្តីបញ្ជាក់ការបង្ហាញ​ឥត​ខ្សែ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"បើក​កំណត់ហេតុ​រៀបរាប់​ Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ការពន្យឺតការស្កេន Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ទិន្នន័យទូរសព្ទចល័តដំណើរការជានិច្ច"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ការ​បង្កើនល្បឿន​ផ្នែករឹងសម្រាប់​ការភ្ជាប់"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"បង្ហាញ​ឧបករណ៍​ប្ល៊ូធូស​គ្មានឈ្មោះ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"មិន​អាចភ្ជាប់​បានទេ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"បង្ហាញ​ជម្រើស​សម្រាប់​សេចក្តីបញ្ជាក់ការបង្ហាញ​ឥត​ខ្សែ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"បង្កើនកម្រិតកំណត់ហេតុ Wi-Fi បង្ហាញក្នុង SSID RSSI ក្នុងកម្មវិធីជ្រើសរើស Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"កាត់បន្ថយ​ការប្រើប្រាស់ថ្ម និងកែលម្អប្រតិបត្តិការ​បណ្ដាញ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"មានការកំណត់"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"មិនមានការកំណត់"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ទំហំកន្លែងផ្ទុករបស់ logger"</string>
@@ -400,8 +402,8 @@
     <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"ថេប្លេត​អាចនឹង​បិទក្នុង​ពេលបន្តិច​ទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ឧបករណ៍​អាចនឹង​បិទក្នុង​ពេលបន្តិច​ទៀត (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"សល់ <xliff:g id="TIME">%1$s</xliff:g> ទើប​សាកថ្ម​ពេញ"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់សាកពេញ"</string>
+    <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ទៀតទើបសាកថ្មពេញ"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"មិន​ស្គាល់"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូល​ថ្ម"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"កំពុង​សាក​ថ្ម"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 59adfb7..97eed0f 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ನೆಟ್‌ವರ್ಕಿಂಗ್"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ವೈರ್‌ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ವೆರ್ಬೋಸ್ ಲಾಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ವೈ-ಫೈ ಸ್ಕ್ಯಾನ್ ನಿರ್ಬಂಧಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ಮೊಬೈಲ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ಟೆಥರಿಂಗ್‍‍ಗಾಗಿ ಹಾರ್ಡ್‍ವೇರ್ ವೇಗವರ್ಧನೆ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ಹೆಸರುಗಳಿಲ್ಲದ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ತೋರಿಸಿ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ವೈರ್‌ಲೆಸ್‌‌‌ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ತೋರಿಸು"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ಲಾಗಿಂಗ್ ಮಟ್ಟನ್ನು ಹೆಚ್ಚಿಸಿ, Wi‑Fi ಆಯ್ಕೆಯಲ್ಲಿ ಪ್ರತಿಯೊಂದು SSID RSSI ತೋರಿಸಿ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ಬ್ಯಾಟರಿ ಹೆಚ್ಚು ಬಾಳಿಕೆ ಬರುವಂತೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ನೆಟ್‌ವರ್ಕ್‌ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ಮೀಟರ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ಮೀಟರ್ ಮಾಡಲಾಗಿಲ್ಲ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ಲಾಗರ್ ಬಫರ್ ಗಾತ್ರಗಳು"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index f195b33..8f8bbc1 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"네트워크"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"무선 디스플레이 인증서"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi 상세 로깅 사용"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi 검색 제한"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"항상 모바일 데이터 활성화"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"테더링 하드웨어 가속"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"이름이 없는 블루투스 기기 표시"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"연결할 수 없음"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"무선 디스플레이 인증서 옵션 표시"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi 로깅 수준을 높이고, Wi‑Fi 선택도구에서 SSID RSSI당 값을 표시"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"배터리 소모를 줄이고 네트워크 성능 개선"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"종량제 네트워크"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"무제한 네트워크"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"로거 버퍼 크기"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 187c0f7..435ce53 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Тармактар"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Зымсыз мониторлорду тастыктамалоо"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi дайын-даректүү журналы"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi тармактарын издөөнү жөнгө салуу"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилдик Интернет иштей берет"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Модем режиминде аппараттын иштешин тездетүү"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Аталышсыз Bluetooth түзмөктөрү көрсөтүлсүн"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Туташпай койду"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Зымсыз мониторлорду тастыктамалоо параметрлери көрүнүп турат"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi тандалганда ар бир SSID үчүн RSSI көрүнүп турат"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Батареянын коротулушун чектеп, тармактын иштешин жакшыртат"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Трафик ченелет"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Чектелбеген тармак"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Журнал буферинин өлчөмү"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 59ad7cc..ed88bc5 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ການ​ສ້າງເຄືອຂ່າຍ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ສະແດງການຮັບຮອງຂອງລະບົບໄຮ້ສາຍ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"​ເປີດ​ນຳ​ໃຊ້ການ​ເກັບ​ປະ​ຫວັດ​ Verbose Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ການຈຳກັດການສະແກນ Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ເປີດໃຊ້ອິນເຕີເນັດມືຖືຕະຫຼອດເວລາ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ເປີດໃຊ້ການເລັ່ງຄວາມໄວດ້ວຍຮາດແວ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ສະແດງອຸປະກອນ Bluetooth ທີ່ບໍ່ມີຊື່"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ບໍ່ສາມາດເຊື່ອມຕໍ່ໄດ້"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ສະແດງໂຕເລືອກສຳລັບການສະແດງການຮັບຮອງລະບົບໄຮ້ສາຍ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ເພີ່ມ​ລະ​ດັບ​ການ​ເກັບ​ປະ​ຫວັດ Wi‑Fi, ສະ​ແດງ​ຕໍ່ SSID RSSI ​ໃນ​ Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ຫຼຸດການໃຊ້ແບັດເຕີຣີ ແລະ ປັບປຸງປະສິດທິພາບເຄືອຂ່າຍ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ມີການວັດແທກ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ບໍ່ໄດ້ວັດແທກ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ຂະໜາດບັບເຟີຕົວບັນທຶກ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index bde71e3..c10bd00 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Tinklai"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Belaidžio rodymo sertifikavimas"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Įgal. „Wi‑Fi“ daugiaž. įraš. į žurnalą"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"„Wi‑Fi“ nuskaitymo ribojimas"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiliojo ryšio duomenys visada suaktyvinti"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Įrenginio kaip modemo naudojimo aparatinės įrangos spartinimas"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Rodyti „Bluetooth“ įrenginius be pavadinimų"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Prisijungti nepavyko"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rodyti belaidžio rodymo sertifikavimo parinktis"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Padidinti „Wi‑Fi“ įrašymo į žurnalą lygį, rodyti SSID RSSI „Wi-Fi“ rinkiklyje"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Sumažinamas akumuliatoriaus eikvojimas ir patobulinamas tinklo našumas"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Matuojamas"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Neišmatuotas"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Registruotuvo buferio dydžiai"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 5a1805a..8feb5ab 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Tīklošana"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Bezvadu attēlošanas sertifikācija"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Iespējot Wi‑Fi detalizēto reģistrēšanu"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi meklēšanas ierobežošana"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Vienmēr aktīvs mobilo datu savienojums"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Paātrināta aparatūras darbība piesaistei"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Rādīt Bluetooth ierīces bez nosaukumiem"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nevarēja izveidot savienojumu."</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rādīt bezvadu attēlošanas sertifikācijas iespējas"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Palieliniet Wi‑Fi reģistrēšanas līmeni; rādīt katram SSID RSSI Wi‑Fi atlasītājā."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Samazina akumulatora izlādi un uzlabo tīkla veiktspēju"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Maksas"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Bezmaksas"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Reģistrētāja buferu lielumi"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 5be177d..dda3462 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Вмрежување"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Приказ на сертификација на безжична мрежа"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Овозможи преопширно пријавување Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Регулирање на скенирањето за Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилниот интернет е секогаш активен"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско забрзување за врзување"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Прикажувај уреди со Bluetooth без имиња"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не може да се поврзе"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Покажи ги опциите за безжичен приказ на сертификат"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Зголеми Wi‑Fi ниво на пријавување, прикажи по SSID RSSI во Wi‑Fi бирач"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Го намалува искористувањето на батеријата и ја подобрува изведбата на мрежата"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Со ограничен интернет"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Без ограничен интернет"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Величини на меѓумеморија за дневникот"</string>
@@ -260,7 +262,7 @@
     <string name="allow_mock_location_summary" msgid="317615105156345626">"Овозможи лажни локации"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"Овозможете проверка на атрибутот на приказот"</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Секогаш држи го активен мобилниот интернет, дури и при активно Wi-Fi (за брзо префрлување мрежа)."</string>
-    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Ако е достапно, користете хардверско забрзување за врзување"</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Ако е достапно, користи хардверско забрзување за врзување"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Овозможи отстранување грешки на USB?"</string>
     <string name="adb_warning_message" msgid="7316799925425402244">"Отстранувањето грешки на USB е наменето само за целите на развој. Користете го за копирање податоци меѓу вашиот компјутер и вашиот уред, за инсталирање апликации на вашиот уред без известување и за читање евиденција на податоци."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Отповикај пристап кон отстранување грешка од USB од сите претходно овластени компјутери?"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index d3ebd99..7016b7f 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"നെറ്റ്‍വര്‍ക്കിംഗ്"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"വയർലെസ് ഡിസ്‌പ്ലേ സർട്ടിഫിക്കേഷൻ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"വൈഫൈ വെർബോസ് ലോഗിംഗ് പ്രവർത്തനക്ഷമമാക്കുക"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"വൈഫൈ സ്‌കാൻ പ്രവർത്തനരഹിതമാക്കുന്നു"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"മൊബൈൽ ഡാറ്റ എല്ലായ്‌പ്പോഴും സജീവം"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ടെതറിംഗ് ഹാർഡ്‌വെയർ ത്വരിതപ്പെടുത്തൽ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"പേരില്ലാത്ത Bluetooth ഉപകരണങ്ങൾ കാണിക്കുക"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"കണക്റ്റ് ചെയ്യാനായില്ല"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"വയർലെസ് ഡിസ്‌പ്ലേ സർട്ടിഫിക്കേഷനായി ഓപ്‌ഷനുകൾ ദൃശ്യമാക്കുക"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"വൈഫൈ പിക്കറിൽ ഓരോ SSID RSSI പ്രകാരം കാണിക്കാൻ വൈഫൈ ലോഗിംഗ് നില വർദ്ധിപ്പിക്കുക"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ബാറ്ററി ചാർജ് വേഗത്തിൽ തീരുന്ന അവസ്ഥ കുറച്ച് നെറ്റ്‌വർക്ക് പ്രകടനം മെച്ചപ്പെടുത്തുന്നു"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"മീറ്റർചെയ്ത"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"മീറ്റർമാപകമല്ലാത്തത്"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ലോഗർ ബഫർ വലുപ്പം"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 46029c7..80e78a3 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Сүлжээ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Утасгүй дэлгэцийн сертификат"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi дэлгэрэнгүй лог-г идэвхжүүлэх"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi скан бууруулалт"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобайл дата байнга идэвхтэй"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Модем болгох техник хангамжийн хурдасгуур"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Нэргүй Bluetooth төхөөрөмжийг харуулах"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Холбогдож чадсангүй"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Утасгүй дэлгэцийн сертификатын сонголтыг харуулах"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi лог-н түвшинг нэмэгдүүлэх, Wi‑Fi Сонгогч дээрх SSID-д ногдох RSSI-г харуулах"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Батарей зарцуулалтыг бууруулж, сүлжээний гүйцэтгэлийг сайжруулдаг"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Хязгаартай"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Хязгааргүй"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Логгерын буферын хэмжээ"</string>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index a364db9..7b46760 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -145,9 +145,9 @@
   </string-array>
   <string-array name="bluetooth_audio_active_device_summaries">
     <item msgid="4862957058729193940"></item>
-    <item msgid="6481691720774549651">", अॅक्टिव्ह"</item>
-    <item msgid="8962366465966010158">", अॅक्टिव्ह (मीडिया)"</item>
-    <item msgid="4046665544396189228">", अॅक्टिव्ह (फोन)"</item>
+    <item msgid="6481691720774549651">", अ‍ॅक्टिव्ह"</item>
+    <item msgid="8962366465966010158">", अ‍ॅक्टिव्ह (मीडिया)"</item>
+    <item msgid="4046665544396189228">", अ‍ॅक्टिव्ह (फोन)"</item>
   </string-array>
   <string-array name="select_logd_size_titles">
     <item msgid="8665206199209698501">"बंद"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 5f6acf1..54723a8 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -34,7 +34,7 @@
     <string name="wifi_check_password_try_again" msgid="516958988102584767">"पासवर्ड तपासा आणि पुन्‍हा प्रयत्‍न करा"</string>
     <string name="wifi_not_in_range" msgid="1136191511238508967">"परिक्षेत्रामध्ये नाही"</string>
     <string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"स्वयंचलितपणे कनेक्ट करणार नाही"</string>
-    <string name="wifi_no_internet" msgid="4663834955626848401">"इंटरनेट अॅक्सेस नाही"</string>
+    <string name="wifi_no_internet" msgid="4663834955626848401">"इंटरनेट अ‍ॅक्सेस नाही"</string>
     <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> द्वारे सेव्ह केले"</string>
     <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s द्वारे स्वयंचलितपणे कनेक्ट केले"</string>
     <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदात्याद्वारे स्वयंचलितपणे कनेक्ट केले"</string>
@@ -46,7 +46,7 @@
     <string name="wifi_limited_connection" msgid="7717855024753201527">"मर्यादित कनेक्शन"</string>
     <string name="wifi_status_no_internet" msgid="5784710974669608361">"इंटरनेट नाही"</string>
     <string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन करणे आवश्यक आहे"</string>
-    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"अॅक्सेस पॉइंट तात्पुरते भरलेले"</string>
+    <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"अ‍ॅक्सेस पॉइंट तात्पुरते भरलेले"</string>
     <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s ने कनेक्‍ट केले"</string>
     <string name="available_via_carrier" msgid="1469036129740799053">"%1$s ने उपलब्‍ध"</string>
     <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> उघडत आहे"</string>
@@ -74,21 +74,21 @@
     <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"कनेक्ट केले (फोन नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_a2dp_battery_level" msgid="3908466636369853652">"कनेक्ट केले (मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
     <string name="bluetooth_connected_no_headset_no_a2dp_battery_level" msgid="1163440823807659316">"कनेक्ट केले (फोन किंवा मीडिया नाही), बॅटरी <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string>
-    <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"अॅक्टिव्ह, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string>
-    <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"अॅक्टिव्ह, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी"</string>
+    <string name="bluetooth_active_battery_level" msgid="3149689299296462009">"अ‍ॅक्टिव्ह, <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string>
+    <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"अ‍ॅक्टिव्ह, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी"</string>
     <string name="bluetooth_battery_level" msgid="1447164613319663655">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> बॅटरी"</string>
     <string name="bluetooth_battery_level_untethered" msgid="5974406100211667177">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> बॅटरी, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> बॅटरी"</string>
-    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"अॅक्टिव्ह"</string>
+    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"अ‍ॅक्टिव्ह"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"मीडिया ऑडिओ"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"फोन कॉल"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"फाइल स्थानांतरण"</string>
     <string name="bluetooth_profile_hid" msgid="3680729023366986480">"इनपुट डिव्हाइस"</string>
-    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट अॅक्सेस"</string>
+    <string name="bluetooth_profile_pan" msgid="3391606497945147673">"इंटरनेट अ‍ॅक्सेस"</string>
     <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"संपर्क शेअरिंग"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"संपर्क सामायिकरणासाठी वापरा"</string>
     <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इंटरनेट कनेक्शन शेअररण"</string>
     <string name="bluetooth_profile_map" msgid="1019763341565580450">"मजकूर मेसेज"</string>
-    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम अॅक्सेस"</string>
+    <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम अ‍ॅक्सेस"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडिओ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडिओ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="6680721080542444257">"श्रवण यंत्रे"</string>
@@ -102,7 +102,7 @@
     <string name="bluetooth_hid_profile_summary_connected" msgid="3381760054215168689">"इनपुट डिव्हाइसवर कनेक्ट केले"</string>
     <string name="bluetooth_pan_user_profile_summary_connected" msgid="6436258151814414028">"इंटरनेट अॅक्सेससाठी डिव्हाइसशी कनेक्ट केले"</string>
     <string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"डिव्हाइससह स्थानिक इंटरनेट कनेक्शन शेअर करत आहे"</string>
-    <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"इंटरनेट अॅक्सेस करण्यासाठी वापरा"</string>
+    <string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"इंटरनेट अ‍ॅक्सेस करण्यासाठी वापरा"</string>
     <string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"नकाशासाठी वापरा"</string>
     <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"SIM प्रवेशासाठी वापरा"</string>
     <string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"मीडिया ऑडिओसाठी वापरा"</string>
@@ -113,7 +113,7 @@
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"पेअर करा"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"पेअर करा"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"रद्द करा"</string>
-    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"कनेक्‍ट केल्यावर पेअरींग तुमचे संपर्क आणि कॉल इतिहास यामध्ये अॅक्सेस देते."</string>
+    <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"कनेक्‍ट केल्यावर पेअरींग तुमचे संपर्क आणि कॉल इतिहास यामध्ये अ‍ॅक्सेस देते."</string>
     <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी जोडू शकलो नाही."</string>
     <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"अयोग्य पिन किंवा पासकीमुळे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> सह जोडू शकलो नाही."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> शी संवाद प्रस्थापित करू शकत नाही."</string>
@@ -138,15 +138,15 @@
     <string name="accessibility_wifi_security_type_none" msgid="1223747559986205423">"नेटवर्क उघडा"</string>
     <string name="accessibility_wifi_security_type_secured" msgid="862921720418885331">"सुरक्षित नेटवर्क"</string>
     <string name="process_kernel_label" msgid="3916858646836739323">"Android OS"</string>
-    <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"काढलेले अॅप्स"</string>
-    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"काढलेले अॅप्स आणि वापरकर्ते"</string>
+    <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"काढलेले अ‍ॅप्स"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"काढलेले अ‍ॅप्स आणि वापरकर्ते"</string>
     <string name="data_usage_ota" msgid="5377889154805560860">"सिस्टम अपडेट"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB टेदरिंग"</string>
     <string name="tether_settings_title_wifi" msgid="3277144155960302049">"पोर्टेबल हॉटस्पॉट"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"ब्लूटूथ टेदरिंग"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"टेदरिंग"</string>
     <string name="tether_settings_title_all" msgid="8356136101061143841">"टेदरिंग आणि पोर्टेबल हॉटस्पॉट"</string>
-    <string name="managed_user_title" msgid="8109605045406748842">"सर्व कार्य अॅप्स"</string>
+    <string name="managed_user_title" msgid="8109605045406748842">"सर्व कार्य अ‍ॅप्स"</string>
     <string name="user_guest" msgid="8475274842845401871">"अतिथी"</string>
     <string name="unknown" msgid="1592123443519355854">"अज्ञात"</string>
     <string name="running_process_item_user_label" msgid="3129887865552025943">"वापरकर्ता: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
@@ -200,7 +200,7 @@
     <string name="development_settings_not_available" msgid="4308569041701535607">"या वापरकर्त्यासाठी डेव्हलपर पर्याय उपलब्ध नाहीत"</string>
     <string name="vpn_settings_not_available" msgid="956841430176985598">"या वापरकर्त्यासाठी VPN सेटिंग्ज उपलब्ध नाहीत"</string>
     <string name="tethering_settings_not_available" msgid="6765770438438291012">"या वापरकर्त्यासाठी टेदरिंग सेटिंग्ज उपलब्ध नाहीत"</string>
-    <string name="apn_settings_not_available" msgid="7873729032165324000">"या वापरकर्त्यासाठी अॅक्सेस बिंदू नाव सेटिंग्ज उपलब्ध नाहीत"</string>
+    <string name="apn_settings_not_available" msgid="7873729032165324000">"या वापरकर्त्यासाठी अ‍ॅक्सेस बिंदू नाव सेटिंग्ज उपलब्ध नाहीत"</string>
     <string name="enable_adb" msgid="7982306934419797485">"USB डीबग करणे"</string>
     <string name="enable_adb_summary" msgid="4881186971746056635">"USB कनेक्ट केलेले असताना डीबग मोड"</string>
     <string name="clear_adb_keys" msgid="4038889221503122743">"USB डीबग करणारी प्रमाणीकरणे रीव्होक करा"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किंग"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"वायरलेस डिस्प्ले प्रमाणीकरण"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"वाय-फाय व्हर्बोझ लॉगिंग सुरू करा"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"वाय-फाय स्कॅन थ्रॉटलिंग"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा नेहमी सक्रिय"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिंग हार्डवेअर प्रवेग"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"नावांशिवाय ब्‍लूटूथ डिव्‍हाइस दाखवा"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"कनेक्ट करू शकलो नाही"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस डिस्प्ले प्रमाणिकरणाचे पर्याय दाखवा"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्‍तर वाढवा, वाय-फाय सिलेक्टरमध्‍ये प्रति SSID RSSI दर्शवा"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"बॅटरी जलदरीतीने संपण्यापासून रोखते आणि नेटवर्क परफॉर्मन्समध्ये सुधारणा करते"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"मीटरने मोजलेले"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"मीटरने न मोजलेले"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"लॉगर बफर आकार"</string>
@@ -259,14 +261,14 @@
     <string name="allow_mock_location" msgid="2787962564578664888">"बनावट स्थानांना अनुमती द्या"</string>
     <string name="allow_mock_location_summary" msgid="317615105156345626">"बनावट स्थानांना अनुमती द्या"</string>
     <string name="debug_view_attributes" msgid="6485448367803310384">"दृश्‍य विशेषता तपासणी सुरू करा"</string>
-    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"जरी वाय-फाय चालू असले तरीही, मोबाईल डेटा नेहमी चालू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string>
-    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"उपलब्ध असल्यास टेदरिंग हार्डवेअर प्रवेग वापरा"</string>
+    <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"वाय-फाय चालू असतानाही मोबाइल डेटा नेहमी सुरू ठेवा (नेटवर्क जलदरीत्या स्विच करण्यासाठी)."</string>
+    <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"उपलब्ध असल्यास टेदरिंग हार्डवेअर अॅक्सिलरेशन वापरा"</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"USB डीबग करण्यास अनुमती द्यायची?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइस वर अॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string>
-    <string name="adb_keys_warning_message" msgid="5659849457135841625">"तुम्ही पूर्वी अॉथोराइझ केलेल्या सर्व संगणकांवरुन USB डीबग करण्यासाठी अॅक्सेस रीव्होक करायचा?"</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB डीबग करण्याचा हेतू फक्त विकास उद्देशांसाठी आहे. याचा वापर तुमचा कॉंप्युटर आणि तुमचे डिव्हाइस यांच्या दरम्यान डेटा कॉपी करण्यासाठी करा, सूचनेशिवाय तुमच्या डिव्हाइस वर अ‍ॅप्स इंस्टॉल करा आणि लॉग डेटा वाचा."</string>
+    <string name="adb_keys_warning_message" msgid="5659849457135841625">"तुम्ही पूर्वी अॉथोराइझ केलेल्या सर्व संगणकांवरुन USB डीबग करण्यासाठी अ‍ॅक्सेस रीव्होक करायचा?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"विकास सेटिंग्जला अनुमती द्यायची?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"या सेटिंग्जचा हेतू फक्त विकास वापरासाठी आहे. त्यामुळे तुमचे डिव्हाइस आणि त्यावरील अॅप्लिकेशन ब्रेक होऊ शकतात किंवा नेहमीपेक्षा वेगळे वर्तन करू शकतात."</string>
-    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB वर अॅप्स पडताळून पाहा"</string>
+    <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB वर अ‍ॅप्स पडताळून पाहा"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"हानिकारक वर्तनासाठी ADB/ADT द्वारे इंस्टॉल अ‍ॅप्स तपासा."</string>
     <string name="bluetooth_show_devices_without_names_summary" msgid="2351196058115755520">"नावांशिवाय ब्‍लूटूथ डीव्‍हाइस (फक्‍त MAC पत्‍ते) दाखवले जातील"</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"रिमोट डिव्हाइसमध्ये सहन न होणारा मोठा आवाज किंवा नियंत्रणाचा अभाव यासारखी आवाजाची समस्या असल्यास ब्लूटूथ संपूर्ण आवाज वैशिष्ट्य बंद करते."</string>
@@ -288,7 +290,7 @@
     <string name="media_category" msgid="4388305075496848353">"मीडिया"</string>
     <string name="debug_monitoring_category" msgid="7640508148375798343">"परीक्षण"</string>
     <string name="strict_mode" msgid="1938795874357830695">"कठोर मोड सुरू"</string>
-    <string name="strict_mode_summary" msgid="142834318897332338">"मुख्य थ्रेडवर अॅप्स मोठी कार्ये करतात तेव्हा स्क्रीन फ्लॅश करा"</string>
+    <string name="strict_mode_summary" msgid="142834318897332338">"मुख्य थ्रेडवर अ‍ॅप्स मोठी कार्ये करतात तेव्हा स्क्रीन फ्लॅश करा"</string>
     <string name="pointer_location" msgid="6084434787496938001">"पॉइंटर स्थान"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"वर्तमान स्पर्श डेटा दर्शविणारे स्क्रीन ओव्हरले"</string>
     <string name="show_touches" msgid="2642976305235070316">"टॅप दाखवा"</string>
@@ -320,7 +322,7 @@
     <string name="transition_animation_scale_title" msgid="387527540523595875">"ट्रांझिशन अॅनिमेशन स्केल"</string>
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"अॅनिमेटर कालावधी स्केल"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"दुय्यम डिस्प्ले सिम्युलेट करा"</string>
-    <string name="debug_applications_category" msgid="4206913653849771549">"अॅप्स"</string>
+    <string name="debug_applications_category" msgid="4206913653849771549">"अ‍ॅप्स"</string>
     <string name="immediately_destroy_activities" msgid="1579659389568133959">"अॅक्टिव्हिटी ठेवू नका"</string>
     <string name="immediately_destroy_activities_summary" msgid="3592221124808773368">"वापरकर्त्याने प्रत्येक अॅक्टिव्हिटी सोडताच ती नष्ट करा"</string>
     <string name="app_process_limit_title" msgid="4280600650253107163">"पार्श्वभूमी प्रक्रिया मर्यादा"</string>
@@ -351,7 +353,7 @@
     <item msgid="8280754435979370728">"डोळ्यांनी पाहिले तसे नैसर्गिक रंग"</item>
     <item msgid="5363960654009010371">"डिजिटल सामग्रीसाठी ऑप्टिमाइझ केलेले रंग"</item>
   </string-array>
-    <string name="inactive_apps_title" msgid="9042996804461901648">"स्टँडबाय अॅप्स"</string>
+    <string name="inactive_apps_title" msgid="9042996804461901648">"स्टँडबाय अ‍ॅप्स"</string>
     <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"निष्क्रिय. टॉगल करण्यासाठी टॅप करा."</string>
     <string name="inactive_app_active_summary" msgid="4174921824958516106">"सक्रिय. टॉगल करण्यासाठी टॅप करा."</string>
     <string name="standby_bucket_summary" msgid="6567835350910684727">"अ‍ॅप स्टँडबाय स्थिती: <xliff:g id="BUCKET"> %s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 03ff0bb..3841a3b 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Perangkaian"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Pensijilan paparan wayarles"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Dayakan Pengelogan Berjela-jela Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Pendikitan pengimbasan Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Data mudah alih sentiasa aktif"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Pecutan perkakasan penambatan"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Tunjukkan peranti Bluetooth tanpa nama"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Tidak dapat menyambung"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Mengurangkan penyusutan bateri &amp; meningkatkan prestasi rangkaian"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Bermeter"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Tidak bermeter"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Saiz penimbal pengelog"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 1db26b4..38f128a 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -153,7 +153,7 @@
     <string name="launch_defaults_some" msgid="313159469856372621">"မူရင်းအချို့ သတ်မှတ်ပြီး"</string>
     <string name="launch_defaults_none" msgid="4241129108140034876">"ပုံမှန်သတ်မှတ်ထားခြင်းမရှိ"</string>
     <string name="tts_settings" msgid="8186971894801348327">"စာသားမှစကားပြောပြောင်း ဆက်တင်များ"</string>
-    <string name="tts_settings_title" msgid="1237820681016639683">"စာသားမှ အသံထွက်စေခြင်း"</string>
+    <string name="tts_settings_title" msgid="1237820681016639683">"စာသားမှ စကားပြောသို့ အထွက်"</string>
     <string name="tts_default_rate_title" msgid="6030550998379310088">"စကားပြောနှုန်း"</string>
     <string name="tts_default_rate_summary" msgid="4061815292287182801">"စာတမ်းအားပြောဆိုသော အမြန်နှုန်း"</string>
     <string name="tts_default_pitch_title" msgid="6135942113172488671">"အသံအနိမ့်အမြင့်"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ချိတ်ဆက်ဆောင်ရွက်ခြင်း"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ကြိုးမဲ့ပြသမှု အသိအမှတ်ပြုလက်မှတ်"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi Verbose မှတ်တမ်းတင်ခြင်းအား ဖွင့်မည်"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi ရှာဖွေခြင်း ထိန်းချုပ်မှု"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"မိုဘိုင်းဒေတာကို အမြဲဖွင့်ထားရန်"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ဖုန်းကို မိုဒမ်အဖြစ်အသုံးပြုမှု စက်ပစ္စည်းဖြင့် အရှိန်မြှင့်တင်ခြင်း"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"အမည်မရှိသော ဘလူးတုသ်စက်ပစ္စည်းများကို ပြသရန်"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ချိတ်ဆက်၍ မရပါ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ကြိုးမဲ့ အခင်းအကျင်း အသိအမှတ်ပြုလက်မှတ်အတွက် ရွေးချယ်စရာများပြရန်"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi မှတ်တမ်းတင်ခြင်း နှုန်းအားမြင့်ကာ၊ Wi‑Fi ရွေးရာတွင် SSID RSSI ဖြင့်ပြပါ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ဘက်ထရီ အသုံးပြုမှုကို လျှော့ကျစေပြီး ကွန်ရက်စွမ်းဆောင်ရည်ကို ပိုမိုကောင်းမွန်စေသည်"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"အခမဲ့ မဟုတ်ပါ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"အခမဲ့"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"မှတ်တမ်းကြားခံနယ် အရွယ်အစားများ"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index abb3410..144d4c2 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Nettverk"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Trådløs skjermsertifisering"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Slå på detaljert Wi-Fi-loggføring"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Begrensning av Wi‑Fi-skanning"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata er alltid aktiv"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvareakselerasjon for internettdeling"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Vis Bluetooth-enheter uten navn"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kunne ikke koble til"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis alternativer for sertifisering av trådløs skjerm"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øk Wi-Fi-loggenivå – vis per SSID RSSI i Wi-Fi-velgeren"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduserer batteriforbruket og forbedrer nettverksytelsen"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Med datamåling"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Uten datamåling"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Bufferstørrelser for logg"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 7d71fdc..f1934c3 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"नेटवर्किङ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ताररहित प्रदर्शन प्रमाणीकरण"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi-Fi वर्बोज लग सक्षम पार्नुहोस्"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi स्क्यान थ्रोटलिङ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"मोबाइल डेटा सधैँ सक्रिय राख्नुहोस्"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"टेदरिङको लागि हार्डवेयरको प्रवेग"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"नामकरण नगरिएका ब्लुटुथ यन्त्रहरू देखाउनुहोस्"</string>
@@ -246,7 +247,8 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"जडान गर्न सकिएन"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi लग स्तर बढाउनुहोस्, Wi-Fi चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string>
-    <string name="wifi_metered_label" msgid="4514924227256839725">"मिटर गरिएको जडान भनी चिन्ह लगाइएको"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ब्याट्रीको खपत कम गरी नेटवर्कको कार्यसम्पादनमा सुधार गर्दछ"</string>
+    <string name="wifi_metered_label" msgid="4514924227256839725">"सशुल्क वाइफाइ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"मिटर नगरिएको"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"लगर बफर आकारहरू"</string>
     <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"लग बफर प्रति लगर आकार चयन गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 6771da1..c50b43a 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Netwerken"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificering van draadloze weergave"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Uitgebreide wifi-logregistratie insch."</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wifi-scannen beperken"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobiele data altijd actief"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardwareversnelling voor tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth-apparaten zonder namen weergeven"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kan geen verbinding maken"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Verlaagt het batterijverbruik en verbetert de netwerkprestaties"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Met datalimiet"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Gratis"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Logger-buffergrootten"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index c4e554b..5725c22 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ନେଟ୍‌ୱର୍କିଙ୍ଗ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ୱାୟରଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"ୱାଇ-ଫାଇ ଭର୍ବୋସ୍‌ ଲଗିଙ୍ଗ ସକ୍ଷମ କରନ୍ତୁ"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ୱାଇ-ଫାଇ ସ୍କାନ୍ ନିୟନ୍ତ୍ରଣ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ମୋବାଇଲ୍‌ ଡାଟା ସର୍ବଦା ସକ୍ରିୟ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ଟିଥରିଙ୍ଗ ହାର୍ଡୱେର ଆକ୍ସିଲିରେସନ୍"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ବ୍ଲୁଟୂଥ୍‍‌ ଡିଭାଇସ୍‌ଗୁଡ଼ିକୁ ନାମ ବିନା ଦେଖନ୍ତୁ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ୱେୟାରଲେସ୍‌ ଡିସ୍‌ପ୍ଲେ ସାର୍ଟିଫିକେସନ୍ ପାଇଁ ବିକଳ୍ପ ଦେଖାନ୍ତୁ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ୱାଇ-ଫାଇ ଲଗିଙ୍ଗ ସ୍ତର ବଢ଼ାନ୍ତୁ, ୱାଇ-ଫାଇ ପିକର୍‌ରେ ପ୍ରତି SSID RSSI ଦେଖାନ୍ତୁ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ବ୍ୟାଟେରୀ ଖର୍ଚ୍ଚ କମ୍ ଏବଂ ନେଟ୍‌ୱାର୍କ କାର୍ଯ୍ୟକ୍ଷମତା ଉନ୍ନତ କରିଥାଏ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ମପାଯାଉଥିବା"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ମପାଯାଉନଥିବା"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ଲଗର୍‌ ବଫର୍‌ ସାଇଜ୍"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 6fff4d8..faccda7 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ਨੈੱਟਵਰਕਿੰਗ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"ਵਾਈ-ਫਾਈ ਵਰਬੋਸ ਲੌਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"ਸੀਮਤ ਵਾਈ‑ਫਾਈ ਸਕੈਨ"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ਮੋਬਾਈਲ ਡਾਟਾ ਹਮੇਸ਼ਾਂ ਕਿਰਿਆਸ਼ੀਲ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ਟੈਦਰਿੰਗ ਹਾਰਡਵੇਅਰ ਐਕਸੈੱਲਰੇਸ਼ਨ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"ਅਨਾਮ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਦਿਖਾਓ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈੱਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਪ੍ਰਦਰਸ਼ਿਤ ਕਰੋ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ਵਾਈ‑ਫਾਈ ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, ਵਾਈ‑ਫਾਈ Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਘਟਾ ਕੇ ਨੈੱਟਵਰਕ ਕਾਰਗੁਜ਼ਾਰੀ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਂਦਾ ਹੈ"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ਗੈਰ-ਮੀਟਰਬੱਧ ਕੀਤਾ ਗਿਆ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ਲੌਗਰ ਬਫ਼ਰ ਆਕਾਰ"</string>
@@ -401,7 +403,7 @@
     <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"ਡੀਵਾਈਸ ਛੇਤੀ ਹੀ ਬੰਦ ਹੋ ਸਕਦਾ ਹੈ (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਲਈ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
-    <string name="power_charging_duration" msgid="4676999980973411875">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਤੱਕ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਪੂਰੀ ਤਰ੍ਹਾਂ ਚਾਰਜ ਹੋਣ ਵਿੱਚ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_info_status_unknown" msgid="196130600938058547">"ਅਗਿਆਤ"</string>
     <string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="battery_info_status_charging_lower" msgid="8689770213898117994">"ਚਾਰਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index bed4d63..60a4c53 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Sieci"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Wyświetlacz bezprzewodowy"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Szczegółowy dziennik Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Ograniczanie skanowania Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilna transmisja danych zawsze aktywna"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Akceleracja sprzętowa tetheringu"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Pokaż urządzenia Bluetooth bez nazw"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nie udało się połączyć"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Zmniejsza zużycie baterii i zwiększa wydajność sieci"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Użycie danych jest mierzone"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Użycie danych nie jest mierzone"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Rozmiary bufora rejestratora"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 7a5522e..dd0a75b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro detalhado de Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitar busca por Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível conectar"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro de Wi-Fi; mostrar conforme o RSSI do SSID no seletor de Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduz o consumo de bateria e melhora o desempenho da rede"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Limitada"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Ilimitada"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 3b0b86c..501cf50 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de display sem fios"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar o registo verboso de Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Controlo da procura de Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware para ligação (à Internet) via telemóvel"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível estabelecer ligação"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções da certificação de display sem fios"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduz o consumo rápido da bateria e melhora o desempenho da rede"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Acesso limitado"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Acesso ilimitado"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos da memória intermédia do registo"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 7a5522e..dd0a75b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Redes"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Ativar registro detalhado de Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitar busca por Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dados móveis sempre ativos"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Aceleração de hardware de tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Mostrar dispositivos Bluetooth sem nomes"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Não foi possível conectar"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro de Wi-Fi; mostrar conforme o RSSI do SSID no seletor de Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduz o consumo de bateria e melhora o desempenho da rede"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Limitada"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Ilimitada"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Tamanhos de buffer de logger"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index b4fd3fa..fb020e2 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Conectare la rețele"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certificare Ecran wireless"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Înregistrare prin Wi-Fi de volume mari de date"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Limitare căutare de rețele Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Date mobile permanent active"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Accelerare hardware pentru tethering"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Afișați dispozitivele Bluetooth fără nume"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nu s-a putut conecta"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afișați opțiunile pentru certificarea Ecran wireless"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Reduce descărcarea bateriei și îmbunătățește performanța rețelei"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Contorizată"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Necontorizată"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Dimensiunile memoriei temporare a jurnalului"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 657e6a9..806be6e 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -60,7 +60,7 @@
     <string name="speed_label_medium" msgid="3175763313268941953">"Средняя"</string>
     <string name="speed_label_fast" msgid="7715732164050975057">"Быстрая"</string>
     <string name="speed_label_very_fast" msgid="2265363430784523409">"Очень быстрая"</string>
-    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="DESCRIPTION">%2$s</xliff:g>: <xliff:g id="STATE">%1$s</xliff:g>"</string>
+    <string name="preference_summary_default_combination" msgid="8532964268242666060">"<xliff:g id="STATE">%1$s</xliff:g> / <xliff:g id="DESCRIPTION">%2$s</xliff:g>"</string>
     <string name="bluetooth_disconnected" msgid="6557104142667339895">"Нет подключения"</string>
     <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Отключение..."</string>
     <string name="bluetooth_connecting" msgid="8555009514614320497">"Подключение..."</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Сети"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Серт. беспроводн. мониторов"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Подробный журнал Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Ограничивать поиск сетей Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Не отключать мобильный Интернет"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Аппаратное ускорение в режиме модема"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показывать Bluetooth-устройства без названий"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ошибка подключения"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показывать параметры сертификации беспроводных мониторов"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Вести подробный журнал, показывать RSSI для каждого SSID при выборе сети"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Уменьшает расход заряда батареи и улучшает работу сети"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Сеть с тарификацией трафика"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Сеть без тарификации трафика"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Размер буфера журнала"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index f499253..925d5b4 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"ජාලකරණය"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"නොරැහැන් සංදර්ශක සහතිකය"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"විස්තරාත්මක Wi‑Fi ලොග් කිරීම සබල කරන්න"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi ස්කෑන් අවකරණය"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"ජංගම දත්ත සැමවිට ක්‍රියාකාරීය"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ටෙදරින් දෘඪාංග ත්වරණය"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"නම් නොමැති බ්ලූටූත් උපාංග පෙන්වන්න"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"සම්බන්ධ වීමට නොහැකි විය"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"නොරැහැන් සංදර්ශක සහතිකය සඳහා විකල්ප පෙන්වන්න"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ලොග් මට්ටම වැඩි කරන්න, Wi‑Fi තෝරනයෙහි SSID RSSI අනුව පෙන්වන්න"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"බැටරි බැසීම අඩු කරන අතර ජාල කාර්ය සාධනය වැඩි දියුණු කරයි"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"මනිනු ලැබේ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"මනින්නේ නැත"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ලෝගයේ අන්තරාවක ප්‍රමාණය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index a7895c4..e28825c 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -91,8 +91,8 @@
     <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Prístup k SIM karte"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD zvuk: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD zvuk"</string>
-    <string name="bluetooth_profile_hearing_aid" msgid="6680721080542444257">"Načúvacie pomôcky"</string>
-    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="3051944447369418317">"Pripojené k načúvacím pomôckam"</string>
+    <string name="bluetooth_profile_hearing_aid" msgid="6680721080542444257">"Načúvadlá"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="3051944447369418317">"Pripojené k načúvadlám"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="963376081347721598">"Pripojené ku zvukovému médiu"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="7661070206715520671">"Pripojené ku zvuku telefónu"</string>
     <string name="bluetooth_opp_profile_summary_connected" msgid="2611913495968309066">"Pripojené na server pre prenos údajov"</string>
@@ -109,7 +109,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Použiť pre zvuk telefónu"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Použiť na prenos súborov"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="232727040453645139">"Použiť pre vstup"</string>
-    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="8843499209204010224">"Použiť pre načúvacie pomôcky"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="8843499209204010224">"Použiť pre načúvadlá"</string>
     <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Párovať"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"PÁROVAŤ"</string>
     <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Zrušiť"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Siete"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikácia bezdrôtového zobrazenia"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Podrobné denníky Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Pribrzdenie vyhľadávania sietí Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobilné dáta ponechať vždy aktívne"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardvérová akcelerácia tetheringu"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Zobrazovať zariadenia Bluetooth bez názvov"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nepodarilo sa pripojiť"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi‑Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Znižuje používanie batérie a zlepšuje výkon siete"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Merané"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Bez merania dát"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Vyrovnávacia pamäť nástroja denníkov"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 4c2441a..b16d5d9 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Omrežja"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Potrdilo brezžičnega zaslona"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Omogoči podrobno zapisovanje dnevnika za Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Omejevanje iskanja omrežij Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Prenos podatkov v mobilnem omrežju je vedno aktiven"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Strojno pospeševanje za internetno povezavo prek mobilnega telefona"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Prikaži naprave Bluetooth brez imen"</string>
@@ -245,7 +246,8 @@
     <string name="private_dns_mode_provider_hostname_hint" msgid="2487492386970928143">"Vnesite ime gostitelja pri ponudniku DNS"</string>
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Povezave ni bilo mogoče vzpostaviti"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži možnosti za potrdilo brezžičnega zaslona"</string>
-    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapis. dnev. za Wi-Fi; v izbir. Wi‑Fi-ja pokaži glede na SSID RSSI"</string>
+    <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapisovanja dnevnika za Wi-Fi; v izbirniku Wi‑Fi-ja pokaži glede na SSID RSSI"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Zmanjša porabo energije akumulatorja in izboljša delovanje omrežja"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Omejen prenos podatkov"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Z neomejenim prenosom podatkov"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Velikosti medpomnilnikov zapisovalnika dnevnika"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index b5f93e4..7a054bb 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Rrjetet"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifikimi i ekranit valor"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivizo hyrjen Wi-Fi Verbose"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Përshpejtimi i skanimit të Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Të dhënat celulare gjithmonë aktive"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Përshpejtimi i harduerit për ndarjen e lidhjes (internet)"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Shfaq pajisjet me Bluetooth pa emra"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Nuk mund të lidhej"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Shfaq opsionet për certifikimin e ekranit valor"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Zvogëlon shkarkimin e baterisë dhe përmirëson cilësinë e funksionimit të rrjetit"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Me matje"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Pa matje"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Madhësitë e regjistruesit"</string>
@@ -305,7 +307,7 @@
     <string name="simulate_color_space" msgid="6745847141353345872">"Simulo hapësirën e ngjyrës"</string>
     <string name="enable_opengl_traces_title" msgid="6790444011053219871">"Aktivizo gjurmët e OpenGL-së"</string>
     <string name="usb_audio_disable_routing" msgid="8114498436003102671">"Çaktivizo rrugëzuezin e audios përmes USB-së"</string>
-    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Çaktivizo rrugëzuesin automatik për te kufjet ose altoparlantët"</string>
+    <string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Çaktivizo router-in automatik për te kufjet ose altoparlantët"</string>
     <string name="debug_layout" msgid="5981361776594526155">"Shfaq konturet e kuadrit"</string>
     <string name="debug_layout_summary" msgid="2001775315258637682">"Shfaq konturet e klipit, hapësirat etj."</string>
     <string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Detyro drejtimin e shkrimit nga e djathta në të majtë"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 2a6e328..0edc985 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Умрежавање"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сертификација бежичног екрана"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Омогући детаљнију евиденцију за Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Успоравање Wi-Fi скенирања"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Мобилни подаци су увек активни"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Хардверско убрзање привезивања"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Прикажи Bluetooth уређаје без назива"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Повезивање није успело"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Приказ опција за сертификацију бежичног екрана"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Смањује потрошњу батерије и побољшава учинак мреже"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Са ограничењем"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Без ограничења"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Величине бафера података у програму за евидентирање"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 9778516..862fc6c 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Nätverk"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certifiering för Wi-Fi-skärmdelning"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Aktivera utförlig loggning för Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Begränsning av Wi-Fi-sökning"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobildata alltid aktiverad"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Maskinvaruacceleration för internetdelning"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Visa namnlösa Bluetooth-enheter"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Kan inte ansluta"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Visa certifieringsalternativ för Wi-Fi-skärmdelning"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Öka loggningsnivån för Wi-Fi, visa per SSID RSSI i Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Sänker batteriförbrukningen och förbättrar nätverksprestandan"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Med datapriser"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Utan datapriser"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Buffertstorlekar för logg"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 35a9954..12922ca 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -78,7 +78,7 @@
     <string name="bluetooth_active_battery_level_untethered" msgid="6662649951391456747">"Inatumika, L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ya betri, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ya betri"</string>
     <string name="bluetooth_battery_level" msgid="1447164613319663655">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="bluetooth_battery_level_untethered" msgid="5974406100211667177">"L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> ya betri, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> ya betri"</string>
-    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Unaendelea"</string>
+    <string name="bluetooth_active_no_battery_level" msgid="8380223546730241956">"Kimeunganishwa"</string>
     <string name="bluetooth_profile_a2dp" msgid="2031475486179830674">"Media ya sauti"</string>
     <string name="bluetooth_profile_headset" msgid="7815495680863246034">"Simu"</string>
     <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Uhamishaji wa faili"</string>
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Mtandao"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Chaguo za cheti cha kuonyesha pasiwaya"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Washa Uwekaji kumbukumbu za WiFi kutumia Sauti"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Kudhibiti utafutaji wa Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Iendelee kutumia data ya simu"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Kuongeza kasi kwa kutumia maunzi ili kusambaza mtandao"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Onyesha vifaa vya Bluetooth visivyo na majina"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Imeshindwa kuunganisha"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Onyesha chaguo za cheti cha kuonyesha pasiwaya"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Ongeza hatua ya uwekaji kumbukumbu ya Wi-Fi, onyesha kwa kila SSID RSSI kwenye Kichukuzi cha Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Hupunguza matumizi ya chaji ya betri na kuboresha utendaji wa mtandao"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Mtandao unapima data"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Mtandao usiopima data"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Ukubwa wa kiweka bafa ya kumbukumbu"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 6b5b056..cf442b7 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"நெட்வொர்க்கிங்"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"வயர்லெஸ் காட்சிக்கான சான்றிதழ்"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"வைஃபை அதிவிவர நுழைவை இயக்கு"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"வைஃபை ஸ்கேனிங்கை வரம்பிடுதல்"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"மொபைல் டேட்டாவை எப்போதும் இயக்கத்திலேயே வை"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"வன்பொருள் விரைவுப்படுத்துதல் இணைப்பு முறை"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"பெயர்கள் இல்லாத புளூடூத் சாதனங்களைக் காட்டு"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"இணைக்க முடியவில்லை"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டு"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"வைஃபை நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"பேட்டரி தீர்ந்துபோவதைக் குறைத்து நெட்வொர்க்கின் செயல்திறனை மேம்படுத்தும்"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"கட்டண நெட்வொர்க்"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"கட்டணமில்லா நெட்வொர்க்"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"லாகர் பஃபர் அளவுகள்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index d3dfda3..83636dc 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"నెట్‌వర్కింగ్"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"వైర్‌లెస్ ప్రదర్శన ప్రామాణీకరణ"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi విశదీకృత లాగింగ్‌ను ప్రారంభించండి"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi స్కాన్ కుదింపు"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"మొబైల్ డేటాని ఎల్లప్పుడూ యాక్టివ్‌గా ఉంచు"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"టెథెరింగ్ హార్డ్‌వేర్ వేగవృద్ధి"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"పేర్లు లేని బ్లూటూత్ పరికరాలు  చూపించు"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"కనెక్ట్ చేయడం సాధ్యపడలేదు"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"వైర్‌లెస్ ప్రదర్శన సర్టిఫికెట్ కోసం ఎంపికలను చూపు"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"బ్యాటరీ శక్తి వినియోగాన్ని తగ్గించి &amp; నెట్‌వర్క్ పనితీరును మెరుగుపరుస్తుంది"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"గణించబడుతోంది"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"గణించబడటం లేదు"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"లాగర్ బఫర్ పరిమాణాలు"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 4f8b9e4..0b184d2 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"เครือข่าย"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"การรับรองการแสดงผลแบบไร้สาย"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"เปิดใช้การบันทึกรายละเอียด Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"การควบคุมการสแกนหา Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"เปิดใช้เน็ตมือถือเสมอ"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"การเร่งฮาร์ดแวร์การเชื่อมต่ออินเทอร์เน็ตผ่านมือถือ"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"แสดงอุปกรณ์บลูทูธที่ไม่มีชื่อ"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"เชื่อมต่อไม่ได้"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"แสดงตัวเลือกสำหรับการรับรองการแสดงผล แบบไร้สาย"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"ลดการเปลืองแบตเตอรี่และเพิ่มประสิทธิภาพเครือข่าย"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"มีการวัดปริมาณอินเทอร์เน็ต"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"ไม่มีการวัดปริมาณอินเทอร์เน็ต"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"ขนาดบัฟเฟอร์ของตัวบันทึก"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index bc33509..85b6438 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Networking"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Certification ng wireless display"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"I-enable ang Pagla-log sa Wi‑Fi Verbose"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Pag-throttle ng pag-scan ng Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Palaging aktibo ang mobile data"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Hardware acceleration para sa pag-tether"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Ipakita ang mga Bluetooth device na walang pangalan"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Hindi makakonekta"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ipakita ang mga opsyon para sa certification ng wireless display"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Pataasin ang antas ng Wi‑Fi logging, ipakita sa bawat SSID RSSI sa Wi‑Fi Picker"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Binabawasan ang pagkaubos ng baterya at pinapahusay ang performance ng network"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Nakametro"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Hindi Nakametro"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Mga laki ng buffer ng Logger"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 9c89b58..6031eca 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Ağ işlemleri"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Kablosuz ekran sertifikası"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Kablosuz Ayrıntılı Günlük Kaydını etkinleştir"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Kablosuz ağ taramasını kısma"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil veri her zaman etkin"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tethering donanım hızlandırıcısı"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Adsız Bluetooth cihazlarını göster"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Bağlanılamadı"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Kablosuz ekran sertifikası seçeneklerini göster"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Kablosuz günlük kaydı seviyesini artır. Kablosuz Seçici\'de her bir SSID RSSI için göster."</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Pili daha az harcar ve ağ performansını iyileştirir"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Sayaçlı"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Sayaçsız"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Günlük Kaydedici arabellek boyutları"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 278928b..5f3c6a6 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Мережі"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Сертифікація бездрот. екрана"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Докладний запис у журнал Wi-Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Зменшити радіус пошуку мереж Wi‑Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Не вимикати мобільне передавання даних"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Апаратне прискорення під час використання телефона в режимі модема"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Показувати пристрої Bluetooth без назв"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Не вдалося під’єднатися"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показати параметри сертифікації бездротового екрана"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Показувати в журналі RSSI для кожного SSID під час вибору Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Зменшує споживання заряду акумулятора й підвищує ефективність роботи мережі"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"З тарифікацією трафіку"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Без тарифікації трафіку"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Розміри буфера журналу"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 8ab1c23..82d9b3f 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"نیٹ ورکنگ"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"وائرلیس ڈسپلے سرٹیفیکیشن"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"‏Wi‑Fi وربوس لاگنگ فعال کریں"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"‏Wi‑Fi اسکین کو زبردستی روکا جا رہا ہے"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"موبائل ڈیٹا ہمیشہ فعال رکھیں"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"ٹیدرنگ ہارڈویئر سرعت کاری"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"بغیر نام والے بلوٹوتھ آلات دکھائیں"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"منسلک نہیں ہو سکا"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"وائرلیس ڈسپلے سرٹیفیکیشن کیلئے اختیارات دکھائیں"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏Wi‑Fi لاگنگ لیول میں اضافہ کریں، Wi‑Fi منتخب کنندہ میں فی SSID RSSI دکھائیں"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"بیٹری ڈرین کم کرتا ہے اور نیٹ ورک کارکردگی کو بہتر بناتا ہے"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"میٹرڈ"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"غیر میٹر شدہ"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"لاگر بفر کے سائز"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 2bcb450..5dca475 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Tarmoqlar"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Simsiz monitor sertifikatlari"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Batafsil Wi-Fi jurnali"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi tarmoqni taqsimlab skanlash"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Mobil internet doim yoniq tursin"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Modem rejimida apparatli tezlashtirish"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bluetooth qurilmalarini nomlarisiz ko‘rsatish"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ulanmadi"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz monitorlarni sertifikatlash parametrini ko‘rsatish"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi ulanishini tanlashda har bir SSID uchun jurnalda ko‘rsatilsin"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Batareya sarfini tejaydi va tarmoq samaradorligini oshiradi"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Trafik hisoblanadigan tarmoq"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Trafik hisobi yuritilmaydigan tarmoq"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Jurnal buferi hajmi"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 26fa772..4e2d6fa 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Mạng"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Chứng nhận hiển thị không dây"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Bật ghi nhật ký chi tiết Wi‑Fi"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Hạn chế quét tìm Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Dữ liệu di động luôn hoạt động"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"Tăng tốc phần cứng khi chia sẻ kết nối"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Hiển thị các thiết bị Bluetooth không có tên"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Không thể kết nối"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Hiển thị tùy chọn chứng nhận hiển thị không dây"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tăng mức ghi nhật ký Wi‑Fi, hiển thị mỗi SSID RSSI trong bộ chọn Wi‑Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Giảm hao pin và cải thiện hiệu suất mạng"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Đo lượng dữ liệu"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Không đo lượng dữ liệu"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Kích thước bộ đệm của trình ghi nhật ký"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 8685c10..460142c 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"网络"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"无线显示认证"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"启用 WLAN 详细日志记录功能"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"WLAN 扫描调节"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"始终开启移动数据网络"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"网络共享硬件加速"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"显示没有名称的蓝牙设备"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"无法连接"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"显示无线显示认证选项"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"提升 WLAN 日志记录级别(在 WLAN 选择器中显示每个 SSID 的 RSSI)"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"降低耗电量以及改善网络性能"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"按流量计费"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"不按流量计费"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"日志记录器缓冲区大小"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 9cc87bd..286765d 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"網絡"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細記錄"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi‑Fi 掃瞄限流"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"一律保持啟用流動數據"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"網絡共享硬件加速"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"顯示沒有名稱的藍牙裝置"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"無法連線"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"減低耗電量並改善網絡表現"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"按用量收費"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"不限數據用量收費"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 1201938..e85199f 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"網路連線"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"無線螢幕分享認證"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"啟用 Wi‑Fi 詳細記錄設定"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"Wi-Fi 掃描調節"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"行動數據連線一律保持啟用狀態"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"數據連線硬體加速"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"顯示沒有名稱的藍牙裝置"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"無法連線"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細記錄"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"降低耗電量以及改善網路效能"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"計量付費"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"非計量付費"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"記錄器緩衝區空間"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 9ea73fa..1bfbf07 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -220,6 +220,7 @@
     <string name="debug_networking_category" msgid="7044075693643009662">"Ukunethiwekha"</string>
     <string name="wifi_display_certification" msgid="8611569543791307533">"Ukunikezwa isitifiketi sokubukeka okungenantambo"</string>
     <string name="wifi_verbose_logging" msgid="4203729756047242344">"Nika amandlaukungena kwe-Wi-Fi Verbose"</string>
+    <string name="wifi_scan_throttling" msgid="160014287416479843">"I-throttling yokuskena kwe-Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8774857027458200434">"Idatha yeselula ihlala isebenza"</string>
     <string name="tethering_hardware_offload" msgid="7470077827090325814">"I-Tethering hardware acceleration"</string>
     <string name="bluetooth_show_devices_without_names" msgid="4708446092962060176">"Bonisa amadivayisi e-Bluetooth ngaphandle kwamagama"</string>
@@ -246,6 +247,7 @@
     <string name="private_dns_mode_provider_failure" msgid="231837290365031223">"Ayikwazanga ukuxhuma"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Bonisa izinketho zokunikeza isitifiketi ukubukeka okungenantambo"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"khuphula izinga lokungena le-Wi-Fi, bonisa nge-SSID RSSI engayodwana kusikhethi se-Wi-Fi"</string>
+    <string name="wifi_scan_throttling_summary" msgid="4461922728822495763">"Yehlisa ukuphela kwebhethri futhi ithuthukise ukusebenza kwenethiwekhi"</string>
     <string name="wifi_metered_label" msgid="4514924227256839725">"Kulinganisiwe"</string>
     <string name="wifi_unmetered_label" msgid="6124098729457992931">"Akulinganiselwa"</string>
     <string name="select_logd_size_title" msgid="7433137108348553508">"Amasayizi weloga ngebhafa"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index 9a41f1d..9672fea 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -663,7 +663,8 @@
         final SpannableStringBuilder sb = new SpannableStringBuilder(textView.getText());
         removeExistingRestrictedSpans(sb);
         if (disabled) {
-            final int disabledColor = context.getColor(R.color.disabled_text_color);
+            final int disabledColor = Utils.getDisabled(context,
+                    textView.getCurrentTextColor());
             sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(),
                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             textView.setCompoundDrawables(null, null, getRestrictedPadlock(context), null);
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 0ed507c..5c05a1b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -24,6 +24,8 @@
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.core.content.res.TypedArrayUtils;
@@ -39,6 +41,7 @@
     RestrictedPreferenceHelper mHelper;
     boolean mUseAdditionalSummary = false;
     CharSequence mRestrictedSwitchSummary;
+    private int mIconSize;
 
     public RestrictedSwitchPreference(Context context, AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
@@ -62,7 +65,7 @@
                     && restrictedSwitchSummary.type == TypedValue.TYPE_STRING) {
                 if (restrictedSwitchSummary.resourceId != 0) {
                     mRestrictedSwitchSummary =
-                        context.getText(restrictedSwitchSummary.resourceId);
+                            context.getText(restrictedSwitchSummary.resourceId);
                 } else {
                     mRestrictedSwitchSummary = restrictedSwitchSummary.string;
                 }
@@ -87,6 +90,10 @@
         this(context, null);
     }
 
+    public void setIconSize(int iconSize) {
+        mIconSize = iconSize;
+    }
+
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
@@ -95,7 +102,7 @@
         CharSequence switchSummary;
         if (mRestrictedSwitchSummary == null) {
             switchSummary = getContext().getText(isChecked()
-                ? R.string.enabled_by_admin : R.string.disabled_by_admin);
+                    ? R.string.enabled_by_admin : R.string.disabled_by_admin);
         } else {
             switchSummary = mRestrictedSwitchSummary;
         }
@@ -109,6 +116,12 @@
             switchWidget.setVisibility(isDisabledByAdmin() ? View.GONE : View.VISIBLE);
         }
 
+        final ImageView icon = holder.itemView.findViewById(android.R.id.icon);
+
+        if (mIconSize > 0) {
+            icon.setLayoutParams(new LinearLayout.LayoutParams(mIconSize, mIconSize));
+        }
+
         if (mUseAdditionalSummary) {
             final TextView additionalSummaryView = (TextView) holder.findViewById(
                     R.id.additional_summary);
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index d32e85f..14f233d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -35,8 +35,6 @@
 
 public class Utils {
 
-    private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
-    private static final String NEW_MODE_KEY = "NEW_MODE";
     @VisibleForTesting
     static final String STORAGE_MANAGER_ENABLED_PROPERTY =
             "ro.storage_manager.enabled";
@@ -56,24 +54,11 @@
 
     public static void updateLocationEnabled(Context context, boolean enabled, int userId,
             int source) {
-        LocationManager locationManager = context.getSystemService(LocationManager.class);
-
         Settings.Secure.putIntForUser(
                 context.getContentResolver(), Settings.Secure.LOCATION_CHANGER, source,
                 userId);
 
-        Intent intent = new Intent(LocationManager.MODE_CHANGING_ACTION);
-        final int oldMode = locationManager.isLocationEnabled()
-                ? Settings.Secure.LOCATION_MODE_ON
-                : Settings.Secure.LOCATION_MODE_OFF;
-        final int newMode = enabled
-                ? Settings.Secure.LOCATION_MODE_ON
-                : Settings.Secure.LOCATION_MODE_OFF;
-        intent.putExtra(CURRENT_MODE_KEY, oldMode);
-        intent.putExtra(NEW_MODE_KEY, newMode);
-        context.sendBroadcastAsUser(
-                intent, UserHandle.of(userId), android.Manifest.permission.WRITE_SECURE_SETTINGS);
-
+        LocationManager locationManager = context.getSystemService(LocationManager.class);
         locationManager.setLocationEnabledForUser(enabled, UserHandle.of(userId));
     }
 
@@ -218,6 +203,13 @@
         return list.getDefaultColor();
     }
 
+    /**
+     * This method computes disabled color from normal color
+     *
+     * @param context
+     * @param inputColor normal color.
+     * @return disabled color.
+     */
     @ColorInt
     public static int getDisabled(Context context, int inputColor) {
         return applyAlphaAttr(context, android.R.attr.disabledAlpha, inputColor);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 402ce90..df30c24 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -35,12 +35,12 @@
 
 import com.android.settingslib.R;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * BluetoothEventManager receives broadcasts and callbacks from the Bluetooth
@@ -56,7 +56,7 @@
     private final Map<String, Handler> mHandlerMap;
     private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver();
     private final BroadcastReceiver mProfileBroadcastReceiver = new BluetoothBroadcastReceiver();
-    private final Collection<BluetoothCallback> mCallbacks = new ArrayList<>();
+    private final Collection<BluetoothCallback> mCallbacks = new CopyOnWriteArrayList<>();
     private final android.os.Handler mReceiverHandler;
     private final UserHandle mUserHandle;
     private final Context mContext;
@@ -93,8 +93,10 @@
                 new ConnectionStateChangedHandler());
 
         // Discovery broadcasts
-        addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true));
-        addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false));
+        addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED,
+                new ScanningStateChangedHandler(true));
+        addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED,
+                new ScanningStateChangedHandler(false));
         addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
         addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());
         addHandler(BluetoothDevice.ACTION_ALIAS_CHANGED, new NameChangedHandler());
@@ -128,16 +130,12 @@
 
     /** Register to start receiving callbacks for Bluetooth events. */
     public void registerCallback(BluetoothCallback callback) {
-        synchronized (mCallbacks) {
-            mCallbacks.add(callback);
-        }
+        mCallbacks.add(callback);
     }
 
     /** Unregister to stop receiving callbacks for Bluetooth events. */
     public void unregisterCallback(BluetoothCallback callback) {
-        synchronized (mCallbacks) {
-            mCallbacks.remove(callback);
-        }
+        mCallbacks.remove(callback);
     }
 
     @VisibleForTesting
@@ -189,63 +187,48 @@
     }
 
     void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) {
-        synchronized (mCallbacks) {
-            for (BluetoothCallback callback : mCallbacks) {
-                callback.onDeviceAdded(cachedDevice);
-            }
+        for (BluetoothCallback callback : mCallbacks) {
+            callback.onDeviceAdded(cachedDevice);
         }
     }
 
     void dispatchDeviceRemoved(CachedBluetoothDevice cachedDevice) {
-        synchronized (mCallbacks) {
-            for (BluetoothCallback callback : mCallbacks) {
-                callback.onDeviceDeleted(cachedDevice);
-            }
+        for (BluetoothCallback callback : mCallbacks) {
+            callback.onDeviceDeleted(cachedDevice);
         }
     }
 
     void dispatchProfileConnectionStateChanged(CachedBluetoothDevice device, int state,
             int bluetoothProfile) {
-        synchronized (mCallbacks) {
-            for (BluetoothCallback callback : mCallbacks) {
-                callback.onProfileConnectionStateChanged(device, state, bluetoothProfile);
-            }
+        for (BluetoothCallback callback : mCallbacks) {
+            callback.onProfileConnectionStateChanged(device, state, bluetoothProfile);
         }
     }
 
     private void dispatchConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
-        synchronized (mCallbacks) {
-            for (BluetoothCallback callback : mCallbacks) {
-                callback.onConnectionStateChanged(cachedDevice, state);
-            }
+        for (BluetoothCallback callback : mCallbacks) {
+            callback.onConnectionStateChanged(cachedDevice, state);
         }
     }
 
     private void dispatchAudioModeChanged() {
         mDeviceManager.dispatchAudioModeChanged();
-        synchronized (mCallbacks) {
-            for (BluetoothCallback callback : mCallbacks) {
-                callback.onAudioModeChanged();
-            }
+        for (BluetoothCallback callback : mCallbacks) {
+            callback.onAudioModeChanged();
         }
     }
 
     private void dispatchActiveDeviceChanged(CachedBluetoothDevice activeDevice,
             int bluetoothProfile) {
         mDeviceManager.onActiveDeviceChanged(activeDevice, bluetoothProfile);
-        synchronized (mCallbacks) {
-            for (BluetoothCallback callback : mCallbacks) {
-                callback.onActiveDeviceChanged(activeDevice, bluetoothProfile);
-            }
+        for (BluetoothCallback callback : mCallbacks) {
+            callback.onActiveDeviceChanged(activeDevice, bluetoothProfile);
         }
     }
 
-    private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice,
-            int state) {
-        synchronized (mCallbacks) {
-            for (BluetoothCallback callback : mCallbacks) {
-                callback.onAclConnectionStateChanged(activeDevice, state);
-            }
+    private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice, int state) {
+        for (BluetoothCallback callback : mCallbacks) {
+            callback.onAclConnectionStateChanged(activeDevice, state);
         }
     }
 
@@ -270,17 +253,14 @@
     }
 
     private class AdapterStateChangedHandler implements Handler {
-        public void onReceive(Context context, Intent intent,
-                BluetoothDevice device) {
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
             int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                     BluetoothAdapter.ERROR);
             // update local profiles and get paired devices
             mLocalAdapter.setBluetoothStateInt(state);
             // send callback to update UI and possibly start scanning
-            synchronized (mCallbacks) {
-                for (BluetoothCallback callback : mCallbacks) {
-                    callback.onBluetoothStateChanged(state);
-                }
+            for (BluetoothCallback callback : mCallbacks) {
+                callback.onBluetoothStateChanged(state);
             }
             // Inform CachedDeviceManager that the adapter state has changed
             mDeviceManager.onBluetoothStateChanged(state);
@@ -293,12 +273,10 @@
         ScanningStateChangedHandler(boolean started) {
             mStarted = started;
         }
-        public void onReceive(Context context, Intent intent,
-                BluetoothDevice device) {
-            synchronized (mCallbacks) {
-                for (BluetoothCallback callback : mCallbacks) {
-                    callback.onScanningStateChanged(mStarted);
-                }
+
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
+            for (BluetoothCallback callback : mCallbacks) {
+                callback.onScanningStateChanged(mStarted);
             }
             mDeviceManager.onScanningStateChanged(mStarted);
         }
@@ -317,7 +295,7 @@
                 Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: "
                         + cachedDevice);
             } else if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
-                    &&!cachedDevice.getDevice().isConnected()) {
+                    && !cachedDevice.getDevice().isConnected()) {
                 // Dispatch device add callback to show bonded but
                 // not connected devices in discovery mode
                 dispatchDeviceAdded(cachedDevice);
@@ -350,8 +328,7 @@
     }
 
     private class BondStateChangedHandler implements Handler {
-        public void onReceive(Context context, Intent intent,
-                BluetoothDevice device) {
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
             if (device == null) {
                 Log.e(TAG, "ACTION_BOND_STATE_CHANGED with no EXTRA_DEVICE");
                 return;
@@ -365,10 +342,8 @@
                 cachedDevice = mDeviceManager.addDevice(device);
             }
 
-            synchronized (mCallbacks) {
-                for (BluetoothCallback callback : mCallbacks) {
-                    callback.onDeviceBondStateChanged(cachedDevice, bondState);
-                }
+            for (BluetoothCallback callback : mCallbacks) {
+                callback.onDeviceBondStateChanged(cachedDevice, bondState);
             }
             cachedDevice.onBondingStateChanged(bondState);
 
@@ -388,12 +363,12 @@
          * Called when we have reached the unbonded state.
          *
          * @param reason one of the error reasons from
-         *            BluetoothDevice.UNBOND_REASON_*
+         *               BluetoothDevice.UNBOND_REASON_*
          */
         private void showUnbondMessage(Context context, String name, int reason) {
             int errorMsg;
 
-            switch(reason) {
+            switch (reason) {
                 case BluetoothDevice.UNBOND_REASON_AUTH_FAILED:
                     errorMsg = R.string.bluetooth_pairing_pin_error_message;
                     break;
@@ -410,7 +385,8 @@
                     errorMsg = R.string.bluetooth_pairing_error_message;
                     break;
                 default:
-                    Log.w(TAG, "showUnbondMessage: Not displaying any message for reason: " + reason);
+                    Log.w(TAG,
+                            "showUnbondMessage: Not displaying any message for reason: " + reason);
                     return;
             }
             BluetoothUtils.showError(context, name, errorMsg);
@@ -418,8 +394,7 @@
     }
 
     private class ClassChangedHandler implements Handler {
-        public void onReceive(Context context, Intent intent,
-                BluetoothDevice device) {
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
             CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
             if (cachedDevice != null) {
                 cachedDevice.refresh();
@@ -428,8 +403,7 @@
     }
 
     private class UuidChangedHandler implements Handler {
-        public void onReceive(Context context, Intent intent,
-                BluetoothDevice device) {
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
             CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
             if (cachedDevice != null) {
                 cachedDevice.onUuidChanged();
@@ -438,8 +412,7 @@
     }
 
     private class BatteryLevelChangedHandler implements Handler {
-        public void onReceive(Context context, Intent intent,
-                BluetoothDevice device) {
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
             CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
             if (cachedDevice != null) {
                 cachedDevice.refresh();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 9a95288..84f5a04 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -38,6 +38,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * CachedBluetoothDevice represents a remote Bluetooth device. It contains
@@ -74,7 +75,7 @@
 
     boolean mJustDiscovered;
 
-    private final Collection<Callback> mCallbacks = new ArrayList<>();
+    private final Collection<Callback> mCallbacks = new CopyOnWriteArrayList<>();
 
     /**
      * Last time a bt profile auto-connect was attempted.
@@ -678,22 +679,16 @@
     }
 
     public void registerCallback(Callback callback) {
-        synchronized (mCallbacks) {
-            mCallbacks.add(callback);
-        }
+        mCallbacks.add(callback);
     }
 
     public void unregisterCallback(Callback callback) {
-        synchronized (mCallbacks) {
-            mCallbacks.remove(callback);
-        }
+        mCallbacks.remove(callback);
     }
 
     void dispatchAttributesChanged() {
-        synchronized (mCallbacks) {
-            for (Callback callback : mCallbacks) {
-                callback.onDeviceAttributesChanged();
-            }
+        for (Callback callback : mCallbacks) {
+            callback.onDeviceAttributesChanged();
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index 7f906f6..6d874ab 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -117,7 +117,7 @@
 
     public boolean isPreferred(BluetoothDevice device) {
         if (mService == null) return false;
-        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+        return mService.getPriority(device) != BluetoothProfile.PRIORITY_OFF;
     }
 
     public int getPreferred(BluetoothDevice device) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java
index 320380f..869de0de 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java
@@ -102,7 +102,8 @@
             OnSharedPreferenceChangeListener listener) {
     }
 
-    private void logValue(String key, Object value) {
+    @VisibleForTesting
+    protected void logValue(String key, Object value) {
         logValue(key, value, false /* forceLog */);
     }
 
@@ -138,11 +139,18 @@
             } else {
                 intVal = (int) floatValue;
             }
+        } else if (value instanceof String) {
+            try {
+                intVal = Integer.parseInt((String) value);
+            } catch (NumberFormatException e) {
+                Log.w(LOG_TAG, "Tried to log unloggable object=" + value);
+                return;
+            }
         } else {
-            Log.w(LOG_TAG, "Tried to log unloggable object" + value);
+            Log.w(LOG_TAG, "Tried to log unloggable object=" + value);
             return;
         }
-        // Pref key exists in set, log it's change in metrics.
+        // Pref key exists in set, log its change in metrics.
         mMetricsFeature.action(SettingsEnums.PAGE_UNKNOWN,
                 SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE,
                 SettingsEnums.PAGE_UNKNOWN,
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
index 7177821..097c028 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractWifiMacAddressPreferenceController.java
@@ -69,8 +69,10 @@
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        mWifiMacAddress = screen.findPreference(KEY_WIFI_MAC_ADDRESS);
-        updateConnectivity();
+        if (isAvailable()) {
+            mWifiMacAddress = screen.findPreference(KEY_WIFI_MAC_ADDRESS);
+            updateConnectivity();
+        }
     }
 
     @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
index 7ce713b..5ac788e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
@@ -22,6 +22,7 @@
 import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Path.Direction;
@@ -33,6 +34,7 @@
 import android.os.Handler;
 import android.telephony.SignalStrength;
 import android.util.LayoutDirection;
+import android.util.PathParser;
 
 import com.android.settingslib.R;
 import com.android.settingslib.Utils;
@@ -48,7 +50,6 @@
 
     private static final float VIEWPORT = 24f;
     private static final float PAD = 2f / VIEWPORT;
-    private static final float CUT_OUT = 7.9f / VIEWPORT;
 
     private static final float DOT_SIZE = 3f / VIEWPORT;
     private static final float DOT_PADDING = 1.5f / VIEWPORT;
@@ -60,27 +61,11 @@
     private static final int NUM_LEVEL_MASK = 0xff << NUM_LEVEL_SHIFT;
     private static final int STATE_SHIFT = 16;
     private static final int STATE_MASK = 0xff << STATE_SHIFT;
-    private static final int STATE_EMPTY = 1;
     private static final int STATE_CUT = 2;
     private static final int STATE_CARRIER_CHANGE = 3;
 
     private static final long DOT_DELAY = 1000;
 
-    private static float[][] X_PATH = new float[][]{
-            {21.9f / VIEWPORT, 17.0f / VIEWPORT},
-            {-1.1f / VIEWPORT, -1.1f / VIEWPORT},
-            {-1.9f / VIEWPORT, 1.9f / VIEWPORT},
-            {-1.9f / VIEWPORT, -1.9f / VIEWPORT},
-            {-1.1f / VIEWPORT, 1.1f / VIEWPORT},
-            {1.9f / VIEWPORT, 1.9f / VIEWPORT},
-            {-1.9f / VIEWPORT, 1.9f / VIEWPORT},
-            {1.1f / VIEWPORT, 1.1f / VIEWPORT},
-            {1.9f / VIEWPORT, -1.9f / VIEWPORT},
-            {1.9f / VIEWPORT, 1.9f / VIEWPORT},
-            {1.1f / VIEWPORT, -1.1f / VIEWPORT},
-            {-1.9f / VIEWPORT, -1.9f / VIEWPORT},
-    };
-
     private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final Paint mTransparentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final int mDarkModeFillColor;
@@ -88,7 +73,11 @@
     private final Path mCutoutPath = new Path();
     private final Path mForegroundPath = new Path();
     private final Path mXPath = new Path();
+    private final Matrix mXScaleMatrix = new Matrix();
+    private final Path mScaledXPath = new Path();
     private final Handler mHandler;
+    private final float mCutoutWidthFraction;
+    private final float mCutoutHeightFraction;
     private float mDarkIntensity = -1;
     private final int mIntrinsicSize;
     private boolean mAnimating;
@@ -96,6 +85,14 @@
 
     public SignalDrawable(Context context) {
         super(context.getDrawable(com.android.internal.R.drawable.ic_signal_cellular));
+        final String xPathString = context.getString(
+                com.android.internal.R.string.config_signalXPath);
+        mXPath.set(PathParser.createPathFromPathData(xPathString));
+        updateScaledXPath();
+        mCutoutWidthFraction = context.getResources().getFloat(
+                com.android.internal.R.dimen.config_signalCutoutWidthFraction);
+        mCutoutHeightFraction = context.getResources().getFloat(
+                com.android.internal.R.dimen.config_signalCutoutHeightFraction);
         mDarkModeFillColor = Utils.getColorStateListDefaultColor(context,
                 R.color.dark_mode_icon_color_single_tone);
         mLightModeFillColor = Utils.getColorStateListDefaultColor(context,
@@ -107,6 +104,15 @@
         setDarkIntensity(0);
     }
 
+    private void updateScaledXPath() {
+        if (getBounds().isEmpty()) {
+            mXScaleMatrix.setScale(1f, 1f);
+        } else {
+            mXScaleMatrix.setScale(getBounds().width() / VIEWPORT, getBounds().height() / VIEWPORT);
+        }
+        mXPath.transform(mXScaleMatrix, mScaledXPath);
+    }
+
     @Override
     public int getIntrinsicWidth() {
         return mIntrinsicSize;
@@ -133,6 +139,7 @@
         super.onLevelChange(unpackLevel(packedState));
         updateAnimation();
         setTintList(ColorStateList.valueOf(mForegroundPaint.getColor()));
+        invalidateSelf();
         return true;
     }
 
@@ -170,6 +177,7 @@
     @Override
     protected void onBoundsChange(Rect bounds) {
         super.onBoundsChange(bounds);
+        updateScaledXPath();
         invalidateSelf();
     }
 
@@ -204,20 +212,16 @@
             drawDotAndPadding(x - dotSpacing * 2, y, dotPadding, dotSize, 0);
             canvas.drawPath(mCutoutPath, mTransparentPaint);
             canvas.drawPath(mForegroundPath, mForegroundPaint);
-        } else if (isInState(STATE_CUT) || isInState(STATE_EMPTY)) {
-            float cut = (CUT_OUT * width);
-            mCutoutPath.moveTo(width - padding, height - padding);
-            mCutoutPath.rLineTo(-cut, 0);
-            mCutoutPath.rLineTo(0, -cut);
-            mCutoutPath.rLineTo(cut, 0);
-            mCutoutPath.rLineTo(0, cut);
+        } else if (isInState(STATE_CUT)) {
+            float cutX = (mCutoutWidthFraction * width / VIEWPORT);
+            float cutY = (mCutoutHeightFraction * height / VIEWPORT);
+            mCutoutPath.moveTo(width, height);
+            mCutoutPath.rLineTo(-cutX, 0);
+            mCutoutPath.rLineTo(0, -cutY);
+            mCutoutPath.rLineTo(cutX, 0);
+            mCutoutPath.rLineTo(0, cutY);
             canvas.drawPath(mCutoutPath, mTransparentPaint);
-            mXPath.reset();
-            mXPath.moveTo(X_PATH[0][0] * width, X_PATH[0][1] * height);
-            for (int i = 1; i < X_PATH.length; i++) {
-                mXPath.rLineTo(X_PATH[i][0] * width, X_PATH[i][1] * height);
-            }
-            canvas.drawPath(mXPath, mForegroundPaint);
+            canvas.drawPath(mScaledXPath, mForegroundPaint);
         }
         if (isRtl) {
             canvas.restore();
@@ -269,14 +273,13 @@
     /**
      * Returns whether this drawable is in the specified state.
      *
-     * @param state must be one of {@link #STATE_CARRIER_CHANGE}, {@link #STATE_CUT},
-     *              or {@link #STATE_EMPTY}.
+     * @param state must be one of {@link #STATE_CARRIER_CHANGE} or {@link #STATE_CUT}
      */
     private boolean isInState(int state) {
         return getState(getLevel()) == state;
     }
 
-    private static int getState(int fullState) {
+    public static int getState(int fullState) {
         return (fullState & STATE_MASK) >> STATE_SHIFT;
     }
 
@@ -288,12 +291,7 @@
 
     /** Returns the state representing empty mobile signal with the given number of levels. */
     public static int getEmptyState(int numLevels) {
-        return (STATE_EMPTY << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT);
-    }
-
-    /** Returns whether fullState corresponds to the empty state. */
-    public static boolean isEmptyState(int fullState) {
-        return getState(fullState) == STATE_EMPTY;
+        return getState(0, numLevels, true);
     }
 
     /** Returns the state representing carrier change with the given number of levels. */
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
index 55b6cda..546095e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
@@ -98,6 +98,7 @@
             // Remove switch widget.
             setWidgetLayoutResource(NO_WIDGET);
         }
+        setIconSize(context.getResources().getDimensionPixelSize(R.dimen.secondary_app_icon_size));
     }
 
     @VisibleForTesting
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
index 0b69963..ac7a121 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlLoaderCompat.java
@@ -38,7 +38,7 @@
             "/odm/etc/NOTICE.xml.gz",
             "/oem/etc/NOTICE.xml.gz",
             "/product/etc/NOTICE.xml.gz",
-            "/product_services/etc/NOTICE.xml.gz"};
+            "/system_ext/etc/NOTICE.xml.gz"};
     static final String NOTICE_HTML_FILE_NAME = "NOTICE.html";
 
     private final Context mContext;
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
index 6fd8749..60c9984 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -90,12 +90,16 @@
 
         for (int i = 0; i < appOpsCount; ++i) {
             AppOpsManager.PackageOps ops = appOps.get(i);
+            // Don't show the Android System in the list - it's not actionable for the user.
+            // Also don't show apps belonging to background users except managed users.
             String packageName = ops.getPackageName();
             int uid = ops.getUid();
             final UserHandle user = UserHandle.getUserHandleForUid(uid);
 
-            // Don't show apps belonging to background users except managed users.
-            if (!profiles.contains(user)) {
+            boolean isAndroidOs =
+                    (uid == android.os.Process.SYSTEM_UID) && ANDROID_SYSTEM_PACKAGE_NAME.equals(
+                            packageName);
+            if (isAndroidOs || !profiles.contains(user)) {
                 continue;
             }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index f30de13..ea3c1d9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -110,13 +110,7 @@
     }
 
     public DataUsageInfo getDataUsageInfo() {
-        final String subscriberId = getActiveSubscriberId();
-        if (subscriberId == null) {
-            return warn("no subscriber id");
-        }
-        NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId);
-        template = NetworkTemplate.normalize(template, getTelephonyManager()
-                .getMergedSubscriberIds());
+        NetworkTemplate template = DataUsageUtils.getMobileTemplate(mContext, mSubscriptionId);
 
         return getDataUsageInfo(template);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
new file mode 100644
index 0000000..23e29493
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net;
+
+import android.content.Context;
+import android.net.NetworkTemplate;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.internal.util.ArrayUtils;
+/**
+ * Utils class for data usage
+ */
+public class DataUsageUtils {
+    private static final String TAG = "DataUsageUtils";
+
+    /**
+     * Return mobile NetworkTemplate based on {@code subId}
+     */
+    public static NetworkTemplate getMobileTemplate(Context context, int subId) {
+        final TelephonyManager telephonyManager = context.getSystemService(
+                TelephonyManager.class);
+        final SubscriptionManager subscriptionManager = context.getSystemService(
+                SubscriptionManager.class);
+        final NetworkTemplate mobileAll = NetworkTemplate.buildTemplateMobileAll(
+                telephonyManager.getSubscriberId(subId));
+
+        if (!subscriptionManager.isActiveSubId(subId)) {
+            Log.i(TAG, "Subscription is not active: " + subId);
+            return mobileAll;
+        }
+
+        final String[] mergedSubscriberIds = telephonyManager.createForSubscriptionId(subId)
+                .getMergedSubscriberIdsFromGroup();
+
+        if (ArrayUtils.isEmpty(mergedSubscriberIds)) {
+            Log.i(TAG, "mergedSubscriberIds is null.");
+            return mobileAll;
+        }
+
+        return NetworkTemplate.normalize(mobileAll, mergedSubscriberIds);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java b/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java
new file mode 100644
index 0000000..c54b471
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/ColorUtil.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.utils;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+
+/** Utility class for getting color attribute **/
+public class ColorUtil {
+
+    /**
+     * Returns android:disabledAlpha value in context
+     */
+    public static float getDisabledAlpha(Context context) {
+        final TypedArray ta = context.obtainStyledAttributes(
+                new int[]{android.R.attr.disabledAlpha});
+        final float alpha = ta.getFloat(0, 0);
+        ta.recycle();
+        return alpha;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
index a31b71e..7100acc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/widget/FooterPreference.java
@@ -17,6 +17,7 @@
 package com.android.settingslib.widget;
 
 import android.content.Context;
+import android.text.TextUtils;
 import android.text.method.LinkMovementMethod;
 import android.util.AttributeSet;
 import android.widget.TextView;
@@ -55,9 +56,26 @@
         title.setLongClickable(false);
     }
 
+    @Override
+    public void setSummary(CharSequence summary) {
+        setTitle(summary);
+    }
+
+    @Override
+    public void setSummary(int summaryResId) {
+        setTitle(summaryResId);
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        return getTitle();
+    }
+
     private void init() {
         setIcon(R.drawable.ic_info_outline_24);
-        setKey(KEY_FOOTER);
         setOrder(ORDER_FOOTER);
+        if (TextUtils.isEmpty(getKey())) {
+            setKey(KEY_FOOTER);
+        }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index e28c612..59754e0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -55,6 +55,7 @@
 import android.util.Log;
 import android.util.Pair;
 
+import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -108,6 +109,14 @@
     /** The key which identifies this AccessPoint grouping. */
     private String mKey;
 
+    /**
+     * Synchronization lock for managing concurrency between main and worker threads.
+     *
+     * <p>This lock should be held for all modifications to {@link #mScanResults} and
+     * {@link #mExtraScanResults}.
+     */
+    private final Object mLock = new Object();
+
     @IntDef({Speed.NONE, Speed.SLOW, Speed.MODERATE, Speed.FAST, Speed.VERY_FAST})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Speed {
@@ -134,12 +143,14 @@
     }
 
     /** The underlying set of scan results comprising this AccessPoint. */
+    @GuardedBy("mLock")
     private final ArraySet<ScanResult> mScanResults = new ArraySet<>();
 
     /**
      * Extra set of unused scan results corresponding to this AccessPoint for verbose logging
      * purposes, such as a set of Passpoint roaming scan results when home scans are available.
      */
+    @GuardedBy("mLock")
     private final ArraySet<ScanResult> mExtraScanResults = new ArraySet<>();
 
     /**
@@ -489,8 +500,10 @@
 
         if (isVerboseLoggingEnabled()) {
             builder.append(",rssi=").append(mRssi);
-            builder.append(",scan cache size=").append(mScanResults.size()
-                    + mExtraScanResults.size());
+            synchronized (mLock) {
+                builder.append(",scan cache size=").append(mScanResults.size()
+                        + mExtraScanResults.size());
+            }
         }
 
         return builder.append(')').toString();
@@ -532,18 +545,20 @@
      */
     private boolean updateScores(WifiNetworkScoreCache scoreCache, long maxScoreCacheAgeMillis) {
         long nowMillis = SystemClock.elapsedRealtime();
-        for (ScanResult result : mScanResults) {
-            ScoredNetwork score = scoreCache.getScoredNetwork(result);
-            if (score == null) {
-                continue;
-            }
-            TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID);
-            if (timedScore == null) {
-                mScoredNetworkCache.put(
-                        result.BSSID, new TimestampedScoredNetwork(score, nowMillis));
-            } else {
-                // Update data since the has been seen in the score cache
-                timedScore.update(score, nowMillis);
+        synchronized (mLock) {
+            for (ScanResult result : mScanResults) {
+                ScoredNetwork score = scoreCache.getScoredNetwork(result);
+                if (score == null) {
+                    continue;
+                }
+                TimestampedScoredNetwork timedScore = mScoredNetworkCache.get(result.BSSID);
+                if (timedScore == null) {
+                    mScoredNetworkCache.put(
+                            result.BSSID, new TimestampedScoredNetwork(score, nowMillis));
+                } else {
+                    // Update data since the has been seen in the score cache
+                    timedScore.update(score, nowMillis);
+                }
             }
         }
 
@@ -619,12 +634,14 @@
                 mIsScoredNetworkMetered |= score.meteredHint;
             }
         } else {
-            for (ScanResult result : mScanResults) {
-                ScoredNetwork score = scoreCache.getScoredNetwork(result);
-                if (score == null) {
-                    continue;
+            synchronized (mLock) {
+                for (ScanResult result : mScanResults) {
+                    ScoredNetwork score = scoreCache.getScoredNetwork(result);
+                    if (score == null) {
+                        continue;
+                    }
+                    mIsScoredNetworkMetered |= score.meteredHint;
                 }
-                mIsScoredNetworkMetered |= score.meteredHint;
             }
         }
         return oldMetering == mIsScoredNetworkMetered;
@@ -695,11 +712,25 @@
     public boolean matches(WifiConfiguration config) {
         if (config.isPasspoint()) {
             return (isPasspoint() && config.FQDN.equals(mConfig.FQDN));
-        } else {
-            // Normal non-Passpoint network
-            return ssid.equals(removeDoubleQuotes(config.SSID))
-                    && security == getSecurity(config)
-                    && (mConfig == null || mConfig.shared == config.shared);
+        }
+
+        if (!ssid.equals(removeDoubleQuotes(config.SSID))
+                || (mConfig != null && mConfig.shared != config.shared)) {
+            return false;
+        }
+
+        final int configSecurity = getSecurity(config);
+        final WifiManager wifiManager = getWifiManager();
+        switch (security) {
+            case SECURITY_PSK_SAE_TRANSITION:
+                return configSecurity == SECURITY_PSK
+                        || (wifiManager.isWpa3SaeSupported() && configSecurity == SECURITY_SAE);
+            case SECURITY_OWE_TRANSITION:
+                return configSecurity == SECURITY_NONE
+                        || (wifiManager.isEnhancedOpenSupported()
+                                && configSecurity == SECURITY_OWE);
+            default:
+                return security == configSecurity;
         }
     }
 
@@ -741,8 +772,10 @@
      */
     public Set<ScanResult> getScanResults() {
         Set<ScanResult> allScans = new ArraySet<>();
-        allScans.addAll(mScanResults);
-        allScans.addAll(mExtraScanResults);
+        synchronized (mLock) {
+            allScans.addAll(mScanResults);
+            allScans.addAll(mExtraScanResults);
+        }
         return allScans;
     }
 
@@ -766,10 +799,12 @@
 
         ScanResult bestResult = null;
         int bestRssi = UNREACHABLE_RSSI;
-        for (ScanResult result : mScanResults) {
-            if (result.level > bestRssi) {
-                bestRssi = result.level;
-                bestResult = result;
+        synchronized (mLock) {
+            for (ScanResult result : mScanResults) {
+                if (result.level > bestRssi) {
+                    bestRssi = result.level;
+                    bestResult = result;
+                }
             }
         }
 
@@ -999,8 +1034,7 @@
                 summary.append(mContext.getString(R.string.tap_to_sign_up));
             }
         } else if (isActive()) {
-            if (mConfig != null && getDetailedState() == DetailedState.CONNECTED
-                    && mIsCarrierAp) {
+            if (getDetailedState() == DetailedState.CONNECTED && mIsCarrierAp) {
                 // This is the active connection on a carrier AP
                 summary.append(String.format(mContext.getString(R.string.connected_via_carrier),
                         mCarrierName));
@@ -1186,8 +1220,7 @@
      * Can only be called for unsecured networks.
      */
     public void generateOpenNetworkConfig() {
-        if ((security != SECURITY_NONE) && (security != SECURITY_OWE)
-                && (security != SECURITY_OWE_TRANSITION)) {
+        if (!isOpenNetwork()) {
             throw new IllegalStateException();
         }
         if (mConfig != null)
@@ -1211,9 +1244,11 @@
         savedState.putInt(KEY_EAPTYPE, mEapType);
         if (mConfig != null) savedState.putParcelable(KEY_CONFIG, mConfig);
         savedState.putParcelable(KEY_WIFIINFO, mInfo);
-        savedState.putParcelableArray(KEY_SCANRESULTS,
-                mScanResults.toArray(new Parcelable[mScanResults.size()
-                        + mExtraScanResults.size()]));
+        synchronized (mLock) {
+            savedState.putParcelableArray(KEY_SCANRESULTS,
+                    mScanResults.toArray(new Parcelable[mScanResults.size()
+                            + mExtraScanResults.size()]));
+        }
         savedState.putParcelableArrayList(KEY_SCOREDNETWORKCACHE,
                 new ArrayList<>(mScoredNetworkCache.values()));
         if (mNetworkInfo != null) {
@@ -1292,8 +1327,10 @@
         }
 
         int oldLevel = getLevel();
-        mScanResults.clear();
-        mScanResults.addAll(scanResults);
+        synchronized (mLock) {
+            mScanResults.clear();
+            mScanResults.addAll(scanResults);
+        }
         updateBestRssiInfo();
         int newLevel = getLevel();
 
@@ -1324,16 +1361,18 @@
     void setScanResultsPasspoint(
             @Nullable Collection<ScanResult> homeScans,
             @Nullable Collection<ScanResult> roamingScans) {
-        mExtraScanResults.clear();
-        if (!CollectionUtils.isEmpty(homeScans)) {
-            if (!CollectionUtils.isEmpty(roamingScans)) {
-                mExtraScanResults.addAll(roamingScans);
+        synchronized (mLock) {
+            mExtraScanResults.clear();
+            if (!CollectionUtils.isEmpty(homeScans)) {
+                mIsRoaming = false;
+                if (!CollectionUtils.isEmpty(roamingScans)) {
+                    mExtraScanResults.addAll(roamingScans);
+                }
+                setScanResults(homeScans);
+            } else if (!CollectionUtils.isEmpty(roamingScans)) {
+                mIsRoaming = true;
+                setScanResults(roamingScans);
             }
-            mIsRoaming = false;
-            setScanResults(homeScans);
-        } else if (!CollectionUtils.isEmpty(roamingScans)) {
-            mIsRoaming = true;
-            setScanResults(roamingScans);
         }
     }
 
@@ -1674,6 +1713,14 @@
     }
 
     /**
+     * Return true if this is an open network AccessPoint.
+     */
+    public boolean isOpenNetwork() {
+        return security == SECURITY_NONE || security == SECURITY_OWE
+                || security == SECURITY_OWE_TRANSITION;
+    }
+
+    /**
      * Callbacks relaying changes to the AccessPoint representation.
      *
      * <p>All methods are invoked on the Main Thread.
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 af4704c..0a16ec2 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
@@ -94,7 +94,7 @@
             new RssiCurve(-150, 10, new byte[]{Speed.FAST});
     public static final String TEST_BSSID = "00:00:00:00:00:00";
     private static final long MAX_SCORE_CACHE_AGE_MILLIS =
-            20 * DateUtils.MINUTE_IN_MILLIS;;
+            20 * DateUtils.MINUTE_IN_MILLIS;
 
     private Context mContext;
     private WifiInfo mWifiInfo;
@@ -1522,4 +1522,26 @@
 
         verify(mMockConnectListener).onFailure(anyInt());
     }
+
+    /**
+     * Verifies that isOpenNetwork returns true for SECURITY_NONE, SECURITY_OWE, and
+     * SECURITY_OWE_TRANSITION.
+     */
+    @Test
+    public void testIsOpenNetwork_returnValidResult() {
+        final Bundle bundle = new Bundle();
+        AccessPoint ap;
+
+        for (int i = 0; i < AccessPoint.SECURITY_MAX_VAL; i++) {
+            bundle.putInt("key_security", i);
+            ap = new AccessPoint(InstrumentationRegistry.getTargetContext(), bundle);
+
+            if (i == AccessPoint.SECURITY_NONE || i == AccessPoint.SECURITY_OWE
+                    || i == AccessPoint.SECURITY_OWE_TRANSITION) {
+                assertThat(ap.isOpenNetwork()).isTrue();
+            } else {
+                assertThat(ap.isOpenNetwork()).isFalse();
+            }
+        }
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index 25c80fa..3756c3b 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -32,6 +32,9 @@
 android_robolectric_test {
     name: "SettingsLibRoboTests",
     srcs: ["src/**/*.java"],
+    static_libs: [
+        "SettingsLib-robo-testutils",
+    ],
     java_resource_dirs: ["config"],
     instrumentation_for: "SettingsLibShell",
     coverage_libs: ["SettingsLib"],
@@ -43,7 +46,7 @@
 java_library {
     name: "SettingsLib-robo-testutils",
     srcs: [
-        "src/com/android/settingslib/testutils/**/*.java",
+        "testutils/com/android/settingslib/testutils/**/*.java",
     ],
 
     libs: [
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedSwitchPreferenceTest.java
new file mode 100644
index 0000000..4702e49
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedSwitchPreferenceTest.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.settingslib;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import androidx.preference.PreferenceViewHolder;
+
+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 RestrictedSwitchPreferenceTest {
+
+    private static final int SIZE = 50;
+
+    private RestrictedSwitchPreference mPreference;
+    private Context mContext;
+    private PreferenceViewHolder mViewHolder;
+    private View mRootView;
+    private ImageView mImageView;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mPreference = new RestrictedSwitchPreference(mContext);
+        mRootView = View.inflate(mContext, R.layout.restricted_switch_preference,
+                null /* parent */);
+        mViewHolder = PreferenceViewHolder.createInstanceForTests(mRootView);
+        mImageView = (ImageView) mViewHolder.findViewById(android.R.id.icon);
+    }
+
+    @Test
+    public void onBindViewHolder_setIconSize_shouldHaveCorrectLayoutParam() {
+        mPreference.setIconSize(SIZE);
+
+        mPreference.onBindViewHolder(mViewHolder);
+
+        assertThat(mImageView.getLayoutParams().height).isEqualTo(SIZE);
+        assertThat(mImageView.getLayoutParams().width).isEqualTo(SIZE);
+    }
+
+    @Test
+    public void onBindViewHolder_notSetIconSize_shouldHaveCorrectLayoutParam() {
+        mPreference.onBindViewHolder(mViewHolder);
+
+        assertThat(mImageView.getLayoutParams().height).isEqualTo(
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+        assertThat(mImageView.getLayoutParams().width).isEqualTo(
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index 4d76e44..fc69b1a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -15,17 +15,13 @@
  */
 package com.android.settingslib;
 
-import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
-
 import static com.android.settingslib.Utils.STORAGE_MANAGER_ENABLED_PROPERTY;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
 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.app.ActivityManager;
@@ -45,7 +41,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
-import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
@@ -85,15 +80,11 @@
     }
 
     @Test
-    public void testUpdateLocationEnabled_sendBroadcast() {
+    public void testUpdateLocationEnabled() {
         int currentUserId = ActivityManager.getCurrentUser();
         Utils.updateLocationEnabled(mContext, true, currentUserId,
                 Settings.Secure.LOCATION_CHANGER_QUICK_SETTINGS);
 
-        verify(mContext).sendBroadcastAsUser(
-            argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
-            ArgumentMatchers.eq(UserHandle.of(currentUserId)),
-            ArgumentMatchers.eq(WRITE_SECURE_SETTINGS));
         assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
                 Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
                 .isEqualTo(Settings.Secure.LOCATION_CHANGER_QUICK_SETTINGS);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
index 8f51dec..89de81f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
@@ -162,4 +162,33 @@
                 "tag/key:com.android.settings",
                 0);
     }
+
+    @Test
+    public void putString_shouldNotLogInitialPut() {
+        mSharedPrefLogger.logValue(TEST_KEY, "1");
+        mSharedPrefLogger.logValue(TEST_KEY, "2");
+        mSharedPrefLogger.logValue(TEST_KEY, "62");
+        mSharedPrefLogger.logValue(TEST_KEY, "0");
+
+        verify(mMetricsFeature, times(3)).action(eq(SettingsEnums.PAGE_UNKNOWN),
+                eq(SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE),
+                eq(SettingsEnums.PAGE_UNKNOWN),
+                eq(TEST_TAGGED_KEY),
+                anyInt());
+    }
+
+    @Test
+    public void putString_shouldNotLogAnyNonIntegers() {
+        mSharedPrefLogger.logValue(TEST_KEY, "string");
+        mSharedPrefLogger.logValue(TEST_KEY, "not an int");
+        mSharedPrefLogger.logValue(TEST_KEY, "1.234f");
+        mSharedPrefLogger.logValue(TEST_KEY, "4.2");
+        mSharedPrefLogger.logValue(TEST_KEY, "3.0");
+
+        verify(mMetricsFeature, times(0)).action(eq(SettingsEnums.PAGE_UNKNOWN),
+                eq(SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE),
+                eq(SettingsEnums.PAGE_UNKNOWN),
+                eq(TEST_TAGGED_KEY),
+                anyInt());
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
index 1f7f4bc..7c2f0a8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/deviceinfo/WifiMacAddressPreferenceControllerTest.java
@@ -20,7 +20,9 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
@@ -92,6 +94,19 @@
     }
 
     @Test
+    public void updateConnectivity_notAvailable_notCalled() {
+        boolean mCalled = false;
+        mController = spy(new ConcreteWifiMacAddressPreferenceController(mContext, mLifecycle) {
+            @Override
+            public boolean isAvailable() {
+                return false;
+            }
+        });
+        mController.displayPreference(mScreen);
+        verify(mController, never()).updateConnectivity();
+    }
+
+    @Test
     public void updateConnectivity_null_setMacUnavailable() {
         doReturn(null).when(mWifiManager).getFactoryMacAddresses();
         mController.displayPreference(mScreen);
@@ -105,10 +120,6 @@
         doReturn(macAddresses).when(mWifiManager).getFactoryMacAddresses();
         mController.displayPreference(mScreen);
         assertThat(mPreference.getSummary()).isEqualTo(TEST_MAC_ADDRESS);
-
-
-
-
     }
 
     private static class ConcreteWifiMacAddressPreferenceController
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
new file mode 100644
index 0000000..5cae611
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageUtilsTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.NetworkTemplate;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class DataUsageUtilsTest {
+
+    private static final int SUB_ID = 1;
+    private static final int SUB_ID_2 = 2;
+    private static final String SUBSCRIBER_ID = "Test Subscriber";
+    private static final String SUBSCRIBER_ID_2 = "Test Subscriber 2";
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+    @Mock
+    private SubscriptionInfo mInfo1;
+    @Mock
+    private SubscriptionInfo mInfo2;
+    @Mock
+    private ParcelUuid mParcelUuid;
+    private Context mContext;
+    private List<SubscriptionInfo> mInfos;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = spy(RuntimeEnvironment.application);
+        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
+        when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
+        when(mTelephonyManager.getSubscriberId(SUB_ID)).thenReturn(SUBSCRIBER_ID);
+        when(mTelephonyManager.getSubscriberId(SUB_ID_2)).thenReturn(SUBSCRIBER_ID_2);
+        when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
+        when(mSubscriptionManager.isActiveSubId(anyInt())).thenReturn(true);
+    }
+
+    @Test
+    public void getMobileTemplate_infoNull_returnMobileAll() {
+        when(mSubscriptionManager.isActiveSubId(SUB_ID)).thenReturn(false);
+
+        final NetworkTemplate networkTemplate = DataUsageUtils.getMobileTemplate(mContext, SUB_ID);
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID)).isTrue();
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID_2)).isFalse();
+    }
+
+    @Test
+    public void getMobileTemplate_groupUuidNull_returnMobileAll() {
+        when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(mInfo1);
+        when(mInfo1.getGroupUuid()).thenReturn(null);
+        when(mTelephonyManager.getMergedSubscriberIdsFromGroup())
+                .thenReturn(new String[] {SUBSCRIBER_ID});
+
+        final NetworkTemplate networkTemplate = DataUsageUtils.getMobileTemplate(mContext, SUB_ID);
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID)).isTrue();
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID_2)).isFalse();
+    }
+
+    @Test
+    public void getMobileTemplate_groupUuidExist_returnMobileMerged() {
+        when(mSubscriptionManager.getActiveSubscriptionInfo(SUB_ID)).thenReturn(mInfo1);
+        when(mInfo1.getGroupUuid()).thenReturn(mParcelUuid);
+        when(mTelephonyManager.getMergedSubscriberIdsFromGroup())
+                .thenReturn(new String[] {SUBSCRIBER_ID, SUBSCRIBER_ID_2});
+
+        final NetworkTemplate networkTemplate = DataUsageUtils.getMobileTemplate(mContext, SUB_ID);
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID)).isTrue();
+        assertThat(networkTemplate.matchesSubscriberId(SUBSCRIBER_ID_2)).isTrue();
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
deleted file mode 100644
index d8fc861..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
+++ /dev/null
@@ -1,44 +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.settingslib.testutils.shadow;
-
-import android.content.Context;
-import android.telecom.DefaultDialerManager;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
-
-@Implements(DefaultDialerManager.class)
-public class ShadowDefaultDialerManager {
-
-    private static String sDefaultDialer;
-
-    @Resetter
-    public void reset() {
-        sDefaultDialer = null;
-    }
-
-    @Implementation
-    protected static String getDefaultDialerApplication(Context context) {
-        return sDefaultDialer;
-    }
-
-    public static void setDefaultDialerApplication(String dialer) {
-        sDefaultDialer = dialer;
-    }
-}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
deleted file mode 100644
index c8c4526..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
+++ /dev/null
@@ -1,46 +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.settingslib.testutils.shadow;
-
-import android.content.ComponentName;
-import android.content.Context;
-
-import com.android.internal.telephony.SmsApplication;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.Resetter;
-
-@Implements(SmsApplication.class)
-public class ShadowSmsApplication {
-
-    private static ComponentName sDefaultSmsApplication;
-
-    @Resetter
-    public void reset() {
-        sDefaultSmsApplication = null;
-    }
-
-    @Implementation
-    protected static ComponentName getDefaultSmsApplication(Context context, boolean update) {
-        return sDefaultSmsApplication;
-    }
-
-    public static void setDefaultSmsApplication(ComponentName cn) {
-        sDefaultSmsApplication = cn;
-    }
-}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
index 0d2399e..1a4f0ef 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/FooterPreferenceTest.java
@@ -37,28 +37,29 @@
 public class FooterPreferenceTest {
 
     private Context mContext;
+    private FooterPreference mFooterPreference;
 
     @Before
     public void setUp() {
         mContext = RuntimeEnvironment.application;
-    }
-
-    @Test
-    public void createNewPreference_shouldSetKeyAndOrder() {
-        final FooterPreference preference = new FooterPreference(mContext);
-
-        assertThat(preference.getKey()).isEqualTo(FooterPreference.KEY_FOOTER);
-        assertThat(preference.getOrder()).isEqualTo(FooterPreference.ORDER_FOOTER);
+        mFooterPreference = new FooterPreference(mContext);
     }
 
     @Test
     public void bindPreference_shouldLinkifyContent() {
-        final FooterPreference preference = new FooterPreference(mContext);
         final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(
                 LayoutInflater.from(mContext).inflate(R.layout.preference_footer, null));
 
-        preference.onBindViewHolder(holder);
+        mFooterPreference.onBindViewHolder(holder);
+
         assertThat(((TextView) holder.findViewById(android.R.id.title)).getMovementMethod())
                 .isInstanceOf(LinkMovementMethod.class);
     }
+
+    @Test
+    public void setSummary_summarySet_shouldSetAsTitle() {
+        mFooterPreference.setSummary("summary");
+
+        assertThat(mFooterPreference.getTitle()).isEqualTo("summary");
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/DrawableTestHelper.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/DrawableTestHelper.java
similarity index 100%
rename from packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/DrawableTestHelper.java
rename to packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/DrawableTestHelper.java
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowActivityManager.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowActivityManager.java
similarity index 100%
rename from packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowActivityManager.java
rename to packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowActivityManager.java
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java
similarity index 100%
rename from packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java
rename to packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowBluetoothAdapter.java
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
new file mode 100644
index 0000000..2c0792f
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
@@ -0,0 +1,44 @@
+/*
+ * 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.settingslib.testutils.shadow;
+
+import android.content.Context;
+import android.telecom.DefaultDialerManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(DefaultDialerManager.class)
+public class ShadowDefaultDialerManager {
+
+    private static String sDefaultDialer;
+
+    @Resetter
+    public void reset() {
+        sDefaultDialer = null;
+    }
+
+    @Implementation
+    protected static String getDefaultDialerApplication(Context context) {
+        return sDefaultDialer;
+    }
+
+    public static void setDefaultDialerApplication(String dialer) {
+        sDefaultDialer = dialer;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
new file mode 100644
index 0000000..381d072
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
@@ -0,0 +1,46 @@
+/*
+ * 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.settingslib.testutils.shadow;
+
+import android.content.ComponentName;
+import android.content.Context;
+
+import com.android.internal.telephony.SmsApplication;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(SmsApplication.class)
+public class ShadowSmsApplication {
+
+    private static ComponentName sDefaultSmsApplication;
+
+    @Resetter
+    public void reset() {
+        sDefaultSmsApplication = null;
+    }
+
+    @Implementation
+    protected static ComponentName getDefaultSmsApplication(Context context, boolean update) {
+        return sDefaultSmsApplication;
+    }
+
+    public static void setDefaultSmsApplication(ComponentName cn) {
+        sDefaultSmsApplication = cn;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowUserManager.java b/packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowUserManager.java
similarity index 100%
rename from packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowUserManager.java
rename to packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowUserManager.java
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java b/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
index 044ec86..5617331 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
@@ -22,14 +22,16 @@
 import android.util.MemoryIntArray;
 import android.util.Slog;
 import android.util.SparseIntArray;
+
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.IOException;
 
 /**
- * This class tracks changes for global/secure/system tables on a
- * per user basis and updates a shared memory region which client
- * processes can read to determine if their local caches are stale,
+ * This class tracks changes for config/global/secure/system tables
+ * on a per user basis and updates a shared memory region which
+ * client processes can read to determine if their local caches are
+ * stale.
  */
 final class GenerationRegistry {
     private static final String LOG_TAG = "GenerationRegistry";
@@ -114,11 +116,12 @@
     @GuardedBy("mLock")
     private MemoryIntArray getBackingStoreLocked() {
         if (mBackingStore == null) {
-            // One for the global table, two for system and secure tables for a
-            // managed profile (managed profile is not included in the max user
-            // count), ten for partially deleted users if users are quickly removed,
-            // and twice max user count for system and secure.
-            final int size = 1 + 2 + 10 + 2 * UserManager.getMaxSupportedUsers();
+            // One for the config table, one for the global table, two for system
+            // and secure tables for a managed profile (managed profile is not
+            // included in the max user count), ten for partially deleted users if
+            // users are quickly removed, and twice max user count for system and
+            // secure.
+            final int size = 1 + 1 + 2 + 10 + 2 * UserManager.getMaxSupportedUsers();
             try {
                 mBackingStore = new MemoryIntArray(size);
                 if (DEBUG) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 9d398b5..b11df48 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,7 +16,6 @@
 
 package com.android.providers.settings;
 
-import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.backup.BackupAgentHelper;
 import android.app.backup.BackupDataInput;
@@ -41,6 +40,7 @@
 import android.util.BackupUtils;
 import android.util.Log;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.LockPatternUtils;
 
 import java.io.BufferedOutputStream;
@@ -586,15 +586,15 @@
         final String[] whitelist;
         Map<String, Validator> validators = null;
         if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
-            whitelist = concat(Settings.Secure.SETTINGS_TO_BACKUP,
+            whitelist = ArrayUtils.concatElements(String.class, Settings.Secure.SETTINGS_TO_BACKUP,
                     Settings.Secure.LEGACY_RESTORE_SETTINGS);
             validators = Settings.Secure.VALIDATORS;
         } else if (contentUri.equals(Settings.System.CONTENT_URI)) {
-            whitelist = concat(Settings.System.SETTINGS_TO_BACKUP,
+            whitelist = ArrayUtils.concatElements(String.class, Settings.System.SETTINGS_TO_BACKUP,
                     Settings.System.LEGACY_RESTORE_SETTINGS);
             validators = Settings.System.VALIDATORS;
         } else if (contentUri.equals(Settings.Global.CONTENT_URI)) {
-            whitelist = concat(Settings.Global.SETTINGS_TO_BACKUP,
+            whitelist = ArrayUtils.concatElements(String.class, Settings.Global.SETTINGS_TO_BACKUP,
                     Settings.Global.LEGACY_RESTORE_SETTINGS);
             validators = Settings.Global.VALIDATORS;
         } else {
@@ -672,18 +672,6 @@
         return (validator != null) && validator.validate(value);
     }
 
-    private final String[] concat(String[] first, @Nullable String[] second) {
-        if (second == null || second.length == 0) {
-            return first;
-        }
-        final int firstLen = first.length;
-        final int secondLen = second.length;
-        String[] both = new String[firstLen + secondLen];
-        System.arraycopy(first, 0, both, 0, firstLen);
-        System.arraycopy(second, 0, both, firstLen, secondLen);
-        return both;
-    }
-
     /**
      * Restores the owner info enabled and other settings in LockSettings.
      *
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 9e84e31..6adb305 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -716,6 +716,9 @@
                 Settings.Global.GAME_DRIVER_OPT_IN_APPS,
                 GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_IN_APPS);
         dumpSetting(s, p,
+                Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS,
+                GlobalSettingsProto.Gpu.GAME_DRIVER_PRERELEASE_OPT_IN_APPS);
+        dumpSetting(s, p,
                 Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
                 GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_OUT_APPS);
         dumpSetting(s, p,
@@ -1941,9 +1944,6 @@
                 Settings.Secure.SILENCE_GESTURE,
                 SecureSettingsProto.Gesture.SILENCE_ENABLED);
         dumpSetting(s, p,
-                Settings.Secure.SILENCE_NOTIFICATION_GESTURE_COUNT,
-                SecureSettingsProto.Gesture.SILENCE_NOTIFICATION_COUNT);
-        dumpSetting(s, p,
                 Settings.Secure.SILENCE_TIMER_GESTURE_COUNT,
                 SecureSettingsProto.Gesture.SILENCE_TIMER_COUNT);
 
@@ -1953,6 +1953,19 @@
         dumpSetting(s, p,
                 Settings.Secure.SKIP_GESTURE,
                 SecureSettingsProto.Gesture.SKIP_ENABLED);
+
+        dumpSetting(s, p,
+                Settings.Secure.SILENCE_ALARMS_TOUCH_COUNT,
+                SecureSettingsProto.Gesture.SILENCE_ALARMS_TOUCH_COUNT);
+        dumpSetting(s, p,
+                Settings.Secure.SILENCE_CALL_TOUCH_COUNT,
+                SecureSettingsProto.Gesture.SILENCE_CALLS_TOUCH_COUNT);
+        dumpSetting(s, p,
+                Settings.Secure.SILENCE_TIMER_TOUCH_COUNT,
+                SecureSettingsProto.Gesture.SILENCE_TIMER_TOUCH_COUNT);
+        dumpSetting(s, p,
+                Settings.Secure.SKIP_TOUCH_COUNT,
+                SecureSettingsProto.Gesture.SKIP_TOUCH_COUNT);
         p.end(gestureToken);
 
         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 a6f7cd3..7016d30 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -3241,7 +3241,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 181;
+            private static final int SETTINGS_VERSION = 182;
 
             private final int mUserId;
 
@@ -4424,6 +4424,37 @@
                     currentVersion = 181;
                 }
 
+                if (currentVersion == 181) {
+                    // Version cd : by default, add STREAM_BLUETOOTH_SCO to list of streams that can
+                    // be muted.
+                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
+                    final Setting currentSetting = systemSettings.getSettingLocked(
+                              Settings.System.MUTE_STREAMS_AFFECTED);
+                    if (!currentSetting.isNull()) {
+                        try {
+                            int currentSettingIntegerValue = Integer.parseInt(
+                                    currentSetting.getValue());
+                            if ((currentSettingIntegerValue
+                                    & (1 << AudioManager.STREAM_BLUETOOTH_SCO)) == 0) {
+                                systemSettings.insertSettingLocked(
+                                        Settings.System.MUTE_STREAMS_AFFECTED,
+                                        Integer.toString(
+                                        currentSettingIntegerValue
+                                        | (1 << AudioManager.STREAM_BLUETOOTH_SCO)),
+                                        null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+                            }
+                        } catch (NumberFormatException e) {
+                            // remove the setting in case it is not a valid integer
+                            Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED"
+                                    + "setting, removing setting", e);
+                            systemSettings.deleteSettingLocked(
+                                    Settings.System.MUTE_STREAMS_AFFECTED);
+                        }
+
+                    }
+                    currentVersion = 182;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 98c6702..8689eef 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -101,6 +101,8 @@
     <uses-permission android:name="android.permission.REVOKE_RUNTIME_PERMISSIONS" />
     <uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" />
     <uses-permission android:name="android.permission.WHITELIST_RESTRICTED_PERMISSIONS" />
+    <!-- Permission required to test onPermissionsChangedListener -->
+    <uses-permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" />
     <uses-permission android:name="android.permission.SET_KEYBOARD_LAYOUT" />
     <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
     <uses-permission android:name="android.permission.SET_SCREEN_COMPATIBILITY" />
diff --git a/packages/Shell/res/values-in/strings.xml b/packages/Shell/res/values-in/strings.xml
index cf2ebe5..5c5ba816 100644
--- a/packages/Shell/res/values-in/strings.xml
+++ b/packages/Shell/res/values-in/strings.xml
@@ -24,10 +24,10 @@
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Harap tunggu..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Laporan bug akan segera muncul di ponsel"</string>
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Pilih untuk membagikan laporan bug Anda"</string>
-    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tap untuk membagikan laporan bug"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ketuk untuk membagikan laporan bug"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Pilih untuk membagikan laporan bug tanpa screenshot atau menunggu screenshot selesai"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tap untuk membagikan laporan bug tanpa screenshot atau menunggu screenshot selesai"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tap untuk membagikan laporan bug tanpa screenshot atau menunggu screenshot selesai"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Ketuk untuk membagikan laporan bug tanpa screenshot atau menunggu screenshot selesai"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Ketuk untuk membagikan laporan bug tanpa screenshot atau menunggu screenshot selesai"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"Laporan bug berisi data dari berbagai file log sistem, yang mungkin mencakup data yang dianggap sensitif (seperti data penggunaan aplikasi dan lokasi). Hanya bagikan laporan bug dengan aplikasi dan orang yang Anda percaya."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Jangan tampilkan lagi"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Laporan bug"</string>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index b90f4a7..c9bb83c 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -50,7 +50,6 @@
 import android.os.BugreportManager.BugreportCallback;
 import android.os.BugreportManager.BugreportCallback.BugreportErrorCode;
 import android.os.BugreportParams;
-import android.os.BugreportParams.BugreportMode;
 import android.os.Bundle;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -354,7 +353,7 @@
         private final int mId;
         private final BugreportInfo mInfo;
 
-        BugreportCallbackImpl(String name, int id, @BugreportMode int bugreportType) {
+        BugreportCallbackImpl(String name, int id) {
             mId = id;
             // pid not used in this workflow, so setting default = 0
             mInfo = new BugreportInfo(mContext, mId, 0 /* pid */, name,
@@ -542,21 +541,21 @@
 
     private void startBugreportAPI(Intent intent) {
         mUsingBugreportApi = true;
-        String currentTimeStamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(
+        String bugreportName = "bugreport-" + new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(
                 new Date());
 
         // TODO(b/126862297): Make file naming same as dumpstate triggered bugreports
         ParcelFileDescriptor bugreportFd = createReadWriteFile(BUGREPORT_DIR,
-                "bugreport-" + currentTimeStamp + ".zip");
+                bugreportName + ".zip");
         if (bugreportFd == null) {
             Log.e(TAG, "Bugreport parcel file descriptor is null.");
             return;
         }
+        int bugreportType = intent.getIntExtra(EXTRA_BUGREPORT_TYPE,
+                BugreportParams.BUGREPORT_MODE_INTERACTIVE);
 
-        // TODO(b/126862297): Screenshot file is not needed for INTERACTIVE_BUGREPORTS
-        // Add logic to pass screenshot file only for specific bugreports.
         ParcelFileDescriptor screenshotFd = createReadWriteFile(BUGREPORT_DIR,
-                "screenshot-" + currentTimeStamp + ".png");
+                bugreportName + ".png");
         if (screenshotFd == null) {
             Log.e(TAG, "Screenshot parcel file descriptor is null.");
             // TODO(b/123617758): Delete bugreport file created above
@@ -570,16 +569,13 @@
         // Dumpstate increments PROPERTY_LAST_ID, may be racy if multiple calls
         // to dumpstate are made simultaneously.
         final int id = SystemProperties.getInt(PROPERTY_LAST_ID, 0) + 1;
-        int bugreportType = intent.getIntExtra(EXTRA_BUGREPORT_TYPE,
-                BugreportParams.BUGREPORT_MODE_INTERACTIVE);
         Log.i(TAG, "bugreport type = " + bugreportType
                 + " bugreport file fd: " + bugreportFd
                 + " screenshot file fd: " + screenshotFd);
 
-        BugreportCallbackImpl bugreportCallback = new BugreportCallbackImpl("bugreport-"
-                + currentTimeStamp, id, bugreportType);
+        BugreportCallbackImpl bugreportCallback = new BugreportCallbackImpl(bugreportName, id);
         try {
-            mBugreportManager.startBugreport(bugreportFd, null,
+            mBugreportManager.startBugreport(bugreportFd, screenshotFd,
                     new BugreportParams(bugreportType), executor, bugreportCallback);
             mBugreportInfos.put(bugreportCallback.mInfo.id, bugreportCallback.mInfo);
         } catch (RuntimeException e) {
@@ -961,14 +957,20 @@
             return;
         }
         final int max = -1; // this is to log metrics for dumpstate duration.
-        final File screenshotFile = new File(BUGREPORT_DIR, info.name + ".png");
-        // TODO(b/126862297): Screenshot file is not needed for INTERACTIVE_BUGREPORTS
-        // Add logic to null check screenshot file only for specific bugreports.
+        File screenshotFile = new File(BUGREPORT_DIR, info.name + ".png");
         if (screenshotFile == null) {
             // Should never happen, an id always has a file linked to it.
             Log.wtf(TAG, "Missing file " + screenshotFile.getPath() + " does not exist.");
             return;
         }
+        // If the screenshot file did not get populated implies this type of bugreport does not
+        // need the screenshot file; setting the file to null so that empty file doesnt get shared
+        if (screenshotFile.length() == 0) {
+            if (screenshotFile.delete()) {
+                Log.d(TAG, "screenshot file deleted successfully.");
+            }
+            screenshotFile = null;
+        }
         onBugreportFinished(id, bugreportFile, screenshotFile, info.title, info.description, max);
     }
 
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 91a8ab5..4c52b132 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -75,6 +75,7 @@
         "--extra-packages",
         "com.android.keyguard",
     ],
+    kotlincflags: ["-Xjvm-default=enable"],
 
     plugins: ["dagger2-compiler-2.19"],
 }
@@ -128,6 +129,7 @@
         "telephony-common",
         "android.test.base",
     ],
+    kotlincflags: ["-Xjvm-default=enable"],
     aaptflags: [
         "--extra-packages",
         "com.android.keyguard:com.android.systemui",
@@ -155,6 +157,8 @@
         "telephony-common",
     ],
 
+    kotlincflags: ["-Xjvm-default=enable"],
+
     dxflags: ["--multi-dex"],
     aaptflags: [
         "--extra-packages",
@@ -191,6 +195,8 @@
         "telephony-common",
     ],
 
+    kotlincflags: ["-Xjvm-default=enable"],
+
     srcs: [
         "legacy/recents/src/**/*.java",
         "legacy/recents/src/**/I*.aidl",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 7db8969..4f74605b 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -20,6 +20,7 @@
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         package="com.android.systemui"
         android:sharedUserId="android.uid.systemui"
+        xmlns:tools="http://schemas.android.com/tools"
         coreApp="true">
 
     <!-- Using OpenGL ES 2.0 -->
@@ -222,6 +223,9 @@
     <!-- to change themes - light or dark -->
     <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
 
+    <!-- Listen app op changes -->
+    <uses-permission android:name="android.permission.WATCH_APPOPS" />
+
     <!-- to read and change hvac values in a car -->
     <uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE" />
 
@@ -256,7 +260,8 @@
         android:theme="@style/Theme.SystemUI"
         android:defaultToDeviceProtectedStorage="true"
         android:directBootAware="true"
-        android:appComponentFactory="androidx.core.app.CoreComponentFactory">
+        tools:replace="android:appComponentFactory"
+        android:appComponentFactory=".SystemUIAppComponentFactory">
         <!-- Keep theme in sync with SystemUIApplication.onCreate().
              Setting the theme on the application does not affect views inflated by services.
              The application theme is set again from onCreate to take effect for those views. -->
@@ -641,7 +646,8 @@
         <provider
             android:name="com.android.keyguard.clock.ClockOptionsProvider"
             android:authorities="com.android.keyguard.clock"
-            android:exported="true"
+            android:enabled="false"
+            android:exported="false"
             android:grantUriPermissions="true">
         </provider>
 
diff --git a/packages/SystemUI/docs/dagger.md b/packages/SystemUI/docs/dagger.md
index c2159df..c440fba 100644
--- a/packages/SystemUI/docs/dagger.md
+++ b/packages/SystemUI/docs/dagger.md
@@ -53,7 +53,7 @@
 ### Adding injection to a new SystemUI object
 
 Anything that depends on any `@Singleton` provider from SystemUIRootComponent
-should be declared as an `@Subcomponent` of the root component, this requires
+should be declared as a `@Subcomponent` of the root component. This requires
 declaring your own interface for generating your own modules or just the
 object you need injected. The subcomponent also needs to be added to
 SystemUIRootComponent in SystemUIFactory so it can be acquired.
@@ -204,6 +204,13 @@
 }
 ```
 
+## Updating Dagger2
+
+Binaries can be downloaded from https://repo1.maven.org/maven2/com/google/dagger/ and then loaded
+into
+[/prebuilts/tools/common/m2/repository/com/google/dagger/](http://cs/android/prebuilts/tools/common/m2/repository/com/google/dagger/)
+
+
 ## TODO List
 
  - Eliminate usages of Dependency#get
diff --git a/packages/SystemUI/legacy/recents/res/values-de/strings.xml b/packages/SystemUI/legacy/recents/res/values-de/strings.xml
index 97a6366..4a089bf 100644
--- a/packages/SystemUI/legacy/recents/res/values-de/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-de/strings.xml
@@ -28,7 +28,7 @@
     <string name="recents_empty_message" msgid="7967713254531861311">"Keine kürzlich verwendeten Elemente"</string>
     <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"Du hast alles gelöscht"</string>
     <string name="recents_app_info_button_label" msgid="8732926607391786762">"App-Info"</string>
-    <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"Bildschirmfixierung"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"Bildschirm anpinnen"</string>
     <string name="recents_search_bar_label" msgid="638132045925945941">"Suchen"</string>
     <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g> konnte nicht gestartet werden."</string>
     <string name="recents_launch_disabled_message" msgid="826461671965217243">"<xliff:g id="APP">%s</xliff:g> ist im abgesicherten Modus deaktiviert."</string>
diff --git a/packages/SystemUI/legacy/recents/res/values-es/strings.xml b/packages/SystemUI/legacy/recents/res/values-es/strings.xml
index 43fb3ad..8bcfe84 100644
--- a/packages/SystemUI/legacy/recents/res/values-es/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-es/strings.xml
@@ -28,7 +28,7 @@
     <string name="recents_empty_message" msgid="7967713254531861311">"No hay elementos recientes"</string>
     <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"Has borrado todo"</string>
     <string name="recents_app_info_button_label" msgid="8732926607391786762">"Información de la aplicación"</string>
-    <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"fijación de pantalla"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"fijar pantalla"</string>
     <string name="recents_search_bar_label" msgid="638132045925945941">"buscar"</string>
     <string name="recents_launch_error_message" msgid="9107963563503438012">"No se ha podido iniciar la aplicación <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="826461671965217243">"La aplicación <xliff:g id="APP">%s</xliff:g> se ha inhabilitado en modo seguro."</string>
diff --git a/packages/SystemUI/legacy/recents/res/values-fr/strings.xml b/packages/SystemUI/legacy/recents/res/values-fr/strings.xml
index 183b6be..5b0d611 100644
--- a/packages/SystemUI/legacy/recents/res/values-fr/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-fr/strings.xml
@@ -32,7 +32,7 @@
     <string name="recents_search_bar_label" msgid="638132045925945941">"rechercher"</string>
     <string name="recents_launch_error_message" msgid="9107963563503438012">"Impossible de lancer l\'application <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="recents_launch_disabled_message" msgid="826461671965217243">"L\'application <xliff:g id="APP">%s</xliff:g> est désactivée en mode sécurisé."</string>
-    <string name="recents_stack_action_button_label" msgid="1974273390109881497">"Tout effacer"</string>
+    <string name="recents_stack_action_button_label" msgid="1974273390109881497">"Tout fermer"</string>
     <string name="recents_drag_hint_message" msgid="610417221848280136">"Faire glisser ici pour utiliser l\'écran partagé"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"Séparation horizontale"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"Séparation verticale"</string>
diff --git a/packages/SystemUI/legacy/recents/res/values-sk/strings.xml b/packages/SystemUI/legacy/recents/res/values-sk/strings.xml
index cbffcaf..9c3a857 100644
--- a/packages/SystemUI/legacy/recents/res/values-sk/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-sk/strings.xml
@@ -20,7 +20,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"Prehľad"</string>
-    <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"Zrušiť aplikáciu <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"Zavrieť aplikáciu <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"Aplikácia <xliff:g id="APP">%s</xliff:g> bola zrušená."</string>
     <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"Všetky nedávne aplikácie boli zrušené."</string>
     <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"Otvoriť informácie o aplikácii <xliff:g id="APP">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
index 79c691c..a7ccc3a 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
@@ -323,7 +323,7 @@
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
         mColorExtractor.addOnColorsChangedListener(this);
         mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK,
-                WallpaperManager.FLAG_SYSTEM, true).supportsDarkText();
+                WallpaperManager.FLAG_SYSTEM).supportsDarkText();
         setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
                 : R.style.RecentsTheme_Wallpaper);
 
@@ -394,8 +394,6 @@
     @Override
     public void onColorsChanged(ColorExtractor colorExtractor, int which) {
         if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
-            // Recents doesn't care about the wallpaper being visible or not, it always
-            // wants to scrim with wallpaper colors
             ColorExtractor.GradientColors colors = mColorExtractor.getNeutralColors();
             boolean darkText = colors.supportsDarkText();
             if (darkText != mUsingDarkText) {
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java
index 14fd149..b89218c 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java
@@ -41,8 +41,10 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.recents.LegacyRecentsImpl;
 import com.android.systemui.recents.RecentsActivity;
 import com.android.systemui.recents.RecentsActivityLaunchState;
@@ -86,15 +88,15 @@
 import com.android.systemui.recents.misc.DozeTrigger;
 import com.android.systemui.recents.misc.ReferenceCountedTrigger;
 import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.utilities.AnimationProps;
 import com.android.systemui.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.views.grid.GridTaskView;
 import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
 import com.android.systemui.recents.views.grid.TaskViewFocusFrame;
-
+import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -256,7 +258,8 @@
         mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
         mStableLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, null);
         mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
-        mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
+        mTouchHandler = new TaskStackViewTouchHandler(
+                context, this, mStackScroller, Dependency.get(FalsingManager.class));
         mAnimationHelper = new TaskStackAnimationHelper(context, this);
         mTaskCornerRadiusPx = LegacyRecentsImpl.getConfiguration().isGridEnabled ?
                 res.getDimensionPixelSize(R.dimen.recents_grid_task_view_rounded_corners_radius) :
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index dd6926c..a7fb4fa 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -37,6 +37,7 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.LegacyRecentsImpl;
 import com.android.systemui.recents.events.EventBus;
@@ -107,7 +108,7 @@
     boolean mInterceptedBySwipeHelper;
 
     public TaskStackViewTouchHandler(Context context, TaskStackView sv,
-            TaskStackViewScroller scroller) {
+            TaskStackViewScroller scroller, FalsingManager falsingManager) {
         Resources res = context.getResources();
         ViewConfiguration configuration = ViewConfiguration.get(context);
         mContext = context;
@@ -119,7 +120,7 @@
         mWindowTouchSlop = configuration.getScaledWindowTouchSlop();
         mFlingAnimUtils = new FlingAnimationUtils(context, 0.2f);
         mOverscrollSize = res.getDimensionPixelSize(R.dimen.recents_fling_overscroll_distance);
-        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context) {
+        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context, falsingManager) {
             @Override
             protected float getSize(View v) {
                 return getScaledDismissSize();
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
index 28d5402..52ec1f0 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
@@ -30,7 +30,7 @@
  */
 @ProvidesInterface(version = FalsingManager.VERSION)
 public interface FalsingManager {
-    int VERSION = 1;
+    int VERSION = 2;
 
     void onSucccessfulUnlock();
 
@@ -103,4 +103,6 @@
     void onTouchEvent(MotionEvent ev, int width, int height);
 
     void dump(PrintWriter pw);
+
+    void cleanup();
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java
index 90fc86b..075df75 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java
@@ -16,12 +16,13 @@
 import android.view.View;
 
 import com.android.systemui.plugins.annotations.ProvidesInterface;
+import com.android.systemui.plugins.statusbar.DozeParameters;
 
 @ProvidesInterface(action = OverlayPlugin.ACTION, version = OverlayPlugin.VERSION)
 public interface OverlayPlugin extends Plugin {
 
     String ACTION = "com.android.systemui.action.PLUGIN_OVERLAY";
-    int VERSION = 3;
+    int VERSION = 4;
 
     /**
      * Setup overlay plugin
@@ -29,9 +30,10 @@
     void setup(View statusBar, View navBar);
 
     /**
-     * Setup overlay plugin with callback
+     * Setup overlay plugin with callback and DozeParameters
      */
-    default void setup(View statusBar, View navBar, Callback callback) {
+    default void setup(View statusBar, View navBar, Callback callback,
+            DozeParameters dozeParameters) {
         setup(statusBar, navBar);
     }
 
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
index 2cbd788..60435d0 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
@@ -58,7 +58,7 @@
         public static final int TYPE_WAKE_LOCK_SCREEN = 1;
         public static final int TYPE_WAKE_DISPLAY = 2;
         public static final int TYPE_SWIPE = 3;
-        public static final int TYPE_STATUS = 4;
+        public static final int TYPE_SKIP_STATUS = 4;
 
         private int mType;
 
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index 30d1352..85a9fec 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -34,7 +34,7 @@
 
     String ACTION = "com.android.systemui.action.PLUGIN_QS";
 
-    int VERSION = 6;
+    int VERSION = 7;
 
     String TAG = "QS";
 
@@ -51,7 +51,7 @@
     void setListening(boolean listening);
     boolean isShowingDetail();
     void closeDetail();
-    void setKeyguardShowing(boolean keyguardShowing);
+    default void setShowCollapsedOnKeyguard(boolean showCollapsedOnKeyguard) {}
     void animateHeaderSlidingIn(long delay);
     void animateHeaderSlidingOut();
     void setQsExpansion(float qsExpansionFraction, float headerTranslation);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java
new file mode 100644
index 0000000..678eb31
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.plugins.statusbar;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Retrieve doze information
+ */
+@ProvidesInterface(version = DozeParameters.VERSION)
+public interface DozeParameters {
+    int VERSION = 1;
+
+    /**
+     * Whether to doze when the screen turns off
+     */
+    boolean shouldControlScreenOff();
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
index 3ee69b4..fe547a0a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
@@ -18,7 +18,6 @@
 
 import com.android.systemui.plugins.annotations.DependsOn;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 
 
 /**
@@ -94,5 +93,15 @@
          * performance regressions.
          */
         default void onDozeAmountChanged(float linear, float eased) {}
+
+        /**
+         * Callback to be notified when the sysui visibility changes
+         */
+        default void onSystemUiVisibilityChanged(int visibility) {}
+
+        /**
+         * Callback to be notified when the pulsing state changes
+         */
+        default void onPulsingChanged(boolean pulsing) {}
     }
 }
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index a9ba19d..f4d34f4 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -41,7 +41,7 @@
             <ImageView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/widget_vertical_padding"
+                android:layout_marginTop="24dp"
                 android:layout_gravity="center_horizontal"
                 android:src="@drawable/kg_security_lock_normal" />
         </LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 04d6afc..847fba4 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -25,14 +25,13 @@
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    androidprv:layout_maxWidth="@dimen/keyguard_security_width"
-    androidprv:layout_maxHeight="@dimen/keyguard_security_height"
     android:gravity="center_horizontal|top">
     <LinearLayout
         android:id="@+id/status_view_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/widget_vertical_padding"
+        android:clipChildren="false"
+        android:clipToPadding="false"
         android:orientation="vertical">
         <TextView
             android:id="@+id/logout"
@@ -71,5 +70,11 @@
             android:letterSpacing="0.05"
             android:ellipsize="marquee"
             android:singleLine="true" />
+        <com.android.systemui.statusbar.phone.NotificationIconContainer
+            android:id="@+id/clock_notification_icon_container"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/notification_shelf_height"
+            android:layout_marginTop="@dimen/widget_vertical_padding"
+        />
     </LinearLayout>
 </com.android.keyguard.KeyguardStatusView>
diff --git a/packages/SystemUI/res-keyguard/values-af/strings.xml b/packages/SystemUI/res-keyguard/values-af/strings.xml
index 882f6e2..11bcc88 100644
--- a/packages/SystemUI/res-keyguard/values-af/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-af/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Jy het <xliff:g id="_NUMBER_1">%d</xliff:g> pogings oor voordat die SIM permanent onbruikbaar word. Kontak die diensverskaffer vir besonderhede.</item>
       <item quantity="one">SIM is nou gedeaktiveer. Voer PUK-kode in om voort te gaan. Jy het <xliff:g id="_NUMBER_0">%d</xliff:g> poging oor voordat die SIM permanent onbruikbaar word. Kontak die diensverskaffer vir besonderhede.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Verstek"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Borrel"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analoog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index 8f85eb3..4feb9f1 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም እስከመጨረሻው መጠቀም የማይቻል ከመሆኑ በፊት <xliff:g id="_NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።</item>
       <item quantity="other">ሲም አሁን ተሰናክሏል። ለመቀጠል የPUK ኮድ ያስገቡ። ሲም እስከመጨረሻው መጠቀም የማይቻል ከመሆኑ በፊት <xliff:g id="_NUMBER_1">%d</xliff:g> ሙከራዎች ይቀረዎታል። ዝርዝሮችን ለማግኘት የአገልግሎት አቅራቢን ያነጋግሩ።</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ነባሪ"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"አረፋ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"አናሎግ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 29f3570..4e163a2 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -183,4 +183,7 @@
       <item quantity="other">‏تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك <xliff:g id="_NUMBER_1">%d</xliff:g> محاولة قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item>
       <item quantity="one">‏تم إيقاف شريحة SIM الآن. أدخل رمز PUK للمتابعة، وتتبقى لديك محاولة واحدة (<xliff:g id="_NUMBER_0">%d</xliff:g>) قبل أن تصبح شريحة SIM غير صالحة للاستخدام نهائيًا. ويمكنك الاتصال بمشغل شبكة الجوّال لمعرفة التفاصيل.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"تلقائي"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"فقاعة"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"ساعة تقليدية"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index de21e49..e225675 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">ছিমখন অক্ষম হ’ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item>
       <item quantity="other">ছিমখন অক্ষম হ’ল। অব্যাহত ৰাখিবলৈ PUK দিয়ক। ছিমখন স্থায়ীভাৱে ব্যৱহাৰৰ অনুপযোগী হোৱাৰ পূৰ্বে আপোনাৰ হাতত <xliff:g id="_NUMBER_1">%d</xliff:g>টা প্ৰয়াস বাকী আছে। সবিশেষ জানিবলৈ বাহকৰ সৈতে যোগাযোগ কৰক।</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ডিফ’ল্ট"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"বাবল"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"এনাল’গ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-az/strings.xml b/packages/SystemUI/res-keyguard/values-az/strings.xml
index d83706e..c0cf129 100644
--- a/packages/SystemUI/res-keyguard/values-az/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-az/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM indi deaktivdir. Davam etmək üçün PUK kodunu daxil edin. SIM birdəfəlik yararsız olmadan öncə <xliff:g id="_NUMBER_1">%d</xliff:g> cəhdiniz qalır. Ətraflı məlumat üçün operatorla əlaqə saxlayın.</item>
       <item quantity="one">SIM indi deaktivdir. Davam etmək üçün PUK kodunu daxil edin. SIM birdəfəlik yararsız olmadan öncə <xliff:g id="_NUMBER_0">%d</xliff:g> cəhdiniz qalır. Ətraflı məlumat üçün operatorla əlaqə saxlayın.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Defolt"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Qabarcıq"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analoq"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index c0dfbc8..88ca77b 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -159,4 +159,7 @@
       <item quantity="few">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.</item>
       <item quantity="other">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja pre nego što SIM postane trajno neupotrebljiv. Detaljne informacije potražite od mobilnog operatera.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Podrazumevani"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Mehurići"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogni"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index 6b5f3ed..a897fb2 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="many">SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ <xliff:g id="_NUMBER_1">%d</xliff:g> спроб, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.</item>
       <item quantity="other">SIM-карта заблакіравана. Каб працягнуць, увядзіце PUK-код. У вас ёсць яшчэ <xliff:g id="_NUMBER_1">%d</xliff:g> спробы, пасля чаго SIM-карта будзе заблакіравана назаўсёды. Звярніцеся да аператара, каб даведацца больш.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Стандартны"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Бурбалкі"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Са стрэлкамі"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-bg/strings.xml b/packages/SystemUI/res-keyguard/values-bg/strings.xml
index 296e77a..eebdb9e 100644
--- a/packages/SystemUI/res-keyguard/values-bg/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bg/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Остават ви <xliff:g id="_NUMBER_1">%d</xliff:g> опита, преди SIM картата да стане неизползваема завинаги. Свържете се с оператора за подробности.</item>
       <item quantity="one">SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Остава ви <xliff:g id="_NUMBER_0">%d</xliff:g> опит, преди SIM картата да стане неизползваема завинаги. Свържете се с оператора за подробности.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Стандартен"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Балонен"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Аналогов"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index b6aa651..b544c14 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">সিম অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আর <xliff:g id="_NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন, তারপরে এই সিমটি আর একেবারেই ব্যবহার করা যাবে না। বিশদে জানতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।</item>
       <item quantity="other">সিম অক্ষম করা হয়েছে। চালিয়ে যেতে PUK কোড লিখুন। আপনি আর <xliff:g id="_NUMBER_1">%d</xliff:g> বার চেষ্টা করতে পারবেন, তারপরে এই সিমটি আর একেবারেই ব্যবহার করা যাবে না। বিশদে জানতে পরিষেবা প্রদানকারীর সাথে যোগাযোগ করুন।</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ডিফল্ট"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"বাবল"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"অ্যানালগ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 40e5270..8547bc8 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -22,7 +22,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name" msgid="3171996292755059205">"Zaključavanje tastature"</string>
     <string name="keyguard_password_enter_pin_code" msgid="3420548423949593123">"Upišite PIN"</string>
-    <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"Upišite PUK kôd za SIM karticu i novi PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="670683628782925409">"Upišite PUK za SIM i novi PIN kôd"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="3747778500166059332">"PUK kôd za SIM karticu"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="8188243197504453830">"Novi PIN za SIM karticu"</string>
     <string name="keyguard_password_entry_touch_hint" msgid="5790410752696806482"><font size="17">"Dodirnite da upišete lozinku"</font></string>
@@ -54,7 +54,7 @@
     <string name="keyguard_accessibility_pin_area" msgid="703175752097279029">"Prostor za PIN"</string>
     <string name="keyguard_accessibility_password" msgid="7695303207740941101">"Lozinka uređaja"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"Prostor za PIN za SIM karticu"</string>
-    <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Prostor za PUK kôd za SIM karticu"</string>
+    <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"Prostor za PUK za SIM"</string>
     <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Naredni alarm je podešen za <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Izbriši"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"Onemogući eSIM karticu"</string>
@@ -116,7 +116,7 @@
       <item quantity="other">PUK kôd za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva.</item>
     </plurals>
     <string name="kg_password_pin_failed" msgid="8769990811451236223">"Korištenje PIN-a za SIM karticu nije uspjelo!"</string>
-    <string name="kg_password_puk_failed" msgid="1331621440873439974">"Korištenje PUK koda za SIM karticu nije uspjelo!"</string>
+    <string name="kg_password_puk_failed" msgid="1331621440873439974">"Korištenje PUK-a za SIM nije uspjelo!"</string>
     <string name="kg_pin_accepted" msgid="7637293533973802143">"Kôd je prihvaćen"</string>
     <string name="keyguard_carrier_default" msgid="4274828292998453695">"Nema mreže."</string>
     <string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Promjena načina unosa"</string>
@@ -159,4 +159,7 @@
       <item quantity="few">SIM kartica je onemogućena. Unesite PUK kôd da nastavite. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Za više informacija kontaktirajte mobilnog operatera.</item>
       <item quantity="other">SIM kartica je onemogućena. Unesite PUK kôd da nastavite. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Za više informacija kontaktirajte mobilnog operatera.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Zadano"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Mjehurići"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogni"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index bb48226..ccde138 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queden <xliff:g id="_NUMBER_1">%d</xliff:g> intents; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador de telefonia mòbil per obtenir-ne més informació.</item>
       <item quantity="one">La targeta SIM s\'ha desactivat. Introdueix el codi PUK per continuar. Et queda <xliff:g id="_NUMBER_0">%d</xliff:g> intent; si no l\'encertes, la SIM no es podrà tornar a fer servir. Contacta amb l\'operador de telefonia mòbil per obtenir-ne més informació.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Predeterminada"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bombolla"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analògica"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index 536dd15..0d88a20 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="other">SIM karta je teď zablokována. Chcete-li pokračovat, zadejte kód PUK. Máte ještě <xliff:g id="_NUMBER_1">%d</xliff:g> pokusů, poté bude SIM karta natrvalo zablokována. Podrobnosti vám poskytne operátor.</item>
       <item quantity="one">SIM karta je teď zablokována. Chcete-li pokračovat, zadejte kód PUK. Máte ještě <xliff:g id="_NUMBER_0">%d</xliff:g> pokus, poté bude SIM karta natrvalo zablokována. Podrobnosti vám poskytne operátor.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Výchozí"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bublina"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogové"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index e60930d..0e6a1f3 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.</item>
       <item quantity="other">SIM-kortet er nu deaktiveret. Angiv PUK-koden for at fortsætte. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt. Kontakt dit mobilselskab for at få flere oplysninger.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Standard"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Boble"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 3a4d013..7f39a19 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -55,7 +55,7 @@
     <string name="keyguard_accessibility_password" msgid="7695303207740941101">"Gerätepasswort"</string>
     <string name="keyguard_accessibility_sim_pin_area" msgid="912702510825058921">"SIM-PIN-Bereich"</string>
     <string name="keyguard_accessibility_sim_puk_area" msgid="136979425761438705">"SIM-PUK-Bereich"</string>
-    <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nächster Wecker gestellt für <xliff:g id="ALARM">%1$s</xliff:g>"</string>
+    <string name="keyguard_accessibility_next_alarm" msgid="5835196989158584991">"Nächster Weckruf eingerichtet für <xliff:g id="ALARM">%1$s</xliff:g>"</string>
     <string name="keyboardview_keycode_delete" msgid="6883116827512721630">"Löschen"</string>
     <string name="disable_carrier_button_text" msgid="6914341927421916114">"eSIM deaktivieren"</string>
     <string name="error_disable_esim_title" msgid="4852978431156228006">"Die eSIM kann nicht deaktiviert werden"</string>
@@ -151,4 +151,7 @@
       <item quantity="other">Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Du hast noch <xliff:g id="_NUMBER_1">%d</xliff:g> Versuche, bevor die SIM-Karte endgültig gesperrt wird. Weitere Informationen erhältst du von deinem Mobilfunkanbieter.</item>
       <item quantity="one">Die SIM-Karte ist jetzt deaktiviert. Gib den PUK-Code ein, um fortzufahren. Du hast noch <xliff:g id="_NUMBER_0">%d</xliff:g> Versuch, bevor die SIM-Karte endgültig gesperrt wird. Weitere Informationen erhältst du von deinem Mobilfunkanbieter.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Standard"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Blase"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-el/strings.xml b/packages/SystemUI/res-keyguard/values-el/strings.xml
index 4733005..46b1d30 100644
--- a/packages/SystemUI/res-keyguard/values-el/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-el/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">Η κάρτα SIM απενεργοποιήθηκε. Καταχωρίστε τον κωδικό PUK, για να συνεχίσετε. Απομένουν <xliff:g id="_NUMBER_1">%d</xliff:g> ακόμη προσπάθειες προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας για λεπτομέρειες.</item>
       <item quantity="one">Η κάρτα SIM απενεργοποιήθηκε. Καταχωρίστε τον κωδικό PUK, για να συνεχίσετε. Απομένει <xliff:g id="_NUMBER_0">%d</xliff:g> ακόμη προσπάθεια προτού να μην είναι πλέον δυνατή η χρήση της κάρτας SIM. Επικοινωνήστε με την εταιρεία κινητής τηλεφωνίας για λεπτομέρειες.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Προεπιλογή"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Συννεφάκι"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Αναλογικό"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
index 8f1a94e..5640b6d 100644
--- a/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rAU/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item>
       <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Default"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bubble"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogue"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
index b7d0722..5836b72 100644
--- a/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rCA/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item>
       <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Default"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bubble"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogue"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
index 8f1a94e..5640b6d 100644
--- a/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rGB/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item>
       <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Default"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bubble"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogue"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
index 8f1a94e..5640b6d 100644
--- a/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rIN/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_1">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact operator for details.</item>
       <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="_NUMBER_0">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact operator for details.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Default"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bubble"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogue"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
index 13e87fa..fb968b7 100644
--- a/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-en-rXC/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎SIM is now disabled. Enter PUK code to continue. You have ‎‏‎‎‏‏‎<xliff:g id="_NUMBER_1">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempts before SIM becomes permanently unusable. Contact carrier for details.‎‏‎‎‏‎</item>
       <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎SIM is now disabled. Enter PUK code to continue. You have ‎‏‎‎‏‏‎<xliff:g id="_NUMBER_0">%d</xliff:g>‎‏‎‎‏‏‏‎ remaining attempt before SIM becomes permanently unusable. Contact carrier for details.‎‏‎‎‏‎</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎Default‎‏‎‎‏‎"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‎Bubble‎‏‎‎‏‎"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎Analog‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index 90ee83d..727cbad 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">Se inhabilitó la SIM. Para continuar, ingresa el código PUK. Te quedan <xliff:g id="_NUMBER_1">%d</xliff:g> intentos más antes de que la SIM quede inutilizable permanentemente. Comunícate con tu proveedor para obtener más detalles.</item>
       <item quantity="one">Se inhabilitó la SIM. Para continuar, ingresa el código PUK. Te queda <xliff:g id="_NUMBER_0">%d</xliff:g> intento más antes de que la SIM quede inutilizable permanentemente. Comunícate con tu proveedor para obtener más detalles.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Predeterminado"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Burbuja"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analógico"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index 5970c82..870741e 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">La tarjeta SIM está inhabilitada. Introduce el código PUK para continuar. Te quedan <xliff:g id="_NUMBER_1">%d</xliff:g> intentos para que la tarjeta SIM quede inservible de forma permanente. Ponte en contacto con tu operador para obtener más información.</item>
       <item quantity="one">La tarjeta SIM está inhabilitada. Introduce el código PUK para continuar. Te queda <xliff:g id="_NUMBER_0">%d</xliff:g> intento para que la tarjeta SIM quede inservible de forma permanente. Ponte en contacto con tu operador para obtener más información.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Predeterminado"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Burbuja"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analógico"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-et/strings.xml b/packages/SystemUI/res-keyguard/values-et/strings.xml
index a95a3d3..7e03a5c 100644
--- a/packages/SystemUI/res-keyguard/values-et/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-et/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Teil on jäänud veel <xliff:g id="_NUMBER_1">%d</xliff:g> katset enne, kui SIM-kaart püsivalt lukustatakse. Lisateavet küsige operaatorilt.</item>
       <item quantity="one">SIM-kaart on nüüd keelatud. Jätkamiseks sisestage PUK-kood. Teil on jäänud veel <xliff:g id="_NUMBER_0">%d</xliff:g> katse enne, kui SIM-kaart püsivalt lukustatakse. Lisateavet küsige operaatorilt.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Vaikenumbrilaud"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Mull"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analoog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-eu/strings.xml b/packages/SystemUI/res-keyguard/values-eu/strings.xml
index 64601ca..8ad942b 100644
--- a/packages/SystemUI/res-keyguard/values-eu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-eu/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. <xliff:g id="_NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIM txartela betiko erabilgaitz geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.</item>
       <item quantity="one">Desgaitu egin da SIM txartela. Aurrera egiteko, idatzi PUK kodea. <xliff:g id="_NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIM txartela betiko erabilgaitz geratu aurretik. Xehetasunak lortzeko, jarri operadorearekin harremanetan.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Lehenetsia"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Puxikak"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogikoa"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index 1c4387e..22c4c48 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">‏سیم‌کارت اکنون غیرفعال است. برای ادامه دادن کد PUK را وارد کنید. <xliff:g id="_NUMBER_1">%d</xliff:g> تلاش دیگر باقی مانده است و پس از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود. برای اطلاع از جزئیات با شرکت مخابراتی تماس بگیرید.</item>
       <item quantity="other">‏سیم‌کارت اکنون غیرفعال است. برای ادامه دادن کد PUK را وارد کنید. <xliff:g id="_NUMBER_1">%d</xliff:g> تلاش دیگر باقی مانده است و پس از آن سیم‌کارت برای همیشه غیرقابل‌استفاده می‌شود. برای اطلاع از جزئیات با شرکت مخابراتی تماس بگیرید.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"پیش‌فرض"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"حباب"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"آنالوگ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index a49b0c4..66f1de5 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM-kortti on nyt lukittu. Anna PUK-koodi, niin voit jatkaa. Sinulla on <xliff:g id="_NUMBER_1">%d</xliff:g> yritystä jäljellä, ennen kuin SIM-kortti poistuu pysyvästi käytöstä. Pyydä lisätietoja operaattoriltasi.</item>
       <item quantity="one">SIM-kortti on nyt lukittu. Anna PUK-koodi, niin voit jatkaa. Sinulla on <xliff:g id="_NUMBER_0">%d</xliff:g> yritys jäljellä, ennen kuin SIM-kortti poistuu pysyvästi käytöstä. Pyydä lisätietoja operaattoriltasi.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Oletus"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Kupla"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analoginen"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 77b1b2e..66c7c86 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM devienne définitivement inutilisable. Pour obtenir plus de détails, communiquez avec votre fournisseur de services.</item>
       <item quantity="other">La carte SIM est maintenant désactivée. Entrez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM devienne définitivement inutilisable. Pour obtenir plus de détails, communiquez avec votre fournisseur de services.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Par défaut"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bulle"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogique"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index b1f9e0d..d6aa5d2 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM ne devienne définitivement inutilisable. Pour de plus amples informations, veuillez contacter votre opérateur.</item>
       <item quantity="other">La carte SIM est maintenant désactivée. Saisissez le code PUK pour continuer. Il vous reste <xliff:g id="_NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne devienne définitivement inutilisable. Pour de plus amples informations, veuillez contacter votre opérateur.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Par défaut"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bulle"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogique"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index 55f84f8..e6b10a0 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">A SIM está desactivada. Introduce o código PUK para continuar. Quédanche <xliff:g id="_NUMBER_1">%d</xliff:g> intentos antes de que a SIM quede inutilizable para sempre. Contacta co operador para obter información.</item>
       <item quantity="one">A SIM está desactivada. Introduce o código PUK para continuar. Quédache <xliff:g id="_NUMBER_0">%d</xliff:g> intento antes de que a SIM quede inutilizable para sempre. Contacta co operador para obter información.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Predeterminado"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Burbulla"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analóxico"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index aa4ebdf..025462e 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">સિમ હવે બંધ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાયમીરૂપે બિનઉપયોગી બની જાય એ પહેલાં તમારી પાસે <xliff:g id="_NUMBER_1">%d</xliff:g> પ્રયાસ બાકી છે. વિગતો માટે કૅરિઅરનો સંપર્ક કરો.</item>
       <item quantity="other">સિમ હવે બંધ કરેલ છે. ચાલુ રાખવા માટે PUK કોડ દાખલ કરો. સિમ કાયમીરૂપે બિનઉપયોગી બની જાય એ પહેલાં તમારી પાસે <xliff:g id="_NUMBER_1">%d</xliff:g> પ્રયાસો બાકી છે. વિગતો માટે કૅરિઅરનો સંપર્ક કરો.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ડિફૉલ્ટ"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"બબલ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"એનાલોગ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-hi/strings.xml b/packages/SystemUI/res-keyguard/values-hi/strings.xml
index 86e14dc..2de75e4 100644
--- a/packages/SystemUI/res-keyguard/values-hi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hi/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास <xliff:g id="_NUMBER_1">%d</xliff:g> मौके बचे हैं, उसके बाद, सिम हमेशा के लिए काम करना बंद कर देगा. जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.</item>
       <item quantity="other">सिम बंद कर दिया गया है. जारी रखने के लिए PUK कोड डालें. आपके पास <xliff:g id="_NUMBER_1">%d</xliff:g> मौके बचे हैं, उसके बाद, सिम हमेशा के लिए काम करना बंद कर देगा. जानकारी के लिए, मोबाइल और इंटरनेट सेवा देने वाली कंपनी से संपर्क करें.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"डिफ़ॉल्ट"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"बबल"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"एनालॉग"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-hr/strings.xml b/packages/SystemUI/res-keyguard/values-hr/strings.xml
index c7f4daf..c4f7bba 100644
--- a/packages/SystemUI/res-keyguard/values-hr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hr/strings.xml
@@ -159,4 +159,7 @@
       <item quantity="few">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.</item>
       <item quantity="other">SIM je sada onemogućen. Unesite PUK kôd da biste nastavili. Imate još <xliff:g id="_NUMBER_1">%d</xliff:g> pokušaja prije nego što SIM kartica postane trajno neupotrebljiva. Više informacija zatražite od mobilnog operatera.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Zadano"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Mjehurić"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogni"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-hu/strings.xml b/packages/SystemUI/res-keyguard/values-hu/strings.xml
index 62c9799..06142bc 100644
--- a/packages/SystemUI/res-keyguard/values-hu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hu/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. Még <xliff:g id="_NUMBER_1">%d</xliff:g> próbálkozása van, mielőtt végleg használhatatlanná válik a SIM-kártya. További információért forduljon a szolgáltatóhoz.</item>
       <item quantity="one">A SIM-kártya le van tiltva. A folytatáshoz adja meg a PUK-kódot. Még <xliff:g id="_NUMBER_0">%d</xliff:g> próbálkozása van, mielőtt végleg használhatatlanná válik a SIM-kártya. További információért forduljon a szolgáltatóhoz.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Alapértelmezett"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Buborék"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analóg"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index fc9f7f2..f501fcc 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">SIM քարտն անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մնացել է <xliff:g id="_NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել: Մանրամասների համար դիմեք օպերատորին:</item>
       <item quantity="other">SIM քարտն անջատված է: Շարունակելու համար մուտքագրեք PUK կոդը: Մնացել է <xliff:g id="_NUMBER_1">%d</xliff:g> փորձ, որից հետո SIM քարտն այլևս հնարավոր չի լինի օգտագործել: Մանրամասների համար դիմեք օպերատորին:</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Կանխադրված"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Պղպջակ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Անալոգային"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index ea9a15f..64f396e 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa <xliff:g id="_NUMBER_1">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.</item>
       <item quantity="one">SIM kini dinonaktifkan. Masukkan kode PUK untuk melanjutkan. Tersisa <xliff:g id="_NUMBER_0">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan secara permanen. Hubungi operator untuk mengetahui detailnya.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Default"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Balon"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index 132e4eb..aa33215 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Það er <xliff:g id="_NUMBER_1">%d</xliff:g> tilraun eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.</item>
       <item quantity="other">SIM-kortið er nú óvirkt. Sláðu inn PUK-númer til að halda áfram. Það eru <xliff:g id="_NUMBER_1">%d</xliff:g> tilraunir eftir þar til SIM-kortið verður ónothæft til frambúðar. Hafðu samband við símafyrirtækið til að fá upplýsingar.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Sjálfgefið"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Blaðra"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Með vísum"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index 468435f..761640c 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">La scheda SIM è ora disattivata. Inserisci il codice PUK per continuare. Hai ancora <xliff:g id="_NUMBER_1">%d</xliff:g> tentativi a disposizione prima che la SIM diventi definitivamente inutilizzabile. Per informazioni dettagliate, contatta l\'operatore.</item>
       <item quantity="one">La scheda SIM è ora disattivata. Inserisci il codice PUK per continuare. Hai ancora <xliff:g id="_NUMBER_0">%d</xliff:g> tentativo a disposizione prima che la SIM diventi definitivamente inutilizzabile. Per informazioni dettagliate, contatta l\'operatore.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Predefinito"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bolla"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogico"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-iw/strings.xml b/packages/SystemUI/res-keyguard/values-iw/strings.xml
index 2b13793..e72c808 100644
--- a/packages/SystemUI/res-keyguard/values-iw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-iw/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="other">‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותרו לך <xliff:g id="_NUMBER_1">%d</xliff:g> ניסיונות נוספים לפני שכרטיס ה-SIM ינעל לצמיתות. למידע נוסף, ניתן לפנות לספק שלך.</item>
       <item quantity="one">‏כרטיס ה-SIM מושבת כעת. יש להזין קוד PUK כדי להמשיך. נותר לך <xliff:g id="_NUMBER_0">%d</xliff:g> ניסיון נוסף לפני שכרטיס ה-SIM ינעל לצמיתות. למידע נוסף, ניתן לפנות לספק שלך.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ברירת מחדל"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"בועה"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"אנלוגי"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ja/strings.xml b/packages/SystemUI/res-keyguard/values-ja/strings.xml
index 97f5b83..27adb8c 100644
--- a/packages/SystemUI/res-keyguard/values-ja/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ja/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM が無効になりました。続行するには PUK コードを入力してください。入力できるのはあと <xliff:g id="_NUMBER_1">%d</xliff:g> 回です。この回数を超えると SIM は完全に使用できなくなります。詳しくは携帯通信会社にお問い合わせください。</item>
       <item quantity="one">SIM が無効になりました。続行するには PUK コードを入力してください。入力できるのはあと <xliff:g id="_NUMBER_0">%d</xliff:g> 回です。この回数を超えると SIM は完全に使用できなくなります。詳しくは携帯通信会社にお問い合わせください。</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"デフォルト"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"バブル"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"アナログ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index 24daf4b..d165230 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. თქვენ დაგრჩათ <xliff:g id="_NUMBER_1">%d</xliff:g> მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდება. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს.</item>
       <item quantity="one">SIM ბარათი ახლა დეაქტივირებულია. გასაგრძელებლად შეიყვანეთ PUK-კოდი. თქვენ დაგრჩათ <xliff:g id="_NUMBER_0">%d</xliff:g> მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდება. დეტალური ინფორმაციისთვის დაუკავშირდით თქვენს ოპერატორს.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ნაგულისხმევი"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ბუშტი"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"ანალოგური"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 330bf53..8522346 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. <xliff:g id="_NUMBER_1">%d</xliff:g> мүмкіндік қалды, одан кейін SIM картасы біржола құлыпталады. Толығырақ мәліметті оператордан алыңыз.</item>
       <item quantity="one">SIM картасы өшірілді. Жалғастыру үшін PUK кодын енгізіңіз. <xliff:g id="_NUMBER_0">%d</xliff:g> мүмкіндік қалды, одан кейін SIM картасы біржола құлыпталады. Толығырақ мәліметті оператордан алыңыз.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Әдепкі"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Көпіршік"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Аналогтық"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-km/strings.xml b/packages/SystemUI/res-keyguard/values-km/strings.xml
index 9fd949ab..7b4266a 100644
--- a/packages/SystemUI/res-keyguard/values-km/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-km/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">ឥឡូវនេះស៊ីមត្រូវបានបិទ។ សូមបញ្ចូលកូដ PUK ដើម្បីបន្ត។ អ្នកនៅសល់ការព្យាយាម <xliff:g id="_NUMBER_1">%d</xliff:g> ដងទៀត​មុនពេល​ស៊ីម​មិនអាច​ប្រើបាន​ជា​អចិន្ត្រៃយ៍។ ទាក់ទង​ទៅ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​សម្រាប់ព័ត៌មានលម្អិត។</item>
       <item quantity="one">ឥឡូវនេះស៊ីមត្រូវបានបិទ។ សូមបញ្ចូលកូដ PUK ដើម្បីបន្ត។ អ្នកនៅសល់ការព្យាយាម <xliff:g id="_NUMBER_0">%d</xliff:g> ដងទៀតមុនពេលស៊ីមមិនអាចប្រើបានជាអចិន្ត្រៃយ៍។ ទាក់ទង​ទៅ​ក្រុមហ៊ុន​សេវា​ទូរសព្ទ​សម្រាប់​ព័ត៌មាន​លម្អិត។</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"លំនាំដើម"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ពពុះ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"អាណាឡូក"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-kn/strings.xml b/packages/SystemUI/res-keyguard/values-kn/strings.xml
index bbda27c..eaaa829 100644
--- a/packages/SystemUI/res-keyguard/values-kn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kn/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">ಸಿಮ್ ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ <xliff:g id="_NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.</item>
       <item quantity="other">ಸಿಮ್ ಅನ್ನು ಈಗ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಸಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ಸಿಮ್ ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಪ್ರಯೋಜಕವಾಗುವ ಮುನ್ನ ನಿಮ್ಮಲ್ಲಿ <xliff:g id="_NUMBER_1">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ಡೀಫಾಲ್ಟ್"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ಬಬಲ್"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"ಅನಲಾಗ್"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ko/strings.xml b/packages/SystemUI/res-keyguard/values-ko/strings.xml
index 8d8e5f8..ca84937 100644
--- a/packages/SystemUI/res-keyguard/values-ko/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ko/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. <xliff:g id="_NUMBER_1">%d</xliff:g>번 더 실패하면 SIM을 완전히 사용할 수 없게 됩니다. 자세한 내용은 이동통신사에 문의하세요.</item>
       <item quantity="one">SIM이 사용 중지되었습니다. 계속하려면 PUK 코드를 입력하세요. <xliff:g id="_NUMBER_0">%d</xliff:g>번 더 실패하면 SIM을 완전히 사용할 수 없게 됩니다. 자세한 내용은 이동통신사에 문의하세요.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"기본"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"버블"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"아날로그"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index fd02abb..805a567 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгарына <xliff:g id="_NUMBER_1">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item>
       <item quantity="one">SIM-карта азыр жарактан чыкты. Улантуу үчүн PUK-кодду киргизиңиз. SIM-картанын биротоло жарактан чыгаарына <xliff:g id="_NUMBER_0">%d</xliff:g> аракет калды. Чоо-жайын билүү үчүн байланыш операторуна кайрылыңыз.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Демейки"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Көбүк"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Аналог"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index f748376..1418d27 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">ຕອນນີ້ປິດການນຳໃຊ້ SIM ແລ້ວ. ໃສ່ລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="_NUMBER_1">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ. ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ.</item>
       <item quantity="one">ຕອນນີ້ປິດການນຳໃຊ້ SIM ແລ້ວ. ໃສ່ລະຫັດ PUK ເພື່ອດຳເນີນການຕໍ່. ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="_NUMBER_0">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຈະບໍ່ສາມາດໃຊ້ໄດ້ຖາວອນ. ກະລຸນາຕິດຕໍ່ຜູ້ໃຫ້ບໍລິການສຳລັບລາຍລະອຽດ.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ຄ່າເລີ່ມຕົ້ນ"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ຟອງ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"ໂມງເຂັມ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index c987b6a..bbd25b2 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="many">SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko <xliff:g id="_NUMBER_1">%d</xliff:g> bandymo. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.</item>
       <item quantity="other">SIM kortelė dabar yra išjungta. Jei norite tęsti, įveskite PUK kodą. Jums liko <xliff:g id="_NUMBER_1">%d</xliff:g> bandymų. Paskui visiškai nebegalėsite naudoti SIM kortelės. Jei reikia išsamios informacijos, susisiekite su operatoriumi.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Numatytasis"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Debesėlis"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analoginis"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index 2ad607e..58ca8ce 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -159,4 +159,7 @@
       <item quantity="one">SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl <xliff:g id="_NUMBER_1">%d</xliff:g> reizi. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.</item>
       <item quantity="other">SIM karte tagad ir atspējota. Ievadiet PUK kodu, lai turpinātu. Varat mēģināt vēl <xliff:g id="_NUMBER_1">%d</xliff:g> reizes. Kļūdas gadījumā SIM karti vairs nevarēs izmantot. Lai iegūtu detalizētu informāciju, sazinieties ar mobilo sakaru operatoru.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Noklusējums"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Burbuļi"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogais"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 1a3c799..1ffd8a4 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостанува уште <xliff:g id="_NUMBER_1">%d</xliff:g> обид пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.</item>
       <item quantity="other">SIM-картичката сега е оневозможена. Внесете PUK-код за да продолжите. Ви преостануваат уште <xliff:g id="_NUMBER_1">%d</xliff:g> обиди пред SIM-картичката да стане трајно неупотреблива. Контактирајте го операторот за детали.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Стандарден"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Балонче"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Аналоген"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ml/strings.xml b/packages/SystemUI/res-keyguard/values-ml/strings.xml
index 685685e..1f60c73 100644
--- a/packages/SystemUI/res-keyguard/values-ml/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ml/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി <xliff:g id="_NUMBER_1">%d</xliff:g> ശ്രമങ്ങൾ കൂടി ശേഷിക്കുന്നു. വിശദാംശങ്ങൾക്ക് കാരിയറുമായി ബന്ധപ്പെടുക.</item>
       <item quantity="one">സിം ഇപ്പോൾ പ്രവർത്തനരഹിതമാക്കി. തുടരുന്നതിന് PUK കോഡ് നൽകുക. സിം ശാശ്വതമായി ഉപയോഗശൂന്യമാകുന്നതിന് മുമ്പായി <xliff:g id="_NUMBER_0">%d</xliff:g> ശ്രമം കൂടി ശേഷിക്കുന്നു. വിശദാംശങ്ങൾക്ക് കാരിയറുമായി ബന്ധപ്പെടുക.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ഡിഫോൾട്ട്"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ബബ്ൾ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"അനലോഗ്"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index acdacdc..55dd70c 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM-г идэвхгүй болголоо. Үргэлжлүүлэхийн тулд PUK кодыг оруулна уу. Таны SIM бүрмөсөн хүчингүй болох хүртэл <xliff:g id="_NUMBER_1">%d</xliff:g> оролдлого үлдлээ. Дэлгэрэнгүй мэдээлэл авахын тулд оператор компанитайгаа холбогдоно уу.</item>
       <item quantity="one">SIM-г идэвхгүй болголоо. Үргэлжлүүлэхийн тулд PUK кодыг оруулна уу. Таны SIM бүрмөсөн хүчингүй болох хүртэл <xliff:g id="_NUMBER_0">%d</xliff:g> оролдлого үлдлээ. Дэлгэрэнгүй мэдээлэл авахын тулд оператор компанитайгаа холбогдоно уу.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Өгөгдмөл"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Бөмбөлөг"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Aналог"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 4ff6862..0ba82e0 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">सिम आता बंद केलेले आहे. सुरू ठेवण्यासाठी PUK कोड टाका. सिम कायमचे बंद होण्याआधी तुमच्याकडे <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत. तपशीलांसाठी वाहकाशी संपर्क साधा.</item>
       <item quantity="one">सिम आता बंद केलेले आहे. सुरू ठेवण्यासाठी PUK कोड टाका. सिम कायमचे बंद होण्याआधी तुमच्याकडे <xliff:g id="_NUMBER_0">%d</xliff:g> प्रयत्न शिल्लक आहे. तपशीलांसाठी वाहकाशी संपर्क साधा.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"डीफॉल्ट"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"बबल"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"अॅनालॉग"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ms/strings.xml b/packages/SystemUI/res-keyguard/values-ms/strings.xml
index 5c9e7c9..17e1056 100644
--- a/packages/SystemUI/res-keyguard/values-ms/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ms/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Tinggal <xliff:g id="_NUMBER_1">%d</xliff:g> percubaan sebelum SIM tidak boleh digunakan secara kekal. Hubungi pembawa untuk mendapatkan butiran.</item>
       <item quantity="one">Kini SIM dilumpuhkan. Masukkan kod PUK untuk meneruskan. Tinggal <xliff:g id="_NUMBER_0">%d</xliff:g> percubaan sebelum SIM tidak boleh digunakan secara kekal. Hubungi pembawa untuk mendapatkan butiran.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Lalai"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Gelembung"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-my/strings.xml b/packages/SystemUI/res-keyguard/values-my/strings.xml
index c816159..28fe2b2 100644
--- a/packages/SystemUI/res-keyguard/values-my/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-my/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">ဆင်းမ်ကဒ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ်ကဒ် အပြီးပိတ်မသွားမီ သင့်တွင် <xliff:g id="_NUMBER_1">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့် ကျန်ပါသေးသည်။ အသေးစိတ်အချက်များအတွက် ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ပါ။</item>
       <item quantity="one">ဆင်းမ်ကဒ်သည် ယခု ပိတ်သွားပါပြီ။ ရှေ့ဆက်ရန် PUK ကုဒ်ကို ထည့်ပါ။ ဆင်းမ်ကဒ် အပြီးပိတ်မသွားမီ သင့်တွင် <xliff:g id="_NUMBER_0">%d</xliff:g> ကြိမ် စမ်းသပ်ခွင့် ကျန်ပါသေးသည်။ အသေးစိတ်အချက်များအတွက် ဝန်ဆောင်မှုပေးသူကို ဆက်သွယ်ပါ။</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"မူလ"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ပူဖောင်းကွက်"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"လက်တံနာရီ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index 60a5d36..692dcad 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM-kortet er deaktivert nå. Skriv inn PUK-koden for å fortsette. Du har <xliff:g id="_NUMBER_1">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig. Kontakt operatøren for å få vite mer.</item>
       <item quantity="one">SIM-kortet er deaktivert nå. Skriv inn PUK-koden for å fortsette. Du har <xliff:g id="_NUMBER_0">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig. Kontakt operatøren for å få vite mer.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Standard"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Boble"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index 5dcacdf..8102021 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_1">%d</xliff:g> प्रयासहरू बाँकी छन्, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item>
       <item quantity="one">SIM लाई असक्षम पारिएको छ। जारी राख्न PUK कोड प्रविष्टि गर्नुहोस्। तपाईंसँग <xliff:g id="_NUMBER_0">%d</xliff:g> प्रयास बाँकी छ, त्यसपछि SIM सदाका लागि प्रयोग गर्न नमिल्ने हुन्छ। विवरणहरूका लागि सेवा प्रदायकलाई सम्पर्क गर्नुहोस्।</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"पूर्वनिर्धारित"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"बबल"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"एनालग"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 7f18008..c79f2f7 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_1">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item>
       <item quantity="one">De simkaart is nu uitgeschakeld. Geef de pukcode op om door te gaan. Je hebt nog <xliff:g id="_NUMBER_0">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt. Neem contact op met je provider voor meer informatie.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Standaard"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bel"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analoog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-or/strings.xml b/packages/SystemUI/res-keyguard/values-or/strings.xml
index e1f5123..c28561a 100644
--- a/packages/SystemUI/res-keyguard/values-or/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-or/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM କାର୍ଡକୁ ବର୍ତ୍ତମାନ ଅକ୍ଷମ କରିଦିଆଯାଇଛି। ଜାରି ରଖିବାକୁ PUK କୋଡ୍‍ ଲେଖନ୍ତୁ। ଆଉ <xliff:g id="_NUMBER_1">%d</xliff:g> ଥର ଭୁଲ କୋଡ୍‍ ଲେଖିବା ପରେ SIM କାର୍ଡ ସ୍ଥାୟୀ ଭାବେ ଅନୁପଯୋଗୀ ହୋଇଯିବ। ବିବରଣୀ ପାଇଁ କେରିଅର୍‌ର ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।</item>
       <item quantity="one">SIM କାର୍ଡକୁ ବର୍ତ୍ତମାନ ଅକ୍ଷମ କରିଦିଆଯାଇଛି। ଜାରି ରଖିବାକୁ PUK କୋଡ୍‍ ଲେଖନ୍ତୁ। ଆଉ <xliff:g id="_NUMBER_0">%d</xliff:g> ଥର ଭୁଲ କୋଡ୍‍ ଲେଖିବା ପରେ SIM କାର୍ଡ ସ୍ଥାୟୀ ଭାବେ ଅନୁପଯୋଗୀ ହୋଇଯିବ। ବିବରଣୀ ପାଇଁ କେରିଅର୍‌ର ସହ ଯୋଗାଯୋଗ କରନ୍ତୁ।</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ଡିଫଲ୍ଟ"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ବବଲ୍"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"ଆନାଲଗ୍"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index d15936d..01b5d8e 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ ਬਾਕੀ ਹੈ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item>
       <item quantity="other">ਸਿਮ ਹੁਣ ਬੰਦ ਹੋ ਗਿਆ ਹੈ। ਜਾਰੀ ਰੱਖਣ ਲਈ PUK ਕੋਡ ਦਾਖਲ ਕਰੋ। ਸਿਮ ਦੇ ਪੱਕੇ ਤੌਰ \'ਤੇ ਬੇਕਾਰ ਹੋ ਜਾਣ ਤੋਂ ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੋਲ <xliff:g id="_NUMBER_1">%d</xliff:g> ਕੋਸ਼ਿਸ਼ਾਂ ਬਾਕੀ ਹਨ। ਵੇਰਵਿਆਂ ਲਈ ਕੈਰੀਅਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ਪੂਰਵ-ਨਿਰਧਾਰਤ"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ਬੁਲਬੁਲਾ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"ਐਨਾਲੌਗ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-pl/strings.xml b/packages/SystemUI/res-keyguard/values-pl/strings.xml
index 796e3b4..f86a082 100644
--- a/packages/SystemUI/res-keyguard/values-pl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pl/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="other">Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Masz jeszcze <xliff:g id="_NUMBER_1">%d</xliff:g> próby, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.</item>
       <item quantity="one">Karta SIM została wyłączona. Wpisz kod PUK, by przejść dalej. Masz jeszcze <xliff:g id="_NUMBER_0">%d</xliff:g> próbę, zanim karta SIM zostanie trwale zablokowana. Aby uzyskać szczegółowe informacje, skontaktuj się z operatorem.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Domyślna"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bąbelkowy"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogowy"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
index bfd046e..436dd55 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rBR/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativa restante antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item>
       <item quantity="other">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas restantes antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Padrão"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bolha"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analógico"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index ba2b5bc..2ba4268 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">O SIM encontra-se desativado. Introduza o código PUK para continuar. Tem mais <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas antes de o cartão SIM ficar permanentemente inutilizável. Contacte o operador para obter mais detalhes.</item>
       <item quantity="one">O SIM encontra-se desativado. Introduza o código PUK para continuar. Tem mais <xliff:g id="_NUMBER_0">%d</xliff:g> tentativa antes de o cartão SIM ficar permanentemente inutilizável. Contacte o operador para obter mais detalhes.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Predefinido"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Balão"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analógico"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-pt/strings.xml b/packages/SystemUI/res-keyguard/values-pt/strings.xml
index bfd046e..436dd55 100644
--- a/packages/SystemUI/res-keyguard/values-pt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativa restante antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item>
       <item quantity="other">O chip agora está desativado. Informe o código PUK para continuar. Você tem <xliff:g id="_NUMBER_1">%d</xliff:g> tentativas restantes antes de o chip se tornar permanentemente inutilizável. Entre em contato com a operadora para saber mais detalhes.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Padrão"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bolha"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analógico"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index bde405c..6fdc958 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -159,4 +159,7 @@
       <item quantity="other">Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-au mai rămas <xliff:g id="_NUMBER_1">%d</xliff:g> de încercări până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.</item>
       <item quantity="one">Cardul SIM este dezactivat acum. Introduceți codul PUK pentru a continua. V-a mai rămas <xliff:g id="_NUMBER_0">%d</xliff:g> încercare până când cardul SIM va deveni inutilizabil definitiv. Contactați operatorul pentru detalii.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Prestabilit"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Balon"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogic"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index 07718c9..f9bd05b 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="many">SIM-карта отключена. Чтобы продолжить, введите PUK-код. Осталось <xliff:g id="_NUMBER_1">%d</xliff:g> попыток. После этого SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.</item>
       <item quantity="other">SIM-карта отключена. Чтобы продолжить, введите PUK-код. Осталось <xliff:g id="_NUMBER_1">%d</xliff:g> попытки. После этого SIM-карта будет заблокирована навсегда. За подробной информацией обратитесь к оператору связи.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"По умолчанию"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Пузырь"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Стрелки"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-si/strings.xml b/packages/SystemUI/res-keyguard/values-si/strings.xml
index 253cf61..e40be05 100644
--- a/packages/SystemUI/res-keyguard/values-si/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-si/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">SIM දැන් අබල කර ඇත. දිගටම කරගෙන යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව උත්සාහයන් <xliff:g id="_NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත. විස්තර සඳහා වාහක සම්බන්ධ කර ගන්න.</item>
       <item quantity="other">SIM දැන් අබල කර ඇත. දිගටම කරගෙන යාමට PUK කේතය ඇතුළු කරන්න. SIM ස්ථිරවම භාවිත කළ නොහැකි බවට පත් වීමට පෙර ඔබ සතුව උත්සාහයන් <xliff:g id="_NUMBER_1">%d</xliff:g>ක් ඉතිරිව ඇත. විස්තර සඳහා වාහක සම්බන්ධ කර ගන්න.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"පෙරනිමි"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"බුබුළ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"ප්‍රතිසමය"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sk/strings.xml b/packages/SystemUI/res-keyguard/values-sk/strings.xml
index 4a70cbc..e7800e9 100644
--- a/packages/SystemUI/res-keyguard/values-sk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sk/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="other">SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám <xliff:g id="_NUMBER_1">%d</xliff:g> pokusov, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.</item>
       <item quantity="one">SIM karta je deaktivovaná. Pokračujte zadaním kódu PUK. Zostáva vám <xliff:g id="_NUMBER_0">%d</xliff:g> pokus, potom sa SIM karta natrvalo zablokuje. Podrobnosti vám poskytne operátor.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Predvolený"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bublina"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analógový"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sl/strings.xml b/packages/SystemUI/res-keyguard/values-sl/strings.xml
index 0fbcbfc..cce3a31 100644
--- a/packages/SystemUI/res-keyguard/values-sl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sl/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="few">Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še <xliff:g id="_NUMBER_1">%d</xliff:g> poskuse. Potem bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.</item>
       <item quantity="other">Kartica SIM je zdaj onemogočena. Če želite nadaljevati, vnesite kodo PUK. Na voljo imate še <xliff:g id="_NUMBER_1">%d</xliff:g> poskusov. Potem bo kartica SIM postala trajno neuporabna. Za podrobnosti se obrnite na operaterja.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Privzeto"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Mehurček"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogno"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sq/strings.xml b/packages/SystemUI/res-keyguard/values-sq/strings.xml
index 82fefea..e4b37d0 100644
--- a/packages/SystemUI/res-keyguard/values-sq/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sq/strings.xml
@@ -38,7 +38,7 @@
     <string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet me shpejtësi"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="509533586841478405">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Po karikohet ngadalë"</string>
-    <string name="keyguard_low_battery" msgid="9218432555787624490">"Lidh ngarkuesin."</string>
+    <string name="keyguard_low_battery" msgid="9218432555787624490">"Lidh karikuesin."</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"Shtyp \"Meny\" për të shkyçur."</string>
     <string name="keyguard_network_locked_message" msgid="6743537524631420759">"Rrjeti është i kyçur"</string>
     <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"Nuk ka kartë SIM"</string>
@@ -151,4 +151,7 @@
       <item quantity="other">Karta SIM tani është çaktivizuar. Fut kodin PUK për të vazhduar. Të kanë mbetur edhe <xliff:g id="_NUMBER_1">%d</xliff:g> përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme. Kontakto me operatorin për detaje.</item>
       <item quantity="one">Karta SIM tani është çaktivizuar. Fut kodin PUK për të vazhduar. Të ka mbetur edhe <xliff:g id="_NUMBER_0">%d</xliff:g> përpjekje përpara se karta SIM të bëhet përgjithmonë e papërdorshme. Kontakto me operatorin për detaje.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"E parazgjedhur"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Flluskë"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analoge"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 23a30c8..1e6de94 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -159,4 +159,7 @@
       <item quantity="few">SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још <xliff:g id="_NUMBER_1">%d</xliff:g> покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.</item>
       <item quantity="other">SIM је сада онемогућен. Унесите PUK кôд да бисте наставили. Имате још <xliff:g id="_NUMBER_1">%d</xliff:g> покушаја пре него што SIM постане трајно неупотребљив. Детаљне информације потражите од мобилног оператера.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Подразумевани"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Мехурићи"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Аналогни"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index a9521bc..4cca176 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM-kortet är inaktiverat. Ange PUK-koden om du vill fortsätta. <xliff:g id="_NUMBER_1">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart. Kontakta operatören för mer information.</item>
       <item quantity="one">SIM-kortet är inaktiverat. Ange PUK-koden om du vill fortsätta. <xliff:g id="_NUMBER_0">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart. Kontakta operatören för mer information.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Standard"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bubbla"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index 5a19535..df51859 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">Sasa SIM imefungwa. Weka msimbo wa PUK ili uendelee. Umesalia na majaribio <xliff:g id="_NUMBER_1">%d</xliff:g> kabla ya SIM kuacha kufanya kazi kabisa. Wasiliana na mtoa huduma kwa maelezo.</item>
       <item quantity="one">Sasa SIM imefungwa. Weka msimbo wa PUK ili uendelee. Umesalia na jaribio <xliff:g id="_NUMBER_0">%d</xliff:g> kabla ya SIM kuacha kufanya kazi kabisa. Wasiliana na mtoa huduma kwa maelezo.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Chaguomsingi"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Kiputo"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analogi"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index db23ccc..9aa1972 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_1">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item>
       <item quantity="one">சிம் தற்போது முடக்கப்பட்டுள்ளது. தொடர்வதற்கு, PUK குறியீட்டை உள்ளிடவும். நீங்கள் <xliff:g id="_NUMBER_0">%d</xliff:g> முறை மட்டுமே முயற்சிக்க முடியும். அதன்பிறகு சிம் நிரந்தரமாக முடக்கப்படும். விவரங்களுக்கு, மொபைல் நிறுவனத்தைத் தொடர்புகொள்ளவும்.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"இயல்பு"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"பபிள்"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"அனலாக்"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-te/strings.xml b/packages/SystemUI/res-keyguard/values-te/strings.xml
index 4cc7056..925d673 100644
--- a/packages/SystemUI/res-keyguard/values-te/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-te/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్‌ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_1">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి. వివరాల కోసం కారియర్‌ను సంప్రదించండి.</item>
       <item quantity="one">SIM ఇప్పుడు నిలిపివేయబడింది. PUK కోడ్‌ను నమోదు చేయండి. SIM శాశ్వతంగా నిరుపయోగం కాకుండా ఉండటానికి మీకు <xliff:g id="_NUMBER_0">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది వివరాల కోసం కారియర్‌ను సంప్రదించండి.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"డిఫాల్ట్"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"బబుల్"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"ఎనలాగ్"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-th/strings.xml b/packages/SystemUI/res-keyguard/values-th/strings.xml
index 9ba096a7..c439c32 100644
--- a/packages/SystemUI/res-keyguard/values-th/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-th/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">ซิมถูกปิดใช้งานในขณะนี้ โปรดป้อนรหัส PUK เพื่อทำต่อ คุณพยายามได้อีก <xliff:g id="_NUMBER_1">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร โปรดติดต่อสอบถามรายละเอียดจากผู้ให้บริการ</item>
       <item quantity="one">ซิมถูกปิดใช้งานในขณะนี้ โปรดป้อนรหัส PUK เพื่อทำต่อ คุณพยายามได้อีก <xliff:g id="_NUMBER_0">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร โปรดติดต่อสอบถามรายละเอียดจากผู้ให้บริการ</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ค่าเริ่มต้น"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"ลูกโป่ง"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"แอนะล็อก"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-tl/strings.xml b/packages/SystemUI/res-keyguard/values-tl/strings.xml
index 4f247c3..a9ca1b6 100644
--- a/packages/SystemUI/res-keyguard/values-tl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tl/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">Naka-disable na ang SIM. Ilagay ang PUK code upang magpatuloy. Mayroon kang <xliff:g id="_NUMBER_1">%d</xliff:g> natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.</item>
       <item quantity="other">Naka-disable na ang SIM. Ilagay ang PUK code upang magpatuloy. Mayroon kang <xliff:g id="_NUMBER_1">%d</xliff:g> na natitirang pagsubok bago tuluyang hindi magamit ang SIM. Makipag-ugnayan sa carrier para sa mga detalye.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Default"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bubble"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index fc4fa40..4e81505 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM artık devre dışı. Devam etmek için PUK kodunu girin. SIM kalıcı olarak kullanım dışı kalmadan önce <xliff:g id="_NUMBER_1">%d</xliff:g> deneme hakkınız kaldı. Ayrıntılı bilgi için operatörünüzle iletişim kurun.</item>
       <item quantity="one">SIM artık devre dışı. Devam etmek için PUK kodunu girin. SIM kalıcı olarak kullanım dışı kalmadan önce <xliff:g id="_NUMBER_0">%d</xliff:g> deneme hakkınız kaldı. Ayrıntılı bilgi için operatörünüzle iletişim kurun.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Varsayılan"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Baloncuk"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index e3b5256..c683e32 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -167,4 +167,7 @@
       <item quantity="many">SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. Залишилося <xliff:g id="_NUMBER_1">%d</xliff:g> спроб. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.</item>
       <item quantity="other">SIM-карту заблоковано. Щоб продовжити, введіть PUK-код. Залишилося <xliff:g id="_NUMBER_1">%d</xliff:g> спроби. Після цього SIM-карту буде назавжди заблоковано. Щоб дізнатися більше, зверніться до свого оператора.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"За умовчанням"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Бульбашковий"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Аналоговий"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-ur/strings.xml b/packages/SystemUI/res-keyguard/values-ur/strings.xml
index ed44c03..96b949b 100644
--- a/packages/SystemUI/res-keyguard/values-ur/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ur/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">‏SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس <xliff:g id="_NUMBER_1">%d</xliff:g> کوششیں بچی ہیں۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔</item>
       <item quantity="one">‏SIM اب غیر فعال ہے۔ جاری رکھنے کیلئے PUK کوڈ درج کریں۔ SIM کے مستقل طور پر ناقابل استعمال ہونے سے پہلے آپ کے پاس <xliff:g id="_NUMBER_0">%d</xliff:g> کوشش بچی ہے۔ تفصیلات کیلئے کیریئر سے رابطہ کریں۔</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"ڈیفالٹ"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"بلبلہ"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"اینالاگ"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-uz/strings.xml b/packages/SystemUI/res-keyguard/values-uz/strings.xml
index b78e5bff..80509ac 100644
--- a/packages/SystemUI/res-keyguard/values-uz/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uz/strings.xml
@@ -153,4 +153,7 @@
       <item quantity="other">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_1">%d</xliff:g> marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item>
       <item quantity="one">SIM karta faolsizlantirildi. Davom etish uchun PUK kodni kiriting. Yana <xliff:g id="_NUMBER_0">%d</xliff:g> marta xato qilsangiz, SIM kartangiz butunlay qulflanadi. Batafsil axborot olish uchun tarmoq operatoriga murojaat qiling.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Odatiy"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Pufaklar"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index 7f51ace..b8c1998 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM hiện đã bị tắt. Hãy nhập mã PUK để tiếp tục. Bạn còn <xliff:g id="_NUMBER_1">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ để biết chi tiết.</item>
       <item quantity="one">SIM hiện đã bị tắt. Hãy nhập mã PUK để tiếp tục. Bạn còn <xliff:g id="_NUMBER_0">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không thể sử dụng được. Hãy liên hệ với nhà cung cấp dịch vụ để biết chi tiết.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Mặc định"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Bong bóng"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"Đồng hồ kim"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
index 7e50824..88fc363 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rCN/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM 卡现已停用,请输入 PUK 码继续使用。您还可以尝试 <xliff:g id="_NUMBER_1">%d</xliff:g> 次。如果仍不正确,该 SIM 卡将永远无法使用。有关详情,请联系您的运营商。</item>
       <item quantity="one">SIM 卡现已停用,请输入 PUK 码继续使用。您还可以尝试 <xliff:g id="_NUMBER_0">%d</xliff:g> 次。如果仍不正确,该 SIM 卡将永远无法使用。有关详情,请联系您的运营商。</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"默认"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"泡泡"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"指针"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index f416cee..2d84106 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 <xliff:g id="_NUMBER_1">%d</xliff:g> 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請與流動網絡供應商聯絡。</item>
       <item quantity="one">SIM 卡已停用。請輸入 PUK 碼以繼續進行。您還可以再試 <xliff:g id="_NUMBER_0">%d</xliff:g> 次。如果仍然輸入錯誤,SIM 卡將永久無法使用。詳情請與流動網絡供應商聯絡。</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"預設"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"泡泡"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"指針"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index c224e22..18b9479 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="other">SIM 卡現在已遭停用。請輸入 PUK 碼以繼續進行。你還可以再試 <xliff:g id="_NUMBER_1">%d</xliff:g> 次,如果仍然失敗,SIM 卡將永久無法使用。詳情請與電信業者聯絡。</item>
       <item quantity="one">SIM 卡現在已遭停用。請輸入 PUK 碼以繼續進行。你還可以再試 <xliff:g id="_NUMBER_0">%d</xliff:g> 次,如果仍然失敗,SIM 卡將永久無法使用。詳情請與電信業者聯絡。</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"預設"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"泡泡"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"類比"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values-zu/strings.xml b/packages/SystemUI/res-keyguard/values-zu/strings.xml
index b4351a7..6a7f647 100644
--- a/packages/SystemUI/res-keyguard/values-zu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zu/strings.xml
@@ -151,4 +151,7 @@
       <item quantity="one">I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unemizamo engu-<xliff:g id="_NUMBER_1">%d</xliff:g> esele ngaphambi kokuthi i-SIM ingasebenziseki unaphakade. Xhumana nenkampani yenethiwekhi ngemininingwane.</item>
       <item quantity="other">I-SIM manje ikhutshaziwe. Faka ikhodi ye-PUK ukuze uqhubeke. Unemizamo engu-<xliff:g id="_NUMBER_1">%d</xliff:g> esele ngaphambi kokuthi i-SIM ingasebenziseki unaphakade. Xhumana nenkampani yenethiwekhi ngemininingwane.</item>
     </plurals>
+    <string name="clock_title_default" msgid="6645600990069154049">"Okuzenzekelayo"</string>
+    <string name="clock_title_bubble" msgid="1286365278681892114">"Ibhamuza"</string>
+    <string name="clock_title_analog" msgid="4047401488577315053">"I-Analog"</string>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 8e00efe..f9389ce 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -53,8 +53,8 @@
     <dimen name="title_clock_padding">4dp</dimen>
     <!-- Clock with header -->
     <dimen name="widget_small_font_size">@dimen/widget_title_font_size</dimen>
-    <dimen name="widget_vertical_padding">24dp</dimen>
-    <dimen name="widget_vertical_padding_with_header">32dp</dimen>
+    <dimen name="widget_vertical_padding">17dp</dimen>
+    <dimen name="widget_vertical_padding_with_header">25dp</dimen>
     <dimen name="widget_vertical_padding_clock">12dp</dimen>
     <!-- Subtitle paddings -->
     <dimen name="widget_horizontal_padding">8dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 9b47e14..0fe7084 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -407,14 +407,11 @@
 number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item>
     </plurals>
 
-    <!-- Title for default clock face that will appear in the picker app next to a preview image of
-         the clock face. [CHAR LIMIT=8] -->
-    <string name="clock_title_default" translatable="false">Default</string>
-    <!-- Title for Bubble clock face that will appear in the picker app next to a preview image of
-         the clock face. [CHAR LIMIT=8] -->
-    <string name="clock_title_bubble" translatable="false">Bubble</string>
-    <!-- Title for Stretch clock face that will appear in the picker app next to a preview image of
-         the clock face. [CHAR LIMIT=8] -->
-    <string name="clock_title_analog" translatable="false">Analog</string>
+    <!-- Name of the "Default" clock face, which is the clock face that will be shown by default. [CHAR LIMIT=15]-->
+    <string name="clock_title_default">Default</string>
+    <!-- Name of the "Bubble" clock face, which is an analog clock with hands shaped like large bubbles [CHAR LIMIT=15]-->
+    <string name="clock_title_bubble">Bubble</string>
+    <!-- Name of the "Analog" clock face [CHAR LIMIT=15]-->
+    <string name="clock_title_analog">Analog</string>
 
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 9a04222..67c4458 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -111,7 +111,7 @@
         <item name="android:colorBackground">@*android:color/background_material_dark</item>
     </style>
 
-    <style name="TextAppearance.Keyguard" parent="Theme.SystemUI">
+    <style name="TextAppearance.Keyguard">
         <item name="android:textSize">@dimen/widget_title_font_size</item>
         <item name="android:gravity">center</item>
         <item name="android:ellipsize">end</item>
diff --git a/packages/SystemUI/res/anim/lock_in.xml b/packages/SystemUI/res/anim/lock_in.xml
deleted file mode 100644
index c7014e8..0000000
--- a/packages/SystemUI/res/anim/lock_in.xml
+++ /dev/null
@@ -1,227 +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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-                 xmlns:aapt="http://schemas.android.com/aapt">
-    <aapt:attr name="android:drawable">
-        <vector android:height="42dp" android:width="32dp" android:viewportHeight="42"
-                android:viewportWidth="32">
-            <group android:name="_R_G">
-                <group android:name="_R_G_L_2_G" android:translateX="1.6669999999999998"
-                       android:translateY="11.992999999999999" android:pivotX="14.333"
-                       android:pivotY="13" android:scaleX="0" android:scaleY="0">
-                    <path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#ffffff"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1"
-                          android:pathData=" M22.33 21 C22.33,21 6.33,21 6.33,21 C5.6,21 5,20.4 5,19.67 C5,19.67 5,6.33 5,6.33 C5,5.6 5.6,5 6.33,5 C6.33,5 22.33,5 22.33,5 C23.07,5 23.67,5.6 23.67,6.33 C23.67,6.33 23.67,19.67 23.67,19.67 C23.67,20.4 23.07,21 22.33,21c "/>
-                </group>
-                <group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="1.6669999999999998"
-                       android:translateY="11.992999999999999" android:pivotX="14.333"
-                       android:pivotY="13" android:scaleX="0" android:scaleY="0">
-                    <group android:name="_R_G_L_1_G" android:translateX="11.583"
-                           android:translateY="10.257">
-                        <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
-                              android:fillAlpha="1" android:fillType="nonZero"
-                              android:pathData=" M2.75 0.25 C4.13,0.25 5.25,1.37 5.25,2.75 C5.25,4.13 4.13,5.25 2.75,5.25 C1.37,5.25 0.25,4.13 0.25,2.75 C0.25,1.37 1.37,0.25 2.75,0.25c "/>
-                    </group>
-                </group>
-                <group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="1.6669999999999998"
-                       android:translateY="11.992999999999999" android:pivotX="14.333"
-                       android:pivotY="13" android:scaleX="0" android:scaleY="0">
-                    <group android:name="_R_G_L_0_G_T_1" android:translateX="14.333"
-                           android:translateY="3.172">
-                        <group android:name="_R_G_L_0_G" android:translateX="-9.667"
-                               android:translateY="-9.667">
-                            <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff"
-                                  android:strokeLineCap="round" android:strokeLineJoin="round"
-                                  android:strokeWidth="2" android:strokeAlpha="1"
-                                  android:trimPathStart="0.14" android:trimPathEnd="0.89"
-                                  android:trimPathOffset="0"
-                                  android:pathData=" M14.33 14.33 C14.33,14.33 14.33,9.67 14.33,9.67 C14.33,7.09 12.24,5 9.67,5 C7.09,5 5,7.09 5,9.67 C5,9.67 5,14.33 5,14.33 "/>
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group"/>
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="233"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="233"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="117"
-                                android:startOffset="233" android:valueFrom="1.02"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="117"
-                                android:startOffset="233" android:valueFrom="1.02"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_4_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="233"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="233"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="117"
-                                android:startOffset="233" android:valueFrom="1.02"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="117"
-                                android:startOffset="233" android:valueFrom="1.02"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathStart" android:duration="50"
-                                android:startOffset="0" android:valueFrom="0.14"
-                                android:valueTo="0.14" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator
-                            android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="trimPathStart" android:duration="67"
-                                android:startOffset="50" android:valueFrom="0.14"
-                                android:valueTo="0" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator
-                            android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="50"
-                                android:startOffset="0" android:valueFrom="0.89"
-                                android:valueTo="0.89" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator
-                            android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="67"
-                                android:startOffset="50" android:valueFrom="0.89"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator
-                            android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_T_1">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="translateY" android:duration="150"
-                                android:startOffset="0" android:valueFrom="3.172"
-                                android:valueTo="0.34" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.23,-0.46 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_N_4_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="233"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="233"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="117"
-                                android:startOffset="233" android:valueFrom="1.02"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="117"
-                                android:startOffset="233" android:valueFrom="1.02"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="translateX" android:duration="717"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType"/>
-            </set>
-        </aapt:attr>
-    </target>
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_in_circular.xml b/packages/SystemUI/res/anim/lock_in_circular.xml
deleted file mode 100644
index d1e98db..0000000
--- a/packages/SystemUI/res/anim/lock_in_circular.xml
+++ /dev/null
@@ -1,327 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <aapt:attr name="android:drawable" >
-        <vector
-            android:height="32dp"
-            android:viewportHeight="32"
-            android:viewportWidth="32"
-            android:width="32dp" >
-            <group android:name="_R_G" >
-                <group
-                    android:name="_R_G_L_2_G"
-                    android:pivotX="9.583"
-                    android:pivotY="8.916"
-                    android:scaleX="0"
-                    android:scaleY="0"
-                    android:translateX="6.416"
-                    android:translateY="10.416999999999998" >
-                    <path
-                        android:name="_R_G_L_2_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="#ffffff"
-                        android:fillType="nonZero"
-                        android:pathData=" M17.42 1.75 C17.42,1.75 17.42,14.58 17.42,14.58 C17.42,15.41 16.74,16.08 15.92,16.08 C15.92,16.08 3.25,16.08 3.25,16.08 C2.42,16.08 1.75,15.41 1.75,14.58 C1.75,14.58 1.75,1.75 1.75,1.75 C1.75,1.75 17.42,1.75 17.42,1.75c  M18.92 0.25 C18.92,0.25 0.25,0.25 0.25,0.25 C0.25,0.25 0.25,14.58 0.25,14.58 C0.25,16.24 1.59,17.58 3.25,17.58 C3.25,17.58 15.92,17.58 15.92,17.58 C17.57,17.58 18.92,16.24 18.92,14.58 C18.92,14.58 18.92,0.25 18.92,0.25c " />
-                </group>
-                <group
-                    android:name="_R_G_L_1_G_N_3_T_0"
-                    android:pivotX="9.583"
-                    android:pivotY="8.916"
-                    android:scaleX="0"
-                    android:scaleY="0"
-                    android:translateX="6.416"
-                    android:translateY="10.416999999999998" >
-                    <group
-                        android:name="_R_G_L_1_G"
-                        android:translateX="7.334"
-                        android:translateY="5.333" >
-                        <path
-                            android:name="_R_G_L_1_G_D_0_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="#ffffff"
-                            android:fillType="nonZero"
-                            android:pathData=" M4.25 2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25 C3.35,0.25 4.25,1.15 4.25,2.25c " />
-                        <path
-                            android:name="_R_G_L_1_G_D_1_P_0"
-                            android:pathData=" M2.25 2.25 C2.25,2.25 2.25,5.92 2.25,5.92 "
-                            android:strokeAlpha="1"
-                            android:strokeColor="#ffffff"
-                            android:strokeLineCap="round"
-                            android:strokeLineJoin="round"
-                            android:strokeWidth="1.5" />
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_0_G_N_3_T_0"
-                    android:pivotX="9.583"
-                    android:pivotY="8.916"
-                    android:scaleX="0"
-                    android:scaleY="0"
-                    android:translateX="6.416"
-                    android:translateY="10.416999999999998" >
-                    <group
-                        android:name="_R_G_L_0_G_T_1"
-                        android:translateX="9.583"
-                        android:translateY="-0.861" >
-                        <group
-                            android:name="_R_G_L_0_G"
-                            android:translateX="-8.083"
-                            android:translateY="-8.173" >
-                            <path
-                                android:name="_R_G_L_0_G_D_0_P_0"
-                                android:pathData=" M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
-                                android:strokeAlpha="1"
-                                android:strokeColor="#ffffff"
-                                android:strokeLineCap="round"
-                                android:strokeLineJoin="round"
-                                android:strokeWidth="1.5"
-                                android:trimPathEnd="0.9"
-                                android:trimPathOffset="0"
-                                android:trimPathStart="0.15" />
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-
-    <target android:name="_R_G_L_2_G" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_3_T_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="trimPathStart"
-                    android:startOffset="0"
-                    android:valueFrom="0.15"
-                    android:valueTo="0.15"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="trimPathStart"
-                    android:startOffset="50"
-                    android:valueFrom="0.15"
-                    android:valueTo="0"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="0"
-                    android:valueFrom="0.9"
-                    android:valueTo="0.9"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="50"
-                    android:valueFrom="0.9"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="150"
-                    android:pathData="M 9.583,-0.861C 9.583,-1.32784640645981 9.583,-3.19515359354019 9.583,-3.662"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="0" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_N_3_T_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="717"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_in_filled.xml b/packages/SystemUI/res/anim/lock_in_filled.xml
deleted file mode 100644
index 4cde38d..0000000
--- a/packages/SystemUI/res/anim/lock_in_filled.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <aapt:attr name="android:drawable" >
-        <vector
-            android:height="32dp"
-            android:viewportHeight="32"
-            android:viewportWidth="32"
-            android:width="32dp" >
-            <group android:name="_R_G" >
-                <group
-                    android:name="_R_G_L_1_G"
-                    android:pivotX="10.917"
-                    android:pivotY="9.583"
-                    android:scaleX="0"
-                    android:scaleY="0"
-                    android:translateX="5.083"
-                    android:translateY="10.417" >
-                    <path
-                        android:name="_R_G_L_1_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="#ffffff"
-                        android:fillType="nonZero"
-                        android:pathData=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c  M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c " />
-                </group>
-                <group
-                    android:name="_R_G_L_0_G_N_2_T_0"
-                    android:pivotX="10.917"
-                    android:pivotY="9.583"
-                    android:scaleX="0"
-                    android:scaleY="0"
-                    android:translateX="5.083"
-                    android:translateY="10.417" >
-                    <group
-                        android:name="_R_G_L_0_G_T_1"
-                        android:translateX="10.917"
-                        android:translateY="0.579" >
-                        <group
-                            android:name="_R_G_L_0_G"
-                            android:translateX="-9"
-                            android:translateY="-9" >
-                            <path
-                                android:name="_R_G_L_0_G_D_0_P_0"
-                                android:pathData=" M13 13 C13,13 13,9 13,9 C13,6.79 11.21,5 9,5 C6.79,5 5,6.79 5,9 C5,9 5,13 5,13 "
-                                android:strokeAlpha="1"
-                                android:strokeColor="#ffffff"
-                                android:strokeLineCap="round"
-                                android:strokeLineJoin="round"
-                                android:strokeWidth="2" />
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-
-    <target android:name="_R_G_L_1_G" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="150"
-                    android:pathData="M 10.917,0.579C 10.917,-0.14248990631104008 10.917,-3.02851009368896 10.917,-3.75"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="0" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_N_2_T_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="717"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_in_rounded.xml b/packages/SystemUI/res/anim/lock_in_rounded.xml
deleted file mode 100644
index 7c8cf9d..0000000
--- a/packages/SystemUI/res/anim/lock_in_rounded.xml
+++ /dev/null
@@ -1,336 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-
-    <aapt:attr name="android:drawable" >
-        <vector
-            android:height="38dp"
-            android:viewportHeight="38"
-            android:viewportWidth="32"
-            android:width="32dp" >
-            <group android:name="_R_G" >
-                <group
-                    android:name="_R_G_L_2_G"
-                    android:pivotX="14.667"
-                    android:pivotY="12.667"
-                    android:scaleX="0"
-                    android:scaleY="0"
-                    android:translateX="1.3330000000000002"
-                    android:translateY="10.333" >
-                    <path
-                        android:name="_R_G_L_2_G_D_0_P_0"
-                        android:pathData=" M22.09 5 C22.09,5 6,5 6,5 C5.45,5 5,5.45 5,6 C5,6 5,19.33 5,19.33 C5,19.89 5.45,20.33 6,20.33 C6,20.33 23.33,20.33 23.33,20.33 C23.89,20.33 24.33,19.89 24.33,19.33 C24.33,19.33 24.33,6 24.33,6 C24.33,5.45 23.89,5 23.33,5 C23.33,5 22.09,5 22.09,5c "
-                        android:strokeAlpha="1"
-                        android:strokeColor="#ffffff"
-                        android:strokeLineCap="round"
-                        android:strokeLineJoin="round"
-                        android:strokeWidth="1.5" />
-                </group>
-                <group
-                    android:name="_R_G_L_1_G_N_3_T_0"
-                    android:pivotX="14.667"
-                    android:pivotY="12.667"
-                    android:scaleX="0"
-                    android:scaleY="0"
-                    android:translateX="1.3330000000000002"
-                    android:translateY="10.333" >
-                    <group
-                        android:name="_R_G_L_1_G"
-                        android:translateX="12.416"
-                        android:translateY="10.417" >
-                        <path
-                            android:name="_R_G_L_1_G_D_0_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="#ffffff"
-                            android:fillType="nonZero"
-                            android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c " />
-                    </group>
-                </group>
-                <group android:name="_R_G_L_0_G_N_3_T_0_M" >
-                    <group
-                        android:name="_R_G_L_0_G_N_3_T_0"
-                        android:pivotX="14.667"
-                        android:pivotY="12.667"
-                        android:scaleX="0"
-                        android:scaleY="0"
-                        android:translateX="1.3330000000000002"
-                        android:translateY="10.333" >
-                        <group
-                            android:name="_R_G_L_0_G_T_1"
-                            android:translateX="14.666"
-                            android:translateY="3.769" >
-                            <group
-                                android:name="_R_G_L_0_G"
-                                android:translateX="-9.333"
-                                android:translateY="-9.713" >
-                                <path
-                                    android:name="_R_G_L_0_G_D_0_P_0"
-                                    android:pathData=" M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
-                                    android:strokeAlpha="1"
-                                    android:strokeColor="#ffffff"
-                                    android:strokeLineCap="round"
-                                    android:strokeLineJoin="round"
-                                    android:strokeWidth="1.5"
-                                    android:trimPathEnd="0.9"
-                                    android:trimPathOffset="0"
-                                    android:trimPathStart="0.14" />
-                            </group>
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-
-    <target android:name="_R_G_L_2_G" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_3_T_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="trimPathStart"
-                    android:startOffset="0"
-                    android:valueFrom="0.14"
-                    android:valueTo="0.14"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="trimPathStart"
-                    android:startOffset="50"
-                    android:valueFrom="0.14"
-                    android:valueTo="0"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="0"
-                    android:valueFrom="0.9"
-                    android:valueTo="0.9"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="50"
-                    android:valueFrom="0.9"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="150"
-                    android:pathData="M 14.666,3.769C 14.666,3.18868762874603 14.666,0.8673123712539699 14.666,0.287"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="0" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_N_3_T_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1.025"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.043,0.277 0.44,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="233"
-                    android:valueFrom="1.025"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_N_3_T_0_M" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleX"
-                    android:startOffset="50"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="717"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_unlock.xml b/packages/SystemUI/res/anim/lock_unlock.xml
index 91d4432..64456ce 100644
--- a/packages/SystemUI/res/anim/lock_unlock.xml
+++ b/packages/SystemUI/res/anim/lock_unlock.xml
@@ -34,7 +34,7 @@
                             android:pathData=" M22.33 21 C22.33,21 6.33,21 6.33,21 C5.6,21 5,20.4 5,19.67 C5,19.67 5,6.33 5,6.33 C5,5.6 5.6,5 6.33,5 C6.33,5 22.33,5 22.33,5 C23.07,5 23.67,5.6 23.67,6.33 C23.67,6.33 23.67,19.67 23.67,19.67 C23.67,20.4 23.07,21 22.33,21c "
                             android:strokeWidth="2"
                             android:strokeAlpha="1"
-                            android:strokeColor="#ffffff" />
+                            android:strokeColor="#ffffff"/>
                     </group>
                 </group>
                 <group
@@ -79,7 +79,7 @@
                                 android:pathData=" M14.33 14.33 C14.33,14.33 14.33,9.67 14.33,9.67 C14.33,7.09 12.24,5 9.67,5 C7.09,5 5,7.09 5,9.67 C5,9.67 5,14.33 5,14.33 "
                                 android:strokeWidth="2"
                                 android:strokeAlpha="1"
-                                android:strokeColor="#ffffff" />
+                                android:strokeColor="#ffffff"/>
                         </group>
                     </group>
                 </group>
@@ -230,7 +230,7 @@
                     </aapt:attr>
                 </objectAnimator>
                 <objectAnimator
-                    android:duration="333"
+                    android:duration="183"
                     android:propertyName="pathData"
                     android:startOffset="67"
                     android:valueFrom="M14.33 14.33 C14.33,14.33 14.29,6.17 14.29,6.17 C14.29,3.59 12.2,1.5 9.63,1.5 C7.05,1.5 4.96,3.59 4.96,6.17 C4.96,6.17 4.96,7.33 4.96,7.33 "
@@ -286,7 +286,7 @@
         <aapt:attr name="android:animation">
             <set android:ordering="together">
                 <objectAnimator
-                    android:duration="717"
+                    android:duration="983"
                     android:propertyName="translateX"
                     android:startOffset="0"
                     android:valueFrom="0"
diff --git a/packages/SystemUI/res/anim/lock_unlock_circular.xml b/packages/SystemUI/res/anim/lock_unlock_circular.xml
index 5fc8576..c3968ac 100644
--- a/packages/SystemUI/res/anim/lock_unlock_circular.xml
+++ b/packages/SystemUI/res/anim/lock_unlock_circular.xml
@@ -1,298 +1,212 @@
-<?xml version="1.0" encoding="utf-8"?>
-<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
-    xmlns:android="http://schemas.android.com/apk/res/android" >
+<!-- Copyright (C) 2019 The Android Open Source Project
 
-    <aapt:attr name="android:drawable" >
-        <vector
-            android:height="42dp"
-            android:viewportHeight="42"
-            android:viewportWidth="32"
-            android:width="32dp" >
-            <group android:name="_R_G" >
-                <group
-                    android:name="_R_G_L_2_G_T_1"
-                    android:translateX="15.999"
-                    android:translateY="24.333" >
-                    <group
-                        android:name="_R_G_L_2_G"
-                        android:translateX="-9.583"
-                        android:translateY="-8.916" >
-                        <path
-                            android:name="_R_G_L_2_G_D_0_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="#ffffff"
-                            android:fillType="nonZero"
-                            android:pathData=" M17.42 1.75 C17.42,1.75 17.42,14.58 17.42,14.58 C17.42,15.41 16.74,16.08 15.92,16.08 C15.92,16.08 3.25,16.08 3.25,16.08 C2.42,16.08 1.75,15.41 1.75,14.58 C1.75,14.58 1.75,1.75 1.75,1.75 C1.75,1.75 17.42,1.75 17.42,1.75c  M18.92 0.25 C18.92,0.25 0.25,0.25 0.25,0.25 C0.25,0.25 0.25,14.58 0.25,14.58 C0.25,16.24 1.59,17.58 3.25,17.58 C3.25,17.58 15.92,17.58 15.92,17.58 C17.57,17.58 18.92,16.24 18.92,14.58 C18.92,14.58 18.92,0.25 18.92,0.25c " />
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="42dp" android:width="32dp" android:viewportHeight="42"
+                android:viewportWidth="32">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_2_G_T_1" android:translateX="15.999"
+                       android:translateY="24.333">
+                    <group android:name="_R_G_L_2_G" android:translateX="-9.583"
+                           android:translateY="-8.916">
+                        <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#ffffff"
+                              android:fillAlpha="1" android:fillType="nonZero"
+                              android:pathData=" M17.42 1.75 C17.42,1.75 17.42,14.58 17.42,14.58 C17.42,15.41 16.74,16.08 15.92,16.08 C15.92,16.08 3.25,16.08 3.25,16.08 C2.42,16.08 1.75,15.41 1.75,14.58 C1.75,14.58 1.75,1.75 1.75,1.75 C1.75,1.75 17.42,1.75 17.42,1.75c  M18.92 0.25 C18.92,0.25 0.25,0.25 0.25,0.25 C0.25,0.25 0.25,14.58 0.25,14.58 C0.25,16.24 1.59,17.58 3.25,17.58 C3.25,17.58 15.92,17.58 15.92,17.58 C17.57,17.58 18.92,16.24 18.92,14.58 C18.92,14.58 18.92,0.25 18.92,0.25c "/>
                     </group>
                 </group>
-                <group
-                    android:name="_R_G_L_1_G_N_3_T_1"
-                    android:translateX="15.999"
-                    android:translateY="24.333" >
-                    <group
-                        android:name="_R_G_L_1_G_N_3_T_0"
-                        android:translateX="-9.583"
-                        android:translateY="-8.916" >
-                        <group
-                            android:name="_R_G_L_1_G"
-                            android:pivotX="2.25"
-                            android:pivotY="3.334"
-                            android:scaleX="1"
-                            android:scaleY="1"
-                            android:translateX="7.334"
-                            android:translateY="5.333" >
-                            <path
-                                android:name="_R_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#ffffff"
-                                android:fillType="nonZero"
-                                android:pathData=" M4.25 2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25 C3.35,0.25 4.25,1.15 4.25,2.25c " />
-                            <path
-                                android:name="_R_G_L_1_G_D_1_P_0"
-                                android:pathData=" M2.25 2.25 C2.25,2.25 2.25,5.92 2.25,5.92 "
-                                android:strokeAlpha="1"
-                                android:strokeColor="#ffffff"
-                                android:strokeLineCap="round"
-                                android:strokeLineJoin="round"
-                                android:strokeWidth="1.5" />
+                <group android:name="_R_G_L_1_G_N_3_T_1" android:translateX="15.999"
+                       android:translateY="24.333">
+                    <group android:name="_R_G_L_1_G_N_3_T_0" android:translateX="-9.583"
+                           android:translateY="-8.916">
+                        <group android:name="_R_G_L_1_G" android:translateX="7.334"
+                               android:translateY="5.333" android:pivotX="2.25"
+                               android:pivotY="3.334" android:scaleX="1" android:scaleY="1">
+                            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
+                                  android:fillAlpha="1" android:fillType="nonZero"
+                                  android:pathData=" M4.25 2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25 C3.35,0.25 4.25,1.15 4.25,2.25c "/>
+                            <path android:name="_R_G_L_1_G_D_1_P_0" android:strokeColor="#ffffff"
+                                  android:strokeLineCap="round" android:strokeLineJoin="round"
+                                  android:strokeWidth="1.5" android:strokeAlpha="1"
+                                  android:pathData=" M2.25 2.25 C2.25,2.25 2.25,5.92 2.25,5.92 "/>
                         </group>
                     </group>
                 </group>
-                <group
-                    android:name="_R_G_L_0_G_N_3_T_1"
-                    android:translateX="15.999"
-                    android:translateY="24.333" >
-                    <group
-                        android:name="_R_G_L_0_G_N_3_T_0"
-                        android:translateX="-9.583"
-                        android:translateY="-8.916" >
-                        <group
-                            android:name="_R_G_L_0_G"
-                            android:translateX="1.5"
-                            android:translateY="-11.835" >
-                            <path
-                                android:name="_R_G_L_0_G_D_0_P_0"
-                                android:pathData=" M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
-                                android:strokeAlpha="1"
-                                android:strokeColor="#ffffff"
-                                android:strokeLineCap="round"
-                                android:strokeLineJoin="round"
-                                android:strokeWidth="1.5" />
+                <group android:name="_R_G_L_0_G_N_3_T_1" android:translateX="15.999"
+                       android:translateY="24.333">
+                    <group android:name="_R_G_L_0_G_N_3_T_0" android:translateX="-9.583"
+                           android:translateY="-8.916">
+                        <group android:name="_R_G_L_0_G" android:translateX="1.5"
+                               android:translateY="-11.835">
+                            <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff"
+                                  android:strokeLineCap="round" android:strokeLineJoin="round"
+                                  android:strokeWidth="1.5" android:strokeAlpha="1"
+                                  android:pathData=" M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "/>
                         </group>
                     </group>
                 </group>
             </group>
-            <group android:name="time_group" />
+            <group android:name="time_group"/>
         </vector>
     </aapt:attr>
-
-    <target android:name="_R_G_L_2_G_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="0"
-                    android:valueFrom="24.333"
-                    android:valueTo="22.458"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0" />
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="0" android:valueFrom="24.333"
+                                android:valueTo="22.458" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="133"
-                    android:valueFrom="22.458"
-                    android:valueTo="25.333"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="133" android:valueFrom="22.458"
+                                android:valueTo="25.333" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="translateY"
-                    android:startOffset="267"
-                    android:valueFrom="25.333"
-                    android:valueTo="24.333"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="100"
+                                android:startOffset="267" android:valueFrom="25.333"
+                                android:valueTo="24.333" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_1_G" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.9"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+    <target android:name="_R_G_L_1_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="scaleX" android:duration="100"
+                                android:startOffset="0" android:valueFrom="1" android:valueTo="0.9"
+                                android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.9"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="scaleY" android:duration="100"
+                                android:startOffset="0" android:valueFrom="1" android:valueTo="0.9"
+                                android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="scaleX"
-                    android:startOffset="100"
-                    android:valueFrom="0.9"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="scaleX" android:duration="283"
+                                android:startOffset="100" android:valueFrom="0.9"
+                                android:valueTo="1" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="scaleY"
-                    android:startOffset="100"
-                    android:valueFrom="0.9"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="scaleY" android:duration="283"
+                                android:startOffset="100" android:valueFrom="0.9"
+                                android:valueTo="1" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_1_G_N_3_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="0"
-                    android:valueFrom="24.333"
-                    android:valueTo="22.458"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0" />
+    <target android:name="_R_G_L_1_G_N_3_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="0" android:valueFrom="24.333"
+                                android:valueTo="22.458" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="133"
-                    android:valueFrom="22.458"
-                    android:valueTo="25.333"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="133" android:valueFrom="22.458"
+                                android:valueTo="25.333" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="translateY"
-                    android:startOffset="267"
-                    android:valueFrom="25.333"
-                    android:valueTo="24.333"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="100"
+                                android:startOffset="267" android:valueFrom="25.333"
+                                android:valueTo="24.333" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
-                    android:valueTo="M12.42 12.6 C12.42,12.6 12.4,5.86 12.4,5.86 C12.4,3.52 10.46,1.44 8.06,1.44 C5.67,1.44 3.73,3.52 3.73,5.86 C3.73,5.86 3.75,7.41 3.75,7.41 "
-                    android:valueType="pathType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.59,0 0.488,1 1.0,1.0" />
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="pathData" android:duration="67"
+                                android:startOffset="0"
+                                android:valueFrom="M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+                                android:valueTo="M12.42 12.6 C12.42,12.6 12.4,5.86 12.4,5.86 C12.4,3.52 10.46,1.44 8.06,1.44 C5.67,1.44 3.73,3.52 3.73,5.86 C3.73,5.86 3.75,7.41 3.75,7.41 "
+                                android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.59,0 0.488,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="pathData"
-                    android:startOffset="67"
-                    android:valueFrom="M12.42 12.6 C12.42,12.6 12.4,5.86 12.4,5.86 C12.4,3.52 10.46,1.44 8.06,1.44 C5.67,1.44 3.73,3.52 3.73,5.86 C3.73,5.86 3.75,7.41 3.75,7.41 "
-                    android:valueTo="M12.42 12.6 C12.42,12.6 12.41,8.16 12.41,8.16 C12.41,5.81 14.36,3.75 16.75,3.77 C19.15,3.78 21.07,5.71 21.07,8.05 C21.07,8.05 21.08,8.22 21.08,8.22 "
-                    android:valueType="pathType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.57,0 0.365,1 1.0,1.0" />
+                <objectAnimator android:propertyName="pathData" android:duration="183"
+                                android:startOffset="67"
+                                android:valueFrom="M12.42 12.6 C12.42,12.6 12.4,5.86 12.4,5.86 C12.4,3.52 10.46,1.44 8.06,1.44 C5.67,1.44 3.73,3.52 3.73,5.86 C3.73,5.86 3.75,7.41 3.75,7.41 "
+                                android:valueTo="M12.42 12.6 C12.42,12.6 12.41,8.16 12.41,8.16 C12.41,5.81 14.36,3.75 16.75,3.77 C19.15,3.78 21.07,5.71 21.07,8.05 C21.07,8.05 21.08,8.22 21.08,8.22 "
+                                android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.57,0 0.365,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_0_G_N_3_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="0"
-                    android:valueFrom="24.333"
-                    android:valueTo="22.458"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0" />
+    <target android:name="_R_G_L_0_G_N_3_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="0" android:valueFrom="24.333"
+                                android:valueTo="22.458" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="133"
-                    android:valueFrom="22.458"
-                    android:valueTo="25.333"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="133" android:valueFrom="22.458"
+                                android:valueTo="25.333" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="translateY"
-                    android:startOffset="267"
-                    android:valueFrom="25.333"
-                    android:valueTo="24.333"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="100"
+                                android:startOffset="267" android:valueFrom="25.333"
+                                android:valueTo="24.333" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="time_group" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="717"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateX" android:duration="717"
+                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+                                android:valueType="floatType"/>
             </set>
         </aapt:attr>
     </target>
-
 </animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_unlock_filled.xml b/packages/SystemUI/res/anim/lock_unlock_filled.xml
index 2bf2d89..b2238ad 100644
--- a/packages/SystemUI/res/anim/lock_unlock_filled.xml
+++ b/packages/SystemUI/res/anim/lock_unlock_filled.xml
@@ -1,204 +1,158 @@
-<?xml version="1.0" encoding="utf-8"?>
-<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
-    xmlns:android="http://schemas.android.com/apk/res/android" >
+<!-- Copyright (C) 2019 The Android Open Source Project
 
-    <aapt:attr name="android:drawable" >
-        <vector
-            android:height="42dp"
-            android:viewportHeight="42"
-            android:viewportWidth="32"
-            android:width="32dp" >
-            <group android:name="_R_G" >
-                <group
-                    android:name="_R_G_L_1_G_T_1"
-                    android:translateX="16"
-                    android:translateY="25" >
-                    <group
-                        android:name="_R_G_L_1_G"
-                        android:translateX="-10.917"
-                        android:translateY="-9.583" >
-                        <path
-                            android:name="_R_G_L_1_G_D_0_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="#ffffff"
-                            android:fillType="nonZero"
-                            android:pathData=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c  M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c " />
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="42dp" android:width="32dp" android:viewportHeight="42"
+                android:viewportWidth="32">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_1_G_T_1" android:translateX="16"
+                       android:translateY="25">
+                    <group android:name="_R_G_L_1_G" android:translateX="-10.917"
+                           android:translateY="-9.583">
+                        <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
+                              android:fillAlpha="1" android:fillType="nonZero"
+                              android:pathData=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c  M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "/>
                     </group>
                 </group>
-                <group
-                    android:name="_R_G_L_0_G_N_3_T_1"
-                    android:translateX="16"
-                    android:translateY="25" >
-                    <group
-                        android:name="_R_G_L_0_G_N_3_T_0"
-                        android:translateX="-10.917"
-                        android:translateY="-9.583" >
-                        <group
-                            android:name="_R_G_L_0_G"
-                            android:translateX="9.917000000000002"
-                            android:translateY="-12.75" >
-                            <path
-                                android:name="_R_G_L_0_G_D_0_P_0"
-                                android:pathData=" M-3 13.04 C-3,13.04 -3,9.04 -3,9.04 C-3,6.83 -1.03,5.04 0.91,5 C3.12,4.96 5,6.79 5,9 C5,9 5,13 5,13 "
-                                android:strokeAlpha="1"
-                                android:strokeColor="#ffffff"
-                                android:strokeLineCap="round"
-                                android:strokeLineJoin="round"
-                                android:strokeWidth="2" />
+                <group android:name="_R_G_L_0_G_N_3_T_1" android:translateX="16"
+                       android:translateY="25">
+                    <group android:name="_R_G_L_0_G_N_3_T_0" android:translateX="-10.917"
+                           android:translateY="-9.583">
+                        <group android:name="_R_G_L_0_G" android:translateX="9.917000000000002"
+                               android:translateY="-12.75">
+                            <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff"
+                                  android:strokeLineCap="round" android:strokeLineJoin="round"
+                                  android:strokeWidth="2" android:strokeAlpha="1"
+                                  android:pathData=" M-3 13.04 C-3,13.04 -3,9.04 -3,9.04 C-3,6.83 -1.03,5.04 0.91,5 C3.12,4.96 5,6.79 5,9 C5,9 5,13 5,13 "/>
                         </group>
                     </group>
                 </group>
             </group>
-            <group android:name="time_group" />
+            <group android:name="time_group"/>
         </vector>
     </aapt:attr>
-
-    <target android:name="_R_G_L_1_G_D_0_P_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
-                    android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 11.78 C9.71,11.78 8.72,10.79 8.72,9.58 C8.72,8.37 9.71,7.38 10.92,7.38 C12.13,7.38 13.12,8.37 13.12,9.58 C13.12,10.79 12.13,11.78 10.92,11.78c "
-                    android:valueType="pathType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+    <target android:name="_R_G_L_1_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="pathData" android:duration="100"
+                                android:startOffset="0"
+                                android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+                                android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 11.78 C9.71,11.78 8.72,10.79 8.72,9.58 C8.72,8.37 9.71,7.38 10.92,7.38 C12.13,7.38 13.12,8.37 13.12,9.58 C13.12,10.79 12.13,11.78 10.92,11.78c "
+                                android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="pathData"
-                    android:startOffset="100"
-                    android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 11.78 C9.71,11.78 8.72,10.79 8.72,9.58 C8.72,8.37 9.71,7.38 10.92,7.38 C12.13,7.38 13.12,8.37 13.12,9.58 C13.12,10.79 12.13,11.78 10.92,11.78c "
-                    android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
-                    android:valueType="pathType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="pathData" android:duration="283"
+                                android:startOffset="100"
+                                android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 11.78 C9.71,11.78 8.72,10.79 8.72,9.58 C8.72,8.37 9.71,7.38 10.92,7.38 C12.13,7.38 13.12,8.37 13.12,9.58 C13.12,10.79 12.13,11.78 10.92,11.78c "
+                                android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+                                android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_1_G_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="0"
-                    android:valueFrom="25"
-                    android:valueTo="23"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.32,0 0.803,1 1.0,1.0" />
+    <target android:name="_R_G_L_1_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="0" android:valueFrom="25" android:valueTo="23"
+                                android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.32,0 0.803,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="133"
-                    android:valueFrom="23"
-                    android:valueTo="26.5"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.223,0 0.761,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="133" android:valueFrom="23"
+                                android:valueTo="26.5" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.223,0 0.761,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="translateY"
-                    android:startOffset="267"
-                    android:valueFrom="26.5"
-                    android:valueTo="25"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.311,0 0.633,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="100"
+                                android:startOffset="267" android:valueFrom="26.5"
+                                android:valueTo="25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.311,0 0.633,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M-3 13.04 C-3,13.04 -3,9.04 -3,9.04 C-3,6.83 -1.03,5.04 0.91,5 C3.12,4.96 5,6.79 5,9 C5,9 5,13 5,13 "
-                    android:valueTo="M-3 6.73 C-3,5.62 -2.56,4.67 -1.84,4 C-1.11,3.32 -0.09,2.93 1.06,2.94 C3.27,2.96 5,4.54 5,6.75 C5,6.75 5,13 5,13 "
-                    android:valueType="pathType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.592,0 0.503,1 1.0,1.0" />
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="pathData" android:duration="67"
+                                android:startOffset="0"
+                                android:valueFrom="M-3 13.04 C-3,13.04 -3,9.04 -3,9.04 C-3,6.83 -1.03,5.04 0.91,5 C3.12,4.96 5,6.79 5,9 C5,9 5,13 5,13 "
+                                android:valueTo="M-3 6.73 C-3,5.62 -2.56,4.67 -1.84,4 C-1.11,3.32 -0.09,2.93 1.06,2.94 C3.27,2.96 5,4.54 5,6.75 C5,6.75 5,13 5,13 "
+                                android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.592,0 0.503,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="pathData"
-                    android:startOffset="67"
-                    android:valueFrom="M-3 6.73 C-3,5.62 -2.56,4.67 -1.84,4 C-1.11,3.32 -0.09,2.93 1.06,2.94 C3.27,2.96 5,4.54 5,6.75 C5,6.75 5,13 5,13 "
-                    android:valueTo="M13 9 C13,7.9 12.55,6.9 11.83,6.17 C11.1,5.45 10.11,5 9,5 C6.79,5 5,6.79 5,9 C5,9 5,13 5,13 "
-                    android:valueType="pathType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.563,0 0.363,1 1.0,1.0" />
+                <objectAnimator android:propertyName="pathData" android:duration="183"
+                                android:startOffset="67"
+                                android:valueFrom="M-3 6.73 C-3,5.62 -2.56,4.67 -1.84,4 C-1.11,3.32 -0.09,2.93 1.06,2.94 C3.27,2.96 5,4.54 5,6.75 C5,6.75 5,13 5,13 "
+                                android:valueTo="M13 9 C13,7.9 12.55,6.9 11.83,6.17 C11.1,5.45 10.11,5 9,5 C6.79,5 5,6.79 5,9 C5,9 5,13 5,13 "
+                                android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.563,0 0.363,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_0_G_N_3_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="0"
-                    android:valueFrom="25"
-                    android:valueTo="23"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.32,0 0.803,1 1.0,1.0" />
+    <target android:name="_R_G_L_0_G_N_3_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="0" android:valueFrom="25" android:valueTo="23"
+                                android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.32,0 0.803,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="133"
-                    android:valueFrom="23"
-                    android:valueTo="26.5"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.223,0 0.761,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="133" android:valueFrom="23"
+                                android:valueTo="26.5" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.223,0 0.761,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="translateY"
-                    android:startOffset="267"
-                    android:valueFrom="26.5"
-                    android:valueTo="25"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.311,0 0.633,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="100"
+                                android:startOffset="267" android:valueFrom="26.5"
+                                android:valueTo="25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.311,0 0.633,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="time_group" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="717"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateX" android:duration="717"
+                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+                                android:valueType="floatType"/>
             </set>
         </aapt:attr>
     </target>
-
 </animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_unlock_rounded.xml b/packages/SystemUI/res/anim/lock_unlock_rounded.xml
index 7c55851..14a88a4 100644
--- a/packages/SystemUI/res/anim/lock_unlock_rounded.xml
+++ b/packages/SystemUI/res/anim/lock_unlock_rounded.xml
@@ -1,292 +1,209 @@
-<?xml version="1.0" encoding="utf-8"?>
-<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
-    xmlns:android="http://schemas.android.com/apk/res/android" >
+<!-- Copyright (C) 2019 The Android Open Source Project
 
-    <aapt:attr name="android:drawable" >
-        <vector
-            android:height="42dp"
-            android:viewportHeight="42"
-            android:viewportWidth="32"
-            android:width="32dp" >
-            <group android:name="_R_G" >
-                <group
-                    android:name="_R_G_L_2_G_T_1"
-                    android:translateX="16"
-                    android:translateY="25" >
-                    <group
-                        android:name="_R_G_L_2_G"
-                        android:translateX="-14.667"
-                        android:translateY="-12.667" >
-                        <path
-                            android:name="_R_G_L_2_G_D_0_P_0"
-                            android:pathData=" M22.09 5 C22.09,5 6,5 6,5 C5.45,5 5,5.45 5,6 C5,6 5,19.33 5,19.33 C5,19.89 5.45,20.33 6,20.33 C6,20.33 23.33,20.33 23.33,20.33 C23.89,20.33 24.33,19.89 24.33,19.33 C24.33,19.33 24.33,6 24.33,6 C24.33,5.45 23.89,5 23.33,5 C23.33,5 22.09,5 22.09,5c "
-                            android:strokeAlpha="1"
-                            android:strokeColor="#ffffff"
-                            android:strokeLineCap="round"
-                            android:strokeLineJoin="round"
-                            android:strokeWidth="1.5" />
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="42dp" android:width="32dp" android:viewportHeight="42"
+                android:viewportWidth="32">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_2_G_T_1" android:translateX="16"
+                       android:translateY="25">
+                    <group android:name="_R_G_L_2_G" android:translateX="-14.667"
+                           android:translateY="-12.667">
+                        <path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#ffffff"
+                              android:strokeLineCap="round" android:strokeLineJoin="round"
+                              android:strokeWidth="1.5" android:strokeAlpha="1"
+                              android:pathData=" M22.09 5 C22.09,5 6,5 6,5 C5.45,5 5,5.45 5,6 C5,6 5,19.33 5,19.33 C5,19.89 5.45,20.33 6,20.33 C6,20.33 23.33,20.33 23.33,20.33 C23.89,20.33 24.33,19.89 24.33,19.33 C24.33,19.33 24.33,6 24.33,6 C24.33,5.45 23.89,5 23.33,5 C23.33,5 22.09,5 22.09,5c "/>
                     </group>
                 </group>
-                <group
-                    android:name="_R_G_L_1_G_N_4_T_1"
-                    android:translateX="16"
-                    android:translateY="25" >
-                    <group
-                        android:name="_R_G_L_1_G_N_4_T_0"
-                        android:translateX="-14.667"
-                        android:translateY="-12.667" >
-                        <group
-                            android:name="_R_G_L_1_G"
-                            android:pivotX="2.25"
-                            android:pivotY="2.25"
-                            android:scaleX="1"
-                            android:scaleY="1"
-                            android:translateX="12.416"
-                            android:translateY="10.417" >
-                            <path
-                                android:name="_R_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#ffffff"
-                                android:fillType="nonZero"
-                                android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c " />
+                <group android:name="_R_G_L_1_G_N_4_T_1" android:translateX="16"
+                       android:translateY="25">
+                    <group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="-14.667"
+                           android:translateY="-12.667">
+                        <group android:name="_R_G_L_1_G" android:translateX="12.416"
+                               android:translateY="10.417" android:pivotX="2.25"
+                               android:pivotY="2.25" android:scaleX="1" android:scaleY="1">
+                            <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
+                                  android:fillAlpha="1" android:fillType="nonZero"
+                                  android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c "/>
                         </group>
                     </group>
                 </group>
-                <group
-                    android:name="_R_G_L_0_G_N_4_T_1"
-                    android:translateX="16"
-                    android:translateY="25" >
-                    <group
-                        android:name="_R_G_L_0_G_N_4_T_0"
-                        android:translateX="-14.667"
-                        android:translateY="-12.667" >
-                        <group
-                            android:name="_R_G_L_0_G"
-                            android:translateX="5.333"
-                            android:translateY="-9.425999999999998" >
-                            <path
-                                android:name="_R_G_L_0_G_D_0_P_0"
-                                android:pathData=" M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
-                                android:strokeAlpha="1"
-                                android:strokeColor="#ffffff"
-                                android:strokeLineCap="round"
-                                android:strokeLineJoin="round"
-                                android:strokeWidth="1.5" />
+                <group android:name="_R_G_L_0_G_N_4_T_1" android:translateX="16"
+                       android:translateY="25">
+                    <group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="-14.667"
+                           android:translateY="-12.667">
+                        <group android:name="_R_G_L_0_G" android:translateX="5.333"
+                               android:translateY="-9.425999999999998">
+                            <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff"
+                                  android:strokeLineCap="round" android:strokeLineJoin="round"
+                                  android:strokeWidth="1.5" android:strokeAlpha="1"
+                                  android:pathData=" M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "/>
                         </group>
                     </group>
                 </group>
             </group>
-            <group android:name="time_group" />
+            <group android:name="time_group"/>
         </vector>
     </aapt:attr>
-
-    <target android:name="_R_G_L_2_G_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="0"
-                    android:valueFrom="25"
-                    android:valueTo="23.5"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+    <target android:name="_R_G_L_2_G_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="0" android:valueFrom="25"
+                                android:valueTo="23.5" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="133"
-                    android:valueFrom="23.5"
-                    android:valueTo="26"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="133" android:valueFrom="23.5"
+                                android:valueTo="26" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="translateY"
-                    android:startOffset="267"
-                    android:valueFrom="26"
-                    android:valueTo="25"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="100"
+                                android:startOffset="267" android:valueFrom="26"
+                                android:valueTo="25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_1_G" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.85"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.346,1 1.0,1.0" />
+    <target android:name="_R_G_L_1_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="scaleX" android:duration="100"
+                                android:startOffset="0" android:valueFrom="1" android:valueTo="0.85"
+                                android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.346,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.85"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.346,1 1.0,1.0" />
+                <objectAnimator android:propertyName="scaleY" android:duration="100"
+                                android:startOffset="0" android:valueFrom="1" android:valueTo="0.85"
+                                android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.346,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="scaleX"
-                    android:startOffset="100"
-                    android:valueFrom="0.85"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.423,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="scaleX" android:duration="283"
+                                android:startOffset="100" android:valueFrom="0.85"
+                                android:valueTo="1" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.423,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="scaleY"
-                    android:startOffset="100"
-                    android:valueFrom="0.85"
-                    android:valueTo="1"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.423,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="scaleY" android:duration="283"
+                                android:startOffset="100" android:valueFrom="0.85"
+                                android:valueTo="1" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.423,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_1_G_N_4_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="0"
-                    android:valueFrom="25"
-                    android:valueTo="23.5"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+    <target android:name="_R_G_L_1_G_N_4_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="0" android:valueFrom="25"
+                                android:valueTo="23.5" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="133"
-                    android:valueFrom="23.5"
-                    android:valueTo="26"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="133" android:valueFrom="23.5"
+                                android:valueTo="26" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="translateY"
-                    android:startOffset="267"
-                    android:valueFrom="26"
-                    android:valueTo="25"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="100"
+                                android:startOffset="267" android:valueFrom="26"
+                                android:valueTo="25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
-                    android:valueTo="M13.67 13.8 C13.67,13.8 13.69,5.06 13.69,5.06 C13.65,2.87 11.71,1.13 9.35,1.16 C7,1.13 5.06,2.87 5.02,5.06 C5.02,5.06 5,7.93 5,7.93 "
-                    android:valueType="pathType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.658,0 0.317,1 1.0,1.0" />
+    <target android:name="_R_G_L_0_G_D_0_P_0">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="pathData" android:duration="67"
+                                android:startOffset="0"
+                                android:valueFrom="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+                                android:valueTo="M13.67 13.8 C13.67,13.8 13.69,5.06 13.69,5.06 C13.65,2.87 11.71,1.13 9.35,1.16 C7,1.13 5.06,2.87 5.02,5.06 C5.02,5.06 5,7.93 5,7.93 "
+                                android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.658,0 0.317,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="pathData"
-                    android:startOffset="67"
-                    android:valueFrom="M13.67 13.8 C13.67,13.8 13.69,5.06 13.69,5.06 C13.65,2.87 11.71,1.13 9.35,1.16 C7,1.13 5.06,2.87 5.02,5.06 C5.02,5.06 5,7.93 5,7.93 "
-                    android:valueTo="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.68,6.62 15.69,5.03 18.01,5.04 C20.46,5.04 22.32,6.89 22.34,8.85 C22.34,8.85 22.33,8.89 22.33,8.89 "
-                    android:valueType="pathType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.679,0 0.175,1 1.0,1.0" />
+                <objectAnimator android:propertyName="pathData" android:duration="183"
+                                android:startOffset="67"
+                                android:valueFrom="M13.67 13.8 C13.67,13.8 13.69,5.06 13.69,5.06 C13.65,2.87 11.71,1.13 9.35,1.16 C7,1.13 5.06,2.87 5.02,5.06 C5.02,5.06 5,7.93 5,7.93 "
+                                android:valueTo="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.68,6.62 15.69,5.03 18.01,5.04 C20.46,5.04 22.32,6.89 22.34,8.85 C22.34,8.85 22.33,8.89 22.33,8.89 "
+                                android:valueType="pathType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.679,0 0.175,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="_R_G_L_0_G_N_4_T_1" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="0"
-                    android:valueFrom="25"
-                    android:valueTo="23.5"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+    <target android:name="_R_G_L_0_G_N_4_T_1">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="0" android:valueFrom="25"
+                                android:valueTo="23.5" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="translateY"
-                    android:startOffset="133"
-                    android:valueFrom="23.5"
-                    android:valueTo="26"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="133"
+                                android:startOffset="133" android:valueFrom="23.5"
+                                android:valueTo="26" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="translateY"
-                    android:startOffset="267"
-                    android:valueFrom="26"
-                    android:valueTo="25"
-                    android:valueType="floatType" >
-                    <aapt:attr name="android:interpolator" >
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+                <objectAnimator android:propertyName="translateY" android:duration="100"
+                                android:startOffset="267" android:valueFrom="26"
+                                android:valueTo="25" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
                     </aapt:attr>
                 </objectAnimator>
             </set>
         </aapt:attr>
     </target>
-    <target android:name="time_group" >
-        <aapt:attr name="android:animation" >
-            <set android:ordering="together" >
-                <objectAnimator
-                    android:duration="717"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:propertyName="translateX" android:duration="717"
+                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+                                android:valueType="floatType"/>
             </set>
         </aapt:attr>
     </target>
-
 </animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_emergency_star.xml b/packages/SystemUI/res/drawable/ic_emergency_star.xml
new file mode 100644
index 0000000..148f250
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_emergency_star.xml
@@ -0,0 +1,28 @@
+<?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.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M9.321,2l0,5.359l-4.641,-2.68l-2.68,4.641l4.641,2.679l-4.641,2.68l2.68,4.641l4.641,-2.68l0,5.359l5.359,0l0,-5.359l4.641,2.68l2.68,-4.641l-4.641,-2.68l4.641,-2.679l-2.68,-4.641l-4.641,2.679l0,-5.359z"
+        android:strokeColor="#00000000"
+        android:fillColor="#EA4335"
+        android:strokeWidth="1"/>
+</vector>
diff --git a/packages/SystemUI/res/layout-land/global_actions_column.xml b/packages/SystemUI/res/layout-land/global_actions_column.xml
index 99a4e13..98cb0d0 100644
--- a/packages/SystemUI/res/layout-land/global_actions_column.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_column.xml
@@ -42,10 +42,10 @@
             android:orientation="horizontal"
             android:layout_marginTop="@dimen/global_actions_grid_side_margin"
             android:translationZ="@dimen/global_actions_translate"
-            android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingTop="@dimen/global_actions_grid_vertical_padding"
-            android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
+            android:paddingLeft="@dimen/global_actions_grid_vertical_padding"
+            android:paddingRight="@dimen/global_actions_grid_vertical_padding"
+            android:paddingTop="@dimen/global_actions_grid_horizontal_padding"
+            android:paddingBottom="@dimen/global_actions_grid_horizontal_padding"
             android:background="?android:attr/colorBackgroundFloating"
         />
         <!-- For separated items-->
@@ -55,10 +55,10 @@
             android:layout_height="wrap_content"
             android:layout_marginLeft="@dimen/global_actions_grid_side_margin"
             android:layout_marginTop="@dimen/global_actions_grid_side_margin"
-            android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingTop="@dimen/global_actions_grid_vertical_padding"
-            android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
+            android:paddingLeft="@dimen/global_actions_grid_vertical_padding"
+            android:paddingRight="@dimen/global_actions_grid_vertical_padding"
+            android:paddingTop="@dimen/global_actions_grid_horizontal_padding"
+            android:paddingBottom="@dimen/global_actions_grid_horizontal_padding"
             android:orientation="horizontal"
             android:background="?android:attr/colorBackgroundFloating"
             android:translationZ="@dimen/global_actions_translate"
diff --git a/packages/SystemUI/res/layout-land/global_actions_column_seascape.xml b/packages/SystemUI/res/layout-land/global_actions_column_seascape.xml
index 0f86131..5e7604c 100644
--- a/packages/SystemUI/res/layout-land/global_actions_column_seascape.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_column_seascape.xml
@@ -41,10 +41,10 @@
             android:orientation="horizontal"
             android:layout_marginBottom="@dimen/global_actions_grid_side_margin"
             android:translationZ="@dimen/global_actions_translate"
-            android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingTop="@dimen/global_actions_grid_vertical_padding"
-            android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
+            android:paddingLeft="@dimen/global_actions_grid_vertical_padding"
+            android:paddingRight="@dimen/global_actions_grid_vertical_padding"
+            android:paddingTop="@dimen/global_actions_grid_horizontal_padding"
+            android:paddingBottom="@dimen/global_actions_grid_horizontal_padding"
             android:background="?android:attr/colorBackgroundFloating"
         />
         <!-- For separated items-->
@@ -55,10 +55,10 @@
             android:layout_height="wrap_content"
             android:layout_marginRight="@dimen/global_actions_grid_side_margin"
             android:layout_marginBottom="@dimen/global_actions_grid_side_margin"
-            android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
-            android:paddingTop="@dimen/global_actions_grid_vertical_padding"
-            android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
+            android:paddingLeft="@dimen/global_actions_grid_vertical_padding"
+            android:paddingRight="@dimen/global_actions_grid_vertical_padding"
+            android:paddingTop="@dimen/global_actions_grid_horizontal_padding"
+            android:paddingBottom="@dimen/global_actions_grid_horizontal_padding"
             android:orientation="horizontal"
             android:background="?android:attr/colorBackgroundFloating"
             android:translationZ="@dimen/global_actions_translate"
diff --git a/packages/SystemUI/res/layout/biometric_dialog.xml b/packages/SystemUI/res/layout/biometric_dialog.xml
index c560d7e..e687cdf 100644
--- a/packages/SystemUI/res/layout/biometric_dialog.xml
+++ b/packages/SystemUI/res/layout/biometric_dialog.xml
@@ -55,7 +55,8 @@
                     android:id="@+id/left_space"
                     android:layout_weight="1"
                     android:layout_width="0dp"
-                    android:layout_height="match_parent"/>
+                    android:layout_height="match_parent"
+                    android:contentDescription="@string/biometric_dialog_empty_space_description"/>
 
                     <LinearLayout
                         android:id="@+id/dialog"
@@ -177,7 +178,8 @@
                     android:id="@+id/right_space"
                     android:layout_weight="1"
                     android:layout_width="0dp"
-                    android:layout_height="match_parent" />
+                    android:layout_height="match_parent"
+                    android:contentDescription="@string/biometric_dialog_empty_space_description"/>
 
             </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 7fc2066..21c2c6b 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -46,6 +46,8 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:gravity="center"
+                android:paddingStart="@dimen/keyguard_indication_text_padding"
+                android:paddingEnd="@dimen/keyguard_indication_text_padding"
                 android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
                 android:visibility="gone" />
 
@@ -54,6 +56,8 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:gravity="center"
+                android:paddingStart="@dimen/keyguard_indication_text_padding"
+                android:paddingEnd="@dimen/keyguard_indication_text_padding"
                 android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"
                 android:accessibilityLiveRegion="polite" />
 
diff --git a/packages/SystemUI/res/layout/notif_half_shelf.xml b/packages/SystemUI/res/layout/notif_half_shelf.xml
index a563bb5..26c8872 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf.xml
@@ -69,7 +69,7 @@
 
                 <Switch
                     android:id="@+id/toggle"
-                    android:layout_height="wrap_content"
+                    android:layout_height="48dp"
                     android:layout_width="wrap_content"
                     android:layout_gravity="center_vertical"
                     android:padding="8dp" />
diff --git a/packages/SystemUI/res/layout/notif_half_shelf_row.xml b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
index 1b80455..b95d5e9 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf_row.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf_row.xml
@@ -71,7 +71,7 @@
 
     <Switch
         android:id="@+id/toggle"
-        android:layout_height="wrap_content"
+        android:layout_height="48dp"
         android:layout_width="wrap_content"
         android:layout_gravity="center_vertical"
         android:padding="8dp"
diff --git a/packages/SystemUI/res/layout/pip_menu_action.xml b/packages/SystemUI/res/layout/pip_menu_action.xml
index 9150a00..3ad3546 100644
--- a/packages/SystemUI/res/layout/pip_menu_action.xml
+++ b/packages/SystemUI/res/layout/pip_menu_action.xml
@@ -13,10 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<ImageView
+<ImageButton
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/pip_action_size"
     android:layout_height="@dimen/pip_action_size"
     android:padding="@dimen/pip_action_padding"
     android:background="?android:selectableItemBackgroundBorderless"
-    android:forceHasOverlappingRendering="false" />
\ No newline at end of file
+    android:forceHasOverlappingRendering="false" />
diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml
index 03d587b..ee0bd14 100644
--- a/packages/SystemUI/res/layout/pip_menu_activity.xml
+++ b/packages/SystemUI/res/layout/pip_menu_activity.xml
@@ -19,48 +19,49 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-  <!-- Menu layout -->
-  <FrameLayout
-      android:id="@+id/menu_container"
-      android:layout_width="match_parent"
-      android:layout_height="match_parent"
-      android:forceHasOverlappingRendering="false">
+    <!-- Menu layout -->
+    <FrameLayout
+        android:id="@+id/menu_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:forceHasOverlappingRendering="false"
+        android:accessibilityTraversalAfter="@id/dismiss">
 
-      <!-- The margins for this container is calculated in the code depending on whether the
-           actions_container is visible. -->
-      <FrameLayout
-          android:id="@+id/expand_container"
-          android:layout_width="match_parent"
-          android:layout_height="match_parent">
-          <ImageView
-              android:id="@+id/expand_button"
-              android:layout_width="60dp"
-              android:layout_height="60dp"
-              android:layout_gravity="center"
-              android:contentDescription="@string/pip_phone_expand"
-              android:padding="10dp"
-              android:src="@drawable/pip_expand"
-              android:background="?android:selectableItemBackgroundBorderless" />
-      </FrameLayout>
+        <!-- The margins for this container is calculated in the code depending on whether the
+             actions_container is visible. -->
+        <FrameLayout
+            android:id="@+id/expand_container"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+            <ImageButton
+                android:id="@+id/expand_button"
+                android:layout_width="60dp"
+                android:layout_height="60dp"
+                android:layout_gravity="center"
+                android:contentDescription="@string/pip_phone_expand"
+                android:padding="10dp"
+                android:src="@drawable/pip_expand"
+                android:background="?android:selectableItemBackgroundBorderless" />
+        </FrameLayout>
 
-      <FrameLayout
-          android:id="@+id/actions_container"
-          android:layout_width="match_parent"
-          android:layout_height="@dimen/pip_action_size"
-          android:layout_gravity="bottom"
-          android:visibility="invisible">
-          <LinearLayout
-              android:id="@+id/actions_group"
-              android:layout_width="wrap_content"
-              android:layout_height="match_parent"
-              android:layout_gravity="center_horizontal"
-              android:orientation="horizontal"
-              android:divider="@android:color/transparent"
-              android:showDividers="middle" />
-      </FrameLayout>
-  </FrameLayout>
+        <FrameLayout
+            android:id="@+id/actions_container"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/pip_action_size"
+            android:layout_gravity="bottom"
+            android:visibility="invisible">
+            <LinearLayout
+                android:id="@+id/actions_group"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_gravity="center_horizontal"
+                android:orientation="horizontal"
+                android:divider="@android:color/transparent"
+                android:showDividers="middle" />
+        </FrameLayout>
+    </FrameLayout>
 
-    <ImageView
+    <ImageButton
         android:id="@+id/settings"
         android:layout_width="@dimen/pip_action_size"
         android:layout_height="@dimen/pip_action_size"
@@ -70,7 +71,7 @@
         android:src="@drawable/ic_settings"
         android:background="?android:selectableItemBackgroundBorderless" />
 
-    <ImageView
+    <ImageButton
         android:id="@+id/dismiss"
         android:layout_width="@dimen/pip_action_size"
         android:layout_height="@dimen/pip_action_size"
diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml
index c812489..683e867 100644
--- a/packages/SystemUI/res/layout/quick_settings_header_info.xml
+++ b/packages/SystemUI/res/layout/quick_settings_header_info.xml
@@ -21,6 +21,7 @@
     android:layout_below="@id/quick_status_bar_system_icons"
     android:paddingStart="@dimen/status_bar_padding_start"
     android:paddingEnd="@dimen/status_bar_padding_end"
+    android:visibility="invisible"
     android:theme="@style/QSHeaderTheme">
 
         <com.android.systemui.qs.QSHeaderInfoLayout
diff --git a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
index d3eb9ae..508619a 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
@@ -22,6 +22,7 @@
     android:focusable="true"
     android:clickable="true"
     >
+
     <com.android.systemui.statusbar.notification.row.NotificationBackgroundView
         android:id="@+id/backgroundNormal"
         android:layout_width="match_parent"
@@ -38,27 +39,7 @@
         android:gravity="center_vertical"
         android:orientation="horizontal"
         >
-        <TextView
-            android:id="@+id/header_label"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:layout_marginStart="@dimen/notification_section_header_padding_left"
-            android:gravity="start"
-            android:textAlignment="gravity"
-            android:text="@string/notification_section_header_gentle"
-            android:textSize="12sp"
-            android:textColor="@color/notification_section_header_label_color"
-            />
-        <ImageView
-            android:id="@+id/btn_clear_all"
-            android:layout_width="@dimen/notification_section_header_height"
-            android:layout_height="@dimen/notification_section_header_height"
-            android:layout_marginEnd="4dp"
-            android:src="@drawable/status_bar_notification_section_header_clear_btn"
-            android:contentDescription="@string/accessibility_notification_section_header_gentle_clear_all"
-            android:scaleType="center"
-            />
+        <include layout="@layout/status_bar_notification_section_header_contents"/>
     </LinearLayout>
 
     <com.android.systemui.statusbar.notification.FakeShadowView
diff --git a/packages/SystemUI/res/layout/status_bar_notification_section_header_contents.xml b/packages/SystemUI/res/layout/status_bar_notification_section_header_contents.xml
new file mode 100644
index 0000000..feabd1c
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_notification_section_header_contents.xml
@@ -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
+  -->
+
+<!-- Used by both status_bar_notification_header and SectionHeaderView -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android" >
+    <TextView
+        android:id="@+id/header_label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:layout_marginStart="@dimen/notification_section_header_padding_left"
+        android:gravity="start"
+        android:textAlignment="gravity"
+        android:text="@string/notification_section_header_gentle"
+        android:textSize="12sp"
+        android:textColor="@color/notification_section_header_label_color"
+        android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+    />
+    <ImageView
+        android:id="@+id/btn_clear_all"
+        android:layout_width="@dimen/notification_section_header_height"
+        android:layout_height="@dimen/notification_section_header_height"
+        android:layout_marginEnd="4dp"
+        android:src="@drawable/status_bar_notification_section_header_clear_btn"
+        android:contentDescription="@string/accessibility_notification_section_header_gentle_clear_all"
+        android:scaleType="center"
+    />
+</merge>
diff --git a/packages/SystemUI/res/values-af/config.xml b/packages/SystemUI/res/values-af/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-af/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 36a2a86..e0907ae 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Soek tans jou gesig"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Gesig is gestaaf"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bevestig"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tik op Bevestig om te voltooi"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Raak die vingerafdruksensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Vingerafdrukikoon"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Soek tans vir jou …"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Diensverskaffernetwerk verander tans"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Maak batterybesonderhede oop"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> persent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> persent, ongeveer <xliff:g id="TIME">%2$s</xliff:g> oor gegrond op jou gebruik"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery laai tans, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Stelselinstellings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Kennisgewings"</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Tot sonsopkoms"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Aan om <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Tot <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Donker-tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Donker-tema\nBatterybespaarder"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Donker-tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Donker-tema\nBatterybespaarder"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC is gedeaktiveer"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC is geaktiveer"</string>
@@ -398,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Minder dringende kennisgewings hieronder"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tik weer om oop te maak"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Swiep op om te ontsluit"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Swiep op om oop te maak"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Jou organisasie bestuur hierdie toestel"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Hierdie toestel word deur <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> bestuur"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swiep vanaf ikoon vir foon"</string>
@@ -452,7 +454,7 @@
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Skakel Batterybespaarder af"</string>
     <string name="media_projection_dialog_text" msgid="8585357687598538511">"Terwyl dit opneem of uitsaai, kan <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> enige sensitiewe inligting vasvang wat op jou skerm gewys word of op jou toestel gespeel word, insluitend sensitiewe inligting soos oudio, wagwoorde, betaalinligting, foto\'s en boodskappe."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Terwyl dit opneem of uitsaai, kan die diens wat hierdie taak uitvoer enige sensitiewe inligting vasvang wat op jou skerm gewys word of op jou toestel gespeel word, insluitend sensitiewe inligting soos oudio, wagwoorde, betaalinligting, foto\'s en boodskappe."</string>
-    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Maak sensitiewe inligting tydens uitsending/opname openbaar"</string>
+    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Bekendmaking van sensitiewe inligting tydens uitsending/opname"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Moenie weer wys nie"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Vee alles uit"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Bestuur"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Hou aan waarsku"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Skakel kennisgewings af"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Hou aan om kennisgewings van hierdie program af te wys?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Lig"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Geprioritiseerd"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Help jou om te fokus met kennisgewings wat net op die aftrekskerm is. Altyd stil."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Wys prioriteitkennisgewings hieronder. Altyd stil."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Wys prioriteitkennisgewings hieronder. Altyd stil."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Wys prioriteitkennisgewings hieronder. Altyd stil."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Trek jou aandag met klank en \'n statusbalk-ikoon. Wys op sluitskerm."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Stil"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Waarskuwings"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Help jou om te fokus sonder klank of vibrasie."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kry jou aandag met klank of vibrasie."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Hierdie kennisgewings kan nie gewysig word nie."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Hierdie groep kennisgewings kan nie hier opgestel word nie"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Instaanbediener-kennisgewing"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Beweeg na links onder"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Beweeg na regs onder"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Maak toe"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Stelselnavigasie is opgedateer. Gaan na Instellings toe om veranderinge te maak."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gaan na Instellings toe om stelselnavigasie op te dateer"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/config.xml b/packages/SystemUI/res/values-am/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-am/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index bd0f960..f16193a 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"የዩኤስቢ እርማት አይፈቀድም"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"አሁን ወደዚህ መሣሪያ የገባው ተጠቃሚ የዩኤስቢ እርማትን ማብራት አይችልም። ይህን ባህሪ ለመጠቀም ወደ ዋና ተጠቃሚ ይቀይሩ።"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"የዩኤስቢ ወደብ ተሰናክሏል"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"መሣሪያዎን ከፈሳሽ ወይም ፍርስራሽ ለመጠበቅ ሲባል የዩኤስቢ ወደቡ ተሰናክሏል፣ እና ማናቸውም ተቀጥላዎችን አያገኝም።\n\nየዩኤስቢ ወደቡን እንደገና መጠቀም ችግር በማይኖረው ጊዜ ማሳወቂያ ይደርሰዎታል።"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ኃይል መሙያዎችን እና ተጨማሪ መሣሪያዎችን ፈልጎ ለማግኘት የነቃ የዩኤስቢ ወደብ"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"ዩኤስቢ አንቃ"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"የበለጠ መረዳት"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ማያ እንዲሞላ አጉላ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ማያ ለመሙለት ሳብ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ቅጽበታዊ ገጽ እይታ"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"መልክዎን በመፈለግ ላይ"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"መልክ ተረጋግጧል"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ተረጋግጧል"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ለማጠናቀቅ አረጋግጥን መታ ያድርጉ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"የጣት አሻራ ዳሳሹን ይንኩ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"የጣት አሻራ አዶ"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"እርስዎን በመፈለግ ላይ…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"የአገልግሎት አቅራቢ አውታረ መረብን በመቀየር ላይ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"የባትሪ ዝርዝሮችን ክፈት"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"የባትሪ <xliff:g id="NUMBER">%d</xliff:g> መቶኛ።"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ባትሪ <xliff:g id="PERCENTAGE">%1$s</xliff:g> በመቶ፣ በአጠቃቀምዎ ላይ በመመስረት <xliff:g id="TIME">%2$s</xliff:g> ገደማ ይቀራል"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ባትሪ ኃይል በመሙላት ላይ፣ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"የስርዓት ቅንብሮች"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ማሳወቂያዎች"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"ጸሐይ እስክትወጣ ድረስ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> ላይ ይበራል"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"እስከ <xliff:g id="TIME">%s</xliff:g> ድረስ"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ጨለማ ገጽታ"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ጨለም ያለ ገጽታ\nየባትሪ ቆጣቢ"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ጨለማ ገጽታ"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ጨለም ያለ ገጽታ\nየባትሪ ቆጣቢ"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"ኤንኤፍሲ"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"ኤንኤፍሲ ተሰናክሏል"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"ኤንኤፍሲ ነቅቷል"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"በጣም አስቸካይ ያልሆኑ ማሳወቂያዎች ከታች"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ለመክፈት ዳግም መታ ያድርጉ"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"ለማስከፈት ወደ ላይ ያንሸራትቱ"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ይህ መሣሪያ በእርስዎ ድርጅት የሚተዳደር ነው"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> የሚተዳደር ነው"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ለስልክ ከአዶ ላይ ጠረግ ያድርጉ"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ዳግመኛ አታሳይ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ሁሉንም አጽዳ"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ያቀናብሩ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ጸጥ ያሉ ማሳወቂያዎች"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ሁሉንም ጸጥ ያሉ ማሳወቂያዎችን ያጽዱ"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"ማሳወቂያዎች በአትረብሽ ባሉበት ቆመዋል"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"አሁን ጀምር"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ምንም ማሳወቂያ የለም"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"አግድ"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ማሳየትን ቀጥል"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"አሳንስ"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ፀጥ ያለ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ጸጥ እንዳለ ቆይ"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ማንቃት"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ማንቃቱን ቀጥል"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ማሳወቂያዎችን አጥፋ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ከዚህ መተግበሪያ ማሳወቂያዎችን ማሳየት ይቀጥል?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ረጋ ያለ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ቅድሚያ የተሰጠው"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"በወደታች ተጎችታች ጥላ ውስጥ ብቻ በማሳወቂያዎች ላይ እንዲያተኩሩ ያግዝዎታል። ሁልጊዜ ጸጥታ።"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ከዚህ በታች ቅድሚያ ተሰጪ ማሳወቂያዎችን ያሳያል። ሁልጊዜ ጸጥታ።"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ከዚህ በታች ቅድሚያ ተሰጪ ማሳወቂያዎችን ያሳያል። ሁልጊዜ ጸጥታ።"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ከዚህ በታች ቅድሚያ ተሰጪ ማሳወቂያዎችን ያሳያል። ሁልጊዜ ጸጥታ።"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ከድምፅ እና የሁኔታ አሞሌ አዶ ጋር የእርስዎን ትኩረት ይስባል። በማያ ገጽ ቁልፍ ላይ ያሳያል።"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ፀጥ ያለ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ማንቃት"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ያለ ድምፅ ወይም ንዝረት እርስዎ ትኩረት እንዲያደርጉ ያግዛል።"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ከድምፅ ወይም ንዝረት ጋር የእርስዎን ትኩረት ይስባል።"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"እነዚህ ማሳወቂያዎች ሊሻሻሉ አይችሉም።"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"የማሳወቂያዎች ይህ ቡድን እዚህ ላይ ሊዋቀር አይችልም"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ተኪ ማሳወቂያ"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ፋይሎችን ለማከል ይዘት ይጎትቱ"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ሰድሮችን ዳግም ለማስተካከል ይያዙ እና ይጎትቱ።"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"ለማስወገድ ወደዚህ ይጎትቱ"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"ቢያንስ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ሰቆች ያስፈልገዎታል"</string>
     <string name="qs_edit" msgid="2232596095725105230">"አርትዕ"</string>
     <string name="tuner_time" msgid="6572217313285536011">"ሰዓት"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"ፍቀድ"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ከልክል"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ለባትሪ ቆጣቢ መርሐግብርን ለማስያዝ መታ ያድርጉ"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ባትሪው የማለቅ ዕድሉ ከፍ ያለ ከሆነ ያብሩት"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"አይ፣ አመሰግናለሁ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"የባትሪ ቆጣቢ መርሐግብር በርቷል"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ባትሪ ልክ ከ<xliff:g id="PERCENTAGE">%d</xliff:g>%% በታች ሲሆን ባትሪ ቆጣቢ በራስ-ሰር ይበራል።"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"የግርጌውን ግራ አንቀሳቅስ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ታችኛውን ቀኝ ያንቀሳቅሱ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"አሰናብት"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"የስርዓት ዳሰሳ ተዘምኗል። ለውጦችን ለማድረግ ወደ ቅንብሮች ይሂዱ።"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"የስርዓት ዳሰሳን ለማዘመን ወደ ቅንብሮች ይሂዱ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/config.xml b/packages/SystemUI/res/values-ar/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ar/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 13df178..3d297ae 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"‏لا يُسمح بتصحيح أخطاء USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"‏لا يمكن للمستخدم الذي يسجّل دخوله حاليًا إلى هذا الجهاز تشغيل تصحيح أخطاء USB. لاستخدام هذه الميزة، يمكنك التبديل إلى المستخدم الأساسي."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"‏تمّ إيقاف منفذ USB"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"‏لحماية جهازك من السوائل أو الشوائب، سيتمّ إيقاف منفذ USB ولن يتم رصد أيّ ملحقات.\n\nوسيتمّ إعلامك عندما يُسمح باستخدام منفذ USB مرة أخرى."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"‏تم تفعيل منفذ USB لاكتشاف أجهزة الشحن والملحقات."</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"‏تفعيل USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"مزيد من المعلومات"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"تكبير/تصغير لملء الشاشة"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"توسيع بملء الشاشة"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"لقطة شاشة"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"جارٍ البحث عن وجهك"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"تمّت مصادقة الوجه."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"تمّ التأكيد."</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"يمكنك النقر على \"تأكيد\" لإكمال المهمة."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"المس زر استشعار بصمة الإصبع"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"رمز بصمة الإصبع"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"جارٍ البحث عن وجهك…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"جارٍ تغيير شبكة مشغِّل شبكة الجوّال."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"فتح تفاصيل البطارية"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"مستوى البطارية <xliff:g id="NUMBER">%d</xliff:g> في المائة."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"نسبة الشحن بالبطارية <xliff:g id="PERCENTAGE">%1$s</xliff:g> بالمائة، ويتبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا بناءً على استخدامك."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"جارٍ شحن البطارية، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"إعدادات النظام."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"الإشعارات."</string>
@@ -384,8 +384,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"حتى شروق الشمس"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"تفعيل الإعداد في <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"حتى <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"مظهر الألوان الداكنة"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"مظهر داكن\nتوفير شحن البطارية"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"مظهر داكن"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"مظهر داكن\nتوفير شحن البطارية"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"‏الاتصالات قصيرة المدى (NFC)"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"تم إيقاف الاتصال القريب المدى"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"تم تفعيل الاتصال القريب المدى"</string>
@@ -408,7 +408,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"الإشعارات الأقل إلحاحًا أدناه"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"انقر مرة أخرى للفتح"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"مرر سريعًا لأعلى لإلغاء القفل"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"تتولى مؤسستك إدارة هذا الجهاز."</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"تتم إدارة هذا الجهاز بواسطة <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"يمكنك التمرير سريعًا من الرمز لتشغيل الهاتف"</string>
@@ -464,16 +464,14 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"تم تفعيل ميزة توفير شحن البطارية"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"لخفض مستوى الأداء وبيانات الخلفية"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"إيقاف ميزة توفير شحن البطارية"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"أثناء التسجيل أو الإرسال، يمكن لتطبيق <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> تسجيل أي معلومات حساسة يتم عرضها على الشاشة أو تشغيلها من جهازك، بما فيها المعلومات الحساسة مثل الصوت الذي تشغّله وكلمات المرور ومعلومات الدفع والصور والرسائل."</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"أثناء التسجيل أو البث، يمكن لتطبيق <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> تسجيل أي معلومات حسّاسة يتم عرضها على الشاشة أو تشغيلها من جهازك، بما فيها المعلومات الحسّاسة مثل المقاطع الصوتية وكلمات المرور ومعلومات الدفع والصور والرسائل."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"أثناء التسجيل أو الإرسال، يمكن للخدمة التي تقدّم هذه الوظيفة تسجيل أي معلومات حساسة يتم عرضها على الشاشة أو تشغيلها من جهازك، بما فيها المعلومات الحساسة مثل الصوت الذي تشغّله وكلمات المرور ومعلومات الدفع والصور والرسائل."</string>
     <string name="media_projection_dialog_title" msgid="8124184308671641248">"عرض معلومات حسّاسة أثناء الإرسال/التسجيل"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"عدم الإظهار مرة أخرى"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"محو الكل"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"إدارة"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"الإشعارات الصامتة"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"محو جميع الإشعارات الصامتة"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"الرجاء عدم الإزعاج\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"البدء الآن"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ليس هناك أي اشعارات"</string>
@@ -544,7 +542,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"إعدادات الصوت"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"توسيع"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"تصغير"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"ترجمة تلقائية للوسائط"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"شرح تلقائي للوسائط"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"إغلاق نصيحة الشرح"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"تراكب الشرح"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"تفعيل"</string>
@@ -573,7 +571,7 @@
     <string name="stream_notification" msgid="2563720670905665031">"الإشعار"</string>
     <string name="stream_bluetooth_sco" msgid="2055645746402746292">"بلوتوث"</string>
     <string name="stream_dtmf" msgid="2447177903892477915">"تردد ثنائي متعدد النغمات"</string>
-    <string name="stream_accessibility" msgid="301136219144385106">"إمكانية الوصول"</string>
+    <string name="stream_accessibility" msgid="301136219144385106">"سهولة الاستخدام"</string>
     <string name="ring_toggle_title" msgid="3281244519428819576">"المكالمات"</string>
     <string name="volume_ringer_status_normal" msgid="4273142424125855384">"استصدار رنين"</string>
     <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"اهتزاز"</string>
@@ -581,8 +579,8 @@
     <string name="qs_status_phone_vibrate" msgid="204362991135761679">"الهاتف في وضع الاهتزاز"</string>
     <string name="qs_status_phone_muted" msgid="5437668875879171548">"تم كتم الهاتف."</string>
     <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"‏%1$s. انقر لإلغاء التجاهل."</string>
-    <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"‏%1$s. انقر للتعيين على الاهتزاز. قد يتم تجاهل خدمات إمكانية الوصول."</string>
-    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‏%1$s. انقر للتجاهل. قد يتم تجاهل خدمات إمكانية الوصول."</string>
+    <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"‏%1$s. انقر للتعيين على الاهتزاز. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string>
+    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"‏%1$s. انقر للتجاهل. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"‏%1$s. انقر للتعيين على الاهتزاز."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"‏%1$s. انقر لكتم الصوت."</string>
     <string name="volume_ringer_hint_mute" msgid="9199811307292269601">"كتم الصوت"</string>
@@ -657,21 +655,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"حظر"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"الاستمرار في تلقّي الإشعارات"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"تصغير"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"صامت"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"متابعة عرض الإشعارات بدون صوت"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"تنبيه"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"متابعة إرسال التنبيهات"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"إيقاف الإشعارات"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"هل تريد الاستمرار في تلقي إشعارات من هذا التطبيق؟"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"الإشعارات الهادئة"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"لها الأولوية"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"لمساعدتك على التركيز، يتم عرض هذه الإشعارات ضمن \"مركز الإشعارات\" فقط. كتم الصوت دائمًا."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"يتم عرض هذه الإشعارات تحت الإشعارات ذات الأولوية، مع كتم صوتها دائمًا."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"يتم عرض هذه الإشعارات تحت الإشعارات ذات الأولوية، مع كتم صوتها دائمًا."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"يتم عرض هذه الإشعارات تحت الإشعارات ذات الأولوية، مع كتم صوتها دائمًا."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"عند تلقّي هذه الإشعارات، سيظهر رمز في شريط الحالة مع صوت للفت انتباهك. ويتم عرض هذه الإشعارات على شاشة التأمين."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"إشعار صامت"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"إشعار مصحوب بتنبيه صوتي"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"يساعدك هذا الإشعار على التركيز بدون صوت أو اهتزاز."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"يلفت هذا الإشعار انتباهك باستخدام الصوت والاهتزاز."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"يتعذّر تعديل هذه الإشعارات."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"يتعذّر ضبط مجموعة الإشعارات هذه هنا."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"إشعار مستند إلى خادم وكيل"</string>
@@ -806,8 +799,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"اضغط باستمرار مع السحب لإضافة الميزات."</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"اضغط باستمرار مع السحب لإعادة ترتيب الميزات."</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"اسحب هنا للإزالة"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"الحدّ الأدنى من عدد المربعات الذي تحتاج إليه هو <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"تعديل"</string>
     <string name="tuner_time" msgid="6572217313285536011">"الوقت"</string>
   <string-array name="clock_options">
@@ -929,8 +921,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"سماح"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"رفض"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"انقر لجدولة \"توفير شحن البطارية\"."</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"فعِّل الميزة إذا كان من المرجح نفاد شحن البطارية."</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"لا، شكرًا"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"تم تفعيل جدولة \"توفير شحن البطارية\"."</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"سيتم تفعيل ميزة \"توفير شحن البطارية\" عندما تنخفض البطارية عن <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -963,4 +954,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"نقل إلى أسفل يمين الشاشة"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"نقل إلى أسفل اليسار"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"تجاهل"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"تم تحديث التنقل داخل النظام. لإجراء التغييرات، يُرجى الانتقال إلى \"الإعدادات\"."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"الانتقال إلى \"الإعدادات\" لتعديل التنقل داخل النظام"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-as/config.xml b/packages/SystemUI/res/values-as/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-as/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 57e190d..c7b5f08 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"ইউএছবি ডিবাগিঙৰ অনুমতি নাই"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"এই ডিভাইচটোত বর্তমান ছাইন ইন হৈ থকা ব্যৱহাৰকাৰীজনে ইউএছবি ডিবাগিং অন কৰিব নোৱাৰে। এই সুবিধাটো ব্যৱহাৰ কৰিবলৈ হ\'লে মুখ্য ব্যৱহাৰকাৰী হিচাপে ছাইন ইন কৰক।"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"ইউএছবি প’ৰ্ট অক্ষম কৰা হ’ল"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"আপোনাৰ ডিভাইচটো তৰল বা ধূলি-মাকতিৰ পৰা ৰক্ষা কৰিবলৈ ইউএছবি প’ৰ্টটো অক্ষম কৰি ৰখা হৈছে ফলত ই কোনো আনুষংগিক সামগ্ৰী ধৰা পেলাব নোৱাৰে।\n\nযেতিয়া ইউএছবি প’ৰ্টটো নিৰাপদভাৱে ব্যৱহাৰ কৰিব পৰা হ’ব তেতিয়া আপোনাক জনোৱা হ’ব।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"চাৰ্জাৰ আৰু আনুষংগিক সামগ্ৰী চিনাক্ত কৰিবলৈ USB প’ৰ্ট সক্ষম কৰা হ’ল"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB সক্ষম কৰক"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"অধিক জানক"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"স্ক্ৰীণ পূর্ণ কৰিবলৈ জুম কৰক"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"স্ক্ৰীণ পূর্ণ কৰিবলৈ প্ৰসাৰিত কৰক"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"স্ক্ৰীণশ্বট"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"আপোনাৰ মুখমণ্ডল বিচাৰি থকা হৈছে"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"মুখমণ্ডলৰ বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"নিশ্চিত কৰিলে"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"সম্পূৰ্ণ কৰিবলৈ নিশ্চিত কৰক-ত টিপক"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"আপোনাৰ মুখমণ্ডল বিচাৰি আছে…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"বাহক নেটৱৰ্কৰ পৰিৱৰ্তন"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"বেটাৰিৰ বিৱৰণসমূহ খোলক"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ বেটাৰি।"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"আপোনাৰ ব্যৱহাৰৰ ওপৰত ভিত্তি কৰি বেটাৰী <xliff:g id="PERCENTAGE">%1$s</xliff:g> শতাংশ, প্ৰায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"বেটাৰি চ্চাৰ্জ কৰি থকা হৈছে, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> শতাংশ।"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ছিষ্টেমৰ ছেটিংসমূহ৷"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"জাননীসমূহ।"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"সূৰ্যোদয়ৰ লৈকে"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>ত অন কৰক"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> পৰ্যন্ত"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"গাঢ় ৰঙৰ থীম"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"গাঢ় ৰঙৰ থীম\nবেটাৰী সঞ্চয়কাৰী"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"গাঢ় ৰঙৰ থীম"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"গাঢ় ৰঙৰ থীম\nবেটাৰী সঞ্চয়কাৰী"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC নিষ্ক্ৰিয় হৈ আছে"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC সক্ষম হৈ আছে"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"কম জৰুৰী জাননীসমূহ তলত"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"খুলিবলৈ পুনৰাই টিপক"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"আনলক কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটো পৰিচালনা কৰে"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ৰ দ্বাৰা পৰিচালিত।"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ফ\'নৰ বাবে আইকনৰপৰা ছোৱাইপ কৰক"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"পুনৰাই নেদেখুৱাব"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"সকলো মচক"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"পৰিচালনা"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"নীৰৱ জাননীসমূহ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"সকলো নীৰৱ জাননী মচক"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"অসুবিধা নিদিব-ই জাননী পজ কৰিছে"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"এতিয়াই আৰম্ভ কৰক"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"কোনো জাননী নাই"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"অৱৰোধ কৰক"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"দেখুওৱাই থাকক"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"সৰু কৰক"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"নিৰৱ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"নীৰৱ হৈ থাকক"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"সতৰ্ক কৰক"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"সতৰ্ক কৰি থাকক"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"জাননী অফ কৰক"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"এই এপটোৰ জাননী দেখুওৱাই থাকিব লাগিবনে?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"সাধাৰণ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"অগ্ৰাধিকাৰপ্ৰাপ্ত"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"আপুনি যাতে অসুবিধা নাপায়, তাৰ বাবে কেৱল পুল-ডাউন শ্বেডত এই জাননী দেখুৱায়। সদায় নিৰৱ।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"অগ্ৰাধিকাৰপ্ৰাপ্ত জাননীসমূহৰ তলত দেখুৱায়। সদায় নিৰৱ।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"অগ্ৰাধিকাৰপ্ৰাপ্ত জাননীসমূহৰ তলত দেখুৱায়। সদায় নিৰৱ।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"অগ্ৰাধিকাৰপ্ৰাপ্ত জাননীসমূহৰ তলত দেখুৱায়। সদায় নিৰৱ।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ধ্বনি আৰু স্থিতি দণ্ডৰ আইকনৰ জৰিয়তে আপোনাৰ মনোযোগ আকৰ্ষণ কৰে। লক স্ক্ৰীণত দেখুৱায়।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"নীৰৱ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"সতৰ্ক কৰক"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"কোনো ধ্বনি অথবা কম্পন অবিহনে আপোনাক মনোযোগ দিয়াত সহায় কৰে।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ধ্বনি অথবা কম্পনৰ জৰিয়তে আপোনাৰ মনোযোগ আকৰ্ষণ কৰে।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"এই জাননীসমূহ সংশোধন কৰিব নোৱাৰি।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"এই ধৰণৰ জাননীবোৰ ইয়াত কনফিগাৰ কৰিব পৰা নাযায়"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"প্ৰক্সি হিচাপে পঠিওৱা জাননী"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"টাইল যোগ কৰিবলৈ হেঁচি ধৰি টানি আনক"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"টাইলসমূহ পুনৰ সজাবলৈ ধৰি টানক"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"আঁতৰাবৰ বাবে টানি আনি ইয়াত এৰি দিয়ক"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"আপোনাক অতিকমেও <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>খন টাইল লাগিব"</string>
     <string name="qs_edit" msgid="2232596095725105230">"সম্পাদনা কৰক"</string>
     <string name="tuner_time" msgid="6572217313285536011">"সময়"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"অনুমতি দিয়ক"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"অস্বীকাৰ কৰক"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"বেটাৰি সঞ্চয়কাৰীৰ সময়সূচী সক্ৰিয় কৰিবলৈ টিপক"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"বেটাৰি শেষ হোৱাৰ সম্ভাৱনা থাকিলে অন কৰক"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"নালাগে, ধন্যবাদ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"বেটাৰি সঞ্চয়কাৰীৰ সময়সূচী অন কৰা অৱস্থাত আছে"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"বেটাৰি চ্চাৰ্জৰ স্তৰ <xliff:g id="PERCENTAGE">%d</xliff:g>%%তকৈ কম হোৱাৰ লগে লগে বেটাৰি সঞ্চয়কাৰী স্বয়ংক্ৰিয়ভাৱে অন হ’ব।"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"বুটামটো বাওঁফালে নিয়ক"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"তলৰ সোঁফালে নিয়ক"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"অগ্ৰাহ্য কৰক"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰা হ’ল। সলনি কৰিবলৈ ছেটিংসমূহ-লৈ যাওক।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ছিষ্টেম নেভিগেশ্বন আপডে’ট কৰিবলৈ ছেটিংসমূহ-লৈ যাওক"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/config.xml b/packages/SystemUI/res/values-az/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-az/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index f7537a1..847d10d 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB debaq prosesinə icazə verilmir"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Hazırda bu cihaza daxil olmuş istifadəçi USB sazlama prosesini aktiv edə bilməz. Bu funksiyadan istifadə etmək üçün əsas istifadəçi hesaba daxil olmalıdır."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB portu deaktiv edildi"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB portu deaktivdir. Cihazı maye və zərbədən qorumaq üçün aksesuar aşkarlanmayacaq.\n\nUSB portu yenidən istifadə üçün təhlükəsiz olduqda bildiriş göndəriləcək."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Adapter və aksesuarları aşkarlamaq üçün USB portu aktiv edildi"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB-ni aktiv edin"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Ətraflı məlumat"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Ekranı doldurmaq üçün yaxınlaşdır"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ekranı doldurmaq üçün uzat"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skrinşot"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Üzünüz axtarılır"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Üz doğrulandı"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Təsdiqləndi"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tamamlamaq üçün \"Təsdiq edin\" seçiminə toxunun"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Barmaq izi sensoruna klikləyin"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Barmaq izi ikonası"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Siz axtarılırsınız…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator şəbəkəsinin dəyişilməsi"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Batareya detallarını açın"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> faizdir."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batareya <xliff:g id="PERCENTAGE">%1$s</xliff:g> faizdir, istifadəyə əsasən təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batareya doldurulur, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%% faiz."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistem parametrləri"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirişlər."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Şəfəq vaxtına qədər"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> olduqda aktiv ediləcək"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> vaxtına qədər"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tünd Tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tünd Tema\nEnerjiyə Qənaət"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tünd tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tünd tema\nEnerjiyə Qənaət"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC deaktiv edilib"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC aktiv edilib"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az təcili bildirişlər aşağıdadır"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Açmaq üçün yenidən tıklayın"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Kiliddən çıxarmaq üçün yuxarı çəkin"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Açmaq üçün yuxarı sürüşdürün"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu cihaz təşkilatınız tərəfindən idarə olunur"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tərəfindən idarə olunur"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefon üçün ikonadan sürüşdürün"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Daha göstərmə"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hamısını silin"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"İdarə edin"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Səssiz bildirişlər"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Səssiz bildirişlərin hamısını silin"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Bildirişlər \"Narahat Etməyin\" rejimi tərəfindən dayandırıldı"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"İndi başlayın"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Heç bir bildiriş yoxdur"</string>
@@ -561,7 +559,7 @@
     <string name="stream_notification" msgid="2563720670905665031">"Bildiriş"</string>
     <string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
     <string name="stream_dtmf" msgid="2447177903892477915">"Çoxsaylı ton olan ikili tezlik"</string>
-    <string name="stream_accessibility" msgid="301136219144385106">"Münasiblik"</string>
+    <string name="stream_accessibility" msgid="301136219144385106">"Əlçatımlılıq"</string>
     <string name="ring_toggle_title" msgid="3281244519428819576">"Zənglər"</string>
     <string name="volume_ringer_status_normal" msgid="4273142424125855384">"Zəng"</string>
     <string name="volume_ringer_status_vibrate" msgid="1825615171021346557">"Vibrasiya"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blok edin"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Göstərməyə davam edin"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Kiçildin"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Səssiz"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Səssiz göstərilsin"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Siqnal"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Xəbərdarlıq göndərməyə davam edin"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Bildirişləri deaktiv edin"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu tətbiqin bildirişləri göstərilməyə davam edilsin?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Daha az əhəmiyyətli"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Mühüm"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Yalnız aşağı açılan siyahıda bildirişlərə fokuslanmağınıza kömək edir. Həmişə səssiz."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Mühüm bildirişlərin aşağısında göstərilir. Həmişə səssiz."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Mühüm bildirişlərin aşağısında göstərilir. Həmişə səssiz."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Mühüm bildirişlərin aşağısında göstərilir. Həmişə səssiz."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Səs &amp; status paneli ikonası ilə diqqətinizi cəlb edir. Ekran kilidini göstərir."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Səssiz"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Siqnal"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Səs və ya vibrasiya olmadan fokuslanmağınıza kömək edir."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Səs və ya vibrasiya ilə diqqətinizi çəkir."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirişlər dəyişdirilə bilməz."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Bu bildiriş qrupunu burada konfiqurasiya etmək olmaz"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proksi bildirişi"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Mozaika əlavə etmək üçün basıb saxlayaraq çəkin"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Mozaikaları yenidən təşkil etmək üçün basıb saxlayın və çəkin"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Silmək üçün bura sürüşdürün"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Minimum <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mozaika lazımdır"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Redaktə edin"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Vaxt"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"İcazə verin"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Rədd edin"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Batareya Qənaətini planlaşdırmaq üçün klikləyin"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Batareya bitmək üzrə olduqda aktiv edin"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Xeyr, təşəkkür"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Batareya Qənaəti aktivdir"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batareya <xliff:g id="PERCENTAGE">%d</xliff:g>%%-dən aşağı düşdükdə Batareya Qənaəti avtomatik aktiv ediləcək."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Aşağıya sola köçürün"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Aşağıya sağa köçürün"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Kənarlaşdırın"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistem naviqasiyası yeniləndi. Dəyişiklik etmək üçün Ayarlara daxil olun."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistem naviqasiyasını yeniləmək üçün Ayarlara keçin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/config.xml b/packages/SystemUI/res/values-b+sr+Latn/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-b+sr+Latn/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 55985df..78e9d04 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Otklanjanje grešaka na USB-u nije dozvoljeno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može da uključi otklanjanje grešaka na USB-u. Da biste koristili ovu funkciju, prebacite na primarnog korisnika."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB port je onemogućen"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Da bi se uređaj zaštitio od tečnosti ili nečistoće, USB port je onemogućen i neće otkrivati dodatnu opremu.\n\nObavestićemo vas kada ponovo budete mogli da koristite USB port."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB port je omogućen radi otkrivanja punjača i dodatne opreme"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Omogući USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saznajte više"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zumiraj na celom ekranu"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Razvuci na ceo ekran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimak ekrana"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Traži se vaše lice"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Lice je potvrđeno"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrđeno"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Dodirnite Potvrdi da biste završili"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor za otisak prsta"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otiska prsta"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Promena mreže mobilnog operatera"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvori detalje o bateriji"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija je na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto, preostalo vreme na osnovu korišćenja je <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemska podešavanja."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obaveštenja."</string>
@@ -378,8 +378,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do izlaska sunca"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tamna tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tamna tema\nUšteda baterije"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tamna tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tamna tema\nUšteda baterije"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC je omogućen"</string>
@@ -402,7 +402,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitna obaveštenja su u nastavku"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da biste otvorili"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Prevucite nagore da biste otključali"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Prevucite nagore da biste otvorili"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prevucite od ikone za telefon"</string>
@@ -461,10 +461,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne prikazuj ponovo"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Obriši sve"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljajte"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Nečujna obaveštenja"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Obrišite sva nečujna obaveštenja"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Obaveštenja su pauzirana režimom Ne uznemiravaj"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Započni odmah"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nema obaveštenja"</string>
@@ -648,21 +646,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokiraj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nastavi da prikazuješ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Umanji"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Nečujno"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Ne uključuj zvuk"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Upozoravanje"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Nastavi sa obaveštenjima"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Isključi obaveštenja"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite li da se obaveštenja iz ove aplikacije i dalje prikazuju?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskretno"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritetno"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomaže vam da se fokusirate. Obaveštenja su samo na padajućoj traci. Uvek nečujno."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Prikazuje se ispod prioritetnih obaveštenja. Uvek nečujno."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Prikazuje se ispod prioritetnih obaveštenja. Uvek nečujno."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Prikazuje se ispod prioritetnih obaveštenja. Uvek nečujno."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Privlači vam pažnju pomoću zvuka i ikone statusne trake. Prikazuje se na zaključanom ekranu."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Nečujno"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Upozoravanje"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se koncentrišete bez zvuka ili vibracije."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vam pažnju pomoću zvuka ili vibracije."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ova obaveštenja ne mogu da se menjaju."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ova grupa obaveštenja ne može da se konfiguriše ovde"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obaveštenje preko proksija"</string>
@@ -791,8 +784,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Zadržite i prevucite da biste dodali pločice"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Zadržite i prevucite da biste promenili raspored pločica"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Prevucite ovde da biste uklonili"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Minimalan broj pločica je <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Izmeni"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Vreme"</string>
   <string-array name="clock_options">
@@ -914,8 +906,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Dozvoli"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Odbij"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Dodirnite da biste napravili raspored za uštedu baterije"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Uključite ako će baterija verovatno da se isprazni"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, hvala"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Raspored za uštedu baterije je uključen"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Ušteda baterije će se automatski uključivati kada baterija padne ispod <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -948,4 +939,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Premesti dole levo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Premesti dole desno"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/config.xml b/packages/SystemUI/res/values-be/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-be/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 0e0ac54..26e34d3 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Адладка USB не дапускаецца"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Карыстальнік, які зараз увайшоў у гэту прыладу, не можа ўключыць адладку USB. Каб выкарыстоўваць гэту функцыю, пераключыцеся на асноўнага карыстальніка."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Порт USB адключаны"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Порт USB адключаны, каб засцерагчы прыладу ад вадкасці і смецця, таму дадатковае абсталяванне не будзе выяўлена.\n\nВы атрымаеце апавяшчэнне, калі порт USB можна будзе выкарыстоўваць зноў."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-порту дазволена вызначаць зарадныя прылады і аксесуары"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Уключыць USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Даведацца больш"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Павял. на ўвесь экран"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Расцягн. на ўвесь экран"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Здымак экрана"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Ідзе пошук твару"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Твар распазнаны"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Пацверджана"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Націсніце \"Пацвердзіць\", каб завяршыць"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Дакраніцеся да сканера адбіткаў пальцаў"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок адбіткаў пальцаў"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ідзе пошук вашага твару…"</string>
@@ -201,6 +200,7 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
     <skip />
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Зарад акумулятара ў працэнтах: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Пры такім выкарыстанні яго хопіць прыблізна на <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Зарадка акумулятара: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Сістэмныя налады."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Апавяшчэнні."</string>
@@ -382,8 +382,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Да ўсходу сонца"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Уключыць у <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Да <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Цёмная тэма"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Цёмная тэма\nЭканомія зараду"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Цёмная тэма"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Цёмная тэма\nЭканомія зараду"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC адключаны"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC уключаны"</string>
@@ -406,7 +406,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Менш тэрміновыя апавяшчэнні ніжэй"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Дакраніцеся яшчэ раз, каб адкрыць"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Правядзіце пальцам уверх, каб разблакіраваць"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Каб адкрыць, прагарніце ўверх"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Гэта прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Тэлефон: правядзіце пальцам ад значка"</string>
@@ -466,10 +466,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Не паказваць зноў"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ачысціць усё"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Кіраваць"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Апавяшчэнні без гуку"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Выдаліць усе апавяшчэнні без гуку"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Паказ апавяшчэнняў прыпынены ў рэжыме \"Не турбаваць\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Пачаць зараз"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Апавяшчэнняў няма"</string>
@@ -540,7 +538,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Налады гуку"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Разгарнуць"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Згарнуць"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Аўтаматычныя цітры"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Аўтаматычныя субцітры"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Падказка \"Схавайце цітры\""</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Накладанне субцітраў"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"уключыць"</string>
@@ -653,26 +651,21 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Заблакіраваць"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Працягваць паказваць"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Згарнуць"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Бязгучны рэжым"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Не ўключаць гук"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Апавяшчаць"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Апавяшчаць далей"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Выключыць апавяшчэнні"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Працягваць паказваць апавяшчэнні гэтай праграмы?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Ціхі рэжым"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Прыярытэтныя"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Дапамагае не адцягваць увагу, паказваючы апавяшчэнні толькі на апушчанай шторцы. Заўсёды без гуку."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Паказвае ўнізе апавяшчэнні з высокім прыярытэтам. Заўсёды без гуку."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Паказвае ўнізе апавяшчэнні з высокім прыярытэтам. Заўсёды без гуку."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Паказвае ўнізе апавяшчэнні з высокім прыярытэтам. Заўсёды без гуку."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Прываблівае ўвагу гукам і значком на панэлі стану. Паказвае на экране блакіроўкі."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Бязгучны рэжым"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Абвесткі"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Не адцягвае ўвагу дзякуючы выключаным гуку і вібрацыі."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Прыцягвае ўвагу гукам і вібрацыяй."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Гэтыя апавяшчэнні нельга змяніць."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Тут канфігурыраваць гэту групу апавяшчэнняў забаронена"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Праксіраванае апавяшчэнне"</string>
     <string name="notification_channel_dialog_title" msgid="5745335243729167866">"Усе апавяшчэнні праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
-    <string name="see_more_title" msgid="5358726697042112726">"Разгарнуць"</string>
+    <string name="see_more_title" msgid="5358726697042112726">"Яшчэ"</string>
     <string name="appops_camera" msgid="8100147441602585776">"Гэта праграма выкарыстоўвае камеру."</string>
     <string name="appops_microphone" msgid="741508267659494555">"Гэта праграма выкарыстоўвае мікрафон."</string>
     <string name="appops_overlay" msgid="6165912637560323464">"Гэта праграма паказваецца на экране паверх іншых праграм."</string>
@@ -798,8 +791,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Перацягніце патрэбныя пліткі"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Каб змяніць парадак плітак, утрымлівайце і перацягвайце іх"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Перацягніце сюды, каб выдаліць"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Мінімальная колькасць плітак: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Рэдагаваць"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Час"</string>
   <string-array name="clock_options">
@@ -921,8 +913,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дазволіць"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Адмовіць"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Націсніце, каб уключыць рэжым эканоміі зараду"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Уключыце, калі зарад акумулятара заканчваецца"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Не, дзякуй"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Уключаны рэжым эканоміі зараду"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Калі ўзровень зараду акумулятара знізіцца да <xliff:g id="PERCENTAGE">%d</xliff:g>%%, аўтаматычна ўключыцца рэжым эканоміі энергіі."</string>
@@ -955,4 +946,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Перамясціць лявей і ніжэй"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Перамясціць правей і ніжэй"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Адхіліць"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навігацыя ў сістэме абноўлена. Каб унесці змяненні, перайдзіце ў Налады."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Перайдзіце ў Налады, каб абнавіць параметры навігацыі ў сістэме"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/config.xml b/packages/SystemUI/res/values-bg/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-bg/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 3f3d2cf..a0128eb 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отстраняването на грешки през USB не е разрешено"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Потребителят, който понастоящем е влязъл в това устройство, не може да включи функцията за отстраняване на грешки през USB. За да я използвате, превключете към основния потребител."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB портът е деактивиран"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"С цел защита на устройството ви от течности и замърсяване USB портът е деактивиран и няма да открива аксесоари.\n\nЩе получите известие, когато можете отново да използвате USB порта."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB портът може да разпознава зарядни устройства и аксесоари"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Активиране на USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Научете повече"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Мащаб – запълва екрана"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Разпъване – запълва екрана"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Екранна снимка"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Лицето ви се търси"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Лицето е удостоверено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Потвърдено"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Докоснете „Потвърждаване“ за завършване"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Докоснете сензора за отпечатъци"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона за отпечатък"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Търсим ви…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Промяна на мрежата на оператора"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Отваряне на подробностите за батерията"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> процента батерия."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батерията е на <xliff:g id="PERCENTAGE">%1$s</xliff:g> процента. Още около <xliff:g id="TIME">%2$s</xliff:g> въз основа на използването"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батерията се зарежда – <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Системни настройки."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Известия."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"До изгрев"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Ще се включи в <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Тъмна тема"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Тъмна тема\nРежим за запазв. на батерията"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Тъмна тема"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Тъмна тема\nЗапазване на батерията: Режим"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"КБП"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"КБП е деактивирана"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"КБП е активирана"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Ппоказване на по-малко спешните известия по-долу"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Докоснете отново, за да отворите"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Плъзнете нагоре, за да отключите"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Прекарайте пръст нагоре, за да отключите"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Това устройство се управлява от организацията ви"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Това устройство се управлява от <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Плъзнете с пръст от иконата, за да използвате телефона"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Да не се показва отново"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Изчистване на всички"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Управление"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Беззвучни известия"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Изчистване на всички беззвучни известия"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Известията са поставени на пауза от режима „Не безпокойте“"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Стартиране сега"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Няма известия"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блокиране"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Да продължат да се показват"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Намаляване"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Тих режим"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Показване на известията без звук"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Сигнализиране"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Продължаване на сигнализирането"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Изключване на известията"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Да продължат ли да се показват известията от това приложение?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Ненатрапчиви известия"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Приоритетни известия"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Помага ви да се съсредоточите, като известията се показват само в падащия панел. Винаги в тих режим."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Показва се под приоритетните известия. Винаги в тих режим."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Показва се под приоритетните известия. Винаги в тих режим."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Показва се под приоритетните известия. Винаги в тих режим."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Привлича вниманието ви със звук и икона в лентата на състоянието. Показва се на заключения екран."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Тих режим"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Сигнализиране"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Помага ви да се фокусирате без звук или вибриране."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привлича вниманието ви със звук или вибриране."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Тези известия не могат да бъдат променяни."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Тази група от известия не може да бъде конфигурирана тук"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Известие, получено чрез делегиране"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Задръжте и плъзнете, за да добавите плочки"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Задръжте и плъзнете, за да пренаредите плочките"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Преместете тук с плъзгане за премахване"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Трябва да останат поне <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> плочки"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Редактиране"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Час"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Разрешаване"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Отказ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Докоснете, за да активирате автоматичния режим за запазване на батерията"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Включване, когато е вероятно батерията да се изтощи"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Не, благодаря"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Включен е автоматичен режим за запазване на батерията"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Режимът за запазване на батерията ще се включи автоматично, след като нивото й премине под <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Преместване долу вляво"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Преместване долу вдясно"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Отхвърляне"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Режимът за навигиране в системата е актуализиран. За да извършите промени, отворете настройките."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Отворете настройките, за да актуализирате режима за навигиране в системата"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/config.xml b/packages/SystemUI/res/values-bn/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-bn/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index ba32785..bf7dd0b 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ডিবাগিং অনুমোদিত নয়"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ব্যবহারকারী এখন এই ডিভাইসে সাইন-ইন করেছেন তাই USB ডিবাগিং চালু করা যাবে না। এই বৈশিষ্ট্যটি ব্যবহার করতে, প্রাথমিক ব্যবহারকারীতে পাল্টে নিন।"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"ইউএসবি পোর্ট বন্ধ করা হয়েছে"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"কোনও তরল পদার্থ ও ধুলো থেকে আপনার ডিভাইসকে সুরক্ষিত রাখতে, ইউএসবি পোর্ট বন্ধ করা আছে, তাই কোনও অ্যাক্সেসরির শনাক্ত করা যাবে না।\n\nইউএসবি পোর্ট আবার ব্যবহার করা নিরাপদ হলে, আপনাকে জানানো হবে।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"চার্জার ও আনুষঙ্গিক আইটেম শনাক্ত করার জন্য ইউএসবি চালু করা হয়েছে"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"ইউএসবি চালু করুন"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"আরও জানুন"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"স্ক্রীণ পূরণ করতে জুম করুন"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ফুল স্ক্রিন করুন"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"স্ক্রিনশট নিন"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"আপনার ফেস খোঁজা হচ্ছে"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"ফেস যাচাই করা হয়েছে"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"কনফার্ম করা হয়েছে"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"সম্পূর্ণ করতে \'কনফার্ম করুন\' বোতামে ট্যাপ করুন"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"আঙ্গুলের ছাপের সেন্সর স্পর্শ করুন"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"আঙ্গুলের ছাপের আইকন"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"আপনার জন্য খোঁজা হচ্ছে…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"পরিষেবা প্রদানকারীর নেটওয়ার্ক পরিবর্তন করা হচ্ছে"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ব্যাটারির বিশদ বিবরণ খুলুন"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> শতাংশ ব্যাটারি রয়েছে৷"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ব্যাটারি <xliff:g id="PERCENTAGE">%1$s</xliff:g> শতাংশ, বর্তমান ব্যবহারের উপর ভিত্তি করে আর <xliff:g id="TIME">%2$s</xliff:g> চলবে"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ব্যাটারি চার্জ হচ্ছে, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> শতাংশ৷"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"সিস্টেম সেটিংস৷"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"বিজ্ঞপ্তি৷"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"সূর্যোদয় পর্যন্ত"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> এ চালু হবে"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> পর্যন্ত"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"গাঢ় থিম"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"গাঢ় থিম\nব্যাটারি সেভার"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"গাঢ় থিম"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"গাঢ় থিম\nব্যাটারি সেভার"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC অক্ষম করা আছে"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC সক্ষম করা আছে"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"নিচে অপেক্ষাকৃত কম জরুরী বিজ্ঞপ্তিগুলি"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"খোলার জন্য আবার আলতো চাপুন"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"আনলক করতে উপরের দিকে সোয়াইপ করুন"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"আপনার সংস্থা এই ডিভাইসটি পরিচালনা করছে"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> এর দ্বারা পরিচালিত"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ফোনের জন্য আইকন থেকে সোয়াইপ করুন"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"আর দেখাবেন না"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"সবকিছু সাফ করুন"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"পরিচালনা করুন"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"নীরব বিজ্ঞপ্তি"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"সব নীরব বিজ্ঞপ্তি মুছুন"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'বিরক্ত করবেন না\' দিয়ে বিজ্ঞপ্তি পজ করা হয়েছে"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"এখন শুরু করুন"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"কোনো বিজ্ঞপ্তি নেই"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ব্লক করুন"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"দেখতে থাকুন"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ছোট করে দিন"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"নীরব রাখুন"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"বিজ্ঞপ্তি মিউট করুন"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"সতর্ক করুন"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"বিজ্ঞপ্তি পান"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"বিজ্ঞপ্তি বন্ধ করুন"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"এই অ্যাপের বিজ্ঞপ্তি পরেও দেখে যেতে চান?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"সাইলেন্ট মোডে"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"অগ্রাধিকার দেওয়া হয়েছে"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"আপনি যাতে বিরক্ত না হন, তার জন্য শুধুমাত্র পুল-ডাউন শেডে এই বিজ্ঞপ্তি দেখায়। সবসময় সাইলেন্ট।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"অগ্রাধিকারযুক্ত বিজ্ঞপ্তির নিচে দেখানো হয়। সবসময় সাইলেন্ট।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"অগ্রাধিকারযুক্ত বিজ্ঞপ্তির নিচে দেখানো হয়। সবসময় সাইলেন্ট।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"অগ্রাধিকারযুক্ত বিজ্ঞপ্তির নিচে দেখানো হয়। সবসময় সাইলেন্ট।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"সাউন্ড ও স্ট্যাটাস বার আইকনের সাহায্যে দৃষ্টি আকর্ষণ করে। এটি লক স্ক্রিনে দেখা যায়।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"সাইলেন্ট"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"সতর্ক করুন"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"সাউন্ড বা ভাইব্রেশন ছাড়া ফোকাস করতে আপনাকে সাহায্য করে।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"সাউন্ড বা ভাইব্রেশনের সাহায্যে দৃষ্টি আকর্ষণ করে।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"এই বিজ্ঞপ্তিগুলি পরিবর্তন করা যাবে না।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"এই সমস্ত বিজ্ঞপ্তিকে এখানে কনফিগার করা যাবে না"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"প্রক্সি করা বিজ্ঞপ্তি"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"টাইল যোগ করতে ধরে থেকে টেনে আনুন"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"টাইলগুলি আবার সাজানোর জন্য ধরে থেকে টেনে আনুন"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"সরানোর জন্য এখানে টেনে আনুন"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"আপনাকে কমপক্ষে <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>টি টাইল রাখতে হবে"</string>
     <string name="qs_edit" msgid="2232596095725105230">"সম্পাদনা করুন"</string>
     <string name="tuner_time" msgid="6572217313285536011">"সময়"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"অনুমতি দিন"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"খারিজ করুন"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ব্যাটারি সেভার চালু হওয়ার সময় সেট করতে ট্যাপ করুন"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ব্যাটারির চার্জ শেষ হয়ে যাওয়ার সম্ভাবনা দেখা দিলে চালু করুন"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"না থাক"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"আগে সেট করা সময় অনুযায়ী ব্যাটারি সেভার চালু হয়েছে"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"চার্জ <xliff:g id="PERCENTAGE">%d</xliff:g>%%-এর নিচে চলে গেলে ব্যাটারি সেভার নিজে থেকেই চালু হয়ে যাবে।"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"নিচে বাঁদিকে সরান"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"নিচে ডান দিকে সরান"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"খারিজ করুন"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"সিস্টেম নেভিগেশন আপডেট হয়েছে। পরিবর্তন করার জন্য সেটিংসে যান।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"সিস্টেম নেভিগেশন আপডেট করতে সেটিংসে যান"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/config.xml b/packages/SystemUI/res/values-bs/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-bs/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index d614159..d7e5c23 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Otklanjanje grešaka putem uređaja spojenog na USB nije dozvoljeno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Korisnik koji je trenutno prijavljen na ovaj uređaj ne može uključiti opciju za otklanjanje grešaka koristeći USB. Da koristite tu funkciju, prebacite se na primarnog korisnika."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB priključak je onemogućen"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB priključak je onemogućen kako bi se vaš uređaj zaštitio od tečnosti i nečistoća i neće detektirati priključene uređaje.\n\nDobit ćete obavještenje kada ponovo bude sigurno koristiti USB priključak."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB priključak je omogućen za prepoznavanje punjača i pribora"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Omogući USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saznajte više"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Uvećaj prikaz na ekran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Razvuci prikaz na ekran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimak ekrana"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Traženje vašeg lica"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Lice je provjereno"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrđeno"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Dodirnite Potvrdi da završite"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor za otisak prsta"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona za otisak prsta"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Promjena mreže mobilnog operatera"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvori detalje o potrošnji baterije"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto. Na osnovu vaše potrošnje preostalo vam je otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Punjenje baterije, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Postavke sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obavještenja."</string>
@@ -378,8 +378,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do svitanja"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tamna tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tamna tema\nUšteda baterije"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tamna tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tamna tema\nUšteda baterije"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC je omogućen"</string>
@@ -402,7 +402,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Prikaži manje važna obavještenja ispod"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da otvorite"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Prevucite prema gore da otključate"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Prevucite da otvorite"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja vaša organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prevucite preko ikone da otvorite telefon"</string>
@@ -461,10 +461,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne prikazuj opet"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Očisti sve"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljaj"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Nečujna obavještenja"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Obriši sva nečujna obavještenja"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Obavještenja su pauzirana načinom rada Ne ometaj"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Započni odmah"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nema obavještenja"</string>
@@ -650,21 +648,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokiraj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nastavi prikazivanje"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimiziraj"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Nečujno"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Ostani u nečujnom načinu rada"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Upozorenja"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Nastavi upozoravati"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Isključi obavještenja"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Nastaviti prikazivanje obavještenja iz ove aplikacije?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskretno"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritetno"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomaže vam da se fokusirate prikazujući obavještenja samo na padajućoj traci. Uvijek nečujno."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Prikazuje se ispod prioritetnih obavještenja. Uvijek nečujno."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Prikazuje se ispod prioritetnih obavještenja. Uvijek nečujno."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Prikazuje se ispod prioritetnih obavještenja. Uvijek nečujno."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Privlači vašu pažnju pomoću zvuka i ikone na statusnoj traci. Prikazuje se na zaključanom ekranu."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Nečujno"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Upozorenja"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se koncentrirate bez zvuka ili vibracije."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vašu pažnju pomoću zvuka ili vibracije."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ta obavještenja se ne mogu izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ovdje nije moguće konfigurirati ovu grupu obavještenja"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obavještenje preko proksi servera"</string>
@@ -793,8 +786,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Držite i prevucite da dodate polja"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Držite i prevucite da preuredite polja"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Prevucite ovdje za uklanjanje"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Broj polja mora biti najmanje <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Uredite"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Vrijeme"</string>
   <string-array name="clock_options">
@@ -916,8 +908,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Dozvoli"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Odbij"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Dodirnite da zakažete Uštedu baterije"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Uključite ako je vjerovatno da će se baterija istrošiti"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, hvala"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Zakazivanje Uštede baterije je uključeno"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Kada je baterija ispod <xliff:g id="PERCENTAGE">%d</xliff:g>%%, Ušteda baterije se automatski uključuje."</string>
@@ -950,4 +941,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Pomjeri dolje lijevo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Pomjerite dolje desno"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigiranje sistemom je ažurirano. Da izvršite promjene, idite u Postavke."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Idite u Postavke da ažurirate navigiranje sistemom"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/config.xml b/packages/SystemUI/res/values-ca/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ca/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 2f69fc9..23d5d5c 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"No es permet la depuració per USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"L\'usuari que té iniciada la sessió al dispositiu en aquest moment no pot activar la depuració per USB. Per utilitzar aquesta funció, cal canviar a l\'usuari principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"El port USB està desactivat"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Per protegir el teu dispositiu dels líquids o de la pols, el port USB s\'ha desactivat i no detectarà cap accessori.\n\nRebràs una notificació quan puguis tornar a utilitzar-lo."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"S\'ha activat el port USB per detectar carregadors i accessoris"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activa l\'USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Més informació"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom per omplir pantalla"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estira per omplir pant."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"S\'està cercant la teva cara"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Cara autenticada"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmat"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toca Confirma per completar"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor d\'empremtes digitals"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona d\'empremta digital"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"S\'està cercant la teva cara…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"S\'està canviant la xarxa de l\'operador de telefonia mòbil"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Obre els detalls de la bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> per cent de bateria."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> per cent de bateria amb aproximadament <xliff:g id="TIME">%2$s</xliff:g> de temps restant segons l\'ús que en fas"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"La bateria s\'està carregant, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configuració del sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacions."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Fins a l\'alba"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"S\'activarà a les <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Fins a les <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema fosc"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema fosc\nEstalvi de bateria"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema fosc"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema fosc\nEstalvi de bateria"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"L\'NFC està desactivada"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"L\'NFC està activada"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacions menys urgents a continuació"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Torna a tocar per obrir-la."</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Llisca cap amunt per desbloquejar el teclat"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Llisca cap amunt per obrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"La teva organització gestiona aquest dispositiu"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> gestiona aquest dispositiu"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Llisca des de la icona per obrir el telèfon"</string>
@@ -413,10 +413,10 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silenci\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Només\ninterr. prior."</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Només\nalarmes"</string>
-    <string name="keyguard_indication_charging_time_wireless" msgid="6959284458466962592">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant sense fil (temps restant: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
-    <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant (temps restant: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time_wireless" msgid="6959284458466962592">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant sense fil (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> per completar la càrrega)"</string>
+    <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • S\'està carregant (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> per completar la càrrega)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="7767562163577492332">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant ràpidament (temps restant: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
-    <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant lentament (temps restant: <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Carregant lentament (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> per completar la càrrega)"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Canvia d\'usuari"</string>
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Canvia d\'usuari. Usuari actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuari actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -452,16 +452,14 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"S\'ha activat l\'estalvi de bateria"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Redueix el rendiment i l\'ús de les dades en segon pla."</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Desactiva l\'estalvi de bateria"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"Quan graves o emets contingut, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> pot capturar la informació sensible que es mostri a la pantalla o que reprodueixi el dispositiu, com ara àudio, contrasenyes, informació de pagament, fotos i missatges."</string>
-    <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Quan graves o emets contingut, el servei que ofereix aquesta funció pot capturar informació sensible que es mostri a la pantalla o que reprodueixi el dispositiu, com ara àudio, contrasenyes, informació de pagament, fotos i missatges."</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"Quan graves o emets contingut, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> pot capturar la informació sensible que es mostri a la pantalla o que es reprodueixi al dispositiu, com ara àudio, contrasenyes, informació de pagament, fotos i missatges."</string>
+    <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Quan graves o emets contingut, el servei que ofereix aquesta funció pot capturar informació sensible que es mostri a la pantalla o que es reprodueixi al dispositiu, com ara àudio, contrasenyes, informació de pagament, fotos i missatges."</string>
     <string name="media_projection_dialog_title" msgid="8124184308671641248">"Es mostra informació sensible durant l\'emissió o la gravació"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"No ho tornis a mostrar"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Esborra-ho tot"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gestió"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificacions silencioses"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Esborra totes les notificacions silencioses"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificacions pausades pel mode No molestis"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Comença ara"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Cap notificació"</string>
@@ -532,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Configuració del so"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Amplia"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Replega"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Subtítols automàtics"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Subtitula el contingut multimèdia automàticament"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Tanca el consell sobre subtítols"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Superposició de subtítols"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"activar"</string>
@@ -546,7 +544,7 @@
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, mantén premut el botó d\'inici."</string>
     <string name="screen_pinning_toast" msgid="2266705122951934150">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Aplicacions recents"</string>
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Inici"</string>
-    <string name="screen_pinning_positive" msgid="3783985798366751226">"D\'acord"</string>
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"Entesos"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gràcies"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"S\'ha fitxat la pantalla"</string>
     <string name="screen_pinning_exit" msgid="5187339744262325372">"S\'ha deixat de fixar la pantalla"</string>
@@ -610,7 +608,7 @@
     <string name="tuner_warning_title" msgid="7094689930793031682">"Diversió per a uns quants, però no per a tothom"</string>
     <string name="tuner_warning" msgid="8730648121973575701">"El Personalitzador d\'interfície d\'usuari presenta opcions addicionals per canviar i personalitzar la interfície d\'usuari d\'Android. És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
     <string name="tuner_persistent_warning" msgid="8597333795565621795">"És possible que aquestes funcions experimentals canviïn, deixin de funcionar o desapareguin en versions futures. Continua amb precaució."</string>
-    <string name="got_it" msgid="2239653834387972602">"D\'acord"</string>
+    <string name="got_it" msgid="2239653834387972602">"Entesos"</string>
     <string name="tuner_toast" msgid="603429811084428439">"Enhorabona! El Personalitzador d\'interfície d\'usuari s\'ha afegit a Configuració."</string>
     <string name="remove_from_settings" msgid="8389591916603406378">"Treu de Configuració"</string>
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Vols suprimir el Personalitzador d\'interfície d\'usuari de Configuració i deixar d\'utilitzar-ne totes les funcions?"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloqueja"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continua rebent"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimitza"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencioses"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continua silenciant"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertes"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continua avisant-me"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desactiva les notificacions"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discreta"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritàries"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"T\'ajuda a concentrar-te perquè les notificacions només es mostren a l\'àrea desplegable. Sempre en silenci."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Es mostren a sota de les notificacions prioritàries. Sempre silencioses."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Es mostren a sota de les notificacions prioritàries. Sempre silencioses."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Es mostren a sota de les notificacions prioritàries. Sempre silencioses."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Atrauen la teva atenció amb un so i una icona a la barra d\'estat. Es mostren a la pantalla de bloqueig."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silenci"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"T\'ajuda a concentrar-te sense so ni vibració."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Atrau la teva atenció amb so i vibració."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Aquestes notificacions no es poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Aquest grup de notificacions no es pot configurar aquí"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificació mitjançant aplicació intermediària"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Mantén premut i arrossega per afegir mosaics"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Mantén premut i arrossega per reorganitzar els mosaics"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Arrossega aquí per suprimir una funció"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Necessites com a mínim <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mosaics"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Edita"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Hora"</string>
   <string-array name="clock_options">
@@ -909,13 +901,12 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permet"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Denega"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Toca per programar l\'estalvi de bateria"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activa\'l quan sigui probable que et quedis sense bateria"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"No"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"S\'ha activat la programació de l\'estalvi de bateria"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"L\'estalvi de bateria s\'activarà automàticament quan el nivell de bateria sigui inferior al <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="open_saver_setting_action" msgid="8314624730997322529">"Configuració"</string>
-    <string name="auto_saver_okay_action" msgid="2701221740227683650">"D\'acord"</string>
+    <string name="auto_saver_okay_action" msgid="2701221740227683650">"Entesos"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Aboca espai de SysUI"</string>
     <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> està fent servir el següent: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
     <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Algunes aplicacions estan fent servir el següent: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mou a baix a l\'esquerra"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mou a baix a la dreta"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Omet"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"S\'ha actualitzat el sistema de navegació. Per fer canvis, ves a Configuració."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ves a Configuració per actualitzar el sistema de navegació"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/config.xml b/packages/SystemUI/res/values-cs/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-cs/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 9ae4ddf..80c6179 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ladění přes USB není povoleno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Uživatel aktuálně přihlášený k tomuto zařízení nemůže zapnout ladění přes USB. Chcete-li tuto funkci použít, přepněte na primárního uživatele."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB je deaktivován"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Kvůli ochraně vašeho zařízení před tekutinami a nečistotami je port USB zakázán a nerozpozná žádné příslušenství.\n\nAž bude opět bezpečné port USB použít, budeme vás informovat."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB může zjišťovat nabíječky a příslušenství"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktivovat USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Další informace"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Přiblížit na celou obrazovku"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Na celou obrazovku"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snímek obrazovky"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Vyhledávání obličeje"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Obličej byl ověřen"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrzeno"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ověření dokončíte klepnutím na Potvrdit"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotkněte se snímače otisků prstů"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otisku prstu"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hledáme vás…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Probíhá změna sítě operátora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otevřít podrobnosti o baterii"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Stav baterie: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterie je nabitá na <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, při vašem používání vydrží ještě <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Baterie se nabíjí. Nabito: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systémová nastavení."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Oznámení."</string>
@@ -380,8 +380,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do svítání"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Zapnout v <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tmavé téma"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tmavý motiv\nSpořič baterie"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tmavý motiv"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tmavý motiv\nSpořič baterie"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC je vypnuto"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC je zapnuto"</string>
@@ -404,7 +404,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Méně urgentní oznámení níže"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Oznámení otevřete opětovným klepnutím"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Zařízení odemknete přejetím prstem nahoru"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Otevřete přejetím prstem nahoru"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Toto zařízení spravuje vaše organizace"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Toto zařízení je spravováno organizací <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefon otevřete přejetím prstem od ikony"</string>
@@ -464,10 +464,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Tuto zprávu příště nezobrazovat"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Smazat vše"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Spravovat"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tichá oznámení"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Vymazat všechna tichá oznámení"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Oznámení jsou pozastavena režimem Nerušit"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Spustit"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Žádná oznámení"</string>
@@ -538,7 +536,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Nastavení zvuku"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozbalit"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sbalit"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatické titulky k médiím"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatické přepisy médií"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Tip k titulkům"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Překryvná vrstva titulků"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"aktivovat"</string>
@@ -651,21 +649,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokovat"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nadále zobrazovat"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimalizovat"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tiché"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Nadále bez zvuku"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Upozorňovat"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Dál upozorňovat"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Vypnout oznámení"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Mají se oznámení z této aplikace nadále zobrazovat?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Nenápadná"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritní"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Budete se moci lépe soustředit, protože oznámení se budou zobrazovat pouze na vysouvacím panelu. Vždy tichý režim."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Níže zobrazit prioritní oznámení. Vždy tichý režim."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Níže zobrazit prioritní oznámení. Vždy tichý režim."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Níže zobrazit prioritní oznámení. Vždy tichý režim."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Upozorní vás pomocí zvuku a ikony na stavovém řádku. Zobrazit na obrazovce uzamčení."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Ticho"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Upozornění"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomáhá vám soustředit se vypnutím zvuku a vibrací."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Upozorňuje vás pomocí zvuku a vibrací."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tato oznámení nelze upravit."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tuto skupinu oznámení tady nelze nakonfigurovat"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Zprostředkované oznámení"</string>
@@ -796,8 +789,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Dlaždice přidáte podržením a přetažením"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Dlaždice můžete uspořádat podržením a přetažením"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Přetažením sem dlaždice odstraníte"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Potřebujete alespoň tento počet dlaždic: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Upravit"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Čas"</string>
   <string-array name="clock_options">
@@ -919,8 +911,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Povolit"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Zamítnout"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Klepnutím naplánujete aktivování spořiče baterie"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Zapnout, když bude pravděpodobné, že se vybije baterie"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, díky"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Plánované aktivování spořiče baterie je zapnuté"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Spořič baterie se automaticky aktivuje, jakmile baterie klesne pod <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -953,4 +944,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Přesunout vlevo dolů"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Přesunout vpravo dolů"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zavřít"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systémová navigace byla aktualizována. Chcete-li provést změny, přejděte do Nastavení."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Přejděte do Nastavení a aktualizujte systémovou navigaci"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/config.xml b/packages/SystemUI/res/values-da/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-da/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 62b4029..08fb0b3 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-fejlretning er ikke tilladt"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Den bruger, der i øjeblikket er logget ind på denne enhed, kan ikke aktivere USB-fejlretning. Skift til den primære bruger for at bruge denne funktion."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-porten er deaktiveret"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB-porten er blevet deaktiveret for at beskytte din enhed mod væske og snavs. Den kan derfor ikke registrere noget tilbehør.\n\nDu får besked, når du kan bruge USB-porten igen."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-porten er aktiveret for at registrere opladere og tilbehør"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktivér USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Få flere oplysninger"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom til fuld skærm"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Stræk til fuld skærm"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -100,7 +98,7 @@
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Isæt som et kamera (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Installer appen Android Filoverførsel til Mac"</string>
     <string name="accessibility_back" msgid="567011538994429120">"Tilbage"</string>
-    <string name="accessibility_home" msgid="8217216074895377641">"Startskærm"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Hjem"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_accessibility_button" msgid="7601252764577607915">"Hjælpefunktioner"</string>
     <string name="accessibility_rotate_button" msgid="7402949513740253006">"Roter skærmen"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Søger efter dit ansigt"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Ansigtet er godkendt"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bekræftet"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tryk på Bekræft for at udføre"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sæt fingeren på fingeraftrykslæseren"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeraftryk"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Forsøger at finde dig…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Skift af mobilnetværk"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Åbn oplysninger om batteri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batteriniveauet er på <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, så du har ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage, alt efter hvordan du bruger enheden"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteriet oplades. <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systemindstillinger."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifikationer."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Indtil solopgang"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Tænd kl. <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Indtil <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Mørkt tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Mørkt tema\nBatterisparefunktion"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Mørkt tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Mørkt tema\nBatterisparefunktion"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC er deaktiveret"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC er aktiveret"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende notifikationer nedenfor"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tryk igen for at åbne"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Stryg opad for at låse op"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Stryg opad for at åbne"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Denne enhed administreres af din organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Denne enhed administreres af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Stryg fra telefonikonet"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Vis ikke igen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ryd alle"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Administrer"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Lydløse notifikationer"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Ryd alle lydløse notifikationer"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifikationer er sat på pause af Forstyr ikke"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start nu"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ingen notifikationer"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloker"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Fortsæt med at vise notifikationer"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimer"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Lydløs"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Fortsæt med lydløse notifikationer"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Underretninger"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Fortsæt med at underrette"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Deaktiver notifikationer"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vil du fortsætte med at se notifikationer fra denne app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskret"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioriteret"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Hjælper dig med at fokusere på de vigtige ting, da notifikationerne kun vises i panelet, der trækkes ned. Altid lydløs."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Viser notifikationer med lav prioritet. Altid lydløs."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Viser notifikationer med lav prioritet. Altid lydløs."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Viser notifikationer med lav prioritet. Altid lydløs."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Fanger din opmærksomhed med lyd og ikoner i statusbjælken. Vises på låseskærmen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Lydløs"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Underretninger"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ingen lyde eller vibrationer, der forstyrrer dig."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Fanger din opmærksomhed med lyd eller vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Disse notifikationer kan ikke redigeres."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Du kan ikke konfigurere denne gruppe notifikationer her"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxyforbundet notifikation"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Tilføj felter ved at holde dem nede og trække"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Flyt rundt på felterne ved at holde dem nede og trække"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Træk herhen for at fjerne"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Du skal bruge mindst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> felter"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Rediger"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Tid"</string>
   <string-array name="clock_options">
@@ -841,7 +833,7 @@
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimer"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Luk"</string>
     <string name="pip_phone_settings" msgid="8080777499521528521">"Indstillinger"</string>
-    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Træk ned for at afvise"</string>
+    <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Træk ned for at fjerne"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"Menu"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> vises som integreret billede"</string>
     <string name="pip_notification_message" msgid="5619512781514343311">"Hvis du ikke ønsker, at <xliff:g id="NAME">%s</xliff:g> skal benytte denne funktion, kan du åbne indstillingerne og deaktivere den."</string>
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Tillad"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Afvis"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tryk for at fastsætte en tidsplan for batterisparefunktionen"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktivér, når det ser ud til, at batteriet løber tør"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nej tak"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Tidsplanen for batterisparefunktionen er aktiveret"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batterisparefunktionen aktiveres automatisk, når batteriniveauet når under <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Flyt ned til venstre"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Flyt ned til højre"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Afvis"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigationen blev opdateret. Gå til Indstillinger for at foretage ændringer."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gå til Indstillinger for at opdatere systemnavigationen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/config.xml b/packages/SystemUI/res/values-de/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-de/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 475ce6f..408254f 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -26,7 +26,7 @@
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Benachrichtigungen"</string>
     <string name="battery_low_title" msgid="9187898087363540349">"Der Akku ist fast leer"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> verbleibend"</string>
-    <string name="battery_low_percent_format_hybrid" msgid="6838677459286775617">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> ausstehend; noch ca. <xliff:g id="TIME">%2$s</xliff:g>, basierend auf deiner Nutzung"</string>
+    <string name="battery_low_percent_format_hybrid" msgid="6838677459286775617">"Noch <xliff:g id="PERCENTAGE">%1$s</xliff:g> übrig; bei deinem Nutzungsmuster hast du noch ca. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_low_percent_format_hybrid_short" msgid="9025795469949145586">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> ausstehend; noch ca. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_low_percent_format_saver_started" msgid="7879389868952879166">"Noch <xliff:g id="PERCENTAGE">%s</xliff:g>. Der Energiesparmodus ist aktiviert."</string>
     <string name="invalid_charger" msgid="2741987096648693172">"Aufladen über USB nicht möglich. Verwende das mit dem Gerät gelieferte Ladegerät."</string>
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-Debugging nicht zulässig"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Der momentan auf diesem Gerät angemeldete Nutzer kann das USB-Debugging nicht aktivieren. Um diese Funktion verwenden zu können, wechsle zum primären Nutzer."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-Port deaktiviert"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Zum Schutz deines Geräts vor Flüssigkeiten oder Fremdkörpern ist der USB-Port zurzeit deaktiviert und erkennt kein Zubehör.\n\nDu wirst benachrichtigt, wenn der USB-Port wieder verwendet werden kann."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Erkennung von Ladegeräten und Zubehör am USB-Port aktiviert"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB aktivieren"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Weitere Informationen"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom auf Bildschirmgröße"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Auf Bildschirmgröße anpassen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Nach deinem Gesicht wird gesucht"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Gesicht authentifiziert"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bestätigt"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Zum Abschließen auf \"Bestätigen\" tippen"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Berühre den Fingerabdrucksensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerabdruck-Symbol"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Wir suchen nach dir…"</string>
@@ -201,6 +200,7 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
     <skip />
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Akku bei <xliff:g id="PERCENTAGE">%1$s</xliff:g> Prozent. Bei deinem Nutzungsmuster hast du noch Strom für etwa <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
     <skip />
@@ -235,7 +235,7 @@
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Der Flugmodus ist deaktiviert."</string>
     <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Der Flugmodus ist aktiviert."</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"lautlos"</string>
-    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"nur Wecker"</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"nur Weckrufe"</string>
     <string name="accessibility_quick_settings_dnd" msgid="5555155552520665891">"Nicht stören."</string>
     <string name="accessibility_quick_settings_dnd_changed_off" msgid="2757071272328547807">"\"Bitte nicht stören\" deaktiviert."</string>
     <string name="accessibility_quick_settings_dnd_changed_on" msgid="6808220653747701059">"\"Bitte nicht stören\" aktiviert"</string>
@@ -305,7 +305,7 @@
     <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Halte die Symbole gedrückt, um weitere Optionen zu sehen"</string>
     <string name="quick_settings_dnd_label" msgid="7112342227663678739">"Bitte nicht stören"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Nur wichtige Unterbrechungen"</string>
-    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Nur Wecker"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Nur Weckrufe"</string>
     <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Lautlos"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> Geräte)"</string>
@@ -380,8 +380,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Bis Sonnenaufgang"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"An um <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Bis <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Dunkles Design"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Dunkles Design\nEnergiesparmodus"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Dunkles Design"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Dunkles Design\nEnergiesparmodus"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC ist deaktiviert"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ist aktiviert"</string>
@@ -404,7 +404,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Erneut tippen, um Benachrichtigung zu öffnen"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Zum Entsperren nach oben wischen"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Zum Öffnen nach oben wischen"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Dieses Gerät wird von deiner Organisation verwaltet"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Dieses Gerät wird von <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> verwaltet"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Zum Öffnen des Telefons vom Symbol wegwischen"</string>
@@ -413,7 +413,7 @@
     <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Lautlos. Damit werden auch Screenreader stummgeschaltet."</string>
     <string name="interruption_level_none" msgid="6000083681244492992">"Lautlos"</string>
     <string name="interruption_level_priority" msgid="6426766465363855505">"Nur wichtige Unterbrechungen"</string>
-    <string name="interruption_level_alarms" msgid="5226306993448328896">"Nur Wecker"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"Nur Weckrufe"</string>
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Laut-\nlos"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Nur\nwichtige"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Nur\nWecker"</string>
@@ -462,10 +462,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nicht mehr anzeigen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alle löschen"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Verwalten"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Lautlose Benachrichtigungen"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Alle lautlosen Benachrichtigungen löschen"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Benachrichtigungen durch \"Bitte nicht stören\" pausiert"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Jetzt starten"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Keine Benachrichtigungen"</string>
@@ -542,7 +540,7 @@
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"aktivieren"</string>
     <string name="volume_odi_captions_hint_disable" msgid="8980842810619956593">"deaktivieren"</string>
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Ausgabegerät wechseln"</string>
-    <string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string>
+    <string name="screen_pinning_title" msgid="3273740381976175811">"Der Bildschirm ist angpinnt"</string>
     <string name="screen_pinning_description" msgid="8909878447196419623">"Der Bildschirm bleibt so lange eingeblendet, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Übersicht\"."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte dazu \"Zurück\" und \"Startbildschirm\"."</string>
     <string name="screen_pinning_description_gestural" msgid="1191513974909607884">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Dazu wischst du nach oben und hältst den Bildschirm gedrückt"</string>
@@ -552,7 +550,7 @@
     <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Um die Fixierung für diesen Bildschirm aufzuheben, berühre und halte \"Zurück\" und \"Startbildschirm\""</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Ok"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Nein danke"</string>
-    <string name="screen_pinning_start" msgid="1022122128489278317">"Bildschirm fixiert"</string>
+    <string name="screen_pinning_start" msgid="1022122128489278317">"Der Bildschirm ist angepinnt"</string>
     <string name="screen_pinning_exit" msgid="5187339744262325372">"Fixierung für Bildschirm aufgehoben"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ausblenden?"</string>
     <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Sie wird wieder eingeblendet, wenn du sie in den Einstellungen erneut aktivierst."</string>
@@ -599,7 +597,7 @@
     <string name="enable_demo_mode" msgid="4844205668718636518">"Demomodus aktivieren"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"Demomodus anzeigen"</string>
     <string name="status_bar_ethernet" msgid="5044290963549500128">"Ethernet"</string>
-    <string name="status_bar_alarm" msgid="8536256753575881818">"Wecker"</string>
+    <string name="status_bar_alarm" msgid="8536256753575881818">"Weckruf"</string>
     <string name="status_bar_work" msgid="6022553324802866373">"Arbeitsprofil"</string>
     <string name="status_bar_airplane" msgid="7057575501472249002">"Flugmodus"</string>
     <string name="add_tile" msgid="2995389510240786221">"Kachel hinzufügen"</string>
@@ -649,21 +647,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blockieren"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Weiterhin anzeigen"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimieren"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Lautlos"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Weiter lautlos bleiben"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Benachrichtigen"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Weiterhin Benachrichtigungen senden"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Benachrichtigungen deaktivieren"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Benachrichtigungen dieser App weiterhin anzeigen?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Stumm"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorisiert"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Benachrichtigungen erscheinen nur in der Benachrichtigungsleiste. So kannst du dich besser konzentrieren. Immer lautlos."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Erscheinen unter den wichtigen Benachrichtigungen. Immer lautlos."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Erscheinen unter den wichtigen Benachrichtigungen. Immer lautlos."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Erscheinen unter den wichtigen Benachrichtigungen. Immer lautlos."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Benachrichtigungen werden mit einem Ton und einem Statusleistensymbol angekündigt. Erscheinen auf dem Sperrbildschirm."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Lautlos"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Benachrichtigen"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Benachrichtigungen werden ohne Ton oder Vibration angekündigt, um deine Konzentration nicht zu stören."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Benachrichtigungen werden mit einem Ton oder einer Vibration angekündigt, um dich auf sie aufmerksam zu machen."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Diese Benachrichtigungen können nicht geändert werden."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Die Benachrichtigungsgruppe kann hier nicht konfiguriert werden"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Weitergeleitete Benachrichtigung"</string>
@@ -790,8 +783,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Zum Hinzufügen von Kacheln Kachel halten und ziehen"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Zum Verschieben der Kacheln Kachel halten und ziehen"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Zum Entfernen hierher ziehen"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Du brauchst mindestens <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> Kacheln"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Bearbeiten"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Uhrzeit"</string>
   <string-array name="clock_options">
@@ -832,7 +824,7 @@
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Einstellungen öffnen."</string>
     <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Schnelleinstellungen öffnen."</string>
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Schnelleinstellungen schließen."</string>
-    <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"Wecker eingestellt."</string>
+    <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"Weckruf eingerichtet."</string>
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Angemeldet als <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Kein Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Details öffnen."</string>
@@ -913,8 +905,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Zulassen"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Ablehnen"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tippen zum Planen des Energiesparmodus"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktivieren, wenn der Akku wahrscheinlich nicht mehr lange hält"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nein danke"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Geplanter Energiesparmodus aktiviert"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Der Energiesparmodus wird bei einem Akkustand von <xliff:g id="PERCENTAGE">%d</xliff:g> %% automatisch aktiviert."</string>
@@ -947,4 +938,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Nach unten links verschieben"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Nach unten rechts verschieben"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Schließen"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemsteuerungseinstellungen wurden angepasst. Änderungen kannst du in den Einstellungen vornehmen."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gehe zu den Einstellungen, um die Systemsteuerung anzupassen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/config.xml b/packages/SystemUI/res/values-el/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-el/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 5299cf4..0ceef42 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Αναζήτηση για το πρόσωπό σας"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Έγινε έλεγχος ταυτότητας προσώπου"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Επιβεβαιώθηκε"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Πατήστε Επιβεβαίωση για ολοκλήρωση"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Αγγίξτε τον αισθητήρα δακτυλικών αποτυπωμάτων"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Αναζήτηση για εσάς…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Αλλαγή δικτύου εταιρείας κινητής τηλεφωνίας"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Άνοιγμα λεπτομερειών μπαταρίας"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Μπαταρία <xliff:g id="NUMBER">%d</xliff:g> τοις εκατό."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Μπαταρία στο <xliff:g id="PERCENTAGE">%1$s</xliff:g> τοις εκατό. Περίπου <xliff:g id="TIME">%2$s</xliff:g> ακόμη, βάσει της χρήσης σας"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Φόρτιση μπαταρίας, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%% τοις εκατό."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Ρυθμίσεις συστήματος."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ειδοποιήσεις."</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Μέχρι την ανατολή"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Ενεργοποίηση στις <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Έως τις <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Σκούρο θέμα"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Σκούρο θέμα\nΕξοικονόμηση μπαταρίας"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Σκούρο θέμα"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Σκούρο θέμα\nΕξοικονόμηση μπαταρίας"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Το NFC είναι απενεργοποιημένο"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Το NFC είναι ενεργοποιημένο"</string>
@@ -398,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Πατήστε ξανά για να ανοίξετε"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Σύρετε για να ξεκλειδώσετε"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Σύρετε προς τα επάνω για άνοιγμα"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Αυτή η συσκευή είναι διαχειριζόμενη από τον οργανισμό σας"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Τη συσκευή διαχειρίζεται ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Σύρετε προς τα έξω για τηλέφωνο"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Να συνεχιστούν οι ειδοποιήσεις"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Απενεργοποίηση ειδοποιήσεων"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Να συνεχίσουν να εμφανίζονται ειδοποιήσεις από αυτήν την εφαρμογή;"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Διακριτικές"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Προτεραιότητας"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Σας βοηθάει να συγκεντρωθείτε με ειδοποιήσεις που εμφανίζονται μόνο στο αναπτυσσόμενο πλαίσιο σκίασης. Πάντα σε σίγαση."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Εμφανίζεται κάτω από ειδοποιήσεις προτεραιότητας. Πάντα σε σίγαση."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Εμφανίζεται κάτω από ειδοποιήσεις προτεραιότητας. Πάντα σε σίγαση."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Εμφανίζεται κάτω από ειδοποιήσεις προτεραιότητας. Πάντα σε σίγαση."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Τραβάει την προσοχή σας με ήχους και ένα εικονίδιο γραμμής κατάστασης. Εμφανίζεται στην οθόνη κλειδώματος."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Σίγαση"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Ειδοποίηση"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Σας βοηθά να συγκεντρωθείτε χωρίς ήχο και δόνηση."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Τραβά την προσοχή σας με ήχο ή δόνηση."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Δεν είναι δυνατή η τροποποίηση αυτών των ειδοποιήσεων"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Δεν είναι δυνατή η διαμόρφωση αυτής της ομάδας ειδοποιήσεων εδώ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ειδοποίηση μέσω διακομιστή μεσολάβησης"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Μετακίνηση κάτω αριστερά"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Μετακίνηση κάτω δεξιά"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Παράβλεψη"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Η πλοήγηση συστήματος ενημερώθηκε. Για να κάνετε αλλαγές, μεταβείτε στις Ρυθμίσεις."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Μεταβείτε στις Ρυθμίσεις για να ενημερώσετε την πλοήγηση συστήματος"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/config.xml b/packages/SystemUI/res/values-en-rAU/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-en-rAU/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 5d78827..dc661dd 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Looking for your face"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator network changing"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Until sunrise"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"On at <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Until <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Dark Theme"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Dark theme\nBattery saver"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Dark theme"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Dark theme\nBattery Saver"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC is enabled"</string>
@@ -398,8 +400,8 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Swipe up to unlock"</string>
-    <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organization"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Swipe from icon for voice assist"</string>
@@ -528,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Sound settings"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expand"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Collapse"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatically caption media"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatically subtitle media"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Close captions tip"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Captions overlay"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"enable"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Keep alerting"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Turn off notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Gentle"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritised"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helps you focus with notifications only in the pull-down shade. Always silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Gets your attention with sound and a status bar icon. Shows on lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Move bottom left"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Move bottom right"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/config.xml b/packages/SystemUI/res/values-en-rCA/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-en-rCA/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index d09808f..9903cc0 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Looking for your face"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator network changing"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Until sunrise"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"On at <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Until <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Dark Theme"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Dark theme\nBattery saver"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Dark theme"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Dark theme\nBattery Saver"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC is enabled"</string>
@@ -398,8 +400,8 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Swipe up to unlock"</string>
-    <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organization"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Swipe from icon for voice assist"</string>
@@ -528,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Sound settings"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expand"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Collapse"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatically caption media"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatically subtitle media"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Close captions tip"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Captions overlay"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"enable"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Keep alerting"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Turn off notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Gentle"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritised"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helps you focus with notifications only in the pull-down shade. Always silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Gets your attention with sound and a status bar icon. Shows on lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Move bottom left"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Move bottom right"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/config.xml b/packages/SystemUI/res/values-en-rGB/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-en-rGB/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 5d78827..dc661dd 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Looking for your face"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator network changing"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Until sunrise"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"On at <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Until <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Dark Theme"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Dark theme\nBattery saver"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Dark theme"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Dark theme\nBattery Saver"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC is enabled"</string>
@@ -398,8 +400,8 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Swipe up to unlock"</string>
-    <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organization"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Swipe from icon for voice assist"</string>
@@ -528,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Sound settings"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expand"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Collapse"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatically caption media"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatically subtitle media"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Close captions tip"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Captions overlay"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"enable"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Keep alerting"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Turn off notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Gentle"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritised"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helps you focus with notifications only in the pull-down shade. Always silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Gets your attention with sound and a status bar icon. Shows on lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Move bottom left"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Move bottom right"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/config.xml b/packages/SystemUI/res/values-en-rIN/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-en-rIN/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 5d78827..dc661dd 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Looking for your face"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Face authenticated"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmed"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tap Confirm to complete"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touch the fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingerprint icon"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Looking for you…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operator network changing"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Open battery details"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Battery <xliff:g id="PERCENTAGE">%1$s</xliff:g> percentage, about <xliff:g id="TIME">%2$s</xliff:g> left based on your usage"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Battery charging, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> percent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Until sunrise"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"On at <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Until <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Dark Theme"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Dark theme\nBattery saver"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Dark theme"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Dark theme\nBattery Saver"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC is enabled"</string>
@@ -398,8 +400,8 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Swipe up to unlock"</string>
-    <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organization"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string>
+    <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string>
     <string name="voice_hint" msgid="8939888732119726665">"Swipe from icon for voice assist"</string>
@@ -528,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Sound settings"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expand"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Collapse"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatically caption media"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatically subtitle media"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Close captions tip"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Captions overlay"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"enable"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Keep alerting"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Turn off notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Gentle"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritised"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helps you focus with notifications only in the pull-down shade. Always silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Displays below priority notifications. Always silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Gets your attention with sound and a status bar icon. Shows on lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alerting"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helps you focus without sound or vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Gets your attention with sound or vibration."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"These notifications can\'t be modified."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"This group of notifications cannot be configured here"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxied notification"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Move bottom left"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Move bottom right"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"System navigation updated. To make changes, go to Settings."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Go to Settings to update system navigation"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/config.xml b/packages/SystemUI/res/values-en-rXC/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-en-rXC/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 7b922b3..d8c862a 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‎‎Looking for your face‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎Face authenticated‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‎Confirmed‎‏‎‎‏‎"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎Tap Confirm to complete‎‏‎‎‏‎"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‎Touch the fingerprint sensor‎‏‎‎‏‎"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎Fingerprint icon‎‏‎‎‏‎"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‏‎Looking for you…‎‏‎‎‏‎"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎Carrier network changing‎‏‎‎‏‎"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎Open battery details‎‏‎‎‏‎"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎Battery ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%d</xliff:g>‎‏‎‎‏‏‏‎ percent.‎‏‎‎‏‎"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‎‎Battery ‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ percent, about ‎‏‎‎‏‏‎<xliff:g id="TIME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ left based on your usage‎‏‎‎‏‎"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎Battery charging, ‎‏‎‎‏‏‎<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>‎‏‎‎‏‏‏‎ percent.‎‏‎‎‏‎"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‎‎‎System settings.‎‏‎‎‏‎"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‎Notifications.‎‏‎‎‏‎"</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎Until sunrise‎‏‎‎‏‎"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎On at ‎‏‎‎‏‏‎<xliff:g id="TIME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‎Until ‎‏‎‎‏‏‎<xliff:g id="TIME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎Dark Theme‎‏‎‎‏‎"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎Dark Theme‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Battery saver‎‏‎‎‏‎"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎Dark theme‎‏‎‎‏‎"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎Dark theme‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Battery saver‎‏‎‎‏‎"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‎NFC‎‏‎‎‏‎"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎NFC is disabled‎‏‎‎‏‎"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‏‎‏‎‏‏‏‎NFC is enabled‎‏‎‎‏‎"</string>
@@ -398,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎+‎‏‎‎‏‏‎<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎Less urgent notifications below‎‏‎‎‏‎"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎Tap again to open‎‏‎‎‏‎"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‏‏‎‎Swipe up to unlock‎‏‎‎‏‎"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎Swipe up to open‎‏‎‎‏‎"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎This device is managed by your organization‎‏‎‎‏‎"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎This device is managed by ‎‏‎‎‏‏‎<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="phone_hint" msgid="4872890986869209950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‎Swipe from icon for phone‎‏‎‎‏‎"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎Keep alerting‎‏‎‎‏‎"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎Turn off notifications‎‏‎‎‏‎"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎Keep showing notifications from this app?‎‏‎‎‏‎"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎Gentle‎‏‎‎‏‎"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎Prioritized‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‎‎‎Helps you focus with notifications only in the pull-down shade. Always silent.‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎Displays below priority notifications. Always silent.‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎Displays below priority notifications. Always silent.‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎Displays below priority notifications. Always silent.‎‏‎‎‏‎"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎Gets your attention with sound &amp; a status bar icon. Shows on lock screen.‎‏‎‎‏‎"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎Silent‎‏‎‎‏‎"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎Alerting‎‏‎‎‏‎"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎Helps you focus without sound or vibration.‎‏‎‎‏‎"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎Gets your attention with sound or vibration.‎‏‎‎‏‎"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‎‎‏‏‎‎These notifications can\'t be modified.‎‏‎‎‏‎"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎This group of notifications cannot be configured here‎‏‎‎‏‎"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎Proxied notification‎‏‎‎‏‎"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎Move bottom left‎‏‎‎‏‎"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‎Move bottom right‎‏‎‎‏‎"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎Dismiss‎‏‎‎‏‎"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‏‏‏‎‎‎System navigation updated. To make changes, go to Settings.‎‏‎‎‏‎"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎Go to Settings to update system navigation‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/config.xml b/packages/SystemUI/res/values-es-rUS/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-es-rUS/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index ecc3e37..37aae55 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"No tienes permitida la depuración por USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"El usuario al que accediste en este dispositivo no puede activar la depuración por USB. Para usar esta función, debes cambiar al usuario principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Puerto USB inhabilitado"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger tu dispositivo de líquidos o suciedad, el puerto USB está inhabilitado y no detectará ningún accesorio.\n\nTe avisaremos cuando puedas usar el puerto USB de nuevo."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Se habilitó el puerto USB para detectar cargadores y accesorios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Habilitar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Más información"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para ocupar la pantalla"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estirar p/ ocupar la pantalla"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Buscando tu rostro"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Se autenticó el rostro"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmado"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Presiona Confirmar para completarla"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor de huellas digitales"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícono de huella digital"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Autenticando tu rostro…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Cambio de proveedor de red"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalles de la batería"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batería <xliff:g id="NUMBER">%d</xliff:g> por ciento"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batería: <xliff:g id="PERCENTAGE">%1$s</xliff:g> por ciento; tiempo restante: aproximadamente <xliff:g id="TIME">%2$s</xliff:g> en función del uso"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Cargando batería: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configuración del sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
@@ -216,7 +216,7 @@
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string>
     <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Pantalla de notificaciones"</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuración rápida"</string>
-    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla bloqueada"</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla de bloqueo"</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"Configuración"</string>
     <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Recientes"</string>
     <string name="accessibility_desc_work_lock" msgid="4288774420752813383">"Pantalla bloqueada del perfil de trabajo"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hasta el amanecer"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"A la(s) <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Hasta <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema oscuro"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema oscuro\nAhorro de batería"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema oscuro"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema oscuro\nAhorro de batería"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"La tecnología NFC está inhabilitada"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"La tecnología NFC está habilitada"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgentes abajo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Presionar de nuevo para abrir"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Desliza el dedo hacia arriba para desbloquear el teléfono"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Desliza el dedo hacia arriba para abrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Tu organización administra este dispositivo"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> administra este dispositivo"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Desliza el dedo para desbloquear el teléfono."</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"No volver a mostrar"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Administrar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificaciones silenciosas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Borrar todas las notificaciones silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificaciones pausadas por el modo \"No interrumpir\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Comenzar ahora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No hay notificaciones"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Seguir viendo"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencio"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Silenciar notificaciones"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertas"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Seguir recibiendo alertas"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desactivar notificaciones"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discretas"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorizadas"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Te ayuda a concentrarte, ya que las notificaciones se muestran solo como banner desplegable. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Se muestra debajo de las notificaciones de prioridad. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Se muestra debajo de las notificaciones de prioridad. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Se muestra debajo de las notificaciones de prioridad. Siempre en silencio."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Notificaciones que llaman la atención con sonido y un ícono en la barra de estado. Se muestra en la pantalla bloqueada."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silencio"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertas"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Te ayuda a concentrarte sin sonar ni vibrar."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Capta tu atención con sonido o vibración."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"No se pueden modificar estas notificaciones."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"No se puede configurar aquí este grupo de notificaciones"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación almacenada en proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Mantén presionado y arrastra para agregar mosaicos"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Mantén presionado y arrastra para reorganizar los mosaicos"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Arrastra aquí para quitar"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Necesitas al menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tarjetas"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Hora"</string>
   <string-array name="clock_options">
@@ -836,7 +828,7 @@
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir configuración de <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar orden de configuración"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Página <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
-    <string name="tuner_lock_screen" msgid="5755818559638850294">"Pantalla bloqueada"</string>
+    <string name="tuner_lock_screen" msgid="5755818559638850294">"Pantalla de bloqueo"</string>
     <string name="pip_phone_expand" msgid="5889780005575693909">"Expandir"</string>
     <string name="pip_phone_minimize" msgid="1079119422589131792">"Minimizar"</string>
     <string name="pip_phone_close" msgid="8416647892889710330">"Cerrar"</string>
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Rechazar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Presiona para programar el Ahorro de batería"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Actívalo cuando la batería se esté por acabar"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"No, gracias"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Se activó la programación del Ahorro de batería"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"El Ahorro de batería se activará automáticamente cuando quede menos de <xliff:g id="PERCENTAGE">%d</xliff:g>%% de batería."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Ubicar abajo a la izquierda"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Ubicar abajo a la derecha"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Se actualizó el sistema de navegación. Para hacer cambios, ve a Configuración."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ve a Configuración para actualizar la navegación del sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/config.xml b/packages/SystemUI/res/values-es/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-es/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 347390a..bcb25f5 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuración USB no permitida"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"El usuario con el que se ha iniciado sesión en este dispositivo no puede activar la depuración USB. Para utilizar esta función, inicia sesión con la cuenta de usuario principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Puerto USB inhabilitado"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger tu dispositivo de los líquidos y la suciedad, el puerto USB se ha inhabilitado y no detectará ningún accesorio.\n\nRecibirás una notificación cuando puedas volver a usarlo."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Puerto USB habilitado para detectar cargadores y accesorios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Habilitar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Más información"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para ajustar"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Expandir para ajustar"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de pantalla"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Buscando tu cara"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Cara autenticada"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmada"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toca Confirmar para completar la acción"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca el sensor de huellas digitales"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icono de huella digital"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Buscando tu cara…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Cambiando la red del operador"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalles de la batería"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> por ciento de batería"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Queda un <xliff:g id="PERCENTAGE">%1$s</xliff:g> por ciento de batería (<xliff:g id="TIME">%2$s</xliff:g> aproximadamente según tu uso)"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batería cargando (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%)."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Ajustes del sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificaciones"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hasta el amanecer"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Hora: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Hasta las <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema oscuro"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema oscuro\nAhorro de batería"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema oscuro"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema oscuro\nAhorro de batería"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"La conexión NFC está inhabilitada"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"La conexión NFC está habilitada"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgente abajo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toca de nuevo para abrir"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Desliza el dedo hacia arriba para desbloquear"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Desliza el dedo hacia arriba para abrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo está administrado por tu organización"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo está administrado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Desliza desde el icono para abrir el teléfono"</string>
@@ -452,16 +452,14 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"Ahorro de batería activado"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Reduce el rendimiento y los datos en segundo plano"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Desactivar Ahorro de batería"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"Mientras graba o envía contenido, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> puede obtener información sensible que se muestre en la pantalla o que se reproduzca en el dispositivo, como audio, contraseñas, información de pagos, fotos y mensajes."</string>
-    <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Mientras graba o envía contenido, el servicio que ofrece esta función puede obtener información sensible que se muestre en la pantalla o que se reproduzca en el dispositivo, como audio, contraseñas, información de pagos, fotos y mensajes."</string>
-    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Se muestra información sensible durante el envío y la grabación"</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"Mientras grabas o envías contenido, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> puede capturar información sensible que se muestre en la pantalla o que se reproduzca en el dispositivo, como audio, contraseñas, información de pagos, fotos y mensajes."</string>
+    <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Mientras grabas o envías contenido, el servicio que ofrece esta función puede capturar información sensible que se muestre en la pantalla o que se reproduzca en el dispositivo, como audio, contraseñas, información de pagos, fotos y mensajes."</string>
+    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Sobre información sensible durante el envío y la grabación"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"No volver a mostrar"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gestionar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificaciones silenciadas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Borrar todas las notificaciones silenciadas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificaciones pausadas por el modo No molestar"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar ahora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No hay notificaciones"</string>
@@ -532,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Ajustes de sonido"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mostrar"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ocultar"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Subtítulos autom. multimedia"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Transcripción instantánea"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Cerrar las recomendaciones de subtítulos"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Superposición de subtítulos"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"habilitar"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Seguir mostrando"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencio"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Silenciar notificaciones"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertas"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Quiero seguir recibiendo alertas"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desactivar notificaciones"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta aplicación?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discretas"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorizadas"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Las notificaciones solo se muestran en la pantalla desplegable para que puedas concentrarte. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Muestra las notificaciones con prioridad baja. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Muestra las notificaciones con prioridad baja. Siempre en silencio."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Muestra las notificaciones con prioridad baja. Siempre en silencio."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Llama tu atención con sonido y un icono en la barra de estado. Se muestra en la pantalla de bloqueo."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silencio"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertas"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Te ayuda a concentrarte sin sonido ni vibración."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Llama tu atención con sonido o vibración."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Estas notificaciones no se pueden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Este grupo de notificaciones no se puede configurar aquí"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación mediante proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Pulsa y arrastra para añadir funciones"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Mantén pulsado un icono y arrástralo para reubicarlo"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Arrastra aquí para quitar una función"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Necesitas al menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> iconos"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Hora"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Denegar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tocar para programar el modo Ahorro de batería"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activar cuando sea probable que se quede sin batería"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"No, gracias"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Se ha activado la programación del modo Ahorro de batería"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"El modo Ahorro de batería se activará automáticamente cuando quede menos de un <xliff:g id="PERCENTAGE">%d</xliff:g> %% de batería."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover abajo a la izquierda."</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover abajo a la derecha"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Cerrar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ve a Ajustes para actualizar la navegación del sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/config.xml b/packages/SystemUI/res/values-et/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-et/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 427d442..729bba4 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-silumine pole lubatud"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Sellesse seadmesse praegu sisse logitud kasutaja ei saa USB-silumist sisse lülitada. Selle funktsiooni kasutamiseks vahetage peamisele kasutajale."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-port on keelatud"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Selleks et kaitsta teie seadet vedeliku või mustuse eest, on USB-port keelatud ja see ei tuvasta lisatarvikuid.\n\nKui USB-porti tohib taas kasutada, saate selle kohta märguande."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-pordil on lubatud tuvastada laadijaid ja tarvikuid"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Luba USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Lisateave"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Suumi ekraani täitmiseks"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Venita ekraani täitmiseks"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekraanipilt"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Teie näo vaatamine"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Nägu on autenditud"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Kinnitatud"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Lõpuleviimiseks puudutage nuppu Kinnita"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Puudutage sõrmejäljeandurit"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Sõrmejälje ikoon"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Otsitakse teid …"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operaatori võrku muudetakse"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Aku üksikasjade avamine"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Aku: <xliff:g id="NUMBER">%d</xliff:g> protsenti."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Aku protsent <xliff:g id="PERCENTAGE">%1$s</xliff:g>, teie kasutuse põhjal on jäänud ligikaudu <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Akut laetakse (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%)."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Süsteemiseaded"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Märguanded"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Kuni päikesetõusuni"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Sisselülitam. kell <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Kuni <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tume teema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tume teema\nAkusäästja"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tume teema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tume teema\nAkusäästja"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC on keelatud"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC on lubatud"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Vähem kiireloomulised märguanded on allpool"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Avamiseks puudutage uuesti"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Lukustuse tühistamiseks pühkige üles"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Pühkige avamiseks üles"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Seda seadet haldab teie organisatsioon"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Seda seadet haldab <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefoni kasutamiseks pühkige ikoonilt eemale"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ära kuva uuesti"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tühjenda kõik"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Haldamine"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Hääletud märguanded"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Kustuta kõik hääletud märguanded"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Režiim Mitte segada peatas märguanded"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Alusta kohe"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Märguandeid pole"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokeeri"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Jätka kuvamist"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimeeri"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Hääletu"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Kuva helita"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Teavitamine"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Teavita ka edaspidi"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Lülita märguanded välja"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Kas jätkata selle rakenduse märguannete kuvamist?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Leebe"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioriseeritud"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Aitab teil allatõmmatavas menüüs ainult märguannetele keskenduda. Alati vaikne."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Kuvatakse prioriteetsete märguannete all. Alati vaikne."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Kuvatakse prioriteetsete märguannete all. Alati vaikne."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Kuvatakse prioriteetsete märguannete all. Alati vaikne."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Haarab teie tähelepanu heli ja olekuriba ikooni abil. Kuvatakse lukustuskuval."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Hääletu"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Teavitamine"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Aitab teil keskenduda (heli või vibreerimine puudub)."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Haarab heli või vibreerimisega teie tähelepanu."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Neid märguandeid ei saa muuta."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Seda märguannete rühma ei saa siin seadistada"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Puhvriga märguanne"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Paanide lisamiseks hoidke all ja lohistage"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Paanide ümberpaigutamiseks hoidke neid all ja lohistage"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Lohistage eemaldamiseks siia"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Teil on vaja vähemalt <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> paani"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Muutmine"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Kellaaeg"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Luba"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Keela"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Puudutage akusäästja ajastamiseks"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Lülitatakse sisse, kui aku hakkab tühjaks saama"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Tänan, ei"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Automaatne akusäästja on sisse lülitatud"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Kui aku tase langeb alla <xliff:g id="PERCENTAGE">%d</xliff:g>%%, lülitub akusäästja automaatselt sisse."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Teisalda alla vasakule"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Teisalda alla paremale"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Loobu"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Süsteemis navigeerimine on värskendatud. Muutmiseks avage jaotis Seaded."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Süsteemi navigeerimise värskendamiseks avage jaotis Seaded"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/config.xml b/packages/SystemUI/res/values-eu/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-eu/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 4d8db9b..7b2d793 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ez da onartzen USB arazketa"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Gailu honetan saioa hasita duen erabiltzaileak ezin du aktibatu USB arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Desgaitu egin da USB ataka"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB ataka desgaitu egin da gailua likido edo zikinkeriengandik babesteko, eta ez du hautemango osagarririk.\n\nJakinarazpen bat jasoko duzu USB ataka berriz erabiltzeko moduan dagoenean."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB ataka gaitu da kargagailuak eta osagarriak hautemateko"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Gaitu USB ataka"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Lortu informazio gehiago"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Handiagotu pantaila betetzeko"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Luzatu pantaila betetzeko"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Pantaila-argazkia"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Aurpegia bilatzen"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Autentifikatu da aurpegia"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Berretsita"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Amaitzeko, sakatu \"Berretsi\""</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sakatu hatz-marken sentsorea"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Hatz-markaren ikonoa"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Zure bila…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operadorearen sarea aldatzen"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Ireki bateriaren xehetasunak"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateriaren karga: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateriak ehuneko <xliff:g id="PERCENTAGE">%1$s</xliff:g> dauka kargatuta. Zure erabilera kontuan izanda, <xliff:g id="TIME">%2$s</xliff:g> inguru gelditzen zaizkio."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Kargatzen ari da bateria. %% <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> arte kargatu da oraingoz."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemaren ezarpenak."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Jakinarazpenak."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Ilunabarrera arte"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Aktibatze-ordua: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> arte"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Gai iluna"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Gai iluna\nBateria-aurrezlea"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Gai iluna"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Gai iluna\nBateria-aurrezlea"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Desgaituta dago NFC"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Gaituta dago NFC"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Horren premiazkoak ez diren jakinarazpenak daude behean"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Irekitzeko, ukitu berriro"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Desblokeatzeko, pasatu hatza gora"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Pasatu hatza gora irekitzeko"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Zure erakundeak kudeatzen du gailua"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak kudeatzen du gailu hau"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Pasatu hatza ikonotik, telefonoa irekitzeko"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ez erakutsi berriro"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Garbitu guztiak"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Kudeatu"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Soinurik gabeko jakinarazpenak"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Garbitu soinurik gabeko jakinarazpen guztiak"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\"Ez molestatu\" moduak pausatu egin ditu jakinarazpenak"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Hasi"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ez dago jakinarazpenik"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokeatu"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Jarraitu erakusten"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizatu"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Soinurik gabe"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Jarraitu isilik"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertak"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Jarraitu jakinarazpenak bidaltzen"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desaktibatu jakinarazpenak"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Aplikazio honen jakinarazpenak erakusten jarraitzea nahi duzu?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Jakinarazi soinurik gabe"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Lehentasunezkoak"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pantailaren goialdeko goitibeherako barran bakarrik erakusten ditu jakinarazpenak, arretarik gal ez dezazun. Beti isilik."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Lehentasunik ez duten jakinarazpenak erakusten ditu. Beti isilik."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Lehentasunik ez duten jakinarazpenak erakusten ditu. Beti isilik."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Lehentasunik ez duten jakinarazpenak erakusten ditu. Beti isilik."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Arretari dei egiten dio soinua eginda eta egoera-barran ikonoa erakutsita. Pantaila blokeatua agertzen da."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Isila"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Ohartarazlea"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ez du egiten soinu edo dardararik, arretarik gal ez dezazun."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Arreta erakartzen du soinua eta dardara eginda."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Jakinarazpen horiek ezin dira aldatu."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Jakinarazpen talde hau ezin da konfiguratu hemen"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxy bidezko jakinarazpena"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Lauzak gehitzeko, eduki sakatuta eta arrastatu"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Lauzak antolatzeko, eduki sakatuta eta arrastatu"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Kentzeko, arrastatu hona"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> lauza behar dituzu gutxienez"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Editatu"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Ordua"</string>
   <string-array name="clock_options">
@@ -879,7 +871,7 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Memoria"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Aholkuak"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Zuzeneko aplikazioak"</string>
-    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> exekutatzen ari da"</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> abian da"</string>
     <string name="instant_apps_message" msgid="1183313016396018086">"Ezer instalatu gabe ireki da aplikazioa."</string>
     <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Ezer instalatu gabe ireki da aplikazioa. Sakatu informazio gehiago lortzeko."</string>
     <string name="app_info" msgid="6856026610594615344">"Aplikazioari buruzko informazioa"</string>
@@ -896,7 +888,7 @@
     <string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> arte"</string>
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Utzi bere horretan"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ordeztu"</string>
-    <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikazioak exekutatzen ari dira atzeko planoan"</string>
+    <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikazioak abian dira atzeko planoan"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Sakatu bateria eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
     <string name="mobile_data_disable_title" msgid="1068272097382942231">"Datu-konexioa desaktibatu nahi duzu?"</string>
     <string name="mobile_data_disable_message" msgid="4756541658791493506">"<xliff:g id="CARRIER">%s</xliff:g> erabilita ezingo dituzu erabili datuak edo Internet. Wifi-sare baten bidez soilik konektatu ahal izango zara Internetera."</string>
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Baimendu"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Ukatu"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Sakatu bateria-aurrezlea noiz aktibatu antolatzeko"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktibatu aurrezlea bateria agortzeko arriskua dagoenean"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ez"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Bateria-aurrezlea aktibatu da"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Bateria-aurrezlea automatikoki aktibatuko da bateriaren %% <xliff:g id="PERCENTAGE">%d</xliff:g> gelditzen denean."</string>
@@ -933,7 +924,7 @@
     <string name="bubbles_prompt" msgid="8807968030159469710">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren burbuilak erabiltzeko baimena eman nahi duzu?"</string>
     <string name="manage_bubbles_text" msgid="7027739766859191408">"Kudeatu"</string>
     <string name="no_bubbles" msgid="337101288173078247">"Ukatu"</string>
-    <string name="yes_bubbles" msgid="668809525728633841">"Onartu"</string>
+    <string name="yes_bubbles" msgid="668809525728633841">"Baimendu"</string>
     <string name="ask_me_later_bubbles" msgid="2147688438402939029">"Galdetu geroago"</string>
     <string name="bubble_content_description_single" msgid="1184462974339387516">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>)"</string>
     <string name="bubble_content_description_stack" msgid="8666349184095622232">"<xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioaren \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\" jakinarazpena, eta beste <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Eraman behealdera, ezkerretara"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Eraman behealdera, eskuinetara"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Baztertu"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Eguneratu da sistemaren nabigazioa. Aldaketak egiteko, joan Ezarpenak atalera."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistemaren nabigazioa eguneratzeko, joan Ezarpenak atalera"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/config.xml b/packages/SystemUI/res/values-fa/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-fa/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 33bcc13..bbbfe0a 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -62,17 +62,15 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"‏اشکال‌زدایی USB مجاز نیست"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"‏کاربری که درحال حاضر در این دستگاه وارد سیستم شده است نمی‌تواند اشکال‌زدایی USB را روشن کند. برای استفاده از این قابلیت، به کاربر اصلی تغییر وضعیت دهید."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"‏درگاه USB غیرفعال شده است"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"‏برای محافظت از دستگاهتان دربرابر مایعات یا خاکروبه، درگاه USB غیرفعال شده است و هیچ‌کدام از لوازم جانبی را شناسایی نخواهد کرد.\n\nهرزمان که استفاده از درگاه USB امکان‌پذیر باشد، به شما اطلاع داده می‌شود."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"‏درگاه USB برای تشخیص شارژرها و لوازم جانبی فعال شد"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"‏فعال کردن USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"بیشتر بدانید"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"بزرگ‌نمایی برای پر کردن صفحه"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"گسترده کردن برای پر کردن صفحه"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"عکس صفحه‌نمایش"</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"در حال ذخیره عکس صفحه‌نمایش..."</string>
-    <string name="screenshot_saving_title" msgid="8242282144535555697">"در حال ذخیره عکس صفحه‌نمایش..."</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"درحال ذخیره عکس صفحه‌نمایش…"</string>
     <string name="screenshot_saved_title" msgid="5637073968117370753">"عکس صفحه‌نمایش ذخیره شد"</string>
     <string name="screenshot_saved_text" msgid="7574667448002050363">"برای مشاهده عکس صفحه‌نمایشتان ضربه بزنید"</string>
     <string name="screenshot_failed_title" msgid="7612509838919089748">"عکس صفحه‌نمایش ذخیره نشد"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"درحال جستجوی چهره"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"چهره احراز هویت شد"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"تأیید شد"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"برای تکمیل، روی تأیید ضربه بزنید"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"حسگر اثر انگشت را لمس کنید"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"نماد اثر انگشت"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"درحال جستجوی شما…"</string>
@@ -153,9 +152,9 @@
     <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"به <xliff:g id="BLUETOOTH">%s</xliff:g> متصل شد."</string>
     <string name="accessibility_cast_name" msgid="4026393061247081201">"متصل به <xliff:g id="CAST">%s</xliff:g>."</string>
     <string name="accessibility_no_wimax" msgid="4329180129727630368">"‏WiMAX وجود ندارد."</string>
-    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"‏WiMAX دارای یک نوار است."</string>
-    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"‏WiMAX دارای دو نوار است."</string>
-    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"‏WiMAX دارای سه نوار است."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"‏WiMAX یک نوار دارد."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"‏WiMAX دو نوار دارد."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"‏WiMAX سه نوار دارد."</string>
     <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"‏قدرت سیگنال WiMAX کامل است."</string>
     <string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"اترنت قطع شد."</string>
     <string name="accessibility_ethernet_connected" msgid="2692130313069182636">"اترنت متصل شد."</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"تغییر شبکه شرکت مخابراتی"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"باز کردن جزئیات باتری"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"باتری <xliff:g id="NUMBER">%d</xliff:g> درصد."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"باتری <xliff:g id="PERCENTAGE">%1$s</xliff:g> درصد شارژ دارد، براساس مصرفتان تقریباً <xliff:g id="TIME">%2$s</xliff:g> شارژ باقی‌مانده است"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"در حال شارژ باتری، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> درصد"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"تنظیمات سیستم."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"اعلان‌ها."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"تا طلوع"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"ساعت <xliff:g id="TIME">%s</xliff:g> روشن می‌شود"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"تا <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"طرح زمینه تیره"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"طرح زمینه تیره\nبهینه‌سازی باتری"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"طرح زمینه تیره"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"طرح زمینه تیره\nبهینه‌سازی باتری"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"‏NFC غیرفعال است"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"‏NFC فعال است"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"اعلان‌های کمتر فوری در زیر"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"دوباره ضربه بزنید تا باز شود"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"برای باز کردن قفل سریع به بالا بکشید"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"برای باز کردن، انگشتتان را تند به بالا بکشید"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"سازمان شما این دستگاه را مدیریت می‌کند"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"این دستگاه توسط <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> مدیریت می‌شود"</string>
     <string name="phone_hint" msgid="4872890986869209950">"انگشتتان را از نماد تلفن تند بکشید"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"دوباره نشان داده نشود"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"پاک کردن همه موارد"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"مدیریت"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"اعلان‌های بی‌صدا"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"پاک کردن همه اعلان‌های بی‌صدا"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"اعلان‌ها توسط «مزاحم نشوید» موقتاً متوقف شدند"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"اکنون شروع شود"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"اعلانی موجود نیست"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"مسدود کردن"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"همچنان نشان داده شود"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"کوچک کردن"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"بی‌صدا"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"بی‌صدا بماند"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"هشدار دادن"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"همچنان اطلاع داده شود"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"خاموش کردن اعلان‌ها"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"نمایش اعلان از این برنامه ادامه یابد؟"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"آرام"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"دراولویت"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"با فقط نمایش اعلان در کشوی اعلان‌های پایین‌کش، به شما کمک می‌کند تمرکزتان را ازدست ندهید همیشه بی‌صدا."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"اعلان‌های با اولویت پایین را نشان می‌دهد. همیشه بی‌صدا."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"اعلان‌های با اولویت پایین را نشان می‌دهد. همیشه بی‌صدا."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"اعلان‌های با اولویت پایین را نشان می‌دهد. همیشه بی‌صدا."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"با صدا و نماد نوار وضعیت توجه شما را جلب می‌کند. در صفحه قفل نشان داده می‌شود."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"بی‌صدا"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"هشدار دادن"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"به شما کمک می‌کند بدون صدا یا لرزش تمرکز کنید."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"با صدا یا لرزش توجه شما را جلب می‌کند."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"این اعلان‌ها قابل اصلاح نیستند."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"نمی‌توانید این گروه اعلان‌ها را در اینجا پیکربندی کنید"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"اعلان‌های دارای پراکسی"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"برای افزودن کاشی، نگه دارید و بکشید"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"برای تغییر دادن ترتیب کاشی‌ها، آن‌ها را نگه دارید و بکشید"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"برای حذف، به اینجا بکشید"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"حداقل به <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> کاشی نیاز دارید"</string>
     <string name="qs_edit" msgid="2232596095725105230">"ویرایش"</string>
     <string name="tuner_time" msgid="6572217313285536011">"زمان"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"مجاز"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"رد کردن"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"برای زمان‌بندی «بهینه‌سازی باتری» ضربه بزنید"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"وقتی باتری روبه‌اتمام است، بهینه‌سازی باتری را روشن کنید"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"نه متشکرم"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"زمان‌بندی «بهینه‌سازی باتری» روشن شد"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"وقتی شارژ باتری به زیر <xliff:g id="PERCENTAGE">%d</xliff:g>%% برسد، «بهینه‌سازی باتری» به‌طور خودکار روشن می‌شود."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"انتقال به پایین سمت راست"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"انتقال به پایین سمت چپ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"رد کردن"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"پیمایش سیستم به‌روزرسانی شد. برای انجام تغییرات به «تنظیمات» بروید."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"برای به‌روزرسانی پیمایش سیستم، به «تنظیمات» بروید"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/config.xml b/packages/SystemUI/res/values-fi/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-fi/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index bd1ae0f..2a4f70e 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-vianetsintää ei sallita"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Laitteelle tällä hetkellä kirjautunut käyttäjä ei voi ottaa USB-vianetsintää käyttöön. Vaihda käyttäjäksi ensisijainen käyttäjä, jotta voit käyttää tätä ominaisuutta."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-portti poistettu käytöstä"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Laitteen suojaamiseksi nesteiltä ja lialta USB-portti on poistettu käytöstä, eikä se havaitse lisävarusteita.\n\nSaat ilmoituksen, kun USB-porttia voi taas käyttää."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-portti on käytössä ja voi havaita latureita sekä lisävarusteita"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Ota USB käyttöön"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Lue lisää"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoomaa koko näyttöön"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Venytä koko näyttöön"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Kuvakaappaus"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Kasvojasi katsotaan"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Kasvot tunnistettu"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Vahvistettu"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Valitse lopuksi Vahvista"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Kosketa sormenjälkitunnistinta"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Sormenjälkikuvake"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Etsitään kasvoja…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operaattorin verkko muuttuu"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Avaa akun tiedot."</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Akun virta <xliff:g id="NUMBER">%d</xliff:g> prosenttia."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Akkua jäljellä <xliff:g id="PERCENTAGE">%1$s</xliff:g> prosenttia eli noin <xliff:g id="TIME">%2$s</xliff:g> käyttösi perusteella"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Akku latautuu: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> prosenttia"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Järjestelmän asetukset"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ilmoitukset"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Auringonnousuun"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Käyttöön klo <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> saakka"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tumma teema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tumma teema\nVirransäästö"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tumma teema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tumma teema\nVirransäästö"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC on poistettu käytöstä"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC on käytössä"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Vähemmän kiireelliset ilmoitukset ovat alla"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Avaa napauttamalla uudelleen"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Avaa lukitus pyyhkäisemällä ylös"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Avaa pyyhkäisemällä ylös"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Organisaatiosi hallinnoi laitetta"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Tätä laitetta hallinnoi <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
     <string name="phone_hint" msgid="4872890986869209950">"Avaa puhelu pyyhkäisemällä."</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Älä näytä uudelleen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Poista kaikki"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Muuta asetuksia"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Hiljaiset ilmoitukset"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Tyhjennä kaikki hiljaiset ilmoitukset"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Älä häiritse ‑tila keskeytti ilmoitukset"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Aloita nyt"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ei ilmoituksia"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Estä"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Jatka näyttämistä"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Pienennä"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Äänetön"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Jatka äänettömyyttä"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Hälyttää"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Jatka ilmoituksista hälyttämistä"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Poista ilmoitukset käytöstä"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Jatketaanko ilmoitusten näyttämistä tästä sovelluksesta?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Varovainen"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorisoitu"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Keskittyminen on helpompaa, sillä ilmoitukset näkyvät vain alas vedettävällä alueella. Aina äänetön."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Näytetään priorisoitujen ilmoitusten alapuolella. Aina äänetön."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Näytetään priorisoitujen ilmoitusten alapuolella. Aina äänetön."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Näytetään priorisoitujen ilmoitusten alapuolella. Aina äänetön."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Kiinnittää huomion äänellä ja tilapalkin kuvakkeella. Näkyy lukitusnäytöllä."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Äänetön"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Hälyttää"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Keskittyminen on helpompaa ilman ääntä tai värinää."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kiinnittää huomion äänellä tai värinällä"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Näitä ilmoituksia ei voi muokata"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tätä ilmoitusryhmää ei voi määrittää tässä"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Välitetty ilmoitus"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Lisää osioita koskettamalla pitkään ja vetämällä"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Järjestele osioita koskettamalla pitkään ja vetämällä"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Poista vetämällä tähän."</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kiekkoa on vähimmäismäärä"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Muokkaa"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Aika"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Salli"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Estä"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Ajoita virransäästö napauttamalla"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ota käyttöön, jos akku todennäköisesti loppuu"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ei kiitos"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Virransäästön ajoitus otettu käyttöön"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Virransäästö käynnistyy automaattisesti, kun akun lataustaso on alle <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Siirrä vasempaan alareunaan"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Siirrä oikeaan alareunaan"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ohita"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Järjestelmän navigointitapa vaihdettu. Voit muuttaa sitä asetuksista."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Vaihda järjestelmän navigointitapaa asetuksista"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/config.xml b/packages/SystemUI/res/values-fr-rCA/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-fr-rCA/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 419666f..a3069a1 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Débogage USB non autorisé"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage USB. Pour utiliser cette fonctionnalité, l\'utilisateur principal doit se connecter."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Le port USB a été désactivé"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Pour protéger votre appareil des liquides et des débris, le port USB est désactivé et ne pourra pas détecter les accessoires.\n\nVous verrez une notification lorsque vous pourrez utiliser le port USB à nouveau."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Le port USB a été activé afin de détecté les chargeurs et les accessoires"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activer l\'USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"En savoir plus"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoomer pour remplir l\'écran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Étirer pour remplir l\'écran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Capture d\'écran"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"L\'appareil recherche votre visage…"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Visage authentifié"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmé"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Touchez Confirmer pour terminer"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Touchez le capteur d\'empreintes digitales"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icône d\'empreinte digitale"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Recherche de votre visage…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Changer de réseau de fournisseur de services"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Ouvrir les détails de la pile"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Pile : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Pile chargée à <xliff:g id="PERCENTAGE">%1$s</xliff:g> pour cent (environ <xliff:g id="TIME">%2$s</xliff:g> d\'autonomie en fonction de votre usage)"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"La pile est en cours de charge : <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Jusqu\'au lev. soleil"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Actif à <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Thème sombre"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Thème sombre\nÉconomiseur de pile"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Thème sombre"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Thème sombre\nÉconomiseur de pile"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC désactivée"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC activée"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes affichées ci-dessous"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Touchez à nouveau pour ouvrir"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Glissez vers le haut pour déverrouiller"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Balayez l\'écran vers le haut pour ouvrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Cet appareil est géré par votre organisation"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Balayez à partir de l\'icône pour accéder au téléphone"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne plus afficher"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tout effacer"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gérer"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notifications silencieuses"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Effacer toutes les notifications silencieuses"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Les notifications sont suspendues par le mode Ne pas déranger"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Commencer"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Aucune notification"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquer"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuer à afficher"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Réduire"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Mode silencieux"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuer d\'util. mode silencieux"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertes"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuer d\'envoyer des alertes"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Désactiver les notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer à afficher les notifications de cette application?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discrètes"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorisées"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Vous aide à vous concentrer en affichant seulement les notifications dans le volet déroulant. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Attire votre attention à l\'aide de sons et d\'une icône dans la barre d\'état. S\'affiche sur l\'écran de verrouillage."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Mode silencieux"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Vous aider à vous concentrer, sans son ni vibration."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Attire votre attention à l\'aide de sons et de vibrations."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ces notifications ne peuvent pas être modifiées"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ce groupe de notifications ne peut pas être configuré ici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notification par mandataire"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Maint. doigt sur écran, puis glissez-le pour ajouter tuiles"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Maint. doigt sur l\'écran, puis glissez-le pour réorg. tuiles"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Faites glisser les tuiles ici pour les supprimer"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Vous avez besoin d\'au moins <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tuiles"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Modifier"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Heure"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Autoriser"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Refuser"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Toucher pour activer la fonction Économie d\'énergie"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activer si la pile est susceptible de s\'épuiser totalement"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Non merci"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"La fonction Économie d\'énergie est activée"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"La fonction Économie d\'énergie s\'activera automatiquement une fois que la pile sera en dessous de <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Déplacer dans coin inf. gauche"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Déplacer dans coin inf. droit"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Fermer"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"La navigation système a été mise à jour. Pour apporter des modifications, accédez au menu Paramètres."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accédez au menu Paramètres pour mettre à jour la navigation système"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/config.xml b/packages/SystemUI/res/values-fr/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-fr/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 2913f66..75a76ae 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -24,7 +24,7 @@
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Aucune notification"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"En cours"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notifications"</string>
-    <string name="battery_low_title" msgid="9187898087363540349">"Il est possible que vous soyez bientôt à court de batterie"</string>
+    <string name="battery_low_title" msgid="9187898087363540349">"La batterie est bientôt épuisée"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> restants"</string>
     <string name="battery_low_percent_format_hybrid" msgid="6838677459286775617">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_low_percent_format_hybrid_short" msgid="9025795469949145586">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – Temps restant : environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -62,19 +62,17 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Débogage USB non autorisé"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"L\'utilisateur actuellement connecté sur cet appareil ne peut pas activer le débogage USB. Pour utiliser cette fonctionnalité, l\'utilisateur principal doit se connecter."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB désactivé"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Pour protéger votre appareil des liquides et des saletés, le port USB est désactivé et ne détecte plus les accessoires.\n\nVous recevrez une notification lorsque vous pourrez de nouveau utiliser le port USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB activé pour détecter les chargeurs et les accessoires"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activer le port USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"En savoir plus"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoomer pour remplir l\'écran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Étirer pour remplir l\'écran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Capture"</string>
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Enregistrement capture écran…"</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Enregistrement de la capture d\'écran…"</string>
     <string name="screenshot_saved_title" msgid="5637073968117370753">"Capture d\'écran enregistrée"</string>
-    <string name="screenshot_saved_text" msgid="7574667448002050363">"Appuyez pour afficher votre capture d\'écran"</string>
+    <string name="screenshot_saved_text" msgid="7574667448002050363">"Appuyez pour voir la capture d\'écran"</string>
     <string name="screenshot_failed_title" msgid="7612509838919089748">"Impossible d\'enregistrer la capture d\'écran"</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Essayez de nouveau de faire une capture d\'écran"</string>
     <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Impossible d\'enregistrer la capture d\'écran, car l\'espace de stockage est limité"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Recherche de votre visage…"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Visage authentifié"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmé"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Appuyez sur \"Confirmer\" pour terminer"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Appuyez sur le lecteur d\'empreinte digitale"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icône d\'empreinte digitale"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Recherche de votre visage…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Modification du réseau de l\'opérateur"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Ouvrir les détails de la batterie"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batterie : <xliff:g id="NUMBER">%d</xliff:g> pour cent"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batterie chargée à <xliff:g id="PERCENTAGE">%1$s</xliff:g> pour cent : il reste environ <xliff:g id="TIME">%2$s</xliff:g> d\'autonomie, selon votre utilisation"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batterie en charge : <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Paramètres système"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Jusqu\'à l\'aube"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"À partir de <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Jusqu\'à <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Thème foncé"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Thème foncé\nÉconomiseur de batterie"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Thème sombre"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Thème foncé\nÉconomiseur de batterie"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"La technologie NFC est désactivée"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"La technologie NFC est activée"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes ci-dessous"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Appuyer à nouveau pour ouvrir"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Faire glisser pour déverrouiller"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Balayer vers le haut pour ouvrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Cet appareil est géré par votre entreprise"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Balayer pour téléphoner"</string>
@@ -413,7 +413,7 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Aucune\ninterruption"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Priorité\nuniquement"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Alarmes\nuniquement"</string>
-    <string name="keyguard_indication_charging_time_wireless" msgid="6959284458466962592">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge sans fil (à 100 % dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time_wireless" msgid="6959284458466962592">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge sans fil (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge... (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_fast" msgid="7767562163577492332">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge rapide… (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
     <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Recharge lente… (à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g>)"</string>
@@ -452,16 +452,14 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"Économiseur de batterie activé"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Limite les performances et les données en arrière-plan."</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Désactiver l\'économiseur de batterie"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"Pendant que vous enregistrez ou diffusez du contenu, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> peut capturer des informations sensibles affichées à l\'écran ou lues par votre appareil, y compris des contenus audio, des mots de passe, des informations de paiement, des photos et des messages."</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"Pendant que vous enregistrez ou diffusez du contenu, l\'appli <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> peut capturer des informations sensibles affichées à l\'écran ou lues par votre appareil, y compris des contenus audio, des mots de passe, des informations de paiement, des photos et des messages."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Pendant que vous enregistrez ou diffusez du contenu, le service concerné peut capturer des informations sensibles affichées à l\'écran ou lues par votre appareil, y compris des contenus audio, des mots de passe, des informations de paiement, des photos et des messages."</string>
-    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Exposition d\'informations sensibles lors de l\'enregistrement ou de la diffusion de contenu"</string>
+    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Présence d\'informations sensibles lors de l\'enregistrement ou de la diffusion de contenu"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne plus afficher"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tout effacer"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gérer"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notifications silencieuses"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Effacer toutes les notifications silencieuses"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications suspendues par le mode Ne pas déranger"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Commencer"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Aucune notification"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquer"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuer d\'afficher les notifications"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Réduire"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Mode silencieux"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Notifications silencieuses"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertes"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuer de m\'avertir"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Désactiver les notifications"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer d\'afficher les notifications de cette application ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discret"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritaire"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Vous aide à vous concentrer en affichant les notifications seulement dans le volet déroulant. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"S\'affiche sous les notifications prioritaires. Toujours silencieux."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Attire votre attention à l\'aide d\'un son et d\'une icône dans la barre d\'état. S\'affiche sur l\'écran de verrouillage."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silencieux"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertes"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Sans sons ni vibrations, vous aide à vous concentrer."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Attire votre attention à l\'aide de sons ou de vibrations."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Impossible de modifier ces notifications."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Vous ne pouvez pas configurer ce groupe de notifications ici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notification de proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Sélectionnez et faites glisser les icônes pour les ajouter"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Sélectionnez et faites glisser les icônes pour réorganiser"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Faites glisser les tuiles ici pour les supprimer."</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Au minimum <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tuiles sont nécessaires"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Modifier"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Heure"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Autoriser"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Refuser"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Appuyez ici pour programmer l\'économiseur de batterie"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activer l\'économiseur de batterie si l\'autonomie restante risque d\'être insuffisante"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Non, merci"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Programmation de l\'économiseur de batterie activée"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"L\'économiseur de batterie s\'active automatiquement lorsque l\'autonomie de la batterie est inférieure à <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Déplacer en bas à gauche"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Déplacer en bas à droite"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorer"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigation système mise à jour. Pour apporter des modifications, accédez aux paramètres."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accédez aux paramètres pour mettre à jour la navigation système"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/config.xml b/packages/SystemUI/res/values-gl/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-gl/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 3c232a1..3268ed0 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Non se permite a depuración por USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"O usuario coa sesión iniciada actualmente neste dispositivo non pode activar a depuración por USB. Para utilizar esta función, cambia ao usuario principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"O porto USB está desactivado"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para protexer o dispositivo de líquidos ou residuos, desactivouse o porto USB e non detectará ningún accesorio.\n\nRecibirás unha notificación cando o poidas utilizar de novo."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Activouse o porto USB para detectar cargadores e accesorios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Máis información"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Ampliar ata ocupar todo"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Estirar ata ocupar todo"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Capt. pantalla"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Buscando a túa cara"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Autenticouse a cara"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmada"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toca Confirmar para completar o proceso"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toca o sensor de impresión dixital"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona de impresión dixital"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Buscándote…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Cambio de rede do operador"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir os detalles da batería"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Carga da batería: <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batería: <xliff:g id="PERCENTAGE">%1$s</xliff:g> por cento, durará <xliff:g id="TIME">%2$s</xliff:g> co uso que adoitas darlle"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"A batería está cargando. Nivel: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configuración do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificacións"</string>
@@ -214,7 +214,7 @@
     <!-- no translation found for accessibility_work_mode (702887484664647430) -->
     <skip />
     <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación rexeitada"</string>
-    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Sombra de notificación"</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Panel despregable"</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuración rápida"</string>
     <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla de bloqueo."</string>
     <string name="accessibility_desc_settings" msgid="3417884241751434521">"Configuración"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Ata o amencer"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Desde: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Ata: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema escuro"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema escuro\nAforro de batería"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema escuro"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema escuro\nAforro de batería"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"A opción NFC está desactivada"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"A opción NFC está activada"</string>
@@ -391,7 +391,7 @@
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"É posible que se\nsupervise a rede"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Pasa o dedo cara arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
-    <string name="description_direction_left" msgid="7207478719805562165">"Pasa o dedo cara a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Pasa o dedo cara á esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
     <string name="zen_priority_introduction" msgid="1149025108714420281">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas, recordatorios, eventos e os emisores de chamada especificados. Seguirás escoitando todo aquilo que decidas reproducir, mesmo a música, os vídeos e os xogos."</string>
     <string name="zen_alarms_introduction" msgid="4934328096749380201">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas. Seguirás escoitando todo aquilo que decidas reproducir, mesmo a música, os vídeos e os xogos."</string>
     <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacións menos urxentes abaixo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toca de novo para abrir"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Pasa o dedo cara arriba para desbloquear"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Pasa o dedo cara arriba para abrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo está xestionado pola túa organización"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo está xestionado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Pasa o dedo desde a icona para acceder ao teléfono"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Non mostrar outra vez"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Eliminar todas"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Xestionar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificacións silenciadas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Borra todas as notificacións silenciadas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"O modo Non molestar puxo en pausa as notificacións"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Non hai notificacións"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando notificacións"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencio"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Notificacións silenciosas"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertando"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar recibindo notificacións"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desactivar notificacións"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Queres seguir mostrando as notificacións desta aplicación?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discretas"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritarias"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Permíteche centrarte con notificacións só no panel despregable. Sempre en silencio."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Mostra as notificacións con prioridade baixa. Sempre en silencio."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Mostra as notificacións con prioridade baixa. Sempre en silencio."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Mostra as notificacións con prioridade baixa. Sempre en silencio."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Chama a túa atención cun son e cunha icona na barra de estado. Móstrase na pantalla de bloqueo."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosas"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Con alertas"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Axúdache a centrarte sen son nin vibración."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama a túa atención con son ou vibración."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Estas notificacións non se poden modificar."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Aquí non se pode configurar este grupo de notificacións"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificación mediante proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Mantén premido un elemento e arrástrao para engadir atallos"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Para reorganizar os atallos, mantenos premidos e arrástraos"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Arrastra o elemento ata aquí para eliminalo"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Como mínimo ten que haber <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mosaicos"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Hora"</string>
   <string-array name="clock_options">
@@ -902,15 +894,14 @@
     <string name="mobile_data_disable_message" msgid="4756541658791493506">"Non terás acceso aos datos nin a Internet a través de <xliff:g id="CARRIER">%s</xliff:g>. Internet só estará dispoñible mediante a wifi."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6078110473451946831">"o teu operador"</string>
     <string name="touch_filtered_warning" msgid="8671693809204767551">"Dado que unha aplicación se superpón sobre unha solicitude de permiso, a configuración non pode verificar a túa resposta."</string>
-    <string name="slice_permission_title" msgid="7465009437851044444">"Queres permitir que a aplicación <xliff:g id="APP_0">%1$s</xliff:g> mostre partes de <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
+    <string name="slice_permission_title" msgid="7465009437851044444">"Queres permitir que <xliff:g id="APP_0">%1$s</xliff:g> mostre fragmentos de aplicación de <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
     <string name="slice_permission_text_1" msgid="3514586565609596523">"- Pode ler información da aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="slice_permission_text_2" msgid="3146758297471143723">"- Pode levar a cabo accións dentro da aplicación <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="slice_permission_checkbox" msgid="7986504458640562900">"Permitir que a aplicación <xliff:g id="APP">%1$s</xliff:g> mostre partes de calquera aplicación"</string>
+    <string name="slice_permission_checkbox" msgid="7986504458640562900">"Permitir que <xliff:g id="APP">%1$s</xliff:g> mostre fragmentos de calquera aplicación"</string>
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Denegar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tocar para programar a función Aforro de batería"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Activa a función se prevés que a batería pode esgotarse"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Non, grazas"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Activouse o programa da función Aforro de batería"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Activarase automaticamente a función Aforro de batería en canto o nivel de carga sexa inferior ao <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover á parte infer. esquerda"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover á parte inferior dereita"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Actualizouse a navegación do sistema. Para facer cambios, vai a Configuración."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Para actualizar a navegación do sistema, vai a Configuración"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/config.xml b/packages/SystemUI/res/values-gu/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-gu/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index baf2fc4..7a1994a 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ડીબગિંગની મંજૂરી નથી"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"હાલમાં આ ઉપકરણમાં સાઇન ઇન થયેલ વપરાશકર્તા USB ડિબગીંગ ચાલુ કરી શકતા નથી. આ સુવિધાનો ઉપયોગ કરવા માટે પ્રાથમિક વપરાશકર્તા પર સ્વિચ કરો."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB પોર્ટ બંધ કરવામાં આવ્યો છે"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"પ્રવાહી અથવા ધૂળથી તમારા ડિવાઇસનું રક્ષણ કરવા માટે, USB પોર્ટ બંધ કરવામાં આવ્યો છે અને કોઈ ઍક્સેસરી શોધશે નહીં.\n\nજ્યારે ફરીથી USB પોર્ટને ઉપયોગમાં લેવાનું સુરક્ષિત હશે ત્યારે તમને નોટિફિકેશન આપવામાં આવશે."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ચાર્જર અને ઍક્સેસરીની ઓળખ માટે USB પોર્ટ ચાલુ કર્યું"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB ચાલુ કરો"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"વધુ જાણો"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"સ્ક્રીન ભરવા માટે ઝૂમ કરો"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"સ્ક્રીન ભરવા માટે ખેંચો"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"સ્ક્રીનશૉટ"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"તમારો ચહેરો શોધી રહ્યાં છીએ"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"ચહેરાનું પ્રમાણીકરણ થયું"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"પુષ્ટિ કરી"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"પરીક્ષણ પૂર્ણ કરવા કન્ફર્મ કરોને ટૅપ કરો"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ફિંગરપ્રિન્ટના સેન્સરને સ્પર્શ કરો"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ફિંગરપ્રિન્ટનું આઇકન"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"તમારા માટે શોધી રહ્યાં છે..."</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"કૅરીઅર નેટવર્કમાં ફેરફાર થઈ રહ્યો છે"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"બૅટરીની વિગતો ખોલો"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"બૅટરી <xliff:g id="NUMBER">%d</xliff:g> ટકા."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"તમારા વપરાશના આધારે બૅટરી <xliff:g id="PERCENTAGE">%1$s</xliff:g> ટકા, જે લગભગ <xliff:g id="TIME">%2$s</xliff:g> સુધી ચાલે તેટલી બચી છે"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"બૅટરી ચાર્જ થઈ રહી છે, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"સિસ્ટમ સેટિંગ્સ."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"નોટિફિકેશનો."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"સૂર્યોદય સુધી"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> વાગ્યે"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> સુધી"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ઘેરી થીમ"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ઘેરી થીમ\nબૅટરી સેવર"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ઘેરી થીમ"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ઘેરી થીમ\nબૅટરી સેવર"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC અક્ષમ કરેલ છે"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC સક્ષમ કરેલ છે"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"નીચે ઓછી તાકીદની સૂચનાઓ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ખોલવા માટે ફરીથી ટૅપ કરો"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"અનલૉક કરવા માટે ઉપર સ્વાઇપ કરો"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"આ ઉપકરણ તમારી સંસ્થા દ્વારા સંચાલિત છે"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"આ ઉપકરણ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> દ્વારા સંચાલિત થાય છે"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ફોન માટે આયકનમાંથી સ્વાઇપ કરો"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ફરીથી બતાવશો નહીં"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"બધુ સાફ કરો"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"મેનેજ કરો"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"સાઇલન્ટ નોટિફિકેશન"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"બધા સાઇલન્ટ નોટિફિકેશન સાફ કરો"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"ખલેલ પાડશો નહીં દ્વારા થોભાવેલ નોટિફિકેશન"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"હવે પ્રારંભ કરો"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"કોઈ સૂચનાઓ નથી"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"બ્લૉક કરો"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"બતાવવાનું ચાલુ રાખો"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"નાનું કરો"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"સાઇલન્ટ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"સાઇલન્ટ મોડ ચાલુ રાખો"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"અલર્ટ કરતા રહો"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"અલર્ટ કરવાનું ચાલુ રાખો"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"નોટિફિકેશન બંધ કરો"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"આ ઍપમાંથી નોટિફિકેશન બતાવવાનું ચાલુ રાખીએ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"સામાન્ય નોટિફિકેશન"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"મહત્ત્વના નોટિફિકેશન"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"નીચે દેખાતા શેડમાં માત્ર નોટિફિકેશન પર ફોકસ કરવામાં તમને સહાય કરે છે. હંમેશાં સાઇલન્ટ."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"પ્રાધાન્યતાવાળા નોટિફિકેશન નીચે બતાવે છે. હંમેશાં સાઇલન્ટ."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"પ્રાધાન્યતાવાળા નોટિફિકેશન નીચે બતાવે છે. હંમેશાં સાઇલન્ટ."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"પ્રાધાન્યતાવાળા નોટિફિકેશન નીચે બતાવે છે. હંમેશાં સાઇલન્ટ."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"સાઉન્ડ અને સ્ટેટસ બાર આઇકન તમારું ધ્યાન દોરે છે. લૉક સ્ક્રીન પર બતાવે છે."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"સાઇલન્ટ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"અલર્ટ કરવાનું ચાલુ રાખો"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"તમને સાઉન્ડ અથવા વાઇબ્રેશન વિના ફોકસ કરવામાં સહાય કરે છે."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"સાઉન્ડ અથવા વાઇબ્રેશન વિના તમારું ધ્યાન દોરે છે."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"આ નોટિફિકેશનમાં કોઈ ફેરફાર થઈ શકશે નહીં."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"નોટિફિકેશનના આ ગ્રૂપની ગોઠવણી અહીં કરી શકાશે નહીં"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"પ્રૉક્સી નોટિફિકેશન"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ટાઇલ ઉમેરવા માટે તેના પર આંગળી દબાવીને ખેંચો"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ટાઇલને ફરીથી ગોઠવવા માટે આંગળી દબાવીને ખેંચો"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"દૂર કરવા માટે અહીં ખેંચો"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"તમને ઓછામાં ઓછી <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ટાઇલની જરૂર છે"</string>
     <string name="qs_edit" msgid="2232596095725105230">"સંપાદિત કરો"</string>
     <string name="tuner_time" msgid="6572217313285536011">"સમય"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"મંજૂરી આપો"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"નકારો"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"બૅટરી સેવર શેડ્યૂલ કરવા માટે ટૅપ કરો"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"જ્યારે બૅટરી સંભવિત રૂપે પૂરી થવામાં હોય ત્યારે બૅટરી સેવર ચાલુ કરો"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ના, આભાર"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"બૅટરી સેવર શેડ્યૂલ ચાલુ થયું"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"બૅટરીનું સ્તર એકવાર <xliff:g id="PERCENTAGE">%d</xliff:g>%% કરતાં ઓછું થાય તે પછી બૅટરી સેવર ઑટોમૅટિક રીતે ચાલુ થશે."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"નીચે ડાબે ખસેડો"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"નીચે જમણે ખસેડો"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"છોડી દો"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"સિસ્ટમ નૅવિગેશન અપડેટ કર્યું. ફેરફારો કરવા માટે, સેટિંગ પર જાઓ."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"સિસ્ટમ નૅવિગેશનને અપડેટ કરવા માટે સેટિંગ પર જાઓ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/config.xml b/packages/SystemUI/res/values-hi/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-hi/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 6136f41..263fe8a 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB डीबगिंग की अनुमति नहीं है"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"अभी इस डिवाइस में जिस उपयोगकर्ता ने साइन इन किया है, वो USB डीबगिंग चालू नहीं कर सकता. इस सुविधा का इस्तेमाल करने के लिए, प्राथमिक उपयोगकर्ता में बदलें."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"यूएसबी पोर्ट बंद है"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"तरल चीज़ या कचरे से आपके डिवाइस की सुरक्षा करने के लिए, यूएसबी पोर्ट को बंद कर दिया गया है. साथ ही, इससे किसी भी एक्सेसरी की पहचान नहीं की जा सकेगी.\n\nयूएसबी पोर्ट का दोबारा इस्तेमाल करना सुरक्षित होने पर आपको सूचित किया जाएगा."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"चार्जर और एक्सेसरी पहचानने के लिए यूएसबी पोर्ट को चालू कर दिया गया है"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"यूएसबी चालू करें"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ज़्यादा जानें"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"स्‍क्रीन भरने के लिए ज़ूम करें"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"स्‍क्रीन भरने के लिए खींचें"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रीनशॉट"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"आपके चेहरे की पुष्टि की जा रही है"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"चेहरे की पुष्टि हो गई"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"पुष्टि हो गई"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"\'पुष्टि करें\' पर टैप करके पूरा करें"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फ़िंगरप्रिंट सेंसर को छुएं"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फ़िंगरप्रिंट आइकॉन"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"आपको पहचान रहा है…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"मोबाइल और इंटरनेट सेवा देने वाली कंपनी का नेटवर्क बदल रहा है"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"बैटरी का विवरण खोलें"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> प्रति‍शत बैटरी."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> प्रतिशत बैटरी बची है और आपके इस्तेमाल के हिसाब से यह <xliff:g id="TIME">%2$s</xliff:g> में खत्म हो जाएगी"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"बैटरी चार्ज हो रही है, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"सिस्टम सेटिंग."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाएं."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"सुबह तक चालू रहेगी"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> पर चालू की जाएगी"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> तक"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"गहरे रंग वाली थीम"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"गहरे रंग वाली थीम\nबैटरी सेवर"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"गहरे रंग वाली थीम"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"गहरे रंग वाली थीम\nबैटरी सेवर"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"एनएफ़सी"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC बंद है"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC चालू है"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"खोलने के लिए फिर से टैप करें"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"अनलॉक करने के लिए ऊपर स्वाइप करें"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"खोलने के लिए ऊपर स्वाइप करें"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"इस डिवाइस का प्रबंधन आपका संगठन करता है"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"इस डिवाइस के प्रबंधक <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> हैं"</string>
     <string name="phone_hint" msgid="4872890986869209950">"फ़ोन के लिए आइकॉन से स्वाइप करें"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"फिर से न दिखाएं"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सभी को हटाएं"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"प्रबंधित करें"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"बिना आवाज़ या वाइब्रेशन वाली सूचनाएं"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"बिना आवाज़ की सभी सूचनाएं हटाएं"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'परेशान न करें\' सुविधा के ज़रिए कुछ समय के लिए सूचनाएं दिखाना रोक दिया गया है"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"अब शुरू करें"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"कोई सूचना नहीं मिली"</string>
@@ -486,7 +484,7 @@
     <string name="monitoring_title_device_owned" msgid="1652495295941959815">"डिवाइस प्रबंधन"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"प्रोफ़ाइल को मॉनीटर करना"</string>
     <string name="monitoring_title" msgid="169206259253048106">"नेटवर्क को मॉनीटर करना"</string>
-    <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"VPN"</string>
+    <string name="monitoring_subtitle_vpn" msgid="876537538087857300">"वीपीएन"</string>
     <string name="monitoring_subtitle_network_logging" msgid="3341264304793193386">"नेटवर्क लॉगिंग"</string>
     <string name="monitoring_subtitle_ca_certificate" msgid="3874151893894355988">"CA प्रमाणपत्र"</string>
     <string name="disable_vpn" msgid="4435534311510272506">"VPN अक्षम करें"</string>
@@ -515,7 +513,7 @@
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"आपके एडमिन ने नेटवर्क लॉग करना चालू कर दिया है, जो आपके डिवाइस पर ट्रैफ़िक की निगरानी करता है.\n\nज़्यादा जानकारी के लिए अपने एडमिन से संपर्क करें."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"आपने किसी ऐप को VPN कनेक्‍शन सेट करने की अनुमति दी है.\n\nयह ऐप ईमेल, ऐप्‍स और सुरक्षित वेबसाइटों सहित आपके डिवाइस और नेटवर्क की गतिविधि की निगरानी कर सकता है."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"<xliff:g id="ORGANIZATION">%1$s</xliff:g> आपकी वर्क प्रोफ़ाइल को प्रबंधित करता है.\n\n आपका एडमिन ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है.\n\nऔर जानकारी के लिए अपने एडमिन से संपर्क करें.\n\nआप ऐसे VPN से भी कनेक्‍ट हैं, जो आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
-    <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
+    <string name="legacy_vpn_name" msgid="6604123105765737830">"वीपीएन"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइटों सहित आपकी नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्‍ट हैं, जो ईमेल, ऐप्‍स और वेबसाइटों सहित आपकी व्‍यक्‍तिगत नेटवर्क गतिविधि की निगरानी कर सकता है."</string>
     <string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"आप <xliff:g id="APPLICATION">%1$s</xliff:g> से कनेक्‍ट हैं, जो ईमेल, ऐप्लिकेशन और वेबसाइट सहित आपकी व्‍यक्‍तिगत नेटवर्क गतिविधि को मॉनिटर कर सकता है."</string>
@@ -636,7 +634,7 @@
     <string name="notification_channel_minimized" msgid="1664411570378910931">"इन सूचनाओं को छोटा कर दिया जाएगा"</string>
     <string name="notification_channel_silenced" msgid="2877199534497961942">"ये सूचनाएं बिना आवाज़ के दिखाई जाएंगी"</string>
     <string name="notification_channel_unsilenced" msgid="4790904571552394137">"ये सूचनाएं आपको अलर्ट करेंगी"</string>
-    <string name="inline_blocking_helper" msgid="3055064577771478591">"अाप अक्सर इन सूचनाओं को खारिज कर देते हैं. \nआगे भी इन्हें देखना जारी रखना चाहते हैं?"</string>
+    <string name="inline_blocking_helper" msgid="3055064577771478591">"आप अक्सर इन सूचनाओं को खारिज कर देते हैं. \nआगे भी इन्हें देखना जारी रखना चाहते हैं?"</string>
     <string name="inline_done_button" msgid="492513001558716452">"हो गया"</string>
     <string name="inline_ok_button" msgid="975600017662930615">"लागू करें"</string>
     <string name="inline_keep_showing" msgid="8945102997083836858">"ये सूचनाएं दिखाना जारी रखें?"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ब्लॉक करें"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"दिखाना जारी रखें"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"सूचनाएं छोटी करें"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"बिना आवाज़ के सूचनाएं दिखाएं"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"साइलेंट मोड में सूचनाएं पाएं"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"चेतावनी देना"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"सूचना देना जारी रखें"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"सूचनाएं बंद करें"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"इस ऐप्लिकेशन से जुड़ी सूचनाएं दिखाना जारी रखें?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"बिना आवाज़ के"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ज़रूरी"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"सिर्फ़ नीचे खिंचने वाली सूची में सूचनाएं दिखती हैं ताकि आप उन पर पूरा ध्यान दे सकें. दिखते समय आवाज़ और वाइब्रेशन हमेशा बंद रहते हैं."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"कम ज़रूरी सूचनाएं दिखती हैं. दिखते समय आवाज़ और वाइब्रेशन हमेशा बंद रहते हैं."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"कम ज़रूरी सूचनाएं दिखती हैं. दिखते समय आवाज़ और वाइब्रेशन हमेशा बंद रहते हैं."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"कम ज़रूरी सूचनाएं दिखती हैं. दिखते समय आवाज़ और वाइब्रेशन हमेशा बंद रहते हैं."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"आवाज़ और स्टेटस बार के आइकॉन की मदद से सूचनाओं पर आपका ध्यान खिंचता है. लॉक स्क्रीन पर दिखाई देता है."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"आवाज़ के बिना सूचनाएं दिखाएं"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"चेतावनी वाली सूचनाएं"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"आवाज़ या वाइब्रेशन न होने की वजह से आप काम में ध्यान लगा पाते हैं."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"आवाज़ या वाइब्रेशन होने की वजह से आपका ध्यान सूचनाओं पर जाता है."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ये सूचनाएं नहीं बदली जा सकती हैं."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"सूचनाओं के इस समूह को यहां कॉन्फ़िगर नहीं किया जा सकता"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रॉक्सी सूचना"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"टाइल जोड़ने के लिए दबाएं और खींचें"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"टाइल का क्रम फिर से बदलने के लिए उन्हें दबाकर रखें और खींचें"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"हटाने के लिए यहां खींचें और छोड़ें"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"आपके पास कम से कम <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> टाइलें होनी चाहिए"</string>
     <string name="qs_edit" msgid="2232596095725105230">"बदलाव करें"</string>
     <string name="tuner_time" msgid="6572217313285536011">"समय"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"मंज़ूरी दें"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"नामंज़ूर करें"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"बैटरी सेवर शेड्यूल करने के लिए टैप करें"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"जब बैटरी खत्म होने वाली हो तब \'बैटरी सेवर\' चालू करें"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"जी नहीं, शुक्रिया"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"शेड्यूल किया गया बैटरी सेवर चालू हो गया"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"बैटरी के <xliff:g id="PERCENTAGE">%d</xliff:g>%% से कम होने पर बैटरी सेवर अपने आप चालू हो जाएगा."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"बाईं ओर सबसे नीचे ले जाएं"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"सबसे नीचे दाईं ओर ले जाएं"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"खारिज करें"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"सिस्टम नेविगेशन अपडेट हो गया. बदलाव करने के लिए \'सेटिंग\' पर जाएं."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"सिस्टम नेविगेशन अपडेट करने के लिए \'सेटिंग\' में जाएं"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/config.xml b/packages/SystemUI/res/values-hr/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-hr/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index d8e2dfb..2954de2 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Otklanjanje pogrešaka putem USB-a nije dopušteno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Korisnik koji je trenutačno prijavljen na ovaj uređaj ne može uključiti otklanjanje pogrešaka putem USB-a. Da biste upotrebljavali tu značajku, prijeđite na primarnog korisnika."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Onemogućen je USB priključak"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Radi zaštite uređaja od tekućine ili prljavštine USB priključak onemogućen je i neće otkrivati pribor.\n\nPrimit ćete obavijest kad upotreba USB priključka ponovo bude sigurna."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB priključak omogućen za otkrivanje punjača i opreme"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Omogući USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saznajte više"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zumiraj i ispuni zaslon"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rastegni i ispuni zaslon"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snimka zaslona"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Traženje lica"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Lice je autentificirano"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrđeno"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Dodirnite Potvrdi za dovršetak"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dodirnite senzor otiska prsta"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona otiska prsta"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Tražimo vas…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Promjena mreže mobilnog operatera"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvaranje pojedinosti o bateriji"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterija je na <xliff:g id="PERCENTAGE">%1$s</xliff:g> posto, još otprilike <xliff:g id="TIME">%2$s</xliff:g> na temelju vaše upotrebe"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> posto."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Postavke sustava."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obavijesti."</string>
@@ -378,8 +378,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do izlaska sunca"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Uključuje se u <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tamna tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tamna tema\nŠtednja baterije"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tamna tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tamna tema\nŠtednja baterije"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC je onemogućen"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC je omogućen"</string>
@@ -402,7 +402,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitne obavijesti pri dnu"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite opet za otvaranje"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Prijeđite prstom prema gore za otključavanje"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Prijeđite prstom prema gore da biste otvorili"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja vaša organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Prijeđite prstom od ikone za telefon"</string>
@@ -461,10 +461,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne prikazuj ponovo"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Izbriši sve"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljajte"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Bešumne obavijesti"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Izbriši sve bešumne obavijesti"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Značajka Ne uznemiravaj pauzirala je Obavijesti"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Započni sad"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nema obavijesti"</string>
@@ -535,7 +533,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Postavke zvuka"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširivanje"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sažimanje"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatski opisi medija"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Automatski titlovi za medije"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Zatvorite opis"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Sloj titlova"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"omogući"</string>
@@ -648,21 +646,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokiraj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Nastavi prikazivati"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimiziraj"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Bešumno"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Nastavi tiho"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Obavještavanje"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Nastavi obavještavati"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Isključi obavijesti"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite li da se obavijesti te aplikacije nastave prikazivati?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Neupadljivo"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritetno"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomaže vam da se usredotočite prikazujući obavijesti samo na zaslonu obavijesti. Uvijek bešumno."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Prikazuje se ispod prioritetnih obavijesti. Uvijek bešumno."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Prikazuje se ispod prioritetnih obavijesti. Uvijek bešumno."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Prikazuje se ispod prioritetnih obavijesti. Uvijek bešumno."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Privlači vašu pažnju zvučnim signalom i ikonom na traci statusa. Prikazuje se na zaključanom zaslonu."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Bešumno"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Upozoravanje"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaže vam da se usredotočite bez zvučnih signala i vibracija."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Privlači vašu pažnju zvučnim signalima ili vibracijama."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Te se obavijesti ne mogu izmijeniti."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ta se grupa obavijesti ne može konfigurirati ovdje"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Obavijest poslana putem proxyja"</string>
@@ -791,8 +784,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Zadržite i povucite za dodavanje pločica"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Zadržite i povucite da biste premjestili pločice"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Povucite ovdje za uklanjanje"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Potrebno je barem <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> pločica"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Uredi"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Vrijeme"</string>
   <string-array name="clock_options">
@@ -914,8 +906,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Dopusti"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Odbij"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Dodirnite za zakazivanje štednje baterije"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Uključite kad bi se baterija mogla isprazniti"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, hvala"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Uključen je raspored štednje baterije"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Štednja baterije uključit će se automatski kad razina baterije padne ispod <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -948,4 +939,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Premjesti u donji lijevi kut"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Premjestite u donji desni kut"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Odbaci"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Ažurirana je navigacija sustavom. Možete je promijeniti u Postavkama."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Navigaciju sustavom možete ažurirati u Postavkama"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/config.xml b/packages/SystemUI/res/values-hu/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-hu/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 5804374..e7e039e 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Az USB hibakeresése nem engedélyezett"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Az eszközre jelenleg bejelentkezett felhasználó nem engedélyezheti az USB-hibakeresést. A funkció használatához váltson az elsődleges felhasználóra."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-port letiltva"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Az eszköz folyadéktól és szennyeződésektől való megóvása érdekében az USB-portot letiltottuk, így az nem észleli a kiegészítőket.\n\nÉrtesítést küldünk, amikor ismét rendben használhatja az USB-portot."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Az USB-csatlakozó számára engedélyezve van a töltők és más tartozékok észlelése"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB engedélyezése"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Részletek"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Nagyítás a kitöltéshez"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Nyújtás kitöltéshez"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Képernyőkép"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Arc keresése"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Arc hitelesítve"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Megerősítve"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Koppintson a Megerősítés lehetőségre"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Érintse meg az ujjlenyomat-érzékelőt"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ujjlenyomat ikonja"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Keresem az Ön arcát…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Szolgáltatói hálózat váltása"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Az akkumulátorral kapcsolatos részletek megnyitása"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Akkumulátor <xliff:g id="NUMBER">%d</xliff:g> százalék."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Az akkumulátor <xliff:g id="PERCENTAGE">%1$s</xliff:g> százalékon áll, a használati adatok alapján körülbelül <xliff:g id="TIME">%2$s</xliff:g> múlva merül le"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Akkumulátor töltése folyamatban, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> százalék."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Rendszerbeállítások"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Értesítések"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Napfelkeltéig"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Bekapcsolás: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Eddig: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Sötét téma"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Sötét téma\nAkkumulátorkímélő mód"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Sötét téma"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Sötét téma\nAkkumulátorkímélő mód"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Az NFC ki van kapcsolva"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Az NFC be van kapcsolva"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"A kevésbé sürgős értesítések lentebb vannak"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Koppintson ismét a megnyitáshoz"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Húzza felfelé az ujját a feloldáshoz"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Csúsztasson felfelé a megnyitáshoz"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Az eszközt az Ön szervezete kezeli"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> felügyeli."</string>
     <string name="phone_hint" msgid="4872890986869209950">"A telefonhoz csúsztasson az ikonról"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne jelenjen meg többé"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Az összes törlése"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Kezelés"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Néma értesítések"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Az összes néma értesítés törlése"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Ne zavarjanak funkcióval szüneteltetett értesítések"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Indítás most"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nincs értesítés"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Tiltás"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Megjelenítés továbbra is"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Kis méret"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Néma"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Néma megjelenítés"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Értesítések"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Értesítések folytatása"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Az értesítések kikapcsolása"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Továbbra is megjelenjenek az alkalmazás értesítései?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diszkrét"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritásos"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Segítségével a fontos dolgokra koncentrálhat, az értesítések csak a lehúzható értesítési felületen jelennek meg. Mindig némítva van."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Az elsőbbségi értesítések alatt jelenik meg. Mindig némítva van."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Az elsőbbségi értesítések alatt jelenik meg. Mindig némítva van."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Az elsőbbségi értesítések alatt jelenik meg. Mindig némítva van."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Figyelemfelkeltő a hangjelzésnek és az állapotsávon megjelenő ikonnak köszönhetően. Megjelenik a lezárási képernyőn."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Néma"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Figyelemfelkeltő"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hangjelzés és rezgés nélkül segít a koncentrálásban."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Figyelemfelkeltő a hangjelzésnek és rezgésnek köszönhetően."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ezeket az értesítéseket nem lehet módosítani."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Az értesítések jelen csoportját itt nem lehet beállítani"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Továbbított értesítés"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Tartsa lenyomva, és húzza a mozaikok hozzáadásához"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Tartsa lenyomva, és húzza a mozaikok átrendezéséhez"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Húzza ide az eltávolításhoz"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Legalább <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kártya szükséges"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Szerkesztés"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Idő"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Engedélyezés"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Elutasítás"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Koppintson az akkumulátorkímélő mód ütemezéséhez"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Kapcsolja be, ha az akkumulátor hamarosan lemerül"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nem"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Akkumulátorkímélő mód ütemezése bekapcsolva"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Az akkumulátorkímélő mód automatikusan bekapcsol, ha az akkumulátor töltöttsége <xliff:g id="PERCENTAGE">%d</xliff:g>%% alá esik."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Áthelyezés le és balra"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Áthelyezés le és jobbra"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Elvetés"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"A rendszer-navigáció módja megváltozott. Módosításához nyissa meg a Beállításokat."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"A rendszer-navigációs lehetőségeket a Beállításokban módosíthatja"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/config.xml b/packages/SystemUI/res/values-hy/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-hy/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index f5f45aa..3156a6f 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB վրիպազերծումը արգելված է"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Ընթացիկ հաշվի օգտատերը չի կարող միացնել USB վրիպազերծումը: Այս գործառույթը միացնելու համար մուտք գործեք հիմնական օգտատիրոջ հաշվով:"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB միացքն անջատված է"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB միացքն անջատվել է, որպեսզի ձեր սարքը չթրջվի կամ չաղտոտվի: Այժմ USB միացքի միջոցով հնարավոր չէ միացնել այլ սարքեր:\n\nԴուք ծանուցում կստանաք, երբ այն նորից անվտանգ լինի օգտագործել:"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB միացքը միացվել է՝ լիցքավորիչներն ու լրասարքերը հայտնաբերելու համար"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Միացնել USB-ն"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Իմանալ ավելին"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Խոշորացնել` էկրանը լցնելու համար"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ձգել` էկրանը լցնելու համար"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Սքրինշոթ"</string>
@@ -126,12 +124,13 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Դեմքի նույնականացում"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Դեմքը ճանաչվեց"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Հաստատվեց"</string>
-    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Հպեք մատնահետքերի սկաներին"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ավարտելու համար հպեք «Հաստատել»"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Հպեք մատնահետքի սկաներին"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Մատնահետքի պատկերակ"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Դեմքի ճանաչում…"</string>
     <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Դեմքի պատկերակ"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Համատեղելիության խոշորացման կոճակը:"</string>
-    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Դիտափոխել փոքրից ավելի մեծ էկրան:"</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Մասշտաբը մեծացնել փոքրից ավելի մեծ էկրան:"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth-ը միացված է:"</string>
     <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth-ն անջատված է:"</string>
     <string name="accessibility_no_battery" msgid="358343022352820946">"Մարտկոց չկա:"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Օպերատորի ցանցի փոփոխություն"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Բացել մարտկոցի տվյալները"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Մարտկոցը <xliff:g id="NUMBER">%d</xliff:g> տոկոս է:"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%1$s</xliff:g> տոկոս է և կբավարարի մոտ <xliff:g id="TIME">%2$s</xliff:g>՝ կախված օգտագործման եղանակից:"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Մարտկոցը լիցքավորվում է: Լիցքը <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> տոկոս է:"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Համակարգի կարգավորումներ:"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Ծանուցումներ:"</string>
@@ -207,7 +207,7 @@
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS-ը միացված է:"</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS-ի ստացում:"</string>
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Հեռամուտքագրիչը միացված է:"</string>
-    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Զանգի թրթռոց:"</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Թրթռազանգ:"</string>
     <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Զանգակը լռեցված է:"</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Մինչև լուսաբաց"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Կմիացվի ժամը <xliff:g id="TIME">%s</xliff:g>-ին"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Մինչև <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Մուգ թեմա"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Մուգ թեմա\nՄարտկոցի տնտեսում"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Մուգ թեմա"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Մուգ թեմա\nՄարտկոցի տնտեսում"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC-ն անջատված է"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC-ն միացված է"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Պակաս հրատապ ծանուցումները ստորև"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Կրկին հպեք՝ բացելու համար"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Սահեցրեք վերև` ապակողպելու համար"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Բացելու համար սահեցրեք վերև"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Այս սարքը կառավարում է ձեր կազմակերպությունը"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Այս սարքը կառավարվում է <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-ի կողմից"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Սահահարվածեք հեռախոսի պատկերակից"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Այլևս ցույց չտալ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Մաքրել բոլորը"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Կառավարել"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Անձայն ծանուցումներ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Ջնջել բոլոր անձայն ծանուցումները"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Ծանուցումները չեն ցուցադրվի «Չանհանգստացնել» ռեժիմում"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Սկսել հիմա"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ծանուցումներ չկան"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Արգելափակել"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Ցուցադրել"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Ծալել"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Անձայն"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Չմիացնել ձայնը"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Ծանուցել"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Ծանուցել"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Անջատել ծանուցումները"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Ցուցադրե՞լ ծանուցումներ այս հավելվածից։"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Անձայն"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Առաջնահերթ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ծանուցումները ցուցադրվում են միայն իջնող վահանակի վրա, որպեսզի դուք չշեղվեք ձեր աշխատանքից: Միշտ անձայն:"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Ցուցադրվում են կարևոր ծանուցումների տակ: Միշտ անձայն:"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Ցուցադրվում են կարևոր ծանուցումների տակ: Միշտ անձայն:"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Ցուցադրվում են կարևոր ծանուցումների տակ: Միշտ անձայն:"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Ծանուցումները ձեր ուշադրությունն են գրավում ազդանշանով և կարգավիճակի գոտում ցուցադրվող պատկերակով: Ցուցադրվում են կողպէկրանին:"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Անձայն"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Ծանուցումներ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ծանուցումները գալիս են առանց ձայնի և թրթռոցի։"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ծանուցումները գալիս են ձայնով կամ թրթռոցով։"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Այս ծանուցումները չեն կարող փոփոխվել:"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ծանուցումների տվյալ խումբը հնարավոր չէ կարգավորել այստեղ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ծանուցումն ուղարկվել է պրոքսի սերվերի միջոցով"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Պահեք և քաշեք՝ սալիկներ ավելացնելու համար"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Պահեք և քաշեք՝ սալիկները վերադասավորելու համար"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Քաշեք այստեղ՝ հեռացնելու համար"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Հարկավոր է առնվազն <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> սալիկ"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Փոփոխել"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Ժամ"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Թույլատրել"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Մերժել"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Հպեք՝ մարտկոցի տնտեսման ռեժիմը կարգավորելու համար"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Միացնել էներգախնայումը, երբ մարտկոցի լիցքը գրեթե սպառված է"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ոչ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Մարտկոցի տնտեսման ռեժիմին ավտոմատ անցումը միացված է"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Մարտկոցի տնտեսման ռեժիմն ավտոմատ կմիանա, երբ մարտկոցի լիցքը <xliff:g id="PERCENTAGE">%d</xliff:g>%%-ից պակասի:"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Տեղափոխել ներքև՝ ձախ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Տեղափոխել ներքև՝ աջ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Փակել"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Համակարգի նավիգացիան թարմացվեց: Փոփոխություններ անելու համար անցեք կարգավորումներ:"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Թարմացրեք համակարգի նավիգացիան կարգավորումներում"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/config.xml b/packages/SystemUI/res/values-in/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-in/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 4d0b40e..19b2b99 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -62,7 +62,7 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Debug USB tidak diizinkan"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Pengguna yang sedang login ke perangkat ini tidak dapat mengaktifkan proses debug USB. Beralihlah ke pengguna utama untuk menggunakan fitur ini."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB dinonaktifkan"</string>
-    <string name="usb_contaminant_message" msgid="7379089091591609111">"Untuk melindungi perangkat dari cairan atau kotoran, port USB dinonaktifkan dan tidak akan mendeteksi aksesori apa pun.\n\nAnda akan diberi tahu jika sudah diperbolehkan menggunakan port USB kembali."</string>
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Untuk melindungi perangkat dari cairan atau kotoran, port USB dinonaktifkan dan tidak akan mendeteksi aksesori apa pun.\n\nAnda akan diberi tahu jika port USB sudah dapat digunakan kembali."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB diaktifkan untuk mendeteksi pengisi daya dan aksesori"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktifkan USB"</string>
     <string name="learn_more" msgid="5000517160980853569">"Pelajari lebih lanjut"</string>
@@ -72,7 +72,7 @@
     <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Menyimpan screenshot..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Menyimpan screenshot..."</string>
     <string name="screenshot_saved_title" msgid="5637073968117370753">"Screenshot disimpan"</string>
-    <string name="screenshot_saved_text" msgid="7574667448002050363">"Tap untuk melihat screenshot"</string>
+    <string name="screenshot_saved_text" msgid="7574667448002050363">"Ketuk untuk melihat screenshot"</string>
     <string name="screenshot_failed_title" msgid="7612509838919089748">"Tidak dapat menyimpan screenshot"</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Coba ambil screenshot lagi"</string>
     <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Tidak dapat menyimpan screenshot karena ruang penyimpanan terbatas"</string>
@@ -89,7 +89,7 @@
     <string name="screenrecord_share_label" msgid="4197867360204019389">"Bagikan"</string>
     <string name="screenrecord_delete_label" msgid="7893716870917824013">"Hapus"</string>
     <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Rekaman layar dibatalkan"</string>
-    <string name="screenrecord_save_message" msgid="4733982661301846778">"Rekaman layar disimpan, tap untuk melihat"</string>
+    <string name="screenrecord_save_message" msgid="4733982661301846778">"Rekaman layar disimpan, ketuk untuk melihat"</string>
     <string name="screenrecord_delete_description" msgid="5743190456090354585">"Rekaman layar dihapus"</string>
     <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error saat menghapus rekaman layar"</string>
     <string name="screenrecord_permission_error" msgid="1526755299469001000">"Gagal mendapatkan izin"</string>
@@ -119,11 +119,12 @@
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
     <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Konfirmasi"</string>
     <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Coba lagi"</string>
-    <string name="biometric_dialog_empty_space_description" msgid="7997936968009073717">"Area kosong. Tap untuk membatalkan autentikasi"</string>
+    <string name="biometric_dialog_empty_space_description" msgid="7997936968009073717">"Area kosong. Ketuk untuk membatalkan autentikasi"</string>
     <string name="biometric_dialog_face_icon_description_idle" msgid="4497694707475970790">"Coba lagi"</string>
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Mencari wajah Anda"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Wajah diautentikasi"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Dikonfirmasi"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ketuk Konfirmasi untuk menyelesaikan"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sentuh sensor sidik jari"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon sidik jari"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Mencari wajah Anda…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Jaringan operator berubah"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Membuka detail baterai"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterai <xliff:g id="NUMBER">%d</xliff:g> persen."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Baterai <xliff:g id="PERCENTAGE">%1$s</xliff:g> persen, sekitar <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan Anda"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Mengisi daya baterai, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> persen."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Setelan sistem."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifikasi."</string>
@@ -296,7 +298,7 @@
     <string name="dessert_case" msgid="1295161776223959221">"Etalase Hidangan Penutup"</string>
     <string name="start_dreams" msgid="5640361424498338327">"Screen saver"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
-    <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Tap lama ikon untuk opsi lainnya"</string>
+    <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Sentuh lama ikon untuk opsi lainnya"</string>
     <string name="quick_settings_dnd_label" msgid="7112342227663678739">"Jangan Ganggu"</string>
     <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Hanya untuk prioritas"</string>
     <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Hanya alarm"</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Sampai pagi"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Aktif pada <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Hingga <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema Gelap"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema Gelap\nPenghemat baterai"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema gelap"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema gelap\nPenghemat baterai"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC dinonaktifkan"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC diaktifkan"</string>
@@ -397,8 +399,8 @@
     <string name="zen_silence_introduction" msgid="3137882381093271568">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir."</string>
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifikasi kurang darurat di bawah"</string>
-    <string name="notification_tap_again" msgid="7590196980943943842">"Tap lagi untuk membuka"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Geser ke atas untuk membuka kunci"</string>
+    <string name="notification_tap_again" msgid="7590196980943943842">"Ketuk lagi untuk membuka"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Geser ke atas untuk membuka"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Perangkat ini dikelola oleh organisasi"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Perangkat ini dikelola oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Geser dari ikon untuk telepon"</string>
@@ -535,13 +537,13 @@
     <string name="volume_odi_captions_hint_disable" msgid="8980842810619956593">"nonaktifkan"</string>
     <string name="accessibility_output_chooser" msgid="8185317493017988680">"Ganti perangkat keluaran"</string>
     <string name="screen_pinning_title" msgid="3273740381976175811">"Layar dipasangi pin"</string>
-    <string name="screen_pinning_description" msgid="8909878447196419623">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh &amp; tahan tombol Kembali dan Ringkasan untuk melepas pin."</string>
-    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh &amp; tahan tombol Kembali dan Beranda untuk melepas pin."</string>
+    <string name="screen_pinning_description" msgid="8909878447196419623">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Kembali dan Ringkasan untuk melepas pin."</string>
+    <string name="screen_pinning_description_recents_invisible" msgid="8281145542163727971">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Kembali dan Beranda untuk melepas pin."</string>
     <string name="screen_pinning_description_gestural" msgid="1191513974909607884">"Ini akan terus ditampilkan sampai Anda melepas pin. Geser ke atas &amp; tahan untuk melepas pin."</string>
-    <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh dan tahan tombol Ringkasan untuk melepas pin."</string>
-    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh dan tahan tombol Beranda untuk melepas pin."</string>
-    <string name="screen_pinning_toast" msgid="2266705122951934150">"Untuk melepas pin layar ini, sentuh &amp; tahan tombol Kembali dan Ringkasan"</string>
-    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Untuk melepas pin layar ini, sentuh &amp; tahan tombol Kembali dan Beranda"</string>
+    <string name="screen_pinning_description_accessible" msgid="426190689254018656">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Ringkasan untuk melepas pin."</string>
+    <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Beranda untuk melepas pin."</string>
+    <string name="screen_pinning_toast" msgid="2266705122951934150">"Untuk melepas pin layar ini, sentuh lama tombol Kembali dan Ringkasan"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Untuk melepas pin layar ini, sentuh lama tombol Kembali dan Beranda"</string>
     <string name="screen_pinning_positive" msgid="3783985798366751226">"Mengerti"</string>
     <string name="screen_pinning_negative" msgid="3741602308343880268">"Lain kali"</string>
     <string name="screen_pinning_start" msgid="1022122128489278317">"Layar dipasangi pin"</string>
@@ -564,11 +566,11 @@
     <string name="volume_ringer_status_silent" msgid="6896394161022916369">"Nonaktifkan"</string>
     <string name="qs_status_phone_vibrate" msgid="204362991135761679">"Ponsel mode getar"</string>
     <string name="qs_status_phone_muted" msgid="5437668875879171548">"Ponsel dimatikan suaranya"</string>
-    <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tap untuk menyuarakan."</string>
-    <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tap untuk menyetel agar bergetar. Layanan aksesibilitas mungkin dibisukan."</string>
-    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tap untuk membisukan. Layanan aksesibilitas mungkin dibisukan."</string>
-    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Tap untuk menyetel agar bergetar."</string>
-    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Tap untuk menonaktifkan."</string>
+    <string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Ketuk untuk menyuarakan."</string>
+    <string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Ketuk untuk menyetel agar bergetar. Layanan aksesibilitas mungkin dibisukan."</string>
+    <string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Ketuk untuk membisukan. Layanan aksesibilitas mungkin dibisukan."</string>
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="6427727603978431301">"%1$s. Ketuk untuk menyetel agar bergetar."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="8995013018414535494">"%1$s. Ketuk untuk menonaktifkan."</string>
     <string name="volume_ringer_hint_mute" msgid="9199811307292269601">"Tanpa suara"</string>
     <string name="volume_ringer_hint_unmute" msgid="6602880133293060368">"aktifkan"</string>
     <string name="volume_ringer_hint_vibrate" msgid="4036802135666515202">"getar"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Terus beri tahu"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Nonaktifkan notifikasi"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Terus tampilkan notifikasi dari aplikasi ini?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Senyap"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Diprioritaskan"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Membantu Anda berfokus hanya pada notifikasi di bayangan pull-down. Selalu senyap."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Ditampilkan di bawah notifikasi prioritas. Selalu senyap."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Ditampilkan di bawah notifikasi prioritas. Selalu senyap."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Ditampilkan di bawah notifikasi prioritas. Selalu senyap."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Menarik perhatian Anda dengan suara &amp; ikon status bar. Ditampilkan di layar kunci."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Senyap"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Pemberitahuan"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Membantu Anda tetap fokus tanpa suara atau getaran."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Menarik perhatian Anda dengan suara atau getaran."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Notifikasi ini tidak dapat diubah."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Grup notifikasi ini tidak dapat dikonfigurasi di sini"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notifikasi proxy"</string>
@@ -780,7 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Tahan dan tarik untuk menambahkan kartu"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Tahan dan tarik untuk mengatur ulang kartu"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Tarik ke sini untuk menghapus"</string>
-    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Anda membutuhkan setidaknya <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tile"</string>
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Anda membutuhkan setidaknya <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kartu"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Edit"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Waktu"</string>
   <string-array name="clock_options">
@@ -806,8 +805,8 @@
     <string name="accessibility_action_divider_top_50" msgid="6385859741925078668">"Atas 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="6201455163864841205">"Atas 30%"</string>
     <string name="accessibility_action_divider_bottom_full" msgid="301433196679548001">"Layar penuh di bawah"</string>
-    <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tap dua kali untuk mengedit."</string>
-    <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Tap dua kali untuk menambahkan."</string>
+    <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Ketuk dua kali untuk mengedit."</string>
+    <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Ketuk dua kali untuk menambahkan."</string>
     <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"Pindahkan <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Hapus <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add" msgid="3520406665865985109">"Tambahkan <xliff:g id="TILE_NAME">%1$s</xliff:g> ke posisi <xliff:g id="POSITION">%2$d</xliff:g>"</string>
@@ -837,7 +836,7 @@
     <string name="pip_phone_dismiss_hint" msgid="6351678169095923899">"Tarik ke bawah untuk menutup"</string>
     <string name="pip_menu_title" msgid="4707292089961887657">"Menu"</string>
     <string name="pip_notification_title" msgid="3204024940158161322">"<xliff:g id="NAME">%s</xliff:g> adalah picture-in-picture"</string>
-    <string name="pip_notification_message" msgid="5619512781514343311">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, tap untuk membuka setelan dan menonaktifkannya."</string>
+    <string name="pip_notification_message" msgid="5619512781514343311">"Jika Anda tidak ingin <xliff:g id="NAME">%s</xliff:g> menggunakan fitur ini, ketuk untuk membuka setelan dan menonaktifkannya."</string>
     <string name="pip_play" msgid="1417176722760265888">"Putar"</string>
     <string name="pip_pause" msgid="8881063404466476571">"Jeda"</string>
     <string name="pip_skip_to_next" msgid="1948440006726306284">"Lewati ke berikutnya"</string>
@@ -874,7 +873,7 @@
     <string name="instant_apps" msgid="6647570248119804907">"Aplikasi Instan"</string>
     <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> berjalan"</string>
     <string name="instant_apps_message" msgid="1183313016396018086">"Aplikasi dapat dibuka tanpa perlu diinstal."</string>
-    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikasi dapat dibuka tanpa perlu diinstal. Tap untuk mempelajari lebih lanjut."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikasi dapat dibuka tanpa perlu diinstal. Ketuk untuk mempelajari lebih lanjut."</string>
     <string name="app_info" msgid="6856026610594615344">"Info aplikasi"</string>
     <string name="go_to_web" msgid="2650669128861626071">"Buka browser"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Data seluler"</string>
@@ -890,7 +889,7 @@
     <string name="qs_dnd_keep" msgid="1825009164681928736">"Simpan"</string>
     <string name="qs_dnd_replace" msgid="8019520786644276623">"Ganti"</string>
     <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikasi yang sedang berjalan di latar belakang"</string>
-    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap untuk melihat detail penggunaan baterai dan data"</string>
+    <string name="running_foreground_services_msg" msgid="6326247670075574355">"Ketuk untuk melihat detail penggunaan baterai dan data"</string>
     <string name="mobile_data_disable_title" msgid="1068272097382942231">"Nonaktifkan kuota?"</string>
     <string name="mobile_data_disable_message" msgid="4756541658791493506">"Anda tidak akan dapat mengakses data atau internet melalui <xliff:g id="CARRIER">%s</xliff:g>. Internet hanya akan tersedia melalui Wi-Fi."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6078110473451946831">"Operator Seluler Anda"</string>
@@ -901,7 +900,7 @@
     <string name="slice_permission_checkbox" msgid="7986504458640562900">"Izinkan <xliff:g id="APP">%1$s</xliff:g> menampilkan potongan dari aplikasi apa pun"</string>
     <string name="slice_permission_allow" msgid="2340244901366722709">"Izinkan"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Tolak"</string>
-    <string name="auto_saver_title" msgid="1217959994732964228">"Tap untuk menjadwalkan Penghemat Baterai"</string>
+    <string name="auto_saver_title" msgid="1217959994732964228">"Ketuk untuk menjadwalkan Penghemat Baterai"</string>
     <string name="auto_saver_text" msgid="2563289953551438248">"Aktifkan jika daya baterai kemungkinan akan habis"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Tidak, terima kasih"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Jadwal Penghemat Baterai diaktifkan"</string>
@@ -919,7 +918,7 @@
     <string name="sensor_privacy_mode" msgid="8982771253020769598">"Sensor nonaktif"</string>
     <string name="device_services" msgid="1191212554435440592">"Layanan Perangkat"</string>
     <string name="music_controls_no_title" msgid="5236895307087002011">"Tanpa judul"</string>
-    <string name="restart_button_description" msgid="2035077840254950187">"Tap untuk memulai ulang aplikasi ini dan membuka layar penuh."</string>
+    <string name="restart_button_description" msgid="2035077840254950187">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string>
     <string name="bubbles_deep_link_button_description" msgid="8895837143057564517">"Buka <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="bubbles_settings_button_description" msgid="2970630476657287189">"Setelan untuk balon <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="bubbles_prompt" msgid="8807968030159469710">"Izinkan balon dari <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Pindahkan ke kiri bawah"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Pindahkan ke kanan bawah"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Tutup"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigasi sistem diupdate. Untuk melakukan perubahan, buka Setelan."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Buka Setelan untuk mengupdate navigasi sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/config.xml b/packages/SystemUI/res/values-is/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-is/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index cba62be..0076add 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-villuleit ekki leyfð"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Notandinn sem er skráður inn í þetta tæki núna getur ekki kveikt á USB-villuleit. Til þess að nota þennan eiginleika skaltu skipta yfir í aðalnotandann."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-tengi gert óvirkt"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Til að vernda tækið fyrir vökva og óhreinindum er USB-tengið óvirkt og mun ekki greina aukabúnað.\n\nÞú færð tilkynningu þegar öruggt er að nota USB-tengið aftur."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Kveikt var á USB-tengi til að greina hleðslutæki og aukabúnað"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Virkja USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Frekari upplýsingar"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Fylla skjá með aðdrætti"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Teygja yfir allan skjáinn"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skjámynd"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Leitar að andliti þínu"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Andlit staðfest"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Staðfest"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ýttu á „Staðfesta“ til að ljúka"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Snertu fingrafaralesarann"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Fingrafaratákn"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Leitar að þér ..."</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Skiptir um farsímakerfi"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Opna upplýsingar um rafhlöðu"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> prósent á rafhlöðu."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Rafhlaða í <xliff:g id="PERCENTAGE">%1$s</xliff:g> prósentum, um það bil <xliff:g id="TIME">%2$s</xliff:g> eftir miðað við notkun þína"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Rafhlaða í hleðslu, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Kerfisstillingar."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Tilkynningar."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Til sólarupprásar"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Kveikt klukkan <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Til klukkan <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Dökkt þema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Dökkt þema\nRafhlöðusparnaður"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Dökkt þema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Dökkt þema\nRafhlöðusparnaður"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Slökkt á NFC"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Kveikt á NFC"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Minna áríðandi tilkynningar fyrir neðan"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ýttu aftur til að opna"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Strjúktu upp til að opna"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Strjúktu upp til að opna"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Þessu tæki er stýrt af fyrirtækinu þínu"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Þessu tæki er stýrt af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Strjúktu frá tákninu fyrir síma"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ekki sýna þetta aftur"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hreinsa allt"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Stjórna"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Þöglar tilkynningar"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Hreinsa allar þöglar tilkynningar"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Hlé gert á tilkynningum þar sem stillt er á „Ónáðið ekki“"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Byrja núna"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Engar tilkynningar"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Loka á"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Sýna áfram"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minnka"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Hljóðlaust"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Áfram hljóðlaust"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Tilkynna"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Halda áfram að gera viðvart"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Slökkva á tilkynningum"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Sýna áfram tilkynningar frá þessu forriti?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Lágstemmdar"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Í forgangi"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Auðveldar þér að einbeita þér með tilkynningum sem birtast aðeins á fellisvæði. Alltaf án hljóðs."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Birtir tilkynningar með lítinn forgang. Alltaf án hljóðs."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Birtir tilkynningar með lítinn forgang. Alltaf án hljóðs."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Birtir tilkynningar með lítinn forgang. Alltaf án hljóðs."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Fangar athygli þína með hljóði og stöðustikutákni. Sést á lásskjánum."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Hljóðlaust"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Viðvörun"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Auðveldar þér að einbeita þér án hljóðs eða titrings."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Fangar athygli þína með hljóði eða titringi."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ekki er hægt að breyta þessum tilkynningum."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ekki er hægt að stilla þessar tilkynningar hér"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Staðgengilstilkynning"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Haltu inni og dragðu til að bæta við reitum"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Haltu og dragðu til að endurraða flísum"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Dragðu hingað til að fjarlægja"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Reitirnir mega ekki vera færri en <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Breyta"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Tími"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Leyfa"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Hafna"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Pikka til að stilla rafhlöðusparnað"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Kveikja þegar rafhlaða er við það að klárast"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nei, takk"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Kveikt á rafhlöðusparnaði"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Sjálfkrafa verður kveikt á rafhlöðusparnaði þegar hleðsla rafhlöðunnar fer niður fyrir <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Færa neðst til vinstri"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Færðu neðst til hægri"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Hunsa"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Kerfisstjórnun uppfærð. Þú getur breytt þessu í stillingunum."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Farðu í stillingar til að uppfæra kerfisstjórnun"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/config.xml b/packages/SystemUI/res/values-it/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-it/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index aed3a1f..78d3d8a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -117,13 +117,14 @@
     <string name="voice_assist_label" msgid="3956854378310019854">"apri Voice Assist"</string>
     <string name="camera_label" msgid="7261107956054836961">"apri fotocamera"</string>
     <string name="cancel" msgid="6442560571259935130">"Annulla"</string>
-    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Confermo"</string>
+    <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Conferma"</string>
     <string name="biometric_dialog_try_again" msgid="1900185172633183201">"Riprova"</string>
     <string name="biometric_dialog_empty_space_description" msgid="7997936968009073717">"Spazio vuoto, tocca per annullare l\'autenticazione"</string>
     <string name="biometric_dialog_face_icon_description_idle" msgid="4497694707475970790">"Riprova"</string>
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Ricerca del tuo volto"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Volto autenticato"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confermato"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tocca Conferma per completare"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Tocca il sensore di impronte digitali"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icona dell\'impronta digitale"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"In attesa del volto…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Cambio della rete dell\'operatore"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Visualizza i dettagli relativi alla batteria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteria: <xliff:g id="NUMBER">%d</xliff:g> percento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Livello della batteria: <xliff:g id="PERCENTAGE">%1$s</xliff:g> percento. Tempo rimanente in base al tuo utilizzo: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteria in carica, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Impostazioni di sistema."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifiche."</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Fino all\'alba"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Dalle <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Fino alle <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema scuro"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema scuro\nRisparmio energetico"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema scuro"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema scuro\nRisparmio energetico"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC non attiva"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC attiva"</string>
@@ -398,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifiche meno urgenti in basso"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tocca ancora per aprire"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Scorri verso l\'alto per sbloccare"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Scorri verso l\'alto per aprire"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Questo dispositivo è gestito dalla tua organizzazione"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Questo dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Scorri per accedere al telefono"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continua ad avvisare"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Disattiva notifiche"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuare a ricevere notifiche da questa app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Silenziose"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Con priorità"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Puoi concentrarti perché le notifiche sono visualizzate solo nell\'area a discesa. Sempre silenziose."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Vengono mostrate le notifiche con priorità bassa. Sempre silenziose."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Vengono mostrate le notifiche con priorità bassa. Sempre silenziose."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Vengono mostrate le notifiche con priorità bassa. Sempre silenziose."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Attirano la tua attenzione con un suono e un\'icona nella barra di stato. Le notifiche sono mostrate nella schermata di blocco."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Modalità silenziosa"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Avvisi"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Favorisce la tua concentrazione grazie all\'assenza di suono o vibrazione."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Richiama la tua attenzione con suono o vibrazione."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Impossibile modificare queste notifiche."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Qui non è possibile configurare questo gruppo di notifiche"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notifica inviata al proxy"</string>
@@ -780,7 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Tieni premuto e trascina per aggiungere riquadri"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Tieni premuto e trascina per riordinare i riquadri"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Trascina qui per rimuovere"</string>
-    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Occorrono almeno <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> riquadri"</string>
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Occorrono almeno <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> schede"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Modifica"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Ora"</string>
   <string-array name="clock_options">
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Sposta in basso a sinistra"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Sposta in basso a destra"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignora"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigazione del sistema aggiornata. Per apportare modifiche, usa le Impostazioni."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Usa le Impostazioni per aggiornare la navigazione del sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/config.xml b/packages/SystemUI/res/values-iw/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-iw/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 0578b5a..3a1525c 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"‏לא ניתן לבצע ניפוי באגים ב-USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"‏למשתמש המחובר לחשבון במכשיר הזה אין אפשרות להפעיל ניפוי באגים ב-USB. כדי להשתמש בתכונה הזו יש לעבור אל המשתמש הראשי."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"‏יציאת ה-USB מושבתת"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"‏כדי להגן על המכשיר שלך מנוזלים או חלקיקים, יציאת ה-USB מושבתת ולא מזהה אביזרים כלל.\n\nתתקבל התראה כשניתן יהיה להשתמש ביציאת ה-USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"‏יציאת USB הופעלה לזיהוי מטענים ואביזרים"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"‏הפעלת USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"מידע נוסף"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"הגדל תצוגה כדי למלא את המסך"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"מתח כדי למלא את המסך"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"צילום מסך"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"המערכת מחפשת את הפנים שלך"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"זיהוי הפנים בוצע"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"מאושר"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"יש להקיש על \'אישור\' לסיום"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"יש לגעת בחיישן טביעות האצבע"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"סמל טביעת אצבע"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"מחפש אותך…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"רשת ספק משתנה"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"פתיחת פרטי סוללה"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> אחוזים של סוללה."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"רמת הטעינה בסוללה: <xliff:g id="PERCENTAGE">%1$s</xliff:g> אחוזים, הזמן הנותר המשוער על סמך השימוש שלך:<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"טעינת סוללה, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"הגדרות מערכת"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"התראות"</string>
@@ -380,8 +380,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"עד הזריחה"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"מופעל בשעה <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"עד <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"עיצוב כהה"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"עיצוב כהה\nלחיסכון בסוללה"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"עיצוב כהה"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"עיצוב כהה\nחיסכון בסוללה"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"‏NFC מושבת"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"‏NFC מופעל"</string>
@@ -404,7 +404,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"התראות בדחיפות נמוכה יותר בהמשך"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"הקש שוב כדי לפתוח"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"החלק מעלה כדי לבטל את הנעילה"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"צריך להחליק כדי לפתוח"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"מכשיר זה מנוהל על ידי הארגון שלך"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"המכשיר הזה מנוהל על ידי <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"החלק מהסמל כדי להפעיל את הטלפון"</string>
@@ -464,10 +464,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"אל תציג שוב"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"נקה הכל"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ניהול"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"התראות שקטות"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ניקוי כל ההתראות השקטות"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"התראות הושהו על ידי מצב \'נא לא להפריע\'"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"התחל כעת"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"אין התראות"</string>
@@ -651,21 +649,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"חסימה"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"כן, המשיכו"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"מזעור"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"שקטה"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"בשקט"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"שליחת התראות"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"המשך שליחת התראות"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"השבתת ההתראות"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"שנמשיך להציג לך התראות מהאפליקציה הזאת?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ברמה מתונה"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"בעדיפות"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"עוזרת לריכוז באמצעות הצגת התראות בלוח ההתראות הנפתח בלבד. תמיד שקטה."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"יופיעו התראות בעדיפות נמוכה. תמיד בשקט."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"יופיעו התראות בעדיפות נמוכה. תמיד בשקט."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"יופיעו התראות בעדיפות נמוכה. תמיד בשקט."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"מעוררת תשומת לב באמצעות צלילים וסמל בשורת הסטטוס. מוצגת במסך הנעילה."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"שקט"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"שליחת התראות"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"עוזרת להתרכז ללא צלילים או רטט."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"מעוררת תשומת לב באמצעות צלילים או רטט."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"לא ניתן לשנות את ההתראות האלה."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"לא ניתן להגדיר כאן את קבוצת ההתראות הזו"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"‏התראה דרך שרת proxy"</string>
@@ -796,8 +789,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"יש ללחוץ ולגרור כדי להוסיף אריחים"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"יש ללחוץ ולגרור כדי לסדר מחדש את האריחים"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"גרור לכאן כדי להסיר"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"יש צורך ב-<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> אריחים לפחות"</string>
     <string name="qs_edit" msgid="2232596095725105230">"עריכה"</string>
     <string name="tuner_time" msgid="6572217313285536011">"שעה"</string>
   <string-array name="clock_options">
@@ -919,8 +911,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"אני רוצה לאשר"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"אני לא מרשה"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"יש להקיש כדי לתזמן את מצב החיסכון בסוללה"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"מומלץ להפעיל את התכונה כשיש סבירות גבוהה שהסוללה תתרוקן"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"לא תודה"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"הופעל תזמון של חיסכון בסוללה"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"מצב חיסכון בסוללה יופעל באופן אוטומטי כשרמת טעינת הסוללה תהיה נמוכה מ-<xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -953,4 +944,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"העברה לפינה השמאלית התחתונה"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"העברה לפינה הימנית התחתונה"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"סגירה"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"הניווט במערכת עודכן. אפשר לערוך שינויים דרך ההגדרות."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"יש לעבור להגדרות כדי לעדכן את הניווט במערכת"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/config.xml b/packages/SystemUI/res/values-ja/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ja/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index a9089d3..51e19a2 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USBデバッグは許可されていません"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"このデバイスに現在ログインしているユーザーでは、USB デバッグを ON にすることはできません。この機能を使用するには、メインユーザーに切り替えてください。"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB ポート無効"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"液体やゴミからデバイスを保護するため、USB ポートは無効になっています。アクセサリの検出は行われません。\n\nUSB ポートを再び安全に使用できるようになりましたらお知らせします。"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB ポートが有効になり、充電器やアクセサリを検出できるようになりました"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB を有効にする"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"詳細"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"画面サイズに合わせて拡大"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"画面サイズに合わせて拡大"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"画面の保存"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"顔を認証中です"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"顔を認証しました"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"確認しました"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"完了するには [確認] をタップしてください"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"指紋認証センサーをタップしてください"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋アイコン"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"顔を認証しています…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"携帯通信会社のネットワークを変更します"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"電池の詳細情報を開きます"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"電池残量: <xliff:g id="NUMBER">%d</xliff:g>パーセント"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"電池残量: <xliff:g id="PERCENTAGE">%1$s</xliff:g>、およそ <xliff:g id="TIME">%2$s</xliff:g> に電池切れ(使用状況に基づく)"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"電池充電中: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"システム設定。"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"日の出まで"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> に ON"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> まで"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ダークテーマ"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ダークテーマ\nバッテリー セーバー"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ダークテーマ"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ダークテーマ\nバッテリー セーバー"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC は無効です"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC は有効です"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"緊急度の低い通知を下に表示"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"開くにはもう一度タップしてください"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"ロック解除するには上にスワイプしてください"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"開くには上にスワイプします"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"このデバイスは組織によって管理されています"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> が管理しています"</string>
     <string name="phone_hint" msgid="4872890986869209950">"右にスワイプして通話"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"次回から表示しない"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"すべて消去"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"サイレント通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"サイレント通知がすべて消去されます"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"サイレント モードにより通知は一時停止中です"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"今すぐ開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"通知はありません"</string>
@@ -532,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"音声の設定"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"折りたたむ"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"自動字幕起こしメディア"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"メディアの自動字幕起こし"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"字幕のヒントを閉じる"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"字幕のオーバーレイ"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"有効にする"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ブロック"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"今後も表示する"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"サイレント"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"音なしで通知"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"アラートを受け取る"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"今後もアラートを受け取る"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"通知を OFF にする"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"このアプリからの通知を今後も表示しますか?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"通知音なし"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"優先"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"プルダウン シェードでのみ通知を確認できます。常に通知音は鳴りません。"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"優先度の低い通知を表示します。常に通知音は鳴りません。"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"優先度の低い通知を表示します。常に通知音は鳴りません。"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"優先度の低い通知を表示します。常に通知音は鳴りません。"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"通知音とステータスバーのアイコンで注意を促します。ロック画面に表示されます。"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"サイレント"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"アラートを受け取る"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"音やバイブレーションが作動しないため、通知に煩わされずに済みます。"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"音やバイブレーションで通知をお知らせします。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"これらの通知は変更できません。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"このグループの通知はここでは設定できません"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"タイルを追加するには長押ししてドラッグ"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"タイルを並べ替えるには長押ししてドラッグ"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"削除するにはここにドラッグ"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"タイルは <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個以上必要です"</string>
     <string name="qs_edit" msgid="2232596095725105230">"編集"</string>
     <string name="tuner_time" msgid="6572217313285536011">"時間"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"許可"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"拒否"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"タップしてバッテリー セーバーのスケジュールを設定"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"電池切れになる可能性が高くなると有効になります"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"いいえ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"バッテリー セーバーのスケジュール設定 ON"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"電池が <xliff:g id="PERCENTAGE">%d</xliff:g>%% を下回ると、バッテリー セーバーが自動的に ON になります。"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"左下に移動"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"右下に移動"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"閉じる"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"システム ナビゲーションを更新しました。変更するには [設定] に移動してください。"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"システム ナビゲーションを更新するには [設定] に移動してください"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/config.xml b/packages/SystemUI/res/values-ka/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ka/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index f4c05a5..058f233 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ხარვეზების გამართვა ნებადართული არაა"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ამ მოწყობილობაზე ამჟამად შესულ მომხმარებელს არ შეუძლია USB ხარვეზების გამართვის ფუნქციის ჩართვა. ამ ფუნქციის გამოსაყენებლად, მიუერთდით მთავარ მომხმარებელს."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB პორტი გათიშულია"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"თქვენი მოწყობილობის სითხის ან ნადებისგან დასაცავად, USB პორტი გათიშულია და ვერცერთი აქსესუარის აღმოჩენას ვერ შეძლებს.\n\nთქვენ მიიღებთ შეტყობინებას, როდესაც USB პორტის გამოყენება კვლავ შესაძლებელი იქნება."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB პორტი ჩართულია დამტენებისა და აქსესუარების აღმოსაჩენად"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB-ის ჩართვა"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"შეიტყვეთ მეტი"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"მასშტაბი შეცვალეთ ეკრანის შესავსებად."</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"გაწიეთ ეკრანის შესავსებად."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ეკრანის ანაბეჭდი"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"მიმდინარეობს თქვენი სახის ძებნა"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"სახის ამოცნობილია"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"დადასტურებული"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"დასასრულებლად შეეხეთ „დადასტურებას“"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"შეეხეთ თითის ანაბეჭდის სენსორს"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"თითის ანაბეჭდის ხატულა"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"მიმდინარეობს თქვენი ძიება…"</string>
@@ -136,9 +135,9 @@
     <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth კავშირი გაწყვეტილია."</string>
     <string name="accessibility_no_battery" msgid="358343022352820946">"ბატარეა დამჯდარია."</string>
     <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ბატარეია ერთ ზოლზეა."</string>
-    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ელემენტი ორ ზოლზე."</string>
-    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ელემენტი სამ ზოლზე."</string>
-    <string name="accessibility_battery_full" msgid="8909122401720158582">"ელემენტი სავსეა."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ბატარეა ორ ზოლზე."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ბატარეა სამ ზოლზე."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"ბატარეა სავსეა."</string>
     <string name="accessibility_no_phone" msgid="4894708937052611281">"ტელეფონი არ არის."</string>
     <string name="accessibility_phone_one_bar" msgid="687699278132664115">"ტელეფონის სიგნალი ერთ ზოლზეა."</string>
     <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"ტელეფონის სიგნალი ორ ზოლზეა."</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ოპერატორის ქსელის შეცვლა"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ბატარეის დეტალების გახსნა"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ბატარეა: <xliff:g id="NUMBER">%d</xliff:g> პროცენტი."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ბატარეა <xliff:g id="PERCENTAGE">%1$s</xliff:g> პროცენტზეა, მოხმარების გათვალისწინებით დარჩა დაახლოებით <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ბატარეა იტენება, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"სისტემის პარამეტრები."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"შეტყობინებები"</string>
@@ -225,7 +225,7 @@
     <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi გამორთულია."</string>
     <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wifi ჩართულია."</string>
     <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"მობილურის <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
-    <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"ელემენტი: <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"ბატარეა: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"თვითმფრინავის რეჟიმი გამორთულია."</string>
     <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"თვითმფრინავის რეჟიმი ჩართულია."</string>
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"თვითმფრინავის რეჟიმი გამოირთო."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"მზის ამოსვლამდე"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"ჩაირთოს <xliff:g id="TIME">%s</xliff:g>-ზე"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g>-მდე"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"მუქი თემა"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"მუქი თემა\nბატარეის დამზოგი"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"მუქი თემა"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"მუქი თემა\nბატარეის დამზოგი"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC გათიშულია"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ჩართულია"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ქვემოთ მითითებულია ნაკლებად სასწრაფო შეტყობინებები"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"შეეხეთ ისევ გასახსნელად"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"გაასრიალეთ ზევით განსაბლოკად"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ამ მოწყობილობას მართავს თქვენი ორგანიზაცია"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ამ მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ტელეფონისთვის გადაფურცლეთ ხატულადან"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"აღარ მაჩვენო"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ყველას გასუფთავება"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"მართვა"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ჩუმი შეტყობინებები"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ყველა ჩუმი შეტყობინების გასუფთავება"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"შეტყობინებები დაპაუზდა „არ შემაწუხოთ“ რეჟიმის მეშვეობით"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"დაწყება ახლავე"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"შეტყობინებები არ არის."</string>
@@ -532,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"ხმის პარამეტრები"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"გავრცობა"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ჩაკეცვა"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"ავტომატური სუბტიტრების მედია"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"მედიის ავტომ. სუბტიტრირება"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"მინიშნება სუბტიტრებისთვის"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"სუბტიტრების გადაფარვა"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"ჩართვა"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"დაბლოკვა"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ჩვენების გაგრძელება"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ჩაკეცვა"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ჩუმი"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"კვლავ ჩუმად ჩვენება"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"გაფრთხილება"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"გაფრთხილების გაგრძელება"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"შეტყობინებების გამორთვა"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"გაგრძელდეს შეტყობინებათა ჩვენება ამ აპიდან?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"მსუბუქი"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"პრიორიტეტული"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"გეხმარებათ იმ შეტყობინებებზე ყურადღების გამახვილებაში, რომლებიც ჩამოსაწევ ფარდაში ჩანს. ყოველთვის ჩუმი."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"აჩვენებს ნაკლებად პრიორიტეტულ შეტყობინებებს. ყოველთვის ჩუმი."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"აჩვენებს ნაკლებად პრიორიტეტულ შეტყობინებებს. ყოველთვის ჩუმი."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"აჩვენებს ნაკლებად პრიორიტეტულ შეტყობინებებს. ყოველთვის ჩუმი."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"იქცევს თქვენს ყურადღებას ხმით &amp; სტატუსის ზოლის ხატულით. ჩნდება ჩაკეტილ ეკრანზე."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ჩუმი"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"გამაფრთხილებელი"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"გეხმარებათ ფოკუსირებაში ხმის ან ვიბრაციის უქონლობის გამო."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"იპყრობს თქვენს ყურადღებას ხმით ან ვიბრაციით."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ამ შეტყობინებების შეცვლა შეუძლებელია."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"შეტყობინებების ამ ჯგუფის კონფიგურირება აქ შეუძლებელია"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"პროქსირებული შეტყობინება"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ჩავლებით გადაიტანეთ ბლოკების დასამატებლად"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ფილების გადაწყობა შეგიძლიათ მათი ჩავლებით გადატანით"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"ამოსაშლელად, ჩავლებით გადმოიტანეთ აქ"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"თქვენ გჭირდებათ მოზაიკის <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ფილა მაინც"</string>
     <string name="qs_edit" msgid="2232596095725105230">"რედაქტირება"</string>
     <string name="tuner_time" msgid="6572217313285536011">"დრო"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"დაშვება"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"უარყოფა"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"შეეხეთ ბატარეის დამზოგის დასაგეგმად"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ჩაირთოს, როცა ბატარეა დაცლის პირას არის"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"არა, გმადლობთ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ბატარეის დამზოგის განრიგი ჩართულია"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ბატარეის დამზოგი ავტომატურად ჩაირთვება, როცა ბატარეა ჩამოსცდება <xliff:g id="PERCENTAGE">%d</xliff:g>%%-ს."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ქვევით და მარცხნივ გადატანა"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"გადაანაცვ. ქვემოთ და მარჯვნივ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"დახურვა"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"სისტემური ნავიგაცია განახლდა. ცვლილებების შესატანად გადადით პარამეტრებზე."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"სისტემური ნავიგაციის გასაახლებლად გადადით პარამეტრებზე"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/config.xml b/packages/SystemUI/res/values-kk/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-kk/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 3e5aac1..1b201dd 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB жөндеу рұқсат етілмеген"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Бұл құрылғыға жаңа кірген пайдаланушы USB түзетуін іске қосылмайды. Бұл мүмкіндікті пайдалану үшін негізгі пайдаланушыға ауысыңыз."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB порты өшірілді"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Құрылғыңызға сұйықтық немесе қоқыс кіріп кетпеуі үшін, USB порты өшірілген және ешқандай керек-жарақты анықтамайды.\n\nUSB портын қайта пайдалануға болатын кезде хабарландыру аласыз."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Зарядтағыштар мен аксессуарларды анықтау үшін USB порты қосылды."</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB қосу"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Толығырақ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Экранды толтыру үшін ұлғайту"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Экранды толтыру үшін созу"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Құрылғы бетіңізді талдап жатыр."</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Бет танылды."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Расталды"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Аяқтау үшін \"Растау\" түймесін түртіңіз."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Саусақ ізін оқу сканерін түртіңіз"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Саусақ ізі белгішесі"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Бет ізделуде…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Оператор желісін өзгерту"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Батарея мәліметтерін ашу"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батарея <xliff:g id="NUMBER">%d</xliff:g> пайыз."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батарея заряды: <xliff:g id="PERCENTAGE">%1$s</xliff:g> пайыз. Пайдалануға байланысты шамамен <xliff:g id="TIME">%2$s</xliff:g> уақытқа жетеді."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батарея зарядталуда, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Жүйе параметрлері."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Хабарлар."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Күн шыққанға дейін"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Қосылу уақыты: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> дейін"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Қараңғы тақырып"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Қараңғы тақырып\nBattery saver"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Қараңғы тақырып"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Қараңғы тақырып\nBattery saver"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC өшірулі"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC қосулы"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Шұғылдығы азырақ хабарландырулар төменде"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ашу үшін қайта түртіңіз"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Құлыпты ашу үшін жоғары сырғытыңыз"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Ашу үшін жоғары қарай сырғытыңыз."</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Бұл құрылғыны ұйым басқарады"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Бұл құрылғыны <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> басқарады"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Телефонды ашу үшін белгішеден әрі қарай сырғытыңыз"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Қайта көрсетпеу"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Барлығын тазалау"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Басқару"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Дыбыссыз хабарландырулар"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Барлық дыбыссыз хабарландыруларды өшіру"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Хабарландырулар \"Мазаламау\" режимінде кідіртілді"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Қазір бастау"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Хабарландырулар жоқ"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Бөгеу"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Көрсету"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Жасыру"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Дыбыссыз"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Хабарландырулар алғым келмейді"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Ескерту"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Хабарландырулар келе берсін"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Хабарландыруларды өшіру"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Осы қолданбаның хабарландырулары көрсетілсін бе?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Дыбыссыз"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Маңызды"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ашылмалы панельдегі хабарландырулар ғана көрсетіледі. Үнемі дыбыссыз режимде болады."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Маңыздылығы төмен хабарландыруларды көрсетеді. Үнемі дыбыссыз режимде болады."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Маңыздылығы төмен хабарландыруларды көрсетеді. Үнемі дыбыссыз режимде болады."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Маңыздылығы төмен хабарландыруларды көрсетеді. Үнемі дыбыссыз режимде болады."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Дыбыс және күй жолағы белгішесі арқылы ескертеді. Құлыптаулы экранда көрсетіледі."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Дыбыссыз"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Ескертулер"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Хабарландырулар келгенде, дыбыс шықпайды не дірілдемейді"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Хабарландырулар келгенде, дыбыс шығады не дірілдейді"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Бұл хабарландыруларды өзгерту мүмкін емес."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Мұндай хабарландырулар бұл жерде конфигурацияланбайды."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси-сервер арқылы жіберілген хабарландыру"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Қажетті элементтерді сүйреп әкеліп қойыңыз"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Элементтердің ретін өзгерту үшін оларды басып тұрып сүйреңіз"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Керексіздерін осы жерге сүйреңіз"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Кемінде <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> бөлшек қажет."</string>
     <string name="qs_edit" msgid="2232596095725105230">"Өңдеу"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Уақыт"</string>
   <string-array name="clock_options">
@@ -884,7 +876,7 @@
     <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Қолданба орнатылмай-ақ ашылды. Толығырақ мәлімет алу үшін түртіңіз."</string>
     <string name="app_info" msgid="6856026610594615344">"Қолданба ақпараты"</string>
     <string name="go_to_web" msgid="2650669128861626071">"Браузерге өту"</string>
-    <string name="mobile_data" msgid="7094582042819250762">"Мобильдік деректер"</string>
+    <string name="mobile_data" msgid="7094582042819250762">"Мобильдік интернет"</string>
     <string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="3241721038678469804">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi өшірулі"</string>
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Рұқсат беру"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Тыйым салу"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Түймені түртіп, Battery Saver функциясын реттеңіз"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Батареяның заряды бітуге жақындағанда қосыңыз."</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Жоқ, рақмет"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Battery Saver кестесі қосылды"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Батарея заряды <xliff:g id="PERCENTAGE">%d</xliff:g>%% деңгейінен төмендегенде, Battery Saver автоматты түрде қосылады."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Төменгі сол жаққа жылжыту"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Төменгі оң жаққа жылжыту"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Жабу"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Жүйе навигациясы жаңартылды. Өзгерту енгізу үшін \"Параметрлер\" бөліміне өтіңіз."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Жүйе навигациясын жаңарту үшін \"Параметрлер\" бөліміне өтіңіз."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/config.xml b/packages/SystemUI/res/values-km/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-km/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 65a8e14..a9ff164 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"មិនអនុញ្ញាតការកែកំហុសតាម USB ទេ"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"អ្នកប្រើ​ដែលបច្ចុប្បន្ន​បានចូលគណនី​នៅលើឧបករណ៍នេះ​មិនអាចបើកការកែកំហុស USB បានទេ។ ដើម្បីប្រើមុខងារនេះ សូមប្តូរទៅអ្នកប្រើចម្បង។"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"បានបិទរន្ធ USB"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ដើម្បី​ការពារ​ឧបករណ៍​របស់អ្នកកុំឱ្យ​ចូលទឹក ឬ​កម្ទេចផ្សេងៗ រន្ធ USB ត្រូវបានបិទ ហើយ​នឹង​មិនស្គាល់​គ្រឿង​បរិក្ខារ​នោះទេ។\n\nអ្នកនឹង​ទទួលបាន​ការជូនដំណឺង នៅពេល​អ្នកអាច​ប្រើប្រាស់​រន្ធ USB ម្ដងទៀត។"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"បាន​បើក​រន្ធ USB ដើម្បី​សម្គាល់​ឆ្នាំងសាក និងគ្រឿងផ្សេងៗ"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"បើក USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ស្វែងយល់​បន្ថែម"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ពង្រីក​​ដើម្បី​ឲ្យ​ពេញ​អេក្រង់"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ទាញ​ដើម្បី​ឲ្យ​ពេញ​អេក្រង់"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"រូបថតអេក្រង់"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"កំពុង​ផ្ទៀងផ្ទាត់​មុខរបស់អ្នក"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"បានផ្ទៀងផ្ទាត់​មុខ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"បានបញ្ជាក់"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ចុច \"បញ្ជាក់\" ដើម្បីបញ្ចប់"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ប៉ះ​ឧបករណ៍​ចាប់ស្នាម​ម្រាមដៃ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"រូបតំណាង​ស្នាម​ម្រាមដៃ"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"កំពុងស្វែងរកអ្នក…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"បណ្តាញ​ក្រុមហ៊ុនសេវាទូរសព្ទ​កំពុងផ្លាស់ប្តូរ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"បើកព័ត៌មានលម្អិតអំពីថ្ម"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ថ្ម <xliff:g id="NUMBER">%d</xliff:g> ភាគរយ។"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ថ្ម <xliff:g id="PERCENTAGE">%1$s</xliff:g> ភាគរយ អាចប្រើបាន​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g> ទៀត ផ្អែក​លើការ​ប្រើប្រាស់​របស់អ្នក"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"កំពុងសាកថ្ម <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ភាគរយ"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ការ​កំណត់​ប្រព័ន្ធ​។"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ការ​ជូន​ដំណឹង។"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"រហូត​ដល់​ពេល​ថ្ងៃរះ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"បើក​នៅម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"រហូតដល់​ម៉ោង <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"រចនាប័ទ្ម​​​ងងឹត"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"រចនាប័ទ្មងងឹត\nកម្មវិធីសន្សំថ្ម"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"រចនាប័ទ្ម​ងងឹត"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"រចនាប័ទ្មងងឹត\nកម្មវិធីសន្សំថ្ម"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"បាន​បិទ NFC"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"បាន​បើក NFC"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ការ​ជូន​ដំណឹង​​មិន​សូវ​បន្ទាន់​ខាង​ក្រោម"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ប៉ះ​ម្ដង​ទៀត ដើម្បី​បើក"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"អូស​ឡើង​លើ ដើម្បី​ដោះ​សោ"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"អូសឡើងលើ​ដើម្បីបើក"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​​របស់ស្ថាប័ន​​អ្នក"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ឧបករណ៍នេះស្ថិតក្រោមការគ្រប់គ្រងរបស់ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"អូសចេញពីរូបតំណាងដើម្បីប្រើទូរស័ព្ទ"</string>
@@ -452,16 +452,14 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"កម្មវិធីសន្សំថ្មបានបើក"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"ការ​បន្ថយ​ការ​ប្រតិបត្តិ និង​ទិន្នន័យ​ផ្ទៃ​ខាងក្រោយ"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"បិទ​កម្មវិធី​សន្សំ​ថ្ម"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"នៅពេល​កំពុងថត ឬបញ្ជូន <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> អាច​ថតព័ត៌មាន​រសើប​ទាំងឡាយ​ដែលបង្ហាញ​នៅលើ​អេក្រង់​របស់អ្នក ឬដែលចាក់ពី​ឧបករណ៍​របស់អ្នក រួមទាំង​ព័ត៌មាន​រសើប​ដូចជា សំឡេង ពាក្យ​សម្ងាត់ ព័ត៌មាន​បង់ប្រាក់ រូបថត និងសារ​ជាដើម។"</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"នៅពេល​កំពុងថត ឬភ្ជាប់ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> អាច​ថតព័ត៌មាន​រសើប​ទាំងឡាយ​ដែលបង្ហាញ​នៅលើ​អេក្រង់​របស់អ្នក ឬដែលចាក់ពី​ឧបករណ៍​របស់អ្នក រួមទាំង​ព័ត៌មាន​រសើប​ដូចជា សំឡេង ពាក្យ​សម្ងាត់ ព័ត៌មាន​បង់ប្រាក់ រូបថត និងសារ​ជាដើម។"</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"នៅពេល​កំពុងថត ឬបញ្ជូន សេវាកម្មដែល​ផ្ដល់មុខងារនេះ​អាចថតព័ត៌មាន​រសើប​ទាំងឡាយ​ដែលបង្ហាញ​នៅលើ​អេក្រង់​របស់អ្នក ឬដែលចាក់​ពីឧបករណ៍​របស់អ្នក រួមទាំង​ព័ត៌មាន​រសើប​ដូចជា សំឡេង ពាក្យ​សម្ងាត់ ព័ត៌មាន​បង់ប្រាក់​ រូបថត និងសារ​ជាដើម។"</string>
-    <string name="media_projection_dialog_title" msgid="8124184308671641248">"បង្ហាញព័ត៌មានរសើប​ អំឡុងពេលបញ្ជូន/ថត"</string>
+    <string name="media_projection_dialog_title" msgid="8124184308671641248">"ការបង្ហាញព័ត៌មានរសើប​ អំឡុងពេលភ្ជាប់/ថត"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"កុំ​បង្ហាញ​ម្ដងទៀត"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"សម្អាត​ទាំងអស់"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"គ្រប់គ្រង"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ការជូនដំណឹង​ស្ងាត់"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"សម្អាត​ការជូនដំណឹង​ស្ងាត់ទាំងអស់"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"ការជូនដំណឹង​បានផ្អាក​ដោយ​មុខងារកុំរំខាន"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ចាប់ផ្ដើម​ឥឡូវ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"គ្មាន​ការ​ជូនដំណឹង"</string>
@@ -532,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"ការកំណត់សំឡេង"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"ពង្រីក"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"បង្រួម"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"ដាក់ចំណងជើងមេឌៀដោយស្វ័យប្រវត្តិ"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"ដាក់អក្សររត់លើមេឌៀដោយស្វ័យប្រវត្តិ"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"គន្លឹះអក្សររត់"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"ការដាក់ត្រួតគ្នា​លើអក្សររត់"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"បើក"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ទប់ស្កាត់"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"បន្ត​បង្ហាញ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"បង្រួម"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ស្ងាត់"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"បន្ត​បិទសំឡេង"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ការជូនដំណឹង"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"បន្ត​ជូនដំណឹង"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"បិទ​ការជូន​ដំណឹង"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"បន្ត​បង្ហាញ​ការជូនដំណឹង​ពីកម្មវិធីនេះ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ស្ងាត់ៗ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ជា​អាទិភាព"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ជួយ​ឱ្យអ្នក​ផ្ដោត​តាមរយៈការជូនដំណឹង​តែនៅក្នុង​ផ្ទាំងជូនដំណឹងធ្លាក់ចុះ​ប៉ុណ្ណោះ។ បិទសំឡេង​ជានិច្ច។"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"បង្ហាញ​ការជូនដំណឹង​អាទិភាព​ខាងក្រោម។ បិទសំឡេង​ជានិច្ច។"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"បង្ហាញ​ការជូនដំណឹង​អាទិភាព​ខាងក្រោម។ បិទសំឡេង​ជានិច្ច។"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"បង្ហាញ​ការជូនដំណឹង​អាទិភាព​ខាងក្រោម។ បិទសំឡេង​ជានិច្ច។"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ធ្វើឱ្យអ្នកចាប់អារម្មណ៍តាមរយៈ​សំឡេង និងរូបរបារស្ថានភាព។ បង្ហាញ​នៅលើ​អេក្រង់ចាក់សោ។"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ស្ងាត់"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"បញ្ចេញ​សំឡេង"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ជួយឱ្យ​អ្នក​ផ្តោតអារម្មណ៍ ដោយមិនឮសំឡេង ឬ​ការញ័រ។"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ធ្វើឱ្យ​អ្នក​ចាប់អារម្មណ៍​តាមរយៈ​សំឡេង ឬ​ការញ័រ។"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"មិនអាច​កែប្រែ​ការជូនដំណឹង​ទាំងនេះ​បានទេ។"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"មិនអាច​កំណត់​រចនាសម្ព័ន្ធ​ក្រុមការជូនដំណឹងនេះ​នៅទីនេះ​បានទេ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ការជូនដំណឹង​ជា​ប្រូកស៊ី"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ចុច​ឱ្យ​ជាប់ រួចអូសដើម្បី​បញ្ចូល​ប្រអប់"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ចុច​ឱ្យ​ជាប់ រួចអូស​ដើម្បី​រៀបចំ​ប្រអប់​ឡើងវិញ"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"អូសទីនេះដើម្បីយកចេញ"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"អ្នក​ត្រូវការ​ប្រអប់​យ៉ាងតិច <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"កែសម្រួល"</string>
     <string name="tuner_time" msgid="6572217313285536011">"ម៉ោង"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"អនុញ្ញាត"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"បដិសេធ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ចុច​ដើម្បី​កំណត់​កាលវិភាគ​កម្មវិធី​សន្សំ​ថ្ម"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"បើក​នៅពេល​ថ្ម​ទំនងជា​អស់"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ទេ អរគុណ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"កាលវិភាគ​កម្មវិធី​សន្សំ​ថ្ម​បាន​បើក​ហើយ"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"កម្មវិធី​សន្សំ​ថ្ម​នឹង​បើក​ដោយ​ស្វ័យ​ប្រវត្តិ​ នៅពេល​ថ្ម​នៅ​សល់​តិច​ជាង <xliff:g id="PERCENTAGE">%d</xliff:g>%% ។"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ផ្លាស់ទីទៅផ្នែកខាងក្រោមខាងឆ្វេង​"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ផ្លាស់ទីទៅផ្នែកខាងក្រោម​ខាងស្ដាំ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ច្រានចោល"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"បានធ្វើ​បច្ចុប្បន្នភាព​ការរុករកក្នុង​ប្រព័ន្ធ។ ដើម្បីធ្វើការផ្លាស់ប្ដូរ សូមចូលទៅ​កាន់ការកំណត់។"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ចូល​ទៅកាន់​ការកំណត់ ដើម្បី​ធ្វើបច្ចុប្បន្នភាព​ការរុករក​ក្នុង​ប្រព័ន្ធ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/config.xml b/packages/SystemUI/res/values-kn/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-kn/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 0c708ed8..e3f3879 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"ನಿಮ್ಮ ಮುಖದ ದೃಢೀಕರಣಕ್ಕಾಗಿ ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ಪೂರ್ಣಗೊಳಿಸಲು ದೃಢೀಕರಿಸಿ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಐಕಾನ್"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ನಿಮಗಾಗಿ ಹುಡುಕಲಾಗುತ್ತಿದೆ…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ವಾಹಕ ನೆಟ್‌ವರ್ಕ್ ಬದಲಾಯಿಸುವಿಕೆ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ಬ್ಯಾಟರಿ ವಿವರಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ಬ್ಯಾಟರಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರತಿಶತ."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ನಿಮ್ಮ ಬಳಕೆಯ ಆಧಾರದ ಮೇಲೆ ಬ್ಯಾಟರಿಯು ಪ್ರತಿಶತ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ರಷ್ಟು ಮತ್ತು <xliff:g id="TIME">%2$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ಬ್ಯಾಟರಿ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ಪ್ರತಿಶತ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ಸಿಸ್ಟಂ ಸೆಟ್ಟಿಂಗ್‌ಗಳು."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ಅಧಿಸೂಚನೆಗಳು."</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"ಸೂರ್ಯೋದಯದ ತನಕ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> ಸಮಯದಲ್ಲಿ"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> ವರೆಗೂ"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ಡಾರ್ಕ್ ಥೀಮ್"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ಡಾರ್ಕ್ ಥೀಮ್\nಬ್ಯಾಟರಿ ಸೇವರ್‌"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ಡಾರ್ಕ್ ಥೀಮ್"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ಡಾರ್ಕ್ ಥೀಮ್\nಬ್ಯಾಟರಿ ಸೇವರ್"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string>
@@ -398,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ಕೆಳಗೆ ಕಡಿಮೆ ಅವಸರದ ಅಧಿಸೂಚನೆಗಳು"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ತೆರೆಯಲು ಮತ್ತೆ ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"ಅನ್‌ಲಾಕ್‌ ಮಾಡಲು ಸ್ವೈಪ್‌ ಮಾಡಿ"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಸಂಸ್ಥೆ ನಿರ್ವಹಿಸುತ್ತಿದೆ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ರಿಂದ ನಿರ್ವಹಿಸಲಾಗಿದೆ"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ಫೋನ್‌ಗಾಗಿ ಐಕಾನ್‌ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ಎಚ್ಚರಿಸುತ್ತಿರಿ"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಿ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ಸಾಮಾನ್ಯ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ಆದ್ಯತೆಗೊಳಿಸಿದ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ಪುಲ್-ಡೌನ್ ಶೇಡ್‌ನಲ್ಲಿರುವ ಅಧಿಸೂಚನೆಗಳ ಕಡೆಗೆ ಮಾತ್ರ ಗಮನಹರಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ. ಯಾವಾಗಲೂ ನಿಶ್ಯಬ್ದ."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ಪ್ರಾಶಸ್ತ್ಯದ ಅಧಿಸೂಚನೆಗಳ ಕೆಳಗೆ ಪ್ರದರ್ಶಿತವಾಗುತ್ತದೆ. ಯಾವಾಗಲೂ ನಿಶ್ಯಬ್ದ."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ಪ್ರಾಶಸ್ತ್ಯದ ಅಧಿಸೂಚನೆಗಳ ಕೆಳಗೆ ಪ್ರದರ್ಶಿತವಾಗುತ್ತದೆ. ಯಾವಾಗಲೂ ನಿಶ್ಯಬ್ದ."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ಪ್ರಾಶಸ್ತ್ಯದ ಅಧಿಸೂಚನೆಗಳ ಕೆಳಗೆ ಪ್ರದರ್ಶಿತವಾಗುತ್ತದೆ. ಯಾವಾಗಲೂ ನಿಶ್ಯಬ್ದ."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ಧ್ವನಿ ಮತ್ತು ಸ್ಥಿತಿ ಪಟ್ಟಿ ಐಕಾನ್ ಮೂಲಕ ನಿಮ್ಮ ಗಮನವನ್ನು ಸೆಳೆಯುತ್ತದೆ. ಲಾಕ್ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ತೋರಿಸುತ್ತದೆ."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ನಿಶ್ಶಬ್ದ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ಎಚ್ಚರಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ಶಬ್ದ ಅಥವಾ ವೈಬ್ರೇಷನ್ ಇರದಂತೆ ನಿಮಗೆ ಗಮನಹರಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ಧ್ವನಿ ಅಥವಾ ವೈಬ್ರೇಷನ್ ಮೂಲಕ ನಿಮ್ಮ ಗಮನವನ್ನು ಸೆಳೆಯುತ್ತದೆ."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ಈ ಗುಂಪಿನ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇಲ್ಲಿ ಕಾನ್ಫಿಗರ್‌ ಮಾಡಲಾಗಿರುವುದಿಲ್ಲ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ಪ್ರಾಕ್ಸಿ ಮಾಡಿದ ಅಧಿಸೂಚನೆಗಳು"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ಸ್ಕ್ರೀನ್‌ನ ಎಡ ಕೆಳಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ಕೆಳಗಿನ ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ವಜಾಗೊಳಿಸಿ"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಷನ್ ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/config.xml b/packages/SystemUI/res/values-ko/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ko/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f187aa5..75af4f1 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB 디버깅이 허용되지 않음"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"현재 이 기기에 로그인한 사용자는 USB 디버깅을 사용 설정할 수 없습니다. 이 기능을 사용하려면 기본 사용자로 전환하세요."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB 포트 비활성화됨"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"기기를 액체나 이물질로부터 보호하기 위해 USB 포트가 사용 중지되었으며 액세서리를 연결할 수 없습니다.\n\nUSB 포트를 다시 안전하게 사용할 수 있게 되면 알려 드리겠습니다."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"충전기와 액세서리를 감지할 수 있도록 USB 포트가 사용 설정됨"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB 사용"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"자세히 알아보기"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"전체화면 모드로 확대"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"전체화면 모드로 확대"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"스크린샷"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"얼굴을 찾는 중"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"얼굴이 인증되었습니다."</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"확인함"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"완료하려면 확인을 탭하세요."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"지문 센서를 터치하세요."</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"지문 아이콘"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"찾는 중..."</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"이동통신사 네트워크 변경"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"배터리 세부정보 열기"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"배터리 <xliff:g id="NUMBER">%d</xliff:g>퍼센트"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"배터리 <xliff:g id="PERCENTAGE">%1$s</xliff:g>퍼센트, 평소 사용량 기준 약 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"배터리 충전 중, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%입니다."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"시스템 설정"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"알림"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"일출까지"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>에"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g>까지"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"어두운 테마"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"어두운 테마\n절전 모드"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"어두운 테마"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"어두운 테마\n절전 모드"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC 사용 중지됨"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC 사용 설정됨"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"아래에 덜 급한 알림 표시"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"다시 탭하여 열기"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"위로 스와이프하여 잠금 해제"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"위로 스와이프하여 열기"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"조직에서 관리하는 기기입니다."</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에서 관리하는 기기입니다."</string>
     <string name="phone_hint" msgid="4872890986869209950">"전화 기능을 사용하려면 아이콘에서 스와이프하세요."</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"다시 표시 안함"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"모두 지우기"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"관리"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"무음 알림"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"무음 알림 모두 삭제"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"방해 금지 모드로 일시중지된 알림"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"시작하기"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"알림 없음"</string>
@@ -532,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"소리 설정"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"펼치기"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"접기"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"자동 자막 미디어"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"미디어 자막 자동 생성"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"자막 팁 닫기"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"캡션 오버레이"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"사용"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"차단"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"계속 표시하기"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"최소화"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"무음"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"계속 무음으로 알림"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"알림"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"계속 알림"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"알림 사용 중지"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"이 앱의 알림을 계속 표시하시겠습니까?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"조용히 표시됨"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"우선순위 지정됨"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"풀다운 창에만 알림을 표시하여 집중에 방해가 되지 않습니다. 항상 음소거됩니다."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"우선순위 알림 아래에 표시됩니다. 항상 음소거됩니다."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"우선순위 알림 아래에 표시됩니다. 항상 음소거됩니다."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"우선순위 알림 아래에 표시됩니다. 항상 음소거됩니다."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"소리 및 상태 표시줄 아이콘으로 주의를 끕니다. 잠금 화면에 표시됩니다."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"무음"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"주의를 끄는 알림"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"소리나 진동 없이 집중할 수 있도록 도와줍니다"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"소리나 진동으로 알립니다."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"이 알림은 수정할 수 없습니다."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"이 알림 그룹은 여기에서 설정할 수 없습니다."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"프록시를 통한 알림"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"길게 터치하고 드래그하여 타일 추가"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"길게 터치하고 드래그하여 타일 재정렬"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"여기로 드래그하여 삭제"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>개 이상의 타일이 필요합니다."</string>
     <string name="qs_edit" msgid="2232596095725105230">"수정"</string>
     <string name="tuner_time" msgid="6572217313285536011">"시간"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"허용"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"거부"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"탭하여 절전 모드 예약"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"배터리가 소진될 것 같으면 사용 설정"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"사용 안함"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"절전 모드 예약 사용 설정됨"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"배터리가 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 아래로 내려가면 절전 모드가 자동으로 켜집니다."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"왼쪽 하단으로 이동"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"오른쪽 하단으로 이동"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"닫기"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"시스템 탐색이 업데이트되었습니다. 변경하려면 설정으로 이동하세요."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"설정으로 이동하여 시스템 탐색을 업데이트하세요."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/config.xml b/packages/SystemUI/res/values-ky/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ky/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index ec99aa4..b094746 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB мүчүлүштүктөрүн оңдоого уруксат жок"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Учурда бул аккаунтта USB аркылуу мүчүлүштүктөрдү оңдоо функциясын иштетүүгө болбойт. Негизги колдонуучунун аккаунтуна кириңиз."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB порту өчүрүлдү"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Түзмөгүңүздүн ичине суюктук же булганч нерселер кирип кетпеши үчүн USB порту өчүрүлдү. Азырынча ал аркылуу башка түзмөктөргө туташууга болбойт.\n\nUSB портун кайра колдонуу мүмкүн болгондо, билдирме аласыз."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Кубаттагычтарды жана аксессуарларды аныктоо үчүн USB оюкчасы иштетилди"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB’ни иштетүү"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Кененирээк"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Экрнд тлтр ү. чен өлч өзг"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Экранды толтуруу ү-н чоюу"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Жүзүңүз изделүүдө"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Жүздүн аныктыгы текшерилди"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Ырасталды"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Бүтүрүү үчүн \"Ырастоо\" баскычын басыңыз"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Манжа изинин сенсорун басыңыз"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Манжа изинин сүрөтчөсү"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Жүзүңүз изделүүдө…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Байланыш оператору өзгөртүлүүдө"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Батареянын чоо-жайын ачуу"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батарея <xliff:g id="NUMBER">%d</xliff:g> пайыз."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батареянын деңгээли <xliff:g id="PERCENTAGE">%1$s</xliff:g> пайыз, колдонгонуңузга караганда болжол менен <xliff:g id="TIME">%2$s</xliff:g> калды"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батарея кубатталууда, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Система тууралоолору."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Билдирмелер"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Күн чыкканга чейин"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Саат <xliff:g id="TIME">%s</xliff:g> күйөт"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> чейин"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Түнкү режим"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Түнкү режим\nБатареяны үнөмдөгүч"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Түнкү режим"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Түнкү режим\nБатареяны үнөмдөгүч"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC өчүрүлгөн"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC иштетилген"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Анчейин шашылыш эмес эскертмелер төмөндө"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ачуу үчүн кайра таптап коюңуз"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Кулпуну ачуу үчүн серпип коюңуз"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Ачуу үчүн өйдө сүрүңүз"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Бул түзмөк уюмуңуз тарабынан башкарылат"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> тарабынан башкарылат"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Сүрөтчөнү серпип телефонго өтүңүз"</string>
@@ -454,14 +454,12 @@
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Батареяны үнөмдөгүч режимин өчүрүү"</string>
     <string name="media_projection_dialog_text" msgid="8585357687598538511">"Жаздырып же тышкы экранга чыгаруу учурунда, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу ойноткон аудиоңуз, сырсөздөрүңүз, төлөө маалыматыңыз, сүрөттөрүңүз жана билдирүүлөрүңүз сыяктуу экранда көрсөтүлгөн купуя маалыматты жаздырып калышы мүмкүн."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Жаздырып же тышкы экранга чыгаруу учурунда, бул функцияны аткарып жаткан колдонмо ойноткон аудиоңуз, сырсөздөрүңүз, төлөө маалыматыңыз, сүрөттөрүңүз жана билдирүүлөрүңүз сыяктуу экранда көрсөтүлгөн купуя маалыматты жаздырып калышы мүмкүн."</string>
-    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Тышкы экранга чыгарууда/жаздырууда купуя маалыматты ачыкка чыгаруу"</string>
+    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Тышкы экранга чыгарууда/жаздырууда купуя маалыматты ачыктоо"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Экинчи көрсөтүлбөсүн"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Бардыгын тазалап салуу"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Башкаруу"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Үнсүз билдирмелер"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Маанилүү эмес билдирмелердин баарын өчүрүү"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\"Тынчымды алба\" режиминде билдирмелер тындырылды"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Азыр баштоо"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Билдирме жок"</string>
@@ -532,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Добуштун жөндөөлөрү"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Жайып көрсөтүү"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Жыйнап коюу"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Медиага автоматтык коштомо жазуу"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Автоматтык коштомо жазуулар"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Коштомо жазуулар кеңеши"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Коштомо жазуулардын үстүнө коюу"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"иштетүү"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Бөгөттөө"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Көрсөтүлө берсин"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Кичирейтүү"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Үнсүз"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Үнү чыкпасын"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Билдирүү"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Кабар бериле берсин"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Билдирмелерди өчүрүү"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Бул колдонмонун эскертмелери көрсөтүлө берсинби?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Маанилүү эмес"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Маанилүү"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Тигинен жайгашкан экрандагы билдирмелерге гана фокустоого жардам берет. Ар дайым үнсүз."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Маанилүү билдирмелердин ылдый жагында чагылдырылат. Ар дайым үнсүз."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Маанилүү билдирмелердин ылдый жагында чагылдырылат. Ар дайым үнсүз."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Маанилүү билдирмелердин ылдый жагында чагылдырылат. Ар дайым үнсүз."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Билдирме келгенде атайын үн чыгат же абал тилкесинде сүрөтчө пайда болот. Билдирмелер кулпуланган экранда көрүнөт."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Үнсүз"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Шашылыш билдирүү"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Үн же дирилдөөсүз ой топтоого жардам берет."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Билдирүүдөн үн чыгат же дирилдейт."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Бул билдирмелерди өзгөртүүгө болбойт."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Бул билдирмелердин тобун бул жерде конфигурациялоого болбойт"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси билдирмеси"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Керектүү элементтерди сүйрөп келиңиз"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Элементтердин иретин өзгөртүү үчүн кармап туруп, сүйрөңүз"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Алып салуу үчүн бул жерге сүйрөңүз"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Сизге жок дегенде <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> мозаика керек"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Түзөтүү"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Убакыт"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Уруксат берүү"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Жок"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Батареяны үнөмдөгүчтүн тартибин жөндөө үчүн басыңыз"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Батареянын кубаты түгөнүп калганда, күйгүзүлсүн"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Жок, рахмат"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Батареяны үнөмдөгүчтүн тартиби күйгүзүлдү"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Батареянын деңгээли <xliff:g id="PERCENTAGE">%d</xliff:g>%% төмөндөгөндө, Батареяны үнөмдөгүч режими автоматтык түрдө күйөт."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Төмөнкү сол жакка жылдыруу"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Төмөнкү оң жакка жылдырыңыз"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Жабуу"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Тутум чабыттоосу жаңыртылды. Өзгөртүү үчүн, Жөндөөлөргө өтүңүз."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Тутум чабыттоосун жаңыртуу үчүн Жөндөөлөргө өтүңүз"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/config.xml b/packages/SystemUI/res/values-lo/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-lo/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 6acbaf5..7bf95b1 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"ບໍ່​ອະ​ນຸ​ຍາດ​ໃຫ້​ມີ​ການ​ແກ້​ໄຂ​ບັນ​ຫາ USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ຜູ້ໃຊ້ທີ່ກຳລັງເຂົ້າສູ່ລະບົບອຸປະກອນຢູ່ໃນຕອນນີ້ບໍ່ສາມາດເປີດໃຊ້ການດີບັກ USB ໄດ້. ເພື່ອໃຊ້ຄຸນສົມບັດນີ້, ໃຫ້ສະຫຼັບໄປໃຊ້ຜູ້ໃຊ້ຫຼັກ."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"ປິດການນຳໃຊ້ຜອດ USB ແລ້ວ"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ເພື່ອປົກປ້ອງອຸປະກອນຂອງທ່ານຈາກຂອງແຫລວ ຫຼື ເສດດິນຕ່າງໆ, ຜອດ USB ຈຶ່ງຖືກປິດການນຳໃຊ້ ແລະ ຈະບໍ່ກວດຫາອຸປະກອນເສີມໃດໆ.\n\nທ່ານຈະໄດ້ຮັບການແຈ້ງເຕືອນເມື່ອສາມາດໃຊ້ຜອດ USB ໄດ້ອີກເທື່ອໜຶ່ງ."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ເປີດນຳໃຊ້ USB ແລ້ວເພື່ອກວດຫາສາຍສາກ ແລະ ອຸປະກອນເສີມ"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"ເປີດໃຊ້ USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ສຶກສາເພີ່ມເຕີມ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ຊູມໃຫ້ເຕັມໜ້າຈໍ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ປັບໃຫ້ເຕັມໜ້າຈໍ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ພາບໜ້າຈໍ"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"ກຳລັງເບິ່ງໃບໜ້າຂອງທ່ານ"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"ພິສູດຢືນຢັນໃບໜ້າແລ້ວ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ຢືນຢັນແລ້ວ"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ແຕະຢືນຢັນເພື່ອສຳເລັດ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ແຕະໃສ່ເຊັນເຊີລາຍນິ້ວມື"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ໄອຄອນລາຍນິ້ວມື"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ກຳລັງຊອກຫາທ່ານ…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ການປ່ຽນເຄືອຂ່າຍຜູ້ໃຫ້ບໍລິການ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ເປີດລາຍລະອຽດແບັດເຕີຣີ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ແບັດເຕີຣີ <xliff:g id="NUMBER">%d</xliff:g> ເປີເຊັນ."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ແບັດເຕີຣີ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ເປີເຊັນ, ເຫຼືອປະມານ <xliff:g id="TIME">%2$s</xliff:g> ອ້າງອີງຈາກການນຳໃຊ້ຂອງທ່ານ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ກຳລັງສາກແບັດເຕີຣີ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ເປີເຊັນ."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ການຕັ້ງຄ່າລະບົບ."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ການແຈ້ງເຕືອນ."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"ຈົນກວ່າຕາເວັນຂຶ້ນ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"ເປີດຕອນ <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"ຈົນກວ່າຈະຮອດ <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ຮູບແບບສີສັນມືດ"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ຮູບແບບສີສັນມືດ\nຕົວປະຢັດແບັດເຕີຣີ"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ຮູບແບບສີສັນມືດ"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ຮູບແບບສີສັນມືດ\nຕົວປະຢັດແບັດເຕີຣີ"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC is disabled"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC is enabled"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ການ​ແຈ້ງເຕືອນ​ທີ່​ສຳຄັນ​ໜ້ອຍ​ກວ່າ​ຢູ່​ດ້ານ​ລຸ່ມ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ແຕະ​ອີກ​ຄັ້ງ​ເພື່ອ​ເປີດ"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"ເລື່ອນ​ຂຶ້ນ​ເພື່ອ​ປົດ​ລັອກ"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍອົງກອນຂອງທ່ານ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ອຸປະກອນນີ້ຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ປັດ​ຈາກ​ໄອ​ຄອນ​ສຳ​ລັບ​ໂທ​ລະ​ສັບ"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ບໍ່​ຕ້ອງ​ສະ​ແດງ​ອີກ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ລຶບລ້າງທັງໝົດ"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ຈັດການ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ການແຈ້ງເຕືອນແບບງຽບ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ລຶບລ້າງການແຈ້ງເຕືອນແບບງຽບທັງໝົດ"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"ຢຸດການແຈ້ງເຕືອນໂດຍໂໝດຫ້າມລົບກວນແລ້ວ"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ເລີ່ມດຽວນີ້"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ບລັອກ"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ສະແດງຕໍ່ໄປ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ຫຍໍ້"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ປິດສຽງ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ສືບຕໍ່ມິດງຽບ"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ການເຕືອນ"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ສືບຕໍ່ແຈ້ງເຕືອນ"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ປິດການແຈ້ງເຕືອນ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ສະແດງການແຈ້ງເຕືອນຈາກແອັບນີ້ຕໍ່ໄປບໍ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ສຸພາບ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ສຳຄັນ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ຊ່ວຍທ່ານມີສະມາທິກກັບການແຈ້ງເຕືອນສະເພາະໃນແຖບເລື່ອນລົງເທົ່ານັ້ນ. ປິດສຽງຕະຫຼອດ."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ສະແດງການແຈ້ງເຕືອນທີ່ຄວາມສຳຄັນຕ່ຳລົງ. ປິດສຽງຕະຫຼອດ."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ສະແດງການແຈ້ງເຕືອນທີ່ຄວາມສຳຄັນຕ່ຳລົງ. ປິດສຽງຕະຫຼອດ."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ສະແດງການແຈ້ງເຕືອນທີ່ຄວາມສຳຄັນຕ່ຳລົງ. ປິດສຽງຕະຫຼອດ."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ດຶງຄວາມສົນໃຈຂອງທ່ານດ້ວຍສຽງ ແລະ ໄອຄອນແຖບສະຖານະ. ສະແດງຢູ່ໜ້າຈໍລັອກ."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ປິດສຽງ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ການເຕືອນ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ຊ່ວຍທ່ານມີສະມາທິໂດຍບໍ່ໃຊ້ສຽງ ຫຼື ການສັ່ນເຕືອນ."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ດຶງຄວາມສົນໃຈຂອງທ່ານດ້ວຍສຽງ ຫຼື ການສັ່ນເຕືອນ."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ບໍ່ສາມາດແກ້ໄຂການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ບໍ່ສາມາດຕັ້ງຄ່າກຸ່ມການແຈ້ງເຕືອນນີ້ຢູ່ບ່ອນນີ້ໄດ້"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ການແຈ້ງເຕືອນແບບພຣັອກຊີ"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ກົດຄ້າງໄວ້ແລ້ວລາກເພື່ອເພີ່ມຊ່ອງ"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ກົດຄ້າງໄວ້ແລ້ວລາກເພື່ອຈັດຮຽງໃໝ່"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"ລາກມາບ່ອນນີ້ເພື່ອລຶບອອກ"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"ທ່ານຍຕ້ອງໃຊ້ຢ່າງໜ້ອຍ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ຊ່ອງ"</string>
     <string name="qs_edit" msgid="2232596095725105230">"ແກ້ໄຂ"</string>
     <string name="tuner_time" msgid="6572217313285536011">"ເວລາ"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"ອະນຸຍາດ"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ປະຕິເສດ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ແຕະເພື່ອຕັ້ງການເປີດຕົວປະຢັດແບັດເຕີຣີ"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ເປີດໃຊ້ເມື່ອແບັດເຕີຣີໜ້າຈະໃກ້ໝົດ"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ບໍ່, ຂອບໃຈ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ຕັ້ງໃຫ້ເປີດຕົວປະຢັດແບັດເຕີຣີແລ້ວ"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ຕົວປະຢັດແບັດເຕີຣີຈະເປີດຂຶ້ນມາໂດຍອັດຕະໂນມັດເມື່ອແບັດເຕີຣີຕ່ຳກວ່າ <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ຍ້າຍຊ້າຍລຸ່ມ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ຍ້າຍຂວາລຸ່ມ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ປິດໄວ້"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ອັບເດດການນຳທາງລະບົບແລ້ວ. ເພື່ອປ່ຽນແປງ, ກະລຸນາໄປທີ່ການຕັ້ງຄ່າ."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ໄປທີ່ການຕັ້ງຄ່າເພື່ອອັບເດດການນຳທາງລະບົບ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/config.xml b/packages/SystemUI/res/values-lt/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-lt/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index ef42272..fb5ec20 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB derinimas neleidžiamas"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Šiuo metu prie įrenginio prisijungęs naudotojas negali įjungti USB derinimo. Kad galėtumėte naudoti šią funkciją, perjunkite į pagrindinį naudotoją."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB prievadas išjungtas"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Siekiant apsaugoti įrenginį nuo skysčių ar smulkių dalelių, USB prievadas buvo išjungtas ir neaptiks jokių priedų.\n\nJums bus pranešta, kai galėsite vėl saugiai naudoti USB prievadą."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB prievadas įgalintas aptikti kroviklius ir priedus"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Įgalinti USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Sužinokite daugiau"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Keisti mast., kad atit. ekr."</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ištempti, kad atit. ekr."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekrano kopija"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Ieškoma veido"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Veidas autentifikuotas"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Patvirtinta"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Paliesk. „Patvirtinti“, kad užbaigtumėte"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Palieskite piršto antspaudo jutiklį"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Piršto antspaudo piktograma"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ieškoma jūsų…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Keičiamas operatoriaus tinklas"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Atidaryti išsamią akumuliatoriaus informaciją"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Akumuliatorius: <xliff:g id="NUMBER">%d</xliff:g> proc."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> proc. akumuliatoriaus energijos – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>, atsižvelgiant į naudojimą"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Įkraunamas akumuliatorius, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemos nustatymai"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pranešimai."</string>
@@ -380,8 +380,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Iki saulėtekio"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Iki <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tamsioji tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tamsioji tema\nAkum. tausojimo priemonė"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tamsioji tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tamsioji tema\nAkumul. tausojimo priemonė"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"ALR"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"ALR išjungtas"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"ALR įjungtas"</string>
@@ -404,7 +404,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mažiau skubūs pranešimai toliau"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Palieskite dar kartą, kad atidarytumėte"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Perbraukite aukštyn, kad atrakintumėte"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Perbraukite aukštyn, kad atidarytumėte"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Šį įrenginį tvarko jūsų organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Šį įrenginį tvarko <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Perbraukite iš telefono piktogramos"</string>
@@ -464,10 +464,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Daugiau neberodyti"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Viską išvalyti"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Tvarkyti"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tylūs pranešimai"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Išvalyti visus tylius pranešimus"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Pranešimai pristabdyti naudojant netrukdymo režimą"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Pradėti dabar"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nėra įspėjimų"</string>
@@ -651,21 +649,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokuoti"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Toliau rodyti"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Sumažinti"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tylūs"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Neskambėti"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Įspėti"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Toliau įspėti"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Išjungti pranešimus"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Toliau rodyti iš šios programos gautus pranešimus?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Netrikdantys"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Pirmenybiniai"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Padeda susikaupti, nes pranešimai pateikiami tik išskleidžiamajame skydelyje. Visada nutildyti."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Pateikiami po prioritetiniais pranešimais. Visada nutildyti."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Pateikiami po prioritetiniais pranešimais. Visada nutildyti."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Pateikiami po prioritetiniais pranešimais. Visada nutildyti."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Dėmesį atkreipia garsas ir būsenos juostos piktograma. Rodomi užrakintame ekrane."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tylūs"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Įspėti"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Padeda atkreipti dėmesį be garso arba vibravimo."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Atkreipia dėmesį garsu arba vibravimu."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Šių pranešimų keisti negalima."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Šios grupės pranešimai čia nekonfigūruojami"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Per tarpinį serverį gautas pranešimas"</string>
@@ -796,8 +789,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Jei norite pridėti išklotinių, laikykite nuspaudę ir vilkite"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Norėdami pertvarkyti išklot., laikykite nuspaudę ir vilkite"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Vilkite čia, jei norite pašalinti"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Turi būti bent <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> išklotinės elem."</string>
     <string name="qs_edit" msgid="2232596095725105230">"Redaguoti"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Laikas"</string>
   <string-array name="clock_options">
@@ -919,8 +911,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Leisti"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Neleisti"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Palietę planuokite akumuliatoriaus tausojimo priemonės veikimą"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Įjunkite, jei akumuliatorius gali greitai išsekti"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, ačiū"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Akumuliatoriaus tausojimo priemonės veikimas suplanuotas"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Akumuliatoriaus tausojimo priemonė bus įjungta automatiškai akumuliatoriaus įkrovai pasiekus mažiau nei <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -953,4 +944,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Perkelti į apačią kairėje"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Perkelti į apačią dešinėje"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Atmesti"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistemos naršymo funkcijos atnaujintos. Jei norite pakeisti, eikite į skiltį „Nustatymai“."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Eikite į skiltį „Nustatymai“, kad atnaujintumėte sistemos naršymo funkcijas"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/config.xml b/packages/SystemUI/res/values-lv/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-lv/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 0666934..581b68a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB atkļūdošana nav atļauta"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Lietotājs, kurš pašlaik ir pierakstījies šajā ierīcē, nevar iespējot USB atkļūdošanu. Lai izmantotu šo funkciju, pārslēdzieties uz galveno lietotāju."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB pieslēgvieta atspējota"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Lai aizsargātu ierīci no šķidruma un gružiem, USB pieslēgvieta ir atspējota un tajā nevarēs noteikt pieslēgtus piederumus.\n\nKad USB pieslēgvietu atkal drīkstēs izmantot, saņemsiet paziņojumu."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB portam ir iespējota uzlādes ierīču un piederumu noteikšana"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Iespējot USB portu"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Uzzināt vairāk"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Tālumm., lai aizp. ekr."</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Stiepiet, lai aizp. ekr."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekrānuzņēmums"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Tiek meklēta jūsu seja"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Seja autentificēta"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Apstiprināts"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Lai pabeigtu, pieskarieties Apstiprināt"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Pieskarieties pirksta nospieduma sensoram"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Pirksta nospieduma ikona"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Notiek jūsu sejas meklēšana…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mobilo sakaru operatora tīkla mainīšana"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Atvērt akumulatora informāciju"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Akumulators: <xliff:g id="NUMBER">%d</xliff:g> procenti"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Akumulatora uzlādes līmenis: <xliff:g id="PERCENTAGE">%1$s</xliff:g> procenti. Ņemot vērā lietojumu, atlikušais laiks ir apmēram <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Notiek akumulatora uzlāde, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistēmas iestatījumi"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Paziņojumi"</string>
@@ -378,8 +378,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Līdz saullēktam"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Plkst. <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Līdz <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tumšais motīvs"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tumšais motīvs\nJaudas taupīšanas režīms"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tumšais motīvs"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tumšais motīvs\nJaudas taupīšanas režīms"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC ir atspējoti"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ir iespējoti"</string>
@@ -402,7 +402,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mazāk steidzami paziņojumi tiek rādīti tālāk"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Pieskarieties vēlreiz, lai atvērtu"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Velciet uz augšu, lai atbloķētu"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Velciet augšup, lai atvērtu"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Šo ierīci pārvalda jūsu organizācija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Šo ierīci pārvalda <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Lai lietotu tālruni, velciet no ikonas"</string>
@@ -461,10 +461,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Vairs nerādīt"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Dzēst visu"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Pārvaldīt"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Klusie paziņojumi"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Notīrīt visus klusos paziņojumus"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Paziņojumi pārtraukti, izmantojot iestatījumu “Netraucēt”"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Sākt tūlīt"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nav paziņojumu"</string>
@@ -648,21 +646,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloķēt"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Turpināt rādīt"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizēt"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Klusums"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Neslēgt skaļumu"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Saņemt brīdinājumus"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Turpināt paziņošanu"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Izslēgt paziņojumus"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vai turpināt rādīt paziņojumus no šīs lietotnes?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Neuzkrītoši"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritāri"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Lai netraucētu jums koncentrēties, paziņojumi tiek rādīti tikai nolaižamajā panelī. Vienmēr bez skaņas."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Tiek rādīts zem prioritārajiem paziņojumiem. Vienmēr bez skaņas."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Tiek rādīts zem prioritārajiem paziņojumiem. Vienmēr bez skaņas."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Tiek rādīts zem prioritārajiem paziņojumiem. Vienmēr bez skaņas."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Lai piesaistītu jūsu uzmanību, tiek atskaņots signāls un tiek rādīta statusa joslas ikona. Paziņojums ir redzams bloķēšanas ekrānā."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Klusums"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Brīdinājumu saņemšana"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Palīdz jums koncentrēties, nenovēršot uzmanību ar skaņu vai vibrāciju."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Jūsu uzmanība tiek piesaistīta ar skaņas vai vibrācijas signālu."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Šos paziņojumus nevar modificēt."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Šeit nevar konfigurēt šo paziņojumu grupu."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Starpniekservera paziņojums"</string>
@@ -791,8 +784,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Lai pievienotu elementus, pieturiet tos un velciet"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Lai pārkārtotu elementus, turiet un velciet tos"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Lai noņemtu vienumus, velciet tos šeit."</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Nepieciešami vismaz <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> elementi"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Rediģēt"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Laiks"</string>
   <string-array name="clock_options">
@@ -914,8 +906,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Atļaut"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Neatļaut"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Pieskarieties, lai iestatītu akumulatora jaudas taupīšanas režīma grafiku"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ieslēgt, ja akumulators var izlādēties"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nē, paldies"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Ieslēgts akumulatora enerģijas taupīšanas režīma grafiks"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Tiklīdz akumulatora uzlādes līmenis būs zemāks nekā <xliff:g id="PERCENTAGE">%d</xliff:g>%%, tiks automātiski ieslēgts akumulatora jaudas taupīšanas režīms."</string>
@@ -948,4 +939,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Pārvietot apakšpusē pa kreisi"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Pārvietot apakšpusē pa labi"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Nerādīt"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistēmas navigācija ir atjaunināta. Lai veiktu izmaiņas, atveriet iestatījumus."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Atveriet iestatījumus, lai atjauninātu sistēmas navigāciju"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/config.xml b/packages/SystemUI/res/values-mk/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-mk/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 38e59b4..d745f8a 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отстранувањето грешки на USB не е дозволено"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Корисникот што моментално е најавен на уредов не може да вклучи отстранување грешки на USB. За да ја користите функцијава, префрлете се на примарниот корисник."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-портата е оневозможена"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"За да го заштитиме уредот од течност или нечистотија, USB-портата е оневозможена и нема да ги открива додатоците.\n\nЌе ве известиме кога ќе биде во ред да ја користите USB-портата повторно."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-портата е овозможена за откривање полначи и додатоци"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Овозможи USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Дознајте повеќе"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Зумирај да се исполни екранот"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Растегни да се исполни екранот"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Слика од екранот"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Го бараме вашето лице"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Лицето е проверено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Потврдено"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Допрете „Потврди“ за да се заврши"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Допрете го сензорот за отпечатоци"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона за отпечатоци"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ве бараме вас…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Променување на мрежата на операторот"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Отвори ги деталите за батеријата"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерија <xliff:g id="NUMBER">%d</xliff:g> проценти."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батерија <xliff:g id="PERCENTAGE">%1$s</xliff:g> отсто, уште околу <xliff:g id="TIME">%2$s</xliff:g> според вашето користење"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Полнење на батеријата, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Поставки на систем."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Известувања"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"До изгрејсонце"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Ќе се вклучи во <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Темна тема"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Темна тема\nШтедач на батерија"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Темна тема"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Темна тема\nШтедач на батерија"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC е оневозможено"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC е овозможено"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Долу се помалку итни известувања"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Допрете повторно за да се отвори"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Повлечете за да се отклучи"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Повлечете за да отворите"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Вашата организација управува со уредов"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Уредов го управува <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Повлечете од иконата за телефонот"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Не покажувај повторно"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Исчисти сè"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Управувајте"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Тивки известувања"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Исчисти ги сите тивки известувања"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Известувањата се паузирани од „Не вознемирувај“"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Започни сега"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нема известувања"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блокирај"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Продолжи да ги прикажуваш"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Минимизирај"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Тивко"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Продолжи со безгласно прикажување"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Предупредувај"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Продолжи да ме предупредуваш"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Исклучи известувања"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Дали да продолжат да се прикажуваат известувања од апликацијава?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Тивко"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Приоритетно"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Не ви го одвлекува вниманието прикажувајќи известувања само во списокот со известувања. Секогаш безгласно."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Се прикажува под приоритетните известувања. Секогаш безгласно."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Се прикажува под приоритетните известувања. Секогаш безгласно."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Се прикажува под приоритетните известувања. Секогаш безгласно."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Ви го привлекува вниманието со звук и икона во статусната лента. Се прикажува на заклучен екран."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Тивко"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Предупредувај"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ви помага да се концентрирате без звук или вибрации."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ви го привлекува вниманието со звук или вибрации."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Овие известувања не може да се изменат"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Оваа група известувања не може да се конфигурира тука"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Известување преку прокси"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Задржете и влечете за да додадете плочки"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Задржете и влечете за да ги преуредите плочките"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Повлечете тука за да се отстрани"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Потребни ви се најмалку <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> плочки"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Измени"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Време"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дозволи"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Одбиј"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Допрете за да закажете „Штедач на батерија“"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Вклучи ако е веројатно дека батеријата ќе се испразни"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Не, фала"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Распоредот за „Штедач на батерија“ е вклучен"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Штедачот на батерија ќе се вклучи автоматски кога батеријата ќе падне под <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Премести долу лево"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Премести долу десно"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Отфрли"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навигацијата на системот е ажурирана. За да извршите промени, одете во „Поставки“."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Одете во „Поставки“ за да ја ажурирате навигацијата на системот"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/config.xml b/packages/SystemUI/res/values-ml/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ml/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 72f5b78..eeaf0f9 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ഡീബഗ്ഗിംഗ് അനുവദനീയമല്ല"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ഉപകരണത്തിൽ ഇപ്പോൾ സൈൻ ഇൻ ചെയ്‌തിരിക്കുന്ന ഉപയോക്താവിന് USB ഡീബഗ്ഗിംഗ് ഓണാക്കാനാകില്ല. ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ പ്രാഥമിക ഉപയോക്താവിലേക്ക് മാറുക."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB പോർട്ട് പ്രവർത്തനരഹിതമാക്കി"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ദ്രാവകത്തിൽ നിന്നോ പൊടിയിൽ നിന്നോ നിങ്ങളുടെ ഉപകരണത്തെ പരിരക്ഷിക്കാനായി USB പോർട്ട് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നതിനാൽ അത് ആക്‌സസറികളൊന്നും തിരിച്ചറിയില്ല.\n\n USB പോർട്ട് വീണ്ടും ഉപയോഗിക്കാനാകുമ്പോൾ നിങ്ങളെ അറിയിക്കും."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ആക്‌സസറികളും ചാർജറുകളും കണ്ടെത്താൻ USB പോർട്ട് പ്രവർത്തനക്ഷമമാക്കുക"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"കൂടുതലറിയുക"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"സ്‌ക്രീനിൽ ഉൾക്കൊള്ളിക്കാൻ സൂം ചെയ്യുക"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"സ്‌ക്രീനിൽ ഉൾക്കൊള്ളിക്കാൻ വലിച്ചുനീട്ടുക"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"സ്‌ക്രീൻഷോട്ട്"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"നിങ്ങളുടെ മുഖത്തിന് വേണ്ടി തിരയുന്നു"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"മുഖം പരിശോധിച്ചുറപ്പിച്ചു"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"സ്ഥിരീകരിച്ചു"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"പൂർത്തിയാക്കാൻ സ്ഥിരീകരിക്കുക ടാപ്പ് ചെയ്യൂ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"വിരലടയാള സെൻസർ സ്‌പർശിക്കുക"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"വിരലടയാള ഐക്കൺ"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"നിങ്ങൾക്കായി തിരയുന്നു…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"കാരിയർ നെറ്റ്‌വർക്ക് മാറ്റൽ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ബാറ്ററി വിശദാംശങ്ങൾ തുറക്കുക"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ബാറ്ററി <xliff:g id="NUMBER">%d</xliff:g> ശതമാനം."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ബാറ്ററി <xliff:g id="PERCENTAGE">%1$s</xliff:g> ശതമാനം, നിങ്ങളുടെ ഉപയോഗത്തിൻ്റെ അടിസ്ഥാനത്തിൽ ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> സമയം കൂടി ശേഷിക്കുന്നു"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ബാറ്ററി ചാർജുചെയ്യുന്നു, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"സിസ്‌റ്റം ക്രമീകരണങ്ങൾ."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"അറിയിപ്പുകൾ."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"സൂര്യോദയം വരെ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>-ന്"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> വരെ"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ഇരുണ്ട തീം"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ഇരുണ്ട തീം\nബാറ്ററി ലാഭിക്കൽ"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ഇരുണ്ട തീം"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ഇരുണ്ട തീം\nബാറ്ററി ലാഭിക്കൽ"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC പ്രവർത്തനരഹിതമാക്കി"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC പ്രവർത്തനക്ഷമമാക്കി"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ആവശ്യം കുറഞ്ഞ അറിയിപ്പുകൾ ചുവടെ നൽകിയിരിക്കുന്നു"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"തുറക്കുന്നതിന് വീണ്ടും ടാപ്പുചെയ്യുക"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"അൺലോക്കുചെയ്യുന്നതിന് മുകളിലേക്ക് സ്വൈപ്പുചെയ്യുക"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ഈ ഉപകരണം മാനേജുചെയ്യുന്നത് നിങ്ങളുടെ സ്ഥാപനമാണ്"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> മാനേജുചെയ്യുന്ന ഉപകരണമാണിത്"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ഫോൺ ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
@@ -452,16 +452,14 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"ബാറ്ററി ലാഭിക്കൽ ഓണാണ്"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്‌ക്കുന്നു"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"ബാറ്ററി ലാഭിക്കൽ ഓഫാക്കുക"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"റെക്കോർഡ് അല്ലെങ്കിൽ കാസ്‌റ്റ് ചെയ്യുന്നതിനിടെ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്‌തതോ ആയ ഓഡിയോ, പാസ്‌വേഡുകൾ, പേയ്മെന്റ് വിവരം, ഫോട്ടോകൾ, സന്ദേശങ്ങൾ എന്നിവ ഉൾപ്പെടെയുള്ള തന്ത്രപ്രധാന വിവരങ്ങൾ ക്യാപ്‌ചർ ചെയ്യാനാവും."</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"റെക്കോർഡ് അല്ലെങ്കിൽ കാസ്‌റ്റ് ചെയ്യുന്നതിനിടെ, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ നിങ്ങളുടെ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്‌തതോ ആയ ഓഡിയോ, പാസ്‌വേഡുകൾ, പേയ്മെന്റ് വിവരം, ഫോട്ടോകൾ, സന്ദേശങ്ങൾ എന്നിവ ഉൾപ്പെടെയുള്ള തന്ത്രപ്രധാന വിവരങ്ങൾ ക്യാപ്‌ചർ ചെയ്യാനാവും."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"റെക്കോർഡ് അല്ലെങ്കിൽ കാസ്‌റ്റ് ചെയ്യുന്നതിനിടെ, ഈ പ്രവർത്തനത്തിനാവശ്യമായ സേവനത്തിന്, നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ഉപകരണത്തിൽ നിന്ന് പ്ലേ ചെയ്‌തതോ ആയ ഓഡിയോ, പാസ്‌വേഡുകൾ, പേയ്മെന്റ് വിവരം, ഫോട്ടോകൾ, സന്ദേശങ്ങൾ എന്നിവ ഉൾപ്പെടെയുള്ള തന്ത്രപ്രധാന വിവരങ്ങൾ ക്യാപ്‌ചർ ചെയ്യാനാവും."</string>
     <string name="media_projection_dialog_title" msgid="8124184308671641248">"കാസ്‌റ്റ്/റെക്കോർഡ് ചെയ്യുമ്പോൾ സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട വിവരം വെളിപ്പെടുത്തുന്നു"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"വീണ്ടും കാണിക്കരുത്"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"എല്ലാം മായ്‌ക്കുക"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"മാനേജ് ചെയ്യുക"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"നിശബ്‌ദ അറിയിപ്പുകൾ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"എല്ലാ നിശബ്‌ദ അറിയിപ്പുകളും മായ്ക്കുക"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'ശല്യപ്പെടുത്തരുത്\' വഴി അറിയിപ്പുകൾ താൽക്കാലികമായി നിർത്തി"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ബ്ലോക്ക് ചെയ്യുക"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"തുടർന്നും കാണിക്കുക"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ചെറുതാക്കുക‍"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"നിശബ്‌ദം"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"നിശബ്‌ദമായ നിലയിൽ തുടരുക"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"മുന്നറിയിപ്പ് നൽകൽ"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"മുന്നറിയിപ്പ് നൽകുന്നത് തുടരുക"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"അറിയിപ്പുകൾ ഓഫാക്കുക"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ഈ ആപ്പിൽ നിന്നുള്ള അറിയിപ്പുകൾ തുടർന്നും കാണിക്കണോ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"സൗമ്യമായ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"മുൻഗണനയുള്ള"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"പുൾ ഡൗൺ ഷെയ്‌ഡിൽ മാത്രമുള്ള അറിയിപ്പുകളിൽ ശ്രദ്ധ കേന്ദ്രീകരിക്കാൻ നിങ്ങളെ സഹായിക്കുന്നു. എപ്പോഴും നിശബ്‌ദം."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"കുറഞ്ഞ പ്രാധാന്യമുള്ള മുൻഗണനാ അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നു. എപ്പോഴും നിശബ്‌ദം."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"കുറഞ്ഞ പ്രാധാന്യമുള്ള മുൻഗണനാ അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നു. എപ്പോഴും നിശബ്‌ദം."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"കുറഞ്ഞ പ്രാധാന്യമുള്ള മുൻഗണനാ അറിയിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നു. എപ്പോഴും നിശബ്‌ദം."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ശബ്‌ദവും സ്‌റ്റാറ്റസ് ബാർ ഐക്കണും ഉപയോഗിച്ച് ശ്രദ്ധ ക്ഷണിക്കുന്നു. ലോക്ക് സ്‌ക്രീനിൽ കാണിക്കും."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"നിശബ്‌ദം"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"മുന്നറിയിപ്പ് നൽകൽ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ശബ്‌ദമോ വൈബ്രേഷനോ ഇല്ലാതെ ശ്രദ്ധ കേന്ദ്രീകരിക്കാൻ നിങ്ങളെ സഹായിക്കുന്നു."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ശബ്‌ദമോ വെെബ്രേഷനോ ഉപയോഗിച്ച് നിങ്ങളുടെ ശ്രദ്ധ ക്ഷണിക്കുന്നു."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ഈ അറിയിപ്പുകൾ പരിഷ്ക്കരിക്കാനാവില്ല."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"അറിയിപ്പുകളുടെ ഈ ഗ്രൂപ്പ് ഇവിടെ കോണ്‍ഫിഗര്‍ ചെയ്യാൻ കഴിയില്ല"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"പ്രോക്‌സി അറിയിപ്പ്"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ടൈലുകൾ ചേർക്കാൻ ക്ലിക്ക് ചെയ്ത് ഇഴയ്‌ക്കുക"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ടൈലുകൾ പുനഃക്രമീകരിക്കാൻ അമർത്തിപ്പിടിച്ച് വലിച്ചിടുക"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"നീക്കംചെയ്യുന്നതിന് ഇവിടെ വലിച്ചിടുക"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"നിങ്ങൾക്ക് ചുരുങ്ങിയത് <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ടൈലുകളെങ്കിലും വേണം"</string>
     <string name="qs_edit" msgid="2232596095725105230">"എഡിറ്റുചെയ്യുക"</string>
     <string name="tuner_time" msgid="6572217313285536011">"സമയം"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"അനുവദിക്കുക"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"നിരസിക്കുക"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ബാറ്ററി ലാഭിക്കൽ ഷെഡ്യൂൾ ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ബാറ്ററി ചാർജ് തീരാൻ സാധ്യതയുണ്ടെങ്കിൽ ഓണാക്കുക"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"വേണ്ട"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ബാറ്ററി ലാഭിക്കൽ ഷെഡ്യൂൾ ഓണാക്കുക"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ബാറ്ററി <xliff:g id="PERCENTAGE">%d</xliff:g>%% ൽ താഴെയാകുമ്പോൾ, ബാറ്ററി ലാഭിക്കൽ സ്വമേധയാ ഓണാകും."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ചുവടെ ഇടതുഭാഗത്തേക്ക് നീക്കുക"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ചുവടെ വലതുഭാഗത്തേക്ക് നീക്കുക"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്‌തു. മാറ്റങ്ങൾ വരുത്താൻ ക്രമീകരണത്തിലേക്ക് പോവുക."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"സിസ്‌റ്റം നാവിഗേഷൻ അപ്‌ഡേറ്റ് ചെയ്യാൻ ക്രമീകരണത്തിലേക്ക് പോവുക"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/config.xml b/packages/SystemUI/res/values-mn/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-mn/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 8f16f8a..bd733ff 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB алдаа засалт хийх боломжгүй"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Энэ төхөөрөмжид нэвтэрсэн хэрэглэгч USB дебаг хийх онцлогийг асаах боломжгүй байна. Энэ онцлогийг ашиглахын тулд үндсэн хэрэглэгч рүү сэлгэнэ үү."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB портыг идэвхгүй болгосон"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Таны төхөөрөмжийг шингэн зүйл эсвэл бохирдлоос хамгаалахын тулд USB портыг идэвхгүй болгосон бөгөөд энэ нь ямар ч дагалдах хэрэгслийг илрүүлэхгүй.\n\nТанд USB портыг дахин ашиглахад аюулгүй болох үед мэдэгдэх болно."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Цэнэглэгч болон нэмэлт хэрэгслийг илрүүлэхийн тулд USB портыг идэвхжүүлсэн"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB-г идэвхжүүлэх"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Нэмэлт мэдээлэл авах"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Дэлгэц дүүргэх бол өсгөнө үү"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Дэлгэц дүүргэх бол татна уу"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Дэлгэцийн зураг дарах"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Таны царайг хайж байна"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Царайг баталгаажууллаа"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Баталгаажсан"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Дуусгахын тулд баталгаажуулахыг товших"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Хурууны хээ мэдрэгчид хүрэх"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Хурууны хээний дүрс тэмдэг"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Таныг хайж байна…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Оператор компанийн сүлжээг өөрчилж байна"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Тэжээлийн дэлгэрэнгүй мэдээллийг нээх"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерей <xliff:g id="NUMBER">%d</xliff:g> хувьтай."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батарей <xliff:g id="PERCENTAGE">%1$s</xliff:g> хувьтай байна. Таны хэрэглээнд тулгуурлан ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батарейг цэнэглэж байна, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Системийн тохиргоо."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Мэдэгдэл."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Нар мандах хүртэл"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>-д"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> хүртэл"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Бараан загвар"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Бараан загвар\nБатарей хэмнэгч"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Бараан загвар"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Бараан загвар\nБатарей хэмнэгч"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC-г цуцалсан"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC-г идэвхжүүлсэн"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Яаралтай биш мэдэгдлүүдийг доор"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Нээхийн тулд дахин товшино уу"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Түгжээг тайлах бол шудрана уу"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Нээхийн тулд дээш шударна уу"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Энэ төхөөрөмжийг таны байгууллага удирдаж байна"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> удирддаг"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Утсыг гаргахын тулд дүрс тэмдгээс шудрах"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Дахиж үл харуулах"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Бүгдийг арилгах"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Удирдах"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Чимээгүй мэдэгдэл"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Бүх чимээгүй мэдэгдлийг арилгах"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Бүү саад бол горимын түр зогсоосон мэдэгдэл"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Одоо эхлүүлэх"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Мэдэгдэл байхгүй"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блоклох"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Харуулсан хэвээр байх"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Багасгах"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Чимээгүй"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Чимээгүй хэвээр харуулах"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Сэрэмжлүүлж байна"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Үргэлжлүүлэн сануулах"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Мэдэгдлийг унтраах"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Энэ аппаас мэдэгдэл харуулсан хэвээр байх уу?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Бага ач холбогдолтой"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Чухал ач холбогдолтой"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Танд зөвхөн доош татдаг сүүдрийн мэдэгдлээр төвлөрөхөд тусалдаг. Үргэлж чимээгүй байна."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Доорх ач холбогдолтой мэдэгдлийг харуулдаг. Үргэлж чимээгүй байна."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Доорх ач холбогдолтой мэдэгдлийг харуулдаг. Үргэлж чимээгүй байна."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Доорх ач холбогдолтой мэдэгдлийг харуулдаг. Үргэлж чимээгүй байна."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Таны анхаарлыг дуу болон статус самбарын дүрс тэмдгээр татдаг. Түгжигдсэн дэлгэц дээр харуулдаг."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Чимээгүй"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Дуутай"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Дуу эсвэл чичиргээгүйгээр танд төвлөрөхөд тусална."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Дуу эсвэл чичиргээгүйгээр таны анхаарлыг татна."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Эдгээр мэдэгдлийг өөрчлөх боломжгүй."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Энэ бүлэг мэдэгдлийг энд тохируулах боломжгүй байна"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Прокси хийсэн мэдэгдэл"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Хавтанд нэмэхийн тулд дараад чирэх"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Хавтангуудыг дахин засварлахын тулд дараад чирнэ үү"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Устгахын тулд энд зөөнө үү"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Танд хамгийн багадаа <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> хавтан шаардлагатай"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Засах"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Цаг"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Зөвшөөрөх"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Татгалзах"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Тэжээл хэмнэгч онцлогийг хуваарилахын тулд товших"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Батарей дуусах гэж байгаа үед асаана уу"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Үгүй, баярлалаа"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Тэжээл хэмнэгч онцлогийн хуваарийг асаасан"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Батарей <xliff:g id="PERCENTAGE">%d</xliff:g>%%-с бага болсон үед Тэжээл хэмнэгч автоматаар асна."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Зүүн доош зөөх"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Баруун доош зөөх"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Үл хэрэгсэх"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Системийн навигацыг шинэчиллээ. Өөрчлөхийн тулд Тохиргоо руу очно уу."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Системийн навигацыг шинэчлэхийн тулд Тохиргоо руу очно уу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/config.xml b/packages/SystemUI/res/values-mr/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-mr/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 0123337..20f638d 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -46,11 +46,11 @@
     <string name="bluetooth_tethered" msgid="7094101612161133267">"ब्लूटूथ टेदर केले"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"इनपुट पद्धती सेट करा"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"वास्तविक कीबोर्ड"</string>
-    <string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अॅक्सेस करण्याची अनुमती द्यायची का?"</string>
-    <string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> अॅक्सेस करण्याची अनुमती द्यायची का?"</string>
+    <string name="usb_device_permission_prompt" msgid="1825685909587559679">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_DEVICE">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची का?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="2465531696941369047">"<xliff:g id="APPLICATION">%1$s</xliff:g> ला <xliff:g id="USB_ACCESSORY">%2$s</xliff:g> अ‍ॅक्सेस करण्याची अनुमती द्यायची का?"</string>
     <string name="usb_device_confirm_prompt" msgid="7440562274256843905">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> हाताळण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे का?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="4333670517539993561">"<xliff:g id="USB_ACCESSORY">%2$s</xliff:g> हाताळण्यासाठी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडायचे का?"</string>
-    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"इंस्टॉल केलेली अॅप्स या USB उपसाधनासह कार्य करत नाहीत. <xliff:g id="URL">%1$s</xliff:g> येथे या उपसाधनाविषयी अधिक जाणून घ्या"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"इंस्टॉल केलेली अ‍ॅप्स या USB उपसाधनासह कार्य करत नाहीत. <xliff:g id="URL">%1$s</xliff:g> येथे या उपसाधनाविषयी अधिक जाणून घ्या"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"USB उपसाधन"</string>
     <string name="label_view" msgid="6304565553218192990">"पहा"</string>
     <string name="always_use_device" msgid="4015357883336738417">"<xliff:g id="USB_DEVICE">%2$s</xliff:g> कनेक्ट केलेली असताना नेहमी <xliff:g id="APPLICATION">%1$s</xliff:g> उघडा"</string>
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB डीबग करण्‍यास अनुमती नाही"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"सध्‍या या डीव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता USB डीबग करणे चालू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी, प्राथमिक वापरकर्त्‍यावर स्विच करा."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB पोर्ट बंद करा"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"तुमच्या डिव्हाइसला ओलावा किंवा धूळीपासून संरक्षित करण्यासाठी, USB पोर्ट बंद आहे आणि अ‍ॅक्सेसरी डिटेक्ट करणार नाही. \n\n तुम्हाला USB पोर्ट पुन्हा वापरणे ठीक आहे तेव्हा सूचित केले जाईल."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"चार्जर आणि अ‍ॅक्सेसरी शोधण्यासाठी USB पोर्ट सुरू केलेले आहे"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB सुरू करा"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"अधिक जाणून घ्या"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"स्क्रीन भरण्यासाठी झूम करा"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"स्क्रीन भरण्यासाठी ताणा"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रीनशॉट"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"तुमचा चेहरा शोधत आहे"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"चेहरा ऑथेंटिकेशन केलेला आहे"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"निश्चित केले"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"पूर्ण करण्यासाठी खात्री करा वर टॅप करा"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फिंगरप्रिंट सेन्सरला स्पर्श करा"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फिंगरप्रिंट आयकन"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"तुमच्यासाठी शोधत आहे…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"वाहक नेटवर्क बदलत आहे"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"बॅटरी तपशील उघडा"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"बॅटरी <xliff:g id="NUMBER">%d</xliff:g> टक्के."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"बॅटरी <xliff:g id="PERCENTAGE">%1$s</xliff:g> टक्के, तुमच्या वापराच्या आधारावर सुमारे <xliff:g id="TIME">%2$s</xliff:g> शिल्लक आहे"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"बॅटरी चार्ज होत आहे, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> टक्के."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"सिस्‍टम सेटिंग्‍ज."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचना."</string>
@@ -376,13 +376,13 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"सूर्योदयापर्यंत"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> वाजता चालू"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> पर्यंत"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"गडद थीम"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"गडद थीम\nबॅटरी सेव्हर"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"गडद थीम"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"गडद थीम\nबॅटरी सेव्हर"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC अक्षम केले आहे"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC सक्षम केले आहे"</string>
     <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"अ‍ॅप्स स्विच करण्यासाठी वर स्वाइप करा"</string>
-    <string name="recents_quick_scrub_onboarding" msgid="2778062804333285789">"अॅप्स वर झटपट स्विच करण्यासाठी उजवीकडे ड्रॅग करा"</string>
+    <string name="recents_quick_scrub_onboarding" msgid="2778062804333285789">"अ‍ॅप्स वर झटपट स्विच करण्यासाठी उजवीकडे ड्रॅग करा"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7171470775439860480">"अवलोकन टॉगल करा."</string>
     <string name="expanded_header_battery_charged" msgid="5945855970267657951">"चार्ज झाली"</string>
     <string name="expanded_header_battery_charging" msgid="205623198487189724">"चार्ज होत आहे"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"खाली कमी तातडीच्या सूचना"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"उघडण्यासाठी पुन्हा टॅप करा"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"अनलॉक करण्यासाठी स्वाइप करा"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"उघडण्यासाठी वर स्वाइप करा"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"हे डिव्हाइस तुमची संस्था व्यवस्थापित करते"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने व्यवस्थापित केले आहे"</string>
     <string name="phone_hint" msgid="4872890986869209950">"फोनसाठी चिन्हावरून स्वाइप करा"</string>
@@ -440,14 +440,14 @@
     <string name="user_logout_notification_text" msgid="3350262809611876284">"वर्तमान वापरकर्ता लॉगआउट करा"</string>
     <string name="user_logout_notification_action" msgid="1195428991423425062">"वापरकर्त्यास लॉगआउट करा"</string>
     <string name="user_add_user_title" msgid="4553596395824132638">"नवीन वापरकर्ता जोडायचा?"</string>
-    <string name="user_add_user_message_short" msgid="2161624834066214559">"तुम्ही एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीने त्यांचे स्थान सेट करणे आवश्यक असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अॅप्स अपडेट करू शकतो."</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"तुम्ही एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीने त्यांचे स्थान सेट करणे आवश्यक असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो."</string>
     <string name="user_limit_reached_title" msgid="7374910700117359177">"वापरकर्ता मर्यादा गाठली"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="1855040563671964242">
       <item quantity="other">तुम्ही <xliff:g id="COUNT">%d</xliff:g> वापरकर्त्यांपर्यंत जोडू शकता.</item>
       <item quantity="one">फक्त एक वापरकर्ता तयार केला जाऊ शकतो.</item>
     </plurals>
     <string name="user_remove_user_title" msgid="4681256956076895559">"वापरकर्त्यास काढायचे?"</string>
-    <string name="user_remove_user_message" msgid="1453218013959498039">"या वापरकर्त्याचे सर्व अॅप्स आणि डेटा काढून टाकला जाईल."</string>
+    <string name="user_remove_user_message" msgid="1453218013959498039">"या वापरकर्त्याचे सर्व अ‍ॅप्स आणि डेटा काढून टाकला जाईल."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"काढा"</string>
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"बॅटरी सेव्‍हर चालू आहे"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"कामगिरी आणि पार्श्वभूमीवरील डेटा कमी करते"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"पुन्हा दर्शवू नका"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सर्व साफ करा"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"व्यवस्थापित करा"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"सायलंट सूचना"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"सर्व सायलंट सूचना साफ करा"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"व्यत्यय आणून नकाद्वारे सूचना थांबवल्या"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"आता सुरू करा"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"सूचना नाहीत"</string>
@@ -492,8 +490,8 @@
     <string name="disable_vpn" msgid="4435534311510272506">"VPN अक्षम करा"</string>
     <string name="disconnect_vpn" msgid="1324915059568548655">"VPN डिस्कनेक्ट करा"</string>
     <string name="monitoring_button_view_policies" msgid="100913612638514424">"धोरणे पहा"</string>
-    <string name="monitoring_description_named_management" msgid="5281789135578986303">"तुमचे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> व्यवस्थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अॅक्सेस, अॅप्स, तुमच्या डिव्हाइस शी संबंधित डेटा आणि तुमच्या डिव्हाइस च्या ठिकाणाची माहिती मॉनिटर करू शकते आणि ती व्यवस्थापित करू शकतो.\n\nआणखी माहितीसाठी, तुमच्या प्रशासकाशी संपर्क साधा."</string>
-    <string name="monitoring_description_management" msgid="4573721970278370790">"तुमचे डिव्हाइस तुमची संस्‍था व्यवस्थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अॅक्सेस, अॅप्स, तुमच्या डिव्हाइस शी संबंधित डेटा आणि तुमच्या डिव्हाइस च्या ठिकाणाची माहिती मॉनिटर करू शकतो आणि ती व्यवस्थापित करू शकतो.\n\nआणखी माहितीसाठी, तुमच्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="monitoring_description_named_management" msgid="5281789135578986303">"तुमचे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> व्यवस्थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अ‍ॅक्सेस, अ‍ॅप्स, तुमच्या डिव्हाइस शी संबंधित डेटा आणि तुमच्या डिव्हाइस च्या ठिकाणाची माहिती मॉनिटर करू शकते आणि ती व्यवस्थापित करू शकतो.\n\nआणखी माहितीसाठी, तुमच्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="monitoring_description_management" msgid="4573721970278370790">"तुमचे डिव्हाइस तुमची संस्‍था व्यवस्थापित करते.\n\nतुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट अ‍ॅक्सेस, अ‍ॅप्स, तुमच्या डिव्हाइस शी संबंधित डेटा आणि तुमच्या डिव्हाइस च्या ठिकाणाची माहिती मॉनिटर करू शकतो आणि ती व्यवस्थापित करू शकतो.\n\nआणखी माहितीसाठी, तुमच्या प्रशासकाशी संपर्क साधा."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="5202023784131001751">"आपल्या संस्थेने या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="4683248196789897964">"आपल्या संस्थेने आपल्या कार्य प्रोफाइलवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
     <string name="monitoring_description_ca_certificate" msgid="7886985418413598352">"या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
@@ -504,7 +502,7 @@
     <string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"तुमचे वैयक्तिक प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
     <string name="monitoring_description_do_header_generic" msgid="96588491028288691">"तुमचे डिव्हाइस <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g> ने व्यवस्थापित केले आहे."</string>
     <string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"तुमचे डिव्हाइस व्यवस्थापित करण्यासाठी <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> वापरते."</string>
-    <string name="monitoring_description_do_body" msgid="3639594537660975895">"तुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट प्रवेश, अॅप्स, आपल्या डिव्हाइशी संबंधित डेटा आणि डिव्हाइसच्या स्थान माहितीचे निरीक्षण आणि व्यवस्थापन करू शकतो."</string>
+    <string name="monitoring_description_do_body" msgid="3639594537660975895">"तुमचा प्रशासक सेटिंग्ज, कॉर्पोरेट प्रवेश, अ‍ॅप्स, आपल्या डिव्हाइशी संबंधित डेटा आणि डिव्हाइसच्या स्थान माहितीचे निरीक्षण आणि व्यवस्थापन करू शकतो."</string>
     <string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
     <string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"अधिक जाणून घ्या"</string>
     <string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"तुम्ही <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जो ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या नेटवर्क क्रियाकलापाचे परीक्षण करू शकतो."</string>
@@ -514,7 +512,7 @@
     <string name="monitoring_description_ca_cert_settings" msgid="5489969458872997092">"विश्वासू क्रेडेंशियल उघडा"</string>
     <string name="monitoring_description_network_logging" msgid="7223505523384076027">"आपल्या प्रशासकाने नेटवर्क लॉगिंग चालू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे निरीक्षण करते.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="monitoring_description_vpn" msgid="4445150119515393526">"तुम्ही VPN कनेक्शन सेट करण्यासाठी अ‍ॅपला परवानगी दिली.\n\nहा अ‍ॅप ईमेल, अ‍ॅप्स आणि वेबसाइटसह, तुमच्या डिव्हाइस आणि नेटवर्क अॅक्टिव्हिटीचे परीक्षण करू शकतो."</string>
-    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"तुमचे कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते.\n\nतुमचा प्रशासक ईमेल, अॅप्स आणि वेबसाइटसह आपल्या नेटवर्क अॅक्टिव्हिटीचे निरीक्षण करण्यास सक्षम आहे.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा.\n\nतुम्ही VPN शी देखील कनेक्ट आहात, जे आपल्या नेटवर्क अॅक्टिव्हिटीचे निरीक्षण करू शकते."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2958019119161161530">"तुमचे कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते.\n\nतुमचा प्रशासक ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्या नेटवर्क अॅक्टिव्हिटीचे निरीक्षण करण्यास सक्षम आहे.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा.\n\nतुम्ही VPN शी देखील कनेक्ट आहात, जे आपल्या नेटवर्क अॅक्टिव्हिटीचे निरीक्षण करू शकते."</string>
     <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
     <string name="monitoring_description_app" msgid="1828472472674709532">"तुम्ही <xliff:g id="APPLICATION">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
     <string name="monitoring_description_app_personal" msgid="484599052118316268">"तुम्ही <xliff:g id="APPLICATION">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जो ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या वैयक्तिक नेटवर्क क्रियाकलापाचे परीक्षण करू शकतो."</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ब्लॉक करा"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"दाखवणे सुरू ठेवा"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"लहान करा"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"सायलंट"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"सायलंट रहा"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"सूचना देत आहे"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"सूचना देत रहा"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"सूचना बंद करा"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"या अ‍ॅपकडील सूचना दाखवणे सुरू ठेवायचे?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"हळू आवाजातील"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"प्राधान्यकृत"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"फक्त पुल डाउन शेडमध्ये सूचनांवर लक्ष केंद्रीत करण्यात मदत करते. नेहमी सायलंट."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"कमी प्राधान्य असलेल्या सूचना दाखवते. नेहमी सायलंट."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"कमी प्राधान्य असलेल्या सूचना दाखवते. नेहमी सायलंट."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"कमी प्राधान्य असलेल्या सूचना दाखवते. नेहमी सायलंट."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"आवाज आणि स्टेटस बार आयकनसह तुमचे लक्ष वेधून घेते. लॉक स्‍क्रीनवर दाखवते."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"सायलंट"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"सूचना देत आहे"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"आवाज किंवा व्हायब्रेशनशिवाय तुम्हाला लक्ष केंद्रित करण्यास मदत करते."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"आवाज किंवा व्हायब्रेशनने तुमचे लक्ष वेधून घेते."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"या सूचनांमध्ये सुधारणा केली जाऊ शकत नाही."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"या सूचनांचा संच येथे कॉन्फिगर केला जाऊ शकत नाही"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रॉक्सी केलेल्या सूचना"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"टाइल जोडण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"टाइलची पुनर्रचना करण्यासाठी धरून ठेवा आणि ड्रॅग करा"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"काढण्यासाठी येथे ड्रॅग करा"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"तुम्हाला किमान <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> टाइलची गरज आहे"</string>
     <string name="qs_edit" msgid="2232596095725105230">"संपादित करा"</string>
     <string name="tuner_time" msgid="6572217313285536011">"वेळ"</string>
   <string-array name="clock_options">
@@ -864,7 +856,7 @@
     <string name="lockscreen_unlock_right" msgid="1529992940510318775">"उजवा शॉर्टकट देखील अनलॉक करतो"</string>
     <string name="lockscreen_none" msgid="4783896034844841821">"काहीही नाही"</string>
     <string name="tuner_launch_app" msgid="1527264114781925348">"<xliff:g id="APP">%1$s</xliff:g> लाँच करा"</string>
-    <string name="tuner_other_apps" msgid="4726596850501162493">"इतर अॅप्स"</string>
+    <string name="tuner_other_apps" msgid="4726596850501162493">"इतर अ‍ॅप्स"</string>
     <string name="tuner_circle" msgid="2340998864056901350">"मंडळ"</string>
     <string name="tuner_plus" msgid="6792960658533229675">"अधिक आयकन"</string>
     <string name="tuner_minus" msgid="4806116839519226809">"उणे आयकन"</string>
@@ -899,7 +891,7 @@
     <string name="running_foreground_services_title" msgid="381024150898615683">"अॅप्‍स बॅकग्राउंडमध्‍ये चालू आहेत"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"बॅटरी आणि डेटा वापराच्‍या तपशीलांसाठी टॅप करा"</string>
     <string name="mobile_data_disable_title" msgid="1068272097382942231">"मोबाइल डेटा बंद करायचा?"</string>
-    <string name="mobile_data_disable_message" msgid="4756541658791493506">"तुम्हाला <xliff:g id="CARRIER">%s</xliff:g> मधून डेटा किंवा इंटरनेटचा अॅक्सेस नसेल. इंटरनेट फक्त वाय-फाय मार्फत उपलब्ध असेल."</string>
+    <string name="mobile_data_disable_message" msgid="4756541658791493506">"तुम्हाला <xliff:g id="CARRIER">%s</xliff:g> मधून डेटा किंवा इंटरनेटचा अ‍ॅक्सेस नसेल. इंटरनेट फक्त वाय-फाय मार्फत उपलब्ध असेल."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6078110473451946831">"तुमचा वाहक"</string>
     <string name="touch_filtered_warning" msgid="8671693809204767551">"अ‍ॅप परवानगी विनंती अस्पष्‍ट करत असल्‍याने, सेटिंग्ज तुमचा प्रतिसाद पडताळू शकत नाहीत."</string>
     <string name="slice_permission_title" msgid="7465009437851044444">"<xliff:g id="APP_0">%1$s</xliff:g> ला <xliff:g id="APP_2">%2$s</xliff:g> चे तुकडे दाखवण्याची अनुमती द्यायची का?"</string>
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"अनुमती द्या"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"नकार द्या"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"बॅटरी बचतकर्ता शेड्यूल करण्यासाठी टॅप करा"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"बॅटरी संपण्याची शक्यता असल्यास सुरू करा"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"नाही नको"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"बॅटरी बचतकर्ता शेड्यूल सुरू केले आहे"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"बॅटरी <xliff:g id="PERCENTAGE">%d</xliff:g>%% पेक्षा खाली गेल्यास बॅटरी सेव्हर आपोआप सुरू होईल."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"तळाशी डावीकडे हलवा"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"तळाशी उजवीकडे हलवा"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"डिसमिस करा"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"सिस्टम नेव्हिगेशन अपडेट केले. बदल करण्यासाठी, सेटिंग्जवर जा."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"सिस्टम नेव्हिगेशन अपडेट करण्यासाठी सेटिंग्जवर जा"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/config.xml b/packages/SystemUI/res/values-ms/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ms/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 024fe62..f58ea18 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Penyahpepijatan USB tidak dibenarkan"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Pengguna yang log masuk ke peranti ini pada masa ini tidak boleh menghidupkan penyahpepijatan USB. Untuk menggunakan ciri ini, tukar kepada pengguna utama."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB dilumpuhkan"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Untuk melindungi peranti anda daripada cecair atau serpihan, port USB dilumpuhkan dan tidak akan mengesan sebarang aksesori.\n\nAnda akan dimaklumi apabila selamat untuk menggunakan port USB lagi."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB didayakan untuk mengesan pengecas dan aksesori"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Dayakan USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Ketahui lebih lanjut"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zum untuk memenuhi skrin"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Regang utk memenuhi skrin"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Tangkapan skrin"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Mencari wajah anda"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Wajah disahkan"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Disahkan"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Ketik Sahkan untuk menyelesaikan"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Sentuh penderia cap jari"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon cap jari"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Mencari anda…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Rangkaian pembawa berubah"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Buka butiran bateri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateri <xliff:g id="NUMBER">%d</xliff:g> peratus."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateri <xliff:g id="PERCENTAGE">%1$s</xliff:g> peratus, tinggal kira-kira <xliff:g id="TIME">%2$s</xliff:g> lagi berdasarkan penggunaan anda"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateri mengecas, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> peratus."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Tetapan sistem."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Pemberitahuan."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hingga matahari terbit"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Dihidupkan pada <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Hingga <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema Gelap"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema Gelap\nPenjimat bateri"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema gelap"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema gelap\nPenjimat bateri"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC dilumpuhkan"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC didayakan"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Pemberitahuan kurang penting di bawah"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ketik lagi untuk membuka"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Leret ke atas untuk membuka kunci"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Leret ke atas untuk buka"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Peranti ini diurus oleh organisasi anda"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Peranti ini diurus oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Leret dari ikon untuk telefon"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Jangan tunjukkan lagi"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Kosongkan semua"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Urus"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Pemberitahuan senyap"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Kosongkan semua pemberitahuan senyap"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Pemberitahuan dijeda oleh Jangan Ganggu"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Mulakan sekarang"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Tiada pemberitahuan"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Sekat"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Terus tunjukkan"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimumkan"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Senyap"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Kekal senyap"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Memaklumi"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Teruskan memberikan makluman"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Matikan pemberitahuan"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Terus tunjukkan pemberitahuan daripada apl ini?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Lembut"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Diutamakan"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Membantu anda fokus dengan memaparkan pemberitahuan sahaja dalam bidai tarik turun. Sentiasa senyap."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Dipaparkan di bawah pemberitahuan keutamaan. Sentiasa senyap."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Dipaparkan di bawah pemberitahuan keutamaan. Sentiasa senyap."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Dipaparkan di bawah pemberitahuan keutamaan. Sentiasa senyap."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Menarik perhatian anda dengan bunyi &amp; ikon bar status. Ditunjukkan pada skrin kunci."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Senyap"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Memaklumi"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Membantu anda fokus tanpa bunyi atau getaran."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Menarik perhatian anda dengan bunyi atau getaran."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Pemberitahuan ini tidak boleh diubah suai."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Kumpulan pemberitahuan ini tidak boleh dikonfigurasikan di sini"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Pemberitahuan berproksi"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Tahan dan seret untuk menambah jubin"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Tahan dan seret untuk mengatur semula jubin"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Seret ke sini untuk mengalih keluar"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Anda memerlukan sekurang-kurangnya <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> jubin"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Edit"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Masa"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Benarkan"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Tolak"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Ketik untuk menjadualkan Penjimat Bateri"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Hidupkan apabila bateri berkemungkinan habis"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Tidak perlu"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Jadual Penjimat Bateri dihidupkan"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Penjimat Bateri akan dihidupkan secara automatik setelah kuasa bateri kurang daripada <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Alihkan ke bawah sebelah kiri"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Alihkan ke bawah sebelah kanan"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ketepikan"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigasi sistem dikemas kini. Untuk membuat perubahan, pergi ke Tetapan."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Pergi ke Tetapan untuk mengemas kini navigasi sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/config.xml b/packages/SystemUI/res/values-my/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-my/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 97bf472..19a9d1c 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"သင့်မျက်နှာကို ရှာနေသည်"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"အတည်ပြုပြီးပြီ"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"အပြီးသတ်ရန်အတွက် \'အတည်ပြုရန်\' ကို တို့ပါ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"လက်ဗွေအာရုံခံကိရိယာကို တို့ပါ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"လက်ဗွေ သင်္ကေတ"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"သင့်ကို ရှာဖွေနေသည်…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ဝန်ဆောင်မှုပေးသူ ကွန်ရက် ပြောင်းလဲနေသည်။"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ဘက်ထရီ အသေးစိတ် အချက်အလက်များကို ဖွင့်ပါ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ဘတ္တရီ <xliff:g id="NUMBER">%d</xliff:g> ရာခိုင်နှုန်း။"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ဘက်ထရီ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ရာခိုင်နှုန်း၊ သင်၏ အသုံးပြုမှုအပေါ် မူတည်၍ <xliff:g id="TIME">%2$s</xliff:g> ခန့်ကျန်သည်"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ဘက်ထရီအားသွင်းနေသည်၊ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%။"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"စနစ်အပြင်အဆင်များ"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"အကြောင်းကြားချက်များ။"</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"နေထွက်ချိန် အထိ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> တွင် ဖွင့်ရန်"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> အထိ"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"မှောင်သည့် အပြင်အဆင်"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"မှောင်သည့် အပြင်အဆင်\nဘက်ထရီ အားထိန်း"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"မှောင်သည့် အပြင်အဆင်"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"မှောင်သည့် အပြင်အဆင်\nဘက်ထရီ အားထိန်း"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC ကို ပိတ်ထားသည်"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ကို ဖွင့်ထားသည်"</string>
@@ -398,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ဖွင့်ရန် ထပ်ပြီး ပုတ်ပါ"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"သော့ဖွင့်ရန် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ဤစက်ပစ္စည်းကို သင်၏အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က စီမံခန့်ခွဲထားပါသည်"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ဖုန်းအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
@@ -450,7 +452,7 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"ဘက်ထရီ အားထိန်းကို ဖွင့်ထားခြင်း"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"လုပ်ကိုင်မှုကို လျှော့ချလျက် နောက်ခံ ဒေတာကို ကန့်သတ်သည်"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"ဘက်ထရီ အားထိန်းကို ပိတ်ရန်"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် အသံ၊ စကားဝှက်၊ ငွေပေးချေမှုဆိုင်ရာ အချက်အလက်၊ ဓာတ်ပုံနှင့် မက်ဆေ့ဂျ်များကဲ့သို့ အရေးကြီးသည့် အချက်အလက်များအပါအဝင် သင့်မျက်နှာပြင်တွင် ပြသထားသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အရေးကြီးသည့် အချက်အလက်မှန်သမျှကို ဖမ်းယူနိုင်ပါသည်။"</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> သည် အသံ၊ စကားဝှက်၊ ငွေပေးချေမှုဆိုင်ရာ အချက်အလက်၊ ဓာတ်ပုံနှင့် မက်ဆေ့ဂျ်များကဲ့သို့ အရေးကြီးသည့် အချက်အလက်များအပါအဝင် ဖန်သားပြင်တွင် ပြသထားသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အရေးကြီးသည့် အချက်အလက်မှန်သမျှကို ဖမ်းယူနိုင်ပါသည်။"</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"အသံဖမ်းနေစဉ် (သို့) ကာစ်လုပ်နေစဉ် ဤလုပ်ဆောင်ချက်ကို ပေးအပ်သည့် ဝန်ဆောင်မှုသည် အသံ၊ စကားဝှက်၊ ငွေပေးချေမှုဆိုင်ရာ အချက်အလက်၊ ဓာတ်ပုံနှင့် မက်ဆေ့ဂျ်များကဲ့သို့ အရေးကြီးသည့် အချက်အလက်များအပါအဝင် သင့်မျက်နှာပြင်တွင် ပြသထားသော (သို့) သင့်စက်တွင် ဖွင့်ထားသော အရေးကြီးသည့် အချက်အလက်မှန်သမျှကို ဖမ်းယူနိုင်ပါသည်။"</string>
     <string name="media_projection_dialog_title" msgid="8124184308671641248">"ကာစ်လုပ်နေစဉ်/အသံဖမ်းနေစဉ် အရေးကြီးသောအချက်အလက်များ ထုတ်ဖော်မိခြင်း"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"နောက်ထပ် မပြပါနှင့်"</string>
@@ -528,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"အသံဆက်တင်များ"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"တိုးချဲ့ရန်"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ခေါက်သိမ်းရန်..."</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"အလိုလို မီဒီယာ စာတန်းထိုးရန်"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"အလိုအလျောက် စာတန်းထိုးရန်"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"စာတန်းအကြံပြုချက်ကို ပိတ်ပါ"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"စာတန်းများ ထပ်ပိုးရန်"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"ဖွင့်ရန်"</string>
@@ -586,7 +588,7 @@
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"အားမသွင်းနေစဉ်တွင် ဘတ်ထရီအဆင့် ရာခိုင်နှုန်းကို အခြေနေပြဘား အိုင်ကွန်တွင် ပြပါ"</string>
     <string name="quick_settings" msgid="10042998191725428">"အမြန် ဆက်တင်များ"</string>
     <string name="status_bar" msgid="4877645476959324760">"အခြေအနေပြနေရာ"</string>
-    <string name="overview" msgid="4018602013895926956">"ခြုံငုံသုံးသပ်ချက်"</string>
+    <string name="overview" msgid="4018602013895926956">"အကျဉ်း"</string>
     <string name="demo_mode" msgid="2532177350215638026">"စနစ် UI စရုပ်ပြမုဒ်"</string>
     <string name="enable_demo_mode" msgid="4844205668718636518">"သရုပ်ပြမုဒ်ကို ဖွင့်ရန်"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"သရုပ်ပြမုဒ် ပြရန်"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ဆက်လက် သတိပေးရန်"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"အကြောင်းကြားချက်များ ပိတ်ရန်"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ဤအက်ပ်ထံမှ အကြောင်းကြားချက်များကို ဆက်ပြလိုပါသလား။"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"မသိမသာ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ဦးစားပေး"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"အပေါ်မှဆွဲချသည့် နေရာတွင်သာ အကြောင်းကြားချက်များကို အာရုံစိုက်ရန် အထောက်ကူပြုပေးသည်။ အမြဲ အသံတိတ်ရန်။"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ဦးစားပေးအကြောင်းကြားချက်များ၏ အောက်တွင်ဖော်ပြသည်။ အမြဲ အသံတိတ်ရန်။"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ဦးစားပေးအကြောင်းကြားချက်များ၏ အောက်တွင်ဖော်ပြသည်။ အမြဲ အသံတိတ်ရန်။"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ဦးစားပေးအကြောင်းကြားချက်များ၏ အောက်တွင်ဖော်ပြသည်။ အမြဲ အသံတိတ်ရန်။"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"အသံ၊ အခြေအနေပြဘား သင်္ကေတတို့ဖြင့် သတိပေးသည်။ လော့ခ်ချထားချိန်မျက်နှာပြင်တွင် ပြသည်။"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"အသံတိတ်ရန်"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"သတိပေးခြင်း"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"အသံ သို့မဟုတ် တုန်ခါမှု မပါဘဲ အာရုံစိုက်နိုင်စေရန် ကူညီပေးသည်။"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"အသံ သို့မဟုတ် တုန်ခါမှုဖြင့် အာရုံစိုက်လာအောင် ပြုလုပ်သည်။"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ဤအကြောင်းကြားချက်များကို ပြုပြင်၍ မရပါ။"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ဤအကြောင်းကြားချက်အုပ်စုကို ဤနေရာတွင် စီစဉ်သတ်မှတ်၍ မရပါ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ပရောက်စီထည့်ထားသော အကြောင်းကြားချက်"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ဘယ်အောက်ခြေသို့ ရွှေ့ရန်"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ညာအောက်ခြေသို့ ရွှေ့ပါ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ပယ်ရန်"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ပြီးပါပြီ။ အပြောင်းအလဲများ ပြုလုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ။"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"စနစ်လမ်းညွှန်ခြင်း အပ်ဒိတ်လုပ်ရန် \'ဆက်တင်များ\' သို့သွားပါ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/config.xml b/packages/SystemUI/res/values-nb/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-nb/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 28eeca9..4288f348 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-feilsøking er ikke tillatt"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Brukeren som for øyeblikket er logget på denne enheten, kan ikke slå på USB-feilsøking. For å bruke denne funksjonen, bytt til hovedbrukeren."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-porten er deaktivert"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"For å beskytte enheten din mot væsker eller rusk er USB-porten deaktivert og kan ikke oppdage tilbehør.\n\nDu blir varslet når det er trygt å bruke USB-porten igjen."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Registrering av ladere og tilbehør er slått på for USB-porten"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Slå på USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Finn ut mer"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom for å fylle skjermen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Strekk for å fylle skjerm"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skjermdump"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Ser etter ansiktet ditt"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Ansiktet er autentisert"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bekreftet"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Trykk på Bekreft for å fullføre"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Trykk på fingeravtrykkssensoren"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon for fingeravtrykk"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Ser etter deg …"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Bytting av operatørnettverk"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Åpne informasjon om batteriet"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri – <xliff:g id="NUMBER">%d</xliff:g> prosent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batterinivået er <xliff:g id="PERCENTAGE">%1$s</xliff:g> prosent – omtrent <xliff:g id="TIME">%2$s</xliff:g> gjenstår basert på bruken din"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteriet lades – <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> prosent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systeminnstillinger."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Varsler."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Til soloppgang"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"På kl. <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Til <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Mørkt tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Mørkt tema\nBatterisparing"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Mørkt tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Mørkt tema\nBatterisparing"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC er slått av"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC er slått på"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende varsler nedenfor"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Trykk på nytt for å åpne"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Sveip oppover for å låse opp"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Sveip opp for å åpne"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Denne enheten administreres av organisasjonen din"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Denne enheten administreres av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Sveip ikonet for å åpne telefon"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ikke vis igjen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Fjern alt"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Administrer"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Lydløse varsler"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Fjern alle lydløse varsler"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Varsler er satt på pause av «Ikke forstyrr»"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start nå"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ingen varsler"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokkér"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Fortsett å vise"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimer"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Lydløs"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Forbli lydløs"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Varsling"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Fortsett å varsle"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Slå av varsler"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vil du fortsette å vise varsler fra denne appen?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskré"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritert"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Hjelper deg med å fokusere, med varsler bare i nedtrekkspanelet. Alltid lydløs."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Vises under prioritetsvarsler. Alltid lydløs."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Vises under prioritetsvarsler. Alltid lydløs."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Vises under prioritetsvarsler. Alltid lydløs."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Får oppmerksomheten din med lyd og et ikon i statusfeltet. Vises på låseskjermen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Lydløs"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Varsling"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hjelper deg med å fokusere uten lyd eller vibrering."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Får oppmerksomheten din med lyd eller vibrering."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Disse varslene kan ikke endres."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Denne varselgruppen kan ikke konfigureres her"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Omdirigert varsel"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Hold og dra for å legge til ruter"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Hold og dra for å flytte på rutene"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Dra hit for å fjerne"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Du trenger minst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> infobrikker"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Endre"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Tid"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Tillat"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Avvis"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Trykk for å planlegge batterisparing"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Slå på når det er sannsynlig at du går tom for batteri"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nei takk"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Tidsplan for batterisparing er slått på"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batterisparing slås på automatisk når batteriet er lavere enn <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Flytt til nederst til venstre"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Flytt til nederst til høyre"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Avvis"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigeringen er oppdatert. For å gjøre endringer, gå til Innstillinger."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Gå til Innstillinger for å oppdatere systemnavigeringen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/config.xml b/packages/SystemUI/res/values-ne/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ne/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index bf18c31..70ebfd8 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB डिबग गर्न अनुमति छैन"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"हाल यस यन्त्रमा साइन इन हुनुभएको प्रयोगकर्ताले USB डिबग सक्रिय गर्न सक्नुहुन्न। यो सुविधाको प्रयोग गर्न प्राथमिक प्रयोगकर्तामा बदल्नुहोस्‌।"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB पोर्ट असक्षम पारियो"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"तपाईंको यन्त्रलाई तरल पदार्थ वा धुलोबाट जोगाउन यसको USB पोर्ट असक्षम पारिएको छ र यसले कुनै पनि सहायक उपकरणहरू पहिचान गर्ने छैन।\n\nउक्त USB पोर्ट फेरि प्रयोग गर्दा हुन्छ भने तपाईंलाई यसबारे सूचित गरिने छ।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"चार्जर तथा सामानहरू पत्ता लगाउन सक्षम पारिएको USB पोर्ट"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB सक्षम पार्नुहोस्"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"थप जान्नुहोस्"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"स्क्रिन भर्न जुम गर्नुहोस्"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"स्क्रिन भर्न तन्काउनुहोस्"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"स्क्रिनसट"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"तपाईंको अनुहार खोज्दै"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"अनुहार प्रमाणीकरण गरियो"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"पुष्टि भयो"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"पूरा गर्नका लागि पुष्टि गर्नुहोस् नामक विकल्पमा ट्याप गर्नुहोस्"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"फिंगरप्रिन्ट सेन्सरमा छुनुहोस्‌"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"फिंगरप्रिन्ट जनाउने आइकन"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"तपाईंलाई खोज्दै…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"सेवा प्रदायकको नेटवर्क परिवर्तन गर्ने आइकन"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ब्याट्री सम्बन्धी विवरणहरूलाई खोल्नुहोस्"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ब्याट्री <xliff:g id="NUMBER">%d</xliff:g> प्रतिशत"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ब्याट्रीको चार्ज <xliff:g id="PERCENTAGE">%1$s</xliff:g> प्रतिशत छ, तपाईंको प्रयोगका आधारमा <xliff:g id="TIME">%2$s</xliff:g> बाँकी छ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ब्याट्री चार्ज हुँदैछ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> प्रतिशत।"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"प्रणाली सेटिङहरू"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"सूचनाहरू।"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"सूर्योदयसम्म"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> मा सक्रिय"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> सम्म"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"अँध्यारो विषयवस्तु"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"अँध्यारो विषयवस्तु\nब्याट्री सेभर"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"अँध्यारो विषयवस्तु"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"अँध्यारो विषयवस्तु\nब्याट्री सेभर"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC लाई असक्षम पारिएको छ"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC लाई सक्षम पारिएको छ"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"तल कम जरुरी सूचनाहरू"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"खोल्न पुनः ट्याप गर्नुहोस्"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"अनलक गर्न स्वाप गर्नुहोस्"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"तपाईंको संगठनले यस यन्त्रलाई व्यवस्थापन गर्दछ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> द्वारा व्यवस्थापन गरिएको छ"</string>
     <string name="phone_hint" msgid="4872890986869209950">"फोनको लागि आइकनबाट स्वाइप गर्नुहोस्"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"फेरि नदेखाउनुहोस्"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"सबै हटाउनुहोस्"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"व्यवस्थित गर्नुहोस्"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"मौन सूचनाहरू"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"सबै मौन सूचनाहरू हटाउनुहोस्"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"बाधा नपुऱ्याउनुहोस् नामक मोडमार्फत पज पारिएका सूचनाहरू"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"अहिले सुरु गर्नुहोस्"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"कुनै सूचनाहरू छैनन्"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"रोक लगाउनुहोस्"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"देखाउने क्रम जारी राख्नुहोस्"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"सानो बनाउनुहोस्"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"मौन"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"मौन रहनुहोस्"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"सतर्क गराउने"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"सर्तक गराइरहनुहोस्"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"सूचनाहरू निष्क्रिय पार्नुहोस्"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"यो अनुप्रयोगका सूचनाहरू देखाउने क्रम जारी राख्ने हो?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"मौन"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"प्राथमिकता दिइएको"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"तपाईंलाई पुल डाउन सेडमा रहेका सूचनाहरूमा मात्र केन्द्रित हुन मद्दत गर्छ। सधैँ मौन।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"न्यून प्राथमिकताका सूचनाहरू देखाउँछ। सधैँ मौन।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"न्यून प्राथमिकताका सूचनाहरू देखाउँछ। सधैँ मौन।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"न्यून प्राथमिकताका सूचनाहरू देखाउँछ। सधैँ मौन।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ध्वनि र वस्तुस्थिति पट्टीको आइकनमार्फत तपाईंको ध्यान खिच्छ। लक स्क्रिनमा देखाउँछ।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"मौन"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"सतर्क गराउँदै"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"तपाईंलाई आवाज वा कम्पनविना ध्यान केन्द्रित गर्न मद्दत गर्छ।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ध्वनि वा कम्पनमार्फत तपाईंको ध्यान आकर्षित गर्छ।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"यी सूचनाहरू परिमार्जन गर्न मिल्दैन।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"यहाँबाट सूचनाहरूको यो समूह कन्फिगर गर्न सकिँदैन"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"प्रोक्सीमार्फत आउने सूचना"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"टाइलहरू थप्न होल्ड गरी ड्र्याग गर्नुहोस्"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"टाइलहरू पुनः क्रमबद्ध गर्न होल्ड गरी ड्र्याग गर्नुहोस्"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"हटाउनका लागि यहाँ तान्नुहोस्"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"तपाईंलाई कम्तीमा <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> वटा टाइल चाहिन्छ"</string>
     <string name="qs_edit" msgid="2232596095725105230">"सम्पादन गर्नुहोस्"</string>
     <string name="tuner_time" msgid="6572217313285536011">"समय"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"अनुमति दिनुहोस्"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"अस्वीकार गर्नु…"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ब्याट्री सेभरको समयतालिका बनाउन ट्याप गर्नुहोस्"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ब्याट्री सकिने सम्भावना भएमा सक्रिय गर्नुहोस्"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"पर्दैन धन्यवाद"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ब्याट्री सेभरको समयतालिका सक्रिय गरियो"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ब्याट्री <xliff:g id="PERCENTAGE">%d</xliff:g>%% भन्दा कम भएको बेला ब्याट्री सेभर स्वतः सक्रिय हुने छ।"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"पुछारमा बायाँतिर सार्नुहोस्"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"पुछारमा दायाँतिर सार्नुहोस्"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"हटाउनुहोस्"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"प्रणालीको नेभिगेसन अद्यावधिक गरियो। परिवर्तन गर्न सेटिङमा जानुहोस्।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"प्रणालीको नेभिगेसन अद्यावधिक गर्न सेटिङमा जानुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index c5f4052..7b55d18 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -46,7 +46,7 @@
     <color name="notification_primary_text_color">@*android:color/notification_primary_text_color_dark</color>
 
     <color name="notification_guts_link_icon_tint">@color/GM2_grey_500</color>
-    <color name="notification_guts_sub_text_color">@color/GM2_grey_500</color>
+    <color name="notification_guts_sub_text_color">@color/GM2_grey_300</color>
     <color name="notification_guts_header_text_color">@color/GM2_grey_200</color>
     <color name="notification_guts_info_button_color">@color/GM2_blue_300</color>
     <color name="notification_guts_priority_button_content_color">@color/GM2_grey_500</color>
@@ -54,7 +54,7 @@
     <color name="notification_guts_priority_button_bg_fill_color">@color/transparent</color>
     <color name="notification_guts_priority_button_bg_fill_color_selected">@color/GM2_grey_800</color>
     <color name="notification_guts_priority_button_bg_stroke_color">@color/GM2_grey_700</color>
-    <color name="notification_guts_priority_button_bg_stroke_color_selected">@color/GM2_grey_700</color>
+    <color name="notification_guts_priority_button_bg_stroke_color_selected">@color/GM2_blue_300</color>
 
     <color name="notification_section_header_label_color">@color/GM2_grey_200</color>
     <color name="notification_section_clear_all_btn_color">@color/GM2_grey_500</color>
diff --git a/packages/SystemUI/res/values-nl/config.xml b/packages/SystemUI/res/values-nl/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-nl/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 0242180..88f5bd4 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-foutopsporing niet toegestaan"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"De gebruiker die momenteel is ingelogd op dit apparaat, kan USB-foutopsporing niet inschakelen. Als je deze functie wilt gebruiken, schakel je naar de primaire gebruiker."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-poort uitgeschakeld"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"De USB-poort is uitgeschakeld en detecteert geen accessoires, zodat je apparaat wordt beschermd tegen vloeistof en vuil.\n\nJe ontvangt een melding wanneer je de USB-poort weer kunt gebruiken."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-poort kan opladers en accessoires detecteren"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB inschakelen"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Meer informatie"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom om scherm te vullen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rek uit v. schermvulling"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Er wordt naar je gezicht gezocht"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Gezicht geverifieerd"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bevestigd"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tik op Bevestigen om te voltooien"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Raak de vingerafdruksensor aan"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Vingerafdrukpictogram"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Jouw gezicht zoeken…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Netwerk van provider wordt gewijzigd"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Accudetails openen"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batterij: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batterij op <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, nog ongeveer <xliff:g id="TIME">%2$s</xliff:g> op basis van je gebruik"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batterij wordt opgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%% procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systeeminstellingen."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meldingen."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Tot zonsopgang"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Aan om <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Tot <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Donker thema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Donker thema\nBatterijbesparing"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Donker thema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Donker thema\nBatterijbesparing"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC is uitgeschakeld"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC is ingeschakeld"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Minder urgente meldingen onderaan"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tik nog eens om te openen"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Veeg omhoog om te ontgrendelen"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Veeg omhoog om te openen"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Dit apparaat wordt beheerd door je organisatie"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Dit apparaat wordt beheerd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Vegen voor telefoon"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Niet opnieuw weergeven"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alles wissen"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Beheren"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Stille meldingen"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Alle stille meldingen wissen"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Meldingen onderbroken door \'Niet storen\'"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Nu starten"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Geen meldingen"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokkeren"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Blijven weergeven"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimaliseren"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Stil"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Stil blijven"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Waarschuwen"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Blijven waarschuwen"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Meldingen uitschakelen"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Meldingen van deze app blijven weergeven?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Vriendelijk"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Met prioriteit"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Helpt je focussen doordat meldingen alleen in het pull-downvenster worden weergegeven. Altijd stil."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Wordt weergegeven onder de prioriteitsmeldingen. Altijd stil."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Wordt weergegeven onder de prioriteitsmeldingen. Altijd stil."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Wordt weergegeven onder de prioriteitsmeldingen. Altijd stil."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Trekt de aandacht met geluid en een pictogram in de statusbalk. Wordt weergegeven op het vergrendelingsscherm."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Stil"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Waarschuwen"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Helpt je focussen zonder geluid of trilling."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Trekt je aandacht met geluid of trillingen."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Deze meldingen kunnen niet worden aangepast."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Deze groep meldingen kan hier niet worden geconfigureerd"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Melding via proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Houd vast en sleep om tegels toe te voegen"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Houd vast en sleep om tegels opnieuw in te delen"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Sleep hier naartoe om te verwijderen"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Je hebt minimaal <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tegels nodig"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Bewerken"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Tijd"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Toestaan"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Weigeren"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tikken om Batterijbesparing in te schakelen"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Inschakelen wanneer de batterij waarschijnlijk leeg raakt"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nee"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Batterijbesparing is ingeschakeld"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batterijbesparing wordt automatisch ingeschakeld wanneer de batterijstatus lager is dan <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Naar linksonder verplaatsen"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Naar rechtsonder verplaatsen"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Sluiten"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systeemnavigatie geüpdatet. Als je wijzigingen wilt aanbrengen, ga je naar Instellingen."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Ga naar Instellingen om de systeemnavigatie te updaten"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-or/config.xml b/packages/SystemUI/res/values-or/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-or/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 7e0f68f..7bc49ce 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USBରେ ଡିବଗ୍‍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ସମ୍ପ୍ରତି ସାଇନ୍‍-ଇନ୍‍ କରିଥିବା ୟୁଜର୍‍ ଜଣକ ଏହି ଡିଭାଇସରେ USB ଡିବଗିଙ୍ଗ ଅନ୍‍ କରିପାରିବେ ନାହିଁ। ଏହି ବୈଶିଷ୍ଟ୍ୟ ବ୍ୟବହାର କରିବାକୁ, ପ୍ରାଥମିକ ୟୁଜର୍‍ରେ ସାଇନ୍‍-ଇନ୍‍ କରନ୍ତୁ।"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB ପୋର୍ଟକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ଆପଣଙ୍କ ଡିଭାଇସ୍‌କୁ ତରଳ ପଦାର୍ଥ ଏବଂ ଧୂଳିରୁ ସୁରକ୍ଷିତ ରଖିବା ପାଇଁ, USB ପୋର୍ଟକୁ ଅକ୍ଷମ କରାଯାଇଛି ଏବଂ ଏହା କୌଣସି ଉପକରଣ ଚିହ୍ନଟ କରିବ ନାହିଁ। \n\n ଯେତେବେଳେ USB ପୋର୍ଟ ପୁଣିି ବ୍ୟବହାର କରିବାକୁ ସୁରକ୍ଷିତ ହେବ, ସେତେବେଳେ ଆପଣଙ୍କୁ ସୂଚିତ କରାଯିବ।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ଚାର୍ଜର୍‍ ଏବଂ ଆକ୍ସେସରିଗୁଡ଼ିକୁ ଚିହ୍ନଟ କରିବାକୁ USB ପୋର୍ଟ ସକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB ସକ୍ଷମ କରନ୍ତୁ"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ସ୍କ୍ରୀନ ଭରିବା ପାଇଁ ଜୁମ୍ କରନ୍ତୁ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ସ୍କ୍ରୀନ୍‌କୁ ଭରିବା ପାଇଁ ଟାଣନ୍ତୁ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ସ୍କ୍ରୀନଶଟ୍‌"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"ଆପଣଙ୍କର ମୁହଁକୁ ପ୍ରମାଣ କରୁଛି"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"ମୁହଁ ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ସୁନିଶ୍ଚିତ କରାଯାଇଛି"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ସୁନିଶ୍ଚିତ କରନ୍ତୁରେ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ଟିପଚିହ୍ନ ସେନସର୍‌କୁ ଛୁଅଁନ୍ତୁ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ଆଙ୍ଗୁଠି ଚିହ୍ନ ଆଇକନ୍"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ଆପଣଙ୍କୁ ଚିହ୍ନଟ କରୁଛି…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"କେରିଅର୍‍ ନେଟ୍‌ୱର୍କ ବଦଳୁଛି"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ବ୍ୟାଟେରୀ ବିବରଣୀ ଖୋଲନ୍ତୁ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ବ୍ୟାଟେରୀ <xliff:g id="NUMBER">%d</xliff:g> ଶତକଡ଼ା ଅଛି।"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ବ୍ୟାଟେରୀ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ଶତକଡା, ଆପଣଙ୍କର ବ୍ୟବହାରକୁ ଆଧାର କରି ପାଖାପାଖି <xliff:g id="TIME">%2$s</xliff:g> ବାକି ଅଛି"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ବ୍ୟାଟେରୀ ଚାର୍ଜ ହେଉଛି, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ଶତକଡ଼ା।"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ସିଷ୍ଟମ୍‍ ସେଟିଙ୍ଗ।"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ବିଜ୍ଞପ୍ତି"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"ସୂର୍ଯ୍ୟୋଦୟ ପର୍ଯ୍ୟନ୍ତ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>ରେ ଅନ୍ ହେବ"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ଗାଢ଼ା ଥିମ୍"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ଗାଢ଼ା ଥିମ୍‍\nବ୍ୟାଟେରୀ ସେଭର୍"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ଗାଢ଼ ଥିମ୍"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ଗାଢ଼ ଥିମ୍\nବ୍ୟାଟେରୀ ସେଭର୍"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC ଅକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ସକ୍ଷମ କରାଯାଇଛି"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ନିମ୍ନରେ କମ୍‍ ଜରୁରୀ ବିଜ୍ଞପ୍ତି"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ଖୋଲିବା ପାଇଁ ପୁଣି ଟାପ୍‍ କରନ୍ତୁ"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"ଅନଲକ୍‌ କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍‌ କରନ୍ତୁ"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ଏହି ଡିଭାଇସ୍‌ ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ।"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ଏହି ଡିଭାଇସ୍‌ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ହେଉଛି"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ଫୋନ୍‍ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
@@ -453,15 +453,13 @@
     <string name="battery_saver_notification_text" msgid="820318788126672692">"କାର୍ଯ୍ୟ ସମ୍ପାଦନ ଓ ବ୍ୟାକ୍‌ଗ୍ରାଉଣ୍ଡ ଡାଟା କମ୍ କରନ୍ତୁ"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅଫ୍‍ କରନ୍ତୁ"</string>
     <string name="media_projection_dialog_text" msgid="8585357687598538511">"ରେକର୍ଡିଂ କିମ୍ବା କାଷ୍ଟିଂ ସମୟରେ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ଯେ କୌଣସି ସମ୍ବେଦନଶୀଳ ସୂଚନା କ୍ୟାପଚର୍ କରିପାରିବ ଯାହା ଅଡ଼ିଓ, ପାସ୍‌ୱାର୍ଡ, ପେମେଣ୍ଟ ସୂଚନା, ଫଟୋ ଏବଂ ମେସେଜ୍‌ଗୁଡ଼ିକ ପରି ସମ୍ବେଦନଶୀଳ ସୂଚନା ଆପଣଙ୍କର ଡିଭାଇସ୍‌ରେ ଚାଲିବ ବା ଆପଣଙ୍କ ସ୍କ୍ରିନ୍‌ରେ ଦେଖାଯିବ।"</string>
-    <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"ରେକର୍ଡିଂ କିମ୍ବା କାଷ୍ଟିଂ ସମୟରେ ସେବା ପ୍ରଦାନ କରୁଥିବା ଏହି ଫଙ୍କ୍‌ସନ୍ ଯେ କୌଣସି ସମ୍ବେଦନଶୀଳ ସୂଚନା କ୍ୟାପଚର୍ କରିପାରିବ ଯାହା ଅଡ଼ିଓ, ପାସ୍‌ୱାର୍ଡ, ପେମେଣ୍ଟ ସୂଚନା, ଫଟୋ ଏବଂ ମେସେଜ୍‌ଗୁଡ଼ିକ ପରି ସମ୍ବେଦନଶୀଳ ସୂଚନା ଆପଣଙ୍କର ଡିଭାଇସ୍‌ରେ ଚାଲିବ ବା ଆପଣଙ୍କ ସ୍କ୍ରିନ୍‌ରେ ଦେଖାଯିବ।"</string>
+    <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"ରେକର୍ଡିଂ କିମ୍ବା କାଷ୍ଟିଂ ସମୟରେ ଏହି ପ୍ରକାର୍ଯ୍ୟ ପ୍ରଦାନ କରୁଥିବା ସେବା ଅଡ଼ିଓ, ପାସ୍‌ୱାର୍ଡ, ପେମେଣ୍ଟ ସୂଚନା, ଫଟୋ ଏବଂ ମେସେଜ୍‌ଗୁଡ଼ିକ ପରି ସମ୍ବେଦନଶୀଳ ସୂଚନା କ୍ୟାପଚର୍ କରିପାରିବ ଯାହା ଆପଣଙ୍କର ଡିଭାଇସ୍‌ରେ ଚାଲିବ ବା ଆପଣଙ୍କ ସ୍କ୍ରିନ୍‌ରେ ଦେଖାଯିବ।"</string>
     <string name="media_projection_dialog_title" msgid="8124184308671641248">"କାଷ୍ଟିଂ/ରେକର୍ଡିଂ ସମୟରେ ସମ୍ବେଦନଶୀଳ ସୂଚନା ଦେଖାନ୍ତୁ"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ପୁଣି ଦେଖାନ୍ତୁ ନାହିଁ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ସମସ୍ତ ଖାଲି କରନ୍ତୁ"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ପରିଚାଳନା କରନ୍ତୁ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ସମସ୍ତ ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଖାଲି କରନ୍ତୁ"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ବିକଳ୍ପ ଦ୍ୱାରା ବିଜ୍ଞପ୍ତି ପଜ୍‍ ହୋଇଛି"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ବ୍ଲକ୍ କରନ୍ତୁ"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ଦେଖାଇବା ଜାରି ରଖନ୍ତୁ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ଛୋଟ କରନ୍ତୁ"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ନୀରବ"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ନୀରବ ରହନ୍ତୁ"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ଆଲର୍ଟ କରିବା"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ଆଲର୍ଟ କରିବା ଜାରି ରଖନ୍ତୁ"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ବିଜ୍ଞପ୍ତି ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ଏହି ଆପ୍‌ରୁ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଦେଖାଇବା ଜାରି ରଖିବେ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ଧିରେ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ପ୍ରାଥମିକତା ଭିତ୍ତିକ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"କେବଳ ପୁଲ୍-ଡାଉନ୍ ସେଡ୍‌ରେ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଉପରେ ଫୋକସ୍ ରହିବା ପାଇଁ ଆପଣଙ୍କୁ ସାହାଯ୍ୟ କରିଥାଏ। ସର୍ବଦା ନୀରବ।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ପ୍ରାଥମିକତା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ତଳେ ଡିସ୍‌ପ୍ଲେ ହୁଏ। ସର୍ବଦା ନିରବ।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ପ୍ରାଥମିକତା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ତଳେ ଡିସ୍‌ପ୍ଲେ ହୁଏ। ସର୍ବଦା ନିରବ।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ପ୍ରାଥମିକତା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ତଳେ ଡିସ୍‌ପ୍ଲେ ହୁଏ। ସର୍ବଦା ନିରବ।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ସାଉଣ୍ଡ୍ ଏବଂ ଏକ ଷ୍ଟାଟସ୍ ବାର୍ ଆଇକନ୍ ମାଧ୍ୟମରେ ଆପଣଙ୍କର ଧ୍ୟାନ ଆକର୍ଷିତ କରିଥାଏ। ଲକ୍ ସ୍କ୍ରିନ୍‌ରେ ଦେଖାଯାଇଥାଏ।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ନୀରବ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ଆଲର୍ଟ କରିବା"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ବିନା ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍‌ରେ ଆପଣଙ୍କୁ ଫୋକସ୍ କରିବାରେ ସାହାଯ୍ୟ କରେ।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ସାଉଣ୍ଡ କିମ୍ବା ଭାଇବ୍ରେସନ୍ ମାଧ୍ୟମରେ ଆପଣଙ୍କର ଧ୍ୟାନ ଆକର୍ଷିତ କରିଥାଏ।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ପରିବର୍ତ୍ତନ କରିହେବ ନାହିଁ।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ଏଠାରେ ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ଗ୍ରୁପ୍ କନଫ୍ୟୁଗର୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ବିଜ୍ଞପ୍ତି ପ୍ରକ୍ସୀ ହୋଇଛି"</string>
@@ -755,7 +748,7 @@
     <string name="accessibility_data_saver_on" msgid="8454111686783887148">"ଡାଟା ସେଭର୍‌ ଅନ୍‌ ଅଛି"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"ଡାଟା ସେଭର୍‍ ଅଫ୍ ଅଛି"</string>
     <string name="switch_bar_on" msgid="1142437840752794229">"ଅନ୍"</string>
-    <string name="switch_bar_off" msgid="8803270596930432874">"ଅଫ୍"</string>
+    <string name="switch_bar_off" msgid="8803270596930432874">"ବନ୍ଦ"</string>
     <string name="nav_bar" msgid="1993221402773877607">"ନାଭିଗେଶନ୍ ବାର୍‍"</string>
     <string name="nav_bar_layout" msgid="3664072994198772020">"ଲେଆଉଟ୍"</string>
     <string name="left_nav_bar_button_type" msgid="8555981238887546528">"ସମ୍ପୂର୍ଣ୍ଣ ବାମ ବଟନ୍‍ ପ୍ରକାର"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ଟାଇଲ୍ ଯୋଡ଼ିବା ପାଇଁ ଦାବିଧରି ଟାଣନ୍ତୁ"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ଟାଇଲ୍‍ ପୁଣି ସଜାଇବାକୁ ଦାବିଧରି ଟାଣନ୍ତୁ"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"ବାହାର କରିବାକୁ ଏଠାକୁ ଡ୍ରାଗ୍‍ କରନ୍ତୁ"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"ଆପଣଙ୍କର ଅତିକମ୍‌ରେ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>ଟି ଟାଇଲ୍ ଆବଶ୍ୟକ"</string>
     <string name="qs_edit" msgid="2232596095725105230">"ଏଡିଟ୍‌ କରନ୍ତୁ"</string>
     <string name="tuner_time" msgid="6572217313285536011">"ସମୟ"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ଅସ୍ଵୀକାର କରନ୍ତୁ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅନ୍‌ ହେବାର ସମୟ ସେଟ୍‌ କରିବାକୁ ଟାପ୍‌ କରନ୍ତୁ"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ବ୍ୟାଟେରୀ ସରିବାକୁ ଥିବା ସମୟରେ ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ନାହିଁ, ଥାଉ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ଆଗରୁ ସେଟ୍‌ କରିଥିବା ସମୟ ଅନୁସାରେ ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅନ୍‌ ହୋଇଛି"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ଚାର୍ଜ <xliff:g id="PERCENTAGE">%d</xliff:g>%%ରୁ କମ୍‌ ହେଲେ ବ୍ୟାଟେରୀ ସେଭର୍‌ ଆପେ ଅନ୍‌ ହୋଇଯିବ।"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ତଳ ବାମକୁ ନିଅନ୍ତୁ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ତଳ ଡାହାଣକୁ ନିଅନ୍ତୁ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ଖାରଜ କରନ୍ତୁ"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ ହୋଇଛି। ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ, ସେଟିଂସ୍‌କୁ ଯାଆନ୍ତୁ।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ଅପ୍‌ଡେଟ୍ କରିବା ପାଇଁ ସେଟିଂସ୍‍କୁ ଯାଆନ୍ତୁ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/config.xml b/packages/SystemUI/res/values-pa/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-pa/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index ba0ac4f..64e2d09 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB ਡਿਬੱਗਿੰਗ ਦੀ ਆਗਿਆ ਨਹੀਂ"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB ਪੋਰਟ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨੂੰ ਪਾਣੀ ਅਤੇ ਧੂੜ-ਮਿੱਟੀ ਤੋਂ ਬਚਾਉਣ ਲਈ, USB ਪੋਰਟ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ ਅਤੇ ਕੋਈ ਵੀ ਐਕਸੈਸਰੀ ਪਛਾਣੀ ਨਹੀਂ ਜਾਵੇਗੀ।\n\nUSB ਪੋਰਟ ਨੂੰ ਦੁਬਾਰਾ ਵਰਤਣਾ ਠੀਕ ਹੋਣ \'ਤੇ ਤੁਹਾਨੂੰ ਸੂਚਿਤ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ਚਾਰਜਰਾਂ ਅਤੇ ਉਪਸਾਧਨਾਂ ਦੀ ਪਛਾਣ ਕਰਨ ਲਈ USB ਪੋਰਟ ਚਾਲੂ ਹੈ"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB ਚਾਲੂ ਕਰੋ"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ਹੋਰ ਜਾਣੋ"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ਸਕ੍ਰੀਨ ਭਰਨ ਲਈ ਜ਼ੂਮ ਕਰੋ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ਸਕ੍ਰੀਨ ਭਰਨ ਲਈ ਸਟ੍ਰੈਚ ਕਰੋ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਲਵੋ"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"ਤੁਹਾਡਾ ਚਿਹਰਾ ਲੱਭਿਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"ਚਿਹਰਾ ਪ੍ਰਮਾਣੀਕਿਰਤ ਹੋਇਆ"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ਪੁਸ਼ਟੀ ਕੀਤੀ ਗਈ"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"ਪੂਰਾ ਕਰਨ ਲਈ ਪੁਸ਼ਟੀ ਕਰੋ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਪ੍ਰਤੀਕ"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ਤੁਹਾਡੀ ਪਛਾਣ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"ਕੈਰੀਅਰ ਨੈੱਟਵਰਕ ਦੀ ਬਦਲੀ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"ਬੈਟਰੀ ਵੇਰਵੇ ਖੋਲ੍ਹੋ"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"ਬੈਟਰੀ <xliff:g id="NUMBER">%d</xliff:g> ਪ੍ਰਤੀਸ਼ਤ ਹੈ।"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"ਬੈਟਰੀ <xliff:g id="PERCENTAGE">%1$s</xliff:g> ਫ਼ੀਸਦ, ਤੁਹਾਡੀ ਵਰਤੋਂ ਦੇ ਆਧਾਰ \'ਤੇ ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"ਬੈਟਰੀ ਚਾਰਜ ਹੋ ਰਹੀ ਹੈ, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> ਪ੍ਰਤੀਸ਼ਤ।"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"ਸਿਸਟਮ ਸੈਟਿੰਗਾਂ।"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"ਸੂਚਨਾਵਾਂ।"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"ਸੂਰਜ ਚੜ੍ਹਨ ਤੱਕ"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> ਵਜੇ ਚਾਲੂ"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> ਤੱਕ"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ਗੂੜ੍ਹਾ ਥੀਮ"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ਗੂੜ੍ਹਾ ਥੀਮ\nਬੈਟਰੀ ਸੇਵਰ"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ਗੂੜ੍ਹਾ ਥੀਮ"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ਗੂੜ੍ਹਾ ਥੀਮ\nਬੈਟਰੀ ਸੇਵਰ"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ਨੂੰ ਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"ਅਣਲਾਕ ਕਰਨ ਲਈ ਉੱਪਰ ਸਵਾਈਪ ਕਰੋ।"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਸੰਗਠਨ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ਫ਼ੋਨ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ਦੁਬਾਰਾ ਨਾ ਦਿਖਾਓ"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ਸਾਰੀਆਂ ਖਾਮੋਸ਼ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ਹੁਣ ਚਾਲੂ ਕਰੋ"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"ਬਲਾਕ ਕਰੋ"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖੋ"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ਛੋਟਾ ਕਰੋ"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ਖਾਮੋਸ਼"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ਚੁੱਪ ਰਹੋ"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"ਸੁਚੇਤਨਾ"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ਸੁਚੇਤ ਰਖੋ"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ਸੂਚਨਾਵਾਂ ਬੰਦ ਕਰੋ"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ਕੀ ਇਸ ਐਪ ਤੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ਸਰਲ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ਤਰਜੀਹੀ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ਸਿਰਫ਼ ਹੇਠਾਂ ਖਿੱਚੀ ਜਾਣ ਵਾਲੀ ਸੂਚੀ ਵਿਚਲੀਆਂ ਸੂਚਨਾਵਾਂ ਨਾਲ ਧਿਆਨ ਦੇਣ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਹਮੇਸ਼ਾਂ ਖਮੋਸ਼।"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੀਆਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ। ਹਮੇਸ਼ਾਂ ਖਮੋਸ਼।"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੀਆਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ। ਹਮੇਸ਼ਾਂ ਖਮੋਸ਼।"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੀਆਂ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ। ਹਮੇਸ਼ਾਂ ਖਮੋਸ਼।"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ਧੁਨੀ ਅਤੇ ਸਥਿਤੀ ਪੱਟੀ ਪ੍ਰਤੀਕ ਨਾਲ ਤੁਹਾਡਾ ਧਿਆਨ ਖਿੱਚਦੀ ਹੈ। ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਾਓ।"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"ਸ਼ਾਂਤ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ਸੁਚੇਤਨਾ"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ਤੁਹਾਨੂੰ ਬਿਨਾਂ ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਦੇ ਫੋਕਸ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰਦਾ ਹੈ।"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ਧੁਨੀ ਅਤੇ ਥਰਥਰਾਹਟ ਨਾਲ ਤੁਹਾਡਾ ਧਿਆਨ ਖਿੱਚਦੀ ਹੈ।"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਸੋਧਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ਇਹ ਸੂਚਨਾਵਾਂ ਦਾ ਗਰੁੱਪ ਇੱਥੇ ਸੰਰੂਪਿਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ਇੱਕ ਐਪ ਦੀ ਥਾਂ \'ਤੇ ਦੂਜੀ ਐਪ ਰਾਹੀਂ ਦਿੱਤੀ ਗਈ ਸੂਚਨਾ"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ਟਾਇਲਾਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਫੜ੍ਹ ਕੇ ਰੱਖੋ ਅਤੇ ਘਸੀਟੋ"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ਟਾਇਲਾਂ ਨੂੰ ਮੁੜ-ਵਿਵਸਥਿਤ ਕਰਨ ਲਈ ਫੜ੍ਹ ਕੇ ਘਸੀਟੋ"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"ਹਟਾਉਣ ਲਈ ਇੱਥੇ ਘਸੀਟੋ"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"ਤੁਹਾਨੂੰ ਘੱਟੋ-ਘੱਟ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ਟਾਇਲਾਂ ਦੀ ਲੋੜ ਪਵੇਗੀ"</string>
     <string name="qs_edit" msgid="2232596095725105230">"ਸੰਪਾਦਨ ਕਰੋ"</string>
     <string name="tuner_time" msgid="6572217313285536011">"ਸਮਾਂ"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"ਕਰਨ ਦਿਓ"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"ਬੈਟਰੀ ਸੇਵਰ ਦੀ ਸਮਾਂ-ਸੂਚੀ ਤਿਆਰ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"ਬੈਟਰੀ ਖਤਮ ਹੋਣ ਦੀ ਸੰਭਾਵਨਾ \'ਤੇ ਚਾਲੂ ਹੁੰਦਾ ਹੈ"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"ਬੈਟਰੀ ਸੇਵਰ ਸਮਾਂ-ਸੂਚੀ ਚਾਲੂ ਕੀਤੀ ਗਈ"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"ਬੈਟਰੀ ਦਾ ਪੱਧਰ <xliff:g id="PERCENTAGE">%d</xliff:g>%% ਤੋਂ ਘੱਟ ਹੋ ਜਾਣ \'ਤੇ ਬੈਟਰੀ ਸੇਵਰ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਚਾਲੂ ਹੋ ਜਾਵੇਗਾ।"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ਹੇਠਾਂ ਵੱਲ ਖੱਬੇ ਲਿਜਾਓ"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ਹੇਠਾਂ ਵੱਲ ਸੱਜੇ ਲਿਜਾਓ"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ਖਾਰਜ ਕਰੋ"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਅੱਪਡੇਟ ਹੋ ਗਿਆ। ਤਬਦੀਲੀਆਂ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਅੱਪਡੇਟ ਕਰਨ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/config.xml b/packages/SystemUI/res/values-pl/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-pl/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 0af942d..8463773 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Debugowanie USB jest niedozwolone"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Użytkownik obecnie zalogowany na tym urządzeniu nie może włączyć debugowania USB. Aby użyć tej funkcji, przełącz się na użytkownika głównego."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB wyłączony"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Aby chronić urządzenie przed wilgocią i zanieczyszczeniami, port USB został wyłączony i nie wykryje żadnych akcesoriów.\n\nOtrzymasz powiadomienie, gdy będzie można znów używać portu."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Port USB włączony, by wykrywać ładowarki i akcesoria"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Włącz USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Więcej informacji"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Powiększ, aby wypełnić ekran"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Rozciągnij, aby wypełnić ekran"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Zrzut ekranu"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Szukam Twojej twarzy"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Twarz rozpoznana"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potwierdzono"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Aby zakończyć, kliknij Potwierdź"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotknij czytnika linii papilarnych"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona odcisku palca"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Szukam Cię…"</string>
@@ -201,6 +200,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Zmiana sieci operatora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Zobacz szczegóły baterii"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria: <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, jeszcze <xliff:g id="TIME">%2$s</xliff:g> (na podstawie Twojego sposobu korzystania)"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Ładuję baterię, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Ustawienia systemu."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Powiadomienia."</string>
@@ -382,8 +382,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do wschodu słońca"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Włącz o <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Ciemny motyw"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Ciemny motywy\nOszczędzanie baterii"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Ciemny motyw"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Ciemny motyw\nOszczędzanie baterii"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"Komunikacja NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Komunikacja NFC jest wyłączona"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Komunikacja NFC jest włączona"</string>
@@ -406,7 +406,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Poniżej widać mniej pilne powiadomienia"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Kliknij ponownie, by otworzyć"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Przesuń w górę, by odblokować"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Przesuń w górę, by otworzyć"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Tym urządzeniem zarządza Twoja organizacja"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Tym urządzeniem zarządza <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Aby włączyć telefon, przesuń palcem od ikony"</string>
@@ -460,16 +460,14 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"Oszczędzanie baterii jest włączone"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Zmniejsza wydajność i ogranicza dane w tle"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Wyłącz Oszczędzanie baterii"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"Podczas nagrywania lub przesyłania aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> może rejestrować wszelkie informacje poufne wyświetlane na ekranie lub odtwarzane na urządzeniu takie jak dźwięki czy podawane hasła, informacje o płatnościach, zdjęcia i wiadomości."</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"Podczas nagrywania lub przesyłania aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> może rejestrować wszelkie informacje poufne wyświetlane na ekranie lub odtwarzane na urządzeniu, takie jak dźwięki czy podawane hasła, informacje o płatnościach, zdjęcia i wiadomości."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Podczas nagrywania lub przesyłania usługa udostępniająca tę funkcję może rejestrować wszelkie informacje poufne wyświetlane na ekranie lub odtwarzane na urządzeniu takie jak dźwięki czy podawane hasła, informacje o płatnościach, zdjęcia i wiadomości."</string>
     <string name="media_projection_dialog_title" msgid="8124184308671641248">"Ujawnianie poufnych informacji podczas przesyłania/nagrywania"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nie pokazuj ponownie"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ukryj wszystkie"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Zarządzaj"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Powiadomienia ciche"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Wyczyść wszystkie ciche powiadomienia"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Powiadomienia wstrzymane przez tryb Nie przeszkadzać"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Rozpocznij teraz"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Brak powiadomień"</string>
@@ -653,21 +651,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Zablokuj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Pokazuj nadal"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimalizuj"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Bez dźwięku"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Zachowaj wyciszenie"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alerty"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Powiadamiaj dalej"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Wyłącz powiadomienia"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Nadal pokazywać powiadomienia z tej aplikacji?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Subtelne"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorytetowe"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomaga Ci się skupić, wyświetlając powiadomienia tylko w obszarze powiadomień. Zawsze wyciszone."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Wyświetla pod powiadomieniami priorytetowymi. Zawsze wyciszone."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Wyświetla pod powiadomieniami priorytetowymi. Zawsze wyciszone."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Wyświetla pod powiadomieniami priorytetowymi. Zawsze wyciszone."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Zwraca Twoją uwagę dźwiękiem i ikoną na pasku stanu. Wyświetla na ekranie blokady."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Bez dźwięku"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alert"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomaga Ci się skupić, nie sygnalizując niczego dźwiękiem ani wibracjami."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Przyciąga uwagę dźwiękiem lub wibracjami."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tych powiadomień nie można zmodyfikować."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Tej grupy powiadomień nie można tu skonfigurować"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Powiadomienie w zastępstwie"</string>
@@ -798,8 +791,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Przytrzymaj i przeciągnij, by dodać kafelki"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Przytrzymaj i przeciągnij, by przestawić kafelki"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Przeciągnij tutaj, by usunąć"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Minimalna liczba kafelków to <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Edytuj"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Godzina"</string>
   <string-array name="clock_options">
@@ -921,8 +913,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Zezwól"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Odmów"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Kliknij, by zaplanować działanie oszczędzania baterii"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Oszczędzanie baterii włącza się, jeśli bateria jest prawie wyczerpana"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nie"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Harmonogram oszczędzania baterii jest aktywny"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Oszczędzanie baterii włączy się automatycznie, gdy poziom naładowania baterii spadnie poniżej <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -955,4 +946,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Przenieś w lewy dolny róg"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Przenieś w prawy dolny róg"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zamknij"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Nawigacja w systemie została zaktualizowana. Aby wprowadzić zmiany, otwórz Ustawienia."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Otwórz Ustawienia, by zaktualizować nawigację w systemie"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/config.xml b/packages/SystemUI/res/values-pt-rBR/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-pt-rBR/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index d155999..c7e5263 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuração USB não permitida"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, mude para o usuário principal \"NAME\"."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Porta USB desativada"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger seu dispositivo de líquidos e detritos, a porta USB está desativada e não detectará nenhum acessório.\n\nVocê receberá uma notificação quando for seguro usar a porta USB novamente."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Porta USB ativada para detectar carregadores e acessórios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Ativar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saiba mais"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom p/ preencher a tela"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ampliar p/ preencher tela"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de tela"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Procurando seu rosto"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Rosto autenticado"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmada"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toque em \"Confirmar\" para concluir"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressão digital"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Procurando você…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Alteração de rede da operadora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalhes da bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria em <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria com <xliff:g id="PERCENTAGE">%1$s</xliff:g> de carga, tempo restante aproximado, com base no seu uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateria carregando: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Até o nascer do sol"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Ativado às <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Até <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema escuro"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema escuro\nEconomia de bateria"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema escuro"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema escuro\nEconomia de bateria"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"A NFC está desativada"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"A NFC está ativada"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Deslize para cima para desbloquear"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize para cima para abrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerenciado pela sua organização"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Deslize a partir do ícone do telefone"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Não mostrar novamente"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gerenciar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificações silenciosas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Apagar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencioso"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuar sem som"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertar"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar alertando"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desativar notificações"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuar mostrando notificações desse app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discreta"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorizada"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ajuda você a se concentrar, já que as notificações são exibidas apenas na aba suspensa. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Chama sua atenção com sons e um ícone na barra de status. Exibida na tela de bloqueio."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosa"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda você a manter o foco sem som ou vibração."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama sua atenção com som ou vibração."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar essas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar esse grupo de notificações aqui"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação salva no proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Mantenha pressionado e arraste para adicionar blocos"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Mantenha pressionado e arraste para reorganizar os blocos"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Arraste aqui para remover"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"É preciso haver pelo menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> blocos"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Horas"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Negar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Toque para programar o recurso Economia de bateria"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ativada quando há possibilidade de a bateria acabar"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Não"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Programação do recurso Economia de bateria ativada"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"O recurso Economia de bateria será ativado automaticamente depois que a bateria ficar abaixo de <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover para canto inferior esquerdo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover para canto inferior direito"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dispensar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Acesse as configurações para atualizar a navegação no sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/config.xml b/packages/SystemUI/res/values-pt-rPT/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-pt-rPT/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index d2f95f8..f60dcac 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuração USB não permitida"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"O utilizador com sessão iniciada atualmente neste dispositivo não pode ativar a depuração USB. Para utilizar esta funcionalidade, mude para o utilizador principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Porta USB desativada"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger o dispositivo contra líquidos ou resíduos, a porta USB está desativada e não irá detetar quaisquer acessórios.\n\nSerá notificado quando for seguro utilizar a porta USB novamente."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Porta USB ativada para detetar carregadores e acessórios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Ativar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saiba mais"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom para preencher o ecrã"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Esticar p. caber em ec. int."</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de ecrã"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"A procurar o seu rosto…"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Rosto autenticado"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmado"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toque em Confirmar para concluir."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressões digitais."</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"À sua procura…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Rede do operador em mudança."</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalhes da bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria a <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria a <xliff:g id="PERCENTAGE">%1$s</xliff:g> por cento, resta(m) cerca de <xliff:g id="TIME">%2$s</xliff:g> com base na sua utilização."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"A bateria está a carregar, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> por cento."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Definições do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Até ao amanhecer"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Ativada à(s) <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Até à(s) <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema escuro"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema escuro\nPoupança de bateria"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema escuro"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema escuro\nPoupança de bateria"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"O NFC está desativado"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"O NFC está ativado"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Deslizar rapidamente com o dedo para cima para desbloquear"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize rapidamente para cima para abrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerido pela sua entidade"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerido por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Deslize rapid. a partir do ícone para aceder ao telemóvel"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Não mostrar de novo"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gerir"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificações silenciosas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Limpar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificações colocadas em pausa pelo modo Não incomodar."</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Começar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar a mostrar"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencioso"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuar sem som"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertar"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar a alertar"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desativar notificações"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Pretende continuar a ver notificações desta aplicação?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discretas"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritárias"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ajuda-o a concentrar-se com notificações apenas no painel pendente. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"É apresentada abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"É apresentada abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Apresentadas abaixo das notificações prioritárias. Sempre silenciosas."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Chamam à atenção com som e ícones na barra de estado. Apresentadas no ecrã de bloqueio."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silencioso"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda-o a focar-se sem som ou vibração."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama a sua atenção com som ou vibração."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar estas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar este grupo de notificações aqui."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação de aplicação proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Toque sem soltar e arraste para adicionar mosaicos."</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Tocar sem soltar e arrastar para reorganizar os mosaicos"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Arrastar para aqui para remover"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Necessita de, pelo menos, <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> cartões"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Hora"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Recusar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tocar para agendar a Poupança de bateria"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ativar quando for provável que a bateria se esgote"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Não, obrigado"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Poupança de bateria agendada ativada"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"A Poupança de bateria é ativada automaticamente quando o nível de bateria está abaixo de <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover p/ parte infer. esquerda"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover parte inferior direita"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ignorar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"A navegação no sistema foi atualizada. Para efetuar alterações, aceda às Definições."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Aceda às Definições para atualizar a navegação no sistema."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/config.xml b/packages/SystemUI/res/values-pt/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-pt/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index d155999..c7e5263 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Depuração USB não permitida"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"O usuário conectado a este dispositivo não pode ativar a depuração USB. Para usar esse recurso, mude para o usuário principal \"NAME\"."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Porta USB desativada"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para proteger seu dispositivo de líquidos e detritos, a porta USB está desativada e não detectará nenhum acessório.\n\nVocê receberá uma notificação quando for seguro usar a porta USB novamente."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Porta USB ativada para detectar carregadores e acessórios"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Ativar USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Saiba mais"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom p/ preencher a tela"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ampliar p/ preencher tela"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Captura de tela"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Procurando seu rosto"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Rosto autenticado"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmada"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Toque em \"Confirmar\" para concluir"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Toque no sensor de impressão digital"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ícone de impressão digital"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Procurando você…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Alteração de rede da operadora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Abrir detalhes da bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria em <xliff:g id="NUMBER">%d</xliff:g> por cento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria com <xliff:g id="PERCENTAGE">%1$s</xliff:g> de carga, tempo restante aproximado, com base no seu uso: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateria carregando: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Configurações do sistema"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificações."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Até o nascer do sol"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Ativado às <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Até <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema escuro"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema escuro\nEconomia de bateria"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema escuro"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema escuro\nEconomia de bateria"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"A NFC está desativada"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"A NFC está ativada"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Deslize para cima para desbloquear"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize para cima para abrir"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerenciado pela sua organização"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Deslize a partir do ícone do telefone"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Não mostrar novamente"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Limpar tudo"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gerenciar"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificações silenciosas"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Apagar todas as notificações silenciosas"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificações pausadas pelo modo \"Não perturbe\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Sem notificações"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloquear"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silencioso"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Continuar sem som"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertar"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Continuar alertando"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Desativar notificações"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuar mostrando notificações desse app?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discreta"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priorizada"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ajuda você a se concentrar, já que as notificações são exibidas apenas na aba suspensa. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Exibida abaixo das notificações prioritárias. Sempre silenciosa."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Chama sua atenção com sons e um ícone na barra de status. Exibida na tela de bloqueio."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silenciosa"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertar"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ajuda você a manter o foco sem som ou vibração."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Chama sua atenção com som ou vibração."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Não é possível modificar essas notificações."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Não é possível configurar esse grupo de notificações aqui"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificação salva no proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Mantenha pressionado e arraste para adicionar blocos"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Mantenha pressionado e arraste para reorganizar os blocos"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Arraste aqui para remover"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"É preciso haver pelo menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> blocos"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Horas"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permitir"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Negar"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Toque para programar o recurso Economia de bateria"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Ativada quando há possibilidade de a bateria acabar"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Não"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Programação do recurso Economia de bateria ativada"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"O recurso Economia de bateria será ativado automaticamente depois que a bateria ficar abaixo de <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mover para canto inferior esquerdo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mover para canto inferior direito"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Dispensar"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navegação no sistema atualizada. Se quiser alterá-la, acesse as configurações."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Acesse as configurações para atualizar a navegação no sistema"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/config.xml b/packages/SystemUI/res/values-ro/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ro/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 069b117..e070fd4 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Remedierea erorilor prin USB nu este permisă"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Utilizatorul conectat momentan pe acest dispozitiv nu poate activa remedierea erorilor prin USB. Pentru a folosi această funcție, comutați la utilizatorul principal."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Portul USB a fost dezactivat"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Pentru a vă proteja dispozitivul de lichide sau reziduuri, portul USB este dezactivat și nu va detecta niciun accesoriu.\n\nVeți primi o notificare când puteți folosi din nou portul USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Portul USB a fost activat pentru a detecta încărcătoarele și accesoriile"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Activați USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Mai multe"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zoom pt. a umple ecranul"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Înt. pt. a umple ecranul"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Instantaneu"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Se caută chipul"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Chip autentificat"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Confirmat"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Atingeți Confirmați pentru a finaliza"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Atingeți senzorul de amprente"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Pictograma amprentă"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Vă căutăm…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Se schimbă rețeaua operatorului"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Deschideți detaliile privind bateria"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterie: <xliff:g id="NUMBER">%d</xliff:g> la sută."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Procentul rămas din baterie este <xliff:g id="PERCENTAGE">%1$s</xliff:g>. În baza utilizării, timpul rămas este de aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Se încarcă bateria, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Setări de sistem."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Notificări."</string>
@@ -378,8 +378,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Până la răsărit"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Activată la <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Până la <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Temă întunecată"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Temă întunecată\nEconomisirea bateriei"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Temă întunecată"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Temă întunecată\nEconomisirea bateriei"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Serviciul NFC este dezactivat"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Serviciul NFC este activat"</string>
@@ -402,7 +402,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificările mai puțin urgente mai jos"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Atingeți din nou pentru a deschide"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Glisați în sus pentru a debloca"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Glisați în sus pentru a deschide"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Acest dispozitiv este gestionat de organizația dvs."</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Acest dispozitiv este gestionat de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Glisați dinspre telefon"</string>
@@ -461,10 +461,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nu se mai afișează"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ștergeți toate notificările"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Gestionați"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Notificări silențioase"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Ștergeți toate notificările silențioase"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notificări întrerupte prin „Nu deranja”"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Începeți acum"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nicio notificare"</string>
@@ -648,21 +646,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blocați"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Continuați afișarea"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizați"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silențios"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Păstrați modul silențios"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Alertare"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Păstrați alerta"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Dezactivați notificările"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Doriți să continuați afișarea notificărilor de la această aplicație?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Discret"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Cu prioritate"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Vă ajută să vă concentrați cu notificări doar în fereastra trasă în jos. Întotdeauna silențios."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Se afișează sub notificările prioritare. Întotdeauna silențios."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Se afișează sub notificările prioritare. Întotdeauna silențios."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Se afișează sub notificările prioritare. Întotdeauna silențios."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Vă atrage atenția cu sunete și o pictogramă în bara de stare. Se afișează pe ecranul de blocare."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Silențios"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Alertare"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Vă ajută să vă concentrați fără sunet sau vibrare."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Vă atrage atenția fără sunet sau vibrare."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Aceste notificări nu pot fi modificate."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Acest grup de notificări nu poate fi configurat aici"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Notificare prin proxy"</string>
@@ -791,8 +784,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Țineți apăsat și trageți pentru a adăuga piese"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Țineți apăsat și trageți pentru a rearanja piesele"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Trageți aici pentru a elimina"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Aveți nevoie de cel puțin <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> carduri"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Editați"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Oră"</string>
   <string-array name="clock_options">
@@ -914,8 +906,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Permiteți"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Refuzați"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Atingeți pentru a programa Economisirea energiei"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Porniți dacă este probabil ca bateria să se descarce"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nu, mulțumesc"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"S-a activat programarea pentru Economisirea bateriei"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Economisirea bateriei se va activa automat imediat ce bateria scade sub <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -948,4 +939,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Mutați în stânga jos"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Mutați în dreapta jos"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Închideți"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigarea în sistem a fost actualizată. Pentru a face modificări, accesați Setările."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Accesați Setările pentru a actualiza navigarea în sistem"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/config.xml b/packages/SystemUI/res/values-ru/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ru/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 9175fe0..f895c02 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отладка по USB запрещена"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"В этом аккаунте нельзя включить отладку по USB. Перейдите в аккаунт основного пользователя."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-порт отключен"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Чтобы внутрь устройства не попала вода или грязь, USB-порт был отключен. Сейчас через него нельзя подсоединять другие устройства.\n\nКогда USB-порт снова можно будет использовать, вы получите уведомление."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-порт активен и может распознавать аксессуары и зарядные устройства."</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Включить USB-порт"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Подробнее"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Подогнать по размерам экрана"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Растянуть на весь экран"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Скриншот"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Распознавание лица"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Лицо распознано"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Подтверждено"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Нажмите \"Подтвердить\""</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Прикоснитесь к сканеру отпечатков пальцев."</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок отпечатка пальца"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Поиск лица…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Сменить сеть"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Сведения о расходе заряда батареи"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд батареи в процентах: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Заряд батареи в процентах: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Оценка оставшегося времени работы: <xliff:g id="TIME">%2$s</xliff:g>."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Зарядка батареи. Текущий заряд: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Настройки"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Уведомления"</string>
@@ -380,8 +380,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"До рассвета"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Включить в <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Тёмная тема"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Тёмная тема\nРежим энергосбережения"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Тёмная тема"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Тёмная тема\nРежим энергосбережения"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"Модуль NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Модуль NFC отключен"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Модуль NFC включен"</string>
@@ -404,7 +404,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Показать менее важные уведомления"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Нажмите ещё раз, чтобы открыть"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Проведите вверх, чтобы разблокировать"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Проведите вверх, чтобы открыть"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Этим устройством управляет ваша организация"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Этим устройством управляет компания \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
     <string name="phone_hint" msgid="4872890986869209950">"Телефон: проведите от значка"</string>
@@ -458,16 +458,14 @@
     <string name="battery_saver_notification_title" msgid="8614079794522291840">"Режим энергосбережения включен"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Откл. фоновой передачи данных"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Отключить режим энергосбережения"</string>
-    <string name="media_projection_dialog_text" msgid="8585357687598538511">"При записи сообщений или трансляции экрана приложение \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" может получить доступ к конфиденциальной информации, которая отображается на экране или воспроизводится на устройстве, например к аудиозаписям, паролям, фото, сообщениям и платежным данным."</string>
+    <string name="media_projection_dialog_text" msgid="8585357687598538511">"При записи сообщений или трансляции экрана приложение <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> может получить доступ к конфиденциальной информации, которая отображается на экране или воспроизводится на устройстве, например к аудиозаписям, паролям, фото, сообщениям и платежным данным."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"При записи сообщений или трансляции экрана сервис может получить доступ к конфиденциальной информации, которая отображается на экране или воспроизводится на устройстве, например к аудиозаписям, паролям, фото, сообщениям и платежным данным."</string>
     <string name="media_projection_dialog_title" msgid="8124184308671641248">"Раскрытие личной информации при записи или трансляции"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Больше не показывать"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Очистить все"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Настроить"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Беззвучные уведомления"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Отклонить все беззвучные уведомления"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"В режиме \"Не беспокоить\" уведомления заблокированы"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Начать"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нет уведомлений"</string>
@@ -651,21 +649,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Заблокировать"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Показывать"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Свернуть"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Без звука"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Не включать звук"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Присылать оповещения"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Присылать уведомления"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Выключить уведомления"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Показывать уведомления от этого приложения?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Беззвучные"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Приоритетные"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Уведомления появляются только на специальной панели, чтобы вы не отвлекались. Всегда без звука."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Показ уведомлений с низким приоритетом. Всегда без звука."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Показ уведомлений с низким приоритетом. Всегда без звука."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Показ уведомлений с низким приоритетом. Всегда без звука."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Со звуком и значком в строке состояния. Появляются на заблокированном экране."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Без звука"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Оповещения"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Уведомления приходят без звука и вибрации"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Уведомления приходят со звуком или вибрацией"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Эти уведомления нельзя изменить."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Эту группу уведомлений нельзя настроить здесь."</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Уведомление отправлено через прокси-сервер."</string>
@@ -796,8 +789,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Перетащите нужные элементы"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Чтобы изменить порядок элементов, перетащите их"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Чтобы удалить, перетащите сюда"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Должно остаться не менее <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> элементов"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Изменить"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Время"</string>
   <string-array name="clock_options">
@@ -919,8 +911,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Да"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Нет"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Нажмите, чтобы настроить режим энергосбережения"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Включать, если высока вероятность, что батарея скоро разрядится"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Отмена"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Автоматический переход в режим энергосбережения включен"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Режим энергосбережения активируется при заряде батареи ниже <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -953,4 +944,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Перенести в левый нижний угол"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Перенести в правый нижний угол"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Закрыть"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Параметры навигации в системе обновлены. Чтобы изменить их, перейдите в настройки."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Чтобы обновить параметры навигации в системе, перейдите в настройки."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/config.xml b/packages/SystemUI/res/values-si/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-si/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 08cdafb..9e00215 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"ඔබේ මුහුණ සොයනු ලැබේ"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"මුහුණ සත්‍යාපන කළා"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"තහවුරු කළා"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"සම්පූර්ණ කිරීමට තහවුරු කරන්න තට්ටු කර."</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ඇඟිලි සලකුණු නිරූපකය"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"ඔබව සොයමින්…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"වාහක ජාලය වෙනස් වෙමින්"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"බැටරි විස්තර විවෘත කරන්න"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"බැටරි ප්‍රතිශතය <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"බැටරි ප්‍රතිශතය <xliff:g id="PERCENTAGE">%1$s</xliff:g>, ඔබේ භාවිතයට අනුව <xliff:g id="TIME">%2$s</xliff:g> ක් පමණ ඉතුරුයි"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"බැටරිය ආරෝපණය කරමින්, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"පද්ධති සැකසීම්."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"දැනුම්දීම්."</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"හිරු නගින තෙක්"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>ට ක්‍රියාත්මකයි"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> තෙක්"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"අඳුරු තේමාව"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"අඳුරු තේමාව\nබැටරි සුරැකුම"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"අඳුරු තේමාව"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"අඳුරු තේමාව\nබැටරි සුරැකුම"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC අබලයි"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC සබලයි"</string>
@@ -398,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"හදිසිය අඩු දැනුම් දීම් පහත"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"විවෘත කිරීමට නැවත තට්ටු කරන්න"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"අගුළු ඇරීමට ස්වයිප් කරන්න."</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"මෙම උපාංගය ඔබගේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> මගින් කළමනාකරණය කෙරේ"</string>
     <string name="phone_hint" msgid="4872890986869209950">"දුරකථනය සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"අඟවමින් සිටින්න"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"දැනුම්දීම් අක්‍රිය කරන්න"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"මෙම යෙදුම වෙතින් දැනුම්දීම් පෙන්වමින් තබන්නද?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"මෘදු"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ප්‍රමුඛ කළ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ඔබට පහළට-ඇදීමේ වැස්මේ පමණක් දැනුම්දීම් සමඟ අවධානය යොමු කිරීමට උදවු කරයි. සැම විටම නිහඬයි."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ප්‍රමුඛතා දැනුම්දීම්වලට පහළින් සංදර්ශනය වේ. සැම විටම නිහඬයි."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ප්‍රමුඛතා දැනුම්දීම්වලට පහළින් සංදර්ශනය වේ. සැම විටම නිහඬයි."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ප්‍රමුඛතා දැනුම්දීම්වලට පහළින් සංදර්ශනය වේ. සැම විටම නිහඬයි."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ශබ්දයක් සහ තත්ත්ව තීරු නිරූපකයක් සමඟින් ඔබේ අවධානය ලබා ගනී. අගුළු තිරයෙහි පෙන්වයි."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"නිහඬ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"ඇඟවීම"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ඔබට ශබ්දය හෝ කම්පනය නොමැතිව අවධානය යොමු කිරීමට උදවු කරයි."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ශබ්දය හෝ කම්පනය සමඟ ඔබේ අවධානය ලබා ගනී."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"මෙම දැනුම්දීම් වෙනස් කළ නොහැක."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"මෙම දැනුම්දීම් සමූහය මෙහි වින්‍යාස කළ නොහැක"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ප්‍රොක්සි කළ දැනුම්දීම"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"පහළ වමට ගෙන යන්න"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"පහළ දකුණට ගෙන යන්න"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ඉවතලන්න"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"පද්ධති සංචලනය යාවත්කාලීන කළා. වෙනස්කම් සිදු කිරීමට, සැකසීම් වෙත යන්න."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"පද්ධති සංචලනය යාවත්කාලීන කිරීමට සැකසීම් වෙත යන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/config.xml b/packages/SystemUI/res/values-sk/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-sk/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 3017030..dabe330 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ladenie cez USB nie je povolené"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Používateľ, ktorý je práve prihlásený v tomto zariadení, nemôže zapnúť ladenie USB. Ak chcete použiť túto funkciu, prepnite na hlavného používateľa."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Port USB je deaktivovaný"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Port USB je deaktivovaný na zaistenie ochrany zariadenia pred tekutinami alebo nečistotami a nerozpoznáva príslušenstvo.\n\nKeď ho budete môcť znova použiť, upozorníme vás."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Bol povolený port USB na zisťovanie nabíjačiek a príslušenstva"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Povoliť USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Ďalšie informácie"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Priblížiť na celú obrazovku"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Na celú obrazovku"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Snímka"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Hľadá sa vaša tvár"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Tvár bola overená"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potvrdené"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Overenie dokončíte klepnutím na Potvrdiť"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotknite sa senzora odtlačkov prstov"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona odtlačku prsta"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hľadáme vás…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mení sa sieť operátora"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Otvoriť podrobnosti o batérii"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batéria <xliff:g id="NUMBER">%d</xliff:g> percent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Percentá batérie: <xliff:g id="PERCENTAGE">%1$s</xliff:g>. Na základe vášho používania zostáva <xliff:g id="TIME">%2$s</xliff:g>."</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Nabíja sa batéria, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Nastavenia systému."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Upozornenia."</string>
@@ -313,7 +313,7 @@
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="5673845963301132071">"Zvuk"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="1880572731276240588">"Náhlavná súprava"</string>
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="2173322305072945905">"Vstup"</string>
-    <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="4930931771490695395">"Načúvacie pomôcky"</string>
+    <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="4930931771490695395">"Načúvadlá"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="4551281899312150640">"Zapína sa…"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Jas"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatické otáčanie"</string>
@@ -380,8 +380,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do východu slnka"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Od <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tmavý motív"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tmavý motív\nŠetrič batérie"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tmavý motív"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tmavý motív\nŠetrič batérie"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC je deaktivované"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC je aktivované"</string>
@@ -404,7 +404,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Menej naliehavé upozornenia sa nachádzajú nižšie"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Upozornenie otvoríte opätovným klepnutím"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Odomknete prejdením prstom nahor"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Otvorte potiahnutím prstom nahor"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Toto zariadenie spravuje vaša organizácia"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Toto zariadenie spravuje organizácia <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefón otvoríte prejdením prstom od ikony"</string>
@@ -464,10 +464,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nabudúce nezobrazovať"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Vymazať všetko"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Spravovať"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tiché upozornenia"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Vymazať všetky tiché upozornenia"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Upozornenia sú pozastavené režimom bez vyrušení"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Spustiť"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Žiadne upozornenia"</string>
@@ -651,21 +649,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokovať"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Naďalej zobrazovať"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimalizovať"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tichý"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Naďalej upozorňovať potichu"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Upozorňovanie"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Naďalej upozorňovať"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Vypnúť upozornenia"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Majú sa upozornenia z tejto aplikácie naďalej zobrazovať?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Nenápadné"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioritné"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Pomáha sústrediť sa zobrazovaním upozornení iba v rozbaľovacom paneli. Vždy potichu."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Zobrazuje sa pod prioritnými upozorneniami. Vždy potichu."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Zobrazuje sa pod prioritnými upozorneniami. Vždy potichu."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Zobrazuje sa pod prioritnými upozorneniami. Vždy potichu."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Upúta zvukom a zobrazením ikony v stavovom riadku. Zobrazuje sa na uzamknutej obrazovke."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tiché"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Varovné"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Pomáha vám sústrediť sa bez zvukov či vibrácií."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Upúta vás zvukom alebo vibráciami."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Tieto upozornenia sa nedajú upraviť."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Túto skupinu upozornení nejde na tomto mieste konfigurovať"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Približné upozornenie"</string>
@@ -796,8 +789,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Pridržaním a presunutím pridáte dlaždice"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Dlaždice môžete usporiadať pridržaním a presunutím"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Presunutím sem odstránite"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Minimálny počet vyžadovaných dlaždíc: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Upraviť"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Čas"</string>
   <string-array name="clock_options">
@@ -919,8 +911,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Povoliť"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Zamietnuť"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Klepnutím naplánujete aktivovanie Šetriča batérie"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Zapnite, keď je batéria takmer vybitá"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nie, vďaka"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Plánované aktivovanie Šetriča batérie bolo zapnuté"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Keď batéria klesne pod <xliff:g id="PERCENTAGE">%d</xliff:g> %%, automaticky sa aktivujte Šetrič batérie."</string>
@@ -953,4 +944,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Presunúť doľava nadol"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Presunúť doprava nadol"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Zavrieť"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigácia v systéme bola aktualizovaná. Ak chcete vykonať zmeny, prejdite do Nastavení."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Prejdite do Nastavení a aktualizujte navigáciu v systéme"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/config.xml b/packages/SystemUI/res/values-sl/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-sl/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 55492a2..2958dc8 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Odpravljanje napak s povezavo USB ni dovoljeno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Uporabnik, trenutno prijavljen v napravo, ne more vklopiti odpravljanja napak s povezavo USB. Če želite uporabljati to funkcijo, preklopite na primarnega uporabnika."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Vrata USB so onemogočena"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Zaradi zaščite naprave pred tekočino ali umazanijo so vrata USB onemogočena in ne bodo zaznala nobene dodatne opreme.\n\nKo bo znova varno uporabljati vrata USB, boste obveščeni."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Vrata USB so omogočena za zaznavanje polnilnikov in dodatne opreme"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Omogoči USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Več o tem"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Povečava čez cel zaslon"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Raztegnitev čez zaslon"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Posnetek"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Iskanje obraza"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Pristnost obraza je potrjena"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Potrjeno"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Za dokončanje se dotaknite »Potrdite«"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Dotaknite se tipala prstnih odtisov"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona prstnih odtisov"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Preverjanje vašega obraza …"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Spreminjanje omrežja operaterja"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Odpiranje podrobnosti o akumulatorju"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija <xliff:g id="NUMBER">%d</xliff:g> odstotkov."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Napolnjenost akumulatorja je <xliff:g id="PERCENTAGE">%1$s</xliff:g>, glede na način uporabe imate na voljo še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Polnjenje akumulatorja, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistemske nastavitve."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obvestila."</string>
@@ -380,8 +380,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Do sončnega vzhoda"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Vklop ob <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Temna tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Temna tema\nVarčevanje energije"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Temna tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Temna tema\nVarčevanje z energijo akumul."</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Tehnologija NFC je onemogočena"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Tehnologija NFC je omogočena"</string>
@@ -404,7 +404,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Manj nujna obvestila spodaj"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Znova se dotaknite, da odprete"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Povlecite, da odklenete"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Povlecite navzgor, da odprete"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"To napravo upravlja vaša organizacija"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"To napravo upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Povlecite z ikone za telefon"</string>
@@ -464,10 +464,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Tega ne prikaži več"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Izbriši vse"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljanje"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Tiha obvestila"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Brisanje vseh tihih obvestil"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Prikazovanje obvestil je začasno zaustavljeno z načinom »ne moti«"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Začni zdaj"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Ni obvestil"</string>
@@ -651,21 +649,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blokiraj"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Prikazuj še naprej"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimiraj"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tiho"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Še naprej prikazuj brez zvoka"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Z opozorilom"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Še naprej opozarjaj"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Izklopi obvestila"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite, da so obvestila te aplikacije še naprej prikazana?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Diskretno"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prednostno"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Nemoteč prikaz samo na poteznem zaslonu z obvestili. Vedno tiho."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Prikaz pod prednostnimi obvestili. Vedno tiho."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Prikaz pod prednostnimi obvestili. Vedno tiho."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Prikaz pod prednostnimi obvestili. Vedno tiho."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Opozarjanje z zvokom in ikono v vrstici stanja. Prikaz na zaklenjenem zaslonu."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tiho"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Z opozorilom"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Nemoteč prikaz brez zvoka ali vibriranja"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Pritegne vašo pozornost z zvokom ali vibriranjem"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Za ta obvestila ni mogoče spremeniti nastavitev."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Te skupine obvestil ni mogoče konfigurirati tukaj"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Posredovano obvestilo"</string>
@@ -796,8 +789,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Držite in povlecite, da dodate ploščice"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Držite in povlecite, da prerazporedite ploščice"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Če želite odstraniti, povlecite sem"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Imeti morate vsaj toliko ploščic: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Uredi"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Ura"</string>
   <string-array name="clock_options">
@@ -919,8 +911,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Dovoli"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Zavrni"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Dotaknite se za načrtovanje varčevanja z energijo akumulatorja"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Vklop, če je verjetno, da se bo akumulator izpraznil"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ne, hvala"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Urnik varčevanja z energijo akumulatorja je vklopljen"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Varčevanje z energijo akumulatorja se bo samodejno vklopilo, ko bo energija akumulatorja pod <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -953,4 +944,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Premakni spodaj levo"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Premakni spodaj desno"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Opusti"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Krmarjenje po sistemu je posodobljeno. Če želite opraviti spremembe, odprite nastavitve."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Če želite posodobiti krmarjenje po sistemu, odprite nastavitve"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/config.xml b/packages/SystemUI/res/values-sq/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-sq/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index df73d7c..83a7aaa 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -29,9 +29,9 @@
     <string name="battery_low_percent_format_hybrid" msgid="6838677459286775617">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> të mbetura, rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
     <string name="battery_low_percent_format_hybrid_short" msgid="9025795469949145586">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> të mbetura, rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
     <string name="battery_low_percent_format_saver_started" msgid="7879389868952879166">"Ka mbetur edhe <xliff:g id="PERCENTAGE">%s</xliff:g>. \"Kursyesi i baterisë\" është i aktivizuar."</string>
-    <string name="invalid_charger" msgid="2741987096648693172">"Nuk mund të ngarkohet përmes USB-së. Përdor ngarkuesin që ke marrë me pajisjen."</string>
+    <string name="invalid_charger" msgid="2741987096648693172">"Nuk mund të karikohet përmes USB-së. Përdor karikuesin që ke marrë me pajisjen."</string>
     <string name="invalid_charger_title" msgid="2836102177577255404">"Nuk mund të ngarkohet përmes USB-së"</string>
-    <string name="invalid_charger_text" msgid="6480624964117840005">"Përdor ngarkuesin që ke marrë me pajisjen"</string>
+    <string name="invalid_charger_text" msgid="6480624964117840005">"Përdor karikuesin që ke marrë me pajisjen"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Cilësimet"</string>
     <string name="battery_saver_confirmation_title" msgid="2052100465684817154">"Të aktivizohet \"Kursyesi i baterisë\"?"</string>
     <string name="battery_saver_confirmation_title_generic" msgid="2090922638411744540">"Rreth \"Kursyesit të baterisë\""</string>
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Korrigjimi i USB-së nuk lejohet"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Përdoruesi i identifikuar aktualisht në këtë pajisje nuk mund ta aktivizojë korrigjimin e USB-së. Për ta përdorur këtë funksion, kalo te përdoruesi parësor."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Porta e USB-së është çaktivizuar"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Për të mbrojtur pajisjen tënde nga lëngjet apo papastërtitë, porta e USB-së është çaktivizuar dhe nuk do t\'i dallojë aksesorët.\n\nDo të njoftohesh kur të mos jetë problem përdorimi përsëri i portës USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Porta USB është aktivizuar për të zbuluar karikuesit dhe aksesorët"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktivizo USB-në"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Mëso më shumë"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zmadho për të mbushur ekranin"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Shtrije për të mbushur ekranin"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Pamja e ekranit"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Po kërkon për fytyrën tënde"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Fytyra u vërtetua"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Konfirmuar"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Trokit \"Konfirmo\" për ta përfunduar"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Prek sensorin e gjurmës së gishtit"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikona e gjurmës së gishtit"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Po të kërkojmë…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Rrjeti i operatorit celular po ndryshohet"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Hap detajet e baterisë"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Bateria ka edhe <xliff:g id="NUMBER">%d</xliff:g> për qind."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Bateria <xliff:g id="PERCENTAGE">%1$s</xliff:g> përqind, rreth <xliff:g id="TIME">%2$s</xliff:g> të mbetura bazuar në përdorimin tënd"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateria po karikohet, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Cilësimet e sistemit."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Njoftimet."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Deri në lindje të diellit"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Aktive në <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Deri në <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tema e errët"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tema e errët\nKursyesi i baterisë"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tema e errët"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tema e errët\nKursyesi i baterisë"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC është çaktivizuar"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC është aktivizuar"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Njoftimet më pak urgjente, më poshtë!"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Trokit përsëri për ta hapur"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Rrëshqit për të shkyçur"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Rrëshqit lart për ta hapur"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Kjo pajisje menaxhohet nga organizata jote"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Kjo pajisje menaxhohet nga <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Rrëshqit për të hapur telefonin"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Mos e shfaq sërish"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Pastroji të gjitha"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Menaxho"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Njoftimet në heshtje"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Pastro të gjitha njoftimet në heshtje"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Njoftimet janë vendosur në pauzë nga modaliteti \"Mos shqetëso\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Fillo tani"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Asnjë njoftim"</string>
@@ -616,7 +614,7 @@
     <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Të hiqet Sintonizuesi i Sistemit të Ndërfaqes së Përdoruesit nga Cilësimet dhe të ndërpritet përdorimi i të gjitha funksioneve të tij?"</string>
     <string name="activity_not_found" msgid="348423244327799974">"Aplikacioni nuk është instaluar në pajisjen tënde."</string>
     <string name="clock_seconds" msgid="7689554147579179507">"Trego sekondat e orës"</string>
-    <string name="clock_seconds_desc" msgid="6282693067130470675">"Trego sekondat e orës në shiritin e statusit. Mund të ndikojë te jeta e baterisë."</string>
+    <string name="clock_seconds_desc" msgid="6282693067130470675">"Trego sekondat e orës në shiritin e statusit. Mund të ndikojë te kohëzgjatja e baterisë."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Risistemo Cilësimet e shpejta"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Shfaq ndriçimin te Cilësimet e shpejta"</string>
     <string name="experimental" msgid="6198182315536726162">"Eksperimentale"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blloko"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Vazhdo të shfaqësh"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimizo"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Në heshtje"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Qëndro në heshtje"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Sinjalizimi"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Vazhdo të sinjalizosh"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Çaktivizo njoftimet"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Do të vazhdosh t\'i shfaqësh njoftimet nga ky aplikacion?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Me rëndësi të ulët"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Me prioritet"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Të ndihmon të përqendrohesh me njoftimet vetëm në panelin zbritës. Gjithmonë në heshtje."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Shfaqet nën njoftimet me përparësi. Gjithmonë në heshtje."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Shfaqet nën njoftimet me përparësi. Gjithmonë në heshtje."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Shfaqet nën njoftimet me përparësi. Gjithmonë në heshtje."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Të tërheq vëmendjen me tingull dhe një ikonë në shiritin e statusit. Shfaqet në ekranin e kyçjes."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Në heshtje"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Sinjalizimi"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Të ndihmon të fokusohesh pa tinguj ose dridhje."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Të tërheq vëmendjen me tinguj ose dridhje."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Këto njoftime nuk mund të modifikohen."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ky grup njoftimesh nuk mund të konfigurohet këtu"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Njoftim i dërguar me përfaqësues"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Mbaje të shtypur dhe zvarrit për të shtuar pllakëza"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Mbaje të shtypur dhe zvarrit për të risistemuar pllakëzat"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Zvarrit këtu për ta hequr"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Të duhen të paktën <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> pllakëza"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Redakto"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Ora"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Lejo"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Refuzo"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Trokit për të planifikuar \"Kursyesin e baterisë\""</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktivizoje kur bateria mund të mbarojë"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Jo"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Planifikimi i \"Kursyesit të baterisë\" është aktivizuar"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"\"Kursyesi i baterisë\" do të aktivizohet automatikisht kur bateria të jetë nën <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Zhvendos poshtë majtas"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Lëvize poshtë djathtas"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Hiq"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Navigimi i sistemit u përditësua. Për të bërë ndryshime, shko te \"Cilësimet\"."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Shko te \"Cilësimet\" për të përditësuar navigimin e sistemit"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/config.xml b/packages/SystemUI/res/values-sr/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-sr/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 00b19c4..f1bf3c9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Отклањање грешака на USB-у није дозвољено"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Корисник који је тренутно пријављен на овај уређај не може да укључи отклањање грешака на USB-у. Да бисте користили ову функцију, пребаците на примарног корисника."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB порт је онемогућен"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Да би се уређај заштитио од течности или нечистоће, USB порт је онемогућен и неће откривати додатну опрему.\n\nОбавестићемо вас када поново будете могли да користите USB порт."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB порт је омогућен ради откривања пуњача и додатне опреме"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Омогући USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Сазнајте више"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Зумирај на целом екрану"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Развуци на цео екран"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Снимак екрана"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Тражи се ваше лице"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Лице је потврђено"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Потврђено"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Додирните Потврди да бисте завршили"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Додирните сензор за отисак прста"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Икона отиска прста"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Тражимо вас…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Промена мреже мобилног оператера"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Отвори детаље о батерији"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Батерија је на <xliff:g id="NUMBER">%d</xliff:g> посто."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Батерија је на <xliff:g id="PERCENTAGE">%1$s</xliff:g> посто, преостало време на основу коришћења је <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Батерија се пуни, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Системска подешавања."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Обавештења."</string>
@@ -378,8 +378,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"До изласка сунца"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Укључује се у <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Тамна тема"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Тамна тема\nУштеда батерије"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Тамна тема"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Тамна тема\nУштеда батерије"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC је онемогућен"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC је омогућен"</string>
@@ -402,7 +402,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Мање хитна обавештења су у наставку"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Додирните поново да бисте отворили"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Превуците нагоре да бисте откључали"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Превуците нагоре да бисте отворили"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Овим уређајем управља организација"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Овим уређајем управља <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Превуците од иконе за телефон"</string>
@@ -461,10 +461,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Не приказуј поново"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Обриши све"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Управљајте"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Нечујна обавештења"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Обришите сва нечујна обавештења"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Обавештења су паузирана режимом Не узнемиравај"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Започни одмах"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Нема обавештења"</string>
@@ -648,21 +646,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блокирај"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Настави да приказујеш"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Умањи"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Нечујно"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Не укључуј звук"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Упозоравање"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Настави са обавештењима"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Искључи обавештења"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Желите ли да се обавештења из ове апликације и даље приказују?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Дискретно"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Приоритетно"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Помаже вам да се фокусирате. Обавештења су само на падајућој траци. Увек нечујно."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Приказује се испод приоритетних обавештења. Увек нечујно."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Приказује се испод приоритетних обавештења. Увек нечујно."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Приказује се испод приоритетних обавештења. Увек нечујно."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Привлачи вам пажњу помоћу звука и иконе статусне траке. Приказује се на закључаном екрану."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Нечујно"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Упозоравање"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Помаже вам да се концентришете без звука или вибрације."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привлачи вам пажњу помоћу звука или вибрације."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ова обавештења не могу да се мењају."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ова група обавештења не може да се конфигурише овде"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Обавештење преко проксија"</string>
@@ -791,8 +784,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Задржите и превуците да бисте додали плочице"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Задржите и превуците да бисте променили распоред плочица"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Превуците овде да бисте уклонили"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Минималан број плочица је <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Измени"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Време"</string>
   <string-array name="clock_options">
@@ -914,8 +906,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дозволи"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Одбиј"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Додирните да бисте направили распоред за уштеду батерије"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Укључите ако ће батерија вероватно да се испразни"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Не, хвала"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Распоред за уштеду батерије је укључен"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Уштеда батерије ће се аутоматски укључивати када батерија падне испод <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -948,4 +939,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Премести доле лево"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Премести доле десно"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Одбаци"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Идите у Подешавања да бисте ажурирали навигацију система"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/config.xml b/packages/SystemUI/res/values-sv/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-sv/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7dd2bee..764ad50 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB-felsökning är inte tillåtet"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Användaren som är inloggad på enheten för närvarande kan inte aktivera USB-felsökning. Byt till den primära användaren om du vill använda den här funktionen."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-porten har inaktiverats"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"USB-porten har inaktiverats för att skydda enheten mot vätska eller smuts. Inga tillbehör kommer att hittas.\n\nDu meddelas när det går att använda USB-porten igen."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB-porten har aktiverats för identifiering av laddare och tillbehör"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Aktivera USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Läs mer"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Zooma för att fylla skärm"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Dra för att fylla skärmen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skärmdump"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Söker efter ditt ansikte"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Ansiktet har autentiserats"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Bekräftat"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Slutför genom att trycka på Bekräfta"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Tryck på fingeravtryckssensorn"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Ikon för fingeravtryck"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Håller utkik efter dig …"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Byter leverantörsnätverk"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Visa uppgifter om batteri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batteri: <xliff:g id="PERCENTAGE">%1$s</xliff:g> procent, cirka <xliff:g id="TIME">%2$s</xliff:g> kvar utifrån din användning"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batteriet laddas, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systeminställningar."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meddelanden."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Till soluppgången"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"På från <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Till <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Mörkt tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Mörkt tema\nBatterisparläge"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Mörkt tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Mörkt tema\nBatterisparläge"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC är inaktiverat"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC är aktiverat"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre brådskande aviseringar nedan"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Tryck igen för att öppna"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Svep uppåt för att låsa upp"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Öppna genom att svepa uppåt"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Den här enheten hanteras av organisationen"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Den här enheten hanteras av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Svep från ikonen och öppna telefonen"</string>
@@ -454,14 +454,12 @@
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Inaktivera batterisparläget"</string>
     <string name="media_projection_dialog_text" msgid="8585357687598538511">"När du spelar in eller castar kan <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> registrera vilka känsliga uppgifter som helst som visas på skärmen eller spelas upp på enheten, inklusive ljud, lösenord, betalningsuppgifter, foton och meddelanden."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"När du spelar in eller castar kan tjänsten som tillhandahåller funktionen registrera vilka känsliga uppgifter som helst som visas på skärmen eller spelas upp på enheten, inklusive ljud, lösenord, betalningsuppgifter, foton och meddelanden."</string>
-    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Avslöja känsliga uppgifter under inspelning och vid castning"</string>
+    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Känsliga uppgifters synlighet under inspelning och vid castning"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Visa inte igen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Rensa alla"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Hantera"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Ljudlösa aviseringar"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Rensa alla ljudlösa aviseringar"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Aviseringar har pausats via Stör ej"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Starta nu"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Inga aviseringar"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Blockera"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Fortsätt visa"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Minimera"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Ljudlöst"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Fortsätt visa utan ljud"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Med avisering"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Fortsätt meddela"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Inaktivera aviseringar"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Vill du fortsätta visa aviseringar för den här appen?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Utan avbrott"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Prioriterade"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Aviseringar visas bara på aviseringspanelen så att du kan fokusera på det viktigaste. Alltid tyst."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Aviseringar med låg prioritet visas. Alltid tyst."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Aviseringar med låg prioritet visas. Alltid tyst."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Aviseringar med låg prioritet visas. Alltid tyst."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Fångar din uppmärksamhet med ljud och en ikon i statusfältet. Visas på låsskärmen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tyst"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Påkallar uppmärksamhet"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Inga ljud eller vibrationer som stör koncentrationen."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Påkallar uppmärksamhet med ljud eller vibrationer."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Det går inte att ändra de här aviseringarna."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Den här aviseringsgruppen kan inte konfigureras här"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Avisering via proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Lägg till rutor genom att trycka och dra"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Ordna om rutor genom att trycka och dra"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Ta bort genom att dra här"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Minst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> rutor måste finnas kvar"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Redigera"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Tid"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Tillåt"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Neka"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Tryck för att skapa ett schema för batterisparläget"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Aktivera när batteriet håller på att ta slut"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Nej tack"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Schema för Batterisparläge aktiverat"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batterisparläget aktiveras automatiskt när batterinivån är under <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Flytta längst ned till vänster"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Flytta längst ned till höger"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Stäng"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Systemnavigeringen har uppdaterats. Öppna inställningarna om du vill ändra något."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Öppna inställningarna och uppdatera systemnavigeringen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/config.xml b/packages/SystemUI/res/values-sw/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-sw/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 855248c..182caa4 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Utatuzi wa USB hauruhusiwi"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Mtumiaji aliyeingia katika akaunti kwa kutumia kifaa hiki kwa sasa hawezi kuwasha utatuzi wa USB. Ili utumie kipengele hiki, tumia akaunti ya mtumiaji wa msingi."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Mlango wa USB umezimwa"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Ili ulinde kifaa chako dhidi ya vitu vyenye unyevu au uchafu, mlango wa USB umezimwa na hautatambua vifaa vyovyote.\n\nUtaarifiwa itapokuwa sawa kutumia mlango wa USB tena."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Mlango wa USB umewezeshwa ili utambue chaja na vifuasi"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Washa kipengele cha USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Pata maelezo zaidi"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Kuza ili kujaza skrini"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Tanua ili kujaza skrini"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Pichaskrini"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Inatafuta uso wako"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Uso umethibitishwa"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Imethibitishwa"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Gusa Thibitisha ili ukamilishe"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Gusa kitambua alama ya kidole"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Aikoni ya alama ya kidole"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Inakutafuta…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mabadiliko katika mtandao wa mtoa huduma"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Fungua maelezo ya betri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Asilimia <xliff:g id="NUMBER">%d</xliff:g> ya betri"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Betri ina asilimia <xliff:g id="PERCENTAGE">%1$s</xliff:g>, zimesalia takribani <xliff:g id="TIME">%2$s</xliff:g> kulingana na jinsi unavyoitumia"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Betri inachaji, asilimia <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Mipangilio ya mfumo."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Arifa."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hadi macheo"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Itawashwa saa <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Hadi <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Mandhari Meusi"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Mandhari Meusi\nKiokoa betri"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Mandhari meusi"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Mandhari meusi\nKiokoa betri"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC imezimwa"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC imewashwa"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>+"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Arifa zisizo za dharura sana ziko hapo chini"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Gusa tena ili ufungue"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Telezesha kidole ili ufungue"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Telezesha kidole juu ili ufungue"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Kifaa hiki kinasimamiwa na shirika lako"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Kifaa hiki kinadhibitiwa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telezesha kidole kutoka kwa aikoni ili ufikie simu"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Usionyeshe tena"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Futa zote"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Dhibiti"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Arifa zisizo na sauti"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Futa arifa zote zisizo na sauti"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Kipengele cha Usinisumbue kimesitisha arifa"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Anza sasa"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Hakuna arifa"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Zuia"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Endelea kuonyesha"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Punguza"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Kimya"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Isitoe sauti"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Kutoa arifa"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Endelea kutoa arifa"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Zima arifa"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Ungependa kuendelea kuonyesha arifa kutoka programu hii?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Bila sauti"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Zilizopewa kipaumbele"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Hukusaidia kuangazia arifa pekee kwenye orodha kunjuzi. Kimya kila wakati."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Huonyeshwa chini ya arifa za kipaumbele. Kimya kila wakati."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Huonyeshwa chini ya arifa za kipaumbele. Kimya kila wakati."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Huonyeshwa chini ya arifa za kipaumbele. Kimya kila wakati."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Hupata umakinifu wako kwa sauti na aikoni ya sehemu ya arifa. Huonyeshwa kwenye skrini iliyofungwa."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Kimya"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Kutoa arifa"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Hukusaidia kuwa makini bila sauti au mtetemo."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Hupata umakinifu wako kwa sauti na mtetemo."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Arifa hizi haziwezi kubadilishwa."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Kikundi hiki cha arifa hakiwezi kuwekewa mipangilio hapa"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Arifa wakilishi"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Shikilia na uburute ili uongeze vigae"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Shikilia na uburute ili upange vigae upya"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Buruta hapa ili uondoe"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Unahitaji angalau vigae <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Badilisha"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Wakati"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Ruhusu"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Kataa"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Gusa ili uratibu wakati wa kuwasha Kiokoa Betri"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Washa wakati betri inakaribia kuisha"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Hapana, asante"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Ratiba ya Kiokoa Betri imewashwa"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Kiokoa Betri kitawaka kiotomatiki baada ya chaji ya betri kufika chini ya <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Sogeza chini kushoto"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Sogeza chini kulia"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Ondoa"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Umesasisha usogezaji kwenye mfumo. Ili ufanye mabadiliko, nenda kwenye Mipangilio."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Nenda kwenye mipangilio ili usasishe usogezaji kwenye mfumo"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/config.xml b/packages/SystemUI/res/values-ta/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ta/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index effa30b..9f8f45e 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB பிழைதிருத்தம் அனுமதிக்கப்படவில்லை"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"தற்போது இந்தச் சாதனத்தில் உள்நுழைந்துள்ள பயனரால் USB பிழைதிருத்தத்தை இயக்க முடியாது. இந்த அம்சத்தை இயக்க, முதன்மைப் பயனருக்கு மாறவும்."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB போர்ட் முடக்கப்பட்டது"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"தேவையற்றவையில் இருந்து உங்கள் சாதனத்தைப் பாதுகாக்க USB போர்ட் முடக்கப்பட்டுள்ளது. மேலும் எந்தத் துணைக் கருவிகளையும் அது கண்டறியாது.\n\nUSB போர்ட்டை மீண்டும் எப்போது பயன்படுத்தலாம் என்பதைப் பற்றி உங்களுக்குத் தெரிவிக்கப்படும்."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"சார்ஜர்களையும் துணைக்கருவிகளையும் கண்டறிவதற்காக USB போர்ட் இயக்கப்பட்டுள்ளது"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USBயை இயக்கு"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"மேலும் அறிக"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"திரையை நிரப்ப அளவை மாற்று"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"திரையை நிரப்ப இழு"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ஸ்கிரீன்ஷாட்"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"உங்கள் முகத்தை அங்கீகரிக்கிறது"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"முகம் அங்கீகரிக்கப்பட்டது"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"உறுதிப்படுத்தப்பட்டது"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"முடிக்க \'உறுதிப்படுத்து\' என்பதை தட்டவும்"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"கைரேகை சென்சாரைத் தொடவும்"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"கைரேகை ஐகான்"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"உங்கள் முகத்தைத் தேடுகிறது…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"மொபைல் நிறுவன நெட்வொர்க்கை மாற்றும்"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"பேட்டரி விவரங்களைத் திறக்கும்"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"பேட்டரி சக்தி <xliff:g id="NUMBER">%d</xliff:g> சதவிகிதம் உள்ளது."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"பேட்டரி: <xliff:g id="PERCENTAGE">%1$s</xliff:g> சதவீதம், உபயோகத்தின் அடிப்படையில் <xliff:g id="TIME">%2$s</xliff:g> மீதமுள்ளது"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"பேட்டரி சார்ஜ் செய்யப்படுகிறது, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> சதவீதம்."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"கணினி அமைப்பு."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"அறிவிப்புகள்."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"காலை வரை"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>க்கு ஆன் செய்"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> வரை"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"டார்க் தீம்"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"டார்க் தீம்\nபேட்டரி சேமிப்பான்"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"டார்க் தீம்"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"டார்க் தீம்\nபேட்டரி சேமிப்பான்"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC முடக்கப்பட்டது"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC இயக்கப்பட்டது"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"அவசர நிலைக் குறைவான அறிவிப்புகள் கீழே உள்ளன"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"திறக்க, மீண்டும் தட்டவும்"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"திறக்க, மேலே ஸ்வைப் செய்யவும்"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"இந்தச் சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"இந்தச் சாதனத்தை நிர்வகிப்பது: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ஃபோனிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"மீண்டும் காட்டாதே"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"எல்லாவற்றையும் அழி"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"அறிவிப்புகளை நிர்வகி"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"ஒலியில்லாத அறிவிப்புகள்"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ஒலியில்லாத அழைப்புகள் அனைத்தையும் அழிக்கும்"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தின் மூலம் அறிவிப்புகள் இடைநிறுத்தப்பட்டுள்ளன"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"இப்போது தொடங்கு"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"அறிவிப்புகள் இல்லை"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"தடு"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"அறிவிப்புகளைத் தொடர்ந்து காட்டு"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"சிறிதாக்கு"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"நிசப்தம்"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"அறிவிப்புகளை ஒலியின்றிக் காட்டு"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"விழிப்பூட்டல்"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"தொடர்ந்து விழிப்பூட்டு"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"அறிவிப்புகளை முடக்கு"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"இந்த ஆப்ஸின் அறிவிப்புகளைத் தொடர்ந்து காட்டவா?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"ஜென்டில்"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"முன்னுரிமைப்படுத்தப்பட்டது"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"கீழ் இழுக்கும் ஷேடில் வரும் அறிவிப்புகளில் மட்டும் கவனம் செலுத்த உதவுகிறது. எப்போதும் நிசப்தம்."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"குறைந்த முன்னுரிமைப் பெற்ற அறிவிப்புகளைக் காட்டும். எப்போதும் நிசப்தம்."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"குறைந்த முன்னுரிமைப் பெற்ற அறிவிப்புகளைக் காட்டும். எப்போதும் நிசப்தம்."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"குறைந்த முன்னுரிமைப் பெற்ற அறிவிப்புகளைக் காட்டும். எப்போதும் நிசப்தம்."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ஒலி &amp; நிலைப் பட்டி ஐகான் மூலம் உங்கள் கவனத்தைப் பெறுகிறது. பூட்டுத் திரையில் காட்டும்."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"நிசப்தம்"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"விழிப்பூட்டல்"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ஒலியோ அதிர்வோ இல்லாமல் முழு கவனம் செலுத்த உதவும்."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ஒலியோ அதிர்வோ ஏற்படுத்தி உங்கள் கவனத்தை ஈர்க்கும்."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"இந்த அறிவிப்புகளை மாற்ற இயலாது."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"இந்த அறிவுப்புக் குழுக்களை இங்கே உள்ளமைக்க இயலாது"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ப்ராக்ஸியான அறிவிப்பு"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"கட்டங்களைச் சேர்க்க, அவற்றைப் பிடித்து இழுக்கவும்"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"கட்டங்களை மறுவரிசைப்படுத்த அவற்றைப் பிடித்து இழுக்கவும்"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"அகற்ற, இங்கே இழுக்கவும்"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"குறைந்தது <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> கட்டங்கள் தேவை"</string>
     <string name="qs_edit" msgid="2232596095725105230">"மாற்று"</string>
     <string name="tuner_time" msgid="6572217313285536011">"நேரம்"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"அனுமதி"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"நிராகரி"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"பேட்டரி சேமிப்பானை ஆன் செய்வது தொடர்பாகத் திட்டமிட, தட்டவும்"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"பேட்டரி தீர்ந்துபோகும் நிலையில் இருக்கும் போது ஆன் செய்யப்படும்"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"வேண்டாம்"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"திட்டமிட்ட பேட்டரி சேமிப்பான் ஆன் செய்யப்பட்டது"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"பேட்டரியின் அளவு <xliff:g id="PERCENTAGE">%d</xliff:g>%%க்குக் கீழ் குறையும்போது, பேட்டரி சேமிப்பான் தானாகவே ஆன் செய்யப்படும்."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"கீழே இடப்புறமாக நகர்த்து"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"கீழே வலதுபுறமாக நகர்த்து"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"மூடுக"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"சிஸ்டம் நேவிகேஷன் மாற்றப்பட்டது. மாற்றங்களைச் செய்ய ‘அமைப்புகளுக்குச்’ செல்லவும்."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"சிஸ்டம் நேவிகேஷனை மாற்ற ’அமைப்புகளுக்குச்’ செல்லவும்"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/config.xml b/packages/SystemUI/res/values-te/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-te/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 5c12073..5717e02f 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన వినియోగదారు USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక వినియోగదారుకి మారాలి."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB పోర్ట్‌ నిలిపివేయబడింది"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"మీ పరికరంలోకి నీరు లేదా చెత్తాచెదారం చేరిపోకుండా కాపాడటానికి, USB పోర్ట్ నిలిపివేయబడుతుంది, అలాగే యాక్సెసరీలు వేటిని గుర్తించదు.\n\nUSB పోర్ట్‌ను ఉపయోగించడం సురక్షితమేనని నిర్ధారించుకున్న తర్వాత, మళ్లీ మీకో నోటిఫికేషన్‌ రూపంలో తెలియజేయబడుతుంది."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"ఛార్జర్‌లు, యాక్సెసరీలను గుర్తించే విధంగా USB పోర్ట్ ప్రారంభించబడింది"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USBని ప్రారంభించు"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"మరింత తెలుసుకోండి"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"స్క్రీన్‌కు నింపేలా జూమ్ చేయండి"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"స్క్రీన్‌కు నింపేలా విస్తరించండి"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"స్క్రీన్‌షాట్"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"మీ ముఖాన్ని క్యాప్చర్ చేస్తోంది"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"ముఖం ప్రామాణీకరించబడింది"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"నిర్ధారించబడింది"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"పూర్తి చేయడానికి \"నిర్ధారించు\" నొక్కండి"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"వేలిముద్ర సెన్సార్‌ను తాకండి"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"వేలిముద్ర చిహ్నం"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"మీ కోసం చూస్తోంది…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"క్యారియర్ నెట్‌వర్క్ మారుతోంది"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"బ్యాటరీ వివరాలను తెరుస్తుంది"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"బ్యాటరీ <xliff:g id="NUMBER">%d</xliff:g> శాతం."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"బ్యాటరీ <xliff:g id="PERCENTAGE">%1$s</xliff:g> శాతం ఉంది, మీ వినియోగాన్ని బట్టి <xliff:g id="TIME">%2$s</xliff:g> పని చేస్తుంది"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"బ్యాటరీ ఛార్జ్ అవుతోంది, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"సిస్టమ్ సెట్టింగ్‌లు."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"నోటిఫికేషన్‌లు."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"సూర్యోదయం వరకు"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g>కి"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> వరకు"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ముదురు రంగు థీమ్"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ముదురు రంగు థీమ్\nబ్యాటరీ సేవర్"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ముదురు రంగు థీమ్"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ముదురు రంగు థీమ్\nబ్యాటరీ సేవర్"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC నిలిపివేయబడింది"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ప్రారంభించబడింది"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"తక్కువ అత్యవసర నోటిఫికేషన్‌లు దిగువన"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"తెరవడానికి మళ్లీ నొక్కండి"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"అన్‌లాక్ చేయడానికి ఎగువకు స్వైప్ చేయండి"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"ఈ పరికరాన్ని మీ సంస్థ నిర్వహిస్తోంది"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> నిర్వహణలో ఉంది"</string>
     <string name="phone_hint" msgid="4872890986869209950">"ఫోన్ కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"మళ్లీ చూపవద్దు"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"అన్నీ క్లియర్ చేయండి"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"నిర్వహించండి"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"నిశ్శబ్ద నోటిఫికేషన్‌లు"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"అన్ని నిశ్శబ్ద నోటిఫికేషన్‌లను క్లియర్ చేస్తుంది"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"అంతరాయం కలిగించవద్దు ద్వారా నోటిఫికేషన్‌లు పాజ్ చేయబడ్డాయి"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ఇప్పుడే ప్రారంభించు"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"నోటిఫికేషన్‌లు లేవు"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"బ్లాక్ చేయి"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"చూపిస్తూనే ఉండు"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"కుదించు"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"నిశ్శబ్దం"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"నిశబ్దంగా తెలియజేయి"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"హెచ్చరించడం"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"ఎప్పటికప్పుడు హెచ్చరించు"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"నోటిఫికేషన్‌లను ఆఫ్ చేయి"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"ఈ యాప్ నుండి నోటిఫికేషన్‌లను చూపిస్తూ ఉండాలా?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"సాధారణ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ప్రాధాన్యం గలవి"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"కిందకు-లాగే షేడ్‌లో కనిపించే నోటిఫికేషన్‌ల మాత్రమే ద్వారా దృష్టి కేంద్రీకరించడానికి మీకు సహాయపడుతుంది. ఎల్లప్పుడూ నిశబ్దంగా ఉంచు."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"ప్రాధాన్యత గల నోటిఫికేషన్‌ల దిగువన ప్రదర్శిస్తుంది. ఎల్లప్పుడూ నిశబ్దంగా ఉంచు."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"ప్రాధాన్యత గల నోటిఫికేషన్‌ల దిగువన ప్రదర్శిస్తుంది. ఎల్లప్పుడూ నిశబ్దంగా ఉంచు."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"ప్రాధాన్యత గల నోటిఫికేషన్‌ల దిగువన ప్రదర్శిస్తుంది. ఎల్లప్పుడూ నిశబ్దంగా ఉంచు."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"శబ్దం &amp; స్టేటస్ బార్ చిహ్నం ద్వారా మీరు దృష్టి సారించేలా చేస్తుంది. లాక్ స్క్రీన్‌‌పై చూపుతుంది."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"నిశ్శబ్దం"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"హెచ్చరించడం"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"శబ్దం లేదా వైబ్రేషన్ లేకుండా దృష్టి కేంద్రీకరించడానికి మీకు సహాయపడుతుంది."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"శబ్దం లేదా వైబ్రేషన్‌తో మీరు దృష్టి సారించేలా చేస్తుంది."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ఈ నోటిఫికేషన్‌లను సవరించడం వీలుపడదు."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"ఈ నోటిఫికేషన్‌ల సమూహాన్ని ఇక్కడ కాన్ఫిగర్ చేయలేము"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"ప్రాక్సీ చేయబడిన నోటిఫికేషన్"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"టైల్‌లను జోడించడం కోసం పట్టుకుని, లాగండి"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"టైల్‌ల క్రమం మార్చడానికి వాటిని పట్టుకుని, లాగండి"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"తీసివేయడానికి ఇక్కడికి లాగండి"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"మీ వద్ద కనీసం <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> టైల్‌లు ఉండాలి"</string>
     <string name="qs_edit" msgid="2232596095725105230">"సవరించు"</string>
     <string name="tuner_time" msgid="6572217313285536011">"సమయం"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"అనుమతించు"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"తిరస్కరించు"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"బ్యాటరీ సేవర్‌ని షెడ్యూల్ చేయడానికి నొక్కండి"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"బ్యాటరీ ఛార్జింగ్ పూర్తిగా అయిపోతున్న తరుణంలో ఆన్ చేస్తుంది"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"వద్దు, ధన్యవాదాలు"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"బ్యాటరీ సేవర్ షెడ్యూల్ ఆన్ చేయబడింది"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"బ్యాటరీ <xliff:g id="PERCENTAGE">%d</xliff:g>%% కంటే తగ్గినప్పుడు బ్యాటరీ సేవర్ ఆటోమేటిక్‌గా ఆన్ అవుతుంది."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"దిగువ ఎడమవైపునకు తరలించు"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"దిగవు కుడివైపునకు జరుపు"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"విస్మరించు"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"సిస్టమ్ నావిగేషన్ అప్‌డేట్ చేయబడింది. మార్పులు చేయడానికి, సెట్టింగ్‌లకు వెళ్లండి."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"సిస్టమ్ నావిగేషన్‌ను అప్‌డేట్ చేయడానికి సెట్టింగ్‌లకు వెళ్లండి"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/config.xml b/packages/SystemUI/res/values-th/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-th/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 28ba865..ce123a5 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"ไม่อนุญาตให้แก้ไขข้อบกพร่องผ่าน USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"ผู้ใช้ที่ลงชื่อเข้าใช้อุปกรณ์อยู่ในขณะนี้ไม่สามารถเปิดการแก้ไขข้อบกพร่องผ่าน USB ได้ หากต้องการใช้ฟีเจอร์นี้ ให้เปลี่ยนไปเป็นผู้ใช้หลัก"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"พอร์ต USB ถูกปิดใช้"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"พอร์ต USB ปิดใช้อยู่และจะไม่ตรวจหาอุปกรณ์เสริมใดๆ เพื่อปกป้องอุปกรณ์จากของเหลวและฝุ่นละออง \n\nคุณจะได้รับแจ้งเมื่อใช้พอร์ต USB ได้อีกครั้ง"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"เปิดใช้พอร์ต USB แล้วเพื่อตรวจหาที่ชาร์จและอุปกรณ์เสริม"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"เปิดใช้ USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"ดูข้อมูลเพิ่มเติม"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"ขยายจนเต็มหน้าจอ"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"ยืดจนเต็มหน้าจอ"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"ภาพหน้าจอ"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"กำลังมองหาใบหน้าของคุณ"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"ตรวจสอบสิทธิ์ใบหน้าแล้ว"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"ยืนยันแล้ว"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"แตะยืนยันเพื่อดำเนินการให้เสร็จสมบูรณ์"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"แตะเซ็นเซอร์ลายนิ้วมือ"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"ไอคอนลายนิ้วมือ"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"กำลังหาใบหน้าคุณ…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"การเปลี่ยนเครือข่ายผู้ให้บริการ"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"เปิดรายละเอียดแบตเตอรี่"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"แบตเตอรี่ <xliff:g id="NUMBER">%d</xliff:g> เปอร์เซ็นต์"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"แบตเตอรี่ <xliff:g id="PERCENTAGE">%1$s</xliff:g> เปอร์เซ็นต์ ใช้ได้อีกประมาณ <xliff:g id="TIME">%2$s</xliff:g> ทั้งนี้ขึ้นอยู่กับการใช้งานของคุณ"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"กำลังชาร์จแบตเตอรี่ <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> เปอร์เซ็นต์"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"การตั้งค่าระบบ"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"การแจ้งเตือน"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"จนพระอาทิตย์ขึ้น"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"เปิดเวลา <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"จนถึง <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"ธีมสีเข้ม"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"ทีมสีเข้ม\nโหมดประหยัดแบตเตอรี่"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"ธีมสีเข้ม"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"ธีมสีเข้ม\nโหมดประหยัดแบตเตอรี่"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC ถูกปิดใช้งาน"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"เปิดใช้งาน NFC แล้ว"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"แตะอีกครั้งเพื่อเปิด"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"เลื่อนเพื่อปลดล็อก"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"เลื่อนขึ้นเพื่อเปิด"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"อุปกรณ์นี้จัดการโดยองค์กรของคุณ"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"อุปกรณ์เครื่องนี้จัดการโดย <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"เลื่อนไอคอนโทรศัพท์"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"ไม่ต้องแสดงข้อความนี้อีก"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"ล้างทั้งหมด"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"จัดการ"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"การแจ้งเตือนแบบไม่มีเสียง"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"ล้างการแจ้งเตือนแบบไม่มีเสียงทั้งหมด"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"หยุดการแจ้งเตือนชั่วคราวโดย \"ห้ามรบกวน\""</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"เริ่มเลย"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"ไม่มีการแจ้งเตือน"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"บล็อก"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"แสดงต่อไป"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"ย่อเล็กสุด"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"ปิดเสียง"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"ปิดเสียงไว้"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"แจ้งเตือน"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"แจ้งเตือนต่อไป"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"ปิดการแจ้งเตือน"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"แสดงการแจ้งเตือนจากแอปนี้ต่อไปไหม"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"แจ้งเตือนเบาๆ"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"สำคัญ"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"ช่วยให้คุณโฟกัสกับการแจ้งเตือนในหน้าต่างแบบเลื่อนลงเท่านั้น ปิดเสียงตลอดเวลา"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"แสดงใต้การแจ้งเตือนเรื่องสำคัญ ปิดเสียงตลอดเวลา"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"แสดงใต้การแจ้งเตือนเรื่องสำคัญ ปิดเสียงตลอดเวลา"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"แสดงใต้การแจ้งเตือนเรื่องสำคัญ ปิดเสียงตลอดเวลา"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"ดึงความสนใจของคุณด้วยเสียงและไอคอนในแถบสถานะ แสดงในหน้าจอล็อก"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"เงียบ"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"แจ้งเตือน"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"ช่วยรักษาสมาธิของคุณด้วยการไม่ส่งเสียงหรือสั่น"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"ดึงความสนใจของคุณด้วยเสียงและการสั่น"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"แก้ไขการแจ้งเตือนเหล่านี้ไม่ได้"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"การแจ้งเตือนกลุ่มนี้กำหนดค่าที่นี่ไม่ได้"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"การแจ้งเตือนที่ผ่านพร็อกซี"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"กดค้างแล้วลากเพื่อเพิ่มไทล์"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"กดไทล์ค้างไว้แล้วลากเพื่อจัดเรียงใหม่"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"ลากมาที่นี่เพื่อนำออก"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"คุณต้องมีการ์ดอย่างน้อย <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> รายการ"</string>
     <string name="qs_edit" msgid="2232596095725105230">"แก้ไข"</string>
     <string name="tuner_time" msgid="6572217313285536011">"เวลา"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"อนุญาต"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"ปฏิเสธ"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"แตะเพื่อตั้งเวลาโหมดประหยัดแบตเตอรี่"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"เปิดเมื่อมีแนวโน้มว่าแบตเตอรี่จะหมด"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"ไม่เป็นไร"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"เปิดใช้กำหนดเวลาโหมดประหยัดแบตเตอรี่อยู่"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"โหมดประหยัดแบตเตอรี่จะเปิดโดยอัตโนมัติเมื่อแบตเตอรี่เหลือไม่ถึง <xliff:g id="PERCENTAGE">%d</xliff:g>%%"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"ย้ายไปด้านซ้ายล่าง"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"ย้ายไปด้านขาวล่าง"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"ปิด"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"อัปเดตการไปยังส่วนต่างๆ ของระบบแล้ว หากต้องการเปลี่ยนแปลง ให้ไปที่การตั้งค่า"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"ไปที่การตั้งค่าเพื่ออัปเดตการไปยังส่วนต่างๆ ของระบบ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/config.xml b/packages/SystemUI/res/values-tl/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-tl/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e1e16cc..0ab01d8 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Hindi pinapayagan ang pagde-debug sa pamamagitan ng USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Hindi mao-on ng user na kasalukuyang naka-sign in sa device na ito ang pag-debug ng USB. Upang magamit ang feature na ito, lumipat sa pangunahing user."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Na-disable ang USB port"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Para protektahan ang iyong device sa likido o dumi, na-disable ang USB port at hindi ito makaka-detect ng anumang accessory.\n\nAabisuhan ka kapag ayos nang gamitin ulit ang USB port."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Na-enable ang USB port para ma-detect ang mga charger at accessory"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"I-enable ang USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Matuto pa"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"I-zoom upang punan screen"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"I-stretch upang mapuno screen"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Screenshot"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Hinahanap ang iyong mukha"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Na-authenticate ang mukha"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Nakumpirma"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"I-tap ang Kumpirmahin para kumpletuhin"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Pindutin ang fingerprint sensor"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Icon ng fingerprint"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Hinahanap ka…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Nagpapalit ng carrier network"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Buksan ang mga detalye ng baterya"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterya <xliff:g id="NUMBER">%d</xliff:g> (na) porsyento."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> (na) porsyento ang baterya, nasa <xliff:g id="TIME">%2$s</xliff:g> ang natitira batay sa paggamit mo"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Nagcha-charge ang baterya, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> (na) porsyento."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Mga setting ng system."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Mga Notification."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Hanggang sunrise"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Mao-on sa ganap na <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Hanggang <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Madilim na Tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Madilim na Tema\nPangtipid sa Baterya"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Madilim na tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Madilim na tema\nPangtipid sa baterya"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"Naka-disable ang NFC"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"Naka-enable ang NFC"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Nasa ibaba ang mga notification na hindi masyadong mahalaga"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"I-tap ulit upang buksan"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"I-swipe pataas upang i-unlock"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Mag-swipe pataas para buksan"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Ang device na ito ay pinamamahalaan ng iyong organisasyon"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Mag-swipe mula sa icon para sa telepono"</string>
@@ -454,14 +454,12 @@
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"I-off ang Pangtipid sa Baterya"</string>
     <string name="media_projection_dialog_text" msgid="8585357687598538511">"Habang nagre-record o nagka-cast, puwedeng kunin ng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ang anumang sensitibong impormasyong ipinapakita sa iyong screen o pine-play mula sa device mo, kasama ang sensitibong impormasyon gaya ng audio, mga password, impormasyon sa pagbabayad, mga larawan, at mga mensahe."</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Habang nagre-record o nagka-cast, puwedeng kunin ng serbisyong nagbibigay ng function na ito ang anumang sensitibong impormasyong ipinapakita sa iyong screen o pine-play mula sa device mo, kasama ang sensitibong impormasyon gaya ng audio, mga password, impormasyon sa pagbabayad, mga larawan, at mga mensahe."</string>
-    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Maglalantad ng sensitibong impormasyon habang nagka-cast/nagre-record"</string>
+    <string name="media_projection_dialog_title" msgid="8124184308671641248">"Mag-e-expose ng sensitibong impormasyon habang nagka-cast/nagre-record"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Huwag ipakitang muli"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"I-clear lahat"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Pamahalaan"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Mga silent na notification"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"I-clear ang lahat ng silent na notification"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Mga notification na na-pause ng Huwag Istorbohin"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Magsimula ngayon"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Walang mga notification"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"I-block"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Patuloy na ipakita"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"I-minimize"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Silent"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Manatiling naka-silent"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Mag-alerto"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Patuloy na mag-alerto"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"I-off ang mga notification"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Patuloy na ipakita ang mga notification mula sa app na ito?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Malumanay"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Priyoridad"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Nakakatulong para hindi ka maabala dahil sa pull-down na shade lang lalabas ang mga notification. Palaging naka-silent."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Ipinapakita sa ibaba ng mga priyoridad na notification. Palaging naka-silent."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Ipinapakita sa ibaba ng mga priyoridad na notification. Palaging naka-silent."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Ipinapakita sa ibaba ng mga priyoridad na notification. Palaging naka-silent."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Kinukuha ang iyong atensyon gamit ang tunog at icon sa status bar. Ipinapakita sa lock screen."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Naka-silent"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Mag-alerto"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Nakakatulong sa iyong tumuon nang walang tunog o pag-vibrate."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Kinukuha ang iyong atensyon sa pamamagitan ng tunog o pag-vibrate."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Hindi puwedeng baguhin ang mga notification na ito."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Hindi mako-configure dito ang pangkat na ito ng mga notification"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Na-proxy na notification"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Pindutin nang matagal at i-drag para magdagdag ng mga tile"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Pindutin nang matagal at i-drag para ayusin ulit ang tile"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"I-drag dito upang alisin"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Kailangan mo ng kahit <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> (na) tile"</string>
     <string name="qs_edit" msgid="2232596095725105230">"I-edit"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Oras"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Payagan"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Tanggihan"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"I-tap para iiskedyul ang Pangtipid sa Baterya"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"I-on kapag malamang na maubos ang baterya"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Hindi, salamat na lang"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Na-on ang iskedyul ng Pangtipid sa Baterya"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Awtomatikong mao-on ang Pangtipid sa Baterya kapag mas mababa na sa <xliff:g id="PERCENTAGE">%d</xliff:g>%% ang baterya."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Ilipat sa kaliwa sa ibaba"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Ilipat sa kanan sa ibaba"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"I-dismiss"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Na-update na ang pag-navigate ng system. Para gumawa ng mga pagbabago, pumunta sa Mga Setting."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Pumunta sa Mga Setting para i-update ang pag-navigate sa system"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/config.xml b/packages/SystemUI/res/values-tr/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-tr/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index a4be5c2..4e2a891 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB hata ayıklama işlevine izin verilmiyor"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Bu cihazda geçerli olarak oturum açmış olan kullanıcı, USB hata ayıklama özelliğini açamaz. Bu özelliği kullanmak için birincil kullanıcıya geçin."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB bağlantı noktası devre dışı bırakıldı"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Cihazınızı sıvılardan veya tozlardan korumak için USB bağlantı noktası devre dışı bırakıldı ve aksesuarları algılamayacak.\n\nUSB bağlantı noktasını tekrar sorunsuz kullanabileceğiniz zaman bilgilendirileceksiniz."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB bağlantı noktası, şarj cihazlarını ve aksesuarları algılamak üzere etkinleştirildi"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB\'yi etkinleştir"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Daha fazla bilgi"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Yakınlaştır (ekranı kaplasın)"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Genişlet (ekran kapansın)"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Ekran görüntüsü"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Yüzünüz aranıyor"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Yüz kimliği doğrulandı"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Onaylandı"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tamamlamak için Onayla\'ya dokunun"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Parmak izi sensörüne dokunun"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Parmak izi simgesi"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Yüzünüz tanınmaya çalışılıyor…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Operatör ağı değiştiriliyor"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Pil ayrıntılarını aç"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Pil yüzdesi: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Pil yüzde <xliff:g id="PERCENTAGE">%1$s</xliff:g> dolu. Kullanımınıza göre yaklaşık <xliff:g id="TIME">%2$s</xliff:g> süresi kaldı"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Pil şarj oluyor, yüzde <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Sistem ayarları."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Bildirimler."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Gün doğumuna kadar"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Şu saatte açılacak: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Şu saate kadar: <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Koyu Tema"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Koyu Tema\nPil tasarrufu"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Koyu tema"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Koyu tema\nPil tasarrufu"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC devre dışı"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC etkin"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az acil bildirimler aşağıdadır"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Açmak için tekrar dokunun"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Kilidi açmak için hızlıca yukarı kaydırın"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Açmak için yukarı kaydırın"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu cihaz kuruluşunuz tarafından yönetiliyor"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarafından yönetilmektedir."</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefon için, simgeden hızlıca kaydırın"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Bir daha gösterme"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Tümünü temizle"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Yönet"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Sessiz bildirimler"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Sessiz bildirimlerin tümünü temizle"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Bildirimler, Rahatsız Etmeyin özelliği tarafından duraklatıldı"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Şimdi başlat"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Bildirim yok"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Engelle"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Göstermeye devam et"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Küçült"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Sessiz"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Sessiz uyarı göster"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Uyarı"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Uyarıda bulunmaya devam et"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Bildirimleri kapat"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu uygulamadan gelen bildirimler gösterilmeye devam edilsin mi?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Sessiz"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Öncelikli"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Bildirimleri yalnızca aşağıya açılır gölgede göstererek işinize odaklanmanızı sağlar. Her zaman sessizdir."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Öncelikli bildirimlerin altında görüntülenir. Her zaman sessizdir."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Öncelikli bildirimlerin altında görüntülenir. Her zaman sessizdir."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Öncelikli bildirimlerin altında görüntülenir. Her zaman sessizdir."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Ses ve bir durum çubuğu simgesiyle dikkatinizi çeker. Kilit ekranında gösterilir."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Sessiz"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Uyarı"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ses veya titreşim olmadan odaklanmanıza yardımcı olur."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ses veya titreşimle dikkatinizi çeker."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirimler değiştirilemez."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Bu bildirim grubu burada yapılandırılamaz"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Proxy uygulanan bildirim"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Blok eklemek için basılı tutup sürükleyin"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Blokları yeniden düzenlemek için basılı tutun ve sürükleyin"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Kaldırmak için buraya sürükleyin"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"En az <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> blok gerekiyor"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Düzenle"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Saat"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"İzin ver"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Reddet"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Pil Tasarrufunu programlamak için dokunun"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Piliniz bitecek gibiyse bu özelliği açın"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Hayır, teşekkürler"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Pil Tasarruf programı açık"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Pil %%<xliff:g id="PERCENTAGE">%d</xliff:g> düzeyinin altına düştüğünde Pil Tasarrufu otomatik olarak açılacaktır."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Sol alta taşı"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Sağ alta taşı"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Kapat"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Sistemde gezinme yöntemi güncellendi. Değişiklik yapmak için Ayarlar\'a gidin."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Sistemde gezinme yöntemini güncellemek için Ayarlar\'a gidin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/config.xml b/packages/SystemUI/res/values-uk/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-uk/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 1352541..56521f6 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -33,7 +33,7 @@
     <string name="invalid_charger_title" msgid="2836102177577255404">"Не вдається зарядити через USB"</string>
     <string name="invalid_charger_text" msgid="6480624964117840005">"Використовуйте зарядний пристрій, який входить у комплект пристрою"</string>
     <string name="battery_low_why" msgid="4553600287639198111">"Налаштування"</string>
-    <string name="battery_saver_confirmation_title" msgid="2052100465684817154">"Увімкнути режим економії заряду акумулятора?"</string>
+    <string name="battery_saver_confirmation_title" msgid="2052100465684817154">"Увімкнути режим енергозбереження?"</string>
     <string name="battery_saver_confirmation_title_generic" msgid="2090922638411744540">"Про режим енергозбереження"</string>
     <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Увімкнути"</string>
     <string name="battery_saver_start_action" msgid="8187820911065797519">"Увімкнути режим економії заряду акумулятора"</string>
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Ви не можете вмикати налагодження USB"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Користувач поточного облікового запису не може вмикати налагодження USB. Щоб увімкнути цю функцію, увійдіть в обліковий запис основного користувача."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB-порт вимкнено"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Щоб захистити ваш пристрій від рідини та сміття, USB-порт вимкнено. Він не виявлятиме жодних аксесуарів.\n\nКоли USB-порт можна буде використовувати, ви отримаєте сповіщення."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Порт USB виявлятиме зарядні пристрої та аксесуари"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Увімкнути USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Докладніше"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Масштабув. на весь екран"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Розтягнути на весь екран"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Знімок екрана"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Триває розпізнавання обличчя"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Обличчя автентифіковано"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Підтверджено"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Щоб завершити, натисніть \"Підтвердити\""</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Торкніться сканера відбитків пальців"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Значок відбитка пальця"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Пошук обличчя…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Змінення мережі оператора"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Відкрити деталі акумулятора"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Заряд акумулятора у відсотках: <xliff:g id="NUMBER">%d</xliff:g>."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Згідно з даними про використання залишилося <xliff:g id="PERCENTAGE">%1$s</xliff:g> заряду акумулятора – близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Акумулятор заряджається: <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Налаштування системи."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Сповіщення."</string>
@@ -380,8 +380,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"До сходу сонця"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Вмикається о <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"До <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Темна тема"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Нічний режим\nЕнергозбереження"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Темна тема"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Темна тема\nЕнергозбереження"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC вимкнено"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC ввімкнено"</string>
@@ -404,7 +404,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Менше термінових сповіщень нижче"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Торкніться знову, щоб відкрити"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Проведіть пальцем угору, щоб розблокувати"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Проведіть пальцем угору, щоб відкрити"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Цим пристроєм керує адміністратор вашої організації"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Цим пристроєм керує організація <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Телефон: проведіть пальцем від значка"</string>
@@ -455,7 +455,7 @@
     <string name="user_remove_user_title" msgid="4681256956076895559">"Видалити користувача?"</string>
     <string name="user_remove_user_message" msgid="1453218013959498039">"Усі додатки й дані цього користувача буде видалено."</string>
     <string name="user_remove_user_remove" msgid="7479275741742178297">"Видалити"</string>
-    <string name="battery_saver_notification_title" msgid="8614079794522291840">"Режим економії заряду акумулятора ввімкнено"</string>
+    <string name="battery_saver_notification_title" msgid="8614079794522291840">"Режим енергозбереження ввімкнено"</string>
     <string name="battery_saver_notification_text" msgid="820318788126672692">"Знижується продуктивність і обмежуються фонові дані"</string>
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"Вимкнути режим економії заряду акумулятора"</string>
     <string name="media_projection_dialog_text" msgid="8585357687598538511">"Під час запису або трансляції додаток <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> може фіксувати будь-яку конфіденційну інформацію (зокрема, аудіо, паролі, платіжну інформацію, фотографії та повідомлення), яка з\'являється на екрані або відтворюється на пристрої."</string>
@@ -464,10 +464,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Більше не показувати"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Очистити все"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Керувати"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Беззвучні сповіщення"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Очистити всі беззвучні сповіщення"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Режим \"Не турбувати\" призупинив сповіщення"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Почати зараз"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Сповіщень немає"</string>
@@ -651,21 +649,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Блокувати"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Показувати надалі"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Згорнути"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Без звуку"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Без звуку"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Сповіщення"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Отримувати сповіщення"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Вимкнути сповіщення"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Чи показувати сповіщення з цього додатка надалі?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Тихі сповіщення"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Пріоритетні сповіщення"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Сповіщення показуються лише на розкривній панелі, щоб не відволікати. Завжди без звуку."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Показуються під пріоритетними сповіщеннями. Завжди без звуку."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Показуються під пріоритетними сповіщеннями. Завжди без звуку."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Показуються під пріоритетними сповіщеннями. Завжди без звуку."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Привертають увагу сигналом і значком у рядку стану. Показуються на заблокованому екрані."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Без звуку"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Зі звуком"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Не відволікає увагу звуковим сигналом або вібрацією."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Привертає увагу звуковим сигналом або вібрацією."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Ці сповіщення не можна змінити."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Цю групу сповіщень не можна налаштувати тут"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Проксі-сповіщення"</string>
@@ -796,8 +789,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Перетягніть потрібні елементи, щоб додати їх"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Щоб змінити порядок елементів, перетягуйте їх"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Перетягніть сюди, щоб видалити"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Мінімальна кількість фрагментів: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Редагувати"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Час"</string>
   <string-array name="clock_options">
@@ -919,10 +911,9 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дозволити"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Відмовити"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Торкніться, щоб увімкнути автоматичний режим економії заряду акумулятора"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Вмикати, коли заряд акумулятора закінчується"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Ні, дякую"</string>
-    <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Автоматичний режим економії заряду акумулятора ввімкнено"</string>
+    <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Автоматичний перехід у режим енергозбереження ввімкнено"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Режим економії заряду акумулятора вмикається автоматично, коли рівень заряду нижчий за <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="open_saver_setting_action" msgid="8314624730997322529">"Налаштування"</string>
     <string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
@@ -953,4 +944,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Перемістити ліворуч униз"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Перемістити праворуч униз"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Закрити"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Навігацію в системі оновлено. Щоб внести зміни, перейдіть у налаштування."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Перейдіть у налаштування, щоб оновити навігацію в системі"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/config.xml b/packages/SystemUI/res/values-ur/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-ur/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 6454455..b698fe4 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"‏USB ڈیبگ کرنے کی اجازت نہیں ہے"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"‏اس آلہ پر فی الحال سائن ان کردہ صارف USB ڈیبگنگ آن نہیں کر سکتا۔ اس خصوصیت کا استعمال کرنے کیلئے، ابتدائی صارف پر سوئچ کریں۔"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"‏USB پورٹ غیر فعال ہو گیا"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"‏آپ کے آلے کی سیال یا دھول سے حفاظت کرنے کے لیے، USB پورٹ کو غیر فعال کر دیا گیا ہے اور یہ کسی لوازم کا پتہ نہیں لگا پائے گا۔\n\nUSB پورٹ کا دوبارہ استعمال کرنا ٹھیک ہونے پر آپ کو مطلع کیا جائے گا۔"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"‏چارجرز اور لوازمات کا پتا لگانے کے لیے USB پورٹ فعال ہے"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"‏USB پورٹ فعال کریں"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"مزید جانیں"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"پوری سکرین پر زوم کریں"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"پوری سکرین پر پھیلائیں"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"اسکرین شاٹ"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"آپ کا چہرہ تلاش کیا جا رہا ہے"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"چہرے کی تصدیق ہو گئی"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"تصدیق شدہ"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"مکمل کرنے کیلئے \'تصدیق کریں\' تھپتھپائیں"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"فنگر پرنٹ سینسر پر ٹچ کریں"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"فنگر پرنٹ آئیکن"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"آپ کے لیے تلاش کیا جا رہا ہے…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"کیریئر نیٹ ورک کی تبدیلی"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"بیٹری کی تفصیلات کھولیں"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"بیٹری <xliff:g id="NUMBER">%d</xliff:g> فیصد۔"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"آپ کے استعمال کی بنیاد پر بیٹری <xliff:g id="PERCENTAGE">%1$s</xliff:g> فیصد، تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی ہے"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"بیٹری چارج ہو رہی ہے، <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"سسٹم کی ترتیبات۔"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"اطلاعات۔"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"طلوع آفتاب تک"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"آن ہوگی بوقت <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> تک"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"گہری تھیم"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"گہری تھیم\nبیٹری سیور"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"گہری تھیم"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"گہری تھیم\nبیٹری سیور"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"‏NFC غیر فعال ہے"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"‏NFC فعال ہے"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"‎+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>‎"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"کم اہم اطلاعات ذیل میں ہیں"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"کھولنے کیلئے دوبارہ تھپتھپائیں"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"غیر مقفل کرنے کیلئے اوپر سوائپ کریں"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"کھولنے کے لیے اوپر سوائپ کريں"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"یہ آلہ آپ کی تنظیم کے زیر انتظام ہے"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> کے زیر انتظام ہے"</string>
     <string name="phone_hint" msgid="4872890986869209950">"فون کیلئے آئیکن سے سوائپ کریں"</string>
@@ -454,14 +454,12 @@
     <string name="battery_saver_notification_action_text" msgid="132118784269455533">"بیٹری سیور آف کریں"</string>
     <string name="media_projection_dialog_text" msgid="8585357687598538511">"ریکارڈ یا کاسٹ کرنے کے دوران، <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> کسی بھی ایسی حساس معلومات کو کیپچر کر سکتا ہے جو آپ کی اسکرین پر ڈسپلے ہوتی ہے یا آپ کے آلہ سے چلائی جاتی ہے، بشمول حساس معلومات جیسے کہ آڈیو، پاسورڈز، ادائیگی کی معلومات، تصاویر اور پیغامات۔"</string>
     <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"ریکارڈ یا کاسٹ کرنے کے دوران، اس فنکشن کی خدمت کا فراہم کنندہ کسی بھی ایسی حساس معلومات کو کیپچر کر سکتا ہے جو آپ کی اسکرین پر ڈسپلے ہوتی ہے یا آپ کے آلہ سے چلائی جاتی ہے، بشمول حساس معلومات جیسے کہ آڈیو، پاسورڈز، ادائیگی کی معلومات، تصاویر اور پیغامات۔"</string>
-    <string name="media_projection_dialog_title" msgid="8124184308671641248">"کاسٹ/ریکارڈ کرنے کے دوران حساس معلومات کا افشاء کیا جا رہا ہے"</string>
+    <string name="media_projection_dialog_title" msgid="8124184308671641248">"کاسٹ/ریکارڈ کرنے کے دوران حساس معلومات کا افشاء"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"دوبارہ نہ دکھائیں"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"سبھی کو صاف کریں"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"نظم کریں"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"اطلاعات خاموش کریں"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"سبھی خاموش اطلاعات کو صاف کریں"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"\'ڈسٹرب نہ کریں\' کے ذریعے اطلاعات کو موقوف کیا گیا"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"ابھی شروع کریں"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"کوئی اطلاعات نہیں ہیں"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"مسدود کریں"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"دکھانا جاری رکھیں"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"چھوٹا کریں"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"خاموش کریں"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"خاموش رہیں"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"الرٹ کرنا"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"متنبہ کرنا جاری رکھیں"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"اطلاعات کو آف کریں"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"اس ایپ کی طرف سے اطلاعات دکھانا جاری رکھیں؟"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"لطیف"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"ترجیحی"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"صرف نیچے کی طرف کھینچیں شیڈ میں اطلاعات کے ساتھ فوکس کرنے میں آپ کی مدد کرتا ہے۔ ہمیشہ خاموش۔"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"کم ترجیحی اطلاعات ڈسپلے کرتا ہے۔ ہمیشہ خاموش۔"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"کم ترجیحی اطلاعات ڈسپلے کرتا ہے۔ ہمیشہ خاموش۔"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"کم ترجیحی اطلاعات ڈسپلے کرتا ہے۔ ہمیشہ خاموش۔"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"آواز اور اسٹیٹس بار کے آئیکن کے ساتھ آپ کی توجہ حاصل کرتا ہے۔ مقفل اسکرین پر دکھاتا ہے۔"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"خاموش"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"الرٹ کرنا"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"بغیر آواز یا وائبریشن کے آپ کو فوکس کرنے میں مدد کرتا ہے۔"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"آواز اور وائبریشن کے ذریعے آپ کی توجہ حاصل کرتا ہے۔"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"ان اطلاعات کی ترمیم نہیں کی جا سکتی۔"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"اطلاعات کے اس گروپ کو یہاں کنفیگر نہیں کیا جا سکتا"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"پراکسی اطلاع"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"ٹائلز شامل کرنے کے لئے پکڑ کر گھسیٹیں"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"ٹائلز کو دوبارہ ترتیب دینے کیلئے پکڑ کر گھسیٹیں"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"ہٹانے کیلئے یہاں گھسیٹیں؟"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"آپ کو کم از کم <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ٹائلز کی ضرورت ہے"</string>
     <string name="qs_edit" msgid="2232596095725105230">"ترمیم کریں"</string>
     <string name="tuner_time" msgid="6572217313285536011">"وقت"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"اجازت دیں"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"مسترد کریں"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"بیٹری سیور شیڈول کرنے کے لیے تھپتھپائیں"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"جب بیٹری کے ختم ہونے کا امکان ہو تو آن کریں"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"نہیں شکریہ"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"بیٹری سیور شیڈول آن ہو گیا"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"بیٹری کے <xliff:g id="PERCENTAGE">%d</xliff:g>%% سے کم ہونے پر بیٹری سیور خودکار طور پر آن ہو جائے گا۔"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"نیچے بائیں جانب لے جائیں"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"نیچے دائیں جانب لے جائیں"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"برخاست کریں"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"سسٹم نیویگیشن اپ ڈیٹ کیا گیا۔ تبدیلیاں کرنے کے لیے، ترتیبات پر جائیں۔"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"سسٹم نیویگیشن اپ ڈیٹ کرنے کے لیے ترتیبات پر جائیں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/config.xml b/packages/SystemUI/res/values-uz/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-uz/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index f917739..c732d4c 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB orqali nosozliklarni tuzatishga ruxsat berilmagan"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Ayni paytda ushbu qurilmaga o‘z hisobi bilan kirgan foydalanuvchi USB orqali nosozliklarni tuzatish funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun asosiy foydalanuvchi profiliga o‘ting."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB port faolsizlashtirildi"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Qurilmangizni suyuqlik va turli parchalardan himoya qilish uchun USB port faolsizlashtiriladi va hech qanday aksessuarni aniqlay olmaydi.\n\nUSB portdan xavfsiz foydalanish mumkin boʻlganda, sizga xabar beriladi."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Quvvatlash moslamalari va aksessuarlarni aniqlash uchun USB port yoqildi"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"USB xususiyatini yoqish"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Batafsil"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Ekranga moslashtirish"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ekran hajmida cho‘zish"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Skrinshot"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Yuz tekshirilmoqda"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Yuzingiz aniqlandi"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Tasdiqlangan"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Tasdiqlash uchun tegining"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Barmoq izi skaneriga tegining"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Barmoq izi belgisi"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Yuzingiz tekshirilmoqda…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mobil tarmoqni o‘zgartirish"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Quvvat sarfi tafsilotlari"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> foiz."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Batareya quvvati <xliff:g id="PERCENTAGE">%1$s</xliff:g> foiz, joriy holatda yana <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Batareya quvvat olmoqda (<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%)."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Tizim sozlamalari."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Eslatmalar."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Quyosh chiqqunicha"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> da yoqish"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> gacha"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Tungi mavzu"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Tungi mavzu\nQuvvat tejash"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Tungi mavzu"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Tungi mavzu\nQuvvat tejash"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC o‘chiq"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC yoniq"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Kam ahamiyatli bildirishnomalarni pastda ko‘rsatish"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Ochish uchun yana bosing"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Qulfdan chiqarish uchun tepaga suring"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Ochish uchun tepaga suring"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu – tashkilotingiz tomonidan boshqariladigan qurilma"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu – <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tomonidan boshqariladigan qurilma"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Telefonni ochish uchun suring"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Boshqa ko‘rsatilmasin"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hammasini tozalash"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Boshqarish"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Ovozsiz bildirishnomalar"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Barcha tovushsiz bildirishnomalarni tozalash"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilingan"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Boshlash"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Bildirishnomalar yo‘q"</string>
@@ -590,7 +588,7 @@
     <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Quvvat olmayotgan vaqtda batareya foizi holat qatorida chiqib turadi"</string>
     <string name="quick_settings" msgid="10042998191725428">"Tezkor sozlamalar"</string>
     <string name="status_bar" msgid="4877645476959324760">"Holat qatori"</string>
-    <string name="overview" msgid="4018602013895926956">"Umumiy ma’lumot"</string>
+    <string name="overview" msgid="4018602013895926956">"Umumiy"</string>
     <string name="demo_mode" msgid="2532177350215638026">"Tizim interfeysi demo rejimi"</string>
     <string name="enable_demo_mode" msgid="4844205668718636518">"Demo rejimni yoqish"</string>
     <string name="show_demo_mode" msgid="2018336697782464029">"Demo rejimni ko‘rsatish"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Bloklash"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Ha"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Kichraytirish"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Tovushsiz"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Ovozsiz qolsin"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Bildirishnoma yuborish"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Signal berishda davom etilsin"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Bildirishnoma kelmasin"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu ilovadan keladigan bildirishnomalar chiqaversinmi?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Tovushsiz"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Muhim"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Bildirishnomalar faqat maxsus panelda chiqadi. Doim tovushsiz."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Muhimlik darajasi past bildirishnomalarning chiqishi. Doim tovushsiz."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Muhimlik darajasi past bildirishnomalarning chiqishi. Doim tovushsiz."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Muhimlik darajasi past bildirishnomalarning chiqishi. Doim tovushsiz."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Kelgan bildirishnomalarni maxsus tovush va holat paneliga chiqadigan nishoncha orqali bilish mumkin. Bildirishnomalar ekran qulfida ham chiqadi."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Tovushsiz"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Bildirishnoma yuborish"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Bildirishnomalar tovush va tebranishsiz keladi."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Bildirishnomalar tovush va tebranish bilan keladi."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Bu bildirishnomalarni tahrirlash imkonsiz."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Ushbu bildirishnomalar guruhi bu yerda sozlanmaydi"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Ishonchli bildirishnoma"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Keraklisini ushlab torting"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Qayta tartiblash uchun ushlab torting"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"O‘chirish uchun bu yerga torting"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Kamida <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ta katakcha lozim"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Tahrirlash"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Vaqt"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Ruxsat"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Rad etish"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Quvvat tejash rejimini rejalashtirish uchun bosing"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Batareya quvvati kamayishi aniqlanganda yoqilsin"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Kerak emas"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Quvvat tejash rejimi jadvali faollashtirildi"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Batareya quvvati <xliff:g id="PERCENTAGE">%d</xliff:g>%% ga tushsa, quvvat tejash rejimi avtomatik ravishda yoqiladi."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Quyi chapga surish"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Quyi oʻngga surish"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Yopish"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Tizim navigatsiyasi yangilandi. Buni Sozlamalar orqali oʻzgartirishingiz mumkin."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Tizim navigatsiyasini yangilash uchun Sozlamalarni oching"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/config.xml b/packages/SystemUI/res/values-vi/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-vi/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 1bb241f..affca3d 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Tính năng gỡ lỗi USB không được phép"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Người dùng hiện đã đăng nhập vào thiết bị này không thể bật tính năng gỡ lỗi USB. Để sử dụng tính năng này, hãy chuyển sang người dùng chính."</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"Đã tắt cổng USB"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"Để bảo vệ thiết bị của bạn khỏi chất lỏng hay mảnh vỡ, cổng USB sẽ tắt và không phát hiện được bất kỳ phụ kiện nào.\n\nBạn sẽ nhận được thông báo khi có thể sử dụng lại cổng USB."</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"Đã bật cổng USB để phát hiện bộ sạc và phụ kiện"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"Bật USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"Tìm hiểu thêm"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"T.phóng để lấp đầy m.hình"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Giãn ra để lấp đầy m.hình"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"Chụp màn hình"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Đang tìm khuôn mặt của bạn"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Đã xác thực khuôn mặt"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Ðã xác nhận"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Nhấn vào Xác nhận để hoàn tất"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Chạm vào cảm biến vân tay"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Biểu tượng vân tay"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Đang tìm kiếm bạn…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Thay đổi mạng của nhà mạng"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Mở chi tiết về pin"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"<xliff:g id="NUMBER">%d</xliff:g> phần trăm pin."</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> phần trăm pin, còn khoảng <xliff:g id="TIME">%2$s</xliff:g> dựa trên mức sử dụng của bạn"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Đang sạc pin, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Cài đặt hệ thống"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Thông báo."</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Cho đến khi trời sáng"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Bật vào lúc <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Cho đến <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Giao diện tối"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Giao diện tối\nTrình tiết kiệm pin"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Giao diện tối"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Giao diện tối\nTrình tiết kiệm pin"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC đã được tắt"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC đã được bật"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Thông báo ít khẩn cấp hơn bên dưới"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Nhấn lại để mở"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Vuốt lên để mở khóa"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Vuốt lên để mở"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Thiết bị này do tổ chức của bạn quản lý"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Thiết bị này được <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> quản lý"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Vuốt từ biểu tượng để mở điện thoại"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Không hiển thị lại"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Xóa tất cả"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"Quản lý"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"Thông báo im lặng"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Xóa tất cả thông báo im lặng"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Chế độ Không làm phiền đã tạm dừng thông báo"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Bắt đầu ngay"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Không có thông báo nào"</string>
@@ -532,7 +530,7 @@
     <string name="accessibility_volume_settings" msgid="4915364006817819212">"Cài đặt âm thanh"</string>
     <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mở rộng"</string>
     <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Thu gọn"</string>
-    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Tự động chú thích nội dung"</string>
+    <string name="volume_odi_captions_tip" msgid="1193653197906918269">"Tự động tạo phụ đề cho nội dung nghe nhìn"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="1163987066404128967">"Đóng mẹo về chú thích"</string>
     <string name="volume_odi_captions_content_description" msgid="2950736796270214785">"Lớp phủ phụ đề"</string>
     <string name="volume_odi_captions_hint_enable" msgid="49750248924730302">"bật"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"Chặn"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"Tiếp tục hiển thị"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"Thu nhỏ"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"Im lặng"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Tiếp tục chế độ im lặng"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"Cảnh báo"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Tiếp tục cảnh báo"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Tắt thông báo"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Tiếp tục hiển thị các thông báo từ ứng dụng này?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Nhẹ nhàng"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Ưu tiên"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Giúp bạn chỉ tập trung vào thông báo trong danh sách kéo xuống. Luôn im lặng."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Hiển thị bên dưới thông báo mức độ ưu tiên. Luôn im lặng."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Hiển thị bên dưới thông báo mức độ ưu tiên. Luôn im lặng."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Hiển thị bên dưới thông báo mức độ ưu tiên. Luôn im lặng."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Thu hút sự chú ý của bạn bằng biểu tượng thanh trạng thái và âm thanh. Hiển thị trên màn hình khóa."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Im lặng"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Cảnh báo"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Giúp bạn tập trung bằng cách tắt tiếng hoặc không rung."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Thu hút sự chú ý của bạn bằng cách bật tiếng hoặc rung."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Không thể sửa đổi các thông báo này."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Không thể định cấu hình nhóm thông báo này tại đây"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Thông báo đã xử lý qua máy chủ proxy"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"Giữ và kéo để thêm ô"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"Giữ và kéo để sắp xếp lại các ô"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"Kéo vào đây để xóa"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"Bạn cần ít nhất <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ô"</string>
     <string name="qs_edit" msgid="2232596095725105230">"Chỉnh sửa"</string>
     <string name="tuner_time" msgid="6572217313285536011">"Thời gian"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Cho phép"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Từ chối"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Nhấn để lên lịch Trình tiết kiệm pin"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"Bật khi pin sắp hết"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Không, cảm ơn"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Đã bật Trình tiết kiệm pin được lên lịch"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"Trình tiết kiệm pin sẽ tự động bật khi mức pin thấp hơn <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Chuyển tới dưới cùng bên trái"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Chuyển tới dưới cùng bên phải"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Loại bỏ"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Đã cập nhật chế độ di chuyển trên hệ thống. Để thay đổi, hãy chuyển đến phần Cài đặt."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Chuyển đến phần Cài đặt để cập nhật chế độ di chuyển trên hệ thống"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/config.xml b/packages/SystemUI/res/values-zh-rCN/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-zh-rCN/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index c09b7fe..b3bf973 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"不允许使用 USB 调试功能"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"目前已登录此设备的用户无法开启 USB 调试功能。要使用此功能,请切换为主要用户的帐号。"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB 端口已停用"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"为避免液体或碎屑导致您的设备受损,系统已停用 USB 端口,因此目前无法检测任何配件。\n\n系统会在重新允许使用 USB 端口时通知您。"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB 端口已启用,可检测充电器和配件"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"启用 USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"了解详情"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"缩放以填满屏幕"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"拉伸以填满屏幕"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"屏幕截图"</string>
@@ -126,9 +124,10 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"正在查找您的面孔"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"面孔身份验证成功"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"已确认"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"点按“确认”即可完成"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"请触摸指纹传感器"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指纹图标"</string>
-    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在查找中…"</string>
+    <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在查找您的面孔…"</string>
     <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"面孔图标"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"兼容性缩放按钮。"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"将小屏幕的图片放大在较大屏幕上显示。"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"运营商网络正在更改"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"打开电量详情"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"电池电量为百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"电池电量为 <xliff:g id="PERCENTAGE">%1$s</xliff:g>,根据您的使用情况,大约还可使用 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"正在充电,已完成 <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"系统设置。"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"在日出时关闭"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"在<xliff:g id="TIME">%s</xliff:g> 开启"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"直到<xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"深色主题背景"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"深色主题背景\n省电模式"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"深色主题背景"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"深色主题背景\n省电模式"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC 已启用"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"不太紧急的通知会显示在下方"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"再次点按即可打开"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"向上滑动即可解锁"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑动即可打开"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"此设备由您所属单位管理"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"此设备是由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>托管"</string>
     <string name="phone_hint" msgid="4872890986869209950">"滑动图标即可拨打电话"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"不再显示"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"无声通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"清除所有无声通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"勿扰模式暂停的通知"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即开始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"没有通知"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"屏蔽"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"继续显示"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"静音"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"显示通知但不发出提示音"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"提醒"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"继续提醒"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"关闭通知"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要继续显示来自此应用的通知吗?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"无声通知"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"已设为优先"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"只会在下拉通知栏中显示通知,引起您的注意。一律不发出提示音。"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"显示在优先通知下方。一律不发出提示音。"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"显示在优先通知下方。一律不发出提示音。"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"显示在优先通知下方。一律不发出提示音。"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"通过提示音和状态栏图标吸引您的注意。这类通知会显示在锁定屏幕上。"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"静音"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"提醒"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"不会发出提示音或振动,可帮助您保持专注。"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"通过提示音或振动吸引您的注意。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"无法修改这些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"您无法在此处配置这组通知"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"按住并拖动即可添加图块"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"按住并拖动即可重新排列图块"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"拖动到此处即可移除"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"您至少需要 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 个卡片"</string>
     <string name="qs_edit" msgid="2232596095725105230">"编辑"</string>
     <string name="tuner_time" msgid="6572217313285536011">"时间"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"允许"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"拒绝"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"点按即可预设省电模式"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"在电池电量可能会耗尽时,系统会开启此模式"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"不用了"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"预设的省电模式已开启"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"一旦电池电量降到 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 以下,省电模式就会自动开启。"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"移至左下角"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"移至右下角"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"关闭"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系统导航已更新。要进行更改,请转到“设置”。"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"转到“设置”即可更新系统导航"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/config.xml b/packages/SystemUI/res/values-zh-rHK/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-zh-rHK/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index fe36271..59480a9 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"不允許 USB 偵錯"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"目前登入此裝置的使用者無法啟用 USB 偵錯功能。如要使用此功能,請切換至主要使用者。"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"已停用 USB 連接埠"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"為了保護您的裝置免受液體或碎片損害,USB 連接埠已停用,因此不會偵測到任何配件。\n\nUSB 連接埠可安全使用時,您會收到通知。"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"已啟用 USB 連接埠以偵測充電器和配件"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"啟用 USB"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"瞭解詳情"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"放大為全螢幕"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"放大為全螢幕"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"螢幕截圖"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"正在尋找您的臉孔"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"臉孔已經驗證"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"已確認"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"輕按 [確定] 以完成"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"請輕觸指紋感應器"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋圖示"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在搜尋您的臉孔…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"流動網絡供應商網絡正在變更"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"開啟電池詳細資料"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"電量仲剩番 <xliff:g id="PERCENTAGE">%1$s</xliff:g>。根據你嘅使用情況,仲可以用大約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"正在充電:<xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"在日出時關閉"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> 開啟"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"直到<xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"深色主題背景"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"深色主題背景\n省電模式"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"深色主題背景"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"深色主題背景\n省電模式"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC 已啟用"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"還有 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g> 則通知"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"不太緊急的通知會在下方顯示"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"再次輕按即可開啟"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"向上滑動即可解鎖"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑動即可開啟"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"此裝置由您的機構管理"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"此裝置由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>管理"</string>
     <string name="phone_hint" msgid="4872890986869209950">"從圖示滑動即可使用手機功能"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"不用再顯示"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"靜音通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"清除所有靜音通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"「請勿騷擾」模式已將通知暫停"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"沒有通知"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"封鎖"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"繼續顯示"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"靜音"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"保持靜音"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"發出提醒"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"繼續提示"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"關閉通知"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要繼續顯示此應用程式的通知嗎?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"低重要性"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"優先"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"協助您只查看下拉式通知欄中的通知。一律靜音。"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"顯示不重要的通知。一律靜音。"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"顯示不重要的通知。一律靜音。"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"顯示不重要的通知。一律靜音。"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"透過聲音和狀態列圖示引起您的注意,並在上鎖畫面顯示。"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"靜音"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"發出提醒"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"助您保持專注,不會發出聲音或震動。"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"發出聲音或震動來吸引您的注意。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"無法修改這些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"無法在此設定這組通知"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"代理通知"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"按住並拖曳即可新增圖塊"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"按住並拖曳即可重新排列圖塊"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"拖曳這裡即可移除"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"您需要有至少 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個資訊方塊"</string>
     <string name="qs_edit" msgid="2232596095725105230">"編輯"</string>
     <string name="tuner_time" msgid="6572217313285536011">"時間"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"允許"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"拒絕"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"輕按即可預定省電模式自動開啟時間"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"在電池電量可能耗盡前啟用「省電模式」"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"不用了,謝謝"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"已預定省電模式開啟時間"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"省電模式將會在電量低於 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 時自動開啟。"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"移去左下角"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"移去右下角"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"關閉"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系統導覽已更新。如需變更,請前往「設定」。"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"前往「設定」更新系統導覽"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/config.xml b/packages/SystemUI/res/values-zh-rTW/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-zh-rTW/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 345af4a..76377fe 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -62,12 +62,10 @@
     <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"無權使用 USB 偵錯功能"</string>
     <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"目前登入這個裝置的使用者無法啟用 USB 偵錯功能。如要使用這項功能,請切換到主要使用者。"</string>
     <string name="usb_contaminant_title" msgid="206854874263058490">"USB 連接埠已停用"</string>
-    <!-- no translation found for usb_contaminant_message (7379089091591609111) -->
-    <skip />
+    <string name="usb_contaminant_message" msgid="7379089091591609111">"為了避免液體或灰塵導致你的裝置受損,系統已停用 USB 連接埠,因此目前無法偵測任何配件。\n\n系統會在可繼續使用 USB 連接埠時通知你。"</string>
     <string name="usb_port_enabled" msgid="7906141351687694867">"USB 通訊埠已啟用,可偵測充電器和配件"</string>
     <string name="usb_disable_contaminant_detection" msgid="2103905315747120033">"啟用 USB 連接埠"</string>
-    <!-- no translation found for learn_more (5000517160980853569) -->
-    <skip />
+    <string name="learn_more" msgid="5000517160980853569">"瞭解詳情"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"放大為全螢幕"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"放大為全螢幕"</string>
     <string name="global_action_screenshot" msgid="8329831278085426283">"擷取螢幕畫面"</string>
@@ -126,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"正在尋找你的臉孔"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"臉孔驗證成功"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"確認完畢"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"輕觸 [確認] 完成驗證設定"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"請輕觸指紋感應器"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"指紋圖示"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"正在尋找你的臉孔…"</string>
@@ -199,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"電信業者網路正在進行變更"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"開啟電量詳細資料"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"電池電量為百分之 <xliff:g id="NUMBER">%d</xliff:g>。"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"目前的電量為 <xliff:g id="PERCENTAGE">%1$s</xliff:g>。根據你的使用情形,大約還能使用到<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"充電中,已完成 <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g>%%。"</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"系統設定"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"通知。"</string>
@@ -376,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"於日出時關閉"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"<xliff:g id="TIME">%s</xliff:g> 開啟"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"<xliff:g id="TIME">%s</xliff:g> 關閉"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"深色主題"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"深色主題\n節約耗電量"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"深色主題"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"深色主題\n節約耗電量"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"NFC 已停用"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"NFC 已啟用"</string>
@@ -400,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"還有 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g> 則通知"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"再次輕觸即可開啟"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"向上滑動即可解鎖"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑動即可開啟"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"這個裝置是由貴機構所管理"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"這個裝置是由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 所管理"</string>
     <string name="phone_hint" msgid="4872890986869209950">"滑動手機圖示即可啟用"</string>
@@ -458,10 +458,8 @@
     <string name="media_projection_remember_text" msgid="3103510882172746752">"不要再顯示"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string>
     <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
-    <!-- no translation found for notification_section_header_gentle (4372438504154095677) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_section_header_gentle_clear_all (4286716295850400959) -->
-    <skip />
+    <string name="notification_section_header_gentle" msgid="4372438504154095677">"無聲通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"清除所有無聲通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"「零打擾」模式已將通知設為暫停"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"沒有通知"</string>
@@ -645,21 +643,16 @@
     <string name="inline_block_button" msgid="8735843688021655065">"封鎖"</string>
     <string name="inline_keep_button" msgid="6665940297019018232">"繼續顯示"</string>
     <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
-    <!-- no translation found for inline_silent_button_silent (5315879183296940969) -->
-    <skip />
+    <string name="inline_silent_button_silent" msgid="5315879183296940969">"無聲"</string>
     <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"繼續顯示通知但不發出音效"</string>
-    <!-- no translation found for inline_silent_button_alert (6008435419895088034) -->
-    <skip />
+    <string name="inline_silent_button_alert" msgid="6008435419895088034">"快訊"</string>
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"繼續顯示通知"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"關閉通知"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"要繼續顯示這個應用程式的通知嗎?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"無聲通知"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"已設為優先"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"只會在下拉式通知欄中顯示通知,且一律不發出音效。"</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"顯示在優先通知下方,且一律不發出音效。"</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"顯示在優先通知下方,且一律不發出音效。"</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"顯示在優先通知下方,且一律不發出音效。"</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"發出音效並顯示「狀態列」圖示吸引你的注意力。這類通知會顯示在螢幕鎖定畫面上。"</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"靜音"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"快訊"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"協助你不受音效或震動干擾。"</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"發出音效或震動吸引你的注意力。"</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"無法修改這些通知。"</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"無法在這裡設定這個通知群組"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"經過 Proxy 處理的通知"</string>
@@ -726,7 +719,7 @@
     <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock 鍵"</string>
     <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"數字鍵 <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"系統"</string>
-    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主螢幕"</string>
     <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string>
     <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string>
     <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"通知"</string>
@@ -786,8 +779,7 @@
     <string name="drag_to_add_tiles" msgid="230586591689084925">"按住並拖曳即可新增圖塊"</string>
     <string name="drag_to_rearrange_tiles" msgid="4566074720193667473">"按住並拖曳即可重新排列圖塊"</string>
     <string name="drag_to_remove_tiles" msgid="3361212377437088062">"拖曳到這裡即可移除"</string>
-    <!-- no translation found for drag_to_remove_disabled (4785920129548299268) -->
-    <skip />
+    <string name="drag_to_remove_disabled" msgid="4785920129548299268">"你至少必須要有 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個資訊方塊"</string>
     <string name="qs_edit" msgid="2232596095725105230">"編輯"</string>
     <string name="tuner_time" msgid="6572217313285536011">"時間"</string>
   <string-array name="clock_options">
@@ -909,8 +901,7 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"允許"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"拒絕"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"輕觸即可排定節約耗電量模式自動開啟的情況"</string>
-    <!-- no translation found for auto_saver_text (2563289953551438248) -->
-    <skip />
+    <string name="auto_saver_text" msgid="2563289953551438248">"在電池電量即將耗盡時開啟"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"不用了,謝謝"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"已按照排定開啟節約耗電量模式"</string>
     <string name="auto_saver_enabled_text" msgid="874711029884777579">"節約耗電量模式會在電量低於 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 時自動開啟。"</string>
@@ -943,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"移至左下方"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"移至右下方"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"關閉"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"系統操作機制已更新。如要進行變更,請前往「設定」。"</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"請前往「設定」更新系統操作機制"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/config.xml b/packages/SystemUI/res/values-zu/config.xml
deleted file mode 100644
index 5309563..0000000
--- a/packages/SystemUI/res/values-zu/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-** Copyright 2009, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<!--  These resources are around just to allow their values to be customized
-     for different hardware and product builds.  -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="doze_pickup_subtype_performs_proximity_check" msgid="533127617385956583"></string>
-</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 4660501..74b9143 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -124,6 +124,7 @@
     <string name="biometric_dialog_face_icon_description_authenticating" msgid="4512727754496228488">"Ifuna ubuso bakho"</string>
     <string name="biometric_dialog_face_icon_description_authenticated" msgid="595380451325425259">"Ubuso bufakazelwe ubuqiniso"</string>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="2003141400387093967">"Kuqinisekisiwe"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="4540715260292022404">"Thepha okuthi Qinisekisa ukuze uqedele"</string>
     <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Thinta inzwa yesigxivizo somunwe"</string>
     <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Isithonjana sezigxivizo zeminwe"</string>
     <string name="face_dialog_looking_for_face" msgid="7049276266074494689">"Kufunwa wena…"</string>
@@ -197,6 +198,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Inethiwekhi yenkampani yenethiwekhi iyashintsha"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Vula imininingwane yebhethri"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Iphesenti <xliff:g id="NUMBER">%d</xliff:g> lebhethri"</string>
+    <string name="accessibility_battery_level_with_estimate" msgid="9033100930684311630">"Amaphesenti ebhethri ngu-<xliff:g id="PERCENTAGE">%1$s</xliff:g>, cishe kusele okungu-<xliff:g id="TIME">%2$s</xliff:g> kusukela ekusetshenzisweni kwakho"</string>
     <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Ibhethri liyashaja, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> iphesenti."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Izilungiselelo zesistimu"</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Izaziso"</string>
@@ -374,8 +376,8 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"Kuze kube sekuphumeni kwelanga"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"Kuvulwe ngo-<xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Kuze kube ngu-<xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="512534812963862137">"Itimu emnyama"</string>
-    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="3496696903886673256">"Itimu emnyama\nIsilondolozi sebethri"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="3419947801072692538">"Itimu emnyama"</string>
+    <string name="quick_settings_ui_mode_night_label_battery_saver" msgid="7438725724589758362">"Itimu emnyama\nIsilondolozi sebethri"</string>
     <string name="quick_settings_nfc_label" msgid="9012153754816969325">"I-NFC"</string>
     <string name="quick_settings_nfc_off" msgid="6883274004315134333">"I-NFC ikhutshaziwe"</string>
     <string name="quick_settings_nfc_on" msgid="6680317193676884311">"I-NFC inikwe amandla"</string>
@@ -398,7 +400,7 @@
     <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
     <string name="speed_bump_explanation" msgid="1288875699658819755">"Izaziso ezingasheshi kakhulu ezingezansi"</string>
     <string name="notification_tap_again" msgid="7590196980943943842">"Thepha futhi ukuze uvule"</string>
-    <string name="keyguard_unlock" msgid="8043466894212841998">"Swayiphela phezulu ukuze uvule"</string>
+    <string name="keyguard_unlock" msgid="6035822649218712063">"Swayiphela phezulu ukuze uvule"</string>
     <string name="do_disclosure_generic" msgid="5615898451805157556">"Le divayisi iphethwe inhlangano yakho"</string>
     <string name="do_disclosure_with_name" msgid="5640615509915445501">"Le divayisi iphethwe yi-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="phone_hint" msgid="4872890986869209950">"Swayiphela ifoni kusukela kusithonjana"</string>
@@ -647,13 +649,10 @@
     <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Qhubeka wazise"</string>
     <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Vala izaziso"</string>
     <string name="inline_keep_showing_app" msgid="1723113469580031041">"Qhubeka nokubonisa izaziso kusuka kulolu hlelo lokusebenza?"</string>
-    <string name="notification_silence_title" msgid="7352089096356977930">"Okumnene"</string>
-    <string name="notification_alert_title" msgid="3966526305405016221">"Okwenziwe kwabaluleka"</string>
-    <string name="notification_channel_summary_low" msgid="1065819618107531284">"Ikusiza ukuthi ugxile ngezaziso kuphela kumthunzi wokudonsela phansi. Ihlala ithulile."</string>
-    <string name="notification_channel_summary_low_status" msgid="2702170424808743755">"Ibonisa izaziso ezibalulekile ezingezansi. Ihlala ithulile."</string>
-    <string name="notification_channel_summary_low_lock" msgid="7966605244472624458">"Ibonisa izaziso ezibalulekile ezingezansi. Ihlala ithulile."</string>
-    <string name="notification_channel_summary_low_status_lock" msgid="7012562768950012739">"Ibonisa izaziso ezibalulekile ezingezansi. Ihlala ithulile."</string>
-    <string name="notification_channel_summary_default" msgid="3847289783382316019">"Yenza uyinake ngomsindo nesithonjana sebha yesimo. Iboniswa kusikrini sokukhiya."</string>
+    <string name="notification_silence_title" msgid="5763240612242137433">"Kuthulile"</string>
+    <string name="notification_alert_title" msgid="8031196611815490340">"Iyazisa"</string>
+    <string name="notification_channel_summary_low" msgid="3387466082089715555">"Ikusiza ukuthi ugxile ngaphandle komsindo noma ukudlidliza."</string>
+    <string name="notification_channel_summary_default" msgid="5994062840431965586">"Ithola ukunaka kwakho ngomsindo noma ukudlidliza."</string>
     <string name="notification_unblockable_desc" msgid="4556908766584964102">"Lezi zaziso azikwazi ukushintshwa."</string>
     <string name="notification_multichannel_desc" msgid="4695920306092240550">"Leli qembu lezaziso alikwazi ukulungiselelwa lapha"</string>
     <string name="notification_delegate_header" msgid="2857691673814814270">"Isaziso sommeli"</string>
@@ -935,4 +934,6 @@
     <string name="bubble_accessibility_action_move_bottom_left" msgid="206369104473183217">"Hambisa inkinobho ngakwesokunxele"</string>
     <string name="bubble_accessibility_action_move_bottom_right" msgid="8705660152384312329">"Hambisa inkinobho ngakwesokudla"</string>
     <string name="bubble_dismiss_text" msgid="8028337712674081668">"Cashisa"</string>
+    <string name="notification_content_system_nav_changed" msgid="7218093915747788444">"Ukuzulazula kwesistimu kubuyekeziwe. Ukuze wenze ushintsho, hamba kokuthi Izilungiselelo."</string>
+    <string name="notification_content_gesture_nav_available" msgid="8111130443656460792">"Hamba kuzilungiselelo ukuze ubuyekeze ukuzulazula kwesistimu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/attrs_car.xml b/packages/SystemUI/res/values/attrs_car.xml
index ced26c9..49b87f3 100644
--- a/packages/SystemUI/res/values/attrs_car.xml
+++ b/packages/SystemUI/res/values/attrs_car.xml
@@ -62,6 +62,8 @@
         <attr name="unselectedAlpha" />
         <!-- icon to be rendered when in selected state -->
         <attr name="selectedIcon" />
+        <!-- icon to be rendered (drawable) -->
+        <attr name="icon"/>
     </declare-styleable>
 
     <!-- Custom attributes to configure hvac values -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index f8efceb..861187f 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -40,6 +40,9 @@
     <!-- Whether or not we show the number in the bar. -->
     <bool name="config_statusBarShowNumber">false</bool>
 
+    <!-- For how long the lock screen can be on before the display turns off. -->
+    <integer name="config_lockScreenDisplayTimeout">10000</integer>
+
     <!-- Vibrator pattern for camera gesture launch. -->
     <integer-array translatable="false" name="config_cameraLaunchGestureVibePattern">
         <item>0</item>
@@ -138,6 +141,9 @@
     <!-- The number of milliseconds before the heads up notification auto-dismisses. -->
     <integer name="heads_up_notification_decay">5000</integer>
 
+    <!-- The number of milliseconds before the heads up notification sent automatically by the system auto-dismisses. -->
+    <integer name="auto_heads_up_notification_decay">3000</integer>
+
     <!-- The number of milliseconds after a heads up notification is pushed back
      before the app can interrupt again. -->
     <integer name="heads_up_default_snooze_length_ms">60000</integer>
@@ -148,15 +154,8 @@
     <!-- The number of milliseconds before the heads up notification accepts touches. -->
     <integer name="touch_acceptance_delay">700</integer>
 
-    <!-- The number of milliseconds before the ambient notification auto-dismisses. This will
-         override the default pulse length. -->
-    <integer name="ambient_notification_decay">10000</integer>
-
-    <!-- Minimum display time for a heads up notification, in milliseconds. -->
-    <integer name="ambient_notification_minimum_time">2000</integer>
-
     <!-- The number of milliseconds to extend ambient pulse by when prompted (e.g. on touch) -->
-    <integer name="ambient_notification_extension_time">6000</integer>
+    <integer name="ambient_notification_extension_time">10000</integer>
 
     <!-- In multi-window, determines whether the stack where recents lives should grow from
          the smallest position when being launched. -->
@@ -197,25 +196,9 @@
     <!-- Doze: duration to avoid false pickup gestures triggered by notification vibrations -->
     <integer name="doze_pickup_vibration_threshold">2000</integer>
 
-    <!-- Doze: can we assume the pickup sensor includes a proximity check?
-         This is ignored if doze_pickup_subtype_performs_proximity_check is not empty.
-         @deprecated: use doze_pickup_subtype_performs_proximity_check instead.-->
+    <!-- Doze: can we assume the pickup sensor includes a proximity check? -->
     <bool name="doze_pickup_performs_proximity_check">false</bool>
 
-    <!-- Doze: a list of pickup sensor subtypes that perform a proximity check before they trigger.
-               If not empty, either * or !* must appear to specify the default.
-               If empty, falls back to doze_pickup_performs_proximity_check.
-
-               Examples: 1,2,3,!* -> subtypes 1,2 and 3 perform the check, all others don't.
-                         !1,!2,*  -> subtypes 1 and 2 don't perform the check, all others do.
-                         !8,*     -> subtype 8 does not perform the check, all others do
-                         1,1,*    -> illegal, every item may only appear once
-                         1,!1,*   -> illegal, no contradictions allowed
-                         1,2      -> illegal, need either * or !*
-                         1,,4a3   -> illegal, no empty or non-numeric terms allowed
-    -->
-    <string name="doze_pickup_subtype_performs_proximity_check"></string>
-
     <!-- Type of a sensor that provides a low-power estimate of the desired display
          brightness, suitable to listen to while the device is asleep (e.g. during
          always-on display) -->
@@ -493,4 +476,10 @@
     <!-- ThemePicker package name for overlaying icons. -->
     <string name="themepicker_overlayable_package" translatable="false">com.android.wallpaper</string>
 
+    <!-- Default rounded corner curve (a Bezier). Must match (the curved path in) rounded.xml.
+         Note that while rounded.xml includes the entire path (including the horizontal and vertical
+         corner edges), this pulls out just the curve.
+     -->
+    <string name="config_rounded_mask" translatable="false">"M8,0C3.6,0,0,3.6,0,8"</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c5e4662..be815e1 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -112,7 +112,7 @@
     <dimen name="status_bar_connected_device_bt_indicator_size">17dp</dimen>
 
     <!-- Height of a small notification in the status bar-->
-    <dimen name="notification_min_height">106dp</dimen>
+    <dimen name="notification_min_height">@*android:dimen/notification_min_height</dimen>
 
     <!-- Increased height of a small notification in the status bar -->
     <dimen name="notification_min_height_increased">146dp</dimen>
@@ -183,6 +183,9 @@
     <!-- The padding on the bottom of the notifications on the keyguard -->
     <dimen name="keyguard_indication_bottom_padding">12sp</dimen>
 
+    <!-- The padding at start and end of indication text shown on AOD -->
+    <dimen name="keyguard_indication_text_padding">16dp</dimen>
+
     <!-- Shadows under the clock, date and other keyguard text fields -->
     <dimen name="keyguard_shadow_radius">5</dimen>
 
@@ -258,8 +261,8 @@
     <!-- size at which Notification icons will be drawn on Ambient Display -->
     <dimen name="status_bar_icon_drawing_size_dark">@*android:dimen/notification_header_icon_size_ambient</dimen>
 
-    <!-- size of notification icons on AOD -->
-    <dimen name="dark_shelf_icon_size">16dp</dimen>
+    <!-- size of notification icons when the notifications are hidden -->
+    <dimen name="hidden_shelf_icon_size">16dp</dimen>
 
     <!-- opacity at which Notification icons will be drawn in the status bar -->
     <item type="dimen" name="status_bar_icon_drawing_alpha">90%</item>
@@ -382,22 +385,16 @@
     <!-- The width of the panel that holds the quick settings. -->
     <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
 
-    <dimen name="volume_dialog_panel_transparent_padding_right">8dp</dimen>
+    <dimen name="volume_dialog_panel_transparent_padding_right">4dp</dimen>
 
     <dimen name="volume_dialog_panel_transparent_padding">20dp</dimen>
 
     <dimen name="volume_dialog_stream_padding">8dp</dimen>
 
-    <!-- the amount the volume panel should be offset at the end from the view next to it (or
-    the screen edge, in portrait-->
-    <dimen name="volume_dialog_base_margin">8dp</dimen>
-
     <dimen name="volume_dialog_panel_width">64dp</dimen>
 
     <dimen name="volume_dialog_slider_height">116dp</dimen>
 
-    <dimen name="volume_dialog_row_height">252dp</dimen>
-
     <dimen name="volume_dialog_ringer_size">64dp</dimen>
 
     <dimen name="volume_dialog_ringer_icon_padding">20dp</dimen>
@@ -414,8 +411,6 @@
 
     <dimen name="volume_dialog_row_margin_bottom">8dp</dimen>
 
-    <dimen name="volume_dialog_settings_icon_size">16dp</dimen>
-
     <dimen name="volume_dialog_elevation">9dp</dimen>
 
     <dimen name="volume_tool_tip_right_margin">76dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index e97055f0..66f1949 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -94,6 +94,16 @@
     <item type="id" name="top_roundess_animator_start_tag"/>
     <item type="id" name="top_roundess_animator_end_tag"/>
 
+    <item type="id" name="keyguard_hun_animator_tag"/>
+    <item type="id" name="keyguard_hun_animator_start_tag"/>
+    <item type="id" name="keyguard_hun_animator_end_tag"/>
+
+    <item type="id" name="view_group_fade_helper_modified_views"/>
+    <item type="id" name="view_group_fade_helper_animator"/>
+    <item type="id" name="view_group_fade_helper_previous_value_tag"/>
+    <item type="id" name="view_group_fade_helper_restore_tag"/>
+    <item type="id" name="view_group_fade_helper_hardware_layer"/>
+
     <!-- Accessibility actions for the notification menu -->
     <item type="id" name="action_snooze_undo"/>
     <item type="id" name="action_snooze_shorter"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 486e2fc..7feacb4 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -303,6 +303,8 @@
     <string name="biometric_dialog_face_icon_description_authenticated">Face authenticated</string>
     <!-- Content description for the face icon when the user has been authenticated and the confirm button has been pressed [CHAR LIMIT=NONE] -->
     <string name="biometric_dialog_face_icon_description_confirmed">Confirmed</string>
+    <!-- Message shown when a biometric is authenticated, waiting for the user to confirm authentication [CHAR LIMIT=40]-->
+    <string name="biometric_dialog_tap_confirm">Tap Confirm to complete</string>
 
     <!-- Message shown when the system-provided fingerprint dialog is shown, asking for authentication -->
     <string name="fingerprint_dialog_touch_sensor">Touch the fingerprint sensor</string>
@@ -495,6 +497,9 @@
     <!-- Content description of the battery level icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_battery_level">Battery <xliff:g id="number">%d</xliff:g> percent.</string>
 
+    <!-- Content description of the battery level icon for accessibility, including the estimated time remaining before the phone runs out of battery (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_battery_level_with_estimate">Battery <xliff:g id="percentage" example="95%">%1$s</xliff:g> percent, about <xliff:g id="time" example="Until 3:15pm">%2$s</xliff:g> left based on your usage</string>
+
     <!-- Content description of the battery level icon for accessibility while the device is charging (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_battery_level_charging">Battery charging, <xliff:g id="battery_percentage">%d</xliff:g> percent.</string>
 
@@ -882,10 +887,10 @@
     <string name="quick_settings_night_secondary_label_on_at">On at <xliff:g id="time" example="10 pm">%s</xliff:g></string>
     <!-- QuickSettings: Secondary text for when the Night Light or some other tile will be on until some user-selected time. [CHAR LIMIT=20] -->
     <string name="quick_settings_secondary_label_until">Until <xliff:g id="time" example="7 am">%s</xliff:g></string>
-    <!-- QuickSettings: Label for the toggle to activate Dark theme (A.K.A Dark Mode). [CHAR LIMIT=20] -->
-    <string name="quick_settings_ui_mode_night_label">Dark Theme</string>
-    <!-- QuickSettings: Label for the Dark theme tile when enabled by battery saver. [CHAR LIMIT=40] -->
-    <string name="quick_settings_ui_mode_night_label_battery_saver">Dark Theme\nBattery saver</string>
+    <!-- QuickSettings: Label for the toggle to activate dark theme (A.K.A Dark Mode). [CHAR LIMIT=20] -->
+    <string name="quick_settings_ui_mode_night_label">Dark theme</string>
+    <!-- QuickSettings: Label for the dark theme tile when enabled by battery saver. [CHAR LIMIT=40] -->
+    <string name="quick_settings_ui_mode_night_label_battery_saver">Dark theme\nBattery saver</string>
 
     <!-- QuickSettings: NFC tile [CHAR LIMIT=NONE] -->
     <string name="quick_settings_nfc_label">NFC</string>
@@ -950,8 +955,8 @@
     <!-- Shows to explain the double tap interaction with notifications: After tapping a notification on Keyguard, this will explain users to tap again to launch a notification. [CHAR LIMIT=60] -->
     <string name="notification_tap_again">Tap again to open</string>
 
-    <!-- Shows when people have pressed the unlock icon to explain how to unlock. [CHAR LIMIT=60] -->
-    <string name="keyguard_unlock">Swipe up to unlock</string>
+    <!-- Message shown when lock screen is tapped or face authentication fails. [CHAR LIMIT=60] -->
+    <string name="keyguard_unlock">Swipe up to open</string>
 
     <!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] -->
     <string name="do_disclosure_generic">This device is managed by your organization</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index b387793..2f1770a 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -450,7 +450,7 @@
 
     <style name="TextAppearance.NotificationInfo.Secondary">
         <item name="android:textSize">14sp</item>
-        <item name="android:alpha">0.54</item>
+        <item name="android:alpha">0.62</item>
     </style>
 
     <style name="TextAppearance.NotificationInfo.Title">
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
index 7139708..53403aa 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
@@ -215,7 +215,7 @@
             Uri uri = intent.getData();
             ComponentName component = ComponentName.unflattenFromString(
                     uri.toString().substring(10));
-            if (mWhitelistedPlugins.contains(component.getPackageName())) {
+            if (isPluginWhitelisted(component)) {
                 // Don't disable whitelisted plugins as they are a part of the OS.
                 return;
             }
@@ -288,7 +288,7 @@
 
     /** Returns class loader specific for the given plugin. */
     public ClassLoader getClassLoader(ApplicationInfo appInfo) {
-        if (!isDebuggable && !mWhitelistedPlugins.contains(appInfo.packageName)) {
+        if (!isDebuggable && !isPluginPackageWhitelisted(appInfo.packageName)) {
             Log.w(TAG, "Cannot get class loader for non-whitelisted plugin. Src:"
                     + appInfo.sourceDir + ", pkg: " + appInfo.packageName);
             return null;
@@ -352,6 +352,34 @@
         }
     }
 
+    private boolean isPluginPackageWhitelisted(String packageName) {
+        for (String componentNameOrPackage : mWhitelistedPlugins) {
+            ComponentName componentName = ComponentName.unflattenFromString(componentNameOrPackage);
+            if (componentName != null) {
+                if (componentName.getPackageName().equals(packageName)) {
+                    return true;
+                }
+            } else if (componentNameOrPackage.equals(packageName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isPluginWhitelisted(ComponentName pluginName) {
+        for (String componentNameOrPackage : mWhitelistedPlugins) {
+            ComponentName componentName = ComponentName.unflattenFromString(componentNameOrPackage);
+            if (componentName != null) {
+                if (componentName.equals(pluginName)) {
+                    return true;
+                }
+            } else if (componentNameOrPackage.equals(pluginName.getPackageName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     // This allows plugins to include any libraries or copied code they want by only including
     // classes from the plugin library.
     private static class ClassLoaderFilter extends ClassLoader {
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 77bb514..9228b17 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
@@ -55,10 +55,17 @@
     /**
      * Control the {@param alpha} of the back button in the navigation bar and {@param animate} if
      * needed from current value
+     * @deprecated
      */
     void setBackButtonAlpha(float alpha, boolean animate) = 8;
 
     /**
+     * Control the {@param alpha} of the option nav bar button (back-button in 2 button mode
+     * and home bar in no-button mode) and {@param animate} if needed from current value
+     */
+    void setNavBarButtonAlpha(float alpha, boolean animate) = 19;
+
+    /**
      * Proxies motion events from the homescreen UI to the status bar. Only called when
      * swipe down is detected on WORKSPACE. The sender guarantees the following order of events on
      * the tracking pointer.
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index 5b9ee1c..dcb134e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -20,6 +20,7 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManager.TaskDescription;
+import android.app.TaskInfo;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -75,7 +76,7 @@
 
         private int mHashCode;
 
-        public TaskKey(ActivityManager.RecentTaskInfo t) {
+        public TaskKey(TaskInfo t) {
             ComponentName sourceComponent = t.origActivity != null
                     // Activity alias if there is one
                     ? t.origActivity
@@ -226,6 +227,17 @@
         // Do nothing
     }
 
+    /**
+     * Creates a task object from the provided task info
+     */
+    public static Task from(TaskKey taskKey, TaskInfo taskInfo, boolean isLocked) {
+        ActivityManager.TaskDescription td = taskInfo.taskDescription;
+        return new Task(taskKey,
+                td != null ? td.getPrimaryColor() : 0,
+                td != null ? td.getBackgroundColor() : 0,
+                taskInfo.supportsSplitScreenMultiWindow, isLocked, td, taskInfo.topActivity);
+    }
+
     public Task(TaskKey key) {
         this.key = key;
         this.taskDescription = new TaskDescription();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
index 98a8110..98b7e24 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/ThumbnailData.java
@@ -38,6 +38,7 @@
     public int windowingMode;
     public int systemUiVisibility;
     public float scale;
+    public long snapshotId;
 
     public ThumbnailData() {
         thumbnail = null;
@@ -49,6 +50,7 @@
         isTranslucent = false;
         windowingMode = WINDOWING_MODE_UNDEFINED;
         systemUiVisibility = 0;
+        snapshotId = 0;
     }
 
     public ThumbnailData(TaskSnapshot snapshot) {
@@ -61,5 +63,6 @@
         isTranslucent = snapshot.isTranslucent();
         windowingMode = snapshot.getWindowingMode();
         systemUiVisibility = snapshot.getSystemUiVisibility();
+        snapshotId = snapshot.getId();
     }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 6b07ed8..328116d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -30,10 +30,12 @@
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RecentTaskInfo;
+import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.app.AppGlobals;
 import android.app.IAssistDataReceiver;
+import android.app.WindowConfiguration;
 import android.app.WindowConfiguration.ActivityType;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -64,6 +66,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Future;
 import java.util.function.Consumer;
 
 public class ActivityManagerWrapper {
@@ -306,28 +309,22 @@
         }
         final ActivityOptions finalOptions = options;
 
-        // Execute this from another thread such that we can do other things (like caching the
-        // bitmap for the thumbnail) while AM is busy starting our activity.
-        mBackgroundExecutor.submit(new Runnable() {
-            @Override
-            public void run() {
-                boolean result = false;
-                try {
-                    result = startActivityFromRecents(taskKey.id, finalOptions);
-                } catch (Exception e) {
-                    // Fall through
+
+        boolean result = false;
+        try {
+            result = startActivityFromRecents(taskKey.id, finalOptions);
+        } catch (Exception e) {
+            // Fall through
+        }
+        final boolean finalResult = result;
+        if (resultCallback != null) {
+            resultCallbackHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    resultCallback.accept(finalResult);
                 }
-                final boolean finalResult = result;
-                if (resultCallback != null) {
-                    resultCallbackHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            resultCallback.accept(finalResult);
-                        }
-                    });
-                }
-            }
-        });
+            });
+        }
     }
 
     /**
@@ -380,8 +377,8 @@
     /**
      * Requests that the system close any open system windows (including other SystemUI).
      */
-    public void closeSystemWindows(final String reason) {
-        mBackgroundExecutor.submit(new Runnable() {
+    public Future<?> closeSystemWindows(final String reason) {
+        return mBackgroundExecutor.submit(new Runnable() {
             @Override
             public void run() {
                 try {
@@ -505,4 +502,12 @@
                 PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT)
                 || freeformDevOption);
     }
+
+    /**
+     * Returns true if the running task represents the home task
+     */
+    public static boolean isHomeTask(RunningTaskInfo info) {
+        return info.configuration.windowConfiguration.getActivityType()
+                == WindowConfiguration.ACTIVITY_TYPE_HOME;
+    }
 }
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 cc3a67c..cc7863c 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
@@ -21,7 +21,9 @@
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 
 import android.annotation.IntDef;
+import android.content.Context;
 import android.content.res.Resources;
+import android.view.ViewConfiguration;
 import android.view.WindowManagerPolicyConstants;
 
 import com.android.internal.policy.ScreenDecorationsUtils;
@@ -47,6 +49,15 @@
     public static final String NAV_BAR_MODE_GESTURAL_OVERLAY =
             WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
 
+    // Action sent by a system app to switch to gesture nav
+    public static final String ACTION_ENABLE_GESTURE_NAV =
+            "com.android.systemui.ENABLE_GESTURE_NAV";
+    // Action for the intent to receive the result
+    public static final String ACTION_ENABLE_GESTURE_NAV_RESULT =
+            "com.android.systemui.action.ENABLE_GESTURE_NAV_RESULT";
+    // Extra containing the pending intent to receive the result
+    public static final String EXTRA_RESULT_INTENT = "com.android.systemui.EXTRA_RESULT_INTENT";
+
     // Overview is disabled, either because the device is in lock task mode, or because the device
     // policy has disabled the feature
     public static final int SYSUI_STATE_SCREEN_PINNING = 1 << 0;
@@ -61,12 +72,14 @@
     public static final int SYSUI_STATE_A11Y_BUTTON_CLICKABLE = 1 << 4;
     // The navigation bar a11y button shortcut is available
     public static final int SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE = 1 << 5;
-    // The keyguard is showing
+    // The keyguard is showing and not occluded
     public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING = 1 << 6;
     // The recents feature is disabled (either by SUW/SysUI/device policy)
     public static final int SYSUI_STATE_OVERVIEW_DISABLED = 1 << 7;
     // The home feature is disabled (either by SUW/SysUI/device policy)
     public static final int SYSUI_STATE_HOME_DISABLED = 1 << 8;
+    // The keyguard is showing, but occluded
+    public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED = 1 << 9;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({SYSUI_STATE_SCREEN_PINNING,
@@ -76,6 +89,7 @@
             SYSUI_STATE_A11Y_BUTTON_CLICKABLE,
             SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE,
             SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
+            SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
             SYSUI_STATE_OVERVIEW_DISABLED,
             SYSUI_STATE_HOME_DISABLED
     })
@@ -89,6 +103,8 @@
         str.add((flags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0 ? "navbar_hidden" : "");
         str.add((flags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0 ? "notif_visible" : "");
         str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) != 0 ? "keygrd_visible" : "");
+        str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0
+                ? "keygrd_occluded" : "");
         str.add((flags & SYSUI_STATE_BOUNCER_SHOWING) != 0 ? "bouncer_visible" : "");
         str.add((flags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0 ? "a11y_click" : "");
         str.add((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0 ? "a11y_long_click" : "");
@@ -96,6 +112,18 @@
     }
 
     /**
+     * Ratio of quickstep touch slop (when system takes over the touch) to view touch slop
+     */
+    public static final float QUICKSTEP_TOUCH_SLOP_RATIO = 3;
+
+    /**
+     * Touch slop for quickstep gesture
+     */
+    public static final float getQuickStepTouchSlopPx(Context context) {
+        return QUICKSTEP_TOUCH_SLOP_RATIO * ViewConfiguration.get(context).getScaledTouchSlop();
+    }
+
+    /**
      * Touch slopes and thresholds for quick step operations. Drag slop is the point where the
      * home button press/long press over are ignored and will start to drag when exceeded and the
      * touch slop is when the respected operation will occur when exceeded. Touch slop must be
@@ -122,13 +150,21 @@
      * disabled.
      */
     public static boolean isAssistantGestureDisabled(int sysuiStateFlags) {
-        // Disable when in screen pinning, immersive, the bouncer is showing, or the notifications
-        // are interactive
+        // Disable when in screen pinning, immersive, the bouncer is showing
         int disableFlags = SYSUI_STATE_SCREEN_PINNING
                 | SYSUI_STATE_NAV_BAR_HIDDEN
-                | SYSUI_STATE_BOUNCER_SHOWING
-                | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
-        return (sysuiStateFlags & disableFlags) != 0;
+                | SYSUI_STATE_BOUNCER_SHOWING;
+        if ((sysuiStateFlags & disableFlags) != 0) {
+            return true;
+        }
+
+        // Disable when notifications are showing (only if unlocked)
+        if ((sysuiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0
+                && (sysuiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) == 0) {
+            return true;
+        }
+
+        return false;
     }
 
     /**
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
index bd7b3d5..9ba21a3 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -22,6 +22,7 @@
 import android.os.Handler;
 import android.os.Handler.Callback;
 import android.os.Message;
+import android.os.Trace;
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewRootImpl;
@@ -95,6 +96,7 @@
                             .sendToTarget();
                     return;
                 }
+                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Sync transaction frameNumber=" + frame);
                 TransactionCompat t = new TransactionCompat();
                 for (int i = params.length - 1; i >= 0; i--) {
                     SyncRtSurfaceTransactionApplierCompat.SurfaceParams surfaceParams =
@@ -105,6 +107,7 @@
                 }
                 t.setEarlyWakeup();
                 t.apply();
+                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                 Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
                         .sendToTarget();
             }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index bd2b19c..c215d0f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -87,6 +87,14 @@
     public void onBackPressedOnTaskRoot(RunningTaskInfo taskInfo) { }
 
     /**
+     * Called when a task is reparented to a stack on a different display.
+     *
+     * @param taskId id of the task which was moved to a different display.
+     * @param newDisplayId id of the new display.
+     */
+    public void onTaskDisplayChanged(int taskId, int newDisplayId) { }
+
+    /**
      * Checks that the current user matches the process. Since
      * {@link android.app.ITaskStackListener} is not multi-user aware, handlers of
      * {@link TaskStackChangeListener} should make this call to verify that we don't act on events
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index c89f2ab..d570a58 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -112,7 +112,7 @@
 
     @Override
     public void onPinnedActivityRestartAttempt(boolean clearedTask)
-            throws RemoteException{
+            throws RemoteException {
         mHandler.removeMessages(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
         mHandler.obtainMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT, clearedTask ? 1 : 0, 0)
                 .sendToTarget();
@@ -154,7 +154,7 @@
     public void onActivityLaunchOnSecondaryDisplayRerouted(RunningTaskInfo taskInfo,
             int requestedDisplayId) throws RemoteException {
         mHandler.obtainMessage(H.ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED,
-                 requestedDisplayId, 0 /* unused */, taskInfo).sendToTarget();
+                requestedDisplayId, 0 /* unused */, taskInfo).sendToTarget();
     }
 
     @Override
@@ -208,6 +208,11 @@
                 0 /* unused */).sendToTarget();
     }
 
+    @Override
+    public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException {
+        mHandler.obtainMessage(H.ON_TASK_DISPLAY_CHANGED, taskId, newDisplayId).sendToTarget();
+    }
+
     private final class H extends Handler {
         private static final int ON_TASK_STACK_CHANGED = 1;
         private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
@@ -228,6 +233,7 @@
         private static final int ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED = 17;
         private static final int ON_BACK_PRESSED_ON_TASK_ROOT = 18;
         private static final int ON_SINGLE_TASK_DISPLAY_DRAWN = 19;
+        private static final int ON_TASK_DISPLAY_CHANGED = 20;
 
 
         public H(Looper looper) {
@@ -313,7 +319,7 @@
                         final RunningTaskInfo info = (RunningTaskInfo) msg.obj;
                         for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
                             mTaskStackListeners.get(i)
-                                .onActivityLaunchOnSecondaryDisplayRerouted(info);
+                                    .onActivityLaunchOnSecondaryDisplayRerouted(info);
                         }
                         break;
                     }
@@ -370,6 +376,12 @@
                         }
                         break;
                     }
+                    case ON_TASK_DISPLAY_CHANGED: {
+                        for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+                            mTaskStackListeners.get(i).onTaskDisplayChanged(msg.arg1, msg.arg2);
+                        }
+                        break;
+                    }
                 }
             }
         }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
index af32f48..073688b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Matrix;
 import android.graphics.Rect;
-import android.os.IBinder;
 import android.view.Surface;
 import android.view.SurfaceControl.Transaction;
 
@@ -88,12 +87,6 @@
     }
 
     public TransactionCompat deferTransactionUntil(SurfaceControlCompat surfaceControl,
-            IBinder handle, long frameNumber) {
-        mTransaction.deferTransactionUntil(surfaceControl.mSurfaceControl, handle, frameNumber);
-        return this;
-    }
-
-    public TransactionCompat deferTransactionUntil(SurfaceControlCompat surfaceControl,
             Surface barrier, long frameNumber) {
         mTransaction.deferTransactionUntilSurface(surfaceControl.mSurfaceControl, barrier,
                 frameNumber);
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 2090748..11d093f 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -303,6 +303,11 @@
             }
         } else {
             subs = mKeyguardUpdateMonitor.getSubscriptionInfo(false);
+            if (subs == null) {
+                subs = new ArrayList<>();
+            } else {
+                filterMobileSubscriptionInSameGroup(subs);
+            }
         }
         return subs;
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 0bb9e744..2483192 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -3,13 +3,13 @@
 import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.graphics.Paint;
 import android.graphics.Paint.Style;
 import android.os.Build;
+import android.transition.Fade;
 import android.transition.Transition;
 import android.transition.TransitionListenerAdapter;
 import android.transition.TransitionManager;
@@ -34,6 +34,7 @@
 import com.android.systemui.plugins.ClockPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -49,6 +50,7 @@
 public class KeyguardClockSwitch extends RelativeLayout {
 
     private static final String TAG = "KeyguardClockSwitch";
+    private static final boolean CUSTOM_CLOCKS_ENABLED = false;
 
     /**
      * Animation fraction when text is transitioned to/from bold.
@@ -116,6 +118,11 @@
     private float mDarkAmount;
 
     /**
+     * Boolean value indicating if notifications are visible on lock screen.
+     */
+    private boolean mHasVisibleNotifications;
+
+    /**
      * If the Keyguard Slice has a header (big center-aligned text.)
      */
     private boolean mShowingHeader;
@@ -192,7 +199,9 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        mClockManager.addOnClockChangedListener(mClockChangedListener);
+        if (CUSTOM_CLOCKS_ENABLED) {
+            mClockManager.addOnClockChangedListener(mClockChangedListener);
+        }
         mStatusBarStateController.addCallback(mStateListener);
         mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener);
         updateColors();
@@ -201,7 +210,9 @@
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        mClockManager.removeOnClockChangedListener(mClockChangedListener);
+        if (CUSTOM_CLOCKS_ENABLED) {
+            mClockManager.removeOnClockChangedListener(mClockChangedListener);
+        }
         mStatusBarStateController.removeCallback(mStateListener);
         mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener);
         setClockPlugin(null);
@@ -222,8 +233,13 @@
             mClockPlugin = null;
         }
         if (plugin == null) {
-            mClockView.setVisibility(View.VISIBLE);
-            mClockViewBold.setVisibility(View.INVISIBLE);
+            if (mShowingHeader) {
+                mClockView.setVisibility(View.GONE);
+                mClockViewBold.setVisibility(View.VISIBLE);
+            } else {
+                mClockView.setVisibility(View.VISIBLE);
+                mClockViewBold.setVisibility(View.INVISIBLE);
+            }
             mKeyguardStatusArea.setVisibility(View.VISIBLE);
             return;
         }
@@ -320,6 +336,24 @@
         if (mClockPlugin != null) {
             mClockPlugin.setDarkAmount(darkAmount);
         }
+        updateBigClockAlpha();
+    }
+
+    /**
+     * Set whether or not the lock screen is showing notifications.
+     */
+    void setHasVisibleNotifications(boolean hasVisibleNotifications) {
+        if (hasVisibleNotifications == mHasVisibleNotifications) {
+            return;
+        }
+        mHasVisibleNotifications = hasVisibleNotifications;
+        if (mDarkAmount == 0f && mBigClockContainer != null) {
+            // Starting a fade transition since the visibility of the big clock will change.
+            TransitionManager.beginDelayedTransition(mBigClockContainer,
+                    new Fade().setDuration(KeyguardSliceView.DEFAULT_ANIM_DURATION / 2).addTarget(
+                            mBigClockContainer));
+        }
+        updateBigClockAlpha();
     }
 
     public Paint getPaint() {
@@ -374,7 +408,7 @@
 
     private void updateColors() {
         ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         mSupportsDarkText = colors.supportsDarkText();
         mColorPalette = colors.getColorPalette();
         if (mClockPlugin != null) {
@@ -396,15 +430,30 @@
         }
     }
 
+    private void updateBigClockAlpha() {
+        if (mBigClockContainer != null) {
+            final float alpha = mHasVisibleNotifications ? mDarkAmount : 1f;
+            mBigClockContainer.setAlpha(alpha);
+            if (alpha == 0f) {
+                mBigClockContainer.setVisibility(INVISIBLE);
+            } else if (mBigClockContainer.getVisibility() == INVISIBLE) {
+                mBigClockContainer.setVisibility(VISIBLE);
+            }
+        }
+    }
+
     /**
      * Sets if the keyguard slice is showing a center-aligned header. We need a smaller clock in
      * these cases.
      */
     void setKeyguardShowingHeader(boolean hasHeader) {
-        if (mShowingHeader == hasHeader || hasCustomClock()) {
+        if (mShowingHeader == hasHeader) {
             return;
         }
         mShowingHeader = hasHeader;
+        if (hasCustomClock()) {
+            return;
+        }
 
         float smallFontSize = mContext.getResources().getDimensionPixelSize(
                 R.dimen.widget_small_font_size);
@@ -569,11 +618,16 @@
                 view.setScaleX(scale);
                 view.setScaleY(scale);
             });
-            animator.addListener(new AnimatorListenerAdapter() {
+            animator.addListener(new KeepAwakeAnimationListener(getContext()) {
                 @Override
                 public void onAnimationStart(Animator animation) {
                     super.onAnimationStart(animation);
                     view.setVisibility(startVisibility);
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    super.onAnimationEnd(animation);
                     animation.removeListener(this);
                 }
             });
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 362ead3..55ddfc3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -248,7 +248,8 @@
 
     @Override
     public boolean disallowInterceptTouch(MotionEvent event) {
-        return mLockPatternScreenBounds.contains((int) event.getRawX(), (int) event.getRawY());
+        return !mLockPatternView.isEmpty()
+                || mLockPatternScreenBounds.contains((int) event.getRawX(), (int) event.getRawY());
     }
 
     /** TODO: hook this up */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index eef61db..4ad262f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -46,6 +46,7 @@
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.systemui.Dependency;
 import com.android.systemui.SystemUIFactory;
+import com.android.systemui.statusbar.phone.UnlockMethodCache;
 import com.android.systemui.util.InjectionInflationController;
 
 public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSecurityView {
@@ -90,6 +91,7 @@
     private final SpringAnimation mSpringAnimation;
     private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
     private final KeyguardUpdateMonitor mUpdateMonitor;
+    private final UnlockMethodCache mUnlockMethodCache;
 
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
     private float mLastTouchY = -1;
@@ -129,6 +131,7 @@
         mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
         mInjectionInflationController =  new InjectionInflationController(
             SystemUIFactory.getInstance().getRootComponent());
+        mUnlockMethodCache = UnlockMethodCache.getInstance(context);
         mViewConfiguration = ViewConfiguration.get(context);
     }
 
@@ -234,6 +237,7 @@
                     MIN_DRAG_SIZE, getResources().getDisplayMetrics())
                     && !mUpdateMonitor.isFaceDetectionRunning()) {
                 mUpdateMonitor.requestFaceAuth();
+                mCallback.userActivity();
                 showMessage(null, null);
             }
         }
@@ -265,12 +269,10 @@
      */
     private void updateBiometricRetry() {
         SecurityMode securityMode = getSecurityMode();
-        int userId = KeyguardUpdateMonitor.getCurrentUser();
-        mSwipeUpToRetry = mUpdateMonitor.isUnlockWithFacePossible(userId)
+        mSwipeUpToRetry = mUnlockMethodCache.isUnlockingWithFacePossible()
                 && securityMode != SecurityMode.SimPin
                 && securityMode != SecurityMode.SimPuk
-                && securityMode != SecurityMode.None
-                && securityMode != SecurityMode.Pattern;
+                && securityMode != SecurityMode.None;
     }
 
     public CharSequence getTitle() {
@@ -511,7 +513,7 @@
                 case SimPuk:
                     // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home
                     SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId);
-                    if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled(
+                    if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled(
                             KeyguardUpdateMonitor.getCurrentUser())) {
                         finish = true;
                         eventSubtype = BOUNCER_DISMISS_SIM;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index a7fe607..37e89c0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -61,6 +61,7 @@
     private KeyguardClockSwitch mClockView;
     private TextView mOwnerInfo;
     private KeyguardSliceView mKeyguardSlice;
+    private View mNotificationIcons;
     private Runnable mPendingMarqueeStart;
     private Handler mHandler;
 
@@ -72,8 +73,8 @@
      * Bottom margin that defines the margin between bottom of smart space and top of notification
      * icons on AOD.
      */
-    private int mBottomMargin;
-    private int mBottomMarginWithHeader;
+    private int mIconTopMargin;
+    private int mIconTopMarginWithHeader;
     private boolean mShowingHeader;
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@@ -144,6 +145,13 @@
         return mClockView.hasCustomClock();
     }
 
+    /**
+     * Set whether or not the lock screen is showing notifications.
+     */
+    public void setHasVisibleNotifications(boolean hasVisibleNotifications) {
+        mClockView.setHasVisibleNotifications(hasVisibleNotifications);
+    }
+
     private void setEnableMarquee(boolean enabled) {
         if (DEBUG) Log.v(TAG, "Schedule setEnableMarquee: " + (enabled ? "Enable" : "Disable"));
         if (enabled) {
@@ -173,6 +181,7 @@
         super.onFinishInflate();
         mStatusViewContainer = findViewById(R.id.status_view_container);
         mLogoutView = findViewById(R.id.logout);
+        mNotificationIcons = findViewById(R.id.clock_notification_icon_container);
         if (mLogoutView != null) {
             mLogoutView.setOnClickListener(this::onLogoutClicked);
         }
@@ -207,12 +216,14 @@
             return;
         }
         mShowingHeader = hasHeader;
-        // Update bottom margin since header has appeared/disappeared.
-        if (mStatusViewContainer != null) {
-            MarginLayoutParams params = (MarginLayoutParams) mStatusViewContainer.getLayoutParams();
-            params.setMargins(params.leftMargin, params.topMargin, params.rightMargin,
-                    hasHeader ? mBottomMarginWithHeader : mBottomMargin);
-            mStatusViewContainer.setLayoutParams(params);
+        if (mNotificationIcons != null) {
+            // Update top margin since header has appeared/disappeared.
+            MarginLayoutParams params = (MarginLayoutParams) mNotificationIcons.getLayoutParams();
+            params.setMargins(params.leftMargin,
+                    hasHeader ? mIconTopMarginWithHeader : mIconTopMargin,
+                    params.rightMargin,
+                    params.bottomMargin);
+            mNotificationIcons.setLayoutParams(params);
         }
     }
 
@@ -338,8 +349,8 @@
     }
 
     private void loadBottomMargin() {
-        mBottomMargin = getResources().getDimensionPixelSize(R.dimen.widget_vertical_padding);
-        mBottomMarginWithHeader = getResources().getDimensionPixelSize(
+        mIconTopMargin = getResources().getDimensionPixelSize(R.dimen.widget_vertical_padding);
+        mIconTopMarginWithHeader = getResources().getDimensionPixelSize(
                 R.dimen.widget_vertical_padding_with_header);
     }
 
@@ -412,6 +423,13 @@
             int expanded = mOwnerInfo.getBottom() + mOwnerInfo.getPaddingBottom();
             int toRemove = (int) ((expanded - collapsed) * ratio);
             setBottom(getMeasuredHeight() - toRemove);
+            if (mNotificationIcons != null) {
+                // We're using scrolling in order not to overload the translation which is used
+                // when appearing the icons
+                mNotificationIcons.setScrollY(toRemove);
+            }
+        } else if (mNotificationIcons != null){
+            mNotificationIcons.setScrollY(0);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 873874f..fd618b0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -28,6 +28,13 @@
 import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
 import static android.os.BatteryManager.EXTRA_PLUGGED;
 import static android.os.BatteryManager.EXTRA_STATUS;
+import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 
 import android.annotation.AnyThread;
 import android.annotation.MainThread;
@@ -70,6 +77,7 @@
 import android.provider.Settings;
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
+import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -88,6 +96,7 @@
 import com.android.settingslib.WirelessUtils;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 
 import com.google.android.collect.Lists;
 
@@ -111,6 +120,7 @@
     private static final String TAG = "KeyguardUpdateMonitor";
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
+    private static final boolean DEBUG_FACE = true;
     private static final int LOW_BATTERY_THRESHOLD = 20;
 
     private static final String ACTION_FACE_UNLOCK_STARTED
@@ -182,6 +192,7 @@
      * Prudently disable lockscreen.
      */
     public static final boolean CORE_APPS_ONLY;
+
     static {
         try {
             CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
@@ -210,6 +221,7 @@
     private boolean mHasLockscreenWallpaper;
     private boolean mAssistantVisible;
     private boolean mKeyguardOccluded;
+    private boolean mSecureCameraLaunched;
     @VisibleForTesting
     protected boolean mTelephonyCapable;
 
@@ -234,6 +246,7 @@
     private List<SubscriptionInfo> mSubscriptionInfo;
     private TrustManager mTrustManager;
     private UserManager mUserManager;
+    private KeyguardBypassController mKeyguardBypassController;
     private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
     private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
     private LockPatternUtils mLockPatternUtils;
@@ -364,19 +377,27 @@
         }
     };
 
-    private boolean mFaceSettingEnabledForUser;
+    private SparseBooleanArray mFaceSettingEnabledForUser = new SparseBooleanArray();
     private BiometricManager mBiometricManager;
     private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
             new IBiometricEnabledOnKeyguardCallback.Stub() {
         @Override
-        public void onChanged(BiometricSourceType type, boolean enabled) throws RemoteException {
+        public void onChanged(BiometricSourceType type, boolean enabled, int userId)
+                throws RemoteException {
             if (type == BiometricSourceType.FACE) {
-                mFaceSettingEnabledForUser = enabled;
+                mFaceSettingEnabledForUser.put(userId, enabled);
                 updateFaceListeningState();
             }
         }
     };
 
+    private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+        @Override
+        public void onActiveDataSubscriptionIdChanged(int subId) {
+            mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
+        }
+    };
+
     private OnSubscriptionsChangedListener mSubscriptionListener =
             new OnSubscriptionsChangedListener() {
         @Override
@@ -426,7 +447,7 @@
     private void handleSimSubscriptionInfoChanged() {
         if (DEBUG_SIM_STATES) {
             Log.v(TAG, "onSubscriptionInfoChanged()");
-            List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
+            List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
             if (sil != null) {
                 for (SubscriptionInfo subInfo : sil) {
                     Log.v(TAG, "SubInfo:" + subInfo);
@@ -478,7 +499,7 @@
     public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
         List<SubscriptionInfo> sil = mSubscriptionInfo;
         if (sil == null || forceReload) {
-            sil = mSubscriptionManager.getActiveSubscriptionInfoList();
+            sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
         }
         if (sil == null) {
             // getActiveSubscriptionInfoList was null callers expect an empty list.
@@ -521,6 +542,14 @@
     }
 
     /**
+     * Invoked when the secure camera is launched.
+     */
+    public void onCameraLaunched() {
+        mSecureCameraLaunched = true;
+        updateBiometricListeningState();
+    }
+
+    /**
      * @return a cached version of DreamManager.isDreaming()
      */
     public boolean isDreaming() {
@@ -650,8 +679,7 @@
         }
 
         if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
-            mLockPatternUtils.requireStrongAuth(
-                    LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
+            mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
                     getCurrentUser());
         }
 
@@ -734,6 +762,7 @@
         if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
             return;
         }
+        if (DEBUG_FACE) Log.d(TAG, "Face acquired");
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -745,6 +774,10 @@
     private void handleFaceAuthenticated(int authUserId) {
         Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
         try {
+            if (mGoingToSleep) {
+                Log.d(TAG, "Aborted successful auth because device is going to sleep.");
+                return;
+            }
             final int userId;
             try {
                 userId = ActivityManager.getService().getCurrentUser().id;
@@ -760,6 +793,7 @@
                 Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
                 return;
             }
+            if (DEBUG_FACE) Log.d(TAG, "Face auth succeeded for user " + userId);
             onFaceAuthenticated(userId);
         } finally {
             setFaceRunningState(BIOMETRIC_STATE_STOPPED);
@@ -768,6 +802,7 @@
     }
 
     private void handleFaceHelp(int msgId, String helpString) {
+        if (DEBUG_FACE) Log.d(TAG, "Face help received: " + helpString);
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -786,6 +821,7 @@
     };
 
     private void handleFaceError(int msgId, String errString) {
+        if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
         if (msgId == FaceManager.FACE_ERROR_CANCELED
                 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
             setFaceRunningState(BIOMETRIC_STATE_STOPPED);
@@ -803,8 +839,7 @@
         }
 
         if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
-            mLockPatternUtils.requireStrongAuth(
-                    LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
+            mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
                     getCurrentUser());
         }
 
@@ -923,8 +958,17 @@
     }
 
     public boolean isUserInLockdown(int userId) {
-        return mStrongAuthTracker.getStrongAuthForUser(userId)
-                == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+        return containsFlag(mStrongAuthTracker.getStrongAuthForUser(userId),
+                STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+    }
+
+    public boolean userNeedsStrongAuth() {
+        return mStrongAuthTracker.getStrongAuthForUser(getCurrentUser())
+                != LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+    }
+
+    private boolean containsFlag(int haystack, int needle) {
+        return (haystack & needle) != 0;
     }
 
     public boolean needsSlowUnlockTransition() {
@@ -1054,6 +1098,8 @@
                 }
                 mHandler.sendMessage(
                         mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
+            } else if (TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
+                mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
             } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
                     action)) {
                 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -1464,6 +1510,7 @@
         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
+        filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
         filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -1537,6 +1584,12 @@
         mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
         mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
         updateAirplaneModeState();
+
+        TelephonyManager telephony =
+                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+        if (telephony != null) {
+            telephony.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+        }
     }
 
     private void updateAirplaneModeState() {
@@ -1634,12 +1687,34 @@
     private boolean shouldListenForFace() {
         final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
         final int user = getCurrentUser();
+        final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
+        final boolean isLockOutOrLockDown =
+                containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_LOCKOUT)
+                        || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
+                        || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+        final boolean isEncryptedOrTimedOut =
+                containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
+                        || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
+
+        boolean canBypass = mKeyguardBypassController != null
+                && mKeyguardBypassController.canBypass();
+        // There's no reason to ask the HAL for authentication when the user can dismiss the
+        // bouncer, unless we're bypassing and need to auto-dismiss the lock screen even when
+        // TrustAgents or biometrics are keeping the device unlocked.
+        boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;
+
+        // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
+        // Lockout/lockdown modes shouldn't scan, since they are more explicit.
+        boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
+                && !isLockOutOrLockDown;
+
         // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
         // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
         return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
-                && !mSwitchingUser && !getUserCanSkipBouncer(user) && !isFaceDisabled(user)
-                && !mKeyguardGoingAway && mFaceSettingEnabledForUser && !mLockIconPressed
-                && mUserManager.isUserUnlocked(user) && mIsPrimaryUser;
+                && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
+                && !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
+                && strongAuthAllowsScanning && mIsPrimaryUser
+                && !mSecureCameraLaunched;
     }
 
     /**
@@ -1709,13 +1784,14 @@
     }
 
     /**
-     * If face hardware is available and user has enrolled. Not considering encryption or
-     * lockdown state.
+     * If face hardware is available, user has enrolled and enabled auth via setting.
+     * Not considering encryption or lock down state.
      */
     public boolean isUnlockWithFacePossible(int userId) {
         return mFaceManager != null && mFaceManager.isHardwareDetected()
                 && !isFaceDisabled(userId)
-                && mFaceManager.hasEnrolledTemplates(userId);
+                && mFaceManager.hasEnrolledTemplates(userId)
+                && mFaceSettingEnabledForUser.get(userId);
     }
 
     private void stopListeningForFingerprint() {
@@ -2087,6 +2163,11 @@
         checkIsHandlerThread();
         Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
         mKeyguardIsVisible = showing;
+
+        if (showing) {
+            mSecureCameraLaunched = false;
+        }
+
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -2124,6 +2205,15 @@
         if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
         boolean isBouncer = (bouncer == 1);
         mBouncer = isBouncer;
+
+        if (isBouncer) {
+            // If the bouncer is shown, always clear this flag. This can happen in the following
+            // situations: 1) Default camera with SHOW_WHEN_LOCKED is not chosen yet. 2) Secure
+            // camera requests dismiss keyguard (tapping on photos for example). When these happen,
+            // face auth should resume.
+            mSecureCameraLaunched = false;
+        }
+
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -2205,6 +2295,10 @@
         sendUpdates(callback);
     }
 
+    public void setKeyguardBypassController(KeyguardBypassController keyguardBypassController) {
+        mKeyguardBypassController = keyguardBypassController;
+    }
+
     public boolean isSwitchingUser() {
         return mSwitchingUser;
     }
@@ -2295,6 +2389,13 @@
         mUserFaceAuthenticated.clear();
         mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
         mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
+
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onBiometricsCleared();
+            }
+        }
     }
 
     public boolean isSimPinVoiceSecure() {
@@ -2558,7 +2659,8 @@
             pw.println("    possible=" + isUnlockWithFacePossible(userId));
             pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
             pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
-            pw.println("    enabledByUser=" + mFaceSettingEnabledForUser);
+            pw.println("    enabledByUser=" + mFaceSettingEnabledForUser.get(userId));
+            pw.println("    mSecureCameraLaunched=" + mSecureCameraLaunched);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 8696bb7..0fef755 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -314,4 +314,9 @@
      */
     public void onLogoutEnabledChanged() { }
 
+    /**
+     * Called when authenticated biometrics are cleared.
+     */
+    public void onBiometricsCleared() { }
+
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
index f468eca..9c5242c 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
@@ -75,6 +75,11 @@
     private TextClock mLockClock;
 
     /**
+     * Helper to extract colors from wallpaper palette for clock face.
+     */
+    private final ClockPalette mPalette = new ClockPalette();
+
+    /**
      * Create a BubbleClockController instance.
      *
      * @param res Resources contains title and thumbnail.
@@ -130,7 +135,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
@@ -162,17 +167,21 @@
     public void setStyle(Style style) {}
 
     @Override
-    public void setTextColor(int color) { }
+    public void setTextColor(int color) {
+        updateColor();
+    }
 
     @Override
     public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
-        if (colorPalette == null || colorPalette.length == 0) {
-            return;
-        }
-        final int length = colorPalette.length;
-        mLockClock.setTextColor(colorPalette[Math.max(0, length - 2)]);
-        mAnalogClock.setClockColors(colorPalette[Math.max(0, length - 5)],
-                colorPalette[Math.max(0, length - 2)]);
+        mPalette.setColorPalette(supportsDarkText, colorPalette);
+        updateColor();
+    }
+
+    private void updateColor() {
+        final int primary = mPalette.getPrimaryColor();
+        final int secondary = mPalette.getSecondaryColor();
+        mLockClock.setTextColor(secondary);
+        mAnalogClock.setClockColors(primary, secondary);
     }
 
     @Override
@@ -184,6 +193,7 @@
 
     @Override
     public void setDarkAmount(float darkAmount) {
+        mPalette.setDarkAmount(darkAmount);
         mClockPosition.setDarkAmount(darkAmount);
         mBigClockView.setDarkAmount(darkAmount);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index bd1e64a..8e81327 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -75,6 +75,11 @@
     private TextClock mLockClock;
 
     /**
+     * Helper to extract colors from wallpaper palette for clock face.
+     */
+    private final ClockPalette mPalette = new ClockPalette();
+
+    /**
      * Create a BubbleClockController instance.
      *
      * @param res Resources contains title and thumbnail.
@@ -130,7 +135,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
@@ -162,22 +167,26 @@
     public void setStyle(Style style) {}
 
     @Override
-    public void setTextColor(int color) { }
+    public void setTextColor(int color) {
+        updateColor();
+    }
 
     @Override
     public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
-        if (colorPalette == null || colorPalette.length == 0) {
-            return;
-        }
-        final int length = colorPalette.length;
-        final int primaryColor = colorPalette[Math.max(0, length - 2)];
-        final int secondaryColor = colorPalette[Math.max(0, length - 5)];
-        mLockClock.setTextColor(primaryColor);
-        mAnalogClock.setClockColors(secondaryColor, primaryColor);
+        mPalette.setColorPalette(supportsDarkText, colorPalette);
+        updateColor();
+    }
+
+    private void updateColor() {
+        final int primary = mPalette.getPrimaryColor();
+        final int secondary = mPalette.getSecondaryColor();
+        mLockClock.setTextColor(secondary);
+        mAnalogClock.setClockColors(primary, secondary);
     }
 
     @Override
     public void setDarkAmount(float darkAmount) {
+        mPalette.setDarkAmount(darkAmount);
         mClockPosition.setDarkAmount(darkAmount);
         mView.setDarkAmount(darkAmount);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
index 1908345..7485d33 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
@@ -94,7 +94,8 @@
                 getBurnInOffset(mBurnInPreventionOffsetX * 2, true) - mBurnInPreventionOffsetX,
                 mDarkAmount);
         final float offsetY = MathUtils.lerp(0f,
-                getBurnInOffset(mBurnInPreventionOffsetY * 2, false) - mBurnInPreventionOffsetY,
+                getBurnInOffset(mBurnInPreventionOffsetY * 2, false)
+                        - 0.5f * mBurnInPreventionOffsetY,
                 mDarkAmount);
 
         // Put the analog clock in the middle of the screen.
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
index 9f4c403e..9e2464e 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
@@ -240,9 +240,9 @@
     }
 
     private void reload() {
-        mPreviewClocks.reload();
+        mPreviewClocks.reloadCurrentClock();
         mListeners.forEach((listener, clocks) -> {
-            clocks.reload();
+            clocks.reloadCurrentClock();
             ClockPlugin clock = clocks.getCurrentClock();
             if (clock instanceof DefaultClockController) {
                 listener.onClockChanged(null);
@@ -287,20 +287,13 @@
         @Override
         public void onPluginConnected(ClockPlugin plugin, Context pluginContext) {
             addClockPlugin(plugin);
-            reload();
-            if (plugin == mCurrentClock) {
-                ClockManager.this.reload();
-            }
+            reloadIfNeeded(plugin);
         }
 
         @Override
         public void onPluginDisconnected(ClockPlugin plugin) {
-            boolean isCurrentClock = plugin == mCurrentClock;
             removeClockPlugin(plugin);
-            reload();
-            if (isCurrentClock) {
-                ClockManager.this.reload();
-            }
+            reloadIfNeeded(plugin);
         }
 
         /**
@@ -347,10 +340,19 @@
             }
         }
 
+        private void reloadIfNeeded(ClockPlugin plugin) {
+            final boolean wasCurrentClock = plugin == mCurrentClock;
+            reloadCurrentClock();
+            final boolean isCurrentClock = plugin == mCurrentClock;
+            if (wasCurrentClock || isCurrentClock) {
+                ClockManager.this.reload();
+            }
+        }
+
         /**
          * Update the current clock.
          */
-        void reload() {
+        void reloadCurrentClock() {
             mCurrentClock = getClockPlugin();
         }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt b/packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt
new file mode 100644
index 0000000..5c5493a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.graphics.Color
+import android.util.MathUtils
+
+private const val PRIMARY_INDEX = 5
+private const val SECONDARY_DARK_INDEX = 8
+private const val SECONDARY_LIGHT_INDEX = 2
+
+/**
+ * A helper class to extract colors from a clock face.
+ */
+class ClockPalette {
+
+    private var darkAmount: Float = 0f
+    private var accentPrimary: Int = Color.WHITE
+    private var accentSecondaryLight: Int = Color.WHITE
+    private var accentSecondaryDark: Int = Color.BLACK
+    private val lightHSV: FloatArray = FloatArray(3)
+    private val darkHSV: FloatArray = FloatArray(3)
+    private val hsv: FloatArray = FloatArray(3)
+
+    /** Returns a color from the palette as an RGB packed int. */
+    fun getPrimaryColor(): Int {
+        return accentPrimary
+    }
+
+    /** Returns either a light or dark color from the palette as an RGB packed int. */
+    fun getSecondaryColor(): Int {
+        Color.colorToHSV(accentSecondaryLight, lightHSV)
+        Color.colorToHSV(accentSecondaryDark, darkHSV)
+        for (i in 0..2) {
+            hsv[i] = MathUtils.lerp(darkHSV[i], lightHSV[i], darkAmount)
+        }
+        return Color.HSVToColor(hsv)
+    }
+
+    /** See {@link ClockPlugin#setColorPalette}. */
+    fun setColorPalette(supportsDarkText: Boolean, colorPalette: IntArray?) {
+        if (colorPalette == null || colorPalette.isEmpty()) {
+            accentPrimary = Color.WHITE
+            accentSecondaryLight = Color.WHITE
+            accentSecondaryDark = if (supportsDarkText) Color.BLACK else Color.WHITE
+            return
+        }
+        val length = colorPalette.size
+        accentPrimary = colorPalette[Math.max(0, length - PRIMARY_INDEX)]
+        accentSecondaryLight = colorPalette[Math.max(0, length - SECONDARY_LIGHT_INDEX)]
+        accentSecondaryDark = colorPalette[Math.max(0,
+                length - if (supportsDarkText) SECONDARY_DARK_INDEX else SECONDARY_LIGHT_INDEX)]
+    }
+
+    /** See {@link ClockPlugin#setDarkAmount}. */
+    fun setDarkAmount(darkAmount: Float) {
+        this.darkAmount = darkAmount
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
index ce1f09c..98679ade 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
@@ -124,7 +124,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java b/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java
index e1c658be..096e943 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java
@@ -15,21 +15,37 @@
  */
 package com.android.keyguard.clock;
 
+import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.provider.Settings;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import org.json.JSONException;
+import org.json.JSONObject;
 
 /**
  * Wrapper around Settings used for testing.
  */
 public class SettingsWrapper {
 
+    private static final String TAG = "ClockFaceSettings";
     private static final String CUSTOM_CLOCK_FACE = Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE;
     private static final String DOCKED_CLOCK_FACE = Settings.Secure.DOCKED_CLOCK_FACE;
+    private static final String CLOCK_FIELD = "clock";
 
-    private ContentResolver mContentResolver;
+    private final ContentResolver mContentResolver;
+    private final Migration mMigration;
 
-    public SettingsWrapper(ContentResolver contentResolver) {
+    SettingsWrapper(ContentResolver contentResolver) {
+        this(contentResolver, new Migrator(contentResolver));
+    }
+
+    @VisibleForTesting
+    SettingsWrapper(ContentResolver contentResolver, Migration migration) {
         mContentResolver = contentResolver;
+        mMigration = migration;
     }
 
     /**
@@ -37,8 +53,10 @@
      *
      * @param userId ID of the user.
      */
-    public String getLockScreenCustomClockFace(int userId) {
-        return Settings.Secure.getStringForUser(mContentResolver, CUSTOM_CLOCK_FACE, userId);
+    String getLockScreenCustomClockFace(int userId) {
+        return decode(
+                Settings.Secure.getStringForUser(mContentResolver, CUSTOM_CLOCK_FACE, userId),
+                userId);
     }
 
     /**
@@ -46,7 +64,74 @@
      *
      * @param userId ID of the user.
      */
-    public String getDockedClockFace(int userId) {
+    String getDockedClockFace(int userId) {
         return Settings.Secure.getStringForUser(mContentResolver, DOCKED_CLOCK_FACE, userId);
     }
+
+    /**
+     * Decodes the string stored in settings, which should be formatted as JSON.
+     * @param value String stored in settings. If value is not JSON, then the settings is
+     *              overwritten with JSON containing the prior value.
+     * @return ID of the clock face to show on AOD and lock screen. If value is not JSON, the value
+     *         is returned.
+     */
+    @VisibleForTesting
+    String decode(@Nullable String value, int userId) {
+        if (value == null) {
+            return value;
+        }
+        JSONObject json;
+        try {
+            json = new JSONObject(value);
+        } catch (JSONException ex) {
+            Log.e(TAG, "Settings value is not valid JSON", ex);
+            // The settings value isn't JSON since it didn't parse so migrate the value to JSON.
+            // TODO(b/135674383): Remove this migration path in the following release.
+            mMigration.migrate(value, userId);
+            return value;
+        }
+        try {
+            return json.getString(CLOCK_FIELD);
+        } catch (JSONException ex) {
+            Log.e(TAG, "JSON object does not contain clock field.", ex);
+            return null;
+        }
+    }
+
+    interface Migration {
+        void migrate(String value, int userId);
+    }
+
+    /**
+     * Implementation of {@link Migration} that writes valid JSON back to Settings.
+     */
+    private static final class Migrator implements Migration {
+
+        private final ContentResolver mContentResolver;
+
+        Migrator(ContentResolver contentResolver) {
+            mContentResolver = contentResolver;
+        }
+
+        /**
+         * Migrate settings values that don't parse by converting to JSON format.
+         *
+         * Values in settings must be JSON to be backed up and restored. To help users maintain
+         * their current settings, convert existing values into the JSON format.
+         *
+         * TODO(b/135674383): Remove this migration code in the following release.
+         */
+        @Override
+        public void migrate(String value, int userId) {
+            try {
+                JSONObject json = new JSONObject();
+                json.put(CLOCK_FIELD, value);
+                Settings.Secure.putStringForUser(mContentResolver, CUSTOM_CLOCK_FACE,
+                        json.toString(),
+                        userId);
+            } catch (JSONException ex) {
+                Log.e(TAG, "Failed migrating settings value to JSON format", ex);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
index 9b15dc6..60ca945 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
@@ -67,7 +67,8 @@
      */
     int getPreferredY() {
         // On AOD, clock needs to appear below the status bar with enough room for pixel shifting
-        int aodY = mStatusBarHeight + mKeyguardLockPadding + mBurnInOffsetY;
+        int aodY = mStatusBarHeight + mKeyguardLockHeight + 2 * mKeyguardLockPadding
+                + mBurnInOffsetY;
         // On lock screen, clock needs to appear below the lock icon
         int lockY =  mStatusBarHeight + mKeyguardLockHeight + 2 * mKeyguardLockPadding;
         return (int) MathUtils.lerp(lockY, aodY, mDarkAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index bce5c23..ffa69fa 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -356,8 +356,8 @@
                     if (estimate != null) {
                         mBatteryPercentView.setText(estimate);
                         setContentDescription(getContext().getString(
-                                R.string.battery_low_percent_format_hybrid, mLevel, estimate));
-
+                                R.string.accessibility_battery_level_with_estimate,
+                                mLevel, estimate));
                     } else {
                         setPercentTextAtCurrentLevel();
                     }
@@ -365,6 +365,10 @@
             } else {
                 setPercentTextAtCurrentLevel();
             }
+        } else {
+            setContentDescription(
+                    getContext().getString(mCharging ? R.string.accessibility_battery_level_charging
+                            : R.string.accessibility_battery_level, mLevel));
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
new file mode 100644
index 0000000..8fabe7a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java
@@ -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.
+ */
+
+package com.android.systemui;
+
+/**
+ * Interface necessary to make Dagger happy. See {@link ContextComponentResolver}.
+ */
+public interface ContextComponentHelper {
+    /** Turns a classname into an instance of the class or returns null. */
+    <T> T resolve(String className);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
new file mode 100644
index 0000000..09bccd9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+/**
+ * Used during Service and Activity instantiation to make them injectable.
+ */
+public class ContextComponentResolver implements ContextComponentHelper {
+    private final Map<Class<?>, Provider<Object>> mCreators;
+
+    @Inject
+    ContextComponentResolver(Map<Class<?>, Provider<Object>> creators) {
+        mCreators = creators;
+    }
+
+    /**
+     * Looks up the class name to see if Dagger has an instance of it.
+     */
+    @Override
+    public <T> T resolve(String className) {
+        for (Map.Entry<Class<?>, Provider<Object>> p : mCreators.entrySet()) {
+            if (p.getKey().getName().equals(className)) {
+                return (T) p.getValue().get();
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
index 528db5a..54a3635 100644
--- a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
+++ b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java
@@ -20,8 +20,8 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.graphics.Path;
 import android.graphics.RectF;
-import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.view.ContextThemeWrapper;
@@ -34,17 +34,19 @@
  * corners.
  */
 public class CornerHandleView extends View {
-    private static final boolean ALLOW_TUNING = false;
-    private static final int ANGLE_DEGREES = 50;
-    public static final int MARGIN_DP = 11;
-    public static final int RADIUS_DP = 37;
-    public static final float STROKE_DP = 2.5f;
+    private static final float STROKE_DP_LARGE = 2f;
+    private static final float STROKE_DP_SMALL = 1.95f;
+    // Radius to use if none is available.
+    private static final int FALLBACK_RADIUS_DP = 15;
+    private static final float MARGIN_DP = 8;
+    private static final int MAX_ARC_DEGREES = 90;
+    // Arc length along the phone's perimeter used to measure the desired angle.
+    private static final float ARC_LENGTH_DP = 31f;
 
     private Paint mPaint;
     private int mLightColor;
     private int mDarkColor;
-    private RectF mOval;
-
+    private Path mPath;
 
     public CornerHandleView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -55,23 +57,51 @@
         mPaint.setStrokeCap(Paint.Cap.ROUND);
         mPaint.setStrokeWidth(getStrokePx());
 
-        final int dualToneDarkTheme = Utils.getThemeAttr(mContext,
-                R.attr.darkIconTheme);
-        final int dualToneLightTheme = Utils.getThemeAttr(mContext,
-                R.attr.lightIconTheme);
+        final int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
+        final int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
         Context lightContext = new ContextThemeWrapper(mContext, dualToneLightTheme);
         Context darkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme);
-        mLightColor = Utils.getColorAttrDefaultColor(lightContext,
-                R.attr.singleToneColor);
-        mDarkColor = Utils.getColorAttrDefaultColor(darkContext,
-                R.attr.singleToneColor);
+        mLightColor = Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor);
+        mDarkColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
 
-        updateOval();
+        updatePath();
+    }
+
+    private void updatePath() {
+        mPath = new Path();
+
+        float marginPx = getMarginPx();
+        float radiusPx = getInnerRadiusPx();
+        float halfStrokePx = getStrokePx() / 2f;
+        float angle = getAngle();
+        float startAngle = 180 + ((90 - angle) / 2);
+        RectF circle = new RectF(marginPx + halfStrokePx,
+                marginPx + halfStrokePx,
+                marginPx + 2 * radiusPx - halfStrokePx,
+                marginPx + 2 * radiusPx - halfStrokePx);
+
+        if (angle >= 90f) {
+            float innerCircumferenceDp = convertPixelToDp(radiusPx * 2 * (float) Math.PI,
+                    mContext);
+            float arcDp = innerCircumferenceDp * getAngle() / 360f;
+            // Add additional "arms" to the two ends of the arc. The length computation is
+            // hand-tuned.
+            float lineLengthPx = convertDpToPixel((ARC_LENGTH_DP - arcDp - MARGIN_DP) / 2,
+                    mContext);
+
+            mPath.moveTo(marginPx + halfStrokePx, marginPx + radiusPx + lineLengthPx);
+            mPath.lineTo(marginPx + halfStrokePx, marginPx + radiusPx);
+            mPath.arcTo(circle, startAngle, angle);
+            mPath.moveTo(marginPx + radiusPx, marginPx + halfStrokePx);
+            mPath.lineTo(marginPx + radiusPx + lineLengthPx, marginPx + halfStrokePx);
+        } else {
+            mPath.arcTo(circle, startAngle, angle);
+        }
     }
 
     /**
      * Receives an intensity from 0 (lightest) to 1 (darkest) and sets the handle color
-     * approriately. Intention is to match the home handle color.
+     * appropriately. Intention is to match the home handle color.
      */
     public void updateDarkness(float darkIntensity) {
         mPaint.setColor((int) ArgbEvaluator.getInstance().evaluate(darkIntensity,
@@ -83,61 +113,61 @@
     @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-
-        if (ALLOW_TUNING) {
-            mPaint.setStrokeWidth(getStrokePx());
-            updateOval();
-        }
-
-        canvas.drawArc(mOval, 180 + ((90 - getAngle()) / 2), getAngle(), false,
-                mPaint);
+        canvas.drawPath(mPath, mPaint);
     }
 
-    // TODO(b/133834204): Remove tweaking of corner handles
     private static float convertDpToPixel(float dp, Context context) {
         return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
                 / DisplayMetrics.DENSITY_DEFAULT);
     }
 
-    private void updateOval() {
-        mOval = new RectF(getMarginPx() - (getStrokePx() / 2.f),
-                getMarginPx() - (getStrokePx() / 2.f),
-                getMarginPx() + (2 * (getRadiusPx()) + (getStrokePx() / 2.f)),
-                getMarginPx() + 2 * getRadiusPx() + (getStrokePx() / 2.f));
+    private static float convertPixelToDp(float px, Context context) {
+        return px * DisplayMetrics.DENSITY_DEFAULT
+                / ((float) context.getResources().getDisplayMetrics().densityDpi);
     }
 
-    private int getAngle() {
-        if (ALLOW_TUNING) {
-            return SystemProperties.getInt("CORNER_HANDLE_ANGLE_DEGREES", ANGLE_DEGREES);
-        } else {
-            return ANGLE_DEGREES;
+    private float getAngle() {
+        // Measure a length of ARC_LENGTH_DP along the *screen's* perimeter, get the angle and cap
+        // it at 90.
+        float circumferenceDp = convertPixelToDp((
+                getOuterRadiusPx()) * 2 * (float) Math.PI, mContext);
+        float angleDeg = (ARC_LENGTH_DP / circumferenceDp) * 360;
+        if (angleDeg > MAX_ARC_DEGREES) {
+            angleDeg = MAX_ARC_DEGREES;
         }
+        return angleDeg;
     }
 
-    private int getMarginPx() {
-        if (ALLOW_TUNING) {
-            return SystemProperties.getInt("CORNER_HANDLE_MARGIN_PX",
-                    (int) convertDpToPixel(MARGIN_DP, getContext()));
-        } else {
-            return (int) convertDpToPixel(MARGIN_DP, getContext());
-        }
+    private float getMarginPx() {
+        return convertDpToPixel(MARGIN_DP, mContext);
     }
 
-    private int getRadiusPx() {
-        if (ALLOW_TUNING) {
-            return SystemProperties.getInt("CORNER_HANDLE_RADIUS_PX",
-                    (int) convertDpToPixel(RADIUS_DP, getContext()));
-        } else {
-            return (int) convertDpToPixel(RADIUS_DP, getContext());
-        }
+    private float getInnerRadiusPx() {
+        return getOuterRadiusPx() - getMarginPx();
     }
 
-    private int getStrokePx() {
-        if (ALLOW_TUNING) {
-            return SystemProperties.getInt("CORNER_HANDLE_STROKE_PX",
-                    (int) convertDpToPixel(STROKE_DP, getContext()));
-        } else {
-            return (int) convertDpToPixel(STROKE_DP, getContext());
+    private float getOuterRadiusPx() {
+        // Attempt to get the bottom corner radius, otherwise fall back on the generic or top
+        // values. If none are available, use the FALLBACK_RADIUS_DP.
+        int radius = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.rounded_corner_radius_bottom);
+        if (radius == 0) {
+            radius = getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.rounded_corner_radius);
         }
+        if (radius == 0) {
+            radius = getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.rounded_corner_radius_top);
+        }
+        if (radius == 0) {
+            radius = (int) convertDpToPixel(FALLBACK_RADIUS_DP, mContext);
+        }
+        return radius;
+    }
+
+    private float getStrokePx() {
+        // Use a slightly smaller stroke if we need to cover the full corner angle.
+        return convertDpToPixel((getAngle() < 90) ? STROKE_DP_LARGE : STROKE_DP_SMALL,
+                getContext());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 7a82402..0ee9bff 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -54,7 +54,6 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
 import com.android.systemui.shared.system.PackageManagerWrapper;
-import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.NavigationBarController;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -268,7 +267,6 @@
     @Inject Lazy<VisualStabilityManager> mVisualStabilityManager;
     @Inject Lazy<NotificationGutsManager> mNotificationGutsManager;
     @Inject Lazy<NotificationMediaManager> mNotificationMediaManager;
-    @Inject Lazy<AmbientPulseManager> mAmbientPulseManager;
     @Inject Lazy<NotificationBlockingHelperManager> mNotificationBlockingHelperManager;
     @Inject Lazy<NotificationRemoteInputManager> mNotificationRemoteInputManager;
     @Inject Lazy<SmartReplyConstants> mSmartReplyConstants;
@@ -449,7 +447,6 @@
                 mNotificationGroupAlertTransferHelper::get);
         mProviders.put(NotificationMediaManager.class, mNotificationMediaManager::get);
         mProviders.put(NotificationGutsManager.class, mNotificationGutsManager::get);
-        mProviders.put(AmbientPulseManager.class, mAmbientPulseManager::get);
         mProviders.put(NotificationBlockingHelperManager.class,
                 mNotificationBlockingHelperManager::get);
         mProviders.put(NotificationRemoteInputManager.class,
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 8484256..c9d4957 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -19,6 +19,7 @@
 import android.app.ActivityManager;
 import android.content.Context;
 import android.graphics.Rect;
+import android.os.HandlerThread;
 import android.service.wallpaper.WallpaperService;
 import android.util.Log;
 import android.util.Size;
@@ -45,12 +46,29 @@
     // We delayed destroy render context that subsequent render requests have chance to cancel it.
     // This is to avoid destroying then recreating render context in a very short time.
     private static final int DELAY_FINISH_RENDERING = 1000;
+    private static final int INTERVAL_WAIT_FOR_RENDERING = 100;
+    private static final int PATIENCE_WAIT_FOR_RENDERING = 5;
+    private HandlerThread mWorker;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mWorker = new HandlerThread(TAG);
+        mWorker.start();
+    }
 
     @Override
     public Engine onCreateEngine() {
         return new GLEngine(this);
     }
 
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mWorker.quitSafely();
+        mWorker = null;
+    }
+
     class GLEngine extends Engine implements GLWallpaperRenderer.SurfaceProxy, StateListener {
         // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin)
         // set min to 64 px (CTS covers this), please refer to ag/4867989 for detail.
@@ -64,7 +82,10 @@
         private StatusBarStateController mController;
         private final Runnable mFinishRenderingTask = this::finishRendering;
         private final boolean mNeedTransition;
+        private final Object mMonitor = new Object();
         private boolean mNeedRedraw;
+        // This variable can only be accessed in synchronized block.
+        private boolean mWaitingForRendering;
 
         GLEngine(Context context) {
             mNeedTransition = ActivityManager.isHighEndGfx()
@@ -83,7 +104,7 @@
         @Override
         public void onCreate(SurfaceHolder surfaceHolder) {
             setFixedSizeAllowed(true);
-            setOffsetNotificationsEnabled(false);
+            setOffsetNotificationsEnabled(true);
             updateSurfaceSize();
         }
 
@@ -96,9 +117,37 @@
         }
 
         @Override
+        public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
+                float yOffsetStep, int xPixelOffset, int yPixelOffset) {
+            mWorker.getThreadHandler().post(() -> mRenderer.updateOffsets(xOffset, yOffset));
+        }
+
+        @Override
         public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
-            mRenderer.updateAmbientMode(inAmbientMode,
-                    (mNeedTransition || animationDuration != 0) ? animationDuration : 0);
+            long duration = mNeedTransition || animationDuration != 0 ? animationDuration : 0;
+            mWorker.getThreadHandler().post(
+                    () -> mRenderer.updateAmbientMode(inAmbientMode, duration));
+            if (inAmbientMode && duration == 0) {
+                // This means that we are transiting from home to aod, to avoid
+                // race condition between window visibility and transition,
+                // we don't return until the transition is finished. See b/136643341.
+                waitForBackgroundRendering();
+            }
+        }
+
+        private void waitForBackgroundRendering() {
+            synchronized (mMonitor) {
+                try {
+                    mWaitingForRendering = true;
+                    for (int patience = 1; mWaitingForRendering; patience++) {
+                        mMonitor.wait(INTERVAL_WAIT_FOR_RENDERING);
+                        mWaitingForRendering &= patience < PATIENCE_WAIT_FOR_RENDERING;
+                    }
+                } catch (InterruptedException ex) {
+                } finally {
+                    mWaitingForRendering = false;
+                }
+            }
         }
 
         @Override
@@ -107,53 +156,62 @@
                 mController.removeCallback(this /* StateListener */);
             }
             mController = null;
-            mRenderer.finish();
-            mRenderer = null;
-            mEglHelper.finish();
-            mEglHelper = null;
-            getSurfaceHolder().getSurface().hwuiDestroy();
+
+            mWorker.getThreadHandler().post(() -> {
+                mRenderer.finish();
+                mRenderer = null;
+                mEglHelper.finish();
+                mEglHelper = null;
+                getSurfaceHolder().getSurface().hwuiDestroy();
+            });
         }
 
         @Override
         public void onSurfaceCreated(SurfaceHolder holder) {
-            mEglHelper.init(holder);
-            mRenderer.onSurfaceCreated();
+            mWorker.getThreadHandler().post(() -> {
+                mEglHelper.init(holder);
+                mRenderer.onSurfaceCreated();
+            });
         }
 
         @Override
         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-            mRenderer.onSurfaceChanged(width, height);
-            mNeedRedraw = true;
+            mWorker.getThreadHandler().post(() -> {
+                mRenderer.onSurfaceChanged(width, height);
+                mNeedRedraw = true;
+            });
         }
 
         @Override
         public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
-            if (mNeedRedraw) {
-                preRender();
-                requestRender();
-                postRender();
-                mNeedRedraw = false;
-            }
-        }
-
-        @Override
-        public SurfaceHolder getHolder() {
-            return getSurfaceHolder();
+            mWorker.getThreadHandler().post(() -> {
+                if (mNeedRedraw) {
+                    preRender();
+                    requestRender();
+                    postRender();
+                    mNeedRedraw = false;
+                }
+            });
         }
 
         @Override
         public void onStatePostChange() {
             // When back to home, we try to release EGL, which is preserved in lock screen or aod.
             if (mController.getState() == StatusBarState.SHADE) {
-                scheduleFinishRendering();
+                mWorker.getThreadHandler().post(this::scheduleFinishRendering);
             }
         }
 
         @Override
         public void preRender() {
+            // This method should only be invoked from worker thread.
+            preRenderInternal();
+        }
+
+        private void preRenderInternal() {
             boolean contextRecreated = false;
             Rect frame = getSurfaceHolder().getSurfaceFrame();
-            getMainThreadHandler().removeCallbacks(mFinishRenderingTask);
+            cancelFinishRenderingTask();
 
             // Check if we need to recreate egl context.
             if (!mEglHelper.hasEglContext()) {
@@ -181,6 +239,11 @@
 
         @Override
         public void requestRender() {
+            // This method should only be invoked from worker thread.
+            requestRenderInternal();
+        }
+
+        private void requestRenderInternal() {
             Rect frame = getSurfaceHolder().getSurfaceFrame();
             boolean readyToRender = mEglHelper.hasEglContext() && mEglHelper.hasEglSurface()
                     && frame.width() > 0 && frame.height() > 0;
@@ -199,12 +262,30 @@
 
         @Override
         public void postRender() {
+            // This method should only be invoked from worker thread.
+            notifyWaitingThread();
             scheduleFinishRendering();
         }
 
+        private void notifyWaitingThread() {
+            synchronized (mMonitor) {
+                if (mWaitingForRendering) {
+                    try {
+                        mWaitingForRendering = false;
+                        mMonitor.notify();
+                    } catch (IllegalMonitorStateException ex) {
+                    }
+                }
+            }
+        }
+
+        private void cancelFinishRenderingTask() {
+            mWorker.getThreadHandler().removeCallbacks(mFinishRenderingTask);
+        }
+
         private void scheduleFinishRendering() {
-            getMainThreadHandler().removeCallbacks(mFinishRenderingTask);
-            getMainThreadHandler().postDelayed(mFinishRenderingTask, DELAY_FINISH_RENDERING);
+            cancelFinishRenderingTask();
+            mWorker.getThreadHandler().postDelayed(mFinishRenderingTask, DELAY_FINISH_RENDERING);
         }
 
         private void finishRendering() {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 4aaf85a..f38b4f2 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -25,6 +25,9 @@
 import static com.android.systemui.tuner.TunablePadding.FLAG_END;
 import static com.android.systemui.tuner.TunablePadding.FLAG_START;
 
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.annotation.Dimension;
 import android.app.ActivityManager;
 import android.app.Fragment;
@@ -49,6 +52,7 @@
 import android.provider.Settings.Secure;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.MathUtils;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.Gravity;
@@ -60,12 +64,9 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.OvershootInterpolator;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
-import android.view.animation.ScaleAnimation;
-import android.view.animation.TranslateAnimation;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
@@ -77,8 +78,10 @@
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.SecureSetting;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.NavigationBarTransitions;
+import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.tuner.TunablePadding;
 import com.android.systemui.tuner.TunerService;
@@ -125,6 +128,7 @@
     private Handler mHandler;
     private boolean mAssistHintBlocked = false;
     private boolean mIsReceivingNavBarColor = false;
+    private boolean mInGesturalMode;
 
     /**
      * Converts a set of {@link Rect}s into a {@link Region}
@@ -149,6 +153,58 @@
         mHandler.post(this::startOnScreenDecorationsThread);
         setupStatusBarPaddingIfNeeded();
         putComponent(ScreenDecorations.class, this);
+        mInGesturalMode = QuickStepContract.isGesturalMode(
+                Dependency.get(NavigationModeController.class)
+                        .addListener(this::handleNavigationModeChange));
+    }
+
+    @VisibleForTesting
+    void handleNavigationModeChange(int navigationMode) {
+        if (!mHandler.getLooper().isCurrentThread()) {
+            mHandler.post(() -> handleNavigationModeChange(navigationMode));
+            return;
+        }
+        boolean inGesturalMode = QuickStepContract.isGesturalMode(navigationMode);
+        if (mInGesturalMode != inGesturalMode) {
+            mInGesturalMode = inGesturalMode;
+
+            if (mInGesturalMode && mOverlay == null) {
+                setupDecorations();
+                if (mOverlay != null) {
+                    updateLayoutParams();
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns an animator that animates the given view from start to end over durationMs. Start and
+     * end represent total animation progress: 0 is the start, 1 is the end, 1.1 would be an
+     * overshoot.
+     */
+    Animator getHandleAnimator(View view, float start, float end, boolean isLeft, long durationMs,
+            Interpolator interpolator) {
+        // Note that lerp does allow overshoot, in cases where start and end are outside of [0,1].
+        float scaleStart = MathUtils.lerp(2f, 1f, start);
+        float scaleEnd = MathUtils.lerp(2f, 1f, end);
+        Animator scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scaleStart, scaleEnd);
+        Animator scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scaleStart, scaleEnd);
+        float translationStart = MathUtils.lerp(0.2f, 0f, start);
+        float translationEnd = MathUtils.lerp(0.2f, 0f, end);
+        int xDirection = isLeft ? -1 : 1;
+        Animator translateX = ObjectAnimator.ofFloat(view, View.TRANSLATION_X,
+                xDirection * translationStart * view.getWidth(),
+                xDirection * translationEnd * view.getWidth());
+        Animator translateY = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y,
+                translationStart * view.getHeight(), translationEnd * view.getHeight());
+
+        AnimatorSet set = new AnimatorSet();
+        set.play(scaleX).with(scaleY);
+        set.play(scaleX).with(translateX);
+        set.play(scaleX).with(translateY);
+        set.setDuration(durationMs);
+        set.setInterpolator(interpolator);
+        return set;
     }
 
     private void fade(View view, boolean fadeIn, boolean isLeft) {
@@ -157,26 +213,29 @@
             view.setAlpha(1f);
             view.setVisibility(View.VISIBLE);
 
-            AnimationSet anim = new AnimationSet(true);
-            anim.setDuration(900);
-
-            Animation scaleAnimation = new ScaleAnimation(2f, 1f, 2f, 1f,
-                    ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
-            anim.addAnimation(scaleAnimation);
-            anim.setInterpolator(new PathInterpolator(0.02f, 0.44f, 0.67f, 1.00f));
-
-            Animation translateAnimation = new TranslateAnimation(
-                    TranslateAnimation.RELATIVE_TO_SELF, isLeft ? -0.2f : 0.2f,
-                    TranslateAnimation.RELATIVE_TO_SELF,
-                    0f,
-                    TranslateAnimation.RELATIVE_TO_SELF, 0.2f, TranslateAnimation.RELATIVE_TO_SELF,
-                    0f);
-            anim.addAnimation(translateAnimation);
-            anim.setInterpolator(new OvershootInterpolator());
-            view.startAnimation(anim);
+            // A piecewise spring-like interpolation.
+            // End value in one animator call must match the start value in the next, otherwise
+            // there will be a discontinuity.
+            AnimatorSet anim = new AnimatorSet();
+            Animator first = getHandleAnimator(view, 0, 1.1f, isLeft, 750,
+                    new PathInterpolator(0, 0.45f, .67f, 1f));
+            Interpolator secondInterpolator = new PathInterpolator(0.33f, 0, 0.67f, 1f);
+            Animator second = getHandleAnimator(view, 1.1f, 0.97f, isLeft, 400,
+                    secondInterpolator);
+            Animator third = getHandleAnimator(view, 0.97f, 1.02f, isLeft, 400,
+                    secondInterpolator);
+            Animator fourth = getHandleAnimator(view, 1.02f, 1f, isLeft, 400,
+                    secondInterpolator);
+            anim.play(first).before(second);
+            anim.play(second).before(third);
+            anim.play(third).before(fourth);
+            anim.start();
         } else {
             view.animate().cancel();
-            view.animate().setDuration(400).alpha(0f);
+            view.animate()
+                    .setInterpolator(new AccelerateInterpolator(1.5f))
+                    .setDuration(250)
+                    .alpha(0f);
         }
 
     }
@@ -199,6 +258,10 @@
             return;
         }
 
+        if (mOverlay == null || mBottomOverlay == null) {
+            return;
+        }
+
         if (mAssistHintVisible != visible) {
             mAssistHintVisible = visible;
 
@@ -228,6 +291,7 @@
                     break;
             }
         }
+        updateWindowVisibilities();
     }
 
     /**
@@ -241,7 +305,7 @@
 
         mAssistHintBlocked = blocked;
         if (mAssistHintVisible && mAssistHintBlocked) {
-            setAssistHintVisible(false);
+            hideAssistHandles();
         }
     }
 
@@ -252,11 +316,15 @@
         return thread.getThreadHandler();
     }
 
+    private boolean shouldHostHandles() {
+        return mInGesturalMode;
+    }
+
     private void startOnScreenDecorationsThread() {
         mRotation = RotationUtils.getExactRotation(mContext);
         mWindowManager = mContext.getSystemService(WindowManager.class);
         updateRoundedCornerRadii();
-        if (hasRoundedCorners() || shouldDrawCutout()) {
+        if (hasRoundedCorners() || shouldDrawCutout() || shouldHostHandles()) {
             setupDecorations();
         }
 
@@ -561,7 +629,10 @@
         boolean visibleForCutout = shouldDrawCutout()
                 && overlay.findViewById(R.id.display_cutout).getVisibility() == View.VISIBLE;
         boolean visibleForRoundedCorners = hasRoundedCorners();
-        overlay.setVisibility(visibleForCutout || visibleForRoundedCorners
+        boolean visibleForHandles = overlay.findViewById(R.id.assist_hint_left).getVisibility()
+                == View.VISIBLE || overlay.findViewById(R.id.assist_hint_right).getVisibility()
+                == View.VISIBLE;
+        overlay.setVisibility(visibleForCutout || visibleForRoundedCorners || visibleForHandles
                 ? View.VISIBLE : View.GONE);
     }
 
@@ -684,10 +755,6 @@
                 setSize(mOverlay.findViewById(R.id.right), sizeTop);
                 setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom);
                 setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom);
-                setSize(mOverlay.findViewById(R.id.assist_hint_left), sizeTop * 2);
-                setSize(mOverlay.findViewById(R.id.assist_hint_right), sizeTop * 2);
-                setSize(mBottomOverlay.findViewById(R.id.assist_hint_left), sizeBottom * 2);
-                setSize(mBottomOverlay.findViewById(R.id.assist_hint_right), sizeBottom * 2);
             }
         });
     }
@@ -701,6 +768,10 @@
 
     @Override
     public void onDarkIntensity(float darkIntensity) {
+        if (!mHandler.getLooper().isCurrentThread()) {
+            mHandler.post(() -> onDarkIntensity(darkIntensity));
+            return;
+        }
         if (mOverlay != null) {
             CornerHandleView assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
             CornerHandleView assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);
@@ -848,6 +919,7 @@
             if (shouldDrawCutout(getContext()) && hasCutout()) {
                 mBounds.addAll(mInfo.displayCutout.getBoundingRects());
                 localBounds(mBoundingRect);
+                updateGravity();
                 updateBoundingPath();
                 invalidate();
                 newVisible = VISIBLE;
@@ -898,6 +970,18 @@
             }
         }
 
+        private void updateGravity() {
+            LayoutParams lp = getLayoutParams();
+            if (lp instanceof FrameLayout.LayoutParams) {
+                FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) lp;
+                int newGravity = getGravity(mInfo.displayCutout);
+                if (flp.gravity != newGravity) {
+                    flp.gravity = newGravity;
+                    setLayoutParams(flp);
+                }
+            }
+        }
+
         private boolean hasCutout() {
             final DisplayCutout displayCutout = mInfo.displayCutout;
             if (displayCutout == null) {
@@ -944,21 +1028,25 @@
         }
 
         private void localBounds(Rect out) {
-            final DisplayCutout displayCutout = mInfo.displayCutout;
+            DisplayCutout displayCutout = mInfo.displayCutout;
+            boundsFromDirection(displayCutout, getGravity(displayCutout), out);
+        }
 
+        private int getGravity(DisplayCutout displayCutout) {
             if (mStart) {
                 if (displayCutout.getSafeInsetLeft() > 0) {
-                    boundsFromDirection(displayCutout, Gravity.LEFT, out);
+                    return Gravity.LEFT;
                 } else if (displayCutout.getSafeInsetTop() > 0) {
-                    boundsFromDirection(displayCutout, Gravity.TOP, out);
+                    return Gravity.TOP;
                 }
             } else {
                 if (displayCutout.getSafeInsetRight() > 0) {
-                    boundsFromDirection(displayCutout, Gravity.RIGHT, out);
+                    return Gravity.RIGHT;
                 } else if (displayCutout.getSafeInsetBottom() > 0) {
-                    boundsFromDirection(displayCutout, Gravity.BOTTOM, out);
+                    return Gravity.BOTTOM;
                 }
             }
+            return Gravity.NO_GRAVITY;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/ServiceBinder.java b/packages/SystemUI/src/com/android/systemui/ServiceBinder.java
new file mode 100644
index 0000000..6282c6e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ServiceBinder.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 com.android.systemui;
+
+import com.android.systemui.doze.DozeService;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
+
+/**
+ * Services and Activities that are injectable should go here.
+ */
+@Module
+public abstract class ServiceBinder {
+
+    @Binds
+    public abstract ContextComponentHelper bindComponentHelper(
+            ContextComponentResolver componentHelper);
+
+    @Binds
+    @IntoMap
+    @ClassKey(DozeService.class)
+    public abstract Object bindDozeService(DozeService service);
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 84e0238..58c52a1 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -34,7 +34,6 @@
 import android.view.ViewConfiguration;
 import android.view.accessibility.AccessibilityEvent;
 
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -98,7 +97,8 @@
 
     private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>();
 
-    public SwipeHelper(int swipeDirection, Callback callback, Context context) {
+    public SwipeHelper(
+            int swipeDirection, Callback callback, Context context, FalsingManager falsingManager) {
         mContext = context;
         mCallback = callback;
         mHandler = new Handler();
@@ -113,7 +113,7 @@
         mDensityScale =  res.getDisplayMetrics().density;
         mFalsingThreshold = res.getDimensionPixelSize(R.dimen.swipe_helper_falsing_threshold);
         mFadeDependingOnAmountSwiped = res.getBoolean(R.bool.config_fadeDependingOnAmountSwiped);
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = falsingManager;
         mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
new file mode 100644
index 0000000..00ae992
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+import android.app.Application;
+import android.app.Service;
+import android.content.Intent;
+
+import androidx.core.app.CoreComponentFactory;
+
+import javax.inject.Inject;
+
+/**
+ * Implementation of AppComponentFactory that injects into constructors.
+ */
+public class SystemUIAppComponentFactory extends CoreComponentFactory {
+
+    @Inject
+    public ContextComponentHelper mComponentHelper;
+
+    public SystemUIAppComponentFactory() {
+        super();
+    }
+
+    @Override
+    public Application instantiateApplication(ClassLoader cl, String className)
+            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        Application app = super.instantiateApplication(cl, className);
+        if (app instanceof SystemUIApplication) {
+            ((SystemUIApplication) app).setContextAvailableCallback(
+                    context -> {
+                        SystemUIFactory.createFromConfig(context);
+                        SystemUIFactory.getInstance().getRootComponent().inject(
+                                SystemUIAppComponentFactory.this);
+                    }
+            );
+        }
+
+        return app;
+    }
+
+    @Override
+    public Service instantiateService(ClassLoader cl, String className, Intent intent)
+            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        Service service = mComponentHelper.resolve(className);
+        if (service != null) {
+            return checkCompatWrapper(service);
+        }
+        return super.instantiateService(cl, className, intent);
+    }
+
+    static <T> T checkCompatWrapper(T obj) {
+        if (obj instanceof CompatWrapped) {
+            T wrapper = (T) ((CompatWrapped) obj).getWrapper();
+            if (wrapper != null) {
+                return wrapper;
+            }
+        }
+
+        return obj;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 61a0f72..f8449ad 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -37,6 +37,7 @@
 import com.android.systemui.plugins.OverlayPlugin;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.util.NotificationChannels;
@@ -59,16 +60,20 @@
     private boolean mServicesStarted;
     private boolean mBootCompleted;
     private final Map<Class<?>, Object> mComponents = new HashMap<>();
+    private ContextAvailableCallback mContextAvailableCallback;
 
     @Override
     public void onCreate() {
         super.onCreate();
+        // This line is used to setup Dagger's dependency injection and should be kept at the
+        // top of this method.
+        mContextAvailableCallback.onContextAvailable(this);
+
         // Set the application theme that is inherited by all services. Note that setting the
         // application theme in the manifest does only work for activities. Keep this in sync with
         // the theme set there.
         setTheme(R.style.Theme_SystemUI);
 
-        SystemUIFactory.createFromConfig(this);
 
         if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
             IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
@@ -215,7 +220,8 @@
                                 StatusBar statusBar = getComponent(StatusBar.class);
                                 if (statusBar != null) {
                                     plugin.setup(statusBar.getStatusBarWindow(),
-                                            statusBar.getNavigationBarView(), new Callback(plugin));
+                                            statusBar.getNavigationBarView(), new Callback(plugin),
+                                            DozeParameters.getInstance(getBaseContext()));
                                 }
                             }
                         });
@@ -284,4 +290,12 @@
     public SystemUI[] getServices() {
         return mServices;
     }
+
+    void setContextAvailableCallback(ContextAvailableCallback callback) {
+        mContextAvailableCallback = callback;
+    }
+
+    interface ContextAvailableCallback {
+        void onContextAvailable(Context context);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index ed07196..311ed8a 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -19,26 +19,25 @@
 import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
 import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
 
-import android.annotation.Nullable;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Log;
 import android.view.ViewGroup;
 
-
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.util.function.TriConsumer;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.assist.AssistManager;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.dock.DockManager;
-import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.EnhancedEstimatesImpl;
@@ -50,10 +49,13 @@
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.NotificationData;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
+import com.android.systemui.statusbar.phone.KeyguardLiftController;
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
@@ -62,9 +64,9 @@
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.UnlockMethodCache;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.util.InjectionInflationController;
-import com.android.systemui.util.leak.GarbageMonitor;
+import com.android.systemui.util.AsyncSensorManager;
 import com.android.systemui.volume.VolumeDialogComponent;
 
 import java.util.function.Consumer;
@@ -72,7 +74,6 @@
 import javax.inject.Named;
 import javax.inject.Singleton;
 
-import dagger.Component;
 import dagger.Module;
 import dagger.Provides;
 
@@ -110,7 +111,7 @@
     public SystemUIFactory() {}
 
     protected void init(Context context) {
-        initWithRootComponent(DaggerSystemUIFactory_SystemUIRootComponent.builder()
+        initWithRootComponent(DaggerSystemUIRootComponent.builder()
                 .systemUIFactory(this)
                 .dependencyProvider(new com.android.systemui.DependencyProvider())
                 .contextHolder(new ContextHolder(context))
@@ -137,11 +138,12 @@
     public KeyguardBouncer createKeyguardBouncer(Context context, ViewMediatorCallback callback,
             LockPatternUtils lockPatternUtils,  ViewGroup container,
             DismissCallbackRegistry dismissCallbackRegistry,
-            KeyguardBouncer.BouncerExpansionCallback expansionCallback) {
+            KeyguardBouncer.BouncerExpansionCallback expansionCallback,
+            FalsingManager falsingManager) {
         return new KeyguardBouncer(context, callback, lockPatternUtils, container,
-                dismissCallbackRegistry, FalsingManagerFactory.getInstance(context),
-                expansionCallback, KeyguardUpdateMonitor.getInstance(context),
-                new Handler(Looper.getMainLooper()));
+                dismissCallbackRegistry, falsingManager,
+                expansionCallback, UnlockMethodCache.getInstance(context),
+                KeyguardUpdateMonitor.getInstance(context), new Handler(Looper.getMainLooper()));
     }
 
     public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
@@ -154,10 +156,13 @@
     }
 
     public NotificationIconAreaController createNotificationIconAreaController(Context context,
-            StatusBar statusBar, StatusBarStateController statusBarStateController,
-            NotificationListener listener) {
+            StatusBar statusBar,
+            NotificationWakeUpCoordinator wakeUpCoordinator,
+            KeyguardBypassController keyguardBypassController,
+            StatusBarStateController statusBarStateController) {
         return new NotificationIconAreaController(context, statusBar, statusBarStateController,
-                listener, Dependency.get(NotificationMediaManager.class));
+                wakeUpCoordinator, keyguardBypassController,
+                Dependency.get(NotificationMediaManager.class));
     }
 
     public KeyguardIndicationController createKeyguardIndicationController(Context context,
@@ -218,6 +223,18 @@
 
     @Singleton
     @Provides
+    @Nullable
+    public KeyguardLiftController provideKeyguardLiftController(Context context,
+            StatusBarStateController statusBarStateController,
+            AsyncSensorManager asyncSensorManager) {
+        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
+            return null;
+        }
+        return new KeyguardLiftController(context, statusBarStateController, asyncSensorManager);
+    }
+
+    @Singleton
+    @Provides
     public NotificationListener provideNotificationListener(Context context) {
         return new NotificationListener(context);
     }
@@ -255,29 +272,4 @@
             return mContext;
         }
     }
-
-    @Singleton
-    @Component(modules = {SystemUIFactory.class, DependencyProvider.class, DependencyBinder.class,
-            ContextHolder.class})
-    public interface SystemUIRootComponent {
-        @Singleton
-        Dependency.DependencyInjector createDependency();
-
-        @Singleton
-        StatusBar.StatusBarInjector getStatusBarInjector();
-
-        /**
-         * FragmentCreator generates all Fragments that need injection.
-         */
-        @Singleton
-        FragmentService.FragmentCreator createFragmentCreator();
-
-        /**
-         * ViewCreator generates all Views that need injection.
-         */
-        InjectionInflationController.ViewCreator createViewCreator();
-
-        @Singleton
-        GarbageMonitor createGarbageMonitor();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
new file mode 100644
index 0000000..c732df3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.util.InjectionInflationController;
+import com.android.systemui.util.leak.GarbageMonitor;
+
+import javax.inject.Singleton;
+
+import dagger.Component;
+
+/**
+ * Root component for Dagger injection.
+ */
+@Singleton
+@Component(modules = {SystemUIFactory.class, DependencyProvider.class, DependencyBinder.class,
+        ServiceBinder.class, SystemUIFactory.ContextHolder.class})
+public interface SystemUIRootComponent {
+    /**
+     * Main dependency providing module.
+     */
+    @Singleton
+    Dependency.DependencyInjector createDependency();
+
+    /**
+     * Injects the StatusBar.
+     */
+    @Singleton
+    StatusBar.StatusBarInjector getStatusBarInjector();
+
+    /**
+     * FragmentCreator generates all Fragments that need injection.
+     */
+    @Singleton
+    FragmentService.FragmentCreator createFragmentCreator();
+
+    /**
+     * ViewCreator generates all Views that need injection.
+     */
+    InjectionInflationController.ViewCreator createViewCreator();
+
+    /**
+     * Creatse a GarbageMonitor.
+     */
+    @Singleton
+    GarbageMonitor createGarbageMonitor();
+
+    /**
+     * Injects into the supplied argument.
+     */
+    void inject(SystemUIAppComponentFactory factory);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index 3fc6689..858ed6d 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -62,6 +62,8 @@
     private H mBGHandler;
     private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>();
     private final ArrayMap<Integer, Set<Callback>> mCallbacksByCode = new ArrayMap<>();
+    private final PermissionFlagsCache mFlagsCache;
+    private boolean mListening;
 
     @GuardedBy("mActiveItems")
     private final List<AppOpItem> mActiveItems = new ArrayList<>();
@@ -78,8 +80,14 @@
 
     @Inject
     public AppOpsControllerImpl(Context context, @Named(BG_LOOPER_NAME) Looper bgLooper) {
+        this(context, bgLooper, new PermissionFlagsCache(context));
+    }
+
+    @VisibleForTesting
+    protected AppOpsControllerImpl(Context context, Looper bgLooper, PermissionFlagsCache cache) {
         mContext = context;
         mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        mFlagsCache = cache;
         mBGHandler = new H(bgLooper);
         final int numOps = OPS.length;
         for (int i = 0; i < numOps; i++) {
@@ -94,12 +102,20 @@
 
     @VisibleForTesting
     protected void setListening(boolean listening) {
+        mListening = listening;
         if (listening) {
             mAppOps.startWatchingActive(OPS, this);
             mAppOps.startWatchingNoted(OPS, this);
         } else {
             mAppOps.stopWatchingActive(this);
             mAppOps.stopWatchingNoted(this);
+            mBGHandler.removeCallbacksAndMessages(null); // null removes all
+            synchronized (mActiveItems) {
+                mActiveItems.clear();
+            }
+            synchronized (mNotedItems) {
+                mNotedItems.clear();
+            }
         }
     }
 
@@ -218,7 +234,7 @@
         if (permission == null) {
             return false;
         }
-        int permFlags = mContext.getPackageManager().getPermissionFlags(permission,
+        int permFlags = mFlagsCache.getPermissionFlags(permission,
                 packageName, UserHandle.getUserHandleForUid(uid));
         return (permFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0;
     }
@@ -301,7 +317,7 @@
     @Override
     public void onOpActiveChanged(int code, int uid, String packageName, boolean active) {
         if (updateActives(code, uid, packageName, active)) {
-            notifySuscribers(code, uid, packageName, active);
+            mBGHandler.post(() -> notifySuscribers(code, uid, packageName, active));
         }
     }
 
@@ -312,7 +328,7 @@
         }
         if (result != AppOpsManager.MODE_ALLOWED) return;
         addNoted(code, uid, packageName);
-        notifySuscribers(code, uid, packageName, true);
+        mBGHandler.post(() -> notifySuscribers(code, uid, packageName, true));
     }
 
     private void notifySuscribers(int code, int uid, String packageName, boolean active) {
@@ -327,6 +343,7 @@
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("AppOpsController state:");
+        pw.println("  Listening: " + mListening);
         pw.println("  Active Items:");
         for (int i = 0; i < mActiveItems.size(); i++) {
             final AppOpItem item = mActiveItems.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/appops/PermissionFlagsCache.kt b/packages/SystemUI/src/com/android/systemui/appops/PermissionFlagsCache.kt
new file mode 100644
index 0000000..f02c7af
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/appops/PermissionFlagsCache.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appops
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.UserHandle
+import android.util.ArrayMap
+import com.android.internal.annotations.VisibleForTesting
+
+private data class PermissionFlag(val flag: Int, val timestamp: Long)
+
+private data class PermissionFlagKey(
+    val permission: String,
+    val packageName: String,
+    val user: UserHandle
+)
+
+internal const val CACHE_EXPIRATION = 10000L
+
+/**
+ * Cache for PackageManager's PermissionFlags.
+ *
+ * Flags older than [CACHE_EXPIRATION] will be retrieved again.
+ */
+internal open class PermissionFlagsCache(context: Context) {
+    private val packageManager = context.packageManager
+    private val permissionFlagsCache = ArrayMap<PermissionFlagKey, PermissionFlag>()
+
+    /**
+     * Retrieve permission flags from cache or PackageManager. There parameters will be passed
+     * directly to [PackageManager].
+     *
+     * Calls to this method should be done from a background thread.
+     */
+    fun getPermissionFlags(permission: String, packageName: String, user: UserHandle): Int {
+        val key = PermissionFlagKey(permission, packageName, user)
+        val now = getCurrentTime()
+        val value = permissionFlagsCache.getOrPut(key) {
+            PermissionFlag(getFlags(key), now)
+        }
+        if (now - value.timestamp > CACHE_EXPIRATION) {
+            val newValue = PermissionFlag(getFlags(key), now)
+            permissionFlagsCache.put(key, newValue)
+            return newValue.flag
+        } else {
+            return value.flag
+        }
+    }
+
+    private fun getFlags(key: PermissionFlagKey) =
+            packageManager.getPermissionFlags(key.permission, key.packageName, key.user)
+
+    @VisibleForTesting
+    protected open fun getCurrentTime() = System.currentTimeMillis()
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
index 01deb03..002d4f3 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.provider.DeviceConfig;
 import android.util.Log;
 
 import androidx.annotation.Nullable;
@@ -30,11 +29,15 @@
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.Dependency;
+import com.android.systemui.DumpController;
+import com.android.systemui.Dumpable;
 import com.android.systemui.ScreenDecorations;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.phone.NavigationModeController;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.EnumMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
@@ -46,11 +49,11 @@
  * Controls when visual handles for Assistant gesture affordance should be shown or hidden using an
  * {@link AssistHandleBehavior}.
  */
-public final class AssistHandleBehaviorController implements AssistHandleCallbacks {
+public final class AssistHandleBehaviorController implements AssistHandleCallbacks, Dumpable {
 
     private static final String TAG = "AssistHandleBehavior";
 
-    private static final long DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(10);
+    private static final long DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS = 0;
     private static final long DEFAULT_SHOW_AND_GO_DURATION_MS = TimeUnit.SECONDS.toMillis(3);
 
     /**
@@ -63,7 +66,9 @@
     private final AssistUtils mAssistUtils;
     private final Handler mHandler;
     private final Runnable mHideHandles = this::hideHandles;
+    private final Runnable mShowAndGo = this::showAndGoInternal;
     private final Supplier<ScreenDecorations> mScreenDecorationsSupplier;
+    private final PhenotypeHelper mPhenotypeHelper;
     private final Map<AssistHandleBehavior, BehaviorController> mBehaviorMap =
             new EnumMap<>(AssistHandleBehavior.class);
 
@@ -80,7 +85,9 @@
         this(
                 context,
                 assistUtils,
-                handler, () -> SysUiServiceProvider.getComponent(context, ScreenDecorations.class),
+                handler,
+                () -> SysUiServiceProvider.getComponent(context, ScreenDecorations.class),
+                new PhenotypeHelper(),
                 /* testBehavior = */ null);
     }
 
@@ -90,15 +97,18 @@
             AssistUtils assistUtils,
             Handler handler,
             Supplier<ScreenDecorations> screenDecorationsSupplier,
+            PhenotypeHelper phenotypeHelper,
             @Nullable BehaviorController testBehavior) {
         mContext = context;
         mAssistUtils = assistUtils;
         mHandler = handler;
         mScreenDecorationsSupplier = screenDecorationsSupplier;
-
+        mPhenotypeHelper = phenotypeHelper;
         mBehaviorMap.put(AssistHandleBehavior.OFF, new AssistHandleOffBehavior());
         mBehaviorMap.put(AssistHandleBehavior.LIKE_HOME, new AssistHandleLikeHomeBehavior());
-        mBehaviorMap.put(AssistHandleBehavior.REMINDER_EXP, new AssistHandleReminderExpBehavior());
+        mBehaviorMap.put(
+                AssistHandleBehavior.REMINDER_EXP,
+                new AssistHandleReminderExpBehavior(handler, phenotypeHelper));
         if (testBehavior != null) {
             mBehaviorMap.put(AssistHandleBehavior.TEST, testBehavior);
         }
@@ -107,41 +117,55 @@
                 Dependency.get(NavigationModeController.class)
                         .addListener(this::handleNavigationModeChange));
 
-        setBehavior(DeviceConfig.getString(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE,
-                DEFAULT_BEHAVIOR.toString()));
-        DeviceConfig.addOnPropertyChangedListener(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        setBehavior(getBehaviorMode());
+        mPhenotypeHelper.addOnPropertiesChangedListener(
                 mHandler::post,
-                (namespace, name, value) -> {
-                    if (SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE.equals(name)) {
-                        setBehavior(value);
+                (properties) -> {
+                    if (properties.getKeyset().contains(
+                            SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE)) {
+                        setBehavior(properties.getString(
+                                SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE, null));
                     }
                 });
+        Dependency.get(DumpController.class).addListener(this);
     }
 
-    @Override
+    @Override // AssistHandleCallbacks
     public void hide() {
-        mHandler.removeCallbacks(mHideHandles);
+        clearPendingCommands();
         mHandler.post(mHideHandles);
     }
 
-    @Override
+    @Override // AssistHandleCallbacks
     public void showAndGo() {
-        mHandler.removeCallbacks(mHideHandles);
-        mHandler.post(() -> {
-            maybeShowHandles(/* ignoreThreshold = */ false);
-            mHandler.postDelayed(mHideHandles, getShowAndGoDuration());
-        });
+        clearPendingCommands();
+        mHandler.post(mShowAndGo);
     }
 
-    @Override
+    private void showAndGoInternal() {
+        maybeShowHandles(/* ignoreThreshold = */ false);
+        mHandler.postDelayed(mHideHandles, getShowAndGoDuration());
+    }
+
+    @Override // AssistHandleCallbacks
+    public void showAndGoDelayed(long delayMs, boolean hideIfShowing) {
+        clearPendingCommands();
+        if (hideIfShowing) {
+            mHandler.post(mHideHandles);
+        }
+        mHandler.postDelayed(mShowAndGo, delayMs);
+    }
+
+    @Override // AssistHandleCallbacks
     public void showAndStay() {
-        mHandler.removeCallbacks(mHideHandles);
+        clearPendingCommands();
         mHandler.post(() -> maybeShowHandles(/* ignoreThreshold = */ true));
     }
 
+    boolean areHandlesShowing() {
+        return mHandlesShowing;
+    }
+
     void onAssistantGesturePerformed() {
         mBehaviorMap.get(mCurrentBehavior).onAssistantGesturePerformed();
     }
@@ -174,37 +198,41 @@
 
     private boolean handlesUnblocked(boolean ignoreThreshold) {
         long timeSinceHidden = SystemClock.elapsedRealtime() - mHandlesLastHiddenAt;
-        boolean notThrottled = ignoreThreshold || timeSinceHidden > getShownFrequencyThreshold();
+        boolean notThrottled = ignoreThreshold || timeSinceHidden >= getShownFrequencyThreshold();
         ComponentName assistantComponent =
                 mAssistUtils.getAssistComponentForUser(KeyguardUpdateMonitor.getCurrentUser());
         return notThrottled && assistantComponent != null;
     }
 
     private long getShownFrequencyThreshold() {
-        return DeviceConfig.getLong(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        return mPhenotypeHelper.getLong(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS,
                 DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS);
     }
 
     private long getShowAndGoDuration() {
-        return DeviceConfig.getLong(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        return mPhenotypeHelper.getLong(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS,
                 DEFAULT_SHOW_AND_GO_DURATION_MS);
     }
 
+    private String getBehaviorMode() {
+        return mPhenotypeHelper.getString(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE,
+                DEFAULT_BEHAVIOR.toString());
+    }
+
     private void maybeShowHandles(boolean ignoreThreshold) {
         if (mHandlesShowing) {
             return;
         }
 
         if (handlesUnblocked(ignoreThreshold)) {
-            mHandlesShowing = true;
             ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
             if (screenDecorations == null) {
                 Log.w(TAG, "Couldn't show handles, ScreenDecorations unavailable");
             } else {
+                mHandlesShowing = true;
                 screenDecorations.setAssistHintVisible(true);
             }
         }
@@ -215,12 +243,12 @@
             return;
         }
 
-        mHandlesShowing = false;
-        mHandlesLastHiddenAt = SystemClock.elapsedRealtime();
         ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
         if (screenDecorations == null) {
             Log.w(TAG, "Couldn't hide handles, ScreenDecorations unavailable");
         } else {
+            mHandlesShowing = false;
+            mHandlesLastHiddenAt = SystemClock.elapsedRealtime();
             screenDecorations.setAssistHintVisible(false);
         }
     }
@@ -240,14 +268,46 @@
         }
     }
 
+    private void clearPendingCommands() {
+        mHandler.removeCallbacks(mHideHandles);
+        mHandler.removeCallbacks(mShowAndGo);
+    }
+
     @VisibleForTesting
     void setInGesturalModeForTest(boolean inGesturalMode) {
         mInGesturalMode = inGesturalMode;
     }
 
+    @Override // Dumpable
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Current AssistHandleBehaviorController State:");
+
+        pw.println("   mHandlesShowing=" + mHandlesShowing);
+        pw.println("   mHandlesLastHiddenAt=" + mHandlesLastHiddenAt);
+        pw.println("   mInGesturalMode=" + mInGesturalMode);
+
+        pw.println("   Phenotype Flags:");
+        pw.println("      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS
+                + "="
+                + getShowAndGoDuration());
+        pw.println("      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS
+                + "="
+                + getShownFrequencyThreshold());
+        pw.println("      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE
+                + "="
+                + getBehaviorMode());
+
+        pw.println("   mCurrentBehavior=" + mCurrentBehavior.toString());
+        mBehaviorMap.get(mCurrentBehavior).dump(pw, "   ");
+    }
+
     interface BehaviorController {
         void onModeActivated(Context context, AssistHandleCallbacks callbacks);
         default void onModeDeactivated() {}
         default void onAssistantGesturePerformed() {}
+        default void dump(PrintWriter pw, String prefix) {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleCallbacks.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleCallbacks.java
index 0577d37..3db861d 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleCallbacks.java
@@ -29,6 +29,13 @@
      */
     void showAndGo();
 
+    /**
+     * Same as show and go, but will not do anything until a delay has elapsed.
+     *
+     * Will be cancelled if another command is given during the delay.
+     */
+    void showAndGoDelayed(long delayMs, boolean hideIfShowing);
+
     /** Show the Assistant handles. */
     void showAndStay();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
index 05e504c..6cf2034 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java
@@ -26,6 +26,8 @@
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.system.QuickStepContract;
 
+import java.io.PrintWriter;
+
 /**
  * Assistant Handle behavior that makes Assistant handles show/hide when the home handle is
  * shown/hidden, respectively.
@@ -108,4 +110,12 @@
             mAssistHandleCallbacks.showAndStay();
         }
     }
+
+    @Override
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println("Current AssistHandleLikeHomeBehavior State:");
+
+        pw.println(prefix + "   mIsDozing=" + mIsDozing);
+        pw.println(prefix + "   mIsHomeHandleHiding=" + mIsHomeHandleHiding);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
index 4b6a6dc..f9ddeae 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
@@ -17,10 +17,14 @@
 package com.android.systemui.assist;
 
 import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
+import android.os.Handler;
 import android.os.SystemClock;
-import android.provider.DeviceConfig;
 import android.provider.Settings;
 
 import androidx.annotation.Nullable;
@@ -31,10 +35,15 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.PackageManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.StatusBarState;
 
+import java.io.PrintWriter;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -46,8 +55,27 @@
 
     private static final String LEARNING_TIME_ELAPSED_KEY = "reminder_exp_learning_time_elapsed";
     private static final String LEARNING_EVENT_COUNT_KEY = "reminder_exp_learning_event_count";
-    private static final long DEFAULT_LEARNING_TIME_MS = TimeUnit.DAYS.toMillis(3);
-    private static final int DEFAULT_LEARNING_COUNT = 3;
+    private static final String LEARNED_HINT_LAST_SHOWN_KEY =
+            "reminder_exp_learned_hint_last_shown";
+    private static final long DEFAULT_LEARNING_TIME_MS = TimeUnit.DAYS.toMillis(10);
+    private static final int DEFAULT_LEARNING_COUNT = 10;
+    private static final long DEFAULT_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS = 150;
+    private static final long DEFAULT_SHOW_AND_GO_DELAYED_LONG_DELAY_MS =
+            TimeUnit.SECONDS.toMillis(1);
+    private static final long DEFAULT_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS =
+            TimeUnit.SECONDS.toMillis(3);
+    private static final boolean DEFAULT_SUPPRESS_ON_LOCKSCREEN = false;
+    private static final boolean DEFAULT_SUPPRESS_ON_LAUNCHER = false;
+    private static final boolean DEFAULT_SUPPRESS_ON_APPS = true;
+    private static final boolean DEFAULT_SHOW_WHEN_TAUGHT = false;
+
+    private static final String[] DEFAULT_HOME_CHANGE_ACTIONS = new String[] {
+            PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED,
+            Intent.ACTION_BOOT_COMPLETED,
+            Intent.ACTION_PACKAGE_ADDED,
+            Intent.ACTION_PACKAGE_CHANGED,
+            Intent.ACTION_PACKAGE_REMOVED
+    };
 
     private final StatusBarStateController.StateListener mStatusBarStateListener =
             new StatusBarStateController.StateListener() {
@@ -64,13 +92,13 @@
     private final TaskStackChangeListener mTaskStackChangeListener =
             new TaskStackChangeListener() {
                 @Override
-                public void onTaskMovedToFront(int taskId) {
-                    handleTaskStackTopChanged(taskId);
+                public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo) {
+                    handleTaskStackTopChanged(taskInfo.taskId, taskInfo.topActivity);
                 }
 
                 @Override
                 public void onTaskCreated(int taskId, ComponentName componentName) {
-                    handleTaskStackTopChanged(taskId);
+                    handleTaskStackTopChanged(taskId, componentName);
                 }
             };
     private final OverviewProxyService.OverviewProxyListener mOverviewProxyListener =
@@ -85,7 +113,17 @@
                     handleSystemUiStateChanged(sysuiStateFlags);
                 }
             };
+    private final BroadcastReceiver mDefaultHomeBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mDefaultHome = getCurrentDefaultHome();
+        }
+    };
+    private final IntentFilter mDefaultHomeIntentFilter;
+    private final Runnable mResetConsecutiveTaskSwitches = this::resetConsecutiveTaskSwitches;
 
+    private final Handler mHandler;
+    private final PhenotypeHelper mPhenotypeHelper;
     private final StatusBarStateController mStatusBarStateController;
     private final ActivityManagerWrapper mActivityManagerWrapper;
     private final OverviewProxyService mOverviewProxyService;
@@ -94,6 +132,8 @@
     private boolean mIsDozing;
     private int mRunningTaskId;
     private boolean mIsNavBarHidden;
+    private boolean mIsLauncherShowing;
+    private int mConsecutiveTaskSwitches;
 
     /** Whether user has learned the gesture. */
     private boolean mIsLearned;
@@ -102,20 +142,31 @@
     private long mLearningTimeElapsed;
     /** Number of successful Assistant invocations while in this behavior. */
     private int mLearningCount;
+    private long mLearnedHintLastShownEpochDay;
 
     @Nullable private Context mContext;
     @Nullable private AssistHandleCallbacks mAssistHandleCallbacks;
+    @Nullable private ComponentName mDefaultHome;
 
-    AssistHandleReminderExpBehavior() {
+    AssistHandleReminderExpBehavior(Handler handler, PhenotypeHelper phenotypeHelper) {
+        mHandler = handler;
+        mPhenotypeHelper = phenotypeHelper;
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
         mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
         mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+        mDefaultHomeIntentFilter = new IntentFilter();
+        for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
+            mDefaultHomeIntentFilter.addAction(action);
+        }
     }
 
     @Override
     public void onModeActivated(Context context, AssistHandleCallbacks callbacks) {
         mContext = context;
         mAssistHandleCallbacks = callbacks;
+        mConsecutiveTaskSwitches = 0;
+        mDefaultHome = getCurrentDefaultHome();
+        context.registerReceiver(mDefaultHomeBroadcastReceiver, mDefaultHomeIntentFilter);
         mOnLockscreen = onLockscreen(mStatusBarStateController.getState());
         mIsDozing = mStatusBarStateController.isDozing();
         mStatusBarStateController.addCallback(mStatusBarStateListener);
@@ -128,6 +179,8 @@
                 context.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, /* default = */ 0);
         mLearningCount = Settings.Secure.getInt(
                 context.getContentResolver(), LEARNING_EVENT_COUNT_KEY, /* default = */ 0);
+        mLearnedHintLastShownEpochDay = Settings.Secure.getLong(
+                context.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, /* default = */ 0);
         mLastLearningTimestamp = SystemClock.uptimeMillis();
 
         callbackForCurrentState(/* justUnlocked = */ false);
@@ -137,10 +190,10 @@
     public void onModeDeactivated() {
         mAssistHandleCallbacks = null;
         if (mContext != null) {
-            Settings.Secure.putLong(
-                    mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed);
-            Settings.Secure.putInt(
-                    mContext.getContentResolver(), LEARNING_EVENT_COUNT_KEY, mLearningCount);
+            mContext.unregisterReceiver(mDefaultHomeBroadcastReceiver);
+            Settings.Secure.putLong(mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, 0);
+            Settings.Secure.putInt(mContext.getContentResolver(), LEARNING_EVENT_COUNT_KEY, 0);
+            Settings.Secure.putLong(mContext.getContentResolver(), LEARNED_HINT_LAST_SHOWN_KEY, 0);
             mContext = null;
         }
         mStatusBarStateController.removeCallback(mStatusBarStateListener);
@@ -162,12 +215,35 @@
         return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
     }
 
+    @Nullable
+    private static ComponentName getCurrentDefaultHome() {
+        List<ResolveInfo> homeActivities = new ArrayList<>();
+        ComponentName defaultHome =
+                PackageManagerWrapper.getInstance().getHomeActivities(homeActivities);
+        if (defaultHome != null) {
+            return defaultHome;
+        }
+
+        int topPriority = Integer.MIN_VALUE;
+        ComponentName topComponent = null;
+        for (ResolveInfo resolveInfo : homeActivities) {
+            if (resolveInfo.priority > topPriority) {
+                topComponent = resolveInfo.activityInfo.getComponentName();
+                topPriority = resolveInfo.priority;
+            } else if (resolveInfo.priority == topPriority) {
+                topComponent = null;
+            }
+        }
+        return topComponent;
+    }
+
     private void handleStatusBarStateChanged(int newState) {
         boolean onLockscreen = onLockscreen(newState);
         if (mOnLockscreen == onLockscreen) {
             return;
         }
 
+        resetConsecutiveTaskSwitches();
         mOnLockscreen = onLockscreen;
         callbackForCurrentState(!onLockscreen);
     }
@@ -177,16 +253,24 @@
             return;
         }
 
+        resetConsecutiveTaskSwitches();
         mIsDozing = isDozing;
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
-    private void handleTaskStackTopChanged(int taskId) {
-        if (mRunningTaskId == taskId) {
+    private void handleTaskStackTopChanged(int taskId, @Nullable ComponentName taskComponentName) {
+        if (mRunningTaskId == taskId || taskComponentName == null) {
             return;
         }
 
         mRunningTaskId = taskId;
+        mIsLauncherShowing = taskComponentName.equals(mDefaultHome);
+        if (mIsLauncherShowing) {
+            resetConsecutiveTaskSwitches();
+        } else {
+            rescheduleConsecutiveTaskSwitchesReset();
+            mConsecutiveTaskSwitches++;
+        }
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
@@ -196,11 +280,13 @@
             return;
         }
 
+        resetConsecutiveTaskSwitches();
         mIsNavBarHidden = isNavBarHidden;
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
     private void handleOverviewShown() {
+        resetConsecutiveTaskSwitches();
         callbackForCurrentState(/* justUnlocked = */ false);
     }
 
@@ -224,10 +310,20 @@
             return;
         }
 
-        if (mIsDozing || mIsNavBarHidden || mOnLockscreen) {
+        if (mIsDozing || mIsNavBarHidden || mOnLockscreen || !getShowWhenTaught()) {
             mAssistHandleCallbacks.hide();
         } else if (justUnlocked) {
-            mAssistHandleCallbacks.showAndGo();
+            long currentEpochDay = LocalDate.now().toEpochDay();
+            if (mLearnedHintLastShownEpochDay < currentEpochDay) {
+                if (mContext != null) {
+                    Settings.Secure.putLong(
+                            mContext.getContentResolver(),
+                            LEARNED_HINT_LAST_SHOWN_KEY,
+                            currentEpochDay);
+                }
+                mLearnedHintLastShownEpochDay = currentEpochDay;
+                mAssistHandleCallbacks.showAndGo();
+            }
         }
     }
 
@@ -236,12 +332,28 @@
             return;
         }
 
-        if (mIsDozing || mIsNavBarHidden) {
+        if (mIsDozing || mIsNavBarHidden || isSuppressed()) {
             mAssistHandleCallbacks.hide();
         } else if (mOnLockscreen) {
             mAssistHandleCallbacks.showAndStay();
-        } else {
+        } else if (mIsLauncherShowing) {
             mAssistHandleCallbacks.showAndGo();
+        } else if (mConsecutiveTaskSwitches == 1) {
+            mAssistHandleCallbacks.showAndGoDelayed(
+                    getShowAndGoDelayedShortDelayMs(), /* hideIfShowing = */ false);
+        } else {
+            mAssistHandleCallbacks.showAndGoDelayed(
+                    getShowAndGoDelayedLongDelayMs(), /* hideIfShowing = */ true);
+        }
+    }
+
+    private boolean isSuppressed() {
+        if (mOnLockscreen) {
+            return getSuppressOnLockscreen();
+        } else if (mIsLauncherShowing) {
+            return getSuppressOnLauncher();
+        } else {
+            return getSuppressOnApps();
         }
     }
 
@@ -260,17 +372,124 @@
                 mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs();
     }
 
+    private void resetConsecutiveTaskSwitches() {
+        mHandler.removeCallbacks(mResetConsecutiveTaskSwitches);
+        mConsecutiveTaskSwitches = 0;
+    }
+
+    private void rescheduleConsecutiveTaskSwitchesReset() {
+        mHandler.removeCallbacks(mResetConsecutiveTaskSwitches);
+        mHandler.postDelayed(mResetConsecutiveTaskSwitches, getShowAndGoDelayResetTimeoutMs());
+    }
+
     private long getLearningTimeMs() {
-        return DeviceConfig.getLong(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        return mPhenotypeHelper.getLong(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_TIME_MS,
                 DEFAULT_LEARNING_TIME_MS);
     }
 
     private int getLearningCount() {
-        return DeviceConfig.getInt(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
+        return mPhenotypeHelper.getInt(
                 SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_COUNT,
                 DEFAULT_LEARNING_COUNT);
     }
+
+    private long getShowAndGoDelayedShortDelayMs() {
+        return mPhenotypeHelper.getLong(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS,
+                DEFAULT_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS);
+    }
+
+    private long getShowAndGoDelayedLongDelayMs() {
+        return mPhenotypeHelper.getLong(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS,
+                DEFAULT_SHOW_AND_GO_DELAYED_LONG_DELAY_MS);
+    }
+
+    private long getShowAndGoDelayResetTimeoutMs() {
+        return mPhenotypeHelper.getLong(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS,
+                DEFAULT_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS);
+    }
+
+    private boolean getSuppressOnLockscreen() {
+        return mPhenotypeHelper.getBoolean(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN,
+                DEFAULT_SUPPRESS_ON_LOCKSCREEN);
+    }
+
+    private boolean getSuppressOnLauncher() {
+        return mPhenotypeHelper.getBoolean(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER,
+                DEFAULT_SUPPRESS_ON_LAUNCHER);
+    }
+
+    private boolean getSuppressOnApps() {
+        return mPhenotypeHelper.getBoolean(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_APPS,
+                DEFAULT_SUPPRESS_ON_APPS);
+    }
+
+    private boolean getShowWhenTaught() {
+        return mPhenotypeHelper.getBoolean(
+                SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_WHEN_TAUGHT,
+                DEFAULT_SHOW_WHEN_TAUGHT);
+    }
+
+    @Override
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "Current AssistHandleReminderExpBehavior State:");
+        pw.println(prefix + "   mOnLockscreen=" + mOnLockscreen);
+        pw.println(prefix + "   mIsDozing=" + mIsDozing);
+        pw.println(prefix + "   mRunningTaskId=" + mRunningTaskId);
+        pw.println(prefix + "   mDefaultHome=" + mDefaultHome);
+        pw.println(prefix + "   mIsNavBarHidden=" + mIsNavBarHidden);
+        pw.println(prefix + "   mIsLauncherShowing=" + mIsLauncherShowing);
+        pw.println(prefix + "   mConsecutiveTaskSwitches=" + mConsecutiveTaskSwitches);
+        pw.println(prefix + "   mIsLearned=" + mIsLearned);
+        pw.println(prefix + "   mLastLearningTimestamp=" + mLastLearningTimestamp);
+        pw.println(prefix + "   mLearningTimeElapsed=" + mLearningTimeElapsed);
+        pw.println(prefix + "   mLearningCount=" + mLearningCount);
+        pw.println(prefix + "   mLearnedHintLastShownEpochDay=" + mLearnedHintLastShownEpochDay);
+        pw.println(
+                prefix + "   mAssistHandleCallbacks present: " + (mAssistHandleCallbacks != null));
+
+        pw.println(prefix + "   Phenotype Flags:");
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_TIME_MS
+                + "="
+                + getLearningTimeMs());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_LEARN_COUNT
+                + "="
+                + getLearningCount());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_SHORT_DELAY_MS
+                + "="
+                + getShowAndGoDelayedShortDelayMs());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAYED_LONG_DELAY_MS
+                + "="
+                + getShowAndGoDelayedLongDelayMs());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DELAY_RESET_TIMEOUT_MS
+                + "="
+                + getShowAndGoDelayResetTimeoutMs());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LOCKSCREEN
+                + "="
+                + getSuppressOnLockscreen());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_LAUNCHER
+                + "="
+                + getSuppressOnLauncher());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SUPPRESS_ON_APPS
+                + "="
+                + getSuppressOnApps());
+        pw.println(prefix + "      "
+                + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_WHEN_TAUGHT
+                + "="
+                + getShowWhenTaught());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 2fc79d6..97b6e7c 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -104,6 +104,11 @@
     public static final int INVOCATION_TYPE_QUICK_SEARCH_BAR = 4;
     public static final int INVOCATION_HOME_BUTTON_LONG_PRESS = 5;
 
+    public static final int DISMISS_REASON_INVOCATION_CANCELLED = 1;
+    public static final int DISMISS_REASON_TAP = 2;
+    public static final int DISMISS_REASON_BACK = 3;
+    public static final int DISMISS_REASON_TIMEOUT = 4;
+
     private static final long TIMEOUT_SERVICE = 2500;
     private static final long TIMEOUT_ACTIVITY = 1000;
 
@@ -251,13 +256,10 @@
         if (invocationType == INVOCATION_TYPE_GESTURE) {
             mHandleController.onAssistantGesturePerformed();
         }
-        args.putInt(INVOCATION_PHONE_STATE_KEY, mPhoneStateMonitor.getPhoneState());
-        args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.uptimeMillis());
-        // Logs assistant start with invocation type.
-        MetricsLogger.action(
-                new LogMaker(MetricsEvent.ASSISTANT)
-                        .setType(MetricsEvent.TYPE_OPEN).setSubtype(
-                        invocationType));
+        int phoneState = mPhoneStateMonitor.getPhoneState();
+        args.putInt(INVOCATION_PHONE_STATE_KEY, phoneState);
+        args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.elapsedRealtime());
+        logStartAssist(invocationType, phoneState);
         startAssistInternal(args, assistComponent, isService);
     }
 
@@ -437,4 +439,26 @@
     public void onLockscreenShown() {
         mAssistUtils.onLockscreenShown();
     }
+
+    /** Returns the logging flags for the given Assistant invocation type. */
+    public int toLoggingSubType(int invocationType) {
+        return toLoggingSubType(invocationType, mPhoneStateMonitor.getPhoneState());
+    }
+
+    protected void logStartAssist(int invocationType, int phoneState) {
+        MetricsLogger.action(
+                new LogMaker(MetricsEvent.ASSISTANT)
+                        .setType(MetricsEvent.TYPE_OPEN)
+                        .setSubtype(toLoggingSubType(invocationType, phoneState)));
+    }
+
+    protected final int toLoggingSubType(int invocationType, int phoneState) {
+        // Note that this logic will break if the number of Assistant invocation types exceeds 7.
+        // There are currently 5 invocation types, but we will be migrating to the new logging
+        // framework in the next update.
+        int subType = mHandleController.areHandlesShowing() ? 0 : 1;
+        subType |= invocationType << 1;
+        subType |= phoneState << 4;
+        return subType;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
new file mode 100644
index 0000000..b3f57af
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.assist;
+
+import android.provider.DeviceConfig;
+
+import androidx.annotation.Nullable;
+
+import java.util.concurrent.Executor;
+
+public class PhenotypeHelper {
+
+    public PhenotypeHelper() {}
+
+    public long getLong(String name, long defaultValue) {
+        return DeviceConfig.getLong(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+    }
+
+    public int getInt(String name, int defaultValue) {
+        return DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+    }
+
+    @Nullable
+    public String getString(String name, @Nullable String defaultValue) {
+        return DeviceConfig.getString(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+    }
+
+    public boolean getBoolean(String name, boolean defaultValue) {
+        return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
+    }
+
+    public void addOnPropertiesChangedListener(
+            Executor executor, DeviceConfig.OnPropertiesChangedListener listener) {
+        DeviceConfig.addOnPropertiesChangedListener(
+                DeviceConfig.NAMESPACE_SYSTEMUI, executor, listener);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
index 1fd3089..e73dc4a 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
@@ -16,8 +16,6 @@
 
 package com.android.systemui.assist;
 
-import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
-
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.content.BroadcastReceiver;
@@ -25,6 +23,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
 
 import androidx.annotation.Nullable;
 
@@ -38,6 +37,7 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /** Class to monitor and report the state of the phone. */
 final class PhoneStateMonitor {
@@ -53,6 +53,14 @@
     private static final int PHONE_STATE_APP_IMMERSIVE = 9;
     private static final int PHONE_STATE_APP_FULLSCREEN = 10;
 
+    private static final String[] DEFAULT_HOME_CHANGE_ACTIONS = new String[] {
+            PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED,
+            Intent.ACTION_BOOT_COMPLETED,
+            Intent.ACTION_PACKAGE_ADDED,
+            Intent.ACTION_PACKAGE_CHANGED,
+            Intent.ACTION_PACKAGE_REMOVED
+    };
+
     private final Context mContext;
     private final StatusBarStateController mStatusBarStateController;
 
@@ -64,14 +72,17 @@
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
 
         ActivityManagerWrapper activityManagerWrapper = ActivityManagerWrapper.getInstance();
-        mDefaultHome = PackageManagerWrapper.getInstance().getHomeActivities(new ArrayList<>());
+        mDefaultHome = getCurrentDefaultHome();
+        IntentFilter intentFilter = new IntentFilter();
+        for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
+            intentFilter.addAction(action);
+        }
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                mDefaultHome =
-                        PackageManagerWrapper.getInstance().getHomeActivities(new ArrayList<>());
+                mDefaultHome = getCurrentDefaultHome();
             }
-        }, new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED));
+        }, intentFilter);
         mLauncherShowing = isLauncherShowing(activityManagerWrapper.getRunningTask());
         activityManagerWrapper.registerTaskStackListener(new TaskStackChangeListener() {
             @Override
@@ -93,6 +104,28 @@
         return phoneState;
     }
 
+    @Nullable
+    private static ComponentName getCurrentDefaultHome() {
+        List<ResolveInfo> homeActivities = new ArrayList<>();
+        ComponentName defaultHome =
+                PackageManagerWrapper.getInstance().getHomeActivities(homeActivities);
+        if (defaultHome != null) {
+            return defaultHome;
+        }
+
+        int topPriority = Integer.MIN_VALUE;
+        ComponentName topComponent = null;
+        for (ResolveInfo resolveInfo : homeActivities) {
+            if (resolveInfo.priority > topPriority) {
+                topComponent = resolveInfo.activityInfo.getComponentName();
+                topPriority = resolveInfo.priority;
+            } else if (resolveInfo.priority == topPriority) {
+                topComponent = null;
+            }
+        }
+        return topComponent;
+    }
+
     private int getPhoneLockscreenState() {
         if (isDozing()) {
             return PHONE_STATE_AOD1;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/CircularCornerPathRenderer.java b/packages/SystemUI/src/com/android/systemui/assist/ui/CircularCornerPathRenderer.java
index 162e09e..e61e47a 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/CircularCornerPathRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/CircularCornerPathRenderer.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.assist.ui;
 
+import android.content.Context;
 import android.graphics.Path;
 
 /**
@@ -29,12 +30,11 @@
     private final int mWidth;
     private final Path mPath = new Path();
 
-    public CircularCornerPathRenderer(int cornerRadiusBottom, int cornerRadiusTop,
-            int width, int height) {
-        mCornerRadiusBottom = cornerRadiusBottom;
-        mCornerRadiusTop = cornerRadiusTop;
-        mHeight = height;
-        mWidth = width;
+    public CircularCornerPathRenderer(Context context) {
+        mCornerRadiusBottom = DisplayUtils.getCornerRadiusBottom(context);
+        mCornerRadiusTop = DisplayUtils.getCornerRadiusTop(context);
+        mHeight = DisplayUtils.getHeight(context);
+        mWidth = DisplayUtils.getWidth(context);
     }
 
     @Override // CornerPathRenderer
@@ -53,11 +53,12 @@
                 break;
             case TOP_RIGHT:
                 mPath.moveTo(mWidth, mCornerRadiusTop);
-                mPath.arcTo(mWidth - mCornerRadiusTop, 0, mWidth, mCornerRadiusTop, 0, -90, true);
+                mPath.arcTo(mWidth - mCornerRadiusTop * 2, 0, mWidth, mCornerRadiusTop * 2, 0, -90,
+                        true);
                 break;
             case TOP_LEFT:
                 mPath.moveTo(mCornerRadiusTop, 0);
-                mPath.arcTo(0, 0, mCornerRadiusTop, mCornerRadiusTop, 270, -90, true);
+                mPath.arcTo(0, 0, mCornerRadiusTop * 2, mCornerRadiusTop * 2, 270, -90, true);
                 break;
         }
         return mPath;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
index b1be811..662de3a 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
@@ -16,10 +16,11 @@
 
 package com.android.systemui.assist.ui;
 
+import static com.android.systemui.assist.AssistManager.DISMISS_REASON_INVOCATION_CANCELLED;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
-import android.annotation.ColorInt;
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.metrics.LogMaker;
@@ -50,6 +51,7 @@
     private static final long ANIM_DURATION_MS = 200;
 
     protected final FrameLayout mRoot;
+    protected InvocationLightsView mInvocationLightsView;
 
     private final WindowManager mWindowManager;
     private final WindowManager.LayoutParams mLayoutParams;
@@ -60,7 +62,6 @@
     private float mLastInvocationProgress = 0;
 
     private ValueAnimator mInvocationAnimator = new ValueAnimator();
-    private InvocationLightsView mInvocationLightsView;
 
     public DefaultUiController(Context context) {
         mRoot = new FrameLayout(context);
@@ -91,6 +92,8 @@
 
     @Override // AssistManager.UiController
     public void onInvocationProgress(int type, float progress) {
+        boolean invocationWasInProgress = mInvocationInProgress;
+
         if (progress == 1) {
             animateInvocationCompletion(type, 0);
         } else if (progress == 0) {
@@ -105,16 +108,7 @@
         }
         mLastInvocationProgress = progress;
 
-        // Logs assistant invocation start.
-        if (!mInvocationInProgress && progress > 0.f) {
-            MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
-                    .setType(MetricsEvent.TYPE_ACTION));
-        }
-        // Logs assistant invocation cancelled.
-        if (mInvocationInProgress && progress == 0f) {
-            MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
-                    .setType(MetricsEvent.TYPE_DISMISS).setSubtype(0));
-        }
+        logInvocationProgressMetrics(type, progress, invocationWasInProgress);
     }
 
     @Override // AssistManager.UiController
@@ -134,12 +128,20 @@
         updateAssistHandleVisibility();
     }
 
-    /**
-     * Sets the colors of the four invocation lights, from left to right.
-     */
-    public void setInvocationColors(@ColorInt int color1, @ColorInt int color2,
-            @ColorInt int color3, @ColorInt int color4) {
-        mInvocationLightsView.setColors(color1, color2, color3, color4);
+    protected static void logInvocationProgressMetrics(
+            int type, float progress, boolean invocationWasInProgress) {
+        // Logs assistant invocation start.
+        if (!invocationWasInProgress && progress > 0.f) {
+            MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
+                    .setType(MetricsEvent.TYPE_ACTION)
+                    .setSubtype(Dependency.get(AssistManager.class).toLoggingSubType(type)));
+        }
+        // Logs assistant invocation cancelled.
+        if (invocationWasInProgress && progress == 0f) {
+            MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
+                    .setType(MetricsEvent.TYPE_DISMISS)
+                    .setSubtype(DISMISS_REASON_INVOCATION_CANCELLED));
+        }
     }
 
     private void updateAssistHandleVisibility() {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index de1d7c8..bc782a7 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -16,24 +16,34 @@
 
 package com.android.systemui.assist.ui;
 
+import android.animation.ArgbEvaluator;
 import android.annotation.ColorInt;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.MathUtils;
+import android.view.ContextThemeWrapper;
 import android.view.View;
 
+import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.phone.NavigationBarFragment;
+import com.android.systemui.statusbar.phone.NavigationBarTransitions;
 
 import java.util.ArrayList;
 
 /**
  * Shows lights at the bottom of the phone, marking the invocation progress.
  */
-public class InvocationLightsView extends View {
+public class InvocationLightsView extends View
+        implements NavigationBarTransitions.DarkIntensityListener {
 
     private static final String TAG = "InvocationLightsView";
 
@@ -49,9 +59,16 @@
     // allocation on each frame.
     private final Path mPath = new Path();
     private final int mViewHeight;
+    private final int mStrokeWidth;
+    @ColorInt
+    private final int mLightColor;
+    @ColorInt
+    private final int mDarkColor;
 
     // Allocate variable for screen location lookup to avoid memory alloc onDraw()
     private int[] mScreenLocation = new int[2];
+    private boolean mRegistered = false;
+    private boolean mUseNavBarColor = true;
 
     public InvocationLightsView(Context context) {
         this(context, null);
@@ -69,26 +86,31 @@
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
 
-        int strokeWidth = DisplayUtils.convertDpToPx(LIGHT_HEIGHT_DP, context);
-        mPaint.setStrokeWidth(strokeWidth);
+        mStrokeWidth = DisplayUtils.convertDpToPx(LIGHT_HEIGHT_DP, context);
+        mPaint.setStrokeWidth(mStrokeWidth);
         mPaint.setStyle(Paint.Style.STROKE);
         mPaint.setStrokeJoin(Paint.Join.MITER);
         mPaint.setAntiAlias(true);
 
-        int cornerRadiusBottom = DisplayUtils.getCornerRadiusBottom(context);
-        int cornerRadiusTop = DisplayUtils.getCornerRadiusTop(context);
+
         int displayWidth = DisplayUtils.getWidth(context);
         int displayHeight = DisplayUtils.getHeight(context);
-        CircularCornerPathRenderer cornerPathRenderer = new CircularCornerPathRenderer(
-                cornerRadiusBottom, cornerRadiusTop, displayWidth, displayHeight);
-        mGuide = new PerimeterPathGuide(context, cornerPathRenderer,
-                strokeWidth / 2, displayWidth, displayHeight);
+        mGuide = new PerimeterPathGuide(context, createCornerPathRenderer(context),
+                mStrokeWidth / 2, displayWidth, displayHeight);
 
+        int cornerRadiusBottom = DisplayUtils.getCornerRadiusBottom(context);
+        int cornerRadiusTop = DisplayUtils.getCornerRadiusTop(context);
         mViewHeight = Math.max(cornerRadiusBottom, cornerRadiusTop);
 
-        @ColorInt int lightColor = getResources().getColor(R.color.default_invocation_lights_color);
+        final int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
+        final int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
+        Context lightContext = new ContextThemeWrapper(mContext, dualToneLightTheme);
+        Context darkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme);
+        mLightColor = Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor);
+        mDarkColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
+
         for (int i = 0; i < 4; i++) {
-            mAssistInvocationLights.add(new EdgeLight(lightColor, 0, 0));
+            mAssistInvocationLights.add(new EdgeLight(Color.TRANSPARENT, 0, 0));
         }
     }
 
@@ -100,12 +122,14 @@
         if (progress == 0) {
             setVisibility(View.GONE);
         } else {
+            attemptRegisterNavBarListener();
+
             float cornerLengthNormalized =
                     mGuide.getRegionWidth(PerimeterPathGuide.Region.BOTTOM_LEFT);
             float arcLengthNormalized = cornerLengthNormalized * MINIMUM_CORNER_RATIO;
             float arcOffsetNormalized = (cornerLengthNormalized - arcLengthNormalized) / 2f;
 
-            float minLightLength = arcLengthNormalized / 2;
+            float minLightLength = 0;
             float maxLightLength = mGuide.getRegionWidth(PerimeterPathGuide.Region.BOTTOM) / 4f;
 
             float lightLength = MathUtils.lerp(minLightLength, maxLightLength, progress);
@@ -131,6 +155,21 @@
         for (EdgeLight light : mAssistInvocationLights) {
             light.setLength(0);
         }
+        attemptUnregisterNavBarListener();
+    }
+
+    /**
+     * Sets all invocation lights to a single color. If color is null, uses the navigation bar
+     * color (updated when the nav bar color changes).
+     */
+    public void setColors(@Nullable @ColorInt Integer color) {
+        if (color == null) {
+            mUseNavBarColor = true;
+            mPaint.setStrokeCap(Paint.Cap.BUTT);
+            attemptRegisterNavBarListener();
+        } else {
+            setColors(color, color, color, color);
+        }
     }
 
     /**
@@ -138,12 +177,25 @@
      */
     public void setColors(@ColorInt int color1, @ColorInt int color2,
             @ColorInt int color3, @ColorInt int color4) {
+        mUseNavBarColor = false;
+        attemptUnregisterNavBarListener();
         mAssistInvocationLights.get(0).setColor(color1);
         mAssistInvocationLights.get(1).setColor(color2);
         mAssistInvocationLights.get(2).setColor(color3);
         mAssistInvocationLights.get(3).setColor(color4);
     }
 
+    /**
+     * Reacts to changes in the navigation bar color
+     *
+     * @param darkIntensity 0 is the lightest color, 1 is the darkest.
+     */
+    @Override // NavigationBarTransitions.DarkIntensityListener
+    public void onDarkIntensity(float darkIntensity) {
+        updateDarkness(darkIntensity);
+    }
+
+
     @Override
     protected void onFinishInflate() {
         getLayoutParams().height = mViewHeight;
@@ -166,15 +218,19 @@
         getLocationOnScreen(mScreenLocation);
         canvas.translate(-mScreenLocation[0], -mScreenLocation[1]);
 
-        // if the lights are different colors, the inner ones need to be drawn last and with a
-        // square cap so that the join between lights is straight
-        mPaint.setStrokeCap(Paint.Cap.ROUND);
-        renderLight(mAssistInvocationLights.get(0), canvas);
-        renderLight(mAssistInvocationLights.get(3), canvas);
+        if (mUseNavBarColor) {
+            for (EdgeLight light : mAssistInvocationLights) {
+                renderLight(light, canvas);
+            }
+        } else {
+            mPaint.setStrokeCap(Paint.Cap.ROUND);
+            renderLight(mAssistInvocationLights.get(0), canvas);
+            renderLight(mAssistInvocationLights.get(3), canvas);
 
-        mPaint.setStrokeCap(Paint.Cap.SQUARE);
-        renderLight(mAssistInvocationLights.get(1), canvas);
-        renderLight(mAssistInvocationLights.get(2), canvas);
+            mPaint.setStrokeCap(Paint.Cap.BUTT);
+            renderLight(mAssistInvocationLights.get(1), canvas);
+            renderLight(mAssistInvocationLights.get(2), canvas);
+        }
     }
 
     protected void setLight(int index, float offset, float length) {
@@ -185,10 +241,67 @@
         mAssistInvocationLights.get(index).setLength(length);
     }
 
+    /**
+     * Returns CornerPathRenderer to be used for rendering invocation lights.
+     *
+     * To render corners that aren't circular, override this method in a subclass.
+     */
+    protected CornerPathRenderer createCornerPathRenderer(Context context) {
+        return new CircularCornerPathRenderer(context);
+    }
+
+    /**
+     * Receives an intensity from 0 (lightest) to 1 (darkest) and sets the handle color
+     * appropriately. Intention is to match the home handle color.
+     */
+    protected void updateDarkness(float darkIntensity) {
+        if (mUseNavBarColor) {
+            @ColorInt int invocationColor = (int) ArgbEvaluator.getInstance().evaluate(
+                    darkIntensity, mLightColor, mDarkColor);
+            for (EdgeLight light : mAssistInvocationLights) {
+                light.setColor(invocationColor);
+            }
+            invalidate();
+        }
+    }
+
     private void renderLight(EdgeLight light, Canvas canvas) {
         mGuide.strokeSegment(mPath, light.getOffset(), light.getOffset() + light.getLength());
         mPaint.setColor(light.getColor());
         canvas.drawPath(mPath, mPaint);
     }
 
+    private void attemptRegisterNavBarListener() {
+        if (!mRegistered) {
+            NavigationBarController controller = Dependency.get(NavigationBarController.class);
+            if (controller == null) {
+                return;
+            }
+
+            NavigationBarFragment navBar = controller.getDefaultNavigationBarFragment();
+            if (navBar == null) {
+                return;
+            }
+
+            updateDarkness(navBar.getBarTransitions().addDarkIntensityListener(this));
+            mRegistered = true;
+        }
+    }
+
+    private void attemptUnregisterNavBarListener() {
+        if (mRegistered) {
+            NavigationBarController controller = Dependency.get(NavigationBarController.class);
+            if (controller == null) {
+                return;
+            }
+
+            NavigationBarFragment navBar = controller.getDefaultNavigationBarFragment();
+            if (navBar == null) {
+                return;
+            }
+
+            navBar.getBarTransitions().removeDarkIntensityListener(this);
+            mRegistered = false;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java
new file mode 100644
index 0000000..2bad7fc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/PathSpecCornerPathRenderer.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.assist.ui;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.util.Log;
+import android.util.PathParser;
+
+import com.android.systemui.R;
+
+/**
+ * Parses a path describing rounded corners from a string.
+ */
+public final class PathSpecCornerPathRenderer extends CornerPathRenderer {
+    private static final String TAG = "PathSpecCornerPathRenderer";
+
+    private final int mHeight;
+    private final int mWidth;
+    private final float mPathScale;
+    private final int mBottomCornerRadius;
+    private final int mTopCornerRadius;
+
+    private final Path mPath = new Path();
+    private final Path mRoundedPath;
+    private final Matrix mMatrix = new Matrix();
+
+    public PathSpecCornerPathRenderer(Context context) {
+        mWidth = DisplayUtils.getWidth(context);
+        mHeight = DisplayUtils.getHeight(context);
+
+        mBottomCornerRadius = DisplayUtils.getCornerRadiusBottom(context);
+        mTopCornerRadius = DisplayUtils.getCornerRadiusTop(context);
+
+        String pathData = context.getResources().getString(R.string.config_rounded_mask);
+        Path path = PathParser.createPathFromPathData(pathData);
+        if (path == null) {
+            Log.e(TAG, "No rounded corner path found!");
+            mRoundedPath = new Path();
+        } else {
+            mRoundedPath = path;
+
+        }
+
+        RectF bounds = new RectF();
+        mRoundedPath.computeBounds(bounds, true);
+
+        // we use this to scale the path such that the larger of its [width, height] is scaled to
+        // the corner radius (to account for asymmetric paths)
+        mPathScale = Math.min(
+                Math.abs(bounds.right - bounds.left),
+                Math.abs(bounds.top - bounds.bottom));
+    }
+
+    /**
+     * Scales and rotates each corner from the path specification to its correct position.
+     *
+     * Note: the rounded corners are passed in as the full shape (a curved triangle), but we only
+     * want the actual corner curve. Therefore we call getSegment to jump past the horizontal and
+     * vertical lines.
+     */
+    @Override
+    public Path getCornerPath(Corner corner) {
+        if (mRoundedPath.isEmpty()) {
+            return mRoundedPath;
+        }
+        int cornerRadius;
+        int rotateDegrees;
+        int translateX;
+        int translateY;
+        switch (corner) {
+            case TOP_LEFT:
+                cornerRadius = mTopCornerRadius;
+                rotateDegrees = 0;
+                translateX = 0;
+                translateY = 0;
+                break;
+            case TOP_RIGHT:
+                cornerRadius = mTopCornerRadius;
+                rotateDegrees = 90;
+                translateX = mWidth;
+                translateY = 0;
+                break;
+            case BOTTOM_RIGHT:
+                cornerRadius = mBottomCornerRadius;
+                rotateDegrees = 180;
+                translateX = mWidth;
+                translateY = mHeight;
+                break;
+            case BOTTOM_LEFT:
+            default:
+                cornerRadius = mBottomCornerRadius;
+                rotateDegrees = 270;
+                translateX = 0;
+                translateY = mHeight;
+                break;
+        }
+        mPath.reset();
+        mMatrix.reset();
+        mPath.addPath(mRoundedPath);
+
+        mMatrix.preScale(cornerRadius / mPathScale, cornerRadius / mPathScale);
+        mMatrix.postRotate(rotateDegrees);
+        mMatrix.postTranslate(translateX, translateY);
+        mPath.transform(mMatrix);
+        return mPath;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java b/packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java
index 8eea368..fb41b1c 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java
@@ -102,7 +102,7 @@
      * Sets the rotation.
      *
      * @param rotation one of Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_180,
-     *                  Surface.ROTATION_270
+     *                 Surface.ROTATION_270
      */
     public void setRotation(int rotation) {
         if (rotation != mRotation) {
@@ -229,14 +229,14 @@
                     - mDeviceWidthPx) / 2, (mDeviceWidthPx - mDeviceHeightPx) / 2);
         }
 
-        CircularCornerPathRenderer.Corner screenBottomLeft = getRotatedCorner(
-                CircularCornerPathRenderer.Corner.BOTTOM_LEFT);
-        CircularCornerPathRenderer.Corner screenBottomRight = getRotatedCorner(
-                CircularCornerPathRenderer.Corner.BOTTOM_RIGHT);
-        CircularCornerPathRenderer.Corner screenTopLeft = getRotatedCorner(
-                CircularCornerPathRenderer.Corner.TOP_LEFT);
-        CircularCornerPathRenderer.Corner screenTopRight = getRotatedCorner(
-                CircularCornerPathRenderer.Corner.TOP_RIGHT);
+        CornerPathRenderer.Corner screenBottomLeft = getRotatedCorner(
+                CornerPathRenderer.Corner.BOTTOM_LEFT);
+        CornerPathRenderer.Corner screenBottomRight = getRotatedCorner(
+                CornerPathRenderer.Corner.BOTTOM_RIGHT);
+        CornerPathRenderer.Corner screenTopLeft = getRotatedCorner(
+                CornerPathRenderer.Corner.TOP_LEFT);
+        CornerPathRenderer.Corner screenTopRight = getRotatedCorner(
+                CornerPathRenderer.Corner.TOP_RIGHT);
 
         mRegions[Region.BOTTOM_LEFT.ordinal()].path =
                 mCornerPathRenderer.getInsetPath(screenBottomLeft, mEdgeInset);
@@ -287,9 +287,12 @@
         float accum = 0;
         for (int i = 0; i < mRegions.length; i++) {
             mRegions[i].normalizedLength = mRegions[i].absoluteLength / perimeterLength;
-            accum += mRegions[i].normalizedLength;
-            mRegions[i].endCoordinate = accum;
+            accum += mRegions[i].absoluteLength;
+            mRegions[i].endCoordinate = accum / perimeterLength;
         }
+        // Ensure that the last coordinate is 1. Setting it explicitly to avoid floating point
+        // error.
+        mRegions[mRegions.length - 1].endCoordinate = 1f;
     }
 
     private CircularCornerPathRenderer.Corner getRotatedCorner(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index 5717a54..a5857df 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.biometrics;
 
+import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
+
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.graphics.PixelFormat;
@@ -36,6 +38,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Interpolator;
 import android.widget.Button;
 import android.widget.ImageView;
@@ -55,6 +59,7 @@
 
     private static final String KEY_TRY_AGAIN_VISIBILITY = "key_try_again_visibility";
     private static final String KEY_CONFIRM_VISIBILITY = "key_confirm_visibility";
+    private static final String KEY_CONFIRM_ENABLED = "key_confirm_enabled";
     private static final String KEY_STATE = "key_state";
     private static final String KEY_ERROR_TEXT_VISIBILITY = "key_error_text_visibility";
     private static final String KEY_ERROR_TEXT_STRING = "key_error_text_string";
@@ -72,6 +77,7 @@
     protected static final int STATE_PENDING_CONFIRMATION = 3;
     protected static final int STATE_AUTHENTICATED = 4;
 
+    private final AccessibilityManager mAccessibilityManager;
     private final IBinder mWindowToken = new Binder();
     private final Interpolator mLinearOutSlowIn;
     private final WindowManager mWindowManager;
@@ -150,6 +156,7 @@
         super(context);
         mCallback = callback;
         mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
+        mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
         mWindowManager = mContext.getSystemService(WindowManager.class);
         mUserManager = mContext.getSystemService(UserManager.class);
         mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
@@ -226,13 +233,22 @@
             handleResetMessage();
             updateState(STATE_AUTHENTICATING);
             showTryAgainButton(false /* show */);
+
+            mPositiveButton.setVisibility(View.VISIBLE);
+            mPositiveButton.setEnabled(false);
+
             mCallback.onTryAgainPressed();
         });
+
+        // Must set these in order for the back button events to be received.
+        mLayout.setFocusableInTouchMode(true);
+        mLayout.requestFocus();
     }
 
     public void onSaveState(Bundle bundle) {
         bundle.putInt(KEY_TRY_AGAIN_VISIBILITY, mTryAgainButton.getVisibility());
         bundle.putInt(KEY_CONFIRM_VISIBILITY, mPositiveButton.getVisibility());
+        bundle.putBoolean(KEY_CONFIRM_ENABLED, mPositiveButton.isEnabled());
         bundle.putInt(KEY_STATE, mState);
         bundle.putInt(KEY_ERROR_TEXT_VISIBILITY, mErrorText.getVisibility());
         bundle.putCharSequence(KEY_ERROR_TEXT_STRING, mErrorText.getText());
@@ -251,6 +267,7 @@
                     mContext.getTheme());
             image.setColorFilter(mDevicePolicyManager.getOrganizationColorForUser(mUserId),
                     PorterDuff.Mode.DARKEN);
+            backgroundView.setScaleType(ImageView.ScaleType.CENTER_CROP);
             backgroundView.setImageDrawable(image);
         } else {
             backgroundView.setImageDrawable(null);
@@ -265,9 +282,16 @@
 
         if (mRestoredState == null) {
             updateState(STATE_AUTHENTICATING);
-            mErrorText.setText(getHintStringResourceId());
-            mErrorText.setContentDescription(mContext.getString(getHintStringResourceId()));
-            mErrorText.setVisibility(View.VISIBLE);
+            mNegativeButton.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
+            final int hint = getHintStringResourceId();
+            if (hint != 0) {
+                mErrorText.setText(hint);
+                mErrorText.setContentDescription(mContext.getString(hint));
+                mErrorText.setVisibility(View.VISIBLE);
+            } else {
+                mErrorText.setVisibility(View.INVISIBLE);
+            }
+            announceAccessibilityEvent();
         } else {
             updateState(mState);
         }
@@ -280,6 +304,7 @@
         final CharSequence subtitleText = mBundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE);
         if (TextUtils.isEmpty(subtitleText)) {
             mSubtitleText.setVisibility(View.GONE);
+            announceAccessibilityEvent();
         } else {
             mSubtitleText.setVisibility(View.VISIBLE);
             mSubtitleText.setText(subtitleText);
@@ -289,13 +314,12 @@
                 mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION);
         if (TextUtils.isEmpty(descriptionText)) {
             mDescriptionText.setVisibility(View.GONE);
+            announceAccessibilityEvent();
         } else {
             mDescriptionText.setVisibility(View.VISIBLE);
             mDescriptionText.setText(descriptionText);
         }
 
-        mNegativeButton.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
-
         if (requiresConfirmation() && mRestoredState == null) {
             mPositiveButton.setVisibility(View.VISIBLE);
             mPositiveButton.setEnabled(false);
@@ -413,6 +437,7 @@
         mErrorText.setText(message);
         mErrorText.setTextColor(mErrorColor);
         mErrorText.setContentDescription(message);
+        mErrorText.setVisibility(View.VISIBLE);
         mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
                 BiometricPrompt.HIDE_DIALOG_DELAY);
     }
@@ -446,17 +471,24 @@
     public void updateState(int newState) {
         if (newState == STATE_PENDING_CONFIRMATION) {
             mHandler.removeMessages(MSG_RESET_MESSAGE);
-            mErrorText.setVisibility(View.INVISIBLE);
+            mErrorText.setTextColor(mTextColor);
+            mErrorText.setText(R.string.biometric_dialog_tap_confirm);
+            mErrorText.setContentDescription(
+                    getResources().getString(R.string.biometric_dialog_tap_confirm));
+            mErrorText.setVisibility(View.VISIBLE);
+            announceAccessibilityEvent();
             mPositiveButton.setVisibility(View.VISIBLE);
             mPositiveButton.setEnabled(true);
         } else if (newState == STATE_AUTHENTICATED) {
             mPositiveButton.setVisibility(View.GONE);
             mNegativeButton.setVisibility(View.GONE);
             mErrorText.setVisibility(View.INVISIBLE);
+            announceAccessibilityEvent();
         }
 
         if (newState == STATE_PENDING_CONFIRMATION || newState == STATE_AUTHENTICATED) {
             mNegativeButton.setText(R.string.cancel);
+            mNegativeButton.setContentDescription(getResources().getString(R.string.cancel));
         }
 
         updateIcon(mState, newState);
@@ -471,14 +503,22 @@
 
     public void restoreState(Bundle bundle) {
         mRestoredState = bundle;
-        mTryAgainButton.setVisibility(bundle.getInt(KEY_TRY_AGAIN_VISIBILITY));
-        mPositiveButton.setVisibility(bundle.getInt(KEY_CONFIRM_VISIBILITY));
+        final int tryAgainVisibility = bundle.getInt(KEY_TRY_AGAIN_VISIBILITY);
+        mTryAgainButton.setVisibility(tryAgainVisibility);
+        final int confirmVisibility = bundle.getInt(KEY_CONFIRM_VISIBILITY);
+        mPositiveButton.setVisibility(confirmVisibility);
+        final boolean confirmEnabled = bundle.getBoolean(KEY_CONFIRM_ENABLED);
+        mPositiveButton.setEnabled(confirmEnabled);
         mState = bundle.getInt(KEY_STATE);
         mErrorText.setText(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
         mErrorText.setContentDescription(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
-        mErrorText.setVisibility(bundle.getInt(KEY_ERROR_TEXT_VISIBILITY));
+        final int errorTextVisibility = bundle.getInt(KEY_ERROR_TEXT_VISIBILITY);
+        mErrorText.setVisibility(errorTextVisibility);
+        if (errorTextVisibility == View.INVISIBLE || tryAgainVisibility == View.INVISIBLE
+                || confirmVisibility == View.INVISIBLE) {
+            announceAccessibilityEvent();
+        }
         mErrorText.setTextColor(bundle.getInt(KEY_ERROR_TEXT_COLOR));
-
         if (bundle.getBoolean(KEY_ERROR_TEXT_IS_TEMPORARY)) {
             mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
                     BiometricPrompt.HIDE_DIALOG_DELAY);
@@ -501,4 +541,18 @@
         lp.token = mWindowToken;
         return lp;
     }
+
+    // Every time a view becomes invisible we need to announce an accessibility event.
+    // This is due to an issue in the framework, b/132298701 recommended this workaround.
+    protected void announceAccessibilityEvent() {
+        if (!mAccessibilityManager.isEnabled()) {
+            return;
+        }
+        AccessibilityEvent event = AccessibilityEvent.obtain();
+        event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+        event.setContentChangeTypes(CONTENT_CHANGE_TYPE_SUBTREE);
+        mDialog.sendAccessibilityEventUnchecked(event);
+        mDialog.notifySubtreeAccessibilityStateChanged(mDialog, mDialog,
+                CONTENT_CHANGE_TYPE_SUBTREE);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
index 8f26f18..729242e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
@@ -149,6 +149,7 @@
     private final Runnable mErrorToIdleAnimationRunnable = () -> {
         updateState(STATE_IDLE);
         mErrorText.setVisibility(View.INVISIBLE);
+        announceAccessibilityEvent();
     };
 
     public FaceDialogView(Context context,
@@ -188,6 +189,7 @@
             mDialog.invalidateOutline();
 
             mSize = newSize;
+            announceAccessibilityEvent();
         } else if (mSize == SIZE_SMALL && newSize == SIZE_BIG) {
             mSize = SIZE_GROWING;
 
@@ -287,14 +289,9 @@
 
     @Override
     protected void handleResetMessage() {
-        mErrorText.setText(getHintStringResourceId());
-        mErrorText.setContentDescription(mContext.getString(getHintStringResourceId()));
         mErrorText.setTextColor(mTextColor);
-        if (getState() == STATE_AUTHENTICATING) {
-            mErrorText.setVisibility(View.VISIBLE);
-        } else {
-            mErrorText.setVisibility(View.INVISIBLE);
-        }
+        mErrorText.setVisibility(View.INVISIBLE);
+        announceAccessibilityEvent();
     }
 
     @Override
@@ -368,17 +365,19 @@
                 mTryAgainButton.setVisibility(View.VISIBLE);
             } else {
                 mTryAgainButton.setVisibility(View.GONE);
+                announceAccessibilityEvent();
             }
         }
 
         if (show) {
             mPositiveButton.setVisibility(View.GONE);
+            announceAccessibilityEvent();
         }
     }
 
     @Override
     protected int getHintStringResourceId() {
-        return R.string.face_dialog_looking_for_face;
+        return 0;
     }
 
     @Override
@@ -403,7 +402,6 @@
             mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
             if (mDialogAnimatedIn) {
                 mIconController.startPulsing();
-                mErrorText.setVisibility(View.VISIBLE);
             } else {
                 mIconController.showIcon(R.drawable.face_dialog_pulse_dark_to_light);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 09d4b05..923ca20 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -499,7 +499,6 @@
         view.setHeadsUp(false);
         view.resetTranslation();
         view.setOnKeyguard(false);
-        view.setOnAmbient(false);
         view.setClipBottomAmount(0);
         view.setClipTopAmount(0);
         view.setContentTransformationAmount(0, false);
@@ -515,7 +514,6 @@
         viewState.gone = false;
         viewState.hidden = false;
         viewState.dimmed = false;
-        viewState.dark = false;
         viewState.alpha = 1f;
         viewState.notGoneIndex = -1;
         viewState.xTranslation = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
index f8856ce..ae7d142 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java
@@ -16,9 +16,13 @@
 
 package com.android.systemui.classifier;
 
+import android.annotation.IntDef;
 import android.hardware.SensorEvent;
 import android.view.MotionEvent;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * An abstract class for classifiers for touch and sensor events.
  */
@@ -34,6 +38,21 @@
     public static final int BOUNCER_UNLOCK = 8;
     public static final int PULSE_EXPAND = 9;
 
+    @IntDef({
+            QUICK_SETTINGS,
+            NOTIFICATION_DISMISS,
+            NOTIFICATION_DRAG_DOWN,
+            NOTIFICATION_DOUBLE_TAP,
+            UNLOCK,
+            LEFT_AFFORDANCE,
+            RIGHT_AFFORDANCE,
+            GENERIC,
+            BOUNCER_UNLOCK,
+            PULSE_EXPAND
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InteractionType {}
+
     /**
      * Contains all the information about touch events from which the classifier can query
      */
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java
deleted file mode 100644
index 01921f0..0000000
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.systemui.classifier;
-
-import android.content.Context;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.plugins.FalsingManager;
-
-/**
- * When the phone is locked, listens to touch, sensor and phone events and sends them to
- * DataCollector and HumanInteractionClassifier.
- *
- * It does not collect touch events when the bouncer shows up.
- *
- * TODO: FalsingManager supports dependency injection. Use it.
- */
-public class FalsingManagerFactory {
-    private static FalsingManager sInstance = null;
-
-    private FalsingManagerFactory() {}
-
-    public static FalsingManager getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = Dependency.get(FalsingManager.class);
-        }
-        return sInstance;
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
new file mode 100644
index 0000000..ea175ed
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier;
+
+import android.net.Uri;
+import android.view.MotionEvent;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.plugins.FalsingManager;
+
+import java.io.PrintWriter;
+
+/**
+ * Simple Fake for testing where {@link FalsingManager} is required.
+ */
+public class FalsingManagerFake implements FalsingManager {
+    private boolean mIsFalseTouch;
+    private boolean mIsUnlockingDisabled;
+    private boolean mIsClassiferEnabled;
+    private boolean mShouldEnforceBouncer;
+    private boolean mIsReportingEnabled;
+
+    @Override
+    public void onSucccessfulUnlock() {
+
+    }
+
+    @Override
+    public void onNotificationActive() {
+
+    }
+
+    @Override
+    public void setShowingAod(boolean showingAod) {
+
+    }
+
+    @Override
+    public void onNotificatonStartDraggingDown() {
+
+    }
+
+    @VisibleForTesting
+    public void setIsUnlockingDisabled(boolean isUnlockingDisabled) {
+        mIsUnlockingDisabled = isUnlockingDisabled;
+    }
+
+    @Override
+    public boolean isUnlockingDisabled() {
+        return mIsUnlockingDisabled;
+    }
+
+    @VisibleForTesting
+    public void setIsFalseTouch(boolean isFalseTouch) {
+        mIsFalseTouch = isFalseTouch;
+    }
+
+    @Override
+    public boolean isFalseTouch() {
+        return mIsFalseTouch;
+    }
+
+    @Override
+    public void onNotificatonStopDraggingDown() {
+
+    }
+
+    @Override
+    public void setNotificationExpanded() {
+
+    }
+
+    @VisibleForTesting
+    public void setIsClassiferEnabled(boolean isClassiferEnabled) {
+        mIsClassiferEnabled = isClassiferEnabled;
+    }
+
+    @Override
+    public boolean isClassiferEnabled() {
+        return mIsClassiferEnabled;
+    }
+
+    @Override
+    public void onQsDown() {
+
+    }
+
+    @Override
+    public void setQsExpanded(boolean expanded) {
+
+    }
+
+    @VisibleForTesting
+    public void setShouldEnforceBouncer(boolean shouldEnforceBouncer) {
+        mShouldEnforceBouncer = shouldEnforceBouncer;
+    }
+
+    @Override
+    public boolean shouldEnforceBouncer() {
+        return mShouldEnforceBouncer;
+    }
+
+    @Override
+    public void onTrackingStarted(boolean secure) {
+
+    }
+
+    @Override
+    public void onTrackingStopped() {
+
+    }
+
+    @Override
+    public void onLeftAffordanceOn() {
+
+    }
+
+    @Override
+    public void onCameraOn() {
+
+    }
+
+    @Override
+    public void onAffordanceSwipingStarted(boolean rightCorner) {
+
+    }
+
+    @Override
+    public void onAffordanceSwipingAborted() {
+
+    }
+
+    @Override
+    public void onStartExpandingFromPulse() {
+
+    }
+
+    @Override
+    public void onExpansionFromPulseStopped() {
+
+    }
+
+    @Override
+    public Uri reportRejectedTouch() {
+        return null;
+    }
+
+    @Override
+    public void onScreenOnFromTouch() {
+
+    }
+
+
+    @VisibleForTesting
+    public void setIsReportingEnabled(boolean isReportingEnabled) {
+        mIsReportingEnabled = isReportingEnabled;
+    }
+
+    @Override
+    public boolean isReportingEnabled() {
+        return mIsReportingEnabled;
+    }
+
+    @Override
+    public void onUnlockHintStarted() {
+
+    }
+
+    @Override
+    public void onCameraHintStarted() {
+
+    }
+
+    @Override
+    public void onLeftAffordanceHintStarted() {
+
+    }
+
+    @Override
+    public void onScreenTurningOn() {
+
+    }
+
+    @Override
+    public void onScreenOff() {
+
+    }
+
+    @Override
+    public void onNotificatonStopDismissing() {
+
+    }
+
+    @Override
+    public void onNotificationDismissed() {
+
+    }
+
+    @Override
+    public void onNotificatonStartDismissing() {
+
+    }
+
+    @Override
+    public void onNotificationDoubleTap(boolean accepted, float dx, float dy) {
+
+    }
+
+    @Override
+    public void onBouncerShown() {
+
+    }
+
+    @Override
+    public void onBouncerHidden() {
+
+    }
+
+    @Override
+    public void onTouchEvent(MotionEvent ev, int width, int height) {
+
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+
+    }
+
+    @Override
+    public void cleanup() {
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
index 6fb6467..fba0d50 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java
@@ -67,8 +67,8 @@
             Sensor.TYPE_LIGHT,
             Sensor.TYPE_ROTATION_VECTOR,
     };
-    private static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts";
-    private static final String FALSING_SUCCESS = "falsing_success_after_attempts";
+    public static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts";
+    public static final String FALSING_SUCCESS = "falsing_success_after_attempts";
 
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Context mContext;
@@ -168,6 +168,7 @@
                     .append("enabled=").append(isEnabled() ? 1 : 0)
                     .append(" mScreenOn=").append(mScreenOn ? 1 : 0)
                     .append(" mState=").append(StatusBarState.toShortString(mState))
+                    .append(" mShowingAod=").append(mShowingAod ? 1 : 0)
                     .toString()
             );
         }
@@ -550,6 +551,14 @@
         pw.println();
     }
 
+    @Override
+    public void cleanup() {
+        mSensorManager.unregisterListener(mSensorEventListener);
+        mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
+        Dependency.get(StatusBarStateController.class).removeCallback(mStatusBarStateListener);
+        KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mKeyguardUpdateCallback);
+    }
+
     public Uri reportRejectedTouch() {
         if (mDataCollector.isEnabled()) {
             return mDataCollector.reportRejectedTouch();
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 28454b0..128cc61 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -16,35 +16,56 @@
 
 package com.android.systemui.classifier;
 
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_MANAGER_ENABLED;
+import static com.android.systemui.Dependency.MAIN_HANDLER_NAME;
+
 import android.content.Context;
 import android.net.Uri;
+import android.os.Handler;
+import android.provider.DeviceConfig;
 import android.view.MotionEvent;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Dependency;
+import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
+import com.android.systemui.classifier.brightline.FalsingDataProvider;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.FalsingPlugin;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.util.AsyncSensorManager;
 
 import java.io.PrintWriter;
 
 import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 /**
  * Simple passthrough implementation of {@link FalsingManager} allowing plugins to swap in.
  *
  * {@link FalsingManagerImpl} is used when a Plugin is not loaded.
  */
+@Singleton
 public class FalsingManagerProxy implements FalsingManager {
 
     private FalsingManager mInternalFalsingManager;
+    private final Handler mMainHandler;
 
     @Inject
-    FalsingManagerProxy(Context context, PluginManager pluginManager) {
-        mInternalFalsingManager = new FalsingManagerImpl(context);
+    FalsingManagerProxy(Context context, PluginManager pluginManager,
+            @Named(MAIN_HANDLER_NAME) Handler handler) {
+        mMainHandler = handler;
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+                command -> mMainHandler.post(command),
+                properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace())
+        );
+        setupFalsingManager(context);
         final PluginListener<FalsingPlugin> mPluginListener = new PluginListener<FalsingPlugin>() {
             public void onPluginConnected(FalsingPlugin plugin, Context context) {
                 FalsingManager pluginFalsingManager = plugin.getFalsingManager(context);
                 if (pluginFalsingManager != null) {
+                    mInternalFalsingManager.cleanup();
                     mInternalFalsingManager = pluginFalsingManager;
                 }
             }
@@ -57,6 +78,44 @@
         pluginManager.addPluginListener(mPluginListener, FalsingPlugin.class);
     }
 
+    private void onDeviceConfigPropertiesChanged(Context context, String namespace) {
+        if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) {
+            return;
+        }
+
+        setupFalsingManager(context);
+    }
+
+    /**
+     * Chooses the FalsingManager implementation.
+     */
+    @VisibleForTesting
+    public void setupFalsingManager(Context context) {
+        boolean brightlineEnabled = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, true);
+
+        if (mInternalFalsingManager != null) {
+            mInternalFalsingManager.cleanup();
+        }
+        if (!brightlineEnabled) {
+            mInternalFalsingManager = new FalsingManagerImpl(context);
+        } else {
+            mInternalFalsingManager = new BrightLineFalsingManager(
+                    new FalsingDataProvider(context.getResources().getDisplayMetrics()),
+                    Dependency.get(AsyncSensorManager.class)
+            );
+        }
+
+    }
+
+    /**
+     * Returns the FalsingManager implementation in use.
+     */
+    @VisibleForTesting
+    FalsingManager getInternalFalsingManager() {
+        return mInternalFalsingManager;
+    }
+
     @Override
     public void onSucccessfulUnlock() {
         mInternalFalsingManager.onSucccessfulUnlock();
@@ -236,4 +295,9 @@
     public void dump(PrintWriter pw) {
         mInternalFalsingManager.dump(pw);
     }
+
+    @Override
+    public void cleanup() {
+        mInternalFalsingManager.cleanup();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
new file mode 100644
index 0000000..cee01a4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_REMAIN_LOCKED;
+import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_SUCCESS;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.net.Uri;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.classifier.Classifier;
+import com.android.systemui.plugins.FalsingManager;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * FalsingManager designed to make clear why a touch was rejected.
+ */
+public class BrightLineFalsingManager implements FalsingManager {
+
+    static final boolean DEBUG = false;
+    private static final String TAG = "FalsingManagerPlugin";
+
+    private final SensorManager mSensorManager;
+    private final FalsingDataProvider mDataProvider;
+    private boolean mSessionStarted;
+    private MetricsLogger mMetricsLogger;
+    private int mIsFalseTouchCalls;
+
+    private final ExecutorService mBackgroundExecutor = Executors.newSingleThreadExecutor();
+
+    private final List<FalsingClassifier> mClassifiers;
+
+    private SensorEventListener mSensorEventListener = new SensorEventListener() {
+        @Override
+        public synchronized void onSensorChanged(SensorEvent event) {
+            onSensorEvent(event);
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        }
+    };
+
+    public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
+            SensorManager sensorManager) {
+        mDataProvider = falsingDataProvider;
+        mSensorManager = sensorManager;
+        mMetricsLogger = new MetricsLogger();
+        mClassifiers = new ArrayList<>();
+        DistanceClassifier distanceClassifier = new DistanceClassifier(mDataProvider);
+        ProximityClassifier proximityClassifier = new ProximityClassifier(distanceClassifier,
+                mDataProvider);
+        mClassifiers.add(new PointerCountClassifier(mDataProvider));
+        mClassifiers.add(new TypeClassifier(mDataProvider));
+        mClassifiers.add(new DiagonalClassifier(mDataProvider));
+        mClassifiers.add(distanceClassifier);
+        mClassifiers.add(proximityClassifier);
+        mClassifiers.add(new ZigZagClassifier(mDataProvider));
+    }
+
+    private void registerSensors() {
+        Sensor s = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+        if (s != null) {
+            // This can be expensive, and doesn't need to happen on the main thread.
+            mBackgroundExecutor.submit(() -> {
+                logDebug("registering sensor listener");
+                mSensorManager.registerListener(
+                        mSensorEventListener, s, SensorManager.SENSOR_DELAY_GAME);
+            });
+        }
+    }
+
+
+    private void unregisterSensors() {
+        // This can be expensive, and doesn't need to happen on the main thread.
+        mBackgroundExecutor.submit(() -> {
+            logDebug("unregistering sensor listener");
+            mSensorManager.unregisterListener(mSensorEventListener);
+        });
+    }
+
+    private void sessionStart() {
+        logDebug("Starting Session");
+        mSessionStarted = true;
+        registerSensors();
+        mClassifiers.forEach(FalsingClassifier::onSessionStarted);
+    }
+
+    private void sessionEnd() {
+        if (mSessionStarted) {
+            logDebug("Ending Session");
+            mSessionStarted = false;
+            unregisterSensors();
+            mDataProvider.onSessionEnd();
+            mClassifiers.forEach(FalsingClassifier::onSessionEnded);
+            if (mIsFalseTouchCalls != 0) {
+                mMetricsLogger.histogram(FALSING_REMAIN_LOCKED, mIsFalseTouchCalls);
+                mIsFalseTouchCalls = 0;
+            }
+        }
+    }
+
+    private void updateInteractionType(@Classifier.InteractionType int type) {
+        logDebug("InteractionType: " + type);
+        mClassifiers.forEach((classifier) -> classifier.setInteractionType(type));
+    }
+
+    @Override
+    public boolean isClassiferEnabled() {
+        return true;
+    }
+
+    @Override
+    public boolean isFalseTouch() {
+        boolean r = mClassifiers.stream().anyMatch(falsingClassifier -> {
+            boolean result = falsingClassifier.isFalseTouch();
+            if (result) {
+                logInfo(falsingClassifier.getClass().getName() + ": true");
+            } else {
+                logDebug(falsingClassifier.getClass().getName() + ": false");
+            }
+            return result;
+        });
+
+        logDebug("Is false touch? " + r);
+
+        return r;
+    }
+
+    @Override
+    public void onTouchEvent(MotionEvent motionEvent, int width, int height) {
+        // TODO: some of these classifiers might allow us to abort early, meaning we don't have to
+        // make these calls.
+        mDataProvider.onMotionEvent(motionEvent);
+        mClassifiers.forEach((classifier) -> classifier.onTouchEvent(motionEvent));
+    }
+
+    private void onSensorEvent(SensorEvent sensorEvent) {
+        // TODO: some of these classifiers might allow us to abort early, meaning we don't have to
+        // make these calls.
+        mClassifiers.forEach((classifier) -> classifier.onSensorEvent(sensorEvent));
+    }
+
+    @Override
+    public void onSucccessfulUnlock() {
+        if (mIsFalseTouchCalls != 0) {
+            mMetricsLogger.histogram(FALSING_SUCCESS, mIsFalseTouchCalls);
+            mIsFalseTouchCalls = 0;
+        }
+    }
+
+    @Override
+    public void onNotificationActive() {
+    }
+
+    @Override
+    public void setShowingAod(boolean showingAod) {
+        if (showingAod) {
+            sessionEnd();
+        } else {
+            sessionStart();
+        }
+    }
+
+    @Override
+    public void onNotificatonStartDraggingDown() {
+        updateInteractionType(Classifier.NOTIFICATION_DRAG_DOWN);
+
+    }
+
+    @Override
+    public boolean isUnlockingDisabled() {
+        return false;
+    }
+
+
+    @Override
+    public void onNotificatonStopDraggingDown() {
+    }
+
+    @Override
+    public void setNotificationExpanded() {
+    }
+
+    @Override
+    public void onQsDown() {
+        updateInteractionType(Classifier.QUICK_SETTINGS);
+    }
+
+    @Override
+    public void setQsExpanded(boolean b) {
+    }
+
+    @Override
+    public boolean shouldEnforceBouncer() {
+        return false;
+    }
+
+    @Override
+    public void onTrackingStarted(boolean secure) {
+        updateInteractionType(secure ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK);
+    }
+
+    @Override
+    public void onTrackingStopped() {
+    }
+
+    @Override
+    public void onLeftAffordanceOn() {
+    }
+
+    @Override
+    public void onCameraOn() {
+    }
+
+    @Override
+    public void onAffordanceSwipingStarted(boolean rightCorner) {
+        updateInteractionType(
+                rightCorner ? Classifier.RIGHT_AFFORDANCE : Classifier.LEFT_AFFORDANCE);
+    }
+
+    @Override
+    public void onAffordanceSwipingAborted() {
+    }
+
+    @Override
+    public void onStartExpandingFromPulse() {
+        updateInteractionType(Classifier.PULSE_EXPAND);
+    }
+
+    @Override
+    public void onExpansionFromPulseStopped() {
+    }
+
+    @Override
+    public Uri reportRejectedTouch() {
+        return null;
+    }
+
+    @Override
+    public void onScreenOnFromTouch() {
+        sessionStart();
+    }
+
+    @Override
+    public boolean isReportingEnabled() {
+        return false;
+    }
+
+    @Override
+    public void onUnlockHintStarted() {
+    }
+
+    @Override
+    public void onCameraHintStarted() {
+    }
+
+    @Override
+    public void onLeftAffordanceHintStarted() {
+    }
+
+    @Override
+    public void onScreenTurningOn() {
+        sessionStart();
+    }
+
+    @Override
+    public void onScreenOff() {
+        sessionEnd();
+    }
+
+
+    @Override
+    public void onNotificatonStopDismissing() {
+    }
+
+    @Override
+    public void onNotificationDismissed() {
+    }
+
+    @Override
+    public void onNotificatonStartDismissing() {
+        updateInteractionType(Classifier.NOTIFICATION_DISMISS);
+    }
+
+    @Override
+    public void onNotificationDoubleTap(boolean b, float v, float v1) {
+    }
+
+    @Override
+    public void onBouncerShown() {
+    }
+
+    @Override
+    public void onBouncerHidden() {
+    }
+
+    @Override
+    public void dump(PrintWriter printWriter) {
+    }
+
+    @Override
+    public void cleanup() {
+        unregisterSensors();
+    }
+
+    static void logDebug(String msg) {
+        logDebug(msg, null);
+    }
+
+    static void logDebug(String msg, Throwable throwable) {
+        if (DEBUG) {
+            Log.d(TAG, msg, throwable);
+        }
+    }
+
+    static void logInfo(String msg) {
+        Log.i(TAG, msg);
+    }
+
+    static void logError(String msg) {
+        Log.e(TAG, msg);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
new file mode 100644
index 0000000..cc66454
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.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.systemui.classifier.brightline;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DIAGONAL_HORIZONTAL_ANGLE_RANGE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DIAGONAL_VERTICAL_ANGLE_RANGE;
+import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
+import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
+
+import android.provider.DeviceConfig;
+
+/**
+ * False on swipes that are too close to 45 degrees.
+ *
+ * Horizontal swipes may have a different threshold than vertical.
+ *
+ * This falser should not run on "affordance" swipes, as they will always be close to 45.
+ */
+class DiagonalClassifier extends FalsingClassifier {
+
+    private static final float HORIZONTAL_ANGLE_RANGE = (float) (5f / 360f * Math.PI * 2f);
+    private static final float VERTICAL_ANGLE_RANGE = (float) (5f / 360f * Math.PI * 2f);
+    private static final float DIAGONAL = (float) (Math.PI / 4); // 45 deg
+    private static final float NINETY_DEG = (float) (Math.PI / 2);
+    private static final float ONE_HUNDRED_EIGHTY_DEG = (float) (Math.PI);
+    private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
+
+    private final float mHorizontalAngleRange;
+    private final float mVerticalAngleRange;
+
+    DiagonalClassifier(FalsingDataProvider dataProvider) {
+        super(dataProvider);
+
+        mHorizontalAngleRange = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DIAGONAL_HORIZONTAL_ANGLE_RANGE,
+                HORIZONTAL_ANGLE_RANGE);
+        mVerticalAngleRange = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DIAGONAL_VERTICAL_ANGLE_RANGE,
+                VERTICAL_ANGLE_RANGE);
+    }
+
+    @Override
+    boolean isFalseTouch() {
+        float angle = getAngle();
+
+        if (angle == Float.MAX_VALUE) {  // Unknown angle
+            return false;
+        }
+
+        if (getInteractionType() == LEFT_AFFORDANCE
+                || getInteractionType() == RIGHT_AFFORDANCE) {
+            return false;
+        }
+
+        float minAngle = DIAGONAL - mHorizontalAngleRange;
+        float maxAngle = DIAGONAL + mHorizontalAngleRange;
+        if (isVertical()) {
+            minAngle = DIAGONAL - mVerticalAngleRange;
+            maxAngle = DIAGONAL + mVerticalAngleRange;
+        }
+
+        return angleBetween(angle, minAngle, maxAngle)
+                || angleBetween(angle, minAngle + NINETY_DEG, maxAngle + NINETY_DEG)
+                || angleBetween(angle, minAngle - NINETY_DEG, maxAngle - NINETY_DEG)
+                || angleBetween(angle, minAngle + ONE_HUNDRED_EIGHTY_DEG,
+                maxAngle + ONE_HUNDRED_EIGHTY_DEG);
+    }
+
+    private boolean angleBetween(float angle, float min, float max) {
+        // No need to normalize angle as it is guaranteed to be between 0 and 2*PI.
+        min = normalizeAngle(min);
+        max = normalizeAngle(max);
+
+        if (min > max) {  // Can happen when angle is close to 0.
+            return angle >= min || angle <= max;
+        }
+
+        return angle >= min && angle <= max;
+    }
+
+    private float normalizeAngle(float angle) {
+        if (angle < 0) {
+            return THREE_HUNDRED_SIXTY_DEG + (angle % THREE_HUNDRED_SIXTY_DEG);
+        } else if (angle > THREE_HUNDRED_SIXTY_DEG) {
+            return angle % THREE_HUNDRED_SIXTY_DEG;
+        }
+        return angle;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
new file mode 100644
index 0000000..a6a617d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_FLING_THRESHOLD_IN;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_SWIPE_THRESHOLD_IN;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_SCREEN_FRACTION_MAX_DISTANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VELOCITY_TO_DISTANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VERTICAL_FLING_THRESHOLD_IN;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN;
+
+import android.provider.DeviceConfig;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+
+import java.util.List;
+
+/**
+ * Ensure that the swipe + momentum covers a minimum distance.
+ */
+class DistanceClassifier extends FalsingClassifier {
+
+    private static final float HORIZONTAL_FLING_THRESHOLD_DISTANCE_IN = 1;
+    private static final float VERTICAL_FLING_THRESHOLD_DISTANCE_IN = 1;
+    private static final float HORIZONTAL_SWIPE_THRESHOLD_DISTANCE_IN = 3;
+    private static final float VERTICAL_SWIPE_THRESHOLD_DISTANCE_IN = 3;
+    private static final float VELOCITY_TO_DISTANCE = 80f;
+    private static final float SCREEN_FRACTION_MAX_DISTANCE = 0.8f;
+
+    private final float mVerticalFlingThresholdPx;
+    private final float mHorizontalFlingThresholdPx;
+    private final float mVerticalSwipeThresholdPx;
+    private final float mHorizontalSwipeThresholdPx;
+    private final float mVelocityToDistanceMultiplier;
+
+    private boolean mDistanceDirty;
+    private DistanceVectors mCachedDistance;
+
+    DistanceClassifier(FalsingDataProvider dataProvider) {
+        super(dataProvider);
+
+        mVelocityToDistanceMultiplier = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_VELOCITY_TO_DISTANCE,
+                VELOCITY_TO_DISTANCE);
+
+        float horizontalFlingThresholdIn = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_FLING_THRESHOLD_IN,
+                HORIZONTAL_FLING_THRESHOLD_DISTANCE_IN);
+
+        float verticalFlingThresholdIn = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_VERTICAL_FLING_THRESHOLD_IN,
+                VERTICAL_FLING_THRESHOLD_DISTANCE_IN);
+
+        float horizontalSwipeThresholdIn = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_HORIZONTAL_SWIPE_THRESHOLD_IN,
+                HORIZONTAL_SWIPE_THRESHOLD_DISTANCE_IN);
+
+        float verticalSwipeThresholdIn = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN,
+                VERTICAL_SWIPE_THRESHOLD_DISTANCE_IN);
+
+        float screenFractionMaxDistance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_DISTANCE_SCREEN_FRACTION_MAX_DISTANCE,
+                SCREEN_FRACTION_MAX_DISTANCE);
+
+        mHorizontalFlingThresholdPx = Math
+                .min(getWidthPixels() * screenFractionMaxDistance,
+                        horizontalFlingThresholdIn * getXdpi());
+        mVerticalFlingThresholdPx = Math
+                .min(getHeightPixels() * screenFractionMaxDistance,
+                        verticalFlingThresholdIn * getYdpi());
+        mHorizontalSwipeThresholdPx = Math
+                .min(getWidthPixels() * screenFractionMaxDistance,
+                        horizontalSwipeThresholdIn * getXdpi());
+        mVerticalSwipeThresholdPx = Math
+                .min(getHeightPixels() * screenFractionMaxDistance,
+                        verticalSwipeThresholdIn * getYdpi());
+        mDistanceDirty = true;
+    }
+
+    private DistanceVectors getDistances() {
+        if (mDistanceDirty) {
+            mCachedDistance = calculateDistances();
+            mDistanceDirty = false;
+        }
+
+        return mCachedDistance;
+    }
+
+    private DistanceVectors calculateDistances() {
+        // This code assumes that there will be no missed DOWN or UP events.
+        VelocityTracker velocityTracker = VelocityTracker.obtain();
+        List<MotionEvent> motionEvents = getRecentMotionEvents();
+
+        if (motionEvents.size() < 3) {
+            logDebug("Only " + motionEvents.size() + " motion events recorded.");
+            return new DistanceVectors(0, 0, 0, 0);
+        }
+
+        for (MotionEvent motionEvent : motionEvents) {
+            velocityTracker.addMovement(motionEvent);
+        }
+        velocityTracker.computeCurrentVelocity(1);
+
+        float vX = velocityTracker.getXVelocity();
+        float vY = velocityTracker.getYVelocity();
+
+        velocityTracker.recycle();
+
+        float dX = getLastMotionEvent().getX() - getFirstMotionEvent().getX();
+        float dY = getLastMotionEvent().getY() - getFirstMotionEvent().getY();
+
+        logInfo("dX: " + dX + " dY: " + dY + " xV: " + vX + " yV: " + vY);
+
+        return new DistanceVectors(dX, dY, vX, vY);
+    }
+
+    @Override
+    public void onTouchEvent(MotionEvent motionEvent) {
+        mDistanceDirty = true;
+    }
+
+    @Override
+    public boolean isFalseTouch() {
+        return !getDistances().getPassedFlingThreshold();
+    }
+
+    boolean isLongSwipe() {
+        boolean longSwipe = getDistances().getPassedDistanceThreshold();
+        logDebug("Is longSwipe? " + longSwipe);
+        return longSwipe;
+    }
+
+    private class DistanceVectors {
+        final float mDx;
+        final float mDy;
+        private final float mVx;
+        private final float mVy;
+
+        DistanceVectors(float dX, float dY, float vX, float vY) {
+            this.mDx = dX;
+            this.mDy = dY;
+            this.mVx = vX;
+            this.mVy = vY;
+        }
+
+        boolean getPassedDistanceThreshold() {
+            if (isHorizontal()) {
+                logDebug("Horizontal swipe distance: " + Math.abs(mDx));
+                logDebug("Threshold: " + mHorizontalSwipeThresholdPx);
+
+                return Math.abs(mDx) >= mHorizontalSwipeThresholdPx;
+            }
+
+            logDebug("Vertical swipe distance: " + Math.abs(mDy));
+            logDebug("Threshold: " + mVerticalSwipeThresholdPx);
+            return Math.abs(mDy) >= mVerticalSwipeThresholdPx;
+        }
+
+        boolean getPassedFlingThreshold() {
+            float dX = this.mDx + this.mVx * mVelocityToDistanceMultiplier;
+            float dY = this.mDy + this.mVy * mVelocityToDistanceMultiplier;
+
+            if (isHorizontal()) {
+                logDebug("Horizontal swipe and fling distance: " + this.mDx + ", "
+                        + this.mVx * mVelocityToDistanceMultiplier);
+                logDebug("Threshold: " + mHorizontalFlingThresholdPx);
+                return Math.abs(dX) >= mHorizontalFlingThresholdPx;
+            }
+
+            logDebug("Vertical swipe and fling distance: " + this.mDy + ", "
+                    + this.mVy * mVelocityToDistanceMultiplier);
+            logDebug("Threshold: " + mVerticalFlingThresholdPx);
+            return Math.abs(dY) >= mVerticalFlingThresholdPx;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
new file mode 100644
index 0000000..685e7c5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.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.systemui.classifier.brightline;
+
+import android.hardware.SensorEvent;
+import android.view.MotionEvent;
+
+import com.android.systemui.classifier.Classifier;
+
+import java.util.List;
+
+/**
+ * Base class for rules that determine False touches.
+ */
+abstract class FalsingClassifier {
+    private final FalsingDataProvider mDataProvider;
+
+    FalsingClassifier(FalsingDataProvider dataProvider) {
+        this.mDataProvider = dataProvider;
+    }
+
+    List<MotionEvent> getRecentMotionEvents() {
+        return mDataProvider.getRecentMotionEvents();
+    }
+
+    MotionEvent getFirstMotionEvent() {
+        return mDataProvider.getFirstRecentMotionEvent();
+    }
+
+    MotionEvent getLastMotionEvent() {
+        return mDataProvider.getLastMotionEvent();
+    }
+
+    boolean isHorizontal() {
+        return mDataProvider.isHorizontal();
+    }
+
+    boolean isRight() {
+        return mDataProvider.isRight();
+    }
+
+    boolean isVertical() {
+        return mDataProvider.isVertical();
+    }
+
+    boolean isUp() {
+        return mDataProvider.isUp();
+    }
+
+    float getAngle() {
+        return mDataProvider.getAngle();
+    }
+
+    int getWidthPixels() {
+        return mDataProvider.getWidthPixels();
+    }
+
+    int getHeightPixels() {
+        return mDataProvider.getHeightPixels();
+    }
+
+    float getXdpi() {
+        return mDataProvider.getXdpi();
+    }
+
+    float getYdpi() {
+        return mDataProvider.getYdpi();
+    }
+
+    final @Classifier.InteractionType int getInteractionType() {
+        return mDataProvider.getInteractionType();
+    }
+
+    final void setInteractionType(@Classifier.InteractionType int interactionType) {
+        mDataProvider.setInteractionType(interactionType);
+    }
+
+    /**
+     * Called whenever a MotionEvent occurs.
+     *
+     * Useful for classifiers that need to see every MotionEvent, but most can probably
+     * use {@link #getRecentMotionEvents()} instead, which will return a list of MotionEvents.
+     */
+    void onTouchEvent(MotionEvent motionEvent) {};
+
+    /**
+     * Called whenever a SensorEvent occurs, specifically the ProximitySensor.
+     */
+    void onSensorEvent(SensorEvent sensorEvent) {};
+
+    /**
+     * The phone screen has turned on and we need to begin falsing detection.
+     */
+    void onSessionStarted() {};
+
+    /**
+     * The phone screen has turned off and falsing data can be discarded.
+     */
+    void onSessionEnded() {};
+
+    /**
+     * Returns true if the data captured so far looks like a false touch.
+     */
+    abstract boolean isFalseTouch();
+
+    static void logDebug(String msg) {
+        BrightLineFalsingManager.logDebug(msg);
+    }
+
+    static void logInfo(String msg) {
+        BrightLineFalsingManager.logInfo(msg);
+    }
+
+    static void logError(String msg) {
+        BrightLineFalsingManager.logError(msg);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java
new file mode 100644
index 0000000..8b11ceb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingDataProvider.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import android.util.DisplayMetrics;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
+
+import com.android.systemui.classifier.Classifier;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Acts as a cache and utility class for FalsingClassifiers.
+ */
+public class FalsingDataProvider {
+
+    private static final long MOTION_EVENT_AGE_MS = 1000;
+    private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
+
+    private final int mWidthPixels;
+    private final int mHeightPixels;
+    private final float mXdpi;
+    private final float mYdpi;
+
+    private @Classifier.InteractionType int mInteractionType;
+    private final TimeLimitedMotionEventBuffer mRecentMotionEvents =
+            new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
+
+    private boolean mDirty = true;
+
+    private float mAngle = 0;
+    private MotionEvent mFirstActualMotionEvent;
+    private MotionEvent mFirstRecentMotionEvent;
+    private MotionEvent mLastMotionEvent;
+
+    public FalsingDataProvider(DisplayMetrics displayMetrics) {
+        mXdpi = displayMetrics.xdpi;
+        mYdpi = displayMetrics.ydpi;
+        mWidthPixels = displayMetrics.widthPixels;
+        mHeightPixels = displayMetrics.heightPixels;
+
+        FalsingClassifier.logInfo("xdpi, ydpi: " + getXdpi() + ", " + getYdpi());
+        FalsingClassifier.logInfo("width, height: " + getWidthPixels() + ", " + getHeightPixels());
+    }
+
+    void onMotionEvent(MotionEvent motionEvent) {
+        if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
+            mFirstActualMotionEvent = motionEvent;
+        }
+
+        List<MotionEvent> motionEvents = unpackMotionEvent(motionEvent);
+        FalsingClassifier.logDebug("Unpacked into: " + motionEvents.size());
+        if (BrightLineFalsingManager.DEBUG) {
+            for (MotionEvent m : motionEvents) {
+                FalsingClassifier.logDebug(
+                        "x,y,t: " + m.getX() + "," + m.getY() + "," + m.getEventTime());
+            }
+        }
+
+        if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
+            mRecentMotionEvents.clear();
+        }
+        mRecentMotionEvents.addAll(motionEvents);
+
+        FalsingClassifier.logDebug("Size: " + mRecentMotionEvents.size());
+
+        mDirty = true;
+    }
+
+    /** Returns screen width in pixels. */
+    int getWidthPixels() {
+        return mWidthPixels;
+    }
+
+    /** Returns screen height in pixels. */
+    int getHeightPixels() {
+        return mHeightPixels;
+    }
+
+    float getXdpi() {
+        return mXdpi;
+    }
+
+    float getYdpi() {
+        return mYdpi;
+    }
+
+    List<MotionEvent> getRecentMotionEvents() {
+        return mRecentMotionEvents;
+    }
+
+    /**
+     * interactionType is defined by {@link com.android.systemui.classifier.Classifier}.
+     */
+    final void setInteractionType(@Classifier.InteractionType int interactionType) {
+        this.mInteractionType = interactionType;
+    }
+
+    final int getInteractionType() {
+        return mInteractionType;
+    }
+
+    MotionEvent getFirstActualMotionEvent() {
+        return mFirstActualMotionEvent;
+    }
+
+    MotionEvent getFirstRecentMotionEvent() {
+        recalculateData();
+        return mFirstRecentMotionEvent;
+    }
+
+    MotionEvent getLastMotionEvent() {
+        recalculateData();
+        return mLastMotionEvent;
+    }
+
+    /**
+     * Returns the angle between the first and last point of the recent points.
+     *
+     * The angle will be in radians, always be between 0 and 2*PI, inclusive.
+     */
+    float getAngle() {
+        recalculateData();
+        return mAngle;
+    }
+
+    boolean isHorizontal() {
+        recalculateData();
+        if (mRecentMotionEvents.isEmpty()) {
+            return false;
+        }
+
+        return Math.abs(mFirstRecentMotionEvent.getX() - mLastMotionEvent.getX()) > Math
+                .abs(mFirstRecentMotionEvent.getY() - mLastMotionEvent.getY());
+    }
+
+    boolean isRight() {
+        recalculateData();
+        if (mRecentMotionEvents.isEmpty()) {
+            return false;
+        }
+
+        return mLastMotionEvent.getX() > mFirstRecentMotionEvent.getX();
+    }
+
+    boolean isVertical() {
+        return !isHorizontal();
+    }
+
+    boolean isUp() {
+        recalculateData();
+        if (mRecentMotionEvents.isEmpty()) {
+            return false;
+        }
+
+        return mLastMotionEvent.getY() < mFirstRecentMotionEvent.getY();
+    }
+
+    private void recalculateData() {
+        if (!mDirty) {
+            return;
+        }
+
+        if (mRecentMotionEvents.isEmpty()) {
+            mFirstRecentMotionEvent = null;
+            mLastMotionEvent = null;
+        } else {
+            mFirstRecentMotionEvent = mRecentMotionEvents.get(0);
+            mLastMotionEvent = mRecentMotionEvents.get(mRecentMotionEvents.size() - 1);
+        }
+
+        calculateAngleInternal();
+
+        mDirty = false;
+    }
+
+    private void calculateAngleInternal() {
+        if (mRecentMotionEvents.size() < 2) {
+            mAngle = Float.MAX_VALUE;
+        } else {
+            float lastX = mLastMotionEvent.getX() - mFirstRecentMotionEvent.getX();
+            float lastY = mLastMotionEvent.getY() - mFirstRecentMotionEvent.getY();
+
+            mAngle = (float) Math.atan2(lastY, lastX);
+            while (mAngle < 0) {
+                mAngle += THREE_HUNDRED_SIXTY_DEG;
+            }
+            while (mAngle > THREE_HUNDRED_SIXTY_DEG) {
+                mAngle -= THREE_HUNDRED_SIXTY_DEG;
+            }
+        }
+    }
+
+    private List<MotionEvent> unpackMotionEvent(MotionEvent motionEvent) {
+        List<MotionEvent> motionEvents = new ArrayList<>();
+        List<PointerProperties> pointerPropertiesList = new ArrayList<>();
+        int pointerCount = motionEvent.getPointerCount();
+        for (int i = 0; i < pointerCount; i++) {
+            PointerProperties pointerProperties = new PointerProperties();
+            motionEvent.getPointerProperties(i, pointerProperties);
+            pointerPropertiesList.add(pointerProperties);
+        }
+        PointerProperties[] pointerPropertiesArray = new PointerProperties[pointerPropertiesList
+                .size()];
+        pointerPropertiesList.toArray(pointerPropertiesArray);
+
+        int historySize = motionEvent.getHistorySize();
+        for (int i = 0; i < historySize; i++) {
+            List<PointerCoords> pointerCoordsList = new ArrayList<>();
+            for (int j = 0; j < pointerCount; j++) {
+                PointerCoords pointerCoords = new PointerCoords();
+                motionEvent.getHistoricalPointerCoords(j, i, pointerCoords);
+                pointerCoordsList.add(pointerCoords);
+            }
+            motionEvents.add(MotionEvent.obtain(
+                    motionEvent.getDownTime(),
+                    motionEvent.getHistoricalEventTime(i),
+                    motionEvent.getAction(),
+                    pointerCount,
+                    pointerPropertiesArray,
+                    pointerCoordsList.toArray(new PointerCoords[0]),
+                    motionEvent.getMetaState(),
+                    motionEvent.getButtonState(),
+                    motionEvent.getXPrecision(),
+                    motionEvent.getYPrecision(),
+                    motionEvent.getDeviceId(),
+                    motionEvent.getEdgeFlags(),
+                    motionEvent.getSource(),
+                    motionEvent.getFlags()
+            ));
+        }
+
+        motionEvents.add(MotionEvent.obtainNoHistory(motionEvent));
+
+        return motionEvents;
+    }
+
+    void onSessionEnd() {
+        mFirstActualMotionEvent = null;
+
+        for (MotionEvent ev : mRecentMotionEvents) {
+            ev.recycle();
+        }
+
+        mRecentMotionEvents.clear();
+
+        mDirty = true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java
new file mode 100644
index 0000000..40e141f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import android.view.MotionEvent;
+
+/**
+ * False touch if more than one finger touches the screen.
+ *
+ * IMPORTANT: This should not be used for certain cases (i.e. a11y) as we expect multiple fingers
+ * for them.
+ */
+class PointerCountClassifier extends FalsingClassifier {
+
+    private static final int MAX_ALLOWED_POINTERS = 1;
+    private int mMaxPointerCount;
+
+    PointerCountClassifier(FalsingDataProvider dataProvider) {
+        super(dataProvider);
+    }
+
+    @Override
+    public void onTouchEvent(MotionEvent motionEvent) {
+        int pCount = mMaxPointerCount;
+        if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
+            mMaxPointerCount = motionEvent.getPointerCount();
+        } else {
+            mMaxPointerCount = Math.max(mMaxPointerCount, motionEvent.getPointerCount());
+        }
+        if (pCount != mMaxPointerCount) {
+            logDebug("Pointers observed:" + mMaxPointerCount);
+        }
+    }
+
+    @Override
+    public boolean isFalseTouch() {
+        return mMaxPointerCount > MAX_ALLOWED_POINTERS;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
new file mode 100644
index 0000000..2644bf9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.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 com.android.systemui.classifier.brightline;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
+import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.provider.DeviceConfig;
+import android.view.MotionEvent;
+
+
+/**
+ * False touch if proximity sensor is covered for more than a certain percentage of the gesture.
+ *
+ * This classifer is essentially a no-op for QUICK_SETTINGS, as we assume the sensor may be
+ * covered when swiping from the top.
+ */
+class ProximityClassifier extends FalsingClassifier {
+
+    private static final float PERCENT_COVERED_THRESHOLD = 0.1f;
+    private final DistanceClassifier mDistanceClassifier;
+    private final float mPercentCoveredThreshold;
+
+    private boolean mNear;
+    private long mGestureStartTimeNs;
+    private long mPrevNearTimeNs;
+    private long mNearDurationNs;
+    private float mPercentNear;
+
+    ProximityClassifier(DistanceClassifier distanceClassifier,
+            FalsingDataProvider dataProvider) {
+        super(dataProvider);
+        this.mDistanceClassifier = distanceClassifier;
+
+        mPercentCoveredThreshold = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD,
+                PERCENT_COVERED_THRESHOLD);
+    }
+
+    @Override
+    void onSessionStarted() {
+        mPrevNearTimeNs = 0;
+        mPercentNear = 0;
+    }
+
+    @Override
+    void onSessionEnded() {
+        mPrevNearTimeNs = 0;
+        mPercentNear = 0;
+    }
+
+    @Override
+    public void onTouchEvent(MotionEvent motionEvent) {
+        int action = motionEvent.getActionMasked();
+
+        if (action == MotionEvent.ACTION_DOWN) {
+            mGestureStartTimeNs = motionEvent.getEventTimeNano();
+            if (mPrevNearTimeNs > 0) {
+                // We only care about if the proximity sensor is triggered while a move event is
+                // happening.
+                mPrevNearTimeNs = motionEvent.getEventTimeNano();
+            }
+            logDebug("Gesture start time: " + mGestureStartTimeNs);
+            mNearDurationNs = 0;
+        }
+
+        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+            update(mNear, motionEvent.getEventTimeNano());
+            long duration = motionEvent.getEventTimeNano() - mGestureStartTimeNs;
+
+            logDebug("Gesture duration, Proximity duration: " + duration + ", " + mNearDurationNs);
+
+            if (duration == 0) {
+                mPercentNear = mNear ? 1.0f : 0.0f;
+            } else {
+                mPercentNear = (float) mNearDurationNs / (float) duration;
+            }
+        }
+
+    }
+
+    @Override
+    public void onSensorEvent(SensorEvent sensorEvent) {
+        if (sensorEvent.sensor.getType() == Sensor.TYPE_PROXIMITY) {
+            logDebug("Sensor is: " + (sensorEvent.values[0] < sensorEvent.sensor.getMaximumRange())
+                    + " at time " + sensorEvent.timestamp);
+            update(
+                    sensorEvent.values[0] < sensorEvent.sensor.getMaximumRange(),
+                    sensorEvent.timestamp);
+        }
+    }
+
+    @Override
+    public boolean isFalseTouch() {
+        if (getInteractionType() == QUICK_SETTINGS) {
+            return false;
+        }
+
+        logInfo("Percent of gesture in proximity: " + mPercentNear);
+
+        if (mPercentNear > mPercentCoveredThreshold) {
+            return !mDistanceClassifier.isLongSwipe();
+        }
+
+        return false;
+    }
+
+    /**
+     * @param near        is the sensor showing the near state right now
+     * @param timeStampNs time of this event in nanoseconds
+     */
+    private void update(boolean near, long timeStampNs) {
+        if (mPrevNearTimeNs != 0 && timeStampNs > mPrevNearTimeNs && mNear) {
+            mNearDurationNs += timeStampNs - mPrevNearTimeNs;
+            logDebug("Updating duration: " + mNearDurationNs);
+        }
+
+        if (near) {
+            logDebug("Set prevNearTimeNs: " + timeStampNs);
+            mPrevNearTimeNs = timeStampNs;
+        }
+
+        mNear = near;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java
new file mode 100644
index 0000000..9a83b5b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TimeLimitedMotionEventBuffer.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import android.view.MotionEvent;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * Maintains an ordered list of the last N milliseconds of MotionEvents.
+ *
+ * This class is simply a convenience class designed to look like a simple list, but that
+ * automatically discards old MotionEvents. It functions much like a queue - first in first out -
+ * but does not have a fixed size like a circular buffer.
+ */
+public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
+
+    private final LinkedList<MotionEvent> mMotionEvents;
+    private long mMaxAgeMs;
+
+    TimeLimitedMotionEventBuffer(long maxAgeMs) {
+        super();
+        this.mMaxAgeMs = maxAgeMs;
+        this.mMotionEvents = new LinkedList<>();
+    }
+
+    private void ejectOldEvents() {
+        if (mMotionEvents.isEmpty()) {
+            return;
+        }
+        Iterator<MotionEvent> iter = listIterator();
+        long mostRecentMs = mMotionEvents.getLast().getEventTime();
+        while (iter.hasNext()) {
+            MotionEvent ev = iter.next();
+            if (mostRecentMs - ev.getEventTime() > mMaxAgeMs) {
+                iter.remove();
+                ev.recycle();
+            }
+        }
+    }
+
+    @Override
+    public void add(int index, MotionEvent element) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public MotionEvent remove(int index) {
+        return mMotionEvents.remove(index);
+    }
+
+    @Override
+    public int indexOf(Object o) {
+        return mMotionEvents.indexOf(o);
+    }
+
+    @Override
+    public int lastIndexOf(Object o) {
+        return mMotionEvents.lastIndexOf(o);
+    }
+
+    @Override
+    public int size() {
+        return mMotionEvents.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return mMotionEvents.isEmpty();
+    }
+
+    @Override
+    public boolean contains(Object o) {
+        return mMotionEvents.contains(o);
+    }
+
+    @Override
+    public Iterator<MotionEvent> iterator() {
+        return mMotionEvents.iterator();
+    }
+
+    @Override
+    public Object[] toArray() {
+        return mMotionEvents.toArray();
+    }
+
+    @Override
+    public <T> T[] toArray(T[] a) {
+        return mMotionEvents.toArray(a);
+    }
+
+    @Override
+    public boolean add(MotionEvent element) {
+        boolean result = mMotionEvents.add(element);
+        ejectOldEvents();
+        return result;
+    }
+
+    @Override
+    public boolean remove(Object o) {
+        return mMotionEvents.remove(o);
+    }
+
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        return mMotionEvents.containsAll(c);
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends MotionEvent> collection) {
+        boolean result = mMotionEvents.addAll(collection);
+        ejectOldEvents();
+        return result;
+    }
+
+    @Override
+    public boolean addAll(int index, Collection<? extends MotionEvent> elements) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        return mMotionEvents.removeAll(c);
+    }
+
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        return mMotionEvents.retainAll(c);
+    }
+
+    @Override
+    public void clear() {
+        mMotionEvents.clear();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return mMotionEvents.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+        return mMotionEvents.hashCode();
+    }
+
+    @Override
+    public MotionEvent get(int index) {
+        return mMotionEvents.get(index);
+    }
+
+    @Override
+    public MotionEvent set(int index, MotionEvent element) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ListIterator<MotionEvent> listIterator() {
+        return new Iter(0);
+    }
+
+    @Override
+    public ListIterator<MotionEvent> listIterator(int index) {
+        return new Iter(index);
+    }
+
+    @Override
+    public List<MotionEvent> subList(int fromIndex, int toIndex) {
+        throw new UnsupportedOperationException();
+    }
+
+    class Iter implements ListIterator<MotionEvent> {
+
+        private final ListIterator<MotionEvent> mIterator;
+
+        Iter(int index) {
+            this.mIterator = mMotionEvents.listIterator(index);
+        }
+
+        @Override
+        public boolean hasNext() {
+            return mIterator.hasNext();
+        }
+
+        @Override
+        public MotionEvent next() {
+            return mIterator.next();
+        }
+
+        @Override
+        public boolean hasPrevious() {
+            return mIterator.hasPrevious();
+        }
+
+        @Override
+        public MotionEvent previous() {
+            return mIterator.previous();
+        }
+
+        @Override
+        public int nextIndex() {
+            return mIterator.nextIndex();
+        }
+
+        @Override
+        public int previousIndex() {
+            return mIterator.previousIndex();
+        }
+
+        @Override
+        public void remove() {
+            mIterator.remove();
+        }
+
+        @Override
+        public void set(MotionEvent motionEvent) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void add(MotionEvent element) {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java
new file mode 100644
index 0000000..b6ceab5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+
+import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
+import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
+import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
+import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
+import static com.android.systemui.classifier.Classifier.PULSE_EXPAND;
+import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
+import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
+import static com.android.systemui.classifier.Classifier.UNLOCK;
+
+/**
+ * Ensure that the swipe direction generally matches that of the interaction type.
+ */
+public class TypeClassifier extends FalsingClassifier {
+    TypeClassifier(FalsingDataProvider dataProvider) {
+        super(dataProvider);
+    }
+
+    @Override
+    public boolean isFalseTouch() {
+        boolean vertical = isVertical();
+        boolean up = isUp();
+        boolean right = isRight();
+
+        switch (getInteractionType()) {
+            case QUICK_SETTINGS:
+            case PULSE_EXPAND:
+            case NOTIFICATION_DRAG_DOWN:
+                return !vertical || up;
+            case NOTIFICATION_DISMISS:
+                return vertical;
+            case UNLOCK:
+            case BOUNCER_UNLOCK:
+                return !vertical || !up;
+            case LEFT_AFFORDANCE:  // Swiping from the bottom left corner for camera or similar.
+                return !right || !up;
+            case RIGHT_AFFORDANCE:  // Swiping from the bottom right corner for camera or similar.
+                return right || !up;
+            default:
+                return true;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
new file mode 100644
index 0000000..c58b7db
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_X_PRIMARY_DEVIANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_Y_PRIMARY_DEVIANCE;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE;
+
+import android.graphics.Point;
+import android.provider.DeviceConfig;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Penalizes gestures that change direction in either the x or y too much.
+ */
+class ZigZagClassifier extends FalsingClassifier {
+
+    // Define how far one can move back and forth over one inch of travel before being falsed.
+    // `PRIMARY` defines how far one can deviate in the primary direction of travel. I.e. if you're
+    // swiping vertically, you shouldn't have a lot of zig zag in the vertical direction. Since
+    // most swipes will follow somewhat of a 'C' or 'S' shape, we allow more deviance along the
+    // `SECONDARY` axis.
+    private static final float MAX_X_PRIMARY_DEVIANCE = .05f;
+    private static final float MAX_Y_PRIMARY_DEVIANCE = .05f;
+    private static final float MAX_X_SECONDARY_DEVIANCE = .3f;
+    private static final float MAX_Y_SECONDARY_DEVIANCE = .3f;
+
+    private final float mMaxXPrimaryDeviance;
+    private final float mMaxYPrimaryDeviance;
+    private final float mMaxXSecondaryDeviance;
+    private final float mMaxYSecondaryDeviance;
+
+    ZigZagClassifier(FalsingDataProvider dataProvider) {
+        super(dataProvider);
+
+        mMaxXPrimaryDeviance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_ZIGZAG_X_PRIMARY_DEVIANCE,
+                MAX_X_PRIMARY_DEVIANCE);
+
+        mMaxYPrimaryDeviance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_ZIGZAG_Y_PRIMARY_DEVIANCE,
+                MAX_Y_PRIMARY_DEVIANCE);
+
+        mMaxXSecondaryDeviance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_ZIGZAG_X_SECONDARY_DEVIANCE,
+                MAX_X_SECONDARY_DEVIANCE);
+
+        mMaxYSecondaryDeviance = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_ZIGZAG_Y_SECONDARY_DEVIANCE,
+                MAX_Y_SECONDARY_DEVIANCE);
+
+    }
+
+    @Override
+    boolean isFalseTouch() {
+        List<MotionEvent> motionEvents = getRecentMotionEvents();
+        // Rotate horizontal gestures to be horizontal between their first and last point.
+        // Rotate vertical gestures to be vertical between their first and last point.
+        // Sum the absolute value of every dx and dy along the gesture. Compare this with the dx
+        // and dy
+        // between the first and last point.
+        // For horizontal lines, the difference in the x direction should be small.
+        // For vertical lines, the difference in the y direction should be small.
+
+        if (motionEvents.size() < 3) {
+            return false;
+        }
+
+        List<Point> rotatedPoints;
+        if (isHorizontal()) {
+            rotatedPoints = rotateHorizontal();
+        } else {
+            rotatedPoints = rotateVertical();
+        }
+
+        float actualDx = Math
+                .abs(rotatedPoints.get(0).x - rotatedPoints.get(rotatedPoints.size() - 1).x);
+        float actualDy = Math
+                .abs(rotatedPoints.get(0).y - rotatedPoints.get(rotatedPoints.size() - 1).y);
+        logDebug("Actual: (" + actualDx + "," + actualDy + ")");
+        float runningAbsDx = 0;
+        float runningAbsDy = 0;
+        float pX = 0;
+        float pY = 0;
+        boolean firstLoop = true;
+        for (Point point : rotatedPoints) {
+            if (firstLoop) {
+                pX = point.x;
+                pY = point.y;
+                firstLoop = false;
+                continue;
+            }
+            runningAbsDx += Math.abs(point.x - pX);
+            runningAbsDy += Math.abs(point.y - pY);
+            pX = point.x;
+            pY = point.y;
+            logDebug("(x, y, runningAbsDx, runningAbsDy) - (" + pX + ", " + pY + ", " + runningAbsDx
+                    + ", " + runningAbsDy + ")");
+        }
+
+        float devianceX = runningAbsDx - actualDx;
+        float devianceY = runningAbsDy - actualDy;
+        float distanceXIn = actualDx / getXdpi();
+        float distanceYIn = actualDy / getYdpi();
+        float totalDistanceIn = (float) Math
+                .sqrt(distanceXIn * distanceXIn + distanceYIn * distanceYIn);
+
+        float maxXDeviance;
+        float maxYDeviance;
+        if (actualDx > actualDy) {
+            maxXDeviance = mMaxXPrimaryDeviance * totalDistanceIn * getXdpi();
+            maxYDeviance = mMaxYSecondaryDeviance * totalDistanceIn * getYdpi();
+        } else {
+            maxXDeviance = mMaxXSecondaryDeviance * totalDistanceIn * getXdpi();
+            maxYDeviance = mMaxYPrimaryDeviance * totalDistanceIn * getYdpi();
+        }
+
+        logDebug("Straightness Deviance: (" + devianceX + "," + devianceY + ") vs "
+                + "(" + maxXDeviance + "," + maxYDeviance + ")");
+        return devianceX > maxXDeviance || devianceY > maxYDeviance;
+    }
+
+    private float getAtan2LastPoint() {
+        MotionEvent firstEvent = getFirstMotionEvent();
+        MotionEvent lastEvent = getLastMotionEvent();
+        float offsetX = firstEvent.getX();
+        float offsetY = firstEvent.getY();
+        float lastX = lastEvent.getX() - offsetX;
+        float lastY = lastEvent.getY() - offsetY;
+
+        return (float) Math.atan2(lastY, lastX);
+    }
+
+    private List<Point> rotateVertical() {
+        // Calculate the angle relative to the y axis.
+        double angle = Math.PI / 2 - getAtan2LastPoint();
+        logDebug("Rotating to vertical by: " + angle);
+        return rotateMotionEvents(getRecentMotionEvents(), -angle);
+    }
+
+    private List<Point> rotateHorizontal() {
+        // Calculate the angle relative to the x axis.
+        double angle = getAtan2LastPoint();
+        logDebug("Rotating to horizontal by: " + angle);
+        return rotateMotionEvents(getRecentMotionEvents(), angle);
+    }
+
+    private List<Point> rotateMotionEvents(List<MotionEvent> motionEvents, double angle) {
+        List<Point> points = new ArrayList<>();
+        double cosAngle = Math.cos(angle);
+        double sinAngle = Math.sin(angle);
+        MotionEvent firstEvent = motionEvents.get(0);
+        float offsetX = firstEvent.getX();
+        float offsetY = firstEvent.getY();
+        for (MotionEvent motionEvent : motionEvents) {
+            float x = motionEvent.getX() - offsetX;
+            float y = motionEvent.getY() - offsetY;
+            double rotatedX = cosAngle * x + sinAngle * y + offsetX;
+            double rotatedY = -sinAngle * x + cosAngle * y + offsetY;
+            points.add(new Point((int) rotatedX, (int) rotatedY));
+        }
+
+        MotionEvent lastEvent = motionEvents.get(motionEvents.size() - 1);
+        Point firstPoint = points.get(0);
+        Point lastPoint = points.get(points.size() - 1);
+        logDebug(
+                "Before: (" + firstEvent.getX() + "," + firstEvent.getY() + "), ("
+                        + lastEvent.getX() + ","
+                        + lastEvent.getY() + ")");
+        logDebug(
+                "After: (" + firstPoint.x + "," + firstPoint.y + "), (" + lastPoint.x + ","
+                        + lastPoint.y
+                        + ")");
+
+        return points;
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 05665b5..d3e8b3d 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -19,14 +19,8 @@
 import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.content.Context;
-import android.os.Handler;
-import android.os.RemoteException;
+import android.graphics.Color;
 import android.os.UserHandle;
-import android.util.Log;
-import android.view.Display;
-import android.view.IWallpaperVisibilityListener;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.colorextraction.ColorExtractor;
@@ -51,56 +45,42 @@
         ConfigurationController.ConfigurationListener {
     private static final String TAG = "SysuiColorExtractor";
     private final Tonal mTonal;
-    private boolean mWallpaperVisible;
-    private boolean mHasBackdrop;
-    // Colors to return when the wallpaper isn't visible
-    private final GradientColors mWpHiddenColors;
+    private boolean mHasMediaArtwork;
+    private final GradientColors mNeutralColorsLock;
+    private final GradientColors mBackdropColors;
 
     @Inject
     public SysuiColorExtractor(Context context, ConfigurationController configurationController) {
-        this(context, new Tonal(context), configurationController, true);
+        this(context, new Tonal(context), configurationController,
+                context.getSystemService(WallpaperManager.class), false /* immediately */);
     }
 
     @VisibleForTesting
     public SysuiColorExtractor(Context context, ExtractionType type,
-            ConfigurationController configurationController, boolean registerVisibility) {
-        super(context, type, false /* immediately */);
+            ConfigurationController configurationController,
+            WallpaperManager wallpaperManager, boolean immediately) {
+        super(context, type, immediately, wallpaperManager);
         mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context);
-        mWpHiddenColors = new GradientColors();
+        mNeutralColorsLock = new GradientColors();
         configurationController.addCallback(this);
 
-        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        updateDefaultGradients(systemColors);
+        mBackdropColors = new GradientColors();
+        mBackdropColors.setMainColor(Color.BLACK);
 
-        if (registerVisibility) {
-            try {
-                IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
-                Handler handler = Handler.getMain();
-                boolean visible = windowManagerService.registerWallpaperVisibilityListener(
-                        new IWallpaperVisibilityListener.Stub() {
-                            @Override
-                            public void onWallpaperVisibilityChanged(boolean newVisibility,
-                                    int displayId) throws RemoteException {
-                                handler.post(() -> setWallpaperVisible(newVisibility));
-                            }
-                        }, Display.DEFAULT_DISPLAY);
-                setWallpaperVisible(visible);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Can't listen to wallpaper visibility changes", e);
-            }
-        }
-
-        WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
-        if (wallpaperManager != null) {
-            // Listen to all users instead of only the current one.
-            wallpaperManager.removeOnColorsChangedListener(this);
-            wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
-                    UserHandle.USER_ALL);
-        }
+        // Listen to all users instead of only the current one.
+        wallpaperManager.removeOnColorsChangedListener(this);
+        wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
+                UserHandle.USER_ALL);
     }
 
-    private void updateDefaultGradients(WallpaperColors colors) {
-        mTonal.applyFallback(colors, mWpHiddenColors);
+    @Override
+    protected void extractWallpaperColors() {
+        super.extractWallpaperColors();
+        // mTonal is final but this method will be invoked by the base class during its ctor.
+        if (mTonal == null || mNeutralColorsLock == null) {
+            return;
+        }
+        mTonal.applyFallback(mLockColors == null ? mSystemColors : mLockColors, mNeutralColorsLock);
     }
 
     @Override
@@ -109,22 +89,28 @@
             // Colors do not belong to current user, ignoring.
             return;
         }
-
-        super.onColorsChanged(colors, which);
-
-        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
-            updateDefaultGradients(colors);
+        if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+            mTonal.applyFallback(colors, mNeutralColorsLock);
         }
+        super.onColorsChanged(colors, which);
     }
 
     @Override
     public void onUiModeChanged() {
-        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        updateDefaultGradients(systemColors);
+        extractWallpaperColors();
+        triggerColorsChanged(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
+    }
+
+    @Override
+    public GradientColors getColors(int which, int type) {
+        if (mHasMediaArtwork && (which & WallpaperManager.FLAG_LOCK) != 0) {
+            return mBackdropColors;
+        }
+        return super.getColors(which, type);
     }
 
     /**
-     * Colors the should be using for scrims.
+     * Colors that should be using for scrims.
      *
      * They will be:
      * - A light gray if the wallpaper is light
@@ -132,81 +118,12 @@
      * - Black otherwise
      */
     public GradientColors getNeutralColors() {
-        return mWpHiddenColors;
+        return mHasMediaArtwork ? mBackdropColors : mNeutralColorsLock;
     }
 
-    /**
-     * Get TYPE_NORMAL colors when wallpaper is visible, or fallback otherwise.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @return colors
-     */
-    @Override
-    public GradientColors getColors(int which) {
-        return getColors(which, TYPE_DARK);
-    }
-
-    /**
-     * Wallpaper colors when the wallpaper is visible, fallback otherwise.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
-     * @return colors
-     */
-    @Override
-    public GradientColors getColors(int which, int type) {
-        return getColors(which, type, false /* ignoreVisibility */);
-    }
-
-    /**
-     * Get TYPE_NORMAL colors, possibly ignoring wallpaper visibility.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param ignoreWallpaperVisibility whether you want fallback colors or not if the wallpaper
-     *                                  isn't visible
-     * @return
-     */
-    public GradientColors getColors(int which, boolean ignoreWallpaperVisibility) {
-        return getColors(which, TYPE_NORMAL, ignoreWallpaperVisibility);
-    }
-
-    /**
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
-     * @param ignoreWallpaperVisibility true if true wallpaper colors should be returning
-     *                                  if it's visible or not
-     * @return colors
-     */
-    public GradientColors getColors(int which, int type, boolean ignoreWallpaperVisibility) {
-        // mWallpaperVisible only handles the "system wallpaper" and will be always set to false
-        // if we have different lock and system wallpapers.
-        if (which == WallpaperManager.FLAG_SYSTEM) {
-            if (mWallpaperVisible || ignoreWallpaperVisibility) {
-                return super.getColors(which, type);
-            } else {
-                return mWpHiddenColors;
-            }
-        } else {
-            if (mHasBackdrop) {
-                return mWpHiddenColors;
-            } else {
-                return super.getColors(which, type);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void setWallpaperVisible(boolean visible) {
-        if (mWallpaperVisible != visible) {
-            mWallpaperVisible = visible;
-            triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
-        }
-    }
-
-    public void setHasBackdrop(boolean hasBackdrop) {
-        if (mHasBackdrop != hasBackdrop) {
-            mHasBackdrop = hasBackdrop;
+    public void setHasMediaArtwork(boolean hasBackdrop) {
+        if (mHasMediaArtwork != hasBackdrop) {
+            mHasMediaArtwork = hasBackdrop;
             triggerColorsChanged(WallpaperManager.FLAG_LOCK);
         }
     }
@@ -224,7 +141,8 @@
         pw.println("  Gradients:");
         pw.println("    system: " + Arrays.toString(system));
         pw.println("    lock: " + Arrays.toString(lock));
-        pw.println("  Default scrim: " + mWpHiddenColors);
+        pw.println("  Neutral colors: " + mNeutralColorsLock);
+        pw.println("  Has media backdrop: " + mHasMediaArtwork);
 
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
new file mode 100644
index 0000000..e6a9e47
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.doze;
+
+import android.content.Context;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+
+/**
+ * Controls removing Keyguard authorization when the phone goes to sleep.
+ */
+public class DozeAuthRemover implements DozeMachine.Part {
+
+    KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+
+    public DozeAuthRemover(Context context) {
+        mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        if (newState == DozeMachine.State.DOZE || newState == DozeMachine.State.DOZE_AOD) {
+            int currentUser = KeyguardUpdateMonitor.getCurrentUser();
+            if (mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(currentUser)) {
+                mKeyguardUpdateMonitor.clearBiometricRecognized();
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
index 3c6dc73..1d7e9ea 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
@@ -43,6 +43,7 @@
     private final DockManager mDockManager;
 
     private int mDockState = DockManager.STATE_NONE;
+    private boolean mPulsePending;
 
     public DozeDockHandler(Context context, DozeMachine machine, DozeHost dozeHost,
             AmbientDisplayConfiguration config, Handler handler, DockManager dockManager) {
@@ -66,7 +67,8 @@
                 }
                 // continue below
             case DOZE:
-                if (mDockState == DockManager.STATE_DOCKED) {
+                if (mDockState == DockManager.STATE_DOCKED && !mPulsePending) {
+                    mPulsePending = true;
                     mHandler.post(() -> requestPulse(newState));
                 }
                 break;
@@ -79,11 +81,10 @@
     }
 
     private void requestPulse(State dozeState) {
-        if (mDozeHost.isPulsingBlocked() || !dozeState.canPulse()) {
-            return;
+        if (!mDozeHost.isPulsingBlocked() && dozeState.canPulse()) {
+            mMachine.requestPulse(DozeLog.PULSE_REASON_DOCKING);
         }
-
-        mMachine.requestPulse(DozeLog.PULSE_REASON_DOCKING);
+        mPulsePending = false;
     }
 
     private void requestPulseOutNow(State dozeState) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 8694d2a..1bc7e63 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -28,8 +28,9 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.dock.DockManager;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AsyncSensorManager;
 import com.android.systemui.util.wakelock.DelayedWakeLock;
@@ -41,7 +42,7 @@
     }
 
     /** Creates a DozeMachine with its parts for {@code dozeService}. */
-    public DozeMachine assembleMachine(DozeService dozeService) {
+    public DozeMachine assembleMachine(DozeService dozeService, FalsingManager falsingManager) {
         Context context = dozeService;
         SensorManager sensorManager = Dependency.get(AsyncSensorManager.class);
         AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
@@ -63,15 +64,16 @@
         DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock);
         machine.setParts(new DozeMachine.Part[]{
                 new DozePauser(handler, machine, alarmManager, params.getPolicy()),
-                new DozeFalsingManagerAdapter(FalsingManagerFactory.getInstance(context)),
+                new DozeFalsingManagerAdapter(falsingManager),
                 createDozeTriggers(context, sensorManager, host, alarmManager, config, params,
                         handler, wakeLock, machine, dockManager),
                 createDozeUi(context, host, wakeLock, machine, handler, alarmManager, params),
                 new DozeScreenState(wrappedService, handler, params, wakeLock),
                 createDozeScreenBrightness(context, wrappedService, sensorManager, host, params,
                         handler),
-                new DozeWallpaperState(context),
-                new DozeDockHandler(context, machine, host, config, handler, dockManager)
+                new DozeWallpaperState(context, getBiometricUnlockController(dozeService)),
+                new DozeDockHandler(context, machine, host, config, handler, dockManager),
+                new DozeAuthRemover(dozeService)
         });
 
         return machine;
@@ -107,4 +109,10 @@
         final SystemUIApplication app = (SystemUIApplication) appCandidate;
         return app.getComponent(DozeHost.class);
     }
+
+    public static BiometricUnlockController getBiometricUnlockController(DozeService service) {
+        Application appCandidate = service.getApplication();
+        final SystemUIApplication app = (SystemUIApplication) appCandidate;
+        return app.getComponent(BiometricUnlockController.class);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 3c9d4a9..ae6dac5 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -50,9 +50,23 @@
      */
     void onSlpiTap(float x, float y);
 
+    /**
+     * Artificially dim down the the display by changing scrim opacities.
+     * @param scrimOpacity opacity from 0 to 1.
+     */
     default void setAodDimmingScrim(float scrimOpacity) {}
+
+    /**
+     * Sets the actual display brightness.
+     * @param value from 0 to 255.
+     */
     void setDozeScreenBrightness(int value);
 
+    /**
+     * Makes scrims black and changes animation durations.
+     */
+    default void prepareForGentleWakeUp() {}
+
     void onIgnoreTouchWhilePulsing(boolean ignore);
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
index 368451a..38ee2fe 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -36,13 +36,13 @@
      * Delay entering low power mode when animating to make sure that we'll have
      * time to move all elements into their final positions while still at 60 fps.
      */
-    private static final int ENTER_DOZE_DELAY = 6000;
+    private static final int ENTER_DOZE_DELAY = 4000;
     /**
      * Hide wallpaper earlier when entering low power mode. The gap between
      * hiding the wallpaper and changing the display mode is necessary to hide
      * the black frame that's inherent to hardware specs.
      */
-    public static final int ENTER_DOZE_HIDE_WALLPAPER_DELAY = 4500;
+    public static final int ENTER_DOZE_HIDE_WALLPAPER_DELAY = 2500;
 
     private final DozeMachine.Service mDozeService;
     private final Handler mHandler;
@@ -82,7 +82,10 @@
         boolean messagePending = mHandler.hasCallbacks(mApplyPendingScreenState);
         boolean pulseEnding = oldState  == DozeMachine.State.DOZE_PULSE_DONE
                 && newState == DozeMachine.State.DOZE_AOD;
-        if (messagePending || oldState == DozeMachine.State.INITIALIZED || pulseEnding) {
+        boolean turningOn = (oldState == DozeMachine.State.DOZE_AOD_PAUSED
+                || oldState  == DozeMachine.State.DOZE) && newState == DozeMachine.State.DOZE_AOD;
+        boolean justInitialized = oldState == DozeMachine.State.INITIALIZED;
+        if (messagePending || justInitialized || pulseEnding || turningOn) {
             // During initialization, we hide the navigation bar. That is however only applied after
             // a traversal; setting the screen state here is immediate however, so it can happen
             // that the screen turns on again before the navigation bar is hidden. To work around
@@ -91,7 +94,7 @@
 
             // Delay screen state transitions even longer while animations are running.
             boolean shouldDelayTransition = newState == DozeMachine.State.DOZE_AOD
-                    && mParameters.shouldControlScreenOff();
+                    && mParameters.shouldControlScreenOff() && !turningOn;
 
             if (shouldDelayTransition) {
                 mWakeLock.setAcquired(true);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 2c85eff..f6a921d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -43,6 +43,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.systemui.R;
 import com.android.systemui.plugins.SensorManagerPlugin;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AlarmTimeout;
@@ -70,11 +71,14 @@
     private final Consumer<Boolean> mProxCallback;
     private final Callback mCallback;
     @VisibleForTesting
-    protected final TriggerSensor[] mSensors;
+    protected TriggerSensor[] mSensors;
 
     private final Handler mHandler = new Handler();
     private final ProxSensor mProxSensor;
     private long mDebounceFrom;
+    private boolean mSettingRegistered;
+    private boolean mListening;
+    private boolean mPaused;
 
     public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
             DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
@@ -99,9 +103,12 @@
                 mPickupSensor = new TriggerSensor(
                         mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
                         Settings.Secure.DOZE_PICK_UP_GESTURE,
+                        true /* settingDef */,
                         config.dozePickupSensorAvailable(),
                         DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
-                        false /* touchscreen */),
+                        false /* touchscreen */,
+                        false /* ignoresSetting */,
+                        mDozeParameters.getPickupPerformsProxCheck()),
                 new TriggerSensor(
                         findSensorWithType(config.doubleTapSensorType()),
                         Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
@@ -126,15 +133,15 @@
                         true /* touchscreen */),
                 new PluginSensor(
                         new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
-                        Settings.Secure.DOZE_WAKE_SCREEN_GESTURE,
+                        Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
                         mConfig.wakeScreenGestureAvailable() && alwaysOn,
                         DozeLog.REASON_SENSOR_WAKE_UP,
                         false /* reports touch coordinates */,
                         false /* touchscreen */),
                 new PluginSensor(
                         new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
-                        Settings.Secure.DOZE_WAKE_SCREEN_GESTURE,
-                        mConfig.wakeScreenGestureAvailable() && alwaysOn,
+                        Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
+                        mConfig.wakeScreenGestureAvailable(),
                         DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
                         false /* reports touch coordinates */,
                         false /* touchscreen */, mConfig.getWakeLockScreenDebounce()),
@@ -169,16 +176,52 @@
         return null;
     }
 
+    /**
+     * If sensors should be registered and sending signals.
+     */
     public void setListening(boolean listen) {
+        if (mListening == listen) {
+            return;
+        }
+        mListening = listen;
+        updateListening();
+    }
+
+    /**
+     * Unregister sensors, when listening, unless they are prox gated.
+     * @see #setListening(boolean)
+     */
+    public void setPaused(boolean paused) {
+        if (mPaused == paused) {
+            return;
+        }
+        mPaused = paused;
+        updateListening();
+    }
+
+    /**
+     * Registers/unregisters sensors based on internal state.
+     */
+    public void updateListening() {
+        boolean anyListening = false;
         for (TriggerSensor s : mSensors) {
+            // We don't want to be listening while we're PAUSED (prox sensor is covered)
+            // except when the sensor is already gated by prox.
+            boolean listen = mListening && (!mPaused || s.performsProxCheck());
             s.setListening(listen);
             if (listen) {
+                anyListening = true;
+            }
+        }
+
+        if (!anyListening) {
+            mResolver.unregisterContentObserver(mSettingsObserver);
+        } else if (!mSettingRegistered) {
+            for (TriggerSensor s : mSensors) {
                 s.registerSettingsObserver(mSettingsObserver);
             }
         }
-        if (!listen) {
-            mResolver.unregisterContentObserver(mSettingsObserver);
-        }
+        mSettingRegistered = anyListening;
     }
 
     /** Set the listening state of only the sensors that require the touchscreen. */
@@ -192,7 +235,7 @@
 
     public void onUserSwitched() {
         for (TriggerSensor s : mSensors) {
-            s.updateListener();
+            s.updateListening();
         }
     }
 
@@ -207,7 +250,7 @@
                 return;
             }
             for (TriggerSensor s : mSensors) {
-                s.updateListener();
+                s.updateListening();
             }
         }
     };
@@ -248,12 +291,21 @@
         long mLastNear;
         final AlarmTimeout mCooldownTimer;
         final AlwaysOnDisplayPolicy mPolicy;
-
+        final Sensor mSensor;
 
         public ProxSensor(AlwaysOnDisplayPolicy policy) {
             mPolicy = policy;
             mCooldownTimer = new AlarmTimeout(mAlarmManager, this::updateRegistered,
                     "prox_cooldown", mHandler);
+
+            // The default prox sensor can be noisy, so let's use a prox gated brightness sensor
+            // if available.
+            Sensor sensor = DozeSensors.findSensorWithType(mSensorManager,
+                    mContext.getString(R.string.doze_brightness_sensor_type));
+            if (sensor == null) {
+                sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+            }
+            mSensor = sensor;
         }
 
         void setRequested(boolean requested) {
@@ -317,8 +369,9 @@
 
         @Override
         public String toString() {
-            return String.format("{registered=%s, requested=%s, coolingDown=%s, currentlyFar=%s}",
-                    mRegistered, mRequested, mCooldownTimer.isScheduled(), mCurrentlyFar);
+            return String.format("{registered=%s, requested=%s, coolingDown=%s, currentlyFar=%s,"
+                    + " sensor=%s}", mRegistered, mRequested, mCooldownTimer.isScheduled(),
+                    mCurrentlyFar, mSensor);
         }
     }
 
@@ -327,10 +380,11 @@
         final Sensor mSensor;
         final boolean mConfigured;
         final int mPulseReason;
-        final String mSetting;
-        final boolean mReportsTouchCoordinates;
-        final boolean mSettingDefault;
-        final boolean mRequiresTouchscreen;
+        private final String mSetting;
+        private final boolean mReportsTouchCoordinates;
+        private final boolean mSettingDefault;
+        private final boolean mRequiresTouchscreen;
+        private final boolean mSensorPerformsProxCheck;
 
         protected boolean mRequested;
         protected boolean mRegistered;
@@ -347,12 +401,14 @@
                 boolean configured, int pulseReason, boolean reportsTouchCoordinates,
                 boolean requiresTouchscreen) {
             this(sensor, setting, settingDef, configured, pulseReason, reportsTouchCoordinates,
-                    requiresTouchscreen, false /* ignoresSetting */);
+                    requiresTouchscreen, false /* ignoresSetting */,
+                    false /* sensorPerformsProxCheck */);
         }
 
         private TriggerSensor(Sensor sensor, String setting, boolean settingDef,
                 boolean configured, int pulseReason, boolean reportsTouchCoordinates,
-                boolean requiresTouchscreen, boolean ignoresSetting) {
+                boolean requiresTouchscreen, boolean ignoresSetting,
+                boolean sensorPerformsProxCheck) {
             mSensor = sensor;
             mSetting = setting;
             mSettingDefault = settingDef;
@@ -361,27 +417,28 @@
             mReportsTouchCoordinates = reportsTouchCoordinates;
             mRequiresTouchscreen = requiresTouchscreen;
             mIgnoresSetting = ignoresSetting;
+            mSensorPerformsProxCheck = sensorPerformsProxCheck;
         }
 
         public void setListening(boolean listen) {
             if (mRequested == listen) return;
             mRequested = listen;
-            updateListener();
+            updateListening();
         }
 
         public void setDisabled(boolean disabled) {
             if (mDisabled == disabled) return;
             mDisabled = disabled;
-            updateListener();
+            updateListening();
         }
 
         public void ignoreSetting(boolean ignored) {
             if (mIgnoresSetting == ignored) return;
             mIgnoresSetting = ignored;
-            updateListener();
+            updateListening();
         }
 
-        public void updateListener() {
+        public void updateListening() {
             if (!mConfigured || mSensor == null) return;
             if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
                     && !mRegistered) {
@@ -420,14 +477,11 @@
             DozeLog.traceSensor(mContext, mPulseReason);
             mHandler.post(mWakeLock.wrap(() -> {
                 if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
-                boolean sensorPerformsProxCheck = false;
                 if (mSensor != null && mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
                     int subType = (int) event.values[0];
                     MetricsLogger.action(
                             mContext, MetricsProto.MetricsEvent.ACTION_AMBIENT_GESTURE,
                             subType);
-                    sensorPerformsProxCheck =
-                            mDozeParameters.getPickupSubtypePerformsProxCheck(subType);
                 }
 
                 mRegistered = false;
@@ -437,14 +491,23 @@
                     screenX = event.values[0];
                     screenY = event.values[1];
                 }
-                mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck, screenX, screenY,
+                mCallback.onSensorPulse(mPulseReason, mSensorPerformsProxCheck, screenX, screenY,
                         event.values);
                 if (!mRegistered) {
-                    updateListener();  // reregister, this sensor only fires once
+                    updateListening();  // reregister, this sensor only fires once
                 }
             }));
         }
 
+        /**
+         * If the sensor itself performs proximity checks, to avoid pocket dialing.
+         * Gated sensors don't need to be stopped when the {@link DozeMachine} is
+         * {@link DozeMachine.State#DOZE_AOD_PAUSED}.
+         */
+        public boolean performsProxCheck() {
+            return mSensorPerformsProxCheck;
+        }
+
         public void registerSettingsObserver(ContentObserver settingsObserver) {
             if (mConfigured && !TextUtils.isEmpty(mSetting)) {
                 mResolver.registerContentObserver(
@@ -492,7 +555,7 @@
         }
 
         @Override
-        public void updateListener() {
+        public void updateListening() {
             if (!mConfigured) return;
             AsyncSensorManager asyncSensorManager = (AsyncSensorManager) mSensorManager;
             if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 2db7306..e92acfc 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -25,23 +25,29 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.DozeServicePlugin;
 import com.android.systemui.plugins.DozeServicePlugin.RequestDoze;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.plugins.PluginManager;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+import javax.inject.Inject;
+
 public class DozeService extends DreamService
         implements DozeMachine.Service, RequestDoze, PluginListener<DozeServicePlugin> {
     private static final String TAG = "DozeService";
     static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private final FalsingManager mFalsingManager;
 
     private DozeMachine mDozeMachine;
     private DozeServicePlugin mDozePlugin;
     private PluginManager mPluginManager;
 
-    public DozeService() {
+    @Inject
+    public DozeService(FalsingManager falsingManager) {
         setDebug(DEBUG);
+        mFalsingManager = falsingManager;
     }
 
     @Override
@@ -56,7 +62,7 @@
         }
         mPluginManager = Dependency.get(PluginManager.class);
         mPluginManager.addPluginListener(this, DozeServicePlugin.class, false /* allowMultiple */);
-        mDozeMachine = new DozeFactory().assembleMachine(this);
+        mDozeMachine = new DozeFactory().assembleMachine(this, mFalsingManager);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index a381e7b..8ef01e8 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -107,9 +107,17 @@
     }
 
     private void onNotification() {
-        if (DozeMachine.DEBUG) Log.d(TAG, "requestNotificationPulse");
+        if (DozeMachine.DEBUG) {
+            Log.d(TAG, "requestNotificationPulse");
+        }
+        if (!sWakeDisplaySensorState) {
+            Log.d(TAG, "Wake display false. Pulse denied.");
+            return;
+        }
         mNotificationPulseTime = SystemClock.elapsedRealtime();
-        if (!mConfig.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) return;
+        if (!mConfig.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) {
+            return;
+        }
         requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */);
         DozeLog.traceNotificationPulse(mContext);
     }
@@ -193,7 +201,7 @@
             // Let's prepare the display to wake-up by drawing black.
             // This will cover the hardware wake-up sequence, where the display
             // becomes black for a few frames.
-            mDozeHost.setAodDimmingScrim(255f);
+            mDozeHost.setAodDimmingScrim(1f);
         }
         mMachine.wakeUp();
     }
@@ -216,15 +224,21 @@
         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);
+            if (DEBUG) {
+                Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
+            }
             mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
         }
 
         if (far && (paused || pausing)) {
-            if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
+            if (DEBUG) {
+                Log.i(TAG, "Prox FAR, unpausing AOD");
+            }
             mMachine.requestState(DozeMachine.State.DOZE_AOD);
         } else if (near && aod) {
-            if (DEBUG) Log.i(TAG, "Prox NEAR, pausing AOD");
+            if (DEBUG) {
+                Log.i(TAG, "Prox NEAR, pausing AOD");
+            }
             mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSING);
         }
     }
@@ -282,6 +296,7 @@
             case DOZE_AOD:
                 mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE);
                 mDozeSensors.setListening(true);
+                mDozeSensors.setPaused(false);
                 if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) {
                     onWakeScreen(false, newState);
                 }
@@ -289,15 +304,19 @@
             case DOZE_AOD_PAUSED:
             case DOZE_AOD_PAUSING:
                 mDozeSensors.setProxListening(true);
-                mDozeSensors.setListening(false);
+                mDozeSensors.setPaused(true);
                 break;
             case DOZE_PULSING:
             case DOZE_PULSING_BRIGHT:
                 mDozeSensors.setTouchscreenSensorsListening(false);
                 mDozeSensors.setProxListening(true);
+                mDozeSensors.setPaused(false);
                 break;
             case DOZE_PULSE_DONE:
                 mDozeSensors.requestTemporaryDisable();
+                // A pulse will temporarily disable sensors that require a touch screen.
+                // Let's make sure that they are re-enabled when the pulse is over.
+                mDozeSensors.updateListening();
                 break;
             case FINISH:
                 mBroadcastReceiver.unregister(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 51e96d2..1f33af8 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.doze;
 
+import static com.android.systemui.doze.DozeMachine.State.DOZE;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
 
 import android.app.AlarmManager;
@@ -116,7 +117,7 @@
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
         switch (newState) {
             case DOZE_AOD:
-                if (oldState == DOZE_AOD_PAUSED) {
+                if (oldState == DOZE_AOD_PAUSED || oldState == DOZE) {
                     // Whenever turning on the display, it's necessary to push a new frame.
                     // The display buffers will be empty and need to be filled.
                     mHost.dozeTimeTick();
@@ -130,6 +131,7 @@
                 break;
             case DOZE:
             case DOZE_AOD_PAUSED:
+                mHost.prepareForGentleWakeUp();
                 unscheduleTimeTick();
                 break;
             case DOZE_REQUEST_PULSE:
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
index 1b3cd88..35c8b74 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java
@@ -24,6 +24,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 
 import java.io.PrintWriter;
@@ -38,18 +39,22 @@
 
     private final IWallpaperManager mWallpaperManagerService;
     private final DozeParameters mDozeParameters;
+    private final BiometricUnlockController mBiometricUnlockController;
     private boolean mIsAmbientMode;
 
-    public DozeWallpaperState(Context context) {
+    public DozeWallpaperState(Context context,
+            BiometricUnlockController biometricUnlockController) {
         this(IWallpaperManager.Stub.asInterface(
                 ServiceManager.getService(Context.WALLPAPER_SERVICE)),
+                biometricUnlockController,
                 DozeParameters.getInstance(context));
     }
 
     @VisibleForTesting
     DozeWallpaperState(IWallpaperManager wallpaperManagerService,
-            DozeParameters parameters) {
+            BiometricUnlockController biometricUnlockController, DozeParameters parameters) {
         mWallpaperManagerService = wallpaperManagerService;
+        mBiometricUnlockController = biometricUnlockController;
         mDozeParameters = parameters;
     }
 
@@ -76,7 +81,9 @@
         } else {
             boolean wakingUpFromPulse = oldState == DozeMachine.State.DOZE_PULSING
                     && newState == DozeMachine.State.FINISH;
-            animated = !mDozeParameters.getDisplayNeedsBlanking() || wakingUpFromPulse;
+            boolean fastDisplay = !mDozeParameters.getDisplayNeedsBlanking();
+            animated = (fastDisplay && !mBiometricUnlockController.unlockedByWakeAndUnlock())
+                    || wakingUpFromPulse;
         }
 
         if (isAmbientMode != mIsAmbientMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
index 8dbaf0f..b4cc571 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
@@ -22,7 +22,7 @@
 
 import com.android.systemui.ConfigurationChangedReceiver;
 import com.android.systemui.Dumpable;
-import com.android.systemui.SystemUIFactory;
+import com.android.systemui.SystemUIRootComponent;
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.statusbar.phone.NavigationBarFragment;
 
@@ -51,7 +51,7 @@
     private final FragmentCreator mFragmentCreator;
 
     @Inject
-    public FragmentService(SystemUIFactory.SystemUIRootComponent rootComponent) {
+    public FragmentService(SystemUIRootComponent rootComponent) {
         mFragmentCreator = rootComponent.createFragmentCreator();
         initInjectionMap();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 4af21bc..df3f36e 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -551,7 +551,7 @@
 
     private class EmergencyDialerAction extends EmergencyAction {
         private EmergencyDialerAction() {
-            super(R.drawable.ic_faster_emergency,
+            super(com.android.systemui.R.drawable.ic_emergency_star,
                     R.string.global_action_emergency);
         }
 
@@ -1021,7 +1021,11 @@
         public boolean onLongClickItem(int position) {
             final Action action = mAdapter.getItem(position);
             if (action instanceof LongPressAction) {
-                mDialog.dismiss();
+                if (mDialog != null) {
+                    mDialog.dismiss();
+                } else {
+                    Log.w(TAG, "Action long-clicked while mDialog is null.");
+                }
                 return ((LongPressAction) action).onLongPress();
             }
             return false;
@@ -1031,9 +1035,13 @@
         public void onClickItem(int position) {
             Action item = mAdapter.getItem(position);
             if (!(item instanceof SilentModeTriStateAction)) {
-                mDialog.dismiss();
+                if (mDialog != null) {
+                    mDialog.dismiss();
+                } else {
+                    Log.w(TAG, "Action clicked while mDialog is null.");
+                }
+                item.onPress();
             }
-            item.onPress();
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 4065d5b..1f3403b 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -30,6 +30,7 @@
 import com.android.internal.R;
 import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.internal.colorextraction.drawable.ScrimDrawable;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.SysUiServiceProvider;
@@ -81,6 +82,7 @@
         mGlobalActions.showDialog(mKeyguardMonitor.isShowing(),
                 mDeviceProvisionedController.isDeviceProvisioned(),
                 mPanelExtension.get());
+        KeyguardUpdateMonitor.getInstance(mContext).requestFaceAuth();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
index 1744c4e..d7411260 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java
@@ -60,6 +60,9 @@
  */
 public class EglHelper {
     private static final String TAG = EglHelper.class.getSimpleName();
+    // Below two constants make drawing at low priority, so other things can preempt our drawing.
+    private static final int EGL_CONTEXT_PRIORITY_LEVEL_IMG = 0x3100;
+    private static final int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
 
     private EGLDisplay mEglDisplay;
     private EGLConfig mEglConfig;
@@ -181,7 +184,8 @@
      * @return true if EglContext is ready.
      */
     public boolean createEglContext() {
-        int[] attrib_list = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+        int[] attrib_list = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2,
+                EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_LOW_IMG, EGL_NONE};
         mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list, 0);
         if (mEglContext == EGL_NO_CONTEXT) {
             Log.w(TAG, "eglCreateContext failed: " + GLUtils.getEGLErrorString(eglGetError()));
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
index 5d85cbf..60ea1cd 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
@@ -17,7 +17,6 @@
 package com.android.systemui.glwallpaper;
 
 import android.util.Size;
-import android.view.SurfaceHolder;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -52,6 +51,13 @@
     void updateAmbientMode(boolean inAmbientMode, long duration);
 
     /**
+     * Notify the wallpaper offsets changed.
+     * @param xOffset offset along x axis.
+     * @param yOffset offset along y axis.
+     */
+    void updateOffsets(float xOffset, float yOffset);
+
+    /**
      * Ask renderer to report the surface size it needs.
      */
     Size reportSurfaceSize();
@@ -76,12 +82,6 @@
     interface SurfaceProxy {
 
         /**
-         * Get surface holder.
-         * @return surface holder.
-         */
-        SurfaceHolder getHolder();
-
-        /**
          * Ask proxy to start rendering frame to surface.
          */
         void requestRender();
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index 4be7623..626d0cf 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -33,9 +33,12 @@
 import static android.opengl.GLES20.glVertexAttribPointer;
 
 import android.graphics.Bitmap;
+import android.graphics.Rect;
 import android.opengl.GLUtils;
 import android.util.Log;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.FloatBuffer;
@@ -91,6 +94,8 @@
     private int mUniTexture;
     private int mTextureId;
 
+    private float[] mCurrentTexCoordinate;
+
     ImageGLWallpaper(ImageGLProgram program) {
         mProgram = program;
 
@@ -195,4 +200,106 @@
         glUniform1i(mUniTexture, 0);
     }
 
+    /**
+     * This method adjust s(x-axis), t(y-axis) texture coordinates to get current display area
+     * of texture and will be used during transition.
+     * The adjustment happens if either the width or height of the surface is larger than
+     * corresponding size of the display area.
+     * If both width and height are larger than corresponding size of the display area,
+     * the adjustment will happen at both s, t side.
+     *
+     * @param surface The size of the surface.
+     * @param scissor The display area.
+     * @param xOffset The offset amount along s axis.
+     * @param yOffset The offset amount along t axis.
+     */
+    void adjustTextureCoordinates(Rect surface, Rect scissor, float xOffset, float yOffset) {
+        mCurrentTexCoordinate = TEXTURES.clone();
+
+        if (surface == null || scissor == null) {
+            mTextureBuffer.put(mCurrentTexCoordinate);
+            mTextureBuffer.position(0);
+            return;
+        }
+
+        int surfaceWidth = surface.width();
+        int surfaceHeight = surface.height();
+        int scissorWidth = scissor.width();
+        int scissorHeight = scissor.height();
+
+        if (surfaceWidth > scissorWidth) {
+            // Calculate the new s pos in pixels.
+            float pixelS = (float) Math.round((surfaceWidth - scissorWidth) * xOffset);
+            // Calculate the s pos in texture coordinate.
+            float coordinateS = pixelS / surfaceWidth;
+            // Calculate the percentage occupied by the scissor width in surface width.
+            float surfacePercentageW = (float) scissorWidth / surfaceWidth;
+            // Need also consider the case if surface height is smaller than scissor height.
+            if (surfaceHeight < scissorHeight) {
+                // We will narrow the surface percentage to keep aspect ratio.
+                surfacePercentageW *= (float) surfaceHeight / scissorHeight;
+            }
+            // Determine the final s pos, also limit the legal s pos to prevent from out of range.
+            float s = coordinateS + surfacePercentageW > 1f ? 1f - surfacePercentageW : coordinateS;
+            // Traverse the s pos in texture coordinates array and adjust the s pos accordingly.
+            for (int i = 0; i < mCurrentTexCoordinate.length; i += 2) {
+                // indices 2, 4 and 6 are the end of s coordinates.
+                if (i == 2 || i == 4 || i == 6) {
+                    mCurrentTexCoordinate[i] = Math.min(1f, s + surfacePercentageW);
+                } else {
+                    mCurrentTexCoordinate[i] = s;
+                }
+            }
+        }
+
+        if (surfaceHeight > scissorHeight) {
+            // Calculate the new t pos in pixels.
+            float pixelT = (float) Math.round((surfaceHeight - scissorHeight) * yOffset);
+            // Calculate the t pos in texture coordinate.
+            float coordinateT = pixelT / surfaceHeight;
+            // Calculate the percentage occupied by the scissor height in surface height.
+            float surfacePercentageH = (float) scissorHeight / surfaceHeight;
+            // Need also consider the case if surface width is smaller than scissor width.
+            if (surfaceWidth < scissorWidth) {
+                // We will narrow the surface percentage to keep aspect ratio.
+                surfacePercentageH *= (float) surfaceWidth / scissorWidth;
+            }
+            // Determine the final t pos, also limit the legal t pos to prevent from out of range.
+            float t = coordinateT + surfacePercentageH > 1f ? 1f - surfacePercentageH : coordinateT;
+            // Traverse the t pos in texture coordinates array and adjust the t pos accordingly.
+            for (int i = 1; i < mCurrentTexCoordinate.length; i += 2) {
+                // indices 1, 3 and 11 are the end of t coordinates.
+                if (i == 1 || i == 3 || i == 11) {
+                    mCurrentTexCoordinate[i] = Math.min(1f, t + surfacePercentageH);
+                } else {
+                    mCurrentTexCoordinate[i] = t;
+                }
+            }
+        }
+
+        mTextureBuffer.put(mCurrentTexCoordinate);
+        mTextureBuffer.position(0);
+    }
+
+    /**
+     * Called to dump current state.
+     * @param prefix prefix.
+     * @param fd fd.
+     * @param out out.
+     * @param args args.
+     */
+    public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
+        StringBuilder sb = new StringBuilder();
+        sb.append('{');
+        if (mCurrentTexCoordinate != null) {
+            for (int i = 0; i < mCurrentTexCoordinate.length; i++) {
+                sb.append(mCurrentTexCoordinate[i]).append(',');
+                if (i == mCurrentTexCoordinate.length - 1) {
+                    sb.deleteCharAt(sb.length() - 1);
+                }
+            }
+        }
+        sb.append('}');
+        out.print(prefix); out.print("mTexCoordinates="); out.println(sb.toString());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
index 6a1f24a..45e97b3 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageRevealHelper.java
@@ -84,7 +84,17 @@
     void updateAwake(boolean awake, long duration) {
         mAwake = awake;
         mAnimator.setDuration(duration);
-        animate();
+        if (!mAwake && duration == 0) {
+            // We are transiting from home to aod,
+            // since main thread is waiting for rendering finished, we only need draw
+            // the last state directly, which is a black screen.
+            mReveal = MIN_REVEAL;
+            mRevealListener.onRevealStart();
+            mRevealListener.onRevealStateChanged();
+            mRevealListener.onRevealEnd();
+        } else {
+            animate();
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index 21711fb..93d8dd6 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -29,6 +29,8 @@
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.Size;
+import android.view.DisplayInfo;
+import android.view.WindowManager;
 
 import com.android.systemui.R;
 
@@ -41,8 +43,8 @@
 public class ImageWallpaperRenderer implements GLWallpaperRenderer,
         ImageRevealHelper.RevealStateListener {
     private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
-    private static final float SCALE_VIEWPORT_MIN = 0.98f;
-    private static final float SCALE_VIEWPORT_MAX = 1f;
+    private static final float SCALE_VIEWPORT_MIN = 1f;
+    private static final float SCALE_VIEWPORT_MAX = 1.1f;
 
     private final WallpaperManager mWallpaperManager;
     private final ImageGLProgram mProgram;
@@ -51,8 +53,13 @@
     private final ImageRevealHelper mImageRevealHelper;
 
     private SurfaceProxy mProxy;
-    private Rect mSurfaceSize;
+    private final Rect mScissor;
+    private final Rect mSurfaceSize = new Rect();
+    private final Rect mViewport = new Rect();
     private Bitmap mBitmap;
+    private boolean mScissorMode;
+    private float mXOffset;
+    private float mYOffset;
 
     public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
         mWallpaperManager = context.getSystemService(WallpaperManager.class);
@@ -60,6 +67,11 @@
             Log.w(TAG, "WallpaperManager not available");
         }
 
+        DisplayInfo displayInfo = new DisplayInfo();
+        WindowManager wm = context.getSystemService(WindowManager.class);
+        wm.getDefaultDisplay().getDisplayInfo(displayInfo);
+        mScissor = new Rect(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
+
         mProxy = proxy;
         mProgram = new ImageGLProgram(context);
         mWallpaper = new ImageGLWallpaper(mProgram);
@@ -91,7 +103,7 @@
             mBitmap = mWallpaperManager.getBitmap();
             mWallpaperManager.forgetLoadedWallpaper();
             if (mBitmap != null) {
-                mSurfaceSize = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+                mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
             }
         }
         return mBitmap != null;
@@ -107,13 +119,17 @@
         float threshold = mImageProcessHelper.getThreshold();
         float reveal = mImageRevealHelper.getReveal();
 
-        glClear(GL_COLOR_BUFFER_BIT);
-
         glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
         glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), threshold);
         glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
 
-        scaleViewport(reveal);
+        glClear(GL_COLOR_BUFFER_BIT);
+        // We only need to scale viewport while doing transition.
+        if (mScissorMode) {
+            scaleViewport(reveal);
+        } else {
+            glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
+        }
         mWallpaper.useTexture();
         mWallpaper.draw();
     }
@@ -124,6 +140,15 @@
     }
 
     @Override
+    public void updateOffsets(float xOffset, float yOffset) {
+        mXOffset = xOffset;
+        mYOffset = yOffset;
+        int left = (int) ((mSurfaceSize.width() - mScissor.width()) * xOffset);
+        int right = left + mScissor.width();
+        mScissor.set(left, mScissor.top, right, mScissor.bottom);
+    }
+
+    @Override
     public Size reportSurfaceSize() {
         return new Size(mSurfaceSize.width(), mSurfaceSize.height());
     }
@@ -134,15 +159,18 @@
     }
 
     private void scaleViewport(float reveal) {
-        int width = mSurfaceSize.width();
-        int height = mSurfaceSize.height();
+        int left = mScissor.left;
+        int top = mScissor.top;
+        int width = mScissor.width();
+        int height = mScissor.height();
         // Interpolation between SCALE_VIEWPORT_MAX and SCALE_VIEWPORT_MIN by reveal.
-        float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MAX, SCALE_VIEWPORT_MIN, reveal);
+        float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MIN, SCALE_VIEWPORT_MAX, reveal);
         // Calculate the offset amount from the lower left corner.
-        float offset = (SCALE_VIEWPORT_MAX - vpScaled) / 2;
+        float offset = (SCALE_VIEWPORT_MIN - vpScaled) / 2;
         // Change the viewport.
-        glViewport((int) (width * offset), (int) (height * offset),
+        mViewport.set((int) (left + width * offset), (int) (top + height * offset),
                 (int) (width * vpScaled), (int) (height * vpScaled));
+        glViewport(mViewport.left, mViewport.top, mViewport.right, mViewport.bottom);
     }
 
     @Override
@@ -152,11 +180,19 @@
 
     @Override
     public void onRevealStart() {
+        mScissorMode = true;
+        // Use current display area of texture.
+        mWallpaper.adjustTextureCoordinates(mSurfaceSize, mScissor, mXOffset, mYOffset);
         mProxy.preRender();
     }
 
     @Override
     public void onRevealEnd() {
+        mScissorMode = false;
+        // reset texture coordinates to use full texture.
+        mWallpaper.adjustTextureCoordinates(null, null, 0, 0);
+        // We need draw full texture back before finishing render.
+        mProxy.requestRender();
         mProxy.postRender();
     }
 
@@ -164,6 +200,12 @@
     public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
         out.print(prefix); out.print("mProxy="); out.print(mProxy);
         out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
+        out.print(prefix); out.print("mScissor="); out.print(mScissor);
+        out.print(prefix); out.print("mViewport="); out.print(mViewport);
+        out.print(prefix); out.print("mScissorMode="); out.print(mScissorMode);
+        out.print(prefix); out.print("mXOffset="); out.print(mXOffset);
+        out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
         out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
+        mWallpaper.dump(prefix, fd, out, args);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index d4c7366..5136682 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -52,6 +52,8 @@
 import com.android.systemui.R;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.NextAlarmController;
 import com.android.systemui.statusbar.policy.NextAlarmControllerImpl;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -102,22 +104,27 @@
     private final Date mCurrentTime = new Date();
     private final Handler mHandler;
     private final AlarmManager.OnAlarmListener mUpdateNextAlarm = this::updateNextAlarm;
-    private final HashSet<Integer> mMediaInvisibleStates;
     private final Object mMediaToken = new Object();
-    private SettableWakeLock mMediaWakeLock;
-    private ZenModeController mZenModeController;
+    private DozeParameters mDozeParameters;
+    @VisibleForTesting
+    protected SettableWakeLock mMediaWakeLock;
+    @VisibleForTesting
+    protected ZenModeController mZenModeController;
     private String mDatePattern;
     private DateFormat mDateFormat;
     private String mLastText;
     private boolean mRegistered;
     private String mNextAlarm;
     private NextAlarmController mNextAlarmController;
+    @VisibleForTesting
     protected AlarmManager mAlarmManager;
+    @VisibleForTesting
     protected ContentResolver mContentResolver;
     private AlarmManager.AlarmClockInfo mNextAlarmInfo;
     private PendingIntent mPendingIntent;
     protected NotificationMediaManager mMediaManager;
     private StatusBarStateController mStatusBarStateController;
+    private KeyguardBypassController mKeyguardBypassController;
     private CharSequence mMediaTitle;
     private CharSequence mMediaArtist;
     protected boolean mDozing;
@@ -178,11 +185,6 @@
         mAlarmUri = Uri.parse(KEYGUARD_NEXT_ALARM_URI);
         mDndUri = Uri.parse(KEYGUARD_DND_URI);
         mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI);
-
-        mMediaInvisibleStates = new HashSet<>();
-        mMediaInvisibleStates.add(PlaybackState.STATE_NONE);
-        mMediaInvisibleStates.add(PlaybackState.STATE_STOPPED);
-        mMediaInvisibleStates.add(PlaybackState.STATE_PAUSED);
     }
 
     /**
@@ -194,11 +196,15 @@
      */
     public void initDependencies(
             NotificationMediaManager mediaManager,
-            StatusBarStateController statusBarStateController) {
+            StatusBarStateController statusBarStateController,
+            KeyguardBypassController keyguardBypassController,
+            DozeParameters dozeParameters) {
         mMediaManager = mediaManager;
         mMediaManager.addCallback(this);
         mStatusBarStateController = statusBarStateController;
         mStatusBarStateController.addCallback(this);
+        mKeyguardBypassController = keyguardBypassController;
+        mDozeParameters = dozeParameters;
     }
 
     @AnyThread
@@ -223,7 +229,9 @@
     }
 
     protected boolean needsMediaLocked() {
-        return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && mDozing;
+        boolean keepWhenAwake = mKeyguardBypassController != null
+                && mKeyguardBypassController.getBypassEnabled() && mDozeParameters.getAlwaysOn();
+        return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && (mDozing || keepWhenAwake);
     }
 
     protected void addMediaLocked(ListBuilder listBuilder) {
@@ -297,22 +305,44 @@
 
     @Override
     public boolean onCreateSliceProvider() {
-        mAlarmManager = getContext().getSystemService(AlarmManager.class);
-        mContentResolver = getContext().getContentResolver();
-        mNextAlarmController = new NextAlarmControllerImpl(getContext());
-        mNextAlarmController.addCallback(this);
-        mZenModeController = new ZenModeControllerImpl(getContext(), mHandler);
-        mZenModeController.addCallback(this);
-        mDatePattern = getContext().getString(R.string.system_ui_aod_date_pattern);
-        mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
-        mMediaWakeLock = new SettableWakeLock(WakeLock.createPartial(getContext(), "media"),
-                "media");
-        KeyguardSliceProvider.sInstance = this;
-        registerClockUpdate();
-        updateClockLocked();
+        synchronized (this) {
+            KeyguardSliceProvider oldInstance = KeyguardSliceProvider.sInstance;
+            if (oldInstance != null) {
+                oldInstance.onDestroy();
+            }
+
+            mAlarmManager = getContext().getSystemService(AlarmManager.class);
+            mContentResolver = getContext().getContentResolver();
+            mNextAlarmController = new NextAlarmControllerImpl(getContext());
+            mNextAlarmController.addCallback(this);
+            mZenModeController = new ZenModeControllerImpl(getContext(), mHandler);
+            mZenModeController.addCallback(this);
+            mDatePattern = getContext().getString(R.string.system_ui_aod_date_pattern);
+            mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
+            mMediaWakeLock = new SettableWakeLock(WakeLock.createPartial(getContext(), "media"),
+                    "media");
+            KeyguardSliceProvider.sInstance = this;
+            registerClockUpdate();
+            updateClockLocked();
+        }
         return true;
     }
 
+    @VisibleForTesting
+    protected void onDestroy() {
+        synchronized (this) {
+            mNextAlarmController.removeCallback(this);
+            mZenModeController.removeCallback(this);
+            mMediaWakeLock.setAcquired(false);
+            mAlarmManager.cancel(mUpdateNextAlarm);
+            if (mRegistered) {
+                mRegistered = false;
+                getKeyguardUpdateMonitor().removeCallback(mKeyguardUpdateMonitorCallback);
+                getContext().unregisterReceiver(mIntentReceiver);
+            }
+        }
+    }
+
     @Override
     public void onZenChanged(int zen) {
         notifyChange();
@@ -350,7 +380,8 @@
      * Registers a broadcast receiver for clock updates, include date, time zone and manually
      * changing the date/time via the settings app.
      */
-    private void registerClockUpdate() {
+    @VisibleForTesting
+    protected void registerClockUpdate() {
         synchronized (this) {
             if (mRegistered) {
                 return;
@@ -425,7 +456,7 @@
     @Override
     public void onMetadataOrStateChanged(MediaMetadata metadata, @PlaybackState.State int state) {
         synchronized (this) {
-            boolean nextVisible = !mMediaInvisibleStates.contains(state);
+            boolean nextVisible = NotificationMediaManager.isPlayingState(state);
             mHandler.removeCallbacksAndMessages(mMediaToken);
             if (mMediaIsVisible && !nextVisible) {
                 // We need to delay this event for a few millis when stopping to avoid jank in the
@@ -444,7 +475,7 @@
     }
 
     private void updateMediaStateLocked(MediaMetadata metadata, @PlaybackState.State int state) {
-        boolean nextVisible = !mMediaInvisibleStates.contains(state);
+        boolean nextVisible = NotificationMediaManager.isPlayingState(state);
         CharSequence title = null;
         if (metadata != null) {
             title = metadata.getText(MediaMetadata.METADATA_KEY_TITLE);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index ec6cfe9..6b2721a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -61,6 +61,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManagerPolicyConstants;
 import android.view.animation.Animation;
@@ -83,8 +84,9 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.classifier.FalsingManagerFactory;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -174,7 +176,7 @@
     /**
      * The default amount of time we stay awake (used for all key input)
      */
-    public static final int AWAKE_INTERVAL_DEFAULT_MS = 10000;
+    public static final int AWAKE_INTERVAL_BOUNCER_MS = 10000;
 
     /**
      * How long to wait after the screen turns off due to timeout before
@@ -208,6 +210,7 @@
     private boolean mBootCompleted;
     private boolean mBootSendUserPresent;
     private boolean mShuttingDown;
+    private boolean mDozing;
 
     /** High level access to the power manager for WakeLocks */
     private PowerManager mPM;
@@ -711,11 +714,10 @@
                 com.android.keyguard.R.bool.config_enableKeyguardService)) {
             setShowingLocked(!shouldWaitForProvisioning()
                     && !mLockPatternUtils.isLockScreenDisabled(
-                            KeyguardUpdateMonitor.getCurrentUser()),
-                    mAodShowing, true /* forceCallbacks */);
+                            KeyguardUpdateMonitor.getCurrentUser()), true /* forceCallbacks */);
         } else {
             // The system's keyguard is disabled or missing.
-            setShowingLocked(false, mAodShowing, true);
+            setShowingLocked(false /* showing */, true /* forceCallbacks */);
         }
 
         mStatusBarKeyguardViewManager =
@@ -1324,7 +1326,7 @@
             if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
                 if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
                 // Without this, settings is not enabled until the lock screen first appears
-                setShowingLocked(false, mAodShowing);
+                setShowingLocked(false);
                 hideLocked();
                 return;
             }
@@ -1594,7 +1596,7 @@
                     Trace.beginSection("KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM");
                     StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj;
                     handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration);
-                    FalsingManagerFactory.getInstance(mContext).onSucccessfulUnlock();
+                    Dependency.get(FalsingManager.class).onSucccessfulUnlock();
                     Trace.endSection();
                     break;
                 case KEYGUARD_DONE_PENDING_TIMEOUT:
@@ -1740,6 +1742,9 @@
 
     private void updateActivityLockScreenState(boolean showing, boolean aodShowing) {
         mUiOffloadThread.submit(() -> {
+            if (DEBUG) {
+                Log.d(TAG, "updateActivityLockScreenState(" + showing + ", " + aodShowing + ")");
+            }
             try {
                 ActivityTaskManager.getService().setLockScreenShown(showing, aodShowing);
             } catch (RemoteException e) {
@@ -1765,10 +1770,10 @@
                 if (DEBUG) Log.d(TAG, "handleShow");
             }
 
-            setShowingLocked(true, mAodShowing);
-            mStatusBarKeyguardViewManager.show(options);
             mHiding = false;
             mWakeAndUnlocking = false;
+            setShowingLocked(true);
+            mStatusBarKeyguardViewManager.show(options);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
@@ -1800,6 +1805,10 @@
             if (mStatusBarKeyguardViewManager.isUnlockWithWallpaper()) {
                 flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
             }
+            if (mStatusBarKeyguardViewManager.shouldSubtleWindowAnimationsForUnlock()) {
+                flags |= WindowManagerPolicyConstants
+                        .KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
+            }
 
             mUpdateMonitor.setKeyguardGoingAway(true /* goingAway */);
 
@@ -1871,7 +1880,7 @@
 
             if (!mHiding) {
                 // Tell ActivityManager that we canceled the keyguardExitAnimation.
-                setShowingLocked(mShowing, mAodShowing, true /* force */);
+                setShowingLocked(mShowing, true /* force */);
                 return;
             }
             mHiding = false;
@@ -1892,8 +1901,8 @@
                 playSounds(false);
             }
 
+            setShowingLocked(false);
             mWakeAndUnlocking = false;
-            setShowingLocked(false, mAodShowing);
             mDismissCallbackRegistry.notifyDismissSucceeded();
             mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
             resetKeyguardDonePendingLocked();
@@ -1930,12 +1939,6 @@
                         +  " --> flags=0x" + Integer.toHexString(flags));
             }
 
-            // TODO(b/113914868): investigation log for disappearing home button
-            Log.d(TAG, "adjustStatusBarLocked (b/113914868): flags=" + flags
-                    + "mShowing=" + mShowing + " mStatusBarManager=" + mStatusBarManager
-                    + " mOccluded=" + mOccluded + " isSecure=" + isSecure()
-                    + " force=" + forceHideHomeRecentsButtons);
-
             mStatusBarManager.disable(flags);
         }
     }
@@ -1959,7 +1962,7 @@
         Trace.beginSection("KeyguardViewMediator#handleVerifyUnlock");
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
-            setShowingLocked(true, mAodShowing);
+            setShowingLocked(true);
             mStatusBarKeyguardViewManager.dismissAndCollapse();
         }
         Trace.endSection();
@@ -2062,9 +2065,12 @@
 
     public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar,
             ViewGroup container, NotificationPanelView panelView,
-            BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer) {
+            BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer,
+            View notificationContainer, KeyguardBypassController bypassController,
+            FalsingManager falsingManager) {
         mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView,
-                biometricUnlockController, mDismissCallbackRegistry, lockIconContainer);
+                biometricUnlockController, mDismissCallbackRegistry, lockIconContainer,
+                notificationContainer, bypassController, falsingManager);
         return mStatusBarKeyguardViewManager;
     }
 
@@ -2104,6 +2110,8 @@
         pw.print("  mDeviceInteractive: "); pw.println(mDeviceInteractive);
         pw.print("  mGoingToSleep: "); pw.println(mGoingToSleep);
         pw.print("  mHiding: "); pw.println(mHiding);
+        pw.print("  mDozing: "); pw.println(mDozing);
+        pw.print("  mAodShowing: "); pw.println(mAodShowing);
         pw.print("  mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible);
         pw.print("  mKeyguardDonePending: "); pw.println(mKeyguardDonePending);
         pw.print("  mHideAnimationRun: "); pw.println(mHideAnimationRun);
@@ -2114,10 +2122,14 @@
     }
 
     /**
-     * @param aodShowing true when AOD - or ambient mode - is showing.
+     * @param dozing true when AOD - or ambient mode - is showing.
      */
-    public void setAodShowing(boolean aodShowing) {
-        setShowingLocked(mShowing, aodShowing);
+    public void setDozing(boolean dozing) {
+        if (dozing == mDozing) {
+            return;
+        }
+        mDozing = dozing;
+        setShowingLocked(mShowing);
     }
 
     /**
@@ -2138,19 +2150,18 @@
         }
     }
 
-    private void setShowingLocked(boolean showing, boolean aodShowing) {
-        setShowingLocked(showing, aodShowing, false /* forceCallbacks */);
+    private void setShowingLocked(boolean showing) {
+        setShowingLocked(showing, false /* forceCallbacks */);
     }
 
-    private void setShowingLocked(boolean showing, boolean aodShowing, boolean forceCallbacks) {
+    private void setShowingLocked(boolean showing, boolean forceCallbacks) {
+        final boolean aodShowing = mDozing && !mWakeAndUnlocking;
         final boolean notifyDefaultDisplayCallbacks = showing != mShowing
                 || aodShowing != mAodShowing || forceCallbacks;
+        mShowing = showing;
+        mAodShowing = aodShowing;
         if (notifyDefaultDisplayCallbacks) {
-            mShowing = showing;
-            mAodShowing = aodShowing;
-            if (notifyDefaultDisplayCallbacks) {
-                notifyDefaultDisplayCallbacks(showing);
-            }
+            notifyDefaultDisplayCallbacks(showing);
             updateActivityLockScreenState(showing, aodShowing);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 86ce60d..21f5812 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -69,7 +69,7 @@
 import android.view.WindowManager.LayoutParams;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
+import android.widget.ImageButton;
 import android.widget.LinearLayout;
 
 import com.android.systemui.Interpolators;
@@ -115,7 +115,6 @@
     private LinearLayout mActionsGroup;
     private View mSettingsButton;
     private View mDismissButton;
-    private ImageView mExpandButton;
     private int mBetweenActionPaddingLand;
 
     private AnimatorSet mMenuContainerAnimator;
@@ -240,13 +239,11 @@
         });
         mDismissButton = findViewById(R.id.dismiss);
         mDismissButton.setAlpha(0);
-        mDismissButton.setOnClickListener((v) -> {
-            dismissPip();
-        });
+        mDismissButton.setOnClickListener(v -> dismissPip());
+        findViewById(R.id.expand_button).setOnClickListener(v -> expandPip());
         mActionsGroup = findViewById(R.id.actions_group);
         mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
                 R.dimen.pip_between_action_padding_land);
-        mExpandButton = findViewById(R.id.expand_button);
 
         updateFromIntent(getIntent());
         setTitle(R.string.pip_menu_title);
@@ -482,7 +479,7 @@
                 // Ensure we have as many buttons as actions
                 final LayoutInflater inflater = LayoutInflater.from(this);
                 while (mActionsGroup.getChildCount() < mActions.size()) {
-                    final ImageView actionView = (ImageView) inflater.inflate(
+                    final ImageButton actionView = (ImageButton) inflater.inflate(
                             R.layout.pip_menu_action, mActionsGroup, false);
                     mActionsGroup.addView(actionView);
                 }
@@ -499,7 +496,7 @@
                         (stackBounds.width() > stackBounds.height());
                 for (int i = 0; i < mActions.size(); i++) {
                     final RemoteAction action = mActions.get(i);
-                    final ImageView actionView = (ImageView) mActionsGroup.getChildAt(i);
+                    final ImageButton actionView = (ImageButton) mActionsGroup.getChildAt(i);
 
                     // TODO: Check if the action drawable has changed before we reload it
                     action.getIcon().loadDrawableAsync(this, d -> {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index 46d53e4..14459d6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -414,6 +414,7 @@
             if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
                     pinnedStackInfo.taskIds.length > 0) {
                 Intent intent = new Intent(mContext, PipMenuActivity.class);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 intent.putExtra(EXTRA_CONTROLLER_MESSENGER, mMessenger);
                 intent.putExtra(EXTRA_ACTIONS, resolveMenuActions());
                 if (stackBounds != null) {
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 3ec6cb7..b05058a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -125,6 +125,7 @@
     private int mImeOffset;
     private boolean mIsShelfShowing;
     private int mShelfHeight;
+    private int mMovementBoundsExtraOffsets;
     private float mSavedSnapFraction = -1f;
     private boolean mSendingHoverAccessibilityEvents;
     private boolean mMovementWithinMinimize;
@@ -262,7 +263,7 @@
         mShelfHeight = shelfHeight;
     }
 
-    public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect animatingBounds,
+    public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds,
             boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) {
         final int bottomOffset = mIsImeShowing ? mImeHeight : 0;
 
@@ -283,6 +284,12 @@
         mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds,
                 bottomOffset);
 
+        // The extra offset does not really affect the movement bounds, but are applied based on the
+        // current state (ime showing, or shelf offset) when we need to actually shift
+        int extraOffset = Math.max(
+                mIsImeShowing ? mImeOffset : 0,
+                !mIsImeShowing && mIsShelfShowing ? mShelfHeight : 0);
+
         // If this is from an IME or shelf adjustment, then we should move the PiP so that it is not
         // occluded by the IME or shelf.
         if (fromImeAdjustment || fromShelfAdjustment) {
@@ -290,41 +297,19 @@
                 // Defer the update of the current movement bounds until after the user finishes
                 // touching the screen
             } else {
-                final int adjustedOffset = Math.max(mIsImeShowing ? mImeHeight + mImeOffset : 0,
-                        mIsShelfShowing ? mShelfHeight : 0);
-                Rect normalAdjustedBounds = new Rect();
-                mSnapAlgorithm.getMovementBounds(mNormalBounds, insetBounds, normalAdjustedBounds,
-                        adjustedOffset);
-                Rect expandedAdjustedBounds = new Rect();
-                mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds,
-                        expandedAdjustedBounds, adjustedOffset);
-                final Rect toAdjustedBounds = mMenuState == MENU_STATE_FULL
-                        ? expandedAdjustedBounds
-                        : normalAdjustedBounds;
-                final Rect toMovementBounds = mMenuState == MENU_STATE_FULL
-                        ? expandedMovementBounds
-                        : normalMovementBounds;
-
-                // If the PIP window needs to shift to right above shelf/IME and it's already above
-                // that, don't move the PIP window.
-                if (toAdjustedBounds.bottom < mMovementBounds.bottom
-                        && animatingBounds.top < toAdjustedBounds.bottom) {
-                    return;
-                }
-
-                // If the PIP window needs to shift down due to dismissal of shelf/IME but it's way
-                // above the position as if shelf/IME shows, don't move the PIP window.
-                int movementBoundsAdjustment = toMovementBounds.bottom - mMovementBounds.bottom;
-                int offsetAdjustment = fromImeAdjustment ? mImeOffset : mShelfHeight;
-                final float bottomOffsetBufferInPx = BOTTOM_OFFSET_BUFFER_DP
+                final float offsetBufferPx = BOTTOM_OFFSET_BUFFER_DP
                         * mContext.getResources().getDisplayMetrics().density;
-                if (toAdjustedBounds.bottom >= mMovementBounds.bottom
-                        && animatingBounds.top + Math.round(bottomOffsetBufferInPx)
-                        < toAdjustedBounds.bottom - movementBoundsAdjustment - offsetAdjustment) {
-                    return;
+                final Rect toMovementBounds = mMenuState == MENU_STATE_FULL
+                        ? new Rect(expandedMovementBounds)
+                        : new Rect(normalMovementBounds);
+                final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets;
+                final int toBottom = toMovementBounds.bottom < toMovementBounds.top
+                        ? toMovementBounds.bottom
+                        : toMovementBounds.bottom - extraOffset;
+                if ((Math.min(prevBottom, toBottom) - offsetBufferPx) <= curBounds.top
+                        && curBounds.top <= (Math.max(prevBottom, toBottom) + offsetBufferPx)) {
+                    mMotionHelper.animateToOffset(curBounds, toBottom - curBounds.top);
                 }
-
-                animateToOffset(animatingBounds, toAdjustedBounds);
             }
         }
 
@@ -335,6 +320,7 @@
         mDisplayRotation = displayRotation;
         mInsetBounds.set(insetBounds);
         updateMovementBounds(mMenuState);
+        mMovementBoundsExtraOffsets = extraOffset;
 
         // If we have a deferred resize, apply it now
         if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) {
@@ -346,14 +332,6 @@
         }
     }
 
-    private void animateToOffset(Rect animatingBounds, Rect toAdjustedBounds) {
-        int offset = toAdjustedBounds.bottom - animatingBounds.top;
-        // In landscape mode, PIP window can go offset while launching IME. We want to align the
-        // the top of the PIP window with the top of the movement bounds in that case.
-        offset += Math.max(0, mMovementBounds.top - animatingBounds.top);
-        mMotionHelper.animateToOffset(animatingBounds, offset);
-    }
-
     private void onRegistrationChanged(boolean isRegistered) {
         mAccessibilityManager.setPictureInPictureActionReplacingConnection(isRegistered
                 ? new PipAccessibilityInteractionConnection(mMotionHelper,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index e22a21a..991d9fa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -244,7 +244,9 @@
 
     private void emptyAndInflateOrRemovePages() {
         final int nTiles = mTiles.size();
-        int numPages = nTiles / mPages.get(0).maxTiles();
+        // We should always have at least one page, even if it's empty.
+        int numPages = Math.max(nTiles / mPages.get(0).maxTiles(), 1);
+
         // Add one more not full page if needed
         numPages += (nTiles % mPages.get(0).maxTiles() == 0 ? 0 : 1);
 
@@ -434,11 +436,14 @@
         }
 
         public boolean isFull() {
-            return mRecords.size() >= mColumns * mRows;
+            return mRecords.size() >= maxTiles();
         }
 
         public int maxTiles() {
-            return mColumns * mRows;
+            // Each page should be able to hold at least one tile. If there's not enough room to
+            // show even 1 or there are no tiles, it probably means we are in the middle of setting
+            // up.
+            return Math.max(mColumns * mRows, 1);
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index ec2feba8..41f66f7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -73,6 +73,7 @@
     private int mNumQuickTiles;
     private float mLastPosition;
     private QSTileHost mHost;
+    private boolean mShowCollapsedOnKeyguard;
 
     public QSAnimator(QS qs, QuickQSPanel quickPanel, QSPanel panel) {
         mQs = qs;
@@ -98,12 +99,32 @@
 
     public void setOnKeyguard(boolean onKeyguard) {
         mOnKeyguard = onKeyguard;
-        mQuickQsPanel.setVisibility(mOnKeyguard ? View.INVISIBLE : View.VISIBLE);
+        updateQQSVisibility();
         if (mOnKeyguard) {
             clearAnimationState();
         }
     }
 
+
+    /**
+     * Sets whether or not the keyguard is currently being shown with a collapsed header.
+     */
+    void setShowCollapsedOnKeyguard(boolean showCollapsedOnKeyguard) {
+        mShowCollapsedOnKeyguard = showCollapsedOnKeyguard;
+        updateQQSVisibility();
+        setCurrentPosition();
+    }
+
+
+    private void setCurrentPosition() {
+        setPosition(mLastPosition);
+    }
+
+    private void updateQQSVisibility() {
+        mQuickQsPanel.setVisibility(mOnKeyguard
+                && !mShowCollapsedOnKeyguard ? View.INVISIBLE : View.VISIBLE);
+    }
+
     public void setHost(QSTileHost qsh) {
         mHost = qsh;
         qsh.addCallback(this);
@@ -322,7 +343,11 @@
     public void setPosition(float position) {
         if (mFirstPageAnimator == null) return;
         if (mOnKeyguard) {
-            return;
+            if (mShowCollapsedOnKeyguard) {
+                position = 0;
+            } else {
+                position = 1;
+            }
         }
         mLastPosition = position;
         if (mOnFirstPage && mAllowFancy) {
@@ -356,7 +381,7 @@
 
     @Override
     public void onAnimationStarted() {
-        mQuickQsPanel.setVisibility(mOnKeyguard ? View.INVISIBLE : View.VISIBLE);
+        updateQQSVisibility();
         if (mOnFirstPage) {
             final int N = mQuickQsViews.size();
             for (int i = 0; i < N; i++) {
@@ -410,7 +435,7 @@
         @Override
         public void run() {
             updateAnimators();
-            setPosition(mLastPosition);
+            setCurrentPosition();
         }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 087a826..0a3b43a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -40,8 +40,10 @@
 import com.android.systemui.R.id;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
@@ -50,16 +52,17 @@
 
 import javax.inject.Inject;
 
-public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Callbacks {
+public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Callbacks,
+        StatusBarStateController.StateListener {
     private static final String TAG = "QS";
     private static final boolean DEBUG = false;
     private static final String EXTRA_EXPANDED = "expanded";
     private static final String EXTRA_LISTENING = "listening";
 
     private final Rect mQsBounds = new Rect();
+    private final StatusBarStateController mStatusBarStateController;
     private boolean mQsExpanded;
     private boolean mHeaderAnimating;
-    private boolean mKeyguardShowing;
     private boolean mStackScrollerOverscrolling;
 
     private long mDelay;
@@ -80,17 +83,27 @@
     private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
     private final InjectionInflationController mInjectionInflater;
     private final QSTileHost mHost;
+    private boolean mShowCollapsedOnKeyguard;
+    private boolean mLastKeyguardAndExpanded;
+    /**
+     * The last received state from the controller. This should not be used directly to check if
+     * we're on keyguard but use {@link #isKeyguardShowing()} instead since that is more accurate
+     * during state transitions which often call into us.
+     */
+    private int mState;
 
     @Inject
     public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
             InjectionInflationController injectionInflater,
             Context context,
-            QSTileHost qsTileHost) {
+            QSTileHost qsTileHost,
+            StatusBarStateController statusBarStateController) {
         mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
         mInjectionInflater = injectionInflater;
         SysUiServiceProvider.getComponent(context, CommandQueue.class)
                 .observe(getLifecycle(), this);
         mHost = qsTileHost;
+        mStatusBarStateController = statusBarStateController;
     }
 
     @Override
@@ -126,11 +139,14 @@
             }
         }
         setHost(mHost);
+        mStatusBarStateController.addCallback(this);
+        onStateChanged(mStatusBarStateController.getState());
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
+        mStatusBarStateController.removeCallback(this);
         if (mListening) {
             setListening(false);
         }
@@ -235,20 +251,43 @@
                 || mHeaderAnimating;
         mQSPanel.setExpanded(mQsExpanded);
         mQSDetail.setExpanded(mQsExpanded);
-        mHeader.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
+        boolean keyguardShowing = isKeyguardShowing();
+        mHeader.setVisibility((mQsExpanded || !keyguardShowing || mHeaderAnimating
+                || mShowCollapsedOnKeyguard)
                 ? View.VISIBLE
                 : View.INVISIBLE);
-        mHeader.setExpanded((mKeyguardShowing && !mHeaderAnimating)
+        mHeader.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard)
                 || (mQsExpanded && !mStackScrollerOverscrolling));
         mFooter.setVisibility(
-                !mQsDisabled && (mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
+                !mQsDisabled && (mQsExpanded || !keyguardShowing || mHeaderAnimating
+                        || mShowCollapsedOnKeyguard)
                 ? View.VISIBLE
                 : View.INVISIBLE);
-        mFooter.setExpanded((mKeyguardShowing && !mHeaderAnimating)
+        mFooter.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard)
                 || (mQsExpanded && !mStackScrollerOverscrolling));
         mQSPanel.setVisibility(!mQsDisabled && expandVisually ? View.VISIBLE : View.INVISIBLE);
     }
 
+    private boolean isKeyguardShowing() {
+        // We want the freshest state here since otherwise we'll have some weirdness if earlier
+        // listeners trigger updates
+        return mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
+    }
+
+    @Override
+    public void setShowCollapsedOnKeyguard(boolean showCollapsedOnKeyguard) {
+        if (showCollapsedOnKeyguard != mShowCollapsedOnKeyguard) {
+            mShowCollapsedOnKeyguard = showCollapsedOnKeyguard;
+            updateQsState();
+            if (mQSAnimator != null) {
+                mQSAnimator.setShowCollapsedOnKeyguard(showCollapsedOnKeyguard);
+            }
+            if (!showCollapsedOnKeyguard && isKeyguardShowing()) {
+                setQsExpansion(mLastQSExpansion, 0);
+            }
+        }
+    }
+
     public QSPanel getQsPanel() {
         return mQSPanel;
     }
@@ -280,10 +319,8 @@
         updateQsState();
     }
 
-    @Override
-    public void setKeyguardShowing(boolean keyguardShowing) {
+    private void setKeyguardShowing(boolean keyguardShowing) {
         if (DEBUG) Log.d(TAG, "setKeyguardShowing " + keyguardShowing);
-        mKeyguardShowing = keyguardShowing;
         mLastQSExpansion = -1;
 
         if (mQSAnimator != null) {
@@ -321,16 +358,18 @@
         if (DEBUG) Log.d(TAG, "setQSExpansion " + expansion + " " + headerTranslation);
         mContainer.setExpansion(expansion);
         final float translationScaleY = expansion - 1;
-        if (!mHeaderAnimating) {
+        boolean onKeyguardAndExpanded = isKeyguardShowing() && !mShowCollapsedOnKeyguard;
+        if (!mHeaderAnimating && !headerWillBeAnimating()) {
             getView().setTranslationY(
-                    mKeyguardShowing
+                    onKeyguardAndExpanded
                             ? translationScaleY * mHeader.getHeight()
                             : headerTranslation);
         }
-        if (expansion == mLastQSExpansion) {
+        if (expansion == mLastQSExpansion && mLastKeyguardAndExpanded == onKeyguardAndExpanded) {
             return;
         }
         mLastQSExpansion = expansion;
+        mLastKeyguardAndExpanded = onKeyguardAndExpanded;
 
         boolean fullyExpanded = expansion == 1;
         int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom()
@@ -338,8 +377,9 @@
         float panelTranslationY = translationScaleY * heightDiff;
 
         // Let the views animate their contents correctly by giving them the necessary context.
-        mHeader.setExpansion(mKeyguardShowing, expansion, panelTranslationY);
-        mFooter.setExpansion(mKeyguardShowing ? 1 : expansion);
+        mHeader.setExpansion(onKeyguardAndExpanded, expansion,
+                panelTranslationY);
+        mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
         mQSPanel.getQsTileRevealController().setExpansion(expansion);
         mQSPanel.getTileLayout().setExpansion(expansion);
         mQSPanel.setTranslationY(translationScaleY * heightDiff);
@@ -361,12 +401,17 @@
         }
     }
 
+    private boolean headerWillBeAnimating() {
+        return mState == StatusBarState.KEYGUARD && mShowCollapsedOnKeyguard
+                && !isKeyguardShowing();
+    }
+
     @Override
     public void animateHeaderSlidingIn(long delay) {
         if (DEBUG) Log.d(TAG, "animateHeaderSlidingIn");
         // If the QS is already expanded we don't need to slide in the header as it's already
         // visible.
-        if (!mQsExpanded) {
+        if (!mQsExpanded && getView().getTranslationY() != 0) {
             mHeaderAnimating = true;
             mDelay = delay;
             getView().getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn);
@@ -376,6 +421,9 @@
     @Override
     public void animateHeaderSlidingOut() {
         if (DEBUG) Log.d(TAG, "animateHeaderSlidingOut");
+        if (getView().getY() == -mHeader.getHeight()) {
+            return;
+        }
         mHeaderAnimating = true;
         getView().animate().y(-mHeader.getHeight())
                 .setStartDelay(0)
@@ -463,7 +511,6 @@
                     .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                     .setListener(mAnimateHeaderSlidingInListener)
                     .start();
-            getView().setY(-mHeader.getHeight());
             return true;
         }
     };
@@ -476,4 +523,10 @@
             updateQsState();
         }
     };
+
+    @Override
+    public void onStateChanged(int newState) {
+        mState = newState;
+        setKeyguardShowing(newState == StatusBarState.KEYGUARD);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 3c4898c..fed59a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
@@ -48,6 +49,7 @@
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
+import com.android.systemui.util.leak.GarbageMonitor;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -259,12 +261,19 @@
             }
         }
         mCurrentUser = currentUser;
+        List<String> currentSpecs = new ArrayList(mTileSpecs);
         mTileSpecs.clear();
         mTileSpecs.addAll(tileSpecs);
         mTiles.clear();
         mTiles.putAll(newTiles);
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            mCallbacks.get(i).onTilesChanged();
+        if (newTiles.isEmpty() && !tileSpecs.isEmpty()) {
+            // If we didn't manage to create any tiles, set it to empty (default)
+            if (DEBUG) Log.d(TAG, "No valid tiles on tuning changed. Setting to default.");
+            changeTiles(currentSpecs, loadTileSpecs(mContext, ""));
+        } else {
+            for (int i = 0; i < mCallbacks.size(); i++) {
+                mCallbacks.get(i).onTilesChanged();
+            }
         }
     }
 
@@ -364,6 +373,10 @@
             if (tile.equals("default")) {
                 if (!addedDefault) {
                     tiles.addAll(Arrays.asList(defaultTileList.split(",")));
+                    if (Build.IS_DEBUGGABLE
+                            && GarbageMonitor.MemoryTile.ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
+                        tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
+                    }
                     addedDefault = true;
                 }
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 7fbd7ce..d20b228 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -440,19 +440,19 @@
     /**
      * Animates the inner contents based on the given expansion details.
      *
-     * @param isKeyguardShowing whether or not we're showing the keyguard (a.k.a. lockscreen)
+     * @param forceExpanded whether we should show the state expanded forcibly
      * @param expansionFraction how much the QS panel is expanded/pulled out (up to 1f)
      * @param panelTranslationY how much the panel has physically moved down vertically (required
      *                          for keyguard animations only)
      */
-    public void setExpansion(boolean isKeyguardShowing, float expansionFraction,
+    public void setExpansion(boolean forceExpanded, float expansionFraction,
                              float panelTranslationY) {
-        final float keyguardExpansionFraction = isKeyguardShowing ? 1f : expansionFraction;
+        final float keyguardExpansionFraction = forceExpanded ? 1f : expansionFraction;
         if (mStatusIconsAlphaAnimator != null) {
             mStatusIconsAlphaAnimator.setPosition(keyguardExpansionFraction);
         }
 
-        if (isKeyguardShowing) {
+        if (forceExpanded) {
             // If the keyguard is showing, we want to offset the text so that it comes in at the
             // same time as the panel as it slides down.
             mHeaderTextContainerView.setTranslationY(panelTranslationY);
@@ -462,6 +462,11 @@
 
         if (mHeaderTextContainerAlphaAnimator != null) {
             mHeaderTextContainerAlphaAnimator.setPosition(keyguardExpansionFraction);
+            if (keyguardExpansionFraction > 0) {
+                mHeaderTextContainerView.setVisibility(VISIBLE);
+            } else {
+                mHeaderTextContainerView.setVisibility(INVISIBLE);
+            }
         }
         if (mPrivacyChipAlphaAnimator != null) {
             mPrivacyChip.setExpanded(expansionFraction > 0.5);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 1848219..19edc94 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -27,6 +27,9 @@
 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;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
 
 import android.annotation.FloatRange;
 import android.app.ActivityTaskManager;
@@ -41,7 +44,6 @@
 import android.hardware.input.InputManager;
 import android.os.Binder;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -54,7 +56,6 @@
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
@@ -69,6 +70,8 @@
 import com.android.systemui.statusbar.phone.NavigationBarView;
 import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -91,7 +94,6 @@
     private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
 
     public static final String TAG_OPS = "OverviewProxyService";
-    public static final boolean DEBUG_OVERVIEW_PROXY = false;
     private static final long BACKOFF_MILLIS = 1000;
     private static final long DEFERRED_CALLBACK_MILLIS = 5000;
 
@@ -100,6 +102,8 @@
 
     private final Context mContext;
     private final Handler mHandler;
+    private final NavigationBarController mNavBarController;
+    private final StatusBarWindowController mStatusBarWinController;
     private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
     private final ComponentName mRecentsComponentName;
     private final DeviceProvisionedController mDeviceProvisionedController;
@@ -114,8 +118,10 @@
     private boolean mBound;
     private boolean mIsEnabled;
     private int mCurrentBoundedUserId = -1;
-    private float mBackButtonAlpha;
-    private MotionEvent mStatusBarGestureDownEvent;
+    private float mNavBarButtonAlpha;
+    private boolean mInputFocusTransferStarted;
+    private float mInputFocusTransferStartY;
+    private long mInputFocusTransferStartMillis;
     private float mWindowCornerRadius;
     private boolean mSupportsRoundedCornersOnWindows;
     private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
@@ -160,6 +166,7 @@
             }
         }
 
+        // TODO: change the method signature to use (boolean inputFocusTransferStarted)
         @Override
         public void onStatusBarMotionEvent(MotionEvent event) {
             if (!verifyCaller("onStatusBarMotionEvent")) {
@@ -171,15 +178,19 @@
                 mHandler.post(()->{
                     StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
                     if (bar != null) {
-                        bar.dispatchNotificationsPanelTouchEvent(event);
 
                         int action = event.getActionMasked();
                         if (action == ACTION_DOWN) {
-                            mStatusBarGestureDownEvent = MotionEvent.obtain(event);
+                            mInputFocusTransferStarted = true;
+                            mInputFocusTransferStartY = event.getY();
+                            mInputFocusTransferStartMillis = event.getEventTime();
+                            bar.onInputFocusTransfer(mInputFocusTransferStarted, 0 /* velocity */);
                         }
                         if (action == ACTION_UP || action == ACTION_CANCEL) {
-                            mStatusBarGestureDownEvent.recycle();
-                            mStatusBarGestureDownEvent = null;
+                            mInputFocusTransferStarted = false;
+                            bar.onInputFocusTransfer(mInputFocusTransferStarted,
+                                    (event.getY() - mInputFocusTransferStartY)
+                                    / (event.getEventTime() - mInputFocusTransferStartMillis));
                         }
                         event.recycle();
                     }
@@ -240,22 +251,25 @@
         }
 
         @Override
-        public void setBackButtonAlpha(float alpha, boolean animate) {
-            if (!verifyCaller("setBackButtonAlpha")) {
+        public void setNavBarButtonAlpha(float alpha, boolean animate) {
+            if (!verifyCaller("setNavBarButtonAlpha")) {
                 return;
             }
             long token = Binder.clearCallingIdentity();
             try {
-                mBackButtonAlpha = alpha;
-                mHandler.post(() -> {
-                    notifyBackButtonAlphaChanged(alpha, animate);
-                });
+                mNavBarButtonAlpha = alpha;
+                mHandler.post(() -> notifyNavBarButtonAlphaChanged(alpha, animate));
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
         }
 
         @Override
+        public void setBackButtonAlpha(float alpha, boolean animate) {
+            setNavBarButtonAlpha(alpha, animate);
+        }
+
+        @Override
         public void onAssistantProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {
             if (!verifyCaller("onAssistantProgress")) {
                 return;
@@ -441,14 +455,20 @@
         }
     };
 
+    private final StatusBarWindowCallback mStatusBarWindowCallback = this::onStatusBarStateChanged;
+
     // This is the death handler for the binder from the launcher service
     private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
             = this::cleanupAfterDeath;
 
     @Inject
-    public OverviewProxyService(Context context, DeviceProvisionedController provisionController) {
+    public OverviewProxyService(Context context, DeviceProvisionedController provisionController,
+            NavigationBarController navBarController, NavigationModeController navModeController,
+            StatusBarWindowController statusBarWinController) {
         mContext = context;
         mHandler = new Handler();
+        mNavBarController = navBarController;
+        mStatusBarWinController = statusBarWinController;
         mDeviceProvisionedController = provisionController;
         mConnectionBackoffAttempts = 0;
         mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
@@ -460,10 +480,10 @@
                 .supportsRoundedCornersOnWindows(mContext.getResources());
 
         // Assumes device always starts with back button until launcher tells it that it does not
-        mBackButtonAlpha = 1.0f;
+        mNavBarButtonAlpha = 1.0f;
 
         // Listen for nav bar mode changes
-        mNavBarMode = Dependency.get(NavigationModeController.class).addListener(this);
+        mNavBarMode = navModeController.addListener(this);
 
         // Listen for device provisioned/user setup
         updateEnabledState();
@@ -476,6 +496,9 @@
                 PatternMatcher.PATTERN_LITERAL);
         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         mContext.registerReceiver(mLauncherStateChangedReceiver, filter);
+
+        // Listen for status bar state changes
+        statusBarWinController.registerCallback(mStatusBarWindowCallback);
     }
 
     public void notifyBackAction(boolean completed, int downX, int downY, boolean isButton,
@@ -513,10 +536,10 @@
     }
 
     private void updateSystemUiStateFlags() {
-        final NavigationBarController navBar = Dependency.get(NavigationBarController.class);
-        final NavigationBarFragment navBarFragment = navBar.getDefaultNavigationBarFragment();
-        final NavigationBarView navBarView = navBar.getNavigationBarView(mContext.getDisplayId());
-        final StatusBar statusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
+        final NavigationBarFragment navBarFragment =
+                mNavBarController.getDefaultNavigationBarFragment();
+        final NavigationBarView navBarView =
+                mNavBarController.getNavigationBarView(mContext.getDisplayId());
 
         mSysUiStateFlags = 0;
         if (navBarFragment != null) {
@@ -525,8 +548,8 @@
         if (navBarView != null) {
             navBarView.updateSystemUiStateFlags();
         }
-        if (statusBar != null) {
-            statusBar.updateSystemUiStateFlags();
+        if (mStatusBarWinController != null) {
+            mStatusBarWinController.notifyStateChangedCallbacks();
         }
         notifySystemUiStateFlags(mSysUiStateFlags);
     }
@@ -541,6 +564,16 @@
         }
     }
 
+    private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
+            boolean bouncerShowing) {
+        int displayId = mContext.getDisplayId();
+        setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
+                keyguardShowing && !keyguardOccluded, displayId);
+        setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
+                keyguardShowing && keyguardOccluded, displayId);
+        setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING, bouncerShowing, displayId);
+    }
+
     /**
      * Sets the navbar region which can receive touch inputs
      */
@@ -560,18 +593,16 @@
     }
 
     public float getBackButtonAlpha() {
-        return mBackButtonAlpha;
+        return mNavBarButtonAlpha;
     }
 
     public void cleanupAfterDeath() {
-        if (mStatusBarGestureDownEvent != null) {
+        if (mInputFocusTransferStarted) {
             mHandler.post(()-> {
                 StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
                 if (bar != null) {
-                    mStatusBarGestureDownEvent.setAction(MotionEvent.ACTION_CANCEL);
-                    bar.dispatchNotificationsPanelTouchEvent(mStatusBarGestureDownEvent);
-                    mStatusBarGestureDownEvent.recycle();
-                    mStatusBarGestureDownEvent = null;
+                    mInputFocusTransferStarted = false;
+                    bar.onInputFocusTransfer(false, 0 /* velocity */);
                 }
             });
         }
@@ -632,7 +663,7 @@
     public void addCallback(OverviewProxyListener listener) {
         mConnectionCallbacks.add(listener);
         listener.onConnectionChanged(mOverviewProxy != null);
-        listener.onBackButtonAlphaChanged(mBackButtonAlpha, false);
+        listener.onNavBarButtonAlphaChanged(mNavBarButtonAlpha, false);
         listener.onSystemUiStateChanged(mSysUiStateFlags);
     }
 
@@ -663,14 +694,14 @@
         if (mOverviewProxy != null) {
             mOverviewProxy.asBinder().unlinkToDeath(mOverviewServiceDeathRcpt, 0);
             mOverviewProxy = null;
-            notifyBackButtonAlphaChanged(1f, false /* animate */);
+            notifyNavBarButtonAlphaChanged(1f, false /* animate */);
             notifyConnectionChanged();
         }
     }
 
-    private void notifyBackButtonAlphaChanged(float alpha, boolean animate) {
+    private void notifyNavBarButtonAlphaChanged(float alpha, boolean animate) {
         for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
-            mConnectionCallbacks.get(i).onBackButtonAlphaChanged(alpha, animate);
+            mConnectionCallbacks.get(i).onNavBarButtonAlphaChanged(alpha, animate);
         }
     }
 
@@ -720,6 +751,8 @@
         try {
             if (mOverviewProxy != null) {
                 mOverviewProxy.onAssistantVisibilityChanged(visibility);
+            } else {
+                Log.e(TAG_OPS, "Failed to get overview proxy for assistant visibility.");
             }
         } catch (RemoteException e) {
             Log.e(TAG_OPS, "Failed to call onAssistantVisibilityChanged()", e);
@@ -754,6 +787,7 @@
         pw.println(QuickStepContract.isBackGestureDisabled(mSysUiStateFlags));
         pw.print("    assistantGestureDisabled=");
         pw.println(QuickStepContract.isAssistantGestureDisabled(mSysUiStateFlags));
+        pw.print(" mInputFocusTransferStarted="); pw.println(mInputFocusTransferStarted);
     }
 
     public interface OverviewProxyListener {
@@ -761,7 +795,8 @@
         default void onQuickStepStarted() {}
         default void onOverviewShown(boolean fromHome) {}
         default void onQuickScrubStarted() {}
-        default void onBackButtonAlphaChanged(float alpha, boolean animate) {}
+        /** Notify changes in the nav bar button alpha */
+        default void onNavBarButtonAlphaChanged(float alpha, boolean animate) {}
         default void onSystemUiStateChanged(int sysuiStateFlags) {}
         default void onAssistantProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {}
         default void onAssistantGestureCompletion(float velocity) {}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 341461b..d47288a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -92,6 +92,11 @@
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+
 
 /**
  * POD used in the AsyncTask which saves an image in the background.
@@ -288,7 +293,11 @@
             sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
             sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
-            PendingIntent chooserAction = PendingIntent.getBroadcast(context, 0,
+            // Make sure pending intents for the system user are still unique across users
+            // by setting the (otherwise unused) request code to the current user id.
+            int requestCode = context.getUserId();
+
+            PendingIntent chooserAction = PendingIntent.getBroadcast(context, requestCode,
                     new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
                     PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
             Intent sharingChooserIntent = Intent.createChooser(sharingIntent, null,
@@ -297,10 +306,11 @@
                     .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
             // Create a share action for the notification
-            PendingIntent shareAction = PendingIntent.getBroadcastAsUser(context, 0,
+            PendingIntent shareAction = PendingIntent.getBroadcastAsUser(context, requestCode,
                     new Intent(context, GlobalScreenshot.ActionProxyReceiver.class)
                             .putExtra(EXTRA_ACTION_INTENT, sharingChooserIntent)
-                            .putExtra(EXTRA_DISALLOW_ENTER_PIP, true),
+                            .putExtra(EXTRA_DISALLOW_ENTER_PIP, true)
+                            .setAction(Intent.ACTION_SEND),
                     PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
             Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder(
                     R.drawable.ic_screenshot_share,
@@ -320,10 +330,11 @@
             editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
 
             // Create a edit action
-            PendingIntent editAction = PendingIntent.getBroadcastAsUser(context, 1,
+            PendingIntent editAction = PendingIntent.getBroadcastAsUser(context, requestCode,
                     new Intent(context, GlobalScreenshot.ActionProxyReceiver.class)
                             .putExtra(EXTRA_ACTION_INTENT, editIntent)
-                            .putExtra(EXTRA_CANCEL_NOTIFICATION, editIntent.getComponent() != null),
+                            .putExtra(EXTRA_CANCEL_NOTIFICATION, editIntent.getComponent() != null)
+                            .setAction(Intent.ACTION_EDIT),
                     PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.SYSTEM);
             Notification.Action.Builder editActionBuilder = new Notification.Action.Builder(
                     R.drawable.ic_screenshot_edit,
@@ -331,7 +342,7 @@
             mNotificationBuilder.addAction(editActionBuilder.build());
 
             // Create a delete action for the notification
-            PendingIntent deleteAction = PendingIntent.getBroadcast(context, 0,
+            PendingIntent deleteAction = PendingIntent.getBroadcast(context, requestCode,
                     new Intent(context, GlobalScreenshot.DeleteScreenshotReceiver.class)
                             .putExtra(GlobalScreenshot.SCREENSHOT_URI_ID, uri.toString()),
                     PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
@@ -446,6 +457,8 @@
     static final String EXTRA_CANCEL_NOTIFICATION = "android:screenshot_cancel_notification";
     static final String EXTRA_DISALLOW_ENTER_PIP = "android:screenshot_disallow_enter_pip";
 
+    private static final String TAG = "GlobalScreenshot";
+
     private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
     private static final int SCREENSHOT_DROP_IN_DURATION = 430;
     private static final int SCREENSHOT_DROP_OUT_DELAY = 500;
@@ -902,11 +915,19 @@
      * appropriate signals to the system (ie. to dismiss the keyguard if necessary).
      */
     public static class ActionProxyReceiver extends BroadcastReceiver {
+        static final int CLOSE_WINDOWS_TIMEOUT_MILLIS = 3000;
+
         @Override
         public void onReceive(Context context, final Intent intent) {
             Runnable startActivityRunnable = () -> {
-                ActivityManagerWrapper.getInstance().closeSystemWindows(
-                        SYSTEM_DIALOG_REASON_SCREENSHOT);
+                try {
+                    ActivityManagerWrapper.getInstance().closeSystemWindows(
+                            SYSTEM_DIALOG_REASON_SCREENSHOT).get(
+                            CLOSE_WINDOWS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+                } catch (TimeoutException | InterruptedException | ExecutionException e) {
+                    Slog.e(TAG, "Unable to share screenshot", e);
+                    return;
+                }
 
                 Intent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
                 if (intent.getBooleanExtra(EXTRA_CANCEL_NOTIFICATION, false)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
deleted file mode 100644
index 5f878ce..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
+++ /dev/null
@@ -1,162 +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;
-
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.ArraySet;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * Manager which handles high priority notifications that should "pulse" in when the device is
- * dozing and/or in AOD.  The pulse uses the notification's ambient view and pops in briefly
- * before automatically dismissing the alert.
- */
-@Singleton
-public class AmbientPulseManager extends AlertingNotificationManager {
-
-    protected final ArraySet<OnAmbientChangedListener> mListeners = new ArraySet<>();
-    @VisibleForTesting
-    protected long mExtensionTime;
-
-    @Inject
-    public AmbientPulseManager(@NonNull final Context context) {
-        Resources resources = context.getResources();
-        mAutoDismissNotificationDecay = resources.getInteger(R.integer.ambient_notification_decay);
-        mMinimumDisplayTime = resources.getInteger(R.integer.ambient_notification_minimum_time);
-        mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
-    }
-
-    /**
-     * Adds an OnAmbientChangedListener to observe events.
-     */
-    public void addListener(@NonNull OnAmbientChangedListener listener) {
-        mListeners.add(listener);
-    }
-
-    /**
-     * Removes the OnAmbientChangedListener from the observer list.
-     */
-    public void removeListener(@NonNull OnAmbientChangedListener listener) {
-        mListeners.remove(listener);
-    }
-
-    /**
-     * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts
-     * longer.
-     */
-    public void extendPulse() {
-        AmbientEntry topEntry = getTopEntry();
-        if (topEntry == null) {
-            return;
-        }
-        topEntry.extendPulse();
-    }
-
-    public @InflationFlag int getContentFlag() {
-        return FLAG_CONTENT_VIEW_AMBIENT;
-    }
-
-    @Override
-    protected void onAlertEntryAdded(AlertEntry alertEntry) {
-        NotificationEntry entry = alertEntry.mEntry;
-        entry.setAmbientPulsing(true);
-        for (OnAmbientChangedListener listener : mListeners) {
-            listener.onAmbientStateChanged(entry, true);
-        }
-    }
-
-    @Override
-    protected void onAlertEntryRemoved(AlertEntry alertEntry) {
-        NotificationEntry entry = alertEntry.mEntry;
-        entry.setAmbientPulsing(false);
-        for (OnAmbientChangedListener listener : mListeners) {
-            listener.onAmbientStateChanged(entry, false);
-        }
-        entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
-    }
-
-    @Override
-    protected AlertEntry createAlertEntry() {
-        return new AmbientEntry();
-    }
-
-    /**
-     * Get the top pulsing entry.  This should be the currently showing one if there are multiple.
-     * @return the currently showing entry
-     */
-    private AmbientEntry getTopEntry() {
-        if (mAlertEntries.isEmpty()) {
-            return null;
-        }
-        AlertEntry topEntry = null;
-        for (AlertEntry entry : mAlertEntries.values()) {
-            if (topEntry == null || entry.compareTo(topEntry) < 0) {
-                topEntry = entry;
-            }
-        }
-        return (AmbientEntry) topEntry;
-    }
-
-    /**
-     * Observer interface for any changes in the ambient entries.
-     */
-    public interface OnAmbientChangedListener {
-        /**
-         * Called when an entry starts or stops pulsing.
-         * @param entry the entry that changed
-         * @param isPulsing true if the entry is now pulsing, false otherwise
-         */
-        void onAmbientStateChanged(@NonNull NotificationEntry entry, boolean isPulsing);
-    }
-
-    private final class AmbientEntry extends AlertEntry {
-        private boolean extended;
-
-        /**
-         * Extend the lifetime of the alertEntry so that it auto-removes later.  Can only be
-         * extended once.
-         */
-        private void extendPulse() {
-            if (!extended) {
-                extended = true;
-                updateEntry(false);
-            }
-        }
-
-        @Override
-        public void reset() {
-            super.reset();
-            extended = false;
-        }
-
-        @Override
-        protected long calculateFinishTime() {
-            return super.calculateFinishTime() + (extended ? mExtensionTime : 0);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index 04534ba..164215b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -28,6 +28,10 @@
 public class CrossFadeHelper {
     public static final long ANIMATION_DURATION_LENGTH = 210;
 
+    public static void fadeOut(final View view) {
+        fadeOut(view, null);
+    }
+
     public static void fadeOut(final View view, final Runnable endRunnable) {
         fadeOut(view, ANIMATION_DURATION_LENGTH, 0, endRunnable);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 514a2ae..d939828 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -29,7 +29,6 @@
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 
@@ -59,14 +58,15 @@
     private FalsingManager mFalsingManager;
 
     public DragDownHelper(Context context, View host, ExpandHelper.Callback callback,
-            DragDownCallback dragDownCallback) {
+            DragDownCallback dragDownCallback,
+            FalsingManager falsingManager) {
         mMinDragDistance = context.getResources().getDimensionPixelSize(
                 R.dimen.keyguard_drag_down_min_distance);
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
         mCallback = callback;
         mDragDownCallback = dragDownCallback;
         mHost = host;
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = falsingManager;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
index 3f1ff33..4597b16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
@@ -43,7 +43,6 @@
     private static final String HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE =
             "heads_up_status_bar_view_super_parcelable";
     private static final String FIRST_LAYOUT = "first_layout";
-    private static final String PUBLIC_MODE = "public_mode";
     private static final String VISIBILITY = "visibility";
     private static final String ALPHA = "alpha";
     private int mAbsoluteStartPadding;
@@ -54,7 +53,6 @@
     private Rect mLayoutedIconRect = new Rect();
     private int[] mTmpPosition = new int[2];
     private boolean mFirstLayout = true;
-    private boolean mPublicMode;
     private int mMaxWidth;
     private View mRootView;
     private int mSysWinInset;
@@ -121,7 +119,6 @@
         bundle.putParcelable(HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE,
                 super.onSaveInstanceState());
         bundle.putBoolean(FIRST_LAYOUT, mFirstLayout);
-        bundle.putBoolean(PUBLIC_MODE, mPublicMode);
         bundle.putInt(VISIBILITY, getVisibility());
         bundle.putFloat(ALPHA, getAlpha());
 
@@ -139,7 +136,6 @@
         Parcelable superState = bundle.getParcelable(HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE);
         super.onRestoreInstanceState(superState);
         mFirstLayout = bundle.getBoolean(FIRST_LAYOUT, true);
-        mPublicMode = bundle.getBoolean(PUBLIC_MODE, false);
         if (bundle.containsKey(VISIBILITY)) {
             setVisibility(bundle.getInt(VISIBILITY));
         }
@@ -166,11 +162,13 @@
         if (entry != null) {
             mShowingEntry = entry;
             CharSequence text = entry.headsUpStatusBarText;
-            if (mPublicMode) {
+            if (entry.isSensitive()) {
                 text = entry.headsUpStatusBarTextPublic;
             }
             mTextView.setText(text);
-        } else {
+            mShowingEntry.setOnSensitiveChangedListener(() -> setEntry(entry));
+        } else if (mShowingEntry != null){
+            mShowingEntry.setOnSensitiveChangedListener(null);
             mShowingEntry = null;
         }
     }
@@ -273,10 +271,6 @@
         mTextView.setTextColor(DarkIconDispatcher.getTint(area, this, tint));
     }
 
-    public void setPublicMode(boolean publicMode) {
-        mPublicMode = publicMode;
-    }
-
     public void setOnDrawingRectChangedListener(Runnable onDrawingRectChangedListener) {
         mOnDrawingRectChangedListener = onDrawingRectChangedListener;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 25bde3b..4be93df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -43,6 +43,7 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.ViewClippingUtil;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.settingslib.Utils;
@@ -80,6 +81,7 @@
     private static final int MSG_CLEAR_BIOMETRIC_MSG = 2;
     private static final int MSG_SWIPE_UP_TO_UNLOCK = 3;
     private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
+    private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
 
     private final Context mContext;
     private final ShadeController mShadeController;
@@ -119,6 +121,13 @@
 
     private final DevicePolicyManager mDevicePolicyManager;
     private boolean mDozing;
+    private final ViewClippingUtil.ClippingParameters mClippingParams =
+            new ViewClippingUtil.ClippingParameters() {
+                @Override
+                public boolean shouldFinish(View view) {
+                    return view == mIndicationArea;
+                }
+            };
 
     /**
      * Creates a new KeyguardIndicationController and registers callbacks.
@@ -414,7 +423,7 @@
         int animateDownDuration = mContext.getResources().getInteger(
                 R.integer.wired_charging_keyguard_text_animation_duration_down);
         textView.animate().cancel();
-        float translation = textView.getTranslationY();
+        ViewClippingUtil.setClippingDeactivated(textView, true, mClippingParams);
         textView.animate()
                 .translationYBy(yTranslation)
                 .setInterpolator(Interpolators.LINEAR)
@@ -429,23 +438,27 @@
 
                     @Override
                     public void onAnimationCancel(Animator animation) {
-                        textView.setTranslationY(translation);
+                        textView.setTranslationY(BOUNCE_ANIMATION_FINAL_Y);
                         mCancelled = true;
                     }
 
                     @Override
                     public void onAnimationEnd(Animator animation) {
                         if (mCancelled) {
+                            ViewClippingUtil.setClippingDeactivated(textView, false,
+                                    mClippingParams);
                             return;
                         }
                         textView.animate()
                                 .setDuration(animateDownDuration)
                                 .setInterpolator(Interpolators.BOUNCE)
-                                .translationY(translation)
+                                .translationY(BOUNCE_ANIMATION_FINAL_Y)
                                 .setListener(new AnimatorListenerAdapter() {
                                     @Override
-                                    public void onAnimationCancel(Animator animation) {
-                                        textView.setTranslationY(translation);
+                                    public void onAnimationEnd(Animator animation) {
+                                        textView.setTranslationY(BOUNCE_ANIMATION_FINAL_Y);
+                                        ViewClippingUtil.setClippingDeactivated(textView, false,
+                                                mClippingParams);
                                     }
                                 });
                     }
@@ -741,13 +754,5 @@
                 updateIndication(false);
             }
         }
-
-        @Override
-        public void onKeyguardBouncerChanged(boolean bouncer) {
-            if (mLockIcon == null) {
-                return;
-            }
-            mLockIcon.setBouncerVisible(bouncer);
-        }
-    };
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 905a8e6..4ea1ed5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -320,7 +320,7 @@
 
     private boolean hideSilentNotificationsOnLockscreen() {
         return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0) == 0;
+                Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0;
     }
 
     private void setShowLockscreenNotifications(boolean show) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 75ef185..f001561 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -57,6 +57,7 @@
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ScrimState;
@@ -68,6 +69,7 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -89,6 +91,15 @@
             = Dependency.get(StatusBarStateController.class);
     private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
     private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
+    private final KeyguardBypassController mKeyguardBypassController;
+    private static final HashSet<Integer> PAUSED_MEDIA_STATES = new HashSet<>();
+    static {
+        PAUSED_MEDIA_STATES.add(PlaybackState.STATE_NONE);
+        PAUSED_MEDIA_STATES.add(PlaybackState.STATE_STOPPED);
+        PAUSED_MEDIA_STATES.add(PlaybackState.STATE_PAUSED);
+        PAUSED_MEDIA_STATES.add(PlaybackState.STATE_ERROR);
+    }
+
 
     // Late binding
     private NotificationEntryManager mEntryManager;
@@ -173,9 +184,11 @@
             Lazy<ShadeController> shadeController,
             Lazy<StatusBarWindowController> statusBarWindowController,
             NotificationEntryManager notificationEntryManager,
-            MediaArtworkProcessor mediaArtworkProcessor) {
+            MediaArtworkProcessor mediaArtworkProcessor,
+            KeyguardBypassController keyguardBypassController) {
         mContext = context;
         mMediaArtworkProcessor = mediaArtworkProcessor;
+        mKeyguardBypassController = keyguardBypassController;
         mMediaListeners = new ArrayList<>();
         mMediaSessionManager
                 = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
@@ -203,6 +216,10 @@
                 mPropertiesChangedListener);
     }
 
+    public static boolean isPlayingState(int state) {
+        return !PAUSED_MEDIA_STATES.contains(state);
+    }
+
     public void setUpWithPresenter(NotificationPresenter presenter) {
         mPresenter = presenter;
     }
@@ -457,7 +474,7 @@
         }
 
         Bitmap artworkBitmap = null;
-        if (mediaMetadata != null) {
+        if (mediaMetadata != null && !mKeyguardBypassController.getBypassEnabled()) {
             artworkBitmap = mediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
             if (artworkBitmap == null) {
                 artworkBitmap = mediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
@@ -488,6 +505,7 @@
         if (bmp != null) {
             artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), bmp);
         }
+        boolean hasMediaArtwork = artworkDrawable != null;
         boolean allowWhenShade = false;
         if (ENABLE_LOCKSCREEN_WALLPAPER && artworkDrawable == null) {
             Bitmap lockWallpaper =
@@ -506,7 +524,7 @@
         boolean hideBecauseOccluded = shadeController != null && shadeController.isOccluded();
 
         final boolean hasArtwork = artworkDrawable != null;
-        mColorExtractor.setHasBackdrop(hasArtwork);
+        mColorExtractor.setHasMediaArtwork(hasMediaArtwork);
         if (mScrimController != null) {
             mScrimController.setHasBackdrop(hasArtwork);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 1440803..c9050d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -52,6 +52,7 @@
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -121,6 +122,7 @@
     protected final Context mContext;
     private final UserManager mUserManager;
     private final KeyguardManager mKeyguardManager;
+    private final StatusBarStateController mStatusBarStateController;
 
     protected RemoteInputController mRemoteInputController;
     protected NotificationLifetimeExtender.NotificationSafeToRemoveCallback
@@ -259,6 +261,7 @@
             SmartReplyController smartReplyController,
             NotificationEntryManager notificationEntryManager,
             Lazy<ShadeController> shadeController,
+            StatusBarStateController statusBarStateController,
             @Named(MAIN_HANDLER_NAME) Handler mainHandler) {
         mContext = context;
         mLockscreenUserManager = lockscreenUserManager;
@@ -271,6 +274,7 @@
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         addLifetimeExtenders();
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
+        mStatusBarStateController = statusBarStateController;
 
         notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
             @Override
@@ -380,7 +384,10 @@
 
         if (!mLockscreenUserManager.shouldAllowLockscreenRemoteInput()) {
             final int userId = pendingIntent.getCreatorUserHandle().getIdentifier();
-            if (mLockscreenUserManager.isLockscreenPublicMode(userId)) {
+            if (mLockscreenUserManager.isLockscreenPublicMode(userId)
+                    || mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
+                // Even if we don't have security we should go through this flow, otherwise we won't
+                // go to the shade
                 mCallback.onLockedRemoteInput(row, view);
                 return true;
             }
@@ -391,6 +398,11 @@
             }
         }
 
+        if (riv != null && !riv.isAttachedToWindow()) {
+            // the remoteInput isn't attached to the window anymore :/ Let's focus on the expanded
+            // one instead if it's available
+            riv = null;
+        }
         if (riv == null) {
             riv = findRemoteInputView(row.getPrivateLayout().getExpandedChild());
             if (riv == null) {
@@ -405,6 +417,10 @@
             return true;
         }
 
+        if (!riv.isAttachedToWindow()) {
+            // if we still didn't find a view that is attached, let's abort.
+            return false;
+        }
         int width = view.getWidth();
         if (view instanceof TextView) {
             // Center the reveal on the text which might be off-center from the TextView
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 799876d..4ccd0cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -18,6 +18,7 @@
 
 import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE;
 import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
+import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
 
 import android.content.Context;
 import android.content.res.Configuration;
@@ -48,8 +49,12 @@
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.ViewState;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationIconContainer;
 
+import javax.inject.Inject;
+import javax.inject.Named;
+
 /**
  * A notification shelf view that is placed inside the notification scroller. It manages the
  * overflow icons that don't fit into the regular list anymore.
@@ -63,15 +68,13 @@
             = SystemProperties.getBoolean("debug.icon_scroll_animations", true);
     private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag;
     private static final String TAG = "NotificationShelf";
-    private static final long SHELF_IN_TRANSLATION_DURATION = 200;
+    private final KeyguardBypassController mBypassController;
 
     private NotificationIconContainer mShelfIcons;
     private int[] mTmp = new int[2];
     private boolean mHideBackground;
     private int mIconAppearTopPadding;
-    private int mShelfAppearTranslation;
-    private float mDarkShelfPadding;
-    private float mDarkShelfIconSize;
+    private float mHiddenShelfIconSize;
     private int mStatusBarHeight;
     private int mStatusBarPaddingStart;
     private AmbientState mAmbientState;
@@ -96,8 +99,12 @@
     private int mCutoutHeight;
     private int mGapHeight;
 
-    public NotificationShelf(Context context, AttributeSet attrs) {
+    @Inject
+    public NotificationShelf(@Named(VIEW_CONTEXT) Context context,
+            AttributeSet attrs,
+            KeyguardBypassController keyguardBypassController) {
         super(context, attrs);
+        mBypassController = keyguardBypassController;
     }
 
     @Override
@@ -140,8 +147,6 @@
         mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
         mStatusBarPaddingStart = res.getDimensionPixelOffset(R.dimen.status_bar_padding_start);
         mPaddingBetweenElements = res.getDimensionPixelSize(R.dimen.notification_divider_height);
-        mShelfAppearTranslation = res.getDimensionPixelSize(R.dimen.shelf_appear_translation);
-        mDarkShelfPadding = res.getDimensionPixelSize(R.dimen.widget_bottom_separator_padding);
 
         ViewGroup.LayoutParams layoutParams = getLayoutParams();
         layoutParams.height = res.getDimensionPixelOffset(R.dimen.notification_shelf_height);
@@ -152,7 +157,7 @@
         mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold);
         mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf);
         mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
-        mDarkShelfIconSize = res.getDimensionPixelOffset(R.dimen.dark_shelf_icon_size);
+        mHiddenShelfIconSize = res.getDimensionPixelOffset(R.dimen.hidden_shelf_icon_size);
         mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding);
 
         if (!mShowNotificationShelf) {
@@ -167,33 +172,6 @@
     }
 
     @Override
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (mDark == dark) return;
-        super.setDark(dark, fade, delay);
-        mShelfIcons.setDark(dark, fade, delay);
-        updateInteractiveness();
-        updateOutline();
-    }
-
-    /**
-     * Alpha animation with translation played when this view is visible on AOD.
-     */
-    public void fadeInTranslating() {
-        mShelfIcons.setTranslationY(-mShelfAppearTranslation);
-        mShelfIcons.setAlpha(0);
-        mShelfIcons.animate()
-                .setInterpolator(Interpolators.DECELERATE_QUINT)
-                .translationY(0)
-                .setDuration(SHELF_IN_TRANSLATION_DURATION)
-                .start();
-        mShelfIcons.animate()
-                .alpha(1)
-                .setInterpolator(Interpolators.LINEAR)
-                .setDuration(SHELF_IN_TRANSLATION_DURATION)
-                .start();
-    }
-
-    @Override
     protected View getContentView() {
         return mShelfIcons;
     }
@@ -219,11 +197,8 @@
             viewState.copyFrom(lastViewState);
             viewState.height = getIntrinsicHeight();
 
-            float awakenTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height,
+            viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height,
                     getFullyClosedTranslation());
-            float yRatio = mAmbientState.hasPulsingNotifications() ?
-                    0 : mAmbientState.getDarkAmount();
-            viewState.yTranslation = awakenTranslation + mDarkShelfPadding * yRatio;
             viewState.zTranslation = ambientState.getBaseZHeight();
             // For the small display size, it's not enough to make the icon not covered by
             // the top cutout so the denominator add the height of cutout.
@@ -294,17 +269,17 @@
         int backgroundTop = 0;
         int clipTopAmount = 0;
         float firstElementRoundness = 0.0f;
-        ExpandableNotificationRow previousRow = null;
+        ActivatableNotificationView previousRow = null;
 
         for (int i = 0; i < mHostLayout.getChildCount(); i++) {
             ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
 
-            if (!(child instanceof ExpandableNotificationRow)
-                    || child.getVisibility() == GONE) {
+            if (!(child instanceof ActivatableNotificationView)
+                    || child.getVisibility() == GONE || child == this) {
                 continue;
             }
 
-            ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+            ActivatableNotificationView row = (ActivatableNotificationView) child;
             float notificationClipEnd;
             boolean aboveShelf = ViewState.getFinalTranslationZ(row) > baseZHeight
                     || row.isPinned();
@@ -324,43 +299,58 @@
             }
             int clipTop = updateNotificationClipHeight(row, notificationClipEnd, notGoneIndex);
             clipTopAmount = Math.max(clipTop, clipTopAmount);
-            float inShelfAmount = updateIconAppearance(row, expandAmount, scrolling, scrollingFast,
-                    expandingAnimated, isLastChild);
-            numViewsInShelf += inShelfAmount;
-            int ownColorUntinted = row.getBackgroundColorWithoutTint();
-            if (rowTranslationY >= shelfStart && mNotGoneIndex == -1) {
-                mNotGoneIndex = notGoneIndex;
-                setTintColor(previousColor);
-                setOverrideTintColor(colorTwoBefore, transitionAmount);
 
-            } else if (mNotGoneIndex == -1) {
-                colorTwoBefore = previousColor;
-                transitionAmount = inShelfAmount;
-            }
-            if (isLastChild) {
-                if (colorOfViewBeforeLast == NO_COLOR) {
+            // If the current row is an ExpandableNotificationRow, update its color, roundedness,
+            // and icon state.
+            if (row instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow expandableRow = (ExpandableNotificationRow) row;
+
+                float inShelfAmount = updateIconAppearance(expandableRow, expandAmount, scrolling,
+                        scrollingFast,
+                        expandingAnimated, isLastChild);
+                numViewsInShelf += inShelfAmount;
+                int ownColorUntinted = row.getBackgroundColorWithoutTint();
+                if (rowTranslationY >= shelfStart && mNotGoneIndex == -1) {
+                    mNotGoneIndex = notGoneIndex;
+                    setTintColor(previousColor);
+                    setOverrideTintColor(colorTwoBefore, transitionAmount);
+
+                } else if (mNotGoneIndex == -1) {
+                    colorTwoBefore = previousColor;
+                    transitionAmount = inShelfAmount;
+                }
+                // We don't want to modify the color if the notification is hun'd
+                boolean canModifyColor = mAmbientState.isShadeExpanded()
+                        && !(mAmbientState.isOnKeyguard() && mBypassController.getBypassEnabled());
+                if (isLastChild && canModifyColor) {
+                    if (colorOfViewBeforeLast == NO_COLOR) {
+                        colorOfViewBeforeLast = ownColorUntinted;
+                    }
+                    row.setOverrideTintColor(colorOfViewBeforeLast, inShelfAmount);
+                } else {
                     colorOfViewBeforeLast = ownColorUntinted;
+                    row.setOverrideTintColor(NO_COLOR, 0 /* overrideAmount */);
                 }
-                row.setOverrideTintColor(colorOfViewBeforeLast, inShelfAmount);
-            } else {
-                colorOfViewBeforeLast = ownColorUntinted;
-                row.setOverrideTintColor(NO_COLOR, 0 /* overrideAmount */);
-            }
-            if (notGoneIndex != 0 || !aboveShelf) {
-                row.setAboveShelf(false);
-            }
-            if (notGoneIndex == 0) {
-                StatusBarIconView icon = row.getEntry().expandedIcon;
-                NotificationIconContainer.IconState iconState = getIconState(icon);
-                // The icon state might be null in rare cases where the notification is actually
-                // added to the layout, but not to the shelf. An example are replied messages, since
-                // they don't show up on AOD
-                if (iconState != null && iconState.clampedAppearAmount == 1.0f) {
-                    // only if the first icon is fully in the shelf we want to clip to it!
-                    backgroundTop = (int) (row.getTranslationY() - getTranslationY());
-                    firstElementRoundness = row.getCurrentTopRoundness();
+                if (notGoneIndex != 0 || !aboveShelf) {
+                    expandableRow.setAboveShelf(false);
                 }
+                if (notGoneIndex == 0) {
+                    StatusBarIconView icon = expandableRow.getEntry().expandedIcon;
+                    NotificationIconContainer.IconState iconState = getIconState(icon);
+                    // The icon state might be null in rare cases where the notification is actually
+                    // added to the layout, but not to the shelf. An example are replied messages,
+                    // since they don't show up on AOD
+                    if (iconState != null && iconState.clampedAppearAmount == 1.0f) {
+                        // only if the first icon is fully in the shelf we want to clip to it!
+                        backgroundTop = (int) (row.getTranslationY() - getTranslationY());
+                        firstElementRoundness = row.getCurrentTopRoundness();
+                    }
+                }
+
+                previousColor = ownColorUntinted;
+                notGoneIndex++;
             }
+
             if (row.isFirstInSection() && previousRow != null && previousRow.isLastInSection()) {
                 // If the top of the shelf is between the view before a gap and the view after a gap
                 // then we need to adjust the shelf's top roundness.
@@ -379,8 +369,6 @@
                     backgroundTop = (int) distanceToGapBottom;
                 }
             }
-            notGoneIndex++;
-            previousColor = ownColorUntinted;
             previousRow = row;
         }
         clipTransientViews();
@@ -442,7 +430,7 @@
         }
         StatusBarIconView icon = row.getEntry().expandedIcon;
         float shelfIconPosition = getTranslationY() + icon.getTop() + icon.getTranslationY();
-        if (shelfIconPosition < maxTop && !mAmbientState.isFullyDark()) {
+        if (shelfIconPosition < maxTop && !mAmbientState.isFullyHidden()) {
             int top = (int) (maxTop - shelfIconPosition);
             Rect clipRect = new Rect(0, top, icon.getWidth(), Math.max(top, icon.getHeight()));
             icon.setClipBounds(clipRect);
@@ -497,13 +485,17 @@
      * Update the clipping of this view.
      * @return the amount that our own top should be clipped
      */
-    private int updateNotificationClipHeight(ExpandableNotificationRow row,
+    private int updateNotificationClipHeight(ActivatableNotificationView row,
             float notificationClipEnd, int childIndex) {
         float viewEnd = row.getTranslationY() + row.getActualHeight();
         boolean isPinned = (row.isPinned() || row.isHeadsUpAnimatingAway())
                 && !mAmbientState.isDozingAndNotPulsing(row);
-        boolean shouldClipOwnTop = row.showingAmbientPulsing()
-                || (mAmbientState.isPulseExpanding() && childIndex == 0);
+        boolean shouldClipOwnTop;
+        if (mAmbientState.isPulseExpanding()) {
+            shouldClipOwnTop = childIndex == 0;
+        } else {
+            shouldClipOwnTop = row.showingPulsing();
+        }
         if (viewEnd > notificationClipEnd && !shouldClipOwnTop
                 && (mAmbientState.isShadeExpanded() || !isPinned)) {
             int clipBottomAmount = (int) (viewEnd - notificationClipEnd);
@@ -656,8 +648,8 @@
             iconState.translateContent = false;
         }
         float transitionAmount;
-        if (mAmbientState.isDarkAtAll() && !row.isInShelf()) {
-            transitionAmount = mAmbientState.isFullyDark() ? 1 : 0;
+        if (mAmbientState.isHiddenAtAll() && !row.isInShelf()) {
+            transitionAmount = mAmbientState.isFullyHidden() ? 1 : 0;
         } else if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount
                 || iconState.useLinearTransitionAmount) {
             transitionAmount = iconTransitionAmount;
@@ -672,7 +664,7 @@
                 ? fullTransitionAmount
                 : transitionAmount;
         iconState.clampedAppearAmount = clampedAmount;
-        float contentTransformationAmount = !row.isAboveShelf()
+        float contentTransformationAmount = !row.isAboveShelf() && !row.showingPulsing()
                     && (isLastChild || iconState.translateContent)
                 ? iconTransitionAmount
                 : 0.0f;
@@ -707,7 +699,7 @@
         }
         notificationIconPosition += iconTopPadding;
         float shelfIconPosition = getTranslationY() + icon.getTop();
-        float iconSize = mDark ? mDarkShelfIconSize : mIconSize;
+        float iconSize = mAmbientState.isFullyHidden() ? mHiddenShelfIconSize : mIconSize;
         shelfIconPosition += (icon.getHeight() - icon.getIconScale() * iconSize) / 2.0f;
         float iconYTranslation = NotificationUtils.interpolate(
                 notificationIconPosition - shelfIconPosition,
@@ -742,7 +734,9 @@
                 iconState.scaleY = 1.0f;
                 iconState.hidden = false;
             }
-            if (row.isAboveShelf() || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
+            if (row.isAboveShelf()
+                    || row.showingPulsing()
+                    || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
                     || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) {
                 iconState.hidden = true;
             }
@@ -784,12 +778,12 @@
 
     @Override
     protected boolean needsOutline() {
-        return !mHideBackground && !mDark && super.needsOutline();
+        return !mHideBackground && super.needsOutline();
     }
 
     @Override
     protected boolean shouldHideBackground() {
-        return super.shouldHideBackground() || mHideBackground || mDark;
+        return super.shouldHideBackground() || mHideBackground;
     }
 
     @Override
@@ -900,8 +894,7 @@
     }
 
     private void updateInteractiveness() {
-        mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf
-                && !mDark;
+        mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf;
         setClickable(mInteractive);
         setFocusable(mInteractive);
         setImportantForAccessibility(mInteractive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
@@ -919,7 +912,6 @@
 
     public void setAnimationsEnabled(boolean enabled) {
         mAnimationsEnabled = enabled;
-        mCollapsedIcons.setAnimationsEnabled(enabled);
         if (!enabled) {
             // we need to wait with enabling the animations until the first frame has passed
             mShelfIcons.setAnimationsEnabled(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index b3da62e..22c9164 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -16,8 +16,11 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.Dependency.MAIN_HANDLER_NAME;
+
 import android.content.Context;
 import android.content.res.Resources;
+import android.os.Handler;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.Log;
@@ -33,9 +36,10 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.UnlockMethodCache;
+import com.android.systemui.util.Assert;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -43,6 +47,7 @@
 import java.util.Stack;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 import javax.inject.Singleton;
 
 import dagger.Lazy;
@@ -58,6 +63,8 @@
 public class NotificationViewHierarchyManager implements DynamicPrivacyController.Listener {
     private static final String TAG = "NotificationViewHierarchyManager";
 
+    private final Handler mHandler;
+
     //TODO: change this top <Entry, List<Entry>>?
     private final HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>>
             mTmpChildOrderMap = new HashMap<>();
@@ -80,12 +87,20 @@
     private final boolean mAlwaysExpandNonGroupedNotification;
     private final BubbleData mBubbleData;
     private final DynamicPrivacyController mDynamicPrivacyController;
+    private final KeyguardBypassController mBypassController;
 
     private NotificationPresenter mPresenter;
     private NotificationListContainer mListContainer;
 
+    // Used to help track down re-entrant calls to our update methods, which will cause bugs.
+    private boolean mPerformingUpdate;
+    // Hack to get around re-entrant call in onDynamicPrivacyChanged() until we can track down
+    // the problem.
+    private boolean mIsHandleDynamicPrivacyChangeScheduled;
+
     @Inject
     public NotificationViewHierarchyManager(Context context,
+            @Named(MAIN_HANDLER_NAME) Handler mainHandler,
             NotificationLockscreenUserManager notificationLockscreenUserManager,
             NotificationGroupManager groupManager,
             VisualStabilityManager visualStabilityManager,
@@ -93,8 +108,11 @@
             NotificationEntryManager notificationEntryManager,
             Lazy<ShadeController> shadeController,
             BubbleData bubbleData,
+            KeyguardBypassController bypassController,
             DynamicPrivacyController privacyController) {
+        mHandler = mainHandler;
         mLockscreenUserManager = notificationLockscreenUserManager;
+        mBypassController = bypassController;
         mGroupManager = groupManager;
         mVisualStabilityManager = visualStabilityManager;
         mStatusBarStateController = (SysuiStatusBarStateController) statusBarStateController;
@@ -119,6 +137,9 @@
      */
     //TODO: Rewrite this to focus on Entries, or some other data object instead of views
     public void updateNotificationViews() {
+        Assert.isMainThread();
+        beginUpdate();
+
         ArrayList<NotificationEntry> activeNotifications = mEntryManager.getNotificationData()
                 .getActiveNotifications();
         ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
@@ -151,7 +172,7 @@
             boolean deviceSensitive = devicePublic
                     && !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(
                     currentUserId);
-            ent.getRow().setSensitive(sensitive, deviceSensitive);
+            ent.setSensitive(sensitive, deviceSensitive);
             ent.getRow().setNeedsRedaction(needsRedaction);
             if (mGroupManager.isChildInGroupWithSummary(ent.notification)) {
                 NotificationEntry summary = mGroupManager.getGroupSummary(ent.notification);
@@ -244,9 +265,11 @@
         // clear the map again for the next usage
         mTmpChildOrderMap.clear();
 
-        updateRowStates();
+        updateRowStatesInternal();
 
         mListContainer.onNotificationViewUpdateFinished();
+
+        endUpdate();
     }
 
     private void addNotificationChildrenAndSort() {
@@ -330,13 +353,20 @@
      * Updates expanded, dimmed and locked states of notification rows.
      */
     public void updateRowStates() {
+        Assert.isMainThread();
+        beginUpdate();
+        updateRowStatesInternal();
+        endUpdate();
+    }
+
+    private void updateRowStatesInternal() {
         Trace.beginSection("NotificationViewHierarchyManager#updateRowStates");
         final int N = mListContainer.getContainerChildCount();
 
         int visibleNotifications = 0;
         boolean onKeyguard = mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
         int maxNotifications = -1;
-        if (onKeyguard) {
+        if (onKeyguard && !mBypassController.getBypassEnabled()) {
             maxNotifications = mPresenter.getMaxNotificationsWhileLocked(true /* recompute */);
         }
         mListContainer.setMaxDisplayedNotifications(maxNotifications);
@@ -364,7 +394,6 @@
                         && !row.isLowPriority()));
             }
 
-            entry.getRow().setOnAmbient(mShadeController.get().isDozing());
             int userId = entry.notification.getUserId();
             boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
                     entry.notification) && !entry.isRowRemoved();
@@ -420,6 +449,34 @@
 
     @Override
     public void onDynamicPrivacyChanged() {
+        if (mPerformingUpdate) {
+            Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call");
+        }
+        // This listener can be called from updateNotificationViews() via a convoluted listener
+        // chain, so we post here to prevent a re-entrant call. See b/136186188
+        // TODO: Refactor away the need for this
+        if (!mIsHandleDynamicPrivacyChangeScheduled) {
+            mIsHandleDynamicPrivacyChangeScheduled = true;
+            mHandler.post(this::onHandleDynamicPrivacyChanged);
+        }
+    }
+
+    private void onHandleDynamicPrivacyChanged() {
+        mIsHandleDynamicPrivacyChangeScheduled = false;
         updateNotificationViews();
     }
+
+    private void beginUpdate() {
+        if (mPerformingUpdate) {
+            Log.wtf(TAG, "Re-entrant code during update", new Exception());
+        }
+        mPerformingUpdate = true;
+    }
+
+    private void endUpdate() {
+        if (!mPerformingUpdate) {
+            Log.wtf(TAG, "Manager state has become desynced", new Exception());
+        }
+        mPerformingUpdate = false;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index a9d4fde..48d6de9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -25,18 +25,23 @@
 import android.os.PowerManager.WAKE_REASON_GESTURE
 import android.os.SystemClock
 import android.view.MotionEvent
+import android.view.VelocityTracker
 import android.view.ViewConfiguration
+import com.android.systemui.Dependency
 
 import com.android.systemui.Gefingerpoken
 import com.android.systemui.Interpolators
 import com.android.systemui.R
-import com.android.systemui.classifier.FalsingManagerFactory
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.ShadeController
+import com.android.systemui.statusbar.policy.HeadsUpManager
 
 import javax.inject.Inject
 import javax.inject.Singleton
@@ -48,22 +53,46 @@
 @Singleton
 class PulseExpansionHandler @Inject
 constructor(context: Context,
-            private val mWakeUpCoordinator: NotificationWakeUpCoordinator) : Gefingerpoken {
+            private val wakeUpCoordinator: NotificationWakeUpCoordinator,
+            private val bypassController: KeyguardBypassController,
+            private val headsUpManager: HeadsUpManagerPhone,
+            private val roundnessManager: NotificationRoundnessManager) : Gefingerpoken {
     companion object {
         private val RUBBERBAND_FACTOR_STATIC = 0.25f
         private val SPRING_BACK_ANIMATION_LENGTH_MS = 375
     }
     private val mPowerManager: PowerManager?
-    private var mShadeController: ShadeController? = null
+    private lateinit var shadeController: ShadeController
 
     private val mMinDragDistance: Int
     private var mInitialTouchX: Float = 0.0f
     private var mInitialTouchY: Float = 0.0f
     var isExpanding: Boolean = false
+        private set(value) {
+            val changed = field != value
+            field = value
+            bypassController.isPulseExpanding = value
+            if (changed) {
+                if (value) {
+                    val topEntry = headsUpManager.topEntry
+                    topEntry?.let {
+                        roundnessManager.setTrackingHeadsUp(it.row)
+                    }
+                } else {
+                    roundnessManager.setTrackingHeadsUp(null)
+                    if (!leavingLockscreen) {
+                        bypassController.maybePerformPendingUnlock()
+                        pulseExpandAbortListener?.run()
+                    }
+                }
+                headsUpManager.unpinAll(true /* userUnPinned */)
+            }
+        }
+    var leavingLockscreen: Boolean = false
         private set
     private val mTouchSlop: Float
-    private var mExpansionCallback: ExpansionCallback? = null
-    private lateinit var mStackScroller: NotificationStackScrollLayout
+    private lateinit var expansionCallback: ExpansionCallback
+    private lateinit var stackScroller: NotificationStackScrollLayout
     private val mTemp2 = IntArray(2)
     private var mDraggedFarEnough: Boolean = false
     private var mStartingChild: ExpandableView? = null
@@ -74,15 +103,19 @@
     private var mEmptyDragAmount: Float = 0.0f
     private var mWakeUpHeight: Float = 0.0f
     private var mReachedWakeUpHeight: Boolean = false
+    private var velocityTracker: VelocityTracker? = null
 
     private val isFalseTouch: Boolean
         get() = mFalsingManager.isFalseTouch
+    var qsExpanded: Boolean = false
+    var pulseExpandAbortListener: Runnable? = null
+    var bouncerShowing: Boolean = false
 
     init {
         mMinDragDistance = context.resources.getDimensionPixelSize(
                 R.dimen.keyguard_drag_down_min_distance)
         mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat()
-        mFalsingManager = FalsingManagerFactory.getInstance(context)
+        mFalsingManager = Dependency.get(FalsingManager::class.java)
         mPowerManager = context.getSystemService(PowerManager::class.java)
     }
 
@@ -91,9 +124,14 @@
     }
 
     private fun maybeStartExpansion(event: MotionEvent): Boolean {
-        if (!mPulsing) {
+        if (!wakeUpCoordinator.canShowPulsingHuns || qsExpanded
+                || bouncerShowing) {
             return false
         }
+        if (velocityTracker == null) {
+            velocityTracker = VelocityTracker.obtain()
+        }
+        velocityTracker!!.addMovement(event)
         val x = event.x
         val y = event.y
 
@@ -101,6 +139,7 @@
             MotionEvent.ACTION_DOWN -> {
                 mDraggedFarEnough = false
                 isExpanding = false
+                leavingLockscreen = false
                 mStartingChild = null
                 mInitialTouchY = y
                 mInitialTouchX = x
@@ -114,29 +153,52 @@
                     captureStartingChild(mInitialTouchX, mInitialTouchY)
                     mInitialTouchY = y
                     mInitialTouchX = x
-                    mWakeUpHeight = mWakeUpCoordinator.getWakeUpHeight()
+                    mWakeUpHeight = wakeUpCoordinator.getWakeUpHeight()
                     mReachedWakeUpHeight = false
                     return true
                 }
             }
+
+            MotionEvent.ACTION_UP -> {
+                recycleVelocityTracker();
+            }
+
+            MotionEvent.ACTION_CANCEL -> {
+                recycleVelocityTracker();
+            }
         }
         return false
     }
 
+    private fun recycleVelocityTracker() {
+        velocityTracker?.recycle();
+        velocityTracker = null
+    }
+
     override fun onTouchEvent(event: MotionEvent): Boolean {
         if (!isExpanding) {
             return maybeStartExpansion(event)
         }
+        velocityTracker!!.addMovement(event)
         val y = event.y
 
+        val moveDistance = y - mInitialTouchY
         when (event.actionMasked) {
-            MotionEvent.ACTION_MOVE -> updateExpansionHeight(y - mInitialTouchY)
-            MotionEvent.ACTION_UP -> if (!mFalsingManager.isUnlockingDisabled && !isFalseTouch) {
-                finishExpansion()
-            } else {
-                cancelExpansion()
+            MotionEvent.ACTION_MOVE -> updateExpansionHeight(moveDistance)
+            MotionEvent.ACTION_UP -> {
+                velocityTracker!!.computeCurrentVelocity(1000 /* units */)
+                val canExpand = moveDistance > 0 && velocityTracker!!.getYVelocity() > -1000
+                if (!mFalsingManager.isUnlockingDisabled && !isFalseTouch && canExpand) {
+                    finishExpansion()
+                } else {
+                    cancelExpansion()
+                }
+                recycleVelocityTracker()
             }
-            MotionEvent.ACTION_CANCEL -> cancelExpansion()
+            MotionEvent.ACTION_CANCEL -> {
+                cancelExpansion()
+                recycleVelocityTracker()
+            }
         }
         return isExpanding
     }
@@ -147,12 +209,15 @@
             setUserLocked(mStartingChild!!, false)
             mStartingChild = null
         }
+        if (shadeController.isDozing) {
+            isWakingToShadeLocked = true
+            wakeUpCoordinator.willWakeUp = true
+            mPowerManager!!.wakeUp(SystemClock.uptimeMillis(), WAKE_REASON_GESTURE,
+                    "com.android.systemui:PULSEDRAG")
+        }
+        shadeController.goToLockedShade(mStartingChild)
+        leavingLockscreen = true;
         isExpanding = false
-        isWakingToShadeLocked = true
-        mWakeUpCoordinator.willWakeUp = true
-        mPowerManager!!.wakeUp(SystemClock.uptimeMillis(), WAKE_REASON_GESTURE,
-                "com.android.systemui:PULSEDRAG")
-        mShadeController!!.goToLockedShade(mStartingChild)
         if (mStartingChild is ExpandableNotificationRow) {
             val row = mStartingChild as ExpandableNotificationRow?
             row!!.onExpandedByGesture(true /* userExpanded */)
@@ -172,17 +237,17 @@
             expansionHeight = max(newHeight.toFloat(), expansionHeight)
         } else {
             val target = if (mReachedWakeUpHeight) mWakeUpHeight else 0.0f
-            mWakeUpCoordinator.setNotificationsVisibleForExpansion(height > target,
+            wakeUpCoordinator.setNotificationsVisibleForExpansion(height > target,
                     true /* animate */,
                     true /* increaseSpeed */)
             expansionHeight = max(mWakeUpHeight, expansionHeight)
         }
-        val emptyDragAmount = mWakeUpCoordinator.setPulseHeight(expansionHeight)
+        val emptyDragAmount = wakeUpCoordinator.setPulseHeight(expansionHeight)
         setEmptyDragAmount(emptyDragAmount * RUBBERBAND_FACTOR_STATIC)
     }
 
     private fun captureStartingChild(x: Float, y: Float) {
-        if (mStartingChild == null) {
+        if (mStartingChild == null && !bypassController.bypassEnabled) {
             mStartingChild = findView(x, y)
             if (mStartingChild != null) {
                 setUserLocked(mStartingChild!!, true)
@@ -192,7 +257,7 @@
 
     private fun setEmptyDragAmount(amount: Float) {
         mEmptyDragAmount = amount
-        mExpansionCallback!!.setEmptyDragAmount(amount)
+        expansionCallback.setEmptyDragAmount(amount)
     }
 
     private fun reset(child: ExpandableView) {
@@ -227,6 +292,7 @@
     }
 
     private fun cancelExpansion() {
+        isExpanding = false
         mFalsingManager.onExpansionFromPulseStopped()
         if (mStartingChild != null) {
             reset(mStartingChild!!)
@@ -234,30 +300,29 @@
         } else {
             resetClock()
         }
-        mWakeUpCoordinator.setNotificationsVisibleForExpansion(false /* visible */,
+        wakeUpCoordinator.setNotificationsVisibleForExpansion(false /* visible */,
                 true /* animate */,
                 false /* increaseSpeed */)
-        isExpanding = false
     }
 
     private fun findView(x: Float, y: Float): ExpandableView? {
         var totalX = x
         var totalY = y
-        mStackScroller.getLocationOnScreen(mTemp2)
+        stackScroller.getLocationOnScreen(mTemp2)
         totalX += mTemp2[0].toFloat()
         totalY += mTemp2[1].toFloat()
-        val childAtRawPosition = mStackScroller.getChildAtRawPosition(totalX, totalY)
+        val childAtRawPosition = stackScroller.getChildAtRawPosition(totalX, totalY)
         return if (childAtRawPosition != null && childAtRawPosition.isContentExpandable) {
             childAtRawPosition
         } else null
     }
 
-    fun setUp(notificationStackScroller: NotificationStackScrollLayout,
-             expansionCallback: ExpansionCallback,
-             shadeController: ShadeController) {
-        mExpansionCallback = expansionCallback
-        mShadeController = shadeController
-        mStackScroller = notificationStackScroller
+    fun setUp(stackScroller: NotificationStackScrollLayout,
+              expansionCallback: ExpansionCallback,
+              shadeController: ShadeController) {
+        this.expansionCallback = expansionCallback
+        this.shadeController = shadeController
+        this.stackScroller = stackScroller
     }
 
     fun setPulsing(pulsing: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 6552fe6..f4af9ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -112,7 +112,7 @@
     };
 
     private boolean mAlwaysScaleIcon;
-    private int mStatusBarIconDrawingSizeDark = 1;
+    private int mStatusBarIconDrawingSizeIncreased = 1;
     private int mStatusBarIconDrawingSize = 1;
     private int mStatusBarIconSize = 1;
     private StatusBarIcon mIcon;
@@ -139,7 +139,7 @@
     private int mDrawableColor;
     private int mIconColor;
     private int mDecorColor;
-    private float mDarkAmount;
+    private float mDozeAmount;
     private ValueAnimator mColorAnimator;
     private int mCurrentSetColor = NO_COLOR;
     private int mAnimationStartColor = NO_COLOR;
@@ -158,6 +158,7 @@
     private Runnable mLayoutRunnable;
     private boolean mDismissed;
     private Runnable mOnDismissListener;
+    private boolean mIncreasedSize;
 
     public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
         this(context, slot, sbn, false);
@@ -196,12 +197,10 @@
     }
 
     private void updateIconScaleForNotifications() {
-        final float imageBounds = NotificationUtils.interpolate(
-                mStatusBarIconDrawingSize,
-                mStatusBarIconDrawingSizeDark,
-                mDarkAmount);
+        final float imageBounds = mIncreasedSize ?
+                mStatusBarIconDrawingSizeIncreased : mStatusBarIconDrawingSize;
         final int outerBounds = mStatusBarIconSize;
-        mIconScale = (float)imageBounds / (float)outerBounds;
+        mIconScale = imageBounds / (float)outerBounds;
         updatePivot();
     }
 
@@ -225,8 +224,8 @@
         }
     }
 
-    public float getIconScaleFullyDark() {
-        return (float) mStatusBarIconDrawingSizeDark / mStatusBarIconDrawingSize;
+    public float getIconScaleIncreased() {
+        return (float) mStatusBarIconDrawingSizeIncreased / mStatusBarIconDrawingSize;
     }
 
     public float getIconScale() {
@@ -256,7 +255,7 @@
         Resources res = getResources();
         mStaticDotRadius = res.getDimensionPixelSize(R.dimen.overflow_dot_radius);
         mStatusBarIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
-        mStatusBarIconDrawingSizeDark =
+        mStatusBarIconDrawingSizeIncreased =
                 res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size_dark);
         mStatusBarIconDrawingSize =
                 res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
@@ -584,7 +583,7 @@
     }
 
     private void updateDecorColor() {
-        int color = NotificationUtils.interpolateColors(mDecorColor, Color.WHITE, mDarkAmount);
+        int color = NotificationUtils.interpolateColors(mDecorColor, Color.WHITE, mDozeAmount);
         if (mDotPaint.getColor() != color) {
             mDotPaint.setColor(color);
 
@@ -618,13 +617,13 @@
                 mMatrixColorFilter = new ColorMatrixColorFilter(mMatrix);
             }
             int color = NotificationUtils.interpolateColors(
-                    mCurrentSetColor, Color.WHITE, mDarkAmount);
-            updateTintMatrix(mMatrix, color, DARK_ALPHA_BOOST * mDarkAmount);
+                    mCurrentSetColor, Color.WHITE, mDozeAmount);
+            updateTintMatrix(mMatrix, color, DARK_ALPHA_BOOST * mDozeAmount);
             mMatrixColorFilter.setColorMatrixArray(mMatrix);
             setColorFilter(null);  // setColorFilter only invalidates if the instance changed.
             setColorFilter(mMatrixColorFilter);
         } else {
-            mDozer.updateGrayscale(this, mDarkAmount);
+            mDozer.updateGrayscale(this, mDozeAmount);
         }
     }
 
@@ -855,19 +854,18 @@
         mOnVisibilityChangedListener = listener;
     }
 
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mDozer.setIntensityDark(f -> {
-            mDarkAmount = f;
-            maybeUpdateIconScaleDimens();
+    public void setDozing(boolean dozing, boolean fade, long delay) {
+        mDozer.setDozing(f -> {
+            mDozeAmount = f;
             updateDecorColor();
             updateIconColor();
             updateAllowAnimation();
-        }, dark, fade, delay, this);
+        }, dozing, fade, delay, this);
     }
 
     private void updateAllowAnimation() {
-        if (mDarkAmount == 0 || mDarkAmount == 1) {
-            setAllowAnimation(mDarkAmount == 0);
+        if (mDozeAmount == 0 || mDozeAmount == 1) {
+            setAllowAnimation(mDozeAmount == 0);
         }
     }
 
@@ -949,6 +947,11 @@
         return mBlocked;
     }
 
+    public void setIncreasedSize(boolean increasedSize) {
+        mIncreasedSize = increasedSize;
+        maybeUpdateIconScaleDimens();
+    }
+
     public interface OnVisibilityChangedListener {
         void onVisibilityChanged(int newVisibility);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index eb386dc..f0eeb04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -20,6 +20,7 @@
 import android.animation.ValueAnimator;
 import android.text.format.DateFormat;
 import android.util.FloatProperty;
+import android.view.View;
 import android.view.animation.Interpolator;
 
 import com.android.internal.annotations.GuardedBy;
@@ -77,6 +78,16 @@
     private HistoricalState[] mHistoricalRecords = new HistoricalState[HISTORY_SIZE];
 
     /**
+     * Current SystemUiVisibility
+     */
+    private int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+
+    /**
+     * If the device is currently pulsing (AOD2).
+     */
+    private boolean mPulsing;
+
+    /**
      * If the device is currently dozing or not.
      */
     private boolean mIsDozing;
@@ -292,6 +303,30 @@
         return mKeyguardRequested;
     }
 
+    @Override
+    public void setSystemUiVisibility(int visibility) {
+        if (mSystemUiVisibility != visibility) {
+            mSystemUiVisibility = visibility;
+            synchronized (mListeners) {
+                for (RankedListener rl : new ArrayList<>(mListeners)) {
+                    rl.mListener.onSystemUiVisibilityChanged(mSystemUiVisibility);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setPulsing(boolean pulsing) {
+        if (mPulsing != pulsing) {
+            mPulsing = pulsing;
+            synchronized (mListeners) {
+                for (RankedListener rl : new ArrayList<>(mListeners)) {
+                    rl.mListener.onPulsingChanged(pulsing);
+                }
+            }
+        }
+    }
+
     /**
      * Returns String readable state of status bar from {@link StatusBarState}
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
index dc5e1e9..2ad979ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
@@ -111,6 +111,16 @@
     boolean isKeyguardRequested();
 
     /**
+     * Set systemui visibility
+     */
+    void setSystemUiVisibility(int visibility);
+
+    /**
+     * Set pulsing
+     */
+    void setPulsing(boolean visibility);
+
+    /**
      * Listener with rankings SbStateListenerRank that have dependencies so must be updated
      * in a certain order
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt
new file mode 100644
index 0000000..ea474ce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
+import android.content.Context
+import android.media.MediaMetadata
+import android.provider.Settings
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationMediaManager
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.tuner.TunerService
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * A class that automatically creates heads up for important notification when bypassing the
+ * lockscreen
+ */
+@Singleton
+class BypassHeadsUpNotifier @Inject constructor(
+        private val context: Context,
+        private val bypassController: KeyguardBypassController,
+        private val statusBarStateController: StatusBarStateController,
+        private val headsUpManager: HeadsUpManagerPhone,
+        private val mediaManager: NotificationMediaManager,
+        tunerService: TunerService) : StatusBarStateController.StateListener,
+        NotificationMediaManager.MediaListener {
+
+    private lateinit var entryManager: NotificationEntryManager
+    private var currentMediaEntry: NotificationEntry? = null
+    private var enabled = true
+
+    var fullyAwake = false
+        set(value) {
+            field = value
+            if (value) {
+                updateAutoHeadsUp(currentMediaEntry)
+            }
+        }
+
+    init {
+        statusBarStateController.addCallback(this)
+        tunerService.addTunable(
+                TunerService.Tunable { _, _ ->
+                    enabled = Settings.Secure.getIntForUser(
+                            context.contentResolver,
+                            Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING,
+                            1 /* default */,
+                            KeyguardUpdateMonitor.getCurrentUser()) != 0
+                }, Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING)
+    }
+
+    fun setUp(entryManager: NotificationEntryManager) {
+        this.entryManager = entryManager
+        mediaManager.addCallback(this)
+    }
+
+    override fun onMetadataOrStateChanged(metadata: MediaMetadata?, state: Int) {
+        val previous = currentMediaEntry
+        var newEntry = entryManager.notificationData.get(mediaManager.mediaNotificationKey)
+        if (!NotificationMediaManager.isPlayingState(state)) {
+            newEntry = null
+        }
+        if (newEntry?.isSensitive == true) {
+            newEntry = null
+        }
+        currentMediaEntry = newEntry
+        updateAutoHeadsUp(previous)
+        updateAutoHeadsUp(currentMediaEntry)
+    }
+
+    private fun updateAutoHeadsUp(entry: NotificationEntry?) {
+        entry?.let {
+            val autoHeadsUp = it == currentMediaEntry && canAutoHeadsUp()
+            it.isAutoHeadsUp = autoHeadsUp
+            if (autoHeadsUp) {
+                headsUpManager.showNotification(it)
+            }
+        }
+    }
+
+    override fun onStatePostChange() {
+        updateAutoHeadsUp(currentMediaEntry)
+    }
+
+    private fun canAutoHeadsUp() : Boolean {
+        if (!enabled) {
+            return false
+        }
+        if (!bypassController.bypassEnabled) {
+            return false
+        }
+        if (statusBarStateController.state != StatusBarState.KEYGUARD) {
+            return false
+        }
+        if (!fullyAwake) {
+            return false
+        }
+        return true
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
index f6d3cdf..d71d407 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification;
 
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
 
 import android.app.Notification;
@@ -25,8 +24,6 @@
 import android.util.Log;
 
 import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.statusbar.AlertingNotificationManager;
-import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -45,7 +42,6 @@
 
     private static final String TAG = "NotifAlertManager";
 
-    private final AmbientPulseManager mAmbientPulseManager;
     private final NotificationRemoteInputManager mRemoteInputManager;
     private final VisualStabilityManager mVisualStabilityManager;
     private final Lazy<ShadeController> mShadeController;
@@ -57,13 +53,11 @@
     @Inject
     public NotificationAlertingManager(
             NotificationEntryManager notificationEntryManager,
-            AmbientPulseManager ambientPulseManager,
             NotificationRemoteInputManager remoteInputManager,
             VisualStabilityManager visualStabilityManager,
             Lazy<ShadeController> shadeController,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationListener notificationListener) {
-        mAmbientPulseManager = ambientPulseManager;
         mRemoteInputManager = remoteInputManager;
         mVisualStabilityManager = visualStabilityManager;
         mShadeController = shadeController;
@@ -108,44 +102,31 @@
             // If it does and we no longer need to heads up, we should free the view.
             if (mNotificationInterruptionStateProvider.shouldHeadsUp(entry)) {
                 mHeadsUpManager.showNotification(entry);
-                // Mark as seen immediately
-                setNotificationShown(entry.notification);
+                if (!mShadeController.get().isDozing()) {
+                    // Mark as seen immediately
+                    setNotificationShown(entry.notification);
+                }
             } else {
                 entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
             }
         }
-        if ((inflatedFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
-            if (mNotificationInterruptionStateProvider.shouldPulse(entry)) {
-                mAmbientPulseManager.showNotification(entry);
-            } else {
-                entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
-            }
-        }
     }
 
     private void updateAlertState(NotificationEntry entry) {
         boolean alertAgain = alertAgain(entry, entry.notification.getNotification());
-        AlertingNotificationManager alertManager;
         boolean shouldAlert;
-        if (mShadeController.get().isDozing()) {
-            alertManager = mAmbientPulseManager;
-            shouldAlert = mNotificationInterruptionStateProvider.shouldPulse(entry);
-        } else {
-            alertManager = mHeadsUpManager;
-            shouldAlert = mNotificationInterruptionStateProvider.shouldHeadsUp(entry);
-        }
-        final boolean wasAlerting = alertManager.isAlerting(entry.key);
+        shouldAlert = mNotificationInterruptionStateProvider.shouldHeadsUp(entry);
+        final boolean wasAlerting = mHeadsUpManager.isAlerting(entry.key);
         if (wasAlerting) {
-            if (!shouldAlert) {
+            if (shouldAlert) {
+                mHeadsUpManager.updateNotification(entry.key, alertAgain);
+            } else if (!mHeadsUpManager.isEntryAutoHeadsUpped(entry.key)) {
                 // We don't want this to be interrupting anymore, let's remove it
-                alertManager.removeNotification(entry.key,
-                        false /* ignoreEarliestRemovalTime */);
-            } else {
-                alertManager.updateNotification(entry.key, alertAgain);
+                mHeadsUpManager.removeNotification(entry.key, false /* removeImmediately */);
             }
         } else if (shouldAlert && alertAgain) {
             // This notification was updated to be alerting, show it!
-            alertManager.showNotification(entry);
+            mHeadsUpManager.showNotification(entry);
         }
     }
 
@@ -171,7 +152,7 @@
     }
 
     private void stopAlerting(final String key) {
-        // Attempt to remove notifications from their alert managers (heads up, ambient pulse).
+        // Attempt to remove notifications from their alert manager.
         // Though the remove itself may fail, it lets the manager know to remove as soon as
         // possible.
         if (mHeadsUpManager.isAlerting(key)) {
@@ -185,8 +166,5 @@
                             || !mVisualStabilityManager.isReorderingAllowed();
             mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
         }
-        if (mAmbientPulseManager.isAlerting(key)) {
-            mAmbientPulseManager.removeNotification(key, false /* ignoreEarliestRemovalTime */);
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index ef042ba..63bb73a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -79,10 +79,11 @@
         animator.start();
     }
 
-    public void setIntensityDark(Consumer<Float> listener, boolean dark,
+    public void setDozing(Consumer<Float> listener, boolean dozing,
             boolean animate, long delay, View view) {
         if (animate) {
-            startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dark, delay,
+            startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dozing,
+                    delay,
                     new AnimatorListenerAdapter() {
 
                         @Override
@@ -100,7 +101,7 @@
             if (animator != null) {
                 animator.cancel();
             }
-            listener.accept(dark ? 1f : 0f);
+            listener.accept(dozing ? 1f : 0f);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
index 1aa6bc9..dfc6450 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
@@ -24,6 +24,8 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
 
+import androidx.annotation.NonNull;
+
 /**
  * Listener interface for changes sent by NotificationEntryManager.
  */
@@ -45,7 +47,7 @@
     /**
      * Called when a new entry is created.
      */
-    default void onNotificationAdded(NotificationEntry entry) {
+    default void onNotificationAdded(@NonNull NotificationEntry entry) {
     }
 
     /**
@@ -61,7 +63,7 @@
     /**
      * Called when a notification was updated, after any filtering of notifications have occurred.
      */
-    default void onPostEntryUpdated(NotificationEntry entry) {
+    default void onPostEntryUpdated(@NonNull NotificationEntry entry) {
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index e8388ce..879a8df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -355,10 +355,10 @@
                     // a child we're keeping around for reply!
                     continue;
                 }
-                entry.setKeepInParent(true);
+                childEntry.setKeepInParent(true);
                 // we need to set this state earlier as otherwise we might generate some weird
                 // animations
-                entry.removeRow();
+                childEntry.removeRow();
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
index 926d4b6..5bab0ef3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
@@ -39,6 +39,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -186,14 +187,15 @@
      * @return true if the entry should heads up, false otherwise
      */
     public boolean shouldHeadsUp(NotificationEntry entry) {
-        StatusBarNotification sbn = entry.notification;
-
-        if (getShadeController().isDozing()) {
-            if (DEBUG) {
-                Log.d(TAG, "No heads up: device is dozing: " + sbn.getKey());
-            }
-            return false;
+        if (mStatusBarStateController.isDozing()) {
+            return shouldHeadsUpWhenDozing(entry);
+        } else {
+            return shouldHeadsUpWhenAwake(entry);
         }
+    }
+
+    private boolean shouldHeadsUpWhenAwake(NotificationEntry entry) {
+        StatusBarNotification sbn = entry.notification;
 
         boolean inShade = mStatusBarStateController.getState() == SHADE;
         if (entry.isBubble() && inShade) {
@@ -251,7 +253,7 @@
      * @param entry the entry to check
      * @return true if the entry should ambient pulse, false otherwise
      */
-    public boolean shouldPulse(NotificationEntry entry) {
+    private boolean shouldHeadsUpWhenDozing(NotificationEntry entry) {
         StatusBarNotification sbn = entry.notification;
 
         if (!mAmbientDisplayConfiguration.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) {
@@ -261,13 +263,6 @@
             return false;
         }
 
-        if (!getShadeController().isDozing()) {
-            if (DEBUG) {
-                Log.d(TAG, "No pulsing: not dozing: " + sbn.getKey());
-            }
-            return false;
-        }
-
         if (!canAlertCommon(entry)) {
             if (DEBUG) {
                 Log.d(TAG, "No pulsing: notification shouldn't alert: " + sbn.getKey());
@@ -288,24 +283,14 @@
             }
             return false;
         }
-
-        Bundle extras = sbn.getNotification().extras;
-        CharSequence title = extras.getCharSequence(Notification.EXTRA_TITLE);
-        CharSequence text = extras.getCharSequence(Notification.EXTRA_TEXT);
-        if (TextUtils.isEmpty(title) && TextUtils.isEmpty(text)) {
-            if (DEBUG) {
-                Log.d(TAG, "No pulsing: title and text are empty: " + sbn.getKey());
-            }
-            return false;
-        }
-
-        return true;
+         return true;
     }
 
     /**
-     * Common checks between heads up alerting and ambient pulse alerting.  See
+     * Common checks between regular heads up and when pulsing.  See
      * {@link #shouldHeadsUp(NotificationEntry)} and
-     * {@link #shouldPulse(NotificationEntry)}.  Notifications that fail any of these checks
+     * {@link #shouldHeadsUpWhenDozing(NotificationEntry)}.  Notifications that fail any of these
+     * checks
      * should not alert at all.
      *
      * @param entry the entry to check
@@ -389,6 +374,19 @@
         return mPresenter;
     }
 
+    /**
+     * When an entry was added, should we launch its fullscreen intent? Examples are Alarms or
+     * incoming calls.
+     *
+     * @param entry the entry that was added
+     * @return {@code true} if we should launch the full screen intent
+     */
+    public boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry) {
+        return entry.notification.getNotification().fullScreenIntent != null
+            && (!shouldHeadsUp(entry)
+                || mStatusBarStateController.getState() == StatusBarState.KEYGUARD);
+    }
+
     /** A component which can suppress heads-up notifications due to the overall state of the UI. */
     public interface HeadsUpSuppressor {
         /**
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 3613f9f..6a3816c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -21,13 +21,15 @@
 import android.util.FloatProperty
 import com.android.systemui.Interpolators
 import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.statusbar.AmbientPulseManager
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator
 import com.android.systemui.statusbar.phone.DozeParameters
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
 import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
 
 import javax.inject.Inject
 import javax.inject.Singleton
@@ -35,10 +37,10 @@
 @Singleton
 class NotificationWakeUpCoordinator @Inject constructor(
         private val mContext: Context,
-        private val mAmbientPulseManager: AmbientPulseManager,
-        private val mStatusBarStateController: StatusBarStateController,
-        private val mBypassController: KeyguardBypassController)
-    : AmbientPulseManager.OnAmbientChangedListener, StatusBarStateController.StateListener {
+        private val mHeadsUpManagerPhone: HeadsUpManagerPhone,
+        private val statusBarStateController: StatusBarStateController,
+        private val bypassController: KeyguardBypassController)
+    : OnHeadsUpChangedListener, StatusBarStateController.StateListener {
 
     private val mNotificationVisibility
             = object : FloatProperty<NotificationWakeUpCoordinator>("notificationVisibility") {
@@ -59,12 +61,18 @@
     private var mNotificationVisibleAmount = 0.0f
     private var mNotificationsVisible = false
     private var mNotificationsVisibleForExpansion = false
-    private var mDarkAnimator: ObjectAnimator? = null
+    private var mVisibilityAnimator: ObjectAnimator? = null
     private var mVisibilityAmount = 0.0f
     private var mLinearVisibilityAmount = 0.0f
     private var mWakingUp = false
     private val mEntrySetToClearWhenFinished = mutableSetOf<NotificationEntry>()
-    private val mDozeParameters: DozeParameters;
+    private val mDozeParameters: DozeParameters
+    private var pulseExpanding: Boolean = false
+    private val wakeUpListeners = arrayListOf<WakeUpListener>()
+    private var state: Int = StatusBarState.KEYGUARD
+
+    var fullyAwake: Boolean = false
+
     var willWakeUp = false
         set(value) {
             if (!value || mDozeAmount != 0.0f) {
@@ -72,6 +80,7 @@
             }
         }
 
+    lateinit var iconAreaController : NotificationIconAreaController
     var pulsing: Boolean = false
         set(value) {
             field = value
@@ -84,17 +93,52 @@
             }
         }
 
+    var notificationsFullyHidden: Boolean = false
+        private set(value) {
+            if (field != value) {
+                field = value
+                for (listener in wakeUpListeners) {
+                    listener.onFullyHiddenChanged(value)
+                }
+            }
+        }
+
+    /**
+     * True if we can show pulsing heads up notifications
+     */
+    var canShowPulsingHuns: Boolean = false
+        private set
+        get() {
+            var canShow = pulsing
+            if (bypassController.bypassEnabled) {
+                // We also allow pulsing on the lock screen!
+                canShow = canShow || (mWakingUp || willWakeUp || fullyAwake)
+                        && statusBarStateController.state == StatusBarState.KEYGUARD
+            }
+            return canShow
+        }
 
     init {
-        mAmbientPulseManager.addListener(this)
-        mStatusBarStateController.addCallback(this)
+        mHeadsUpManagerPhone.addListener(this)
+        statusBarStateController.addCallback(this)
         mDozeParameters = DozeParameters.getInstance(mContext)
     }
 
     fun setStackScroller(stackScroller: NotificationStackScrollLayout) {
         mStackScroller = stackScroller
+        pulseExpanding = stackScroller.isPulseExpanding
+        stackScroller.setOnPulseHeightChangedListener {
+            val nowExpanding = isPulseExpanding()
+            val changed = nowExpanding != pulseExpanding
+            pulseExpanding = nowExpanding
+            for (listener in wakeUpListeners) {
+                listener.onPulseExpansionChanged(changed)
+            }
+        }
     }
 
+    fun isPulseExpanding(): Boolean = mStackScroller.isPulseExpanding
+
     /**
      * @param visible should notifications be visible
      * @param animate should this change be animated
@@ -108,13 +152,23 @@
             // If we stopped expanding and we're still visible because we had a pulse that hasn't
             // times out, let's release them all to make sure were not stuck in a state where
             // notifications are visible
-            mAmbientPulseManager.releaseAllImmediately()
+            mHeadsUpManagerPhone.releaseAllImmediately()
         }
     }
 
+    fun addListener(listener: WakeUpListener) {
+        wakeUpListeners.add(listener);
+    }
+
+    fun removeFullyHiddenChangedListener(listener: WakeUpListener) {
+        wakeUpListeners.remove(listener);
+    }
+
     private fun updateNotificationVisibility(animate: Boolean, increaseSpeed: Boolean) {
-        var visible = (mNotificationsVisibleForExpansion || mAmbientPulseManager.hasNotifications())
-                && pulsing;
+        // TODO: handle Lockscreen wakeup for bypass when we're not pulsing anymore
+        var visible = mNotificationsVisibleForExpansion || mHeadsUpManagerPhone.hasNotifications()
+        visible = visible && canShowPulsingHuns
+
         if (!visible && mNotificationsVisible && (mWakingUp || willWakeUp) && mDozeAmount != 0.0f) {
             // let's not make notifications invisible while waking up, otherwise the animation
             // is strange
@@ -129,7 +183,7 @@
             return
         }
         mNotificationsVisible = visible
-        mDarkAnimator?.cancel();
+        mVisibilityAnimator?.cancel();
         if (animate) {
             notifyAnimationStart(visible)
             startVisibilityAnimation(increaseSpeed)
@@ -155,7 +209,7 @@
         mLinearDozeAmount = linear
         mDozeAmount = eased
         mStackScroller.setDozeAmount(mDozeAmount)
-        updateDarkAmount()
+        updateHideAmount()
         if (changed && linear == 0.0f) {
             setNotificationsVisible(visible = false, animate = false, increaseSpeed = false);
             setNotificationsVisibleForExpansion(visible = false, animate = false,
@@ -165,13 +219,21 @@
 
     override fun onStateChanged(newState: Int) {
         updateDozeAmountIfBypass();
+        if (bypassController.bypassEnabled &&
+                newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED
+                && (!statusBarStateController.isDozing || shouldAnimateVisibility())) {
+            // We're leaving shade locked. Let's animate the notifications away
+            setNotificationsVisible(visible = true, increaseSpeed = false, animate = false)
+            setNotificationsVisible(visible = false, increaseSpeed = false, animate = true)
+        }
+        this.state = newState
     }
 
     private fun updateDozeAmountIfBypass(): Boolean {
-        if (mBypassController.bypassEnabled) {
+        if (bypassController.bypassEnabled) {
             var amount = 1.0f;
-            if (mStatusBarStateController.state == StatusBarState.SHADE
-                    || mStatusBarStateController.state == StatusBarState.SHADE_LOCKED) {
+            if (statusBarStateController.state == StatusBarState.SHADE
+                    || statusBarStateController.state == StatusBarState.SHADE_LOCKED) {
                 amount = 0.0f;
             }
             setDozeAmount(amount,  amount)
@@ -188,15 +250,15 @@
                 Interpolators.FAST_OUT_SLOW_IN_REVERSE
         }
         val target = if (mNotificationsVisible) 1.0f else 0.0f
-        val darkAnimator = ObjectAnimator.ofFloat(this, mNotificationVisibility, target)
-        darkAnimator.setInterpolator(Interpolators.LINEAR)
+        val visibilityAnimator = ObjectAnimator.ofFloat(this, mNotificationVisibility, target)
+        visibilityAnimator.setInterpolator(Interpolators.LINEAR)
         var duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP.toLong()
         if (increaseSpeed) {
             duration = (duration.toFloat() / 1.5F).toLong();
         }
-        darkAnimator.setDuration(duration)
-        darkAnimator.start()
-        mDarkAnimator = darkAnimator
+        visibilityAnimator.setDuration(duration)
+        visibilityAnimator.start()
+        mVisibilityAnimator = visibilityAnimator
     }
 
     private fun setVisibilityAmount(visibilityAmount: Float) {
@@ -204,28 +266,29 @@
         mVisibilityAmount = mVisibilityInterpolator.getInterpolation(
                 visibilityAmount)
         handleAnimationFinished();
-        updateDarkAmount()
+        updateHideAmount()
     }
 
     private fun handleAnimationFinished() {
         if (mLinearDozeAmount == 0.0f || mLinearVisibilityAmount == 0.0f) {
-            mEntrySetToClearWhenFinished.forEach { it.setAmbientGoingAway(false) }
+            mEntrySetToClearWhenFinished.forEach { it.setHeadsUpAnimatingAway(false) }
             mEntrySetToClearWhenFinished.clear()
         }
     }
 
     fun getWakeUpHeight() : Float {
-        return mStackScroller.pulseHeight
+        return mStackScroller.wakeUpHeight
     }
 
-    private fun updateDarkAmount() {
+    private fun updateHideAmount() {
         val linearAmount = Math.min(1.0f - mLinearVisibilityAmount, mLinearDozeAmount)
         val amount = Math.min(1.0f - mVisibilityAmount, mDozeAmount)
-        mStackScroller.setDarkAmount(linearAmount, amount)
+        mStackScroller.setHideAmount(linearAmount, amount)
+        notificationsFullyHidden = linearAmount == 1.0f;
     }
 
     private fun notifyAnimationStart(awake: Boolean) {
-        mStackScroller.notifyDarkAnimationStart(!awake)
+        mStackScroller.notifyHideAnimationStart(!awake)
     }
 
     override fun onDozingChanged(isDozing: Boolean) {
@@ -234,39 +297,60 @@
         }
     }
 
+    /**
+     * Set the height how tall notifications are pulsing. This is only set whenever we are expanding
+     * from a pulse and determines how much the notifications are expanded.
+     */
     fun setPulseHeight(height: Float): Float {
-        return mStackScroller.setPulseHeight(height)
+        val overflow = mStackScroller.setPulseHeight(height)
+        //  no overflow for the bypass experience
+        return if (bypassController.bypassEnabled) 0.0f else overflow
     }
 
     fun setWakingUp(wakingUp: Boolean) {
         willWakeUp = false
         mWakingUp = wakingUp
-        if (wakingUp && mNotificationsVisible && !mNotificationsVisibleForExpansion) {
+        if (wakingUp && mNotificationsVisible && !mNotificationsVisibleForExpansion
+                && !bypassController.bypassEnabled) {
             // We're waking up while pulsing, let's make sure the animation looks nice
             mStackScroller.wakeUpFromPulse();
         }
     }
 
-    override fun onAmbientStateChanged(entry: NotificationEntry, isPulsing: Boolean) {
+    override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
         var animate = shouldAnimateVisibility()
-        if (!isPulsing) {
+        if (!isHeadsUp) {
             if (mLinearDozeAmount != 0.0f && mLinearVisibilityAmount != 0.0f) {
                 if (entry.isRowDismissed) {
                     // if we animate, we see the shelf briefly visible. Instead we fully animate
                     // the notification and its background out
                     animate = false
                 } else if (!mWakingUp && !willWakeUp){
-                    entry.setAmbientGoingAway(true)
+                    // TODO: look that this is done properly and not by anyone else
+                    entry.setHeadsUpAnimatingAway(true)
                     mEntrySetToClearWhenFinished.add(entry)
                 }
             }
         } else if (mEntrySetToClearWhenFinished.contains(entry)) {
             mEntrySetToClearWhenFinished.remove(entry)
-            entry.setAmbientGoingAway(false)
+            entry.setHeadsUpAnimatingAway(false)
         }
         updateNotificationVisibility(animate, increaseSpeed = false)
     }
 
     private fun shouldAnimateVisibility() =
             mDozeParameters.getAlwaysOn() && !mDozeParameters.getDisplayNeedsBlanking()
+
+    interface WakeUpListener {
+        /**
+         * Called whenever the notifications are fully hidden or shown
+         */
+        @JvmDefault fun onFullyHiddenChanged(isFullyHidden: Boolean) {}
+
+        /**
+         * Called whenever the pulseExpansion changes
+         * @param expandingChanged if the user has started or stopped expanding
+         */
+        @JvmDefault fun onPulseExpansionChanged(expandingChanged: Boolean) {}
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
index aacb22d..fe56552 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
@@ -115,7 +115,20 @@
         view.setTag(animationEndTag, newEndValue);
     }
 
-    public static <T extends View> boolean isAnimating(T view, AnimatableProperty property) {
-        return  view.getTag(property.getAnimatorTag()) != null;
+    public static <T extends View> void applyImmediately(T view, AnimatableProperty property,
+            float newValue) {
+        cancelAnimation(view, property);
+        property.getProperty().set(view, newValue);
+    }
+
+    public static void cancelAnimation(View view, AnimatableProperty property) {
+        ValueAnimator animator = (ValueAnimator) view.getTag(property.getAnimatorTag());
+        if (animator != null) {
+            animator.cancel();
+        }
+    }
+
+    public static boolean isAnimating(View view, AnimatableProperty property) {
+        return view.getTag(property.getAnimatorTag()) != null;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
new file mode 100644
index 0000000..847d1cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.Interpolators
+import com.android.systemui.R
+
+/**
+ * Class to help with fading of view groups without fading one subview
+ */
+class ViewGroupFadeHelper {
+    companion object {
+        private val visibilityIncluder = {
+            view: View -> view.visibility == View.VISIBLE
+        }
+
+        /**
+         * Fade out all views of a root except a single child. This will iterate over all children
+         * of the view and make sure that the animation works smoothly.
+         * @param root the view root to fade the children away
+         * @param excludedView which view should remain
+         * @param duration the duration of the animation
+         */
+        @JvmStatic
+        fun fadeOutAllChildrenExcept(root: ViewGroup, excludedView: View, duration: Long,
+                                     endRunnable: Runnable?) {
+            // starting from the view going up, we are adding the siblings of the child to the set
+            // of views that need to be faded.
+            val viewsToFadeOut = gatherViews(root, excludedView, visibilityIncluder)
+
+            // Applying the right layertypes for the animation
+            for (viewToFade in viewsToFadeOut) {
+                if (viewToFade.hasOverlappingRendering
+                        && viewToFade.layerType == View.LAYER_TYPE_NONE) {
+                    viewToFade.setLayerType(View.LAYER_TYPE_HARDWARE, null)
+                    viewToFade.setTag(R.id.view_group_fade_helper_hardware_layer, true)
+                }
+            }
+
+            val animator = ValueAnimator.ofFloat(1.0f, 0.0f).apply {
+                this.duration = duration
+                interpolator = Interpolators.ALPHA_OUT
+                addUpdateListener { animation ->
+                    val previousSetAlpha = root.getTag(
+                            R.id.view_group_fade_helper_previous_value_tag) as Float?
+                    val newAlpha = animation.animatedValue as Float
+                    for (viewToFade in viewsToFadeOut) {
+                        if (viewToFade.alpha != previousSetAlpha) {
+                            // A value was set that wasn't set from our view, let's store it and restore
+                            // it at the end
+                            viewToFade.setTag(R.id.view_group_fade_helper_restore_tag, viewToFade.alpha)
+                        }
+                        viewToFade.alpha = newAlpha
+                    }
+                    root.setTag(R.id.view_group_fade_helper_previous_value_tag, newAlpha)
+                }
+                addListener(object : AnimatorListenerAdapter() {
+                    override fun onAnimationEnd(animation: Animator?) {
+                        endRunnable?.run()
+                    }
+                })
+                start()
+            }
+            root.setTag(R.id.view_group_fade_helper_modified_views, viewsToFadeOut)
+            root.setTag(R.id.view_group_fade_helper_animator, animator)
+        }
+
+        private fun gatherViews(root: ViewGroup, excludedView: View,
+                                shouldInclude: (View) -> Boolean): MutableSet<View> {
+            val viewsToFadeOut = mutableSetOf<View>()
+            var parent = excludedView.parent as ViewGroup?
+            var viewContainingExcludedView = excludedView;
+            while (parent != null) {
+                for (i in 0 until parent.childCount) {
+                    val child = parent.getChildAt(i)
+                    if (shouldInclude.invoke(child) && viewContainingExcludedView != child) {
+                        viewsToFadeOut.add(child)
+                    }
+                }
+                if (parent == root) {
+                    break;
+                }
+                viewContainingExcludedView = parent
+                parent = parent.parent as ViewGroup?
+            }
+            return viewsToFadeOut
+        }
+
+        /**
+         * Reset all view alphas for views previously transformed away.
+         */
+        @JvmStatic
+        fun reset(root: ViewGroup) {
+            @Suppress("UNCHECKED_CAST")
+            val modifiedViews = root.getTag(R.id.view_group_fade_helper_modified_views)
+                    as MutableSet<View>?
+            val animator = root.getTag(R.id.view_group_fade_helper_animator) as Animator?
+            if (modifiedViews == null || animator == null) {
+                // nothing to restore
+                return
+            }
+            animator.cancel()
+            val lastSetValue = root.getTag(
+                    R.id.view_group_fade_helper_previous_value_tag) as Float?
+            for (viewToFade in modifiedViews) {
+                val restoreAlpha = viewToFade.getTag(
+                        R.id.view_group_fade_helper_restore_tag) as Float?
+                if (restoreAlpha == null) {
+                    continue
+                }
+                if (lastSetValue == viewToFade.alpha) {
+                    // it was modified after the transition!
+                    viewToFade.alpha = restoreAlpha
+                }
+                val needsLayerReset = viewToFade.getTag(
+                        R.id.view_group_fade_helper_hardware_layer) as Boolean?
+                if (needsLayerReset == true) {
+                    viewToFade.setLayerType(View.LAYER_TYPE_NONE, null)
+                    viewToFade.setTag(R.id.view_group_fade_helper_hardware_layer, null)
+                }
+                viewToFade.setTag(R.id.view_group_fade_helper_restore_tag, null)
+            }
+            root.setTag(R.id.view_group_fade_helper_modified_views, null)
+            root.setTag(R.id.view_group_fade_helper_previous_value_tag, null)
+            root.setTag(R.id.view_group_fade_helper_animator, null)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index 396a3a7..4a6c7d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -16,18 +16,26 @@
 
 package com.android.systemui.statusbar.notification;
 
+import static com.android.systemui.Dependency.MAIN_HANDLER_NAME;
+
+import android.os.Handler;
+import android.os.SystemClock;
 import android.view.View;
 
 import androidx.collection.ArraySet;
 
+import com.android.systemui.Dumpable;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 import javax.inject.Singleton;
 
 /**
@@ -35,14 +43,19 @@
  * and reorder at the right time when they are out of view.
  */
 @Singleton
-public class VisualStabilityManager implements OnHeadsUpChangedListener {
+public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpable {
+
+    private static final long TEMPORARY_REORDERING_ALLOWED_DURATION = 1000;
 
     private final ArrayList<Callback> mCallbacks =  new ArrayList<>();
+    private final Handler mHandler;
 
     private NotificationPresenter mPresenter;
     private boolean mPanelExpanded;
     private boolean mScreenOn;
     private boolean mReorderingAllowed;
+    private boolean mIsTemporaryReorderingAllowed;
+    private long mTemporaryReorderingStart;
     private VisibilityLocationProvider mVisibilityLocationProvider;
     private ArraySet<View> mAllowedReorderViews = new ArraySet<>();
     private ArraySet<NotificationEntry> mLowPriorityReorderingViews = new ArraySet<>();
@@ -50,7 +63,12 @@
     private boolean mPulsing;
 
     @Inject
-    public VisualStabilityManager(NotificationEntryManager notificationEntryManager) {
+    public VisualStabilityManager(
+            NotificationEntryManager notificationEntryManager,
+            @Named(MAIN_HANDLER_NAME) Handler handler) {
+
+        mHandler = handler;
+
         notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
             @Override
             public void onPreEntryUpdated(NotificationEntry entry) {
@@ -114,10 +132,11 @@
     }
 
     private void updateReorderingAllowed() {
-        boolean reorderingAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing;
-        boolean changed = reorderingAllowed && !mReorderingAllowed;
+        boolean reorderingAllowed =
+                (!mScreenOn || !mPanelExpanded || mIsTemporaryReorderingAllowed) && !mPulsing;
+        boolean changedToTrue = reorderingAllowed && !mReorderingAllowed;
         mReorderingAllowed = reorderingAllowed;
-        if (changed) {
+        if (changedToTrue) {
             notifyCallbacks();
         }
     }
@@ -180,6 +199,25 @@
     }
 
     /**
+     * Temporarily allows reordering of the entire shade for a period of 1000ms. Subsequent calls
+     * to this method will extend the timer.
+     */
+    public void temporarilyAllowReordering() {
+        mHandler.removeCallbacks(mOnTemporaryReorderingExpired);
+        mHandler.postDelayed(mOnTemporaryReorderingExpired, TEMPORARY_REORDERING_ALLOWED_DURATION);
+        if (!mIsTemporaryReorderingAllowed) {
+            mTemporaryReorderingStart = SystemClock.elapsedRealtime();
+        }
+        mIsTemporaryReorderingAllowed = true;
+        updateReorderingAllowed();
+    }
+
+    private final Runnable mOnTemporaryReorderingExpired = () -> {
+        mIsTemporaryReorderingAllowed = false;
+        updateReorderingAllowed();
+    };
+
+    /**
      * Notify the visual stability manager that a new view was added and should be allowed to
      * reorder next time.
      */
@@ -187,6 +225,20 @@
         mAddedChildren.add(view);
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("VisualStabilityManager state:");
+        pw.print("  mIsTemporaryReorderingAllowed="); pw.println(mIsTemporaryReorderingAllowed);
+        pw.print("  mTemporaryReorderingStart="); pw.println(mTemporaryReorderingStart);
+
+        long now = SystemClock.elapsedRealtime();
+        pw.print("    Temporary reordering window has been open for ");
+        pw.print(now - (mIsTemporaryReorderingAllowed ? mTemporaryReorderingStart : now));
+        pw.println("ms");
+
+        pw.println();
+    }
+
     public interface Callback {
         /**
          * Called when reordering is allowed again.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
index 64b2f04..fca520f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
@@ -114,8 +114,6 @@
             } else if (isHeadsUp) {
                 // Provide consistent ranking with headsUpManager
                 return mHeadsUpManager.compare(a, b);
-            } else if (a.getRow().showingAmbientPulsing() != b.getRow().showingAmbientPulsing()) {
-                return a.getRow().showingAmbientPulsing() ? -1 : 1;
             } else if (aMedia != bMedia) {
                 // Upsort current media notification.
                 return aMedia ? -1 : 1;
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 a3e18ef..b19d2ca 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
@@ -96,6 +96,7 @@
     public StatusBarIconView icon;
     public StatusBarIconView expandedIcon;
     public StatusBarIconView centeredIcon;
+    public StatusBarIconView aodIcon;
     private boolean interruption;
     public boolean autoRedacted; // whether the redacted notification was generated by us
     public int targetSdk;
@@ -122,7 +123,6 @@
     public boolean suspended;
 
     private NotificationEntry parent; // our parent (if we're in a group)
-    private ArrayList<NotificationEntry> children = new ArrayList<NotificationEntry>();
     private ExpandableNotificationRow row; // the outer expanded view
 
     private int mCachedContrastColor = COLOR_INVALID;
@@ -173,6 +173,9 @@
      * the lock screen/status bar and in the top section in the shade.
      */
     private boolean mHighPriority;
+    private boolean mSensitive = true;
+    private Runnable mOnSensitiveChangedListener;
+    private boolean mAutoHeadsUp;
 
     public NotificationEntry(StatusBarNotification n) {
         this(n, null);
@@ -277,10 +280,20 @@
 
     @Nullable
     public List<NotificationEntry> getChildren() {
-        if (children.size() <= 0) {
+        if (row == null) {
             return null;
         }
 
+        List<ExpandableNotificationRow> rowChildren = row.getNotificationChildren();
+        if (rowChildren == null) {
+            return null;
+        }
+
+        ArrayList<NotificationEntry> children = new ArrayList<>();
+        for (ExpandableNotificationRow child : rowChildren) {
+            children.add(child.getEntry());
+        }
+
         return children;
     }
 
@@ -327,6 +340,12 @@
                 sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
         expandedIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
+        // Construct the expanded icon.
+        aodIcon = new StatusBarIconView(context,
+                sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
+        aodIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+        aodIcon.setIncreasedSize(true);
+
         final StatusBarIcon ic = new StatusBarIcon(
                 sbn.getUser(),
                 sbn.getPackageName(),
@@ -335,10 +354,11 @@
                 n.number,
                 StatusBarIconView.contentDescForNotification(context, n));
 
-        if (!icon.set(ic) || !expandedIcon.set(ic)) {
+        if (!icon.set(ic) || !expandedIcon.set(ic) || !aodIcon.set(ic)) {
             icon = null;
             expandedIcon = null;
             centeredIcon = null;
+            aodIcon = null;
             throw new InflationException("Couldn't create icon: " + ic);
         }
         expandedIcon.setVisibility(View.INVISIBLE);
@@ -371,6 +391,10 @@
         if (centeredIcon != null) {
             centeredIcon.setTag(key, tag);
         }
+
+        if (aodIcon != null) {
+            aodIcon.setTag(key, tag);
+        }
     }
 
     /**
@@ -394,7 +418,8 @@
                     StatusBarIconView.contentDescForNotification(context, n));
             icon.setNotification(sbn);
             expandedIcon.setNotification(sbn);
-            if (!icon.set(ic) || !expandedIcon.set(ic)) {
+            aodIcon.setNotification(sbn);
+            if (!icon.set(ic) || !expandedIcon.set(ic) || !aodIcon.set(ic)) {
                 throw new InflationException("Couldn't update icon: " + ic);
             }
 
@@ -606,10 +631,6 @@
         if (row != null) row.freeContentViewWhenSafe(inflationFlag);
     }
 
-    public void setAmbientPulsing(boolean pulsing) {
-        if (row != null) row.setAmbientPulsing(pulsing);
-    }
-
     public boolean rowExists() {
         return row != null;
     }
@@ -638,23 +659,37 @@
         if (row != null) row.setPinned(pinned);
     }
 
-    public boolean isRowAnimatingAway() {
-        return row != null && row.isHeadsUpAnimatingAway();
-    }
-
     public boolean isRowHeadsUp() {
         return row != null && row.isHeadsUp();
     }
 
+    public boolean showingPulsing() {
+        return row != null && row.showingPulsing();
+    }
+
     public void setHeadsUp(boolean shouldHeadsUp) {
         if (row != null) row.setHeadsUp(shouldHeadsUp);
     }
 
-
-    public void setAmbientGoingAway(boolean goingAway) {
-        if (row != null) row.setAmbientGoingAway(goingAway);
+    public void setHeadsUpAnimatingAway(boolean animatingAway) {
+        if (row != null) row.setHeadsUpAnimatingAway(animatingAway);
     }
 
+    /**
+     * Set that this notification was automatically heads upped. This happens for example when
+     * the user bypasses the lockscreen and media is playing.
+     */
+    public void setAutoHeadsUp(boolean autoHeadsUp) {
+        mAutoHeadsUp = autoHeadsUp;
+    }
+
+    /**
+     * @return if this notification was automatically heads upped. This happens for example when
+     *      * the user bypasses the lockscreen and media is playing.
+     */
+    public boolean isAutoHeadsUp() {
+        return mAutoHeadsUp;
+    }
 
     public boolean mustStayOnScreen() {
         return row != null && row.mustStayOnScreen();
@@ -740,7 +775,9 @@
         if (notification == null || !notification.isClearable()) {
             return false;
         }
-        if (children.size() > 0) {
+
+        List<NotificationEntry> children = getChildren();
+        if (children != null && children.size() > 0) {
             for (int i = 0; i < children.size(); i++) {
                 NotificationEntry child =  children.get(i);
                 if (!child.isClearable()) {
@@ -839,6 +876,30 @@
         return Objects.equals(n.category, category);
     }
 
+    /**
+     * Set this notification to be sensitive.
+     *
+     * @param sensitive true if the content of this notification is sensitive right now
+     * @param deviceSensitive true if the device in general is sensitive right now
+     */
+    public void setSensitive(boolean sensitive, boolean deviceSensitive) {
+        getRow().setSensitive(sensitive, deviceSensitive);
+        if (sensitive != mSensitive) {
+            mSensitive = sensitive;
+            if (mOnSensitiveChangedListener != null) {
+                mOnSensitiveChangedListener.run();
+            }
+        }
+    }
+
+    public boolean isSensitive() {
+        return mSensitive;
+    }
+
+    public void setOnSensitiveChangedListener(Runnable listener) {
+        mOnSensitiveChangedListener = listener;
+    }
+
     /** Information about a suggestion that is being edited. */
     public static class EditedSuggestionInfo {
 
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 d3e5af8..247c31f 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
@@ -18,7 +18,6 @@
 
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
 
 import android.annotation.Nullable;
@@ -34,6 +33,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.UiOffloadThread;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -47,6 +47,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.row.RowInflaterTask;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -69,6 +70,8 @@
     private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
             this::logNotificationExpansion;
     private final boolean mAllowLongPress;
+    private final KeyguardBypassController mKeyguardBypassController;
+    private final StatusBarStateController mStatusBarStateController;
 
     private NotificationRemoteInputManager mRemoteInputManager;
     private NotificationPresenter mPresenter;
@@ -80,10 +83,14 @@
     private NotificationClicker mNotificationClicker;
     private final NotificationLogger mNotificationLogger = Dependency.get(NotificationLogger.class);
 
-    public NotificationRowBinderImpl(Context context, boolean allowLongPress) {
+    public NotificationRowBinderImpl(Context context, boolean allowLongPress,
+            KeyguardBypassController keyguardBypassController,
+            StatusBarStateController statusBarStateController) {
         mContext = context;
         mMessagingUtil = new NotificationMessagingUtil(context);
         mAllowLongPress = allowLongPress;
+        mKeyguardBypassController = keyguardBypassController;
+        mStatusBarStateController = statusBarStateController;
     }
 
     private NotificationRemoteInputManager getRemoteInputManager() {
@@ -144,6 +151,8 @@
             StatusBarNotification sbn, ExpandableNotificationRow row,
             Runnable onDismissRunnable) {
         row.setExpansionLogger(mExpansionLogger, entry.notification.getKey());
+        row.setBypassController(mKeyguardBypassController);
+        row.setStatusBarStateController(mStatusBarStateController);
         row.setGroupManager(mGroupManager);
         row.setHeadsUpManager(mHeadsUpManager);
         row.setOnExpandClickListener(mPresenter);
@@ -249,9 +258,6 @@
         if (mNotificationInterruptionStateProvider.shouldHeadsUp(entry)) {
             row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, true /* shouldInflate */);
         }
-        if (mNotificationInterruptionStateProvider.shouldPulse(entry)) {
-            row.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, true /* shouldInflate */);
-        }
         row.setNeedsRedaction(
                 Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry));
         row.inflateViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index 94f7e65..81275fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -101,7 +101,7 @@
 
     // Tracks notifications currently visible in mNotificationStackScroller and
     // emits visibility events via NoMan on changes.
-    protected final Runnable mVisibilityReporter = new Runnable() {
+    protected Runnable mVisibilityReporter = new Runnable() {
         private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
                 new ArraySet<>();
         private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
@@ -407,6 +407,11 @@
         mExpansionStateLogger.onExpansionChanged(key, isUserAction, isExpanded, location);
     }
 
+    @VisibleForTesting
+    public void setVisibilityReporter(Runnable visibilityReporter) {
+        mVisibilityReporter = visibilityReporter;
+    }
+
     /**
      * A listener that is notified when some child locations might have changed.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 94face2..8d73251 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -33,9 +33,9 @@
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.notification.FakeShadowView;
@@ -52,7 +52,6 @@
 
     private static final int BACKGROUND_ANIMATION_LENGTH_MS = 220;
     private static final int ACTIVATE_ANIMATION_LENGTH = 220;
-    private static final long DARK_ANIMATION_LENGTH = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
 
     /**
      * The amount of width, which is kept in the end when performing a disappear animation (also
@@ -85,11 +84,6 @@
     private static final float VERTICAL_ANIMATION_START = 1.0f;
 
     /**
-     * Scale for the background to animate from when exiting dark mode.
-     */
-    private static final float DARK_EXIT_SCALE_START = 0.93f;
-
-    /**
      * A sentinel value when no color should be used. Can be used with {@link #setTintColor(int)}
      * or {@link #setOverrideTintColor(int, float)}.
      */
@@ -105,7 +99,6 @@
     private final DoubleTapHelper mDoubleTapHelper;
 
     private boolean mDimmed;
-    protected boolean mDark;
 
     protected int mBgTint = NO_COLOR;
     private float mBgAlpha = 1f;
@@ -137,7 +130,7 @@
     private boolean mLastInSection;
     private boolean mFirstInSection;
     private boolean mIsBelowSpeedBump;
-    private FalsingManager mFalsingManager;
+    private final FalsingManager mFalsingManager;
 
     private float mNormalBackgroundVisibilityAmount;
     private float mDimmedBackgroundFadeInAmount = -1;
@@ -171,10 +164,10 @@
         super(context, attrs);
         mSlowOutFastInInterpolator = new PathInterpolator(0.8f, 0.0f, 0.6f, 1.0f);
         mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f);
+        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
         setClipChildren(false);
         setClipToPadding(false);
         updateColors();
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
         mAccessibilityManager = AccessibilityManager.getInstance(mContext);
 
         mDoubleTapHelper = new DoubleTapHelper(this, (active) -> {
@@ -440,16 +433,6 @@
         return true;
     }
 
-    public void setDark(boolean dark, boolean fade, long delay) {
-        super.setDark(dark, fade, delay);
-        if (mDark == dark) {
-            return;
-        }
-        mDark = dark;
-        updateBackground();
-        updateBackgroundTint(false);
-    }
-
     private void updateOutlineAlpha() {
         float alpha = NotificationStackScrollLayout.BACKGROUND_ALPHA_DIMMED;
         alpha = (alpha + (1.0f - alpha) * mNormalBackgroundVisibilityAmount);
@@ -542,10 +525,6 @@
      *                       used and the background color not at all.
      */
     public void setOverrideTintColor(int color, float overrideAmount) {
-        if (mDark) {
-            color = NO_COLOR;
-            overrideAmount = 0;
-        }
         mOverrideTint = color;
         mOverrideAmount = overrideAmount;
         int newColor = calculateBgColor();
@@ -1057,6 +1036,14 @@
         return false;
     }
 
+    public boolean isHeadsUp() {
+        return false;
+    }
+
+    public int getHeadsUpHeightWithoutHeader() {
+        return getHeight();
+    }
+
     public interface OnActivatedListener {
         void onActivated(ActivatableNotificationView view);
         void onActivationReset(ActivatableNotificationView view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
index b89b5cb..8e68227 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
@@ -29,6 +29,7 @@
 import android.graphics.drawable.ColorDrawable
 import android.util.Log
 import android.view.Gravity
+import android.view.View
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.view.Window
@@ -43,6 +44,18 @@
 
 const val TAG = "ChannelDialogController"
 
+/**
+ * ChannelEditorDialogController is the controller for the dialog half-shelf
+ * that allows users to quickly turn off channels. It is launched from the NotificationInfo
+ * guts view and displays controls for toggling app notifications as well as up to 4 channels
+ * from that app like so:
+ *
+ *   APP TOGGLE                                                 <on/off>
+ *   - Channel from which we launched                           <on/off>
+ *   -                                                          <on/off>
+ *   - the next 3 channels sorted alphabetically for that app   <on/off>
+ *   -                                                          <on/off>
+ */
 @Singleton
 class ChannelEditorDialogController @Inject constructor(
     c: Context,
@@ -58,6 +71,9 @@
     private var appName: String? = null
     private var onSettingsClickListener: NotificationInfo.OnSettingsClickListener? = null
 
+    // Caller should set this if they care about when we dismiss
+    var onFinishListener: OnChannelEditorDialogFinishedListener? = null
+
     // Channels handed to us from NotificationInfo
     @VisibleForTesting
     internal val providedChannels = mutableListOf<NotificationChannel>()
@@ -71,13 +87,17 @@
     internal val groupNameLookup = hashMapOf<String, CharSequence>()
     private val channelGroupList = mutableListOf<NotificationChannelGroup>()
 
+    /**
+     * Give the controller all of the information it needs to present the dialog
+     * for a given app. Does a bunch of querying of NoMan, but won't present anything yet
+     */
     fun prepareDialogForApp(
         appName: String,
         packageName: String,
         uid: Int,
         channels: Set<NotificationChannel>,
         appIcon: Drawable,
-        onSettingsClickListener: NotificationInfo.OnSettingsClickListener
+        onSettingsClickListener: NotificationInfo.OnSettingsClickListener?
     ) {
         this.appName = appName
         this.packageName = packageName
@@ -141,9 +161,17 @@
         dialog.show()
     }
 
+    /**
+     * Close the dialog without saving. For external callers
+     */
+    fun close() {
+        done()
+    }
+
     private fun done() {
         resetState()
         dialog.dismiss()
+        onFinishListener?.onChannelEditorDialogFinished()
     }
 
     private fun resetState() {
@@ -219,10 +247,17 @@
         }
     }
 
+    @VisibleForTesting
+    fun launchSettings(sender: View) {
+        onSettingsClickListener?.onClick(sender, null, appUid!!)
+    }
+
     private fun initDialog() {
         dialog = Dialog(context)
 
         dialog.window?.requestFeature(Window.FEATURE_NO_TITLE)
+        // Prevent a11y readers from reading the first element in the dialog twice
+        dialog.setTitle("\u00A0")
         dialog.apply {
             setContentView(R.layout.notif_half_shelf)
             setCanceledOnTouchOutside(true)
@@ -239,8 +274,8 @@
             }
 
             findViewById<TextView>(R.id.see_more_button)?.setOnClickListener {
-                onSettingsClickListener?.onClick(it, null, appUid!!)
-                dismiss()
+                launchSettings(it)
+                done()
             }
 
             window?.apply {
@@ -265,3 +300,7 @@
             or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
             or WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
 }
+
+interface OnChannelEditorDialogFinishedListener {
+    fun onChannelEditorDialogFinished()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
index 4d49760..6faf77e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Drawable
 import android.text.TextUtils
 import android.transition.AutoTransition
+import android.transition.Transition
 import android.transition.TransitionManager
 import android.util.AttributeSet
 import android.view.LayoutInflater
@@ -62,6 +63,23 @@
 
         val transition = AutoTransition()
         transition.duration = 200
+        transition.addListener(object : Transition.TransitionListener {
+            override fun onTransitionEnd(p0: Transition?) {
+                notifySubtreeAccessibilityStateChangedIfNeeded()
+            }
+
+            override fun onTransitionResume(p0: Transition?) {
+            }
+
+            override fun onTransitionPause(p0: Transition?) {
+            }
+
+            override fun onTransitionCancel(p0: Transition?) {
+            }
+
+            override fun onTransitionStart(p0: Transition?) {
+            }
+        })
         TransitionManager.beginDelayedTransition(this, transition)
 
         // Remove any rows
@@ -143,7 +161,7 @@
     private fun updateViews() {
         val nc = channel ?: return
 
-        channelName.text = nc.name ?: "(missing)"
+        channelName.text = nc.name ?: ""
 
         nc.group?.let { groupId ->
             channelDescription.text = controller.groupNameForId(groupId)
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 d625b31..6e84089 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
@@ -17,11 +17,9 @@
 package com.android.systemui.statusbar.notification.row;
 
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_PUBLIC;
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationCallback;
-import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_AMBIENT;
 import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
 import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
 
@@ -76,11 +74,11 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.RemoteInputController;
@@ -98,6 +96,7 @@
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -127,14 +126,16 @@
     private static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
     private boolean mUpdateBackgroundOnUpdate;
     private boolean mNotificationTranslationFinished = false;
-
     /**
      * Listener for when {@link ExpandableNotificationRow} is laid out.
      */
     public interface LayoutListener {
         void onLayout();
+
     }
 
+    private StatusBarStateController mStatusbarStateController;
+    private KeyguardBypassController mBypassController;
     private LayoutListener mLayoutListener;
     private final NotificationContentInflater mNotificationInflater;
     private int mIconTransformContentShift;
@@ -187,11 +188,6 @@
      */
     private boolean mOnKeyguard;
 
-    /**
-     * Whether or not the row is currently on the doze screen.
-     */
-    private boolean mOnAmbient;
-
     private Animator mTranslateAnim;
     private ArrayList<View> mTranslateableViews;
     private NotificationContentView mPublicLayout;
@@ -211,17 +207,6 @@
     private boolean mIsHeadsUp;
 
     /**
-     * Whether or not the notification is using the ambient display view and is pulsing.  This
-     * occurs when a high priority notification alerts while the phone is dozing or is on AOD.
-     */
-    private boolean mIsAmbientPulsing;
-
-    /**
-     * Happens when the notification was pulsing before and goes away to ensure smooth animations.
-     */
-    private boolean mAmbientGoingAway;
-
-    /**
      * Whether or not the notification should be redacted on the lock screen, i.e has sensitive
      * content which should be redacted on the lock screen.
      */
@@ -341,7 +326,6 @@
 
     private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
             new SystemNotificationAsyncTask();
-    private int mStatusBarState = -1;
 
     /**
      * Returns whether the given {@code statusBarNotification} is a system notification.
@@ -487,12 +471,6 @@
                 getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_HEADSUP,
                         freeViewRunnable);
                 break;
-            case FLAG_CONTENT_VIEW_AMBIENT:
-                getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_AMBIENT,
-                        freeViewRunnable);
-                getPublicLayout().performWhenContentInactive(VISIBLE_TYPE_AMBIENT,
-                        freeViewRunnable);
-                break;
             case FLAG_CONTENT_VIEW_PUBLIC:
                 getPublicLayout().performWhenContentInactive(VISIBLE_TYPE_CONTRACTED,
                         freeViewRunnable);
@@ -648,7 +626,7 @@
         if (!getShowingLayout().isDimmable()) {
             return false;
         }
-        if (showingAmbientPulsing()) {
+        if (showingPulsing()) {
             return false;
         }
         return super.isDimmable();
@@ -698,7 +676,7 @@
         if (headsUpWrapper != null) {
             headsUpHeight = Math.max(headsUpHeight, headsUpWrapper.getMinLayoutHeight());
         }
-        layout.setHeights(minHeight, headsUpHeight, mNotificationMaxHeight, headsUpHeight);
+        layout.setHeights(minHeight, headsUpHeight, mNotificationMaxHeight);
     }
 
     public StatusBarNotification getStatusBarNotification() {
@@ -709,6 +687,7 @@
         return mEntry;
     }
 
+    @Override
     public boolean isHeadsUp() {
         return mIsHeadsUp;
     }
@@ -734,14 +713,18 @@
     }
 
     @Override
-    public boolean showingAmbientPulsing() {
-        return mIsAmbientPulsing || mAmbientGoingAway;
+    public boolean showingPulsing() {
+        return isHeadsUpState() && (isDozing() || (mOnKeyguard && isBypassEnabled()));
     }
 
-    public void setAmbientPulsing(boolean isAmbientPulsing) {
-        mIsAmbientPulsing = isAmbientPulsing;
+    /**
+     * @return if the view is in heads up state, i.e either still heads upped or it's disappearing.
+     */
+    public boolean isHeadsUpState() {
+        return mIsHeadsUp || mHeadsupDisappearRunning;
     }
 
+
     public void setGroupManager(NotificationGroupManager groupManager) {
         mGroupManager = groupManager;
         mPrivateLayout.setGroupManager(groupManager);
@@ -1651,7 +1634,7 @@
 
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
         mNotificationInflater = new NotificationContentInflater(this);
         mMenuRow = new NotificationMenuRow(mContext);
         mImageResolver = new NotificationInlineImageResolver(context,
@@ -1660,6 +1643,14 @@
         initDimens();
     }
 
+    public void setBypassController(KeyguardBypassController bypassController) {
+        mBypassController = bypassController;
+    }
+
+    public void setStatusBarStateController(StatusBarStateController statusBarStateController) {
+        mStatusbarStateController = statusBarStateController;
+    }
+
     private void initDimens() {
         mNotificationMinHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext,
                 R.dimen.notification_min_height_legacy);
@@ -2050,23 +2041,6 @@
         return false;
     }
 
-    @Override
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (mDark == dark) {
-            return;
-        }
-        super.setDark(dark, fade, delay);
-        if (!mIsAmbientPulsing) {
-            // Only fade the showing view of the pulsing notification.
-            fade = false;
-        }
-        final NotificationContentView showing = getShowingLayout();
-        if (showing != null) {
-            showing.setDark(dark, fade, delay);
-        }
-        updateShelfIconColor();
-    }
-
     public void applyExpandAnimationParams(ExpandAnimationParameters params) {
         if (params == null) {
             return;
@@ -2180,7 +2154,9 @@
      */
     @Override
     public boolean isSoundEffectsEnabled() {
-        final boolean mute = mDark && mSecureStateProvider != null &&
+        final boolean mute = mStatusbarStateController != null
+                && mStatusbarStateController.isDozing()
+                && mSecureStateProvider != null &&
                 !mSecureStateProvider.getAsBoolean();
         return !mute && super.isSoundEffectsEnabled();
     }
@@ -2345,9 +2321,9 @@
             return mPrivateLayout.getMinHeight();
         } else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
             return getMinHeight();
-        } else if (mIsSummaryWithChildren && !mOnKeyguard) {
+        } else if (mIsSummaryWithChildren) {
             return mChildrenContainer.getIntrinsicHeight();
-        } else if (isHeadsUpAllowed() && (mIsHeadsUp || mHeadsupDisappearRunning)) {
+        } else if (canShowHeadsUp() && isHeadsUpState()) {
             if (isPinned() || mHeadsupDisappearRunning) {
                 return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
             } else if (isExpanded()) {
@@ -2362,24 +2338,29 @@
         }
     }
 
-    private boolean isHeadsUpAllowed() {
-        return !mOnKeyguard && !mOnAmbient;
+    /**
+     * @return {@code true} if the notification can show it's heads up layout. This is mostly true
+     *         except for legacy use cases.
+     */
+    public boolean canShowHeadsUp() {
+        if (mOnKeyguard && !isDozing() && !isBypassEnabled()) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean isBypassEnabled() {
+        return mBypassController == null || mBypassController.getBypassEnabled();
+    }
+
+    private boolean isDozing() {
+        return mStatusbarStateController != null && mStatusbarStateController.isDozing();
     }
 
     private boolean isShownAsBubble() {
         return mEntry.isBubble() && !mEntry.showInShadeWhenBubble() && !mEntry.isBubbleDismissed();
     }
 
-    /**
-     * Set the current status bar state.
-     * @param state should be from {@link com.android.systemui.statusbar.StatusBarState}.
-     */
-    public void setStatusBarState(int state) {
-        if (mStatusBarState != state) {
-            mStatusBarState = state;
-        }
-    }
-
     @Override
     public boolean isGroupExpanded() {
         return mGroupManager.isGroupExpanded(mStatusBarNotification);
@@ -2563,7 +2544,6 @@
         showingLayout.updateBackgroundColor(animated);
         mPrivateLayout.updateExpandButtons(isExpandable());
         updateShelfIconColor();
-        showingLayout.setDark(isDark(), false /* animate */, 0 /* delay */);
         mShowingPublicInitialized = true;
     }
 
@@ -2656,7 +2636,7 @@
 
 
     private int getHeadsUpHeight() {
-        return getShowingLayout().getHeadsUpHeight();
+        return getShowingLayout().getHeadsUpHeight(false /* forceNoHeader */);
     }
 
     public boolean areGutsExposed() {
@@ -2717,6 +2697,8 @@
                 l.setAlpha(1.0f);
                 l.setLayerType(LAYER_TYPE_NONE, null);
             }
+        } else {
+            setHeadsUpAnimatingAway(false);
         }
     }
 
@@ -2773,12 +2755,12 @@
     public int getMinHeight(boolean ignoreTemporaryStates) {
         if (!ignoreTemporaryStates && mGuts != null && mGuts.isExposed()) {
             return mGuts.getIntrinsicHeight();
-        } else if (!ignoreTemporaryStates && isHeadsUpAllowed() && mIsHeadsUp
+        } else if (!ignoreTemporaryStates && canShowHeadsUp() && mIsHeadsUp
                 && mHeadsUpManager.isTrackingHeadsUp()) {
                 return getPinnedHeadsUpHeight(false /* atLeastMinHeight */);
         } else if (mIsSummaryWithChildren && !isGroupExpanded() && !shouldShowPublic()) {
             return mChildrenContainer.getMinHeight();
-        } else if (!ignoreTemporaryStates && isHeadsUpAllowed() && mIsHeadsUp) {
+        } else if (!ignoreTemporaryStates && canShowHeadsUp() && mIsHeadsUp) {
             return getHeadsUpHeight();
         }
         NotificationContentView showingLayout = getShowingLayout();
@@ -2794,6 +2776,17 @@
     }
 
     @Override
+    public int getHeadsUpHeightWithoutHeader() {
+        if (!canShowHeadsUp() || !mIsHeadsUp) {
+            return getCollapsedHeight();
+        }
+        if (mIsSummaryWithChildren && !shouldShowPublic()) {
+            return mChildrenContainer.getCollapsedHeightWithoutHeader();
+        }
+        return getShowingLayout().getHeadsUpHeight(true /* forceNoHeader */);
+    }
+
+    @Override
     public void setClipTopAmount(int clipTopAmount) {
         super.setClipTopAmount(clipTopAmount);
         for (NotificationContentView l : mLayouts) {
@@ -3050,18 +3043,11 @@
 
     @Override
     public boolean isAboveShelf() {
-        return showingAmbientPulsing() || (!isOnKeyguard()
+        return (canShowHeadsUp()
                 && (mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf)
                 || mExpandAnimationRunning || mChildIsExpanding));
     }
 
-    public void setOnAmbient(boolean onAmbient) {
-        if (onAmbient != mOnAmbient) {
-            mOnAmbient = onAmbient;
-            notifyHeightChanged(false /* needsAnimation */);
-        }
-    }
-
     @Override
     public boolean topAmountNeedsClipping() {
         if (isGroupExpanded()) {
@@ -3125,10 +3111,6 @@
         return getCurrentBottomRoundness() == 0.0f && getCurrentTopRoundness() == 0.0f;
     }
 
-    public boolean isOnAmbient() {
-        return mOnAmbient;
-    }
-
     //TODO: this logic can't depend on layout if we are recycling!
     public boolean isMediaRow() {
         return getExpandedContentView() != null
@@ -3206,10 +3188,6 @@
         }
     }
 
-    public void setAmbientGoingAway(boolean goingAway) {
-        mAmbientGoingAway = goingAway;
-    }
-
     /**
      * Returns the Smart Suggestions backing the smart suggestion buttons in the notification.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index cac41da..a0fef00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -49,7 +49,6 @@
     protected int mClipBottomAmount;
     protected int mMinimumHeightForClipping = 0;
     protected float mExtraWidthForClipping = 0;
-    private boolean mDark;
     private ArrayList<View> mMatchParentViews = new ArrayList<View>();
     private static Rect mClipRect = new Rect();
     private boolean mWillBeGone;
@@ -212,21 +211,6 @@
     public void setDimmed(boolean dimmed, boolean fade) {
     }
 
-    /**
-     * Sets the notification as dark. The default implementation does nothing.
-     *
-     * @param dark Whether the notification should be dark.
-     * @param fade Whether an animation should be played to change the state.
-     * @param delay If fading, the delay of the animation.
-     */
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mDark = dark;
-    }
-
-    public boolean isDark() {
-        return mDark;
-    }
-
     public boolean isRemoved() {
         return false;
     }
@@ -527,7 +511,7 @@
     public void setHeadsUpIsVisible() {
     }
 
-    public boolean showingAmbientPulsing() {
+    public boolean showingPulsing() {
         return false;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 396cd73..d057a1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.notification.row;
 
-import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_AMBIENT;
 import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
 import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
 
@@ -51,12 +50,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.HashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * A utility that inflates the right kind of contentView based on the state
@@ -72,7 +65,6 @@
                 FLAG_CONTENT_VIEW_CONTRACTED,
                 FLAG_CONTENT_VIEW_EXPANDED,
                 FLAG_CONTENT_VIEW_HEADS_UP,
-                FLAG_CONTENT_VIEW_AMBIENT,
                 FLAG_CONTENT_VIEW_PUBLIC,
                 FLAG_CONTENT_VIEW_ALL})
     public @interface InflationFlag {}
@@ -93,17 +85,11 @@
     public static final int FLAG_CONTENT_VIEW_HEADS_UP = 1 << 2;
 
     /**
-     * The ambient view.  Seen when a high priority notification is received and the phone
-     * is dozing.
-     */
-    public static final int FLAG_CONTENT_VIEW_AMBIENT = 1 << 3;
-
-    /**
      * The public view.  This is a version of the contracted view that hides sensitive
      * information and is used on the lock screen if we determine that the notification's
      * content should be hidden.
      */
-    public static final int FLAG_CONTENT_VIEW_PUBLIC = 1 << 4;
+    public static final int FLAG_CONTENT_VIEW_PUBLIC = 1 << 3;
 
     public static final int FLAG_CONTENT_VIEW_ALL = ~0;
 
@@ -128,7 +114,6 @@
     private RemoteViews.OnClickHandler mRemoteViewClickHandler;
     private boolean mIsChildInGroup;
     private InflationCallback mCallback;
-    private boolean mRedactAmbient;
     private boolean mInflateSynchronously = false;
     private final ArrayMap<Integer, RemoteViews> mCachedContentViews = new ArrayMap<>();
 
@@ -169,21 +154,18 @@
 
     /**
      * Update whether or not the notification is redacted on the lock screen.  If the notification
-     * is now redacted, we should inflate the public contracted view and public ambient view to
-     * now show on the lock screen.
+     * is now redacted, we should inflate the public contracted view to now show on the lock screen.
      *
      * @param needsRedaction true if the notification should now be redacted on the lock screen
      */
     public void updateNeedsRedaction(boolean needsRedaction) {
-        mRedactAmbient = needsRedaction;
         if (mRow.getEntry() == null) {
             return;
         }
-        int flags = FLAG_CONTENT_VIEW_AMBIENT;
         if (needsRedaction) {
-            flags |= FLAG_CONTENT_VIEW_PUBLIC;
+            int flags = FLAG_CONTENT_VIEW_PUBLIC;
+            inflateNotificationViews(flags);
         }
-        inflateNotificationViews(flags);
     }
 
     /**
@@ -263,7 +245,6 @@
                 mIsChildInGroup,
                 mUsesIncreasedHeight,
                 mUsesIncreasedHeadsUpHeight,
-                mRedactAmbient,
                 mCallback,
                 mRemoteViewClickHandler);
         if (mInflateSynchronously) {
@@ -281,7 +262,7 @@
             Context packageContext) {
         InflationProgress result = createRemoteViews(reInflateFlags, builder, mIsLowPriority,
                 mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
-                mRedactAmbient, packageContext);
+                packageContext);
         result = inflateSmartReplyViews(result, reInflateFlags, mRow.getEntry(),
                 mRow.getContext(), mRow.getHeadsUpManager(),
                 mRow.getExistingSmartRepliesAndActions());
@@ -291,7 +272,6 @@
                 reInflateFlags,
                 mCachedContentViews,
                 mRow,
-                mRedactAmbient,
                 mRemoteViewClickHandler,
                 null);
         return result;
@@ -316,21 +296,6 @@
                     mRow.getPrivateLayout().setHeadsUpInflatedSmartReplies(null);
                 }
                 break;
-            case FLAG_CONTENT_VIEW_AMBIENT:
-                boolean privateSafeToRemove = mRow.getPrivateLayout().isContentViewInactive(
-                        VISIBLE_TYPE_AMBIENT);
-                boolean publicSafeToRemove = mRow.getPublicLayout().isContentViewInactive(
-                        VISIBLE_TYPE_AMBIENT);
-                if (privateSafeToRemove) {
-                    mRow.getPrivateLayout().setAmbientChild(null);
-                }
-                if (publicSafeToRemove) {
-                    mRow.getPublicLayout().setAmbientChild(null);
-                }
-                if (privateSafeToRemove && publicSafeToRemove) {
-                    mCachedContentViews.remove(FLAG_CONTENT_VIEW_AMBIENT);
-                }
-                break;
             case FLAG_CONTENT_VIEW_PUBLIC:
                 if (mRow.getPublicLayout().isContentViewInactive(VISIBLE_TYPE_CONTRACTED)) {
                     mRow.getPublicLayout().setContractedChild(null);
@@ -366,7 +331,7 @@
 
     private static InflationProgress createRemoteViews(@InflationFlag int reInflateFlags,
             Notification.Builder builder, boolean isLowPriority, boolean isChildInGroup,
-            boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, boolean redactAmbient,
+            boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight,
             Context packageContext) {
         InflationProgress result = new InflationProgress();
         isLowPriority = isLowPriority && !isChildInGroup;
@@ -387,10 +352,6 @@
             result.newPublicView = builder.makePublicContentView();
         }
 
-        if ((reInflateFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
-            result.newAmbientView = redactAmbient ? builder.makePublicAmbientNotification()
-                    : builder.makeAmbientNotification();
-        }
         result.packageContext = packageContext;
         result.headsUpStatusBarText = builder.getHeadsUpStatusBarText(false /* showingPublic */);
         result.headsUpStatusBarTextPublic = builder.getHeadsUpStatusBarText(
@@ -404,7 +365,6 @@
             @InflationFlag int reInflateFlags,
             ArrayMap<Integer, RemoteViews> cachedContentViews,
             ExpandableNotificationRow row,
-            boolean redactAmbient,
             RemoteViews.OnClickHandler remoteViewClickHandler,
             @Nullable InflationCallback callback) {
         NotificationContentView privateLayout = row.getPrivateLayout();
@@ -428,7 +388,7 @@
                 }
             };
             applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews,
-                    row, redactAmbient, isNewView, remoteViewClickHandler, callback, privateLayout,
+                    row, isNewView, remoteViewClickHandler, callback, privateLayout,
                     privateLayout.getContractedChild(), privateLayout.getVisibleWrapper(
                             NotificationContentView.VISIBLE_TYPE_CONTRACTED),
                     runningInflations, applyCallback);
@@ -452,7 +412,7 @@
                     }
                 };
                 applyRemoteView(inflateSynchronously, result, reInflateFlags, flag,
-                        cachedContentViews, row, redactAmbient, isNewView, remoteViewClickHandler,
+                        cachedContentViews, row, isNewView, remoteViewClickHandler,
                         callback, privateLayout, privateLayout.getExpandedChild(),
                         privateLayout.getVisibleWrapper(
                                 NotificationContentView.VISIBLE_TYPE_EXPANDED), runningInflations,
@@ -478,7 +438,7 @@
                     }
                 };
                 applyRemoteView(inflateSynchronously, result, reInflateFlags, flag,
-                        cachedContentViews, row, redactAmbient, isNewView, remoteViewClickHandler,
+                        cachedContentViews, row, isNewView, remoteViewClickHandler,
                         callback, privateLayout, privateLayout.getHeadsUpChild(),
                         privateLayout.getVisibleWrapper(
                                 VISIBLE_TYPE_HEADSUP), runningInflations,
@@ -503,39 +463,14 @@
                 }
             };
             applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews,
-                    row, redactAmbient, isNewView, remoteViewClickHandler, callback,
+                    row, isNewView, remoteViewClickHandler, callback,
                     publicLayout, publicLayout.getContractedChild(),
                     publicLayout.getVisibleWrapper(NotificationContentView.VISIBLE_TYPE_CONTRACTED),
                     runningInflations, applyCallback);
         }
 
-        flag = FLAG_CONTENT_VIEW_AMBIENT;
-        if ((reInflateFlags & flag) != 0) {
-            NotificationContentView newParent = redactAmbient ? publicLayout : privateLayout;
-            boolean isNewView = (!canReapplyAmbient(row, redactAmbient)
-                    || !canReapplyRemoteView(result.newAmbientView,
-                            cachedContentViews.get(FLAG_CONTENT_VIEW_AMBIENT)));
-            ApplyCallback applyCallback = new ApplyCallback() {
-                @Override
-                public void setResultView(View v) {
-                    result.inflatedAmbientView = v;
-                }
-
-                @Override
-                public RemoteViews getRemoteView() {
-                    return result.newAmbientView;
-                }
-            };
-            applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews,
-                    row, redactAmbient, isNewView, remoteViewClickHandler, callback,
-                    newParent, newParent.getAmbientChild(), newParent.getVisibleWrapper(
-                            NotificationContentView.VISIBLE_TYPE_AMBIENT), runningInflations,
-                    applyCallback);
-        }
-
         // Let's try to finish, maybe nobody is even inflating anything
-        finishIfDone(result, reInflateFlags, cachedContentViews, runningInflations, callback, row,
-                redactAmbient);
+        finishIfDone(result, reInflateFlags, cachedContentViews, runningInflations, callback, row);
         CancellationSignal cancellationSignal = new CancellationSignal();
         cancellationSignal.setOnCancelListener(
                 () -> runningInflations.values().forEach(CancellationSignal::cancel));
@@ -550,7 +485,6 @@
             @InflationFlag int inflationId,
             final ArrayMap<Integer, RemoteViews> cachedContentViews,
             final ExpandableNotificationRow row,
-            final boolean redactAmbient,
             boolean isNewView,
             RemoteViews.OnClickHandler remoteViewClickHandler,
             @Nullable final InflationCallback callback,
@@ -603,7 +537,7 @@
                 }
                 runningInflations.remove(inflationId);
                 finishIfDone(result, reInflateFlags, cachedContentViews, runningInflations,
-                        callback, row, redactAmbient);
+                        callback, row);
             }
 
             @Override
@@ -670,8 +604,7 @@
     private static boolean finishIfDone(InflationProgress result,
             @InflationFlag int reInflateFlags, ArrayMap<Integer, RemoteViews> cachedContentViews,
             HashMap<Integer, CancellationSignal> runningInflations,
-            @Nullable InflationCallback endListener, ExpandableNotificationRow row,
-            boolean redactAmbient) {
+            @Nullable InflationCallback endListener, ExpandableNotificationRow row) {
         Assert.isMainThread();
         NotificationEntry entry = row.getEntry();
         NotificationContentView privateLayout = row.getPrivateLayout();
@@ -735,19 +668,6 @@
                 }
             }
 
-            if ((reInflateFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
-                if (result.inflatedAmbientView != null) {
-                    NotificationContentView newParent = redactAmbient
-                            ? publicLayout : privateLayout;
-                    NotificationContentView otherParent = !redactAmbient
-                            ? publicLayout : privateLayout;
-                    newParent.setAmbientChild(result.inflatedAmbientView);
-                    otherParent.setAmbientChild(null);
-                    cachedContentViews.put(FLAG_CONTENT_VIEW_AMBIENT, result.newAmbientView);
-                } else if (cachedContentViews.get(FLAG_CONTENT_VIEW_AMBIENT) != null) {
-                    cachedContentViews.put(FLAG_CONTENT_VIEW_AMBIENT, result.newAmbientView);
-                }
-            }
             entry.headsUpStatusBarText = result.headsUpStatusBarText;
             entry.headsUpStatusBarTextPublic = result.headsUpStatusBarTextPublic;
             if (endListener != null) {
@@ -827,12 +747,6 @@
         mInflateSynchronously = inflateSynchronously;
     }
 
-    private static boolean canReapplyAmbient(ExpandableNotificationRow row, boolean redactAmbient) {
-        NotificationContentView ambientView = redactAmbient ? row.getPublicLayout()
-                : row.getPrivateLayout();
-        return ambientView.getAmbientChild() != null;
-    }
-
     public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress>
             implements InflationCallback, InflationTask {
 
@@ -844,7 +758,6 @@
         private final boolean mUsesIncreasedHeight;
         private final InflationCallback mCallback;
         private final boolean mUsesIncreasedHeadsUpHeight;
-        private final boolean mRedactAmbient;
         private @InflationFlag int mReInflateFlags;
         private final ArrayMap<Integer, RemoteViews> mCachedContentViews;
         private ExpandableNotificationRow mRow;
@@ -862,7 +775,6 @@
                 boolean isChildInGroup,
                 boolean usesIncreasedHeight,
                 boolean usesIncreasedHeadsUpHeight,
-                boolean redactAmbient,
                 InflationCallback callback,
                 RemoteViews.OnClickHandler remoteViewClickHandler) {
             mRow = row;
@@ -875,7 +787,6 @@
             mIsChildInGroup = isChildInGroup;
             mUsesIncreasedHeight = usesIncreasedHeight;
             mUsesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight;
-            mRedactAmbient = redactAmbient;
             mRemoteViewClickHandler = remoteViewClickHandler;
             mCallback = callback;
             NotificationEntry entry = row.getEntry();
@@ -903,9 +814,8 @@
                     processor.processNotification(notification, recoveredBuilder);
                 }
                 InflationProgress inflationProgress = createRemoteViews(mReInflateFlags,
-                        recoveredBuilder, mIsLowPriority,
-                        mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
-                        mRedactAmbient, packageContext);
+                        recoveredBuilder, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight,
+                        mUsesIncreasedHeadsUpHeight, packageContext);
                 return inflateSmartReplyViews(inflationProgress, mReInflateFlags, mRow.getEntry(),
                         mRow.getContext(), mRow.getHeadsUpManager(),
                         mRow.getExistingSmartRepliesAndActions());
@@ -919,7 +829,7 @@
         protected void onPostExecute(InflationProgress result) {
             if (mError == null) {
                 mCancellationSignal = apply(mInflateSynchronously, result, mReInflateFlags,
-                        mCachedContentViews, mRow, mRedactAmbient, mRemoteViewClickHandler, this);
+                        mCachedContentViews, mRow, mRemoteViewClickHandler, this);
             } else {
                 handleError(mError);
             }
@@ -974,7 +884,6 @@
         private RemoteViews newContentView;
         private RemoteViews newHeadsUpView;
         private RemoteViews newExpandedView;
-        private RemoteViews newAmbientView;
         private RemoteViews newPublicView;
 
         @VisibleForTesting
@@ -983,7 +892,6 @@
         private View inflatedContentView;
         private View inflatedHeadsUpView;
         private View inflatedExpandedView;
-        private View inflatedAmbientView;
         private View inflatedPublicView;
         private CharSequence headsUpStatusBarText;
         private CharSequence headsUpStatusBarTextPublic;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 354ed2d..90f6324 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -71,7 +71,6 @@
     public static final int VISIBLE_TYPE_EXPANDED = 1;
     public static final int VISIBLE_TYPE_HEADSUP = 2;
     private static final int VISIBLE_TYPE_SINGLELINE = 3;
-    public static final int VISIBLE_TYPE_AMBIENT = 4;
     public static final int UNDEFINED = -1;
 
     private final Rect mClipBounds = new Rect();
@@ -82,7 +81,6 @@
     private View mExpandedChild;
     private View mHeadsUpChild;
     private HybridNotificationView mSingleLineView;
-    private View mAmbientChild;
 
     private RemoteInputView mExpandedRemoteInput;
     private RemoteInputView mHeadsUpRemoteInput;
@@ -98,12 +96,10 @@
     private NotificationViewWrapper mContractedWrapper;
     private NotificationViewWrapper mExpandedWrapper;
     private NotificationViewWrapper mHeadsUpWrapper;
-    private NotificationViewWrapper mAmbientWrapper;
     private HybridGroupManager mHybridGroupManager;
     private int mClipTopAmount;
     private int mContentHeight;
     private int mVisibleType = VISIBLE_TYPE_CONTRACTED;
-    private boolean mDark;
     private boolean mAnimate;
     private boolean mIsHeadsUp;
     private boolean mLegacy;
@@ -111,7 +107,6 @@
     private int mSmallHeight;
     private int mHeadsUpHeight;
     private int mNotificationMaxHeight;
-    private int mNotificationAmbientHeight;
     private StatusBarNotification mStatusBarNotification;
     private NotificationGroupManager mGroupManager;
     private RemoteInputController mRemoteInputController;
@@ -166,7 +161,6 @@
     private int mUnrestrictedContentHeight;
     private MediaTransferManager mMediaTransferManager;
 
-
     public NotificationContentView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mHybridGroupManager = new HybridGroupManager(getContext(), this);
@@ -183,12 +177,10 @@
                 com.android.internal.R.dimen.notification_content_margin_end);
     }
 
-    public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight,
-            int ambientHeight) {
+    public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight) {
         mSmallHeight = smallHeight;
         mHeadsUpHeight = headsUpMaxHeight;
         mNotificationMaxHeight = maxHeight;
-        mNotificationAmbientHeight = ambientHeight;
     }
 
     @Override
@@ -286,20 +278,6 @@
                     MeasureSpec.makeMeasureSpec(mNotificationMaxHeight, MeasureSpec.AT_MOST));
             maxChildHeight = Math.max(maxChildHeight, mSingleLineView.getMeasuredHeight());
         }
-        if (mAmbientChild != null) {
-            int size = mNotificationAmbientHeight;
-            ViewGroup.LayoutParams layoutParams = mAmbientChild.getLayoutParams();
-            boolean useExactly = false;
-            if (layoutParams.height >= 0) {
-                // An actual height is set
-                size = Math.min(size, layoutParams.height);
-                useExactly = true;
-            }
-            mAmbientChild.measure(widthMeasureSpec,
-                    MeasureSpec.makeMeasureSpec(size, useExactly ? MeasureSpec.EXACTLY
-                            : MeasureSpec.AT_MOST));
-            maxChildHeight = Math.max(maxChildHeight, mAmbientChild.getMeasuredHeight());
-        }
         int ownHeight = Math.min(maxChildHeight, maxSize);
         setMeasuredDimension(width, ownHeight);
     }
@@ -394,10 +372,6 @@
         return mHeadsUpChild;
     }
 
-    public View getAmbientChild() {
-        return mAmbientChild;
-    }
-
     /**
      * Sets the contracted view. Child may be null to remove the content view.
      *
@@ -432,9 +406,6 @@
         if (child == mHeadsUpChild) {
             return mHeadsUpWrapper;
         }
-        if (child == mAmbientChild) {
-            return mAmbientWrapper;
-        }
         return null;
     }
 
@@ -514,33 +485,6 @@
                 mContainingNotification);
     }
 
-    /**
-     * Sets the ambient view. Child may be null to remove the content view.
-     *
-     * @param child ambient content view to set
-     */
-    public void setAmbientChild(@Nullable View child) {
-        if (mAmbientChild != null) {
-            mAmbientChild.animate().cancel();
-            removeView(mAmbientChild);
-        }
-        if (child == null) {
-            mAmbientChild = null;
-            mAmbientWrapper = null;
-            if (mTransformationStartVisibleType == VISIBLE_TYPE_AMBIENT) {
-                mTransformationStartVisibleType = UNDEFINED;
-            }
-            if (mVisibleType == VISIBLE_TYPE_AMBIENT) {
-                selectLayout(false /* animate */, true /* force */);
-            }
-            return;
-        }
-        addView(child);
-        mAmbientChild = child;
-        mAmbientWrapper = NotificationViewWrapper.wrap(getContext(), child,
-                mContainingNotification);
-    }
-
     @Override
     public void onViewAdded(View child) {
         super.onViewAdded(child);
@@ -645,7 +589,7 @@
                     isTransitioningFromTo(VISIBLE_TYPE_EXPANDED, VISIBLE_TYPE_HEADSUP);
             boolean pinned = !isVisibleOrTransitioning(VISIBLE_TYPE_CONTRACTED)
                     && (mIsHeadsUp || mHeadsUpAnimatingAway)
-                    && !mContainingNotification.isOnKeyguard();
+                    && mContainingNotification.canShowHeadsUp();
             if (transitioningBetweenHunAndExpanded || pinned) {
                 return Math.min(getViewHeight(VISIBLE_TYPE_HEADSUP),
                         getViewHeight(VISIBLE_TYPE_EXPANDED));
@@ -659,9 +603,7 @@
         }
 
         int hint;
-        if (mAmbientChild != null && isVisibleOrTransitioning(VISIBLE_TYPE_AMBIENT)) {
-            hint = mAmbientChild.getHeight();
-        }  else if (mHeadsUpChild != null && isVisibleOrTransitioning(VISIBLE_TYPE_HEADSUP)) {
+        if (mHeadsUpChild != null && isVisibleOrTransitioning(VISIBLE_TYPE_HEADSUP)) {
             hint = getViewHeight(VISIBLE_TYPE_HEADSUP);
         } else if (mExpandedChild != null) {
             hint = getViewHeight(VISIBLE_TYPE_EXPANDED);
@@ -761,9 +703,7 @@
         if (mExpandedChild != null) {
             return getViewHeight(VISIBLE_TYPE_EXPANDED)
                     + getExtraRemoteInputHeight(mExpandedRemoteInput);
-        } else if (mContainingNotification.isOnAmbient() && getShowingAmbientView() != null) {
-            return getShowingAmbientView().getHeight();
-        } else if (mIsHeadsUp && mHeadsUpChild != null && !mContainingNotification.isOnKeyguard()) {
+        } else if (mIsHeadsUp && mHeadsUpChild != null && mContainingNotification.canShowHeadsUp()) {
             return getViewHeight(VISIBLE_TYPE_HEADSUP)
                     + getExtraRemoteInputHeight(mHeadsUpRemoteInput);
         } else if (mContractedChild != null) {
@@ -773,11 +713,15 @@
     }
 
     private int getViewHeight(int visibleType) {
+        return getViewHeight(visibleType, false /* forceNoHeader */);
+    }
+
+    private int getViewHeight(int visibleType, boolean forceNoHeader) {
         View view = getViewForVisibleType(visibleType);
         int height = view.getHeight();
         NotificationViewWrapper viewWrapper = getWrapperForView(view);
         if (viewWrapper != null) {
-            height += viewWrapper.getHeaderTranslation();
+            height += viewWrapper.getHeaderTranslation(forceNoHeader);
         }
         return height;
     }
@@ -787,9 +731,7 @@
     }
 
     public int getMinHeight(boolean likeGroupExpanded) {
-        if (mContainingNotification.isOnAmbient() && getShowingAmbientView() != null) {
-            return getShowingAmbientView().getHeight();
-        } else if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded()) {
+        if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded()) {
             return mContractedChild != null
                     ? getViewHeight(VISIBLE_TYPE_CONTRACTED) : mMinContractedHeight;
         } else {
@@ -797,15 +739,6 @@
         }
     }
 
-    public View getShowingAmbientView() {
-        View v = mIsChildInGroup ? mSingleLineView : mAmbientChild;
-        if (v != null) {
-            return v;
-        } else {
-            return mContractedChild;
-        }
-    }
-
     private boolean isGroupExpanded() {
         return mGroupManager.isGroupExpanded(mStatusBarNotification);
     }
@@ -887,7 +820,6 @@
         forceUpdateVisibility(VISIBLE_TYPE_EXPANDED, mExpandedChild, mExpandedWrapper);
         forceUpdateVisibility(VISIBLE_TYPE_HEADSUP, mHeadsUpChild, mHeadsUpWrapper);
         forceUpdateVisibility(VISIBLE_TYPE_SINGLELINE, mSingleLineView, mSingleLineView);
-        forceUpdateVisibility(VISIBLE_TYPE_AMBIENT, mAmbientChild, mAmbientWrapper);
         fireExpandedVisibleListenerIfVisible();
         // forceUpdateVisibilities cancels outstanding animations without updating the
         // mAnimationStartVisibleType. Do so here instead.
@@ -963,8 +895,6 @@
                 mHeadsUpChild, mHeadsUpWrapper);
         updateViewVisibility(visibleType, VISIBLE_TYPE_SINGLELINE,
                 mSingleLineView, mSingleLineView);
-        updateViewVisibility(visibleType, VISIBLE_TYPE_AMBIENT,
-                mAmbientChild, mAmbientWrapper);
         fireExpandedVisibleListenerIfVisible();
         // updateViewVisibilities cancels outstanding animations without updating the
         // mAnimationStartVisibleType. Do so here instead.
@@ -1025,8 +955,6 @@
                 return mHeadsUpWrapper;
             case VISIBLE_TYPE_SINGLELINE:
                 return mSingleLineView;
-            case VISIBLE_TYPE_AMBIENT:
-                return mAmbientWrapper;
             default:
                 return mContractedWrapper;
         }
@@ -1044,8 +972,6 @@
                 return mHeadsUpChild;
             case VISIBLE_TYPE_SINGLELINE:
                 return mSingleLineView;
-            case VISIBLE_TYPE_AMBIENT:
-                return mAmbientChild;
             default:
                 return mContractedChild;
         }
@@ -1059,8 +985,6 @@
                 return mHeadsUpWrapper;
             case VISIBLE_TYPE_CONTRACTED:
                 return mContractedWrapper;
-            case VISIBLE_TYPE_AMBIENT:
-                return mAmbientWrapper;
             default:
                 return null;
         }
@@ -1100,26 +1024,23 @@
         if (!noExpandedChild && viewHeight == getViewHeight(VISIBLE_TYPE_EXPANDED)) {
             return VISIBLE_TYPE_EXPANDED;
         }
-        boolean onAmbient = mContainingNotification.isOnAmbient();
         if (!mUserExpanding && mIsChildInGroup && !isGroupExpanded()) {
             return VISIBLE_TYPE_SINGLELINE;
         }
 
         if ((mIsHeadsUp || mHeadsUpAnimatingAway) && mHeadsUpChild != null
-                && !mContainingNotification.isOnKeyguard()) {
+                && mContainingNotification.canShowHeadsUp()) {
             if (viewHeight <= getViewHeight(VISIBLE_TYPE_HEADSUP) || noExpandedChild) {
                 return VISIBLE_TYPE_HEADSUP;
             } else {
                 return VISIBLE_TYPE_EXPANDED;
             }
         } else {
-            int collapsedType = onAmbient && mAmbientChild != null ? VISIBLE_TYPE_AMBIENT :
-                    VISIBLE_TYPE_CONTRACTED;
             if (noExpandedChild || (mContractedChild != null
-                    && viewHeight <= getViewHeight(collapsedType)
+                    && viewHeight <= getViewHeight(VISIBLE_TYPE_CONTRACTED)
                     && (!mIsChildInGroup || isGroupExpanded()
                             || !mContainingNotification.isExpanded(true /* allowOnKeyguard */)))) {
-                return collapsedType;
+                return VISIBLE_TYPE_CONTRACTED;
             } else {
                 return VISIBLE_TYPE_EXPANDED;
             }
@@ -1130,14 +1051,6 @@
         return mIsContentExpandable;
     }
 
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (mContractedChild == null) {
-            return;
-        }
-        mDark = dark;
-        selectLayout(!dark && fade /* animate */, false /* force */);
-    }
-
     public void setHeadsUp(boolean headsUp) {
         mIsHeadsUp = headsUp;
         selectLayout(false /* animate */, true /* force */);
@@ -1180,9 +1093,6 @@
         if (mHeadsUpChild != null) {
             mHeadsUpWrapper.setIsChildInGroup(mIsChildInGroup);
         }
-        if (mAmbientChild != null) {
-            mAmbientWrapper.setIsChildInGroup(mIsChildInGroup);
-        }
         updateAllSingleLineViews();
     }
 
@@ -1201,14 +1111,10 @@
         if (mHeadsUpChild != null) {
             mHeadsUpWrapper.onContentUpdated(row);
         }
-        if (mAmbientChild != null) {
-            mAmbientWrapper.onContentUpdated(row);
-        }
         applyRemoteInputAndSmartReply(entry);
         applyMediaTransfer(entry);
         updateLegacy();
         mForceSelectNextLayout = true;
-        setDark(mDark, false /* animate */, 0 /* delay */);
         mPreviousExpandedRemoteInputIntent = null;
         mPreviousHeadsUpRemoteInputIntent = null;
     }
@@ -1514,7 +1420,7 @@
         // if the expanded child has the same height as the collapsed one we hide it.
         if (mExpandedChild != null && mExpandedChild.getHeight() != 0) {
             if ((!mIsHeadsUp && !mHeadsUpAnimatingAway)
-                    || mHeadsUpChild == null || mContainingNotification.isOnKeyguard()) {
+                    || mHeadsUpChild == null || !mContainingNotification.canShowHeadsUp()) {
                 if (mExpandedChild.getHeight() <= mContractedChild.getHeight()) {
                     expandable = false;
                 }
@@ -1545,9 +1451,6 @@
         if (header == null && mHeadsUpChild != null) {
             header = mHeadsUpWrapper.getNotificationHeader();
         }
-        if (header == null && mAmbientChild != null) {
-            header = mAmbientWrapper.getNotificationHeader();
-        }
         return header;
     }
 
@@ -1849,14 +1752,15 @@
         return getViewHeight(viewType) + getExtraRemoteInputHeight(mExpandedRemoteInput);
     }
 
-    public int getHeadsUpHeight() {
+    public int getHeadsUpHeight(boolean forceNoHeader) {
         int viewType = VISIBLE_TYPE_HEADSUP;
         if (mHeadsUpChild == null) {
             viewType = VISIBLE_TYPE_CONTRACTED;
         }
         // The headsUp remote input quickly switches to the expanded one, so lets also include that
         // one
-        return getViewHeight(viewType) + getExtraRemoteInputHeight(mHeadsUpRemoteInput)
+        return getViewHeight(viewType, forceNoHeader)
+                + getExtraRemoteInputHeight(mHeadsUpRemoteInput)
                 + getExtraRemoteInputHeight(mExpandedRemoteInput);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index f15d6b7..8f7671a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -41,13 +41,16 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationLifetimeExtender;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateControllerImpl;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -73,6 +76,7 @@
 
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
     private final Context mContext;
+    private final VisualStabilityManager mVisualStabilityManager;
     private final AccessibilityManager mAccessibilityManager;
 
     // Dependencies:
@@ -95,9 +99,14 @@
     @VisibleForTesting
     protected String mKeyToRemoveOnGutsClosed;
 
+    private StatusBar mStatusBar;
+
     @Inject
-    public NotificationGutsManager(Context context) {
+    public NotificationGutsManager(
+            Context context,
+            VisualStabilityManager visualStabilityManager) {
         mContext = context;
+        mVisualStabilityManager = visualStabilityManager;
         mAccessibilityManager = (AccessibilityManager)
                 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
     }
@@ -109,6 +118,7 @@
         mListContainer = listContainer;
         mCheckSaveListener = checkSave;
         mOnSettingsClickListener = onSettingsClick;
+        mStatusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
     }
 
     public void setNotificationActivityStarter(
@@ -304,6 +314,7 @@
         notificationInfoView.bindNotification(
                 pmUser,
                 iNotificationManager,
+                mVisualStabilityManager,
                 packageName,
                 row.getEntry().channel,
                 row.getUniqueChannels(),
@@ -370,6 +381,34 @@
             int x,
             int y,
             NotificationMenuRowPlugin.MenuItem menuItem) {
+        if (menuItem.getGutsView() instanceof NotificationInfo) {
+            if (mStatusBarStateController instanceof StatusBarStateControllerImpl) {
+                ((StatusBarStateControllerImpl) mStatusBarStateController)
+                        .setLeaveOpenOnKeyguardHide(true);
+            }
+
+            Runnable r = () -> Dependency.get(Dependency.MAIN_HANDLER).post(
+                    () -> openGutsInternal(view, x, y, menuItem));
+
+            mStatusBar.executeRunnableDismissingKeyguard(
+                    r,
+                    null /* cancelAction */,
+                    false /* dismissShade */,
+                    true /* afterKeyguardGone */,
+                    true /* deferred */);
+
+            return true;
+        }
+        return openGutsInternal(view, x, y, menuItem);
+    }
+
+    @VisibleForTesting
+    boolean openGutsInternal(
+            View view,
+            int x,
+            int y,
+            NotificationMenuRowPlugin.MenuItem menuItem) {
+
         if (!(view instanceof ExpandableNotificationRow)) {
             return false;
         }
@@ -380,9 +419,6 @@
         }
 
         final ExpandableNotificationRow row = (ExpandableNotificationRow) view;
-        if (row.isDark()) {
-            return false;
-        }
         view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
         if (row.areGutsExposed()) {
             closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 1dc96b8..148d83b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -65,6 +65,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.logging.NotificationCounters;
 
 import java.lang.annotation.Retention;
@@ -104,6 +105,7 @@
     private INotificationManager mINotificationManager;
     private PackageManager mPm;
     private MetricsLogger mMetricsLogger;
+    private VisualStabilityManager mVisualStabilityManager;
     private ChannelEditorDialogController mChannelEditorDialogController;
 
     private String mPackageName;
@@ -116,6 +118,7 @@
     private int mStartingChannelImportance;
     private boolean mWasShownHighPriority;
     private boolean mPressedApply;
+    private boolean mPresentingChannelEditorDialog = false;
 
     /**
      * The last importance level chosen by the user.  Null if the user has not chosen an importance
@@ -159,13 +162,13 @@
     // used by standard ui
     private OnClickListener mOnDismissSettings = v -> {
         mPressedApply = true;
-        closeControls(v);
+        closeControls(v, true);
     };
 
     // used by blocking helper
     private OnClickListener mOnKeepShowing = v -> {
         mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
-        closeControls(v);
+        closeControls(v, true);
         mMetricsLogger.write(getLogMaker().setCategory(
                 MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
                 .setType(MetricsEvent.TYPE_ACTION)
@@ -244,6 +247,7 @@
     void bindNotification(
             final PackageManager pm,
             final INotificationManager iNotificationManager,
+            final VisualStabilityManager visualStabilityManager,
             final String pkg,
             final NotificationChannel notificationChannel,
             final Set<NotificationChannel> uniqueChannelsInRow,
@@ -256,7 +260,7 @@
             int importance,
             boolean wasShownHighPriority)
             throws RemoteException {
-        bindNotification(pm, iNotificationManager, pkg, notificationChannel,
+        bindNotification(pm, iNotificationManager, visualStabilityManager, pkg, notificationChannel,
                 uniqueChannelsInRow, sbn, checkSaveListener, onSettingsClick,
                 onAppSettingsClick, isDeviceProvisioned, isNonblockable,
                 false /* isBlockingHelper */,
@@ -266,6 +270,7 @@
     public void bindNotification(
             PackageManager pm,
             INotificationManager iNotificationManager,
+            VisualStabilityManager visualStabilityManager,
             String pkg,
             NotificationChannel notificationChannel,
             Set<NotificationChannel> uniqueChannelsInRow,
@@ -281,6 +286,7 @@
             throws RemoteException {
         mINotificationManager = iNotificationManager;
         mMetricsLogger = Dependency.get(MetricsLogger.class);
+        mVisualStabilityManager = visualStabilityManager;
         mChannelEditorDialogController = Dependency.get(ChannelEditorDialogController.class);
         mPackageName = pkg;
         mUniqueChannelsInRow = uniqueChannelsInRow;
@@ -442,9 +448,15 @@
 
     private OnClickListener getTurnOffNotificationsClickListener() {
         return ((View view) -> {
-            if (mChannelEditorDialogController != null) {
+            if (!mPresentingChannelEditorDialog && mChannelEditorDialogController != null) {
+                mPresentingChannelEditorDialog = true;
+
                 mChannelEditorDialogController.prepareDialogForApp(mAppName, mPackageName, mAppUid,
                         mUniqueChannelsInRow, mPkgIcon, mOnSettingsClickListener);
+                mChannelEditorDialogController.setOnFinishListener(() -> {
+                    mPresentingChannelEditorDialog = false;
+                    closeControls(this, false);
+                });
                 mChannelEditorDialogController.show();
             }
         });
@@ -537,6 +549,7 @@
                     new UpdateImportanceRunnable(mINotificationManager, mPackageName, mAppUid,
                             mNumUniqueChannelsInRow == 1 ? mSingleNotificationChannel : null,
                             mStartingChannelImportance, newImportance));
+            mVisualStabilityManager.temporarilyAllowReordering();
         }
     }
 
@@ -561,16 +574,21 @@
 
         switch (behavior) {
             case BEHAVIOR_ALERTING:
-                alert.setSelected(true);
-                silence.setSelected(false);
                 mPriorityDescriptionView.setVisibility(VISIBLE);
                 mSilentDescriptionView.setVisibility(GONE);
+                post(() -> {
+                    alert.setSelected(true);
+                    silence.setSelected(false);
+                });
                 break;
             case BEHAVIOR_SILENT:
-                alert.setSelected(false);
-                silence.setSelected(true);
+
                 mSilentDescriptionView.setVisibility(VISIBLE);
                 mPriorityDescriptionView.setVisibility(GONE);
+                post(() -> {
+                    alert.setSelected(false);
+                    silence.setSelected(true);
+                });
                 break;
             default:
                 throw new IllegalArgumentException("Unrecognized alerting behavior: " + behavior);
@@ -725,7 +743,7 @@
      * {@link #swapContent(boolean, boolean)} for where undo is handled.
      */
     @VisibleForTesting
-    void closeControls(View v) {
+    void closeControls(View v, boolean save) {
         int[] parentLoc = new int[2];
         int[] targetLoc = new int[2];
         mGutsContainer.getLocationOnScreen(parentLoc);
@@ -734,7 +752,7 @@
         final int centerY = v.getHeight() / 2;
         final int x = targetLoc[0] - parentLoc[0] + centerX;
         final int y = targetLoc[1] - parentLoc[1] + centerY;
-        mGutsContainer.closeControls(x, y, true /* save */, false /* force */);
+        mGutsContainer.closeControls(x, y, save, false /* force */);
     }
 
     @Override
@@ -759,6 +777,13 @@
 
     @Override
     public boolean handleCloseControls(boolean save, boolean force) {
+        if (mPresentingChannelEditorDialog && mChannelEditorDialogController != null) {
+            mPresentingChannelEditorDialog = false;
+            // No need for the finish listener because we're closing
+            mChannelEditorDialogController.setOnFinishListener(null);
+            mChannelEditorDialogController.close();
+        }
+
         // Save regardless of the importance so we can lock the importance field if the user wants
         // to keep getting notifications
         if (save) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index d911e1a..b4ccb56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -346,8 +346,7 @@
         if (mShouldShowMenu
                 && !NotificationStackScrollLayout.isPinnedHeadsUp(getParent())
                 && !mParent.areGutsExposed()
-                && !mParent.isDark()
-                && !mParent.showingAmbientPulsing()
+                && !mParent.showingPulsing()
                 && (mCheckForDrag == null || !mHandler.hasCallbacks(mCheckForDrag))) {
             // Only show the menu if we're not a heads up view and guts aren't exposed.
             mCheckForDrag = new CheckForDrag();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index ee2dacd6..20e8b73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -18,6 +18,7 @@
 
 import static com.android.systemui.Dependency.MAIN_HANDLER;
 
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -28,7 +29,6 @@
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.text.format.DateUtils;
-import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewStub;
@@ -52,7 +52,6 @@
  */
 public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper {
 
-    private static final String TAG = "NotificationMediaTVW";
     private static final long PROGRESS_UPDATE_INTERVAL = 1000; // 1s
     private static final String COMPACT_MEDIA_TAG = "media";
     private final Handler mHandler = Dependency.get(MAIN_HANDLER);
@@ -63,6 +62,7 @@
     private TextView mSeekBarTotalTime;
     private long mDuration = 0;
     private MediaController mMediaController;
+    private MediaMetadata mMediaMetadata;
     private NotificationMediaManager mMediaManager;
     private View mSeekBarView;
     private Context mContext;
@@ -81,7 +81,7 @@
 
         @Override
         public void onStopTrackingTouch(SeekBar seekBar) {
-            if (mMediaController != null && canSeekMedia()) {
+            if (mMediaController != null) {
                 mMediaController.getTransportControls().seekTo(mSeekBar.getProgress());
                 mMetricsLogger.write(newLog(MetricsEvent.TYPE_UPDATE));
             }
@@ -96,16 +96,28 @@
         }
 
         @Override
-        public void onPlaybackStateChanged(PlaybackState state) {
+        public void onPlaybackStateChanged(@Nullable PlaybackState state) {
+            if (state == null) {
+                return;
+            }
+
             if (state.getState() != PlaybackState.STATE_PLAYING) {
                 // Update the UI once, in case playback info changed while we were paused
-                mUpdatePlaybackUi.run();
+                updatePlaybackUi(state);
                 clearTimer();
             } else if (mSeekBarTimer == null && mSeekBarView != null
                     && mSeekBarView.getVisibility() != View.GONE) {
                 startTimer();
             }
         }
+
+        @Override
+        public void onMetadataChanged(@Nullable MediaMetadata metadata) {
+            if (mMediaMetadata == null || !mMediaMetadata.equals(metadata)) {
+                mMediaMetadata = metadata;
+                updateDuration();
+            }
+        }
     };
 
     protected NotificationMediaTemplateViewWrapper(Context ctx, View view,
@@ -140,12 +152,11 @@
             controllerUpdated = true;
         }
 
-        if (mMediaController.getMetadata() != null) {
-            long duration = mMediaController.getMetadata().getLong(
-                    MediaMetadata.METADATA_KEY_DURATION);
+        mMediaMetadata = mMediaController.getMetadata();
+        if (mMediaMetadata != null) {
+            long duration = mMediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
             if (duration <= 0) {
                 // Don't include the seekbar if this is a livestream
-                Log.d(TAG, "removing seekbar");
                 if (mSeekBarView != null && mSeekBarView.getVisibility() != View.GONE) {
                     mSeekBarView.setVisibility(View.GONE);
                     mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE));
@@ -156,12 +167,12 @@
                     mMetricsLogger.write(newLog(MetricsEvent.TYPE_CLOSE));
                 }
                 return;
-            } else {
+            } else if (mSeekBarView != null && mSeekBarView.getVisibility() == View.GONE) {
                 // Otherwise, make sure the seekbar is visible
-                if (mSeekBarView != null && mSeekBarView.getVisibility() == View.GONE) {
-                    mSeekBarView.setVisibility(View.VISIBLE);
-                    mMetricsLogger.write(newLog(MetricsEvent.TYPE_OPEN));
-                }
+                mSeekBarView.setVisibility(View.VISIBLE);
+                mMetricsLogger.write(newLog(MetricsEvent.TYPE_OPEN));
+                updateDuration();
+                startTimer();
             }
         }
 
@@ -181,13 +192,13 @@
             mSeekBarTotalTime = mSeekBarView.findViewById(R.id.notification_media_total_time);
 
             if (mSeekBarTimer == null) {
-                if (canSeekMedia()) {
+                if (mMediaController != null && canSeekMedia(mMediaController.getPlaybackState())) {
                     // Log initial state, since it will not be updated
                     mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, 1));
                 } else {
                     setScrubberVisible(false);
                 }
-
+                updateDuration();
                 startTimer();
                 mMediaController.registerCallback(mMediaCallback);
             }
@@ -201,7 +212,7 @@
         mSeekBarTimer.schedule(new TimerTask() {
             @Override
             public void run() {
-                mHandler.post(mUpdatePlaybackUi);
+                mHandler.post(mOnUpdateTimerTick);
             }
         }, 0, PROGRESS_UPDATE_INTERVAL);
     }
@@ -215,14 +226,12 @@
         }
     }
 
-    private boolean canSeekMedia() {
-        if (mMediaController == null || mMediaController.getPlaybackState() == null) {
-            Log.d(TAG, "Cannot seek media because the controller is invalid");
+    private boolean canSeekMedia(@Nullable PlaybackState state) {
+        if (state == null) {
             return false;
         }
 
-        long actions = mMediaController.getPlaybackState().getActions();
-        Log.d(TAG, "Playback state actions are " + actions);
+        long actions = state.getActions();
         return ((actions & PlaybackState.ACTION_SEEK_TO) != 0);
     }
 
@@ -236,39 +245,44 @@
         mMetricsLogger.write(newLog(MetricsEvent.TYPE_DETAIL, isVisible ? 1 : 0));
     }
 
-    protected final Runnable mUpdatePlaybackUi = new Runnable() {
+    private void updateDuration() {
+        if (mMediaMetadata != null && mSeekBar != null) {
+            long duration = mMediaMetadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
+            if (mDuration != duration) {
+                mDuration = duration;
+                mSeekBar.setMax((int) mDuration);
+                mSeekBarTotalTime.setText(millisecondsToTimeString(duration));
+            }
+        }
+    }
+
+    protected final Runnable mOnUpdateTimerTick = new Runnable() {
         @Override
         public void run() {
             if (mMediaController != null && mSeekBar != null) {
-                MediaMetadata metadata = mMediaController.getMetadata();
                 PlaybackState playbackState = mMediaController.getPlaybackState();
 
-                if (metadata != null && playbackState != null) {
-                    long position = playbackState.getPosition();
-                    long duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
-
-                    if (mDuration != duration) {
-                        mDuration = duration;
-                        mSeekBar.setMax((int) mDuration);
-                        mSeekBarTotalTime.setText(millisecondsToTimeString(duration));
-                    }
-                    mSeekBar.setProgress((int) position);
-
-                    mSeekBarElapsedTime.setText(millisecondsToTimeString(position));
-
-                    // Update scrubber in case available actions have changed
-                    setScrubberVisible(canSeekMedia());
+                if (playbackState != null) {
+                    updatePlaybackUi(playbackState);
                 } else {
-                    Log.d(TAG, "Controller missing data " + metadata + " " + playbackState);
                     clearTimer();
                 }
             } else {
-                Log.d(TAG, "No longer have a valid media controller");
                 clearTimer();
             }
         }
     };
 
+    private void updatePlaybackUi(PlaybackState state) {
+        long position = state.getPosition();
+        mSeekBar.setProgress((int) position);
+
+        mSeekBarElapsedTime.setText(millisecondsToTimeString(position));
+
+        // Update scrubber in case available actions have changed
+        setScrubberVisible(canSeekMedia(state));
+    }
+
     private String millisecondsToTimeString(long milliseconds) {
         long seconds = milliseconds / 1000;
         String text = DateUtils.formatElapsedTime(seconds);
@@ -295,6 +309,7 @@
         int tintColor = getNotificationHeader().getOriginalIconColor();
         mSeekBarElapsedTime.setTextColor(tintColor);
         mSeekBarTotalTime.setTextColor(tintColor);
+        mSeekBarTotalTime.setShadowLayer(1.5f, 1.5f, 1.5f, mBackgroundColor);
 
         ColorStateList tintList = ColorStateList.valueOf(tintColor);
         mSeekBar.setThumbTintList(tintList);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index 7ebdb93..97d8443 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -51,7 +51,7 @@
  */
 public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapper {
 
-    private final int mTranslationForHeader;
+    private final int mFullHeaderTranslation;
     protected ImageView mPicture;
     private ProgressBar mProgressBar;
     private TextView mTitle;
@@ -135,7 +135,7 @@
                     }
 
                 }, TRANSFORMING_VIEW_TEXT);
-        mTranslationForHeader = ctx.getResources().getDimensionPixelSize(
+        mFullHeaderTranslation = ctx.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin)
                 - ctx.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin_top);
@@ -340,20 +340,20 @@
 
             // We also need to compensate for any header translation, since we're always at the end.
             mActionsContainer.setTranslationY(constrainedContentHeight - mView.getHeight()
-                    - getHeaderTranslation());
+                    - getHeaderTranslation(false /* forceNoHeader */));
         }
     }
 
     @Override
-    public int getHeaderTranslation() {
-        return (int) mHeaderTranslation;
+    public int getHeaderTranslation(boolean forceNoHeader) {
+        return forceNoHeader ? mFullHeaderTranslation : (int) mHeaderTranslation;
     }
 
     @Override
     public void setHeaderVisibleAmount(float headerVisibleAmount) {
         super.setHeaderVisibleAmount(headerVisibleAmount);
         mNotificationHeader.setAlpha(headerVisibleAmount);
-        mHeaderTranslation = (1.0f - headerVisibleAmount) * mTranslationForHeader;
+        mHeaderTranslation = (1.0f - headerVisibleAmount) * mFullHeaderTranslation;
         mView.setTranslationY(mHeaderTranslation);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 3808702..47906a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -224,7 +224,7 @@
         return null;
     }
 
-    public int getHeaderTranslation() {
+    public int getHeaderTranslation(boolean forceNoHeader) {
         return 0;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index d9162c0..f3d068a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -24,7 +24,6 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -32,6 +31,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import java.util.ArrayList;
 
@@ -54,7 +54,6 @@
     private int mSpeedBumpIndex = -1;
     private boolean mDozing;
     private boolean mHideSensitive;
-    private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
     private float mStackTranslation;
     private int mLayoutHeight;
     private int mTopPadding;
@@ -79,15 +78,19 @@
     private int mIntrinsicPadding;
     private int mExpandAnimationTopChange;
     private ExpandableNotificationRow mExpandingNotification;
-    private float mDarkAmount;
+    private float mHideAmount;
     private boolean mAppearing;
     private float mPulseHeight = MAX_PULSE_HEIGHT;
     private float mDozeAmount = 0.0f;
+    private HeadsUpManager mHeadUpManager;
+    private Runnable mOnPulseHeightChangedListener;
 
     public AmbientState(
             Context context,
-            @NonNull SectionProvider sectionProvider) {
+            @NonNull SectionProvider sectionProvider,
+            HeadsUpManager headsUpManager) {
         mSectionProvider = sectionProvider;
+        mHeadUpManager = headsUpManager;
         reload(context);
     }
 
@@ -180,23 +183,23 @@
         mDimmed = dimmed;
     }
 
-    /** In dark mode, we draw as little as possible, assuming a black background */
+    /** While dozing, we draw as little as possible, assuming a black background */
     public void setDozing(boolean dozing) {
         mDozing = dozing;
     }
 
-    /** Dark ratio of the status bar **/
-    public void setDarkAmount(float darkAmount) {
-        if (darkAmount == 1.0f && mDarkAmount != darkAmount) {
-            // Whenever we are fully dark, let's reset the pulseHeight again
-            mPulseHeight = MAX_PULSE_HEIGHT;
+    /** Hide ratio of the status bar **/
+    public void setHideAmount(float hidemount) {
+        if (hidemount == 1.0f && mHideAmount != hidemount) {
+            // Whenever we are fully hidden, let's reset the pulseHeight again
+            setPulseHeight(MAX_PULSE_HEIGHT);
         }
-        mDarkAmount = darkAmount;
+        mHideAmount = hidemount;
     }
 
-    /** Returns the dark ratio of the status bar */
-    public float getDarkAmount() {
-        return mDarkAmount;
+    /** Returns the hide ratio of the status bar */
+    public float getHideAmount() {
+        return mHideAmount;
     }
 
     public void setHideSensitive(boolean hideSensitive) {
@@ -295,7 +298,7 @@
     }
 
     public boolean isPulseExpanding() {
-        return mPulseHeight != MAX_PULSE_HEIGHT && mDozeAmount != 0.0f && mDarkAmount != 1.0f;
+        return mPulseHeight != MAX_PULSE_HEIGHT && mDozeAmount != 0.0f && mHideAmount != 1.0f;
     }
 
     public boolean isShadeExpanded() {
@@ -389,8 +392,7 @@
     }
 
     public boolean hasPulsingNotifications() {
-        return mPulsing && mAmbientPulseManager != null
-                && mAmbientPulseManager.hasNotifications();
+        return mPulsing && mHeadUpManager != null && mHeadUpManager.hasNotifications();
     }
 
     public void setPulsing(boolean hasPulsing) {
@@ -405,10 +407,10 @@
     }
 
     public boolean isPulsing(NotificationEntry entry) {
-        if (!mPulsing || mAmbientPulseManager == null) {
+        if (!mPulsing || mHeadUpManager == null) {
             return false;
         }
-        return mAmbientPulseManager.isAlerting(entry.key);
+        return mHeadUpManager.isAlerting(entry.key);
     }
 
     public boolean isPanelTracking() {
@@ -481,14 +483,15 @@
     }
 
     /**
-     * @return {@code true } when shade is completely dark: in AOD or ambient display.
+     * @return {@code true } when shade is completely hidden: in AOD, ambient display or when
+     * bypassing.
      */
-    public boolean isFullyDark() {
-        return mDarkAmount == 1;
+    public boolean isFullyHidden() {
+        return mHideAmount == 1;
     }
 
-    public boolean isDarkAtAll() {
-        return mDarkAmount != 0;
+    public boolean isHiddenAtAll() {
+        return mHideAmount != 0;
     }
 
     public void setAppearing(boolean appearing) {
@@ -500,7 +503,20 @@
     }
 
     public void setPulseHeight(float height) {
-        mPulseHeight = height;
+        if (height != mPulseHeight) {
+            mPulseHeight = height;
+            if (mOnPulseHeightChangedListener != null) {
+                mOnPulseHeightChangedListener.run();
+            }
+        }
+    }
+
+    public float getPulseHeight() {
+        if (mPulseHeight == MAX_PULSE_HEIGHT) {
+            // If we're not pulse expanding, the height should be 0
+            return 0;
+        }
+        return mPulseHeight;
     }
 
     public void setDozeAmount(float dozeAmount) {
@@ -508,7 +524,7 @@
             mDozeAmount = dozeAmount;
             if (dozeAmount == 0.0f || dozeAmount == 1.0f) {
                 // We woke all the way up, let's reset the pulse height
-                mPulseHeight = MAX_PULSE_HEIGHT;
+                setPulseHeight(MAX_PULSE_HEIGHT);
             }
         }
     }
@@ -520,4 +536,12 @@
     public boolean isFullyAwake() {
         return mDozeAmount == 0.0f;
     }
+
+    public void setOnPulseHeightChangedListener(Runnable onPulseHeightChangedListener) {
+        mOnPulseHeightChangedListener = onPulseHeightChangedListener;
+    }
+
+    public Runnable getOnPulseHeightChangedListener() {
+        return mOnPulseHeightChangedListener;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
index a471d87..6cd2290 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
@@ -36,7 +36,6 @@
     boolean animateHeight;
     boolean animateTopInset;
     boolean animateDimmed;
-    boolean animateDark;
     boolean animateHideSensitive;
     boolean hasDelays;
     boolean hasGoToFullShadeEvent;
@@ -89,11 +88,6 @@
         return this;
     }
 
-    public AnimationFilter animateDark() {
-        animateDark = true;
-        return this;
-    }
-
     public AnimationFilter animateHideSensitive() {
         animateHideSensitive = true;
         return this;
@@ -145,7 +139,6 @@
         animateHeight |= filter.animateHeight;
         animateTopInset |= filter.animateTopInset;
         animateDimmed |= filter.animateDimmed;
-        animateDark |= filter.animateDark;
         animateHideSensitive |= filter.animateHideSensitive;
         hasDelays |= filter.hasDelays;
         mAnimatedProperties.addAll(filter.mAnimatedProperties);
@@ -160,7 +153,6 @@
         animateHeight = false;
         animateTopInset = false;
         animateDimmed = false;
-        animateDark = false;
         animateHideSensitive = false;
         hasDelays = false;
         hasGoToFullShadeEvent = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
index f28e556..72ef7f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
@@ -85,7 +85,6 @@
 
     public int height;
     public boolean dimmed;
-    public boolean dark;
     public boolean hideSensitive;
     public boolean belowSpeedBump;
     public boolean inShelf;
@@ -121,7 +120,6 @@
             ExpandableViewState svs = (ExpandableViewState) viewState;
             height = svs.height;
             dimmed = svs.dimmed;
-            dark = svs.dark;
             hideSensitive = svs.hideSensitive;
             belowSpeedBump = svs.belowSpeedBump;
             clipTopAmount = svs.clipTopAmount;
@@ -158,9 +156,6 @@
             // apply below shelf speed bump
             expandableView.setBelowSpeedBump(this.belowSpeedBump);
 
-            // apply dark
-            expandableView.setDark(this.dark, false /* animate */, 0 /* delay */);
-
             // apply clipping
             float oldClipTopAmount = expandableView.getClipTopAmount();
             if (oldClipTopAmount != this.clipTopAmount) {
@@ -209,9 +204,6 @@
         expandableView.setHideSensitive(this.hideSensitive, animationFilter.animateHideSensitive,
                 properties.delay, properties.duration);
 
-        // start dark animation
-        expandableView.setDark(this.dark, animationFilter.animateDark, properties.delay);
-
         if (properties.wasAdded(child) && !hidden) {
             expandableView.performAddAnimation(properties.delay, properties.duration,
                     false /* isHeadsUpAppear */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 6632ae6..45f7b3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -567,7 +567,6 @@
                     ? parentState.zTranslation
                     : 0;
             childState.dimmed = parentState.dimmed;
-            childState.dark = parentState.dark;
             childState.hideSensitive = parentState.hideSensitive;
             childState.belowSpeedBump = parentState.belowSpeedBump;
             childState.clipTopAmount = 0;
@@ -662,8 +661,10 @@
                 && !showingAsLowPriority()) {
             return NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;
         }
-        if (mIsLowPriority || !mContainingNotification.isOnKeyguard()
-                && (mContainingNotification.isExpanded() || mContainingNotification.isHeadsUp())) {
+        if (mIsLowPriority
+                || (!mContainingNotification.isOnKeyguard() && mContainingNotification.isExpanded())
+                || (mContainingNotification.isHeadsUpState()
+                        && mContainingNotification.canShowHeadsUp())) {
             return NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED;
         }
         return NUMBER_OF_CHILDREN_WHEN_COLLAPSED;
@@ -1066,6 +1067,11 @@
                 false /* likeHighPriority */);
     }
 
+    public int getCollapsedHeightWithoutHeader() {
+        return getMinHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */),
+                false /* likeHighPriority */, 0);
+    }
+
     /**
      * Get the minimum Height for this group.
      *
@@ -1073,10 +1079,22 @@
      * @param likeHighPriority if the height should be calculated as if it were not low priority
      */
     private int getMinHeight(int maxAllowedVisibleChildren, boolean likeHighPriority) {
+        return getMinHeight(maxAllowedVisibleChildren, likeHighPriority, mCurrentHeaderTranslation);
+    }
+
+    /**
+     * Get the minimum Height for this group.
+     *
+     * @param maxAllowedVisibleChildren the number of children that should be visible
+     * @param likeHighPriority if the height should be calculated as if it were not low priority
+     * @param headerTranslation the translation amount of the header
+     */
+    private int getMinHeight(int maxAllowedVisibleChildren, boolean likeHighPriority,
+            int headerTranslation) {
         if (!likeHighPriority && showingAsLowPriority()) {
             return mNotificationHeaderLowPriority.getHeight();
         }
-        int minExpandHeight = mNotificationHeaderMargin + mCurrentHeaderTranslation;
+        int minExpandHeight = mNotificationHeaderMargin + headerTranslation;
         int visibleChildren = 0;
         boolean firstChild = true;
         int childCount = mChildren.size();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index c5ab9f6..4221846 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -18,11 +18,14 @@
 
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.NUM_SECTIONS;
 
-import com.android.systemui.statusbar.AmbientPulseManager;
+
+import android.util.MathUtils;
+
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 
 import java.util.HashSet;
@@ -34,27 +37,26 @@
  * A class that manages the roundness for notification views
  */
 @Singleton
-class NotificationRoundnessManager implements OnHeadsUpChangedListener,
-        AmbientPulseManager.OnAmbientChangedListener {
+public class NotificationRoundnessManager implements OnHeadsUpChangedListener {
 
     private final ActivatableNotificationView[] mFirstInSectionViews;
     private final ActivatableNotificationView[] mLastInSectionViews;
     private final ActivatableNotificationView[] mTmpFirstInSectionViews;
     private final ActivatableNotificationView[] mTmpLastInSectionViews;
+    private final KeyguardBypassController mBypassController;
     private boolean mExpanded;
     private HashSet<ExpandableView> mAnimatedChildren;
     private Runnable mRoundingChangedCallback;
     private ExpandableNotificationRow mTrackedHeadsUp;
-    private ActivatableNotificationView mTrackedAmbient;
     private float mAppearFraction;
 
     @Inject
-    NotificationRoundnessManager(AmbientPulseManager ambientPulseManager) {
+    NotificationRoundnessManager(KeyguardBypassController keyguardBypassController) {
         mFirstInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
         mLastInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
         mTmpFirstInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
         mTmpLastInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
-        ambientPulseManager.addListener(this);
+        mBypassController = keyguardBypassController;
     }
 
     @Override
@@ -73,14 +75,8 @@
     }
 
     @Override
-    public void onAmbientStateChanged(NotificationEntry entry, boolean isPulsing) {
-        ActivatableNotificationView row = entry.getRow();
-        if (isPulsing) {
-            mTrackedAmbient = row;
-        } else if (mTrackedAmbient == row) {
-            mTrackedAmbient = null;
-        }
-        updateView(row, false /* animate */);
+    public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
+        updateView(entry.getRow(), false /* animate */);
     }
 
     private void updateView(ActivatableNotificationView view, boolean animate) {
@@ -140,12 +136,12 @@
         if (isLastInSection(view, true /* include last section */) && !top) {
             return 1.0f;
         }
-        if (view == mTrackedHeadsUp && mAppearFraction <= 0.0f) {
+        if (view == mTrackedHeadsUp) {
             // If we're pushing up on a headsup the appear fraction is < 0 and it needs to still be
             // rounded.
-            return 1.0f;
+            return MathUtils.saturate(1.0f - mAppearFraction);
         }
-        if (view == mTrackedAmbient) {
+        if (view.showingPulsing() && !mBypassController.getBypassEnabled()) {
             return 1.0f;
         }
         return 0.0f;
@@ -242,6 +238,10 @@
     }
 
     public void setTrackingHeadsUp(ExpandableNotificationRow row) {
+        ExpandableNotificationRow previous = mTrackedHeadsUp;
         mTrackedHeadsUp = row;
+        if (previous != null) {
+            updateView(previous, true /* animate */);
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
index cbcfdd4..f39ed2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -254,7 +254,7 @@
                 newTop = (int) Math.ceil(firstView.getTranslationY());
             }
             top = Math.max(newTop, top);
-            if (firstView.showingAmbientPulsing()) {
+            if (firstView.showingPulsing()) {
                 // If we're pulsing, the notification can actually go below!
                 bottom = Math.max(bottom, finalTranslationY
                         + ExpandableViewState.getFinalActualHeight(firstView));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
index 5747bb1..170a4d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
@@ -19,7 +19,6 @@
 import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
 
 import android.annotation.Nullable;
-import android.content.Context;
 import android.content.Intent;
 import android.provider.Settings;
 import android.view.LayoutInflater;
@@ -32,6 +31,8 @@
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 
 /**
  * Manages the boundaries of the two notification sections (high priority and low priority). Also
@@ -43,8 +44,10 @@
     private final NotificationStackScrollLayout mParent;
     private final ActivityStarter mActivityStarter;
     private final StatusBarStateController mStatusBarStateController;
+    private final ConfigurationController mConfigurationController;
     private final boolean mUseMultipleSections;
 
+    private boolean mInitialized = false;
     private SectionHeaderView mGentleHeader;
     private boolean mGentleHeaderVisible = false;
     @Nullable private ExpandableNotificationRow mFirstGentleNotif;
@@ -54,18 +57,29 @@
             NotificationStackScrollLayout parent,
             ActivityStarter activityStarter,
             StatusBarStateController statusBarStateController,
+            ConfigurationController configurationController,
             boolean useMultipleSections) {
         mParent = parent;
         mActivityStarter = activityStarter;
         mStatusBarStateController = statusBarStateController;
+        mConfigurationController = configurationController;
         mUseMultipleSections = useMultipleSections;
     }
 
+    /** Must be called before use. */
+    void initialize(LayoutInflater layoutInflater) {
+        if (mInitialized) {
+            throw new IllegalStateException("NotificationSectionsManager already initialized");
+        }
+        mInitialized = true;
+        reinflateViews(layoutInflater);
+        mConfigurationController.addCallback(mConfigurationListener);
+    }
+
     /**
-     * Must be called before use. Should be called again whenever inflation-related things change,
-     * such as density or theme changes.
+     * Reinflates the entire notification header, including all decoration views.
      */
-    void inflateViews(Context context) {
+    void reinflateViews(LayoutInflater layoutInflater) {
         int oldPos = -1;
         if (mGentleHeader != null) {
             if (mGentleHeader.getTransientContainer() != null) {
@@ -76,7 +90,7 @@
             }
         }
 
-        mGentleHeader = (SectionHeaderView) LayoutInflater.from(context).inflate(
+        mGentleHeader = (SectionHeaderView) layoutInflater.inflate(
                 R.layout.status_bar_notification_section_header, mParent, false);
         mGentleHeader.setOnHeaderClickListener(this::onGentleHeaderClick);
         mGentleHeader.setOnClearAllClickListener(this::onClearGentleNotifsClick);
@@ -244,6 +258,13 @@
         return lastChildBeforeGap;
     }
 
+    private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+        @Override
+        public void onLocaleListChanged() {
+            mGentleHeader.reinflateContents();
+        }
+    };
+
     private void onGentleHeaderClick(View v) {
         Intent intent = new Intent(Settings.ACTION_NOTIFICATION_SETTINGS);
         mActivityStarter.startActivity(
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 6ce604b..bec9520 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
@@ -20,7 +20,7 @@
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
 import static com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.ANCHOR_SCROLLING;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
-import static com.android.systemui.statusbar.phone.NotificationIconAreaController.LOW_PRIORITY;
+import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
 import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -32,7 +32,6 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -87,7 +86,6 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
@@ -97,7 +95,6 @@
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DragDownHelper.DragDownCallback;
 import com.android.systemui.statusbar.EmptyShadeView;
@@ -126,10 +123,10 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.row.NotificationSnooze;
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
-import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.NotificationGroupManager.OnGroupChangeListener;
@@ -143,6 +140,7 @@
 import com.android.systemui.statusbar.policy.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
 import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.Assert;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -180,14 +178,14 @@
      * gap is drawn between them). In this case we don't want to round their corners.
      */
     private static final int DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX = 1;
-    private final AmbientPulseManager mAmbientPulseManager;
+    private final KeyguardBypassController mKeyguardBypassController;
 
     private ExpandHelper mExpandHelper;
     private final NotificationSwipeHelper mSwipeHelper;
     private int mCurrentStackHeight = Integer.MAX_VALUE;
     private final Paint mBackgroundPaint = new Paint();
     private final boolean mShouldDrawNotificationBackground;
-    private boolean mLowPriorityBeforeSpeedBump;
+    private boolean mHighPriorityBeforeSpeedBump;
     private final boolean mAllowLongPress;
     private boolean mDismissRtl;
 
@@ -267,8 +265,6 @@
     private boolean mTopPaddingNeedsAnimation;
     private boolean mDimmedNeedsAnimation;
     private boolean mHideSensitiveNeedsAnimation;
-    private boolean mDarkNeedsAnimation;
-    private int mDarkAnimationOriginIndex;
     private boolean mActivateNeedsAnimation;
     private boolean mGoToFullShadeNeedsAnimation;
     private boolean mIsExpanded = true;
@@ -409,9 +405,9 @@
     private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() {
         @Override
         public void getOutline(View view, Outline outline) {
-            if (mAmbientState.isDarkAtAll()) {
-                float xProgress = mDarkXInterpolator.getInterpolation(
-                        (1 - mLinearDarkAmount) * mBackgroundXFactor);
+            if (mAmbientState.isHiddenAtAll()) {
+                float xProgress = mHideXInterpolator.getInterpolation(
+                        (1 - mLinearHideAmount) * mBackgroundXFactor);
                 outline.setRoundRect(mBackgroundAnimationRect,
                         MathUtils.lerp(mCornerRadius / 2.0f, mCornerRadius,
                                 xProgress));
@@ -427,14 +423,14 @@
     private View mForcedScroll;
 
     /**
-     * @see #setDarkAmount(float, float)
+     * @see #setHideAmount(float, float)
      */
-    private float mInterpolatedDarkAmount = 0f;
+    private float mInterpolatedHideAmount = 0f;
 
     /**
-     * @see #setDarkAmount(float, float)
+     * @see #setHideAmount(float, float)
      */
-    private float mLinearDarkAmount = 0f;
+    private float mLinearHideAmount = 0f;
 
     /**
      * How fast the background scales in the X direction as a factor of the Y expansion.
@@ -469,16 +465,12 @@
     private int mCornerRadius;
     private int mSidePaddings;
     private final Rect mBackgroundAnimationRect = new Rect();
-    private int mAntiBurnInOffsetX;
     private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
     private int mHeadsUpInset;
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
     private NotificationIconAreaController mIconAreaController;
-    private float mHorizontalPanelTranslation;
     private final NotificationLockscreenUserManager mLockscreenUserManager =
             Dependency.get(NotificationLockscreenUserManager.class);
-    protected final NotificationGutsManager mGutsManager =
-            Dependency.get(NotificationGutsManager.class);
     private final Rect mTmpRect = new Rect();
     private final NotificationEntryManager mEntryManager =
             Dependency.get(NotificationEntryManager.class);
@@ -497,17 +489,16 @@
             Dependency.get(VisualStabilityManager.class);
     protected boolean mClearAllEnabled;
 
-    private Interpolator mDarkXInterpolator = Interpolators.FAST_OUT_SLOW_IN;
+    private Interpolator mHideXInterpolator = Interpolators.FAST_OUT_SLOW_IN;
     private NotificationPanelView mNotificationPanel;
     private final ShadeController mShadeController = Dependency.get(ShadeController.class);
 
     private final NotificationGutsManager
             mNotificationGutsManager = Dependency.get(NotificationGutsManager.class);
     private final NotificationSectionsManager mSectionsManager;
-    /**
-     * If the {@link NotificationShelf} should be visible when dark.
-     */
     private boolean mAnimateBottomOnLayout;
+    private float mLastSentAppear;
+    private float mLastSentExpandedHeight;
 
     @Inject
     public NotificationStackScrollLayout(
@@ -515,10 +506,13 @@
             AttributeSet attrs,
             @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
             NotificationRoundnessManager notificationRoundnessManager,
-            AmbientPulseManager ambientPulseManager,
             DynamicPrivacyController dynamicPrivacyController,
+            ConfigurationController configurationController,
             ActivityStarter activityStarter,
-            StatusBarStateController statusBarStateController) {
+            StatusBarStateController statusBarStateController,
+            HeadsUpManagerPhone headsUpManager,
+            KeyguardBypassController keyguardBypassController,
+            FalsingManager falsingManager) {
         super(context, attrs, 0, 0);
         Resources res = getResources();
 
@@ -527,24 +521,29 @@
         for (int i = 0; i < NUM_SECTIONS; i++) {
             mSections[i] = new NotificationSection(this);
         }
+        mRoundnessManager = notificationRoundnessManager;
 
-        mAmbientPulseManager = ambientPulseManager;
+        mHeadsUpManager = headsUpManager;
+        mHeadsUpManager.addListener(mRoundnessManager);
+        mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
+        mKeyguardBypassController = keyguardBypassController;
+        mFalsingManager = falsingManager;
 
         mSectionsManager =
                 new NotificationSectionsManager(
                         this,
                         activityStarter,
                         statusBarStateController,
+                        configurationController,
                         NotificationUtils.useNewInterruptionModel(context));
-        mSectionsManager.inflateViews(context);
+        mSectionsManager.initialize(LayoutInflater.from(context));
         mSectionsManager.setOnClearGentleNotifsClickListener(v -> {
             // Leave the shade open if there will be other notifs left over to clear
             final boolean closeShade = !hasActiveClearableNotifications(ROWS_HIGH_PRIORITY);
             clearNotifications(ROWS_GENTLE, closeShade);
         });
 
-        mAmbientState = new AmbientState(context, mSectionsManager);
-        mRoundnessManager = notificationRoundnessManager;
+        mAmbientState = new AmbientState(context, mSectionsManager, mHeadsUpManager);
         mBgColor = context.getColor(R.color.notification_shade_background_color);
         int minHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
         int maxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
@@ -553,27 +552,27 @@
         mExpandHelper.setEventSource(this);
         mExpandHelper.setScrollAdapter(this);
         mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, mNotificationCallback,
-                getContext(), mMenuEventListener);
+                getContext(), mMenuEventListener, mFalsingManager);
         mStackScrollAlgorithm = createStackScrollAlgorithm(context);
         initView(context);
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
         mShouldDrawNotificationBackground =
                 res.getBoolean(R.bool.config_drawNotificationBackground);
         mFadeNotificationsOnDismiss =
                 res.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
         mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
         mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
-        addOnExpandedHeightListener(mRoundnessManager::setExpanded);
+        addOnExpandedHeightChangedListener(mRoundnessManager::setExpanded);
         setOutlineProvider(mOutlineProvider);
 
         // Blocking helper manager wants to know the expanded state, update as well.
         NotificationBlockingHelperManager blockingHelperManager =
                 Dependency.get(NotificationBlockingHelperManager.class);
-        addOnExpandedHeightListener((height, unused) -> {
+        addOnExpandedHeightChangedListener((height, unused) -> {
             blockingHelperManager.setNotificationShadeExpanded(height);
         });
 
-        updateWillNotDraw();
+        boolean willDraw = mShouldDrawNotificationBackground || DEBUG;
+        setWillNotDraw(!willDraw);
         mBackgroundPaint.setAntiAlias(true);
         if (DEBUG) {
             mDebugPaint = new Paint();
@@ -586,12 +585,12 @@
 
         TunerService tunerService = Dependency.get(TunerService.class);
         tunerService.addTunable((key, newValue) -> {
-            if (key.equals(LOW_PRIORITY)) {
-                mLowPriorityBeforeSpeedBump = "1".equals(newValue);
+            if (key.equals(HIGH_PRIORITY)) {
+                mHighPriorityBeforeSpeedBump = "1".equals(newValue);
             } else if (key.equals(Settings.Secure.NOTIFICATION_DISMISS_RTL)) {
                 updateDismissRtlSetting("1".equals(newValue));
             }
-        }, LOW_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL);
+        }, HIGH_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL);
 
         mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
             @Override
@@ -625,17 +624,21 @@
         inflateFooterView();
         mVisualStabilityManager.setVisibilityLocationProvider(this::isInVisibleLocation);
         if (mAllowLongPress) {
-            setLongPressListener(mGutsManager::openGuts);
+            setLongPressListener(mNotificationGutsManager::openGuts);
         }
     }
 
     /**
      * @return the height at which we will wake up when pulsing
      */
-    public float getPulseHeight() {
+    public float getWakeUpHeight() {
         ActivatableNotificationView firstChild = getFirstChildWithBackground();
         if (firstChild != null) {
-            return firstChild.getCollapsedHeight();
+            if (mKeyguardBypassController.getBypassEnabled()) {
+                return firstChild.getHeadsUpHeightWithoutHeader();
+            } else {
+                return firstChild.getCollapsedHeight();
+            }
         }
         return 0f;
     }
@@ -650,21 +653,13 @@
         inflateFooterView();
         inflateEmptyShadeView();
         updateFooter();
-        mSectionsManager.inflateViews(mContext);
+        mSectionsManager.reinflateViews(LayoutInflater.from(mContext));
     }
 
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void onThemeChanged() {
-        int which;
-        if (mStatusBarState == StatusBarState.KEYGUARD
-                || mStatusBarState == StatusBarState.SHADE_LOCKED) {
-            which = WallpaperManager.FLAG_LOCK;
-        } else {
-            which = WallpaperManager.FLAG_SYSTEM;
-        }
-        final boolean useDarkText = mColorExtractor.getColors(which,
-                true /* ignoreVisibility */).supportsDarkText();
+        final boolean useDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         updateDecorViews(useDarkText);
 
         updateFooter();
@@ -816,17 +811,17 @@
         int lockScreenRight = getWidth() - mSidePaddings;
         int lockScreenTop = mSections[0].getCurrentBounds().top;
         int lockScreenBottom = mSections[NUM_SECTIONS - 1].getCurrentBounds().bottom;
-        int darkLeft = getWidth() / 2;
-        int darkTop = mTopPadding;
+        int hiddenLeft = getWidth() / 2;
+        int hiddenTop = mTopPadding;
 
-        float yProgress = 1 - mInterpolatedDarkAmount;
-        float xProgress = mDarkXInterpolator.getInterpolation(
-                (1 - mLinearDarkAmount) * mBackgroundXFactor);
+        float yProgress = 1 - mInterpolatedHideAmount;
+        float xProgress = mHideXInterpolator.getInterpolation(
+                (1 - mLinearHideAmount) * mBackgroundXFactor);
 
-        int left = (int) MathUtils.lerp(darkLeft, lockScreenLeft, xProgress);
-        int right = (int) MathUtils.lerp(darkLeft, lockScreenRight, xProgress);
-        int top = (int) MathUtils.lerp(darkTop, lockScreenTop, yProgress);
-        int bottom = (int) MathUtils.lerp(darkTop, lockScreenBottom, yProgress);
+        int left = (int) MathUtils.lerp(hiddenLeft, lockScreenLeft, xProgress);
+        int right = (int) MathUtils.lerp(hiddenLeft, lockScreenRight, xProgress);
+        int top = (int) MathUtils.lerp(hiddenTop, lockScreenTop, yProgress);
+        int bottom = (int) MathUtils.lerp(hiddenTop, lockScreenBottom, yProgress);
         mBackgroundAnimationRect.set(
                 left,
                 top,
@@ -842,7 +837,13 @@
                 break;
             }
         }
-        if (!mAmbientState.isDozing() || anySectionHasVisibleChild) {
+        boolean shouldDrawBackground;
+        if (mKeyguardBypassController.getBypassEnabled() && onKeyguard()) {
+            shouldDrawBackground = isPulseExpanding();
+        } else {
+            shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild;
+        }
+        if (shouldDrawBackground) {
             drawBackgroundRects(canvas, left, right, top, backgroundTopAnimationOffset);
         }
 
@@ -870,8 +871,8 @@
         int backgroundRectTop = top;
         int lastSectionBottom =
                 mSections[0].getCurrentBounds().bottom + animationYOffset;
-        int previousLeft = left;
-        int previousRight = right;
+        int currentLeft = left;
+        int currentRight = right;
         boolean first = true;
         for (NotificationSection section : mSections) {
             if (section.getFirstVisibleChild() == null) {
@@ -884,23 +885,23 @@
             // as separate roundrects, as the rounded corners right next to each other look
             // bad.
             if (sectionTop - lastSectionBottom > DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX
-                    || (previousLeft != ownLeft && !first)) {
-                canvas.drawRoundRect(ownLeft,
+                    || ((currentLeft != ownLeft || currentRight != ownRight) && !first)) {
+                canvas.drawRoundRect(currentLeft,
                         backgroundRectTop,
-                        ownRight,
+                        currentRight,
                         lastSectionBottom,
                         mCornerRadius, mCornerRadius, mBackgroundPaint);
                 backgroundRectTop = sectionTop;
             }
-            previousLeft = ownLeft;
-            previousRight = ownRight;
+            currentLeft = ownLeft;
+            currentRight = ownRight;
             lastSectionBottom =
                     section.getCurrentBounds().bottom + animationYOffset;
             first = false;
         }
-        canvas.drawRoundRect(previousLeft,
+        canvas.drawRoundRect(currentLeft,
                 backgroundRectTop,
-                previousRight,
+                currentRight,
                 lastSectionBottom,
                 mCornerRadius, mCornerRadius, mBackgroundPaint);
     }
@@ -942,7 +943,7 @@
         // Interpolate between semi-transparent notification panel background color
         // and white AOD separator.
         float colorInterpolation = MathUtils.smoothStep(0.4f /* start */, 1f /* end */,
-                mLinearDarkAmount);
+                mLinearHideAmount);
         int color = ColorUtils.blendARGB(mBgColor, Color.WHITE, colorInterpolation);
 
         if (mCachedBackgroundColor != color) {
@@ -996,6 +997,10 @@
         }
     }
 
+    public boolean isPulseExpanding() {
+        return mAmbientState.isPulseExpanding();
+    }
+
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@@ -1311,7 +1316,7 @@
                 stackHeight = (int) height;
             }
         } else {
-            appearFraction = getAppearFraction(height);
+            appearFraction = calculateAppearFraction(height);
             if (appearFraction >= 0) {
                 translationY = NotificationUtils.interpolate(getExpandTranslationStart(), 0,
                         appearFraction);
@@ -1334,9 +1339,26 @@
             requestChildrenUpdate();
         }
         setStackTranslation(translationY);
-        for (int i = 0; i < mExpandedHeightListeners.size(); i++) {
-            BiConsumer<Float, Float> listener = mExpandedHeightListeners.get(i);
-            listener.accept(mExpandedHeight, appearFraction);
+        notifyAppearChangedListeners();
+    }
+
+    private void notifyAppearChangedListeners() {
+        float appear;
+        float expandAmount;
+        if (mKeyguardBypassController.getBypassEnabled() && onKeyguard()) {
+            appear = calculateAppearFractionBypass();
+            expandAmount = getPulseHeight();
+        } else {
+            appear = MathUtils.saturate(calculateAppearFraction(mExpandedHeight));
+            expandAmount = mExpandedHeight;
+        }
+        if (appear != mLastSentAppear || expandAmount != mLastSentExpandedHeight) {
+            mLastSentAppear = appear;
+            mLastSentExpandedHeight = expandAmount;
+            for (int i = 0; i < mExpandedHeightListeners.size(); i++) {
+                BiConsumer<Float, Float> listener = mExpandedHeightListeners.get(i);
+                listener.accept(expandAmount, appear);
+            }
         }
     }
 
@@ -1363,11 +1385,12 @@
             mIsClipped = clipped;
         }
 
-        if (!mAmbientPulseManager.hasNotifications() && mAmbientState.isFullyDark()) {
-            setClipBounds(null);
-        } else if (mAmbientState.isDarkAtAll()) {
+        if (mAmbientState.isHiddenAtAll()) {
             clipToOutline = true;
             invalidateOutline();
+            if (isFullyHidden()) {
+                setClipBounds(null);
+            }
         } else if (clipped) {
             setClipBounds(mRequestedClipBounds);
         } else {
@@ -1457,7 +1480,7 @@
      * @return the fraction of the appear animation that has been performed
      */
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
-    public float getAppearFraction(float height) {
+    public float calculateAppearFraction(float height) {
         float appearEndPosition = getAppearEndPosition();
         float appearStartPosition = getAppearStartPosition();
         return (height - appearStartPosition)
@@ -2436,7 +2459,7 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private void updateBackground() {
         // No need to update the background color if it's not being drawn.
-        if (!mShouldDrawNotificationBackground || mAmbientState.isFullyDark()) {
+        if (!mShouldDrawNotificationBackground) {
             return;
         }
 
@@ -2528,12 +2551,15 @@
         }
         int minTopPosition = 0;
         NotificationSection lastSection = getLastVisibleSection();
-        if (mStatusBarState != StatusBarState.KEYGUARD) {
+        boolean onKeyguard = mStatusBarState == StatusBarState.KEYGUARD;
+        if (!onKeyguard) {
             minTopPosition = (int) (mTopPadding + mStackTranslation);
         } else if (lastSection == null) {
             minTopPosition = mTopPadding;
         }
-        boolean shiftPulsingWithFirst = mAmbientPulseManager.getAllEntries().count() <= 1;
+        boolean shiftPulsingWithFirst = mHeadsUpManager.getAllEntries().count() <= 1
+                && (mAmbientState.isDozing()
+                        || (mKeyguardBypassController.getBypassEnabled() && onKeyguard));
         for (NotificationSection section : mSections) {
             int minBottomPosition = minTopPosition;
             if (section == lastSection) {
@@ -2788,7 +2814,7 @@
         } else {
             mTopPaddingOverflow = 0;
         }
-        setTopPadding(topPadding, animate);
+        setTopPadding(topPadding, animate && !mKeyguardBypassController.getBypassEnabled());
         setExpandedHeight(mExpandedHeight);
     }
 
@@ -2857,6 +2883,7 @@
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void setChildTransferInProgress(boolean childTransferInProgress) {
+        Assert.isMainThread();
         mChildTransferInProgress = childTransferInProgress;
     }
 
@@ -3282,7 +3309,7 @@
     @Override
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {
-        if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress) {
+        if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress && !isFullyHidden()) {
             // Generate Animations
             mChildrenToAddAnimated.add(child);
             if (fromMoreCard) {
@@ -3290,7 +3317,8 @@
             }
             mNeedsAnimation = true;
         }
-        if (isHeadsUp(child) && mAnimationsEnabled && !mChangePositionInProgress) {
+        if (isHeadsUp(child) && mAnimationsEnabled && !mChangePositionInProgress
+                && !isFullyHidden()) {
             mAddedHeadsUpChildren.add(child);
             mChildrenToAddAnimated.remove(child);
         }
@@ -3299,6 +3327,11 @@
     @Override
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     public void changeViewPosition(ExpandableView child, int newIndex) {
+        Assert.isMainThread();
+        if (mChangePositionInProgress) {
+            throw new IllegalStateException("Reentrant call to changeViewPosition");
+        }
+
         int currentIndex = indexOfChild(child);
 
         if (currentIndex == -1) {
@@ -3358,7 +3391,6 @@
         generateActivateEvent();
         generateDimmedEvent();
         generateHideSensitiveEvent();
-        generateDarkEvent();
         generateGoToFullShadeEvent();
         generateViewResizeEvent();
         generateGroupExpansionEvent();
@@ -3370,10 +3402,20 @@
         for (Pair<ExpandableNotificationRow, Boolean> eventPair : mHeadsUpChangeAnimations) {
             ExpandableNotificationRow row = eventPair.first;
             boolean isHeadsUp = eventPair.second;
+            if (isHeadsUp != row.isHeadsUp()) {
+                // For cases where we have a heads up showing and appearing again we shouldn't
+                // do the animations at all.
+                continue;
+            }
             int type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER;
             boolean onBottom = false;
             boolean pinnedAndClosed = row.isPinned() && !mIsExpanded;
-            if (!mIsExpanded && !isHeadsUp) {
+            boolean performDisappearAnimation = !mIsExpanded
+                    // Only animate if we still have pinned heads up, otherwise we just have the
+                    // regular collapse animation of the lock screen
+                    || (mKeyguardBypassController.getBypassEnabled() && onKeyguard()
+                            && mHeadsUpManager.hasPinnedHeadsUp());
+            if (performDisappearAnimation && !isHeadsUp) {
                 type = row.wasJustClicked()
                         ? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
                         : AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
@@ -3573,20 +3615,6 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
-    private void generateDarkEvent() {
-        if (mDarkNeedsAnimation) {
-            AnimationEvent ev = new AnimationEvent(null,
-                    AnimationEvent.ANIMATION_TYPE_DARK,
-                    new AnimationFilter()
-                            .animateDark()
-                            .animateY(mShelf));
-            ev.darkAnimationOriginIndex = mDarkAnimationOriginIndex;
-            mAnimationEvents.add(ev);
-        }
-        mDarkNeedsAnimation = false;
-    }
-
-    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     private void generateGoToFullShadeEvent() {
         if (mGoToFullShadeNeedsAnimation) {
             mAnimationEvents.add(
@@ -4688,14 +4716,6 @@
         return mIntrinsicPadding;
     }
 
-    /**
-     * @return the y position of the first notification
-     */
-    @ShadeViewRefactor(RefactorComponent.COORDINATOR)
-    public float getNotificationsTopY() {
-        return mTopPadding + getStackTranslation();
-    }
-
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public boolean shouldDelayChildPressedState() {
@@ -4712,115 +4732,59 @@
             return;
         }
         mAmbientState.setDozing(dozing);
-        if (animate && mAnimationsEnabled) {
-            mDarkNeedsAnimation = true;
-            mDarkAnimationOriginIndex = findDarkAnimationOriginIndex(touchWakeUpScreenLocation);
-            mNeedsAnimation = true;
-        }
         requestChildrenUpdate();
-        updateWillNotDraw();
         notifyHeightChangeListener(mShelf);
     }
 
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    private void updatePanelTranslation() {
-        setTranslationX(mHorizontalPanelTranslation + mAntiBurnInOffsetX * mInterpolatedDarkAmount);
-    }
-
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setHorizontalPanelTranslation(float verticalPanelTranslation) {
-        mHorizontalPanelTranslation = verticalPanelTranslation;
-        updatePanelTranslation();
-    }
-
     /**
-     * Updates whether or not this Layout will perform its own custom drawing (i.e. whether or
-     * not {@link #onDraw(Canvas)} is called). This method should be called whenever the
-     * {@link #mAmbientState}'s dark mode is toggled.
-     */
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    private void updateWillNotDraw() {
-        boolean willDraw = mShouldDrawNotificationBackground || DEBUG;
-        setWillNotDraw(!willDraw);
-    }
-
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    private void setDarkAmount(float darkAmount) {
-        setDarkAmount(darkAmount, darkAmount);
-    }
-
-    /**
-     * Sets the current dark amount.
+     * Sets the current hide amount.
      *
-     * @param linearDarkAmount       The dark amount that follows linear interpoloation in the
+     * @param linearHideAmount       The hide amount that follows linear interpoloation in the
      *                               animation,
      *                               i.e. animates from 0 to 1 or vice-versa in a linear manner.
-     * @param interpolatedDarkAmount The dark amount that follows the actual interpolation of the
+     * @param interpolatedHideAmount The hide amount that follows the actual interpolation of the
      *                               animation curve.
      */
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setDarkAmount(float linearDarkAmount, float interpolatedDarkAmount) {
-        mLinearDarkAmount = linearDarkAmount;
-        mInterpolatedDarkAmount = interpolatedDarkAmount;
-        boolean wasFullyDark = mAmbientState.isFullyDark();
-        boolean wasDarkAtAll = mAmbientState.isDarkAtAll();
-        mAmbientState.setDarkAmount(interpolatedDarkAmount);
-        boolean nowFullyDark = mAmbientState.isFullyDark();
-        boolean nowDarkAtAll = mAmbientState.isDarkAtAll();
-        if (nowFullyDark != wasFullyDark) {
-            updateContentHeight();
-            if (nowFullyDark) {
-                updateDarkShelfVisibility();
-            }
+    public void setHideAmount(float linearHideAmount, float interpolatedHideAmount) {
+        mLinearHideAmount = linearHideAmount;
+        mInterpolatedHideAmount = interpolatedHideAmount;
+        boolean wasFullyHidden = mAmbientState.isFullyHidden();
+        boolean wasHiddenAtAll = mAmbientState.isHiddenAtAll();
+        mAmbientState.setHideAmount(interpolatedHideAmount);
+        boolean nowFullyHidden = mAmbientState.isFullyHidden();
+        boolean nowHiddenAtAll = mAmbientState.isHiddenAtAll();
+        if (nowFullyHidden != wasFullyHidden) {
+            updateVisibility();
         }
-        if (!wasDarkAtAll && nowDarkAtAll) {
+        if (!wasHiddenAtAll && nowHiddenAtAll) {
             resetExposedMenuView(true /* animate */, true /* animate */);
         }
-        if (nowFullyDark != wasFullyDark || wasDarkAtAll != nowDarkAtAll) {
+        if (nowFullyHidden != wasFullyHidden || wasHiddenAtAll != nowHiddenAtAll) {
             invalidateOutline();
         }
         updateAlgorithmHeightAndPadding();
         updateBackgroundDimming();
-        updatePanelTranslation();
         requestChildrenUpdate();
     }
 
-    private void updateDarkShelfVisibility() {
-        DozeParameters dozeParameters = DozeParameters.getInstance(mContext);
-        if (dozeParameters.shouldControlScreenOff()) {
-            mShelf.fadeInTranslating();
-        }
-        updateClipping();
+    private void updateVisibility() {
+        boolean shouldShow = !mAmbientState.isFullyHidden() || !onKeyguard();
+        setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
-    public void notifyDarkAnimationStart(boolean dark) {
-        // We only swap the scaling factor if we're fully dark or fully awake to avoid
+    public void notifyHideAnimationStart(boolean hide) {
+        // We only swap the scaling factor if we're fully hidden or fully awake to avoid
         // interpolation issues when playing with the power button.
-        if (mInterpolatedDarkAmount == 0 || mInterpolatedDarkAmount == 1) {
-            mBackgroundXFactor = dark ? 1.8f : 1.5f;
-            mDarkXInterpolator = dark
+        if (mInterpolatedHideAmount == 0 || mInterpolatedHideAmount == 1) {
+            mBackgroundXFactor = hide ? 1.8f : 1.5f;
+            mHideXInterpolator = hide
                     ? Interpolators.FAST_OUT_SLOW_IN_REVERSE
                     : Interpolators.FAST_OUT_SLOW_IN;
         }
     }
 
-    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
-    private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) {
-        if (screenLocation == null || screenLocation.y < mTopPadding) {
-            return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
-        }
-        if (screenLocation.y > getBottomMostNotificationBottom()) {
-            return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_BELOW;
-        }
-        View child = getClosestChildAtRawPosition(screenLocation.x, screenLocation.y);
-        if (child != null) {
-            return getNotGoneIndex(child);
-        } else {
-            return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
-        }
-    }
-
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private int getNotGoneIndex(View child) {
         int count = getChildCount();
@@ -5003,7 +4967,6 @@
     public void onInitializeAccessibilityEventInternal(AccessibilityEvent event) {
         super.onInitializeAccessibilityEventInternal(event);
         event.setScrollable(mScrollable);
-        event.setScrollX(mScrollX);
         event.setMaxScrollX(mScrollX);
         if (ANCHOR_SCROLLING) {
             // TODO
@@ -5057,12 +5020,14 @@
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void removeContainerView(View v) {
+        Assert.isMainThread();
         removeView(v);
     }
 
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void addContainerView(View v) {
+        Assert.isMainThread();
         addView(v);
     }
 
@@ -5071,13 +5036,6 @@
         mAnimationFinishedRunnables.add(runnable);
     }
 
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
-        mHeadsUpManager = headsUpManager;
-        mHeadsUpManager.addListener(mRoundnessManager);
-        mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
-    }
-
     public void generateHeadsUpAnimation(NotificationEntry entry, boolean isHeadsUp) {
         ExpandableNotificationRow row = entry.getHeadsUpAnimationView();
         generateHeadsUpAnimation(row, isHeadsUp);
@@ -5304,7 +5262,7 @@
         boolean publicMode = mLockscreenUserManager.isAnyProfilePublicMode();
 
         if (mHeadsUpAppearanceController != null) {
-            mHeadsUpAppearanceController.setPublicMode(publicMode);
+            mHeadsUpAppearanceController.onStateChanged();
         }
 
         SysuiStatusBarStateController state = (SysuiStatusBarStateController)
@@ -5322,6 +5280,7 @@
         onUpdateRowStates();
 
         mEntryManager.updateNotifications();
+        updateVisibility();
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5360,12 +5319,6 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setAntiBurnInOffsetX(int antiBurnInOffsetX) {
-        mAntiBurnInOffsetX = antiBurnInOffsetX;
-        updatePanelTranslation();
-    }
-
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(String.format("[%s: pulsing=%s qsCustomizerShowing=%s visibility=%s"
                         + " alpha:%f scrollY:%d maxTopPadding:%d showShelfOnly=%s"
@@ -5418,18 +5371,18 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public boolean isFullyDark() {
-        return mAmbientState.isFullyDark();
+    public boolean isFullyHidden() {
+        return mAmbientState.isFullyHidden();
     }
 
     /**
-     * Add a listener whenever the expanded height changes. The first value passed as an argument
-     * is the expanded height and the second one is the appearFraction.
+     * Add a listener whenever the expanded height changes. The first value passed as an
+     * argument is the expanded height and the second one is the appearFraction.
      *
      * @param listener the listener to notify.
      */
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void addOnExpandedHeightListener(BiConsumer<Float, Float> listener) {
+    public void addOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
         mExpandedHeightListeners.add(listener);
     }
 
@@ -5437,7 +5390,7 @@
      * Stop a listener from listening to the expandedHeight.
      */
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void removeOnExpandedHeightListener(BiConsumer<Float, Float> listener) {
+    public void removeOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
         mExpandedHeightListeners.remove(listener);
     }
 
@@ -5658,12 +5611,19 @@
      */
     public float setPulseHeight(float height) {
         mAmbientState.setPulseHeight(height);
+        if (mKeyguardBypassController.getBypassEnabled()) {
+            notifyAppearChangedListeners();
+        }
         requestChildrenUpdate();
         return Math.max(0, height - mAmbientState.getInnerHeight(true /* ignorePulseHeight */));
     }
 
+    public float getPulseHeight() {
+        return mAmbientState.getPulseHeight();
+    }
+
     /**
-     * Set the amount how much we're dozing. This is different from how dark the shade is, when
+     * Set the amount how much we're dozing. This is different from how hidden the shade is, when
      * the notification is pulsing.
      */
     public void setDozeAmount(float dozeAmount) {
@@ -5673,7 +5633,7 @@
     }
 
     public void wakeUpFromPulse() {
-        setPulseHeight(getPulseHeight());
+        setPulseHeight(getWakeUpHeight());
         // Let's place the hidden views at the end of the pulsing notification to make sure we have
         // a smooth animation
         boolean firstVisibleView = true;
@@ -5709,6 +5669,20 @@
         }
     }
 
+    public void setOnPulseHeightChangedListener(Runnable listener) {
+        mAmbientState.setOnPulseHeightChangedListener(listener);
+    }
+
+    public float calculateAppearFractionBypass() {
+        float pulseHeight = getPulseHeight();
+        float wakeUpHeight = getWakeUpHeight();
+        float dragDownAmount = pulseHeight - wakeUpHeight;
+
+        // The total distance required to fully reveal the header
+        float totalDistance = getIntrinsicPadding();
+        return MathUtils.smoothStep(0, totalDistance, dragDownAmount);
+    }
+
     /**
      * A listener that is notified when the empty space below the notifications is clicked on
      */
@@ -5762,10 +5736,10 @@
             ExpandableNotificationRow row = (ExpandableNotificationRow) view;
             currentIndex++;
             boolean beforeSpeedBump;
-            if (mLowPriorityBeforeSpeedBump) {
-                beforeSpeedBump = !row.getEntry().ambient;
-            } else {
+            if (mHighPriorityBeforeSpeedBump) {
                 beforeSpeedBump = row.getEntry().isHighPriority();
+            } else {
+                beforeSpeedBump = !row.getEntry().ambient;
             }
             if (beforeSpeedBump) {
                 speedBumpIndex = currentIndex;
@@ -5882,9 +5856,6 @@
                         .animateY()
                         .animateZ(),
 
-                // ANIMATION_TYPE_DARK
-                null, // Unused
-
                 // ANIMATION_TYPE_GO_TO_FULL_SHADE
                 new AnimationFilter()
                         .animateHeight()
@@ -5946,7 +5917,6 @@
                 // ANIMATION_TYPE_EVERYTHING
                 new AnimationFilter()
                         .animateAlpha()
-                        .animateDark()
                         .animateDimmed()
                         .animateHideSensitive()
                         .animateHeight()
@@ -5978,9 +5948,6 @@
                 // ANIMATION_TYPE_CHANGE_POSITION
                 StackStateAnimator.ANIMATION_DURATION_STANDARD,
 
-                // ANIMATION_TYPE_DARK
-                StackStateAnimator.ANIMATION_DURATION_WAKEUP,
-
                 // ANIMATION_TYPE_GO_TO_FULL_SHADE
                 StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE,
 
@@ -6016,19 +5983,15 @@
         static final int ANIMATION_TYPE_ACTIVATED_CHILD = 4;
         static final int ANIMATION_TYPE_DIMMED = 5;
         static final int ANIMATION_TYPE_CHANGE_POSITION = 6;
-        static final int ANIMATION_TYPE_DARK = 7;
-        static final int ANIMATION_TYPE_GO_TO_FULL_SHADE = 8;
-        static final int ANIMATION_TYPE_HIDE_SENSITIVE = 9;
-        static final int ANIMATION_TYPE_VIEW_RESIZE = 10;
-        static final int ANIMATION_TYPE_GROUP_EXPANSION_CHANGED = 11;
-        static final int ANIMATION_TYPE_HEADS_UP_APPEAR = 12;
-        static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR = 13;
-        static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK = 14;
-        static final int ANIMATION_TYPE_HEADS_UP_OTHER = 15;
-        static final int ANIMATION_TYPE_EVERYTHING = 16;
-
-        static final int DARK_ANIMATION_ORIGIN_INDEX_ABOVE = -1;
-        static final int DARK_ANIMATION_ORIGIN_INDEX_BELOW = -2;
+        static final int ANIMATION_TYPE_GO_TO_FULL_SHADE = 7;
+        static final int ANIMATION_TYPE_HIDE_SENSITIVE = 8;
+        static final int ANIMATION_TYPE_VIEW_RESIZE = 9;
+        static final int ANIMATION_TYPE_GROUP_EXPANSION_CHANGED = 10;
+        static final int ANIMATION_TYPE_HEADS_UP_APPEAR = 11;
+        static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR = 12;
+        static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK = 13;
+        static final int ANIMATION_TYPE_HEADS_UP_OTHER = 14;
+        static final int ANIMATION_TYPE_EVERYTHING = 15;
 
         final long eventStartTime;
         final ExpandableView mChangingView;
@@ -6036,7 +5999,6 @@
         final AnimationFilter filter;
         final long length;
         View viewAfterChangingView;
-        int darkAnimationOriginIndex;
         boolean headsUpFromBottom;
 
         AnimationEvent(ExpandableView view, int type) {
@@ -6141,6 +6103,9 @@
                         .setType(MetricsEvent.TYPE_ACTION));
                 mHeadsUpManager.setMenuShown(notificationRow.getEntry(), true);
                 mSwipeHelper.onMenuShown(row);
+                mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
+                        false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
+                        false /* resetMenu */);
 
                 // Check to see if we want to go directly to the notfication guts
                 NotificationMenuRowPlugin provider = notificationRow.getProvider();
@@ -6148,7 +6113,7 @@
                     MenuItem item = provider.menuItemToExposeOnSnap();
                     if (item != null) {
                         Point origin = provider.getRevealAnimationOrigin();
-                        mGutsManager.openGuts(row, origin.x, origin.y, item);
+                        mNotificationGutsManager.openGuts(row, origin.x, origin.y, item);
                     } else  {
                         Log.e(TAG, "Provider has shouldShowGutsOnSnapOpen, but provided no "
                                 + "menu item in menuItemtoExposeOnSnap. Skipping.");
@@ -6288,6 +6253,15 @@
             mAmbientState.onDragFinished(animView);
             updateContinuousShadowDrawing();
             updateContinuousBackgroundDrawing();
+            if (animView instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
+                if (row.isPinned() && !canChildBeDismissed(row)
+                        && row.getStatusBarNotification().getNotification().fullScreenIntent
+                                == null) {
+                    mHeadsUpManager.removeNotification(row.getStatusBarNotification().getKey(),
+                            true /* removeImmediately */);
+                }
+            }
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index 8dd324b..0968674 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -23,12 +23,12 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.service.notification.StatusBarNotification;
-import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.SwipeHelper;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -51,9 +51,11 @@
     private boolean mIsExpanded;
     private boolean mPulsing;
 
-    public NotificationSwipeHelper(int swipeDirection, NotificationCallback callback,
-            Context context, NotificationMenuRowPlugin.OnMenuEventListener menuListener) {
-        super(swipeDirection, callback, context);
+    NotificationSwipeHelper(
+            int swipeDirection, NotificationCallback callback, Context context,
+            NotificationMenuRowPlugin.OnMenuEventListener menuListener,
+            FalsingManager falsingManager) {
+        super(swipeDirection, callback, context, falsingManager);
         mMenuListener = menuListener;
         mCallback = callback;
         mFalsingCheck = new Runnable() {
@@ -313,8 +315,6 @@
     public void setTranslation(View v, float translate) {
         if (v instanceof ExpandableNotificationRow) {
             ((ExpandableNotificationRow) v).setTranslation(translate);
-        } else {
-            Log.wtf(TAG, "setTranslation should only be called on an ExpandableNotificationRow.");
         }
     }
 
@@ -324,7 +324,6 @@
             return ((ExpandableNotificationRow) v).getTranslation();
         }
         else {
-            Log.wtf(TAG, "getTranslation should only be called on an ExpandableNotificationRow.");
             return 0f;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
index e2f702d..b444fa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/SectionHeaderView.java
@@ -16,11 +16,16 @@
 
 package com.android.systemui.statusbar.notification.stack;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.RectF;
 import android.util.AttributeSet;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
 
@@ -32,9 +37,10 @@
  * notification sections. Currently only used for gentle notifications.
  */
 public class SectionHeaderView extends ActivatableNotificationView {
-    private View mContents;
+    private ViewGroup mContents;
     private TextView mLabelView;
     private ImageView mClearAllButton;
+    @Nullable private View.OnClickListener mOnClearClickListener = null;
 
     private final RectF mTmpRect = new RectF();
 
@@ -45,9 +51,16 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mContents = findViewById(R.id.content);
-        mLabelView = findViewById(R.id.header_label);
-        mClearAllButton = findViewById(R.id.btn_clear_all);
+        mContents = checkNotNull(findViewById(R.id.content));
+        bindContents();
+    }
+
+    private void bindContents() {
+        mLabelView = checkNotNull(findViewById(R.id.header_label));
+        mClearAllButton = checkNotNull(findViewById(R.id.btn_clear_all));
+        if (mOnClearClickListener != null) {
+            mClearAllButton.setOnClickListener(mOnClearClickListener);
+        }
     }
 
     @Override
@@ -55,6 +68,26 @@
         return mContents;
     }
 
+    /**
+     * Destroys and reinflates the visible contents of the section header. For use on configuration
+     * changes or any other time that layout values might need to be re-evaluated.
+     *
+     * Does not reinflate the base content view itself ({@link #getContentView()} or any of the
+     * decorator views, such as the background view or shadow view.
+     */
+    void reinflateContents() {
+        mContents.removeAllViews();
+        LayoutInflater.from(getContext()).inflate(
+                R.layout.status_bar_notification_section_header_contents,
+                mContents);
+        bindContents();
+    }
+
+    @Override
+    public boolean isTransparent() {
+        return true;
+    }
+
     /** Must be called whenever the UI mode changes (i.e. when we enter night mode). */
     void onUiModeChanged() {
         updateBackgroundColors();
@@ -88,6 +121,7 @@
 
     /** Fired when the user clicks on the "X" button on the far right of the header. */
     void setOnClearAllClickListener(View.OnClickListener listener) {
+        mOnClearClickListener = listener;
         mClearAllButton.setOnClickListener(listener);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 2980ee4..7655056 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -159,15 +159,13 @@
         float drawStart = !ambientState.isOnKeyguard() ? ambientState.getTopPadding()
                 + ambientState.getStackTranslation() + ambientState.getExpandAnimationTopChange()
                 : 0;
-        float previousNotificationEnd = 0;
-        float previousNotificationStart = 0;
+        float clipStart = 0;
         int childCount = algorithmState.visibleChildren.size();
         for (int i = 0; i < childCount; i++) {
             ExpandableView child = algorithmState.visibleChildren.get(i);
             ExpandableViewState state = child.getViewState();
             if (!child.mustStayOnScreen() || state.headsUpIsVisible) {
-                previousNotificationEnd = Math.max(drawStart, previousNotificationEnd);
-                previousNotificationStart = Math.max(drawStart, previousNotificationStart);
+                clipStart = Math.max(drawStart, clipStart);
             }
             float newYTranslation = state.yTranslation;
             float newHeight = state.height;
@@ -175,10 +173,10 @@
             boolean isHeadsUp = (child instanceof ExpandableNotificationRow)
                     && ((ExpandableNotificationRow) child).isPinned();
             if (mClipNotificationScrollToTop
-                    && !state.inShelf && newYTranslation < previousNotificationEnd
-                    && (!isHeadsUp || ambientState.isShadeExpanded())) {
+                    && (!state.inShelf || isHeadsUp)
+                    && newYTranslation < clipStart) {
                 // The previous view is overlapping on top, clip!
-                float overlapAmount = previousNotificationEnd - newYTranslation;
+                float overlapAmount = clipStart - newYTranslation;
                 state.clipTopAmount = (int) overlapAmount;
             } else {
                 state.clipTopAmount = 0;
@@ -187,8 +185,7 @@
             if (!child.isTransparent()) {
                 // Only update the previous values if we are not transparent,
                 // otherwise we would clip to a transparent view.
-                previousNotificationEnd = newNotificationEnd;
-                previousNotificationStart = newYTranslation;
+                clipStart = Math.max(clipStart, isHeadsUp ? newYTranslation : newNotificationEnd);
             }
         }
     }
@@ -213,7 +210,6 @@
     private void updateDimmedActivatedHideSensitive(AmbientState ambientState,
             StackScrollAlgorithmState algorithmState) {
         boolean dimmed = ambientState.isDimmed();
-        boolean dark = ambientState.isFullyDark();
         boolean hideSensitive = ambientState.isHideSensitive();
         View activatedChild = ambientState.getActivatedChild();
         int childCount = algorithmState.visibleChildren.size();
@@ -221,7 +217,6 @@
             ExpandableView child = algorithmState.visibleChildren.get(i);
             ExpandableViewState childViewState = child.getViewState();
             childViewState.dimmed = dimmed;
-            childViewState.dark = dark;
             childViewState.hideSensitive = hideSensitive;
             boolean isActivatedChild = activatedChild == child;
             if (dimmed && isActivatedChild) {
@@ -501,7 +496,7 @@
                 continue;
             }
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
-            if (!row.showingAmbientPulsing() || (i == 0 && ambientState.isPulseExpanding())) {
+            if (!row.showingPulsing() || (i == 0 && ambientState.isPulseExpanding())) {
                 continue;
             }
             ExpandableViewState viewState = row.getViewState();
@@ -516,11 +511,11 @@
         for (int i = 0; i < childCount; i++) {
             View child = algorithmState.visibleChildren.get(i);
             if (!(child instanceof ExpandableNotificationRow)) {
-                break;
+                continue;
             }
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
             if (!row.isHeadsUp()) {
-                break;
+                continue;
             }
             ExpandableViewState childState = row.getViewState();
             if (topHeadsUpEntry == null && row.mustStayOnScreen() && !childState.headsUpIsVisible) {
@@ -530,7 +525,8 @@
             boolean isTopEntry = topHeadsUpEntry == row;
             float unmodifiedEndLocation = childState.yTranslation + childState.height;
             if (mIsExpanded) {
-                if (row.mustStayOnScreen() && !childState.headsUpIsVisible) {
+                if (row.mustStayOnScreen() && !childState.headsUpIsVisible
+                        && !row.showingPulsing()) {
                     // Ensure that the heads up is always visible even when scrolled off
                     clampHunToTop(ambientState, row, childState);
                     if (i == 0 && row.isAboveShelf()) {
@@ -547,12 +543,12 @@
                 ExpandableViewState topState =
                         topHeadsUpEntry == null ? null : topHeadsUpEntry.getViewState();
                 if (topState != null && !isTopEntry && (!mIsExpanded
-                        || unmodifiedEndLocation < topState.yTranslation + topState.height)) {
+                        || unmodifiedEndLocation > topState.yTranslation + topState.height)) {
                     // Ensure that a headsUp doesn't vertically extend further than the heads-up at
                     // the top most z-position
                     childState.height = row.getIntrinsicHeight();
-                    childState.yTranslation = topState.yTranslation + topState.height
-                            - childState.height;
+                    childState.yTranslation = Math.min(topState.yTranslation + topState.height
+                            - childState.height, childState.yTranslation);
                 }
 
                 // heads up notification show and this row is the top entry of heads up
@@ -667,7 +663,7 @@
             }
             childViewState.zTranslation = baseZ
                     + childrenOnTop * zDistanceBetweenElements;
-        } else if (i == 0 && child.isAboveShelf()) {
+        } else if (i == 0 && (child.isAboveShelf() || child.showingPulsing())) {
             // In case this is a new view that has never been measured before, we don't want to
             // elevate if we are currently expanded more then the notification
             int shelfHeight = ambientState.getShelf() == null ? 0 :
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index 7332b03..0996ff2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -28,6 +28,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 
@@ -61,6 +62,7 @@
     public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
     public static final int ANIMATION_DELAY_HEADS_UP = 120;
     public static final int ANIMATION_DELAY_HEADS_UP_CLICKED= 120;
+    private static final int MAX_STAGGER_COUNT = 5;
 
     private final int mGoToFullShadeAppearingTranslation;
     private final int mPulsingAppearingTranslation;
@@ -78,8 +80,6 @@
     private long mCurrentLength;
     private long mCurrentAdditionalDelay;
 
-    /** The current index for the last child which was not added in this event set. */
-    private int mCurrentLastNotAddedIndex;
     private ValueAnimator mTopOverScrollAnimator;
     private ValueAnimator mBottomOverScrollAnimator;
     private int mHeadsUpAppearHeightBottom;
@@ -137,7 +137,8 @@
         mAnimationFilter.applyCombination(mNewEvents);
         mCurrentAdditionalDelay = additionalDelay;
         mCurrentLength = NotificationStackScrollLayout.AnimationEvent.combineLength(mNewEvents);
-        mCurrentLastNotAddedIndex = findLastNotAddedIndex();
+        // Used to stagger concurrent animations' delays and durations for visual effect
+        int animationStaggerCount = 0;
         for (int i = 0; i < childCount; i++) {
             final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
 
@@ -147,7 +148,10 @@
                 continue;
             }
 
-            initAnimationProperties(child, viewState);
+            if (mAnimationProperties.wasAdded(child) && animationStaggerCount < MAX_STAGGER_COUNT) {
+                animationStaggerCount++;
+            }
+            initAnimationProperties(child, viewState, animationStaggerCount);
             viewState.animateTo(child, mAnimationProperties);
         }
         if (!isRunning()) {
@@ -161,29 +165,27 @@
     }
 
     private void initAnimationProperties(ExpandableView child,
-            ExpandableViewState viewState) {
+            ExpandableViewState viewState, int animationStaggerCount) {
         boolean wasAdded = mAnimationProperties.wasAdded(child);
         mAnimationProperties.duration = mCurrentLength;
-        adaptDurationWhenGoingToFullShade(child, viewState, wasAdded);
+        adaptDurationWhenGoingToFullShade(child, viewState, wasAdded, animationStaggerCount);
         mAnimationProperties.delay = 0;
         if (wasAdded || mAnimationFilter.hasDelays
                         && (viewState.yTranslation != child.getTranslationY()
                         || viewState.zTranslation != child.getTranslationZ()
                         || viewState.alpha != child.getAlpha()
                         || viewState.height != child.getActualHeight()
-                        || viewState.clipTopAmount != child.getClipTopAmount()
-                        || viewState.dark != child.isDark())) {
+                        || viewState.clipTopAmount != child.getClipTopAmount())) {
             mAnimationProperties.delay = mCurrentAdditionalDelay
-                    + calculateChildAnimationDelay(viewState);
+                    + calculateChildAnimationDelay(viewState, animationStaggerCount);
         }
     }
 
     private void adaptDurationWhenGoingToFullShade(ExpandableView child,
-            ExpandableViewState viewState, boolean wasAdded) {
+            ExpandableViewState viewState, boolean wasAdded, int animationStaggerCount) {
         if (wasAdded && mAnimationFilter.hasGoToFullShadeEvent) {
             child.setTranslationY(child.getTranslationY() + mGoToFullShadeAppearingTranslation);
-            float longerDurationFactor = viewState.notGoneIndex - mCurrentLastNotAddedIndex;
-            longerDurationFactor = (float) Math.pow(longerDurationFactor, 0.7f);
+            float longerDurationFactor = (float) Math.pow(animationStaggerCount, 0.7f);
             mAnimationProperties.duration = ANIMATION_DURATION_APPEAR_DISAPPEAR + 50 +
                     (long) (100 * longerDurationFactor);
         }
@@ -214,25 +216,10 @@
         return true;
     }
 
-    private int findLastNotAddedIndex() {
-        int childCount = mHostLayout.getChildCount();
-        for (int i = childCount - 1; i >= 0; i--) {
-            final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
-
-            ExpandableViewState viewState = child.getViewState();
-            if (viewState == null || child.getVisibility() == View.GONE) {
-                continue;
-            }
-            if (!mNewAddChildren.contains(child)) {
-                return viewState.notGoneIndex;
-            }
-        }
-        return -1;
-    }
-
-    private long calculateChildAnimationDelay(ExpandableViewState viewState) {
+    private long calculateChildAnimationDelay(ExpandableViewState viewState,
+            int animationStaggerCount) {
         if (mAnimationFilter.hasGoToFullShadeEvent) {
-            return calculateDelayGoToFullShade(viewState);
+            return calculateDelayGoToFullShade(viewState, animationStaggerCount);
         }
         if (mAnimationFilter.customDelay != AnimationFilter.NO_DELAY) {
             return mAnimationFilter.customDelay;
@@ -286,13 +273,13 @@
         return minDelay;
     }
 
-    private long calculateDelayGoToFullShade(ExpandableViewState viewState) {
+    private long calculateDelayGoToFullShade(ExpandableViewState viewState,
+            int animationStaggerCount) {
         int shelfIndex = mShelf.getNotGoneIndex();
         float index = viewState.notGoneIndex;
         long result = 0;
         if (index > shelfIndex) {
-            float diff = index - shelfIndex;
-            diff = (float) Math.pow(diff, 0.7f);
+            float diff = (float) Math.pow(animationStaggerCount, 0.7f);
             result += (long) (diff * ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE * 0.25);
             index = shelfIndex;
         }
@@ -465,7 +452,11 @@
                     if (row.isDismissed()) {
                         needsAnimation = false;
                     }
-                    StatusBarIconView icon = row.getEntry().icon;
+                    NotificationEntry entry = row.getEntry();
+                    StatusBarIconView icon = entry.icon;
+                    if (entry.centeredIcon != null && entry.centeredIcon.getParent() != null) {
+                        icon = entry.centeredIcon;
+                    }
                     if (icon.getParent() != null) {
                         icon.getLocationOnScreen(mTmpLocation);
                         float iconPosition = mTmpLocation[0] - icon.getTranslationX()
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 d677952..94cd2cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.hardware.biometrics.BiometricSourceType;
 import android.metrics.LogMaker;
@@ -39,6 +40,8 @@
 import com.android.systemui.statusbar.NotificationMediaManager;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * Controller which coordinates all the biometric unlocking actions with the UI.
@@ -50,6 +53,20 @@
     private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
     private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock wakelock";
 
+    @IntDef(prefix = { "MODE_" }, value = {
+            MODE_NONE,
+            MODE_WAKE_AND_UNLOCK,
+            MODE_WAKE_AND_UNLOCK_PULSING,
+            MODE_SHOW_BOUNCER,
+            MODE_ONLY_WAKE,
+            MODE_UNLOCK_COLLAPSING,
+            MODE_UNLOCK_FADING,
+            MODE_DISMISS_BOUNCER,
+            MODE_WAKE_AND_UNLOCK_FROM_DREAM
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WakeAndUnlockMode {}
+
     /**
      * Mode in which we don't need to wake up the device when we authenticate.
      */
@@ -81,18 +98,23 @@
     /**
      * Mode in which fingerprint unlocks the device.
      */
-    public static final int MODE_UNLOCK = 5;
-
-    /**
-     * Mode in which fingerprint brings up the bouncer because fingerprint unlocking is currently
-     * not allowed.
-     */
-    public static final int MODE_DISMISS_BOUNCER = 6;
+    public static final int MODE_UNLOCK_COLLAPSING = 5;
 
     /**
      * Mode in which fingerprint wakes and unlocks the device from a dream.
      */
-    public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 7;
+    public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 6;
+
+    /**
+     * Faster mode of dismissing the lock screen when we cross fade to an app
+     * (used for keyguard bypass.)
+     */
+    public static final int MODE_UNLOCK_FADING = 7;
+
+    /**
+     * When bouncer is visible and will be dismissed.
+     */
+    public static final int MODE_DISMISS_BOUNCER = 8;
 
     /**
      * How much faster we collapse the lockscreen when authenticating with biometric.
@@ -119,6 +141,7 @@
     private BiometricSourceType mPendingAuthenticatedBioSourceType = null;
     private boolean mPendingShowBouncer;
     private boolean mHasScreenTurnedOnSinceAuthenticating;
+    private boolean mFadedAwayAfterWakeAndUnlock;
 
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
 
@@ -163,6 +186,7 @@
         mHandler = handler;
         mWakeUpDelay = wakeUpDelay;
         mKeyguardBypassController = keyguardBypassController;
+        mKeyguardBypassController.setUnlockController(this);
     }
 
     public void setStatusBarKeyguardViewManager(
@@ -234,11 +258,21 @@
         }
         mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
                 .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
+        boolean unlockAllowed = mKeyguardBypassController.onBiometricAuthenticated(
+                biometricSourceType);
+        if (unlockAllowed) {
+            mKeyguardViewMediator.userActivity();
+            startWakeAndUnlock(biometricSourceType);
+        } else {
+            Log.d(TAG, "onBiometricAuthenticated aborted by bypass controller");
+        }
+    }
+
+    public void startWakeAndUnlock(BiometricSourceType biometricSourceType) {
         startWakeAndUnlock(calculateMode(biometricSourceType));
     }
 
-    public void startWakeAndUnlock(int mode) {
-        // TODO(b/62444020): remove when this bug is fixed
+    public void startWakeAndUnlock(@WakeAndUnlockMode int mode) {
         Log.v(TAG, "startWakeAndUnlock(" + mode + ")");
         boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
         mMode = mode;
@@ -275,14 +309,15 @@
         }
         switch (mMode) {
             case MODE_DISMISS_BOUNCER:
-                Trace.beginSection("MODE_DISMISS");
+            case MODE_UNLOCK_FADING:
+                Trace.beginSection("MODE_DISMISS_BOUNCER or MODE_UNLOCK_FADING");
                 mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
                         false /* strongAuth */);
                 Trace.endSection();
                 break;
-            case MODE_UNLOCK:
+            case MODE_UNLOCK_COLLAPSING:
             case MODE_SHOW_BOUNCER:
-                Trace.beginSection("MODE_UNLOCK or MODE_SHOW_BOUNCER");
+                Trace.beginSection("MODE_UNLOCK_COLLAPSING or MODE_SHOW_BOUNCER");
                 if (!wasDeviceInteractive) {
                     mPendingShowBouncer = true;
                 } else {
@@ -334,6 +369,7 @@
     @Override
     public void onStartedGoingToSleep(int why) {
         resetMode();
+        mFadedAwayAfterWakeAndUnlock = false;
         mPendingAuthenticatedUserId = -1;
         mPendingAuthenticatedBioSourceType = null;
     }
@@ -362,33 +398,38 @@
         return mMode;
     }
 
-    private int calculateMode(BiometricSourceType biometricSourceType) {
+    private @WakeAndUnlockMode int calculateMode(BiometricSourceType biometricSourceType) {
+        if (biometricSourceType == BiometricSourceType.FACE
+                || biometricSourceType == BiometricSourceType.IRIS) {
+            return calculateModeForPassiveAuth();
+        } else {
+            return calculateModeForFingerprint();
+        }
+    }
+
+    private @WakeAndUnlockMode int calculateModeForFingerprint() {
         boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithBiometricAllowed();
         boolean deviceDreaming = mUpdateMonitor.isDreaming();
-        boolean faceStayingOnKeyguard = biometricSourceType == BiometricSourceType.FACE
-                && !mKeyguardBypassController.getBypassEnabled();
 
         if (!mUpdateMonitor.isDeviceInteractive()) {
             if (!mStatusBarKeyguardViewManager.isShowing()) {
                 return MODE_ONLY_WAKE;
             } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
-                return faceStayingOnKeyguard ? MODE_NONE : MODE_WAKE_AND_UNLOCK_PULSING;
+                return MODE_WAKE_AND_UNLOCK_PULSING;
             } else if (unlockingAllowed || !mUnlockMethodCache.isMethodSecure()) {
                 return MODE_WAKE_AND_UNLOCK;
             } else {
                 return MODE_SHOW_BOUNCER;
             }
         }
-        if (unlockingAllowed && deviceDreaming && !faceStayingOnKeyguard) {
+        if (unlockingAllowed && deviceDreaming) {
             return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
         }
         if (mStatusBarKeyguardViewManager.isShowing()) {
-            if ((mStatusBarKeyguardViewManager.isBouncerShowing()
-                    || mStatusBarKeyguardViewManager.isBouncerPartiallyVisible())
-                    && unlockingAllowed) {
+            if (mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing() && unlockingAllowed) {
                 return MODE_DISMISS_BOUNCER;
             } else if (unlockingAllowed) {
-                return faceStayingOnKeyguard ? MODE_ONLY_WAKE : MODE_UNLOCK;
+                return MODE_UNLOCK_COLLAPSING;
             } else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
                 return MODE_SHOW_BOUNCER;
             }
@@ -396,6 +437,52 @@
         return MODE_NONE;
     }
 
+    private @WakeAndUnlockMode int calculateModeForPassiveAuth() {
+        boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithBiometricAllowed();
+        boolean deviceDreaming = mUpdateMonitor.isDreaming();
+        boolean bypass = mKeyguardBypassController.getBypassEnabled();
+
+        if (!mUpdateMonitor.isDeviceInteractive()) {
+            if (!mStatusBarKeyguardViewManager.isShowing()) {
+                return bypass ? MODE_WAKE_AND_UNLOCK : MODE_ONLY_WAKE;
+            } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
+                // Let's not wake-up to lock screen when not bypassing, otherwise the notification
+                // would move as the user tried to tap it.
+                return bypass ? MODE_WAKE_AND_UNLOCK_PULSING : MODE_NONE;
+            } else {
+                if (!(mDozeScrimController.isPulsing() && !unlockingAllowed)) {
+                    Log.wtf(TAG, "Face somehow arrived when the device was not interactive");
+                }
+                if (bypass) {
+                    // Wake-up fading out nicely
+                    return MODE_WAKE_AND_UNLOCK_PULSING;
+                } else {
+                    // We could theoretically return MODE_NONE, but this means that the device
+                    // would be not interactive, unlocked, and the user would not see the device
+                    // state.
+                    return MODE_ONLY_WAKE;
+                }
+            }
+        }
+        if (unlockingAllowed && deviceDreaming) {
+            return bypass ? MODE_WAKE_AND_UNLOCK_FROM_DREAM : MODE_ONLY_WAKE;
+        }
+        if (mStatusBarKeyguardViewManager.isShowing()) {
+            if (mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing() && unlockingAllowed) {
+                if (bypass && mKeyguardBypassController.canPlaySubtleWindowAnimations()) {
+                    return MODE_UNLOCK_FADING;
+                } else {
+                    return MODE_DISMISS_BOUNCER;
+                }
+            } else if (unlockingAllowed) {
+                return bypass ? MODE_UNLOCK_FADING : MODE_NONE;
+            } else {
+                return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
+            }
+        }
+        return MODE_NONE;
+    }
+
     @Override
     public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
         mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
@@ -428,6 +515,9 @@
     }
 
     public void finishKeyguardFadingAway() {
+        if (isWakeAndUnlock()) {
+            mFadedAwayAfterWakeAndUnlock = true;
+        }
         resetMode();
     }
 
@@ -478,11 +568,26 @@
     }
 
     /**
+     * Successful authentication with fingerprint, face, or iris that wakes up the device.
+     * This will return {@code true} even after the keyguard fades away.
+     */
+    public boolean unlockedByWakeAndUnlock() {
+        return  isWakeAndUnlock() || mFadedAwayAfterWakeAndUnlock;
+    }
+
+    /**
      * Successful authentication with fingerprint, face, or iris when the screen was either
      * on or off.
      */
     public boolean isBiometricUnlock() {
-        return isWakeAndUnlock() || mMode == MODE_UNLOCK;
+        return isWakeAndUnlock() || mMode == MODE_UNLOCK_COLLAPSING || mMode == MODE_UNLOCK_FADING;
+    }
+
+    /**
+     * Successful authentication with fingerprint, face, or iris when the lockscreen fades away
+     */
+    public boolean isUnlockFading() {
+        return mMode == MODE_UNLOCK_FADING;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 58f457e..d655b2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -35,6 +35,7 @@
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
 import com.android.systemui.statusbar.policy.EncryptionHelper;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -201,20 +202,21 @@
     }
 
     protected int adjustDisableFlags(int state) {
+        boolean headsUpVisible = mStatusBarComponent.headsUpShouldBeVisible();
+        if (headsUpVisible) {
+            state |= DISABLE_CLOCK;
+        }
+
         if (!mKeyguardMonitor.isLaunchTransitionFadingAway()
                 && !mKeyguardMonitor.isKeyguardFadingAway()
-                && shouldHideNotificationIcons()) {
+                && shouldHideNotificationIcons()
+                && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+                        && headsUpVisible)) {
             state |= DISABLE_NOTIFICATION_ICONS;
             state |= DISABLE_SYSTEM_INFO;
             state |= DISABLE_CLOCK;
         }
 
-        // In landscape, the heads up show but shouldHideNotificationIcons() return false
-        // because the visual icon is in notification icon area rather than heads up's space.
-        // whether the notification icon show or not, clock should hide when heads up show.
-        if (mStatusBarComponent.isHeadsUpShouldBeVisible()) {
-            state |= DISABLE_CLOCK;
-        }
 
         if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
             if (mNetworkController.hasEmergencyCryptKeeperText()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index a17e042..10b48e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -22,9 +22,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.MathUtils;
-import android.util.SparseBooleanArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dependency;
@@ -35,15 +33,17 @@
 
 import java.io.PrintWriter;
 
-public class DozeParameters implements TunerService.Tunable {
+/**
+ * Retrieve doze information
+ */
+public class DozeParameters implements TunerService.Tunable,
+        com.android.systemui.plugins.statusbar.DozeParameters {
     private static final int MAX_DURATION = 60 * 1000;
-    public static final String DOZE_SENSORS_WAKE_UP_FULLY = "doze_sensors_wake_up_fully";
     public static final boolean FORCE_NO_BLANKING =
             SystemProperties.getBoolean("debug.force_no_blanking", false);
     public static final boolean FORCE_BLANKING =
             SystemProperties.getBoolean("debug.force_blanking", false);
 
-    private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
     private static DozeParameters sInstance;
 
     private final Context mContext;
@@ -88,20 +88,6 @@
         pw.print("    getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
         pw.print("    getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
         pw.print("    getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
-        pw.print("    getPickupSubtypePerformsProxCheck(): ");pw.println(
-                dumpPickupSubtypePerformsProxCheck());
-    }
-
-    private String dumpPickupSubtypePerformsProxCheck() {
-        // Refresh sPickupSubtypePerformsProxMatcher
-        getPickupSubtypePerformsProxCheck(0);
-
-        if (sPickupSubtypePerformsProxMatcher == null) {
-            return "fallback: " + mContext.getResources().getBoolean(
-                    R.bool.doze_pickup_performs_proximity_check);
-        } else {
-            return "spec: " + sPickupSubtypePerformsProxMatcher.mSpec;
-        }
     }
 
     public boolean getDisplayStateSupported() {
@@ -221,21 +207,8 @@
         return SystemProperties.get(propName, mContext.getString(resId));
     }
 
-    public boolean getPickupSubtypePerformsProxCheck(int subType) {
-        String spec = getString("doze.pickup.proxcheck",
-                R.string.doze_pickup_subtype_performs_proximity_check);
-
-        if (TextUtils.isEmpty(spec)) {
-            // Fall back to non-subtype based property.
-            return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check);
-        }
-
-        if (sPickupSubtypePerformsProxMatcher == null
-                || !TextUtils.equals(spec, sPickupSubtypePerformsProxMatcher.mSpec)) {
-            sPickupSubtypePerformsProxMatcher = new IntInOutMatcher(spec);
-        }
-
-        return sPickupSubtypePerformsProxMatcher.isIn(subType);
+    public boolean getPickupPerformsProxCheck() {
+        return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check);
     }
 
     public int getPulseVisibleDurationExtended() {
@@ -254,81 +227,4 @@
     public AlwaysOnDisplayPolicy getPolicy() {
         return mAlwaysOnPolicy;
     }
-
-    /**
-     * Parses a spec of the form `1,2,3,!5,*`. The resulting object will match numbers that are
-     * listed, will not match numbers that are listed with a ! prefix, and will match / not match
-     * unlisted numbers depending on whether * or !* is present.
-     *
-     * *  -> match any numbers that are not explicitly listed
-     * !* -> don't match any numbers that are not explicitly listed
-     * 2  -> match 2
-     * !3 -> don't match 3
-     *
-     * It is illegal to specify:
-     * - an empty spec
-     * - a spec containing that are empty, or a lone !
-     * - a spec for anything other than numbers or *
-     * - multiple terms for the same number / multiple *s
-     */
-    public static class IntInOutMatcher {
-        private static final String WILDCARD = "*";
-        private static final char OUT_PREFIX = '!';
-
-        private final SparseBooleanArray mIsIn;
-        private final boolean mDefaultIsIn;
-        final String mSpec;
-
-        public IntInOutMatcher(String spec) {
-            if (TextUtils.isEmpty(spec)) {
-                throw new IllegalArgumentException("Spec must not be empty");
-            }
-
-            boolean defaultIsIn = false;
-            boolean foundWildcard = false;
-
-            mSpec = spec;
-            mIsIn = new SparseBooleanArray();
-
-            for (String itemPrefixed : spec.split(",", -1)) {
-                if (itemPrefixed.length() == 0) {
-                    throw new IllegalArgumentException(
-                            "Illegal spec, must not have zero-length items: `" + spec + "`");
-                }
-                boolean isIn = itemPrefixed.charAt(0) != OUT_PREFIX;
-                String item = isIn ? itemPrefixed : itemPrefixed.substring(1);
-
-                if (itemPrefixed.length() == 0) {
-                    throw new IllegalArgumentException(
-                            "Illegal spec, must not have zero-length items: `" + spec + "`");
-                }
-
-                if (WILDCARD.equals(item)) {
-                    if (foundWildcard) {
-                        throw new IllegalArgumentException("Illegal spec, `" + WILDCARD +
-                                "` must not appear multiple times in `" + spec + "`");
-                    }
-                    defaultIsIn = isIn;
-                    foundWildcard = true;
-                } else {
-                    int key = Integer.parseInt(item);
-                    if (mIsIn.indexOfKey(key) >= 0) {
-                        throw new IllegalArgumentException("Illegal spec, `" + key +
-                                "` must not appear multiple times in `" + spec + "`");
-                    }
-                    mIsIn.put(key, isIn);
-                }
-            }
-
-            if (!foundWildcard) {
-                throw new IllegalArgumentException("Illegal spec, must specify either * or !*");
-            }
-
-            mDefaultIsIn = defaultIsIn;
-        }
-
-        public boolean isIn(int value) {
-            return (mIsIn.get(value, mDefaultIsIn));
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index d9d74b9..60e381a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -84,6 +84,14 @@
         public void onCancelled() {
             pulseFinished();
         }
+
+        /**
+         * Whether to timeout wallpaper or not.
+         */
+        @Override
+        public boolean shouldTimeoutWallpaper() {
+            return mPulseReason == DozeLog.PULSE_REASON_DOCKING;
+        }
     };
 
     public DozeScrimController(DozeParameters dozeParameters) {
@@ -141,6 +149,14 @@
         mHandler.removeCallbacks(mPulseOut);
     }
 
+    /**
+     * When pulsing, cancel any timeouts that would take you out of the pulsing state.
+     */
+    public void cancelPendingPulseTimeout() {
+        mHandler.removeCallbacks(mPulseOut);
+        mHandler.removeCallbacks(mPulseOutExtended);
+    }
+
     private void cancelPulsing() {
         if (mPulseCallback != null) {
             if (DEBUG) Log.d(TAG, "Cancel pulsing");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
index 05a86fa..f9cdde8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -57,6 +57,7 @@
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
+import java.io.PrintWriter;
 import java.util.concurrent.Executor;
 
 /**
@@ -65,6 +66,7 @@
 public class EdgeBackGestureHandler implements DisplayListener {
 
     private static final String TAG = "EdgeBackGestureHandler";
+    private static final int MAX_LONG_PRESS_TIMEOUT = 250;
 
     private final IPinnedStackListener.Stub mImeChangedListener = new IPinnedStackListener.Stub() {
         @Override
@@ -118,7 +120,7 @@
 
     private final Region mExcludeRegion = new Region();
     // The edge width where touch down is allowed
-    private final int mEdgeWidth;
+    private int mEdgeWidth;
     // The slop to distinguish between horizontal and vertical motion
     private final float mTouchSlop;
     // Duration after which we consider the event as longpress.
@@ -152,6 +154,8 @@
     private WindowManager.LayoutParams mEdgePanelLp;
     private final Rect mSamplingRect = new Rect();
     private RegionSamplingHelper mRegionSamplingHelper;
+    private int mLeftInset;
+    private int mRightInset;
 
     public EdgeBackGestureHandler(Context context, OverviewProxyService overviewProxyService) {
         final Resources res = context.getResources();
@@ -161,19 +165,22 @@
         mWm = context.getSystemService(WindowManager.class);
         mOverviewProxyService = overviewProxyService;
 
-        // TODO: Get this for the current user
-        mEdgeWidth = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.config_backGestureInset);
-
         // Reduce the default touch slop to ensure that we can intercept the gesture
         // before the app starts to react to it.
         // TODO(b/130352502) Tune this value and extract into a constant
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 0.75f;
-        mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
+        mLongPressTimeout = Math.min(MAX_LONG_PRESS_TIMEOUT,
+                ViewConfiguration.getLongPressTimeout());
 
         mNavBarHeight = res.getDimensionPixelSize(R.dimen.navigation_bar_frame_height);
         mMinArrowPosition = res.getDimensionPixelSize(R.dimen.navigation_edge_arrow_min_y);
         mFingerOffset = res.getDimensionPixelSize(R.dimen.navigation_edge_finger_offset);
+        updateCurrentUserResources(res);
+    }
+
+    public void updateCurrentUserResources(Resources res) {
+        mEdgeWidth = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.config_backGestureInset);
     }
 
     /**
@@ -192,9 +199,10 @@
         updateIsEnabled();
     }
 
-    public void onNavigationModeChanged(int mode) {
+    public void onNavigationModeChanged(int mode, Context currentUserContext) {
         mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mode);
         updateIsEnabled();
+        updateCurrentUserResources(currentUserContext.getResources());
     }
 
     private void disposeInputChannel() {
@@ -268,6 +276,8 @@
                             | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                             | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                     PixelFormat.TRANSLUCENT);
+            mEdgePanelLp.privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
             mEdgePanelLp.setTitle(TAG + mDisplayId);
             mEdgePanelLp.accessibilityTitle = mContext.getString(R.string.nav_bar_edge_panel);
             mEdgePanelLp.windowAnimations = 0;
@@ -299,7 +309,7 @@
             return false;
         }
 
-        if (x > mEdgeWidth && x < (mDisplaySize.x - mEdgeWidth)) {
+        if (x > mEdgeWidth + mLeftInset && x < (mDisplaySize.x - mEdgeWidth - mRightInset)) {
             return false;
         }
         boolean isInExcludedRegion = mExcludeRegion.contains(x, y);
@@ -325,7 +335,7 @@
             // Verify if this is in within the touch region and we aren't in immersive mode, and
             // either the bouncer is showing or the notification panel is hidden
             int stateFlags = mOverviewProxyService.getSystemUiStateFlags();
-            mIsOnLeftEdge = ev.getX() <= mEdgeWidth;
+            mIsOnLeftEdge = ev.getX() <= mEdgeWidth + mLeftInset;
             mAllowGesture = !QuickStepContract.isBackGestureDisabled(stateFlags)
                     && isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
             if (mAllowGesture) {
@@ -400,7 +410,7 @@
 
     private void updateSamplingRect() {
         int top = mEdgePanelLp.y;
-        int left = mIsOnLeftEdge ? 0 : mDisplaySize.x - mEdgePanelLp.width;
+        int left = mIsOnLeftEdge ? mLeftInset : mDisplaySize.x - mRightInset - mEdgePanelLp.width;
         int right = left + mEdgePanelLp.width;
         int bottom = top + mEdgePanelLp.height;
         mSamplingRect.set(left, top, right, bottom);
@@ -442,6 +452,21 @@
         InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
     }
 
+    public void setInsets(int leftInset, int rightInset) {
+        mLeftInset = leftInset;
+        mRightInset = rightInset;
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("EdgeBackGestureHandler:");
+        pw.println("  mIsEnabled=" + mIsEnabled);
+        pw.println("  mAllowGesture=" + mAllowGesture);
+        pw.println("  mExcludeRegion=" + mExcludeRegion);
+        pw.println("  mImeHeight=" + mImeHeight);
+        pw.println("  mIsAttached=" + mIsAttached);
+        pw.println("  mEdgeWidth=" + mEdgeWidth);
+    }
+
     class SysUiInputEventReceiver extends InputEventReceiver {
         SysUiInputEventReceiver(InputChannel channel, Looper looper) {
             super(channel, looper);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
index a4965ba..deb314b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
@@ -16,8 +16,10 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.ColorInt;
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
@@ -26,6 +28,7 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 import com.android.systemui.statusbar.policy.KeyButtonView;
@@ -33,6 +36,8 @@
 /** Containing logic for the rotation button on the physical left bottom corner of the screen. */
 public class FloatingRotationButton implements RotationButton {
 
+    private static final float BACKGROUND_ALPHA = 0.92f;
+
     private final Context mContext;
     private final WindowManager mWindowManager;
     private final KeyButtonView mKeyButtonView;
@@ -73,8 +78,7 @@
             return false;
         }
         mIsShowing = true;
-        int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+        int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(mDiameter, mDiameter,
                 mMargin, mMargin, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags,
                 PixelFormat.TRANSLUCENT);
@@ -111,7 +115,6 @@
             return false;
         }
         mWindowManager.removeViewImmediate(mKeyButtonView);
-        mRotationButtonController.cleanUp();
         mIsShowing = false;
         return true;
     }
@@ -137,10 +140,7 @@
 
     @Override
     public void setOnClickListener(View.OnClickListener onClickListener) {
-        mKeyButtonView.setOnClickListener(view -> {
-            hide();
-            onClickListener.onClick(view);
-        });
+        mKeyButtonView.setOnClickListener(onClickListener);
     }
 
     @Override
@@ -152,8 +152,18 @@
     public KeyButtonDrawable getImageDrawable() {
         Context context = new ContextThemeWrapper(mContext.getApplicationContext(),
                 mRotationButtonController.getStyleRes());
-        return KeyButtonDrawable.create(context, R.drawable.ic_sysbar_rotate_button,
-                false /* shadow */, true /* hasOvalBg */);
+        final int dualToneDarkTheme = Utils.getThemeAttr(context, R.attr.darkIconTheme);
+        final int dualToneLightTheme = Utils.getThemeAttr(context, R.attr.lightIconTheme);
+        Context lightContext = new ContextThemeWrapper(context, dualToneLightTheme);
+        Context darkContext = new ContextThemeWrapper(context, dualToneDarkTheme);
+        @ColorInt int darkColor = Utils.getColorAttrDefaultColor(darkContext,
+                R.attr.singleToneColor);
+        Color ovalBackgroundColor = Color.valueOf(Color.red(darkColor), Color.green(darkColor),
+                Color.blue(darkColor), BACKGROUND_ALPHA);
+
+        return KeyButtonDrawable.create(lightContext,
+                Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor), darkColor,
+                R.drawable.ic_sysbar_rotate_button, false /* shadow */, ovalBackgroundColor);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 66903fa..46dd5e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.SysUiServiceProvider.getComponent;
+
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.view.DisplayCutout;
@@ -27,11 +29,16 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 
 import java.util.function.BiConsumer;
@@ -56,13 +63,16 @@
     private final Consumer<ExpandableNotificationRow>
             mSetTrackingHeadsUp = this::setTrackingHeadsUp;
     private final Runnable mUpdatePanelTranslation = this::updatePanelTranslation;
-    private final BiConsumer<Float, Float> mSetExpandedHeight = this::setExpandedHeight;
+    private final BiConsumer<Float, Float> mSetExpandedHeight = this::setAppearFraction;
+    private final KeyguardBypassController mBypassController;
+    private final StatusBarStateController mStatusBarStateController;
+    private final CommandQueue mCommandQueue;
     @VisibleForTesting
     float mExpandedHeight;
     @VisibleForTesting
     boolean mIsExpanded;
     @VisibleForTesting
-    float mExpandFraction;
+    float mAppearFraction;
     private ExpandableNotificationRow mTrackedChild;
     private boolean mShown;
     private final View.OnLayoutChangeListener mStackScrollLayoutChangeListener =
@@ -77,13 +87,17 @@
             };
     private boolean mAnimationsEnabled = true;
     Point mPoint;
+    private KeyguardMonitor mKeyguardMonitor;
 
 
     public HeadsUpAppearanceController(
             NotificationIconAreaController notificationIconAreaController,
             HeadsUpManagerPhone headsUpManager,
-            View statusbarView) {
-        this(notificationIconAreaController, headsUpManager,
+            View statusbarView,
+            SysuiStatusBarStateController statusBarStateController,
+            KeyguardBypassController keyguardBypassController) {
+        this(notificationIconAreaController, headsUpManager, statusBarStateController,
+                keyguardBypassController,
                 statusbarView.findViewById(R.id.heads_up_status_bar_view),
                 statusbarView.findViewById(R.id.notification_stack_scroller),
                 statusbarView.findViewById(R.id.notification_panel),
@@ -96,6 +110,8 @@
     public HeadsUpAppearanceController(
             NotificationIconAreaController notificationIconAreaController,
             HeadsUpManagerPhone headsUpManager,
+            StatusBarStateController stateController,
+            KeyguardBypassController bypassController,
             HeadsUpStatusBarView headsUpStatusBarView,
             NotificationStackScrollLayout stackScroller,
             NotificationPanelView panelView,
@@ -114,7 +130,7 @@
         panelView.addTrackingHeadsUpListener(mSetTrackingHeadsUp);
         panelView.addVerticalTranslationListener(mUpdatePanelTranslation);
         panelView.setHeadsUpAppearanceController(this);
-        mStackScroller.addOnExpandedHeightListener(mSetExpandedHeight);
+        mStackScroller.addOnExpandedHeightChangedListener(mSetExpandedHeight);
         mStackScroller.addOnLayoutChangeListener(mStackScrollLayoutChangeListener);
         mStackScroller.setHeadsUpAppearanceController(this);
         mClockView = clockView;
@@ -135,6 +151,10 @@
                 mHeadsUpStatusBarView.removeOnLayoutChangeListener(this);
             }
         });
+        mBypassController = bypassController;
+        mStatusBarStateController = stateController;
+        mCommandQueue = getComponent(headsUpStatusBarView.getContext(), CommandQueue.class);
+        mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
     }
 
 
@@ -144,7 +164,7 @@
         mPanelView.removeTrackingHeadsUpListener(mSetTrackingHeadsUp);
         mPanelView.removeVerticalTranslationListener(mUpdatePanelTranslation);
         mPanelView.setHeadsUpAppearanceController(null);
-        mStackScroller.removeOnExpandedHeightListener(mSetExpandedHeight);
+        mStackScroller.removeOnExpandedHeightChangedListener(mSetExpandedHeight);
         mStackScroller.removeOnLayoutChangeListener(mStackScrollLayoutChangeListener);
         mDarkIconDispatcher.removeDarkReceiver(this);
     }
@@ -219,7 +239,7 @@
 
     private void updateTopEntry() {
         NotificationEntry newEntry = null;
-        if (!mIsExpanded && mHeadsUpManager.hasPinnedHeadsUp()) {
+        if (shouldBeVisible()) {
             newEntry = mHeadsUpManager.getTopEntry();
         }
         NotificationEntry previousEntry = mHeadsUpStatusBarView.getShowingEntry();
@@ -342,7 +362,13 @@
      * @return if the heads up status bar view should be shown
      */
     public boolean shouldBeVisible() {
-        return !mIsExpanded && mHeadsUpManager.hasPinnedHeadsUp();
+        boolean canShow = !mIsExpanded;
+        if (mBypassController.getBypassEnabled() &&
+                (mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+                        || mKeyguardMonitor.isKeyguardGoingAway())) {
+            canShow = true;
+        }
+        return canShow && mHeadsUpManager.hasPinnedHeadsUp();
     }
 
     @Override
@@ -351,12 +377,24 @@
         updateHeader(entry);
     }
 
-    public void setExpandedHeight(float expandedHeight, float appearFraction) {
-        boolean changedHeight = expandedHeight != mExpandedHeight;
+    @Override
+    public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
+        if (mStatusBarStateController.getState() != StatusBarState.SHADE) {
+            // Show the status bar icons when the pinned mode changes
+            mCommandQueue.recomputeDisableFlags(
+                    mHeadsUpStatusBarView.getContext().getDisplayId(), false);
+        }
+    }
+
+    public void setAppearFraction(float expandedHeight, float appearFraction) {
+        boolean changed = expandedHeight != mExpandedHeight;
         mExpandedHeight = expandedHeight;
-        mExpandFraction = appearFraction;
+        mAppearFraction = appearFraction;
         boolean isExpanded = expandedHeight > 0;
-        if (changedHeight) {
+        // We only notify if the expandedHeight changed and not on the appearFraction, since
+        // otherwise we may run into an infinite loop where the panel and this are constantly
+        // updating themselves over just a small fraction
+        if (changed) {
             updateHeadsUpHeaders();
         }
         if (isExpanded != mIsExpanded) {
@@ -389,8 +427,9 @@
     public void updateHeader(NotificationEntry entry) {
         ExpandableNotificationRow row = entry.getRow();
         float headerVisibleAmount = 1.0f;
-        if (row.isPinned() || row.isHeadsUpAnimatingAway() || row == mTrackedChild) {
-            headerVisibleAmount = mExpandFraction;
+        if (row.isPinned() || row.isHeadsUpAnimatingAway() || row == mTrackedChild
+                || row.showingPulsing()) {
+            headerVisibleAmount = mAppearFraction;
         }
         row.setHeaderVisibleAmount(headerVisibleAmount);
     }
@@ -400,8 +439,7 @@
         mHeadsUpStatusBarView.onDarkChanged(area, darkIntensity, tint);
     }
 
-    public void setPublicMode(boolean publicMode) {
-        mHeadsUpStatusBarView.setPublicMode(publicMode);
+    public void onStateChanged() {
         updateTopEntry();
     }
 
@@ -410,7 +448,7 @@
             mTrackedChild = oldController.mTrackedChild;
             mExpandedHeight = oldController.mExpandedHeight;
             mIsExpanded = oldController.mIsExpanded;
-            mExpandFraction = oldController.mExpandFraction;
+            mAppearFraction = oldController.mAppearFraction;
         }
     }
 }
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 a0cda69..a7e7f08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -22,6 +22,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.util.Log;
 import android.util.Pools;
 import android.view.DisplayCutout;
@@ -31,7 +32,7 @@
 
 import androidx.collection.ArraySet;
 
-import com.android.systemui.Dependency;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.ScreenDecorations;
@@ -50,18 +51,27 @@
 import java.util.HashSet;
 import java.util.Stack;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * A implementation of HeadsUpManager for phone and car.
  */
+@Singleton
 public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
         VisualStabilityManager.Callback, OnHeadsUpChangedListener,
         ConfigurationController.ConfigurationListener, StateListener {
     private static final String TAG = "HeadsUpManagerPhone";
 
-    private final View mStatusBarWindowView;
-    private final NotificationGroupManager mGroupManager;
-    private final VisualStabilityManager mVisualStabilityManager;
-    private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+    @VisibleForTesting
+    final int mExtensionTime;
+    private final StatusBarStateController mStatusBarStateController;
+    private final KeyguardBypassController mBypassController;
+    private final int mAutoHeadsUpNotificationDecay;
+    private View mStatusBarWindowView;
+    private NotificationGroupManager mGroupManager;
+    private VisualStabilityManager mVisualStabilityManager;
+    private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
     private boolean mReleaseOnExpandFinish;
 
     private int mStatusBarHeight;
@@ -70,13 +80,14 @@
     private boolean mTrackingHeadsUp;
     private HashSet<String> mSwipedOutKeys = new HashSet<>();
     private HashSet<NotificationEntry> mEntriesToRemoveAfterExpand = new HashSet<>();
+    private HashSet<String> mKeysToRemoveWhenLeavingKeyguard = new HashSet<>();
     private ArraySet<NotificationEntry> mEntriesToRemoveWhenReorderingAllowed
             = new ArraySet<>();
     private boolean mIsExpanded;
     private int[] mTmpTwoArray = new int[2];
     private boolean mHeadsUpGoingAway;
     private int mStatusBarState;
-    private Rect mTouchableRegion = new Rect();
+    private Region mTouchableRegion = new Region();
 
     private AnimationStateHandler mAnimationStateHandler;
 
@@ -101,21 +112,33 @@
     ///////////////////////////////////////////////////////////////////////////////////////////////
     //  Constructor:
 
+    @Inject
     public HeadsUpManagerPhone(@NonNull final Context context,
-                               @NonNull View statusBarWindowView,
-                               @NonNull NotificationGroupManager groupManager,
-                               @NonNull StatusBar bar,
-                               @NonNull VisualStabilityManager visualStabilityManager) {
+            StatusBarStateController statusBarStateController,
+            KeyguardBypassController bypassController) {
         super(context);
+        Resources resources = mContext.getResources();
+        mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
+        mAutoHeadsUpNotificationDecay = resources.getInteger(
+                R.integer.auto_heads_up_notification_decay);
+        mStatusBarStateController = statusBarStateController;
+        mStatusBarStateController.addCallback(this);
+        mBypassController = bypassController;
 
+        initResources();
+    }
+
+
+    public void setUp(@NonNull View statusBarWindowView,
+            @NonNull NotificationGroupManager groupManager,
+            @NonNull StatusBar bar,
+            @NonNull VisualStabilityManager visualStabilityManager) {
         mStatusBarWindowView = statusBarWindowView;
-        mStatusBarTouchableRegionManager = new StatusBarTouchableRegionManager(context, this, bar,
+        mStatusBarTouchableRegionManager = new StatusBarTouchableRegionManager(mContext, this, bar,
                 statusBarWindowView);
         mGroupManager = groupManager;
         mVisualStabilityManager = visualStabilityManager;
 
-        initResources();
-
         addListener(new OnHeadsUpChangedListener() {
             @Override
             public void onHeadsUpPinnedModeChanged(boolean hasPinnedNotification) {
@@ -125,7 +148,6 @@
                 mStatusBarTouchableRegionManager.updateTouchableRegion();
             }
         });
-        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     public void setAnimationStateHandler(AnimationStateHandler handler) {
@@ -209,7 +231,36 @@
 
     @Override
     public void onStateChanged(int newState) {
+        boolean wasKeyguard = mStatusBarState == StatusBarState.KEYGUARD;
+        boolean isKeyguard = newState == StatusBarState.KEYGUARD;
         mStatusBarState = newState;
+        if (wasKeyguard && !isKeyguard && mKeysToRemoveWhenLeavingKeyguard.size() != 0) {
+            String[] keys = mKeysToRemoveWhenLeavingKeyguard.toArray(new String[0]);
+            for (String key : keys) {
+                removeAlertEntry(key);
+            }
+            mKeysToRemoveWhenLeavingKeyguard.clear();
+        }
+    }
+
+    @Override
+    public void onDozingChanged(boolean isDozing) {
+        if (!isDozing) {
+            // Let's make sure all huns we got while dozing time out within the normal timeout
+            // duration. Otherwise they could get stuck for a very long time
+            for (AlertEntry entry : mAlertEntries.values()) {
+                entry.updateEntry(true /* updatePostTime */);
+            }
+        }
+    }
+
+    @Override
+    public boolean isEntryAutoHeadsUpped(String key) {
+        HeadsUpEntryPhone headsUpEntryPhone = getHeadsUpEntryPhone(key);
+        if (headsUpEntryPhone == null) {
+            return false;
+        }
+        return headsUpEntryPhone.isAutoHeadsUp();
     }
 
     /**
@@ -261,6 +312,18 @@
         }
     }
 
+    /**
+     * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts
+     * longer.
+     */
+    public void extendHeadsUp() {
+        HeadsUpEntryPhone topEntry = getTopHeadsUpEntryPhone();
+        if (topEntry == null) {
+            return;
+        }
+        topEntry.extendPulse();
+    }
+
     ///////////////////////////////////////////////////////////////////////////////////////////////
     //  HeadsUpManager public methods overrides:
 
@@ -299,12 +362,16 @@
         info.touchableRegion.set(calculateTouchableRegion());
     }
 
-    public Rect calculateTouchableRegion() {
-        if (!hasPinnedHeadsUp()) {
+    public Region calculateTouchableRegion() {
+        NotificationEntry topEntry = getTopEntry();
+        // This call could be made in an inconsistent state while the pinnedMode hasn't been
+        // updated yet, but callbacks leading out of the headsUp manager, querying it. Let's
+        // therefore also check if the topEntry is null.
+        if (!hasPinnedHeadsUp() || topEntry == null) {
             mTouchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
             updateRegionForNotch(mTouchableRegion);
+
         } else {
-            NotificationEntry topEntry = getTopEntry();
             if (topEntry.isChildInGroup()) {
                 final NotificationEntry groupSummary =
                         mGroupManager.getGroupSummary(topEntry.notification);
@@ -322,7 +389,7 @@
         return mTouchableRegion;
     }
 
-    private void updateRegionForNotch(Rect region) {
+    private void updateRegionForNotch(Region region) {
         DisplayCutout cutout = mStatusBarWindowView.getRootWindowInsets().getDisplayCutout();
         if (cutout == null) {
             return;
@@ -375,14 +442,18 @@
 
     @Override
     protected void onAlertEntryRemoved(AlertEntry alertEntry) {
+        mKeysToRemoveWhenLeavingKeyguard.remove(alertEntry.mEntry.key);
         super.onAlertEntryRemoved(alertEntry);
         mEntryPool.release((HeadsUpEntryPhone) alertEntry);
     }
 
     @Override
     protected boolean shouldHeadsUpBecomePinned(NotificationEntry entry) {
-        return mStatusBarState != StatusBarState.KEYGUARD && !mIsExpanded
-                || super.shouldHeadsUpBecomePinned(entry);
+        boolean pin = mStatusBarState == StatusBarState.SHADE && !mIsExpanded;
+        if (mBypassController.getBypassEnabled()) {
+            pin |= mStatusBarState == StatusBarState.KEYGUARD;
+        }
+        return pin || super.shouldHeadsUpBecomePinned(entry);
     }
 
     @Override
@@ -390,6 +461,8 @@
         super.dumpInternal(fd, pw, args);
         pw.print("  mBarState=");
         pw.println(mStatusBarState);
+        pw.print("  mTouchableRegion=");
+        pw.println(mTouchableRegion);
     }
 
     ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -426,6 +499,17 @@
 
         private boolean mMenuShownPinned;
 
+        /**
+         * If the time this entry has been on was extended
+         */
+        private boolean extended;
+
+        /**
+         * Was this entry received while on keyguard
+         */
+        private boolean mIsAutoHeadsUp;
+
+
         @Override
         protected boolean isSticky() {
             return super.isSticky() || mMenuShownPinned;
@@ -433,14 +517,19 @@
 
         public void setEntry(@NonNull final NotificationEntry entry) {
             Runnable removeHeadsUpRunnable = () -> {
-                if (!mVisualStabilityManager.isReorderingAllowed()) {
+                if (!mVisualStabilityManager.isReorderingAllowed()
+                        // We don't want to allow reordering while pulsing, but headsup need to
+                        // time out anyway
+                        && !entry.showingPulsing()) {
                     mEntriesToRemoveWhenReorderingAllowed.add(entry);
                     mVisualStabilityManager.addReorderingAllowedCallback(
                             HeadsUpManagerPhone.this);
-                } else if (!mTrackingHeadsUp) {
-                    removeAlertEntry(entry.key);
-                } else {
+                } else if (mTrackingHeadsUp) {
                     mEntriesToRemoveAfterExpand.add(entry);
+                } else if (mIsAutoHeadsUp && mStatusBarState == StatusBarState.KEYGUARD) {
+                    mKeysToRemoveWhenLeavingKeyguard.add(entry.key);
+                } else {
+                    removeAlertEntry(entry.key);
                 }
             };
 
@@ -449,6 +538,7 @@
 
         @Override
         public void updateEntry(boolean updatePostTime) {
+            mIsAutoHeadsUp = mEntry.isAutoHeadsUp();
             super.updateEntry(updatePostTime);
 
             if (mEntriesToRemoveAfterExpand.contains(mEntry)) {
@@ -457,6 +547,7 @@
             if (mEntriesToRemoveWhenReorderingAllowed.contains(mEntry)) {
                 mEntriesToRemoveWhenReorderingAllowed.remove(mEntry);
             }
+            mKeysToRemoveWhenLeavingKeyguard.remove(mEntry.key);
         }
 
         @Override
@@ -490,6 +581,45 @@
         public void reset() {
             super.reset();
             mMenuShownPinned = false;
+            extended = false;
+            mIsAutoHeadsUp = false;
+        }
+
+        private void extendPulse() {
+            if (!extended) {
+                extended = true;
+                updateEntry(false);
+            }
+        }
+
+        @Override
+        public int compareTo(AlertEntry alertEntry) {
+            HeadsUpEntryPhone headsUpEntry = (HeadsUpEntryPhone) alertEntry;
+            boolean autoShown = isAutoHeadsUp();
+            boolean otherAutoShown = headsUpEntry.isAutoHeadsUp();
+            if (autoShown && !otherAutoShown) {
+                return 1;
+            } else if (!autoShown && otherAutoShown) {
+                return -1;
+            }
+            return super.compareTo(alertEntry);
+        }
+
+        @Override
+        protected long calculateFinishTime() {
+            return mPostTime + getDecayDuration() + (extended ? mExtensionTime : 0);
+        }
+
+        private int getDecayDuration() {
+            if (isAutoHeadsUp()) {
+                return getRecommendedHeadsUpTimeoutMs(mAutoHeadsUpNotificationDecay);
+            } else {
+                return getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay);
+            }
+        }
+
+        private boolean isAutoHeadsUp() {
+            return mIsAutoHeadsUp;
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index 4691a31..66b1dd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -27,7 +27,6 @@
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -59,7 +58,7 @@
     private KeyguardAffordanceView mLeftIcon;
     private KeyguardAffordanceView mRightIcon;
     private Animator mSwipeAnimator;
-    private FalsingManager mFalsingManager;
+    private final FalsingManager mFalsingManager;
     private int mMinBackgroundRadius;
     private boolean mMotionCancelled;
     private int mTouchTargetSize;
@@ -80,12 +79,13 @@
         }
     };
 
-    KeyguardAffordanceHelper(Callback callback, Context context) {
+    KeyguardAffordanceHelper(Callback callback, Context context, FalsingManager falsingManager) {
         mContext = context;
         mCallback = callback;
         initIcons();
         updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false);
         updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false);
+        mFalsingManager = falsingManager;
         initDimens();
     }
 
@@ -102,7 +102,6 @@
         mHintGrowAmount =
                 mContext.getResources().getDimensionPixelSize(R.dimen.hint_grow_amount_sideways);
         mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f);
-        mFalsingManager = FalsingManagerFactory.getInstance(mContext);
     }
 
     private void initIcons() {
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 bbae62e..d6f8a60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -54,7 +54,7 @@
 public class KeyguardBouncer {
 
     private static final String TAG = "KeyguardBouncer";
-    static final long BOUNCER_FACE_DELAY = 800;
+    static final long BOUNCER_FACE_DELAY = 1200;
     static final float ALPHA_EXPANSION_THRESHOLD = 0.95f;
     static final float EXPANSION_HIDDEN = 1f;
     static final float EXPANSION_VISIBLE = 0f;
@@ -68,6 +68,7 @@
     private final Handler mHandler;
     private final BouncerExpansionCallback mExpansionCallback;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final UnlockMethodCache mUnlockMethodCache;
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
                 @Override
@@ -95,7 +96,7 @@
     public KeyguardBouncer(Context context, ViewMediatorCallback callback,
             LockPatternUtils lockPatternUtils, ViewGroup container,
             DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager,
-            BouncerExpansionCallback expansionCallback,
+            BouncerExpansionCallback expansionCallback, UnlockMethodCache unlockMethodCache,
             KeyguardUpdateMonitor keyguardUpdateMonitor, Handler handler) {
         mContext = context;
         mCallback = callback;
@@ -106,6 +107,7 @@
         mDismissCallbackRegistry = dismissCallbackRegistry;
         mExpansionCallback = expansionCallback;
         mHandler = handler;
+        mUnlockMethodCache = unlockMethodCache;
         mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
     }
 
@@ -168,7 +170,8 @@
 
         // Split up the work over multiple frames.
         DejankUtils.removeCallbacks(mResetRunnable);
-        if (mKeyguardUpdateMonitor.isFaceDetectionRunning()) {
+        if (mUnlockMethodCache.isUnlockingWithFacePossible() && !needsFullscreenBouncer()
+                && !mKeyguardUpdateMonitor.userNeedsStrongAuth()) {
             mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
         } else {
             DejankUtils.postAfterTraversal(mShowRunnable);
@@ -285,8 +288,6 @@
     }
 
     public void hide(boolean destroyView) {
-        // TODO(b/113914868): investigation log for disappearing home button
-        Log.i(TAG, "KeyguardBouncer.hide (b/113914868): destroyView=" + destroyView);
         if (isShowing()) {
             StatsLog.write(StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED,
                 StatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN);
@@ -344,9 +345,11 @@
                 && mExpansion == EXPANSION_VISIBLE && !isAnimatingAway();
     }
 
-    public boolean isPartiallyVisible() {
-        return (mShowingSoon || (mRoot != null && mRoot.getVisibility() == View.VISIBLE))
-                && mExpansion != EXPANSION_HIDDEN && !isAnimatingAway();
+    /**
+     * {@link #show(boolean)} was called but we're not showing yet, or being dragged.
+     */
+    public boolean inTransit() {
+        return mShowingSoon || mExpansion != EXPANSION_HIDDEN;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index 5abf39e7..0aec2b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -17,48 +17,158 @@
 package com.android.systemui.statusbar.phone
 
 import android.content.Context
+import android.content.pm.PackageManager
+import android.hardware.biometrics.BiometricSourceType
 import android.hardware.face.FaceManager
 import android.provider.Settings
-import com.android.internal.annotations.VisibleForTesting
-import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.tuner.TunerService
-
+import java.io.PrintWriter
 import javax.inject.Inject
 import javax.inject.Singleton
 
 @Singleton
 class KeyguardBypassController {
 
-    @Inject
-    constructor(context: Context,
-                tunerService: TunerService) {
-        val faceManager = context.getSystemService(FaceManager::class.java)
-        if (faceManager?.isHardwareDetected != true) {
-            return
-        }
+    private val unlockMethodCache: UnlockMethodCache
+    private val statusBarStateController: StatusBarStateController
 
-        val dismissByDefault = if (context.resources.getBoolean(
-                com.android.internal.R.bool.config_faceAuthDismissesKeyguard)) 1 else 0
-        tunerService.addTunable(
-                object : TunerService.Tunable {
-                        override fun onTuningChanged(key: String?, newValue: String?) {
-                                bypassEnabled = Settings.Secure.getIntForUser(
-                                        context.contentResolver,
-                                        Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
-                                        dismissByDefault,
-                                        KeyguardUpdateMonitor.getCurrentUser()) != 0
-            }
-        }, Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD)
-    }
+    /**
+     * The pending unlock type which is set if the bypass was blocked when it happened.
+     */
+    private var pendingUnlockType: BiometricSourceType? = null
 
-    @VisibleForTesting
-    constructor(bypassEnabled: Boolean) {
-       this.bypassEnabled = bypassEnabled;
-    }
+    lateinit var unlockController: BiometricUnlockController
+    var isPulseExpanding = false
 
     /**
      * If face unlock dismisses the lock screen or keeps user on keyguard for the current user.
      */
     var bypassEnabled: Boolean = false
-    private set
+        get() = field && unlockMethodCache.isUnlockingWithFacePossible
+        private set
+
+    var bouncerShowing: Boolean = false
+    var launchingAffordance: Boolean = false
+    var qSExpanded = false
+        set(value) {
+            val changed = field != value
+            field = value
+            if (changed && !value) {
+                maybePerformPendingUnlock()
+            }
+        }
+
+    @Inject
+    constructor(
+        context: Context,
+        tunerService: TunerService,
+        statusBarStateController: StatusBarStateController,
+        lockscreenUserManager: NotificationLockscreenUserManager
+    ) {
+        unlockMethodCache = UnlockMethodCache.getInstance(context)
+        this.statusBarStateController = statusBarStateController
+
+        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
+            return
+        }
+        val faceManager = context.getSystemService(FaceManager::class.java)
+        if (faceManager?.isHardwareDetected != true) {
+            return
+        }
+
+        statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
+            override fun onStateChanged(newState: Int) {
+                if (newState != StatusBarState.KEYGUARD) {
+                    pendingUnlockType = null
+                }
+            }
+        })
+
+        val dismissByDefault = if (context.resources.getBoolean(
+                        com.android.internal.R.bool.config_faceAuthDismissesKeyguard)) 1 else 0
+        tunerService.addTunable(object : TunerService.Tunable {
+            override fun onTuningChanged(key: String?, newValue: String?) {
+                bypassEnabled = tunerService.getValue(key, dismissByDefault) != 0
+            }
+        }, Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD)
+        lockscreenUserManager.addUserChangedListener { pendingUnlockType = null }
+    }
+
+    /**
+     * Notify that the biometric unlock has happened.
+     *
+     * @return false if we can not wake and unlock right now
+     */
+    fun onBiometricAuthenticated(biometricSourceType: BiometricSourceType): Boolean {
+        if (bypassEnabled) {
+            val can = canBypass()
+            if (!can && (isPulseExpanding || qSExpanded)) {
+                pendingUnlockType = biometricSourceType
+            }
+            return can
+        }
+        return true
+    }
+
+    fun maybePerformPendingUnlock() {
+        if (pendingUnlockType != null) {
+            if (onBiometricAuthenticated(pendingUnlockType!!)) {
+                unlockController.startWakeAndUnlock(pendingUnlockType)
+                pendingUnlockType = null
+            }
+        }
+    }
+
+    /**
+     * If keyguard can be dismissed because of bypass.
+     */
+    fun canBypass(): Boolean {
+        if (bypassEnabled) {
+            return when {
+                bouncerShowing -> true
+                statusBarStateController.state != StatusBarState.KEYGUARD -> false
+                launchingAffordance -> false
+                isPulseExpanding || qSExpanded -> false
+                else -> true
+            }
+        }
+        return false
+    }
+
+    /**
+     * If shorter animations should be played when unlocking.
+     */
+    fun canPlaySubtleWindowAnimations(): Boolean {
+        if (bypassEnabled) {
+            return when {
+                statusBarStateController.state != StatusBarState.KEYGUARD -> false
+                qSExpanded -> false
+                else -> true
+            }
+        }
+        return false
+    }
+
+    fun onStartedGoingToSleep() {
+        pendingUnlockType = null
+    }
+
+    fun dump(pw: PrintWriter) {
+        pw.println("KeyguardBypassController:")
+        pw.print("  pendingUnlockType: "); pw.println(pendingUnlockType)
+        pw.print("  bypassEnabled: "); pw.println(bypassEnabled)
+        pw.print("  canBypass: "); pw.println(canBypass())
+        pw.print("  bouncerShowing: "); pw.println(bouncerShowing)
+        pw.print("  isPulseExpanding: "); pw.println(isPulseExpanding)
+        pw.print("  launchingAffordance: "); pw.println(launchingAffordance)
+        pw.print("  qSExpanded: "); pw.println(qSExpanded)
+        pw.print("  bouncerShowing: "); pw.println(bouncerShowing)
+    }
+
+    companion object {
+        const val BYPASS_PANEL_FADE_DURATION = 67
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index 579d1ab..179375e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -112,10 +112,15 @@
     private float mEmptyDragAmount;
 
     /**
-     * If true the clock should always be positioned like it's dark. Used in the bypass, where
-     * notifications don't expand on the lock screen and should be kept stable
+     * Setting if bypass is enabled. If true the clock should always be positioned like it's dark
+     * and other minor adjustments.
      */
-    private boolean mPositionLikeDark;
+    private boolean mBypassEnabled;
+
+    /**
+     * The stackscroller padding when unlocked
+     */
+    private int mUnlockedStackScrollerPadding;
 
     /**
      * Refreshes the dimension values.
@@ -139,7 +144,7 @@
     public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
             float panelExpansion, int parentHeight, int keyguardStatusHeight, int clockPreferredY,
             boolean hasCustomClock, boolean hasVisibleNotifs, float dark, float emptyDragAmount,
-            boolean positionLikeDark) {
+            boolean bypassEnabled, int unlockedStackScrollerPadding) {
         mMinTopMargin = minTopMargin + mContainerTopPadding;
         mMaxShadeBottom = maxShadeBottom;
         mNotificationStackHeight = notificationStackHeight;
@@ -151,20 +156,24 @@
         mHasVisibleNotifs = hasVisibleNotifs;
         mDarkAmount = dark;
         mEmptyDragAmount = emptyDragAmount;
-        mPositionLikeDark = positionLikeDark;
+        mBypassEnabled = bypassEnabled;
+        mUnlockedStackScrollerPadding = unlockedStackScrollerPadding;
     }
 
     public void run(Result result) {
         final int y = getClockY(mPanelExpansion);
         result.clockY = y;
         result.clockAlpha = getClockAlpha(y);
-        result.stackScrollerPadding = y + mKeyguardStatusHeight;
-        result.stackScrollerPaddingExpanded = getClockY(1.0f) + mKeyguardStatusHeight;
+        result.stackScrollerPadding = mBypassEnabled ? mUnlockedStackScrollerPadding
+                : y + mKeyguardStatusHeight;
+        result.stackScrollerPaddingExpanded = mBypassEnabled ? mUnlockedStackScrollerPadding
+                : getClockY(1.0f) + mKeyguardStatusHeight;
         result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount);
     }
 
     public float getMinStackScrollerPadding() {
-        return mMinTopMargin + mKeyguardStatusHeight + mClockNotificationsMargin;
+        return mBypassEnabled ? mUnlockedStackScrollerPadding
+                : mMinTopMargin + mKeyguardStatusHeight + mClockNotificationsMargin;
     }
 
     private int getMaxClockY() {
@@ -176,7 +185,7 @@
     }
 
     private int getExpandedPreferredClockY() {
-        return (mHasCustomClock && !mHasVisibleNotifs) ? getPreferredClockY()
+        return (mHasCustomClock && (!mHasVisibleNotifs || mBypassEnabled)) ? getPreferredClockY()
                 : getExpandedClockPosition();
     }
 
@@ -218,7 +227,7 @@
         float clockY = MathUtils.lerp(clockYBouncer, clockYRegular, shadeExpansion);
         clockYDark = MathUtils.lerp(clockYBouncer, clockYDark, shadeExpansion);
 
-        float darkAmount = mPositionLikeDark ? 1.0f : mDarkAmount;
+        float darkAmount = mBypassEnabled && !mHasCustomClock ? 1.0f : mDarkAmount;
         return (int) (MathUtils.lerp(clockY, clockYDark, darkAmount) + mEmptyDragAmount);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
index 6111178..b11329a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
@@ -24,6 +24,7 @@
     /**
      * Executes an action that requres the screen to be unlocked, showing the keyguard if
      * necessary. Does not close the notification shade (in case it was open).
+     * @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
      */
-    void executeWhenUnlocked(OnDismissAction action);
+    void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
index e541e14..834d2a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
@@ -37,7 +37,7 @@
     public KeyguardDismissUtil() {
     }
 
-    /** Sets the actual {@link DismissHandler} implementation. */
+    /** Sets the actual {@link KeyguardDismissHandler} implementation. */
     public void setDismissHandler(KeyguardDismissHandler dismissHandler) {
         mDismissHandler = dismissHandler;
     }
@@ -46,15 +46,17 @@
      * Executes an action that requires the screen to be unlocked.
      *
      * <p>Must be called after {@link #setDismissHandler}.
+     *
+     * @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
      */
     @Override
-    public void executeWhenUnlocked(OnDismissAction action) {
+    public void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen) {
         KeyguardDismissHandler dismissHandler = mDismissHandler;
         if (dismissHandler == null) {
             Log.wtf(TAG, "KeyguardDismissHandler not set.");
             action.onDismiss();
             return;
         }
-        dismissHandler.executeWhenUnlocked(action);
+        dismissHandler.executeWhenUnlocked(action, requiresShadeOpen);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
new file mode 100644
index 0000000..f4635d1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.Sensor
+import android.hardware.TriggerEvent
+import android.hardware.TriggerEventListener
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.util.Assert
+import com.android.systemui.util.AsyncSensorManager
+
+class KeyguardLiftController constructor(
+    context: Context,
+    private val statusBarStateController: StatusBarStateController,
+    private val asyncSensorManager: AsyncSensorManager
+) : StatusBarStateController.StateListener, KeyguardUpdateMonitorCallback() {
+
+    private val keyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context)
+    private val pickupSensor = asyncSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE)
+    private var isListening = false
+    private var bouncerVisible = false
+
+    init {
+        statusBarStateController.addCallback(this)
+        keyguardUpdateMonitor.registerCallback(this)
+        updateListeningState()
+    }
+
+    private val listener: TriggerEventListener = object : TriggerEventListener() {
+        override fun onTrigger(event: TriggerEvent?) {
+            Assert.isMainThread()
+            // Not listening anymore since trigger events unregister themselves
+            isListening = false
+            updateListeningState()
+            keyguardUpdateMonitor.requestFaceAuth()
+        }
+    }
+
+    override fun onDozingChanged(isDozing: Boolean) {
+        updateListeningState()
+    }
+
+    override fun onKeyguardBouncerChanged(bouncer: Boolean) {
+        bouncerVisible = bouncer
+        updateListeningState()
+    }
+
+    override fun onKeyguardVisibilityChanged(showing: Boolean) {
+        updateListeningState()
+    }
+
+    private fun updateListeningState() {
+        val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible &&
+                !statusBarStateController.isDozing
+
+        val shouldListen = onKeyguard || bouncerVisible
+        if (shouldListen != isListening) {
+            isListening = shouldListen
+
+            if (shouldListen) {
+                asyncSensorManager.requestTriggerSensor(listener, pickupSensor)
+            } else {
+                asyncSensorManager.cancelTriggerSensor(listener, pickupSensor)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index c7f778d..1360a08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.Dependency.MAIN_HANDLER_NAME;
 import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
 
 import android.annotation.IntDef;
@@ -29,12 +28,12 @@
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
 import android.hardware.biometrics.BiometricSourceType;
-import android.os.Handler;
 import android.os.Trace;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 import androidx.annotation.Nullable;
@@ -43,14 +42,18 @@
 import com.android.internal.telephony.IccCardConstants;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.phone.ScrimController.ScrimVisibility;
 import com.android.systemui.statusbar.policy.AccessibilityController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
 
 import java.lang.annotation.Retention;
@@ -64,9 +67,9 @@
  */
 public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChangedListener,
         StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
-        UnlockMethodCache.OnUnlockMethodChangedListener {
-
-    private static final int FP_DRAW_OFF_TIMEOUT = 800;
+        UnlockMethodCache.OnUnlockMethodChangedListener,
+        NotificationWakeUpCoordinator.WakeUpListener, ViewTreeObserver.OnPreDrawListener,
+        OnHeadsUpChangedListener {
 
     private static final int STATE_LOCKED = 0;
     private static final int STATE_LOCK_OPEN = 1;
@@ -78,40 +81,55 @@
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final AccessibilityController mAccessibilityController;
     private final DockManager mDockManager;
-    private final Handler mMainHandler;
     private final KeyguardMonitor mKeyguardMonitor;
+    private final KeyguardBypassController mBypassController;
+    private final NotificationWakeUpCoordinator mWakeUpCoordinator;
+    private final HeadsUpManagerPhone mHeadsUpManager;
 
     private int mLastState = 0;
+    private boolean mForceUpdate;
     private boolean mTransientBiometricsError;
-    private boolean mScreenOn;
-    private boolean mLastScreenOn;
     private boolean mIsFaceUnlockState;
     private boolean mSimLocked;
     private int mDensity;
     private boolean mPulsing;
     private boolean mDozing;
-    private boolean mBouncerVisible;
     private boolean mDocked;
-    private boolean mLastDozing;
-    private boolean mLastPulsing;
-    private boolean mLastBouncerVisible;
+    private boolean mBlockUpdates;
     private int mIconColor;
     private float mDozeAmount;
-    private int mIconRes;
-    private boolean mWasPulsingOnThisFrame;
+    private boolean mBouncerShowingScrimmed;
     private boolean mWakeAndUnlockRunning;
     private boolean mKeyguardShowing;
     private boolean mShowingLaunchAffordance;
+    private boolean mKeyguardJustShown;
+    private boolean mUpdatePending;
 
     private final KeyguardMonitor.Callback mKeyguardMonitorCallback =
             new KeyguardMonitor.Callback() {
                 @Override
                 public void onKeyguardShowingChanged() {
+                    boolean force = false;
+                    boolean wasShowing = mKeyguardShowing;
                     mKeyguardShowing = mKeyguardMonitor.isShowing();
-                    update(false /* force */);
+                    if (!wasShowing && mKeyguardShowing && mBlockUpdates) {
+                        mBlockUpdates = false;
+                        force = true;
+                    }
+                    if (!wasShowing && mKeyguardShowing) {
+                        mKeyguardJustShown = true;
+                    }
+                    update(force);
+                }
+
+                @Override
+                public void onKeyguardFadingAwayChanged() {
+                    if (!mKeyguardMonitor.isKeyguardFadingAway() && mBlockUpdates) {
+                        mBlockUpdates = false;
+                        update(true /* force */);
+                    }
                 }
             };
-    private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */);
     private final DockManager.DockEventListener mDockEventListener =
             new DockManager.DockEventListener() {
                 @Override
@@ -120,7 +138,7 @@
                             || event == DockManager.STATE_DOCKED_HIDE;
                     if (docked != mDocked) {
                         mDocked = docked;
-                        update(true /* force */);
+                        update();
                     }
         }
     };
@@ -128,23 +146,10 @@
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
                 @Override
-                public void onScreenTurnedOn() {
-                    mScreenOn = true;
-                    update();
-                }
-
-                @Override
-                public void onScreenTurnedOff() {
-                    mScreenOn = false;
-                    update();
-                }
-
-                @Override
                 public void onSimStateChanged(int subId, int slotId,
                         IccCardConstants.State simState) {
-                    boolean oldSimLocked = mSimLocked;
                     mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
-                    update(oldSimLocked != mSimLocked);
+                    update();
                 }
 
                 @Override
@@ -169,9 +174,11 @@
             StatusBarStateController statusBarStateController,
             ConfigurationController configurationController,
             AccessibilityController accessibilityController,
+            KeyguardBypassController bypassController,
+            NotificationWakeUpCoordinator wakeUpCoordinator,
             KeyguardMonitor keyguardMonitor,
             @Nullable DockManager dockManager,
-            @Named(MAIN_HANDLER_NAME) Handler mainHandler) {
+            HeadsUpManagerPhone headsUpManager) {
         super(context, attrs);
         mContext = context;
         mUnlockMethodCache = UnlockMethodCache.getInstance(context);
@@ -179,9 +186,11 @@
         mAccessibilityController = accessibilityController;
         mConfigurationController = configurationController;
         mStatusBarStateController = statusBarStateController;
+        mBypassController = bypassController;
+        mWakeUpCoordinator = wakeUpCoordinator;
         mKeyguardMonitor = keyguardMonitor;
         mDockManager = dockManager;
-        mMainHandler = mainHandler;
+        mHeadsUpManager = headsUpManager;
     }
 
     @Override
@@ -192,11 +201,13 @@
         mKeyguardMonitor.addCallback(mKeyguardMonitorCallback);
         mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
         mUnlockMethodCache.addListener(this);
+        mWakeUpCoordinator.addListener(this);
         mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
         if (mDockManager != null) {
             mDockManager.addListener(mDockEventListener);
         }
         onThemeChanged();
+        update();
     }
 
     @Override
@@ -206,6 +217,7 @@
         mConfigurationController.removeCallback(this);
         mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
         mKeyguardMonitor.removeCallback(mKeyguardMonitorCallback);
+        mWakeUpCoordinator.removeFullyHiddenChangedListener(this);
         mUnlockMethodCache.removeListener(this);
         if (mDockManager != null) {
             mDockManager.removeListener(mDockEventListener);
@@ -249,67 +261,102 @@
     }
 
     public void update(boolean force) {
-        int state = getState();
-        mIsFaceUnlockState = state == STATE_SCANNING_FACE;
-        if (state != mLastState || mLastDozing != mDozing || mLastPulsing != mPulsing
-                || mLastScreenOn != mScreenOn || mLastBouncerVisible != mBouncerVisible || force) {
-            @LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(mLastState,
-                    state, mLastPulsing, mPulsing, mLastDozing, mDozing, mBouncerVisible);
-            boolean isAnim = lockAnimIndex != -1;
-
-            int iconRes = isAnim ? getThemedAnimationResId(lockAnimIndex) : getIconForState(state);
-            if (iconRes != mIconRes) {
-                mIconRes = iconRes;
-
-                Drawable icon = mContext.getDrawable(iconRes);
-                final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
-                        ? (AnimatedVectorDrawable) icon
-                        : null;
-                setImageDrawable(icon, false);
-                if (mIsFaceUnlockState) {
-                    announceForAccessibility(getContext().getString(
-                            R.string.accessibility_scanning_face));
-                }
-
-                if (animation != null && isAnim) {
-                    animation.forceAnimationOnUI();
-                    animation.clearAnimationCallbacks();
-                    animation.registerAnimationCallback(new Animatable2.AnimationCallback() {
-                        @Override
-                        public void onAnimationEnd(Drawable drawable) {
-                            if (getDrawable() == animation && state == getState()
-                                    && doesAnimationLoop(lockAnimIndex)) {
-                                animation.start();
-                            } else {
-                                Trace.endAsyncSection("LockIcon#Animation", state);
-                            }
-                        }
-                    });
-                    Trace.beginAsyncSection("LockIcon#Animation", state);
-                    animation.start();
-                }
-            }
-            updateDarkTint();
-
-            if (isAnim && !mLastScreenOn) {
-                removeCallbacks(mDrawOffTimeout);
-                postDelayed(mDrawOffTimeout, FP_DRAW_OFF_TIMEOUT);
-            } else {
-                removeCallbacks(mDrawOffTimeout);
-            }
-
-            mLastState = state;
-            mLastScreenOn = mScreenOn;
-            mLastDozing = mDozing;
-            mLastPulsing = mPulsing;
-            mLastBouncerVisible = mBouncerVisible;
+        if (force) {
+            mForceUpdate = true;
         }
+        if (!mUpdatePending) {
+            mUpdatePending = true;
+            getViewTreeObserver().addOnPreDrawListener(this);
+        }
+    }
+
+    @Override
+    public boolean onPreDraw() {
+        mUpdatePending = false;
+        getViewTreeObserver().removeOnPreDrawListener(this);
+
+        int state = getState();
+        int lastState = mLastState;
+        boolean keyguardJustShown = mKeyguardJustShown;
+        mIsFaceUnlockState = state == STATE_SCANNING_FACE;
+        mLastState = state;
+        mKeyguardJustShown = false;
+
+        boolean shouldUpdate = lastState != state || mForceUpdate;
+        if (mBlockUpdates && canBlockUpdates()) {
+            shouldUpdate = false;
+        }
+        if (shouldUpdate) {
+            mForceUpdate = false;
+            @LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(lastState,
+                    state, mPulsing, mDozing, keyguardJustShown);
+            boolean isAnim = lockAnimIndex != -1;
+            int iconRes = isAnim ? getThemedAnimationResId(lockAnimIndex) : getIconForState(state);
+
+            Drawable icon = mContext.getDrawable(iconRes);
+            final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
+                    ? (AnimatedVectorDrawable) icon
+                    : null;
+            setImageDrawable(icon, false);
+            if (mIsFaceUnlockState) {
+                announceForAccessibility(getContext().getString(
+                        R.string.accessibility_scanning_face));
+            }
+
+            if (animation != null && isAnim) {
+                animation.forceAnimationOnUI();
+                animation.clearAnimationCallbacks();
+                animation.registerAnimationCallback(new Animatable2.AnimationCallback() {
+                    @Override
+                    public void onAnimationEnd(Drawable drawable) {
+                        if (getDrawable() == animation && state == getState()
+                                && doesAnimationLoop(lockAnimIndex)) {
+                            animation.start();
+                        } else {
+                            Trace.endAsyncSection("LockIcon#Animation", state);
+                        }
+                    }
+                });
+                Trace.beginAsyncSection("LockIcon#Animation", state);
+                animation.start();
+            }
+        }
+        updateDarkTint();
 
         boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked);
         boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning
                 || mShowingLaunchAffordance;
-        setVisibility(invisible ? INVISIBLE : VISIBLE);
+        if (mBypassController.getBypassEnabled() && !mBouncerShowingScrimmed) {
+            if (mHeadsUpManager.isHeadsUpGoingAway()
+                    || mHeadsUpManager.hasPinnedHeadsUp()
+                    || (mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+                    && !mWakeUpCoordinator.getNotificationsFullyHidden())) {
+                invisible = true;
+            }
+        }
+        boolean wasInvisible = getVisibility() == INVISIBLE;
+        if (invisible != wasInvisible) {
+            setVisibility(invisible ? INVISIBLE : VISIBLE);
+            animate().cancel();
+            if (!invisible) {
+                setScaleX(0);
+                setScaleY(0);
+                animate()
+                        .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
+                        .scaleX(1)
+                        .scaleY(1)
+                        .withLayer()
+                        .setDuration(233)
+                        .start();
+            }
+        }
         updateClickability();
+
+        return true;
+    }
+
+    private boolean canBlockUpdates() {
+        return mKeyguardShowing || mKeyguardMonitor.isKeyguardFadingAway();
     }
 
     private void updateClickability() {
@@ -370,67 +417,68 @@
         return lockAnimIndex == SCANNING;
     }
 
-    private int getAnimationIndexForTransition(int oldState, int newState,
-            boolean wasPulsing, boolean pulsing, boolean wasDozing, boolean dozing,
-            boolean bouncerVisible) {
+    private static int getAnimationIndexForTransition(int oldState, int newState, boolean pulsing,
+            boolean dozing, boolean keyguardJustShown) {
 
         // Never animate when screen is off
-        if (dozing && !pulsing && !mWasPulsingOnThisFrame) {
+        if (dozing && !pulsing) {
             return -1;
         }
 
-        boolean isError = oldState != STATE_BIOMETRICS_ERROR && newState == STATE_BIOMETRICS_ERROR;
-        boolean justUnlocked = oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN;
-        boolean justLocked = oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED;
-        boolean nowPulsing = !wasPulsing && pulsing;
-        boolean turningOn = wasDozing && !dozing && !mWasPulsingOnThisFrame;
-
-        if (isError) {
+        if (newState == STATE_BIOMETRICS_ERROR) {
             return ERROR;
-        } else if (justUnlocked) {
+        } else if (oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN) {
             return UNLOCK;
-        } else if (justLocked) {
+        } else if (oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED && !keyguardJustShown) {
             return LOCK;
-        } else if (newState == STATE_SCANNING_FACE && bouncerVisible) {
+        } else if (newState == STATE_SCANNING_FACE) {
             return SCANNING;
-        } else if ((nowPulsing || turningOn) && newState != STATE_LOCK_OPEN) {
-            return LOCK_IN;
         }
         return -1;
     }
 
+    @Override
+    public void onFullyHiddenChanged(boolean isFullyHidden) {
+        if (mBypassController.getBypassEnabled()) {
+            update();
+        }
+    }
+
+    public void setBouncerShowingScrimmed(boolean bouncerShowing) {
+        mBouncerShowingScrimmed = bouncerShowing;
+        if (mBypassController.getBypassEnabled()) {
+            update();
+        }
+    }
+
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({ERROR, UNLOCK, LOCK, SCANNING, LOCK_IN})
+    @IntDef({ERROR, UNLOCK, LOCK, SCANNING})
     @interface LockAnimIndex {}
-    private static final int ERROR = 0, UNLOCK = 1, LOCK = 2, SCANNING = 3, LOCK_IN = 4;
+    private static final int ERROR = 0, UNLOCK = 1, LOCK = 2, SCANNING = 3;
     private static final int[][] LOCK_ANIM_RES_IDS = new int[][] {
             {
                     R.anim.lock_to_error,
                     R.anim.lock_unlock,
                     R.anim.lock_lock,
-                    R.anim.lock_scanning,
-                    R.anim.lock_in,
+                    R.anim.lock_scanning
             },
             {
                     R.anim.lock_to_error_circular,
                     R.anim.lock_unlock_circular,
                     R.anim.lock_lock_circular,
-                    R.anim.lock_scanning_circular,
-                    R.anim.lock_in_circular,
+                    R.anim.lock_scanning_circular
             },
             {
                     R.anim.lock_to_error_filled,
                     R.anim.lock_unlock_filled,
                     R.anim.lock_lock_filled,
-                    R.anim.lock_scanning_filled,
-                    R.anim.lock_in_filled,
+                    R.anim.lock_scanning_filled
             },
             {
                     R.anim.lock_to_error_rounded,
                     R.anim.lock_unlock_rounded,
                     R.anim.lock_lock_rounded,
-                    R.anim.lock_scanning_rounded,
-                    R.anim.lock_in_rounded,
+                    R.anim.lock_scanning_rounded
             },
     };
 
@@ -450,11 +498,12 @@
 
     private int getState() {
         KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
-        if (mTransientBiometricsError) {
-            return STATE_BIOMETRICS_ERROR;
-        } else if ((mUnlockMethodCache.canSkipBouncer() || !mKeyguardShowing) && !mSimLocked) {
+        if ((mUnlockMethodCache.canSkipBouncer() || !mKeyguardShowing
+                || mKeyguardMonitor.isKeyguardGoingAway()) && !mSimLocked) {
             return STATE_LOCK_OPEN;
-        } else if (updateMonitor.isFaceDetectionRunning()) {
+        } else if (mTransientBiometricsError) {
+            return STATE_BIOMETRICS_ERROR;
+        } else if (updateMonitor.isFaceDetectionRunning() && !mPulsing) {
             return STATE_SCANNING_FACE;
         } else {
             return STATE_LOCKED;
@@ -473,12 +522,6 @@
      */
     public void setPulsing(boolean pulsing) {
         mPulsing = pulsing;
-        if (!mPulsing) {
-            mWasPulsingOnThisFrame = true;
-            mMainHandler.post(() -> {
-                mWasPulsingOnThisFrame = false;
-            });
-        }
         update();
     }
 
@@ -496,17 +539,6 @@
         setImageTintList(ColorStateList.valueOf(color));
     }
 
-    /**
-     * If bouncer is visible or not.
-     */
-    public void setBouncerVisible(boolean bouncerVisible) {
-        if (mBouncerVisible == bouncerVisible) {
-            return;
-        }
-        mBouncerVisible = bouncerVisible;
-        update();
-    }
-
     @Override
     public void onDensityOrFontScaleChanged() {
         ViewGroup.LayoutParams lp = getLayoutParams();
@@ -533,11 +565,17 @@
     /**
      * We need to hide the lock whenever there's a fingerprint unlock, otherwise you'll see the
      * icon on top of the black front scrim.
+     * @param wakeAndUnlock are we wake and unlocking
+     * @param isUnlock are we currently unlocking
      */
-    public void onBiometricAuthModeChanged(boolean wakeAndUnlock) {
+    public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
         if (wakeAndUnlock) {
             mWakeAndUnlockRunning = true;
         }
+        if (isUnlock && mBypassController.getBypassEnabled() && canBlockUpdates()) {
+            // We don't want the icon to change while we are unlocking
+            mBlockUpdates = true;
+        }
         update();
     }
 
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 443cc43..c0a1b12 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -112,7 +112,9 @@
 
         final boolean guestEnabled = !mContext.getSystemService(DevicePolicyManager.class)
                 .getGuestUserDisabled(null);
-        return mUserSwitcherController.getSwitchableUserCount() > 1 || guestEnabled
+        return mUserSwitcherController.getSwitchableUserCount() > 1
+                // If we cannot add guests even if they are enabled, do not show
+                || (guestEnabled && !mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER))
                 || mContext.getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user);
     }
 
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 2f245ff..8bb8ca2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
@@ -45,6 +45,7 @@
     private final NavigationBarView mNavigationBarView;
     private final LightBarTransitionsController mLightBarController;
     private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
+    private boolean mWindowVisible;
 
     private final CompositionSamplingListener mSamplingListener;
     private final Runnable mUpdateSamplingListener = this::updateSamplingListener;
@@ -148,7 +149,7 @@
             mSamplingListenerRegistered = false;
             CompositionSamplingListener.unregister(mSamplingListener);
         }
-        if (mSamplingEnabled && !mSamplingBounds.isEmpty()
+        if (mSamplingEnabled && mWindowVisible && !mSamplingBounds.isEmpty()
                 && mNavigationBarView.isAttachedToWindow()) {
             if (!mNavigationBarView.getViewRootImpl().getSurfaceControl().isValid()) {
                 // The view may still be attached, but the surface backing the window can be
@@ -158,7 +159,7 @@
             }
             mSamplingListenerRegistered = true;
             CompositionSamplingListener.register(mSamplingListener, DEFAULT_DISPLAY,
-                    mNavigationBarView.getViewRootImpl().getSurfaceControl().getHandle(),
+                    mNavigationBarView.getViewRootImpl().getSurfaceControl(),
                     mSamplingBounds);
         }
     }
@@ -180,6 +181,11 @@
         }
     }
 
+    public void setWindowVisible(boolean visible) {
+        mWindowVisible = visible;
+        requestUpdateSamplingListener();
+    }
+
     public void onNavigationModeChanged(int mode) {
         mNavBarMode = mode;
     }
@@ -194,6 +200,7 @@
         pw.println("  mSamplingBounds: " + mSamplingBounds);
         pw.println("  mLastMedianLuma: " + mLastMedianLuma);
         pw.println("  mCurrentMedianLuma: " + mCurrentMedianLuma);
+        pw.println("  mWindowVisible: " + mWindowVisible);
     }
 
     public static boolean isEnabled(Context context, int navBarMode) {
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 d94a335..e9731c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -136,6 +136,7 @@
     protected final AssistManager mAssistManager;
     private final MetricsLogger mMetricsLogger;
     private final DeviceProvisionedController mDeviceProvisionedController;
+    private final StatusBarStateController mStatusBarStateController;
 
     protected NavigationBarView mNavigationBarView = null;
 
@@ -202,17 +203,16 @@
         }
 
         @Override
-        public void onBackButtonAlphaChanged(float alpha, boolean animate) {
-            final ButtonDispatcher backButton = mNavigationBarView.getBackButton();
-            final boolean useAltBack =
-                    (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
-            if (QuickStepContract.isGesturalMode(mNavBarMode) && !useAltBack) {
-                // 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);
-            } else {
-                backButton.setVisibility(alpha > 0 ? View.VISIBLE : View.INVISIBLE);
-                backButton.setAlpha(alpha, animate);
+        public void onNavBarButtonAlphaChanged(float alpha, boolean animate) {
+            ButtonDispatcher buttonDispatcher = null;
+            if (QuickStepContract.isSwipeUpMode(mNavBarMode)) {
+                buttonDispatcher = mNavigationBarView.getBackButton();
+            } else if (QuickStepContract.isGesturalMode(mNavBarMode)) {
+                buttonDispatcher = mNavigationBarView.getHomeHandle();
+            }
+            if (buttonDispatcher != null) {
+                buttonDispatcher.setVisibility(alpha > 0 ? View.VISIBLE : View.INVISIBLE);
+                buttonDispatcher.setAlpha(alpha, animate);
             }
         }
     };
@@ -244,9 +244,11 @@
     public NavigationBarFragment(AccessibilityManagerWrapper accessibilityManagerWrapper,
             DeviceProvisionedController deviceProvisionedController, MetricsLogger metricsLogger,
             AssistManager assistManager, OverviewProxyService overviewProxyService,
-            NavigationModeController navigationModeController) {
+            NavigationModeController navigationModeController,
+            StatusBarStateController statusBarStateController) {
         mAccessibilityManagerWrapper = accessibilityManagerWrapper;
         mDeviceProvisionedController = deviceProvisionedController;
+        mStatusBarStateController = statusBarStateController;
         mMetricsLogger = metricsLogger;
         mAssistManager = assistManager;
         mAssistantAvailable = mAssistManager.getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
@@ -320,6 +322,7 @@
             mNavigationBarView.getLightTransitionsController().restoreState(savedInstanceState);
         }
         mNavigationBarView.setNavigationIconHints(mNavigationIconHints);
+        mNavigationBarView.setWindowVisible(isNavBarWindowVisible());
 
         prepareNavigationBarView();
         checkNavBarModes();
@@ -465,8 +468,7 @@
             if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
 
             updateSystemUiStateFlags(-1);
-            mNavigationBarView.getRotationButtonController().onNavigationBarWindowVisibilityChange(
-                    isNavBarWindowVisible());
+            mNavigationBarView.setWindowVisible(isNavBarWindowVisible());
         }
     }
 
@@ -869,9 +871,6 @@
         boolean[] feedbackEnabled = new boolean[1];
         int a11yFlags = getA11yButtonState(feedbackEnabled);
 
-        mNavigationBarView.getRotationButtonController().setAccessibilityFeedbackEnabled(
-                feedbackEnabled[0]);
-
         boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
         boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
         mNavigationBarView.setAccessibilityButtonState(clickable, longClickable);
@@ -951,7 +950,7 @@
     public void touchAutoDim() {
         getBarTransitions().setAutoDim(false);
         mHandler.removeCallbacks(mAutoDim);
-        int state = Dependency.get(StatusBarStateController.class).getState();
+        int state = mStatusBarStateController.getState();
         if (state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED) {
             mHandler.postDelayed(mAutoDim, AUTODIM_TIMEOUT_MS);
         }
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 2b5a28e..23cc0fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -213,9 +213,12 @@
 
     /**
      * Register {@code listener} to be notified when the color of nav bar elements changes.
+     *
+     * Returns the current nav bar color.
      */
-    public void addDarkIntensityListener(DarkIntensityListener listener) {
+    public float addDarkIntensityListener(DarkIntensityListener listener) {
         mDarkIntensityListeners.add(listener);
+        return mLightTransitionsController.getCurrentDarkIntensity();
     }
 
     /**
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 8a895e1..22e3edb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -238,7 +238,19 @@
             info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
             return;
         }
+
         info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+        ButtonDispatcher imeSwitchButton = getImeSwitchButton();
+        if (imeSwitchButton.getVisibility() == VISIBLE) {
+            // If the IME is not up, but the ime switch button is visible, then make sure that
+            // button is touchable
+            int[] loc = new int[2];
+            View buttonView = imeSwitchButton.getCurrentView();
+            buttonView.getLocationInWindow(loc);
+            info.touchableRegion.set(loc[0], loc[1], loc[0] + buttonView.getWidth(),
+                    loc[1] + buttonView.getHeight());
+            return;
+        }
         info.touchableRegion.setEmpty();
     };
 
@@ -521,6 +533,11 @@
         return KeyButtonDrawable.create(mContext, icon, hasShadow);
     }
 
+    public void setWindowVisible(boolean visible) {
+        mTintController.setWindowVisible(visible);
+        mRotationButtonController.onNavigationBarWindowVisibilityChange(visible);
+    }
+
     @Override
     public void setLayoutDirection(int layoutDirection) {
         reloadNavIcons();
@@ -597,10 +614,6 @@
         boolean disableHome = isGesturalMode(mNavBarMode)
                 || ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
 
-        // TODO(b/113914868): investigation log for disappearing home button
-        Log.i(TAG, "updateNavButtonIcons (b/113914868): home disabled=" + disableHome
-                + " mDisabledFlags=" + mDisabledFlags);
-
         // Always disable recents when alternate car mode UI is active and for secondary displays.
         boolean disableRecent = isRecentsButtonDisabled();
 
@@ -614,7 +627,7 @@
         if (mOverviewProxyService.isEnabled()) {
             // Force disable recents when not in legacy mode
             disableRecent |= !QuickStepContract.isLegacyMode(mNavBarMode);
-            if (pinningActive) {
+            if (pinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
                 disableBack = disableHome = false;
             }
         } else if (pinningActive) {
@@ -764,9 +777,10 @@
 
     @Override
     public void onNavigationModeChanged(int mode) {
+        Context curUserCtx = Dependency.get(NavigationModeController.class).getCurrentUserContext();
         mNavBarMode = mode;
         mBarTransitions.onNavigationModeChanged(mNavBarMode);
-        mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode);
+        mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode, curUserCtx);
         mRecentsOnboarding.onNavigationModeChanged(mNavBarMode);
         getRotateSuggestionButton().onNavigationModeChanged(mNavBarMode);
 
@@ -1031,6 +1045,9 @@
         reorient();
         onNavigationModeChanged(mNavBarMode);
         setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
+        if (mRotationButtonController != null) {
+            mRotationButtonController.registerListeners();
+        }
 
         mEdgeBackGestureHandler.onNavBarAttached();
         getViewTreeObserver().addOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
@@ -1044,6 +1061,10 @@
         for (int i = 0; i < mButtonDispatchers.size(); ++i) {
             mButtonDispatchers.valueAt(i).onDestroy();
         }
+        if (mRotationButtonController != null) {
+            mRotationButtonController.unregisterListeners();
+        }
+
         mEdgeBackGestureHandler.onNavBarDetached();
         getViewTreeObserver().removeOnComputeInternalInsetsListener(
                 mOnComputeInternalInsetsListener);
@@ -1095,12 +1116,18 @@
         mContextualButtonGroup.dump(pw);
         mRecentsOnboarding.dump(pw);
         mTintController.dump(pw);
+        mEdgeBackGestureHandler.dump(pw);
     }
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        setPadding(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
-                insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
+        int leftInset = insets.getSystemWindowInsetLeft();
+        int rightInset = insets.getSystemWindowInsetRight();
+        setPadding(leftInset, insets.getSystemWindowInsetTop(), rightInset,
+                insets.getSystemWindowInsetBottom());
+        // we're passing the insets onto the gesture handler since the back arrow is only
+        // conditionally added and doesn't always get all the insets.
+        mEdgeBackGestureHandler.setInsets(leftInset, rightInset);
         return super.onApplyWindowInsets(insets);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
index 7cd8f7b..64fef55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
@@ -16,35 +16,52 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.app.Activity.RESULT_CANCELED;
+import static android.app.Activity.RESULT_OK;
+import static android.app.admin.DevicePolicyManager.STATE_USER_UNMANAGED;
 import static android.content.Intent.ACTION_OVERLAY_CHANGED;
 import static android.content.Intent.ACTION_PREFERRED_ACTIVITY_CHANGED;
+import static android.content.pm.PackageManager.FEATURE_DEVICE_ADMIN;
 import static android.os.UserHandle.USER_CURRENT;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
 
+import static com.android.systemui.shared.system.QuickStepContract.ACTION_ENABLE_GESTURE_NAV;
+import static com.android.systemui.shared.system.QuickStepContract.ACTION_ENABLE_GESTURE_NAV_RESULT;
+import static com.android.systemui.shared.system.QuickStepContract.EXTRA_RESULT_INTENT;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.om.IOverlayManager;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.ApkAssets;
 import android.os.PatternMatcher;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.provider.Settings.Secure;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseBooleanArray;
 
 import com.android.systemui.Dumpable;
+import com.android.systemui.R;
 import com.android.systemui.UiOffloadThread;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.util.NotificationChannels;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -63,6 +80,11 @@
     private static final String TAG = NavigationModeController.class.getSimpleName();
     private static final boolean DEBUG = false;
 
+    private static final int SYSTEM_APP_MASK =
+            ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+    static final String SHARED_PREFERENCES_NAME = "navigation_mode_controller_preferences";
+    static final String PREFS_SWITCHED_FROM_GESTURE_NAV_KEY = "switched_from_gesture_nav";
+
     public interface ModeChangedListener {
         void onNavigationModeChanged(int mode);
     }
@@ -78,6 +100,8 @@
     private int mMode = NAV_BAR_MODE_3BUTTON;
     private ArrayList<ModeChangedListener> mListeners = new ArrayList<>();
 
+    private String mLastDefaultLauncher;
+
     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -92,7 +116,13 @@
                     if (DEBUG) {
                         Log.d(TAG, "ACTION_PREFERRED_ACTIVITY_CHANGED");
                     }
-                    switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
+                    final String launcher = getDefaultLauncherPackageName(mCurrentUserContext);
+                    // Check if it is a default launcher change
+                    if (!TextUtils.equals(mLastDefaultLauncher, launcher)) {
+                        switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
+                        showNotificationIfDefaultLauncherSupportsGestureNav();
+                        mLastDefaultLauncher = launcher;
+                    }
                     break;
             }
         }
@@ -137,6 +167,8 @@
                 }
             };
 
+    private BroadcastReceiver mEnableGestureNavReceiver;
+
     @Inject
     public NavigationModeController(Context context,
             DeviceProvisionedController deviceProvisionedController,
@@ -158,6 +190,9 @@
         mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, preferredActivityFilter, null,
                 null);
 
+        // We are only interested in launcher changes, so keeping track of the current default.
+        mLastDefaultLauncher = getDefaultLauncherPackageName(mContext);
+
         updateCurrentInteractionMode(false /* notify */);
         switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
 
@@ -165,6 +200,82 @@
         deferGesturalNavOverlayIfNecessary();
     }
 
+    private void removeEnableGestureNavListener() {
+        if (mEnableGestureNavReceiver != null) {
+            if (DEBUG) {
+                Log.d(TAG, "mEnableGestureNavReceiver unregistered");
+            }
+            mContext.unregisterReceiver(mEnableGestureNavReceiver);
+            mEnableGestureNavReceiver = null;
+        }
+    }
+
+    private boolean setGestureModeOverlayForMainLauncher() {
+        removeEnableGestureNavListener();
+        if (getCurrentInteractionMode(mCurrentUserContext) == NAV_BAR_MODE_GESTURAL) {
+            // Already in gesture mode
+            return true;
+        }
+        final Boolean supported = isGestureNavSupportedByDefaultLauncher(mCurrentUserContext);
+        if (supported == null || supported) {
+            Log.d(TAG, "Switching system navigation to full-gesture mode:"
+                    + " defaultLauncher="
+                    + getDefaultLauncherPackageName(mCurrentUserContext)
+                    + " contextUser="
+                    + mCurrentUserContext.getUserId());
+
+            setModeOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT);
+            return true;
+        } else {
+            Log.e(TAG, "Gesture nav is not supported for defaultLauncher="
+                    + getDefaultLauncherPackageName(mCurrentUserContext));
+            return false;
+        }
+    }
+
+    private boolean enableGestureNav(Intent intent) {
+        if (!(intent.getParcelableExtra(EXTRA_RESULT_INTENT) instanceof PendingIntent)) {
+            Log.e(TAG, "No callback pending intent was attached");
+            return false;
+        }
+
+        PendingIntent callback = intent.getParcelableExtra(EXTRA_RESULT_INTENT);
+        Intent callbackIntent = callback.getIntent();
+        if (callbackIntent == null
+                || !ACTION_ENABLE_GESTURE_NAV_RESULT.equals(callbackIntent.getAction())) {
+            Log.e(TAG, "Invalid callback intent");
+            return false;
+        }
+        String callerPackage = callback.getCreatorPackage();
+        UserHandle callerUser = callback.getCreatorUserHandle();
+
+        DevicePolicyManager dpm = mCurrentUserContext.getSystemService(DevicePolicyManager.class);
+        ComponentName ownerComponent = dpm.getDeviceOwnerComponentOnCallingUser();
+
+        if (ownerComponent != null) {
+            // Verify that the caller is the owner component
+            if (!ownerComponent.getPackageName().equals(callerPackage)
+                    || !mCurrentUserContext.getUser().equals(callerUser)) {
+                Log.e(TAG, "Callback must be from the device owner");
+                return false;
+            }
+        } else {
+            UserHandle callerParent = mCurrentUserContext.getSystemService(UserManager.class)
+                    .getProfileParent(callerUser);
+            if (callerParent == null || !callerParent.equals(mCurrentUserContext.getUser())) {
+                Log.e(TAG, "Callback must be from a managed user");
+                return false;
+            }
+            ComponentName profileOwner = dpm.getProfileOwnerAsUser(callerUser);
+            if (profileOwner == null || !profileOwner.getPackageName().equals(callerPackage)) {
+                Log.e(TAG, "Callback must be from the profile owner");
+                return false;
+            }
+        }
+
+        return setGestureModeOverlayForMainLauncher();
+    }
+
     public void updateCurrentInteractionMode(boolean notify) {
         mCurrentUserContext = getCurrentUserContext();
         int mode = getCurrentInteractionMode(mCurrentUserContext);
@@ -205,7 +316,7 @@
         return mode;
     }
 
-    private Context getCurrentUserContext() {
+    public Context getCurrentUserContext() {
         int userId = ActivityManagerWrapper.getInstance().getCurrentUserId();
         if (DEBUG) {
             Log.d(TAG, "getCurrentUserContext: contextUser=" + mContext.getUserId()
@@ -223,6 +334,10 @@
         }
     }
 
+    private boolean supportsDeviceAdmin() {
+        return mContext.getPackageManager().hasSystemFeature(FEATURE_DEVICE_ADMIN);
+    }
+
     private void deferGesturalNavOverlayIfNecessary() {
         final int userId = mDeviceProvisionedController.getCurrentUser();
         mRestoreGesturalNavBarMode.put(userId, false);
@@ -233,6 +348,7 @@
                 Log.d(TAG, "deferGesturalNavOverlayIfNecessary: device is provisioned and user is "
                         + "setup");
             }
+            removeEnableGestureNavListener();
             return;
         }
 
@@ -248,6 +364,7 @@
                 Log.d(TAG, "deferGesturalNavOverlayIfNecessary: no default gestural overlay, "
                         + "default=" + defaultOverlays);
             }
+            removeEnableGestureNavListener();
             return;
         }
 
@@ -255,6 +372,24 @@
         // provisioned
         setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
         mRestoreGesturalNavBarMode.put(userId, true);
+
+        if (supportsDeviceAdmin() && mEnableGestureNavReceiver == null) {
+            mEnableGestureNavReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (DEBUG) {
+                        Log.d(TAG, "ACTION_ENABLE_GESTURE_NAV");
+                    }
+                    setResultCode(enableGestureNav(intent) ? RESULT_OK : RESULT_CANCELED);
+                }
+            };
+            // Register for all users so that we can get managed users as well
+            mContext.registerReceiverAsUser(mEnableGestureNavReceiver, UserHandle.ALL,
+                    new IntentFilter(ACTION_ENABLE_GESTURE_NAV), null, null);
+            if (DEBUG) {
+                Log.d(TAG, "mEnableGestureNavReceiver registered");
+            }
+        }
         if (DEBUG) {
             Log.d(TAG, "deferGesturalNavOverlayIfNecessary: setting to 3 button mode");
         }
@@ -268,7 +403,15 @@
         final int userId = mDeviceProvisionedController.getCurrentUser();
         if (mRestoreGesturalNavBarMode.get(userId)) {
             // Restore the gestural state if necessary
-            setModeOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT);
+            if (!supportsDeviceAdmin()
+                    || mCurrentUserContext.getSystemService(DevicePolicyManager.class)
+                    .getUserProvisioningState() == STATE_USER_UNMANAGED) {
+                setGestureModeOverlayForMainLauncher();
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, "Not restoring to gesture nav for managed user");
+                }
+            }
             mRestoreGesturalNavBarMode.put(userId, false);
         }
     }
@@ -287,6 +430,100 @@
         });
     }
 
+    private void switchFromGestureNavModeIfNotSupportedByDefaultLauncher() {
+        if (getCurrentInteractionMode(mCurrentUserContext) != NAV_BAR_MODE_GESTURAL) {
+            return;
+        }
+        final Boolean supported = isGestureNavSupportedByDefaultLauncher(mCurrentUserContext);
+        if (supported == null || supported) {
+            return;
+        }
+
+        Log.d(TAG, "Switching system navigation to 3-button mode:"
+                + " defaultLauncher=" + getDefaultLauncherPackageName(mCurrentUserContext)
+                + " contextUser=" + mCurrentUserContext.getUserId());
+
+        setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
+        showNotification(mCurrentUserContext, R.string.notification_content_system_nav_changed);
+        mCurrentUserContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .edit().putBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, true).apply();
+    }
+
+    private void showNotificationIfDefaultLauncherSupportsGestureNav() {
+        boolean previouslySwitchedFromGestureNav = mCurrentUserContext
+                .getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .getBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false);
+        if (!previouslySwitchedFromGestureNav) {
+            return;
+        }
+        if (getCurrentInteractionMode(mCurrentUserContext) == NAV_BAR_MODE_GESTURAL) {
+            return;
+        }
+        final Boolean supported = isGestureNavSupportedByDefaultLauncher(mCurrentUserContext);
+        if (supported == null || !supported) {
+            return;
+        }
+
+        showNotification(mCurrentUserContext, R.string.notification_content_gesture_nav_available);
+        mCurrentUserContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .edit().putBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false).apply();
+    }
+
+    /**
+     * Returns null if there is no default launcher set for the current user. Returns true if the
+     * current default launcher supports Gesture Navigation. Returns false otherwise.
+     */
+    private Boolean isGestureNavSupportedByDefaultLauncher(Context context) {
+        final String defaultLauncherPackageName = getDefaultLauncherPackageName(context);
+        if (DEBUG) {
+            Log.d(TAG, "isGestureNavSupportedByDefaultLauncher:"
+                    + " defaultLauncher=" + defaultLauncherPackageName
+                    + " contextUser=" + context.getUserId());
+        }
+        if (defaultLauncherPackageName == null) {
+            return null;
+        }
+        if (isSystemApp(context, defaultLauncherPackageName)) {
+            return true;
+        }
+        return false;
+    }
+
+    private String getDefaultLauncherPackageName(Context context) {
+        final ComponentName cn = context.getPackageManager().getHomeActivities(new ArrayList<>());
+        if (cn == null) {
+            return null;
+        }
+        return cn.getPackageName();
+    }
+
+    /** Returns true if the app for the given package name is a system app for this device */
+    private boolean isSystemApp(Context context, String packageName) {
+        try {
+            ApplicationInfo ai = context.getPackageManager().getApplicationInfo(packageName,
+                    PackageManager.GET_META_DATA);
+            return ai != null && ((ai.flags & SYSTEM_APP_MASK) != 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    private void showNotification(Context context, int resId) {
+        final CharSequence message = context.getResources().getString(resId);
+        if (DEBUG) {
+            Log.d(TAG, "showNotification: message=" + message);
+        }
+
+        final Notification.Builder builder =
+                new Notification.Builder(mContext, NotificationChannels.ALERTS)
+                        .setContentText(message)
+                        .setStyle(new Notification.BigTextStyle())
+                        .setSmallIcon(R.drawable.ic_info)
+                        .setAutoCancel(true)
+                        .setContentIntent(PendingIntent.getActivity(context, 0, new Intent(), 0));
+        context.getSystemService(NotificationManager.class).notify(TAG, 0, builder.build());
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("NavigationModeController:");
@@ -299,6 +536,12 @@
         }
         pw.println("  defaultOverlays=" + defaultOverlays);
         dumpAssetPaths(mCurrentUserContext);
+
+        pw.println("  defaultLauncher=" + mLastDefaultLauncher);
+        boolean previouslySwitchedFromGestureNav = mCurrentUserContext
+                .getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
+                .getBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false);
+        pw.println("  previouslySwitchedFromGestureNav=" + previouslySwitchedFromGestureNav);
     }
 
     private void dumpAssetPaths(Context context) {
@@ -308,27 +551,4 @@
             Log.d(TAG, "    " + a.getAssetPath());
         }
     }
-
-    private void switchFromGestureNavModeIfNotSupportedByDefaultLauncher() {
-        if (getCurrentInteractionMode(mCurrentUserContext) == NAV_BAR_MODE_GESTURAL
-                && !isGestureNavSupportedByDefaultLauncher(mCurrentUserContext)) {
-            setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
-        }
-    }
-
-    private boolean isGestureNavSupportedByDefaultLauncher(Context context) {
-        final ComponentName cn = context.getPackageManager().getHomeActivities(new ArrayList<>());
-        if (cn == null) {
-            // There is no default home app set for the current user, don't make any changes yet.
-            return true;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "isGestureNavSupportedByDefaultLauncher: launcher=" + cn.getPackageName()
-                    + " contextUser=" + context.getUserId());
-        }
-
-        ComponentName recentsComponentName = ComponentName.unflattenFromString(context.getString(
-                com.android.internal.R.string.config_recentsComponentName));
-        return recentsComponentName.getPackageName().equals(cn.getPackageName());
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
index 4dbd854..4d69f77e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
@@ -28,8 +28,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.AlertingNotificationManager;
-import com.android.systemui.statusbar.AmbientPulseManager;
-import com.android.systemui.statusbar.AmbientPulseManager.OnAmbientChangedListener;
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -48,13 +46,13 @@
 import javax.inject.Singleton;
 
 /**
- * A helper class dealing with the alert interactions between {@link NotificationGroupManager},
- * {@link HeadsUpManager}, {@link AmbientPulseManager}. In particular, this class deals with keeping
+ * A helper class dealing with the alert interactions between {@link NotificationGroupManager} and
+ * {@link HeadsUpManager}. In particular, this class deals with keeping
  * the correct notification in a group alerting based off the group suppression.
  */
 @Singleton
 public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedListener,
-        OnAmbientChangedListener, StateListener {
+        StateListener {
 
     private static final long ALERT_TRANSFER_TIMEOUT = 300;
 
@@ -70,8 +68,6 @@
     private final ArrayMap<String, PendingAlertInfo> mPendingAlerts = new ArrayMap<>();
 
     private HeadsUpManager mHeadsUpManager;
-    private final AmbientPulseManager mAmbientPulseManager =
-            Dependency.get(AmbientPulseManager.class);
     private final NotificationGroupManager mGroupManager =
             Dependency.get(NotificationGroupManager.class);
 
@@ -144,10 +140,9 @@
 
         @Override
         public void onGroupSuppressionChanged(NotificationGroup group, boolean suppressed) {
-            AlertingNotificationManager alertManager = getActiveAlertManager();
             if (suppressed) {
-                if (alertManager.isAlerting(group.summary.key)) {
-                    handleSuppressedSummaryAlerted(group.summary, alertManager);
+                if (mHeadsUpManager.isAlerting(group.summary.key)) {
+                    handleSuppressedSummaryAlerted(group.summary, mHeadsUpManager);
                 }
             } else {
                 // Group summary can be null if we are no longer suppressed because the summary was
@@ -160,8 +155,8 @@
                 // Group is no longer suppressed. We should check if we need to transfer the alert
                 // back to the summary now that it's no longer suppressed.
                 if (groupAlertEntry.mAlertSummaryOnNextAddition) {
-                    if (!alertManager.isAlerting(group.summary.key)) {
-                        alertNotificationWhenPossible(group.summary, alertManager);
+                    if (!mHeadsUpManager.isAlerting(group.summary.key)) {
+                        alertNotificationWhenPossible(group.summary, mHeadsUpManager);
                     }
                     groupAlertEntry.mAlertSummaryOnNextAddition = false;
                 } else {
@@ -172,11 +167,6 @@
     };
 
     @Override
-    public void onAmbientStateChanged(NotificationEntry entry, boolean isAmbient) {
-        onAlertStateChanged(entry, isAmbient, mAmbientPulseManager);
-    }
-
-    @Override
     public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
         onAlertStateChanged(entry, isHeadsUp, mHeadsUpManager);
     }
@@ -208,11 +198,10 @@
             PendingAlertInfo alertInfo = mPendingAlerts.remove(entry.key);
             if (alertInfo != null) {
                 if (alertInfo.isStillValid()) {
-                    alertNotificationWhenPossible(entry, getActiveAlertManager());
+                    alertNotificationWhenPossible(entry, mHeadsUpManager);
                 } else {
                     // The transfer is no longer valid. Free the content.
-                    entry.getRow().freeContentViewWhenSafe(
-                            alertInfo.mAlertManager.getContentFlag());
+                    entry.getRow().freeContentViewWhenSafe(mHeadsUpManager.getContentFlag());
                 }
             }
         }
@@ -354,7 +343,6 @@
         if (SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime
                 < ALERT_TRANSFER_TIMEOUT) {
             NotificationEntry summary = groupAlertEntry.mGroup.summary;
-            AlertingNotificationManager alertManager = getActiveAlertManager();
 
             if (!onlySummaryAlerts(summary)) {
                 return;
@@ -369,9 +357,9 @@
             boolean releasedChild = false;
             for (int i = 0; i < children.size(); i++) {
                 NotificationEntry entry = children.get(i);
-                if (onlySummaryAlerts(entry) && alertManager.isAlerting(entry.key)) {
+                if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.key)) {
                     releasedChild = true;
-                    alertManager.removeNotification(entry.key, true /* releaseImmediately */);
+                    mHeadsUpManager.removeNotification(entry.key, true /* releaseImmediately */);
                 }
                 if (mPendingAlerts.containsKey(entry.key)) {
                     // This is the child that would've been removed if it was inflated.
@@ -379,10 +367,10 @@
                     mPendingAlerts.get(entry.key).mAbortOnInflation = true;
                 }
             }
-            if (releasedChild && !alertManager.isAlerting(summary.key)) {
+            if (releasedChild && !mHeadsUpManager.isAlerting(summary.key)) {
                 boolean notifyImmediately = (numChildren - numPendingChildren) > 1;
                 if (notifyImmediately) {
-                    alertNotificationWhenPossible(summary, alertManager);
+                    alertNotificationWhenPossible(summary, mHeadsUpManager);
                 } else {
                     // Should wait until the pending child inflates before alerting.
                     groupAlertEntry.mAlertSummaryOnNextAddition = true;
@@ -403,7 +391,7 @@
             @NonNull AlertingNotificationManager alertManager) {
         @InflationFlag int contentFlag = alertManager.getContentFlag();
         if (!entry.getRow().isInflationFlagSet(contentFlag)) {
-            mPendingAlerts.put(entry.key, new PendingAlertInfo(entry, alertManager));
+            mPendingAlerts.put(entry.key, new PendingAlertInfo(entry));
             entry.getRow().updateInflationFlag(contentFlag, true /* shouldInflate */);
             entry.getRow().inflateViews();
             return;
@@ -415,10 +403,6 @@
         }
     }
 
-    private AlertingNotificationManager getActiveAlertManager() {
-        return mIsDozing ? mAmbientPulseManager : mHeadsUpManager;
-    }
-
     private boolean onlySummaryAlerts(NotificationEntry entry) {
         return entry.notification.getNotification().getGroupAlertBehavior()
                 == Notification.GROUP_ALERT_SUMMARY;
@@ -429,10 +413,6 @@
      * inflation completes.
      */
     private class PendingAlertInfo {
-        /**
-         * The alert manager when the transfer is initiated.
-         */
-        final AlertingNotificationManager mAlertManager;
 
         /**
          * The original notification when the transfer is initiated. This is used to determine if
@@ -450,10 +430,9 @@
          */
         boolean mAbortOnInflation;
 
-        PendingAlertInfo(NotificationEntry entry, AlertingNotificationManager alertManager) {
+        PendingAlertInfo(NotificationEntry entry) {
             mOriginalNotification = entry.notification;
             mEntry = entry;
-            mAlertManager = alertManager;
         }
 
         /**
@@ -466,10 +445,6 @@
                 // Notification is aborted due to the transfer being explicitly cancelled
                 return false;
             }
-            if (mAlertManager != getActiveAlertManager()) {
-                // Alert manager has changed
-                return false;
-            }
             if (mEntry.notification.getGroupKey() != mOriginalNotification.getGroupKey()) {
                 // Groups have changed
                 return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index cc8af3b..195870b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -24,8 +24,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.statusbar.AmbientPulseManager;
-import com.android.systemui.statusbar.AmbientPulseManager.OnAmbientChangedListener;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -46,8 +44,7 @@
  * A class to handle notifications and their corresponding groups.
  */
 @Singleton
-public class NotificationGroupManager implements OnHeadsUpChangedListener,
-        OnAmbientChangedListener, StateListener {
+public class NotificationGroupManager implements OnHeadsUpChangedListener, StateListener {
 
     private static final String TAG = "NotificationGroupManager";
     private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
@@ -55,12 +52,11 @@
     private int mBarState = -1;
     private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
     private HeadsUpManager mHeadsUpManager;
-    private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
     private boolean mIsUpdatingUnchangedGroup;
 
     @Inject
-    public NotificationGroupManager() {
-        Dependency.get(StatusBarStateController.class).addCallback(this);
+    public NotificationGroupManager(StatusBarStateController statusBarStateController) {
+        statusBarStateController.addCallback(this);
     }
 
     /**
@@ -439,23 +435,6 @@
     }
 
     @Override
-    public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
-    }
-
-    @Override
-    public void onHeadsUpPinned(NotificationEntry entry) {
-    }
-
-    @Override
-    public void onHeadsUpUnPinned(NotificationEntry entry) {
-    }
-
-    @Override
-    public void onAmbientStateChanged(NotificationEntry entry, boolean isAmbient) {
-        onAlertStateChanged(entry, isAmbient);
-    }
-
-    @Override
     public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
         onAlertStateChanged(entry, isHeadsUp);
     }
@@ -485,7 +464,7 @@
         if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) {
             return false;
         }
-        if (!mHeadsUpManager.isAlerting(entry.key) && !mAmbientPulseManager.isAlerting(entry.key)) {
+        if (mHeadsUpManager != null && !mHeadsUpManager.isAlerting(entry.key)) {
             return false;
         }
         return (sbn.getNotification().fullScreenIntent != null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index bb490f5..d2159ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -1,11 +1,10 @@
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.provider.Settings;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -14,23 +13,26 @@
 import androidx.annotation.NonNull;
 import androidx.collection.ArrayMap;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ContrastColorUtil;
-import com.android.internal.widget.ViewClippingUtil;
+import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
+import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationUtils;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.tuner.TunerService;
 
 import java.util.ArrayList;
 import java.util.Objects;
@@ -41,29 +43,22 @@
  * normally reserved for notifications.
  */
 public class NotificationIconAreaController implements DarkReceiver,
-        StatusBarStateController.StateListener {
+        StatusBarStateController.StateListener,
+        NotificationWakeUpCoordinator.WakeUpListener {
 
-    public static final String LOW_PRIORITY = "low_priority";
+    public static final String HIGH_PRIORITY = "high_priority";
+    private static final long AOD_ICONS_APPEAR_DURATION = 200;
 
     private final ContrastColorUtil mContrastColorUtil;
     private final NotificationEntryManager mEntryManager;
     private final Runnable mUpdateStatusBarIcons = this::updateStatusBarIcons;
     private final StatusBarStateController mStatusBarStateController;
     private final NotificationMediaManager mMediaManager;
-    @VisibleForTesting
-    final NotificationListener.NotificationSettingsListener mSettingsListener =
-            new NotificationListener.NotificationSettingsListener() {
-                @Override
-                public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
-                    if (NotificationUtils.useNewInterruptionModel(mContext)) {
-                        mShowLowPriority = !hideSilentStatusIcons;
-                        if (mNotificationScrollLayout != null) {
-                            updateStatusBarIcons();
-                        }
-                    }
-                }
-            };
+    private final NotificationWakeUpCoordinator mWakeUpCoordinator;
+    private final KeyguardBypassController mBypassController;
+    private final DozeParameters mDozeParameters;
 
+    private boolean mShowSilentOnLockscreen = true;
     private int mIconSize;
     private int mIconHPadding;
     private int mIconTint = Color.WHITE;
@@ -75,32 +70,22 @@
     private NotificationIconContainer mShelfIcons;
     protected View mCenteredIconArea;
     private NotificationIconContainer mCenteredIcon;
+    private NotificationIconContainer mAodIcons;
     private StatusBarIconView mCenteredIconView;
     private final Rect mTintArea = new Rect();
     private ViewGroup mNotificationScrollLayout;
     private Context mContext;
-    private boolean mFullyDark;
-    private boolean mShowLowPriority = true;
+    private int mAodIconAppearTranslation;
 
-    /**
-     * Ratio representing being awake or in ambient mode, where 1 is dark and 0 awake.
-     */
-    private float mDarkAmount;
-    /**
-     * Maximum translation to avoid burn in.
-     */
-    private int mBurnInOffset;
-    /**
-     * Height of the keyguard status bar (not the one after unlocking.)
-     */
-    private int mKeyguardStatusBarHeight;
-
-    private final ViewClippingUtil.ClippingParameters mClippingParameters =
-            view -> view instanceof StatusBarWindowView;
+    private boolean mAnimationsEnabled;
+    private int mAodIconTint;
+    private boolean mFullyHidden;
+    private boolean mAodIconsVisible;
 
     public NotificationIconAreaController(Context context, StatusBar statusBar,
             StatusBarStateController statusBarStateController,
-            NotificationListener notificationListener,
+            NotificationWakeUpCoordinator wakeUpCoordinator,
+            KeyguardBypassController keyguardBypassController,
             NotificationMediaManager notificationMediaManager) {
         mStatusBar = statusBar;
         mContrastColorUtil = ContrastColorUtil.getInstance(context);
@@ -109,9 +94,18 @@
         mStatusBarStateController = statusBarStateController;
         mStatusBarStateController.addCallback(this);
         mMediaManager = notificationMediaManager;
-        notificationListener.addNotificationSettingsListener(mSettingsListener);
+        mDozeParameters = DozeParameters.getInstance(mContext);
+        mWakeUpCoordinator = wakeUpCoordinator;
+        wakeUpCoordinator.addListener(this);
+        mBypassController = keyguardBypassController;
 
         initializeNotificationAreaViews(context);
+        reloadAodColor();
+
+        TunerService tunerService = Dependency.get(TunerService.class);
+        tunerService.addTunable((key, newValue) -> {
+            mShowSilentOnLockscreen = "1".equals(newValue);
+        }, Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS);
     }
 
     protected View inflateIconArea(LayoutInflater inflater) {
@@ -132,6 +126,24 @@
 
         mCenteredIconArea = layoutInflater.inflate(R.layout.center_icon_area, null);
         mCenteredIcon = mCenteredIconArea.findViewById(R.id.centeredIcon);
+
+        initAodIcons();
+    }
+
+    public void initAodIcons() {
+        boolean changed = mAodIcons != null;
+        if (changed) {
+            mAodIcons.setAnimationsEnabled(false);
+            mAodIcons.removeAllViews();
+        }
+        mAodIcons = mStatusBar.getStatusBarWindow().findViewById(
+                R.id.clock_notification_icon_container);
+        mAodIcons.setOnLockScreen(true);
+        updateAodIconsVisibility(false /* animate */);
+        updateAnimations();
+        if (changed) {
+            updateAodNotificationIcons();
+        }
     }
 
     public void setupShelf(NotificationShelf shelf) {
@@ -154,6 +166,10 @@
             View child = mCenteredIcon.getChildAt(i);
             child.setLayoutParams(params);
         }
+        for (int i = 0; i < mAodIcons.getChildCount(); i++) {
+            View child = mAodIcons.getChildAt(i);
+            child.setLayoutParams(params);
+        }
     }
 
     @NonNull
@@ -166,9 +182,8 @@
         Resources res = context.getResources();
         mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
         mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
-        mBurnInOffset = res.getDimensionPixelSize(R.dimen.default_burn_in_prevention_offset);
-        mKeyguardStatusBarHeight = res
-                .getDimensionPixelSize(R.dimen.status_bar_header_height_keyguard);
+        mAodIconAppearTranslation = res.getDimensionPixelSize(
+                R.dimen.shelf_appear_translation);
     }
 
     /**
@@ -224,11 +239,16 @@
 
     protected boolean shouldShowNotificationIcon(NotificationEntry entry,
             boolean showAmbient, boolean showLowPriority, boolean hideDismissed,
-            boolean hideRepliedMessages, boolean hideCurrentMedia, boolean hideCenteredIcon) {
+            boolean hideRepliedMessages, boolean hideCurrentMedia, boolean hideCenteredIcon,
+            boolean hidePulsing, boolean onlyShowCenteredIcon) {
 
-        final boolean isCenteredNotificationIcon = entry.centeredIcon != null
+        final boolean isCenteredNotificationIcon = mCenteredIconView != null
+                && entry.centeredIcon != null
                 && Objects.equals(entry.centeredIcon, mCenteredIconView);
-        if (hideCenteredIcon == isCenteredNotificationIcon) {
+        if (onlyShowCenteredIcon) {
+            return isCenteredNotificationIcon;
+        }
+        if (hideCenteredIcon && isCenteredNotificationIcon && !entry.isRowHeadsUp()) {
             return false;
         }
         if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) {
@@ -253,7 +273,10 @@
             return false;
         }
         // showAmbient == show in shade but not shelf
-        if ((!showAmbient || mFullyDark) && entry.shouldSuppressStatusBar()) {
+        if (!showAmbient && entry.shouldSuppressStatusBar()) {
+            return false;
+        }
+        if (hidePulsing && entry.showingPulsing()) {
             return false;
         }
         return true;
@@ -266,6 +289,7 @@
         updateStatusBarIcons();
         updateShelfIcons();
         updateCenterIcon();
+        updateAodNotificationIcons();
 
         applyNotificationIconsTint();
     }
@@ -273,36 +297,49 @@
     private void updateShelfIcons() {
         updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons,
                 true /* showAmbient */,
-                !mFullyDark /* showLowPriority */,
+                true /* showLowPriority */,
                 false /* hideDismissed */,
-                mFullyDark /* hideRepliedMessages */,
-                mFullyDark /* hideCurrentMedia */,
-                true /* hide centered icon */);
+                false /* hideRepliedMessages */,
+                false /* hideCurrentMedia */,
+                false /* hide centered icon */,
+                false /* hidePulsing */,
+                false /* onlyShowCenteredIcon */);
     }
 
     public void updateStatusBarIcons() {
         updateIconsForLayout(entry -> entry.icon, mNotificationIcons,
                 false /* showAmbient */,
-                mShowLowPriority /* showLowPriority */,
+                true /* showLowPriority */,
                 true /* hideDismissed */,
                 true /* hideRepliedMessages */,
                 false /* hideCurrentMedia */,
-                true /* hide centered icon */);
+                true /* hide centered icon */,
+                false /* hidePulsing */,
+                false /* onlyShowCenteredIcon */);
     }
 
     private void updateCenterIcon() {
         updateIconsForLayout(entry -> entry.centeredIcon, mCenteredIcon,
                 false /* showAmbient */,
-                !mFullyDark /* showLowPriority */,
+                true /* showLowPriority */,
                 false /* hideDismissed */,
                 false /* hideRepliedMessages */,
-                mFullyDark /* hideCurrentMedia */,
-                false /* hide centered icon */);
+                false /* hideCurrentMedia */,
+                false /* hide centered icon */,
+                false /* hidePulsing */,
+                true/* onlyShowCenteredIcon */);
     }
 
-    @VisibleForTesting
-    boolean shouldShouldLowPriorityIcons() {
-        return mShowLowPriority;
+    public void updateAodNotificationIcons() {
+        updateIconsForLayout(entry -> entry.aodIcon, mAodIcons,
+                false /* showAmbient */,
+                mShowSilentOnLockscreen /* showLowPriority */,
+                true /* hideDismissed */,
+                true /* hideRepliedMessages */,
+                true /* hideCurrentMedia */,
+                true /* hide centered icon */,
+                mBypassController.getBypassEnabled() /* hidePulsing */,
+                false /* onlyShowCenteredIcon */);
     }
 
     /**
@@ -313,11 +350,12 @@
      * @param showAmbient should ambient notification icons be shown
      * @param hideDismissed should dismissed icons be hidden
      * @param hideRepliedMessages should messages that have been replied to be hidden
+     * @param hidePulsing should pulsing notifications be hidden
      */
     private void updateIconsForLayout(Function<NotificationEntry, StatusBarIconView> function,
             NotificationIconContainer hostLayout, boolean showAmbient, boolean showLowPriority,
             boolean hideDismissed, boolean hideRepliedMessages, boolean hideCurrentMedia,
-            boolean hideCenteredIcon) {
+            boolean hideCenteredIcon, boolean hidePulsing, boolean onlyShowCenteredIcon) {
         ArrayList<StatusBarIconView> toShow = new ArrayList<>(
                 mNotificationScrollLayout.getChildCount());
 
@@ -327,7 +365,8 @@
             if (view instanceof ExpandableNotificationRow) {
                 NotificationEntry ent = ((ExpandableNotificationRow) view).getEntry();
                 if (shouldShowNotificationIcon(ent, showAmbient, showLowPriority, hideDismissed,
-                        hideRepliedMessages, hideCurrentMedia, hideCenteredIcon)) {
+                        hideRepliedMessages, hideCurrentMedia, hideCenteredIcon, hidePulsing,
+                        onlyShowCenteredIcon)) {
                     StatusBarIconView iconView = function.apply(ent);
                     if (iconView != null) {
                         toShow.add(iconView);
@@ -441,6 +480,8 @@
                 iv.executeOnLayout(() -> updateTintForIcon(iv, mCenteredIconTint));
             }
         }
+
+        updateAodIconColors();
     }
 
     private void updateTintForIcon(StatusBarIconView v, int tint) {
@@ -454,12 +495,6 @@
         v.setDecorColor(tint);
     }
 
-    public void setDark(boolean dark) {
-        mNotificationIcons.setDark(dark, false, 0);
-        mShelfIcons.setDark(dark, false, 0);
-        mCenteredIcon.setDark(dark, false, 0);
-    }
-
     /**
      * Shows the icon view given in the center.
      */
@@ -479,53 +514,120 @@
         mNotificationIcons.setIsolatedIconLocation(iconDrawingRect, requireStateUpdate);
     }
 
-    /**
-     * Moves icons whenever the device wakes up in AOD, to avoid burn in.
-     */
-    public void dozeTimeTick() {
-        if (mNotificationIcons.getVisibility() != View.VISIBLE) {
-            return;
-        }
-
-        if (mDarkAmount == 0 && !mStatusBarStateController.isDozing()) {
-            mNotificationIcons.setTranslationX(0);
-            mNotificationIcons.setTranslationY(0);
-            mCenteredIcon.setTranslationX(0);
-            mCenteredIcon.setTranslationY(0);
-            return;
-        }
-
-        int yOffset = (mKeyguardStatusBarHeight - getHeight()) / 2;
-        int translationX = getBurnInOffset(mBurnInOffset, true /* xAxis */);
-        int translationY = getBurnInOffset(mBurnInOffset, false /* xAxis */) + yOffset;
-        mNotificationIcons.setTranslationX(translationX);
-        mNotificationIcons.setTranslationY(translationY);
-        mCenteredIcon.setTranslationX(translationX);
-        mCenteredIcon.setTranslationY(translationY);
-    }
-
     @Override
     public void onDozingChanged(boolean isDozing) {
-        dozeTimeTick();
+        boolean animate = mDozeParameters.getAlwaysOn()
+                && !mDozeParameters.getDisplayNeedsBlanking();
+        mAodIcons.setDozing(isDozing, animate, 0);
+    }
+
+    public void setAnimationsEnabled(boolean enabled) {
+        mAnimationsEnabled = enabled;
+        updateAnimations();
     }
 
     @Override
-    public void onDozeAmountChanged(float linear, float eased) {
-        boolean wasOrIsAwake = mDarkAmount == 0 || linear == 0;
-        boolean wasOrIsDozing = mDarkAmount == 1 || linear == 1;
-        mDarkAmount = linear;
-        if (wasOrIsAwake) {
-            ViewClippingUtil.setClippingDeactivated(mNotificationIcons, mDarkAmount != 0,
-                    mClippingParameters);
-        }
-        if (wasOrIsAwake || wasOrIsDozing) {
-            dozeTimeTick();
-        }
+    public void onStateChanged(int newState) {
+        updateAodIconsVisibility(false /* animate */);
+        updateAnimations();
+    }
 
-        boolean fullyDark = mDarkAmount == 1f;
-        if (mFullyDark != fullyDark) {
-            mFullyDark = fullyDark;
-            updateShelfIcons();
+    private void updateAnimations() {
+        boolean inShade = mStatusBarStateController.getState() == StatusBarState.SHADE;
+        mAodIcons.setAnimationsEnabled(mAnimationsEnabled && !inShade);
+        mCenteredIcon.setAnimationsEnabled(mAnimationsEnabled && inShade);
+        mNotificationIcons.setAnimationsEnabled(mAnimationsEnabled && inShade);
+    }
+
+    public void onThemeChanged() {
+        reloadAodColor();
+        updateAodIconColors();
+    }
+
+    public void appearAodIcons() {
+        DozeParameters dozeParameters = DozeParameters.getInstance(mContext);
+        if (dozeParameters.shouldControlScreenOff()) {
+            mAodIcons.setTranslationY(-mAodIconAppearTranslation);
+            mAodIcons.setAlpha(0);
+            mAodIcons.animate()
+                    .setInterpolator(Interpolators.DECELERATE_QUINT)
+                    .translationY(0)
+                    .setDuration(AOD_ICONS_APPEAR_DURATION)
+                    .start();
+            mAodIcons.animate()
+                    .alpha(1)
+                    .setInterpolator(Interpolators.LINEAR)
+                    .setDuration(AOD_ICONS_APPEAR_DURATION)
+                    .start();
+        }
+    }
+
+    private void reloadAodColor() {
+        mAodIconTint = Utils.getColorAttrDefaultColor(mContext,
+                R.attr.wallpaperTextColor);
+    }
+    private void updateAodIconColors() {
+        for (int i = 0; i < mAodIcons.getChildCount(); i++) {
+            final StatusBarIconView iv = (StatusBarIconView) mAodIcons.getChildAt(i);
+            if (iv.getWidth() != 0) {
+                updateTintForIcon(iv, mAodIconTint);
+            } else {
+                iv.executeOnLayout(() -> updateTintForIcon(iv, mAodIconTint));
+            }
+        }
+    }
+
+    @Override
+    public void onFullyHiddenChanged(boolean fullyHidden) {
+        boolean animate = true;
+        if (!mBypassController.getBypassEnabled()) {
+            animate = mDozeParameters.getAlwaysOn() && !mDozeParameters.getDisplayNeedsBlanking();
+            // We only want the appear animations to happen when the notifications get fully hidden,
+            // since otherwise the unhide animation overlaps
+            animate &= fullyHidden;
+        }
+        updateAodIconsVisibility(animate);
+        updateAodNotificationIcons();
+    }
+
+    @Override
+    public void onPulseExpansionChanged(boolean expandingChanged) {
+        if (expandingChanged) {
+            updateAodIconsVisibility(true /* animate */);
+        }
+    }
+
+    private void updateAodIconsVisibility(boolean animate) {
+        boolean visible = mBypassController.getBypassEnabled()
+                || mWakeUpCoordinator.getNotificationsFullyHidden();
+        if (mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
+            visible = false;
+        }
+        if (visible && mWakeUpCoordinator.isPulseExpanding()) {
+            visible = false;
+        }
+        if (mAodIconsVisible != visible) {
+            mAodIconsVisible = visible;
+            mAodIcons.animate().cancel();
+            if (animate) {
+                boolean wasFullyInvisible = mAodIcons.getVisibility() != View.VISIBLE;
+                if (mAodIconsVisible) {
+                    if (wasFullyInvisible) {
+                        // No fading here, let's just appear the icons instead!
+                        mAodIcons.setVisibility(View.VISIBLE);
+                        mAodIcons.setAlpha(1.0f);
+                        appearAodIcons();
+                    } else {
+                        // We were fading out, let's fade in instead
+                        CrossFadeHelper.fadeIn(mAodIcons);
+                    }
+                } else {
+                    CrossFadeHelper.fadeOut(mAodIcons);
+                }
+            } else {
+                mAodIcons.setAlpha(1.0f);
+                mAodIcons.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 009afca..a53ce9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -128,7 +128,7 @@
         }
     }.setDuration(CONTENT_FADE_DURATION);
 
-    private static final int MAX_VISIBLE_ICONS_WHEN_DARK = 5;
+    private static final int MAX_VISIBLE_ICONS_ON_LOCK = 5;
     public static final int MAX_STATIC_ICONS = 4;
     private static final int MAX_DOTS = 1;
 
@@ -141,7 +141,8 @@
     private int mActualLayoutWidth = NO_VALUE;
     private float mActualPaddingEnd = NO_VALUE;
     private float mActualPaddingStart = NO_VALUE;
-    private boolean mDark;
+    private boolean mDozing;
+    private boolean mOnLockScreen;
     private boolean mChangingViewPositions;
     private int mAddAnimationStartIndex = -1;
     private int mCannedAnimationStartIndex = -1;
@@ -288,7 +289,7 @@
             }
         }
         if (child instanceof StatusBarIconView) {
-            ((StatusBarIconView) child).setDark(mDark, false, 0);
+            ((StatusBarIconView) child).setDozing(mDozing, false, 0);
         }
     }
 
@@ -315,10 +316,11 @@
     @Override
     public void onViewRemoved(View child) {
         super.onViewRemoved(child);
+
         if (child instanceof StatusBarIconView) {
             boolean isReplacingIcon = isReplacingIcon(child);
             final StatusBarIconView icon = (StatusBarIconView) child;
-            if (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
+            if (areAnimationsEnabled(icon) && icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
                     && child.getVisibility() == VISIBLE && isReplacingIcon) {
                 int animationStartIndex = findFirstViewIndexAfter(icon.getTranslationX());
                 if (mAddAnimationStartIndex < 0) {
@@ -329,7 +331,7 @@
             }
             if (!mChangingViewPositions) {
                 mIconStates.remove(child);
-                if (!isReplacingIcon) {
+                if (areAnimationsEnabled(icon) && !isReplacingIcon) {
                     addTransientView(icon, 0);
                     boolean isIsolatedIcon = child == mIsolatedIcon;
                     icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, true /* animate */,
@@ -340,6 +342,10 @@
         }
     }
 
+    private boolean areAnimationsEnabled(StatusBarIconView icon) {
+        return mAnimationsEnabled || icon == mIsolatedIcon;
+    }
+
     /**
      * Finds the first view with a translation bigger then a given value
      */
@@ -372,7 +378,7 @@
         float translationX = getActualPaddingStart();
         int firstOverflowIndex = -1;
         int childCount = getChildCount();
-        int maxVisibleIcons = mDark ? MAX_VISIBLE_ICONS_WHEN_DARK :
+        int maxVisibleIcons = mOnLockScreen ? MAX_VISIBLE_ICONS_ON_LOCK :
                 mIsStaticLayout ? MAX_STATIC_ICONS : childCount;
         float layoutEnd = getLayoutEnd();
         float overflowStart = getMaxOverflowStart();
@@ -389,8 +395,8 @@
             boolean forceOverflow = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
                     && iconState.iconAppearAmount > 0.0f || i >= maxVisibleIcons;
             boolean noOverflowAfter = i == childCount - 1;
-            float drawingScale = mDark && view instanceof StatusBarIconView
-                    ? ((StatusBarIconView) view).getIconScaleFullyDark()
+            float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
+                    ? ((StatusBarIconView) view).getIconScaleIncreased()
                     : 1f;
             if (mOpenedAmount != 0.0f) {
                 noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow;
@@ -437,7 +443,7 @@
             mFirstVisibleIconState = mIconStates.get(getChildAt(0));
         }
 
-        boolean center = mDark;
+        boolean center = mOnLockScreen;
         if (center && translationX < getLayoutEnd()) {
             float initialTranslation =
                     mFirstVisibleIconState == null ? 0 : mFirstVisibleIconState.xTranslation;
@@ -557,13 +563,13 @@
         mChangingViewPositions = changingViewPositions;
     }
 
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mDark = dark;
+    public void setDozing(boolean dozing, boolean fade, long delay) {
+        mDozing = dozing;
         mDisallowNextAnimation |= !fade;
         for (int i = 0; i < getChildCount(); i++) {
             View view = getChildAt(i);
             if (view instanceof StatusBarIconView) {
-                ((StatusBarIconView) view).setDark(dark, fade, delay);
+                ((StatusBarIconView) view).setDozing(dozing, fade, delay);
             }
         }
     }
@@ -667,6 +673,10 @@
         }
     }
 
+    public void setOnLockScreen(boolean onLockScreen) {
+        mOnLockScreen = onLockScreen;
+    }
+
     public class IconState extends ViewState {
         public static final int NO_VALUE = NotificationIconContainer.NO_VALUE;
         public float iconAppearAmount = 1.0f;
@@ -689,7 +699,7 @@
                 StatusBarIconView icon = (StatusBarIconView) view;
                 boolean animate = false;
                 AnimationProperties animationProperties = null;
-                boolean animationsAllowed = mAnimationsEnabled && !mDisallowNextAnimation
+                boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation
                         && !noAnimations;
                 if (animationsAllowed) {
                     if (justAdded || justReplaced) {
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 b3cbf08..971a7ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -38,6 +38,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.PowerManager;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -56,11 +57,11 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardClockSwitch;
 import com.android.keyguard.KeyguardStatusView;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.FalsingManager;
@@ -113,7 +114,8 @@
         KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener,
         OnHeadsUpChangedListener, QS.HeightListener, ZenModeController.Callback,
         ConfigurationController.ConfigurationListener, StateListener,
-        PulseExpansionHandler.ExpansionCallback, DynamicPrivacyController.Listener {
+        PulseExpansionHandler.ExpansionCallback, DynamicPrivacyController.Listener,
+        NotificationWakeUpCoordinator.WakeUpListener {
 
     private static final boolean DEBUG = false;
 
@@ -146,6 +148,15 @@
 
     private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties()
             .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+    private static final AnimatableProperty KEYGUARD_HEADS_UP_SHOWING_AMOUNT
+            = AnimatableProperty.from("KEYGUARD_HEADS_UP_SHOWING_AMOUNT",
+            NotificationPanelView::setKeyguardHeadsUpShowingAmount,
+            NotificationPanelView::getKeyguardHeadsUpShowingAmount,
+            R.id.keyguard_hun_animator_tag,
+            R.id.keyguard_hun_animator_end_tag,
+            R.id.keyguard_hun_animator_start_tag);
+    private static final AnimationProperties KEYGUARD_HUN_PROPERTIES =
+            new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
 
     private final InjectionInflationController mInjectionInflationController;
     private final PowerManager mPowerManager;
@@ -153,6 +164,7 @@
     private final NotificationWakeUpCoordinator mWakeUpCoordinator;
     private final PulseExpansionHandler mPulseExpansionHandler;
     private final KeyguardBypassController mKeyguardBypassController;
+    private final KeyguardUpdateMonitor mUpdateMonitor;
 
     @VisibleForTesting
     protected KeyguardAffordanceHelper mAffordanceHelper;
@@ -213,6 +225,8 @@
     private int mNotificationsHeaderCollideDistance;
     private int mUnlockMoveDistance;
     private float mEmptyDragAmount;
+    private float mDownX;
+    private float mDownY;
 
     private final KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
             new KeyguardClockPositionAlgorithm();
@@ -277,6 +291,12 @@
     private boolean mBlockingExpansionForCurrentTouch;
 
     /**
+     * Following variables maintain state of events when input focus transfer may occur.
+     */
+    private boolean mExpectingSynthesizedDown; // expecting to see synthesized DOWN event
+    private boolean mLastEventSynthesizedDown; // last event was synthesized DOWN event
+
+    /**
      * Current dark amount that follows regular interpolation curve of animation.
      */
     private float mInterpolatedDarkAmount;
@@ -304,6 +324,8 @@
     private int mCurrentPanelAlpha;
     private final Paint mAlphaPaint = new Paint();
     private Runnable mPanelAlphaEndAction;
+    private float mBottomAreaShadeAlpha;
+    private final ValueAnimator mBottomAreaShadeAlphaAnimator;
     private AnimatorListenerAdapter mAnimatorListenerAdapter = new AnimatorListenerAdapter() {
         @Override
         public void onAnimationEnd(Animator animation) {
@@ -345,6 +367,13 @@
     private int mThemeResId;
     private KeyguardIndicationController mKeyguardIndicationController;
     private Consumer<Boolean> mAffordanceLaunchListener;
+    private int mShelfHeight;
+    private Runnable mOnReinflationListener;
+    private int mDarkIconSize;
+    private int mHeadsUpInset;
+    private boolean mHeadsUpPinnedMode;
+    private float mKeyguardHeadsUpShowingAmount = 0.0f;
+    private boolean mShowingKeyguardHeadsUp;
 
     @Inject
     public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
@@ -352,11 +381,12 @@
             NotificationWakeUpCoordinator coordinator,
             PulseExpansionHandler pulseExpansionHandler,
             DynamicPrivacyController dynamicPrivacyController,
-            KeyguardBypassController bypassController) {
+            KeyguardBypassController bypassController,
+            FalsingManager falsingManager) {
         super(context, attrs);
         setWillNotDraw(!DEBUG);
         mInjectionInflationController = injectionInflationController;
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = falsingManager;
         mPowerManager = context.getSystemService(PowerManager.class);
         mWakeUpCoordinator = coordinator;
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
@@ -366,9 +396,23 @@
         mCommandQueue = getComponent(context, CommandQueue.class);
         mDisplayId = context.getDisplayId();
         mPulseExpansionHandler = pulseExpansionHandler;
+        pulseExpansionHandler.setPulseExpandAbortListener(() -> {
+            if (mQs != null) {
+                mQs.animateHeaderSlidingOut();
+            }
+        });
         mThemeResId = context.getThemeResId();
         mKeyguardBypassController = bypassController;
+        mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
         dynamicPrivacyController.addListener(this);
+
+        mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0);
+        mBottomAreaShadeAlphaAnimator.addUpdateListener(animation -> {
+            mBottomAreaShadeAlpha = (float) animation.getAnimatedValue();
+            updateKeyguardBottomAreaAlpha();
+        });
+        mBottomAreaShadeAlphaAnimator.setDuration(160);
+        mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
     }
 
     /**
@@ -408,6 +452,16 @@
         mWakeUpCoordinator.setStackScroller(mNotificationStackScroller);
         mQsFrame = findViewById(R.id.qs_frame);
         mPulseExpansionHandler.setUp(mNotificationStackScroller, this, mShadeController);
+        mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
+            @Override
+            public void onPulseExpansionChanged(boolean expandingChanged) {
+                if (mKeyguardBypassController.getBypassEnabled()) {
+                    // Position the notifications while dragging down while pulsing
+                    requestScrollerTopPaddingUpdate(false /* animate */);
+                    updateQSPulseExpansion();
+                }
+            }
+        });
     }
 
     @Override
@@ -452,6 +506,13 @@
                 R.dimen.keyguard_indication_bottom_padding);
         mQsNotificationTopPadding = getResources().getDimensionPixelSize(
                 R.dimen.qs_notification_padding);
+        mShelfHeight = getResources().getDimensionPixelSize(R.dimen.notification_shelf_height);
+        mDarkIconSize = getResources().getDimensionPixelSize(
+                R.dimen.status_bar_icon_drawing_size_dark);
+        int statusbarHeight = getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_height);
+        mHeadsUpInset = statusbarHeight + getResources().getDimensionPixelSize(
+                R.dimen.heads_up_status_bar_padding);
     }
 
     /**
@@ -544,10 +605,13 @@
 
         setKeyguardStatusViewVisibility(mBarState, false, false);
         setKeyguardBottomAreaVisibility(mBarState, false);
+        if (mOnReinflationListener != null) {
+            mOnReinflationListener.run();
+        }
     }
 
     private void initBottomArea() {
-        mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
+        mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext(), mFalsingManager);
         mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
         mKeyguardBottomArea.setStatusBar(mStatusBar);
         mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
@@ -613,9 +677,10 @@
 
     private Rect calculateGestureExclusionRect() {
         Rect exclusionRect = null;
-        if (isFullyCollapsed()) {
+        Region touchableRegion = mHeadsUpManager.calculateTouchableRegion();
+        if (isFullyCollapsed() && touchableRegion != null) {
             // Note: The heads up manager also calculates the non-pinned touchable region
-            exclusionRect = mHeadsUpManager.calculateTouchableRegion();
+            exclusionRect = touchableRegion.getBounds();
         }
         return exclusionRect != null
                 ? exclusionRect
@@ -662,35 +727,40 @@
         boolean animateClock = animate || mAnimateNextPositionUpdate;
         int stackScrollerPadding;
         if (mBarState != StatusBarState.KEYGUARD) {
-            stackScrollerPadding = (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight
-                    + mQsNotificationTopPadding;
+            stackScrollerPadding = getUnlockedStackScrollerPadding();
         } else {
             int totalHeight = getHeight();
             int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
             int clockPreferredY = mKeyguardStatusView.getClockPreferredY(totalHeight);
+            boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
+            final boolean hasVisibleNotifications =
+                    !bypassEnabled && mNotificationStackScroller.getVisibleNotificationCount() != 0;
+            mKeyguardStatusView.setHasVisibleNotifications(hasVisibleNotifications);
             mClockPositionAlgorithm.setup(
                     mStatusBarMinHeight,
                     totalHeight - bottomPadding,
                     mNotificationStackScroller.getIntrinsicContentHeight(),
                     getExpandedFraction(),
                     totalHeight,
-                    mKeyguardStatusView.getHeight(),
+                    (int) (mKeyguardStatusView.getHeight()
+                            - mShelfHeight / 2.0f - mDarkIconSize / 2.0f),
                     clockPreferredY,
                     hasCustomClock(),
-                    mNotificationStackScroller.getVisibleNotificationCount() != 0,
+                    hasVisibleNotifications,
                     mInterpolatedDarkAmount,
                     mEmptyDragAmount,
-                    mKeyguardBypassController.getBypassEnabled());
+                    bypassEnabled,
+                    getUnlockedStackScrollerPadding());
             mClockPositionAlgorithm.run(mClockPositionResult);
             PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.X,
                     mClockPositionResult.clockX, CLOCK_ANIMATION_PROPERTIES, animateClock);
             PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.Y,
                     mClockPositionResult.clockY, CLOCK_ANIMATION_PROPERTIES, animateClock);
+            updateNotificationTranslucency();
             updateClock();
             stackScrollerPadding = mClockPositionResult.stackScrollerPaddingExpanded;
         }
         mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding);
-        mNotificationStackScroller.setAntiBurnInOffsetX(mClockPositionResult.clockX);
         mKeyguardBottomArea.setAntiBurnInOffsetX(mClockPositionResult.clockX);
 
         mStackScrollerMeasuringPass++;
@@ -700,6 +770,14 @@
     }
 
     /**
+     * @return the padding of the stackscroller when unlocked
+     */
+    private int getUnlockedStackScrollerPadding() {
+        return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight
+                + mQsNotificationTopPadding;
+    }
+
+    /**
      * @param maximum the maximum to return at most
      * @return the maximum keyguard notifications that can fit on the screen
      */
@@ -860,7 +938,7 @@
     protected void flingToHeight(float vel, boolean expand, float target,
             float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) {
         mHeadsUpTouchHelper.notifyFling(!expand);
-        setClosingWithAlphaFadeout(!expand && getFadeoutAlpha() == 1.0f);
+        setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f);
         super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
     }
 
@@ -881,7 +959,8 @@
             MetricsLogger.count(mContext, COUNTER_PANEL_OPEN_PEEK, 1);
             return true;
         }
-        if (mPulseExpansionHandler.onInterceptTouchEvent(event)) {
+        if (!shouldQuickSettingsIntercept(mDownX, mDownY, 0)
+                && mPulseExpansionHandler.onInterceptTouchEvent(event)) {
             return true;
         }
 
@@ -982,8 +1061,19 @@
             mOnlyAffordanceInThisMotion = false;
             mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
             mDozingOnDown = isDozing();
+            mDownX = event.getX();
+            mDownY = event.getY();
             mCollapsedOnDown = isFullyCollapsed();
             mListenForHeadsUp = mCollapsedOnDown && mHeadsUpManager.hasPinnedHeadsUp();
+            if (mExpectingSynthesizedDown) {
+                mLastEventSynthesizedDown = true;
+            } else {
+                // down but not synthesized motion event.
+                mLastEventSynthesizedDown = false;
+            }
+        } else {
+            // not down event at all.
+            mLastEventSynthesizedDown = false;
         }
     }
 
@@ -1049,13 +1139,20 @@
             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)) {
+        // When touch focus transfer happens, ACTION_DOWN->ACTION_UP may happen immediately
+        // without any ACTION_MOVE event.
+        // In such case, simply expand the panel instead of being stuck at the bottom bar.
+        if (mLastEventSynthesizedDown && event.getAction() == MotionEvent.ACTION_UP) {
+            expand(true /* animate */);
+        }
+        initDownStates(event);
+        if (!mIsExpanding && !shouldQuickSettingsIntercept(mDownX, mDownY, 0)
+                && mPulseExpansionHandler.onTouchEvent(event)) {
             // We're expanding all the other ones shouldn't get this anymore
             return true;
         }
@@ -1172,6 +1269,39 @@
         }
     }
 
+    /**
+     * Input focus transfer is about to happen.
+     */
+    public void startWaitingForOpenPanelGesture() {
+        if (!isFullyCollapsed()) {
+            return;
+        }
+        mExpectingSynthesizedDown = true;
+        onTrackingStarted();
+    }
+
+    /**
+     * Called when this view is no longer waiting for input focus transfer.
+     *
+     * There are two scenarios behind this function call. First, input focus transfer
+     * has successfully happened and this view already received synthetic DOWN event.
+     * (mExpectingSynthesizedDown == false). Do nothing.
+     *
+     * Second, before input focus transfer finished, user may have lifted finger
+     * in previous window and this window never received synthetic DOWN event.
+     * (mExpectingSynthesizedDown == true).
+     * In this case, we use the velocity to trigger fling event.
+     *
+     * @param velocity unit is in px / millis
+     */
+    public void stopWaitingForOpenPanelGesture(float velocity) {
+        if (mExpectingSynthesizedDown) {
+            mExpectingSynthesizedDown = false;
+            fling(velocity > 1f ? 1000f * velocity : 0, true /* animate */);
+            onTrackingStopped(false);
+        }
+    }
+
     @Override
     protected boolean flingExpands(float vel, float vectorVel, float x, float y) {
         boolean expands = super.flingExpands(vel, vectorVel, x, y);
@@ -1184,8 +1314,12 @@
     }
 
     @Override
-    protected boolean hasConflictingGestures() {
-        return mBarState != StatusBarState.SHADE;
+    protected boolean shouldGestureWaitForTouchSlop() {
+        if (mExpectingSynthesizedDown) {
+            mExpectingSynthesizedDown = false;
+            return false;
+        }
+        return isFullyCollapsed() || mBarState != StatusBarState.SHADE;
     }
 
     @Override
@@ -1326,6 +1460,8 @@
             mFalsingManager.setQsExpanded(expanded);
             mStatusBar.setQsExpanded(expanded);
             mNotificationContainerParent.setQsExpanded(expanded);
+            mPulseExpansionHandler.setQsExpanded(expanded);
+            mKeyguardBypassController.setQSExpanded(expanded);
         }
     }
 
@@ -1340,9 +1476,6 @@
 
         mBarState = statusBarState;
         mKeyguardShowing = keyguardShowing;
-        if (mQs != null) {
-            mQs.setKeyguardShowing(mKeyguardShowing);
-        }
 
         if (oldState == StatusBarState.KEYGUARD
                 && (goingToFullShade || statusBarState == StatusBarState.SHADE_LOCKED)) {
@@ -1353,6 +1486,7 @@
         } else if (oldState == StatusBarState.SHADE_LOCKED
                 && statusBarState == StatusBarState.KEYGUARD) {
             animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+            mNotificationStackScroller.resetScrollPosition();
             // Only animate header if the header is visible. If not, it will partially animate out
             // the top of QS
             if (!mQsExpanded) {
@@ -1367,14 +1501,27 @@
                 }
             }
         }
+        updateKeyguardStatusBarForHeadsUp();
         if (keyguardShowing) {
             updateDozingVisibilities(false /* animate */);
         }
-
+        // THe update needs to happen after the headerSlide in above, otherwise the translation
+        // would reset
+        updateQSPulseExpansion();
+        maybeAnimateBottomAreaAlpha();
         resetHorizontalPanelPosition();
         updateQsState();
     }
 
+    private void maybeAnimateBottomAreaAlpha() {
+        mBottomAreaShadeAlphaAnimator.cancel();
+        if (mBarState == StatusBarState.SHADE_LOCKED) {
+            mBottomAreaShadeAlphaAnimator.start();
+        } else {
+            mBottomAreaShadeAlpha = 1f;
+        }
+    }
+
     private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = new Runnable() {
         @Override
         public void run() {
@@ -1465,6 +1612,7 @@
         } else if (statusBarState == StatusBarState.KEYGUARD
                 || statusBarState == StatusBarState.SHADE_LOCKED) {
             mKeyguardBottomArea.setVisibility(View.VISIBLE);
+            mKeyguardBottomArea.setAlpha(1f);
         } else {
             mKeyguardBottomArea.setVisibility(View.GONE);
         }
@@ -1608,7 +1756,7 @@
             // padding on Keyguard, maxQsPadding denotes the top padding from the quick settings
             // panel. We need to take the maximum and linearly interpolate with the panel expansion
             // for a nice motion.
-            int maxNotificationPadding = mClockPositionResult.stackScrollerPadding;
+            int maxNotificationPadding = getKeyguardNotificationStaticPadding();
             int maxQsPadding = mQsMaxExpansionHeight + mQsNotificationTopPadding;
             int max = mBarState == StatusBarState.KEYGUARD
                     ? Math.max(maxNotificationPadding, maxQsPadding)
@@ -1616,11 +1764,12 @@
             return (int) MathUtils.lerp((float) mQsMinExpansionHeight, (float) max,
                     getExpandedFraction());
         } else if (mQsSizeChangeAnimator != null) {
-            return (int) mQsSizeChangeAnimator.getAnimatedValue();
+            return Math.max((int) mQsSizeChangeAnimator.getAnimatedValue(),
+                    getKeyguardNotificationStaticPadding());
         } else if (mKeyguardShowing) {
             // We can only do the smoother transition on Keyguard when we also are not collapsing
             // from a scrolled quick settings.
-            return MathUtils.lerp((float) mClockPositionResult.stackScrollerPadding,
+            return MathUtils.lerp((float) getKeyguardNotificationStaticPadding(),
                     (float) (mQsMaxExpansionHeight + mQsNotificationTopPadding),
                     getQsExpansionFraction());
         } else {
@@ -1628,8 +1777,43 @@
         }
     }
 
+    /**
+     * @return the topPadding of notifications when on keyguard not respecting quick settings
+     *         expansion
+     */
+    private int getKeyguardNotificationStaticPadding() {
+        if (!mKeyguardShowing) {
+            return 0;
+        }
+        if (!mKeyguardBypassController.getBypassEnabled()) {
+            return mClockPositionResult.stackScrollerPadding;
+        }
+        int collapsedPosition = mHeadsUpInset;
+        if (!mNotificationStackScroller.isPulseExpanding()) {
+            return collapsedPosition;
+        } else {
+            int expandedPosition = mClockPositionResult.stackScrollerPadding;
+            return (int) MathUtils.lerp(collapsedPosition, expandedPosition,
+                    mNotificationStackScroller.calculateAppearFractionBypass());
+        }
+    }
+
+
     protected void requestScrollerTopPaddingUpdate(boolean animate) {
         mNotificationStackScroller.updateTopPadding(calculateQsTopPadding(), animate);
+        if (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()) {
+            // update the position of the header
+            updateQsExpansion();
+        }
+    }
+
+
+    private void updateQSPulseExpansion() {
+        if (mQs != null) {
+            mQs.setShowCollapsedOnKeyguard(mKeyguardShowing
+                    && mKeyguardBypassController.getBypassEnabled()
+                    && mNotificationStackScroller.isPulseExpanding());
+        }
     }
 
     private void trackMovement(MotionEvent event) {
@@ -1760,8 +1944,16 @@
 
     @Override
     protected int getMaxPanelHeight() {
+        if (mKeyguardBypassController.getBypassEnabled() && mBarState == StatusBarState.KEYGUARD) {
+            return getMaxPanelHeightBypass();
+        } else {
+            return getMaxPanelHeightNonBypass();
+        }
+    }
+
+    private int getMaxPanelHeightNonBypass() {
         int min = mStatusBarMinHeight;
-        if (mBarState != StatusBarState.KEYGUARD
+        if (!(mBarState == StatusBarState.KEYGUARD)
                 && mNotificationStackScroller.getNotGoneChildCount() == 0) {
             int minHeight = (int) (mQsMinExpansionHeight + getOverExpansionAmount());
             min = Math.max(min, minHeight);
@@ -1777,6 +1969,15 @@
         return maxHeight;
     }
 
+    private int getMaxPanelHeightBypass() {
+        int position = mClockPositionAlgorithm.getExpandedClockPosition()
+                + mKeyguardStatusView.getHeight();
+        if (mNotificationStackScroller.getVisibleNotificationCount() != 0) {
+            position += mShelfHeight / 2.0f + mDarkIconSize / 2.0f;
+        }
+        return position;
+    }
+
     public boolean isInSettings() {
         return mQsExpanded;
     }
@@ -1891,15 +2092,19 @@
                 !mHeadsUpManager.hasPinnedHeadsUp()) {
             alpha = getFadeoutAlpha();
         }
-        if (mBarState == StatusBarState.KEYGUARD && !mHintAnimationRunning) {
+        if (mBarState == StatusBarState.KEYGUARD && !mHintAnimationRunning
+                && !mKeyguardBypassController.getBypassEnabled()) {
             alpha *= mClockPositionResult.clockAlpha;
         }
         mNotificationStackScroller.setAlpha(alpha);
     }
 
     private float getFadeoutAlpha() {
-        float alpha = (getNotificationsTopY() + mNotificationStackScroller.getFirstItemMinHeight())
-                / mQsMinExpansionHeight;
+        float alpha;
+        if (mQsMinExpansionHeight == 0) {
+            return 1.0f;
+        }
+        alpha = getExpandedHeight() / mQsMinExpansionHeight;
         alpha = Math.max(0, Math.min(alpha, 1));
         alpha = (float) Math.pow(alpha, 0.75);
         return alpha;
@@ -1926,11 +2131,25 @@
     }
 
     protected float getHeaderTranslation() {
-        if (mBarState == StatusBarState.KEYGUARD) {
-            return 0;
+        if (mBarState == StatusBarState.KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) {
+            return -mQs.getQsMinExpansionHeight();
         }
-        float translation = MathUtils.lerp(-mQsMinExpansionHeight, 0,
-                Math.min(1.0f, mNotificationStackScroller.getAppearFraction(mExpandedHeight)))
+        float appearAmount = mNotificationStackScroller.calculateAppearFraction(mExpandedHeight);
+        float startHeight = -mQsExpansionHeight;
+        if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()
+                && mNotificationStackScroller.isPulseExpanding()) {
+            if (!mPulseExpansionHandler.isExpanding()
+                    && !mPulseExpansionHandler.getLeavingLockscreen()) {
+                // If we aborted the expansion we need to make sure the header doesn't reappear
+                // again after the header has animated away
+                appearAmount = 0;
+            } else {
+                appearAmount = mNotificationStackScroller.calculateAppearFractionBypass();
+            }
+            startHeight = -mQs.getQsMinExpansionHeight();
+        }
+        float translation = MathUtils.lerp(startHeight, 0,
+                Math.min(1.0f, appearAmount))
                 + mExpandOffset;
         return Math.min(0, translation);
     }
@@ -1943,18 +2162,18 @@
         float alpha;
         if (mBarState == StatusBarState.KEYGUARD) {
 
-            // When on Keyguard, we hide the header as soon as the top card of the notification
-            // stack scroller is close enough (collision distance) to the bottom of the header.
-            alpha = getNotificationsTopY()
+            // When on Keyguard, we hide the header as soon as we expanded close enough to the
+            // header
+            alpha = getExpandedHeight()
                     /
                     (mKeyguardStatusBar.getHeight() + mNotificationsHeaderCollideDistance);
         } else {
 
             // In SHADE_LOCKED, the top card is already really close to the header. Hide it as
             // soon as we start translating the stack.
-            alpha = getNotificationsTopY() / mKeyguardStatusBar.getHeight();
+            alpha = getExpandedHeight() / mKeyguardStatusBar.getHeight();
         }
-        alpha = MathUtils.constrain(alpha, 0, 1);
+        alpha = MathUtils.saturate(alpha);
         alpha = (float) Math.pow(alpha, 0.75);
         return alpha;
     }
@@ -1966,6 +2185,7 @@
         float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
         float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
                 * mKeyguardStatusBarAnimateAlpha;
+        newAlpha *= 1.0f - mKeyguardHeadsUpShowingAmount;
         mKeyguardStatusBar.setAlpha(newAlpha);
         mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing ? VISIBLE : INVISIBLE);
     }
@@ -1981,6 +2201,7 @@
                         ? 0 : KeyguardBouncer.ALPHA_EXPANSION_THRESHOLD, 1f,
                 0f, 1f, getExpandedFraction());
         float alpha = Math.min(expansionAlpha, 1 - getQsExpansionFraction());
+        alpha *= mBottomAreaShadeAlpha;
         mKeyguardBottomArea.setAffordanceAlpha(alpha);
         mKeyguardBottomArea.setImportantForAccessibility(alpha == 0f
                 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
@@ -2004,13 +2225,6 @@
         mBigClockContainer.setAlpha(alpha);
     }
 
-    private float getNotificationsTopY() {
-        if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
-            return getExpandedHeight();
-        }
-        return mNotificationStackScroller.getNotificationsTopY();
-    }
-
     @Override
     protected void onExpandingStarted() {
         super.onExpandingStarted();
@@ -2497,10 +2711,14 @@
         switch (mBarState) {
             case StatusBarState.KEYGUARD:
                 if (!mDozingOnDown) {
-                    mLockscreenGestureLogger.write(
-                            MetricsEvent.ACTION_LS_HINT,
-                            0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
-                    startUnlockHintAnimation();
+                    if (mKeyguardBypassController.getBypassEnabled()) {
+                        mUpdateMonitor.requestFaceAuth();
+                    } else {
+                        mLockscreenGestureLogger.write(
+                                MetricsEvent.ACTION_LS_HINT,
+                                0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
+                        startUnlockHintAnimation();
+                    }
                 }
                 return true;
             case StatusBarState.SHADE_LOCKED:
@@ -2593,16 +2811,51 @@
                     mHeadsUpExistenceChangedRunnable);
         }
         updateGestureExclusionRect();
+        mHeadsUpPinnedMode = inPinnedMode;
+        updateHeadsUpVisibility();
+        updateKeyguardStatusBarForHeadsUp();
+    }
+
+    private void updateKeyguardStatusBarForHeadsUp() {
+        boolean showingKeyguardHeadsUp = mKeyguardShowing
+                && mHeadsUpAppearanceController.shouldBeVisible();
+        if (mShowingKeyguardHeadsUp != showingKeyguardHeadsUp) {
+            mShowingKeyguardHeadsUp = showingKeyguardHeadsUp;
+            if (mKeyguardShowing) {
+                PropertyAnimator.setProperty(this, KEYGUARD_HEADS_UP_SHOWING_AMOUNT,
+                        showingKeyguardHeadsUp ? 1.0f : 0.0f, KEYGUARD_HUN_PROPERTIES,
+                        true /* animate */);
+            } else {
+                PropertyAnimator.applyImmediately(this, KEYGUARD_HEADS_UP_SHOWING_AMOUNT, 0.0f);
+            }
+        }
+    }
+
+    private void setKeyguardHeadsUpShowingAmount(float amount) {
+        mKeyguardHeadsUpShowingAmount = amount;
+        updateHeaderKeyguardAlpha();
+    }
+
+    private float getKeyguardHeadsUpShowingAmount() {
+        return mKeyguardHeadsUpShowingAmount;
     }
 
     public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
         mHeadsUpAnimatingAway = headsUpAnimatingAway;
         mNotificationStackScroller.setHeadsUpAnimatingAway(headsUpAnimatingAway);
+        updateHeadsUpVisibility();
+    }
+
+    private void updateHeadsUpVisibility() {
+        ((PhoneStatusBarView) mBar).setHeadsUpVisible(mHeadsUpAnimatingAway || mHeadsUpPinnedMode);
     }
 
     @Override
     public void onHeadsUpPinned(NotificationEntry entry) {
-        mNotificationStackScroller.generateHeadsUpAnimation(entry.getHeadsUpAnimationView(), true);
+        if (!isOnKeyguard()) {
+            mNotificationStackScroller.generateHeadsUpAnimation(entry.getHeadsUpAnimationView(),
+                    true);
+        }
     }
 
     @Override
@@ -2611,7 +2864,7 @@
         // When we're unpinning the notification via active edge they remain heads-upped,
         // we need to make sure that an animation happens in this case, otherwise the notification
         // will stick to the top without any interaction.
-        if (isFullyCollapsed() && entry.isRowHeadsUp()) {
+        if (isFullyCollapsed() && entry.isRowHeadsUp() && !isOnKeyguard()) {
             mNotificationStackScroller.generateHeadsUpAnimation(
                     entry.getHeadsUpAnimationView(), false);
             entry.setHeadsUpIsVisible();
@@ -2678,7 +2931,7 @@
     }
 
     protected void setHorizontalPanelTranslation(float translation) {
-        mNotificationStackScroller.setHorizontalPanelTranslation(translation);
+        mNotificationStackScroller.setTranslationX(translation);
         mQsFrame.setTranslationX(translation);
         int size = mVerticalTranslationListener.size();
         for (int i = 0; i < size; i++) {
@@ -2690,6 +2943,10 @@
         if (mTracking) {
             mNotificationStackScroller.setExpandingVelocity(getCurrentExpandVelocity());
         }
+        if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()) {
+            // The expandedHeight is always the full panel Height when bypassing
+            expandedHeight = getMaxPanelHeightNonBypass();
+        }
         mNotificationStackScroller.setExpandedHeight(expandedHeight);
         updateKeyguardBottomAreaAlpha();
         updateBigClockAlpha();
@@ -2730,7 +2987,8 @@
 
     @Override
     protected boolean isPanelVisibleBecauseOfHeadsUp() {
-        return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway;
+        return (mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway)
+                && mBarState == StatusBarState.SHADE;
     }
 
     @Override
@@ -2755,7 +3013,6 @@
         // nor setting these flags, since the occluded state doesn't change anymore, hence it's
         // never reset.
         if (!isFullyCollapsed()) {
-            mLaunchingAffordance = true;
             setLaunchingAffordance(true);
         } else {
             animate = false;
@@ -2765,7 +3022,6 @@
     }
 
     public void onAffordanceLaunchEnded() {
-        mLaunchingAffordance = false;
         setLaunchingAffordance(false);
     }
 
@@ -2774,8 +3030,10 @@
      * launched via a camera gesture.
      */
     private void setLaunchingAffordance(boolean launchingAffordance) {
+        mLaunchingAffordance = launchingAffordance;
         getLeftIcon().setLaunchingAffordance(launchingAffordance);
         getRightIcon().setLaunchingAffordance(launchingAffordance);
+        mKeyguardBypassController.setLaunchingAffordance(launchingAffordance);
         if (mAffordanceLaunchListener != null) {
             mAffordanceLaunchListener.accept(launchingAffordance);
         }
@@ -2839,7 +3097,7 @@
             mQs.setPanelView(NotificationPanelView.this);
             mQs.setExpandClickListener(NotificationPanelView.this);
             mQs.setHeaderClickable(mQsExpansionEnabled);
-            mQs.setKeyguardShowing(mKeyguardShowing);
+            updateQSPulseExpansion();
             mQs.setOverscrolling(mStackScrollerOverscrolling);
 
             // recompute internal state when qspanel height changes
@@ -2891,6 +3149,10 @@
         mNotificationStackScroller.setDozing(mDozing, animate, wakeUpTouchLocation);
         mKeyguardBottomArea.setDozing(mDozing, animate);
 
+        if (dozing) {
+            mBottomAreaShadeAlphaAnimator.cancel();
+        }
+
         if (mBarState == StatusBarState.KEYGUARD
                 || mBarState == StatusBarState.SHADE_LOCKED) {
             updateDozingVisibilities(animate);
@@ -3062,10 +3324,6 @@
         return mNotificationStackScroller.hasPulsingNotifications();
     }
 
-    public boolean isFullyDark() {
-        return mNotificationStackScroller.isFullyDark();
-    }
-
     public ActivatableNotificationView getActivatedChild() {
         return mNotificationStackScroller.getActivatedChild();
     }
@@ -3093,7 +3351,6 @@
         mNotificationStackScroller.setIconAreaController(notificationIconAreaController);
         mNotificationStackScroller.setStatusBar(statusBar);
         mNotificationStackScroller.setGroupManager(groupManager);
-        mNotificationStackScroller.setHeadsUpManager(headsUpManager);
         mNotificationStackScroller.setShelf(notificationShelf);
         mNotificationStackScroller.setScrimController(scrimController);
         updateShowEmptyShadeView();
@@ -3113,6 +3370,10 @@
         mAnimateNextPositionUpdate = true;
     }
 
+    public void setOnReinflationListener(Runnable onReinflationListener) {
+        mOnReinflationListener = onReinflationListener;
+    }
+
     /**
      * Panel and QS expansion callbacks.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index ca762cd..27c94d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -36,6 +36,9 @@
 import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 
+import java.util.ArrayList;
+import java.util.Comparator;
+
 /**
  * The container with notification stack scroller and quick settings inside.
  */
@@ -54,6 +57,9 @@
     private int mBottomPadding;
     private int mStackScrollerMargin;
     private boolean mHasViewsAboveShelf;
+    private ArrayList<View> mDrawingOrderedChildren = new ArrayList<>();
+    private ArrayList<View> mLayoutDrawingOrder = new ArrayList<>();
+    private final Comparator<View> mIndexComparator = Comparator.comparingInt(this::indexOfChild);
 
     public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -107,35 +113,44 @@
     }
 
     @Override
-    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
-        boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE;
-        boolean statusBarVisible = mKeyguardStatusBar.getVisibility() == View.VISIBLE;
-
-        final boolean qsBottom = mHasViewsAboveShelf;
-        View stackQsTop = qsBottom ? mStackScroller : mQsFrame;
-        View stackQsBottom = !qsBottom ? mStackScroller : mQsFrame;
+    protected void dispatchDraw(Canvas canvas) {
         // Invert the order of the scroll view and user switcher such that the notifications receive
         // touches first but the panel gets drawn above.
-        if (child == mQsFrame) {
-            return super.drawChild(canvas, userSwitcherVisible && statusBarVisible ? mUserSwitcher
-                    : statusBarVisible ? mKeyguardStatusBar
-                    : userSwitcherVisible ? mUserSwitcher
-                    : stackQsBottom, drawingTime);
-        } else if (child == mStackScroller) {
-            return super.drawChild(canvas,
-                    userSwitcherVisible && statusBarVisible ? mKeyguardStatusBar
-                    : statusBarVisible || userSwitcherVisible ? stackQsBottom
-                    : stackQsTop,
-                    drawingTime);
-        } else if (child == mUserSwitcher) {
-            return super.drawChild(canvas,
-                    userSwitcherVisible && statusBarVisible ? stackQsBottom
-                    : stackQsTop,
-                    drawingTime);
-        } else if (child == mKeyguardStatusBar) {
-            return super.drawChild(canvas,
-                    stackQsTop,
-                    drawingTime);
+        mDrawingOrderedChildren.clear();
+        mLayoutDrawingOrder.clear();
+        if (mInflated && mUserSwitcher.getVisibility() == View.VISIBLE) {
+            mDrawingOrderedChildren.add(mUserSwitcher);
+            mLayoutDrawingOrder.add(mUserSwitcher);
+        }
+        if (mKeyguardStatusBar.getVisibility() == View.VISIBLE) {
+            mDrawingOrderedChildren.add(mKeyguardStatusBar);
+            mLayoutDrawingOrder.add(mKeyguardStatusBar);
+        }
+        if (mStackScroller.getVisibility() == View.VISIBLE) {
+            mDrawingOrderedChildren.add(mStackScroller);
+            mLayoutDrawingOrder.add(mStackScroller);
+        }
+        if (mQsFrame.getVisibility() == View.VISIBLE) {
+            mDrawingOrderedChildren.add(mQsFrame);
+            mLayoutDrawingOrder.add(mQsFrame);
+        }
+
+        if (mHasViewsAboveShelf) {
+            // StackScroller needs to be on top
+            mDrawingOrderedChildren.remove(mStackScroller);
+            mDrawingOrderedChildren.add(mStackScroller);
+        }
+
+        // Let's now find the order that the view has when drawing regulary by sorting
+        mLayoutDrawingOrder.sort(mIndexComparator);
+        super.dispatchDraw(canvas);
+    }
+
+    @Override
+    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+        int layoutIndex = mLayoutDrawingOrder.indexOf(child);
+        if (layoutIndex >= 0) {
+            return super.drawChild(canvas, mDrawingOrderedChildren.get(layoutIndex), drawingTime);
         } else {
             return super.drawChild(canvas, child, drawingTime);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 65b0ecc..063d00b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -107,8 +107,12 @@
         return mExpanded;
     }
 
-    private void updateVisibility() {
-        mPanel.setVisibility(mExpanded || mBouncerShowing ? VISIBLE : INVISIBLE);
+    protected void updateVisibility() {
+        mPanel.setVisibility(shouldPanelBeVisible() ? VISIBLE : INVISIBLE);
+    }
+
+    protected boolean shouldPanelBeVisible() {
+        return mExpanded || mBouncerShowing;
     }
 
     public boolean panelEnabled() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index a9a3b2d..853faab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -42,7 +42,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -110,7 +109,7 @@
     private FlingAnimationUtils mFlingAnimationUtils;
     private FlingAnimationUtils mFlingAnimationUtilsClosing;
     private FlingAnimationUtils mFlingAnimationUtilsDismissing;
-    private FalsingManager mFalsingManager;
+    private final FalsingManager mFalsingManager;
     private final VibratorHelper mVibratorHelper;
 
     /**
@@ -213,7 +212,7 @@
                 0.5f /* maxLengthSeconds */, 0.2f /* speedUpFactor */, 0.6f /* x2 */,
                 0.84f /* y2 */);
         mBounceInterpolator = new BounceInterpolator();
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
         mNotificationsDragEnabled =
                 getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
         mVibratorHelper = Dependency.get(VibratorHelper.class);
@@ -301,7 +300,7 @@
         final float y = event.getY(pointerIndex);
 
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            mGestureWaitForTouchSlop = isFullyCollapsed() || hasConflictingGestures();
+            mGestureWaitForTouchSlop = shouldGestureWaitForTouchSlop();
             mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
         }
 
@@ -519,7 +518,7 @@
         return (int) (mUnlockFalsingThreshold * factor);
     }
 
-    protected abstract boolean hasConflictingGestures();
+    protected abstract boolean shouldGestureWaitForTouchSlop();
 
     protected abstract boolean shouldGestureIgnoreXTouchSlop(float x, float y);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 68eba50..660810f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -46,6 +46,7 @@
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import java.util.Objects;
 
@@ -82,6 +83,7 @@
      * Draw this many pixels into the left/right side of the cutout to optimally use the space
      */
     private int mCutoutSideNudge = 0;
+    private boolean mHeadsUpVisible;
 
     public PhoneStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -379,4 +381,14 @@
         }
         return null;
     }
+
+    public void setHeadsUpVisible(boolean headsUpVisible) {
+        mHeadsUpVisible = headsUpVisible;
+        updateVisibility();
+    }
+
+    @Override
+    protected boolean shouldPanelBeVisible() {
+        return mHeadsUpVisible || super.shouldPanelBeVisible();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
index 2b0bb21..8026f65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
@@ -18,12 +18,9 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import android.annotation.Nullable;
 import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Handler;
-import android.os.IBinder;
-import android.provider.Settings;
 import android.view.CompositionSamplingListener;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -181,8 +178,7 @@
                 unregisterSamplingListener();
                 mSamplingListenerRegistered = true;
                 CompositionSamplingListener.register(mSamplingListener, DEFAULT_DISPLAY,
-                        stopLayerControl != null ? stopLayerControl.getHandle() : null,
-                        mSamplingRequestBounds);
+                        stopLayerControl, mSamplingRequestBounds);
                 mRegisteredSamplingBounds.set(mSamplingRequestBounds);
                 mRegisteredStopLayer = stopLayerControl;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
index 1e5406f..0147e7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
@@ -26,7 +26,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.os.Handler;
-import android.os.Message;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.provider.Settings;
 import android.view.IRotationWatcher.Stub;
@@ -34,6 +34,7 @@
 import android.view.Surface;
 import android.view.View;
 import android.view.WindowManagerGlobal;
+import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -42,6 +43,7 @@
 import com.android.systemui.R;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 import com.android.systemui.statusbar.policy.RotationLockController;
 
@@ -64,8 +66,10 @@
     private boolean mPendingRotationSuggestion;
     private boolean mHoveringRotationSuggestion;
     private RotationLockController mRotationLockController;
+    private AccessibilityManagerWrapper mAccessibilityManagerWrapper;
     private TaskStackListenerImpl mTaskStackListener;
     private Consumer<Integer> mRotWatcherListener;
+    private boolean mListenersRegistered = false;
     private boolean mIsNavigationBarShowing;
 
     private final Runnable mRemoveRotationProposal =
@@ -73,22 +77,17 @@
     private final Runnable mCancelPendingRotationProposal =
             () -> mPendingRotationSuggestion = false;
     private Animator mRotateHideAnimator;
-    private boolean mAccessibilityFeedbackEnabled;
 
     private final Context mContext;
     private final RotationButton mRotationButton;
+    private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
 
     private final Stub mRotationWatcher = new Stub() {
         @Override
         public void onRotationChanged(final int rotation) throws RemoteException {
-            if (mRotationButton.getCurrentView() == null) {
-                return;
-            }
-
             // We need this to be scheduled as early as possible to beat the redrawing of
             // window in response to the orientation change.
-            Handler h = mRotationButton.getCurrentView().getHandler();
-            Message msg = Message.obtain(h, () -> {
+            mMainThreadHandler.postAtFrontOfQueue(() -> {
                 // If the screen rotation changes while locked, potentially update lock to flow with
                 // new screen rotation and hide any showing suggestions.
                 if (mRotationLockController.isRotationLocked()) {
@@ -102,8 +101,6 @@
                     mRotWatcherListener.accept(rotation);
                 }
             });
-            msg.setAsynchronous(true);
-            h.sendMessageAtFrontOfQueue(msg);
         }
     };
 
@@ -124,40 +121,49 @@
         mStyleRes = style;
         mIsNavigationBarShowing = true;
         mRotationLockController = Dependency.get(RotationLockController.class);
+        mAccessibilityManagerWrapper = Dependency.get(AccessibilityManagerWrapper.class);
 
         // Register the task stack listener
         mTaskStackListener = new TaskStackListenerImpl();
-        ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
         mRotationButton.setOnClickListener(this::onRotateSuggestionClick);
         mRotationButton.setOnHoverListener(this::onRotateSuggestionHover);
+    }
 
+    void registerListeners() {
+        if (mListenersRegistered) {
+            return;
+        }
+
+        mListenersRegistered = true;
         try {
             WindowManagerGlobal.getWindowManagerService()
                     .watchRotation(mRotationWatcher, mContext.getDisplay().getDisplayId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
+
+        ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
     }
 
-    void cleanUp() {
-        // Unregister the task stack listener
-        ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
+    void unregisterListeners() {
+        if (!mListenersRegistered) {
+            return;
+        }
 
+        mListenersRegistered = false;
         try {
             WindowManagerGlobal.getWindowManagerService().removeRotationWatcher(mRotationWatcher);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
+
+        ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
     }
 
     void addRotationCallback(Consumer<Integer> watcher) {
         mRotWatcherListener = watcher;
     }
 
-    void setAccessibilityFeedbackEnabled(boolean flag) {
-        mAccessibilityFeedbackEnabled = flag;
-    }
-
     void setRotationLockedAtAngle(int rotationSuggestion) {
         mRotationLockController.setRotationLockedAtAngle(true /* locked */, rotationSuggestion);
     }
@@ -185,7 +191,7 @@
 
         // Clear any pending suggestion flag as it has either been nullified or is being shown
         mPendingRotationSuggestion = false;
-        view.removeCallbacks(mCancelPendingRotationProposal);
+        mMainThreadHandler.removeCallbacks(mCancelPendingRotationProposal);
 
         // Handle the visibility change and animation
         if (visible) { // Appear and change (cannot force)
@@ -255,13 +261,9 @@
             return;
         }
 
-        final View currentView = mRotationButton.getCurrentView();
-
         // If window rotation matches suggested rotation, remove any current suggestions
         if (rotation == windowRotation) {
-            if (currentView != null) {
-                currentView.removeCallbacks(mRemoveRotationProposal);
-            }
+            mMainThreadHandler.removeCallbacks(mRemoveRotationProposal);
             setRotateSuggestionButtonState(false /* visible */);
             return;
         }
@@ -285,11 +287,9 @@
             // If the navbar isn't shown, flag the rotate icon to be shown should the navbar become
             // visible given some time limit.
             mPendingRotationSuggestion = true;
-            if (currentView != null) {
-                currentView.removeCallbacks(mCancelPendingRotationProposal);
-                currentView.postDelayed(mCancelPendingRotationProposal,
-                        NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS);
-            }
+            mMainThreadHandler.removeCallbacks(mCancelPendingRotationProposal);
+            mMainThreadHandler.postDelayed(mCancelPendingRotationProposal,
+                    NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS);
         }
     }
 
@@ -334,9 +334,7 @@
     private void onRotationSuggestionsDisabled() {
         // Immediately hide the rotate button and clear any planned removal
         setRotateSuggestionButtonState(false /* visible */, true /* force */);
-        if (mRotationButton.getCurrentView() != null) {
-            mRotationButton.getCurrentView().removeCallbacks(mRemoveRotationProposal);
-        }
+        mMainThreadHandler.removeCallbacks(mRemoveRotationProposal);
     }
 
     private void showAndLogRotationSuggestion() {
@@ -369,10 +367,6 @@
     }
 
     private void rescheduleRotationTimeout(final boolean reasonHover) {
-        if (mRotationButton.getCurrentView() == null) {
-            return;
-        }
-
         // May be called due to a new rotation proposal or a change in hover state
         if (reasonHover) {
             // Don't reschedule if a hide animator is running
@@ -382,16 +376,16 @@
         }
 
         // Stop any pending removal
-        mRotationButton.getCurrentView().removeCallbacks(mRemoveRotationProposal);
+        mMainThreadHandler.removeCallbacks(mRemoveRotationProposal);
         // Schedule timeout
-        mRotationButton.getCurrentView().postDelayed(mRemoveRotationProposal,
+        mMainThreadHandler.postDelayed(mRemoveRotationProposal,
                 computeRotationProposalTimeout());
     }
 
     private int computeRotationProposalTimeout() {
-        if (mAccessibilityFeedbackEnabled) return 10000;
-        if (mHoveringRotationSuggestion) return 8000;
-        return 5000;
+        return mAccessibilityManagerWrapper.getRecommendedTimeoutMillis(
+                mHoveringRotationSuggestion ? 16000 : 5000,
+                AccessibilityManager.FLAG_CONTENT_CONTROLS);
     }
 
     private boolean isRotateSuggestionIntroduced() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
index b117dec..bd96752 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
@@ -24,7 +24,6 @@
 import android.view.ContextThemeWrapper;
 import android.view.View;
 
-import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 
 /** Containing logic for the rotation button in nav bar. */
@@ -61,14 +60,7 @@
         Context context = new ContextThemeWrapper(getContext().getApplicationContext(),
                 mRotationButtonController.getStyleRes());
         return KeyButtonDrawable.create(context, mIconResId, false /* shadow */,
-                QuickStepContract.isGesturalMode(mNavBarMode));
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mRotationButtonController != null) {
-            mRotationButtonController.cleanUp();
-        }
+                null /* ovalBackgroundColor */);
     }
 
     @Override
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 5dcbea2..1aec5e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -284,15 +284,12 @@
 
         // AOD wallpapers should fade away after a while.
         // Docking pulses may take a long time, wallpapers should also fade away after a while.
-        if (mWallpaperSupportsAmbientMode && mDozeParameters.getAlwaysOn()
-                && mState == ScrimState.AOD) {
-            if (!mWallpaperVisibilityTimedOut) {
-                mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
-                        AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
-            }
+        mWallpaperVisibilityTimedOut = false;
+        if (shouldFadeAwayWallpaper()) {
+            mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
+                    AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
         } else {
             mTimeTicker.cancel();
-            mWallpaperVisibilityTimedOut = false;
         }
 
         if (mKeyguardUpdateMonitor.needsSlowUnlockTransition() && mState == ScrimState.UNLOCKED) {
@@ -313,6 +310,23 @@
         dispatchScrimState(mScrimBehind.getViewAlpha());
     }
 
+    private boolean shouldFadeAwayWallpaper() {
+        if (!mWallpaperSupportsAmbientMode) {
+            return false;
+        }
+
+        if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) {
+            return true;
+        }
+
+        if (mState == ScrimState.PULSING
+                && mCallback != null && mCallback.shouldTimeoutWallpaper()) {
+            return true;
+        }
+
+        return false;
+    }
+
     public ScrimState getState() {
         return mState;
     }
@@ -387,6 +401,14 @@
             setOrAdaptCurrentAnimation(mScrimInFront);
 
             dispatchScrimState(mScrimBehind.getViewAlpha());
+
+            // Reset wallpaper timeout if it's already timeout like expanding panel while PULSING
+            // and docking.
+            if (mWallpaperVisibilityTimedOut) {
+                mWallpaperVisibilityTimedOut = false;
+                mTimeTicker.schedule(mDozeParameters.getWallpaperAodDuration(),
+                        AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
+            }
         }
     }
 
@@ -465,6 +487,20 @@
     }
 
     /**
+     * Set front scrim to black, cancelling animations, in order to prepare to fade them
+     * away once the display turns on.
+     */
+    public void prepareForGentleWakeUp() {
+        if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) {
+            mCurrentInFrontAlpha = 1f;
+            mAnimateChange = false;
+            updateScrims();
+            mAnimateChange = true;
+            mAnimationDuration = ANIMATION_DURATION_LONG;
+        }
+    }
+
+    /**
      * If the lock screen sensor is active.
      */
     public void setWakeLockScreenSensorActive(boolean active) {
@@ -910,6 +946,12 @@
         }
     }
 
+    public void setUnlockIsFading(boolean unlockFading) {
+        for (ScrimState state : ScrimState.values()) {
+            state.setUnlockIsFading(unlockFading);
+        }
+    }
+
     public void setLaunchingAffordanceWithPreview(boolean launchingAffordanceWithPreview) {
         for (ScrimState state : ScrimState.values()) {
             state.setLaunchingAffordanceWithPreview(launchingAffordanceWithPreview);
@@ -925,6 +967,10 @@
         }
         default void onCancelled() {
         }
+        /** Returns whether to timeout wallpaper or not. */
+        default boolean shouldTimeoutWallpaper() {
+            return false;
+        }
     }
 
     /**
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 d152ecd..763e0d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -147,7 +147,9 @@
         public void prepare(ScrimState previousState) {
             mCurrentBehindAlpha = 0;
             mCurrentInFrontAlpha = 0;
-            mAnimationDuration = StatusBar.FADE_KEYGUARD_DURATION;
+            mAnimationDuration = mUnlockIsFading
+                    ? KeyguardBypassController.BYPASS_PANEL_FADE_DURATION
+                    : StatusBar.FADE_KEYGUARD_DURATION;
             mAnimateChange = !mLaunchingAffordanceWithPreview;
 
             if (previousState == ScrimState.AOD) {
@@ -198,6 +200,7 @@
     boolean mHasBackdrop;
     boolean mLaunchingAffordanceWithPreview;
     boolean mWakeLockScreenSensorActive;
+    boolean mUnlockIsFading;
 
     ScrimState(int index) {
         mIndex = index;
@@ -285,4 +288,8 @@
     public void setWakeLockScreenSensorActive(boolean active) {
         mWakeLockScreenSensorActive = active;
     }
+
+    public void setUnlockIsFading(boolean unlockIsFading) {
+        mUnlockIsFading = unlockIsFading;
+    }
 }
\ 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 5fca4f8..f8e6aa3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -30,8 +30,6 @@
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
 import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_INVALID;
 import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_LEFT;
 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
@@ -149,7 +147,6 @@
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.charging.WirelessChargingAnimation;
 import com.android.systemui.classifier.FalsingLog;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
@@ -169,13 +166,11 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.qs.QSPanel;
-import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.stackdivider.WindowManagerProxy;
-import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.BackDropView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
@@ -197,6 +192,7 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationAlertingManager;
 import com.android.systemui.statusbar.notification.NotificationClicker;
@@ -204,6 +200,7 @@
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationListController;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
@@ -230,7 +227,6 @@
 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.InjectionInflationController;
 import com.android.systemui.volume.VolumeComponent;
 
@@ -249,8 +245,7 @@
         OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
         ColorExtractor.OnColorsChangedListener, ConfigurationListener,
         StatusBarStateController.StateListener, ShadeController,
-        ActivityLaunchAnimator.Callback, AmbientPulseManager.OnAmbientChangedListener,
-        AppOpsController.Callback {
+        ActivityLaunchAnimator.Callback, AppOpsController.Callback {
     public static final boolean MULTIUSER_DEBUG = false;
 
     public static final boolean ENABLE_CHILD_NOTIFICATIONS
@@ -320,17 +315,6 @@
     /** If true, the lockscreen will show a distinct wallpaper */
     public static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
 
-    private static final AudioAttributes AUDIO_ATTRIBUTES =
-            new AudioAttributes.Builder()
-                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                    // Temporary fix for b/123870990. No time in this release to
-                    // introduce a new vibration type, but we need to distinguish these vibrations
-                    // from other haptic feedback vibrations. Fortunately, Alarm vibrations have
-                    // exactly the same behavior as we need
-                    // TODO: refactor within the scope of b/132170758
-                    .setUsage(AudioAttributes.USAGE_ALARM)
-                    .build();
-
     static {
         boolean onlyCoreApps;
         try {
@@ -388,6 +372,13 @@
     NotificationWakeUpCoordinator mWakeUpCoordinator;
     @Inject
     KeyguardBypassController mKeyguardBypassController;
+    @Inject
+    protected HeadsUpManagerPhone mHeadsUpManager;
+    @Inject
+    BypassHeadsUpNotifier mBypassHeadsUpNotifier;
+    @Nullable
+    @Inject
+    protected KeyguardLiftController mKeyguardLiftController;
 
     // expanded notifications
     protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -509,7 +500,7 @@
 
     private Runnable mLaunchTransitionEndRunnable;
     private NotificationEntry mDraggedDownEntry;
-    private boolean mLaunchCameraOnScreenTurningOn;
+    private boolean mLaunchCameraWhenFinishedWaking;
     private boolean mLaunchCameraOnFinishedGoingToSleep;
     private int mLastCameraLaunchSource;
     protected PowerManager.WakeLock mGestureWakeLock;
@@ -645,6 +636,7 @@
         mGutsManager = Dependency.get(NotificationGutsManager.class);
         mMediaManager = Dependency.get(NotificationMediaManager.class);
         mEntryManager = Dependency.get(NotificationEntryManager.class);
+        mBypassHeadsUpNotifier.setUp(mEntryManager);
         mNotificationInterruptionStateProvider =
                 Dependency.get(NotificationInterruptionStateProvider.class);
         mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class);
@@ -660,7 +652,8 @@
         mActivityIntentHelper = new ActivityIntentHelper(mContext);
         KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance();
         if (sliceProvider != null) {
-            sliceProvider.initDependencies(mMediaManager, mStatusBarStateController);
+            sliceProvider.initDependencies(mMediaManager, mStatusBarStateController,
+                    mKeyguardBypassController, DozeParameters.getInstance(mContext));
         } else {
             Log.w(TAG, "Cannot init KeyguardSliceProvider dependencies");
         }
@@ -694,12 +687,14 @@
 
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+        mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
 
         mRecents = getComponent(Recents.class);
 
         mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mFalsingManager = Dependency.get(FalsingManager.class);
 
         // Connect in to the status bar manager service
         mCommandQueue = getComponent(CommandQueue.class);
@@ -775,7 +770,6 @@
         putComponent(DozeHost.class, mDozeServiceHost);
 
         mScreenPinningRequest = new ScreenPinningRequest(mContext);
-        mFalsingManager = FalsingManagerFactory.getInstance(mContext);
 
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
 
@@ -787,8 +781,6 @@
         int disabledFlags2 = result.mDisabledFlags2;
         Dependency.get(InitController.class).addPostInitTask(
                 () -> setUpDisableFlags(disabledFlags1, disabledFlags2));
-
-        updateSystemUiStateFlags();
     }
 
     // ================================================================================
@@ -802,6 +794,7 @@
 
         inflateStatusBarWindow(context);
         mStatusBarWindow.setService(this);
+        mStatusBarWindow.setBypassController(mKeyguardBypassController);
         mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
 
         // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
@@ -814,9 +807,12 @@
 
         mNotificationIconAreaController = SystemUIFactory.getInstance()
                 .createNotificationIconAreaController(context, this,
-                        mStatusBarStateController, mNotificationListener);
+                        mWakeUpCoordinator, mKeyguardBypassController,
+                        mStatusBarStateController);
+        mWakeUpCoordinator.setIconAreaController(mNotificationIconAreaController);
         inflateShelf();
         mNotificationIconAreaController.setupShelf(mNotificationShelf);
+        mNotificationPanel.setOnReinflationListener(mNotificationIconAreaController::initAodIcons);
 
         Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController);
         // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
@@ -858,7 +854,8 @@
                         mHeadsUpAppearanceController.destroy();
                     }
                     mHeadsUpAppearanceController = new HeadsUpAppearanceController(
-                            mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow);
+                            mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow,
+                            mStatusBarStateController, mKeyguardBypassController);
                     mHeadsUpAppearanceController.readFrom(oldController);
                     mStatusBarWindow.setStatusBarView(mStatusBarView);
                     updateAreThereNotifications();
@@ -870,17 +867,13 @@
                 .commit();
         mIconController = Dependency.get(StatusBarIconController.class);
 
-        mHeadsUpManager = new HeadsUpManagerPhone(context, mStatusBarWindow, mGroupManager, this,
-                mVisualStabilityManager);
+        mHeadsUpManager.setUp(mStatusBarWindow, mGroupManager, this, mVisualStabilityManager);
         Dependency.get(ConfigurationController.class).addCallback(mHeadsUpManager);
         mHeadsUpManager.addListener(this);
         mHeadsUpManager.addListener(mNotificationPanel);
         mHeadsUpManager.addListener(mGroupManager);
         mHeadsUpManager.addListener(mGroupAlertTransferHelper);
         mHeadsUpManager.addListener(mVisualStabilityManager);
-        mAmbientPulseManager.addListener(this);
-        mAmbientPulseManager.addListener(mGroupManager);
-        mAmbientPulseManager.addListener(mGroupAlertTransferHelper);
         mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
         mGroupAlertTransferHelper.setHeadsUpManager(mHeadsUpManager);
@@ -1062,7 +1055,9 @@
         final NotificationRowBinderImpl rowBinder =
                 new NotificationRowBinderImpl(
                         mContext,
-                        SystemUIFactory.getInstance().provideAllowNotificationLongPress());
+                        SystemUIFactory.getInstance().provideAllowNotificationLongPress(),
+                        mKeyguardBypassController,
+                        mStatusBarStateController);
 
         mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
                 mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
@@ -1163,8 +1158,9 @@
 
     private void inflateShelf() {
         mNotificationShelf =
-                (NotificationShelf) LayoutInflater.from(mContext).inflate(
-                        R.layout.status_bar_notification_shelf, mStackScroller, false);
+                (NotificationShelf) mInjectionInflater.injectable(
+                        LayoutInflater.from(mContext)).inflate(
+                                R.layout.status_bar_notification_shelf, mStackScroller, false);
         mNotificationShelf.setOnClickListener(mGoToLockedShadeListener);
     }
 
@@ -1193,6 +1189,7 @@
         if (mAmbientIndicationContainer instanceof AutoReinflateContainer) {
             ((AutoReinflateContainer) mAmbientIndicationContainer).inflateLayout();
         }
+        mNotificationIconAreaController.onThemeChanged();
     }
 
     @Override
@@ -1232,9 +1229,11 @@
                 mDozeScrimController, keyguardViewMediator,
                 mScrimController, this, UnlockMethodCache.getInstance(mContext),
                 new Handler(), mKeyguardUpdateMonitor, mKeyguardBypassController);
+        putComponent(BiometricUnlockController.class, mBiometricUnlockController);
         mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
                 getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
-                mStatusBarWindow.findViewById(R.id.lock_icon_container));
+                mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
+                mKeyguardBypassController, mFalsingManager);
         mKeyguardIndicationController
                 .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
@@ -1313,7 +1312,6 @@
                 && !mDozing
                 && !ONLY_CORE_APPS;
         mNotificationPanel.setQsExpansionEnabled(expandEnabled);
-        // STOPSHIP(kozynski, b/129405675) Remove log
         Log.d(TAG, "updateQsExpansionEnabled - QS Expand enabled: " + expandEnabled);
     }
 
@@ -1528,6 +1526,8 @@
 
     @Override  // UnlockMethodCache.OnUnlockMethodChangedListener
     public void onUnlockMethodStateChanged() {
+        // Unlock method state changed. Notify KeguardMonitor
+        updateKeyguardState();
         logStateToEventlog();
     }
 
@@ -1548,10 +1548,16 @@
                 });
             }
         } else {
-            if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
+            boolean bypassKeyguard = mKeyguardBypassController.getBypassEnabled()
+                    && mState == StatusBarState.KEYGUARD;
+            if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()
+                    || bypassKeyguard) {
                 // We are currently tracking or is open and the shade doesn't need to be kept
                 // open artificially.
                 mStatusBarWindowController.setHeadsUpShowing(false);
+                if (bypassKeyguard) {
+                    mStatusBarWindowController.setForceStatusBarVisible(false);
+                }
             } else {
                 // we need to keep the panel open artificially, let's wait until the animation
                 // is finished.
@@ -1568,25 +1574,15 @@
     }
 
     @Override
-    public void onHeadsUpPinned(NotificationEntry entry) {
-        dismissVolumeDialog();
-    }
-
-    @Override
-    public void onHeadsUpUnPinned(NotificationEntry entry) {
-    }
-
-    @Override
     public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
         mEntryManager.updateNotifications();
-    }
-
-    @Override
-    public void onAmbientStateChanged(NotificationEntry entry, boolean isAmbient) {
-        mEntryManager.updateNotifications();
-        if (isAmbient) {
+        if (isDozing() && isHeadsUp) {
             mDozeServiceHost.fireNotificationPulse();
-        } else if (!mAmbientPulseManager.hasNotifications()) {
+            if (mPulsing) {
+                mDozeScrimController.cancelPendingPulseTimeout();
+            }
+        }
+        if (!isHeadsUp && !mHeadsUpManager.hasNotifications()) {
             // There are no longer any notifications to show.  We should end the pulse now.
             mDozeScrimController.pulseOutNow();
         }
@@ -1684,7 +1680,7 @@
         }
     }
 
-    public boolean isHeadsUpShouldBeVisible() {
+    public boolean headsUpShouldBeVisible() {
         return mHeadsUpAppearanceController.shouldBeVisible();
     }
 
@@ -1932,19 +1928,19 @@
         mStatusBarKeyguardViewManager.readyForKeyguardDone();
     }
 
-    public void dispatchNotificationsPanelTouchEvent(MotionEvent ev) {
+    /**
+     * Called when another window is about to transfer it's input focus.
+     */
+    public void onInputFocusTransfer(boolean start, float velocity) {
         if (!mCommandQueue.panelsEnabled()) {
             return;
         }
-        mNotificationPanel.dispatchTouchEvent(ev);
 
-        int action = ev.getAction();
-        if (action == MotionEvent.ACTION_DOWN) {
-            // Start ignoring all touch events coming to status bar window.
-            // TODO: handle case where ACTION_UP is not sent over the binder
-            mStatusBarWindowController.setNotTouchable(true);
-        } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
-            mStatusBarWindowController.setNotTouchable(false);
+        if (start) {
+            mNotificationPanel.startWaitingForOpenPanelGesture();
+            setPanelExpanded(true);
+        } else {
+            mNotificationPanel.stopWaitingForOpenPanelGesture(velocity);
         }
     }
 
@@ -2134,6 +2130,7 @@
                 checkBarModes();
                 mAutoHideController.touchAutoHide();
             }
+            mStatusBarStateController.setSystemUiVisibility(mSystemUiVisibility);
         }
         mLightBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
                 mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode,
@@ -2390,11 +2387,15 @@
             mLightBarController.dump(fd, pw, args);
         }
 
+        if (mKeyguardBypassController != null) {
+            mKeyguardBypassController.dump(pw);
+        }
+
         if (mKeyguardUpdateMonitor != null) {
             mKeyguardUpdateMonitor.dump(fd, pw, args);
         }
 
-        FalsingManagerFactory.getInstance(mContext).dump(pw);
+        Dependency.get(FalsingManager.class).dump(pw);
         FalsingLog.dump(pw);
 
         pw.println("SharedPreferences:");
@@ -2623,8 +2624,8 @@
         }
     }
 
-    private void executeWhenUnlocked(OnDismissAction action) {
-        if (mStatusBarKeyguardViewManager.isShowing()) {
+    private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen) {
+        if (mStatusBarKeyguardViewManager.isShowing() && requiresShadeOpen) {
             mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
         }
         dismissKeyguardThenExecute(action, null /* cancelAction */, false /* afterKeyguardGone */);
@@ -3174,6 +3175,7 @@
         mNotificationPanel.onAffordanceLaunchEnded();
         mNotificationPanel.animate().cancel();
         mNotificationPanel.setAlpha(1f);
+        ViewGroupFadeHelper.reset(mNotificationPanel);
         updateScrimController();
         Trace.endSection();
         return staying;
@@ -3228,8 +3230,7 @@
 
         // Lock wallpaper defines the color of the majority of the views, hence we'll use it
         // to set our default theme.
-        final boolean lockDarkText = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true
-                /* ignoreVisibility */).supportsDarkText();
+        final boolean lockDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI;
         if (mContext.getThemeResId() != themeResId) {
             mContext.setTheme(themeResId);
@@ -3423,11 +3424,8 @@
         updateDozingState();
         checkBarModes();
         updateScrimController();
-        updateSystemUiStateFlags();
         mPresenter.updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
-        mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
-                mUnlockMethodCache.isMethodSecure(),
-                mStatusBarKeyguardViewManager.isOccluded());
+        updateKeyguardState();
         Trace.endSection();
     }
 
@@ -3442,7 +3440,7 @@
         mNotificationPanel.resetViews(dozingAnimated);
 
         updateQsExpansionEnabled();
-        mKeyguardViewMediator.setAodShowing(mDozing);
+        mKeyguardViewMediator.setDozing(mDozing);
 
         mEntryManager.updateNotifications();
         updateDozingState();
@@ -3466,6 +3464,12 @@
         mStatusBarStateController.setIsDozing(dozing);
     }
 
+    private void updateKeyguardState() {
+        mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
+                mUnlockMethodCache.isMethodSecure(),
+                mStatusBarKeyguardViewManager.isOccluded());
+    }
+
     public void onActivationReset() {
         mKeyguardIndicationController.hideTransientIndication();
     }
@@ -3583,6 +3587,9 @@
      */
     public void setBouncerShowing(boolean bouncerShowing) {
         mBouncerShowing = bouncerShowing;
+        mKeyguardBypassController.setBouncerShowing(bouncerShowing);
+        mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
+        mStatusBarWindow.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
         if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
         updateHideIconsForBouncer(true /* animate */);
         mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
@@ -3590,16 +3597,6 @@
         if (!mBouncerShowing) {
             updatePanelExpansionForKeyguard();
         }
-        updateSystemUiStateFlags();
-    }
-
-    public void updateSystemUiStateFlags() {
-        OverviewProxyService overviewProxyService = Dependency.get(OverviewProxyService.class);
-        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
-                mStatusBarStateController.getState() == StatusBarState.KEYGUARD,
-                mDisplayId);
-        overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING,
-                isBouncerShowing(), mDisplayId);
     }
 
     /**
@@ -3620,7 +3617,7 @@
         public void onFinishedGoingToSleep() {
             mNotificationPanel.onAffordanceLaunchEnded();
             releaseGestureWakeLock();
-            mLaunchCameraOnScreenTurningOn = false;
+            mLaunchCameraWhenFinishedWaking = false;
             mDeviceInteractive = false;
             mWakeUpComingFromTouch = false;
             mWakeUpTouchLocation = null;
@@ -3644,13 +3641,18 @@
             updateNotificationPanelTouchState();
             notifyHeadsUpGoingToSleep();
             dismissVolumeDialog();
+            mWakeUpCoordinator.setFullyAwake(false);
+            mBypassHeadsUpNotifier.setFullyAwake(false);
+            mKeyguardBypassController.onStartedGoingToSleep();
         }
 
         @Override
         public void onStartedWakingUp() {
             mDeviceInteractive = true;
             mWakeUpCoordinator.setWakingUp(true);
-            mAmbientPulseManager.releaseAllImmediately();
+            if (!mKeyguardBypassController.getBypassEnabled()) {
+                mHeadsUpManager.releaseAllImmediately();
+            }
             mVisualStabilityManager.setScreenOn(true);
             updateVisibleToUser();
             updateIsKeyguard();
@@ -3664,7 +3666,14 @@
 
         @Override
         public void onFinishedWakingUp() {
+            mWakeUpCoordinator.setFullyAwake(true);
+            mBypassHeadsUpNotifier.setFullyAwake(true);
             mWakeUpCoordinator.setWakingUp(false);
+            if (mLaunchCameraWhenFinishedWaking) {
+                mNotificationPanel.launchCamera(false /* animate */, mLastCameraLaunchSource);
+                mLaunchCameraWhenFinishedWaking = false;
+            }
+            updateScrimController();
         }
     };
 
@@ -3676,8 +3685,9 @@
     private void updateNotificationPanelTouchState() {
         boolean goingToSleepWithoutAnimation = isGoingToSleep()
                 && !DozeParameters.getInstance(mContext).shouldControlScreenOff();
-        mNotificationPanel.setTouchAndAnimationDisabled((!mDeviceInteractive && !mPulsing)
-                || goingToSleepWithoutAnimation);
+        boolean disabled = (!mDeviceInteractive && !mPulsing) || goingToSleepWithoutAnimation;
+        mNotificationPanel.setTouchAndAnimationDisabled(disabled);
+        mNotificationIconAreaController.setAnimationsEnabled(!disabled);
     }
 
     final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
@@ -3685,13 +3695,6 @@
         public void onScreenTurningOn() {
             mFalsingManager.onScreenTurningOn();
             mNotificationPanel.onScreenTurningOn();
-
-            if (mLaunchCameraOnScreenTurningOn) {
-                mNotificationPanel.launchCamera(false, mLastCameraLaunchSource);
-                mLaunchCameraOnScreenTurningOn = false;
-            }
-
-            updateScrimController();
         }
 
         @Override
@@ -3713,7 +3716,7 @@
 
     private void vibrateForCameraGesture() {
         // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
-        mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */, AUDIO_ATTRIBUTES);
+        mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */);
     }
 
     /**
@@ -3776,6 +3779,12 @@
                     "com.android.systemui:CAMERA_GESTURE");
         }
         vibrateForCameraGesture();
+
+        if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) {
+            Log.v(TAG, "Camera launch");
+            mKeyguardUpdateMonitor.onCameraLaunched();
+        }
+
         if (!mStatusBarKeyguardViewManager.isShowing()) {
             startActivityDismissingKeyguard(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
                     false /* onlyProvisioned */, true /* dismissShade */,
@@ -3786,7 +3795,7 @@
                 // comes on.
                 mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
             }
-            if (isScreenTurningOnOrOn()) {
+            if (isWakingUpOrAwake()) {
                 if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Launching camera");
                 if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                     mStatusBarKeyguardViewManager.reset(true /* hide */);
@@ -3799,7 +3808,7 @@
                 // incorrectly get notified because of the screen on event (which resumes and pauses
                 // some activities)
                 if (DEBUG_CAMERA_LIFT) Slog.d(TAG, "Deferring until screen turns on");
-                mLaunchCameraOnScreenTurningOn = true;
+                mLaunchCameraWhenFinishedWaking = true;
             }
         }
     }
@@ -3824,15 +3833,17 @@
                 == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
     }
 
-    private boolean isScreenTurningOnOrOn() {
-        return mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_ON
-                || mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
+    private boolean isWakingUpOrAwake() {
+        return mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE
+                || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING;
     }
 
     public void notifyBiometricAuthModeChanged() {
         updateDozing();
+        mScrimController.setUnlockIsFading(mBiometricUnlockController.isUnlockFading());
         updateScrimController();
-        mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock());
+        mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock(),
+                mBiometricUnlockController.isBiometricUnlock());
     }
 
     @VisibleForTesting
@@ -3841,7 +3852,8 @@
 
         // We don't want to end up in KEYGUARD state when we're unlocking with
         // fingerprint from doze. We should cross fade directly from black.
-        boolean wakeAndUnlocking = mBiometricUnlockController.isWakeAndUnlock();
+        boolean unlocking = mBiometricUnlockController.isWakeAndUnlock()
+                || mKeyguardMonitor.isKeyguardFadingAway();
 
         // Do not animate the scrim expansion when triggered by the fingerprint sensor.
         mScrimController.setExpansionAffectsAlpha(
@@ -3858,7 +3870,7 @@
             ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
                     ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
             mScrimController.transitionTo(state);
-        } else if (isInLaunchTransition() || mLaunchCameraOnScreenTurningOn
+        } else if (isInLaunchTransition() || mLaunchCameraWhenFinishedWaking
                 || launchingAffordanceWithPreview) {
             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
         } else if (mBrightnessMirrorVisible) {
@@ -3866,9 +3878,9 @@
         } else if (isPulsing()) {
             mScrimController.transitionTo(ScrimState.PULSING,
                     mDozeScrimController.getScrimCallback());
-        } else if (mDozing && !wakeAndUnlocking) {
+        } else if (mDozing && !unlocking) {
             mScrimController.transitionTo(ScrimState.AOD);
-        } else if (mIsKeyguard && !wakeAndUnlocking) {
+        } else if (mIsKeyguard && !unlocking) {
             mScrimController.transitionTo(ScrimState.KEYGUARD);
         } else if (mBubbleController.isStackExpanded()) {
             mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED);
@@ -3892,8 +3904,9 @@
         private boolean mAnimateWakeup;
         private boolean mAnimateScreenOff;
         private boolean mIgnoreTouchWhilePulsing;
-        private boolean mWakeLockScreenPerformsAuth = SystemProperties.getBoolean(
-                "persist.sysui.wake_performs_auth", false);
+        @VisibleForTesting
+        boolean mWakeLockScreenPerformsAuth = SystemProperties.getBoolean(
+                "persist.sysui.wake_performs_auth", true);
 
         @Override
         public String toString() {
@@ -3949,9 +3962,8 @@
                 mStatusBarWindow.suppressWakeUpGesture(true);
             }
 
-            boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_NOTIFICATION || (
-                    reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
-                            && mWakeLockScreenPerformsAuth);
+            boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
+                            && mWakeLockScreenPerformsAuth;
             // 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
             // are black, indicating that StatusBar is ready to present the rest of the UI.
@@ -3977,6 +3989,7 @@
                 }
 
                 private void setPulsing(boolean pulsing) {
+                    mStatusBarStateController.setPulsing(pulsing);
                     mStatusBarKeyguardViewManager.setPulsing(pulsing);
                     mKeyguardViewMediator.setPulsing(pulsing);
                     mNotificationPanel.setPulsing(pulsing);
@@ -4019,7 +4032,6 @@
         @Override
         public void dozeTimeTick() {
             mNotificationPanel.dozeTimeTick();
-            mNotificationIconAreaController.dozeTimeTick();
             if (mAmbientIndicationContainer instanceof DozeReceiver) {
                 ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick();
             }
@@ -4056,8 +4068,8 @@
             if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
                 mScrimController.setWakeLockScreenSensorActive(true);
             }
-            if (mDozeScrimController.isPulsing() && mAmbientPulseManager.hasNotifications()) {
-                mAmbientPulseManager.extendPulse();
+            if (mDozeScrimController.isPulsing() && mHeadsUpManager.hasNotifications()) {
+                mHeadsUpManager.extendHeadsUp();
             } else {
                 mDozeScrimController.extendPulse();
             }
@@ -4109,6 +4121,11 @@
             mScrimController.setAodFrontScrimAlpha(scrimOpacity);
         }
 
+        @Override
+        public void prepareForGentleWakeUp() {
+            mScrimController.prepareForGentleWakeUp();
+        }
+
         private void dispatchTap(View view, float x, float y) {
             long now = SystemClock.elapsedRealtime();
             dispatchTouchEvent(view, x, y, now, MotionEvent.ACTION_DOWN);
@@ -4146,12 +4163,6 @@
 
     protected NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
 
-
-    // for heads up notifications
-    protected HeadsUpManagerPhone mHeadsUpManager;
-
-    protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
-
     // handling reordering
     protected VisualStabilityManager mVisualStabilityManager;
 
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 93168db..5ce1329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_FADING;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
 import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
 
@@ -43,6 +44,7 @@
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.CommandQueue;
@@ -51,6 +53,7 @@
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
 import com.android.systemui.statusbar.phone.KeyguardBouncer.BouncerExpansionCallback;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -132,6 +135,7 @@
 
     private ViewGroup mContainer;
     private ViewGroup mLockIconContainer;
+    private View mNotificationContainer;
 
     protected KeyguardBouncer mBouncer;
     protected boolean mShowing;
@@ -165,9 +169,10 @@
             (KeyguardMonitorImpl) Dependency.get(KeyguardMonitor.class);
     private final NotificationMediaManager mMediaManager =
             Dependency.get(NotificationMediaManager.class);
-    private final StatusBarStateController mStatusBarStateController =
-            Dependency.get(StatusBarStateController.class);
+    private final SysuiStatusBarStateController mStatusBarStateController =
+            (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class);
     private final DockManager mDockManager;
+    private KeyguardBypassController mBypassController;
 
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
@@ -205,7 +210,8 @@
             NotificationPanelView notificationPanelView,
             BiometricUnlockController biometricUnlockController,
             DismissCallbackRegistry dismissCallbackRegistry,
-            ViewGroup lockIconContainer) {
+            ViewGroup lockIconContainer, View notificationContainer,
+            KeyguardBypassController bypassController, FalsingManager falsingManager) {
         mStatusBar = statusBar;
         mContainer = container;
         mLockIconContainer = lockIconContainer;
@@ -215,9 +221,11 @@
         mBiometricUnlockController = biometricUnlockController;
         mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext,
                 mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry,
-                mExpansionCallback);
+                mExpansionCallback, falsingManager);
         mNotificationPanelView = notificationPanelView;
         notificationPanelView.setExpansionListener(this);
+        mBypassController = bypassController;
+        mNotificationContainer = notificationContainer;
     }
 
     @Override
@@ -261,7 +269,7 @@
         boolean keyguardWithoutQs = mStatusBarStateController.getState() == StatusBarState.KEYGUARD
                 && !mNotificationPanelView.isQsExpanded();
         boolean lockVisible = (mBouncer.isShowing() || keyguardWithoutQs)
-                && !mBouncer.isAnimatingAway();
+                && !mBouncer.isAnimatingAway() && !mKeyguardMonitor.isKeyguardFadingAway();
 
         if (mLastLockVisible != lockVisible) {
             mLastLockVisible = lockVisible;
@@ -270,8 +278,14 @@
                         AppearAnimationUtils.DEFAULT_APPEAR_DURATION /* duration */,
                         0 /* delay */);
             } else {
+                final long duration;
+                if (needsBypassFading()) {
+                    duration = KeyguardBypassController.BYPASS_PANEL_FADE_DURATION;
+                } else {
+                    duration = AppearAnimationUtils.DEFAULT_APPEAR_DURATION / 2;
+                }
                 CrossFadeHelper.fadeOut(mLockIconContainer,
-                        AppearAnimationUtils.DEFAULT_APPEAR_DURATION / 2 /* duration */,
+                        duration /* duration */,
                         0 /* delay */, null /* runnable */);
             }
         }
@@ -555,12 +569,32 @@
             mBiometricUnlockController.startKeyguardFadingAway();
             hideBouncer(true /* destroyView */);
             if (wakeUnlockPulsing) {
-                mStatusBar.fadeKeyguardWhilePulsing();
+                if (needsBypassFading()) {
+                    ViewGroupFadeHelper.fadeOutAllChildrenExcept(mNotificationPanelView,
+                            mNotificationContainer,
+                            KeyguardBypassController.BYPASS_PANEL_FADE_DURATION,
+                                    () -> {
+                        mStatusBar.hideKeyguard();
+                        onKeyguardFadedAway();
+                    });
+                } else {
+                    mStatusBar.fadeKeyguardWhilePulsing();
+                }
                 wakeAndUnlockDejank();
             } else {
-                boolean staying = mStatusBar.hideKeyguard();
+                boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
                 if (!staying) {
                     mStatusBarWindowController.setKeyguardFadingAway(true);
+                    if (needsBypassFading()) {
+                        ViewGroupFadeHelper.fadeOutAllChildrenExcept(mNotificationPanelView,
+                                mNotificationContainer,
+                                KeyguardBypassController.BYPASS_PANEL_FADE_DURATION,
+                                () -> {
+                                    mStatusBar.hideKeyguard();
+                                });
+                    } else {
+                        mStatusBar.hideKeyguard();
+                    }
                     // hide() will happen asynchronously and might arrive after the scrims
                     // were already hidden, this means that the transition callback won't
                     // be triggered anymore and StatusBarWindowController will be forever in
@@ -568,10 +602,12 @@
                     mStatusBar.updateScrimController();
                     wakeAndUnlockDejank();
                 } else {
+                    mStatusBar.hideKeyguard();
                     mStatusBar.finishKeyguardFadingAway();
                     mBiometricUnlockController.finishKeyguardFadingAway();
                 }
             }
+            updateLockIcon();
             updateStates();
             mStatusBarWindowController.setKeyguardShowing(false);
             mViewMediatorCallback.keyguardGone();
@@ -580,6 +616,13 @@
             StatsLog.KEYGUARD_STATE_CHANGED__STATE__HIDDEN);
     }
 
+    private boolean needsBypassFading() {
+        return (mBiometricUnlockController.getMode() == MODE_UNLOCK_FADING
+                || mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK_PULSING
+                || mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK)
+                && mBypassController.getBypassEnabled();
+    }
+
     @Override
     public void onDensityOrFontScaleChanged() {
         hideBouncer(true /* destroyView */);
@@ -602,6 +645,7 @@
     public void onKeyguardFadedAway() {
         mContainer.postDelayed(() -> mStatusBarWindowController.setKeyguardFadingAway(false),
                 100);
+        ViewGroupFadeHelper.reset(mNotificationPanelView);
         mStatusBar.finishKeyguardFadingAway();
         mBiometricUnlockController.finishKeyguardFadingAway();
         WindowManagerGlobal.getInstance().trimMemory(
@@ -677,8 +721,12 @@
         return mBouncer.isShowing();
     }
 
-    public boolean isBouncerPartiallyVisible() {
-        return mBouncer.isPartiallyVisible();
+    /**
+     * When bouncer is fully visible or {@link KeyguardBouncer#show(boolean)} was called but
+     * animation didn't finish yet.
+     */
+    public boolean bouncerIsOrWillBeShowing() {
+        return mBouncer.isShowing() || mBouncer.inTransit();
     }
 
     public boolean isFullscreenBouncer() {
@@ -730,6 +778,7 @@
         if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
             mStatusBarWindowController.setBouncerShowing(bouncerShowing);
             mStatusBar.setBouncerShowing(bouncerShowing);
+            updateLockIcon();
         }
 
         KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
@@ -812,6 +861,14 @@
         return mStatusBar.isInLaunchTransition();
     }
 
+
+    /**
+     * @return Whether subtle animation should be used for unlocking the device.
+     */
+    public boolean shouldSubtleWindowAnimationsForUnlock() {
+        return needsBypassFading();
+    }
+
     public boolean isGoingToNotificationShade() {
         return ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
                 .leaveOpenOnKeyguardHide();
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 e00d439..bec53a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -406,8 +406,7 @@
     }
 
     private void handleFullScreenIntent(NotificationEntry entry) {
-        boolean isHeadsUped = mNotificationInterruptionStateProvider.shouldHeadsUp(entry);
-        if (!isHeadsUped && entry.notification.getNotification().fullScreenIntent != null) {
+        if (mNotificationInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) {
             if (shouldSuppressFullScreenIntent(entry)) {
                 if (DEBUG) {
                     Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + entry.key);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 6fe8964..a87dca4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -49,7 +49,6 @@
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationMediaManager;
@@ -106,7 +105,6 @@
             Dependency.get(VisualStabilityManager.class);
     private final NotificationGutsManager mGutsManager =
             Dependency.get(NotificationGutsManager.class);
-    protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
 
     private final NotificationPanelView mNotificationPanel;
     private final HeadsUpManagerPhone mHeadsUpManager;
@@ -213,7 +211,6 @@
             mEntryManager.setUpWithPresenter(this, notifListContainer, mHeadsUpManager);
             mEntryManager.addNotificationEntryListener(notificationEntryListener);
             mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager);
-            mEntryManager.addNotificationLifetimeExtender(mAmbientPulseManager);
             mEntryManager.addNotificationLifetimeExtender(mGutsManager);
             mEntryManager.addNotificationLifetimeExtenders(
                     remoteInputManager.getLifetimeExtenders());
@@ -297,7 +294,7 @@
 
     private void maybeEndAmbientPulse() {
         if (mNotificationPanel.hasPulsingNotifications() &&
-                !mAmbientPulseManager.hasNotifications()) {
+                !mHeadsUpManager.hasNotifications()) {
             // We were showing a pulse for a notification, but no notifications are pulsing anymore.
             // Finish the pulse.
             mDozeScrimController.pulseOutNow();
@@ -343,10 +340,6 @@
     }
 
     public boolean canHeadsUp(NotificationEntry entry, StatusBarNotification sbn) {
-        if (mShadeController.isDozing()) {
-            return false;
-        }
-
         if (mShadeController.isOccluded()) {
             boolean devicePublic = mLockscreenUserManager.
                     isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
@@ -354,6 +347,7 @@
                     || mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
             boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
             if (userPublic && needsRedaction) {
+                // TODO(b/135046837): we can probably relax this with dynamic privacy
                 return false;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index 6691f7a..13d4b8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -48,6 +48,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
+import com.android.systemui.statusbar.policy.RemoteInputView;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -93,9 +94,11 @@
 
     @Override
     public void onStateChanged(int state) {
-        if (state == StatusBarState.SHADE && mStatusBarStateController.leaveOpenOnKeyguardHide()) {
+        boolean hasPendingRemoteInput = mPendingRemoteInputView != null;
+        if (state == StatusBarState.SHADE
+                && (mStatusBarStateController.leaveOpenOnKeyguardHide() || hasPendingRemoteInput)) {
             if (!mStatusBarStateController.isKeyguardRequested()) {
-                if (mPendingRemoteInputView != null) {
+                if (hasPendingRemoteInput) {
                     mMainHandler.post(mPendingRemoteInputView::callOnClick);
                 }
                 mPendingRemoteInputView = null;
@@ -105,7 +108,9 @@
 
     @Override
     public void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
-        mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+        if (!row.isPinned()) {
+            mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+        }
         mShadeController.showBouncer(true /* scrimmed */);
         mPendingRemoteInputView = clicked;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 2558d77..8286d26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -22,7 +22,6 @@
 import android.util.ArraySet;
 import android.util.Log;
 
-import com.android.settingslib.graph.SignalDrawable;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.NetworkController;
@@ -187,8 +186,8 @@
 
         // Visibility of the data type indicator changed
         boolean typeChanged = statusType != state.typeId && (statusType == 0 || state.typeId == 0);
-        state.visible = statusIcon.visible && !mBlockMobile
-                && !isInEmptyStateOnSingleSimDevice(subId, statusIcon.icon);
+
+        state.visible = statusIcon.visible && !mBlockMobile;
         state.strengthId = statusIcon.icon;
         state.typeId = statusType;
         state.contentDescription = statusIcon.contentDescription;
@@ -210,12 +209,6 @@
         }
     }
 
-    private boolean isInEmptyStateOnSingleSimDevice(int subId, int icon) {
-        return mMobileStates.size() == 1
-                && mMobileStates.get(0).subId == subId
-                && SignalDrawable.isEmptyState(icon);
-    }
-
     private MobileIconState getState(int subId) {
         for (MobileIconState state : mMobileStates) {
             if (state.subId == subId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
new file mode 100644
index 0000000..f33ff27
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
@@ -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.
+ */
+package com.android.systemui.statusbar.phone;
+
+public interface StatusBarWindowCallback {
+    void onStateChanged(boolean keyguardShowing, boolean keyguardOccluded, boolean bouncerShowing);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index f08db1b..4ddd0e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -22,7 +22,6 @@
 
 import android.app.ActivityManager;
 import android.app.IActivityManager;
-import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
@@ -51,10 +50,13 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 
+import com.google.android.collect.Lists;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
 
+import java.util.ArrayList;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
@@ -72,6 +74,7 @@
     private final DozeParameters mDozeParameters;
     private final WindowManager.LayoutParams mLpChanged;
     private final boolean mKeyguardScreenRotation;
+    private final long mLockScreenDisplayTimeout;
     private ViewGroup mStatusBarView;
     private WindowManager.LayoutParams mLp;
     private boolean mHasTopUi;
@@ -81,6 +84,8 @@
     private final State mCurrentState = new State();
     private OtherwisedCollapsedListener mListener;
     private ForcePluginOpenListener mForcePluginOpenListener;
+    private final ArrayList<WeakReference<StatusBarWindowCallback>>
+            mCallbacks = Lists.newArrayList();
 
     private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
 
@@ -100,12 +105,27 @@
         mDozeParameters = dozeParameters;
         mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
         mLpChanged = new WindowManager.LayoutParams();
+        mLockScreenDisplayTimeout = context.getResources()
+                .getInteger(R.integer.config_lockScreenDisplayTimeout);
         ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
                 .addCallback(mStateListener,
                         SysuiStatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
+    /**
+     * Register to receive notifications about status bar window state changes.
+     */
+    public void registerCallback(StatusBarWindowCallback callback) {
+        // Prevent adding duplicate callbacks
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            if (mCallbacks.get(i).get() == callback) {
+                return;
+            }
+        }
+        mCallbacks.add(new WeakReference<StatusBarWindowCallback>(callback));
+    }
+
     private boolean shouldEnableKeyguardScreenRotation() {
         Resources res = mContext.getResources();
         return SystemProperties.getBoolean("lockscreen.rot_override", false)
@@ -263,7 +283,8 @@
         if (state.isKeyguardShowingAndNotOccluded()
                 && state.statusBarState == StatusBarState.KEYGUARD
                 && !state.qsExpanded) {
-            mLpChanged.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
+            mLpChanged.userActivityTimeout = state.bouncerShowing
+                    ? KeyguardViewMediator.AWAKE_INTERVAL_BOUNCER_MS : mLockScreenDisplayTimeout;
         } else {
             mLpChanged.userActivityTimeout = -1;
         }
@@ -316,6 +337,18 @@
             }
             mHasTopUi = mHasTopUiChanged;
         }
+        notifyStateChangedCallbacks();
+    }
+
+    public void notifyStateChangedCallbacks() {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            StatusBarWindowCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onStateChanged(mCurrentState.keyguardShowing,
+                        mCurrentState.keyguardOccluded,
+                        mCurrentState.bouncerShowing);
+            }
+        }
     }
 
     private void applyForceStatusBarVisibleFlag(State state) {
@@ -555,17 +588,7 @@
             return;
         }
 
-        StatusBarStateController state = Dependency.get(StatusBarStateController.class);
-        int which;
-        if (state.getState() == StatusBarState.KEYGUARD
-                || state.getState() == StatusBarState.SHADE_LOCKED) {
-            which = WallpaperManager.FLAG_LOCK;
-        } else {
-            which = WallpaperManager.FLAG_SYSTEM;
-        }
-        final boolean useDarkText = mColorExtractor.getColors(which,
-                true /* ignoreVisibility */).supportsDarkText();
-
+        final boolean useDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         // Make sure we have the correct navbar/statusbar colors.
         setKeyguardDark(useDarkText);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 7d5f23b..f1049f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -62,7 +62,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
-import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.DragDownHelper;
@@ -149,13 +148,14 @@
      * events manually as it's outside of the regular view bounds.
      */
     private boolean mExpandingBelowNotch;
+    private KeyguardBypassController mBypassController;
 
     public StatusBarWindowView(Context context, AttributeSet attrs) {
         super(context, attrs);
         setMotionEventSplittingEnabled(false);
         mTransparentSrcPaint.setColor(0);
         mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
-        mFalsingManager = FalsingManagerFactory.getInstance(context);
+        mFalsingManager = Dependency.get(FalsingManager.class);  // TODO: inject into a controller.
         mGestureDetector = new GestureDetector(context, mGestureListener);
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
         Dependency.get(TunerService.class).addTunable(mTunable,
@@ -271,10 +271,11 @@
     /**
      * Called when the biometric authentication mode changes.
      * @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
+     * @param isUnlock If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
      */
-    public void onBiometricAuthModeChanged(boolean wakeAndUnlock) {
+    public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
         if (mLockIcon != null) {
-            mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock);
+            mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
         }
     }
 
@@ -288,7 +289,7 @@
         ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback();
         DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback();
         setDragDownHelper(new DragDownHelper(getContext(), this, expandHelperCallback,
-                dragDownCallback));
+                dragDownCallback, mFalsingManager));
     }
 
     @VisibleForTesting
@@ -415,9 +416,9 @@
         }
         boolean intercept = false;
         if (mNotificationPanel.isFullyExpanded()
-                && stackScrollLayout.getVisibility() == View.VISIBLE
                 && mStatusBarStateController.getState() == StatusBarState.KEYGUARD
                 && !mService.isBouncerShowing()
+                && !mBypassController.getBypassEnabled()
                 && !mService.isDozing()) {
             intercept = mDragDownHelper.onInterceptTouchEvent(ev);
         }
@@ -440,7 +441,8 @@
         if (mService.isDozing()) {
             handled = !mService.isPulsing();
         }
-        if ((mStatusBarStateController.getState() == StatusBarState.KEYGUARD && !handled)
+        if ((mStatusBarStateController.getState() == StatusBarState.KEYGUARD && !handled
+                && !mBypassController.getBypassEnabled())
                 || mDragDownHelper.isDraggingDown()) {
             // we still want to finish our drag down gesture when locking the screen
             handled = mDragDownHelper.onTouchEvent(ev);
@@ -519,6 +521,16 @@
         }
     }
 
+    public void setBypassController(KeyguardBypassController bypassController) {
+        mBypassController = bypassController;
+    }
+
+    public void setBouncerShowingScrimmed(boolean bouncerShowing) {
+        if (mLockIcon != null) {
+            mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
+        }
+    }
+
     public class LayoutParams extends FrameLayout.LayoutParams {
 
         public boolean ignoreRightInset;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 48a9fb6..e61a67c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -20,7 +20,6 @@
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.UserHandle;
@@ -34,10 +33,13 @@
 
 /**
  * Base class for dialogs that should appear over panels and keyguard.
+ * The SystemUIDialog registers a listener for the screen off / close system dialogs broadcast,
+ * and dismisses itself when it receives the broadcast.
  */
 public class SystemUIDialog extends AlertDialog {
 
     private final Context mContext;
+    private final DismissReceiver mDismissReceiver;
 
     public SystemUIDialog(Context context) {
         this(context, R.style.Theme_SystemUI_Dialog);
@@ -52,7 +54,19 @@
         attrs.setTitle(getClass().getSimpleName());
         getWindow().setAttributes(attrs);
 
-        registerDismissListener(this);
+        mDismissReceiver = new DismissReceiver(this);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mDismissReceiver.register();
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mDismissReceiver.unregister();
     }
 
     public void setShowForAllUsers(boolean show) {
@@ -100,12 +114,22 @@
         return dialog;
     }
 
+    /**
+     * Registers a listener that dismisses the given dialog when it receives
+     * the screen off / close system dialogs broadcast.
+     * <p>
+     * <strong>Note:</strong> Don't call dialog.setOnDismissListener() after
+     * calling this because it causes a leak of BroadcastReceiver.
+     *
+     * @param dialog The dialog to be associated with the listener.
+     */
     public static void registerDismissListener(Dialog dialog) {
         DismissReceiver dismissReceiver = new DismissReceiver(dialog);
+        dialog.setOnDismissListener(d -> dismissReceiver.unregister());
         dismissReceiver.register();
     }
 
-    private static class DismissReceiver extends BroadcastReceiver implements OnDismissListener {
+    private static class DismissReceiver extends BroadcastReceiver {
         private static final IntentFilter INTENT_FILTER = new IntentFilter();
         static {
             INTENT_FILTER.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
@@ -125,16 +149,16 @@
             mRegistered = true;
         }
 
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            mDialog.dismiss();
-        }
-
-        @Override
-        public void onDismiss(DialogInterface dialog) {
+        void unregister() {
             if (mRegistered) {
                 mDialog.getContext().unregisterReceiver(this);
                 mRegistered = false;
             }
         }
-    }}
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mDialog.dismiss();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 39bf728..a71fcdb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -16,18 +16,14 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.biometrics.BiometricSourceType;
-import android.media.AudioManager;
 import android.os.Build;
 import android.os.Trace;
-import android.telephony.TelephonyManager;
 
-import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -55,6 +51,7 @@
     private boolean mTrustManaged;
     private boolean mTrusted;
     private boolean mDebugUnlocked = false;
+    private boolean mIsUnlockingWithFacePossible;
 
     private UnlockMethodCache(Context ctx) {
         mLockPatternUtils = new LockPatternUtils(ctx);
@@ -110,6 +107,13 @@
         mListeners.remove(listener);
     }
 
+    /**
+     * If there are faces enrolled and user enabled face auth on keyguard.
+     */
+    public boolean isUnlockingWithFacePossible() {
+        return mIsUnlockingWithFacePossible;
+    }
+
     private void update(boolean updateAlways) {
         Trace.beginSection("UnlockMethodCache#update");
         int user = KeyguardUpdateMonitor.getCurrentUser();
@@ -118,13 +122,16 @@
                 || (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB && mDebugUnlocked);
         boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
         boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
-        boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
-                trustManaged != mTrustManaged;
+        boolean isUnlockingWithFacePossible = mKeyguardUpdateMonitor.isUnlockWithFacePossible(user);
+        boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer
+                || trustManaged != mTrustManaged
+                || mIsUnlockingWithFacePossible != isUnlockingWithFacePossible;
         if (changed || updateAlways) {
             mSecure = secure;
             mCanSkipBouncer = canSkipBouncer;
             mTrusted = trusted;
             mTrustManaged = trustManaged;
+            mIsUnlockingWithFacePossible = isUnlockingWithFacePossible;
             notifyListeners();
         }
         Trace.endSection();
@@ -187,6 +194,11 @@
         public void onKeyguardVisibilityChanged(boolean showing) {
             update(false /* updateAlways */);
         }
+
+        @Override
+        public void onBiometricsCleared() {
+            update(false /* alwaysUpdate */);
+        }
     };
 
     public boolean isTrustManaged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 78e845a..40c3d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -294,6 +294,18 @@
     }
 
     @Override
+    public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
+            int state, int bluetoothProfile) {
+        if (DEBUG) {
+            Log.d(TAG, "ProfileConnectionStateChanged=" + cachedDevice.getAddress() + " "
+                    + stateToString(state) + " profileId=" + bluetoothProfile);
+        }
+        mCachedState.remove(cachedDevice);
+        updateConnected();
+        mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
+    }
+
+    @Override
     public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
         if (DEBUG) {
             Log.d(TAG, "ACLConnectionStateChanged=" + cachedDevice.getAddress() + " "
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index d1a2253..b84dc47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -356,6 +356,10 @@
     public void onDensityOrFontScaleChanged() {
     }
 
+    public boolean isEntryAutoHeadsUpped(String key) {
+        return false;
+    }
+
     /**
      * This represents a notification and how long it is in a heads up mode. It also manages its
      * lifecycle automatically when created.
@@ -416,16 +420,17 @@
 
         @Override
         protected long calculateFinishTime() {
-            return mPostTime + getRecommendedTimeoutMillis();
+            return mPostTime + getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay);
         }
 
         /**
          * Get user-preferred or default timeout duration. The larger one will be returned.
          * @return milliseconds before auto-dismiss
+         * @param requestedTimeout
          */
-        private int getRecommendedTimeoutMillis() {
+        protected int getRecommendedHeadsUpTimeoutMs(int requestedTimeout) {
             return mAccessibilityMgr.getRecommendedTimeoutMillis(
-                    mAutoDismissNotificationDecay,
+                    requestedTimeout,
                     AccessibilityManager.FLAG_CONTENT_CONTROLS
                             | AccessibilityManager.FLAG_CONTENT_ICONS
                             | AccessibilityManager.FLAG_CONTENT_TEXT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
index 568de63..8fcaa67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
@@ -82,9 +82,9 @@
     private AnimatedVectorDrawable mAnimatedDrawable;
 
     public KeyButtonDrawable(Drawable d, @ColorInt int lightColor, @ColorInt int darkColor,
-            boolean horizontalFlip, boolean hasOvalBg) {
+            boolean horizontalFlip, Color ovalBackgroundColor) {
         this(d, new ShadowDrawableState(lightColor, darkColor,
-                d instanceof AnimatedVectorDrawable, horizontalFlip, hasOvalBg));
+                d instanceof AnimatedVectorDrawable, horizontalFlip, ovalBackgroundColor));
     }
 
     private KeyButtonDrawable(Drawable d, ShadowDrawableState state) {
@@ -166,7 +166,7 @@
     public void setColorFilter(ColorFilter colorFilter) {
         mIconPaint.setColorFilter(colorFilter);
         if (mAnimatedDrawable != null) {
-            if (mState.mHasOvalBg) {
+            if (hasOvalBg()) {
                 mAnimatedDrawable.setColorFilter(
                         new PorterDuffColorFilter(mState.mLightColor, PorterDuff.Mode.SRC_IN));
             } else {
@@ -212,15 +212,6 @@
         return mState.mBaseWidth + (mState.mShadowSize + Math.abs(mState.mShadowOffsetX)) * 2;
     }
 
-    /** Return if the drawable has oval background. */
-    public boolean hasOvalBg() {
-        return mState.mHasOvalBg;
-    }
-
-    public int getDarkColor() {
-        return mState.mDarkColor;
-    }
-
     public boolean canAnimate() {
         return mState.mSupportsAnimation;
     }
@@ -290,6 +281,14 @@
         return mState.canApplyTheme();
     }
 
+    @ColorInt int getDrawableBackgroundColor() {
+        return mState.mOvalBackgroundColor.toArgb();
+    }
+
+    boolean hasOvalBg() {
+        return mState.mOvalBackgroundColor != null;
+    }
+
     private void regenerateBitmapIconCache() {
         final int width = getIntrinsicWidth();
         final int height = getIntrinsicHeight();
@@ -394,16 +393,16 @@
         final int mLightColor;
         final int mDarkColor;
         final boolean mSupportsAnimation;
-        final boolean mHasOvalBg;
+        final Color mOvalBackgroundColor;
 
         public ShadowDrawableState(@ColorInt int lightColor, @ColorInt int darkColor,
-                boolean animated, boolean horizontalFlip, boolean hasOvalBg) {
+                boolean animated, boolean horizontalFlip, Color ovalBackgroundColor) {
             mLightColor = lightColor;
             mDarkColor = darkColor;
             mSupportsAnimation = animated;
             mAlpha = 255;
             mHorizontalFlip = horizontalFlip;
-            mHasOvalBg = hasOvalBg;
+            mOvalBackgroundColor = ovalBackgroundColor;
         }
 
         @Override
@@ -428,16 +427,17 @@
      * @param ctx Context to get the drawable and determine the dark and light theme
      * @param icon the icon resource id
      * @param hasShadow if a shadow will appear with the drawable
-     * @param hasOvalBg if an oval bg will be drawn
+     * @param ovalBackgroundColor the color of the oval bg that will be drawn
      * @return KeyButtonDrawable
      */
     public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon,
-            boolean hasShadow, boolean hasOvalBg) {
+            boolean hasShadow, Color ovalBackgroundColor) {
         final int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
         final int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
         Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
         Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
-        return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow, hasOvalBg);
+        return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow,
+                ovalBackgroundColor);
     }
 
     /**
@@ -446,7 +446,7 @@
      */
     public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon,
             boolean hasShadow) {
-        return create(ctx, icon, hasShadow, false /* hasOvalBg */);
+        return create(ctx, icon, hasShadow, null /* ovalBackgroundColor */);
     }
 
     /**
@@ -454,11 +454,11 @@
      * {@link #create(Context, int, boolean, boolean)}.
      */
     public static KeyButtonDrawable create(Context lightContext, Context darkContext,
-            @DrawableRes int iconResId, boolean hasShadow, boolean hasOvalBg) {
+            @DrawableRes int iconResId, boolean hasShadow, Color ovalBackgroundColor) {
         return create(lightContext,
             Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor),
             Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor),
-            iconResId, hasShadow, hasOvalBg);
+            iconResId, hasShadow, ovalBackgroundColor);
     }
 
     /**
@@ -467,12 +467,12 @@
      */
     public static KeyButtonDrawable create(Context context, @ColorInt int lightColor,
             @ColorInt int darkColor, @DrawableRes int iconResId, boolean hasShadow,
-            boolean hasOvalBg) {
+            Color ovalBackgroundColor) {
         final Resources res = context.getResources();
         boolean isRtl = res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
         Drawable d = context.getDrawable(iconResId);
         final KeyButtonDrawable drawable = new KeyButtonDrawable(d, lightColor, darkColor,
-                isRtl && d.isAutoMirrored(), hasOvalBg);
+                isRtl && d.isAutoMirrored(), ovalBackgroundColor);
         if (hasShadow) {
             int offsetX = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_x);
             int offsetY = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_y);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index c9579fd..c2f246f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -79,6 +79,7 @@
     private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
     private final InputManager mInputManager;
     private final Paint mOvalBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+    private float mDarkIntensity;
     private boolean mHasOvalBg = false;
 
     private final Runnable mCheckLongPress = new Runnable() {
@@ -248,13 +249,8 @@
                 x = (int)ev.getRawX();
                 y = (int)ev.getRawY();
 
-                boolean exceededTouchSlopX = Math.abs(x - mTouchDownX) > (mIsVertical
-                        ? QuickStepContract.getQuickScrubTouchSlopPx()
-                        : QuickStepContract.getQuickStepTouchSlopPx());
-                boolean exceededTouchSlopY = Math.abs(y - mTouchDownY) > (mIsVertical
-                        ? QuickStepContract.getQuickStepTouchSlopPx()
-                        : QuickStepContract.getQuickScrubTouchSlopPx());
-                if (exceededTouchSlopX || exceededTouchSlopY) {
+                float slop = QuickStepContract.getQuickStepTouchSlopPx(getContext());
+                if (Math.abs(x - mTouchDownX) > slop || Math.abs(y - mTouchDownY) > slop) {
                     // When quick step is enabled, prevent animating the ripple triggered by
                     // setPressed and decide to run it on touch up
                     setPressed(false);
@@ -304,6 +300,23 @@
         return true;
     }
 
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+        super.setImageDrawable(drawable);
+
+        if (drawable == null) {
+            return;
+        }
+        KeyButtonDrawable keyButtonDrawable = (KeyButtonDrawable) drawable;
+        keyButtonDrawable.setDarkIntensity(mDarkIntensity);
+        mHasOvalBg = keyButtonDrawable.hasOvalBg();
+        if (mHasOvalBg) {
+            mOvalBgPaint.setColor(keyButtonDrawable.getDrawableBackgroundColor());
+        }
+        mRipple.setType(keyButtonDrawable.hasOvalBg() ? KeyButtonRipple.Type.OVAL
+                : KeyButtonRipple.Type.ROUNDED_RECT);
+    }
+
     public void playSoundEffect(int soundConstant) {
         if (!mPlaySounds) return;
         mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
@@ -360,17 +373,11 @@
 
     @Override
     public void setDarkIntensity(float darkIntensity) {
+        mDarkIntensity = darkIntensity;
+
         Drawable drawable = getDrawable();
         if (drawable != null) {
-            KeyButtonDrawable keyButtonDrawable = (KeyButtonDrawable) drawable;
-            keyButtonDrawable.setDarkIntensity(darkIntensity);
-            mHasOvalBg = keyButtonDrawable.hasOvalBg();
-            if (mHasOvalBg) {
-                mOvalBgPaint.setColor(keyButtonDrawable.getDarkColor());
-            }
-            mRipple.setType(keyButtonDrawable.hasOvalBg() ? KeyButtonRipple.Type.OVAL
-                    : KeyButtonRipple.Type.ROUNDED_RECT);
-
+            ((KeyButtonDrawable) drawable).setDarkIntensity(darkIntensity);
             // Since we reuse the same drawable for multiple views, we need to invalidate the view
             // manually.
             invalidate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
index 01498e6..f61b556 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
@@ -50,5 +50,6 @@
 
     interface Callback {
         void onKeyguardShowingChanged();
+        default void onKeyguardFadingAwayChanged() {}
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
index b53ff0e..68d0070 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
@@ -141,14 +141,24 @@
     }
 
     public void notifyKeyguardFadingAway(long delay, long fadeoutDuration) {
-        mKeyguardFadingAway = true;
+        setKeyguardFadingAway(true);
         mKeyguardFadingAwayDelay = delay;
         mKeyguardFadingAwayDuration = fadeoutDuration;
     }
 
+    private void setKeyguardFadingAway(boolean keyguardFadingAway) {
+        if (mKeyguardFadingAway != keyguardFadingAway) {
+            mKeyguardFadingAway = keyguardFadingAway;
+            ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
+            for (int i = 0; i < callbacks.size(); i++) {
+                callbacks.get(i).onKeyguardFadingAwayChanged();
+            }
+        }
+    }
+
     public void notifyKeyguardDoneFading() {
-        mKeyguardFadingAway = false;
         mKeyguardGoingAway = false;
+        setKeyguardFadingAway(false);
     }
 
     @Override
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 2afe485..4562763 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -163,7 +163,8 @@
                         | PhoneStateListener.LISTEN_CALL_STATE
                         | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
                         | PhoneStateListener.LISTEN_DATA_ACTIVITY
-                        | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE);
+                        | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE
+                        | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
         mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA),
                 true, mObserver);
         mContext.getContentResolver().registerContentObserver(Global.getUriFor(
@@ -376,9 +377,9 @@
     }
 
     private void updateDataSim() {
-        int defaultDataSub = mDefaults.getDefaultDataSubId();
-        if (SubscriptionManager.isValidSubscriptionId(defaultDataSub)) {
-            mCurrentState.dataSim = defaultDataSub == mSubscriptionInfo.getSubscriptionId();
+        int activeDataSubId = mDefaults.getActiveDataSubId();
+        if (SubscriptionManager.isValidSubscriptionId(activeDataSubId)) {
+            mCurrentState.dataSim = activeDataSubId == mSubscriptionInfo.getSubscriptionId();
         } else {
             // There doesn't seem to be a data sim selected, however if
             // there isn't a MobileSignalController with dataSim set, then
@@ -545,7 +546,7 @@
     }
 
     private boolean isDataDisabled() {
-        return !mPhone.getDataEnabled(mSubscriptionInfo.getSubscriptionId());
+        return !mPhone.isDataCapable();
     }
 
     @VisibleForTesting
@@ -566,6 +567,7 @@
         pw.println("  mDataState=" + mDataState + ",");
         pw.println("  mDataNetType=" + mDataNetType + ",");
         pw.println("  mInflateSignalStrengths=" + mInflateSignalStrengths + ",");
+        pw.println("  isDataDisabled=" + isDataDisabled() + ",");
     }
 
     class MobilePhoneStateListener extends PhoneStateListener {
@@ -635,6 +637,13 @@
 
             updateTelephony();
         }
+
+        @Override
+        public void onActiveDataSubscriptionIdChanged(int subId) {
+            if (DEBUG) Log.d(mTag, "onActiveDataSubscriptionIdChanged: subId=" + subId);
+            updateDataSim();
+            updateTelephony();
+        }
     };
 
     static class MobileIconGroup extends SignalController.IconGroup {
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 b2972fc..d545dc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -361,7 +361,7 @@
     }
 
     private MobileSignalController getDataController() {
-        int dataSubId = mSubDefaults.getDefaultDataSubId();
+        int dataSubId = mSubDefaults.getActiveDataSubId();
         if (!SubscriptionManager.isValidSubscriptionId(dataSubId)) {
             if (DEBUG) Log.e(TAG, "No data sim selected");
             return mDefaultSignalController;
@@ -1098,6 +1098,10 @@
         public int getDefaultDataSubId() {
             return SubscriptionManager.getDefaultDataSubscriptionId();
         }
+
+        public int getActiveDataSubId() {
+            return SubscriptionManager.getActiveDataSubscriptionId();
+        }
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java
index 438226a..94aa391 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.annotation.NonNull;
+
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
 /**
@@ -45,5 +47,5 @@
      * @param entry     the entry of the changed notification
      * @param isHeadsUp whether the notification is now a headsUp notification
      */
-    default void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {}
+    default void onHeadsUpStateChanged(@NonNull NotificationEntry entry, boolean isHeadsUp) {}
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 640f0f0..282d28c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -303,7 +303,7 @@
         };
 
         OnClickListener onClickListener = view ->
-            smartReplyView.mKeyguardDismissUtil.executeWhenUnlocked(action);
+            smartReplyView.mKeyguardDismissUtil.executeWhenUnlocked(action, !entry.isRowPinned());
         if (useDelayedOnClickListener) {
             onClickListener = new DelayedOnClickListener(onClickListener,
                     smartReplyView.mConstants.getOnClickInitDelay());
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 f726321..395add7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -111,7 +111,9 @@
     public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor,
             @Named(MAIN_HANDLER_NAME) Handler handler, ActivityStarter activityStarter) {
         mContext = context;
-        mGuestResumeSessionReceiver.register(context);
+        if (!UserManager.isGuestUserEphemeral()) {
+            mGuestResumeSessionReceiver.register(context);
+        }
         mKeyguardMonitor = keyguardMonitor;
         mHandler = handler;
         mActivityStarter = activityStarter;
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
index 930016b..41e026a 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
@@ -172,10 +172,15 @@
     private void setEnabledAsync(String pkg, UserHandle userHandle, boolean enabled) {
         mExecutor.execute(() -> {
             if (DEBUG) Log.d(TAG, String.format("setEnabled: %s %s %b", pkg, userHandle, enabled));
-            if (enabled) {
-                mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle);
-            } else {
-                mOverlayManager.setEnabled(pkg, false, userHandle);
+            try {
+                if (enabled) {
+                    mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle);
+                } else {
+                    mOverlayManager.setEnabled(pkg, false, userHandle);
+                }
+            } catch (IllegalStateException e) {
+                Log.e(TAG,
+                        String.format("setEnabled failed: %s %s %b", pkg, userHandle, enabled), e);
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 6185063..aa4dcc0 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -15,7 +15,7 @@
  */
 package com.android.systemui.tuner;
 
-import static com.android.systemui.Dependency.BG_HANDLER_NAME;
+import static com.android.systemui.Dependency.MAIN_HANDLER_NAME;
 
 import android.app.ActivityManager;
 import android.content.ContentResolver;
@@ -82,7 +82,7 @@
     /**
      */
     @Inject
-    public TunerServiceImpl(Context context, @Named(BG_HANDLER_NAME) Handler bgHandler,
+    public TunerServiceImpl(Context context, @Named(MAIN_HANDLER_NAME) Handler mainHandler,
             LeakDetector leakDetector) {
         mContext = context;
         mContentResolver = mContext.getContentResolver();
@@ -91,7 +91,7 @@
         for (UserInfo user : UserManager.get(mContext).getUsers()) {
             mCurrentUser = user.getUserHandle().getIdentifier();
             if (getValue(TUNER_VERSION, 0) != CURRENT_TUNER_VERSION) {
-                upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION, bgHandler);
+                upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION, mainHandler);
             }
         }
 
@@ -112,7 +112,7 @@
         mUserTracker.stopTracking();
     }
 
-    private void upgradeTuner(int oldVersion, int newVersion, Handler bgHandler) {
+    private void upgradeTuner(int oldVersion, int newVersion, Handler mainHandler) {
         if (oldVersion < 1) {
             String blacklistStr = getValue(StatusBarIconController.ICON_BLACKLIST);
             if (blacklistStr != null) {
@@ -134,7 +134,7 @@
         if (oldVersion < 4) {
             // Delay this so that we can wait for everything to be registered first.
             final int user = mCurrentUser;
-            bgHandler.postDelayed(
+            mainHandler.postDelayed(
                     () -> clearAllFromUser(user), 5000);
         }
         setValue(TUNER_VERSION, newVersion);
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index de86f3d..ff5bd03 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -628,6 +628,14 @@
             final int requestKey = vol.getId().hashCode();
             return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
                     PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
+        } else if (isAutomotive()) {
+            intent.setClassName("com.android.car.settings",
+                    "com.android.car.settings.storage.StorageUnmountReceiver");
+            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+
+            final int requestKey = vol.getId().hashCode();
+            return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent,
+                    PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT);
         } else {
             intent.setClassName("com.android.settings",
                     "com.android.settings.deviceinfo.StorageUnmountReceiver");
@@ -749,6 +757,11 @@
                 PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
     }
 
+    private boolean isAutomotive() {
+        PackageManager packageManager = mContext.getPackageManager();
+        return packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+    }
+
     private boolean isTv() {
         PackageManager packageManager = mContext.getPackageManager();
         return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index 12006fa..4d12cc9 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -86,6 +86,7 @@
         mAlwaysAllow = (CheckBox)checkbox.findViewById(com.android.internal.R.id.alwaysUse);
         mAlwaysAllow.setText(getString(R.string.usb_debugging_always));
         ap.mView = checkbox;
+        window.setCloseOnTouchOutside(false);
 
         setupAlert();
 
diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
index 31f4991..b9c5ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
+++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
@@ -156,17 +156,21 @@
      * Requests for all sensors that match the given type from all plugins.
      * @param sensor
      * @param listener
+     * @return true if there were plugins to register the listener to
      */
-    public void registerPluginListener(SensorManagerPlugin.Sensor sensor,
+    public boolean registerPluginListener(SensorManagerPlugin.Sensor sensor,
             SensorManagerPlugin.SensorEventListener listener) {
         if (mPlugins.isEmpty()) {
             Log.w(TAG, "No plugins registered");
+            return false;
         }
         mHandler.post(() -> {
             for (int i = 0; i < mPlugins.size(); i++) {
                 mPlugins.get(i).registerListener(sensor, listener);
             }
         });
+
+        return true;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/util/AutoMarqueeTextView.java b/packages/SystemUI/src/com/android/systemui/util/AutoMarqueeTextView.java
index d9d410d..09dbfee 100644
--- a/packages/SystemUI/src/com/android/systemui/util/AutoMarqueeTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/util/AutoMarqueeTextView.java
@@ -49,6 +49,11 @@
     }
 
     @Override
+    protected void onFinishInflate() {
+        onVisibilityAggregated(isVisibleToUser());
+    }
+
+    @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         setSelected(true);
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index d521e55..9b264c4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -26,12 +26,13 @@
 import com.android.keyguard.KeyguardClockSwitch;
 import com.android.keyguard.KeyguardMessageArea;
 import com.android.keyguard.KeyguardSliceView;
-import com.android.systemui.SystemUIFactory;
+import com.android.systemui.SystemUIRootComponent;
 import com.android.systemui.qs.QSCarrierGroup;
 import com.android.systemui.qs.QSFooterImpl;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QuickQSPanel;
 import com.android.systemui.qs.QuickStatusBarHeader;
+import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
@@ -61,7 +62,7 @@
     private final LayoutInflater.Factory2 mFactory = new InjectionFactory();
 
     @Inject
-    public InjectionInflationController(SystemUIFactory.SystemUIRootComponent rootComponent) {
+    public InjectionInflationController(SystemUIRootComponent rootComponent) {
         mViewCreator = rootComponent.createViewCreator();
         initInjectionMap();
     }
@@ -138,6 +139,11 @@
         QSCarrierGroup createQSCarrierGroup();
 
         /**
+         * Creates the Shelf.
+         */
+        NotificationShelf creatNotificationShelf();
+
+        /**
          * Creates the KeyguardClockSwitch.
          */
         KeyguardClockSwitch createKeyguardClockSwitch();
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
index efd6e03..fa7af0b 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.util.leak;
 
+import android.content.ClipData;
+import android.content.ClipDescription;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
@@ -47,10 +49,11 @@
     private static final String FILEPROVIDER_PATH = "leak";
 
     private static final String TAG = "DumpTruck";
-    private static final int BUFSIZ = 512 * 1024; // 512K
+    private static final int BUFSIZ = 1024 * 1024; // 1MB
 
     private final Context context;
     private Uri hprofUri;
+    private long pss;
     final StringBuilder body = new StringBuilder();
 
     public DumpTruck(Context context) {
@@ -89,6 +92,7 @@
                             .append(info.currentPss)
                             .append(" uss=")
                             .append(info.currentUss);
+                    pss = info.currentPss;
                 }
             }
             if (pid == myPid) {
@@ -114,6 +118,7 @@
             if (DumpTruck.zipUp(zipfile, paths)) {
                 final File pathFile = new File(zipfile);
                 hprofUri = FileProvider.getUriForFile(context, FILEPROVIDER_AUTHORITY, pathFile);
+                Log.v(TAG, "Heap dump accessible at URI: " + hprofUri);
             }
         } catch (IOException e) {
             Log.e(TAG, "unable to zip up heapdumps", e);
@@ -138,16 +143,27 @@
      * @return share intent
      */
     public Intent createShareIntent() {
-        Intent shareIntent = new Intent(Intent.ACTION_SEND);
+        Intent shareIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
         shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        shareIntent.putExtra(Intent.EXTRA_SUBJECT, "SystemUI memory dump");
+        shareIntent.putExtra(Intent.EXTRA_SUBJECT,
+                String.format("SystemUI memory dump (pss=%dM)", pss / 1024));
 
         shareIntent.putExtra(Intent.EXTRA_TEXT, body.toString());
 
         if (hprofUri != null) {
+            final ArrayList<Uri> uriList = new ArrayList<>();
+            uriList.add(hprofUri);
             shareIntent.setType("application/zip");
-            shareIntent.putExtra(Intent.EXTRA_STREAM, hprofUri);
+            shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList);
+
+            // Include URI in ClipData also, so that grantPermission picks it up.
+            // We don't use setData here because some apps interpret this as "to:".
+            ClipData clipdata = new ClipData(new ClipDescription("content",
+                    new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}),
+                    new ClipData.Item(hprofUri));
+            shareIntent.setClipData(clipdata);
+            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
         }
         return shareIntent;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index b590e77..583f6b3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -16,9 +16,13 @@
 
 package com.android.systemui.util.leak;
 
+import static android.service.quicksettings.Tile.STATE_ACTIVE;
+import static android.telephony.ims.feature.ImsFeature.STATE_UNAVAILABLE;
+
 import static com.android.internal.logging.MetricsLogger.VIEW_UNKNOWN;
 import static com.android.systemui.Dependency.BG_LOOPER_NAME;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
@@ -38,11 +42,11 @@
 import android.os.Process;
 import android.os.SystemProperties;
 import android.provider.Settings;
-import android.service.quicksettings.Tile;
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.LongSparseArray;
 
+import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
@@ -50,6 +54,8 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 import javax.inject.Inject;
@@ -59,26 +65,33 @@
 /**
  */
 @Singleton
-public class GarbageMonitor {
+public class GarbageMonitor implements Dumpable {
     private static final boolean LEAK_REPORTING_ENABLED =
             Build.IS_DEBUGGABLE
                     && SystemProperties.getBoolean("debug.enable_leak_reporting", false);
     private static final String FORCE_ENABLE_LEAK_REPORTING = "sysui_force_enable_leak_reporting";
 
     private static final boolean HEAP_TRACKING_ENABLED = Build.IS_DEBUGGABLE;
-    private static final boolean ENABLE_AM_HEAP_LIMIT = true; // use ActivityManager.setHeapLimit
+
+    // whether to use ActivityManager.setHeapLimit
+    private static final boolean ENABLE_AM_HEAP_LIMIT = Build.IS_DEBUGGABLE;
+    // heap limit value, in KB (overrides R.integer.watch_heap_limit)
+    private static final String SETTINGS_KEY_AM_HEAP_LIMIT = "systemui_am_heap_limit";
 
     private static final String TAG = "GarbageMonitor";
 
     private static final long GARBAGE_INSPECTION_INTERVAL =
             15 * DateUtils.MINUTE_IN_MILLIS; // 15 min
     private static final long HEAP_TRACK_INTERVAL = 1 * DateUtils.MINUTE_IN_MILLIS; // 1 min
+    private static final int HEAP_TRACK_HISTORY_LEN = 720; // 12 hours
 
     private static final int DO_GARBAGE_INSPECTION = 1000;
     private static final int DO_HEAP_TRACK = 3000;
 
     private static final int GARBAGE_ALLOWANCE = 5;
 
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
     private final Handler mHandler;
     private final TrackedGarbage mTrackedGarbage;
     private final LeakReporter mLeakReporter;
@@ -112,7 +125,9 @@
         mDumpTruck = new DumpTruck(mContext);
 
         if (ENABLE_AM_HEAP_LIMIT) {
-            mHeapLimit = mContext.getResources().getInteger(R.integer.watch_heap_limit);
+            mHeapLimit = Settings.Global.getInt(context.getContentResolver(),
+                    SETTINGS_KEY_AM_HEAP_LIMIT,
+                    mContext.getResources().getInteger(R.integer.watch_heap_limit));
         }
     }
 
@@ -174,7 +189,7 @@
             sb.append(p);
             sb.append(" ");
         }
-        Log.v(TAG, sb.toString());
+        if (DEBUG) Log.v(TAG, sb.toString());
     }
 
     private void update() {
@@ -183,18 +198,18 @@
             for (int i = 0; i < dinfos.length; i++) {
                 Debug.MemoryInfo dinfo = dinfos[i];
                 if (i > mPids.size()) {
-                    Log.e(TAG, "update: unknown process info received: " + dinfo);
+                    if (DEBUG) Log.e(TAG, "update: unknown process info received: " + dinfo);
                     break;
                 }
                 final long pid = mPids.get(i).intValue();
                 final ProcessMemInfo info = mData.get(pid);
-                info.head = (info.head + 1) % info.pss.length;
                 info.pss[info.head] = info.currentPss = dinfo.getTotalPss();
                 info.uss[info.head] = info.currentUss = dinfo.getTotalPrivateDirty();
+                info.head = (info.head + 1) % info.pss.length;
                 if (info.currentPss > info.max) info.max = info.currentPss;
                 if (info.currentUss > info.max) info.max = info.currentUss;
                 if (info.currentPss == 0) {
-                    Log.v(TAG, "update: pid " + pid + " has pss=0, it probably died");
+                    if (DEBUG) Log.v(TAG, "update: pid " + pid + " has pss=0, it probably died");
                     mData.remove(pid);
                 }
             }
@@ -224,11 +239,36 @@
         return b + SUFFIXES[i];
     }
 
-    private void dumpHprofAndShare() {
-        final Intent share = mDumpTruck.captureHeaps(getTrackedProcesses()).createShareIntent();
-        mContext.startActivity(share);
+    private Intent dumpHprofAndGetShareIntent() {
+        return mDumpTruck.captureHeaps(getTrackedProcesses()).createShareIntent();
     }
 
+    @Override
+    public void dump(@Nullable FileDescriptor fd, PrintWriter pw, @Nullable String[] args) {
+        pw.println("GarbageMonitor params:");
+        pw.println(String.format("   mHeapLimit=%d KB", mHeapLimit));
+        pw.println(String.format("   GARBAGE_INSPECTION_INTERVAL=%d (%.1f mins)",
+                GARBAGE_INSPECTION_INTERVAL,
+                (float) GARBAGE_INSPECTION_INTERVAL / DateUtils.MINUTE_IN_MILLIS));
+        final float htiMins = HEAP_TRACK_INTERVAL / DateUtils.MINUTE_IN_MILLIS;
+        pw.println(String.format("   HEAP_TRACK_INTERVAL=%d (%.1f mins)",
+                HEAP_TRACK_INTERVAL,
+                htiMins));
+        pw.println(String.format("   HEAP_TRACK_HISTORY_LEN=%d (%.1f hr total)",
+                HEAP_TRACK_HISTORY_LEN,
+                (float) HEAP_TRACK_HISTORY_LEN * htiMins / 60f));
+
+        pw.println("GarbageMonitor tracked processes:");
+
+        for (long pid : mPids) {
+            final ProcessMemInfo pmi = mData.get(pid);
+            if (pmi != null) {
+                pmi.dump(fd, pw, args);
+            }
+        }
+    }
+
+
     private static class MemoryIconDrawable extends Drawable {
         long pss, limit;
         final Drawable baseIcon;
@@ -238,7 +278,7 @@
         MemoryIconDrawable(Context context) {
             baseIcon = context.getDrawable(R.drawable.ic_memory).mutate();
             dp = context.getResources().getDisplayMetrics().density;
-            paint.setColor(QSTileImpl.getColorForState(context, Tile.STATE_ACTIVE));
+            paint.setColor(QSTileImpl.getColorForState(context, STATE_ACTIVE));
         }
 
         public void setPss(long pss) {
@@ -343,8 +383,12 @@
     public static class MemoryTile extends QSTileImpl<QSTile.State> {
         public static final String TILE_SPEC = "dbg:mem";
 
+        // Tell QSTileHost.java to toss this into the default tileset?
+        public static final boolean ADD_TO_DEFAULT_ON_DEBUGGABLE_BUILDS = true;
+
         private final GarbageMonitor gm;
         private ProcessMemInfo pmi;
+        private boolean dumpInProgress;
 
         @Inject
         public MemoryTile(QSHost host) {
@@ -364,8 +408,26 @@
 
         @Override
         protected void handleClick() {
-            getHost().collapsePanels();
-            mHandler.post(gm::dumpHprofAndShare);
+            if (dumpInProgress) return;
+
+            dumpInProgress = true;
+            refreshState();
+            new Thread("HeapDumpThread") {
+                @Override
+                public void run() {
+                    try {
+                        // wait for animations & state changes
+                        Thread.sleep(500);
+                    } catch (InterruptedException ignored) { }
+                    final Intent shareIntent = gm.dumpHprofAndGetShareIntent();
+                    mHandler.post(() -> {
+                        dumpInProgress = false;
+                        refreshState();
+                        getHost().collapsePanels();
+                        mContext.startActivity(shareIntent);
+                    });
+                }
+            }.start();
         }
 
         @Override
@@ -395,9 +457,12 @@
             pmi = gm.getMemInfo(Process.myPid());
             final MemoryGraphIcon icon = new MemoryGraphIcon();
             icon.setHeapLimit(gm.mHeapLimit);
+            state.state = dumpInProgress ? STATE_UNAVAILABLE : STATE_ACTIVE;
+            state.label = dumpInProgress
+                    ? "Dumping..."
+                    : mContext.getString(R.string.heap_dump_tile_name);
             if (pmi != null) {
                 icon.setPss(pmi.currentPss);
-                state.label = mContext.getString(R.string.heap_dump_tile_name);
                 state.secondaryLabel =
                         String.format(
                                 "pss: %s / %s",
@@ -405,7 +470,6 @@
                                 formatBytes(gm.mHeapLimit * 1024));
             } else {
                 icon.setPss(0);
-                state.label = "Dump SysUI";
                 state.secondaryLabel = null;
             }
             state.icon = icon;
@@ -424,13 +488,14 @@
         }
     }
 
-    public static class ProcessMemInfo {
+    /** */
+    public static class ProcessMemInfo implements Dumpable {
         public long pid;
         public String name;
         public long startTime;
         public long currentPss, currentUss;
-        public long[] pss = new long[256];
-        public long[] uss = new long[256];
+        public long[] pss = new long[HEAP_TRACK_HISTORY_LEN];
+        public long[] uss = new long[HEAP_TRACK_HISTORY_LEN];
         public long max = 1;
         public int head = 0;
 
@@ -443,9 +508,33 @@
         public long getUptime() {
             return System.currentTimeMillis() - startTime;
         }
+
+        @Override
+        public void dump(@Nullable FileDescriptor fd, PrintWriter pw, @Nullable String[] args) {
+            pw.print("{ \"pid\": ");
+            pw.print(pid);
+            pw.print(", \"name\": \"");
+            pw.print(name.replace('"', '-'));
+            pw.print("\", \"start\": ");
+            pw.print(startTime);
+            pw.print(", \"pss\": [");
+            // write pss values starting from the oldest, which is pss[head], wrapping around to
+            // pss[(head-1) % pss.length]
+            for (int i = 0; i < pss.length; i++) {
+                if (i > 0) pw.print(",");
+                pw.print(pss[(head + i) % pss.length]);
+            }
+            pw.print("], \"uss\": [");
+            for (int i = 0; i < uss.length; i++) {
+                if (i > 0) pw.print(",");
+                pw.print(uss[(head + i) % uss.length]);
+            }
+            pw.println("] }");
+        }
     }
 
-    public static class Service extends SystemUI {
+    /** */
+    public static class Service extends SystemUI implements Dumpable {
         private GarbageMonitor mGarbageMonitor;
 
         @Override
@@ -463,6 +552,11 @@
                 mGarbageMonitor.startHeapTracking();
             }
         }
+
+        @Override
+        public void dump(@Nullable FileDescriptor fd, PrintWriter pw, @Nullable String[] args) {
+            if (mGarbageMonitor != null) mGarbageMonitor.dump(fd, pw, args);
+        }
     }
 
     private class BackgroundHeapCheckHandler extends Handler {
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
index bebc20b..775a3ab 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
@@ -31,6 +31,11 @@
     static final String REASON_WRAP = "wrap";
 
     /**
+     * Default wake-lock timeout, to avoid battery regressions.
+     */
+    long DEFAULT_MAX_TIMEOUT = 20000;
+
+    /**
      * @param why A tag that will be saved for sysui dumps.
      * @see android.os.PowerManager.WakeLock#acquire()
      **/
@@ -46,7 +51,14 @@
     Runnable wrap(Runnable r);
 
     static WakeLock createPartial(Context context, String tag) {
-        return wrap(createPartialInner(context, tag));
+        return createPartial(context, tag, DEFAULT_MAX_TIMEOUT);
+    }
+
+    /**
+     * Creates a {@link WakeLock} that has a default release timeout.
+     * @see android.os.PowerManager.WakeLock#acquire(long) */
+    static WakeLock createPartial(Context context, String tag, long maxTimeout) {
+        return wrap(createPartialInner(context, tag), maxTimeout);
     }
 
     @VisibleForTesting
@@ -66,7 +78,14 @@
         };
     }
 
-    static WakeLock wrap(final PowerManager.WakeLock inner) {
+    /**
+     * Create a {@link WakeLock} containing a {@link PowerManager.WakeLock}.
+     * @param inner To be wrapped.
+     * @param maxTimeout When to expire.
+     * @return The new wake lock.
+     */
+    @VisibleForTesting
+    static WakeLock wrap(final PowerManager.WakeLock inner, long maxTimeout) {
         return new WakeLock() {
             private final HashMap<String, Integer> mActiveClients = new HashMap<>();
 
@@ -74,7 +93,7 @@
             public void acquire(String why) {
                 mActiveClients.putIfAbsent(why, 0);
                 mActiveClients.put(why, mActiveClients.get(why) + 1);
-                inner.acquire();
+                inner.acquire(maxTimeout);
             }
 
             /** @see PowerManager.WakeLock#release() */
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 69d2e31..3f3e1e3 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -243,8 +243,11 @@
         pw.print("  mState: "); pw.println(mState.toString(4));
         pw.print("  mShowDndTile: "); pw.println(mShowDndTile);
         pw.print("  mHasVibrator: "); pw.println(mHasVibrator);
-        pw.print("  mRemoteStreams: "); pw.println(mMediaSessionsCallbacksW.mRemoteStreams
-                .values());
+        synchronized (mMediaSessionsCallbacksW.mRemoteStreams) {
+            pw.print("  mRemoteStreams: ");
+            pw.println(mMediaSessionsCallbacksW.mRemoteStreams
+                    .values());
+        }
         pw.print("  mShowA11yStream: "); pw.println(mShowA11yStream);
         pw.println();
         mMediaSessions.dump(pw);
@@ -1075,7 +1078,10 @@
         @Override
         public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) {
             addStream(token, "onRemoteUpdate");
-            final int stream = mRemoteStreams.get(token);
+            int stream = 0;
+            synchronized (mRemoteStreams) {
+                 stream = mRemoteStreams.get(token);
+            }
             boolean changed = mState.states.indexOfKey(stream) < 0;
             final StreamState ss = streamStateW(stream);
             ss.dynamic = true;
@@ -1100,7 +1106,10 @@
         @Override
         public void onRemoteVolumeChanged(Token token, int flags) {
             addStream(token, "onRemoteVolumeChanged");
-            final int stream = mRemoteStreams.get(token);
+            int stream = 0;
+            synchronized (mRemoteStreams) {
+                stream = mRemoteStreams.get(token);
+            }
             final boolean showUI = shouldShowUI(flags);
             boolean changed = updateActiveStreamW(stream);
             if (showUI) {
@@ -1116,12 +1125,15 @@
 
         @Override
         public void onRemoteRemoved(Token token) {
-            if (!mRemoteStreams.containsKey(token)) {
-                if (D.BUG) Log.d(TAG, "onRemoteRemoved: stream doesn't exist, "
-                        + "aborting remote removed for token:" +  token.toString());
-                return;
+            int stream = 0;
+            synchronized (mRemoteStreams) {
+                if (!mRemoteStreams.containsKey(token)) {
+                    if (D.BUG) Log.d(TAG, "onRemoteRemoved: stream doesn't exist, "
+                            + "aborting remote removed for token:" +  token.toString());
+                    return;
+                }
+                stream = mRemoteStreams.get(token);
             }
-            final int stream = mRemoteStreams.get(token);
             mState.states.remove(stream);
             if (mState.activeStream == stream) {
                 updateActiveStreamW(-1);
@@ -1139,20 +1151,24 @@
         }
 
         private Token findToken(int stream) {
-            for (Map.Entry<Token, Integer> entry : mRemoteStreams.entrySet()) {
-                if (entry.getValue().equals(stream)) {
-                    return entry.getKey();
+            synchronized (mRemoteStreams) {
+                for (Map.Entry<Token, Integer> entry : mRemoteStreams.entrySet()) {
+                    if (entry.getValue().equals(stream)) {
+                        return entry.getKey();
+                    }
                 }
             }
             return null;
         }
 
         private void addStream(Token token, String triggeringMethod) {
-            if (!mRemoteStreams.containsKey(token)) {
-                mRemoteStreams.put(token, mNextStream);
-                if (D.BUG) Log.d(TAG, triggeringMethod + ": added stream " +  mNextStream
-                        + " from token + "+ token.toString());
-                mNextStream++;
+            synchronized (mRemoteStreams) {
+                if (!mRemoteStreams.containsKey(token)) {
+                    mRemoteStreams.put(token, mNextStream);
+                    if (D.BUG) Log.d(TAG, triggeringMethod + ": added stream " + mNextStream
+                            + " from token + " + token.toString());
+                    mNextStream++;
+                }
             }
         }
     }
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index efb4ff0..bfb0e15 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -54,7 +54,7 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS" />
 
-    <application android:debuggable="true">
+    <application android:debuggable="true" android:largeHeap="true">
         <uses-library android:name="android.test.runner" />
         <activity android:name="com.android.systemui.screenshot.ScreenshotStubActivity" />
 
diff --git a/packages/SystemUI/tests/res/values/overlayable_icons_test.xml b/packages/SystemUI/tests/res/values/overlayable_icons_test.xml
deleted file mode 100644
index ba651ac..0000000
--- a/packages/SystemUI/tests/res/values/overlayable_icons_test.xml
+++ /dev/null
@@ -1,70 +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.
--->
-<resources>
-  <!-- overlayable_icons references all of the drawables in this package
-       that are being overlayed by resource overlays. If you remove/rename
-       any of these resources, you must also change the resource overlay icons.-->
-  <array name="overlayable_icons">
-    <item>@drawable/ic_alarm</item>
-    <item>@drawable/ic_alarm_dim</item>
-    <item>@drawable/ic_arrow_back</item>
-    <item>@drawable/ic_bluetooth_connected</item>
-    <item>@drawable/ic_brightness_thumb</item>
-    <item>@drawable/ic_camera</item>
-    <item>@drawable/ic_cast</item>
-    <item>@drawable/ic_cast_connected</item>
-    <item>@drawable/ic_close_white</item>
-    <item>@drawable/ic_data_saver</item>
-    <item>@drawable/ic_data_saver_off</item>
-    <item>@drawable/ic_drag_handle</item>
-    <item>@drawable/ic_headset</item>
-    <item>@drawable/ic_headset_mic</item>
-    <item>@drawable/ic_hotspot</item>
-    <item>@drawable/ic_info</item>
-    <item>@drawable/ic_info_outline</item>
-    <item>@drawable/ic_invert_colors</item>
-    <item>@drawable/ic_location</item>
-    <item>@drawable/ic_lockscreen_ime</item>
-    <item>@drawable/ic_notifications_alert</item>
-    <item>@drawable/ic_notifications_silence</item>
-    <item>@drawable/ic_power_low</item>
-    <item>@drawable/ic_power_saver</item>
-    <item>@drawable/ic_qs_bluetooth_connecting</item>
-    <item>@drawable/ic_qs_cancel</item>
-    <item>@drawable/ic_qs_no_sim</item>
-    <item>@drawable/ic_qs_wifi_0</item>
-    <item>@drawable/ic_qs_wifi_1</item>
-    <item>@drawable/ic_qs_wifi_2</item>
-    <item>@drawable/ic_qs_wifi_3</item>
-    <item>@drawable/ic_qs_wifi_4</item>
-    <item>@drawable/ic_qs_wifi_disconnected</item>
-    <item>@drawable/ic_screenshot_delete</item>
-    <item>@drawable/ic_settings</item>
-    <item>@drawable/ic_swap_vert</item>
-    <item>@drawable/ic_tune_black_16dp</item>
-    <item>@drawable/ic_volume_alarm_mute</item>
-    <item>@drawable/ic_volume_bt_sco</item>
-    <item>@drawable/ic_volume_media</item>
-    <item>@drawable/ic_volume_media_mute</item>
-    <item>@drawable/ic_volume_ringer</item>
-    <item>@drawable/ic_volume_ringer_mute</item>
-    <item>@drawable/ic_volume_ringer_vibrate</item>
-    <item>@drawable/ic_volume_voice</item>
-    <item>@drawable/stat_sys_managed_profile_status</item>
-    <item>@drawable/stat_sys_mic_none</item>
-    <item>@drawable/stat_sys_vpn_ic</item>
-  </array>
-</resources>
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 6208ab8..db6177a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -52,6 +53,7 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -88,6 +90,8 @@
     private UserManager mUserManager;
     @Mock
     private DevicePolicyManager mDevicePolicyManager;
+    @Mock
+    private KeyguardBypassController mKeyguardBypassController;
     private TestableLooper mTestableLooper;
     private TestableKeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
@@ -99,7 +103,8 @@
         when(context.getPackageManager()).thenReturn(mPackageManager);
         doAnswer(invocation -> {
             IBiometricEnabledOnKeyguardCallback callback = invocation.getArgument(0);
-            callback.onChanged(BiometricSourceType.FACE, true /* enabled */);
+            callback.onChanged(BiometricSourceType.FACE, true /* enabled */,
+                    KeyguardUpdateMonitor.getCurrentUser());
             return null;
         }).when(mBiometricManager).registerEnabledOnKeyguardCallback(any());
         when(mFaceManager.isHardwareDetected()).thenReturn(true);
@@ -314,13 +319,44 @@
 
     @Test
     public void skipsAuthentication_whenEncryptedKeyguard() {
-        reset(mUserManager);
-        when(mUserManager.isUserUnlocked(anyInt())).thenReturn(false);
+        when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
+                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
+        mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
 
         mKeyguardUpdateMonitor.dispatchStartedWakingUp();
         mTestableLooper.processAllMessages();
         mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
-        verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any());
+        verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+    }
+
+    @Test
+    public void requiresAuthentication_whenEncryptedKeyguard_andBypass() {
+        testStrongAuthExceptOnBouncer(
+                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
+    }
+
+    @Test
+    public void requiresAuthentication_whenTimeoutKeyguard_andBypass() {
+        testStrongAuthExceptOnBouncer(
+                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
+    }
+
+    private void testStrongAuthExceptOnBouncer(int strongAuth) {
+        when(mKeyguardBypassController.canBypass()).thenReturn(true);
+        mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
+        when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth);
+
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+        mTestableLooper.processAllMessages();
+        mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+
+        // Stop scanning when bouncer becomes visible
+        mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true /* showingBouncer */);
+        mTestableLooper.processAllMessages();
+        clearInvocations(mFaceManager);
+        mKeyguardUpdateMonitor.requestFaceAuth();
+        verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
     }
 
     @Test
@@ -332,6 +368,50 @@
     }
 
     @Test
+    public void testTriesToAuthenticate_whenTrustOnAgentKeyguard_ifBypass() {
+        mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+        mTestableLooper.processAllMessages();
+        when(mKeyguardBypassController.canBypass()).thenReturn(true);
+        mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
+                KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */);
+        mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+        verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+    }
+
+    @Test
+    public void testIgnoresAuth_whenTrustAgentOnKeyguard_withoutBypass() {
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+        mTestableLooper.processAllMessages();
+        mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
+                KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */);
+        mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+        verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+    }
+
+    @Test
+    public void testIgnoresAuth_whenLockdown() {
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+        mTestableLooper.processAllMessages();
+        when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
+                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+
+        mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+        verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+    }
+
+    @Test
+    public void testIgnoresAuth_whenLockout() {
+        mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+        mTestableLooper.processAllMessages();
+        when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
+                KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT);
+
+        mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+        verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+    }
+
+    @Test
     public void testOnFaceAuthenticated_skipsFaceWhenAuthenticated() {
         mKeyguardUpdateMonitor.onFaceAuthenticated(KeyguardUpdateMonitor.getCurrentUser());
         mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
index 3f48ea7..ef3af8a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
@@ -18,6 +18,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
@@ -67,9 +68,9 @@
     public void setColorPalette_setDigitalClock() {
         ViewGroup smallClock = (ViewGroup) mClockController.getView();
         // WHEN color palette is set
-        mClockController.setColorPalette(true, new int[]{42});
+        mClockController.setColorPalette(true, new int[]{Color.RED});
         // THEN child of small clock should have text color set.
         TextView digitalClock = (TextView) smallClock.getChildAt(0);
-        assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
+        assertThat(digitalClock.getCurrentTextColor()).isEqualTo(Color.RED);
     }
 }
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 90083b4..b56986e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
@@ -18,6 +18,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.res.Resources;
+import android.graphics.Color;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
@@ -66,9 +67,9 @@
     public void setColorPalette_setDigitalClock() {
         ViewGroup smallClock = (ViewGroup) mClockController.getView();
         // WHEN text color is set
-        mClockController.setColorPalette(true, new int[]{42});
+        mClockController.setColorPalette(true, new int[]{Color.RED});
         // THEN child of small clock should have text color set.
         TextView digitalClock = (TextView) smallClock.getChildAt(0);
-        assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
+        assertThat(digitalClock.getCurrentTextColor()).isEqualTo(Color.RED);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt
new file mode 100644
index 0000000..347b26d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.graphics.Color
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ClockPaletteTest : SysuiTestCase() {
+
+    private lateinit var clockPalette: ClockPalette
+    private lateinit var colors: IntArray
+
+    @Before
+    fun setUp() {
+        clockPalette = ClockPalette()
+        // colors used are reds from light to dark.
+        val hsv: FloatArray = FloatArray(3)
+        Color.colorToHSV(Color.RED, hsv)
+        colors = IntArray(10)
+        val step: Float = (0f - hsv[2]) / colors.size
+        for (i in 0 until colors.size) {
+            hsv[2] += step
+            colors[i] = Color.HSVToColor(hsv)
+        }
+    }
+
+    @Test
+    fun testDark() {
+        // GIVEN on AOD
+        clockPalette.setDarkAmount(1f)
+        // AND GIVEN that wallpaper doesn't support dark text
+        clockPalette.setColorPalette(false, colors)
+        // THEN the secondary color should be lighter than the primary color
+        assertThat(value(clockPalette.getPrimaryColor()))
+                .isGreaterThan(value(clockPalette.getSecondaryColor()))
+    }
+
+    @Test
+    fun testDarkText() {
+        // GIVEN on lock screen
+        clockPalette.setDarkAmount(0f)
+        // AND GIVEN that wallpaper supports dark text
+        clockPalette.setColorPalette(true, colors)
+        // THEN the secondary color should be darker the primary color
+        assertThat(value(clockPalette.getPrimaryColor()))
+                .isLessThan(value(clockPalette.getSecondaryColor()))
+    }
+
+    @Test
+    fun testLightText() {
+        // GIVEN on lock screen
+        clockPalette.setDarkAmount(0f)
+        // AND GIVEN that wallpaper doesn't support dark text
+        clockPalette.setColorPalette(false, colors)
+        // THEN the secondary color should be darker than the primary color
+        assertThat(value(clockPalette.getPrimaryColor()))
+                .isGreaterThan(value(clockPalette.getSecondaryColor()))
+    }
+
+    @Test
+    fun testNullColors() {
+        // GIVEN on AOD
+        clockPalette.setDarkAmount(1f)
+        // AND GIVEN that wallpaper colors are null
+        clockPalette.setColorPalette(false, null)
+        // THEN the primary color should be whilte
+        assertThat(clockPalette.getPrimaryColor()).isEqualTo(Color.WHITE)
+    }
+
+    private fun value(color: Int): Float {
+        val hsv: FloatArray = FloatArray(3)
+        Color.colorToHSV(color, hsv)
+        return hsv[2]
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/SettingsWrapperTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/SettingsWrapperTest.kt
new file mode 100644
index 0000000..573581d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/SettingsWrapperTest.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.json.JSONObject
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+private const val PACKAGE = "com.android.keyguard.clock.Clock"
+private const val CLOCK_FIELD = "clock"
+private const val TIMESTAMP_FIELD = "_applied_timestamp"
+private const val USER_ID = 0
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class SettingsWrapperTest : SysuiTestCase() {
+
+    private lateinit var wrapper: SettingsWrapper
+    private lateinit var migration: SettingsWrapper.Migration
+
+    @Before
+    fun setUp() {
+        migration = mock(SettingsWrapper.Migration::class.java)
+        wrapper = SettingsWrapper(getContext().contentResolver, migration)
+    }
+
+    @Test
+    fun testDecodeUnnecessary() {
+        // GIVEN a settings value that doesn't need to be decoded
+        val value = PACKAGE
+        // WHEN the value is decoded
+        val decoded = wrapper.decode(value, USER_ID)
+        // THEN the same value is returned, because decoding isn't necessary.
+        // TODO(b/135674383): Null should be returned when the migration code in removed.
+        assertThat(decoded).isEqualTo(value)
+        // AND the value is migrated to JSON format
+        verify(migration).migrate(value, USER_ID)
+    }
+
+    @Test
+    fun testDecodeJSON() {
+        // GIVEN a settings value that is encoded in JSON
+        val json: JSONObject = JSONObject()
+        json.put(CLOCK_FIELD, PACKAGE)
+        json.put(TIMESTAMP_FIELD, System.currentTimeMillis())
+        val value = json.toString()
+        // WHEN the value is decoded
+        val decoded = wrapper.decode(value, USER_ID)
+        // THEN the clock field should have been extracted
+        assertThat(decoded).isEqualTo(PACKAGE)
+    }
+
+    @Test
+    fun testDecodeJSONWithoutClockField() {
+        // GIVEN a settings value that doesn't contain the CLOCK_FIELD
+        val json: JSONObject = JSONObject()
+        json.put(TIMESTAMP_FIELD, System.currentTimeMillis())
+        val value = json.toString()
+        // WHEN the value is decoded
+        val decoded = wrapper.decode(value, USER_ID)
+        // THEN null is returned
+        assertThat(decoded).isNull()
+        // AND the value is not migrated to JSON format
+        verify(migration, never()).migrate(value, USER_ID)
+    }
+
+    @Test
+    fun testDecodeNullJSON() {
+        assertThat(wrapper.decode(null, USER_ID)).isNull()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt
index f4d59cc..456f32b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt
@@ -52,8 +52,8 @@
     fun darkPosition() {
         // GIVEN on AOD
         position.setDarkAmount(1f)
-        // THEN Y position is statusBarHeight + lockPadding + burnInY (100 + 15 + 20 = 135)
-        assertThat(position.preferredY).isEqualTo(135)
+        // THEN Y is sum of statusBarHeight, lockPadding, lockHeight, lockPadding, burnInY
+        assertThat(position.preferredY).isEqualTo(185)
     }
 
     @Test
@@ -64,4 +64,4 @@
         // (100 + 15 + 35 + 15 = 165)
         assertThat(position.preferredY).isEqualTo(165)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt
index d9ef7fa..5ece6ef 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt
@@ -47,7 +47,7 @@
         val width = 100
         val height = 100
         // WHEN a preview image is created
-        val bitmap = previewer.createPreview(view, width, height)
+        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)
@@ -60,4 +60,4 @@
             canvas?.drawColor(Color.RED)
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 64ab060..3b5e12c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -45,6 +45,7 @@
 import android.view.Display;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.WindowManagerPolicyConstants;
 
 import androidx.test.filters.SmallTest;
 
@@ -52,6 +53,7 @@
 import com.android.systemui.ScreenDecorations.TunablePaddingTagListener;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarWindowView;
 import com.android.systemui.tuner.TunablePadding;
@@ -78,6 +80,7 @@
     private TunerService mTunerService;
     private StatusBarWindowView mView;
     private TunablePaddingService mTunablePaddingService;
+    private NavigationModeController mNavigationModeController;
 
     @Before
     public void setup() {
@@ -87,6 +90,8 @@
         mTunablePaddingService = mDependency.injectMockDependency(TunablePaddingService.class);
         mTunerService = mDependency.injectMockDependency(TunerService.class);
         mFragmentService = mDependency.injectMockDependency(FragmentService.class);
+        mNavigationModeController = mDependency.injectMockDependency(
+                NavigationModeController.class);
 
         mStatusBar = mock(StatusBar.class);
         mWindowManager = mock(WindowManager.class);
@@ -208,6 +213,54 @@
     }
 
     @Test
+    public void testAssistHandles() {
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius, 0);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius_top, 0);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius_bottom, 0);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 0);
+        when(mNavigationModeController.addListener(any())).thenReturn(
+                WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL);
+
+        mScreenDecorations.start();
+
+        // Add 2 windows for rounded corners (top and bottom).
+        verify(mWindowManager, times(2)).addView(any(), any());
+    }
+
+    @Test
+    public void testDelayedAssistHandles() {
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius, 0);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius_top, 0);
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.dimen.rounded_corner_radius_bottom, 0);
+        mContext.getOrCreateTestableResources()
+                .addOverride(dimen.rounded_corner_content_padding, 0);
+        when(mNavigationModeController.addListener(any())).thenReturn(
+                WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON);
+
+        mScreenDecorations.start();
+
+        // No handles and no corners
+        verify(mWindowManager, never()).addView(any(), any());
+
+        mScreenDecorations.handleNavigationModeChange(
+                WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL);
+
+        // Add 2 windows for rounded corners (top and bottom).
+        verify(mWindowManager, times(2)).addView(any(), any());
+    }
+
+    @Test
     public void hasRoundedCornerOverlayFlagSet() {
         assertThat(mScreenDecorations.getWindowLayoutParams().privateFlags
                         & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
index b9afea1..540ac84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
@@ -16,7 +16,10 @@
 
 package com.android.systemui.appops;
 
+import static junit.framework.TestCase.assertFalse;
+
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -36,7 +39,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
@@ -62,28 +64,32 @@
     private AppOpsController.Callback mCallback;
     @Mock
     private AppOpsControllerImpl.H mMockHandler;
+    @Mock
+    private PermissionFlagsCache mFlagsCache;
 
     private AppOpsControllerImpl mController;
+    private TestableLooper mTestableLooper;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mTestableLooper = TestableLooper.get(this);
 
         getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager);
 
         // All permissions of TEST_UID and TEST_UID_OTHER are user sensitive. None of
         // TEST_UID_NON_USER_SENSITIVE are user sensitive.
         getContext().setMockPackageManager(mPackageManager);
-        when(mPackageManager.getPermissionFlags(anyString(), anyString(),
+        when(mFlagsCache.getPermissionFlags(anyString(), anyString(),
                 eq(UserHandle.getUserHandleForUid(TEST_UID)))).thenReturn(
                 PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED);
-        when(mPackageManager.getPermissionFlags(anyString(), anyString(),
+        when(mFlagsCache.getPermissionFlags(anyString(), anyString(),
                 eq(UserHandle.getUserHandleForUid(TEST_UID_OTHER)))).thenReturn(
                 PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED);
-        when(mPackageManager.getPermissionFlags(anyString(), anyString(),
+        when(mFlagsCache.getPermissionFlags(anyString(), anyString(),
                 eq(UserHandle.getUserHandleForUid(TEST_UID_NON_USER_SENSITIVE)))).thenReturn(0);
 
-        mController = new AppOpsControllerImpl(mContext, Dependency.get(Dependency.BG_LOOPER));
+        mController = new AppOpsControllerImpl(mContext, mTestableLooper.getLooper(), mFlagsCache);
     }
 
     @Test
@@ -107,6 +113,7 @@
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
         mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
                 AppOpsManager.MODE_ALLOWED);
+        mTestableLooper.processAllMessages();
         verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO,
                 TEST_UID, TEST_PACKAGE_NAME, true);
     }
@@ -116,6 +123,7 @@
         mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback);
         mController.onOpActiveChanged(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+        mTestableLooper.processAllMessages();
         verify(mCallback, never()).onActiveStateChanged(
                 anyInt(), anyInt(), anyString(), anyBoolean());
     }
@@ -126,6 +134,7 @@
         mController.removeCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback);
         mController.onOpActiveChanged(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+        mTestableLooper.processAllMessages();
         verify(mCallback, never()).onActiveStateChanged(
                 anyInt(), anyInt(), anyString(), anyBoolean());
     }
@@ -136,6 +145,7 @@
         mController.removeCallback(new int[]{AppOpsManager.OP_CAMERA}, mCallback);
         mController.onOpActiveChanged(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
+        mTestableLooper.processAllMessages();
         verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO,
                 TEST_UID, TEST_PACKAGE_NAME, true);
     }
@@ -189,4 +199,21 @@
                 AppOpsManager.MODE_ALLOWED);
         verify(mMockHandler).scheduleRemoval(any(AppOpItem.class), anyLong());
     }
+
+    @Test
+    public void noItemsAfterStopListening() {
+        mController.setBGHandler(mMockHandler);
+
+        mController.setListening(true);
+        mController.onOpActiveChanged(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+                true);
+        mController.onOpNoted(AppOpsManager.OP_FINE_LOCATION, TEST_UID, TEST_PACKAGE_NAME,
+                AppOpsManager.MODE_ALLOWED);
+        assertFalse(mController.getActiveAppOps().isEmpty());
+
+        mController.setListening(false);
+
+        verify(mMockHandler).removeCallbacksAndMessages(null);
+        assertTrue(mController.getActiveAppOps().isEmpty());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/PermissionFlagsCacheTest.kt b/packages/SystemUI/tests/src/com/android/systemui/appops/PermissionFlagsCacheTest.kt
new file mode 100644
index 0000000..dc070de
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/PermissionFlagsCacheTest.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.appops
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+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.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class PermissionFlagsCacheTest : SysuiTestCase() {
+
+    companion object {
+        const val TEST_PERMISSION = "test_permission"
+        const val TEST_PACKAGE = "test_package"
+    }
+
+    @Mock
+    private lateinit var mPackageManager: PackageManager
+    @Mock
+    private lateinit var mUserHandle: UserHandle
+    private lateinit var flagsCache: TestPermissionFlagsCache
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        mContext.setMockPackageManager(mPackageManager)
+        flagsCache = TestPermissionFlagsCache(mContext)
+    }
+
+    @Test
+    fun testCallsPackageManager_exactlyOnce() {
+        flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, mUserHandle)
+        flagsCache.time = CACHE_EXPIRATION - 1
+        verify(mPackageManager).getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, mUserHandle)
+    }
+
+    @Test
+    fun testCallsPackageManager_cacheExpired() {
+        flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, mUserHandle)
+        flagsCache.time = CACHE_EXPIRATION + 1
+        flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, mUserHandle)
+        verify(mPackageManager, times(2))
+                .getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, mUserHandle)
+    }
+
+    @Test
+    fun testCallsPackageMaanger_multipleKeys() {
+        flagsCache.getPermissionFlags(TEST_PERMISSION, TEST_PACKAGE, mUserHandle)
+        flagsCache.getPermissionFlags(TEST_PERMISSION, "", mUserHandle)
+        verify(mPackageManager, times(2))
+                .getPermissionFlags(anyString(), anyString(), any())
+    }
+
+    private class TestPermissionFlagsCache(context: Context) : PermissionFlagsCache(context) {
+        var time = 0L
+
+        override fun getCurrentTime(): Long {
+            return time
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
index 18f114a..a583b1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.reset;
@@ -35,11 +36,13 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.app.AssistUtils;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.systemui.ScreenDecorations;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -59,6 +62,7 @@
     @Mock private ScreenDecorations mMockScreenDecorations;
     @Mock private AssistUtils mMockAssistUtils;
     @Mock private Handler mMockHandler;
+    @Mock private PhenotypeHelper mMockPhenotypeHelper;
     @Mock private AssistHandleBehaviorController.BehaviorController mMockBehaviorController;
 
     @Before
@@ -69,14 +73,21 @@
         doAnswer(answerVoid(Runnable::run)).when(mMockHandler).post(any(Runnable.class));
         doAnswer(answerVoid(Runnable::run)).when(mMockHandler)
                 .postDelayed(any(Runnable.class), anyLong());
+
         mAssistHandleBehaviorController =
                 new AssistHandleBehaviorController(
                         mContext,
                         mMockAssistUtils,
                         mMockHandler, () -> mMockScreenDecorations,
+                        mMockPhenotypeHelper,
                         mMockBehaviorController);
     }
 
+    @After
+    public void teardown() {
+        mAssistHandleBehaviorController.setBehavior(AssistHandleBehavior.OFF);
+    }
+
     @Test
     public void hide_hidesHandlesWhenShowing() {
         // Arrange
@@ -185,6 +196,9 @@
     public void showAndGo_doesNothingIfRecentlyHidden() {
         // Arrange
         when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        when(mMockPhenotypeHelper.getLong(
+                eq(SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS),
+                anyLong())).thenReturn(10000L);
         mAssistHandleBehaviorController.showAndGo();
         reset(mMockScreenDecorations);
 
@@ -210,6 +224,87 @@
     }
 
     @Test
+    public void showAndGoDelayed_showsThenHidesHandlesWhenHiding() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        mAssistHandleBehaviorController.hide();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
+
+        // Assert
+        InOrder inOrder = inOrder(mMockScreenDecorations);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void showAndGoDelayed_hidesHandlesAfterTimeoutWhenShowing() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        mAssistHandleBehaviorController.showAndStay();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
+
+        // Assert
+        verify(mMockScreenDecorations).setAssistHintVisible(false);
+        verifyNoMoreInteractions(mMockScreenDecorations);
+    }
+
+    @Test
+    public void showAndGoDelayed_hidesInitiallyThenShowsThenHidesAfterTimeoutWhenHideRequested() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        mAssistHandleBehaviorController.showAndStay();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, true);
+
+        // Assert
+        InOrder inOrder = inOrder(mMockScreenDecorations);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(true);
+        inOrder.verify(mMockScreenDecorations).setAssistHintVisible(false);
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void showAndGoDelayed_doesNothingIfRecentlyHidden() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
+        when(mMockPhenotypeHelper.getLong(
+                eq(SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS),
+                anyLong())).thenReturn(10000L);
+        mAssistHandleBehaviorController.showAndGo();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
+
+        // Assert
+        verifyNoMoreInteractions(mMockScreenDecorations);
+    }
+
+    @Test
+    public void showAndGoDelayed_doesNothingWhenThereIsNoAssistant() {
+        // Arrange
+        when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(null);
+        mAssistHandleBehaviorController.hide();
+        reset(mMockScreenDecorations);
+
+        // Act
+        mAssistHandleBehaviorController.showAndGoDelayed(1000, false);
+
+        // Assert
+        verifyNoMoreInteractions(mMockScreenDecorations);
+    }
+
+    @Test
     public void setBehavior_activatesTheBehaviorWhenInGesturalMode() {
         // Arrange
         when(mMockAssistUtils.getAssistComponentForUser(anyInt())).thenReturn(COMPONENT_NAME);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
new file mode 100644
index 0000000..7ea6493
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_MANAGER_ENABLED;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertThat;
+
+import android.os.Handler;
+import android.provider.DeviceConfig;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
+import com.android.systemui.shared.plugins.PluginManager;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class FalsingManagerProxyTest extends SysuiTestCase {
+    @Mock
+    PluginManager mPluginManager;
+    private boolean mDefaultConfigValue;
+    private Handler mHandler;
+    private TestableLooper mTestableLooper;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mTestableLooper = TestableLooper.get(this);
+        mHandler = new Handler(mTestableLooper.getLooper());
+        mDefaultConfigValue = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_MANAGER_ENABLED, false);
+        // In case it runs on a device where it's been set to true, set it to false by hand.
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false);
+    }
+
+    @After
+    public void tearDown() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_MANAGER_ENABLED, mDefaultConfigValue ? "true" : "false", false);
+    }
+
+    @Test
+    public void test_brightLineFalsingManagerDisabled() {
+        FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
+
+        assertThat(proxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
+    }
+
+    @Test
+    public void test_brightLineFalsingManagerEnabled() {
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false);
+        FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
+
+        assertThat(proxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class));
+    }
+
+    @Test
+    public void test_brightLineFalsingManagerToggled() {
+        FalsingManagerProxy proxy = new FalsingManagerProxy(getContext(), mPluginManager, mHandler);
+        assertThat(proxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false);
+        mTestableLooper.processAllMessages();
+        proxy.setupFalsingManager(getContext());
+        assertThat(proxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class));
+
+        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
+                BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false);
+        mTestableLooper.processAllMessages();
+        proxy.setupFalsingManager(getContext());
+        assertThat(proxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java
new file mode 100644
index 0000000..d011e48
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ClassifierTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import android.util.DisplayMetrics;
+import android.view.MotionEvent;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassifierTest extends SysuiTestCase {
+
+    private FalsingDataProvider mDataProvider;
+    private List<MotionEvent> mMotionEvents = new ArrayList<>();
+    private float mOffsetX = 0;
+    private float mOffsetY = 0;
+
+    @Before
+    public void setup() {
+        DisplayMetrics displayMetrics = new DisplayMetrics();
+        displayMetrics.xdpi = 100;
+        displayMetrics.ydpi = 100;
+        displayMetrics.widthPixels = 1000;
+        displayMetrics.heightPixels = 1000;
+        mDataProvider = new FalsingDataProvider(displayMetrics);
+    }
+
+    @After
+    public void tearDown() {
+        resetDataProvider();
+    }
+
+    FalsingDataProvider getDataProvider() {
+        return mDataProvider;
+    }
+
+    void setOffsetX(float offsetX) {
+        mOffsetX = offsetX;
+    }
+
+    void setOffsetY(float offsetY) {
+        mOffsetY = offsetY;
+    }
+
+    void resetDataProvider() {
+        for (MotionEvent motionEvent : mMotionEvents) {
+            motionEvent.recycle();
+        }
+
+        mMotionEvents.clear();
+
+        mDataProvider.onSessionEnd();
+    }
+
+    MotionEvent appendDownEvent(float x, float y) {
+        return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y);
+    }
+
+    MotionEvent appendDownEvent(float x, float y, long eventTime) {
+        return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y, eventTime);
+    }
+
+    MotionEvent appendMoveEvent(float x, float y) {
+        return appendMotionEvent(MotionEvent.ACTION_MOVE, x, y);
+    }
+
+    MotionEvent appendMoveEvent(float x, float y, long eventTime) {
+        return appendMotionEvent(MotionEvent.ACTION_MOVE, x, y, eventTime);
+    }
+
+
+    MotionEvent appendUpEvent(float x, float y) {
+        return appendMotionEvent(MotionEvent.ACTION_UP, x, y);
+    }
+
+    MotionEvent appendUpEvent(float x, float y, long eventTime) {
+        return appendMotionEvent(MotionEvent.ACTION_UP, x, y, eventTime);
+    }
+
+    private MotionEvent appendMotionEvent(int actionType, float x, float y) {
+
+        long eventTime = mMotionEvents.isEmpty() ? 1 : mMotionEvents.get(
+                mMotionEvents.size() - 1).getEventTime() + 1;
+        return appendMotionEvent(actionType, x, y, eventTime);
+    }
+
+    private MotionEvent appendMotionEvent(int actionType, float x, float y, long eventTime) {
+        x += mOffsetX;
+        y += mOffsetY;
+
+        MotionEvent motionEvent = MotionEvent.obtain(1, eventTime, actionType, x, y,
+                0);
+        mMotionEvents.add(motionEvent);
+
+        mDataProvider.onMotionEvent(motionEvent);
+
+        return motionEvent;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java
new file mode 100644
index 0000000..b45d3f2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DiagonalClassifierTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
+import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class DiagonalClassifierTest extends ClassifierTest {
+
+    // Next variable is not actually five, but is very close. 5 degrees is currently the value
+    // used in the diagonal classifier, so we want slightly less than that to deal with
+    // floating point errors.
+    private static final float FIVE_DEG_IN_RADIANS = (float) (4.99f / 360f * Math.PI * 2f);
+    private static final float UP_IN_RADIANS = (float) (Math.PI / 2f);
+    private static final float DOWN_IN_RADIANS = (float) (3 * Math.PI / 2f);
+    private static final float RIGHT_IN_RADIANS = 0;
+    private static final float LEFT_IN_RADIANS = (float) Math.PI;
+    private static final float FORTY_FIVE_DEG_IN_RADIANS = (float) (Math.PI / 4);
+
+    @Mock
+    private FalsingDataProvider mDataProvider;
+    private FalsingClassifier mClassifier;
+
+    @Before
+    public void setup() {
+        super.setup();
+        MockitoAnnotations.initMocks(this);
+        mClassifier = new DiagonalClassifier(mDataProvider);
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+    }
+
+    @Test
+    public void testPass_UnknownAngle() {
+        when(mDataProvider.getAngle()).thenReturn(Float.MAX_VALUE);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_VerticalSwipe() {
+        when(mDataProvider.getAngle()).thenReturn(UP_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(DOWN_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_MostlyVerticalSwipe() {
+        when(mDataProvider.getAngle()).thenReturn(UP_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(UP_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(DOWN_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(DOWN_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS * 2);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_BarelyVerticalSwipe() {
+        when(mDataProvider.getAngle()).thenReturn(
+                UP_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                UP_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                DOWN_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                DOWN_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS * 2);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_HorizontalSwipe() {
+        when(mDataProvider.getAngle()).thenReturn(RIGHT_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(LEFT_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_MostlyHorizontalSwipe() {
+        when(mDataProvider.getAngle()).thenReturn(RIGHT_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(RIGHT_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(LEFT_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(LEFT_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_BarelyHorizontalSwipe() {
+        when(mDataProvider.getAngle()).thenReturn(
+                RIGHT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                LEFT_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                LEFT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                RIGHT_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS * 2);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_AffordanceSwipe() {
+        when(mDataProvider.getInteractionType()).thenReturn(LEFT_AFFORDANCE);
+        when(mDataProvider.getAngle()).thenReturn(
+                RIGHT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.getInteractionType()).thenReturn(RIGHT_AFFORDANCE);
+        when(mDataProvider.getAngle()).thenReturn(
+                LEFT_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        // This classifier may return false for other angles, but these are the only
+        // two that actually matter, as affordances generally only travel in these two directions.
+        // We expect other classifiers to false in those cases, so it really doesn't matter what
+        // we do here.
+    }
+
+    @Test
+    public void testFail_DiagonalSwipe() {
+        // Horizontal Swipes
+        when(mDataProvider.isVertical()).thenReturn(false);
+        when(mDataProvider.getAngle()).thenReturn(
+                RIGHT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                UP_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS + FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                LEFT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                DOWN_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS + FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        // Vertical Swipes
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.getAngle()).thenReturn(
+                RIGHT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS + FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                UP_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+
+        when(mDataProvider.getAngle()).thenReturn(
+                LEFT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS + FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.getAngle()).thenReturn(
+                DOWN_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - FIVE_DEG_IN_RADIANS);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java
new file mode 100644
index 0000000..805bb91
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/DistanceClassifierTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class DistanceClassifierTest extends ClassifierTest {
+
+    private FalsingDataProvider mDataProvider;
+    private FalsingClassifier mClassifier;
+
+    @Before
+    public void setup() {
+        super.setup();
+        mDataProvider = getDataProvider();
+        mClassifier = new DistanceClassifier(mDataProvider);
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+    }
+
+    @Test
+    public void testPass_noPointer() {
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_fling() {
+
+        mClassifier.onTouchEvent(appendDownEvent(1, 1));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        mClassifier.onTouchEvent(appendMoveEvent(1, 2));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        mClassifier.onTouchEvent(appendUpEvent(1, 40));
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFail_flingShort() {
+        mClassifier.onTouchEvent(appendDownEvent(1, 1));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        mClassifier.onTouchEvent(appendMoveEvent(1, 2));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        mClassifier.onTouchEvent(appendUpEvent(1, 10));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testFail_flingSlowly() {
+        // These events, in testing, result in a fling that falls just short of the threshold.
+
+        mClassifier.onTouchEvent(appendDownEvent(1, 1, 1));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        mClassifier.onTouchEvent(appendMoveEvent(1, 15, 2));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        mClassifier.onTouchEvent(appendMoveEvent(1, 16, 3));
+        mClassifier.onTouchEvent(appendMoveEvent(1, 17, 300));
+        mClassifier.onTouchEvent(appendMoveEvent(1, 18, 301));
+        mClassifier.onTouchEvent(appendUpEvent(1, 19, 501));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_swipe() {
+
+        mClassifier.onTouchEvent(appendDownEvent(1, 1));
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        mClassifier.onTouchEvent(appendMoveEvent(1, mDataProvider.getYdpi() * 3, 3));
+        mClassifier.onTouchEvent(appendUpEvent(1, mDataProvider.getYdpi() * 3, 300));
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java
new file mode 100644
index 0000000..748c137
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/FalsingDataProviderTest.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.closeTo;
+import static org.junit.Assert.assertThat;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.util.DisplayMetrics;
+import android.view.MotionEvent;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class FalsingDataProviderTest extends ClassifierTest {
+
+    private FalsingDataProvider mDataProvider;
+
+    @Before
+    public void setup() {
+        super.setup();
+        DisplayMetrics displayMetrics = new DisplayMetrics();
+        displayMetrics.xdpi = 100;
+        displayMetrics.ydpi = 100;
+        displayMetrics.widthPixels = 1000;
+        displayMetrics.heightPixels = 1000;
+        mDataProvider = new FalsingDataProvider(displayMetrics);
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+        mDataProvider.onSessionEnd();
+    }
+
+    @Test
+    public void test_trackMotionEvents() {
+        mDataProvider.onMotionEvent(appendDownEvent(2, 9));
+        mDataProvider.onMotionEvent(appendMoveEvent(4, 7));
+        mDataProvider.onMotionEvent(appendUpEvent(6, 5));
+        List<MotionEvent> motionEventList = mDataProvider.getRecentMotionEvents();
+
+        assertThat(motionEventList.size(), is(3));
+        assertThat(motionEventList.get(0).getActionMasked(), is(MotionEvent.ACTION_DOWN));
+        assertThat(motionEventList.get(1).getActionMasked(), is(MotionEvent.ACTION_MOVE));
+        assertThat(motionEventList.get(2).getActionMasked(), is(MotionEvent.ACTION_UP));
+        assertThat(motionEventList.get(0).getEventTime(), is(1L));
+        assertThat(motionEventList.get(1).getEventTime(), is(2L));
+        assertThat(motionEventList.get(2).getEventTime(), is(3L));
+        assertThat(motionEventList.get(0).getX(), is(2f));
+        assertThat(motionEventList.get(1).getX(), is(4f));
+        assertThat(motionEventList.get(2).getX(), is(6f));
+        assertThat(motionEventList.get(0).getY(), is(9f));
+        assertThat(motionEventList.get(1).getY(), is(7f));
+        assertThat(motionEventList.get(2).getY(), is(5f));
+    }
+
+    @Test
+    public void test_trackRecentMotionEvents() {
+        mDataProvider.onMotionEvent(appendDownEvent(2, 9, 1));
+        mDataProvider.onMotionEvent(appendMoveEvent(4, 7, 800));
+        List<MotionEvent> motionEventList = mDataProvider.getRecentMotionEvents();
+
+        assertThat(motionEventList.size(), is(2));
+        assertThat(motionEventList.get(0).getActionMasked(), is(MotionEvent.ACTION_DOWN));
+        assertThat(motionEventList.get(1).getActionMasked(), is(MotionEvent.ACTION_MOVE));
+        assertThat(motionEventList.get(0).getEventTime(), is(1L));
+        assertThat(motionEventList.get(1).getEventTime(), is(800L));
+        assertThat(motionEventList.get(0).getX(), is(2f));
+        assertThat(motionEventList.get(1).getX(), is(4f));
+        assertThat(motionEventList.get(0).getY(), is(9f));
+        assertThat(motionEventList.get(1).getY(), is(7f));
+
+        mDataProvider.onMotionEvent(appendUpEvent(6, 5, 1200));
+
+        // Still two events, but event a is gone.
+        assertThat(motionEventList.size(), is(2));
+        assertThat(motionEventList.get(0).getActionMasked(), is(MotionEvent.ACTION_MOVE));
+        assertThat(motionEventList.get(1).getActionMasked(), is(MotionEvent.ACTION_UP));
+        assertThat(motionEventList.get(0).getEventTime(), is(800L));
+        assertThat(motionEventList.get(1).getEventTime(), is(1200L));
+        assertThat(motionEventList.get(0).getX(), is(4f));
+        assertThat(motionEventList.get(1).getX(), is(6f));
+        assertThat(motionEventList.get(0).getY(), is(7f));
+        assertThat(motionEventList.get(1).getY(), is(5f));
+
+        // The first, real event should still be a, however.
+        MotionEvent firstRealMotionEvent = mDataProvider.getFirstActualMotionEvent();
+        assertThat(firstRealMotionEvent.getActionMasked(), is(MotionEvent.ACTION_DOWN));
+        assertThat(firstRealMotionEvent.getEventTime(), is(1L));
+        assertThat(firstRealMotionEvent.getX(), is(2f));
+        assertThat(firstRealMotionEvent.getY(), is(9f));
+    }
+
+    @Test
+    public void test_unpackMotionEvents() {
+        // Batching only works for motion events of the same type.
+        MotionEvent motionEventA = appendMoveEvent(2, 9);
+        MotionEvent motionEventB = appendMoveEvent(4, 7);
+        MotionEvent motionEventC = appendMoveEvent(6, 5);
+        motionEventA.addBatch(motionEventB);
+        motionEventA.addBatch(motionEventC);
+        // Note that calling addBatch changes properties on the original event, not just it's
+        // historical artifacts.
+
+        mDataProvider.onMotionEvent(motionEventA);
+        List<MotionEvent> motionEventList = mDataProvider.getRecentMotionEvents();
+
+        assertThat(motionEventList.size(), is(3));
+        assertThat(motionEventList.get(0).getActionMasked(), is(MotionEvent.ACTION_MOVE));
+        assertThat(motionEventList.get(1).getActionMasked(), is(MotionEvent.ACTION_MOVE));
+        assertThat(motionEventList.get(2).getActionMasked(), is(MotionEvent.ACTION_MOVE));
+        assertThat(motionEventList.get(0).getEventTime(), is(1L));
+        assertThat(motionEventList.get(1).getEventTime(), is(2L));
+        assertThat(motionEventList.get(2).getEventTime(), is(3L));
+        assertThat(motionEventList.get(0).getX(), is(2f));
+        assertThat(motionEventList.get(1).getX(), is(4f));
+        assertThat(motionEventList.get(2).getX(), is(6f));
+        assertThat(motionEventList.get(0).getY(), is(9f));
+        assertThat(motionEventList.get(1).getY(), is(7f));
+        assertThat(motionEventList.get(2).getY(), is(5f));
+    }
+
+    @Test
+    public void test_getAngle() {
+        MotionEvent motionEventOrigin = appendDownEvent(0, 0);
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(1, 1));
+        assertThat((double) mDataProvider.getAngle(), closeTo(Math.PI / 4, .001));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(-1, -1));
+        assertThat((double) mDataProvider.getAngle(), closeTo(5 * Math.PI / 4, .001));
+        mDataProvider.onSessionEnd();
+
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(2, 0));
+        assertThat((double) mDataProvider.getAngle(), closeTo(0, .001));
+        mDataProvider.onSessionEnd();
+    }
+
+    @Test
+    public void test_isHorizontal() {
+        MotionEvent motionEventOrigin = appendDownEvent(0, 0);
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(1, 1));
+        assertThat(mDataProvider.isHorizontal(), is(false));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(2, 1));
+        assertThat(mDataProvider.isHorizontal(), is(true));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(-3, -1));
+        assertThat(mDataProvider.isHorizontal(), is(true));
+        mDataProvider.onSessionEnd();
+    }
+
+    @Test
+    public void test_isVertical() {
+        MotionEvent motionEventOrigin = appendDownEvent(0, 0);
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(1, 0));
+        assertThat(mDataProvider.isVertical(), is(false));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(0, 1));
+        assertThat(mDataProvider.isVertical(), is(true));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(-3, -10));
+        assertThat(mDataProvider.isVertical(), is(true));
+        mDataProvider.onSessionEnd();
+    }
+
+    @Test
+    public void test_isRight() {
+        MotionEvent motionEventOrigin = appendDownEvent(0, 0);
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(1, 1));
+        assertThat(mDataProvider.isRight(), is(true));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(0, 1));
+        assertThat(mDataProvider.isRight(), is(false));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(-3, -10));
+        assertThat(mDataProvider.isRight(), is(false));
+        mDataProvider.onSessionEnd();
+    }
+
+    @Test
+    public void test_isUp() {
+        // Remember that our y axis is flipped.
+
+        MotionEvent motionEventOrigin = appendDownEvent(0, 0);
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(1, -1));
+        assertThat(mDataProvider.isUp(), is(true));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(0, 0));
+        assertThat(mDataProvider.isUp(), is(false));
+        mDataProvider.onSessionEnd();
+
+        mDataProvider.onMotionEvent(motionEventOrigin);
+        mDataProvider.onMotionEvent(appendMoveEvent(-3, 10));
+        assertThat(mDataProvider.isUp(), is(false));
+        mDataProvider.onSessionEnd();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java
new file mode 100644
index 0000000..341b74b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/PointerCountClassifierTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.MotionEvent;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class PointerCountClassifierTest extends ClassifierTest {
+
+    private FalsingClassifier mClassifier;
+
+    @Before
+    public void setup() {
+        super.setup();
+        mClassifier = new PointerCountClassifier(getDataProvider());
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+    }
+
+    @Test
+    public void testPass_noPointer() {
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_singlePointer() {
+        mClassifier.onTouchEvent(appendDownEvent(1, 1));
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFail_multiPointer() {
+        MotionEvent.PointerProperties[] pointerProperties =
+                MotionEvent.PointerProperties.createArray(2);
+        pointerProperties[0].id = 0;
+        pointerProperties[1].id = 1;
+        MotionEvent.PointerCoords[] pointerCoords = MotionEvent.PointerCoords.createArray(2);
+        MotionEvent motionEvent = MotionEvent.obtain(
+                1, 1, MotionEvent.ACTION_DOWN, 2, pointerProperties, pointerCoords, 0, 0, 0, 0, 0,
+                0,
+                0, 0);
+        mClassifier.onTouchEvent(motionEvent);
+        motionEvent.recycle();
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
new file mode 100644
index 0000000..a6cabbf
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ProximityClassifierTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static com.android.systemui.classifier.Classifier.GENERIC;
+import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.MotionEvent;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.lang.reflect.Field;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ProximityClassifierTest extends ClassifierTest {
+
+    private static final long NS_PER_MS = 1000000;
+
+    @Mock
+    private FalsingDataProvider mDataProvider;
+    @Mock
+    private DistanceClassifier mDistanceClassifier;
+    private FalsingClassifier mClassifier;
+
+    @Before
+    public void setup() {
+        super.setup();
+        MockitoAnnotations.initMocks(this);
+        when(mDataProvider.getInteractionType()).thenReturn(GENERIC);
+        when(mDistanceClassifier.isLongSwipe()).thenReturn(false);
+        mClassifier = new ProximityClassifier(mDistanceClassifier, mDataProvider);
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+    }
+
+    @Test
+    public void testPass_uncovered() {
+        touchDown();
+        touchUp(10);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_mostlyUncovered() {
+        touchDown();
+        mClassifier.onSensorEvent(createSensorEvent(true, 1));
+        mClassifier.onSensorEvent(createSensorEvent(false, 2));
+        touchUp(20);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_quickSettings() {
+        touchDown();
+        when(mDataProvider.getInteractionType()).thenReturn(QUICK_SETTINGS);
+        mClassifier.onSensorEvent(createSensorEvent(true, 1));
+        mClassifier.onSensorEvent(createSensorEvent(false, 11));
+        touchUp(10);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFail_covered() {
+        touchDown();
+        mClassifier.onSensorEvent(createSensorEvent(true, 1));
+        mClassifier.onSensorEvent(createSensorEvent(false, 11));
+        touchUp(10);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testFail_mostlyCovered() {
+        touchDown();
+        mClassifier.onSensorEvent(createSensorEvent(true, 1));
+        mClassifier.onSensorEvent(createSensorEvent(true, 95));
+        mClassifier.onSensorEvent(createSensorEvent(true, 96));
+        mClassifier.onSensorEvent(createSensorEvent(false, 100));
+        touchUp(100);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_coveredWithLongSwipe() {
+        touchDown();
+        mClassifier.onSensorEvent(createSensorEvent(true, 1));
+        mClassifier.onSensorEvent(createSensorEvent(false, 11));
+        touchUp(10);
+        when(mDistanceClassifier.isLongSwipe()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    private void touchDown() {
+        MotionEvent motionEvent = MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, 0, 0, 0);
+        mClassifier.onTouchEvent(motionEvent);
+        motionEvent.recycle();
+    }
+
+    private void touchUp(long duration) {
+        MotionEvent motionEvent = MotionEvent.obtain(1, 1 + duration, MotionEvent.ACTION_UP, 0,
+                100, 0);
+
+        mClassifier.onTouchEvent(motionEvent);
+
+        motionEvent.recycle();
+    }
+
+    private SensorEvent createSensorEvent(boolean covered, long timestampMs) {
+        SensorEvent sensorEvent = Mockito.mock(SensorEvent.class);
+        Sensor sensor = Mockito.mock(Sensor.class);
+        when(sensor.getType()).thenReturn(Sensor.TYPE_PROXIMITY);
+        when(sensor.getMaximumRange()).thenReturn(1f);
+        sensorEvent.sensor = sensor;
+        sensorEvent.timestamp = timestampMs * NS_PER_MS;
+        try {
+            Field valuesField = SensorEvent.class.getField("values");
+            valuesField.setAccessible(true);
+            float[] sensorValue = {covered ? 0 : 1};
+            try {
+                valuesField.set(sensorEvent, sensorValue);
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+        } catch (NoSuchFieldException e) {
+            e.printStackTrace();
+        }
+
+        return sensorEvent;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java
new file mode 100644
index 0000000..0355dc3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/TypeClassifierTest.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
+import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
+import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
+import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
+import static com.android.systemui.classifier.Classifier.PULSE_EXPAND;
+import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
+import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
+import static com.android.systemui.classifier.Classifier.UNLOCK;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+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 TypeClassifierTest extends ClassifierTest {
+
+    @Mock
+    private FalsingDataProvider mDataProvider;
+    private FalsingClassifier mClassifier;
+
+    @Before
+    public void setup() {
+        super.setup();
+        MockitoAnnotations.initMocks(this);
+        mClassifier = new TypeClassifier(mDataProvider);
+    }
+
+    @Test
+    public void testPass_QuickSettings() {
+        when(mDataProvider.getInteractionType()).thenReturn(QUICK_SETTINGS);
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(false);
+
+        when(mDataProvider.isRight()).thenReturn(false);  // right should cause no effect.
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFalse_QuickSettings() {
+        when(mDataProvider.getInteractionType()).thenReturn(QUICK_SETTINGS);
+
+        when(mDataProvider.isVertical()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_PulseExpand() {
+        when(mDataProvider.getInteractionType()).thenReturn(PULSE_EXPAND);
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(false);
+
+        when(mDataProvider.isRight()).thenReturn(false);  // right should cause no effect.
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFalse_PulseExpand() {
+        when(mDataProvider.getInteractionType()).thenReturn(PULSE_EXPAND);
+
+        when(mDataProvider.isVertical()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_NotificationDragDown() {
+        when(mDataProvider.getInteractionType()).thenReturn(NOTIFICATION_DRAG_DOWN);
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(false);
+
+        when(mDataProvider.isRight()).thenReturn(false);  // right should cause no effect.
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFalse_NotificationDragDown() {
+        when(mDataProvider.getInteractionType()).thenReturn(NOTIFICATION_DRAG_DOWN);
+
+        when(mDataProvider.isVertical()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_NotificationDismiss() {
+        when(mDataProvider.getInteractionType()).thenReturn(NOTIFICATION_DISMISS);
+        when(mDataProvider.isVertical()).thenReturn(false);
+
+        when(mDataProvider.isUp()).thenReturn(false);  // up and right should cause no effect.
+        when(mDataProvider.isRight()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isUp()).thenReturn(false);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFalse_NotificationDismiss() {
+        when(mDataProvider.getInteractionType()).thenReturn(NOTIFICATION_DISMISS);
+        when(mDataProvider.isVertical()).thenReturn(true);
+
+        when(mDataProvider.isUp()).thenReturn(false);  // up and right should cause no effect.
+        when(mDataProvider.isRight()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isUp()).thenReturn(false);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+
+    @Test
+    public void testPass_Unlock() {
+        when(mDataProvider.getInteractionType()).thenReturn(UNLOCK);
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(true);
+
+
+        when(mDataProvider.isRight()).thenReturn(false);  // right should cause no effect.
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFalse_Unlock() {
+        when(mDataProvider.getInteractionType()).thenReturn(UNLOCK);
+
+        when(mDataProvider.isVertical()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isVertical()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_BouncerUnlock() {
+        when(mDataProvider.getInteractionType()).thenReturn(BOUNCER_UNLOCK);
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(true);
+
+
+        when(mDataProvider.isRight()).thenReturn(false);  // right should cause no effect.
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFalse_BouncerUnlock() {
+        when(mDataProvider.getInteractionType()).thenReturn(BOUNCER_UNLOCK);
+
+        when(mDataProvider.isVertical()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isVertical()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isVertical()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_LeftAffordance() {
+        when(mDataProvider.getInteractionType()).thenReturn(LEFT_AFFORDANCE);
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(true);
+
+
+        when(mDataProvider.isVertical()).thenReturn(false);  // vertical should cause no effect.
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isVertical()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFalse_LeftAffordance() {
+        when(mDataProvider.getInteractionType()).thenReturn(LEFT_AFFORDANCE);
+
+        when(mDataProvider.isRight()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isRight()).thenReturn(true);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isRight()).thenReturn(false);
+        when(mDataProvider.isUp()).thenReturn(false);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_RightAffordance() {
+        when(mDataProvider.getInteractionType()).thenReturn(RIGHT_AFFORDANCE);
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(false);
+
+
+        when(mDataProvider.isVertical()).thenReturn(false);  // vertical should cause no effect.
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        when(mDataProvider.isVertical()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFalse_RightAffordance() {
+        when(mDataProvider.getInteractionType()).thenReturn(RIGHT_AFFORDANCE);
+
+        when(mDataProvider.isUp()).thenReturn(true);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isUp()).thenReturn(false);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+
+        when(mDataProvider.isUp()).thenReturn(false);
+        when(mDataProvider.isRight()).thenReturn(true);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java
new file mode 100644
index 0000000..25a1a75
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/brightline/ZigZagClassifierTest.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.classifier.brightline;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class ZigZagClassifierTest extends ClassifierTest {
+
+    private FalsingClassifier mClassifier;
+
+    @Before
+    public void setup() {
+        super.setup();
+        mClassifier = new ZigZagClassifier(getDataProvider());
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+    }
+
+    @Test
+    public void testPass_fewTouchesVertical() {
+        assertThat(mClassifier.isFalseTouch(), is(false));
+        appendMoveEvent(0, 0);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+        appendMoveEvent(0, 100);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_vertical() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(0, 100);
+        appendMoveEvent(0, 200);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_fewTouchesHorizontal() {
+        assertThat(mClassifier.isFalseTouch(), is(false));
+        appendMoveEvent(0, 0);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+        appendMoveEvent(100, 0);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_horizontal() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(100, 0);
+        appendMoveEvent(200, 0);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+
+    @Test
+    public void testFail_minimumTouchesVertical() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(0, 100);
+        appendMoveEvent(0, 1);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testFail_minimumTouchesHorizontal() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(100, 0);
+        appendMoveEvent(1, 0);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testPass_fortyFiveDegreesStraight() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(10, 10);
+        appendMoveEvent(20, 20);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_horizontalZigZagVerticalStraight() {
+        // This test looks just like testFail_horizontalZigZagVerticalStraight but with
+        // a longer y range, making it look straighter.
+        appendMoveEvent(0, 0);
+        appendMoveEvent(5, 100);
+        appendMoveEvent(-5, 200);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testPass_horizontalStraightVerticalZigZag() {
+        // This test looks just like testFail_horizontalStraightVerticalZigZag but with
+        // a longer x range, making it look straighter.
+        appendMoveEvent(0, 0);
+        appendMoveEvent(100, 5);
+        appendMoveEvent(200, -5);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+    }
+
+    @Test
+    public void testFail_horizontalZigZagVerticalStraight() {
+        // This test looks just like testPass_horizontalZigZagVerticalStraight but with
+        // a shorter y range, making it look more crooked.
+        appendMoveEvent(0, 0);
+        appendMoveEvent(5, 10);
+        appendMoveEvent(-5, 20);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void testFail_horizontalStraightVerticalZigZag() {
+        // This test looks just like testPass_horizontalStraightVerticalZigZag but with
+        // a shorter x range, making it look more crooked.
+        appendMoveEvent(0, 0);
+        appendMoveEvent(10, 5);
+        appendMoveEvent(20, -5);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_between0And45() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(100, 5);
+        appendMoveEvent(200, 10);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(100, 0);
+        appendMoveEvent(200, 10);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(100, -10);
+        appendMoveEvent(200, 10);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(100, -10);
+        appendMoveEvent(200, 50);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_between45And90() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(10, 50);
+        appendMoveEvent(8, 100);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(1, 800);
+        appendMoveEvent(2, 900);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-10, 600);
+        appendMoveEvent(30, 700);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(40, 100);
+        appendMoveEvent(0, 101);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_between90And135() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-10, 50);
+        appendMoveEvent(-24, 100);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-20, 800);
+        appendMoveEvent(-20, 900);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(30, 600);
+        appendMoveEvent(-10, 700);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-80, 100);
+        appendMoveEvent(-10, 101);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_between135And180() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-120, 10);
+        appendMoveEvent(-200, 20);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-20, 8);
+        appendMoveEvent(-40, 2);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-500, -2);
+        appendMoveEvent(-600, 70);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-80, 100);
+        appendMoveEvent(-100, 1);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_between180And225() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-120, -10);
+        appendMoveEvent(-200, -20);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-20, -8);
+        appendMoveEvent(-40, -2);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-500, 2);
+        appendMoveEvent(-600, -70);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-80, -100);
+        appendMoveEvent(-100, -1);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_between225And270() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-12, -20);
+        appendMoveEvent(-20, -40);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-20, -130);
+        appendMoveEvent(-40, -260);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(1, -100);
+        appendMoveEvent(-6, -200);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-80, -100);
+        appendMoveEvent(-10, -110);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_between270And315() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(12, -20);
+        appendMoveEvent(20, -40);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(20, -130);
+        appendMoveEvent(40, -260);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(-1, -100);
+        appendMoveEvent(6, -200);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(80, -100);
+        appendMoveEvent(10, -110);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_between315And360() {
+        appendMoveEvent(0, 0);
+        appendMoveEvent(120, -20);
+        appendMoveEvent(200, -40);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(200, -13);
+        appendMoveEvent(400, -30);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(100, 10);
+        appendMoveEvent(600, -20);
+        assertThat(mClassifier.isFalseTouch(), is(false));
+
+        resetDataProvider();
+        appendMoveEvent(0, 0);
+        appendMoveEvent(80, -100);
+        appendMoveEvent(100, -1);
+        assertThat(mClassifier.isFalseTouch(), is(true));
+    }
+
+    @Test
+    public void test_randomOrigins() {
+        // The purpose of this test is to try all the other tests from different starting points.
+        // We use a pre-determined seed to make this test repeatable.
+        Random rand = new Random(23);
+        for (int i = 0; i < 100; i++) {
+            setOffsetX(rand.nextInt(2000) - 1000);
+            setOffsetY(rand.nextInt(2000) - 1000);
+            try {
+                resetDataProvider();
+                testPass_fewTouchesVertical();
+                resetDataProvider();
+                testPass_vertical();
+                resetDataProvider();
+                testFail_horizontalStraightVerticalZigZag();
+                resetDataProvider();
+                testFail_horizontalZigZagVerticalStraight();
+                resetDataProvider();
+                testFail_minimumTouchesHorizontal();
+                resetDataProvider();
+                testFail_minimumTouchesVertical();
+                resetDataProvider();
+                testPass_fewTouchesHorizontal();
+                resetDataProvider();
+                testPass_fortyFiveDegreesStraight();
+                resetDataProvider();
+                testPass_horizontal();
+                resetDataProvider();
+                testPass_horizontalStraightVerticalZigZag();
+                resetDataProvider();
+                testPass_horizontalZigZagVerticalStraight();
+                resetDataProvider();
+                test_between0And45();
+                resetDataProvider();
+                test_between45And90();
+                resetDataProvider();
+                test_between90And135();
+                resetDataProvider();
+                test_between135And180();
+                resetDataProvider();
+                test_between180And225();
+                resetDataProvider();
+                test_between225And270();
+                resetDataProvider();
+                test_between270And315();
+                resetDataProvider();
+                test_between315And360();
+            } catch (AssertionError e) {
+                throw new AssertionError("Random origin failure in iteration " + i, e);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
index 67df60a..41747f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -36,8 +37,11 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Tests color extraction generation.
@@ -54,62 +58,52 @@
             ColorExtractor.TYPE_DARK,
             ColorExtractor.TYPE_EXTRA_DARK};
 
-    @Test
-    public void getColors_usesGreyIfWallpaperNotVisible() {
-        ColorExtractor.GradientColors colors = new ColorExtractor.GradientColors();
-        colors.setMainColor(Color.RED);
-        colors.setSecondaryColor(Color.RED);
+    @Mock
+    private WallpaperManager mWallpaperManager;
+    private ColorExtractor.GradientColors mColors;
+    private SysuiColorExtractor mColorExtractor;
 
-        SysuiColorExtractor extractor = getTestableExtractor(colors);
-        simulateEvent(extractor);
-        extractor.setWallpaperVisible(false);
-
-        ColorExtractor.GradientColors fallbackColors = extractor.getNeutralColors();
-
-        for (int type : sTypes) {
-            assertEquals("Not using fallback!",
-                    extractor.getColors(WallpaperManager.FLAG_SYSTEM, type), fallbackColors);
-            assertNotEquals("Wallpaper visibility event should not affect lock wallpaper.",
-                    extractor.getColors(WallpaperManager.FLAG_LOCK, type), fallbackColors);
-        }
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mColors = new ColorExtractor.GradientColors();
+        mColors.setMainColor(Color.RED);
+        mColors.setSecondaryColor(Color.RED);
+        mColorExtractor = new SysuiColorExtractor(getContext(),
+                (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark,
+                        outGradientColorsExtraDark) -> {
+                    outGradientColorsNormal.set(mColors);
+                    outGradientColorsDark.set(mColors);
+                    outGradientColorsExtraDark.set(mColors);
+                }, mock(ConfigurationController.class), mWallpaperManager, true /* immediately */);
     }
 
     @Test
-    public void getColors_doesntUseFallbackIfVisible() {
-        ColorExtractor.GradientColors colors = new ColorExtractor.GradientColors();
-        colors.setMainColor(Color.RED);
-        colors.setSecondaryColor(Color.RED);
+    public void getColors() {
+        mColors.setMainColor(Color.RED);
+        mColors.setSecondaryColor(Color.RED);
 
-        SysuiColorExtractor extractor = getTestableExtractor(colors);
-        simulateEvent(extractor);
-        extractor.setWallpaperVisible(true);
-
+        simulateEvent(mColorExtractor);
         for (int which : sWhich) {
             for (int type : sTypes) {
                 assertEquals("Not using extracted colors!",
-                        extractor.getColors(which, type), colors);
+                        mColorExtractor.getColors(which, type), mColors);
             }
         }
     }
 
     @Test
     public void getColors_fallbackWhenMediaIsVisible() {
-        ColorExtractor.GradientColors colors = new ColorExtractor.GradientColors();
-        colors.setMainColor(Color.RED);
-        colors.setSecondaryColor(Color.RED);
+        simulateEvent(mColorExtractor);
+        mColorExtractor.setHasMediaArtwork(true);
 
-        SysuiColorExtractor extractor = getTestableExtractor(colors);
-        simulateEvent(extractor);
-        extractor.setWallpaperVisible(true);
-        extractor.setHasBackdrop(true);
-
-        ColorExtractor.GradientColors fallbackColors = extractor.getNeutralColors();
+        ColorExtractor.GradientColors fallbackColors = mColorExtractor.getNeutralColors();
 
         for (int type : sTypes) {
             assertEquals("Not using fallback!",
-                    extractor.getColors(WallpaperManager.FLAG_LOCK, type), fallbackColors);
+                    mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, type), fallbackColors);
             assertNotEquals("Media visibility should not affect system wallpaper.",
-                    extractor.getColors(WallpaperManager.FLAG_SYSTEM, type), fallbackColors);
+                    mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM, type), fallbackColors);
         }
     }
 
@@ -118,7 +112,7 @@
         Tonal tonal = mock(Tonal.class);
         ConfigurationController configurationController = mock(ConfigurationController.class);
         SysuiColorExtractor sysuiColorExtractor = new SysuiColorExtractor(getContext(),
-                tonal, configurationController, false /* registerVisibility */);
+                tonal, configurationController, mWallpaperManager, true /* immediately */);
         verify(configurationController).addCallback(eq(sysuiColorExtractor));
 
         reset(tonal);
@@ -126,14 +120,13 @@
         verify(tonal).applyFallback(any(), any());
     }
 
-    private SysuiColorExtractor getTestableExtractor(ColorExtractor.GradientColors colors) {
-        return new SysuiColorExtractor(getContext(),
-                (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark,
-                        outGradientColorsExtraDark) -> {
-                    outGradientColorsNormal.set(colors);
-                    outGradientColorsDark.set(colors);
-                    outGradientColorsExtraDark.set(colors);
-                }, mock(ConfigurationController.class), false);
+    @Test
+    public void onUiModeChanged_notifiesListener() {
+        ColorExtractor.OnColorsChangedListener listener = mock(
+                ColorExtractor.OnColorsChangedListener.class);
+        mColorExtractor.addOnColorsChangedListener(listener);
+        mColorExtractor.onUiModeChanged();
+        verify(listener).onColorsChanged(any(), anyInt());
     }
 
     private void simulateEvent(SysuiColorExtractor extractor) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
index 9438cbb..2ed0970 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
@@ -24,6 +24,7 @@
 import static org.mockito.Mockito.withSettings;
 
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.utils.hardware.FakeSensorManager;
 
 import org.mockito.Answers;
 import org.mockito.MockSettings;
@@ -36,9 +37,10 @@
         when(params.getPulseOnSigMotion()).thenReturn(false);
         when(params.getPickupVibrationThreshold()).thenReturn(0);
         when(params.getProxCheckBeforePulse()).thenReturn(true);
-        when(params.getPickupSubtypePerformsProxCheck(anyInt())).thenReturn(true);
+        when(params.getPickupPerformsProxCheck()).thenReturn(true);
         when(params.getPolicy()).thenReturn(mock(AlwaysOnDisplayPolicy.class));
         when(params.doubleTapReportsTouchCoordinates()).thenReturn(false);
+        when(params.getDisplayNeedsBlanking()).thenReturn(false);
 
         doneHolder[0] = true;
         return params;
@@ -52,11 +54,17 @@
         when(config.pickupGestureEnabled(anyInt())).thenReturn(false);
         when(config.pulseOnNotificationEnabled(anyInt())).thenReturn(true);
         when(config.alwaysOnEnabled(anyInt())).thenReturn(false);
+        when(config.enabled(anyInt())).thenReturn(true);
+        when(config.getWakeLockScreenDebounce()).thenReturn(0L);
 
         when(config.doubleTapSensorType()).thenReturn(null);
         when(config.tapSensorType()).thenReturn(null);
         when(config.longPressSensorType()).thenReturn(null);
 
+        when(config.tapGestureEnabled(anyInt())).thenReturn(true);
+        when(config.tapSensorAvailable()).thenReturn(true);
+        when(config.tapSensorType()).thenReturn(FakeSensorManager.TAP_SENSOR_TYPE);
+
         when(config.dozePickupSensorAvailable()).thenReturn(false);
         when(config.wakeScreenGestureAvailable()).thenReturn(false);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 4467faf..7df45a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -23,14 +23,17 @@
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 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.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
+import android.database.ContentObserver;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -39,6 +42,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.doze.DozeSensors.TriggerSensor;
 import com.android.systemui.plugins.SensorManagerPlugin;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AsyncSensorManager;
@@ -73,6 +77,10 @@
     private Consumer<Boolean> mProxCallback;
     @Mock
     private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy;
+    @Mock
+    private TriggerSensor mTriggerSensor;
+    @Mock
+    private TriggerSensor mProxGatedTriggerSensor;
     private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
     private TestableLooper mTestableLooper;
     private DozeSensors mDozeSensors;
@@ -80,6 +88,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        when(mProxGatedTriggerSensor.performsProxCheck()).thenReturn(true);
         mTestableLooper = TestableLooper.get(this);
         when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L);
         when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
@@ -107,6 +116,38 @@
                 anyBoolean(), anyFloat(), anyFloat(), eq(null));
     }
 
+    @Test
+    public void testSetListening_firstTrue_registerSettingsObserver() {
+        mDozeSensors.setListening(true);
+
+        verify(mTriggerSensor).registerSettingsObserver(any(ContentObserver.class));
+    }
+
+    @Test
+    public void testSetListening_twiceTrue_onlyRegisterSettingsObserverOnce() {
+        mDozeSensors.setListening(true);
+        mDozeSensors.setListening(true);
+
+        verify(mTriggerSensor, times(1)).registerSettingsObserver(any(ContentObserver.class));
+    }
+
+    @Test
+    public void testSetPaused_onlyPausesNonGatedSensors() {
+        mDozeSensors.setListening(true);
+        verify(mTriggerSensor).setListening(eq(true));
+        verify(mProxGatedTriggerSensor).setListening(eq(true));
+
+        clearInvocations(mTriggerSensor, mProxGatedTriggerSensor);
+        mDozeSensors.setPaused(true);
+        verify(mTriggerSensor).setListening(eq(false));
+        verify(mProxGatedTriggerSensor).setListening(eq(true));
+
+        clearInvocations(mTriggerSensor, mProxGatedTriggerSensor);
+        mDozeSensors.setPaused(false);
+        verify(mTriggerSensor).setListening(eq(true));
+        verify(mProxGatedTriggerSensor).setListening(eq(true));
+    }
+
     private class TestableDozeSensors extends DozeSensors {
 
         TestableDozeSensors() {
@@ -120,6 +161,7 @@
                     mWakeLockScreenListener = (PluginSensor) sensor;
                 }
             }
+            mSensors = new TriggerSensor[] {mTriggerSensor, mProxGatedTriggerSensor};
         }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 6979fd8..eb8ef09 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -27,18 +28,17 @@
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
-import android.app.Instrumentation;
+import android.hardware.Sensor;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.Handler;
 import android.os.Looper;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 
-import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dock.DockManagerFake;
+import com.android.systemui.dock.DockManager;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.wakelock.WakeLock;
 import com.android.systemui.util.wakelock.WakeLockFake;
@@ -46,14 +46,12 @@
 
 import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @SmallTest
-@Ignore("failing")
 @RunWith(AndroidTestingRunner.class)
-@RunWithLooper
+@RunWithLooper(setAsMainLooper = true)
 public class DozeTriggersTest extends SysuiTestCase {
     private DozeTriggers mTriggers;
     private DozeMachine mMachine;
@@ -61,10 +59,10 @@
     private AmbientDisplayConfiguration mConfig;
     private DozeParameters mParameters;
     private FakeSensorManager mSensors;
+    private Sensor mTapSensor;
     private WakeLock mWakeLock;
-    private Instrumentation mInstrumentation;
     private AlarmManager mAlarmManager;
-    private DockManagerFake mDockManagerFake;
+    private DockManager mDockManagerFake;
 
     @BeforeClass
     public static void setupSuite() {
@@ -74,15 +72,15 @@
 
     @Before
     public void setUp() throws Exception {
-        mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mMachine = mock(DozeMachine.class);
         mAlarmManager = mock(AlarmManager.class);
-        mHost = new DozeHostFake();
+        mHost = spy(new DozeHostFake());
         mConfig = DozeConfigurationUtil.createMockConfig();
         mParameters = DozeConfigurationUtil.createMockParameters();
-        mSensors = new FakeSensorManager(mContext);
+        mSensors = spy(new FakeSensorManager(mContext));
+        mTapSensor = mSensors.getFakeTapSensor().getSensor();
         mWakeLock = new WakeLockFake();
-        mDockManagerFake = spy(new DockManagerFake());
+        mDockManagerFake = mock(DockManager.class);
 
         mTriggers = new DozeTriggers(mContext, mMachine, mHost, mAlarmManager, mConfig, mParameters,
                 mSensors, Handler.createAsync(Looper.myLooper()), mWakeLock, true,
@@ -95,29 +93,45 @@
 
         mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
         mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
+        clearInvocations(mMachine);
 
         mHost.callback.onNotificationAlerted();
-
         mSensors.getMockProximitySensor().sendProximityResult(false); /* Near */
 
         verify(mMachine, never()).requestState(any());
         verify(mMachine, never()).requestPulse(anyInt());
 
         mHost.callback.onNotificationAlerted();
-
         mSensors.getMockProximitySensor().sendProximityResult(true); /* Far */
 
         verify(mMachine).requestPulse(anyInt());
     }
 
     @Test
+    public void testTransitionTo_disablesAndEnablesTouchSensors() {
+        when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
+
+        mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
+        verify(mSensors).requestTriggerSensor(any(), eq(mTapSensor));
+
+        clearInvocations(mSensors);
+        mTriggers.transitionTo(DozeMachine.State.DOZE,
+                DozeMachine.State.DOZE_REQUEST_PULSE);
+        mTriggers.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE,
+                DozeMachine.State.DOZE_PULSING);
+        verify(mSensors).cancelTriggerSensor(any(), eq(mTapSensor));
+
+        clearInvocations(mSensors);
+        mTriggers.transitionTo(DozeMachine.State.DOZE_PULSING, DozeMachine.State.DOZE_PULSE_DONE);
+        verify(mSensors).requestTriggerSensor(any(), eq(mTapSensor));
+    }
+
+    @Test
     public void testDockEventListener_registerAndUnregister() {
         mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
-
         verify(mDockManagerFake).addListener(any());
 
         mTriggers.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH);
-
         verify(mDockManagerFake).removeListener(any());
     }
 
@@ -128,7 +142,6 @@
         mTriggers.onSensor(DozeLog.REASON_SENSOR_DOUBLE_TAP,
                 false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */,
                 null /* rawValues */);
-
         verify(mMachine, never()).wakeUp();
     }
 
@@ -142,7 +155,7 @@
                 false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */,
                 null /* rawValues */);
 
-        verify(mHost).setAodDimmingScrim(eq(255));
+        verify(mHost).setAodDimmingScrim(eq(1f));
         verify(mMachine).wakeUp();
     }
 }
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 87ae85f..f07edf3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java
@@ -18,6 +18,7 @@
 
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -29,6 +30,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
 
 import org.junit.Before;
@@ -44,12 +46,14 @@
 
     private DozeWallpaperState mDozeWallpaperState;
     @Mock IWallpaperManager mIWallpaperManager;
+    @Mock BiometricUnlockController mBiometricUnlockController;
     @Mock DozeParameters mDozeParameters;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mDozeParameters);
+        mDozeWallpaperState = new DozeWallpaperState(mIWallpaperManager, mBiometricUnlockController,
+                mDozeParameters);
     }
 
     @Test
@@ -102,6 +106,20 @@
     }
 
     @Test
+    public void testDoesNotAnimate_whenWakeAndUnlock() throws RemoteException {
+        // Pre-conditions
+        when(mDozeParameters.getAlwaysOn()).thenReturn(true);
+        when(mBiometricUnlockController.unlockedByWakeAndUnlock()).thenReturn(true);
+
+        mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED,
+                DozeMachine.State.DOZE_AOD);
+        clearInvocations(mIWallpaperManager);
+
+        mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH);
+        verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(0L));
+    }
+
+    @Test
     public void testTransitionTo_requestPulseIsAmbientMode() throws RemoteException {
         mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE,
                 DozeMachine.State.DOZE_REQUEST_PULSE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index 355e260..893f3d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -48,6 +48,10 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.wakelock.SettableWakeLock;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -73,6 +77,16 @@
     private NotificationMediaManager mNotificationMediaManager;
     @Mock
     private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private KeyguardBypassController mKeyguardBypassController;
+    @Mock
+    private ZenModeController mZenModeController;
+    @Mock
+    private SettableWakeLock mMediaWakeLock;
+    @Mock
+    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @Mock
+    private DozeParameters mDozeParameters;
     private TestableKeyguardSliceProvider mProvider;
     private boolean mIsZenMode;
 
@@ -82,7 +96,8 @@
         mIsZenMode = false;
         mProvider = new TestableKeyguardSliceProvider();
         mProvider.attachInfo(getContext(), null);
-        mProvider.initDependencies(mNotificationMediaManager, mStatusBarStateController);
+        mProvider.initDependencies(mNotificationMediaManager, mStatusBarStateController,
+                mKeyguardBypassController, mDozeParameters);
         SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));
     }
 
@@ -102,7 +117,7 @@
     }
 
     @Test
-    public void onBindSlice_readsMedia() {
+    public void onBindSlice_readsMedia_withoutBypass() {
         MediaMetadata metadata = mock(MediaMetadata.class);
         when(metadata.getText(any())).thenReturn("metadata");
         mProvider.onDozingChanged(true);
@@ -114,6 +129,19 @@
     }
 
     @Test
+    public void onBindSlice_readsMedia_withBypass_notDozing() {
+        MediaMetadata metadata = mock(MediaMetadata.class);
+        when(metadata.getText(any())).thenReturn("metadata");
+        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+        when(mDozeParameters.getAlwaysOn()).thenReturn(true);
+        mProvider.onMetadataOrStateChanged(metadata, PlaybackState.STATE_PLAYING);
+        mProvider.onBindSlice(mProvider.getUri());
+        verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_TITLE));
+        verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_ARTIST));
+        verify(mNotificationMediaManager).getMediaIcon();
+    }
+
+    @Test
     public void cleansDateFormat() {
         mProvider.mKeyguardUpdateMonitorCallback.onTimeZoneChanged(null);
         TestableLooper.get(this).processAllMessages();
@@ -194,6 +222,20 @@
         verify(mContentResolver, never()).notifyChange(eq(mProvider.getUri()), eq(null));
     }
 
+    @Test
+    public void onDestroy_noCrash() {
+        mProvider.onDestroy();
+    }
+
+    @Test
+    public void onDestroy_unregisterListeners() {
+        mProvider.registerClockUpdate();
+        mProvider.onDestroy();
+        verify(mMediaWakeLock).setAcquired(eq(false));
+        verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
+        verify(mKeyguardUpdateMonitor).removeCallback(any());
+    }
+
     private class TestableKeyguardSliceProvider extends KeyguardSliceProvider {
         int mCleanDateFormatInvokations;
         private int mCounter;
@@ -207,6 +249,8 @@
             super.onCreateSliceProvider();
             mAlarmManager = KeyguardSliceProviderTest.this.mAlarmManager;
             mContentResolver = KeyguardSliceProviderTest.this.mContentResolver;
+            mZenModeController = KeyguardSliceProviderTest.this.mZenModeController;
+            mMediaWakeLock = KeyguardSliceProviderTest.this.mMediaWakeLock;
             return true;
         }
 
@@ -223,7 +267,7 @@
 
         @Override
         public KeyguardUpdateMonitor getKeyguardUpdateMonitor() {
-            return mock(KeyguardUpdateMonitor.class);
+            return mKeyguardUpdateMonitor;
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
index 99fc509..462c82e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
@@ -44,6 +44,7 @@
 import org.junit.Assert.assertThat
 import org.junit.Assert.assertTrue
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
@@ -69,6 +70,7 @@
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
 @RunWithLooper
+@Ignore
 class PrivacyItemControllerTest : SysuiTestCase() {
 
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index db4f5ff..4eee230 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -39,6 +39,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiBaseFragmentTest;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.qs.tileimpl.QSFactoryImpl;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.AutoTileManager;
@@ -139,6 +140,7 @@
                 new RemoteInputQuickSettingsDisabler(context, mock(ConfigurationController.class)),
                 new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()),
                 context,
-                mock(QSTileHost.class));
+                mock(QSTileHost.class),
+                mock(StatusBarStateController.class));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index f73472f..f2292fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -18,23 +18,28 @@
 
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
 import static junit.framework.TestCase.assertFalse;
 
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
 import android.os.Looper;
+import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.util.CollectionUtils;
 import com.android.systemui.DumpController;
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.qs.QSTile;
@@ -108,7 +113,6 @@
                             return null;
                     }
                 });
-
     }
 
     @Test
@@ -124,6 +128,26 @@
     }
 
     @Test
+    public void testInvalidSpecUsesDefault() {
+        mContext.getOrCreateTestableResources()
+                .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
+        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "not-valid");
+
+        assertEquals(2, mQSTileHost.getTiles().size());
+    }
+
+    @Test
+    public void testSpecWithInvalidDoesNotUseDefault() {
+        mContext.getOrCreateTestableResources()
+                .addOverride(R.string.quick_settings_tiles, "spec1,spec2");
+        mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec2,not-valid");
+
+        assertEquals(1, mQSTileHost.getTiles().size());
+        QSTile element = CollectionUtils.firstOrNull(mQSTileHost.getTiles());
+        assertTrue(element instanceof TestTile2);
+    }
+
+    @Test
     public void testDump() {
         mQSTileHost.onTuningChanged(QSTileHost.TILES_SETTING, "spec1,spec2");
         StringWriter w = new StringWriter();
@@ -153,6 +177,21 @@
         @Override
         public void onPluginDisconnected(QSFactory plugin) {
         }
+
+        @Override
+        public void changeTiles(List<String> previousTiles, List<String> newTiles) {
+            String previousSetting = Settings.Secure.getStringForUser(
+                    getContext().getContentResolver(), TILES_SETTING,
+                    ActivityManager.getCurrentUser());
+            super.changeTiles(previousTiles, newTiles);
+            // After tiles are changed, make sure to call onTuningChanged with the new setting if it
+            // changed
+            String newSetting = Settings.Secure.getStringForUser(getContext().getContentResolver(),
+                    TILES_SETTING, ActivityManager.getCurrentUser());
+            if (!previousSetting.equals(newSetting)) {
+                onTuningChanged(TILES_SETTING, newSetting);
+            }
+        }
     }
 
     private class TestTile extends QSTileImpl<QSTile.State> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index 5c1f473..881cc39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -64,7 +64,7 @@
     protected static final int TEST_AUTO_DISMISS_TIME = 500;
     // Number of notifications to use in tests requiring multiple notifications
     private static final int TEST_NUM_NOTIFICATIONS = 4;
-    protected static final int TEST_TIMEOUT_TIME = 10000;
+    protected static final int TEST_TIMEOUT_TIME = 15000;
     protected final Runnable TEST_TIMEOUT_RUNNABLE = () -> mTimedOut = true;
 
     private AlertingNotificationManager mAlertingNotificationManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java
deleted file mode 100644
index 0b25a7c..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java
+++ /dev/null
@@ -1,79 +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;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class AmbientPulseManagerTest extends AlertingNotificationManagerTest {
-    @Rule
-    public MockitoRule rule = MockitoJUnit.rule();
-
-    private static final int TEST_EXTENSION_TIME = 500;
-    private AmbientPulseManager mAmbientPulseManager;
-    private boolean mLivesPastNormalTime;
-
-    protected AlertingNotificationManager createAlertingNotificationManager() {
-        return mAmbientPulseManager;
-    }
-
-    @Before
-    public void setUp() {
-        mAmbientPulseManager = new AmbientPulseManager(mContext);
-        mAmbientPulseManager.mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
-        mAmbientPulseManager.mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
-        mAmbientPulseManager.mExtensionTime = TEST_EXTENSION_TIME;
-        super.setUp();
-        mAmbientPulseManager.mHandler = mTestHandler;
-    }
-
-    @Test
-    public void testExtendPulse() {
-        mAmbientPulseManager.showNotification(mEntry);
-        Runnable pastNormalTimeRunnable =
-                () -> mLivesPastNormalTime = mAmbientPulseManager.isAlerting(mEntry.key);
-        mTestHandler.postDelayed(pastNormalTimeRunnable,
-                mAmbientPulseManager.mAutoDismissNotificationDecay +
-                        mAmbientPulseManager.mExtensionTime / 2);
-        mTestHandler.postDelayed(TEST_TIMEOUT_RUNNABLE, TEST_TIMEOUT_TIME);
-
-        mAmbientPulseManager.extendPulse();
-
-        // Wait for normal time runnable and extended remove runnable and process them on arrival.
-        TestableLooper.get(this).processMessages(2);
-
-        assertFalse("Test timed out", mTimedOut);
-        assertTrue("Pulse was not extended", mLivesPastNormalTime);
-        assertFalse(mAmbientPulseManager.isAlerting(mEntry.key));
-    }
-}
-
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index b81e048..da25eed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -1,3 +1,4 @@
+
 package com.android.systemui.statusbar;
 
 import static junit.framework.Assert.assertEquals;
@@ -22,12 +23,14 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputActiveExtender;
 import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputHistoryExtender;
 import com.android.systemui.statusbar.NotificationRemoteInputManager.SmartReplyHistoryExtender;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ShadeController;
 
 import com.google.android.collect.Sets;
@@ -54,6 +57,7 @@
     @Mock private SmartReplyController mSmartReplyController;
     @Mock private NotificationListenerService.RankingMap mRanking;
     @Mock private ExpandableNotificationRow mRow;
+    @Mock private StatusBarStateController mStateController;
 
     // Dependency mocks:
     @Mock private NotificationEntryManager mEntryManager;
@@ -73,6 +77,7 @@
         mRemoteInputManager = new TestableNotificationRemoteInputManager(mContext,
                 mLockscreenUserManager, mSmartReplyController, mEntryManager,
                 () -> mock(ShadeController.class),
+                mStateController,
                 Handler.createAsync(Looper.myLooper()));
         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
                 0, new Notification(), UserHandle.CURRENT, null, 0);
@@ -196,15 +201,15 @@
 
     private class TestableNotificationRemoteInputManager extends NotificationRemoteInputManager {
 
-
         TestableNotificationRemoteInputManager(Context context,
                 NotificationLockscreenUserManager lockscreenUserManager,
                 SmartReplyController smartReplyController,
                 NotificationEntryManager notificationEntryManager,
                 Lazy<ShadeController> shadeController,
+                StatusBarStateController statusBarStateController,
                 Handler mainHandler) {
             super(context, lockscreenUserManager, smartReplyController, notificationEntryManager,
-                    shadeController, mainHandler);
+                    shadeController, statusBarStateController, mainHandler);
         }
 
         public void setUpWithPresenterForTest(Callback callback,
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 028fd7a..7063ddf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -20,6 +20,8 @@
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 
+import static org.mockito.Mockito.mock;
+
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.Instrumentation;
@@ -40,11 +42,13 @@
 
 import com.android.systemui.R;
 import com.android.systemui.bubbles.BubblesTestActivity;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
 import com.android.systemui.statusbar.notification.row.NotificationContentInflaterTest;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
@@ -66,14 +70,18 @@
     private final Context mContext;
     private final Instrumentation mInstrumentation;
     private int mId;
-    private final NotificationGroupManager mGroupManager = new NotificationGroupManager();
+    private final NotificationGroupManager mGroupManager;
     private ExpandableNotificationRow mRow;
-    private HeadsUpManager mHeadsUpManager;
+    private HeadsUpManagerPhone mHeadsUpManager;
 
     public NotificationTestHelper(Context context) {
         mContext = context;
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
-        mHeadsUpManager = new HeadsUpManagerPhone(mContext, null, mGroupManager, null, null);
+        StatusBarStateController stateController = mock(StatusBarStateController.class);
+        mGroupManager = new NotificationGroupManager(stateController);
+        mHeadsUpManager = new HeadsUpManagerPhone(mContext, stateController,
+                mock(KeyguardBypassController.class));
+        mHeadsUpManager.setUp(null, mGroupManager, null, null);
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index c476d80..58fb53a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -20,12 +20,16 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.os.Handler;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.View;
@@ -48,6 +52,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.util.Assert;
@@ -78,13 +83,19 @@
     @Mock private VisualStabilityManager mVisualStabilityManager;
     @Mock private ShadeController mShadeController;
 
+    private TestableLooper mTestableLooper;
+    private Handler mHandler;
     private NotificationViewHierarchyManager mViewHierarchyManager;
     private NotificationTestHelper mHelper;
+    private boolean mMadeReentrantCall = false;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        Assert.sMainLooper = TestableLooper.get(this).getLooper();
+        mTestableLooper = TestableLooper.get(this);
+        Assert.sMainLooper = mTestableLooper.getLooper();
+        mHandler = Handler.createAsync(mTestableLooper.getLooper());
+
         mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
         mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
                 mLockscreenUserManager);
@@ -97,9 +108,11 @@
         when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
 
         mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
-                mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
+                mHandler, mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
                 mock(StatusBarStateControllerImpl.class), mEntryManager,
-                () -> mShadeController, new BubbleData(mContext), mock(DynamicPrivacyController.class));
+                () -> mShadeController, new BubbleData(mContext),
+                mock(KeyguardBypassController.class),
+                mock(DynamicPrivacyController.class));
         Dependency.get(InitController.class).executePostInitTasks();
         mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
     }
@@ -212,9 +225,60 @@
         verify(entry0.getRow(), times(1)).showAppOpsIcons(any());
     }
 
+    @Test
+    public void testReentrantCallsToOnDynamicPrivacyChangedPostForLater() {
+        // GIVEN a ListContainer that will make a re-entrant call to updateNotificationViews()
+        mMadeReentrantCall = false;
+        doAnswer((invocation) -> {
+            if (!mMadeReentrantCall) {
+                mMadeReentrantCall = true;
+                mViewHierarchyManager.onDynamicPrivacyChanged();
+            }
+            return null;
+        }).when(mListContainer).setMaxDisplayedNotifications(anyInt());
+
+        // WHEN we call updateNotificationViews()
+        mViewHierarchyManager.updateNotificationViews();
+
+        // THEN onNotificationViewUpdateFinished() is only called once
+        verify(mListContainer).onNotificationViewUpdateFinished();
+
+        // WHEN we drain the looper
+        mTestableLooper.processAllMessages();
+
+        // THEN updateNotificationViews() is called a second time (for the reentrant call)
+        verify(mListContainer, times(2)).onNotificationViewUpdateFinished();
+    }
+
+    @Test
+    public void testMultipleReentrantCallsToOnDynamicPrivacyChangedOnlyPostOnce() {
+        // GIVEN a ListContainer that will make many re-entrant calls to updateNotificationViews()
+        mMadeReentrantCall = false;
+        doAnswer((invocation) -> {
+            if (!mMadeReentrantCall) {
+                mMadeReentrantCall = true;
+                mViewHierarchyManager.onDynamicPrivacyChanged();
+                mViewHierarchyManager.onDynamicPrivacyChanged();
+                mViewHierarchyManager.onDynamicPrivacyChanged();
+                mViewHierarchyManager.onDynamicPrivacyChanged();
+            }
+            return null;
+        }).when(mListContainer).setMaxDisplayedNotifications(anyInt());
+
+        // WHEN we call updateNotificationViews() and drain the looper
+        mViewHierarchyManager.updateNotificationViews();
+        verify(mListContainer).onNotificationViewUpdateFinished();
+        clearInvocations(mListContainer);
+        mTestableLooper.processAllMessages();
+
+        // THEN updateNotificationViews() is called only one more time
+        verify(mListContainer).onNotificationViewUpdateFinished();
+    }
+
     private class FakeListContainer implements NotificationListContainer {
         final LinearLayout mLayout = new LinearLayout(mContext);
         final List<View> mRows = Lists.newArrayList();
+        private boolean mMakeReentrantCallDuringSetMaxDisplayedNotifications;
 
         @Override
         public void setChildTransferInProgress(boolean childTransferInProgress) {}
@@ -263,7 +327,11 @@
         }
 
         @Override
-        public void setMaxDisplayedNotifications(int maxNotifications) {}
+        public void setMaxDisplayedNotifications(int maxNotifications) {
+            if (mMakeReentrantCallDuringSetMaxDisplayedNotifications) {
+                mViewHierarchyManager.onDynamicPrivacyChanged();
+            }
+        }
 
         @Override
         public ViewGroup getViewParentForNotification(NotificationEntry entry) {
@@ -298,5 +366,7 @@
             return false;
         }
 
+        @Override
+        public void onNotificationViewUpdateFinished() { }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index 81e373a..185723f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -38,6 +38,7 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.phone.ShadeController;
@@ -70,6 +71,7 @@
     @Mock private StatusBarNotification mSbn;
     @Mock private NotificationEntryManager mNotificationEntryManager;
     @Mock private IStatusBarService mIStatusBarService;
+    @Mock private StatusBarStateController mStatusBarStateController;
 
     @Before
     public void setUp() {
@@ -85,6 +87,7 @@
         mRemoteInputManager = new NotificationRemoteInputManager(mContext,
                 mock(NotificationLockscreenUserManager.class), mSmartReplyController,
                 mNotificationEntryManager, () -> mock(ShadeController.class),
+                mStatusBarStateController,
                 Handler.createAsync(Looper.myLooper()));
         mRemoteInputManager.setUpWithCallback(mCallback, mDelegate);
         mNotification = new Notification.Builder(mContext, "")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 72f3a62..2ca1b06 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -64,6 +64,7 @@
 import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationLifetimeExtender;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -83,6 +84,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.row.RowInflaterTask;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -247,7 +249,8 @@
         mEntryManager.setNotificationRemoveInterceptor(mRemoveInterceptor);
 
         NotificationRowBinderImpl notificationRowBinder =
-                new NotificationRowBinderImpl(mContext, true /* allowLongPress */);
+                new NotificationRowBinderImpl(mContext, true, /* allowLongPress */
+                        mock(KeyguardBypassController.class), mock(StatusBarStateController.class));
         notificationRowBinder.setUpWithPresenter(
                 mPresenter, mListContainer, mHeadsUpManager, mEntryManager, mBindCallback);
         notificationRowBinder.setNotificationClicker(mock(NotificationClicker.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
index 91a7ea8..6f7751b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
@@ -40,6 +40,7 @@
 
 import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.collection.NotificationData;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -90,7 +91,7 @@
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
         mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
         mDependency.injectTestDependency(NotificationGroupManager.class,
-                new NotificationGroupManager());
+                new NotificationGroupManager(mock(StatusBarStateController.class)));
         mDependency.injectMockDependency(ShadeController.class);
         mDependency.injectTestDependency(NotificationData.KeyguardEnvironment.class, mEnvironment);
         when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
index b35dcb6..dd2630b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
@@ -16,17 +16,20 @@
 
 package com.android.systemui.statusbar.notification;
 
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.Matchers.anyObject;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.os.Handler;
 import android.service.notification.StatusBarNotification;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
 
-import androidx.test.runner.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationPresenter;
@@ -38,11 +41,13 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper()
 public class VisualStabilityManagerTest extends SysuiTestCase {
 
-    private VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager(
-            mock(NotificationEntryManager.class));
+    private TestableLooper mTestableLooper;
+
+    private VisualStabilityManager mVisualStabilityManager;
     private VisualStabilityManager.Callback mCallback = mock(VisualStabilityManager.Callback.class);
     private VisibilityLocationProvider mLocationProvider = mock(VisibilityLocationProvider.class);
     private ExpandableNotificationRow mRow = mock(ExpandableNotificationRow.class);
@@ -50,46 +55,53 @@
 
     @Before
     public void setUp() {
+        mTestableLooper = TestableLooper.get(this);
+        mVisualStabilityManager = new VisualStabilityManager(
+                mock(NotificationEntryManager.class),
+                new Handler(mTestableLooper.getLooper()));
+
         mVisualStabilityManager.setUpWithPresenter(mock(NotificationPresenter.class));
         mVisualStabilityManager.setVisibilityLocationProvider(mLocationProvider);
         mEntry = new NotificationEntry(mock(StatusBarNotification.class));
         mEntry.setRow(mRow);
+
+        when(mRow.getEntry()).thenReturn(mEntry);
     }
 
     @Test
     public void testPanelExpansion() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
         mVisualStabilityManager.setPanelExpanded(false);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testScreenOn() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
         mVisualStabilityManager.setScreenOn(false);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingAllowedChangesScreenOn() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), false);
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
         mVisualStabilityManager.setScreenOn(false);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), true);
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
     }
 
     @Test
     public void testReorderingAllowedChangesPanel() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), false);
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
         mVisualStabilityManager.setPanelExpanded(false);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), true);
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
     }
 
     @Test
@@ -126,51 +138,51 @@
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
         mVisualStabilityManager.notifyViewAddition(mRow);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingVisibleHeadsUpNotAllowed() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        when(mLocationProvider.isInVisibleLocation(anyObject())).thenReturn(true);
+        when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(true);
         mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingVisibleHeadsUpAllowed() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        when(mLocationProvider.isInVisibleLocation(anyObject())).thenReturn(false);
+        when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(false);
         mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingVisibleHeadsUpAllowedOnce() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        when(mLocationProvider.isInVisibleLocation(anyObject())).thenReturn(false);
+        when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(false);
         mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
         mVisualStabilityManager.onReorderingFinished();
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testPulsing() {
         mVisualStabilityManager.setPulsing(true);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), false);
+        assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
         mVisualStabilityManager.setPulsing(false);
-        assertEquals(mVisualStabilityManager.canReorderNotification(mRow), true);
+        assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
     }
 
     @Test
     public void testReorderingAllowedChanges_Pulsing() {
         mVisualStabilityManager.setPulsing(true);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), false);
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
         mVisualStabilityManager.setPulsing(false);
-        assertEquals(mVisualStabilityManager.isReorderingAllowed(), true);
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
     }
 
     @Test
@@ -180,4 +192,49 @@
         mVisualStabilityManager.setPulsing(false);
         verify(mCallback).onReorderingAllowed();
     }
+
+    @Test
+    public void testTemporarilyAllowReorderingNotifiesCallbacks() {
+        // GIVEN having the panel open (which would block reordering)
+        mVisualStabilityManager.setScreenOn(true);
+        mVisualStabilityManager.setPanelExpanded(true);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+
+        // WHEN we temprarily allow reordering
+        mVisualStabilityManager.temporarilyAllowReordering();
+
+        // THEN callbacks are notified that reordering is allowed
+        verify(mCallback).onReorderingAllowed();
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
+    }
+
+    @Test
+    public void testTemporarilyAllowReorderingDoesntOverridePulsing() {
+        // GIVEN we are in a pulsing state
+        mVisualStabilityManager.setPulsing(true);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+
+        // WHEN we temprarily allow reordering
+        mVisualStabilityManager.temporarilyAllowReordering();
+
+        // THEN reordering is still not allowed
+        verify(mCallback, never()).onReorderingAllowed();
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
+    }
+
+    @Test
+    public void testTemporarilyAllowReorderingExpires() {
+        // GIVEN having the panel open (which would block reordering)
+        mVisualStabilityManager.setScreenOn(true);
+        mVisualStabilityManager.setPanelExpanded(true);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+
+        // WHEN we temprarily allow reordering and then wait until the window expires
+        mVisualStabilityManager.temporarilyAllowReordering();
+        assertTrue(mVisualStabilityManager.isReorderingAllowed());
+        mTestableLooper.processMessages(1);
+
+        // THEN reordering is no longer allowed
+        assertFalse(mVisualStabilityManager.isReorderingAllowed());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index 6e0ddbf..260555f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -66,6 +66,7 @@
 import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.InitController;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.collection.NotificationData.KeyguardEnvironment;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -125,7 +126,7 @@
 
         mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
         mDependency.injectTestDependency(NotificationGroupManager.class,
-                new NotificationGroupManager());
+                new NotificationGroupManager(mock(StatusBarStateController.class)));
         mDependency.injectMockDependency(ShadeController.class);
         mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
         when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
index 7632630..8b81a7a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
@@ -109,7 +109,7 @@
     }
 
     @Test
-    fun testPrepareDialogForApp_retrievesUpto4Channels() {
+    fun testPrepareDialogForApp_retrievesUpTo4Channels() {
         val channel3 = NotificationChannel("test_channel_3", "Test channel 3", IMPORTANCE_DEFAULT)
         val channel4 = NotificationChannel("test_channel_4", "Test channel 4", IMPORTANCE_DEFAULT)
 
@@ -169,6 +169,16 @@
                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(true))
     }
 
+    @Test
+    fun testSettingsClickListenerNull_noCrash() {
+        group.channels = listOf(channel1, channel2)
+        controller.prepareDialogForApp(TEST_APP_NAME, TEST_PACKAGE_NAME, TEST_UID,
+                setOf(channel1, channel2), appIcon, null)
+
+        // Pass in any old view, it should never actually be used
+        controller.launchSettings(View(context))
+    }
+
     private val clickListener = object : NotificationInfo.OnSettingsClickListener {
         override fun onClick(v: View, c: NotificationChannel, appUid: Int) {
         }
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 8077e3f..d526d10 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,9 +37,7 @@
 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;
@@ -51,6 +49,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
@@ -138,13 +137,6 @@
     }
 
     @Test
-    public void testIconColorShouldBeUpdatedWhenSettingDark() throws Exception {
-        ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow());
-        row.setDark(true, false, 0);
-        verify(row).updateShelfIconColor();
-    }
-
-    @Test
     public void testFreeContentViewWhenSafe() throws Exception {
         ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
 
@@ -212,7 +204,9 @@
     @Test
     public void testClickSound() throws Exception {
         assertTrue("Should play sounds by default.", mGroupRow.isSoundEffectsEnabled());
-        mGroupRow.setDark(true /* dark */, false /* fade */, 0 /* delay */);
+        StatusBarStateController mock = mock(StatusBarStateController.class);
+        when(mock.isDozing()).thenReturn(true);
+        mGroupRow.setStatusBarStateController(mock);
         mGroupRow.setSecureStateProvider(()-> false);
         assertFalse("Shouldn't play sounds when dark and trusted.",
                 mGroupRow.isSoundEffectsEnabled());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 025296d..2ec125e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification.row;
 
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_ALL;
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_EXPANDED;
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
 import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_PUBLIC;
@@ -101,7 +100,7 @@
         mNotificationInflater.setUsesIncreasedHeadsUpHeight(true);
         Notification.Builder builder = spy(mBuilder);
         mNotificationInflater.inflateNotificationViews(
-                false /* inflateSynchronously */,
+                true /* inflateSynchronously */,
                 FLAG_CONTENT_VIEW_ALL,
                 builder,
                 mContext);
@@ -113,7 +112,7 @@
         mNotificationInflater.setUsesIncreasedHeight(true);
         Notification.Builder builder = spy(mBuilder);
         mNotificationInflater.inflateNotificationViews(
-                false /* inflateSynchronously */,
+                true /* inflateSynchronously */,
                 FLAG_CONTENT_VIEW_ALL,
                 builder,
                 mContext);
@@ -135,7 +134,6 @@
                 mNotificationInflater);
 
         assertNotNull(mRow.getPrivateLayout().getHeadsUpChild());
-        assertNull(mRow.getShowingLayout().getAmbientChild());
         verify(mRow).onNotificationUpdated();
     }
 
@@ -161,6 +159,7 @@
     @Test
     public void testRemovedNotInflated() throws Exception {
         mRow.setRemoved();
+        mNotificationInflater.setInflateSynchronously(true);
         mNotificationInflater.inflateNotificationViews();
         Assert.assertNull(mRow.getEntry().getRunningTask());
     }
@@ -177,7 +176,7 @@
                 result,
                 FLAG_CONTENT_VIEW_EXPANDED,
                 0,
-                new ArrayMap() /* cachedContentViews */, mRow, false /* redactAmbient */,
+                new ArrayMap() /* cachedContentViews */, mRow,
                 true /* isNewView */, (v, p, r) -> true,
                 new InflationCallback() {
                     @Override
@@ -209,14 +208,12 @@
 
     @Test
     public void testUpdateNeedsRedactionReinflatesChangedContentViews() {
-        mNotificationInflater.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, true);
         mNotificationInflater.updateInflationFlag(FLAG_CONTENT_VIEW_PUBLIC, true);
         mNotificationInflater.updateNeedsRedaction(true);
 
         NotificationContentInflater.AsyncInflationTask asyncInflationTask =
                 (NotificationContentInflater.AsyncInflationTask) mRow.getEntry().getRunningTask();
-        assertEquals(FLAG_CONTENT_VIEW_AMBIENT | FLAG_CONTENT_VIEW_PUBLIC,
-                asyncInflationTask.getReInflateFlags());
+        assertEquals(FLAG_CONTENT_VIEW_PUBLIC, asyncInflationTask.getReInflateFlags());
         asyncInflationTask.abort();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
index 5cd0ca7..675b3ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
@@ -50,8 +50,6 @@
 
     NotificationContentView mView;
 
-    private Icon mActionIcon;
-
     @Before
     @UiThreadTest
     public void setup() {
@@ -62,12 +60,11 @@
         doReturn(10).when(mockRow).getIntrinsicHeight();
 
         mView.setContainingNotification(mockRow);
-        mView.setHeights(10, 20, 30, 40);
+        mView.setHeights(10, 20, 30);
 
         mView.setContractedChild(createViewWithHeight(10));
         mView.setExpandedChild(createViewWithHeight(20));
         mView.setHeadsUpChild(createViewWithHeight(30));
-        mView.setAmbientChild(createViewWithHeight(40));
 
         mView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
         mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
@@ -81,16 +78,6 @@
 
     @Test
     @UiThreadTest
-    public void animationStartType_getsClearedAfterUpdatingVisibilitiesWithoutAnimation() {
-        mView.setHeadsUp(true);
-        mView.setDark(true, false, 0);
-        mView.setDark(false, true, 0);
-        mView.setHeadsUpAnimatingAway(true);
-        assertFalse(mView.isAnimatingVisibleType());
-    }
-
-    @Test
-    @UiThreadTest
     public void testShowAppOpsIcons() {
         NotificationHeaderView mockContracted = mock(NotificationHeaderView.class);
         when(mockContracted.findViewById(com.android.internal.R.id.notification_header))
@@ -101,14 +88,10 @@
         NotificationHeaderView mockHeadsUp = mock(NotificationHeaderView.class);
         when(mockHeadsUp.findViewById(com.android.internal.R.id.notification_header))
                 .thenReturn(mockHeadsUp);
-        NotificationHeaderView mockAmbient = mock(NotificationHeaderView.class);
-        when(mockAmbient.findViewById(com.android.internal.R.id.notification_header))
-                .thenReturn(mockAmbient);
 
         mView.setContractedChild(mockContracted);
         mView.setExpandedChild(mockExpanded);
         mView.setHeadsUpChild(mockHeadsUp);
-        mView.setAmbientChild(mockAmbient);
 
         ArraySet<Integer> ops = new ArraySet<>();
         ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
@@ -116,7 +99,6 @@
 
         verify(mockContracted, times(1)).showAppOpsIcons(ops);
         verify(mockExpanded, times(1)).showAppOpsIcons(ops);
-        verify(mockAmbient, never()).showAppOpsIcons(ops);
         verify(mockHeadsUp, times(1)).showAppOpsIcons(any());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 6376bd3..7959484 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -63,9 +63,11 @@
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.util.Assert;
 
@@ -97,12 +99,14 @@
 
     @Rule public MockitoRule mockito = MockitoJUnit.rule();
     @Mock private MetricsLogger mMetricsLogger;
+    @Mock private VisualStabilityManager mVisualStabilityManager;
     @Mock private NotificationPresenter mPresenter;
     @Mock private NotificationActivityStarter mNotificationActivityStarter;
     @Mock private NotificationStackScrollLayout mStackScroller;
     @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener;
     @Mock private OnSettingsClickListener mOnSettingsClickListener;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
+    @Mock private StatusBar mStatusBar;
 
     @Before
     public void setUp() {
@@ -111,11 +115,12 @@
         mDependency.injectTestDependency(DeviceProvisionedController.class,
                 mDeviceProvisionedController);
         mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
+        mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
         mHandler = Handler.createAsync(mTestableLooper.getLooper());
-
+        mContext.putComponent(StatusBar.class, mStatusBar);
         mHelper = new NotificationTestHelper(mContext);
 
-        mGutsManager = new NotificationGutsManager(mContext);
+        mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager);
         mGutsManager.setUpWithPresenter(mPresenter, mStackScroller,
                 mCheckSaveListener, mOnSettingsClickListener);
         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
@@ -147,7 +152,7 @@
         when(row.getWindowToken()).thenReturn(new Binder());
         when(row.getGuts()).thenReturn(guts);
 
-        assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem));
+        assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem));
         assertEquals(View.INVISIBLE, guts.getVisibility());
         mTestableLooper.processAllMessages();
         verify(guts).openControls(
@@ -195,7 +200,7 @@
         when(entry.getRow()).thenReturn(row);
         when(entry.getGuts()).thenReturn(guts);
 
-        assertTrue(mGutsManager.openGuts(row, 0, 0, menuItem));
+        assertTrue(mGutsManager.openGutsInternal(row, 0, 0, menuItem));
         mTestableLooper.processAllMessages();
         verify(guts).openControls(
                 eq(true),
@@ -316,6 +321,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
@@ -344,6 +350,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
@@ -374,6 +381,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
@@ -403,6 +411,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
@@ -431,6 +440,7 @@
         verify(notificationInfoView).bindNotification(
                 any(PackageManager.class),
                 any(INotificationManager.class),
+                eq(mVisualStabilityManager),
                 eq(statusBarNotification.getPackageName()),
                 any(NotificationChannel.class),
                 anySet(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 06acc73..703adf7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -72,6 +72,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
 
 import org.junit.After;
 import org.junit.Before;
@@ -116,6 +117,8 @@
     private PackageManager mMockPackageManager;
     @Mock
     private NotificationBlockingHelperManager mBlockingHelperManager;
+    @Mock
+    private VisualStabilityManager mVisualStabilityManager;
 
     @Before
     public void setUp() throws Exception {
@@ -193,11 +196,21 @@
     @Test
     public void testBindNotification_SetsTextApplicationName() throws Exception {
         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null,
-                true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.pkgname);
         assertTrue(textView.getText().toString().contains("App Name"));
         assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
@@ -208,20 +221,42 @@
         final Drawable iconDrawable = mock(Drawable.class);
         when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
                 .thenReturn(iconDrawable);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final ImageView iconView = mNotificationInfo.findViewById(R.id.pkgicon);
         assertEquals(iconDrawable, iconView.getDrawable());
     }
 
     @Test
     public void testBindNotification_noDelegate() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
         assertEquals(GONE, nameView.getVisibility());
         final TextView dividerView = mNotificationInfo.findViewById(R.id.pkg_divider);
@@ -238,10 +273,21 @@
                 applicationInfo);
         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("Other");
 
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
         assertEquals(VISIBLE, nameView.getVisibility());
         assertTrue(nameView.getText().toString().contains("Proxied"));
@@ -251,10 +297,21 @@
 
     @Test
     public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(GONE, groupNameView.getVisibility());
     }
@@ -267,10 +324,21 @@
         when(mMockINotificationManager.getNotificationChannelGroupForPackage(
                 eq("test_group_id"), eq(TEST_PACKAGE_NAME), eq(TEST_UID)))
                 .thenReturn(notificationChannelGroup);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
         assertEquals(View.VISIBLE, groupNameView.getVisibility());
         assertEquals("Test Group Name", groupNameView.getText());
@@ -278,19 +346,42 @@
 
     @Test
     public void testBindNotification_SetsTextChannelName() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(TEST_CHANNEL_NAME, textView.getText());
     }
 
     @Test
     public void testBindNotification_DefaultChannelDoesNotUseChannelName() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mDefaultNotificationChannel, mDefaultNotificationChannelSet,
-                mSbn, null, null, null, true, false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mDefaultNotificationChannel,
+                mDefaultNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(GONE, textView.getVisibility());
     }
@@ -301,30 +392,64 @@
         // Package has one channel by default.
         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
                 eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(10);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mDefaultNotificationChannel, mDefaultNotificationChannelSet,
-                mSbn, null, null, null, true,
-                false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mDefaultNotificationChannel,
+                mDefaultNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(VISIBLE, textView.getVisibility());
     }
 
     @Test
     public void testBindNotification_UnblockablePackageUsesChannelName() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, true,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(VISIBLE, textView.getVisibility());
     }
 
     @Test
     public void testBindNotification_BlockLink_BlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, mock(
-                        NotificationInfo.OnSettingsClickListener.class), null, true, false,
-                true /* isBlockingHelper */, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                mock(NotificationInfo.OnSettingsClickListener.class),
+                null,
+                true,
+                false,
+                true /* isBlockingHelper */,
+                IMPORTANCE_DEFAULT,
+                true);
         final View block =
                 mNotificationInfo.findViewById(R.id.blocking_helper_turn_off_notifications);
         final View interruptivenessSettings = mNotificationInfo.findViewById(
@@ -336,12 +461,24 @@
     @Test
     public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
                 (View v, NotificationChannel c, int appUid) -> {
                     assertEquals(mNotificationChannel, c);
                     latch.countDown();
-                }, null, true, false, IMPORTANCE_DEFAULT, true);
+                },
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
 
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         settingsButton.performClick();
@@ -351,10 +488,21 @@
 
     @Test
     public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
     }
@@ -362,36 +510,80 @@
     @Test
     public void testBindNotification_SettingsButtonInvisibleWhenDeviceUnprovisioned()
             throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
                 (View v, NotificationChannel c, int appUid) -> {
                     assertEquals(mNotificationChannel, c);
-                }, null, false, false, IMPORTANCE_DEFAULT, true);
+                },
+                null,
+                false,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertTrue(settingsButton.getVisibility() != View.VISIBLE);
     }
 
     @Test
     public void testBindNotification_SettingsButtonReappearsAfterSecondBind() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null,
-                (View v, NotificationChannel c, int appUid) -> {
-                }, null, true, false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                (View v, NotificationChannel c, int appUid) -> { },
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final View settingsButton = mNotificationInfo.findViewById(R.id.info);
         assertEquals(View.VISIBLE, settingsButton.getVisibility());
     }
 
     @Test
     public void testBindNotificationLogging_notBlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null,
-                true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         verify(mMetricsLogger).write(argThat(logMaker ->
                 logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
                         && logMaker.getType() == MetricsEvent.TYPE_OPEN
@@ -401,12 +593,22 @@
 
     @Test
     public void testBindNotificationLogging_BlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null,
-                false, true,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                false,
                 true,
-                IMPORTANCE_DEFAULT, true);
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
         verify(mMetricsLogger).write(argThat(logMaker ->
                 logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
                         && logMaker.getType() == MetricsEvent.TYPE_OPEN
@@ -416,12 +618,22 @@
 
     @Test
     public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
-                null, null, null,
-                false, true,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                false,
                 true,
-                IMPORTANCE_DEFAULT, true);
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
         mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
         verify(mMetricsLogger).count(eq("HowCanNotifsBeRealIfAppsArent"), eq(1));
     }
@@ -429,13 +641,23 @@
     @Test
     public void testOnClickListenerPassesNullChannelForBundle() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
                 TEST_PACKAGE_NAME, mNotificationChannel,
-                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT), mSbn, null,
+                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
+                mSbn,
+                null,
                 (View v, NotificationChannel c, int appUid) -> {
                     assertEquals(null, c);
                     latch.countDown();
-                }, null, true, true, IMPORTANCE_DEFAULT, true);
+                },
+                null,
+                true,
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.findViewById(R.id.info).performClick();
         // Verify that listener was triggered.
@@ -446,10 +668,21 @@
     @UiThreadTest
     public void testBindNotification_ChannelNameInvisibleWhenBundleFromDifferentChannels()
             throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel,
-                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT), mSbn, null, null,
-                null, true, false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView channelNameView =
                 mNotificationInfo.findViewById(R.id.channel_name);
         assertEquals(GONE, channelNameView.getVisibility());
@@ -458,10 +691,21 @@
     @Test
     @UiThreadTest
     public void testStopInvisibleIfBundleFromDifferentChannels() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel,
-                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT), mSbn, null, null,
-                null, true, false, IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         assertEquals(GONE, mNotificationInfo.findViewById(
                 R.id.interruptiveness_settings).getVisibility());
         assertEquals(VISIBLE, mNotificationInfo.findViewById(
@@ -470,10 +714,21 @@
 
     @Test
     public void testBindNotification_whenAppUnblockable() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, true,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
         final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_text);
         assertEquals(View.VISIBLE, view.getVisibility());
         assertEquals(mContext.getString(R.string.notification_unblockable_desc),
@@ -484,10 +739,21 @@
 
     @Test
     public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
         mTestableLooper.processAllMessages();
         verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
                 anyString(), eq(TEST_UID), any());
@@ -496,10 +762,21 @@
     @Test
     public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
         mTestableLooper.processAllMessages();
@@ -511,10 +788,21 @@
     public void testDoesNotUpdateNotificationChannelAfterImportanceChangedSilenced()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mTestableLooper.processAllMessages();
@@ -526,10 +814,21 @@
     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
             throws Exception {
         int originalImportance = mNotificationChannel.getImportance();
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.handleCloseControls(true, false);
         mTestableLooper.processAllMessages();
@@ -542,10 +841,21 @@
     public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnspecified()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_UNSPECIFIED, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_UNSPECIFIED,
+                true);
 
         mNotificationInfo.handleCloseControls(true, false);
 
@@ -561,13 +871,22 @@
         NotificationInfo.CheckSaveListener listener =
                 mock(NotificationInfo.CheckSaveListener.class);
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
-                createMultipleChannelSet(10) /* numUniqueChannelsInRow */, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel /* notificationChannel */,
+                createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
+                mSbn,
                 listener /* checkSaveListener */,
-                null /* onSettingsClick */, null /* onAppSettingsClick */, true /* provisioned */,
-                false /* isNonblockable */, true /* isForBlockingHelper */,
-                IMPORTANCE_DEFAULT, true);
+                null /* onSettingsClick */,
+                null /* onAppSettingsClick */,
+                true /* provisioned */,
+                false /* isNonblockable */,
+                true /* isForBlockingHelper */,
+                IMPORTANCE_DEFAULT,
+                true);
 
         NotificationGuts guts = spy(new NotificationGuts(mContext, null));
         when(guts.getWindowToken()).thenReturn(mock(IBinder.class));
@@ -591,13 +910,21 @@
         NotificationInfo.CheckSaveListener listener =
                 mock(NotificationInfo.CheckSaveListener.class);
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
-                createMultipleChannelSet(10) /* numUniqueChannelsInRow */, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel /* notificationChannel */,
+                createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
+                mSbn,
                 listener /* checkSaveListener */,
-                null /* onSettingsClick */, null /* onAppSettingsClick */,
-                false /* isNonblockable */, true /* isForBlockingHelper */,
-                true, IMPORTANCE_DEFAULT, true);
+                null /* onSettingsClick */,
+                null /* onAppSettingsClick */,
+                false /* isNonblockable */,
+                true /* isForBlockingHelper */,
+                true, IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.handleCloseControls(true /* save */, false /* force */);
 
@@ -611,14 +938,22 @@
         NotificationInfo.CheckSaveListener listener =
                 mock(NotificationInfo.CheckSaveListener.class);
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
-                createMultipleChannelSet(10) /* numUniqueChannelsInRow */, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel /* notificationChannel */,
+                createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
+                mSbn,
                 listener /* checkSaveListener */,
-                null /* onSettingsClick */, null /* onAppSettingsClick */,
+                null /* onSettingsClick */,
+                null /* onAppSettingsClick */,
                 true /* provisioned */,
-                false /* isNonblockable */, true /* isForBlockingHelper */,
-                IMPORTANCE_DEFAULT, true);
+                false /* isNonblockable */,
+                true /* isForBlockingHelper */,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.findViewById(R.id.deliver_silently).performClick();
         mTestableLooper.processAllMessages();
@@ -631,6 +966,7 @@
         mNotificationInfo.bindNotification(
                 mMockPackageManager,
                 mMockINotificationManager,
+                mVisualStabilityManager,
                 TEST_PACKAGE_NAME,
                 mNotificationChannel,
                 mNotificationChannelSet /* numChannels */,
@@ -641,12 +977,13 @@
                 false /* isNonblockable */,
                 true /* isForBlockingHelper */,
                 true,
-                IMPORTANCE_DEFAULT, true);
+                IMPORTANCE_DEFAULT,
+                true);
         NotificationGuts guts = mock(NotificationGuts.class);
         doCallRealMethod().when(guts).closeControls(anyInt(), anyInt(), anyBoolean(), anyBoolean());
         mNotificationInfo.setGutsParent(guts);
 
-        mNotificationInfo.closeControls(mNotificationInfo);
+        mNotificationInfo.closeControls(mNotificationInfo, true);
 
         verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
     }
@@ -658,6 +995,7 @@
         mNotificationInfo.bindNotification(
                 mMockPackageManager,
                 mMockINotificationManager,
+                mVisualStabilityManager,
                 TEST_PACKAGE_NAME,
                 mNotificationChannel,
                 mNotificationChannelSet /* numChannels */,
@@ -688,10 +1026,21 @@
     @Test
     public void testKeepUpdatesNotificationChannel_blockingHelper() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, true,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                true,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.keep_showing).performClick();
         mNotificationInfo.handleCloseControls(true, false);
@@ -708,10 +1057,21 @@
     @Test
     public void testNoActionsUpdatesNotificationChannel_blockingHelper() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, true,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                true,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.handleCloseControls(true, false);
 
@@ -727,10 +1087,21 @@
     @Test
     public void testSilenceCallsUpdateNotificationChannel() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_DEFAULT, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -749,10 +1120,21 @@
     @Test
     public void testUnSilenceCallsUpdateNotificationChannel() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -772,10 +1154,21 @@
     public void testSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_UNSPECIFIED, true);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_UNSPECIFIED,
+                true);
 
         mNotificationInfo.findViewById(R.id.silence).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -795,10 +1188,21 @@
     public void testSilenceCallsUpdateNotificationChannel_channelImportanceMin()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_MIN);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_MIN, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_MIN,
+                false);
 
         assertEquals(mContext.getString(R.string.inline_done_button),
                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
@@ -821,10 +1225,21 @@
     public void testAlertCallsUpdateNotificationChannel_channelImportanceMin()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_MIN);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_MIN, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_MIN,
+                false);
 
         assertEquals(mContext.getString(R.string.inline_done_button),
                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
@@ -844,13 +1259,50 @@
     }
 
     @Test
+    public void testAdjustImportanceTemporarilyAllowsReordering() throws Exception {
+        mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_DEFAULT,
+                true);
+
+        mNotificationInfo.findViewById(R.id.silence).performClick();
+        mNotificationInfo.findViewById(R.id.done).performClick();
+        mNotificationInfo.handleCloseControls(true, false);
+
+        verify(mVisualStabilityManager).temporarilyAllowReordering();
+    }
+
+    @Test
     public void testDoneText()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         assertEquals(mContext.getString(R.string.inline_done_button),
                 ((TextView) mNotificationInfo.findViewById(R.id.done)).getText());
@@ -866,10 +1318,21 @@
     public void testUnSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
             throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -888,10 +1351,21 @@
     @Test
     public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn, null, null,
-                null, true, false,
-                IMPORTANCE_LOW, false);
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
+                null,
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false);
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
         mNotificationInfo.findViewById(R.id.done).performClick();
@@ -905,11 +1379,23 @@
     @Test
     public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
                 (Runnable saveImportance, StatusBarNotification sbn) -> {
                     saveImportance.run();
-                }, null, null, true, false, IMPORTANCE_LOW, false
+                },
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false
         );
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
@@ -928,11 +1414,23 @@
     @Test
     public void testCloseControls_withoutHittingApply() throws Exception {
         mNotificationChannel.setImportance(IMPORTANCE_LOW);
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
                 (Runnable saveImportance, StatusBarNotification sbn) -> {
                     saveImportance.run();
-                }, null, null, true, false, IMPORTANCE_LOW, false
+                },
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false
         );
 
         mNotificationInfo.findViewById(R.id.alert).performClick();
@@ -944,11 +1442,23 @@
     public void testWillBeRemovedReturnsFalse() throws Exception {
         assertFalse(mNotificationInfo.willBeRemoved());
 
-        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
-                TEST_PACKAGE_NAME, mNotificationChannel, mNotificationChannelSet, mSbn,
+        mNotificationInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mVisualStabilityManager,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mSbn,
                 (Runnable saveImportance, StatusBarNotification sbn) -> {
                     saveImportance.run();
-                }, null, null, true, false, IMPORTANCE_LOW, false
+                },
+                null,
+                null,
+                true,
+                false,
+                IMPORTANCE_LOW,
+                false
         );
 
         assertFalse(mNotificationInfo.willBeRemoved());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
index df41a84..4f844f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
@@ -131,7 +131,7 @@
         ));
 
         // Ensure the callback runs at least once
-        mWrapper.mUpdatePlaybackUi.run();
+        mWrapper.mOnUpdateTimerTick.run();
 
         verify(mMetricsLogger).write(argThat(logMaker ->
                 logMaker.getCategory() == MetricsEvent.MEDIA_NOTIFICATION_SEEKBAR
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index 1b4acd7..524ad85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -30,11 +30,12 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -56,12 +57,14 @@
     private ExpandableNotificationRow mFirst;
     private ExpandableNotificationRow mSecond;
     @Mock
-    private AmbientPulseManager mAmbientPulseManager;
+    private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private KeyguardBypassController mBypassController;
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mRoundnessManager = new NotificationRoundnessManager(mAmbientPulseManager);
+        mRoundnessManager = new NotificationRoundnessManager(mBypassController);
         com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
         NotificationTestHelper testHelper = new NotificationTestHelper(getContext());
         mFirst = testHelper.createRow();
@@ -147,11 +150,15 @@
         NotificationEntry entry = mock(NotificationEntry.class);
         when(entry.getRow()).thenReturn(row);
 
-        mRoundnessManager.onAmbientStateChanged(entry, true);
+        when(mStatusBarStateController.isDozing()).thenReturn(true);
+        row.setStatusBarStateController(mStatusBarStateController);
+        row.setHeadsUp(true);
+        mRoundnessManager.onHeadsUpStateChanged(entry, true);
         Assert.assertEquals(1f, row.getCurrentBottomRoundness(), 0.0f);
         Assert.assertEquals(1f, row.getCurrentTopRoundness(), 0.0f);
 
-        mRoundnessManager.onAmbientStateChanged(entry, false);
+        row.setHeadsUp(false);
+        mRoundnessManager.onHeadsUpStateChanged(entry, false);
         Assert.assertEquals(0f, row.getCurrentBottomRoundness(), 0.0f);
         Assert.assertEquals(0f, row.getCurrentTopRoundness(), 0.0f);
     }
@@ -256,15 +263,15 @@
     }
 
     @Test
-    public void testTrackingHeadsUpNotRoundedIfPushingDown() {
+    public void testTrackingHeadsUpPartiallyRoundedIfPushingDown() {
         mRoundnessManager.setExpanded(1.0f /* expandedHeight */, 0.5f /* appearFraction */);
         mRoundnessManager.setTrackingHeadsUp(mFirst);
         mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
                 createSection(mSecond, mSecond),
                 createSection(null, null)
         });
-        Assert.assertEquals(0.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
-        Assert.assertEquals(0.0f, mFirst.getCurrentTopRoundness(), 0.0f);
+        Assert.assertEquals(0.5f, mFirst.getCurrentBottomRoundness(), 0.0f);
+        Assert.assertEquals(0.5f, mFirst.getCurrentTopRoundness(), 0.0f);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index b99958a..73abda9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -31,6 +31,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.AttributeSet;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -41,6 +42,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -60,6 +62,7 @@
     @Mock private NotificationStackScrollLayout mNssl;
     @Mock private ActivityStarterDelegate mActivityStarterDelegate;
     @Mock private StatusBarStateController mStatusBarStateController;
+    @Mock private ConfigurationController mConfigurationController;
 
     private NotificationSectionsManager mSectionsManager;
 
@@ -70,15 +73,21 @@
                         mNssl,
                         mActivityStarterDelegate,
                         mStatusBarStateController,
+                        mConfigurationController,
                         true);
         // Required in order for the header inflation to work properly
         when(mNssl.generateLayoutParams(any(AttributeSet.class)))
                 .thenReturn(new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
-        mSectionsManager.inflateViews(mContext);
+        mSectionsManager.initialize(LayoutInflater.from(mContext));
         when(mNssl.indexOfChild(any(View.class))).thenReturn(-1);
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
     }
 
+    @Test(expected =  IllegalStateException.class)
+    public void testDuplicateInitializeThrows() {
+        mSectionsManager.initialize(LayoutInflater.from(mContext));
+    }
+
     @Test
     public void testInsertHeader() {
         // GIVEN a stack with HI and LO rows but no section headers
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 662edd2..c1911ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -38,11 +38,12 @@
 
 import android.metrics.LogMaker;
 import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
 import android.view.View;
 
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
@@ -52,9 +53,9 @@
 import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -69,14 +70,16 @@
 import com.android.systemui.statusbar.notification.row.FooterView;
 import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEntryManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 
 import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -93,7 +96,8 @@
  * Tests for {@link NotificationStackScrollLayout}.
  */
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
 public class NotificationStackScrollLayoutTest extends SysuiTestCase {
 
     private NotificationStackScrollLayout mStackScroller;  // Normally test this
@@ -110,8 +114,10 @@
     @Mock private NotificationData mNotificationData;
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
     @Mock private RemoteInputController mRemoteInputController;
+    @Mock private NotificationIconAreaController mNotificationIconAreaController;
     @Mock private MetricsLogger mMetricsLogger;
     @Mock private NotificationRoundnessManager mNotificationRoundnessManager;
+    @Mock private KeyguardBypassController mKeyguardBypassController;
     private TestableNotificationEntryManager mEntryManager;
     private int mOriginalInterruptionModelSetting;
 
@@ -119,6 +125,8 @@
     @Before
     @UiThreadTest
     public void setUp() throws Exception {
+        com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+
         mOriginalInterruptionModelSetting = Settings.Secure.getInt(mContext.getContentResolver(),
                 NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
         Settings.Secure.putInt(mContext.getContentResolver(),
@@ -151,17 +159,20 @@
         // member variables, not the spy's member variables.
         mStackScrollerInternal = new NotificationStackScrollLayout(getContext(), null,
                 true /* allowLongPress */, mNotificationRoundnessManager,
-                new AmbientPulseManager(mContext),
                 mock(DynamicPrivacyController.class),
+                mock(ConfigurationController.class),
                 mock(ActivityStarterDelegate.class),
-                mock(StatusBarStateController.class));
+                mock(StatusBarStateController.class),
+                mHeadsUpManager,
+                mKeyguardBypassController,
+                new FalsingManagerFake());
         mStackScroller = spy(mStackScrollerInternal);
         mStackScroller.setShelf(notificationShelf);
         mStackScroller.setStatusBar(mBar);
         mStackScroller.setScrimController(mock(ScrimController.class));
-        mStackScroller.setHeadsUpManager(mHeadsUpManager);
         mStackScroller.setGroupManager(mGroupManager);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
+        mStackScroller.setIconAreaController(mNotificationIconAreaController);
 
         // Stub out functionality that isn't necessary to test.
         doNothing().when(mBar)
@@ -173,7 +184,6 @@
         doNothing().when(mGroupManager).collapseAllGroups();
         doNothing().when(mExpandHelper).cancelImmediately();
         doNothing().when(notificationShelf).setAnimationsEnabled(anyBoolean());
-        doNothing().when(notificationShelf).fadeInTranslating();
     }
 
     @After
@@ -191,17 +201,6 @@
     }
 
     @Test
-    public void testAntiBurnInOffset() {
-        final int burnInOffset = 30;
-        mStackScroller.setAntiBurnInOffsetX(burnInOffset);
-        mStackScroller.setDarkAmount(0.0f, 0.0f);
-        Assert.assertEquals(0 /* expected */, mStackScroller.getTranslationX(), 0.01 /* delta */);
-        mStackScroller.setDarkAmount(1.0f, 1.0f);
-        Assert.assertEquals(burnInOffset /* expected */, mStackScroller.getTranslationX(),
-                0.01 /* delta */);
-    }
-
-    @Test
     public void updateEmptyView_dndSuppressing() {
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
         when(mBar.areNotificationsHidden()).thenReturn(true);
@@ -386,7 +385,7 @@
         NotificationSwipeHelper swipeActionHelper =
                 (NotificationSwipeHelper) mStackScroller.getSwipeActionHelper();
         swipeActionHelper.setExposedMenuView(new View(mContext));
-        mStackScroller.setDarkAmount(0.1f, 0.1f);
+        mStackScroller.setHideAmount(0.1f, 0.1f);
         assertNull(swipeActionHelper.getExposedMenuView());
     }
 
@@ -433,9 +432,7 @@
 
     @Test
     @UiThreadTest
-    public void testOnMenuShownLogging() {
-        // Set up the object under test to have a valid mHeadsUpManager. See notes in setup.
-        mStackScrollerInternal.setHeadsUpManager(mHeadsUpManager);
+    public void testOnMenuShownLogging() { ;
 
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class, RETURNS_DEEP_STUBS);
         when(row.getStatusBarNotification().getLogMaker()).thenReturn(new LogMaker(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index b24c3dd..06a2eec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -40,6 +40,7 @@
 
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -76,7 +77,8 @@
     public void setUp() throws Exception {
         mCallback = mock(NotificationSwipeHelper.NotificationCallback.class);
         mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class);
-        mSwipeHelper = spy(new NotificationSwipeHelper(SwipeHelper.X, mCallback, mContext, mListener));
+        mSwipeHelper = spy(new NotificationSwipeHelper(
+                SwipeHelper.X, mCallback, mContext, mListener, new FalsingManagerFake()));
         mView = mock(View.class);
         mEvent = mock(MotionEvent.class);
         mMenuRow = mock(NotificationMenuRowPlugin.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index fdc2cd3..7d9920d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
@@ -37,7 +39,6 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.tuner.TunerService;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -72,6 +73,8 @@
     private UnlockMethodCache mUnlockMethodCache;
     @Mock
     private Handler mHandler;
+    @Mock
+    private KeyguardBypassController mKeyguardBypassController;
     private BiometricUnlockController mBiometricUnlockController;
 
     @Before
@@ -79,12 +82,16 @@
         MockitoAnnotations.initMocks(this);
         when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
         when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);
+        when(mUnlockMethodCache.isUnlockingWithFacePossible()).thenReturn(true);
+        when(mKeyguardBypassController.onBiometricAuthenticated(any())).thenReturn(true);
+        when(mKeyguardBypassController.canPlaySubtleWindowAnimations()).thenReturn(true);
         mContext.addMockSystemService(PowerManager.class, mPowerManager);
         mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager);
         mDependency.injectTestDependency(StatusBarWindowController.class,
                 mStatusBarWindowController);
-        mBiometricUnlockController = new TestableBiometricUnlockController(
-                false /* faceDismissesKeyguard */);
+        mBiometricUnlockController = new BiometricUnlockController(mContext, mDozeScrimController,
+                mKeyguardViewMediator, mScrimController, mStatusBar, mUnlockMethodCache,
+                mHandler, mUpdateMonitor, 0 /* wakeUpDelay */, mKeyguardBypassController);
         mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
     }
 
@@ -122,7 +129,7 @@
     @Test
     public void onBiometricAuthenticated_whenFingerprintOnBouncer_dismissBouncer() {
         when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
-        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
         mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
                 BiometricSourceType.FINGERPRINT);
 
@@ -136,25 +143,50 @@
                 BiometricSourceType.FACE);
 
         verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
+        verify(mStatusBarKeyguardViewManager, never()).notifyKeyguardAuthenticated(anyBoolean());
     }
 
     @Test
-    public void onBiometricAuthenticated_whenFace_dismissingKeyguard() {
-        mBiometricUnlockController = new TestableBiometricUnlockController(
-                true /* faceDismissesKeyguard */);
+    public void onBiometricAuthenticated_whenFace_andBypass_dismissKeyguard() {
+        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
         mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
 
         when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
         mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
                 BiometricSourceType.FACE);
 
-        verify(mStatusBarKeyguardViewManager).animateCollapsePanels(anyFloat());
+        verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
+        verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
+    }
+
+    @Test
+    public void onBiometricAuthenticated_whenFace_andBypass_encrypted_showBouncer() {
+        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+        mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+
+        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(false);
+        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+                BiometricSourceType.FACE);
+
+        verify(mStatusBarKeyguardViewManager).showBouncer(eq(false));
+    }
+
+    @Test
+    public void onBiometricAuthenticated_whenFace_noBypass_encrypted_doNothing() {
+        mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+
+        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(false);
+        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+                BiometricSourceType.FACE);
+
+        verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
+        verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
     }
 
     @Test
     public void onBiometricAuthenticated_whenFaceOnBouncer_dismissBouncer() {
         when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
-        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
         mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
                 BiometricSourceType.FACE);
 
@@ -162,6 +194,34 @@
     }
 
     @Test
+    public void onBiometricAuthenticated_whenBypassOnBouncer_dismissBouncer() {
+        reset(mKeyguardBypassController);
+        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
+        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+        when(mKeyguardBypassController.onBiometricAuthenticated(any())).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
+        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+                BiometricSourceType.FACE);
+
+        verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
+        assertThat(mBiometricUnlockController.getMode())
+                .isEqualTo(BiometricUnlockController.MODE_DISMISS_BOUNCER);
+    }
+
+    @Test
+    public void onBiometricAuthenticated_whenBypassOnBouncer_respectsCanPlaySubtleAnim() {
+        when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
+        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
+        mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+                BiometricSourceType.FACE);
+
+        verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
+        assertThat(mBiometricUnlockController.getMode())
+                .isEqualTo(BiometricUnlockController.MODE_UNLOCK_FADING);
+    }
+
+    @Test
     public void onBiometricAuthenticated_whenFaceAndPulsing_dontDismissKeyguard() {
         reset(mUpdateMonitor);
         reset(mStatusBarKeyguardViewManager);
@@ -184,14 +244,4 @@
         mBiometricUnlockController.onFinishedGoingToSleep(-1);
         verify(mHandler).post(any());
     }
-
-    private class TestableBiometricUnlockController extends BiometricUnlockController {
-
-        TestableBiometricUnlockController(boolean faceDismissesKeyguard) {
-            super(mContext, mDozeScrimController,
-                    mKeyguardViewMediator, mScrimController, mStatusBar, mUnlockMethodCache,
-                    mHandler, mUpdateMonitor, 0 /* wakeUpDelay */,
-                    new KeyguardBypassController(faceDismissesKeyguard));
-        }
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index f6f4eb48..60050b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -16,10 +16,6 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
-
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -33,7 +29,6 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.doze.DozeScreenState;
-import com.android.systemui.statusbar.phone.DozeParameters.IntInOutMatcher;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -44,160 +39,6 @@
 public class DozeParametersTest extends SysuiTestCase {
 
     @Test
-    public void test_inOutMatcher_defaultIn() {
-        IntInOutMatcher intInOutMatcher = new IntInOutMatcher("*");
-
-        assertTrue(intInOutMatcher.isIn(1));
-        assertTrue(intInOutMatcher.isIn(-1));
-        assertTrue(intInOutMatcher.isIn(0));
-    }
-
-    @Test
-    public void test_inOutMatcher_defaultOut() {
-        IntInOutMatcher intInOutMatcher = new IntInOutMatcher("!*");
-
-        assertFalse(intInOutMatcher.isIn(1));
-        assertFalse(intInOutMatcher.isIn(-1));
-        assertFalse(intInOutMatcher.isIn(0));
-    }
-
-    @Test
-    public void test_inOutMatcher_someIn() {
-        IntInOutMatcher intInOutMatcher = new IntInOutMatcher("1,2,3,!*");
-
-        assertTrue(intInOutMatcher.isIn(1));
-        assertTrue(intInOutMatcher.isIn(2));
-        assertTrue(intInOutMatcher.isIn(3));
-
-        assertFalse(intInOutMatcher.isIn(0));
-        assertFalse(intInOutMatcher.isIn(4));
-    }
-
-    @Test
-    public void test_inOutMatcher_someOut() {
-        IntInOutMatcher intInOutMatcher = new IntInOutMatcher("!1,!2,!3,*");
-
-        assertFalse(intInOutMatcher.isIn(1));
-        assertFalse(intInOutMatcher.isIn(2));
-        assertFalse(intInOutMatcher.isIn(3));
-
-        assertTrue(intInOutMatcher.isIn(0));
-        assertTrue(intInOutMatcher.isIn(4));
-    }
-
-    @Test
-    public void test_inOutMatcher_mixed() {
-        IntInOutMatcher intInOutMatcher = new IntInOutMatcher("!1,2,!3,*");
-
-        assertFalse(intInOutMatcher.isIn(1));
-        assertTrue(intInOutMatcher.isIn(2));
-        assertFalse(intInOutMatcher.isIn(3));
-
-        assertTrue(intInOutMatcher.isIn(0));
-        assertTrue(intInOutMatcher.isIn(4));
-    }
-
-    @Test
-    public void test_inOutMatcher_failEmpty() {
-        try {
-            new IntInOutMatcher("");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failNull() {
-        try {
-            new IntInOutMatcher(null);
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failEmptyClause() {
-        try {
-            new IntInOutMatcher("!1,*,");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failDuplicate() {
-        try {
-            new IntInOutMatcher("!1,*,!1");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failDuplicateDefault() {
-        try {
-            new IntInOutMatcher("!1,*,*");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failMalformedNot() {
-        try {
-            new IntInOutMatcher("!,*");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failText() {
-        try {
-            new IntInOutMatcher("!abc,*");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failContradiction() {
-        try {
-            new IntInOutMatcher("1,!1,*");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failContradictionDefault() {
-        try {
-            new IntInOutMatcher("1,*,!*");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
-    public void test_inOutMatcher_failMissingDefault() {
-        try {
-            new IntInOutMatcher("1");
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-    }
-
-    @Test
     public void test_setControlScreenOffAnimation_setsDozeAfterScreenOff_false() {
         TestableDozeParameters dozeParameters = new TestableDozeParameters(getContext());
         PowerManager mockedPowerManager = dozeParameters.getPowerManager();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 0479b4a..b45707e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -32,6 +32,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.HeadsUpStatusBarView;
 import com.android.systemui.statusbar.NotificationTestHelper;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -56,6 +57,8 @@
     private HeadsUpStatusBarView mHeadsUpStatusBarView;
     private HeadsUpManagerPhone mHeadsUpManager;
     private View mOperatorNameView;
+    private StatusBarStateController mStatusbarStateController;
+    private KeyguardBypassController mBypassController;
 
     @Before
     public void setUp() throws Exception {
@@ -67,16 +70,20 @@
                 mock(TextView.class));
         mHeadsUpManager = mock(HeadsUpManagerPhone.class);
         mOperatorNameView = new View(mContext);
+        mStatusbarStateController = mock(StatusBarStateController.class);
+        mBypassController = mock(KeyguardBypassController.class);
         mHeadsUpAppearanceController = new HeadsUpAppearanceController(
                 mock(NotificationIconAreaController.class),
                 mHeadsUpManager,
+                mStatusbarStateController,
+                mBypassController,
                 mHeadsUpStatusBarView,
                 mStackScroller,
                 mPanelView,
                 new View(mContext),
                 mOperatorNameView,
                 new View(mContext));
-        mHeadsUpAppearanceController.setExpandedHeight(0.0f, 0.0f);
+        mHeadsUpAppearanceController.setAppearFraction(0.0f, 0.0f);
     }
 
     @Test
@@ -139,11 +146,13 @@
 
     @Test
     public void testHeaderReadFromOldController() {
-        mHeadsUpAppearanceController.setExpandedHeight(1.0f, 1.0f);
+        mHeadsUpAppearanceController.setAppearFraction(1.0f, 1.0f);
 
         HeadsUpAppearanceController newController = new HeadsUpAppearanceController(
                 mock(NotificationIconAreaController.class),
                 mHeadsUpManager,
+                mStatusbarStateController,
+                mBypassController,
                 mHeadsUpStatusBarView,
                 mStackScroller,
                 mPanelView,
@@ -154,8 +163,8 @@
 
         Assert.assertEquals(mHeadsUpAppearanceController.mExpandedHeight,
                 newController.mExpandedHeight, 0.0f);
-        Assert.assertEquals(mHeadsUpAppearanceController.mExpandFraction,
-                newController.mExpandFraction, 0.0f);
+        Assert.assertEquals(mHeadsUpAppearanceController.mAppearFraction,
+                newController.mAppearFraction, 0.0f);
         Assert.assertEquals(mHeadsUpAppearanceController.mIsExpanded,
                 newController.mIsExpanded);
     }
@@ -172,7 +181,7 @@
         verify(mPanelView).removeVerticalTranslationListener(any());
         verify(mPanelView).removeTrackingHeadsUpListener(any());
         verify(mPanelView).setHeadsUpAppearanceController(any());
-        verify(mStackScroller).removeOnExpandedHeightListener(any());
+        verify(mStackScroller).removeOnExpandedHeightChangedListener(any());
         verify(mStackScroller).removeOnLayoutChangeListener(any());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 7bd4158..48934da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -29,6 +29,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.AlertingNotificationManager;
 import com.android.systemui.statusbar.AlertingNotificationManagerTest;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
@@ -55,12 +56,18 @@
     @Mock private View mStatusBarWindowView;
     @Mock private VisualStabilityManager mVSManager;
     @Mock private StatusBar mBar;
+    @Mock private StatusBarStateController mStatusBarStateController;
+    @Mock private KeyguardBypassController mBypassController;
+    private boolean mLivesPastNormalTime;
 
     private final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
         TestableHeadsUpManagerPhone(Context context, View statusBarWindowView,
                 NotificationGroupManager groupManager, StatusBar bar,
-                VisualStabilityManager vsManager) {
-            super(context, statusBarWindowView, groupManager, bar, vsManager);
+                VisualStabilityManager vsManager,
+                StatusBarStateController statusBarStateController,
+                KeyguardBypassController keyguardBypassController) {
+            super(context, statusBarStateController, keyguardBypassController);
+            setUp(statusBarWindowView, groupManager, bar, vsManager);
             mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
             mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
         }
@@ -72,13 +79,13 @@
 
     @Before
     public void setUp() {
-        AccessibilityManagerWrapper mAccessibilityMgr =
+        AccessibilityManagerWrapper accessibilityMgr =
                 mDependency.injectMockDependency(AccessibilityManagerWrapper.class);
-        when(mAccessibilityMgr.getRecommendedTimeoutMillis(anyInt(), anyInt()))
+        when(accessibilityMgr.getRecommendedTimeoutMillis(anyInt(), anyInt()))
                 .thenReturn(TEST_AUTO_DISMISS_TIME);
         when(mVSManager.isReorderingAllowed()).thenReturn(true);
         mHeadsUpManager = new TestableHeadsUpManagerPhone(mContext, mStatusBarWindowView,
-                mGroupManager, mBar, mVSManager);
+                mGroupManager, mBar, mVSManager, mStatusBarStateController, mBypassController);
         super.setUp();
         mHeadsUpManager.mHandler = mTestHandler;
     }
@@ -122,4 +129,24 @@
         // Notification is "behind" a higher priority notification so we can remove it immediately.
         assertTrue(mHeadsUpManager.canRemoveImmediately(mEntry.key));
     }
+
+
+    @Test
+    public void testExtendHeadsUp() {
+        mHeadsUpManager.showNotification(mEntry);
+        Runnable pastNormalTimeRunnable =
+                () -> mLivesPastNormalTime = mHeadsUpManager.isAlerting(mEntry.key);
+        mTestHandler.postDelayed(pastNormalTimeRunnable,
+                TEST_AUTO_DISMISS_TIME + mHeadsUpManager.mExtensionTime / 2);
+        mTestHandler.postDelayed(TEST_TIMEOUT_RUNNABLE, TEST_TIMEOUT_TIME);
+
+        mHeadsUpManager.extendHeadsUp();
+
+        // Wait for normal time runnable and extended remove runnable and process them on arrival.
+        TestableLooper.get(this).processMessages(2);
+
+        assertFalse("Test timed out", mTimedOut);
+        assertTrue("Pulse was not extended", mLivesPastNormalTime);
+        assertFalse(mHeadsUpManager.isAlerting(mEntry.key));
+    }
 }
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 3bc5f3e..4e0ef56 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
@@ -82,6 +82,8 @@
     @Mock
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock
+    private UnlockMethodCache mUnlockMethodCache;
+    @Mock
     private Handler mHandler;
 
     private KeyguardBouncer mBouncer;
@@ -96,7 +98,7 @@
         when(mKeyguardHostView.getHeight()).thenReturn(500);
         mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback,
                 mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager,
-                mExpansionCallback, mKeyguardUpdateMonitor, mHandler) {
+                mExpansionCallback, mUnlockMethodCache, mKeyguardUpdateMonitor, mHandler) {
             @Override
             protected void inflateView() {
                 super.inflateView();
@@ -377,7 +379,7 @@
 
     @Test
     public void testShow_delaysIfFaceAuthIsRunning() {
-        when(mKeyguardUpdateMonitor.isFaceDetectionRunning()).thenReturn(true);
+        when(mUnlockMethodCache.isUnlockingWithFacePossible()).thenReturn(true);
         mBouncer.show(true /* reset */);
 
         ArgumentCaptor<Runnable> showRunnable = ArgumentCaptor.forClass(Runnable.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index 66c61ce..2042fab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -383,7 +383,8 @@
     private void positionClock() {
         mClockPositionAlgorithm.setup(EMPTY_MARGIN, SCREEN_HEIGHT, mNotificationStackHeight,
                 mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight, mPreferredClockY,
-                mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG, false /* positionLikeDark */);
+                mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
+                0 /* unlockedStackScrollerPadding */);
         mClockPositionAlgorithm.run(mClockPosition);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
index cb70a1f..be69f5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
@@ -180,9 +180,9 @@
         final Drawable d = mock(Drawable.class);
         final ContextualButton button = spy(mBtn0);
         final KeyButtonDrawable kbd1 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
-                false /* horizontalFlip */, false /* hasOvalBg */));
+                false /* horizontalFlip */, null /* ovalBackgroundColor */));
         final KeyButtonDrawable kbd2 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
-                false /* horizontalFlip */, false /* hasOvalBg */));
+                false /* horizontalFlip */, null /* ovalBackgroundColor */));
         kbd1.setDarkIntensity(TEST_DARK_INTENSITY);
         kbd2.setDarkIntensity(0f);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index faf5a97..3da9a4b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -56,6 +56,7 @@
 import com.android.systemui.SysuiBaseFragmentTest;
 import com.android.systemui.SysuiTestableContext;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.stackdivider.Divider;
@@ -215,7 +216,8 @@
                 new MetricsLogger(),
                 mock(AssistManager.class),
                 mOverviewProxyService,
-                mock(NavigationModeController.class));
+                mock(NavigationModeController.class),
+                mock(StatusBarStateController.class));
     }
 
     private class HostCallbacksForExternalDisplay extends
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
index 337c35c..b1c3c83 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -32,7 +33,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -58,7 +59,6 @@
 
     private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
     private NotificationGroupManager mGroupManager;
-    private AmbientPulseManager mAmbientPulseManager;
     private HeadsUpManager mHeadsUpManager;
     @Mock private NotificationEntryManager mNotificationEntryManager;
     @Captor
@@ -71,14 +71,12 @@
 
     @Before
     public void setup() {
-        mAmbientPulseManager = new AmbientPulseManager(mContext);
-        mDependency.injectTestDependency(AmbientPulseManager.class, mAmbientPulseManager);
         mHeadsUpManager = new HeadsUpManager(mContext) {};
 
         when(mNotificationEntryManager.getPendingNotificationsIterator())
                 .thenReturn(mPendingEntries.values());
 
-        mGroupManager = new NotificationGroupManager();
+        mGroupManager = new NotificationGroupManager(mock(StatusBarStateController.class));
         mDependency.injectTestDependency(NotificationGroupManager.class, mGroupManager);
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
 
@@ -89,7 +87,6 @@
         verify(mNotificationEntryManager).addNotificationEntryListener(mListenerCaptor.capture());
         mNotificationEntryListener = mListenerCaptor.getValue();
         mHeadsUpManager.addListener(mGroupAlertTransferHelper);
-        mAmbientPulseManager.addListener(mGroupAlertTransferHelper);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
index 43685f0..dd274c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
@@ -21,6 +21,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.testing.AndroidTestingRunner;
@@ -29,7 +30,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
@@ -53,17 +54,14 @@
             new NotificationGroupTestHelper(mContext);
 
     @Mock HeadsUpManager mHeadsUpManager;
-    @Mock AmbientPulseManager mAmbientPulseManager;
 
     @Before
     public void setup() {
-        mDependency.injectTestDependency(AmbientPulseManager.class, mAmbientPulseManager);
-
         initializeGroupManager();
     }
 
     private void initializeGroupManager() {
-        mGroupManager = new NotificationGroupManager();
+        mGroupManager = new NotificationGroupManager(mock(StatusBarStateController.class));
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
     }
 
@@ -146,21 +144,4 @@
         assertEquals(childEntry, mGroupManager.getGroupSummary(childEntry.notification));
         assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(childEntry.notification));
     }
-
-    @Test
-    public void testAmbientPulseEntryIsIsolated() {
-        NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
-        NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
-        mGroupManager.onEntryAdded(summaryEntry);
-        mGroupManager.onEntryAdded(childEntry);
-        mGroupManager.onEntryAdded(mGroupTestHelper.createChildNotification());
-        when(mAmbientPulseManager.isAlerting(childEntry.key)).thenReturn(true);
-
-        mGroupManager.onAmbientStateChanged(childEntry, true);
-
-        // Child entries that are heads upped should be considered separate groups visually even if
-        // they are the same group logically
-        assertEquals(childEntry, mGroupManager.getGroupSummary(childEntry.notification));
-        assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(childEntry.notification));
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
deleted file mode 100644
index 7f7a3e7..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
+++ /dev/null
@@ -1,88 +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 static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.NotificationMediaManager;
-
-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 NotificationIconAreaControllerTest extends SysuiTestCase {
-
-    @Mock
-    private NotificationListener mListener;
-    @Mock
-    StatusBar mStatusBar;
-    @Mock
-    StatusBarStateController mStatusBarStateController;
-    @Mock
-    private NotificationMediaManager mMediaManager;
-    private NotificationIconAreaController mController;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        mController = new NotificationIconAreaController(mContext, mStatusBar,
-                mStatusBarStateController, mListener, mMediaManager);
-    }
-
-    @Test
-    public void testNotificationIcons_featureOff() {
-        Settings.Secure.putInt(
-                mContext.getContentResolver(), NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
-        assertTrue(mController.shouldShouldLowPriorityIcons());
-    }
-
-    @Test
-    public void testNotificationIcons_featureOn_settingHideIcons() {
-        Settings.Secure.putInt(
-                mContext.getContentResolver(), NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
-        mController.mSettingsListener.onStatusBarIconsBehaviorChanged(true);
-
-        assertFalse(mController.shouldShouldLowPriorityIcons());
-    }
-
-    @Test
-    public void testNotificationIcons_featureOn_settingShowIcons() {
-        Settings.Secure.putInt(
-                mContext.getContentResolver(), NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
-        mController.mSettingsListener.onStatusBarIconsBehaviorChanged(false);
-
-        assertTrue(mController.shouldShouldLowPriorityIcons());
-    }
-}
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 e0e4a25..a96efd7 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
@@ -36,8 +36,8 @@
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationShelf;
@@ -46,6 +46,7 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -98,6 +99,8 @@
     private PanelBar mPanelBar;
     @Mock
     private KeyguardAffordanceHelper mAffordanceHelper;
+    @Mock
+    private FalsingManager mFalsingManager;
     private NotificationPanelView mNotificationPanelView;
 
     @Before
@@ -113,13 +116,15 @@
         mDependency.injectMockDependency(ConfigurationController.class);
         mDependency.injectMockDependency(ZenModeController.class);
         KeyguardBypassController bypassController = new KeyguardBypassController(mContext,
-                mock(TunerService.class));
+                mock(TunerService.class), mStatusBarStateController,
+                mock(NotificationLockscreenUserManager.class));
         NotificationWakeUpCoordinator coordinator =
                 new NotificationWakeUpCoordinator(mContext,
-                        new AmbientPulseManager(mContext),
+                        mock(HeadsUpManagerPhone.class),
                         new StatusBarStateControllerImpl(),
                         bypassController);
-        PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator);
+        PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator,
+                bypassController, mHeadsUpManager, mock(NotificationRoundnessManager.class));
         mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler,
                 bypassController);
         mNotificationPanelView.setHeadsUpManager(mHeadsUpManager);
@@ -189,7 +194,8 @@
                     new InjectionInflationController(
                             SystemUIFactory.getInstance().getRootComponent()),
                     coordinator, expansionHandler, mock(DynamicPrivacyController.class),
-                    bypassController);
+                    bypassController,
+                    mFalsingManager);
             mNotificationStackScroller = mNotificationStackScrollLayout;
             mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
             mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
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 191c983..d8e90a5 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
@@ -508,6 +508,38 @@
     }
 
     @Test
+    public void transitionToPulsing_withTimeoutWallpaperCallback_willHideWallpaper() {
+        mScrimController.setWallpaperSupportsAmbientMode(true);
+
+        mScrimController.transitionTo(ScrimState.PULSING, new ScrimController.Callback() {
+            @Override
+            public boolean shouldTimeoutWallpaper() {
+                return true;
+            }
+        });
+
+        verify(mAlarmManager).setExact(anyInt(), anyLong(), any(), any(), any());
+    }
+
+    @Test
+    public void transitionToPulsing_withDefaultCallback_wontHideWallpaper() {
+        mScrimController.setWallpaperSupportsAmbientMode(true);
+
+        mScrimController.transitionTo(ScrimState.PULSING, new ScrimController.Callback() {});
+
+        verify(mAlarmManager, never()).setExact(anyInt(), anyLong(), any(), any(), any());
+    }
+
+    @Test
+    public void transitionToPulsing_withoutCallback_wontHideWallpaper() {
+        mScrimController.setWallpaperSupportsAmbientMode(true);
+
+        mScrimController.transitionTo(ScrimState.PULSING);
+
+        verify(mAlarmManager, never()).setExact(anyInt(), anyLong(), any(), any(), any());
+    }
+
+    @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 f50cf5a..63f653b 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
@@ -19,6 +19,7 @@
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -29,16 +30,21 @@
 import android.content.Context;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -70,7 +76,11 @@
     @Mock
     private ViewGroup mLockIconContainer;
     @Mock
-    private StatusBarStateController mStatusBarStateController;
+    private SysuiStatusBarStateController mStatusBarStateController;
+    @Mock
+    private View mNotificationContainer;
+    @Mock
+    private KeyguardBypassController mBypassController;
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     @Before
@@ -79,11 +89,14 @@
         mDependency.injectMockDependency(StatusBarWindowController.class);
         mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
         when(mLockIconContainer.getParent()).thenReturn(mock(ViewGroup.class));
+        when(mLockIconContainer.animate()).thenReturn(mock(ViewPropertyAnimator.class,
+                RETURNS_DEEP_STUBS));
         mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(getContext(),
                 mViewMediatorCallback, mLockPatternUtils);
         mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
                 mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry,
-                mLockIconContainer);
+                mLockIconContainer, mNotificationContainer, mBypassController,
+                new FalsingManagerFake());
         mStatusBarKeyguardViewManager.show(null);
     }
 
@@ -221,10 +234,12 @@
                 NotificationPanelView notificationPanelView,
                 BiometricUnlockController fingerprintUnlockController,
                 DismissCallbackRegistry dismissCallbackRegistry,
-                ViewGroup lockIconContainer) {
+                ViewGroup lockIconContainer, View notificationContainer,
+                KeyguardBypassController bypassController, FalsingManager falsingManager) {
             super.registerStatusBar(statusBar, container, notificationPanelView,
-                    fingerprintUnlockController, dismissCallbackRegistry, lockIconContainer);
+                    fingerprintUnlockController, dismissCallbackRegistry, lockIconContainer,
+                    notificationContainer, bypassController, falsingManager);
             mBouncer = StatusBarKeyguardViewManagerTest.this.mBouncer;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 79e05c3..cffd57b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -222,6 +222,7 @@
         mNotificationLogger = new NotificationLogger(mNotificationListener,
                 Dependency.get(UiOffloadThread.class), mEntryManager, mStatusBarStateController,
                 mExpansionStateLogger);
+        mNotificationLogger.setVisibilityReporter(mock(Runnable.class));
         mDependency.injectTestDependency(NotificationLogger.class, mNotificationLogger);
         DozeLog.traceDozing(mContext, false /* dozing */);
 
@@ -253,7 +254,7 @@
 
         when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
         mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
-                mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
+                mKeyguardIndicationController, mStackScroller,
                 mPowerManager, mNotificationPanelView, mBarService, mNotificationListener,
                 mNotificationLogger, mVisualStabilityManager, mViewHierarchyManager,
                 mEntryManager, mScrimController, mBiometricUnlockController,
@@ -269,19 +270,13 @@
         SystemUIFactory.getInstance().getRootComponent()
                 .getStatusBarInjector()
                 .createStatusBar(mStatusBar);
+        mStatusBar.setHeadsUpManager(mHeadsUpManager);
         mStatusBar.putComponent(StatusBar.class, mStatusBar);
         Dependency.get(InitController.class).executePostInitTasks();
         mEntryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller,
                 mHeadsUpManager, mNotificationData);
         mEntryManager.addNotificationEntryListener(mEntryListener);
         mNotificationLogger.setUpWithContainer(mStackScroller);
-
-        TestableLooper.get(this).setMessageHandler(m -> {
-            if (m.getCallback() == mStatusBar.mNotificationLogger.getVisibilityReporter()) {
-                return false;
-            }
-            return true;
-        });
     }
 
     @Test
@@ -644,10 +639,10 @@
     @Test
     public void testPulseWhileDozing_notifyAuthInterrupt() {
         HashSet<Integer> reasonsWantingAuth = new HashSet<>(
-                Collections.singletonList(DozeLog.PULSE_REASON_NOTIFICATION));
+                Collections.singletonList(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN));
         HashSet<Integer> reasonsSkippingAuth = new HashSet<>(
                 Arrays.asList(DozeLog.PULSE_REASON_INTENT,
-                        DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
+                        DozeLog.PULSE_REASON_NOTIFICATION,
                         DozeLog.PULSE_REASON_SENSOR_SIGMOTION,
                         DozeLog.REASON_SENSOR_PICKUP,
                         DozeLog.REASON_SENSOR_DOUBLE_TAP,
@@ -666,6 +661,7 @@
             return null;
         }).when(mDozeScrimController).pulse(any(), anyInt());
 
+        mStatusBar.mDozeServiceHost.mWakeLockScreenPerformsAuth = true;
         for (int i = 0; i < DozeLog.REASONS; i++) {
             reset(mKeyguardUpdateMonitor);
             mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class), i);
@@ -765,7 +761,7 @@
     static class TestableStatusBar extends StatusBar {
         public TestableStatusBar(StatusBarKeyguardViewManager man,
                 UnlockMethodCache unlock, KeyguardIndicationController key,
-                NotificationStackScrollLayout stack, HeadsUpManagerPhone hum,
+                NotificationStackScrollLayout stack,
                 PowerManager pm, NotificationPanelView panelView,
                 IStatusBarService barService, NotificationListener notificationListener,
                 NotificationLogger notificationLogger,
@@ -794,7 +790,6 @@
             mUnlockMethodCache = unlock;
             mKeyguardIndicationController = key;
             mStackScroller = stack;
-            mHeadsUpManager = hum;
             mPowerManager = pm;
             mNotificationPanel = panelView;
             mBarService = barService;
@@ -824,6 +819,7 @@
             mAutoHideController = autoHideController;
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
             mStatusBarWindow = statusBarWindow;
+            mDozeServiceHost.mWakeLockScreenPerformsAuth = false;
         }
 
         private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
@@ -842,6 +838,10 @@
             mState = state;
         }
 
+        void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
+            mHeadsUpManager = headsUpManager;
+        }
+
         public void setUserSetupForTest(boolean userSetup) {
             mUserSetup = userSetup;
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
index ca64823..a9a1392 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemUIDialogTest.java
@@ -17,9 +17,11 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -52,13 +54,18 @@
 
     @Test
     public void testRegisterReceiver() {
+        final ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
         final ArgumentCaptor<IntentFilter> intentFilterCaptor =
                 ArgumentCaptor.forClass(IntentFilter.class);
 
-        verify(mContextSpy).registerReceiverAsUser(any(), any(),
+        mDialog.show();
+        verify(mContextSpy).registerReceiverAsUser(broadcastReceiverCaptor.capture(), any(),
                 intentFilterCaptor.capture(), any(), any());
 
         assertTrue(intentFilterCaptor.getValue().hasAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
-    }
 
+        mDialog.dismiss();
+        verify(mContextSpy).unregisterReceiver(eq(broadcastReceiverCaptor.getValue()));
+    }
 }
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 616b46a..9ae9ceb 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
@@ -164,7 +164,7 @@
     protected void setupNetworkController() {
         // For now just pretend to be the data sim, so we can test that too.
         mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-        when(mMockTm.getDataEnabled(mSubId)).thenReturn(true);
+        when(mMockTm.isDataCapable()).thenReturn(true);
         setDefaultSubId(mSubId);
         setSubscriptions(mSubId);
         mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
@@ -181,6 +181,7 @@
     protected void setDefaultSubId(int subId) {
         when(mMockSubDefaults.getDefaultDataSubId()).thenReturn(subId);
         when(mMockSubDefaults.getDefaultVoiceSubId()).thenReturn(subId);
+        when(mMockSubDefaults.getActiveDataSubId()).thenReturn(subId);
     }
 
     protected void setSubscriptions(int... subIds) {
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 cd0a0441..5128675 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
@@ -119,7 +119,7 @@
     @Test
     public void testNoInternetIcon_withDefaultSub() {
         setupNetworkController();
-        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -133,7 +133,7 @@
     @Test
     public void testDataDisabledIcon_withDefaultSub() {
         setupNetworkController();
-        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -147,7 +147,7 @@
     @Test
     public void testNoInternetIcon_withoutDefaultSub() {
         setupNetworkController();
-        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         setupDefaultSignal();
         setDefaultSubId(mSubId + 1);
         updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
@@ -162,7 +162,7 @@
     @Test
     public void testDataDisabledIcon_withoutDefaultSub() {
         setupNetworkController();
-        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         setupDefaultSignal();
         setDefaultSubId(mSubId + 1);
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
@@ -218,7 +218,7 @@
     @Test
     public void testDataDisabledIcon_UserNotSetup() {
         setupNetworkController();
-        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         setupDefaultSignal();
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
         setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -233,7 +233,7 @@
     @Test
     public void testAlwaysShowDataRatIcon() {
         setupDefaultSignal();
-        when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+        when(mMockTm.isDataCapable()).thenReturn(false);
         updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED,
                 TelephonyManager.NETWORK_TYPE_GSM);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 8c5fac4..0cb5754 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -109,7 +109,9 @@
         MockitoAnnotations.initMocks(this);
         mReceiver = new BlockingQueueIntentReceiver();
         mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION));
-        mDependency.get(KeyguardDismissUtil.class).setDismissHandler(action -> action.onDismiss());
+        mDependency.get(KeyguardDismissUtil.class).setDismissHandler((action, unused) -> {
+            action.onDismiss();
+        });
         mDependency.injectMockDependency(ShadeController.class);
         mDependency.injectTestDependency(ActivityStarter.class, mActivityStarter);
         mDependency.injectTestDependency(SmartReplyConstants.class, mConstants);
@@ -162,7 +164,7 @@
 
     @Test
     public void testSendSmartReply_keyguardCancelled() throws InterruptedException {
-        mDependency.get(KeyguardDismissUtil.class).setDismissHandler(action -> {});
+        mDependency.get(KeyguardDismissUtil.class).setDismissHandler((action, unused) -> {});
         setSmartReplies(TEST_CHOICES);
 
         mView.getChildAt(2).performClick();
@@ -173,7 +175,9 @@
     @Test
     public void testSendSmartReply_waitsForKeyguard() throws InterruptedException {
         AtomicReference<OnDismissAction> actionRef = new AtomicReference<>();
-        mDependency.get(KeyguardDismissUtil.class).setDismissHandler(actionRef::set);
+        mDependency.get(KeyguardDismissUtil.class).setDismissHandler((action, unused) -> {
+            actionRef.set(action);
+        });
         setSmartReplies(TEST_CHOICES);
 
         mView.getChildAt(2).performClick();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
index 66eb299..3357be8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
@@ -42,7 +42,7 @@
     @Before
     public void setUp() {
         mInner = WakeLock.createPartialInner(mContext, WakeLockTest.class.getName());
-        mWakeLock = WakeLock.wrap(mInner);
+        mWakeLock = WakeLock.wrap(mInner, 20000);
     }
 
     @After
@@ -70,14 +70,6 @@
     }
 
     @Test
-    public void wakeLock_refCounted() {
-        mWakeLock.acquire(WHY);
-        mWakeLock.acquire(WHY);
-        mWakeLock.release(WHY);
-        assertTrue(mInner.isHeld());
-    }
-
-    @Test
     public void wakeLock_wrap() {
         boolean[] ran = new boolean[1];
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
index a4ae166..29b8ab60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
@@ -40,18 +40,23 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
+import javax.annotation.Nullable;
+
 /**
  * Rudimentary fake for SensorManager
  *
- * Currently only supports the proximity sensor.
+ * Currently only supports proximity, light and tap sensors.
  *
  * Note that this class ignores the "Handler" argument, so the test is responsible for calling the
  * listener on the right thread.
  */
 public class FakeSensorManager extends SensorManager {
 
+    public static final String TAP_SENSOR_TYPE = "tapSensorType";
+
     private final MockProximitySensor mMockProximitySensor;
     private final FakeGenericSensor mFakeLightSensor;
+    private final FakeGenericSensor mFakeTapSensor;
     private final FakeGenericSensor[] mSensors;
 
     public FakeSensorManager(Context context) throws Exception {
@@ -59,12 +64,13 @@
                 .getDefaultSensor(Sensor.TYPE_PROXIMITY);
         if (proxSensor == null) {
             // No prox? Let's create a fake one!
-            proxSensor = createSensor(Sensor.TYPE_PROXIMITY);
+            proxSensor = createSensor(Sensor.TYPE_PROXIMITY, null);
         }
 
         mSensors = new FakeGenericSensor[]{
                 mMockProximitySensor = new MockProximitySensor(proxSensor),
-                mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT)),
+                mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)),
+                mFakeTapSensor = new FakeGenericSensor(createSensor(99, TAP_SENSOR_TYPE))
         };
     }
 
@@ -76,6 +82,10 @@
         return mFakeLightSensor;
     }
 
+    public FakeGenericSensor getFakeTapSensor() {
+        return mFakeTapSensor;
+    }
+
     @Override
     public Sensor getDefaultSensor(int type) {
         Sensor s = super.getDefaultSensor(type);
@@ -160,13 +170,13 @@
 
     @Override
     protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
-        return false;
+        return true;
     }
 
     @Override
     protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
             boolean disable) {
-        return false;
+        return true;
     }
 
     @Override
@@ -185,12 +195,15 @@
         return false;
     }
 
-    private Sensor createSensor(int type) throws Exception {
+    private Sensor createSensor(int type, @Nullable String stringType) throws Exception {
         Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
         constr.setAccessible(true);
         Sensor sensor = constr.newInstance();
 
         setSensorType(sensor, type);
+        if (stringType != null) {
+            setSensorField(sensor, "mStringType", stringType);
+        }
         setSensorField(sensor, "mName", "Mock " + sensor.getStringType() + "/" + type);
         setSensorField(sensor, "mVendor", "Mock Vendor");
         setSensorField(sensor, "mVersion", 1);
diff --git a/packages/SystemUI/tools/lint/baseline.xml b/packages/SystemUI/tools/lint/baseline.xml
index 8c43222..096a639 100644
--- a/packages/SystemUI/tools/lint/baseline.xml
+++ b/packages/SystemUI/tools/lint/baseline.xml
@@ -2685,39 +2685,6 @@
 
     <issue
         id="UnusedResources"
-        message="The resource `R.dimen.volume_dialog_base_margin` appears to be unused"
-        errorLine1="    &lt;dimen name=&quot;volume_dialog_base_margin&quot;>8dp&lt;/dimen>"
-        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/dimens.xml"
-            line="308"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnusedResources"
-        message="The resource `R.dimen.volume_dialog_row_height` appears to be unused"
-        errorLine1="    &lt;dimen name=&quot;volume_dialog_row_height&quot;>252dp&lt;/dimen>"
-        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/dimens.xml"
-            line="314"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnusedResources"
-        message="The resource `R.dimen.volume_dialog_settings_icon_size` appears to be unused"
-        errorLine1="    &lt;dimen name=&quot;volume_dialog_settings_icon_size&quot;>16dp&lt;/dimen>"
-        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="res/values/dimens.xml"
-            line="328"
-            column="12"/>
-    </issue>
-
-    <issue
-        id="UnusedResources"
         message="The resource `R.dimen.carrier_label_height` appears to be unused"
         errorLine1="    &lt;dimen name=&quot;carrier_label_height&quot;>24dp&lt;/dimen>"
         errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/packages/VpnDialogs/res/values-hi/strings.xml b/packages/VpnDialogs/res/values-hi/strings.xml
index 5560a85..34b79cb 100644
--- a/packages/VpnDialogs/res/values-hi/strings.xml
+++ b/packages/VpnDialogs/res/values-hi/strings.xml
@@ -30,7 +30,7 @@
     <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
     <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"VPN सेटिंग बदलें"</string>
     <string name="configure" msgid="4905518375574791375">"कॉन्फ़िगर करें"</string>
-    <string name="disconnect" msgid="971412338304200056">"डिस्‍कनेक्‍ट करें"</string>
+    <string name="disconnect" msgid="971412338304200056">"डिसकनेक्ट करें"</string>
     <string name="open_app" msgid="3717639178595958667">"ऐप खोलें"</string>
     <string name="dismiss" msgid="6192859333764711227">"खारिज करें"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sk/strings.xml b/packages/VpnDialogs/res/values-sk/strings.xml
index 0002964..a08117a 100644
--- a/packages/VpnDialogs/res/values-sk/strings.xml
+++ b/packages/VpnDialogs/res/values-sk/strings.xml
@@ -32,5 +32,5 @@
     <string name="configure" msgid="4905518375574791375">"Konfigurovať"</string>
     <string name="disconnect" msgid="971412338304200056">"Odpojiť"</string>
     <string name="open_app" msgid="3717639178595958667">"Otvoriť aplikáciu"</string>
-    <string name="dismiss" msgid="6192859333764711227">"Zrušiť"</string>
+    <string name="dismiss" msgid="6192859333764711227">"Zavrieť"</string>
 </resources>
diff --git a/packages/overlays/AccentColorBlackOverlay/Android.mk b/packages/overlays/AccentColorBlackOverlay/Android.mk
index a689def..86d873dc 100644
--- a/packages/overlays/AccentColorBlackOverlay/Android.mk
+++ b/packages/overlays/AccentColorBlackOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AccentColorBlackOverlay
diff --git a/packages/overlays/AccentColorCinnamonOverlay/Android.mk b/packages/overlays/AccentColorCinnamonOverlay/Android.mk
index 3a6cbe3..a8d3f10 100644
--- a/packages/overlays/AccentColorCinnamonOverlay/Android.mk
+++ b/packages/overlays/AccentColorCinnamonOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AccentColorCinnamonOverlay
diff --git a/packages/overlays/AccentColorGreenOverlay/Android.mk b/packages/overlays/AccentColorGreenOverlay/Android.mk
index d96dbe1..c3aa6a8 100644
--- a/packages/overlays/AccentColorGreenOverlay/Android.mk
+++ b/packages/overlays/AccentColorGreenOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AccentColorGreenOverlay
diff --git a/packages/overlays/AccentColorOceanOverlay/Android.mk b/packages/overlays/AccentColorOceanOverlay/Android.mk
index cf0c6b3..96fbee4 100644
--- a/packages/overlays/AccentColorOceanOverlay/Android.mk
+++ b/packages/overlays/AccentColorOceanOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AccentColorOceanOverlay
diff --git a/packages/overlays/AccentColorOrchidOverlay/Android.mk b/packages/overlays/AccentColorOrchidOverlay/Android.mk
index fc55bef..352e36b 100644
--- a/packages/overlays/AccentColorOrchidOverlay/Android.mk
+++ b/packages/overlays/AccentColorOrchidOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AccentColorOrchidOverlay
diff --git a/packages/overlays/AccentColorPurpleOverlay/Android.mk b/packages/overlays/AccentColorPurpleOverlay/Android.mk
index 3a28efa..29d5fc9 100644
--- a/packages/overlays/AccentColorPurpleOverlay/Android.mk
+++ b/packages/overlays/AccentColorPurpleOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AccentColorPurpleOverlay
diff --git a/packages/overlays/AccentColorSpaceOverlay/Android.mk b/packages/overlays/AccentColorSpaceOverlay/Android.mk
index 78cbf73..cbddf63 100644
--- a/packages/overlays/AccentColorSpaceOverlay/Android.mk
+++ b/packages/overlays/AccentColorSpaceOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := AccentColorSpaceOverlay
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index 3f16c12..3eb9049 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -44,7 +44,6 @@
 	IconPackRoundedSystemUIOverlay \
 	IconPackRoundedThemePickerUIOverlay \
 	IconShapeRoundedRectOverlay \
-	IconShapeSquareOverlay \
 	IconShapeSquircleOverlay \
 	IconShapeTeardropOverlay \
 	NavigationBarMode3ButtonOverlay \
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/Android.mk b/packages/overlays/DisplayCutoutEmulationCornerOverlay/Android.mk
index b73aea3..c3e8642 100644
--- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/Android.mk
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/Android.mk
@@ -6,8 +6,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := DisplayCutoutEmulationCornerOverlay
diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/Android.mk b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/Android.mk
index 8ca2dad..09d158d 100644
--- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/Android.mk
+++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/Android.mk
@@ -6,8 +6,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := DisplayCutoutEmulationDoubleOverlay
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/Android.mk b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/Android.mk
index 7458cb5..6a1c09c 100644
--- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/Android.mk
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/Android.mk
@@ -6,8 +6,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := DisplayCutoutEmulationNarrowOverlay
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/Android.mk b/packages/overlays/DisplayCutoutEmulationTallOverlay/Android.mk
index 1a405e2..cbceff0 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/Android.mk
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/Android.mk
@@ -6,8 +6,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := DisplayCutoutEmulationTallOverlay
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/Android.mk b/packages/overlays/DisplayCutoutEmulationWideOverlay/Android.mk
index 3ebc540..82a076a 100644
--- a/packages/overlays/DisplayCutoutEmulationWideOverlay/Android.mk
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/Android.mk
@@ -6,8 +6,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := DisplayCutoutEmulationWideOverlay
diff --git a/packages/overlays/FontNotoSerifSourceOverlay/Android.mk b/packages/overlays/FontNotoSerifSourceOverlay/Android.mk
index f4eedaf..16a0173 100644
--- a/packages/overlays/FontNotoSerifSourceOverlay/Android.mk
+++ b/packages/overlays/FontNotoSerifSourceOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := FontNotoSerifSourceOverlay
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/Android.mk b/packages/overlays/IconPackCircularAndroidOverlay/Android.mk
index 8f3baa5..d96185f 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/Android.mk
+++ b/packages/overlays/IconPackCircularAndroidOverlay/Android.mk
@@ -20,8 +20,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackCircularAndroidOverlay
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
new file mode 100644
index 0000000..3cf7541
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
@@ -0,0 +1,27 @@
+<?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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <path
+        android:fillColor="@android:color/white"
+        android:fillType="evenOdd"
+        android:pathData="M12,20.5 L12,3.5 C16.687,3.5 20.5,7.313 20.5,12 C20.5,16.687 16.687,20.5 12,20.5 M12,2 C10.619,2 9.304,2.279 8.107,2.786 C7.51,3.039 6.941,3.349 6.409,3.708 C6.143,3.888 5.886,4.08 5.639,4.283 C4.651,5.099 3.822,6.1 3.207,7.233 C2.899,7.8 2.645,8.4 2.449,9.026 C2.255,9.652 2.12,10.305 2.052,10.978 C2.018,11.313 2,11.654 2,12 C2,17.522 6.478,22 12,22 C17.522,22 22,17.522 22,12 C22,6.478 17.522,2 12,2"
+        android:strokeWidth="1" />
+</vector>
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml
new file mode 100644
index 0000000..6480264
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml
@@ -0,0 +1,40 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="2.000000"
+        android:translateY="2.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M12.64,3 L12.64,8.82352941 C12.2536,8.5 11.772,8.29411765 11.24,8.29411765 C10.0024,8.29411765 9,9.34705882 9,10.6470588 C9,11.9470588 10.0024,13 11.24,13 C12.4776,13 13.48,11.9470588 13.48,10.6470588 L13.48,5.00157166 L15.02,5.00157166 C15.5576,5.00157166 16,4.53686577 16,3.97215989 L16,3 L12.64,3 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M20,2 C20,0.9 19.1,0 18,0 L6,0 C4.9,0 4,0.9 4,2 L4,14 C4,15.1 4.9,16 6,16 L18,16 C19.1,16 20,15.1 20,14 L20,2 Z M18.5,14 C18.5,14.28 18.28,14.5 18,14.5 L6,14.5 C5.72,14.5 5.5,14.28 5.5,14 L5.5,2 C5.5,1.72 5.72,1.5 6,1.5 L18,1.5 C18.28,1.5 18.5,1.72 18.5,2 L18.5,14 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M0.5,4.75 L0.5,16.75 C0.5,18.27 1.73,19.5 3.25,19.5 L15.25,19.5 C15.66,19.5 16,19.16 16,18.75 C16,18.34 15.66,18 15.25,18 L3.25,18 C2.56,18 2,17.44 2,16.75 L2,4.75 C2,4.34 1.66,4 1.25,4 C0.84,4 0.5,4.34 0.5,4.75 Z"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml
index ae5cc2b..30f29f7 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml
@@ -30,4 +30,12 @@
     <string name="config_batterymeterPowersavePath" translatable="false">
         M 3.75,11.25 H 5.25 V 12.75 C 5.25,13.16 5.59,13.5 6,13.5 6.41,13.5 6.75,13.16 6.75,12.75 V 11.25 H 8.25 C 8.66,11.25 9,10.91 9,10.5 9,10.09 8.6601,9.75 8.25,9.75 H 6.75 V 8.25 C 6.75,7.84 6.41,7.5 6,7.5 5.59,7.5 5.25,7.84 5.25,8.25 V 9.75 H 3.75 C 3.34,9.75 3,10.09 3,10.5 3,10.91 3.34,11.25 3.75,11.25 Z
     </string>
+    <!-- X path for SignalDrawable as defined on a 24x24 canvas. -->
+    <string name="config_signalXPath" translatable="false">
+        M 17.81,18.75 L 19.81,16.75 C 20.01,16.56 20.09,16.28 20.02,16.02 C 19.96,15.75 19.75,15.54 19.48,15.47 C 19.22,15.41 18.94,15.49 18.75,15.69 L 16.75,17.69 L 14.75,15.69 C 14.56,15.49 14.28,15.41 14.02,15.47 C 13.75,15.54 13.54,15.75 13.47,16.02 C 13.41,16.28 13.49,16.56 13.69,16.75 L 15.69,18.75 L 13.69,20.75 C 13.4,21.04 13.4,21.52 13.69,21.81 C 13.98,22.1 14.46,22.1 14.75,21.81 L 16.75,19.81 L 18.75,21.81 C 19.04,22.1 19.52,22.1 19.81,21.81 C 20.1,21.52 20.1,21.04 19.81,20.75 Z
+    </string>
+    <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that
+         should be cut out to display config_signalXPath.-->
+    <item name="config_signalCutoutWidthFraction" format="float" type="dimen">10.5</item>
+    <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item>
 </resources>
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/Android.mk b/packages/overlays/IconPackCircularLauncherOverlay/Android.mk
index 310bdef..d736d7d 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/Android.mk
+++ b/packages/overlays/IconPackCircularLauncherOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackCircularLauncherOverlay
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/Android.mk b/packages/overlays/IconPackCircularSettingsOverlay/Android.mk
index d067322..ea2da30 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/Android.mk
+++ b/packages/overlays/IconPackCircularSettingsOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackCircularSettingsOverlay
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other_32dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other_32dp.xml
new file mode 100644
index 0000000..f0754ed
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other_32dp.xml
@@ -0,0 +1,32 @@
+<?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:height="32dp"
+    android:tint="?android:attr/colorAccent"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="32dp">
+    <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_devices_other_opaque_black.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other_opaque_black.xml
deleted file mode 100644
index 5828806..0000000
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other_opaque_black.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:height="24dp"
-    android:tint="@android:color/black"
-    android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp" >
-    <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_scan_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_scan_24dp.xml
new file mode 100644
index 0000000..f160fe9
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_scan_24dp.xml
@@ -0,0 +1,55 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorAccent"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="3.000000"
+        android:translateY="3.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M1.5,4.5 L1.5,1.9 C1.5,1.6790861 1.6790861,1.5 1.9,1.5 L4.1,1.5 C4.3209139,1.5 4.5,1.6790861 4.5,1.9 L4.5,4.5 L1.5,4.5 L1.5,4.5 Z M0,6 L6,6 L6,1.5 C6,0.671572875 5.32842712,0 4.5,0 L1.5,0 C0.671572875,0 0,0.671572875 0,1.5 L0,6 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M13.5,4.5 L13.5,1.9 C13.5,1.6790861 13.6790861,1.5 13.9,1.5 L16.1,1.5 C16.3209139,1.5 16.5,1.6790861 16.5,1.9 L16.5,4.5 L13.5,4.5 L13.5,4.5 Z M12,6 L18,6 L18,1.5 C18,0.671572875 17.3284271,0 16.5,0 L13.5,0 C12.6715729,0 12,0.671572875 12,1.5 L12,6 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M4.5,13.5 L4.5,16.1 C4.5,16.3209139 4.3209139,16.5 4.1,16.5 L1.9,16.5 C1.6790861,16.5 1.5,16.3209139 1.5,16.1 L1.5,13.5 L4.5,13.5 L4.5,13.5 Z M6,12 L0,12 L0,16.5 C0,17.3284271 0.671572875,18 1.5,18 L4.5,18 C5.32842712,18 6,17.3284271 6,16.5 L6,12 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M 2 8 L 0 8 L 0 10 L 2 10 L 2 8 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M9,0 C8.58803794,0.00538581231 8.25538581,0.338037936 8.25,0.75 L8.25,5.75 C8.25000002,6.16421355 8.58578645,6.49999997 9,6.49999997 C9.41421355,6.49999997 9.74999998,6.16421355 9.75,5.75 L9.75,0.75 C9.74461419,0.338037936 9.41196206,0.00538581231 9,0 L9,0 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M13.75,12.25 L17.25,12.25 C17.6619621,12.2553858 17.9946142,12.5880379 18,13 C17.9946142,13.4119621 17.6619621,13.7446142 17.25,13.75 L13.75,13.75 L13.75,17.25 C13.75,17.6642136 13.4142136,18 13,18 C12.5857864,18 12.25,17.6642136 12.25,17.25 L12.25,13.75 L8.74999997,13.75 C8.33578642,13.75 8,13.4142136 8,13 C8,12.5857864 8.33578642,12.25 8.74999997,12.25 L12.25,12.25 L12.25,8.75 C12.2553858,8.33803794 12.5880379,8.00538581 13,8 C13.4119621,8.00538581 13.7446142,8.33803794 13.75,8.75 L13.75,12.25 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M 6 8 L 4 8 L 4 10 L 6 10 L 6 8 Z"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml
new file mode 100644
index 0000000..0572fb7
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml
@@ -0,0 +1,37 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="1.000000"
+        android:translateY="2.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M11,18.5 C6.313,18.5 2.5,14.687 2.5,10 C2.5,8.182 3.078,6.498 4.055,5.114 L15.887,16.945 C14.503,17.922 12.818,18.5 11,18.5 M20.031,18.969 L2.032,0.971 C1.739,0.678 1.264,0.678 0.971,0.971 C0.678,1.264 0.678,1.738 0.971,2.031 L2.983,4.043 C1.742,5.707 1,7.765 1,10 C1,15.522 5.477,20 11,20 C13.236,20 15.293,19.258 16.957,18.017 L18.971,20.029 C19.117,20.176 19.309,20.249 19.501,20.249 C19.693,20.249 19.885,20.176 20.031,20.029 C20.324,19.736 20.324,19.262 20.031,18.969"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M11,1.5 C15.687,1.5 19.5,5.313 19.5,10 C19.5,11.782 18.946,13.436 18.006,14.804 L19.078,15.877 C20.281,14.226 21,12.199 21,10 C21,4.478 16.522,0 11,0 C8.801,0 6.774,0.719 5.124,1.922 L6.196,2.994 C7.564,2.054 9.218,1.5 11,1.5"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml
new file mode 100644
index 0000000..41962b2
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml
@@ -0,0 +1,37 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="2.000000"
+        android:translateY="2.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M12.25,0.2637 L12.25,1.8127 C15.847,2.8017 18.5,6.0927 18.5,9.9997 C18.5,14.6867 14.687,18.4997 10,18.4997 C5.313,18.4997 1.5,14.6867 1.5,9.9997 C1.5,6.0927 4.153,2.8017 7.75,1.8127 L7.75,0.2637 C3.312,1.2847 0,5.2517 0,9.9997 C0,15.5227 4.477,19.9997 10,19.9997 C15.523,19.9997 20,15.5227 20,9.9997 C20,5.2517 16.687,1.2847 12.25,0.2637"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M15.0303,9.9697 C14.7373,9.6767 14.2623,9.6767 13.9693,9.9697 L10.7503,13.1897 L10.7503,0.7387 C10.7503,0.3307 10.4143,-0.0003 10.0003,-0.0003 C9.5863,-0.0003 9.2503,0.3307 9.2503,0.7387 L9.2503,13.1897 L6.0303,9.9697 C5.7373,9.6767 5.2623,9.6767 4.9693,9.9697 C4.6763,10.2627 4.6763,10.7377 4.9693,11.0307 L10.0003,16.0607 L15.0303,11.0307 C15.3233,10.7377 15.3233,10.2627 15.0303,9.9697"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
new file mode 100644
index 0000000..a0233ba
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
@@ -0,0 +1,37 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="4.000000"
+        android:translateY="3.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M12.9902,13.5098 C12.9902,13.7858 12.7652,14.0098 12.4902,14.0098 C12.2142,14.0098 11.9902,13.7858 11.9902,13.5098 L11.9902,11.5098 C11.9902,11.2348 12.2142,11.0098 12.4902,11.0098 C12.7652,11.0098 12.9902,11.2348 12.9902,11.5098 L12.9902,13.5098 Z M12.4902,16.0098 C12.2142,16.0098 11.9902,15.7858 11.9902,15.5098 C11.9902,15.2348 12.2142,15.0098 12.4902,15.0098 C12.7652,15.0098 12.9902,15.2348 12.9902,15.5098 C12.9902,15.7858 12.7652,16.0098 12.4902,16.0098 L12.4902,16.0098 Z M15.5182,11.7848 C15.8372,10.9048 16.0102,9.9558 16.0102,8.9698 C16.0102,6.0698 14.5002,3.4798 12.1102,2.0098 L14.5102,2.0098 C14.9102,1.9998 15.2502,1.6598 15.2502,1.2498 C15.2502,0.8398 14.9102,0.4998 14.5002,0.4998 L9.2502,0.4998 L9.2502,6.2498 C9.2502,6.6598 9.5902,6.9998 10.0002,6.9998 C10.4102,6.9998 10.7502,6.6598 10.7502,6.2498 L10.7502,2.9398 C13.0302,4.0598 14.5002,6.3698 14.5002,8.9698 C14.5002,9.5068 14.4172,10.0238 14.2982,10.5268 C13.7682,10.2048 13.1542,10.0098 12.4902,10.0098 C10.5562,10.0098 8.9902,11.5768 8.9902,13.5098 C8.9902,15.4438 10.5562,17.0098 12.4902,17.0098 C14.4232,17.0098 15.9902,15.4438 15.9902,13.5098 C15.9902,12.8798 15.8092,12.2958 15.5182,11.7848 L15.5182,11.7848 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M6.3901,1.04 C2.6301,1.91 0.0001,5.21 0.0001,9.07 C0.0001,11.65 1.2001,13.98 3.1301,15.5 L1.5001,15.5 C1.0901,15.5 0.7501,15.84 0.7501,16.25 C0.7501,16.66 1.0901,17 1.5001,17 L6.7501,17 L6.7501,11.75 C6.7501,11.34 6.4101,11 6.0001,11 C5.5901,11 5.2501,11.34 5.2501,11.75 L5.2501,15.09 C2.9701,13.97 1.5001,11.66 1.5001,9.06 C1.5001,5.91 3.6501,3.21 6.7301,2.5 C7.1301,2.41 7.3901,2 7.2901,1.6 C7.2001,1.2 6.8001,0.95 6.3901,1.04"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/Android.mk b/packages/overlays/IconPackCircularSystemUIOverlay/Android.mk
index 5e0dcbe..9045e8e 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/Android.mk
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackCircularSystemUIOverlay
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
new file mode 100644
index 0000000..e210bcb0
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
@@ -0,0 +1,51 @@
+<?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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="2.000000"
+        android:translateY="4.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M3.75,11.5 L13.25,11.5 C13.664,11.5 14,11.836 14,12.25 C14,12.664 13.664,13 13.25,13 L3.75,13 C3.336,13 3,12.664 3,12.25 C3,11.836 3.336,11.5 3.75,11.5"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M3.75,8.5 L3.75,8.5 C4.164,8.5 4.5,8.836 4.5,9.25 C4.5,9.664 4.164,10 3.75,10 C3.336,10 3,9.664 3,9.25 C3,8.836 3.336,8.5 3.75,8.5"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M17,12.25 L17,12.25 C17,12.664 16.664,13 16.25,13 C15.836,13 15.5,12.664 15.5,12.25 C15.5,11.836 15.836,11.5 16.25,11.5 C16.664,11.5 17,11.836 17,12.25"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M17,9.25 L17,9.25 C17,9.664 16.664,10 16.25,10 L6.75,10 C6.336,10 6,9.664 6,9.25 C6,8.836 6.336,8.5 6.75,8.5 L16.25,8.5 C16.664,8.5 17,8.836 17,9.25"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M18,0 L2,0 C0.896,0 0,0.896 0,2 L0,14 C0,15.104 0.896,16 2,16 L18,16 C19.104,16 20,15.104 20,14 L20,2 C20,0.896 19.104,0 18,0 M18,1.5 C18.275,1.5 18.5,1.725 18.5,2 L18.5,14 C18.5,14.275 18.275,14.5 18,14.5 L2,14.5 C1.725,14.5 1.5,14.275 1.5,14 L1.5,2 C1.5,1.725 1.725,1.5 2,1.5 L18,1.5"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
new file mode 100644
index 0000000..660f64a
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
@@ -0,0 +1,56 @@
+<?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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="1.000000"
+        android:translateY="2.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M19,3.5 C19.275,3.5 19.5,3.725 19.5,4 L19.5,16 C19.5,16.09 19.47,16.17 19.428,16.244 L20.497,17.313 C20.807,16.961 21,16.506 21,16 L21,4 C21,2.896 20.104,2 19,2 L5.184,2 L6.684,3.5 L19,3.5 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M19,3.5 C19.275,3.5 19.5,3.725 19.5,4 L19.5,16 C19.5,16.09 19.47,16.17 19.428,16.244 L20.497,17.313 C20.807,16.961 21,16.506 21,16 L21,4 C21,2.896 20.104,2 19,2 L5.184,2 L6.684,3.5 L19,3.5 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M18,14.25 C18,13.836 17.664,13.5 17.25,13.5 C17.091,13.5 16.951,13.561 16.829,13.646 L17.854,14.671 C17.939,14.549 18,14.409 18,14.25"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M4.75,12 C5.164,12 5.5,11.664 5.5,11.25 C5.5,10.836 5.164,10.5 4.75,10.5 C4.336,10.5 4,10.836 4,11.25 C4,11.664 4.336,12 4.75,12"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M3,16.5 C2.725,16.5 2.5,16.275 2.5,16 L2.5,4 C2.5,3.878 2.549,3.77 2.622,3.684 L9.439,10.5 L7.75,10.5 C7.336,10.5 7,10.836 7,11.25 C7,11.664 7.336,12 7.75,12 L10.939,12 L12.439,13.5 L4.75,13.5 C4.336,13.5 4,13.836 4,14.25 C4,14.664 4.336,15 4.75,15 L13.939,15 L15.44,16.5 L3,16.5 Z M20.03,18.969 L2.03,0.971 C1.737,0.678 1.263,0.678 0.97,0.971 C0.677,1.264 0.677,1.738 0.97,2.031 L1.558,2.619 C1.214,2.979 1,3.463 1,4 L1,16 C1,17.104 1.896,18 3,18 L16.94,18 L18.97,20.029 C19.116,20.176 19.308,20.249 19.5,20.249 C19.692,20.249 19.884,20.176 20.03,20.029 C20.323,19.736 20.323,19.262 20.03,18.969 L20.03,18.969 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M17.25,12 C17.664,12 18,11.664 18,11.25 C18,10.836 17.664,10.5 17.25,10.5 L13.684,10.5 L15.184,12 L17.25,12 Z"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularThemePickerOverlay/Android.mk b/packages/overlays/IconPackCircularThemePickerOverlay/Android.mk
index 412c26f..c2d472d 100644
--- a/packages/overlays/IconPackCircularThemePickerOverlay/Android.mk
+++ b/packages/overlays/IconPackCircularThemePickerOverlay/Android.mk
@@ -21,8 +21,6 @@
 LOCAL_CERTIFICATE := platform
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackCircularThemePickerOverlay
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/Android.mk b/packages/overlays/IconPackFilledAndroidOverlay/Android.mk
index 3036f7d..78db765 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/Android.mk
+++ b/packages/overlays/IconPackFilledAndroidOverlay/Android.mk
@@ -20,8 +20,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackFilledAndroidOverlay
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
index df79827..8ff3c1c 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
@@ -22,5 +22,5 @@
     android:width="24dp" >
     <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" />
+        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/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
index 58800c8..18a60d8 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
@@ -22,5 +22,5 @@
     android:width="24dp" >
     <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" />
+        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/IconPackFilledAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
new file mode 100644
index 0000000..5eea889
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_ui_mode_night.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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <path
+        android:fillColor="@android:color/white"
+        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,2z M12,20V4c4.41,0,8,3.59,8,8 C20,16.41,16.41,20,12,20z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
index 58800c8..18a60d8 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
@@ -22,5 +22,5 @@
     android:width="24dp" >
     <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" />
+        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/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml
new file mode 100644
index 0000000..3f5c75b
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml
@@ -0,0 +1,27 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <path android:pathData="M0 0h24v24H0z" />
+    <path
+        android:fillColor="@android:color/white"
+        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.51 V5h4v2zM4 6H2v14c0 1.1 0.9 2 2 2h14v-2H4V6z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml
index 6b59b62..f1d8c73 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml
@@ -33,4 +33,12 @@
         M 9,11 C 9,11.55 8.55,12 8,12 H 7 V 13 C 7,13.55 6.55,14 6,14 5.45,14 5,13.55 5,13 V 12 H 4 C 3.45,12 3,11.55 3,11 3,10.45 3.45,10.005 4,10 H 5 V 9 C 5,8.45 5.45,8 6,8 6.55,8 7,8.45 7,9 V 10 H 8 C 8.55,10 9,10.45 9,11 Z
     </string>
     <bool name="config_batterymeterDualTone">true</bool>
+    <!-- X path for SignalDrawable as defined on a 24x24 canvas. -->
+    <string name="config_signalXPath" translatable="false">
+        M 21.7,20.28 L 19.92,18.5 L 21.7,16.72 C 22.1,16.32 22.1,15.68 21.71,15.29 C 21.32,14.9 20.68,14.9 20.28,15.3 L 18.5,17.08 L 16.72,15.3 C 16.32,14.9 15.68,14.9 15.29,15.29 C 14.9,15.68 14.9,16.32 15.3,16.72 L 17.08,18.5 L 15.3,20.28 C 14.9,20.68 14.9,21.32 15.29,21.71 C 15.68,22.1 16.32,22.1 16.72,21.7 L 18.5,19.92 L 20.28,21.7 C 20.68,22.1 21.32,22.1 21.71,21.71 C 22.1,21.32 22.1,20.68 21.7,20.28
+    </string>
+    <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that
+         should be cut out to display config_signalXPath.-->
+    <item name="config_signalCutoutWidthFraction" format="float" type="dimen">11</item>
+    <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item>
 </resources>
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/Android.mk b/packages/overlays/IconPackFilledLauncherOverlay/Android.mk
index 2460fa4..16b8f52 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/Android.mk
+++ b/packages/overlays/IconPackFilledLauncherOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackFilledLauncherOverlay
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/Android.mk b/packages/overlays/IconPackFilledSettingsOverlay/Android.mk
index 3cc071d..d4e9000 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/Android.mk
+++ b/packages/overlays/IconPackFilledSettingsOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackFilledSettingsOverlay
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other_32dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other_32dp.xml
new file mode 100644
index 0000000..c78050e
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other_32dp.xml
@@ -0,0 +1,32 @@
+<?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:height="32dp"
+    android:tint="?android:attr/colorAccent"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="32dp">
+    <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_devices_other_opaque_black.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other_opaque_black.xml
deleted file mode 100644
index e65b119..0000000
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other_opaque_black.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:height="24dp"
-    android:tint="@android:color/black"
-    android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp" >
-    <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_scan_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_scan_24dp.xml
new file mode 100644
index 0000000..146e20f
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_scan_24dp.xml
@@ -0,0 +1,27 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorAccent"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M4,9 L8,9 C8.55228475,9 9,8.55228475 9,8 L9,4 C9,3.44771525 8.55228475,3 8,3 L4,3 C3.44771525,3 3,3.44771525 3,4 L3,8 C3,8.55228475 3.44771525,9 4,9 Z M5,5 L7,5 L7,7 L5,7 L5,5 Z M15,4 L15,8 C15,8.55228475 15.4477153,9 16,9 L20,9 C20.5522847,9 21,8.55228475 21,8 L21,4 C21,3.44771525 20.5522847,3 20,3 L16,3 C15.4477153,3 15,3.44771525 15,4 Z M19,7 L17,7 L17,5 L19,5 L19,7 Z M4,21 L8,21 C8.55228475,21 9,20.5522847 9,20 L9,16 C9,15.4477153 8.55228475,15 8,15 L4,15 C3.44771525,15 3,15.4477153 3,16 L3,20 C3,20.5522847 3.44771525,21 4,21 Z M5,17 L7,17 L7,19 L5,19 L5,17 Z M7.4,11 L8.6,11 C8.8209139,11 9,11.1790861 9,11.4 L9,12.6 C9,12.8209139 8.8209139,13 8.6,13 L7.4,13 C7.1790861,13 7,12.8209139 7,12.6 L7,11.4 C7,11.1790861 7.1790861,11 7.4,11 Z M4.6,13 L3.4,13 C3.1790861,13 3,12.8209139 3,12.6 L3,11.4 C3,11.1790861 3.1790861,11 3.4,11 L4.6,11 C4.8209139,11 5,11.1790861 5,11.4 L5,12.6 C5,12.8209139 4.8209139,13 4.6,13 L4.6,13 Z M11.6,9 C11.2686292,9 11,8.73137085 11,8.4 L11,3.6 C11,3.26862915 11.2686292,3 11.6,3 L12.4,3 C12.7313708,3 13,3.26862915 13,3.6 L13,8.4 C13,8.73137085 12.7313708,9 12.4,9 L11.6,9 Z M17,15 L20.5,15 C20.7761424,15 21,15.2238576 21,15.5 L21,16.5 C21,16.7761424 20.7761424,17 20.5,17 L17,17 L17,20.5 C17,20.7761424 16.7761424,21 16.5,21 L15.5,21 C15.2238576,21 15,20.7761424 15,20.5 L15,17 L11.5,17 C11.2238576,17 11,16.7761424 11,16.5 L11,15.5 C11,15.2238576 11.2238576,15 11.5,15 L15,15 L15,11.5 C15,11.2238576 15.2238576,11 15.5,11 L16.5,11 C16.7761424,11 17,11.2238576 17,11.5 L17,15 Z"
+        android:strokeWidth="1" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml
new file mode 100644
index 0000000..b816e4e
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml
@@ -0,0 +1,36 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:scaleX="-1"
+        android:translateX="-12.000000"
+        android:translateY="-12.000000" >
+        <path
+            android:fillType="evenOdd"
+            android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z"
+            android:strokeWidth="1" />
+    </group>
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M12.11,2 C10.33,2 8.67,2.46 7.22,3.28 L8.7,4.76 C9.74,4.28 10.89,4 12.11,4 C16.52,4 20.11,7.59 20.11,12 C20.11,13.22 19.83,14.37 19.35,15.41 L20.83,16.89 C21.65,15.44 22.11,13.78 22.11,12 C22.11,6.48 17.63,2 12.11,2 Z M18.23,17.13 L6.98,5.87 L4.12750442,3.01750442 C3.73635677,2.62635677 3.10252735,2.62523693 2.71,3.015 C2.31926097,3.40298735 2.31703029,4.0342698 2.70501764,4.42500883 C2.70584509,4.42584216 2.70667402,4.42667402 2.70750442,4.42750442 L4.19,5.91 C2.88,7.59 2.11,9.71 2.11,12 C2.11,17.52 6.59,22 12.11,22 C14.4,22 16.52,21.23 18.2,19.92 L19.685,21.405 C20.0743607,21.7943607 20.7056393,21.7943607 21.095,21.405 C21.4843607,21.0156393 21.4843607,20.3843607 21.095,19.995 L18.23,17.13 Z M12.11,20 C7.7,20 4.11,16.41 4.11,12 C4.11,10.26 4.67,8.65 5.62,7.34 L16.77,18.49 C15.46,19.44 13.85,20 12.11,20 Z M8.7,4.76 L7.22,3.28 L8.7,4.76 Z"
+        android:strokeWidth="1" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml
new file mode 100644
index 0000000..d0b6209
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml
@@ -0,0 +1,36 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:scaleX="-1"
+        android:translateX="-12.000000"
+        android:translateY="-12.000000" >
+        <path
+            android:fillType="evenOdd"
+            android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z"
+            android:strokeWidth="1" />
+    </group>
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M13.0016705,11.5012475 L15.3917467,11.5012475 C15.9314188,11.5012475 16.206996,12.1426752 15.8165949,12.5140281 L12.4292913,15.822445 C12.1961989,16.0553846 11.8138355,16.0598858 11.5761501,15.8314475 C11.5738536,15.8280716 11.5704089,15.8258209 11.5681124,15.822445 L8.17851232,12.5117775 C7.79729714,12.1392993 8.06713319,11.5012475 8.60565705,11.5012475 L11.002341,11.5012475 L11.002341,2.99966471 C11.002341,2.44756514 11.4499062,2 12.0020057,2 C12.5541053,2 13.0016705,2.44756514 13.0016705,2.99966471 L13.0016705,11.5012475 Z M15,2.46 L15,4.59 C17.93,5.78 20,8.65 20,12 C20,16.41 16.41,20 12,20 C7.59,20 4,16.41 4,12 C4,8.65 6.07,5.78 9,4.59 L9,2.46 C4.94,3.74 2,7.53 2,12 C2,17.52 6.48,22 12,22 C17.52,22 22,17.52 22,12 C22,7.53 19.06,3.74 15,2.46 Z"
+        android:strokeWidth="1" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
new file mode 100644
index 0000000..f2dd9e8
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
@@ -0,0 +1,27 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <path android:pathData="M0 0h24v24H0z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M3 12c0 2.21 0.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24C5.68 15.15 5 13.66 5 12c0-2.61 1.67-4.83 4-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24C18.32 8.85 19 10.34 19 12c0 2.61-1.67 4.83-4 5.65v2.09c3.45-0.89 6-4.01 6-7.74 0-2.21-0.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/Android.mk b/packages/overlays/IconPackFilledSystemUIOverlay/Android.mk
index f027692..35e157a 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/Android.mk
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackFilledSystemUIOverlay
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
new file mode 100644
index 0000000..42ef41c
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
@@ -0,0 +1,31 @@
+<?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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="2.000000"
+        android:translateY="4.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M8,8 L16,8 L16,6 L8,6 L8,8 Z M14,12 L16,12 L16,10 L14,10 L14,12 Z M4,12 L12,12 L12,10 L4,10 L4,12 Z M4,8 L6,8 L6,6 L4,6 L4,8 Z M18,0 L2,0 C0.9,0 0,0.9 0,2 L0,14 C0,15.1 0.9,16 2,16 L18,16 C19.1,16 20,15.1 20,14 L20,2 C20,0.9 19.1,0 18,0 L18,0 Z"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
new file mode 100644
index 0000000..f164ba8
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
@@ -0,0 +1,29 @@
+<?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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group android:translateY="2.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M6,14 L13.17,14 L11.17,12 L6,12 L6,14 Z M6,8 L6,10 L8,10 L8,8.83 L7.17,8 L6,8 Z M1.293,0.7085 C1.68545692,0.318530482 2.3194559,0.319620835 2.71056916,0.71093794 L20.4851837,18.4948164 C20.8744727,18.8843082 20.8743905,19.5156095 20.485,19.905 C20.0956393,20.2943607 19.4643607,20.2943607 19.075,19.905 L17.17,18 L4,18 C2.9,18 2,17.1 2,16 L2,4 C2,3.663 2.092,3.35 2.241,3.071 L1.29096704,2.12154004 C1.29014848,2.12072198 1.28933135,2.11990248 1.28851564,2.11908157 C0.900232614,1.7283219 0.902240332,1.09678302 1.293,0.7085 Z M6.82,2 L20,2 C21.1,2 22,2.9 22,4 L22,16 C22,16.342 21.905,16.659 21.753,16.94 L18,13.187 L18,12 L16.814,12 L14.815,10 L18,10 L18,8 L12.816,8 L8.819,4 L6.82,2 Z"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledThemePickerOverlay/Android.mk b/packages/overlays/IconPackFilledThemePickerOverlay/Android.mk
index 6d15603..835d35e 100644
--- a/packages/overlays/IconPackFilledThemePickerOverlay/Android.mk
+++ b/packages/overlays/IconPackFilledThemePickerOverlay/Android.mk
@@ -21,8 +21,6 @@
 LOCAL_CERTIFICATE := platform
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackFilledThemePickerOverlay
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/Android.mk b/packages/overlays/IconPackRoundedAndroidOverlay/Android.mk
index c6ad4ac..70d6fc4 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/Android.mk
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/Android.mk
@@ -20,8 +20,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackRoundedAndroidOverlay
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
new file mode 100644
index 0000000..3cf7541
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
@@ -0,0 +1,27 @@
+<?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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <path
+        android:fillColor="@android:color/white"
+        android:fillType="evenOdd"
+        android:pathData="M12,20.5 L12,3.5 C16.687,3.5 20.5,7.313 20.5,12 C20.5,16.687 16.687,20.5 12,20.5 M12,2 C10.619,2 9.304,2.279 8.107,2.786 C7.51,3.039 6.941,3.349 6.409,3.708 C6.143,3.888 5.886,4.08 5.639,4.283 C4.651,5.099 3.822,6.1 3.207,7.233 C2.899,7.8 2.645,8.4 2.449,9.026 C2.255,9.652 2.12,10.305 2.052,10.978 C2.018,11.313 2,11.654 2,12 C2,17.522 6.478,22 12,22 C17.522,22 22,17.522 22,12 C22,6.478 17.522,2 12,2"
+        android:strokeWidth="1" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml
new file mode 100644
index 0000000..8cd240d
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml
@@ -0,0 +1,40 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="2.000000"
+        android:translateY="2.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M18,0 L6,0 C4.9,0 4,0.9 4,2 L4,14 C4,15.1 4.9,16 6,16 L18,16 C19.1,16 20,15.1 20,14 L20,2 C20,0.9 19.1,0 18,0 Z M18.5,14 C18.5,14.28 18.28,14.5 18,14.5 L6,14.5 C5.72,14.5 5.5,14.28 5.5,14 L5.5,2 C5.5,1.72 5.72,1.5 6,1.5 L18,1.5 C18.28,1.5 18.5,1.72 18.5,2 L18.5,14 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M15.86,3.10740288 C15.7704,3.02963963 15.6528,2.990758 15.5352,3.00186703 L13.0152,3.27959295 C12.8024,3.30736554 12.64,3.48511013 12.64,3.69618182 L12.64,9.056292 C12.2536,8.75079349 11.772,8.55638535 11.24,8.55638535 C10.0024,8.55638535 9,9.55064413 9,10.7781927 C9,12.0057412 10.0024,13 11.24,13 C12.4776,13 13.48,12.0057412 13.48,10.7781927 L13.48,5.01241596 L15.6248,4.77912619 C15.8376,4.7513536 16,4.57360901 16,4.36253732 L16,3.41845591 C16,3.30181102 15.9496,3.18516614 15.86,3.10740288 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M15.25,18 L3.25,18 C2.56,18 2,17.44 2,16.75 L2,4.75 C2,4.34 1.66,4 1.25,4 C0.84,4 0.5,4.34 0.5,4.75 L0.5,16.75 C0.5,18.27 1.73,19.5 3.25,19.5 L15.25,19.5 C15.66,19.5 16,19.16 16,18.75 C16,18.34 15.66,18 15.25,18 Z"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml
index ebcac82..b7bfaad 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml
@@ -30,4 +30,12 @@
     <string name="config_batterymeterPowersavePath" translatable="false">
         M 3.75,11.25 H 5.25 V 12.75 C 5.25,13.16 5.59,13.5 6,13.5 6.41,13.5 6.75,13.16 6.75,12.75 V 11.25 H 8.25 C 8.66,11.25 9,10.91 9,10.5 9,10.09 8.66,9.7499 8.25,9.7499 H 6.75 V 8.2499 C 6.75,7.8399 6.41,7.4999 6,7.4999 5.59,7.4999 5.2794,7.841 5.25,8.2499 V 9.7499 H 3.75 C 3.34,9.7499 3,10.09 3,10.5 3,10.91 3.3401,11.25 3.75,11.25 Z
     </string>
+    <!-- X path for SignalDrawable as defined on a 24x24 canvas. -->
+    <string name="config_signalXPath" translatable="false">
+        M 20.72,16.22 L 19,17.94 L 17.28,16.22 C 16.99,15.93 16.51,15.93 16.22,16.22 C 15.93,16.51 15.93,16.99 16.22,17.28 L 17.94,19 L 16.22,20.72 C 15.93,21.01 15.93,21.49 16.22,21.78 C 16.37,21.93 16.56,22 16.75,22 C 16.94,22 17.13,21.93 17.28,21.78 L 19,20.06 L 20.72,21.78 C 20.87,21.93 21.06,22 21.25,22 C 21.44,22 21.63,21.93 21.78,21.78 C 22.07,21.49 22.07,21.01 21.78,20.72 L 20.06,19 L 21.78,17.28 C 22.07,16.99 22.07,16.51 21.78,16.22 C 21.49,15.93 21.01,15.93 20.72,16.22 Z
+    </string>
+    <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that
+         should be cut out to display config_signalXPath.-->
+    <item name="config_signalCutoutWidthFraction" format="float" type="dimen">10</item>
+    <item name="config_signalCutoutHeightFraction" format="float" type="dimen">10</item>
 </resources>
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/Android.mk b/packages/overlays/IconPackRoundedLauncherOverlay/Android.mk
index 713e281..63de27f 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/Android.mk
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackRoundedLauncherOverlay
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/Android.mk b/packages/overlays/IconPackRoundedSettingsOverlay/Android.mk
index 6c77519..c59bf7d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/Android.mk
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackRoundedSettingsOverlay
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other_32dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other_32dp.xml
new file mode 100644
index 0000000..dfd4b20
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other_32dp.xml
@@ -0,0 +1,32 @@
+<?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:height="32dp"
+    android:tint="?android:attr/colorAccent"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="32dp">
+    <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_devices_other_opaque_black.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other_opaque_black.xml
deleted file mode 100644
index 05a0989..0000000
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other_opaque_black.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:height="24dp"
-    android:tint="@android:color/black"
-    android:viewportHeight="24"
-    android:viewportWidth="24"
-    android:width="24dp" >
-    <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_find_in_page_24px.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
index a54c0f0..36d5c7c 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
@@ -26,7 +26,7 @@
         <path
             android:fillColor="@android:color/white"
             android:fillType="evenOdd"
-            android:pathData="M8,15.25 C6.208,15.25 4.75,13.792 4.75,12 C4.75,10.208 6.208,8.75 8,8.75 C9.792,8.75 11.25,10.208 11.25,12 C11.25,13.792 9.792,15.25 8,15.25 L8,15.25 Z M1.5,18 L1.5,2 C1.5,1.725 1.725,1.5 2,1.5 L9.379,1.5 L14.5,6.621 L14.5,17.439 L11.837,14.776 C12.405,13.993 12.75,13.039 12.75,12 C12.75,9.381 10.619,7.25 8,7.25 C5.381,7.25 3.25,9.381 3.25,12 C3.25,14.619 5.381,16.75 8,16.75 C9.039,16.75 9.993,16.405 10.776,15.837 L13.439,18.5 L2,18.5 C1.725,18.5 1.5,18.275 1.5,18 L1.5,18 Z M10,0 L2,0 C0.896,0 0,0.896 0,2 L0,18 C0,19.104 0.896,20 2,20 L14,20 C15.104,20 16,19.104 16,18 L16,6 L10,0 Z"
+            android:pathData="M8.0001,15.25 C6.2081,15.25 4.7501,13.792 4.7501,12 C4.7501,10.208 6.2081,8.75 8.0001,8.75 C9.7921,8.75 11.2501,10.208 11.2501,12 C11.2501,13.792 9.7921,15.25 8.0001,15.25 L8.0001,15.25 Z M1.5001,18.5 L1.5001,1.5 L9.3791,1.5 L14.5001,6.621 L14.5001,17.439 L11.8371,14.776 C12.5921,13.735 12.9531,12.393 12.6341,10.949 C12.2191,9.075 10.6391,7.595 8.7411,7.307 C5.5431,6.82 2.8181,9.547 3.3071,12.745 C3.5971,14.642 5.0781,16.221 6.9521,16.634 C8.3941,16.952 9.7361,16.592 10.7761,15.837 L13.4391,18.5 L1.5001,18.5 Z M10.0001,0 L1.5001,0 C0.6721,0 0.0001,0.672 0.0001,1.5 L0.0001,18.5 C0.0001,19.328 0.6721,20 1.5001,20 L14.5001,20 C15.3281,20 16.0001,19.328 16.0001,18.5 L16.0001,6 L10.0001,0 Z"
             android:strokeWidth="1" />
     </group>
 </vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_scan_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_scan_24dp.xml
new file mode 100644
index 0000000..3d79f79
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_scan_24dp.xml
@@ -0,0 +1,55 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorAccent"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="3.000000"
+        android:translateY="3.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M4.5,1.5 L4.5,4.5 L1.5,4.5 L1.5,1.5 L4.5,1.5 L4.5,1.5 Z M5,0 L1,0 C0.44771525,0 0,0.44771525 0,1 L0,5 C0,5.55228475 0.44771525,6 1,6 L5,6 C5.55228475,6 6,5.55228475 6,5 L6,1 C6,0.44771525 5.55228475,0 5,0 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M16.5,1.5 L16.5,4.5 L13.5,4.5 L13.5,1.5 L16.5,1.5 L16.5,1.5 Z M17,0 L13,0 C12.4477153,0 12,0.44771525 12,1 L12,5 C12,5.55228475 12.4477153,6 13,6 L17,6 C17.5522847,6 18,5.55228475 18,5 L18,1 C18,0.44771525 17.5522847,0 17,0 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M4.5,13.5 L4.5,16.5 L1.5,16.5 L1.5,13.5 L4.5,13.5 L4.5,13.5 Z M5,12 L1,12 C0.44771525,12 0,12.4477153 0,13 L0,17 C0,17.5522847 0.44771525,18 1,18 L5,18 C5.55228475,18 6,17.5522847 6,17 L6,13 C6,12.4477153 5.55228475,12 5,12 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M13.75,12.25 L17.25,12.25 C17.6619621,12.2553858 17.9946142,12.5880379 18,13 C17.9946142,13.4119621 17.6619621,13.7446142 17.25,13.75 L13.75,13.75 L13.75,17.25 C13.75,17.6642136 13.4142136,18 13,18 C12.5857864,18 12.25,17.6642136 12.25,17.25 L12.25,13.75 L8.74999997,13.75 C8.33578642,13.75 8,13.4142136 8,13 C8,12.5857864 8.33578642,12.25 8.74999997,12.25 L12.25,12.25 L12.25,8.75 C12.2553858,8.33803794 12.5880379,8.00538581 13,8 C13.4119621,8.00538581 13.7446142,8.33803794 13.75,8.75 L13.75,12.25 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M1.6,8 L0.4,8 C0.1790861,8 0,8.1790861 0,8.4 L0,9.6 C0,9.8209139 0.1790861,10 0.4,10 L1.6,10 C1.8209139,10 2,9.8209139 2,9.6 L2,8.4 C2,8.1790861 1.8209139,8 1.6,8 L1.6,8 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M9,0 C8.58803794,0.00538581231 8.25538581,0.338037936 8.25,0.75 L8.25,5.75 C8.25000002,6.16421355 8.58578645,6.49999997 9,6.49999997 C9.41421355,6.49999997 9.74999998,6.16421355 9.75,5.75 L9.75,0.75 C9.74461419,0.338037936 9.41196206,0.00538581231 9,0 L9,0 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:pathData="M5.6,8 L4.4,8 C4.1790861,8 4,8.1790861 4,8.4 L4,9.6 C4,9.8209139 4.1790861,10 4.4,10 L5.6,10 C5.8209139,10 6,9.8209139 6,9.6 L6,8.4 C6,8.1790861 5.8209139,8 5.6,8 Z"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml
new file mode 100644
index 0000000..0572fb7
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml
@@ -0,0 +1,37 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="1.000000"
+        android:translateY="2.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M11,18.5 C6.313,18.5 2.5,14.687 2.5,10 C2.5,8.182 3.078,6.498 4.055,5.114 L15.887,16.945 C14.503,17.922 12.818,18.5 11,18.5 M20.031,18.969 L2.032,0.971 C1.739,0.678 1.264,0.678 0.971,0.971 C0.678,1.264 0.678,1.738 0.971,2.031 L2.983,4.043 C1.742,5.707 1,7.765 1,10 C1,15.522 5.477,20 11,20 C13.236,20 15.293,19.258 16.957,18.017 L18.971,20.029 C19.117,20.176 19.309,20.249 19.501,20.249 C19.693,20.249 19.885,20.176 20.031,20.029 C20.324,19.736 20.324,19.262 20.031,18.969"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M11,1.5 C15.687,1.5 19.5,5.313 19.5,10 C19.5,11.782 18.946,13.436 18.006,14.804 L19.078,15.877 C20.281,14.226 21,12.199 21,10 C21,4.478 16.522,0 11,0 C8.801,0 6.774,0.719 5.124,1.922 L6.196,2.994 C7.564,2.054 9.218,1.5 11,1.5"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml
new file mode 100644
index 0000000..ec608cd
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml
@@ -0,0 +1,37 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="2.000000"
+        android:translateY="2.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M12.2502,0.2637 L12.2502,1.8127 C15.8472,2.8017 18.5002,6.0927 18.5002,9.9997 C18.5002,14.6867 14.6872,18.4997 10.0002,18.4997 C5.3132,18.4997 1.5002,14.6867 1.5002,9.9997 C1.5002,6.0927 4.1532,2.8017 7.7502,1.8127 L7.7502,0.2637 C3.3122,1.2847 0.0002,5.2517 0.0002,9.9997 C0.0002,15.5227 4.4772,19.9997 10.0002,19.9997 C15.5222,19.9997 20.0002,15.5227 20.0002,9.9997 C20.0002,5.2517 16.6872,1.2847 12.2502,0.2637"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M15.0304,9.9697 C14.7374,9.6767 14.2624,9.6767 13.9694,9.9697 L10.7504,13.1897 L10.7504,0.7387 C10.7504,0.3307 10.4144,-0.0003 10.0004,-0.0003 C9.5864,-0.0003 9.2504,0.3307 9.2504,0.7387 L9.2504,13.1897 L6.0304,9.9697 C5.7374,9.6767 5.2624,9.6767 4.9694,9.9697 C4.6764,10.2627 4.6764,10.7377 4.9694,11.0307 L9.4694,15.5307 C9.6164,15.6767 9.8074,15.7497 10.0004,15.7497 C10.1924,15.7497 10.3844,15.6767 10.5304,15.5307 L15.0304,11.0307 C15.3234,10.7377 15.3234,10.2627 15.0304,9.9697"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
new file mode 100644
index 0000000..e9a07cc
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
@@ -0,0 +1,37 @@
+<?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:height="24dp"
+    android:tint="?android:attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="3.000000"
+        android:translateY="3.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M16.7178,12.626 C17.2378,11.522 17.5288,10.291 17.5288,9 C17.5288,6.119 16.1088,3.539 13.8488,2 L15.7588,2 C16.1578,2 16.4988,1.659 16.4988,1.25 C16.4988,0.84 16.1578,0.5 15.7488,0.5 L10.7488,0.5 C10.3388,0.5 9.9988,0.84 9.9988,1.25 L9.9988,6.25 C9.9988,6.659 10.3388,7 10.7488,7 C11.1578,7 11.4988,6.659 11.4988,6.25 L11.4988,2.47 C14.1978,3.489 16.0188,6.039 16.0188,9 C16.0188,9.785 15.8828,10.542 15.6438,11.252 C15.0498,10.788 14.3108,10.5 13.4988,10.5 C11.5658,10.5 9.9988,12.066 9.9988,14 C9.9988,15.933 11.5658,17.5 13.4988,17.5 C15.4318,17.5 16.9988,15.933 16.9988,14 C16.9988,13.512 16.8978,13.048 16.7178,12.626 L16.7178,12.626 Z M13.4988,16.5 C13.2228,16.5 12.9988,16.275 12.9988,16 C12.9988,15.723 13.2228,15.5 13.4988,15.5 C13.7748,15.5 13.9988,15.723 13.9988,16 C13.9988,16.275 13.7748,16.5 13.4988,16.5 L13.4988,16.5 Z M13.9988,14 C13.9988,14.275 13.7748,14.5 13.4988,14.5 C13.2228,14.5 12.9988,14.275 12.9988,14 L12.9988,12 C12.9988,11.723 13.2228,11.5 13.4988,11.5 C13.7748,11.5 13.9988,11.723 13.9988,12 L13.9988,14 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M7.0811,0.7197 C3.1901,1.6097 0.4801,5.0097 0.4801,8.9997 C0.4801,11.8797 1.9011,14.4587 4.1611,15.9987 L2.2511,15.9987 C1.8411,15.9987 1.5011,16.3397 1.5011,16.7497 C1.5011,17.1577 1.8411,17.4997 2.2511,17.4997 L7.2511,17.4997 C7.6621,17.4997 8.0011,17.1577 8.0011,16.7497 L8.0011,11.7487 C8.0011,11.3397 7.6621,10.9997 7.2511,10.9997 C6.8411,10.9997 6.5021,11.3397 6.5021,11.7487 L6.5021,15.5287 C3.8011,14.5107 1.9811,11.9587 1.9811,8.9997 C1.9811,5.7197 4.2111,2.9097 7.4211,2.1807 C7.8221,2.0907 8.0811,1.6797 7.9801,1.2797 C7.9041,0.9347 7.5961,0.7017 7.2491,0.7017 C7.1941,0.7017 7.1381,0.7067 7.0811,0.7197"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/Android.mk b/packages/overlays/IconPackRoundedSystemUIOverlay/Android.mk
index 4e21b41..3b68c92 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/Android.mk
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackRoundedSystemUIOverlay
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
new file mode 100644
index 0000000..ad79132
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
@@ -0,0 +1,51 @@
+<?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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="2.000000"
+        android:translateY="4.000000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M18.0001,0 L2.0001,0 C0.8961,0 0.0001,0.896 0.0001,2 L0.0001,14 C0.0001,15.104 0.8961,16 2.0001,16 L18.0001,16 C19.1041,16 20.0001,15.104 20.0001,14 L20.0001,2 C20.0001,0.896 19.1041,0 18.0001,0 M18.0001,1.5 C18.2751,1.5 18.5001,1.725 18.5001,2 L18.5001,14 C18.5001,14.275 18.2751,14.5 18.0001,14.5 L2.0001,14.5 C1.7251,14.5 1.5001,14.275 1.5001,14 L1.5001,2 C1.5001,1.725 1.7251,1.5 2.0001,1.5 L18.0001,1.5"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M3.5001,11.5 L13.5001,11.5 C13.7761,11.5 14.0001,11.724 14.0001,12 L14.0001,12.5 C14.0001,12.776 13.7761,13 13.5001,13 L3.5001,13 C3.2241,13 3.0001,12.776 3.0001,12.5 L3.0001,12 C3.0001,11.724 3.2241,11.5 3.5001,11.5"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M3.5001,8.5 L4.0001,8.5 C4.2761,8.5 4.5001,8.724 4.5001,9 L4.5001,9.5 C4.5001,9.776 4.2761,10 4.0001,10 L3.5001,10 C3.2241,10 3.0001,9.776 3.0001,9.5 L3.0001,9 C3.0001,8.724 3.2241,8.5 3.5001,8.5"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M16.0001,11.5 L16.5001,11.5 C16.7761,11.5 17.0001,11.724 17.0001,12 L17.0001,12.5 C17.0001,12.776 16.7761,13 16.5001,13 L16.0001,13 C15.7241,13 15.5001,12.776 15.5001,12.5 L15.5001,12 C15.5001,11.724 15.7241,11.5 16.0001,11.5"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M6.5001,8.5 L16.5001,8.5 C16.7761,8.5 17.0001,8.724 17.0001,9 L17.0001,9.5 C17.0001,9.776 16.7761,10 16.5001,10 L6.5001,10 C6.2241,10 6.0001,9.776 6.0001,9.5 L6.0001,9 C6.0001,8.724 6.2241,8.5 6.5001,8.5"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
new file mode 100644
index 0000000..2ea41f2
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
@@ -0,0 +1,61 @@
+<?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:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24"
+    android:width="24dp" >
+    <group
+        android:translateX="1.750150"
+        android:translateY="2.750000" >
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M3.74975,9.74875 L4.24975,9.74875 C4.52575,9.74875 4.74975,9.97275 4.74975,10.24875 L4.74975,10.74875 C4.74975,11.02475 4.52575,11.24875 4.24975,11.24875 L3.74975,11.24875 C3.47375,11.24875 3.24975,11.02475 3.24975,10.74875 L3.24975,10.24875 C3.24975,9.97275 3.47375,9.74875 3.74975,9.74875"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M18.24975,2.74875 C18.52475,2.74875 18.74975,2.97375 18.74975,3.24875 L18.74975,15.24875 C18.74975,15.33875 18.71975,15.41875 18.67775,15.49275 L19.74675,16.56175 C20.05675,16.20975 20.24975,15.75475 20.24975,15.24875 L20.24975,3.24875 C20.24975,2.14475 19.35375,1.24875 18.24975,1.24875 L4.43375,1.24875 L5.93375,2.74875 L18.24975,2.74875 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M17.24975,13.74875 L17.24975,13.24875 C17.24975,12.97275 17.02575,12.74875 16.74975,12.74875 L16.24975,12.74875 C16.15875,12.74875 16.07875,12.77875 16.00575,12.82075 L17.17775,13.99275 C17.21975,13.91975 17.24975,13.83875 17.24975,13.74875"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M16.74975,11.24875 C17.02575,11.24875 17.24975,11.02475 17.24975,10.74875 L17.24975,10.24875 C17.24975,9.97275 17.02575,9.74875 16.74975,9.74875 L12.93375,9.74875 L14.43375,11.24875 L16.74975,11.24875 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M2.24975,15.74875 C1.97475,15.74875 1.74975,15.52375 1.74975,15.24875 L1.74975,3.24875 C1.74975,3.12675 1.79875,3.01875 1.87175,2.93275 L8.68875,9.74875 L6.74975,9.74875 C6.47375,9.74875 6.24975,9.97275 6.24975,10.24875 L6.24975,10.74875 C6.24975,11.02475 6.47375,11.24875 6.74975,11.24875 L10.18875,11.24875 L11.68875,12.74875 L3.74975,12.74875 C3.47375,12.74875 3.24975,12.97275 3.24975,13.24875 L3.24975,13.74875 C3.24975,14.02475 3.47375,14.24875 3.74975,14.24875 L13.18875,14.24875 L14.68975,15.74875 L2.24975,15.74875 Z M19.27975,18.21775 L1.27975,0.21975 C0.98675,-0.07325 0.51275,-0.07325 0.21975,0.21975 C-0.07325,0.51275 -0.07325,0.98675 0.21975,1.27975 L0.80775,1.86775 C0.46375,2.22775 0.24975,2.71175 0.24975,3.24875 L0.24975,15.24875 C0.24975,16.35275 1.14575,17.24875 2.24975,17.24875 L16.18975,17.24875 L18.21975,19.27775 C18.51275,19.57075 18.98675,19.57075 19.27975,19.27775 C19.57275,18.98475 19.57275,18.51075 19.27975,18.21775 L19.27975,18.21775 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M2.24975,15.74875 C1.97475,15.74875 1.74975,15.52375 1.74975,15.24875 L1.74975,3.24875 C1.74975,3.12675 1.79875,3.01875 1.87175,2.93275 L0.80775,1.86775 C0.46375,2.22775 0.24975,2.71175 0.24975,3.24875 L0.24975,15.24875 C0.24975,16.35275 1.14575,17.24875 2.24975,17.24875 L16.18975,17.24875 L14.68975,15.74875 L2.24975,15.74875 Z"
+            android:strokeWidth="1" />
+        <path
+            android:fillColor="@android:color/white"
+            android:fillType="evenOdd"
+            android:pathData="M18.24975,2.74875 C18.52475,2.74875 18.74975,2.97375 18.74975,3.24875 L18.74975,15.24875 C18.74975,15.33875 18.71975,15.41875 18.67775,15.49275 L19.74675,16.56175 C20.05675,16.20975 20.24975,15.75475 20.24975,15.24875 L20.24975,3.24875 C20.24975,2.14475 19.35375,1.24875 18.24975,1.24875 L4.43375,1.24875 L5.93375,2.74875 L18.24975,2.74875 Z"
+            android:strokeWidth="1" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedThemePickerOverlay/Android.mk b/packages/overlays/IconPackRoundedThemePickerOverlay/Android.mk
index ae48186..e31aa4a 100644
--- a/packages/overlays/IconPackRoundedThemePickerOverlay/Android.mk
+++ b/packages/overlays/IconPackRoundedThemePickerOverlay/Android.mk
@@ -21,8 +21,6 @@
 LOCAL_CERTIFICATE := platform
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconPackRoundedThemePickerOverlay
diff --git a/packages/overlays/IconShapeRoundedRectOverlay/Android.mk b/packages/overlays/IconShapeRoundedRectOverlay/Android.mk
index 21cd011..c6f00d1 100644
--- a/packages/overlays/IconShapeRoundedRectOverlay/Android.mk
+++ b/packages/overlays/IconShapeRoundedRectOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconShapeRoundedRectOverlay
diff --git a/packages/overlays/IconShapeSquareOverlay/Android.mk b/packages/overlays/IconShapeSquareOverlay/Android.mk
index c872883..6020721 100644
--- a/packages/overlays/IconShapeSquareOverlay/Android.mk
+++ b/packages/overlays/IconShapeSquareOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconShapeSquareOverlay
diff --git a/packages/overlays/IconShapeSquircleOverlay/Android.mk b/packages/overlays/IconShapeSquircleOverlay/Android.mk
index fa5fe69..04409a5 100644
--- a/packages/overlays/IconShapeSquircleOverlay/Android.mk
+++ b/packages/overlays/IconShapeSquircleOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconShapeSquircleOverlay
diff --git a/packages/overlays/IconShapeTeardropOverlay/Android.mk b/packages/overlays/IconShapeTeardropOverlay/Android.mk
index d5f01f3..b127dea 100644
--- a/packages/overlays/IconShapeTeardropOverlay/Android.mk
+++ b/packages/overlays/IconShapeTeardropOverlay/Android.mk
@@ -21,8 +21,6 @@
 
 LOCAL_PRODUCT_MODULE := true
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := IconShapeTeardropOverlay
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk b/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk
index be86ef2..30477cc 100644
--- a/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk
@@ -20,8 +20,6 @@
 LOCAL_RRO_THEME := NavigationBarMode2Button
 
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := NavigationBarMode2ButtonOverlay
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk b/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk
index f44a362..3d5a5a5 100644
--- a/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk
@@ -20,8 +20,6 @@
 LOCAL_RRO_THEME := NavigationBarMode3Button
 
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := NavigationBarMode3ButtonOverlay
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk b/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk
index 02e2074..3b7605a 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk
@@ -20,8 +20,6 @@
 LOCAL_RRO_THEME := NavigationBarModeGestural
 
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := NavigationBarModeGesturalOverlay
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
index f1d2e0b..96ed7b4 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
index 1232201..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
@@ -25,6 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
-        <!-- The height of the bottom navigation gesture area. -->
+    <!-- The height of the bottom navigation gesture area. -->
     <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/Android.mk b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/Android.mk
index 9a38efa..1a1388e 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/Android.mk
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/Android.mk
@@ -20,8 +20,6 @@
 LOCAL_RRO_THEME := NavigationBarModeGesturalExtraWideBack
 
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := NavigationBarModeGesturalOverlayExtraWideBack
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
index c8f994c..d5991f3 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/Android.mk b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/Android.mk
index 1d004c8..8689986 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/Android.mk
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/Android.mk
@@ -20,8 +20,6 @@
 LOCAL_RRO_THEME := NavigationBarModeGesturalNarrowBack
 
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := NavigationBarModeGesturalOverlayNarrowBack
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
index 693110a..ff507ee 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/Android.mk b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/Android.mk
index 0ab463f..2723add 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/Android.mk
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/Android.mk
@@ -20,8 +20,6 @@
 LOCAL_RRO_THEME := NavigationBarModeGesturalWideBack
 
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
 LOCAL_PACKAGE_NAME := NavigationBarModeGesturalOverlayWideBack
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
index 5cd6ce3..378756a 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/tests/Android.bp b/packages/overlays/tests/Android.bp
new file mode 100644
index 0000000..343367a
--- /dev/null
+++ b/packages/overlays/tests/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+    name: "OverlayTests",
+
+    certificate: "platform",
+
+    srcs: ["src/**/*.java"],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+
+    platform_apis: true,
+
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.test.espresso.core",
+        "mockito-target-minus-junit4",
+        "truth-prebuilt",
+    ],
+
+    dxflags: ["--multi-dex"],
+}
diff --git a/packages/overlays/tests/AndroidManifest.xml b/packages/overlays/tests/AndroidManifest.xml
new file mode 100644
index 0000000..6ebc555
--- /dev/null
+++ b/packages/overlays/tests/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?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.overlays">
+
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+    <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY"/>
+    <uses-permission android:name="android.permission.SET_TIME_ZONE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.systemui"
+        android:label="Tests for Overlays">
+    </instrumentation>
+</manifest>
diff --git a/packages/overlays/tests/AndroidTest.xml b/packages/overlays/tests/AndroidTest.xml
new file mode 100644
index 0000000..8843d62
--- /dev/null
+++ b/packages/overlays/tests/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?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
+  -->
+<configuration description="Runs Tests for Overlays.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="OverlayTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="OverlayTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.overlays" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/packages/overlays/tests/src/com/android/theme/icon/IconPackOverlayTest.java b/packages/overlays/tests/src/com/android/theme/icon/IconPackOverlayTest.java
new file mode 100644
index 0000000..6bc56ba
--- /dev/null
+++ b/packages/overlays/tests/src/com/android/theme/icon/IconPackOverlayTest.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.theme.icon;
+
+import static junit.framework.Assert.fail;
+
+import static org.junit.Assert.assertEquals;
+
+import android.annotation.DrawableRes;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.text.TextUtils;
+import android.util.TypedValue;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.XmlUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class IconPackOverlayTest {
+    private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
+    private static final String[] SYSTEMUI_ICON_PACK_OVERLAY_PACKAGES = {
+            "com.android.theme.icon_pack.circular.systemui",
+            "com.android.theme.icon_pack.rounded.systemui",
+            "com.android.theme.icon_pack.filled.systemui",
+    };
+    private static final String ANDROID_PACKAGE = "android";
+    private static final String[] ANDROID_ICON_PACK_OVERLAY_PACKAGES = {
+            "com.android.theme.icon_pack.circular.android",
+            "com.android.theme.icon_pack.rounded.android",
+            "com.android.theme.icon_pack.filled.android",
+    };
+    private static final String SETTINGS_PACKAGE = "com.android.settings";
+    private static final String[] SETTINGS_ICON_PACK_OVERLAY_PACKAGES = {
+            "com.android.theme.icon_pack.circular.settings",
+            "com.android.theme.icon_pack.rounded.settings",
+            "com.android.theme.icon_pack.filled.settings",
+    };
+
+    private static final int[] VECTOR_ATTRIBUTES = {
+            android.R.attr.tint,
+            android.R.attr.height,
+            android.R.attr.width,
+            android.R.attr.alpha,
+            android.R.attr.autoMirrored,
+    };
+
+    private final TypedValue mTargetTypedValue = new TypedValue();
+    private final TypedValue mOverlayTypedValue = new TypedValue();
+    private Context mContext;
+
+    @Before
+    public void setup() {
+        mContext = InstrumentationRegistry.getContext();
+    }
+
+    /**
+     * Ensure that drawable icons in icon packs targeting android have corresponding underlying
+     * drawables in android. This test fails if you remove/rename an overlaid icon in android.
+     * If so, make the same change to the corresponding drawables in the overlay packages.
+     */
+    @Test
+    public void testAndroidFramework_containsAllOverlayedIcons() {
+        containsAllOverlayedIcons(ANDROID_PACKAGE, ANDROID_ICON_PACK_OVERLAY_PACKAGES);
+    }
+
+    /**
+     * Ensure that drawable icons in icon packs targeting settings have corresponding underlying
+     * drawables in settings. This test fails if you remove/rename an overlaid icon in settings.
+     * If so, make the same change to the corresponding drawables in the overlay packages.
+     */
+    @Test
+    public void testSettings_containsAllOverlayedIcons() {
+        containsAllOverlayedIcons(SETTINGS_PACKAGE, SETTINGS_ICON_PACK_OVERLAY_PACKAGES);
+    }
+
+    /**
+     * Ensure that drawable icons in icon packs targeting systemui have corresponding underlying
+     * drawables in systemui. This test fails if you remove/rename an overlaid icon in systemui.
+     * If so, make the same change to the corresponding drawables in the overlay packages.
+     */
+    @Test
+    public void testSystemUI_containAllOverlayedIcons() {
+        containsAllOverlayedIcons(SYSTEMUI_PACKAGE, SYSTEMUI_ICON_PACK_OVERLAY_PACKAGES);
+    }
+
+    /**
+     * Ensures that all overlay icons have the same values for {@link #VECTOR_ATTRIBUTES} as the
+     * underlying drawable in android. To fix this test, make the attribute change to all of the
+     * corresponding drawables in the overlay packages.
+     */
+    @Test
+    public void testAndroidFramework_hasEqualVectorDrawableAttributes() {
+        hasEqualVectorDrawableAttributes(ANDROID_PACKAGE, ANDROID_ICON_PACK_OVERLAY_PACKAGES);
+    }
+
+    /**
+     * Ensures that all overlay icons have the same values for {@link #VECTOR_ATTRIBUTES} as the
+     * underlying drawable in settings. To fix this test, make the attribute change to all of the
+     * corresponding drawables in the overlay packages.
+     */
+    @Test
+    public void testSettings_hasEqualVectorDrawableAttributes() {
+        hasEqualVectorDrawableAttributes(SETTINGS_PACKAGE, SETTINGS_ICON_PACK_OVERLAY_PACKAGES);
+    }
+
+    /**
+     * Ensures that all overlay icons have the same values for {@link #VECTOR_ATTRIBUTES} as the
+     * underlying drawable in systemui. To fix this test, make the attribute change to all of the
+     * corresponding drawables in the overlay packages.
+     */
+    @Test
+    public void testSystemUI_hasEqualVectorDrawableAttributes() {
+        hasEqualVectorDrawableAttributes(SYSTEMUI_PACKAGE, SYSTEMUI_ICON_PACK_OVERLAY_PACKAGES);
+    }
+
+    private void containsAllOverlayedIcons(String targetPkg, String[] overlayPkgs) {
+        final Resources targetResources;
+        try {
+            targetResources = mContext.getPackageManager()
+                    .getResourcesForApplication(targetPkg);
+        } catch (PackageManager.NameNotFoundException e) {
+            return; // No need to test overlays if target package does not exist on the system.
+        }
+
+        StringBuilder errors = new StringBuilder();
+        for (String overlayPackage : overlayPkgs) {
+            final ApplicationInfo info;
+            try {
+                info = mContext.getPackageManager().getApplicationInfo(overlayPackage, 0);
+            } catch (PackageManager.NameNotFoundException e) {
+                continue; // No need to test overlay resources if apk is not on the system.
+            }
+            final List<String> iconPackDrawables = getDrawablesFromOverlay(info);
+            for (int i = 0; i < iconPackDrawables.size(); i++) {
+                String resourceName = iconPackDrawables.get(i);
+                int targetRid = targetResources.getIdentifier(resourceName, "drawable", targetPkg);
+                if (targetRid == Resources.ID_NULL) {
+                    errors.append(String.format("[%s] is not contained in the target package [%s]",
+                            resourceName, targetPkg));
+                }
+            }
+        }
+
+        if (!TextUtils.isEmpty(errors)) {
+            fail(errors.toString());
+        }
+    }
+
+    private void hasEqualVectorDrawableAttributes(String targetPkg, String[] overlayPackages) {
+        final Resources targetRes;
+        try {
+            targetRes = mContext.getPackageManager().getResourcesForApplication(targetPkg);
+        } catch (PackageManager.NameNotFoundException e) {
+            return; // No need to test overlays if target package does not exist on the system.
+        }
+
+        StringBuilder errors = new StringBuilder();
+
+        for (String overlayPkg : overlayPackages) {
+            final ApplicationInfo info;
+            try {
+                info = mContext.getPackageManager().getApplicationInfo(overlayPkg, 0);
+            } catch (PackageManager.NameNotFoundException e) {
+                continue; // No need to test overlay resources if apk is not on the system.
+            }
+            final List<String> iconPackDrawables = getDrawablesFromOverlay(info);
+            final Resources overlayRes;
+            try {
+                overlayRes = mContext.getPackageManager().getResourcesForApplication(overlayPkg);
+            } catch (PackageManager.NameNotFoundException e) {
+                continue; // No need to test overlay resources if apk is not on the system.
+            }
+
+            for (int i = 0; i < iconPackDrawables.size(); i++) {
+                String resourceName = iconPackDrawables.get(i);
+                int targetRid = targetRes.getIdentifier(resourceName, "drawable", targetPkg);
+                int overlayRid = overlayRes.getIdentifier(resourceName, "drawable", overlayPkg);
+                TypedArray targetAttrs = getAVDAttributes(targetRes, targetRid);
+                if (targetAttrs == null) {
+                    errors.append(String.format(
+                            "[%s] in pkg [%s] does not exist or is not a valid vector drawable.\n",
+                            resourceName, targetPkg));
+                    continue;
+                }
+
+                TypedArray overlayAttrs = getAVDAttributes(overlayRes, overlayRid);
+                if (overlayAttrs == null) {
+                    errors.append(String.format(
+                            "[%s] in pkg [%s] does not exist or is not a valid vector drawable.\n",
+                            resourceName, overlayPkg));
+                    continue;
+                }
+
+                if (!attributesEquals(targetAttrs, overlayAttrs)) {
+                    errors.append(String.format("[drawable/%s] in [%s] does not have the same "
+                                    + "attributes as the corresponding drawable from [%s]\n",
+                            resourceName, targetPkg, overlayPkg));
+                }
+                targetAttrs.recycle();
+                overlayAttrs.recycle();
+            }
+        }
+
+        if (!TextUtils.isEmpty(errors)) {
+            fail(errors.toString());
+        }
+    }
+
+    private TypedArray getAVDAttributes(Resources resources, @DrawableRes int rid) {
+        try {
+            XmlResourceParser parser = resources.getXml(rid);
+            XmlUtils.nextElement(parser);
+            // Always use the the test apk theme to resolve attributes.
+            return mContext.getTheme().obtainStyledAttributes(parser, VECTOR_ATTRIBUTES, 0, 0);
+        } catch (XmlPullParserException | IOException  | Resources.NotFoundException e) {
+            return null;
+        }
+    }
+
+    private boolean attributesEquals(TypedArray target, TypedArray overlay) {
+        assertEquals(target.length(), overlay.length());
+        for (int i = 0; i < target.length(); i++) {
+            target.getValue(i, mTargetTypedValue);
+            overlay.getValue(i, mOverlayTypedValue);
+            if (!attributesEquals(mTargetTypedValue, mOverlayTypedValue)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean attributesEquals(TypedValue target, TypedValue overlay) {
+        return target.type == overlay.type && target.data == overlay.data;
+    }
+
+    private static List<String> getDrawablesFromOverlay(ApplicationInfo applicationInfo) {
+        try {
+            final ArrayList<String> drawables = new ArrayList<>();
+            ZipFile file = new ZipFile(applicationInfo.sourceDir);
+            Enumeration<? extends ZipEntry> entries = file.entries();
+            while (entries.hasMoreElements()) {
+                ZipEntry element = entries.nextElement();
+                String name = element.getName();
+                if (name.contains("/drawable/")) {
+                    name = name.substring(name.lastIndexOf('/') + 1);
+                    if (name.contains(".")) {
+                        name = name.substring(0, name.indexOf('.'));
+                    }
+                    drawables.add(name);
+                }
+            }
+            return drawables;
+        } catch (IOException e) {
+            fail(String.format("Failed to retrieve drawables from package [%s] with message [%s]",
+                    applicationInfo.packageName, e.getMessage()));
+            return null;
+        }
+    }
+}
diff --git a/proto/Android.bp b/proto/Android.bp
index 7b119a7..65bccbb 100644
--- a/proto/Android.bp
+++ b/proto/Android.bp
@@ -5,7 +5,6 @@
         type: "nano",
     },
     srcs: ["src/**/*.proto"],
-    no_framework_libs: true,
     sdk_version: "9",
     // Pin java_version until jarjar is certified to support later versions. http://b/72703434
     java_version: "1.8",
@@ -26,6 +25,5 @@
         type: "nano",
     },
     srcs: ["src/metrics_constants/metrics_constants.proto"],
-    no_framework_libs: true,
     sdk_version: "system_current",
 }
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 0f0e6f9..5a4892c 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -5780,7 +5780,7 @@
     // OS: P
     WIFI_SCANNING_NEEDED_DIALOG = 1373;
 
-    // OPEN: Settings > System > Gestures > Swipe up gesture
+    // OPEN: Settings > System > Gestures > System navigation
     // CATEGORY: SETTINGS
     // OS: P
     SETTINGS_GESTURE_SWIPE_UP = 1374;
@@ -7388,6 +7388,32 @@
     // CATEGORY: NOTIFICATION
     MEDIA_NOTIFICATION_SEEKBAR = 1743;
 
+    // Custom tag for StatusBarNotification. Length of
+    // Notification.extras[EXTRA_PEOPLE_LIST], set by addPerson().
+    FIELD_NOTIFICATION_PEOPLE = 1744;
+
+    // Custom tag for StatusBarNotification. The Java hashcode of
+    // Notification.extras[EXTRA_TEMPLATE], which is a string like
+    // android.app.Notification$MessagingStyle, set by setStyle().
+    FIELD_NOTIFICATION_STYLE = 1745;
+
+    // OPEN: Settings > About phone > Legal information > Google Play system update licenses
+    // CATEGORY: SETTINGS
+    // OS: Q
+    MODULE_LICENSES_DASHBOARD = 1746;
+
+    // OPEN: Settings > System > Gestures > System navigation > Info icon
+    // CATEGORY: SETTINGS
+    // OS: Q
+    // Note: Info icon is visible only when gesture navigation is not available and disabled
+    SETTINGS_GESTURE_NAV_NOT_AVAILABLE_DLG = 1747;
+
+    // OPEN: Settings > System > Gestures > System navigation > Gear icon
+    // CATEGORY: SETTINGS
+    // OS: Q
+    // Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
+    SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
+
     // ---- 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/task_snapshot.proto b/proto/src/task_snapshot.proto
index a1bbe52..821db86 100644
--- a/proto/src/task_snapshot.proto
+++ b/proto/src/task_snapshot.proto
@@ -32,4 +32,6 @@
      int32 system_ui_visibility = 8;
      bool is_translucent = 9;
      string top_activity_component = 10;
- }
\ No newline at end of file
+     float scale = 11;
+     int64 id = 12;
+ }
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index c7f4154..2db7f0e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -17,7 +17,6 @@
 package com.android.server.accessibility;
 
 import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
-import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
@@ -37,6 +36,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.graphics.Region;
+import android.hardware.display.DisplayManager;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -49,6 +49,7 @@
 import android.os.SystemClock;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
 import android.view.View;
@@ -91,6 +92,7 @@
     private final WindowManagerInternal mWindowManagerService;
     private final GlobalActionPerformer mGlobalActionPerformer;
     private final AccessibilityWindowManager mA11yWindowManager;
+    private final DisplayManager mDisplayManager;
     private final PowerManager mPowerManager;
 
     // Handler for scheduling method invocations on the main thread.
@@ -149,7 +151,7 @@
     // types as message types allowing us to remove messages per event type.
     public Handler mEventDispatchHandler;
 
-    final IBinder mOverlayWindowToken = new Binder();
+    final SparseArray<IBinder> mOverlayWindowTokens = new SparseArray();
 
 
     public interface SystemSupport {
@@ -222,6 +224,7 @@
         mSystemSupport = systemSupport;
         mInvocationHandler = new InvocationHandler(mainHandler.getLooper());
         mA11yWindowManager = a11yWindowManager;
+        mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mEventDispatchHandler = new Handler(mainHandler.getLooper()) {
             @Override
@@ -297,7 +300,7 @@
     }
 
     public boolean canReceiveEventsLocked() {
-        return (mEventTypes != 0 && mFeedbackType != 0 && mService != null);
+        return (mEventTypes != 0 && mService != null);
     }
 
     @Override
@@ -928,24 +931,73 @@
     }
 
     public void onAdded() {
+        final Display[] displays = mDisplayManager.getDisplays();
+        for (int i = 0; i < displays.length; i++) {
+            final int displayId = displays[i].getDisplayId();
+            onDisplayAdded(displayId);
+        }
+    }
+
+    /**
+     * Called whenever a logical display has been added to the system. Add a window token for adding
+     * an accessibility overlay.
+     *
+     * @param displayId The id of the logical display that was added.
+     */
+    public void onDisplayAdded(int displayId) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            mWindowManagerService.addWindowToken(mOverlayWindowToken,
-                    TYPE_ACCESSIBILITY_OVERLAY, DEFAULT_DISPLAY);
+            final IBinder overlayWindowToken = new Binder();
+            mWindowManagerService.addWindowToken(overlayWindowToken, TYPE_ACCESSIBILITY_OVERLAY,
+                    displayId);
+            synchronized (mLock) {
+                mOverlayWindowTokens.put(displayId, overlayWindowToken);
+            }
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     public void onRemoved() {
+        final Display[] displays = mDisplayManager.getDisplays();
+        for (int i = 0; i < displays.length; i++) {
+            final int displayId = displays[i].getDisplayId();
+            onDisplayRemoved(displayId);
+        }
+    }
+
+    /**
+     * Called whenever a logical display has been removed from the system. Remove a window token for
+     * removing an accessibility overlay.
+     *
+     * @param displayId The id of the logical display that was added.
+     */
+    public void onDisplayRemoved(int displayId) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            mWindowManagerService.removeWindowToken(mOverlayWindowToken, true, DEFAULT_DISPLAY);
+            mWindowManagerService.removeWindowToken(mOverlayWindowTokens.get(displayId), true,
+                    displayId);
+            synchronized (mLock) {
+                mOverlayWindowTokens.remove(displayId);
+            }
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
+    /**
+     * Gets overlay window token by the display Id.
+     *
+     * @param displayId The id of the logical display that was added.
+     * @return window token.
+     */
+    @Override
+    public IBinder getOverlayWindowToken(int displayId) {
+        synchronized (mLock) {
+            return mOverlayWindowTokens.get(displayId);
+        }
+    }
+
     public void resetLocked() {
         mSystemSupport.getKeyEventDispatcher().flush(this);
         try {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 303230b..b6cbbac 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -385,9 +385,10 @@
 
         for (int i = displaysList.size() - 1; i >= 0; i--) {
             final int displayId = displaysList.get(i).getDisplayId();
+            final Context displayContext = mContext.createDisplayContext(displaysList.get(i));
 
             if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) {
-                TouchExplorer explorer = new TouchExplorer(mContext, mAms);
+                TouchExplorer explorer = new TouchExplorer(displayContext, mAms);
                 addFirstEventHandler(displayId, explorer);
                 mTouchExplorer.put(displayId, explorer);
             }
@@ -400,7 +401,7 @@
                 final boolean triggerable = (mEnabledFeatures
                         & FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER) != 0;
                 MagnificationGestureHandler magnificationGestureHandler =
-                        new MagnificationGestureHandler(mContext,
+                        new MagnificationGestureHandler(displayContext,
                                 mAms.getMagnificationController(),
                                 detectControlGestures, triggerable, displayId);
                 addFirstEventHandler(displayId, magnificationGestureHandler);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 47f137c..a220451 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -579,10 +579,11 @@
             // Make sure clients receiving this event will be able to get the
             // current state of the windows as the window manager may be delaying
             // the computation for performance reasons.
+            // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
             if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
                     && mA11yWindowManager.isTrackingWindowsLocked()) {
                 WindowManagerInternal wm = LocalServices.getService(WindowManagerInternal.class);
-                wm.computeWindowsForAccessibility();
+                wm.computeWindowsForAccessibility(Display.DEFAULT_DISPLAY);
             }
             synchronized (mLock) {
                 notifyAccessibilityServicesDelayedLocked(event, false);
@@ -2550,6 +2551,13 @@
                     mInputFilter.onDisplayChanged();
                 }
                 UserState userState = getCurrentUserStateLocked();
+                if (displayId != Display.DEFAULT_DISPLAY) {
+                    final List<AccessibilityServiceConnection> services = userState.mBoundServices;
+                    for (int i = 0; i < services.size(); i++) {
+                        AccessibilityServiceConnection boundClient = services.get(i);
+                        boundClient.onDisplayAdded(displayId);
+                    }
+                }
                 updateMagnificationLocked(userState);
             }
         }
@@ -2566,6 +2574,14 @@
                 if (mInputFilter != null) {
                     mInputFilter.onDisplayChanged();
                 }
+                UserState userState = getCurrentUserStateLocked();
+                if (displayId != Display.DEFAULT_DISPLAY) {
+                    final List<AccessibilityServiceConnection> services = userState.mBoundServices;
+                    for (int i = 0; i < services.size(); i++) {
+                        AccessibilityServiceConnection boundClient = services.get(i);
+                        boundClient.onDisplayRemoved(displayId);
+                    }
+                }
             }
             if (mMagnificationController != null) {
                 mMagnificationController.onDisplayRemoved(displayId);
@@ -2601,8 +2617,6 @@
         public final RemoteCallbackList<IAccessibilityManagerClient> mUserClients =
                 new RemoteCallbackList<>();
 
-        public final SparseArray<IBinder> mWindowTokens = new SparseArray<>();
-
         // Transient state.
 
         public final ArrayList<AccessibilityServiceConnection> mBoundServices = new ArrayList<>();
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 547f7d3..02306c0 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -31,6 +31,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
+import android.view.Display;
 
 import com.android.server.accessibility.AccessibilityManagerService.UserState;
 import com.android.server.wm.WindowManagerInternal;
@@ -196,7 +197,7 @@
             return;
         }
         try {
-            serviceInterface.init(this, mId, mOverlayWindowToken);
+            serviceInterface.init(this, mId, mOverlayWindowTokens.get(Display.DEFAULT_DISPLAY));
         } catch (RemoteException re) {
             Slog.w(LOG_TAG, "Error while setting connection for service: "
                     + serviceInterface, re);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 2619ed2..c129291 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -23,7 +23,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
 import android.os.Handler;
@@ -31,8 +30,10 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.IWindow;
 import android.view.WindowInfo;
 import android.view.WindowManager;
@@ -83,6 +84,7 @@
             mInteractionConnections = new SparseArray<>();
     private final SparseArray<SparseArray<IBinder>> mWindowTokens = new SparseArray<>();
 
+    private final List<WindowInfo> mCachedWindowInfos = new ArrayList<>();
     private List<AccessibilityWindowInfo> mWindows;
 
     private RemoteAccessibilityConnection mPictureInPictureActionReplacingConnection;
@@ -173,25 +175,133 @@
     }
 
     /**
-     * Callbacks from from window manager when there's an accessibility change in windows.
+     * Callbacks from window manager when there's an accessibility change in windows.
      *
+     * @param forceSend Send the windows for accessibility even if they haven't changed.
      * @param windows The windows of current display for accessibility.
      */
     @Override
-    public void onWindowsForAccessibilityChanged(@NonNull List<WindowInfo> windows) {
+    public void onWindowsForAccessibilityChanged(boolean forceSend,
+            @NonNull List<WindowInfo> windows) {
         synchronized (mLock) {
             if (DEBUG) {
                 Slog.i(LOG_TAG, "Windows changed: " + windows);
             }
 
-            // Let the policy update the focused and active windows.
-            updateWindowsLocked(mAccessibilityUserManager.getCurrentUserIdLocked(), windows);
-
-            // Someone may be waiting for the windows - advertise it.
-            mLock.notifyAll();
+            if (shouldUpdateWindowsLocked(forceSend, windows)) {
+                cacheWindows(windows);
+                // Let the policy update the focused and active windows.
+                updateWindowsLocked(mAccessibilityUserManager.getCurrentUserIdLocked(), windows);
+                // Someone may be waiting for the windows - advertise it.
+                mLock.notifyAll();
+            }
         }
     }
 
+    private boolean shouldUpdateWindowsLocked(boolean forceSend,
+            @NonNull List<WindowInfo> windows) {
+        if (forceSend) {
+            return true;
+        }
+
+        final int windowCount = windows.size();
+        // We computed the windows and if they changed notify the client.
+        if (mCachedWindowInfos.size() != windowCount) {
+            // Different size means something changed.
+            return true;
+        } else if (!mCachedWindowInfos.isEmpty() || !windows.isEmpty()) {
+            // Since we always traverse windows from high to low layer
+            // the old and new windows at the same index should be the
+            // same, otherwise something changed.
+            for (int i = 0; i < windowCount; i++) {
+                WindowInfo oldWindow = mCachedWindowInfos.get(i);
+                WindowInfo newWindow = windows.get(i);
+                // We do not care for layer changes given the window
+                // order does not change. This brings no new information
+                // to the clients.
+                if (windowChangedNoLayer(oldWindow, newWindow)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private void cacheWindows(List<WindowInfo> windows) {
+        final int oldWindowCount = mCachedWindowInfos.size();
+        for (int i = oldWindowCount - 1; i >= 0; i--) {
+            mCachedWindowInfos.remove(i).recycle();
+        }
+        final int newWindowCount = windows.size();
+        for (int i = 0; i < newWindowCount; i++) {
+            WindowInfo newWindow = windows.get(i);
+            mCachedWindowInfos.add(WindowInfo.obtain(newWindow));
+        }
+    }
+
+    private boolean windowChangedNoLayer(WindowInfo oldWindow, WindowInfo newWindow) {
+        if (oldWindow == newWindow) {
+            return false;
+        }
+        if (oldWindow == null) {
+            return true;
+        }
+        if (newWindow == null) {
+            return true;
+        }
+        if (oldWindow.type != newWindow.type) {
+            return true;
+        }
+        if (oldWindow.focused != newWindow.focused) {
+            return true;
+        }
+        if (oldWindow.token == null) {
+            if (newWindow.token != null) {
+                return true;
+            }
+        } else if (!oldWindow.token.equals(newWindow.token)) {
+            return true;
+        }
+        if (oldWindow.parentToken == null) {
+            if (newWindow.parentToken != null) {
+                return true;
+            }
+        } else if (!oldWindow.parentToken.equals(newWindow.parentToken)) {
+            return true;
+        }
+        if (oldWindow.activityToken == null) {
+            if (newWindow.activityToken != null) {
+                return true;
+            }
+        } else if (!oldWindow.activityToken.equals(newWindow.activityToken)) {
+            return true;
+        }
+        if (!oldWindow.regionInScreen.equals(newWindow.regionInScreen)) {
+            return true;
+        }
+        if (oldWindow.childTokens != null && newWindow.childTokens != null
+                && !oldWindow.childTokens.equals(newWindow.childTokens)) {
+            return true;
+        }
+        if (!TextUtils.equals(oldWindow.title, newWindow.title)) {
+            return true;
+        }
+        if (oldWindow.accessibilityIdOfAnchor != newWindow.accessibilityIdOfAnchor) {
+            return true;
+        }
+        if (oldWindow.inPictureInPicture != newWindow.inPictureInPicture) {
+            return true;
+        }
+        if (oldWindow.hasFlagWatchOutsideTouch != newWindow.hasFlagWatchOutsideTouch) {
+            return true;
+        }
+        if (oldWindow.displayId != newWindow.displayId) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Start tracking windows changes from window manager.
      */
@@ -202,7 +312,9 @@
                 // In some cases, onWindowsForAccessibilityChanged will be called immediately in
                 // setWindowsForAccessibilityCallback. We'll lost windows if flag is false.
                 mTrackingWindows = true;
-                mWindowManagerInternal.setWindowsForAccessibilityCallback(this);
+                // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
+                mWindowManagerInternal.setWindowsForAccessibilityCallback(Display.DEFAULT_DISPLAY,
+                        this);
             }
         }
     }
@@ -213,7 +325,9 @@
     public void stopTrackingWindows() {
         synchronized (mLock) {
             if (mTrackingWindows) {
-                mWindowManagerInternal.setWindowsForAccessibilityCallback(null);
+                // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
+                mWindowManagerInternal.setWindowsForAccessibilityCallback(Display.DEFAULT_DISPLAY,
+                        null);
                 mTrackingWindows = false;
                 clearWindowsLocked();
             }
@@ -412,7 +526,8 @@
                 }
             }
         }
-        mWindowManagerInternal.computeWindowsForAccessibility();
+        // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
+        mWindowManagerInternal.computeWindowsForAccessibility(Display.DEFAULT_DISPLAY);
         return windowId;
     }
 
@@ -645,20 +760,20 @@
         boolean windowInteractiveRegionChanged = false;
 
         final int windowCount = mWindows.size();
-        final Rect currentWindowBounds = new Rect();
+        final Region currentWindowRegions = new Region();
         for (int i = windowCount - 1; i >= 0; i--) {
             AccessibilityWindowInfo currentWindow = mWindows.get(i);
             if (windowInteractiveRegion == null) {
                 if (currentWindow.getId() == windowId) {
-                    currentWindow.getBoundsInScreen(currentWindowBounds);
-                    outRegion.set(currentWindowBounds);
+                    currentWindow.getRegionInScreen(currentWindowRegions);
+                    outRegion.set(currentWindowRegions);
                     windowInteractiveRegion = outRegion;
                     continue;
                 }
             } else if (currentWindow.getType()
                     != AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) {
-                currentWindow.getBoundsInScreen(currentWindowBounds);
-                if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
+                currentWindow.getRegionInScreen(currentWindowRegions);
+                if (windowInteractiveRegion.op(currentWindowRegions, Region.Op.DIFFERENCE)) {
                     windowInteractiveRegionChanged = true;
                 }
             }
@@ -1005,10 +1120,11 @@
         reportedWindow.setType(getTypeForWindowManagerWindowType(window.type));
         reportedWindow.setLayer(window.layer);
         reportedWindow.setFocused(window.focused);
-        reportedWindow.setBoundsInScreen(window.boundsInScreen);
+        reportedWindow.setRegionInScreen(window.regionInScreen);
         reportedWindow.setTitle(window.title);
         reportedWindow.setAnchorId(window.accessibilityIdOfAnchor);
         reportedWindow.setPictureInPicture(window.inPictureInPicture);
+        reportedWindow.setDisplayId(window.displayId);
 
         final int parentId = findWindowIdLocked(userId, window.parentToken);
         if (parentId >= 0) {
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
index 2fbaee6..1d58e90 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationGestureHandler.java
@@ -39,6 +39,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.SystemClock;
 import android.util.Log;
 import android.util.MathUtils;
 import android.util.Slog;
@@ -622,6 +623,8 @@
         private MotionEvent mLastUp;
         private MotionEvent mPreLastUp;
 
+        private long mLastDetectingDownEventTime;
+
         @VisibleForTesting boolean mShortcutTriggered;
 
         @VisibleForTesting Handler mHandler = new Handler(Looper.getMainLooper(), this);
@@ -662,6 +665,7 @@
             switch (event.getActionMasked()) {
                 case MotionEvent.ACTION_DOWN: {
 
+                    mLastDetectingDownEventTime = event.getDownTime();
                     mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
 
                     if (!mMagnificationController.magnificationRegionContains(
@@ -838,14 +842,25 @@
         }
 
         private void sendDelayedMotionEvents() {
-            while (mDelayedEventQueue != null) {
+            if (mDelayedEventQueue == null) {
+                return;
+            }
+
+            // Adjust down time to prevent subsequent modules being misleading, and also limit
+            // the maximum offset to mMultiTapMaxDelay to prevent the down time of 2nd tap is
+            // in the future when multi-tap happens.
+            final long offset = Math.min(
+                    SystemClock.uptimeMillis() - mLastDetectingDownEventTime, mMultiTapMaxDelay);
+
+            do {
                 MotionEventInfo info = mDelayedEventQueue;
                 mDelayedEventQueue = info.mNext;
 
+                info.event.setDownTime(info.event.getDownTime() + offset);
                 handleEventWith(mDelegatingState, info.event, info.rawEvent, info.policyFlags);
 
                 info.recycle();
-            }
+            } while (mDelayedEventQueue != null);
         }
 
         private void clearDelayedMotionEvents() {
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index 1008eab..7920bbb 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -75,10 +75,6 @@
     // pointers so they can be considered moving in the same direction.
     private static final float MAX_DRAGGING_ANGLE_COS = 0.525321989f; // cos(pi/4)
 
-    // The minimal distance before we take the middle of the distance between
-    // the two dragging pointers as opposed to use the location of the primary one.
-    private static final int MIN_POINTER_DISTANCE_TO_USE_MIDDLE_LOCATION_DIP = 200;
-
     // The timeout after which we are no longer trying to detect a gesture.
     private static final int EXIT_GESTURE_DETECTION_TIMEOUT = 2000;
 
@@ -115,10 +111,6 @@
     // Helper to detect gestures.
     private final AccessibilityGestureDetector mGestureDetector;
 
-    // The scaled minimal distance before we take the middle of the distance between
-    // the two dragging pointers as opposed to use the location of the primary one.
-    private final int mScaledMinPointerDistanceToUseMiddleLocation;
-
     // Helper class to track received pointers.
     private final TouchState.ReceivedPointerTracker mReceivedPointerTracker;
 
@@ -188,9 +180,6 @@
         } else {
             mGestureDetector = detector;
         }
-        final float density = context.getResources().getDisplayMetrics().density;
-        mScaledMinPointerDistanceToUseMiddleLocation =
-            (int) (MIN_POINTER_DISTANCE_TO_USE_MIDDLE_LOCATION_DIP * density);
     }
 
     @Override
@@ -409,161 +398,185 @@
      * @param rawEvent The raw (unmodified) motion event.
      * @param policyFlags The policy flags associated with the event.
      */
-    private void handleMotionEventStateTouchExploring(MotionEvent event, MotionEvent rawEvent,
-            int policyFlags) {
+    private void handleMotionEventStateTouchExploring(
+            MotionEvent event, MotionEvent rawEvent, int policyFlags) {
         switch (event.getActionMasked()) {
-            case MotionEvent.ACTION_DOWN: {
-                mAms.onTouchInteractionStart();
+            case MotionEvent.ACTION_DOWN:
+                handleActionDownStateTouchExploring(event, policyFlags);
+                break;
+            case MotionEvent.ACTION_POINTER_DOWN:
+                handleActionPointerDownStateTouchExploring();
+                break;
+            case MotionEvent.ACTION_MOVE:
+                handleActionMoveStateTouchExploring(event, rawEvent, policyFlags);
+                break;
+            case MotionEvent.ACTION_UP:
+                handleActionUpStateTouchExploring(event, policyFlags);
+                break;
+        }
+    }
 
-                // If we still have not notified the user for the last
-                // touch, we figure out what to do. If were waiting
-                // we resent the delayed callback and wait again.
-                mSendHoverEnterAndMoveDelayed.cancel();
-                mSendHoverExitDelayed.cancel();
+    /**
+     * Handles ACTION_DOWN while in the default touch exploring state. This event represents the
+     * first finger touching the screen.
+     */
+    private void handleActionDownStateTouchExploring(MotionEvent event, int policyFlags) {
+        mAms.onTouchInteractionStart();
 
-                // If a touch exploration gesture is in progress send events for its end.
-                if (mState.isTouchExplorationInProgress()) {
-                    sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
-                }
+        // If we still have not notified the user for the last
+        // touch, we figure out what to do. If were waiting
+        // we resent the delayed callback and wait again.
+        mSendHoverEnterAndMoveDelayed.cancel();
+        mSendHoverExitDelayed.cancel();
 
-                // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double tap.
-                if (!mGestureDetector.firstTapDetected()) {
-                    mSendTouchExplorationEndDelayed.forceSendAndRemove();
-                    mSendTouchInteractionEndDelayed.forceSendAndRemove();
-                    sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
-                } else {
-                    // Let gesture to handle to avoid duplicated TYPE_TOUCH_INTERACTION_END event.
-                    mSendTouchInteractionEndDelayed.cancel();
-                }
+        // If a touch exploration gesture is in progress send events for its end.
+        if (mState.isTouchExplorationInProgress()) {
+            sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
+        }
 
-                if (!mGestureDetector.firstTapDetected()
-                        && !mState.isTouchExplorationInProgress()) {
-                    if (!mSendHoverEnterAndMoveDelayed.isPending()) {
-                        // Deliver hover enter with a delay to have a chance
-                        // to detect what the user is trying to do.
-                        final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
-                        final int pointerIdBits = (1 << pointerId);
-                        mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits,
-                                policyFlags);
-                    } else {
-                        // Cache the event until we discern exploration from gesturing.
-                        mSendHoverEnterAndMoveDelayed.addEvent(event);
-                    }
-                }
-            } break;
-            case MotionEvent.ACTION_POINTER_DOWN: {
-                // Another finger down means that if we have not started to deliver
-                // hover events, we will not have to. The code for ACTION_MOVE will
-                // decide what we will actually do next.
-                mSendHoverEnterAndMoveDelayed.cancel();
-                mSendHoverExitDelayed.cancel();
-            } break;
-            case MotionEvent.ACTION_MOVE: {
+        // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double
+        // tap.
+        if (!mGestureDetector.firstTapDetected()) {
+            mSendTouchExplorationEndDelayed.forceSendAndRemove();
+            mSendTouchInteractionEndDelayed.forceSendAndRemove();
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
+        } else {
+            // Let gesture to handle to avoid duplicated TYPE_TOUCH_INTERACTION_END event.
+            mSendTouchInteractionEndDelayed.cancel();
+        }
+
+        if (!mGestureDetector.firstTapDetected() && !mState.isTouchExplorationInProgress()) {
+            if (!mSendHoverEnterAndMoveDelayed.isPending()) {
+                // Deliver hover enter with a delay to have a chance
+                // to detect what the user is trying to do.
                 final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
-                final int pointerIndex = event.findPointerIndex(pointerId);
                 final int pointerIdBits = (1 << pointerId);
-                switch (event.getPointerCount()) {
-                    case 1: {
-                        // We have not started sending events since we try to
-                        // figure out what the user is doing.
-                        if (mSendHoverEnterAndMoveDelayed.isPending()) {
-                            // Cache the event until we discern exploration from gesturing.
-                            mSendHoverEnterAndMoveDelayed.addEvent(event);
-                        } else {
-                            if (mState.isTouchExplorationInProgress()) {
-                                sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
-                                sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits,
-                                        policyFlags);
-                            }
-                        }
-                    } break;
-                    case 2: {
-                        // More than one pointer so the user is not touch exploring
-                        // and now we have to decide whether to delegate or drag.
-                        if (mSendHoverEnterAndMoveDelayed.isPending()) {
-                            // We have not started sending events so cancel
-                            // scheduled sending events.
-                            mSendHoverEnterAndMoveDelayed.cancel();
-                            mSendHoverExitDelayed.cancel();
-                        } else {
-                            if (mState.isTouchExplorationInProgress()) {
-                                // If the user is touch exploring the second pointer may be
-                                // performing a double tap to activate an item without need
-                                // for the user to lift his exploring finger.
-                                // It is *important* to use the distance traveled by the pointers
-                                // on the screen which may or may not be magnified.
-                                final float deltaX =
-                                        mReceivedPointerTracker.getReceivedPointerDownX(pointerId)
-                                        - rawEvent.getX(pointerIndex);
-                                final float deltaY =
-                                        mReceivedPointerTracker.getReceivedPointerDownY(
-                                        pointerId) - rawEvent.getY(pointerIndex);
-                                final double moveDelta = Math.hypot(deltaX, deltaY);
-                                if (moveDelta < mDoubleTapSlop) {
-                                    break;
-                                }
-                                // We are sending events so send exit and gesture
-                                // end since we transition to another state.
-                                sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
-                            }
-                        }
+                mSendHoverEnterAndMoveDelayed.post(event, true, pointerIdBits, policyFlags);
+            } else {
+                // Cache the event until we discern exploration from gesturing.
+                mSendHoverEnterAndMoveDelayed.addEvent(event);
+            }
+        }
+    }
 
-                        // Remove move history before send injected non-move events
-                        event = MotionEvent.obtainNoHistory(event);
-                        if (isDraggingGesture(event)) {
-                            // Two pointers moving in the same direction within
-                            // a given distance perform a drag.
-                            mState.startDragging();
-                            mDraggingPointerId = pointerId;
-                            event.setEdgeFlags(
-                                    mReceivedPointerTracker.getLastReceivedDownEdgeFlags());
-                            sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits,
-                                    policyFlags);
-                        } else {
-                            // Two pointers moving arbitrary are delegated to the view hierarchy.
-                            mState.startDelegating();
-                            sendDownForAllNotInjectedPointers(event, policyFlags);
-                        }
-                    } break;
-                    default: {
-                        // More than one pointer so the user is not touch exploring
-                        // and now we have to decide whether to delegate or drag.
-                        if (mSendHoverEnterAndMoveDelayed.isPending()) {
-                            // We have not started sending events so cancel
-                            // scheduled sending events.
-                            mSendHoverEnterAndMoveDelayed.cancel();
-                            mSendHoverExitDelayed.cancel();
-                        } else {
-                            // We are sending events so send exit and gesture
-                            // end since we transition to another state.
-                            sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
-                        }
-
-                        // More than two pointers are delegated to the view hierarchy.
-                        mState.startDelegating();
-                        event = MotionEvent.obtainNoHistory(event);
-                        sendDownForAllNotInjectedPointers(event, policyFlags);
-                    }
-                }
-            } break;
-            case MotionEvent.ACTION_UP: {
-                mAms.onTouchInteractionEnd();
-                final int pointerId = event.getPointerId(event.getActionIndex());
-                final int pointerIdBits = (1 << pointerId);
-
+    /**
+     * Handles ACTION_POINTER_DOWN when in the touch exploring state. This event represents an
+     * additional finger touching the screen.
+     */
+    private void handleActionPointerDownStateTouchExploring() {
+        // Another finger down means that if we have not started to deliver
+        // hover events, we will not have to. The code for ACTION_MOVE will
+        // decide what we will actually do next.
+        mSendHoverEnterAndMoveDelayed.cancel();
+        mSendHoverExitDelayed.cancel();
+    }
+    /**
+     * Handles ACTION_MOVE while in the initial touch exploring state. This is where transitions to
+     * delegating and dragging states are handled.
+     */
+    private void handleActionMoveStateTouchExploring(
+            MotionEvent event, MotionEvent rawEvent, int policyFlags) {
+        final int pointerId = mReceivedPointerTracker.getPrimaryPointerId();
+        final int pointerIndex = event.findPointerIndex(pointerId);
+        final int pointerIdBits = (1 << pointerId);
+        switch (event.getPointerCount()) {
+            case 1:
+                // We have not started sending events since we try to
+                // figure out what the user is doing.
                 if (mSendHoverEnterAndMoveDelayed.isPending()) {
-                    // If we have not delivered the enter schedule an exit.
-                    mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags);
-                } else {
-                    // The user is touch exploring so we send events for end.
+                    // Cache the event until we discern exploration from gesturing.
+                    mSendHoverEnterAndMoveDelayed.addEvent(event);
+                } else if (mState.isTouchExplorationInProgress()) {
+                    sendTouchExplorationGestureStartAndHoverEnterIfNeeded(policyFlags);
+                    sendMotionEvent(
+                            event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags);
+                }
+                break;
+            case 2:
+                // More than one pointer so the user is not touch exploring
+                // and now we have to decide whether to delegate or drag.
+                if (mSendHoverEnterAndMoveDelayed.isPending()) {
+                    // We have not started sending events so cancel
+                    // scheduled sending events.
+                    mSendHoverEnterAndMoveDelayed.cancel();
+                    mSendHoverExitDelayed.cancel();
+                } else if (mState.isTouchExplorationInProgress()) {
+                    // If the user is touch exploring the second pointer may be
+                    // performing a double tap to activate an item without need
+                    // for the user to lift his exploring finger.
+                    // It is *important* to use the distance traveled by the pointers
+                    // on the screen which may or may not be magnified.
+                    final float deltaX =
+                            mReceivedPointerTracker.getReceivedPointerDownX(pointerId)
+                                    - rawEvent.getX(pointerIndex);
+                    final float deltaY =
+                            mReceivedPointerTracker.getReceivedPointerDownY(pointerId)
+                                    - rawEvent.getY(pointerIndex);
+                    final double moveDelta = Math.hypot(deltaX, deltaY);
+                    if (moveDelta < mDoubleTapSlop) {
+                        break;
+                    }
+                    // We are sending events so send exit and gesture
+                    // end since we transition to another state.
                     sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
                 }
 
-                if (!mSendTouchInteractionEndDelayed.isPending()) {
-                    mSendTouchInteractionEndDelayed.post();
+                // Remove move history before send injected non-move events
+                event = MotionEvent.obtainNoHistory(event);
+                if (isDraggingGesture(event)) {
+                    // Two pointers moving in the same direction within
+                    // a given distance perform a drag.
+                    mState.startDragging();
+                    mDraggingPointerId = pointerId;
+                    event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags());
+                    sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits, policyFlags);
+                } else {
+                    // Two pointers moving arbitrary are delegated to the view hierarchy.
+                    mState.startDelegating();
+                    sendDownForAllNotInjectedPointers(event, policyFlags);
+                }
+                break;
+            default:
+                // More than one pointer so the user is not touch exploring
+                // and now we have to decide whether to delegate or drag.
+                if (mSendHoverEnterAndMoveDelayed.isPending()) {
+                    // We have not started sending events so cancel
+                    // scheduled sending events.
+                    mSendHoverEnterAndMoveDelayed.cancel();
+                    mSendHoverExitDelayed.cancel();
+                } else {
+                    // We are sending events so send exit and gesture
+                    // end since we transition to another state.
+                    sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
                 }
 
-            } break;
+                // More than two pointers are delegated to the view hierarchy.
+                mState.startDelegating();
+                event = MotionEvent.obtainNoHistory(event);
+                sendDownForAllNotInjectedPointers(event, policyFlags);
+                break;
+        }
+    }
+
+    /**
+     * Handles ACTION_UP while in the initial touch exploring state. This event represents all
+     * fingers being lifted from the screen.
+     */
+    private void handleActionUpStateTouchExploring(MotionEvent event, int policyFlags) {
+        mAms.onTouchInteractionEnd();
+        final int pointerId = event.getPointerId(event.getActionIndex());
+        final int pointerIdBits = (1 << pointerId);
+
+        if (mSendHoverEnterAndMoveDelayed.isPending()) {
+            // If we have not delivered the enter schedule an exit.
+            mSendHoverExitDelayed.post(event, pointerIdBits, policyFlags);
+        } else {
+            // The user is touch exploring so we send events for end.
+            sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
+        }
+
+        if (!mSendTouchInteractionEndDelayed.isPending()) {
+            mSendTouchInteractionEndDelayed.post();
         }
     }
 
@@ -610,11 +623,11 @@
                     } break;
                     case 2: {
                         if (isDraggingGesture(event)) {
+                            // Adjust event location to the middle location of the two pointers.
                             final float firstPtrX = event.getX(0);
                             final float firstPtrY = event.getY(0);
                             final float secondPtrX = event.getX(1);
                             final float secondPtrY = event.getY(1);
-
                             final int pointerIndex = event.findPointerIndex(mDraggingPointerId);
                             final float deltaX =
                                     (pointerIndex == 0) ? (secondPtrX - firstPtrX)
@@ -622,12 +635,7 @@
                             final float deltaY =
                                     (pointerIndex == 0) ? (secondPtrY - firstPtrY)
                                             : (firstPtrY - secondPtrY);
-                            final double distance = Math.hypot(deltaX, deltaY);
-
-                            if (distance > mScaledMinPointerDistanceToUseMiddleLocation) {
-                                event.offsetLocation(deltaX / 2, deltaY / 2);
-                            }
-
+                            event.offsetLocation(deltaX / 2, deltaY / 2);
                             // If still dragging send a drag event.
                             sendMotionEvent(event, MotionEvent.ACTION_MOVE, pointerIdBits,
                                     policyFlags);
@@ -1181,8 +1189,6 @@
                 + ", mLongPressingPointerId: " + mLongPressingPointerId
                 + ", mLongPressingPointerDeltaX: " + mLongPressingPointerDeltaX
                 + ", mLongPressingPointerDeltaY: " + mLongPressingPointerDeltaY
-                + ", mScaledMinPointerDistanceToUseMiddleLocation: "
-                + mScaledMinPointerDistanceToUseMiddleLocation
                 + ", mTempPoint: " + mTempPoint
                 + " }";
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
index 285bd09..2698b72 100644
--- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
@@ -27,6 +27,7 @@
 import android.os.IBinder.DeathRecipient;
 import android.os.RemoteException;
 import android.util.Slog;
+import android.view.Display;
 import android.view.accessibility.AccessibilityEvent;
 
 import com.android.internal.util.DumpUtils;
@@ -246,7 +247,8 @@
                     // another thread.
                     if (serviceInterface != null) {
                         service.linkToDeath(this, 0);
-                        serviceInterface.init(this, mId, mOverlayWindowToken);
+                        serviceInterface.init(this, mId,
+                                mOverlayWindowTokens.get(Display.DEFAULT_DISPLAY));
                     }
                 } catch (RemoteException re) {
                     Slog.w(LOG_TAG, "Error initialized connection", re);
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 10ba9a5..03c4542 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -28,7 +28,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ServiceInfo;
-import android.os.IBinder;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.service.appprediction.AppPredictionService;
 import android.util.ArrayMap;
@@ -37,7 +37,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.infra.AbstractPerUserSystemService;
 
-import java.util.ArrayList;
+import java.util.function.Consumer;
 
 /**
  * Per-user instance of {@link AppPredictionManagerService}.
@@ -108,15 +108,10 @@
         if (service != null) {
             service.onCreatePredictionSession(context, sessionId);
 
-            mSessionInfos.put(sessionId, new AppPredictionSessionInfo(sessionId, context, () -> {
-                synchronized (mLock) {
-                    AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
-                    if (sessionInfo != null) {
-                        sessionInfo.removeAllCallbacksLocked();
-                        mSessionInfos.remove(sessionId);
-                    }
-                }
-            }));
+            if (!mSessionInfos.containsKey(sessionId)) {
+                mSessionInfos.put(sessionId, new AppPredictionSessionInfo(sessionId, context,
+                        this::removeAppPredictionSessionInfo));
+            }
         }
     }
 
@@ -212,8 +207,7 @@
 
             AppPredictionSessionInfo sessionInfo = mSessionInfos.get(sessionId);
             if (sessionInfo != null) {
-                sessionInfo.removeAllCallbacksLocked();
-                mSessionInfos.remove(sessionId);
+                sessionInfo.destroy();
             }
         }
     }
@@ -273,6 +267,15 @@
         }
     }
 
+    private void removeAppPredictionSessionInfo(AppPredictionSessionId sessionId) {
+        if (isDebug()) {
+            Slog.d(TAG, "removeAppPredictionSessionInfo(): sessionId=" + sessionId);
+        }
+        synchronized (mLock) {
+            mSessionInfos.remove(sessionId);
+        }
+    }
+
     @GuardedBy("mLock")
     @Nullable
     private RemoteAppPredictionService getRemoteServiceLocked() {
@@ -295,55 +298,71 @@
     }
 
     private static final class AppPredictionSessionInfo {
-        private final AppPredictionSessionId mSessionId;
-        private final AppPredictionContext mContext;
-        private final ArrayList<IPredictionCallback> mCallbacks = new ArrayList<>();
-        private final IBinder.DeathRecipient mBinderDeathHandler;
+        private static final boolean DEBUG = false;  // Do not submit with true
 
-        AppPredictionSessionInfo(AppPredictionSessionId id, AppPredictionContext context,
-                IBinder.DeathRecipient binderDeathHandler) {
+        private final AppPredictionSessionId mSessionId;
+        private final AppPredictionContext mPredictionContext;
+        private final Consumer<AppPredictionSessionId> mRemoveSessionInfoAction;
+
+        private final RemoteCallbackList<IPredictionCallback> mCallbacks =
+                new RemoteCallbackList<IPredictionCallback>() {
+                    @Override
+                    public void onCallbackDied(IPredictionCallback callback) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Binder died for session Id=" + mSessionId
+                                    + " and callback=" + callback.asBinder());
+                        }
+                        if (mCallbacks.getRegisteredCallbackCount() == 0) {
+                            destroy();
+                        }
+                    }
+                };
+
+        AppPredictionSessionInfo(AppPredictionSessionId id, AppPredictionContext predictionContext,
+                Consumer<AppPredictionSessionId> removeSessionInfoAction) {
+            if (DEBUG) {
+                Slog.d(TAG, "Creating AppPredictionSessionInfo for session Id=" + id);
+            }
             mSessionId = id;
-            mContext = context;
-            mBinderDeathHandler = binderDeathHandler;
+            mPredictionContext = predictionContext;
+            mRemoveSessionInfoAction = removeSessionInfoAction;
         }
 
         void addCallbackLocked(IPredictionCallback callback) {
-            if (mBinderDeathHandler != null) {
-                try {
-                    callback.asBinder().linkToDeath(mBinderDeathHandler, 0);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Failed to link to death: " + e);
-                }
+            if (DEBUG) {
+                Slog.d(TAG, "Storing callback for session Id=" + mSessionId
+                        + " and callback=" + callback.asBinder());
             }
-            mCallbacks.add(callback);
+            mCallbacks.register(callback);
         }
 
         void removeCallbackLocked(IPredictionCallback callback) {
-            if (mBinderDeathHandler != null) {
-                callback.asBinder().unlinkToDeath(mBinderDeathHandler, 0);
+            if (DEBUG) {
+                Slog.d(TAG, "Removing callback for session Id=" + mSessionId
+                        + " and callback=" + callback.asBinder());
             }
-            mCallbacks.remove(callback);
+            mCallbacks.unregister(callback);
         }
 
-        void removeAllCallbacksLocked() {
-            if (mBinderDeathHandler != null) {
-                for (IPredictionCallback callback : mCallbacks) {
-                    callback.asBinder().unlinkToDeath(mBinderDeathHandler, 0);
-                }
+        void destroy() {
+            if (DEBUG) {
+                Slog.d(TAG, "Removing all callbacks for session Id=" + mSessionId
+                        + " and " + mCallbacks.getRegisteredCallbackCount() + " callbacks.");
             }
-            mCallbacks.clear();
+            mCallbacks.kill();
+            mRemoveSessionInfoAction.accept(mSessionId);
         }
 
         void resurrectSessionLocked(AppPredictionPerUserService service) {
-            if (service.isDebug()) {
+            int callbackCount = mCallbacks.getRegisteredCallbackCount();
+            if (DEBUG) {
                 Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked()
                         + ") for session Id=" + mSessionId + " and "
-                        + mCallbacks.size() + " callbacks.");
+                        + callbackCount + " callbacks.");
             }
-            service.onCreatePredictionSessionLocked(mContext, mSessionId);
-            for (IPredictionCallback callback : mCallbacks) {
-                service.registerPredictionUpdatesLocked(mSessionId, callback);
-            }
+            service.onCreatePredictionSessionLocked(mPredictionContext, mSessionId);
+            mCallbacks.broadcast(
+                    callback -> service.registerPredictionUpdatesLocked(mSessionId, callback));
         }
     }
 }
diff --git a/services/art-profile b/services/art-profile
index a9d5982..cbc4627 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -16071,7 +16071,7 @@
 PLcom/android/server/wm/DisplayPolicy;->offsetInputMethodWindowLw(Lcom/android/server/wm/WindowState;Lcom/android/server/wm/DisplayFrames;)V
 HSPLcom/android/server/wm/DisplayPolicy;->onConfigurationChanged()V
 PLcom/android/server/wm/DisplayPolicy;->onPowerKeyDown(Z)V
-HSPLcom/android/server/wm/DisplayPolicy;->prepareAddWindowLw(Lcom/android/server/wm/WindowState;Landroid/view/WindowManager$LayoutParams;)I
+HSPLcom/android/server/wm/DisplayPolicy;->validateAddingWindowLw(Landroid/view/WindowManager$LayoutParams;)I
 HSPLcom/android/server/wm/DisplayPolicy;->removeWindowLw(Lcom/android/server/wm/WindowState;)V
 HSPLcom/android/server/wm/DisplayPolicy;->requestTransientBars(Lcom/android/server/wm/WindowState;)V
 HSPLcom/android/server/wm/DisplayPolicy;->resetSystemUiVisibilityLw()V
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index aada967..1e1e07d 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -769,6 +769,19 @@
     }
 
     /**
+     * Updates the last fill response when a dataset is shown.
+     */
+    void logDatasetShown(int sessionId, @Nullable Bundle clientState) {
+        synchronized (mLock) {
+            if (isValidEventLocked("logDatasetShown", sessionId)) {
+                mEventHistory.addEvent(
+                        new Event(Event.TYPE_DATASETS_SHOWN, null, clientState, null, null, null,
+                                null, null, null, null, null));
+            }
+        }
+    }
+
+    /**
      * Updates the last fill response when an autofill context is committed.
      */
     @GuardedBy("mLock")
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 44f19ff..5a9320f 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -187,10 +187,9 @@
                 if (err instanceof TimeoutException) {
                     dispatchCancellationSignal(cancellationSink.get());
                     mCallbacks.onFillRequestTimeout(request.getId());
+                } else if (err instanceof CancellationException) {
+                    dispatchCancellationSignal(cancellationSink.get());
                 } else {
-                    if (err instanceof CancellationException) {
-                        dispatchCancellationSignal(cancellationSink.get());
-                    }
                     mCallbacks.onFillRequestFailure(request.getId(), err.getMessage());
                 }
             }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 66b5437..46c2a85 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -569,12 +569,13 @@
     @GuardedBy("mLock")
     private void requestNewFillResponseLocked(@NonNull ViewState viewState, int newState,
             int flags) {
-        if (mForAugmentedAutofillOnly) {
+        if (mForAugmentedAutofillOnly || mRemoteFillService == null) {
             if (sVerbose) {
                 Slog.v(TAG, "requestNewFillResponse(): triggering augmented autofill instead "
                         + "(mForAugmentedAutofillOnly=" + mForAugmentedAutofillOnly
                         + ", flags=" + flags + ")");
             }
+            mForAugmentedAutofillOnly = true;
             triggerAugmentedAutofillLocked();
             return;
         }
@@ -2178,6 +2179,7 @@
     private void requestNewFillResponseOnViewEnteredIfNecessaryLocked(@NonNull AutofillId id,
             @NonNull ViewState viewState, int flags) {
         if ((flags & FLAG_MANUAL_REQUEST) != 0) {
+            mForAugmentedAutofillOnly = false;
             if (sDebug) Slog.d(TAG, "Re-starting session on view " + id + " and flags " + flags);
             requestNewFillResponseLocked(viewState, ViewState.STATE_RESTARTED_SESSION, flags);
             return;
@@ -2495,6 +2497,8 @@
                 mService.getServicePackageName(), mComponentName,
                 serviceLabel, serviceIcon, this, id, mCompatMode);
 
+        mService.logDatasetShown(id, mClientState);
+
         synchronized (mLock) {
             if (mUiShownTime == 0) {
                 // Log first time UI is shown.
@@ -2922,6 +2926,7 @@
             if (sVerbose) {
                 Slog.v(TAG, "Adding autofillable view with id " + id + " and state " + state);
             }
+            viewState.setCurrentValue(findValueLocked(id));
             mViewStates.put(id, viewState);
         }
         if ((state & ViewState.STATE_AUTOFILLED) != 0) {
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index e1b089c..84886f8 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -227,6 +227,7 @@
         if (mVirtualBounds != null) {
             builder.append(", virtualBounds:" ).append(mVirtualBounds);
         }
+        builder.append("]");
         return builder.toString();
     }
 
diff --git a/services/backup/java/com/android/server/backup/BackupAgentTimeoutParameters.java b/services/backup/java/com/android/server/backup/BackupAgentTimeoutParameters.java
index 2bca34d..0e99b34 100644
--- a/services/backup/java/com/android/server/backup/BackupAgentTimeoutParameters.java
+++ b/services/backup/java/com/android/server/backup/BackupAgentTimeoutParameters.java
@@ -16,14 +16,12 @@
 
 package com.android.server.backup;
 
-import static com.android.server.backup.BackupManagerService.DEBUG_SCHEDULING;
 
 import android.content.ContentResolver;
 import android.os.Handler;
 import android.provider.Settings;
 import android.util.KeyValueListParser;
 import android.util.KeyValueSettingObserver;
-import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -35,8 +33,6 @@
  * are represented as a comma-delimited key value list.
  */
 public class BackupAgentTimeoutParameters extends KeyValueSettingObserver {
-    private static final String TAG = "BackupAgentTimeout";
-
     @VisibleForTesting
     public static final String SETTING = Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS;
 
@@ -140,62 +136,36 @@
 
     public long getKvBackupAgentTimeoutMillis() {
         synchronized (mLock) {
-            if (DEBUG_SCHEDULING) {
-                Slog.v(TAG, "getKvBackupAgentTimeoutMillis(): " + mKvBackupAgentTimeoutMillis);
-            }
             return mKvBackupAgentTimeoutMillis;
         }
     }
 
     public long getFullBackupAgentTimeoutMillis() {
         synchronized (mLock) {
-            if (DEBUG_SCHEDULING) {
-                Slog.v(TAG, "getFullBackupAgentTimeoutMillis(): " + mFullBackupAgentTimeoutMillis);
-            }
             return mFullBackupAgentTimeoutMillis;
         }
     }
 
     public long getSharedBackupAgentTimeoutMillis() {
         synchronized (mLock) {
-            if (DEBUG_SCHEDULING) {
-                Slog.v(
-                        TAG,
-                        "getSharedBackupAgentTimeoutMillis(): " + mSharedBackupAgentTimeoutMillis);
-            }
             return mSharedBackupAgentTimeoutMillis;
         }
     }
 
     public long getRestoreAgentTimeoutMillis() {
         synchronized (mLock) {
-            if (DEBUG_SCHEDULING) {
-                Slog.v(TAG, "getRestoreAgentTimeoutMillis(): " + mRestoreAgentTimeoutMillis);
-            }
             return mRestoreAgentTimeoutMillis;
         }
     }
 
     public long getRestoreAgentFinishedTimeoutMillis() {
         synchronized (mLock) {
-            if (DEBUG_SCHEDULING) {
-                Slog.v(
-                        TAG,
-                        "getRestoreAgentFinishedTimeoutMillis(): "
-                                + mRestoreAgentFinishedTimeoutMillis);
-            }
             return mRestoreAgentFinishedTimeoutMillis;
         }
     }
 
     public long getQuotaExceededTimeoutMillis() {
         synchronized (mLock) {
-            if (DEBUG_SCHEDULING) {
-                Slog.v(
-                        TAG,
-                        "getQuotaExceededTimeoutMillis(): "
-                                + mQuotaExceededTimeoutMillis);
-            }
             return mQuotaExceededTimeoutMillis;
         }
     }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerConstants.java b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
index 785d3ca..d8c5f6f 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerConstants.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
@@ -19,6 +19,7 @@
 import static com.android.server.backup.BackupManagerService.DEBUG_SCHEDULING;
 
 import android.app.AlarmManager;
+import android.app.job.JobInfo;
 import android.content.ContentResolver;
 import android.os.Handler;
 import android.provider.Settings;
@@ -80,14 +81,18 @@
     public static final long DEFAULT_KEY_VALUE_BACKUP_FUZZ_MILLISECONDS = 10 * 60 * 1000;
 
     @VisibleForTesting public static final boolean DEFAULT_KEY_VALUE_BACKUP_REQUIRE_CHARGING = true;
-    @VisibleForTesting public static final int DEFAULT_KEY_VALUE_BACKUP_REQUIRED_NETWORK_TYPE = 1;
+    @VisibleForTesting
+    public static final int DEFAULT_KEY_VALUE_BACKUP_REQUIRED_NETWORK_TYPE =
+            JobInfo.NETWORK_TYPE_ANY;
 
     @VisibleForTesting
     public static final long DEFAULT_FULL_BACKUP_INTERVAL_MILLISECONDS =
             24 * AlarmManager.INTERVAL_HOUR;
 
     @VisibleForTesting public static final boolean DEFAULT_FULL_BACKUP_REQUIRE_CHARGING = true;
-    @VisibleForTesting public static final int DEFAULT_FULL_BACKUP_REQUIRED_NETWORK_TYPE = 2;
+    @VisibleForTesting
+    public static final int DEFAULT_FULL_BACKUP_REQUIRED_NETWORK_TYPE =
+            JobInfo.NETWORK_TYPE_UNMETERED;
 
     @VisibleForTesting
     public static final String DEFAULT_BACKUP_FINISHED_NOTIFICATION_RECEIVERS = "";
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 302e3ff..d5a7c81 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -39,7 +39,6 @@
 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;
 import android.os.Trace;
@@ -87,7 +86,6 @@
 
     private final Context mContext;
     private final Trampoline mTrampoline;
-    private final HandlerThread mBackupThread;
 
     // Keeps track of all unlocked users registered with this service. Indexed by user id.
     private final SparseArray<UserBackupManagerService> mServiceUsers = new SparseArray<>();
@@ -107,11 +105,9 @@
     };
 
     /** Instantiate a new instance of {@link BackupManagerService}. */
-    public BackupManagerService(
-            Context context, Trampoline trampoline, HandlerThread backupThread) {
+    public BackupManagerService(Context context, Trampoline trampoline) {
         mContext = checkNotNull(context);
         mTrampoline = checkNotNull(trampoline);
-        mBackupThread = checkNotNull(backupThread);
 
         // Set up our transport options.
         SystemConfig systemConfig = SystemConfig.getInstance();
@@ -198,6 +194,11 @@
         }
     }
 
+    boolean isAbleToServeUser(int userId) {
+        return getServiceUsers().get(UserHandle.USER_SYSTEM) != null
+                && getServiceUsers().get(userId) != null;
+    }
+
     /**
      *  Returns a lst of users currently unlocked that have a
      *  {@link UserBackupManagerService} registered.
diff --git a/services/backup/java/com/android/server/backup/FullBackupJob.java b/services/backup/java/com/android/server/backup/FullBackupJob.java
index f62a875..088e1f9 100644
--- a/services/backup/java/com/android/server/backup/FullBackupJob.java
+++ b/services/backup/java/com/android/server/backup/FullBackupJob.java
@@ -16,6 +16,8 @@
 
 package com.android.server.backup;
 
+import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
@@ -37,7 +39,7 @@
     public static final int MAX_JOB_ID = 52419896;
 
     private static ComponentName sIdleService =
-            new ComponentName("android", FullBackupJob.class.getName());
+            new ComponentName(PLATFORM_PACKAGE_NAME, FullBackupJob.class.getName());
 
     @GuardedBy("mParamsForUser")
     private final SparseArray<JobParameters> mParamsForUser = new SparseArray<>();
diff --git a/services/backup/java/com/android/server/backup/KeyValueBackupJob.java b/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
index 72d81d3..ac43fc3 100644
--- a/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
+++ b/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
@@ -17,6 +17,7 @@
 package com.android.server.backup;
 
 import static com.android.server.backup.BackupManagerService.DEBUG_SCHEDULING;
+import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.app.AlarmManager;
 import android.app.job.JobInfo;
@@ -43,7 +44,7 @@
 public class KeyValueBackupJob extends JobService {
     private static final String TAG = "KeyValueBackupJob";
     private static ComponentName sKeyValueJobService =
-            new ComponentName("android", KeyValueBackupJob.class.getName());
+            new ComponentName(PLATFORM_PACKAGE_NAME, KeyValueBackupJob.class.getName());
 
     private static final String USER_ID_EXTRA_KEY = "userId";
 
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index a9b292b3..f4b6645 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -110,15 +110,15 @@
     private final Object mStateLock = new Object();
 
     private volatile BackupManagerService mService;
-    private HandlerThread mHandlerThread;
-    private Handler mHandler;
+    private final Handler mHandler;
 
     public Trampoline(Context context) {
         mContext = context;
         mGlobalDisable = isBackupDisabled();
-        mHandlerThread = new HandlerThread(BACKUP_THREAD, Process.THREAD_PRIORITY_BACKGROUND);
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
+        HandlerThread handlerThread =
+                new HandlerThread(BACKUP_THREAD, Process.THREAD_PRIORITY_BACKGROUND);
+        handlerThread.start();
+        mHandler = new Handler(handlerThread.getLooper());
         mUserManager = UserManager.get(context);
     }
 
@@ -202,11 +202,10 @@
         }
     }
 
-    // A user is ready for a backup if it's unlocked and is not suppressed by a device
-    // admin (device owner or profile owner).
+    // This method should not perform any I/O (e.g. do not call isBackupActivatedForUser),
+    // it's used in multiple places where I/O waits would cause system lock-ups.
     private boolean isUserReadyForBackup(int userId) {
-        return mService != null && mService.getServiceUsers().get(userId) != null
-                && isBackupActivatedForUser(userId);
+        return mService != null && mService.isAbleToServeUser(userId);
     }
 
     /**
@@ -232,7 +231,7 @@
     }
 
     protected BackupManagerService createBackupManagerService() {
-        return new BackupManagerService(mContext, this, mHandlerThread);
+        return new BackupManagerService(mContext, this);
     }
 
     protected void postToHandler(Runnable runnable) {
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index c0af99c..ed4e596 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -367,6 +367,9 @@
     private long mCurrentToken = 0;
     @Nullable private File mAncestralSerialNumberFile;
 
+    private final ContentObserver mSetupObserver;
+    private final BroadcastReceiver mRunBackupReceiver;
+    private final BroadcastReceiver mRunInitReceiver;
 
     /**
      * Creates an instance of {@link UserBackupManagerService} and initializes state for it. This
@@ -493,11 +496,11 @@
         mAutoRestore = Settings.Secure.getIntForUser(resolver,
                 Settings.Secure.BACKUP_AUTO_RESTORE, 1, userId) != 0;
 
-        ContentObserver setupObserver = new SetupObserver(this, mBackupHandler);
+        mSetupObserver = new SetupObserver(this, mBackupHandler);
         resolver.registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE),
                 /* notifyForDescendents */ false,
-                setupObserver,
+                mSetupObserver,
                 mUserId);
 
         mBaseStateDir = checkNotNull(baseStateDir, "baseStateDir cannot be null");
@@ -516,21 +519,21 @@
         mBackupPasswordManager = new BackupPasswordManager(mContext, mBaseStateDir, mRng);
 
         // Receivers for scheduled backups and transport initialization operations.
-        BroadcastReceiver runBackupReceiver = new RunBackupReceiver(this);
+        mRunBackupReceiver = new RunBackupReceiver(this);
         IntentFilter filter = new IntentFilter();
         filter.addAction(RUN_BACKUP_ACTION);
         context.registerReceiverAsUser(
-                runBackupReceiver,
+                mRunBackupReceiver,
                 UserHandle.of(userId),
                 filter,
                 android.Manifest.permission.BACKUP,
                 /* scheduler */ null);
 
-        BroadcastReceiver runInitReceiver = new RunInitializeReceiver(this);
+        mRunInitReceiver = new RunInitializeReceiver(this);
         filter = new IntentFilter();
         filter.addAction(RUN_INITIALIZE_ACTION);
         context.registerReceiverAsUser(
-                runInitReceiver,
+                mRunInitReceiver,
                 UserHandle.of(userId),
                 filter,
                 android.Manifest.permission.BACKUP,
@@ -599,6 +602,12 @@
 
     /** Cleans up state when the user of this service is stopped. */
     void tearDownService() {
+        mAgentTimeoutParameters.stop();
+        mConstants.stop();
+        mContext.getContentResolver().unregisterContentObserver(mSetupObserver);
+        mContext.unregisterReceiver(mRunBackupReceiver);
+        mContext.unregisterReceiver(mRunInitReceiver);
+        mContext.unregisterReceiver(mPackageTrackingReceiver);
         mUserBackupThread.quit();
     }
 
@@ -747,7 +756,7 @@
 
     @VisibleForTesting
     BroadcastReceiver getPackageTrackingReceiver() {
-        return mBroadcastReceiver;
+        return mPackageTrackingReceiver;
     }
 
     @Nullable
@@ -788,10 +797,6 @@
         mPendingInits.clear();
     }
 
-    public PerformFullTransportBackupTask getRunningFullBackupTask() {
-        return mRunningFullBackupTask;
-    }
-
     public void setRunningFullBackupTask(
             PerformFullTransportBackupTask runningFullBackupTask) {
         mRunningFullBackupTask = runningFullBackupTask;
@@ -874,7 +879,7 @@
         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         filter.addDataScheme("package");
         mContext.registerReceiverAsUser(
-                mBroadcastReceiver,
+                mPackageTrackingReceiver,
                 UserHandle.of(mUserId),
                 filter,
                 /* broadcastPermission */ null,
@@ -885,7 +890,7 @@
         sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
         sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
         mContext.registerReceiverAsUser(
-                mBroadcastReceiver,
+                mPackageTrackingReceiver,
                 UserHandle.of(mUserId),
                 sdFilter,
                 /* broadcastPermission */ null,
@@ -1158,7 +1163,7 @@
      * A {@link BroadcastReceiver} tracking changes to packages and sd cards in order to update our
      * internal bookkeeping.
      */
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+    private BroadcastReceiver mPackageTrackingReceiver = new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
             if (MORE_DEBUG) {
                 Slog.d(TAG, "Received broadcast " + intent);
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java b/services/backup/java/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.java
new file mode 100644
index 0000000..ae2e150
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutput.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.server.backup.encryption.chunking;
+
+import static com.android.internal.util.Preconditions.checkState;
+
+import android.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.backup.encryption.tasks.DecryptedChunkOutput;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/** Writes plaintext chunks to a file, building a digest of the plaintext of the resulting file. */
+public class DecryptedChunkFileOutput implements DecryptedChunkOutput {
+    @VisibleForTesting static final String DIGEST_ALGORITHM = "SHA-256";
+
+    private final File mOutputFile;
+    private final MessageDigest mMessageDigest;
+    @Nullable private FileOutputStream mFileOutputStream;
+    private boolean mClosed;
+    @Nullable private byte[] mDigest;
+
+    /**
+     * Constructs a new instance which writes chunks to the given file and uses the default message
+     * digest algorithm.
+     */
+    public DecryptedChunkFileOutput(File outputFile) {
+        mOutputFile = outputFile;
+        try {
+            mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
+        } catch (NoSuchAlgorithmException e) {
+            throw new AssertionError(
+                    "Impossible condition: JCE thinks it does not support AES.", e);
+        }
+    }
+
+    @Override
+    public DecryptedChunkOutput open() throws IOException {
+        checkState(mFileOutputStream == null, "Cannot open twice");
+        mFileOutputStream = new FileOutputStream(mOutputFile);
+        return this;
+    }
+
+    @Override
+    public void processChunk(byte[] plaintextBuffer, int length) throws IOException {
+        checkState(mFileOutputStream != null, "Must open before processing chunks");
+        mFileOutputStream.write(plaintextBuffer, /*off=*/ 0, length);
+        mMessageDigest.update(plaintextBuffer, /*offset=*/ 0, length);
+    }
+
+    @Override
+    public byte[] getDigest() {
+        checkState(mClosed, "Must close before getting mDigest");
+
+        // After the first call to mDigest() the MessageDigest is reset, thus we must store the
+        // result.
+        if (mDigest == null) {
+            mDigest = mMessageDigest.digest();
+        }
+        return mDigest;
+    }
+
+    @Override
+    public void close() throws IOException {
+        mFileOutputStream.close();
+        mClosed = true;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
index ebf09df..a425c72 100644
--- a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
+++ b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
@@ -35,7 +35,7 @@
             mKeyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
             mKeyGenerator.init(KEY_SIZE_BITS, secureRandom);
         } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException(
+            throw new AssertionError(
                     "Impossible condition: JCE thinks it does not support AES.", e);
         }
     }
diff --git a/services/backup/java/com/android/server/backup/encryption/tasks/BackupEncrypter.java b/services/backup/java/com/android/server/backup/encryption/tasks/BackupEncrypter.java
new file mode 100644
index 0000000..95d0d97
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/tasks/BackupEncrypter.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.encryption.tasks;
+
+import static java.util.Collections.unmodifiableList;
+
+import android.annotation.Nullable;
+
+import com.android.server.backup.encryption.chunk.ChunkHash;
+import com.android.server.backup.encryption.chunking.EncryptedChunk;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+
+/** Task which reads data from some source, splits it into chunks and encrypts new chunks. */
+public interface BackupEncrypter {
+    /** The algorithm which we use to compute the digest of the backup file plaintext. */
+    String MESSAGE_DIGEST_ALGORITHM = "SHA-256";
+
+    /**
+     * Splits the backup input into encrypted chunks and encrypts new chunks.
+     *
+     * @param secretKey Key used to encrypt backup.
+     * @param fingerprintMixerSalt Fingerprint mixer salt used for content-defined chunking during a
+     *     full backup. Should be {@code null} for a key-value backup.
+     * @param existingChunks Set of the SHA-256 Macs of chunks the server already has.
+     * @return a result containing an array of new encrypted chunks to upload, and an ordered
+     *     listing of the chunks in the backup file.
+     * @throws IOException if a problem occurs reading from the backup data.
+     * @throws GeneralSecurityException if there is a problem encrypting the data.
+     */
+    Result backup(
+            SecretKey secretKey,
+            @Nullable byte[] fingerprintMixerSalt,
+            Set<ChunkHash> existingChunks)
+            throws IOException, GeneralSecurityException;
+
+    /**
+     * The result of an incremental backup. Contains new encrypted chunks to upload, and an ordered
+     * list of the chunks in the backup file.
+     */
+    class Result {
+        private final List<ChunkHash> mAllChunks;
+        private final List<EncryptedChunk> mNewChunks;
+        private final byte[] mDigest;
+
+        public Result(List<ChunkHash> allChunks, List<EncryptedChunk> newChunks, byte[] digest) {
+            mAllChunks = unmodifiableList(new ArrayList<>(allChunks));
+            mDigest = digest;
+            mNewChunks = unmodifiableList(new ArrayList<>(newChunks));
+        }
+
+        /**
+         * Returns an unmodifiable list of the hashes of all the chunks in the backup, in the order
+         * they appear in the plaintext.
+         */
+        public List<ChunkHash> getAllChunks() {
+            return mAllChunks;
+        }
+
+        /** Returns an unmodifiable list of the new chunks in the backup. */
+        public List<EncryptedChunk> getNewChunks() {
+            return mNewChunks;
+        }
+
+        /** Returns the message digest of the backup. */
+        public byte[] getDigest() {
+            return mDigest;
+        }
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java b/services/backup/java/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.java
new file mode 100644
index 0000000..45798d3
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/tasks/BackupStreamEncrypter.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 com.android.server.backup.encryption.tasks;
+
+import android.util.Slog;
+
+import com.android.server.backup.encryption.chunk.ChunkHash;
+import com.android.server.backup.encryption.chunking.ChunkEncryptor;
+import com.android.server.backup.encryption.chunking.ChunkHasher;
+import com.android.server.backup.encryption.chunking.EncryptedChunk;
+import com.android.server.backup.encryption.chunking.cdc.ContentDefinedChunker;
+import com.android.server.backup.encryption.chunking.cdc.FingerprintMixer;
+import com.android.server.backup.encryption.chunking.cdc.IsChunkBreakpoint;
+import com.android.server.backup.encryption.chunking.cdc.RabinFingerprint64;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Splits backup data into variable-sized chunks using content-defined chunking, then encrypts the
+ * chunks. Given a hash of the SHA-256s of existing chunks, performs an incremental backup (i.e.,
+ * only encrypts new chunks).
+ */
+public class BackupStreamEncrypter implements BackupEncrypter {
+    private static final String TAG = "BackupStreamEncryptor";
+
+    private final InputStream mData;
+    private final int mMinChunkSizeBytes;
+    private final int mMaxChunkSizeBytes;
+    private final int mAverageChunkSizeBytes;
+
+    /**
+     * A new instance over the given distribution of chunk sizes.
+     *
+     * @param data The data to be backed up.
+     * @param minChunkSizeBytes The minimum chunk size. No chunk will be smaller than this.
+     * @param maxChunkSizeBytes The maximum chunk size. No chunk will be larger than this.
+     * @param averageChunkSizeBytes The average chunk size. The mean size of chunks will be roughly
+     *     this (with a few tens of bytes of overhead for the initialization vector and message
+     *     authentication code).
+     */
+    public BackupStreamEncrypter(
+            InputStream data,
+            int minChunkSizeBytes,
+            int maxChunkSizeBytes,
+            int averageChunkSizeBytes) {
+        this.mData = data;
+        this.mMinChunkSizeBytes = minChunkSizeBytes;
+        this.mMaxChunkSizeBytes = maxChunkSizeBytes;
+        this.mAverageChunkSizeBytes = averageChunkSizeBytes;
+    }
+
+    @Override
+    public Result backup(
+            SecretKey secretKey, byte[] fingerprintMixerSalt, Set<ChunkHash> existingChunks)
+            throws IOException, GeneralSecurityException {
+        MessageDigest messageDigest =
+                MessageDigest.getInstance(BackupEncrypter.MESSAGE_DIGEST_ALGORITHM);
+        RabinFingerprint64 rabinFingerprint64 = new RabinFingerprint64();
+        FingerprintMixer fingerprintMixer = new FingerprintMixer(secretKey, fingerprintMixerSalt);
+        IsChunkBreakpoint isChunkBreakpoint =
+                new IsChunkBreakpoint(mAverageChunkSizeBytes - mMinChunkSizeBytes);
+        ContentDefinedChunker chunker =
+                new ContentDefinedChunker(
+                        mMinChunkSizeBytes,
+                        mMaxChunkSizeBytes,
+                        rabinFingerprint64,
+                        fingerprintMixer,
+                        isChunkBreakpoint);
+        ChunkHasher chunkHasher = new ChunkHasher(secretKey);
+        ChunkEncryptor encryptor = new ChunkEncryptor(secretKey, new SecureRandom());
+        Set<ChunkHash> includedChunks = new HashSet<>();
+        // New chunks will be added only once to this list, even if they occur multiple times.
+        List<EncryptedChunk> newChunks = new ArrayList<>();
+        // All chunks (including multiple occurrences) will be added to the chunkListing.
+        List<ChunkHash> chunkListing = new ArrayList<>();
+
+        includedChunks.addAll(existingChunks);
+
+        chunker.chunkify(
+                mData,
+                chunk -> {
+                    messageDigest.update(chunk);
+                    ChunkHash key = chunkHasher.computeHash(chunk);
+
+                    if (!includedChunks.contains(key)) {
+                        newChunks.add(encryptor.encrypt(key, chunk));
+                        includedChunks.add(key);
+                    }
+                    chunkListing.add(key);
+                });
+
+        Slog.i(
+                TAG,
+                String.format(
+                        "Chunks: %d total, %d unique, %d new",
+                        chunkListing.size(), new HashSet<>(chunkListing).size(), newChunks.size()));
+        return new Result(
+                Collections.unmodifiableList(chunkListing),
+                Collections.unmodifiableList(newChunks),
+                messageDigest.digest());
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java b/services/backup/java/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java
new file mode 100644
index 0000000..e3df3c1
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/tasks/DecryptedChunkOutput.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.encryption.tasks;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+
+/**
+ * Accepts the plaintext bytes of decrypted chunks and writes them to some output. Also keeps track
+ * of the message digest of the chunks.
+ */
+public interface DecryptedChunkOutput extends Closeable {
+    /**
+     * Opens whatever output the implementation chooses, ready to process chunks.
+     *
+     * @return {@code this}, to allow use with try-with-resources
+     */
+    DecryptedChunkOutput open() throws IOException;
+
+    /**
+     * Writes the plaintext bytes of chunk to whatever output the implementation chooses. Also
+     * updates the digest with the chunk.
+     *
+     * <p>You must call {@link #open()} before this method, and you may not call it after calling
+     * {@link Closeable#close()}.
+     *
+     * @param plaintextBuffer An array containing the bytes of the plaintext of the chunk, starting
+     *     at index 0.
+     * @param length The length in bytes of the plaintext contained in {@code plaintextBuffer}.
+     */
+    void processChunk(byte[] plaintextBuffer, int length) throws IOException, InvalidKeyException;
+
+    /**
+     * Returns the message digest of all the chunks processed by {@link #processChunk}.
+     *
+     * <p>You must call {@link Closeable#close()} before calling this method.
+     */
+    byte[] getDigest();
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java b/services/backup/java/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java
new file mode 100644
index 0000000..487c0d9
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/tasks/EncryptedRestoreException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.encryption.tasks;
+
+/** Wraps any exception related to encryption which occurs during restore. */
+public class EncryptedRestoreException extends Exception {
+    public EncryptedRestoreException(String message) {
+        super(message);
+    }
+
+    public EncryptedRestoreException(Throwable cause) {
+        super(cause);
+    }
+
+    public EncryptedRestoreException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index 18ee7a4..18c38dc 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -128,7 +128,7 @@
 
     private static final String TAG = "PFTBT";
 
-    private UserBackupManagerService backupManagerService;
+    private UserBackupManagerService mUserBackupManagerService;
     private final Object mCancelLock = new Object();
 
     ArrayList<PackageInfo> mPackages;
@@ -159,7 +159,7 @@
             @Nullable IBackupManagerMonitor monitor, @Nullable OnTaskFinishedListener listener,
             boolean userInitiated) {
         super(observer);
-        this.backupManagerService = backupManagerService;
+        this.mUserBackupManagerService = backupManagerService;
         mTransportClient = transportClient;
         mUpdateSchedule = updateSchedule;
         mLatch = latch;
@@ -252,16 +252,16 @@
     }
 
     private void registerTask() {
-        synchronized (backupManagerService.getCurrentOpLock()) {
+        synchronized (mUserBackupManagerService.getCurrentOpLock()) {
             Slog.d(TAG, "backupmanager pftbt token=" + Integer.toHexString(mCurrentOpToken));
-            backupManagerService.getCurrentOperations().put(
+            mUserBackupManagerService.getCurrentOperations().put(
                     mCurrentOpToken,
                     new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
         }
     }
 
     public void unregisterTask() {
-        backupManagerService.removeOperation(mCurrentOpToken);
+        mUserBackupManagerService.removeOperation(mCurrentOpToken);
     }
 
     @Override
@@ -288,7 +288,7 @@
 
             mCancelAll = true;
             if (mIsDoingBackup) {
-                backupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
+                mUserBackupManagerService.handleCancel(mBackupRunnerOpToken, cancelAll);
                 try {
                     // If we're running a backup we should be connected to a transport
                     IBackupTransport transport =
@@ -320,16 +320,17 @@
         int backupRunStatus = BackupManager.SUCCESS;
 
         try {
-            if (!backupManagerService.isEnabled() || !backupManagerService.isSetupComplete()) {
+            if (!mUserBackupManagerService.isEnabled()
+                    || !mUserBackupManagerService.isSetupComplete()) {
                 // Backups are globally disabled, so don't proceed.
                 if (DEBUG) {
-                    Slog.i(TAG, "full backup requested but enabled=" + backupManagerService
+                    Slog.i(TAG, "full backup requested but enabled=" + mUserBackupManagerService
                             .isEnabled()
-                            + " setupComplete=" + backupManagerService.isSetupComplete()
+                            + " setupComplete=" + mUserBackupManagerService.isSetupComplete()
                             + "; ignoring");
                 }
                 int monitoringEvent;
-                if (backupManagerService.isSetupComplete()) {
+                if (mUserBackupManagerService.isSetupComplete()) {
                     monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED;
                 } else {
                     monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED;
@@ -532,7 +533,8 @@
                 // Roll this package to the end of the backup queue if we're
                 // in a queue-driven mode (regardless of success/failure)
                 if (mUpdateSchedule) {
-                    backupManagerService.enqueueFullBackup(packageName, System.currentTimeMillis());
+                    mUserBackupManagerService.enqueueFullBackup(
+                            packageName, System.currentTimeMillis());
                 }
 
                 if (backupPackageStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
@@ -549,7 +551,8 @@
                     // from the preflight pass.  If we got as far as preflight, we now need
                     // to tear down the target process.
                     if (mBackupRunner != null) {
-                        backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                        mUserBackupManagerService.tearDownAgentAndKill(
+                                currentPackage.applicationInfo);
                     }
                     // ... and continue looping.
                 } else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
@@ -561,7 +564,7 @@
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
                                 packageName);
                     }
-                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
                     // Do nothing, clean up, and continue looping.
                 } else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
                     BackupObserverUtils
@@ -569,7 +572,7 @@
                                     BackupManager.ERROR_AGENT_FAILURE);
                     Slog.w(TAG, "Application failure for package: " + packageName);
                     EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
-                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
                     // Do nothing, clean up, and continue looping.
                 } else if (backupPackageStatus == BackupManager.ERROR_BACKUP_CANCELLED) {
                     BackupObserverUtils
@@ -578,7 +581,7 @@
                     Slog.w(TAG, "Backup cancelled. package=" + packageName +
                             ", cancelAll=" + mCancelAll);
                     EventLog.writeEvent(EventLogTags.FULL_BACKUP_CANCELLED, packageName);
-                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
                     // Do nothing, clean up, and continue looping.
                 } else if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
                     BackupObserverUtils
@@ -588,7 +591,7 @@
                     EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
                     // Abort entire backup pass.
                     backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
-                    backupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
+                    mUserBackupManagerService.tearDownAgentAndKill(currentPackage.applicationInfo);
                     return;
                 } else {
                     // Success!
@@ -596,14 +599,14 @@
                             .sendBackupOnPackageResult(mBackupObserver, packageName,
                                     BackupManager.SUCCESS);
                     EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS, packageName);
-                    backupManagerService.logBackupComplete(packageName);
+                    mUserBackupManagerService.logBackupComplete(packageName);
                 }
                 cleanUpPipes(transportPipes);
                 cleanUpPipes(enginePipes);
                 if (currentPackage.applicationInfo != null) {
                     Slog.i(TAG, "Unbinding agent in " + packageName);
                     try {
-                        backupManagerService.getActivityManager().unbindBackupAgent(
+                        mUserBackupManagerService.getActivityManager().unbindBackupAgent(
                                 currentPackage.applicationInfo);
                     } catch (RemoteException e) { /* can't happen; activity manager is local */ }
                 }
@@ -639,8 +642,8 @@
                 mJob.finishBackupPass(mUserId);
             }
 
-            synchronized (backupManagerService.getQueueLock()) {
-                backupManagerService.setRunningFullBackupTask(null);
+            synchronized (mUserBackupManagerService.getQueueLock()) {
+                mUserBackupManagerService.setRunningFullBackupTask(null);
             }
 
             mListener.onFinished("PFTBT.run()");
@@ -650,11 +653,11 @@
             // Now that we're actually done with schedule-driven work, reschedule
             // the next pass based on the new queue state.
             if (mUpdateSchedule) {
-                backupManagerService.scheduleNextFullBackupJob(backoff);
+                mUserBackupManagerService.scheduleNextFullBackupJob(backoff);
             }
 
             Slog.i(TAG, "Full data backup pass finished.");
-            backupManagerService.getWakelock().release();
+            mUserBackupManagerService.getWakelock().release();
         }
     }
 
@@ -709,13 +712,13 @@
             long fullBackupAgentTimeoutMillis =
                     mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
             try {
-                backupManagerService.prepareOperationTimeout(
+                mUserBackupManagerService.prepareOperationTimeout(
                         mCurrentOpToken, fullBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
                 if (MORE_DEBUG) {
                     Slog.d(TAG, "Preflighting full payload of " + pkg.packageName);
                 }
                 agent.doMeasureFullBackup(mQuota, mCurrentOpToken,
-                        backupManagerService.getBackupManagerBinder(), mTransportFlags);
+                        mUserBackupManagerService.getBackupManagerBinder(), mTransportFlags);
 
                 // Now wait to get our result back.  If this backstop timeout is reached without
                 // the latch being thrown, flow will continue as though a result or "normal"
@@ -765,7 +768,7 @@
             }
             mResult.set(result);
             mLatch.countDown();
-            backupManagerService.removeOperation(mCurrentOpToken);
+            mUserBackupManagerService.removeOperation(mCurrentOpToken);
         }
 
         @Override
@@ -775,7 +778,7 @@
             }
             mResult.set(BackupTransport.AGENT_ERROR);
             mLatch.countDown();
-            backupManagerService.removeOperation(mCurrentOpToken);
+            mUserBackupManagerService.removeOperation(mCurrentOpToken);
         }
 
         @Override
@@ -812,7 +815,7 @@
             mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
             mTarget = target;
             mCurrentOpToken = currentOpToken;
-            mEphemeralToken = backupManagerService.generateRandomIntegerToken();
+            mEphemeralToken = mUserBackupManagerService.generateRandomIntegerToken();
             mPreflight = new SinglePackageBackupPreflight(
                     transportClient, quota, mEphemeralToken, transportFlags);
             mPreflightLatch = new CountDownLatch(1);
@@ -825,23 +828,32 @@
         }
 
         void registerTask() {
-            synchronized (backupManagerService.getCurrentOpLock()) {
-                backupManagerService.getCurrentOperations().put(
+            synchronized (mUserBackupManagerService.getCurrentOpLock()) {
+                mUserBackupManagerService.getCurrentOperations().put(
                         mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP_WAIT));
             }
         }
 
         void unregisterTask() {
-            synchronized (backupManagerService.getCurrentOpLock()) {
-                backupManagerService.getCurrentOperations().remove(mCurrentOpToken);
+            synchronized (mUserBackupManagerService.getCurrentOpLock()) {
+                mUserBackupManagerService.getCurrentOperations().remove(mCurrentOpToken);
             }
         }
 
         @Override
         public void run() {
             FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
-            mEngine = new FullBackupEngine(backupManagerService, out, mPreflight, mTarget, false,
-                    this, mQuota, mCurrentOpToken, mTransportFlags);
+            mEngine =
+                    new FullBackupEngine(
+                            mUserBackupManagerService,
+                            out,
+                            mPreflight,
+                            mTarget,
+                            false,
+                            this,
+                            mQuota,
+                            mCurrentOpToken,
+                            mTransportFlags);
             try {
                 try {
                     if (!mIsCancelled) {
@@ -928,13 +940,13 @@
                     mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT, null);
             mIsCancelled = true;
             // Cancel tasks spun off by this task.
-            backupManagerService.handleCancel(mEphemeralToken, cancelAll);
-            backupManagerService.tearDownAgentAndKill(mTarget.applicationInfo);
+            mUserBackupManagerService.handleCancel(mEphemeralToken, cancelAll);
+            mUserBackupManagerService.tearDownAgentAndKill(mTarget.applicationInfo);
             // Free up everyone waiting on this task and its children.
             mPreflightLatch.countDown();
             mBackupLatch.countDown();
             // We are done with this operation.
-            backupManagerService.removeOperation(mCurrentOpToken);
+            mUserBackupManagerService.removeOperation(mCurrentOpToken);
         }
     }
 }
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 56eacc0..eba9e4a 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -88,7 +88,6 @@
     final PackageInfo mOnlyPackage;
 
     final boolean mAllowApks;
-    private final boolean mAllowObbs;
 
     // Which package are we currently handling data for?
     private String mAgentPackage;
@@ -113,9 +112,6 @@
     // Packages we've already wiped data on when restoring their first file
     private final HashSet<String> mClearedPackages = new HashSet<>();
 
-    // How much data have we moved?
-    private long mBytes;
-
     // Working buffer
     final byte[] mBuffer;
 
@@ -130,14 +126,14 @@
     final int mEphemeralOpToken;
 
     private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
-    final boolean mIsAdbRestore;
+    private final boolean mIsAdbRestore;
     @GuardedBy("mPipesLock")
     private boolean mPipesClosed;
 
     public FullRestoreEngine(UserBackupManagerService backupManagerService,
             BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
             IBackupManagerMonitor monitor, PackageInfo onlyPackage, boolean allowApks,
-            boolean allowObbs, int ephemeralOpToken, boolean isAdbRestore) {
+            int ephemeralOpToken, boolean isAdbRestore) {
         mBackupManagerService = backupManagerService;
         mEphemeralOpToken = ephemeralOpToken;
         mMonitorTask = monitorTask;
@@ -145,9 +141,7 @@
         mMonitor = monitor;
         mOnlyPackage = onlyPackage;
         mAllowApks = allowApks;
-        mAllowObbs = allowObbs;
         mBuffer = new byte[32 * 1024];
-        mBytes = 0;
         mAgentTimeoutParameters = Preconditions.checkNotNull(
                 backupManagerService.getAgentTimeoutParameters(),
                 "Timeout parameters cannot be null");
@@ -170,12 +164,7 @@
             return false;
         }
 
-        BytesReadListener bytesReadListener = new BytesReadListener() {
-            @Override
-            public void onBytesRead(long bytesRead) {
-                mBytes += bytesRead;
-            }
-        };
+        BytesReadListener bytesReadListener = bytesRead -> { };
 
         TarBackupReader tarBackupReader = new TarBackupReader(instream,
                 bytesReadListener, monitor);
@@ -378,9 +367,7 @@
                                             ? ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL
                                             : ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL);
                             mAgentPackage = pkg;
-                        } catch (IOException e) {
-                            // fall through to error handling
-                        } catch (NameNotFoundException e) {
+                        } catch (IOException | NameNotFoundException e) {
                             // fall through to error handling
                         }
 
@@ -485,9 +472,6 @@
                                 int toRead = (toCopy > buffer.length)
                                         ? buffer.length : (int) toCopy;
                                 int nRead = instream.read(buffer, 0, toRead);
-                                if (nRead >= 0) {
-                                    mBytes += nRead;
-                                }
                                 if (nRead <= 0) {
                                     break;
                                 }
@@ -548,9 +532,6 @@
                             int toRead = (bytesToConsume > buffer.length)
                                     ? buffer.length : (int) bytesToConsume;
                             long nRead = instream.read(buffer, 0, toRead);
-                            if (nRead >= 0) {
-                                mBytes += nRead;
-                            }
                             if (nRead <= 0) {
                                 break;
                             }
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
index c904256..ec2d545 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -23,21 +23,12 @@
 import static com.android.server.backup.BackupPasswordManager.PBKDF_FALLBACK;
 import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_HEADER_MAGIC;
 import static com.android.server.backup.UserBackupManagerService.BACKUP_FILE_VERSION;
-import static com.android.server.backup.UserBackupManagerService.SETTINGS_PACKAGE;
-import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
 
-import android.app.IBackupAgent;
-import android.app.backup.BackupAgent;
 import android.app.backup.IFullBackupRestoreObserver;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.Signature;
-import android.os.Environment;
 import android.os.ParcelFileDescriptor;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
-import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.UserBackupManagerService;
 import com.android.server.backup.fullbackup.FullBackupObbConnection;
 import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
@@ -50,8 +41,6 @@
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.zip.InflaterInputStream;
 
@@ -71,34 +60,9 @@
     private final String mCurrentPassword;
     private final String mDecryptPassword;
     private final AtomicBoolean mLatchObject;
-    private final BackupAgent mPackageManagerBackupAgent;
-    private final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();
+    private final FullBackupObbConnection mObbConnection;
 
     private IFullBackupRestoreObserver mObserver;
-    private IBackupAgent mAgent;
-    private String mAgentPackage;
-    private ApplicationInfo mTargetApp;
-    private FullBackupObbConnection mObbConnection = null;
-    private ParcelFileDescriptor[] mPipes = null;
-    private byte[] mWidgetData = null;
-    private long mAppVersion;
-
-    private long mBytes;
-    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
-
-    // possible handling states for a given package in the restore dataset
-    private final HashMap<String, RestorePolicy> mPackagePolicies
-            = new HashMap<>();
-
-    // installer package names for each encountered app, derived from the manifests
-    private final HashMap<String, String> mPackageInstallers = new HashMap<>();
-
-    // Signatures for a given package found in its manifest file
-    private final HashMap<String, Signature[]> mManifestSignatures
-            = new HashMap<>();
-
-    // Packages we've already wiped data on when restoring their first file
-    private final HashSet<String> mClearedPackages = new HashSet<>();
 
     public PerformAdbRestoreTask(UserBackupManagerService backupManagerService,
             ParcelFileDescriptor fd, String curPassword, String decryptPassword,
@@ -109,19 +73,7 @@
         mDecryptPassword = decryptPassword;
         mObserver = observer;
         mLatchObject = latch;
-        mAgent = null;
-        mPackageManagerBackupAgent = backupManagerService.makeMetadataAgent();
-        mAgentPackage = null;
-        mTargetApp = null;
         mObbConnection = new FullBackupObbConnection(backupManagerService);
-        mAgentTimeoutParameters = Preconditions.checkNotNull(
-                backupManagerService.getAgentTimeoutParameters(),
-                "Timeout parameters cannot be null");
-
-        // Which packages we've already wiped data on.  We prepopulate this
-        // with a whitelist of packages known to be unclearable.
-        mClearedPackages.add("android");
-        mClearedPackages.add(SETTINGS_PACKAGE);
     }
 
     @Override
@@ -130,11 +82,6 @@
         mObbConnection.establish();
         mObserver = FullBackupRestoreObserverUtils.sendStartRestore(mObserver);
 
-        // Are we able to restore shared-storage data?
-        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-            mPackagePolicies.put(SHARED_BACKUP_AGENT_PACKAGE, RestorePolicy.ACCEPT);
-        }
-
         FileInputStream rawInStream = null;
         try {
             if (!mBackupManagerService.backupPasswordMatches(mCurrentPassword)) {
@@ -144,8 +91,6 @@
                 return;
             }
 
-            mBytes = 0;
-
             rawInStream = new FileInputStream(mInputFile.getFileDescriptor());
 
             InputStream tarInputStream = parseBackupFileHeaderAndReturnTarStream(rawInStream,
@@ -157,7 +102,7 @@
             }
 
             FullRestoreEngine mEngine = new FullRestoreEngine(mBackupManagerService, null,
-                    mObserver, null, null, true, true/*unused*/, 0 /*unused*/, true);
+                    mObserver, null, null, true, 0 /*unused*/, true);
             FullRestoreEngineThread mEngineThread = new FullRestoreEngineThread(mEngine,
                     tarInputStream);
             mEngineThread.run();
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 6714b0a..675a6eb 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -26,6 +26,7 @@
 import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
+import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.annotation.Nullable;
 import android.app.ApplicationThreadConstants;
@@ -86,7 +87,7 @@
     private final TransportClient mTransportClient;
 
     // Where per-transport saved state goes
-    File mStateDir;
+    private File mStateDir;
 
     // Restore observer; may be null
     private IRestoreObserver mObserver;
@@ -153,10 +154,9 @@
     // Key/value: bookkeeping about staged data and files for agent access
     private File mBackupDataName;
     private File mStageName;
-    private File mSavedStateName;
     private File mNewStateName;
-    ParcelFileDescriptor mBackupData;
-    ParcelFileDescriptor mNewState;
+    private ParcelFileDescriptor mBackupData;
+    private ParcelFileDescriptor mNewState;
 
     private final int mEphemeralOpToken;
     private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
@@ -223,7 +223,7 @@
                 try {
                     PackageManager pm = backupManagerService.getPackageManager();
                     PackageInfo info = pm.getPackageInfoAsUser(filterSet[i], 0, mUserId);
-                    if ("android".equals(info.packageName)) {
+                    if (PLATFORM_PACKAGE_NAME.equals(info.packageName)) {
                         hasSystem = true;
                         continue;
                     }
@@ -242,7 +242,7 @@
             if (hasSystem) {
                 try {
                     mAcceptSet.add(0, backupManagerService.getPackageManager().getPackageInfoAsUser(
-                                    "android", 0, mUserId));
+                                    PLATFORM_PACKAGE_NAME, 0, mUserId));
                 } catch (NameNotFoundException e) {
                     // won't happen; we know a priori that it's valid
                 }
@@ -666,7 +666,7 @@
     }
 
     // Guts of a key/value restore operation
-    void initiateOneRestore(PackageInfo app, long appVersionCode) {
+    private void initiateOneRestore(PackageInfo app, long appVersionCode) {
         final String packageName = app.packageName;
 
         if (DEBUG) {
@@ -677,13 +677,12 @@
         mBackupDataName = new File(backupManagerService.getDataDir(), packageName + ".restore");
         mStageName = new File(backupManagerService.getDataDir(), packageName + ".stage");
         mNewStateName = new File(mStateDir, packageName + ".new");
-        mSavedStateName = new File(mStateDir, packageName);
 
         // don't stage the 'android' package where the wallpaper data lives.  this is
         // an optimization: we know there's no widget data hosted/published by that
         // package, and this way we avoid doing a spurious copy of MB-sized wallpaper
         // data following the download.
-        boolean staging = !packageName.equals("android");
+        boolean staging = !packageName.equals(PLATFORM_PACKAGE_NAME);
         ParcelFileDescriptor stage;
         File downloadFile = (staging) ? mStageName : mBackupDataName;
         boolean startedAgentRestore = false;
@@ -870,7 +869,7 @@
                     mCurrentPackage.packageName);
 
             mEngine = new FullRestoreEngine(backupManagerService, this, null,
-                    mMonitor, mCurrentPackage, false, false, mEphemeralOpToken, false);
+                    mMonitor, mCurrentPackage, false, mEphemeralOpToken, false);
             mEngineThread = new FullRestoreEngineThread(mEngine, mEnginePipes[0]);
 
             ParcelFileDescriptor eWriteEnd = mEnginePipes[1];
@@ -1160,7 +1159,6 @@
         // the following from a discard of the newly-written state to the
         // "correct" operation of renaming into the canonical state blob.
         mNewStateName.delete();                      // TODO: remove; see above comment
-        //mNewStateName.renameTo(mSavedStateName);   // TODO: replace with this
 
         // If this wasn't the PM pseudopackage, tear down the agent side
         if (mCurrentPackage.applicationInfo != null) {
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
index 7709311..06d9395 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
@@ -95,10 +95,10 @@
 
     @GuardedBy("mLock")
     void provideContextImageLocked(int taskId, @NonNull Bundle imageContextRequestExtras) {
-        RemoteContentSuggestionsService service = getRemoteServiceLocked();
+        RemoteContentSuggestionsService service = ensureRemoteServiceLocked();
         if (service != null) {
             ActivityManager.TaskSnapshot snapshot =
-                    mActivityTaskManagerInternal.getTaskSnapshot(taskId, false);
+                    mActivityTaskManagerInternal.getTaskSnapshotNoRestore(taskId, false);
             GraphicBuffer snapshotBuffer = null;
             int colorSpaceId = 0;
             if (snapshot != null) {
@@ -118,7 +118,7 @@
     void suggestContentSelectionsLocked(
             @NonNull SelectionsRequest selectionsRequest,
             @NonNull ISelectionsCallback selectionsCallback) {
-        RemoteContentSuggestionsService service = getRemoteServiceLocked();
+        RemoteContentSuggestionsService service = ensureRemoteServiceLocked();
         if (service != null) {
             service.suggestContentSelections(selectionsRequest, selectionsCallback);
         }
@@ -128,7 +128,7 @@
     void classifyContentSelectionsLocked(
             @NonNull ClassificationsRequest classificationsRequest,
             @NonNull IClassificationsCallback callback) {
-        RemoteContentSuggestionsService service = getRemoteServiceLocked();
+        RemoteContentSuggestionsService service = ensureRemoteServiceLocked();
         if (service != null) {
             service.classifyContentSelections(classificationsRequest, callback);
         }
@@ -136,7 +136,7 @@
 
     @GuardedBy("mLock")
     void notifyInteractionLocked(@NonNull String requestId, @NonNull Bundle bundle) {
-        RemoteContentSuggestionsService service = getRemoteServiceLocked();
+        RemoteContentSuggestionsService service = ensureRemoteServiceLocked();
         if (service != null) {
             service.notifyInteraction(requestId, bundle);
         }
@@ -153,12 +153,12 @@
 
     @GuardedBy("mLock")
     @Nullable
-    private RemoteContentSuggestionsService getRemoteServiceLocked() {
+    private RemoteContentSuggestionsService ensureRemoteServiceLocked() {
         if (mRemoteService == null) {
             final String serviceName = getComponentNameLocked();
             if (serviceName == null) {
                 if (mMaster.verbose) {
-                    Slog.v(TAG, "getRemoteServiceLocked(): not set");
+                    Slog.v(TAG, "ensureRemoteServiceLocked(): not set");
                 }
                 return null;
             }
@@ -170,8 +170,8 @@
                         @Override
                         public void onServiceDied(
                                 @NonNull RemoteContentSuggestionsService service) {
-                            // TODO(b/120865921): properly implement
                             Slog.w(TAG, "remote content suggestions service died");
+                            updateRemoteServiceLocked();
                         }
                     }, mMaster.isBindInstantServiceAllowed(), mMaster.verbose);
         }
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index d0edaaa..d162441 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -210,6 +210,7 @@
     IAlarmListener mTimeTickTrigger;
     PendingIntent mDateChangeSender;
     Random mRandom;
+    PendingIntent.CancelListener mOperationCancelListener;
     boolean mInteractive = true;
     long mNonInteractiveStartTime;
     long mNonInteractiveTime;
@@ -1497,6 +1498,7 @@
 
         synchronized (mLock) {
             mHandler = new AlarmHandler();
+            mOperationCancelListener = (intent) -> removeImpl(intent, null);
             mConstants = new Constants(mHandler);
             mAppWakeupHistory = new AppWakeupHistory(Constants.DEFAULT_APP_STANDBY_WINDOW);
 
@@ -1748,7 +1750,9 @@
         } else {
             maxElapsed = triggerElapsed + windowLength;
         }
-
+        if (operation != null) {
+            operation.registerCancelListener(mOperationCancelListener);
+        }
         synchronized (mLock) {
             if (DEBUG_BATCH) {
                 Slog.v(TAG, "set(" + operation + ") : type=" + type
@@ -1761,8 +1765,9 @@
                         "Maximum limit of concurrent alarms " + mConstants.MAX_ALARMS_PER_UID
                                 + " reached for uid: " + UserHandle.formatUid(callingUid)
                                 + ", callingPackage: " + callingPackage;
-                // STOPSHIP (b/128866264): Just to catch breakages. Remove before final release.
-                Slog.wtf(TAG, errorMsg);
+                mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
+                        operation).sendToTarget();
+                Slog.w(TAG, errorMsg);
                 throw new IllegalStateException(errorMsg);
             }
             setImplLocked(type, triggerAtTime, triggerElapsed, windowLength, maxElapsed,
@@ -1782,6 +1787,8 @@
             if (ActivityManager.getService().isAppStartModeDisabled(callingUid, callingPackage)) {
                 Slog.w(TAG, "Not setting alarm from " + callingUid + ":" + a
                         + " -- package not allowed to start");
+                mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
+                        operation).sendToTarget();
                 return;
             }
         } catch (RemoteException e) {
@@ -2136,10 +2143,11 @@
                 Slog.w(TAG, "remove() with no intent or listener");
                 return;
             }
-
             synchronized (mLock) {
                 removeLocked(operation, listener);
             }
+            mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
+                    operation).sendToTarget();
         }
 
         @Override
@@ -3011,46 +3019,10 @@
                 DateFormat.format(pattern, info.getTriggerTime()).toString();
     }
 
-    /**
-     * If the last time AlarmThread woke up precedes any due wakeup or non-wakeup alarm that we set
-     * by more than half a minute, log a wtf.
-     */
-    private void validateLastAlarmExpiredLocked(long nowElapsed) {
-        final StringBuilder errorMsg = new StringBuilder();
-        boolean stuck = false;
-        if (mNextNonWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextNonWakeup) {
-            stuck = true;
-            errorMsg.append("[mNextNonWakeup=");
-            TimeUtils.formatDuration(mNextNonWakeup - nowElapsed, errorMsg);
-            errorMsg.append(" set at ");
-            TimeUtils.formatDuration(mNextNonWakeUpSetAt - nowElapsed, errorMsg);
-            errorMsg.append(", mLastWakeup=");
-            TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
-            errorMsg.append(", timerfd_gettime=" + mInjector.getNextAlarm(ELAPSED_REALTIME));
-            errorMsg.append("];");
-        }
-        if (mNextWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextWakeup) {
-            stuck = true;
-            errorMsg.append("[mNextWakeup=");
-            TimeUtils.formatDuration(mNextWakeup - nowElapsed, errorMsg);
-            errorMsg.append(" set at ");
-            TimeUtils.formatDuration(mNextWakeUpSetAt - nowElapsed, errorMsg);
-            errorMsg.append(", mLastWakeup=");
-            TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
-            errorMsg.append(", timerfd_gettime="
-                    + mInjector.getNextAlarm(ELAPSED_REALTIME_WAKEUP));
-            errorMsg.append("];");
-        }
-        if (stuck) {
-            Slog.wtf(TAG, "Alarm delivery stuck: " + errorMsg.toString());
-        }
-    }
-
     void rescheduleKernelAlarmsLocked() {
         // Schedule the next upcoming wakeup alarm.  If there is a deliverable batch
         // prior to that which contains no wakeups, we schedule that as well.
         final long nowElapsed = mInjector.getElapsedRealtime();
-        validateLastAlarmExpiredLocked(nowElapsed);
         long nextNonWakeup = 0;
         if (mAlarmBatches.size() > 0) {
             final Batch firstWakeup = findFirstWakeupBatchLocked();
@@ -4179,6 +4151,7 @@
         public static final int APP_STANDBY_BUCKET_CHANGED = 5;
         public static final int APP_STANDBY_PAROLE_CHANGED = 6;
         public static final int REMOVE_FOR_STOPPED = 7;
+        public static final int UNREGISTER_CANCEL_LISTENER = 8;
 
         AlarmHandler() {
             super(Looper.myLooper());
@@ -4261,6 +4234,13 @@
                     }
                     break;
 
+                case UNREGISTER_CANCEL_LISTENER:
+                    final PendingIntent pi = (PendingIntent) msg.obj;
+                    if (pi != null) {
+                        pi.unregisterCancelListener(mOperationCancelListener);
+                    }
+                    break;
+
                 default:
                     // nope, just ignore it
                     break;
@@ -4716,6 +4696,11 @@
                                         Intent.EXTRA_ALARM_COUNT, alarm.count),
                                 mDeliveryTracker, mHandler, null,
                                 allowWhileIdle ? mIdleOptions : null);
+                        if (alarm.repeatInterval == 0) {
+                            // Keep the listener for repeating alarms until they get cancelled
+                            mHandler.obtainMessage(AlarmHandler.UNREGISTER_CANCEL_LISTENER,
+                                    alarm.operation).sendToTarget();
+                        }
                     } catch (PendingIntent.CanceledException e) {
                         if (alarm.repeatInterval > 0) {
                             // This IntentSender is no longer valid, but this
diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java
index 5c5b477..112cf08 100644
--- a/services/core/java/com/android/server/BluetoothService.java
+++ b/services/core/java/com/android/server/BluetoothService.java
@@ -18,8 +18,7 @@
 
 import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
-
-import com.android.internal.os.RoSystemProperties;
+import android.os.UserManager;
 
 class BluetoothService extends SystemService {
     private BluetoothManagerService mBluetoothManagerService;
@@ -47,7 +46,7 @@
             publishBinderService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE,
                     mBluetoothManagerService);
         } else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY &&
-                !RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER) {
+                !UserManager.isHeadlessSystemUserMode()) {
             initialize();
         }
     }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 374ac59..4f7900e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -20,6 +20,7 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.NETID_UNSET;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
 import static android.net.ConnectivityManager.TYPE_ETHERNET;
 import static android.net.ConnectivityManager.TYPE_NONE;
 import static android.net.ConnectivityManager.TYPE_VPN;
@@ -91,6 +92,7 @@
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkMisc;
+import android.net.NetworkMonitorManager;
 import android.net.NetworkPolicyManager;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkRequest;
@@ -965,6 +967,8 @@
             }
         }
 
+        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+
         mTethering = makeTethering();
 
         mPermissionMonitor = new PermissionMonitor(mContext, mNetd);
@@ -1012,8 +1016,6 @@
         final DataConnectionStats dataConnectionStats = new DataConnectionStats(mContext);
         dataConnectionStats.startMonitoring();
 
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-
         mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler);
         mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
                 mContext.getSystemService(NotificationManager.class));
@@ -1784,8 +1786,7 @@
             // callback from each caller type. Need to re-factor NetdEventListenerService to allow
             // multiple NetworkMonitor registrants.
             if (nai != null && nai.satisfies(mDefaultRequest)) {
-                Binder.withCleanCallingIdentity(() ->
-                        nai.networkMonitor().notifyDnsResponse(returnCode));
+                nai.networkMonitor().notifyDnsResponse(returnCode);
             }
         }
 
@@ -2575,11 +2576,11 @@
                     break;
                 }
                 case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
-                    if (nai.everConnected && !nai.networkMisc.explicitlySelected) {
-                        loge("ERROR: already-connected network explicitly selected.");
+                    if (nai.everConnected) {
+                        loge("ERROR: cannot call explicitlySelected on already-connected network");
                     }
-                    nai.networkMisc.explicitlySelected = true;
-                    nai.networkMisc.acceptUnvalidated = msg.arg1 == 1;
+                    nai.networkMisc.explicitlySelected = toBool(msg.arg1);
+                    nai.networkMisc.acceptUnvalidated = toBool(msg.arg1) && toBool(msg.arg2);
                     // Mark the network as temporarily accepting partial connectivity so that it
                     // will be validated (and possibly become default) even if it only provides
                     // partial internet access. Note that if user connects to partial connectivity
@@ -2587,7 +2588,7 @@
                     // out of wifi coverage) and if the same wifi is available again, the device
                     // will auto connect to this wifi even though the wifi has "no internet".
                     // TODO: Evaluate using a separate setting in IpMemoryStore.
-                    nai.networkMisc.acceptPartialConnectivity = msg.arg1 == 1;
+                    nai.networkMisc.acceptPartialConnectivity = toBool(msg.arg2);
                     break;
                 }
                 case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
@@ -2613,9 +2614,11 @@
                     final boolean valid = ((msg.arg1 & NETWORK_VALIDATION_RESULT_VALID) != 0);
                     final boolean wasValidated = nai.lastValidated;
                     final boolean wasDefault = isDefaultNetwork(nai);
-                    if (nai.everCaptivePortalDetected && !nai.captivePortalLoginNotified
-                            && valid) {
-                        nai.captivePortalLoginNotified = true;
+                    // Only show a connected notification if the network is pending validation
+                    // after the captive portal app was open, and it has now validated.
+                    if (nai.captivePortalValidationPending && valid) {
+                        // User is now logged in, network validated.
+                        nai.captivePortalValidationPending = false;
                         showNetworkNotification(nai, NotificationType.LOGGED_IN);
                     }
 
@@ -2661,6 +2664,17 @@
                             NetworkAgent.CMD_REPORT_NETWORK_STATUS,
                             (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
                             0, redirectUrlBundle);
+
+                    // If NetworkMonitor detects partial connectivity before
+                    // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
+                    // immediately. Re-notify partial connectivity silently if no internet
+                    // notification already there.
+                    if (!wasPartial && nai.partialConnectivity) {
+                        // Remove delayed message if there is a pending message.
+                        mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
+                        handlePromptUnvalidated(nai.network);
+                    }
+
                     if (wasValidated && !nai.lastValidated) {
                         handleNetworkUnvalidated(nai);
                     }
@@ -2675,9 +2689,6 @@
                         final int oldScore = nai.getCurrentScore();
                         nai.lastCaptivePortalDetected = visible;
                         nai.everCaptivePortalDetected |= visible;
-                        if (visible) {
-                            nai.captivePortalLoginNotified = false;
-                        }
                         if (nai.lastCaptivePortalDetected &&
                             Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) {
                             if (DBG) log("Avoiding captive portal network: " + nai.name());
@@ -2852,11 +2863,7 @@
         // Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
         // schedule DNS resolutions. If a DNS resolution is required the
         // result will be sent back to us.
-        try {
-            nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
+        nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
 
         // With Private DNS bypass support, we can proceed to update the
         // Private DNS config immediately, even if we're in strict mode
@@ -3022,11 +3029,7 @@
             // Disable wakeup packet monitoring for each interface.
             wakeupModifyInterface(iface, nai.networkCapabilities, false);
         }
-        try {
-            nai.networkMonitor().notifyNetworkDisconnected();
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
+        nai.networkMonitor().notifyNetworkDisconnected();
         mNetworkAgentInfos.remove(nai.messenger);
         nai.clatd.update();
         synchronized (mNetworkForNetId) {
@@ -3439,11 +3442,7 @@
             //
             // TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
             // per network. Therefore, NetworkMonitor may still do https probe.
-            try {
-                nai.networkMonitor().setAcceptPartialConnectivity();
-            } catch (RemoteException e) {
-                e.rethrowAsRuntimeException();
-            }
+            nai.networkMonitor().setAcceptPartialConnectivity();
         }
     }
 
@@ -3475,11 +3474,7 @@
             NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
             if (nai == null) return;
             if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
-            try {
-                nai.networkMonitor().launchCaptivePortalApp();
-            } catch (RemoteException e) {
-                e.rethrowAsRuntimeException();
-            }
+            nai.networkMonitor().launchCaptivePortalApp();
         });
     }
 
@@ -3502,6 +3497,12 @@
                 new CaptivePortal(new CaptivePortalImpl(network).asBinder()));
         appIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
 
+        // This runs on a random binder thread, but getNetworkAgentInfoForNetwork is thread-safe,
+        // and captivePortalValidationPending is volatile.
+        final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+        if (nai != null) {
+            nai.captivePortalValidationPending = true;
+        }
         Binder.withCleanCallingIdentity(() ->
                 mContext.startActivityAsUser(appIntent, UserHandle.CURRENT));
     }
@@ -3514,7 +3515,7 @@
         }
 
         @Override
-        public void appResponse(final int response) throws RemoteException {
+        public void appResponse(final int response) {
             if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
                 enforceSettingsPermission();
             }
@@ -3524,16 +3525,9 @@
             if (nai == null) return;
 
             // nai.networkMonitor() is thread-safe
-            final INetworkMonitor nm = nai.networkMonitor();
+            final NetworkMonitorManager nm = nai.networkMonitor();
             if (nm == null) return;
-
-            final long token = Binder.clearCallingIdentity();
-            try {
-                nm.notifyCaptivePortalAppFinished(response);
-            } finally {
-                // Not using Binder.withCleanCallingIdentity() to keep the checked RemoteException
-                Binder.restoreCallingIdentity(token);
-            }
+            nm.notifyCaptivePortalAppFinished(response);
         }
 
         @Override
@@ -3609,21 +3603,31 @@
 
     private void showNetworkNotification(NetworkAgentInfo nai, NotificationType type) {
         final String action;
+        final boolean highPriority;
         switch (type) {
             case LOGGED_IN:
                 action = Settings.ACTION_WIFI_SETTINGS;
                 mHandler.removeMessages(EVENT_TIMEOUT_NOTIFICATION);
                 mHandler.sendMessageDelayed(mHandler.obtainMessage(EVENT_TIMEOUT_NOTIFICATION,
                         nai.network.netId, 0), TIMEOUT_NOTIFICATION_DELAY_MS);
+                // High priority because it is a direct result of the user logging in to a portal.
+                highPriority = true;
                 break;
             case NO_INTERNET:
                 action = ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
+                // High priority because it is only displayed for explicitly selected networks.
+                highPriority = true;
                 break;
             case LOST_INTERNET:
                 action = ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
+                // High priority because it could help the user avoid unexpected data usage.
+                highPriority = true;
                 break;
             case PARTIAL_CONNECTIVITY:
                 action = ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
+                // Don't bother the user with a high-priority notification if the network was not
+                // explicitly selected by the user.
+                highPriority = nai.networkMisc.explicitlySelected;
                 break;
             default:
                 Slog.wtf(TAG, "Unknown notification type " + type);
@@ -3640,25 +3644,50 @@
 
         PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
                 mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
-        mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, true);
+
+        mNotifier.showNotification(nai.network.netId, type, nai, null, pendingIntent, highPriority);
+    }
+
+    private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
+        // Don't prompt if the network is validated, and don't prompt on captive portals
+        // because we're already prompting the user to sign in.
+        if (nai.everValidated || nai.everCaptivePortalDetected) {
+            return false;
+        }
+
+        // If a network has partial connectivity, always prompt unless the user has already accepted
+        // partial connectivity and selected don't ask again. This ensures that if the device
+        // automatically connects to a network that has partial Internet access, the user will
+        // always be able to use it, either because they've already chosen "don't ask again" or
+        // because we have prompt them.
+        if (nai.partialConnectivity && !nai.networkMisc.acceptPartialConnectivity) {
+            return true;
+        }
+
+        // If a network has no Internet access, only prompt if the network was explicitly selected
+        // and if the user has not already told us to use the network regardless of whether it
+        // validated or not.
+        if (nai.networkMisc.explicitlySelected && !nai.networkMisc.acceptUnvalidated) {
+            return true;
+        }
+
+        return false;
     }
 
     private void handlePromptUnvalidated(Network network) {
         if (VDBG || DDBG) log("handlePromptUnvalidated " + network);
         NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
 
-        // Only prompt if the network is unvalidated or network has partial internet connectivity
-        // and was explicitly selected by the user, and if we haven't already been told to switch
-        // to it regardless of whether it validated or not. Also don't prompt on captive portals
-        // because we're already prompting the user to sign in.
-        if (nai == null || nai.everValidated || nai.everCaptivePortalDetected
-                || !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated
-                // TODO: Once the value of acceptPartialConnectivity is moved to IpMemoryStore,
-                // we should reevaluate how to handle acceptPartialConnectivity when network just
-                // connected.
-                || nai.networkMisc.acceptPartialConnectivity) {
+        if (nai == null || !shouldPromptUnvalidated(nai)) {
             return;
         }
+
+        // Stop automatically reconnecting to this network in the future. Automatically connecting
+        // to a network that provides no or limited connectivity is not useful, because the user
+        // cannot use that network except through the notification shown by this method, and the
+        // notification is only shown if the network is explicitly selected by the user.
+        nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
+
         // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
         // NetworkMonitor detects the network is partial connectivity. Need to change the design to
         // popup the notification immediately when the network is partial connectivity.
@@ -4104,11 +4133,7 @@
         if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) {
             return;
         }
-        try {
-            nai.networkMonitor().forceReevaluation(uid);
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
+        nai.networkMonitor().forceReevaluation(uid);
     }
 
     /**
@@ -4383,8 +4408,12 @@
             List<String> interfaces = new ArrayList<>();
             for (Network network : underlyingNetworks) {
                 LinkProperties lp = getLinkProperties(network);
-                if (lp != null && !TextUtils.isEmpty(lp.getInterfaceName())) {
-                    interfaces.add(lp.getInterfaceName());
+                if (lp != null) {
+                    for (String iface : lp.getAllInterfaceNames()) {
+                        if (!TextUtils.isEmpty(iface)) {
+                            interfaces.add(iface);
+                        }
+                    }
                 }
             }
             if (!interfaces.isEmpty()) {
@@ -5541,11 +5570,7 @@
             // Start or stop DNS64 detection and 464xlat according to network state.
             networkAgent.clatd.update();
             notifyIfacesChangedForNetworkStats();
-            try {
-                networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
-            } catch (RemoteException e) {
-                e.rethrowAsRuntimeException();
-            }
+            networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
             if (networkAgent.everConnected) {
                 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
             }
@@ -6529,15 +6554,11 @@
             // command must be sent after updating LinkProperties to maximize chances of
             // NetworkMonitor seeing the correct LinkProperties when starting.
             // TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
-            try {
-                if (networkAgent.networkMisc.acceptPartialConnectivity) {
-                    networkAgent.networkMonitor().setAcceptPartialConnectivity();
-                }
-                networkAgent.networkMonitor().notifyNetworkConnected(
-                        networkAgent.linkProperties, networkAgent.networkCapabilities);
-            } catch (RemoteException e) {
-                e.rethrowAsRuntimeException();
+            if (networkAgent.networkMisc.acceptPartialConnectivity) {
+                networkAgent.networkMonitor().setAcceptPartialConnectivity();
             }
+            networkAgent.networkMonitor().notifyNetworkConnected(
+                    networkAgent.linkProperties, networkAgent.networkCapabilities);
             scheduleUnvalidatedPrompt(networkAgent);
 
             // Whether a particular NetworkRequest listen should cause signal strength thresholds to
@@ -6780,7 +6801,7 @@
 
     /**
      * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
-     * properties tracked by NetworkStatsService on an active iface has changed.
+     * active iface's tracked properties has changed.
      */
     private void notifyIfacesChangedForNetworkStats() {
         ensureRunningOnConnectivityServiceThread();
@@ -6789,9 +6810,11 @@
         if (activeLinkProperties != null) {
             activeIface = activeLinkProperties.getInterfaceName();
         }
+
+        final VpnInfo[] vpnInfos = getAllVpnInfo();
         try {
             mStatsService.forceUpdateIfaces(
-                    getDefaultNetworks(), getAllVpnInfo(), getAllNetworkState(), activeIface);
+                    getDefaultNetworks(), getAllNetworkState(), activeIface, vpnInfos);
         } catch (Exception ignored) {
         }
     }
@@ -6895,8 +6918,10 @@
 
         final int userId = UserHandle.getCallingUserId();
 
-        final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
-        ipMemoryStore.factoryReset();
+        Binder.withCleanCallingIdentity(() -> {
+            final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
+            ipMemoryStore.factoryReset();
+        });
 
         // Turn airplane mode off
         setAirplaneMode(false);
@@ -6946,6 +6971,12 @@
             }
         }
 
+        // restore private DNS settings to default mode (opportunistic)
+        if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) {
+            Settings.Global.putString(mContext.getContentResolver(),
+                    Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OPPORTUNISTIC);
+        }
+
         Settings.Global.putString(mContext.getContentResolver(),
                 Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
     }
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 52a4218..ddfc3a6 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -429,7 +429,15 @@
     private long mNextLightIdleDelay;
     private long mNextLightAlarmTime;
     private long mNextSensingTimeoutAlarmTime;
-    private long mCurIdleBudget;
+
+    /** How long a light idle maintenance window should last. */
+    private long mCurLightIdleBudget;
+
+    /**
+     * Start time of the current (light or full) maintenance window, in the elapsed timebase. Valid
+     * only if {@link #mState} == {@link #STATE_IDLE_MAINTENANCE} or
+     * {@link #mLightState} == {@link #LIGHT_STATE_IDLE_MAINTENANCE}.
+     */
     private long mMaintenanceStartTime;
     private long mIdleStartTime;
 
@@ -2651,9 +2659,12 @@
             EventLogTags.writeDeviceIdle(STATE_ACTIVE, activeReason);
             mState = STATE_ACTIVE;
             mInactiveTimeout = newInactiveTimeout;
-            mCurIdleBudget = 0;
-            mMaintenanceStartTime = 0;
             resetIdleManagementLocked();
+            // Don't reset maintenance window start time if we're in a light idle maintenance window
+            // because its used in the light idle budget calculation.
+            if (mLightState != LIGHT_STATE_IDLE_MAINTENANCE) {
+                mMaintenanceStartTime = 0;
+            }
 
             if (changeLightIdle) {
                 EventLogTags.writeDeviceIdleLight(LIGHT_STATE_ACTIVE, activeReason);
@@ -2763,7 +2774,6 @@
     private void resetIdleManagementLocked() {
         mNextIdlePendingDelay = 0;
         mNextIdleDelay = 0;
-        mNextLightIdleDelay = 0;
         mIdleStartTime = 0;
         cancelAlarmLocked();
         cancelSensingTimeoutAlarmLocked();
@@ -2774,6 +2784,8 @@
     }
 
     private void resetLightIdleManagementLocked() {
+        mNextLightIdleDelay = 0;
+        mCurLightIdleBudget = 0;
         cancelLightAlarmLocked();
     }
 
@@ -2816,7 +2828,7 @@
 
         switch (mLightState) {
             case LIGHT_STATE_INACTIVE:
-                mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
+                mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
                 // Reset the upcoming idle delays.
                 mNextLightIdleDelay = mConstants.LIGHT_IDLE_TIMEOUT;
                 mMaintenanceStartTime = 0;
@@ -2835,10 +2847,12 @@
                     long duration = SystemClock.elapsedRealtime() - mMaintenanceStartTime;
                     if (duration < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
                         // We didn't use up all of our minimum budget; add this to the reserve.
-                        mCurIdleBudget += (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET-duration);
+                        mCurLightIdleBudget +=
+                                (mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET - duration);
                     } else {
                         // We used more than our minimum budget; this comes out of the reserve.
-                        mCurIdleBudget -= (duration-mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
+                        mCurLightIdleBudget -=
+                                (duration - mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
                     }
                 }
                 mMaintenanceStartTime = 0;
@@ -2862,12 +2876,12 @@
                     mActiveIdleOpCount = 1;
                     mActiveIdleWakeLock.acquire();
                     mMaintenanceStartTime = SystemClock.elapsedRealtime();
-                    if (mCurIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
-                        mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
-                    } else if (mCurIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
-                        mCurIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
+                    if (mCurLightIdleBudget < mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET) {
+                        mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
+                    } else if (mCurLightIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
+                        mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
                     }
-                    scheduleLightAlarmLocked(mCurIdleBudget);
+                    scheduleLightAlarmLocked(mCurLightIdleBudget);
                     if (DEBUG) Slog.d(TAG,
                             "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
                     mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
@@ -4360,9 +4374,9 @@
                 TimeUtils.formatDuration(mNextLightAlarmTime, SystemClock.elapsedRealtime(), pw);
                 pw.println();
             }
-            if (mCurIdleBudget != 0) {
-                pw.print("  mCurIdleBudget=");
-                TimeUtils.formatDuration(mCurIdleBudget, pw);
+            if (mCurLightIdleBudget != 0) {
+                pw.print("  mCurLightIdleBudget=");
+                TimeUtils.formatDuration(mCurLightIdleBudget, pw);
                 pw.println();
             }
             if (mMaintenanceStartTime != 0) {
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 67b2c1d..5089ee0 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -42,7 +42,6 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.Signature;
 import android.content.res.Resources;
@@ -97,6 +96,7 @@
 import com.android.internal.location.ProviderRequest;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.server.location.AbstractLocationProvider;
 import com.android.server.location.ActivityRecognitionProxy;
@@ -120,6 +120,7 @@
 import com.android.server.location.MockProvider;
 import com.android.server.location.PassiveProvider;
 import com.android.server.location.RemoteListenerHelper;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
@@ -281,12 +282,12 @@
 
         // Let the package manager query which are the default location
         // providers as they get certain permissions granted by default.
-        PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        packageManagerInternal.setLocationPackagesProvider(
+        PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
+                PermissionManagerServiceInternal.class);
+        permissionManagerInternal.setLocationPackagesProvider(
                 userId -> mContext.getResources().getStringArray(
                         com.android.internal.R.array.config_locationProviderPackageNames));
-        packageManagerInternal.setLocationExtraPackagesProvider(
+        permissionManagerInternal.setLocationExtraPackagesProvider(
                 userId -> mContext.getResources().getStringArray(
                       com.android.internal.R.array.config_locationExtraPackageNames));
 
@@ -466,7 +467,7 @@
         // the user being changed will cause a reload of all user specific settings, which causes
         // provider initialization, and propagates changes until a steady state is reached
         mCurrentUserId = UserHandle.USER_NULL;
-        onUserChangedLocked(UserHandle.USER_SYSTEM);
+        onUserChangedLocked(ActivityManager.getCurrentUser());
 
         // initialize in-memory settings values
         onBackgroundThrottleWhitelistChangedLocked();
@@ -905,7 +906,8 @@
                     Integer.parseInt(fragments[9]) /* accuracy */);
             LocationProvider testProviderManager = new LocationProvider(name);
             addProviderLocked(testProviderManager);
-            new MockProvider(mContext, testProviderManager, properties);
+            testProviderManager.attachLocked(
+                    new MockProvider(mContext, testProviderManager, properties));
         }
     }
 
@@ -1026,38 +1028,55 @@
             return mProperties;
         }
 
-        @GuardedBy("mLock")
-        public void setRequestLocked(ProviderRequest request, WorkSource workSource) {
-            if (mProvider != null) {
-                long identity = Binder.clearCallingIdentity();
-                try {
-                    mProvider.setRequest(request, workSource);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
+        public void setRequest(ProviderRequest request, WorkSource workSource) {
+            // move calls going to providers onto a different thread to avoid deadlock
+            mHandler.post(() -> {
+                synchronized (mLock) {
+                    if (mProvider != null) {
+                        mProvider.onSetRequest(request, workSource);
+                    }
                 }
-            }
+            });
+        }
+
+        public void sendExtraCommand(String command, Bundle extras) {
+            int uid = Binder.getCallingUid();
+            int pid = Binder.getCallingPid();
+
+            // move calls going to providers onto a different thread to avoid deadlock
+            mHandler.post(() -> {
+                synchronized (mLock) {
+                    if (mProvider != null) {
+                        mProvider.onSendExtraCommand(uid, pid, command, extras);
+                    }
+                }
+            });
         }
 
         @GuardedBy("mLock")
-        public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
-            pw.print("  " + mName + " provider");
+        public void dumpLocked(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {
+            pw.print(mName + " provider");
             if (isMock()) {
                 pw.print(" [mock]");
             }
             pw.println(":");
 
-            pw.println("    useable=" + mUseable);
+            pw.increaseIndent();
+
+            pw.println("useable=" + mUseable);
             if (!mUseable) {
-                pw.println("    attached=" + (mProvider != null));
+                pw.println("attached=" + (mProvider != null));
                 if (mIsManagedBySettings) {
-                    pw.println("    allowed=" + mAllowed);
+                    pw.println("allowed=" + mAllowed);
                 }
-                pw.println("    enabled=" + mEnabled);
+                pw.println("enabled=" + mEnabled);
             }
 
-            pw.println("    properties=" + mProperties);
+            pw.println("properties=" + mProperties);
 
             if (mProvider != null) {
+                // in order to be consistent with other provider APIs, this should be run on the
+                // location thread... but this likely isn't worth it just for dumping info.
                 long identity = Binder.clearCallingIdentity();
                 try {
                     mProvider.dump(fd, pw, args);
@@ -1065,6 +1084,8 @@
                     Binder.restoreCallingIdentity(identity);
                 }
             }
+
+            pw.decreaseIndent();
         }
 
         @GuardedBy("mLock")
@@ -1095,82 +1116,53 @@
             }
         }
 
-        @GuardedBy("mLock")
-        public void sendExtraCommandLocked(String command, Bundle extras) {
-            if (mProvider != null) {
-                long identity = Binder.clearCallingIdentity();
+        @Override
+        public void onReportLocation(Location location) {
+            synchronized (mLock) {
+                handleLocationChangedLocked(location, this);
+            }
+        }
+
+        @Override
+        public void onReportLocation(List<Location> locations) {
+            synchronized (mLock) {
+                LocationProvider gpsProvider = getLocationProviderLocked(GPS_PROVIDER);
+                if (gpsProvider == null || !gpsProvider.isUseableLocked()) {
+                    Slog.w(TAG, "reportLocationBatch() called without user permission");
+                    return;
+                }
+
+                if (mGnssBatchingCallback == null) {
+                    Slog.e(TAG, "reportLocationBatch() called without active Callback");
+                    return;
+                }
+
                 try {
-                    mProvider.sendExtraCommand(command, extras);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
+                    mGnssBatchingCallback.onLocationBatch(locations);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "mGnssBatchingCallback.onLocationBatch failed", e);
                 }
             }
         }
 
-        // called from any thread
-        @Override
-        public void onReportLocation(Location location) {
-            // no security check necessary because this is coming from an internal-only interface
-            // move calls coming from below LMS onto a different thread to avoid deadlock
-            mHandler.post(() -> {
-                synchronized (mLock) {
-                    handleLocationChangedLocked(location, this);
-                }
-            });
-        }
-
-        // called from any thread
-        @Override
-        public void onReportLocation(List<Location> locations) {
-            // move calls coming from below LMS onto a different thread to avoid deadlock
-            mHandler.post(() -> {
-                synchronized (mLock) {
-                    LocationProvider gpsProvider = getLocationProviderLocked(GPS_PROVIDER);
-                    if (gpsProvider == null || !gpsProvider.isUseableLocked()) {
-                        Slog.w(TAG, "reportLocationBatch() called without user permission");
-                        return;
-                    }
-
-                    if (mGnssBatchingCallback == null) {
-                        Slog.e(TAG, "reportLocationBatch() called without active Callback");
-                        return;
-                    }
-
-                    try {
-                        mGnssBatchingCallback.onLocationBatch(locations);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "mGnssBatchingCallback.onLocationBatch failed", e);
-                    }
-                }
-            });
-        }
-
-        // called from any thread
         @Override
         public void onSetEnabled(boolean enabled) {
-            // move calls coming from below LMS onto a different thread to avoid deadlock
-            mHandler.post(() -> {
-                synchronized (mLock) {
-                    if (enabled == mEnabled) {
-                        return;
-                    }
-
-                    if (D) {
-                        Log.d(TAG, mName + " provider enabled is now " + mEnabled);
-                    }
-
-                    mEnabled = enabled;
-                    onUseableChangedLocked(false);
+            synchronized (mLock) {
+                if (enabled == mEnabled) {
+                    return;
                 }
-            });
+
+                if (D) {
+                    Log.d(TAG, mName + " provider enabled is now " + mEnabled);
+                }
+
+                mEnabled = enabled;
+                onUseableChangedLocked(false);
+            }
         }
 
         @Override
         public void onSetProperties(ProviderProperties properties) {
-            // because this does not invoke any other methods which might result in calling back
-            // into the location provider, it is safe to run this on the calling thread. it is also
-            // currently necessary to run this on the calling thread to ensure that property changes
-            // are publicly visibly immediately, ie for mock providers which are created.
             synchronized (mLock) {
                 mProperties = properties;
             }
@@ -1328,9 +1320,8 @@
         }
 
         @Override
-        @GuardedBy("mLock")
-        public void setRequestLocked(ProviderRequest request, WorkSource workSource) {
-            super.setRequestLocked(request, workSource);
+        public void setRequest(ProviderRequest request, WorkSource workSource) {
+            super.setRequest(request, workSource);
             mCurrentRequest = request;
         }
 
@@ -2235,7 +2226,7 @@
             }
         }
 
-        provider.setRequestLocked(providerRequest, worksource);
+        provider.setRequest(providerRequest, worksource);
     }
 
     /**
@@ -2361,7 +2352,7 @@
                     mRealRequest,
                     mReceiver.isListener(),
                     mReceiver.isPendingIntent(),
-                    /* radius= */ 0,
+                    /* geofence= */ null,
                     mActivityManager.getPackageImportance(packageName));
 
             // remove from mRecordsByProvider
@@ -2541,7 +2532,7 @@
                         LocationStatsEnums.USAGE_STARTED,
                         LocationStatsEnums.API_REQUEST_LOCATION_UPDATES,
                         packageName, request, listener != null, intent != null,
-                        /* radius= */ 0,
+                        /* geofence= */ null,
                         mActivityManager.getPackageImportance(packageName));
 
                 Receiver receiver;
@@ -2844,7 +2835,7 @@
                         request,
                         /* hasListener= */ false,
                         intent != null,
-                        geofence.getRadius(),
+                        geofence,
                         mActivityManager.getPackageImportance(packageName));
             }
 
@@ -2876,7 +2867,7 @@
                         /* LocationRequest= */ null,
                         /* hasListener= */ false,
                         intent != null,
-                        geofence.getRadius(),
+                        geofence,
                         mActivityManager.getPackageImportance(packageName));
             }
             mGeofenceManager.removeFence(geofence, intent);
@@ -2919,6 +2910,12 @@
             mCallerIdentity = callerIdentity;
             mListenerName = listenerName;
         }
+
+        @Override
+        public String toString() {
+            return mListenerName + "[" + mCallerIdentity.mPackageName + "(" + mCallerIdentity.mPid
+                    + ")]";
+        }
     }
 
     private static class LinkedListener<TListener> extends LinkedListenerBase {
@@ -2962,18 +2959,18 @@
             gnssDataListeners.put(binder, linkedListener);
             long identity = Binder.clearCallingIdentity();
             try {
-                if (gnssDataProvider == mGnssNavigationMessageProvider
+                if (gnssDataProvider == mGnssMeasurementsProvider
                         || gnssDataProvider == mGnssStatusProvider) {
                     mLocationUsageLogger.logLocationApiUsage(
                             LocationStatsEnums.USAGE_STARTED,
-                            gnssDataProvider == mGnssNavigationMessageProvider
+                            gnssDataProvider == mGnssMeasurementsProvider
                                 ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
                                 : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
                             packageName,
                             /* LocationRequest= */ null,
                             /* hasListener= */ true,
                             /* hasIntent= */ false,
-                            /* radius */ 0,
+                            /* geofence= */ null,
                             mActivityManager.getPackageImportance(packageName));
                 }
                 if (isThrottlingExemptLocked(callerIdentity)
@@ -3003,18 +3000,18 @@
             }
             long identity = Binder.clearCallingIdentity();
             try {
-                if (gnssDataProvider == mGnssNavigationMessageProvider
+                if (gnssDataProvider == mGnssMeasurementsProvider
                         || gnssDataProvider == mGnssStatusProvider) {
                     mLocationUsageLogger.logLocationApiUsage(
                             LocationStatsEnums.USAGE_ENDED,
-                            gnssDataProvider == mGnssNavigationMessageProvider
+                            gnssDataProvider == mGnssMeasurementsProvider
                                 ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
                                 : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
                             linkedListener.mCallerIdentity.mPackageName,
                             /* LocationRequest= */ null,
                             /* hasListener= */ true,
                             /* hasIntent= */ false,
-                            /* radius= */ 0,
+                            /* geofence= */ null,
                             mActivityManager.getPackageImportance(
                                     linkedListener.mCallerIdentity.mPackageName));
                 }
@@ -3119,7 +3116,7 @@
 
             LocationProvider provider = getLocationProviderLocked(providerName);
             if (provider != null) {
-                provider.sendExtraCommandLocked(command, extras);
+                provider.sendExtraCommand(command, extras);
             }
 
             mLocationUsageLogger.logLocationApiUsage(
@@ -3674,6 +3671,8 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
+        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
+
         synchronized (mLock) {
             if (args.length > 0 && args[0].equals("--gnssmetrics")) {
                 if (mGnssMetricsProvider != null) {
@@ -3681,115 +3680,133 @@
                 }
                 return;
             }
-            pw.println("Current Location Manager state:");
-            pw.print("  Current System Time: "
+
+            ipw.println("Location Manager State:");
+            ipw.increaseIndent();
+            ipw.print("Current System Time: "
                     + TimeUtils.logTimeOfDay(System.currentTimeMillis()));
-            pw.println(", Current Elapsed Time: "
+            ipw.println(", Current Elapsed Time: "
                     + TimeUtils.formatDuration(SystemClock.elapsedRealtime()));
-            pw.println("  Current user: " + mCurrentUserId + " " + Arrays.toString(
+            ipw.println("Current user: " + mCurrentUserId + " " + Arrays.toString(
                     mCurrentUserProfiles));
-            pw.println("  Location mode: " + isLocationEnabled());
-            pw.println("  Battery Saver Location Mode: "
+            ipw.println("Location Mode: " + isLocationEnabled());
+            ipw.println("Battery Saver Location Mode: "
                     + locationPowerSaveModeToString(mBatterySaverMode));
-            pw.println("  Location Listeners:");
+
+            ipw.println("Location Listeners:");
+            ipw.increaseIndent();
             for (Receiver receiver : mReceivers.values()) {
-                pw.println("    " + receiver);
+                ipw.println(receiver);
             }
-            pw.println("  Active Records by Provider:");
+            ipw.decreaseIndent();
+
+            ipw.println("Active Records by Provider:");
+            ipw.increaseIndent();
             for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
-                pw.println("    " + entry.getKey() + ":");
+                ipw.println(entry.getKey() + ":");
+                ipw.increaseIndent();
                 for (UpdateRecord record : entry.getValue()) {
-                    pw.println("      " + record);
+                    ipw.println(record);
                 }
+                ipw.decreaseIndent();
             }
+            ipw.decreaseIndent();
 
-            pw.println("  Active GnssMeasurement Listeners:");
-            dumpGnssDataListenersLocked(pw, mGnssMeasurementsListeners);
-            pw.println("  Active GnssNavigationMessage Listeners:");
-            dumpGnssDataListenersLocked(pw, mGnssNavigationMessageListeners);
-            pw.println("  Active GnssStatus Listeners:");
-            dumpGnssDataListenersLocked(pw, mGnssStatusListeners);
+            ipw.println("GnssMeasurement Listeners:");
+            ipw.increaseIndent();
+            for (LinkedListenerBase listener : mGnssMeasurementsListeners.values()) {
+                ipw.println(listener + ": " + isThrottlingExemptLocked(listener.mCallerIdentity));
+            }
+            ipw.decreaseIndent();
 
-            pw.println("  Historical Records by Provider:");
+            ipw.println("GnssNavigationMessage Listeners:");
+            ipw.increaseIndent();
+            for (LinkedListenerBase listener : mGnssNavigationMessageListeners.values()) {
+                ipw.println(listener + ": " + isThrottlingExemptLocked(listener.mCallerIdentity));
+            }
+            ipw.decreaseIndent();
+
+            ipw.println("GnssStatus Listeners:");
+            ipw.increaseIndent();
+            for (LinkedListenerBase listener : mGnssStatusListeners.values()) {
+                ipw.println(listener + ": " + isThrottlingExemptLocked(listener.mCallerIdentity));
+            }
+            ipw.decreaseIndent();
+
+            ipw.println("Historical Records by Provider:");
+            ipw.increaseIndent();
             for (Map.Entry<PackageProviderKey, PackageStatistics> entry
                     : mRequestStatistics.statistics.entrySet()) {
                 PackageProviderKey key = entry.getKey();
-                PackageStatistics stats = entry.getValue();
-                pw.println("    " + key.packageName + ": " + key.providerName + ": " + stats);
+                ipw.println(key.packageName + ": " + key.providerName + ": " + entry.getValue());
             }
-            pw.println("  Last Known Locations:");
-            for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) {
-                String provider = entry.getKey();
-                Location location = entry.getValue();
-                pw.println("    " + provider + ": " + location);
-            }
+            ipw.decreaseIndent();
 
-            pw.println("  Last Known Locations Coarse Intervals:");
-            for (Map.Entry<String, Location> entry : mLastLocationCoarseInterval.entrySet()) {
-                String provider = entry.getKey();
-                Location location = entry.getValue();
-                pw.println("    " + provider + ": " + location);
+            ipw.println("Last Known Locations:");
+            ipw.increaseIndent();
+            for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) {
+                ipw.println(entry.getKey() + ": " + entry.getValue());
             }
+            ipw.decreaseIndent();
+
+            ipw.println("Last Known Coarse Locations:");
+            ipw.increaseIndent();
+            for (Map.Entry<String, Location> entry : mLastLocationCoarseInterval.entrySet()) {
+                ipw.println(entry.getKey() + ": " + entry.getValue());
+            }
+            ipw.decreaseIndent();
 
             if (mGeofenceManager != null) {
-                mGeofenceManager.dump(pw);
-            } else {
-                pw.println("  Geofences: null");
+                ipw.println("Geofences:");
+                ipw.increaseIndent();
+                mGeofenceManager.dump(ipw);
+                ipw.decreaseIndent();
             }
           
             if (mBlacklist != null) {
-                pw.append("  ");
-                mBlacklist.dump(pw);
-            } else {
-                pw.println("  mBlacklist=null");
+                mBlacklist.dump(ipw);
             }
 
             if (mExtraLocationControllerPackage != null) {
-                pw.println(" Location controller extra package: " + mExtraLocationControllerPackage
-                        + " enabled: " + mExtraLocationControllerPackageEnabled);
+                ipw.println("Location Controller Extra Package: " + mExtraLocationControllerPackage
+                        + (mExtraLocationControllerPackageEnabled ? " [enabled]" : "[disabled]"));
             }
 
             if (!mBackgroundThrottlePackageWhitelist.isEmpty()) {
-                pw.println("  Throttling Whitelisted Packages:");
+                ipw.println("Throttling Whitelisted Packages:");
+                ipw.increaseIndent();
                 for (String packageName : mBackgroundThrottlePackageWhitelist) {
-                    pw.println("    " + packageName);
+                    ipw.println(packageName);
                 }
+                ipw.decreaseIndent();
             }
 
             if (!mIgnoreSettingsPackageWhitelist.isEmpty()) {
-                pw.println("  Bypass Whitelisted Packages:");
+                ipw.println("Bypass Whitelisted Packages:");
+                ipw.increaseIndent();
                 for (String packageName : mIgnoreSettingsPackageWhitelist) {
-                    pw.println("    " + packageName);
+                    ipw.println(packageName);
                 }
+                ipw.decreaseIndent();
             }
 
             if (mLocationFudger != null) {
-                pw.append("  fudger: ");
-                mLocationFudger.dump(fd, pw, args);
-            } else {
-                pw.println("  fudger: null");
+                ipw.println("Location Fudger:");
+                ipw.increaseIndent();
+                mLocationFudger.dump(fd, ipw, args);
+                ipw.decreaseIndent();
             }
 
-            if (args.length > 0 && "short".equals(args[0])) {
-                return;
-            }
+            ipw.println("Location Providers:");
+            ipw.increaseIndent();
             for (LocationProvider provider : mProviders) {
-                provider.dumpLocked(fd, pw, args);
+                provider.dumpLocked(fd, ipw, args);
             }
-            if (mGnssBatchingInProgress) {
-                pw.println("  GNSS batching in progress");
-            }
-        }
-    }
+            ipw.decreaseIndent();
 
-    @GuardedBy("mLock")
-    private void dumpGnssDataListenersLocked(PrintWriter pw,
-            ArrayMap<IBinder, ? extends LinkedListenerBase> gnssDataListeners) {
-        for (LinkedListenerBase listener : gnssDataListeners.values()) {
-            CallerIdentity callerIdentity = listener.mCallerIdentity;
-            pw.println("    " + callerIdentity.mPid + " " + callerIdentity.mUid + " "
-                    + callerIdentity.mPackageName + ": "
-                    + isThrottlingExemptLocked(callerIdentity));
+            if (mGnssBatchingInProgress) {
+                ipw.println("GNSS batching in progress");
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/LocationUsageLogger.java b/services/core/java/com/android/server/LocationUsageLogger.java
index c503035..4ca74bf 100644
--- a/services/core/java/com/android/server/LocationUsageLogger.java
+++ b/services/core/java/com/android/server/LocationUsageLogger.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.app.ActivityManager;
+import android.location.Geofence;
 import android.location.LocationManager;
 import android.location.LocationRequest;
 import android.os.SystemClock;
@@ -180,13 +181,14 @@
     public void logLocationApiUsage(int usageType, int apiInUse,
             String packageName, LocationRequest locationRequest,
             boolean hasListener, boolean hasIntent,
-            float radius, int activityImportance) {
+            Geofence geofence, int activityImportance) {
         try {
             if (!checkApiUsageLogCap()) {
                 return;
             }
 
             boolean isLocationRequestNull = locationRequest == null;
+            boolean isGeofenceNull = geofence == null;
             if (D) {
                 Log.d(TAG, "log API Usage to statsd. usageType: " + usageType + ", apiInUse: "
                         + apiInUse + ", packageName: " + (packageName == null ? "" : packageName)
@@ -194,7 +196,8 @@
                         + (isLocationRequestNull ? "" : locationRequest.toString())
                         + ", hasListener: " + hasListener
                         + ", hasIntent: " + hasIntent
-                        + ", radius: " + radius
+                        + ", geofence: "
+                        + (isGeofenceNull ? "" : geofence.toString())
                         + ", importance: " + activityImportance);
             }
 
@@ -219,7 +222,9 @@
                         ? LocationStatsEnums.EXPIRATION_UNKNOWN
                         : getBucketizedExpireIn(locationRequest.getExpireAt()),
                     getCallbackType(apiInUse, hasListener, hasIntent),
-                    bucketizeRadiusToStatsdEnum(radius),
+                    isGeofenceNull
+                        ? LocationStatsEnums.RADIUS_UNKNOWN
+                        : bucketizeRadiusToStatsdEnum(geofence.getRadius()),
                     categorizeActivityImportance(activityImportance));
         } catch (Exception e) {
             // Swallow exceptions to avoid crashing LMS.
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index 06c46b9..fa1653d 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -16,16 +16,15 @@
 
 package com.android.server;
 
-import android.app.PendingIntent;
 import android.app.ProgressDialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncTask;
 import android.os.RecoverySystem;
+import android.os.UserHandle;
 import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.telephony.euicc.EuiccManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
 import android.view.WindowManager;
@@ -33,8 +32,6 @@
 import com.android.internal.R;
 
 import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 public class MasterClearReceiver extends BroadcastReceiver {
     private static final String TAG = "MasterClear";
@@ -58,6 +55,15 @@
                     + "Intent#EXTRA_FORCE_FACTORY_RESET should be used instead.");
         }
 
+        final String factoryResetPackage = context
+                .getString(com.android.internal.R.string.config_factoryResetPackage);
+        if (Intent.ACTION_FACTORY_RESET.equals(intent.getAction())
+                && !TextUtils.isEmpty(factoryResetPackage)) {
+            intent.setPackage(factoryResetPackage).setComponent(null);
+            context.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
+            return;
+        }
+
         final boolean shutdown = intent.getBooleanExtra("shutdown", false);
         final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
         mWipeExternalStorage = intent.getBooleanExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index b6fa157..c0f10a3 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -37,6 +37,7 @@
 import android.os.UserHandle;
 import android.service.carrier.CarrierMessagingService;
 import android.telephony.SmsManager;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.Slog;
 
@@ -331,7 +332,7 @@
         @Override
         public void sendMessage(int subId, String callingPkg, Uri contentUri,
                 String locationUrl, Bundle configOverrides, PendingIntent sentIntent)
-                        throws RemoteException {
+                throws RemoteException {
             Slog.d(TAG, "sendMessage() by " + callingPkg);
             mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message");
             if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
@@ -341,7 +342,8 @@
             }
             contentUri = adjustUriForUserAndGrantPermission(contentUri,
                     CarrierMessagingService.SERVICE_INTERFACE,
-                    Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                    Intent.FLAG_GRANT_READ_URI_PERMISSION,
+                    subId);
             getServiceGuarded().sendMessage(subId, callingPkg, contentUri, locationUrl,
                     configOverrides, sentIntent);
         }
@@ -360,7 +362,8 @@
             }
             contentUri = adjustUriForUserAndGrantPermission(contentUri,
                     CarrierMessagingService.SERVICE_INTERFACE,
-                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+                    subId);
 
             getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, contentUri,
                     configOverrides, downloadedIntent);
@@ -388,7 +391,7 @@
         @Override
         public Uri importMultimediaMessage(String callingPkg, Uri contentUri,
                 String messageId, long timestampSecs, boolean seen, boolean read)
-                        throws RemoteException {
+                throws RemoteException {
             if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SMS, Binder.getCallingUid(),
                     callingPkg) != AppOpsManager.MODE_ALLOWED) {
                 // Silently fail AppOps failure due to not being the default SMS app
@@ -496,12 +499,12 @@
          * even if the caller is not in the primary user.
          *
          * @param contentUri The Uri to adjust
-         * @param action The intent action used to find the associated carrier app
+         * @param action     The intent action used to find the associated carrier app
          * @param permission The permission to add
          * @return The adjusted Uri containing the calling userId.
          */
         private Uri adjustUriForUserAndGrantPermission(Uri contentUri, String action,
-                int permission) {
+                int permission, int subId) {
             final Intent grantIntent = new Intent();
             grantIntent.setData(contentUri);
             grantIntent.setFlags(permission);
@@ -521,9 +524,10 @@
                 // Grant permission for the carrier app.
                 Intent intent = new Intent(action);
                 TelephonyManager telephonyManager =
-                    (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-                List<String> carrierPackages = telephonyManager.getCarrierPackageNamesForIntent(
-                        intent);
+                        (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+                List<String> carrierPackages =
+                        telephonyManager.getCarrierPackageNamesForIntentAndPhone(
+                                intent, SubscriptionManager.getPhoneId(subId));
                 if (carrierPackages != null && carrierPackages.size() == 1) {
                     LocalServices.getService(UriGrantsManagerInternal.class)
                             .grantUriPermissionFromIntent(callingUid, carrierPackages.get(0),
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 8d76634..59e0a28 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -34,9 +34,7 @@
 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.STATS_PER_UID;
-import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_TETHERING;
 
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
@@ -92,7 +90,6 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.HexDump;
 import com.android.internal.util.Preconditions;
-import com.android.server.net.NetworkStatsFactory;
 
 import com.google.android.collect.Maps;
 
@@ -166,8 +163,6 @@
     private final RemoteCallbackList<INetworkManagementEventObserver> mObservers =
             new RemoteCallbackList<>();
 
-    private final NetworkStatsFactory mStatsFactory = new NetworkStatsFactory();
-
     @GuardedBy("mTetheringStatsProviders")
     private final HashMap<ITetheringStatsProvider, String>
             mTetheringStatsProviders = Maps.newHashMap();
@@ -1213,36 +1208,6 @@
     }
 
     @Override
-    public NetworkStats getNetworkStatsSummaryDev() {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        try {
-            return mStatsFactory.readNetworkStatsSummaryDev();
-        } catch (IOException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    @Override
-    public NetworkStats getNetworkStatsSummaryXt() {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        try {
-            return mStatsFactory.readNetworkStatsSummaryXt();
-        } catch (IOException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    @Override
-    public NetworkStats getNetworkStatsDetail() {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        try {
-            return mStatsFactory.readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
-        } catch (IOException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    @Override
     public void setInterfaceQuota(String iface, long quotaBytes) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
@@ -1541,16 +1506,6 @@
         return true;
     }
 
-    @Override
-    public NetworkStats getNetworkStatsUidDetail(int uid, String[] ifaces) {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        try {
-            return mStatsFactory.readNetworkStatsDetail(uid, ifaces, TAG_ALL, null);
-        } catch (IOException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
     private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub {
         @Override
         public NetworkStats getTetherStats(int how) {
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 80d7ac9..df5005e 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -26,7 +26,6 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.database.ContentObserver;
 import android.location.LocationManager;
 import android.net.INetworkRecommendationProvider;
@@ -54,15 +53,14 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.IntArray;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.TransferPipe;
-import com.android.internal.telephony.SmsApplication;
 import com.android.internal.util.DumpUtils;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -294,7 +292,7 @@
                     String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
                             Global.USE_OPEN_WIFI_PACKAGE);
                     if (!TextUtils.isEmpty(useOpenWifiPackage)) {
-                        LocalServices.getService(PackageManagerInternal.class)
+                        LocalServices.getService(PermissionManagerServiceInternal.class)
                                 .grantDefaultPermissionsToDefaultUseOpenWifiApp(useOpenWifiPackage,
                                         userId);
                     }
@@ -306,17 +304,14 @@
                 false /*notifyForDescendants*/,
                 mUseOpenWifiPackageObserver);
         // Set a callback for the package manager to query the use open wifi app.
-        LocalServices.getService(PackageManagerInternal.class).setUseOpenWifiAppPackagesProvider(
-                new PackageManagerInternal.PackagesProvider() {
-                    @Override
-                    public String[] getPackages(int userId) {
-                        String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
-                                Global.USE_OPEN_WIFI_PACKAGE);
-                        if (!TextUtils.isEmpty(useOpenWifiPackage)) {
-                            return new String[]{useOpenWifiPackage};
-                        }
-                        return null;
+        LocalServices.getService(PermissionManagerServiceInternal.class)
+                .setUseOpenWifiAppPackagesProvider((userId) -> {
+                    String useOpenWifiPackage = Global.getString(mContext.getContentResolver(),
+                            Global.USE_OPEN_WIFI_PACKAGE);
+                    if (!TextUtils.isEmpty(useOpenWifiPackage)) {
+                        return new String[]{useOpenWifiPackage};
                     }
+                    return null;
                 });
     }
 
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java b/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java
new file mode 100644
index 0000000..b0b45f4
--- /dev/null
+++ b/services/core/java/com/android/server/NetworkTimeUpdateServiceImpl.java
@@ -0,0 +1,329 @@
+/*
+ * 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.
+ */
+
+package com.android.server;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.NtpTrustedTime;
+import android.util.TimeUtils;
+
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Monitors the network time and updates the system time if it is out of sync
+ * and there hasn't been any NITZ update from the carrier recently.
+ * If looking up the network time fails for some reason, it tries a few times with a short
+ * interval and then resets to checking on longer intervals.
+ * <p>
+ * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
+ * available.
+ * </p>
+ */
+public class NetworkTimeUpdateServiceImpl extends Binder implements NetworkTimeUpdateService {
+
+    private static final String TAG = "NetworkTimeUpdateService";
+    private static final boolean DBG = false;
+
+    private static final int EVENT_AUTO_TIME_CHANGED = 1;
+    private static final int EVENT_POLL_NETWORK_TIME = 2;
+    private static final int EVENT_NETWORK_CHANGED = 3;
+
+    private static final String ACTION_POLL =
+            "com.android.server.NetworkTimeUpdateService.action.POLL";
+
+    private static final int POLL_REQUEST = 0;
+
+    private static final long NOT_SET = -1;
+    private long mNitzTimeSetTime = NOT_SET;
+    private Network mDefaultNetwork = null;
+
+    private final Context mContext;
+    private final NtpTrustedTime mTime;
+    private final AlarmManager mAlarmManager;
+    private final ConnectivityManager mCM;
+    private final PendingIntent mPendingPollIntent;
+    private final PowerManager.WakeLock mWakeLock;
+
+    // NTP lookup is done on this thread and handler
+    private Handler mHandler;
+    private SettingsObserver mSettingsObserver;
+    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
+
+    // Normal polling frequency
+    private final long mPollingIntervalMs;
+    // Try-again polling interval, in case the network request failed
+    private final long mPollingIntervalShorterMs;
+    // Number of times to try again
+    private final int mTryAgainTimesMax;
+    // If the time difference is greater than this threshold, then update the time.
+    private final int mTimeErrorThresholdMs;
+    // Keeps track of how many quick attempts were made to fetch NTP time.
+    // During bootup, the network may not have been up yet, or it's taking time for the
+    // connection to happen.
+    private int mTryAgainCounter;
+
+    public NetworkTimeUpdateServiceImpl(Context context) {
+        mContext = context;
+        mTime = NtpTrustedTime.getInstance(context);
+        mAlarmManager = mContext.getSystemService(AlarmManager.class);
+        mCM = mContext.getSystemService(ConnectivityManager.class);
+
+        Intent pollIntent = new Intent(ACTION_POLL, null);
+        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
+
+        mPollingIntervalMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingInterval);
+        mPollingIntervalShorterMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
+        mTryAgainTimesMax = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpRetry);
+        mTimeErrorThresholdMs = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_ntpThreshold);
+
+        mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
+                PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    }
+
+    @Override
+    public void systemRunning() {
+        registerForTelephonyIntents();
+        registerForAlarms();
+
+        HandlerThread thread = new HandlerThread(TAG);
+        thread.start();
+        mHandler = new MyHandler(thread.getLooper());
+        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
+        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
+
+        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
+        mSettingsObserver.observe(mContext);
+    }
+
+    private void registerForTelephonyIntents() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
+        mContext.registerReceiver(mNitzReceiver, intentFilter);
+    }
+
+    private void registerForAlarms() {
+        mContext.registerReceiver(
+            new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
+                }
+            }, new IntentFilter(ACTION_POLL));
+    }
+
+    private void onPollNetworkTime(int event) {
+        // If Automatic time is not set, don't bother. Similarly, if we don't
+        // have any default network, don't bother.
+        if (mDefaultNetwork == null) return;
+        mWakeLock.acquire();
+        try {
+            onPollNetworkTimeUnderWakeLock(event);
+        } finally {
+            mWakeLock.release();
+        }
+    }
+
+    private void onPollNetworkTimeUnderWakeLock(int event) {
+        // Force an NTP fix when outdated
+        if (mTime.getCacheAge() >= mPollingIntervalMs) {
+            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
+            mTime.forceRefresh();
+        }
+
+        if (mTime.getCacheAge() < mPollingIntervalMs) {
+            // Obtained fresh fix; schedule next normal update
+            resetAlarm(mPollingIntervalMs);
+            if (isAutomaticTimeRequested()) {
+                updateSystemClock(event);
+            }
+
+        } else {
+            // No fresh fix; schedule retry
+            mTryAgainCounter++;
+            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
+                resetAlarm(mPollingIntervalShorterMs);
+            } else {
+                // Try much later
+                mTryAgainCounter = 0;
+                resetAlarm(mPollingIntervalMs);
+            }
+        }
+    }
+
+    private long getNitzAge() {
+        if (mNitzTimeSetTime == NOT_SET) {
+            return Long.MAX_VALUE;
+        } else {
+            return SystemClock.elapsedRealtime() - mNitzTimeSetTime;
+        }
+    }
+
+    /**
+     * Consider updating system clock based on current NTP fix, if requested by
+     * user, significant enough delta, and we don't have a recent NITZ.
+     */
+    private void updateSystemClock(int event) {
+        final boolean forceUpdate = (event == EVENT_AUTO_TIME_CHANGED);
+        if (!forceUpdate) {
+            if (getNitzAge() < mPollingIntervalMs) {
+                if (DBG) Log.d(TAG, "Ignoring NTP update due to recent NITZ");
+                return;
+            }
+
+            final long skew = Math.abs(mTime.currentTimeMillis() - System.currentTimeMillis());
+            if (skew < mTimeErrorThresholdMs) {
+                if (DBG) Log.d(TAG, "Ignoring NTP update due to low skew");
+                return;
+            }
+        }
+
+        SystemClock.setCurrentTimeMillis(mTime.currentTimeMillis());
+    }
+
+    /**
+     * Cancel old alarm and starts a new one for the specified interval.
+     *
+     * @param interval when to trigger the alarm, starting from now.
+     */
+    private void resetAlarm(long interval) {
+        mAlarmManager.cancel(mPendingPollIntent);
+        long now = SystemClock.elapsedRealtime();
+        long next = now + interval;
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
+    }
+
+    /**
+     * Checks if the user prefers to automatically set the time.
+     */
+    private boolean isAutomaticTimeRequested() {
+        return Settings.Global.getInt(
+                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
+    }
+
+    /** Receiver for Nitz time events */
+    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (DBG) Log.d(TAG, "Received " + action);
+            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
+                mNitzTimeSetTime = SystemClock.elapsedRealtime();
+            }
+        }
+    };
+
+    /** Handler to do the network accesses on */
+    private class MyHandler extends Handler {
+
+        public MyHandler(Looper l) {
+            super(l);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_AUTO_TIME_CHANGED:
+                case EVENT_POLL_NETWORK_TIME:
+                case EVENT_NETWORK_CHANGED:
+                    onPollNetworkTime(msg.what);
+                    break;
+            }
+        }
+    }
+
+    private class NetworkTimeUpdateCallback extends NetworkCallback {
+        @Override
+        public void onAvailable(Network network) {
+            Log.d(TAG, String.format("New default network %s; checking time.", network));
+            mDefaultNetwork = network;
+            // Running on mHandler so invoke directly.
+            onPollNetworkTime(EVENT_NETWORK_CHANGED);
+        }
+
+        @Override
+        public void onLost(Network network) {
+            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
+        }
+    }
+
+    /** Observer to watch for changes to the AUTO_TIME setting */
+    private static class SettingsObserver extends ContentObserver {
+
+        private int mMsg;
+        private Handler mHandler;
+
+        SettingsObserver(Handler handler, int msg) {
+            super(handler);
+            mHandler = handler;
+            mMsg = msg;
+        }
+
+        void observe(Context context) {
+            ContentResolver resolver = context.getContentResolver();
+            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            mHandler.obtainMessage(mMsg).sendToTarget();
+        }
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+        pw.print("PollingIntervalMs: ");
+        TimeUtils.formatDuration(mPollingIntervalMs, pw);
+        pw.print("\nPollingIntervalShorterMs: ");
+        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
+        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
+        pw.print("TimeErrorThresholdMs: ");
+        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
+        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
+        pw.println("NTP cache age: " + mTime.getCacheAge());
+        pw.println("NTP cache certainty: " + mTime.getCacheCertainty());
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/NewNetworkTimeUpdateService.java b/services/core/java/com/android/server/NewNetworkTimeUpdateService.java
deleted file mode 100644
index d21741a..0000000
--- a/services/core/java/com/android/server/NewNetworkTimeUpdateService.java
+++ /dev/null
@@ -1,329 +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.
- */
-
-package com.android.server;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-import android.util.NtpTrustedTime;
-import android.util.TimeUtils;
-
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.DumpUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Monitors the network time and updates the system time if it is out of sync
- * and there hasn't been any NITZ update from the carrier recently.
- * If looking up the network time fails for some reason, it tries a few times with a short
- * interval and then resets to checking on longer intervals.
- * <p>
- * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
- * available.
- * </p>
- */
-public class NewNetworkTimeUpdateService extends Binder implements NetworkTimeUpdateService {
-
-    private static final String TAG = "NetworkTimeUpdateService";
-    private static final boolean DBG = false;
-
-    private static final int EVENT_AUTO_TIME_CHANGED = 1;
-    private static final int EVENT_POLL_NETWORK_TIME = 2;
-    private static final int EVENT_NETWORK_CHANGED = 3;
-
-    private static final String ACTION_POLL =
-            "com.android.server.NetworkTimeUpdateService.action.POLL";
-
-    private static final int POLL_REQUEST = 0;
-
-    private static final long NOT_SET = -1;
-    private long mNitzTimeSetTime = NOT_SET;
-    private Network mDefaultNetwork = null;
-
-    private final Context mContext;
-    private final NtpTrustedTime mTime;
-    private final AlarmManager mAlarmManager;
-    private final ConnectivityManager mCM;
-    private final PendingIntent mPendingPollIntent;
-    private final PowerManager.WakeLock mWakeLock;
-
-    // NTP lookup is done on this thread and handler
-    private Handler mHandler;
-    private SettingsObserver mSettingsObserver;
-    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
-
-    // Normal polling frequency
-    private final long mPollingIntervalMs;
-    // Try-again polling interval, in case the network request failed
-    private final long mPollingIntervalShorterMs;
-    // Number of times to try again
-    private final int mTryAgainTimesMax;
-    // If the time difference is greater than this threshold, then update the time.
-    private final int mTimeErrorThresholdMs;
-    // Keeps track of how many quick attempts were made to fetch NTP time.
-    // During bootup, the network may not have been up yet, or it's taking time for the
-    // connection to happen.
-    private int mTryAgainCounter;
-
-    public NewNetworkTimeUpdateService(Context context) {
-        mContext = context;
-        mTime = NtpTrustedTime.getInstance(context);
-        mAlarmManager = mContext.getSystemService(AlarmManager.class);
-        mCM = mContext.getSystemService(ConnectivityManager.class);
-
-        Intent pollIntent = new Intent(ACTION_POLL, null);
-        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
-
-        mPollingIntervalMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingInterval);
-        mPollingIntervalShorterMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
-        mTryAgainTimesMax = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpRetry);
-        mTimeErrorThresholdMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpThreshold);
-
-        mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
-                PowerManager.PARTIAL_WAKE_LOCK, TAG);
-    }
-
-    @Override
-    public void systemRunning() {
-        registerForTelephonyIntents();
-        registerForAlarms();
-
-        HandlerThread thread = new HandlerThread(TAG);
-        thread.start();
-        mHandler = new MyHandler(thread.getLooper());
-        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
-        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
-
-        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
-        mSettingsObserver.observe(mContext);
-    }
-
-    private void registerForTelephonyIntents() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
-        mContext.registerReceiver(mNitzReceiver, intentFilter);
-    }
-
-    private void registerForAlarms() {
-        mContext.registerReceiver(
-            new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
-                }
-            }, new IntentFilter(ACTION_POLL));
-    }
-
-    private void onPollNetworkTime(int event) {
-        // If Automatic time is not set, don't bother. Similarly, if we don't
-        // have any default network, don't bother.
-        if (mDefaultNetwork == null) return;
-        mWakeLock.acquire();
-        try {
-            onPollNetworkTimeUnderWakeLock(event);
-        } finally {
-            mWakeLock.release();
-        }
-    }
-
-    private void onPollNetworkTimeUnderWakeLock(int event) {
-        // Force an NTP fix when outdated
-        if (mTime.getCacheAge() >= mPollingIntervalMs) {
-            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
-            mTime.forceRefresh();
-        }
-
-        if (mTime.getCacheAge() < mPollingIntervalMs) {
-            // Obtained fresh fix; schedule next normal update
-            resetAlarm(mPollingIntervalMs);
-            if (isAutomaticTimeRequested()) {
-                updateSystemClock(event);
-            }
-
-        } else {
-            // No fresh fix; schedule retry
-            mTryAgainCounter++;
-            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
-                resetAlarm(mPollingIntervalShorterMs);
-            } else {
-                // Try much later
-                mTryAgainCounter = 0;
-                resetAlarm(mPollingIntervalMs);
-            }
-        }
-    }
-
-    private long getNitzAge() {
-        if (mNitzTimeSetTime == NOT_SET) {
-            return Long.MAX_VALUE;
-        } else {
-            return SystemClock.elapsedRealtime() - mNitzTimeSetTime;
-        }
-    }
-
-    /**
-     * Consider updating system clock based on current NTP fix, if requested by
-     * user, significant enough delta, and we don't have a recent NITZ.
-     */
-    private void updateSystemClock(int event) {
-        final boolean forceUpdate = (event == EVENT_AUTO_TIME_CHANGED);
-        if (!forceUpdate) {
-            if (getNitzAge() < mPollingIntervalMs) {
-                if (DBG) Log.d(TAG, "Ignoring NTP update due to recent NITZ");
-                return;
-            }
-
-            final long skew = Math.abs(mTime.currentTimeMillis() - System.currentTimeMillis());
-            if (skew < mTimeErrorThresholdMs) {
-                if (DBG) Log.d(TAG, "Ignoring NTP update due to low skew");
-                return;
-            }
-        }
-
-        SystemClock.setCurrentTimeMillis(mTime.currentTimeMillis());
-    }
-
-    /**
-     * Cancel old alarm and starts a new one for the specified interval.
-     *
-     * @param interval when to trigger the alarm, starting from now.
-     */
-    private void resetAlarm(long interval) {
-        mAlarmManager.cancel(mPendingPollIntent);
-        long now = SystemClock.elapsedRealtime();
-        long next = now + interval;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
-    }
-
-    /**
-     * Checks if the user prefers to automatically set the time.
-     */
-    private boolean isAutomaticTimeRequested() {
-        return Settings.Global.getInt(
-                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
-    }
-
-    /** Receiver for Nitz time events */
-    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (DBG) Log.d(TAG, "Received " + action);
-            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
-                mNitzTimeSetTime = SystemClock.elapsedRealtime();
-            }
-        }
-    };
-
-    /** Handler to do the network accesses on */
-    private class MyHandler extends Handler {
-
-        public MyHandler(Looper l) {
-            super(l);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_AUTO_TIME_CHANGED:
-                case EVENT_POLL_NETWORK_TIME:
-                case EVENT_NETWORK_CHANGED:
-                    onPollNetworkTime(msg.what);
-                    break;
-            }
-        }
-    }
-
-    private class NetworkTimeUpdateCallback extends NetworkCallback {
-        @Override
-        public void onAvailable(Network network) {
-            Log.d(TAG, String.format("New default network %s; checking time.", network));
-            mDefaultNetwork = network;
-            // Running on mHandler so invoke directly.
-            onPollNetworkTime(EVENT_NETWORK_CHANGED);
-        }
-
-        @Override
-        public void onLost(Network network) {
-            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
-        }
-    }
-
-    /** Observer to watch for changes to the AUTO_TIME setting */
-    private static class SettingsObserver extends ContentObserver {
-
-        private int mMsg;
-        private Handler mHandler;
-
-        SettingsObserver(Handler handler, int msg) {
-            super(handler);
-            mHandler = handler;
-            mMsg = msg;
-        }
-
-        void observe(Context context) {
-            ContentResolver resolver = context.getContentResolver();
-            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
-                    false, this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            mHandler.obtainMessage(mMsg).sendToTarget();
-        }
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        pw.print("PollingIntervalMs: ");
-        TimeUtils.formatDuration(mPollingIntervalMs, pw);
-        pw.print("\nPollingIntervalShorterMs: ");
-        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
-        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
-        pw.print("TimeErrorThresholdMs: ");
-        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
-        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
-        pw.println("NTP cache age: " + mTime.getCacheAge());
-        pw.println("NTP cache certainty: " + mTime.getCacheCertainty());
-        pw.println();
-    }
-}
diff --git a/services/core/java/com/android/server/OldNetworkTimeUpdateService.java b/services/core/java/com/android/server/OldNetworkTimeUpdateService.java
deleted file mode 100644
index 068b83d..0000000
--- a/services/core/java/com/android/server/OldNetworkTimeUpdateService.java
+++ /dev/null
@@ -1,329 +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.
- */
-
-package com.android.server;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-import android.util.NtpTrustedTime;
-import android.util.TimeUtils;
-
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.DumpUtils;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Monitors the network time and updates the system time if it is out of sync
- * and there hasn't been any NITZ update from the carrier recently.
- * If looking up the network time fails for some reason, it tries a few times with a short
- * interval and then resets to checking on longer intervals.
- * <p>
- * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't
- * available.
- * </p>
- */
-public class OldNetworkTimeUpdateService extends Binder implements NetworkTimeUpdateService {
-
-    private static final String TAG = "NetworkTimeUpdateService";
-    private static final boolean DBG = false;
-
-    private static final int EVENT_AUTO_TIME_CHANGED = 1;
-    private static final int EVENT_POLL_NETWORK_TIME = 2;
-    private static final int EVENT_NETWORK_CHANGED = 3;
-
-    private static final String ACTION_POLL =
-            "com.android.server.NetworkTimeUpdateService.action.POLL";
-
-    private static final int POLL_REQUEST = 0;
-
-    private static final long NOT_SET = -1;
-    private long mNitzTimeSetTime = NOT_SET;
-    private Network mDefaultNetwork = null;
-
-    private final Context mContext;
-    private final NtpTrustedTime mTime;
-    private final AlarmManager mAlarmManager;
-    private final ConnectivityManager mCM;
-    private final PendingIntent mPendingPollIntent;
-    private final PowerManager.WakeLock mWakeLock;
-
-    // NTP lookup is done on this thread and handler
-    private Handler mHandler;
-    private SettingsObserver mSettingsObserver;
-    private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback;
-
-    // Normal polling frequency
-    private final long mPollingIntervalMs;
-    // Try-again polling interval, in case the network request failed
-    private final long mPollingIntervalShorterMs;
-    // Number of times to try again
-    private final int mTryAgainTimesMax;
-    // If the time difference is greater than this threshold, then update the time.
-    private final int mTimeErrorThresholdMs;
-    // Keeps track of how many quick attempts were made to fetch NTP time.
-    // During bootup, the network may not have been up yet, or it's taking time for the
-    // connection to happen.
-    private int mTryAgainCounter;
-
-    public OldNetworkTimeUpdateService(Context context) {
-        mContext = context;
-        mTime = NtpTrustedTime.getInstance(context);
-        mAlarmManager = mContext.getSystemService(AlarmManager.class);
-        mCM = mContext.getSystemService(ConnectivityManager.class);
-
-        Intent pollIntent = new Intent(ACTION_POLL, null);
-        mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
-
-        mPollingIntervalMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingInterval);
-        mPollingIntervalShorterMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpPollingIntervalShorter);
-        mTryAgainTimesMax = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpRetry);
-        mTimeErrorThresholdMs = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_ntpThreshold);
-
-        mWakeLock = context.getSystemService(PowerManager.class).newWakeLock(
-                PowerManager.PARTIAL_WAKE_LOCK, TAG);
-    }
-
-    @Override
-    public void systemRunning() {
-        registerForTelephonyIntents();
-        registerForAlarms();
-
-        HandlerThread thread = new HandlerThread(TAG);
-        thread.start();
-        mHandler = new MyHandler(thread.getLooper());
-        mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback();
-        mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler);
-
-        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
-        mSettingsObserver.observe(mContext);
-    }
-
-    private void registerForTelephonyIntents() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME);
-        mContext.registerReceiver(mNitzReceiver, intentFilter);
-    }
-
-    private void registerForAlarms() {
-        mContext.registerReceiver(
-            new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
-                }
-            }, new IntentFilter(ACTION_POLL));
-    }
-
-    private void onPollNetworkTime(int event) {
-        // If Automatic time is not set, don't bother. Similarly, if we don't
-        // have any default network, don't bother.
-        if (mDefaultNetwork == null) return;
-        mWakeLock.acquire();
-        try {
-            onPollNetworkTimeUnderWakeLock(event);
-        } finally {
-            mWakeLock.release();
-        }
-    }
-
-    private void onPollNetworkTimeUnderWakeLock(int event) {
-        // Force an NTP fix when outdated
-        if (mTime.getCacheAge() >= mPollingIntervalMs) {
-            if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
-            mTime.forceRefresh();
-        }
-
-        if (mTime.getCacheAge() < mPollingIntervalMs) {
-            // Obtained fresh fix; schedule next normal update
-            resetAlarm(mPollingIntervalMs);
-            if (isAutomaticTimeRequested()) {
-                updateSystemClock(event);
-            }
-
-        } else {
-            // No fresh fix; schedule retry
-            mTryAgainCounter++;
-            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {
-                resetAlarm(mPollingIntervalShorterMs);
-            } else {
-                // Try much later
-                mTryAgainCounter = 0;
-                resetAlarm(mPollingIntervalMs);
-            }
-        }
-    }
-
-    private long getNitzAge() {
-        if (mNitzTimeSetTime == NOT_SET) {
-            return Long.MAX_VALUE;
-        } else {
-            return SystemClock.elapsedRealtime() - mNitzTimeSetTime;
-        }
-    }
-
-    /**
-     * Consider updating system clock based on current NTP fix, if requested by
-     * user, significant enough delta, and we don't have a recent NITZ.
-     */
-    private void updateSystemClock(int event) {
-        final boolean forceUpdate = (event == EVENT_AUTO_TIME_CHANGED);
-        if (!forceUpdate) {
-            if (getNitzAge() < mPollingIntervalMs) {
-                if (DBG) Log.d(TAG, "Ignoring NTP update due to recent NITZ");
-                return;
-            }
-
-            final long skew = Math.abs(mTime.currentTimeMillis() - System.currentTimeMillis());
-            if (skew < mTimeErrorThresholdMs) {
-                if (DBG) Log.d(TAG, "Ignoring NTP update due to low skew");
-                return;
-            }
-        }
-
-        SystemClock.setCurrentTimeMillis(mTime.currentTimeMillis());
-    }
-
-    /**
-     * Cancel old alarm and starts a new one for the specified interval.
-     *
-     * @param interval when to trigger the alarm, starting from now.
-     */
-    private void resetAlarm(long interval) {
-        mAlarmManager.cancel(mPendingPollIntent);
-        long now = SystemClock.elapsedRealtime();
-        long next = now + interval;
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent);
-    }
-
-    /**
-     * Checks if the user prefers to automatically set the time.
-     */
-    private boolean isAutomaticTimeRequested() {
-        return Settings.Global.getInt(
-                mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0;
-    }
-
-    /** Receiver for Nitz time events */
-    private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (DBG) Log.d(TAG, "Received " + action);
-            if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) {
-                mNitzTimeSetTime = SystemClock.elapsedRealtime();
-            }
-        }
-    };
-
-    /** Handler to do the network accesses on */
-    private class MyHandler extends Handler {
-
-        public MyHandler(Looper l) {
-            super(l);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_AUTO_TIME_CHANGED:
-                case EVENT_POLL_NETWORK_TIME:
-                case EVENT_NETWORK_CHANGED:
-                    onPollNetworkTime(msg.what);
-                    break;
-            }
-        }
-    }
-
-    private class NetworkTimeUpdateCallback extends NetworkCallback {
-        @Override
-        public void onAvailable(Network network) {
-            Log.d(TAG, String.format("New default network %s; checking time.", network));
-            mDefaultNetwork = network;
-            // Running on mHandler so invoke directly.
-            onPollNetworkTime(EVENT_NETWORK_CHANGED);
-        }
-
-        @Override
-        public void onLost(Network network) {
-            if (network.equals(mDefaultNetwork)) mDefaultNetwork = null;
-        }
-    }
-
-    /** Observer to watch for changes to the AUTO_TIME setting */
-    private static class SettingsObserver extends ContentObserver {
-
-        private int mMsg;
-        private Handler mHandler;
-
-        SettingsObserver(Handler handler, int msg) {
-            super(handler);
-            mHandler = handler;
-            mMsg = msg;
-        }
-
-        void observe(Context context) {
-            ContentResolver resolver = context.getContentResolver();
-            resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME),
-                    false, this);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            mHandler.obtainMessage(mMsg).sendToTarget();
-        }
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        pw.print("PollingIntervalMs: ");
-        TimeUtils.formatDuration(mPollingIntervalMs, pw);
-        pw.print("\nPollingIntervalShorterMs: ");
-        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
-        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
-        pw.print("TimeErrorThresholdMs: ");
-        TimeUtils.formatDuration(mTimeErrorThresholdMs, pw);
-        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
-        pw.println("NTP cache age: " + mTime.getCacheAge());
-        pw.println("NTP cache certainty: " + mTime.getCacheCertainty());
-        pw.println();
-    }
-}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d2b992b..deff7ef 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -580,6 +580,7 @@
     private static final int H_RUN_IDLE_MAINT = 11;
     private static final int H_ABORT_IDLE_MAINT = 12;
     private static final int H_BOOT_COMPLETED = 13;
+    private static final int H_COMPLETE_UNLOCK_USER = 14;
 
     class StorageManagerServiceHandler extends Handler {
         public StorageManagerServiceHandler(Looper looper) {
@@ -698,7 +699,10 @@
                     abortIdleMaint((Runnable)msg.obj);
                     break;
                 }
-
+                case H_COMPLETE_UNLOCK_USER: {
+                    completeUnlockUser((int) msg.obj);
+                    break;
+                }
             }
         }
     }
@@ -978,6 +982,17 @@
             Slog.wtf(TAG, e);
         }
 
+        mHandler.obtainMessage(H_COMPLETE_UNLOCK_USER, userId).sendToTarget();
+    }
+
+    private void completeUnlockUser(int userId) {
+        // If user 0 has completed unlock, perform a one-time migration of legacy obb data
+        // to its new location. This may take time depending on the size of the data to be copied
+        // so it's done on the StorageManager handler thread.
+        if (userId == 0) {
+            mPmInternal.migrateLegacyObbData();
+        }
+
         // Record user as started so newly mounted volumes kick off events
         // correctly, then synthesize events for any already-mounted volumes.
         synchronized (mLock) {
@@ -2820,6 +2835,12 @@
         }
     }
 
+    private boolean isSystemUnlocked(int userId) {
+        synchronized (mLock) {
+            return ArrayUtils.contains(mSystemUnlockedUsers, userId);
+        }
+    }
+
     @Override
     public void prepareUserStorage(String volumeUuid, int userId, int serialNumber, int flags) {
         enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
@@ -2996,6 +3017,11 @@
         final boolean realState = (flags & StorageManager.FLAG_REAL_STATE) != 0;
         final boolean includeInvisible = (flags & StorageManager.FLAG_INCLUDE_INVISIBLE) != 0;
 
+        // Report all volumes as unmounted until we've recorded that user 0 has unlocked. There
+        // are no guarantees that callers will see a consistent view of the volume before that
+        // point
+        final boolean systemUserUnlocked = isSystemUnlocked(UserHandle.USER_SYSTEM);
+
         final boolean userKeyUnlocked;
         final boolean storagePermission;
         final long token = Binder.clearCallingIdentity();
@@ -3031,7 +3057,9 @@
                 if (!match) continue;
 
                 boolean reportUnmounted = false;
-                if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
+                if (!systemUserUnlocked) {
+                    reportUnmounted = true;
+                } else if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
                     reportUnmounted = true;
                 } else if (!storagePermission && !realState) {
                     reportUnmounted = true;
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index c5b4966..9711152 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -17,12 +17,15 @@
 package com.android.server;
 
 import android.annotation.NonNull;
+import android.annotation.UserIdInt;
 import android.content.Context;
 import android.os.Environment;
 import android.os.SystemClock;
 import android.os.Trace;
 import android.util.Slog;
 
+import com.android.server.utils.TimingsTraceAndSlog;
+
 import java.io.File;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -138,9 +141,10 @@
      * Starts the specified boot phase for all system services that have been started up to
      * this point.
      *
+     * @param t trace logger
      * @param phase The boot phase to start.
      */
-    public void startBootPhase(final int phase) {
+    public void startBootPhase(@NonNull TimingsTraceAndSlog t, int phase) {
         if (phase <= mCurrentPhase) {
             throw new IllegalArgumentException("Next phase must be larger than previous");
         }
@@ -148,12 +152,12 @@
 
         Slog.i(TAG, "Starting phase " + mCurrentPhase);
         try {
-            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase);
+            t.traceBegin("OnBootPhase " + phase);
             final int serviceLen = mServices.size();
             for (int i = 0; i < serviceLen; i++) {
                 final SystemService service = mServices.get(i);
                 long time = SystemClock.elapsedRealtime();
-                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName());
+                t.traceBegin(service.getClass().getName());
                 try {
                     service.onBootPhase(mCurrentPhase);
                 } catch (Exception ex) {
@@ -163,10 +167,15 @@
                             + mCurrentPhase, ex);
                 }
                 warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase");
-                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+                t.traceEnd();
             }
         } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+            t.traceEnd();
+        }
+
+        if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+            final long totalBootTime = SystemClock.uptimeMillis() - mRuntimeStartUptime;
+            t.logDuration("TotalBootTime", totalBootTime);
         }
     }
 
@@ -177,13 +186,17 @@
         return mCurrentPhase >= SystemService.PHASE_BOOT_COMPLETED;
     }
 
-    public void startUser(final int userHandle) {
+    /**
+     * Starts the given user.
+     */
+    public void startUser(@NonNull TimingsTraceAndSlog t, final @UserIdInt int userHandle) {
+        t.traceBegin("ssm.startUser-" + userHandle);
         Slog.i(TAG, "Calling onStartUser u" + userHandle);
         final int serviceLen = mServices.size();
         for (int i = 0; i < serviceLen; i++) {
             final SystemService service = mServices.get(i);
-            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStartUser "
-                    + service.getClass().getName());
+            final String serviceName = service.getClass().getName();
+            t.traceBegin("onStartUser-" + userHandle + " " + serviceName);
             long time = SystemClock.elapsedRealtime();
             try {
                 service.onStartUser(userHandle);
@@ -192,84 +205,109 @@
                         + " to service " + service.getClass().getName(), ex);
             }
             warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStartUser ");
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+            t.traceEnd();
         }
+        t.traceEnd();
     }
 
-    public void unlockUser(final int userHandle) {
+    /**
+     * Unlocks the given user.
+     */
+    public void unlockUser(final @UserIdInt int userHandle) {
+        final TimingsTraceAndSlog t = TimingsTraceAndSlog.newAsyncLog();
+        t.traceBegin("ssm.unlockUser-" + userHandle);
         Slog.i(TAG, "Calling onUnlockUser u" + userHandle);
         final int serviceLen = mServices.size();
         for (int i = 0; i < serviceLen; i++) {
             final SystemService service = mServices.get(i);
-            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onUnlockUser "
-                    + service.getClass().getName());
+            final String serviceName = service.getClass().getName();
+            t.traceBegin("onUnlockUser-" + userHandle + " " + serviceName);
             long time = SystemClock.elapsedRealtime();
             try {
                 service.onUnlockUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting unlock of user " + userHandle
-                        + " to service " + service.getClass().getName(), ex);
+                        + " to service " + serviceName, ex);
             }
             warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onUnlockUser ");
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+            t.traceEnd();
         }
+        t.traceEnd();
     }
 
-    public void switchUser(final int userHandle) {
+    /**
+     * Switches to the given user.
+     */
+    public void switchUser(final @UserIdInt int userHandle) {
+        final TimingsTraceAndSlog t = TimingsTraceAndSlog.newAsyncLog();
+        t.traceBegin("ssm.switchUser-" + userHandle);
         Slog.i(TAG, "Calling switchUser u" + userHandle);
         final int serviceLen = mServices.size();
         for (int i = 0; i < serviceLen; i++) {
             final SystemService service = mServices.get(i);
-            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onSwitchUser "
-                    + service.getClass().getName());
+            final String serviceName = service.getClass().getName();
+            t.traceBegin("onSwitchUser-" + userHandle + " " + serviceName);
             long time = SystemClock.elapsedRealtime();
             try {
                 service.onSwitchUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting switch of user " + userHandle
-                        + " to service " + service.getClass().getName(), ex);
+                        + " to service " + serviceName, ex);
             }
             warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onSwitchUser");
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+            t.traceEnd();
         }
+        t.traceEnd();
     }
 
-    public void stopUser(final int userHandle) {
+    /**
+     * Stops the given user.
+     */
+    public void stopUser(final @UserIdInt int userHandle) {
+        final TimingsTraceAndSlog t = TimingsTraceAndSlog.newAsyncLog();
+        t.traceBegin("ssm.stopUser-" + userHandle);
         Slog.i(TAG, "Calling onStopUser u" + userHandle);
         final int serviceLen = mServices.size();
         for (int i = 0; i < serviceLen; i++) {
             final SystemService service = mServices.get(i);
-            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStopUser "
-                    + service.getClass().getName());
+            final String serviceName = service.getClass().getName();
+            t.traceBegin("onStopUser-" + userHandle + " " + serviceName);
             long time = SystemClock.elapsedRealtime();
             try {
                 service.onStopUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting stop of user " + userHandle
-                        + " to service " + service.getClass().getName(), ex);
+                        + " to service " + serviceName, ex);
             }
             warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStopUser");
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+            t.traceEnd();
         }
+        t.traceEnd();
     }
 
-    public void cleanupUser(final int userHandle) {
+    /**
+     * Cleans up the given user.
+     */
+    public void cleanupUser(final @UserIdInt int userHandle) {
+        final TimingsTraceAndSlog t = TimingsTraceAndSlog.newAsyncLog();
+        t.traceBegin("ssm.cleanupUser-" + userHandle);
         Slog.i(TAG, "Calling onCleanupUser u" + userHandle);
         final int serviceLen = mServices.size();
         for (int i = 0; i < serviceLen; i++) {
             final SystemService service = mServices.get(i);
-            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onCleanupUser "
-                    + service.getClass().getName());
+            final String serviceName = service.getClass().getName();
+            t.traceBegin("onCleanupUser-" + userHandle + " " + serviceName);
             long time = SystemClock.elapsedRealtime();
             try {
                 service.onCleanupUser(userHandle);
             } catch (Exception ex) {
                 Slog.wtf(TAG, "Failure reporting cleanup of user " + userHandle
-                        + " to service " + service.getClass().getName(), ex);
+                        + " to service " + serviceName, ex);
             }
             warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onCleanupUser");
-            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+            t.traceEnd();
         }
+        t.traceEnd();
     }
 
     /** Sets the safe mode flag for services to query. */
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 1a6faec..f7e825e 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1027,7 +1027,12 @@
                 log(str);
             }
             mLocalLog.log(str);
-            if (validatePhoneId(phoneId)) {
+            // for service state updates, don't notify clients when subId is invalid. This prevents
+            // us from sending incorrect notifications like b/133140128
+            // In the future, we can remove this logic for every notification here and add a
+            // callback so listeners know when their PhoneStateListener's subId becomes invalid, but
+            // for now we use the simplest fix.
+            if (validatePhoneId(phoneId) && SubscriptionManager.isValidSubscriptionId(subId)) {
                 mServiceState[phoneId] = state;
 
                 for (Record r : mRecords) {
@@ -1059,7 +1064,8 @@
                     }
                 }
             } else {
-                log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId);
+                log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId
+                        + " or subId=" + subId);
             }
             handleRemoveListLocked();
         }
@@ -1255,23 +1261,21 @@
         }
     }
 
-    public void notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
-        notifyPhysicalChannelConfigurationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                configs);
-    }
-
-    public void notifyPhysicalChannelConfigurationForSubscriber(int subId,
+    /**
+     * Notify physical channel configuration according to subscripton ID and phone ID
+     */
+    public void notifyPhysicalChannelConfigurationForSubscriber(int phoneId, int subId,
             List<PhysicalChannelConfig> configs) {
         if (!checkNotifyPermission("notifyPhysicalChannelConfiguration()")) {
             return;
         }
 
         if (VDBG) {
-            log("notifyPhysicalChannelConfiguration: subId=" + subId + " configs=" + configs);
+            log("notifyPhysicalChannelConfiguration: subId=" + subId + " phoneId=" + phoneId
+                    + " configs=" + configs);
         }
 
         synchronized (mRecords) {
-            int phoneId = SubscriptionManager.getPhoneId(subId);
             if (validatePhoneId(phoneId)) {
                 mPhysicalChannelConfigs.set(phoneId, configs);
                 for (Record r : mRecords) {
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 0eb3a84..30a3563 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -46,7 +46,9 @@
 import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
+import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings.Secure;
 import android.service.dreams.Sandman;
 import android.service.vr.IVrManager;
@@ -71,6 +73,7 @@
 
     // Enable launching of applications when entering the dock.
     private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true;
+    private static final String SYSTEM_PROPERTY_DEVICE_THEME = "persist.sys.theme";
 
     final Object mLock = new Object();
     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
@@ -330,8 +333,7 @@
             mNightMode = defaultNightMode;
         }
 
-        // false if night mode stayed the same, true otherwise.
-        return !(oldNightMode == mNightMode);
+        return oldNightMode != mNightMode;
     }
 
     private final IUiModeManager.Stub mService = new IUiModeManager.Stub() {
@@ -415,6 +417,11 @@
                         if (!mCarModeEnabled) {
                             Secure.putIntForUser(getContext().getContentResolver(),
                                     Secure.UI_NIGHT_MODE, mode, user);
+
+                            if (UserManager.get(getContext()).isPrimaryUser()) {
+                                SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME,
+                                        Integer.toString(mode));
+                            }
                         }
 
                         mNightMode = mode;
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 1d94662..0748279 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.IUidObserver;
@@ -116,6 +117,7 @@
     private final LinkedList<VibrationInfo> mPreviousRingVibrations;
     private final LinkedList<VibrationInfo> mPreviousNotificationVibrations;
     private final LinkedList<VibrationInfo> mPreviousAlarmVibrations;
+    private final LinkedList<ExternalVibration> mPreviousExternalVibrations;
     private final LinkedList<VibrationInfo> mPreviousVibrations;
     private final int mPreviousVibrationsLimit;
     private final boolean mAllowPriorityVibrationsInLowPowerMode;
@@ -192,7 +194,7 @@
         // with other system events, any duration calculations should be done use startTime so as
         // not to be affected by discontinuities created by RTC adjustments.
         public final long startTimeDebug;
-        public final int usageHint;
+        public final AudioAttributes attrs;
         public final int uid;
         public final String opPkg;
         public final String reason;
@@ -205,12 +207,12 @@
         public VibrationEffect originalEffect;
 
         private Vibration(IBinder token, VibrationEffect effect,
-                int usageHint, int uid, String opPkg, String reason) {
+                AudioAttributes attrs, int uid, String opPkg, String reason) {
             this.token = token;
             this.effect = effect;
             this.startTime = SystemClock.elapsedRealtime();
             this.startTimeDebug = System.currentTimeMillis();
-            this.usageHint = usageHint;
+            this.attrs = attrs;
             this.uid = uid;
             this.opPkg = opPkg;
             this.reason = reason;
@@ -230,7 +232,7 @@
         }
 
         public boolean isHapticFeedback() {
-            if (VibratorService.this.isHapticFeedback(usageHint)) {
+            if (VibratorService.this.isHapticFeedback(attrs.getUsage())) {
                 return true;
             }
             if (effect instanceof VibrationEffect.Prebaked) {
@@ -255,15 +257,15 @@
         }
 
         public boolean isNotification() {
-            return VibratorService.this.isNotification(usageHint);
+            return VibratorService.this.isNotification(attrs.getUsage());
         }
 
         public boolean isRingtone() {
-            return VibratorService.this.isRingtone(usageHint);
+            return VibratorService.this.isRingtone(attrs.getUsage());
         }
 
         public boolean isAlarm() {
-            return VibratorService.this.isAlarm(usageHint);
+            return VibratorService.this.isAlarm(attrs.getUsage());
         }
 
         public boolean isFromSystem() {
@@ -272,7 +274,7 @@
 
         public VibrationInfo toInfo() {
             return new VibrationInfo(
-                    startTimeDebug, effect, originalEffect, usageHint, uid, opPkg, reason);
+                    startTimeDebug, effect, originalEffect, attrs, uid, opPkg, reason);
         }
     }
 
@@ -280,18 +282,18 @@
         private final long mStartTimeDebug;
         private final VibrationEffect mEffect;
         private final VibrationEffect mOriginalEffect;
-        private final int mUsageHint;
+        private final AudioAttributes mAttrs;
         private final int mUid;
         private final String mOpPkg;
         private final String mReason;
 
         public VibrationInfo(long startTimeDebug, VibrationEffect effect,
-                VibrationEffect originalEffect, int usageHint, int uid,
+                VibrationEffect originalEffect, AudioAttributes attrs, int uid,
                 String opPkg, String reason) {
             mStartTimeDebug = startTimeDebug;
             mEffect = effect;
             mOriginalEffect = originalEffect;
-            mUsageHint = usageHint;
+            mAttrs = attrs;
             mUid = uid;
             mOpPkg = opPkg;
             mReason = reason;
@@ -306,8 +308,8 @@
                     .append(mEffect)
                     .append(", originalEffect: ")
                     .append(mOriginalEffect)
-                    .append(", usageHint: ")
-                    .append(mUsageHint)
+                    .append(", attrs: ")
+                    .append(mAttrs)
                     .append(", uid: ")
                     .append(mUid)
                     .append(", opPkg: ")
@@ -368,6 +370,7 @@
         mPreviousNotificationVibrations = new LinkedList<>();
         mPreviousAlarmVibrations = new LinkedList<>();
         mPreviousVibrations = new LinkedList<>();
+        mPreviousExternalVibrations = new LinkedList<>();
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_SCREEN_OFF);
@@ -547,12 +550,11 @@
     }
 
     @Override // Binder call
-    public void vibrate(int uid, String opPkg, VibrationEffect effect, int usageHint, String reason,
-            IBinder token) {
+    public void vibrate(int uid, String opPkg, VibrationEffect effect,
+            @Nullable AudioAttributes attrs, String reason, IBinder token) {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason = " + reason);
         try {
-            if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
-                    != PackageManager.PERMISSION_GRANTED) {
+            if (!hasPermission(android.Manifest.permission.VIBRATE)) {
                 throw new SecurityException("Requires VIBRATE permission");
             }
             if (token == null) {
@@ -564,6 +566,22 @@
                 return;
             }
 
+            if (attrs == null) {
+                attrs = new AudioAttributes.Builder()
+                        .setUsage(AudioAttributes.USAGE_UNKNOWN)
+                        .build();
+            }
+
+            if (shouldBypassDnd(attrs)) {
+                if (!(hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+                        || hasPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+                        || hasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING))) {
+                    final int flags = attrs.getAllFlags()
+                            & ~AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
+                    attrs = new AudioAttributes.Builder(attrs).replaceFlags(flags).build();
+                }
+            }
+
             // If our current vibration is longer than the new vibration and is the same amplitude,
             // then just let the current one finish.
             synchronized (mLock) {
@@ -606,13 +624,13 @@
                     return;
                 }
 
-                Vibration vib = new Vibration(token, effect, usageHint, uid, opPkg, reason);
+                Vibration vib = new Vibration(token, effect, attrs, uid, opPkg, reason);
                 if (mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)
                         > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
                         && !vib.isNotification() && !vib.isRingtone() && !vib.isAlarm()) {
                     Slog.e(TAG, "Ignoring incoming vibration as process with"
-                            + " uid = " + uid + " is background,"
-                            + " usage = " + AudioAttributes.usageToString(vib.usageHint));
+                            + " uid= " + uid + " is background,"
+                            + " attrs= " + vib.attrs);
                     return;
                 }
                 linkVibration(vib);
@@ -630,6 +648,11 @@
         }
     }
 
+    private boolean hasPermission(String permission) {
+        return mContext.checkCallingOrSelfPermission(permission)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
     private static boolean isRepeatingVibration(VibrationEffect effect) {
         return effect.getDuration() == Long.MAX_VALUE;
     }
@@ -758,14 +781,14 @@
             if (vib.effect instanceof VibrationEffect.OneShot) {
                 Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
                 VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect;
-                doVibratorOn(oneShot.getDuration(), oneShot.getAmplitude(), vib.uid, vib.usageHint);
+                doVibratorOn(oneShot.getDuration(), oneShot.getAmplitude(), vib.uid, vib.attrs);
                 mH.postDelayed(mVibrationEndRunnable, oneShot.getDuration());
             } else if (vib.effect instanceof VibrationEffect.Waveform) {
                 // mThread better be null here. doCancelVibrate should always be
                 // called before startNextVibrationLocked or startVibrationLocked.
                 Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
                 VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect;
-                mThread = new VibrateThread(waveform, vib.uid, vib.usageHint);
+                mThread = new VibrateThread(waveform, vib.uid, vib.attrs);
                 mThread.start();
             } else if (vib.effect instanceof VibrationEffect.Prebaked) {
                 Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
@@ -786,13 +809,14 @@
             return true;
         }
 
-        if (vib.usageHint == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {
+        if (vib.attrs.getUsage() == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {
             return true;
         }
 
-        if (vib.usageHint == AudioAttributes.USAGE_ALARM ||
-                vib.usageHint == AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY ||
-                vib.usageHint == AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST) {
+        if (vib.attrs.getUsage() == AudioAttributes.USAGE_ALARM
+                || vib.attrs.getUsage() == AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
+                || vib.attrs.getUsage()
+                    == AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST) {
             return true;
         }
 
@@ -885,12 +909,24 @@
         }
     }
 
+    private static boolean shouldBypassDnd(AudioAttributes attrs) {
+        return (attrs.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0;
+    }
+
     private int getAppOpMode(Vibration vib) {
         int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE,
-                vib.usageHint, vib.uid, vib.opPkg);
+                vib.attrs.getUsage(), vib.uid, vib.opPkg);
         if (mode == AppOpsManager.MODE_ALLOWED) {
             mode = mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, vib.uid, vib.opPkg);
         }
+
+        if (mode == AppOpsManager.MODE_IGNORED && shouldBypassDnd(vib.attrs)) {
+            // If we're just ignoring the vibration op then this is set by DND and we should ignore
+            // if we're asked to bypass. AppOps won't be able to record this operation, so make
+            // sure we at least note it in the logs for debugging.
+            Slog.d(TAG, "Bypassing DND for vibration: " + vib);
+            mode = AppOpsManager.MODE_ALLOWED;
+        }
         return mode;
     }
 
@@ -1030,7 +1066,7 @@
         return vibratorExists();
     }
 
-    private void doVibratorOn(long millis, int amplitude, int uid, int usageHint) {
+    private void doVibratorOn(long millis, int amplitude, int uid, AudioAttributes attrs) {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn");
         try {
             synchronized (mInputDeviceVibrators) {
@@ -1044,10 +1080,8 @@
                 noteVibratorOnLocked(uid, millis);
                 final int vibratorCount = mInputDeviceVibrators.size();
                 if (vibratorCount != 0) {
-                    final AudioAttributes attributes =
-                            new AudioAttributes.Builder().setUsage(usageHint).build();
                     for (int i = 0; i < vibratorCount; i++) {
-                        mInputDeviceVibrators.get(i).vibrate(millis, attributes);
+                        mInputDeviceVibrators.get(i).vibrate(millis, attrs);
                     }
                 } else {
                     // Note: ordering is important here! Many haptic drivers will reset their
@@ -1116,7 +1150,7 @@
                 Slog.w(TAG, "Failed to play prebaked effect, no fallback");
                 return 0;
             }
-            Vibration fallbackVib = new Vibration(vib.token, effect, vib.usageHint, vib.uid,
+            Vibration fallbackVib = new Vibration(vib.token, effect, vib.attrs, vib.uid,
                     vib.opPkg, vib.reason + " (fallback)");
             final int intensity = getCurrentIntensityLocked(fallbackVib);
             linkVibration(fallbackVib);
@@ -1211,14 +1245,14 @@
     private class VibrateThread extends Thread {
         private final VibrationEffect.Waveform mWaveform;
         private final int mUid;
-        private final int mUsageHint;
+        private final AudioAttributes mAttrs;
 
         private boolean mForceStop;
 
-        VibrateThread(VibrationEffect.Waveform waveform, int uid, int usageHint) {
+        VibrateThread(VibrationEffect.Waveform waveform, int uid, AudioAttributes attrs) {
             mWaveform = waveform;
             mUid = uid;
-            mUsageHint = usageHint;
+            mAttrs = attrs;
             mTmpWorkSource.set(uid);
             mWakeLock.setWorkSource(mTmpWorkSource);
         }
@@ -1293,7 +1327,7 @@
                                     // appropriate intervals.
                                     onDuration = getTotalOnDuration(timings, amplitudes, index - 1,
                                             repeat);
-                                    doVibratorOn(onDuration, amplitude, mUid, mUsageHint);
+                                    doVibratorOn(onDuration, amplitude, mUid, mAttrs);
                                 } else {
                                     doVibratorSetAmplitude(amplitude);
                                 }
@@ -1417,6 +1451,12 @@
                 pw.print("    ");
                 pw.println(info.toString());
             }
+
+            pw.println("  Previous external vibrations:");
+            for (ExternalVibration vib : mPreviousExternalVibrations) {
+                pw.print("    ");
+                pw.println(vib.toString());
+            }
         }
     }
 
@@ -1428,6 +1468,8 @@
     }
 
     final class ExternalVibratorService extends IExternalVibratorService.Stub {
+        ExternalVibrationDeathRecipient mCurrentExternalDeathRecipient;
+
         @Override
         public int onExternalVibrationStart(ExternalVibration vib) {
             if (!mSupportsExternalControl) {
@@ -1461,6 +1503,12 @@
                     // Note that this doesn't support multiple concurrent external controls, as we
                     // would need to mute the old one still if it came from a different controller.
                     mCurrentExternalVibration = vib;
+                    mCurrentExternalDeathRecipient = new ExternalVibrationDeathRecipient();
+                    mCurrentExternalVibration.linkToDeath(mCurrentExternalDeathRecipient);
+                    if (mPreviousExternalVibrations.size() > mPreviousVibrationsLimit) {
+                        mPreviousExternalVibrations.removeFirst();
+                    }
+                    mPreviousExternalVibrations.addLast(vib);
                     if (DEBUG) {
                         Slog.e(TAG, "Playing external vibration: " + vib);
                     }
@@ -1501,6 +1549,8 @@
         public void onExternalVibrationStop(ExternalVibration vib) {
             synchronized (mLock) {
                 if (vib.equals(mCurrentExternalVibration)) {
+                    mCurrentExternalVibration.unlinkToDeath(mCurrentExternalDeathRecipient);
+                    mCurrentExternalDeathRecipient = null;
                     mCurrentExternalVibration = null;
                     setVibratorUnderExternalControl(false);
                     if (DEBUG) {
@@ -1509,6 +1559,14 @@
                 }
             }
         }
+
+        private class ExternalVibrationDeathRecipient implements IBinder.DeathRecipient {
+            public void binderDied() {
+                synchronized (mLock) {
+                    onExternalVibrationStop(mCurrentExternalVibration);
+                }
+            }
+        }
     }
 
     private final class VibratorShellCommand extends ShellCommand {
@@ -1586,8 +1644,9 @@
 
                 VibrationEffect effect =
                         VibrationEffect.createOneShot(duration, VibrationEffect.DEFAULT_AMPLITUDE);
-                vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
-                        "Shell Command", mToken);
+                AudioAttributes attrs = createAudioAttributes(commonOptions);
+                vibrate(Binder.getCallingUid(), description, effect, attrs, "Shell Command",
+                        mToken);
                 return 0;
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
@@ -1646,8 +1705,9 @@
                             amplitudesList.stream().mapToInt(Integer::intValue).toArray();
                     effect = VibrationEffect.createWaveform(timings, amplitudes, repeat);
                 }
-                vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
-                        "Shell Command", mToken);
+                AudioAttributes attrs = createAudioAttributes(commonOptions);
+                vibrate(Binder.getCallingUid(), description, effect, attrs, "Shell Command",
+                        mToken);
                 return 0;
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
@@ -1677,14 +1737,25 @@
 
                 VibrationEffect effect =
                         VibrationEffect.get(id, false);
-                vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
-                        "Shell Command", mToken);
+                AudioAttributes attrs = createAudioAttributes(commonOptions);
+                vibrate(Binder.getCallingUid(), description, effect, attrs, "Shell Command",
+                        mToken);
                 return 0;
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
             }
         }
 
+        private AudioAttributes createAudioAttributes(CommonOptions commonOptions) {
+            final int flags = commonOptions.force
+                    ? AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY
+                    : 0;
+            return new AudioAttributes.Builder()
+                    .setUsage(AudioAttributes.USAGE_UNKNOWN)
+                    .setFlags(flags)
+                    .build();
+        }
+
         @Override
         public void onHelp() {
             try (PrintWriter pw = getOutPrintWriter();) {
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index e097d85..a502ff2 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -63,7 +63,7 @@
     static final String TAG = "Watchdog";
 
     /** Debug flag. */
-    public static final boolean DEBUG = true; // STOPSHIP disable it (b/113252928)
+    public static final boolean DEBUG = false;
 
     // Set this to true to use debug default values.
     static final boolean DB = false;
@@ -103,6 +103,8 @@
     public static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList(
             "android.hardware.audio@2.0::IDevicesFactory",
             "android.hardware.audio@4.0::IDevicesFactory",
+            "android.hardware.audio@5.0::IDevicesFactory",
+            "android.hardware.biometrics.face@1.0::IBiometricsFace",
             "android.hardware.bluetooth@1.0::IBluetoothHci",
             "android.hardware.camera.provider@2.4::ICameraProvider",
             "android.hardware.graphics.allocator@2.0::IAllocator",
@@ -111,9 +113,10 @@
             "android.hardware.media.c2@1.0::IComponentStore",
             "android.hardware.media.omx@1.0::IOmx",
             "android.hardware.media.omx@1.0::IOmxStore",
+            "android.hardware.power.stats@1.0::IPowerStats",
             "android.hardware.sensors@1.0::ISensors",
             "android.hardware.vr@1.0::IVr",
-            "android.hardware.biometrics.face@1.0::IBiometricsFace"
+            "android.system.suspend@1.0::ISystemSuspend"
     );
 
     static Watchdog sWatchdog;
@@ -570,7 +573,7 @@
                         continue;
                     } else if (waitState == WAITED_HALF) {
                         if (!waitedHalf) {
-                            if (DEBUG) Slog.d(TAG, "WAITED_HALF");
+                            Slog.i(TAG, "WAITED_HALF");
                             // We've waited half the deadlock-detection interval.  Pull a stack
                             // trace and wait another half.
                             ArrayList<Integer> pids = new ArrayList<Integer>();
diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java
index 9bbc315..8e5c73bf 100644
--- a/services/core/java/com/android/server/WiredAccessoryManager.java
+++ b/services/core/java/com/android/server/WiredAccessoryManager.java
@@ -16,33 +16,33 @@
 
 package com.android.server;
 
+import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT;
+import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT_BIT;
+import static com.android.server.input.InputManagerService.SW_LINEOUT_INSERT;
+import static com.android.server.input.InputManagerService.SW_LINEOUT_INSERT_BIT;
+import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT;
+import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT_BIT;
+
 import android.content.Context;
+import android.media.AudioManager;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.UEventObserver;
+import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
-import android.media.AudioManager;
-import android.util.Log;
 import android.view.InputDevice;
 
 import com.android.internal.R;
 import com.android.server.input.InputManagerService;
 import com.android.server.input.InputManagerService.WiredAccessoryCallbacks;
 
-import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT;
-import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT;
-import static com.android.server.input.InputManagerService.SW_LINEOUT_INSERT;
-import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT_BIT;
-import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT_BIT;
-import static com.android.server.input.InputManagerService.SW_LINEOUT_INSERT_BIT;
-
 import java.io.File;
-import java.io.FileReader;
 import java.io.FileNotFoundException;
+import java.io.FileReader;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
@@ -538,7 +538,7 @@
             synchronized (mLock) {
                 int mask = maskAndState.first;
                 int state = maskAndState.second;
-                updateLocked(name, mHeadsetState | (mask & state) & ~(mask & ~state));
+                updateLocked(name, mHeadsetState & ~(mask & ~state) | (mask & state));
                 return;
             }
         }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 1432f57..4f54e64 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1440,6 +1440,11 @@
 
     @Override
     public void onServiceChanged(AuthenticatorDescription desc, int userId, boolean removed) {
+        UserInfo user = getUserManager().getUserInfo(userId);
+        if (user == null) {
+            Log.w(TAG, "onServiceChanged: ignore removed user " + userId);
+            return;
+        }
         validateAccountsInternal(getUserAccounts(userId), false /* invalidateAuthenticatorCache */);
     }
 
@@ -5310,7 +5315,8 @@
         long identityToken = clearCallingIdentity();
         try {
             INotificationManager service = mInjector.getNotificationManager();
-            service.cancelNotificationWithTag(packageName, id.mTag, id.mId, user.getIdentifier());
+            service.cancelNotificationWithTag(
+                    packageName, "android", id.mTag, id.mId, user.getIdentifier());
         } catch (RemoteException e) {
             /* ignore - local call */
         } finally {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index fae853c..7bc2e6d 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1946,8 +1946,6 @@
                                 r.binding.service.app.hasClientActivities()
                                 || r.binding.service.app.treatLikeActivity, null);
                     }
-                    mAm.updateOomAdjLocked(r.binding.service.app, false,
-                            OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                 }
             }
 
@@ -2906,15 +2904,15 @@
 
         // Tell the service that it has been unbound.
         if (r.app != null && r.app.thread != null) {
-            for (int i=r.bindings.size()-1; i>=0; i--) {
+            boolean needOomAdj = false;
+            for (int i = r.bindings.size() - 1; i >= 0; i--) {
                 IntentBindRecord ibr = r.bindings.valueAt(i);
                 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding " + ibr
                         + ": hasBound=" + ibr.hasBound);
                 if (ibr.hasBound) {
                     try {
                         bumpServiceExecutingLocked(r, false, "bring down unbind");
-                        mAm.updateOomAdjLocked(r.app, true,
-                                OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
+                        needOomAdj = true;
                         ibr.hasBound = false;
                         ibr.requested = false;
                         r.app.thread.scheduleUnbindService(r,
@@ -2926,6 +2924,10 @@
                     }
                 }
             }
+            if (needOomAdj) {
+                mAm.updateOomAdjLocked(r.app, true,
+                        OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
+            }
         }
 
         // Check to see if the service had been started as foreground, but being
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 104cadc..7fea5fc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -30,8 +30,6 @@
 import android.provider.DeviceConfig.Properties;
 import android.provider.Settings;
 import android.text.TextUtils;
-import android.text.TextUtils.SimpleStringSplitter;
-import android.util.ArraySet;
 import android.util.KeyValueListParser;
 import android.util.Slog;
 
@@ -125,13 +123,6 @@
     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;
@@ -263,8 +254,6 @@
     // If not set explicitly the default is controlled by DeviceConfig.
     volatile boolean mFlagBackgroundActivityStartsEnabled;
 
-    volatile ArraySet<String> mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>();
-
     private final ActivityManagerService mService;
     private ContentResolver mResolver;
     private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -309,10 +298,6 @@
     private static final Uri ACTIVITY_STARTS_LOGGING_ENABLED_URI = Settings.Global.getUriFor(
                 Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED);
 
-    private static final Uri BACKGROUND_ACTIVITY_STARTS_ENABLED_URI =
-                Settings.Global.getUriFor(
-                        Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED);
-
     private static final Uri ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI =
             Settings.Global.getUriFor(Settings.Global.ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS);
 
@@ -329,7 +314,6 @@
                                 updateMaxCachedProcesses();
                                 break;
                             case KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED:
-                            case KEY_BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST:
                                 updateBackgroundActivityStarts();
                                 break;
                             default:
@@ -356,7 +340,6 @@
         mResolver = resolver;
         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);
         if (mSystemServerAutomaticHeapDumpEnabled) {
             mResolver.registerContentObserver(ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI,
                     false, this);
@@ -393,8 +376,6 @@
             updateConstants();
         } else if (ACTIVITY_STARTS_LOGGING_ENABLED_URI.equals(uri)) {
             updateActivityStartsLoggingEnabled();
-        } else if (BACKGROUND_ACTIVITY_STARTS_ENABLED_URI.equals(uri)) {
-            updateBackgroundActivityStarts();
         } else if (ENABLE_AUTOMATIC_SYSTEM_SERVER_HEAP_DUMPS_URI.equals(uri)) {
             updateEnableAutomaticSystemServerHeapDumps();
         }
@@ -485,39 +466,10 @@
     }
 
     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*/ false);
-            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;
-        }
+        mFlagBackgroundActivityStartsEnabled = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED,
+                /*defaultValue*/ false);
     }
 
     private void updateEnableAutomaticSystemServerHeapDumps() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index 7ab70fa..ed64475 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -42,7 +42,7 @@
     static final boolean DEBUG_ALL = false;
 
     // Available log categories in the activity manager package.
-    static final boolean DEBUG_ANR = true;  // STOPSHIP disable it (b/113252928)
+    static final boolean DEBUG_ANR = false;
     static final boolean DEBUG_BACKGROUND_CHECK = DEBUG_ALL || false;
     static final boolean DEBUG_BACKUP = DEBUG_ALL || false;
     static final boolean DEBUG_BROADCAST = DEBUG_ALL || false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7e2c59a..ff8c3e9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -120,8 +120,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.MemoryStatUtil.hasMemcg;
-import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
-import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs;
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
@@ -178,7 +176,6 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.app.ProcessMemoryHighWaterMark;
 import android.app.ProcessMemoryState;
 import android.app.ProfilerInfo;
 import android.app.WaitResult;
@@ -213,7 +210,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageManagerInternal.CheckPermissionDelegate;
 import android.content.pm.PackageParser;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.PathPermission;
@@ -273,7 +269,9 @@
 import android.os.WorkSource;
 import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
+import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
 import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
 import android.provider.Settings;
 import android.server.ServerProtoEnums;
 import android.sysprop.VoldProperties;
@@ -292,7 +290,6 @@
 import android.util.SparseIntArray;
 import android.util.StatsLog;
 import android.util.TimeUtils;
-import android.util.TimingsTraceLog;
 import android.util.proto.ProtoOutputStream;
 import android.util.proto.ProtoUtils;
 import android.view.Display;
@@ -349,17 +346,20 @@
 import com.android.server.ThreadPriorityBooster;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
-import com.android.server.am.MemoryStatUtil.MemoryStat;
 import com.android.server.appop.AppOpsService;
+import com.android.server.compat.CompatConfig;
 import com.android.server.contentcapture.ContentCaptureManagerInternal;
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.job.JobSchedulerInternal;
 import com.android.server.pm.Installer;
 import com.android.server.pm.Installer.InstallerException;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.uri.GrantUri;
 import com.android.server.uri.UriGrantsManagerInternal;
 import com.android.server.utils.PriorityDump;
+import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.vr.VrManagerInternal;
+import com.android.server.wm.ActivityMetricsLaunchObserver;
 import com.android.server.wm.ActivityServiceConnectionsHolder;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.ActivityTaskManagerService;
@@ -393,9 +393,12 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.BiFunction;
 
@@ -547,6 +550,7 @@
     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
 
     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
+    private static final int JAVA_DUMP_MINIMUM_SIZE = 100; // 100 bytes.
 
     OomAdjuster mOomAdjuster;
     final LowMemDetector mLowMemDetector;
@@ -864,6 +868,51 @@
      */
     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
 
+    /**
+     * Depth of overlapping activity-start PSS deferral notes
+     */
+    private final AtomicInteger mActivityStartingNesting = new AtomicInteger(0);
+
+    private final ActivityMetricsLaunchObserver mActivityLaunchObserver =
+            new ActivityMetricsLaunchObserver() {
+        @Override
+        public void onActivityLaunched(byte[] activity, int temperature) {
+            // This is safe to force to the head of the queue because it relies only
+            // on refcounting to track begin/end of deferrals, not on actual
+            // message ordering.  We don't care *what* activity is being
+            // launched; only that we're doing so.
+            if (mPssDeferralTime > 0) {
+                final Message msg = mBgHandler.obtainMessage(DEFER_PSS_MSG);
+                mBgHandler.sendMessageAtFrontOfQueue(msg);
+            }
+        }
+
+        // The other observer methods are unused
+        @Override
+        public void onIntentStarted(Intent intent) {
+        }
+
+        @Override
+        public void onIntentFailed() {
+        }
+
+        @Override
+        public void onActivityLaunchCancelled(byte[] abortingActivity) {
+        }
+
+        @Override
+        public void onActivityLaunchFinished(byte[] finalActivity) {
+        }
+    };
+
+    /**
+     * How long we defer PSS gathering while activities are starting, in milliseconds.
+     * This is adjustable via DeviceConfig.  If it is zero or negative, no PSS deferral
+     * is done.
+     */
+    private volatile long mPssDeferralTime = 0;
+    private static final String ACTIVITY_START_PSS_DEFER_CONFIG = "activity_start_pss_defer";
+
     private boolean mBinderTransactionTrackingEnabled = false;
 
     /**
@@ -877,6 +926,20 @@
      */
     boolean mFullPssPending = false;
 
+    /**
+     * Observe DeviceConfig changes to the PSS calculation interval
+     */
+    private final DeviceConfig.OnPropertiesChangedListener mPssDelayConfigListener =
+            new DeviceConfig.OnPropertiesChangedListener() {
+                @Override
+                public void onPropertiesChanged(Properties properties) {
+                    mPssDeferralTime = properties.getLong(ACTIVITY_START_PSS_DEFER_CONFIG, 0);
+                    if (DEBUG_PSS) {
+                        Slog.d(TAG_PSS, "Activity-start PSS delay now "
+                                + mPssDeferralTime + " ms");
+                    }
+                }
+            };
 
     /**
      * This is for verifying the UID report flow.
@@ -1502,6 +1565,7 @@
     final HiddenApiSettings mHiddenApiBlacklist;
 
     PackageManagerInternal mPackageManagerInt;
+    PermissionManagerServiceInternal mPermissionManagerInt;
 
     /**
      * Whether to force background check on all apps (for battery saver) or not.
@@ -1841,6 +1905,8 @@
     }
 
     static final int COLLECT_PSS_BG_MSG = 1;
+    static final int DEFER_PSS_MSG = 2;
+    static final int STOP_DEFERRING_PSS_MSG = 3;
 
     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
         @Override
@@ -1948,6 +2014,30 @@
                     }
                 } while (true);
             }
+
+            case DEFER_PSS_MSG: {
+                deferPssForActivityStart();
+            } break;
+
+            case STOP_DEFERRING_PSS_MSG: {
+                final int nesting = mActivityStartingNesting.decrementAndGet();
+                if (nesting <= 0) {
+                    if (DEBUG_PSS) {
+                        Slog.d(TAG_PSS, "PSS activity start deferral interval ended; now "
+                                + nesting);
+                    }
+                    if (nesting < 0) {
+                        Slog.wtf(TAG, "Activity start nesting undercount!");
+                        mActivityStartingNesting.incrementAndGet();
+                    }
+                } else {
+                    if (DEBUG_PSS) {
+                        Slog.d(TAG_PSS, "Still deferring PSS, nesting=" + nesting);
+                    }
+                }
+            }
+            break;
+
             }
         }
     };
@@ -2805,6 +2895,7 @@
             if (mIsolatedAppBindArgs == null) {
                 mIsolatedAppBindArgs = new ArrayMap<>(1);
                 addServiceToMap(mIsolatedAppBindArgs, "package");
+                addServiceToMap(mIsolatedAppBindArgs, "permissionmgr");
             }
             return mIsolatedAppBindArgs;
         }
@@ -2816,6 +2907,7 @@
             // IMPORTANT: Before adding services here, make sure ephemeral apps can access them too.
             // Enable the check in ApplicationThread.bindApplication() to make sure.
             addServiceToMap(mAppBindArgs, "package");
+            addServiceToMap(mAppBindArgs, "permissionmgr");
             addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE);
             addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE);
             addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE);
@@ -3682,9 +3774,7 @@
             ArrayList<Integer> nativePids) {
         ArrayList<Integer> extraPids = null;
 
-        if (DEBUG_ANR) {
-            Slog.d(TAG, "dumpStackTraces pids=" + lastPids + " nativepids=" + nativePids);
-        }
+        Slog.i(TAG, "dumpStackTraces pids=" + lastPids + " nativepids=" + nativePids);
 
         // Measure CPU usage as soon as we're called in order to get a realistic sampling
         // of the top users at the time of the request.
@@ -3706,8 +3796,8 @@
                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
 
                     extraPids.add(stats.pid);
-                } else if (DEBUG_ANR) {
-                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
+                } else {
+                    Slog.i(TAG, "Skipping next CPU consuming process, not a java proc: "
                             + stats.pid);
                 }
             }
@@ -3725,9 +3815,6 @@
         if (tracesFile == null) {
             return null;
         }
-        if (DEBUG_ANR) {
-            Slog.d(TAG, "Dumping to " + tracesFile.getAbsolutePath());
-        }
 
         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids);
         return tracesFile;
@@ -3790,9 +3877,28 @@
      */
     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
         final long timeStart = SystemClock.elapsedRealtime();
-        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
-            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
-                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
+        boolean javaSuccess = Debug.dumpJavaBacktraceToFileTimeout(pid, fileName,
+                (int) (timeoutMs / 1000));
+        if (javaSuccess) {
+            // Check that something is in the file, actually. Try-catch should not be necessary,
+            // but better safe than sorry.
+            try {
+                long size = new File(fileName).length();
+                if (size < JAVA_DUMP_MINIMUM_SIZE) {
+                    Slog.w(TAG, "Successfully created Java ANR file is empty!");
+                    javaSuccess = false;
+                }
+            } catch (Exception e) {
+                Slog.w(TAG, "Unable to get ANR file size", e);
+                javaSuccess = false;
+            }
+        }
+        if (!javaSuccess) {
+            Slog.w(TAG, "Dumping Java threads failed, initiating native stack dump.");
+            if (!Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
+                    (NATIVE_DUMP_TIMEOUT_MS / 1000))) {
+                Slog.w(TAG, "Native stack dump failed!");
+            }
         }
 
         return SystemClock.elapsedRealtime() - timeStart;
@@ -3801,6 +3907,8 @@
     public static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids) {
 
+        Slog.i(TAG, "Dumping to " + tracesFile);
+
         // We don't need any sort of inotify based monitoring when we're dumping traces via
         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
         // control of all writes to the file in question.
@@ -3812,7 +3920,7 @@
         if (firstPids != null) {
             int num = firstPids.size();
             for (int i = 0; i < num; i++) {
-                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid " + firstPids.get(i));
+                Slog.i(TAG, "Collecting stacks for pid " + firstPids.get(i));
                 final long timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile,
                                                                 remainingTime);
 
@@ -3832,7 +3940,7 @@
         // Next collect the stacks of the native pids
         if (nativePids != null) {
             for (int pid : nativePids) {
-                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
+                Slog.i(TAG, "Collecting stacks for native pid " + pid);
                 final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
 
                 final long start = SystemClock.elapsedRealtime();
@@ -3856,7 +3964,7 @@
         // Lastly, dump stacks for all extra PIDs from the CPU tracker.
         if (extraPids != null) {
             for (int pid : extraPids) {
-                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
+                Slog.i(TAG, "Collecting stacks for extra pid " + pid);
 
                 final long timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
 
@@ -3872,6 +3980,7 @@
                 }
             }
         }
+        Slog.i(TAG, "Done dumping");
     }
 
     @Override
@@ -4735,7 +4844,7 @@
         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
 
         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
-        app.setCurrentSchedulingGroup(app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT);
+        mOomAdjuster.setAttachingSchedGroupLocked(app);
         app.forcingToImportant = null;
         updateProcessForegroundLocked(app, false, 0, false);
         app.hasShownUi = false;
@@ -4921,6 +5030,7 @@
             bindApplicationTimeMillis = SystemClock.elapsedRealtime();
             mAtmInternal.preBindApplication(app.getWindowProcessController());
             final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
+            long[] disabledCompatChanges = CompatConfig.get().getDisabledChanges(app.info);
             if (app.isolatedEntryPoint != null) {
                 // This is an isolated process which should just call an entry point instead of
                 // being bound to an application.
@@ -4936,7 +5046,8 @@
                         new Configuration(app.getWindowProcessController().getConfiguration()),
                         app.compat, getCommonServicesLocked(app.isolated),
                         mCoreSettingsObserver.getCoreSettingsLocked(),
-                        buildSerial, autofillOptions, contentCaptureOptions);
+                        buildSerial, autofillOptions, contentCaptureOptions,
+                        disabledCompatChanges);
             } else {
                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                         null, null, null, testMode,
@@ -4945,7 +5056,8 @@
                         new Configuration(app.getWindowProcessController().getConfiguration()),
                         app.compat, getCommonServicesLocked(app.isolated),
                         mCoreSettingsObserver.getCoreSettingsLocked(),
-                        buildSerial, autofillOptions, contentCaptureOptions);
+                        buildSerial, autofillOptions, contentCaptureOptions,
+                        disabledCompatChanges);
             }
             if (profilerInfo != null) {
                 profilerInfo.closeFd();
@@ -5074,7 +5186,9 @@
     }
 
     final void finishBooting() {
-        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
+        TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
+                Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        t.traceBegin("FinishBooting");
 
         synchronized (this) {
             if (!mBootAnimationComplete) {
@@ -5147,7 +5261,7 @@
         }
 
         // Let system services know.
-        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_BOOT_COMPLETED);
 
         synchronized (this) {
             // Ensure that any processes we had put on hold are now started
@@ -5191,7 +5305,7 @@
             mUserController.scheduleStartProfiles();
         }
 
-        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        t.traceEnd();
     }
 
     @Override
@@ -5360,34 +5474,13 @@
 
     @Override
     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
-        if (!(sender instanceof PendingIntentRecord)) {
-            return;
-        }
-        boolean isCancelled;
-        synchronized(this) {
-            PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
-            isCancelled = pendingIntent.canceled;
-            if (!isCancelled) {
-                pendingIntent.registerCancelListenerLocked(receiver);
-            }
-        }
-        if (isCancelled) {
-            try {
-                receiver.send(Activity.RESULT_CANCELED, null);
-            } catch (RemoteException e) {
-            }
-        }
+        mPendingIntentController.registerIntentSenderCancelListener(sender, receiver);
     }
 
     @Override
     public void unregisterIntentSenderCancelListener(IIntentSender sender,
             IResultReceiver receiver) {
-        if (!(sender instanceof PendingIntentRecord)) {
-            return;
-        }
-        synchronized(this) {
-            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
-        }
+        mPendingIntentController.unregisterIntentSenderCancelListener(sender, receiver);
     }
 
     @Override
@@ -7122,6 +7215,14 @@
         return mPackageManagerInt;
     }
 
+    private PermissionManagerServiceInternal getPermissionManagerInternalLocked() {
+        if (mPermissionManagerInt == null) {
+            mPermissionManagerInt =
+                    LocalServices.getService(PermissionManagerServiceInternal.class);
+        }
+        return mPermissionManagerInt;
+    }
+
     @Override
     public final ContentProviderHolder getContentProvider(
             IApplicationThread caller, String callingPackage, String name, int userId,
@@ -7285,6 +7386,13 @@
                     if (wasInLaunchingProviders) {
                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
                     }
+                    // Make sure the package is associated with the process.
+                    // XXX We shouldn't need to do this, since we have added the package
+                    // when we generated the providers in generateApplicationProvidersLocked().
+                    // But for some reason in some cases we get here with the package no longer
+                    // added...  for now just patch it in to make things happy.
+                    r.addPackage(dst.info.applicationInfo.packageName,
+                            dst.info.applicationInfo.longVersionCode, mProcessStats);
                     synchronized (dst) {
                         dst.provider = src.provider;
                         dst.setProcess(r);
@@ -7561,7 +7669,25 @@
             holder = getContentProviderExternalUnchecked(name, null, callingUid,
                     "*getmimetype*", userId);
             if (holder != null) {
-                return holder.provider.getType(uri);
+                final IBinder providerConnection = holder.connection;
+                final ComponentName providerName = holder.info.getComponentName();
+                // Note: creating a new Runnable instead of using a lambda here since lambdas in
+                // java provide no guarantee that there will be a new instance returned every call.
+                // Hence, it's possible that a cached copy is returned and the ANR is executed on
+                // the incorrect provider.
+                final Runnable providerNotResponding = new Runnable() {
+                    @Override
+                    public void run() {
+                        Log.w(TAG, "Provider " + providerName + " didn't return from getType().");
+                        appNotRespondingViaProvider(providerConnection);
+                    }
+                };
+                mHandler.postDelayed(providerNotResponding, 1000);
+                try {
+                    return holder.provider.getType(uri);
+                } finally {
+                    mHandler.removeCallbacks(providerNotResponding);
+                }
             }
         } catch (RemoteException e) {
             Log.w(TAG, "Content provider dead retrieving " + uri, e);
@@ -7586,6 +7712,34 @@
         return null;
     }
 
+    int checkContentProviderUriPermission(Uri uri, int userId, int callingUid, int modeFlags) {
+        final String name = uri.getAuthority();
+        final long ident = Binder.clearCallingIdentity();
+        ContentProviderHolder holder = null;
+        try {
+            holder = getContentProviderExternalUnchecked(name, null, callingUid,
+                    "*checkContentProviderUriPermission*", userId);
+            if (holder != null) {
+                return holder.provider.checkUriPermission(null, uri, callingUid, modeFlags);
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Content provider dead retrieving " + uri, e);
+            return PackageManager.PERMISSION_DENIED;
+        } catch (Exception e) {
+            Log.w(TAG, "Exception while determining type of " + uri, e);
+            return PackageManager.PERMISSION_DENIED;
+        } finally {
+            try {
+                if (holder != null) {
+                    removeContentProviderExternalUnchecked(name, null, userId);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+        return PackageManager.PERMISSION_DENIED;
+    }
+
     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
         if (UserHandle.getUserId(callingUid) == userId) {
             return true;
@@ -8828,6 +8982,12 @@
                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
         mHiddenApiBlacklist.registerObserver();
 
+        final long pssDeferralMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                ACTIVITY_START_PSS_DEFER_CONFIG, 0L);
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                ActivityThread.currentApplication().getMainExecutor(),
+                mPssDelayConfigListener);
+
         synchronized (this) {
             mDebugApp = mOrigDebugApp = debugApp;
             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
@@ -8844,11 +9004,15 @@
                     com.android.internal.R.bool.config_multiuserDelayUserDataLocking);
 
             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
+            mPssDeferralTime = pssDeferralMs;
         }
     }
 
-    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
-        traceLog.traceBegin("PhaseActivityManagerReady");
+    /**
+     * Ready. Set. Go!
+     */
+    public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
+        t.traceBegin("PhaseActivityManagerReady");
         synchronized(this) {
             if (mSystemReady) {
                 // If we're done calling all the receivers, run the next "boot phase" passed in
@@ -8856,9 +9020,11 @@
                 if (goingCallback != null) {
                     goingCallback.run();
                 }
+                t.traceEnd(); // PhaseActivityManagerReady
                 return;
             }
 
+            t.traceBegin("controllersReady");
             mLocalDeviceIdleController
                     = LocalServices.getService(DeviceIdleController.LocalService.class);
             mActivityTaskManager.onSystemReady();
@@ -8866,6 +9032,7 @@
             mUserController.onSystemReady();
             mAppOpsService.systemReady();
             mSystemReady = true;
+            t.traceEnd();
         }
 
         try {
@@ -8874,6 +9041,7 @@
                     .getSerial();
         } catch (RemoteException e) {}
 
+        t.traceBegin("killProcesses");
         ArrayList<ProcessRecord> procsToKill = null;
         synchronized(mPidsSelfLocked) {
             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
@@ -8901,17 +9069,32 @@
             // we won't trample on them any more.
             mProcessesReady = true;
         }
+        t.traceEnd(); // KillProcesses
 
         Slog.i(TAG, "System now ready");
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis());
 
+        t.traceBegin("updateTopComponentForFactoryTest");
         mAtmInternal.updateTopComponentForFactoryTest();
+        t.traceEnd();
 
+        t.traceBegin("registerActivityLaunchObserver");
+        mAtmInternal.getLaunchObserverRegistry().registerLaunchObserver(mActivityLaunchObserver);
+        t.traceEnd();
+
+        t.traceBegin("watchDeviceProvisioning");
         watchDeviceProvisioning(mContext);
+        t.traceEnd();
 
+        t.traceBegin("retrieveSettings");
         retrieveSettings();
-        mUgmInternal.onSystemReady();
+        t.traceEnd();
 
+        t.traceBegin("Ugm.onSystemReady");
+        mUgmInternal.onSystemReady();
+        t.traceEnd();
+
+        t.traceBegin("updateForceBackgroundCheck");
         final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
         if (pmi != null) {
             pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
@@ -8921,8 +9104,11 @@
         } else {
             Slog.wtf(TAG, "PowerManagerInternal not found.");
         }
+        t.traceEnd();
 
         if (goingCallback != null) goingCallback.run();
+
+        t.traceBegin("getCurrentUser"); // should be fast, but these methods acquire locks
         // Check the current user here as a user can be started inside goingCallback.run() from
         // other system services.
         final int currentUserId = mUserController.getCurrentUserId();
@@ -8933,17 +9119,21 @@
             throw new RuntimeException("System user not started while current user is:"
                     + currentUserId);
         }
-        traceLog.traceBegin("ActivityManagerStartApps");
+        t.traceEnd();
+
+        t.traceBegin("ActivityManagerStartApps");
         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
                 Integer.toString(currentUserId), currentUserId);
         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
                 Integer.toString(currentUserId), currentUserId);
-        mSystemServiceManager.startUser(currentUserId);
+        mSystemServiceManager.startUser(t, currentUserId);
 
         synchronized (this) {
             // Only start up encryption-aware persistent apps; once user is
             // unlocked we'll come back around and start unaware apps
+            t.traceBegin("startPersistentApps");
             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
+            t.traceEnd();
 
             // Start up initial activity.
             mBooting = true;
@@ -8953,6 +9143,7 @@
             if (UserManager.isSplitSystemUser() &&
                     Settings.Secure.getInt(mContext.getContentResolver(),
                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
+                t.traceBegin("enableHomeActivity");
                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
                 try {
                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
@@ -8961,66 +9152,84 @@
                 } catch (RemoteException e) {
                     throw e.rethrowAsRuntimeException();
                 }
+                t.traceEnd();
             }
+            t.traceBegin("startHomeOnAllDisplays");
             mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
+            t.traceEnd();
 
+            t.traceBegin("showSystemReadyErrorDialogs");
             mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
+            t.traceEnd();
 
-            final int callingUid = Binder.getCallingUid();
-            final int callingPid = Binder.getCallingPid();
-            long ident = Binder.clearCallingIdentity();
-            try {
-                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                        | Intent.FLAG_RECEIVER_FOREGROUND);
-                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
-                broadcastIntentLocked(null, null, intent,
-                        null, null, 0, null, null, null, OP_NONE,
-                        null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
-                        currentUserId);
-                intent = new Intent(Intent.ACTION_USER_STARTING);
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
-                broadcastIntentLocked(null, null, intent,
-                        null, new IIntentReceiver.Stub() {
-                            @Override
-                            public void performReceive(Intent intent, int resultCode, String data,
-                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
-                                    throws RemoteException {
-                            }
-                        }, 0, null, null,
-                        new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
-                        null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
-                        UserHandle.USER_ALL);
-            } catch (Throwable t) {
-                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
+            boolean isSystemUser = currentUserId == UserHandle.USER_SYSTEM;
+            if (isSystemUser) {
+                t.traceBegin("sendUserStartBroadcast");
+                final int callingUid = Binder.getCallingUid();
+                final int callingPid = Binder.getCallingPid();
+                long ident = Binder.clearCallingIdentity();
+                try {
+                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
+                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                            | Intent.FLAG_RECEIVER_FOREGROUND);
+                    intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
+                    broadcastIntentLocked(null, null, intent,
+                            null, null, 0, null, null, null, OP_NONE,
+                            null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
+                            currentUserId);
+                    intent = new Intent(Intent.ACTION_USER_STARTING);
+                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
+                    broadcastIntentLocked(null, null, intent, null,
+                            new IIntentReceiver.Stub() {
+                                @Override
+                                public void performReceive(Intent intent, int resultCode,
+                                        String data, Bundle extras, boolean ordered, boolean sticky,
+                                        int sendingUser) {}
+                            }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, OP_NONE, null,
+                            true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
+                            UserHandle.USER_ALL);
+                } catch (Throwable e) {
+                    Slog.wtf(TAG, "Failed sending first user broadcasts", e);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+                t.traceEnd();
+            } else {
+                Slog.i(TAG, "Not sending multi-user broadcasts for non-system user "
+                        + currentUserId);
             }
-            mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
-            mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
 
+            t.traceBegin("resumeTopActivities");
+            mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
+            t.traceEnd();
+
+            if (isSystemUser) {
+                t.traceBegin("sendUserSwitchBroadcasts");
+                mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
+                t.traceEnd();
+            }
+
+            t.traceBegin("setBinderProxies");
             BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK,
                     BINDER_PROXY_LOW_WATERMARK);
             BinderInternal.nSetBinderProxyCountEnabled(true);
             BinderInternal.setBinderProxyCountCallback(
-                    new BinderInternal.BinderProxyLimitListener() {
-                        @Override
-                        public void onLimitReached(int uid) {
-                            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
-                                    + Process.myUid());
-                            BinderProxy.dumpProxyDebugInfo();
-                            if (uid == Process.SYSTEM_UID) {
-                                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
-                            } else {
-                                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
-                                        "Too many Binders sent to SYSTEM");
-                            }
+                    (uid) -> {
+                        Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
+                                + Process.myUid());
+                        BinderProxy.dumpProxyDebugInfo();
+                        if (uid == Process.SYSTEM_UID) {
+                            Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
+                        } else {
+                            killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
+                                    "Too many Binders sent to SYSTEM");
                         }
                     }, mHandler);
+            t.traceEnd(); // setBinderProxies
 
-            traceLog.traceEnd(); // ActivityManagerStartApps
-            traceLog.traceEnd(); // PhaseActivityManagerReady
+            t.traceEnd(); // ActivityManagerStartApps
+            t.traceEnd(); // PhaseActivityManagerReady
         }
     }
 
@@ -15772,7 +15981,7 @@
             // Can't call out of the system process with a lock held, so post a message.
             if (instr.mUiAutomationConnection != null) {
                 mAppOpsService.setAppOpsServiceDelegate(null);
-                getPackageManagerInternalLocked().setCheckPermissionDelegate(null);
+                getPermissionManagerInternalLocked().setCheckPermissionDelegate(null);
                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
                         instr.mUiAutomationConnection).sendToTarget();
             }
@@ -16129,7 +16338,13 @@
             return false;
         }
         if (mPendingPssProcesses.size() == 0) {
-            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
+            final long deferral = (mPssDeferralTime > 0 && mActivityStartingNesting.get() > 0)
+                    ? mPssDeferralTime : 0;
+            if (DEBUG_PSS && deferral > 0) {
+                Slog.d(TAG_PSS, "requestPssLocked() deferring PSS request by "
+                        + deferral + " ms");
+            }
+            mBgHandler.sendEmptyMessageDelayed(COLLECT_PSS_BG_MSG, deferral);
         }
         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting pss of: " + proc);
         proc.pssProcState = procState;
@@ -16139,6 +16354,30 @@
     }
 
     /**
+     * Re-defer a posted PSS collection pass, if one exists.  Assumes deferral is
+     * currently active policy when called.
+     */
+    private void deferPssIfNeededLocked() {
+        if (mPendingPssProcesses.size() > 0) {
+            mBgHandler.removeMessages(COLLECT_PSS_BG_MSG);
+            mBgHandler.sendEmptyMessageDelayed(COLLECT_PSS_BG_MSG, mPssDeferralTime);
+        }
+    }
+
+    private void deferPssForActivityStart() {
+        synchronized (ActivityManagerService.this) {
+            if (mPssDeferralTime > 0) {
+                if (DEBUG_PSS) {
+                    Slog.d(TAG_PSS, "Deferring PSS collection for activity start");
+                }
+                deferPssIfNeededLocked();
+                mActivityStartingNesting.getAndIncrement();
+                mBgHandler.sendEmptyMessageDelayed(STOP_DEFERRING_PSS_MSG, mPssDeferralTime);
+            }
+        }
+    }
+
+    /**
      * Schedule PSS collection of all processes.
      */
     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
@@ -17621,6 +17860,35 @@
         }
 
         @Override
+        public int checkContentProviderUriPermission(Uri uri, int userId,
+                int callingUid, int modeFlags) {
+            // We can find ourselves needing to check Uri permissions while
+            // already holding the WM lock, which means reaching back here for
+            // the AM lock would cause an inversion. The WM team has requested
+            // that we use the strategy below instead of shifting where Uri
+            // grants are calculated.
+
+            // Since we could also arrive here while holding the AM lock, we
+            // can't always delegate the call through the handler, and we need
+            // to delicately dance between the deadlocks.
+            if (Thread.currentThread().holdsLock(ActivityManagerService.this)) {
+                return ActivityManagerService.this.checkContentProviderUriPermission(uri,
+                        userId, callingUid, modeFlags);
+            } else {
+                final CompletableFuture<Integer> res = new CompletableFuture<>();
+                mHandler.post(() -> {
+                    res.complete(ActivityManagerService.this.checkContentProviderUriPermission(uri,
+                            userId, callingUid, modeFlags));
+                });
+                try {
+                    return res.get();
+                } catch (InterruptedException | ExecutionException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+
+        @Override
         public void onWakefulnessChanged(int wakefulness) {
             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
         }
@@ -17664,13 +17932,8 @@
         @Override
         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
                 long duration) {
-            if (!(target instanceof PendingIntentRecord)) {
-                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
-                return;
-            }
-            synchronized (ActivityManagerService.this) {
-                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
-            }
+            mPendingIntentController.setPendingIntentWhitelistDuration(target, whitelistToken,
+                    duration);
         }
 
         @Override
@@ -17845,43 +18108,14 @@
             synchronized (mPidsSelfLocked) {
                 for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
                     final ProcessRecord r = mPidsSelfLocked.valueAt(i);
-                    final int pid = r.pid;
-                    final int uid = r.uid;
-                    final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
-                    if (memoryStat == null) {
-                        continue;
-                    }
-                    ProcessMemoryState processMemoryState =
-                            new ProcessMemoryState(uid,
-                                    r.processName,
-                                    r.curAdj,
-                                    memoryStat.pgfault,
-                                    memoryStat.pgmajfault,
-                                    memoryStat.rssInBytes,
-                                    memoryStat.cacheInBytes,
-                                    memoryStat.swapInBytes,
-                                    memoryStat.startTimeNanos);
-                    processMemoryStates.add(processMemoryState);
+                    processMemoryStates.add(
+                            new ProcessMemoryState(r.uid, r.pid, r.processName, r.curAdj));
                 }
             }
             return processMemoryStates;
         }
 
         @Override
-        public List<ProcessMemoryHighWaterMark> getMemoryHighWaterMarkForProcesses() {
-            List<ProcessMemoryHighWaterMark> results = new ArrayList<>();
-            synchronized (mPidsSelfLocked) {
-                for (int i = 0, size = mPidsSelfLocked.size(); i < size; i++) {
-                    final ProcessRecord r = mPidsSelfLocked.valueAt(i);
-                    final long rssHighWaterMarkInBytes = readRssHighWaterMarkFromProcfs(r.pid);
-                    results.add(new ProcessMemoryHighWaterMark(r.uid, r.processName,
-                            rssHighWaterMarkInBytes));
-                }
-            }
-            return results;
-        }
-
-        @Override
         public int handleIncomingUser(int callingPid, int callingUid, int userId,
                 boolean allowAll, int allowMode, String name, String callerPackage) {
             return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
@@ -18141,13 +18375,20 @@
             }
         }
 
+        // The arguments here are untyped because the base ActivityManagerInternal class
+        // doesn't have compile-time visiblity into ActivityServiceConnectionHolder or
+        // ConnectionRecord.
         @Override
-        public void disconnectActivityFromServices(Object connectionHolder) {
+        public void disconnectActivityFromServices(Object connectionHolder, Object conns) {
+            // 'connectionHolder' is an untyped ActivityServiceConnectionsHolder
+            // 'conns' is an untyped HashSet<ConnectionRecord>
+            final ActivityServiceConnectionsHolder holder =
+                    (ActivityServiceConnectionsHolder) connectionHolder;
+            final HashSet<ConnectionRecord> toDisconnect = (HashSet<ConnectionRecord>) conns;
             synchronized(ActivityManagerService.this) {
-                final ActivityServiceConnectionsHolder c =
-                        (ActivityServiceConnectionsHolder) connectionHolder;
-                c.forEachConnection(cr -> mServices.removeConnectionLocked(
-                        (ConnectionRecord) cr, null, c));
+                for (ConnectionRecord cr : toDisconnect) {
+                    mServices.removeConnectionLocked(cr, null, holder);
+                }
             }
         }
 
@@ -18179,10 +18420,6 @@
             return mConstants.mFlagActivityStartsLoggingEnabled;
         }
 
-        public boolean isPackageNameWhitelistedForBgActivityStarts(String packageName) {
-            return mConstants.mPackageNamesWhitelistedForBgActivityStarts.contains(packageName);
-        }
-
         public boolean isBackgroundActivityStartsEnabled() {
             return mConstants.mFlagBackgroundActivityStartsEnabled;
         }
@@ -18287,16 +18524,19 @@
         }
 
         @Override
-        public void startProcess(String processName, ApplicationInfo info,
-                boolean knownToBeDead, String hostingType, ComponentName hostingName) {
+        public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
+                boolean isTop, String hostingType, ComponentName hostingName) {
             try {
                 if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
                             + processName);
                 }
                 synchronized (ActivityManagerService.this) {
+                    // If the process is known as top app, set a hint so when the process is
+                    // started, the top priority can be applied immediately to avoid cpu being
+                    // preempted by other processes before attaching the process of top app.
                     startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
-                            new HostingRecord(hostingType, hostingName),
+                            new HostingRecord(hostingType, hostingName, isTop),
                             false /* allowWhileBooting */, false /* isolated */,
                             true /* keepIfLarge */);
                 }
@@ -18726,7 +18966,7 @@
         synchronized (ActivityManagerService.this) {
             // If there is a delegate it should be the same instance for app ops and permissions.
             if (mAppOpsService.getAppOpsServiceDelegate()
-                    != getPackageManagerInternalLocked().getCheckPermissionDelegate()) {
+                    != getPermissionManagerInternalLocked().getCheckPermissionDelegate()) {
                 throw new IllegalStateException("Bad shell delegate state");
             }
 
@@ -18761,7 +19001,7 @@
                 final ShellDelegate shellDelegate = new ShellDelegate(
                         instr.mTargetInfo.packageName, delegateUid, permissions);
                 mAppOpsService.setAppOpsServiceDelegate(shellDelegate);
-                getPackageManagerInternalLocked().setCheckPermissionDelegate(shellDelegate);
+                getPermissionManagerInternalLocked().setCheckPermissionDelegate(shellDelegate);
                 return;
             }
         }
@@ -18775,7 +19015,7 @@
         }
         synchronized (ActivityManagerService.this) {
             mAppOpsService.setAppOpsServiceDelegate(null);
-            getPackageManagerInternalLocked().setCheckPermissionDelegate(null);
+            getPermissionManagerInternalLocked().setCheckPermissionDelegate(null);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index cba9674..33070dc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -29,6 +29,7 @@
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.app.AppGlobals;
+import android.app.BroadcastOptions;
 import android.app.IActivityController;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
@@ -88,6 +89,7 @@
 import com.android.internal.util.HexDump;
 import com.android.internal.util.MemInfoReader;
 import com.android.internal.util.Preconditions;
+import com.android.server.compat.CompatConfig;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -148,6 +150,7 @@
     private int mTaskId;
     private boolean mIsTaskOverlay;
     private boolean mIsLockTask;
+    private BroadcastOptions mBroadcastOptions;
 
     final boolean mDumping;
 
@@ -288,6 +291,8 @@
                     return runNoHomeScreen(pw);
                 case "wait-for-broadcast-idle":
                     return runWaitForBroadcastIdle(pw);
+                case "compat":
+                    return runCompat(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -313,6 +318,7 @@
         mTaskId = INVALID_TASK_ID;
         mIsTaskOverlay = false;
         mIsLockTask = false;
+        mBroadcastOptions = null;
 
         return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
             @Override
@@ -371,6 +377,11 @@
                     mIsTaskOverlay = true;
                 } else if (opt.equals("--lock-task")) {
                     mIsLockTask = true;
+                } else if (opt.equals("--allow-background-activity-starts")) {
+                    if (mBroadcastOptions == null) {
+                        mBroadcastOptions = BroadcastOptions.makeBasic();
+                    }
+                    mBroadcastOptions.setBackgroundActivityStartsAllowed(true);
                 } else {
                     return false;
                 }
@@ -717,8 +728,9 @@
                 : new String[] {mReceiverPermission};
         pw.println("Broadcasting: " + intent);
         pw.flush();
+        Bundle bundle = mBroadcastOptions == null ? null : mBroadcastOptions.toBundle();
         mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
-                android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
+                android.app.AppOpsManager.OP_NONE, bundle, true, false, mUserId);
         receiver.waitForFinish();
         return 0;
     }
@@ -2865,6 +2877,50 @@
         return 0;
     }
 
+    private int runCompat(PrintWriter pw) {
+        final CompatConfig config = CompatConfig.get();
+        String toggleValue = getNextArgRequired();
+        long changeId;
+        String changeIdString = getNextArgRequired();
+        try {
+            changeId = Long.parseLong(changeIdString);
+        } catch (NumberFormatException e) {
+            changeId = config.lookupChangeId(changeIdString);
+        }
+        if (changeId == -1) {
+            pw.println("Unknown or invalid change: '" + changeIdString + "'.");
+        }
+        String packageName = getNextArgRequired();
+        switch(toggleValue) {
+            case "enable":
+                if (!config.addOverride(changeId, packageName, true)) {
+                    pw.println("Warning! Change " + changeId + " is not known yet. Enabling it"
+                            + " could have no effect.");
+                }
+                pw.println("Enabled change " + changeId + " for " + packageName + ".");
+                return 0;
+            case "disable":
+                if (!config.addOverride(changeId, packageName, false)) {
+                    pw.println("Warning! Change " + changeId + " is not known yet. Disabling it"
+                            + " could have no effect.");
+                }
+                pw.println("Disabled change " + changeId + " for " + packageName + ".");
+                return 0;
+            case "reset":
+                if (config.removeOverride(changeId, packageName)) {
+                    pw.println("Reset change " + changeId + " for " + packageName
+                            + " to default value.");
+                } else {
+                    pw.println("No override exists for changeId " + changeId + ".");
+                }
+                return 0;
+            default:
+                pw.println("Invalid toggle value: '" + toggleValue + "'.");
+        }
+        return -1;
+    }
+
+
     private Resources getResources(PrintWriter pw) throws RemoteException {
         // system resources does not contain all the device configuration, construct it manually.
         Configuration config = mInterface.getConfiguration();
@@ -2967,6 +3023,8 @@
             pw.println("      --user <USER_ID> | all | current: Specify which user to send to; if not");
             pw.println("          specified then send to all users.");
             pw.println("      --receiver-permission <PERMISSION>: Require receiver to hold permission.");
+            pw.println("      --allow-background-activity-starts: The receiver may start activities");
+            pw.println("          even if in the background.");
             pw.println("  instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
             pw.println("          [--user <USER_ID> | current] [--no-hidden-api-checks]");
             pw.println("          [--no-isolated-storage]");
@@ -3170,6 +3228,8 @@
             pw.println("      without restarting any processes.");
             pw.println("  write");
             pw.println("      Write all pending state to storage.");
+            pw.println("  compat enable|disable|reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>");
+            pw.println("      Toggles a change either by id or by name for <PACKAGE_NAME>.");
             pw.println();
             Intent.printIntentArgsHelp(pw, "");
         }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 05264af..9239d03 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -108,7 +108,7 @@
                     .replaceWith("?");
     private ByteBuffer mUtf8BufferStat = ByteBuffer.allocateDirect(MAX_LOW_POWER_STATS_SIZE);
     private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE);
-    private static final int MAX_LOW_POWER_STATS_SIZE = 2048;
+    private static final int MAX_LOW_POWER_STATS_SIZE = 4096;
 
     /**
      * Replaces the information in the given rpmStats with up-to-date information.
diff --git a/services/core/java/com/android/server/am/BroadcastDispatcher.java b/services/core/java/com/android/server/am/BroadcastDispatcher.java
index d029482..f8a3d1e 100644
--- a/services/core/java/com/android/server/am/BroadcastDispatcher.java
+++ b/services/core/java/com/android/server/am/BroadcastDispatcher.java
@@ -725,6 +725,14 @@
         final Dumper dumper = new Dumper(pw, queueName, dumpPackage, sdf);
         boolean printed = false;
 
+        dumper.setHeading("Currently in flight");
+        dumper.setLabel("In-Flight Ordered Broadcast");
+        if (mCurrentBroadcast != null) {
+            dumper.dump(mCurrentBroadcast);
+        } else {
+            pw.println("  (null)");
+        }
+
         dumper.setHeading("Active ordered broadcasts");
         dumper.setLabel("Active Ordered Broadcast");
         for (Deferrals d : mAlarmBroadcasts) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 746c250..56208a95 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -30,7 +30,6 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
@@ -44,6 +43,7 @@
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.permission.IPermissionManager;
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.SparseIntArray;
@@ -921,7 +921,7 @@
         if (perms == null) {
             return false;
         }
-        IPackageManager pm = AppGlobals.getPackageManager();
+        IPermissionManager pm = AppGlobals.getPermissionManager();
         for (int i = perms.length-1; i >= 0; i--) {
             try {
                 PermissionInfo pi = pm.getPermissionInfo(perms[i], "android", 0);
diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java
index fe95542..4595084 100644
--- a/services/core/java/com/android/server/am/ConnectionRecord.java
+++ b/services/core/java/com/android/server/am/ConnectionRecord.java
@@ -65,6 +65,8 @@
             Context.BIND_VISIBLE,
             Context.BIND_SHOWING_UI,
             Context.BIND_NOT_VISIBLE,
+            Context.BIND_NOT_PERCEPTIBLE,
+            Context.BIND_INCLUDE_CAPABILITIES,
     };
     private static final int[] BIND_PROTO_ENUMS = new int[] {
             ConnectionRecordProto.AUTO_CREATE,
@@ -82,6 +84,8 @@
             ConnectionRecordProto.VISIBLE,
             ConnectionRecordProto.SHOWING_UI,
             ConnectionRecordProto.NOT_VISIBLE,
+            ConnectionRecordProto.NOT_PERCEPTIBLE,
+            ConnectionRecordProto.INCLUDE_CAPABILITIES,
     };
 
     void dump(PrintWriter pw, String prefix) {
@@ -212,6 +216,12 @@
         if ((flags&Context.BIND_NOT_VISIBLE) != 0) {
             sb.append("!VIS ");
         }
+        if ((flags & Context.BIND_NOT_PERCEPTIBLE) != 0) {
+            sb.append("!PRCP ");
+        }
+        if ((flags & Context.BIND_INCLUDE_CAPABILITIES) != 0) {
+            sb.append("CAPS ");
+        }
         if (serviceDead) {
             sb.append("DEAD ");
         }
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index b053d84..aa8bc04 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -76,6 +76,8 @@
         sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYER_APP, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALL_APPS, int.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_IN_APPS, String.class);
+        sGlobalSettingToTypeMap.put(
+                Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_OUT_APPS, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_BLACKLIST, String.class);
         sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_WHITELIST, 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 30a297e..cf0de06 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -54,9 +54,9 @@
 # An activity has been relaunched:
 30020 am_relaunch_activity (User|1|5),(Token|1|5),(Task ID|1|5),(Component Name|3)
 # The activity's onPause has been called.
-30021 am_on_paused_called (User|1|5),(Component Name|3),(Reason|3)
+30021 am_on_paused_called (Token|1|5),(Component Name|3),(Reason|3)
 # The activity's onResume has been called.
-30022 am_on_resume_called (User|1|5),(Component Name|3),(Reason|3)
+30022 am_on_resume_called (Token|1|5),(Component Name|3),(Reason|3)
 # Kill a process to reclaim memory.
 30023 am_kill (User|1|5),(PID|1|5),(Process Name|3),(OomAdj|1|5),(Reason|3)
 # Discard an undelivered serialized broadcast (timeout/ANR/crash)
@@ -104,7 +104,7 @@
 # Attempting to stop an activity
 30048 am_stop_activity (User|1|5),(Token|1|5),(Component Name|3)
 # The activity's onStop has been called.
-30049 am_on_stop_called (User|1|5),(Component Name|3),(Reason|3)
+30049 am_on_stop_called (Token|1|5),(Component Name|3),(Reason|3)
 
 # Report changing memory conditions (Values are ProcessStats.ADJ_MEM_FACTOR* constants)
 30050 am_mem_factor (Current|1|5),(Previous|1|5)
@@ -124,15 +124,15 @@
 30056 am_stop_idle_service (UID|1|5),(Component Name|3)
 
 # The activity's onCreate has been called.
-30057 am_on_create_called (User|1|5),(Component Name|3),(Reason|3)
+30057 am_on_create_called (Token|1|5),(Component Name|3),(Reason|3)
 # The activity's onRestart has been called.
-30058 am_on_restart_called (User|1|5),(Component Name|3),(Reason|3)
+30058 am_on_restart_called (Token|1|5),(Component Name|3),(Reason|3)
 # The activity's onStart has been called.
-30059 am_on_start_called (User|1|5),(Component Name|3),(Reason|3)
+30059 am_on_start_called (Token|1|5),(Component Name|3),(Reason|3)
 # The activity's onDestroy has been called.
-30060 am_on_destroy_called (User|1|5),(Component Name|3),(Reason|3)
+30060 am_on_destroy_called (Token|1|5),(Component Name|3),(Reason|3)
 # The activity's onActivityResult has been called.
-30062 am_on_activity_result_called (User|1|5),(Component Name|3),(Reason|3)
+30062 am_on_activity_result_called (Token|1|5),(Component Name|3),(Reason|3)
 
 # The task is being removed from its parent stack
 30061 am_remove_task (Task ID|1|5), (Stack ID|1|5)
@@ -141,9 +141,12 @@
 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)
 
 # The activity's onTopResumedActivityChanged(true) has been called.
-30064 am_on_top_resumed_gained_called (User|1|5),(Component Name|3),(Reason|3)
+30064 am_on_top_resumed_gained_called (Token|1|5),(Component Name|3),(Reason|3)
 # The activity's onTopResumedActivityChanged(false) has been called.
-30065 am_on_top_resumed_lost_called (User|1|5),(Component Name|3),(Reason|3)
+30065 am_on_top_resumed_lost_called (Token|1|5),(Component Name|3),(Reason|3)
 
 # An activity been add into stopping list
-30066 am_add_to_stopping (User|1|5),(Token|1|5),(Component Name|3),(Reason|3)
\ No newline at end of file
+30066 am_add_to_stopping (User|1|5),(Token|1|5),(Component Name|3),(Reason|3)
+
+# Keyguard status changed
++30067 am_set_keyguard_shown (keyguardShowing|1),(aodShowing|1),(keyguardGoingAway|1),(Reason|3)
\ No newline at end of file
diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
index 784dde1..6bb5def 100644
--- a/services/core/java/com/android/server/am/HostingRecord.java
+++ b/services/core/java/com/android/server/am/HostingRecord.java
@@ -41,6 +41,8 @@
  * {@link android.content.Context#BIND_EXTERNAL_SERVICE} service. In that case, the packageName
  * and uid in the ApplicationInfo will be set to those of the caller, not of the defining package.
  *
+ * {@code mIsTopApp} will be passed to {@link android.os.Process#start}. So Zygote will initialize
+ * the process with high priority.
  */
 
 public final class HostingRecord {
@@ -53,15 +55,22 @@
     private final int mHostingZygote;
     private final String mDefiningPackageName;
     private final int mDefiningUid;
+    private final boolean mIsTopApp;
 
     public HostingRecord(String hostingType) {
-        this(hostingType, null, REGULAR_ZYGOTE, null, -1);
+        this(hostingType, null /* hostingName */, REGULAR_ZYGOTE, null /* definingPackageName */,
+                -1 /* mDefiningUid */, false /* isTopApp */);
     }
 
     public HostingRecord(String hostingType, ComponentName hostingName) {
         this(hostingType, hostingName, REGULAR_ZYGOTE);
     }
 
+    public HostingRecord(String hostingType, ComponentName hostingName, boolean isTopApp) {
+        this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE,
+                null /* definingPackageName */, -1 /* mDefiningUid */, isTopApp /* isTopApp */);
+    }
+
     public HostingRecord(String hostingType, String hostingName) {
         this(hostingType, hostingName, REGULAR_ZYGOTE);
     }
@@ -71,16 +80,18 @@
     }
 
     private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
-        this(hostingType, hostingName, hostingZygote, null, -1);
+        this(hostingType, hostingName, hostingZygote, null /* definingPackageName */,
+                -1 /* mDefiningUid */, false /* isTopApp */);
     }
 
     private HostingRecord(String hostingType, String hostingName, int hostingZygote,
-            String definingPackageName, int definingUid) {
+            String definingPackageName, int definingUid, boolean isTopApp) {
         mHostingType = hostingType;
         mHostingName = hostingName;
         mHostingZygote = hostingZygote;
         mDefiningPackageName = definingPackageName;
         mDefiningUid = definingUid;
+        mIsTopApp = isTopApp;
     }
 
     public String getType() {
@@ -91,6 +102,10 @@
         return mHostingName;
     }
 
+    public boolean isTopApp() {
+        return mIsTopApp;
+    }
+
     /**
      * Returns the UID of the package defining the component we want to start. Only valid
      * when {@link #usesAppZygote()} returns true.
@@ -130,7 +145,7 @@
     public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName,
             int definingUid) {
         return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE,
-                definingPackageName, definingUid);
+                definingPackageName, definingUid, false /* isTopApp */);
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/LmkdConnection.java b/services/core/java/com/android/server/am/LmkdConnection.java
new file mode 100644
index 0000000..d1e09db
--- /dev/null
+++ b/services/core/java/com/android/server/am/LmkdConnection.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
+import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.os.MessageQueue;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import libcore.io.IoUtils;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Lmkd connection to communicate with lowmemorykiller daemon.
+ */
+public class LmkdConnection {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "LmkdConnection" : TAG_AM;
+
+    // lmkd reply max size in bytes
+    private static final int LMKD_REPLY_MAX_SIZE = 8;
+
+    // connection listener interface
+    interface LmkdConnectionListener {
+        public boolean onConnect(OutputStream ostream);
+        public void onDisconnect();
+        /**
+         * Check if received reply was expected (reply to an earlier request)
+         *
+         * @param replyBuf The buffer provided in exchange() to receive the reply.
+         *                 It can be used by exchange() caller to store reply-specific
+         *                 tags for later use in isReplyExpected() to verify if
+         *                 received packet is the expected reply.
+         * @param dataReceived The buffer holding received data
+         * @param receivedLen Size of the data received
+         */
+        public boolean isReplyExpected(ByteBuffer replyBuf, ByteBuffer dataReceived,
+            int receivedLen);
+    }
+
+    private final MessageQueue mMsgQueue;
+
+    // lmkd connection listener
+    private final LmkdConnectionListener mListener;
+
+    // mutex to synchronize access to the socket
+    private final Object mLmkdSocketLock = new Object();
+
+    // socket to communicate with lmkd
+    @GuardedBy("mLmkdSocketLock")
+    private LocalSocket mLmkdSocket = null;
+
+    // socket I/O streams
+    @GuardedBy("mLmkdSocketLock")
+    private OutputStream mLmkdOutputStream = null;
+    @GuardedBy("mLmkdSocketLock")
+    private InputStream mLmkdInputStream = null;
+
+    // buffer to store incoming data
+    private final ByteBuffer mInputBuf =
+            ByteBuffer.allocate(LMKD_REPLY_MAX_SIZE);
+
+    // object to protect mReplyBuf and to wait/notify when reply is received
+    private final Object mReplyBufLock = new Object();
+
+    // reply buffer
+    @GuardedBy("mReplyBufLock")
+    private ByteBuffer mReplyBuf = null;
+
+    ////////////////////  END FIELDS  ////////////////////
+
+    LmkdConnection(MessageQueue msgQueue, LmkdConnectionListener listener) {
+        mMsgQueue = msgQueue;
+        mListener = listener;
+    }
+
+    public boolean connect() {
+        synchronized (mLmkdSocketLock) {
+            if (mLmkdSocket != null) {
+                return true;
+            }
+            // temporary sockets and I/O streams
+            final LocalSocket socket = openSocket();
+
+            if (socket == null) {
+                Slog.w(TAG, "Failed to connect to lowmemorykiller, retry later");
+                return false;
+            }
+
+            final OutputStream ostream;
+            final InputStream istream;
+            try {
+                ostream = socket.getOutputStream();
+                istream = socket.getInputStream();
+            } catch (IOException ex) {
+                IoUtils.closeQuietly(socket);
+                return false;
+            }
+            // execute onConnect callback
+            if (mListener != null && !mListener.onConnect(ostream)) {
+                Slog.w(TAG, "Failed to communicate with lowmemorykiller, retry later");
+                IoUtils.closeQuietly(socket);
+                return false;
+            }
+            // connection established
+            mLmkdSocket = socket;
+            mLmkdOutputStream = ostream;
+            mLmkdInputStream = istream;
+            mMsgQueue.addOnFileDescriptorEventListener(mLmkdSocket.getFileDescriptor(),
+                EVENT_INPUT | EVENT_ERROR,
+                new MessageQueue.OnFileDescriptorEventListener() {
+                    public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                        return fileDescriptorEventHandler(fd, events);
+                    }
+                }
+            );
+            mLmkdSocketLock.notifyAll();
+        }
+        return true;
+    }
+
+    private int fileDescriptorEventHandler(FileDescriptor fd, int events) {
+        if (mListener == null) {
+            return 0;
+        }
+        if ((events & EVENT_INPUT) != 0) {
+            processIncomingData();
+        }
+        if ((events & EVENT_ERROR) != 0) {
+            synchronized (mLmkdSocketLock) {
+                // stop listening on this socket
+                mMsgQueue.removeOnFileDescriptorEventListener(
+                        mLmkdSocket.getFileDescriptor());
+                IoUtils.closeQuietly(mLmkdSocket);
+                mLmkdSocket = null;
+            }
+            // wake up reply waiters if any
+            synchronized (mReplyBufLock) {
+                if (mReplyBuf != null) {
+                    mReplyBuf = null;
+                    mReplyBufLock.notifyAll();
+                }
+            }
+            // notify listener
+            mListener.onDisconnect();
+            return 0;
+        }
+        return (EVENT_INPUT | EVENT_ERROR);
+    }
+
+    private void processIncomingData() {
+        int len = read(mInputBuf);
+        if (len > 0) {
+            synchronized (mReplyBufLock) {
+                if (mReplyBuf != null) {
+                    if (mListener.isReplyExpected(mReplyBuf, mInputBuf, len)) {
+                        // copy into reply buffer
+                        mReplyBuf.put(mInputBuf.array(), 0, len);
+                        mReplyBuf.rewind();
+                        // wakeup the waiting thread
+                        mReplyBufLock.notifyAll();
+                    } else {
+                        // received asynchronous or unexpected packet
+                        // treat this as an error
+                        mReplyBuf = null;
+                        mReplyBufLock.notifyAll();
+                        Slog.e(TAG, "Received unexpected packet from lmkd");
+                    }
+                } else {
+                    // received asynchronous communication from lmkd
+                    // we don't support this yet
+                    Slog.w(TAG, "Received an asynchronous packet from lmkd");
+                }
+            }
+        }
+    }
+
+    public boolean isConnected() {
+        synchronized (mLmkdSocketLock) {
+            return (mLmkdSocket != null);
+        }
+    }
+
+    public boolean waitForConnection(long timeoutMs) {
+        synchronized (mLmkdSocketLock) {
+            if (mLmkdSocket != null) {
+                return true;
+            }
+            try {
+                mLmkdSocketLock.wait(timeoutMs);
+                return (mLmkdSocket != null);
+            } catch (InterruptedException e) {
+                return false;
+            }
+        }
+    }
+
+    private LocalSocket openSocket() {
+        final LocalSocket socket;
+
+        try {
+            socket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
+            socket.connect(
+                new LocalSocketAddress("lmkd",
+                        LocalSocketAddress.Namespace.RESERVED));
+        } catch (IOException ex) {
+            Slog.e(TAG, "Connection failed: " + ex.toString());
+            return null;
+        }
+        return socket;
+    }
+
+    private boolean write(ByteBuffer buf) {
+        synchronized (mLmkdSocketLock) {
+            try {
+                mLmkdOutputStream.write(buf.array(), 0, buf.position());
+            } catch (IOException ex) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private int read(ByteBuffer buf) {
+        synchronized (mLmkdSocketLock) {
+            try {
+                return mLmkdInputStream.read(buf.array(), 0, buf.array().length);
+            } catch (IOException ex) {
+            }
+            return -1;
+        }
+    }
+
+    /**
+     * Exchange a request/reply packets with lmkd
+     *
+     * @param req The buffer holding the request data to be sent
+     * @param repl The buffer to receive the reply
+     */
+    public boolean exchange(ByteBuffer req, ByteBuffer repl) {
+        if (repl == null) {
+            return write(req);
+        }
+
+        boolean result = false;
+        // set reply buffer to user-defined one to fill it
+        synchronized (mReplyBufLock) {
+            mReplyBuf = repl;
+
+            if (write(req)) {
+                try {
+                    // wait for the reply
+                    mReplyBufLock.wait();
+                    result = (mReplyBuf != null);
+                } catch (InterruptedException ie) {
+                    result = false;
+                }
+            }
+
+            // reset reply buffer
+            mReplyBuf = null;
+        }
+        return result;
+    }
+}
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index 78d2634..95eb2c69 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -26,12 +26,17 @@
 import android.system.Os;
 import android.system.OsConstants;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -69,11 +74,15 @@
             Pattern.compile("VmHWM:\\s*(\\d+)\\s*kB");
     private static final Pattern PROCFS_RSS_IN_KILOBYTES =
             Pattern.compile("VmRSS:\\s*(\\d+)\\s*kB");
+    private static final Pattern PROCFS_ANON_RSS_IN_KILOBYTES =
+            Pattern.compile("RssAnon:\\s*(\\d+)\\s*kB");
     private static final Pattern PROCFS_SWAP_IN_KILOBYTES =
             Pattern.compile("VmSwap:\\s*(\\d+)\\s*kB");
 
     private static final Pattern ION_HEAP_SIZE_IN_BYTES =
             Pattern.compile("\n\\s*total\\s*(\\d+)\\s*\n");
+    private static final Pattern PROCESS_ION_HEAP_SIZE_IN_BYTES =
+            Pattern.compile("\n\\s+\\S+\\s+(\\d+)\\s+(\\d+)");
 
     private static final int PGFAULT_INDEX = 9;
     private static final int PGMAJFAULT_INDEX = 11;
@@ -145,6 +154,16 @@
         return parseIonHeapSizeFromDebugfs(readFileContents(DEBUG_SYSTEM_ION_HEAP_FILE));
     }
 
+    /**
+     * Reads process allocation sizes on the system ion heap from debugfs.
+     *
+     * Returns values of allocation sizes in bytes on the system ion heap from
+     * /sys/kernel/debug/ion/heaps/system.
+     */
+    public static List<IonAllocations> readProcessSystemIonHeapSizesFromDebugfs() {
+        return parseProcessIonHeapSizesFromDebugfs(readFileContents(DEBUG_SYSTEM_ION_HEAP_FILE));
+    }
+
     private static String readFileContents(String path) {
         final File file = new File(path);
         if (!file.exists()) {
@@ -204,6 +223,8 @@
             memoryStat.pgmajfault = Long.parseLong(splits[PGMAJFAULT_INDEX]);
             memoryStat.rssInBytes =
                 tryParseLong(PROCFS_RSS_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE;
+            memoryStat.anonRssInBytes =
+                tryParseLong(PROCFS_ANON_RSS_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE;
             memoryStat.swapInBytes =
                 tryParseLong(PROCFS_SWAP_IN_KILOBYTES, procStatusContents) * BYTES_IN_KILOBYTE;
             memoryStat.startTimeNanos = Long.parseLong(splits[START_TIME_INDEX]) * JIFFY_NANOS;
@@ -259,6 +280,43 @@
     }
 
     /**
+     * Parses per-process allocation sizes on the ion heap from the contents of a file under
+     * /sys/kernel/debug/ion/heaps in debugfs.
+     */
+    @VisibleForTesting
+    static List<IonAllocations> parseProcessIonHeapSizesFromDebugfs(String contents) {
+        if (contents == null || contents.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        final Matcher m = PROCESS_ION_HEAP_SIZE_IN_BYTES.matcher(contents);
+        final SparseArray<IonAllocations> entries = new SparseArray<>();
+        while (m.find()) {
+            try {
+                final int pid = Integer.parseInt(m.group(1));
+                final long sizeInBytes = Long.parseLong(m.group(2));
+                IonAllocations allocations = entries.get(pid);
+                if (allocations == null) {
+                    allocations = new IonAllocations();
+                    entries.put(pid, allocations);
+                }
+                allocations.pid = pid;
+                allocations.totalSizeInBytes += sizeInBytes;
+                allocations.count += 1;
+                allocations.maxSizeInBytes = Math.max(allocations.maxSizeInBytes, sizeInBytes);
+            } catch (NumberFormatException e) {
+                Slog.e(TAG, "Failed to parse value", e);
+            }
+        }
+
+        final List<IonAllocations> result = new ArrayList<>(entries.size());
+        for (int i = 0; i < entries.size(); i++) {
+            result.add(entries.valueAt(i));
+        }
+        return result;
+    }
+
+    /**
      * Returns whether per-app memcg is available on device.
      */
     static boolean hasMemcg() {
@@ -284,13 +342,51 @@
         public long pgfault;
         /** Number of major page faults */
         public long pgmajfault;
-        /** Number of bytes of anonymous and swap cache memory */
+        /** For memcg stats, the anon rss + swap cache size. Otherwise total RSS. */
         public long rssInBytes;
-        /** Number of bytes of page cache memory */
+        /** Number of bytes of the anonymous RSS. Only present for non-memcg stats. */
+        public long anonRssInBytes;
+        /** Number of bytes of page cache memory. Only present for memcg stats. */
         public long cacheInBytes;
         /** Number of bytes of swap usage */
         public long swapInBytes;
         /** Device time when the processes started. */
         public long startTimeNanos;
     }
+
+    /** Summary information about process ion allocations. */
+    public static final class IonAllocations {
+        /** PID these allocations belong to. */
+        public int pid;
+        /** Size of all individual allocations added together. */
+        public long totalSizeInBytes;
+        /** Number of allocations. */
+        public int count;
+        /** Size of the largest allocation. */
+        public long maxSizeInBytes;
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            IonAllocations that = (IonAllocations) o;
+            return pid == that.pid && totalSizeInBytes == that.totalSizeInBytes
+                    && count == that.count && maxSizeInBytes == that.maxSizeInBytes;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(pid, totalSizeInBytes, count, maxSizeInBytes);
+        }
+
+        @Override
+        public String toString() {
+            return "IonAllocations{"
+                    + "pid=" + pid
+                    + ", totalSizeInBytes=" + totalSizeInBytes
+                    + ", count=" + count
+                    + ", maxSizeInBytes=" + maxSizeInBytes
+                    + '}';
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/OomAdjProfiler.java b/services/core/java/com/android/server/am/OomAdjProfiler.java
index 9846b31..7e381840 100644
--- a/services/core/java/com/android/server/am/OomAdjProfiler.java
+++ b/services/core/java/com/android/server/am/OomAdjProfiler.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.os.Message;
 import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.SystemClock;
@@ -29,14 +30,20 @@
 import java.io.PrintWriter;
 
 public class OomAdjProfiler {
-    // Disable profiling for Q. Re-enable once b/130635979 is fixed.
-    private static final boolean PROFILING_DISABLED = true;
+    private static final int MSG_UPDATE_CPU_TIME = 42;
 
     @GuardedBy("this")
     private boolean mOnBattery;
     @GuardedBy("this")
     private boolean mScreenOff;
 
+    /** The value of {@link #mOnBattery} when the CPU time update was last scheduled. */
+    @GuardedBy("this")
+    private boolean mLastScheduledOnBattery;
+    /** The value of {@link #mScreenOff} when the CPU time update was last scheduled. */
+    @GuardedBy("this")
+    private boolean mLastScheduledScreenOff;
+
     @GuardedBy("this")
     private long mOomAdjStartTimeMs;
     @GuardedBy("this")
@@ -59,9 +66,6 @@
     final RingBuffer<CpuTimes> mSystemServerCpuTimesHist = new RingBuffer<>(CpuTimes.class, 10);
 
     void batteryPowerChanged(boolean onBattery) {
-        if (PROFILING_DISABLED) {
-            return;
-        }
         synchronized (this) {
             scheduleSystemServerCpuTimeUpdate();
             mOnBattery = onBattery;
@@ -69,9 +73,6 @@
     }
 
     void onWakefulnessChanged(int wakefulness) {
-        if (PROFILING_DISABLED) {
-            return;
-        }
         synchronized (this) {
             scheduleSystemServerCpuTimeUpdate();
             mScreenOff = wakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE;
@@ -79,9 +80,6 @@
     }
 
     void oomAdjStarted() {
-        if (PROFILING_DISABLED) {
-            return;
-        }
         synchronized (this) {
             mOomAdjStartTimeMs = SystemClock.currentThreadTimeMillis();
             mOomAdjStarted = true;
@@ -89,9 +87,6 @@
     }
 
     void oomAdjEnded() {
-        if (PROFILING_DISABLED) {
-            return;
-        }
         synchronized (this) {
             if (!mOomAdjStarted) {
                 return;
@@ -101,31 +96,33 @@
     }
 
     private void scheduleSystemServerCpuTimeUpdate() {
-        if (PROFILING_DISABLED) {
-            return;
-        }
         synchronized (this) {
             if (mSystemServerCpuTimeUpdateScheduled) {
                 return;
             }
+            mLastScheduledOnBattery = mOnBattery;
+            mLastScheduledScreenOff = mScreenOff;
             mSystemServerCpuTimeUpdateScheduled = true;
-            BackgroundThread.getHandler().sendMessage(PooledLambda.obtainMessage(
+            Message scheduledMessage = PooledLambda.obtainMessage(
                     OomAdjProfiler::updateSystemServerCpuTime,
-                    this, mOnBattery, mScreenOff));
+                    this, mLastScheduledOnBattery, mLastScheduledScreenOff, true);
+            scheduledMessage.setWhat(MSG_UPDATE_CPU_TIME);
+
+            BackgroundThread.getHandler().sendMessage(scheduledMessage);
         }
     }
 
-    private void updateSystemServerCpuTime(boolean onBattery, boolean screenOff) {
-        if (PROFILING_DISABLED) {
-            return;
-        }
+    private void updateSystemServerCpuTime(boolean onBattery, boolean screenOff,
+            boolean onlyIfScheduled) {
         final long cpuTimeMs = mProcessCpuTracker.getCpuTimeForPid(Process.myPid());
         synchronized (this) {
+            if (onlyIfScheduled && !mSystemServerCpuTimeUpdateScheduled) {
+                return;
+            }
             mSystemServerCpuTime.addCpuTimeMs(
                     cpuTimeMs - mLastSystemServerCpuTimeMs, onBattery, screenOff);
             mLastSystemServerCpuTimeMs = cpuTimeMs;
             mSystemServerCpuTimeUpdateScheduled = false;
-            notifyAll();
         }
     }
 
@@ -142,20 +139,14 @@
     }
 
     void dump(PrintWriter pw) {
-        if (PROFILING_DISABLED) {
-            return;
-        }
         synchronized (this) {
             if (mSystemServerCpuTimeUpdateScheduled) {
-                while (mSystemServerCpuTimeUpdateScheduled) {
-                    try {
-                        wait();
-                    } catch (InterruptedException e) {
-                        Thread.currentThread().interrupt();
-                    }
-                }
+                // Cancel the scheduled update since we're going to update it here instead.
+                BackgroundThread.getHandler().removeMessages(MSG_UPDATE_CPU_TIME);
+                // Make sure the values are attributed to the right states.
+                updateSystemServerCpuTime(mLastScheduledOnBattery, mLastScheduledScreenOff, false);
             } else {
-                updateSystemServerCpuTime(mOnBattery, mScreenOff);
+                updateSystemServerCpuTime(mOnBattery, mScreenOff, false);
             }
 
             pw.println("System server and oomAdj runtimes (ms) in recent battery sessions "
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 7abfcea..a2613d8 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -177,9 +177,12 @@
         adjusterThread.start();
         Process.setThreadGroupAndCpuset(adjusterThread.getThreadId(), THREAD_GROUP_TOP_APP);
         mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> {
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup");
             final int pid = msg.arg1;
             final int group = msg.arg2;
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup "
+                        + msg.obj + " to " + group);
+            }
             try {
                 setProcessGroup(pid, group);
             } catch (Exception e) {
@@ -431,7 +434,7 @@
             for (int i = 0; i < N; i++) {
                 ProcessRecord app = mProcessList.mLruProcesses.get(i);
                 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
-                    if (computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now,
+                    if (computeOomAdjLocked(app, app.getCurRawAdj(), TOP_APP, true, now,
                             true)) {
                         retryCycles = true;
                     }
@@ -1264,7 +1267,7 @@
                                         cr.trackProcState(procState, mAdjSeq, now);
                                         trackedProcState = true;
                                     }
-                                } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0
+                                } else if ((cr.flags & Context.BIND_NOT_PERCEPTIBLE) != 0
                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
                                         && adj > ProcessList.PERCEPTIBLE_LOW_APP_ADJ) {
                                     newAdj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ;
@@ -1757,7 +1760,7 @@
                         break;
                 }
                 mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage(
-                        0 /* unused */, app.pid, processGroup));
+                        0 /* unused */, app.pid, processGroup, app.processName));
                 try {
                     if (curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
                         // do nothing if we already switched to RT
@@ -1948,6 +1951,38 @@
         return success;
     }
 
+    @GuardedBy("mService")
+    void setAttachingSchedGroupLocked(ProcessRecord app) {
+        int initialSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+        // If the process has been marked as foreground via Zygote.START_FLAG_USE_TOP_APP_PRIORITY,
+        // then verify that the top priority is actually is applied.
+        if (app.hasForegroundActivities()) {
+            String fallbackReason = null;
+            try {
+                // The priority must be the same as how does {@link #applyOomAdjLocked} set for
+                // {@link ProcessList.SCHED_GROUP_TOP_APP}. We don't check render thread because it
+                // is not ready when attaching.
+                if (Process.getProcessGroup(app.pid) == THREAD_GROUP_TOP_APP) {
+                    app.getWindowProcessController().onTopProcChanged();
+                    setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
+                } else {
+                    fallbackReason = "not expected top priority";
+                }
+            } catch (Exception e) {
+                fallbackReason = e.toString();
+            }
+            if (fallbackReason == null) {
+                initialSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
+            } else {
+                // The real scheduling group will depend on if there is any component of the process
+                // did something during attaching.
+                Slog.w(TAG, "Fallback pre-set sched group to default: " + fallbackReason);
+            }
+        }
+
+        app.setCurrentSchedulingGroup(app.setSchedGroup = initialSchedGroup);
+    }
+
     // ONLY used for unit testing in OomAdjusterTests.java
     @VisibleForTesting
     void maybeUpdateUsageStats(ProcessRecord app, long nowElapsed) {
diff --git a/services/core/java/com/android/server/am/PendingIntentController.java b/services/core/java/com/android/server/am/PendingIntentController.java
index a5d4738..d75591c 100644
--- a/services/core/java/com/android/server/am/PendingIntentController.java
+++ b/services/core/java/com/android/server/am/PendingIntentController.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
@@ -39,6 +40,7 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Slog;
+
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
@@ -242,6 +244,47 @@
         }
     }
 
+    void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
+        if (!(sender instanceof PendingIntentRecord)) {
+            return;
+        }
+        boolean isCancelled;
+        synchronized (mLock) {
+            PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
+            isCancelled = pendingIntent.canceled;
+            if (!isCancelled) {
+                pendingIntent.registerCancelListenerLocked(receiver);
+            }
+        }
+        if (isCancelled) {
+            try {
+                receiver.send(Activity.RESULT_CANCELED, null);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    void unregisterIntentSenderCancelListener(IIntentSender sender,
+            IResultReceiver receiver) {
+        if (!(sender instanceof PendingIntentRecord)) {
+            return;
+        }
+        synchronized (mLock) {
+            ((PendingIntentRecord) sender).unregisterCancelListenerLocked(receiver);
+        }
+    }
+
+    void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
+            long duration) {
+        if (!(target instanceof PendingIntentRecord)) {
+            Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
+            return;
+        }
+        synchronized (mLock) {
+            ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+        }
+    }
+
     private void makeIntentSenderCanceled(PendingIntentRecord rec) {
         rec.canceled = true;
         final RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 943fe75..5465309 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -57,17 +57,15 @@
 import android.content.pm.IPackageManager;
 import android.content.res.Resources;
 import android.graphics.Point;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
 import android.os.AppZygote;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.GraphicsEnvironment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.MessageQueue;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.StrictMode;
@@ -118,11 +116,6 @@
 
 /**
  * Activity manager code dealing with processes.
- *
- * Method naming convention:
- * <ul>
- * <li> Methods suffixed with "LS" should be called within the {@link #sLmkdSocketLock} lock.
- * </ul>
  */
 public final class ProcessList {
     static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM;
@@ -185,8 +178,8 @@
     // is not entirely fatal but is generally a bad idea.
     static final int BACKUP_APP_ADJ = 300;
 
-    // This is a process bound by the system that's more important than services but not so
-    // perceptible that it affects the user immediately if killed.
+    // This is a process bound by the system (or other app) that's more important than services but
+    // not so perceptible that it affects the user immediately if killed.
     static final int PERCEPTIBLE_LOW_APP_ADJ = 250;
 
     // This is a process only hosting components that are perceptible to the
@@ -269,6 +262,9 @@
     static final byte LMK_PROCPURGE = 3;
     static final byte LMK_GETKILLCNT = 4;
 
+    // lmkd reconnect delay in msecs
+    private final static long LMDK_RECONNECT_DELAY_MS = 1000;
+
     ActivityManagerService mService = null;
 
     // To kill process groups asynchronously
@@ -280,7 +276,7 @@
     // can't give it a different value for every possible kind of process.
     private final int[] mOomAdj = new int[] {
             FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ,
-            BACKUP_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
+            PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ
     };
     // These are the low-end OOM level limits.  This is appropriate for an
     // HVGA or smaller phone with less than 512MB.  Values are in KB.
@@ -303,16 +299,9 @@
 
     private boolean mHaveDisplaySize;
 
-    private static Object sLmkdSocketLock = new Object();
+    private static LmkdConnection sLmkdConnection = null;
 
-    @GuardedBy("sLmkdSocketLock")
-    private static LocalSocket sLmkdSocket;
-
-    @GuardedBy("sLmkdSocketLock")
-    private static OutputStream sLmkdOutputStream;
-
-    @GuardedBy("sLmkdSocketLock")
-    private static InputStream sLmkdInputStream;
+    private boolean mOomLevelsSet = false;
 
     /**
      * Temporary to avoid allocations.  Protected by main lock.
@@ -537,6 +526,7 @@
 
     final class KillHandler extends Handler {
         static final int KILL_PROCESS_GROUP_MSG = 4000;
+        static final int LMDK_RECONNECT_MSG = 4001;
 
         public KillHandler(Looper looper) {
             super(looper, null, true);
@@ -550,6 +540,15 @@
                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
+                case LMDK_RECONNECT_MSG:
+                    if (!sLmkdConnection.connect()) {
+                        Slog.i(TAG, "Failed to connect to lmkd, retry after " +
+                                LMDK_RECONNECT_DELAY_MS + " ms");
+                        // retry after LMDK_RECONNECT_DELAY_MS
+                        sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
+                                KillHandler.LMDK_RECONNECT_MSG), LMDK_RECONNECT_DELAY_MS);
+                    }
+                    break;
 
                 default:
                     super.handleMessage(msg);
@@ -575,6 +574,30 @@
                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
             sKillThread.start();
             sKillHandler = new KillHandler(sKillThread.getLooper());
+            sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(),
+                    new LmkdConnection.LmkdConnectionListener() {
+                        @Override
+                        public boolean onConnect(OutputStream ostream) {
+                            Slog.i(TAG, "Connection with lmkd established");
+                            return onLmkdConnect(ostream);
+                        }
+                        @Override
+                        public void onDisconnect() {
+                            Slog.w(TAG, "Lost connection to lmkd");
+                            // start reconnection after delay to let lmkd restart
+                            sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
+                                    KillHandler.LMDK_RECONNECT_MSG), LMDK_RECONNECT_DELAY_MS);
+                        }
+                        @Override
+                        public boolean isReplyExpected(ByteBuffer replyBuf,
+                                ByteBuffer dataReceived, int receivedLen) {
+                            // compare the preambule (currently one integer) to check if
+                            // this is the reply packet we are waiting for
+                            return (receivedLen == replyBuf.array().length &&
+                                    dataReceived.getInt(0) == replyBuf.getInt(0));
+                        }
+                    }
+            );
         }
     }
 
@@ -680,6 +703,7 @@
 
             writeLmkd(buf, null);
             SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve));
+            mOomLevelsSet = true;
         }
         // GB: 2048,3072,4096,6144,7168,8192
         // HC: 8192,10240,12288,14336,16384,20480
@@ -705,16 +729,6 @@
         return prefix + "+" + Integer.toString(diff);
     }
 
-    private static boolean shouldUseSystemGraphicsDriver(Context context, Bundle coreSettings,
-            ApplicationInfo applicationInfo) {
-        final boolean shouldUseGameDriver =
-                GraphicsEnvironment.shouldUseGameDriver(context, coreSettings, applicationInfo);
-        final boolean shouldUseAngle =
-                GraphicsEnvironment.shouldUseAngle(context, coreSettings,
-                    applicationInfo.packageName);
-        return !shouldUseGameDriver && !shouldUseAngle;
-    }
-
     public static String makeOomAdjString(int setAdj, boolean compact) {
         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
             return buildOomTag("cch", "cch", "   ", setAdj,
@@ -1229,93 +1243,50 @@
         buf.putInt(LMK_GETKILLCNT);
         buf.putInt(min_oom_adj);
         buf.putInt(max_oom_adj);
-        if (writeLmkd(buf, repl)) {
-            int i = repl.getInt();
-            if (i != LMK_GETKILLCNT) {
-                Slog.e("ActivityManager", "Failed to get kill count, code mismatch");
-                return null;
-            }
+        // indicate what we are waiting for
+        repl.putInt(LMK_GETKILLCNT);
+        repl.rewind();
+        if (writeLmkd(buf, repl) && repl.getInt() == LMK_GETKILLCNT) {
             return new Integer(repl.getInt());
         }
         return null;
     }
 
-    @GuardedBy("sLmkdSocketLock")
-    private static boolean openLmkdSocketLS() {
+    public boolean onLmkdConnect(OutputStream ostream) {
         try {
-            sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET);
-            sLmkdSocket.connect(
-                new LocalSocketAddress("lmkd",
-                        LocalSocketAddress.Namespace.RESERVED));
-            sLmkdOutputStream = sLmkdSocket.getOutputStream();
-            sLmkdInputStream = sLmkdSocket.getInputStream();
-        } catch (IOException ex) {
-            Slog.w(TAG, "lowmemorykiller daemon socket open failed");
-            sLmkdSocket = null;
-            return false;
-        }
-
-        return true;
-    }
-
-    // Never call directly, use writeLmkd() instead
-    @GuardedBy("sLmkdSocketLock")
-    private static boolean writeLmkdCommandLS(ByteBuffer buf) {
-        try {
-            sLmkdOutputStream.write(buf.array(), 0, buf.position());
-        } catch (IOException ex) {
-            Slog.w(TAG, "Error writing to lowmemorykiller socket");
-            IoUtils.closeQuietly(sLmkdSocket);
-            sLmkdSocket = null;
-            return false;
-        }
-        return true;
-    }
-
-    // Never call directly, use writeLmkd() instead
-    @GuardedBy("sLmkdSocketLock")
-    private static boolean readLmkdReplyLS(ByteBuffer buf) {
-        int len;
-        try {
-            len = sLmkdInputStream.read(buf.array(), 0, buf.array().length);
-            if (len == buf.array().length) {
-                return true;
+            // Purge any previously registered pids
+            ByteBuffer buf = ByteBuffer.allocate(4);
+            buf.putInt(LMK_PROCPURGE);
+            ostream.write(buf.array(), 0, buf.position());
+            if (mOomLevelsSet) {
+                // Reset oom_adj levels
+                buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1));
+                buf.putInt(LMK_TARGET);
+                for (int i = 0; i < mOomAdj.length; i++) {
+                    buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
+                    buf.putInt(mOomAdj[i]);
+                }
+                ostream.write(buf.array(), 0, buf.position());
             }
         } catch (IOException ex) {
-            Slog.w(TAG, "Error reading from lowmemorykiller socket");
+            return false;
         }
-
-        IoUtils.closeQuietly(sLmkdSocket);
-        sLmkdSocket = null;
-        return false;
+        return true;
     }
 
     private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) {
-        synchronized (sLmkdSocketLock) {
-            for (int i = 0; i < 3; i++) {
-                if (sLmkdSocket == null) {
-                    if (openLmkdSocketLS() == false) {
-                        try {
-                            Thread.sleep(1000);
-                        } catch (InterruptedException ie) {
-                        }
-                        continue;
-                    }
+        if (!sLmkdConnection.isConnected()) {
+            // try to connect immediately and then keep retrying
+            sKillHandler.sendMessage(
+                sKillHandler.obtainMessage(KillHandler.LMDK_RECONNECT_MSG));
 
-                    // Purge any previously registered pids
-                    ByteBuffer purge_buf = ByteBuffer.allocate(4);
-                    purge_buf.putInt(LMK_PROCPURGE);
-                    if (writeLmkdCommandLS(purge_buf) == false) {
-                        // Write failed, skip the rest and retry
-                        continue;
-                    }
-                }
-                if (writeLmkdCommandLS(buf) && (repl == null || readLmkdReplyLS(repl))) {
-                    return true;
-                }
+            // wait for connection retrying 3 times (up to 3 seconds)
+            if (!sLmkdConnection.waitForConnection(3 * LMDK_RECONNECT_DELAY_MS)) {
+                return false;
             }
         }
-        return false;
+
+        return sLmkdConnection.exchange(buf, repl);
     }
 
     static void killProcessGroup(int uid, int pid) {
@@ -1555,6 +1526,9 @@
             if ("1".equals(SystemProperties.get("debug.assert"))) {
                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
             }
+            if ("1".equals(SystemProperties.get("debug.ignoreappsignalhandler"))) {
+                runtimeFlags |= Zygote.DEBUG_IGNORE_APP_SIGNAL_HANDLER;
+            }
             if (mService.mNativeDebuggingApp != null
                     && mService.mNativeDebuggingApp.equals(app.processName)) {
                 // Enable all debug flags required by the native debugger.
@@ -1668,7 +1642,7 @@
         final long startSeq = app.startSeq = ++mProcStartSeqCounter;
         app.setStartParams(uid, hostingRecord, seInfo, startTime);
         app.setUsingWrapper(invokeWith != null
-                || SystemProperties.get("wrap." + app.processName) != null);
+                || Zygote.getWrapProperty(app.processName) != null);
         mPendingStarts.put(startSeq, app);
 
         if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
@@ -1811,18 +1785,23 @@
             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
             long startTime) {
         try {
-            final boolean useSystemGraphicsDriver = shouldUseSystemGraphicsDriver(mService.mContext,
-                    mService.mCoreSettingsObserver.getCoreSettingsLocked(), app.info);
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                     app.processName);
             checkSlow(startTime, "startProcess: asking zygote to start proc");
+            final boolean isTopApp = hostingRecord.isTopApp();
+            if (isTopApp) {
+                // Use has-foreground-activities as a temporary hint so the current scheduling
+                // group won't be lost when the process is attaching. The actual state will be
+                // refreshed when computing oom-adj.
+                app.setHasForegroundActivities(true);
+            }
+
             final Process.ProcessStartResult startResult;
             if (hostingRecord.usesWebviewZygote()) {
                 startResult = startWebView(entryPoint,
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, null, app.info.packageName,
-                        useSystemGraphicsDriver,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             } else if (hostingRecord.usesAppZygote()) {
                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
@@ -1831,14 +1810,13 @@
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, null, app.info.packageName,
-                        /*useUsapPool=*/ false, useSystemGraphicsDriver,
+                        /*useUsapPool=*/ false, isTopApp,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             } else {
                 startResult = Process.start(entryPoint,
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
-                        app.info.dataDir, invokeWith, app.info.packageName,
-                        useSystemGraphicsDriver,
+                        app.info.dataDir, invokeWith, app.info.packageName, isTopApp,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             }
             checkSlow(startTime, "startProcess: returned from zygote!");
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index dee8e3b..8619ad5 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -911,18 +911,20 @@
         // avoid deadlocks.
         final String localPackageName = packageName;
         final int localForegroundId = foregroundId;
+        final int appUid = appInfo.uid;
+        final int appPid = app != null ? app.pid : 0;
         ams.mHandler.post(new Runnable() {
             public void run() {
-                INotificationManager inm = NotificationManager.getService();
-                if (inm == null) {
+                NotificationManagerInternal nm = LocalServices.getService(
+                        NotificationManagerInternal.class);
+                if (nm == null) {
                     return;
                 }
                 try {
-                    inm.cancelNotificationWithTag(localPackageName, null,
-                            localForegroundId, userId);
+                    nm.cancelNotification(localPackageName, localPackageName, appUid, appPid,
+                            null, localForegroundId, userId);
                 } catch (RuntimeException e) {
                     Slog.w(TAG, "Error canceling notification for service", e);
-                } catch (RemoteException e) {
                 }
             }
         });
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 2399d05..d4ceb5a 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -72,7 +72,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
@@ -85,7 +84,6 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
-import android.util.TimingsTraceLog;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
@@ -100,6 +98,7 @@
 import com.android.server.SystemServiceManager;
 import com.android.server.am.UserState.KeyEvictedCallback;
 import com.android.server.pm.UserManagerService;
+import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerService;
 
@@ -559,7 +558,7 @@
         // Spin up app widgets prior to boot-complete, so they can be ready promptly
         mInjector.startUserWidgets(userId);
 
-        Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
+        Slog.i(TAG, "Posting BOOT_COMPLETED user #" + userId);
         // Do not report secondary users, runtime restarts or first boot/upgrade
         if (userId == UserHandle.USER_SYSTEM
                 && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
@@ -572,18 +571,26 @@
         bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
                 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
                 | Intent.FLAG_RECEIVER_OFFLOAD);
-        mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() {
-                    @Override
-                    public void performReceive(Intent intent, int resultCode, String data,
-                            Bundle extras, boolean ordered, boolean sticky, int sendingUser)
-                            throws RemoteException {
-                        Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
-                        mBootCompleted = true;
-                    }
-                }, 0, null, null,
-                new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
-                AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
-                Binder.getCallingUid(), Binder.getCallingPid(), userId);
+        // Widget broadcasts are outbound via FgThread, so to guarantee sequencing
+        // we also send the boot_completed broadcast from that thread.
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
+        FgThread.getHandler().post(() -> {
+            mInjector.broadcastIntent(bootIntent, null,
+                    new IIntentReceiver.Stub() {
+                        @Override
+                        public void performReceive(Intent intent, int resultCode, String data,
+                                Bundle extras, boolean ordered, boolean sticky, int sendingUser)
+                                        throws RemoteException {
+                            Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u"
+                                    + userId);
+                            mBootCompleted = true;
+                        }
+                    }, 0, null, null,
+                    new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
+                    AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID,
+                    callingUid, callingPid, userId);
+        });
     }
 
     int restartUser(final int userId, final boolean foreground) {
@@ -599,15 +606,7 @@
 
     int stopUser(final int userId, final boolean force, final IStopUserCallback stopUserCallback,
             KeyEvictedCallback keyEvictedCallback) {
-        if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
-                != PackageManager.PERMISSION_GRANTED) {
-            String msg = "Permission Denial: switchUser() from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid()
-                    + " requires " + INTERACT_ACROSS_USERS_FULL;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
+        checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "stopUser");
         if (userId < 0 || userId == UserHandle.USER_SYSTEM) {
             throw new IllegalArgumentException("Can't stop system user " + userId);
         }
@@ -977,11 +976,13 @@
      * <ul>
      *     <li>{@link Intent#ACTION_USER_STARTED} - sent to registered receivers of the new user
      *     <li>{@link Intent#ACTION_USER_BACKGROUND} - sent to registered receivers of the outgoing
-     *     user and all profiles of this user. Sent only if {@code foreground} parameter is true
+     *     user and all profiles of this user. Sent only if {@code foreground} parameter is
+     *     {@code false}
      *     <li>{@link Intent#ACTION_USER_FOREGROUND} - sent to registered receivers of the new
-     *     user and all profiles of this user. Sent only if {@code foreground} parameter is true
+     *     user and all profiles of this user. Sent only if {@code foreground} parameter is
+     *     {@code true}
      *     <li>{@link Intent#ACTION_USER_SWITCHED} - sent to registered receivers of the new user.
-     *     Sent only if {@code foreground} parameter is true
+     *     Sent only if {@code foreground} parameter is {@code true}
      *     <li>{@link Intent#ACTION_USER_STARTING} - ordered broadcast sent to registered receivers
      *     of the new fg user
      *     <li>{@link Intent#ACTION_LOCKED_BOOT_COMPLETED} - ordered broadcast sent to receivers of
@@ -1004,22 +1005,28 @@
             final int userId,
             final boolean foreground,
             @Nullable IProgressListener unlockListener) {
-        if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
-                != PackageManager.PERMISSION_GRANTED) {
-            String msg = "Permission Denial: switchUser() from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid()
-                    + " requires " + INTERACT_ACROSS_USERS_FULL;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
 
+        checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "startUser");
+
+        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
+
+        t.traceBegin("startUser-" + userId + "-" + (foreground ? "fg" : "bg"));
+        try {
+            return startUserInternal(userId, foreground, unlockListener, t);
+        } finally {
+            t.traceEnd();
+        }
+    }
+
+    private boolean startUserInternal(int userId, boolean foreground,
+            @Nullable IProgressListener unlockListener, @NonNull TimingsTraceAndSlog t) {
         Slog.i(TAG, "Starting userid:" + userId + " fg:" + foreground);
 
         final int callingUid = Binder.getCallingUid();
         final int callingPid = Binder.getCallingPid();
         final long ident = Binder.clearCallingIdentity();
         try {
+            t.traceBegin("getStartedUserState");
             final int oldUserId = getCurrentUserId();
             if (oldUserId == userId) {
                 final UserState state = getStartedUserState(userId);
@@ -1036,16 +1043,23 @@
                             // unlocked.
                             notifyFinished(userId, unlockListener);
                         }
+                        t.traceEnd(); //getStartedUserState
                         return true;
                     }
                 }
             }
+            t.traceEnd(); //getStartedUserState
 
             if (foreground) {
+                t.traceBegin("clearAllLockedTasks");
                 mInjector.clearAllLockedTasks("startUser");
+                t.traceEnd();
             }
 
+            t.traceBegin("getUserInfo");
             final UserInfo userInfo = getUserInfo(userId);
+            t.traceEnd();
+
             if (userInfo == null) {
                 Slog.w(TAG, "No user info for user #" + userId);
                 return false;
@@ -1056,8 +1070,10 @@
             }
 
             if (foreground && mUserSwitchUiEnabled) {
+                t.traceBegin("startFreezingScreen");
                 mInjector.getWindowManager().startFreezingScreen(
                         R.anim.screen_user_exit, R.anim.screen_user_enter);
+                t.traceEnd();
             }
 
             boolean needStart = false;
@@ -1066,6 +1082,7 @@
 
             // If the user we are switching to is not currently started, then
             // we need to start it now.
+            t.traceBegin("updateStartedUserArrayStarting");
             synchronized (mLock) {
                 uss = mStartedUsers.get(userId);
                 if (uss == null) {
@@ -1079,6 +1096,7 @@
                     Slog.i(TAG, "User #" + userId
                             + " is shutting down - will start after full stop");
                     mHandler.post(() -> startUser(userId, foreground, unlockListener));
+                    t.traceEnd(); // updateStartedUserArrayStarting
                     return true;
                 }
                 final Integer userIdInt = userId;
@@ -1088,9 +1106,14 @@
             if (unlockListener != null) {
                 uss.mUnlockProgress.addListener(unlockListener);
             }
+            t.traceEnd(); // updateStartedUserArrayStarting
+
             if (updateUmState) {
+                t.traceBegin("setUserState");
                 mInjector.getUserManagerInternal().setUserState(userId, uss.state);
+                t.traceEnd();
             }
+            t.traceBegin("updateConfigurationAndProfileIds");
             if (foreground) {
                 // Make sure the old user is no longer considering the display to be on.
                 mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
@@ -1117,10 +1140,12 @@
                     mUserLru.add(currentUserIdInt);
                 }
             }
+            t.traceEnd();
 
             // Make sure user is in the started state.  If it is currently
             // stopping, we need to knock that off.
             if (uss.state == UserState.STATE_STOPPING) {
+                t.traceBegin("updateStateStopping");
                 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
                 // so we can just fairly silently bring the user back from
                 // the almost-dead.
@@ -1130,7 +1155,9 @@
                     updateStartedUserArrayLU();
                 }
                 needStart = true;
+                t.traceEnd();
             } else if (uss.state == UserState.STATE_SHUTDOWN) {
+                t.traceBegin("updateStateShutdown");
                 // This means ACTION_SHUTDOWN has been sent, so we will
                 // need to treat this as a new boot of the user.
                 uss.setState(UserState.STATE_BOOTING);
@@ -1139,9 +1166,11 @@
                     updateStartedUserArrayLU();
                 }
                 needStart = true;
+                t.traceBegin("updateStateStopping");
             }
 
             if (uss.state == UserState.STATE_BOOTING) {
+                t.traceBegin("updateStateBooting");
                 // Give user manager a chance to propagate user restrictions
                 // to other services and prepare app storage
                 mInjector.getUserManager().onBeforeStartUser(userId);
@@ -1151,8 +1180,10 @@
                 // which is important because it needs to go first.
                 mHandler.sendMessage(
                         mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
+                t.traceEnd();
             }
 
+            t.traceBegin("sendMessages");
             if (foreground) {
                 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
                         oldUserId));
@@ -1174,14 +1205,20 @@
                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
                         null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, userId);
             }
+            t.traceEnd();
 
             if (foreground) {
+                t.traceBegin("moveUserToForeground");
                 moveUserToForeground(uss, oldUserId, userId);
+                t.traceEnd();
             } else {
+                t.traceBegin("finishUserBoot");
                 finishUserBoot(uss);
+                t.traceEnd();
             }
 
             if (needStart) {
+                t.traceBegin("sendRestartBroadcast");
                 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
@@ -1197,6 +1234,7 @@
                         new String[]{INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
                         null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
                         UserHandle.USER_ALL);
+                t.traceEnd();
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
@@ -1220,16 +1258,7 @@
     }
 
     boolean unlockUser(final int userId, byte[] token, byte[] secret, IProgressListener listener) {
-        if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
-                != PackageManager.PERMISSION_GRANTED) {
-            String msg = "Permission Denial: unlockUser() from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid()
-                    + " requires " + INTERACT_ACROSS_USERS_FULL;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
-
+        checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "unlockUser");
         final long binderToken = Binder.clearCallingIdentity();
         try {
             return unlockUserCleared(userId, token, secret, listener);
@@ -1313,6 +1342,7 @@
     }
 
     boolean switchUser(final int targetUserId) {
+        checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "switchUser");
         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
         int currentUserId = getCurrentUserId();
         UserInfo targetUserInfo = getUserInfo(targetUserId);
@@ -1667,15 +1697,7 @@
 
     void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
         Preconditions.checkNotNull(name, "Observer name cannot be null");
-        if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
-                != PackageManager.PERMISSION_GRANTED) {
-            final String msg = "Permission Denial: registerUserSwitchObserver() from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid()
-                    + " requires " + INTERACT_ACROSS_USERS_FULL;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
+        checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "registerUserSwitchObserver");
         mUserSwitchObservers.register(observer, name);
     }
 
@@ -1922,6 +1944,18 @@
         return mInjector.getUserManager().exists(userId);
     }
 
+    private void checkCallingPermission(String permission, String methodName) {
+        if (mInjector.checkCallingPermission(permission)
+                != PackageManager.PERMISSION_GRANTED) {
+            String msg = "Permission denial: " + methodName
+                    + "() from pid=" + Binder.getCallingPid()
+                    + ", uid=" + Binder.getCallingUid()
+                    + " requires " + permission;
+            Slog.w(TAG, msg);
+            throw new SecurityException(msg);
+        }
+    }
+
     private void enforceShellRestriction(String restriction, int userHandle) {
         if (Binder.getCallingUid() == SHELL_UID) {
             if (userHandle < 0 || hasUserRestriction(restriction, userHandle)) {
@@ -2101,6 +2135,7 @@
         }
     }
 
+    @Override
     public boolean handleMessage(Message msg) {
         switch (msg.what) {
             case START_USER_SWITCH_FG_MSG:
@@ -2125,7 +2160,8 @@
                 mInjector.batteryStatsServiceNoteEvent(
                         BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
                         Integer.toString(msg.arg1), msg.arg1);
-                mInjector.getSystemServiceManager().startUser(msg.arg1);
+                mInjector.getSystemServiceManager().startUser(TimingsTraceAndSlog.newAsyncLog(),
+                        msg.arg1);
                 break;
             case SYSTEM_USER_UNLOCK_MSG:
                 final int userId = msg.arg1;
@@ -2181,14 +2217,12 @@
 
             // Report system user unlock time to perf dashboard
             if (id == UserHandle.USER_SYSTEM) {
-                new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
-                        .logDuration("SystemUserUnlock", unlockTime);
+                new TimingsTraceAndSlog().logDuration("SystemUserUnlock", unlockTime);
             } else {
-                new TimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER)
-                        .logDuration("User" + id + "Unlock", unlockTime);
+                new TimingsTraceAndSlog().logDuration("User" + id + "Unlock", unlockTime);
             }
         }
-    };
+    }
 
     @VisibleForTesting
     static class Injector {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 7056799..3007016 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -198,10 +198,11 @@
         }
     };
 
+    @GuardedBy("this")
     @VisibleForTesting
     final SparseArray<UidState> mUidStates = new SparseArray<>();
 
-    private final HistoricalRegistry mHistoricalRegistry = new HistoricalRegistry(this);
+    final HistoricalRegistry mHistoricalRegistry = new HistoricalRegistry(this);
 
     long mLastRealtime;
 
@@ -905,6 +906,8 @@
                     }
                 }
             }
+
+            mHistoricalRegistry.clearHistory(uid, packageName);
         }
     }
 
@@ -1185,7 +1188,7 @@
         }
     }
 
-    private void pruneOp(Op op, int uid, String packageName) {
+    private void pruneOpLocked(Op op, int uid, String packageName) {
         if (!op.hasAnyTime()) {
             Ops ops = getOpsRawLocked(uid, packageName, false /* isPrivileged */, false /* edit */);
             if (ops != null) {
@@ -1394,7 +1397,7 @@
                     if (mode == AppOpsManager.opToDefaultMode(op.op)) {
                         // If going into the default mode, prune this op
                         // if there is nothing else interesting in it.
-                        pruneOp(op, uid, packageName);
+                        pruneOpLocked(op, uid, packageName);
                     }
                     scheduleFastWriteLocked();
                 }
@@ -1747,7 +1750,14 @@
      */
     private @Mode int checkOperationUnchecked(int code, int uid, @NonNull String packageName,
                 boolean raw) {
-        boolean isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
+        boolean isPrivileged;
+
+        try {
+            isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
+        } catch (SecurityException e) {
+            Slog.e(TAG, "checkOperation", e);
+            return AppOpsManager.opToDefaultMode(code);
+        }
 
         synchronized (this) {
             if (isOpRestrictedLocked(uid, code, packageName, isPrivileged)) {
@@ -1937,8 +1947,8 @@
         try {
             isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
         } catch (SecurityException e) {
-            Slog.e(TAG, "Cannot startOperation", e);
-            return AppOpsManager.MODE_IGNORED;
+            Slog.e(TAG, "noteOperation", e);
+            return AppOpsManager.MODE_ERRORED;
         }
 
         synchronized (this) {
@@ -2115,8 +2125,8 @@
         try {
             isPrivileged = verifyAndGetIsPrivileged(uid, packageName);
         } catch (SecurityException e) {
-            Slog.e(TAG, "Cannot startOperation", e);
-            return AppOpsManager.MODE_IGNORED;
+            Slog.e(TAG, "startOperation", e);
+            return AppOpsManager.MODE_ERRORED;
         }
 
         synchronized (this) {
@@ -2970,23 +2980,25 @@
                 out.startTag(null, "app-ops");
                 out.attribute(null, "v", String.valueOf(CURRENT_VERSION));
 
-                final int uidStateCount = mUidStates.size();
-                for (int i = 0; i < uidStateCount; i++) {
-                    UidState uidState = mUidStates.valueAt(i);
-                    if (uidState.opModes != null && uidState.opModes.size() > 0) {
-                        out.startTag(null, "uid");
-                        out.attribute(null, "n", Integer.toString(uidState.uid));
-                        SparseIntArray uidOpModes = uidState.opModes;
-                        final int opCount = uidOpModes.size();
-                        for (int j = 0; j < opCount; j++) {
-                            final int op = uidOpModes.keyAt(j);
-                            final int mode = uidOpModes.valueAt(j);
-                            out.startTag(null, "op");
-                            out.attribute(null, "n", Integer.toString(op));
-                            out.attribute(null, "m", Integer.toString(mode));
-                            out.endTag(null, "op");
+                synchronized (this) {
+                    final int uidStateCount = mUidStates.size();
+                    for (int i = 0; i < uidStateCount; i++) {
+                        UidState uidState = mUidStates.valueAt(i);
+                        if (uidState.opModes != null && uidState.opModes.size() > 0) {
+                            out.startTag(null, "uid");
+                            out.attribute(null, "n", Integer.toString(uidState.uid));
+                            SparseIntArray uidOpModes = uidState.opModes;
+                            final int opCount = uidOpModes.size();
+                            for (int j = 0; j < opCount; j++) {
+                                final int op = uidOpModes.keyAt(j);
+                                final int mode = uidOpModes.valueAt(j);
+                                out.startTag(null, "op");
+                                out.attribute(null, "n", Integer.toString(op));
+                                out.attribute(null, "m", Integer.toString(mode));
+                                out.endTag(null, "op");
+                            }
+                            out.endTag(null, "uid");
                         }
-                        out.endTag(null, "uid");
                     }
                 }
 
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index d723c7b..9cf342c 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -108,6 +108,12 @@
  * must be called with the mInMemoryLock, xxxDMLocked suffix means the method
  * must be called with the mOnDiskLock and mInMemoryLock locks acquired in that
  * exact order.
+ * <p>
+ * INITIALIZATION: We can initialize persistence only after the system is ready
+ * as we need to check the optional configuration override from the settings
+ * database which is not initialized at the time the app ops service is created.
+ * This means that all entry points that touch persistence should be short
+ * circuited via isPersistenceInitialized() check.
  */
 // TODO (bug:122218838): Make sure we handle start of epoch time
 // TODO (bug:122218838): Validate changed time is handled correctly
@@ -177,14 +183,33 @@
 
     // Object managing persistence (read/write)
     @GuardedBy("mOnDiskLock")
-    private Persistence mPersistence = new Persistence(mBaseSnapshotInterval,
-            mIntervalCompressionMultiplier);
+    private Persistence mPersistence;
 
     HistoricalRegistry(@NonNull Object lock) {
         mInMemoryLock = lock;
-        if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
-            synchronized (mOnDiskLock) {
-                synchronized (mInMemoryLock) {
+    }
+
+    void systemReady(@NonNull ContentResolver resolver) {
+        final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
+        resolver.registerContentObserver(uri, false, new ContentObserver(
+                FgThread.getHandler()) {
+            @Override
+            public void onChange(boolean selfChange) {
+                updateParametersFromSetting(resolver);
+            }
+        });
+
+        updateParametersFromSetting(resolver);
+
+        synchronized (mOnDiskLock) {
+            synchronized (mInMemoryLock) {
+                if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
+                    // Can be uninitialized if there is no config in the settings table.
+                    if (!isPersistenceInitializedMLocked()) {
+                        mPersistence = new Persistence(mBaseSnapshotInterval,
+                                mIntervalCompressionMultiplier);
+                    }
+
                     // When starting always adjust history to now.
                     final long lastPersistTimeMills =
                             mPersistence.getLastPersistTimeMillisDLocked();
@@ -197,16 +222,8 @@
         }
     }
 
-    void systemReady(@NonNull ContentResolver resolver) {
-        updateParametersFromSetting(resolver);
-        final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
-        resolver.registerContentObserver(uri, false, new ContentObserver(
-                FgThread.getHandler()) {
-            @Override
-            public void onChange(boolean selfChange) {
-                updateParametersFromSetting(resolver);
-            }
-        });
+    private boolean isPersistenceInitializedMLocked() {
+        return mPersistence != null;
     }
 
     private void updateParametersFromSetting(@NonNull ContentResolver resolver) {
@@ -274,6 +291,11 @@
                 makeRelativeToEpochStart(currentOps, nowMillis);
                 currentOps.accept(visitor);
 
+                if(isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
+
                 final List<HistoricalOps> ops = mPersistence.readHistoryDLocked();
                 if (ops != null) {
                     // TODO (bug:122218838): Make sure this is properly dumped
@@ -302,12 +324,21 @@
     void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName,
             @Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
             @OpFlags int flags, @NonNull RemoteCallback callback) {
-        final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
-        mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
-                beginTimeMillis, endTimeMillis, flags);
-        final Bundle payload = new Bundle();
-        payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
-        callback.sendResult(payload);
+        synchronized (mOnDiskLock) {
+            synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    callback.sendResult(new Bundle());
+                    return;
+                }
+                final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
+                mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
+                        beginTimeMillis, endTimeMillis, flags);
+                final Bundle payload = new Bundle();
+                payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
+                callback.sendResult(payload);
+            }
+        }
     }
 
     void getHistoricalOps(int uid, @NonNull String packageName,
@@ -331,6 +362,12 @@
             boolean collectOpsFromDisk;
 
             synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    callback.sendResult(new Bundle());
+                    return;
+                }
+
                 currentOps = getUpdatedPendingHistoricalOpsMLocked(currentTimeMillis);
                 if (!(inMemoryAdjBeginTimeMillis >= currentOps.getEndTimeMillis()
                         || inMemoryAdjEndTimeMillis <= currentOps.getBeginTimeMillis())) {
@@ -374,6 +411,10 @@
             @UidState int uidState, @OpFlags int flags) {
         synchronized (mInMemoryLock) {
             if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
                         .increaseAccessCount(op, uid, packageName, uidState, flags, 1);
             }
@@ -384,6 +425,10 @@
             @UidState int uidState, @OpFlags int flags) {
         synchronized (mInMemoryLock) {
             if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
                         .increaseRejectCount(op, uid, packageName, uidState, flags, 1);
             }
@@ -394,6 +439,10 @@
             @UidState int uidState, @OpFlags int flags, long increment) {
         synchronized (mInMemoryLock) {
             if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
                         .increaseAccessDuration(op, uid, packageName, uidState, flags, increment);
             }
@@ -404,6 +453,8 @@
             long baseSnapshotInterval, long intervalCompressionMultiplier) {
         synchronized (mOnDiskLock) {
             synchronized (mInMemoryLock) {
+                // NOTE: We allow this call if persistence is not initialized as
+                // it is a part of the persistence initialization process.
                 boolean resampleHistory = false;
                 Slog.i(LOG_TAG, "New history parameters: mode:"
                         + AppOpsManager.historicalModeToString(mMode) + " baseSnapshotInterval:"
@@ -412,7 +463,7 @@
                 if (mMode != mode) {
                     mMode = mode;
                     if (mMode == AppOpsManager.HISTORICAL_MODE_DISABLED) {
-                        clearHistoryOnDiskLocked();
+                        clearHistoryOnDiskDLocked();
                     }
                 }
                 if (mBaseSnapshotInterval != baseSnapshotInterval) {
@@ -433,6 +484,10 @@
     void offsetHistory(long offsetMillis) {
         synchronized (mOnDiskLock) {
             synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
                 final List<HistoricalOps> history = mPersistence.readHistoryDLocked();
                 clearHistory();
                 if (history != null) {
@@ -453,6 +508,10 @@
     void addHistoricalOps(HistoricalOps ops) {
         final List<HistoricalOps> pendingWrites;
         synchronized (mInMemoryLock) {
+            if (!isPersistenceInitializedMLocked()) {
+                Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                return;
+            }
             // The history files start from mBaseSnapshotInterval - take this into account.
             ops.offsetBeginAndEndTime(mBaseSnapshotInterval);
             mPendingWrites.offerFirst(ops);
@@ -468,24 +527,57 @@
     }
 
     void resetHistoryParameters() {
+        if (!isPersistenceInitializedMLocked()) {
+            Slog.e(LOG_TAG, "Interaction before persistence initialized");
+            return;
+        }
         setHistoryParameters(DEFAULT_MODE, DEFAULT_SNAPSHOT_INTERVAL_MILLIS,
                 DEFAULT_COMPRESSION_STEP);
     }
 
-    void clearHistory() {
+    void clearHistory(int uid, String packageName) {
         synchronized (mOnDiskLock) {
-            clearHistoryOnDiskLocked();
+            synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
+                if (mMode != AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+                    return;
+                }
+
+                for (int index = 0; index < mPendingWrites.size(); index++) {
+                    mPendingWrites.get(index).clearHistory(uid, packageName);
+                }
+
+                getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
+                        .clearHistory(uid, packageName);
+
+                mPersistence.clearHistoryDLocked(uid, packageName);
+            }
         }
     }
 
-    private void clearHistoryOnDiskLocked() {
+    void clearHistory() {
+        synchronized (mOnDiskLock) {
+            synchronized (mInMemoryLock) {
+                if (!isPersistenceInitializedMLocked()) {
+                    Slog.e(LOG_TAG, "Interaction before persistence initialized");
+                    return;
+                }
+                clearHistoryOnDiskDLocked();
+            }
+        }
+    }
+
+    private void clearHistoryOnDiskDLocked() {
         BackgroundThread.getHandler().removeMessages(MSG_WRITE_PENDING_HISTORY);
         synchronized (mInMemoryLock) {
             mCurrentHistoricalOps = null;
             mNextPersistDueTimeMillis = System.currentTimeMillis();
             mPendingWrites.clear();
         }
-        mPersistence.clearHistoryDLocked();
+        Persistence.clearHistoryDLocked();
     }
 
     private @NonNull HistoricalOps getUpdatedPendingHistoricalOpsMLocked(long now) {
@@ -620,7 +712,7 @@
             mIntervalCompressionMultiplier = intervalCompressionMultiplier;
         }
 
-        private final AtomicDirectory mHistoricalAppOpsDir = new AtomicDirectory(
+        private static final AtomicDirectory sHistoricalAppOpsDir = new AtomicDirectory(
                 new File(new File(Environment.getDataSystemDirectory(), "appops"), "history"));
 
         private File generateFile(@NonNull File baseDir, int depth) {
@@ -628,8 +720,24 @@
             return new File(baseDir, Long.toString(globalBeginMillis) + HISTORY_FILE_SUFFIX);
         }
 
-        void clearHistoryDLocked() {
-            mHistoricalAppOpsDir.delete();
+        void clearHistoryDLocked(int uid, String packageName) {
+            List<HistoricalOps> historicalOps = readHistoryDLocked();
+
+            if (historicalOps == null) {
+                return;
+            }
+
+            for (int index = 0; index < historicalOps.size(); index++) {
+                historicalOps.get(index).clearHistory(uid, packageName);
+            }
+
+            clearHistoryDLocked();
+
+            persistHistoricalOpsDLocked(historicalOps);
+        }
+
+        static void clearHistoryDLocked() {
+            sHistoricalAppOpsDir.delete();
         }
 
         void persistHistoricalOpsDLocked(@NonNull List<HistoricalOps> ops) {
@@ -638,8 +746,8 @@
                 enforceOpsWellFormed(ops);
             }
             try {
-                final File newBaseDir = mHistoricalAppOpsDir.startWrite();
-                final File oldBaseDir = mHistoricalAppOpsDir.getBackupDirectory();
+                final File newBaseDir = sHistoricalAppOpsDir.startWrite();
+                final File oldBaseDir = sHistoricalAppOpsDir.getBackupDirectory();
                 final HistoricalFilesInvariant filesInvariant;
                 if (DEBUG) {
                     filesInvariant = new HistoricalFilesInvariant();
@@ -651,10 +759,10 @@
                 if (DEBUG) {
                     filesInvariant.stopTracking(newBaseDir);
                 }
-                mHistoricalAppOpsDir.finishWrite();
+                sHistoricalAppOpsDir.finishWrite();
             } catch (Throwable t) {
                 wtf("Failed to write historical app ops, restoring backup", t, null);
-                mHistoricalAppOpsDir.failWrite();
+                sHistoricalAppOpsDir.failWrite();
             }
         }
 
@@ -680,22 +788,36 @@
         long getLastPersistTimeMillisDLocked() {
             File baseDir = null;
             try {
-                baseDir = mHistoricalAppOpsDir.startRead();
+                baseDir = sHistoricalAppOpsDir.startRead();
                 final File[] files = baseDir.listFiles();
                 if (files != null && files.length > 0) {
-                    final Set<File> historyFiles = new ArraySet<>();
-                    Collections.addAll(historyFiles, files);
-                    for (int i = 0;; i++) {
-                        final File file = generateFile(baseDir, i);
-                        if (historyFiles.contains(file)) {
-                            return file.lastModified();
+                    File shortestFile = null;
+                    for (File candidate : files) {
+                        final String candidateName = candidate.getName();
+                        if (!candidateName.endsWith(HISTORY_FILE_SUFFIX)) {
+                            continue;
+                        }
+                        if (shortestFile == null) {
+                            shortestFile = candidate;
+                        } else if (candidateName.length() < shortestFile.getName().length()) {
+                            shortestFile = candidate;
                         }
                     }
+                    if (shortestFile == null) {
+                        return 0;
+                    }
+                    final String shortestNameNoExtension = shortestFile.getName()
+                            .replace(HISTORY_FILE_SUFFIX, "");
+                    try {
+                        return Long.parseLong(shortestNameNoExtension);
+                    } catch (NumberFormatException e) {
+                        return 0;
+                    }
                 }
-                mHistoricalAppOpsDir.finishRead();
+                sHistoricalAppOpsDir.finishRead();
             } catch (Throwable e) {
                 wtf("Error reading historical app ops. Deleting history.", e, baseDir);
-                mHistoricalAppOpsDir.delete();
+                sHistoricalAppOpsDir.delete();
             }
             return 0;
         }
@@ -720,7 +842,7 @@
                 long filterBeginTimeMillis, long filterEndTimeMillis, @OpFlags int filterFlags) {
             File baseDir = null;
             try {
-                baseDir = mHistoricalAppOpsDir.startRead();
+                baseDir = sHistoricalAppOpsDir.startRead();
                 final HistoricalFilesInvariant filesInvariant;
                 if (DEBUG) {
                     filesInvariant = new HistoricalFilesInvariant();
@@ -735,11 +857,11 @@
                 if (DEBUG) {
                     filesInvariant.stopTracking(baseDir);
                 }
-                mHistoricalAppOpsDir.finishRead();
+                sHistoricalAppOpsDir.finishRead();
                 return ops;
             } catch (Throwable t) {
                 wtf("Error reading historical app ops. Deleting history.", t, baseDir);
-                mHistoricalAppOpsDir.delete();
+                sHistoricalAppOpsDir.delete();
             }
             return null;
         }
@@ -1206,7 +1328,7 @@
 
         private void writeHistoricalOpsDLocked(@Nullable List<HistoricalOps> allOps,
                 long intervalOverflowMillis, @NonNull File file) throws IOException {
-            final FileOutputStream output = mHistoricalAppOpsDir.openWrite(file);
+            final FileOutputStream output = sHistoricalAppOpsDir.openWrite(file);
             try {
                 final XmlSerializer serializer = Xml.newSerializer();
                 serializer.setOutput(output, StandardCharsets.UTF_8.name());
@@ -1228,9 +1350,9 @@
                 }
                 serializer.endTag(null, TAG_HISTORY);
                 serializer.endDocument();
-                mHistoricalAppOpsDir.closeWrite(output);
+                sHistoricalAppOpsDir.closeWrite(output);
             } catch (IOException e) {
-                mHistoricalAppOpsDir.failWrite(output);
+                sHistoricalAppOpsDir.failWrite(output);
                 throw e;
             }
         }
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 3b19d08..087c84f 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -190,9 +190,7 @@
 
             final UserState userState = getOrCreateCurrentUserStateLocked();
             // lazily start the service, which should be very lightweight to start
-            if (!userState.bindLocked()) {
-                return false;
-            }
+            userState.bindLocked();
 
             // throttle frequent requests
             final AttentionCheckCache cache = userState.mAttentionCheckCache;
@@ -310,7 +308,7 @@
     protected UserState getOrCreateUserStateLocked(int userId) {
         UserState result = mUserStates.get(userId);
         if (result == null) {
-            result = new UserState(userId, mContext, mLock, mComponentName);
+            result = new UserState(userId, mContext, mLock, mAttentionHandler, mComponentName);
             mUserStates.put(userId, result);
         }
         return result;
@@ -377,7 +375,7 @@
 
     private void dumpInternal(IndentingPrintWriter ipw) {
         ipw.println("Attention Manager Service (dumpsys attention) state:\n");
-
+        ipw.println("isServiceEnabled=" + isServiceEnabled());
         ipw.println("AttentionServicePackageName=" + getServiceConfigPackage(mContext));
         ipw.println("Resolved component:");
         if (mComponentName != null) {
@@ -456,31 +454,33 @@
 
     @VisibleForTesting
     protected static class UserState {
-        final ComponentName mComponentName;
-        final AttentionServiceConnection mConnection = new AttentionServiceConnection();
+        private final ComponentName mComponentName;
+        private final AttentionServiceConnection mConnection = new AttentionServiceConnection();
 
         @GuardedBy("mLock")
         IAttentionService mService;
         @GuardedBy("mLock")
-        boolean mBinding;
-        @GuardedBy("mLock")
         AttentionCheck mCurrentAttentionCheck;
         @GuardedBy("mLock")
         AttentionCheckCache mAttentionCheckCache;
+        @GuardedBy("mLock")
+        private boolean mBinding;
 
         @UserIdInt
-        final int mUserId;
-        final Context mContext;
-        final Object mLock;
+        private final int mUserId;
+        private final Context mContext;
+        private final Object mLock;
+        private final Handler mAttentionHandler;
 
-        UserState(int userId, Context context, Object lock, ComponentName componentName) {
+        UserState(int userId, Context context, Object lock, Handler handler,
+                ComponentName componentName) {
             mUserId = userId;
             mContext = Preconditions.checkNotNull(context);
             mLock = Preconditions.checkNotNull(lock);
             mComponentName = Preconditions.checkNotNull(componentName);
+            mAttentionHandler = handler;
         }
 
-
         @GuardedBy("mLock")
         private void handlePendingCallbackLocked() {
             if (!mCurrentAttentionCheck.mIsDispatched) {
@@ -499,26 +499,25 @@
 
         /** Binds to the system's AttentionService which provides an actual implementation. */
         @GuardedBy("mLock")
-        private boolean bindLocked() {
+        private void bindLocked() {
             // No need to bind if service is binding or has already been bound.
             if (mBinding || mService != null) {
-                return true;
+                return;
             }
 
-            final boolean willBind;
-            final long identity = Binder.clearCallingIdentity();
-
-            try {
-                final Intent mServiceIntent = new Intent(
+            mBinding = true;
+            // mContext.bindServiceAsUser() calls into ActivityManagerService which it may already
+            // hold the lock and had called into PowerManagerService, which holds a lock.
+            // That would create a deadlock. To solve that, putting it on a handler.
+            mAttentionHandler.post(() -> {
+                final Intent serviceIntent = new Intent(
                         AttentionService.SERVICE_INTERFACE).setComponent(
                         mComponentName);
-                willBind = mContext.bindServiceAsUser(mServiceIntent, mConnection,
+                // Note: no reason to clear the calling identity, we won't have one in a handler.
+                mContext.bindServiceAsUser(serviceIntent, mConnection,
                         Context.BIND_AUTO_CREATE, UserHandle.CURRENT);
-                mBinding = willBind;
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-            return willBind;
+
+            });
         }
 
         private void dump(IndentingPrintWriter pw) {
@@ -587,6 +586,7 @@
             super(Looper.myLooper());
         }
 
+        @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 // Do not occupy resources when not in use - unbind proactively.
@@ -651,7 +651,12 @@
                 return;
             }
 
-            mContext.unbindService(userState.mConnection);
+            mAttentionHandler.post(() -> mContext.unbindService(userState.mConnection));
+            // Note: this will set mBinding to false even though it could still be trying to bind
+            // (i.e. the runnable was posted in bindLocked but then cancelAndUnbindLocked was
+            // called before it's run yet). This is a safe state at the moment,
+            // since it will eventually, but feels like a source for confusion down the road and
+            // may cause some expensive and unnecessary work to be done.
             userState.mConnection.cleanupService();
             mUserStates.remove(userState.mUserId);
         }
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index fcd6a0a..cb6cf74 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -40,9 +40,11 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.Log;
+import android.util.PrintWriterPrinter;
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.io.PrintWriter;
 
 /** @hide */
 /*package*/ final class AudioDeviceBroker {
@@ -123,6 +125,8 @@
     /*package*/ void onAudioServerDied() {
         // Restore forced usage for communications and record
         synchronized (mDeviceStateLock) {
+            AudioSystem.setParameters(
+                    "BT_SCO=" + (mForcedUseForComm == AudioSystem.FORCE_BT_SCO ? "on" : "off"));
             onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, "onAudioServerDied");
             onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm, "onAudioServerDied");
         }
@@ -569,9 +573,8 @@
         return mBrokerHandler.hasMessages(MSG_IL_BTA2DP_DOCK_TIMEOUT);
     }
 
-    //###
     // must be called synchronized on mConnectedDevices
-    /*package*/  boolean hasScheduledA2dpSinkConnectionState(BluetoothDevice btDevice) {
+    /*package*/ boolean hasScheduledA2dpSinkConnectionState(BluetoothDevice btDevice) {
         return mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE,
                 new BtHelper.BluetoothA2dpDeviceInfo(btDevice));
     }
@@ -598,6 +601,15 @@
         }
     }
 
+    /*package*/ void dump(PrintWriter pw, String prefix) {
+        if (mBrokerHandler != null) {
+            pw.println(prefix + "Message handler (watch for unhandled messages):");
+            mBrokerHandler.dump(new PrintWriterPrinter(pw), prefix + "  ");
+        } else {
+            pw.println("Message handler is null");
+        }
+    }
+
     //---------------------------------------------------------------------
     // Internal handling of messages
     // These methods are ALL synchronous, in response to message handling in BrokerHandler
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 99b97cb..a9a8ef2 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -146,6 +146,7 @@
         }
     }
 
+    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     /*package*/ void onSetA2dpSinkConnectionState(@NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo,
             @AudioService.BtProfileConnectionState int state) {
         final BluetoothDevice btDevice = btInfo.getBtDevice();
@@ -259,6 +260,7 @@
         }
     }
 
+    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     /*package*/ void onBluetoothA2dpActiveDeviceChange(
             @NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo, int event) {
         final BluetoothDevice btDevice = btInfo.getBtDevice();
@@ -532,6 +534,7 @@
         return mCurAudioRoutes;
     }
 
+    @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
     /*package*/ void setBluetoothA2dpDeviceConnectionState(
             @NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
             int profile, boolean suppressNoisyIntent, int musicDevice, int a2dpVolume) {
@@ -559,9 +562,13 @@
             final BtHelper.BluetoothA2dpDeviceInfo a2dpDeviceInfo =
                     new BtHelper.BluetoothA2dpDeviceInfo(device, a2dpVolume, a2dpCodec);
             if (profile == BluetoothProfile.A2DP) {
-                mDeviceBroker.postA2dpSinkConnection(state,
-                        a2dpDeviceInfo,
-                        delay);
+                if (delay == 0) {
+                    onSetA2dpSinkConnectionState(a2dpDeviceInfo, state);
+                } else {
+                    mDeviceBroker.postA2dpSinkConnection(state,
+                            a2dpDeviceInfo,
+                            delay);
+                }
             } else { //profile == BluetoothProfile.A2DP_SINK
                 mDeviceBroker.postA2dpSourceConnection(state,
                         a2dpDeviceInfo,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 30035c8..7458bee 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -54,8 +54,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
 import android.database.ContentObserver;
 import android.hardware.hdmi.HdmiAudioSystemClient;
 import android.hardware.hdmi.HdmiControlManager;
@@ -82,11 +80,7 @@
 import android.media.IVolumeController;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
-import android.media.MediaPlayer;
-import android.media.MediaPlayer.OnCompletionListener;
-import android.media.MediaPlayer.OnErrorListener;
 import android.media.PlayerBase;
-import android.media.SoundPool;
 import android.media.VolumePolicy;
 import android.media.audiofx.AudioEffect;
 import android.media.audiopolicy.AudioMix;
@@ -102,7 +96,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -127,6 +120,7 @@
 import android.util.IntArray;
 import android.util.Log;
 import android.util.MathUtils;
+import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SparseIntArray;
 import android.view.KeyEvent;
@@ -136,7 +130,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
-import com.android.internal.util.XmlUtils;
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -145,15 +138,11 @@
 import com.android.server.pm.UserManagerService;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -162,6 +151,7 @@
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * The implementation of the volume manager service.
@@ -265,6 +255,7 @@
     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
     private static final int MSG_HDMI_VOLUME_CHECK = 28;
+    private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
     // start of messages handled under wakelock
     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
@@ -291,19 +282,6 @@
     // protects mRingerMode
     private final Object mSettingsLock = new Object();
 
-    private SoundPool mSoundPool;
-    private final Object mSoundEffectsLock = new Object();
-    private static final int NUM_SOUNDPOOL_CHANNELS = 4;
-
-    /* Sound effect file names  */
-    private static final String SOUND_EFFECTS_PATH = "/media/audio/ui/";
-    private static final List<String> SOUND_EFFECT_FILES = new ArrayList<String>();
-
-    /* Sound effect file name mapping sound effect id (AudioManager.FX_xxx) to
-     * file index in SOUND_EFFECT_FILES[] (first column) and indicating if effect
-     * uses soundpool (second column) */
-    private final int[][] SOUND_EFFECT_FILES_MAP = new int[AudioManager.NUM_SOUND_EFFECTS][2];
-
    /** Maximum volume index values for audio streams */
     protected static int[] MAX_STREAM_VOLUME = new int[] {
         5,  // STREAM_VOICE_CALL
@@ -363,7 +341,7 @@
         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
-        AudioSystem.STREAM_MUSIC,       // STREAM_BLUETOOTH_SCO
+        AudioSystem.STREAM_BLUETOOTH_SCO,       // STREAM_BLUETOOTH_SCO
         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
         AudioSystem.STREAM_MUSIC,       // STREAM_TTS
@@ -450,6 +428,9 @@
      * @see System#MUTE_STREAMS_AFFECTED */
     private int mMuteAffectedStreams;
 
+    @NonNull
+    private SoundEffectsHelper mSfxHelper;
+
     /**
      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
      * mVibrateSetting is just maintained during deprecation period but vibration policy is
@@ -490,14 +471,6 @@
     private boolean mSystemReady;
     // true if Intent.ACTION_USER_SWITCHED has ever been received
     private boolean mUserSwitchedReceived;
-    // listener for SoundPool sample load completion indication
-    private SoundPoolCallback mSoundPoolCallBack;
-    // thread for SoundPool listener
-    private SoundPoolListenerThread mSoundPoolListenerThread;
-    // message looper for SoundPool listener
-    private Looper mSoundPoolLooper = null;
-    // volume applied to sound played with playSoundEffect()
-    private static int sSoundEffectVolumeDb;
     // previous volume adjustment direction received by checkForRingerModeChange()
     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
@@ -639,6 +612,8 @@
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
 
+        mSfxHelper = new SoundEffectsHelper(mContext);
+
         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
 
@@ -729,9 +704,6 @@
                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
         }
 
-        sSoundEffectVolumeDb = context.getResources().getInteger(
-                com.android.internal.R.integer.config_soundEffectVolumeDb);
-
         createAudioSystemThread();
 
         AudioSystem.setErrorCallback(mAudioSystemCallback);
@@ -1014,6 +986,7 @@
             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
             sendEnabledSurroundFormats(mContentResolver, true);
             updateAssistantUId(true);
+            updateRttEanbled(mContentResolver);
         }
         synchronized (mAccessibilityServiceUidsLock) {
             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
@@ -1275,8 +1248,6 @@
                             System.VOLUME_SETTINGS_INT[a11yStreamAlias];
                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
                             mStreamStates[a11yStreamAlias], caller);
-                    mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].refreshRange(
-                            mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY]);
                 }
             }
             if (sIndependentA11yVolume) {
@@ -1480,6 +1451,12 @@
         }
     }
 
+    private void updateRttEanbled(ContentResolver cr) {
+        final boolean rttEnabled = Settings.Secure.getIntForUser(cr,
+                    Settings.Secure.RTT_CALLING_MODE, 0, UserHandle.USER_CURRENT) != 0;
+        AudioSystem.setRttEnabled(rttEnabled);
+    }
+
     private void readPersistedSettings() {
         final ContentResolver cr = mContentResolver;
 
@@ -1524,6 +1501,7 @@
             sendEncodedSurroundMode(cr, "readPersistedSettings");
             sendEnabledSurroundFormats(cr, true);
             updateAssistantUId(true);
+            updateRttEanbled(cr);
         }
 
         mMuteAffectedStreams = System.getIntForUser(cr,
@@ -1577,20 +1555,19 @@
     }
 
     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)
-                / mStreamStates[srcStream].getMaxIndex();
-        if (rescaled < mStreamStates[dstStream].getMinIndex()) {
+        int srcRange =
+                mStreamStates[srcStream].getMaxIndex() - mStreamStates[srcStream].getMinIndex();
+        int dstRange =
+                mStreamStates[dstStream].getMaxIndex() - mStreamStates[dstStream].getMinIndex();
+
+        if (srcRange == 0) {
+            Log.e(TAG, "rescaleIndex : index range should not be zero");
             return mStreamStates[dstStream].getMinIndex();
-        } else {
-            return rescaled;
         }
+
+        return mStreamStates[dstStream].getMinIndex()
+                + ((index - mStreamStates[srcStream].getMinIndex()) * dstRange + srcRange / 2)
+                / srcRange;
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -1870,9 +1847,15 @@
 
             // Check if volume update should be send to Hearing Aid
             if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
-                Log.i(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index=" + newIndex
-                        + " stream=" + streamType);
-                mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+                // only modify the hearing aid attenuation when the stream to modify matches
+                // the one expected by the hearing aid
+                if (streamType == getHearingAidStreamType()) {
+                    if (DEBUG_VOL) {
+                        Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
+                                + newIndex + " stream=" + streamType);
+                    }
+                    mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+                }
             }
 
             // Check if volume update should be sent to Hdmi system audio.
@@ -1903,8 +1886,8 @@
                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
                             final long ident = Binder.clearCallingIdentity();
                             try {
-                                mHdmiPlaybackClient.sendKeyEvent(keyCode, true);
-                                mHdmiPlaybackClient.sendKeyEvent(keyCode, false);
+                                mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true);
+                                mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false);
                             } finally {
                                 Binder.restoreCallingIdentity(ident);
                             }
@@ -2039,8 +2022,11 @@
             setRingerMode(getNewRingerMode(stream, index, flags),
                     TAG + ".onSetStreamVolume", false /*external*/);
         }
-        // setting non-zero volume for a muted stream unmutes the stream and vice versa
-        mStreamStates[stream].mute(index == 0);
+        // setting non-zero volume for a muted stream unmutes the stream and vice versa,
+        // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
+        if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) {
+            mStreamStates[stream].mute(index == 0);
+        }
     }
 
     private void enforceModifyAudioRoutingPermission() {
@@ -2118,14 +2104,11 @@
                     + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
             return;
         }
-        if ((streamType == AudioManager.STREAM_VOICE_CALL ||
-                streamType == AudioManager.STREAM_BLUETOOTH_SCO) &&
-                (index == 0) &&
-                (mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.MODIFY_PHONE_STATE)
+        if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
+                && (mContext.checkCallingOrSelfPermission(
+                    android.Manifest.permission.MODIFY_PHONE_STATE)
                     != PackageManager.PERMISSION_GRANTED)) {
-            Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL or"
-                    + " STREAM_BLUETOOTH_SCO and index 0 without"
+            Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
                     + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
             return;
         }
@@ -2164,11 +2147,53 @@
                 return AudioSystem.STREAM_VOICE_CALL;
             case AudioSystem.MODE_NORMAL:
             default:
+                // other conditions will influence the stream type choice, read on...
                 break;
         }
+        if (mVoiceActive.get()) {
+            return AudioSystem.STREAM_VOICE_CALL;
+        }
         return AudioSystem.STREAM_MUSIC;
     }
 
+    private AtomicBoolean mVoiceActive = new AtomicBoolean(false);
+
+    private final IPlaybackConfigDispatcher mVoiceActivityMonitor =
+            new IPlaybackConfigDispatcher.Stub() {
+        @Override
+        public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
+                                                 boolean flush) {
+            sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
+                    0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
+                    configs /*obj*/, 0 /*delay*/);
+        }
+    };
+
+    private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
+        boolean voiceActive = false;
+        for (AudioPlaybackConfiguration config : configs) {
+            final int usage = config.getAudioAttributes().getUsage();
+            if ((usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
+                    || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
+                    && config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+                voiceActive = true;
+                break;
+            }
+        }
+        if (mVoiceActive.getAndSet(voiceActive) != voiceActive) {
+            updateHearingAidVolumeOnVoiceActivityUpdate();
+        }
+    }
+
+    private void updateHearingAidVolumeOnVoiceActivityUpdate() {
+        final int streamType = getHearingAidStreamType();
+        final int index = getStreamVolume(streamType);
+        sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
+                mVoiceActive.get(), streamType, index));
+        mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+
+    }
+
     /**
      * Manage an audio mode change for audio devices that use an "absolute volume" model,
      * i.e. the framework sends the full scale signal, and the actual volume for the use case
@@ -2203,10 +2228,8 @@
         // handling of specific interfaces goes here:
         if ((device & mAbsVolumeMultiModeCaseDevices) == AudioSystem.DEVICE_OUT_HEARING_AID) {
             final int index = getStreamVolume(streamType);
-            mModeLogger.log(new AudioEventLogger.StringEvent("setMode to "
-                    + AudioSystem.modeToString(newMode)
-                    + " causes setting HEARING_AID volume to idx:" + index
-                    + " stream:" + AudioSystem.streamToString(streamType)));
+            sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
+                    newMode, streamType, index));
             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
         }
     }
@@ -2272,7 +2295,8 @@
                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
             }
 
-            if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0) {
+            if ((device & AudioSystem.DEVICE_OUT_HEARING_AID) != 0
+                    && streamType == getHearingAidStreamType()) {
                 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
                         + " stream=" + streamType);
                 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
@@ -2488,15 +2512,11 @@
         mVolumeController.postVolumeChanged(streamType, flags);
     }
 
-    // If Hdmi-CEC system audio mode is on, we show volume bar only when TV
-    // receives volume notification from Audio Receiver.
+    // If Hdmi-CEC system audio mode is on and we are a TV panel, never show volume bar.
     private int updateFlagsForTvPlatform(int flags) {
         synchronized (mHdmiClientLock) {
-            if (mHdmiTvClient != null) {
-                if (mHdmiSystemAudioSupported &&
-                        ((flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) == 0)) {
-                    flags &= ~AudioManager.FLAG_SHOW_UI;
-                }
+            if (mHdmiTvClient != null && mHdmiSystemAudioSupported) {
+                flags &= ~AudioManager.FLAG_SHOW_UI;
             }
         }
         return flags;
@@ -2812,8 +2832,9 @@
             AudioSystem.muteMicrophone(on);
             Binder.restoreCallingIdentity(identity);
             if (on != currentMute) {
-                mContext.sendBroadcast(new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED)
-                        .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY));
+                mContext.sendBroadcastAsUser(
+                        new Intent(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED)
+                                .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL);
             }
         }
     }
@@ -3317,104 +3338,30 @@
     //==========================================================================================
     // Sound Effects
     //==========================================================================================
+    private static final class LoadSoundEffectReply
+            implements SoundEffectsHelper.OnEffectsLoadCompleteHandler {
+        private static final int SOUND_EFFECTS_LOADING = 1;
+        private static final int SOUND_EFFECTS_LOADED = 0;
+        private static final int SOUND_EFFECTS_ERROR = -1;
+        private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
 
-    private static final String TAG_AUDIO_ASSETS = "audio_assets";
-    private static final String ATTR_VERSION = "version";
-    private static final String TAG_GROUP = "group";
-    private static final String ATTR_GROUP_NAME = "name";
-    private static final String TAG_ASSET = "asset";
-    private static final String ATTR_ASSET_ID = "id";
-    private static final String ATTR_ASSET_FILE = "file";
+        private int mStatus = SOUND_EFFECTS_LOADING;
 
-    private static final String ASSET_FILE_VERSION = "1.0";
-    private static final String GROUP_TOUCH_SOUNDS = "touch_sounds";
-
-    private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
-
-    class LoadSoundEffectReply {
-        public int mStatus = 1;
-    };
-
-    private void loadTouchSoundAssetDefaults() {
-        SOUND_EFFECT_FILES.add("Effect_Tick.ogg");
-        for (int i = 0; i < AudioManager.NUM_SOUND_EFFECTS; i++) {
-            SOUND_EFFECT_FILES_MAP[i][0] = 0;
-            SOUND_EFFECT_FILES_MAP[i][1] = -1;
-        }
-    }
-
-    private void loadTouchSoundAssets() {
-        XmlResourceParser parser = null;
-
-        // only load assets once.
-        if (!SOUND_EFFECT_FILES.isEmpty()) {
-            return;
+        @Override
+        public synchronized void run(boolean success) {
+            mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR;
+            notify();
         }
 
-        loadTouchSoundAssetDefaults();
-
-        try {
-            parser = mContext.getResources().getXml(com.android.internal.R.xml.audio_assets);
-
-            XmlUtils.beginDocument(parser, TAG_AUDIO_ASSETS);
-            String version = parser.getAttributeValue(null, ATTR_VERSION);
-            boolean inTouchSoundsGroup = false;
-
-            if (ASSET_FILE_VERSION.equals(version)) {
-                while (true) {
-                    XmlUtils.nextElement(parser);
-                    String element = parser.getName();
-                    if (element == null) {
-                        break;
-                    }
-                    if (element.equals(TAG_GROUP)) {
-                        String name = parser.getAttributeValue(null, ATTR_GROUP_NAME);
-                        if (GROUP_TOUCH_SOUNDS.equals(name)) {
-                            inTouchSoundsGroup = true;
-                            break;
-                        }
-                    }
-                }
-                while (inTouchSoundsGroup) {
-                    XmlUtils.nextElement(parser);
-                    String element = parser.getName();
-                    if (element == null) {
-                        break;
-                    }
-                    if (element.equals(TAG_ASSET)) {
-                        String id = parser.getAttributeValue(null, ATTR_ASSET_ID);
-                        String file = parser.getAttributeValue(null, ATTR_ASSET_FILE);
-                        int fx;
-
-                        try {
-                            Field field = AudioManager.class.getField(id);
-                            fx = field.getInt(null);
-                        } catch (Exception e) {
-                            Log.w(TAG, "Invalid touch sound ID: "+id);
-                            continue;
-                        }
-
-                        int i = SOUND_EFFECT_FILES.indexOf(file);
-                        if (i == -1) {
-                            i = SOUND_EFFECT_FILES.size();
-                            SOUND_EFFECT_FILES.add(file);
-                        }
-                        SOUND_EFFECT_FILES_MAP[fx][0] = i;
-                    } else {
-                        break;
-                    }
+        public synchronized boolean waitForLoaded(int attempts) {
+            while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) {
+                try {
+                    wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
+                } catch (InterruptedException e) {
+                    Log.w(TAG, "Interrupted while waiting sound pool loaded.");
                 }
             }
-        } catch (Resources.NotFoundException e) {
-            Log.w(TAG, "audio assets file not found", e);
-        } catch (XmlPullParserException e) {
-            Log.w(TAG, "XML parser exception reading touch sound assets", e);
-        } catch (IOException e) {
-            Log.w(TAG, "I/O exception reading touch sound assets", e);
-        } finally {
-            if (parser != null) {
-                parser.close();
-            }
+            return mStatus == SOUND_EFFECTS_LOADED;
         }
     }
 
@@ -3444,20 +3391,9 @@
      * This method must be called at first when sound effects are enabled
      */
     public boolean loadSoundEffects() {
-        int attempts = 3;
         LoadSoundEffectReply reply = new LoadSoundEffectReply();
-
-        synchronized (reply) {
-            sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
-            while ((reply.mStatus == 1) && (attempts-- > 0)) {
-                try {
-                    reply.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
-                } catch (InterruptedException e) {
-                    Log.w(TAG, "loadSoundEffects Interrupted while waiting sound pool loaded.");
-                }
-            }
-        }
-        return (reply.mStatus == 0);
+        sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
+        return reply.waitForLoaded(3 /*attempts*/);
     }
 
     /**
@@ -3477,61 +3413,6 @@
         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
     }
 
-    class SoundPoolListenerThread extends Thread {
-        public SoundPoolListenerThread() {
-            super("SoundPoolListenerThread");
-        }
-
-        @Override
-        public void run() {
-
-            Looper.prepare();
-            mSoundPoolLooper = Looper.myLooper();
-
-            synchronized (mSoundEffectsLock) {
-                if (mSoundPool != null) {
-                    mSoundPoolCallBack = new SoundPoolCallback();
-                    mSoundPool.setOnLoadCompleteListener(mSoundPoolCallBack);
-                }
-                mSoundEffectsLock.notify();
-            }
-            Looper.loop();
-        }
-    }
-
-    private final class SoundPoolCallback implements
-            android.media.SoundPool.OnLoadCompleteListener {
-
-        int mStatus = 1; // 1 means neither error nor last sample loaded yet
-        List<Integer> mSamples = new ArrayList<Integer>();
-
-        public int status() {
-            return mStatus;
-        }
-
-        public void setSamples(int[] samples) {
-            for (int i = 0; i < samples.length; i++) {
-                // do not wait ack for samples rejected upfront by SoundPool
-                if (samples[i] > 0) {
-                    mSamples.add(samples[i]);
-                }
-            }
-        }
-
-        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
-            synchronized (mSoundEffectsLock) {
-                int i = mSamples.indexOf(sampleId);
-                if (i >= 0) {
-                    mSamples.remove(i);
-                }
-                if ((status != 0) || mSamples. isEmpty()) {
-                    mStatus = status;
-                    mSoundEffectsLock.notify();
-                }
-            }
-        }
-    }
-
     /** @see AudioManager#reloadAudioSettings() */
     public void reloadAudioSettings() {
         readAudioSettings(false /*userSwitch*/);
@@ -4348,6 +4229,11 @@
             throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
                     + " (dis)connection, got " + state);
         }
+        if (state == BluetoothProfile.STATE_CONNECTED) {
+            mPlaybackMonitor.registerPlaybackCallback(mVoiceActivityMonitor, true);
+        } else {
+            mPlaybackMonitor.unregisterPlaybackCallback(mVoiceActivityMonitor);
+        }
         mDeviceBroker.postBluetoothHearingAidDeviceConnectionState(
                 device, state, suppressNoisyIntent, musicDevice, "AudioService");
     }
@@ -4582,6 +4468,16 @@
             return index;
         }
 
+        private void setStreamVolumeIndex(int index, int device) {
+            // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
+            // This allows RX path muting by the audio HAL only when explicitly muted but not when
+            // index is just set to 0 to repect BT requirements
+            if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0 && !mIsMuted) {
+                index = 1;
+            }
+            AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
+        }
+
         // must be called while synchronized VolumeStreamState.class
         /*package*/ void applyDeviceVolume_syncVSS(int device, boolean isAvrcpAbsVolSupported) {
             int index;
@@ -4596,7 +4492,7 @@
             } else {
                 index = (getIndex(device) + 5)/10;
             }
-            AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
+            setStreamVolumeIndex(index, device);
         }
 
         public void applyAllVolumes() {
@@ -4619,7 +4515,7 @@
                         } else {
                             index = (mIndexMap.valueAt(i) + 5)/10;
                         }
-                        AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
+                        setStreamVolumeIndex(index, device);
                     }
                 }
                 // apply default volume last: by convention , default device volume will be used
@@ -4629,8 +4525,7 @@
                 } else {
                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
                 }
-                AudioSystem.setStreamVolumeIndexAS(
-                        mStreamType, index, AudioSystem.DEVICE_OUT_DEFAULT);
+                setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
             }
         }
 
@@ -4730,24 +4625,6 @@
         }
 
         /**
-         * Updates the min/max index values from another stream. Use this when changing the alias
-         * for the current stream type.
-         * @param sourceStreamType
-         */
-        // must be sync'd on mSettingsLock before VolumeStreamState.class
-        @GuardedBy("VolumeStreamState.class")
-        public void refreshRange(int sourceStreamType) {
-            mIndexMin = MIN_STREAM_VOLUME[sourceStreamType] * 10;
-            mIndexMax = MAX_STREAM_VOLUME[sourceStreamType] * 10;
-            // verify all current volumes are within bounds
-            for (int i = 0 ; i < mIndexMap.size(); i++) {
-                final int device = mIndexMap.keyAt(i);
-                final int index = mIndexMap.valueAt(i);
-                mIndexMap.put(device, getValidIndex(index));
-            }
-        }
-
-        /**
          * Copies all device/index pairs from the given VolumeStreamState after initializing
          * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
          * has the same stream type as this instance.
@@ -4853,6 +4730,7 @@
             pw.println((mIndexMin + 5) / 10);
             pw.print("   Max: ");
             pw.println((mIndexMax + 5) / 10);
+            pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
             pw.print("   Current: ");
             for (int i = 0; i < mIndexMap.size(); i++) {
                 if (i > 0) {
@@ -5055,230 +4933,6 @@
             Settings.Global.putInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode);
         }
 
-        private String getSoundEffectFilePath(int effectType) {
-            String filePath = Environment.getProductDirectory() + SOUND_EFFECTS_PATH
-                    + SOUND_EFFECT_FILES.get(SOUND_EFFECT_FILES_MAP[effectType][0]);
-            if (!new File(filePath).isFile()) {
-                filePath = Environment.getRootDirectory() + SOUND_EFFECTS_PATH
-                        + SOUND_EFFECT_FILES.get(SOUND_EFFECT_FILES_MAP[effectType][0]);
-            }
-            return filePath;
-        }
-
-        private boolean onLoadSoundEffects() {
-            int status;
-
-            synchronized (mSoundEffectsLock) {
-                if (!mSystemReady) {
-                    Log.w(TAG, "onLoadSoundEffects() called before boot complete");
-                    return false;
-                }
-
-                if (mSoundPool != null) {
-                    return true;
-                }
-
-                loadTouchSoundAssets();
-
-                mSoundPool = new SoundPool.Builder()
-                        .setMaxStreams(NUM_SOUNDPOOL_CHANNELS)
-                        .setAudioAttributes(new AudioAttributes.Builder()
-                            .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
-                            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                            .build())
-                        .build();
-                mSoundPoolCallBack = null;
-                mSoundPoolListenerThread = new SoundPoolListenerThread();
-                mSoundPoolListenerThread.start();
-                int attempts = 3;
-                while ((mSoundPoolCallBack == null) && (attempts-- > 0)) {
-                    try {
-                        // Wait for mSoundPoolCallBack to be set by the other thread
-                        mSoundEffectsLock.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
-                    } catch (InterruptedException e) {
-                        Log.w(TAG, "Interrupted while waiting sound pool listener thread.");
-                    }
-                }
-
-                if (mSoundPoolCallBack == null) {
-                    Log.w(TAG, "onLoadSoundEffects() SoundPool listener or thread creation error");
-                    if (mSoundPoolLooper != null) {
-                        mSoundPoolLooper.quit();
-                        mSoundPoolLooper = null;
-                    }
-                    mSoundPoolListenerThread = null;
-                    mSoundPool.release();
-                    mSoundPool = null;
-                    return false;
-                }
-                /*
-                 * poolId table: The value -1 in this table indicates that corresponding
-                 * file (same index in SOUND_EFFECT_FILES[] has not been loaded.
-                 * Once loaded, the value in poolId is the sample ID and the same
-                 * sample can be reused for another effect using the same file.
-                 */
-                int[] poolId = new int[SOUND_EFFECT_FILES.size()];
-                for (int fileIdx = 0; fileIdx < SOUND_EFFECT_FILES.size(); fileIdx++) {
-                    poolId[fileIdx] = -1;
-                }
-                /*
-                 * Effects whose value in SOUND_EFFECT_FILES_MAP[effect][1] is -1 must be loaded.
-                 * If load succeeds, value in SOUND_EFFECT_FILES_MAP[effect][1] is > 0:
-                 * this indicates we have a valid sample loaded for this effect.
-                 */
-
-                int numSamples = 0;
-                for (int effect = 0; effect < AudioManager.NUM_SOUND_EFFECTS; effect++) {
-                    // Do not load sample if this effect uses the MediaPlayer
-                    if (SOUND_EFFECT_FILES_MAP[effect][1] == 0) {
-                        continue;
-                    }
-                    if (poolId[SOUND_EFFECT_FILES_MAP[effect][0]] == -1) {
-                        String filePath = getSoundEffectFilePath(effect);
-                        int sampleId = mSoundPool.load(filePath, 0);
-                        if (sampleId <= 0) {
-                            Log.w(TAG, "Soundpool could not load file: "+filePath);
-                        } else {
-                            SOUND_EFFECT_FILES_MAP[effect][1] = sampleId;
-                            poolId[SOUND_EFFECT_FILES_MAP[effect][0]] = sampleId;
-                            numSamples++;
-                        }
-                    } else {
-                        SOUND_EFFECT_FILES_MAP[effect][1] =
-                                poolId[SOUND_EFFECT_FILES_MAP[effect][0]];
-                    }
-                }
-                // wait for all samples to be loaded
-                if (numSamples > 0) {
-                    mSoundPoolCallBack.setSamples(poolId);
-
-                    attempts = 3;
-                    status = 1;
-                    while ((status == 1) && (attempts-- > 0)) {
-                        try {
-                            mSoundEffectsLock.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
-                            status = mSoundPoolCallBack.status();
-                        } catch (InterruptedException e) {
-                            Log.w(TAG, "Interrupted while waiting sound pool callback.");
-                        }
-                    }
-                } else {
-                    status = -1;
-                }
-
-                if (mSoundPoolLooper != null) {
-                    mSoundPoolLooper.quit();
-                    mSoundPoolLooper = null;
-                }
-                mSoundPoolListenerThread = null;
-                if (status != 0) {
-                    Log.w(TAG,
-                            "onLoadSoundEffects(), Error "+status+ " while loading samples");
-                    for (int effect = 0; effect < AudioManager.NUM_SOUND_EFFECTS; effect++) {
-                        if (SOUND_EFFECT_FILES_MAP[effect][1] > 0) {
-                            SOUND_EFFECT_FILES_MAP[effect][1] = -1;
-                        }
-                    }
-
-                    mSoundPool.release();
-                    mSoundPool = null;
-                }
-            }
-            return (status == 0);
-        }
-
-        /**
-         *  Unloads samples from the sound pool.
-         *  This method can be called to free some memory when
-         *  sound effects are disabled.
-         */
-        private void onUnloadSoundEffects() {
-            synchronized (mSoundEffectsLock) {
-                if (mSoundPool == null) {
-                    return;
-                }
-
-                int[] poolId = new int[SOUND_EFFECT_FILES.size()];
-                for (int fileIdx = 0; fileIdx < SOUND_EFFECT_FILES.size(); fileIdx++) {
-                    poolId[fileIdx] = 0;
-                }
-
-                for (int effect = 0; effect < AudioManager.NUM_SOUND_EFFECTS; effect++) {
-                    if (SOUND_EFFECT_FILES_MAP[effect][1] <= 0) {
-                        continue;
-                    }
-                    if (poolId[SOUND_EFFECT_FILES_MAP[effect][0]] == 0) {
-                        mSoundPool.unload(SOUND_EFFECT_FILES_MAP[effect][1]);
-                        SOUND_EFFECT_FILES_MAP[effect][1] = -1;
-                        poolId[SOUND_EFFECT_FILES_MAP[effect][0]] = -1;
-                    }
-                }
-                mSoundPool.release();
-                mSoundPool = null;
-            }
-        }
-
-        private void onPlaySoundEffect(int effectType, int volume) {
-            synchronized (mSoundEffectsLock) {
-
-                onLoadSoundEffects();
-
-                if (mSoundPool == null) {
-                    return;
-                }
-                float volFloat;
-                // use default if volume is not specified by caller
-                if (volume < 0) {
-                    volFloat = (float)Math.pow(10, (float)sSoundEffectVolumeDb/20);
-                } else {
-                    volFloat = volume / 1000.0f;
-                }
-
-                if (SOUND_EFFECT_FILES_MAP[effectType][1] > 0) {
-                    mSoundPool.play(SOUND_EFFECT_FILES_MAP[effectType][1],
-                                        volFloat, volFloat, 0, 0, 1.0f);
-                } else {
-                    MediaPlayer mediaPlayer = new MediaPlayer();
-                    try {
-                        String filePath = getSoundEffectFilePath(effectType);
-                        mediaPlayer.setDataSource(filePath);
-                        mediaPlayer.setAudioStreamType(AudioSystem.STREAM_SYSTEM);
-                        mediaPlayer.prepare();
-                        mediaPlayer.setVolume(volFloat);
-                        mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
-                            public void onCompletion(MediaPlayer mp) {
-                                cleanupPlayer(mp);
-                            }
-                        });
-                        mediaPlayer.setOnErrorListener(new OnErrorListener() {
-                            public boolean onError(MediaPlayer mp, int what, int extra) {
-                                cleanupPlayer(mp);
-                                return true;
-                            }
-                        });
-                        mediaPlayer.start();
-                    } catch (IOException ex) {
-                        Log.w(TAG, "MediaPlayer IOException: "+ex);
-                    } catch (IllegalArgumentException ex) {
-                        Log.w(TAG, "MediaPlayer IllegalArgumentException: "+ex);
-                    } catch (IllegalStateException ex) {
-                        Log.w(TAG, "MediaPlayer IllegalStateException: "+ex);
-                    }
-                }
-            }
-        }
-
-        private void cleanupPlayer(MediaPlayer mp) {
-            if (mp != null) {
-                try {
-                    mp.stop();
-                    mp.release();
-                } catch (IllegalStateException ex) {
-                    Log.w(TAG, "MediaPlayer IllegalStateException: "+ex);
-                }
-            }
-        }
-
         private void onPersistSafeVolumeState(int state) {
             Settings.Global.putInt(mContentResolver,
                     Settings.Global.AUDIO_SAFE_VOLUME_STATE,
@@ -5325,24 +4979,25 @@
                     break;
 
                 case MSG_UNLOAD_SOUND_EFFECTS:
-                    onUnloadSoundEffects();
+                    mSfxHelper.unloadSoundEffects();
                     break;
 
                 case MSG_LOAD_SOUND_EFFECTS:
-                    //FIXME: onLoadSoundEffects() should be executed in a separate thread as it
-                    // can take several dozens of milliseconds to complete
-                    boolean loaded = onLoadSoundEffects();
-                    if (msg.obj != null) {
-                        LoadSoundEffectReply reply = (LoadSoundEffectReply)msg.obj;
-                        synchronized (reply) {
-                            reply.mStatus = loaded ? 0 : -1;
-                            reply.notify();
+                {
+                    LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj;
+                    if (mSystemReady) {
+                        mSfxHelper.loadSoundEffects(reply);
+                    } else {
+                        Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete");
+                        if (reply != null) {
+                            reply.run(false);
                         }
                     }
+                }
                     break;
 
                 case MSG_PLAY_SOUND_EFFECT:
-                    onPlaySoundEffect(msg.arg1, msg.arg2);
+                    mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
                     break;
 
                 case MSG_SET_FORCE_USE:
@@ -5429,6 +5084,11 @@
 
                 case MSG_HDMI_VOLUME_CHECK:
                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
+                    break;
+
+                case MSG_PLAYBACK_CONFIG_CHANGE:
+                    onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
+                    break;
             }
         }
     }
@@ -5463,6 +5123,8 @@
 
             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
+            mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.RTT_CALLING_MODE), false, this);
         }
 
         @Override
@@ -5486,6 +5148,7 @@
                 updateEncodedSurroundOutput();
                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
                 updateAssistantUId(false);
+                updateRttEanbled(mContentResolver);
             }
         }
 
@@ -5508,6 +5171,8 @@
 
     public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
         // address is not used for now, but may be used when multiple a2dp devices are supported
+        sVolumeLogger.log(new AudioEventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
+                + address + " support=" + support));
         mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support);
         sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
@@ -5516,6 +5181,7 @@
 
     /**
      * @return true if there is currently a registered dynamic mixing policy that affects media
+     * and is not a render + loopback policy
      */
     /*package*/ boolean hasMediaDynamicPolicy() {
         synchronized (mAudioPolicies) {
@@ -5524,7 +5190,8 @@
             }
             final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values();
             for (AudioPolicyProxy app : appColl) {
-                if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA)) {
+                if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA,
+                        AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
                     return true;
                 }
             }
@@ -6317,6 +5984,12 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
+        if (mAudioHandler != null) {
+            pw.println("\nMessage handler (watch for unhandled messages):");
+            mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");
+        } else {
+            pw.println("\nMessage handler is null");
+        }
         mMediaFocusControl.dump(pw);
         dumpStreamStates(pw);
         dumpRingerMode(pw);
@@ -6352,11 +6025,14 @@
 
         dumpAudioPolicies(pw);
         mDynPolicyLogger.dump(pw);
-
         mPlaybackMonitor.dump(pw);
-
         mRecordMonitor.dump(pw);
 
+        pw.println("\nAudioDeviceBroker:");
+        mDeviceBroker.dump(pw, "  ");
+        pw.println("\nSoundEffects:");
+        mSfxHelper.dump(pw, "  ");
+
         pw.println("\n");
         pw.println("\nEvent logs:");
         mModeLogger.dump(pw);
@@ -7287,9 +6963,10 @@
             Binder.restoreCallingIdentity(identity);
         }
 
-        boolean hasMixAffectingUsage(int usage) {
+        boolean hasMixAffectingUsage(int usage, int excludedFlags) {
             for (AudioMix mix : mMixes) {
-                if (mix.isAffectingUsage(usage)) {
+                if (mix.isAffectingUsage(usage)
+                        && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) {
                     return true;
                 }
             }
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index d999217..fcd8701 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -95,6 +95,8 @@
         static final int VOL_SET_HEARING_AID_VOL = 3;
         static final int VOL_SET_AVRCP_VOL = 4;
         static final int VOL_ADJUST_VOL_UID = 5;
+        static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6;
+        static final int VOL_MODE_CHANGE_HEARING_AID = 7;
 
         final int mOp;
         final int mStream;
@@ -102,6 +104,10 @@
         final int mVal2;
         final String mCaller;
 
+        /** used for VOL_ADJUST_VOL_UID,
+         *           VOL_ADJUST_SUGG_VOL,
+         *           VOL_ADJUST_STREAM_VOL,
+         *           VOL_SET_STREAM_VOL */
         VolumeEvent(int op, int stream, int val1, int val2, String caller) {
             mOp = op;
             mStream = stream;
@@ -110,24 +116,46 @@
             mCaller = caller;
         }
 
+        /** used for VOL_SET_HEARING_AID_VOL*/
         VolumeEvent(int op, int index, int gainDb) {
             mOp = op;
             mVal1 = index;
             mVal2 = gainDb;
-            //unused
+            // unused
             mStream = -1;
             mCaller = null;
         }
 
+        /** used for VOL_SET_AVRCP_VOL */
         VolumeEvent(int op, int index) {
             mOp = op;
             mVal1 = index;
-            //unused
+            // unused
             mVal2 = 0;
             mStream = -1;
             mCaller = null;
         }
 
+        /** used for VOL_VOICE_ACTIVITY_HEARING_AID */
+        VolumeEvent(int op, boolean voiceActive, int stream, int index) {
+            mOp = op;
+            mStream = stream;
+            mVal1 = index;
+            mVal2 = voiceActive ? 1 : 0;
+            // unused
+            mCaller = null;
+        }
+
+        /** used for VOL_MODE_CHANGE_HEARING_AID */
+        VolumeEvent(int op, int mode, int stream, int index) {
+            mOp = op;
+            mStream = stream;
+            mVal1 = index;
+            mVal2 = mode;
+            // unused
+            mCaller = null;
+        }
+
         @Override
         public String eventToString() {
             switch (mOp) {
@@ -168,7 +196,19 @@
                             .append(" flags:0x").append(Integer.toHexString(mVal2))
                             .append(") from ").append(mCaller)
                             .toString();
-               default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
+                case VOL_VOICE_ACTIVITY_HEARING_AID:
+                    return new StringBuilder("Voice activity change (")
+                            .append(mVal2 == 1 ? "active" : "inactive")
+                            .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
+                            .append(" stream:").append(AudioSystem.streamToString(mStream))
+                            .toString();
+                case VOL_MODE_CHANGE_HEARING_AID:
+                    return new StringBuilder("setMode(")
+                            .append(AudioSystem.modeToString(mVal2))
+                            .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
+                            .append(" stream:").append(AudioSystem.streamToString(mStream))
+                            .toString();
+                default: return new StringBuilder("FIXME invalid op:").append(mOp).toString();
             }
         }
     }
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 934c7bf..1a63f8f 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -200,16 +200,20 @@
 
     /*package*/ synchronized void setAvrcpAbsoluteVolumeSupported(boolean supported) {
         mAvrcpAbsVolSupported = supported;
+        Log.i(TAG, "setAvrcpAbsoluteVolumeSupported supported=" + supported);
     }
 
     /*package*/ synchronized void setAvrcpAbsoluteVolumeIndex(int index) {
         if (mA2dp == null) {
             if (AudioService.DEBUG_VOL) {
-                Log.d(TAG, "setAvrcpAbsoluteVolumeIndex: bailing due to null mA2dp");
+                AudioService.sVolumeLogger.log(new AudioEventLogger.StringEvent(
+                        "setAvrcpAbsoluteVolumeIndex: bailing due to null mA2dp").printLog(TAG));
                 return;
             }
         }
         if (!mAvrcpAbsVolSupported) {
+            AudioService.sVolumeLogger.log(new AudioEventLogger.StringEvent(
+                    "setAvrcpAbsoluteVolumeIndex: abs vol not supported ").printLog(TAG));
             return;
         }
         if (AudioService.DEBUG_VOL) {
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index 5d31dbe..5c50962 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -86,6 +86,12 @@
             return mIsActive && mConfig != null;
         }
 
+        void release() {
+            if (mDeathHandler != null) {
+                mDeathHandler.release();
+            }
+        }
+
         // returns true if status of an active recording has changed
         boolean setActive(boolean active) {
             if (mIsActive == active) return false;
@@ -417,6 +423,7 @@
                     break;
                 case AudioManager.RECORD_CONFIG_EVENT_RELEASE:
                     configChanged = state.isActiveConfiguration();
+                    state.release();
                     mRecordStates.remove(stateIndex);
                     break;
                 default:
@@ -519,6 +526,10 @@
                 return false;
             }
         }
+
+        void release() {
+            mRecorderToken.unlinkToDeath(this, 0);
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/audio/SoundEffectsHelper.java b/services/core/java/com/android/server/audio/SoundEffectsHelper.java
new file mode 100644
index 0000000..cf5bc8d
--- /dev/null
+++ b/services/core/java/com/android/server/audio/SoundEffectsHelper.java
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.audio;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.AudioSystem;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnErrorListener;
+import android.media.SoundPool;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.util.PrintWriterPrinter;
+
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A helper class for managing sound effects loading / unloading
+ * used by AudioService. As its methods are called on the message handler thread
+ * of AudioService, the actual work is offloaded to a dedicated thread.
+ * This helps keeping AudioService responsive.
+ * @hide
+ */
+class SoundEffectsHelper {
+    private static final String TAG = "AS.SfxHelper";
+
+    private static final int NUM_SOUNDPOOL_CHANNELS = 4;
+
+    /* Sound effect file names  */
+    private static final String SOUND_EFFECTS_PATH = "/media/audio/ui/";
+
+    private static final int EFFECT_NOT_IN_SOUND_POOL = 0; // SoundPool sample IDs > 0
+
+    private static final int MSG_LOAD_EFFECTS = 0;
+    private static final int MSG_UNLOAD_EFFECTS = 1;
+    private static final int MSG_PLAY_EFFECT = 2;
+    private static final int MSG_LOAD_EFFECTS_TIMEOUT = 3;
+
+    interface OnEffectsLoadCompleteHandler {
+        void run(boolean success);
+    }
+
+    private final AudioEventLogger mSfxLogger = new AudioEventLogger(
+            AudioManager.NUM_SOUND_EFFECTS + 10, "Sound Effects Loading");
+
+    private final Context mContext;
+    // default attenuation applied to sound played with playSoundEffect()
+    private final int mSfxAttenuationDb;
+
+    // thread for doing all work
+    private SfxWorker mSfxWorker;
+    // thread's message handler
+    private SfxHandler mSfxHandler;
+
+    private static final class Resource {
+        final String mFileName;
+        int mSampleId;
+        boolean mLoaded;  // for effects in SoundPool
+        Resource(String fileName) {
+            mFileName = fileName;
+            mSampleId = EFFECT_NOT_IN_SOUND_POOL;
+        }
+    }
+    // All the fields below are accessed by the worker thread exclusively
+    private final List<Resource> mResources = new ArrayList<Resource>();
+    private final int[] mEffects = new int[AudioManager.NUM_SOUND_EFFECTS]; // indexes in mResources
+    private SoundPool mSoundPool;
+    private SoundPoolLoader mSoundPoolLoader;
+
+    SoundEffectsHelper(Context context) {
+        mContext = context;
+        mSfxAttenuationDb = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_soundEffectVolumeDb);
+        startWorker();
+    }
+
+    /*package*/ void loadSoundEffects(OnEffectsLoadCompleteHandler onComplete) {
+        sendMsg(MSG_LOAD_EFFECTS, 0, 0, onComplete, 0);
+    }
+
+    /**
+     *  Unloads samples from the sound pool.
+     *  This method can be called to free some memory when
+     *  sound effects are disabled.
+     */
+    /*package*/ void unloadSoundEffects() {
+        sendMsg(MSG_UNLOAD_EFFECTS, 0, 0, null, 0);
+    }
+
+    /*package*/ void playSoundEffect(int effect, int volume) {
+        sendMsg(MSG_PLAY_EFFECT, effect, volume, null, 0);
+    }
+
+    /*package*/ void dump(PrintWriter pw, String prefix) {
+        if (mSfxHandler != null) {
+            pw.println(prefix + "Message handler (watch for unhandled messages):");
+            mSfxHandler.dump(new PrintWriterPrinter(pw), "  ");
+        } else {
+            pw.println(prefix + "Message handler is null");
+        }
+        pw.println(prefix + "Default attenuation (dB): " + mSfxAttenuationDb);
+        mSfxLogger.dump(pw);
+    }
+
+    private void startWorker() {
+        mSfxWorker = new SfxWorker();
+        mSfxWorker.start();
+        synchronized (this) {
+            while (mSfxHandler == null) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    Log.w(TAG, "Interrupted while waiting " + mSfxWorker.getName() + " to start");
+                }
+            }
+        }
+    }
+
+    private void sendMsg(int msg, int arg1, int arg2, Object obj, int delayMs) {
+        mSfxHandler.sendMessageDelayed(mSfxHandler.obtainMessage(msg, arg1, arg2, obj), delayMs);
+    }
+
+    private void logEvent(String msg) {
+        mSfxLogger.log(new AudioEventLogger.StringEvent(msg));
+    }
+
+    // All the methods below run on the worker thread
+    private void onLoadSoundEffects(OnEffectsLoadCompleteHandler onComplete) {
+        if (mSoundPoolLoader != null) {
+            // Loading is ongoing.
+            mSoundPoolLoader.addHandler(onComplete);
+            return;
+        }
+        if (mSoundPool != null) {
+            if (onComplete != null) {
+                onComplete.run(true /*success*/);
+            }
+            return;
+        }
+
+        logEvent("effects loading started");
+        mSoundPool = new SoundPool.Builder()
+                .setMaxStreams(NUM_SOUNDPOOL_CHANNELS)
+                .setAudioAttributes(new AudioAttributes.Builder()
+                        .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+                        .build())
+                .build();
+        loadTouchSoundAssets();
+
+        mSoundPoolLoader = new SoundPoolLoader();
+        mSoundPoolLoader.addHandler(new OnEffectsLoadCompleteHandler() {
+            @Override
+            public void run(boolean success) {
+                mSoundPoolLoader = null;
+                if (!success) {
+                    Log.w(TAG, "onLoadSoundEffects(), Error while loading samples");
+                    onUnloadSoundEffects();
+                }
+            }
+        });
+        mSoundPoolLoader.addHandler(onComplete);
+
+        int resourcesToLoad = 0;
+        for (Resource res : mResources) {
+            String filePath = getResourceFilePath(res);
+            int sampleId = mSoundPool.load(filePath, 0);
+            if (sampleId > 0) {
+                res.mSampleId = sampleId;
+                res.mLoaded = false;
+                resourcesToLoad++;
+            } else {
+                logEvent("effect " + filePath + " rejected by SoundPool");
+                Log.w(TAG, "SoundPool could not load file: " + filePath);
+            }
+        }
+
+        if (resourcesToLoad > 0) {
+            sendMsg(MSG_LOAD_EFFECTS_TIMEOUT, 0, 0, null, SOUND_EFFECTS_LOAD_TIMEOUT_MS);
+        } else {
+            logEvent("effects loading completed, no effects to load");
+            mSoundPoolLoader.onComplete(true /*success*/);
+        }
+    }
+
+    void onUnloadSoundEffects() {
+        if (mSoundPool == null) {
+            return;
+        }
+        if (mSoundPoolLoader != null) {
+            mSoundPoolLoader.addHandler(new OnEffectsLoadCompleteHandler() {
+                @Override
+                public void run(boolean success) {
+                    onUnloadSoundEffects();
+                }
+            });
+        }
+
+        logEvent("effects unloading started");
+        for (Resource res : mResources) {
+            if (res.mSampleId != EFFECT_NOT_IN_SOUND_POOL) {
+                mSoundPool.unload(res.mSampleId);
+            }
+        }
+        mSoundPool.release();
+        mSoundPool = null;
+        logEvent("effects unloading completed");
+    }
+
+    void onPlaySoundEffect(int effect, int volume) {
+        float volFloat;
+        // use default if volume is not specified by caller
+        if (volume < 0) {
+            volFloat = (float) Math.pow(10, (float) mSfxAttenuationDb / 20);
+        } else {
+            volFloat = volume / 1000.0f;
+        }
+
+        Resource res = mResources.get(mEffects[effect]);
+        if (res.mSampleId != EFFECT_NOT_IN_SOUND_POOL && res.mLoaded) {
+            mSoundPool.play(res.mSampleId, volFloat, volFloat, 0, 0, 1.0f);
+        } else {
+            MediaPlayer mediaPlayer = new MediaPlayer();
+            try {
+                String filePath = getResourceFilePath(res);
+                mediaPlayer.setDataSource(filePath);
+                mediaPlayer.setAudioStreamType(AudioSystem.STREAM_SYSTEM);
+                mediaPlayer.prepare();
+                mediaPlayer.setVolume(volFloat);
+                mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
+                    public void onCompletion(MediaPlayer mp) {
+                        cleanupPlayer(mp);
+                    }
+                });
+                mediaPlayer.setOnErrorListener(new OnErrorListener() {
+                    public boolean onError(MediaPlayer mp, int what, int extra) {
+                        cleanupPlayer(mp);
+                        return true;
+                    }
+                });
+                mediaPlayer.start();
+            } catch (IOException ex) {
+                Log.w(TAG, "MediaPlayer IOException: " + ex);
+            } catch (IllegalArgumentException ex) {
+                Log.w(TAG, "MediaPlayer IllegalArgumentException: " + ex);
+            } catch (IllegalStateException ex) {
+                Log.w(TAG, "MediaPlayer IllegalStateException: " + ex);
+            }
+        }
+    }
+
+    private static void cleanupPlayer(MediaPlayer mp) {
+        if (mp != null) {
+            try {
+                mp.stop();
+                mp.release();
+            } catch (IllegalStateException ex) {
+                Log.w(TAG, "MediaPlayer IllegalStateException: " + ex);
+            }
+        }
+    }
+
+    private static final String TAG_AUDIO_ASSETS = "audio_assets";
+    private static final String ATTR_VERSION = "version";
+    private static final String TAG_GROUP = "group";
+    private static final String ATTR_GROUP_NAME = "name";
+    private static final String TAG_ASSET = "asset";
+    private static final String ATTR_ASSET_ID = "id";
+    private static final String ATTR_ASSET_FILE = "file";
+
+    private static final String ASSET_FILE_VERSION = "1.0";
+    private static final String GROUP_TOUCH_SOUNDS = "touch_sounds";
+
+    private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 15000;
+
+    private String getResourceFilePath(Resource res) {
+        String filePath = Environment.getProductDirectory() + SOUND_EFFECTS_PATH + res.mFileName;
+        if (!new File(filePath).isFile()) {
+            filePath = Environment.getRootDirectory() + SOUND_EFFECTS_PATH + res.mFileName;
+        }
+        return filePath;
+    }
+
+    private void loadTouchSoundAssetDefaults() {
+        int defaultResourceIdx = mResources.size();
+        mResources.add(new Resource("Effect_Tick.ogg"));
+        for (int i = 0; i < mEffects.length; i++) {
+            mEffects[i] = defaultResourceIdx;
+        }
+    }
+
+    private void loadTouchSoundAssets() {
+        XmlResourceParser parser = null;
+
+        // only load assets once.
+        if (!mResources.isEmpty()) {
+            return;
+        }
+
+        loadTouchSoundAssetDefaults();
+
+        try {
+            parser = mContext.getResources().getXml(com.android.internal.R.xml.audio_assets);
+
+            XmlUtils.beginDocument(parser, TAG_AUDIO_ASSETS);
+            String version = parser.getAttributeValue(null, ATTR_VERSION);
+            boolean inTouchSoundsGroup = false;
+
+            if (ASSET_FILE_VERSION.equals(version)) {
+                while (true) {
+                    XmlUtils.nextElement(parser);
+                    String element = parser.getName();
+                    if (element == null) {
+                        break;
+                    }
+                    if (element.equals(TAG_GROUP)) {
+                        String name = parser.getAttributeValue(null, ATTR_GROUP_NAME);
+                        if (GROUP_TOUCH_SOUNDS.equals(name)) {
+                            inTouchSoundsGroup = true;
+                            break;
+                        }
+                    }
+                }
+                while (inTouchSoundsGroup) {
+                    XmlUtils.nextElement(parser);
+                    String element = parser.getName();
+                    if (element == null) {
+                        break;
+                    }
+                    if (element.equals(TAG_ASSET)) {
+                        String id = parser.getAttributeValue(null, ATTR_ASSET_ID);
+                        String file = parser.getAttributeValue(null, ATTR_ASSET_FILE);
+                        int fx;
+
+                        try {
+                            Field field = AudioManager.class.getField(id);
+                            fx = field.getInt(null);
+                        } catch (Exception e) {
+                            Log.w(TAG, "Invalid touch sound ID: " + id);
+                            continue;
+                        }
+
+                        mEffects[fx] = findOrAddResourceByFileName(file);
+                    } else {
+                        break;
+                    }
+                }
+            }
+        } catch (Resources.NotFoundException e) {
+            Log.w(TAG, "audio assets file not found", e);
+        } catch (XmlPullParserException e) {
+            Log.w(TAG, "XML parser exception reading touch sound assets", e);
+        } catch (IOException e) {
+            Log.w(TAG, "I/O exception reading touch sound assets", e);
+        } finally {
+            if (parser != null) {
+                parser.close();
+            }
+        }
+    }
+
+    private int findOrAddResourceByFileName(String fileName) {
+        for (int i = 0; i < mResources.size(); i++) {
+            if (mResources.get(i).mFileName.equals(fileName)) {
+                return i;
+            }
+        }
+        int result = mResources.size();
+        mResources.add(new Resource(fileName));
+        return result;
+    }
+
+    private Resource findResourceBySampleId(int sampleId) {
+        for (Resource res : mResources) {
+            if (res.mSampleId == sampleId) {
+                return res;
+            }
+        }
+        return null;
+    }
+
+    private class SfxWorker extends Thread {
+        SfxWorker() {
+            super("AS.SfxWorker");
+        }
+
+        @Override
+        public void run() {
+            Looper.prepare();
+            synchronized (SoundEffectsHelper.this) {
+                mSfxHandler = new SfxHandler();
+                SoundEffectsHelper.this.notify();
+            }
+            Looper.loop();
+        }
+    }
+
+    private class SfxHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_LOAD_EFFECTS:
+                    onLoadSoundEffects((OnEffectsLoadCompleteHandler) msg.obj);
+                    break;
+                case MSG_UNLOAD_EFFECTS:
+                    onUnloadSoundEffects();
+                    break;
+                case MSG_PLAY_EFFECT:
+                    onLoadSoundEffects(new OnEffectsLoadCompleteHandler() {
+                        @Override
+                        public void run(boolean success) {
+                            if (success) {
+                                onPlaySoundEffect(msg.arg1 /*effect*/, msg.arg2 /*volume*/);
+                            }
+                        }
+                    });
+                    break;
+                case MSG_LOAD_EFFECTS_TIMEOUT:
+                    if (mSoundPoolLoader != null) {
+                        mSoundPoolLoader.onTimeout();
+                    }
+                    break;
+            }
+        }
+    }
+
+    private class SoundPoolLoader implements
+            android.media.SoundPool.OnLoadCompleteListener {
+
+        private List<OnEffectsLoadCompleteHandler> mLoadCompleteHandlers =
+                new ArrayList<OnEffectsLoadCompleteHandler>();
+
+        SoundPoolLoader() {
+            // SoundPool use the current Looper when creating its message handler.
+            // Since SoundPoolLoader is created on the SfxWorker thread, SoundPool's
+            // message handler ends up running on it (it's OK to have multiple
+            // handlers on the same Looper). Thus, onLoadComplete gets executed
+            // on the worker thread.
+            mSoundPool.setOnLoadCompleteListener(this);
+        }
+
+        void addHandler(OnEffectsLoadCompleteHandler handler) {
+            if (handler != null) {
+                mLoadCompleteHandlers.add(handler);
+            }
+        }
+
+        @Override
+        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
+            if (status == 0) {
+                int remainingToLoad = 0;
+                for (Resource res : mResources) {
+                    if (res.mSampleId == sampleId && !res.mLoaded) {
+                        logEvent("effect " + res.mFileName + " loaded");
+                        res.mLoaded = true;
+                    }
+                    if (res.mSampleId != EFFECT_NOT_IN_SOUND_POOL && !res.mLoaded) {
+                        remainingToLoad++;
+                    }
+                }
+                if (remainingToLoad == 0) {
+                    onComplete(true);
+                }
+            } else {
+                Resource res = findResourceBySampleId(sampleId);
+                String filePath;
+                if (res != null) {
+                    filePath = getResourceFilePath(res);
+                } else {
+                    filePath = "with unknown sample ID " + sampleId;
+                }
+                logEvent("effect " + filePath + " loading failed, status " + status);
+                Log.w(TAG, "onLoadSoundEffects(), Error " + status + " while loading sample "
+                        + filePath);
+                onComplete(false);
+            }
+        }
+
+        void onTimeout() {
+            onComplete(false);
+        }
+
+        void onComplete(boolean success) {
+            mSoundPool.setOnLoadCompleteListener(null);
+            for (OnEffectsLoadCompleteHandler handler : mLoadCompleteHandlers) {
+                handler.run(success);
+            }
+            logEvent("effects loading " + (success ? "completed" : "failed"));
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index b899d02..4a9ccde 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -46,6 +46,7 @@
     // authentication while the device is already locked out. In that case, the client is created
     // but not started yet. The user shouldn't receive the error haptics in this case.
     private boolean mStarted;
+    private long mStartTimeMs;
 
     /**
      * This method is called when authentication starts.
@@ -75,6 +76,10 @@
         mRequireConfirmation = requireConfirmation;
     }
 
+    protected long getStartTimeMs() {
+        return mStartTimeMs;
+    }
+
     @Override
     public void binderDied() {
         super.binderDied();
@@ -228,6 +233,7 @@
         mStarted = true;
         onStart();
         try {
+            mStartTimeMs = System.currentTimeMillis();
             final int result = getDaemonWrapper().authenticate(mOpId, getGroupId());
             if (result != 0) {
                 Slog.w(getLogTag(), "startAuthentication failed, result=" + result);
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index db17f83..bd3cd54 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -170,6 +170,8 @@
         // the authentication.
         byte[] mTokenEscrow;
 
+        // Timestamp when authentication started
+        private long mStartTimeMs;
         // Timestamp when hardware authentication occurred
         private long mAuthenticatedTimeMs;
 
@@ -519,8 +521,8 @@
             List<EnabledOnKeyguardCallback> callbacks = mEnabledOnKeyguardCallbacks;
             for (int i = 0; i < callbacks.size(); i++) {
                 callbacks.get(i).notify(BiometricSourceType.FACE,
-                        mFaceEnabledOnKeyguard.getOrDefault(userId,
-                                DEFAULT_KEYGUARD_ENABLED));
+                        mFaceEnabledOnKeyguard.getOrDefault(userId, DEFAULT_KEYGUARD_ENABLED),
+                        userId);
             }
         }
     }
@@ -538,9 +540,9 @@
             }
         }
 
-        void notify(BiometricSourceType sourceType, boolean enabled) {
+        void notify(BiometricSourceType sourceType, boolean enabled, int userId) {
             try {
-                mCallback.onChanged(sourceType, enabled);
+                mCallback.onChanged(sourceType, enabled, userId);
             } catch (DeadObjectException e) {
                 Slog.w(TAG, "Death while invoking notify", e);
                 mEnabledOnKeyguardCallbacks.remove(this);
@@ -766,10 +768,16 @@
         }
 
         @Override // Binder call
-        public int canAuthenticate(String opPackageName) {
-            checkPermission();
+        public int canAuthenticate(String opPackageName, int userId) {
+            Slog.d(TAG, "canAuthenticate: User=" + userId
+                    + ", Caller=" + UserHandle.getCallingUserId());
 
-            final int userId = UserHandle.getCallingUserId();
+            if (userId != UserHandle.getCallingUserId()) {
+                checkInternalPermission();
+            } else {
+                checkPermission();
+            }
+
             final long ident = Binder.clearCallingIdentity();
             int error;
             try {
@@ -788,7 +796,8 @@
             mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback));
             try {
                 callback.onChanged(BiometricSourceType.FACE,
-                        mSettingObserver.getFaceEnabledOnKeyguard());
+                        mSettingObserver.getFaceEnabledOnKeyguard(),
+                        UserHandle.getCallingUserId());
             } catch (RemoteException e) {
                 Slog.w(TAG, "Remote exception", e);
             }
@@ -965,6 +974,11 @@
             }
         }
 
+        Slog.d(TAG, "checkAndGetBiometricModality: user=" + userId
+                + " isHardwareDetected=" + isHardwareDetected
+                + " hasTemplatesEnrolled=" + hasTemplatesEnrolled
+                + " enabledForApps=" + enabledForApps);
+
         // Check error conditions
         if (!isHardwareDetected) {
             return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
@@ -1065,6 +1079,9 @@
                     latency,
                     Utils.isDebugEnabled(getContext(), mCurrentAuthSession.mUserId));
         } else {
+
+            final long latency = System.currentTimeMillis() - mCurrentAuthSession.mStartTimeMs;
+
             int error = reason == BiometricPrompt.DISMISSED_REASON_NEGATIVE
                     ? BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON
                     : reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL
@@ -1076,7 +1093,8 @@
                         + ", IsCrypto: " + mCurrentAuthSession.isCrypto()
                         + ", Action: " + BiometricsProtoEnums.ACTION_AUTHENTICATE
                         + ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
-                        + ", Error: " + error);
+                        + ", Error: " + error
+                        + ", Latency: " + latency);
             }
             // Auth canceled
             StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
@@ -1087,7 +1105,8 @@
                     BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
                     error,
                     0 /* vendorCode */,
-                    Utils.isDebugEnabled(getContext(), mCurrentAuthSession.mUserId));
+                    Utils.isDebugEnabled(getContext(), mCurrentAuthSession.mUserId),
+                    latency);
         }
     }
 
@@ -1411,6 +1430,9 @@
                     && mCurrentAuthSession.mState == STATE_AUTH_PAUSED;
 
             mCurrentAuthSession = mPendingAuthSession;
+
+            // Time starts when lower layers are ready to start the client.
+            mCurrentAuthSession.mStartTimeMs = System.currentTimeMillis();
             mPendingAuthSession = null;
 
             mCurrentAuthSession.mState = STATE_AUTH_STARTED;
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index d3c62be..20eb618 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -497,9 +497,9 @@
         }
     }
 
-    private final class BiometricTaskStackListener extends TaskStackListener {
+    private final Runnable mOnTaskStackChangedRunnable = new Runnable() {
         @Override
-        public void onTaskStackChanged() {
+        public void run() {
             try {
                 if (!(mCurrentClient instanceof AuthenticationClient)) {
                     return;
@@ -514,8 +514,8 @@
                     final String topPackage = runningTasks.get(0).topActivity.getPackageName();
                     if (!topPackage.contentEquals(currentClient)
                             && !mCurrentClient.isAlreadyDone()) {
-                        Slog.e(getTag(), "Stopping background authentication, top: " + topPackage
-                                + " currentClient: " + currentClient);
+                        Slog.e(getTag(), "Stopping background authentication, top: "
+                                + topPackage + " currentClient: " + currentClient);
                         mCurrentClient.stop(false /* initiatedByClient */);
                     }
                 }
@@ -523,6 +523,13 @@
                 Slog.e(getTag(), "Unable to get running tasks", e);
             }
         }
+    };
+
+    private final class BiometricTaskStackListener extends TaskStackListener {
+        @Override
+        public void onTaskStackChanged() {
+            mHandler.post(mOnTaskStackChangedRunnable);
+        }
     }
 
     private final class ResetClientStateRunnable implements Runnable {
@@ -658,8 +665,12 @@
         mMetricsLogger.count(getConstants().tagHalDied(), 1);
         mHALDeathCount++;
         mCurrentUserId = UserHandle.USER_NULL;
-        handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                0 /*vendorCode */);
+
+        // All client lifecycle must be managed on the handler.
+        mHandler.post(() -> {
+            handleError(getHalDeviceId(), BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                    0 /*vendorCode */);
+        });
 
         StatsLog.write(StatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED, statsModality(),
                 BiometricsProtoEnums.ISSUE_HAL_DEATH);
@@ -713,8 +724,6 @@
             // already generated a new authenticator id when the new biometric is enrolled.
             if (identifier instanceof Fingerprint) {
                 updateActiveGroup(((Fingerprint)identifier).getGroupId(), null);
-            } else {
-                updateActiveGroup(mCurrentUserId, null);
             }
         }
     }
@@ -1090,6 +1099,8 @@
         if (DEBUG) Slog.v(getTag(), "starting client "
                 + mCurrentClient.getClass().getSuperclass().getSimpleName()
                 + "(" + mCurrentClient.getOwnerString() + ")"
+                + " targetUserId: " + mCurrentClient.getTargetUserId()
+                + " currentUserId: " + mCurrentUserId
                 + " cookie: " + cookie + "/" + mCurrentClient.getCookie());
         if (cookie != mCurrentClient.getCookie()) {
             Slog.e(getTag(), "Mismatched cookie");
diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java
index 421b3f5..942e050 100644
--- a/services/core/java/com/android/server/biometrics/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java
@@ -42,12 +42,7 @@
     private static final AudioAttributes FINGERPRINT_SONFICATION_ATTRIBUTES =
             new AudioAttributes.Builder()
                     .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                    // Temporary fix for b/123870990. No time in this release to
-                    // introduce a new vibration type, but we need to distinguish these vibrations
-                    // from other haptic feedback vibrations. Fortunately, Alarm vibrations have
-                    // exactly the same behavior as we need
-                    // TODO: refactor within the scope of b/132170758
-                    .setUsage(AudioAttributes.USAGE_ALARM)
+                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                     .build();
 
     private final Context mContext;
diff --git a/services/core/java/com/android/server/biometrics/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
index 9c04088..6c7cbc1 100644
--- a/services/core/java/com/android/server/biometrics/LoggableMonitor.java
+++ b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
@@ -33,6 +33,10 @@
 
     private long mFirstAcquireTimeMs;
 
+    protected long getFirstAcquireTimeMs() {
+        return mFirstAcquireTimeMs;
+    }
+
     /**
      * Only valid for AuthenticationClient.
      * @return true if the client is authenticating for a crypto operation.
@@ -94,6 +98,10 @@
     }
 
     protected final void logOnError(Context context, int error, int vendorCode, int targetUserId) {
+
+        final long latency = mFirstAcquireTimeMs != 0
+                ? (System.currentTimeMillis() - mFirstAcquireTimeMs) : -1;
+
         if (DEBUG) {
             Slog.v(TAG, "Error! Modality: " + statsModality()
                     + ", User: " + targetUserId
@@ -101,7 +109,10 @@
                     + ", Action: " + statsAction()
                     + ", Client: " + statsClient()
                     + ", Error: " + error
-                    + ", VendorCode: " + vendorCode);
+                    + ", VendorCode: " + vendorCode
+                    + ", Latency: " + latency);
+        } else {
+            Slog.v(TAG, "Error latency: " + latency);
         }
         StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
                 statsModality(),
@@ -111,7 +122,8 @@
                 statsClient(),
                 error,
                 vendorCode,
-                Utils.isDebugEnabled(context, targetUserId));
+                Utils.isDebugEnabled(context, targetUserId),
+                latency);
     }
 
     protected final void logOnAuthenticated(Context context, boolean authenticated,
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index 5544bed..4fa29ac 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -18,10 +18,15 @@
 
 import android.content.Context;
 import android.os.Build;
+import android.os.UserHandle;
 import android.provider.Settings;
 
 public class Utils {
     public static boolean isDebugEnabled(Context context, int targetUserId) {
+        if (targetUserId == UserHandle.USER_NULL) {
+            return false;
+        }
+
         if (!(Build.IS_ENG || Build.IS_USERDEBUG)) {
             return false;
         }
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 463a499..a38abdc 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -54,7 +54,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -64,6 +63,7 @@
 import com.android.server.biometrics.AuthenticationClient;
 import com.android.server.biometrics.BiometricServiceBase;
 import com.android.server.biometrics.BiometricUtils;
+import com.android.server.biometrics.ClientMonitor;
 import com.android.server.biometrics.Constants;
 import com.android.server.biometrics.EnumerateClient;
 import com.android.server.biometrics.RemovalClient;
@@ -79,7 +79,9 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * A service to manage multiple clients that want to access the face HAL API.
@@ -97,6 +99,107 @@
             "com.android.server.biometrics.face.ACTION_LOCKOUT_RESET";
     private static final int CHALLENGE_TIMEOUT_SEC = 600; // 10 minutes
 
+    private static final String NOTIFICATION_TAG = "FaceService";
+    private static final int NOTIFICATION_ID = 1;
+
+    /**
+     * Events for bugreports.
+     */
+    public static final class AuthenticationEvent {
+        private long mStartTime;
+        private long mLatency;
+        // Only valid if mError is 0
+        private boolean mAuthenticated;
+        private int mError;
+        // Only valid if mError is ERROR_VENDOR
+        private int mVendorError;
+
+        AuthenticationEvent(long startTime, long latency, boolean authenticated, int error,
+                int vendorError) {
+            mStartTime = startTime;
+            mLatency = latency;
+            mAuthenticated = authenticated;
+            mError = error;
+            mVendorError = vendorError;
+        }
+
+        public String toString(Context context) {
+            return "Start: " + mStartTime
+                    + "\tLatency: " + mLatency
+                    + "\tAuthenticated: " + mAuthenticated
+                    + "\tError: " + mError
+                    + "\tVendorCode: " + mVendorError
+                    + "\t" + FaceManager.getErrorString(context, mError, mVendorError);
+        }
+    }
+
+    /**
+     * Keep a short historical buffer of stats, with an aggregated usage time.
+     */
+    private class UsageStats {
+        static final int EVENT_LOG_SIZE = 100;
+
+        Context mContext;
+        List<AuthenticationEvent> mAuthenticationEvents;
+
+        int acceptCount;
+        int rejectCount;
+        Map<Integer, Integer> mErrorCount;
+
+        long acceptLatency;
+        long rejectLatency;
+        Map<Integer, Long> mErrorLatency;
+
+        UsageStats(Context context) {
+            mAuthenticationEvents = new ArrayList<>();
+            mErrorCount = new HashMap<>();
+            mErrorLatency = new HashMap<>();
+            mContext = context;
+        }
+
+        void addEvent(AuthenticationEvent event) {
+            if (mAuthenticationEvents.size() >= EVENT_LOG_SIZE) {
+                mAuthenticationEvents.remove(0);
+            }
+            mAuthenticationEvents.add(event);
+
+            if (event.mAuthenticated) {
+                acceptCount++;
+                acceptLatency += event.mLatency;
+            } else if (event.mError == 0) {
+                rejectCount++;
+                rejectLatency += event.mLatency;
+            } else {
+                mErrorCount.put(event.mError, mErrorCount.getOrDefault(event.mError, 0) + 1);
+                mErrorLatency.put(event.mError,
+                        mErrorLatency.getOrDefault(event.mError, 0l) + event.mLatency);
+            }
+        }
+
+        void print(PrintWriter pw) {
+            pw.println("Events since last reboot: " + mAuthenticationEvents.size());
+            for (int i = 0; i < mAuthenticationEvents.size(); i++) {
+                pw.println(mAuthenticationEvents.get(i).toString(mContext));
+            }
+
+            // Dump aggregated usage stats
+            // TODO: Remove or combine with json dump in a future release
+            pw.println("Accept\tCount: " + acceptCount + "\tLatency: " + acceptLatency
+                    + "\tAverage: " + (acceptCount > 0 ? acceptLatency / acceptCount : 0));
+            pw.println("Reject\tCount: " + rejectCount + "\tLatency: " + rejectLatency
+                    + "\tAverage: " + (rejectCount > 0 ? rejectLatency / rejectCount : 0));
+
+            for (Integer key : mErrorCount.keySet()) {
+                final int count = mErrorCount.get(key);
+                pw.println("Error" + key + "\tCount: " + count
+                        + "\tLatency: " + mErrorLatency.getOrDefault(key, 0l)
+                        + "\tAverage: " + (count > 0 ? mErrorLatency.getOrDefault(key, 0l) / count
+                        : 0)
+                        + "\t" + FaceManager.getErrorString(mContext, key, 0 /* vendorCode */));
+            }
+        }
+    }
+
     private final class FaceAuthClient extends AuthenticationClientImpl {
         private int mLastAcquire;
 
@@ -128,6 +231,13 @@
                 boolean authenticated, ArrayList<Byte> token) {
             final boolean result = super.onAuthenticated(identifier, authenticated, token);
 
+            mUsageStats.addEvent(new AuthenticationEvent(
+                    getStartTimeMs(),
+                    System.currentTimeMillis() - getStartTimeMs() /* latency */,
+                    authenticated,
+                    0 /* error */,
+                    0 /* vendorError */));
+
             // For face, the authentication lifecycle ends either when
             // 1) Authenticated == true
             // 2) Error occurred
@@ -138,6 +248,18 @@
         }
 
         @Override
+        public boolean onError(long deviceId, int error, int vendorCode) {
+            mUsageStats.addEvent(new AuthenticationEvent(
+                    getStartTimeMs(),
+                    System.currentTimeMillis() - getStartTimeMs() /* latency */,
+                    false /* authenticated */,
+                    error,
+                    vendorCode));
+
+            return super.onError(deviceId, error, vendorCode);
+        }
+
+        @Override
         public int[] getAcquireIgnorelist() {
             if (isBiometricPrompt()) {
                 return mBiometricPromptIgnoreList;
@@ -177,13 +299,11 @@
                         0 /* requestCode */, intent, 0 /* flags */, null /* options */,
                         UserHandle.CURRENT);
 
-                final String id = "FaceService";
+                final String channelName = "FaceEnrollNotificationChannel";
 
-                NotificationManager nm =
-                        getContext().getSystemService(NotificationManager.class);
-                NotificationChannel channel = new NotificationChannel(id, name,
+                NotificationChannel channel = new NotificationChannel(channelName, name,
                         NotificationManager.IMPORTANCE_HIGH);
-                Notification notification = new Notification.Builder(getContext(), id)
+                Notification notification = new Notification.Builder(getContext(), channelName)
                         .setSmallIcon(R.drawable.ic_lock)
                         .setContentTitle(title)
                         .setContentText(content)
@@ -193,10 +313,12 @@
                         .setAutoCancel(true)
                         .setCategory(Notification.CATEGORY_SYSTEM)
                         .setContentIntent(pendingIntent)
+                        .setVisibility(Notification.VISIBILITY_SECRET)
                         .build();
 
-                nm.createNotificationChannel(channel);
-                nm.notifyAsUser(null /* tag */, 0 /* id */, notification, UserHandle.CURRENT);
+                mNotificationManager.createNotificationChannel(channel);
+                mNotificationManager.notifyAsUser(NOTIFICATION_TAG, NOTIFICATION_ID, notification,
+                        UserHandle.CURRENT);
             }
 
             return super.onAcquired(acquireInfo, vendorCode);
@@ -221,14 +343,27 @@
         @Override // Binder call
         public int revokeChallenge(IBinder token) {
             checkPermission(MANAGE_BIOMETRIC);
-            return startRevokeChallenge(token);
+            // TODO(b/137106905): Schedule binder calls in FaceService to avoid deadlocks.
+            if (getCurrentClient() == null) {
+                // if we aren't handling any other HIDL calls (mCurrentClient == null), revoke the
+                // challenge right away.
+                return startRevokeChallenge(token);
+            } else {
+                // postpone revoking the challenge until we finish processing the current HIDL call.
+                mRevokeChallengePending = true;
+                return Status.OK;
+            }
         }
 
         @Override // Binder call
-        public void enroll(final IBinder token, final byte[] cryptoToken,
+        public void enroll(int userId, final IBinder token, final byte[] cryptoToken,
                 final IFaceServiceReceiver receiver, final String opPackageName,
                 final int[] disabledFeatures) {
             checkPermission(MANAGE_BIOMETRIC);
+            updateActiveGroup(userId, opPackageName);
+
+            mNotificationManager.cancelAsUser(NOTIFICATION_TAG, NOTIFICATION_ID,
+                    UserHandle.CURRENT);
 
             final boolean restricted = isRestricted();
             final EnrollClientImpl client = new EnrollClientImpl(getContext(), mDaemonWrapper,
@@ -324,8 +459,9 @@
 
         @Override // Binder call
         public void remove(final IBinder token, final int faceId, final int userId,
-                final IFaceServiceReceiver receiver) {
+                final IFaceServiceReceiver receiver, final String opPackageName) {
             checkPermission(MANAGE_BIOMETRIC);
+            updateActiveGroup(userId, opPackageName);
 
             if (token == null) {
                 Slog.w(TAG, "remove(): token is null");
@@ -378,8 +514,6 @@
             try {
                 if (args.length > 1 && "--hal".equals(args[0])) {
                     dumpHal(fd, Arrays.copyOfRange(args, 1, args.length, args.getClass()));
-                } else if (args.length > 0 && "--proto".equals(args[0])) {
-                    dumpProto(fd);
                 } else {
                     dumpInternal(pw);
                 }
@@ -480,6 +614,8 @@
                 return;
             }
 
+            Slog.d(TAG, "Resetting lockout for user: " + mCurrentUserId);
+
             try {
                 mDaemonWrapper.resetLockout(token);
             } catch (RemoteException e) {
@@ -488,9 +624,10 @@
         }
 
         @Override
-        public void setFeature(int feature, boolean enabled, final byte[] token,
-                IFaceServiceReceiver receiver) {
+        public void setFeature(int userId, int feature, boolean enabled, final byte[] token,
+                IFaceServiceReceiver receiver, final String opPackageName) {
             checkPermission(MANAGE_BIOMETRIC);
+            updateActiveGroup(userId, opPackageName);
 
             mHandler.post(() -> {
                 if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
@@ -520,8 +657,10 @@
         }
 
         @Override
-        public void getFeature(int feature, IFaceServiceReceiver receiver) {
+        public void getFeature(int userId, int feature, IFaceServiceReceiver receiver,
+                final String opPackageName) {
             checkPermission(MANAGE_BIOMETRIC);
+            updateActiveGroup(userId, opPackageName);
 
             mHandler.post(() -> {
                 // This should ideally return tri-state, but the user isn't shown settings unless
@@ -682,9 +821,13 @@
 
     @GuardedBy("this")
     private IBiometricsFace mDaemon;
+    private UsageStats mUsageStats;
+    private boolean mRevokeChallengePending = false;
     // One of the AuthenticationClient constants
     private int mCurrentUserLockoutMode;
 
+    private NotificationManager mNotificationManager;
+
     private int[] mBiometricPromptIgnoreList;
     private int[] mBiometricPromptIgnoreListVendor;
     private int[] mKeyguardIgnoreList;
@@ -704,6 +847,18 @@
                 final Face face = new Face(getBiometricUtils()
                         .getUniqueName(getContext(), userId), faceId, deviceId);
                 FaceService.super.handleEnrollResult(face, remaining);
+
+                // Enrollment changes the authenticatorId, so update it here.
+                IBiometricsFace daemon = getFaceDaemon();
+                if (remaining == 0 && daemon != null) {
+                    try {
+                        mAuthenticatorIds.put(userId,
+                                hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId().value
+                                        : 0L);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Unable to get authenticatorId", e);
+                    }
+                }
             });
         }
 
@@ -878,6 +1033,10 @@
     public FaceService(Context context) {
         super(context);
 
+        mUsageStats = new UsageStats(context);
+
+        mNotificationManager = getContext().getSystemService(NotificationManager.class);
+
         mBiometricPromptIgnoreList = getContext().getResources()
                 .getIntArray(R.array.config_face_acquire_biometricprompt_ignorelist);
         mBiometricPromptIgnoreListVendor = getContext().getResources()
@@ -893,10 +1052,22 @@
     }
 
     @Override
+    protected void removeClient(ClientMonitor client) {
+        super.removeClient(client);
+        if (mRevokeChallengePending) {
+            startRevokeChallenge(null);
+            mRevokeChallengePending = false;
+        }
+    }
+
+    @Override
     public void onStart() {
         super.onStart();
         publishBinderService(Context.FACE_SERVICE, new FaceServiceWrapper());
-        SystemServerInitThreadPool.get().submit(this::getFaceDaemon, TAG + ".onStart");
+        // Get the face daemon on FaceService's on thread so SystemServerInitThreadPool isn't
+        // blocked
+        SystemServerInitThreadPool.get().submit(() -> mHandler.post(this::getFaceDaemon),
+                TAG + ".onStart");
     }
 
     @Override
@@ -965,9 +1136,9 @@
 
                     daemon.setActiveUser(userId, faceDir.getAbsolutePath());
                     mCurrentUserId = userId;
+                    mAuthenticatorIds.put(userId,
+                            hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId().value : 0L);
                 }
-                mAuthenticatorIds.put(userId,
-                        hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId().value : 0L);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Failed to setActiveUser():", e);
             }
@@ -1100,7 +1271,11 @@
             return 0;
         }
         try {
-            return daemon.revokeChallenge();
+            final int res = daemon.revokeChallenge();
+            if (res != Status.OK) {
+                Slog.e(TAG, "revokeChallenge returned " + res);
+            }
+            return res;
         } catch (RemoteException e) {
             Slog.e(TAG, "startRevokeChallenge failed", e);
         }
@@ -1142,51 +1317,9 @@
             Slog.e(TAG, "dump formatting failure", e);
         }
         pw.println(dump);
-        pw.println("HAL Deaths: " + mHALDeathCount);
-        mHALDeathCount = 0;
-    }
+        pw.println("HAL deaths since last reboot: " + mHALDeathCount);
 
-    private void dumpProto(FileDescriptor fd) {
-        final ProtoOutputStream proto = new ProtoOutputStream(fd);
-        for (UserInfo user : UserManager.get(getContext()).getUsers()) {
-            final int userId = user.getUserHandle().getIdentifier();
-
-            final long userToken = proto.start(FaceServiceDumpProto.USERS);
-
-            proto.write(FaceUserStatsProto.USER_ID, userId);
-            proto.write(FaceUserStatsProto.NUM_FACES,
-                    getBiometricUtils().getBiometricsForUser(getContext(), userId).size());
-
-            // Normal face authentications (e.g. lockscreen)
-            final PerformanceStats normal = mPerformanceMap.get(userId);
-            if (normal != null) {
-                final long countsToken = proto.start(FaceUserStatsProto.NORMAL);
-                proto.write(FaceActionStatsProto.ACCEPT, normal.accept);
-                proto.write(FaceActionStatsProto.REJECT, normal.reject);
-                proto.write(FaceActionStatsProto.ACQUIRE, normal.acquire);
-                proto.write(FaceActionStatsProto.LOCKOUT, normal.lockout);
-                proto.write(FaceActionStatsProto.LOCKOUT_PERMANENT, normal.lockout);
-                proto.end(countsToken);
-            }
-
-            // Statistics about secure face transactions (e.g. to unlock password
-            // storage, make secure purchases, etc.)
-            final PerformanceStats crypto = mCryptoPerformanceMap.get(userId);
-            if (crypto != null) {
-                final long countsToken = proto.start(FaceUserStatsProto.CRYPTO);
-                proto.write(FaceActionStatsProto.ACCEPT, crypto.accept);
-                proto.write(FaceActionStatsProto.REJECT, crypto.reject);
-                proto.write(FaceActionStatsProto.ACQUIRE, crypto.acquire);
-                proto.write(FaceActionStatsProto.LOCKOUT, crypto.lockout);
-                proto.write(FaceActionStatsProto.LOCKOUT_PERMANENT, crypto.lockout);
-                proto.end(countsToken);
-            }
-
-            proto.end(userToken);
-        }
-        proto.flush();
-        mPerformanceMap.clear();
-        mCryptoPerformanceMap.clear();
+        mUsageStats.print(pw);
     }
 
     private void dumpHal(FileDescriptor fd, String[] args) {
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 24fd1b7..28336f4 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -1035,8 +1035,7 @@
             Slog.e(TAG, "dump formatting failure", e);
         }
         pw.println(dump);
-        pw.println("HAL Deaths: " + mHALDeathCount);
-        mHALDeathCount = 0;
+        pw.println("HAL deaths since last reboot: " + mHALDeathCount);
     }
 
     private void dumpProto(FileDescriptor fd) {
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
new file mode 100644
index 0000000..bb3b9be
--- /dev/null
+++ b/services/core/java/com/android/server/compat/CompatChange.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.server.compat;
+
+import android.annotation.Nullable;
+import android.compat.annotation.EnabledAfter;
+import android.content.pm.ApplicationInfo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents the state of a single compatibility change.
+ *
+ * <p>A compatibility change has a default setting, determined by the {@code enableAfterTargetSdk}
+ * and {@code disabled} constructor parameters. If a change is {@code disabled}, this overrides any
+ * target SDK criteria set. These settings can be overridden for a specific package using
+ * {@link #addPackageOverride(String, boolean)}.
+ *
+ * <p>Note, this class is not thread safe so callers must ensure thread safety.
+ */
+public final class CompatChange {
+
+    private final long mChangeId;
+    @Nullable private final String mName;
+    private final int mEnableAfterTargetSdk;
+    private final boolean mDisabled;
+    private Map<String, Boolean> mPackageOverrides;
+
+    public CompatChange(long changeId) {
+        this(changeId, null, -1, false);
+    }
+
+    /**
+     * @param changeId Unique ID for the change. See {@link android.compat.Compatibility}.
+     * @param name Short descriptive name.
+     * @param enableAfterTargetSdk {@code targetSdkVersion} restriction. See {@link EnabledAfter};
+     *                             -1 if the change is always enabled.
+     * @param disabled If {@code true}, overrides any {@code enableAfterTargetSdk} set.
+     */
+    public CompatChange(long changeId, @Nullable String name, int enableAfterTargetSdk,
+            boolean disabled) {
+        mChangeId = changeId;
+        mName = name;
+        mEnableAfterTargetSdk = enableAfterTargetSdk;
+        mDisabled = disabled;
+    }
+
+    long getId() {
+        return mChangeId;
+    }
+
+    @Nullable
+    String getName() {
+        return mName;
+    }
+
+    /**
+     * Force the enabled state of this change for a given package name. The change will only take
+     * effect after that packages process is killed and restarted.
+     *
+     * <p>Note, this method is not thread safe so callers must ensure thread safety.
+     *
+     * @param pname Package name to enable the change for.
+     * @param enabled Whether or not to enable the change.
+     */
+    void addPackageOverride(String pname, boolean enabled) {
+        if (mPackageOverrides == null) {
+            mPackageOverrides = new HashMap<>();
+        }
+        mPackageOverrides.put(pname, enabled);
+    }
+
+    /**
+     * Remove any package override for the given package name, restoring the default behaviour.
+     *
+     * <p>Note, this method is not thread safe so callers must ensure thread safety.
+     *
+     * @param pname Package name to reset to defaults for.
+     */
+    void removePackageOverride(String pname) {
+        if (mPackageOverrides != null) {
+            mPackageOverrides.remove(pname);
+        }
+    }
+
+    /**
+     * Find if this change is enabled for the given package, taking into account any overrides that
+     * exist.
+     *
+     * @param app Info about the app in question
+     * @return {@code true} if the change should be enabled for the package.
+     */
+    boolean isEnabled(ApplicationInfo app) {
+        if (mPackageOverrides != null && mPackageOverrides.containsKey(app.packageName)) {
+            return mPackageOverrides.get(app.packageName);
+        }
+        if (mDisabled) {
+            return false;
+        }
+        if (mEnableAfterTargetSdk != -1) {
+            return app.targetSdkVersion > mEnableAfterTargetSdk;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("ChangeId(")
+                .append(mChangeId);
+        if (mName != null) {
+            sb.append("; name=").append(mName);
+        }
+        if (mEnableAfterTargetSdk != -1) {
+            sb.append("; enableAfterTargetSdk=").append(mEnableAfterTargetSdk);
+        }
+        if (mDisabled) {
+            sb.append("; disabled");
+        }
+        if (mPackageOverrides != null && mPackageOverrides.size() > 0) {
+            sb.append("; packageOverrides=").append(mPackageOverrides);
+        }
+        return sb.append(")").toString();
+    }
+}
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
new file mode 100644
index 0000000..bcf1d80
--- /dev/null
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.compat;
+
+import android.content.pm.ApplicationInfo;
+import android.text.TextUtils;
+import android.util.LongArray;
+import android.util.LongSparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * This class maintains state relating to platform compatibility changes.
+ *
+ * <p>It stores the default configuration for each change, and any per-package overrides that have
+ * been configured.
+ */
+public final class CompatConfig {
+
+    private static final CompatConfig sInstance = new CompatConfig();
+
+    @GuardedBy("mChanges")
+    private final LongSparseArray<CompatChange> mChanges = new LongSparseArray<>();
+
+    @VisibleForTesting
+    public CompatConfig() {
+    }
+
+    /**
+     * @return The static instance of this class to be used within the system server.
+     */
+    public static CompatConfig get() {
+        return sInstance;
+    }
+
+    /**
+     * Add a change. This is intended to be used by code that reads change config from the
+     * filesystem. This should be done at system startup time.
+     *
+     * @param change The change to add. Any change with the same ID will be overwritten.
+     */
+    public void addChange(CompatChange change) {
+        synchronized (mChanges) {
+            mChanges.put(change.getId(), change);
+        }
+    }
+
+    /**
+     * Retrieves the set of disabled changes for a given app. Any change ID not in the returned
+     * array is by default enabled for the app.
+     *
+     * @param app The app in question
+     * @return A sorted long array of change IDs. We use a primitive array to minimize memory
+     *      footprint: Every app process will store this array statically so we aim to reduce
+     *      overhead as much as possible.
+     */
+    public long[] getDisabledChanges(ApplicationInfo app) {
+        LongArray disabled = new LongArray();
+        synchronized (mChanges) {
+            for (int i = 0; i < mChanges.size(); ++i) {
+                CompatChange c = mChanges.valueAt(i);
+                if (!c.isEnabled(app)) {
+                    disabled.add(c.getId());
+                }
+            }
+        }
+        // Note: we don't need to explicitly sort the array, as the behaviour of LongSparseArray
+        // (mChanges) ensures it's already sorted.
+        return disabled.toArray();
+    }
+
+    /**
+     * Look up a change ID by name.
+     *
+     * @param name Name of the change to look up
+     * @return The change ID, or {@code -1} if no change with that name exists.
+     */
+    public long lookupChangeId(String name) {
+        synchronized (mChanges) {
+            for (int i = 0; i < mChanges.size(); ++i) {
+                if (TextUtils.equals(mChanges.valueAt(i).getName(), name)) {
+                    return mChanges.keyAt(i);
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Find if a given change is enabled for a given application.
+     *
+     * @param changeId The ID of the change in question
+     * @param app App to check for
+     * @return {@code true} if the change is enabled for this app. Also returns {@code true} if the
+     *      change ID is not known, as unknown changes are enabled by default.
+     */
+    public boolean isChangeEnabled(long changeId, ApplicationInfo app) {
+        synchronized (mChanges) {
+            CompatChange c = mChanges.get(changeId);
+            if (c == null) {
+                // we know nothing about this change: default behaviour is enabled.
+                return true;
+            }
+            return c.isEnabled(app);
+        }
+    }
+
+    /**
+     * Overrides the enabled state for a given change and app. This method is intended to be used
+     * *only* for debugging purposes, ultimately invoked either by an adb command, or from some
+     * developer settings UI.
+     *
+     * <p>Note, package overrides are not persistent and will be lost on system or runtime restart.
+     *
+     * @param changeId The ID of the change to be overridden. Note, this call will succeed even if
+     *                 this change is not known; it will only have any effect if any code in the
+     *                 platform is gated on the ID given.
+     * @param packageName The app package name to override the change for.
+     * @param enabled If the change should be enabled or disabled.
+     * @return {@code true} if the change existed before adding the override.
+     */
+    public boolean addOverride(long changeId, String packageName, boolean enabled) {
+        boolean alreadyKnown = true;
+        synchronized (mChanges) {
+            CompatChange c = mChanges.get(changeId);
+            if (c == null) {
+                alreadyKnown = false;
+                c = new CompatChange(changeId);
+                addChange(c);
+            }
+            c.addPackageOverride(packageName, enabled);
+        }
+        return alreadyKnown;
+    }
+
+    /**
+     * Removes an override previously added via {@link #addOverride(long, String, boolean)}. This
+     * restores the default behaviour for the given change and app, once any app processes have been
+     * restarted.
+     *
+     * @param changeId The ID of the change that was overridden.
+     * @param packageName The app package name that was overridden.
+     * @return {@code true} if an override existed;
+     */
+    public boolean removeOverride(long changeId, String packageName) {
+        boolean overrideExists = false;
+        synchronized (mChanges) {
+            CompatChange c = mChanges.get(changeId);
+            if (c != null) {
+                overrideExists = true;
+                c.removePackageOverride(packageName);
+            }
+        }
+        return overrideExists;
+    }
+
+}
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
new file mode 100644
index 0000000..456d15e
--- /dev/null
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.compat;
+
+import android.content.pm.ApplicationInfo;
+import android.util.Slog;
+
+/**
+ * System server internal API for gating and reporting compatibility changes.
+ */
+public class PlatformCompat {
+
+    private static final String TAG = "Compatibility";
+
+    /**
+     * Reports that a compatibility change is affecting an app process now.
+     *
+     * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)},
+     * you do not need to call this API directly. The change will be reported for you in the case
+     * that {@link #isChangeEnabled(long, ApplicationInfo)} returns {@code true}.
+     *
+     * @param changeId The ID of the compatibility change taking effect.
+     * @param appInfo Representing the affected app.
+     */
+    public static void reportChange(long changeId, ApplicationInfo appInfo) {
+        Slog.d(TAG, "Compat change reported: " + changeId + "; UID " + appInfo.uid);
+        // TODO log via StatsLog
+    }
+
+    /**
+     * Query if a given compatibility change is enabled for an app process. This method should
+     * be called when implementing functionality on behalf of the affected app.
+     *
+     * <p>If this method returns {@code true}, the calling code should implement the compatibility
+     * change, resulting in differing behaviour compared to earlier releases. If this method returns
+     * {@code false}, the calling code should behave as it did in earlier releases.
+     *
+     * <p>When this method returns {@code true}, it will also report the change as
+     * {@link #reportChange(long, ApplicationInfo)} would, so there is no need to call that method
+     * directly.
+     *
+     * @param changeId The ID of the compatibility change in question.
+     * @param appInfo Representing the app in question.
+     * @return {@code true} if the change is enabled for the current app.
+     */
+    public static boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
+        if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) {
+            reportChange(changeId, appInfo);
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index e10d737..9bae902 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -216,6 +216,7 @@
 
         public String toString() {
             return "KeepaliveInfo ["
+                    + " type=" + mType
                     + " network=" + mNai.network
                     + " startedState=" + startedStateString(mStartedState)
                     + " "
@@ -561,7 +562,7 @@
         if (KeepaliveInfo.STARTING == ki.mStartedState) {
             if (SUCCESS == reason) {
                 // Keepalive successfully started.
-                if (DBG) Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
+                Log.d(TAG, "Started keepalive " + slot + " on " + nai.name());
                 ki.mStartedState = KeepaliveInfo.STARTED;
                 try {
                     ki.mCallback.onStarted(slot);
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 34772d0..5b04379 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -25,12 +25,12 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkMisc;
+import android.net.NetworkMonitorManager;
 import android.net.NetworkRequest;
 import android.net.NetworkState;
 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;
@@ -155,9 +155,9 @@
     // Whether a captive portal was found during the last network validation attempt.
     public boolean lastCaptivePortalDetected;
 
-    // Indicates the user was notified of a successful captive portal login since a portal was
-    // last detected.
-    public boolean captivePortalLoginNotified;
+    // Indicates the captive portal app was opened to show a login UI to the user, but the network
+    // has not validated yet.
+    public volatile boolean captivePortalValidationPending;
 
     // Set to true when partial connectivity was detected.
     public boolean partialConnectivity;
@@ -247,7 +247,7 @@
     public final Nat464Xlat clatd;
 
     // Set after asynchronous creation of the NetworkMonitor.
-    private volatile INetworkMonitor mNetworkMonitor;
+    private volatile NetworkMonitorManager mNetworkMonitor;
 
     private static final String TAG = ConnectivityService.class.getSimpleName();
     private static final boolean VDBG = false;
@@ -278,7 +278,7 @@
      * Inform NetworkAgentInfo that a new NetworkMonitor was created.
      */
     public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
-        mNetworkMonitor = networkMonitor;
+        mNetworkMonitor = new NetworkMonitorManager(networkMonitor);
     }
 
     /**
@@ -290,13 +290,9 @@
      */
     public void setNetworkCapabilities(NetworkCapabilities nc) {
         networkCapabilities = nc;
-        final INetworkMonitor nm = mNetworkMonitor;
+        final NetworkMonitorManager nm = mNetworkMonitor;
         if (nm != null) {
-            try {
-                nm.notifyNetworkCapabilitiesChanged(nc);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Error notifying NetworkMonitor of updated NetworkCapabilities", e);
-            }
+            nm.notifyNetworkCapabilitiesChanged(nc);
         }
     }
 
@@ -317,11 +313,11 @@
     }
 
     /**
-     * Get the INetworkMonitor in this NetworkAgentInfo.
+     * Get the NetworkMonitorManager in this NetworkAgentInfo.
      *
      * <p>This will be null before {@link #onNetworkMonitorCreated(INetworkMonitor)} is called.
      */
-    public INetworkMonitor networkMonitor() {
+    public NetworkMonitorManager networkMonitor() {
         return mNetworkMonitor;
     }
 
@@ -633,7 +629,7 @@
                 + "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} "
                 + "everCaptivePortalDetected{" + everCaptivePortalDetected + "} "
                 + "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} "
-                + "captivePortalLoginNotified{" + captivePortalLoginNotified + "} "
+                + "captivePortalValidationPending{" + captivePortalValidationPending + "} "
                 + "partialConnectivity{" + partialConnectivity + "} "
                 + "acceptPartialConnectivity{" + networkMisc.acceptPartialConnectivity + "} "
                 + "clat{" + clatd + "} "
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index f6735d9..077c405 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -232,6 +232,11 @@
             title = r.getString(R.string.network_switch_metered, toTransport);
             details = r.getString(R.string.network_switch_metered_detail, toTransport,
                     fromTransport);
+        } else if (notifyType == NotificationType.NO_INTERNET
+                    || notifyType == NotificationType.PARTIAL_CONNECTIVITY) {
+            // NO_INTERNET and PARTIAL_CONNECTIVITY notification for non-WiFi networks
+            // are sent, but they are not implemented yet.
+            return;
         } else {
             Slog.wtf(TAG, "Unknown notification type " + notifyType + " on network transport "
                     + getTransportName(transportType));
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 33c84d1..4957eed 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -44,6 +44,7 @@
 import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static com.android.server.ConnectivityService.SHORT_ARG;
 
@@ -89,6 +90,8 @@
 import android.os.UserManager;
 import android.os.UserManagerInternal;
 import android.os.UserManagerInternal.UserRestrictionsListener;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -97,7 +100,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
-import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.MessageUtils;
@@ -182,12 +184,13 @@
     // into a single coherent structure.
     private final HashSet<IpServer> mForwardedDownstreams;
     private final VersionedBroadcastListener mCarrierConfigChange;
-    private final VersionedBroadcastListener mDefaultSubscriptionChange;
     private final TetheringDependencies mDeps;
     private final EntitlementManager mEntitlementMgr;
     private final Handler mHandler;
     private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks =
             new RemoteCallbackList<>();
+    private final PhoneStateListener mPhoneStateListener;
+    private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
 
     private volatile TetheringConfiguration mConfig;
     private InterfaceSet mCurrentUpstreamIfaceSet;
@@ -238,7 +241,6 @@
             stopTethering(downstream);
         });
         mEntitlementMgr.setTetheringConfigurationFetcher(() -> {
-            maybeDefaultDataSubChanged();
             return mConfig;
         });
 
@@ -250,22 +252,26 @@
                     mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
                 });
 
-        filter = new IntentFilter();
-        filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
-        mDefaultSubscriptionChange = new VersionedBroadcastListener(
-                "DefaultSubscriptionChangeListener", mContext, mHandler, filter,
-                (Intent ignored) -> {
-                    mLog.log("OBSERVED default data subscription change");
-                    maybeDefaultDataSubChanged();
-                    // To avoid launch unexpected provisioning checks, ignore re-provisioning when
-                    // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be
-                    // triggered again when CarrierConfig is loaded.
-                    if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
-                        mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
-                    } else {
-                        mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded");
-                    }
-                });
+        mPhoneStateListener = new PhoneStateListener(mLooper) {
+            @Override
+            public void onActiveDataSubscriptionIdChanged(int subId) {
+                mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId
+                        + " to " + subId);
+                if (subId == mActiveDataSubId) return;
+
+                mActiveDataSubId = subId;
+                updateConfiguration();
+                // To avoid launching unexpected provisioning checks, ignore re-provisioning when
+                // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be
+                // triggered again when CarrierConfig is loaded.
+                if (mEntitlementMgr.getCarrierConfig(mConfig) != null) {
+                    mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
+                } else {
+                    mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded");
+                }
+            }
+        };
+
         mStateReceiver = new StateReceiver();
 
         // Load tethering configuration.
@@ -276,7 +282,8 @@
 
     private void startStateMachineUpdaters(Handler handler) {
         mCarrierConfigChange.startListening();
-        mDefaultSubscriptionChange.startListening();
+        TelephonyManager.from(mContext).listen(mPhoneStateListener,
+                PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(UsbManager.ACTION_USB_STATE);
@@ -304,27 +311,17 @@
 
     // NOTE: This is always invoked on the mLooper thread.
     private void updateConfiguration() {
-        final int subId = mDeps.getDefaultDataSubscriptionId();
-        updateConfiguration(subId);
-    }
-
-    private void updateConfiguration(final int subId) {
-        mConfig = new TetheringConfiguration(mContext, mLog, subId);
+        mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId);
         mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
     }
 
     private void maybeDunSettingChanged() {
-        final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext);
+        final boolean isDunRequired = TetheringConfiguration.checkDunRequired(
+                mContext, mActiveDataSubId);
         if (isDunRequired == mConfig.isDunRequired) return;
         updateConfiguration();
     }
 
-    private void maybeDefaultDataSubChanged() {
-        final int subId = mDeps.getDefaultDataSubscriptionId();
-        if (subId == mConfig.subId) return;
-        updateConfiguration(subId);
-    }
-
     @Override
     public void interfaceStatusChanged(String iface, boolean up) {
         // Never called directly: only called from interfaceLinkStateChanged.
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 8427b6e..1907892 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -112,7 +112,7 @@
         tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs);
         tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs);
 
-        isDunRequired = checkDunRequired(ctx);
+        isDunRequired = checkDunRequired(ctx, subId);
 
         chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic);
         preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired);
@@ -228,9 +228,9 @@
     }
 
     /** Check whether dun is required. */
-    public static boolean checkDunRequired(Context ctx) {
+    public static boolean checkDunRequired(Context ctx, int id) {
         final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
-        return (tm != null) ? tm.getTetherApnRequired() : false;
+        return (tm != null) ? tm.getTetherApnRequired(id) : false;
     }
 
     private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) {
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 a0aad7c..4ad7ac4 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
@@ -21,7 +21,6 @@
 import android.net.ip.IpServer;
 import android.net.util.SharedLog;
 import android.os.Handler;
-import android.telephony.SubscriptionManager;
 
 import com.android.internal.util.StateMachine;
 import com.android.server.connectivity.MockableSystemProperties;
@@ -88,9 +87,10 @@
     }
 
     /**
-     * Get default data subscription id to build TetheringConfiguration.
+     * Generate a new TetheringConfiguration according to input sub Id.
      */
-    public int getDefaultDataSubscriptionId() {
-        return SubscriptionManager.getDefaultDataSubscriptionId();
+    public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
+            int subId) {
+        return new TetheringConfiguration(ctx, log, subId);
     }
 }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 998ee1e..3e1817b 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -22,6 +22,7 @@
 import android.annotation.RequiresPermission;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.job.JobInfo;
 import android.content.BroadcastReceiver;
@@ -39,7 +40,6 @@
 import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ProviderInfo;
 import android.database.IContentObserver;
 import android.database.sqlite.SQLiteException;
@@ -56,6 +56,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
@@ -63,11 +64,13 @@
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BinderDeathDispatcher;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -83,6 +86,9 @@
     static final String TAG = "ContentService";
     static final boolean DEBUG = false;
 
+    /** Do a WTF if a single observer is registered more than this times. */
+    private static final int TOO_MANY_OBSERVERS_THRESHOLD = 1000;
+
     public static class Lifecycle extends SystemService {
         private ContentService mService;
 
@@ -135,6 +141,12 @@
     private SyncManager mSyncManager = null;
     private final Object mSyncManagerLock = new Object();
 
+    private static final BinderDeathDispatcher<IContentObserver> sObserverDeathDispatcher =
+            new BinderDeathDispatcher<>();
+
+    @GuardedBy("sObserverLeakDetectedUid")
+    private static final ArraySet<Integer> sObserverLeakDetectedUid = new ArraySet<>(0);
+
     /**
      * Map from userId to providerPackageName to [clientPackageName, uri] to
      * value. This structure is carefully optimized to keep invalidation logic
@@ -236,6 +248,13 @@
                 pw.println();
                 pw.print(" Total number of nodes: "); pw.println(counts[0]);
                 pw.print(" Total number of observers: "); pw.println(counts[1]);
+
+                sObserverDeathDispatcher.dump(pw, " ");
+            }
+            synchronized (sObserverLeakDetectedUid) {
+                pw.println();
+                pw.print("Observer leaking UIDs: ");
+                pw.println(sObserverLeakDetectedUid.toString());
             }
 
             synchronized (mCache) {
@@ -261,15 +280,11 @@
 
         // Let the package manager query for the sync adapters for a given authority
         // as we grant default permissions to sync adapters for specific authorities.
-        PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        packageManagerInternal.setSyncAdapterPackagesprovider(
-                new PackageManagerInternal.SyncAdapterPackagesProvider() {
-                    @Override
-                    public String[] getPackages(String authority, int userId) {
-                        return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
-                    }
-                });
+        final PermissionManagerServiceInternal permissionManagerInternal =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
+        permissionManagerInternal.setSyncAdapterPackagesProvider((authority, userId) -> {
+            return getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
+        });
 
         final IntentFilter packageFilter = new IntentFilter();
         packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -1345,18 +1360,40 @@
             private final Object observersLock;
 
             public ObserverEntry(IContentObserver o, boolean n, Object observersLock,
-                                 int _uid, int _pid, int _userHandle) {
+                                 int _uid, int _pid, int _userHandle, Uri uri) {
                 this.observersLock = observersLock;
                 observer = o;
                 uid = _uid;
                 pid = _pid;
                 userHandle = _userHandle;
                 notifyForDescendants = n;
-                try {
-                    observer.asBinder().linkToDeath(this, 0);
-                } catch (RemoteException e) {
+
+                final int entries = sObserverDeathDispatcher.linkToDeath(observer, this);
+                if (entries == -1) {
                     binderDied();
+                } else if (entries == TOO_MANY_OBSERVERS_THRESHOLD) {
+                    boolean alreadyDetected;
+
+                    synchronized (sObserverLeakDetectedUid) {
+                        alreadyDetected = sObserverLeakDetectedUid.contains(uid);
+                        if (!alreadyDetected) {
+                            sObserverLeakDetectedUid.add(uid);
+                        }
+                    }
+                    if (!alreadyDetected) {
+                        String caller = null;
+                        try {
+                            caller = ArrayUtils.firstOrNull(AppGlobals.getPackageManager()
+                                    .getPackagesForUid(uid));
+                        } catch (RemoteException ignore) {
+                        }
+                        Slog.wtf(TAG, "Observer registered too many times. Leak? cpid=" + pid
+                                + " cuid=" + uid
+                                + " cpkg=" + caller
+                                + " url=" + uri);
+                    }
                 }
+
             }
 
             @Override
@@ -1454,7 +1491,7 @@
             // If this is the leaf node add the observer
             if (index == countUriSegments(uri)) {
                 mObservers.add(new ObserverEntry(observer, notifyForDescendants, observersLock,
-                        uid, pid, userHandle));
+                        uid, pid, userHandle, uri));
                 return;
             }
 
@@ -1498,7 +1535,7 @@
                 if (entry.observer.asBinder() == observerBinder) {
                     mObservers.remove(i);
                     // We no longer need to listen for death notifications. Remove it.
-                    observerBinder.unlinkToDeath(entry, 0);
+                    sObserverDeathDispatcher.unlinkToDeath(observer, entry);
                     break;
                 }
             }
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index fa8c48b..64a05c9 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -1533,7 +1533,13 @@
                 }
             }
             if (duplicatesCount > 1) {
-                Slog.e(TAG, "FATAL ERROR! File a bug if you see this.");
+                Slog.wtf(TAG, "duplicates found when scheduling a sync operation: "
+                        + "owningUid=" + syncOperation.owningUid
+                        + "; owningPackage=" + syncOperation.owningPackage
+                        + "; source=" + syncOperation.syncSource
+                        + "; adapter=" + (syncOperation.target != null
+                                            ? syncOperation.target.provider
+                                            : "unknown"));
             }
 
             if (syncOperation != syncToRun) {
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 6d7dff5..31632dc 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -322,7 +322,7 @@
         }
         changed |= setLightSensorEnabled(enable && !dozing);
         if (changed) {
-            updateAutoBrightness(false /*sendUpdate*/);
+            updateAutoBrightness(false /*sendUpdate*/, userInitiatedChange);
         }
     }
 
@@ -667,7 +667,7 @@
                         "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", " +
                         "mAmbientLux=" + mAmbientLux);
             }
-            updateAutoBrightness(true);
+            updateAutoBrightness(true /* sendUpdate */, false /* isManuallySet */);
         }
 
         long nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
@@ -697,7 +697,7 @@
                         + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer + ", "
                         + "mAmbientLux=" + mAmbientLux);
             }
-            updateAutoBrightness(true);
+            updateAutoBrightness(true /* sendUpdate */, false /* isManuallySet */);
             nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
             nextDarkenTransition = nextAmbientLightDarkeningTransition(time);
         }
@@ -717,7 +717,7 @@
         mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, nextTransitionTime);
     }
 
-    private void updateAutoBrightness(boolean sendUpdate) {
+    private void updateAutoBrightness(boolean sendUpdate, boolean isManuallySet) {
         if (!mAmbientLuxValid) {
             return;
         }
@@ -732,6 +732,7 @@
         // in which case we ignore the new screen brightness if it doesn't differ enough from the
         // previous one.
         if (mScreenAutoBrightness != -1
+                && !isManuallySet
                 && newScreenAutoBrightness > mScreenDarkeningThreshold
                 && newScreenAutoBrightness < mScreenBrighteningThreshold) {
             if (mLoggingEnabled) {
@@ -879,7 +880,7 @@
         mPendingForegroundAppPackageName = null;
         mForegroundAppCategory = mPendingForegroundAppCategory;
         mPendingForegroundAppCategory = ApplicationInfo.CATEGORY_UNDEFINED;
-        updateAutoBrightness(true /* sendUpdate */);
+        updateAutoBrightness(true /* sendUpdate */, false /* isManuallySet */);
     }
 
     private final class AutomaticBrightnessHandler extends Handler {
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index 36d9c0e..7be1b8a 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -634,13 +634,8 @@
         if (mSurfaceControl != null) {
             mSurfaceLayout.dispose();
             mSurfaceLayout = null;
-            SurfaceControl.openTransaction();
-            try {
-                mSurfaceControl.remove();
-                mSurface.release();
-            } finally {
-                SurfaceControl.closeTransaction();
-            }
+            new Transaction().remove(mSurfaceControl).apply();
+            mSurface.release();
             mSurfaceControl = null;
             mSurfaceVisible = false;
             mSurfaceAlpha = 0f;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 99341d1..4f33ebb0 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -303,6 +303,8 @@
     private final Spline mMinimumBrightnessSpline;
     private final ColorSpace mWideColorSpace;
 
+    private SensorManager mSensorManager;
+
     public DisplayManagerService(Context context) {
         this(context, new Injector());
     }
@@ -430,7 +432,7 @@
         }
 
         mDisplayModeDirector.setListener(new AllowedDisplayModeObserver());
-        mDisplayModeDirector.start();
+        mDisplayModeDirector.start(mSensorManager);
 
         mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
     }
@@ -2358,6 +2360,7 @@
                 };
                 mDisplayPowerController = new DisplayPowerController(
                         mContext, callbacks, handler, sensorManager, blanker);
+                mSensorManager = sensorManager;
             }
 
             mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 0940a2e..78a48da 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -18,26 +18,41 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.hardware.display.DisplayManager;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.UserHandle;
+import android.os.PowerManager;
+import android.os.SystemClock;
 import android.provider.Settings;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayInfo;
 
 import com.android.internal.R;
+import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
+import com.android.server.display.whitebalance.AmbientFilter;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -74,7 +89,7 @@
     private final AppRequestObserver mAppRequestObserver;
     private final SettingsObserver mSettingsObserver;
     private final DisplayObserver mDisplayObserver;
-
+    private final BrightnessObserver mBrightnessObserver;
 
     private Listener mListener;
 
@@ -87,6 +102,8 @@
         mAppRequestObserver = new AppRequestObserver();
         mSettingsObserver = new SettingsObserver(context, handler);
         mDisplayObserver = new DisplayObserver(context, handler);
+        mBrightnessObserver = new BrightnessObserver(context, handler);
+
     }
 
     /**
@@ -96,15 +113,17 @@
      * This has to be deferred because the object may be constructed before the rest of the system
      * is ready.
      */
-    public void start() {
+    public void start(SensorManager sensorManager) {
         mSettingsObserver.observe();
         mDisplayObserver.observe();
         mSettingsObserver.observe();
+        mBrightnessObserver.observe(sensorManager);
         synchronized (mLock) {
             // We may have a listener already registered before the call to start, so go ahead and
             // notify them to pick up our newly initialized state.
             notifyAllowedModesChangedLocked();
         }
+
     }
 
     /**
@@ -315,6 +334,7 @@
             }
             mSettingsObserver.dumpLocked(pw);
             mAppRequestObserver.dumpLocked(pw);
+            mBrightnessObserver.dumpLocked(pw);
         }
     }
 
@@ -402,17 +422,18 @@
     }
 
     private static final class Vote {
-        public static final int PRIORITY_USER_SETTING = 0;
         // We split the app request into two priorities in case we can satisfy one desire without
         // the other.
-        public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 1;
-        public static final int PRIORITY_APP_REQUEST_SIZE = 2;
-        public static final int PRIORITY_LOW_POWER_MODE = 3;
+        public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 0;
+        public static final int PRIORITY_APP_REQUEST_SIZE = 1;
+        public static final int PRIORITY_USER_SETTING_REFRESH_RATE = 2;
+        public static final int PRIORITY_LOW_BRIGHTNESS = 3;
+        public static final int PRIORITY_LOW_POWER_MODE = 4;
 
         // Whenever a new priority is added, remember to update MIN_PRIORITY and/or MAX_PRIORITY as
         // appropriate, as well as priorityToString.
 
-        public static final int MIN_PRIORITY = PRIORITY_USER_SETTING;
+        public static final int MIN_PRIORITY = PRIORITY_APP_REQUEST_REFRESH_RATE;
         public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
 
         /**
@@ -456,12 +477,12 @@
 
         public static String priorityToString(int priority) {
             switch (priority) {
-                case PRIORITY_USER_SETTING:
-                    return "PRIORITY_USER_SETTING";
                 case PRIORITY_APP_REQUEST_REFRESH_RATE:
                     return "PRIORITY_APP_REQUEST_REFRESH_RATE";
                 case PRIORITY_APP_REQUEST_SIZE:
                     return "PRIORITY_APP_REQUEST_SIZE";
+                case PRIORITY_USER_SETTING_REFRESH_RATE:
+                    return "PRIORITY_USER_SETTING_REFRESH_RATE";
                 case PRIORITY_LOW_POWER_MODE:
                     return "PRIORITY_LOW_POWER_MODE";
                 default:
@@ -529,13 +550,15 @@
                 vote = null;
             }
             updateVoteLocked(Vote.PRIORITY_LOW_POWER_MODE, vote);
+            mBrightnessObserver.onLowPowerModeEnabled(inLowPowerMode);
         }
 
         private void updateRefreshRateSettingLocked() {
             float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
                     Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
             Vote vote = Vote.forRefreshRates(0f, peakRefreshRate);
-            updateVoteLocked(Vote.PRIORITY_USER_SETTING, vote);
+            updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote);
+            mBrightnessObserver.onPeakRefreshRateEnabled(peakRefreshRate > 60f);
         }
 
         public void dumpLocked(PrintWriter pw) {
@@ -685,4 +708,240 @@
             }
         }
     }
+
+    /**
+     * This class manages brightness threshold for switching between 60 hz and higher refresh rate.
+     * See more information at the definition of
+     * {@link R.array#config_brightnessThresholdsOfPeakRefreshRate} and
+     * {@link R.array#config_ambientThresholdsOfPeakRefreshRate}.
+     */
+    private class BrightnessObserver extends ContentObserver {
+        private final Uri mDisplayBrightnessSetting =
+                Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
+
+        private final static int LIGHT_SENSOR_RATE_MS = 250;
+        private final int[] mDisplayBrightnessThresholds;
+        private final int[] mAmbientBrightnessThresholds;
+        // valid threshold if any item from the array >= 0
+        private boolean mShouldObserveDisplayChange;
+        private boolean mShouldObserveAmbientChange;
+
+        private SensorManager mSensorManager;
+        private Sensor mLightSensor;
+        // Take it as low brightness before valid sensor data comes
+        private float mAmbientLux = -1.0f;
+        private AmbientFilter mAmbientFilter;
+
+        private final Context mContext;
+        private ScreenStateReceiver mScreenStateReceiver;
+
+        // Enable light sensor only when screen is on, peak refresh rate enabled and low power mode
+        // off. After initialization, these states will be updated from the same handler thread.
+        private boolean mScreenOn = false;
+        private boolean mPeakRefreshRateEnabled = false;
+        private boolean mLowPowerModeEnabled = false;
+
+        BrightnessObserver(Context context, Handler handler) {
+            super(handler);
+            mContext = context;
+            mDisplayBrightnessThresholds = context.getResources().getIntArray(
+                    R.array.config_brightnessThresholdsOfPeakRefreshRate);
+            mAmbientBrightnessThresholds = context.getResources().getIntArray(
+                    R.array.config_ambientThresholdsOfPeakRefreshRate);
+            if (mDisplayBrightnessThresholds.length != mAmbientBrightnessThresholds.length) {
+                throw new RuntimeException("display brightness threshold array and ambient "
+                        + "brightness threshold array have different length");
+            }
+
+            mShouldObserveDisplayChange = checkShouldObserve(mDisplayBrightnessThresholds);
+            mShouldObserveAmbientChange = checkShouldObserve(mAmbientBrightnessThresholds);
+        }
+
+        public void observe(SensorManager sensorManager) {
+            if (mShouldObserveDisplayChange) {
+                final ContentResolver cr = mContext.getContentResolver();
+                cr.registerContentObserver(mDisplayBrightnessSetting,
+                        false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM);
+            }
+
+            if (mShouldObserveAmbientChange) {
+                Resources resources = mContext.getResources();
+                String lightSensorType = resources.getString(
+                        com.android.internal.R.string.config_displayLightSensorType);
+
+                Sensor lightSensor = null;
+                if (!TextUtils.isEmpty(lightSensorType)) {
+                    List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
+                    for (int i = 0; i < sensors.size(); i++) {
+                        Sensor sensor = sensors.get(i);
+                        if (lightSensorType.equals(sensor.getStringType())) {
+                            lightSensor = sensor;
+                            break;
+                        }
+                    }
+                }
+
+                if (lightSensor == null) {
+                    lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+                }
+
+                if (lightSensor != null) {
+                    final Resources res = mContext.getResources();
+
+                    mAmbientFilter = DisplayWhiteBalanceFactory.createBrightnessFilter(res);
+                    mSensorManager = sensorManager;
+                    mLightSensor = lightSensor;
+
+                    // Intent.ACTION_SCREEN_ON is not sticky. Check current screen status.
+                    if (mContext.getSystemService(PowerManager.class).isInteractive()) {
+                        onScreenOn(true);
+                    }
+                    mScreenStateReceiver = new ScreenStateReceiver(mContext);
+                }
+            }
+
+            if (mShouldObserveDisplayChange || mShouldObserveAmbientChange) {
+                synchronized (mLock) {
+                    onBrightnessChangedLocked();
+                }
+            }
+        }
+
+        public void onPeakRefreshRateEnabled(boolean b) {
+            if (mShouldObserveAmbientChange && mPeakRefreshRateEnabled != b) {
+                mPeakRefreshRateEnabled = b;
+                updateSensorStatus();
+            }
+        }
+
+        public void onLowPowerModeEnabled(boolean b) {
+            if (mShouldObserveAmbientChange && mLowPowerModeEnabled != b) {
+                mLowPowerModeEnabled = b;
+                updateSensorStatus();
+            }
+        }
+
+        public void dumpLocked(PrintWriter pw) {
+            pw.println("  BrightnessObserver");
+
+            for (int d: mDisplayBrightnessThresholds) {
+                pw.println("    mDisplayBrightnessThreshold: " + d);
+            }
+
+            for (int d: mAmbientBrightnessThresholds) {
+                pw.println("    mAmbientBrightnessThreshold: " + d);
+            }
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri, int userId) {
+            synchronized (mLock) {
+                onBrightnessChangedLocked();
+            }
+        }
+
+        /**
+         * Checks to see if at least one value is positive, in which case it is necessary to listen
+         * to value changes.
+         */
+        private boolean checkShouldObserve(int[] a) {
+            for (int d: a) {
+                if (d >= 0) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private void onBrightnessChangedLocked() {
+            int brightness = Settings.System.getInt(mContext.getContentResolver(),
+                    Settings.System.SCREEN_BRIGHTNESS, -1);
+
+            Vote vote = null;
+            for (int i = 0; i < mDisplayBrightnessThresholds.length; i++) {
+                int disp = mDisplayBrightnessThresholds[i];
+                int ambi = mAmbientBrightnessThresholds[i];
+
+                if (disp >= 0 && ambi >= 0) {
+                    if (brightness <= disp && mAmbientLux <= ambi) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                } else if (disp >= 0) {
+                    if (brightness <= disp) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                } else if (ambi >= 0) {
+                    if (mAmbientLux <= ambi) {
+                        vote = Vote.forRefreshRates(0f, 60f);
+                    }
+                }
+
+                if (vote != null) {
+                    break;
+                }
+            }
+
+            if (DEBUG) {
+                Slog.d(TAG, "Display brightness " + brightness + ", ambient lux " +  mAmbientLux +
+                        (vote != null ? " 60hz only" : " no refresh rate limit"));
+            }
+            updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);
+        }
+
+        private void onScreenOn(boolean on) {
+            // Not check mShouldObserveAmbientChange because Screen status receiver is registered
+            // only when it is true.
+            if (mScreenOn != on) {
+                mScreenOn = on;
+                updateSensorStatus();
+            }
+        }
+
+        private void updateSensorStatus() {
+            if (mSensorManager == null || mLightSensorListener == null) {
+                return;
+            }
+
+            if (mScreenOn && !mLowPowerModeEnabled && mPeakRefreshRateEnabled) {
+                mSensorManager.registerListener(mLightSensorListener,
+                        mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler);
+            } else {
+                mSensorManager.unregisterListener(mLightSensorListener);
+            }
+        }
+
+        private final SensorEventListener mLightSensorListener = new SensorEventListener() {
+            @Override
+            public void onSensorChanged(SensorEvent event) {
+                long now = SystemClock.uptimeMillis();
+                mAmbientFilter.addValue(now, event.values[0]);
+                mAmbientLux = mAmbientFilter.getEstimate(now);
+
+                synchronized (mLock) {
+                    onBrightnessChangedLocked();
+                }
+            }
+
+            @Override
+            public void onAccuracyChanged(Sensor sensor, int accuracy) {
+                // Not used.
+            }
+        };
+
+        private final class ScreenStateReceiver extends BroadcastReceiver {
+            public ScreenStateReceiver(Context context) {
+                IntentFilter filter = new IntentFilter();
+                filter.addAction(Intent.ACTION_SCREEN_OFF);
+                filter.addAction(Intent.ACTION_SCREEN_ON);
+                filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+                context.registerReceiver(this, filter, null, mHandler);
+            }
+
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                onScreenOn(Intent.ACTION_SCREEN_ON.equals(intent.getAction()));
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 5fb67dd..5804fc8 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -309,6 +309,13 @@
     private boolean mAppliedTemporaryAutoBrightnessAdjustment;
     private boolean mAppliedBrightnessBoost;
 
+    // Reason for which the brightness was last changed. See {@link BrightnessReason} for more
+    // information.
+    // At the time of this writing, this value is changed within updatePowerState() only, which is
+    // limited to the thread used by DisplayControllerHandler.
+    private BrightnessReason mBrightnessReason = new BrightnessReason();
+    private BrightnessReason mBrightnessReasonTemp = new BrightnessReason();
+
     // Brightness animation ramp rates in brightness units per second
     private final int mBrightnessRampRateFast;
     private final int mBrightnessRampRateSlow;
@@ -733,6 +740,8 @@
         final boolean mustNotify;
         final int previousPolicy;
         boolean mustInitialize = false;
+        int brightnessAdjustmentFlags = 0;
+        mBrightnessReasonTemp.set(null);
 
         synchronized (mLock) {
             mPendingUpdatePowerStateLocked = false;
@@ -786,6 +795,7 @@
                 }
                 if (!mAllowAutoBrightnessWhileDozingConfig) {
                     brightness = mPowerRequest.dozeScreenBrightness;
+                    mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE);
                 }
                 break;
             case DisplayPowerRequest.POLICY_VR:
@@ -839,15 +849,18 @@
         // Use zero brightness when screen is off.
         if (state == Display.STATE_OFF) {
             brightness = PowerManager.BRIGHTNESS_OFF;
+            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_SCREEN_OFF);
         }
 
         // Always use the VR brightness when in the VR state.
         if (state == Display.STATE_VR) {
             brightness = mScreenBrightnessForVr;
+            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_VR);
         }
 
         if (brightness < 0 && mPowerRequest.screenBrightnessOverride > 0) {
             brightness = mPowerRequest.screenBrightnessOverride;
+            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_OVERRIDE);
             mAppliedScreenBrightnessOverride = true;
         } else {
             mAppliedScreenBrightnessOverride = false;
@@ -867,6 +880,7 @@
         if (mTemporaryScreenBrightness > 0) {
             brightness = mTemporaryScreenBrightness;
             mAppliedTemporaryBrightness = true;
+            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_TEMPORARY);
         } else {
             mAppliedTemporaryBrightness = false;
         }
@@ -880,9 +894,11 @@
         final float autoBrightnessAdjustment;
         if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) {
             autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment;
+            brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO_TEMP;
             mAppliedTemporaryAutoBrightnessAdjustment = true;
         } else {
             autoBrightnessAdjustment = mAutoBrightnessAdjustment;
+            brightnessAdjustmentFlags = BrightnessReason.ADJUSTMENT_AUTO;
             mAppliedTemporaryAutoBrightnessAdjustment = false;
         }
 
@@ -893,6 +909,7 @@
         if (mPowerRequest.boostScreenBrightness
                 && brightness != PowerManager.BRIGHTNESS_OFF) {
             brightness = PowerManager.BRIGHTNESS_ON;
+            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_BOOST);
             mAppliedBrightnessBoost = true;
         } else {
             mAppliedBrightnessBoost = false;
@@ -936,6 +953,7 @@
                 // it means in absolute terms.
                 putScreenBrightnessSetting(brightness);
                 mAppliedAutoBrightness = true;
+                mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
             } else {
                 mAppliedAutoBrightness = false;
             }
@@ -943,19 +961,25 @@
                 // If the autobrightness controller has decided to change the adjustment value
                 // used, make sure that's reflected in settings.
                 putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
+            } else {
+                // Adjustment values resulted in no change
+                brightnessAdjustmentFlags = 0;
             }
         } else {
             mAppliedAutoBrightness = false;
+            brightnessAdjustmentFlags = 0;
         }
 
         // Use default brightness when dozing unless overridden.
         if (brightness < 0 && Display.isDozeState(state)) {
             brightness = mScreenBrightnessDozeConfig;
+            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_DEFAULT);
         }
 
         // Apply manual brightness.
         if (brightness < 0) {
             brightness = clampScreenBrightness(mCurrentScreenBrightnessSetting);
+            mBrightnessReasonTemp.setReason(BrightnessReason.REASON_MANUAL);
         }
 
         // Apply dimming by at least some minimum amount when user activity
@@ -964,6 +988,7 @@
             if (brightness > mScreenBrightnessRangeMinimum) {
                 brightness = Math.max(Math.min(brightness - SCREEN_DIM_MINIMUM_REDUCTION,
                         mScreenBrightnessDimConfig), mScreenBrightnessRangeMinimum);
+                mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_DIMMED);
             }
             if (!mAppliedDimming) {
                 slowChange = false;
@@ -982,6 +1007,7 @@
                         Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);
                 final int lowPowerBrightness = (int) (brightness * brightnessFactor);
                 brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);
+                mBrightnessReasonTemp.addModifier(BrightnessReason.MODIFIER_LOW_POWER);
             }
             if (!mAppliedLowPower) {
                 slowChange = false;
@@ -1047,6 +1073,14 @@
 
         }
 
+        // Log any changes to what is currently driving the brightness setting.
+        if (!mBrightnessReasonTemp.equals(mBrightnessReason) || brightnessAdjustmentFlags != 0) {
+            Slog.v(TAG, "Brightness [" + brightness + "] reason changing to: '"
+                    + mBrightnessReasonTemp.toString(brightnessAdjustmentFlags)
+                    + "', previous reason: '" + mBrightnessReason + "'.");
+            mBrightnessReason.set(mBrightnessReasonTemp);
+        }
+
         // Update display white-balance.
         if (mDisplayWhiteBalanceController != null) {
             if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) {
@@ -1737,6 +1771,7 @@
         pw.println("  mPendingScreenBrightnessSetting=" + mPendingScreenBrightnessSetting);
         pw.println("  mTemporaryScreenBrightness=" + mTemporaryScreenBrightness);
         pw.println("  mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
+        pw.println("  mBrightnessReason=" + mBrightnessReason);
         pw.println("  mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
         pw.println("  mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
         pw.println("  mScreenBrightnessForVr=" + mScreenBrightnessForVr);
@@ -1956,4 +1991,121 @@
             sendUpdatePowerState();
         }
     }
+
+    /**
+     * Stores data about why the brightness was changed.  Made up of one main
+     * {@code BrightnessReason.REASON_*} reason and various {@code BrightnessReason.MODIFIER_*}
+     * modifiers.
+     */
+    private final class BrightnessReason {
+        static final int REASON_UNKNOWN = 0;
+        static final int REASON_MANUAL = 1;
+        static final int REASON_DOZE = 2;
+        static final int REASON_DOZE_DEFAULT = 3;
+        static final int REASON_AUTOMATIC = 4;
+        static final int REASON_SCREEN_OFF = 5;
+        static final int REASON_VR = 6;
+        static final int REASON_OVERRIDE = 7;
+        static final int REASON_TEMPORARY = 8;
+        static final int REASON_BOOST = 9;
+        static final int REASON_MAX = REASON_BOOST;
+
+        static final int MODIFIER_DIMMED = 0x1;
+        static final int MODIFIER_LOW_POWER = 0x2;
+        static final int MODIFIER_MASK = 0x3;
+
+        // ADJUSTMENT_*
+        // These things can happen at any point, even if the main brightness reason doesn't
+        // fundamentally change, so they're not stored.
+
+        // Auto-brightness adjustment factor changed
+        static final int ADJUSTMENT_AUTO_TEMP = 0x1;
+        // Temporary adjustment to the auto-brightness adjustment factor.
+        static final int ADJUSTMENT_AUTO = 0x2;
+
+        // One of REASON_*
+        public int reason;
+        // Any number of MODIFIER_*
+        public int modifier;
+
+        public void set(BrightnessReason other) {
+            setReason(other == null ? REASON_UNKNOWN : other.reason);
+            setModifier(other == null ? 0 : other.modifier);
+        }
+
+        public void setReason(int reason) {
+            if (reason < REASON_UNKNOWN || reason > REASON_MAX) {
+                Slog.w(TAG, "brightness reason out of bounds: " + reason);
+            } else {
+                this.reason = reason;
+            }
+        }
+
+        public void setModifier(int modifier) {
+            if ((modifier & ~MODIFIER_MASK) != 0) {
+                Slog.w(TAG, "brightness modifier out of bounds: 0x"
+                        + Integer.toHexString(modifier));
+            } else {
+                this.modifier = modifier;
+            }
+        }
+
+        public void addModifier(int modifier) {
+            setModifier(modifier | this.modifier);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null || !(obj instanceof BrightnessReason)) {
+                return false;
+            }
+            BrightnessReason other = (BrightnessReason) obj;
+            return other.reason == reason && other.modifier == modifier;
+        }
+
+        @Override
+        public String toString() {
+            return toString(0);
+        }
+
+        public String toString(int adjustments) {
+            final StringBuilder sb = new StringBuilder();
+            sb.append(reasonToString(reason));
+            sb.append(" [");
+            if ((adjustments & ADJUSTMENT_AUTO_TEMP) != 0) {
+                sb.append(" temp_adj");
+            }
+            if ((adjustments & ADJUSTMENT_AUTO) != 0) {
+                sb.append(" auto_adj");
+            }
+            if ((modifier & MODIFIER_LOW_POWER) != 0) {
+                sb.append(" low_pwr");
+            }
+            if ((modifier & MODIFIER_DIMMED) != 0) {
+                sb.append(" dim");
+            }
+            int strlen = sb.length();
+            if (sb.charAt(strlen - 1) == '[') {
+                sb.setLength(strlen - 2);
+            } else {
+                sb.append(" ]");
+            }
+            return sb.toString();
+        }
+
+        private String reasonToString(int reason) {
+            switch (reason) {
+                case REASON_MANUAL: return "manual";
+                case REASON_DOZE: return "doze";
+                case REASON_DOZE_DEFAULT: return "doze_default";
+                case REASON_AUTOMATIC: return "automatic";
+                case REASON_SCREEN_OFF: return "screen_off";
+                case REASON_VR: return "vr";
+                case REASON_OVERRIDE: return "override";
+                case REASON_TEMPORARY: return "temporary";
+                case REASON_BOOST: return "boost";
+                default: return Integer.toString(reason);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 85fbdf6..b03dc3b 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -856,7 +856,7 @@
 
     private final class PhysicalDisplayEventReceiver extends DisplayEventReceiver {
         PhysicalDisplayEventReceiver(Looper looper) {
-            super(looper, VSYNC_SOURCE_APP);
+            super(looper, VSYNC_SOURCE_APP, CONFIG_CHANGED_EVENT_DISPATCH);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index 9e4c1cb..5584dcf 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.WifiDisplay;
 import android.hardware.display.WifiDisplaySessionInfo;
@@ -95,6 +96,12 @@
             Context context, Handler handler, Listener listener,
             PersistentDataStore persistentDataStore) {
         super(syncRoot, context, handler, listener, TAG);
+
+        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT)) {
+            throw new RuntimeException("WiFi display was requested, "
+                    + "but there is no WiFi Direct feature");
+        }
+
         mHandler = new WifiDisplayHandler(handler.getLooper());
         mPersistentDataStore = persistentDataStore;
         mSupportsProtectedBuffers = context.getResources().getBoolean(
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 b2420b5..7fb5b19 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -63,6 +63,8 @@
 import android.provider.Settings.System;
 import android.util.MathUtils;
 import android.util.Slog;
+import android.util.SparseIntArray;
+import android.view.Display;
 import android.view.SurfaceControl;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.AnimationUtils;
@@ -171,6 +173,11 @@
 
     private NightDisplayAutoMode mNightDisplayAutoMode;
 
+    /**
+     * Map of color modes -> display composition colorspace
+     */
+    private SparseIntArray mColorModeCompositionColorSpaces = null;
+
     public ColorDisplayService(Context context) {
         super(context);
         mHandler = new TintHandler(DisplayThread.get().getLooper());
@@ -226,7 +233,7 @@
         }
     }
 
-    private void onUserChanged(int userHandle) {
+    @VisibleForTesting void onUserChanged(int userHandle) {
         final ContentResolver cr = getContext().getContentResolver();
 
         if (mCurrentUser != UserHandle.USER_NULL) {
@@ -267,6 +274,30 @@
         return Secure.getIntForUser(cr, Secure.USER_SETUP_COMPLETE, 0, userHandle) == 1;
     }
 
+    private void setUpDisplayCompositionColorSpaces(Resources res) {
+        mColorModeCompositionColorSpaces = null;
+
+        final int[] colorModes = res.getIntArray(R.array.config_displayCompositionColorModes);
+        if (colorModes == null) {
+            return;
+        }
+
+        final int[] compSpaces = res.getIntArray(R.array.config_displayCompositionColorSpaces);
+        if (compSpaces == null) {
+            return;
+        }
+
+        if (colorModes.length != compSpaces.length) {
+            Slog.e(TAG, "Number of composition color spaces doesn't match specified color modes");
+            return;
+        }
+
+        mColorModeCompositionColorSpaces = new SparseIntArray(colorModes.length);
+        for (int i = 0; i < colorModes.length; i++) {
+            mColorModeCompositionColorSpaces.put(colorModes[i], compSpaces[i]);
+        }
+    }
+
     private void setUp() {
         Slog.d(TAG, "setUp: currentUser=" + mCurrentUser);
 
@@ -359,6 +390,8 @@
         onAccessibilityInversionChanged();
         onAccessibilityDaltonizerChanged();
 
+        setUpDisplayCompositionColorSpaces(getContext().getResources());
+
         // Set the color mode, if valid, and immediately apply the updated tint matrix based on the
         // existing activated state. This ensures consistency of tint across the color mode change.
         onDisplayColorModeChanged(getColorModeInternal());
@@ -394,7 +427,9 @@
     private void tearDown() {
         Slog.d(TAG, "tearDown: currentUser=" + mCurrentUser);
 
-        getContext().getContentResolver().unregisterContentObserver(mContentObserver);
+        if (mContentObserver != null) {
+            getContext().getContentResolver().unregisterContentObserver(mContentObserver);
+        }
 
         if (mNightDisplayTintController.isAvailable(getContext())) {
             if (mNightDisplayAutoMode != null) {
@@ -448,6 +483,14 @@
         }
     }
 
+    private int getCompositionColorSpace(int mode) {
+        if (mColorModeCompositionColorSpaces == null) {
+            return Display.COLOR_MODE_INVALID;
+        }
+
+        return mColorModeCompositionColorSpaces.get(mode, Display.COLOR_MODE_INVALID);
+    }
+
     private void onDisplayColorModeChanged(int mode) {
         if (mode == NOT_SET) {
             return;
@@ -463,12 +506,17 @@
                     .setMatrix(mNightDisplayTintController.getColorTemperatureSetting());
         }
 
+        // dtm.setColorMode() needs to be called before
+        // updateDisplayWhiteBalanceStatus(), this is because the latter calls
+        // DisplayTransformManager.needsLinearColorMatrix(), therefore it is dependent
+        // on the state of DisplayTransformManager.
+        final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
+        dtm.setColorMode(mode, mNightDisplayTintController.getMatrix(),
+                getCompositionColorSpace(mode));
+
         if (mDisplayWhiteBalanceTintController.isAvailable(getContext())) {
             updateDisplayWhiteBalanceStatus();
         }
-
-        final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
-        dtm.setColorMode(mode, mNightDisplayTintController.getMatrix());
     }
 
     private void onAccessibilityActivated() {
@@ -929,7 +977,7 @@
 
             if (mNightDisplayTintController.isActivatedStateNotSet()
                     || (mNightDisplayTintController.isActivated() != activate)) {
-                mNightDisplayTintController.setActivated(activate);
+                mNightDisplayTintController.setActivated(activate, activate ? start : end);
             }
 
             updateNextAlarm(mNightDisplayTintController.isActivated(), now);
@@ -1125,6 +1173,14 @@
 
         @Override
         public void setActivated(Boolean activated) {
+            setActivated(activated, LocalDateTime.now());
+        }
+
+        /**
+         * Use directly when it is important that the last activation time be exact (for example, an
+         * automatic change). Otherwise use {@link #setActivated(Boolean)}.
+         */
+        public void setActivated(Boolean activated, @NonNull LocalDateTime lastActivationTime) {
             if (activated == null) {
                 super.setActivated(null);
                 return;
@@ -1136,7 +1192,7 @@
                 // This is a true state change, so set this as the last activation time.
                 Secure.putStringForUser(getContext().getContentResolver(),
                         Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
-                        LocalDateTime.now().toString(),
+                        lastActivationTime.toString(),
                         mCurrentUser);
             }
 
diff --git a/services/core/java/com/android/server/display/color/DisplayTransformManager.java b/services/core/java/com/android/server/display/color/DisplayTransformManager.java
index 5ff45a9..d5706a5 100644
--- a/services/core/java/com/android/server/display/color/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/color/DisplayTransformManager.java
@@ -26,6 +26,7 @@
 import android.os.SystemProperties;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.view.Display;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -77,6 +78,8 @@
     @VisibleForTesting
     static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
     @VisibleForTesting
+    static final String PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE = "persist.sys.sf.color_mode";
+    @VisibleForTesting
     static final String PERSISTENT_PROPERTY_DISPLAY_COLOR = "persist.sys.sf.native_mode";
 
     private static final float COLOR_SATURATION_NATURAL = 1.0f;
@@ -251,23 +254,24 @@
     /**
      * Sets color mode and updates night display transform values.
      */
-    public boolean setColorMode(int colorMode, float[] nightDisplayMatrix) {
+    public boolean setColorMode(int colorMode, float[] nightDisplayMatrix,
+            int compositionColorMode) {
         if (colorMode == ColorDisplayManager.COLOR_MODE_NATURAL) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setDisplayColor(DISPLAY_COLOR_MANAGED);
+            setDisplayColor(DISPLAY_COLOR_MANAGED, compositionColorMode);
         } else if (colorMode == ColorDisplayManager.COLOR_MODE_BOOSTED) {
             applySaturation(COLOR_SATURATION_BOOSTED);
-            setDisplayColor(DISPLAY_COLOR_MANAGED);
+            setDisplayColor(DISPLAY_COLOR_MANAGED, compositionColorMode);
         } else if (colorMode == ColorDisplayManager.COLOR_MODE_SATURATED) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setDisplayColor(DISPLAY_COLOR_UNMANAGED);
+            setDisplayColor(DISPLAY_COLOR_UNMANAGED, compositionColorMode);
         } else if (colorMode == ColorDisplayManager.COLOR_MODE_AUTOMATIC) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setDisplayColor(DISPLAY_COLOR_ENHANCED);
+            setDisplayColor(DISPLAY_COLOR_ENHANCED, compositionColorMode);
         } else if (colorMode >= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MIN
                 && colorMode <= ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MAX) {
             applySaturation(COLOR_SATURATION_NATURAL);
-            setDisplayColor(colorMode);
+            setDisplayColor(colorMode, compositionColorMode);
         }
 
         setColorMatrix(LEVEL_COLOR_MATRIX_NIGHT_DISPLAY, nightDisplayMatrix);
@@ -323,13 +327,21 @@
     /**
      * Toggles native mode on/off in SurfaceFlinger.
      */
-    private void setDisplayColor(int color) {
+    private void setDisplayColor(int color, int compositionColorMode) {
         SystemProperties.set(PERSISTENT_PROPERTY_DISPLAY_COLOR, Integer.toString(color));
+        if (compositionColorMode != Display.COLOR_MODE_INVALID) {
+            SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE,
+                Integer.toString(compositionColorMode));
+        }
+
         final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
         if (flinger != null) {
             final Parcel data = Parcel.obtain();
             data.writeInterfaceToken("android.ui.ISurfaceComposer");
             data.writeInt(color);
+            if (compositionColorMode != Display.COLOR_MODE_INVALID) {
+                data.writeInt(compositionColorMode);
+            }
             try {
                 flinger.transact(SURFACE_FLINGER_TRANSACTION_DISPLAY_COLOR, data, null, 0);
             } catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java b/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
index 532bbed..3580897 100644
--- a/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
+++ b/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
@@ -18,6 +18,7 @@
 
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.display.utils.RollingBuffer;
 
 import java.io.PrintWriter;
@@ -35,7 +36,7 @@
  * - {@link WeightedMovingAverageAmbientFilter}
  *   A weighted average prioritising recent changes.
  */
-abstract class AmbientFilter {
+abstract public class AmbientFilter {
 
     protected static final boolean DEBUG = false; // Enable for verbose logs.
 
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
index 0f86b47..02ec10e 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
@@ -20,6 +20,7 @@
 import android.util.Slog;
 import android.util.Spline;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
@@ -53,18 +54,22 @@
     private Callbacks mCallbacks;
 
     private AmbientSensor.AmbientBrightnessSensor mBrightnessSensor;
-    private AmbientFilter mBrightnessFilter;
+
+    @VisibleForTesting
+    AmbientFilter mBrightnessFilter;
     private AmbientSensor.AmbientColorTemperatureSensor mColorTemperatureSensor;
-    private AmbientFilter mColorTemperatureFilter;
+
+    @VisibleForTesting
+    AmbientFilter mColorTemperatureFilter;
     private DisplayWhiteBalanceThrottler mThrottler;
 
-    // When the brightness drops below a certain threshold, it affects the color temperature
-    // accuracy, so we fall back to a fixed ambient color temperature.
-    private final float mLowLightAmbientBrightnessThreshold;
     private final float mLowLightAmbientColorTemperature;
+    private final float mHighLightAmbientColorTemperature;
 
     private float mAmbientColorTemperature;
-    private float mPendingAmbientColorTemperature;
+
+    @VisibleForTesting
+    float mPendingAmbientColorTemperature;
     private float mLastAmbientColorTemperature;
 
     private ColorDisplayServiceInternal mColorDisplayServiceInternal;
@@ -79,6 +84,17 @@
     // A piecewise linear relationship between ambient and display color temperatures.
     private Spline.LinearSpline mAmbientToDisplayColorTemperatureSpline;
 
+    // In very low or very high brightness conditions ambient EQ should to set to a default
+    // instead of using mAmbientToDisplayColorTemperatureSpline. However, setting ambient EQ
+    // based on thresholds can cause the display to rapidly change color temperature. To solve
+    // this, mLowLightAmbientBrightnessToBiasSpline and mHighLightAmbientBrightnessToBiasSpline
+    // are used to smoothly interpolate from ambient color temperature to the defaults.
+    // A piecewise linear relationship between low light brightness and low light bias.
+    private Spline.LinearSpline mLowLightAmbientBrightnessToBiasSpline;
+
+    // A piecewise linear relationship between high light brightness and high light bias.
+    private Spline.LinearSpline mHighLightAmbientBrightnessToBiasSpline;
+
     /**
      * @param brightnessSensor
      *      The sensor used to detect changes in the ambient brightness.
@@ -93,12 +109,22 @@
      * @param throttler
      *      The throttler used to determine whether the new display color temperature should be
      *      updated or not.
-     * @param lowLightAmbientBrightnessThreshold
-     *      The ambient brightness threshold beneath which we fall back to a fixed ambient color
-     *      temperature.
+     * @param lowLightAmbientBrightnesses
+     *      The ambient brightness used to map the ambient brightnesses to the biases used to
+     *      interpolate to lowLightAmbientColorTemperature.
+     * @param lowLightAmbientBiases
+     *      The biases used to map the ambient brightnesses to the biases used to interpolate to
+     *      lowLightAmbientColorTemperature.
      * @param lowLightAmbientColorTemperature
-     *      The ambient color temperature to which we fall back when the ambient brightness drops
-     *      beneath a certain threshold.
+     *      The ambient color temperature to which we interpolate to based on the low light curve.
+     * @param highLightAmbientBrightnesses
+     *      The ambient brightness used to map the ambient brightnesses to the biases used to
+     *      interpolate to highLightAmbientColorTemperature.
+     * @param highLightAmbientBiases
+     *      The biases used to map the ambient brightnesses to the biases used to interpolate to
+     *      highLightAmbientColorTemperature.
+     * @param highLightAmbientColorTemperature
+     *      The ambient color temperature to which we interpolate to based on the high light curve.
      * @param ambientColorTemperatures
      *      The ambient color tempeartures used to map the ambient color temperature to the display
      *      color temperature (or null if no mapping is necessary).
@@ -119,7 +145,10 @@
             @NonNull AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor,
             @NonNull AmbientFilter colorTemperatureFilter,
             @NonNull DisplayWhiteBalanceThrottler throttler,
-            float lowLightAmbientBrightnessThreshold, float lowLightAmbientColorTemperature,
+            float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBiases,
+            float lowLightAmbientColorTemperature,
+            float[] highLightAmbientBrightnesses, float[] highLightAmbientBiases,
+            float highLightAmbientColorTemperature,
             float[] ambientColorTemperatures, float[] displayColorTemperatures) {
         validateArguments(brightnessSensor, brightnessFilter, colorTemperatureSensor,
                 colorTemperatureFilter, throttler);
@@ -131,8 +160,8 @@
         mColorTemperatureSensor = colorTemperatureSensor;
         mColorTemperatureFilter = colorTemperatureFilter;
         mThrottler = throttler;
-        mLowLightAmbientBrightnessThreshold = lowLightAmbientBrightnessThreshold;
         mLowLightAmbientColorTemperature = lowLightAmbientColorTemperature;
+        mHighLightAmbientColorTemperature = highLightAmbientColorTemperature;
         mAmbientColorTemperature = -1.0f;
         mPendingAmbientColorTemperature = -1.0f;
         mLastAmbientColorTemperature = -1.0f;
@@ -140,9 +169,55 @@
         mAmbientColorTemperatureOverride = -1.0f;
 
         try {
+            mLowLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline(
+                    lowLightAmbientBrightnesses, lowLightAmbientBiases);
+        } catch (Exception e) {
+            Slog.e(TAG, "failed to create low light ambient brightness to bias spline.", e);
+            mLowLightAmbientBrightnessToBiasSpline = null;
+        }
+        if (mLowLightAmbientBrightnessToBiasSpline != null) {
+            if (mLowLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f ||
+                    mLowLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY)
+                    != 1.0f) {
+                Slog.d(TAG, "invalid low light ambient brightness to bias spline, "
+                        + "bias must begin at 0.0 and end at 1.0.");
+                mLowLightAmbientBrightnessToBiasSpline = null;
+            }
+        }
+
+        try {
+            mHighLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline(
+                    highLightAmbientBrightnesses, highLightAmbientBiases);
+        } catch (Exception e) {
+            Slog.e(TAG, "failed to create high light ambient brightness to bias spline.", e);
+            mHighLightAmbientBrightnessToBiasSpline = null;
+        }
+        if (mHighLightAmbientBrightnessToBiasSpline != null) {
+            if (mHighLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f ||
+                    mHighLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY)
+                    != 1.0f) {
+                Slog.d(TAG, "invalid high light ambient brightness to bias spline, "
+                        + "bias must begin at 0.0 and end at 1.0.");
+                mHighLightAmbientBrightnessToBiasSpline = null;
+            }
+        }
+
+        if (mLowLightAmbientBrightnessToBiasSpline != null &&
+                mHighLightAmbientBrightnessToBiasSpline != null) {
+            if (lowLightAmbientBrightnesses[lowLightAmbientBrightnesses.length - 1] >
+                    highLightAmbientBrightnesses[0]) {
+                Slog.d(TAG, "invalid low light and high light ambient brightness to bias spline "
+                        + "combination, defined domains must not intersect.");
+                mLowLightAmbientBrightnessToBiasSpline = null;
+                mHighLightAmbientBrightnessToBiasSpline = null;
+            }
+        }
+
+        try {
             mAmbientToDisplayColorTemperatureSpline = new Spline.LinearSpline(
                     ambientColorTemperatures, displayColorTemperatures);
         } catch (Exception e) {
+            Slog.e(TAG, "failed to create ambient to display color temperature spline.", e);
             mAmbientToDisplayColorTemperatureSpline = null;
         }
 
@@ -238,9 +313,8 @@
         mColorTemperatureSensor.dump(writer);
         mColorTemperatureFilter.dump(writer);
         mThrottler.dump(writer);
-        writer.println("  mLowLightAmbientBrightnessThreshold="
-                + mLowLightAmbientBrightnessThreshold);
         writer.println("  mLowLightAmbientColorTemperature=" + mLowLightAmbientColorTemperature);
+        writer.println("  mHighLightAmbientColorTemperature=" + mHighLightAmbientColorTemperature);
         writer.println("  mAmbientColorTemperature=" + mAmbientColorTemperature);
         writer.println("  mPendingAmbientColorTemperature=" + mPendingAmbientColorTemperature);
         writer.println("  mLastAmbientColorTemperature=" + mLastAmbientColorTemperature);
@@ -248,6 +322,10 @@
         writer.println("  mAmbientColorTemperatureOverride=" + mAmbientColorTemperatureOverride);
         writer.println("  mAmbientToDisplayColorTemperatureSpline="
                 + mAmbientToDisplayColorTemperatureSpline);
+        writer.println("  mLowLightAmbientBrightnessToBiasSpline="
+                + mLowLightAmbientBrightnessToBiasSpline);
+        writer.println("  mHighLightAmbientBrightnessToBiasSpline="
+                + mHighLightAmbientBrightnessToBiasSpline);
     }
 
     @Override // AmbientSensor.AmbientBrightnessSensor.Callbacks
@@ -276,15 +354,21 @@
                 mAmbientToDisplayColorTemperatureSpline.interpolate(ambientColorTemperature);
         }
 
-        final float ambientBrightness = mBrightnessFilter.getEstimate(time);
-        if (ambientBrightness < mLowLightAmbientBrightnessThreshold) {
-            if (mLoggingEnabled) {
-                Slog.d(TAG, "low light ambient brightness: " + ambientBrightness + " < "
-                        + mLowLightAmbientBrightnessThreshold
-                        + ", falling back to fixed ambient color temperature: "
-                        + ambientColorTemperature + " => " + mLowLightAmbientColorTemperature);
-            }
-            ambientColorTemperature = mLowLightAmbientColorTemperature;
+        float ambientBrightness = mBrightnessFilter.getEstimate(time);
+
+        if (ambientColorTemperature != -1.0f &&
+                mLowLightAmbientBrightnessToBiasSpline != null) {
+            float bias = mLowLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness);
+            ambientColorTemperature =
+                    bias * ambientColorTemperature + (1.0f - bias)
+                    * mLowLightAmbientColorTemperature;
+        }
+        if (ambientColorTemperature != -1.0f &&
+                mHighLightAmbientBrightnessToBiasSpline != null) {
+            float bias = mHighLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness);
+            ambientColorTemperature =
+                    (1.0f - bias) * ambientColorTemperature + bias
+                    * mHighLightAmbientColorTemperature;
         }
 
         if (mAmbientColorTemperatureOverride != -1.0f) {
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
index 6ff2b09..bf0a1d1 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
@@ -63,19 +63,34 @@
                 createColorTemperatureSensor(handler, sensorManager, resources);
         final AmbientFilter colorTemperatureFilter = createColorTemperatureFilter(resources);
         final DisplayWhiteBalanceThrottler throttler = createThrottler(resources);
-        final float lowLightAmbientBrightnessThreshold = getFloat(resources,
-                com.android.internal.R.dimen
-                .config_displayWhiteBalanceLowLightAmbientBrightnessThreshold);
+        final float[] displayWhiteBalanceLowLightAmbientBrightnesses = getFloatArray(resources,
+                com.android.internal.R.array
+                .config_displayWhiteBalanceLowLightAmbientBrightnesses);
+        final float[] displayWhiteBalanceLowLightAmbientBiases = getFloatArray(resources,
+                com.android.internal.R.array
+                .config_displayWhiteBalanceLowLightAmbientBiases);
         final float lowLightAmbientColorTemperature = getFloat(resources,
                 com.android.internal.R.dimen
                 .config_displayWhiteBalanceLowLightAmbientColorTemperature);
+        final float[] displayWhiteBalanceHighLightAmbientBrightnesses = getFloatArray(resources,
+                com.android.internal.R.array
+                .config_displayWhiteBalanceHighLightAmbientBrightnesses);
+        final float[] displayWhiteBalanceHighLightAmbientBiases = getFloatArray(resources,
+                com.android.internal.R.array
+                .config_displayWhiteBalanceHighLightAmbientBiases);
+        final float highLightAmbientColorTemperature = getFloat(resources,
+                com.android.internal.R.dimen
+                .config_displayWhiteBalanceHighLightAmbientColorTemperature);
         final float[] ambientColorTemperatures = getFloatArray(resources,
                 com.android.internal.R.array.config_displayWhiteBalanceAmbientColorTemperatures);
         final float[] displayColorTempeartures = getFloatArray(resources,
                 com.android.internal.R.array.config_displayWhiteBalanceDisplayColorTemperatures);
         final DisplayWhiteBalanceController controller = new DisplayWhiteBalanceController(
                 brightnessSensor, brightnessFilter, colorTemperatureSensor, colorTemperatureFilter,
-                throttler, lowLightAmbientBrightnessThreshold, lowLightAmbientColorTemperature,
+                throttler, displayWhiteBalanceLowLightAmbientBrightnesses,
+                displayWhiteBalanceLowLightAmbientBiases, lowLightAmbientColorTemperature,
+                displayWhiteBalanceHighLightAmbientBrightnesses,
+                displayWhiteBalanceHighLightAmbientBiases, highLightAmbientColorTemperature,
                 ambientColorTemperatures, displayColorTempeartures);
         brightnessSensor.setCallbacks(controller);
         colorTemperatureSensor.setCallbacks(controller);
@@ -100,8 +115,7 @@
      * Creates a BrightnessFilter which functions as a weighted moving average buffer for recent
      * brightness values.
      */
-    @VisibleForTesting
-    static AmbientFilter createBrightnessFilter(Resources resources) {
+    public static AmbientFilter createBrightnessFilter(Resources resources) {
         final int horizon = resources.getInteger(
                 com.android.internal.R.integer.config_displayWhiteBalanceBrightnessFilterHorizon);
         final float intercept = getFloat(resources,
@@ -114,7 +128,6 @@
                 + "expected config_displayWhiteBalanceBrightnessFilterIntercept");
     }
 
-
     /**
      * Creates an ambient color sensor instance to redirect sensor data to callbacks.
      */
diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java
index d439653..955f177 100644
--- a/services/core/java/com/android/server/gpu/GpuService.java
+++ b/services/core/java/com/android/server/gpu/GpuService.java
@@ -64,7 +64,6 @@
 
     private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
     private static final String GAME_DRIVER_WHITELIST_FILENAME = "whitelist.txt";
-    private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
     private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP;
 
     private final Context mContext;
@@ -230,9 +229,6 @@
         // Reset the whitelist.
         Settings.Global.putString(mContentResolver,
                                   Settings.Global.GAME_DRIVER_WHITELIST, "");
-        // Reset the sphal libraries
-        Settings.Global.putString(mContentResolver,
-                                  Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, "");
         mGameDriverVersionCode = driverInfo.longVersionCode;
 
         try {
@@ -241,10 +237,6 @@
 
             assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_WHITELIST_FILENAME,
                     Settings.Global.GAME_DRIVER_WHITELIST, ",");
-
-            assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_SPHAL_LIBRARIES_FILENAME,
-                    Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, ":");
-
         } catch (PackageManager.NameNotFoundException e) {
             if (DEBUG) {
                 Slog.w(TAG, "driver package '" + mDriverPackageName + "' not installed");
diff --git a/services/core/java/com/android/server/hdmi/ArcInitiationActionFromAvr.java b/services/core/java/com/android/server/hdmi/ArcInitiationActionFromAvr.java
index 137833c..6d26934 100644
--- a/services/core/java/com/android/server/hdmi/ArcInitiationActionFromAvr.java
+++ b/services/core/java/com/android/server/hdmi/ArcInitiationActionFromAvr.java
@@ -27,9 +27,6 @@
 
     // the required maximum response time specified in CEC 9.2
     private static final int TIMEOUT_MS = 1000;
-    private static final int MAX_RETRY_COUNT = 5;
-
-    private int mSendRequestActiveSourceRetryCount = 0;
 
     ArcInitiationActionFromAvr(HdmiCecLocalDevice source) {
         super(source);
@@ -64,12 +61,7 @@
                 return true;
             case Constants.MESSAGE_REPORT_ARC_INITIATED:
                 mState = STATE_ARC_INITIATED;
-                if (audioSystem().getActiveSource().physicalAddress != getSourcePath()
-                        && audioSystem().isSystemAudioActivated()) {
-                    sendRequestActiveSource();
-                } else {
-                    finish();
-                }
+                finish();
                 return true;
         }
         return false;
@@ -99,24 +91,8 @@
     }
 
     private void handleInitiateArcTimeout() {
+        // Keep ARC status as what it is when TV does not respond to ARC init
         HdmiLogger.debug("handleInitiateArcTimeout");
-        audioSystem().setArcStatus(false);
         finish();
     }
-
-    protected void sendRequestActiveSource() {
-        sendCommand(HdmiCecMessageBuilder.buildRequestActiveSource(getSourceAddress()),
-                result -> {
-                    if (result != SendMessageResult.SUCCESS) {
-                        if (mSendRequestActiveSourceRetryCount < MAX_RETRY_COUNT) {
-                            mSendRequestActiveSourceRetryCount++;
-                            sendRequestActiveSource();
-                        } else {
-                            finish();
-                        }
-                    } else {
-                        finish();
-                    }
-                });
-    }
 }
diff --git a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java
index eb7c0cd..dedf2e2 100644
--- a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java
+++ b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java
@@ -76,6 +76,11 @@
         sendCommand(HdmiCecMessageBuilder.buildTerminateArc(getSourceAddress(), Constants.ADDR_TV),
             result -> {
                 if (result != SendMessageResult.SUCCESS) {
+                    // If the physical connection is already off or TV does not handle
+                    // Terminate ARC, turn off ARC internally.
+                    if (result == SendMessageResult.NACK) {
+                        audioSystem().setArcStatus(false);
+                    }
                     HdmiLogger.debug("Terminate ARC was not successfully sent.");
                     finish();
                 }
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 7c42cc2..cfbf8bc 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -86,6 +86,82 @@
     /** Logical address used to indicate the source comes from internal device. */
     public static final int ADDR_INTERNAL = HdmiDeviceInfo.ADDR_INTERNAL;
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        MESSAGE_FEATURE_ABORT,
+        MESSAGE_IMAGE_VIEW_ON,
+        MESSAGE_TUNER_STEP_INCREMENT,
+        MESSAGE_TUNER_STEP_DECREMENT,
+        MESSAGE_TUNER_DEVICE_STATUS,
+        MESSAGE_GIVE_TUNER_DEVICE_STATUS,
+        MESSAGE_RECORD_ON,
+        MESSAGE_RECORD_STATUS,
+        MESSAGE_RECORD_OFF,
+        MESSAGE_TEXT_VIEW_ON,
+        MESSAGE_RECORD_TV_SCREEN,
+        MESSAGE_GIVE_DECK_STATUS,
+        MESSAGE_DECK_STATUS,
+        MESSAGE_SET_MENU_LANGUAGE,
+        MESSAGE_CLEAR_ANALOG_TIMER,
+        MESSAGE_SET_ANALOG_TIMER,
+        MESSAGE_TIMER_STATUS,
+        MESSAGE_STANDBY,
+        MESSAGE_PLAY,
+        MESSAGE_DECK_CONTROL,
+        MESSAGE_TIMER_CLEARED_STATUS,
+        MESSAGE_USER_CONTROL_PRESSED,
+        MESSAGE_USER_CONTROL_RELEASED,
+        MESSAGE_GIVE_OSD_NAME,
+        MESSAGE_SET_OSD_NAME,
+        MESSAGE_SET_OSD_STRING,
+        MESSAGE_SET_TIMER_PROGRAM_TITLE,
+        MESSAGE_SYSTEM_AUDIO_MODE_REQUEST,
+        MESSAGE_GIVE_AUDIO_STATUS,
+        MESSAGE_SET_SYSTEM_AUDIO_MODE,
+        MESSAGE_REPORT_AUDIO_STATUS,
+        MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS,
+        MESSAGE_SYSTEM_AUDIO_MODE_STATUS,
+        MESSAGE_ROUTING_CHANGE,
+        MESSAGE_ROUTING_INFORMATION,
+        MESSAGE_ACTIVE_SOURCE,
+        MESSAGE_GIVE_PHYSICAL_ADDRESS,
+        MESSAGE_REPORT_PHYSICAL_ADDRESS,
+        MESSAGE_REQUEST_ACTIVE_SOURCE,
+        MESSAGE_SET_STREAM_PATH,
+        MESSAGE_DEVICE_VENDOR_ID,
+        MESSAGE_VENDOR_COMMAND,
+        MESSAGE_VENDOR_REMOTE_BUTTON_DOWN,
+        MESSAGE_VENDOR_REMOTE_BUTTON_UP,
+        MESSAGE_GIVE_DEVICE_VENDOR_ID,
+        MESSAGE_MENU_REQUEST,
+        MESSAGE_MENU_STATUS,
+        MESSAGE_GIVE_DEVICE_POWER_STATUS,
+        MESSAGE_REPORT_POWER_STATUS,
+        MESSAGE_GET_MENU_LANGUAGE,
+        MESSAGE_SELECT_ANALOG_SERVICE,
+        MESSAGE_SELECT_DIGITAL_SERVICE,
+        MESSAGE_SET_DIGITAL_TIMER,
+        MESSAGE_CLEAR_DIGITAL_TIMER,
+        MESSAGE_SET_AUDIO_RATE,
+        MESSAGE_INACTIVE_SOURCE,
+        MESSAGE_CEC_VERSION,
+        MESSAGE_GET_CEC_VERSION,
+        MESSAGE_VENDOR_COMMAND_WITH_ID,
+        MESSAGE_CLEAR_EXTERNAL_TIMER,
+        MESSAGE_SET_EXTERNAL_TIMER,
+        MESSAGE_REPORT_SHORT_AUDIO_DESCRIPTOR,
+        MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR,
+        MESSAGE_INITIATE_ARC,
+        MESSAGE_REPORT_ARC_INITIATED,
+        MESSAGE_REPORT_ARC_TERMINATED,
+        MESSAGE_REQUEST_ARC_INITIATION,
+        MESSAGE_REQUEST_ARC_TERMINATION,
+        MESSAGE_TERMINATE_ARC,
+        MESSAGE_CDC_MESSAGE,
+        MESSAGE_ABORT,
+    })
+    public @interface FeatureOpcode {}
+
     static final int MESSAGE_FEATURE_ABORT = 0x00;
     static final int MESSAGE_IMAGE_VIEW_ON = 0x04;
     static final int MESSAGE_TUNER_STEP_INCREMENT = 0x05;
@@ -163,6 +239,18 @@
     static final int TRUE = 1;
     static final int FALSE = 0;
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        ABORT_NO_ERROR,
+        ABORT_UNRECOGNIZED_OPCODE,
+        ABORT_NOT_IN_CORRECT_MODE,
+        ABORT_CANNOT_PROVIDE_SOURCE,
+        ABORT_INVALID_OPERAND,
+        ABORT_REFUSED,
+        ABORT_UNABLE_TO_DETERMINE,
+    })
+    public @interface AbortReason {}
+
     // Internal abort error code. It's the same as success.
     static final int ABORT_NO_ERROR = -1;
     // Constants related to operands of HDMI CEC commands.
diff --git a/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java b/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java
index 15ec486..46b4f48 100644
--- a/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java
+++ b/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java
@@ -64,7 +64,7 @@
         }
     }
 
-    private void removeActiveSource() {
+    protected void removeActiveSource() {
         // Uses iterator to remove elements while looping through the list.
         for (Iterator<HdmiCecMessage> iter = mBuffer.iterator(); iter.hasNext(); ) {
             HdmiCecMessage message = iter.next();
diff --git a/services/core/java/com/android/server/hdmi/DetectTvSystemAudioModeSupportAction.java b/services/core/java/com/android/server/hdmi/DetectTvSystemAudioModeSupportAction.java
index 7187319..dc53688 100644
--- a/services/core/java/com/android/server/hdmi/DetectTvSystemAudioModeSupportAction.java
+++ b/services/core/java/com/android/server/hdmi/DetectTvSystemAudioModeSupportAction.java
@@ -26,9 +26,11 @@
 
     // State that waits for <Active Source> once send <Request Active Source>.
     private static final int STATE_WAITING_FOR_FEATURE_ABORT = 1;
+    private static final int STATE_WAITING_FOR_SET_SAM = 2;
+    private int mSendSetSystemAudioModeRetryCount = 0;
+    static final int MAX_RETRY_COUNT = 5;
 
     private TvSystemAudioModeSupportedCallback mCallback;
-    private int mState;
 
     DetectTvSystemAudioModeSupportAction(HdmiCecLocalDevice source,
             TvSystemAudioModeSupportedCallback callback) {
@@ -50,8 +52,18 @@
             if (mState != STATE_WAITING_FOR_FEATURE_ABORT) {
                 return false;
             }
-            if ((cmd.getParams()[0] & 0xFF) == Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE) {
-                finishAction(false);
+            if (HdmiUtils.getAbortFeatureOpcode(cmd) == Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE) {
+                if (HdmiUtils.getAbortReason(cmd) == Constants.ABORT_NOT_IN_CORRECT_MODE) {
+                    mActionTimer.clearTimerMessage();
+                    mState = STATE_WAITING_FOR_SET_SAM;
+                    // Outgoing User Control Press commands, when in 'Press and Hold' mode, should
+                    // be this much apart from the adjacent one so as not to place unnecessarily
+                    // heavy load on the CEC line. We also wait this much time to send the next
+                    // retry of the System Audio Mode support detection message.
+                    addTimer(mState, HdmiConfig.IRT_MS);
+                } else {
+                    finishAction(false);
+                }
                 return true;
             }
         }
@@ -68,6 +80,18 @@
             case STATE_WAITING_FOR_FEATURE_ABORT:
                 finishAction(true);
                 break;
+            case STATE_WAITING_FOR_SET_SAM:
+                mSendSetSystemAudioModeRetryCount++;
+                if (mSendSetSystemAudioModeRetryCount < MAX_RETRY_COUNT) {
+                    mState = STATE_WAITING_FOR_FEATURE_ABORT;
+                    addTimer(mState, HdmiConfig.TIMEOUT_MS);
+                    sendSetSystemAudioMode();
+                } else {
+                    finishAction(false);
+                }
+                break;
+            default:
+                return;
         }
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 86be585..6174e54 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -580,7 +580,9 @@
     @ServiceThreadOnly
     private void onReceiveCommand(HdmiCecMessage message) {
         assertRunOnServiceThread();
-        if (isAcceptableAddress(message.getDestination()) && mService.handleCecCommand(message)) {
+        if ((isAcceptableAddress(message.getDestination())
+            || !mService.isAddressAllocated())
+            && mService.handleCecCommand(message)) {
             return;
         }
         // Not handled message, so we will reply it with <Feature Abort>.
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 78b091e..a358707 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -20,6 +20,7 @@
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.hardware.hdmi.IHdmiControlCallback;
 import android.hardware.input.InputManager;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -426,15 +427,26 @@
         assertRunOnServiceThread();
         // Note that since this method is called after logical address allocation is done,
         // mDeviceInfo should not be null.
+        buildAndSendSetOsdName(message.getSource());
+        return true;
+    }
+
+    protected void buildAndSendSetOsdName(int dest) {
         HdmiCecMessage cecMessage =
-                HdmiCecMessageBuilder.buildSetOsdNameCommand(
-                        mAddress, message.getSource(), mDeviceInfo.getDisplayName());
+            HdmiCecMessageBuilder.buildSetOsdNameCommand(
+                mAddress, dest, mDeviceInfo.getDisplayName());
         if (cecMessage != null) {
-            mService.sendCecCommand(cecMessage);
+            mService.sendCecCommand(cecMessage, new SendMessageCallback() {
+                @Override
+                public void onSendCompleted(int error) {
+                    if (error != SendMessageResult.SUCCESS) {
+                        HdmiLogger.debug("Failed to send cec command " + cecMessage);
+                    }
+                }
+            });
         } else {
             Slog.w(TAG, "Failed to build <Get Osd Name>:" + mDeviceInfo.getDisplayName());
         }
-        return true;
     }
 
     // Audio System device with no Playback device type
@@ -864,7 +876,7 @@
     }
 
     ActiveSource getActiveSource() {
-        return mService.getActiveSource();
+        return mService.getLocalActiveSource();
     }
 
     void setActiveSource(ActiveSource newActive) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 82aacfe..4f4baab 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -110,6 +110,12 @@
     // device id is used as key of container.
     private final SparseArray<HdmiDeviceInfo> mDeviceInfos = new SparseArray<>();
 
+    // Message buffer used to buffer selected messages to process later. <Active Source>
+    // from a source device, for instance, needs to be buffered if the device is not
+    // discovered yet. The buffered commands are taken out and when they are ready to
+    // handle.
+    private final DelayedMessageBuffer mDelayedMessageBuffer = new DelayedMessageBuffer(this);
+
     protected HdmiCecLocalDeviceAudioSystem(HdmiControlService service) {
         super(service, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
         mRoutingControlFeatureEnabled =
@@ -151,6 +157,9 @@
             }
             mPortIdToTvInputs.put(info.getPortId(), inputId);
             mTvInputsToDeviceInfo.put(inputId, info);
+            if (info.isCecDevice()) {
+                processDelayedActiveSource(info.getLogicalAddress());
+            }
         }
     }
 
@@ -167,6 +176,15 @@
         }
     }
 
+    @Override
+    @ServiceThreadOnly
+    protected boolean isInputReady(int portId) {
+        assertRunOnServiceThread();
+        String tvInputId = mPortIdToTvInputs.get(portId);
+        HdmiDeviceInfo info = mTvInputsToDeviceInfo.get(tvInputId);
+        return info != null;
+    }
+
     /**
      * Called when a device is newly added or a new device is detected or
      * an existing device is updated.
@@ -233,6 +251,7 @@
     @VisibleForTesting
     protected HdmiDeviceInfo addDeviceInfo(HdmiDeviceInfo deviceInfo) {
         assertRunOnServiceThread();
+        mService.checkLogicalAddressConflictAndReallocate(deviceInfo.getLogicalAddress());
         HdmiDeviceInfo oldDeviceInfo = getCecDeviceInfo(deviceInfo.getLogicalAddress());
         if (oldDeviceInfo != null) {
             removeDeviceInfo(deviceInfo.getId());
@@ -304,6 +323,15 @@
         }
         if (mService.getPortInfo(portId).getType() == HdmiPortInfo.PORT_OUTPUT) {
             mCecMessageCache.flushAll();
+            if (!connected) {
+                if (isSystemAudioActivated()) {
+                    mTvSystemAudioModeSupport = null;
+                    checkSupportAndSetSystemAudioMode(false);
+                }
+                if (isArcEnabled()) {
+                    setArcStatus(false);
+                }
+            }
         } else if (!connected && mPortIdToTvInputs.get(portId) != null) {
             String tvInputId = mPortIdToTvInputs.get(portId);
             HdmiDeviceInfo info = mTvInputsToDeviceInfo.get(tvInputId);
@@ -329,6 +357,9 @@
     @ServiceThreadOnly
     protected void onStandby(boolean initiatedByCec, int standbyAction) {
         assertRunOnServiceThread();
+        // Invalidate the internal active source record when goes to standby
+        // This set will also update mIsActiveSource
+        mService.setActiveSource(Constants.ADDR_INVALID, Constants.INVALID_PHYSICAL_ADDRESS);
         mTvSystemAudioModeSupport = null;
         // Record the last state of System Audio Control before going to standby
         synchronized (mLock) {
@@ -403,6 +434,40 @@
                 Constants.PROPERTY_PREFERRED_ADDRESS_AUDIO_SYSTEM, String.valueOf(addr));
     }
 
+    @ServiceThreadOnly
+    void processDelayedActiveSource(int address) {
+        assertRunOnServiceThread();
+        mDelayedMessageBuffer.processActiveSource(address);
+    }
+
+    @Override
+    @ServiceThreadOnly
+    protected boolean handleActiveSource(HdmiCecMessage message) {
+        assertRunOnServiceThread();
+        int logicalAddress = message.getSource();
+        int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+        if (HdmiUtils.getLocalPortFromPhysicalAddress(
+            physicalAddress, mService.getPhysicalAddress())
+                == HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE) {
+            return super.handleActiveSource(message);
+        }
+        // If the new Active Source is under the current device, check if the device info and the TV
+        // input is ready to switch to the new Active Source. If not ready, buffer the cec command
+        // to handle later when the device is ready.
+        HdmiDeviceInfo info = getCecDeviceInfo(logicalAddress);
+        if (info == null) {
+            HdmiLogger.debug("Device info %X not found; buffering the command", logicalAddress);
+            mDelayedMessageBuffer.add(message);
+        } else if (!isInputReady(info.getPortId())){
+            HdmiLogger.debug("Input not ready for device: %X; buffering the command", info.getId());
+            mDelayedMessageBuffer.add(message);
+        } else {
+            mDelayedMessageBuffer.removeActiveSource();
+            return super.handleActiveSource(message);
+        }
+        return true;
+    }
+
     @Override
     @ServiceThreadOnly
     protected boolean handleReportPhysicalAddress(HdmiCecMessage message) {
@@ -783,6 +848,39 @@
         mService.sendCecCommand(
                 HdmiCecMessageBuilder.buildSetSystemAudioMode(
                         mAddress, Constants.ADDR_BROADCAST, systemAudioStatusOn));
+
+        if (systemAudioStatusOn) {
+            int sourcePhysicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+            if (sourcePhysicalAddress != getActiveSource().physicalAddress) {
+                // If the Active Source recorded by the current device is not synced up with TV,
+                // update the Active Source internally.
+                if (sourcePhysicalAddress == mService.getPhysicalAddress()) {
+                    // If the active path is the current device itself, update with local info
+                    if (mService.playback() != null) {
+                        setActiveSource(mService.playback().mAddress, sourcePhysicalAddress);
+                    } else {
+                        setActiveSource(mAddress, sourcePhysicalAddress);
+                    }
+                } else {
+                    // If it's not the current device, look for the device info from the list
+                    for (HdmiDeviceInfo info : HdmiUtils.sparseArrayToList(mDeviceInfos)) {
+                        if (info.getPhysicalAddress() == sourcePhysicalAddress) {
+                            setActiveSource(info.getLogicalAddress(), info.getPhysicalAddress());
+                            break;
+                        }
+                    }
+                }
+                // If the Active path from TV's System Audio Mode request does not belong to any
+                // device in the local device list, record the new Active physicalAddress with an
+                // unregistered logical address first. Then query the Active Source again.
+                if (sourcePhysicalAddress != getActiveSource().physicalAddress) {
+                    setActiveSource(Constants.ADDR_UNREGISTERED, sourcePhysicalAddress);
+                    mService.sendCecCommand(
+                        HdmiCecMessageBuilder.buildRequestActiveSource(mAddress));
+                }
+            }
+            switchInputOnReceivingNewActivePath(sourcePhysicalAddress);
+        }
         return true;
     }
 
@@ -918,17 +1016,25 @@
                 mService.announceSystemAudioModeChange(newSystemAudioMode);
             }
         }
+        // Since ARC is independent from System Audio Mode control, when the TV requests
+        // System Audio Mode off, it does not need to terminate ARC at the same time.
+        // When the current audio device is using ARC as a TV input and disables muting,
+        // it needs to automatically switch to the previous active input source when System
+        // Audio Mode is off even without terminating the ARC. This can stop the current
+        // audio device from playing audio when system audio mode is off.
+        if (mArcIntentUsed
+            && !mService.readBooleanSystemProperty(
+                    Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, true)
+            && !newSystemAudioMode
+            && getLocalActivePort() == Constants.CEC_SWITCH_ARC) {
+            routeToInputFromPortId(getRoutingPort());
+        }
         // Init arc whenever System Audio Mode is on
-        // Terminate arc when System Audio Mode is off
         // Since some TVs don't request ARC on with System Audio Mode on request
         if (SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)
-                && isDirectConnectToTv()) {
-            if (newSystemAudioMode && !isArcEnabled()
-                    && !hasAction(ArcInitiationActionFromAvr.class)) {
+                && isDirectConnectToTv() && mService.isSystemAudioActivated()) {
+            if (!hasAction(ArcInitiationActionFromAvr.class)) {
                 addAndStartAction(new ArcInitiationActionFromAvr(this));
-            } else if (!newSystemAudioMode && isArcEnabled()) {
-                removeAction(ArcTerminationActionFromAvr.class);
-                addAndStartAction(new ArcTerminationActionFromAvr(this));
             }
         }
     }
@@ -1101,6 +1207,7 @@
     }
 
     private void initArcOnFromAvr() {
+        removeAction(ArcTerminationActionFromAvr.class);
         if (SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)
                 && isDirectConnectToTv() && !isArcEnabled()) {
             removeAction(ArcInitiationActionFromAvr.class);
@@ -1142,6 +1249,11 @@
         }
         // Wake up if the current device if ready to route.
         mService.wakeUp();
+        if (getLocalActivePort() == portId) {
+            HdmiLogger.debug("Not switching to the same port " + portId);
+            return;
+        }
+        // Switch to HOME if the current active port is not HOME yet
         if (portId == Constants.CEC_SWITCH_HOME && mService.isPlaybackDevice()) {
             switchToHomeTvInput();
         } else if (portId == Constants.CEC_SWITCH_ARC) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 560f7a0..413e7a0 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -87,6 +87,10 @@
                 mAddress, mService.getPhysicalAddress(), mDeviceType));
         mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
                 mAddress, mService.getVendorId()));
+        // Actively send out an OSD name to the TV to update the TV panel in case the TV
+        // does not query the OSD name on time. This is not a required behavior by the spec.
+        // It is used for some TVs that need the OSD name update but don't query it themselves.
+        buildAndSendSetOsdName(Constants.ADDR_TV);
         if (mService.audioSystem() == null) {
             // If current device is not a functional audio system device,
             // send message to potential audio system device in the system to get the system
@@ -159,7 +163,17 @@
     @ServiceThreadOnly
     protected void onStandby(boolean initiatedByCec, int standbyAction) {
         assertRunOnServiceThread();
-        if (!mService.isControlEnabled() || initiatedByCec || !mAutoTvOff) {
+        if (!mService.isControlEnabled()) {
+            return;
+        }
+        if (mIsActiveSource) {
+            mService.sendCecCommand(HdmiCecMessageBuilder.buildInactiveSource(
+                mAddress, mService.getPhysicalAddress()));
+        }
+        // Invalidate the internal active source record when goes to standby
+        // This set will also update mIsActiveSource
+        mService.setActiveSource(Constants.ADDR_INVALID, Constants.INVALID_PHYSICAL_ADDRESS);
+        if (initiatedByCec || !mAutoTvOff) {
             return;
         }
         switch (standbyAction) {
@@ -342,11 +356,6 @@
         super.disableDevice(initiatedByCec, callback);
 
         assertRunOnServiceThread();
-        if (!initiatedByCec && mIsActiveSource && mService.isControlEnabled()) {
-            mService.sendCecCommand(HdmiCecMessageBuilder.buildInactiveSource(
-                    mAddress, mService.getPhysicalAddress()));
-        }
-        setIsActiveSource(false);
         checkIfPendingActionsCleared();
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 440676a..4d5dc6a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -56,6 +56,7 @@
 import android.media.tv.TvInputManager.TvInputCallback;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
@@ -380,6 +381,9 @@
                 case Constants.MESSAGE_TEXT_VIEW_ON:
                     bufferImageOrTextViewOn(message);
                     return true;
+                case Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST:
+                    bufferSystemAudioModeRequest(message);
+                    return true;
                     // Add here if new message that needs to buffer
                 default:
                     // Do not need to buffer messages other than above
@@ -412,6 +416,12 @@
             }
         }
 
+        private void bufferSystemAudioModeRequest(HdmiCecMessage message) {
+            if (!replaceMessageIfBuffered(message, Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST)) {
+                mBuffer.add(message);
+            }
+        }
+
         // Returns true if the message is replaced
         private boolean replaceMessageIfBuffered(HdmiCecMessage message, int opcode) {
             for (int i = 0; i < mBuffer.size(); i++) {
@@ -1163,6 +1173,29 @@
         return mCecController.getLocalDeviceList();
     }
 
+    /**
+     * Check if a logical address is conflict with the current device's. Reallocate the logical
+     * address of the current device if there is conflict.
+     *
+     * Android HDMI CEC 1.4 is handling logical address allocation in the framework side. This could
+     * introduce delay between the logical address allocation and notifying the driver that the
+     * address is occupied. Adding this check to avoid such case.
+     *
+     * @param logicalAddress logical address of the remote device that might have the same logical
+     * address as the current device.
+     */
+    protected void checkLogicalAddressConflictAndReallocate(int logicalAddress) {
+        for (HdmiCecLocalDevice device : getAllLocalDevices()) {
+            if (device.getDeviceInfo().getLogicalAddress() == logicalAddress) {
+                HdmiLogger.debug("allocate logical address for " + device.getDeviceInfo());
+                ArrayList<HdmiCecLocalDevice> localDevices = new ArrayList<>();
+                localDevices.add(device);
+                allocateLogicalAddress(localDevices, HdmiControlService.INITIATED_BY_HOTPLUG);
+                return;
+            }
+        }
+    }
+
     Object getServiceLock() {
         return mLock;
     }
@@ -1452,25 +1485,34 @@
                         return playback().getDeviceInfo();
                     }
                     // Otherwise get the active source and look for it from the device list
-                    ActiveSource activeSource = mActiveSource;
-                    // If the active source is not set yet, return null
-                    if (!activeSource.isValid()) {
+                    ActiveSource activeSource = getLocalActiveSource();
+                    // If the physical address is not set yet, return null
+                    if (activeSource.physicalAddress == Constants.INVALID_PHYSICAL_ADDRESS) {
                         return null;
                     }
                     if (audioSystem() != null) {
                         HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem();
                         for (HdmiDeviceInfo info : audioSystem.getSafeCecDevicesLocked()) {
-                            if (info.getLogicalAddress() == activeSource.logicalAddress) {
+                            if (info.getPhysicalAddress() == activeSource.physicalAddress) {
                                 return info;
                             }
                         }
                     }
                     // If the device info is not in the list yet, return a device info with minimum
                     // information from mActiveSource.
-                    return new HdmiDeviceInfo(activeSource.logicalAddress,
-                        activeSource.physicalAddress, pathToPortId(activeSource.physicalAddress),
-                        HdmiUtils.getTypeFromAddress(activeSource.logicalAddress), 0,
-                        HdmiUtils.getDefaultDeviceName(activeSource.logicalAddress));
+                    // If the Active Source has unregistered logical address, return with an
+                    // HdmiDeviceInfo built from physical address information only.
+                    return HdmiUtils.isValidAddress(activeSource.logicalAddress)
+                        ?
+                        new HdmiDeviceInfo(activeSource.logicalAddress,
+                            activeSource.physicalAddress,
+                            pathToPortId(activeSource.physicalAddress),
+                            HdmiUtils.getTypeFromAddress(activeSource.logicalAddress), 0,
+                            HdmiUtils.getDefaultDeviceName(activeSource.logicalAddress))
+                        :
+                            new HdmiDeviceInfo(activeSource.physicalAddress,
+                                pathToPortId(activeSource.physicalAddress));
+
                 }
                 return null;
             }
@@ -1498,6 +1540,11 @@
                         Slog.e(TAG, "Callback cannot be null");
                         return;
                     }
+                    if (isPowerStandby()) {
+                        Slog.e(TAG, "Device is in standby. Not handling deviceSelect");
+                        invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
+                        return;
+                    }
                     HdmiCecLocalDeviceTv tv = tv();
                     if (tv == null) {
                         if (!mAddressAllocated) {
@@ -1540,6 +1587,11 @@
                         Slog.e(TAG, "Callback cannot be null");
                         return;
                     }
+                    if (isPowerStandby()) {
+                        Slog.e(TAG, "Device is in standby. Not handling portSelect");
+                        invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
+                        return;
+                    }
                     HdmiCecLocalDeviceTv tv = tv();
                     if (tv != null) {
                         tv.doManualPortSwitching(portId, callback);
@@ -1611,6 +1663,8 @@
         @Override
         public void oneTouchPlay(final IHdmiControlCallback callback) {
             enforceAccessPermission();
+            int pid = Binder.getCallingPid();
+            Slog.d(TAG, "Proccess pid: " + pid + " is calling oneTouchPlay.");
             runOnServiceThread(new Runnable() {
                 @Override
                 public void run() {
@@ -2789,7 +2843,7 @@
         setLastInputForMhl(Constants.INVALID_PORT_ID);
     }
 
-    ActiveSource getActiveSource() {
+    ActiveSource getLocalActiveSource() {
         synchronized (mLock) {
             return mActiveSource;
         }
@@ -2800,6 +2854,21 @@
             mActiveSource.logicalAddress = logicalAddress;
             mActiveSource.physicalAddress = physicalAddress;
         }
+        // If the current device is a source device, check if the current Active Source matches
+        // the local device info. Set mIsActiveSource of the local device accordingly.
+        for (HdmiCecLocalDevice device : getAllLocalDevices()) {
+            // mIsActiveSource only exists in source device, ignore this setting if the current
+            // device is not an HdmiCecLocalDeviceSource.
+            if (!(device instanceof HdmiCecLocalDeviceSource)) {
+                continue;
+            }
+            if (logicalAddress == device.getDeviceInfo().getLogicalAddress()
+                && physicalAddress == getPhysicalAddress()) {
+                ((HdmiCecLocalDeviceSource) device).setIsActiveSource(true);
+            } else {
+                ((HdmiCecLocalDeviceSource) device).setIsActiveSource(false);
+            }
+        }
     }
 
     // This method should only be called when the device can be the active source
diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java
index e44f1d1..cd65db6 100644
--- a/services/core/java/com/android/server/hdmi/HdmiUtils.java
+++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java
@@ -24,8 +24,10 @@
 
 import com.android.internal.util.HexDump;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.hdmi.Constants.AudioCodec;
 
+import com.android.server.hdmi.Constants.AbortReason;
+import com.android.server.hdmi.Constants.AudioCodec;
+import com.android.server.hdmi.Constants.FeatureOpcode;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -457,6 +459,28 @@
         return port;
     }
 
+    /**
+     * Parse the Feature Abort CEC message parameter into a [Feature Opcode].
+     *
+     * @param cmd the CEC message to parse
+     * @return the original opcode of the cec message that got aborted.
+     */
+    @FeatureOpcode
+    static int getAbortFeatureOpcode(HdmiCecMessage cmd) {
+        return cmd.getParams()[0] & 0xFF;
+    }
+
+    /**
+     * Parse the Feature Abort CEC message parameter into an [Abort Reason].
+     *
+     * @param cmd the CEC message to parse
+     * @return The reason to abort the feature.
+     */
+    @AbortReason
+    static int getAbortReason(HdmiCecMessage cmd) {
+        return cmd.getParams()[1];
+    }
+
     public static class ShortAudioDescriptorXmlParser {
         // We don't use namespaces
         private static final String NS = null;
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index 354d8d1..c8fc5fc 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -87,14 +87,13 @@
         HdmiCecLocalDeviceSource source = source();
         source.mService.setAndBroadcastActiveSourceFromOneDeviceType(
                 mTargetAddress, getSourcePath());
-        // Set local active port to HOME when One Touch Play.
-        // Active Port and Current Input are handled by the switch functionality device.
+        // When OneTouchPlay is called, client side should be responsible to send out the intent
+        // of which internal source, for example YouTube, it would like to switch to.
+        // Here we only update the active port and the active source records in the local
+        // device as well as claiming Active Source.
         if (source.mService.audioSystem() != null) {
             source = source.mService.audioSystem();
         }
-        if (source.getLocalActivePort() != Constants.CEC_SWITCH_HOME) {
-            source.switchInputOnReceivingNewActivePath(getSourcePath());
-        }
         source.setRoutingPort(Constants.CEC_SWITCH_HOME);
         source.setLocalActivePort(Constants.CEC_SWITCH_HOME);
     }
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
index b6ebcd7c..0907e5d 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioInitiationActionFromAvr.java
@@ -46,6 +46,7 @@
             addTimer(mState, HdmiConfig.TIMEOUT_MS);
             sendRequestActiveSource();
         } else {
+            mState = STATE_WAITING_FOR_TV_SUPPORT;
             queryTvSystemAudioModeSupport();
         }
         return true;
diff --git a/services/core/java/com/android/server/incident/PendingReports.java b/services/core/java/com/android/server/incident/PendingReports.java
index c45a904..9fcbab7 100644
--- a/services/core/java/com/android/server/incident/PendingReports.java
+++ b/services/core/java/com/android/server/incident/PendingReports.java
@@ -17,6 +17,7 @@
 package com.android.server.incident;
 
 import android.app.AppOpsManager;
+import android.app.BroadcastOptions;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -358,10 +359,12 @@
     private void sendBroadcast(ComponentName receiver, int primaryUser) {
         final Intent intent = new Intent(Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED);
         intent.setComponent(receiver);
+        final BroadcastOptions options = BroadcastOptions.makeBasic();
+        options.setBackgroundActivityStartsAllowed(true);
 
         // Send it to the primary user.
         mContext.sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(primaryUser),
-                android.Manifest.permission.APPROVE_INCIDENT_REPORTS);
+                android.Manifest.permission.APPROVE_INCIDENT_REPORTS, options.toBundle());
     }
 
     /**
diff --git a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
index c52921e..16cf7ee 100644
--- a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
@@ -75,6 +75,14 @@
         mMaster = master;
         mLock = lock;
         mUserId = userId;
+        updateIsSetupComplete(userId);
+    }
+
+    /** Updates whether setup is complete for current user */
+    private void updateIsSetupComplete(@UserIdInt int userId) {
+        final String setupComplete = Settings.Secure.getStringForUser(
+                getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, userId);
+        mSetupComplete = "1".equals(setupComplete);
     }
 
     /**
@@ -143,9 +151,7 @@
                     + ", disabled=" + disabled + ", mDisabled=" + mDisabled);
         }
 
-        final String setupComplete = Settings.Secure.getStringForUser(
-                getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
-        mSetupComplete = "1".equals(setupComplete);
+        updateIsSetupComplete(mUserId);
         mDisabled = disabled;
 
         updateServiceInfoLocked();
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 6330270..09e9375 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -17,7 +17,6 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
-import static android.view.inputmethod.InputMethodSystemProperty.PER_PROFILE_IME_ENABLED;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
@@ -239,13 +238,6 @@
             | Context.BIND_SHOWING_UI
             | Context.BIND_SCHEDULE_LIKE_TOP_APP;
 
-    @Retention(SOURCE)
-    @IntDef({HardKeyboardBehavior.WIRELESS_AFFORDANCE, HardKeyboardBehavior.WIRED_AFFORDANCE})
-    private @interface  HardKeyboardBehavior {
-        int WIRELESS_AFFORDANCE = 0;
-        int WIRED_AFFORDANCE = 1;
-    }
-
     /**
      * A protected broadcast intent action for internal use for {@link PendingIntent} in
      * the notification.
@@ -689,8 +681,6 @@
     private final MyPackageMonitor mMyPackageMonitor = new MyPackageMonitor();
     private final IPackageManager mIPackageManager;
     private final String mSlotIme;
-    @HardKeyboardBehavior
-    private final int mHardKeyboardBehavior;
 
     /**
      * Internal state snapshot when {@link #MSG_START_INPUT} message is about to be posted to the
@@ -1045,9 +1035,7 @@
                 // sender userId can be a real user ID or USER_ALL.
                 final int senderUserId = pendingResult.getSendingUserId();
                 if (senderUserId != UserHandle.USER_ALL) {
-                    final int resolvedUserId = PER_PROFILE_IME_ENABLED
-                            ? senderUserId : mUserManagerInternal.getProfileParentId(senderUserId);
-                    if (resolvedUserId != mSettings.getCurrentUserId()) {
+                    if (senderUserId != mSettings.getCurrentUserId()) {
                         // A background user is trying to hide the dialog. Ignore.
                         return;
                     }
@@ -1465,8 +1453,6 @@
         mHasFeature = context.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_INPUT_METHODS);
         mSlotIme = mContext.getString(com.android.internal.R.string.status_bar_ime);
-        mHardKeyboardBehavior = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_externalHardKeyboardBehavior);
         mIsLowRam = ActivityManager.isLowRamDeviceStatic();
 
         Bundle extras = new Bundle();
@@ -1673,9 +1659,6 @@
         if (userId == mSettings.getCurrentUserId()) {
             return true;
         }
-        if (!PER_PROFILE_IME_ENABLED && mSettings.isCurrentProfile(userId)) {
-            return true;
-        }
 
         // Caveat: A process which has INTERACT_ACROSS_USERS_FULL gets results for the
         // foreground user, not for the user of that process. Accordingly InputMethodManagerService
@@ -2435,13 +2418,11 @@
             return false;
         }
         if (mWindowManagerInternal.isHardKeyboardAvailable()) {
-            if (mHardKeyboardBehavior == HardKeyboardBehavior.WIRELESS_AFFORDANCE) {
-                // When physical keyboard is attached, we show the ime switcher (or notification if
-                // NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently
-                // exists in the IME switcher dialog.  Might be OK to remove this condition once
-                // SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live.
-                return true;
-            }
+            // When physical keyboard is attached, we show the ime switcher (or notification if
+            // NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently
+            // exists in the IME switcher dialog.  Might be OK to remove this condition once
+            // SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live.
+            return true;
         } else if ((visibility & InputMethodService.IME_VISIBLE) == 0) {
             return false;
         }
@@ -3018,7 +2999,7 @@
             return InputBindResult.INVALID_USER;
         }
 
-        if (PER_PROFILE_IME_ENABLED && userId != mSettings.getCurrentUserId()) {
+        if (userId != mSettings.getCurrentUserId()) {
             switchUserLocked(userId);
         }
         // Master feature flag that overrides other conditions and forces IME preRendering.
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
index b5e19ae..77e2fbd 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java
@@ -35,13 +35,11 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.IntArray;
 import android.util.Pair;
 import android.util.Printer;
 import android.util.Slog;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype;
-import android.view.inputmethod.InputMethodSystemProperty;
 import android.view.textservice.SpellCheckerInfo;
 
 import com.android.internal.annotations.GuardedBy;
@@ -1303,9 +1301,6 @@
      * Converts a user ID, which can be a pseudo user ID such as {@link UserHandle#USER_ALL} to a
      * list of real user IDs.
      *
-     * <p>This method also converts profile user ID to profile parent user ID unless
-     * {@link InputMethodSystemProperty#PER_PROFILE_IME_ENABLED} is {@code true}.</p>
-     *
      * @param userIdToBeResolved A user ID. Two pseudo user ID {@link UserHandle#USER_CURRENT} and
      *                           {@link UserHandle#USER_ALL} are also supported
      * @param currentUserId A real user ID, which will be used when {@link UserHandle#USER_CURRENT}
@@ -1320,17 +1315,7 @@
                 LocalServices.getService(UserManagerInternal.class);
 
         if (userIdToBeResolved == UserHandle.USER_ALL) {
-            if (InputMethodSystemProperty.PER_PROFILE_IME_ENABLED) {
-                return userManagerInternal.getUserIds();
-            }
-            final IntArray result = new IntArray();
-            for (int userId : userManagerInternal.getUserIds()) {
-                final int parentUserId = userManagerInternal.getProfileParentId(userId);
-                if (result.indexOf(parentUserId) < 0) {
-                    result.add(parentUserId);
-                }
-            }
-            return result.toArray();
+            return userManagerInternal.getUserIds();
         }
 
         final int sourceUserId;
@@ -1353,8 +1338,6 @@
             }
             return new int[]{};
         }
-        final int resolvedUserId = InputMethodSystemProperty.PER_PROFILE_IME_ENABLED
-                ? sourceUserId : userManagerInternal.getProfileParentId(sourceUserId);
-        return new int[]{resolvedUserId};
+        return new int[]{sourceUserId};
     }
 }
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index ea1c49d..e44e902 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -150,7 +150,7 @@
     @VisibleForTesting
     public static Clock sSystemClock = Clock.systemUTC();
     @VisibleForTesting
-    public static Clock sUptimeMillisClock = SystemClock.uptimeMillisClock();
+    public static Clock sUptimeMillisClock = SystemClock.uptimeClock();
     @VisibleForTesting
     public static Clock sElapsedRealtimeClock = SystemClock.elapsedRealtimeClock();
 
@@ -187,6 +187,9 @@
     private final StorageController mStorageController;
     /** Need directly for sending uid state changes */
     private final DeviceIdleJobsController mDeviceIdleJobsController;
+    /** Needed to get remaining quota time. */
+    private final QuotaController mQuotaController;
+
     /** Need directly for receiving thermal events */
     private IThermalService mThermalService;
     /** Thermal constraint. */
@@ -443,6 +446,10 @@
         private static final String KEY_MIN_CONNECTIVITY_COUNT = "min_connectivity_count";
         private static final String KEY_MIN_CONTENT_COUNT = "min_content_count";
         private static final String KEY_MIN_READY_JOBS_COUNT = "min_ready_jobs_count";
+        private static final String KEY_MIN_READY_NON_ACTIVE_JOBS_COUNT =
+                "min_ready_non_active_jobs_count";
+        private static final String KEY_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS =
+                "max_non_active_job_batch_delay_ms";
         private static final String KEY_HEAVY_USE_FACTOR = "heavy_use_factor";
         private static final String KEY_MODERATE_USE_FACTOR = "moderate_use_factor";
 
@@ -473,6 +480,8 @@
         private static final int DEFAULT_MIN_CONNECTIVITY_COUNT = 1;
         private static final int DEFAULT_MIN_CONTENT_COUNT = 1;
         private static final int DEFAULT_MIN_READY_JOBS_COUNT = 1;
+        private static final int DEFAULT_MIN_READY_NON_ACTIVE_JOBS_COUNT = 5;
+        private static final long DEFAULT_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS = 31 * MINUTE_IN_MILLIS;
         private static final float DEFAULT_HEAVY_USE_FACTOR = .9f;
         private static final float DEFAULT_MODERATE_USE_FACTOR = .5f;
         private static final int DEFAULT_MAX_STANDARD_RESCHEDULE_COUNT = Integer.MAX_VALUE;
@@ -524,6 +533,18 @@
          * a much better mechanism.
          */
         int MIN_READY_JOBS_COUNT = DEFAULT_MIN_READY_JOBS_COUNT;
+
+        /**
+         * Minimum # of non-ACTIVE jobs for which the JMS will be happy running some work early.
+         */
+        int MIN_READY_NON_ACTIVE_JOBS_COUNT = DEFAULT_MIN_READY_NON_ACTIVE_JOBS_COUNT;
+
+        /**
+         * Don't batch a non-ACTIVE job if it's been delayed due to force batching attempts for
+         * at least this amount of time.
+         */
+        long MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS = DEFAULT_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS;
+
         /**
          * This is the job execution factor that is considered to be heavy use of the system.
          */
@@ -657,6 +678,12 @@
                     DEFAULT_MIN_CONTENT_COUNT);
             MIN_READY_JOBS_COUNT = mParser.getInt(KEY_MIN_READY_JOBS_COUNT,
                     DEFAULT_MIN_READY_JOBS_COUNT);
+            MIN_READY_NON_ACTIVE_JOBS_COUNT = mParser.getInt(
+                    KEY_MIN_READY_NON_ACTIVE_JOBS_COUNT,
+                    DEFAULT_MIN_READY_NON_ACTIVE_JOBS_COUNT);
+            MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS = mParser.getLong(
+                    KEY_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS,
+                    DEFAULT_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS);
             HEAVY_USE_FACTOR = mParser.getFloat(KEY_HEAVY_USE_FACTOR,
                     DEFAULT_HEAVY_USE_FACTOR);
             MODERATE_USE_FACTOR = mParser.getFloat(KEY_MODERATE_USE_FACTOR,
@@ -707,6 +734,10 @@
             pw.printPair(KEY_MIN_CONNECTIVITY_COUNT, MIN_CONNECTIVITY_COUNT).println();
             pw.printPair(KEY_MIN_CONTENT_COUNT, MIN_CONTENT_COUNT).println();
             pw.printPair(KEY_MIN_READY_JOBS_COUNT, MIN_READY_JOBS_COUNT).println();
+            pw.printPair(KEY_MIN_READY_NON_ACTIVE_JOBS_COUNT,
+                    MIN_READY_NON_ACTIVE_JOBS_COUNT).println();
+            pw.printPair(KEY_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS,
+                    MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS).println();
             pw.printPair(KEY_HEAVY_USE_FACTOR, HEAVY_USE_FACTOR).println();
             pw.printPair(KEY_MODERATE_USE_FACTOR, MODERATE_USE_FACTOR).println();
 
@@ -749,6 +780,10 @@
             proto.write(ConstantsProto.MIN_CONNECTIVITY_COUNT, MIN_CONNECTIVITY_COUNT);
             proto.write(ConstantsProto.MIN_CONTENT_COUNT, MIN_CONTENT_COUNT);
             proto.write(ConstantsProto.MIN_READY_JOBS_COUNT, MIN_READY_JOBS_COUNT);
+            proto.write(ConstantsProto.MIN_READY_NON_ACTIVE_JOBS_COUNT,
+                    MIN_READY_NON_ACTIVE_JOBS_COUNT);
+            proto.write(ConstantsProto.MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS,
+                    MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS);
             proto.write(ConstantsProto.HEAVY_USE_FACTOR, HEAVY_USE_FACTOR);
             proto.write(ConstantsProto.MODERATE_USE_FACTOR, MODERATE_USE_FACTOR);
 
@@ -1338,7 +1373,8 @@
         mControllers.add(new ContentObserverController(this));
         mDeviceIdleJobsController = new DeviceIdleJobsController(this);
         mControllers.add(mDeviceIdleJobsController);
-        mControllers.add(new QuotaController(this));
+        mQuotaController = new QuotaController(this);
+        mControllers.add(mQuotaController);
 
         // If the job store determined that it can't yet reschedule persisted jobs,
         // we need to start watching the clock.
@@ -1494,16 +1530,16 @@
     }
 
     /**
-     * Called when we want to remove a JobStatus object that we've finished executing. Returns the
-     * object removed.
+     * Called when we want to remove a JobStatus object that we've finished executing.
+     * @return true if the job was removed.
      */
     private boolean stopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
-            boolean writeBack) {
+            boolean removeFromPersisted) {
         // Deal with any remaining work items in the old job.
         jobStatus.stopTrackingJobLocked(ActivityManager.getService(), incomingJob);
 
         // Remove from store as well as controllers.
-        final boolean removed = mJobs.remove(jobStatus, writeBack);
+        final boolean removed = mJobs.remove(jobStatus, removeFromPersisted);
         if (removed && mReadyToRock) {
             for (int i=0; i<mControllers.size(); i++) {
                 StateController controller = mControllers.get(i);
@@ -1635,6 +1671,9 @@
      */
     private static final long PERIODIC_JOB_WINDOW_BUFFER = 30 * MINUTE_IN_MILLIS;
 
+    /** The maximum period a periodic job can have. Anything higher will be clamped down to this. */
+    public static final long MAX_ALLOWED_PERIOD_MS = 365 * 24 * 60 * 60 * 1000L;
+
     /**
      * Called after a periodic has executed so we can reschedule it. We take the last execution
      * time of the job to be the time of completion (i.e. the time at which this function is
@@ -1652,11 +1691,21 @@
     JobStatus getRescheduleJobForPeriodic(JobStatus periodicToReschedule) {
         final long elapsedNow = sElapsedRealtimeClock.millis();
         final long newLatestRuntimeElapsed;
-        final long period = periodicToReschedule.getJob().getIntervalMillis();
-        final long latestRunTimeElapsed = periodicToReschedule.getOriginalLatestRunTimeElapsed();
-        final long flex = periodicToReschedule.getJob().getFlexMillis();
+        // Make sure period is in the interval [min_possible_period, max_possible_period].
+        final long period = Math.max(JobInfo.getMinPeriodMillis(),
+                Math.min(MAX_ALLOWED_PERIOD_MS, periodicToReschedule.getJob().getIntervalMillis()));
+        // Make sure flex is in the interval [min_possible_flex, period].
+        final long flex = Math.max(JobInfo.getMinFlexMillis(),
+                Math.min(period, periodicToReschedule.getJob().getFlexMillis()));
         long rescheduleBuffer = 0;
 
+        long olrte = periodicToReschedule.getOriginalLatestRunTimeElapsed();
+        if (olrte < 0 || olrte == JobStatus.NO_LATEST_RUNTIME) {
+            Slog.wtf(TAG, "Invalid periodic job original latest run time: " + olrte);
+            olrte = elapsedNow;
+        }
+        final long latestRunTimeElapsed = olrte;
+
         final long diffMs = Math.abs(elapsedNow - latestRunTimeElapsed);
         if (elapsedNow > latestRunTimeElapsed) {
             // The job ran past its expected run window. Have it count towards the current window
@@ -1664,7 +1713,7 @@
             if (DEBUG) {
                 Slog.i(TAG, "Periodic job ran after its intended window.");
             }
-            int numSkippedWindows = (int) (diffMs / period) + 1; // +1 to include original window
+            long numSkippedWindows = (diffMs / period) + 1; // +1 to include original window
             if (period != flex && diffMs > Math.min(PERIODIC_JOB_WINDOW_BUFFER,
                     (period - flex) / 2)) {
                 if (DEBUG) {
@@ -1684,6 +1733,16 @@
             }
         }
 
+        if (newLatestRuntimeElapsed < elapsedNow) {
+            Slog.wtf(TAG, "Rescheduling calculated latest runtime in the past: "
+                    + newLatestRuntimeElapsed);
+            return new JobStatus(periodicToReschedule, getCurrentHeartbeat(),
+                    elapsedNow + period - flex, elapsedNow + period,
+                    0 /* backoffAttempt */,
+                    sSystemClock.millis() /* lastSuccessfulRunTime */,
+                    periodicToReschedule.getLastFailedRunTime());
+        }
+
         final long newEarliestRunTimeElapsed = newLatestRuntimeElapsed
                 - Math.min(flex, period - rescheduleBuffer);
 
@@ -1962,7 +2021,7 @@
     }
 
     final class ReadyJobQueueFunctor implements Consumer<JobStatus> {
-        ArrayList<JobStatus> newReadyJobs;
+        final ArrayList<JobStatus> newReadyJobs = new ArrayList<>();
 
         @Override
         public void accept(JobStatus job) {
@@ -1970,9 +2029,6 @@
                 if (DEBUG) {
                     Slog.d(TAG, "    queued " + job.toShortString());
                 }
-                if (newReadyJobs == null) {
-                    newReadyJobs = new ArrayList<JobStatus>();
-                }
                 newReadyJobs.add(job);
             } else {
                 evaluateControllerStatesLocked(job);
@@ -1980,14 +2036,13 @@
         }
 
         public void postProcess() {
-            if (newReadyJobs != null) {
-                noteJobsPending(newReadyJobs);
-                mPendingJobs.addAll(newReadyJobs);
-                if (mPendingJobs.size() > 1) {
-                    mPendingJobs.sort(mEnqueueTimeComparator);
-                }
+            noteJobsPending(newReadyJobs);
+            mPendingJobs.addAll(newReadyJobs);
+            if (mPendingJobs.size() > 1) {
+                mPendingJobs.sort(mEnqueueTimeComparator);
             }
-            newReadyJobs = null;
+
+            newReadyJobs.clear();
         }
     }
     private final ReadyJobQueueFunctor mReadyQueueFunctor = new ReadyJobQueueFunctor();
@@ -2004,7 +2059,9 @@
         int backoffCount;
         int connectivityCount;
         int contentCount;
-        List<JobStatus> runnableJobs;
+        int forceBatchedCount;
+        int unbatchedCount;
+        final List<JobStatus> runnableJobs = new ArrayList<>();
 
         public MaybeReadyJobQueueFunctor() {
             reset();
@@ -2024,29 +2081,39 @@
                     }
                 } catch (RemoteException e) {
                 }
-                if (job.getNumFailures() > 0) {
-                    backoffCount++;
-                }
-                if (job.hasIdleConstraint()) {
-                    idleCount++;
-                }
-                if (job.hasConnectivityConstraint()) {
-                    connectivityCount++;
-                }
-                if (job.hasChargingConstraint()) {
-                    chargingCount++;
-                }
-                if (job.hasBatteryNotLowConstraint()) {
-                    batteryNotLowCount++;
-                }
-                if (job.hasStorageNotLowConstraint()) {
-                    storageNotLowCount++;
-                }
-                if (job.hasContentTriggerConstraint()) {
-                    contentCount++;
-                }
-                if (runnableJobs == null) {
-                    runnableJobs = new ArrayList<>();
+                if (mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT > 1
+                        && job.getStandbyBucket() != ACTIVE_INDEX
+                        && (job.getFirstForceBatchedTimeElapsed() == 0
+                        || sElapsedRealtimeClock.millis() - job.getFirstForceBatchedTimeElapsed()
+                                < mConstants.MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS)) {
+                    // Force batching non-ACTIVE jobs. Don't include them in the other counts.
+                    forceBatchedCount++;
+                    if (job.getFirstForceBatchedTimeElapsed() == 0) {
+                        job.setFirstForceBatchedTimeElapsed(sElapsedRealtimeClock.millis());
+                    }
+                } else {
+                    unbatchedCount++;
+                    if (job.getNumFailures() > 0) {
+                        backoffCount++;
+                    }
+                    if (job.hasIdleConstraint()) {
+                        idleCount++;
+                    }
+                    if (job.hasConnectivityConstraint()) {
+                        connectivityCount++;
+                    }
+                    if (job.hasChargingConstraint()) {
+                        chargingCount++;
+                    }
+                    if (job.hasBatteryNotLowConstraint()) {
+                        batteryNotLowCount++;
+                    }
+                    if (job.hasStorageNotLowConstraint()) {
+                        storageNotLowCount++;
+                    }
+                    if (job.hasContentTriggerConstraint()) {
+                        contentCount++;
+                    }
                 }
                 runnableJobs.add(job);
             } else {
@@ -2062,8 +2129,9 @@
                     batteryNotLowCount >= mConstants.MIN_BATTERY_NOT_LOW_COUNT ||
                     storageNotLowCount >= mConstants.MIN_STORAGE_NOT_LOW_COUNT ||
                     contentCount >= mConstants.MIN_CONTENT_COUNT ||
-                    (runnableJobs != null
-                            && runnableJobs.size() >= mConstants.MIN_READY_JOBS_COUNT)) {
+                    forceBatchedCount >= mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT ||
+                    (unbatchedCount > 0 && (unbatchedCount + forceBatchedCount)
+                            >= mConstants.MIN_READY_JOBS_COUNT)) {
                 if (DEBUG) {
                     Slog.d(TAG, "maybeQueueReadyJobsForExecutionLocked: Running jobs.");
                 }
@@ -2082,7 +2150,8 @@
             reset();
         }
 
-        private void reset() {
+        @VisibleForTesting
+        void reset() {
             chargingCount = 0;
             idleCount =  0;
             backoffCount = 0;
@@ -2090,7 +2159,9 @@
             batteryNotLowCount = 0;
             storageNotLowCount = 0;
             contentCount = 0;
-            runnableJobs = null;
+            forceBatchedCount = 0;
+            unbatchedCount = 0;
+            runnableJobs.clear();
         }
     }
     private final MaybeReadyJobQueueFunctor mMaybeQueueFunctor = new MaybeReadyJobQueueFunctor();
@@ -2199,7 +2270,8 @@
      *      - The job's standby bucket has come due to be runnable.
      *      - The component is enabled and runnable.
      */
-    private boolean isReadyToBeExecutedLocked(JobStatus job) {
+    @VisibleForTesting
+    boolean isReadyToBeExecutedLocked(JobStatus job) {
         final boolean jobReady = job.isReady();
 
         if (DEBUG) {
@@ -2280,8 +2352,6 @@
                     if (bucket >= mConstants.STANDBY_BEATS.length
                             || (mHeartbeat > appLastRan
                             && mHeartbeat < appLastRan + mConstants.STANDBY_BEATS[bucket])) {
-                        // TODO: log/trace that we're deferring the job due to bucketing if we
-                        // hit this
                         if (job.getWhenStandbyDeferred() == 0) {
                             if (DEBUG_STANDBY) {
                                 Slog.v(TAG, "Bucket deferral: " + mHeartbeat + " < "
@@ -2333,7 +2403,8 @@
         return !appIsBad;
     }
 
-    private void evaluateControllerStatesLocked(final JobStatus job) {
+    @VisibleForTesting
+    void evaluateControllerStatesLocked(final JobStatus job) {
         for (int c = mControllers.size() - 1; c >= 0; --c) {
             final StateController sc = mControllers.get(c);
             sc.evaluateStateLocked(job);
@@ -2376,6 +2447,17 @@
         return isComponentUsable(job);
     }
 
+    /** Returns the maximum amount of time this job could run for. */
+    public long getMaxJobExecutionTimeMs(JobStatus job) {
+        synchronized (mLock) {
+            if (mConstants.USE_HEARTBEATS) {
+                return JobServiceContext.EXECUTING_TIMESLICE_MILLIS;
+            }
+            return Math.min(mQuotaController.getMaxJobExecutionTimeMsLocked(job),
+                    JobServiceContext.EXECUTING_TIMESLICE_MILLIS);
+        }
+    }
+
     /**
      * Reconcile jobs in the pending queue against available execution contexts.
      * A controller can force a job into the pending queue even if it's already running, but
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 7689bd2..7da128f 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -247,10 +247,20 @@
             mVerb = VERB_BINDING;
             scheduleOpTimeOutLocked();
             final Intent intent = new Intent().setComponent(job.getServiceComponent());
-            boolean binding = mContext.bindServiceAsUser(intent, this,
-                    Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
-                    | Context.BIND_NOT_VISIBLE | Context.BIND_ADJUST_BELOW_PERCEPTIBLE,
-                    new UserHandle(job.getUserId()));
+            boolean binding = false;
+            try {
+                binding = mContext.bindServiceAsUser(intent, this,
+                        Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
+                        | Context.BIND_NOT_PERCEPTIBLE,
+                        new UserHandle(job.getUserId()));
+            } catch (SecurityException e) {
+                // Some permission policy, for example INTERACT_ACROSS_USERS and
+                // android:singleUser, can result in a SecurityException being thrown from
+                // bindServiceAsUser().  If this happens, catch it and fail gracefully.
+                Slog.w(TAG, "Job service " + job.getServiceComponent().getShortClassName()
+                        + " cannot be executed: " + e.getMessage());
+                binding = false;
+            }
             if (!binding) {
                 if (DEBUG) {
                     Slog.d(TAG, job.getServiceComponent().getShortClassName() + " unavailable.");
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 4ef37a2..d69faf3 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -235,10 +235,11 @@
 
     /**
      * Remove the provided job. Will also delete the job if it was persisted.
-     * @param writeBack If true, the job will be deleted (if it was persisted) immediately.
+     * @param removeFromPersisted If true, the job will be removed from the persisted job list
+     *                            immediately (if it was persisted).
      * @return Whether or not the job existed to be removed.
      */
-    public boolean remove(JobStatus jobStatus, boolean writeBack) {
+    public boolean remove(JobStatus jobStatus, boolean removeFromPersisted) {
         boolean removed = mJobSet.remove(jobStatus);
         if (!removed) {
             if (DEBUG) {
@@ -246,7 +247,7 @@
             }
             return false;
         }
-        if (writeBack && jobStatus.isPersisted()) {
+        if (removeFromPersisted && jobStatus.isPersisted()) {
             maybeWriteStatusToDiskAsync();
         }
         return removed;
@@ -344,6 +345,19 @@
         new ReadJobMapFromDiskRunnable(jobSet, rtcGood).run();
     }
 
+    /** Write persisted JobStore state to disk synchronously. Should only be used for testing. */
+    @VisibleForTesting
+    public void writeStatusToDiskForTesting() {
+        synchronized (mWriteScheduleLock) {
+            if (mWriteScheduled) {
+                throw new IllegalStateException("An asynchronous write is already scheduled.");
+            }
+
+            mWriteScheduled = mWriteInProgress = true;
+            mWriteRunnable.run();
+        }
+    }
+
     /**
      * Wait for any pending write to the persistent store to clear
      * @param maxWaitMillis Maximum time from present to wait
@@ -1049,7 +1063,9 @@
         }
     }
 
-    static final class JobSet {
+    /** Set of all tracked jobs. */
+    @VisibleForTesting
+    public static final class JobSet {
         @VisibleForTesting // Key is the getUid() originator of the jobs in each sheaf
         final SparseArray<ArraySet<JobStatus>> mJobs;
 
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index c820841..f8cf6ae 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -29,13 +29,13 @@
 import android.net.NetworkInfo;
 import android.net.NetworkPolicyManager;
 import android.net.NetworkRequest;
-import android.net.TrafficStats;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.UserHandle;
 import android.text.format.DateUtils;
 import android.util.ArraySet;
+import android.util.DataUnit;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -88,8 +88,11 @@
     @GuardedBy("mLock")
     private final ArraySet<Network> mAvailableNetworks = new ArraySet<>();
 
+    private boolean mUseQuotaLimit;
+
     private static final int MSG_DATA_SAVER_TOGGLED = 0;
     private static final int MSG_UID_RULES_CHANGES = 1;
+    private static final int MSG_REEVALUATE_JOBS = 2;
 
     private final Handler mHandler;
 
@@ -107,6 +110,8 @@
         mConnManager.registerNetworkCallback(request, mNetworkCallback);
 
         mNetPolicyManager.registerListener(mNetPolicyListener);
+
+        mUseQuotaLimit = !mConstants.USE_HEARTBEATS;
     }
 
     @GuardedBy("mLock")
@@ -149,6 +154,10 @@
             }
             mRequestedWhitelistJobs.clear();
         }
+        if (mUseQuotaLimit == mConstants.USE_HEARTBEATS) {
+            mUseQuotaLimit = !mConstants.USE_HEARTBEATS;
+            mHandler.obtainMessage(MSG_REEVALUATE_JOBS).sendToTarget();
+        }
     }
 
     /**
@@ -318,38 +327,51 @@
      * connection, it would take 10.4 minutes, and has no chance of succeeding
      * before the job times out, so we'd be insane to try running it.
      */
-    @SuppressWarnings("unused")
-    private static boolean isInsane(JobStatus jobStatus, Network network,
+    private boolean isInsane(JobStatus jobStatus, Network network,
             NetworkCapabilities capabilities, Constants constants) {
-        final long estimatedBytes = jobStatus.getEstimatedNetworkBytes();
-        if (estimatedBytes == JobInfo.NETWORK_BYTES_UNKNOWN) {
-            // We don't know how large the job is; cross our fingers!
-            return false;
+        final long maxJobExecutionTimeMs = mUseQuotaLimit
+                ? mService.getMaxJobExecutionTimeMs(jobStatus)
+                : JobServiceContext.EXECUTING_TIMESLICE_MILLIS;
+
+        final long downloadBytes = jobStatus.getEstimatedNetworkDownloadBytes();
+        if (downloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+            final long bandwidth = capabilities.getLinkDownstreamBandwidthKbps();
+            // If we don't know the bandwidth, all we can do is hope the job finishes in time.
+            if (bandwidth != LINK_BANDWIDTH_UNSPECIFIED) {
+                // Divide by 8 to convert bits to bytes.
+                final long estimatedMillis = ((downloadBytes * DateUtils.SECOND_IN_MILLIS)
+                        / (DataUnit.KIBIBYTES.toBytes(bandwidth) / 8));
+                if (estimatedMillis > maxJobExecutionTimeMs) {
+                    // If we'd never finish before the timeout, we'd be insane!
+                    Slog.w(TAG, "Estimated " + downloadBytes + " download bytes over " + bandwidth
+                            + " kbps network would take " + estimatedMillis + "ms and job has "
+                            + maxJobExecutionTimeMs + "ms to run; that's insane!");
+                    return true;
+                }
+            }
         }
 
-        // We don't ask developers to differentiate between upstream/downstream
-        // in their size estimates, so test against the slowest link direction.
-        final long slowest = NetworkCapabilities.minBandwidth(
-                capabilities.getLinkDownstreamBandwidthKbps(),
-                capabilities.getLinkUpstreamBandwidthKbps());
-        if (slowest == LINK_BANDWIDTH_UNSPECIFIED) {
-            // We don't know what the network is like; cross our fingers!
-            return false;
+        final long uploadBytes = jobStatus.getEstimatedNetworkUploadBytes();
+        if (uploadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+            final long bandwidth = capabilities.getLinkUpstreamBandwidthKbps();
+            // If we don't know the bandwidth, all we can do is hope the job finishes in time.
+            if (bandwidth != LINK_BANDWIDTH_UNSPECIFIED) {
+                // Divide by 8 to convert bits to bytes.
+                final long estimatedMillis = ((uploadBytes * DateUtils.SECOND_IN_MILLIS)
+                        / (DataUnit.KIBIBYTES.toBytes(bandwidth) / 8));
+                if (estimatedMillis > maxJobExecutionTimeMs) {
+                    // If we'd never finish before the timeout, we'd be insane!
+                    Slog.w(TAG, "Estimated " + uploadBytes + " upload bytes over " + bandwidth
+                            + " kbps network would take " + estimatedMillis + "ms and job has "
+                            + maxJobExecutionTimeMs + "ms to run; that's insane!");
+                    return true;
+                }
+            }
         }
 
-        final long estimatedMillis = ((estimatedBytes * DateUtils.SECOND_IN_MILLIS)
-                / (slowest * TrafficStats.KB_IN_BYTES / 8));
-        if (estimatedMillis > JobServiceContext.EXECUTING_TIMESLICE_MILLIS) {
-            // If we'd never finish before the timeout, we'd be insane!
-            Slog.w(TAG, "Estimated " + estimatedBytes + " bytes over " + slowest
-                    + " kbps network would take " + estimatedMillis + "ms; that's insane!");
-            return true;
-        } else {
-            return false;
-        }
+        return false;
     }
 
-    @SuppressWarnings("unused")
     private static boolean isCongestionDelayed(JobStatus jobStatus, Network network,
             NetworkCapabilities capabilities, Constants constants) {
         // If network is congested, and job is less than 50% through the
@@ -361,14 +383,12 @@
         }
     }
 
-    @SuppressWarnings("unused")
     private static boolean isStrictSatisfied(JobStatus jobStatus, Network network,
             NetworkCapabilities capabilities, Constants constants) {
         return jobStatus.getJob().getRequiredNetwork().networkCapabilities
                 .satisfiedByNetworkCapabilities(capabilities);
     }
 
-    @SuppressWarnings("unused")
     private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network,
             NetworkCapabilities capabilities, Constants constants) {
         // Only consider doing this for prefetching jobs
@@ -389,7 +409,7 @@
     }
 
     @VisibleForTesting
-    static boolean isSatisfied(JobStatus jobStatus, Network network,
+    boolean isSatisfied(JobStatus jobStatus, Network network,
             NetworkCapabilities capabilities, Constants constants) {
         // Zeroth, we gotta have a network to think about being satisfied
         if (network == null || capabilities == null) return false;
@@ -585,6 +605,9 @@
                     case MSG_UID_RULES_CHANGES:
                         updateTrackedJobs(msg.arg1, null);
                         break;
+                    case MSG_REEVALUATE_JOBS:
+                        updateTrackedJobs(-1, null);
+                        break;
                 }
             }
         }
@@ -594,6 +617,8 @@
     @Override
     public void dumpControllerStateLocked(IndentingPrintWriter pw,
             Predicate<JobStatus> predicate) {
+        pw.print("mUseQuotaLimit="); pw.println(mUseQuotaLimit);
+
         if (mRequestedWhitelistJobs.size() > 0) {
             pw.print("Requested standby exceptions:");
             for (int i = 0; i < mRequestedWhitelistJobs.size(); i++) {
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index fd20e11..d73c253 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -24,7 +24,6 @@
 import android.app.job.JobWorkItem;
 import android.content.ClipData;
 import android.content.ComponentName;
-import android.content.pm.PackageManagerInternal;
 import android.net.Network;
 import android.net.Uri;
 import android.os.RemoteException;
@@ -131,7 +130,6 @@
      * that underly Sync Manager operation.
      */
     final int callingUid;
-    final int targetSdkVersion;
     final String batteryName;
 
     /**
@@ -188,6 +186,9 @@
      */
     private long whenStandbyDeferred;
 
+    /** The first time this job was force batched. */
+    private long mFirstForceBatchedTimeElapsed;
+
     // Constraints.
     final int requiredConstraints;
     private final int mRequiredConstraintsOfInterest;
@@ -305,7 +306,8 @@
      */
     ContentObserverController.JobInstance contentObserverJobInstance;
 
-    private long totalNetworkBytes = JobInfo.NETWORK_BYTES_UNKNOWN;
+    private long mTotalNetworkDownloadBytes = JobInfo.NETWORK_BYTES_UNKNOWN;
+    private long mTotalNetworkUploadBytes = JobInfo.NETWORK_BYTES_UNKNOWN;
 
     /////// Booleans that track if a job is ready to run. They should be updated whenever dependent
     /////// states change.
@@ -343,7 +345,6 @@
      * @param job The actual requested parameters for the job
      * @param callingUid Identity of the app that is scheduling the job.  This may not be the
      *     app in which the job is implemented; such as with sync jobs.
-     * @param targetSdkVersion The targetSdkVersion of the app in which the job will run.
      * @param sourcePackageName The package name of the app in which the job will run.
      * @param sourceUserId The user in which the job will run
      * @param standbyBucket The standby bucket that the source package is currently assigned to,
@@ -362,13 +363,12 @@
      * @param lastFailedRunTime When did we last run this job only to have it stop incomplete?
      * @param internalFlags Non-API property flags about this job
      */
-    private JobStatus(JobInfo job, int callingUid, int targetSdkVersion, String sourcePackageName,
+    private JobStatus(JobInfo job, int callingUid, String sourcePackageName,
             int sourceUserId, int standbyBucket, long heartbeat, String tag, int numFailures,
             long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis,
             long lastSuccessfulRunTime, long lastFailedRunTime, int internalFlags) {
         this.job = job;
         this.callingUid = callingUid;
-        this.targetSdkVersion = targetSdkVersion;
         this.standbyBucket = standbyBucket;
         this.baseHeartbeat = heartbeat;
 
@@ -438,7 +438,7 @@
     /** Copy constructor: used specifically when cloning JobStatus objects for persistence,
      *   so we preserve RTC window bounds if the source object has them. */
     public JobStatus(JobStatus jobStatus) {
-        this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.targetSdkVersion,
+        this(jobStatus.getJob(), jobStatus.getUid(),
                 jobStatus.getSourcePackageName(), jobStatus.getSourceUserId(),
                 jobStatus.getStandbyBucket(), jobStatus.getBaseHeartbeat(),
                 jobStatus.getSourceTag(), jobStatus.getNumFailures(),
@@ -467,7 +467,7 @@
             long lastSuccessfulRunTime, long lastFailedRunTime,
             Pair<Long, Long> persistedExecutionTimesUTC,
             int innerFlags) {
-        this(job, callingUid, resolveTargetSdkVersion(job), sourcePkgName, sourceUserId,
+        this(job, callingUid, sourcePkgName, sourceUserId,
                 standbyBucket, baseHeartbeat,
                 sourceTag, 0,
                 earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
@@ -490,7 +490,7 @@
             long newEarliestRuntimeElapsedMillis,
             long newLatestRuntimeElapsedMillis, int backoffAttempt,
             long lastSuccessfulRunTime, long lastFailedRunTime) {
-        this(rescheduling.job, rescheduling.getUid(), resolveTargetSdkVersion(rescheduling.job),
+        this(rescheduling.job, rescheduling.getUid(),
                 rescheduling.getSourcePackageName(), rescheduling.getSourceUserId(),
                 rescheduling.getStandbyBucket(), newBaseHeartbeat,
                 rescheduling.getSourceTag(), backoffAttempt, newEarliestRuntimeElapsedMillis,
@@ -511,8 +511,13 @@
         final long elapsedNow = sElapsedRealtimeClock.millis();
         final long earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis;
         if (job.isPeriodic()) {
-            latestRunTimeElapsedMillis = elapsedNow + job.getIntervalMillis();
-            earliestRunTimeElapsedMillis = latestRunTimeElapsedMillis - job.getFlexMillis();
+            // Make sure period is in the interval [min_possible_period, max_possible_period].
+            final long period = Math.max(JobInfo.getMinPeriodMillis(),
+                    Math.min(JobSchedulerService.MAX_ALLOWED_PERIOD_MS, job.getIntervalMillis()));
+            latestRunTimeElapsedMillis = elapsedNow + period;
+            earliestRunTimeElapsedMillis = latestRunTimeElapsedMillis
+                    // Make sure flex is in the interval [min_possible_flex, period].
+                    - Math.max(JobInfo.getMinFlexMillis(), Math.min(period, job.getFlexMillis()));
         } else {
             earliestRunTimeElapsedMillis = job.hasEarlyConstraint() ?
                     elapsedNow + job.getMinLatencyMillis() : NO_EARLIEST_RUNTIME;
@@ -527,7 +532,7 @@
         long currentHeartbeat = js != null
                 ? js.baseHeartbeatForApp(jobPackage, sourceUserId, standbyBucket)
                 : 0;
-        return new JobStatus(job, callingUid, resolveTargetSdkVersion(job), sourcePkg, sourceUserId,
+        return new JobStatus(job, callingUid, sourcePkg, sourceUserId,
                 standbyBucket, currentHeartbeat, tag, 0,
                 earliestRunTimeElapsedMillis, latestRunTimeElapsedMillis,
                 0 /* lastSuccessfulRunTime */, 0 /* lastFailedRunTime */,
@@ -675,10 +680,6 @@
         return job.getId();
     }
 
-    public int getTargetSdkVersion() {
-        return targetSdkVersion;
-    }
-
     public void printUniqueId(PrintWriter pw) {
         UserHandle.formatUid(pw, callingUid);
         pw.print("/");
@@ -731,6 +732,18 @@
         whenStandbyDeferred = now;
     }
 
+    /**
+     * Returns the first time this job was force batched, in the elapsed realtime timebase. Will be
+     * 0 if this job was never force batched.
+     */
+    public long getFirstForceBatchedTimeElapsed() {
+        return mFirstForceBatchedTimeElapsed;
+    }
+
+    public void setFirstForceBatchedTimeElapsed(long now) {
+        mFirstForceBatchedTimeElapsed = now;
+    }
+
     public String getSourceTag() {
         return sourceTag;
     }
@@ -782,35 +795,39 @@
     }
 
     private void updateEstimatedNetworkBytesLocked() {
-        totalNetworkBytes = computeEstimatedNetworkBytesLocked();
-    }
+        mTotalNetworkDownloadBytes = job.getEstimatedNetworkDownloadBytes();
+        mTotalNetworkUploadBytes = job.getEstimatedNetworkUploadBytes();
 
-    private long computeEstimatedNetworkBytesLocked() {
-        // If any component of the job has unknown usage, we don't have a
-        // complete picture of what data will be used, and we have to treat the
-        // entire job as unknown.
-        long totalNetworkBytes = 0;
-        long networkBytes = job.getEstimatedNetworkBytes();
-        if (networkBytes == JobInfo.NETWORK_BYTES_UNKNOWN) {
-            return JobInfo.NETWORK_BYTES_UNKNOWN;
-        } else {
-            totalNetworkBytes += networkBytes;
-        }
         if (pendingWork != null) {
             for (int i = 0; i < pendingWork.size(); i++) {
-                networkBytes = pendingWork.get(i).getEstimatedNetworkBytes();
-                if (networkBytes == JobInfo.NETWORK_BYTES_UNKNOWN) {
-                    return JobInfo.NETWORK_BYTES_UNKNOWN;
-                } else {
-                    totalNetworkBytes += networkBytes;
+                if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+                    // If any component of the job has unknown usage, we don't have a
+                    // complete picture of what data will be used, and we have to treat the
+                    // entire up/download as unknown.
+                    long downloadBytes = pendingWork.get(i).getEstimatedNetworkDownloadBytes();
+                    if (downloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+                        mTotalNetworkDownloadBytes += downloadBytes;
+                    }
+                }
+                if (mTotalNetworkUploadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+                    // If any component of the job has unknown usage, we don't have a
+                    // complete picture of what data will be used, and we have to treat the
+                    // entire up/download as unknown.
+                    long uploadBytes = pendingWork.get(i).getEstimatedNetworkUploadBytes();
+                    if (uploadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+                        mTotalNetworkUploadBytes += uploadBytes;
+                    }
                 }
             }
         }
-        return totalNetworkBytes;
     }
 
-    public long getEstimatedNetworkBytes() {
-        return totalNetworkBytes;
+    public long getEstimatedNetworkDownloadBytes() {
+        return mTotalNetworkDownloadBytes;
+    }
+
+    public long getEstimatedNetworkUploadBytes() {
+        return mTotalNetworkUploadBytes;
     }
 
     /** Does this job have any sort of networking constraint? */
@@ -1431,11 +1448,6 @@
         }
     }
 
-    private static int resolveTargetSdkVersion(JobInfo job) {
-        return LocalServices.getService(PackageManagerInternal.class)
-                .getPackageTargetSdkVersion(job.getService().getPackageName());
-    }
-
     // Dumpsys infrastructure
     public void dump(PrintWriter pw, String prefix, boolean full, long elapsedRealtimeMillis) {
         pw.print(prefix); UserHandle.formatUid(pw, callingUid);
@@ -1519,9 +1531,13 @@
                 pw.print(prefix); pw.print("  Network type: ");
                 pw.println(job.getRequiredNetwork());
             }
-            if (totalNetworkBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
-                pw.print(prefix); pw.print("  Network bytes: ");
-                pw.println(totalNetworkBytes);
+            if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+                pw.print(prefix); pw.print("  Network download bytes: ");
+                pw.println(mTotalNetworkDownloadBytes);
+            }
+            if (mTotalNetworkUploadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+                pw.print(prefix); pw.print("  Network upload bytes: ");
+                pw.println(mTotalNetworkUploadBytes);
             }
             if (job.getMinLatencyMillis() != 0) {
                 pw.print(prefix); pw.print("  Minimum latency: ");
@@ -1624,6 +1640,12 @@
             TimeUtils.formatDuration(whenStandbyDeferred, elapsedRealtimeMillis, pw);
             pw.println();
         }
+        if (mFirstForceBatchedTimeElapsed != 0) {
+            pw.print(prefix);
+            pw.print("  Time since first force batch attempt: ");
+            TimeUtils.formatDuration(mFirstForceBatchedTimeElapsed, elapsedRealtimeMillis, pw);
+            pw.println();
+        }
         pw.print(prefix); pw.print("Enqueue time: ");
         TimeUtils.formatDuration(enqueueTime, elapsedRealtimeMillis, pw);
         pw.println();
@@ -1631,6 +1653,9 @@
         formatRunTime(pw, earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME, elapsedRealtimeMillis);
         pw.print(", latest=");
         formatRunTime(pw, latestRunTimeElapsedMillis, NO_LATEST_RUNTIME, elapsedRealtimeMillis);
+        pw.print(", original latest=");
+        formatRunTime(pw, mOriginalLatestRunTimeElapsedMillis,
+                NO_LATEST_RUNTIME, elapsedRealtimeMillis);
         pw.println();
         if (numFailures != 0) {
             pw.print(prefix); pw.print("Num failures: "); pw.println(numFailures);
@@ -1713,8 +1738,13 @@
             if (job.getRequiredNetwork() != null) {
                 job.getRequiredNetwork().writeToProto(proto, JobStatusDumpProto.JobInfo.REQUIRED_NETWORK);
             }
-            if (totalNetworkBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
-                proto.write(JobStatusDumpProto.JobInfo.TOTAL_NETWORK_BYTES, totalNetworkBytes);
+            if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+                proto.write(JobStatusDumpProto.JobInfo.TOTAL_NETWORK_DOWNLOAD_BYTES,
+                        mTotalNetworkDownloadBytes);
+            }
+            if (mTotalNetworkUploadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
+                proto.write(JobStatusDumpProto.JobInfo.TOTAL_NETWORK_UPLOAD_BYTES,
+                        mTotalNetworkUploadBytes);
             }
             proto.write(JobStatusDumpProto.JobInfo.MIN_LATENCY_MS, job.getMinLatencyMillis());
             proto.write(JobStatusDumpProto.JobInfo.MAX_EXECUTION_DELAY_MS, job.getMaxExecutionDelayMillis());
@@ -1808,6 +1838,11 @@
 
         proto.write(JobStatusDumpProto.STANDBY_BUCKET, standbyBucket);
         proto.write(JobStatusDumpProto.ENQUEUE_DURATION_MS, elapsedRealtimeMillis - enqueueTime);
+        proto.write(JobStatusDumpProto.TIME_SINCE_FIRST_DEFERRAL_MS,
+                whenStandbyDeferred == 0 ? 0 : elapsedRealtimeMillis - whenStandbyDeferred);
+        proto.write(JobStatusDumpProto.TIME_SINCE_FIRST_FORCE_BATCH_ATTEMPT_MS,
+                mFirstForceBatchedTimeElapsed == 0
+                        ? 0 : elapsedRealtimeMillis - mFirstForceBatchedTimeElapsed);
         if (earliestRunTimeElapsedMillis == NO_EARLIEST_RUNTIME) {
             proto.write(JobStatusDumpProto.TIME_UNTIL_EARLIEST_RUNTIME_MS, 0);
         } else {
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 ef6944e..b8cfac4 100644
--- a/services/core/java/com/android/server/job/controllers/QuotaController.java
+++ b/services/core/java/com/android/server/job/controllers/QuotaController.java
@@ -68,6 +68,7 @@
 import com.android.server.LocalServices;
 import com.android.server.job.ConstantsProto;
 import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobServiceContext;
 import com.android.server.job.StateControllerProto;
 
 import java.util.ArrayList;
@@ -617,7 +618,7 @@
         jobStatus.setTrackingController(JobStatus.TRACKING_QUOTA);
         if (mShouldThrottle) {
             final boolean isWithinQuota = isWithinQuotaLocked(jobStatus);
-            jobStatus.setQuotaConstraintSatisfied(isWithinQuota);
+            setConstraintSatisfied(jobStatus, isWithinQuota);
             if (!isWithinQuota) {
                 maybeScheduleStartAlarmLocked(userId, pkgName,
                         getEffectiveStandbyBucket(jobStatus));
@@ -737,6 +738,18 @@
         return mTopStartedJobs.contains(jobStatus);
     }
 
+    /** Returns the maximum amount of time this job could run for. */
+    public long getMaxJobExecutionTimeMsLocked(@NonNull final JobStatus jobStatus) {
+        // If quota is currently "free", then the job can run for the full amount of time.
+        if (mChargeTracker.isCharging()
+                || mInParole
+                || isTopStartedJobLocked(jobStatus)
+                || isUidInForeground(jobStatus.getSourceUid())) {
+            return JobServiceContext.EXECUTING_TIMESLICE_MILLIS;
+        }
+        return getRemainingExecutionTimeLocked(jobStatus);
+    }
+
     /**
      * Returns an appropriate standby bucket for the job, taking into account any standby
      * exemptions.
@@ -1282,10 +1295,10 @@
                 // An app in the ACTIVE bucket may be out of quota while the job could be in quota
                 // for some reason. Therefore, avoid setting the real value here and check each job
                 // individually.
-                changed |= js.setQuotaConstraintSatisfied(realInQuota);
+                changed |= setConstraintSatisfied(js, realInQuota);
             } else {
                 // This job is somehow exempted. Need to determine its own quota status.
-                changed |= js.setQuotaConstraintSatisfied(isWithinQuotaLocked(js));
+                changed |= setConstraintSatisfied(js, isWithinQuotaLocked(js));
             }
         }
         if (!realInQuota) {
@@ -1310,7 +1323,7 @@
 
         @Override
         public void accept(JobStatus jobStatus) {
-            wasJobChanged |= jobStatus.setQuotaConstraintSatisfied(isWithinQuotaLocked(jobStatus));
+            wasJobChanged |= setConstraintSatisfied(jobStatus, isWithinQuotaLocked(jobStatus));
             final int userId = jobStatus.getSourceUserId();
             final String packageName = jobStatus.getSourcePackageName();
             final int realStandbyBucket = jobStatus.getStandbyBucket();
@@ -1434,6 +1447,14 @@
         }
     }
 
+    private boolean setConstraintSatisfied(@NonNull JobStatus jobStatus, boolean isWithinQuota) {
+        if (!isWithinQuota && jobStatus.getWhenStandbyDeferred() == 0) {
+            // Mark that the job is being deferred due to buckets.
+            jobStatus.setWhenStandbyDeferred(sElapsedRealtimeClock.millis());
+        }
+        return jobStatus.setQuotaConstraintSatisfied(isWithinQuota);
+    }
+
     private final class ChargingTracker extends BroadcastReceiver {
         /**
          * Track whether we're charging. This has a slightly different definition than that of
@@ -2270,8 +2291,10 @@
                     mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
                     changed = true;
                 }
-                long newQuotaBufferMs = Math.max(0,
-                        Math.min(5 * MINUTE_IN_MILLIS, IN_QUOTA_BUFFER_MS));
+                // Make sure quota buffer is non-negative, not greater than allowed time per period,
+                // and no more than 5 minutes.
+                long newQuotaBufferMs = Math.max(0, Math.min(mAllowedTimePerPeriodMs,
+                        Math.min(5 * MINUTE_IN_MILLIS, IN_QUOTA_BUFFER_MS)));
                 if (mQuotaBufferMs != newQuotaBufferMs) {
                     mQuotaBufferMs = newQuotaBufferMs;
                     mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index ababad9..4c11947 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -18,20 +18,13 @@
 
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.AlarmManager.OnAlarmListener;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.provider.Settings;
-import android.util.KeyValueListParser;
 import android.util.Log;
 import android.util.Slog;
 import android.util.TimeUtils;
@@ -39,7 +32,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.job.ConstantsProto;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.StateControllerProto;
 
@@ -63,9 +55,6 @@
     /** Delay alarm tag for logging purposes */
     private final String DELAY_TAG = "*job.delay*";
 
-    private final Handler mHandler;
-    private final TcConstants mTcConstants;
-
     private long mNextJobExpiredElapsedMillis;
     private long mNextDelayExpiredElapsedMillis;
 
@@ -81,14 +70,6 @@
         mNextJobExpiredElapsedMillis = Long.MAX_VALUE;
         mNextDelayExpiredElapsedMillis = Long.MAX_VALUE;
         mChainedAttributionEnabled = mService.isChainedAttributionEnabled();
-
-        mHandler = new Handler(mContext.getMainLooper());
-        mTcConstants = new TcConstants(mHandler);
-    }
-
-    @Override
-    public void onSystemServicesReady() {
-        mTcConstants.start(mContext.getContentResolver());
     }
 
     /**
@@ -133,20 +114,16 @@
 
             job.setTrackingController(JobStatus.TRACKING_TIME);
             WorkSource ws = deriveWorkSource(job.getSourceUid(), job.getSourcePackageName());
-            final long deadlineExpiredElapsed =
-                    job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE;
-            final long delayExpiredElapsed =
-                    job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE;
-            if (mTcConstants.SKIP_NOT_READY_JOBS) {
-                if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
-                    maybeUpdateDelayAlarmLocked(delayExpiredElapsed, ws);
-                }
-                if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) {
-                    maybeUpdateDeadlineAlarmLocked(deadlineExpiredElapsed, ws);
-                }
-            } else {
-                maybeUpdateDelayAlarmLocked(delayExpiredElapsed, ws);
-                maybeUpdateDeadlineAlarmLocked(deadlineExpiredElapsed, ws);
+
+            // Only update alarms if the job would be ready with the relevant timing constraint
+            // satisfied.
+            if (job.hasTimingDelayConstraint()
+                    && wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
+                maybeUpdateDelayAlarmLocked(job.getEarliestRunTime(), ws);
+            }
+            if (job.hasDeadlineConstraint()
+                    && wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) {
+                maybeUpdateDeadlineAlarmLocked(job.getLatestRunTimeElapsed(), ws);
             }
         }
     }
@@ -168,10 +145,6 @@
 
     @Override
     public void evaluateStateLocked(JobStatus job) {
-        if (!mTcConstants.SKIP_NOT_READY_JOBS) {
-            return;
-        }
-
         final long nowElapsedMillis = sElapsedRealtimeClock.millis();
 
         // Check deadline constraint first because if it's satisfied, we avoid a little bit of
@@ -261,9 +234,7 @@
                     }
                     it.remove();
                 } else {  // Sorted by expiry time, so take the next one and stop.
-                    if (mTcConstants.SKIP_NOT_READY_JOBS
-                            && !wouldBeReadyWithConstraintLocked(
-                            job, JobStatus.CONSTRAINT_DEADLINE)) {
+                    if (!wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) {
                         if (DEBUG) {
                             Slog.i(TAG,
                                     "Skipping " + job + " because deadline won't make it ready.");
@@ -321,9 +292,7 @@
                         ready = true;
                     }
                 } else {
-                    if (mTcConstants.SKIP_NOT_READY_JOBS
-                            && !wouldBeReadyWithConstraintLocked(
-                            job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
+                    if (!wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_TIMING_DELAY)) {
                         if (DEBUG) {
                             Slog.i(TAG,
                                     "Skipping " + job + " because delay won't make it ready.");
@@ -458,81 +427,6 @@
         checkExpiredDelaysAndResetAlarm();
     }
 
-    @VisibleForTesting
-    class TcConstants extends ContentObserver {
-        private ContentResolver mResolver;
-        private final KeyValueListParser mParser = new KeyValueListParser(',');
-
-        private static final String KEY_SKIP_NOT_READY_JOBS = "skip_not_ready_jobs";
-
-        private static final boolean DEFAULT_SKIP_NOT_READY_JOBS = true;
-
-        /**
-         * Whether or not TimeController should skip setting wakeup alarms for jobs that aren't
-         * ready now.
-         */
-        public boolean SKIP_NOT_READY_JOBS = DEFAULT_SKIP_NOT_READY_JOBS;
-
-        /**
-         * Creates a content observer.
-         *
-         * @param handler The handler to run {@link #onChange} on, or null if none.
-         */
-        TcConstants(Handler handler) {
-            super(handler);
-        }
-
-        private void start(ContentResolver resolver) {
-            mResolver = resolver;
-            mResolver.registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS), false, this);
-            onChange(true, null);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            final String constants = Settings.Global.getString(
-                    mResolver, Settings.Global.JOB_SCHEDULER_TIME_CONTROLLER_CONSTANTS);
-
-            try {
-                mParser.setString(constants);
-            } catch (Exception e) {
-                // Failed to parse the settings string, log this and move on with defaults.
-                Slog.e(TAG, "Bad jobscheduler time controller settings", e);
-            }
-
-            final boolean oldVal = SKIP_NOT_READY_JOBS;
-            SKIP_NOT_READY_JOBS = mParser.getBoolean(
-                    KEY_SKIP_NOT_READY_JOBS, DEFAULT_SKIP_NOT_READY_JOBS);
-
-            if (oldVal != SKIP_NOT_READY_JOBS) {
-                synchronized (mLock) {
-                    recheckAlarmsLocked();
-                }
-            }
-        }
-
-        private void dump(IndentingPrintWriter pw) {
-            pw.println();
-            pw.println("TimeController:");
-            pw.increaseIndent();
-            pw.printPair(KEY_SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS).println();
-            pw.decreaseIndent();
-        }
-
-        private void dump(ProtoOutputStream proto) {
-            final long tcToken = proto.start(ConstantsProto.TIME_CONTROLLER);
-            proto.write(ConstantsProto.TimeController.SKIP_NOT_READY_JOBS, SKIP_NOT_READY_JOBS);
-            proto.end(tcToken);
-        }
-    }
-
-    @VisibleForTesting
-    @NonNull
-    TcConstants getTcConstants() {
-        return mTcConstants;
-    }
-
     @Override
     public void dumpControllerStateLocked(IndentingPrintWriter pw,
             Predicate<JobStatus> predicate) {
@@ -607,14 +501,4 @@
         proto.end(mToken);
         proto.end(token);
     }
-
-    @Override
-    public void dumpConstants(IndentingPrintWriter pw) {
-        mTcConstants.dump(pw);
-    }
-
-    @Override
-    public void dumpConstants(ProtoOutputStream proto) {
-        mTcConstants.dump(proto);
-    }
 }
diff --git a/services/core/java/com/android/server/location/AbstractLocationProvider.java b/services/core/java/com/android/server/location/AbstractLocationProvider.java
index 0edd17b..c1a6394 100644
--- a/services/core/java/com/android/server/location/AbstractLocationProvider.java
+++ b/services/core/java/com/android/server/location/AbstractLocationProvider.java
@@ -77,20 +77,6 @@
     }
 
     /**
-     * Call this method to report a new location. May be called from any thread.
-     */
-    protected void reportLocation(Location location) {
-        mLocationProviderManager.onReportLocation(location);
-    }
-
-    /**
-     * Call this method to report a new location. May be called from any thread.
-     */
-    protected void reportLocation(List<Location> locations) {
-        mLocationProviderManager.onReportLocation(locations);
-    }
-
-    /**
      * Call this method to report a change in provider enabled/disabled status. May be called from
      * any thread.
      */
@@ -106,24 +92,50 @@
         mLocationProviderManager.onSetProperties(properties);
     }
 
-    /** Returns list of packages currently associated with this provider. */
+    /**
+     * Call this method to report a new location. May be called from any thread.
+     */
+    protected void reportLocation(Location location) {
+        mLocationProviderManager.onReportLocation(location);
+    }
+
+    /**
+     * Call this method to report a new location. May be called from any thread.
+     */
+    protected void reportLocation(List<Location> locations) {
+        mLocationProviderManager.onReportLocation(locations);
+    }
+
+    /**
+     * Invoked by the location service to return a list of packages currently associated with this
+     * provider. May be called from any thread.
+     */
     public List<String> getProviderPackages() {
         return Collections.singletonList(mContext.getPackageName());
     }
 
     /**
-     * Called when the location service delivers a new request for fulfillment to the provider.
-     * Replaces any previous requests completely.
+     * Invoked by the location service to deliver a new request for fulfillment to the provider.
+     * Replaces any previous requests completely. Will always be invoked from the location service
+     * thread with a cleared binder identity.
      */
-    public abstract void setRequest(ProviderRequest request, WorkSource source);
+    public abstract void onSetRequest(ProviderRequest request, WorkSource source);
 
     /**
-     * Called to dump debug or log information.
+     * Invoked by the location service to deliver a custom command to this provider. Will always be
+     * invoked from the location service thread with a cleared binder identity.
+     */
+    public void onSendExtraCommand(int uid, int pid, String command, Bundle extras) {}
+
+    /**
+     * Invoked by the location service to dump debug or log information. May be invoked from any
+     * thread.
      */
     public abstract void dump(FileDescriptor fd, PrintWriter pw, String[] args);
 
     /**
-     * Retrieves the current status of the provider.
+     * Invoked by the location service to retrieve the current status of the provider. May be
+     * invoked from any thread.
      *
      * @deprecated Will be removed in a future release.
      */
@@ -133,7 +145,8 @@
     }
 
     /**
-     * Retrieves the last update time of the status of the provider.
+     * Invoked by the location service to retrieve the last update time of the status of the
+     * provider. May be invoked from any thread.
      *
      * @deprecated Will be removed in a future release.
      */
@@ -141,7 +154,4 @@
     public long getStatusUpdateTime() {
         return 0;
     }
-
-    /** Sends a custom command to this provider. */
-    public abstract void sendExtraCommand(String command, Bundle extras);
 }
diff --git a/services/core/java/com/android/server/location/GeofenceManager.java b/services/core/java/com/android/server/location/GeofenceManager.java
index fafe99c..a192206 100644
--- a/services/core/java/com/android/server/location/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/GeofenceManager.java
@@ -16,11 +16,6 @@
 
 package com.android.server.location;
 
-import java.io.PrintWriter;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
 import android.content.ContentResolver;
@@ -44,6 +39,11 @@
 import com.android.server.LocationManagerService;
 import com.android.server.PendingIntentUtils;
 
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
 public class GeofenceManager implements LocationListener, PendingIntent.OnFinished {
     private static final String TAG = "GeofenceManager";
     private static final boolean D = LocationManagerService.D;
@@ -79,13 +79,13 @@
     private final GeofenceHandler mHandler;
     private final LocationBlacklist mBlacklist;
 
-    private Object mLock = new Object();
+    private final Object mLock = new Object();
 
     // access to members below is synchronized on mLock
     /**
      * A list containing all registered geofences.
      */
-    private List<GeofenceState> mFences = new LinkedList<GeofenceState>();
+    private List<GeofenceState> mFences = new LinkedList<>();
 
     /**
      * This is set true when we have an active request for {@link Location} updates via
@@ -272,8 +272,8 @@
      */
     // Runs on the handler.
     private void updateFences() {
-        List<PendingIntent> enterIntents = new LinkedList<PendingIntent>();
-        List<PendingIntent> exitIntents = new LinkedList<PendingIntent>();
+        List<PendingIntent> enterIntents = new LinkedList<>();
+        List<PendingIntent> exitIntents = new LinkedList<>();
 
         synchronized (mLock) {
             mPendingUpdate = false;
@@ -446,14 +446,8 @@
     }
 
     public void dump(PrintWriter pw) {
-        pw.println("  Geofences:");
-
         for (GeofenceState state : mFences) {
-            pw.append("    ");
-            pw.append(state.mPackageName);
-            pw.append(" ");
-            pw.append(state.mFence.toString());
-            pw.append("\n");
+            pw.println(state.mPackageName + " " + state.mFence);
         }
     }
 
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index f28bce5..6911b7c 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -182,7 +182,6 @@
     private static final int INJECT_NTP_TIME = 5;
     // PSDS stands for Predicted Satellite Data Service
     private static final int DOWNLOAD_PSDS_DATA = 6;
-    private static final int UPDATE_LOCATION = 7;  // Handle external location from network listener
     private static final int DOWNLOAD_PSDS_DATA_FINISHED = 11;
     private static final int INITIALIZE_HANDLER = 13;
     private static final int REQUEST_LOCATION = 16;
@@ -222,6 +221,8 @@
     private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
     // Default update duration in milliseconds for REQUEST_LOCATION.
     private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
+    // Update duration extension multiplier for emergency REQUEST_LOCATION.
+    private static final int EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER = 3;
 
     /** simpler wrapper for ProviderRequest + Worksource */
     private static class GpsRequest {
@@ -724,15 +725,28 @@
                 Context.LOCATION_SERVICE);
         String provider;
         LocationChangeListener locationListener;
+        LocationRequest locationRequest = new LocationRequest()
+                .setInterval(LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS)
+                .setFastestInterval(LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS);
 
         if (independentFromGnss) {
             // For fast GNSS TTFF
             provider = LocationManager.NETWORK_PROVIDER;
             locationListener = mNetworkLocationListener;
+            locationRequest.setQuality(LocationRequest.POWER_LOW);
         } else {
             // For Device-Based Hybrid (E911)
             provider = LocationManager.FUSED_PROVIDER;
             locationListener = mFusedLocationListener;
+            locationRequest.setQuality(LocationRequest.ACCURACY_FINE);
+        }
+
+        locationRequest.setProvider(provider);
+
+        // Ignore location settings if in emergency mode.
+        if (isUserEmergency && mNIHandler.getInEmergency()) {
+            locationRequest.setLocationSettingsIgnored(true);
+            durationMillis *= EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER;
         }
 
         Log.i(TAG,
@@ -740,14 +754,6 @@
                         "GNSS HAL Requesting location updates from %s provider for %d millis.",
                         provider, durationMillis));
 
-        LocationRequest locationRequest = LocationRequest.createFromDeprecatedProvider(provider,
-                LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /* minDistance= */ 0,
-                /* singleShot= */ false);
-
-        // Ignore location settings if in emergency mode.
-        if (isUserEmergency && mNIHandler.getInEmergency()) {
-            locationRequest.setLocationSettingsIgnored(true);
-        }
         try {
             locationManager.requestLocationUpdates(locationRequest,
                     locationListener, mHandler.getLooper());
@@ -765,6 +771,9 @@
     }
 
     private void injectBestLocation(Location location) {
+        if (DEBUG) {
+            Log.d(TAG, "injectBestLocation: " + location);
+        }
         int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
                 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
                 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
@@ -867,8 +876,11 @@
         });
     }
 
-    private void handleUpdateLocation(Location location) {
+    private void injectLocation(Location location) {
         if (location.hasAccuracy()) {
+            if (DEBUG) {
+                Log.d(TAG, "injectLocation: " + location);
+            }
             native_inject_location(location.getLatitude(), location.getLongitude(),
                     location.getAccuracy());
         }
@@ -937,7 +949,7 @@
             mGnssNavigationMessageProvider.onGpsEnabledChanged();
             mGnssBatchingProvider.enable();
             if (mGnssVisibilityControl != null) {
-                mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */true);
+                mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ true);
             }
         } else {
             setGpsEnabled(false);
@@ -1016,7 +1028,7 @@
     }
 
     @Override
-    public void setRequest(ProviderRequest request, WorkSource source) {
+    public void onSetRequest(ProviderRequest request, WorkSource source) {
         sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
     }
 
@@ -1153,7 +1165,7 @@
     }
 
     @Override
-    public void sendExtraCommand(String command, Bundle extras) {
+    public void onSendExtraCommand(int uid, int pid, String command, Bundle extras) {
 
         long identity = Binder.clearCallingIdentity();
         try {
@@ -2021,9 +2033,6 @@
                 case DOWNLOAD_PSDS_DATA_FINISHED:
                     mDownloadPsdsDataPending = STATE_IDLE;
                     break;
-                case UPDATE_LOCATION:
-                    handleUpdateLocation((Location) msg.obj);
-                    break;
                 case INITIALIZE_HANDLER:
                     handleInitialize();
                     break;
@@ -2119,7 +2128,7 @@
         public void onLocationChanged(Location location) {
             // this callback happens on mHandler looper
             if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
-                handleUpdateLocation(location);
+                injectLocation(location);
             }
         }
     }
@@ -2148,8 +2157,6 @@
                 return "DOWNLOAD_PSDS_DATA";
             case DOWNLOAD_PSDS_DATA_FINISHED:
                 return "DOWNLOAD_PSDS_DATA_FINISHED";
-            case UPDATE_LOCATION:
-                return "UPDATE_LOCATION";
             case INITIALIZE_HANDLER:
                 return "INITIALIZE_HANDLER";
             case REPORT_LOCATION:
@@ -2164,18 +2171,18 @@
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         StringBuilder s = new StringBuilder();
-        s.append("  mStarted=").append(mStarted).append("   (changed ");
+        s.append("mStarted=").append(mStarted).append("   (changed ");
         TimeUtils.formatDuration(SystemClock.elapsedRealtime()
                 - mStartedChangedElapsedRealtime, s);
         s.append(" ago)").append('\n');
-        s.append("  mFixInterval=").append(mFixInterval).append('\n');
-        s.append("  mLowPowerMode=").append(mLowPowerMode).append('\n');
-        s.append("  mGnssMeasurementsProvider.isRegistered()=")
+        s.append("mFixInterval=").append(mFixInterval).append('\n');
+        s.append("mLowPowerMode=").append(mLowPowerMode).append('\n');
+        s.append("mGnssMeasurementsProvider.isRegistered()=")
                 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
-        s.append("  mGnssNavigationMessageProvider.isRegistered()=")
+        s.append("mGnssNavigationMessageProvider.isRegistered()=")
                 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
-        s.append("  mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n');
-        s.append("  mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities));
+        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 ");
@@ -2192,12 +2199,13 @@
         }
         s.append(")\n");
         if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) {
-            s.append("  SubHal=MEASUREMENT_CORRECTIONS[");
+            s.append("SubHal=MEASUREMENT_CORRECTIONS[");
             s.append(mGnssMeasurementCorrectionsProvider.toStringCapabilities());
             s.append("]\n");
         }
         s.append(mGnssMetrics.dumpGnssMetricsAsText());
-        s.append("  native internal state: ").append(native_get_internal_state());
+        s.append("native internal state: \n");
+        s.append("  ").append(native_get_internal_state());
         s.append("\n");
         pw.append(s);
     }
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index 65bd5c6..ea4f9c4 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -78,7 +78,6 @@
     private final Handler mHandler;
     private final Context mContext;
     private final GpsNetInitiatedHandler mNiHandler;
-    private final Notification mEmergencyLocationUserNotification;
 
     private boolean mIsGpsEnabled;
 
@@ -107,7 +106,6 @@
         mNiHandler = niHandler;
         mAppOps = mContext.getSystemService(AppOpsManager.class);
         mPackageManager = mContext.getPackageManager();
-        mEmergencyLocationUserNotification = createEmergencyLocationUserNotification(mContext);
 
         // Complete initialization as the first event to run in mHandler thread. After that,
         // all object state read/update events run in the mHandler thread.
@@ -153,7 +151,6 @@
     }
 
     private void handleInitialize() {
-        disableNfwLocationAccess(); // Disable until config properties are loaded.
         listenForProxyAppsPackageUpdates();
     }
 
@@ -263,25 +260,21 @@
         return false;
     }
 
-    private void handleGpsEnabledChanged(boolean isEnabled) {
-        if (DEBUG) Log.d(TAG, "handleGpsEnabledChanged, isEnabled: " + isEnabled);
-
-        if (mIsGpsEnabled == isEnabled) {
-            return;
+    private void handleGpsEnabledChanged(boolean isGpsEnabled) {
+        if (DEBUG) {
+            Log.d(TAG, "handleGpsEnabledChanged, mIsGpsEnabled: " + mIsGpsEnabled
+                    + ", isGpsEnabled: " + isGpsEnabled);
         }
 
-        mIsGpsEnabled = isEnabled;
+        // The proxy app list in the GNSS HAL needs to be configured if it restarts after
+        // a crash. So, update HAL irrespective of the previous GPS enabled state.
+        mIsGpsEnabled = isGpsEnabled;
         if (!mIsGpsEnabled) {
             disableNfwLocationAccess();
             return;
         }
 
-        // When GNSS was disabled, we already set the proxy app list to empty in GNSS HAL.
-        // Update only if the proxy app list is not empty.
-        String[] locationPermissionEnabledProxyApps = getLocationPermissionEnabledProxyApps();
-        if (locationPermissionEnabledProxyApps.length != 0) {
-            setNfwLocationAccessProxyAppsInGnssHal(locationPermissionEnabledProxyApps);
-        }
+        setNfwLocationAccessProxyAppsInGnssHal(getLocationPermissionEnabledProxyApps());
     }
 
     private void disableNfwLocationAccess() {
@@ -632,13 +625,15 @@
         }
 
         notificationManager.notifyAsUser(/* tag= */ null, /* notificationId= */ 0,
-                mEmergencyLocationUserNotification, UserHandle.ALL);
+                createEmergencyLocationUserNotification(mContext), UserHandle.ALL);
     }
 
     private static Notification createEmergencyLocationUserNotification(Context context) {
-        String firstLineText = context.getString(R.string.gpsNotifTitle);
-        String secondLineText =  context.getString(R.string.global_action_emergency);
-        String accessibilityServicesText = firstLineText + " (" + secondLineText + ")";
+        // NOTE: Do not reuse the returned notification object as it will not reflect
+        //       changes to notification text when the system language is changed.
+        final String firstLineText = context.getString(R.string.gpsNotifTitle);
+        final String secondLineText =  context.getString(R.string.global_action_emergency);
+        final String accessibilityServicesText = firstLineText + " (" + secondLineText + ")";
         return new Notification.Builder(context, SystemNotificationChannels.NETWORK_ALERTS)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_gps_on)
                 .setWhen(0)
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index ddbc203..09911ff 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -168,7 +168,7 @@
     }
 
     @Override
-    public void setRequest(ProviderRequest request, WorkSource source) {
+    public void onSetRequest(ProviderRequest request, WorkSource source) {
         synchronized (mRequestLock) {
             mRequest = request;
             mWorkSource = source;
@@ -181,10 +181,10 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("    service=" + mServiceWatcher);
+        pw.println("service=" + mServiceWatcher);
         synchronized (mProviderPackagesLock) {
             if (mProviderPackages.size() > 1) {
-                pw.println("    additional packages=" + mProviderPackages);
+                pw.println("additional packages=" + mProviderPackages);
             }
         }
     }
@@ -206,7 +206,7 @@
     }
 
     @Override
-    public void sendExtraCommand(String command, Bundle extras) {
+    public void onSendExtraCommand(int uid, int pid, String command, Bundle extras) {
         mServiceWatcher.runOnBinder(binder -> {
             ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
             service.sendExtraCommand(command, extras);
diff --git a/services/core/java/com/android/server/location/MockProvider.java b/services/core/java/com/android/server/location/MockProvider.java
index 6accad8..b0c4c2e 100644
--- a/services/core/java/com/android/server/location/MockProvider.java
+++ b/services/core/java/com/android/server/location/MockProvider.java
@@ -81,11 +81,11 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println(" last location=" + mLocation);
+        pw.println("last location=" + mLocation);
     }
 
     @Override
-    public void setRequest(ProviderRequest request, WorkSource source) {}
+    public void onSetRequest(ProviderRequest request, WorkSource source) {}
 
     @Override
     public int getStatus(Bundle extras) {
@@ -101,7 +101,4 @@
     public long getStatusUpdateTime() {
         return mStatusUpdateTime;
     }
-
-    @Override
-    public void sendExtraCommand(String command, Bundle extras) {}
 }
diff --git a/services/core/java/com/android/server/location/PassiveProvider.java b/services/core/java/com/android/server/location/PassiveProvider.java
index 3a841c9..639b1eb 100644
--- a/services/core/java/com/android/server/location/PassiveProvider.java
+++ b/services/core/java/com/android/server/location/PassiveProvider.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.location.Criteria;
 import android.location.Location;
-import android.os.Bundle;
 import android.os.WorkSource;
 
 import com.android.internal.location.ProviderProperties;
@@ -53,7 +52,7 @@
     }
 
     @Override
-    public void setRequest(ProviderRequest request, WorkSource source) {
+    public void onSetRequest(ProviderRequest request, WorkSource source) {
         mReportLocation = request.reportLocation;
     }
 
@@ -64,10 +63,7 @@
     }
 
     @Override
-    public void sendExtraCommand(String command, Bundle extras) {}
-
-    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println(" report location=" + mReportLocation);
+        pw.println("report location=" + mReportLocation);
     }
 }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 107e1fbb..433ce81 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -32,6 +32,7 @@
 import static com.android.internal.widget.LockPatternUtils.frpCredentialEnabled;
 import static com.android.internal.widget.LockPatternUtils.userOwnsFrpCredential;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
@@ -169,6 +170,20 @@
     private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
     private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
 
+    // No challenge provided
+    private static final int CHALLENGE_NONE = 0;
+    // Challenge was provided from the external caller (non-LockSettingsService)
+    private static final int CHALLENGE_FROM_CALLER = 1;
+    // Challenge was generated from within LockSettingsService, for resetLockout. When challenge
+    // type is set to internal, LSS will revokeChallenge after all profiles for that user are
+    // unlocked.
+    private static final int CHALLENGE_INTERNAL = 2;
+
+    @IntDef({CHALLENGE_NONE,
+            CHALLENGE_FROM_CALLER,
+            CHALLENGE_INTERNAL})
+    @interface ChallengeType {};
+
     // Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
     // Do not call into ActivityManager while holding mSpManager lock.
     private final Object mSeparateChallengeLock = new Object();
@@ -276,6 +291,15 @@
         }
     }
 
+    private class PendingResetLockout {
+        final int mUserId;
+        final byte[] mHAT;
+        PendingResetLockout(int userId, byte[] hat) {
+            mUserId = userId;
+            mHAT = hat;
+        }
+    }
+
     /**
      * Tie managed profile to primary profile if it is in unified mode and not tied before.
      *
@@ -420,9 +444,9 @@
                     new PasswordSlotManager());
         }
 
-        public boolean hasEnrolledBiometrics() {
+        public boolean hasEnrolledBiometrics(int userId) {
             BiometricManager bm = mContext.getSystemService(BiometricManager.class);
-            return bm.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
+            return bm.canAuthenticate(userId) == BiometricManager.BIOMETRIC_SUCCESS;
         }
 
         public int binderGetCallingUid() {
@@ -584,7 +608,8 @@
                 // If boot took too long and the password in vold got expired, parent keystore will
                 // be still locked, we ignore this case since the user will be prompted to unlock
                 // the device after boot.
-                unlockChildProfile(userId, true /* ignoreUserNotAuthenticated */);
+                unlockChildProfile(userId, true /* ignoreUserNotAuthenticated */,
+                        CHALLENGE_NONE, 0 /* challenge */, null /* resetLockouts */);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Failed to unlock child profile");
             }
@@ -1160,12 +1185,15 @@
         return decryptionResult;
     }
 
-    private void unlockChildProfile(int profileHandle, boolean ignoreUserNotAuthenticated)
+    private void unlockChildProfile(int profileHandle, boolean ignoreUserNotAuthenticated,
+            @ChallengeType int challengeType, long challenge,
+            @Nullable ArrayList<PendingResetLockout> resetLockouts)
             throws RemoteException {
         try {
             doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
                     CREDENTIAL_TYPE_PASSWORD,
-                    false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
+                    challengeType, challenge, profileHandle, null /* progressCallback */,
+                    resetLockouts);
         } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
                 | NoSuchAlgorithmException | NoSuchPaddingException
                 | InvalidAlgorithmParameterException | IllegalBlockSizeException
@@ -1180,6 +1208,10 @@
         }
     }
 
+    private void unlockUser(int userId, byte[] token, byte[] secret) {
+        unlockUser(userId, token, secret, CHALLENGE_NONE, 0 /* challenge */, null);
+    }
+
     /**
      * Unlock the user (both storage and user state) and its associated managed profiles
      * synchronously.
@@ -1188,7 +1220,9 @@
      * can end up calling into other system services to process user unlock request (via
      * {@link com.android.server.SystemServiceManager#unlockUser} </em>
      */
-    private void unlockUser(int userId, byte[] token, byte[] secret) {
+    private void unlockUser(int userId, byte[] token, byte[] secret,
+            @ChallengeType int challengeType, long challenge,
+            @Nullable ArrayList<PendingResetLockout> resetLockouts) {
         // TODO: make this method fully async so we can update UI with progress strings
         final boolean alreadyUnlocked = mUserManager.isUserUnlockingOrUnlocked(userId);
         final CountDownLatch latch = new CountDownLatch(1);
@@ -1230,7 +1264,10 @@
             // Unlock managed profile with unified lock
             if (tiedManagedProfileReadyToUnlock(profile)) {
                 try {
-                    unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */);
+                    // Must pass the challenge on for resetLockout, so it's not over-written, which
+                    // causes LockSettingsService to revokeChallenge inappropriately.
+                    unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */,
+                            challengeType, challenge, resetLockouts);
                 } catch (RemoteException e) {
                     Log.d(TAG, "Failed to unlock child profile", e);
                 }
@@ -1247,6 +1284,21 @@
             }
 
         }
+
+        if (resetLockouts != null && !resetLockouts.isEmpty()) {
+            mHandler.post(() -> {
+                final BiometricManager bm = mContext.getSystemService(BiometricManager.class);
+                final PackageManager pm = mContext.getPackageManager();
+                for (int i = 0; i < resetLockouts.size(); i++) {
+                    bm.setActiveUser(resetLockouts.get(i).mUserId);
+                    bm.resetLockout(resetLockouts.get(i).mHAT);
+                }
+                if (challengeType == CHALLENGE_INTERNAL
+                        && pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+                    mContext.getSystemService(FaceManager.class).revokeChallenge();
+                }
+            });
+        }
     }
 
     private boolean tiedManagedProfileReadyToUnlock(UserInfo userInfo) {
@@ -1518,7 +1570,8 @@
             setUserKeyProtection(userId, credential, convertResponse(gkResponse));
             fixateNewestUserKeyAuth(userId);
             // Refresh the auth token
-            doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
+            doVerifyCredential(credential, credentialType, CHALLENGE_FROM_CALLER, 0, userId,
+                    null /* progressCallback */);
             synchronizeUnifiedWorkChallengeForProfiles(userId, null);
             sendCredentialsOnChangeIfRequired(
                     credentialType, credential, userId, isLockTiedToParent);
@@ -1743,24 +1796,32 @@
     public VerifyCredentialResponse checkCredential(byte[] credential, int type, int userId,
             ICheckCredentialProgressCallback progressCallback) throws RemoteException {
         checkPasswordReadPermission(userId);
-        return doVerifyCredential(credential, type, false, 0, userId, progressCallback);
+        return doVerifyCredential(credential, type, CHALLENGE_NONE, 0, userId, progressCallback);
     }
 
     @Override
     public VerifyCredentialResponse verifyCredential(byte[] credential, int type, long challenge,
             int userId) throws RemoteException {
         checkPasswordReadPermission(userId);
-        return doVerifyCredential(credential, type, true, challenge, userId,
+        return doVerifyCredential(credential, type, CHALLENGE_FROM_CALLER, challenge, userId,
                 null /* progressCallback */);
     }
 
+    private VerifyCredentialResponse doVerifyCredential(byte[] credential, int credentialType,
+            @ChallengeType int challengeType, long challenge, int userId,
+            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+        return doVerifyCredential(credential, credentialType, challengeType, challenge, userId,
+                progressCallback, null /* resetLockouts */);
+    }
+
     /**
      * Verify user credential and unlock the user. Fix pattern bug by deprecating the old base zero
      * format.
      */
     private VerifyCredentialResponse doVerifyCredential(byte[] credential, int credentialType,
-            boolean hasChallenge, long challenge, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+            @ChallengeType int challengeType, long challenge, int userId,
+            ICheckCredentialProgressCallback progressCallback,
+            @Nullable ArrayList<PendingResetLockout> resetLockouts) throws RemoteException {
         if (credential == null || credential.length == 0) {
             throw new IllegalArgumentException("Credential can't be null or empty");
         }
@@ -1770,8 +1831,8 @@
             return VerifyCredentialResponse.ERROR;
         }
         VerifyCredentialResponse response = null;
-        response = spBasedDoVerifyCredential(credential, credentialType, hasChallenge, challenge,
-                userId, progressCallback);
+        response = spBasedDoVerifyCredential(credential, credentialType, challengeType, challenge,
+                userId, progressCallback, resetLockouts);
         // The user employs synthetic password based credential.
         if (response != null) {
             if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
@@ -1803,7 +1864,7 @@
         }
 
         response = verifyCredential(userId, storedHash, credentialToVerify,
-                hasChallenge, challenge, progressCallback);
+                challengeType, challenge, progressCallback);
 
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
             mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
@@ -1829,7 +1890,7 @@
         final VerifyCredentialResponse parentResponse = doVerifyCredential(
                 credential,
                 type,
-                true /* hasChallenge */,
+                CHALLENGE_FROM_CALLER,
                 challenge,
                 parentProfileId,
                 null /* progressCallback */);
@@ -1842,7 +1903,7 @@
             // Unlock work profile, and work profile with unified lock must use password only
             return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
                     CREDENTIAL_TYPE_PASSWORD,
-                    true,
+                    CHALLENGE_FROM_CALLER,
                     challenge,
                     userId, null /* progressCallback */);
         } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
@@ -1860,7 +1921,7 @@
      * hash to GK.
      */
     private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
-            byte[] credential, boolean hasChallenge, long challenge,
+            byte[] credential, @ChallengeType int challengeType, long challenge,
             ICheckCredentialProgressCallback progressCallback) throws RemoteException {
         if ((storedHash == null || storedHash.hash.length == 0)
                     && (credential == null || credential.length == 0)) {
@@ -1903,7 +1964,7 @@
                                 : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
                                 /* TODO(roosa): keep the same password quality */,
                         userId, false, /* isLockTiedToParent= */ false);
-                if (!hasChallenge) {
+                if (challengeType == CHALLENGE_NONE) {
                     notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
                     // Use credentials to create recoverable keystore snapshot.
                     sendCredentialsOnUnlockIfRequired(storedHash.type, credential, userId);
@@ -2491,9 +2552,14 @@
     }
 
     private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential,
-            @CredentialType int credentialType, boolean hasChallenge, long challenge, int userId,
-            ICheckCredentialProgressCallback progressCallback) throws RemoteException {
-        if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
+            @CredentialType int credentialType, @ChallengeType int challengeType, long challenge,
+            int userId, ICheckCredentialProgressCallback progressCallback,
+            @Nullable ArrayList<PendingResetLockout> resetLockouts) throws RemoteException {
+
+        final boolean hasEnrolledBiometrics = mInjector.hasEnrolledBiometrics(userId);
+
+        Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId + " challengeType=" + challengeType
+                + " hasEnrolledBiometrics=" + hasEnrolledBiometrics);
         if (credentialType == CREDENTIAL_TYPE_NONE) {
             userCredential = null;
         }
@@ -2502,8 +2568,11 @@
         // TODO: When lockout is handled under the HAL for all biometrics (fingerprint),
         // we need to generate challenge for each one, have it signed by GK and reset lockout
         // for each modality.
-        if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)
-                && mInjector.hasEnrolledBiometrics()) {
+        if (challengeType == CHALLENGE_NONE && pm.hasSystemFeature(PackageManager.FEATURE_FACE)
+                && hasEnrolledBiometrics) {
+            // If there are multiple profiles in the same account, ensure we only generate the
+            // challenge once.
+            challengeType = CHALLENGE_INTERNAL;
             challenge = mContext.getSystemService(FaceManager.class).generateChallenge();
         }
 
@@ -2545,21 +2614,18 @@
         if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
             notifyActivePasswordMetricsAvailable(credentialType, userCredential, userId);
             unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
-            // Reset lockout only if user has enrolled templates
-            if (mInjector.hasEnrolledBiometrics()) {
-                BiometricManager bm = mContext.getSystemService(BiometricManager.class);
-                Slog.i(TAG, "Resetting lockout, length: "
-                        + authResult.gkResponse.getPayload().length);
-                bm.resetLockout(authResult.gkResponse.getPayload());
 
-                if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
-                    mContext.getSystemService(FaceManager.class).revokeChallenge();
+            // Do resetLockout / revokeChallenge when all profiles are unlocked
+            if (hasEnrolledBiometrics) {
+                if (resetLockouts == null) {
+                    resetLockouts = new ArrayList<>();
                 }
+                resetLockouts.add(new PendingResetLockout(userId, response.getPayload()));
             }
 
             final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
             Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
-            unlockUser(userId, null, secret);
+            unlockUser(userId, null, secret, challengeType, challenge, resetLockouts);
 
             activateEscrowTokens(authResult.authToken, userId);
 
diff --git a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
index 5cbd237..4ef63c0 100644
--- a/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
+++ b/services/core/java/com/android/server/locksettings/PasswordSlotManager.java
@@ -122,7 +122,7 @@
      */
     public void markSlotDeleted(int slot) throws RuntimeException {
         ensureSlotMapLoaded();
-        if (mSlotMap.containsKey(slot) && mSlotMap.get(slot) != getMode()) {
+        if (mSlotMap.containsKey(slot) && !mSlotMap.get(slot).equals(getMode())) {
             throw new RuntimeException("password slot " + slot + " cannot be deleted");
         }
         mSlotMap.remove(slot);
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
index 2fd2d74..9e34018 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -17,6 +17,7 @@
 package com.android.server.media;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -84,9 +85,16 @@
         mCallback = callback;
     }
 
-    public void setSelectedRoute(int uid, String routeId) {
+    public void selectRoute(String packageName, String routeId) {
         if (mConnectionReady) {
-            mActiveConnection.selectRoute(uid, routeId);
+            mActiveConnection.selectRoute(packageName, routeId);
+            updateBinding();
+        }
+    }
+
+    public void unselectRoute(String packageName, String routeId) {
+        if (mConnectionReady) {
+            mActiveConnection.unselectRotue(packageName, routeId);
             updateBinding();
         }
     }
@@ -98,6 +106,7 @@
         }
     }
 
+    @Nullable
     public MediaRoute2ProviderInfo getProviderInfo() {
         return mProviderInfo;
     }
@@ -233,17 +242,6 @@
         }
     }
 
-    private void onRouteSelected(Connection connection, int uid, String routeId) {
-        if (mActiveConnection != connection) {
-            return;
-        }
-
-        if (DEBUG) {
-            Slog.d(TAG, this + ": State changed ");
-        }
-        mHandler.post(mStateChanged);
-    }
-
     private void onProviderInfoUpdated(Connection connection, MediaRoute2ProviderInfo info) {
         if (mActiveConnection != connection) {
             return;
@@ -296,8 +294,8 @@
         public boolean register() {
             try {
                 mProvider.asBinder().linkToDeath(this, 0);
-                mProvider.registerClient(mClient);
-                mHandler.post((Runnable) () -> onConnectionReady(Connection.this));
+                mProvider.setClient(mClient);
+                mHandler.post(() -> onConnectionReady(Connection.this));
                 return true;
             } catch (RemoteException ex) {
                 binderDied();
@@ -310,23 +308,25 @@
             mClient.dispose();
         }
 
-        public void selectRoute(int uid, String id) {
-            if (mClient == null) {
-                return;
-            }
+        public void selectRoute(String packageName, String routeId) {
             try {
-                mProvider.selectRoute(mClient, uid, id);
+                mProvider.selectRoute(packageName, routeId);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "Failed to deliver request to set discovery mode.", ex);
             }
         }
 
-        public void sendControlRequest(String id, Intent request) {
-            if (mClient == null) {
-                return;
-            }
+        public void unselectRotue(String packageName, String routeId) {
             try {
-                mProvider.notifyControlRequestSent(mClient, id, request);
+                mProvider.unselectRoute(packageName, routeId);
+            } catch (RemoteException ex) {
+                Slog.e(TAG, "Failed to deliver request to set discovery mode.", ex);
+            }
+        }
+
+        public void sendControlRequest(String routeId, Intent request) {
+            try {
+                mProvider.notifyControlRequestSent(routeId, request);
             } catch (RemoteException ex) {
                 Slog.e(TAG, "Failed to deliver request to send control request.", ex);
             }
@@ -337,10 +337,6 @@
             mHandler.post(() -> onConnectionDied(Connection.this));
         }
 
-        void postRouteSelected(int uid, String routeId) {
-            mHandler.post(() -> onRouteSelected(Connection.this, uid, routeId));
-        }
-
         void postProviderUpdated(MediaRoute2ProviderInfo info) {
             mHandler.post(() -> onProviderInfoUpdated(Connection.this, info));
         }
@@ -358,14 +354,6 @@
         }
 
         @Override
-        public void notifyRouteSelected(int uid, String routeId) throws RemoteException {
-            Connection connection = mConnectionRef.get();
-            if (connection != null) {
-                connection.postRouteSelected(uid, routeId);
-            }
-        }
-
-        @Override
         public void notifyProviderInfoUpdated(MediaRoute2ProviderInfo info) {
             Connection connection = mConnectionRef.get();
             if (connection != null) {
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 98fbf75..12137fe 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -16,6 +16,8 @@
 
 package com.android.server.media;
 
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -30,15 +32,15 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.RemoteException;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -167,12 +169,24 @@
         }
     }
 
-    public void setRemoteRoute(@NonNull IMediaRouter2Manager manager,
-            int uid, @Nullable String routeId, boolean explicit) {
+    public void selectRoute2(@NonNull IMediaRouter2Client client,
+            @Nullable MediaRoute2Info route) {
         final long token = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                setRemoteRouteLocked(manager, uid, routeId, explicit);
+                selectRoute2Locked(client, route);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public void selectClientRoute2(@NonNull IMediaRouter2Manager manager,
+            String packageName, @Nullable MediaRoute2Info route) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                selectClientRoute2Locked(manager, packageName, route);
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -189,13 +203,15 @@
 
                 UserRecord oldUser = mUserRecords.get(oldUserId);
                 if (oldUser != null) {
-                    oldUser.mHandler.sendEmptyMessage(MediaRouterService.UserHandler.MSG_STOP);
+                    oldUser.mHandler.sendMessage(
+                            obtainMessage(UserHandler::stop, oldUser.mHandler));
                     disposeUserIfNeededLocked(oldUser); // since no longer current user
                 }
 
                 UserRecord newUser = mUserRecords.get(userId);
                 if (newUser != null) {
-                    newUser.mHandler.sendEmptyMessage(MediaRouterService.UserHandler.MSG_START);
+                    newUser.mHandler.sendMessage(
+                            obtainMessage(UserHandler::start, newUser.mHandler));
                 }
             }
         }
@@ -252,6 +268,53 @@
         }
     }
 
+    private void selectRoute2Locked(IMediaRouter2Client client, MediaRoute2Info route) {
+        ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+        if (clientRecord != null) {
+            MediaRoute2Info oldRoute = clientRecord.mSelectedRoute;
+            clientRecord.mSelectedRoute = route;
+
+            UserHandler handler = clientRecord.mUserRecord.mHandler;
+            //TODO: Handle transfer instead of unselect and select
+            if (oldRoute != null) {
+                handler.sendMessage(
+                        obtainMessage(UserHandler::unselectRoute, handler, clientRecord,
+                                oldRoute));
+            }
+            if (route != null) {
+                handler.sendMessage(
+                        obtainMessage(UserHandler::selectRoute, handler, clientRecord, route));
+            }
+            handler.sendMessage(
+                    obtainMessage(UserHandler::updateClientUsage, handler, clientRecord));
+        }
+    }
+
+    private void setControlCategoriesLocked(IMediaRouter2Client client, List<String> categories) {
+        final IBinder binder = client.asBinder();
+        ClientRecord clientRecord = mAllClientRecords.get(binder);
+
+        if (clientRecord != null) {
+            clientRecord.mControlCategories = categories;
+
+            clientRecord.mUserRecord.mHandler.sendMessage(
+                    obtainMessage(UserHandler::updateClientUsage,
+                            clientRecord.mUserRecord.mHandler, clientRecord));
+        }
+    }
+
+    private void sendControlRequestLocked(IMediaRouter2Client client, MediaRoute2Info route,
+            Intent request) {
+        final IBinder binder = client.asBinder();
+        ClientRecord clientRecord = mAllClientRecords.get(binder);
+
+        if (clientRecord != null) {
+            clientRecord.mUserRecord.mHandler.sendMessage(
+                    obtainMessage(UserHandler::sendControlRequest,
+                            clientRecord.mUserRecord.mHandler, route, request));
+        }
+    }
+
     private void registerManagerLocked(IMediaRouter2Manager manager,
             int uid, int pid, String packageName, int userId, boolean trusted) {
         final IBinder binder = manager.asBinder();
@@ -285,8 +348,9 @@
             final int count = userRecord.mClientRecords.size();
             for (int i = 0; i < count; i++) {
                 ClientRecord clientRecord = userRecord.mClientRecords.get(i);
-                clientRecord.mUserRecord.mHandler.obtainMessage(
-                        UserHandler.MSG_UPDATE_CLIENT_USAGE, clientRecord).sendToTarget();
+                clientRecord.mUserRecord.mHandler.sendMessage(
+                        obtainMessage(UserHandler::updateClientUsage,
+                            clientRecord.mUserRecord.mHandler, clientRecord));
             }
         }
     }
@@ -301,38 +365,17 @@
         }
     }
 
-    private void setRemoteRouteLocked(IMediaRouter2Manager manager,
-            int uid, String routeId, boolean explicit) {
+    private void selectClientRoute2Locked(IMediaRouter2Manager manager,
+            String packageName, MediaRoute2Info route) {
         ManagerRecord managerRecord = mAllManagerRecords.get(manager.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();
+            ClientRecord clientRecord = managerRecord.mUserRecord.findClientRecord(packageName);
+            if (clientRecord == null) {
+                Slog.w(TAG, "Ignoring route selection for unknown client.");
             }
-        }
-    }
-
-    private void setControlCategoriesLocked(IMediaRouter2Client 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 sendControlRequestLocked(IMediaRouter2Client client, MediaRoute2Info route,
-            Intent request) {
-        final IBinder binder = client.asBinder();
-        ClientRecord clientRecord = mAllClientRecords.get(binder);
-
-        if (clientRecord != null) {
-            Pair<MediaRoute2Info, Intent> obj = new Pair<>(route, request);
-            clientRecord.mUserRecord.mHandler.obtainMessage(
-                    UserHandler.MSG_SEND_CONTROL_REQUEST, obj).sendToTarget();
+            if (clientRecord != null && managerRecord.mTrusted) {
+                selectRoute2Locked(clientRecord.mClient, route);
+            }
         }
     }
 
@@ -341,7 +384,8 @@
             Slog.d(TAG, userRecord + ": Initialized");
         }
         if (userRecord.mUserId == mCurrentUserId) {
-            userRecord.mHandler.sendEmptyMessage(UserHandler.MSG_START);
+            userRecord.mHandler.sendMessage(
+                    obtainMessage(UserHandler::start, userRecord.mHandler));
         }
     }
 
@@ -371,6 +415,15 @@
             mUserId = userId;
             mHandler = new UserHandler(MediaRouter2ServiceImpl.this, this);
         }
+
+        ClientRecord findClientRecord(String packageName) {
+            for (ClientRecord clientRecord : mClientRecords) {
+                if (TextUtils.equals(clientRecord.mPackageName, packageName)) {
+                    return clientRecord;
+                }
+            }
+            return null;
+        }
     }
 
     final class ClientRecord implements IBinder.DeathRecipient {
@@ -381,6 +434,7 @@
         public final String mPackageName;
         public final boolean mTrusted;
         public List<String> mControlCategories;
+        public MediaRoute2Info mSelectedRoute;
 
         ClientRecord(UserRecord userRecord, IMediaRouter2Client client,
                 int uid, int pid, String packageName, boolean trusted) {
@@ -447,20 +501,12 @@
             MediaRoute2ProviderWatcher.Callback,
             MediaRoute2ProviderProxy.Callback {
 
-        //TODO: Should be rearranged
-        public static final int MSG_START = 1;
-        public static final int MSG_STOP = 2;
-
-        private static final int MSG_SELECT_REMOTE_ROUTE = 10;
-        private static final int MSG_UPDATE_CLIENT_USAGE = 11;
-        private static final int MSG_UPDATE_MANAGER_STATE = 12;
-        private static final int MSG_SEND_CONTROL_REQUEST = 13;
-
         private final WeakReference<MediaRouter2ServiceImpl> mServiceRef;
         private final UserRecord mUserRecord;
         private final MediaRoute2ProviderWatcher mWatcher;
         private final ArrayList<IMediaRouter2Manager> mTempManagers = new ArrayList<>();
 
+        //TODO: Make this thread-safe.
         private final ArrayList<MediaRoute2ProviderProxy> mMediaProviders =
                 new ArrayList<>();
 
@@ -475,37 +521,6 @@
                     this, mUserRecord.mUserId);
         }
 
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_START: {
-                    start();
-                    break;
-                }
-                case MSG_STOP: {
-                    stop();
-                    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;
-                }
-                case MSG_UPDATE_MANAGER_STATE: {
-                    updateManagerState();
-                    break;
-                }
-                case MSG_SEND_CONTROL_REQUEST: {
-                    Pair<MediaRoute2Info, Intent> obj = (Pair<MediaRoute2Info, Intent>) msg.obj;
-                    sendControlRequest(obj.first, obj.second);
-                }
-            }
-        }
-
         private void start() {
             if (!mRunning) {
                 mRunning = true;
@@ -541,29 +556,39 @@
             scheduleUpdateManagerState();
         }
 
+        private void selectRoute(ClientRecord clientRecord, MediaRoute2Info route) {
+            if (route != null) {
+                MediaRoute2ProviderProxy provider = findProvider(route.getProviderId());
+                if (provider == null) {
+                    Log.w(TAG, "Ignoring to select route of unknown provider " + route);
+                } else {
+                    provider.selectRoute(clientRecord.mPackageName, route.getId());
+                }
+            }
+        }
 
-        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 unselectRoute(ClientRecord clientRecord, MediaRoute2Info route) {
+            if (route != null) {
+                MediaRoute2ProviderProxy provider = findProvider(route.getProviderId());
+                if (provider == null) {
+                    Log.w(TAG, "Ignoring to unselect route of unknown provider " + route);
+                } else {
+                    provider.unselectRoute(clientRecord.mPackageName, route.getId());
                 }
             }
         }
 
         private void sendControlRequest(MediaRoute2Info route, Intent request) {
-            final int providerCount = mMediaProviders.size();
-            for (int i = 0; i < providerCount; i++) {
-                mMediaProviders.get(i).sendControlRequest(route, request);
+            final MediaRoute2ProviderProxy provider = findProvider(route.getProviderId());
+            if (provider != null) {
+                provider.sendControlRequest(route, request);
             }
         }
 
         private void scheduleUpdateManagerState() {
             if (!mManagerStateUpdateScheduled) {
                 mManagerStateUpdateScheduled = true;
-                sendEmptyMessage(MSG_UPDATE_MANAGER_STATE);
+                sendMessage(PooledLambda.obtainMessage(UserHandler::updateManagerState, this));
             }
         }
 
@@ -576,10 +601,9 @@
             }
             //TODO: Consider using a member variable (like mTempManagers).
             final List<MediaRoute2ProviderInfo> providers = new ArrayList<>();
-            final int mediaCount = mMediaProviders.size();
-            for (int i = 0; i < mediaCount; i++) {
+            for (MediaRoute2ProviderProxy mediaProvider : mMediaProviders) {
                 final MediaRoute2ProviderInfo providerInfo =
-                        mMediaProviders.get(i).getProviderInfo();
+                        mediaProvider.getProviderInfo();
                 if (providerInfo == null || !providerInfo.isValid()) {
                     Log.w(TAG, "Ignoring invalid provider info : " + providerInfo);
                 } else {
@@ -594,16 +618,11 @@
                         mTempManagers.add(mUserRecord.mManagerRecords.get(i).mManager);
                     }
                 }
-                //TODO: Call !proper callbacks when provider descriptor is implemented.
-                if (!providers.isEmpty()) {
-                    final int count = mTempManagers.size();
-                    for (int i = 0; i < count; i++) {
-                        try {
-                            mTempManagers.get(i).notifyProviderInfosUpdated(providers);
-                        } catch (RemoteException ex) {
-                            Slog.w(TAG, "Failed to call onStateChanged. Manager probably died.",
-                                    ex);
-                        }
+                for (IMediaRouter2Manager tempManager : mTempManagers) {
+                    try {
+                        tempManager.notifyProviderInfosUpdated(providers);
+                    } catch (RemoteException ex) {
+                        Slog.w(TAG, "Failed to update manager state. Manager probably died.", ex);
                     }
                 }
             } finally {
@@ -624,16 +643,27 @@
                     managers.add(mUserRecord.mManagerRecords.get(i).mManager);
                 }
             }
-            final int count = managers.size();
-            for (int i = 0; i < count; i++) {
+            for (IMediaRouter2Manager manager : managers) {
                 try {
-                    managers.get(i).notifyControlCategoriesChanged(clientRecord.mUid,
+                    manager.notifyRouteSelected(clientRecord.mPackageName,
+                            clientRecord.mSelectedRoute);
+                    manager.notifyControlCategoriesChanged(clientRecord.mPackageName,
                             clientRecord.mControlCategories);
                 } catch (RemoteException ex) {
-                    Slog.w(TAG, "Failed to call onControlCategoriesChanged. "
-                            + "Manager probably died.", ex);
+                    Slog.w(TAG, "Failed to update client usage. Manager probably died.", ex);
                 }
             }
         }
+
+        private MediaRoute2ProviderProxy findProvider(String providerId) {
+            for (MediaRoute2ProviderProxy provider : mMediaProviders) {
+                final MediaRoute2ProviderInfo providerInfo = provider.getProviderInfo();
+                if (providerInfo != null
+                        && TextUtils.equals(providerInfo.getUniqueId(), providerId)) {
+                    return provider;
+                }
+            }
+            return null;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index d820c62..a43068b 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -451,6 +451,12 @@
 
     // Binder call
     @Override
+    public void selectRoute2(IMediaRouter2Client client, MediaRoute2Info route) {
+        mService2.selectRoute2(client, route);
+    }
+
+    // Binder call
+    @Override
     public void sendControlRequest(IMediaRouter2Client client, MediaRoute2Info route,
             Intent request) {
         mService2.sendControlRequest(client, route, request);
@@ -475,9 +481,9 @@
 
     // Binder call
     @Override
-    public void setRemoteRoute(IMediaRouter2Manager manager,
-            int uid, String routeId, boolean explicit) {
-        mService2.setRemoteRoute(manager, uid, routeId, explicit);
+    public void selectClientRoute2(IMediaRouter2Manager manager,
+            String packageName, MediaRoute2Info route) {
+        mService2.selectClientRoute2(manager, packageName, route);
     }
 
     // Binder call
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index adc1561..c05655a 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -54,6 +54,7 @@
 import android.media.session.ISession2TokensListener;
 import android.media.session.ISessionCallback;
 import android.media.session.ISessionManager;
+import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.net.Uri;
@@ -91,6 +92,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -747,6 +749,8 @@
 
         private final int mFullUserId;
         private final MediaSessionStack mPriorityStack;
+        private final HashMap<IBinder, CallbackRecord> mCallbacks = new HashMap<>();
+
         private PendingIntent mLastMediaButtonReceiver;
         private ComponentName mRestoredMediaButtonReceiver;
         private int mRestoredMediaButtonReceiverComponentType;
@@ -760,7 +764,6 @@
 
         private IOnMediaKeyListener mOnMediaKeyListener;
         private int mOnMediaKeyListenerUid;
-        private ICallback mCallback;
 
         FullUserRecord(int fullUserId) {
             mFullUserId = fullUserId;
@@ -792,6 +795,24 @@
             }
         }
 
+        public void registerCallbackLocked(ICallback callback, int uid) {
+            IBinder cbBinder = callback.asBinder();
+            CallbackRecord cr = new CallbackRecord(callback, uid);
+            mCallbacks.put(cbBinder, cr);
+            try {
+                cbBinder.linkToDeath(cr, 0);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to register callback", e);
+                mCallbacks.remove(cbBinder);
+            }
+        }
+
+        public void unregisterCallbackLocked(ICallback callback) {
+            IBinder cbBinder = callback.asBinder();
+            CallbackRecord cr = mCallbacks.remove(cbBinder);
+            cbBinder.unlinkToDeath(cr, 0);
+        }
+
         public void dumpLocked(PrintWriter pw, String prefix) {
             pw.print(prefix + "Record for full_user=" + mFullUserId);
             // Dump managed profile user ids associated with this user.
@@ -810,7 +831,10 @@
             pw.println(indent + "Media key listener: " + mOnMediaKeyListener);
             pw.println(indent + "Media key listener package: "
                     + getCallingPackageName(mOnMediaKeyListenerUid));
-            pw.println(indent + "Callback: " + mCallback);
+            pw.println(indent + "Callbacks: registered " + mCallbacks.size() + " callback(s)");
+            for (CallbackRecord cr : mCallbacks.values()) {
+                pw.println(indent + "  from " + getCallingPackageName(cr.uid));
+            }
             pw.println(indent + "Last MediaButtonReceiver: " + mLastMediaButtonReceiver);
             pw.println(indent + "Restored MediaButtonReceiver: " + mRestoredMediaButtonReceiver);
             pw.println(indent + "Restored MediaButtonReceiverComponentType: "
@@ -870,21 +894,18 @@
                     mFullUserId);
         }
 
-        private void pushAddressedPlayerChangedLocked() {
-            if (mCallback == null) {
-                return;
-            }
+        private void pushAddressedPlayerChangedLocked(ICallback callback) {
             try {
                 MediaSessionRecord mediaButtonSession = getMediaButtonSessionLocked();
                 if (mediaButtonSession != null) {
-                    mCallback.onAddressedPlayerChangedToMediaSession(
+                    callback.onAddressedPlayerChangedToMediaSession(
                             mediaButtonSession.getSessionToken());
                 } else if (mCurrentFullUserRecord.mLastMediaButtonReceiver != null) {
-                    mCallback.onAddressedPlayerChangedToMediaButtonReceiver(
+                    callback.onAddressedPlayerChangedToMediaButtonReceiver(
                             mCurrentFullUserRecord.mLastMediaButtonReceiver
                                     .getIntent().getComponent());
                 } else if (mCurrentFullUserRecord.mRestoredMediaButtonReceiver != null) {
-                    mCallback.onAddressedPlayerChangedToMediaButtonReceiver(
+                    callback.onAddressedPlayerChangedToMediaButtonReceiver(
                             mCurrentFullUserRecord.mRestoredMediaButtonReceiver);
                 }
             } catch (RemoteException e) {
@@ -892,6 +913,12 @@
             }
         }
 
+        private void pushAddressedPlayerChangedLocked() {
+            for (CallbackRecord cr : mCallbacks.values()) {
+                pushAddressedPlayerChangedLocked(cr.callback);
+            }
+        }
+
         private MediaSessionRecord getMediaButtonSessionLocked() {
             return isGlobalPriorityActiveLocked()
                     ? mGlobalPrioritySession : mPriorityStack.getMediaButtonSession();
@@ -925,6 +952,23 @@
             // Pick legacy behavior for BroadcastReceiver or unknown.
             return COMPONENT_TYPE_BROADCAST;
         }
+
+        final class CallbackRecord implements IBinder.DeathRecipient {
+            public final ICallback callback;
+            public final int uid;
+
+            CallbackRecord(ICallback callback, int uid) {
+                this.callback = callback;
+                this.uid = uid;
+            }
+
+            @Override
+            public void binderDied() {
+                synchronized (mLock) {
+                    mCallbacks.remove(callback.asBinder());
+                }
+            }
+        }
     }
 
     final class SessionsListenerRecord implements IBinder.DeathRecipient {
@@ -1183,6 +1227,9 @@
         }
 
         /**
+         * Dispaches media key events. This is called when the foreground activity didn't handled
+         * the incoming media key event.
+         * <p>
          * Handles the dispatching of the media button events to one of the
          * registered listeners, or if there was none, broadcast an
          * ACTION_MEDIA_BUTTON intent to the rest of the system.
@@ -1262,6 +1309,18 @@
             }
         }
 
+        /**
+         * Dispatches media key events to session as system service. This is used only when the
+         * foreground activity has set
+         * {@link android.app.Activity#setMediaController(MediaController)} and a media key was
+         * pressed.
+         *
+         * @param packageName The caller's package name, obtained by Context#getPackageName()
+         * @param opPackageName The caller's op package name, obtained by Context#getOpPackageName()
+         * @param sessionToken token for the session that the controller is pointing to
+         * @param keyEvent media key event
+         * @see #dispatchVolumeKeyEvent
+         */
         @Override
         public boolean dispatchMediaKeyEventToSessionAsSystemService(String packageName,
                 MediaSession.Token sessionToken, KeyEvent keyEvent) {
@@ -1272,9 +1331,7 @@
                 synchronized (mLock) {
                     MediaSessionRecord record = getMediaSessionRecordLocked(sessionToken);
                     if (record == null) {
-                        if (DEBUG) {
-                            Log.d(TAG, "Failed to find session to dispatch key event.");
-                        }
+                        Log.w(TAG, "Failed to find session to dispatch key event.");
                         return false;
                     }
                     if (DEBUG) {
@@ -1291,44 +1348,53 @@
         }
 
         @Override
-        public void setCallback(ICallback callback) {
+        public void registerCallback(final ICallback callback) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
+            final int userId = UserHandle.getUserId(uid);
             final long token = Binder.clearCallingIdentity();
             try {
-                if (!UserHandle.isSameApp(uid, Process.BLUETOOTH_UID)) {
-                    throw new SecurityException("Only Bluetooth service processes can set"
-                            + " Callback");
+                if (!hasMediaControlPermission(pid, uid)) {
+                    throw new SecurityException("MEDIA_CONTENT_CONTROL permission is required to"
+                            + "  register Callback");
                 }
                 synchronized (mLock) {
-                    int userId = UserHandle.getUserId(uid);
                     FullUserRecord user = getFullUserRecordLocked(userId);
                     if (user == null || user.mFullUserId != userId) {
-                        Log.w(TAG, "Only the full user can set the callback"
+                        Log.w(TAG, "Only the full user can register the callback"
                                 + ", userId=" + userId);
                         return;
                     }
-                    user.mCallback = callback;
-                    Log.d(TAG, "The callback " + user.mCallback
-                            + " is set by " + getCallingPackageName(uid));
-                    if (user.mCallback == null) {
+                    user.registerCallbackLocked(callback, uid);
+                    Log.d(TAG, "The callback (" + callback.asBinder()
+                            + ") is registered by " + getCallingPackageName(uid));
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void unregisterCallback(final ICallback callback) {
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final int userId = UserHandle.getUserId(uid);
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (!hasMediaControlPermission(pid, uid)) {
+                    throw new SecurityException("MEDIA_CONTENT_CONTROL permission is required to"
+                            + "  unregister Callback");
+                }
+                synchronized (mLock) {
+                    FullUserRecord user = getFullUserRecordLocked(userId);
+                    if (user == null || user.mFullUserId != userId) {
+                        Log.w(TAG, "Only the full user can unregister the callback"
+                                + ", userId=" + userId);
                         return;
                     }
-                    try {
-                        user.mCallback.asBinder().linkToDeath(
-                                new IBinder.DeathRecipient() {
-                                    @Override
-                                    public void binderDied() {
-                                        synchronized (mLock) {
-                                            user.mCallback = null;
-                                        }
-                                    }
-                                }, 0);
-                        user.pushAddressedPlayerChangedLocked();
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "Failed to set callback", e);
-                        user.mCallback = null;
-                    }
+                    user.unregisterCallbackLocked(callback);
+                    Log.d(TAG, "The callback (" + callback.asBinder()
+                            + ") is unregistered by " + getCallingPackageName(uid));
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -1452,9 +1518,12 @@
         }
 
         /**
+         * Dispaches volume key events. This is called when the foreground activity didn't handled
+         * the incoming volume key event.
+         * <p>
          * Handles the dispatching of the volume button events to one of the
          * registered listeners. If there's a volume key long-press listener and
-         * there's no active global priority session, long-pressess will be sent to the
+         * there's no active global priority session, long-presses will be sent to the
          * long-press listener instead of adjusting volume.
          *
          * @param packageName The caller's package name, obtained by Context#getPackageName()
@@ -1471,6 +1540,7 @@
          *            or {@link KeyEvent#KEYCODE_VOLUME_MUTE}.
          * @param stream stream type to adjust volume.
          * @param musicOnly true if both UI nor haptic feedback aren't needed when adjust volume.
+         * @see #dispatchVolumeKeyEventToSessionAsSystemService
          */
         @Override
         public void dispatchVolumeKeyEvent(String packageName, String opPackageName,
@@ -1597,6 +1667,18 @@
             }
         }
 
+        /**
+         * Dispatches volume key events to session as system service. This is used only when the
+         * foreground activity has set
+         * {@link android.app.Activity#setMediaController(MediaController)} and a hardware volume
+         * key was pressed.
+         *
+         * @param packageName The caller's package name, obtained by Context#getPackageName()
+         * @param opPackageName The caller's op package name, obtained by Context#getOpPackageName()
+         * @param sessionToken token for the session that the controller is pointing to
+         * @param keyEvent volume key event
+         * @see #dispatchVolumeKeyEvent
+         */
         @Override
         public void dispatchVolumeKeyEventToSessionAsSystemService(String packageName,
                 String opPackageName, MediaSession.Token sessionToken, KeyEvent keyEvent) {
@@ -1607,9 +1689,10 @@
                 synchronized (mLock) {
                     MediaSessionRecord record = getMediaSessionRecordLocked(sessionToken);
                     if (record == null) {
-                        if (DEBUG) {
-                            Log.d(TAG, "Failed to find session to dispatch key event.");
-                        }
+                        Log.w(TAG, "Failed to find session to dispatch key event, token="
+                                + sessionToken + ". Fallbacks to the default handling.");
+                        dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid, true,
+                                keyEvent, AudioManager.USE_DEFAULT_STREAM_TYPE, false);
                         return;
                     }
                     if (DEBUG) {
@@ -1740,6 +1823,7 @@
         public boolean isTrusted(String controllerPackageName, int controllerPid, int controllerUid)
                 throws RemoteException {
             final int uid = Binder.getCallingUid();
+            final int userId = UserHandle.getUserId(uid);
             final long token = Binder.clearCallingIdentity();
             try {
                 // Don't perform sanity check between controllerPackageName and controllerUid.
@@ -1750,8 +1834,8 @@
                 // Note that we can use Context#getOpPackageName() instead of
                 // Context#getPackageName() for getting package name that matches with the PID/UID,
                 // but it doesn't tell which package has created the MediaController, so useless.
-                return hasMediaControlPermission(UserHandle.getUserId(uid), controllerPackageName,
-                        controllerPid, controllerUid);
+                return hasMediaControlPermission(controllerPid, controllerUid)
+                        || hasEnabledNotificationListener(userId, controllerPackageName);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -1777,13 +1861,7 @@
             return resolvedUserId;
         }
 
-        private boolean hasMediaControlPermission(int resolvedUserId, String packageName,
-                int pid, int uid) throws RemoteException {
-            // Allow API calls from the System UI and Settings
-            if (hasStatusBarServicePermission(pid, uid)) {
-                return true;
-            }
-
+        private boolean hasMediaControlPermission(int pid, int uid) {
             // 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.
@@ -1792,11 +1870,15 @@
                     == PackageManager.PERMISSION_GRANTED) {
                 return true;
             } else if (DEBUG) {
-                Log.d(TAG, packageName + " (uid=" + uid + ") hasn't granted MEDIA_CONTENT_CONTROL");
+                Log.d(TAG, "uid(" + uid + ") hasn't granted MEDIA_CONTENT_CONTROL");
             }
+            return false;
+        }
 
+        private boolean hasEnabledNotificationListener(int resolvedUserId, String packageName)
+                throws RemoteException {
             // You may not access another user's content as an enabled listener.
-            final int userId = UserHandle.getUserId(uid);
+            final int userId = UserHandle.getUserId(resolvedUserId);
             if (resolvedUserId != userId) {
                 return false;
             }
@@ -1814,7 +1896,7 @@
                 }
             }
             if (DEBUG) {
-                Log.d(TAG, packageName + " (uid=" + uid + ") doesn't have an enabled "
+                Log.d(TAG, packageName + " (uid=" + resolvedUserId + ") doesn't have an enabled "
                         + "notification listener");
             }
             return false;
@@ -1919,13 +2001,14 @@
                 session.sendMediaButton(packageName, pid, uid, asSystemService, keyEvent,
                         needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
                         mKeyEventReceiver);
-                if (mCurrentFullUserRecord.mCallback != null) {
-                    try {
-                        mCurrentFullUserRecord.mCallback.onMediaKeyEventDispatchedToMediaSession(
+                try {
+                    for (FullUserRecord.CallbackRecord cr
+                            : mCurrentFullUserRecord.mCallbacks.values()) {
+                        cr.callback.onMediaKeyEventDispatchedToMediaSession(
                                 keyEvent, session.getSessionToken());
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "Failed to send callback", e);
                     }
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Failed to send callback", e);
                 }
             } else if (mCurrentFullUserRecord.mLastMediaButtonReceiver != null
                     || mCurrentFullUserRecord.mRestoredMediaButtonReceiver != null) {
@@ -1949,12 +2032,12 @@
                         receiver.send(mContext,
                                 needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
                                 mediaButtonIntent, mKeyEventReceiver, mHandler);
-                        if (mCurrentFullUserRecord.mCallback != null) {
-                            ComponentName componentName = mCurrentFullUserRecord
-                                    .mLastMediaButtonReceiver.getIntent().getComponent();
-                            if (componentName != null) {
-                                mCurrentFullUserRecord.mCallback
-                                        .onMediaKeyEventDispatchedToMediaButtonReceiver(
+                        ComponentName componentName = mCurrentFullUserRecord
+                                .mLastMediaButtonReceiver.getIntent().getComponent();
+                        if (componentName != null) {
+                            for (FullUserRecord.CallbackRecord cr
+                                    : mCurrentFullUserRecord.mCallbacks.values()) {
+                                cr.callback.onMediaKeyEventDispatchedToMediaButtonReceiver(
                                                 keyEvent, componentName);
                             }
                         }
@@ -1987,9 +2070,9 @@
                             Log.w(TAG, "Error sending media button to the restored intent "
                                     + receiver + ", type=" + componentType, e);
                         }
-                        if (mCurrentFullUserRecord.mCallback != null) {
-                            mCurrentFullUserRecord.mCallback
-                                    .onMediaKeyEventDispatchedToMediaButtonReceiver(
+                        for (FullUserRecord.CallbackRecord cr
+                                : mCurrentFullUserRecord.mCallbacks.values()) {
+                            cr.callback.onMediaKeyEventDispatchedToMediaButtonReceiver(
                                             keyEvent, receiver);
                         }
                     }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 19ff2c1..b4a8099 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -231,7 +231,6 @@
 import com.android.server.SystemConfig;
 
 import libcore.io.IoUtils;
-import libcore.util.EmptyArray;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlSerializer;
@@ -403,8 +402,10 @@
     private IConnectivityManager mConnManager;
     private PowerManagerInternal mPowerManagerInternal;
     private IDeviceIdleController mDeviceIdleController;
+
+    /** Current cached value of the current Battery Saver mode's setting for restrict background. */
     @GuardedBy("mUidRulesFirstLock")
-    private PowerSaveState mRestrictBackgroundPowerState;
+    private boolean mRestrictBackgroundLowPowerMode;
 
     // Store the status of restrict background before turning on battery saver.
     // Used to restore mRestrictBackground when battery saver is turned off.
@@ -539,7 +540,7 @@
     private final SparseArray<String> mSubIdToSubscriberId = new SparseArray<>();
     /** Set of all merged subscriberId as of last update */
     @GuardedBy("mNetworkPoliciesSecondLock")
-    private String[] mMergedSubscriberIds = EmptyArray.STRING;
+    private List<String[]> mMergedSubscriberIds = new ArrayList<>();
 
     /**
      * Indicates the uids restricted by admin from accessing metered data. It's a mapping from
@@ -771,11 +772,9 @@
 
                     // Update the restrictBackground if battery saver is turned on
                     mRestrictBackgroundBeforeBsm = mLoadedRestrictBackground;
-                    mRestrictBackgroundPowerState = mPowerManagerInternal
-                            .getLowPowerState(ServiceType.DATA_SAVER);
-                    final boolean localRestrictBackground =
-                            mRestrictBackgroundPowerState.batterySaverEnabled;
-                    if (localRestrictBackground && !mLoadedRestrictBackground) {
+                    mRestrictBackgroundLowPowerMode = mPowerManagerInternal
+                            .getLowPowerState(ServiceType.DATA_SAVER).batterySaverEnabled;
+                    if (mRestrictBackgroundLowPowerMode && !mLoadedRestrictBackground) {
                         mLoadedRestrictBackground = true;
                     }
                     mPowerManagerInternal.registerLowPowerModeObserver(
@@ -1353,9 +1352,15 @@
                         mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
 
                 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
-                builder.setContentIntent(PendingIntent.getActivity(
-                        mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
-
+                // TODO: Resolve to single code path.
+                if (UserManager.isHeadlessSystemUserMode()) {
+                    builder.setContentIntent(PendingIntent.getActivityAsUser(
+                            mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT,
+                            /* options= */ null, UserHandle.CURRENT));
+                } else {
+                    builder.setContentIntent(PendingIntent.getActivity(
+                            mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+                }
                 break;
             }
             case TYPE_LIMIT: {
@@ -1375,8 +1380,15 @@
                 builder.setSmallIcon(R.drawable.stat_notify_disabled_data);
 
                 final Intent intent = buildNetworkOverLimitIntent(res, policy.template);
-                builder.setContentIntent(PendingIntent.getActivity(
-                        mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+                // TODO: Resolve to single code path.
+                if (UserManager.isHeadlessSystemUserMode()) {
+                    builder.setContentIntent(PendingIntent.getActivityAsUser(
+                            mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT,
+                            /* options= */ null, UserHandle.CURRENT));
+                } else {
+                    builder.setContentIntent(PendingIntent.getActivity(
+                            mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+                }
                 break;
             }
             case TYPE_LIMIT_SNOOZED: {
@@ -1399,8 +1411,15 @@
                 builder.setChannelId(SystemNotificationChannels.NETWORK_STATUS);
 
                 final Intent intent = buildViewDataUsageIntent(res, policy.template);
-                builder.setContentIntent(PendingIntent.getActivity(
-                        mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+                // TODO: Resolve to single code path.
+                if (UserManager.isHeadlessSystemUserMode()) {
+                    builder.setContentIntent(PendingIntent.getActivityAsUser(
+                            mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT,
+                            /* options= */ null, UserHandle.CURRENT));
+                } else {
+                    builder.setContentIntent(PendingIntent.getActivity(
+                            mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+                }
                 break;
             }
             case TYPE_RAPID: {
@@ -1419,8 +1438,15 @@
                         mContext, 0, snoozeIntent, PendingIntent.FLAG_UPDATE_CURRENT));
 
                 final Intent viewIntent = buildViewDataUsageIntent(res, policy.template);
-                builder.setContentIntent(PendingIntent.getActivity(
-                        mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+                // TODO: Resolve to single code path.
+                if (UserManager.isHeadlessSystemUserMode()) {
+                    builder.setContentIntent(PendingIntent.getActivityAsUser(
+                            mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT,
+                            /* options= */ null, UserHandle.CURRENT));
+                } else {
+                    builder.setContentIntent(PendingIntent.getActivity(
+                            mContext, 0, viewIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+                }
                 break;
             }
             default: {
@@ -1773,7 +1799,7 @@
         final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
 
         final int[] subIds = ArrayUtils.defeatNullable(sm.getActiveSubscriptionIdList());
-        final String[] mergedSubscriberIds = ArrayUtils.defeatNullable(tm.getMergedSubscriberIds());
+        final List<String[]> mergedSubscriberIdsList = new ArrayList();
 
         final SparseArray<String> subIdToSubscriberId = new SparseArray<>(subIds.length);
         for (int subId : subIds) {
@@ -1783,6 +1809,10 @@
             } else {
                 Slog.wtf(TAG, "Missing subscriberId for subId " + subId);
             }
+
+            String[] mergedSubscriberId = ArrayUtils.defeatNullable(
+                    tm.createForSubscriptionId(subId).getMergedSubscriberIdsFromGroup());
+            mergedSubscriberIdsList.add(mergedSubscriberId);
         }
 
         synchronized (mNetworkPoliciesSecondLock) {
@@ -1792,7 +1822,7 @@
                         subIdToSubscriberId.valueAt(i));
             }
 
-            mMergedSubscriberIds = mergedSubscriberIds;
+            mMergedSubscriberIds = mergedSubscriberIdsList;
         }
 
         Trace.traceEnd(TRACE_TAG_NETWORK);
@@ -2869,7 +2899,7 @@
             sendRestrictBackgroundChangedMsg();
             mLogger.restrictBackgroundChanged(oldRestrictBackground, mRestrictBackground);
 
-            if (mRestrictBackgroundPowerState.globalBatterySaverEnabled) {
+            if (mRestrictBackgroundLowPowerMode) {
                 mRestrictBackgroundChangedInBsm = true;
             }
             synchronized (mNetworkPoliciesSecondLock) {
@@ -3345,8 +3375,10 @@
                 fout.decreaseIndent();
 
                 fout.println();
-                fout.println("Merged subscriptions: "
-                        + Arrays.toString(NetworkIdentity.scrubSubscriberId(mMergedSubscriberIds)));
+                for (String[] mergedSubscribers : mMergedSubscriberIds) {
+                    fout.println("Merged subscriptions: " + Arrays.toString(
+                            NetworkIdentity.scrubSubscriberId(mergedSubscribers)));
+                }
 
                 fout.println();
                 fout.println("Policy for UIDs:");
@@ -4874,17 +4906,21 @@
     @GuardedBy("mUidRulesFirstLock")
     @VisibleForTesting
     void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
-        mRestrictBackgroundPowerState = result;
+        if (mRestrictBackgroundLowPowerMode == result.batterySaverEnabled) {
+            // Nothing changed. Nothing to do.
+            return;
+        }
+        mRestrictBackgroundLowPowerMode = result.batterySaverEnabled;
 
-        boolean restrictBackground = result.batterySaverEnabled;
+        boolean restrictBackground = mRestrictBackgroundLowPowerMode;
         boolean shouldInvokeRestrictBackground;
-        // store the temporary mRestrictBackgroundChangedInBsm and update it at last
+        // store the temporary mRestrictBackgroundChangedInBsm and update it at the end.
         boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
 
-        if (result.globalBatterySaverEnabled) {
+        if (mRestrictBackgroundLowPowerMode) {
             // Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
             // turn it on.
-            shouldInvokeRestrictBackground = !mRestrictBackground && result.batterySaverEnabled;
+            shouldInvokeRestrictBackground = !mRestrictBackground;
             mRestrictBackgroundBeforeBsm = mRestrictBackground;
             localRestrictBgChangedInBsm = false;
         } else {
diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java
index 473cc97..3ca1803 100644
--- a/services/core/java/com/android/server/net/NetworkStatsFactory.java
+++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java
@@ -16,6 +16,7 @@
 
 package com.android.server.net;
 
+import static android.net.NetworkStats.INTERFACES_ALL;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkStats.TAG_NONE;
@@ -33,6 +34,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.net.VpnInfo;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ProcFileReader;
 
@@ -66,31 +68,59 @@
     /** Path to {@code /proc/net/xt_qtaguid/stats}. */
     private final File mStatsXtUid;
 
-    private boolean mUseBpfStats;
+    private final boolean mUseBpfStats;
 
     private INetd mNetdService;
 
-    // A persistent Snapshot since device start for eBPF stats
-    @GuardedBy("mPersistSnapshot")
-    private final NetworkStats mPersistSnapshot;
+    /**
+     * Guards persistent data access in this class
+     *
+     * <p>In order to prevent deadlocks, critical sections protected by this lock SHALL NOT call out
+     * to other code that will acquire other locks within the system server. See b/134244752.
+     */
+    private final Object mPersistentDataLock = new Object();
 
-    // TODO: only do adjustments in NetworkStatsService and remove this.
+    /** Set containing info about active VPNs and their underlying networks. */
+    private volatile VpnInfo[] mVpnInfos = new VpnInfo[0];
+
+    // A persistent snapshot of cumulative stats since device start
+    @GuardedBy("mPersistentDataLock")
+    private NetworkStats mPersistSnapshot;
+
+    // The persistent snapshot of tun and 464xlat adjusted stats since device start
+    @GuardedBy("mPersistentDataLock")
+    private NetworkStats mTunAnd464xlatAdjustedStats;
+
     /**
      * (Stacked interface) -> (base interface) association for all connected ifaces since boot.
      *
      * Because counters must never roll backwards, once a given interface is stacked on top of an
      * underlying interface, the stacked interface can never be stacked on top of
      * another interface. */
-    private static final ConcurrentHashMap<String, String> sStackedIfaces
+    private final ConcurrentHashMap<String, String> mStackedIfaces
             = new ConcurrentHashMap<>();
 
-    public static void noteStackedIface(String stackedIface, String baseIface) {
+    /** Informs the factory of a new stacked interface. */
+    public void noteStackedIface(String stackedIface, String baseIface) {
         if (stackedIface != null && baseIface != null) {
-            sStackedIfaces.put(stackedIface, baseIface);
+            mStackedIfaces.put(stackedIface, baseIface);
         }
     }
 
     /**
+     * Set active VPN information for data usage migration purposes
+     *
+     * <p>Traffic on TUN-based VPNs inherently all appear to be originated from the VPN providing
+     * app's UID. This method is used to support migration of VPN data usage, ensuring data is
+     * accurately billed to the real owner of the traffic.
+     *
+     * @param vpnArray The snapshot of the currently-running VPNs.
+     */
+    public void updateVpnInfos(VpnInfo[] vpnArray) {
+        mVpnInfos = vpnArray.clone();
+    }
+
+    /**
      * Get a set of interfaces containing specified ifaces and stacked interfaces.
      *
      * <p>The added stacked interfaces are ifaces stacked on top of the specified ones, or ifaces
@@ -98,7 +128,7 @@
      * {@link #noteStackedIface(String, String)}, but only interfaces noted before this method
      * is called are guaranteed to be included.
      */
-    public static String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
+    public String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
         if (requiredIfaces == NetworkStats.INTERFACES_ALL) {
             return null;
         }
@@ -108,7 +138,7 @@
         // elements as they existed upon construction exactly once, and may
         // (but are not guaranteed to) reflect any modifications subsequent to construction".
         // This is enough here.
-        for (Map.Entry<String, String> entry : sStackedIfaces.entrySet()) {
+        for (Map.Entry<String, String> entry : mStackedIfaces.entrySet()) {
             if (relatedIfaces.contains(entry.getKey())) {
                 relatedIfaces.add(entry.getValue());
             } else if (relatedIfaces.contains(entry.getValue())) {
@@ -124,17 +154,12 @@
      * Applies 464xlat adjustments with ifaces noted with {@link #noteStackedIface(String, String)}.
      * @see NetworkStats#apply464xlatAdjustments(NetworkStats, NetworkStats, Map, boolean)
      */
-    public static void apply464xlatAdjustments(NetworkStats baseTraffic,
+    public void apply464xlatAdjustments(NetworkStats baseTraffic,
             NetworkStats stackedTraffic, boolean useBpfStats) {
-        NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, sStackedIfaces,
+        NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, mStackedIfaces,
                 useBpfStats);
     }
 
-    @VisibleForTesting
-    public static void clearStackedIfaces() {
-        sStackedIfaces.clear();
-    }
-
     public NetworkStatsFactory() {
         this(new File("/proc/"), new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists());
     }
@@ -145,7 +170,10 @@
         mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
         mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
         mUseBpfStats = useBpfStats;
-        mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+        synchronized (mPersistentDataLock) {
+            mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+            mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+        }
     }
 
     public NetworkStats readBpfNetworkStatsDev() throws IOException {
@@ -263,52 +291,44 @@
         return stats;
     }
 
-    /**
-     * @deprecated Use NetworkStatsService#getDetailedUidStats which also accounts for
-     * VPN traffic
-     */
     public NetworkStats readNetworkStatsDetail() throws IOException {
-        return readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
+        return readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
     }
 
-    public NetworkStats readNetworkStatsDetail(int limitUid, String[] limitIfaces, int limitTag,
-            NetworkStats lastStats) throws IOException {
-        final NetworkStats stats =
-              readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats);
-
-        // No locking here: apply464xlatAdjustments behaves fine with an add-only ConcurrentHashMap.
-        // TODO: remove this and only apply adjustments in NetworkStatsService.
-        stats.apply464xlatAdjustments(sStackedIfaces, mUseBpfStats);
-
-        return stats;
-    }
-
-    @GuardedBy("mPersistSnapshot")
+    @GuardedBy("mPersistentDataLock")
     private void requestSwapActiveStatsMapLocked() throws RemoteException {
         // Ask netd to do a active map stats swap. When the binder call successfully returns,
         // the system server should be able to safely read and clean the inactive map
         // without race problem.
-        if (mUseBpfStats) {
-            if (mNetdService == null) {
-                mNetdService = NetdService.getInstance();
-            }
-            mNetdService.trafficSwapActiveStatsMap();
+        if (mNetdService == null) {
+            mNetdService = NetdService.getInstance();
         }
+        mNetdService.trafficSwapActiveStatsMap();
     }
 
-    // TODO: delete the lastStats parameter
-    private NetworkStats readNetworkStatsDetailInternal(int limitUid, String[] limitIfaces,
-            int limitTag, NetworkStats lastStats) throws IOException {
-        if (USE_NATIVE_PARSING) {
-            final NetworkStats stats;
-            if (lastStats != null) {
-                stats = lastStats;
-                stats.setElapsedRealtime(SystemClock.elapsedRealtime());
-            } else {
-                stats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
-            }
-            if (mUseBpfStats) {
-                synchronized (mPersistSnapshot) {
+    /**
+     * Reads the detailed UID stats based on the provided parameters
+     *
+     * @param limitUid the UID to limit this query to
+     * @param limitIfaces the interfaces to limit this query to. Use {@link
+     *     NetworkStats.INTERFACES_ALL} to select all interfaces
+     * @param limitTag the tags to limit this query to
+     * @return the NetworkStats instance containing network statistics at the present time.
+     */
+    public NetworkStats readNetworkStatsDetail(
+            int limitUid, String[] limitIfaces, int limitTag) throws IOException {
+        // In order to prevent deadlocks, anything protected by this lock MUST NOT call out to other
+        // code that will acquire other locks within the system server. See b/134244752.
+        synchronized (mPersistentDataLock) {
+            // Take a reference. If this gets swapped out, we still have the old reference.
+            final VpnInfo[] vpnArray = mVpnInfos;
+            // Take a defensive copy. mPersistSnapshot is mutated in some cases below
+            final NetworkStats prev = mPersistSnapshot.clone();
+
+            if (USE_NATIVE_PARSING) {
+                final NetworkStats stats =
+                        new NetworkStats(SystemClock.elapsedRealtime(), 0 /* initialSize */);
+                if (mUseBpfStats) {
                     try {
                         requestSwapActiveStatsMapLocked();
                     } catch (RemoteException e) {
@@ -317,32 +337,66 @@
                     // Stats are always read from the inactive map, so they must be read after the
                     // swap
                     if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL,
-                            null, TAG_ALL, mUseBpfStats) != 0) {
+                            INTERFACES_ALL, TAG_ALL, mUseBpfStats) != 0) {
                         throw new IOException("Failed to parse network stats");
                     }
+
+                    // BPF stats are incremental; fold into mPersistSnapshot.
                     mPersistSnapshot.setElapsedRealtime(stats.getElapsedRealtime());
                     mPersistSnapshot.combineAllValues(stats);
-                    NetworkStats result = mPersistSnapshot.clone();
-                    result.filter(limitUid, limitIfaces, limitTag);
-                    return result;
+                } else {
+                    if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), UID_ALL,
+                            INTERFACES_ALL, TAG_ALL, mUseBpfStats) != 0) {
+                        throw new IOException("Failed to parse network stats");
+                    }
+                    if (SANITY_CHECK_NATIVE) {
+                        final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid,
+                                UID_ALL, INTERFACES_ALL, TAG_ALL);
+                        assertEquals(javaStats, stats);
+                    }
+
+                    mPersistSnapshot = stats;
                 }
             } else {
-                if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), limitUid,
-                        limitIfaces, limitTag, mUseBpfStats) != 0) {
-                    throw new IOException("Failed to parse network stats");
-                }
-                if (SANITY_CHECK_NATIVE) {
-                    final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid, limitUid,
-                            limitIfaces, limitTag);
-                    assertEquals(javaStats, stats);
-                }
-                return stats;
+                mPersistSnapshot = javaReadNetworkStatsDetail(mStatsXtUid, UID_ALL, INTERFACES_ALL,
+                        TAG_ALL);
             }
-        } else {
-            return javaReadNetworkStatsDetail(mStatsXtUid, limitUid, limitIfaces, limitTag);
+
+            NetworkStats adjustedStats = adjustForTunAnd464Xlat(mPersistSnapshot, prev, vpnArray);
+
+            // Filter return values
+            adjustedStats.filter(limitUid, limitIfaces, limitTag);
+            return adjustedStats;
         }
     }
 
+    @GuardedBy("mPersistentDataLock")
+    private NetworkStats adjustForTunAnd464Xlat(
+            NetworkStats uidDetailStats, NetworkStats previousStats, VpnInfo[] vpnArray) {
+        // Calculate delta from last snapshot
+        final NetworkStats delta = uidDetailStats.subtract(previousStats);
+
+        // Apply 464xlat adjustments before VPN adjustments. If VPNs are using v4 on a v6 only
+        // network, the overhead is their fault.
+        // No locking here: apply464xlatAdjustments behaves fine with an add-only
+        // ConcurrentHashMap.
+        delta.apply464xlatAdjustments(mStackedIfaces, mUseBpfStats);
+
+        // Migrate data usage over a VPN to the TUN network.
+        for (VpnInfo info : vpnArray) {
+            delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
+        }
+
+        // Filter out debug entries as that may lead to over counting.
+        delta.filterDebugEntries();
+
+        // Update mTunAnd464xlatAdjustedStats with migrated delta.
+        mTunAnd464xlatAdjustedStats.combineAllValues(delta);
+        mTunAnd464xlatAdjustedStats.setElapsedRealtime(uidDetailStats.getElapsedRealtime());
+
+        return mTunAnd464xlatAdjustedStats.clone();
+    }
+
     /**
      * Parse and return {@link NetworkStats} with UID-level details. Values are
      * expected to monotonically increase since device boot.
diff --git a/services/core/java/com/android/server/net/NetworkStatsObservers.java b/services/core/java/com/android/server/net/NetworkStatsObservers.java
index d840873..2564dae 100644
--- a/services/core/java/com/android/server/net/NetworkStatsObservers.java
+++ b/services/core/java/com/android/server/net/NetworkStatsObservers.java
@@ -39,7 +39,6 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.VpnInfo;
 
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -104,9 +103,9 @@
     public void updateStats(NetworkStats xtSnapshot, NetworkStats uidSnapshot,
                 ArrayMap<String, NetworkIdentitySet> activeIfaces,
                 ArrayMap<String, NetworkIdentitySet> activeUidIfaces,
-                VpnInfo[] vpnArray, long currentTime) {
+                long currentTime) {
         StatsContext statsContext = new StatsContext(xtSnapshot, uidSnapshot, activeIfaces,
-                activeUidIfaces, vpnArray, currentTime);
+                activeUidIfaces, currentTime);
         getHandler().sendMessage(mHandler.obtainMessage(MSG_UPDATE_STATS, statsContext));
     }
 
@@ -354,7 +353,7 @@
             // thread will update it. We pass a null VPN array because usage is aggregated by uid
             // for this snapshot, so VPN traffic can't be reattributed to responsible apps.
             mRecorder.recordSnapshotLocked(statsContext.mXtSnapshot, statsContext.mActiveIfaces,
-                    null /* vpnArray */, statsContext.mCurrentTime);
+                    statsContext.mCurrentTime);
         }
 
         /**
@@ -396,7 +395,7 @@
             // thread will update it. We pass the VPN info so VPN traffic is reattributed to
             // responsible apps.
             mRecorder.recordSnapshotLocked(statsContext.mUidSnapshot, statsContext.mActiveUidIfaces,
-                    statsContext.mVpnArray, statsContext.mCurrentTime);
+                    statsContext.mCurrentTime);
         }
 
         /**
@@ -427,18 +426,16 @@
         NetworkStats mUidSnapshot;
         ArrayMap<String, NetworkIdentitySet> mActiveIfaces;
         ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces;
-        VpnInfo[] mVpnArray;
         long mCurrentTime;
 
         StatsContext(NetworkStats xtSnapshot, NetworkStats uidSnapshot,
                 ArrayMap<String, NetworkIdentitySet> activeIfaces,
                 ArrayMap<String, NetworkIdentitySet> activeUidIfaces,
-                VpnInfo[] vpnArray, long currentTime) {
+                long currentTime) {
             mXtSnapshot = xtSnapshot;
             mUidSnapshot = uidSnapshot;
             mActiveIfaces = activeIfaces;
             mActiveUidIfaces = activeUidIfaces;
-            mVpnArray = vpnArray;
             mCurrentTime = currentTime;
         }
     }
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index bdff500..06ec341 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -23,7 +23,6 @@
 
 import static com.android.internal.util.Preconditions.checkNotNull;
 
-import android.annotation.Nullable;
 import android.net.NetworkStats;
 import android.net.NetworkStats.NonMonotonicObserver;
 import android.net.NetworkStatsHistory;
@@ -37,7 +36,6 @@
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
-import com.android.internal.net.VpnInfo;
 import com.android.internal.util.FileRotator;
 import com.android.internal.util.IndentingPrintWriter;
 
@@ -202,18 +200,12 @@
     }
 
     /**
-     * Record any delta that occurred since last {@link NetworkStats} snapshot,
-     * using the given {@link Map} to identify network interfaces. First
-     * snapshot is considered bootstrap, and is not counted as delta.
-     *
-     * @param vpnArray Optional info about the currently active VPN, if any. This is used to
-     *                 redistribute traffic from the VPN app to the underlying responsible apps.
-     *                 This should always be set to null if the provided snapshot is aggregated
-     *                 across all UIDs (e.g. contains UID_ALL buckets), regardless of VPN state.
+     * Record any delta that occurred since last {@link NetworkStats} snapshot, using the given
+     * {@link Map} to identify network interfaces. First snapshot is considered bootstrap, and is
+     * not counted as delta.
      */
     public void recordSnapshotLocked(NetworkStats snapshot,
-            Map<String, NetworkIdentitySet> ifaceIdent, @Nullable VpnInfo[] vpnArray,
-            long currentTimeMillis) {
+            Map<String, NetworkIdentitySet> ifaceIdent, long currentTimeMillis) {
         final HashSet<String> unknownIfaces = Sets.newHashSet();
 
         // skip recording when snapshot missing
@@ -232,12 +224,6 @@
         final long end = currentTimeMillis;
         final long start = end - delta.getElapsedRealtime();
 
-        if (vpnArray != null) {
-            for (VpnInfo info : vpnArray) {
-                delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
-            }
-        }
-
         NetworkStats.Entry entry = null;
         for (int i = 0; i < delta.size(); i++) {
             entry = delta.getValues(i, entry);
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index a13368f..41806ca 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -182,6 +182,7 @@
 
     private final Context mContext;
     private final INetworkManagementService mNetworkManager;
+    private final NetworkStatsFactory mStatsFactory;
     private final AlarmManager mAlarmManager;
     private final Clock mClock;
     private final TelephonyManager mTeleManager;
@@ -267,10 +268,6 @@
     @GuardedBy("mStatsLock")
     private Network[] mDefaultNetworks = new Network[0];
 
-    /** Set containing info about active VPNs and their underlying networks. */
-    @GuardedBy("mStatsLock")
-    private VpnInfo[] mVpnInfos = new VpnInfo[0];
-
     private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
             new DropBoxNonMonotonicObserver();
 
@@ -293,22 +290,6 @@
     /** Data layer operation counters for splicing into other structures. */
     private NetworkStats mUidOperations = new NetworkStats(0L, 10);
 
-    /**
-     * Snapshot containing most recent network stats for all UIDs across all interfaces and tags
-     * since boot.
-     *
-     * <p>Maintains migrated VPN stats which are result of performing TUN migration on {@link
-     * #mLastUidDetailSnapshot}.
-     */
-    @GuardedBy("mStatsLock")
-    private NetworkStats mTunAdjustedStats;
-    /**
-     * Used by {@link #mTunAdjustedStats} to migrate VPN traffic over delta between this snapshot
-     * and latest snapshot.
-     */
-    @GuardedBy("mStatsLock")
-    private NetworkStats mLastUidDetailSnapshot;
-
     /** Must be set in factory by calling #setHandler. */
     private Handler mHandler;
     private Handler.Callback mHandlerCallback;
@@ -357,8 +338,8 @@
 
         NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
                 wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
-                new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
-                getDefaultSystemDir(), getDefaultBaseDir());
+                new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
+                new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir());
         service.registerLocalService();
 
         HandlerThread handlerThread = new HandlerThread(TAG);
@@ -375,7 +356,8 @@
     NetworkStatsService(Context context, INetworkManagementService networkManager,
             AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
             TelephonyManager teleManager, NetworkStatsSettings settings,
-            NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
+            NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
+            File baseDir) {
         mContext = checkNotNull(context, "missing Context");
         mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
         mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
@@ -383,6 +365,7 @@
         mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
         mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
         mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
+        mStatsFactory = checkNotNull(factory, "missing factory");
         mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
         mSystemDir = checkNotNull(systemDir, "missing systemDir");
         mBaseDir = checkNotNull(baseDir, "missing baseDir");
@@ -401,14 +384,9 @@
     }
 
     public void systemReady() {
-        mSystemReady = true;
-
-        if (!isBandwidthControlEnabled()) {
-            Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
-            return;
-        }
-
         synchronized (mStatsLock) {
+            mSystemReady = true;
+
             // create data recorders along with historical rotators
             mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
             mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
@@ -454,7 +432,14 @@
             // ignored; service lives in system_server
         }
 
-        registerPollAlarmLocked();
+        //  schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
+        final PendingIntent pollIntent =
+                PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
+
+        final long currentRealtime = SystemClock.elapsedRealtime();
+        mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
+                mSettings.getPollInterval(), pollIntent);
+
         registerGlobalAlert();
     }
 
@@ -515,23 +500,6 @@
     }
 
     /**
-     * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
-     * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
-     */
-    private void registerPollAlarmLocked() {
-        if (mPollIntent != null) {
-            mAlarmManager.cancel(mPollIntent);
-        }
-
-        mPollIntent = PendingIntent.getBroadcast(
-                mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
-
-        final long currentRealtime = SystemClock.elapsedRealtime();
-        mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
-                mSettings.getPollInterval(), mPollIntent);
-    }
-
-    /**
      * Register for a global alert that is delivered through
      * {@link INetworkManagementEventObserver} once a threshold amount of data
      * has been transferred.
@@ -576,8 +544,6 @@
     }
 
     private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
-        assertBandwidthControlEnabled();
-
         final int callingUid = Binder.getCallingUid();
         final int usedFlags = isRateLimitedForPoll(callingUid)
                 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
@@ -770,7 +736,6 @@
 
     private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
         assertSystemReady();
-        assertBandwidthControlEnabled();
 
         // NOTE: if callers want to get non-augmented data, they should go
         // through the public API
@@ -781,7 +746,6 @@
 
     private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
         assertSystemReady();
-        assertBandwidthControlEnabled();
 
         final NetworkStatsCollection uidComplete;
         synchronized (mStatsLock) {
@@ -796,18 +760,10 @@
         if (Binder.getCallingUid() != uid) {
             mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
         }
-        assertBandwidthControlEnabled();
 
         // TODO: switch to data layer stats once kernel exports
         // for now, read network layer stats and flatten across all ifaces
-        final long token = Binder.clearCallingIdentity();
-        final NetworkStats networkLayer;
-        try {
-            networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid,
-                    NetworkStats.INTERFACES_ALL);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
+        final NetworkStats networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
 
         // splice in operation counts
         networkLayer.spliceOperationsFrom(mUidOperations);
@@ -828,39 +784,15 @@
     @Override
     public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
         try {
-            // Get the latest snapshot from NetworkStatsFactory.
-            // TODO: Querying for INTERFACES_ALL may incur performance penalty. Consider restricting
-            // this to limited set of ifaces.
-            NetworkStats uidDetailStats = getNetworkStatsUidDetail(INTERFACES_ALL);
-
-            // Migrate traffic from VPN UID over delta and update mTunAdjustedStats.
-            NetworkStats result;
-            synchronized (mStatsLock) {
-                migrateTunTraffic(uidDetailStats, mVpnInfos);
-                result = mTunAdjustedStats.clone();
-            }
-
-            // Apply filter based on ifacesToQuery.
             final String[] ifacesToQuery =
-                    NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
-            result.filter(UID_ALL, ifacesToQuery, TAG_ALL);
-            return result;
+                    mStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
+            return getNetworkStatsUidDetail(ifacesToQuery);
         } catch (RemoteException e) {
             Log.wtf(TAG, "Error compiling UID stats", e);
             return new NetworkStats(0L, 0);
         }
     }
 
-    @VisibleForTesting
-    NetworkStats getTunAdjustedStats() {
-        synchronized (mStatsLock) {
-            if (mTunAdjustedStats == null) {
-                return null;
-            }
-            return mTunAdjustedStats.clone();
-        }
-    }
-
     @Override
     public String[] getMobileIfaces() {
         return mMobileIfaces;
@@ -904,24 +836,27 @@
     @Override
     public void forceUpdateIfaces(
             Network[] defaultNetworks,
-            VpnInfo[] vpnArray,
             NetworkState[] networkStates,
-            String activeIface) {
+            String activeIface,
+            VpnInfo[] vpnInfos) {
         checkNetworkStackPermission(mContext);
-        assertBandwidthControlEnabled();
 
         final long token = Binder.clearCallingIdentity();
         try {
-            updateIfaces(defaultNetworks, vpnArray, networkStates, activeIface);
+            updateIfaces(defaultNetworks, networkStates, activeIface);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
+
+        // Update the VPN underlying interfaces only after the poll is made and tun data has been
+        // migrated. Otherwise the migration would use the new interfaces instead of the ones that
+        // were current when the polled data was transferred.
+        mStatsFactory.updateVpnInfos(vpnInfos);
     }
 
     @Override
     public void forceUpdate() {
         mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
-        assertBandwidthControlEnabled();
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -932,8 +867,6 @@
     }
 
     private void advisePersistThreshold(long thresholdBytes) {
-        assertBandwidthControlEnabled();
-
         // clamp threshold into safe range
         mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
         if (LOGV) {
@@ -1178,13 +1111,11 @@
 
     private void updateIfaces(
             Network[] defaultNetworks,
-            VpnInfo[] vpnArray,
             NetworkState[] networkStates,
             String activeIface) {
         synchronized (mStatsLock) {
             mWakeLock.acquire();
             try {
-                mVpnInfos = vpnArray;
                 mActiveIface = activeIface;
                 updateIfacesLocked(defaultNetworks, networkStates);
             } finally {
@@ -1194,10 +1125,9 @@
     }
 
     /**
-     * Inspect all current {@link NetworkState} to derive mapping from {@code
-     * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
-     * are active on a single {@code iface}, they are combined under a single
-     * {@link NetworkIdentitySet}.
+     * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link
+     * NetworkStatsHistory}. When multiple {@link NetworkInfo} are active on a single {@code iface},
+     * they are combined under a single {@link NetworkIdentitySet}.
      */
     @GuardedBy("mStatsLock")
     private void updateIfacesLocked(Network[] defaultNetworks, NetworkState[] states) {
@@ -1257,20 +1187,28 @@
                     }
                 }
 
-                // Traffic occurring on stacked interfaces is usually clatd,
-                // which is already accounted against its final egress interface
-                // by the kernel. Thus, we only need to collect stacked
-                // interface stats at the UID level.
+                // Traffic occurring on stacked interfaces is usually clatd.
+                // UID stats are always counted on the stacked interface and never
+                // on the base interface, because the packets on the base interface
+                // do not actually match application sockets until they are translated.
+                //
+                // Interface stats are more complicated. Packets subject to BPF offload
+                // never appear on the base interface and only appear on the stacked
+                // interface, so to ensure those packets increment interface stats, interface
+                // stats from stacked interfaces must be collected.
                 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
                 for (LinkProperties stackedLink : stackedLinks) {
                     final String stackedIface = stackedLink.getInterfaceName();
                     if (stackedIface != null) {
+                        if (mUseBpfTrafficStats) {
+                            findOrCreateNetworkIdentitySet(mActiveIfaces, stackedIface).add(ident);
+                        }
                         findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
                         if (isMobile) {
                             mobileIfaces.add(stackedIface);
                         }
 
-                        NetworkStatsFactory.noteStackedIface(stackedIface, baseIface);
+                        mStatsFactory.noteStackedIface(stackedIface, baseIface);
                     }
                 }
             }
@@ -1300,7 +1238,7 @@
         final NetworkStats xtSnapshot = getNetworkStatsXt();
         Trace.traceEnd(TRACE_TAG_NETWORK);
         Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
-        final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
+        final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
         Trace.traceEnd(TRACE_TAG_NETWORK);
 
         // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
@@ -1314,55 +1252,24 @@
         // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
         // can't be reattributed to responsible apps.
         Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
-        mDevRecorder.recordSnapshotLocked(
-                devSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
+        mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
         Trace.traceEnd(TRACE_TAG_NETWORK);
         Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
-        mXtRecorder.recordSnapshotLocked(
-                xtSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
+        mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
         Trace.traceEnd(TRACE_TAG_NETWORK);
 
         // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
-        VpnInfo[] vpnArray = mVpnInfos;
         Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
-        mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
+        mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
         Trace.traceEnd(TRACE_TAG_NETWORK);
         Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
-        mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
+        mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
         Trace.traceEnd(TRACE_TAG_NETWORK);
 
         // We need to make copies of member fields that are sent to the observer to avoid
         // a race condition between the service handler thread and the observer's
         mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
-                new ArrayMap<>(mActiveUidIfaces), vpnArray, currentTime);
-
-        migrateTunTraffic(uidSnapshot, vpnArray);
-    }
-
-    /**
-     * Updates {@link #mTunAdjustedStats} with the delta containing traffic migrated off of VPNs.
-     */
-    @GuardedBy("mStatsLock")
-    private void migrateTunTraffic(NetworkStats uidDetailStats, VpnInfo[] vpnInfoArray) {
-        if (mTunAdjustedStats == null) {
-            // Either device booted or system server restarted, hence traffic cannot be migrated
-            // correctly without knowing the past state of VPN's underlying networks.
-            mTunAdjustedStats = uidDetailStats;
-            mLastUidDetailSnapshot = uidDetailStats;
-            return;
-        }
-        // Migrate delta traffic from VPN to other apps.
-        NetworkStats delta = uidDetailStats.subtract(mLastUidDetailSnapshot);
-        for (VpnInfo info : vpnInfoArray) {
-            delta.migrateTun(info.ownerUid, info.vpnIface, info.underlyingIfaces);
-        }
-        // Filter out debug entries as that may lead to over counting.
-        delta.filterDebugEntries();
-        // Update #mTunAdjustedStats with migrated delta.
-        mTunAdjustedStats.combineAllValues(delta);
-        mTunAdjustedStats.setElapsedRealtime(uidDetailStats.getElapsedRealtime());
-        // Update last snapshot.
-        mLastUidDetailSnapshot = uidDetailStats;
+                new ArrayMap<>(mActiveUidIfaces), currentTime);
     }
 
     /**
@@ -1725,6 +1632,30 @@
         }
     }
 
+    private NetworkStats readNetworkStatsSummaryDev() {
+        try {
+            return mStatsFactory.readNetworkStatsSummaryDev();
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private NetworkStats readNetworkStatsSummaryXt() {
+        try {
+            return mStatsFactory.readNetworkStatsSummaryXt();
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    private NetworkStats readNetworkStatsUidDetail(int uid, String[] ifaces, int tag) {
+        try {
+            return mStatsFactory.readNetworkStatsDetail(uid, ifaces, tag);
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
     /**
      * Return snapshot of current UID statistics, including any
      * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
@@ -1735,15 +1666,12 @@
      */
     private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
             throws RemoteException {
-
-        // TODO: remove 464xlat adjustments from NetworkStatsFactory and apply all at once here.
-        final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL,
-                ifaces);
+        final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL,  ifaces, TAG_ALL);
 
         // fold tethering stats and operations into uid snapshot
         final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
         tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
-        NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
+        mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
                 mUseBpfTrafficStats);
         uidSnapshot.combineAllValues(tetherSnapshot);
 
@@ -1754,7 +1682,7 @@
         final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
         if (vtStats != null) {
             vtStats.filter(UID_ALL, ifaces, TAG_ALL);
-            NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
+            mStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
                     mUseBpfTrafficStats);
             uidSnapshot.combineAllValues(vtStats);
         }
@@ -1768,7 +1696,7 @@
      * Return snapshot of current XT statistics with video calling data usage statistics.
      */
     private NetworkStats getNetworkStatsXt() throws RemoteException {
-        final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
+        final NetworkStats xtSnapshot = readNetworkStatsSummaryXt();
 
         final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
                 Context.TELEPHONY_SERVICE);
@@ -1828,24 +1756,6 @@
         }
     }
 
-    private void assertBandwidthControlEnabled() {
-        if (!isBandwidthControlEnabled()) {
-            throw new IllegalStateException("Bandwidth module disabled");
-        }
-    }
-
-    private boolean isBandwidthControlEnabled() {
-        final long token = Binder.clearCallingIdentity();
-        try {
-            return mNetworkManager.isBandwidthControlEnabled();
-        } catch (RemoteException e) {
-            // ignored; service lives in system_server
-            return false;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
     private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
         @Override
         public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
diff --git a/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java b/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java
index 766d8ca..3b24f46 100644
--- a/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java
+++ b/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java
@@ -17,8 +17,6 @@
 package com.android.server.net.watchlist;
 
 import android.content.Context;
-import android.content.Intent;
-import android.net.NetworkWatchlistManager;
 import android.os.Binder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -26,7 +24,6 @@
 import android.provider.Settings;
 
 import java.io.FileInputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
 
@@ -74,10 +71,12 @@
         try {
             final String configXmlPath = getNextArgRequired();
             final ParcelFileDescriptor pfd = openFileForSystem(configXmlPath, "r");
-            if (pfd != null) {
-                final InputStream fileStream = new FileInputStream(pfd.getFileDescriptor());
-                WatchlistConfig.getInstance().setTestMode(fileStream);
+            if (pfd == null) {
+                pw.println("Error: can't open input file " + configXmlPath);
+                return -1;
             }
+            final InputStream fileStream = new FileInputStream(pfd.getFileDescriptor());
+            WatchlistConfig.getInstance().setTestMode(fileStream);
             pw.println("Success!");
         } catch (Exception ex) {
             pw.println("Error: " + ex.toString());
diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
index f1476b3..fce10e6 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
@@ -23,6 +23,8 @@
     NotificationChannel getNotificationChannel(String pkg, int uid, String channelId);
     void enqueueNotification(String pkg, String basePkg, int callingUid, int callingPid,
             String tag, int id, Notification notification, int userId);
+    void cancelNotification(String pkg, String basePkg, int callingUid, int callingPid,
+            String tag, int id, int userId);
 
     void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId);
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c4eb661..d30895e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -25,9 +25,12 @@
 import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
 import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED;
+import static android.app.NotificationManager.ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED;
 import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED;
 import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED;
 import static android.app.NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED;
+import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_ID;
+import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_STATUS;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
@@ -42,10 +45,10 @@
 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.content.Context.BIND_ADJUST_BELOW_PERCEPTIBLE;
 import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
 import static android.content.Context.BIND_AUTO_CREATE;
 import static android.content.Context.BIND_FOREGROUND_SERVICE;
+import static android.content.Context.BIND_NOT_PERCEPTIBLE;
 import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_TELEVISION;
@@ -207,6 +210,7 @@
 import android.util.proto.ProtoOutputStream;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
+import android.widget.RemoteViews;
 import android.widget.Toast;
 
 import com.android.internal.R;
@@ -283,7 +287,7 @@
     static final boolean DEBUG_INTERRUPTIVENESS = SystemProperties.getBoolean(
             "debug.notification.interruptiveness", false);
 
-    static final int MAX_PACKAGE_NOTIFICATIONS = 50;
+    static final int MAX_PACKAGE_NOTIFICATIONS = 25;
     static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
 
     // message codes
@@ -397,7 +401,7 @@
 
     // for enabling and disabling notification pulse behavior
     boolean mScreenOn = true;
-    protected boolean mInCall = false;
+    protected boolean mInCallStateOffHook = false;
     boolean mNotificationPulseEnabled;
 
     private Uri mInCallNotificationUri;
@@ -463,6 +467,9 @@
     private boolean mIsAutomotive;
     private boolean mNotificationEffectsEnabledForAutomotive;
 
+    private int mWarnRemoteViewsSizeBytes;
+    private int mStripRemoteViewsSizeBytes;
+
     private MetricsLogger mMetricsLogger;
     private TriPredicate<String, Integer, String> mAllowedManagedServicePackages;
 
@@ -1292,7 +1299,7 @@
                 mScreenOn = false;
                 updateNotificationPulse();
             } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
-                mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK
+                mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK
                         .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
                 updateNotificationPulse();
             } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
@@ -1641,6 +1648,15 @@
                 sendRegisteredOnlyBroadcast(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
                 mRankingHandler.requestSort();
             }
+
+            @Override
+            void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {
+                Intent intent = new Intent(ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED);
+                intent.setPackage(pkg);
+                intent.putExtra(EXTRA_AUTOMATIC_ZEN_RULE_ID, id);
+                intent.putExtra(EXTRA_AUTOMATIC_ZEN_RULE_STATUS, status);
+                getContext().sendBroadcastAsUser(intent, UserHandle.of(userId));
+            }
         });
         mPreferencesHelper = new PreferencesHelper(getContext(),
                 mPackageManagerClient,
@@ -1723,6 +1739,11 @@
 
         mZenModeHelper.setPriorityOnlyDndExemptPackages(getContext().getResources().getStringArray(
                 com.android.internal.R.array.config_priorityOnlyDndExemptPackages));
+
+        mWarnRemoteViewsSizeBytes = getContext().getResources().getInteger(
+                com.android.internal.R.integer.config_notificationWarnRemoteViewSizeBytes);
+        mStripRemoteViewsSizeBytes = getContext().getResources().getInteger(
+                com.android.internal.R.integer.config_notificationStripRemoteViewSizeBytes);
     }
 
     @Override
@@ -2256,7 +2277,7 @@
             final int callingUid = Binder.getCallingUid();
             final boolean isSystemToast = isCallerSystemOrPhone()
                     || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(pkg);
-            final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
+            final boolean isPackageSuspended = isPackagePaused(pkg);
             final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg,
                     callingUid);
 
@@ -2378,16 +2399,10 @@
         }
 
         @Override
-        public void cancelNotificationWithTag(String pkg, String tag, int id, int userId) {
-            checkCallerIsSystemOrSameApp(pkg);
-            userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
-                    Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg);
-            // Don't allow client applications to cancel foreground service notis or autobundled
-            // summaries.
-            final int mustNotHaveFlags = isCallingUidSystem() ? 0 :
-                    (FLAG_FOREGROUND_SERVICE | FLAG_AUTOGROUP_SUMMARY);
-            cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0,
-                    mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null);
+        public void cancelNotificationWithTag(String pkg, String opPkg, String tag, int id,
+                int userId) {
+            cancelNotificationInternal(pkg, opPkg, Binder.getCallingUid(), Binder.getCallingPid(),
+                    tag, id, userId);
         }
 
         @Override
@@ -2405,9 +2420,25 @@
         }
 
         @Override
+        public void silenceNotificationSound() {
+            checkCallerIsSystem();
+
+            mNotificationDelegate.clearEffects();
+        }
+
+        @Override
         public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
             enforceSystemOrSystemUI("setNotificationsEnabledForPackage");
 
+            synchronized (mNotificationLock) {
+                boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid)
+                        != NotificationManager.IMPORTANCE_NONE;
+
+                if (wasEnabled == enabled) {
+                    return;
+                }
+            }
+
             mPreferencesHelper.setEnabled(pkg, uid, enabled);
             mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES)
                     .setType(MetricsEvent.TYPE_ACTION)
@@ -4094,17 +4125,7 @@
             Preconditions.checkNotNull(pkg);
             checkCallerIsSameApp(pkg);
 
-            boolean isPaused;
-
-            final PackageManagerInternal pmi = LocalServices.getService(
-                    PackageManagerInternal.class);
-            int flags = pmi.getDistractingPackageRestrictions(
-                    pkg, Binder.getCallingUserHandle().getIdentifier());
-            isPaused = ((flags & PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) != 0);
-
-            isPaused |= isPackageSuspendedForUser(pkg, Binder.getCallingUid());
-
-            return isPaused;
+            return isPackagePausedOrSuspended(pkg, Binder.getCallingUid());
         }
 
         private void verifyPrivilegedListener(INotificationListener token, UserHandle user,
@@ -4610,6 +4631,12 @@
         }
 
         @Override
+        public void cancelNotification(String pkg, String opPkg, int callingUid, int callingPid,
+                String tag, int id, int userId) {
+            cancelNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, userId);
+        }
+
+        @Override
         public void removeForegroundServiceFlagFromNotification(String pkg, int notificationId,
                 int userId) {
             checkCallerIsSystem();
@@ -4650,6 +4677,37 @@
         }
     };
 
+    void cancelNotificationInternal(String pkg, String opPkg, int callingUid, int callingPid,
+            String tag, int id, int userId) {
+        userId = ActivityManager.handleIncomingUser(callingPid,
+                callingUid, userId, true, false, "cancelNotificationWithTag", pkg);
+
+        // ensure opPkg is delegate if does not match pkg
+        int uid = resolveNotificationUid(opPkg, pkg, callingUid, userId);
+
+        // if opPkg is not the same as pkg, make sure the notification given was posted
+        // by opPkg
+        if (!Objects.equals(pkg, opPkg)) {
+            synchronized (mNotificationLock) {
+                // Look for the notification, searching both the posted and enqueued lists.
+                NotificationRecord r = findNotificationLocked(pkg, tag, id, userId);
+                if (r != null) {
+                    if (!Objects.equals(opPkg, r.sbn.getOpPkg())) {
+                        throw new SecurityException(opPkg + " does not have permission to "
+                                + "cancel a notification they did not post " + tag + " " + id);
+                    }
+                }
+            }
+        }
+
+        // Don't allow client applications to cancel foreground service notis or autobundled
+        // summaries.
+        final int mustNotHaveFlags = isCallingUidSystem() ? 0 :
+                (FLAG_FOREGROUND_SERVICE | FLAG_AUTOGROUP_SUMMARY);
+        cancelNotification(uid, callingPid, pkg, tag, id, 0,
+                mustNotHaveFlags, false, userId, REASON_APP_CANCEL, null);
+    }
+
     void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
             final int callingPid, final String tag, final int id, final Notification notification,
             int incomingUserId) {
@@ -4675,7 +4733,7 @@
 
         // Fix the notification as best we can.
         try {
-            fixNotification(notification, pkg, userId);
+            fixNotification(notification, pkg, tag, id, userId);
 
         } catch (NameNotFoundException e) {
             Slog.e(TAG, "Cannot create a context for sending app", e);
@@ -4780,8 +4838,8 @@
     }
 
     @VisibleForTesting
-    protected void fixNotification(Notification notification, String pkg, int userId)
-            throws NameNotFoundException {
+    protected void fixNotification(Notification notification, String pkg, String tag, int id,
+            int userId) throws NameNotFoundException {
         final ApplicationInfo ai = mPackageManagerClient.getApplicationInfoAsUser(
                 pkg, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                 (userId == UserHandle.USER_ALL) ? USER_SYSTEM : userId);
@@ -4804,6 +4862,50 @@
                         ": Use of fullScreenIntent requires the USE_FULL_SCREEN_INTENT permission");
             }
         }
+
+        // Remote views? Are they too big?
+        checkRemoteViews(pkg, tag, id, notification);
+    }
+
+    private void checkRemoteViews(String pkg, String tag, int id, Notification notification) {
+        if (removeRemoteView(pkg, tag, id, notification.contentView)) {
+            notification.contentView = null;
+        }
+        if (removeRemoteView(pkg, tag, id, notification.bigContentView)) {
+            notification.bigContentView = null;
+        }
+        if (removeRemoteView(pkg, tag, id, notification.headsUpContentView)) {
+            notification.headsUpContentView = null;
+        }
+        if (notification.publicVersion != null) {
+            if (removeRemoteView(pkg, tag, id, notification.publicVersion.contentView)) {
+                notification.publicVersion.contentView = null;
+            }
+            if (removeRemoteView(pkg, tag, id, notification.publicVersion.bigContentView)) {
+                notification.publicVersion.bigContentView = null;
+            }
+            if (removeRemoteView(pkg, tag, id, notification.publicVersion.headsUpContentView)) {
+                notification.publicVersion.headsUpContentView = null;
+            }
+        }
+    }
+
+    private boolean removeRemoteView(String pkg, String tag, int id, RemoteViews contentView) {
+        if (contentView == null) {
+            return false;
+        }
+        final int contentViewSize = contentView.estimateMemoryUsage();
+        if (contentViewSize > mWarnRemoteViewsSizeBytes
+                && contentViewSize < mStripRemoteViewsSizeBytes) {
+            Slog.w(TAG, "RemoteViews too large on tag: " + tag + " id: " + id
+                    + " this might be stripped in a future release");
+        }
+        if (contentViewSize >= mStripRemoteViewsSizeBytes) {
+            mUsageStats.registerImageRemoved(pkg);
+            Slog.w(TAG, "Removed too large RemoteViews on tag: " + tag + " id: " + id);
+            return true;
+        }
+        return false;
     }
 
     /**
@@ -5032,23 +5134,25 @@
             }
         }
 
-        // snoozed apps
-        if (mSnoozeHelper.isSnoozed(userId, pkg, r.getKey())) {
-            MetricsLogger.action(r.getLogMaker()
-                    .setType(MetricsProto.MetricsEvent.TYPE_UPDATE)
-                    .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED));
-            if (DBG) {
-                Slog.d(TAG, "Ignored enqueue for snoozed notification " + r.getKey());
+        synchronized (mNotificationLock) {
+            // snoozed apps
+            if (mSnoozeHelper.isSnoozed(userId, pkg, r.getKey())) {
+                MetricsLogger.action(r.getLogMaker()
+                        .setType(MetricsProto.MetricsEvent.TYPE_UPDATE)
+                        .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED));
+                if (DBG) {
+                    Slog.d(TAG, "Ignored enqueue for snoozed notification " + r.getKey());
+                }
+                mSnoozeHelper.update(userId, r);
+                handleSavePolicyFile();
+                return false;
             }
-            mSnoozeHelper.update(userId, r);
-            handleSavePolicyFile();
-            return false;
-        }
 
 
-        // blocked apps
-        if (isBlocked(r, mUsageStats)) {
-            return false;
+            // blocked apps
+            if (isBlocked(r, mUsageStats)) {
+                return false;
+            }
         }
 
         return true;
@@ -5083,7 +5187,9 @@
 
     protected boolean isBlocked(NotificationRecord r, NotificationUsageStats usageStats) {
         if (isBlocked(r)) {
-            Slog.e(TAG, "Suppressing notification from package by user request.");
+            if (DBG) {
+                Slog.e(TAG, "Suppressing notification from package by user request.");
+            }
             usageStats.registerBlocked(r);
             return true;
         }
@@ -5326,11 +5432,18 @@
     }
 
     @GuardedBy("mNotificationLock")
-    private boolean isPackageSuspendedLocked(NotificationRecord r) {
-        final String pkg = r.sbn.getPackageName();
-        final int callingUid = r.sbn.getUid();
+    boolean isPackagePausedOrSuspended(String pkg, int uid) {
+        boolean isPaused;
 
-        return isPackageSuspendedForUser(pkg, callingUid);
+        final PackageManagerInternal pmi = LocalServices.getService(
+                PackageManagerInternal.class);
+        int flags = pmi.getDistractingPackageRestrictions(
+                pkg, Binder.getCallingUserHandle().getIdentifier());
+        isPaused = ((flags & PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) != 0);
+
+        isPaused |= isPackageSuspendedForUser(pkg, uid);
+
+        return isPaused;
     }
 
     protected class PostNotificationRunnable implements Runnable {
@@ -5363,7 +5476,8 @@
                         return;
                     }
 
-                    final boolean isPackageSuspended = isPackageSuspendedLocked(r);
+                    final boolean isPackageSuspended =
+                            isPackagePausedOrSuspended(r.sbn.getPackageName(), r.getUid());
                     r.setHidden(isPackageSuspended);
                     if (isPackageSuspended) {
                         mUsageStats.registerSuspendedByAdmin(r);
@@ -5710,7 +5824,7 @@
                     }
                     if (DBG) Slog.v(TAG, "Interrupting!");
                     if (hasValidSound) {
-                        if (mInCall) {
+                        if (isInCall()) {
                             playInCallNotification();
                             beep = true;
                         } else {
@@ -5724,7 +5838,7 @@
                     final boolean ringerModeSilent =
                             mAudioManager.getRingerModeInternal()
                                     == AudioManager.RINGER_MODE_SILENT;
-                    if (!mInCall && hasValidVibrate && !ringerModeSilent) {
+                    if (!isInCall() && hasValidVibrate && !ringerModeSilent) {
                         buzz = playVibration(record, vibration, hasValidSound);
                         if(buzz) {
                             mVibrateNotificationKey = key;
@@ -5812,7 +5926,7 @@
             return false;
         }
         // not if in call or the screen's on
-        if (mInCall || mScreenOn) {
+        if (isInCall() || mScreenOn) {
             return false;
         }
 
@@ -6913,7 +7027,7 @@
         }
 
         // Don't flash while we are in a call or screen is on
-        if (ledNotification == null || mInCall || mScreenOn) {
+        if (ledNotification == null || isInCall() || mScreenOn) {
             mNotificationLight.turnOff();
         } else {
             NotificationRecord.Light light = ledNotification.getLight();
@@ -7151,6 +7265,10 @@
             return false;
         }
 
+        if (userId == UserHandle.USER_ALL) {
+            userId = USER_SYSTEM;
+        }
+
         try {
             final String[] pkgs = mPackageManager.getPackagesForUid(callingUid);
             if (pkgs == null) {
@@ -7234,72 +7352,42 @@
     @GuardedBy("mNotificationLock")
     private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
         final int N = mNotificationList.size();
-        ArrayList<String> keys = new ArrayList<String>(N);
-        ArrayList<String> interceptedKeys = new ArrayList<String>(N);
-        ArrayList<Integer> importance = new ArrayList<>(N);
-        Bundle overrideGroupKeys = new Bundle();
-        Bundle visibilityOverrides = new Bundle();
-        Bundle suppressedVisualEffects = new Bundle();
-        Bundle explanation = new Bundle();
-        Bundle channels = new Bundle();
-        Bundle overridePeople = new Bundle();
-        Bundle snoozeCriteria = new Bundle();
-        Bundle showBadge = new Bundle();
-        Bundle userSentiment = new Bundle();
-        Bundle hidden = new Bundle();
-        Bundle systemGeneratedSmartActions = new Bundle();
-        Bundle smartReplies = new Bundle();
-        Bundle lastAudiblyAlerted = new Bundle();
-        Bundle noisy = new Bundle();
-        ArrayList<Boolean> canBubble = new ArrayList<>(N);
+        final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>();
+
         for (int i = 0; i < N; i++) {
             NotificationRecord record = mNotificationList.get(i);
             if (!isVisibleToListener(record.sbn, info)) {
                 continue;
             }
             final String key = record.sbn.getKey();
-            keys.add(key);
-            importance.add(record.getImportance());
-            if (record.getImportanceExplanation() != null) {
-                explanation.putCharSequence(key, record.getImportanceExplanation());
-            }
-            if (record.isIntercepted()) {
-                interceptedKeys.add(key);
+            final NotificationListenerService.Ranking ranking =
+                    new NotificationListenerService.Ranking();
+            ranking.populate(
+                    key,
+                    rankings.size(),
+                    !record.isIntercepted(),
+                    record.getPackageVisibilityOverride(),
+                    record.getSuppressedVisualEffects(),
+                    record.getImportance(),
+                    record.getImportanceExplanation(),
+                    record.sbn.getOverrideGroupKey(),
+                    record.getChannel(),
+                    record.getPeopleOverride(),
+                    record.getSnoozeCriteria(),
+                    record.canShowBadge(),
+                    record.getUserSentiment(),
+                    record.isHidden(),
+                    record.getLastAudiblyAlertedMs(),
+                    record.getSound() != null || record.getVibration() != null,
+                    record.getSystemGeneratedSmartActions(),
+                    record.getSmartReplies(),
+                    record.canBubble()
+            );
+            rankings.add(ranking);
+        }
 
-            }
-            suppressedVisualEffects.putInt(key, record.getSuppressedVisualEffects());
-            if (record.getPackageVisibilityOverride()
-                    != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
-                visibilityOverrides.putInt(key, record.getPackageVisibilityOverride());
-            }
-            overrideGroupKeys.putString(key, record.sbn.getOverrideGroupKey());
-            channels.putParcelable(key, record.getChannel());
-            overridePeople.putStringArrayList(key, record.getPeopleOverride());
-            snoozeCriteria.putParcelableArrayList(key, record.getSnoozeCriteria());
-            showBadge.putBoolean(key, record.canShowBadge());
-            userSentiment.putInt(key, record.getUserSentiment());
-            hidden.putBoolean(key, record.isHidden());
-            systemGeneratedSmartActions.putParcelableArrayList(key,
-                    record.getSystemGeneratedSmartActions());
-            smartReplies.putCharSequenceArrayList(key, record.getSmartReplies());
-            lastAudiblyAlerted.putLong(key, record.getLastAudiblyAlertedMs());
-            noisy.putBoolean(key, record.getSound() != null || record.getVibration() != null);
-            canBubble.add(record.canBubble());
-        }
-        final int M = keys.size();
-        String[] keysAr = keys.toArray(new String[M]);
-        String[] interceptedKeysAr = interceptedKeys.toArray(new String[interceptedKeys.size()]);
-        int[] importanceAr = new int[M];
-        boolean[] canBubbleAr = new boolean[M];
-        for (int i = 0; i < M; i++) {
-            importanceAr[i] = importance.get(i);
-            canBubbleAr[i] = canBubble.get(i);
-        }
-        return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
-                suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys,
-                channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden,
-                systemGeneratedSmartActions, smartReplies, lastAudiblyAlerted, noisy,
-                canBubbleAr);
+        return new NotificationRankingUpdate(
+                rankings.toArray(new NotificationListenerService.Ranking[0]));
     }
 
     boolean hasCompanionDevice(ManagedServiceInfo info) {
@@ -7407,6 +7495,18 @@
         }
     }
 
+    private boolean isInCall() {
+        if (mInCallStateOffHook) {
+            return true;
+        }
+        int audioMode = mAudioManager.getMode();
+        if (audioMode == AudioManager.MODE_IN_CALL
+                || audioMode == AudioManager.MODE_IN_COMMUNICATION) {
+            return true;
+        }
+        return false;
+    }
+
     public class NotificationAssistants extends ManagedServices {
         static final String TAG_ENABLED_NOTIFICATION_ASSISTANTS = "enabled_assistants";
 
@@ -7816,12 +7916,12 @@
 
         @Override
         protected int getBindFlags() {
-            // Most of the same flags as the base, but also add BIND_ADJUST_BELOW_PERCEPTIBLE
+            // Most of the same flags as the base, but also add BIND_NOT_PERCEPTIBLE
             // because too many 3P apps could be kept in memory as notification listeners and
             // cause extreme memory pressure.
             // TODO: Change the binding lifecycle of NotificationListeners to avoid this situation.
             return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE
-                    | BIND_ADJUST_BELOW_PERCEPTIBLE | BIND_ALLOW_WHITELIST_MANAGEMENT;
+                    | BIND_NOT_PERCEPTIBLE | BIND_ALLOW_WHITELIST_MANAGEMENT;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index c2e559a..a126073 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -34,11 +34,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
-import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.drawable.Icon;
 import android.media.AudioAttributes;
 import android.media.AudioSystem;
 import android.metrics.LogMaker;
@@ -453,16 +450,11 @@
 
     void dump(PrintWriter pw, String prefix, Context baseContext, boolean redact) {
         final Notification notification = sbn.getNotification();
-        final Icon icon = notification.getSmallIcon();
-        String iconStr = String.valueOf(icon);
-        if (icon != null && icon.getType() == Icon.TYPE_RESOURCE) {
-            iconStr += " / " + idDebugString(baseContext, icon.getResPackage(), icon.getResId());
-        }
         pw.println(prefix + this);
         prefix = prefix + "  ";
         pw.println(prefix + "uid=" + sbn.getUid() + " userId=" + sbn.getUserId());
         pw.println(prefix + "opPkg=" + sbn.getOpPkg());
-        pw.println(prefix + "icon=" + iconStr);
+        pw.println(prefix + "icon=" + notification.getSmallIcon());
         pw.println(prefix + "flags=0x" + Integer.toHexString(notification.flags));
         pw.println(prefix + "pri=" + notification.priority);
         pw.println(prefix + "key=" + sbn.getKey());
@@ -592,37 +584,15 @@
         pw.println(prefix + "mAdjustments=" + mAdjustments);
     }
 
-
-    static String idDebugString(Context baseContext, String packageName, int id) {
-        Context c;
-
-        if (packageName != null) {
-            try {
-                c = baseContext.createPackageContext(packageName, 0);
-            } catch (NameNotFoundException e) {
-                c = baseContext;
-            }
-        } else {
-            c = baseContext;
-        }
-
-        Resources r = c.getResources();
-        try {
-            return r.getResourceName(id);
-        } catch (Resources.NotFoundException e) {
-            return "<name unknown>";
-        }
-    }
-
     @Override
     public final String toString() {
         return String.format(
                 "NotificationRecord(0x%08x: pkg=%s user=%s id=%d tag=%s importance=%d key=%s" +
-                        "appImportanceLocked=%s: %s)",
+                        ": %s)",
                 System.identityHashCode(this),
                 this.sbn.getPackageName(), this.sbn.getUser(), this.sbn.getId(),
                 this.sbn.getTag(), this.mImportance, this.sbn.getKey(),
-                mIsAppImportanceLocked, this.sbn.getNotification());
+                this.sbn.getNotification());
     }
 
     public boolean hasAdjustment(String key) {
diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java
index dd0f420..979015d 100644
--- a/services/core/java/com/android/server/notification/NotificationShellCmd.java
+++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java
@@ -16,6 +16,12 @@
 
 package com.android.server.notification;
 
+import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_UNKNOWN;
+
 import android.app.ActivityManager;
 import android.app.INotificationManager;
 import android.app.Notification;
@@ -33,12 +39,15 @@
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ShellCommand;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Slog;
 
+import com.android.internal.util.FunctionalUtils;
+
 import java.io.PrintWriter;
 import java.net.URISyntaxException;
 import java.util.Collections;
@@ -47,13 +56,13 @@
  * Implementation of `cmd notification` in NotificationManagerService.
  */
 public class NotificationShellCmd extends ShellCommand {
-    private static final String USAGE =
-              "usage: cmd notification SUBCMD [args]\n\n"
+    private static final String USAGE = "usage: cmd notification SUBCMD [args]\n\n"
             + "SUBCMDs:\n"
             + "  allow_listener COMPONENT [user_id (current user if not specified)]\n"
             + "  disallow_listener COMPONENT [user_id (current user if not specified)]\n"
             + "  allow_assistant COMPONENT [user_id (current user if not specified)]\n"
             + "  remove_assistant COMPONENT [user_id (current user if not specified)]\n"
+            + "  set_dnd [on|none (same as on)|priority|alarms|all|off (same as all)]"
             + "  allow_dnd PACKAGE [user_id (current user if not specified)]\n"
             + "  disallow_dnd PACKAGE [user_id (current user if not specified)]\n"
             + "  suspend_package PACKAGE\n"
@@ -90,7 +99,7 @@
             + "  <args> are as described in `am start`";
 
     public static final int NOTIFICATION_ID = 1138;
-    public static final String NOTIFICATION_PACKAGE = "com.android.shell";
+    public static final String NOTIFICATION_PACKAGE = "android";
     public static final String CHANNEL_ID = "shellcmd";
     public static final String CHANNEL_NAME = "Shell command";
     public static final int CHANNEL_IMP = NotificationManager.IMPORTANCE_DEFAULT;
@@ -111,6 +120,29 @@
         final PrintWriter pw = getOutPrintWriter();
         try {
             switch (cmd.replace('-', '_')) {
+                case "set_dnd": {
+                    String mode = getNextArgRequired();
+                    int interruptionFilter = INTERRUPTION_FILTER_UNKNOWN;
+                    switch(mode) {
+                        case "none":
+                        case "on":
+                            interruptionFilter = INTERRUPTION_FILTER_NONE;
+                            break;
+                        case "priority":
+                            interruptionFilter = INTERRUPTION_FILTER_PRIORITY;
+                            break;
+                        case "alarms":
+                            interruptionFilter = INTERRUPTION_FILTER_ALARMS;
+                            break;
+                        case "all":
+                        case "off":
+                            interruptionFilter = INTERRUPTION_FILTER_ALL;
+                    }
+                    final int filter = interruptionFilter;
+                    Binder.withCleanCallingIdentity(() -> mBinderService.setInterruptionFilter(
+                            mDirectService.getContext().getPackageName(), filter));
+                }
+                break;
                 case "allow_dnd": {
                     String packageName = getNextArgRequired();
                     int userId = ActivityManager.getCurrentUser();
@@ -239,7 +271,7 @@
     }
 
     void ensureChannel() throws RemoteException {
-        final int uid = Binder.getCallingUid();
+        final int uid = Process.myUid();
         final int userid = UserHandle.getCallingUserId();
         final long token = Binder.clearCallingIdentity();
         try {
@@ -491,7 +523,7 @@
         final long token = Binder.clearCallingIdentity();
         try {
             mBinderService.enqueueNotificationWithTag(
-                    NOTIFICATION_PACKAGE, "android",
+                    NOTIFICATION_PACKAGE, NOTIFICATION_PACKAGE,
                     tag, NOTIFICATION_ID,
                     n, userId);
         } finally {
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index dd393b8..fe3d0eb 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -41,7 +41,6 @@
 import org.json.JSONObject;
 
 import java.io.PrintWriter;
-import java.lang.Math;
 import java.util.ArrayDeque;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
@@ -263,6 +262,17 @@
         }
     }
 
+    /**
+     * Call this when RemoteViews object has been removed from a notification because the images
+     * it contains are too big (even after rescaling).
+     */
+    public synchronized void registerImageRemoved(String packageName) {
+        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(packageName);
+        for (AggregatedStats stats : aggregatedStatsArray) {
+            stats.numImagesRemoved++;
+        }
+    }
+
     // Locked by this.
     private AggregatedStats[] getAggregatedStatsLocked(NotificationRecord record) {
         return getAggregatedStatsLocked(record.sbn.getPackageName());
@@ -405,6 +415,7 @@
         public int numAlertViolations;
         public int numQuotaViolations;
         public long mLastAccessTime;
+        public int numImagesRemoved;
 
         public AggregatedStats(Context context, String key) {
             this.key = key;
@@ -529,6 +540,7 @@
             maybeCount("note_over_rate", (numRateViolations - previous.numRateViolations));
             maybeCount("note_over_alert_rate", (numAlertViolations - previous.numAlertViolations));
             maybeCount("note_over_quota", (numQuotaViolations - previous.numQuotaViolations));
+            maybeCount("note_images_removed", (numImagesRemoved - previous.numImagesRemoved));
             noisyImportance.maybeCount(previous.noisyImportance);
             quietImportance.maybeCount(previous.quietImportance);
             finalImportance.maybeCount(previous.finalImportance);
@@ -562,6 +574,7 @@
             previous.numRateViolations = numRateViolations;
             previous.numAlertViolations = numAlertViolations;
             previous.numQuotaViolations = numQuotaViolations;
+            previous.numImagesRemoved = numImagesRemoved;
             noisyImportance.update(previous.noisyImportance);
             quietImportance.update(previous.quietImportance);
             finalImportance.update(previous.finalImportance);
@@ -667,6 +680,8 @@
             output.append("numAlertViolations=").append(numAlertViolations).append("\n");
             output.append(indentPlusTwo);
             output.append("numQuotaViolations=").append(numQuotaViolations).append("\n");
+            output.append(indentPlusTwo);
+            output.append("numImagesRemoved=").append(numImagesRemoved).append("\n");
             output.append(indentPlusTwo).append(noisyImportance.toString()).append("\n");
             output.append(indentPlusTwo).append(quietImportance.toString()).append("\n");
             output.append(indentPlusTwo).append(finalImportance.toString()).append("\n");
@@ -709,6 +724,7 @@
             maybePut(dump, "numQuotaLViolations", numQuotaViolations);
             maybePut(dump, "notificationEnqueueRate", getEnqueueRate());
             maybePut(dump, "numAlertViolations", numAlertViolations);
+            maybePut(dump, "numImagesRemoved", numImagesRemoved);
             noisyImportance.maybePut(dump, previous.noisyImportance);
             quietImportance.maybePut(dump, previous.quietImportance);
             finalImportance.maybePut(dump, previous.finalImportance);
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 1c0ac16..92ac1d4 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -17,6 +17,7 @@
 package com.android.server.notification;
 
 import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -78,7 +79,7 @@
     private static final String TAG_CHANNEL = "channel";
     private static final String TAG_GROUP = "channelGroup";
     private static final String TAG_DELEGATE = "delegate";
-    private static final String TAG_STATUS_ICONS = "status_icons";
+    private static final String TAG_STATUS_ICONS = "silent_status_icons";
 
     private static final String ATT_VERSION = "version";
     private static final String ATT_NAME = "name";
@@ -686,6 +687,11 @@
                     }
                 }
 
+                if (existing.getOriginalImportance() == IMPORTANCE_UNSPECIFIED) {
+                    existing.setOriginalImportance(channel.getImportance());
+                    needsPolicyFileChange = true;
+                }
+
                 updateConfig();
                 return needsPolicyFileChange;
             }
@@ -719,7 +725,7 @@
             if (!r.showBadge) {
                 channel.setShowBadge(false);
             }
-
+            channel.setOriginalImportance(channel.getImportance());
             r.channels.put(channel.getId(), channel);
             if (channel.canBypassDnd() != mAreChannelsBypassingDnd) {
                 updateChannelsBypassingDnd(mContext.getUserId());
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index f81015d..ee948b2 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -16,6 +16,10 @@
 
 package com.android.server.notification;
 
+import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_DISABLED;
+import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_ENABLED;
+import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_REMOVED;
+
 import android.app.AppOpsManager;
 import android.app.AutomaticZenRule;
 import android.app.Notification;
@@ -351,6 +355,12 @@
                             "Cannot update rules not owned by your condition provider");
                 }
             }
+            if (rule.enabled != automaticZenRule.isEnabled()) {
+                dispatchOnAutomaticRuleStatusChanged(mConfig.user, rule.pkg, ruleId,
+                        automaticZenRule.isEnabled()
+                                ? AUTOMATIC_RULE_STATUS_ENABLED : AUTOMATIC_RULE_STATUS_DISABLED);
+            }
+
             populateZenRule(automaticZenRule, rule, false);
             return setConfigLocked(newConfig, reason, rule.component, true);
         }
@@ -370,6 +380,8 @@
                 throw new SecurityException(
                         "Cannot delete rules not owned by your condition provider");
             }
+            dispatchOnAutomaticRuleStatusChanged(
+                    mConfig.user, rule.pkg, id, AUTOMATIC_RULE_STATUS_REMOVED);
             return setConfigLocked(newConfig, reason, null, true);
         }
     }
@@ -1120,6 +1132,13 @@
         }
     }
 
+    private void dispatchOnAutomaticRuleStatusChanged(int userId, String pkg, String id,
+            int status) {
+        for (Callback callback : mCallbacks) {
+            callback.onAutomaticRuleStatusChanged(userId, pkg, id, status);
+        }
+    }
+
     private ZenModeConfig readDefaultConfig(Resources resources) {
         XmlResourceParser parser = null;
         try {
@@ -1509,5 +1528,6 @@
         void onZenModeChanged() {}
         void onPolicyChanged() {}
         void onConsolidatedPolicyChanged() {}
+        void onAutomaticRuleStatusChanged(int userId, String pkg, String id, int status) {}
     }
 }
diff --git a/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java b/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
index a1c27d6..2474b2aa 100644
--- a/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
+++ b/services/core/java/com/android/server/oemlock/PersistentDataBlockLock.java
@@ -73,6 +73,10 @@
         // unlocked but doesn't actually do any unlocking.
         final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
                 mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        if (pdbm == null) {
+            Slog.w(TAG, "PersistentDataBlock is not supported on this device");
+            return;
+        }
         pdbm.setOemUnlockEnabled(allowedByDevice);
     }
 
@@ -80,6 +84,10 @@
     boolean isOemUnlockAllowedByDevice() {
         final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
             mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        if (pdbm == null) {
+            Slog.w(TAG, "PersistentDataBlock is not supported on this device");
+            return false;
+        }
         return pdbm.getOemUnlockEnabled();
     }
 
@@ -91,6 +99,10 @@
     private void disallowUnlockIfNotUnlocked() {
         final PersistentDataBlockManager pdbm = (PersistentDataBlockManager)
             mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
+        if (pdbm == null) {
+            Slog.w(TAG, "PersistentDataBlock is not supported on this device");
+            return;
+        }
         if (pdbm.getFlashLockState() != PersistentDataBlockManager.FLASH_LOCK_UNLOCKED) {
             pdbm.setOemUnlockEnabled(false);
         }
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 4b435de..1f20968 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -58,9 +58,16 @@
 
     private static final boolean VENDOR_IS_Q_OR_LATER;
     static {
-        // STOPSHIP(b/119390857): Check api version once Q sdk version is finalized
-        final String value = SystemProperties.get("ro.vndk.version", "Q");
-        VENDOR_IS_Q_OR_LATER = value.equals("Q") || value.equals("q");
+        final String value = SystemProperties.get("ro.vndk.version", "29");
+        boolean isQOrLater;
+        try {
+            isQOrLater = Integer.parseInt(value) >= 29;
+        } catch (NumberFormatException e) {
+            // The version is not a number, therefore it is a development codename.
+            isQOrLater = true;
+        }
+
+        VENDOR_IS_Q_OR_LATER = isQOrLater;
     }
 
     IdmapManager(final Installer installer, final PackageManagerHelper packageManager) {
@@ -230,14 +237,9 @@
             return fulfilledPolicies | IIdmap2.POLICY_OEM_PARTITION;
         }
 
-        // Check partitions for which there exists no policy so overlays on these partitions will
-        // not fulfill the system policy.
-        if (ai.isProductServices()) {
-            return fulfilledPolicies;
-        }
-
+        // System_ext partition (/system_ext) is considered as system
         // Check this last since every partition except for data is scanned as system in the PMS.
-        if (ai.isSystemApp()) {
+        if (ai.isSystemApp() || ai.isSystemExt()) {
             return fulfilledPolicies | IIdmap2.POLICY_SYSTEM_PARTITION;
         }
 
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index df18923..dd099b1 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -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.s
+ * limitations under the License.
  */
 
 package com.android.server.pm;
@@ -29,14 +29,12 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.PackageParserException;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.ServiceManager.ServiceNotFoundException;
 import android.sysprop.ApexProperties;
-import android.util.ArrayMap;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
@@ -56,117 +54,33 @@
  * ApexManager class handles communications with the apex service to perform operation and queries,
  * as well as providing caching to avoid unnecessary calls to the service.
  */
-class ApexManager {
-    static final String TAG = "ApexManager";
-    private final IApexService mApexService;
-    private final Context mContext;
-    private final Object mLock = new Object();
-    /**
-     * A map from {@code APEX packageName} to the {@Link PackageInfo} generated from the {@code
-     * AndroidManifest.xml}
-     *
-     * <p>Note that key of this map is {@code packageName} field of the corresponding {@code
-     * AndroidManifest.xml}.
-      */
-    @GuardedBy("mLock")
-    private List<PackageInfo> mAllPackagesCache;
-    /**
-     * A map from {@code apexName} to the {@Link PackageInfo} generated from the {@code
-     * AndroidManifest.xml}.
-     *
-     * <p>Note that key of this map is {@code apexName} field which corresponds to the {@code name}
-     * field of {@code apex_manifest.json}.
-     */
-    // TODO(b/132324953): remove.
-    @GuardedBy("mLock")
-    private ArrayMap<String, PackageInfo> mApexNameToPackageInfoCache;
+abstract class ApexManager {
 
-
-    ApexManager(Context context) {
-        mContext = context;
-        if (!isApexSupported()) {
-            mApexService = null;
-            return;
-        }
-        try {
-            mApexService = IApexService.Stub.asInterface(
-                ServiceManager.getServiceOrThrow("apexservice"));
-        } catch (ServiceNotFoundException e) {
-            throw new IllegalStateException("Required service apexservice not available");
-        }
-    }
+    private static final String TAG = "ApexManager";
 
     static final int MATCH_ACTIVE_PACKAGE = 1 << 0;
     static final int MATCH_FACTORY_PACKAGE = 1 << 1;
-    @IntDef(
-            flag = true,
-            prefix = { "MATCH_"},
-            value = {MATCH_ACTIVE_PACKAGE, MATCH_FACTORY_PACKAGE})
-    @Retention(RetentionPolicy.SOURCE)
-    @interface PackageInfoFlags{}
 
-    void systemReady() {
-        if (!isApexSupported()) return;
-        mContext.registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                onBootCompleted();
-                mContext.unregisterReceiver(this);
-            }
-        }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
-    }
-
-    private void populateAllPackagesCacheIfNeeded() {
-        synchronized (mLock) {
-            if (mAllPackagesCache != null) {
-                return;
-            }
-            mApexNameToPackageInfoCache = new ArrayMap<>();
+    /**
+     * Returns an instance of either {@link ApexManagerImpl} or {@link ApexManagerNoOp} depending
+     * on whenever this device supports APEX, i.e. {@link ApexProperties#updatable()} evaluates to
+     * {@code true}.
+     */
+    static ApexManager create(Context systemContext) {
+        if (ApexProperties.updatable().orElse(false)) {
             try {
-                mAllPackagesCache = new ArrayList<>();
-                HashSet<String> activePackagesSet = new HashSet<>();
-                HashSet<String> factoryPackagesSet = new HashSet<>();
-                final ApexInfo[] allPkgs = mApexService.getAllPackages();
-                for (ApexInfo ai : allPkgs) {
-                    // If the device is using flattened APEX, don't report any APEX
-                    // packages since they won't be managed or updated by PackageManager.
-                    if ((new File(ai.packagePath)).isDirectory()) {
-                        break;
-                    }
-                    try {
-                        final PackageInfo pkg = PackageParser.generatePackageInfoFromApex(
-                                ai, PackageManager.GET_META_DATA
-                                        | PackageManager.GET_SIGNING_CERTIFICATES);
-                        mAllPackagesCache.add(pkg);
-                        if (ai.isActive) {
-                            if (activePackagesSet.contains(pkg.packageName)) {
-                                throw new IllegalStateException(
-                                        "Two active packages have the same name: "
-                                                + pkg.packageName);
-                            }
-                            activePackagesSet.add(ai.packageName);
-                            // TODO(b/132324953): remove.
-                            mApexNameToPackageInfoCache.put(ai.packageName, pkg);
-                        }
-                        if (ai.isFactory) {
-                            if (factoryPackagesSet.contains(pkg.packageName)) {
-                                throw new IllegalStateException(
-                                        "Two factory packages have the same name: "
-                                                + pkg.packageName);
-                            }
-                            factoryPackagesSet.add(ai.packageName);
-                        }
-                    } catch (PackageParserException pe) {
-                        throw new IllegalStateException("Unable to parse: " + ai, pe);
-                    }
-                }
-            } catch (RemoteException re) {
-                Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
-                throw new RuntimeException(re);
+                return new ApexManagerImpl(systemContext, IApexService.Stub.asInterface(
+                        ServiceManager.getServiceOrThrow("apexservice")));
+            } catch (ServiceManager.ServiceNotFoundException e) {
+                throw new IllegalStateException("Required service apexservice not available");
             }
+        } else {
+            return new ApexManagerNoOp();
         }
     }
 
+    abstract void systemReady();
+
     /**
      * Retrieves information about an APEX package.
      *
@@ -179,35 +93,8 @@
      * @return a PackageInfo object with the information about the package, or null if the package
      *         is not found.
      */
-    @Nullable PackageInfo getPackageInfo(String packageName, @PackageInfoFlags int flags) {
-        if (!isApexSupported()) return null;
-        populateAllPackagesCacheIfNeeded();
-        boolean matchActive = (flags & MATCH_ACTIVE_PACKAGE) != 0;
-        boolean matchFactory = (flags & MATCH_FACTORY_PACKAGE) != 0;
-        for (PackageInfo packageInfo: mAllPackagesCache) {
-            if (!packageInfo.packageName.equals(packageName)) {
-                continue;
-            }
-            if ((!matchActive || isActive(packageInfo))
-                    && (!matchFactory || isFactory(packageInfo))) {
-                return packageInfo;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns a {@link PackageInfo} for an active APEX package keyed by it's {@code apexName}.
-     *
-     * @deprecated this API will soon be deleted, please don't depend on it.
-     */
-    // TODO(b/132324953): delete.
-    @Deprecated
-    @Nullable PackageInfo getPackageInfoForApexName(String apexName) {
-        if (!isApexSupported()) return null;
-        populateAllPackagesCacheIfNeeded();
-        return mApexNameToPackageInfoCache.get(apexName);
-    }
+    @Nullable
+    abstract PackageInfo getPackageInfo(String packageName, @PackageInfoFlags int flags);
 
     /**
      * Retrieves information about all active APEX packages.
@@ -215,14 +102,7 @@
      * @return a List of PackageInfo object, each one containing information about a different
      *         active package.
      */
-    List<PackageInfo> getActivePackages() {
-        if (!isApexSupported()) return Collections.emptyList();
-        populateAllPackagesCacheIfNeeded();
-        return mAllPackagesCache
-                .stream()
-                .filter(item -> isActive(item))
-                .collect(Collectors.toList());
-    }
+    abstract List<PackageInfo> getActivePackages();
 
     /**
      * Retrieves information about all active pre-installed APEX packages.
@@ -230,14 +110,7 @@
      * @return a List of PackageInfo object, each one containing information about a different
      *         active pre-installed package.
      */
-    List<PackageInfo> getFactoryPackages() {
-        if (!isApexSupported()) return Collections.emptyList();
-        populateAllPackagesCacheIfNeeded();
-        return mAllPackagesCache
-                .stream()
-                .filter(item -> isFactory(item))
-                .collect(Collectors.toList());
-    }
+    abstract List<PackageInfo> getFactoryPackages();
 
     /**
      * Retrieves information about all inactive APEX packages.
@@ -245,14 +118,7 @@
      * @return a List of PackageInfo object, each one containing information about a different
      *         inactive package.
      */
-    List<PackageInfo> getInactivePackages() {
-        if (!isApexSupported()) return Collections.emptyList();
-        populateAllPackagesCacheIfNeeded();
-        return mAllPackagesCache
-                .stream()
-                .filter(item -> !isActive(item))
-                .collect(Collectors.toList());
-    }
+    abstract List<PackageInfo> getInactivePackages();
 
     /**
      * Checks if {@code packageName} is an apex package.
@@ -260,16 +126,7 @@
      * @param packageName package to check.
      * @return {@code true} if {@code packageName} is an apex package.
      */
-    boolean isApexPackage(String packageName) {
-        if (!isApexSupported()) return false;
-        populateAllPackagesCacheIfNeeded();
-        for (PackageInfo packageInfo : mAllPackagesCache) {
-            if (packageInfo.packageName.equals(packageName)) {
-                return true;
-            }
-        }
-        return false;
-    }
+    abstract boolean isApexPackage(String packageName);
 
     /**
      * Retrieves information about an apexd staged session i.e. the internal state used by apexd to
@@ -278,19 +135,8 @@
      * @param sessionId the identifier of the session.
      * @return an ApexSessionInfo object, or null if the session is not known.
      */
-    @Nullable ApexSessionInfo getStagedSessionInfo(int sessionId) {
-        if (!isApexSupported()) return null;
-        try {
-            ApexSessionInfo apexSessionInfo = mApexService.getStagedSessionInfo(sessionId);
-            if (apexSessionInfo.isUnknown) {
-                return null;
-            }
-            return apexSessionInfo;
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to contact apexservice", re);
-            throw new RuntimeException(re);
-        }
-    }
+    @Nullable
+    abstract ApexSessionInfo getStagedSessionInfo(int sessionId);
 
     /**
      * Submit a staged session to apex service. This causes the apex service to perform some initial
@@ -302,39 +148,19 @@
      * @param childSessionIds if {@code sessionId} is a multi-package session, this should contain
      *                        an array of identifiers of all the child sessions. Otherwise it should
      *                        be an empty array.
-     * @param apexInfoList this is an output parameter, which needs to be initialized by tha caller
-     *                     and will be filled with a list of {@link ApexInfo} objects, each of which
-     *                     contains metadata about one of the packages being submitted as part of
-     *                     the session.
-     * @return whether the submission of the session was successful.
+     * @throws PackageManagerException if call to apexd fails
      */
-    boolean submitStagedSession(
-            int sessionId, @NonNull int[] childSessionIds, @NonNull ApexInfoList apexInfoList) {
-        if (!isApexSupported()) return false;
-        try {
-            return mApexService.submitStagedSession(sessionId, childSessionIds, apexInfoList);
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to contact apexservice", re);
-            throw new RuntimeException(re);
-        }
-    }
+    abstract ApexInfoList submitStagedSession(int sessionId, @NonNull int[] childSessionIds)
+            throws PackageManagerException;
 
     /**
      * Mark a staged session previously submitted using {@code submitStagedSession} as ready to be
      * applied at next reboot.
      *
      * @param sessionId the identifier of the {@link PackageInstallerSession} being marked as ready.
-     * @return true upon success, false if the session is unknown.
+     * @throws PackageManagerException if call to apexd fails
      */
-    boolean markStagedSessionReady(int sessionId) {
-        if (!isApexSupported()) return false;
-        try {
-            return mApexService.markStagedSessionReady(sessionId);
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to contact apexservice", re);
-            throw new RuntimeException(re);
-        }
-    }
+    abstract void markStagedSessionReady(int sessionId) throws PackageManagerException;
 
     /**
      * Marks a staged session as successful.
@@ -344,44 +170,21 @@
      * @param sessionId the identifier of the {@link PackageInstallerSession} being marked as
      *                  successful.
      */
-    void markStagedSessionSuccessful(int sessionId) {
-        if (!isApexSupported()) return;
-        try {
-            mApexService.markStagedSessionSuccessful(sessionId);
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to contact apexservice", re);
-            throw new RuntimeException(re);
-        } catch (Exception e) {
-            // It is fine to just log an exception in this case. APEXd will be able to recover in
-            // case markStagedSessionSuccessful fails.
-            Slog.e(TAG, "Failed to mark session " + sessionId + " as successful", e);
-        }
-    }
+    abstract void markStagedSessionSuccessful(int sessionId);
 
     /**
      * Whether the current device supports the management of APEX packages.
      *
      * @return true if APEX packages can be managed on this device, false otherwise.
      */
-    boolean isApexSupported() {
-        return ApexProperties.updatable().orElse(false);
-    }
+    abstract boolean isApexSupported();
 
     /**
      * Abandons the (only) active session previously submitted.
      *
      * @return {@code true} upon success, {@code false} if any remote exception occurs
      */
-    boolean abortActiveSession() {
-        if (!isApexSupported()) return false;
-        try {
-            mApexService.abortActiveSession();
-            return true;
-        } catch (RemoteException re) {
-            Slog.e(TAG, "Unable to contact apexservice", re);
-            return false;
-        }
-    }
+    abstract boolean abortActiveSession();
 
     /**
      * Uninstalls given {@code apexPackage}.
@@ -391,64 +194,7 @@
      * @param apexPackagePath package to uninstall.
      * @return {@code true} upon successful uninstall, {@code false} otherwise.
      */
-    boolean uninstallApex(String apexPackagePath) {
-        if (!isApexSupported()) return false;
-        try {
-            mApexService.unstagePackages(Collections.singletonList(apexPackagePath));
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * Whether an APEX package is active or not.
-     *
-     * @param packageInfo the package to check
-     * @return {@code true} if this package is active, {@code false} otherwise.
-     */
-    private static boolean isActive(PackageInfo packageInfo) {
-        return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
-    }
-
-    /**
-     * Whether the APEX package is pre-installed or not.
-     *
-     * @param packageInfo the package to check
-     * @return {@code true} if this package is pre-installed, {@code false} otherwise.
-     */
-    private static boolean isFactory(PackageInfo packageInfo) {
-        return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
-    }
-
-    /**
-     * Dump information about the packages contained in a particular cache
-     * @param packagesCache the cache to print information about.
-     * @param packageName a {@link String} containing a package name, or {@code null}. If set, only
-     *                    information about that specific package will be dumped.
-     * @param ipw the {@link IndentingPrintWriter} object to send information to.
-     */
-    void dumpFromPackagesCache(
-            List<PackageInfo> packagesCache,
-            @Nullable String packageName,
-            IndentingPrintWriter ipw) {
-        ipw.println();
-        ipw.increaseIndent();
-        for (PackageInfo pi : packagesCache) {
-            if (packageName != null && !packageName.equals(pi.packageName)) {
-                continue;
-            }
-            ipw.println(pi.packageName);
-            ipw.increaseIndent();
-            ipw.println("Version: " + pi.versionCode);
-            ipw.println("Path: " + pi.applicationInfo.sourceDir);
-            ipw.println("IsActive: " + isActive(pi));
-            ipw.println("IsFactory: " + isFactory(pi));
-            ipw.decreaseIndent();
-        }
-        ipw.decreaseIndent();
-        ipw.println();
-    }
+    abstract boolean uninstallApex(String apexPackagePath);
 
     /**
      * Dumps various state information to the provided {@link PrintWriter} object.
@@ -457,54 +203,410 @@
      * @param packageName a {@link String} containing a package name, or {@code null}. If set, only
      *                    information about that specific package will be dumped.
      */
-    void dump(PrintWriter pw, @Nullable String packageName) {
-        if (!isApexSupported()) return;
-        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
-        try {
-            populateAllPackagesCacheIfNeeded();
-            ipw.println();
-            ipw.println("Active APEX packages:");
-            dumpFromPackagesCache(getActivePackages(), packageName, ipw);
-            ipw.println("Inactive APEX packages:");
-            dumpFromPackagesCache(getInactivePackages(), packageName, ipw);
-            ipw.println("Factory APEX packages:");
-            dumpFromPackagesCache(getFactoryPackages(), packageName, ipw);
-            ipw.increaseIndent();
-            ipw.println("APEX session state:");
-            ipw.increaseIndent();
-            final ApexSessionInfo[] sessions = mApexService.getSessions();
-            for (ApexSessionInfo si : sessions) {
-                ipw.println("Session ID: " + si.sessionId);
-                ipw.increaseIndent();
-                if (si.isUnknown) {
-                    ipw.println("State: UNKNOWN");
-                } else if (si.isVerified) {
-                    ipw.println("State: VERIFIED");
-                } else if (si.isStaged) {
-                    ipw.println("State: STAGED");
-                } else if (si.isActivated) {
-                    ipw.println("State: ACTIVATED");
-                } else if (si.isActivationFailed) {
-                    ipw.println("State: ACTIVATION FAILED");
-                } else if (si.isSuccess) {
-                    ipw.println("State: SUCCESS");
-                } else if (si.isRollbackInProgress) {
-                    ipw.println("State: ROLLBACK IN PROGRESS");
-                } else if (si.isRolledBack) {
-                    ipw.println("State: ROLLED BACK");
-                } else if (si.isRollbackFailed) {
-                    ipw.println("State: ROLLBACK FAILED");
+    abstract void dump(PrintWriter pw, @Nullable String packageName);
+
+    @IntDef(
+            flag = true,
+            prefix = { "MATCH_"},
+            value = {MATCH_ACTIVE_PACKAGE, MATCH_FACTORY_PACKAGE})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface PackageInfoFlags{}
+
+    /**
+     * An implementation of {@link ApexManager} that should be used in case device supports updating
+     * APEX packages.
+     */
+    private static class ApexManagerImpl extends ApexManager {
+        private final IApexService mApexService;
+        private final Context mContext;
+        private final Object mLock = new Object();
+        /**
+         * A map from {@code APEX packageName} to the {@Link PackageInfo} generated from the {@code
+         * AndroidManifest.xml}
+         *
+         * <p>Note that key of this map is {@code packageName} field of the corresponding {@code
+         * AndroidManifest.xml}.
+          */
+        @GuardedBy("mLock")
+        private List<PackageInfo> mAllPackagesCache;
+
+        ApexManagerImpl(Context context, IApexService apexService) {
+            mContext = context;
+            mApexService = apexService;
+        }
+
+        /**
+         * Whether an APEX package is active or not.
+         *
+         * @param packageInfo the package to check
+         * @return {@code true} if this package is active, {@code false} otherwise.
+         */
+        private static boolean isActive(PackageInfo packageInfo) {
+            return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
+        }
+
+        /**
+         * Whether the APEX package is pre-installed or not.
+         *
+         * @param packageInfo the package to check
+         * @return {@code true} if this package is pre-installed, {@code false} otherwise.
+         */
+        private static boolean isFactory(PackageInfo packageInfo) {
+            return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+        }
+
+        @Override
+        void systemReady() {
+            mContext.registerReceiver(new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    populateAllPackagesCacheIfNeeded();
+                    mContext.unregisterReceiver(this);
                 }
+            }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
+        }
+
+        private void populateAllPackagesCacheIfNeeded() {
+            synchronized (mLock) {
+                if (mAllPackagesCache != null) {
+                    return;
+                }
+                try {
+                    mAllPackagesCache = new ArrayList<>();
+                    HashSet<String> activePackagesSet = new HashSet<>();
+                    HashSet<String> factoryPackagesSet = new HashSet<>();
+                    final ApexInfo[] allPkgs = mApexService.getAllPackages();
+                    for (ApexInfo ai : allPkgs) {
+                        // If the device is using flattened APEX, don't report any APEX
+                        // packages since they won't be managed or updated by PackageManager.
+                        if ((new File(ai.modulePath)).isDirectory()) {
+                            break;
+                        }
+                        try {
+                            final PackageInfo pkg = PackageParser.generatePackageInfoFromApex(
+                                    ai, PackageManager.GET_META_DATA
+                                            | PackageManager.GET_SIGNING_CERTIFICATES);
+                            mAllPackagesCache.add(pkg);
+                            if (ai.isActive) {
+                                if (activePackagesSet.contains(pkg.packageName)) {
+                                    throw new IllegalStateException(
+                                            "Two active packages have the same name: "
+                                                    + pkg.packageName);
+                                }
+                                activePackagesSet.add(pkg.packageName);
+                            }
+                            if (ai.isFactory) {
+                                if (factoryPackagesSet.contains(pkg.packageName)) {
+                                    throw new IllegalStateException(
+                                            "Two factory packages have the same name: "
+                                                    + pkg.packageName);
+                                }
+                                factoryPackagesSet.add(pkg.packageName);
+                            }
+                        } catch (PackageParser.PackageParserException pe) {
+                            throw new IllegalStateException("Unable to parse: " + ai, pe);
+                        }
+                    }
+                } catch (RemoteException re) {
+                    Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
+                    throw new RuntimeException(re);
+                }
+            }
+        }
+
+        @Override
+        @Nullable PackageInfo getPackageInfo(String packageName, @PackageInfoFlags int flags) {
+            populateAllPackagesCacheIfNeeded();
+            boolean matchActive = (flags & MATCH_ACTIVE_PACKAGE) != 0;
+            boolean matchFactory = (flags & MATCH_FACTORY_PACKAGE) != 0;
+            for (PackageInfo packageInfo: mAllPackagesCache) {
+                if (!packageInfo.packageName.equals(packageName)) {
+                    continue;
+                }
+                if ((!matchActive || isActive(packageInfo))
+                        && (!matchFactory || isFactory(packageInfo))) {
+                    return packageInfo;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        List<PackageInfo> getActivePackages() {
+            populateAllPackagesCacheIfNeeded();
+            return mAllPackagesCache
+                    .stream()
+                    .filter(item -> isActive(item))
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        List<PackageInfo> getFactoryPackages() {
+            populateAllPackagesCacheIfNeeded();
+            return mAllPackagesCache
+                    .stream()
+                    .filter(item -> isFactory(item))
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        List<PackageInfo> getInactivePackages() {
+            populateAllPackagesCacheIfNeeded();
+            return mAllPackagesCache
+                    .stream()
+                    .filter(item -> !isActive(item))
+                    .collect(Collectors.toList());
+        }
+
+        @Override
+        boolean isApexPackage(String packageName) {
+            if (!isApexSupported()) return false;
+            populateAllPackagesCacheIfNeeded();
+            for (PackageInfo packageInfo : mAllPackagesCache) {
+                if (packageInfo.packageName.equals(packageName)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        @Nullable ApexSessionInfo getStagedSessionInfo(int sessionId) {
+            try {
+                ApexSessionInfo apexSessionInfo = mApexService.getStagedSessionInfo(sessionId);
+                if (apexSessionInfo.isUnknown) {
+                    return null;
+                }
+                return apexSessionInfo;
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Unable to contact apexservice", re);
+                throw new RuntimeException(re);
+            }
+        }
+
+        @Override
+        ApexInfoList submitStagedSession(int sessionId, @NonNull int[] childSessionIds)
+                throws PackageManagerException {
+            try {
+                final ApexInfoList apexInfoList = new ApexInfoList();
+                mApexService.submitStagedSession(sessionId, childSessionIds, apexInfoList);
+                return apexInfoList;
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Unable to contact apexservice", re);
+                throw new RuntimeException(re);
+            } catch (Exception e) {
+                throw new PackageManagerException(
+                        PackageInstaller.SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                        "apexd verification failed : " + e.getMessage());
+            }
+        }
+
+        @Override
+        void markStagedSessionReady(int sessionId) throws PackageManagerException {
+            try {
+                mApexService.markStagedSessionReady(sessionId);
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Unable to contact apexservice", re);
+                throw new RuntimeException(re);
+            } catch (Exception e) {
+                throw new PackageManagerException(
+                        PackageInstaller.SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                        "Failed to mark apexd session as ready : " + e.getMessage());
+            }
+        }
+
+        @Override
+        void markStagedSessionSuccessful(int sessionId) {
+            try {
+                mApexService.markStagedSessionSuccessful(sessionId);
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Unable to contact apexservice", re);
+                throw new RuntimeException(re);
+            } catch (Exception e) {
+                // It is fine to just log an exception in this case. APEXd will be able to recover
+                // in case markStagedSessionSuccessful fails.
+                Slog.e(TAG, "Failed to mark session " + sessionId + " as successful", e);
+            }
+        }
+
+        @Override
+        boolean isApexSupported() {
+            return true;
+        }
+
+        @Override
+        boolean abortActiveSession() {
+            try {
+                mApexService.abortActiveSession();
+                return true;
+            } catch (RemoteException re) {
+                Slog.e(TAG, "Unable to contact apexservice", re);
+                return false;
+            }
+        }
+
+        @Override
+        boolean uninstallApex(String apexPackagePath) {
+            try {
+                mApexService.unstagePackages(Collections.singletonList(apexPackagePath));
+                return true;
+            } catch (Exception e) {
+                return false;
+            }
+        }
+
+        /**
+         * Dump information about the packages contained in a particular cache
+         * @param packagesCache the cache to print information about.
+         * @param packageName a {@link String} containing a package name, or {@code null}. If set,
+         *                    only information about that specific package will be dumped.
+         * @param ipw the {@link IndentingPrintWriter} object to send information to.
+         */
+        void dumpFromPackagesCache(
+                List<PackageInfo> packagesCache,
+                @Nullable String packageName,
+                IndentingPrintWriter ipw) {
+            ipw.println();
+            ipw.increaseIndent();
+            for (PackageInfo pi : packagesCache) {
+                if (packageName != null && !packageName.equals(pi.packageName)) {
+                    continue;
+                }
+                ipw.println(pi.packageName);
+                ipw.increaseIndent();
+                ipw.println("Version: " + pi.versionCode);
+                ipw.println("Path: " + pi.applicationInfo.sourceDir);
+                ipw.println("IsActive: " + isActive(pi));
+                ipw.println("IsFactory: " + isFactory(pi));
                 ipw.decreaseIndent();
             }
             ipw.decreaseIndent();
-        } catch (RemoteException e) {
-            ipw.println("Couldn't communicate with apexd.");
+            ipw.println();
+        }
+
+        @Override
+        void dump(PrintWriter pw, @Nullable String packageName) {
+            final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
+            try {
+                populateAllPackagesCacheIfNeeded();
+                ipw.println();
+                ipw.println("Active APEX packages:");
+                dumpFromPackagesCache(getActivePackages(), packageName, ipw);
+                ipw.println("Inactive APEX packages:");
+                dumpFromPackagesCache(getInactivePackages(), packageName, ipw);
+                ipw.println("Factory APEX packages:");
+                dumpFromPackagesCache(getFactoryPackages(), packageName, ipw);
+                ipw.increaseIndent();
+                ipw.println("APEX session state:");
+                ipw.increaseIndent();
+                final ApexSessionInfo[] sessions = mApexService.getSessions();
+                for (ApexSessionInfo si : sessions) {
+                    ipw.println("Session ID: " + si.sessionId);
+                    ipw.increaseIndent();
+                    if (si.isUnknown) {
+                        ipw.println("State: UNKNOWN");
+                    } else if (si.isVerified) {
+                        ipw.println("State: VERIFIED");
+                    } else if (si.isStaged) {
+                        ipw.println("State: STAGED");
+                    } else if (si.isActivated) {
+                        ipw.println("State: ACTIVATED");
+                    } else if (si.isActivationFailed) {
+                        ipw.println("State: ACTIVATION FAILED");
+                    } else if (si.isSuccess) {
+                        ipw.println("State: SUCCESS");
+                    } else if (si.isRollbackInProgress) {
+                        ipw.println("State: ROLLBACK IN PROGRESS");
+                    } else if (si.isRolledBack) {
+                        ipw.println("State: ROLLED BACK");
+                    } else if (si.isRollbackFailed) {
+                        ipw.println("State: ROLLBACK FAILED");
+                    }
+                    ipw.decreaseIndent();
+                }
+                ipw.decreaseIndent();
+            } catch (RemoteException e) {
+                ipw.println("Couldn't communicate with apexd.");
+            }
         }
     }
 
-    public void onBootCompleted() {
-        if (!isApexSupported()) return;
-        populateAllPackagesCacheIfNeeded();
+    /**
+     * An implementation of {@link ApexManager} that should be used in case device does not support
+     * updating APEX packages.
+     */
+    private static final class ApexManagerNoOp extends ApexManager {
+
+        @Override
+        void systemReady() {
+            // No-op
+        }
+
+        @Override
+        PackageInfo getPackageInfo(String packageName, int flags) {
+            return null;
+        }
+
+        @Override
+        List<PackageInfo> getActivePackages() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        List<PackageInfo> getFactoryPackages() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        List<PackageInfo> getInactivePackages() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        boolean isApexPackage(String packageName) {
+            return false;
+        }
+
+        @Override
+        ApexSessionInfo getStagedSessionInfo(int sessionId) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        ApexInfoList submitStagedSession(int sessionId, int[] childSessionIds)
+                throws PackageManagerException {
+            throw new PackageManagerException(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
+                    "Device doesn't support updating APEX");
+        }
+
+        @Override
+        void markStagedSessionReady(int sessionId) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        void markStagedSessionSuccessful(int sessionId) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        boolean isApexSupported() {
+            return false;
+        }
+
+        @Override
+        boolean abortActiveSession() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        boolean uninstallApex(String apexPackagePath) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        void dump(PrintWriter pw, String packageName) {
+            // No-op
+        }
     }
 }
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index ad9ac12..2b33ace 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -254,9 +254,16 @@
             @Override
             public void run() {
                 int result = idleOptimization(pm, pkgs, BackgroundDexOptService.this);
-                if (result != OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
+                if (result == OPTIMIZE_PROCESSED) {
+                    Log.i(TAG, "Idle optimizations completed.");
+                } else if (result == OPTIMIZE_ABORT_NO_SPACE_LEFT) {
                     Log.w(TAG, "Idle optimizations aborted because of space constraints.");
-                    // If we didn't abort we ran to completion (or stopped because of space).
+                } else if (result == OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
+                    Log.w(TAG, "Idle optimizations aborted by job scheduler.");
+                } else {
+                    Log.w(TAG, "Idle optimizations ended with unexpected code: " + result);
+                }
+                if (result != OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
                     // Abandon our timeslice and do not reschedule.
                     jobFinished(jobParams, /* reschedule */ false);
                 }
@@ -339,6 +346,7 @@
             long lowStorageThreshold, boolean isForPrimaryDex) {
         ArraySet<String> updatedPackages = new ArraySet<>();
         Set<String> unusedPackages = pm.getUnusedPackages(mDowngradeUnusedAppsThresholdInMillis);
+        boolean hadSomeLowSpaceFailure = false;
         Log.d(TAG, "Unsused Packages " +  String.join(",", unusedPackages));
         // Only downgrade apps when space is low on device.
         // Threshold is selected above the lowStorageThreshold so that we can pro-actively clean
@@ -359,6 +367,7 @@
             } else {
                 if (abort_code == OPTIMIZE_ABORT_NO_SPACE_LEFT) {
                     // can't dexopt because of low space.
+                    hadSomeLowSpaceFailure = true;
                     continue;
                 }
                 dex_opt_performed = optimizePackage(pm, pkg, isForPrimaryDex);
@@ -369,7 +378,7 @@
         }
 
         notifyPinService(updatedPackages);
-        return OPTIMIZE_PROCESSED;
+        return hadSomeLowSpaceFailure ? OPTIMIZE_ABORT_NO_SPACE_LEFT : OPTIMIZE_PROCESSED;
     }
 
 
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index c2d5b2f8..b3b0029 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -85,6 +85,9 @@
     public static final int FLAG_USE_QUOTA = IInstalld.FLAG_USE_QUOTA;
     public static final int FLAG_FORCE = IInstalld.FLAG_FORCE;
 
+    public static final int FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES =
+            IInstalld.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
+
     private final boolean mIsolated;
 
     private volatile IInstalld mInstalld;
@@ -121,24 +124,6 @@
         }
     }
 
-    @Override
-    public void onUnlockUser(int userId) {
-        if (userId == 0) {
-            if (!checkBeforeRemote()) return;
-
-            if (mInstalld == null) {
-                Slog.wtf(TAG, "Call to onUnlockUser prior to onStart.");
-                return;
-            }
-
-            try {
-                mInstalld.migrateLegacyObbData();
-            } catch (RemoteException re) {
-                Slog.wtf(TAG, "Error migrating legacy OBB data.", re);
-            }
-        }
-    }
-
     private void connect() {
         IBinder binder = ServiceManager.getService("installd");
         if (binder != null) {
@@ -708,6 +693,24 @@
         }
     }
 
+    /**
+     * Migrates obb data from its legacy location {@code /data/media/obb} to
+     * {@code /data/media/0/Android/obb}. This call is idempotent and a fast no-op if data has
+     * already been migrated.
+     *
+     * @throws InstallerException if an error occurs.
+     */
+    public boolean migrateLegacyObbData() throws InstallerException {
+        if (!checkBeforeRemote()) return false;
+
+        try {
+            mInstalld.migrateLegacyObbData();
+            return true;
+        } catch (Exception e) {
+            throw InstallerException.from(e);
+        }
+    }
+
     private static void assertValidInstructionSet(String instructionSet)
             throws InstallerException {
         for (String abi : Build.SUPPORTED_ABIS) {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 9094e1b..e5a2e77 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -376,12 +376,12 @@
                 continue;
             }
 
-            // If the path is in /system, /vendor, /product or /product_services, ignore. It will
+            // If the path is in /system, /vendor, /product or /system_ext, ignore. It will
             // have been ota-dexopted into /data/ota and moved into the dalvik-cache already.
             if (pkg.codePath.startsWith("/system")
                     || pkg.codePath.startsWith("/vendor")
                     || pkg.codePath.startsWith("/product")
-                    || pkg.codePath.startsWith("/product_services")) {
+                    || pkg.codePath.startsWith("/system_ext")) {
                 continue;
             }
 
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 6594751..4f7c8c8 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -47,12 +47,10 @@
 import android.content.pm.dex.DexMetadataHelper;
 import android.os.FileUtils;
 import android.os.PowerManager;
-import android.os.Process;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.WorkSource;
-import android.os.storage.StorageManager;
 import android.util.Log;
 import android.util.Slog;
 
@@ -269,10 +267,7 @@
             return DEX_OPT_SKIPPED;
         }
 
-        // TODO(calin): there's no need to try to create the oat dir over and over again,
-        //              especially since it involve an extra installd call. We should create
-        //              if (if supported) on the fly during the dexopt call.
-        String oatDir = createOatDirIfSupported(pkg, isa);
+        String oatDir = getPackageOatDirIfSupported(pkg);
 
         Log.i(TAG, "Running dexopt (dexoptNeeded=" + dexoptNeeded + ") on: " + path
                 + " pkg=" + pkg.applicationInfo.packageName + " isa=" + isa
@@ -638,7 +633,7 @@
     }
 
     /**
-     * Creates oat dir for the specified package if needed and supported.
+     * Gets oat dir for the specified package if needed and supported.
      * In certain cases oat directory
      * <strong>cannot</strong> be created:
      * <ul>
@@ -646,29 +641,19 @@
      *      <li>Package location is not a directory, i.e. monolithic install.</li>
      * </ul>
      *
-     * @return Absolute path to the oat directory or null, if oat directory
-     * cannot be created.
+     * @return Absolute path to the oat directory or null, if oat directories
+     * not needed or unsupported for the package.
      */
     @Nullable
-    private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet) {
+    private String getPackageOatDirIfSupported(PackageParser.Package pkg) {
         if (!pkg.canHaveOatDir()) {
             return null;
         }
         File codePath = new File(pkg.codePath);
-        if (codePath.isDirectory()) {
-            // TODO(calin): why do we create this only if the codePath is a directory? (i.e for
-            //              cluster packages). It seems that the logic for the folder creation is
-            //              split between installd and here.
-            File oatDir = getOatDir(codePath);
-            try {
-                mInstaller.createOatDir(oatDir.getAbsolutePath(), dexInstructionSet);
-            } catch (InstallerException e) {
-                Slog.w(TAG, "Failed to create oat dir", e);
-                return null;
-            }
-            return oatDir.getAbsolutePath();
+        if (!codePath.isDirectory()) {
+            return null;
         }
-        return null;
+        return getOatDir(codePath).getAbsolutePath();
     }
 
     static File getOatDir(File codePath) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index bd88594..0032e9a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -617,7 +617,9 @@
             mStagingManager.createSession(session);
         }
 
-        mCallbacks.notifySessionCreated(session.sessionId, session.userId);
+        if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+            mCallbacks.notifySessionCreated(session.sessionId, session.userId);
+        }
         writeSessionsAsync();
         return sessionId;
     }
@@ -1210,16 +1212,25 @@
 
     class InternalCallback {
         public void onSessionBadgingChanged(PackageInstallerSession session) {
-            mCallbacks.notifySessionBadgingChanged(session.sessionId, session.userId);
+            if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+                mCallbacks.notifySessionBadgingChanged(session.sessionId, session.userId);
+            }
+
             writeSessionsAsync();
         }
 
         public void onSessionActiveChanged(PackageInstallerSession session, boolean active) {
-            mCallbacks.notifySessionActiveChanged(session.sessionId, session.userId, active);
+            if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+                mCallbacks.notifySessionActiveChanged(session.sessionId, session.userId,
+                        active);
+            }
         }
 
         public void onSessionProgressChanged(PackageInstallerSession session, float progress) {
-            mCallbacks.notifySessionProgressChanged(session.sessionId, session.userId, progress);
+            if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+                mCallbacks.notifySessionProgressChanged(session.sessionId, session.userId,
+                        progress);
+            }
         }
 
         public void onStagedSessionChanged(PackageInstallerSession session) {
@@ -1232,7 +1243,9 @@
         }
 
         public void onSessionFinished(final PackageInstallerSession session, boolean success) {
-            mCallbacks.notifySessionFinished(session.sessionId, session.userId, success);
+            if ((session.params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
+                mCallbacks.notifySessionFinished(session.sessionId, session.userId, success);
+            }
 
             mInstallHandler.post(new Runnable() {
                 @Override
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 6f9a918..4eddb930 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -23,6 +23,7 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SPLIT;
+import static android.content.pm.PackageParser.APEX_FILE_EXTENSION;
 import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
 import static android.system.OsConstants.O_CREAT;
 import static android.system.OsConstants.O_RDONLY;
@@ -1484,7 +1485,29 @@
                     "Too many files for apex install");
         }
 
-        mResolvedBaseFile = addedFiles[0];
+        try {
+            resolveStageDirLocked();
+        } catch (IOException e) {
+            throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
+                    "Failed to resolve stage location", e);
+        }
+
+        File addedFile = addedFiles[0]; // there is only one file
+
+        // Ensure file name has proper suffix
+        final String sourceName = addedFile.getName();
+        final String targetName = sourceName.endsWith(APEX_FILE_EXTENSION)
+                ? sourceName
+                : sourceName + APEX_FILE_EXTENSION;
+        if (!FileUtils.isValidExtFilename(targetName)) {
+            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+                    "Invalid filename: " + targetName);
+        }
+
+        final File targetFile = new File(mResolvedStageDir, targetName);
+        resolveAndStageFile(addedFile, targetFile);
+
+        mResolvedBaseFile = targetFile;
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 07ad1cb..c72b38a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -37,11 +37,11 @@
 import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
 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;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
@@ -90,6 +90,7 @@
 import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
 import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
 import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
+import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
 
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
@@ -111,9 +112,6 @@
 import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
 import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
 import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
-import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
-import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
-import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
 
 import android.Manifest;
 import android.annotation.IntDef;
@@ -147,7 +145,6 @@
 import android.content.pm.FallbackCategoryProvider;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IDexModuleRegisterCallback;
-import android.content.pm.IOnPermissionsChangeListener;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.IPackageDeleteObserver2;
@@ -171,9 +168,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
 import android.content.pm.PackageManager.ModuleInfoFlags;
-import android.content.pm.PackageManager.PermissionWhitelistFlags;
 import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageManagerInternal.CheckPermissionDelegate;
 import android.content.pm.PackageManagerInternal.PackageListObserver;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.ActivityIntentInfo;
@@ -241,6 +236,7 @@
 import android.os.storage.StorageManagerInternal;
 import android.os.storage.VolumeInfo;
 import android.os.storage.VolumeRecord;
+import android.permission.IPermissionManager;
 import android.provider.DeviceConfig;
 import android.provider.MediaStore;
 import android.provider.Settings.Global;
@@ -315,13 +311,12 @@
 import com.android.server.pm.dex.PackageDexUsage;
 import com.android.server.pm.dex.ViewCompiler;
 import com.android.server.pm.permission.BasePermission;
-import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
 import com.android.server.pm.permission.PermissionManagerService;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
-import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
 import com.android.server.pm.permission.PermissionsState;
 import com.android.server.security.VerityUtils;
 import com.android.server.storage.DeviceStorageMonitorInternal;
+import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import dalvik.system.CloseGuard;
@@ -476,7 +471,7 @@
     static final int SCAN_AS_OEM = 1 << 19;
     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_SYSTEM_EXT = 1 << 22;
     static final int SCAN_AS_ODM = 1 << 23;
 
     @IntDef(flag = true, prefix = { "SCAN_" }, value = {
@@ -580,12 +575,6 @@
 
     public static final String PLATFORM_PACKAGE_NAME = "android";
 
-    private static final String KILL_APP_REASON_GIDS_CHANGED =
-            "permission grant or revoke changed gids";
-
-    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
-            "permissions revoked";
-
     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
 
     private static final String PACKAGE_SCHEME = "package";
@@ -594,7 +583,7 @@
 
     private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
 
-    private static final String PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
+    private static final String SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
 
     private static final String ODM_OVERLAY_DIR = "/odm/overlay";
 
@@ -915,8 +904,6 @@
     private AtomicInteger mNextMoveId = new AtomicInteger();
     private final MoveCallbacks mMoveCallbacks;
 
-    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
-
     // Cache of users who need badging.
     private final SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
 
@@ -960,9 +947,10 @@
     final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
             = new SparseArray<>();
 
-    // TODO remove this and go through mPermissonManager directly
-    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
+    // Internal interface for permission manager
     private final PermissionManagerServiceInternal mPermissionManager;
+    // Public interface for permission manager
+    private final IPermissionManager mPermissionManagerService;
 
     private final ComponentResolver mComponentResolver;
     // List of packages names to keep cached, even if they are uninstalled for all users
@@ -1001,18 +989,6 @@
         void receiveVerificationResponse(int verificationId);
     }
 
-    @GuardedBy("mPackages")
-    private CheckPermissionDelegate mCheckPermissionDelegate;
-
-    @GuardedBy("mPackages")
-    private PackageManagerInternal.DefaultBrowserProvider mDefaultBrowserProvider;
-
-    @GuardedBy("mPackages")
-    private PackageManagerInternal.DefaultDialerProvider mDefaultDialerProvider;
-
-    @GuardedBy("mPackages")
-    private PackageManagerInternal.DefaultHomeProvider mDefaultHomeProvider;
-
     private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
         private Context mContext;
         private ComponentName mIntentFilterVerifierComponent;
@@ -1507,7 +1483,8 @@
                         final List<String> whitelistedRestrictedPermissions = ((args.installFlags
                                 & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0
                                     && parentRes.pkg != null)
-                                ? parentRes.pkg.requestedPermissions : null;
+                                ? parentRes.pkg.requestedPermissions
+                                : args.whitelistedRestrictedPermissions;
 
                         // Handle the parent package
                         handlePackagePostInstall(parentRes, grantPermissions,
@@ -1762,66 +1739,6 @@
         }
     }
 
-    private PermissionCallback mPermissionCallback = new PermissionCallback() {
-        @Override
-        public void onGidsChanged(int appId, int userId) {
-            mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
-        }
-        @Override
-        public void onPermissionGranted(int uid, int userId) {
-            mOnPermissionChangeListeners.onPermissionsChanged(uid);
-
-            // Not critical; if this is lost, the application has to request again.
-            synchronized (mPackages) {
-                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
-            }
-        }
-        @Override
-        public void onInstallPermissionGranted() {
-            synchronized (mPackages) {
-                scheduleWriteSettingsLocked();
-            }
-        }
-        @Override
-        public void onPermissionRevoked(int uid, int userId) {
-            mOnPermissionChangeListeners.onPermissionsChanged(uid);
-
-            synchronized (mPackages) {
-                // Critical; after this call the application should never have the permission
-                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
-            }
-
-            final int appId = UserHandle.getAppId(uid);
-            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
-        }
-        @Override
-        public void onInstallPermissionRevoked() {
-            synchronized (mPackages) {
-                scheduleWriteSettingsLocked();
-            }
-        }
-        @Override
-        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
-            synchronized (mPackages) {
-                for (int userId : updatedUserIds) {
-                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
-                }
-            }
-        }
-        @Override
-        public void onInstallPermissionUpdated() {
-            synchronized (mPackages) {
-                scheduleWriteSettingsLocked();
-            }
-        }
-        @Override
-        public void onPermissionRemoved() {
-            synchronized (mPackages) {
-                mSettings.writeLPr();
-            }
-        }
-    };
-
     private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
             boolean killApp, boolean virtualPreload,
             String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
@@ -1842,8 +1759,7 @@
                     && !whitelistedRestrictedPermissions.isEmpty()) {
                 mPermissionManager.setWhitelistedRestrictedPermissions(
                         res.pkg, res.newUsers, whitelistedRestrictedPermissions,
-                        Process.myUid(), PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER,
-                        mPermissionCallback);
+                        Process.myUid(), FLAG_PERMISSION_WHITELIST_INSTALLER);
             }
 
             // Now that we successfully installed the package, grant runtime
@@ -1854,8 +1770,7 @@
             if (grantPermissions) {
                 final int callingUid = Binder.getCallingUid();
                 mPermissionManager.grantRequestedRuntimePermissions(
-                        res.pkg, res.newUsers, grantedPermissions, callingUid,
-                        mPermissionCallback);
+                        res.pkg, res.newUsers, grantedPermissions, callingUid);
             }
 
             final String installerPackageName =
@@ -1871,7 +1786,7 @@
             if (res.pkg.parentPackage != null) {
                 final int callingUid = Binder.getCallingUid();
                 mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
-                        res.pkg, callingUid, mPermissionCallback);
+                        res.pkg, callingUid);
             }
 
             synchronized (mPackages) {
@@ -2039,7 +1954,7 @@
                             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
                             if (pkgSetting.getInstallReason(userId)
                                     != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
-                                setDefaultBrowserAsyncLPw(null, userId);
+                                mPermissionManager.setDefaultBrowser(null, true, true, userId);
                             }
                         }
                     }
@@ -2384,10 +2299,12 @@
         }
     }
 
-    public PackageManagerService(Context context, Installer installer,
-            boolean factoryTest, boolean onlyCore) {
+    public PackageManagerService(Context context, Installer installer, boolean factoryTest,
+            boolean onlyCore) {
+        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
+                Trace.TRACE_TAG_PACKAGE_MANAGER);
+        t.traceBegin("create package manager");
         LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
-        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                 SystemClock.uptimeMillis());
 
@@ -2403,6 +2320,8 @@
         mInstaller = installer;
 
         // Create sub-components that provide services / data. Order here is important.
+        t.traceBegin("createSubComponents");
+        // CHECKSTYLE:OFF IndentationCheck
         synchronized (mInstallLock) {
         synchronized (mPackages) {
             // Expose private service for system components to use.
@@ -2415,11 +2334,16 @@
                     mPackages);
             mPermissionManager = PermissionManagerService.create(context,
                     mPackages /*externalLock*/);
-            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
+            mPermissionManagerService =
+                    (IPermissionManager) ServiceManager.getService("permissionmgr");
             mSettings = new Settings(Environment.getDataDirectory(),
                     mPermissionManager.getPermissionSettings(), mPackages);
         }
         }
+        // CHECKSTYLE:ON IndentationCheck
+        t.traceEnd();
+
+        t.traceBegin("addSharedUsers");
         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
@@ -2436,6 +2360,7 @@
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
         mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
+        t.traceEnd();
 
         String separateProcesses = SystemProperties.get("debug.separate_processes");
         if (separateProcesses != null && separateProcesses.length() > 0) {
@@ -2462,19 +2387,17 @@
 
         mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
 
-        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
-                FgThread.get().getLooper());
-
         getDefaultDisplayMetrics(context, mMetrics);
 
-        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
+        t.traceBegin("get system config");
         SystemConfig systemConfig = SystemConfig.getInstance();
         mAvailableFeatures = systemConfig.getAvailableFeatures();
-        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        t.traceEnd();
 
         mProtectedPackages = new ProtectedPackages(mContext);
 
-        mApexManager = new ApexManager(context);
+        mApexManager = ApexManager.create(context);
+        // CHECKSTYLE:OFF IndentationCheck
         synchronized (mInstallLock) {
         // writer
         synchronized (mPackages) {
@@ -2513,13 +2436,13 @@
 
             SELinuxMMAC.readInstallPolicy();
 
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
+            t.traceBegin("loadFallbacks");
             FallbackCategoryProvider.loadFallbacks();
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+            t.traceEnd();
 
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
+            t.traceBegin("read user settings");
             mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+            t.traceEnd();
 
             // Clean up orphaned packages for which the code path doesn't exist
             // and they are an update to a system app - caused by bug/32321269
@@ -2578,9 +2501,7 @@
             mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
 
             mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
-            mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q
-                    // STOPSHIP: Remove next line when API level for Q is defined.
-                    && Build.VERSION.SDK_INT > Build.VERSION_CODES.P;
+            mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
 
             int preUpgradeSdkVersion = ver.sdkVersion;
 
@@ -2606,7 +2527,7 @@
                 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
             }
 
-            // Collect vendor/product/product_services overlay packages. (Do this before scanning
+            // Collect vendor/product/system_ext overlay packages. (Do this before scanning
             // any apps.)
             // For security and version matching reason, only consider overlay packages if they
             // reside in the right directory.
@@ -2624,12 +2545,12 @@
                     | SCAN_AS_SYSTEM
                     | SCAN_AS_PRODUCT,
                     0);
-            scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
+            scanDirTracedLI(new File(SYSTEM_EXT_OVERLAY_DIR),
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES,
+                    | SCAN_AS_SYSTEM_EXT,
                     0);
             scanDirTracedLI(new File(ODM_OVERLAY_DIR),
                     mDefParseFlags
@@ -2787,37 +2708,37 @@
                     | SCAN_AS_PRODUCT,
                     0);
 
-            // Collected privileged /product_services packages.
-            File privilegedProductServicesAppDir =
-                    new File(Environment.getProductServicesDirectory(), "priv-app");
+            // Collected privileged /system_ext packages.
+            File privilegedSystemExtAppDir =
+                    new File(Environment.getSystemExtDirectory(), "priv-app");
             try {
-                privilegedProductServicesAppDir =
-                        privilegedProductServicesAppDir.getCanonicalFile();
+                privilegedSystemExtAppDir =
+                        privilegedSystemExtAppDir.getCanonicalFile();
             } catch (IOException e) {
                 // failed to look up canonical path, continue with original one
             }
-            scanDirTracedLI(privilegedProductServicesAppDir,
+            scanDirTracedLI(privilegedSystemExtAppDir,
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES
+                    | SCAN_AS_SYSTEM_EXT
                     | SCAN_AS_PRIVILEGED,
                     0);
 
-            // Collect ordinary /product_services packages.
-            File productServicesAppDir = new File(Environment.getProductServicesDirectory(), "app");
+            // Collect ordinary /system_ext packages.
+            File systemExtAppDir = new File(Environment.getSystemExtDirectory(), "app");
             try {
-                productServicesAppDir = productServicesAppDir.getCanonicalFile();
+                systemExtAppDir = systemExtAppDir.getCanonicalFile();
             } catch (IOException e) {
                 // failed to look up canonical path, continue with original one
             }
-            scanDirTracedLI(productServicesAppDir,
+            scanDirTracedLI(systemExtAppDir,
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES,
+                    | SCAN_AS_SYSTEM_EXT,
                     0);
 
             // Prune any system packages that no longer exist.
@@ -3047,23 +2968,23 @@
                                     scanFlags
                                     | SCAN_AS_SYSTEM
                                     | SCAN_AS_PRODUCT;
-                        } else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
+                        } else if (FileUtils.contains(privilegedSystemExtAppDir, scanFile)) {
                             reparseFlags =
                                     mDefParseFlags |
                                     PackageParser.PARSE_IS_SYSTEM_DIR;
                             rescanFlags =
                                     scanFlags
                                     | SCAN_AS_SYSTEM
-                                    | SCAN_AS_PRODUCT_SERVICES
+                                    | SCAN_AS_SYSTEM_EXT
                                     | SCAN_AS_PRIVILEGED;
-                        } else if (FileUtils.contains(productServicesAppDir, scanFile)) {
+                        } else if (FileUtils.contains(systemExtAppDir, scanFile)) {
                             reparseFlags =
                                     mDefParseFlags |
                                     PackageParser.PARSE_IS_SYSTEM_DIR;
                             rescanFlags =
                                     scanFlags
                                     | SCAN_AS_SYSTEM
-                                    | SCAN_AS_PRODUCT_SERVICES;
+                                    | SCAN_AS_SYSTEM_EXT;
                         } else {
                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                             continue;
@@ -3166,8 +3087,7 @@
                         + mSdkVersion + "; regranting permissions for internal storage");
             }
             mPermissionManager.updateAllPermissions(
-                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
-                    mPermissionCallback);
+                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);
             ver.sdkVersion = mSdkVersion;
 
             // If this is the first boot or an update from pre-M, and it is a normal
@@ -3242,7 +3162,8 @@
                         // No apps are running this early, so no need to freeze
                         clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
                                 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
-                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
+                                        | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
                     }
                 }
                 ver.fingerprint = Build.FINGERPRINT;
@@ -3271,9 +3192,9 @@
             ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
 
             // can downgrade to reader
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
+            t.traceBegin("write settings");
             mSettings.writeLPr();
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+            t.traceEnd();
             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                     SystemClock.uptimeMillis());
 
@@ -3359,15 +3280,16 @@
             }
         } // synchronized (mPackages)
         } // synchronized (mInstallLock)
+        // CHECKSTYLE:ON IndentationCheck
 
         mModuleInfoProvider = new ModuleInfoProvider(mContext, this);
 
         // Now after opening every single application zip, make sure they
         // are all flushed.  Not really needed, but keeps things nice and
         // tidy.
-        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
+        t.traceBegin("GC");
         Runtime.getRuntime().gc();
-        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        t.traceEnd();
 
         // The initial scanning above does many calls into installd while
         // holding the mPackages lock, but we're mostly interested in yelling
@@ -3378,7 +3300,7 @@
 
         mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
 
-        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+        t.traceEnd(); // "create package manager"
     }
 
     /**
@@ -3461,8 +3383,7 @@
                     } catch (PackageManagerException e) {
                         Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
                     }
-                    mPermissionManager.updatePermissions(pkg.packageName, pkg, mPackages.values(),
-                            mPermissionCallback);
+                    mPermissionManager.updatePermissions(pkg.packageName, pkg);
                     mSettings.writeLPr();
                 }
             } catch (PackageManagerException e) {
@@ -4533,55 +4454,6 @@
         return -1;
     }
 
-    /**
-     * Check if any package sharing/holding a uid has a low enough target SDK.
-     *
-     * @param uid The uid of the packages
-     * @param higherTargetSDK The target SDK that might be higher than the searched package
-     *
-     * @return {@code true} if there is a package sharing/holding the uid with
-     * {@code package.targetSDK < higherTargetSDK}
-     */
-    private boolean hasTargetSdkInUidLowerThan(int uid, int higherTargetSDK) {
-        int userId = UserHandle.getUserId(uid);
-
-        synchronized (mPackages) {
-            Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
-            if (obj == null) {
-                return false;
-            }
-
-            if (obj instanceof PackageSetting) {
-                final PackageSetting ps = (PackageSetting) obj;
-
-                if (!ps.getInstalled(userId)) {
-                    return false;
-                }
-
-                return ps.pkg.applicationInfo.targetSdkVersion < higherTargetSDK;
-            } else if (obj instanceof SharedUserSetting) {
-                final SharedUserSetting sus = (SharedUserSetting) obj;
-
-                final int numPkgs = sus.packages.size();
-                for (int i = 0; i < numPkgs; i++) {
-                    final PackageSetting ps = sus.packages.valueAt(i);
-
-                    if (!ps.getInstalled(userId)) {
-                        continue;
-                    }
-
-                    if (ps.pkg.applicationInfo.targetSdkVersion < higherTargetSDK) {
-                        return true;
-                    }
-                }
-
-                return false;
-            } else {
-                return false;
-            }
-        }
-    }
-
     @Override
     public int[] getPackageGids(String packageName, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
@@ -4614,30 +4486,15 @@
         return null;
     }
 
-    @Override
-    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
-        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
-    }
-
-    @Override
-    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
-            int flags) {
-        final List<PermissionInfo> permissionList =
-                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
-        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
-    }
-
+    // NOTE: Can't remove due to unsupported app usage
     @Override
     public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
-        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
-    }
-
-    @Override
-    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
-        final List<PermissionGroupInfo> permissionList =
-                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
-        return (permissionList == null)
-                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
+        try {
+            // Because this is accessed via the package manager service AIDL,
+            // go through the permission manager service AIDL
+            return mPermissionManagerService.getPermissionGroupInfo(groupName, flags);
+        } catch (RemoteException ignore) { }
+        return null;
     }
 
     @GuardedBy("mPackages")
@@ -5606,100 +5463,26 @@
         }
     }
 
+    // NOTE: Can't remove due to unsupported app usage
     @Override
     public int checkPermission(String permName, String pkgName, int userId) {
-        final CheckPermissionDelegate checkPermissionDelegate;
-        synchronized (mPackages) {
-            if (mCheckPermissionDelegate == null)  {
-                return checkPermissionImpl(permName, pkgName, userId);
-            }
-            checkPermissionDelegate = mCheckPermissionDelegate;
-        }
-        return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
-                PackageManagerService.this::checkPermissionImpl);
+        try {
+            // Because this is accessed via the package manager service AIDL,
+            // go through the permission manager service AIDL
+            return mPermissionManagerService.checkPermission(permName, pkgName, userId);
+        } catch (RemoteException ignore) { }
+        return PackageManager.PERMISSION_DENIED;
     }
 
-    private int checkPermissionImpl(String permName, String pkgName, int userId) {
-        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
-    }
-
+    // NOTE: Can't remove without a major refactor. Keep around for now.
     @Override
     public int checkUidPermission(String permName, int uid) {
-        final CheckPermissionDelegate checkPermissionDelegate;
-        synchronized (mPackages) {
-            if (mCheckPermissionDelegate == null)  {
-                return checkUidPermissionImpl(permName, uid);
-            }
-            checkPermissionDelegate = mCheckPermissionDelegate;
-        }
-        return checkPermissionDelegate.checkUidPermission(permName, uid,
-                PackageManagerService.this::checkUidPermissionImpl);
-    }
-
-    private int checkUidPermissionImpl(String permName, int uid) {
-        synchronized (mPackages) {
-            final String[] packageNames = getPackagesForUid(uid);
-            PackageParser.Package pkg = null;
-            final int N = packageNames == null ? 0 : packageNames.length;
-            for (int i = 0; pkg == null && i < N; i++) {
-                pkg = mPackages.get(packageNames[i]);
-            }
-            // Additional logs for b/111075456; ignore system UIDs
-            if (pkg == null && UserHandle.getAppId(uid) >= Process.FIRST_APPLICATION_UID) {
-                if (packageNames == null || packageNames.length < 2) {
-                    // unclear if this is shared user or just a missing application
-                    Log.e(TAG, "Failed to find package"
-                            + "; permName: " + permName
-                            + ", uid: " + uid
-                            + ", caller: " + Binder.getCallingUid(),
-                            new Throwable());
-                } else {
-                    // definitely shared user
-                    Log.e(TAG, "Failed to find package"
-                            + "; permName: " + permName
-                            + ", uid: " + uid
-                            + ", caller: " + Binder.getCallingUid()
-                            + ", packages: " + Arrays.toString(packageNames),
-                            new Throwable());
-                }
-                // run again just to try to get debug output
-                getPackagesForUid_debug(uid, true);
-            }
-            return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
-        }
-    }
-
-    @Override
-    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "isPermissionRevokedByPolicy for user " + userId);
-        }
-
-        if (checkPermission(permission, packageName, userId)
-                == PackageManager.PERMISSION_GRANTED) {
-            return false;
-        }
-
-        final int callingUid = Binder.getCallingUid();
-        if (getInstantAppPackageName(callingUid) != null) {
-            if (!isCallerSameApp(packageName, callingUid)) {
-                return false;
-            }
-        } else {
-            if (isInstantApp(packageName, userId)) {
-                return false;
-            }
-        }
-
-        final long identity = Binder.clearCallingIdentity();
         try {
-            final int flags = getPermissionFlags(permission, packageName, userId);
-            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
+            // Because this is accessed via the package manager service AIDL,
+            // go through the permission manager service AIDL
+            return mPermissionManagerService.checkUidPermission(permName, uid);
+        } catch (RemoteException ignore) { }
+        return PackageManager.PERMISSION_DENIED;
     }
 
     @Override
@@ -5715,428 +5498,46 @@
         }
     }
 
-    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
-        return mPermissionManager.addDynamicPermission(
-                info, async, getCallingUid(), new PermissionCallback() {
-                    @Override
-                    public void onPermissionChanged() {
-                        if (!async) {
-                            mSettings.writeLPr();
-                        } else {
-                            scheduleWriteSettingsLocked();
-                        }
-                    }
-                });
-    }
-
+    // NOTE: Can't remove due to unsupported app usage
     @Override
     public boolean addPermission(PermissionInfo info) {
-        synchronized (mPackages) {
-            return addDynamicPermission(info, false);
-        }
+        try {
+            // Because this is accessed via the package manager service AIDL,
+            // go through the permission manager service AIDL
+            return mPermissionManagerService.addPermission(info, false);
+        } catch (RemoteException ignore) { }
+        return false;
     }
 
+    // NOTE: Can't remove due to unsupported app usage
     @Override
     public boolean addPermissionAsync(PermissionInfo info) {
-        synchronized (mPackages) {
-            return addDynamicPermission(info, true);
-        }
+        try {
+            // Because this is accessed via the package manager service AIDL,
+            // go through the permission manager service AIDL
+            return mPermissionManagerService.addPermission(info, true);
+        } catch (RemoteException ignore) { }
+        return false;
     }
 
+    // NOTE: Can't remove due to unsupported app usage
     @Override
     public void removePermission(String permName) {
-        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
+        try {
+            // Because this is accessed via the package manager service AIDL,
+            // go through the permission manager service AIDL
+            mPermissionManagerService.removePermission(permName);
+        } catch (RemoteException ignore) { }
     }
 
+    // NOTE: Can't remove due to unsupported app usage
     @Override
     public void grantRuntimePermission(String packageName, String permName, final int userId) {
-        boolean overridePolicy = (checkUidPermission(
-                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, Binder.getCallingUid())
-                == PackageManager.PERMISSION_GRANTED);
-
-        mPermissionManager.grantRuntimePermission(permName, packageName, overridePolicy,
-                getCallingUid(), userId, mPermissionCallback);
-    }
-
-    @Override
-    public void revokeRuntimePermission(String packageName, String permName, int userId) {
-        boolean overridePolicy = (checkUidPermission(
-                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY, Binder.getCallingUid())
-                == PackageManager.PERMISSION_GRANTED);
-
-        mPermissionManager.revokeRuntimePermission(permName, packageName, overridePolicy,
-                userId, mPermissionCallback);
-    }
-
-    @Override
-    public void resetRuntimePermissions() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
-                "revokeRuntimePermission");
-
-        int callingUid = Binder.getCallingUid();
-        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "resetRuntimePermissions");
-        }
-
-        synchronized (mPackages) {
-            mPermissionManager.updateAllPermissions(
-                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
-                    mPermissionCallback);
-            for (int userId : UserManagerService.getInstance().getUserIds()) {
-                final int packageCount = mPackages.size();
-                for (int i = 0; i < packageCount; i++) {
-                    PackageParser.Package pkg = mPackages.valueAt(i);
-                    if (!(pkg.mExtras instanceof PackageSetting)) {
-                        continue;
-                    }
-                    PackageSetting ps = (PackageSetting) pkg.mExtras;
-                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
-                }
-            }
-        }
-    }
-
-    @Override
-    public int getPermissionFlags(String permName, String packageName, int userId) {
-        return mPermissionManager.getPermissionFlags(
-                permName, packageName, getCallingUid(), userId);
-    }
-
-    @Override
-    public void updatePermissionFlags(String permName, String packageName, int flagMask,
-            int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
-        int callingUid = getCallingUid();
-        boolean overridePolicy = false;
-
-        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
-            long callingIdentity = Binder.clearCallingIdentity();
-            try {
-                if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
-                    if (checkAdjustPolicyFlagPermission) {
-                        mContext.enforceCallingOrSelfPermission(
-                                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
-                                "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
-                                        + " to change policy flags");
-                    } else if (!hasTargetSdkInUidLowerThan(callingUid, Build.VERSION_CODES.Q)) {
-                        throw new IllegalArgumentException(
-                                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
-                                        + " to be checked for packages targeting "
-                                        + Build.VERSION_CODES.Q + " or later when changing policy "
-                                        + "flags");
-                    }
-
-                    overridePolicy = true;
-                }
-            } finally {
-                Binder.restoreCallingIdentity(callingIdentity);
-            }
-        }
-
-        mPermissionManager.updatePermissionFlags(
-                permName, packageName, flagMask, flagValues, callingUid, userId,
-                overridePolicy, mPermissionCallback);
-    }
-
-    /**
-     * Update the permission flags for all packages and runtime permissions of a user in order
-     * to allow device or profile owner to remove POLICY_FIXED.
-     */
-    @Override
-    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
-        synchronized (mPackages) {
-            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
-                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
-                    mPermissionCallback);
-            if (changed) {
-                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
-            }
-        }
-    }
-
-    @Override
-    public @Nullable List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
-            @PermissionWhitelistFlags int whitelistFlags, @UserIdInt int userId) {
-        Preconditions.checkNotNull(packageName);
-        Preconditions.checkFlagsArgument(whitelistFlags,
-                PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
-                        | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
-                        | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
-        Preconditions.checkArgumentNonNegative(userId, null);
-
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS,
-                    "getWhitelistedRestrictedPermissions for user " + userId);
-        }
-
-        final PackageParser.Package pkg;
-
-        synchronized (mPackages) {
-            final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
-            if (packageSetting == null) {
-                Slog.w(TAG, "Unknown package: " + packageName);
-                return null;
-            }
-
-            pkg = packageSetting.pkg;
-
-            final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
-                    Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
-                            == PackageManager.PERMISSION_GRANTED;
-            final PackageSetting installerPackageSetting = mSettings.mPackages.get(
-                    packageSetting.installerPackageName);
-            final boolean isCallerInstallerOnRecord = installerPackageSetting != null
-                    && UserHandle.isSameApp(installerPackageSetting.appId, Binder.getCallingUid());
-
-            if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
-                    && !isCallerPrivileged) {
-                throw new SecurityException("Querying system whitelist requires "
-                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
-            }
-
-            if ((whitelistFlags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
-                    | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
-                if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
-                    throw new SecurityException("Querying upgrade or installer whitelist"
-                            + " requires being installer on record or "
-                            + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
-                }
-            }
-
-            if (filterAppAccessLPr(packageSetting, Binder.getCallingUid(),
-                    UserHandle.getCallingUserId())) {
-                return null;
-            }
-        }
-
-        final long identity = Binder.clearCallingIdentity();
         try {
-            return mPermissionManager.getWhitelistedRestrictedPermissions(
-                    pkg, whitelistFlags, userId);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
-            @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags,
-            @UserIdInt int userId) {
-        // Other argument checks are done in get/setWhitelistedRestrictedPermissions
-        Preconditions.checkNotNull(permission);
-
-        if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permission)) {
-            return false;
-        }
-
-        List<String> permissions = getWhitelistedRestrictedPermissions(packageName,
-                whitelistFlags, userId);
-        if (permissions == null) {
-            permissions = new ArrayList<>(1);
-        }
-        if (permissions.indexOf(permission) < 0) {
-            permissions.add(permission);
-            return setWhitelistedRestrictedPermissions(packageName, permissions,
-                    whitelistFlags, userId);
-        }
-        return false;
-    }
-
-    private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
-            @NonNull String permission) {
-        synchronized (mPackages) {
-            final BasePermission bp = mPermissionManager.getPermissionTEMP(permission);
-            if (bp == null) {
-                Slog.w(TAG, "No such permissions: " + permission);
-                return false;
-            }
-            if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
-                    && mContext.checkCallingOrSelfPermission(
-                    Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
-                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("Cannot modify whitelisting of an immutably "
-                        + "restricted permission: " + permission);
-            }
-            return true;
-        }
-    }
-
-    @Override
-    public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
-            @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags,
-            @UserIdInt int userId) {
-        // Other argument checks are done in get/setWhitelistedRestrictedPermissions
-        Preconditions.checkNotNull(permission);
-
-        if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permission)) {
-            return false;
-        }
-
-        final List<String> permissions = getWhitelistedRestrictedPermissions(packageName,
-                whitelistFlags, userId);
-        if (permissions != null && permissions.remove(permission)) {
-            return setWhitelistedRestrictedPermissions(packageName, permissions,
-                    whitelistFlags, userId);
-        }
-        return false;
-    }
-
-    private boolean setWhitelistedRestrictedPermissions(@NonNull String packageName,
-            @Nullable List<String> permissions, @PermissionWhitelistFlags int whitelistFlag,
-            @UserIdInt int userId) {
-        Preconditions.checkNotNull(packageName);
-        Preconditions.checkFlagsArgument(whitelistFlag,
-                PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
-                        | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
-                        | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
-        Preconditions.checkArgument(Integer.bitCount(whitelistFlag) == 1);
-        Preconditions.checkArgumentNonNegative(userId, null);
-
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    Manifest.permission.INTERACT_ACROSS_USERS,
-                    "setWhitelistedRestrictedPermissions for user " + userId);
-        }
-
-        final PackageParser.Package pkg;
-
-        synchronized (mPackages) {
-            final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
-            if (packageSetting == null) {
-                Slog.w(TAG, "Unknown package: " + packageName);
-                return false;
-            }
-
-            pkg = packageSetting.pkg;
-
-            final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
-                    Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
-                            == PackageManager.PERMISSION_GRANTED;
-            final PackageSetting installerPackageSetting = mSettings.mPackages.get(
-                    packageSetting.installerPackageName);
-            final boolean isCallerInstallerOnRecord = installerPackageSetting != null
-                    && UserHandle.isSameApp(installerPackageSetting.appId, Binder.getCallingUid());
-
-            if ((whitelistFlag & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
-                    && !isCallerPrivileged) {
-                throw new SecurityException("Modifying system whitelist requires "
-                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
-            }
-
-            if ((whitelistFlag & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
-                if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
-                    throw new SecurityException("Modifying upgrade whitelist requires"
-                            + " being installer on record or "
-                            + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
-                }
-                final List<String> whitelistedPermissions = getWhitelistedRestrictedPermissions(
-                        packageName, whitelistFlag, userId);
-                if (permissions == null || permissions.isEmpty()) {
-                    if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
-                        return true;
-                    }
-                } else {
-                    // Only the system can add and remove while the installer can only remove.
-                    final int permissionCount = permissions.size();
-                    for (int i = 0; i < permissionCount; i++) {
-                        if ((whitelistedPermissions == null
-                                || !whitelistedPermissions.contains(permissions.get(i)))
-                                && !isCallerPrivileged) {
-                            throw new SecurityException("Adding to upgrade whitelist requires"
-                                    + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
-                        }
-                    }
-                }
-            }
-
-            if ((whitelistFlag & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
-                if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
-                    throw new SecurityException("Modifying installer whitelist requires"
-                            + " being installer on record or "
-                            + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
-                }
-            }
-
-            if (filterAppAccessLPr(packageSetting, Binder.getCallingUid(),
-                    UserHandle.getCallingUserId())) {
-                return false;
-            }
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            mPermissionManager.setWhitelistedRestrictedPermissions(pkg,
-                    new int[]{userId}, permissions, Process.myUid(), whitelistFlag,
-                    mPermissionCallback);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean shouldShowRequestPermissionRationale(String permissionName,
-            String packageName, int userId) {
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "canShowRequestPermissionRationale for user " + userId);
-        }
-
-        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
-        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
-            return false;
-        }
-
-        if (checkPermission(permissionName, packageName, userId)
-                == PackageManager.PERMISSION_GRANTED) {
-            return false;
-        }
-
-        final int flags;
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            flags = getPermissionFlags(permissionName,
-                    packageName, userId);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-
-        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
-                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
-                | PackageManager.FLAG_PERMISSION_USER_FIXED;
-
-        if ((flags & fixedFlags) != 0) {
-            return false;
-        }
-
-        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
-    }
-
-    @Override
-    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
-        mContext.enforceCallingOrSelfPermission(
-                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
-                "addOnPermissionsChangeListener");
-
-        synchronized (mPackages) {
-            mOnPermissionChangeListeners.addListenerLocked(listener);
-        }
-    }
-
-    @Override
-    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            throw new SecurityException("Instant applications don't have access to this method");
-        }
-        synchronized (mPackages) {
-            mOnPermissionChangeListeners.removeListenerLocked(listener);
-        }
+            // Because this is accessed via the package manager service AIDL,
+            // go through the permission manager service AIDL
+            mPermissionManagerService.grantRuntimePermission(packageName, permName, userId);
+        } catch (RemoteException ignore) { }
     }
 
     @Override
@@ -6301,29 +5702,6 @@
     }
 
     /**
-     * This method should typically only be used when granting or revoking
-     * permissions, since the app may immediately restart after this call.
-     * <p>
-     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
-     * guard your work against the app being relaunched.
-     */
-    private void killUid(int appId, int userId, String reason) {
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            IActivityManager am = ActivityManager.getService();
-            if (am != null) {
-                try {
-                    am.killUid(appId, userId, reason);
-                } catch (RemoteException e) {
-                    /* ignore - same process */
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
      * If the database version for this type of package (internal storage or
      * external storage) is less than the version where package signatures
      * were updated, return true.
@@ -6392,25 +5770,15 @@
      */
     @Override
     public String[] getPackagesForUid(int uid) {
-        return getPackagesForUid_debug(uid, false);
-    }
-    // Debug output for b/111075456
-    private String[] getPackagesForUid_debug(int uid, boolean debug) {
         final int callingUid = Binder.getCallingUid();
         final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
         final int userId = UserHandle.getUserId(uid);
         final int appId = UserHandle.getAppId(uid);
-        if (debug) Slog.e(TAG, "Finding packages for UID"
-                + "; uid: " + uid
-                + ", userId: " + userId
-                + ", appId: " + appId
-                + ", caller: " + callingUid);
         // reader
         synchronized (mPackages) {
             final Object obj = mSettings.getSettingLPr(appId);
             if (obj instanceof SharedUserSetting) {
                 if (isCallerInstantApp) {
-                    if (debug) Slog.e(TAG, "Caller is instant and package has shared users");
                     return null;
                 }
                 final SharedUserSetting sus = (SharedUserSetting) obj;
@@ -6418,13 +5786,8 @@
                 String[] res = new String[N];
                 final Iterator<PackageSetting> it = sus.packages.iterator();
                 int i = 0;
-                if (debug && !it.hasNext()) Slog.e(TAG, "Shared user, but, no packages");
                 while (it.hasNext()) {
                     PackageSetting ps = it.next();
-                    if (debug) Slog.e(TAG, "Check shared package"
-                            + "; installed? " + ps.getInstalled(userId)
-                            + ", shared setting: " + ps
-                            + ", package setting: " + mSettings.mPackages.get(ps.name));
                     if (ps.getInstalled(userId)) {
                         res[i++] = ps.name;
                     } else {
@@ -6437,12 +5800,6 @@
                 if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
                     return new String[]{ps.name};
                 }
-                if (debug) Slog.e(TAG, "Removing normal package"
-                        + "; installed? " + ps.getInstalled(userId)
-                        + ", filtered? " + filterAppAccessLPr(ps, callingUid, userId));
-            } else if (debug) {
-                if (debug) Slog.e(TAG, "No setting found"
-                        + "; obj: " + (obj == null ? "<<NULL>>" : obj.toString()));
             }
         }
         return null;
@@ -6597,9 +5954,15 @@
         return false;
     }
 
+    // NOTE: Can't remove due to unsupported app usage
     @Override
     public String[] getAppOpPermissionPackages(String permName) {
-        return mPermissionManager.getAppOpPermissionPackages(permName);
+        try {
+            // Because this is accessed via the package manager service AIDL,
+            // go through the permission manager service AIDL
+            return mPermissionManagerService.getAppOpPermissionPackages(permName);
+        } catch (RemoteException ignore) { }
+        return null;
     }
 
     @Override
@@ -7836,7 +7199,8 @@
                 } else {
                     // Browser/generic handling case.  If there's a default browser, go straight
                     // to that (but only if there is no other higher-priority match).
-                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
+                    final String defaultBrowserPackageName =
+                            mPermissionManager.getDefaultBrowser(userId);
                     int maxMatchPrio = 0;
                     ResolveInfo defaultBrowserMatch = null;
                     final int numCandidates = matchAllList.size();
@@ -9886,16 +9250,6 @@
     }
 
     @GuardedBy("mPackages")
-    public CheckPermissionDelegate getCheckPermissionDelegateLocked() {
-        return mCheckPermissionDelegate;
-    }
-
-    @GuardedBy("mPackages")
-    public void setCheckPermissionDelegateLocked(CheckPermissionDelegate delegate) {
-        mCheckPermissionDelegate = delegate;
-    }
-
-    @GuardedBy("mPackages")
     private void notifyPackageUseLocked(String packageName, int reason) {
         final PackageParser.Package p = mPackages.get(packageName);
         if (p == null) {
@@ -10364,7 +9718,9 @@
             clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
         }
 
-        clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
+        if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
+            clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
+        }
     }
 
     private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
@@ -10898,7 +10254,7 @@
      * <li>{@link #SCAN_AS_OEM}</li>
      * <li>{@link #SCAN_AS_VENDOR}</li>
      * <li>{@link #SCAN_AS_PRODUCT}</li>
-     * <li>{@link #SCAN_AS_PRODUCT_SERVICES}</li>
+     * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
      * <li>{@link #SCAN_AS_INSTANT_APP}</li>
      * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
      * <li>{@link #SCAN_AS_ODM}</li>
@@ -10935,8 +10291,8 @@
                 scanFlags |= SCAN_AS_PRODUCT;
             }
             if ((systemPkgSetting.pkgPrivateFlags
-                    & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0) {
-                scanFlags |= SCAN_AS_PRODUCT_SERVICES;
+                    & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
+                scanFlags |= SCAN_AS_SYSTEM_EXT;
             }
             if ((systemPkgSetting.pkgPrivateFlags
                     & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
@@ -11634,16 +10990,16 @@
             if (pkg.applicationInfo.isDirectBootAware()) {
                 // we're direct boot aware; set for all components
                 for (PackageParser.Service s : pkg.services) {
-                    s.info.encryptionAware = s.info.directBootAware = true;
+                    s.info.directBootAware = true;
                 }
                 for (PackageParser.Provider p : pkg.providers) {
-                    p.info.encryptionAware = p.info.directBootAware = true;
+                    p.info.directBootAware = true;
                 }
                 for (PackageParser.Activity a : pkg.activities) {
-                    a.info.encryptionAware = a.info.directBootAware = true;
+                    a.info.directBootAware = true;
                 }
                 for (PackageParser.Activity r : pkg.receivers) {
-                    r.info.encryptionAware = r.info.directBootAware = true;
+                    r.info.directBootAware = true;
                 }
             }
             if (compressedFileExists(pkg.codePath)) {
@@ -11714,8 +11070,8 @@
             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
         }
 
-        if ((scanFlags & SCAN_AS_PRODUCT_SERVICES) != 0) {
-            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+        if ((scanFlags & SCAN_AS_SYSTEM_EXT) != 0) {
+            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
         }
 
         if ((scanFlags & SCAN_AS_ODM) != 0) {
@@ -12350,7 +11706,7 @@
 
                 AsyncTask.execute(() ->
                         mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
-                                allPackageNames, mPermissionCallback));
+                                allPackageNames));
             }
         }
 
@@ -12679,8 +12035,8 @@
             codeRoot = Environment.getOdmDirectory();
         } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
             codeRoot = Environment.getProductDirectory();
-        } else if (FileUtils.contains(Environment.getProductServicesDirectory(), codePath)) {
-            codeRoot = Environment.getProductServicesDirectory();
+        } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
+            codeRoot = Environment.getSystemExtDirectory();
         } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
             codeRoot = Environment.getOdmDirectory();
         } else {
@@ -13384,7 +12740,9 @@
 
     @Override
     public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
-        enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled");
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled", callingUid);
         synchronized (mPackages) {
             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
             if (pkgSetting == null || !pkgSetting.isSystem()) {
@@ -13407,7 +12765,9 @@
 
     @Override
     public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
-        enforceSystemOrPhoneCaller("setSystemAppInstallState");
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("setSystemAppInstallState", callingUid);
         synchronized (mPackages) {
             final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
             // The target app should always be in system
@@ -13596,8 +12956,8 @@
                         != 0 && pkgSetting.pkg != null) {
                     whiteListedPermissions = pkgSetting.pkg.requestedPermissions;
                 }
-                setWhitelistedRestrictedPermissions(packageName, whiteListedPermissions,
-                        PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
+                mPermissionManager.setWhitelistedRestrictedPermissions(packageName,
+                        whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
 
                 if (pkgSetting.pkg != null) {
                     synchronized (mInstallLock) {
@@ -13979,7 +13339,7 @@
         final long callingId = Binder.clearCallingIdentity();
         try {
             final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
-            final String dialerPackageName = getDefaultDialerPackageName(userId);
+            final String dialerPackageName = mPermissionManager.getDefaultDialer(userId);
             for (int i = 0; i < packageNames.length; i++) {
                 canSuspend[i] = false;
                 final String packageName = packageNames[i];
@@ -14061,19 +13421,6 @@
         return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
     }
 
-    @Nullable
-    private String getDefaultDialerPackageName(@UserIdInt int userId) {
-        PackageManagerInternal.DefaultDialerProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultDialerProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "mDefaultDialerProvider is null");
-            return null;
-        }
-        return provider.getDefaultDialer(userId);
-    }
-
     @Override
     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
         mContext.enforceCallingOrSelfPermission(
@@ -14432,75 +13779,6 @@
         }
     }
 
-    @Override
-    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
-        }
-        if (userId == UserHandle.USER_ALL) {
-            return false;
-        }
-        PackageManagerInternal.DefaultBrowserProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultBrowserProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "mDefaultBrowserProvider is null");
-            return false;
-        }
-        boolean successful = provider.setDefaultBrowser(packageName, userId);
-        if (!successful) {
-            return false;
-        }
-        if (packageName != null) {
-            synchronized (mPackages) {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
-                        userId);
-            }
-        }
-        return true;
-    }
-
-    private void setDefaultBrowserAsyncLPw(@Nullable String packageName, @UserIdInt int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            return;
-        }
-        if (mDefaultBrowserProvider == null) {
-            Slog.e(TAG, "mDefaultBrowserProvider is null");
-            return;
-        }
-        mDefaultBrowserProvider.setDefaultBrowserAsync(packageName, userId);
-        if (packageName != null) {
-            synchronized (mPackages) {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
-                        userId);
-            }
-        }
-    }
-
-    @Override
-    public String getDefaultBrowserPackageName(int userId) {
-        if (UserHandle.getCallingUserId() != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
-        }
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        PackageManagerInternal.DefaultBrowserProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultBrowserProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "mDefaultBrowserProvider is null");
-            return null;
-        }
-        return provider.getDefaultBrowser(userId);
-    }
-
     /**
      * Get the "allow unknown sources" setting.
      *
@@ -14763,7 +14041,7 @@
 
             if (ps != null) {
                 try {
-                    rm.restoreUserData(packageName, installedUsers, appId, ceDataInode,
+                    rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode,
                             seInfo, token);
                 } catch (RemoteException re) {
                     // Cannot happen, the RollbackManager is hosted in the same process.
@@ -15020,7 +14298,6 @@
                 params.handleStartCopy();
                 if (params.mRet != INSTALL_SUCCEEDED) {
                     mRet = params.mRet;
-                    break;
                 }
             }
         }
@@ -15031,7 +14308,6 @@
                 params.handleReturnCode();
                 if (params.mRet != INSTALL_SUCCEEDED) {
                     mRet = params.mRet;
-                    break;
                 }
             }
         }
@@ -15571,6 +14847,22 @@
         @Override
         void handleReturnCode() {
             if (mVerificationCompleted && mEnableRollbackCompleted) {
+                if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
+                    String packageName = "";
+                    try {
+                        PackageLite packageInfo =
+                                new PackageParser().parsePackageLite(origin.file, 0);
+                        packageName = packageInfo.packageName;
+                    } catch (PackageParserException e) {
+                        Slog.e(TAG, "Can't parse package at " + origin.file.getAbsolutePath(), e);
+                    }
+                    try {
+                        observer.onPackageInstalled(packageName, mRet, "Dry run", new Bundle());
+                    } catch (RemoteException e) {
+                        Slog.i(TAG, "Observer no longer exists.");
+                    }
+                    return;
+                }
                 if (mRet == PackageManager.INSTALL_SUCCEEDED) {
                     mRet = mArgs.copyApk();
                 }
@@ -16249,8 +15541,7 @@
         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
         synchronized (mPackages) {
 // NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
-            mPermissionManager.updatePermissions(pkg.packageName, pkg, mPackages.values(),
-                    mPermissionCallback);
+            mPermissionManager.updatePermissions(pkg.packageName, pkg);
             // For system-bundled packages, we assume that installing an upgraded version
             // of the package implies that the user actually wants to run that new code,
             // so we enable the package.
@@ -16627,13 +15918,13 @@
                                 && compareSignatures(sharedUserSignatures,
                                         pkg.mSigningDetails.signatures)
                                         != PackageManager.SIGNATURE_MATCH) {
-                            if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 28) {
+                            if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
                                 // Mismatched signatures is an error and silently skipping system
                                 // packages will likely break the device in unforeseen ways.
-                                // However,
-                                // we allow the device to boot anyway because, prior to P,
-                                // vendors were
-                                // not expecting the platform to crash in this situation.
+                                // However, we allow the device to boot anyway because, prior to Q,
+                                // vendors were not expecting the platform to crash in this
+                                // situation.
+                                // This WILL be a hard failure on any new API levels after Q.
                                 throw new ReconcileFailure(
                                         INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
                                         "Signature mismatch for shared user: "
@@ -18042,9 +17333,15 @@
                 if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
                 final FileDescriptor fd = result.getUnownedFileDescriptor();
                 try {
-                    mInstaller.installApkVerity(filePath, fd, result.getContentSize());
                     final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
-                    mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
+                    try {
+                        // A file may already have fs-verity, e.g. when reused during a split
+                        // install. If the measurement succeeds, no need to attempt to set up.
+                        mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
+                    } catch (InstallerException e) {
+                        mInstaller.installApkVerity(filePath, fd, result.getContentSize());
+                        mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
+                    }
                 } finally {
                     IoUtils.closeQuietly(fd);
                 }
@@ -18217,9 +17514,9 @@
         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
     }
 
-    private static boolean isProductServicesApp(PackageParser.Package pkg) {
+    private static boolean isSystemExtApp(PackageParser.Package pkg) {
         return (pkg.applicationInfo.privateFlags
-                & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+                & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     private static boolean isOdmApp(PackageParser.Package pkg) {
@@ -18913,8 +18210,7 @@
                     if (outInfo != null) {
                         outInfo.removedAppId = removedAppId;
                     }
-                    mPermissionManager.updatePermissions(
-                            deletedPs.name, null, mPackages.values(), mPermissionCallback);
+                    mPermissionManager.updatePermissions(deletedPs.name, null);
                     if (deletedPs.sharedUser != null) {
                         // Remove permissions associated with package. Since runtime
                         // permissions are per user we have to kill the removed package
@@ -18985,13 +18281,13 @@
             final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
             final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
             final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
-            final File privilegedProductServicesAppDir =
-                    new File(Environment.getProductServicesDirectory(), "priv-app");
+            final File privilegedSystemExtAppDir =
+                    new File(Environment.getSystemExtDirectory(), "priv-app");
             return path.startsWith(privilegedAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedVendorAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedOdmAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedProductAppDir.getCanonicalPath() + "/")
-                    || path.startsWith(privilegedProductServicesAppDir.getCanonicalPath() + "/");
+                    || path.startsWith(privilegedSystemExtAppDir.getCanonicalPath() + "/");
         } catch (IOException e) {
             Slog.e(TAG, "Unable to access code path " + path);
         }
@@ -19026,10 +18322,10 @@
         return false;
     }
 
-    static boolean locationIsProductServices(String path) {
+    static boolean locationIsSystemExt(String path) {
         try {
             return path.startsWith(
-              Environment.getProductServicesDirectory().getCanonicalPath() + "/");
+              Environment.getSystemExtDirectory().getCanonicalPath() + "/");
         } catch (IOException e) {
             Slog.e(TAG, "Unable to access code path " + path);
         }
@@ -19162,8 +18458,8 @@
         if (locationIsProduct(codePathString)) {
             scanFlags |= SCAN_AS_PRODUCT;
         }
-        if (locationIsProductServices(codePathString)) {
-            scanFlags |= SCAN_AS_PRODUCT_SERVICES;
+        if (locationIsSystemExt(codePathString)) {
+            scanFlags |= SCAN_AS_SYSTEM_EXT;
         }
         if (locationIsOdm(codePathString)) {
             scanFlags |= SCAN_AS_ODM;
@@ -19192,8 +18488,7 @@
             if (origPermissionState != null) {
                 ps.getPermissionsState().copyFrom(origPermissionState);
             }
-            mPermissionManager.updatePermissions(pkg.packageName, pkg, mPackages.values(),
-                    mPermissionCallback);
+            mPermissionManager.updatePermissions(pkg.packageName, pkg);
 
             final boolean applyUserRestrictions
                     = (allUserHandles != null) && (origUserHandles != null);
@@ -19655,9 +18950,7 @@
                     scheduleWritePackageRestrictionsLocked(nextUserId);
                 }
             }
-            synchronized (mPackages) {
-                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
-            }
+            mPermissionManager.resetRuntimePermissions(pkg, nextUserId);
             // Also delete contributed media, when requested
             if ((flags & PackageManager.DELETE_CONTRIBUTED_MEDIA) != 0) {
                 try {
@@ -19768,15 +19061,12 @@
                     pkg = ps.pkg;
                 }
             }
-
-            if (pkg == null) {
-                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
-                return false;
-            }
-
-            PackageSetting ps = (PackageSetting) pkg.mExtras;
-            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
         }
+        if (pkg == null) {
+            Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
+            return false;
+        }
+        mPermissionManager.resetRuntimePermissions(pkg, userId);
 
         clearAppDataLIF(pkg, userId,
                 FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
@@ -19798,147 +19088,11 @@
         return true;
     }
 
-    /**
-     * Reverts user permission state changes (permissions and flags) in
-     * all packages for a given user.
-     *
-     * @param userId The device user for which to do a reset.
-     */
-    @GuardedBy("mPackages")
-    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
-        final int packageCount = mPackages.size();
-        for (int i = 0; i < packageCount; i++) {
-            PackageParser.Package pkg = mPackages.valueAt(i);
-            PackageSetting ps = (PackageSetting) pkg.mExtras;
-            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
-        }
-    }
-
     private void resetNetworkPolicies(int userId) {
         LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
     }
 
     /**
-     * Reverts user permission state changes (permissions and flags).
-     *
-     * @param ps The package for which to reset.
-     * @param userId The device user for which to do a reset.
-     */
-    @GuardedBy("mPackages")
-    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
-            final PackageSetting ps, final int userId) {
-        if (ps.pkg == null) {
-            return;
-        }
-
-        // These are flags that can change base on user actions.
-        final int userSettableMask = FLAG_PERMISSION_USER_SET
-                | FLAG_PERMISSION_USER_FIXED
-                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
-                | FLAG_PERMISSION_REVIEW_REQUIRED;
-
-        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
-                | FLAG_PERMISSION_POLICY_FIXED;
-
-        boolean writeInstallPermissions = false;
-        boolean writeRuntimePermissions = false;
-
-        final int permissionCount = ps.pkg.requestedPermissions.size();
-        for (int i = 0; i < permissionCount; i++) {
-            final String permName = ps.pkg.requestedPermissions.get(i);
-            final BasePermission bp =
-                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
-            if (bp == null) {
-                continue;
-            }
-
-            if (bp.isRemoved()) {
-                continue;
-            }
-
-            // If shared user we just reset the state to which only this app contributed.
-            if (ps.sharedUser != null) {
-                boolean used = false;
-                final int packageCount = ps.sharedUser.packages.size();
-                for (int j = 0; j < packageCount; j++) {
-                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
-                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
-                            && pkg.pkg.requestedPermissions.contains(permName)) {
-                        used = true;
-                        break;
-                    }
-                }
-                if (used) {
-                    continue;
-                }
-            }
-
-            final PermissionsState permissionsState = ps.getPermissionsState();
-
-            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
-
-            // Always clear the user settable flags.
-            final boolean hasInstallState =
-                    permissionsState.getInstallPermissionState(permName) != null;
-            // If permission review is enabled and this is a legacy app, mark the
-            // permission as requiring a review as this is the initial state.
-            int flags = 0;
-            if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) {
-                flags |= FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
-            }
-            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
-                if (hasInstallState) {
-                    writeInstallPermissions = true;
-                } else {
-                    writeRuntimePermissions = true;
-                }
-            }
-
-            // Below is only runtime permission handling.
-            if (!bp.isRuntime()) {
-                continue;
-            }
-
-            // Never clobber system or policy.
-            if ((oldFlags & policyOrSystemFlags) != 0) {
-                continue;
-            }
-
-            // If this permission was granted by default, make sure it is.
-            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
-                if (permissionsState.grantRuntimePermission(bp, userId)
-                        != PERMISSION_OPERATION_FAILURE) {
-                    writeRuntimePermissions = true;
-                }
-            // If permission review is enabled the permissions for a legacy apps
-            // are represented as constantly granted runtime ones, so don't revoke.
-            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
-                // Otherwise, reset the permission.
-                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
-                switch (revokeResult) {
-                    case PERMISSION_OPERATION_SUCCESS:
-                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
-                        writeRuntimePermissions = true;
-                        final int appId = ps.appId;
-                        mHandler.post(
-                                () -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
-                    } break;
-                }
-            }
-        }
-
-        // Synchronously write as we are taking permissions away.
-        if (writeRuntimePermissions) {
-            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
-        }
-
-        // Synchronously write as we are taking permissions away.
-        if (writeInstallPermissions) {
-            mSettings.writeLPr();
-        }
-    }
-
-    /**
      * Remove entries from the keystore daemon. Will only remove it if the
      * {@code appId} is valid.
      */
@@ -20370,10 +19524,10 @@
     }
 
     private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
-        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
+        final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId);
         if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
             if (packageName.equals(defaultBrowserPackageName)) {
-                setDefaultBrowserPackageName(null, userId);
+                mPermissionManager.setDefaultBrowser(null, true, true, userId);
             }
         }
     }
@@ -20394,14 +19548,14 @@
                 mSettings.applyDefaultPreferredAppsLPw(userId);
                 clearIntentFilterVerificationsLPw(userId);
                 primeDomainVerificationsLPw(userId);
-                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
             }
+            mPermissionManager.resetAllRuntimePermissions(userId);
             updateDefaultHomeNotLocked(userId);
             // TODO: We have to reset the default SMS and Phone. This requires
             // significant refactoring to keep all default apps in the package
             // manager (cleaner but more work) or have the services provide
             // callbacks to the package manager to request a default app reset.
-            setDefaultBrowserPackageName(null, userId);
+            mPermissionManager.setDefaultBrowser(null, true, true, userId);
             resetNetworkPolicies(userId);
             synchronized (mPackages) {
                 scheduleWritePackageRestrictionsLocked(userId);
@@ -20654,17 +19808,14 @@
             parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
             restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
                     (parser1, userId1) -> {
-                        String defaultBrowser;
+                        final String defaultBrowser;
                         synchronized (mPackages) {
                             mSettings.readDefaultAppsLPw(parser1, userId1);
                             defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
                         }
                         if (defaultBrowser != null) {
-                            PackageManagerInternal.DefaultBrowserProvider provider;
-                            synchronized (mPackages) {
-                                provider = mDefaultBrowserProvider;
-                            }
-                            provider.setDefaultBrowser(defaultBrowser, userId1);
+                            mPermissionManager
+                                    .setDefaultBrowser(defaultBrowser, false, false, userId1);
                         }
                     });
         } catch (Exception e) {
@@ -20901,15 +20052,7 @@
         }
         allHomeCandidates.addAll(resolveInfos);
 
-        PackageManagerInternal.DefaultHomeProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultHomeProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "mDefaultHomeProvider is null");
-            return null;
-        }
-        String packageName = provider.getDefaultHome(userId);
+        final String packageName = mPermissionManager.getDefaultHome(userId);
         if (packageName == null) {
             return null;
         }
@@ -20962,15 +20105,7 @@
         final String packageName = preferredResolveInfo != null
                 && preferredResolveInfo.activityInfo != null
                 ? preferredResolveInfo.activityInfo.packageName : null;
-        final PackageManagerInternal.DefaultHomeProvider provider;
-        synchronized (mPackages) {
-            provider = mDefaultHomeProvider;
-        }
-        if (provider == null) {
-            Slog.e(TAG, "Default home provider has not been set");
-            return false;
-        }
-        final String currentPackageName = provider.getDefaultHome(userId);
+        final String currentPackageName = mPermissionManager.getDefaultHome(userId);
         if (TextUtils.equals(currentPackageName, packageName)) {
             return false;
         }
@@ -20980,7 +20115,7 @@
             // PermissionController manages default home directly.
             return false;
         }
-        provider.setDefaultHomeAsync(packageName, userId, (successful) -> {
+        mPermissionManager.setDefaultHome(currentPackageName, userId, (successful) -> {
             if (successful) {
                 postPreferredActivityChangedBroadcast(userId);
             }
@@ -21536,7 +20671,8 @@
         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
         // disabled after already being started.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
-                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
+                mPermissionManagerService, mContext.getContentResolver(),
+                UserHandle.USER_SYSTEM);
 
         disableSkuSpecificApps();
 
@@ -21550,8 +20686,6 @@
             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
         }
 
-        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
-
         synchronized (mPackages) {
             // Verify that all of the preferred activity components actually
             // exist.  It is possible for applications to be updated and at
@@ -21581,35 +20715,15 @@
                             mSettings.mPreferredActivities.keyAt(i));
                 }
             }
-
-            for (int userId : UserManagerService.getInstance().getUserIds()) {
-                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
-                    grantPermissionsUserIds = ArrayUtils.appendInt(
-                            grantPermissionsUserIds, userId);
-                }
-            }
         }
 
         sUserManager.systemReady();
-        // If we upgraded grant all default permissions before kicking off.
-        for (int userId : grantPermissionsUserIds) {
-            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
-        }
-
-        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
-            // If we did not grant default permissions, we preload from this the
-            // default permission exceptions lazily to ensure we don't hit the
-            // disk on a new user creation.
-            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
-        }
 
         // Now that we've scanned all packages, and granted any default
         // permissions, ensure permissions are updated. Beware of dragons if you
         // try optimizing this.
         synchronized (mPackages) {
-            mPermissionManager.updateAllPermissions(
-                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
-                    mPermissionCallback);
+            mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);
         }
 
         // Watch for external volumes that come and go over time
@@ -21703,7 +20817,7 @@
     public void onShellCommand(FileDescriptor in, FileDescriptor out,
             FileDescriptor err, String[] args, ShellCallback callback,
             ResultReceiver resultReceiver) {
-        (new PackageManagerShellCommand(this)).exec(
+        (new PackageManagerShellCommand(this, mPermissionManagerService)).exec(
                 this, in, out, err, args, callback, resultReceiver);
     }
 
@@ -22565,7 +21679,8 @@
 
                 if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
                     clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
-                            | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+                            | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
+                            | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
                 }
             }
         }
@@ -22601,8 +21716,7 @@
                 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
                         + mSdkVersion + "; regranting permissions for " + volumeUuid);
             }
-            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
-                    mPermissionCallback);
+            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated);
 
             // Yay, everything is now upgraded
             ver.forceCurrent();
@@ -23627,13 +22741,7 @@
     }
 
     void onNewUserCreated(final int userId) {
-        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
-        synchronized(mPackages) {
-            // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
-            mPermissionManager.updateAllPermissions(
-                    StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
-                    mPermissionCallback);
-        }
+        mPermissionManager.onNewUserCreated(userId);
     }
 
     @Override
@@ -23648,44 +22756,6 @@
     }
 
     @Override
-    public void setPermissionEnforced(String permission, boolean enforced) {
-        // TODO: Now that we no longer change GID for storage, this should to away.
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
-                "setPermissionEnforced");
-        if (READ_EXTERNAL_STORAGE.equals(permission)) {
-            synchronized (mPackages) {
-                if (mSettings.mReadExternalStorageEnforced == null
-                        || mSettings.mReadExternalStorageEnforced != enforced) {
-                    mSettings.mReadExternalStorageEnforced =
-                            enforced ? Boolean.TRUE : Boolean.FALSE;
-                    mSettings.writeLPr();
-                }
-            }
-            // kill any non-foreground processes so we restart them and
-            // grant/revoke the GID.
-            final IActivityManager am = ActivityManager.getService();
-            if (am != null) {
-                final long token = Binder.clearCallingIdentity();
-                try {
-                    am.killProcessesBelowForeground("setPermissionEnforcement");
-                } catch (RemoteException e) {
-                } finally {
-                    Binder.restoreCallingIdentity(token);
-                }
-            }
-        } else {
-            throw new IllegalArgumentException("No selective enforcement for " + permission);
-        }
-    }
-
-    @Override
-    @Deprecated
-    public boolean isPermissionEnforced(String permission) {
-        // allow instant applications
-        return true;
-    }
-
-    @Override
     public boolean isStorageLow() {
         // allow instant applications
         final long token = Binder.clearCallingIdentity();
@@ -23966,59 +23036,6 @@
         }
     }
 
-    private final static class OnPermissionChangeListeners extends Handler {
-        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
-
-        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
-                new RemoteCallbackList<>();
-
-        public OnPermissionChangeListeners(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_ON_PERMISSIONS_CHANGED: {
-                    final int uid = msg.arg1;
-                    handleOnPermissionsChanged(uid);
-                } break;
-            }
-        }
-
-        public void addListenerLocked(IOnPermissionsChangeListener listener) {
-            mPermissionListeners.register(listener);
-
-        }
-
-        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
-            mPermissionListeners.unregister(listener);
-        }
-
-        public void onPermissionsChanged(int uid) {
-            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
-                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
-            }
-        }
-
-        private void handleOnPermissionsChanged(int uid) {
-            final int count = mPermissionListeners.beginBroadcast();
-            try {
-                for (int i = 0; i < count; i++) {
-                    IOnPermissionsChangeListener callback = mPermissionListeners
-                            .getBroadcastItem(i);
-                    try {
-                        callback.onPermissionsChanged(uid);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Permission listener is dead", e);
-                    }
-                }
-            } finally {
-                mPermissionListeners.finishBroadcast();
-            }
-        }
-    }
-
     private class PackageManagerNative extends IPackageManagerNative.Stub {
         @Override
         public String[] getNamesForUids(int[] uids) throws RemoteException {
@@ -24110,13 +23127,6 @@
 
     private class PackageManagerInternalImpl extends PackageManagerInternal {
         @Override
-        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
-                int flagValues, int userId) {
-            PackageManagerService.this.updatePermissionFlags(
-                    permName, packageName, flagMask, flagValues, true, userId);
-        }
-
-        @Override
         public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
                 int callingUid) {
             return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
@@ -24197,11 +23207,6 @@
         }
 
         @Override
-        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
-            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
-        }
-
-        @Override
         public boolean isInstantApp(String packageName, int userId) {
             return PackageManagerService.this.isInstantApp(packageName, userId);
         }
@@ -24214,8 +23219,20 @@
         @Override
         public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
             synchronized (mPackages) {
-                return PackageManagerService.this.filterAppAccessLPr(
-                        (PackageSetting) pkg.mExtras, callingUid, userId);
+                return PackageManagerService.this
+                        .filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid, userId);
+            }
+        }
+
+        @Override
+        public boolean filterAppAccess(String packageName, int callingUid, int userId) {
+            synchronized (mPackages) {
+                final PackageParser.Package pkg = mPackages.get(packageName);
+                if (pkg == null) {
+                    return false;
+                }
+                return PackageManagerService.this
+                        .filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid, userId);
             }
         }
 
@@ -24229,6 +23246,19 @@
         }
 
         @Override
+        public PackageParser.Package getPackage(int uid) {
+            synchronized (mPackages) {
+                final String[] packageNames = getPackagesForUid(uid);
+                PackageParser.Package pkg = null;
+                final int numPackages = packageNames == null ? 0 : packageNames.length;
+                for (int i = 0; pkg == null && i < numPackages; i++) {
+                    pkg = mPackages.get(packageNames[i]);
+                }
+                return pkg;
+            }
+        }
+
+        @Override
         public PackageList getPackageList(PackageListObserver observer) {
             synchronized (mPackages) {
                 final int N = mPackages.size();
@@ -24269,7 +23299,7 @@
         public String getKnownPackageName(int knownPackage, int userId) {
             switch(knownPackage) {
                 case PackageManagerInternal.PACKAGE_BROWSER:
-                    return getDefaultBrowserPackageName(userId);
+                    return mPermissionManager.getDefaultBrowser(userId);
                 case PackageManagerInternal.PACKAGE_INSTALLER:
                     return mRequiredInstallerPackage;
                 case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
@@ -24303,37 +23333,6 @@
         }
 
         @Override
-        public void setLocationPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
-        }
-
-        @Override
-        public void setLocationExtraPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionPolicy.setLocationExtraPackagesProvider(provider);
-        }
-
-        @Override
-        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
-        }
-
-        @Override
-        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
-            mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
-        }
-
-        @Override
-        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
-            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
-        }
-
-        @Override
-        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
-            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
-                    packageName, userId);
-        }
-
-        @Override
         public void setKeepUninstalledPackages(final List<String> packageList) {
             Preconditions.checkNotNull(packageList);
             List<String> removedFromList = null;
@@ -24364,8 +23363,12 @@
         @Override
         public boolean isPermissionsReviewRequired(String packageName, int userId) {
             synchronized (mPackages) {
-                return mPermissionManager.isPermissionsReviewRequired(
-                        mPackages.get(packageName), userId);
+                final PackageParser.Package pkg = mPackages.get(packageName);
+                if (pkg == null) {
+                    return false;
+                }
+
+                return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
             }
         }
 
@@ -24530,22 +23533,6 @@
         }
 
         @Override
-        public void grantRuntimePermission(String packageName, String permName, int userId,
-                boolean overridePolicy) {
-            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
-                    permName, packageName, overridePolicy, getCallingUid(), userId,
-                    mPermissionCallback);
-        }
-
-        @Override
-        public void revokeRuntimePermission(String packageName, String permName, int userId,
-                boolean overridePolicy) {
-            mPermissionManager.revokeRuntimePermission(
-                    permName, packageName, overridePolicy, userId,
-                    mPermissionCallback);
-        }
-
-        @Override
         public String getNameForUid(int uid) {
             return PackageManagerService.this.getNameForUid(uid);
         }
@@ -24748,20 +23735,6 @@
         }
 
         @Override
-        public CheckPermissionDelegate getCheckPermissionDelegate() {
-            synchronized (mPackages) {
-                return PackageManagerService.this.getCheckPermissionDelegateLocked();
-            }
-        }
-
-        @Override
-        public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
-            synchronized (mPackages) {
-                PackageManagerService.this.setCheckPermissionDelegateLocked(delegate);
-            }
-        }
-
-        @Override
         public SparseArray<String> getAppsWithSharedUserIds() {
             synchronized (mPackages) {
                 return getAppsWithSharedUserIdsLocked();
@@ -24872,27 +23845,6 @@
         }
 
         @Override
-        public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
-            synchronized (mPackages) {
-                mDefaultBrowserProvider = provider;
-            }
-        }
-
-        @Override
-        public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
-            synchronized (mPackages) {
-                mDefaultDialerProvider = provider;
-            }
-        }
-
-        @Override
-        public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
-            synchronized (mPackages) {
-                mDefaultHomeProvider = provider;
-            }
-        }
-
-        @Override
         public boolean isApexPackage(String packageName) {
             return PackageManagerService.this.mApexManager.isApexPackage(packageName);
         }
@@ -24938,19 +23890,110 @@
         }
 
         @Override
-        public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
-            synchronized (mPackages) {
-                return mDefaultPermissionPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
-            }
-        }
-
-        @Override
         public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
                 @UserIdInt int userId) {
             synchronized (mPackages) {
                 mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
             }
         }
+
+        @Override
+        public void migrateLegacyObbData() {
+            try {
+                mInstaller.migrateLegacyObbData();
+            } catch (Exception e) {
+                Slog.wtf(TAG, e);
+            }
+        }
+
+        @Override
+        public void writeSettings(boolean async) {
+            synchronized (mPackages) {
+                if (async) {
+                    scheduleWriteSettingsLocked();
+                } else {
+                    mSettings.writeLPr();
+                }
+            }
+        }
+
+        @Override
+        public void writePermissionSettings(int[] userIds, boolean async) {
+            synchronized (mPackages) {
+                for (int userId : userIds) {
+                    mSettings.writeRuntimePermissionsForUserLPr(userId, !async);
+                }
+            }
+        }
+
+        @Override
+        public int getTargetSdk(int uid) {
+            int userId = UserHandle.getUserId(uid);
+
+            synchronized (mPackages) {
+                final Object obj = mSettings.getSettingLPr(UserHandle.getAppId(uid));
+                if (obj instanceof PackageSetting) {
+                    final PackageSetting ps = (PackageSetting) obj;
+                    if (!ps.getInstalled(userId)) {
+                        return 0;
+                    }
+                    return ps.pkg.applicationInfo.targetSdkVersion;
+                } else if (obj instanceof SharedUserSetting) {
+                    int maxTargetSdk = 0;
+                    final SharedUserSetting sus = (SharedUserSetting) obj;
+                    final int numPkgs = sus.packages.size();
+                    for (int i = 0; i < numPkgs; i++) {
+                        final PackageSetting ps = sus.packages.valueAt(i);
+                        if (!ps.getInstalled(userId)) {
+                            continue;
+                        }
+                        if (ps.pkg.applicationInfo.targetSdkVersion < maxTargetSdk) {
+                            continue;
+                        }
+                        maxTargetSdk = ps.pkg.applicationInfo.targetSdkVersion;
+                    }
+                    return maxTargetSdk;
+                }
+                return 0;
+            }
+        }
+
+        @Override
+        public boolean isCallerInstallerOfRecord(
+                @NonNull PackageParser.Package pkg, int callingUid) {
+            synchronized (mPackages) {
+                if (pkg == null) {
+                    return false;
+                }
+                final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
+                if (packageSetting == null) {
+                    return false;
+                }
+                final PackageSetting installerPackageSetting =
+                        mSettings.mPackages.get(packageSetting.installerPackageName);
+                return installerPackageSetting != null
+                        && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
+            }
+        }
+
+        @Override
+        public boolean areDefaultRuntimePermissionsGranted(int userId) {
+            synchronized (mPackages) {
+                return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
+            }
+        }
+
+        @Override
+        public void setReadExternalStorageEnforced(boolean enforced) {
+            synchronized (mPackages) {
+                if (mSettings.mReadExternalStorageEnforced != null
+                        && mSettings.mReadExternalStorageEnforced == enforced) {
+                    return;
+                }
+                mSettings.mReadExternalStorageEnforced = enforced ? Boolean.TRUE : Boolean.FALSE;
+                mSettings.writeLPr();
+            }
+        }
     }
 
     @GuardedBy("mPackages")
@@ -25019,83 +24062,6 @@
         }
     }
 
-    @Override
-    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
-                        packageNames, userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
-                        packageNames, userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void grantDefaultPermissionsToEnabledTelephonyDataServices(
-            String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledTelephonyDataServices");
-        synchronized (mPackages) {
-            Binder.withCleanCallingIdentity( () -> mDefaultPermissionPolicy.
-                    grantDefaultPermissionsToEnabledTelephonyDataServices(
-                            packageNames, userId));
-        }
-    }
-
-    @Override
-    public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
-            String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromDisabledTelephonyDataServices");
-        synchronized (mPackages) {
-            Binder.withCleanCallingIdentity( () -> mDefaultPermissionPolicy.
-                    revokeDefaultPermissionsFromDisabledTelephonyDataServices(
-                            packageNames, userId));
-        }
-    }
-
-    @Override
-    public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
-        enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp");
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                mDefaultPermissionPolicy.grantDefaultPermissionsToActiveLuiApp(
-                        packageName, userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
-    @Override
-    public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
-        enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps");
-        synchronized (mPackages) {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                mDefaultPermissionPolicy.revokeDefaultPermissionsFromLuiApps(packageNames, userId);
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-
     void forEachPackage(Consumer<PackageParser.Package> actionLocked) {
         synchronized (mPackages) {
             int numPackages = mPackages.size();
@@ -25120,14 +24086,6 @@
         }
     }
 
-    private static void enforceSystemOrPhoneCaller(String tag) {
-        int callingUid = Binder.getCallingUid();
-        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
-            throw new SecurityException(
-                    "Cannot call " + tag + " from UID " + callingUid);
-        }
-    }
-
     boolean isHistoricalPackageUsageAvailable() {
         return mPackageUsage.isHistoricalPackageUsageAvailable();
     }
@@ -25228,7 +24186,8 @@
             return false;
         }
         String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
-        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
+        String[] packagesDeclaringPermission =
+                mPermissionManager.getAppOpPermissionPackages(appOpPermission, callingUid);
         if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
             if (throwIfPermNotDeclared) {
                 throw new SecurityException("Need to declare " + appOpPermission
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 45b6834..4c7db9a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -62,6 +62,7 @@
 import com.android.server.EventLogTags;
 import com.android.server.pm.dex.DexManager;
 import com.android.server.pm.dex.PackageDexUsage;
+import com.android.server.pm.permission.PermissionsState;
 
 import dalvik.system.VMRuntime;
 
@@ -389,6 +390,17 @@
     }
 
     /**
+     * Enforces that the caller must be either the system process or the phone process.
+     * If not, throws a {@link SecurityException}.
+     */
+    public static void enforceSystemOrPhoneCaller(String methodName, int callingUid) {
+        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException(
+                    "Cannot call " + methodName + " from UID " + callingUid);
+        }
+    }
+
+    /**
      * Derive the value of the {@code cpuAbiOverride} based on the provided
      * value and an optional stored value from the package settings.
      */
@@ -885,4 +897,16 @@
             IoUtils.closeQuietly(source);
         }
     }
+
+    /**
+     * Returns the {@link PermissionsState} for the given package. If the {@link PermissionsState}
+     * could not be found, {@code null} will be returned.
+     */
+    public static PermissionsState getPermissionsState(PackageParser.Package pkg) {
+        final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
+        if (packageSetting == null) {
+            return null;
+        }
+        return packageSetting.getPermissionsState();
+    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 50fd8a7..85bc9f3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -87,6 +87,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
+import android.permission.IPermissionManager;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.text.TextUtils;
@@ -129,8 +130,10 @@
     private static final String STDIN_PATH = "-";
     /** Path where ART profiles snapshots are dumped for the shell user */
     private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
+    private static final int DEFAULT_WAIT_MS = 60 * 1000;
 
     final IPackageManager mInterface;
+    final IPermissionManager mPermissionManager;
     final private WeakHashMap<String, Resources> mResourceCache =
             new WeakHashMap<String, Resources>();
     int mTargetUser;
@@ -138,8 +141,10 @@
     boolean mComponents;
     int mQueryFlags;
 
-    PackageManagerShellCommand(PackageManagerService service) {
+    PackageManagerShellCommand(
+            PackageManagerService service, IPermissionManager permissionManager) {
         mInterface = service;
+        mPermissionManager = permissionManager;
     }
 
     @Override
@@ -785,7 +790,8 @@
 
     private int runListPermissionGroups() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
-        final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
+        final List<PermissionGroupInfo> pgs =
+                mPermissionManager.getAllPermissionGroups(0).getList();
 
         final int count = pgs.size();
         for (int p = 0; p < count ; p++) {
@@ -832,7 +838,7 @@
         final ArrayList<String> groupList = new ArrayList<String>();
         if (groups) {
             final List<PermissionGroupInfo> infos =
-                    mInterface.getAllPermissionGroups(0 /*flags*/).getList();
+                    mPermissionManager.getAllPermissionGroups(0 /*flags*/).getList();
             final int count = infos.size();
             for (int i = 0; i < count; i++) {
                 groupList.add(infos.get(i).name);
@@ -1078,6 +1084,45 @@
                 return 1;
             }
             abandonSession = false;
+
+            if (!params.sessionParams.isStaged || !params.waitForStagedSessionReady) {
+                pw.println("Success");
+                return 0;
+            }
+
+            long timeoutMs = params.timeoutMs <= 0
+                    ? DEFAULT_WAIT_MS
+                    : params.timeoutMs;
+            PackageInstaller.SessionInfo si = mInterface.getPackageInstaller()
+                    .getSessionInfo(sessionId);
+            long currentTime = System.currentTimeMillis();
+            long endTime = currentTime + timeoutMs;
+            // Using a loop instead of BroadcastReceiver since we can receive session update
+            // broadcast only if packageInstallerName is "android". We can't always force
+            // "android" as packageIntallerName, e.g, rollback auto implies
+            // "-i com.android.shell".
+            while (currentTime < endTime) {
+                if (si != null
+                        && (si.isStagedSessionReady() || si.isStagedSessionFailed())) {
+                    break;
+                }
+                SystemClock.sleep(Math.min(endTime - currentTime, 100));
+                currentTime = System.currentTimeMillis();
+                si = mInterface.getPackageInstaller().getSessionInfo(sessionId);
+            }
+            if (si == null) {
+                pw.println("Failure [failed to retrieve SessionInfo]");
+                return 1;
+            }
+            if (!si.isStagedSessionReady() && !si.isStagedSessionFailed()) {
+                pw.println("Failure [timed out after " + timeoutMs + " ms]");
+                return 1;
+            }
+            if (!si.isStagedSessionReady()) {
+                pw.println("Error [" + si.getStagedSessionErrorCode() + "] ["
+                        + si.getStagedSessionErrorMessage() + "]");
+                return 1;
+            }
             pw.println("Success");
             return 0;
         } finally {
@@ -1952,15 +1997,15 @@
         }
 
         if (grant) {
-            mInterface.grantRuntimePermission(pkg, perm, userId);
+            mPermissionManager.grantRuntimePermission(pkg, perm, userId);
         } else {
-            mInterface.revokeRuntimePermission(pkg, perm, userId);
+            mPermissionManager.revokeRuntimePermission(pkg, perm, userId);
         }
         return 0;
     }
 
     private int runResetPermissions() throws RemoteException {
-        mInterface.resetRuntimePermissions();
+        mPermissionManager.resetRuntimePermissions();
         return 0;
     }
 
@@ -1975,7 +2020,7 @@
             getErrPrintWriter().println("Error: no enforcement specified");
             return 1;
         }
-        mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
+        mPermissionManager.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
         return 0;
     }
 
@@ -1997,10 +2042,10 @@
         }
     }
 
-    private boolean isProductServicesApp(String pkg) {
+    private boolean isSystemExtApp(String pkg) {
         try {
             final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
-            return info != null && info.applicationInfo.isProductServices();
+            return info != null && info.applicationInfo.isSystemExt();
         } catch (RemoteException e) {
             return false;
         }
@@ -2018,9 +2063,9 @@
             privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
         } else if (isProductApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
-        } else if (isProductServicesApp(pkg)) {
+        } else if (isSystemExtApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance()
-                    .getProductServicesPrivAppPermissions(pkg);
+                    .getSystemExtPrivAppPermissions(pkg);
         } else {
             privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
         }
@@ -2042,9 +2087,9 @@
             privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
         } else if (isProductApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
-        } else if (isProductServicesApp(pkg)) {
+        } else if (isSystemExtApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance()
-                    .getProductServicesPrivAppDenyPermissions(pkg);
+                    .getSystemExtPrivAppDenyPermissions(pkg);
         } else {
             privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
         }
@@ -2368,6 +2413,8 @@
         SessionParams sessionParams;
         String installerPackageName;
         int userId = UserHandle.USER_ALL;
+        boolean waitForStagedSessionReady = false;
+        long timeoutMs = DEFAULT_WAIT_MS;
     }
 
     private InstallParams makeInstallParams() {
@@ -2493,6 +2540,14 @@
                     }
                     sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
                     break;
+                case "--wait":
+                    params.waitForStagedSessionReady = true;
+                    try {
+                        params.timeoutMs = Long.parseLong(peekNextArg());
+                        getNextArg();
+                    } catch (NumberFormatException ignore) {
+                    }
+                    break;
                 default:
                     throw new IllegalArgumentException("Unknown option " + opt);
             }
@@ -2883,8 +2938,8 @@
                 }
                 prefix = "  ";
             }
-            List<PermissionInfo> ps =
-                    mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
+            List<PermissionInfo> ps = mPermissionManager
+                    .queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
             final int count = ps.size();
             boolean first = true;
             for (int p = 0 ; p < count ; p++) {
@@ -3048,7 +3103,8 @@
         pw.println("       [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
         pw.println("       [--preload] [--instantapp] [--full] [--dont-kill]");
         pw.println("       [--enable-rollback]");
-        pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [--apex]");
+        pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
+        pw.println("       [--apex] [--wait TIMEOUT]");
         pw.println("       [PATH|-]");
         pw.println("    Install an application.  Must provide the apk data to install, either as a");
         pw.println("    file path or '-' to read from stdin.  Options are:");
@@ -3078,6 +3134,9 @@
         pw.println("          3=device setup, 4=user request");
         pw.println("      --force-uuid: force install on to disk volume with given UUID");
         pw.println("      --apex: install an .apex file, not an .apk");
+        pw.println("      --wait: when performing staged install, wait TIMEOUT milliseconds");
+        pw.println("          for pre-reboot verification to complete. If TIMEOUT is not");
+        pw.println("          specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds.");
         pw.println("");
         pw.println("  install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
         pw.println("       [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index e859893..4ea8a30 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -148,8 +148,8 @@
         return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
     }
 
-    public boolean isProductServices() {
-        return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+    public boolean isSystemExt() {
+        return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     public boolean isOdm() {
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index a24818f..ec9746d 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -63,7 +63,7 @@
                 | ApplicationInfo.PRIVATE_FLAG_OEM
                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
-                | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+                | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
                 | 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 11a8f4b..3bc2236 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -774,7 +774,7 @@
                 | ApplicationInfo.PRIVATE_FLAG_OEM
                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
-                | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+                | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
                 | ApplicationInfo.PRIVATE_FLAG_ODM);
         pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
         pkgSetting.pkgPrivateFlags |=
@@ -786,7 +786,7 @@
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT;
         pkgSetting.pkgPrivateFlags |=
-                pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+                pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM;
         pkgSetting.primaryCpuAbiString = primaryCpuAbi;
@@ -4413,7 +4413,7 @@
             ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
             ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
             ApplicationInfo.PRIVATE_FLAG_PRODUCT, "PRODUCT",
-            ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES, "PRODUCT_SERVICES",
+            ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT, "SYSTEM_EXT",
             ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
             ApplicationInfo.PRIVATE_FLAG_ODM, "ODM",
     };
diff --git a/services/core/java/com/android/server/pm/ShareTargetInfo.java b/services/core/java/com/android/server/pm/ShareTargetInfo.java
index 9e8b73e..fdfee77 100644
--- a/services/core/java/com/android/server/pm/ShareTargetInfo.java
+++ b/services/core/java/com/android/server/pm/ShareTargetInfo.java
@@ -15,12 +15,36 @@
  */
 package com.android.server.pm;
 
+import android.annotation.NonNull;
 import android.text.TextUtils;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
 /**
  * Represents a Share Target definition, read from the application's manifest (shortcuts.xml)
  */
 class ShareTargetInfo {
+
+    private static final String TAG_SHARE_TARGET = "share-target";
+    private static final String ATTR_TARGET_CLASS = "targetClass";
+
+    private static final String TAG_DATA = "data";
+    private static final String ATTR_SCHEME = "scheme";
+    private static final String ATTR_HOST = "host";
+    private static final String ATTR_PORT = "port";
+    private static final String ATTR_PATH = "path";
+    private static final String ATTR_PATH_PATTERN = "pathPattern";
+    private static final String ATTR_PATH_PREFIX = "pathPrefix";
+    private static final String ATTR_MIME_TYPE = "mimeType";
+
+    private static final String TAG_CATEGORY = "category";
+    private static final String ATTR_NAME = "name";
+
     static class TargetData {
         final String mScheme;
         final String mHost;
@@ -98,4 +122,72 @@
 
         return strBuilder.toString();
     }
+
+    void saveToXml(@NonNull XmlSerializer out) throws IOException {
+        out.startTag(null, TAG_SHARE_TARGET);
+
+        ShortcutService.writeAttr(out, ATTR_TARGET_CLASS, mTargetClass);
+
+        for (int i = 0; i < mTargetData.length; i++) {
+            out.startTag(null, TAG_DATA);
+            ShortcutService.writeAttr(out, ATTR_SCHEME, mTargetData[i].mScheme);
+            ShortcutService.writeAttr(out, ATTR_HOST, mTargetData[i].mHost);
+            ShortcutService.writeAttr(out, ATTR_PORT, mTargetData[i].mPort);
+            ShortcutService.writeAttr(out, ATTR_PATH, mTargetData[i].mPath);
+            ShortcutService.writeAttr(out, ATTR_PATH_PATTERN, mTargetData[i].mPathPattern);
+            ShortcutService.writeAttr(out, ATTR_PATH_PREFIX, mTargetData[i].mPathPrefix);
+            ShortcutService.writeAttr(out, ATTR_MIME_TYPE, mTargetData[i].mMimeType);
+            out.endTag(null, TAG_DATA);
+        }
+
+        for (int i = 0; i < mCategories.length; i++) {
+            out.startTag(null, TAG_CATEGORY);
+            ShortcutService.writeAttr(out, ATTR_NAME, mCategories[i]);
+            out.endTag(null, TAG_CATEGORY);
+        }
+
+        out.endTag(null, TAG_SHARE_TARGET);
+    }
+
+    static ShareTargetInfo loadFromXml(XmlPullParser parser)
+            throws IOException, XmlPullParserException {
+        final String targetClass = ShortcutService.parseStringAttribute(parser, ATTR_TARGET_CLASS);
+        final ArrayList<ShareTargetInfo.TargetData> targetData = new ArrayList<>();
+        final ArrayList<String> categories = new ArrayList<>();
+
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+            if (type == XmlPullParser.START_TAG) {
+                switch (parser.getName()) {
+                    case TAG_DATA:
+                        targetData.add(parseTargetData(parser));
+                        break;
+                    case TAG_CATEGORY:
+                        categories.add(ShortcutService.parseStringAttribute(parser, ATTR_NAME));
+                        break;
+                }
+            } else if (type == XmlPullParser.END_TAG && parser.getName().equals(TAG_SHARE_TARGET)) {
+                break;
+            }
+        }
+        if (targetData.isEmpty() || targetClass == null || categories.isEmpty()) {
+            return null;
+        }
+        return new ShareTargetInfo(
+                targetData.toArray(new ShareTargetInfo.TargetData[targetData.size()]),
+                targetClass, categories.toArray(new String[categories.size()]));
+    }
+
+    private static ShareTargetInfo.TargetData parseTargetData(XmlPullParser parser) {
+        final String scheme = ShortcutService.parseStringAttribute(parser, ATTR_SCHEME);
+        final String host = ShortcutService.parseStringAttribute(parser, ATTR_HOST);
+        final String port = ShortcutService.parseStringAttribute(parser, ATTR_PORT);
+        final String path = ShortcutService.parseStringAttribute(parser, ATTR_PATH);
+        final String pathPattern = ShortcutService.parseStringAttribute(parser, ATTR_PATH_PATTERN);
+        final String pathPrefix = ShortcutService.parseStringAttribute(parser, ATTR_PATH_PREFIX);
+        final String mimeType = ShortcutService.parseStringAttribute(parser, ATTR_MIME_TYPE);
+
+        return new ShareTargetInfo.TargetData(scheme, host, port, path, pathPattern, pathPrefix,
+                mimeType);
+    }
 }
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index d6e87aa..06c71ba 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -73,6 +73,7 @@
     private static final String TAG_INTENT = "intent";
     private static final String TAG_EXTRAS = "extras";
     private static final String TAG_SHORTCUT = "shortcut";
+    private static final String TAG_SHARE_TARGET = "share-target";
     private static final String TAG_CATEGORIES = "categories";
     private static final String TAG_PERSON = "person";
 
@@ -1453,8 +1454,9 @@
     public void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
             throws IOException, XmlPullParserException {
         final int size = mShortcuts.size();
+        final int shareTargetSize = mShareTargets.size();
 
-        if (size == 0 && mApiCallCount == 0) {
+        if (size == 0 && shareTargetSize == 0 && mApiCallCount == 0) {
             return; // nothing to write.
         }
 
@@ -1470,6 +1472,12 @@
                     getPackageInfo().isBackupAllowed());
         }
 
+        if (!forBackup) {
+            for (int j = 0; j < shareTargetSize; j++) {
+                mShareTargets.get(j).saveToXml(out);
+            }
+        }
+
         out.endTag(null, TAG_ROOT);
     }
 
@@ -1627,6 +1635,9 @@
                         // Don't use addShortcut(), we don't need to save the icon.
                         ret.mShortcuts.put(si.getId(), si);
                         continue;
+                    case TAG_SHARE_TARGET:
+                        ret.mShareTargets.add(ShareTargetInfo.loadFromXml(parser));
+                        continue;
                 }
             }
             ShortcutService.warnForInvalidTag(depth, tag);
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 950450c..bf141a0 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -30,6 +30,7 @@
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.PackageParserException;
 import android.content.pm.PackageParser.SigningDetails;
 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
@@ -43,6 +44,7 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.util.IntArray;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.apk.ApkSignatureVerifier;
@@ -57,6 +59,7 @@
 import java.util.List;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 /**
@@ -103,21 +106,22 @@
         return new ParceledListSlice<>(result);
     }
 
-    private boolean validateApexSignature(String apexPath, String packageName) {
+    private void validateApexSignature(String apexPath, String packageName)
+            throws PackageManagerException {
         final SigningDetails signingDetails;
         try {
             signingDetails = ApkSignatureVerifier.verify(apexPath, SignatureSchemeVersion.JAR);
         } catch (PackageParserException e) {
-            Slog.e(TAG, "Unable to parse APEX package: " + apexPath, e);
-            return false;
+            throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                    "Failed to parse APEX package " + apexPath, e);
         }
 
-        final PackageInfo packageInfo = mApexManager.getPackageInfoForApexName(packageName);
-
+        final PackageInfo packageInfo = mApexManager.getPackageInfo(packageName,
+                ApexManager.MATCH_ACTIVE_PACKAGE);
         if (packageInfo == null) {
-            // Don't allow installation of new APEX.
-            Slog.e(TAG, "Attempted to install a new apex " + packageName + ". Rejecting");
-            return false;
+            // This should never happen, because submitSessionToApexService ensures that no new
+            // apexes were installed.
+            throw new IllegalStateException("Unknown apex package " + packageName);
         }
 
         final SigningDetails existingSigningDetails;
@@ -125,73 +129,95 @@
             existingSigningDetails = ApkSignatureVerifier.verify(
                 packageInfo.applicationInfo.sourceDir, SignatureSchemeVersion.JAR);
         } catch (PackageParserException e) {
-            Slog.e(TAG, "Unable to parse APEX package: "
-                    + packageInfo.applicationInfo.sourceDir, e);
-            return false;
+            throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                    "Failed to parse APEX package " + packageInfo.applicationInfo.sourceDir, e);
         }
 
         // Now that we have both sets of signatures, demand that they're an exact match.
         if (Signature.areExactMatch(existingSigningDetails.signatures, signingDetails.signatures)) {
-            return true;
+            return;
         }
 
-        return false;
+        throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                "APK-container signature verification failed for package "
+                        + packageName + ". Signature of file "
+                        + apexPath + " does not match the signature of "
+                        + " the package already installed.");
     }
 
-    private boolean submitSessionToApexService(@NonNull PackageInstallerSession session,
-                                               List<PackageInstallerSession> childSessions,
-                                               ApexInfoList apexInfoList) {
-        boolean submittedToApexd = mApexManager.submitStagedSession(
-                session.sessionId,
-                childSessions != null
-                        ? childSessions.stream().mapToInt(s -> s.sessionId).toArray() :
-                        new int[]{},
-                apexInfoList);
-        if (!submittedToApexd) {
-            session.setStagedSessionFailed(
-                    SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
-                    "APEX staging failed, check logcat messages from apexd for more details.");
-            return false;
-        }
-        for (ApexInfo newPackage : apexInfoList.apexInfos) {
-            PackageInfo activePackage = mApexManager.getPackageInfoForApexName(
-                    newPackage.packageName);
-            if (activePackage == null) {
-                continue;
+    private List<PackageInfo> submitSessionToApexService(
+            @NonNull PackageInstallerSession session) throws PackageManagerException {
+        final IntArray childSessionsIds = new IntArray();
+        if (session.isMultiPackage()) {
+            for (int id : session.getChildSessionIds()) {
+                if (isApexSession(mStagedSessions.get(id))) {
+                    childSessionsIds.add(id);
+                }
             }
-            long activeVersion = activePackage.applicationInfo.longVersionCode;
-            if (session.params.requiredInstalledVersionCode
-                    != PackageManager.VERSION_CODE_HIGHEST) {
-                if (activeVersion != session.params.requiredInstalledVersionCode) {
-                    session.setStagedSessionFailed(
-                            SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
-                            "Installed version of APEX package " + newPackage.packageName
+        }
+        // submitStagedSession will throw a PackageManagerException if apexd verification fails,
+        // which will be propagated to populate stagedSessionErrorMessage of this session.
+        final ApexInfoList apexInfoList = mApexManager.submitStagedSession(session.sessionId,
+                childSessionsIds.toArray());
+        final List<PackageInfo> result = new ArrayList<>();
+        for (ApexInfo newPackage : apexInfoList.apexInfos) {
+            final PackageInfo pkg;
+            try {
+                pkg = PackageParser.generatePackageInfoFromApex(newPackage,
+                        PackageManager.GET_META_DATA);
+            } catch (PackageParserException e) {
+                throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                        "Failed to parse APEX package " + newPackage.modulePath, e);
+            }
+            final PackageInfo activePackage = mApexManager.getPackageInfo(pkg.packageName,
+                    ApexManager.MATCH_ACTIVE_PACKAGE);
+            if (activePackage == null) {
+                Slog.w(TAG, "Attempting to install new APEX package " + pkg.packageName);
+                throw new PackageManagerException(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                        "It is forbidden to install new APEX packages.");
+            }
+            checkRequiredVersionCode(session, activePackage);
+            checkDowngrade(session, activePackage, pkg);
+            result.add(pkg);
+        }
+        return result;
+    }
+
+    private void checkRequiredVersionCode(final PackageInstallerSession session,
+            final PackageInfo activePackage) throws PackageManagerException {
+        if (session.params.requiredInstalledVersionCode == PackageManager.VERSION_CODE_HIGHEST) {
+            return;
+        }
+        final long activeVersion = activePackage.applicationInfo.longVersionCode;
+        if (activeVersion != session.params.requiredInstalledVersionCode) {
+            if (!mApexManager.abortActiveSession()) {
+                Slog.e(TAG, "Failed to abort apex session " + session.sessionId);
+            }
+            throw new PackageManagerException(
+                    SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                    "Installed version of APEX package " + activePackage.packageName
                             + " does not match required. Active version: " + activeVersion
                             + " required: " + session.params.requiredInstalledVersionCode);
-
-                    if (!mApexManager.abortActiveSession()) {
-                        Slog.e(TAG, "Failed to abort apex session " + session.sessionId);
-                    }
-                    return false;
-                }
-            }
-
-            boolean allowsDowngrade = PackageManagerServiceUtils.isDowngradePermitted(
-                    session.params.installFlags, activePackage.applicationInfo.flags);
-            if (activeVersion > newPackage.versionCode && !allowsDowngrade) {
-                session.setStagedSessionFailed(
-                        SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
-                        "Downgrade of APEX package " + newPackage.packageName
-                                + " is not allowed. Active version: " + activeVersion
-                                + " attempted: " + newPackage.versionCode);
-
-                if (!mApexManager.abortActiveSession()) {
-                    Slog.e(TAG, "Failed to abort apex session " + session.sessionId);
-                }
-                return false;
-            }
         }
-        return true;
+    }
+
+    private void checkDowngrade(final PackageInstallerSession session,
+            final PackageInfo activePackage, final PackageInfo newPackage)
+            throws PackageManagerException {
+        final long activeVersion = activePackage.applicationInfo.longVersionCode;
+        final long newVersionCode = newPackage.applicationInfo.longVersionCode;
+        boolean allowsDowngrade = PackageManagerServiceUtils.isDowngradePermitted(
+                session.params.installFlags, activePackage.applicationInfo.flags);
+        if (activeVersion > newVersionCode && !allowsDowngrade) {
+            if (!mApexManager.abortActiveSession()) {
+                Slog.e(TAG, "Failed to abort apex session " + session.sessionId);
+            }
+            throw new PackageManagerException(
+                    SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
+                    "Downgrade of APEX package " + newPackage.packageName
+                            + " is not allowed. Active version: " + activeVersion
+                            + " attempted: " + newVersionCode);
+        }
     }
 
     private static boolean isApexSession(@NonNull PackageInstallerSession session) {
@@ -199,53 +225,29 @@
     }
 
     private void preRebootVerification(@NonNull PackageInstallerSession session) {
-        boolean success = true;
-
-        // STOPSHIP: TODO(b/123753157): Verify APKs through Package Verifier.
-        // TODO: Decide whether we want to fail fast by detecting signature mismatches for APKs,
-        // right away.
-
-        final ApexInfoList apexInfoList = new ApexInfoList();
+        final boolean hasApex = sessionContainsApex(session);
         // APEX checks. For single-package sessions, check if they contain an APEX. For
         // multi-package sessions, find all the child sessions that contain an APEX.
-        if (!session.isMultiPackage()
-                && isApexSession(session)) {
-            success = submitSessionToApexService(session, null, apexInfoList);
-
-        } else if (session.isMultiPackage()) {
-            List<PackageInstallerSession> childSessions =
-                    Arrays.stream(session.getChildSessionIds())
-                            // Retrieve cached sessions matching ids.
-                            .mapToObj(i -> mStagedSessions.get(i))
-                            // Filter only the ones containing APEX.
-                            .filter(childSession -> isApexSession(childSession))
-                            .collect(Collectors.toList());
-            if (!childSessions.isEmpty()) {
-                success = submitSessionToApexService(session, childSessions, apexInfoList);
-            } // else this is a staged multi-package session with no APEX files.
-        }
-
-        if (!success) {
-            // submitSessionToApexService will populate error.
-            return;
-        }
-
-        if (apexInfoList.apexInfos != null && apexInfoList.apexInfos.length > 0) {
-            // For APEXes, we validate the signature here before we mark the session as ready,
-            // so we fail the session early if there is a signature mismatch. For APKs, the
-            // signature verification will be done by the package manager at the point at which
-            // it applies the staged install.
-            for (ApexInfo apexPackage : apexInfoList.apexInfos) {
-                if (!validateApexSignature(apexPackage.packagePath,
-                        apexPackage.packageName)) {
-                    session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
-                            "APK-container signature verification failed for package "
-                                    + apexPackage.packageName + ". Signature of file "
-                                    + apexPackage.packagePath + " does not match the signature of "
-                                    + " the package already installed.");
-                    // TODO(b/118865310): abort the session on apexd.
-                    return;
+        if (hasApex) {
+            try {
+                final List<PackageInfo> apexPackages = submitSessionToApexService(session);
+                for (PackageInfo apexPackage : apexPackages) {
+                    validateApexSignature(apexPackage.applicationInfo.sourceDir,
+                            apexPackage.packageName);
                 }
+            } catch (PackageManagerException e) {
+                session.setStagedSessionFailed(e.error, e.getMessage());
+                return;
+            }
+        }
+
+        if (sessionContainsApk(session)) {
+            try {
+                installApksInSession(session, /* preReboot */ true);
+                // TODO(b/118865310): abort the session on apexd.
+            } catch (PackageManagerException e) {
+                session.setStagedSessionFailed(e.error, e.getMessage());
+                return;
             }
         }
 
@@ -266,32 +268,54 @@
             }
         }
 
+        // Proactively mark session as ready before calling apexd. Although this call order looks
+        // counter-intuitive, this is the easiest way to ensure that session won't end up in the
+        // inconsistent state:
+        //  - If device gets rebooted right before call to apexd, then apexd will never activate
+        //      apex files of this staged session. This will result in StagingManager failing the
+        //      session.
+        // On the other hand, if the order of the calls was inverted (first call apexd, then mark
+        // session as ready), then if a device gets rebooted right after the call to apexd, only
+        // apex part of the train will be applied, leaving device in an inconsistent state.
         session.setStagedSessionReady();
-        if (sessionContainsApex(session)
-                && !mApexManager.markStagedSessionReady(session.sessionId)) {
-            session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
-                            "APEX staging failed, check logcat messages from apexd for more "
-                            + "details.");
+        if (!hasApex) {
+            // Session doesn't contain apex, nothing to do.
+            return;
+        }
+        try {
+            mApexManager.markStagedSessionReady(session.sessionId);
+        } catch (PackageManagerException e) {
+            session.setStagedSessionFailed(e.error, e.getMessage());
         }
     }
 
-    private boolean sessionContainsApex(@NonNull PackageInstallerSession session) {
+
+    private boolean sessionContains(@NonNull PackageInstallerSession session,
+                                    Predicate<PackageInstallerSession> filter) {
         if (!session.isMultiPackage()) {
-            return isApexSession(session);
+            return filter.test(session);
         }
         synchronized (mStagedSessions) {
             return !(Arrays.stream(session.getChildSessionIds())
                     // Retrieve cached sessions matching ids.
                     .mapToObj(i -> mStagedSessions.get(i))
                     // Filter only the ones containing APEX.
-                    .filter(childSession -> isApexSession(childSession))
+                    .filter(childSession -> filter.test(childSession))
                     .collect(Collectors.toList())
                     .isEmpty());
         }
     }
 
+    private boolean sessionContainsApex(@NonNull PackageInstallerSession session) {
+        return sessionContains(session, (s) -> isApexSession(s));
+    }
+
+    private boolean sessionContainsApk(@NonNull PackageInstallerSession session) {
+        return sessionContains(session, (s) -> !isApexSession(s));
+    }
+
     private void resumeSession(@NonNull PackageInstallerSession session) {
-        boolean hasApex = sessionContainsApex(session);
+        final boolean hasApex = sessionContainsApex(session);
         if (hasApex) {
             // Check with apexservice whether the apex packages have been activated.
             ApexSessionInfo apexSessionInfo = mApexManager.getStagedSessionInfo(session.sessionId);
@@ -326,10 +350,10 @@
             }
         }
         // The APEX part of the session is activated, proceed with the installation of APKs.
-        if (!installApksInSession(session)) {
-            session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
-                    "Staged installation of APKs failed. Check logcat messages for"
-                        + "more information.");
+        try {
+            installApksInSession(session, /* preReboot */ false);
+        } catch (PackageManagerException e) {
+            session.setStagedSessionFailed(e.error, e.getMessage());
 
             if (!hasApex) {
                 return;
@@ -343,7 +367,6 @@
                                 + "to the previous state of APEXd.");
                 mPowerManager.reboot(null);
             }
-
             return;
         }
 
@@ -365,23 +388,34 @@
         return ret;
     }
 
+    @NonNull
     private PackageInstallerSession createAndWriteApkSession(
-            @NonNull PackageInstallerSession originalSession) {
+            @NonNull PackageInstallerSession originalSession, boolean preReboot)
+            throws PackageManagerException {
+        final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
+                : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
         if (originalSession.stageDir == null) {
             Slog.wtf(TAG, "Attempting to install a staged APK session with no staging dir");
-            return null;
+            throw new PackageManagerException(errorCode,
+                    "Attempting to install a staged APK session with no staging dir");
         }
         List<String> apkFilePaths = findAPKsInDir(originalSession.stageDir);
         if (apkFilePaths.isEmpty()) {
             Slog.w(TAG, "Can't find staged APK in " + originalSession.stageDir.getAbsolutePath());
-            return null;
+            throw new PackageManagerException(errorCode,
+                    "Can't find staged APK in " + originalSession.stageDir.getAbsolutePath());
         }
 
         PackageInstaller.SessionParams params = originalSession.params.copy();
         params.isStaged = false;
-        params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
         params.installFlags |= PackageManager.INSTALL_STAGED;
         // TODO(b/129744602): use the userid from the original session.
+        if (preReboot) {
+            params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
+            params.installFlags |= PackageManager.INSTALL_DRY_RUN;
+        } else {
+            params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
+        }
         int apkSessionId = mPi.createSession(
                 params, originalSession.getInstallerPackageName(),
                 0 /* UserHandle.SYSTEM */);
@@ -396,29 +430,33 @@
                 long sizeBytes = pfd.getStatSize();
                 if (sizeBytes < 0) {
                     Slog.e(TAG, "Unable to get size of: " + apkFilePath);
-                    return null;
+                    throw new PackageManagerException(errorCode,
+                            "Unable to get size of: " + apkFilePath);
                 }
                 apkSession.write(apkFile.getName(), 0, sizeBytes, pfd);
             }
         } catch (IOException e) {
             Slog.e(TAG, "Failure to install APK staged session " + originalSession.sessionId, e);
-            return null;
+            throw new PackageManagerException(errorCode, "Failed to write APK session", e);
         }
         return apkSession;
     }
 
-    private boolean commitApkSession(@NonNull PackageInstallerSession apkSession,
-                                     int originalSessionId) {
-
-        if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
-            // If rollback is available for this session, notify the rollback
-            // manager of the apk session so it can properly enable rollback.
-            final IRollbackManager rm = IRollbackManager.Stub.asInterface(
-                    ServiceManager.getService(Context.ROLLBACK_SERVICE));
-            try {
-                rm.notifyStagedApkSession(originalSessionId, apkSession.sessionId);
-            } catch (RemoteException re) {
-                // Cannot happen, the rollback manager is in the same process.
+    private void commitApkSession(@NonNull PackageInstallerSession apkSession,
+            int originalSessionId, boolean preReboot) throws PackageManagerException {
+        final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
+                : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
+        if (!preReboot) {
+            if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
+                // If rollback is available for this session, notify the rollback
+                // manager of the apk session so it can properly enable rollback.
+                final IRollbackManager rm = IRollbackManager.Stub.asInterface(
+                        ServiceManager.getService(Context.ROLLBACK_SERVICE));
+                try {
+                    rm.notifyStagedApkSession(originalSessionId, apkSession.sessionId);
+                } catch (RemoteException re) {
+                    // Cannot happen, the rollback manager is in the same process.
+                }
             }
         }
 
@@ -427,22 +465,24 @@
         final Intent result = receiver.getResult();
         final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
                 PackageInstaller.STATUS_FAILURE);
-        if (status == PackageInstaller.STATUS_SUCCESS) {
-            return true;
+        if (status != PackageInstaller.STATUS_SUCCESS) {
+
+            final String errorMessage = result.getStringExtra(
+                    PackageInstaller.EXTRA_STATUS_MESSAGE);
+            Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " ["
+                    + errorMessage + "]");
+            throw new PackageManagerException(errorCode, errorMessage);
         }
-        Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " ["
-                + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
-        return false;
     }
 
-    private boolean installApksInSession(@NonNull PackageInstallerSession session) {
+    private void installApksInSession(@NonNull PackageInstallerSession session,
+                                         boolean preReboot) throws PackageManagerException {
+        final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
+                : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
         if (!session.isMultiPackage() && !isApexSession(session)) {
             // APK single-packaged staged session. Do a regular install.
-            PackageInstallerSession apkSession = createAndWriteApkSession(session);
-            if (apkSession == null) {
-                return false;
-            }
-            return commitApkSession(apkSession, session.sessionId);
+            PackageInstallerSession apkSession = createAndWriteApkSession(session, preReboot);
+            commitApkSession(apkSession, session.sessionId, preReboot);
         } else if (session.isMultiPackage()) {
             // For multi-package staged sessions containing APKs, we identify which child sessions
             // contain an APK, and with those then create a new multi-package group of sessions,
@@ -460,10 +500,13 @@
             }
             if (childSessions.isEmpty()) {
                 // APEX-only multi-package staged session, nothing to do.
-                return true;
+                return;
             }
             PackageInstaller.SessionParams params = session.params.copy();
             params.isStaged = false;
+            if (preReboot) {
+                params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK;
+            }
             // TODO(b/129744602): use the userid from the original session.
             int apkParentSessionId = mPi.createSession(
                     params, session.getInstallerPackageName(),
@@ -474,25 +517,24 @@
             } catch (IOException e) {
                 Slog.e(TAG, "Unable to prepare multi-package session for staged session "
                         + session.sessionId);
-                return false;
+                throw new PackageManagerException(errorCode,
+                        "Unable to prepare multi-package session for staged session");
             }
 
             for (PackageInstallerSession sessionToClone : childSessions) {
-                PackageInstallerSession apkChildSession = createAndWriteApkSession(sessionToClone);
-                if (apkChildSession == null) {
-                    return false;
-                }
+                PackageInstallerSession apkChildSession =
+                        createAndWriteApkSession(sessionToClone, preReboot);
                 try {
                     apkParentSession.addChildSessionId(apkChildSession.sessionId);
                 } catch (IllegalStateException e) {
                     Slog.e(TAG, "Failed to add a child session for installing the APK files", e);
-                    return false;
+                    throw new PackageManagerException(errorCode,
+                            "Failed to add a child session " + apkChildSession.sessionId);
                 }
             }
-            return commitApkSession(apkParentSession, session.sessionId);
+            commitApkSession(apkParentSession, session.sessionId, preReboot);
         }
         // APEX single-package staged session, nothing to do.
-        return true;
     }
 
     void commitSession(@NonNull PackageInstallerSession session) {
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 15dc6ae..b829f0b 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -10,6 +10,16 @@
       "name": "CtsCompilationTestCases"
     }
   ],
+  "postsubmit": [
+    {
+      "name": "CtsPermissionTestCases",
+      "options": [
+        {
+            "include-filter": "android.permission.cts.PermissionUpdateListenerTest"
+        }
+      ]
+    }
+  ],
   "imports": [
     {
       "path": "frameworks/base/core/java/android/content/pm"
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 204f186..f4ba449 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -100,6 +100,7 @@
 import com.android.server.SystemService;
 import com.android.server.am.UserState;
 import com.android.server.storage.DeviceStorageMonitorInternal;
+import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import libcore.io.IoUtils;
@@ -3450,17 +3451,26 @@
         if (userInfo == null) {
             return;
         }
+        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
+        t.traceBegin("onBeforeStartUser-" + userId);
         final int userSerial = userInfo.serialNumber;
         // Migrate only if build fingerprints mismatch
         boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint);
+        t.traceBegin("prepareUserData");
         mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE);
+        t.traceEnd();
+        t.traceBegin("reconcileAppsData");
         mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE, migrateAppsData);
+        t.traceEnd();
 
         if (userId != UserHandle.USER_SYSTEM) {
+            t.traceBegin("applyUserRestrictions");
             synchronized (mRestrictionsLock) {
                 applyUserRestrictionsLR(userId);
             }
+            t.traceEnd();
         }
+        t.traceEnd(); // onBeforeStartUser
     }
 
     /**
@@ -3683,6 +3693,11 @@
 
         long now = System.currentTimeMillis();
         final long nowRealtime = SystemClock.elapsedRealtime();
+
+        final int currentUser = LocalServices.getService(ActivityManagerInternal.class)
+                .getCurrentUserId();
+        pw.print("Current user: "); pw.println(currentUser);
+
         StringBuilder sb = new StringBuilder();
         synchronized (mPackagesLock) {
             synchronized (mUsersLock) {
@@ -3696,6 +3711,7 @@
                     final int userId = userInfo.id;
                     pw.print("  "); pw.print(userInfo);
                     pw.print(" serialNo="); pw.print(userInfo.serialNumber);
+                    pw.print(" isPrimary="); pw.print(userInfo.isPrimary());
                     if (mRemovingUserIds.get(userId)) {
                         pw.print(" <removing> ");
                     }
@@ -3778,13 +3794,15 @@
             synchronized (mUserStates) {
                 pw.println("  Started users state: " + mUserStates);
             }
-            // Dump some capabilities
-            pw.println();
-            pw.println("  Max users: " + UserManager.getMaxSupportedUsers());
-            pw.println("  Supports switchable users: " + UserManager.supportsMultipleUsers());
-            pw.println("  All guests ephemeral: " + Resources.getSystem().getBoolean(
-                    com.android.internal.R.bool.config_guestUserEphemeral));
-        }
+        } // synchronized (mPackagesLock)
+
+        // Dump some capabilities
+        pw.println();
+        pw.println("  Max users: " + UserManager.getMaxSupportedUsers());
+        pw.println("  Supports switchable users: " + UserManager.supportsMultipleUsers());
+        pw.println("  All guests ephemeral: " + Resources.getSystem().getBoolean(
+                com.android.internal.R.bool.config_guestUserEphemeral));
+        pw.println("  Is split-system user: " + UserManager.isSplitSystemUser());
     }
 
     private static void dumpTimeAgo(PrintWriter pw, StringBuilder sb, long nowTime, long time) {
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 22eb9fd..fe0b3a3 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -34,8 +34,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageManagerInternal.PackagesProvider;
-import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
 import android.content.pm.PermissionInfo;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
@@ -69,6 +67,8 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.XmlUtils;
 import com.android.server.LocalServices;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.PackagesProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.SyncAdapterPackagesProvider;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -143,12 +143,6 @@
         CONTACTS_PERMISSIONS.add(Manifest.permission.GET_ACCOUNTS);
     }
 
-    private static final Set<String> LOCATION_PERMISSIONS = new ArraySet<>();
-    static {
-        LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_FINE_LOCATION);
-        LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_COARSE_LOCATION);
-    }
-
     private static final Set<String> ALWAYS_LOCATION_PERMISSIONS = new ArraySet<>();
     static {
         ALWAYS_LOCATION_PERMISSIONS.add(Manifest.permission.ACCESS_FINE_LOCATION);
@@ -453,7 +447,8 @@
         // SetupWizard
         grantPermissionsToSystemPackage(
                 getKnownPackage(PackageManagerInternal.PACKAGE_SETUP_WIZARD, userId), userId,
-                PHONE_PERMISSIONS, CONTACTS_PERMISSIONS, LOCATION_PERMISSIONS, CAMERA_PERMISSIONS);
+                PHONE_PERMISSIONS, CONTACTS_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
+                CAMERA_PERMISSIONS);
 
         // Camera
         grantPermissionsToSystemPackage(
@@ -469,7 +464,7 @@
         // Media provider
         grantSystemFixedPermissionsToSystemPackage(
                 getDefaultProviderAuthorityPackage(MediaStore.AUTHORITY, userId), userId,
-                STORAGE_PERMISSIONS, PHONE_PERMISSIONS);
+                STORAGE_PERMISSIONS);
 
         // Downloads provider
         grantSystemFixedPermissionsToSystemPackage(
@@ -585,7 +580,7 @@
         // Maps
         grantPermissionsToSystemPackage(
                 getDefaultSystemHandlerActivityPackageForCategory(Intent.CATEGORY_APP_MAPS, userId),
-                userId, LOCATION_PERMISSIONS);
+                userId, ALWAYS_LOCATION_PERMISSIONS);
 
         // Gallery
         grantPermissionsToSystemPackage(
@@ -609,14 +604,14 @@
             }
         }
         grantPermissionsToPackage(browserPackage, userId, false /* ignoreSystemPackage */,
-                true /*whitelistRestrictedPermissions*/, LOCATION_PERMISSIONS);
+                true /*whitelistRestrictedPermissions*/, ALWAYS_LOCATION_PERMISSIONS);
 
         // Voice interaction
         if (voiceInteractPackageNames != null) {
             for (String voiceInteractPackageName : voiceInteractPackageNames) {
                 grantPermissionsToSystemPackage(voiceInteractPackageName, userId,
                         CONTACTS_PERMISSIONS, CALENDAR_PERMISSIONS, MICROPHONE_PERMISSIONS,
-                        PHONE_PERMISSIONS, SMS_PERMISSIONS, LOCATION_PERMISSIONS);
+                        PHONE_PERMISSIONS, SMS_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS);
             }
         }
 
@@ -625,7 +620,7 @@
             grantPermissionsToSystemPackage(
                     getDefaultSystemHandlerActivityPackage(
                             SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId),
-                    userId, MICROPHONE_PERMISSIONS, LOCATION_PERMISSIONS);
+                    userId, MICROPHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS);
         }
 
         // Voice recognition
@@ -667,7 +662,7 @@
                 .addCategory(Intent.CATEGORY_LAUNCHER_APP);
         grantPermissionsToSystemPackage(
                 getDefaultSystemHandlerActivityPackage(homeIntent, userId), userId,
-                LOCATION_PERMISSIONS);
+                ALWAYS_LOCATION_PERMISSIONS);
 
         // Watches
         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH, 0)) {
@@ -676,18 +671,18 @@
             String wearPackage = getDefaultSystemHandlerActivityPackageForCategory(
                     Intent.CATEGORY_HOME_MAIN, userId);
             grantPermissionsToSystemPackage(wearPackage, userId,
-                    CONTACTS_PERMISSIONS, MICROPHONE_PERMISSIONS, LOCATION_PERMISSIONS);
+                    CONTACTS_PERMISSIONS, MICROPHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS);
             grantSystemFixedPermissionsToSystemPackage(wearPackage, userId, PHONE_PERMISSIONS);
 
             // Fitness tracking on watches
             grantPermissionsToSystemPackage(
                     getDefaultSystemHandlerActivityPackage(ACTION_TRACK, userId), userId,
-                    SENSORS_PERMISSIONS, LOCATION_PERMISSIONS);
+                    SENSORS_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS);
         }
 
         // Print Spooler
         grantSystemFixedPermissionsToSystemPackage(PrintManager.PRINT_SPOOLER_PACKAGE_NAME, userId,
-                LOCATION_PERMISSIONS);
+                ALWAYS_LOCATION_PERMISSIONS);
 
         // EmergencyInfo
         grantSystemFixedPermissionsToSystemPackage(
@@ -725,7 +720,7 @@
         if (!TextUtils.isEmpty(textClassifierPackageName)) {
             grantPermissionsToSystemPackage(textClassifierPackageName, userId,
                     PHONE_PERMISSIONS, SMS_PERMISSIONS, CALENDAR_PERMISSIONS,
-                    LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
+                    ALWAYS_LOCATION_PERMISSIONS, CONTACTS_PERMISSIONS);
         }
 
         // Atthention Service
@@ -835,7 +830,7 @@
         }
         for (String packageName : packageNames) {
             grantPermissionsToSystemPackage(packageName, userId,
-                    PHONE_PERMISSIONS, MICROPHONE_PERMISSIONS, LOCATION_PERMISSIONS,
+                    PHONE_PERMISSIONS, MICROPHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
                     CAMERA_PERMISSIONS, CONTACTS_PERMISSIONS);
         }
     }
@@ -850,7 +845,7 @@
             // Grant these permissions as system-fixed, so that nobody can accidentally
             // break cellular data.
             grantSystemFixedPermissionsToSystemPackage(packageName, userId,
-                    PHONE_PERMISSIONS, LOCATION_PERMISSIONS);
+                    PHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS);
         }
     }
 
@@ -864,7 +859,7 @@
             PackageInfo pkg = getSystemPackageInfo(packageName);
             if (isSystemPackage(pkg) && doesPackageSupportRuntimePermissions(pkg)) {
                 revokeRuntimePermissions(packageName, PHONE_PERMISSIONS, true, userId);
-                revokeRuntimePermissions(packageName, LOCATION_PERMISSIONS, true, userId);
+                revokeRuntimePermissions(packageName, ALWAYS_LOCATION_PERMISSIONS, true, userId);
             }
         }
     }
@@ -889,7 +884,7 @@
 
     public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
         Log.i(TAG, "Granting permissions to default browser for user:" + userId);
-        grantPermissionsToSystemPackage(packageName, userId, LOCATION_PERMISSIONS);
+        grantPermissionsToSystemPackage(packageName, userId, ALWAYS_LOCATION_PERMISSIONS);
     }
 
     private String getDefaultSystemHandlerActivityPackage(String intentAction, int userId) {
@@ -1393,8 +1388,7 @@
         if (dir.isDirectory() && dir.canRead()) {
             Collections.addAll(ret, dir.listFiles());
         }
-        dir = new File(Environment.getProductServicesDirectory(),
-                "etc/default-permissions");
+        dir = new File(Environment.getSystemExtDirectory(), "etc/default-permissions");
         if (dir.isDirectory() && dir.canRead()) {
             Collections.addAll(ret, dir.listFiles());
         }
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 bfd47fc..673ab6c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.pm.permission;
 
+import static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY;
 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
 import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
@@ -32,13 +33,17 @@
 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
 import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
+import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
+import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
 
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
 import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
 import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import static com.android.server.pm.permission.PermissionManagerService.killUid;
 import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
 
 import static java.util.concurrent.TimeUnit.SECONDS;
@@ -48,13 +53,18 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.app.ActivityManager;
 import android.app.ApplicationPackageManager;
+import android.app.IActivityManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.PermissionGroupInfoFlags;
+import android.content.pm.PackageManager.PermissionInfoFlags;
 import android.content.pm.PackageManager.PermissionWhitelistFlags;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.Package;
+import android.content.pm.ParceledListSlice;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
 import android.metrics.LogMaker;
@@ -62,22 +72,31 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
 import android.os.Process;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageManagerInternal;
+import android.permission.IOnPermissionsChangeListener;
+import android.permission.IPermissionManager;
 import android.permission.PermissionControllerManager;
 import android.permission.PermissionManager;
 import android.permission.PermissionManagerInternal;
+import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
 import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.DebugUtils;
 import android.util.EventLog;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -88,6 +107,8 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.RoSystemProperties;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.IntPair;
+import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
@@ -98,15 +119,18 @@
 import com.android.server.pm.PackageSetting;
 import com.android.server.pm.SharedUserSetting;
 import com.android.server.pm.UserManagerService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
 import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
 import com.android.server.pm.permission.PermissionsState.PermissionState;
+import com.android.server.policy.SoftRestrictedPermissionPolicy;
 
 import libcore.util.EmptyArray;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -117,11 +141,12 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
 
 /**
  * Manages all permissions and handles permissions related tasks.
  */
-public class PermissionManagerService {
+public class PermissionManagerService extends IPermissionManager.Stub {
     private static final String TAG = "PackageManager";
 
     /** Permission grant: not grant the permission. */
@@ -223,6 +248,79 @@
     final private ArrayList<OnRuntimePermissionStateChangedListener>
             mRuntimePermissionStateChangedListeners = new ArrayList<>();
 
+    @GuardedBy("mLock")
+    private CheckPermissionDelegate mCheckPermissionDelegate;
+
+    @GuardedBy("mLock")
+    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
+
+    @GuardedBy("mLock")
+    private DefaultBrowserProvider mDefaultBrowserProvider;
+
+    @GuardedBy("mLock")
+    private DefaultDialerProvider mDefaultDialerProvider;
+
+    @GuardedBy("mLock")
+    private DefaultHomeProvider mDefaultHomeProvider;
+
+    // TODO: Take a look at the methods defined in the callback.
+    // The callback was initially created to support the split between permission
+    // manager and the package manager. However, it's started to be used for other
+    // purposes. It may make sense to keep as an abstraction, but, the methods
+    // necessary to be overridden may be different than what was initially needed
+    // for the split.
+    private PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
+        @Override
+        public void onGidsChanged(int appId, int userId) {
+            mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
+        }
+        @Override
+        public void onPermissionGranted(int uid, int userId) {
+            mOnPermissionChangeListeners.onPermissionsChanged(uid);
+
+            // Not critical; if this is lost, the application has to request again.
+            mPackageManagerInt.writeSettings(true);
+        }
+        @Override
+        public void onInstallPermissionGranted() {
+            mPackageManagerInt.writeSettings(true);
+        }
+        @Override
+        public void onPermissionRevoked(int uid, int userId) {
+            mOnPermissionChangeListeners.onPermissionsChanged(uid);
+
+            // Critical; after this call the application should never have the permission
+            mPackageManagerInt.writeSettings(false);
+            final int appId = UserHandle.getAppId(uid);
+            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
+        }
+        @Override
+        public void onInstallPermissionRevoked() {
+            mPackageManagerInt.writeSettings(true);
+        }
+        @Override
+        public void onPermissionUpdated(int[] userIds, boolean sync) {
+            mPackageManagerInt.writePermissionSettings(userIds, !sync);
+        }
+        @Override
+        public void onInstallPermissionUpdated() {
+            mPackageManagerInt.writeSettings(true);
+        }
+        @Override
+        public void onPermissionRemoved() {
+            mPackageManagerInt.writeSettings(false);
+        }
+        public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
+                int uid) {
+            onPermissionUpdated(updatedUserIds, sync);
+            mOnPermissionChangeListeners.onPermissionsChanged(uid);
+        }
+        public void onInstallPermissionUpdatedNotifyListener(int uid) {
+            onInstallPermissionUpdated();
+            mOnPermissionChangeListeners.onPermissionsChanged(uid);
+        }
+    };
+
     PermissionManagerService(Context context,
             @NonNull Object externalLock) {
         mContext = context;
@@ -242,6 +340,7 @@
         SystemConfig systemConfig = SystemConfig.getInstance();
         mSystemPermissions = systemConfig.getSystemPermissions();
         mGlobalGids = systemConfig.getGlobalGids();
+        mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
 
         // propagate permission configuration
         final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
@@ -282,22 +381,423 @@
         if (permMgrInt != null) {
             return permMgrInt;
         }
-        new PermissionManagerService(context, externalLock);
+        PermissionManagerService permissionService =
+                (PermissionManagerService) ServiceManager.getService("permissionmgr");
+        if (permissionService == null) {
+            permissionService =
+                    new PermissionManagerService(context, externalLock);
+            ServiceManager.addService("permissionmgr", permissionService);
+        }
         return LocalServices.getService(PermissionManagerServiceInternal.class);
     }
 
+    /**
+     * This method should typically only be used when granting or revoking
+     * permissions, since the app may immediately restart after this call.
+     * <p>
+     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
+     * guard your work against the app being relaunched.
+     */
+    public static void killUid(int appId, int userId, String reason) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            IActivityManager am = ActivityManager.getService();
+            if (am != null) {
+                try {
+                    am.killUid(appId, userId, reason);
+                } catch (RemoteException e) {
+                    /* ignore - same process */
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     @Nullable BasePermission getPermission(String permName) {
         synchronized (mLock) {
             return mSettings.getPermissionLocked(permName);
         }
     }
 
-    private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
+    @Override
+    public String[] getAppOpPermissionPackages(String permName) {
+        return getAppOpPermissionPackagesInternal(permName, getCallingUid());
+    }
+
+    private String[] getAppOpPermissionPackagesInternal(String permName, int callingUid) {
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
+            if (pkgs == null) {
+                return null;
+            }
+            return pkgs.toArray(new String[pkgs.size()]);
+        }
+    }
+
+    @Override
+    @NonNull
+    public ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(
+            @PermissionGroupInfoFlags int flags) {
+        final int callingUid = getCallingUid();
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return ParceledListSlice.emptyList();
+        }
+        synchronized (mLock) {
+            final int n = mSettings.mPermissionGroups.size();
+            final ArrayList<PermissionGroupInfo> out =
+                    new ArrayList<PermissionGroupInfo>(n);
+            for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
+                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
+            }
+            return new ParceledListSlice<>(out);
+        }
+    }
+
+
+    @Override
+    @Nullable
+    public PermissionGroupInfo getPermissionGroupInfo(String groupName,
+            @PermissionGroupInfoFlags int flags) {
+        final int callingUid = getCallingUid();
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            return PackageParser.generatePermissionGroupInfo(
+                    mSettings.mPermissionGroups.get(groupName), flags);
+        }
+    }
+
+
+    @Override
+    @Nullable
+    public PermissionInfo getPermissionInfo(String permName, String packageName,
+            @PermissionInfoFlags int flags) {
+        final int callingUid = getCallingUid();
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            final BasePermission bp = mSettings.getPermissionLocked(permName);
+            if (bp == null) {
+                return null;
+            }
+            final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
+                    bp.getProtectionLevel(), packageName, callingUid);
+            return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
+        }
+    }
+
+    @Override
+    @Nullable
+    public ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
+            @PermissionInfoFlags int flags) {
+        final int callingUid = getCallingUid();
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
+                return null;
+            }
+            final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
+            for (BasePermission bp : mSettings.mPermissions.values()) {
+                final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
+                if (pi != null) {
+                    out.add(pi);
+                }
+            }
+            return new ParceledListSlice<>(out);
+        }
+    }
+
+    @Override
+    public boolean addPermission(PermissionInfo info, boolean async) {
+        final int callingUid = getCallingUid();
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            throw new SecurityException("Instant apps can't add permissions");
+        }
+        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
+            throw new SecurityException("Label must be specified in permission");
+        }
+        final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
+        final boolean added;
+        final boolean changed;
+        synchronized (mLock) {
+            BasePermission bp = mSettings.getPermissionLocked(info.name);
+            added = bp == null;
+            int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
+            if (added) {
+                enforcePermissionCapLocked(info, tree);
+                bp = new BasePermission(info.name, tree.getSourcePackageName(),
+                        BasePermission.TYPE_DYNAMIC);
+            } else if (!bp.isDynamic()) {
+                throw new SecurityException("Not allowed to modify non-dynamic permission "
+                        + info.name);
+            }
+            changed = bp.addToTree(fixedLevel, info, tree);
+            if (added) {
+                mSettings.putPermissionLocked(info.name, bp);
+            }
+        }
+        if (changed) {
+            mPackageManagerInt.writeSettings(async);
+        }
+        return added;
+    }
+
+    @Override
+    public void removePermission(String permName) {
+        final int callingUid = getCallingUid();
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            throw new SecurityException("Instant applications don't have access to this method");
+        }
+        final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
+        synchronized (mLock) {
+            final BasePermission bp = mSettings.getPermissionLocked(permName);
+            if (bp == null) {
+                return;
+            }
+            if (bp.isDynamic()) {
+                // TODO: switch this back to SecurityException
+                Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
+                        + permName);
+            }
+            mSettings.removePermissionLocked(permName);
+            mPackageManagerInt.writeSettings(false);
+        }
+    }
+
+    @Override
+    public int getPermissionFlags(String permName, String packageName, int userId) {
+        final int callingUid = getCallingUid();
+        return getPermissionFlagsInternal(permName, packageName, callingUid, userId);
+    }
+
+    private int getPermissionFlagsInternal(
+            String permName, String packageName, int callingUid, int userId) {
+        if (!mUserManagerInt.exists(userId)) {
+            return 0;
+        }
+
+        enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
+        enforceCrossUserPermission(callingUid, userId,
+                true,  // requireFullPermission
+                false, // checkShell
+                false, // requirePermissionWhenSameUser
+                "getPermissionFlags");
+
+        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+        if (pkg == null || pkg.mExtras == null) {
+            return 0;
+        }
+        synchronized (mLock) {
+            if (mSettings.getPermissionLocked(permName) == null) {
+                return 0;
+            }
+        }
+        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
+            return 0;
+        }
+        final PackageSetting ps = (PackageSetting) pkg.mExtras;
+        PermissionsState permissionsState = ps.getPermissionsState();
+        return permissionsState.getPermissionFlags(permName, userId);
+    }
+
+    @Override
+    public void updatePermissionFlags(String permName, String packageName, int flagMask,
+            int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
+        final int callingUid = getCallingUid();
+        boolean overridePolicy = false;
+
+        if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
+            long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
+                    if (checkAdjustPolicyFlagPermission) {
+                        mContext.enforceCallingOrSelfPermission(
+                                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
+                                "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
+                                        + " to change policy flags");
+                    } else if (mPackageManagerInt.getTargetSdk(callingUid)
+                            >= Build.VERSION_CODES.Q) {
+                        throw new IllegalArgumentException(
+                                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
+                                        + " to be checked for packages targeting "
+                                        + Build.VERSION_CODES.Q + " or later when changing policy "
+                                        + "flags");
+                    }
+                    overridePolicy = true;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+
+        updatePermissionFlagsInternal(
+                permName, packageName, flagMask, flagValues, callingUid, userId,
+                overridePolicy, mDefaultPermissionCallback);
+    }
+
+    private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
+            int flagValues, int callingUid, int userId, boolean overridePolicy,
+            PermissionCallback callback) {
+        if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
+                && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
+            Log.i(TAG, "System is updating flags for "
+                            + permName + " for user " + userId  + " "
+                            + DebugUtils.flagsToString(
+                                    PackageManager.class, "FLAG_PERMISSION_", flagMask)
+                            + " := "
+                            + DebugUtils.flagsToString(
+                                    PackageManager.class, "FLAG_PERMISSION_", flagValues)
+                            + " on behalf of uid " + callingUid
+                            + " " + mPackageManagerInt.getNameForUid(callingUid),
+                    new RuntimeException());
+        }
+
+        if (!mUserManagerInt.exists(userId)) {
+            return;
+        }
+
+        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
+
+        enforceCrossUserPermission(callingUid, userId,
+                true,  // requireFullPermission
+                true,  // checkShell
+                false, // requirePermissionWhenSameUser
+                "updatePermissionFlags");
+
+        if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
+            throw new SecurityException("updatePermissionFlags requires "
+                    + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
+        }
+
+        // Only the system can change these flags and nothing else.
+        if (callingUid != Process.SYSTEM_UID) {
+            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
+            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
+            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
+            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+            flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
+        }
+
+        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+        if (pkg == null || pkg.mExtras == null) {
+            Log.e(TAG, "Unknown package: " + packageName);
+            return;
+        }
+        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
+            throw new IllegalArgumentException("Unknown package: " + packageName);
+        }
+
+        final BasePermission bp;
+        synchronized (mLock) {
+            bp = mSettings.getPermissionLocked(permName);
+        }
+        if (bp == null) {
+            throw new IllegalArgumentException("Unknown permission: " + permName);
+        }
+
+        final PackageSetting ps = (PackageSetting) pkg.mExtras;
+        final PermissionsState permissionsState = ps.getPermissionsState();
+        final boolean hadState =
+                permissionsState.getRuntimePermissionState(permName, userId) != null;
+        final boolean permissionUpdated =
+                permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
+        if (permissionUpdated && bp.isRuntime()) {
+            notifyRuntimePermissionStateChanged(packageName, userId);
+        }
+        if (permissionUpdated && callback != null) {
+            // Install and runtime permissions are stored in different places,
+            // so figure out what permission changed and persist the change.
+            if (permissionsState.getInstallPermissionState(permName) != null) {
+                callback.onInstallPermissionUpdatedNotifyListener(pkg.applicationInfo.uid);
+            } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
+                    || hadState) {
+                callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false,
+                        pkg.applicationInfo.uid);
+            }
+        }
+    }
+
+    /**
+     * Update the permission flags for all packages and runtime permissions of a user in order
+     * to allow device or profile owner to remove POLICY_FIXED.
+     */
+    @Override
+    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
+            final int userId) {
+        final int callingUid = getCallingUid();
+        if (!mUserManagerInt.exists(userId)) {
+            return;
+        }
+
+        enforceGrantRevokeRuntimePermissionPermissions(
+                "updatePermissionFlagsForAllApps");
+        enforceCrossUserPermission(callingUid, userId,
+                true,  // requireFullPermission
+                true,  // checkShell
+                false, // requirePermissionWhenSameUser
+                "updatePermissionFlagsForAllApps");
+
+        // Only the system can change system fixed flags.
+        final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
+                ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+        final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
+                ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+
+        final boolean[] changed = new boolean[1];
+        mPackageManagerInt.forEachPackage(new Consumer<PackageParser.Package>() {
+            @Override
+            public void accept(Package pkg) {
+                final PackageSetting ps = (PackageSetting) pkg.mExtras;
+                if (ps == null) {
+                    return;
+                }
+                final PermissionsState permissionsState = ps.getPermissionsState();
+                changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
+                        userId, effectiveFlagMask, effectiveFlagValues);
+                mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
+            }
+        });
+
+        if (changed[0]) {
+            mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
+        }
+    }
+
+    @Override
+    public int checkPermission(String permName, String pkgName, int userId) {
+        final CheckPermissionDelegate checkPermissionDelegate;
+        synchronized (mLock) {
+            if (mCheckPermissionDelegate == null)  {
+                return checkPermissionImpl(permName, pkgName, userId);
+            }
+            checkPermissionDelegate = mCheckPermissionDelegate;
+        }
+        return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
+                PermissionManagerService.this::checkPermissionImpl);
+    }
+
+    private int checkPermissionImpl(String permName, String pkgName, int userId) {
+        return checkPermissionInternal(permName, pkgName, getCallingUid(), userId);
+    }
+
+    private int checkPermissionInternal(String permName, String packageName, int callingUid,
+            int userId) {
         if (!mUserManagerInt.exists(userId)) {
             return PackageManager.PERMISSION_DENIED;
         }
-
-        final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
+        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
         if (pkg != null && pkg.mExtras != null) {
             if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
                 return PackageManager.PERMISSION_DENIED;
@@ -321,12 +821,38 @@
                 return PackageManager.PERMISSION_GRANTED;
             }
         }
-
         return PackageManager.PERMISSION_DENIED;
     }
 
-    private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
-            int callingUid) {
+    @Override
+    public int checkUidPermission(String permName, int uid) {
+        final CheckPermissionDelegate checkPermissionDelegate;
+        synchronized (mLock) {
+            if (mCheckPermissionDelegate == null)  {
+                return checkUidPermissionImpl(permName, uid);
+            }
+            checkPermissionDelegate = mCheckPermissionDelegate;
+        }
+        return checkPermissionDelegate.checkUidPermission(permName, uid,
+                PermissionManagerService.this::checkUidPermissionImpl);
+    }
+
+    private int checkUidPermissionImpl(@NonNull String permName, int uid) {
+        final PackageParser.Package pkg = mPackageManagerInt.getPackage(uid);
+        synchronized (mLock) {
+            return checkUidPermissionInternal(permName, pkg, uid, getCallingUid());
+        }
+    }
+
+    /**
+     * Checks whether or not the given package has been granted the specified
+     * permission. If the given package is {@code null}, we instead check the
+     * system permissions for the given UID.
+     *
+     * @see SystemConfig#getSystemPermissions()
+     */
+    private int checkUidPermissionInternal(@NonNull String permName,
+            @Nullable PackageParser.Package pkg, int uid, int callingUid) {
         final int callingUserId = UserHandle.getUserId(callingUid);
         final boolean isCallerInstantApp =
                 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
@@ -374,6 +900,948 @@
         return PackageManager.PERMISSION_DENIED;
     }
 
+    @Override
+    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
+                "addOnPermissionsChangeListener");
+
+        synchronized (mLock) {
+            mOnPermissionChangeListeners.addListenerLocked(listener);
+        }
+    }
+
+    @Override
+    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
+        if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
+            throw new SecurityException("Instant applications don't have access to this method");
+        }
+        synchronized (mLock) {
+            mOnPermissionChangeListeners.removeListenerLocked(listener);
+        }
+    }
+
+    @Override
+    @Nullable public List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
+            @PermissionWhitelistFlags int flags, @UserIdInt int userId) {
+        Preconditions.checkNotNull(packageName);
+        Preconditions.checkFlagsArgument(flags,
+                PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
+                        | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
+                        | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
+        Preconditions.checkArgumentNonNegative(userId, null);
+
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS,
+                    "getWhitelistedRestrictedPermissions for user " + userId);
+        }
+
+        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+        if (pkg == null) {
+            return null;
+        }
+
+        final int callingUid = Binder.getCallingUid();
+        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
+            return null;
+        }
+        final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
+                Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
+                        == PackageManager.PERMISSION_GRANTED;
+        final boolean isCallerInstallerOnRecord =
+                mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
+
+        if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
+                && !isCallerPrivileged) {
+            throw new SecurityException("Querying system whitelist requires "
+                    + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
+        }
+
+        if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
+                | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
+            if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
+                throw new SecurityException("Querying upgrade or installer whitelist"
+                        + " requires being installer on record or "
+                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
+            }
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final PermissionsState permissionsState =
+                    PackageManagerServiceUtils.getPermissionsState(pkg);
+            if (permissionsState == null) {
+                return null;
+            }
+
+            int queryFlags = 0;
+            if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
+                queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+            }
+            if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
+                queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+            }
+            if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
+                queryFlags |=  PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+            }
+
+            ArrayList<String> whitelistedPermissions = null;
+
+            final int permissionCount = pkg.requestedPermissions.size();
+            for (int i = 0; i < permissionCount; i++) {
+                final String permissionName = pkg.requestedPermissions.get(i);
+                final int currentFlags =
+                        permissionsState.getPermissionFlags(permissionName, userId);
+                if ((currentFlags & queryFlags) != 0) {
+                    if (whitelistedPermissions == null) {
+                        whitelistedPermissions = new ArrayList<>();
+                    }
+                    whitelistedPermissions.add(permissionName);
+                }
+            }
+
+            return whitelistedPermissions;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
+            @NonNull String permName, @PermissionWhitelistFlags int flags,
+            @UserIdInt int userId) {
+        // Other argument checks are done in get/setWhitelistedRestrictedPermissions
+        Preconditions.checkNotNull(permName);
+
+        if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
+            return false;
+        }
+
+        List<String> permissions =
+                getWhitelistedRestrictedPermissions(packageName, flags, userId);
+        if (permissions == null) {
+            permissions = new ArrayList<>(1);
+        }
+        if (permissions.indexOf(permName) < 0) {
+            permissions.add(permName);
+            return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
+                    flags, userId);
+        }
+        return false;
+    }
+
+    private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
+            @NonNull String permName) {
+        synchronized (mLock) {
+            final BasePermission bp = mSettings.getPermissionLocked(permName);
+            if (bp == null) {
+                Slog.w(TAG, "No such permissions: " + permName);
+                return false;
+            }
+            if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
+                    && mContext.checkCallingOrSelfPermission(
+                    Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
+                    != PackageManager.PERMISSION_GRANTED) {
+                throw new SecurityException("Cannot modify whitelisting of an immutably "
+                        + "restricted permission: " + permName);
+            }
+            return true;
+        }
+    }
+
+    @Override
+    public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
+            @NonNull String permName, @PermissionWhitelistFlags int flags,
+            @UserIdInt int userId) {
+        // Other argument checks are done in get/setWhitelistedRestrictedPermissions
+        Preconditions.checkNotNull(permName);
+
+        if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
+            return false;
+        }
+
+        final List<String> permissions =
+                getWhitelistedRestrictedPermissions(packageName, flags, userId);
+        if (permissions != null && permissions.remove(permName)) {
+            return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
+                    flags, userId);
+        }
+        return false;
+    }
+
+    private boolean setWhitelistedRestrictedPermissionsInternal(@NonNull String packageName,
+            @Nullable List<String> permissions, @PermissionWhitelistFlags int flags,
+            @UserIdInt int userId) {
+        Preconditions.checkNotNull(packageName);
+        Preconditions.checkFlagsArgument(flags,
+                PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
+                        | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
+                        | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
+        Preconditions.checkArgument(Integer.bitCount(flags) == 1);
+        Preconditions.checkArgumentNonNegative(userId, null);
+
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.INTERACT_ACROSS_USERS,
+                    "setWhitelistedRestrictedPermissions for user " + userId);
+        }
+
+        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+        if (pkg == null) {
+            return false;
+        }
+
+        final int callingUid = Binder.getCallingUid();
+        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
+            return false;
+        }
+
+        final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
+                Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
+                        == PackageManager.PERMISSION_GRANTED;
+        final boolean isCallerInstallerOnRecord =
+                mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
+
+        if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
+                && !isCallerPrivileged) {
+            throw new SecurityException("Modifying system whitelist requires "
+                    + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
+        }
+
+        if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
+            if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
+                throw new SecurityException("Modifying upgrade whitelist requires"
+                        + " being installer on record or "
+                        + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
+            }
+            final List<String> whitelistedPermissions =
+                    getWhitelistedRestrictedPermissions(pkg.packageName, flags, userId);
+            if (permissions == null || permissions.isEmpty()) {
+                if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
+                    return true;
+                }
+            } else {
+                // Only the system can add and remove while the installer can only remove.
+                final int permissionCount = permissions.size();
+                for (int i = 0; i < permissionCount; i++) {
+                    if ((whitelistedPermissions == null
+                            || !whitelistedPermissions.contains(permissions.get(i)))
+                            && !isCallerPrivileged) {
+                        throw new SecurityException("Adding to upgrade whitelist requires"
+                                + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
+                    }
+                }
+            }
+
+            if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
+                if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
+                    throw new SecurityException("Modifying installer whitelist requires"
+                            + " being installer on record or "
+                            + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
+                }
+            }
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            setWhitelistedRestrictedPermissionsForUser(
+                    pkg, userId, permissions, Process.myUid(), flags, mDefaultPermissionCallback);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+        return true;
+    }
+
+    @Override
+    public void grantRuntimePermission(String packageName, String permName, final int userId) {
+        final int callingUid = Binder.getCallingUid();
+        final boolean overridePolicy =
+                checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
+                        == PackageManager.PERMISSION_GRANTED;
+
+        grantRuntimePermissionInternal(permName, packageName, overridePolicy,
+                callingUid, userId, mDefaultPermissionCallback);
+    }
+
+    // TODO swap permission name and package name
+    private void grantRuntimePermissionInternal(String permName, String packageName,
+            boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
+        if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
+                && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
+            Log.i(TAG, "System is granting "
+                    + permName + " for user " + userId + " on behalf of uid " + callingUid
+                    + " " + mPackageManagerInt.getNameForUid(callingUid),
+                    new RuntimeException());
+        }
+        if (!mUserManagerInt.exists(userId)) {
+            Log.e(TAG, "No such user:" + userId);
+            return;
+        }
+
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
+                "grantRuntimePermission");
+
+        enforceCrossUserPermission(callingUid, userId,
+                true,  // requireFullPermission
+                true,  // checkShell
+                false, // requirePermissionWhenSameUser
+                "grantRuntimePermission");
+
+        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+        if (pkg == null || pkg.mExtras == null) {
+            throw new IllegalArgumentException("Unknown package: " + packageName);
+        }
+        final BasePermission bp;
+        synchronized (mLock) {
+            bp = mSettings.getPermissionLocked(permName);
+        }
+        if (bp == null) {
+            throw new IllegalArgumentException("Unknown permission: " + permName);
+        }
+        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
+            throw new IllegalArgumentException("Unknown package: " + packageName);
+        }
+
+        bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
+
+        // If a permission review is required for legacy apps we represent
+        // their permissions as always granted runtime ones since we need
+        // to keep the review required permission flag per user while an
+        // install permission's state is shared across all users.
+        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
+                && bp.isRuntime()) {
+            return;
+        }
+
+        final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
+
+        final PackageSetting ps = (PackageSetting) pkg.mExtras;
+        final PermissionsState permissionsState = ps.getPermissionsState();
+
+        final int flags = permissionsState.getPermissionFlags(permName, userId);
+        if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
+            Log.e(TAG, "Cannot grant system fixed permission "
+                    + permName + " for package " + packageName);
+            return;
+        }
+        if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
+            Log.e(TAG, "Cannot grant policy fixed permission "
+                    + permName + " for package " + packageName);
+            return;
+        }
+
+        if (bp.isHardRestricted()
+                && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
+            Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
+                    + permName + " for package " + packageName);
+            return;
+        }
+
+        if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
+                pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
+            Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
+                    + packageName);
+            return;
+        }
+
+        if (bp.isDevelopment()) {
+            // Development permissions must be handled specially, since they are not
+            // normal runtime permissions.  For now they apply to all users.
+            if (permissionsState.grantInstallPermission(bp)
+                    != PERMISSION_OPERATION_FAILURE) {
+                if (callback != null) {
+                    callback.onInstallPermissionGranted();
+                }
+            }
+            return;
+        }
+
+        if (ps.getInstantApp(userId) && !bp.isInstant()) {
+            throw new SecurityException("Cannot grant non-ephemeral permission"
+                    + permName + " for package " + packageName);
+        }
+
+        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
+            Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
+            return;
+        }
+
+        final int result = permissionsState.grantRuntimePermission(bp, userId);
+        switch (result) {
+            case PERMISSION_OPERATION_FAILURE: {
+                return;
+            }
+
+            case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
+                if (callback != null) {
+                    callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
+                }
+            }
+            break;
+        }
+
+        if (bp.isRuntime()) {
+            logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
+        }
+
+        if (callback != null) {
+            callback.onPermissionGranted(uid, userId);
+        }
+
+        if (bp.isRuntime()) {
+            notifyRuntimePermissionStateChanged(packageName, userId);
+        }
+
+        // Only need to do this if user is initialized. Otherwise it's a new user
+        // and there are no processes running as the user yet and there's no need
+        // to make an expensive call to remount processes for the changed permissions.
+        if (READ_EXTERNAL_STORAGE.equals(permName)
+                || WRITE_EXTERNAL_STORAGE.equals(permName)) {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (mUserManagerInt.isUserInitialized(userId)) {
+                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
+                            StorageManagerInternal.class);
+                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+    }
+
+    @Override
+    public void revokeRuntimePermission(String packageName, String permName, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        final boolean overridePolicy =
+                checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
+                        == PackageManager.PERMISSION_GRANTED;
+
+        revokeRuntimePermissionInternal(permName, packageName, overridePolicy, callingUid, userId,
+                mDefaultPermissionCallback);
+    }
+
+    // TODO swap permission name and package name
+    private void revokeRuntimePermissionInternal(String permName, String packageName,
+            boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
+        if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
+                && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
+            Log.i(TAG, "System is revoking "
+                            + permName + " for user " + userId + " on behalf of uid " + callingUid
+                            + " " + mPackageManagerInt.getNameForUid(callingUid),
+                    new RuntimeException());
+        }
+        if (!mUserManagerInt.exists(userId)) {
+            Log.e(TAG, "No such user:" + userId);
+            return;
+        }
+
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+                "revokeRuntimePermission");
+
+        enforceCrossUserPermission(callingUid, userId,
+                true,  // requireFullPermission
+                true,  // checkShell
+                false, // requirePermissionWhenSameUser
+                "revokeRuntimePermission");
+
+        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+        if (pkg == null || pkg.mExtras == null) {
+            throw new IllegalArgumentException("Unknown package: " + packageName);
+        }
+        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
+            throw new IllegalArgumentException("Unknown package: " + packageName);
+        }
+        final BasePermission bp = mSettings.getPermissionLocked(permName);
+        if (bp == null) {
+            throw new IllegalArgumentException("Unknown permission: " + permName);
+        }
+
+        bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
+
+        // If a permission review is required for legacy apps we represent
+        // their permissions as always granted runtime ones since we need
+        // to keep the review required permission flag per user while an
+        // install permission's state is shared across all users.
+        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
+                && bp.isRuntime()) {
+            return;
+        }
+
+        final PackageSetting ps = (PackageSetting) pkg.mExtras;
+        final PermissionsState permissionsState = ps.getPermissionsState();
+
+        final int flags = permissionsState.getPermissionFlags(permName, userId);
+        // Only the system may revoke SYSTEM_FIXED permissions.
+        if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
+                && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
+            throw new SecurityException("Non-System UID cannot revoke system fixed permission "
+                    + permName + " for package " + packageName);
+        }
+        if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
+            throw new SecurityException("Cannot revoke policy fixed permission "
+                    + permName + " for package " + packageName);
+        }
+
+        if (bp.isDevelopment()) {
+            // Development permissions must be handled specially, since they are not
+            // normal runtime permissions.  For now they apply to all users.
+            if (permissionsState.revokeInstallPermission(bp)
+                    != PERMISSION_OPERATION_FAILURE) {
+                if (callback != null) {
+                    mDefaultPermissionCallback.onInstallPermissionRevoked();
+                }
+            }
+            return;
+        }
+
+        // Permission is already revoked, no need to do anything.
+        if (!permissionsState.hasRuntimePermission(permName, userId)) {
+            return;
+        }
+
+        if (permissionsState.revokeRuntimePermission(bp, userId)
+                == PERMISSION_OPERATION_FAILURE) {
+            return;
+        }
+
+        if (bp.isRuntime()) {
+            logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
+        }
+
+        if (callback != null) {
+            callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
+        }
+
+        if (bp.isRuntime()) {
+            notifyRuntimePermissionStateChanged(packageName, userId);
+        }
+    }
+
+    @Override
+    public void resetRuntimePermissions() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
+                "revokeRuntimePermission");
+
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                    "resetRuntimePermissions");
+        }
+
+        updateAllPermissions(
+                StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback);
+        for (final int userId : UserManagerService.getInstance().getUserIds()) {
+            mPackageManagerInt.forEachPackage(
+                    (PackageParser.Package pkg) -> resetRuntimePermissionsInternal(pkg, userId));
+        }
+    }
+
+    /**
+     * Reverts user permission state changes (permissions and flags).
+     *
+     * @param ps The package for which to reset.
+     * @param userId The device user for which to do a reset.
+     */
+    @GuardedBy("mPackages")
+    private void resetRuntimePermissionsInternal(final PackageParser.Package pkg,
+            final int userId) {
+        final String packageName = pkg.packageName;
+
+        // These are flags that can change base on user actions.
+        final int userSettableMask = FLAG_PERMISSION_USER_SET
+                | FLAG_PERMISSION_USER_FIXED
+                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
+                | FLAG_PERMISSION_REVIEW_REQUIRED;
+
+        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
+                | FLAG_PERMISSION_POLICY_FIXED;
+
+        // Delay and combine non-async permission callbacks
+        final int permissionCount = pkg.requestedPermissions.size();
+        final boolean[] permissionRemoved = new boolean[1];
+        final ArraySet<Long> revokedPermissions = new ArraySet<>();
+        final IntArray syncUpdatedUsers = new IntArray(permissionCount);
+        final IntArray asyncUpdatedUsers = new IntArray(permissionCount);
+
+        PermissionCallback delayingPermCallback = new PermissionCallback() {
+            public void onGidsChanged(int appId, int userId) {
+                mDefaultPermissionCallback.onGidsChanged(appId, userId);
+            }
+
+            public void onPermissionChanged() {
+                mDefaultPermissionCallback.onPermissionChanged();
+            }
+
+            public void onPermissionGranted(int uid, int userId) {
+                mDefaultPermissionCallback.onPermissionGranted(uid, userId);
+            }
+
+            public void onInstallPermissionGranted() {
+                mDefaultPermissionCallback.onInstallPermissionGranted();
+            }
+
+            public void onPermissionRevoked(int uid, int userId) {
+                revokedPermissions.add(IntPair.of(uid, userId));
+
+                syncUpdatedUsers.add(userId);
+            }
+
+            public void onInstallPermissionRevoked() {
+                mDefaultPermissionCallback.onInstallPermissionRevoked();
+            }
+
+            public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
+                for (int userId : updatedUserIds) {
+                    if (sync) {
+                        syncUpdatedUsers.add(userId);
+                        asyncUpdatedUsers.remove(userId);
+                    } else {
+                        // Don't override sync=true by sync=false
+                        if (syncUpdatedUsers.indexOf(userId) == -1) {
+                            asyncUpdatedUsers.add(userId);
+                        }
+                    }
+                }
+            }
+
+            public void onPermissionRemoved() {
+                permissionRemoved[0] = true;
+            }
+
+            public void onInstallPermissionUpdated() {
+                mDefaultPermissionCallback.onInstallPermissionUpdated();
+            }
+        };
+
+        for (int i = 0; i < permissionCount; i++) {
+            final String permName = pkg.requestedPermissions.get(i);
+            final BasePermission bp;
+            synchronized (mLock) {
+                bp = mSettings.getPermissionLocked(permName);
+            }
+            if (bp == null) {
+                continue;
+            }
+
+            if (bp.isRemoved()) {
+                continue;
+            }
+
+            // If shared user we just reset the state to which only this app contributed.
+            final String sharedUserId =
+                    mPackageManagerInt.getSharedUserIdForPackage(pkg.packageName);
+            final String[] pkgNames =
+                    mPackageManagerInt.getPackagesForSharedUserId(sharedUserId, userId);
+            if (pkgNames != null && pkgNames.length > 0) {
+                boolean used = false;
+                final int packageCount = pkgNames.length;
+                for (int j = 0; j < packageCount; j++) {
+                    final String sharedPkgName = pkgNames[j];
+                    final PackageParser.Package sharedPkg =
+                            mPackageManagerInt.getPackage(sharedPkgName);
+                    if (sharedPkg != null && !sharedPkg.packageName.equals(packageName)
+                            && sharedPkg.requestedPermissions.contains(permName)) {
+                        used = true;
+                        break;
+                    }
+                }
+                if (used) {
+                    continue;
+                }
+            }
+
+            final int oldFlags =
+                    getPermissionFlagsInternal(permName, packageName, Process.SYSTEM_UID, userId);
+
+            // Always clear the user settable flags.
+            // If permission review is enabled and this is a legacy app, mark the
+            // permission as requiring a review as this is the initial state.
+            final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
+            final int targetSdk = mPackageManagerInt.getTargetSdk(uid);
+            final int flags = (targetSdk < Build.VERSION_CODES.M && bp.isRuntime())
+                    ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE
+                    : 0;
+
+            updatePermissionFlagsInternal(
+                    permName, packageName, userSettableMask, flags, Process.SYSTEM_UID, userId,
+                    false, delayingPermCallback);
+
+            // Below is only runtime permission handling.
+            if (!bp.isRuntime()) {
+                continue;
+            }
+
+            // Never clobber system or policy.
+            if ((oldFlags & policyOrSystemFlags) != 0) {
+                continue;
+            }
+
+            // If this permission was granted by default, make sure it is.
+            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
+                grantRuntimePermissionInternal(permName, packageName, false,
+                        Process.SYSTEM_UID, userId, delayingPermCallback);
+            // If permission review is enabled the permissions for a legacy apps
+            // are represented as constantly granted runtime ones, so don't revoke.
+            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
+                // Otherwise, reset the permission.
+                revokeRuntimePermissionInternal(permName, packageName, false, Process.SYSTEM_UID,
+                        userId, delayingPermCallback);
+            }
+        }
+
+        // Execute delayed callbacks
+        if (permissionRemoved[0]) {
+            mDefaultPermissionCallback.onPermissionRemoved();
+        }
+
+        // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
+        // kill uid while holding mPackages-lock
+        if (!revokedPermissions.isEmpty()) {
+            int numRevokedPermissions = revokedPermissions.size();
+            for (int i = 0; i < numRevokedPermissions; i++) {
+                int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
+                int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
+
+                mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
+
+                // Kill app later as we are holding mPackages
+                mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
+                        KILL_APP_REASON_PERMISSIONS_REVOKED));
+            }
+        }
+
+        mPackageManagerInt.writePermissionSettings(syncUpdatedUsers.toArray(), false);
+        mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
+    }
+
+    @Override
+    public String getDefaultBrowser(int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (UserHandle.getUserId(callingUid) != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+        }
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            return mDefaultBrowserProvider == null
+                    ? null : mDefaultBrowserProvider.getDefaultBrowser(userId);
+        }
+    }
+
+    @Override
+    public boolean setDefaultBrowser(String packageName, int userId) {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+        }
+        return setDefaultBrowserInternal(packageName, false, true, userId);
+    }
+
+    private boolean setDefaultBrowserInternal(String packageName, boolean async,
+            boolean doGrant, int userId) {
+        synchronized (mLock) {
+            if (userId == UserHandle.USER_ALL) {
+                return false;
+            }
+            if (mDefaultBrowserProvider == null) {
+                return false;
+            }
+            if (async) {
+                mDefaultBrowserProvider.setDefaultBrowserAsync(packageName, userId);
+            } else {
+                if (!mDefaultBrowserProvider.setDefaultBrowser(packageName, userId)) {
+                    return false;
+                }
+            }
+            if (doGrant && packageName != null) {
+                mDefaultPermissionGrantPolicy
+                        .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
+        }
+    }
+
+    @Override
+    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                "grantDefaultPermissionsToEnabledImsServices", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
+        }
+    }
+
+    @Override
+    public void grantDefaultPermissionsToEnabledTelephonyDataServices(
+            String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToEnabledTelephonyDataServices(
+                            packageNames, userId));
+        }
+    }
+
+    @Override
+    public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+            String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
+                "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
+                            packageNames, userId));
+        }
+    }
+
+    @Override
+    public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
+        }
+    }
+
+    @Override
+    public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        PackageManagerServiceUtils
+                .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
+        synchronized (mLock) {
+            Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
+                    .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
+        }
+    }
+
+    @Override
+    public void setPermissionEnforced(String permName, boolean enforced) {
+        // TODO: Now that we no longer change GID for storage, this should to away.
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
+                "setPermissionEnforced");
+        if (READ_EXTERNAL_STORAGE.equals(permName)) {
+            mPackageManagerInt.setReadExternalStorageEnforced(enforced);
+            // kill any non-foreground processes so we restart them and
+            // grant/revoke the GID.
+            final IActivityManager am = ActivityManager.getService();
+            if (am != null) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    am.killProcessesBelowForeground("setPermissionEnforcement");
+                } catch (RemoteException e) {
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
+        } else {
+            throw new IllegalArgumentException("No selective enforcement for " + permName);
+        }
+    }
+
+    /** @deprecated */
+    @Override
+    @Deprecated
+    public boolean isPermissionEnforced(String permName) {
+        // allow instant applications
+        return true;
+    }
+
+    @Override
+    public boolean shouldShowRequestPermissionRationale(String permName,
+            String packageName, int userId) {
+        final int callingUid = Binder.getCallingUid();
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                    "canShowRequestPermissionRationale for user " + userId);
+        }
+
+        final int uid =
+                mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
+        if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
+            return false;
+        }
+
+        if (checkPermission(permName, packageName, userId)
+                == PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
+
+        final int flags;
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
+                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
+                | PackageManager.FLAG_PERMISSION_USER_FIXED;
+
+        if ((flags & fixedFlags) != 0) {
+            return false;
+        }
+
+        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
+    }
+
+    @Override
+    public boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId) {
+        if (UserHandle.getCallingUserId() != userId) {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                    "isPermissionRevokedByPolicy for user " + userId);
+        }
+
+        if (checkPermission(permName, packageName, userId) == PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
+
+        final int callingUid = Binder.getCallingUid();
+        if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
+            return false;
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final int flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
+            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     /**
      * Get the state of the runtime permissions as xml file.
      *
@@ -490,69 +1958,6 @@
                 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
     }
 
-    private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
-            int callingUid) {
-        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
-            return null;
-        }
-        synchronized (mLock) {
-            return PackageParser.generatePermissionGroupInfo(
-                    mSettings.mPermissionGroups.get(groupName), flags);
-        }
-    }
-
-    private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
-        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
-            return null;
-        }
-        synchronized (mLock) {
-            final int N = mSettings.mPermissionGroups.size();
-            final ArrayList<PermissionGroupInfo> out
-                    = new ArrayList<PermissionGroupInfo>(N);
-            for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
-                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
-            }
-            return out;
-        }
-    }
-
-    private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
-            int callingUid) {
-        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
-            return null;
-        }
-        // reader
-        synchronized (mLock) {
-            final BasePermission bp = mSettings.getPermissionLocked(permName);
-            if (bp == null) {
-                return null;
-            }
-            final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
-                    bp.getProtectionLevel(), packageName, callingUid);
-            return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
-        }
-    }
-
-    private List<PermissionInfo> getPermissionInfoByGroup(
-            String groupName, int flags, int callingUid) {
-        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
-            return null;
-        }
-        synchronized (mLock) {
-            if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
-                return null;
-            }
-            final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
-            for (BasePermission bp : mSettings.mPermissions.values()) {
-                final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
-                if (pi != null) {
-                    out.add(pi);
-                }
-            }
-            return out;
-        }
-    }
-
     private int adjustPermissionProtectionFlagsLocked(
             int protectionLevel, String packageName, int uid) {
         // Signature permission flags area always reported
@@ -616,6 +2021,7 @@
             }
         }
 
+        final int callingUid = Binder.getCallingUid();
         final int numNewPackagePermissions = newPackage.permissions.size();
         for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
                 newPermissionNum++) {
@@ -640,9 +2046,9 @@
                         final int numPackages = allPackageNames.size();
                         for (int packageNum = 0; packageNum < numPackages; packageNum++) {
                             final String packageName = allPackageNames.get(packageNum);
-
-                            if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
-                                    userId) == PackageManager.PERMISSION_GRANTED) {
+                            final int permissionState = checkPermissionInternal(
+                                    permissionName, packageName, UserHandle.USER_SYSTEM, userId);
+                            if (permissionState == PackageManager.PERMISSION_GRANTED) {
                                 EventLog.writeEvent(0x534e4554, "72710897",
                                         newPackage.applicationInfo.uid,
                                         "Revoking permission " + permissionName +
@@ -651,8 +2057,8 @@
                                         " to " + newPermissionGroupName);
 
                                 try {
-                                    revokeRuntimePermission(permissionName, packageName, false,
-                                            userId, permissionCallback);
+                                    revokeRuntimePermissionInternal(permissionName, packageName,
+                                            false, callingUid, userId, permissionCallback);
                                 } catch (IllegalArgumentException e) {
                                     Slog.e(TAG, "Could not revoke " + permissionName + " from "
                                             + packageName, e);
@@ -798,63 +2204,6 @@
         }
     }
 
-    private boolean addDynamicPermission(
-            PermissionInfo info, int callingUid, PermissionCallback callback) {
-        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
-            throw new SecurityException("Instant apps can't add permissions");
-        }
-        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
-            throw new SecurityException("Label must be specified in permission");
-        }
-        final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
-        final boolean added;
-        final boolean changed;
-        synchronized (mLock) {
-            BasePermission bp = mSettings.getPermissionLocked(info.name);
-            added = bp == null;
-            int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
-            if (added) {
-                enforcePermissionCapLocked(info, tree);
-                bp = new BasePermission(info.name, tree.getSourcePackageName(),
-                        BasePermission.TYPE_DYNAMIC);
-            } else if (!bp.isDynamic()) {
-                throw new SecurityException("Not allowed to modify non-dynamic permission "
-                        + info.name);
-            }
-            changed = bp.addToTree(fixedLevel, info, tree);
-            if (added) {
-                mSettings.putPermissionLocked(info.name, bp);
-            }
-        }
-        if (changed && callback != null) {
-            callback.onPermissionChanged();
-        }
-        return added;
-    }
-
-    private void removeDynamicPermission(
-            String permName, int callingUid, PermissionCallback callback) {
-        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
-            throw new SecurityException("Instant applications don't have access to this method");
-        }
-        final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
-        synchronized (mLock) {
-            final BasePermission bp = mSettings.getPermissionLocked(permName);
-            if (bp == null) {
-                return;
-            }
-            if (bp.isDynamic()) {
-                // TODO: switch this back to SecurityException
-                Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
-                        + permName);
-            }
-            mSettings.removePermissionLocked(permName);
-            if (callback != null) {
-                callback.onPermissionRemoved();
-            }
-        }
-    }
-
     /**
      * Restore the permission state for a package.
      *
@@ -1178,6 +2527,14 @@
                                     }
                                 }
 
+                                if (hardRestricted && !restrictionExempt
+                                        && (flags & FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
+                                    // Applying a hard restriction implies revoking it. This might
+                                    // lead to a system-fixed, revoked permission.
+                                    flags &= ~FLAG_PERMISSION_SYSTEM_FIXED;
+                                    wasChanged = true;
+                                }
+
                                 if (wasChanged) {
                                     updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                                 }
@@ -1622,9 +2979,9 @@
         } else if (pkg.isProduct()) {
             wlPermissions =
                     SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
-        } else if (pkg.isProductServices()) {
+        } else if (pkg.isSystemExt()) {
             wlPermissions =
-                    SystemConfig.getInstance().getProductServicesPrivAppPermissions(
+                    SystemConfig.getInstance().getSystemExtPrivAppPermissions(
                             pkg.packageName);
         } else {
             wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
@@ -1658,9 +3015,9 @@
                     } else if (pkg.isProduct()) {
                         deniedPermissions = SystemConfig.getInstance()
                                 .getProductPrivAppDenyPermissions(pkg.packageName);
-                    } else if (pkg.isProductServices()) {
+                    } else if (pkg.isSystemExt()) {
                         deniedPermissions = SystemConfig.getInstance()
-                                .getProductServicesPrivAppDenyPermissions(pkg.packageName);
+                                .getSystemExtPrivAppDenyPermissions(pkg.packageName);
                     } else {
                         deniedPermissions = SystemConfig.getInstance()
                                 .getPrivAppDenyPermissions(pkg.packageName);
@@ -1669,13 +3026,15 @@
                             deniedPermissions == null || !deniedPermissions.contains(perm);
                     if (permissionViolation) {
                         Slog.w(TAG, "Privileged permission " + perm + " for package "
-                                + pkg.packageName + " - not in privapp-permissions whitelist");
+                                + pkg.packageName + " (" + pkg.codePath
+                                + ") not in privapp-permissions whitelist");
 
                         if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
                             if (mPrivappPermissionsViolations == null) {
                                 mPrivappPermissionsViolations = new ArraySet<>();
                             }
-                            mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
+                            mPrivappPermissionsViolations.add(
+                                    pkg.packageName + " (" + pkg.codePath + "): " + perm);
                         }
                     } else {
                         return false;
@@ -1895,14 +3254,15 @@
         return Boolean.TRUE == granted;
     }
 
-    private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
+    private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
+            @UserIdInt int userId) {
         // Permission review applies only to apps not supporting the new permission model.
         if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
             return false;
         }
 
         // Legacy apps have the permission and get user consent on launch.
-        if (pkg == null || pkg.mExtras == null) {
+        if (pkg.mExtras == null) {
             return false;
         }
         final PackageSetting ps = (PackageSetting) pkg.mExtras;
@@ -1948,7 +3308,7 @@
             }
             for (int userId : mUserManagerInt.getUserIds()) {
                 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
-                    grantRuntimePermission(
+                    grantRuntimePermissionInternal(
                             permission, pkg.packageName, false, callingUid, userId, callback);
                 }
             }
@@ -1963,54 +3323,6 @@
         }
     }
 
-    private @Nullable List<String> getWhitelistedRestrictedPermissions(
-            @NonNull PackageParser.Package pkg, @PermissionWhitelistFlags int whitelistFlags,
-            @UserIdInt int userId) {
-        final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
-        if (packageSetting == null) {
-            return null;
-        }
-
-        final PermissionsState permissionsState = packageSetting.getPermissionsState();
-
-        int queryFlags = 0;
-        if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
-            queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
-        }
-        if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
-            queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
-        }
-        if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
-            queryFlags |=  PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
-        }
-
-        ArrayList<String> whitelistedPermissions = null;
-
-        final int permissionCount = pkg.requestedPermissions.size();
-        for (int i = 0; i < permissionCount; i++) {
-            final String permissionName = pkg.requestedPermissions.get(i);
-            final int currentFlags = permissionsState.getPermissionFlags(permissionName, userId);
-            if ((currentFlags & queryFlags) != 0) {
-                if (whitelistedPermissions == null) {
-                    whitelistedPermissions = new ArrayList<>();
-                }
-                whitelistedPermissions.add(permissionName);
-            }
-        }
-
-        return whitelistedPermissions;
-    }
-
-    private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
-            @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
-            @PackageManager.PermissionWhitelistFlags int whitelistFlags,
-            @NonNull PermissionCallback callback) {
-        for (int userId : userIds) {
-            setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
-                    callingUid, whitelistFlags, callback);
-        }
-    }
-
     private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
             String[] grantedPermissions, int callingUid, PermissionCallback callback) {
         PackageSetting ps = (PackageSetting) pkg.mExtras;
@@ -2042,14 +3354,14 @@
                 if (supportsRuntimePermissions) {
                     // Installer cannot change immutable permissions.
                     if ((flags & immutableFlags) == 0) {
-                        grantRuntimePermission(permission, pkg.packageName, false, callingUid,
-                                userId, callback);
+                        grantRuntimePermissionInternal(permission, pkg.packageName, false,
+                                callingUid, userId, callback);
                     }
                 } else {
                     // In permission review mode we clear the review flag when we
                     // are asked to install the app with all permissions granted.
                     if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
-                        updatePermissionFlags(permission, pkg.packageName,
+                        updatePermissionFlagsInternal(permission, pkg.packageName,
                                 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
                                 userId, false, callback);
                     }
@@ -2058,250 +3370,15 @@
         }
     }
 
-    private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
-            int callingUid, final int userId, PermissionCallback callback) {
-        if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
-                && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
-            Log.i(TAG, "System is granting "
-                    + permName + " for user " + userId + " on behalf of uid " + callingUid
-                    + " " + mPackageManagerInt.getNameForUid(callingUid),
-                    new RuntimeException());
-        }
-        if (!mUserManagerInt.exists(userId)) {
-            Log.e(TAG, "No such user:" + userId);
-            return;
-        }
-
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
-                "grantRuntimePermission");
-
-        enforceCrossUserPermission(callingUid, userId,
-                true,  // requireFullPermission
-                true,  // checkShell
-                false, // requirePermissionWhenSameUser
-                "grantRuntimePermission");
-
-        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
-        if (pkg == null || pkg.mExtras == null) {
-            throw new IllegalArgumentException("Unknown package: " + packageName);
-        }
-        final BasePermission bp;
-        synchronized(mLock) {
-            bp = mSettings.getPermissionLocked(permName);
-        }
-        if (bp == null) {
-            throw new IllegalArgumentException("Unknown permission: " + permName);
-        }
-        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
-            throw new IllegalArgumentException("Unknown package: " + packageName);
-        }
-
-        bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
-
-        // If a permission review is required for legacy apps we represent
-        // their permissions as always granted runtime ones since we need
-        // to keep the review required permission flag per user while an
-        // install permission's state is shared across all users.
-        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
-                && bp.isRuntime()) {
-            return;
-        }
-
-        final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
-
-        final PackageSetting ps = (PackageSetting) pkg.mExtras;
-        final PermissionsState permissionsState = ps.getPermissionsState();
-
-        final int flags = permissionsState.getPermissionFlags(permName, userId);
-        if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
-            Log.e(TAG, "Cannot grant system fixed permission "
-                    + permName + " for package " + packageName);
-            return;
-        }
-        if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
-            Log.e(TAG, "Cannot grant policy fixed permission "
-                    + permName + " for package " + packageName);
-            return;
-        }
-
-        if (bp.isHardRestricted()
-                && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
-            Log.e(TAG, "Cannot grant restricted non-exempt permission "
-                    + permName + " for package " + packageName);
-            return;
-        }
-
-        if (bp.isDevelopment()) {
-            // Development permissions must be handled specially, since they are not
-            // normal runtime permissions.  For now they apply to all users.
-            if (permissionsState.grantInstallPermission(bp) !=
-                    PERMISSION_OPERATION_FAILURE) {
-                if (callback != null) {
-                    callback.onInstallPermissionGranted();
-                }
-            }
-            return;
-        }
-
-        if (ps.getInstantApp(userId) && !bp.isInstant()) {
-            throw new SecurityException("Cannot grant non-ephemeral permission"
-                    + permName + " for package " + packageName);
-        }
-
-        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
-            Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
-            return;
-        }
-
-        final int result = permissionsState.grantRuntimePermission(bp, userId);
-        switch (result) {
-            case PERMISSION_OPERATION_FAILURE: {
-                return;
-            }
-
-            case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
-                if (callback != null) {
-                    callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
-                }
-            }
-            break;
-        }
-
-        if (bp.isRuntime()) {
-            logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
-        }
-
-        if (callback != null) {
-            callback.onPermissionGranted(uid, userId);
-        }
-
-        if (bp.isRuntime()) {
-            notifyRuntimePermissionStateChanged(packageName, userId);
-        }
-
-        // Only need to do this if user is initialized. Otherwise it's a new user
-        // and there are no processes running as the user yet and there's no need
-        // to make an expensive call to remount processes for the changed permissions.
-        if (READ_EXTERNAL_STORAGE.equals(permName)
-                || WRITE_EXTERNAL_STORAGE.equals(permName)) {
-            final long token = Binder.clearCallingIdentity();
-            try {
-                if (mUserManagerInt.isUserInitialized(userId)) {
-                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
-                            StorageManagerInternal.class);
-                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
-                }
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-    }
-
-    private void revokeRuntimePermission(String permName, String packageName,
-            boolean overridePolicy, int userId, PermissionCallback callback) {
-        int callingUid = Binder.getCallingUid();
-        if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
-                && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
-            Log.i(TAG, "System is revoking "
-                            + permName + " for user " + userId + " on behalf of uid " + callingUid
-                            + " " + mPackageManagerInt.getNameForUid(callingUid),
-                    new RuntimeException());
-        }
-        if (!mUserManagerInt.exists(userId)) {
-            Log.e(TAG, "No such user:" + userId);
-            return;
-        }
-
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
-                "revokeRuntimePermission");
-
-        enforceCrossUserPermission(callingUid, userId,
-                true,  // requireFullPermission
-                true,  // checkShell
-                false, // requirePermissionWhenSameUser
-                "revokeRuntimePermission");
-
-        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
-        if (pkg == null || pkg.mExtras == null) {
-            throw new IllegalArgumentException("Unknown package: " + packageName);
-        }
-        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
-            throw new IllegalArgumentException("Unknown package: " + packageName);
-        }
-        final BasePermission bp = mSettings.getPermissionLocked(permName);
-        if (bp == null) {
-            throw new IllegalArgumentException("Unknown permission: " + permName);
-        }
-
-        bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
-
-        // If a permission review is required for legacy apps we represent
-        // their permissions as always granted runtime ones since we need
-        // to keep the review required permission flag per user while an
-        // install permission's state is shared across all users.
-        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
-                && bp.isRuntime()) {
-            return;
-        }
-
-        final PackageSetting ps = (PackageSetting) pkg.mExtras;
-        final PermissionsState permissionsState = ps.getPermissionsState();
-
-        final int flags = permissionsState.getPermissionFlags(permName, userId);
-        // Only the system may revoke SYSTEM_FIXED permissions.
-        if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
-                && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
-            throw new SecurityException("Non-System UID cannot revoke system fixed permission "
-                    + permName + " for package " + packageName);
-        }
-        if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
-            throw new SecurityException("Cannot revoke policy fixed permission "
-                    + permName + " for package " + packageName);
-        }
-
-        if (bp.isDevelopment()) {
-            // Development permissions must be handled specially, since they are not
-            // normal runtime permissions.  For now they apply to all users.
-            if (permissionsState.revokeInstallPermission(bp) !=
-                    PERMISSION_OPERATION_FAILURE) {
-                if (callback != null) {
-                    callback.onInstallPermissionRevoked();
-                }
-            }
-            return;
-        }
-
-        if (permissionsState.revokeRuntimePermission(bp, userId) ==
-                PERMISSION_OPERATION_FAILURE) {
-            return;
-        }
-
-        if (bp.isRuntime()) {
-            logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
-        }
-
-        if (callback != null) {
-            callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
-        }
-
-        if (bp.isRuntime()) {
-            notifyRuntimePermissionStateChanged(packageName, userId);
-        }
-    }
-
     private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg,
             @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
             @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
-        final PackageSetting ps = (PackageSetting) pkg.mExtras;
-        if (ps == null) {
+        final PermissionsState permissionsState =
+                PackageManagerServiceUtils.getPermissionsState(pkg);
+        if (permissionsState == null) {
             return;
         }
 
-        final PermissionsState permissionsState = ps.getPermissionsState();
-
         ArraySet<String> oldGrantedRestrictedPermissions = null;
         boolean updatePermissions = false;
 
@@ -2310,12 +3387,8 @@
             final String permissionName = pkg.requestedPermissions.get(i);
 
             final BasePermission bp = mSettings.getPermissionLocked(permissionName);
-            if (bp == null) {
-                Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
-                continue;
-            }
 
-            if (!bp.isHardOrSoftRestricted()) {
+            if (bp == null || !bp.isHardOrSoftRestricted()) {
                 continue;
             }
 
@@ -2393,7 +3466,7 @@
                 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
             }
 
-            updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
+            updatePermissionFlagsInternal(permissionName, pkg.packageName, mask, newFlags,
                     callingUid, userId, false, null /*callback*/);
         }
 
@@ -2407,7 +3480,9 @@
                 for (int i = 0; i < oldGrantedCount; i++) {
                     final String permission = oldGrantedRestrictedPermissions.valueAt(i);
                     // Sometimes we create a new permission state instance during update.
-                    if (!ps.getPermissionsState().hasPermission(permission, userId)) {
+                    final PermissionsState newPermissionsState =
+                            PackageManagerServiceUtils.getPermissionsState(pkg);
+                    if (!newPermissionsState.hasPermission(permission, userId)) {
                         callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
                         break;
                     }
@@ -2480,50 +3555,6 @@
         return runtimePermissionChangedUserIds;
     }
 
-    private String[] getAppOpPermissionPackages(String permName) {
-        if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        synchronized (mLock) {
-            final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
-            if (pkgs == null) {
-                return null;
-            }
-            return pkgs.toArray(new String[pkgs.size()]);
-        }
-    }
-
-    private int getPermissionFlags(
-            String permName, String packageName, int callingUid, int userId) {
-        if (!mUserManagerInt.exists(userId)) {
-            return 0;
-        }
-
-        enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
-
-        enforceCrossUserPermission(callingUid, userId,
-                true,  // requireFullPermission
-                false, // checkShell
-                false, // requirePermissionWhenSameUser
-                "getPermissionFlags");
-
-        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
-        if (pkg == null || pkg.mExtras == null) {
-            return 0;
-        }
-        synchronized (mLock) {
-            if (mSettings.getPermissionLocked(permName) == null) {
-                return 0;
-            }
-        }
-        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
-            return 0;
-        }
-        final PackageSetting ps = (PackageSetting) pkg.mExtras;
-        PermissionsState permissionsState = ps.getPermissionsState();
-        return permissionsState.getPermissionFlags(permName, userId);
-    }
-
     /**
      * Update permissions when a package changed.
      *
@@ -2538,16 +3569,15 @@
      * @param callback Callback to call after permission changes
      */
     private void updatePermissions(@NonNull String packageName, @Nullable PackageParser.Package pkg,
-            @NonNull Collection<PackageParser.Package> allPackages,
             @NonNull PermissionCallback callback) {
         final int flags =
                 (pkg != null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG : 0);
         updatePermissions(
-                packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
+                packageName, pkg, getVolumeUuidForPackage(pkg), flags, callback);
         if (pkg != null && pkg.childPackages != null) {
             for (PackageParser.Package childPkg : pkg.childPackages) {
                 updatePermissions(childPkg.packageName, childPkg,
-                        getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
+                        getVolumeUuidForPackage(childPkg), flags, callback);
             }
         }
     }
@@ -2565,13 +3595,12 @@
      * @param callback Callback to call after permission changes
      */
     private void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
-            @NonNull Collection<PackageParser.Package> allPackages,
             @NonNull PermissionCallback callback) {
         final int flags = UPDATE_PERMISSIONS_ALL |
                 (sdkUpdated
                         ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
                         : 0);
-        updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
+        updatePermissions(null, null, volumeUuid, flags, callback);
     }
 
     /**
@@ -2649,11 +3678,11 @@
      * @param allPackages All currently known packages
      * @param callback Callback to call after permission changes
      */
-    private void updatePermissions(@Nullable String changingPkgName,
-            @Nullable PackageParser.Package changingPkg, @Nullable String replaceVolumeUuid,
+    private void updatePermissions(final @Nullable String changingPkgName,
+            final @Nullable PackageParser.Package changingPkg,
+            final @Nullable String replaceVolumeUuid,
             @UpdatePermissionFlags int flags,
-            @NonNull Collection<PackageParser.Package> allPackages,
-            @Nullable PermissionCallback callback) {
+            final @Nullable PermissionCallback callback) {
         // TODO: Most of the methods exposing BasePermission internals [source package name,
         // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
         // have package settings, we should make note of it elsewhere [map between
@@ -2682,15 +3711,16 @@
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
         // Now update the permissions for all packages.
         if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
-            for (PackageParser.Package pkg : allPackages) {
-                if (pkg != changingPkg) {
-                    // Only replace for packages on requested volume
-                    final String volumeUuid = getVolumeUuidForPackage(pkg);
-                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
-                            && Objects.equals(replaceVolumeUuid, volumeUuid);
-                    restorePermissionState(pkg, replace, changingPkgName, callback);
+            final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
+            mPackageManagerInt.forEachPackage((Package pkg) -> {
+                if (pkg == changingPkg) {
+                    return;
                 }
-            }
+                // Only replace for packages on requested volume
+                final String volumeUuid = getVolumeUuidForPackage(pkg);
+                final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
+                restorePermissionState(pkg, replace, changingPkgName, callback);
+            });
         }
 
         if (changingPkg != null) {
@@ -2832,124 +3862,6 @@
         return changed;
     }
 
-    private void updatePermissionFlags(String permName, String packageName, int flagMask,
-            int flagValues, int callingUid, int userId, boolean overridePolicy,
-            PermissionCallback callback) {
-        if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
-                && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
-            Log.i(TAG, "System is updating flags for "
-                            + permName + " for user " + userId  + " "
-                            + DebugUtils.flagsToString(
-                                    PackageManager.class, "FLAG_PERMISSION_", flagMask)
-                            + " := "
-                            + DebugUtils.flagsToString(
-                                    PackageManager.class, "FLAG_PERMISSION_", flagValues)
-                            + " on behalf of uid " + callingUid
-                            + " " + mPackageManagerInt.getNameForUid(callingUid),
-                    new RuntimeException());
-        }
-
-        if (!mUserManagerInt.exists(userId)) {
-            return;
-        }
-
-        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
-
-        enforceCrossUserPermission(callingUid, userId,
-                true,  // requireFullPermission
-                true,  // checkShell
-                false, // requirePermissionWhenSameUser
-                "updatePermissionFlags");
-
-        if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
-            throw new SecurityException("updatePermissionFlags requires "
-                    + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
-        }
-
-        // Only the system can change these flags and nothing else.
-        if (callingUid != Process.SYSTEM_UID) {
-            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
-            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
-            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
-            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
-            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
-            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
-            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
-            flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
-            flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
-        }
-
-        final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
-        if (pkg == null || pkg.mExtras == null) {
-            Log.e(TAG, "Unknown package: " + packageName);
-            return;
-        }
-        if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
-            throw new IllegalArgumentException("Unknown package: " + packageName);
-        }
-
-        final BasePermission bp;
-        synchronized (mLock) {
-            bp = mSettings.getPermissionLocked(permName);
-        }
-        if (bp == null) {
-            throw new IllegalArgumentException("Unknown permission: " + permName);
-        }
-
-        final PackageSetting ps = (PackageSetting) pkg.mExtras;
-        final PermissionsState permissionsState = ps.getPermissionsState();
-        final boolean hadState =
-                permissionsState.getRuntimePermissionState(permName, userId) != null;
-        final boolean permissionUpdated =
-                permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
-        if (permissionUpdated && bp.isRuntime()) {
-            notifyRuntimePermissionStateChanged(packageName, userId);
-        }
-        if (permissionUpdated && callback != null) {
-            // Install and runtime permissions are stored in different places,
-            // so figure out what permission changed and persist the change.
-            if (permissionsState.getInstallPermissionState(permName) != null) {
-                callback.onInstallPermissionUpdated();
-            } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
-                    || hadState) {
-                callback.onPermissionUpdated(new int[] { userId }, false);
-            }
-        }
-    }
-
-    private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
-            int userId, Collection<Package> packages, PermissionCallback callback) {
-        if (!mUserManagerInt.exists(userId)) {
-            return false;
-        }
-
-        enforceGrantRevokeRuntimePermissionPermissions(
-                "updatePermissionFlagsForAllApps");
-        enforceCrossUserPermission(callingUid, userId,
-                true,  // requireFullPermission
-                true,  // checkShell
-                false, // requirePermissionWhenSameUser
-                "updatePermissionFlagsForAllApps");
-
-        // Only the system can change system fixed flags.
-        if (callingUid != Process.SYSTEM_UID) {
-            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
-            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
-        }
-
-        boolean changed = false;
-        for (PackageParser.Package pkg : packages) {
-            final PackageSetting ps = (PackageSetting) pkg.mExtras;
-            if (ps == null) {
-                continue;
-            }
-            PermissionsState permissionsState = ps.getPermissionsState();
-            changed |= permissionsState.updatePermissionFlagsForAllPermissions(
-                    userId, flagMask, flagValues);
-        }
-        return changed;
-    }
-
     private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
         if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
                 != PackageManager.PERMISSION_GRANTED
@@ -3037,6 +3949,24 @@
         }
 
         mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
+
+        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
+        for (int userId : UserManagerService.getInstance().getUserIds()) {
+            if (!mPackageManagerInt.areDefaultRuntimePermissionsGranted(userId)) {
+                grantPermissionsUserIds = ArrayUtils.appendInt(
+                        grantPermissionsUserIds, userId);
+            }
+        }
+        // If we upgraded grant all default permissions before kicking off.
+        for (int userId : grantPermissionsUserIds) {
+            mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
+        }
+        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
+            // If we did not grant default permissions, we preload from this the
+            // default permission exceptions lazily to ensure we don't hit the
+            // disk on a new user creation.
+            mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
+        }
     }
 
     private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
@@ -3095,17 +4025,16 @@
             PermissionManagerService.this.systemReady();
         }
         @Override
-        public boolean isPermissionsReviewRequired(Package pkg, int userId) {
+        public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
             return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
         }
         @Override
         public void revokeRuntimePermissionsIfGroupChanged(
                 @NonNull PackageParser.Package newPackage,
                 @NonNull PackageParser.Package oldPackage,
-                @NonNull ArrayList<String> allPackageNames,
-                @NonNull PermissionCallback permissionCallback) {
+                @NonNull ArrayList<String> allPackageNames) {
             PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
-                    oldPackage, allPackageNames, permissionCallback);
+                    oldPackage, allPackageNames, mDefaultPermissionCallback);
         }
         @Override
         public void addAllPermissions(Package pkg, boolean chatty) {
@@ -3120,91 +4049,55 @@
             PermissionManagerService.this.removeAllPermissions(pkg, chatty);
         }
         @Override
-        public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
-                PermissionCallback callback) {
-            return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
-        }
-        @Override
-        public void removeDynamicPermission(String permName, int callingUid,
-                PermissionCallback callback) {
-            PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
-        }
-        @Override
-        public void grantRuntimePermission(String permName, String packageName,
-                boolean overridePolicy, int callingUid, int userId,
-                PermissionCallback callback) {
-            PermissionManagerService.this.grantRuntimePermission(
-                    permName, packageName, overridePolicy, callingUid, userId, callback);
-        }
-        @Override
         public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
-                String[] grantedPermissions, int callingUid, PermissionCallback callback) {
+                String[] grantedPermissions, int callingUid) {
             PermissionManagerService.this.grantRequestedRuntimePermissions(
-                    pkg, userIds, grantedPermissions, callingUid, callback);
-        }
-        @Override
-        public List<String> getWhitelistedRestrictedPermissions(PackageParser.Package pkg,
-                @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId) {
-            return PermissionManagerService.this.getWhitelistedRestrictedPermissions(pkg,
-                    whitelistFlags, userId);
+                    pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
         }
         @Override
         public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
                 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
-                @PackageManager.PermissionWhitelistFlags int whitelistFlags,
-                @NonNull PermissionCallback callback) {
-            PermissionManagerService.this.setWhitelistedRestrictedPermissions(
-                    pkg, userIds, permissions, callingUid, whitelistFlags, callback);
+                @PackageManager.PermissionWhitelistFlags int flags) {
+            for (int userId : userIds) {
+                setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
+                        callingUid, flags, mDefaultPermissionCallback);
+            }
+        }
+        @Override
+        public void setWhitelistedRestrictedPermissions(String packageName,
+                List<String> permissions, int flags, int userId) {
+            PermissionManagerService.this.setWhitelistedRestrictedPermissionsInternal(
+                    packageName, permissions, flags, userId);
         }
         @Override
         public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
-                int callingUid, PermissionCallback callback) {
+                int callingUid) {
             PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
-                    pkg, callingUid, callback);
+                    pkg, callingUid, mDefaultPermissionCallback);
         }
         @Override
-        public void revokeRuntimePermission(String permName, String packageName,
-                boolean overridePolicy, int userId, PermissionCallback callback) {
-            PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
-                    overridePolicy, userId, callback);
+        public void updatePermissions(@NonNull String packageName, @Nullable Package pkg) {
+            PermissionManagerService.this
+                    .updatePermissions(packageName, pkg, mDefaultPermissionCallback);
         }
         @Override
-        public void updatePermissions(@NonNull String packageName, @Nullable Package pkg,
-                @NonNull Collection<PackageParser.Package> allPackages,
-                @NonNull PermissionCallback callback) {
-            PermissionManagerService.this.updatePermissions(
-                    packageName, pkg, allPackages, callback);
+        public void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated) {
+            PermissionManagerService.this
+                    .updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback);
         }
         @Override
-        public void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
-                @NonNull Collection<PackageParser.Package> allPackages,
-                @NonNull PermissionCallback callback) {
-            PermissionManagerService.this.updateAllPermissions(
-                    volumeUuid, sdkUpdated, allPackages, callback);
+        public void resetRuntimePermissions(Package pkg, int userId) {
+            PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId);
         }
         @Override
-        public String[] getAppOpPermissionPackages(String permName) {
-            return PermissionManagerService.this.getAppOpPermissionPackages(permName);
+        public void resetAllRuntimePermissions(final int userId) {
+            mPackageManagerInt.forEachPackage(
+                    (PackageParser.Package pkg) -> resetRuntimePermissionsInternal(pkg, userId));
         }
         @Override
-        public int getPermissionFlags(String permName, String packageName, int callingUid,
-                int userId) {
-            return PermissionManagerService.this.getPermissionFlags(permName, packageName,
-                    callingUid, userId);
-        }
-        @Override
-        public void updatePermissionFlags(String permName, String packageName, int flagMask,
-                int flagValues, int callingUid, int userId, boolean overridePolicy,
-                PermissionCallback callback) {
-            PermissionManagerService.this.updatePermissionFlags(
-                    permName, packageName, flagMask, flagValues, callingUid, userId,
-                    overridePolicy, callback);
-        }
-        @Override
-        public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
-                int userId, Collection<Package> packages, PermissionCallback callback) {
-            return PermissionManagerService.this.updatePermissionFlagsForAllApps(
-                    flagMask, flagValues, callingUid, userId, packages, callback);
+        public String[] getAppOpPermissionPackages(String permName, int callingUid) {
+            return PermissionManagerService.this
+                    .getAppOpPermissionPackagesInternal(permName, callingUid);
         }
         @Override
         public void enforceCrossUserPermission(int callingUid, int userId,
@@ -3224,46 +4117,10 @@
             PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
         }
         @Override
-        public int checkPermission(String permName, String packageName, int callingUid,
-                int userId) {
-            return PermissionManagerService.this.checkPermission(
-                    permName, packageName, callingUid, userId);
-        }
-        @Override
-        public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
-                int callingUid) {
-            return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
-        }
-        @Override
-        public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
-                int callingUid) {
-            return PermissionManagerService.this.getPermissionGroupInfo(
-                    groupName, flags, callingUid);
-        }
-        @Override
-        public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
-            return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
-        }
-        @Override
-        public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
-                int callingUid) {
-            return PermissionManagerService.this.getPermissionInfo(
-                    permName, packageName, flags, callingUid);
-        }
-        @Override
-        public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
-                int callingUid) {
-            return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
-        }
-        @Override
         public PermissionSettings getPermissionSettings() {
             return mSettings;
         }
         @Override
-        public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
-            return mDefaultPermissionGrantPolicy;
-        }
-        @Override
         public BasePermission getPermissionTEMP(String permName) {
             synchronized (PermissionManagerService.this.mLock) {
                 return mSettings.getPermissionLocked(permName);
@@ -3271,6 +4128,27 @@
         }
 
         @Override
+        public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
+                @PermissionInfo.Protection int protectionLevel) {
+            ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
+
+            synchronized (PermissionManagerService.this.mLock) {
+                int numTotalPermissions = mSettings.mPermissions.size();
+
+                for (int i = 0; i < numTotalPermissions; i++) {
+                    BasePermission bp = mSettings.mPermissions.valueAt(i);
+
+                    if (bp.perm != null && bp.perm.info != null
+                            && bp.protectionLevel == protectionLevel) {
+                        matchingPermissions.add(bp.perm.info);
+                    }
+                }
+            }
+
+            return matchingPermissions;
+        }
+
+        @Override
         public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
             return PermissionManagerService.this.backupRuntimePermissions(user);
         }
@@ -3299,5 +4177,233 @@
             PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
                     listener);
         }
+
+        @Override
+        public CheckPermissionDelegate getCheckPermissionDelegate() {
+            synchronized (mLock) {
+                return mCheckPermissionDelegate;
+            }
+        }
+
+        @Override
+        public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
+            synchronized (mLock) {
+                mCheckPermissionDelegate = delegate;
+            }
+        }
+
+        @Override
+        public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
+            synchronized (mLock) {
+                mDefaultBrowserProvider = provider;
+            }
+        }
+
+        @Override
+        public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
+                int userId) {
+            setDefaultBrowserInternal(packageName, async, doGrant, userId);
+        }
+
+        @Override
+        public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
+            synchronized (mLock) {
+                mDefaultDialerProvider = provider;
+            }
+        }
+
+        @Override
+        public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
+            synchronized (mLock) {
+                mDefaultHomeProvider = provider;
+            }
+        }
+
+        @Override
+        public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
+            synchronized (mLock) {
+                if (userId == UserHandle.USER_ALL) {
+                    return;
+                }
+                if (mDefaultHomeProvider == null) {
+                    return;
+                }
+                mDefaultHomeProvider.setDefaultHomeAsync(packageName, userId, callback);
+            }
+        }
+
+        @Override
+        public void setDialerAppPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setLocationExtraPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setLocationPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setSmsAppPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
+            }
+        }
+
+        @Override
+        public String getDefaultBrowser(int userId) {
+            synchronized (mLock) {
+                return mDefaultBrowserProvider == null
+                        ? null : mDefaultBrowserProvider.getDefaultBrowser(userId);
+            }
+        }
+
+        @Override
+        public String getDefaultDialer(int userId) {
+            synchronized (mLock) {
+                return mDefaultDialerProvider == null
+                        ? null : mDefaultDialerProvider.getDefaultDialer(userId);
+            }
+        }
+
+        @Override
+        public String getDefaultHome(int userId) {
+            synchronized (mLock) {
+                return mDefaultHomeProvider == null
+                        ? null : mDefaultHomeProvider.getDefaultHome(userId);
+            }
+        }
+
+        @Override
+        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy
+                        .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
+            }
+        }
+
+        @Override
+        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy
+                        .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
+            }
+        }
+
+        @Override
+        public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy
+                        .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
+            }
+        }
+
+        @Override
+        public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
+            synchronized (mLock) {
+                return mDefaultPermissionGrantPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
+            }
+        }
+
+        @Override
+        public void onNewUserCreated(int userId) {
+            synchronized (mLock) {
+                mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
+                // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
+                PermissionManagerService.this.updateAllPermissions(
+                        StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
+            }
+        }
+    }
+
+    private static final class OnPermissionChangeListeners extends Handler {
+        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
+
+        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
+                new RemoteCallbackList<>();
+
+        OnPermissionChangeListeners(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_ON_PERMISSIONS_CHANGED: {
+                    final int uid = msg.arg1;
+                    handleOnPermissionsChanged(uid);
+                } break;
+            }
+        }
+
+        public void addListenerLocked(IOnPermissionsChangeListener listener) {
+            mPermissionListeners.register(listener);
+
+        }
+
+        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
+            mPermissionListeners.unregister(listener);
+        }
+
+        public void onPermissionsChanged(int uid) {
+            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
+                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
+            }
+        }
+
+        private void handleOnPermissionsChanged(int uid) {
+            final int count = mPermissionListeners.beginBroadcast();
+            try {
+                for (int i = 0; i < count; i++) {
+                    IOnPermissionsChangeListener callback = mPermissionListeners
+                            .getBroadcastItem(i);
+                    try {
+                        callback.onPermissionsChanged(uid);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Permission listener is dead", e);
+                    }
+                }
+            } finally {
+                mPermissionListeners.finishBroadcast();
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index fc92a77..04ec5ba 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -16,18 +16,18 @@
 
 package com.android.server.pm.permission;
 
+import android.annotation.AppIdInt;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.PermissionInfoFlags;
 import android.content.pm.PackageParser;
-import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
 import android.permission.PermissionManagerInternal;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
+import java.util.function.Consumer;
 
 /**
  * Internal interfaces services.
@@ -36,6 +36,109 @@
  */
 public abstract class PermissionManagerServiceInternal extends PermissionManagerInternal {
     /**
+     * Provider for package names.
+     */
+    public interface PackagesProvider {
+
+        /**
+         * Gets the packages for a given user.
+         * @param userId The user id.
+         * @return The package names.
+         */
+        String[] getPackages(int userId);
+    }
+
+    /**
+     * Provider for package names.
+     */
+    public interface SyncAdapterPackagesProvider {
+
+        /**
+         * Gets the sync adapter packages for given authority and user.
+         * @param authority The authority.
+         * @param userId The user id.
+         * @return The package names.
+         */
+        String[] getPackages(String authority, int userId);
+    }
+
+    /**
+     * Provider for default browser
+     */
+    public interface DefaultBrowserProvider {
+
+        /**
+         * Get the package name of the default browser.
+         *
+         * @param userId the user id
+         *
+         * @return the package name of the default browser, or {@code null} if none
+         */
+        @Nullable
+        String getDefaultBrowser(@UserIdInt int userId);
+
+        /**
+         * Set the package name of the default browser.
+         *
+         * @param packageName package name of the default browser, or {@code null} to remove
+         * @param userId the user id
+         *
+         * @return whether the default browser was successfully set.
+         */
+        boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId);
+
+        /**
+         * Set the package name of the default browser asynchronously.
+         *
+         * @param packageName package name of the default browser, or {@code null} to remove
+         * @param userId the user id
+         */
+        void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId);
+    }
+
+    /**
+     * Provider for default dialer
+     */
+    public interface DefaultDialerProvider {
+
+        /**
+         * Get the package name of the default dialer.
+         *
+         * @param userId the user id
+         *
+         * @return the package name of the default dialer, or {@code null} if none
+         */
+        @Nullable
+        String getDefaultDialer(@UserIdInt int userId);
+    }
+
+    /**
+     * Provider for default home
+     */
+    public interface DefaultHomeProvider {
+
+        /**
+         * Get the package name of the default home.
+         *
+         * @param userId the user id
+         *
+         * @return the package name of the default home, or {@code null} if none
+         */
+        @Nullable
+        String getDefaultHome(@UserIdInt int userId);
+
+        /**
+         * Set the package name of the default home.
+         *
+         * @param packageName package name of the default home, or {@code null} to remove
+         * @param userId the user id
+         * @param callback the callback made after the default home as been updated
+         */
+        void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
+                @NonNull Consumer<Boolean> callback);
+    }
+
+    /**
      * Callbacks invoked when interesting actions have been taken on a permission.
      * <p>
      * NOTE: The current arguments are merely to support the existing use cases. This
@@ -43,51 +146,49 @@
      * callback methods.
      */
     public static class PermissionCallback {
-        public void onGidsChanged(int appId, int userId) {
+        public void onGidsChanged(@AppIdInt int appId, @UserIdInt int userId) {
         }
         public void onPermissionChanged() {
         }
-        public void onPermissionGranted(int uid, int userId) {
+        public void onPermissionGranted(int uid, @UserIdInt int userId) {
         }
         public void onInstallPermissionGranted() {
         }
-        public void onPermissionRevoked(int uid, int userId) {
+        public void onPermissionRevoked(int uid, @UserIdInt int userId) {
         }
         public void onInstallPermissionRevoked() {
         }
-        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
+        public void onPermissionUpdated(@UserIdInt int[] updatedUserIds, boolean sync) {
+        }
+        public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
+                int uid) {
         }
         public void onPermissionRemoved() {
         }
         public void onInstallPermissionUpdated() {
         }
+        public void onInstallPermissionUpdatedNotifyListener(int uid) {
+        }
     }
 
     public abstract void systemReady();
 
-    public abstract boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId);
+    public abstract boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
+            @UserIdInt int userId);
 
-    public abstract void grantRuntimePermission(
-            @NonNull String permName, @NonNull String packageName, boolean overridePolicy,
-            int callingUid, int userId, @Nullable PermissionCallback callback);
     public abstract void grantRuntimePermissionsGrantedToDisabledPackage(
-            @NonNull PackageParser.Package pkg, int callingUid,
-            @Nullable PermissionCallback callback);
+            @NonNull PackageParser.Package pkg, int callingUid);
     public abstract void grantRequestedRuntimePermissions(
             @NonNull PackageParser.Package pkg, @NonNull int[] userIds,
-            @NonNull String[] grantedPermissions, int callingUid,
-            @Nullable PermissionCallback callback);
-    public abstract @Nullable List<String> getWhitelistedRestrictedPermissions(
-            @NonNull PackageParser.Package pkg,
-            @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId);
+            @NonNull String[] grantedPermissions, int callingUid);
     public abstract void setWhitelistedRestrictedPermissions(
             @NonNull PackageParser.Package pkg, @NonNull int[] userIds,
             @NonNull List<String> permissions, int callingUid,
-            @PackageManager.PermissionWhitelistFlags int whitelistFlags,
-            @Nullable PermissionCallback callback);
-    public abstract void revokeRuntimePermission(@NonNull String permName,
-            @NonNull String packageName, boolean overridePolicy, int userId,
-            @Nullable PermissionCallback callback);
+            @PackageManager.PermissionWhitelistFlags int whitelistFlags);
+    /** Sets the whitelisted, restricted permissions for the given package. */
+    public abstract void setWhitelistedRestrictedPermissions(
+            @NonNull String packageName, @NonNull List<String> permissions,
+            @PackageManager.PermissionWhitelistFlags int flags, @NonNull int userId);
 
     /**
      * Update permissions when a package changed.
@@ -103,9 +204,7 @@
      * @param callback Callback to call after permission changes
      */
     public abstract void updatePermissions(@NonNull String packageName,
-            @Nullable PackageParser.Package pkg,
-            @NonNull Collection<PackageParser.Package> allPackages,
-            @NonNull PermissionCallback callback);
+            @Nullable PackageParser.Package pkg);
 
     /**
      * Update all permissions for all apps.
@@ -119,9 +218,22 @@
      * @param allPackages All currently known packages
      * @param callback Callback to call after permission changes
      */
-    public abstract void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdate,
-            @NonNull Collection<PackageParser.Package> allPackages,
-            @NonNull PermissionCallback callback);
+    public abstract void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdate);
+
+    /**
+     * Resets any user permission state changes (eg. permissions and flags) of all
+     * packages installed for the given user.
+     *
+     * @see #resetRuntimePermissions(android.content.pm.PackageParser.Package, int)
+     */
+    public abstract void resetAllRuntimePermissions(@UserIdInt int userId);
+
+    /**
+     * Resets any user permission state changes (eg. permissions and flags) of the
+     * specified package for the given user.
+     */
+    public abstract void resetRuntimePermissions(@NonNull PackageParser.Package pkg,
+            @UserIdInt int userId);
 
     /**
      * We might auto-grant permissions if any permission of the group is already granted. Hence if
@@ -131,13 +243,11 @@
      * @param newPackage The new package that was installed
      * @param oldPackage The old package that was updated
      * @param allPackageNames All packages
-     * @param permissionCallback Callback for permission changed
      */
     public abstract void revokeRuntimePermissionsIfGroupChanged(
             @NonNull PackageParser.Package newPackage,
             @NonNull PackageParser.Package oldPackage,
-            @NonNull ArrayList<String> allPackageNames,
-            @NonNull PermissionCallback permissionCallback);
+            @NonNull ArrayList<String> allPackageNames);
 
     /**
      * Add all permissions in the given package.
@@ -148,55 +258,10 @@
     public abstract void addAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty);
     public abstract void addAllPermissionGroups(@NonNull PackageParser.Package pkg, boolean chatty);
     public abstract void removeAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty);
-    public abstract boolean addDynamicPermission(@NonNull PermissionInfo info, boolean async,
-            int callingUid, @Nullable PermissionCallback callback);
-    public abstract void removeDynamicPermission(@NonNull String permName, int callingUid,
-            @Nullable PermissionCallback callback);
 
-    public abstract @Nullable String[] getAppOpPermissionPackages(@NonNull String permName);
-
-    public abstract int getPermissionFlags(@NonNull String permName,
-            @NonNull String packageName, int callingUid, int userId);
-    /**
-     * Retrieve all of the information we know about a particular group of permissions.
-     */
-    public abstract @Nullable PermissionGroupInfo getPermissionGroupInfo(
-            @NonNull String groupName, int flags, int callingUid);
-    /**
-     * Retrieve all of the known permission groups in the system.
-     */
-    public abstract @Nullable List<PermissionGroupInfo> getAllPermissionGroups(int flags,
-            int callingUid);
-    /**
-     * Retrieve all of the information we know about a particular permission.
-     */
-    public abstract @Nullable PermissionInfo getPermissionInfo(@NonNull String permName,
-            @NonNull String packageName, @PermissionInfoFlags int flags, int callingUid);
-    /**
-     * Retrieve all of the permissions associated with a particular group.
-     */
-    public abstract @Nullable List<PermissionInfo> getPermissionInfoByGroup(@NonNull String group,
-            @PermissionInfoFlags int flags, int callingUid);
-
-    /**
-     * Updates the flags associated with a permission by replacing the flags in
-     * the specified mask with the provided flag values.
-     */
-    public abstract void updatePermissionFlags(@NonNull String permName,
-            @NonNull String packageName, int flagMask, int flagValues, int callingUid, int userId,
-            boolean overridePolicy, @Nullable PermissionCallback callback);
-    /**
-     * Updates the flags for all applications by replacing the flags in the specified mask
-     * with the provided flag values.
-     */
-    public abstract boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues,
-            int callingUid, int userId, @NonNull Collection<PackageParser.Package> packages,
-            @Nullable PermissionCallback callback);
-
-    public abstract int checkPermission(@NonNull String permName, @NonNull String packageName,
-            int callingUid, int userId);
-    public abstract int checkUidPermission(@NonNull String permName,
-            @Nullable PackageParser.Package pkg, int uid, int callingUid);
+    /** Retrieve the packages that have requested the given app op permission */
+    public abstract @Nullable String[] getAppOpPermissionPackages(
+            @NonNull String permName, int callingUid);
 
     /**
      * Enforces the request is from the system or an app that has INTERACT_ACROSS_USERS
@@ -217,8 +282,167 @@
     public abstract void enforceGrantRevokeRuntimePermissionPermissions(@NonNull String message);
 
     public abstract @NonNull PermissionSettings getPermissionSettings();
-    public abstract @NonNull DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy();
+
+    /** Grants default browser permissions to the given package */
+    public abstract void grantDefaultPermissionsToDefaultBrowser(
+            @NonNull String packageName, @UserIdInt int userId);
 
     /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
     public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
+
+    /** Get all permission that have a certain protection level */
+    public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
+            @PermissionInfo.Protection int protectionLevel);
+
+    /**
+     * Returns the delegate used to influence permission checking.
+     *
+     * @return The delegate instance.
+     */
+    public abstract @Nullable CheckPermissionDelegate getCheckPermissionDelegate();
+
+    /**
+     * Sets the delegate used to influence permission checking.
+     *
+     * @param delegate A delegate instance or {@code null} to clear.
+     */
+    public abstract void setCheckPermissionDelegate(@Nullable CheckPermissionDelegate delegate);
+
+    /**
+     * Sets the dialer application packages provider.
+     * @param provider The provider.
+     */
+    public abstract void setDialerAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Set the location extra packages provider.
+     * @param provider The packages provider.
+     */
+    public abstract  void setLocationExtraPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the location provider packages provider.
+     * @param provider The packages provider.
+     */
+    public abstract void setLocationPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the SIM call manager packages provider.
+     * @param provider The provider.
+     */
+    public abstract void setSimCallManagerPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the SMS application packages provider.
+     * @param provider The provider.
+     */
+    public abstract void setSmsAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the sync adapter packages provider.
+     * @param provider The provider.
+     */
+    public abstract void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider);
+
+    /**
+     * Sets the Use Open Wifi packages provider.
+     * @param provider The packages provider.
+     */
+    public abstract void setUseOpenWifiAppPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the voice interaction packages provider.
+     * @param provider The packages provider.
+     */
+    public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider);
+
+    /**
+     * Sets the default browser provider.
+     *
+     * @param provider the provider
+     */
+    public abstract void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider);
+
+    /**
+     * Sets the package name of the default browser provider for the given user.
+     *
+     * @param packageName The package name of the default browser or {@code null}
+     *          to clear the default browser
+     * @param async If {@code true}, set the default browser asynchronously,
+     *          otherwise set it synchronously
+     * @param doGrant If {@code true} and if {@code packageName} is not {@code null},
+     *          perform default permission grants on the browser, otherwise skip the
+     *          default permission grants.
+     * @param userId The user to set the default browser for.
+     */
+    public abstract void setDefaultBrowser(@Nullable String packageName, boolean async,
+            boolean doGrant, @UserIdInt int userId);
+
+    /**
+     * Sets the default dialer provider.
+     *
+     * @param provider the provider
+     */
+    public abstract void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider);
+
+    /**
+     * Sets the default home provider.
+     *
+     * @param provider the provider
+     */
+    public abstract void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider);
+
+    /**
+     * Asynchronously sets the package name of the default home provider for the given user.
+     *
+     * @param packageName The package name of the default home or {@code null}
+     *          to clear the default browser
+     * @param userId The user to set the default browser for
+     * @param callback Invoked after the default home has been set
+     */
+    public abstract void setDefaultHome(@Nullable String packageName, @UserIdInt int userId,
+            @NonNull Consumer<Boolean> callback);
+
+    /**
+     * Returns the default browser package name for the given user.
+     */
+    @Nullable
+    public abstract String getDefaultBrowser(@UserIdInt int userId);
+
+    /**
+     * Returns the default dialer package name for the given user.
+     */
+    @Nullable
+    public abstract String getDefaultDialer(@UserIdInt int userId);
+
+    /**
+     * Returns the default home package name for the given user.
+     */
+    @Nullable
+    public abstract String getDefaultHome(@UserIdInt int userId);
+
+    /**
+     * Requests granting of the default permissions to the current default Use Open Wifi app.
+     * @param packageName The default use open wifi package name.
+     * @param userId The user for which to grant the permissions.
+     */
+    public abstract void grantDefaultPermissionsToDefaultSimCallManager(
+            @NonNull String packageName, @UserIdInt int userId);
+
+    /**
+     * Requests granting of the default permissions to the current default Use Open Wifi app.
+     * @param packageName The default use open wifi package name.
+     * @param userId The user for which to grant the permissions.
+     */
+    public abstract void grantDefaultPermissionsToDefaultUseOpenWifiApp(
+            @NonNull String packageName, @UserIdInt int userId);
+
+    /**
+     * Returns whether or not default permission grants have been performed for the given
+     * user since the device booted.
+     */
+    public abstract boolean wereDefaultPermissionsGrantedSinceBoot(@UserIdInt int userId);
+
+    /** Called when a new user has been created. */
+    public abstract void onNewUserCreated(@UserIdInt int userId);
 }
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 3f9eb2d..af94e44 100644
--- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
@@ -53,6 +53,14 @@
                     "include-filter": "android.appsecurity.cts.AppSecurityTests#testPermissionDiffCert"
                 }
             ]
+        },
+        {
+            "name": "CtsPermissionTestCases",
+            "options": [
+                {
+                    "include-filter": "android.permission.cts.PermissionUpdateListenerTest"
+                }
+            ]
         }
     ]
 }
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index a799cd9..8da7f7b 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -16,10 +16,16 @@
 
 package com.android.server.policy;
 
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+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_NONE;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 
-import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
@@ -36,20 +42,29 @@
 import android.content.pm.PermissionInfo;
 import android.os.Build;
 import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManagerInternal;
 import android.permission.PermissionControllerManager;
-import android.permission.PermissionManagerInternal;
 import android.provider.Telephony;
 import android.telecom.TelecomManager;
+import android.util.ArraySet;
+import android.util.LongSparseLongArray;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IAppOpsCallback;
+import com.android.internal.app.IAppOpsService;
+import com.android.internal.util.IntPair;
+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.pm.permission.PermissionManagerServiceInternal;
 
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
@@ -71,6 +86,13 @@
     @GuardedBy("mLock")
     private final SparseBooleanArray mIsStarted = new SparseBooleanArray();
 
+    /**
+     * Whether an async {@link #synchronizePackagePermissionsAndAppOpsForUser} is currently
+     * scheduled for a package/user.
+     */
+    @GuardedBy("mLock")
+    private final ArraySet<Pair<String, Integer>> mIsPackageSyncsScheduled = new ArraySet<>();
+
     public PermissionPolicyService(@NonNull Context context) {
         super(context);
 
@@ -81,8 +103,10 @@
     public void onStart() {
         final PackageManagerInternal packageManagerInternal = LocalServices.getService(
                 PackageManagerInternal.class);
-        final PermissionManagerInternal permManagerInternal = LocalServices.getService(
-                PermissionManagerInternal.class);
+        final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService(
+                PermissionManagerServiceInternal.class);
+        final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
+                ServiceManager.getService(Context.APP_OPS_SERVICE));
 
         packageManagerInternal.getPackageList(new PackageListObserver() {
             @Override
@@ -106,11 +130,79 @@
         });
 
         permManagerInternal.addOnRuntimePermissionStateChangedListener(
-                (packageName, changedUserId) -> {
-                    if (isStarted(changedUserId)) {
-                        synchronizePackagePermissionsAndAppOpsForUser(packageName, changedUserId);
+                this::synchronizePackagePermissionsAndAppOpsAsyncForUser);
+
+        IAppOpsCallback appOpsListener = new IAppOpsCallback.Stub() {
+            public void opChanged(int op, int uid, String packageName) {
+                synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName,
+                        UserHandle.getUserId(uid));
+            }
+        };
+
+        final ArrayList<PermissionInfo> dangerousPerms =
+                permManagerInternal.getAllPermissionWithProtectionLevel(
+                        PermissionInfo.PROTECTION_DANGEROUS);
+
+        try {
+            int numDangerousPerms = dangerousPerms.size();
+            for (int i = 0; i < numDangerousPerms; i++) {
+                PermissionInfo perm = dangerousPerms.get(i);
+
+                if (perm.isHardRestricted() || perm.backgroundPermission != null) {
+                    appOpsService.startWatchingMode(getSwitchOp(perm.name), null, appOpsListener);
+                } else if (perm.isSoftRestricted()) {
+                    appOpsService.startWatchingMode(getSwitchOp(perm.name), null, appOpsListener);
+
+                    SoftRestrictedPermissionPolicy policy =
+                            SoftRestrictedPermissionPolicy.forPermission(null, null, null,
+                                    perm.name);
+                    if (policy.resolveAppOp() != OP_NONE) {
+                        appOpsService.startWatchingMode(policy.resolveAppOp(), null,
+                                appOpsListener);
                     }
-                });
+                }
+            }
+        } catch (RemoteException doesNotHappen) {
+            Slog.wtf(LOG_TAG, "Cannot set up app-ops listener");
+        }
+    }
+
+    /**
+     * Get op that controls the access related to the permission.
+     *
+     * <p>Usually the permission-op relationship is 1:1 but some permissions (e.g. fine location)
+     * {@link AppOpsManager#sOpToSwitch share an op} to control the access.
+     *
+     * @param permission The permission
+     *
+     * @return The op that controls the access of the permission
+     */
+    private static int getSwitchOp(@NonNull String permission) {
+        int op = AppOpsManager.permissionToOpCode(permission);
+        if (op == OP_NONE) {
+            return OP_NONE;
+        }
+
+        return AppOpsManager.opToSwitch(op);
+    }
+
+    private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
+            @UserIdInt int changedUserId) {
+        if (isStarted(changedUserId)) {
+            synchronized (mLock) {
+                if (mIsPackageSyncsScheduled.add(new Pair<>(packageName, changedUserId))) {
+                    FgThread.getHandler().sendMessage(PooledLambda.obtainMessage(
+                            PermissionPolicyService
+                                    ::synchronizePackagePermissionsAndAppOpsForUser,
+                            this, packageName, changedUserId));
+                } else {
+                    if (DEBUG) {
+                        Slog.v(LOG_TAG, "sync for " + packageName + "/" + changedUserId
+                                + " already scheduled");
+                    }
+                }
+            }
+        }
     }
 
     @Override
@@ -168,9 +260,11 @@
     private void grantOrUpgradeDefaultRuntimePermissionsIfNeeded(@UserIdInt int userId) {
         if (DEBUG) Slog.i(LOG_TAG, "grantOrUpgradeDefaultPermsIfNeeded(" + userId + ")");
 
-        final PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        if (packageManagerInternal.wereDefaultPermissionsGrantedSinceBoot(userId)) {
+        final PackageManagerInternal packageManagerInternal =
+                LocalServices.getService(PackageManagerInternal.class);
+        final PermissionManagerServiceInternal permissionManagerInternal =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
+        if (permissionManagerInternal.wereDefaultPermissionsGrantedSinceBoot(userId)) {
             if (DEBUG) Slog.i(LOG_TAG, "defaultPermsWereGrantedSinceBoot(" + userId + ")");
 
             // Now call into the permission controller to apply policy around permissions
@@ -225,10 +319,14 @@
      */
     private void synchronizePackagePermissionsAndAppOpsForUser(@NonNull String packageName,
             @UserIdInt int userId) {
+        synchronized (mLock) {
+            mIsPackageSyncsScheduled.remove(new Pair<>(packageName, userId));
+        }
+
         if (DEBUG) {
             Slog.v(LOG_TAG,
-                    "synchronizePackagePermissionsAndAppOpsForUser(" + packageName + ", " + userId
-                            + ")");
+                    "synchronizePackagePermissionsAndAppOpsForUser(" + packageName + ", "
+                            + userId + ")");
         }
 
         final PackageManagerInternal packageManagerInternal = LocalServices.getService(
@@ -286,43 +384,60 @@
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
-        private final @NonNull ArrayList<OpToRestrict> mOpsToDefault = new ArrayList<>();
+        private final @NonNull ArrayList<OpToChange> mOpsToDefault = new ArrayList<>();
 
         /**
          * All ops that need to be flipped to allow if default.
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
-        private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllowIfDefault = new ArrayList<>();
+        private final @NonNull ArrayList<OpToChange> mOpsToAllowIfDefault = new ArrayList<>();
 
         /**
          * All ops that need to be flipped to allow.
          *
-         * Currently, only used by the restricted permissions logic.
-         *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
-        private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllow = new ArrayList<>();
+        private final @NonNull ArrayList<OpToChange> mOpsToAllow = new ArrayList<>();
 
         /**
          * All ops that need to be flipped to ignore if default.
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
-        private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnoreIfDefault = new ArrayList<>();
+        private final @NonNull ArrayList<OpToChange> mOpsToIgnoreIfDefault = new ArrayList<>();
 
         /**
-         * All foreground permissions
+         * All ops that need to be flipped to ignore.
          *
-         * @see #syncOpsOfFgPermissions()
+         * @see #syncPackages
          */
-        private final @NonNull ArrayList<FgPermission> mFgPermOps = new ArrayList<>();
+        private final @NonNull ArrayList<OpToChange> mOpsToIgnore = new ArrayList<>();
+
+        /**
+         * All ops that need to be flipped to foreground.
+         *
+         * Currently, only used by the foreground/background permissions logic.
+         *
+         * @see #syncPackages
+         */
+        private final @NonNull ArrayList<OpToChange> mOpsToForeground = new ArrayList<>();
+
+        /**
+         * All ops that need to be flipped to foreground if allow.
+         *
+         * Currently, only used by the foreground/background permissions logic.
+         *
+         * @see #syncPackages
+         */
+        private final @NonNull ArrayList<OpToChange> mOpsToForegroundIfAllow =
+                new ArrayList<>();
 
         PermissionToOpSynchroniser(@NonNull Context context) {
             mContext = context;
@@ -331,74 +446,100 @@
         }
 
         /**
-         * Set app ops that belong to restricted permissions.
+         * Set app ops that were added in {@link #addPackage}.
          *
          * <p>This processes ops previously added by {@link #addOpIfRestricted}
          */
-        private void syncRestrictedOps() {
+        private void syncPackages() {
+            // Remember which ops were already set. This makes sure that we always set the most
+            // permissive mode if two OpChanges are scheduled. This can e.g. happen if two
+            // permissions change the same op. See {@link #getSwitchOp}.
+            LongSparseLongArray alreadySetAppOps = new LongSparseLongArray();
+
             final int allowCount = mOpsToAllow.size();
             for (int i = 0; i < allowCount; i++) {
-                final OpToUnrestrict op = mOpsToAllow.get(i);
-                setUidModeAllowed(op.code, op.uid);
+                final OpToChange op = mOpsToAllow.get(i);
+
+                setUidModeAllowed(op.code, op.uid, op.packageName);
+                alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
             }
+
             final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
             for (int i = 0; i < allowIfDefaultCount; i++) {
-                final OpToUnrestrict op = mOpsToAllowIfDefault.get(i);
-                setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
-            }
-            final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
-            for (int i = 0; i < ignoreIfDefaultCount; i++) {
-                final OpToUnrestrict op = mOpsToIgnoreIfDefault.get(i);
-                setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
-            }
-            final int defaultCount = mOpsToDefault.size();
-            for (int i = 0; i < defaultCount; i++) {
-                final OpToRestrict op = mOpsToDefault.get(i);
-                setUidModeDefault(op.code, op.uid);
-            }
-        }
+                final OpToChange op = mOpsToAllowIfDefault.get(i);
+                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
+                    continue;
+                }
 
-        /**
-         * Set app ops that belong to restricted permissions.
-         *
-         * <p>This processed ops previously added by {@link #addOpIfRestricted}
-         */
-        private void syncOpsOfFgPermissions() {
-            int numFgPermOps = mFgPermOps.size();
-            for (int i = 0; i < numFgPermOps; i++) {
-                FgPermission perm = mFgPermOps.get(i);
-
-                if (mPackageManager.checkPermission(perm.fgPermissionName, perm.packageName)
-                        == PackageManager.PERMISSION_GRANTED) {
-                    if (mPackageManager.checkPermission(perm.bgPermissionName, perm.packageName)
-                            == PackageManager.PERMISSION_GRANTED) {
-                        mAppOpsManager.setUidMode(
-                                AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                                AppOpsManager.MODE_ALLOWED);
-                    } else {
-                        mAppOpsManager.setUidMode(
-                                AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                                AppOpsManager.MODE_FOREGROUND);
-                    }
-                } else {
-                    mAppOpsManager.setUidMode(
-                            AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                            AppOpsManager.MODE_IGNORED);
+                boolean wasSet = setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
+                if (wasSet) {
+                    alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
                 }
             }
-        }
 
-        /**
-         * Synchronize all previously {@link #addPackage added} packages.
-         */
-        void syncPackages() {
-            syncRestrictedOps();
-            syncOpsOfFgPermissions();
+            final int foregroundIfAllowedCount = mOpsToForegroundIfAllow.size();
+            for (int i = 0; i < foregroundIfAllowedCount; i++) {
+                final OpToChange op = mOpsToForegroundIfAllow.get(i);
+                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
+                    continue;
+                }
+
+                boolean wasSet = setUidModeForegroundIfAllow(op.code, op.uid, op.packageName);
+                if (wasSet) {
+                    alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
+                }
+            }
+
+            final int foregroundCount = mOpsToForeground.size();
+            for (int i = 0; i < foregroundCount; i++) {
+                final OpToChange op = mOpsToForeground.get(i);
+                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
+                    continue;
+                }
+
+                setUidModeForeground(op.code, op.uid, op.packageName);
+                alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
+            }
+
+            final int ignoreCount = mOpsToIgnore.size();
+            for (int i = 0; i < ignoreCount; i++) {
+                final OpToChange op = mOpsToIgnore.get(i);
+                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
+                    continue;
+                }
+
+                setUidModeIgnored(op.code, op.uid, op.packageName);
+                alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
+            }
+
+            final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
+            for (int i = 0; i < ignoreIfDefaultCount; i++) {
+                final OpToChange op = mOpsToIgnoreIfDefault.get(i);
+                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
+                    continue;
+                }
+
+                boolean wasSet = setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
+                if (wasSet) {
+                    alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
+                }
+            }
+
+            final int defaultCount = mOpsToDefault.size();
+            for (int i = 0; i < defaultCount; i++) {
+                final OpToChange op = mOpsToDefault.get(i);
+                if (alreadySetAppOps.indexOfKey(IntPair.of(op.uid, op.code)) >= 0) {
+                    continue;
+                }
+
+                setUidModeDefault(op.code, op.uid, op.packageName);
+                alreadySetAppOps.put(IntPair.of(op.uid, op.code), 1);
+            }
         }
 
         /**
          * Add op that belong to a restricted permission for later processing in
-         * {@link #syncRestrictedOps}.
+         * {@link #syncPackages()}.
          *
          * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
          *
@@ -408,7 +549,7 @@
         private void addOpIfRestricted(@NonNull PermissionInfo permissionInfo,
                 @NonNull PackageInfo pkg) {
             final String permission = permissionInfo.name;
-            final int opCode = AppOpsManager.permissionToOpCode(permission);
+            final int opCode = getSwitchOp(permission);
             final int uid = pkg.applicationInfo.uid;
 
             if (!permissionInfo.isRestricted()) {
@@ -420,44 +561,132 @@
                     mContext.getUser()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
 
             if (permissionInfo.isHardRestricted()) {
-                if (applyRestriction) {
-                    mOpsToDefault.add(new OpToRestrict(uid, opCode));
-                } else {
-                    mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+                if (opCode != OP_NONE) {
+                    if (applyRestriction) {
+                        mOpsToDefault.add(new OpToChange(uid, pkg.packageName, opCode));
+                    } else {
+                        mOpsToAllowIfDefault.add(new OpToChange(uid, pkg.packageName, opCode));
+                    }
                 }
             } else if (permissionInfo.isSoftRestricted()) {
-                // Storage uses a special app op to decide the mount state and
-                // supports soft restriction where the restricted state allows
-                // the permission but only for accessing the medial collections.
-                if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(permission)
-                        || Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) {
-                    if (applyRestriction) {
-                        mOpsToDefault.add(new OpToRestrict(uid,
-                                AppOpsManager.OP_LEGACY_STORAGE));
-                    } else if (pkg.applicationInfo.hasRequestedLegacyExternalStorage()) {
-                        mOpsToAllow.add(new OpToUnrestrict(uid, pkg.packageName,
-                                AppOpsManager.OP_LEGACY_STORAGE));
+                final SoftRestrictedPermissionPolicy policy =
+                        SoftRestrictedPermissionPolicy.forPermission(mContext, pkg.applicationInfo,
+                                mContext.getUser(), permission);
+
+                if (opCode != OP_NONE) {
+                    if (policy.canBeGranted()) {
+                        mOpsToAllowIfDefault.add(new OpToChange(uid, pkg.packageName, opCode));
                     } else {
-                        mOpsToIgnoreIfDefault.add(new OpToUnrestrict(uid, pkg.packageName,
-                                AppOpsManager.OP_LEGACY_STORAGE));
+                        mOpsToDefault.add(new OpToChange(uid, pkg.packageName, opCode));
+                    }
+                }
+
+                final int op = policy.resolveAppOp();
+                if (op != OP_NONE) {
+                    switch (policy.getDesiredOpMode()) {
+                        case MODE_DEFAULT:
+                            mOpsToDefault.add(new OpToChange(uid, pkg.packageName, op));
+                            break;
+                        case MODE_ALLOWED:
+                            if (policy.shouldSetAppOpIfNotDefault()) {
+                                mOpsToAllow.add(new OpToChange(uid, pkg.packageName, op));
+                            } else {
+                                mOpsToAllowIfDefault.add(
+                                        new OpToChange(uid, pkg.packageName, op));
+                            }
+                            break;
+                        case MODE_FOREGROUND:
+                            Slog.wtf(LOG_TAG,
+                                    "Setting appop to foreground is not implemented");
+                            break;
+                        case MODE_IGNORED:
+                            if (policy.shouldSetAppOpIfNotDefault()) {
+                                mOpsToIgnore.add(new OpToChange(uid, pkg.packageName, op));
+                            } else {
+                                mOpsToIgnoreIfDefault.add(
+                                        new OpToChange(uid, pkg.packageName,
+                                                op));
+                            }
+                            break;
+                        case MODE_ERRORED:
+                            Slog.wtf(LOG_TAG, "Setting appop to errored is not implemented");
                     }
                 }
             }
         }
 
+        private boolean isBgPermRestricted(@NonNull String pkg, @NonNull String perm, int uid) {
+            try {
+                final PermissionInfo bgPermInfo = mPackageManager.getPermissionInfo(perm, 0);
+
+                if (bgPermInfo.isSoftRestricted()) {
+                    Slog.wtf(LOG_TAG, "Support for soft restricted background permissions not "
+                            + "implemented");
+                }
+
+                return bgPermInfo.isHardRestricted() && (mPackageManager.getPermissionFlags(
+                                perm, pkg, UserHandle.getUserHandleForUid(uid))
+                                & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+            } catch (NameNotFoundException e) {
+                Slog.w(LOG_TAG, "Cannot read permission state of " + perm, e);
+                return false;
+            }
+        }
+
+        /**
+         * Add op that belong to a foreground permission for later processing in
+         * {@link #syncPackages()}.
+         *
+         * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
+         *
+         * @param permissionInfo The permission that is currently looked at
+         * @param pkg The package looked at
+         */
         private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo,
                 @NonNull PackageInfo pkg) {
+            final String bgPermissionName = permissionInfo.backgroundPermission;
+
+            if (bgPermissionName == null) {
+                return;
+            }
+
+            final String permission = permissionInfo.name;
+            final int opCode = getSwitchOp(permission);
+            final String pkgName = pkg.packageName;
+            final int uid = pkg.applicationInfo.uid;
+
+            // App does not support runtime permissions. Hence the state is encoded in the app-op.
+            // To not override unrecoverable state don't change app-op unless bg perm is reviewed.
             if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
-                // Pre-M apps do not store their fg/bg state in the permissions
+                // If the review is required for this permission, the grant state does not
+                // really matter. To have a stable state, don't change the app-op if review is still
+                // pending.
+                int flags = mPackageManager.getPermissionFlags(bgPermissionName,
+                        pkg.packageName, UserHandle.getUserHandleForUid(uid));
+
+                if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0
+                        && isBgPermRestricted(pkgName, bgPermissionName, uid)) {
+                    mOpsToForegroundIfAllow.add(new OpToChange(uid, pkgName, opCode));
+                }
+
                 return;
             }
 
-            if (permissionInfo.backgroundPermission == null) {
-                return;
-            }
+            if (mPackageManager.checkPermission(permission, pkgName)
+                    == PackageManager.PERMISSION_GRANTED) {
+                final boolean isBgHardRestricted = isBgPermRestricted(pkgName, bgPermissionName,
+                        uid);
+                final boolean isBgPermGranted = mPackageManager.checkPermission(bgPermissionName,
+                        pkgName) == PackageManager.PERMISSION_GRANTED;
 
-            mFgPermOps.add(new FgPermission(pkg.applicationInfo.uid, pkg.packageName,
-                    permissionInfo.name, permissionInfo.backgroundPermission));
+                if (!isBgHardRestricted && isBgPermGranted) {
+                    mOpsToAllow.add(new OpToChange(uid, pkgName, opCode));
+                } else {
+                    mOpsToForeground.add(new OpToChange(uid, pkgName, opCode));
+                }
+            } else {
+                mOpsToIgnore.add(new OpToChange(uid, pkgName, opCode));
+            }
         }
 
         /**
@@ -482,8 +711,8 @@
             }
 
             for (String permission : pkg.requestedPermissions) {
-                final int opCode = AppOpsManager.permissionToOpCode(permission);
-                if (opCode == AppOpsManager.OP_NONE) {
+                final int opCode = getSwitchOp(permission);
+                if (opCode == OP_NONE) {
                     continue;
                 }
 
@@ -499,67 +728,71 @@
             }
         }
 
-        private void setUidModeAllowedIfDefault(int opCode, int uid, @NonNull String packageName) {
-            setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_ALLOWED, packageName);
+        private boolean setUidModeAllowedIfDefault(int opCode, int uid,
+                @NonNull String packageName) {
+            return setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_ALLOWED, packageName);
         }
 
-        private void setUidModeAllowed(int opCode, int uid) {
-            mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
+        private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
+            setUidMode(opCode, uid, MODE_ALLOWED, packageName);
         }
 
-        private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
-            setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
+        private boolean setUidModeForegroundIfAllow(int opCode, int uid,
+                @NonNull String packageName) {
+            return setUidModeIfMode(opCode, uid, MODE_ALLOWED, MODE_FOREGROUND, packageName);
         }
 
-        private void setUidModeIfDefault(int opCode, int uid, int mode,
+        private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
+            setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
+        }
+
+        private boolean setUidModeIgnoredIfDefault(int opCode, int uid,
+                @NonNull String packageName) {
+            return setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_IGNORED, packageName);
+        }
+
+        private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) {
+            setUidMode(opCode, uid, MODE_IGNORED, packageName);
+        }
+
+        private void setUidMode(int opCode, int uid, int mode,
                 @NonNull String packageName) {
             final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
                     .opToPublicName(opCode), uid, packageName);
-            if (currentMode == AppOpsManager.MODE_DEFAULT) {
+
+            if (currentMode != mode) {
                 mAppOpsManager.setUidMode(opCode, uid, mode);
             }
         }
 
-        private void setUidModeDefault(int opCode, int uid) {
-            mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_DEFAULT);
-        }
+        private boolean setUidModeIfMode(int opCode, int uid, int requiredModeBefore, int newMode,
+                @NonNull String packageName) {
+            final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
+                    .opToPublicName(opCode), uid, packageName);
 
-        private class OpToRestrict {
-            final int uid;
-            final int code;
-
-            OpToRestrict(int uid, int code) {
-                this.uid = uid;
-                this.code = code;
+            if (currentMode == requiredModeBefore) {
+                mAppOpsManager.setUidMode(opCode, uid, newMode);
+                return true;
             }
+
+            return false;
         }
 
-        private class OpToUnrestrict {
+        private void setUidModeDefault(int opCode, int uid, String packageName) {
+            setUidMode(opCode, uid, MODE_DEFAULT, packageName);
+        }
+
+        private class OpToChange {
             final int uid;
             final @NonNull String packageName;
             final int code;
 
-            OpToUnrestrict(int uid, @NonNull String packageName, int code) {
+            OpToChange(int uid, @NonNull String packageName, int code) {
                 this.uid = uid;
                 this.packageName = packageName;
                 this.code = code;
             }
         }
-
-        private class FgPermission {
-            final int uid;
-            final @NonNull String packageName;
-            final @NonNull String fgPermissionName;
-            final @NonNull String bgPermissionName;
-
-            private FgPermission(int uid, @NonNull String packageName,
-                    @NonNull String fgPermissionName, @NonNull String bgPermissionName) {
-                this.uid = uid;
-                this.packageName = packageName;
-                this.fgPermissionName = fgPermissionName;
-                this.bgPermissionName = bgPermissionName;
-            }
-        }
     }
 
     private class Internal extends PermissionPolicyInternal {
@@ -567,7 +800,7 @@
         @Override
         public boolean checkStartActivity(@NonNull Intent intent, int callingUid,
                 @Nullable String callingPackage) {
-            if (callingPackage != null && isActionRemovedForCallingPackage(intent.getAction(),
+            if (callingPackage != null && isActionRemovedForCallingPackage(intent, callingUid,
                     callingPackage)) {
                 Slog.w(LOG_TAG, "Action Removed: starting " + intent.toString() + " from "
                         + callingPackage + " (uid=" + callingUid + ")");
@@ -580,8 +813,9 @@
          * Check if the intent action is removed for the calling package (often based on target SDK
          * version). If the action is removed, we'll silently cancel the activity launch.
          */
-        private boolean isActionRemovedForCallingPackage(@Nullable String action,
+        private boolean isActionRemovedForCallingPackage(@NonNull Intent intent, int callingUid,
                 @NonNull String callingPackage) {
+            String action = intent.getAction();
             if (action == null) {
                 return false;
             }
@@ -590,15 +824,19 @@
                 case Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT: {
                     ApplicationInfo applicationInfo;
                     try {
-                        applicationInfo = getContext().getPackageManager().getApplicationInfo(
-                                callingPackage, 0);
+                        applicationInfo = getContext().getPackageManager().getApplicationInfoAsUser(
+                                callingPackage, 0, UserHandle.getUserId(callingUid));
+                        if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) {
+                            // Applications targeting Q or higher should use
+                            // RoleManager.createRequestRoleIntent() instead.
+                            return true;
+                        }
                     } catch (PackageManager.NameNotFoundException e) {
                         Slog.i(LOG_TAG, "Cannot find application info for " + callingPackage);
-                        return false;
                     }
-                    // Applications targeting Q should use RoleManager.createRequestRoleIntent()
-                    // instead.
-                    return applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q;
+                    // Make sure RequestRoleActivity can know the calling package if we allow it.
+                    intent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);
+                    return false;
                 }
                 default:
                     return false;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d624a85..ab531899 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -107,6 +107,7 @@
 import android.app.ActivityTaskManager;
 import android.app.AppOpsManager;
 import android.app.IUiModeManager;
+import android.app.NotificationManager;
 import android.app.ProgressDialog;
 import android.app.SearchManager;
 import android.app.UiModeManager;
@@ -2517,14 +2518,21 @@
 
     @Override
     public Animation createHiddenByKeyguardExit(boolean onWallpaper,
-            boolean goingToNotificationShade) {
+            boolean goingToNotificationShade, boolean subtleAnimation) {
         if (goingToNotificationShade) {
             return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
         }
 
-        AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ?
-                    R.anim.lock_screen_behind_enter_wallpaper :
-                    R.anim.lock_screen_behind_enter);
+        final int resource;
+        if (subtleAnimation) {
+            resource = R.anim.lock_screen_behind_enter_subtle;
+        } else if (onWallpaper) {
+            resource = R.anim.lock_screen_behind_enter_wallpaper;
+        } else  {
+            resource = R.anim.lock_screen_behind_enter;
+        }
+
+        AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, resource);
 
         // TODO: Use XML interpolators when we have log interpolators available in XML.
         final List<Animation> animations = set.getAnimations();
@@ -2565,6 +2573,10 @@
         return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
     }
 
+    NotificationManager getNotificationService() {
+        return mContext.getSystemService(NotificationManager.class);
+    }
+
     static IAudioService getAudioService() {
         IAudioService audioService = IAudioService.Stub.asInterface(
                 ServiceManager.checkService(Context.AUDIO_SERVICE));
@@ -3319,7 +3331,7 @@
                 & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
             // On TV, use legacy handling until assistants are implemented in the proper way.
             ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                    .launchLegacyAssist(hint, UserHandle.myUserId(), args);
+                    .launchLegacyAssist(hint, mCurrentUserId, args);
         } else {
             if (hint != null) {
                 if (args == null) {
@@ -3799,6 +3811,11 @@
                 if (down) {
                     sendSystemKeyToStatusBarAsync(event.getKeyCode());
 
+                    NotificationManager nm = getNotificationService();
+                    if (nm != null && !mHandleVolumeKeysInWM) {
+                        nm.silenceNotificationSound();
+                    }
+
                     TelecomManager telecomManager = getTelecommService();
                     if (telecomManager != null && !mHandleVolumeKeysInWM) {
                         // When {@link #mHandleVolumeKeysInWM} is set, volume key events
@@ -4149,7 +4166,7 @@
             case KeyEvent.KEYCODE_VOLUME_MUTE:
                 return mDefaultDisplayPolicy.getDockMode() != Intent.EXTRA_DOCK_STATE_UNDOCKED;
 
-            // ignore media and camera keys
+            // ignore media keys
             case KeyEvent.KEYCODE_MUTE:
             case KeyEvent.KEYCODE_HEADSETHOOK:
             case KeyEvent.KEYCODE_MEDIA_PLAY:
@@ -4162,7 +4179,6 @@
             case KeyEvent.KEYCODE_MEDIA_RECORD:
             case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
             case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK:
-            case KeyEvent.KEYCODE_CAMERA:
                 return false;
         }
         return true;
@@ -4863,6 +4879,7 @@
             }
         }
         startedWakingUp(ON_BECAUSE_OF_UNKNOWN);
+        finishedWakingUp(ON_BECAUSE_OF_UNKNOWN);
         screenTurningOn(null);
         screenTurnedOn();
     }
@@ -5198,6 +5215,11 @@
             awakenDreams();
         }
 
+        if (!isUserSetupComplete()) {
+            Slog.i(TAG, "Not going home because user setup is in progress.");
+            return;
+        }
+
         // Start dock.
         Intent dock = createHomeDockIntent();
         if (dock != null) {
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
new file mode 100644
index 0000000..c1a6dbd
--- /dev/null
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.policy;
+
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_DEFAULT;
+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.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
+
+import static java.lang.Integer.min;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.UserHandle;
+
+/**
+ * The behavior of soft restricted permissions is different for each permission. This class collects
+ * the policies in one place.
+ *
+ * This is the twin of
+ * {@link com.android.packageinstaller.permission.utils.SoftRestrictedPermissionPolicy}
+ */
+public abstract class SoftRestrictedPermissionPolicy {
+    private static final int FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT =
+            FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
+                    | FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT
+                    | FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
+
+    private static final SoftRestrictedPermissionPolicy DUMMY_POLICY =
+            new SoftRestrictedPermissionPolicy() {
+                @Override
+                public int resolveAppOp() {
+                    return OP_NONE;
+                }
+
+                @Override
+                public int getDesiredOpMode() {
+                    return MODE_DEFAULT;
+                }
+
+                @Override
+                public boolean shouldSetAppOpIfNotDefault() {
+                    return false;
+                }
+
+                @Override
+                public boolean canBeGranted() {
+                    return true;
+                }
+            };
+
+    /**
+     * TargetSDK is per package. To make sure two apps int the same shared UID do not fight over
+     * what to set, always compute the combined targetSDK.
+     *
+     * @param context A context
+     * @param appInfo The app that is changed
+     * @param user The user the app belongs to
+     *
+     * @return The minimum targetSDK of all apps sharing the uid of the app
+     */
+    private static int getMinimumTargetSDK(@NonNull Context context,
+            @NonNull ApplicationInfo appInfo, @NonNull UserHandle user) {
+        PackageManager pm = context.getPackageManager();
+
+        int minimumTargetSDK = appInfo.targetSdkVersion;
+
+        String[] uidPkgs = pm.getPackagesForUid(appInfo.uid);
+        if (uidPkgs != null) {
+            for (String uidPkg : uidPkgs) {
+                if (!uidPkg.equals(appInfo.packageName)) {
+                    ApplicationInfo uidPkgInfo;
+                    try {
+                        uidPkgInfo = pm.getApplicationInfoAsUser(uidPkg, 0, user);
+                    } catch (PackageManager.NameNotFoundException e) {
+                        continue;
+                    }
+
+                    minimumTargetSDK = min(minimumTargetSDK, uidPkgInfo.targetSdkVersion);
+                }
+            }
+        }
+
+        return minimumTargetSDK;
+    }
+
+    /**
+     * Get the policy for a soft restricted permission.
+     *
+     * @param context A context to use
+     * @param appInfo The application the permission belongs to. Can be {@code null}, but then
+     *                only {@link #resolveAppOp} will work.
+     * @param user The user the app belongs to. Can be {@code null}, but then only
+     *             {@link #resolveAppOp} will work.
+     * @param permission The name of the permission
+     *
+     * @return The policy for this permission
+     */
+    public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
+            @Nullable ApplicationInfo appInfo, @Nullable UserHandle user,
+            @NonNull String permission) {
+        switch (permission) {
+            // Storage uses a special app op to decide the mount state and supports soft restriction
+            // where the restricted state allows the permission but only for accessing the medial
+            // collections.
+            case READ_EXTERNAL_STORAGE: {
+                final int flags;
+                final boolean applyRestriction;
+                final boolean isWhiteListed;
+                final boolean hasRequestedLegacyExternalStorage;
+                final int targetSDK;
+
+                if (appInfo != null) {
+                    PackageManager pm = context.getPackageManager();
+                    flags = pm.getPermissionFlags(permission, appInfo.packageName, user);
+                    applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+                    isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
+                    targetSDK = getMinimumTargetSDK(context, appInfo, user);
+
+                    boolean hasAnyRequestedLegacyExternalStorage =
+                            appInfo.hasRequestedLegacyExternalStorage();
+
+                    // hasRequestedLegacyExternalStorage is per package. To make sure two apps in
+                    // the same shared UID do not fight over what to set, always compute the
+                    // combined hasRequestedLegacyExternalStorage
+                    String[] uidPkgs = pm.getPackagesForUid(appInfo.uid);
+                    if (uidPkgs != null) {
+                        for (String uidPkg : uidPkgs) {
+                            if (!uidPkg.equals(appInfo.packageName)) {
+                                ApplicationInfo uidPkgInfo;
+                                try {
+                                    uidPkgInfo = pm.getApplicationInfoAsUser(uidPkg, 0, user);
+                                } catch (PackageManager.NameNotFoundException e) {
+                                    continue;
+                                }
+
+                                hasAnyRequestedLegacyExternalStorage |=
+                                        uidPkgInfo.hasRequestedLegacyExternalStorage();
+                            }
+                        }
+                    }
+
+                    hasRequestedLegacyExternalStorage = hasAnyRequestedLegacyExternalStorage;
+                } else {
+                    flags = 0;
+                    applyRestriction = false;
+                    isWhiteListed = false;
+                    hasRequestedLegacyExternalStorage = false;
+                    targetSDK = 0;
+                }
+
+                return new SoftRestrictedPermissionPolicy() {
+                    @Override
+                    public int resolveAppOp() {
+                        return OP_LEGACY_STORAGE;
+                    }
+
+                    @Override
+                    public int getDesiredOpMode() {
+                        if (applyRestriction) {
+                            return MODE_DEFAULT;
+                        } else if (hasRequestedLegacyExternalStorage) {
+                            return MODE_ALLOWED;
+                        } else {
+                            return MODE_IGNORED;
+                        }
+                    }
+
+                    @Override
+                    public boolean shouldSetAppOpIfNotDefault() {
+                        // Do not switch from allowed -> ignored as this would mean to retroactively
+                        // turn on isolated storage. This will make the app loose all its files.
+                        return getDesiredOpMode() != MODE_IGNORED;
+                    }
+
+                    @Override
+                    public boolean canBeGranted() {
+                        if (isWhiteListed || targetSDK >= Build.VERSION_CODES.Q) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    }
+                };
+            }
+            case WRITE_EXTERNAL_STORAGE: {
+                final boolean isWhiteListed;
+                final int targetSDK;
+
+                if (appInfo != null) {
+                    final int flags = context.getPackageManager().getPermissionFlags(permission,
+                            appInfo.packageName, user);
+                    isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
+                    targetSDK = getMinimumTargetSDK(context, appInfo, user);
+                } else {
+                    isWhiteListed = false;
+                    targetSDK = 0;
+                }
+
+                return new SoftRestrictedPermissionPolicy() {
+                    @Override
+                    public int resolveAppOp() {
+                        return OP_NONE;
+                    }
+
+                    @Override
+                    public int getDesiredOpMode() {
+                        return MODE_DEFAULT;
+                    }
+
+                    @Override
+                    public boolean shouldSetAppOpIfNotDefault() {
+                        return false;
+                    }
+
+                    @Override
+                    public boolean canBeGranted() {
+                        return isWhiteListed || targetSDK >= Build.VERSION_CODES.Q;
+                    }
+                };
+            }
+            default:
+                return DUMMY_POLICY;
+        }
+    }
+
+    /**
+     * @return An app op to be changed based on the state of the permission or
+     * {@link AppOpsManager#OP_NONE} if not app-op should be set.
+     */
+    public abstract int resolveAppOp();
+
+    /**
+     * @return The mode the {@link #resolveAppOp() app op} should be in.
+     */
+    public abstract @AppOpsManager.Mode int getDesiredOpMode();
+
+    /**
+     * @return If the {@link #resolveAppOp() app op} should be set even if the app-op is currently
+     * not {@link AppOpsManager#MODE_DEFAULT}.
+     */
+    public abstract boolean shouldSetAppOpIfNotDefault();
+
+    /**
+     * @return If the permission can be granted
+     */
+    public abstract boolean canBeGranted();
+}
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
index 437ef73..484017b 100644
--- a/services/core/java/com/android/server/policy/TEST_MAPPING
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -27,6 +27,36 @@
           "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
+    },
+    {
+      "name": "CtsPermission2TestCases",
+      "options": [
+        {
+          "include-filter": "android.permission2.cts.RestrictedPermissionsTest"
+        },
+        {
+          "include-filter": "android.permission2.cts.RestrictedStoragePermissionSharedUidTest"
+        }
+      ]
+    },
+    {
+      "name": "CtsPermissionTestCases",
+      "options": [
+        {
+          "include-filter": "android.permission.cts.SplitPermissionTest"
+        },
+        {
+          "include-filter": "android.permission.cts.BackgroundPermissionsTest"
+        }
+      ]
+    },
+    {
+      "name": "CtsBackupTestCases",
+      "options": [
+        {
+          "include-filter": "android.backup.cts.PermissionTest"
+        }
+      ]
     }
   ],
   "postsubmit": [
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index b196754..6d9c710 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -980,7 +980,7 @@
      * Create and return an animation to re-display a window that was force hidden by Keyguard.
      */
     public Animation createHiddenByKeyguardExit(boolean onWallpaper,
-            boolean goingToNotificationShade);
+            boolean goingToNotificationShade, boolean subtleAnimation);
 
     /**
      * Create and return an animation to let the wallpaper disappear after being shown behind
diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java
index ed11fd4..56d8396 100644
--- a/services/core/java/com/android/server/power/AttentionDetector.java
+++ b/services/core/java/com/android/server/power/AttentionDetector.java
@@ -40,6 +40,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
+import com.android.server.wm.WindowManagerInternal;
 
 import java.io.PrintWriter;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -102,6 +103,9 @@
     protected AttentionManagerInternal mAttentionManager;
 
     @VisibleForTesting
+    protected WindowManagerInternal mWindowManager;
+
+    @VisibleForTesting
     protected PackageManager mPackageManager;
 
     @VisibleForTesting
@@ -142,6 +146,7 @@
         mPackageManager = context.getPackageManager();
         mContentResolver = context.getContentResolver();
         mAttentionManager = LocalServices.getService(AttentionManagerInternal.class);
+        mWindowManager = LocalServices.getService(WindowManagerInternal.class);
         mMaximumExtensionMillis = context.getResources().getInteger(
                 com.android.internal.R.integer.config_attentionMaximumExtension);
         mMaxAttentionApiTimeoutMillis = context.getResources().getInteger(
@@ -165,14 +170,10 @@
     }
 
     public long updateUserActivity(long nextScreenDimming) {
-        if (nextScreenDimming == mLastActedOnNextScreenDimming) {
-            return nextScreenDimming;
-        }
-        if (!mIsSettingEnabled) {
-            return nextScreenDimming;
-        }
-
-        if (!isAttentionServiceSupported()) {
+        if (nextScreenDimming == mLastActedOnNextScreenDimming
+                || !mIsSettingEnabled
+                || !isAttentionServiceSupported()
+                || mWindowManager.isKeyguardShowingAndNotOccluded()) {
             return nextScreenDimming;
         }
 
@@ -297,6 +298,7 @@
 
     public void dump(PrintWriter pw) {
         pw.println("AttentionDetector:");
+        pw.println(" mIsSettingEnabled=" + mIsSettingEnabled);
         pw.println(" mMaximumExtensionMillis=" + mMaximumExtensionMillis);
         pw.println(" mMaxAttentionApiTimeoutMillis=" + mMaxAttentionApiTimeoutMillis);
         pw.println(" mLastUserActivityTime(excludingAttention)=" + mLastUserActivityTime);
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index b81d969..edf0cbf 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -91,7 +91,6 @@
     private static final int MSG_USER_ACTIVITY = 1;
     private static final int MSG_BROADCAST = 2;
     private static final int MSG_WIRELESS_CHARGING_STARTED = 3;
-    private static final int MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED = 4;
     private static final int MSG_PROFILE_TIMED_OUT = 5;
     private static final int MSG_WIRED_CHARGING_STARTED = 6;
 
@@ -127,7 +126,6 @@
     private final NotifierHandler mHandler;
     private final Intent mScreenOnIntent;
     private final Intent mScreenOffIntent;
-    private final Intent mScreenBrightnessBoostIntent;
 
     // True if the device should suspend when the screen is off due to proximity.
     private final boolean mSuspendWhenScreenOffDueToProximityConfig;
@@ -181,10 +179,6 @@
         mScreenOffIntent.addFlags(
                 Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
-        mScreenBrightnessBoostIntent =
-                new Intent(PowerManager.ACTION_SCREEN_BRIGHTNESS_BOOST_CHANGED);
-        mScreenBrightnessBoostIntent.addFlags(
-                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
 
         mSuspendWhenScreenOffDueToProximityConfig = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity);
@@ -560,20 +554,6 @@
     }
 
     /**
-     * Called when screen brightness boost begins or ends.
-     */
-    public void onScreenBrightnessBoostChanged() {
-        if (DEBUG) {
-            Slog.d(TAG, "onScreenBrightnessBoostChanged");
-        }
-
-        mSuspendBlocker.acquire();
-        Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED);
-        msg.setAsynchronous(true);
-        mHandler.sendMessage(msg);
-    }
-
-    /**
      * Called when there has been user activity.
      */
     public void onUserActivity(int event, int uid) {
@@ -729,22 +709,6 @@
         }
     }
 
-    private void sendBrightnessBoostChangedBroadcast() {
-        if (DEBUG) {
-            Slog.d(TAG, "Sending brightness boost changed broadcast.");
-        }
-
-        mContext.sendOrderedBroadcastAsUser(mScreenBrightnessBoostIntent, UserHandle.ALL, null,
-                mScreeBrightnessBoostChangedDone, mHandler, 0, null, null);
-    }
-
-    private final BroadcastReceiver mScreeBrightnessBoostChangedDone = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            mSuspendBlocker.release();
-        }
-    };
-
     private void sendWakeUpBroadcast() {
         if (DEBUG) {
             Slog.d(TAG, "Sending wake up broadcast.");
@@ -861,9 +825,6 @@
                 case MSG_WIRELESS_CHARGING_STARTED:
                     showWirelessChargingStarted(msg.arg1, msg.arg2);
                     break;
-                case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
-                    sendBrightnessBoostChangedBroadcast();
-                    break;
                 case MSG_PROFILE_TIMED_OUT:
                     lockProfile(msg.arg1);
                     break;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index cfd3ae6..d599441 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2516,7 +2516,6 @@
                     }
                 }
                 mScreenBrightnessBoostInProgress = false;
-                mNotifier.onScreenBrightnessBoostChanged();
                 userActivityNoUpdateLocked(now,
                         PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
             }
@@ -3123,10 +3122,7 @@
 
             Slog.i(TAG, "Brightness boost activated (uid " + uid +")...");
             mLastScreenBrightnessBoostTime = eventTime;
-            if (!mScreenBrightnessBoostInProgress) {
-                mScreenBrightnessBoostInProgress = true;
-                mNotifier.onScreenBrightnessBoostChanged();
-            }
+            mScreenBrightnessBoostInProgress = true;
             mDirty |= DIRTY_SCREEN_BRIGHTNESS_BOOST;
 
             userActivityNoUpdateLocked(eventTime,
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index 9cd6b0d..1948b20 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.role;
 
 import android.Manifest;
+import android.annotation.AnyThread;
 import android.annotation.CheckResult;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
@@ -60,6 +61,9 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.infra.AndroidFuture;
+import com.android.internal.infra.ThrottledRunnable;
+import com.android.internal.telephony.SmsApplication;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.BitUtils;
 import com.android.internal.util.CollectionUtils;
@@ -72,6 +76,7 @@
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
@@ -80,7 +85,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -97,6 +101,8 @@
 
     private static final boolean DEBUG = false;
 
+    private static final long GRANT_DEFAULT_ROLES_INTERVAL_MILLIS = 1000;
+
     @NonNull
     private final UserManagerInternal mUserManagerInternal;
     @NonNull
@@ -140,6 +146,14 @@
     @NonNull
     private final Handler mListenerHandler = FgThread.getHandler();
 
+    /**
+     * Maps user id to its throttled runnable for granting default roles.
+     */
+    @GuardedBy("mLock")
+    @NonNull
+    private final SparseArray<ThrottledRunnable> mGrantDefaultRolesThrottledRunnables =
+            new SparseArray<>();
+
     public RoleManagerService(@NonNull Context context,
             @NonNull RoleHoldersResolver legacyRoleResolver) {
         super(context);
@@ -153,11 +167,11 @@
 
         LocalServices.addService(RoleManagerInternal.class, new Internal());
 
-        PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        packageManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
-        packageManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider());
-        packageManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
+        PermissionManagerServiceInternal permissionManagerInternal =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
+        permissionManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
+        permissionManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider());
+        permissionManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
 
         registerUserRemovedReceiver();
     }
@@ -180,8 +194,6 @@
     public void onStart() {
         publishBinderService(Context.ROLE_SERVICE, new Stub());
 
-        //TODO add watch for new user creation and run default grants for them
-
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -201,64 +213,78 @@
                     // Package is being upgraded - we're about to get ACTION_PACKAGE_ADDED
                     return;
                 }
-                performInitialGrantsIfNecessaryAsync(userId);
+                maybeGrantDefaultRolesAsync(userId);
             }
         }, UserHandle.ALL, intentFilter, null, null);
     }
 
     @Override
     public void onStartUser(@UserIdInt int userId) {
-        performInitialGrantsIfNecessary(userId);
-    }
-
-    private CompletableFuture<Void> performInitialGrantsIfNecessaryAsync(@UserIdInt int userId) {
-        RoleUserState userState;
-        userState = getOrCreateUserState(userId);
-
-        String packagesHash = computeComponentStateHash(userId);
-        String oldPackagesHash = userState.getPackagesHash();
-        boolean needGrant = !Objects.equals(packagesHash, oldPackagesHash);
-        if (needGrant) {
-
-            //TODO gradually add more role migrations statements here for remaining roles
-            // Make sure to implement LegacyRoleResolutionPolicy#getRoleHolders
-            // for a given role before adding a migration statement for it here
-            migrateRoleIfNecessary(RoleManager.ROLE_SMS, userId);
-            migrateRoleIfNecessary(RoleManager.ROLE_ASSISTANT, userId);
-            migrateRoleIfNecessary(RoleManager.ROLE_DIALER, userId);
-            migrateRoleIfNecessary(RoleManager.ROLE_EMERGENCY, userId);
-
-            // Some vital packages state has changed since last role grant
-            // Run grants again
-            Slog.i(LOG_TAG, "Granting default permissions...");
-            CompletableFuture<Void> result = new CompletableFuture<>();
-            getOrCreateController(userId).grantDefaultRoles(FgThread.getExecutor(),
-                    successful -> {
-                        if (successful) {
-                            userState.setPackagesHash(packagesHash);
-                            result.complete(null);
-                        } else {
-                            result.completeExceptionally(new RuntimeException());
-                        }
-                    });
-            return result;
-        } else if (DEBUG) {
-            Slog.i(LOG_TAG, "Already ran grants for package state " + packagesHash);
-        }
-        return CompletableFuture.completedFuture(null);
+        maybeGrantDefaultRolesSync(userId);
     }
 
     @MainThread
-    private void performInitialGrantsIfNecessary(@UserIdInt int userId) {
-        CompletableFuture<Void> result = performInitialGrantsIfNecessaryAsync(userId);
+    private void maybeGrantDefaultRolesSync(@UserIdInt int userId) {
+        AndroidFuture<Void> future = maybeGrantDefaultRolesInternal(userId);
         try {
-            result.get(30, TimeUnit.SECONDS);
+            future.get(30, TimeUnit.SECONDS);
         } catch (InterruptedException | ExecutionException | TimeoutException e) {
-            Slog.e(LOG_TAG, "Failed to grant defaults for user " + userId, e);
+            Slog.e(LOG_TAG, "Failed to grant default roles for user " + userId, e);
         }
     }
 
-    private void migrateRoleIfNecessary(String role, @UserIdInt int userId) {
+    private void maybeGrantDefaultRolesAsync(@UserIdInt int userId) {
+        ThrottledRunnable runnable;
+        synchronized (mLock) {
+            runnable = mGrantDefaultRolesThrottledRunnables.get(userId);
+            if (runnable == null) {
+                runnable = new ThrottledRunnable(FgThread.getHandler(),
+                        GRANT_DEFAULT_ROLES_INTERVAL_MILLIS,
+                        () -> maybeGrantDefaultRolesInternal(userId));
+                mGrantDefaultRolesThrottledRunnables.put(userId, runnable);
+            }
+        }
+        runnable.run();
+    }
+
+    @AnyThread
+    @NonNull
+    private AndroidFuture<Void> maybeGrantDefaultRolesInternal(@UserIdInt int userId) {
+        RoleUserState userState = getOrCreateUserState(userId);
+        String oldPackagesHash = userState.getPackagesHash();
+        String newPackagesHash = computeComponentStateHash(userId);
+        if (Objects.equals(oldPackagesHash, newPackagesHash)) {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "Already granted default roles for packages hash "
+                        + newPackagesHash);
+            }
+            return AndroidFuture.completedFuture(null);
+        }
+
+        //TODO gradually add more role migrations statements here for remaining roles
+        // Make sure to implement LegacyRoleResolutionPolicy#getRoleHolders
+        // for a given role before adding a migration statement for it here
+        maybeMigrateRole(RoleManager.ROLE_SMS, userId);
+        maybeMigrateRole(RoleManager.ROLE_ASSISTANT, userId);
+        maybeMigrateRole(RoleManager.ROLE_DIALER, userId);
+        maybeMigrateRole(RoleManager.ROLE_EMERGENCY, userId);
+
+        // Some package state has changed, so grant default roles again.
+        Slog.i(LOG_TAG, "Granting default roles...");
+        AndroidFuture<Void> future = new AndroidFuture<>();
+        getOrCreateController(userId).grantDefaultRoles(FgThread.getExecutor(),
+                successful -> {
+                    if (successful) {
+                        userState.setPackagesHash(newPackagesHash);
+                        future.complete(null);
+                    } else {
+                        future.completeExceptionally(new RuntimeException());
+                    }
+                });
+        return future;
+    }
+
+    private void maybeMigrateRole(String role, @UserIdInt int userId) {
         // Any role for which we have a record are already migrated
         RoleUserState userState = getOrCreateUserState(userId);
         if (!userState.isRoleAvailable(role)) {
@@ -364,6 +390,7 @@
         RemoteCallbackList<IOnRoleHoldersChangedListener> listeners;
         RoleUserState userState;
         synchronized (mLock) {
+            mGrantDefaultRolesThrottledRunnables.remove(userId);
             listeners = mListeners.removeReturnOld(userId);
             mControllers.remove(userId);
             userState = mUserStates.removeReturnOld(userId);
@@ -377,13 +404,16 @@
     }
 
     @Override
-    public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
+    public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId,
+            @Nullable String removedHolder, @Nullable String addedHolder) {
         mListenerHandler.sendMessage(PooledLambda.obtainMessage(
-                RoleManagerService::notifyRoleHoldersChanged, this, roleName, userId));
+                RoleManagerService::notifyRoleHoldersChanged, this, roleName, userId,
+                removedHolder, addedHolder));
     }
 
     @WorkerThread
-    private void notifyRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
+    private void notifyRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId,
+            @Nullable String removedHolder, @Nullable String addedHolder) {
         RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId);
         if (listeners != null) {
             notifyRoleHoldersChangedForListeners(listeners, roleName, userId);
@@ -394,6 +424,12 @@
         if (allUsersListeners != null) {
             notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId);
         }
+
+        // Legacy: sms app changed broadcasts
+        if (RoleManager.ROLE_SMS.equals(roleName)) {
+            SmsApplication.broadcastSmsAppChange(getContext(), UserHandle.of(userId),
+                    removedHolder, addedHolder);
+        }
     }
 
     @WorkerThread
@@ -720,7 +756,8 @@
         }
     }
 
-    private class DefaultBrowserProvider implements PackageManagerInternal.DefaultBrowserProvider {
+    private class DefaultBrowserProvider implements
+            PermissionManagerServiceInternal.DefaultBrowserProvider {
 
         @Nullable
         @Override
@@ -731,7 +768,7 @@
 
         @Override
         public boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) {
-            CompletableFuture<Void> future = new CompletableFuture<>();
+            AndroidFuture<Void> future = new AndroidFuture<>();
             RemoteCallback callback = new RemoteCallback(result -> {
                 boolean successful = result != null;
                 if (successful) {
@@ -774,7 +811,8 @@
         }
     }
 
-    private class DefaultDialerProvider implements PackageManagerInternal.DefaultDialerProvider {
+    private class DefaultDialerProvider implements
+            PermissionManagerServiceInternal.DefaultDialerProvider {
 
         @Nullable
         @Override
@@ -784,7 +822,8 @@
         }
     }
 
-    private class DefaultHomeProvider implements PackageManagerInternal.DefaultHomeProvider {
+    private class DefaultHomeProvider implements
+            PermissionManagerServiceInternal.DefaultHomeProvider {
 
         @Nullable
         @Override
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index c7e3fa4..6375b48 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -294,7 +294,7 @@
         }
 
         if (changed) {
-            mCallback.onRoleHoldersChanged(roleName, mUserId);
+            mCallback.onRoleHoldersChanged(roleName, mUserId, null, packageName);
         }
         return true;
     }
@@ -328,7 +328,7 @@
         }
 
         if (changed) {
-            mCallback.onRoleHoldersChanged(roleName, mUserId);
+            mCallback.onRoleHoldersChanged(roleName, mUserId, packageName, null);
         }
         return true;
     }
@@ -632,6 +632,7 @@
          * @param roleName the name of the role whose holders are changed
          * @param userId the user id for this role holder change
          */
-        void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId);
+        void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId,
+                @Nullable String removedHolder, @Nullable String addedHolder);
     }
 }
diff --git a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
index 56e1d08..f5f7d67 100644
--- a/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
+++ b/services/core/java/com/android/server/rollback/AppDataRollbackHelper.java
@@ -20,7 +20,7 @@
 import android.content.rollback.PackageRollbackInfo.RestoreInfo;
 import android.os.storage.StorageManager;
 import android.util.IntArray;
-import android.util.Log;
+import android.util.Slog;
 import android.util.SparseLongArray;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -62,7 +62,7 @@
             if (isUserCredentialLocked(user)) {
                 // We've encountered a user that hasn't unlocked on a FBE device, so we can't copy
                 // across app user data until the user unlocks their device.
-                Log.v(TAG, "User: " + user + " isn't unlocked, skipping CE userdata backup.");
+                Slog.v(TAG, "User: " + user + " isn't unlocked, skipping CE userdata backup.");
                 storageFlags = Installer.FLAG_STORAGE_DE;
                 packageRollbackInfo.addPendingBackup(user);
             } else {
@@ -76,7 +76,7 @@
                     packageRollbackInfo.putCeSnapshotInode(user, ceSnapshotInode);
                 }
             } catch (InstallerException ie) {
-                Log.e(TAG, "Unable to create app data snapshot for: "
+                Slog.e(TAG, "Unable to create app data snapshot for: "
                         + packageRollbackInfo.getPackageName() + ", userId: " + user, ie);
             }
         }
@@ -122,7 +122,7 @@
             mInstaller.restoreAppDataSnapshot(packageRollbackInfo.getPackageName(), appId, seInfo,
                     userId, rollbackId, storageFlags);
         } catch (InstallerException ie) {
-            Log.e(TAG, "Unable to restore app data snapshot: "
+            Slog.e(TAG, "Unable to restore app data snapshot: "
                         + packageRollbackInfo.getPackageName(), ie);
         }
 
@@ -148,7 +148,7 @@
                 ceSnapshotInodes.delete(user);
             }
         } catch (InstallerException ie) {
-            Log.e(TAG, "Unable to delete app data snapshot for "
+            Slog.e(TAG, "Unable to delete app data snapshot for "
                         + packageRollbackInfo.getPackageName(), ie);
         }
     }
@@ -257,7 +257,7 @@
                             info.putCeSnapshotInode(userId, ceSnapshotInode);
                             pendingBackupUsers.remove(idx);
                         } catch (InstallerException ie) {
-                            Log.e(TAG,
+                            Slog.e(TAG,
                                     "Unable to create app data snapshot for: "
                                     + info.getPackageName() + ", userId: " + userId, ie);
                         }
@@ -277,7 +277,7 @@
                                     Installer.FLAG_STORAGE_CE);
                             info.removeRestoreInfo(ri);
                         } catch (InstallerException ie) {
-                            Log.e(TAG, "Unable to restore app data snapshot for: "
+                            Slog.e(TAG, "Unable to restore app data snapshot for: "
                                     + info.getPackageName(), ie);
                         }
                     }
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 9a2778d..cfa370b 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -45,14 +45,13 @@
 import android.os.HandlerThread;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
-import android.os.UserHandle;   // duped to avoid merge conflict
-import android.os.UserManager;  // out of order to avoid merge conflict
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.DeviceConfig;
 import android.util.ArraySet;
 import android.util.IntArray;
-import android.util.Log;
+import android.util.Slog;
 import android.util.SparseBooleanArray;
 import android.util.SparseLongArray;
 
@@ -76,6 +75,7 @@
 import java.util.List;
 import java.util.Random;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
@@ -86,9 +86,9 @@
 
     private static final String TAG = "RollbackManager";
 
-    // Rollbacks expire after 48 hours.
+    // Rollbacks expire after 14 days.
     private static final long DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS =
-            TimeUnit.HOURS.toMillis(48);
+            TimeUnit.DAYS.toMillis(14);
 
     // Lock used to synchronize accesses to in-memory rollback data
     // structures. By convention, methods with the suffix "Locked" require
@@ -115,9 +115,8 @@
     private final Set<NewRollback> mNewRollbacks = new ArraySet<>();
 
     // The list of all rollbacks, including available and committed rollbacks.
-    // This list is null until the rollback data has been loaded.
     @GuardedBy("mLock")
-    private List<RollbackData> mRollbacks;
+    private final List<RollbackData> mRollbacks;
 
     private final RollbackStore mRollbackStore;
 
@@ -139,29 +138,25 @@
         // SystemService#onStart.
         mInstaller = new Installer(mContext);
         mInstaller.onStart();
-        mHandlerThread = new HandlerThread("RollbackManagerServiceHandler");
-        mHandlerThread.start();
-
-        // Monitor the handler thread
-        Watchdog.getInstance().addThread(getHandler(), HANDLER_THREAD_TIMEOUT_DURATION_MILLIS);
 
         mRollbackStore = new RollbackStore(new File(Environment.getDataDirectory(), "rollback"));
 
         mPackageHealthObserver = new RollbackPackageHealthObserver(mContext);
         mAppDataRollbackHelper = new AppDataRollbackHelper(mInstaller);
 
-        // Kick off loading of the rollback data from strorage in a background
-        // thread.
-        // TODO: Consider loading the rollback data directly here instead, to
-        // avoid the need to call ensureRollbackDataLoaded every time before
-        // accessing the rollback data?
-        // TODO: Test that this kicks off initial scheduling of rollback
-        // expiration.
-        getHandler().post(() -> ensureRollbackDataLoaded());
+        // Load rollback data from device storage.
+        synchronized (mLock) {
+            mRollbacks = mRollbackStore.loadAllRollbackData();
+            for (RollbackData data : mRollbacks) {
+                mAllocatedRollbackIds.put(data.info.getRollbackId(), true);
+            }
+        }
 
-        // TODO: Make sure to register these call backs when a new user is
-        // added too.
-        SessionCallback sessionCallback = new SessionCallback();
+        // Kick off and start monitoring the handler thread.
+        mHandlerThread = new HandlerThread("RollbackManagerServiceHandler");
+        mHandlerThread.start();
+        Watchdog.getInstance().addThread(getHandler(), HANDLER_THREAD_TIMEOUT_DURATION_MILLIS);
+
         for (UserInfo userInfo : UserManager.get(mContext).getUsers(true)) {
             registerUserCallbacks(userInfo.getUserHandle());
         }
@@ -171,7 +166,7 @@
         try {
             enableRollbackFilter.addDataType("application/vnd.android.package-archive");
         } catch (IntentFilter.MalformedMimeTypeException e) {
-            Log.e(TAG, "addDataType", e);
+            Slog.e(TAG, "addDataType", e);
         }
 
         mContext.registerReceiver(new BroadcastReceiver() {
@@ -251,13 +246,10 @@
     private void registerUserCallbacks(UserHandle user) {
         Context context = getContextAsUser(user);
         if (context == null) {
-            Log.e(TAG, "Unable to register user callbacks for user " + user);
+            Slog.e(TAG, "Unable to register user callbacks for user " + user);
             return;
         }
 
-        // TODO: Reuse the same SessionCallback and broadcast receiver
-        // instances, rather than creating new instances for each user.
-
         context.getPackageManager().getPackageInstaller()
                 .registerSessionCallback(new SessionCallback(), getHandler());
 
@@ -290,7 +282,7 @@
     public ParceledListSlice getAvailableRollbacks() {
         enforceManageRollbacks("getAvailableRollbacks");
         if (Thread.currentThread().equals(mHandlerThread)) {
-            Log.wtf(TAG, "Calling getAvailableRollbacks from mHandlerThread "
+            Slog.wtf(TAG, "Calling getAvailableRollbacks from mHandlerThread "
                     + "causes a deadlock");
             throw new IllegalStateException("Cannot call RollbackManager#getAvailableRollbacks "
                     + "from the handler thread!");
@@ -300,20 +292,15 @@
         // 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));
-
+        CountDownLatch latch = new CountDownLatch(1);
+        getHandler().post(() -> latch.countDown());
         try {
-            result.take();
+            latch.await();
         } 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");
+            throw new IllegalStateException("RollbackManagerHandlerThread interrupted");
         }
 
         synchronized (mLock) {
-            ensureRollbackDataLoadedLocked();
             List<RollbackInfo> rollbacks = new ArrayList<>();
             for (int i = 0; i < mRollbacks.size(); ++i) {
                 RollbackData data = mRollbacks.get(i);
@@ -326,11 +313,10 @@
     }
 
     @Override
-    public ParceledListSlice<RollbackInfo> getRecentlyExecutedRollbacks() {
+    public ParceledListSlice<RollbackInfo> getRecentlyCommittedRollbacks() {
         enforceManageRollbacks("getRecentlyCommittedRollbacks");
 
         synchronized (mLock) {
-            ensureRollbackDataLoadedLocked();
             List<RollbackInfo> rollbacks = new ArrayList<>();
             for (int i = 0; i < mRollbacks.size(); ++i) {
                 RollbackData data = mRollbacks.get(i);
@@ -345,7 +331,7 @@
     @Override
     public void commitRollback(int rollbackId, ParceledListSlice causePackages,
             String callerPackageName, IntentSender statusReceiver) {
-        enforceManageRollbacks("executeRollback");
+        enforceManageRollbacks("commitRollback");
 
         final int callingUid = Binder.getCallingUid();
         AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
@@ -365,8 +351,6 @@
                 final long timeDifference = mRelativeBootTime - oldRelativeBootTime;
 
                 synchronized (mLock) {
-                    ensureRollbackDataLoadedLocked();
-
                     Iterator<RollbackData> iter = mRollbacks.iterator();
                     while (iter.hasNext()) {
                         RollbackData data = iter.next();
@@ -393,7 +377,7 @@
      */
     private void commitRollbackInternal(int rollbackId, List<VersionedPackage> causePackages,
             String callerPackageName, IntentSender statusReceiver) {
-        Log.i(TAG, "Initiating rollback");
+        Slog.i(TAG, "Initiating rollback");
 
         RollbackData data = getRollbackForId(rollbackId);
         if (data == null || data.state != RollbackData.ROLLBACK_STATE_AVAILABLE) {
@@ -532,7 +516,7 @@
             }
             parentSession.commit(receiver.getIntentSender());
         } catch (IOException e) {
-            Log.e(TAG, "Rollback failed", e);
+            Slog.e(TAG, "Rollback failed", e);
             sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE,
                     "IOException: " + e.toString());
             return;
@@ -545,13 +529,21 @@
                 Manifest.permission.TEST_MANAGE_ROLLBACKS,
                 "reloadPersistedData");
 
-        synchronized (mLock) {
-            mRollbacks = null;
-        }
+        CountDownLatch latch = new CountDownLatch(1);
         getHandler().post(() -> {
             updateRollbackLifetimeDurationInMillis();
-            ensureRollbackDataLoaded();
+            synchronized (mLock) {
+                mRollbacks.clear();
+                mRollbacks.addAll(mRollbackStore.loadAllRollbackData());
+            }
+            latch.countDown();
         });
+
+        try {
+            latch.await();
+        } catch (InterruptedException ie) {
+            throw new IllegalStateException("RollbackManagerHandlerThread interrupted");
+        }
     }
 
     @Override
@@ -560,7 +552,6 @@
                 Manifest.permission.TEST_MANAGE_ROLLBACKS,
                 "expireRollbackForPackage");
         synchronized (mLock) {
-            ensureRollbackDataLoadedLocked();
             Iterator<RollbackData> iter = mRollbacks.iterator();
             while (iter.hasNext()) {
                 RollbackData data = iter.next();
@@ -575,6 +566,20 @@
         }
     }
 
+    @Override
+    public void blockRollbackManager(long millis) {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.TEST_MANAGE_ROLLBACKS,
+                "blockRollbackManager");
+        getHandler().post(() -> {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+                throw new IllegalStateException("RollbackManagerHandlerThread interrupted");
+            }
+        });
+    }
+
     void onUnlockUser(int userId) {
         getHandler().post(() -> {
             final List<RollbackData> rollbacks;
@@ -613,7 +618,6 @@
             List<RollbackData> restoreInProgress = new ArrayList<>();
             Set<String> apexPackageNames = new HashSet<>();
             synchronized (mLock) {
-                ensureRollbackDataLoadedLocked();
                 for (RollbackData data : mRollbacks) {
                     if (data.isStaged()) {
                         if (data.state == RollbackData.ROLLBACK_STATE_ENABLING) {
@@ -635,17 +639,14 @@
                 PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
                 PackageInstaller.SessionInfo session = installer.getSessionInfo(
                         data.stagedSessionId);
-                // TODO: What if session is null?
-                if (session != null) {
-                    if (session.isStagedSessionApplied()) {
-                        makeRollbackAvailable(data);
-                    } else if (session.isStagedSessionFailed()) {
-                        // TODO: Do we need to remove this from
-                        // mRollbacks, or is it okay to leave as
-                        // unavailable until the next reboot when it will go
-                        // away on its own?
-                        deleteRollback(data);
-                    }
+                if (session == null || session.isStagedSessionFailed()) {
+                    // TODO: Do we need to remove this from
+                    // mRollbacks, or is it okay to leave as
+                    // unavailable until the next reboot when it will go
+                    // away on its own?
+                    deleteRollback(data);
+                } else if (session.isStagedSessionApplied()) {
+                    makeRollbackAvailable(data);
                 }
             }
 
@@ -676,42 +677,6 @@
     }
 
     /**
-     * Load rollback data from storage if it has not already been loaded.
-     * After calling this funciton, mAvailableRollbacks and
-     * mRecentlyExecutedRollbacks will be non-null.
-     */
-    private void ensureRollbackDataLoaded() {
-        synchronized (mLock) {
-            ensureRollbackDataLoadedLocked();
-        }
-    }
-
-    /**
-     * Load rollback data from storage if it has not already been loaded.
-     * After calling this function, mRollbacks will be non-null.
-     */
-    @GuardedBy("mLock")
-    private void ensureRollbackDataLoadedLocked() {
-        if (mRollbacks == null) {
-            loadAllRollbackDataLocked();
-        }
-    }
-
-    /**
-     * Load all rollback data from storage.
-     * Note: We do potentially heavy IO here while holding mLock, because we
-     * have to have the rollback data loaded before we can do anything else
-     * meaningful.
-     */
-    @GuardedBy("mLock")
-    private void loadAllRollbackDataLocked() {
-        mRollbacks = mRollbackStore.loadAllRollbackData();
-        for (RollbackData data : mRollbacks) {
-            mAllocatedRollbackIds.put(data.info.getRollbackId(), true);
-        }
-    }
-
-    /**
      * Called when a package has been replaced with a different version.
      * Removes all backups for the package not matching the currently
      * installed package version.
@@ -722,7 +687,6 @@
         VersionedPackage installedVersion = getInstalledPackageVersion(packageName);
 
         synchronized (mLock) {
-            ensureRollbackDataLoadedLocked();
             Iterator<RollbackData> iter = mRollbacks.iterator();
             while (iter.hasNext()) {
                 RollbackData data = iter.next();
@@ -761,7 +725,7 @@
      */
     private void sendFailure(IntentSender statusReceiver, @RollbackManager.Status int status,
             String message) {
-        Log.e(TAG, message);
+        Slog.e(TAG, message);
         try {
             final Intent fillIn = new Intent();
             fillIn.putExtra(RollbackManager.EXTRA_STATUS, status);
@@ -791,8 +755,6 @@
         Instant now = Instant.now();
         Instant oldest = null;
         synchronized (mLock) {
-            ensureRollbackDataLoadedLocked();
-
             Iterator<RollbackData> iter = mRollbacks.iterator();
             while (iter.hasNext()) {
                 RollbackData data = iter.next();
@@ -876,7 +838,7 @@
         // session.
         final Context context = getContextAsUser(UserHandle.of(user));
         if (context == null) {
-            Log.e(TAG, "Unable to create context for install session user.");
+            Slog.e(TAG, "Unable to create context for install session user.");
             return false;
         }
 
@@ -903,7 +865,7 @@
         }
 
         if (parentSession == null || packageSession == null) {
-            Log.e(TAG, "Unable to find session for enabled rollback.");
+            Slog.e(TAG, "Unable to find session for enabled rollback.");
             return false;
         }
 
@@ -912,7 +874,6 @@
         // TODO: This check could be made more efficient.
         RollbackData rd = null;
         synchronized (mLock) {
-            ensureRollbackDataLoadedLocked();
             for (int i = 0; i < mRollbacks.size(); ++i) {
                 RollbackData data = mRollbacks.get(i);
                 if (data.apkSessionId == parentSession.getSessionId()) {
@@ -923,26 +884,24 @@
         }
 
         if (rd != null) {
-            // This is the apk session for a staged session. We have already
-            // backed up the apks, we just need to do user data backup.
+            // This is the apk session for a staged session. We do not need to create a new rollback
+            // for this session.
             PackageParser.PackageLite newPackage = null;
             try {
                 newPackage = PackageParser.parsePackageLite(
                         new File(packageSession.resolvedBaseCodePath), 0);
             } catch (PackageParser.PackageParserException e) {
-                Log.e(TAG, "Unable to parse new package", e);
+                Slog.e(TAG, "Unable to parse new package", e);
                 return false;
             }
             String packageName = newPackage.packageName;
             for (PackageRollbackInfo info : rd.info.getPackages()) {
                 if (info.getPackageName().equals(packageName)) {
                     info.getInstalledUsers().addAll(IntArray.wrap(installedUsers));
-                    mAppDataRollbackHelper.snapshotAppData(rd.info.getRollbackId(), info);
-                    saveRollbackData(rd);
                     return true;
                 }
             }
-            Log.e(TAG, "Unable to find package in apk session");
+            Slog.e(TAG, "Unable to find package in apk session");
             return false;
         }
 
@@ -959,8 +918,7 @@
         }
         newRollback.addToken(token);
 
-        return enableRollbackForPackageSession(newRollback.data, packageSession,
-                installedUsers, /* snapshotUserData*/ true);
+        return enableRollbackForPackageSession(newRollback.data, packageSession, installedUsers);
     }
 
     /**
@@ -971,21 +929,20 @@
      * @return true on success, false on failure.
      */
     private boolean enableRollbackForPackageSession(RollbackData data,
-            PackageInstaller.SessionInfo session, @NonNull int[] installedUsers,
-            boolean snapshotUserData) {
+            PackageInstaller.SessionInfo session, @NonNull int[] installedUsers) {
         // TODO: Don't attempt to enable rollback for split installs.
         final int installFlags = session.installFlags;
         if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
-            Log.e(TAG, "Rollback is not enabled.");
+            Slog.e(TAG, "Rollback is not enabled.");
             return false;
         }
         if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
-            Log.e(TAG, "Rollbacks not supported for instant app install");
+            Slog.e(TAG, "Rollbacks not supported for instant app install");
             return false;
         }
 
         if (session.resolvedBaseCodePath == null) {
-            Log.e(TAG, "Session code path has not been resolved.");
+            Slog.e(TAG, "Session code path has not been resolved.");
             return false;
         }
 
@@ -994,17 +951,17 @@
         try {
             newPackage = PackageParser.parsePackageLite(new File(session.resolvedBaseCodePath), 0);
         } catch (PackageParser.PackageParserException e) {
-            Log.e(TAG, "Unable to parse new package", e);
+            Slog.e(TAG, "Unable to parse new package", e);
             return false;
         }
 
         String packageName = newPackage.packageName;
-        Log.i(TAG, "Enabling rollback for install of " + packageName
+        Slog.i(TAG, "Enabling rollback for install of " + packageName
                 + ", session:" + session.sessionId);
 
         String installerPackageName = session.getInstallerPackageName();
         if (!enableRollbackAllowed(installerPackageName, packageName)) {
-            Log.e(TAG, "Installer " + installerPackageName
+            Slog.e(TAG, "Installer " + installerPackageName
                     + " is not allowed to enable rollback on " + packageName);
             return false;
         }
@@ -1020,7 +977,7 @@
         } catch (PackageManager.NameNotFoundException e) {
             // TODO: Support rolling back fresh package installs rather than
             // fail here. Test this case.
-            Log.e(TAG, packageName + " is not installed");
+            Slog.e(TAG, packageName + " is not installed");
             return false;
         }
 
@@ -1033,10 +990,6 @@
                 isApex, IntArray.wrap(installedUsers),
                 new SparseLongArray() /* ceSnapshotInodes */);
 
-        if (snapshotUserData && !isApex) {
-            mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), packageRollbackInfo);
-        }
-
         try {
             ApplicationInfo appInfo = pkgInfo.applicationInfo;
             RollbackStore.backupPackageCodePath(data, packageName, appInfo.sourceDir);
@@ -1046,7 +999,7 @@
                 }
             }
         } catch (IOException e) {
-            Log.e(TAG, "Unable to copy package for rollback for " + packageName, e);
+            Slog.e(TAG, "Unable to copy package for rollback for " + packageName, e);
             return false;
         }
 
@@ -1057,13 +1010,15 @@
     }
 
     @Override
-    public void restoreUserData(String packageName, int[] userIds, int appId, long ceDataInode,
-            String seInfo, int token) {
+    public void snapshotAndRestoreUserData(String packageName, int[] userIds, int appId,
+            long ceDataInode, String seInfo, int token) {
         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
-            throw new SecurityException("restoreUserData may only be called by the system.");
+            throw new SecurityException(
+                    "snapshotAndRestoreUserData may only be called by the system.");
         }
 
         getHandler().post(() -> {
+            snapshotUserDataInternal(packageName);
             restoreUserDataInternal(packageName, userIds, appId, ceDataInode, seInfo, token);
             final PackageManagerInternal pmi = LocalServices.getService(
                     PackageManagerInternal.class);
@@ -1071,12 +1026,41 @@
         });
     }
 
+    private void snapshotUserDataInternal(String packageName) {
+        synchronized (mLock) {
+            // staged installs
+            for (int i = 0; i < mRollbacks.size(); i++) {
+                RollbackData data = mRollbacks.get(i);
+                if (data.state != RollbackData.ROLLBACK_STATE_ENABLING) {
+                    continue;
+                }
+
+                for (PackageRollbackInfo info : data.info.getPackages()) {
+                    if (info.getPackageName().equals(packageName)) {
+                        mAppDataRollbackHelper.snapshotAppData(data.info.getRollbackId(), info);
+                        saveRollbackData(data);
+                        break;
+                    }
+                }
+            }
+            // non-staged installs
+            PackageRollbackInfo info;
+            for (NewRollback rollback : mNewRollbacks) {
+                info = getPackageRollbackInfo(rollback.data, packageName);
+                if (info != null) {
+                    mAppDataRollbackHelper.snapshotAppData(rollback.data.info.getRollbackId(),
+                            info);
+                    saveRollbackData(rollback.data);
+                }
+            }
+        }
+    }
+
     private void restoreUserDataInternal(String packageName, int[] userIds, int appId,
             long ceDataInode, String seInfo, int token) {
         PackageRollbackInfo info = null;
         RollbackData rollbackData = null;
         synchronized (mLock) {
-            ensureRollbackDataLoadedLocked();
             for (int i = 0; i < mRollbacks.size(); ++i) {
                 RollbackData data = mRollbacks.get(i);
                 if (data.restoreUserDataInProgress) {
@@ -1118,7 +1102,7 @@
 
             final PackageInstaller.SessionInfo session = installer.getSessionInfo(sessionId);
             if (session == null) {
-                Log.e(TAG, "No matching install session for: " + sessionId);
+                Slog.e(TAG, "No matching install session for: " + sessionId);
                 result.offer(false);
                 return;
             }
@@ -1130,8 +1114,8 @@
 
             if (!session.isMultiPackage()) {
                 if (!enableRollbackForPackageSession(newRollback.data, session,
-                            new int[0], /* snapshotUserData */ false)) {
-                    Log.e(TAG, "Unable to enable rollback for session: " + sessionId);
+                            new int[0])) {
+                    Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
                     result.offer(false);
                     return;
                 }
@@ -1140,13 +1124,13 @@
                     final PackageInstaller.SessionInfo childSession =
                             installer.getSessionInfo(childSessionId);
                     if (childSession == null) {
-                        Log.e(TAG, "No matching child install session for: " + childSessionId);
+                        Slog.e(TAG, "No matching child install session for: " + childSessionId);
                         result.offer(false);
                         return;
                     }
                     if (!enableRollbackForPackageSession(newRollback.data, childSession,
-                                new int[0], /* snapshotUserData */ false)) {
-                        Log.e(TAG, "Unable to enable rollback for session: " + sessionId);
+                                new int[0])) {
+                        Slog.e(TAG, "Unable to enable rollback for session: " + sessionId);
                         result.offer(false);
                         return;
                     }
@@ -1159,7 +1143,7 @@
         try {
             return result.take();
         } catch (InterruptedException ie) {
-            Log.e(TAG, "Interrupted while waiting for notifyStagedSession response");
+            Slog.e(TAG, "Interrupted while waiting for notifyStagedSession response");
             return false;
         }
     }
@@ -1172,7 +1156,6 @@
         getHandler().post(() -> {
             RollbackData rd = null;
             synchronized (mLock) {
-                ensureRollbackDataLoadedLocked();
                 for (int i = 0; i < mRollbacks.size(); ++i) {
                     RollbackData data = mRollbacks.get(i);
                     if (data.stagedSessionId == originalSessionId) {
@@ -1264,7 +1247,8 @@
 
 
     private boolean packageVersionsEqual(VersionedPackage a, VersionedPackage b) {
-        return a.getPackageName().equals(b.getPackageName())
+        return a != null && b != null
+            && a.getPackageName().equals(b.getPackageName())
             && a.getLongVersionCode() == b.getLongVersionCode();
     }
 
@@ -1317,7 +1301,7 @@
             return null;
         }
         if (newRollback.isCancelled) {
-            Log.e(TAG, "Rollback has been cancelled by PackageManager");
+            Slog.e(TAG, "Rollback has been cancelled by PackageManager");
             deleteRollback(data);
             return null;
         }
@@ -1326,7 +1310,7 @@
         // this is running on the handler thread and all changes to the
         // data.info occur on the handler thread.
         if (data.info.getPackages().size() != newRollback.packageSessionIds.length) {
-            Log.e(TAG, "Failed to enable rollback for all packages in session.");
+            Slog.e(TAG, "Failed to enable rollback for all packages in session.");
             deleteRollback(data);
             return null;
         }
@@ -1343,7 +1327,6 @@
             // device reboots between when the session is
             // committed and this point. Revisit this after
             // adding support for rollback of staged installs.
-            ensureRollbackDataLoadedLocked();
             mRollbacks.add(data);
         }
 
@@ -1380,9 +1363,6 @@
      */
     private RollbackData getRollbackForId(int rollbackId) {
         synchronized (mLock) {
-            // TODO: Have ensureRollbackDataLoadedLocked return the list of
-            // available rollbacks, to hopefully avoid forgetting to call it?
-            ensureRollbackDataLoadedLocked();
             for (int i = 0; i < mRollbacks.size(); ++i) {
                 RollbackData data = mRollbacks.get(i);
                 if (data.info.getRollbackId() == rollbackId) {
@@ -1446,7 +1426,7 @@
         try {
             mRollbackStore.saveRollbackData(rollbackData);
         } catch (IOException ioe) {
-            Log.e(TAG, "Unable to save rollback info for: "
+            Slog.e(TAG, "Unable to save rollback info for: "
                     + rollbackData.info.getRollbackId(), ioe);
         }
     }
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 8a26368c..1c36dc7 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -25,7 +25,7 @@
 import android.content.rollback.PackageRollbackInfo.RestoreInfo;
 import android.content.rollback.RollbackInfo;
 import android.util.IntArray;
-import android.util.Log;
+import android.util.Slog;
 import android.util.SparseLongArray;
 
 import libcore.io.IoUtils;
@@ -83,7 +83,7 @@
                 try {
                     rollbacks.add(loadRollbackData(rollbackDir));
                 } catch (IOException e) {
-                    Log.e(TAG, "Unable to read rollback data at " + rollbackDir, e);
+                    Slog.e(TAG, "Unable to read rollback data at " + rollbackDir, e);
                     removeFile(rollbackDir);
                 }
             }
diff --git a/services/core/java/com/android/server/rollback/TEST_MAPPING b/services/core/java/com/android/server/rollback/TEST_MAPPING
index 8c7b5ac..2cc931b 100644
--- a/services/core/java/com/android/server/rollback/TEST_MAPPING
+++ b/services/core/java/com/android/server/rollback/TEST_MAPPING
@@ -1,12 +1,6 @@
 {
   "presubmit": [
     {
-      "name": "RollbackTest"
-    },
-    {
-      "name": "StagedRollbackTest"
-    },
-    {
       "name": "FrameworksServicesTests",
       "options": [
         {
@@ -21,6 +15,9 @@
     },
     {
       "path": "cts/hostsidetests/rollback"
+    },
+    {
+      "path": "frameworks/base/tests/RollbackTest"
     }
   ]
 }
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 73775b4..5fd2ab8 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -26,10 +26,7 @@
 import static android.os.Process.SYSTEM_UID;
 
 import android.Manifest.permission;
-import android.app.ActivityManager;
 import android.app.AppOpsManager;
-import android.app.ContentProviderHolder;
-import android.app.IActivityManager;
 import android.app.slice.ISliceManager;
 import android.app.slice.SliceSpec;
 import android.app.usage.UsageStatsManagerInternal;
@@ -391,7 +388,7 @@
     }
 
     protected int checkAccess(String pkg, Uri uri, int uid, int pid) {
-        return checkSlicePermission(uri, null, pkg, uid, pid, null);
+        return checkSlicePermission(uri, null, pkg, pid, uid, null);
     }
 
     private String getProviderPkg(Uri uri, int user) {
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index b10b5ac..c76bbb0 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -25,7 +25,9 @@
 
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
+import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
+import static com.android.server.am.MemoryStatUtil.readProcessSystemIonHeapSizesFromDebugfs;
 import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs;
 import static com.android.server.am.MemoryStatUtil.readSystemIonHeapSizeFromDebugfs;
 
@@ -39,7 +41,6 @@
 import android.app.AppOpsManager.HistoricalOpsRequest;
 import android.app.AppOpsManager.HistoricalPackageOps;
 import android.app.AppOpsManager.HistoricalUidOps;
-import android.app.ProcessMemoryHighWaterMark;
 import android.app.ProcessMemoryState;
 import android.app.StatsManager;
 import android.bluetooth.BluetoothActivityEnergyInfo;
@@ -137,6 +138,7 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.SystemServiceManager;
+import com.android.server.am.MemoryStatUtil.IonAllocations;
 import com.android.server.am.MemoryStatUtil.MemoryStat;
 import com.android.server.role.RoleManagerInternal;
 import com.android.server.storage.DiskStatsFileLogger;
@@ -489,8 +491,7 @@
                 // Add in all the apps for every user/profile.
                 for (UserInfo profile : users) {
                     List<PackageInfo> pi =
-                            pm.getInstalledPackagesAsUser(
-                                    PackageManager.MATCH_KNOWN_PACKAGES | PackageManager.MATCH_APEX,
+                            pm.getInstalledPackagesAsUser(PackageManager.MATCH_KNOWN_PACKAGES,
                                     profile.id);
                     for (int j = 0; j < pi.size(); j++) {
                         if (pi.get(j).applicationInfo != null) {
@@ -1171,17 +1172,23 @@
                 LocalServices.getService(
                         ActivityManagerInternal.class).getMemoryStateForProcesses();
         for (ProcessMemoryState processMemoryState : processMemoryStates) {
+            final MemoryStat memoryStat = readMemoryStatFromFilesystem(processMemoryState.uid,
+                    processMemoryState.pid);
+            if (memoryStat == null) {
+                continue;
+            }
             StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
             e.writeInt(processMemoryState.uid);
             e.writeString(processMemoryState.processName);
             e.writeInt(processMemoryState.oomScore);
-            e.writeLong(processMemoryState.pgfault);
-            e.writeLong(processMemoryState.pgmajfault);
-            e.writeLong(processMemoryState.rssInBytes);
-            e.writeLong(processMemoryState.cacheInBytes);
-            e.writeLong(processMemoryState.swapInBytes);
+            e.writeLong(memoryStat.pgfault);
+            e.writeLong(memoryStat.pgmajfault);
+            e.writeLong(memoryStat.rssInBytes);
+            e.writeLong(memoryStat.cacheInBytes);
+            e.writeLong(memoryStat.swapInBytes);
             e.writeLong(0);  // unused
-            e.writeLong(processMemoryState.startTimeNanos);
+            e.writeLong(memoryStat.startTimeNanos);
+            e.writeInt(anonAndSwapInKilobytes(memoryStat));
             pulledData.add(e);
         }
     }
@@ -1214,20 +1221,31 @@
             e.writeLong(0);  // unused
             e.writeLong(memoryStat.startTimeNanos);
             e.writeLong(memoryStat.swapInBytes);
+            e.writeInt(anonAndSwapInKilobytes(memoryStat));
             pulledData.add(e);
         }
     }
 
+    private static int anonAndSwapInKilobytes(MemoryStat memoryStat) {
+        return (int) ((memoryStat.anonRssInBytes + memoryStat.swapInBytes) / 1024);
+    }
+
     private void pullProcessMemoryHighWaterMark(
             int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
-        List<ProcessMemoryHighWaterMark> results = LocalServices.getService(
-                ActivityManagerInternal.class).getMemoryHighWaterMarkForProcesses();
-        for (ProcessMemoryHighWaterMark processMemoryHighWaterMark : results) {
+        List<ProcessMemoryState> managedProcessList =
+                LocalServices.getService(
+                        ActivityManagerInternal.class).getMemoryStateForProcesses();
+        for (ProcessMemoryState managedProcess : managedProcessList) {
+            final long rssHighWaterMarkInBytes =
+                    readRssHighWaterMarkFromProcfs(managedProcess.pid);
+            if (rssHighWaterMarkInBytes == 0) {
+                continue;
+            }
             StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeInt(processMemoryHighWaterMark.uid);
-            e.writeString(processMemoryHighWaterMark.processName);
-            e.writeLong(processMemoryHighWaterMark.rssHighWaterMarkInBytes);
+            e.writeInt(managedProcess.uid);
+            e.writeString(managedProcess.processName);
+            e.writeLong(rssHighWaterMarkInBytes);
             pulledData.add(e);
         }
         int[] pids = getPidsForCommands(MEMORY_INTERESTING_NATIVE_PROCESSES);
@@ -1255,6 +1273,21 @@
         pulledData.add(e);
     }
 
+    private void pullProcessSystemIonHeapSize(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        List<IonAllocations> result = readProcessSystemIonHeapSizesFromDebugfs();
+        for (IonAllocations allocations : result) {
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+            e.writeInt(getUidForPid(allocations.pid));
+            e.writeString(readCmdlineFromProcfs(allocations.pid));
+            e.writeInt((int) (allocations.totalSizeInBytes / 1024));
+            e.writeInt(allocations.count);
+            e.writeInt((int) (allocations.maxSizeInBytes / 1024));
+            pulledData.add(e);
+        }
+    }
+
     private void pullBinderCallsStats(
             int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
@@ -1984,10 +2017,9 @@
                         e.writeString(permName);
                         e.writeInt(pkg.applicationInfo.uid);
                         e.writeString(pkg.packageName);
-                        e.writeInt(permissionFlags);
-
                         e.writeBoolean((pkg.requestedPermissionsFlags[permNum]
                                 & REQUESTED_PERMISSION_GRANTED) != 0);
+                        e.writeInt(permissionFlags);
 
                         pulledData.add(e);
                     }
@@ -2318,6 +2350,10 @@
                 pullSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
+            case StatsLog.PROCESS_SYSTEM_ION_HEAP_SIZE: {
+                pullProcessSystemIonHeapSize(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
             case StatsLog.BINDER_CALLS: {
                 pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
@@ -2513,7 +2549,7 @@
         @Override
         public void onBootPhase(int phase) {
             super.onBootPhase(phase);
-            if (phase == PHASE_BOOT_COMPLETED) {
+            if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
                 mStatsCompanionService.systemReady();
             }
         }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 112104d..828f790 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -719,21 +719,6 @@
         // Ensure state for the current user is applied, even if passed a non-current user.
         final int net1 = gatherDisableActionsLocked(mCurrentUserId, 1);
         final int net2 = gatherDisableActionsLocked(mCurrentUserId, 2);
-
-        // TODO(b/113914868): investigation log for disappearing home button
-        if (whichFlag == 1 && pkg != null && pkg.contains("systemui")) {
-            String disabledData = "{ ";
-            for (int i = 0; i < mDisableRecords.size(); i++) {
-                DisableRecord tok = mDisableRecords.get(i);
-                disabledData += "    ([" + i + "] " + tok + "), ";
-            }
-            disabledData += " }";
-            final UiState state = getUiState(displayId);
-
-            Log.d(TAG, "disabledlocked (b/113914868): displayId=" + displayId + ", net1=" + net1
-                    + ", mDisabled1=" + state.mDisabled1 + ", token=" + token
-                    + ", mDisableRecords=" + mDisableRecords.size() + " => " + disabledData);
-        }
         final UiState state = getUiState(displayId);
         if (!state.disableEquals(net1, net2)) {
             state.setDisabled(net1, net2);
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index 54369ca..a853529 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -39,7 +39,6 @@
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.pm.UserManagerService;
-import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 /**
@@ -66,9 +65,9 @@
                 ServiceManager.addService(Context.TELECOM_SERVICE, service);
 
                 synchronized (mLock) {
+                    final PermissionManagerServiceInternal permissionManager =
+                            LocalServices.getService(PermissionManagerServiceInternal.class);
                     if (mDefaultSimCallManagerRequests != null) {
-                        final DefaultPermissionGrantPolicy permissionPolicy =
-                                getDefaultPermissionGrantPolicy();
                         if (mDefaultSimCallManagerRequests != null) {
                             TelecomManager telecomManager =
                                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
@@ -80,7 +79,7 @@
                                 for (int i = requestCount - 1; i >= 0; i--) {
                                     final int userId = mDefaultSimCallManagerRequests.get(i);
                                     mDefaultSimCallManagerRequests.remove(i);
-                                    permissionPolicy
+                                    permissionManager
                                             .grantDefaultPermissionsToDefaultSimCallManager(
                                                     packageName, userId);
                                 }
@@ -99,11 +98,6 @@
         }
     }
 
-    private DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
-        return LocalServices.getService(PermissionManagerServiceInternal.class)
-                .getDefaultPermissionGrantPolicy();
-    }
-
     private static final ComponentName SERVICE_COMPONENT = new ComponentName(
             "com.android.server.telecom",
             "com.android.server.telecom.components.TelecomService");
@@ -162,10 +156,11 @@
 
 
     private void registerDefaultAppProviders() {
-        final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
+        final PermissionManagerServiceInternal permissionManager =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
 
         // Set a callback for the permission grant policy to query the default sms app.
-        permissionPolicy.setSmsAppPackagesProvider(userId -> {
+        permissionManager.setSmsAppPackagesProvider(userId -> {
             synchronized (mLock) {
                 if (mServiceConnection == null) {
                     return null;
@@ -180,7 +175,7 @@
         });
 
         // Set a callback for the permission grant policy to query the default dialer app.
-        permissionPolicy.setDialerAppPackagesProvider(userId -> {
+        permissionManager.setDialerAppPackagesProvider(userId -> {
             synchronized (mLock) {
                 if (mServiceConnection == null) {
                     return null;
@@ -194,7 +189,7 @@
         });
 
         // Set a callback for the permission grant policy to query the default sim call manager.
-        permissionPolicy.setSimCallManagerPackagesProvider(userId -> {
+        permissionManager.setSimCallManagerPackagesProvider(userId -> {
             synchronized (mLock) {
                 if (mServiceConnection == null) {
                     if (mDefaultSimCallManagerRequests == null) {
@@ -215,12 +210,11 @@
     }
 
     private void registerDefaultAppNotifier() {
-        final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
         // Notify the package manager on default app changes
         final RoleManager roleManager = mContext.getSystemService(RoleManager.class);
         roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(),
-                (roleName, user) -> updateSimCallManagerPermissions(permissionPolicy,
-                        user.getIdentifier()), UserHandle.ALL);
+                (roleName, user) -> updateSimCallManagerPermissions(user.getIdentifier()),
+                UserHandle.ALL);
     }
 
 
@@ -230,7 +224,7 @@
             public void onReceive(Context context, Intent intent) {
                 if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
                     for (int userId : UserManagerService.getInstance().getUserIds()) {
-                        updateSimCallManagerPermissions(getDefaultPermissionGrantPolicy(), userId);
+                        updateSimCallManagerPermissions(userId);
                     }
                 }
             }
@@ -240,16 +234,16 @@
             new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null);
     }
 
-    private void updateSimCallManagerPermissions(
-            DefaultPermissionGrantPolicy permissionGrantPolicy, int userId) {
+    private void updateSimCallManagerPermissions(int userId) {
+        final PermissionManagerServiceInternal permissionManager =
+                LocalServices.getService(PermissionManagerServiceInternal.class);
         TelecomManager telecomManager =
             (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
         PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
         if (phoneAccount != null) {
             Slog.i(TAG, "updating sim call manager permissions for userId:" + userId);
             String packageName = phoneAccount.getComponentName().getPackageName();
-            permissionGrantPolicy.grantDefaultPermissionsToDefaultSimCallManager(
-                packageName, userId);
+            permissionManager.grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
         }
     }
 }
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 5f00148..ab3d7b7 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -30,6 +30,7 @@
 import android.service.textclassifier.ITextClassifierCallback;
 import android.service.textclassifier.ITextClassifierService;
 import android.service.textclassifier.TextClassifierService;
+import android.util.ArrayMap;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.textclassifier.ConversationActions;
@@ -54,6 +55,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayDeque;
+import java.util.Map;
 import java.util.Queue;
 
 /**
@@ -119,6 +121,8 @@
     private final Object mLock;
     @GuardedBy("mLock")
     final SparseArray<UserState> mUserStates = new SparseArray<>();
+    @GuardedBy("mLock")
+    private final Map<TextClassificationSessionId, Integer> mSessionUserIds = new ArrayMap<>();
 
     private TextClassificationManagerService(Context context) {
         mContext = Preconditions.checkNotNull(context);
@@ -127,15 +131,16 @@
 
     @Override
     public void onSuggestSelection(
-            TextClassificationSessionId sessionId,
+            @Nullable TextClassificationSessionId sessionId,
             TextSelection.Request request, ITextClassifierCallback callback)
             throws RemoteException {
         Preconditions.checkNotNull(request);
         Preconditions.checkNotNull(callback);
-        validateInput(mContext, request.getCallingPackageName());
+        final int userId = request.getUserId();
+        validateInput(mContext, request.getCallingPackageName(), userId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            UserState userState = getUserStateLocked(userId);
             if (!userState.bindLocked()) {
                 callback.onFailure();
             } else if (userState.isBoundLocked()) {
@@ -150,15 +155,16 @@
 
     @Override
     public void onClassifyText(
-            TextClassificationSessionId sessionId,
+            @Nullable TextClassificationSessionId sessionId,
             TextClassification.Request request, ITextClassifierCallback callback)
             throws RemoteException {
         Preconditions.checkNotNull(request);
         Preconditions.checkNotNull(callback);
-        validateInput(mContext, request.getCallingPackageName());
+        final int userId = request.getUserId();
+        validateInput(mContext, request.getCallingPackageName(), userId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            UserState userState = getUserStateLocked(userId);
             if (!userState.bindLocked()) {
                 callback.onFailure();
             } else if (userState.isBoundLocked()) {
@@ -173,15 +179,16 @@
 
     @Override
     public void onGenerateLinks(
-            TextClassificationSessionId sessionId,
+            @Nullable TextClassificationSessionId sessionId,
             TextLinks.Request request, ITextClassifierCallback callback)
             throws RemoteException {
         Preconditions.checkNotNull(request);
         Preconditions.checkNotNull(callback);
-        validateInput(mContext, request.getCallingPackageName());
+        final int userId = request.getUserId();
+        validateInput(mContext, request.getCallingPackageName(), userId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            UserState userState = getUserStateLocked(userId);
             if (!userState.bindLocked()) {
                 callback.onFailure();
             } else if (userState.isBoundLocked()) {
@@ -196,12 +203,14 @@
 
     @Override
     public void onSelectionEvent(
-            TextClassificationSessionId sessionId, SelectionEvent event) throws RemoteException {
+            @Nullable TextClassificationSessionId sessionId, SelectionEvent event)
+            throws RemoteException {
         Preconditions.checkNotNull(event);
-        validateInput(mContext, event.getPackageName());
+        final int userId = event.getUserId();
+        validateInput(mContext, event.getPackageName(), userId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            UserState userState = getUserStateLocked(userId);
             if (userState.isBoundLocked()) {
                 userState.mService.onSelectionEvent(sessionId, event);
             } else {
@@ -213,16 +222,19 @@
     }
     @Override
     public void onTextClassifierEvent(
-            TextClassificationSessionId sessionId,
+            @Nullable TextClassificationSessionId sessionId,
             TextClassifierEvent event) throws RemoteException {
         Preconditions.checkNotNull(event);
         final String packageName = event.getEventContext() == null
                 ? null
                 : event.getEventContext().getPackageName();
-        validateInput(mContext, packageName);
+        final int userId = event.getEventContext() == null
+                ? UserHandle.getCallingUserId()
+                : event.getEventContext().getUserId();
+        validateInput(mContext, packageName, userId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            UserState userState = getUserStateLocked(userId);
             if (userState.isBoundLocked()) {
                 userState.mService.onTextClassifierEvent(sessionId, event);
             } else {
@@ -235,15 +247,16 @@
 
     @Override
     public void onDetectLanguage(
-            TextClassificationSessionId sessionId,
+            @Nullable TextClassificationSessionId sessionId,
             TextLanguage.Request request,
             ITextClassifierCallback callback) throws RemoteException {
         Preconditions.checkNotNull(request);
         Preconditions.checkNotNull(callback);
-        validateInput(mContext, request.getCallingPackageName());
+        final int userId = request.getUserId();
+        validateInput(mContext, request.getCallingPackageName(), userId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            UserState userState = getUserStateLocked(userId);
             if (!userState.bindLocked()) {
                 callback.onFailure();
             } else if (userState.isBoundLocked()) {
@@ -258,15 +271,16 @@
 
     @Override
     public void onSuggestConversationActions(
-            TextClassificationSessionId sessionId,
+            @Nullable TextClassificationSessionId sessionId,
             ConversationActions.Request request,
             ITextClassifierCallback callback) throws RemoteException {
         Preconditions.checkNotNull(request);
         Preconditions.checkNotNull(callback);
-        validateInput(mContext, request.getCallingPackageName());
+        final int userId = request.getUserId();
+        validateInput(mContext, request.getCallingPackageName(), userId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            UserState userState = getUserStateLocked(userId);
             if (!userState.bindLocked()) {
                 callback.onFailure();
             } else if (userState.isBoundLocked()) {
@@ -285,13 +299,15 @@
             throws RemoteException {
         Preconditions.checkNotNull(sessionId);
         Preconditions.checkNotNull(classificationContext);
-        validateInput(mContext, classificationContext.getPackageName());
+        final int userId = classificationContext.getUserId();
+        validateInput(mContext, classificationContext.getPackageName(), userId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            UserState userState = getUserStateLocked(userId);
             if (userState.isBoundLocked()) {
                 userState.mService.onCreateTextClassificationSession(
                         classificationContext, sessionId);
+                mSessionUserIds.put(sessionId, userId);
             } else {
                 userState.mPendingRequests.add(new PendingRequest(
                         () -> onCreateTextClassificationSession(classificationContext, sessionId),
@@ -306,9 +322,15 @@
         Preconditions.checkNotNull(sessionId);
 
         synchronized (mLock) {
-            UserState userState = getCallingUserStateLocked();
+            final int userId = mSessionUserIds.containsKey(sessionId)
+                    ? mSessionUserIds.get(sessionId)
+                    : UserHandle.getCallingUserId();
+            validateInput(mContext, null /* packageName */, userId);
+
+            UserState userState = getUserStateLocked(userId);
             if (userState.isBoundLocked()) {
                 userState.mService.onDestroyTextClassificationSession(sessionId);
+                mSessionUserIds.remove(sessionId);
             } else {
                 userState.mPendingRequests.add(new PendingRequest(
                         () -> onDestroyTextClassificationSession(sessionId),
@@ -318,11 +340,6 @@
     }
 
     @GuardedBy("mLock")
-    private UserState getCallingUserStateLocked() {
-        return getUserStateLocked(UserHandle.getCallingUserId());
-    }
-
-    @GuardedBy("mLock")
     private UserState getUserStateLocked(int userId) {
         UserState result = mUserStates.get(userId);
         if (result == null) {
@@ -356,6 +373,7 @@
                     pw.decreaseIndent();
                 }
             }
+            pw.println("Number of active sessions: " + mSessionUserIds.size());
         }
     }
 
@@ -420,20 +438,32 @@
                 e -> Slog.d(LOG_TAG, "Error " + opDesc + ": " + e.getMessage()));
     }
 
-    private static void validateInput(Context context, @Nullable String packageName)
+    private static void validateInput(
+            Context context, @Nullable String packageName, @UserIdInt int userId)
             throws RemoteException {
-        if (packageName == null) return;
 
         try {
-            final int packageUid = context.getPackageManager()
-                    .getPackageUidAsUser(packageName, UserHandle.getCallingUserId());
-            final int callingUid = Binder.getCallingUid();
-            Preconditions.checkArgument(callingUid == packageUid
-                    // Trust the system process:
-                    || callingUid == android.os.Process.SYSTEM_UID);
+            if (packageName != null) {
+                final int packageUid = context.getPackageManager()
+                        .getPackageUidAsUser(packageName, UserHandle.getCallingUserId());
+                final int callingUid = Binder.getCallingUid();
+                Preconditions.checkArgument(callingUid == packageUid
+                        // Trust the system process:
+                        || callingUid == android.os.Process.SYSTEM_UID,
+                        "Invalid package name. Package=" + packageName
+                                + ", CallingUid=" + callingUid);
+            }
+
+            Preconditions.checkArgument(userId != UserHandle.USER_NULL, "Null userId");
+            final int callingUserId = UserHandle.getCallingUserId();
+            if (callingUserId != userId) {
+                context.enforceCallingPermission(
+                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+                        "Invalid userId. UserId=" + userId + ", CallingUserId=" + callingUserId);
+            }
         } catch (Exception e) {
-            throw new RemoteException(
-                    String.format("Invalid package: name=%s, error=%s", packageName, e));
+            throw new RemoteException("Invalid request", e,
+                    /* enableSuppression */ true, /* writableStackTrace */ true);
         }
     }
 
diff --git a/services/core/java/com/android/server/textservices/LazyIntToIntMap.java b/services/core/java/com/android/server/textservices/LazyIntToIntMap.java
deleted file mode 100644
index 2e7f2a9..0000000
--- a/services/core/java/com/android/server/textservices/LazyIntToIntMap.java
+++ /dev/null
@@ -1,64 +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.server.textservices;
-
-import android.annotation.NonNull;
-import android.util.SparseIntArray;
-
-import java.util.function.IntUnaryOperator;
-
-/**
- * Simple int-to-int key-value-store that is to be lazily initialized with the given
- * {@link IntUnaryOperator}.
- */
-final class LazyIntToIntMap {
-
-    private final SparseIntArray mMap = new SparseIntArray();
-
-    @NonNull
-    private final IntUnaryOperator mMappingFunction;
-
-    /**
-     * @param mappingFunction int to int mapping rules to be (lazily) evaluated
-     */
-    public LazyIntToIntMap(@NonNull IntUnaryOperator mappingFunction) {
-        mMappingFunction = mappingFunction;
-    }
-
-    /**
-     * Deletes {@code key} and associated value.
-     * @param key key to be deleted
-     */
-    public void delete(int key) {
-        mMap.delete(key);
-    }
-
-    /**
-     * @param key key associated with the value
-     * @return value associated with the {@code key}. If this is the first time to access
-     * {@code key}, then {@code mappingFunction} passed to the constructor will be evaluated
-     */
-    public int get(int key) {
-        final int index = mMap.indexOfKey(key);
-        if (index >= 0) {
-            return mMap.valueAt(index);
-        }
-        final int value = mMappingFunction.applyAsInt(key);
-        mMap.append(key, value);
-        return value;
-    }
-}
diff --git a/services/core/java/com/android/server/textservices/TextServicesManagerService.java b/services/core/java/com/android/server/textservices/TextServicesManagerService.java
index d4aa59d..e0bac93 100644
--- a/services/core/java/com/android/server/textservices/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/textservices/TextServicesManagerService.java
@@ -43,7 +43,6 @@
 import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.view.inputmethod.InputMethodSystemProperty;
 import android.view.textservice.SpellCheckerInfo;
 import android.view.textservice.SpellCheckerSubtype;
 
@@ -86,10 +85,6 @@
     private final UserManager mUserManager;
     private final Object mLock = new Object();
 
-    @NonNull
-    @GuardedBy("mLock")
-    private final LazyIntToIntMap mSpellCheckerOwnerUserIdMap;
-
     private static class TextServicesData {
         @UserIdInt
         private final int mUserId;
@@ -312,9 +307,6 @@
 
     void onStopUser(@UserIdInt int userId) {
         synchronized (mLock) {
-            // Clear user ID mapping table.
-            mSpellCheckerOwnerUserIdMap.delete(userId);
-
             // Clean per-user data
             TextServicesData tsd = mUserData.get(userId);
             if (tsd == null) return;
@@ -334,33 +326,12 @@
     public TextServicesManagerService(Context context) {
         mContext = context;
         mUserManager = mContext.getSystemService(UserManager.class);
-        mSpellCheckerOwnerUserIdMap = new LazyIntToIntMap(callingUserId -> {
-            if (!InputMethodSystemProperty.PER_PROFILE_IME_ENABLED) {
-                final long token = Binder.clearCallingIdentity();
-                try {
-                    final UserInfo parent = mUserManager.getProfileParent(callingUserId);
-                    return (parent != null) ? parent.id : callingUserId;
-                } finally {
-                    Binder.restoreCallingIdentity(token);
-                }
-            } else {
-                return callingUserId;
-            }
-        });
-
         mMonitor = new TextServicesMonitor();
         mMonitor.register(context, null, UserHandle.ALL, true);
     }
 
     @GuardedBy("mLock")
     private void initializeInternalStateLocked(@UserIdInt int userId) {
-        // When DISABLE_PER_PROFILE_SPELL_CHECKER is true, we make sure here that work profile users
-        // will never have non-null TextServicesData for their user ID.
-        if (!InputMethodSystemProperty.PER_PROFILE_IME_ENABLED
-                && userId != mSpellCheckerOwnerUserIdMap.get(userId)) {
-            return;
-        }
-
         TextServicesData tsd = mUserData.get(userId);
         if (tsd == null) {
             tsd = new TextServicesData(userId, mContext);
@@ -506,8 +477,7 @@
     @Nullable
     private SpellCheckerInfo getCurrentSpellCheckerForUser(@UserIdInt int userId) {
         synchronized (mLock) {
-            final int spellCheckerOwnerUserId = mSpellCheckerOwnerUserIdMap.get(userId);
-            final TextServicesData data = mUserData.get(spellCheckerOwnerUserId);
+            final TextServicesData data = mUserData.get(userId);
             return data != null ? data.getCurrentSpellChecker() : null;
         }
     }
@@ -790,27 +760,7 @@
     @GuardedBy("mLock")
     @Nullable
     private TextServicesData getDataFromCallingUserIdLocked(@UserIdInt int callingUserId) {
-        final int spellCheckerOwnerUserId = mSpellCheckerOwnerUserIdMap.get(callingUserId);
-        final TextServicesData data = mUserData.get(spellCheckerOwnerUserId);
-        if (!InputMethodSystemProperty.PER_PROFILE_IME_ENABLED) {
-            if (spellCheckerOwnerUserId != callingUserId) {
-                // Calling process is running under child profile.
-                if (data == null) {
-                    return null;
-                }
-                final SpellCheckerInfo info = data.getCurrentSpellChecker();
-                if (info == null) {
-                    return null;
-                }
-                final ServiceInfo serviceInfo = info.getServiceInfo();
-                if ((serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
-                    // To be conservative, non pre-installed spell checker services are not allowed
-                    // to be used for child profiles.
-                    return null;
-                }
-            }
-        }
-        return data;
+        return mUserData.get(callingUserId);
     }
 
     private static final class SessionRequest {
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index 296a652..28c171b 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -108,7 +108,7 @@
 
     private static RulesManagerService create(Context context) {
         RulesManagerServiceHelperImpl helper = new RulesManagerServiceHelperImpl(context);
-        File baseVersionFile = new File(TimeZoneDataFiles.getRuntimeModuleTzVersionFile());
+        File baseVersionFile = new File(TimeZoneDataFiles.getTimeZoneModuleTzVersionFile());
         File tzDataDir = new File(TimeZoneDataFiles.getDataTimeZoneRootDir());
         return new RulesManagerService(
                 helper /* permissionHelper */,
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index a2eb40b..7408dd4 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -199,6 +199,7 @@
         private final Uri LOCK_SCREEN_WHEN_TRUST_LOST =
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_WHEN_TRUST_LOST);
 
+        private final boolean mIsAutomotive;
         private final ContentResolver mContentResolver;
         private boolean mTrustAgentsExtendUnlock;
         private boolean mLockWhenTrustLost;
@@ -210,6 +211,10 @@
          */
         SettingsObserver(Handler handler) {
             super(handler);
+
+            PackageManager packageManager = getContext().getPackageManager();
+            mIsAutomotive = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+
             mContentResolver = getContext().getContentResolver();
             updateContentObserver();
         }
@@ -233,11 +238,15 @@
         @Override
         public void onChange(boolean selfChange, Uri uri) {
             if (TRUST_AGENTS_EXTEND_UNLOCK.equals(uri)) {
+                // Smart lock should only extend unlock. The only exception is for automotive,
+                // where it can actively unlock the head unit.
+                int defaultValue = mIsAutomotive ? 0 : 1;
+
                 mTrustAgentsExtendUnlock =
                         Settings.Secure.getIntForUser(
                                 mContentResolver,
                                 Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
-                                0 /* default */,
+                                defaultValue,
                                 mCurrentUser) != 0;
             } else if (LOCK_SCREEN_WHEN_TRUST_LOST.equals(uri)) {
                 mLockWhenTrustLost =
diff --git a/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java b/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
index ec65f8d..bf32045 100644
--- a/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
@@ -16,25 +16,30 @@
 
 package com.android.server.updates;
 
-import com.android.internal.util.HexDump;
 import android.os.FileUtils;
-import android.system.Os;
 import android.system.ErrnoException;
+import android.system.Os;
 import android.util.Base64;
 import android.util.Slog;
+
+import com.android.internal.util.HexDump;
+
+import libcore.io.Streams;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileFilter;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStreamWriter;
-import java.io.StringBufferInputStream;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
-import java.security.PublicKey;
 import java.security.NoSuchAlgorithmException;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
 
 public class CertificateTransparencyLogInstallReceiver extends ConfigUpdateInstallReceiver {
 
@@ -46,14 +51,13 @@
     }
 
     @Override
-    protected void install(byte[] content, int version) throws IOException {
+    protected void install(InputStream inputStream, int version) throws IOException {
         /* Install is complicated here because we translate the input, which is a JSON file
          * containing log information to a directory with a file per log. To support atomically
          * replacing the old configuration directory with the new there's a bunch of steps. We
          * create a new directory with the logs and then do an atomic update of the current symlink
          * to point to the new directory.
          */
-
         // 1. Ensure that the update dir exists and is readable
         updateDir.mkdir();
         if (!updateDir.isDirectory()) {
@@ -72,7 +76,8 @@
             // and so we cannot delete the directory since its in use. Instead just bump the version
             // and return.
             if (newVersion.getCanonicalPath().equals(currentSymlink.getCanonicalPath())) {
-                writeUpdate(updateDir, updateVersion, Long.toString(version).getBytes());
+                writeUpdate(updateDir, updateVersion,
+                        new ByteArrayInputStream(Long.toString(version).getBytes()));
                 deleteOldLogDirectories();
                 return;
             } else {
@@ -92,6 +97,7 @@
 
             // 4. For each log in the log file create the corresponding file in <new_version>/ .
             try {
+                byte[] content = Streams.readFullyNoClose(inputStream);
                 JSONObject json = new JSONObject(new String(content, StandardCharsets.UTF_8));
                 JSONArray logs = json.getJSONArray("logs");
                 for (int i = 0; i < logs.length(); i++) {
@@ -119,7 +125,8 @@
         }
         Slog.i(TAG, "CT log directory updated to " + newVersion.getAbsolutePath());
         // 7. Update the current version information
-        writeUpdate(updateDir, updateVersion, Long.toString(version).getBytes());
+        writeUpdate(updateDir, updateVersion,
+                new ByteArrayInputStream(Long.toString(version).getBytes()));
         // 8. Cleanup
         deleteOldLogDirectories();
     }
diff --git a/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index c3c841c..73bb4bf 100644
--- a/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -16,9 +16,6 @@
 
 package com.android.server.updates;
 
-import com.android.server.EventLogTags;
-import com.android.internal.util.HexDump;
-
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -26,6 +23,14 @@
 import android.util.EventLog;
 import android.util.Slog;
 
+import com.android.internal.util.HexDump;
+import com.android.server.EventLogTags;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -33,9 +38,6 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-
 public class ConfigUpdateInstallReceiver extends BroadcastReceiver {
 
     private static final String TAG = "ConfigUpdateInstallReceiver";
@@ -61,8 +63,6 @@
             @Override
             public void run() {
                 try {
-                    // get the content path from the extras
-                    byte[] altContent = getAltContent(context, intent);
                     // get the version from the extras
                     int altVersion = getVersionFromIntent(intent);
                     // get the previous value from the extras
@@ -75,11 +75,13 @@
                         Slog.i(TAG, "Not installing, new version is <= current version");
                     } else if (!verifyPreviousHash(currentHash, altRequiredHash)) {
                         EventLog.writeEvent(EventLogTags.CONFIG_INSTALL_FAILED,
-                                            "Current hash did not match required value");
+                                "Current hash did not match required value");
                     } else {
                         // install the new content
                         Slog.i(TAG, "Found new update, installing...");
-                        install(altContent, altVersion);
+                        try (BufferedInputStream altContent = getAltContent(context, intent)) {
+                            install(altContent, altVersion);
+                        }
                         Slog.i(TAG, "Installation successful");
                         postInstall(context, intent);
                     }
@@ -130,14 +132,9 @@
         }
     }
 
-    private byte[] getAltContent(Context c, Intent i) throws IOException {
+    private BufferedInputStream getAltContent(Context c, Intent i) throws IOException {
         Uri content = getContentFromIntent(i);
-        InputStream is = c.getContentResolver().openInputStream(content);
-        try {
-            return Streams.readFullyNoClose(is);
-        } finally {
-            is.close();
-        }
+        return new BufferedInputStream(c.getContentResolver().openInputStream(content));
     }
 
     private byte[] getCurrentContent() {
@@ -175,7 +172,7 @@
         return current.equals(required);
     }
 
-    protected void writeUpdate(File dir, File file, byte[] content) throws IOException {
+    protected void writeUpdate(File dir, File file, InputStream inputStream) throws IOException {
         FileOutputStream out = null;
         File tmp = null;
         try {
@@ -192,7 +189,7 @@
             tmp.setReadable(true, false);
             // write to it
             out = new FileOutputStream(tmp);
-            out.write(content);
+            Streams.copy(inputStream, out);
             // sync to disk
             out.getFD().sync();
             // atomic rename
@@ -207,9 +204,10 @@
         }
     }
 
-    protected void install(byte[] content, int version) throws IOException {
-        writeUpdate(updateDir, updateContent, content);
-        writeUpdate(updateDir, updateVersion, Long.toString(version).getBytes());
+    protected void install(InputStream inputStream, int version) throws IOException {
+        writeUpdate(updateDir, updateContent, inputStream);
+        writeUpdate(updateDir, updateVersion,
+                new ByteArrayInputStream(Long.toString(version).getBytes()));
     }
 
     protected void postInstall(Context context, Intent intent) {
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index 8b332d2..04839e1 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -110,6 +110,7 @@
     private static final String TAG = "UriGrantsManagerService";
     // Maximum number of persisted Uri grants a package is allowed
     private static final int MAX_PERSISTED_URI_GRANTS = 128;
+    private static final boolean ENABLE_DYNAMIC_PERMISSIONS = false;
 
     private final Object mLock = new Object();
     private final Context mContext;
@@ -949,7 +950,25 @@
             return false;
         }
 
-        return readMet && writeMet;
+        // If this provider says that grants are always required, we need to
+        // consult it directly to determine if the UID has permission
+        final boolean forceMet;
+        if (ENABLE_DYNAMIC_PERMISSIONS && pi.forceUriPermissions) {
+            final int providerUserId = UserHandle.getUserId(pi.applicationInfo.uid);
+            final int clientUserId = UserHandle.getUserId(uid);
+            if (providerUserId == clientUserId) {
+                forceMet = (mAmInternal.checkContentProviderUriPermission(grantUri.uri,
+                        providerUserId, uid, modeFlags) == PackageManager.PERMISSION_GRANTED);
+            } else {
+                // The provider can't track cross-user permissions, so we have
+                // to assume they're always denied
+                forceMet = false;
+            }
+        } else {
+            forceMet = true;
+        }
+
+        return readMet && writeMet && forceMet;
     }
 
     private void removeUriPermissionIfNeeded(UriPermission perm) {
@@ -1032,11 +1051,13 @@
         // must always grant permissions on behalf of someone explicit.
         final int callingAppId = UserHandle.getAppId(callingUid);
         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
-            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
+            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())
+                    || "com.android.settings.module_licenses".equals(grantUri.uri.getAuthority())) {
                 // Exempted authority for
                 // 1. cropping user photos and sharing a generated license html
                 //    file in Settings app
                 // 2. sharing a generated license html file in TvSettings app
+                // 3. Sharing module license files from Settings app
             } else {
                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
diff --git a/services/core/java/com/android/server/utils/TimingsTraceAndSlog.java b/services/core/java/com/android/server/utils/TimingsTraceAndSlog.java
new file mode 100644
index 0000000..03c96e9
--- /dev/null
+++ b/services/core/java/com/android/server/utils/TimingsTraceAndSlog.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.utils;
+
+import android.annotation.NonNull;
+import android.os.Trace;
+import android.util.Slog;
+import android.util.TimingsTraceLog;
+
+/**
+ * Helper class for reporting boot and shutdown timing metrics, also logging to {@link Slog}.
+ */
+public final class TimingsTraceAndSlog extends TimingsTraceLog {
+
+    /**
+    * Tag for timing measurement of main thread.
+    */
+    public static final String SYSTEM_SERVER_TIMING_TAG = "SystemServerTiming";
+
+    /**
+     * Tag for timing measurement of non-main asynchronous operations.
+     */
+    private static final String SYSTEM_SERVER_TIMING_ASYNC_TAG = SYSTEM_SERVER_TIMING_TAG + "Async";
+
+    /**
+     * Set this to a positive value to get a {@Slog.w} log for any trace that took longer than it.
+     */
+    private static final long BOTTLENECK_DURATION_MS = -1;
+
+    private final String mTag;
+
+    /**
+     * Creates a new {@link TimingsTraceAndSlog} for async operations.
+     */
+    @NonNull
+    public static TimingsTraceAndSlog newAsyncLog() {
+        return new TimingsTraceAndSlog(SYSTEM_SERVER_TIMING_ASYNC_TAG,
+                Trace.TRACE_TAG_SYSTEM_SERVER);
+    }
+
+    /**
+     * Default constructor using {@code system_server} tags.
+     */
+    public TimingsTraceAndSlog() {
+        this(SYSTEM_SERVER_TIMING_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+    }
+
+    /**
+     * Custom constructor.
+     *
+     * @param tag {@code logcat} tag
+     * @param traceTag {@code atrace} tag
+     */
+    public TimingsTraceAndSlog(@NonNull String tag, long traceTag) {
+        super(tag, traceTag);
+        mTag = tag;
+    }
+
+    @Override
+    public void traceBegin(@NonNull String name) {
+        Slog.i(mTag, name);
+        super.traceBegin(name);
+    }
+
+    @Override
+    public void logDuration(String name, long timeMs) {
+        super.logDuration(name, timeMs);
+        if (BOTTLENECK_DURATION_MS > 0 && timeMs >= BOTTLENECK_DURATION_MS) {
+            Slog.w(mTag, "Slow duration for " + name + ": " + timeMs + "ms");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "TimingsTraceAndSlog[" + mTag + "]";
+    }
+}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 9908b36..b0f1e5d 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1172,8 +1172,16 @@
                 return false;
             }
             final int displayId = display.getDisplayId();
-            return displayId == DEFAULT_DISPLAY
-                    || mWindowManagerInternal.shouldShowSystemDecorOnDisplay(displayId);
+            if (displayId == DEFAULT_DISPLAY) {
+                return true;
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                return mWindowManagerInternal.shouldShowSystemDecorOnDisplay(displayId);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
 
         void forEachDisplayConnector(Consumer<DisplayConnector> action) {
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index 165055a..11fd795 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -82,6 +82,22 @@
     void prepareWebViewInSystemServer() {
         migrateFallbackStateOnBoot();
         mWebViewUpdater.prepareWebViewInSystemServer();
+        if (getCurrentWebViewPackage() == null) {
+            // We didn't find a valid WebView implementation. Try explicitly re-enabling the
+            // fallback package for all users in case it was disabled, even if we already did the
+            // one-time migration before. If this actually changes the state, WebViewUpdater will
+            // see the PackageManager broadcast shortly and try again.
+            WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
+            WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
+            if (fallbackProvider != null) {
+                Slog.w(TAG, "No valid provider, trying to enable " + fallbackProvider.packageName);
+                mSystemInterface.enablePackageForAllUsers(mContext, fallbackProvider.packageName,
+                                                          true);
+            } else {
+                Slog.e(TAG, "No valid provider and no fallback available.");
+            }
+        }
+
         boolean multiProcessEnabled = isMultiProcessEnabled();
         mSystemInterface.notifyZygote(multiProcessEnabled);
         if (multiProcessEnabled) {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 4cfc1d1..26ca975 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -22,6 +22,7 @@
 
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.utils.RegionUtils.forEachRect;
 
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
@@ -43,9 +44,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.text.TextUtils;
 import android.util.ArraySet;
-import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TypedValue;
@@ -86,7 +85,8 @@
 
     private SparseArray<DisplayMagnifier> mDisplayMagnifiers = new SparseArray<>();
 
-    private WindowsForAccessibilityObserver mWindowsForAccessibilityObserver;
+    private SparseArray<WindowsForAccessibilityObserver> mWindowsForAccessibilityObserver =
+            new SparseArray<>();
 
     public boolean setMagnificationCallbacksLocked(int displayId,
             MagnificationCallbacks callbacks) {
@@ -116,27 +116,52 @@
         return result;
     }
 
-    public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) {
+    public boolean setWindowsForAccessibilityCallbackLocked(int displayId,
+            WindowsForAccessibilityCallback callback) {
         if (callback != null) {
-            if (mWindowsForAccessibilityObserver != null) {
-                throw new IllegalStateException(
-                        "Windows for accessibility callback already set!");
+            final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
+            if (dc == null) {
+                return false;
             }
-            mWindowsForAccessibilityObserver = new WindowsForAccessibilityObserver(
-                    mService, callback);
+
+            final Display display = dc.getDisplay();
+            if (mWindowsForAccessibilityObserver.get(displayId) != null) {
+                if (display.getType() == Display.TYPE_VIRTUAL && dc.getParentWindow() != null) {
+                    // The window observer of this embedded display had been set from
+                    // window manager after setting its parent window
+                    return true;
+                } else {
+                    throw new IllegalStateException(
+                            "Windows for accessibility callback of display "
+                                    + displayId + " already set!");
+                }
+            }
+            if (display.getType() == Display.TYPE_OVERLAY) {
+                return false;
+            }
+            mWindowsForAccessibilityObserver.put(displayId,
+                    new WindowsForAccessibilityObserver(mService, displayId, callback));
         } else {
-            if (mWindowsForAccessibilityObserver == null) {
+            final WindowsForAccessibilityObserver windowsForA11yObserver =
+                    mWindowsForAccessibilityObserver.get(displayId);
+            if  (windowsForA11yObserver == null) {
                 throw new IllegalStateException(
-                        "Windows for accessibility callback already cleared!");
+                        "Windows for accessibility callback of display " + displayId
+                                + " already cleared!");
             }
-            mWindowsForAccessibilityObserver = null;
+            mWindowsForAccessibilityObserver.remove(displayId);
         }
+        return true;
     }
 
-    public void performComputeChangedWindowsNotLocked(boolean forceSend) {
+    public void performComputeChangedWindowsNotLocked(int displayId, boolean forceSend) {
         WindowsForAccessibilityObserver observer = null;
         synchronized (mService) {
-            observer = mWindowsForAccessibilityObserver;
+            final WindowsForAccessibilityObserver windowsForA11yObserver =
+                    mWindowsForAccessibilityObserver.get(displayId);
+            if (windowsForA11yObserver != null) {
+                observer = windowsForA11yObserver;
+            }
         }
         if (observer != null) {
             observer.performComputeChangedWindowsNotLocked(forceSend);
@@ -148,9 +173,10 @@
         if (displayMagnifier != null) {
             displayMagnifier.setMagnificationSpecLocked(spec);
         }
-        // TODO: support multi-display for windows observer
-        if (mWindowsForAccessibilityObserver != null && displayId == Display.DEFAULT_DISPLAY) {
-            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
+        final WindowsForAccessibilityObserver windowsForA11yObserver =
+                mWindowsForAccessibilityObserver.get(displayId);
+        if (windowsForA11yObserver != null) {
+            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
         }
     }
 
@@ -174,9 +200,10 @@
         if (displayMagnifier != null) {
             displayMagnifier.onWindowLayersChangedLocked();
         }
-        // TODO: support multi-display for windows observer
-        if (mWindowsForAccessibilityObserver != null && displayId == Display.DEFAULT_DISPLAY) {
-            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
+        final WindowsForAccessibilityObserver windowsForA11yObserver =
+                mWindowsForAccessibilityObserver.get(displayId);
+        if (windowsForA11yObserver != null) {
+            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
         }
     }
 
@@ -186,9 +213,10 @@
         if (displayMagnifier != null) {
             displayMagnifier.onRotationChangedLocked(displayContent);
         }
-        // TODO: support multi-display for windows observer
-        if (mWindowsForAccessibilityObserver != null && displayId == Display.DEFAULT_DISPLAY) {
-            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
+        final WindowsForAccessibilityObserver windowsForA11yObserver =
+                mWindowsForAccessibilityObserver.get(displayId);
+        if (windowsForA11yObserver != null) {
+            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
         }
     }
 
@@ -207,29 +235,36 @@
         if (displayMagnifier != null) {
             displayMagnifier.onWindowTransitionLocked(windowState, transition);
         }
-        // TODO: support multi-display for windows observer
-        if (mWindowsForAccessibilityObserver != null && displayId == Display.DEFAULT_DISPLAY) {
-            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
+        final WindowsForAccessibilityObserver windowsForA11yObserver =
+                mWindowsForAccessibilityObserver.get(displayId);
+        if (windowsForA11yObserver != null) {
+            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
         }
     }
 
-    public void onWindowFocusChangedNotLocked() {
+    public void onWindowFocusChangedNotLocked(int displayId) {
         // Not relevant for the display magnifier.
 
         WindowsForAccessibilityObserver observer = null;
         synchronized (mService) {
-            observer = mWindowsForAccessibilityObserver;
+            final WindowsForAccessibilityObserver windowsForA11yObserver =
+                    mWindowsForAccessibilityObserver.get(displayId);
+            if (windowsForA11yObserver != null) {
+                observer = windowsForA11yObserver;
+            }
         }
         if (observer != null) {
             observer.performComputeChangedWindowsNotLocked(false);
         }
     }
 
-    public void onSomeWindowResizedOrMovedLocked() {
+    public void onSomeWindowResizedOrMovedLocked(int displayId) {
         // Not relevant for the display magnifier.
 
-        if (mWindowsForAccessibilityObserver != null) {
-            mWindowsForAccessibilityObserver.scheduleComputeChangedWindowsLocked();
+        final WindowsForAccessibilityObserver windowsForA11yObserver =
+                mWindowsForAccessibilityObserver.get(displayId);
+        if (windowsForA11yObserver != null) {
+            windowsForA11yObserver.scheduleComputeChangedWindowsLocked();
         }
     }
 
@@ -265,6 +300,29 @@
         }
     }
 
+    public void handleWindowObserverOfEmbeddedDisplayLocked(int embeddedDisplayId,
+            WindowState parentWindow) {
+        if (embeddedDisplayId == Display.DEFAULT_DISPLAY || parentWindow == null) {
+            return;
+        }
+        // Finds the parent display of this embedded display
+        final int parentDisplayId;
+        WindowState candidate = parentWindow;
+        while (candidate != null) {
+            parentWindow = candidate;
+            candidate = parentWindow.getDisplayContent().getParentWindow();
+        }
+        parentDisplayId = parentWindow.getDisplayId();
+        // Uses the observer of parent display
+        final WindowsForAccessibilityObserver windowsForA11yObserver =
+                mWindowsForAccessibilityObserver.get(parentDisplayId);
+
+        if (windowsForA11yObserver != null) {
+            // Replaces the observer of embedded display to the one of parent display
+            mWindowsForAccessibilityObserver.put(embeddedDisplayId, windowsForA11yObserver);
+        }
+    }
+
     private static void populateTransformationMatrixLocked(WindowState windowState,
             Matrix outMatrix) {
         windowState.getTransformationMatrix(sTempFloats, outMatrix);
@@ -907,7 +965,7 @@
                 }
 
                 public void releaseSurface() {
-                    mSurfaceControl.remove();
+                    mService.mTransactionFactory.make().remove(mSurfaceControl).apply();
                     mSurface.release();
                 }
 
@@ -1036,12 +1094,9 @@
 
         private static final boolean DEBUG = false;
 
-        private final SparseArray<WindowState> mTempWindowStates =
-                new SparseArray<WindowState>();
+        private final SparseArray<WindowState> mTempWindowStates = new SparseArray<>();
 
-        private final List<WindowInfo> mOldWindows = new ArrayList<WindowInfo>();
-
-        private final Set<IBinder> mTempBinderSet = new ArraySet<IBinder>();
+        private final Set<IBinder> mTempBinderSet = new ArraySet<>();
 
         private final RectF mTempRectF = new RectF();
 
@@ -1063,13 +1118,17 @@
 
         private final WindowsForAccessibilityCallback mCallback;
 
+        private final int mDisplayId;
+
         private final long mRecurringAccessibilityEventsIntervalMillis;
 
         public WindowsForAccessibilityObserver(WindowManagerService windowManagerService,
+                int displayId,
                 WindowsForAccessibilityCallback callback) {
             mContext = windowManagerService.mContext;
             mService = windowManagerService;
             mCallback = callback;
+            mDisplayId = displayId;
             mHandler = new MyHandler(mService.mH.getLooper());
             mRecurringAccessibilityEventsIntervalMillis = ViewConfiguration
                     .getSendRecurringAccessibilityEventsInterval();
@@ -1098,21 +1157,23 @@
                 Slog.i(LOG_TAG, "computeChangedWindows()");
             }
 
-            boolean windowsChanged = false;
-            List<WindowInfo> windows = new ArrayList<WindowInfo>();
+            List<WindowInfo> windows = new ArrayList<>();
 
             synchronized (mService.mGlobalLock) {
                 // Do not send the windows if there is no current focus as
                 // the window manager is still looking for where to put it.
                 // We will do the work when we get a focus change callback.
-                // TODO(b/112273690): Support multiple displays
+                // TODO [Multi-Display] : only checks top focused window
                 if (!isCurrentFocusWindowOnDefaultDisplay()) {
                     return;
                 }
 
-                WindowManager windowManager = (WindowManager)
-                        mContext.getSystemService(Context.WINDOW_SERVICE);
-                windowManager.getDefaultDisplay().getRealSize(mTempPoint);
+                final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
+                if (dc == null) {
+                    return;
+                }
+                final Display display = dc.getDisplay();
+                display.getRealSize(mTempPoint);
                 final int screenWidth = mTempPoint.x;
                 final int screenHeight = mTempPoint.y;
 
@@ -1132,14 +1193,13 @@
                 // Iterate until we figure out what is touchable for the entire screen.
                 for (int i = visibleWindowCount - 1; i >= 0; i--) {
                     final WindowState windowState = visibleWindows.valueAt(i);
+                    final Region regionInScreen = new Region();
+                    computeWindowRegionInScreen(windowState, regionInScreen);
 
-                    final Rect boundsInScreen = mTempRect;
-                    computeWindowBoundsInScreen(windowState, boundsInScreen);
-
-                    if (windowMattersToAccessibility(windowState, boundsInScreen, unaccountedSpace,
+                    if (windowMattersToAccessibility(windowState, regionInScreen, unaccountedSpace,
                             skipRemainingWindowsForTasks)) {
-                        addPopulatedWindowInfo(windowState, boundsInScreen, windows, addedWindows);
-                        updateUnaccountedSpace(windowState, boundsInScreen, unaccountedSpace,
+                        addPopulatedWindowInfo(windowState, regionInScreen, windows, addedWindows);
+                        updateUnaccountedSpace(windowState, regionInScreen, unaccountedSpace,
                                 skipRemainingWindowsForTasks);
                         focusedWindowAdded |= windowState.isFocused();
                     }
@@ -1169,53 +1229,17 @@
 
                 visibleWindows.clear();
                 addedWindows.clear();
-
-                if (!forceSend) {
-                    // We computed the windows and if they changed notify the client.
-                    if (mOldWindows.size() != windows.size()) {
-                        // Different size means something changed.
-                        windowsChanged = true;
-                    } else if (!mOldWindows.isEmpty() || !windows.isEmpty()) {
-                        // Since we always traverse windows from high to low layer
-                        // the old and new windows at the same index should be the
-                        // same, otherwise something changed.
-                        for (int i = 0; i < windowCount; i++) {
-                            WindowInfo oldWindow = mOldWindows.get(i);
-                            WindowInfo newWindow = windows.get(i);
-                            // We do not care for layer changes given the window
-                            // order does not change. This brings no new information
-                            // to the clients.
-                            if (windowChangedNoLayer(oldWindow, newWindow)) {
-                                windowsChanged = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-
-                if (forceSend || windowsChanged) {
-                    cacheWindows(windows);
-                }
             }
 
-            // Now we do not hold the lock, so send the windows over.
-            if (forceSend || windowsChanged) {
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "Windows changed or force sending:" + windows);
-                }
-                mCallback.onWindowsForAccessibilityChanged(windows);
-            } else {
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "No windows changed.");
-                }
-            }
+            mCallback.onWindowsForAccessibilityChanged(forceSend, windows);
 
             // Recycle the windows as we do not need them.
             clearAndRecycleWindows(windows);
         }
 
-        private boolean windowMattersToAccessibility(WindowState windowState, Rect boundsInScreen,
-                Region unaccountedSpace, HashSet<Integer> skipRemainingWindowsForTasks) {
+        private boolean windowMattersToAccessibility(WindowState windowState,
+                Region regionInScreen, Region unaccountedSpace,
+                HashSet<Integer> skipRemainingWindowsForTasks) {
             if (windowState.isFocused()) {
                 return true;
             }
@@ -1235,7 +1259,7 @@
             }
 
             // If the window is completely covered by other windows - ignore.
-            if (unaccountedSpace.quickReject(boundsInScreen)) {
+            if (unaccountedSpace.quickReject(regionInScreen)) {
                 return false;
             }
 
@@ -1247,7 +1271,7 @@
             return false;
         }
 
-        private void updateUnaccountedSpace(WindowState windowState, Rect boundsInScreen,
+        private void updateUnaccountedSpace(WindowState windowState, Region regionInScreen,
                 Region unaccountedSpace, HashSet<Integer> skipRemainingWindowsForTasks) {
             if (windowState.mAttrs.type
                     != WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
@@ -1255,122 +1279,76 @@
                 // Account for the space this window takes if the window
                 // is not an accessibility overlay which does not change
                 // the reported windows.
-                unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+                unaccountedSpace.op(regionInScreen, unaccountedSpace,
                         Region.Op.REVERSE_DIFFERENCE);
 
                 // If a window is modal it prevents other windows from being touched
                 if ((windowState.mAttrs.flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                         | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)) == 0) {
-                    // Account for all space in the task, whether the windows in it are
-                    // touchable or not. The modal window blocks all touches from the task's
-                    // area.
-                    unaccountedSpace.op(windowState.getDisplayFrameLw(), unaccountedSpace,
-                            Region.Op.REVERSE_DIFFERENCE);
+                    if (!windowState.hasTapExcludeRegion()) {
+                        // Account for all space in the task, whether the windows in it are
+                        // touchable or not. The modal window blocks all touches from the task's
+                        // area.
+                        unaccountedSpace.op(windowState.getDisplayFrameLw(), unaccountedSpace,
+                                Region.Op.REVERSE_DIFFERENCE);
+                    } else {
+                        // If a window has tap exclude region, we need to account it.
+                        final Region displayRegion = new Region(windowState.getDisplayFrameLw());
+                        final Region tapExcludeRegion = new Region();
+                        windowState.amendTapExcludeRegion(tapExcludeRegion);
+                        displayRegion.op(tapExcludeRegion, displayRegion,
+                                Region.Op.REVERSE_DIFFERENCE);
+                        unaccountedSpace.op(displayRegion, unaccountedSpace,
+                                Region.Op.REVERSE_DIFFERENCE);
+                    }
 
                     final Task task = windowState.getTask();
                     if (task != null) {
                         // If the window is associated with a particular task, we can skip the
                         // rest of the windows for that task.
                         skipRemainingWindowsForTasks.add(task.mTaskId);
-                    } else {
+                    } else if (!windowState.hasTapExcludeRegion()) {
                         // If the window is not associated with a particular task, then it is
-                        // globally modal. In this case we can skip all remaining windows.
+                        // globally modal. In this case we can skip all remaining windows when
+                        // it doesn't has tap exclude region.
                         unaccountedSpace.setEmpty();
                     }
                 }
             }
         }
 
-        private void computeWindowBoundsInScreen(WindowState windowState, Rect outBounds) {
+        private void computeWindowRegionInScreen(WindowState windowState, Region outRegion) {
             // Get the touchable frame.
             Region touchableRegion = mTempRegion1;
             windowState.getTouchableRegion(touchableRegion);
-            Rect touchableFrame = mTempRect;
-            touchableRegion.getBounds(touchableFrame);
-
-            // Move to origin as all transforms are captured by the matrix.
-            RectF windowFrame = mTempRectF;
-            windowFrame.set(touchableFrame);
-            windowFrame.offset(-windowState.getFrameLw().left, -windowState.getFrameLw().top);
 
             // Map the frame to get what appears on the screen.
             Matrix matrix = mTempMatrix;
             populateTransformationMatrixLocked(windowState, matrix);
-            matrix.mapRect(windowFrame);
 
-            // Got the bounds.
-            outBounds.set((int) windowFrame.left, (int) windowFrame.top,
-                    (int) windowFrame.right, (int) windowFrame.bottom);
+            forEachRect(touchableRegion, rect -> {
+                // Move to origin as all transforms are captured by the matrix.
+                RectF windowFrame = mTempRectF;
+                windowFrame.set(rect);
+                windowFrame.offset(-windowState.getFrameLw().left, -windowState.getFrameLw().top);
+
+                matrix.mapRect(windowFrame);
+
+                // Union all rects.
+                outRegion.union(new Rect((int) windowFrame.left, (int) windowFrame.top,
+                        (int) windowFrame.right, (int) windowFrame.bottom));
+            });
         }
 
-        private static void addPopulatedWindowInfo(
-                WindowState windowState, Rect boundsInScreen,
+        private static void addPopulatedWindowInfo(WindowState windowState, Region regionInScreen,
                 List<WindowInfo> out, Set<IBinder> tokenOut) {
             final WindowInfo window = windowState.getWindowInfo();
-            window.boundsInScreen.set(boundsInScreen);
+            window.regionInScreen.set(regionInScreen);
             window.layer = tokenOut.size();
             out.add(window);
             tokenOut.add(window.token);
         }
 
-        private void cacheWindows(List<WindowInfo> windows) {
-            final int oldWindowCount = mOldWindows.size();
-            for (int i = oldWindowCount - 1; i >= 0; i--) {
-                mOldWindows.remove(i).recycle();
-            }
-            final int newWindowCount = windows.size();
-            for (int i = 0; i < newWindowCount; i++) {
-                WindowInfo newWindow = windows.get(i);
-                mOldWindows.add(WindowInfo.obtain(newWindow));
-            }
-        }
-
-        private boolean windowChangedNoLayer(WindowInfo oldWindow, WindowInfo newWindow) {
-            if (oldWindow == newWindow) {
-                return false;
-            }
-            if (oldWindow == null) {
-                return true;
-            }
-            if (newWindow == null) {
-                return true;
-            }
-            if (oldWindow.type != newWindow.type) {
-                return true;
-            }
-            if (oldWindow.focused != newWindow.focused) {
-                return true;
-            }
-            if (oldWindow.token == null) {
-                if (newWindow.token != null) {
-                    return true;
-                }
-            } else if (!oldWindow.token.equals(newWindow.token)) {
-                return true;
-            }
-            if (oldWindow.parentToken == null) {
-                if (newWindow.parentToken != null) {
-                    return true;
-                }
-            } else if (!oldWindow.parentToken.equals(newWindow.parentToken)) {
-                return true;
-            }
-            if (!oldWindow.boundsInScreen.equals(newWindow.boundsInScreen)) {
-                return true;
-            }
-            if (oldWindow.childTokens != null && newWindow.childTokens != null
-                    && !oldWindow.childTokens.equals(newWindow.childTokens)) {
-                return true;
-            }
-            if (!TextUtils.equals(oldWindow.title, newWindow.title)) {
-                return true;
-            }
-            if (oldWindow.accessibilityIdOfAnchor != newWindow.accessibilityIdOfAnchor) {
-                return true;
-            }
-            return false;
-        }
-
         private static void clearAndRecycleWindows(List<WindowInfo> windows) {
             final int windowCount = windows.size();
             for (int i = windowCount - 1; i >= 0; i--) {
@@ -1393,8 +1371,12 @@
 
         private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
             final List<WindowState> tempWindowStatesList = new ArrayList<>();
-            final DisplayContent dc = mService.getDefaultDisplayContentLocked();
-            dc.forAllWindows((w) -> {
+            final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
+            if (dc == null) {
+                return;
+            }
+
+            dc.forAllWindows(w -> {
                 if (w.isVisibleLw()) {
                     tempWindowStatesList.add(w);
                 }
@@ -1407,17 +1389,10 @@
                     return;
                 }
 
-                // TODO: Use Region instead to get rid of this complicated logic.
-                // Check the tap exclude region of the parent window. If the tap exclude region
-                // is empty, it means there is another can-receive-pointer-event view on top of
-                // the region. Hence, we don't count the window as visible.
-                if (w.isVisibleLw() && parentWindow.getDisplayContent().isDefaultDisplay
-                        && parentWindow.hasTapExcludeRegion()
-                        && tempWindowStatesList.contains(parentWindow)) {
-                    tempWindowStatesList.add(
-                            tempWindowStatesList.lastIndexOf(parentWindow) + 1, w);
+                if (w.isVisibleLw() && tempWindowStatesList.contains(parentWindow)) {
+                    tempWindowStatesList.add(tempWindowStatesList.lastIndexOf(parentWindow), w);
                 }
-            }, true /* traverseTopToBottom */);
+            }, false /* traverseTopToBottom */);
             for (int i = 0; i < tempWindowStatesList.size(); i++) {
                 outWindows.put(i, tempWindowStatesList.get(i));
             }
@@ -1435,7 +1410,7 @@
             }
             return displayParentWindow;
         }
-
+        // TODO [Multi-Display] : only checks top focused window
         private boolean isCurrentFocusWindowOnDefaultDisplay() {
             final WindowState focusedWindow =
                     mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus;
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index 637ad03..f1cd721 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -29,6 +29,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.os.Build.VERSION_CODES.N;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
@@ -55,18 +56,24 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
 import android.app.WindowConfiguration;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.os.IBinder;
+import android.os.Message;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.IntArray;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.am.EventLogTags;
 
 import java.io.PrintWriter;
@@ -156,6 +163,9 @@
     // Used in updating the display size
     private Point mTmpDisplaySize = new Point();
 
+    // Used in updating override configurations
+    private final Configuration mTempConfig = new Configuration();
+
     private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
 
     ActivityDisplay(RootActivityContainer root, Display display) {
@@ -164,6 +174,7 @@
         mDisplayId = display.getDisplayId();
         mDisplay = display;
         mDisplayContent = createDisplayContent();
+        mDisplayContent.reconfigureDisplayLocked();
         updateBounds();
     }
 
@@ -999,6 +1010,89 @@
         return mStacks.indexOf(stack);
     }
 
+    boolean updateDisplayOverrideConfigurationLocked() {
+        Configuration values = new Configuration();
+        mDisplayContent.computeScreenConfiguration(values);
+
+        if (mService.mWindowManager != null) {
+            final Message msg = PooledLambda.obtainMessage(
+                    ActivityManagerInternal::updateOomLevelsForDisplay, mService.mAmInternal,
+                    mDisplayId);
+            mService.mH.sendMessage(msg);
+        }
+
+        Settings.System.clearConfiguration(values);
+        updateDisplayOverrideConfigurationLocked(values, null /* starting */,
+                false /* deferResume */, mService.mTmpUpdateConfigurationResult);
+        return mService.mTmpUpdateConfigurationResult.changes != 0;
+    }
+
+    /**
+     * Updates override configuration specific for the selected display. If no config is provided,
+     * new one will be computed in WM based on current display info.
+     */
+    boolean updateDisplayOverrideConfigurationLocked(Configuration values,
+            ActivityRecord starting, boolean deferResume,
+            ActivityTaskManagerService.UpdateConfigurationResult result) {
+
+        int changes = 0;
+        boolean kept = true;
+
+        if (mService.mWindowManager != null) {
+            mService.mWindowManager.deferSurfaceLayout();
+        }
+        try {
+            if (values != null) {
+                if (mDisplayId == DEFAULT_DISPLAY) {
+                    // Override configuration of the default display duplicates global config, so
+                    // we're calling global config update instead for default display. It will also
+                    // apply the correct override config.
+                    changes = mService.updateGlobalConfigurationLocked(values,
+                            false /* initLocale */, false /* persistent */,
+                            UserHandle.USER_NULL /* userId */, deferResume);
+                } else {
+                    changes = performDisplayOverrideConfigUpdate(values, deferResume);
+                }
+            }
+
+            kept = mService.ensureConfigAndVisibilityAfterUpdate(starting, changes);
+        } finally {
+            if (mService.mWindowManager != null) {
+                mService.mWindowManager.continueSurfaceLayout();
+            }
+        }
+
+        if (result != null) {
+            result.changes = changes;
+            result.activityRelaunched = !kept;
+        }
+        return kept;
+    }
+
+    int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume) {
+        mTempConfig.setTo(getRequestedOverrideConfiguration());
+        final int changes = mTempConfig.updateFrom(values);
+        if (changes != 0) {
+            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
+                    + mTempConfig + " for displayId=" + mDisplayId);
+            onRequestedOverrideConfigurationChanged(mTempConfig);
+
+            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
+            if (isDensityChange && mDisplayId == DEFAULT_DISPLAY) {
+                mService.mAppWarnings.onDensityChanged();
+
+                // Post message to start process to avoid possible deadlock of calling into AMS with
+                // the ATMS lock held.
+                final Message msg = PooledLambda.obtainMessage(
+                        ActivityManagerInternal::killAllBackgroundProcessesExcept,
+                        mService.mAmInternal, N,
+                        ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
+                mService.mH.sendMessage(msg);
+            }
+        }
+        return changes;
+    }
+
     @Override
     public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
         final int currRotation =
@@ -1136,7 +1230,7 @@
                 final ActivityStack stack = mStacks.get(stackNdx);
                 // Always finish non-standard type stacks.
                 if (destroyContentOnRemoval || !stack.isActivityTypeStandardOrUndefined()) {
-                    stack.finishAllActivitiesLocked(true /* immediately */);
+                    stack.finishAllActivitiesImmediately();
                 } else {
                     // If default display is in split-window mode, set windowing mode of the stack
                     // to split-screen secondary. Otherwise, set the windowing mode to undefined by
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index feef5e2..a0a2967 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -225,7 +225,7 @@
 
         private WindowingModeTransitionInfoSnapshot(WindowingModeTransitionInfo info,
                 ActivityRecord launchedActivity, int windowsFullyDrawnDelayMs) {
-            applicationInfo = launchedActivity.appInfo;
+            applicationInfo = launchedActivity.info.applicationInfo;
             packageName = launchedActivity.packageName;
             launchedActivityName = launchedActivity.info.name;
             launchedActivityLaunchedFromPackage = launchedActivity.launchedFromPackage;
@@ -544,14 +544,30 @@
 
             // If we have an active transition that's waiting on a certain activity that will be
             // invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
-            if (info != null && !hasVisibleNonFinishingActivity(t)) {
-                if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
-                        + " activity=" + r);
-                logAppTransitionCancel(info);
-                mWindowingModeTransitionInfo.remove(r.getWindowingMode());
-                if (mWindowingModeTransitionInfo.size() == 0) {
-                    reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
-                }
+
+            // We have no active transitions.
+            if (info == null) {
+                return;
+            }
+
+            // The notified activity whose visibility changed is no longer the launched activity.
+            // We can still wait to get onWindowsDrawn.
+            if (info.launchedActivity != r) {
+                return;
+            }
+
+            // Check if there is any activity in the task that is visible and not finishing. If the
+            // launched activity finished before it is drawn and if there is another activity in
+            // the task then that activity will be draw on screen.
+            if (hasVisibleNonFinishingActivity(t)) {
+                return;
+            }
+
+            if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible activity=" + r);
+            logAppTransitionCancel(info);
+            mWindowingModeTransitionInfo.remove(r.getWindowingMode());
+            if (mWindowingModeTransitionInfo.size() == 0) {
+                reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
             }
         }
     }
@@ -566,7 +582,7 @@
             final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(i);
 
             // App isn't attached to record yet, so match with info.
-            if (info.launchedActivity.appInfo == appInfo) {
+            if (info.launchedActivity.info.applicationInfo == appInfo) {
                 info.bindApplicationDelayMs = calculateCurrentDelay();
             }
         }
@@ -633,13 +649,13 @@
         mMetricsLogger.write(builder);
         StatsLog.write(
                 StatsLog.APP_START_CANCELED,
-                info.launchedActivity.appInfo.uid,
+                info.launchedActivity.info.applicationInfo.uid,
                 info.launchedActivity.packageName,
                 convertAppStartTransitionType(type),
                 info.launchedActivity.info.name);
         if (DEBUG_METRICS) {
             Slog.i(TAG, String.format("APP_START_CANCELED(%s, %s, %s, %s)",
-                    info.launchedActivity.appInfo.uid,
+                    info.launchedActivity.info.applicationInfo.uid,
                     info.launchedActivity.packageName,
                     convertAppStartTransitionType(type),
                     info.launchedActivity.info.name));
@@ -805,7 +821,7 @@
         mMetricsLogger.write(builder);
         StatsLog.write(
                 StatsLog.APP_START_FULLY_DRAWN,
-                info.launchedActivity.appInfo.uid,
+                info.launchedActivity.info.applicationInfo.uid,
                 info.launchedActivity.packageName,
                 restoredFromBundle
                         ? StatsLog.APP_START_FULLY_DRAWN__TYPE__WITH_BUNDLE
@@ -945,7 +961,7 @@
     private WindowProcessController findProcessForActivity(ActivityRecord launchedActivity) {
         return launchedActivity != null
                 ? mSupervisor.mService.mProcessNames.get(
-                        launchedActivity.processName, launchedActivity.appInfo.uid)
+                        launchedActivity.processName, launchedActivity.info.applicationInfo.uid)
                 : null;
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 1344727..26b1f7b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -92,6 +92,8 @@
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
+import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
 
 import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
 import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
@@ -103,11 +105,13 @@
 import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
 import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.wm.ActivityStack.ActivityState.FINISHING;
 import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
 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.RESTARTING_PROCESS;
 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.wm.ActivityStack.ActivityState.STARTED;
 import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.wm.ActivityStack.LAUNCH_TICK;
@@ -115,18 +119,29 @@
 import static com.android.server.wm.ActivityStack.PAUSE_TIMEOUT_MSG;
 import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
 import static com.android.server.wm.ActivityStack.STOP_TIMEOUT_MSG;
+import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONTAINERS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONTAINERS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TRANSITION;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -150,6 +165,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.Activity;
 import android.app.ActivityManager.TaskDescription;
 import android.app.ActivityOptions;
 import android.app.PendingIntent;
@@ -193,6 +209,7 @@
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.service.voice.IVoiceInteractionSession;
+import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.MergedConfiguration;
@@ -214,11 +231,14 @@
 import com.android.server.AttributeCache;
 import com.android.server.AttributeCache.Entry;
 import com.android.server.am.AppTimeTracker;
+import com.android.server.am.EventLogTags;
 import com.android.server.am.PendingIntentRecord;
 import com.android.server.uri.UriPermissionOwner;
 import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
 import com.android.server.wm.ActivityStack.ActivityState;
 
+import com.google.android.collect.Sets;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -239,15 +259,16 @@
 final class ActivityRecord extends ConfigurationContainer {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
+    private static final String TAG_CONTAINERS = TAG + POSTFIX_CONTAINERS;
+    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
+    private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
+    private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
     private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
     private static final String TAG_STATES = TAG + POSTFIX_STATES;
     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
+    private static final String TAG_TRANSITION = TAG + POSTFIX_TRANSITION;
+    private static final String TAG_USER_LEAVING = TAG + POSTFIX_USER_LEAVING;
     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
-    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
-    // TODO(b/67864419): Remove once recents component is overridden
-    private static final String LEGACY_RECENTS_PACKAGE_NAME = "com.android.systemui.recents";
-
-    private static final boolean SHOW_ACTIVITY_START_TIME = true;
 
     private static final String ATTR_ID = "id";
     private static final String TAG_INTENT = "intent";
@@ -264,9 +285,7 @@
     // TODO: Remove after unification
     AppWindowToken mAppWindowToken;
 
-    final ActivityInfo info; // all about me
-    // TODO: This is duplicated state already contained in info.applicationInfo - remove
-    ApplicationInfo appInfo; // information about activity's app
+    final ActivityInfo info; // activity info provided by developer in AndroidManifest
     final int launchedFromPid; // always the pid who started the activity.
     final int launchedFromUid; // always the uid who started the activity.
     final String launchedFromPackage; // always the package who started the activity.
@@ -322,12 +341,15 @@
     UriPermissionOwner uriPermissions; // current special URI access perms.
     WindowProcessController app;      // if non-null, hosting application
     private ActivityState mState;    // current state we are in
-    Bundle  icicle;         // last saved activity state
-    PersistableBundle persistentState; // last persistently saved activity state
-    // TODO: See if this is still needed.
-    boolean frontOfTask;    // is this the root activity of its task?
+    private Bundle mIcicle;         // last saved activity state
+    private PersistableBundle mPersistentState; // last persistently saved activity state
+    private boolean mHaveState = true; // Indicates whether the last saved state of activity is
+                                       // preserved. This starts out 'true', since the initial state
+                                       // of an activity is that we have everything, and we should
+                                       // never consider it lacking in state to be removed if it
+                                       // dies. After an activity is launched it follows the value
+                                       // of #mIcicle.
     boolean launchFailed;   // set if a launched failed, to abort on 2nd try
-    boolean haveState;      // have we gotten the last activity state?
     boolean stopped;        // is activity pause finished?
     boolean delayedResume;  // not yet resumed because of stopped app switches?
     boolean finishing;      // activity in pending finish list?
@@ -444,12 +466,13 @@
                 pw.print(" userId="); pw.println(mUserId);
         pw.print(prefix); pw.print("app="); pw.println(app);
         pw.print(prefix); pw.println(intent.toInsecureStringWithClip());
-        pw.print(prefix); pw.print("frontOfTask="); pw.print(frontOfTask);
+        pw.print(prefix); pw.print("rootOfTask="); pw.print(isRootOfTask());
                 pw.print(" task="); pw.println(task);
         pw.print(prefix); pw.print("taskAffinity="); pw.println(taskAffinity);
         pw.print(prefix); pw.print("mActivityComponent=");
                 pw.println(mActivityComponent.flattenToShortString());
-        if (appInfo != null) {
+        if (info != null && info.applicationInfo != null) {
+            final ApplicationInfo appInfo = info.applicationInfo;
             pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
             if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
                 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
@@ -556,8 +579,8 @@
                 if (lastLaunchTime == 0) pw.print("0");
                 else TimeUtils.formatDuration(lastLaunchTime, now, pw);
                 pw.println();
-        pw.print(prefix); pw.print("haveState="); pw.print(haveState);
-                pw.print(" icicle="); pw.println(icicle);
+        pw.print(prefix); pw.print("mHaveState="); pw.print(mHaveState);
+                pw.print(" mIcicle="); pw.println(mIcicle);
         pw.print(prefix); pw.print("state="); pw.print(mState);
                 pw.print(" stopped="); pw.print(stopped);
                 pw.print(" delayedResume="); pw.print(delayedResume);
@@ -618,8 +641,35 @@
         }
     }
 
+    /** Update the saved state of an activity. */
+    void setSavedState(@Nullable Bundle savedState) {
+        mIcicle = savedState;
+        mHaveState = mIcicle != null;
+    }
+
+    /**
+     * Get the actual Bundle instance of the saved state.
+     * @see #hasSavedState() for checking if the record has saved state.
+     */
+    @Nullable Bundle getSavedState() {
+        return mIcicle;
+    }
+
+    /**
+     * Check if the activity has saved state.
+     * @return {@code true} if the client reported a non-empty saved state from last onStop(), or
+     *         if this record was just created and the client is yet to be launched and resumed.
+     */
+    boolean hasSavedState() {
+        return mHaveState;
+    }
+
+    /** @return The actual PersistableBundle instance of the saved persistent state. */
+    @Nullable PersistableBundle getPersistentSavedState() {
+        return mPersistentState;
+    }
+
     void updateApplicationInfo(ApplicationInfo aInfo) {
-        appInfo = aInfo;
         info.applicationInfo = aInfo;
     }
 
@@ -921,8 +971,9 @@
         return ResolverActivity.class.getName().equals(className);
     }
 
-    boolean isResolverActivity() {
-        return isResolverActivity(mActivityComponent.getClassName());
+    boolean isResolverOrDelegateActivity() {
+        return isResolverActivity(mActivityComponent.getClassName()) || Objects.equals(
+                mActivityComponent, mAtmService.mStackSupervisor.getSystemChooserActivity());
     }
 
     boolean isResolverOrChildActivity() {
@@ -961,7 +1012,6 @@
         resultWho = _resultWho;
         requestCode = _reqCode;
         setState(INITIALIZING, "ActivityRecord ctor");
-        frontOfTask = false;
         launchFailed = false;
         stopped = false;
         delayedResume = false;
@@ -976,10 +1026,6 @@
         hasBeenLaunched = false;
         mStackSupervisor = supervisor;
 
-        // This starts out true, since the initial state of an activity is that we have everything,
-        // and we shouldn't never consider it lacking in state to be removed if it dies.
-        haveState = true;
-
         // If the class name in the intent doesn't match that of the target, this is
         // probably an alias. We have to create a new ComponentName object to keep track
         // of the real activity name, so that FLAG_ACTIVITY_CLEAR_TOP is handled properly.
@@ -993,7 +1039,6 @@
         }
         taskAffinity = aInfo.taskAffinity;
         stateNotNeeded = (aInfo.flags & FLAG_STATE_NOT_NEEDED) != 0;
-        appInfo = aInfo.applicationInfo;
         nonLocalizedLabel = aInfo.nonLocalizedLabel;
         labelRes = aInfo.labelRes;
         if (nonLocalizedLabel == null && labelRes == 0) {
@@ -1052,7 +1097,8 @@
 
         mRotationAnimationHint = aInfo.rotationAnimation;
         lockTaskLaunchMode = aInfo.lockTaskLaunchMode;
-        if (appInfo.isPrivilegedApp() && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
+        if (info.applicationInfo.isPrivilegedApp()
+                && (lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_ALWAYS
                 || lockTaskLaunchMode == LOCK_TASK_LAUNCH_MODE_NEVER)) {
             lockTaskLaunchMode = LOCK_TASK_LAUNCH_MODE_DEFAULT;
         }
@@ -1122,7 +1168,8 @@
                     task.voiceSession != null, container.getDisplayContent(),
                     ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this)
                             * 1000000L, fullscreen,
-                    (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, appInfo.targetSdkVersion,
+                    (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0,
+                    info.applicationInfo.targetSdkVersion,
                     info.screenOrientation, mRotationAnimationHint,
                     mLaunchTaskBehind, isAlwaysFocusable());
             if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) {
@@ -1251,7 +1298,8 @@
                 && intent.getType() == null;
     }
 
-    private boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
+    @VisibleForTesting
+    boolean canLaunchHomeActivity(int uid, ActivityRecord sourceRecord) {
         if (uid == Process.myUid() || uid == 0) {
             // System process can launch home activity.
             return true;
@@ -1261,8 +1309,8 @@
         if (recentTasks != null && recentTasks.isCallerRecents(uid)) {
             return true;
         }
-        // Resolver activity can launch home activity.
-        return sourceRecord != null && sourceRecord.isResolverActivity();
+        // Resolver or system chooser activity can launch home activity.
+        return sourceRecord != null && sourceRecord.isResolverOrDelegateActivity();
     }
 
     /**
@@ -1281,7 +1329,7 @@
             ActivityOptions options, ActivityRecord sourceRecord) {
         int activityType = ACTIVITY_TYPE_UNDEFINED;
         if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
-                && isHomeIntent(intent) && !isResolverActivity()) {
+                && isHomeIntent(intent) && !isResolverOrDelegateActivity()) {
             // This sure looks like a home activity!
             activityType = ACTIVITY_TYPE_HOME;
 
@@ -1290,8 +1338,8 @@
                 // We only allow home activities to be resizeable if they explicitly requested it.
                 info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
             }
-        } else if (mActivityComponent.getClassName().contains(LEGACY_RECENTS_PACKAGE_NAME)
-                || mAtmService.getRecentTasks().isRecentsComponent(mActivityComponent, appInfo.uid)) {
+        } else if (mAtmService.getRecentTasks().isRecentsComponent(mActivityComponent,
+                info.applicationInfo.uid)) {
             activityType = ACTIVITY_TYPE_RECENTS;
         } else if (options != null && options.getLaunchActivityType() == ACTIVITY_TYPE_ASSISTANT
                 && canLaunchAssistActivity(launchedFromPackage)) {
@@ -1489,7 +1537,7 @@
      */
     private boolean checkEnterPictureInPictureAppOpsState() {
         return mAtmService.getAppOpsService().checkOperation(
-                OP_PICTURE_IN_PICTURE, appInfo.uid, packageName) == MODE_ALLOWED;
+                OP_PICTURE_IN_PICTURE, info.applicationInfo.uid, packageName) == MODE_ALLOWED;
     }
 
     boolean isAlwaysFocusable() {
@@ -1527,12 +1575,283 @@
         stack.moveToFront(reason, task);
         // Report top activity change to tracking services and WM
         if (mRootActivityContainer.getTopResumedActivity() == this) {
-            // TODO(b/111361570): Support multiple focused apps in WM
             mAtmService.setResumedActivityUncheckLocked(this, reason);
         }
         return true;
     }
 
+    /** Finish all activities in the task with the same affinity as this one. */
+    void finishActivityAffinity() {
+        final ArrayList<ActivityRecord> activities = getTaskRecord().mActivities;
+        for (int index = activities.indexOf(this); index >= 0; --index) {
+            final ActivityRecord cur = activities.get(index);
+            if (!Objects.equals(cur.taskAffinity, taskAffinity)) {
+                break;
+            }
+            cur.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+                    "request-affinity", true /* oomAdj */);
+        }
+    }
+
+    /**
+     * Sets the result for activity that started this one, clears the references to activities
+     * started for result from this one, and clears new intents.
+     */
+    void finishActivityResults(int resultCode, Intent resultData) {
+        // Send the result if needed
+        if (resultTo != null) {
+            if (DEBUG_RESULTS) {
+                Slog.v(TAG_RESULTS, "Adding result to " + resultTo
+                        + " who=" + resultWho + " req=" + requestCode
+                        + " res=" + resultCode + " data=" + resultData);
+            }
+            if (resultTo.mUserId != mUserId) {
+                if (resultData != null) {
+                    resultData.prepareToLeaveUser(mUserId);
+                }
+            }
+            if (info.applicationInfo.uid > 0) {
+                mAtmService.mUgmInternal.grantUriPermissionFromIntent(info.applicationInfo.uid,
+                        resultTo.packageName, resultData,
+                        resultTo.getUriPermissionsLocked(), resultTo.mUserId);
+            }
+            resultTo.addResultLocked(this, resultWho, requestCode, resultCode, resultData);
+            resultTo = null;
+        } else if (DEBUG_RESULTS) {
+            Slog.v(TAG_RESULTS, "No result destination from " + this);
+        }
+
+        // Make sure this HistoryRecord is not holding on to other resources,
+        // because clients have remote IPC references to this object so we
+        // can't assume that will go away and want to avoid circular IPC refs.
+        results = null;
+        pendingResults = null;
+        newIntents = null;
+        setSavedState(null /* savedState */);
+    }
+
+    /**
+     * See {@link #finishActivityLocked(int, Intent, String, boolean, boolean)}
+     */
+    boolean finishActivityLocked(int resultCode, Intent resultData, String reason, boolean oomAdj) {
+        return finishActivityLocked(resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
+    }
+
+    /**
+     * @return Returns true if this activity has been removed from the history
+     * list, or false if it is still in the list and will be removed later.
+     */
+    boolean finishActivityLocked(int resultCode, Intent resultData, String reason, boolean oomAdj,
+            boolean pauseImmediately) {
+        if (finishing) {
+            Slog.w(TAG, "Duplicate finish request for " + this);
+            return false;
+        }
+
+        mAtmService.mWindowManager.deferSurfaceLayout();
+        try {
+            makeFinishingLocked();
+            final TaskRecord task = getTaskRecord();
+            EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
+                    mUserId, System.identityHashCode(this),
+                    task.taskId, shortComponentName, reason);
+            final ArrayList<ActivityRecord> activities = task.mActivities;
+            final int index = activities.indexOf(this);
+            if (index < (activities.size() - 1)) {
+                if ((intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+                    // If the caller asked that this activity (and all above it)
+                    // be cleared when the task is reset, don't lose that information,
+                    // but propagate it up to the next activity.
+                    final ActivityRecord next = activities.get(index + 1);
+                    next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+                }
+            }
+
+            pauseKeyDispatchingLocked();
+
+            final ActivityStack stack = getActivityStack();
+            stack.adjustFocusedActivityStack(this, "finishActivity");
+
+            finishActivityResults(resultCode, resultData);
+
+            final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
+            final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
+            if (stack.getResumedActivity() == this) {
+                if (DEBUG_VISIBILITY || DEBUG_TRANSITION) {
+                    Slog.v(TAG_TRANSITION, "Prepare close transition: finishing " + this);
+                }
+                if (endTask) {
+                    mAtmService.getTaskChangeNotificationController().notifyTaskRemovalStarted(
+                            task.getTaskInfo());
+                }
+                getDisplay().mDisplayContent.prepareAppTransition(transit, false);
+
+                // When finishing the activity preemptively take the snapshot before the app window
+                // is marked as hidden and any configuration changes take place
+                if (mAtmService.mWindowManager.mTaskSnapshotController != null) {
+                    final ArraySet<Task> tasks = Sets.newArraySet(task.mTask);
+                    mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks);
+                    mAtmService.mWindowManager.mTaskSnapshotController
+                            .addSkipClosingAppSnapshotTasks(tasks);
+                }
+
+                // Tell window manager to prepare for this one to be removed.
+                setVisibility(false);
+
+                if (stack.mPausingActivity == null) {
+                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + this);
+                    if (DEBUG_USER_LEAVING) {
+                        Slog.v(TAG_USER_LEAVING, "finish() => pause with userLeaving=false");
+                    }
+                    stack.startPausingLocked(false, false, null, pauseImmediately);
+                }
+
+                if (endTask) {
+                    mAtmService.getLockTaskController().clearLockedTask(task);
+                }
+            } else if (!isState(PAUSING)) {
+                // If the activity is PAUSING, we will complete the finish once
+                // it is done pausing; else we can just directly finish it here.
+                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + this);
+                if (visible) {
+                    prepareActivityHideTransitionAnimation(transit);
+                }
+
+                final int finishMode = (visible || nowVisible) ? FINISH_AFTER_VISIBLE
+                        : FINISH_AFTER_PAUSE;
+                final boolean removedActivity = finishCurrentActivityLocked(finishMode, oomAdj,
+                        "finishActivityLocked") == null;
+
+                // The following code is an optimization. When the last non-task overlay activity
+                // is removed from the task, we remove the entire task from the stack. However,
+                // since that is done after the scheduled destroy callback from the activity, that
+                // call to change the visibility of the task overlay activities would be out of
+                // sync with the activity visibility being set for this finishing activity above.
+                // In this case, we can set the visibility of all the task overlay activities when
+                // we detect the last one is finishing to keep them in sync.
+                if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
+                    for (ActivityRecord taskOverlay : task.mActivities) {
+                        if (!taskOverlay.mTaskOverlay) {
+                            continue;
+                        }
+                        taskOverlay.prepareActivityHideTransitionAnimation(transit);
+                    }
+                }
+                return removedActivity;
+            } else {
+                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + this);
+            }
+
+            return false;
+        } finally {
+            mAtmService.mWindowManager.continueSurfaceLayout();
+        }
+    }
+
+    private void prepareActivityHideTransitionAnimation(int transit) {
+        final DisplayContent dc = getDisplay().mDisplayContent;
+        dc.prepareAppTransition(transit, false);
+        setVisibility(false);
+        dc.executeAppTransition();
+    }
+
+    static final int FINISH_IMMEDIATELY = 0;
+    private static final int FINISH_AFTER_PAUSE = 1;
+    static final int FINISH_AFTER_VISIBLE = 2;
+
+    ActivityRecord finishCurrentActivityLocked(int mode, boolean oomAdj, String reason) {
+        // First things first: if this activity is currently visible,
+        // and the resumed activity is not yet visible, then hold off on
+        // finishing until the resumed one becomes visible.
+
+        // The activity that we are finishing may be over the lock screen. In this case, we do not
+        // want to consider activities that cannot be shown on the lock screen as running and should
+        // proceed with finishing the activity if there is no valid next top running activity.
+        // Note that if this finishing activity is floating task, we don't need to wait the
+        // next activity resume and can destroy it directly.
+        final ActivityStack stack = getActivityStack();
+        final ActivityDisplay display = getDisplay();
+        final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
+        final boolean isFloating = getConfiguration().windowConfiguration.tasksAreFloating();
+
+        if (mode == FINISH_AFTER_VISIBLE && (visible || nowVisible)
+                && next != null && !next.nowVisible && !isFloating) {
+            if (!mStackSupervisor.mStoppingActivities.contains(this)) {
+                stack.addToStopping(this, false /* scheduleIdle */, false /* idleDelayed */,
+                        "finishCurrentActivityLocked");
+            }
+            if (DEBUG_STATES) {
+                Slog.v(TAG_STATES, "Moving to STOPPING: " + this + " (finish requested)");
+            }
+            setState(STOPPING, "finishCurrentActivityLocked");
+            if (oomAdj) {
+                mAtmService.updateOomAdj();
+            }
+            return this;
+        }
+
+        // make sure the record is cleaned out of other places.
+        mStackSupervisor.mStoppingActivities.remove(this);
+        mStackSupervisor.mGoingToSleepActivities.remove(this);
+        final ActivityState prevState = getState();
+        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + this);
+
+        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 = stack != display.getFocusedStack();
+        final boolean finishingInNonFocusedStackOrNoRunning = mode == FINISH_AFTER_VISIBLE
+                && prevState == PAUSED && (noFocusedStack || noRunningStack);
+
+        if (mode == FINISH_IMMEDIATELY
+                || (prevState == PAUSED && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
+                || finishingInNonFocusedStackOrNoRunning
+                || prevState == STARTED
+                || prevState == STOPPING
+                || prevState == STOPPED
+                || prevState == ActivityState.INITIALIZING) {
+            makeFinishingLocked();
+            boolean activityRemoved = stack.destroyActivityLocked(this, true /* removeFromApp */,
+                    "finish-imm:" + reason);
+
+            if (finishingInNonFocusedStackOrNoRunning) {
+                // Finishing activity that was in paused state and it was in not currently focused
+                // stack, need to make something visible in its place. Also if the display does not
+                // have running activity, the configuration may need to be updated for restoring
+                // original orientation of the display.
+                mRootActivityContainer.ensureVisibilityAndConfig(next, getDisplayId(),
+                        false /* markFrozenIfConfigChanged */, true /* deferResume */);
+            }
+            if (activityRemoved) {
+                mRootActivityContainer.resumeFocusedStacksTopActivities();
+            }
+            if (DEBUG_CONTAINERS) {
+                Slog.d(TAG_CONTAINERS, "destroyActivityLocked: finishCurrentActivityLocked r="
+                        + this + " destroy returned removed=" + activityRemoved);
+            }
+            return activityRemoved ? null : this;
+        }
+
+        // Need to go through the full pause cycle to get this
+        // activity into the stopped state and then finish it.
+        if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + this);
+        mStackSupervisor.mFinishingActivities.add(this);
+        resumeKeyDispatchingLocked();
+        mRootActivityContainer.resumeFocusedStacksTopActivities();
+        // If activity was not paused at this point - explicitly pause it to start finishing
+        // process. Finishing will be completed once it reports pause back.
+        if (isState(RESUMED) && stack.mPausingActivity != null) {
+            stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
+                    next /* resuming */, false /* dontWait */);
+        }
+        return this;
+    }
+
     void makeFinishingLocked() {
         if (finishing) {
             return;
@@ -1616,8 +1935,11 @@
             try {
                 ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
                 ar.add(rintent);
+                // Making sure the client state is RESUMED after transaction completed and doing
+                // so only if activity is currently RESUMED. Otherwise, client may have extra
+                // life-cycle calls to RESUMED (and PAUSED later).
                 mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
-                        NewIntentItem.obtain(ar));
+                        NewIntentItem.obtain(ar, mState == RESUMED));
                 unsent = false;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
@@ -1924,6 +2246,15 @@
         return state1 == mState || state2 == mState || state3 == mState || state4 == mState;
     }
 
+    /**
+     * Returns {@code true} if the Activity is in one of the specified states.
+     */
+    boolean isState(ActivityState state1, ActivityState state2, ActivityState state3,
+            ActivityState state4, ActivityState state5) {
+        return state1 == mState || state2 == mState || state3 == mState || state4 == mState
+                || state5 == mState;
+    }
+
     void notifyAppResumed(boolean wasStopped) {
         if (mAppWindowToken == null) {
             Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: "
@@ -2039,6 +2370,11 @@
             mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
                     WindowVisibilityItem.obtain(true /* showWindow */));
             makeActiveIfNeeded(null /* activeActivity*/);
+            if (isState(STOPPING, STOPPED)) {
+                // Set state to STARTED in order to have consistent state with client while
+                // making an non-active activity visible from stopped.
+                setState(STARTED, "makeClientVisible");
+            }
         } catch (Exception e) {
             Slog.w(TAG, "Exception thrown sending visibility update: " + intent.getComponent(), e);
         }
@@ -2113,7 +2449,7 @@
         // calls will lead to noticeable jank. A later call to
         // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to a proper
         // active state.
-        if (!isState(RESUMED, PAUSED, STOPPED, STOPPING)
+        if (!isState(STARTED, RESUMED, PAUSED, STOPPED, STOPPING)
                 || getActivityStack().mTranslucentActivityWaiting != null) {
             return false;
         }
@@ -2171,8 +2507,7 @@
             // been removed (e.g. destroy timeout), so the token could be null.
             return;
         }
-        r.icicle = null;
-        r.haveState = false;
+        r.setSavedState(null /* savedState */);
 
         final ActivityDisplay display = r.getDisplay();
         if (display != null) {
@@ -2245,19 +2580,18 @@
             return;
         }
         if (newPersistentState != null) {
-            persistentState = newPersistentState;
+            mPersistentState = newPersistentState;
             mAtmService.notifyTaskPersisterLocked(task, false);
         }
-        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + icicle);
 
         if (newIcicle != null) {
             // If icicle is null, this is happening due to a timeout, so we haven't really saved
             // the state.
-            icicle = newIcicle;
-            haveState = true;
+            setSavedState(newIcicle);
             launchCount = 0;
             updateTaskDescription(description);
         }
+        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE, "Saving icicle of " + this + ": " + mIcicle);
         if (!stopped) {
             if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
             stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
@@ -2461,8 +2795,8 @@
 
         if (windowFromSameProcessAsActivity) {
             return mAtmService.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
-                    anrActivity.shortComponentName, anrActivity.appInfo, shortComponentName,
-                    app, false, reason);
+                    anrActivity.shortComponentName, anrActivity.info.applicationInfo,
+                    shortComponentName, app, false, reason);
         } else {
             // In this case another process added windows using this activity token. So, we call the
             // generic service input dispatch timed out method so that the right process is blamed.
@@ -2538,7 +2872,8 @@
         }
         final TaskRecord task = r.task;
         final int activityNdx = task.mActivities.indexOf(r);
-        if (activityNdx < 0 || (onlyRoot && activityNdx > task.findEffectiveRootIndex())) {
+        if (activityNdx < 0
+                || (onlyRoot && activityNdx > task.findRootIndex(true /* effectiveRoot */))) {
             return INVALID_TASK_ID;
         }
         return task.taskId;
@@ -2576,7 +2911,7 @@
         }
         final ActivityStack stack = getActivityStack();
         if (stack == null || this == stack.getResumedActivity() || this == stack.mPausingActivity
-                || !haveState || !stopped) {
+                || !mHaveState || !stopped) {
             // We're not ready for this kind of thing.
             return false;
         }
@@ -2641,7 +2976,7 @@
                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
                 allowTaskSnapshot(),
-                mState.ordinal() >= RESUMED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
+                mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
                 fromRecents);
         if (shown) {
             mStartingWindowState = STARTING_WINDOW_SHOWN;
@@ -3155,7 +3490,7 @@
 
     boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
         return ensureActivityConfiguration(globalChanges, preserveWindow,
-                false /* ignoreStopState */);
+                false /* ignoreVisibility */);
     }
 
     /**
@@ -3165,15 +3500,15 @@
      * @param globalChanges The changes to the global configuration.
      * @param preserveWindow If the activity window should be preserved on screen if the activity
      *                       is relaunched.
-     * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
-     *                        state. This is useful for the case where we know the activity will be
-     *                        visible soon and we want to ensure its configuration before we make it
-     *                        visible.
+     * @param ignoreVisibility If we should try to relaunch the activity even if it is invisible
+     *                         (stopped state). This is useful for the case where we know the
+     *                         activity will be visible soon and we want to ensure its configuration
+     *                         before we make it visible.
      * @return False if the activity was relaunched and true if it wasn't relaunched because we
      *         can't or the app handles the specific configuration that is changing.
      */
     boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
-            boolean ignoreStopState) {
+            boolean ignoreVisibility) {
         final ActivityStack stack = getActivityStack();
         if (stack.mConfigWillChange) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -3189,15 +3524,9 @@
             return true;
         }
 
-        if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
+        if (!ignoreVisibility && (mState == STOPPING || mState == STOPPED || !shouldBeVisible())) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
-                    "Skipping config check stopped or stopping: " + this);
-            return true;
-        }
-
-        if (!shouldBeVisible()) {
-            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
-                    "Skipping config check invisible stack: " + this);
+                    "Skipping config check invisible: " + this);
             return true;
         }
 
@@ -3358,7 +3687,7 @@
         // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
         // to the config change.
         // For O and later, apps will be required to add configChanges="uimode" to their manifest.
-        if (appInfo.targetSdkVersion < O
+        if (info.applicationInfo.targetSdkVersion < O
                 && requestedVrComponent != null
                 && onlyVrUiModeChanged) {
             configChanged |= CONFIG_UI_MODE;
@@ -3517,7 +3846,7 @@
         // The restarting state avoids removing this record when process is died.
         setState(RESTARTING_PROCESS, "restartActivityProcess");
 
-        if (!visible || haveState) {
+        if (!visible || mHaveState) {
             // Kill its process immediately because the activity should be in background.
             // The activity state will be update to {@link #DESTROYED} in
             // {@link ActivityStack#cleanUpActivityLocked} when handling process died.
@@ -3549,7 +3878,7 @@
         mStackSupervisor.scheduleRestartTimeout(this);
     }
 
-    private boolean isProcessRunning() {
+    boolean isProcessRunning() {
         WindowProcessController proc = app;
         if (proc == null) {
             proc = mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
@@ -3606,9 +3935,9 @@
         intent.saveToXml(out);
         out.endTag(null, TAG_INTENT);
 
-        if (isPersistable() && persistentState != null) {
+        if (isPersistable() && mPersistentState != null) {
             out.startTag(null, TAG_PERSISTABLEBUNDLE);
-            persistentState.saveToXml(out);
+            mPersistentState.saveToXml(out);
             out.endTag(null, TAG_PERSISTABLEBUNDLE);
         }
     }
@@ -3689,7 +4018,7 @@
                 0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
                 stackSupervisor, null /* options */, null /* sourceRecord */);
 
-        r.persistentState = persistentState;
+        r.mPersistentState = persistentState;
         r.taskDescription = taskDescription;
         r.createTime = createTime;
 
@@ -3795,6 +4124,27 @@
         return display != null && this == display.getResumedActivity();
     }
 
+
+    /**
+     * Check if this is the root of the task - first activity that is not finishing, starting from
+     * the bottom of the task. If all activities are finishing - then this method will return
+     * {@code true} if the activity is at the bottom.
+     *
+     * NOTE: This is different from 'effective root' - an activity that defines the task identity.
+     */
+    boolean isRootOfTask() {
+        if (task == null) {
+            return false;
+        }
+        final ActivityRecord rootActivity = task.getRootActivity();
+        if (rootActivity != null) {
+            return this == rootActivity;
+        }
+        // No non-finishing activity found. In this case the bottom-most activity is considered to
+        // be the root.
+        return task.getChildAt(0) == this;
+    }
+
     void registerRemoteAnimations(RemoteAnimationDefinition definition) {
         if (mAppWindowToken == null) {
             Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
@@ -3838,7 +4188,7 @@
         writeIdentifierToProto(proto, IDENTIFIER);
         proto.write(STATE, mState.toString());
         proto.write(VISIBLE, visible);
-        proto.write(FRONT_OF_TASK, frontOfTask);
+        proto.write(FRONT_OF_TASK, isRootOfTask());
         if (hasProcess()) {
             proto.write(PROC_ID, app.getPid());
         }
diff --git a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
index ad46248..c56a9e2 100644
--- a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
+++ b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
@@ -101,7 +101,13 @@
         if (mConnections == null || mConnections.isEmpty()) {
             return;
         }
-        mService.mH.post(() -> mService.mAmInternal.disconnectActivityFromServices(this));
+        // Capture and null out mConnections, to guarantee that we process
+        // disconnect of these specific connections exactly once even if
+        // we're racing with rapid activity lifecycle churn and this
+        // method is invoked more than once on this object.
+        final Object disc = mConnections;
+        mConnections = null;
+        mService.mH.post(() -> mService.mAmInternal.disconnectActivityFromServices(this, disc));
     }
 
     public void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index b3b6efe..81d8fa9 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -56,12 +56,14 @@
 import static com.android.server.am.ActivityStackProto.TASKS;
 import static com.android.server.wm.ActivityDisplay.POSITION_BOTTOM;
 import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
+import static com.android.server.wm.ActivityRecord.FINISH_AFTER_VISIBLE;
+import static com.android.server.wm.ActivityRecord.FINISH_IMMEDIATELY;
 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
 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;
+import static com.android.server.wm.ActivityStack.ActivityState.STARTED;
 import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
@@ -77,7 +79,6 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
@@ -92,7 +93,6 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
@@ -184,7 +184,6 @@
     private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
     private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
     private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
-    private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
     private static final String TAG_STACK = TAG + POSTFIX_STACK;
     private static final String TAG_STATES = TAG + POSTFIX_STATES;
     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
@@ -292,6 +291,7 @@
 
     enum ActivityState {
         INITIALIZING,
+        STARTED,
         RESUMED,
         PAUSING,
         PAUSED,
@@ -561,7 +561,6 @@
                     + reason);
             setResumedActivity(record, reason + " - onActivityStateChanged");
             if (record == mRootActivityContainer.getTopResumedActivity()) {
-                // TODO(b/111361570): Support multiple focused apps in WM
                 mService.setResumedActivityUncheckLocked(record, reason);
             }
             mStackSupervisor.mRecentTasks.add(record.getTaskRecord());
@@ -782,7 +781,7 @@
                 && !topActivity.noDisplay) {
             // Inform the user that they are starting an app that may not work correctly in
             // multi-window mode.
-            final String packageName = topActivity.appInfo.packageName;
+            final String packageName = topActivity.info.applicationInfo.packageName;
             mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
                     topTask.taskId, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN, packageName);
         }
@@ -1302,6 +1301,11 @@
             return;
         }
 
+        getDisplay().positionChildAtBottom(this, reason);
+        if (task != null) {
+            insertTaskAtBottom(task);
+        }
+
         /**
          * The intent behind moving a primary split screen stack to the back is usually to hide
          * behind the home stack. Exit split screen in this case.
@@ -1309,11 +1313,6 @@
         if (getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
             setWindowingMode(WINDOWING_MODE_UNDEFINED);
         }
-
-        getDisplay().positionChildAtBottom(this, reason);
-        if (task != null) {
-            insertTaskAtBottom(task);
-        }
     }
 
     boolean isFocusable() {
@@ -1388,13 +1387,12 @@
             }
 
             if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Comparing existing cls="
-                    + taskIntent.getComponent().flattenToShortString()
+                    + (task.realActivity != null ? task.realActivity.flattenToShortString() : "")
                     + "/aff=" + r.getTaskRecord().rootAffinity + " to new cls="
                     + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
             // TODO Refactor to remove duplications. Check if logic can be simplified.
-            if (taskIntent != null && taskIntent.getComponent() != null &&
-                    taskIntent.getComponent().compareTo(cls) == 0 &&
-                    Objects.equals(documentData, taskDocumentData)) {
+            if (task.realActivity != null && task.realActivity.compareTo(cls) == 0
+                    && Objects.equals(documentData, taskDocumentData)) {
                 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Found matching class!");
                 //dump();
                 if (DEBUG_TASKS) Slog.d(TAG_TASKS,
@@ -1497,8 +1495,6 @@
                 + " callers=" + Debug.getCallers(5));
         r.setState(RESUMED, "minimalResumeActivityLocked");
         r.completeResumeLocked();
-        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
-                "Launch completed; removing icicle of " + r.icicle);
     }
 
     private void clearLaunchTime(ActivityRecord r) {
@@ -1609,7 +1605,7 @@
             final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = activities.get(activityNdx);
-                if (r.isState(STOPPING, STOPPED, PAUSED, PAUSING)) {
+                if (r.isState(STARTED, STOPPING, STOPPED, PAUSED, PAUSING)) {
                     r.setSleeping(true);
                 }
             }
@@ -1780,7 +1776,7 @@
                     if (r.finishing) {
                         if (DEBUG_PAUSE) Slog.v(TAG,
                                 "Executing finish of failed to pause activity: " + r);
-                        finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false,
+                        r.finishCurrentActivityLocked(FINISH_AFTER_VISIBLE, false,
                                 "activityPausedLocked");
                     }
                 }
@@ -1799,7 +1795,7 @@
             prev.setState(PAUSED, "completePausedLocked");
             if (prev.finishing) {
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
-                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
+                prev = prev.finishCurrentActivityLocked(FINISH_AFTER_VISIBLE, false /* oomAdj */,
                         "completePausedLocked");
             } else if (prev.hasProcess()) {
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
@@ -1881,8 +1877,7 @@
         mRootActivityContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
     }
 
-    private void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed,
-            String reason) {
+    void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed, String reason) {
         if (!mStackSupervisor.mStoppingActivities.contains(r)) {
             EventLog.writeEvent(EventLogTags.AM_ADD_TO_STOPPING, r.mUserId,
                     System.identityHashCode(r), r.shortComponentName, reason);
@@ -1894,7 +1889,7 @@
         // last of activity of the last task the stack will be empty and must
         // be cleared immediately.
         boolean forceIdle = mStackSupervisor.mStoppingActivities.size() > MAX_STOPPING_TO_FORCE
-                || (r.frontOfTask && mTaskHistory.size() <= 1);
+                || (r.isRootOfTask() && mTaskHistory.size() <= 1);
         if (scheduleIdle || forceIdle) {
             if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Scheduling idle now: forceIdle="
                     + forceIdle + "immediate=" + !idleDelayed);
@@ -2177,7 +2172,7 @@
                         // sure it matches the current configuration.
                         if (r != starting && notifyClients) {
                             r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
-                                    true /* ignoreStopState */);
+                                    true /* ignoreVisibility */);
                         }
 
                         if (!r.attachedToProcess()) {
@@ -2383,7 +2378,11 @@
                 r.setVisible(true);
             }
             if (r != starting) {
-                mStackSupervisor.startSpecificActivityLocked(r, andResume, true /* checkConfig */);
+                // We should not resume activities that being launched behind because these
+                // activities are actually behind other fullscreen activities, but still required
+                // to be visible (such as performing Recents animation).
+                mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind,
+                        true /* checkConfig */);
                 return true;
             }
         }
@@ -2433,6 +2432,7 @@
                 case RESUMED:
                 case PAUSING:
                 case PAUSED:
+                case STARTED:
                     addToStopping(r, true /* scheduleIdle */,
                             canEnterPictureInPicture /* idleDelayed */, "makeInvisible");
                     break;
@@ -2636,7 +2636,7 @@
 
         if (!hasRunningActivity) {
             // There are no activities left in the stack, let's look somewhere else.
-            return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
+            return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
         }
 
         next.delayedResume = false;
@@ -2739,7 +2739,7 @@
         final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
                 && !lastResumedCanPip;
 
-        boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
+        boolean pausing = display.pauseBackStacks(userLeaving, next, false);
         if (mResumedActivity != null) {
             if (DEBUG_STATES) Slog.d(TAG_STATES,
                     "resumeTopActivityLocked: Pausing " + mResumedActivity);
@@ -2755,6 +2755,13 @@
             if (next.attachedToProcess()) {
                 next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
                         true /* activityChange */, false /* updateOomAdj */);
+            } else if (!next.isProcessRunning()) {
+                // Since the start-process is asynchronous, if we already know the process of next
+                // activity isn't running, we can start the process earlier to save the time to wait
+                // for the current activity to be paused.
+                final boolean isTop = this == display.getFocusedStack();
+                mService.startProcessAsync(next, false /* knownToBeDead */, isTop,
+                        isTop ? "pre-top-activity" : "pre-activity");
             }
             if (lastResumed != null) {
                 lastResumed.setWillCloseOrEnterPip(true);
@@ -2823,7 +2830,7 @@
         // that the previous one will be hidden soon.  This way it can know
         // to ignore it when computing the desired screen orientation.
         boolean anim = true;
-        final DisplayContent dc = getDisplay().mDisplayContent;
+        final DisplayContent dc = display.mDisplayContent;
         if (prev != null) {
             if (prev.finishing) {
                 if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
@@ -2962,7 +2969,8 @@
                 }
 
                 if (next.newIntents != null) {
-                    transaction.addCallback(NewIntentItem.obtain(next.newIntents));
+                    transaction.addCallback(
+                            NewIntentItem.obtain(next.newIntents, true /* resume */));
                 }
 
                 // Well the app will no longer be stopped.
@@ -2979,7 +2987,7 @@
                 next.clearOptionsLocked();
                 transaction.setLifecycleStateRequest(
                         ResumeActivityItem.obtain(next.app.getReportedProcState(),
-                                getDisplay().mDisplayContent.isNextTransitionForward()));
+                                dc.isNextTransitionForward()));
                 mService.getLifecycleManager().scheduleTransaction(transaction);
 
                 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
@@ -3037,21 +3045,33 @@
         return true;
     }
 
-    private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
-            ActivityOptions options, String reason) {
-        final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
-        if (nextFocusedStack != null) {
-            // Try to move focus to the next visible stack with a running activity if this
-            // stack is not covering the entire screen or is on a secondary display (with no home
-            // stack).
-            return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack, prev,
-                    null /* targetOptions */);
+    /**
+     * Resume the next eligible activity in a focusable stack when this one does not have any
+     * running activities left. The focus will be adjusted to the next focusable stack and
+     * top running activities will be resumed in all focusable stacks. However, if the current stack
+     * is a home stack - we have to keep it focused, start and resume a home activity on the current
+     * display instead to make sure that the display is not empty.
+     */
+    private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
+            ActivityOptions options) {
+        final String reason = "noMoreActivities";
+
+        if (!isActivityTypeHome()) {
+            final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
+            if (nextFocusedStack != null) {
+                // Try to move focus to the next visible stack with a running activity if this
+                // stack is not covering the entire screen or is on a secondary display with no home
+                // stack.
+                return mRootActivityContainer.resumeFocusedStacksTopActivities(nextFocusedStack,
+                        prev, null /* targetOptions */);
+            }
         }
 
-        // Let's just start up the Launcher...
+        // If the current stack is a home stack, or if focus didn't switch to a different stack -
+        // just start up the Launcher...
         ActivityOptions.abort(options);
         if (DEBUG_STATES) Slog.d(TAG_STATES,
-                "resumeTopActivityInNextFocusableStack: " + reason + ", go home");
+                "resumeNextFocusableActivityWhenStackIsEmpty: " + reason + ", go home");
         return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
     }
 
@@ -3123,8 +3143,10 @@
             boolean newTask, boolean keepCurTransition, ActivityOptions options) {
         TaskRecord rTask = r.getTaskRecord();
         final int taskId = rTask.taskId;
+        final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
         // mLaunchTaskBehind tasks get placed at the back of the task stack.
-        if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
+        if (!r.mLaunchTaskBehind && allowMoveToFront
+                && (taskForIdLocked(taskId) == null || newTask)) {
             // Last activity in task had been removed or ActivityManagerService is reusing task.
             // Insert or replace.
             // Might not even be in.
@@ -3181,9 +3203,9 @@
             r.createAppWindowToken();
         }
 
-        task.setFrontOfTask();
-
-        if (!isHomeOrRecentsStack() || numActivities() > 0) {
+        // The transition animation and starting window are not needed if {@code allowMoveToFront}
+        // is false, because the activity won't be visible.
+        if ((!isHomeOrRecentsStack() || numActivities() > 0) && allowMoveToFront) {
             final DisplayContent dc = getDisplay().mDisplayContent;
             if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                     "Prepare open transition: starting " + r);
@@ -3232,6 +3254,9 @@
                 // tell WindowManager that r is visible even though it is at the back of the stack.
                 r.setVisibility(true);
                 ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+                // Go ahead to execute app transition for this activity since the app transition
+                // will not be triggered through the resume channel.
+                getDisplay().mDisplayContent.executeAppTransition();
             } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
                 // Figure out if we are transitioning from another activity that is
                 // "has the same starting icon" as the next one.  This allows the
@@ -3289,20 +3314,17 @@
     }
 
     /**
-     * Perform a reset of the given task, if needed as part of launching it.
-     * Returns the new HistoryRecord at the top of the task.
-     */
-    /**
-     * Helper method for #resetTaskIfNeededLocked.
-     * We are inside of the task being reset...  we'll either finish this activity, push it out
-     * for another task, or leave it as-is.
+     * Helper method for {@link #resetTaskIfNeededLocked(ActivityRecord, ActivityRecord)}.
+     * Performs a reset of the given task, if needed for new activity start.
      * @param task The task containing the Activity (taskTop) that might be reset.
-     * @param forceReset
+     * @param forceReset Flag indicating if clear task was requested
      * @return An ActivityOptions that needs to be processed.
      */
     private ActivityOptions resetTargetTaskIfNeededLocked(TaskRecord task, boolean forceReset) {
         ActivityOptions topOptions = null;
 
+        // Tracker of the end of currently handled reply chain (sublist) of activities. What happens
+        // to activities in the same chain will depend on what the end activity of the chain needs.
         int replyChainEnd = -1;
         boolean canMoveOptions = true;
 
@@ -3310,11 +3332,14 @@
         // the root, we may no longer have the task!).
         final ArrayList<ActivityRecord> activities = task.mActivities;
         final int numActivities = activities.size();
-        final int rootActivityNdx = task.findEffectiveRootIndex();
-        for (int i = numActivities - 1; i > rootActivityNdx; --i ) {
+        int lastActivityNdx = task.findRootIndex(true /* effectiveRoot */);
+        if (lastActivityNdx == -1) {
+            lastActivityNdx = 0;
+        }
+        for (int i = numActivities - 1; i > lastActivityNdx; --i) {
             ActivityRecord target = activities.get(i);
-            if (target.frontOfTask)
-                break;
+            // TODO: Why is this needed? Looks like we're breaking the loop before we reach the root
+            if (target.isRootOfTask()) break;
 
             final int flags = target.info.flags;
             final boolean finishOnTaskLaunch =
@@ -3347,12 +3372,13 @@
                 // bottom of the activity stack.  This also keeps it
                 // correctly ordered with any activities we previously
                 // moved.
+                // TODO: We should probably look for other stacks also, since corresponding task
+                // with the same affinity is unlikely to be in the same stack.
                 final TaskRecord targetTask;
                 final ActivityRecord bottom =
                         !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ?
                                 mTaskHistory.get(0).mActivities.get(0) : null;
-                if (bottom != null && target.taskAffinity != null
-                        && target.taskAffinity.equals(bottom.getTaskRecord().affinity)) {
+                if (bottom != null && target.taskAffinity.equals(bottom.getTaskRecord().affinity)) {
                     // If the activity currently at the bottom has the
                     // same task affinity as the one we are moving,
                     // then merge it into the same task.
@@ -3362,7 +3388,8 @@
                 } else {
                     targetTask = createTaskRecord(
                             mStackSupervisor.getNextTaskIdForUserLocked(target.mUserId),
-                            target.info, null, null, null, false);
+                            target.info, null /* intent */, null /* voiceSession */,
+                            null /* voiceInteractor */, false /* toTop */);
                     targetTask.affinityIntent = target.intent;
                     if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
                             + " out to new task " + targetTask);
@@ -3424,8 +3451,8 @@
                     }
                     if (DEBUG_TASKS) Slog.w(TAG_TASKS,
                             "resetTaskIntendedTask: calling finishActivity on " + p);
-                    if (finishActivityLocked(
-                            p, Activity.RESULT_CANCELED, null, "reset-task", false)) {
+                    if (p.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+                            "reset-task", false /* oomAdj */)) {
                         end--;
                         srcPos--;
                     }
@@ -3443,28 +3470,34 @@
     }
 
     /**
-     * Helper method for #resetTaskIfNeededLocked. Processes all of the activities in a given
-     * TaskRecord looking for an affinity with the task of resetTaskIfNeededLocked.taskTop.
+     * Helper method for {@link #resetTaskIfNeededLocked(ActivityRecord, ActivityRecord)}.
+     * Processes all of the activities in a given TaskRecord looking for an affinity with the task
+     * of resetTaskIfNeededLocked.taskTop.
      * @param affinityTask The task we are looking for an affinity to.
      * @param task Task that resetTaskIfNeededLocked.taskTop belongs to.
      * @param topTaskIsHigher True if #task has already been processed by resetTaskIfNeededLocked.
-     * @param forceReset Flag passed in to resetTaskIfNeededLocked.
+     * @param forceReset Flag indicating if clear task was requested
      */
+    // TODO: Consider merging with #resetTargetTaskIfNeededLocked() above
     private int resetAffinityTaskIfNeededLocked(TaskRecord affinityTask, TaskRecord task,
             boolean topTaskIsHigher, boolean forceReset, int taskInsertionPoint) {
+        // Tracker of the end of currently handled reply chain (sublist) of activities. What happens
+        // to activities in the same chain will depend on what the end activity of the chain needs.
         int replyChainEnd = -1;
-        final int taskId = task.taskId;
         final String taskAffinity = task.affinity;
 
         final ArrayList<ActivityRecord> activities = affinityTask.mActivities;
         final int numActivities = activities.size();
-        final int rootActivityNdx = affinityTask.findEffectiveRootIndex();
 
         // Do not operate on or below the effective root Activity.
-        for (int i = numActivities - 1; i > rootActivityNdx; --i) {
+        int lastActivityNdx = affinityTask.findRootIndex(true /* effectiveRoot */);
+        if (lastActivityNdx == -1) {
+            lastActivityNdx = 0;
+        }
+        for (int i = numActivities - 1; i > lastActivityNdx; --i) {
             ActivityRecord target = activities.get(i);
-            if (target.frontOfTask)
-                break;
+            // TODO: Why is this needed? Looks like we're breaking the loop before we reach the root
+            if (target.isRootOfTask()) break;
 
             final int flags = target.info.flags;
             boolean finishOnTaskLaunch = (flags & ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
@@ -3503,8 +3536,8 @@
                         if (p.finishing) {
                             continue;
                         }
-                        finishActivityLocked(
-                                p, Activity.RESULT_CANCELED, null, "move-affinity", false);
+                        p.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+                                "move-affinity", false /* oomAdj */);
                     }
                 } else {
                     if (taskInsertionPoint < 0) {
@@ -3533,13 +3566,13 @@
                     // instance of the same activity?  Then we drop the instance
                     // below so it remains singleTop.
                     if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
-                        ArrayList<ActivityRecord> taskActivities = task.mActivities;
-                        int targetNdx = taskActivities.indexOf(target);
+                        final ArrayList<ActivityRecord> taskActivities = task.mActivities;
+                        final int targetNdx = taskActivities.indexOf(target);
                         if (targetNdx > 0) {
-                            ActivityRecord p = taskActivities.get(targetNdx - 1);
+                            final ActivityRecord p = taskActivities.get(targetNdx - 1);
                             if (p.intent.getComponent().equals(target.intent.getComponent())) {
-                                finishActivityLocked(p, Activity.RESULT_CANCELED, null, "replace",
-                                        false);
+                                p.finishActivityLocked(Activity.RESULT_CANCELED,
+                                        null /* resultData */, "replace", false /* oomAdj */);
                             }
                         }
                     }
@@ -3557,11 +3590,11 @@
                 (newActivity.info.flags & ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
         final TaskRecord task = taskTop.getTaskRecord();
 
-        /** False until we evaluate the TaskRecord associated with taskTop. Switches to true
-         * for remaining tasks. Used for later tasks to reparent to task. */
+        // False until we evaluate the TaskRecord associated with taskTop. Switches to true
+        // for remaining tasks. Used for later tasks to reparent to task.
         boolean taskFound = false;
 
-        /** If ActivityOptions are moved out and need to be aborted or moved to taskTop. */
+        // If ActivityOptions are moved out and need to be aborted or moved to taskTop.
         ActivityOptions topOptions = null;
 
         // Preserve the location for reparenting in the new task.
@@ -3642,7 +3675,7 @@
         return false;
     }
 
-    private void adjustFocusedActivityStack(ActivityRecord r, String reason) {
+    void adjustFocusedActivityStack(ActivityRecord r, String reason) {
         if (!mRootActivityContainer.isTopDisplayFocusedStack(this) ||
                 ((mResumedActivity != r) && (mResumedActivity != null))) {
             return;
@@ -3677,9 +3710,6 @@
         if (nextFocusableStack != null) {
             final ActivityRecord top = nextFocusableStack.topRunningActivityLocked();
             if (top != null && top == mRootActivityContainer.getTopResumedActivity()) {
-                // TODO(b/111361570): Remove this and update focused app per-display in
-                // WindowManager every time an activity becomes resumed in
-                // ActivityTaskManagerService#setResumedActivityUncheckLocked().
                 mService.setResumedActivityUncheckLocked(top, reason);
             }
             return;
@@ -3797,7 +3827,7 @@
             return false;
         }
 
-        finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
+        r.finishActivityLocked(resultCode, resultData, reason, oomAdj);
         return true;
     }
 
@@ -3809,8 +3839,8 @@
                 if (r.resultTo == self && r.requestCode == requestCode) {
                     if ((r.resultWho == null && resultWho == null) ||
                         (r.resultWho != null && r.resultWho.equals(resultWho))) {
-                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, "request-sub",
-                                false);
+                        r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+                                "request-sub", false /* oomAdj */);
                     }
                 }
             }
@@ -3840,7 +3870,8 @@
         int activityNdx = task.mActivities.indexOf(r);
         getDisplay().mDisplayContent.prepareAppTransition(
                 TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
-        finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
+        r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */, reason,
+                false /* oomAdj */);
         finishedTask = task;
         // Also terminate any activities below it that aren't yet
         // stopped, to avoid a situation where one will get
@@ -3857,11 +3888,12 @@
         }
         if (activityNdx >= 0) {
             r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx);
-            if (r.isState(RESUMED, PAUSING, PAUSED)) {
+            if (r.isState(STARTED, RESUMED, PAUSING, PAUSED)) {
                 if (!r.isActivityTypeHome() || mService.mHomeProcess != r.app) {
                     Slog.w(TAG, "  Force finishing activity "
                             + r.intent.getComponent().flattenToShortString());
-                    finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
+                    r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */, reason,
+                            false /* oomAdj */);
                 }
             }
         }
@@ -3877,8 +3909,8 @@
                 for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
                     ActivityRecord r = tr.mActivities.get(activityNdx);
                     if (!r.finishing) {
-                        finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-voice",
-                                false);
+                        r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+                                "finish-voice", false /* oomAdj */);
                         didOne = true;
                     }
                 }
@@ -3907,271 +3939,17 @@
         }
     }
 
-    final boolean finishActivityAffinityLocked(ActivityRecord r) {
-        ArrayList<ActivityRecord> activities = r.getTaskRecord().mActivities;
-        for (int index = activities.indexOf(r); index >= 0; --index) {
-            ActivityRecord cur = activities.get(index);
-            if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) {
-                break;
-            }
-            finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true);
-        }
-        return true;
-    }
-
-    private void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
-        // send the result
-        ActivityRecord resultTo = r.resultTo;
-        if (resultTo != null) {
-            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Adding result to " + resultTo
-                    + " who=" + r.resultWho + " req=" + r.requestCode
-                    + " res=" + resultCode + " data=" + resultData);
-            if (resultTo.mUserId != r.mUserId) {
-                if (resultData != null) {
-                    resultData.prepareToLeaveUser(r.mUserId);
-                }
-            }
-            if (r.info.applicationInfo.uid > 0) {
-                mService.mUgmInternal.grantUriPermissionFromIntent(r.info.applicationInfo.uid,
-                        resultTo.packageName, resultData,
-                        resultTo.getUriPermissionsLocked(), resultTo.mUserId);
-            }
-            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode, resultData);
-            r.resultTo = null;
-        }
-        else if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "No result destination from " + r);
-
-        // Make sure this HistoryRecord is not holding on to other resources,
-        // because clients have remote IPC references to this object so we
-        // can't assume that will go away and want to avoid circular IPC refs.
-        r.results = null;
-        r.pendingResults = null;
-        r.newIntents = null;
-        r.icicle = null;
-    }
-
-    /**
-     * See {@link #finishActivityLocked(ActivityRecord, int, Intent, String, boolean, boolean)}
-     */
-    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
-            String reason, boolean oomAdj) {
-        return finishActivityLocked(r, resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
-    }
-
-    /**
-     * @return Returns true if this activity has been removed from the history
-     * list, or false if it is still in the list and will be removed later.
-     */
-    final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
-            String reason, boolean oomAdj, boolean pauseImmediately) {
-        if (r.finishing) {
-            Slog.w(TAG, "Duplicate finish request for " + r);
-            return false;
-        }
-
-        mWindowManager.deferSurfaceLayout();
-        try {
-            r.makeFinishingLocked();
-            final TaskRecord task = r.getTaskRecord();
-            EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
-                    r.mUserId, System.identityHashCode(r),
-                    task.taskId, r.shortComponentName, reason);
-            final ArrayList<ActivityRecord> activities = task.mActivities;
-            final int index = activities.indexOf(r);
-            if (index < (activities.size() - 1)) {
-                task.setFrontOfTask();
-                if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
-                    // If the caller asked that this activity (and all above it)
-                    // be cleared when the task is reset, don't lose that information,
-                    // but propagate it up to the next activity.
-                    ActivityRecord next = activities.get(index+1);
-                    next.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-                }
-            }
-
-            r.pauseKeyDispatchingLocked();
-
-            adjustFocusedActivityStack(r, "finishActivity");
-
-            finishActivityResultsLocked(r, resultCode, resultData);
-
-            final boolean endTask = index <= 0 && !task.isClearingToReuseTask();
-            final int transit = endTask ? TRANSIT_TASK_CLOSE : TRANSIT_ACTIVITY_CLOSE;
-            if (mResumedActivity == r) {
-                if (DEBUG_VISIBILITY || DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
-                        "Prepare close transition: finishing " + r);
-                if (endTask) {
-                    mService.getTaskChangeNotificationController().notifyTaskRemovalStarted(
-                            task.getTaskInfo());
-                }
-                getDisplay().mDisplayContent.prepareAppTransition(transit, false);
-
-                // Tell window manager to prepare for this one to be removed.
-                r.setVisibility(false);
-
-                if (mPausingActivity == null) {
-                    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
-                    if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
-                            "finish() => pause with userLeaving=false");
-                    startPausingLocked(false, false, null, pauseImmediately);
-                }
-
-                if (endTask) {
-                    mService.getLockTaskController().clearLockedTask(task);
-                }
-            } else if (!r.isState(PAUSING)) {
-                // If the activity is PAUSING, we will complete the finish once
-                // it is done pausing; else we can just directly finish it here.
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish not pausing: " + r);
-                if (r.visible) {
-                    prepareActivityHideTransitionAnimation(r, transit);
-                }
-
-                final int finishMode = (r.visible || r.nowVisible) ? FINISH_AFTER_VISIBLE
-                        : FINISH_AFTER_PAUSE;
-                final boolean removedActivity = finishCurrentActivityLocked(r, finishMode, oomAdj,
-                        "finishActivityLocked") == null;
-
-                // The following code is an optimization. When the last non-task overlay activity
-                // is removed from the task, we remove the entire task from the stack. However,
-                // since that is done after the scheduled destroy callback from the activity, that
-                // call to change the visibility of the task overlay activities would be out of
-                // sync with the activitiy visibility being set for this finishing activity above.
-                // In this case, we can set the visibility of all the task overlay activities when
-                // we detect the last one is finishing to keep them in sync.
-                if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
-                    for (ActivityRecord taskOverlay : task.mActivities) {
-                        if (!taskOverlay.mTaskOverlay) {
-                            continue;
-                        }
-                        prepareActivityHideTransitionAnimation(taskOverlay, transit);
-                    }
-                }
-                return removedActivity;
-            } else {
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
-            }
-
-            return false;
-        } finally {
-            mWindowManager.continueSurfaceLayout();
-        }
-    }
-
-    private void prepareActivityHideTransitionAnimation(ActivityRecord r, int transit) {
-        final DisplayContent dc = getDisplay().mDisplayContent;
-        dc.prepareAppTransition(transit, false);
-        r.setVisibility(false);
-        dc.executeAppTransition();
-    }
-
-    static final int FINISH_IMMEDIATELY = 0;
-    static final int FINISH_AFTER_PAUSE = 1;
-    static final int FINISH_AFTER_VISIBLE = 2;
-
-    final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj,
-            String reason) {
-        // First things first: if this activity is currently visible,
-        // and the resumed activity is not yet visible, then hold off on
-        // finishing until the resumed one becomes visible.
-
-        // The activity that we are finishing may be over the lock screen. In this case, we do not
-        // want to consider activities that cannot be shown on the lock screen as running and should
-        // proceed with finishing the activity if there is no valid next top running activity.
-        // Note that if this finishing activity is floating task, we don't need to wait the
-        // next activity resume and can destroy it directly.
-        final ActivityDisplay display = getDisplay();
-        final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
-        final boolean isFloating = r.getConfiguration().windowConfiguration.tasksAreFloating();
-
-        if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
-                && next != null && !next.nowVisible && !isFloating) {
-            if (!mStackSupervisor.mStoppingActivities.contains(r)) {
-                addToStopping(r, false /* scheduleIdle */, false /* idleDelayed */,
-                        "finishCurrentActivityLocked");
-            }
-            if (DEBUG_STATES) Slog.v(TAG_STATES,
-                    "Moving to STOPPING: "+ r + " (finish requested)");
-            r.setState(STOPPING, "finishCurrentActivityLocked");
-            if (oomAdj) {
-                mService.updateOomAdj();
-            }
-            return r;
-        }
-
-        // make sure the record is cleaned out of other places.
-        mStackSupervisor.mStoppingActivities.remove(r);
-        mStackSupervisor.mGoingToSleepActivities.remove(r);
-        final ActivityState prevState = r.getState();
-        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 && (noFocusedStack || noRunningStack);
-
-        if (mode == FINISH_IMMEDIATELY
-                || (prevState == PAUSED
-                    && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
-                || finishingInNonFocusedStackOrNoRunning
-                || prevState == STOPPING
-                || prevState == STOPPED
-                || prevState == ActivityState.INITIALIZING) {
-            r.makeFinishingLocked();
-            boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm:" + reason);
-
-            if (finishingInNonFocusedStackOrNoRunning) {
-                // Finishing activity that was in paused state and it was in not currently focused
-                // stack, need to make something visible in its place. Also if the display does not
-                // have running activity, the configuration may need to be updated for restoring
-                // original orientation of the display.
-                mRootActivityContainer.ensureVisibilityAndConfig(next, mDisplayId,
-                        false /* markFrozenIfConfigChanged */, true /* deferResume */);
-            }
-            if (activityRemoved) {
-                mRootActivityContainer.resumeFocusedStacksTopActivities();
-            }
-            if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
-                    "destroyActivityLocked: finishCurrentActivityLocked r=" + r +
-                    " destroy returned removed=" + activityRemoved);
-            return activityRemoved ? null : r;
-        }
-
-        // Need to go through the full pause cycle to get this
-        // activity into the stopped state and then finish it.
-        if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
-        mStackSupervisor.mFinishingActivities.add(r);
-        r.resumeKeyDispatchingLocked();
-        mRootActivityContainer.resumeFocusedStacksTopActivities();
-        // If activity was not paused at this point - explicitly pause it to start finishing
-        // process. Finishing will be completed once it reports pause back.
-        if (r.isState(RESUMED) && mPausingActivity != null) {
-            startPausingLocked(false /* userLeaving */, false /* uiSleeping */, next /* resuming */,
-                    false /* dontWait */);
-        }
-        return r;
-    }
-
-    void finishAllActivitiesLocked(boolean immediately) {
+    /** Finish all activities in the stack without waiting. */
+    void finishAllActivitiesImmediately() {
         boolean noActivitiesInStack = true;
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = activities.get(activityNdx);
                 noActivitiesInStack = false;
-                if (r.finishing && !immediately) {
-                    continue;
-                }
-                Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r + " immediately");
-                finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false,
-                        "finishAllActivitiesLocked");
+                Slog.d(TAG, "finishAllActivitiesImmediatelyLocked: finishing " + r);
+                r.finishCurrentActivityLocked(FINISH_IMMEDIATELY, false /* oomAdj */,
+                        "finishAllActivitiesImmediatelyLocked");
             }
         }
         if (noActivitiesInStack) {
@@ -4205,7 +3983,8 @@
         // of a document, unless simply finishing it will return them to the the
         // correct app behind.
         final TaskRecord task = srec.getTaskRecord();
-        if (srec.frontOfTask && task.getBaseIntent() != null && task.getBaseIntent().isDocument()) {
+        if (srec.isRootOfTask() && task.getBaseIntent() != null
+                && task.getBaseIntent().isDocument()) {
             // Okay, this activity is at the root of its task.  What to do, what to do...
             if (!inFrontOfStandardStack()) {
                 // Finishing won't return to an application, so we need to recreate.
@@ -4397,7 +4176,7 @@
     }
 
     private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
-        finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
+        r.finishActivityResults(Activity.RESULT_CANCELED, null /* resultData */);
         r.makeFinishingLocked();
         if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
                 "Removing activity " + r + " from stack callers=" + Debug.getCallers(5));
@@ -4755,7 +4534,7 @@
                         // it has failed more than twice. Skip activities that's already finishing
                         // cleanly by itself.
                         remove = false;
-                    } else if ((!r.haveState && !r.stateNotNeeded
+                    } else if ((!r.hasSavedState() && !r.stateNotNeeded
                             && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) {
                         // Don't currently have state for the activity, or
                         // it is finishing -- always remove it.
@@ -4775,7 +4554,7 @@
                     if (remove) {
                         if (DEBUG_ADD_REMOVE || DEBUG_CLEANUP) Slog.i(TAG_ADD_REMOVE,
                                 "Removing activity " + r + " from stack at " + i
-                                + ": haveState=" + r.haveState
+                                + ": hasSavedState=" + r.hasSavedState()
                                 + " stateNotNeeded=" + r.stateNotNeeded
                                 + " finishing=" + r.finishing
                                 + " state=" + r.getState() + " callers=" + Debug.getCallers(5));
@@ -4798,11 +4577,6 @@
                         // This is needed when user later tap on the dead window, we need to stop
                         // other apps when user transfers focus to the restarted activity.
                         r.nowVisible = r.visible;
-                        if (!r.haveState) {
-                            if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
-                                    "App died, clearing saved state of " + r);
-                            r.icicle = null;
-                        }
                     }
                     cleanUpActivityLocked(r, true, true);
                     if (remove) {
@@ -4982,6 +4756,17 @@
             return true;
         }
 
+        ActivityRecord topActivity = getDisplay().topRunningActivity();
+        ActivityStack topStack = topActivity.getActivityStack();
+        if (topStack != null && topStack != this && topActivity.isState(RESUMED)) {
+            // The new top activity is already resumed, so there's a good chance that nothing will
+            // get resumed below. So, update visibility now in case the transition is closed
+            // prematurely.
+            mRootActivityContainer.ensureVisibilityAndConfig(null /* starting */,
+                    getDisplay().mDisplayId, false /* markFrozenIfConfigChanged */,
+                    false /* deferResume */);
+        }
+
         mRootActivityContainer.resumeFocusedStacksTopActivities();
         return true;
     }
@@ -5129,7 +4914,7 @@
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = activities.get(activityNdx);
                 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
-                    finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
+                    r.finishActivityLocked(Activity.RESULT_CANCELED, null, "close-sys", true);
                 }
             }
         }
@@ -5173,8 +4958,7 @@
                     didSomething = true;
                     Slog.i(TAG, "  Force finishing activity " + r);
                     lastTask = r.getTaskRecord();
-                    finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
-                            true);
+                    r.finishActivityLocked(Activity.RESULT_CANCELED, null, "force-stop", true);
                 }
             }
         }
@@ -5228,7 +5012,7 @@
             final ArrayList<ActivityRecord> activities = mTaskHistory.get(top).mActivities;
             int activityTop = activities.size() - 1;
             if (activityTop >= 0) {
-                finishActivityLocked(activities.get(activityTop), Activity.RESULT_CANCELED, null,
+                activities.get(activityTop).finishActivityLocked(Activity.RESULT_CANCELED, null,
                         "unhandled-back", true);
             }
         }
@@ -5265,7 +5049,7 @@
                     r.app = null;
                     getDisplay().mDisplayContent.prepareAppTransition(
                             TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
-                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false,
+                    r.finishCurrentActivityLocked(FINISH_IMMEDIATELY, false /* oomAdj */,
                             "handleAppCrashedLocked");
                 }
             }
@@ -5597,7 +5381,6 @@
         // If the original state is resumed, there is no state change to update focused app.
         // So here makes sure the activity focus is set if it is the top.
         if (origState == RESUMED && r == mRootActivityContainer.getTopResumedActivity()) {
-            // TODO(b/111361570): Support multiple focused apps in WM
             mService.setResumedActivityUncheckLocked(r, reason);
         }
     }
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index c992a69..e49e991 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -130,6 +130,7 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.ReferrerIntent;
@@ -323,6 +324,12 @@
     boolean mUserLeaving = false;
 
     /**
+     * The system chooser activity which worked as a delegate of
+     * {@link com.android.internal.app.ResolverActivity}.
+     */
+    private ComponentName mSystemChooserActivity;
+
+    /**
      * We don't want to allow the device to go to sleep while in the process
      * of launching an activity.  This is primarily to allow alarm intent
      * receivers to launch an activity and get that to run before the device
@@ -415,7 +422,7 @@
 
         void sendErrorResult(String message) {
             try {
-                if (callerApp.hasThread()) {
+                if (callerApp != null && callerApp.hasThread()) {
                     callerApp.getThread().scheduleCrash(message);
                 }
             } catch (RemoteException e) {
@@ -469,6 +476,14 @@
         return mKeyguardController;
     }
 
+    ComponentName getSystemChooserActivity() {
+        if (mSystemChooserActivity == null) {
+            mSystemChooserActivity = ComponentName.unflattenFromString(
+                    mService.mContext.getResources().getString(R.string.config_chooserActivity));
+        }
+        return mSystemChooserActivity;
+    }
+
     void setRecentTasks(RecentTasks recentTasks) {
         mRecentTasks = recentTasks;
         mRecentTasks.registerCallback(this);
@@ -761,10 +776,10 @@
 
             final int applicationInfoUid =
                     (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
-            if ((r.mUserId != proc.mUserId) || (r.appInfo.uid != applicationInfoUid)) {
+            if ((r.mUserId != proc.mUserId) || (r.info.applicationInfo.uid != applicationInfoUid)) {
                 Slog.wtf(TAG,
                         "User ID for activity changing for " + r
-                                + " appInfo.uid=" + r.appInfo.uid
+                                + " appInfo.uid=" + r.info.applicationInfo.uid
                                 + " info.ai.uid=" + applicationInfoUid
                                 + " old=" + r.app + " new=" + proc);
             }
@@ -798,8 +813,9 @@
                     newIntents = r.newIntents;
                 }
                 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
-                        "Launching: " + r + " icicle=" + r.icicle + " with results=" + results
-                                + " newIntents=" + newIntents + " andResume=" + andResume);
+                        "Launching: " + r + " savedState=" + r.getSavedState()
+                                + " with results=" + results + " newIntents=" + newIntents
+                                + " andResume=" + andResume);
                 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.mUserId,
                         System.identityHashCode(r), task.taskId, r.shortComponentName);
                 if (r.isActivityTypeHome()) {
@@ -821,7 +837,7 @@
                         proc.getConfiguration(), r.getMergedOverrideConfiguration());
                 r.setLastReportedConfiguration(mergedConfiguration);
 
-                logIfTransactionTooLarge(r.intent, r.icicle);
+                logIfTransactionTooLarge(r.intent, r.getSavedState());
 
 
                 // Create activity launch transaction.
@@ -836,7 +852,7 @@
                         mergedConfiguration.getGlobalConfiguration(),
                         mergedConfiguration.getOverrideConfiguration(), r.compat,
                         r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
-                        r.icicle, r.persistentState, results, newIntents,
+                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                         dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                 r.assistToken));
 
@@ -980,20 +996,8 @@
             r.notifyUnknownVisibilityLaunched();
         }
 
-        try {
-            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
-                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
-                        + r.processName);
-            }
-            // Post message to start process to avoid possible deadlock of calling into AMS with the
-            // ATMS lock held.
-            final Message msg = PooledLambda.obtainMessage(
-                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
-                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
-            mService.mH.sendMessage(msg);
-        } finally {
-            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
-        }
+        final boolean isTop = andResume && r.isTopRunningActivity();
+        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
     }
 
     boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho,
@@ -1187,7 +1191,8 @@
         final PackageInfo packageInfo;
         try {
             packageInfo = mService.mContext.getPackageManager()
-                    .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
+                    .getPackageInfoAsUser(callingPackage, PackageManager.GET_PERMISSIONS,
+                            UserHandle.getUserId(callingUid));
         } catch (PackageManager.NameNotFoundException e) {
             Slog.i(TAG, "Cannot find package info for " + callingPackage);
             return ACTIVITY_RESTRICTION_NONE;
@@ -1336,8 +1341,8 @@
             final ActivityStack stack = r.getActivityStack();
             if (stack != null) {
                 if (r.finishing) {
-                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
-                            "activityIdleInternalLocked");
+                    r.finishCurrentActivityLocked(ActivityRecord.FINISH_IMMEDIATELY,
+                            false /* oomAdj */, "activityIdleInternalLocked");
                 } else {
                     stack.stopActivityLocked(r);
                 }
@@ -2084,7 +2089,7 @@
         r.mLaunchTaskBehind = false;
         mRecentTasks.add(task);
         mService.getTaskChangeNotificationController().notifyTaskStackChanged();
-        r.setVisibility(false);
+        stack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
 
         // When launching tasks behind, update the last active time of the top task after the new
         // task has been shown briefly
@@ -2474,7 +2479,7 @@
             return;
         }
         mService.getTaskChangeNotificationController().notifyActivityForcedResizable(
-                task.taskId, reason, topActivity.appInfo.packageName);
+                task.taskId, reason, topActivity.info.applicationInfo.packageName);
     }
 
     void activityRelaunchedLocked(IBinder token) {
@@ -2810,7 +2815,7 @@
                     // receive input keys, so we should move the focused app to the home app so that
                     // window manager can correctly calculate the focus window that can receive
                     // input keys.
-                    display.moveHomeStackToFront(
+                    display.moveHomeActivityToTop(
                             "startActivityFromRecents: homeVisibleInSplitScreen");
 
                     // Immediately update the minimized docked stack mode, the upcoming animation
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 1718ac6..a334ed8 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -101,7 +101,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.Bundle;
@@ -118,9 +117,7 @@
 import android.util.EventLog;
 import android.util.Pools.SynchronizedPool;
 import android.util.Slog;
-import android.widget.Toast;
 
-import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.app.IVoiceInteractor;
@@ -1044,12 +1041,6 @@
                     + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
             return false;
         }
-        // don't abort if the callingPackage is temporarily whitelisted
-        if (mService.isPackageNameWhitelistedForBgActivityStarts(callingPackage)) {
-            Slog.w(TAG, "Background activity start for " + callingPackage
-                    + " temporarily whitelisted. This will not be supported in future Q builds.");
-            return false;
-        }
         // anything that has fallen through would currently be aborted
         Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
                 + "; callingUid: " + callingUid
@@ -1074,18 +1065,6 @@
         return true;
     }
 
-    // TODO: remove this toast after feature development is done
-    void showBackgroundActivityBlockedToast(boolean abort, String callingPackage) {
-        final Resources res = mService.mContext.getResources();
-        final String toastMsg = res.getString(abort
-                        ? R.string.activity_starter_block_bg_activity_starts_enforcing
-                        : R.string.activity_starter_block_bg_activity_starts_permissive,
-                callingPackage);
-        mService.mUiHandler.post(() -> {
-            Toast.makeText(mService.mContext, toastMsg, Toast.LENGTH_LONG).show();
-        });
-    }
-
     /**
      * Creates a launch intent for the given auxiliary resolution data.
      */
@@ -1437,9 +1416,16 @@
                 // performing operations without a window container.
                 final ActivityStack stack = mStartActivity.getActivityStack();
                 if (stack != null) {
-                    stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
+                    mStartActivity.finishActivityLocked(RESULT_CANCELED,
                             null /* intentResultData */, "startActivity", true /* oomAdj */);
                 }
+
+                // Stack should also be detached from display and be removed if it's empty.
+                if (startedActivityStack != null && startedActivityStack.isAttached()
+                        && startedActivityStack.numActivities() == 0
+                        && !startedActivityStack.isActivityTypeHome()) {
+                    startedActivityStack.remove();
+                }
             }
             mService.mWindowManager.continueSurfaceLayout();
         }
@@ -1457,7 +1443,6 @@
     private boolean handleBackgroundActivityAbort(ActivityRecord r) {
         // TODO(b/131747138): Remove toast and refactor related code in Q release.
         boolean abort = !mService.isBackgroundActivityStartsEnabled();
-        showBackgroundActivityBlockedToast(abort, r.launchedFromPackage);
         if (!abort) {
             return false;
         }
@@ -1572,7 +1557,7 @@
                 }
 
                 if (top != null) {
-                    if (top.frontOfTask) {
+                    if (top.isRootOfTask()) {
                         // Activity aliases may mean we use different intents for the top activity,
                         // so make sure the task now has the identity of the new intent.
                         top.getTaskRecord().setIntent(mStartActivity);
@@ -1699,7 +1684,8 @@
         mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
                 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.mUserId);
         mService.getPackageManagerInternalLocked().grantEphemeralAccess(
-                mStartActivity.mUserId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
+                mStartActivity.mUserId, mIntent,
+                UserHandle.getAppId(mStartActivity.info.applicationInfo.uid),
                 UserHandle.getAppId(mCallingUid));
         if (newTask) {
             EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.mUserId,
@@ -1860,7 +1846,7 @@
         // of this in the record so that we can skip it when trying to find
         // the top running activity.
         mDoResume = doResume;
-        if (!doResume || !r.okToShowLocked()) {
+        if (!doResume || !r.okToShowLocked() || mLaunchTaskBehind) {
             r.delayedResume = true;
             mDoResume = false;
         }
@@ -1994,8 +1980,8 @@
             // Also put noDisplay activities in the source task. These by itself can be placed
             // in any task/stack, however it could launch other activities like ResolverActivity,
             // and we want those to stay in the original task.
-            if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null
-                    && mSourceRecord.inFreeformWindowingMode())  {
+            if ((mStartActivity.isResolverOrDelegateActivity() || mStartActivity.noDisplay)
+                    && mSourceRecord != null && mSourceRecord.inFreeformWindowingMode()) {
                 mAddingToTask = true;
             }
         }
@@ -2274,7 +2260,7 @@
                         || LAUNCH_SINGLE_TOP == mLaunchMode)
                     && intentActivity.mActivityComponent.equals(
                             mStartActivity.mActivityComponent)) {
-                if (intentActivity.frontOfTask) {
+                if (intentActivity.isRootOfTask()) {
                     intentActivity.getTaskRecord().setIntent(mStartActivity);
                 }
                 deliverNewIntent(intentActivity);
@@ -2311,32 +2297,29 @@
     }
 
     private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
+        if (mRestrictedBgActivity && (mReuseTask == null || !mReuseTask.containsAppUid(mCallingUid))
+                && handleBackgroundActivityAbort(mStartActivity)) {
+            return START_ABORTED;
+        }
+
         mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
 
         // Do no move the target stack to front yet, as we might bail if
         // isLockTaskModeViolation fails below.
 
         if (mReuseTask == null) {
-            if (mRestrictedBgActivity && handleBackgroundActivityAbort(mStartActivity)) {
-                return START_ABORTED;
-            }
+            final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
             final TaskRecord task = mTargetStack.createTaskRecord(
                     mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
                     mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                     mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
-                    mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
-                    mOptions);
+                    mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
             addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
             updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
 
             if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
                     + " in new task " + mStartActivity.getTaskRecord());
         } else {
-            if (mRestrictedBgActivity && !mReuseTask.containsAppUid(mCallingUid)) {
-                if (handleBackgroundActivityAbort(mStartActivity)) {
-                    return START_ABORTED;
-                }
-            }
             addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
         }
 
@@ -2697,7 +2680,8 @@
 
         if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
                  || mPreferredDisplayId != DEFAULT_DISPLAY) {
-            final boolean onTop = aOptions == null || !aOptions.getAvoidMoveToFront();
+            final boolean onTop =
+                    (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
             final ActivityStack stack =
                     mRootActivityContainer.getLaunchStack(r, aOptions, task, onTop, mLaunchParams);
             return stack;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index dbc530d..ab35652 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -559,7 +559,7 @@
     /**
      * Gets bitmap snapshot of the provided task id.
      */
-    public abstract ActivityManager.TaskSnapshot getTaskSnapshot(int taskId,
+    public abstract ActivityManager.TaskSnapshot getTaskSnapshotNoRestore(int taskId,
             boolean reducedResolution);
 
     /** Returns true if uid is considered foreground for activity start purposes. */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 2e5b9fd..fb393e6 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -246,7 +246,6 @@
 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;
@@ -434,9 +433,6 @@
     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<>();
@@ -463,7 +459,7 @@
 
     boolean mSuppressResizeConfigChanges;
 
-    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
+    final UpdateConfigurationResult mTmpUpdateConfigurationResult =
             new UpdateConfigurationResult();
 
     static final class UpdateConfigurationResult {
@@ -508,6 +504,12 @@
      */
     private boolean mDidAppSwitch;
 
+    /**
+     * Last stop app switches time, apps finished before this time cannot start background activity
+     * even if they are in grace period.
+     */
+    private long mLastStopAppSwitchesTime;
+
     IActivityController mController = null;
     boolean mControllerIsAMonkey = false;
 
@@ -629,7 +631,7 @@
     /** If non-null, we are tracking the time the user spends in the currently focused app. */
     AppTimeTracker mCurAppTimeTracker;
 
-    private AppWarnings mAppWarnings;
+    AppWarnings mAppWarnings;
 
     /**
      * Packages that the user has asked to have run in screen size
@@ -1009,6 +1011,7 @@
     public final int startActivities(IApplicationThread caller, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
             int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         final String reason = "startActivities";
         enforceNotIsolatedCaller(reason);
         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
@@ -1028,10 +1031,11 @@
                 true /*validateIncomingUser*/);
     }
 
-    int startActivityAsUser(IApplicationThread caller, String callingPackage,
+    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
             boolean validateIncomingUser) {
+        assertPackageMatchesCallingUid(callingPackage);
         enforceNotIsolatedCaller("startActivityAsUser");
 
         userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
@@ -1204,6 +1208,7 @@
     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         final WaitResult res = new WaitResult();
         synchronized (mGlobalLock) {
             enforceNotIsolatedCaller("startActivityAndWait");
@@ -1231,6 +1236,7 @@
     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, Configuration config, Bundle bOptions, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         synchronized (mGlobalLock) {
             enforceNotIsolatedCaller("startActivityWithConfig");
             userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
@@ -1280,6 +1286,7 @@
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, IBinder permissionToken,
             boolean ignoreTargetSecurity, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         // This is very dangerous -- it allows you to perform a start activity (including
         // permission grants) as any app that may launch one of your own activities.  So we only
         // allow this in two cases:
@@ -1409,6 +1416,7 @@
             Intent intent, String resolvedType, IVoiceInteractionSession session,
             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
             Bundle bOptions, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
         if (session == null || interactor == null) {
             throw new NullPointerException("null session or interactor");
@@ -1432,6 +1440,7 @@
     @Override
     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
             Intent intent, String resolvedType, Bundle bOptions, int userId) {
+        assertPackageMatchesCallingUid(callingPackage);
         mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
         userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
 
@@ -1445,9 +1454,15 @@
                 .execute();
     }
 
+    /**
+     * Start the recents activity to perform the recents animation.
+     *
+     * @param intent The intent to start the recents activity.
+     * @param recentsAnimationRunner Pass {@code null} to only preload the activity.
+     */
     @Override
-    public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
-            IRecentsAnimationRunner recentsAnimationRunner) {
+    public void startRecentsActivity(Intent intent, @Deprecated IAssistDataReceiver unused,
+            @Nullable IRecentsAnimationRunner recentsAnimationRunner) {
         enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
         final int callingPid = Binder.getCallingPid();
         final long origId = Binder.clearCallingIdentity();
@@ -1458,9 +1473,13 @@
 
                 // Start a new recents animation
                 final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
-                        getActivityStartController(), mWindowManager, callingPid);
-                anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
-                        recentsUid, assistDataReceiver);
+                        getActivityStartController(), mWindowManager, intent, recentsComponent,
+                        recentsUid, callingPid);
+                if (recentsAnimationRunner == null) {
+                    anim.preloadRecentsActivity();
+                } else {
+                    anim.startRecentsActivity(recentsAnimationRunner);
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -1634,7 +1653,8 @@
                 if (getLockTaskController().activityBlockedFromFinish(r)) {
                     return false;
                 }
-                return task.getStack().finishActivityAffinityLocked(r);
+                r.finishActivityAffinity();
+                return true;
             } finally {
                 Binder.restoreCallingIdentity(origId);
             }
@@ -2347,15 +2367,9 @@
     void moveTaskToFrontLocked(@Nullable IApplicationThread appThread,
             @Nullable String callingPackage, int taskId, int flags, SafeActivityOptions options,
             boolean fromRecents) {
-
         final int callingPid = Binder.getCallingPid();
         final int callingUid = Binder.getCallingUid();
-        if (!isSameApp(callingUid, callingPackage)) {
-            String msg = "Permission Denial: moveTaskToFrontLocked() from pid="
-                    + Binder.getCallingPid() + " as package " + callingPackage;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
+        assertPackageMatchesCallingUid(callingPackage);
         if (!checkAppSwitchAllowedLocked(callingPid, callingUid, -1, -1, "Task to front")) {
             SafeActivityOptions.abort(options);
             return;
@@ -2369,9 +2383,7 @@
                 null /* intent */, "moveTaskToFront");
         if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1,
                 -1, callerApp, null, false, null)) {
-            boolean abort = !isBackgroundActivityStartsEnabled();
-            starter.showBackgroundActivityBlockedToast(abort, callingPackage);
-            if (abort) {
+            if (!isBackgroundActivityStartsEnabled()) {
                 return;
             }
         }
@@ -2409,7 +2421,7 @@
     /**
      * Return true if callingUid is system, or packageName belongs to that callingUid.
      */
-    boolean isSameApp(int callingUid, @Nullable String packageName) {
+    private boolean isSameApp(int callingUid, @Nullable String packageName) {
         try {
             if (callingUid != 0 && callingUid != SYSTEM_UID) {
                 if (packageName == null) {
@@ -2426,6 +2438,21 @@
         return true;
     }
 
+    /**
+     * Checks that the provided package name matches the current calling UID, throws a security
+     * exception if it doesn't.
+     */
+    void assertPackageMatchesCallingUid(@Nullable String packageName) {
+        final int callingUid = Binder.getCallingUid();
+        if (isSameApp(callingUid, packageName)) {
+            return;
+        }
+        final String msg = "Permission Denial: package=" + packageName
+                + " does not belong to uid=" + callingUid;
+        Slog.w(TAG, msg);
+        throw new SecurityException(msg);
+    }
+
     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
             int callingPid, int callingUid, String name) {
         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
@@ -2959,6 +2986,7 @@
     @Override
     public List<IBinder> getAppTasks(String callingPackage) {
         int callingUid = Binder.getCallingUid();
+        assertPackageMatchesCallingUid(callingPackage);
         long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
@@ -3075,9 +3103,9 @@
         try {
             if (TextUtils.equals(pae.intent.getAction(),
                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
-                pae.intent.putExtras(pae.extras);
-
-                startVoiceInteractionServiceAsUser(pae.intent, pae.userHandle, "AssistContext");
+                // Start voice interaction through VoiceInteractionManagerService.
+                mAssistUtils.showSessionForActiveService(sendBundle, SHOW_SOURCE_APPLICATION,
+                        null, null);
             } else {
                 pae.intent.replaceExtras(pae.extras);
                 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
@@ -3096,34 +3124,6 @@
         }
     }
 
-    /**
-     * 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 {
@@ -3769,7 +3769,7 @@
                     voiceInteractor);
             long token = Binder.clearCallingIdentity();
             try {
-                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
+                startRunningVoiceLocked(voiceSession, activityToCallback.info.applicationInfo.uid);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -3911,7 +3911,8 @@
     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
-                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
+                + Arrays.toString(horizontalSizeConfiguration) + " "
+                + Arrays.toString(verticalSizeConfigurations));
         synchronized (mGlobalLock) {
             ActivityRecord record = ActivityRecord.isInStackLocked(token);
             if (record == null) {
@@ -3945,10 +3946,10 @@
                     // Caller wants the current split-screen primary stack to be the top stack after
                     // it goes fullscreen, so move it to the front.
                     stack.moveToFront("dismissSplitScreenMode");
-                } else if (mRootActivityContainer.isTopDisplayFocusedStack(stack)) {
+                } else {
                     // In this case the current split-screen primary stack shouldn't be the top
-                    // stack after it goes fullscreen, but it current has focus, so we move the
-                    // focus to the top-most split-screen secondary stack next to it.
+                    // stack after it goes fullscreen, so we move the focus to the top-most
+                    // split-screen secondary stack next to it.
                     final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
                             WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
                     if (otherStack != null) {
@@ -4135,8 +4136,9 @@
                         final ActivityStack stack = r.getActivityStack();
                         stack.setPictureInPictureAspectRatio(aspectRatio);
                         stack.setPictureInPictureActions(actions);
-                        MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
-                                r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
+                        MetricsLoggerWrapper.logPictureInPictureEnter(mContext,
+                                r.info.applicationInfo.uid, r.shortComponentName,
+                                r.supportsEnterPipOnTaskSwitch);
                         logPictureInPictureArgs(params);
                     }
                 };
@@ -4404,46 +4406,6 @@
     }
 
     @Override
-    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
-        mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
-
-        synchronized (mGlobalLock) {
-            // Check if display is initialized in AM.
-            if (!mRootActivityContainer.isDisplayAdded(displayId)) {
-                // Call might come when display is not yet added or has already been removed.
-                if (DEBUG_CONFIGURATION) {
-                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
-                            + displayId);
-                }
-                return false;
-            }
-
-            if (values == null && mWindowManager != null) {
-                // sentinel: fetch the current configuration from the window manager
-                values = mWindowManager.computeNewConfiguration(displayId);
-            }
-
-            if (mWindowManager != null) {
-                final Message msg = PooledLambda.obtainMessage(
-                        ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
-                mH.sendMessage(msg);
-            }
-
-            final long origId = Binder.clearCallingIdentity();
-            try {
-                if (values != null) {
-                    Settings.System.clearConfiguration(values);
-                }
-                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
-                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
-                return mTmpUpdateConfigurationResult.changes != 0;
-            } finally {
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
-    @Override
     public boolean updateConfiguration(Configuration values) {
         mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
 
@@ -4517,22 +4479,27 @@
         enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
         final long ident = Binder.clearCallingIdentity();
         try {
-            final TaskRecord task;
-            synchronized (mGlobalLock) {
-                task = mRootActivityContainer.anyTaskForId(taskId,
-                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
-                if (task == null) {
-                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
-                    return null;
-                }
-            }
-            // Don't call this while holding the lock as this operation might hit the disk.
-            return task.getSnapshot(reducedResolution);
+            return getTaskSnapshot(taskId, reducedResolution, true /* restoreFromDisk */);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
+    private ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution,
+            boolean restoreFromDisk) {
+        final TaskRecord task;
+        synchronized (mGlobalLock) {
+            task = mRootActivityContainer.anyTaskForId(taskId,
+                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+            if (task == null) {
+                Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
+                return null;
+            }
+        }
+        // Don't call this while holding the lock as this operation might hit the disk.
+        return task.getSnapshot(reducedResolution, restoreFromDisk);
+    }
+
     @Override
     public void setDisablePreviewScreenshots(IBinder token, boolean disable) {
         synchronized (mGlobalLock) {
@@ -4731,6 +4698,7 @@
         enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
         synchronized (mGlobalLock) {
             mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
+            mLastStopAppSwitchesTime = SystemClock.uptimeMillis();
             mDidAppSwitch = false;
             getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
         }
@@ -4747,6 +4715,10 @@
         }
     }
 
+    long getLastStopAppSwitchesTime() {
+        return mLastStopAppSwitchesTime;
+    }
+
     void onStartActivitySetDidAppSwitch() {
         if (mDidAppSwitch) {
             // This is the second allowed switch since we stopped switches, so now just generally
@@ -4767,18 +4739,12 @@
 
     private void applyUpdateVrModeLocked(ActivityRecord r) {
         // VR apps are expected to run in a main display. If an app is turning on VR for
-        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
-        // fullscreen stack before enabling VR Mode.
-        // TODO: The goal of this code is to keep the VR app on the main display. When the
-        // stack implementation changes in the future, keep in mind that the use of the fullscreen
-        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
-        // option would be a better choice here.
+        // itself, but isn't on the main display, then move it there before enabling VR Mode.
         if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) {
-            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
-                    + " to main stack for VR");
-            final ActivityStack stack = mRootActivityContainer.getDefaultDisplay().getOrCreateStack(
-                    WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */);
-            moveTaskToStack(r.getTaskRecord().taskId, stack.mStackId, true /* toTop */);
+            Slog.i(TAG, "Moving " + r.shortComponentName + " from display " + r.getDisplayId()
+                    + " to main display for VR");
+            mRootActivityContainer.moveStackToDisplay(
+                    r.getStackId(), DEFAULT_DISPLAY, true /* toTop */);
         }
         mH.post(() -> {
             if (!mVrController.onVrModeChanged(r)) {
@@ -4964,7 +4930,7 @@
     }
 
     void dumpActivityContainersLocked(PrintWriter pw) {
-        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
+        pw.println("ACTIVITY MANAGER CONTAINERS (dumpsys activity containers)");
         mRootActivityContainer.dumpChildrenNames(pw, " ");
         pw.println(" ");
     }
@@ -4980,6 +4946,9 @@
      *  - the cmd arg isn't the flattened component name of an existing activity:
      *    dump all activity whose component contains the cmd as a substring
      *  - A hex number of the ActivityRecord object instance.
+     * <p>
+     * The caller should not hold lock when calling this method because it will wait for the
+     * activities to complete the dump.
      *
      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
@@ -5032,29 +5001,28 @@
     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
             final ActivityRecord r, String[] args, boolean dumpAll) {
         String innerPrefix = prefix + "  ";
+        IApplicationThread appThread = null;
         synchronized (mGlobalLock) {
             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
             pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
             pw.print(" pid=");
-            if (r.hasProcess()) pw.println(r.app.getPid());
-            else pw.println("(not running)");
+            if (r.hasProcess()) {
+                pw.println(r.app.getPid());
+                appThread = r.app.getThread();
+            } else {
+                pw.println("(not running)");
+            }
             if (dumpAll) {
                 r.dump(pw, innerPrefix);
             }
         }
-        if (r.attachedToProcess()) {
+        if (appThread != null) {
             // flush anything that is already in the PrintWriter since the thread is going
             // to write to the file descriptor directly
             pw.flush();
-            try {
-                TransferPipe tp = new TransferPipe();
-                try {
-                    r.app.getThread().dumpActivity(tp.getWriteFd(),
-                            r.appToken, innerPrefix, args);
-                    tp.go(fd);
-                } finally {
-                    tp.kill();
-                }
+            try (TransferPipe tp = new TransferPipe()) {
+                appThread.dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args);
+                tp.go(fd);
             } catch (IOException e) {
                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
             } catch (RemoteException e) {
@@ -5177,8 +5145,12 @@
     }
 
     /** Update default (global) configuration and notify listeners about changes. */
-    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
+    int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
             boolean persistent, int userId, boolean deferResume) {
+
+        final ActivityDisplay defaultDisplay =
+                mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY);
+
         mTempConfig.setTo(getGlobalConfiguration());
         final int changes = mTempConfig.updateFrom(values);
         if (changes == 0) {
@@ -5186,7 +5158,7 @@
             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
             // performDisplayOverrideConfigUpdate in order to send the new display configuration
             // (even if there are no actual changes) to unfreeze the window.
-            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
+            defaultDisplay.performDisplayOverrideConfigUpdate(values, deferResume);
             return 0;
         }
 
@@ -5284,82 +5256,12 @@
 
         // Override configuration of the default display duplicates global config, so we need to
         // update it also. This will also notify WindowManager about changes.
-        performDisplayOverrideConfigUpdate(mRootActivityContainer.getConfiguration(), deferResume,
-                DEFAULT_DISPLAY);
+        defaultDisplay.performDisplayOverrideConfigUpdate(mRootActivityContainer.getConfiguration(),
+                deferResume);
 
         return changes;
     }
 
-    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
-            boolean deferResume, int displayId) {
-        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
-                displayId, null /* result */);
-    }
-
-    /**
-     * Updates override configuration specific for the selected display. If no config is provided,
-     * new one will be computed in WM based on current display info.
-     */
-    boolean updateDisplayOverrideConfigurationLocked(Configuration values,
-            ActivityRecord starting, boolean deferResume, int displayId,
-            ActivityTaskManagerService.UpdateConfigurationResult result) {
-        int changes = 0;
-        boolean kept = true;
-
-        if (mWindowManager != null) {
-            mWindowManager.deferSurfaceLayout();
-        }
-        try {
-            if (values != null) {
-                if (displayId == DEFAULT_DISPLAY) {
-                    // Override configuration of the default display duplicates global config, so
-                    // we're calling global config update instead for default display. It will also
-                    // apply the correct override config.
-                    changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
-                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
-                } else {
-                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
-                }
-            }
-
-            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
-        } finally {
-            if (mWindowManager != null) {
-                mWindowManager.continueSurfaceLayout();
-            }
-        }
-
-        if (result != null) {
-            result.changes = changes;
-            result.activityRelaunched = !kept;
-        }
-        return kept;
-    }
-
-    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
-            int displayId) {
-        mTempConfig.setTo(mRootActivityContainer.getDisplayOverrideConfiguration(displayId));
-        final int changes = mTempConfig.updateFrom(values);
-        if (changes != 0) {
-            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
-                    + mTempConfig + " for displayId=" + displayId);
-            mRootActivityContainer.setDisplayOverrideConfiguration(mTempConfig, displayId);
-
-            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
-            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
-                mAppWarnings.onDensityChanged();
-
-                // Post message to start process to avoid possible deadlock of calling into AMS with
-                // the ATMS lock held.
-                final Message msg = PooledLambda.obtainMessage(
-                        ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
-                        N, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
-                mH.sendMessage(msg);
-            }
-        }
-        return changes;
-    }
-
     private void updateEventDispatchingLocked(boolean booted) {
         mWindowManager.setEventDispatching(booted && !mShuttingDown);
     }
@@ -5397,13 +5299,6 @@
         return mAmInternal.isBackgroundActivityStartsEnabled();
     }
 
-    boolean isPackageNameWhitelistedForBgActivityStarts(@Nullable String packageName) {
-        if (packageName == null) {
-            return false;
-        }
-        return mAmInternal.isPackageNameWhitelistedForBgActivityStarts(packageName);
-    }
-
     void enableScreenAfterBoot(boolean booted) {
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
                 SystemClock.uptimeMillis());
@@ -5623,6 +5518,24 @@
         mH.sendMessage(m);
     }
 
+    void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
+            String hostingType) {
+        try {
+            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
+                        + activity.processName);
+            }
+            // Post message to start process to avoid possible deadlock of calling into AMS with the
+            // ATMS lock held.
+            final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
+                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
+                    isTop, hostingType, activity.intent.getComponent());
+            mH.sendMessage(m);
+        } finally {
+            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+        }
+    }
+
     void setBooting(boolean booting) {
         mAmInternal.setBooting(booting);
     }
@@ -5676,7 +5589,7 @@
             return;
         }
         try {
-            inm.cancelNotificationWithTag("android", null,
+            inm.cancelNotificationWithTag("android", "android", null,
                     SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION, userId);
         } catch (RuntimeException e) {
             Slog.w(TAG, "Error canceling notification for service", e);
@@ -5787,7 +5700,7 @@
     }
 
     /** Applies latest configuration and/or visibility updates if needed. */
-    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
+    boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
         boolean kept = true;
         final ActivityStack mainStack = mRootActivityContainer.getTopDisplayFocusedStack();
         // mainStack is null during startup.
@@ -5867,8 +5780,10 @@
      */
     Intent getSecondaryHomeIntent(String preferredPackage) {
         final Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
-        if (preferredPackage == null) {
-            // Using the component stored in config if no package name.
+        final boolean useSystemProvidedLauncher = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_useSystemProvidedLauncherForSecondary);
+        if (preferredPackage == null || useSystemProvidedLauncher) {
+            // Using the component stored in config if no package name or forced.
             final String secondaryHomeComponent = mContext.getResources().getString(
                     com.android.internal.R.string.config_secondaryHomeComponent);
             intent.setComponent(ComponentName.unflattenFromString(secondaryHomeComponent));
@@ -6178,6 +6093,7 @@
                 SafeActivityOptions options, int userId, boolean validateIncomingUser,
                 PendingIntentRecord originatingPendingIntent,
                 boolean allowBackgroundActivityStart) {
+            assertPackageMatchesCallingUid(callingPackage);
             synchronized (mGlobalLock) {
                 return getActivityStartController().startActivitiesInPackage(uid, realCallingPid,
                         realCallingUid, callingPackage, intents, resolvedTypes, resultTo, options,
@@ -6193,6 +6109,7 @@
                 int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
                 PendingIntentRecord originatingPendingIntent,
                 boolean allowBackgroundActivityStart) {
+            assertPackageMatchesCallingUid(callingPackage);
             synchronized (mGlobalLock) {
                 return getActivityStartController().startActivityInPackage(uid, realCallingPid,
                         realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
@@ -7168,10 +7085,8 @@
         public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
                 String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
                 boolean dumpFocusedStackOnly) {
-            synchronized (mGlobalLock) {
-                return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
-                        dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
-            }
+            return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti, dumpAll,
+                    dumpVisibleStacksOnly, dumpFocusedStackOnly);
         }
 
         @Override
@@ -7415,10 +7330,10 @@
         }
 
         @Override
-        public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
-            synchronized (mGlobalLock) {
-                return ActivityTaskManagerService.this.getTaskSnapshot(taskId, reducedResolution);
-            }
+        public ActivityManager.TaskSnapshot getTaskSnapshotNoRestore(int taskId,
+                boolean reducedResolution) {
+            return ActivityTaskManagerService.this.getTaskSnapshot(taskId, reducedResolution,
+                    false /* restoreFromDisk */);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 78f1e69..a8f7768 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -27,7 +27,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.UserHandle;
-import android.util.Slog;
 
 /**
  * An implementation of IAppTask, that allows an app to manage its own tasks via
@@ -97,12 +96,7 @@
         // Will bring task to front if it already has a root activity.
         final int callingPid = Binder.getCallingPid();
         final int callingUid = Binder.getCallingUid();
-        if (!mService.isSameApp(callingUid, callingPackage)) {
-            String msg = "Permission Denial: moveToFront() from pid="
-                    + Binder.getCallingPid() + " as package " + callingPackage;
-            Slog.w(TAG, msg);
-            throw new SecurityException(msg);
-        }
+        mService.assertPackageMatchesCallingUid(callingPackage);
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mService.mGlobalLock) {
@@ -118,9 +112,7 @@
                         null /* intent */, "moveToFront");
                 if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid,
                         callingPackage, -1, -1, callerApp, null, false, null)) {
-                    boolean abort = !mService.isBackgroundActivityStartsEnabled();
-                    starter.showBackgroundActivityBlockedToast(abort, callingPackage);
-                    if (abort) {
+                    if (!mService.isBackgroundActivityStartsEnabled()) {
                         return;
                     }
                 }
@@ -136,6 +128,7 @@
     public int startActivity(IBinder whoThread, String callingPackage,
             Intent intent, String resolvedType, Bundle bOptions) {
         checkCaller();
+        mService.assertPackageMatchesCallingUid(callingPackage);
 
         int callingUser = UserHandle.getCallingUserId();
         TaskRecord tr;
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 19ccc62..557a609 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -23,6 +23,7 @@
 import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
@@ -88,6 +89,7 @@
 import android.content.res.ResourceId;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
+import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -259,6 +261,8 @@
     private final boolean mGridLayoutRecentsEnabled;
     private final boolean mLowRamRecentsEnabled;
 
+    private final int mDefaultWindowAnimationStyleResId;
+
     private RemoteAnimationController mRemoteAnimationController;
 
     final Handler mHandler;
@@ -306,6 +310,12 @@
                 * mContext.getResources().getDisplayMetrics().density);
         mGridLayoutRecentsEnabled = SystemProperties.getBoolean("ro.recents.grid", false);
         mLowRamRecentsEnabled = ActivityManager.isLowRamDeviceStatic();
+
+        final TypedArray windowStyle = mContext.getTheme().obtainStyledAttributes(
+                com.android.internal.R.styleable.Window);
+        mDefaultWindowAnimationStyleResId = windowStyle.getResourceId(
+                com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
+        windowStyle.recycle();
     }
 
     boolean isTransitionSet() {
@@ -524,6 +534,25 @@
         return redoLayout;
     }
 
+    @VisibleForTesting
+    int getDefaultWindowAnimationStyleResId() {
+        return mDefaultWindowAnimationStyleResId;
+    }
+
+    /** Returns window animation style ID from {@link LayoutParams} or from system in some cases */
+    @VisibleForTesting
+    int getAnimationStyleResId(@NonNull LayoutParams lp) {
+        int resId = lp.windowAnimations;
+        if (lp.type == LayoutParams.TYPE_APPLICATION_STARTING) {
+            // Note that we don't want application to customize starting window animation.
+            // Since this window is specific for displaying while app starting,
+            // application should not change its animation directly.
+            // In this case, it will use system resource to get default animation.
+            resId = mDefaultWindowAnimationStyleResId;
+        }
+        return resId;
+    }
+
     private AttributeCache.Entry getCachedAnimations(LayoutParams lp) {
         if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
                 + (lp != null ? lp.packageName : null)
@@ -533,7 +562,7 @@
             // application resources.  It is nice to avoid loading application
             // resources if we can.
             String packageName = lp.packageName != null ? lp.packageName : "android";
-            int resId = lp.windowAnimations;
+            int resId = getAnimationStyleResId(lp);
             if ((resId&0xFF000000) == 0x01000000) {
                 packageName = "android";
             }
@@ -1774,8 +1803,10 @@
         }
         final boolean toShade =
                 (mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0;
+        final boolean subtle =
+                (mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) != 0;
         return mService.mPolicy.createHiddenByKeyguardExit(
-                transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade);
+                transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade, subtle);
     }
 
     int getAppStackClipMode() {
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 6c5ef52..d4e95cf 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -23,6 +23,7 @@
 import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
@@ -425,7 +426,8 @@
     private void handleNonAppWindowsInTransition(int transit, int flags) {
         if (transit == TRANSIT_KEYGUARD_GOING_AWAY) {
             if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0
-                    && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0) {
+                    && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0
+                    && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) == 0) {
                 Animation anim = mService.mPolicy.createKeyguardWallpaperExit(
                         (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
                 if (anim != null) {
@@ -437,7 +439,8 @@
                 || transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
             mDisplayContent.startKeyguardExitOnNonAppWindows(
                     transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
-                    (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
+                    (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0,
+                    (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) != 0);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/AppWarnings.java b/services/core/java/com/android/server/wm/AppWarnings.java
index 6c3fbc1..21b6809 100644
--- a/services/core/java/com/android/server/wm/AppWarnings.java
+++ b/services/core/java/com/android/server/wm/AppWarnings.java
@@ -105,7 +105,8 @@
     public void showUnsupportedDisplaySizeDialogIfNeeded(ActivityRecord r) {
         final Configuration globalConfig = mAtm.getGlobalConfiguration();
         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
-                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
+                && r.info.applicationInfo.requiresSmallestWidthDp
+                > globalConfig.smallestScreenWidthDp) {
             mUiHandler.showUnsupportedDisplaySizeDialog(r);
         }
     }
@@ -116,7 +117,8 @@
      * @param r activity record for which the warning may be displayed
      */
     public void showUnsupportedCompileSdkDialogIfNeeded(ActivityRecord r) {
-        if (r.appInfo.compileSdkVersion == 0 || r.appInfo.compileSdkVersionCodename == null) {
+        if (r.info.applicationInfo.compileSdkVersion == 0
+                || r.info.applicationInfo.compileSdkVersionCodename == null) {
             // We don't know enough about this package. Abort!
             return;
         }
@@ -135,14 +137,16 @@
         // the application was built OR both are pre-release with the same SDK_INT but different
         // codenames (e.g. simultaneous pre-release development), then we're likely to run into
         // compatibility issues. Warn the user and offer to check for an update.
-        final int compileSdk = r.appInfo.compileSdkVersion;
+        final int compileSdk = r.info.applicationInfo.compileSdkVersion;
         final int platformSdk = Build.VERSION.SDK_INT;
-        final boolean isCompileSdkPreview = !"REL".equals(r.appInfo.compileSdkVersionCodename);
+        final boolean isCompileSdkPreview =
+                !"REL".equals(r.info.applicationInfo.compileSdkVersionCodename);
         final boolean isPlatformSdkPreview = !"REL".equals(Build.VERSION.CODENAME);
         if ((isCompileSdkPreview && compileSdk < platformSdk)
                 || (isPlatformSdkPreview && platformSdk < compileSdk)
                 || (isCompileSdkPreview && isPlatformSdkPreview && platformSdk == compileSdk
-                    && !Build.VERSION.CODENAME.equals(r.appInfo.compileSdkVersionCodename))) {
+                    && !Build.VERSION.CODENAME.equals(
+                            r.info.applicationInfo.compileSdkVersionCodename))) {
             mUiHandler.showUnsupportedCompileSdkDialog(r);
         }
     }
@@ -153,7 +157,7 @@
      * @param r activity record for which the warning may be displayed
      */
     public void showDeprecatedTargetDialogIfNeeded(ActivityRecord r) {
-        if (r.appInfo.targetSdkVersion < Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT) {
+        if (r.info.applicationInfo.targetSdkVersion < Build.VERSION.MIN_SUPPORTED_TARGET_SDK_INT) {
             mUiHandler.showDeprecatedTargetDialog(r);
         }
     }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index cae7612..d15081c 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -33,6 +33,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
 import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE;
+import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND;
 import static android.view.WindowManager.TRANSIT_UNSET;
 import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN;
 
@@ -79,6 +80,7 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.logWithStack;
 import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
+import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
 
@@ -176,6 +178,7 @@
     boolean inPendingTransaction;
     boolean allDrawn;
     private boolean mLastAllDrawn;
+    private boolean mUseTransferredAnimation;
 
     // Set to true when this app creates a surface while in the middle of an animation. In that
     // case do not clear allDrawn until the animation completes.
@@ -257,9 +260,9 @@
     ActivityRecord mActivityRecord;
 
     /**
-     * See {@link #canTurnScreenOn()}
+     * @see #currentLaunchCanTurnScreenOn()
      */
-    private boolean mCanTurnScreenOn = true;
+    private boolean mCurrentLaunchCanTurnScreenOn = true;
 
     /**
      * If we are running an animation, this determines the transition type. Must be one of
@@ -539,6 +542,18 @@
                 // If the app was already visible, don't reset the waitingToShow state.
                 if (isHidden()) {
                     waitingToShow = true;
+
+                    // Let's reset the draw state in order to prevent the starting window to be
+                    // immediately dismissed when the app still has the surface.
+                    forAllWindows(w -> {
+                        if (w.mWinAnimator.mDrawState == HAS_DRAWN) {
+                            w.mWinAnimator.resetDrawState();
+
+                            // Force add to mResizingWindows, so that we are guaranteed to get
+                            // another reportDrawn callback.
+                            w.resetLastContentInsets();
+                        }
+                    },  true /* traverseTopToBottom */);
                 }
             }
 
@@ -567,8 +582,7 @@
                 displayContent.mClosingApps.add(this);
                 mEnteringAnimation = false;
             }
-            if (appTransition.getAppTransition()
-                    == WindowManager.TRANSIT_TASK_OPEN_BEHIND) {
+            if (appTransition.getAppTransition() == TRANSIT_TASK_OPEN_BEHIND) {
                 // We're launchingBehind, add the launching activity to mOpeningApps.
                 final WindowState win = getDisplayContent().findFocusedWindow();
                 if (win != null) {
@@ -579,7 +593,6 @@
                                     + " adding " + focusedToken + " to mOpeningApps");
                         }
                         // Force animation to be loaded.
-                        focusedToken.setHidden(true);
                         displayContent.mOpeningApps.add(focusedToken);
                     }
                 }
@@ -606,9 +619,14 @@
         // * token is transitioning visibility state
         // * or the token was marked as hidden and is exiting before we had a chance to play the
         // transition animation
-        // * or this is an opening app and windows are being replaced.
+        // * or this is an opening app and windows are being replaced
+        // * or the token is the opening app and visible while opening task behind existing one.
+        final DisplayContent displayContent = getDisplayContent();
         boolean visibilityChanged = false;
-        if (isHidden() == visible || (isHidden() && mIsExiting) || (visible && waitingForReplacement())) {
+        if (isHidden() == visible || (isHidden() && mIsExiting)
+                || (visible && waitingForReplacement())
+                || (visible && displayContent.mOpeningApps.contains(this)
+                && displayContent.mAppTransition.getAppTransition() == TRANSIT_TASK_OPEN_BEHIND)) {
             final AccessibilityController accessibilityController =
                     mWmService.mAccessibilityController;
             boolean changed = false;
@@ -618,9 +636,12 @@
             boolean runningAppAnimation = false;
 
             if (transit != WindowManager.TRANSIT_UNSET) {
-                if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
-                    delayed = runningAppAnimation = true;
+                if (mUseTransferredAnimation) {
+                    runningAppAnimation = isReallyAnimating();
+                } else if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
+                    runningAppAnimation = true;
                 }
+                delayed = runningAppAnimation;
                 final WindowState window = findMainWindow();
                 if (window != null && accessibilityController != null) {
                     accessibilityController.onAppWindowTransitionLocked(window, transit);
@@ -658,15 +679,16 @@
             }
 
             if (changed) {
-                getDisplayContent().getInputMonitor().setUpdateInputWindowsNeededLw();
+                displayContent.getInputMonitor().setUpdateInputWindowsNeededLw();
                 if (performLayout) {
                     mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
                             false /*updateInputWindows*/);
                     mWmService.mWindowPlacerLocked.performSurfacePlacement();
                 }
-                getDisplayContent().getInputMonitor().updateInputWindowsLw(false /*force*/);
+                displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/);
             }
         }
+        mUseTransferredAnimation = false;
 
         if (isReallyAnimating()) {
             delayed = true;
@@ -702,14 +724,14 @@
                 setClientHidden(!visible);
             }
 
-            if (!getDisplayContent().mClosingApps.contains(this)
-                    && !getDisplayContent().mOpeningApps.contains(this)) {
+            if (!displayContent.mClosingApps.contains(this)
+                    && !displayContent.mOpeningApps.contains(this)) {
                 // The token is not closing nor opening, so even if there is an animation set, that
                 // doesn't mean that it goes through the normal app transition cycle so we have
                 // to inform the docked controller about visibility change.
                 // TODO(multi-display): notify docked divider on all displays where visibility was
                 // affected.
-                getDisplayContent().getDockedDividerController().notifyAppVisibilityChanged();
+                displayContent.getDockedDividerController().notifyAppVisibilityChanged();
 
                 // Take the screenshot before possibly hiding the WSA, otherwise the screenshot
                 // will not be taken.
@@ -726,7 +748,7 @@
             // no animation but there will still be a transition set.
             // We still need to delay hiding the surface such that it
             // can be synchronized with showing the next surface in the transition.
-            if (isHidden() && !delayed && !getDisplayContent().mAppTransition.isTransitionSet()) {
+            if (isHidden() && !delayed && !displayContent.mAppTransition.isTransitionSet()) {
                 SurfaceControl.openTransaction();
                 for (int i = mChildren.size() - 1; i >= 0; i--) {
                     mChildren.get(i).mWinAnimator.hide("immediately hidden");
@@ -980,7 +1002,7 @@
                 + " " + this);
         mAppStopped = false;
         // Allow the window to turn the screen on once the app is resumed again.
-        setCanTurnScreenOn(true);
+        setCurrentLaunchCanTurnScreenOn(true);
         if (!wasStopped) {
             destroySurfaces(true /*cleanupOnResume*/);
         }
@@ -1317,7 +1339,15 @@
         if (prevDc == null || prevDc == mDisplayContent) {
             return;
         }
-        if (prevDc.mChangingApps.contains(this)) {
+
+        if (prevDc.mOpeningApps.remove(this)) {
+            // Transfer opening transition to new display.
+            mDisplayContent.mOpeningApps.add(this);
+            mDisplayContent.prepareAppTransition(prevDc.mAppTransition.getAppTransition(), true);
+            mDisplayContent.executeAppTransition();
+        }
+
+        if (prevDc.mChangingApps.remove(this)) {
             // This gets called *after* the AppWindowToken has been reparented to the new display.
             // That reparenting resulted in this window changing modes (eg. FREEFORM -> FULLSCREEN),
             // so this token is now "frozen" while waiting for the animation to start on prevDc
@@ -1326,6 +1356,8 @@
             // so we need to cancel the change transition here.
             clearChangeLeash(getPendingTransaction(), true /* cancel */);
         }
+        prevDc.mClosingApps.remove(this);
+
         if (prevDc.mFocusedApp == this) {
             prevDc.setFocusedApp(null);
             final TaskStack stack = dc.getTopStack();
@@ -1531,9 +1563,9 @@
                 transferAnimation(fromToken);
 
                 // When transferring an animation, we no longer need to apply an animation to the
-                // the token we transfer the animation over. Thus, remove the animation from
-                // pending opening apps.
-                getDisplayContent().mOpeningApps.remove(this);
+                // the token we transfer the animation over. Thus, set this flag to indicate we've
+                // transferred the animation.
+                mUseTransferredAnimation = true;
 
                 mWmService.updateFocusedWindowLocked(
                         UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
@@ -2388,21 +2420,25 @@
     }
 
     /**
-     * Sets whether the current launch can turn the screen on. See {@link #canTurnScreenOn()}
+     * Sets whether the current launch can turn the screen on.
+     * @see #currentLaunchCanTurnScreenOn()
      */
-    void setCanTurnScreenOn(boolean canTurnScreenOn) {
-        mCanTurnScreenOn = canTurnScreenOn;
+    void setCurrentLaunchCanTurnScreenOn(boolean currentLaunchCanTurnScreenOn) {
+        mCurrentLaunchCanTurnScreenOn = currentLaunchCanTurnScreenOn;
     }
 
     /**
      * Indicates whether the current launch can turn the screen on. This is to prevent multiple
      * relayouts from turning the screen back on. The screen should only turn on at most
      * once per activity resume.
+     * <p>
+     * Note this flag is only meaningful when {@link WindowManager.LayoutParams#FLAG_TURN_SCREEN_ON}
+     * or {@link ActivityRecord#canTurnScreenOn} is set.
      *
-     * @return true if the screen can be turned on.
+     * @return {@code true} if the activity is ready to turn on the screen.
      */
-    boolean canTurnScreenOn() {
-        return mCanTurnScreenOn;
+    boolean currentLaunchCanTurnScreenOn() {
+        return mCurrentLaunchCanTurnScreenOn;
     }
 
     /**
@@ -3211,16 +3247,6 @@
                 true /* topToBottom */);
     }
 
-    void removeFromPendingTransition() {
-        if (isWaitingForTransitionStart() && mDisplayContent != null) {
-            mDisplayContent.mOpeningApps.remove(this);
-            if (mDisplayContent.mChangingApps.remove(this)) {
-                clearChangeLeash(getPendingTransaction(), true /* cancel */);
-            }
-            mDisplayContent.mClosingApps.remove(this);
-        }
-    }
-
     private void updateColorTransform() {
         if (mSurfaceControl != null && mLastAppSaturationInfo != null) {
             getPendingTransaction().setColorTransform(mSurfaceControl,
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 84ba5ca9..7fc17e1 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -97,6 +97,7 @@
     final BlackSurface[] mBlackSurfaces = new BlackSurface[4];
 
     final boolean mForceDefaultOrientation;
+    private final TransactionFactory mTransactionFactory;
 
     public void printTo(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("Outer: "); mOuterRect.printShortString(pw);
@@ -111,11 +112,12 @@
         }
     }
 
-    public BlackFrame(SurfaceControl.Transaction t,
-            Rect outer, Rect inner, int layer, DisplayContent dc,
-            boolean forceDefaultOrientation) throws OutOfResourcesException {
+    public BlackFrame(TransactionFactory factory, SurfaceControl.Transaction t, Rect outer,
+            Rect inner, int layer, DisplayContent dc, boolean forceDefaultOrientation)
+            throws OutOfResourcesException {
         boolean success = false;
 
+        mTransactionFactory = factory;
         mForceDefaultOrientation = forceDefaultOrientation;
 
         // TODO: Why do we use 4 surfaces instead of just one big one behind the screenshot?
@@ -149,14 +151,16 @@
 
     public void kill() {
         if (mBlackSurfaces != null) {
+            SurfaceControl.Transaction t = mTransactionFactory.make();
             for (int i=0; i<mBlackSurfaces.length; i++) {
                 if (mBlackSurfaces[i] != null) {
                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
                             "  BLACK " + mBlackSurfaces[i].surface + ": DESTROY");
-                    mBlackSurfaces[i].surface.remove();
+                    t.remove(mBlackSurfaces[i].surface);
                     mBlackSurfaces[i] = null;
                 }
             }
+            t.apply();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index b5e7067..5dc88b3 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -410,7 +410,7 @@
         @VisibleForTesting
         boolean animatingToLargerSize() {
             // TODO: Fix this check for aspect ratio changes
-            return (mFrom.width() * mFrom.height() <= mTo.width() * mTo.height());
+            return (mFrom.width() * mFrom.height() < mTo.width() * mTo.height());
         }
 
         @Override
@@ -453,16 +453,10 @@
             boolean moveFromFullscreen, boolean moveToFullscreen,
             @AnimationType int animationType) {
         final BoundsAnimator existing = mRunningAnimations.get(target);
-        // animateBoundsImpl gets called twice for each animation. The second time we get the final
-        // to rect that respects the shelf, which is when we want to resize. Our signal for fade in
-        // comes in from how to enter into pip, but we also need to use the to and from rect to
-        // decide which animation we want to run finally.
-        boolean shouldResize = false;
-        if (isRunningFadeInAnimation(target)) {
-            shouldResize = true;
-            if (from.contains(to)) {
-                animationType = FADE_IN;
-            }
+
+        if (isRunningFadeInAnimation(target) && from.width() == to.width()
+                && from.height() == to.height()) {
+            animationType = FADE_IN;
         }
         final boolean replacing = existing != null;
         @SchedulePipModeChangedState int prevSchedulePipModeChangedState =
@@ -523,9 +517,10 @@
             // Since we are replacing, we skip both animation start and end callbacks
             existing.cancel();
         }
-        if (shouldResize) {
+        if (animationType == FADE_IN) {
             target.setPinnedStackSize(to, null);
         }
+
         final BoundsAnimator animator = new BoundsAnimator(target, animationType, from, to,
                 schedulePipModeChangedState, prevSchedulePipModeChangedState,
                 moveFromFullscreen, moveToFullscreen, frozenTask);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e901d43..faf75b6 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -30,16 +30,21 @@
 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.util.DisplayMetrics.DENSITY_DEFAULT;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.InsetsState.TYPE_IME;
+import static android.view.InsetsState.TYPE_LEFT_GESTURES;
+import static android.view.InsetsState.TYPE_RIGHT_GESTURES;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 import static android.view.View.GONE;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.DOCKED_TOP;
@@ -117,7 +122,6 @@
 import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_CHANGE;
 import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE;
 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
-import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
 import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
 import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
 import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
@@ -135,6 +139,7 @@
 import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
 import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
 import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
+import static com.android.server.wm.utils.RegionUtils.forEachRectReverse;
 import static com.android.server.wm.utils.RegionUtils.rectListToRegion;
 
 import android.animation.AnimationHandler;
@@ -323,6 +328,7 @@
     private final RemoteCallbackList<ISystemGestureExclusionListener>
             mSystemGestureExclusionListeners = new RemoteCallbackList<>();
     private final Region mSystemGestureExclusion = new Region();
+    private int mSystemGestureExclusionLimit;
 
     /**
      * For default display it contains real metrics, empty for others.
@@ -893,6 +899,8 @@
         mWallpaperController = new WallpaperController(mWmService, this);
         display.getDisplayInfo(mDisplayInfo);
         display.getMetrics(mDisplayMetrics);
+        mSystemGestureExclusionLimit = mWmService.mSystemGestureExclusionLimitDp
+                * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
         isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
         mDisplayFrames = new DisplayFrames(mDisplayId, mDisplayInfo,
                 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
@@ -1203,9 +1211,46 @@
         }
     }
 
-    /** Notify the configuration change of this display. */
+    void reconfigureDisplayLocked() {
+        if (!isReady()) {
+            return;
+        }
+        configureDisplayPolicy();
+        setLayoutNeeded();
+
+        boolean configChanged = updateOrientationFromAppTokens();
+        final Configuration currentDisplayConfig = getConfiguration();
+        mTmpConfiguration.setTo(currentDisplayConfig);
+        computeScreenConfiguration(mTmpConfiguration);
+        configChanged |= currentDisplayConfig.diff(mTmpConfiguration) != 0;
+
+        if (configChanged) {
+            mWaitingForConfig = true;
+            mWmService.startFreezingDisplayLocked(0 /* exitAnim */, 0 /* enterAnim */, this);
+            sendNewConfiguration();
+        }
+
+        mWmService.mWindowPlacerLocked.performSurfacePlacement();
+    }
+
     void sendNewConfiguration() {
-        mWmService.mH.obtainMessage(SEND_NEW_CONFIGURATION, this).sendToTarget();
+        if (!isReady() || mAcitvityDisplay == null) {
+            return;
+        }
+        final boolean configUpdated = mAcitvityDisplay.updateDisplayOverrideConfigurationLocked();
+        if (configUpdated) {
+            return;
+        }
+        // Something changed (E.g. device rotation), but no configuration update is needed.
+        // E.g. changing device rotation by 180 degrees. Go ahead and perform surface placement to
+        // unfreeze the display since we froze it when the rotation was updated in
+        // DisplayContent#updateRotationUnchecked.
+        if (mWaitingForConfig) {
+            mWaitingForConfig = false;
+            mWmService.mLastFinishedFreezeSource = "config-unchanged";
+            setLayoutNeeded();
+            mWmService.mWindowPlacerLocked.performSurfacePlacement();
+        }
     }
 
     @Override
@@ -1223,8 +1268,8 @@
 
         if (handled && requestingContainer instanceof ActivityRecord) {
             final ActivityRecord activityRecord = (ActivityRecord) requestingContainer;
-            final boolean kept = mWmService.mAtmService.updateDisplayOverrideConfigurationLocked(
-                    config, activityRecord, false /* deferResume */, getDisplayId());
+            final boolean kept = mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(
+                    config, activityRecord, false /* deferResume */, null /* result */);
             activityRecord.frozenBeforeDestroy = true;
             if (!kept) {
                 mWmService.mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
@@ -1232,8 +1277,8 @@
         } else {
             // We have a new configuration to push so we need to update ATMS for now.
             // TODO: Clean up display configuration push between ATMS and WMS after unification.
-            mWmService.mAtmService.updateDisplayOverrideConfigurationLocked(
-                    config, null /* starting */, false /* deferResume */, getDisplayId());
+            mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(
+                    config, null /* starting */, false /* deferResume */, null);
         }
         return handled;
     }
@@ -1342,7 +1387,7 @@
      * Update rotation of the DisplayContent with an option to force the update. This updates
      * the container's perception of rotation and, depending on the top activities, will freeze
      * the screen or start seamless rotation. The display itself gets rotated in
-     * {@link #applyRotationLocked} during {@link WindowManagerService#sendNewConfiguration}.
+     * {@link #applyRotationLocked} during {@link DisplayContent#sendNewConfiguration}.
      *
      * @param forceUpdate Force the rotation update. Sometimes in WM we might skip updating
      *                    orientation because we're waiting for some rotation to finish or display
@@ -1548,8 +1593,8 @@
             longSize = height;
         }
 
-        final int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
-        final int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
+        final int shortSizeDp = shortSize * DENSITY_DEFAULT / mBaseDisplayDensity;
+        final int longSizeDp = longSize * DENSITY_DEFAULT / mBaseDisplayDensity;
 
         mDisplayPolicy.updateConfigurationAndScreenSizeDependentBehaviors();
         mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
@@ -2199,6 +2244,18 @@
         onDisplayChanged(this);
     }
 
+    @Override
+    void onDisplayChanged(DisplayContent dc) {
+        super.onDisplayChanged(dc);
+        updateSystemGestureExclusionLimit();
+    }
+
+    void updateSystemGestureExclusionLimit() {
+        mSystemGestureExclusionLimit = mWmService.mSystemGestureExclusionLimitDp
+                * mDisplayMetrics.densityDpi / DENSITY_DEFAULT;
+        updateSystemGestureExclusion();
+    }
+
     void initializeDisplayBaseInfo() {
         final DisplayManagerInternal displayManagerInternal = mWmService.mDisplayManagerInternal;
         if (displayManagerInternal != null) {
@@ -2252,7 +2309,7 @@
             mInitialDisplayHeight = newHeight;
             mInitialDisplayDensity = newDensity;
             mInitialDisplayCutout = newCutout;
-            mWmService.reconfigureDisplayLocked(this);
+            reconfigureDisplayLocked();
         }
     }
 
@@ -2305,7 +2362,7 @@
         final boolean updateCurrent = userId == UserHandle.USER_CURRENT;
         if (mWmService.mCurrentUserId == userId || updateCurrent) {
             mBaseDisplayDensity = density;
-            mWmService.reconfigureDisplayLocked(this);
+            reconfigureDisplayLocked();
         }
         if (updateCurrent) {
             // We are applying existing settings so no need to save it again.
@@ -2326,7 +2383,7 @@
 
         mDisplayScalingDisabled = (mode != FORCE_SCALING_MODE_AUTO);
         Slog.i(TAG_WM, "Using display scaling mode: " + (mDisplayScalingDisabled ? "off" : "auto"));
-        mWmService.reconfigureDisplayLocked(this);
+        reconfigureDisplayLocked();
 
         mWmService.mDisplayWindowSettings.setForcedScalingMode(this, mode);
     }
@@ -2345,7 +2402,7 @@
 
         Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
         updateBaseDisplayMetrics(width, height, mBaseDisplayDensity);
-        mWmService.reconfigureDisplayLocked(this);
+        reconfigureDisplayLocked();
 
         if (clear) {
             width = height = 0;
@@ -2376,9 +2433,6 @@
                     + " to its current displayId=" + mDisplayId);
         }
 
-        // Clean up all pending transitions when stack reparent to another display.
-        stack.forAllAppWindows(AppWindowToken::removeFromPendingTransition);
-
         prevDc.mTaskStackContainers.removeChild(stack);
         mTaskStackContainers.addStackToDisplay(stack, onTop);
     }
@@ -3473,12 +3527,14 @@
     /**
      * Starts the Keyguard exit animation on all windows that don't belong to an app token.
      */
-    void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade) {
+    void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade,
+            boolean subtle) {
         final WindowManagerPolicy policy = mWmService.mPolicy;
         forAllWindows(w -> {
             if (w.mAppToken == null && policy.canBeHiddenByKeyguardLw(w)
                     && w.wouldBeVisibleIfPolicyIgnored() && !w.isVisible()) {
-                w.startAnimation(policy.createHiddenByKeyguardExit(onWallpaper, goingToShade));
+                w.startAnimation(policy.createHiddenByKeyguardExit(
+                        onWallpaper, goingToShade, subtle));
             }
         }, true /* traverseTopToBottom */);
     }
@@ -4552,13 +4608,15 @@
                         .show(mSplitScreenDividerAnchor);
                 scheduleAnimation();
             } else {
-                mAppAnimationLayer.remove();
+                mWmService.mTransactionFactory.make()
+                        .remove(mAppAnimationLayer)
+                        .remove(mBoostedAppAnimationLayer)
+                        .remove(mHomeAppAnimationLayer)
+                        .remove(mSplitScreenDividerAnchor)
+                        .apply();
                 mAppAnimationLayer = null;
-                mBoostedAppAnimationLayer.remove();
                 mBoostedAppAnimationLayer = null;
-                mHomeAppAnimationLayer.remove();
                 mHomeAppAnimationLayer = null;
-                mSplitScreenDividerAnchor.remove();
                 mSplitScreenDividerAnchor = null;
             }
         }
@@ -5053,7 +5111,7 @@
         if (!mLocationInParentWindow.equals(x, y)) {
             mLocationInParentWindow.set(x, y);
             if (mWmService.mAccessibilityController != null) {
-                mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+                mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(mDisplayId);
             }
             notifyLocationInParentDisplayChanged();
         }
@@ -5126,42 +5184,120 @@
 
     @VisibleForTesting
     Region calculateSystemGestureExclusion() {
+        final Region unhandled = Region.obtain();
+        unhandled.set(0, 0, mDisplayFrames.mDisplayWidth, mDisplayFrames.mDisplayHeight);
+
+        final Rect leftEdge = mInsetsStateController.getSourceProvider(TYPE_LEFT_GESTURES)
+                .getSource().getFrame();
+        final Rect rightEdge = mInsetsStateController.getSourceProvider(TYPE_RIGHT_GESTURES)
+                .getSource().getFrame();
+
         final Region global = Region.obtain();
         final Region touchableRegion = Region.obtain();
         final Region local = Region.obtain();
+        final int[] remainingLeftRight =
+                {mSystemGestureExclusionLimit, mSystemGestureExclusionLimit};
 
-        // Traverse all windows bottom up to assemble the gesture exclusion rects.
+        // Traverse all windows top down to assemble the gesture exclusion rects.
         // For each window, we only take the rects that fall within its touchable region.
         forAllWindows(w -> {
             if (w.cantReceiveTouchInput() || !w.isVisible()
-                    || (w.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0) {
+                    || (w.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0
+                    || unhandled.isEmpty()) {
                 return;
             }
-            final boolean modal =
-                    (w.mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
 
-            // Only keep the exclusion zones from the windows behind where the current window
-            // isn't touchable.
-            w.getTouchableRegion(touchableRegion);
-            global.op(touchableRegion, Op.DIFFERENCE);
+            // Get the touchable region of the window, and intersect with where the screen is still
+            // touchable, i.e. touchable regions on top are not covering it yet.
+            w.getEffectiveTouchableRegion(touchableRegion);
+            touchableRegion.op(unhandled, Op.INTERSECT);
 
-            rectListToRegion(w.getSystemGestureExclusion(), local);
+            if (w.isImplicitlyExcludingAllSystemGestures()) {
+                local.set(touchableRegion);
+            } else {
+                rectListToRegion(w.getSystemGestureExclusion(), local);
 
-            // Transform to display coordinates
-            local.scale(w.mGlobalScale);
-            final Rect frame = w.getWindowFrames().mFrame;
-            local.translate(frame.left, frame.top);
+                // Transform to display coordinates
+                local.scale(w.mGlobalScale);
+                final Rect frame = w.getWindowFrames().mFrame;
+                local.translate(frame.left, frame.top);
 
-            // A window can only exclude system gestures where it is actually touchable
-            local.op(touchableRegion, Op.INTERSECT);
+                // A window can only exclude system gestures where it is actually touchable
+                local.op(touchableRegion, Op.INTERSECT);
+            }
 
-            global.op(local, Op.UNION);
-        }, false /* topToBottom */);
+            // Apply restriction if necessary.
+            if (needsGestureExclusionRestrictions(w, mLastDispatchedSystemUiVisibility)) {
+
+                // Processes the region along the left edge.
+                remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, global, leftEdge,
+                        remainingLeftRight[0]);
+
+                // Processes the region along the right edge.
+                remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, global, rightEdge,
+                        remainingLeftRight[1]);
+
+                // Adds the middle (unrestricted area)
+                final Region middle = Region.obtain(local);
+                middle.op(leftEdge, Op.DIFFERENCE);
+                middle.op(rightEdge, Op.DIFFERENCE);
+                global.op(middle, Op.UNION);
+                middle.recycle();
+            } else {
+                global.op(local, Op.UNION);
+            }
+            unhandled.op(touchableRegion, Op.DIFFERENCE);
+        }, true /* topToBottom */);
         local.recycle();
         touchableRegion.recycle();
+        unhandled.recycle();
         return global;
     }
 
+    /**
+     * @return Whether gesture exclusion area should be restricted from the window depending on the
+     *         current SystemUI visibility flags.
+     */
+    private static boolean needsGestureExclusionRestrictions(WindowState win, int sysUiVisibility) {
+        final int type = win.mAttrs.type;
+        final int stickyHideNavFlags =
+                SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+        final boolean stickyHideNav =
+                (sysUiVisibility & stickyHideNavFlags) == stickyHideNavFlags;
+        return !stickyHideNav && type != TYPE_INPUT_METHOD && type != TYPE_STATUS_BAR
+                && win.getActivityType() != ACTIVITY_TYPE_HOME;
+    }
+
+    /**
+     * Adds a local gesture exclusion area to the global area while applying a limit per edge.
+     *
+     * @param local The gesture exclusion area to add.
+     * @param global The destination.
+     * @param edge Only processes the part in that region.
+     * @param limit How much limit in pixels we have.
+     * @return How much of the limit are remaining.
+     */
+    private static int addToGlobalAndConsumeLimit(Region local, Region global, Rect edge,
+            int limit) {
+        final Region r = Region.obtain(local);
+        r.op(edge, Op.INTERSECT);
+
+        final int[] remaining = {limit};
+        forEachRectReverse(r, rect -> {
+            if (remaining[0] <= 0) {
+                return;
+            }
+            final int height = rect.height();
+            if (height > remaining[0]) {
+                rect.top = rect.bottom - remaining[0];
+            }
+            remaining[0] -= height;
+            global.op(rect, Op.UNION);
+        });
+        r.recycle();
+        return remaining[0];
+    }
+
     void registerSystemGestureExclusionListener(ISystemGestureExclusionListener listener) {
         mSystemGestureExclusionListeners.register(listener);
         final boolean changed;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 21f01ff..1576873 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -198,6 +198,8 @@
     private static final int NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED = 0;
     // Nav bar is always translucent when the freeform stack is visible, otherwise always opaque.
     private static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1;
+    // Nav bar is never forced opaque.
+    private static final int NAV_BAR_FORCE_TRANSPARENT = 2;
 
     /**
      * These are the system UI flags that, when changing, can cause the layout
@@ -282,6 +284,8 @@
     /** See {@link #getNavigationBarFrameHeight} */
     private int[] mNavigationBarFrameHeightForRotationDefault = new int[4];
 
+    private boolean mIsFreeformWindowOverlappingWithNavBar;
+
     /** Cached value of {@link ScreenShapeHelper#getWindowOutsetBottomPx} */
     @Px private int mWindowOutsetBottom;
 
@@ -476,8 +480,10 @@
 
                     @Override
                     public void onSwipeFromRight() {
-                        final Region excludedRegion =
-                                mDisplayContent.calculateSystemGestureExclusion();
+                        final Region excludedRegion;
+                        synchronized (mLock) {
+                            excludedRegion = mDisplayContent.calculateSystemGestureExclusion();
+                        }
                         final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
                                 || mNavigationBarPosition == NAV_BAR_RIGHT;
                         if (mNavigationBar != null && sideAllowed
@@ -488,8 +494,10 @@
 
                     @Override
                     public void onSwipeFromLeft() {
-                        final Region excludedRegion =
-                                mDisplayContent.calculateSystemGestureExclusion();
+                        final Region excludedRegion;
+                        synchronized (mLock) {
+                            excludedRegion = mDisplayContent.calculateSystemGestureExclusion();
+                        }
                         final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
                                 || mNavigationBarPosition == NAV_BAR_LEFT;
                         if (mNavigationBar != null && sideAllowed
@@ -871,27 +879,24 @@
     }
 
     /**
-     * Preflight adding a window to the system.
+     * Check if a window can be added to the system.
      *
-     * Currently enforces that three window types are singletons per display:
+     * Currently enforces that two window types are singletons per display:
      * <ul>
      * <li>{@link WindowManager.LayoutParams#TYPE_STATUS_BAR}</li>
      * <li>{@link WindowManager.LayoutParams#TYPE_NAVIGATION_BAR}</li>
      * </ul>
      *
-     * @param win The window to be added
-     * @param attrs Information about the window to be added
+     * @param attrs Information about the window to be added.
      *
      * @return If ok, WindowManagerImpl.ADD_OKAY.  If too many singletons,
      * WindowManagerImpl.ADD_MULTIPLE_SINGLETON
      */
-    public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
-
+    int validateAddingWindowLw(WindowManager.LayoutParams attrs) {
         if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.STATUS_BAR_SERVICE,
                     "DisplayPolicy");
-            mScreenDecorWindows.add(win);
         }
 
         switch (attrs.type) {
@@ -904,6 +909,42 @@
                         return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
                     }
                 }
+                break;
+            case TYPE_NAVIGATION_BAR:
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                        "DisplayPolicy");
+                if (mNavigationBar != null) {
+                    if (mNavigationBar.isAlive()) {
+                        return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
+                    }
+                }
+                break;
+            case TYPE_NAVIGATION_BAR_PANEL:
+            case TYPE_STATUS_BAR_PANEL:
+            case TYPE_STATUS_BAR_SUB_PANEL:
+            case TYPE_VOICE_INTERACTION_STARTING:
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.STATUS_BAR_SERVICE,
+                        "DisplayPolicy");
+                break;
+        }
+        return ADD_OKAY;
+    }
+
+    /**
+     * Called when a window is being added to the system.  Must not throw an exception.
+     *
+     * @param win The window being added.
+     * @param attrs Information about the window to be added.
+     */
+    void addWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
+        if ((attrs.privateFlags & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0) {
+            mScreenDecorWindows.add(win);
+        }
+
+        switch (attrs.type) {
+            case TYPE_STATUS_BAR:
                 mStatusBar = win;
                 mStatusBarController.setWindow(win);
                 if (mDisplayContent.isDefaultDisplay) {
@@ -919,14 +960,6 @@
                 mDisplayContent.setInsetProvider(TYPE_TOP_TAPPABLE_ELEMENT, win, frameProvider);
                 break;
             case TYPE_NAVIGATION_BAR:
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE,
-                        "DisplayPolicy");
-                if (mNavigationBar != null) {
-                    if (mNavigationBar.isAlive()) {
-                        return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
-                    }
-                }
                 mNavigationBar = win;
                 mNavigationBarController.setWindow(win);
                 mNavigationBarController.setOnBarVisibilityChangedListener(
@@ -960,16 +993,7 @@
                         });
                 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
-            case TYPE_NAVIGATION_BAR_PANEL:
-            case TYPE_STATUS_BAR_PANEL:
-            case TYPE_STATUS_BAR_SUB_PANEL:
-            case TYPE_VOICE_INTERACTION_STARTING:
-                mContext.enforceCallingOrSelfPermission(
-                        android.Manifest.permission.STATUS_BAR_SERVICE,
-                        "DisplayPolicy");
-                break;
         }
-        return ADD_OKAY;
     }
 
     /**
@@ -978,7 +1002,7 @@
      *
      * @param win The window being removed.
      */
-    public void removeWindowLw(WindowState win) {
+    void removeWindowLw(WindowState win) {
         if (mStatusBar == win) {
             mStatusBar = null;
             mStatusBarController.setWindow(null);
@@ -1492,8 +1516,6 @@
         }
 
         sTmpRect.setEmpty();
-        sTmpDockedFrame.set(displayFrames.mDock);
-
         final int displayId = displayFrames.mDisplayId;
         final Rect dockFrame = displayFrames.mDock;
         final int displayHeight = displayFrames.mDisplayHeight;
@@ -1506,11 +1528,13 @@
                 continue;
             }
 
-            w.getWindowFrames().setFrames(sTmpDockedFrame /* parentFrame */,
-                    sTmpDockedFrame /* displayFrame */, sTmpDockedFrame /* overscanFrame */,
-                    sTmpDockedFrame /* contentFrame */, sTmpDockedFrame /* visibleFrame */,
-                    sTmpRect /* decorFrame */, sTmpDockedFrame /* stableFrame */,
-                    sTmpDockedFrame /* outsetFrame */);
+            w.getWindowFrames().setFrames(displayFrames.mUnrestricted /* parentFrame */,
+                    displayFrames.mUnrestricted /* displayFrame */,
+                    displayFrames.mUnrestricted /* overscanFrame */,
+                    displayFrames.mUnrestricted /* contentFrame */,
+                    displayFrames.mUnrestricted /* visibleFrame */, sTmpRect /* decorFrame */,
+                    displayFrames.mUnrestricted /* stableFrame */,
+                    displayFrames.mUnrestricted /* outsetFrame */);
             w.getWindowFrames().setDisplayCutout(displayFrames.mDisplayCutout);
             w.computeFrameLw();
             final Rect frame = w.getFrameLw();
@@ -2373,6 +2397,7 @@
         mAllowLockscreenWhenOn = false;
         mShowingDream = false;
         mWindowSleepTokenNeeded = false;
+        mIsFreeformWindowOverlappingWithNavBar = false;
     }
 
     /**
@@ -2472,6 +2497,13 @@
             }
         }
 
+        // Check if the freeform window overlaps with the navigation bar area.
+        final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null;
+        if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()
+                && isOverlappingWithNavBar(win, navBarWin)) {
+            mIsFreeformWindowOverlappingWithNavBar = true;
+        }
+
         // Also keep track of any windows that are dimming but not necessarily fullscreen in the
         // docked stack.
         if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming()
@@ -3288,8 +3320,10 @@
                 : mTopFullscreenOpaqueWindowState;
         vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
         vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
-        final int dockedVis = mStatusBarController.applyTranslucentFlagLw(
+        int dockedVis = mStatusBarController.applyTranslucentFlagLw(
                 mTopDockedOpaqueWindowState, 0, 0);
+        dockedVis = mNavigationBarController.applyTranslucentFlagLw(
+                mTopDockedOpaqueWindowState, dockedVis, 0);
 
         final boolean fullscreenDrawsStatusBarBackground =
                 drawsStatusBarBackground(vis, mTopFullscreenOpaqueWindowState);
@@ -3297,6 +3331,8 @@
                 drawsStatusBarBackground(dockedVis, mTopDockedOpaqueWindowState);
         final boolean fullscreenDrawsNavBarBackground =
                 drawsNavigationBarBackground(vis, mTopFullscreenOpaqueWindowState);
+        final boolean dockedDrawsNavigationBarBackground =
+                drawsNavigationBarBackground(dockedVis, mTopDockedOpaqueWindowState);
 
         // prevent status bar interaction from clearing certain flags
         int type = win.getAttrs().type;
@@ -3321,7 +3357,7 @@
         }
 
         vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing,
-                fullscreenDrawsNavBarBackground);
+                fullscreenDrawsNavBarBackground, dockedDrawsNavigationBarBackground);
 
         // update status bar
         boolean immersiveSticky =
@@ -3439,10 +3475,20 @@
      */
     private int configureNavBarOpacity(int visibility, boolean dockedStackVisible,
             boolean freeformStackVisible, boolean isDockedDividerResizing,
-            boolean fullscreenDrawsBackground) {
-        if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
-            if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
+            boolean fullscreenDrawsBackground, boolean dockedDrawsNavigationBarBackground) {
+        if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
+            if (fullscreenDrawsBackground && dockedDrawsNavigationBarBackground) {
+                visibility = setNavBarTransparentFlag(visibility);
+            } else if (dockedStackVisible) {
                 visibility = setNavBarOpaqueFlag(visibility);
+            }
+        } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
+            if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
+                if (mIsFreeformWindowOverlappingWithNavBar) {
+                    visibility = setNavBarTranslucentFlag(visibility);
+                } else {
+                    visibility = setNavBarOpaqueFlag(visibility);
+                }
             } else if (fullscreenDrawsBackground) {
                 visibility = setNavBarTransparentFlag(visibility);
             }
@@ -3731,4 +3777,14 @@
         wm.removeView(mPointerLocationView);
         mPointerLocationView = null;
     }
+
+    @VisibleForTesting
+    static boolean isOverlappingWithNavBar(WindowState targetWindow, WindowState navBarWindow) {
+        if (navBarWindow == null || !navBarWindow.isVisibleLw()
+                || targetWindow.mAppToken == null || !targetWindow.isVisibleLw()) {
+            return false;
+        }
+
+        return Rect.intersects(targetWindow.getFrameLw(), navBarWindow.getFrameLw());
+    }
 }
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 1d76a71..b1bc2197 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -569,7 +569,6 @@
             mMaximizeMeetFraction = getClipRevealMeetFraction(stack);
             animDuration = (long) (mAnimationDuration * mMaximizeMeetFraction);
         }
-        mService.mAtmInternal.notifyDockedStackMinimizedChanged(minimizedDock);
         final int size = mDockedStackListeners.beginBroadcast();
         for (int i = 0; i < size; ++i) {
             final IDockedStackListener listener = mDockedStackListeners.getBroadcastItem(i);
@@ -581,6 +580,9 @@
             }
         }
         mDockedStackListeners.finishBroadcast();
+        // Only notify ATM after we update the remote listeners, otherwise it may trigger another
+        // minimize change, which would lead to an inversion of states send to the listeners
+        mService.mAtmInternal.notifyDockedStackMinimizedChanged(minimizedDock);
     }
 
     void notifyDockSideChanged(int newDockSide) {
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 6127303..553b0ff 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -176,6 +176,8 @@
         mTransaction.transferTouchFocus(mTransferTouchFromToken, h.token);
         mTransferTouchFromToken = null;
 
+        // syncInputWindows here to ensure the input channel isn't removed before the transfer.
+        mTransaction.syncInputWindows();
         mTransaction.apply();
     }
 
diff --git a/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java b/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java
index c0f53b8..315de91 100644
--- a/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java
+++ b/services/core/java/com/android/server/wm/HighRefreshRateBlacklist.java
@@ -16,60 +16,102 @@
 
 package com.android.server.wm;
 
+import static android.provider.DeviceConfig.WindowManager.KEY_HIGH_REFRESH_RATE_BLACKLIST;
+
 import android.annotation.NonNull;
-import android.os.SystemProperties;
+import android.annotation.Nullable;
+import android.content.res.Resources;
+import android.provider.DeviceConfig;
 import android.util.ArraySet;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
+
+import java.io.PrintWriter;
+import java.util.concurrent.Executor;
 
 /**
  * A Blacklist for packages that should force the display out of high refresh rate.
  */
 class HighRefreshRateBlacklist {
 
-    private static final String SYSPROP_KEY = "ro.window_manager.high_refresh_rate_blacklist";
-    private static final String SYSPROP_KEY_LENGTH_SUFFIX = "_length";
-    private static final String SYSPROP_KEY_ENTRY_SUFFIX = "_entry";
-    private static final int MAX_ENTRIES = 50;
+    private final ArraySet<String> mBlacklistedPackages = new ArraySet<>();
+    @NonNull
+    private final String[] mDefaultBlacklist;
+    private final Object mLock = new Object();
 
-    private ArraySet<String> mBlacklistedPackages = new ArraySet<>();
-
-    static HighRefreshRateBlacklist create() {
-        return new HighRefreshRateBlacklist(new SystemPropertyGetter() {
+    static HighRefreshRateBlacklist create(@NonNull Resources r) {
+        return new HighRefreshRateBlacklist(r, new DeviceConfigInterface() {
             @Override
-            public int getInt(String key, int def) {
-                return SystemProperties.getInt(key, def);
+            public @Nullable String getProperty(@NonNull String namespace, @NonNull String name) {
+                return DeviceConfig.getProperty(namespace, name);
             }
-
-            @Override
-            public String get(String key) {
-                return SystemProperties.get(key);
+            public void addOnPropertiesChangedListener(@NonNull String namespace,
+                    @NonNull Executor executor,
+                    @NonNull DeviceConfig.OnPropertiesChangedListener listener) {
+                DeviceConfig.addOnPropertiesChangedListener(namespace, executor, listener);
             }
         });
     }
 
     @VisibleForTesting
-    HighRefreshRateBlacklist(SystemPropertyGetter propertyGetter) {
+    HighRefreshRateBlacklist(Resources r, DeviceConfigInterface deviceConfig) {
+        mDefaultBlacklist = r.getStringArray(R.array.config_highRefreshRateBlacklist);
+        deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                BackgroundThread.getExecutor(), new OnPropertiesChangedListener());
+        final String property = deviceConfig.getProperty(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                KEY_HIGH_REFRESH_RATE_BLACKLIST);
+        updateBlacklist(property);
+    }
 
-        // Read and populate the blacklist
-        final int length = Math.min(
-                propertyGetter.getInt(SYSPROP_KEY + SYSPROP_KEY_LENGTH_SUFFIX, 0),
-                MAX_ENTRIES);
-        for (int i = 1; i <= length; i++) {
-            final String packageName = propertyGetter.get(
-                    SYSPROP_KEY + SYSPROP_KEY_ENTRY_SUFFIX + i);
-            if (!packageName.isEmpty()) {
-                mBlacklistedPackages.add(packageName);
+    private void updateBlacklist(@Nullable String property) {
+        synchronized (mLock) {
+            mBlacklistedPackages.clear();
+            if (property != null) {
+                String[] packages = property.split(",");
+                for (String pkg : packages) {
+                    String pkgName = pkg.trim();
+                    if (!pkgName.isEmpty()) {
+                        mBlacklistedPackages.add(pkgName);
+                    }
+                }
+            } else {
+                // If there's no config, or the config has been deleted, fallback to the device's
+                // default blacklist
+                for (String pkg : mDefaultBlacklist) {
+                    mBlacklistedPackages.add(pkg);
+                }
             }
         }
     }
 
     boolean isBlacklisted(String packageName) {
-        return mBlacklistedPackages.contains(packageName);
+        synchronized (mLock) {
+            return mBlacklistedPackages.contains(packageName);
+        }
+    }
+    void dump(PrintWriter pw) {
+        pw.println("High Refresh Rate Blacklist");
+        pw.println("  Packages:");
+        synchronized (mLock) {
+            for (String pkg : mBlacklistedPackages) {
+                pw.println("    " + pkg);
+            }
+        }
     }
 
-    interface SystemPropertyGetter {
-        int getInt(String key, int def);
-        @NonNull String get(String key);
+    interface DeviceConfigInterface {
+        @Nullable String getProperty(@NonNull String namespace, @NonNull String name);
+        void addOnPropertiesChangedListener(@NonNull String namespace, @NonNull Executor executor,
+                @NonNull DeviceConfig.OnPropertiesChangedListener listener);
+    }
+
+    private class OnPropertiesChangedListener implements DeviceConfig.OnPropertiesChangedListener {
+        public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
+            updateBlacklist(
+                    properties.getString(KEY_HIGH_REFRESH_RATE_BLACKLIST, null /*default*/));
+        }
     }
 }
+
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index 6b500967..6830ade 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -133,7 +133,10 @@
     @Override
     public void notifyConfigurationChanged() {
         // TODO(multi-display): Notify proper displays that are associated with this input device.
-        mService.sendNewConfiguration(DEFAULT_DISPLAY);
+
+        synchronized (mService.mGlobalLock) {
+            mService.getDefaultDisplayContentLocked().sendNewConfiguration();
+        }
 
         synchronized (mInputDevicesReadyMonitor) {
             if (!mInputDevicesReady) {
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index d3dba90..2eec926 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -321,11 +321,10 @@
     }
 
     void updateInputWindowsImmediately() {
-        if (mUpdateInputWindowsPending) {
-            mApplyImmediately = true;
-            mUpdateInputWindows.run();
-            mApplyImmediately = false;
-        }
+        mHandler.removeCallbacks(mUpdateInputWindows);
+        mApplyImmediately = true;
+        mUpdateInputWindows.run();
+        mApplyImmediately = false;
     }
 
     /* Called when the current input focus changes.
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 169f03b..422b6e5 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -19,6 +19,7 @@
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
 import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
@@ -26,6 +27,7 @@
 import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
 import static android.view.WindowManager.TRANSIT_UNSET;
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
+import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
 
@@ -41,11 +43,13 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.Trace;
+import android.util.EventLog;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.server.am.EventLogTags;
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
 
@@ -140,6 +144,11 @@
         if (!keyguardChanged && !aodChanged) {
             return;
         }
+        EventLog.writeEvent(EventLogTags.AM_SET_KEYGUARD_SHOWN,
+                keyguardShowing ? 1 : 0,
+                aodShowing ? 1 : 0,
+                mKeyguardGoingAway ? 1 : 0,
+                "setKeyguardShown");
         mKeyguardShowing = keyguardShowing;
         mAodShowing = aodShowing;
         mWindowManager.setAodShowing(aodShowing);
@@ -176,6 +185,11 @@
         mWindowManager.deferSurfaceLayout();
         try {
             setKeyguardGoingAway(true);
+            EventLog.writeEvent(EventLogTags.AM_SET_KEYGUARD_SHOWN,
+                    1 /* keyguardShowing */,
+                    mAodShowing ? 1 : 0,
+                    1 /* keyguardGoingAway */,
+                    "keyguardGoingAway");
             mRootActivityContainer.getDefaultDisplay().mDisplayContent
                     .prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY,
                             false /* alwaysKeepCurrent */, convertTransitFlags(flags),
@@ -238,6 +252,9 @@
         if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) {
             result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
         }
+        if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS) != 0) {
+            result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
+        }
         return result;
     }
 
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index c3ea72f..bb035d5 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -261,7 +261,7 @@
 
         public void remove() {
             if (mSurface != null) {
-                mSurface.remove();
+                new SurfaceControl.Transaction().remove(mSurface).apply();
                 mSurface = null;
             }
             if (mInputInterceptor != null) {
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index ba23258..ef0049b 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -25,6 +25,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.annotation.NonNull;
 import android.app.RemoteAction;
 import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
@@ -45,6 +46,7 @@
 import android.view.IPinnedStackListener;
 
 import com.android.internal.policy.PipSnapAlgorithm;
+import com.android.internal.util.Preconditions;
 import com.android.server.UiThread;
 
 import java.io.PrintWriter;
@@ -326,8 +328,8 @@
     boolean onTaskStackBoundsChanged(Rect targetBounds, Rect outBounds) {
         synchronized (mService.mGlobalLock) {
             final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
-            if (mDisplayInfo.equals(displayInfo)) {
-                // We are already in the right orientation, ignore
+            if (isSameDimensionAndRotation(mDisplayInfo, displayInfo)) {
+                // No dimension/rotation change, ignore
                 outBounds.setEmpty();
                 return false;
             } else if (targetBounds.isEmpty()) {
@@ -348,7 +350,7 @@
             // Calculate the stack bounds in the new orientation to the same same fraction along the
             // rotated movement bounds.
             final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
-                    false /* adjustForIme */, false /* adjustForShelf */);
+                    false /* adjustForIme */);
             mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
                     snapFraction);
             if (mIsMinimized) {
@@ -427,6 +429,15 @@
         notifyActionsChanged(mActions);
     }
 
+    private boolean isSameDimensionAndRotation(@NonNull DisplayInfo display1,
+            @NonNull DisplayInfo display2) {
+        Preconditions.checkNotNull(display1);
+        Preconditions.checkNotNull(display2);
+        return ((display1.rotation == display2.rotation)
+                && (display1.logicalWidth == display2.logicalWidth)
+                && (display1.logicalHeight == display2.logicalHeight));
+    }
+
     /**
      * Notifies listeners that the PIP needs to be adjusted for the IME.
      */
@@ -529,8 +540,7 @@
      */
     private Rect getMovementBounds(Rect stackBounds) {
         synchronized (mService.mGlobalLock) {
-            return getMovementBounds(stackBounds, true /* adjustForIme */,
-                    true /* adjustForShelf */);
+            return getMovementBounds(stackBounds, true /* adjustForIme */);
         }
     }
 
@@ -538,15 +548,16 @@
      * @return the movement bounds for the given {@param stackBounds} and the current state of the
      *         controller.
      */
-    private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme, boolean adjustForShelf) {
+    private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
         synchronized (mService.mGlobalLock) {
             final Rect movementBounds = new Rect();
             getInsetBounds(movementBounds);
 
-            // Apply the movement bounds adjustments based on the current state
+            // Apply the movement bounds adjustments based on the current state.
+            // Note that shelf offset does not affect the movement bounds here
+            // since it's been taken care of in system UI.
             mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
-                    Math.max((adjustForIme && mIsImeShowing) ? mImeHeight : 0,
-                            (adjustForShelf && mIsShelfShowing) ? mShelfHeight : 0));
+                    (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
             return movementBounds;
         }
     }
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index e0ab722..541a8bb 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -308,11 +308,13 @@
      */
     @VisibleForTesting
     void resetFreezeTaskListReorderingOnTimeout() {
-        final ActivityStack focusedStack = mService.getTopDisplayFocusedStack();
-        final TaskRecord topTask = focusedStack != null
-                ? focusedStack.topTask()
-                : null;
-        resetFreezeTaskListReordering(topTask);
+        synchronized (mService.mGlobalLock) {
+            final ActivityStack focusedStack = mService.getTopDisplayFocusedStack();
+            final TaskRecord topTask = focusedStack != null
+                    ? focusedStack.topTask()
+                    : null;
+            resetFreezeTaskListReordering(topTask);
+        }
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 434239f..bf627ec 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -34,7 +34,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
 
 import android.app.ActivityOptions;
-import android.app.IAssistDataReceiver;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.os.RemoteException;
@@ -58,7 +57,12 @@
     private final ActivityStartController mActivityStartController;
     private final WindowManagerService mWindowManager;
     private final ActivityDisplay mDefaultDisplay;
+    private final Intent mTargetIntent;
+    private final ComponentName mRecentsComponent;
+    private final int mRecentsUid;
     private final int mCallingPid;
+    private final int mUserId;
+    private final int mTargetActivityType;
 
     /**
      * The activity which has been launched behind. We need to remember the activity because the
@@ -66,27 +70,90 @@
      * for the exact activity.
      */
     private ActivityRecord mLaunchedTargetActivity;
-    private int mTargetActivityType;
 
     // The stack to restore the target stack behind when the animation is finished
     private ActivityStack mRestoreTargetBehindStack;
 
     RecentsAnimation(ActivityTaskManagerService atm, ActivityStackSupervisor stackSupervisor,
             ActivityStartController activityStartController, WindowManagerService wm,
-            int callingPid) {
+            Intent targetIntent, ComponentName recentsComponent, int recentsUid, int callingPid) {
         mService = atm;
         mStackSupervisor = stackSupervisor;
         mDefaultDisplay = mService.mRootActivityContainer.getDefaultDisplay();
         mActivityStartController = activityStartController;
         mWindowManager = wm;
+        mTargetIntent = targetIntent;
+        mRecentsComponent = recentsComponent;
+        mRecentsUid = recentsUid;
         mCallingPid = callingPid;
+        mUserId = atm.getCurrentUserId();
+        mTargetActivityType = targetIntent.getComponent() != null
+                && recentsComponent.equals(targetIntent.getComponent())
+                        ? ACTIVITY_TYPE_RECENTS
+                        : ACTIVITY_TYPE_HOME;
     }
 
-    void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner,
-            ComponentName recentsComponent, int recentsUid,
-            @Deprecated IAssistDataReceiver assistDataReceiver) {
-        if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + intent
-                + " assistDataReceiver=" + assistDataReceiver);
+    /**
+     * Starts the recents activity in background without animation if the record doesn't exist or
+     * the client isn't launched. If the recents activity is already alive, ensure its configuration
+     * is updated to the current one.
+     */
+    void preloadRecentsActivity() {
+        if (DEBUG) Slog.d(TAG, "Preload recents with " + mTargetIntent);
+        ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
+                mTargetActivityType);
+        ActivityRecord targetActivity = getTargetActivity(targetStack);
+        if (targetActivity != null) {
+            if (targetActivity.visible || targetActivity.isTopRunningActivity()) {
+                // The activity is ready.
+                return;
+            }
+            if (targetActivity.attachedToProcess()) {
+                // The activity may be relaunched if it cannot handle the current configuration
+                // changes. The activity will be paused state if it is relaunched, otherwise it
+                // keeps the original stopped state.
+                targetActivity.ensureActivityConfiguration(0 /* globalChanges */,
+                        false /* preserveWindow */, true /* ignoreVisibility */);
+                if (DEBUG) Slog.d(TAG, "Updated config=" + targetActivity.getConfiguration());
+            }
+        } else {
+            // Create the activity record. Because the activity is invisible, this doesn't really
+            // start the client.
+            startRecentsActivityInBackground("preloadRecents");
+            targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType);
+            targetActivity = getTargetActivity(targetStack);
+            if (targetActivity == null) {
+                Slog.w(TAG, "Cannot start " + mTargetIntent);
+                return;
+            }
+        }
+
+        if (!targetActivity.attachedToProcess()) {
+            if (DEBUG) Slog.d(TAG, "Real start recents");
+            mStackSupervisor.startSpecificActivityLocked(targetActivity, false /* andResume */,
+                    false /* checkConfig */);
+            // Make sure the activity won't be involved in transition.
+            if (targetActivity.mAppWindowToken != null) {
+                targetActivity.mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
+                        .appRemovedOrHidden(targetActivity.mAppWindowToken);
+            }
+        }
+
+        // Invisible activity should be stopped. If the recents activity is alive and its doesn't
+        // need to relaunch by current configuration, then it may be already in stopped state.
+        if (!targetActivity.isState(ActivityStack.ActivityState.STOPPING,
+                ActivityStack.ActivityState.STOPPED)) {
+            // Add to stopping instead of stop immediately. So the client has the chance to perform
+            // traversal in non-stopped state (ViewRootImpl.mStopped) that would initialize more
+            // things (e.g. the measure can be done earlier). The actual stop will be performed when
+            // it reports idle.
+            targetStack.addToStopping(targetActivity, true /* scheduleIdle */,
+                    true /* idleDelayed */, "preloadRecents");
+        }
+    }
+
+    void startRecentsActivity(IRecentsAnimationRunner recentsAnimationRunner) {
+        if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + mTargetIntent);
         Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity");
 
         // TODO(multi-display) currently only support recents animation in default display.
@@ -100,15 +167,9 @@
         }
 
         // If the activity is associated with the recents stack, then try and get that first
-        final int userId = mService.getCurrentUserId();
-        mTargetActivityType = intent.getComponent() != null
-                && recentsComponent.equals(intent.getComponent())
-                        ? ACTIVITY_TYPE_RECENTS
-                        : ACTIVITY_TYPE_HOME;
         ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
                 mTargetActivityType);
-        ActivityRecord targetActivity = getTargetActivity(targetStack, intent.getComponent(),
-                userId);
+        ActivityRecord targetActivity = getTargetActivity(targetStack);
         final boolean hasExistingActivity = targetActivity != null;
         if (hasExistingActivity) {
             final ActivityDisplay display = targetActivity.getDisplay();
@@ -127,7 +188,7 @@
                     true /* forceSend */, targetActivity);
         }
 
-        mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
+        mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mTargetIntent);
 
         mService.mH.post(() -> mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, true));
 
@@ -148,23 +209,12 @@
                 }
             } else {
                 // No recents activity, create the new recents activity bottom most
-                ActivityOptions options = ActivityOptions.makeBasic();
-                options.setLaunchActivityType(mTargetActivityType);
-                options.setAvoidMoveToFront();
-                intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
-
-                mActivityStartController
-                        .obtainStarter(intent, "startRecentsActivity_noTargetActivity")
-                        .setCallingUid(recentsUid)
-                        .setCallingPackage(recentsComponent.getPackageName())
-                        .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle()))
-                        .setMayWait(userId)
-                        .execute();
+                startRecentsActivityInBackground("startRecentsActivity_noTargetActivity");
 
                 // Move the recents activity into place for the animation
                 targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
                         mTargetActivityType);
-                targetActivity = getTargetActivity(targetStack, intent.getComponent(), userId);
+                targetActivity = getTargetActivity(targetStack);
                 mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
                 if (DEBUG) {
                     Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
@@ -176,7 +226,7 @@
 
                 // TODO: Maybe wait for app to draw in this particular case?
 
-                if (DEBUG) Slog.d(TAG, "Started intent=" + intent);
+                if (DEBUG) Slog.d(TAG, "Started intent=" + mTargetIntent);
             }
 
             // Mark the target activity as launch-behind to bump its visibility for the
@@ -383,6 +433,21 @@
         }
     }
 
+    private void startRecentsActivityInBackground(String reason) {
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchActivityType(mTargetActivityType);
+        options.setAvoidMoveToFront();
+        mTargetIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
+
+        mActivityStartController
+                .obtainStarter(mTargetIntent, reason)
+                .setCallingUid(mRecentsUid)
+                .setCallingPackage(mRecentsComponent.getPackageName())
+                .setActivityOptions(new SafeActivityOptions(options))
+                .setMayWait(mUserId)
+                .execute();
+    }
+
     /**
      * Called only when the animation should be canceled prior to starting.
      */
@@ -412,15 +477,15 @@
      * @return the top activity in the {@param targetStack} matching the {@param component}, or just
      * the top activity of the top task if no task matches the component.
      */
-    private ActivityRecord getTargetActivity(ActivityStack targetStack, ComponentName component,
-            int userId) {
+    private ActivityRecord getTargetActivity(ActivityStack targetStack) {
         if (targetStack == null) {
             return null;
         }
 
         for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
             final TaskRecord task = targetStack.getChildAt(i);
-            if (task.userId == userId && task.getBaseIntent().getComponent().equals(component)) {
+            if (task.userId == mUserId
+                    && task.getBaseIntent().getComponent().equals(mTargetIntent.getComponent())) {
                 return task.getTopActivity();
             }
         }
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index c03dabe..163be1e 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
 
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
 import static com.android.server.wm.AnimationAdapterProto.REMOTE;
@@ -651,8 +652,8 @@
     }
 
     boolean isWallpaperVisible(WindowState w) {
-        return w != null && w.mAppToken != null && mTargetAppToken == w.mAppToken
-                && isTargetOverWallpaper();
+        return w != null && w.mAttrs.type == TYPE_BASE_APPLICATION && w.mAppToken != null
+                && mTargetAppToken == w.mAppToken && isTargetOverWallpaper();
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index d58c613..66d42db 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -317,11 +317,6 @@
         return activityDisplay;
     }
 
-    /** Check if display with specified id is added to the list. */
-    boolean isDisplayAdded(int displayId) {
-        return getActivityDisplayOrCreate(displayId) != null;
-    }
-
     ActivityRecord getDefaultDisplayHomeActivity() {
         return getDefaultDisplayHomeActivityForUser(mCurrentUser);
     }
@@ -656,9 +651,13 @@
             starting.frozenBeforeDestroy = true;
         }
 
-        // Update the configuration of the activities on the display.
-        return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
-                displayId);
+        if (displayContent != null && displayContent.mAcitvityDisplay != null) {
+            // Update the configuration of the activities on the display.
+            return displayContent.mAcitvityDisplay.updateDisplayOverrideConfigurationLocked(config,
+                    starting, deferResume, null /* result */);
+        } else {
+            return true;
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 8a5f52f..a00bee0 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -248,8 +248,6 @@
             dc.configureDisplayPolicy();
         }
 
-        mWmService.reconfigureDisplayLocked(dc);
-
         return dc;
     }
 
@@ -267,7 +265,7 @@
             }
 
             displayContent.initializeDisplayOverrideConfiguration();
-            mWmService.reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
 
             // We need to update global configuration as well if config of default display has
             // changed. Do it inline because ATMS#retrieveSettings() will soon update the
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index b90d602..dc62877 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -279,7 +279,8 @@
                 mService.mDisplayManagerInternal.screenshot(displayId);
             if (gb != null) {
                 try {
-                    surface.attachAndQueueBuffer(gb.getGraphicBuffer());
+                    surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),
+                            gb.getColorSpace());
                 } catch (RuntimeException e) {
                     Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
                 }
@@ -557,7 +558,7 @@
                 Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
                         mOriginalWidth*2, mOriginalHeight*2);
                 Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
-                mCustomBlackFrame = new BlackFrame(t, outer, inner,
+                mCustomBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
                         SCREEN_FREEZE_LAYER_CUSTOM, mDisplayContent, false);
                 mCustomBlackFrame.setMatrix(t, mFrameInitialMatrix);
             } catch (OutOfResourcesException e) {
@@ -588,7 +589,7 @@
                             mOriginalWidth*2, mOriginalHeight*2);
                     inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
                 }
-                mExitingBlackFrame = new BlackFrame(t, outer, inner,
+                mExitingBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
                         SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation);
                 mExitingBlackFrame.setMatrix(t, mFrameInitialMatrix);
             } catch (OutOfResourcesException e) {
@@ -601,7 +602,7 @@
                 Rect outer = new Rect(-finalWidth*1, -finalHeight*1,
                         finalWidth*2, finalHeight*2);
                 Rect inner = new Rect(0, 0, finalWidth, finalHeight);
-                mEnteringBlackFrame = new BlackFrame(t, outer, inner,
+                mEnteringBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner,
                         SCREEN_FREEZE_LAYER_ENTER, mDisplayContent, false);
             } catch (OutOfResourcesException e) {
                 Slog.w(TAG, "Unable to allocate black surface", e);
@@ -639,7 +640,7 @@
             if (SHOW_TRANSACTIONS ||
                     SHOW_SURFACE_ALLOC) Slog.i(TAG_WM,
                             "  FREEZE " + mSurfaceControl + ": DESTROY");
-            mSurfaceControl.remove();
+            mService.mTransactionFactory.make().remove(mSurfaceControl).apply();
             mSurfaceControl = null;
         }
         if (mCustomBlackFrame != null) {
diff --git a/services/core/java/com/android/server/wm/SeamlessRotator.java b/services/core/java/com/android/server/wm/SeamlessRotator.java
index 05f556c..bcd90a1 100644
--- a/services/core/java/com/android/server/wm/SeamlessRotator.java
+++ b/services/core/java/com/android/server/wm/SeamlessRotator.java
@@ -100,9 +100,9 @@
         t.setPosition(win.mSurfaceControl, win.mLastSurfacePosition.x, win.mLastSurfacePosition.y);
         if (win.mWinAnimator.mSurfaceController != null && !timeout) {
             t.deferTransactionUntil(win.mSurfaceControl,
-                    win.mWinAnimator.mSurfaceController.getHandle(), win.getFrameNumber());
+                    win.mWinAnimator.mSurfaceController.mSurfaceControl, win.getFrameNumber());
             t.deferTransactionUntil(win.mWinAnimator.mSurfaceController.mSurfaceControl,
-                    win.mWinAnimator.mSurfaceController.getHandle(), win.getFrameNumber());
+                    win.mWinAnimator.mSurfaceController.mSurfaceControl, win.getFrameNumber());
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index ecb0941..9f8f265 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -28,6 +28,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.annotation.Nullable;
 import android.content.ClipData;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -225,10 +226,11 @@
     }
 
     @Override
-    public void finishDrawing(IWindow window) {
+    public void finishDrawing(IWindow window,
+            @Nullable SurfaceControl.Transaction postDrawTransaction) {
         if (WindowManagerService.localLOGV) Slog.v(
             TAG_WM, "IWindow finishDrawing called for " + window);
-        mService.finishDrawingWindow(this, window);
+        mService.finishDrawingWindow(this, window, postDrawTransaction);
     }
 
     @Override
@@ -610,4 +612,16 @@
     boolean hasAlertWindowSurfaces() {
         return !mAlertWindowSurfaces.isEmpty();
     }
+
+    public void blessInputSurface(int displayId, SurfaceControl surface,
+            InputChannel outInputChannel) {
+        final int callerUid = Binder.getCallingUid();
+        final int callerPid = Binder.getCallingPid();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mService.blessInputSurface(callerUid, callerPid, displayId, surface, outInputChannel);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 3820106..fd86faa 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -348,6 +348,9 @@
     void onDisplayChanged(DisplayContent dc) {
         adjustBoundsForDisplayChangeIfNeeded(dc);
         super.onDisplayChanged(dc);
+        final int displayId = (dc != null) ? dc.getDisplayId() : Display.INVALID_DISPLAY;
+        mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged(
+                mTaskId, displayId);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 27175c7..f776062 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -55,6 +55,7 @@
     private static final int NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG = 20;
     private static final int NOTIFY_BACK_PRESSED_ON_TASK_ROOT = 21;
     private static final int NOTIFY_SINGLE_TASK_DISPLAY_DRAWN = 22;
+    private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 23;
 
     // Delay in notifying task stack change listeners (in millis)
     private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -159,6 +160,10 @@
         l.onSingleTaskDisplayDrawn(m.arg1);
     };
 
+    private final TaskStackConsumer mNotifyTaskDisplayChanged = (l, m) -> {
+        l.onTaskDisplayChanged(m.arg1, m.arg2);
+    };
+
     @FunctionalInterface
     public interface TaskStackConsumer {
         void accept(ITaskStackListener t, Message m) throws RemoteException;
@@ -241,6 +246,9 @@
                 case NOTIFY_SINGLE_TASK_DISPLAY_DRAWN:
                     forAllRemoteListeners(mNotifySingleTaskDisplayDrawn, msg);
                     break;
+                case NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG:
+                    forAllRemoteListeners(mNotifyTaskDisplayChanged, msg);
+                    break;
             }
         }
     }
@@ -495,4 +503,14 @@
         forAllLocalListeners(mNotifySingleTaskDisplayDrawn, msg);
         msg.sendToTarget();
     }
+
+    /**
+     * Notify listeners that a task is reparented to another display.
+     */
+    void notifyTaskDisplayChanged(int taskId, int newDisplayId) {
+        final Message msg = mHandler.obtainMessage(NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG,
+                taskId, newDisplayId);
+        forAllLocalListeners(mNotifyTaskStackChanged, msg);
+        msg.sendToTarget();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 14585c5..0d18b30 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -211,7 +211,9 @@
         if (!currentParams.isEmpty() && !hasInitialBounds
                 && (!currentParams.hasPreferredDisplay()
                     || displayId == currentParams.mPreferredDisplayId)) {
-            if (currentParams.hasWindowingMode()) {
+            // Only set windowing mode if display is in freeform. If the display is in fullscreen
+            // mode we should only launch a task in fullscreen mode.
+            if (currentParams.hasWindowingMode() && display.inFreeformWindowingMode()) {
                 launchMode = currentParams.mWindowingMode;
                 fullyResolvedCurrentParam = launchMode != WINDOWING_MODE_FREEFORM;
                 if (DEBUG) {
@@ -276,7 +278,7 @@
                 // an existing task.
                 adjustBoundsToAvoidConflictInDisplay(display, outParams.mBounds);
             }
-        } else {
+        } else if (display.inFreeformWindowingMode()) {
             if (source != null && source.inFreeformWindowingMode()
                     && resolvedMode == WINDOWING_MODE_FREEFORM
                     && outParams.mBounds.isEmpty()
@@ -421,8 +423,8 @@
      * @return {@code true} if it should be forced to maximize; {@code false} otherwise.
      */
     private boolean isTaskForcedMaximized(@NonNull ActivityRecord root) {
-        if (root.appInfo.targetSdkVersion < Build.VERSION_CODES.DONUT
-                || (root.appInfo.flags & SUPPORTS_SCREEN_RESIZEABLE_MASK) == 0) {
+        if (root.info.applicationInfo.targetSdkVersion < Build.VERSION_CODES.DONUT
+                || (root.info.applicationInfo.flags & SUPPORTS_SCREEN_RESIZEABLE_MASK) == 0) {
             return true;
         }
 
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 298b302..23515d8 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -851,11 +851,12 @@
     /**
      * DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
      */
-    TaskSnapshot getSnapshot(boolean reducedResolution) {
+    TaskSnapshot getSnapshot(boolean reducedResolution, boolean restoreFromDisk) {
 
         // TODO: Move this to {@link TaskWindowContainerController} once recent tasks are more
         // synchronized between AM and WM.
-        return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution);
+        return mService.mWindowManager.getTaskSnapshot(taskId, userId, reducedResolution,
+                restoreFromDisk);
     }
 
     void touchActiveTime() {
@@ -1112,16 +1113,14 @@
         return intent != null ? intent : affinityIntent;
     }
 
-    /** Returns the first non-finishing activity from the root. */
+    /** Returns the first non-finishing activity from the bottom. */
     ActivityRecord getRootActivity() {
-        for (int i = 0; i < mActivities.size(); i++) {
-            final ActivityRecord r = mActivities.get(i);
-            if (r.finishing) {
-                continue;
-            }
-            return r;
+        final int rootActivityIndex = findRootIndex(false /* effectiveRoot */);
+        if (rootActivityIndex == -1) {
+            // There are no non-finishing activities in the task.
+            return null;
         }
-        return null;
+        return mActivities.get(rootActivityIndex);
     }
 
     ActivityRecord getTopActivity() {
@@ -1236,27 +1235,6 @@
                 || topRunningActivityLocked() != null;
     }
 
-    /** Call after activity movement or finish to make sure that frontOfTask is set correctly */
-    final void setFrontOfTask() {
-        boolean foundFront = false;
-        final int numActivities = mActivities.size();
-        for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) {
-            final ActivityRecord r = mActivities.get(activityNdx);
-            if (foundFront || r.finishing) {
-                r.frontOfTask = false;
-            } else {
-                r.frontOfTask = true;
-                // Set frontOfTask false for every following activity.
-                foundFront = true;
-            }
-        }
-        if (!foundFront && numActivities > 0) {
-            // All activities of this task are finishing. As we ought to have a frontOfTask
-            // activity, make the bottom activity front.
-            mActivities.get(0).frontOfTask = true;
-        }
-    }
-
     /**
      * Reorder the history stack so that the passed activity is brought to the front.
      */
@@ -1271,8 +1249,6 @@
         // Make sure window manager is aware of the position change.
         mTask.positionChildAtTop(newTop.mAppWindowToken);
         updateEffectiveIntent();
-
-        setFrontOfTask();
     }
 
     void addActivityToTop(ActivityRecord r) {
@@ -1442,8 +1418,8 @@
                 mActivities.remove(activityNdx);
                 --activityNdx;
                 --numActivities;
-            } else if (mStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null,
-                    reason, false, pauseImmediately)) {
+            } else if (r.finishActivityLocked(Activity.RESULT_CANCELED, null,
+                    reason, false /* oomAdj */, pauseImmediately)) {
                 --activityNdx;
                 --numActivities;
             }
@@ -1497,8 +1473,8 @@
                     if (opts != null) {
                         ret.updateOptionsLocked(opts);
                     }
-                    if (mStack != null && mStack.finishActivityLocked(
-                            r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
+                    if (r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+                            "clear-task-stack", false /* oomAdj */)) {
                         --activityNdx;
                         --numActivities;
                     }
@@ -1511,10 +1487,8 @@
                         && (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0
                         && !ActivityStarter.isDocumentLaunchesIntoExisting(launchFlags)) {
                     if (!ret.finishing) {
-                        if (mStack != null) {
-                            mStack.finishActivityLocked(
-                                    ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
-                        }
+                        ret.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+                                "clear-task-top", false /* oomAdj */);
                         return null;
                     }
                 }
@@ -1657,6 +1631,7 @@
 
     /** Updates the last task description values. */
     void updateTaskDescription() {
+        // TODO(AM refactor): Cleanup to use findRootIndex()
         // Traverse upwards looking for any break between main task activities and
         // utility activities.
         int activityNdx;
@@ -1735,8 +1710,19 @@
         }
     }
 
-    int findEffectiveRootIndex() {
-        int effectiveNdx = 0;
+    /**
+     * Find the index of the root activity in the task. It will be the first activity from the
+     * bottom that is not finishing.
+     *
+     * @param effectiveRoot Flag indicating whether 'effective root' should be returned - an
+     *                      activity that defines the task identity (its base intent). It's the
+     *                      first one that does not have
+     *                      {@link ActivityInfo#FLAG_RELINQUISH_TASK_IDENTITY}.
+     * @return index of the 'root' or 'effective' root in the list of activities, -1 if no eligible
+     *         activity was found.
+     */
+    int findRootIndex(boolean effectiveRoot) {
+        int effectiveNdx = -1;
         final int topActivityNdx = mActivities.size() - 1;
         for (int activityNdx = 0; activityNdx <= topActivityNdx; ++activityNdx) {
             final ActivityRecord r = mActivities.get(activityNdx);
@@ -1744,15 +1730,22 @@
                 continue;
             }
             effectiveNdx = activityNdx;
-            if ((r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
+            if (!effectiveRoot || (r.info.flags & FLAG_RELINQUISH_TASK_IDENTITY) == 0) {
                 break;
             }
         }
         return effectiveNdx;
     }
 
+    // TODO (AM refactor): Invoke automatically when there is a change in children
+    @VisibleForTesting
     void updateEffectiveIntent() {
-        final int effectiveRootIndex = findEffectiveRootIndex();
+        int effectiveRootIndex = findRootIndex(true /* effectiveRoot */);
+        if (effectiveRootIndex == -1) {
+            // All activities in the task are either finishing or relinquish task identity.
+            // But we still want to update the intent, so let's use the bottom activity.
+            effectiveRootIndex = 0;
+        }
         final ActivityRecord r = mActivities.get(effectiveRootIndex);
         setIntent(r);
 
@@ -1907,7 +1900,7 @@
     /**
      * Saves launching state if necessary so that we can launch the activity to its latest state.
      * It only saves state if this task has been shown to user and it's in fullscreen or freeform
-     * mode.
+     * mode on freeform displays.
      */
     void saveLaunchingStateIfNeeded() {
         if (!hasBeenVisible) {
@@ -1916,8 +1909,15 @@
         }
 
         final int windowingMode = getWindowingMode();
-        if (windowingMode != WindowConfiguration.WINDOWING_MODE_FULLSCREEN
-                && windowingMode != WindowConfiguration.WINDOWING_MODE_FREEFORM) {
+        if (windowingMode != WINDOWING_MODE_FULLSCREEN
+                && windowingMode != WINDOWING_MODE_FREEFORM) {
+            return;
+        }
+
+        // Don't persist state if display isn't in freeform mode. Then the task will be launched
+        // back to its last state in a freeform display when it's launched in a freeform display
+        // next time.
+        if (getWindowConfiguration().getDisplayWindowingMode() != WINDOWING_MODE_FREEFORM) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index ee4e462..1a57168 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -47,8 +47,7 @@
         }
         final Rect tmpRect = task.getBounds();
         tmpRect.offset(0, 0);
-        return SurfaceControl.captureLayers(
-                task.getSurfaceControl().getHandle(), tmpRect, 1f);
+        return SurfaceControl.captureLayers(task.getSurfaceControl(), tmpRect, 1f);
     }
 
     private TaskScreenshotAnimatable(Task task,
@@ -69,7 +68,7 @@
         if (buffer != null) {
             final Surface surface = new Surface();
             surface.copyFrom(mSurfaceControl);
-            surface.attachAndQueueBuffer(buffer);
+            surface.attachAndQueueBufferWithColorSpace(buffer, screenshotBuffer.getColorSpace());
             surface.release();
         }
         getPendingTransaction().show(mSurfaceControl);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 1815218..f9a6fe7 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -95,6 +95,7 @@
     private final ArraySet<Task> mSkipClosingAppSnapshotTasks = new ArraySet<>();
     private final ArraySet<Task> mTmpTasks = new ArraySet<>();
     private final Handler mHandler = new Handler();
+    private final float mFullSnapshotScale;
 
     private final Rect mTmpRect = new Rect();
 
@@ -124,6 +125,8 @@
                 PackageManager.FEATURE_EMBEDDED);
         mIsRunningOnWear = mService.mContext.getPackageManager().hasSystemFeature(
             PackageManager.FEATURE_WATCH);
+        mFullSnapshotScale = mService.mContext.getResources().getFloat(
+                com.android.internal.R.dimen.config_fullTaskSnapshotScale);
     }
 
     void systemReady() {
@@ -255,7 +258,7 @@
         mTmpRect.offsetTo(0, 0);
         final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
                 SurfaceControl.captureLayers(
-                        task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
+                        task.getSurfaceControl(), mTmpRect, scaleFraction);
         final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer()
                 : null;
         if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
@@ -287,7 +290,9 @@
         }
 
         final boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
-        final float scaleFraction = isLowRamDevice ? mPersister.getReducedScale() : 1f;
+        final float scaleFraction = isLowRamDevice
+                ? mPersister.getReducedScale()
+                : mFullSnapshotScale;
 
         final WindowState mainWindow = appWindowToken.findMainWindow();
         if (mainWindow == null) {
@@ -305,8 +310,10 @@
         }
         final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
         return new TaskSnapshot(
+                System.currentTimeMillis() /* id */,
                 appWindowToken.mActivityComponent, screenshotBuffer.getGraphicBuffer(),
-                screenshotBuffer.getColorSpace(), appWindowToken.getConfiguration().orientation,
+                screenshotBuffer.getColorSpace(),
+                appWindowToken.getTask().getConfiguration().orientation,
                 getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */,
                 true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
                 !appWindowToken.fillsParent() || isWindowTranslucent);
@@ -378,9 +385,10 @@
                 task.getTaskDescription().getBackgroundColor(), 255);
         final LayoutParams attrs = mainWindow.getAttrs();
         final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,
-                attrs.privateFlags, attrs.systemUiVisibility, task.getTaskDescription());
-        final int width = mainWindow.getFrameLw().width();
-        final int height = mainWindow.getFrameLw().height();
+                attrs.privateFlags, attrs.systemUiVisibility, task.getTaskDescription(),
+                mFullSnapshotScale);
+        final int width = (int) (task.getBounds().width() * mFullSnapshotScale);
+        final int height = (int) (task.getBounds().height() * mFullSnapshotScale);
 
         final RenderNode node = RenderNode.create("TaskSnapshotController", null);
         node.setLeftTopRightBottom(0, 0, width, height);
@@ -394,12 +402,15 @@
         if (hwBitmap == null) {
             return null;
         }
+
         // Note, the app theme snapshot is never translucent because we enforce a non-translucent
         // color above
-        return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
-                hwBitmap.getColorSpace(), topChild.getConfiguration().orientation,
-                mainWindow.getStableInsets(), ActivityManager.isLowRamDeviceStatic() /* reduced */,
-                1.0f /* scale */, false /* isRealSnapshot */, task.getWindowingMode(),
+        return new TaskSnapshot(
+                System.currentTimeMillis() /* id */,
+                topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
+                hwBitmap.getColorSpace(), topChild.getTask().getConfiguration().orientation,
+                getInsets(mainWindow), ActivityManager.isLowRamDeviceStatic() /* reduced */,
+                mFullSnapshotScale, false /* isRealSnapshot */, task.getWindowingMode(),
                 getSystemUiVisibility(task), false);
     }
 
@@ -481,6 +492,7 @@
     }
 
     void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "mFullSnapshotScale=" + mFullSnapshotScale);
         mCache.dump(pw, prefix);
     }
 }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
index f7b8945..696e1c3 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
@@ -87,14 +87,16 @@
                         + bitmapFile.getPath());
                 return null;
             }
-            ComponentName topActivityComponent = ComponentName.unflattenFromString(
+            final ComponentName topActivityComponent = ComponentName.unflattenFromString(
                     proto.topActivityComponent);
-            return new TaskSnapshot(topActivityComponent, buffer, bitmap.getColorSpace(),
+            // For legacy snapshots, restore the scale based on the reduced resolution state
+            final float legacyScale = reducedResolution ? mPersister.getReducedScale() : 1f;
+            final float scale = Float.compare(proto.scale, 0f) != 0 ? proto.scale : legacyScale;
+            return new TaskSnapshot(proto.id, topActivityComponent, buffer, bitmap.getColorSpace(),
                     proto.orientation,
                     new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
-                    reducedResolution, reducedResolution ? mPersister.getReducedScale() : 1f,
-                    proto.isRealSnapshot, proto.windowingMode, proto.systemUiVisibility,
-                    proto.isTranslucent);
+                    reducedResolution, scale, proto.isRealSnapshot, proto.windowingMode,
+                    proto.systemUiVisibility, proto.isTranslucent);
         } catch (IOException e) {
             Slog.w(TAG, "Unable to load task snapshot data for taskId=" + taskId);
             return null;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 0b63f48..32a1d90 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -342,6 +342,8 @@
             proto.systemUiVisibility = mSnapshot.getSystemUiVisibility();
             proto.isTranslucent = mSnapshot.isTranslucent();
             proto.topActivityComponent = mSnapshot.getTopActivityComponent().flattenToString();
+            proto.scale = mSnapshot.getScale();
+            proto.id = mSnapshot.getId();
             final byte[] bytes = TaskSnapshotProto.toByteArray(proto);
             final File file = getProtoFile(mTaskId, mUserId);
             final AtomicFile atomicFile = new AtomicFile(file);
@@ -369,12 +371,13 @@
             }
 
             final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
-            final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
             final Bitmap reduced = mSnapshot.isReducedResolution()
                     ? swBitmap
                     : Bitmap.createScaledBitmap(swBitmap,
                             (int) (bitmap.getWidth() * mReducedScale),
                             (int) (bitmap.getHeight() * mReducedScale), true /* filter */);
+
+            final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
             try {
                 FileOutputStream reducedFos = new FileOutputStream(reducedFile);
                 reduced.compress(JPEG, QUALITY, reducedFos);
@@ -383,6 +386,7 @@
                 Slog.e(TAG, "Unable to open " + reducedFile +" for persisting.", e);
                 return false;
             }
+            reduced.recycle();
 
             // For snapshots with reduced resolution, do not create or save full sized bitmaps
             if (mSnapshot.isReducedResolution()) {
@@ -399,7 +403,6 @@
                 Slog.e(TAG, "Unable to open " + file + " for persisting.", e);
                 return false;
             }
-            reduced.recycle();
             swBitmap.recycle();
             return true;
         }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 5d99db5..1b3e4c1 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -248,7 +248,7 @@
         mBackgroundPaint.setColor(backgroundColor != 0 ? backgroundColor : WHITE);
         mTaskBounds = taskBounds;
         mSystemBarBackgroundPainter = new SystemBarBackgroundPainter(windowFlags,
-                windowPrivateFlags, sysUiVis, taskDescription);
+                windowPrivateFlags, sysUiVis, taskDescription, 1f);
         mStatusBarColor = taskDescription.getStatusBarColor();
         mOrientationOnCreation = currentOrientation;
     }
@@ -284,7 +284,6 @@
     }
 
     private void drawSnapshot() {
-        final GraphicBuffer buffer = mSnapshot.getSnapshot();
         mSurface.copyFrom(mSurfaceControl);
 
         if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Drawing snapshot surface sizeMismatch="
@@ -293,9 +292,9 @@
             // The dimensions of the buffer and the window don't match, so attaching the buffer
             // will fail. Better create a child window with the exact dimensions and fill the parent
             // window with the background color!
-            drawSizeMismatchSnapshot(buffer);
+            drawSizeMismatchSnapshot();
         } else {
-            drawSizeMatchSnapshot(buffer);
+            drawSizeMatchSnapshot();
         }
         synchronized (mService.mGlobalLock) {
             mShownTime = SystemClock.uptimeMillis();
@@ -307,16 +306,23 @@
         mSnapshot = null;
     }
 
-    private void drawSizeMatchSnapshot(GraphicBuffer buffer) {
-        mSurface.attachAndQueueBuffer(buffer);
+    private void drawSizeMatchSnapshot() {
+        mSurface.attachAndQueueBufferWithColorSpace(mSnapshot.getSnapshot(),
+                mSnapshot.getColorSpace());
         mSurface.release();
     }
 
-    private void drawSizeMismatchSnapshot(GraphicBuffer buffer) {
+    private void drawSizeMismatchSnapshot() {
         if (!mSurface.isValid()) {
             throw new IllegalStateException("mSurface does not hold a valid surface.");
         }
+        final GraphicBuffer buffer = mSnapshot.getSnapshot();
         final SurfaceSession session = new SurfaceSession();
+        // We consider nearly matched dimensions as there can be rounding errors and the user won't
+        // notice very minute differences from scaling one dimension more than the other
+        final boolean aspectRatioMismatch = Math.abs(
+                ((float) buffer.getWidth() / buffer.getHeight())
+                - ((float) mFrame.width() / mFrame.height())) > 0.01f;
 
         // Keep a reference to it such that it doesn't get destroyed when finalized.
         mChildSurfaceControl = new SurfaceControl.Builder(session)
@@ -328,16 +334,21 @@
         Surface surface = new Surface();
         surface.copyFrom(mChildSurfaceControl);
 
-        // Clip off ugly navigation bar.
-        final Rect crop = calculateSnapshotCrop();
-        final Rect frame = calculateSnapshotFrame(crop);
+        final Rect frame;
         SurfaceControl.openTransaction();
         try {
             // We can just show the surface here as it will still be hidden as the parent is
             // still hidden.
             mChildSurfaceControl.show();
-            mChildSurfaceControl.setWindowCrop(crop);
-            mChildSurfaceControl.setPosition(frame.left, frame.top);
+            if (aspectRatioMismatch) {
+                // Clip off ugly navigation bar.
+                final Rect crop = calculateSnapshotCrop();
+                frame = calculateSnapshotFrame(crop);
+                mChildSurfaceControl.setWindowCrop(crop);
+                mChildSurfaceControl.setPosition(frame.left, frame.top);
+            } else {
+                frame = null;
+            }
 
             // Scale the mismatch dimensions to fill the task bounds
             final float scale = 1 / mSnapshot.getScale();
@@ -345,13 +356,15 @@
         } finally {
             SurfaceControl.closeTransaction();
         }
-        surface.attachAndQueueBuffer(buffer);
+        surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace());
         surface.release();
 
-        final Canvas c = mSurface.lockCanvas(null);
-        drawBackgroundAndBars(c, frame);
-        mSurface.unlockCanvasAndPost(c);
-        mSurface.release();
+        if (aspectRatioMismatch) {
+            final Canvas c = mSurface.lockCanvas(null);
+            drawBackgroundAndBars(c, frame);
+            mSurface.unlockCanvasAndPost(c);
+            mSurface.release();
+        }
     }
 
     /**
@@ -418,7 +431,7 @@
 
     private void reportDrawn() {
         try {
-            mSession.finishDrawing(mWindow);
+            mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
         } catch (RemoteException e) {
             // Local call.
         }
@@ -488,12 +501,14 @@
         private final int mWindowFlags;
         private final int mWindowPrivateFlags;
         private final int mSysUiVis;
+        private final float mScale;
 
-        SystemBarBackgroundPainter( int windowFlags, int windowPrivateFlags, int sysUiVis,
-                TaskDescription taskDescription) {
+        SystemBarBackgroundPainter(int windowFlags, int windowPrivateFlags, int sysUiVis,
+                TaskDescription taskDescription, float scale) {
             mWindowFlags = windowFlags;
             mWindowPrivateFlags = windowPrivateFlags;
             mSysUiVis = sysUiVis;
+            mScale = scale;
             final Context context = ActivityThread.currentActivityThread().getSystemUiContext();
             final int semiTransparent = context.getColor(
                     R.color.system_bar_background_semi_transparent);
@@ -521,7 +536,7 @@
                     (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
             if (STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
                     mSysUiVis, mStatusBarColor, mWindowFlags, forceBarBackground)) {
-                return getColorViewTopInset(mStableInsets.top, mContentInsets.top);
+                return (int) (getColorViewTopInset(mStableInsets.top, mContentInsets.top) * mScale);
             } else {
                 return 0;
             }
@@ -544,8 +559,8 @@
                 int statusBarHeight) {
             if (statusBarHeight > 0 && Color.alpha(mStatusBarColor) != 0
                     && (alreadyDrawnFrame == null || c.getWidth() > alreadyDrawnFrame.right)) {
-                final int rightInset = DecorView.getColorViewRightInset(mStableInsets.right,
-                        mContentInsets.right);
+                final int rightInset = (int) (DecorView.getColorViewRightInset(mStableInsets.right,
+                        mContentInsets.right) * mScale);
                 final int left = alreadyDrawnFrame != null ? alreadyDrawnFrame.right : 0;
                 c.drawRect(left, 0, c.getWidth() - rightInset, statusBarHeight, mStatusBarPaint);
             }
@@ -555,7 +570,7 @@
         void drawNavigationBarBackground(Canvas c) {
             final Rect navigationBarRect = new Rect();
             getNavigationBarRect(c.getWidth(), c.getHeight(), mStableInsets, mContentInsets,
-                    navigationBarRect);
+                    navigationBarRect, mScale);
             final boolean visible = isNavigationBarColorViewVisible();
             if (visible && Color.alpha(mNavigationBarColor) != 0 && !navigationBarRect.isEmpty()) {
                 c.drawRect(navigationBarRect, mNavigationBarPaint);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index d838691..eb45e73 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -802,12 +802,7 @@
         if (width == mLastSurfaceSize.x && height == mLastSurfaceSize.y) {
             return;
         }
-        if (getWindowConfiguration().tasksAreFloating()) {
-            // Don't crop freeform windows to the stack.
-            transaction.setWindowCrop(mSurfaceControl, -1, -1);
-        } else {
-            transaction.setWindowCrop(mSurfaceControl, width, height);
-        }
+        transaction.setWindowCrop(mSurfaceControl, width, height);
         mLastSurfaceSize.set(width, height);
     }
 
@@ -1012,7 +1007,7 @@
         EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
 
         if (mAnimationBackgroundSurface != null) {
-            mAnimationBackgroundSurface.remove();
+            mWmService.mTransactionFactory.make().remove(mAnimationBackgroundSurface).apply();
             mAnimationBackgroundSurface = null;
         }
 
@@ -1640,6 +1635,7 @@
             if (mAnimationType == BoundsAnimationController.FADE_IN) {
                 setPinnedStackAlpha(1f);
                 mActivityStack.mService.notifyPinnedStackAnimationEnded();
+                return;
             }
 
             if (finalStackSize != null && !mCancelCurrentBoundsAnimation) {
@@ -1935,14 +1931,15 @@
     public boolean setPinnedStackAlpha(float alpha) {
         // Hold the lock since this is called from the BoundsAnimator running on the UiThread
         synchronized (mWmService.mGlobalLock) {
-            if (mCancelCurrentBoundsAnimation) {
+            final SurfaceControl sc = getSurfaceControl();
+            if (sc == null || !sc.isValid()) {
+                // If the stack is already removed, don't bother updating any stack animation
                 return false;
             }
-            getPendingTransaction().setAlpha(getSurfaceControl(), alpha);
+            getPendingTransaction().setAlpha(sc, mCancelCurrentBoundsAnimation ? 1 : alpha);
             scheduleAnimation();
+            return !mCancelCurrentBoundsAnimation;
         }
-
-        return true;
     }
 
     public DisplayInfo getDisplayInfo() {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index da873b8..6147272 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -24,7 +24,6 @@
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
 
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
@@ -612,10 +611,10 @@
             if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
                     "*** WALLPAPER DRAW TIMEOUT");
 
-            // If there was a recents animation in progress, cancel that animation
+            // If there was a pending recents animation, start the animation anyways (it's better
+            // to not see the wallpaper than for the animation to not start)
             if (mService.getRecentsAnimationController() != null) {
-                mService.getRecentsAnimationController().cancelAnimation(
-                        REORDER_MOVE_TO_ORIGINAL_POSITION, "wallpaperDrawPendingTimeout");
+                mService.getRecentsAnimationController().startAnimation();
             }
             return true;
         }
@@ -736,7 +735,7 @@
         bounds.offsetTo(0, 0);
 
         SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
-                wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */);
+                wallpaperWindowState.getSurfaceControl(), bounds, 1 /* frameScale */);
 
         if (wallpaperBuffer == null) {
             Slog.w(TAG_WM, "Failed to screenshot wallpaper");
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 40bec14..636f4e6 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -51,9 +51,10 @@
         /**
          * Called when the windows for accessibility changed.
          *
+         * @param forceSend Send the windows for accessibility even if they haven't changed.
          * @param windows The windows for accessibility.
          */
-        public void onWindowsForAccessibilityChanged(List<WindowInfo> windows);
+        void onWindowsForAccessibilityChanged(boolean forceSend, List<WindowInfo> windows);
     }
 
     /**
@@ -262,11 +263,13 @@
 
     /**
      * Sets a callback for observing which windows are touchable for the purposes
-     * of accessibility.
+     * of accessibility on specified display.
      *
+     * @param displayId The logical display id.
      * @param callback The callback.
+     * @return {@code false} if display id is not valid.
      */
-    public abstract void setWindowsForAccessibilityCallback(
+    public abstract boolean setWindowsForAccessibilityCallback(int displayId,
             WindowsForAccessibilityCallback callback);
 
     /**
@@ -417,9 +420,11 @@
     public abstract boolean isStackVisibleLw(int windowingMode);
 
     /**
-     * Requests the window manager to resend the windows for accessibility.
+     * Requests the window manager to resend the windows for accessibility on specified display.
+     *
+     * @param displayId Display ID to be computed its windows for accessibility
      */
-    public abstract void computeWindowsForAccessibility();
+    public abstract void computeWindowsForAccessibility(int displayId);
 
     /**
      * Called after virtual display Id is updated by
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0a2fc9b..70e446c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -32,6 +32,8 @@
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Process.myPid;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE;
+import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
@@ -77,7 +79,6 @@
 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;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -100,6 +101,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN;
 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_APP;
+import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_DISPLAY_ID;
 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_WINDOW;
 import static com.android.server.wm.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
 import static com.android.server.wm.WindowManagerServiceDumpProto.LAST_ORIENTATION;
@@ -154,6 +156,7 @@
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.Looper;
@@ -175,6 +178,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.WorkSource;
+import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.service.vr.IVrManager;
 import android.service.vr.IVrStateCallbacks;
@@ -215,6 +219,7 @@
 import android.view.InputDevice;
 import android.view.InputEvent;
 import android.view.InputEventReceiver;
+import android.view.InputWindowHandle;
 import android.view.InsetsState;
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
@@ -380,6 +385,8 @@
 
     private static final int ANIMATION_COMPLETED_TIMEOUT_MS = 5000;
 
+    private static final int MIN_GESTURE_EXCLUSION_LIMIT_DP = 200;
+
     final WindowTracing mWindowTracing;
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
@@ -838,6 +845,9 @@
     final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
     boolean mWindowsChanged = false;
 
+    int mSystemGestureExclusionLimitDp;
+    boolean mSystemGestureExcludedByPreQStickyImmersive;
+
     public interface WindowChangeListener {
         public void windowsChanged();
         public void focusChanged();
@@ -845,7 +855,7 @@
 
     final Configuration mTempConfiguration = new Configuration();
 
-    final HighRefreshRateBlacklist mHighRefreshRateBlacklist = HighRefreshRateBlacklist.create();
+    final HighRefreshRateBlacklist mHighRefreshRateBlacklist;
 
     // If true, only the core apps and services are being launched because the device
     // is in a special boot mode, such as being encrypted or waiting for a decryption password.
@@ -1132,6 +1142,31 @@
                 this, mInputManager, mActivityTaskManager, mH.getLooper());
         mDragDropController = new DragDropController(this, mH.getLooper());
 
+        mHighRefreshRateBlacklist = HighRefreshRateBlacklist.create(context.getResources());
+
+        mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
+                DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                        KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
+        mSystemGestureExcludedByPreQStickyImmersive =
+                DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                        KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                new HandlerExecutor(mH), properties -> {
+                    synchronized (mGlobalLock) {
+                        final int exclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
+                                properties.getInt(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
+                        final boolean excludedByPreQSticky = DeviceConfig.getBoolean(
+                                DeviceConfig.NAMESPACE_WINDOW_MANAGER,
+                                KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
+                        if (mSystemGestureExcludedByPreQStickyImmersive != excludedByPreQSticky
+                                || mSystemGestureExclusionLimitDp != exclusionLimitDp) {
+                            mSystemGestureExclusionLimitDp = exclusionLimitDp;
+                            mSystemGestureExcludedByPreQStickyImmersive = excludedByPreQSticky;
+                            mRoot.forAllDisplays(DisplayContent::updateSystemGestureExclusionLimit);
+                        }
+                    }
+                });
+
         LocalServices.addService(WindowManagerInternal.class, new LocalService());
     }
 
@@ -1396,7 +1431,7 @@
                     Binder.getCallingUid());
             win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
 
-            res = displayPolicy.prepareAddWindowLw(win, attrs);
+            res = displayPolicy.validateAddingWindowLw(attrs);
             if (res != WindowManagerGlobal.ADD_OKAY) {
                 return res;
             }
@@ -1472,6 +1507,7 @@
             boolean imMayMove = true;
 
             win.mToken.addWindow(win);
+            displayPolicy.addWindowLw(win, attrs);
             if (type == TYPE_INPUT_METHOD) {
                 displayContent.setInputMethodWindowLocked(win);
                 imMayMove = false;
@@ -1573,10 +1609,10 @@
             if (win.isVisibleOrAdding() && displayContent.updateOrientationFromAppTokens()) {
                 reportNewConfig = true;
             }
-        }
 
-        if (reportNewConfig) {
-            sendNewConfiguration(displayId);
+            if (reportNewConfig) {
+                displayContent.sendNewConfiguration();
+            }
         }
 
         Binder.restoreCallingIdentity(origId);
@@ -1614,7 +1650,8 @@
             final Display display = mDisplayManager.getDisplay(displayId);
 
             if (display != null) {
-                displayContent = mRoot.createDisplayContent(display, null /* controller */);
+                displayContent = mRoot.createDisplayContent(display, null /* activityDisplay */);
+                displayContent.reconfigureDisplayLocked();
             }
         }
 
@@ -1875,10 +1912,9 @@
                     mWindowPlacerLocked.performSurfacePlacement();
 
                     // We need to report touchable region changes to accessibility.
-                    if (mAccessibilityController != null
-                            && (w.getDisplayContent().getDisplayId() == DEFAULT_DISPLAY
-                                    || w.getDisplayContent().getParentWindow() != null)) {
-                        mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+                    if (mAccessibilityController != null) {
+                        mAccessibilityController.onSomeWindowResizedOrMovedLocked(
+                                w.getDisplayContent().getDisplayId());
                     }
                 }
             }
@@ -2008,11 +2044,10 @@
                     win.mAppToken.checkKeyguardFlagsChanged();
                 }
                 if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0)
-                        && (mAccessibilityController != null)
-                        && (win.getDisplayId() == DEFAULT_DISPLAY
-                                || win.getDisplayContent().getParentWindow() != null)) {
+                        && (mAccessibilityController != null)) {
                     // No move or resize, but the controller checks for title changes as well
-                    mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+                    mAccessibilityController.onSomeWindowResizedOrMovedLocked(
+                            win.getDisplayContent().getDisplayId());
                 }
 
                 if ((flagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
@@ -2256,13 +2291,15 @@
                 Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
             }
             win.mInRelayout = false;
+
+            if (configChanged) {
+                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+                        "relayoutWindow: postNewConfigurationToHandler");
+                displayContent.sendNewConfiguration();
+                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+            }
         }
 
-        if (configChanged) {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: sendNewConfiguration");
-            sendNewConfiguration(displayId);
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        }
         Binder.restoreCallingIdentity(origId);
         return result;
     }
@@ -2356,14 +2393,15 @@
         }
     }
 
-    void finishDrawingWindow(Session session, IWindow client) {
+    void finishDrawingWindow(Session session, IWindow client,
+            @Nullable SurfaceControl.Transaction postDrawTransaction) {
         final long origId = Binder.clearCallingIdentity();
         try {
             synchronized (mGlobalLock) {
                 WindowState win = windowForClientLocked(session, client, false);
                 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState="
                         + (win != null ? win.mWinAnimator.drawStateToString() : "null"));
-                if (win != null && win.mWinAnimator.finishDrawingLocked()) {
+                if (win != null && win.mWinAnimator.finishDrawingLocked(postDrawTransaction)) {
                     if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
                         win.getDisplayContent().pendingLayoutChanges |=
                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -3551,8 +3589,9 @@
         return true;
     }
 
-    public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean reducedResolution) {
-        return mTaskSnapshotController.getSnapshot(taskId, userId, true /* restoreFromDisk */,
+    public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean reducedResolution,
+            boolean restoreFromDisk) {
+        return mTaskSnapshotController.getSnapshot(taskId, userId, restoreFromDisk,
                 reducedResolution);
     }
 
@@ -4253,34 +4292,6 @@
         }
     }
 
-    /**
-     * Instruct the Activity Manager to fetch and update the current display's configuration and
-     * broadcast them to config-changed listeners if appropriate.
-     * NOTE: Can't be called with the window manager lock held since it call into activity manager.
-     */
-    void sendNewConfiguration(int displayId) {
-        try {
-            final boolean configUpdated = mActivityTaskManager.updateDisplayOverrideConfiguration(
-                    null /* values */, displayId);
-            if (!configUpdated) {
-                // Something changed (E.g. device rotation), but no configuration update is needed.
-                // E.g. changing device rotation by 180 degrees. Go ahead and perform surface
-                // placement to unfreeze the display since we froze it when the rotation was updated
-                // in DisplayContent#updateRotationUnchecked.
-                synchronized (mGlobalLock) {
-                    final DisplayContent dc = mRoot.getDisplayContent(displayId);
-                    if (dc != null && dc.mWaitingForConfig) {
-                        dc.mWaitingForConfig = false;
-                        mLastFinishedFreezeSource = "config-unchanged";
-                        dc.setLayoutNeeded();
-                        mWindowPlacerLocked.performSurfacePlacement();
-                    }
-                }
-            }
-        } catch (RemoteException e) {
-        }
-    }
-
     public Configuration computeNewConfiguration(int displayId) {
         synchronized (mGlobalLock) {
             return computeNewConfigurationLocked(displayId);
@@ -4404,12 +4415,12 @@
             if (mMaxUiWidth > 0) {
                 mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
             }
-            final boolean changed = applyForcedPropertiesForDefaultDisplay();
+            applyForcedPropertiesForDefaultDisplay();
             mAnimator.ready();
             mDisplayReady = true;
-            if (changed) {
-                reconfigureDisplayLocked(getDefaultDisplayContentLocked());
-            }
+            // Reconfigure all displays to make sure that forced properties and
+            // DisplayWindowSettings are applied.
+            mRoot.forAllDisplays(DisplayContent::reconfigureDisplayLocked);
             mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_TOUCHSCREEN);
         }
@@ -4488,7 +4499,6 @@
         public static final int FORCE_GC = 15;
         public static final int ENABLE_SCREEN = 16;
         public static final int APP_FREEZE_TIMEOUT = 17;
-        public static final int SEND_NEW_CONFIGURATION = 18;
         public static final int REPORT_WINDOWS_CHANGE = 19;
 
         public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
@@ -4543,22 +4553,16 @@
                     AccessibilityController accessibilityController = null;
 
                     synchronized (mGlobalLock) {
-                        // TODO(multidisplay): Accessibility supported only of default display and
-                        // embedded displays.
-                        if (mAccessibilityController != null
-                                && (displayContent.isDefaultDisplay
-                                || displayContent.getParentWindow() != null)) {
+                        if (mAccessibilityController != null) {
                             accessibilityController = mAccessibilityController;
                         }
 
                         lastFocus = displayContent.mLastFocus;
                         newFocus = displayContent.mCurrentFocus;
-                    }
-                    if (lastFocus == newFocus) {
-                        // Focus is not changing, so nothing to do.
-                        return;
-                    }
-                    synchronized (mGlobalLock) {
+                        if (lastFocus == newFocus) {
+                            // Focus is not changing, so nothing to do.
+                            return;
+                        }
                         displayContent.mLastFocus = newFocus;
                         if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Focus moving from " + lastFocus +
                                 " to " + newFocus + " displayId=" + displayContent.getDisplayId());
@@ -4572,7 +4576,8 @@
                     // First notify the accessibility manager for the change so it has
                     // the windows before the newly focused one starts firing eventgs.
                     if (accessibilityController != null) {
-                        accessibilityController.onWindowFocusChangedNotLocked();
+                        accessibilityController.onWindowFocusChangedNotLocked(
+                                displayContent.getDisplayId());
                     }
 
                     if (newFocus != null) {
@@ -4702,23 +4707,6 @@
                     break;
                 }
 
-                case SEND_NEW_CONFIGURATION: {
-                    final DisplayContent displayContent = (DisplayContent) msg.obj;
-                    removeMessages(SEND_NEW_CONFIGURATION, displayContent);
-                    if (displayContent.isReady()) {
-                        sendNewConfiguration(displayContent.getDisplayId());
-                    } else {
-                        // Message could come after display has already been removed.
-                        if (DEBUG_CONFIGURATION) {
-                            final String reason = displayContent.getParent() == null
-                                    ? "detached" : "unready";
-                            Slog.w(TAG, "Trying to send configuration to " + reason + " display="
-                                    + displayContent);
-                        }
-                    }
-                    break;
-                }
-
                 case REPORT_WINDOWS_CHANGE: {
                     if (mWindowsChanged) {
                         synchronized (mGlobalLock) {
@@ -5173,29 +5161,6 @@
         return 0;
     }
 
-    void reconfigureDisplayLocked(@NonNull DisplayContent displayContent) {
-        if (!displayContent.isReady()) {
-            return;
-        }
-        displayContent.configureDisplayPolicy();
-        displayContent.setLayoutNeeded();
-
-        boolean configChanged = displayContent.updateOrientationFromAppTokens();
-        final Configuration currentDisplayConfig = displayContent.getConfiguration();
-        mTempConfiguration.setTo(currentDisplayConfig);
-        displayContent.computeScreenConfiguration(mTempConfiguration);
-        configChanged |= currentDisplayConfig.diff(mTempConfiguration) != 0;
-
-        if (configChanged) {
-            displayContent.mWaitingForConfig = true;
-            startFreezingDisplayLocked(0 /* exitAnim */,
-                    0 /* enterAnim */, displayContent);
-            displayContent.sendNewConfiguration();
-        }
-
-        mWindowPlacerLocked.performSurfacePlacement();
-    }
-
     @Override
     public void setOverscan(int displayId, int left, int top, int right, int bottom) {
         if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
@@ -5225,7 +5190,7 @@
 
         mDisplayWindowSettings.setOverscanLocked(displayInfo, left, top, right, bottom);
 
-        reconfigureDisplayLocked(displayContent);
+        displayContent.reconfigureDisplayLocked();
     }
 
     @Override
@@ -5889,6 +5854,12 @@
         mRoot.dumpTokens(pw, dumpAll);
     }
 
+
+    private void dumpHighRefreshRateBlacklist(PrintWriter pw) {
+        pw.println("WINDOW MANAGER HIGH REFRESH RATE BLACKLIST (dumpsys window refresh)");
+        mHighRefreshRateBlacklist.dump(pw);
+    }
+
     private void dumpTraceStatus(PrintWriter pw) {
         pw.println("WINDOW MANAGER TRACE (dumpsys window trace)");
         pw.print(mWindowTracing.getStatus() + "\n");
@@ -5928,6 +5899,7 @@
         final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
         proto.write(ROTATION, defaultDisplayContent.getRotation());
         proto.write(LAST_ORIENTATION, defaultDisplayContent.getLastOrientation());
+        proto.write(FOCUSED_DISPLAY_ID, topFocusedDisplayContent.getDisplayId());
     }
 
     private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
@@ -6288,6 +6260,9 @@
             } else if ("trace".equals(cmd)) {
                 dumpTraceStatus(pw);
                 return;
+            } else if ("refresh".equals(cmd)) {
+                dumpHighRefreshRateBlacklist(pw);
+                return;
             } else {
                 // Dumping a single name?
                 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
@@ -6343,6 +6318,10 @@
                 pw.println(separator);
             }
             dumpTraceStatus(pw);
+            if (dumpAll) {
+                pw.println(separator);
+            }
+            dumpHighRefreshRateBlacklist(pw);
         }
     }
 
@@ -6733,6 +6712,12 @@
                     return;
                 }
                 getDisplayContentOrCreate(displayId, null).reparentDisplayContent(win, sc);
+                // Notifies AccessibilityController to re-compute the window observer of
+                // this embedded display
+                if (mAccessibilityController != null) {
+                    mAccessibilityController.handleWindowObserverOfEmbeddedDisplayLocked(displayId,
+                            win);
+                }
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -6839,17 +6824,16 @@
             int lastWindowingMode = displayContent.getWindowingMode();
             mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
 
             if (lastWindowingMode != displayContent.getWindowingMode()) {
                 // reconfigure won't detect this change in isolation because the windowing mode is
                 // already set on the display, so fire off a new config now.
-                mH.removeMessages(H.SEND_NEW_CONFIGURATION);
 
                 final long origId = Binder.clearCallingIdentity();
                 try {
                     // direct call since lock is shared.
-                    sendNewConfiguration(displayId);
+                    displayContent.sendNewConfiguration();
                 } finally {
                     Binder.restoreCallingIdentity(origId);
                 }
@@ -6892,7 +6876,7 @@
 
             mDisplayWindowSettings.setRemoveContentModeLocked(displayContent, mode);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
         }
     }
 
@@ -6931,7 +6915,7 @@
             mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(displayContent,
                     shouldShow);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
         }
     }
 
@@ -6975,7 +6959,7 @@
 
             mDisplayWindowSettings.setShouldShowSystemDecorsLocked(displayContent, shouldShow);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
         }
     }
 
@@ -7020,7 +7004,7 @@
 
             mDisplayWindowSettings.setShouldShowImeLocked(displayContent, shouldShow);
 
-            reconfigureDisplayLocked(displayContent);
+            displayContent.reconfigureDisplayLocked();
         }
     }
 
@@ -7144,16 +7128,20 @@
         }
 
         @Override
-        public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) {
+        public boolean setWindowsForAccessibilityCallback(int displayId,
+                WindowsForAccessibilityCallback callback) {
             synchronized (mGlobalLock) {
                 if (mAccessibilityController == null) {
                     mAccessibilityController = new AccessibilityController(
                             WindowManagerService.this);
                 }
-                mAccessibilityController.setWindowsForAccessibilityCallback(callback);
+                final boolean result =
+                        mAccessibilityController.setWindowsForAccessibilityCallbackLocked(
+                        displayId, callback);
                 if (!mAccessibilityController.hasCallbacksLocked()) {
                     mAccessibilityController = null;
                 }
+                return result;
             }
         }
 
@@ -7319,13 +7307,13 @@
         }
 
         @Override
-        public void computeWindowsForAccessibility() {
+        public void computeWindowsForAccessibility(int displayId) {
             final AccessibilityController accessibilityController;
             synchronized (mGlobalLock) {
                 accessibilityController = mAccessibilityController;
             }
             if (accessibilityController != null) {
-                accessibilityController.performComputeChangedWindowsNotLocked(true);
+                accessibilityController.performComputeChangedWindowsNotLocked(displayId, true);
             }
         }
 
@@ -7628,22 +7616,30 @@
 
     @Override
     public boolean injectInputAfterTransactionsApplied(InputEvent ev, int mode) {
-        boolean shouldWaitForAnimToComplete = false;
+        boolean isDown;
+        boolean isUp;
+
         if (ev instanceof KeyEvent) {
             KeyEvent keyEvent = (KeyEvent) ev;
-            shouldWaitForAnimToComplete = keyEvent.getSource() == InputDevice.SOURCE_MOUSE
-                    || keyEvent.getAction() == KeyEvent.ACTION_DOWN;
-        } else if (ev instanceof MotionEvent) {
+            isDown = keyEvent.getAction() == KeyEvent.ACTION_DOWN;
+            isUp = keyEvent.getAction() == KeyEvent.ACTION_UP;
+        } else {
             MotionEvent motionEvent = (MotionEvent) ev;
-            shouldWaitForAnimToComplete = motionEvent.getSource() == InputDevice.SOURCE_MOUSE
-                    || motionEvent.getAction() == MotionEvent.ACTION_DOWN;
+            isDown = motionEvent.getAction() == MotionEvent.ACTION_DOWN;
+            isUp = motionEvent.getAction() == MotionEvent.ACTION_UP;
         }
 
-        if (shouldWaitForAnimToComplete) {
+        // For ACTION_DOWN, syncInputTransactions before injecting input.
+        // For ACTION_UP, sync after injecting.
+        if (isDown) {
             syncInputTransactions();
         }
-
-        return LocalServices.getService(InputManagerInternal.class).injectInputEvent(ev, mode);
+        final boolean result =
+                LocalServices.getService(InputManagerInternal.class).injectInputEvent(ev, mode);
+        if (isUp) {
+            syncInputTransactions();
+        }
+        return result;
     }
 
     @Override
@@ -7684,7 +7680,7 @@
 
     private void onPointerDownOutsideFocusLocked(IBinder touchedToken) {
         final WindowState touchedWindow = windowForClientLocked(null, touchedToken, false);
-        if (touchedWindow == null) {
+        if (touchedWindow == null || !touchedWindow.canReceiveKeys()) {
             return;
         }
 
@@ -7738,4 +7734,53 @@
                     0 /* configChanges */, !PRESERVE_WINDOWS, true /* notifyClients */);
         }
     }
+
+    /**
+     * Assigns an InputChannel to a SurfaceControl and configures it to receive
+     * touch input according to it's on-screen geometry.
+     *
+     * Used by WindowlessWindowManager to enable input on SurfaceControl embedded
+     * views.
+     */
+    void blessInputSurface(int callingUid, int callingPid, int displayId, SurfaceControl surface,
+            InputChannel outInputChannel) {
+        String name = "Blessed Surface";
+        InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
+        InputChannel inputChannel = inputChannels[0];
+        InputChannel clientChannel = inputChannels[1];
+
+        clientChannel.transferTo(outInputChannel);
+        clientChannel.dispose();
+
+        IBinder token = new Binder();
+        mInputManager.registerInputChannel(inputChannel, token);
+
+        // Prevent the java finalizer from breaking the input channel. But we won't
+        // do any further management so we just release the java ref and let the
+        // InputDispatcher hold the last ref.
+        inputChannel.release();
+
+        InputWindowHandle h = new InputWindowHandle(null, null, displayId);
+        h.token = token;
+        h.name = name;
+        h.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+        h.layoutParamsType = 0;
+        h.dispatchingTimeoutNanos = -1;
+        h.canReceiveKeys = false;
+        h.hasFocus = false;
+        h.hasWallpaper = false;
+        h.paused = false;
+
+        h.ownerUid = callingUid;
+        h.ownerPid = callingPid;
+
+        h.inputFeatures = 0;
+
+        h.replaceTouchableRegionWithCrop(null);
+
+        SurfaceSession s = new SurfaceSession();
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        t.setInputWindowInfo(surface, h);
+        t.apply();
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 2ad25cf..f74e2c0 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -27,6 +27,7 @@
 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;
+import static com.android.server.wm.ActivityStack.ActivityState.STARTED;
 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
@@ -402,11 +403,17 @@
         if (mAllowBackgroundActivityStarts) {
             return true;
         }
-        // allow if any activity in the caller has either started or finished very recently
+        // allow if any activity in the caller has either started or finished very recently, and
+        // it must be started or finished after last stop app switches time.
         final long now = SystemClock.uptimeMillis();
         if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
                 || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
-            return true;
+            // if activity is started and finished before stop app switch time, we should not
+            // let app to be able to start background activity even it's in grace period.
+            if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
+                    || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
+                return true;
+            }
         }
         // allow if the proc is instrumenting with background activity starts privs
         if (mInstrumentingWithBackgroundActivityStartPrivileges) {
@@ -622,8 +629,8 @@
         for (int i = 0; i < activities.size(); i++) {
             final ActivityRecord r = activities.get(i);
             if (!r.finishing && r.isInStackLocked()) {
-                r.getActivityStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
-                        null, "finish-heavy", true);
+                r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+                        "finish-heavy", true /* oomAdj */);
             }
         }
     }
@@ -725,10 +732,10 @@
                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
                 return null;
             }
-            // Don't consider any activies that are currently not in a state where they
+            // Don't consider any activities that are currently not in a state where they
             // can be destroyed.
-            if (r.visible || !r.stopped || !r.haveState
-                    || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) {
+            if (r.visible || !r.stopped || !r.hasSavedState()
+                    || r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING)) {
                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
                 continue;
             }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 89fd33b..9f9ef24 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -22,8 +22,9 @@
 import static android.app.AppOpsManager.OP_NONE;
 import static android.os.PowerManager.DRAW_WAKE_LOCK;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.SurfaceControl.Transaction;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
@@ -155,6 +156,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Debug;
 import android.os.IBinder;
 import android.os.PowerManager;
@@ -667,6 +669,15 @@
         return true;
     }
 
+    boolean isImplicitlyExcludingAllSystemGestures() {
+        final int immersiveStickyFlags =
+                SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+        final boolean immersiveSticky =
+                (mSystemUiVisibility & immersiveStickyFlags) == immersiveStickyFlags;
+        return immersiveSticky && mWmService.mSystemGestureExcludedByPreQStickyImmersive
+                && mAppToken != null && mAppToken.mTargetSdk < Build.VERSION_CODES.Q;
+    }
+
     interface PowerManagerWrapper {
         void wakeUp(long time, @WakeReason int reason, String details);
 
@@ -1457,10 +1468,12 @@
 
     void clearPolicyVisibilityFlag(int policyVisibilityFlag) {
         mPolicyVisibility &= ~policyVisibilityFlag;
+        mWmService.scheduleAnimationLocked();
     }
 
     void setPolicyVisibilityFlag(int policyVisibilityFlag) {
         mPolicyVisibility |= policyVisibilityFlag;
+        mWmService.scheduleAnimationLocked();
     }
 
     private boolean isLegacyPolicyVisibility() {
@@ -1556,7 +1569,8 @@
      */
     boolean isInteresting() {
         return mAppToken != null && !mAppDied
-                && (!mAppToken.isFreezingScreen() || !mAppFreezing);
+                && (!mAppToken.isFreezingScreen() || !mAppFreezing)
+                && mViewVisibility == View.VISIBLE;
     }
 
     /**
@@ -1618,7 +1632,7 @@
                 || !mRelayoutCalled
                 || (atoken == null && mToken.isHidden())
                 || (atoken != null && atoken.hiddenRequested)
-                || isParentWindowHidden()
+                || isParentWindowGoneForLayout()
                 || (mAnimatingExit && !isAnimatingLw())
                 || mDestroying;
     }
@@ -1787,11 +1801,8 @@
             startMoveAnimation(left, top);
         }
 
-        // TODO (multidisplay): Accessibility supported only for the default display and
-        // embedded displays
-        if (mWmService.mAccessibilityController != null && (getDisplayId() == DEFAULT_DISPLAY
-                || getDisplayContent().getParentWindow() != null)) {
-            mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+        if (mWmService.mAccessibilityController != null) {
+            mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(getDisplayId());
         }
         updateLocationInParentDisplayIfNeeded();
 
@@ -2090,6 +2101,13 @@
             return false;
         }
 
+        final TaskStack stack = getStack();
+        if (stack != null && stack.shouldIgnoreInput()) {
+            // Ignore when the stack shouldn't receive input event.
+            // (i.e. the minimized stack in split screen mode.)
+            return false;
+        }
+
         final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM);
         final int type = mAttrs.type;
 
@@ -2371,10 +2389,11 @@
 
     void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
         // We need to turn on screen regardless of visibility.
-        boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0;
+        final boolean hasTurnScreenOnFlag = (mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0
+                || (mAppToken != null && mAppToken.mActivityRecord.canTurnScreenOn());
 
         // The screen will turn on if the following conditions are met
-        // 1. The window has the flag FLAG_TURN_SCREEN_ON
+        // 1. The window has the flag FLAG_TURN_SCREEN_ON or ActivityRecord#canTurnScreenOn.
         // 2. The WMS allows theater mode.
         // 3. No AWT or the AWT allows the screen to be turned on. This should only be true once
         // per resume to prevent the screen getting getting turned on for each relayout. Set
@@ -2388,7 +2407,7 @@
             boolean allowTheaterMode = mWmService.mAllowTheaterModeWakeFromLayout
                     || Settings.Global.getInt(mWmService.mContext.getContentResolver(),
                             Settings.Global.THEATER_MODE_ON, 0) == 0;
-            boolean canTurnScreenOn = mAppToken == null || mAppToken.canTurnScreenOn();
+            boolean canTurnScreenOn = mAppToken == null || mAppToken.currentLaunchCanTurnScreenOn();
 
             if (allowTheaterMode && canTurnScreenOn && !mPowerManagerWrapper.isInteractive()) {
                 if (DEBUG_VISIBILITY || DEBUG_POWER) {
@@ -2399,7 +2418,7 @@
             }
 
             if (mAppToken != null) {
-                mAppToken.setCanTurnScreenOn(false);
+                mAppToken.setCurrentLaunchCanTurnScreenOn(false);
             }
         }
 
@@ -3008,6 +3027,25 @@
         subtractTouchExcludeRegionIfNeeded(outRegion);
     }
 
+    /**
+     * Get the effective touchable region in global coordinates.
+     *
+     * In contrast to {@link #getTouchableRegion}, this takes into account
+     * {@link WindowManager.LayoutParams#FLAG_NOT_TOUCH_MODAL touch modality.}
+     */
+    void getEffectiveTouchableRegion(Region outRegion) {
+        final boolean modal = (mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
+        final DisplayContent dc = getDisplayContent();
+
+        if (modal && dc != null) {
+            outRegion.set(dc.getBounds());
+            cropRegionToStackBoundsIfNeeded(outRegion);
+            subtractTouchExcludeRegionIfNeeded(outRegion);
+        } else {
+            getTouchableRegion(outRegion);
+        }
+    }
+
     private void setTouchableRegionCropIfNeeded(InputWindowHandle handle) {
         final Task task = getTask();
         if (task == null || !task.cropWindowsToStackBounds()) {
@@ -3154,12 +3192,9 @@
                         outsets, reportDraw, mergedConfiguration, reportOrientation, displayId,
                         displayCutout);
             }
-
-            // TODO (multidisplay): Accessibility supported only for the default display and
-            // embedded displays
-            if (mWmService.mAccessibilityController != null && (getDisplayId() == DEFAULT_DISPLAY
-                    || getDisplayContent().getParentWindow() != null)) {
-                mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+            if (mWmService.mAccessibilityController != null) {
+                mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(
+                        getDisplayId());
             }
             updateLocationInParentDisplayIfNeeded();
 
@@ -3806,6 +3841,11 @@
         return parent != null && parent.mHidden;
     }
 
+    private boolean isParentWindowGoneForLayout() {
+        final WindowState parent = getParentWindow();
+        return parent != null && parent.isGoneForLayoutLw();
+    }
+
     void setWillReplaceWindow(boolean animate) {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final WindowState c = mChildren.get(i);
@@ -3934,7 +3974,7 @@
     boolean performShowLocked() {
         if (isHiddenFromUserLocked()) {
             if (DEBUG_VISIBILITY) Slog.w(TAG, "hiding " + this + ", belonging to " + mOwnerUid);
-            hideLw(false);
+            clearPolicyVisibilityFlag(VISIBLE_FOR_USER);
             return false;
         }
 
@@ -4008,6 +4048,7 @@
 
     WindowInfo getWindowInfo() {
         WindowInfo windowInfo = WindowInfo.obtain();
+        windowInfo.displayId = getDisplayId();
         windowInfo.type = mAttrs.type;
         windowInfo.layer = mLayer;
         windowInfo.token = mClient.asBinder();
@@ -4253,12 +4294,8 @@
         if (isSelfAnimating()) {
             return;
         }
-
-        // TODO (multidisplay): Accessibility supported only for the default display and
-        // embedded displays
-        if (mWmService.mAccessibilityController != null && (getDisplayId() == DEFAULT_DISPLAY
-                || getDisplayContent().getParentWindow() != null)) {
-            mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+        if (mWmService.mAccessibilityController != null) {
+            mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked(getDisplayId());
         }
 
         if (!isSelfOrAncestorWindowAnimatingExit()) {
@@ -4907,7 +4944,7 @@
             if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) {
                 mLastSurfaceInsets.set(mAttrs.surfaceInsets);
                 t.deferTransactionUntil(mSurfaceControl,
-                        mWinAnimator.mSurfaceController.mSurfaceControl.getHandle(),
+                        mWinAnimator.mSurfaceController.mSurfaceControl,
                         getFrameNumber());
             }
         }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 10a63ee..3ba3280 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -20,6 +20,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static android.view.WindowManager.TRANSIT_NONE;
@@ -219,7 +220,16 @@
 
     private final Rect mTmpSize = new Rect();
 
-    private final SurfaceControl.Transaction mReparentTransaction = new SurfaceControl.Transaction();
+    /**
+     * Handles surface changes synchronized to after the client has drawn the surface. This
+     * transaction is currently used to reparent the old surface children to the new surface once
+     * the client has completed drawing to the new surface.
+     * This transaction is also used to merge transactions parceled in by the client. The client
+     * uses the transaction to update the relative z of its children from the old parent surface
+     * to the new parent surface once window manager reparents its children.
+     */
+    private final SurfaceControl.Transaction mPostDrawTransaction =
+            new SurfaceControl.Transaction();
 
     // Used to track whether we have called detach children on the way to invisibility, in which
     // case we need to give the client a new Surface if it lays back out to a visible state.
@@ -300,7 +310,7 @@
         SurfaceControl.mergeToGlobalTransaction(mTmpTransaction);
     }
 
-    boolean finishDrawingLocked() {
+    boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
         final boolean startingWindow =
                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
         if (DEBUG_STARTING_WINDOW && startingWindow) {
@@ -320,6 +330,9 @@
             mDrawState = COMMIT_DRAW_PENDING;
             layoutNeeded = true;
         }
+        if (postDrawTransaction != null) {
+            mPostDrawTransaction.merge(postDrawTransaction);
+        }
 
         return layoutNeeded;
     }
@@ -384,8 +397,8 @@
                 // child layers need to be reparented to the new surface to make this
                 // transparent to the app.
                 if (mWin.mAppToken == null || mWin.mAppToken.isRelaunching() == false) {
-                    mReparentTransaction.reparentChildren(mPendingDestroySurface.mSurfaceControl,
-                            mSurfaceController.mSurfaceControl.getHandle())
+                    mPostDrawTransaction.reparentChildren(mPendingDestroySurface.mSurfaceControl,
+                            mSurfaceController.mSurfaceControl)
                             .apply();
                 }
             }
@@ -1000,7 +1013,7 @@
                         // the WS position is reset (so the stack position is shown) at the same
                         // time that the buffer size changes.
                         setOffsetPositionForStackResize(false);
-                        mSurfaceController.deferTransactionUntil(mSurfaceController.getHandle(),
+                        mSurfaceController.deferTransactionUntil(mSurfaceController.mSurfaceControl,
                                 mWin.getFrameNumber());
                     } else {
                         final TaskStack stack = mWin.getStack();
@@ -1031,7 +1044,7 @@
         // comes in at the new size (normally position and crop are unfrozen).
         // setGeometryAppliesWithResizeInTransaction accomplishes this for us.
         if (wasForceScaled && !mForceScaleUntilResize) {
-            mSurfaceController.deferTransactionUntil(mSurfaceController.getHandle(),
+            mSurfaceController.deferTransactionUntil(mSurfaceController.mSurfaceControl,
                     mWin.getFrameNumber());
             mSurfaceController.forceScaleableInTransaction(false);
         }
@@ -1149,7 +1162,7 @@
                             // LogicalDisplay.
                             mAnimator.setPendingLayoutChanges(w.getDisplayId(),
                                     FINISH_LAYOUT_REDO_ANIM);
-                            if (DEBUG_LAYOUT_REPEATS) {                        
+                            if (DEBUG_LAYOUT_REPEATS) {
                                 mService.mWindowPlacerLocked.debugLayoutRepeats(
                                         "showSurfaceRobustlyLocked " + w,
                                         mAnimator.getPendingLayoutChanges(w.getDisplayId()));
@@ -1280,10 +1293,13 @@
         // If we had a preserved surface it's no longer needed, and it may be harmful
         // if we are transparent.
         if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) {
-            mPendingDestroySurface.mSurfaceControl.hide();
-            mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
+            final SurfaceControl pendingSurfaceControl = mPendingDestroySurface.mSurfaceControl;
+            mPostDrawTransaction.hide(pendingSurfaceControl);
+            mPostDrawTransaction.reparentChildren(pendingSurfaceControl,
+                    mSurfaceController.mSurfaceControl);
         }
 
+        mPostDrawTransaction.apply();
         return true;
     }
 
@@ -1294,6 +1310,7 @@
         if (mWin.mSkipEnterAnimationForSeamlessReplacement) {
             return;
         }
+
         final int transit;
         if (mEnterAnimationPending) {
             mEnterAnimationPending = false;
@@ -1301,7 +1318,13 @@
         } else {
             transit = WindowManagerPolicy.TRANSIT_SHOW;
         }
-        applyAnimationLocked(transit, true);
+
+        // We don't apply animation for application main window here since this window type
+        // should be controlled by AppWindowToken in general.
+        if (mAttrType != TYPE_BASE_APPLICATION) {
+            applyAnimationLocked(transit, true);
+        }
+
         if (mService.mAccessibilityController != null) {
             mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
         }
@@ -1365,6 +1388,7 @@
                     + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
                     + " a=" + a
                     + " transit=" + transit
+                    + " type=" + mAttrType
                     + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
             if (a != null) {
                 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
@@ -1484,6 +1508,12 @@
     }
 
     void detachChildren() {
+
+        // Do not detach children of starting windows, as their lifecycle is well under control and
+        // it may lead to issues in case we relaunch when we just added the starting window.
+        if (mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
+            return;
+        }
         if (mSurfaceController != null) {
             mSurfaceController.detachChildren();
         }
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index bef0f81..a616e06 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -33,7 +33,6 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Debug;
-import android.os.IBinder;
 import android.os.Trace;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
@@ -123,7 +122,7 @@
     void reparentChildrenInTransaction(WindowSurfaceController other) {
         if (SHOW_TRANSACTIONS) Slog.i(TAG, "REPARENT from: " + this + " to: " + other);
         if ((mSurfaceControl != null) && (other.mSurfaceControl != null)) {
-            mSurfaceControl.reparentChildren(other.getHandle());
+            mSurfaceControl.reparentChildren(other.mSurfaceControl);
         }
     }
 
@@ -162,7 +161,7 @@
         }
         try {
             if (mSurfaceControl != null) {
-                mSurfaceControl.remove();
+                mTmpTransaction.remove(mSurfaceControl).apply();
             }
         } catch (RuntimeException e) {
             Slog.w(TAG, "Error destroying surface in: " + this, e);
@@ -452,9 +451,9 @@
         return false;
     }
 
-    void deferTransactionUntil(IBinder handle, long frame) {
+    void deferTransactionUntil(SurfaceControl barrier, long frame) {
         // TODO: Logging
-        mSurfaceControl.deferTransactionUntil(handle, frame);
+        mSurfaceControl.deferTransactionUntil(barrier, frame);
     }
 
     void forceScaleableInTransaction(boolean force) {
@@ -483,13 +482,6 @@
         return mSurfaceControl != null;
     }
 
-    IBinder getHandle() {
-        if (mSurfaceControl == null) {
-            return null;
-        }
-        return mSurfaceControl.getHandle();
-    }
-
     void getSurfaceControl(SurfaceControl outSurfaceControl) {
         outSurfaceControl.copyFrom(mSurfaceControl);
     }
diff --git a/services/core/java/com/android/server/wm/utils/RegionUtils.java b/services/core/java/com/android/server/wm/utils/RegionUtils.java
index 1458440..ce7776f 100644
--- a/services/core/java/com/android/server/wm/utils/RegionUtils.java
+++ b/services/core/java/com/android/server/wm/utils/RegionUtils.java
@@ -18,8 +18,12 @@
 
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.graphics.RegionIterator;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.function.Consumer;
 
 /**
  * Utility methods to handle Regions.
@@ -42,4 +46,39 @@
             outRegion.union(rects.get(i));
         }
     }
+
+    /**
+     * Applies actions on each rect contained within a {@code Region}.
+     *
+     * @param region the given region.
+     * @param rectConsumer the action holder.
+     */
+    public static void forEachRect(Region region, Consumer<Rect> rectConsumer) {
+        final RegionIterator it = new RegionIterator(region);
+        final Rect rect = new Rect();
+        while (it.next(rect)) {
+            rectConsumer.accept(rect);
+        }
+    }
+
+    /**
+     * Applies actions on each rect contained within a {@code Region}.
+     *
+     * Order is bottom to top, then right to left.
+     *
+     * @param region the given region.
+     * @param rectConsumer the action holder.
+     */
+    public static void forEachRectReverse(Region region, Consumer<Rect> rectConsumer) {
+        final RegionIterator it = new RegionIterator(region);
+        final ArrayList<Rect> rects = new ArrayList<>();
+        final Rect rect = new Rect();
+        while (it.next(rect)) {
+            rects.add(new Rect(rect));
+        }
+        // TODO: instead of creating an array and reversing it, expose the reverse iterator through
+        //       JNI.
+        Collections.reverse(rects);
+        rects.forEach(rectConsumer);
+    }
 }
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index fb3076b..1c8c46c 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -826,18 +826,19 @@
         }
     }
 
-    uint32_t changes = 0;
+    bool pointerGesturesEnabledChanged = false;
     { // acquire lock
         AutoMutex _l(mLock);
 
         if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) {
             mLocked.pointerGesturesEnabled = newPointerGesturesEnabled;
-            changes |= InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT;
+            pointerGesturesEnabledChanged = true;
         }
     } // release lock
 
-    if (changes) {
-        mInputManager->getReader()->requestRefreshConfiguration(changes);
+    if (pointerGesturesEnabledChanged) {
+        mInputManager->getReader()->requestRefreshConfiguration(
+                InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT);
     }
 }
 
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index da17579..21bdc43 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -357,6 +357,33 @@
     return value ? JNI_TRUE : JNI_FALSE;
 }
 
+template<class T>
+static inline void logHidlError(Return<T>& result, const char* errorMessage) {
+    ALOGE("%s HIDL transport error: %s", errorMessage, result.description().c_str());
+}
+
+template<class T>
+static jboolean checkHidlReturn(Return<T>& result, const char* errorMessage) {
+    if (!result.isOk()) {
+        logHidlError(result, errorMessage);
+        return JNI_FALSE;
+    } else {
+        return JNI_TRUE;
+    }
+}
+
+static jboolean checkHidlReturn(Return<bool>& result, const char* errorMessage) {
+    if (!result.isOk()) {
+        logHidlError(result, errorMessage);
+        return JNI_FALSE;
+    } else if (!result) {
+        ALOGE("%s", errorMessage);
+        return JNI_FALSE;
+    } else {
+        return JNI_TRUE;
+    }
+}
+
 static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
     if (env->ExceptionCheck()) {
         ALOGE("An exception was thrown by callback '%s'.", methodName);
@@ -1913,8 +1940,7 @@
         result = gnssHal->setCallback(gnssCbIface);
     }
 
-    if (!result.isOk() || !result) {
-        ALOGE("SetCallback for IGnss interface failed.");
+    if (!checkHidlReturn(result, "IGnss setCallback() failed.")) {
         return JNI_FALSE;
     }
 
@@ -1924,35 +1950,29 @@
     } else {
         sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
         result = gnssXtraIface->setCallback(gnssXtraCbIface);
-        if (!result.isOk() || !result) {
+        if (!checkHidlReturn(result, "IGnssXtra setCallback() failed.")) {
             gnssXtraIface = nullptr;
-            ALOGI("SetCallback for IGnssXtra interface failed.");
         }
     }
 
     // Set IAGnss.hal callback.
-    Return<void> agnssStatus;
     if (agnssIface_V2_0 != nullptr) {
         sp<IAGnssCallback_V2_0> aGnssCbIface = new AGnssCallback_V2_0();
-        agnssStatus = agnssIface_V2_0->setCallback(aGnssCbIface);
+        auto agnssStatus = agnssIface_V2_0->setCallback(aGnssCbIface);
+        checkHidlReturn(agnssStatus, "IAGnss 2.0 setCallback() failed.");
     } else if (agnssIface != nullptr) {
         sp<IAGnssCallback_V1_0> aGnssCbIface = new AGnssCallback_V1_0();
-        agnssStatus = agnssIface->setCallback(aGnssCbIface);
+        auto agnssStatus = agnssIface->setCallback(aGnssCbIface);
+        checkHidlReturn(agnssStatus, "IAGnss setCallback() failed.");
     } else {
         ALOGI("Unable to initialize IAGnss interface.");
     }
 
-    if (!agnssStatus.isOk()) {
-        ALOGI("SetCallback for IAGnss interface failed.");
-    }
-
     // Set IGnssGeofencing.hal callback.
     sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
     if (gnssGeofencingIface != nullptr) {
         auto status = gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
-        if (!status.isOk()) {
-            ALOGI("SetCallback for IGnssGeofencing interface failed.");
-        }
+        checkHidlReturn(status, "IGnssGeofencing setCallback() failed.");
     } else {
         ALOGI("Unable to initialize IGnssGeofencing interface.");
     }
@@ -1961,9 +1981,7 @@
     sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
     if (gnssNiIface != nullptr) {
         auto status = gnssNiIface->setCallback(gnssNiCbIface);
-        if (!status.isOk()) {
-            ALOGI("SetCallback for IGnssNi interface failed.");
-        }
+        checkHidlReturn(status, "IGnssNi setCallback() failed.");
     } else {
         ALOGI("Unable to initialize IGnssNi interface.");
     }
@@ -1972,9 +1990,7 @@
     sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
     if (agnssRilIface != nullptr) {
         auto status = agnssRilIface->setCallback(aGnssRilCbIface);
-        if (!status.isOk()) {
-            ALOGI("SetCallback for IAGnssRil interface failed.");
-        }
+        checkHidlReturn(status, "IAGnssRil setCallback() failed.");
     } else {
         ALOGI("Unable to initialize IAGnssRil interface.");
     }
@@ -1984,9 +2000,7 @@
         sp<IGnssVisibilityControlCallback> gnssVisibilityControlCbIface =
                 new GnssVisibilityControlCallback();
         result = gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
-        if (!result.isOk() || !result) {
-            ALOGI("SetCallback for IGnssVisibilityControl interface failed.");
-        }
+        checkHidlReturn(result, "IGnssVisibilityControl setCallback() failed.");
     }
 
     // Set IMeasurementCorrections.hal callback.
@@ -1994,18 +2008,19 @@
         sp<IMeasurementCorrectionsCallback> gnssCorrectionsIfaceCbIface =
                 new MeasurementCorrectionsCallback();
         result = gnssCorrectionsIface->setCallback(gnssCorrectionsIfaceCbIface);
-        if (!result.isOk() || !result) {
-            ALOGI("SetCallback for IMeasurementCorrections interface failed.");
-        }
+        checkHidlReturn(result, "IMeasurementCorrections setCallback() failed.");
     }
 
     return JNI_TRUE;
 }
 
 static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
-    if (gnssHal != nullptr) {
-        gnssHal->cleanup();
+    if (gnssHal == nullptr) {
+        return;
     }
+
+    auto result = gnssHal->cleanup();
+    checkHidlReturn(result, "IGnss cleanup() failed.");
 }
 
 static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
@@ -2026,48 +2041,37 @@
                  preferred_accuracy,
                  preferred_time);
     }
-    if (!result.isOk()) {
-       ALOGE("%s: GNSS setPositionMode failed\n", __func__);
-       return JNI_FALSE;
-    } else {
-       return result;
-    }
+
+    return checkHidlReturn(result, "IGnss setPositionMode() failed.");
 }
 
 static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
-    if (gnssHal != nullptr) {
-        auto result = gnssHal->start();
-        if (!result.isOk()) {
-            return JNI_FALSE;
-        } else {
-            return result;
-        }
-    } else {
+    if (gnssHal == nullptr) {
         return JNI_FALSE;
     }
+
+    auto result = gnssHal->start();
+    return checkHidlReturn(result, "IGnss start() failed.");
 }
 
 static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
-    if (gnssHal != nullptr) {
-        auto result = gnssHal->stop();
-        if (!result.isOk()) {
-            return JNI_FALSE;
-        } else {
-            return result;
-        }
-    } else {
+    if (gnssHal == nullptr) {
         return JNI_FALSE;
     }
+
+    auto result = gnssHal->stop();
+    return checkHidlReturn(result, "IGnss stop() failed.");
 }
+
 static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
                                                                     jobject /* obj */,
                                                                     jint flags) {
-    if (gnssHal != nullptr) {
-        auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
-        if (!result.isOk()) {
-            ALOGE("Error in deleting aiding data");
-        }
+    if (gnssHal == nullptr) {
+        return;
     }
+
+    auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
+    checkHidlReturn(result, "IGnss deleteAidingData() failed.");
 }
 
 static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
@@ -2075,7 +2079,7 @@
     IAGnssRil_V1_0::AGnssRefLocation location;
 
     if (agnssRilIface == nullptr) {
-        ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
+        ALOGE("%s: IAGnssRil interface not available.", __func__);
         return;
     }
 
@@ -2094,18 +2098,20 @@
             break;
     }
 
-    agnssRilIface->setRefLocation(location);
+    auto result = agnssRilIface->setRefLocation(location);
+    checkHidlReturn(result, "IAGnssRil setRefLocation() failed.");
 }
 
 static void android_location_GnssLocationProvider_agps_set_id(JNIEnv* env, jobject /* obj */,
                                                              jint type, jstring  setid_string) {
     if (agnssRilIface == nullptr) {
-        ALOGE("no AGPS RIL interface in agps_set_id");
+        ALOGE("%s: IAGnssRil interface not available.", __func__);
         return;
     }
 
     ScopedJniString jniSetId{env, setid_string};
-    agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId);
+    auto result = agnssRilIface->setSetId((IAGnssRil_V1_0::SetIDType)type, jniSetId);
+    checkHidlReturn(result, "IAGnssRil setSetId() failed.");
 }
 
 static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
@@ -2122,12 +2128,12 @@
 
 static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
         jlong time, jlong timeReference, jint uncertainty) {
-    if (gnssHal != nullptr) {
-        auto result = gnssHal->injectTime(time, timeReference, uncertainty);
-        if (!result.isOk() || !result) {
-            ALOGE("%s: Gnss injectTime() failed", __func__);
-        }
+    if (gnssHal == nullptr) {
+        return;
     }
+
+    auto result = gnssHal->injectTime(time, timeReference, uncertainty);
+    checkHidlReturn(result, "IGnss injectTime() failed.");
 }
 
 static void android_location_GnssLocationProvider_inject_best_location(
@@ -2164,10 +2170,7 @@
                 elapsedRealtimeNanos,
                 elapsedRealtimeUncertaintyNanos);
         auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
-
-        if (!result.isOk() || !result) {
-            ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
-        }
+        checkHidlReturn(result, "IGnss injectBestLocation_2_0() failed.");
         return;
     }
 
@@ -2185,24 +2188,20 @@
                 bearingAccuracyDegrees,
                 timestamp);
         auto result = gnssHal_V1_1->injectBestLocation(location);
-
-        if (!result.isOk() || !result) {
-            ALOGE("%s: Gnss injectBestLocation() failed.", __func__);
-        }
-        return;
+        checkHidlReturn(result, "IGnss injectBestLocation() failed.");
     }
 
-    ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__);
+    ALOGE("IGnss injectBestLocation() is called but gnssHal_V1_1 is not available.");
 }
 
 static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
         jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
-    if (gnssHal != nullptr) {
-        auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
-        if (!result.isOk() || !result) {
-            ALOGE("%s: Gnss injectLocation() failed", __func__);
-        }
+    if (gnssHal == nullptr) {
+        return;
     }
+
+    auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
+    checkHidlReturn(result, "IGnss injectLocation() failed.");
 }
 
 static jboolean android_location_GnssLocationProvider_supports_psds(
@@ -2213,12 +2212,13 @@
 static void android_location_GnssLocationProvider_inject_psds_data(JNIEnv* env, jobject /* obj */,
         jbyteArray data, jint length) {
     if (gnssXtraIface == nullptr) {
-        ALOGE("XTRA Interface not supported");
+        ALOGE("%s: IGnssXtra interface not available.", __func__);
         return;
     }
 
     jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
-    gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
+    auto result = gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
+    checkHidlReturn(result, "IGnssXtra injectXtraData() failed.");
     env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
 }
 
@@ -2245,9 +2245,7 @@
     ScopedJniString jniApn{env, apn};
     auto result = agnssIface->dataConnOpen(jniApn,
             static_cast<IAGnss_V1_0::ApnIpType>(apnIpType));
-    if (!result.isOk() || !result){
-        ALOGE("%s: Failed to set APN and its IP type", __func__);
-    }
+    checkHidlReturn(result, "IAGnss dataConnOpen() failed. APN and its IP type not set.");
 }
 
 void AGnssDispatcher::dataConnOpen(sp<IAGnss_V2_0> agnssIface_V2_0, JNIEnv* env,
@@ -2255,25 +2253,19 @@
     ScopedJniString jniApn{env, apn};
     auto result = agnssIface_V2_0->dataConnOpen(static_cast<uint64_t>(networkHandle), jniApn,
             static_cast<IAGnss_V2_0::ApnIpType>(apnIpType));
-    if (!result.isOk() || !result){
-        ALOGE("%s: Failed to set APN and its IP type", __func__);
-    }
+    checkHidlReturn(result, "IAGnss 2.0 dataConnOpen() failed. APN and its IP type not set.");
 }
 
 template<class T>
 void AGnssDispatcher::dataConnClosed(sp<T> agnssIface) {
     auto result = agnssIface->dataConnClosed();
-    if (!result.isOk() || !result) {
-        ALOGE("%s: Failed to close AGnss data connection", __func__);
-    }
+    checkHidlReturn(result, "IAGnss dataConnClosed() failed.");
 }
 
 template<class T>
 void AGnssDispatcher::dataConnFailed(sp<T> agnssIface) {
     auto result = agnssIface->dataConnFailed();
-    if (!result.isOk() || !result) {
-        ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
-    }
+    checkHidlReturn(result, "IAGnss dataConnFailed() failed.");
 }
 
 template <class T, class U>
@@ -2282,9 +2274,7 @@
     ScopedJniString jniHostName{env, hostname};
     auto result = agnssIface->setServer(static_cast<typename U::AGnssType>(type),
             jniHostName, port);
-    if (!result.isOk() || !result) {
-        ALOGE("%s: Failed to set AGnss host name and port", __func__);
-    }
+    checkHidlReturn(result, "IAGnss setServer() failed. Host name and port not set.");
 }
 
 static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
@@ -2299,7 +2289,7 @@
     } else if (agnssIface != nullptr) {
         AGnssDispatcher::dataConnOpen(agnssIface, env, apn, apnIpType);
     } else {
-        ALOGE("%s: AGPS interface not supported", __func__);
+        ALOGE("%s: IAGnss interface not available.", __func__);
         return;
     }
 }
@@ -2311,7 +2301,7 @@
     } else if (agnssIface != nullptr) {
         AGnssDispatcher::dataConnClosed(agnssIface);
     } else {
-        ALOGE("%s: AGPS interface not supported", __func__);
+        ALOGE("%s: IAGnss interface not available.", __func__);
         return;
     }
 }
@@ -2323,7 +2313,7 @@
     } else if (agnssIface != nullptr) {
         AGnssDispatcher::dataConnFailed(agnssIface);
     } else {
-        ALOGE("%s: AGPS interface not supported", __func__);
+        ALOGE("%s: IAGnss interface not available.", __func__);
         return;
     }
 }
@@ -2337,26 +2327,30 @@
         AGnssDispatcher::setServer<IAGnss_V1_0, IAGnssCallback_V1_0>(agnssIface, env, type,
                 hostname, port);
     } else {
-        ALOGE("%s: AGPS interface not supported", __func__);
+        ALOGE("%s: IAGnss interface not available.", __func__);
         return;
     }
 }
 
 static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
-      jobject /* obj */, jint notifId, jint response) {
+        jobject /* obj */, jint notifId, jint response) {
     if (gnssNiIface == nullptr) {
-        ALOGE("no NI interface in send_ni_response");
+        ALOGE("%s: IGnssNi interface not available.", __func__);
         return;
     }
 
-    gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
+    auto result = gnssNiIface->respond(notifId,
+            static_cast<IGnssNiCallback::GnssUserResponseType>(response));
+    checkHidlReturn(result, "IGnssNi respond() failed.");
 }
 
-const IGnssDebug_V1_0::SatelliteData& getSatelliteData(const hidl_vec<IGnssDebug_V1_0::SatelliteData>& satelliteDataArray, size_t i) {
+const IGnssDebug_V1_0::SatelliteData& getSatelliteData(
+        const hidl_vec<IGnssDebug_V1_0::SatelliteData>& satelliteDataArray, size_t i) {
     return satelliteDataArray[i];
 }
 
-const IGnssDebug_V1_0::SatelliteData& getSatelliteData(const hidl_vec<IGnssDebug_V2_0::SatelliteData>& satelliteDataArray, size_t i) {
+const IGnssDebug_V1_0::SatelliteData& getSatelliteData(
+        const hidl_vec<IGnssDebug_V2_0::SatelliteData>& satelliteDataArray, size_t i) {
     return satelliteDataArray[i].v1_0;
 }
 
@@ -2424,7 +2418,7 @@
 
 static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
                                                                        jobject /* obj */) {
-    jstring result = nullptr;
+    jstring internalStateStr = nullptr;
     /*
      * TODO: Create a jobject to represent GnssDebug.
      */
@@ -2432,21 +2426,27 @@
     std::stringstream internalState;
 
     if (gnssDebugIface == nullptr) {
-        internalState << "Gnss Debug Interface not available"  << std::endl;
+        ALOGE("%s: IGnssDebug interface not available.", __func__);
     } else if (gnssDebugIface_V2_0 != nullptr) {
         IGnssDebug_V2_0::DebugData data;
-        gnssDebugIface_V2_0->getDebugData_2_0([&data](const IGnssDebug_V2_0::DebugData& debugData) {
-            data = debugData;
-        });
-        result = parseDebugData(env, internalState, data);
+        auto result = gnssDebugIface_V2_0->getDebugData_2_0(
+                [&data](const IGnssDebug_V2_0::DebugData& debugData) {
+                    data = debugData;
+                });
+        if (checkHidlReturn(result, "IGnssDebug getDebugData_2_0() failed.")) {
+            internalStateStr = parseDebugData(env, internalState, data);
+        }
     } else {
         IGnssDebug_V1_0::DebugData data;
-        gnssDebugIface->getDebugData([&data](const IGnssDebug_V1_0::DebugData& debugData) {
-            data = debugData;
-        });
-        result = parseDebugData(env, internalState, data);
+        auto result = gnssDebugIface->getDebugData(
+                [&data](const IGnssDebug_V1_0::DebugData& debugData) {
+                    data = debugData;
+                });
+        if (checkHidlReturn(result, "IGnssDebug getDebugData() failed.")) {
+            internalStateStr = parseDebugData(env, internalState, data);
+        }
     }
-    return result;
+    return internalStateStr;
 }
 
 static jboolean android_location_GnssLocationProvider_is_gnss_visibility_control_supported(
@@ -2473,26 +2473,20 @@
         };
 
         auto result = agnssRilIface_V2_0->updateNetworkState_2_0(networkAttributes);
-        if (!result.isOk() || !result) {
-            ALOGE("updateNetworkState_2_0 failed");
-        }
+        checkHidlReturn(result, "IAGnssRil updateNetworkState_2_0() failed.");
     } else if (agnssRilIface != nullptr) {
         ScopedJniString jniApn{env, apn};
         hidl_string hidlApn{jniApn};
         auto result = agnssRilIface->updateNetworkState(connected,
                 static_cast<IAGnssRil_V1_0::NetworkType>(type), roaming);
-        if (!result.isOk() || !result) {
-            ALOGE("updateNetworkState failed");
-        }
+        checkHidlReturn(result, "IAGnssRil updateNetworkState() failed.");
 
         if (!hidlApn.empty()) {
             result = agnssRilIface->updateNetworkAvailability(available, hidlApn);
-            if (!result.isOk() || !result) {
-                ALOGE("updateNetworkAvailability failed");
-            }
+            checkHidlReturn(result, "IAGnssRil updateNetworkAvailability() failed.");
         }
     } else {
-        ALOGE("AGnssRilInterface does not exist");
+        ALOGE("%s: IAGnssRil interface not available.", __func__);
     }
 }
 
@@ -2505,49 +2499,49 @@
         jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
         jint last_transition, jint monitor_transition, jint notification_responsiveness,
         jint unknown_timer) {
-    if (gnssGeofencingIface != nullptr) {
-        auto result = gnssGeofencingIface->addGeofence(
-                geofenceId, latitude, longitude, radius,
-                static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
-                monitor_transition, notification_responsiveness, unknown_timer);
-        return boolToJbool(result.isOk());
-    } else {
-        ALOGE("Geofence Interface not available");
+    if (gnssGeofencingIface == nullptr) {
+        ALOGE("%s: IGnssGeofencing interface not available.", __func__);
+        return JNI_FALSE;
     }
-    return JNI_FALSE;
+
+    auto result = gnssGeofencingIface->addGeofence(
+            geofenceId, latitude, longitude, radius,
+            static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
+            monitor_transition, notification_responsiveness, unknown_timer);
+    return checkHidlReturn(result, "IGnssGeofencing addGeofence() failed.");
 }
 
 static jboolean android_location_GnssGeofenceProvider_remove_geofence(JNIEnv* /* env */,
         jobject /* obj */, jint geofenceId) {
-    if (gnssGeofencingIface != nullptr) {
-        auto result = gnssGeofencingIface->removeGeofence(geofenceId);
-        return boolToJbool(result.isOk());
-    } else {
-        ALOGE("Geofence interface not available");
+    if (gnssGeofencingIface == nullptr) {
+        ALOGE("%s: IGnssGeofencing interface not available.", __func__);
+        return JNI_FALSE;
     }
-    return JNI_FALSE;
+
+    auto result = gnssGeofencingIface->removeGeofence(geofenceId);
+    return checkHidlReturn(result, "IGnssGeofencing removeGeofence() failed.");
 }
 
 static jboolean android_location_GnssGeofenceProvider_pause_geofence(JNIEnv* /* env */,
         jobject /* obj */, jint geofenceId) {
-    if (gnssGeofencingIface != nullptr) {
-        auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
-        return boolToJbool(result.isOk());
-    } else {
-        ALOGE("Geofence interface not available");
+    if (gnssGeofencingIface == nullptr) {
+        ALOGE("%s: IGnssGeofencing interface not available.", __func__);
+        return JNI_FALSE;
     }
-    return JNI_FALSE;
+
+    auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
+    return checkHidlReturn(result, "IGnssGeofencing pauseGeofence() failed.");
 }
 
 static jboolean android_location_GnssGeofenceProvider_resume_geofence(JNIEnv* /* env */,
         jobject /* obj */, jint geofenceId, jint monitor_transition) {
-    if (gnssGeofencingIface != nullptr) {
-        auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
-        return boolToJbool(result.isOk());
-    } else {
-        ALOGE("Geofence interface not available");
+    if (gnssGeofencingIface == nullptr) {
+        ALOGE("%s: IGnssGeofencing interface not available.", __func__);
+        return JNI_FALSE;
     }
-    return JNI_FALSE;
+
+    auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
+    return checkHidlReturn(result, "IGnssGeofencing resumeGeofence() failed.");
 }
 
 static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
@@ -2564,12 +2558,12 @@
         jobject /* obj */,
         jboolean enableFullTracking) {
     if (gnssMeasurementIface == nullptr) {
-        ALOGE("GNSS Measurement interface is not available.");
+        ALOGE("%s: IGnssMeasurement interface not available.", __func__);
         return JNI_FALSE;
     }
 
     sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
-    IGnssMeasurement_V1_0::GnssMeasurementStatus result =
+    Return<IGnssMeasurement_V1_0::GnssMeasurementStatus> result =
             IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;
     if (gnssMeasurementIface_V2_0 != nullptr) {
         result = gnssMeasurementIface_V2_0->setCallback_2_0(cbIface, enableFullTracking);
@@ -2578,14 +2572,20 @@
     } else {
         if (enableFullTracking == JNI_TRUE) {
             // full tracking mode not supported in 1.0 HAL
+            result.assertOk(); // isOk() must be called before result destructor is invoked.
             return JNI_FALSE;
         }
         result = gnssMeasurementIface->setCallback(cbIface);
     }
 
-    if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
+    if (!checkHidlReturn(result, "IGnssMeasurement setCallback() failed.")) {
+        return JNI_FALSE;
+    }
+
+    IGnssMeasurement_V1_0::GnssMeasurementStatus initRet = result;
+    if (initRet != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
         ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
-              static_cast<int32_t>(result));
+              static_cast<int32_t>(initRet));
         return JNI_FALSE;
     } else {
         ALOGD("gnss measurement infc has been enabled");
@@ -2598,12 +2598,12 @@
         JNIEnv* env,
         jobject obj) {
     if (gnssMeasurementIface == nullptr) {
-        ALOGE("Measurement interface not available");
+        ALOGE("%s: IGnssMeasurement interface not available.", __func__);
         return JNI_FALSE;
     }
 
     auto result = gnssMeasurementIface->close();
-    return boolToJbool(result.isOk());
+    return checkHidlReturn(result, "IGnssMeasurement close() failed.");
 }
 
 static jboolean
@@ -2718,8 +2718,8 @@
         .satCorrections = list,
     };
 
-    gnssCorrectionsIface->setCorrections(measurementCorrections);
-    return JNI_TRUE;
+    auto result = gnssCorrectionsIface->setCorrections(measurementCorrections);
+    return checkHidlReturn(result, "IMeasurementCorrections setCorrections() failed.");
 }
 
 static jboolean android_location_GnssNavigationMessageProvider_is_navigation_message_supported(
@@ -2735,17 +2735,20 @@
         JNIEnv* env,
         jobject obj) {
     if (gnssNavigationMessageIface == nullptr) {
-        ALOGE("Navigation Message interface is not available.");
+        ALOGE("%s: IGnssNavigationMessage interface not available.", __func__);
         return JNI_FALSE;
     }
 
     sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
             new GnssNavigationMessageCallback();
-    IGnssNavigationMessage::GnssNavigationMessageStatus result =
-            gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
+    auto result = gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
+    if (!checkHidlReturn(result, "IGnssNavigationMessage setCallback() failed.")) {
+        return JNI_FALSE;
+    }
 
-    if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
-        ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
+    IGnssNavigationMessage::GnssNavigationMessageStatus initRet = result;
+    if (initRet != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
+        ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(initRet));
         return JNI_FALSE;
     }
 
@@ -2756,43 +2759,35 @@
         JNIEnv* env,
         jobject obj) {
     if (gnssNavigationMessageIface == nullptr) {
-        ALOGE("Navigation Message interface is not available.");
+        ALOGE("%s: IGnssNavigationMessage interface not available.", __func__);
         return JNI_FALSE;
     }
 
     auto result = gnssNavigationMessageIface->close();
-    return boolToJbool(result.isOk());
+    return checkHidlReturn(result, "IGnssNavigationMessage close() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv*,
                                                                           jobject,
                                                                           jint emergencySuplPdn) {
     if (gnssConfigurationIface == nullptr) {
-        ALOGE("no GNSS configuration interface available");
+        ALOGE("%s: IGnssConfiguration interface not available.", __func__);
         return JNI_FALSE;
     }
 
     auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setEmergencySuplPdn() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_supl_version(JNIEnv*,
                                                                     jobject,
                                                                     jint version) {
     if (gnssConfigurationIface == nullptr) {
-        ALOGE("no GNSS configuration interface available");
+        ALOGE("%s: IGnssConfiguration interface not available.", __func__);
         return JNI_FALSE;
     }
     auto result = gnssConfigurationIface->setSuplVersion(version);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setSuplVersion() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_supl_es(JNIEnv*,
@@ -2804,32 +2799,24 @@
     }
 
     if (gnssConfigurationIface == nullptr) {
-        ALOGE("no GNSS configuration interface available");
+        ALOGE("%s: IGnssConfiguration interface not available.", __func__);
         return JNI_FALSE;
     }
 
     auto result = gnssConfigurationIface->setSuplEs(suplEs);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setSuplEs() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_supl_mode(JNIEnv*,
                                                                  jobject,
                                                                  jint mode) {
     if (gnssConfigurationIface == nullptr) {
-        ALOGE("no GNSS configuration interface available");
+        ALOGE("%s: IGnssConfiguration interface not available.", __func__);
         return JNI_FALSE;
     }
 
     auto result = gnssConfigurationIface->setSuplMode(mode);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setSuplMode() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_gps_lock(JNIEnv*,
@@ -2841,55 +2828,42 @@
     }
 
     if (gnssConfigurationIface == nullptr) {
-        ALOGE("no GNSS configuration interface available");
+        ALOGE("%s: IGnssConfiguration interface not available.", __func__);
         return JNI_FALSE;
     }
 
     auto result = gnssConfigurationIface->setGpsLock(gpsLock);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setGpsLock() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_lpp_profile(JNIEnv*,
                                                                    jobject,
                                                                    jint lppProfile) {
     if (gnssConfigurationIface == nullptr) {
-        ALOGE("no GNSS configuration interface available");
+        ALOGE("%s: IGnssConfiguration interface not available.", __func__);
         return JNI_FALSE;
     }
 
     auto result = gnssConfigurationIface->setLppProfile(lppProfile);
-
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setLppProfile() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_gnss_pos_protocol_select(JNIEnv*,
                                                                             jobject,
                                                                             jint gnssPosProtocol) {
     if (gnssConfigurationIface == nullptr) {
-        ALOGE("no GNSS configuration interface available");
+        ALOGE("%s: IGnssConfiguration interface not available.", __func__);
         return JNI_FALSE;
     }
 
     auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setGlonassPositioningProtocol() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_satellite_blacklist(
         JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
     if (gnssConfigurationIface_V1_1 == nullptr) {
-        ALOGI("No GNSS Satellite Blacklist interface available");
+        ALOGI("IGnssConfiguration interface does not support satellite blacklist.");
         return JNI_FALSE;
     }
 
@@ -2920,17 +2894,13 @@
     }
 
     auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setBlacklist() failed.");
 }
 
 static jboolean android_location_GnssConfiguration_set_es_extension_sec(
         JNIEnv*, jobject, jint emergencyExtensionSeconds) {
     if (gnssConfigurationIface == nullptr) {
-        ALOGE("no GNSS configuration interface available");
+        ALOGE("%s: IGnssConfiguration interface not available.", __func__);
         return JNI_FALSE;
     }
 
@@ -2941,11 +2911,7 @@
     }
 
     auto result = gnssConfigurationIface_V2_0->setEsExtensionSec(emergencyExtensionSeconds);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssConfiguration setEsExtensionSec() failed.");
 }
 
 static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) {
@@ -2953,20 +2919,22 @@
         return 0; // batching not supported, size = 0
     }
     auto result = gnssBatchingIface->getBatchSize();
-    if (result.isOk()) {
-        return static_cast<jint>(result);
-    } else {
+    if (!checkHidlReturn(result, "IGnssBatching getBatchSize() failed.")) {
         return 0; // failure in binder, don't support batching
     }
+
+    return static_cast<jint>(result);
 }
 
 static jboolean android_location_GnssBatchingProvider_init_batching(JNIEnv*, jclass) {
     if (gnssBatchingIface_V2_0 != nullptr) {
         sp<IGnssBatchingCallback_V2_0> gnssBatchingCbIface_V2_0 = new GnssBatchingCallback_V2_0();
-        return static_cast<jboolean>(gnssBatchingIface_V2_0->init_2_0(gnssBatchingCbIface_V2_0));
+        auto result = gnssBatchingIface_V2_0->init_2_0(gnssBatchingCbIface_V2_0);
+        return checkHidlReturn(result, "IGnssBatching init_2_0() failed.");
     } else if (gnssBatchingIface != nullptr) {
         sp<IGnssBatchingCallback_V1_0> gnssBatchingCbIface_V1_0 = new GnssBatchingCallback_V1_0();
-        return static_cast<jboolean>(gnssBatchingIface->init(gnssBatchingCbIface_V1_0));
+        auto result = gnssBatchingIface->init(gnssBatchingCbIface_V1_0);
+        return checkHidlReturn(result, "IGnssBatching init() failed.");
     } else {
         return JNI_FALSE; // batching not supported
     }
@@ -2976,7 +2944,8 @@
     if (gnssBatchingIface == nullptr) {
         return; // batching not supported
     }
-    gnssBatchingIface->cleanup();
+    auto result = gnssBatchingIface->cleanup();
+    checkHidlReturn(result, "IGnssBatching cleanup() failed.");
 }
 
 static jboolean android_location_GnssBatchingProvider_start_batch(JNIEnv*, jclass,
@@ -2993,29 +2962,30 @@
         options.flags = 0;
     }
 
-    return static_cast<jboolean>(gnssBatchingIface->start(options));
+    auto result = gnssBatchingIface->start(options);
+    return checkHidlReturn(result, "IGnssBatching start() failed.");
 }
 
 static void android_location_GnssBatchingProvider_flush_batch(JNIEnv*, jclass) {
     if (gnssBatchingIface == nullptr) {
         return; // batching not supported
     }
-
-    gnssBatchingIface->flush();
+    auto result = gnssBatchingIface->flush();
+    checkHidlReturn(result, "IGnssBatching flush() failed.");
 }
 
 static jboolean android_location_GnssBatchingProvider_stop_batch(JNIEnv*, jclass) {
     if (gnssBatchingIface == nullptr) {
         return JNI_FALSE; // batching not supported
     }
-
-    return gnssBatchingIface->stop();
+    auto result = gnssBatchingIface->stop();
+    return checkHidlReturn(result, "IGnssBatching stop() failed.");
 }
 
 static jboolean android_location_GnssVisibilityControl_enable_nfw_location_access(
         JNIEnv* env, jobject, jobjectArray proxyApps) {
     if (gnssVisibilityControlIface == nullptr) {
-        ALOGI("No GNSS Visibility Control interface available");
+        ALOGI("IGnssVisibilityControl interface not available.");
         return JNI_FALSE;
     }
 
@@ -3028,11 +2998,7 @@
     }
 
     auto result = gnssVisibilityControlIface->enableNfwLocationAccess(hidlProxyApps);
-    if (result.isOk()) {
-        return result;
-    } else {
-        return JNI_FALSE;
-    }
+    return checkHidlReturn(result, "IGnssVisibilityControl enableNfwLocationAccess() failed.");
 }
 
 static const JNINativeMethod sMethods[] = {
diff --git a/services/devicepolicy/TEST_MAPPING b/services/devicepolicy/TEST_MAPPING
index febfa17..a5ee3e2 100644
--- a/services/devicepolicy/TEST_MAPPING
+++ b/services/devicepolicy/TEST_MAPPING
@@ -1,12 +1,20 @@
 {
-  "postsubmit": [
+  "presubmit": [
     {
       "name": "CtsDevicePolicyManagerTestCases",
       "options": [
         {
           "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+        },
+        {
+          "exclude-annotation": "android.platform.test.annotations.LargeTest"
         }
       ]
     }
+  ],
+  "postsubmit": [
+    {
+      "name": "CtsDevicePolicyManagerTestCases"
+    }
   ]
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ac7c16e..68c9bad 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -196,6 +196,7 @@
 import android.os.UserManagerInternal;
 import android.os.UserManagerInternal.UserRestrictionsListener;
 import android.os.storage.StorageManager;
+import android.permission.IPermissionManager;
 import android.permission.PermissionControllerManager;
 import android.provider.CalendarContract;
 import android.provider.ContactsContract.QuickContact;
@@ -228,7 +229,6 @@
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.IAccessibilityManager;
 import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodSystemProperty;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -493,6 +493,7 @@
     final Context mContext;
     final Injector mInjector;
     final IPackageManager mIPackageManager;
+    final IPermissionManager mIPermissionManager;
     final UserManager mUserManager;
     final UserManagerInternal mUserManagerInternal;
     final UsageStatsManagerInternal mUsageStatsManagerInternal;
@@ -1975,6 +1976,10 @@
             return AppGlobals.getPackageManager();
         }
 
+        IPermissionManager getIPermissionManager() {
+            return AppGlobals.getPermissionManager();
+        }
+
         IBackupManager getIBackupManager() {
             return IBackupManager.Stub.asInterface(
                     ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -2218,6 +2223,7 @@
         mUsageStatsManagerInternal = Preconditions.checkNotNull(
                 injector.getUsageStatsManagerInternal());
         mIPackageManager = Preconditions.checkNotNull(injector.getIPackageManager());
+        mIPermissionManager = Preconditions.checkNotNull(injector.getIPermissionManager());
         mTelephonyManager = Preconditions.checkNotNull(injector.getTelephonyManager());
 
         mLocalService = new LocalService();
@@ -4119,9 +4125,8 @@
 
     @Override
     public boolean isSeparateProfileChallengeAllowed(int userHandle) {
-        if (!isCallerWithSystemUid()) {
-            throw new SecurityException("Caller must be system");
-        }
+        enforceSystemCaller("query separate challenge support");
+
         ComponentName profileOwner = getProfileOwner(userHandle);
         // Profile challenge is supported on N or newer release.
         return profileOwner != null &&
@@ -5943,10 +5948,7 @@
     @Override
     public void choosePrivateKeyAlias(final int uid, final Uri uri, final String alias,
             final IBinder response) {
-        // Caller UID needs to be trusted, so we restrict this method to SYSTEM_UID callers.
-        if (!isCallerWithSystemUid()) {
-            return;
-        }
+        enforceSystemCaller("choose private key alias");
 
         final UserHandle caller = mInjector.binderGetCallingUserHandle();
         // If there is a profile owner, redirect to that; otherwise query the device owner.
@@ -6044,7 +6046,7 @@
      *
      * @param who the device owner or profile owner.
      * @param delegatePackage the name of the delegate package.
-     * @param scopes the list of delegation scopes to be given to the delegate package.
+     * @param scopeList the list of delegation scopes to be given to the delegate package.
      */
     @Override
     public void setDelegatedScopes(ComponentName who, String delegatePackage,
@@ -6443,7 +6445,7 @@
                     .setAdmin(admin)
                     .setStrings(vpnPackage)
                     .setBoolean(lockdown)
-                    .setInt(/* number of vpn packages */ 0)
+                    .setInt(lockdownWhitelist != null ? lockdownWhitelist.size() : 0)
                     .write();
         } finally {
             mInjector.binderRestoreCallingIdentity(token);
@@ -6654,7 +6656,7 @@
      */
     @Override
     public void setActivePasswordState(PasswordMetrics metrics, int userHandle) {
-        if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
+        if (!mLockPatternUtils.hasSecureLockScreen()) {
             return;
         }
         enforceFullCrossUsersPermission(userHandle);
@@ -6677,36 +6679,28 @@
         if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {
             return;
         }
-        enforceFullCrossUsersPermission(userId);
+        enforceSystemCaller("report password change");
 
         // Managed Profile password can only be changed when it has a separate challenge.
         if (!isSeparateProfileChallengeEnabled(userId)) {
             enforceNotManagedProfile(userId, "set the active password");
         }
 
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
-
         DevicePolicyData policy = getUserData(userId);
 
-        long ident = mInjector.binderClearCallingIdentity();
-        try {
-            synchronized (getLockObject()) {
-                policy.mFailedPasswordAttempts = 0;
-                updatePasswordValidityCheckpointLocked(userId, /* parent */ false);
-                saveSettingsLocked(userId);
-                updatePasswordExpirationsLocked(userId);
-                setExpirationAlarmCheckLocked(mContext, userId, /* parent */ false);
+        synchronized (getLockObject()) {
+            policy.mFailedPasswordAttempts = 0;
+            updatePasswordValidityCheckpointLocked(userId, /* parent */ false);
+            saveSettingsLocked(userId);
+            updatePasswordExpirationsLocked(userId);
+            setExpirationAlarmCheckLocked(mContext, userId, /* parent */ false);
 
-                // Send a broadcast to each profile using this password as its primary unlock.
-                sendAdminCommandForLockscreenPoliciesLocked(
-                        DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
-                        DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userId);
-            }
-            removeCaApprovalsIfNeeded(userId);
-        } finally {
-            mInjector.binderRestoreCallingIdentity(ident);
+            // Send a broadcast to each profile using this password as its primary unlock.
+            sendAdminCommandForLockscreenPoliciesLocked(
+                    DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
+                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userId);
         }
+        removeCaApprovalsIfNeeded(userId);
     }
 
     /**
@@ -8230,7 +8224,7 @@
         saveSettingsLocked(userId);
 
         try {
-            mIPackageManager.updatePermissionFlagsForAllApps(
+            mIPermissionManager.updatePermissionFlagsForAllApps(
                     PackageManager.FLAG_PERMISSION_POLICY_FIXED,
                     0  /* flagValues */, userId);
             pushUserRestrictions(userId);
@@ -8703,15 +8697,17 @@
         enforceSystemUserOrPermission(permission);
     }
 
-    private void enforceManagedProfile(int userHandle, String message) {
-        if(!isManagedProfile(userHandle)) {
-            throw new SecurityException("You can not " + message + " outside a managed profile.");
+    private void enforceManagedProfile(int userId, String message) {
+        if (!isManagedProfile(userId)) {
+            throw new SecurityException(String.format(
+                    "You can not %s outside a managed profile, userId = %d", message, userId));
         }
     }
 
-    private void enforceNotManagedProfile(int userHandle, String message) {
-        if(isManagedProfile(userHandle)) {
-            throw new SecurityException("You can not " + message + " for a managed profile.");
+    private void enforceNotManagedProfile(int userId, String message) {
+        if (isManagedProfile(userId)) {
+            throw new SecurityException(String.format(
+                    "You can not %s for a managed profile, userId = %d", message, userId));
         }
     }
 
@@ -8785,8 +8781,7 @@
 
     private void ensureCallerPackage(@Nullable String packageName) {
         if (packageName == null) {
-            Preconditions.checkState(isCallerWithSystemUid(),
-                    "Only caller can omit package name");
+            enforceSystemCaller("omit package name");
         } else {
             final int callingUid = mInjector.binderGetCallingUid();
             final int userId = mInjector.userHandleGetCallingUserId();
@@ -9098,10 +9093,8 @@
 
     @Override
     public ComponentName getRestrictionsProvider(int userHandle) {
+        enforceSystemCaller("query the permission provider");
         synchronized (getLockObject()) {
-            if (!isCallerWithSystemUid()) {
-                throw new SecurityException("Only the system can query the permission provider");
-            }
             DevicePolicyData userData = getUserData(userHandle);
             return userData != null ? userData.mRestrictionsProvider : null;
         }
@@ -9366,10 +9359,8 @@
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
         Preconditions.checkStringNotEmpty(packageName, "packageName is null");
-        if (!isCallerWithSystemUid()){
-            throw new SecurityException(
-                    "Only the system can query if an accessibility service is disabled by admin");
-        }
+        enforceSystemCaller("query if an accessibility service is disabled by admin");
+
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
             if (admin == null) {
@@ -9418,12 +9409,6 @@
             return false;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-
-        // TODO When InputMethodManager supports per user calls remove this restriction.
-        if (!InputMethodSystemProperty.PER_PROFILE_IME_ENABLED
-                && !checkCallerIsCurrentUserOrProfile()) {
-            return false;
-        }
         final int callingUserId = mInjector.userHandleGetCallingUserId();
         if (packageList != null) {
             List<InputMethodInfo> enabledImes = InputMethodManagerInternal.get()
@@ -9479,26 +9464,16 @@
         final int callingUserId = mInjector.userHandleGetCallingUserId();
         synchronized (getLockObject()) {
             List<String> result = null;
-            // If we have multiple profiles we return the intersection of the
-            // permitted lists. This can happen in cases where we have a device
-            // and profile owner.
-            int[] profileIds = InputMethodSystemProperty.PER_PROFILE_IME_ENABLED
-                    ? new int[]{callingUserId}
-                    : mUserManager.getProfileIdsWithDisabled(callingUserId);
-            for (int profileId : profileIds) {
-                // Just loop though all admins, only device or profiles
-                // owners can have permitted lists set.
-                DevicePolicyData policy = getUserDataUnchecked(profileId);
-                final int N = policy.mAdminList.size();
-                for (int j = 0; j < N; j++) {
-                    ActiveAdmin admin = policy.mAdminList.get(j);
-                    List<String> fromAdmin = admin.permittedInputMethods;
-                    if (fromAdmin != null) {
-                        if (result == null) {
-                            result = new ArrayList<String>(fromAdmin);
-                        } else {
-                            result.retainAll(fromAdmin);
-                        }
+            // Only device or profile owners can have permitted lists set.
+            DevicePolicyData policy = getUserDataUnchecked(callingUserId);
+            for (int i = 0; i < policy.mAdminList.size(); i++) {
+                ActiveAdmin admin = policy.mAdminList.get(i);
+                List<String> fromAdmin = admin.permittedInputMethods;
+                if (fromAdmin != null) {
+                    if (result == null) {
+                        result = new ArrayList<String>(fromAdmin);
+                    } else {
+                        result.retainAll(fromAdmin);
                     }
                 }
             }
@@ -9529,10 +9504,8 @@
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
         Preconditions.checkStringNotEmpty(packageName, "packageName is null");
-        if (!isCallerWithSystemUid()) {
-            throw new SecurityException(
-                    "Only the system can query if an input method is disabled by admin");
-        }
+        enforceSystemCaller("query if an input method is disabled by admin");
+
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
             if (admin == null) {
@@ -9589,10 +9562,8 @@
         }
 
         Preconditions.checkStringNotEmpty(packageName, "packageName is null or empty");
-        if (!isCallerWithSystemUid()) {
-            throw new SecurityException(
-                    "Only the system can query if a notification listener service is permitted");
-        }
+        enforceSystemCaller("query if a notification listener service is permitted");
+
         synchronized (getLockObject()) {
             ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
             if (profileOwner == null || profileOwner.permittedNotificationListeners == null) {
@@ -9604,6 +9575,12 @@
         }
     }
 
+    private void enforceSystemCaller(String action) {
+        if (!isCallerWithSystemUid()) {
+            throw new SecurityException("Only the system can " + action);
+        }
+    }
+
     private void maybeSendAdminEnabledBroadcastLocked(int userHandle) {
         DevicePolicyData policyData = getUserData(userHandle);
         if (policyData.mAdminBroadcastPending) {
@@ -10758,9 +10735,7 @@
 
     @Override
     public void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userHandle) {
-        if (!isCallerWithSystemUid()) {
-            throw new SecurityException("notifyLockTaskModeChanged can only be called by system");
-        }
+        enforceSystemCaller("call notifyLockTaskModeChanged");
         synchronized (getLockObject()) {
             final DevicePolicyData policy = getUserData(userHandle);
 
@@ -11018,7 +10993,11 @@
                 return false;
             }
             mLockPatternUtils.setLockScreenDisabled(disabled, userId);
-            mInjector.getIWindowManager().dismissKeyguard(null /* callback */, null /* message */);
+            if (disabled) {
+                mInjector
+                        .getIWindowManager()
+                        .dismissKeyguard(null /* callback */, null /* message */);
+            }
             DevicePolicyEventLogger
                     .createEvent(DevicePolicyEnums.SET_KEYGUARD_DISABLED)
                     .setAdmin(who)
@@ -12113,8 +12092,7 @@
         final ApplicationInfo ai;
         try {
             ai = mIPackageManager.getApplicationInfo(packageName, 0, userId);
-            final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion;
-            return targetSdkVersion;
+            return ai == null ? 0 : ai.targetSdkVersion;
         } catch (RemoteException e) {
             // Shouldn't happen
             return 0;
@@ -12163,8 +12141,7 @@
         Preconditions.checkNotNull(who, "ComponentName is null");
         final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getActiveAdminForUidLocked(who,
-                    mInjector.binderGetCallingUid());
+            ActiveAdmin admin = getActiveAdminForUidLocked(who, mInjector.binderGetCallingUid());
             if (!TextUtils.equals(admin.shortSupportMessage, message)) {
                 admin.shortSupportMessage = message;
                 saveSettingsLocked(userHandle);
@@ -12183,8 +12160,7 @@
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getActiveAdminForUidLocked(who,
-                    mInjector.binderGetCallingUid());
+            ActiveAdmin admin = getActiveAdminForUidLocked(who, mInjector.binderGetCallingUid());
             return admin.shortSupportMessage;
         }
     }
@@ -12197,8 +12173,7 @@
         Preconditions.checkNotNull(who, "ComponentName is null");
         final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getActiveAdminForUidLocked(who,
-                    mInjector.binderGetCallingUid());
+            ActiveAdmin admin = getActiveAdminForUidLocked(who, mInjector.binderGetCallingUid());
             if (!TextUtils.equals(admin.longSupportMessage, message)) {
                 admin.longSupportMessage = message;
                 saveSettingsLocked(userHandle);
@@ -12217,8 +12192,7 @@
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
         synchronized (getLockObject()) {
-            ActiveAdmin admin = getActiveAdminForUidLocked(who,
-                    mInjector.binderGetCallingUid());
+            ActiveAdmin admin = getActiveAdminForUidLocked(who, mInjector.binderGetCallingUid());
             return admin.longSupportMessage;
         }
     }
@@ -12229,9 +12203,8 @@
             return null;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        if (!isCallerWithSystemUid()) {
-            throw new SecurityException("Only the system can query support message for user");
-        }
+        enforceSystemCaller("query support message for user");
+
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
             if (admin != null) {
@@ -12247,9 +12220,8 @@
             return null;
         }
         Preconditions.checkNotNull(who, "ComponentName is null");
-        if (!isCallerWithSystemUid()) {
-            throw new SecurityException("Only the system can query support message for user");
-        }
+        enforceSystemCaller("query support message for user");
+
         synchronized (getLockObject()) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
             if (admin != null) {
@@ -12456,10 +12428,8 @@
         if (!mHasFeature) {
             return false;
         }
-        if (!isCallerWithSystemUid()) {
-            throw new SecurityException(
-                    "Only the system can query restricted pkgs for a specific user");
-        }
+        enforceSystemCaller("query restricted pkgs for a specific user");
+
         synchronized (getLockObject()) {
             final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId);
             if (admin != null && admin.meteredDisabledPackages != null) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
index 699bec2..261a83c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
@@ -33,7 +33,6 @@
 import android.content.pm.ResolveInfo;
 import android.util.ArraySet;
 import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodSystemProperty;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -61,17 +60,11 @@
 
     @VisibleForTesting
     interface Injector {
-        boolean isPerProfileImeEnabled();
         @NonNull
         List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId);
     }
 
     private static final class DefaultInjector implements Injector {
-        @Override
-        public boolean isPerProfileImeEnabled() {
-            return InputMethodSystemProperty.PER_PROFILE_IME_ENABLED;
-        }
-
         @NonNull
         @Override
         public List<InputMethodInfo> getInputMethodListAsUser(@UserIdInt int userId) {
@@ -108,13 +101,7 @@
         // Newly installed system apps are uninstalled when they are not required and are either
         // disallowed or have a launcher icon.
         nonRequiredApps.removeAll(getRequiredApps(provisioningAction, admin.getPackageName()));
-        if (mInjector.isPerProfileImeEnabled()) {
-            nonRequiredApps.removeAll(getSystemInputMethods(userId));
-        } else if (ACTION_PROVISION_MANAGED_DEVICE.equals(provisioningAction)
-                || ACTION_PROVISION_MANAGED_USER.equals(provisioningAction)) {
-            // Don't delete the system input method packages in case of Device owner provisioning.
-            nonRequiredApps.removeAll(getSystemInputMethods(userId));
-        }
+        nonRequiredApps.removeAll(getSystemInputMethods(userId));
         nonRequiredApps.addAll(getDisallowedApps(provisioningAction));
         return nonRequiredApps;
     }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4cb043c..a04875f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -22,6 +22,8 @@
 import static android.os.IServiceManager.DUMP_FLAG_PROTO;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.server.utils.TimingsTraceAndSlog.SYSTEM_SERVER_TIMING_TAG;
+
 import android.annotation.NonNull;
 import android.app.ActivityThread;
 import android.app.INotificationManager;
@@ -54,7 +56,6 @@
 import android.os.StrictMode;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.IStorageManager;
 import android.provider.DeviceConfig;
@@ -64,7 +65,6 @@
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Slog;
-import android.util.TimingsTraceLog;
 import android.view.WindowManager;
 import android.view.contentcapture.ContentCaptureManager;
 import android.view.inputmethod.InputMethodSystemProperty;
@@ -151,6 +151,7 @@
 import com.android.server.twilight.TwilightService;
 import com.android.server.uri.UriGrantsManagerService;
 import com.android.server.usage.UsageStatsService;
+import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.vr.VrManagerService;
 import com.android.server.webkit.WebViewUpdateService;
 import com.android.server.wm.ActivityTaskManagerService;
@@ -172,14 +173,6 @@
 
     private static final String TAG = "SystemServer";
 
-    // Tag for timing measurement of main thread.
-    private static final String SYSTEM_SERVER_TIMING_TAG = "SystemServerTiming";
-    // Tag for timing measurement of non-main asynchronous operations.
-    private static final String SYSTEM_SERVER_TIMING_ASYNC_TAG = SYSTEM_SERVER_TIMING_TAG + "Async";
-
-    private static final TimingsTraceLog BOOT_TIMINGS_TRACE_LOG
-            = new TimingsTraceLog(SYSTEM_SERVER_TIMING_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
-
     private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
     private static final String ENCRYPTED_STATE = "1";
 
@@ -370,8 +363,9 @@
     }
 
     private void run() {
+        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
         try {
-            traceBeginAndSlog("InitBeforeStartServices");
+            t.traceBegin("InitBeforeStartServices");
 
             // Record the process start information in sys props.
             SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
@@ -503,22 +497,22 @@
             // Prepare the thread pool for init tasks that can be parallelized
             SystemServerInitThreadPool.get();
         } finally {
-            traceEnd();  // InitBeforeStartServices
+            t.traceEnd();  // InitBeforeStartServices
         }
 
         // Start services.
         try {
-            traceBeginAndSlog("StartServices");
-            startBootstrapServices();
-            startCoreServices();
-            startOtherServices();
+            t.traceBegin("StartServices");
+            startBootstrapServices(t);
+            startCoreServices(t);
+            startOtherServices(t);
             SystemServerInitThreadPool.shutdown();
         } catch (Throwable ex) {
             Slog.e("System", "******************************************");
             Slog.e("System", "************ Failure starting system services", ex);
             throw ex;
         } finally {
-            traceEnd();
+            t.traceEnd(); // StartServices
         }
 
         StrictMode.initVmDefaults(null);
@@ -622,40 +616,42 @@
      * in one place here.  Unless your service is also entwined in these dependencies, it should be
      * initialized in one of the other functions.
      */
-    private void startBootstrapServices() {
+    private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
+        t.traceBegin("startBootstrapServices");
+
         // Start the watchdog as early as possible so we can crash the system server
         // if we deadlock during early boot
-        traceBeginAndSlog("StartWatchdog");
+        t.traceBegin("StartWatchdog");
         final Watchdog watchdog = Watchdog.getInstance();
         watchdog.start();
-        traceEnd();
+        t.traceEnd();
 
         Slog.i(TAG, "Reading configuration...");
         final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
-        traceBeginAndSlog(TAG_SYSTEM_CONFIG);
+        t.traceBegin(TAG_SYSTEM_CONFIG);
         SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
-        traceEnd();
+        t.traceEnd();
 
         // Wait for installd to finish starting up so that it has a chance to
         // create critical directories such as /data/user with the appropriate
         // permissions.  We need this to complete before we initialize other services.
-        traceBeginAndSlog("StartInstaller");
+        t.traceBegin("StartInstaller");
         Installer installer = mSystemServiceManager.startService(Installer.class);
-        traceEnd();
+        t.traceEnd();
 
         // In some cases after launching an app we need to access device identifiers,
         // therefore register the device identifier policy before the activity manager.
-        traceBeginAndSlog("DeviceIdentifiersPolicyService");
+        t.traceBegin("DeviceIdentifiersPolicyService");
         mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
-        traceEnd();
+        t.traceEnd();
 
         // Uri Grants Manager.
-        traceBeginAndSlog("UriGrantsManagerService");
+        t.traceBegin("UriGrantsManagerService");
         mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
-        traceEnd();
+        t.traceEnd();
 
         // Activity manager runs the show.
-        traceBeginAndSlog("StartActivityManager");
+        t.traceBegin("StartActivityManager");
         // TODO: Might need to move after migration to WM.
         ActivityTaskManagerService atm = mSystemServiceManager.startService(
                 ActivityTaskManagerService.Lifecycle.class).getService();
@@ -664,30 +660,30 @@
         mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
         mActivityManagerService.setInstaller(installer);
         mWindowManagerGlobalLock = atm.getGlobalLock();
-        traceEnd();
+        t.traceEnd();
 
         // Power manager needs to be started early because other services need it.
         // Native daemons may be watching for it to be registered so it must be ready
         // to handle incoming binder calls immediately (including being able to verify
         // the permissions for those calls).
-        traceBeginAndSlog("StartPowerManager");
+        t.traceBegin("StartPowerManager");
         mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
-        traceEnd();
+        t.traceEnd();
 
-        traceBeginAndSlog("StartThermalManager");
+        t.traceBegin("StartThermalManager");
         mSystemServiceManager.startService(ThermalManagerService.class);
-        traceEnd();
+        t.traceEnd();
 
         // Now that the power manager has been started, let the activity manager
         // initialize power management features.
-        traceBeginAndSlog("InitPowerManagement");
+        t.traceBegin("InitPowerManagement");
         mActivityManagerService.initPowerManagement();
-        traceEnd();
+        t.traceEnd();
 
         // Bring up recovery system in case a rescue party needs a reboot
-        traceBeginAndSlog("StartRecoverySystemService");
+        t.traceBegin("StartRecoverySystemService");
         mSystemServiceManager.startService(RecoverySystemService.class);
-        traceEnd();
+        t.traceEnd();
 
         // Now that we have the bare essentials of the OS up and running, take
         // note that we just booted, which might send out a rescue party if
@@ -695,27 +691,27 @@
         RescueParty.noteBoot(mSystemContext);
 
         // Manages LEDs and display backlight so we need it to bring up the display.
-        traceBeginAndSlog("StartLightsService");
+        t.traceBegin("StartLightsService");
         mSystemServiceManager.startService(LightsService.class);
-        traceEnd();
+        t.traceEnd();
 
-        traceBeginAndSlog("StartSidekickService");
+        t.traceBegin("StartSidekickService");
         // Package manager isn't started yet; need to use SysProp not hardware feature
         if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
             mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
         }
-        traceEnd();
+        t.traceEnd();
 
         // Display manager is needed to provide display metrics before package manager
         // starts up.
-        traceBeginAndSlog("StartDisplayManager");
+        t.traceBegin("StartDisplayManager");
         mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
-        traceEnd();
+        t.traceEnd();
 
         // We need the default display before we can initialize the package manager.
-        traceBeginAndSlog("WaitForDisplay");
-        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
-        traceEnd();
+        t.traceBegin("WaitForDisplay");
+        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
+        t.traceEnd();
 
         // Only run "core" apps if we're encrypting the device.
         String cryptState = VoldProperties.decrypt().orElse("");
@@ -732,12 +728,19 @@
             MetricsLogger.histogram(null, "boot_package_manager_init_start",
                     (int) SystemClock.elapsedRealtime());
         }
-        traceBeginAndSlog("StartPackageManagerService");
-        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
-                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
+
+        t.traceBegin("StartPackageManagerService");
+        try {
+            Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
+            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
+                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
+        } finally {
+            Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
+        }
+
         mFirstBoot = mPackageManagerService.isFirstBoot();
         mPackageManager = mSystemContext.getPackageManager();
-        traceEnd();
+        t.traceEnd();
         if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
             MetricsLogger.histogram(null, "boot_package_manager_init_ready",
                     (int) SystemClock.elapsedRealtime());
@@ -749,49 +752,51 @@
             boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                     false);
             if (!disableOtaDexopt) {
-                traceBeginAndSlog("StartOtaDexOptService");
+                t.traceBegin("StartOtaDexOptService");
                 try {
+                    Watchdog.getInstance().pauseWatchingCurrentThread("moveab");
                     OtaDexoptService.main(mSystemContext, mPackageManagerService);
                 } catch (Throwable e) {
                     reportWtf("starting OtaDexOptService", e);
                 } finally {
-                    traceEnd();
+                    Watchdog.getInstance().resumeWatchingCurrentThread("moveab");
+                    t.traceEnd();
                 }
             }
         }
 
-        traceBeginAndSlog("StartUserManagerService");
+        t.traceBegin("StartUserManagerService");
         mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
-        traceEnd();
+        t.traceEnd();
 
         // Initialize attribute cache used to cache resources from packages.
-        traceBeginAndSlog("InitAttributerCache");
+        t.traceBegin("InitAttributerCache");
         AttributeCache.init(mSystemContext);
-        traceEnd();
+        t.traceEnd();
 
         // Set up the Application instance for the system process and get started.
-        traceBeginAndSlog("SetSystemProcess");
+        t.traceBegin("SetSystemProcess");
         mActivityManagerService.setSystemProcess();
-        traceEnd();
+        t.traceEnd();
 
         // Complete the watchdog setup with an ActivityManager instance and listen for reboots
         // Do this only after the ActivityManagerService is properly started as a system process
-        traceBeginAndSlog("InitWatchdog");
+        t.traceBegin("InitWatchdog");
         watchdog.init(mSystemContext, mActivityManagerService);
-        traceEnd();
+        t.traceEnd();
 
         // DisplayManagerService needs to setup android.display scheduling related policies
         // since setSystemProcess() would have overridden policies due to setProcessGroup
         mDisplayManagerService.setupSchedulerPolicies();
 
         // Manages Overlay packages
-        traceBeginAndSlog("StartOverlayManagerService");
+        t.traceBegin("StartOverlayManagerService");
         mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
-        traceEnd();
+        t.traceEnd();
 
-        traceBeginAndSlog("StartSensorPrivacyService");
+        t.traceBegin("StartSensorPrivacyService");
         mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));
-        traceEnd();
+        t.traceEnd();
 
         if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
             // DisplayManager needs the overlay immediately.
@@ -804,72 +809,79 @@
         // Start sensor service in a separate thread. Completion should be checked
         // before using it.
         mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
-            TimingsTraceLog traceLog = new TimingsTraceLog(
-                    SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+            TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
             traceLog.traceBegin(START_SENSOR_SERVICE);
             startSensorService();
             traceLog.traceEnd();
         }, START_SENSOR_SERVICE);
+
+        t.traceEnd(); // startBootstrapServices
     }
 
     /**
      * Starts some essential services that are not tangled up in the bootstrap process.
      */
-    private void startCoreServices() {
-        traceBeginAndSlog("StartBatteryService");
+    private void startCoreServices(@NonNull TimingsTraceAndSlog t) {
+        t.traceBegin("startCoreServices");
+
+        t.traceBegin("StartBatteryService");
         // Tracks the battery level.  Requires LightService.
         mSystemServiceManager.startService(BatteryService.class);
-        traceEnd();
+        t.traceEnd();
 
         // Tracks application usage stats.
-        traceBeginAndSlog("StartUsageService");
+        t.traceBegin("StartUsageService");
         mSystemServiceManager.startService(UsageStatsService.class);
         mActivityManagerService.setUsageStatsManager(
                 LocalServices.getService(UsageStatsManagerInternal.class));
-        traceEnd();
+        t.traceEnd();
 
         // Tracks whether the updatable WebView is in a ready state and watches for update installs.
         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
-            traceBeginAndSlog("StartWebViewUpdateService");
+            t.traceBegin("StartWebViewUpdateService");
             mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
-            traceEnd();
+            t.traceEnd();
         }
 
         // Tracks and caches the device state.
-        traceBeginAndSlog("StartCachedDeviceStateService");
+        t.traceBegin("StartCachedDeviceStateService");
         mSystemServiceManager.startService(CachedDeviceStateService.class);
-        traceEnd();
+        t.traceEnd();
 
         // Tracks cpu time spent in binder calls
-        traceBeginAndSlog("StartBinderCallsStatsService");
+        t.traceBegin("StartBinderCallsStatsService");
         mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);
-        traceEnd();
+        t.traceEnd();
 
         // Tracks time spent in handling messages in handlers.
-        traceBeginAndSlog("StartLooperStatsService");
+        t.traceBegin("StartLooperStatsService");
         mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
-        traceEnd();
+        t.traceEnd();
 
         // Manages apk rollbacks.
-        traceBeginAndSlog("StartRollbackManagerService");
+        t.traceBegin("StartRollbackManagerService");
         mSystemServiceManager.startService(RollbackManagerService.class);
-        traceEnd();
+        t.traceEnd();
 
         // Service to capture bugreports.
-        traceBeginAndSlog("StartBugreportManagerService");
+        t.traceBegin("StartBugreportManagerService");
         mSystemServiceManager.startService(BugreportManagerService.class);
-        traceEnd();
+        t.traceEnd();
 
         // Serivce for GPU and GPU driver.
-        traceBeginAndSlog("GpuService");
+        t.traceBegin("GpuService");
         mSystemServiceManager.startService(GpuService.class);
-        traceEnd();
+        t.traceEnd();
+
+        t.traceEnd(); // startCoreServices
     }
 
     /**
      * Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
      */
-    private void startOtherServices() {
+    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
+        t.traceBegin("startOtherServices");
+
         final Context context = mSystemContext;
         VibratorService vibrator = null;
         DynamicSystemService dynamicSystem = null;
@@ -924,8 +936,7 @@
             mZygotePreload = SystemServerInitThreadPool.get().submit(() -> {
                 try {
                     Slog.i(TAG, SECONDARY_ZYGOTE_PRELOAD);
-                    TimingsTraceLog traceLog = new TimingsTraceLog(
-                            SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+                    TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
                     traceLog.traceBegin(SECONDARY_ZYGOTE_PRELOAD);
                     if (!Process.ZYGOTE_PROCESS.preloadDefault(Build.SUPPORTED_32_BIT_ABIS[0])) {
                         Slog.e(TAG, "Unable to preload default resources");
@@ -936,82 +947,82 @@
                 }
             }, SECONDARY_ZYGOTE_PRELOAD);
 
-            traceBeginAndSlog("StartKeyAttestationApplicationIdProviderService");
+            t.traceBegin("StartKeyAttestationApplicationIdProviderService");
             ServiceManager.addService("sec_key_att_app_id_provider",
                     new KeyAttestationApplicationIdProviderService(context));
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartKeyChainSystemService");
+            t.traceBegin("StartKeyChainSystemService");
             mSystemServiceManager.startService(KeyChainSystemService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartSchedulingPolicyService");
+            t.traceBegin("StartSchedulingPolicyService");
             ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartTelecomLoaderService");
+            t.traceBegin("StartTelecomLoaderService");
             mSystemServiceManager.startService(TelecomLoaderService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartTelephonyRegistry");
+            t.traceBegin("StartTelephonyRegistry");
             telephonyRegistry = new TelephonyRegistry(context);
             ServiceManager.addService("telephony.registry", telephonyRegistry);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartEntropyMixer");
+            t.traceBegin("StartEntropyMixer");
             mEntropyMixer = new EntropyMixer(context);
-            traceEnd();
+            t.traceEnd();
 
             mContentResolver = context.getContentResolver();
 
             // The AccountManager must come before the ContentService
-            traceBeginAndSlog("StartAccountManagerService");
+            t.traceBegin("StartAccountManagerService");
             mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartContentService");
+            t.traceBegin("StartContentService");
             mSystemServiceManager.startService(CONTENT_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("InstallSystemProviders");
+            t.traceBegin("InstallSystemProviders");
             mActivityManagerService.installSystemProviders();
             // Now that SettingsProvider is ready, reactivate SQLiteCompatibilityWalFlags
             SQLiteCompatibilityWalFlags.reset();
-            traceEnd();
+            t.traceEnd();
 
             // Records errors and logs, for example wtf()
             // Currently this service indirectly depends on SettingsProvider so do this after
             // InstallSystemProviders.
-            traceBeginAndSlog("StartDropBoxManager");
+            t.traceBegin("StartDropBoxManager");
             mSystemServiceManager.startService(DropBoxManagerService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartVibratorService");
+            t.traceBegin("StartVibratorService");
             vibrator = new VibratorService(context);
             ServiceManager.addService("vibrator", vibrator);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartDynamicSystemService");
+            t.traceBegin("StartDynamicSystemService");
             dynamicSystem = new DynamicSystemService(context);
             ServiceManager.addService("dynamic_system", dynamicSystem);
-            traceEnd();
+            t.traceEnd();
 
             if (!isWatch) {
-                traceBeginAndSlog("StartConsumerIrService");
+                t.traceBegin("StartConsumerIrService");
                 consumerIr = new ConsumerIrService(context);
                 ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartAlarmManagerService");
+            t.traceBegin("StartAlarmManagerService");
             mSystemServiceManager.startService(new AlarmManagerService(context));
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartInputManagerService");
+            t.traceBegin("StartInputManagerService");
             inputManager = new InputManagerService(context);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartWindowManagerService");
+            t.traceBegin("StartWindowManagerService");
             // WMS needs sensor service ready
             ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
             mSensorServiceStart = null;
@@ -1021,42 +1032,41 @@
                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
             ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                     /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("SetWindowManagerService");
+            t.traceBegin("SetWindowManagerService");
             mActivityManagerService.setWindowManager(wm);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("WindowManagerServiceOnInitReady");
+            t.traceBegin("WindowManagerServiceOnInitReady");
             wm.onInitReady();
-            traceEnd();
+            t.traceEnd();
 
             // Start receiving calls from HIDL services. Start in in a separate thread
             // because it need to connect to SensorManager. This have to start
             // after START_SENSOR_SERVICE is done.
             SystemServerInitThreadPool.get().submit(() -> {
-                TimingsTraceLog traceLog = new TimingsTraceLog(
-                        SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+                TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
                 traceLog.traceBegin(START_HIDL_SERVICES);
                 startHidlServices();
                 traceLog.traceEnd();
             }, START_HIDL_SERVICES);
 
             if (!isWatch && enableVrService) {
-                traceBeginAndSlog("StartVrManagerService");
+                t.traceBegin("StartVrManagerService");
                 mSystemServiceManager.startService(VrManagerService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartInputManager");
+            t.traceBegin("StartInputManager");
             inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
             inputManager.start();
-            traceEnd();
+            t.traceEnd();
 
             // TODO: Use service dependencies instead.
-            traceBeginAndSlog("DisplayManagerWindowManagerAndInputReady");
+            t.traceBegin("DisplayManagerWindowManagerAndInputReady");
             mDisplayManagerService.windowManagerAndInputReady();
-            traceEnd();
+            t.traceEnd();
 
             if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
                 Slog.i(TAG, "No Bluetooth Service (factory test)");
@@ -1064,30 +1074,30 @@
                     (PackageManager.FEATURE_BLUETOOTH)) {
                 Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)");
             } else {
-                traceBeginAndSlog("StartBluetoothService");
+                t.traceBegin("StartBluetoothService");
                 mSystemServiceManager.startService(BluetoothService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("IpConnectivityMetrics");
+            t.traceBegin("IpConnectivityMetrics");
             mSystemServiceManager.startService(IpConnectivityMetrics.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("NetworkWatchlistService");
+            t.traceBegin("NetworkWatchlistService");
             mSystemServiceManager.startService(NetworkWatchlistService.Lifecycle.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("PinnerService");
+            t.traceBegin("PinnerService");
             mSystemServiceManager.startService(PinnerService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("IorapForwardingService");
+            t.traceBegin("IorapForwardingService");
             mSystemServiceManager.startService(IorapForwardingService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("SignedConfigService");
+            t.traceBegin("SignedConfigService");
             SignedConfigService.registerUpdateReceiver(mSystemContext);
-            traceEnd();
+            t.traceEnd();
         } catch (RuntimeException e) {
             Slog.e("System", "******************************************");
             Slog.e("System", "************ Failure starting core service", e);
@@ -1114,35 +1124,35 @@
 
         // Bring up services needed for UI.
         if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
-            traceBeginAndSlog("StartInputMethodManagerLifecycle");
+            t.traceBegin("StartInputMethodManagerLifecycle");
             if (InputMethodSystemProperty.MULTI_CLIENT_IME_ENABLED) {
                 mSystemServiceManager.startService(
                         MultiClientInputMethodManagerService.Lifecycle.class);
             } else {
                 mSystemServiceManager.startService(InputMethodManagerService.Lifecycle.class);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartAccessibilityManagerService");
+            t.traceBegin("StartAccessibilityManagerService");
             try {
                 mSystemServiceManager.startService(ACCESSIBILITY_MANAGER_SERVICE_CLASS);
             } catch (Throwable e) {
                 reportWtf("starting Accessibility Manager", e);
             }
-            traceEnd();
+            t.traceEnd();
         }
 
-        traceBeginAndSlog("MakeDisplayReady");
+        t.traceBegin("MakeDisplayReady");
         try {
             wm.displayReady();
         } catch (Throwable e) {
             reportWtf("making display ready", e);
         }
-        traceEnd();
+        t.traceEnd();
 
         if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
             if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
-                traceBeginAndSlog("StartStorageManagerService");
+                t.traceBegin("StartStorageManagerService");
                 try {
                     /*
                      * NotificationManagerService is dependant on StorageManagerService,
@@ -1154,26 +1164,26 @@
                 } catch (Throwable e) {
                     reportWtf("starting StorageManagerService", e);
                 }
-                traceEnd();
+                t.traceEnd();
 
-                traceBeginAndSlog("StartStorageStatsService");
+                t.traceBegin("StartStorageStatsService");
                 try {
                     mSystemServiceManager.startService(STORAGE_STATS_SERVICE_CLASS);
                 } catch (Throwable e) {
                     reportWtf("starting StorageStatsService", e);
                 }
-                traceEnd();
+                t.traceEnd();
             }
         }
 
         // We start this here so that we update our configuration to set watch or television
         // as appropriate.
-        traceBeginAndSlog("StartUiModeManager");
+        t.traceBegin("StartUiModeManager");
         mSystemServiceManager.startService(UiModeManagerService.class);
-        traceEnd();
+        t.traceEnd();
 
         if (!mOnlyCore) {
-            traceBeginAndSlog("UpdatePackagesIfNeeded");
+            t.traceBegin("UpdatePackagesIfNeeded");
             try {
                 Watchdog.getInstance().pauseWatchingCurrentThread("dexopt");
                 mPackageManagerService.updatePackagesIfNeeded();
@@ -1182,19 +1192,19 @@
             } finally {
                 Watchdog.getInstance().resumeWatchingCurrentThread("dexopt");
             }
-            traceEnd();
+            t.traceEnd();
         }
 
-        traceBeginAndSlog("PerformFstrimIfNeeded");
+        t.traceBegin("PerformFstrimIfNeeded");
         try {
             mPackageManagerService.performFstrimIfNeeded();
         } catch (Throwable e) {
             reportWtf("performing fstrim", e);
         }
-        traceEnd();
+        t.traceEnd();
 
         if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
-            traceBeginAndSlog("StartLockSettingsService");
+            t.traceBegin("StartLockSettingsService");
             try {
                 mSystemServiceManager.startService(LOCK_SETTINGS_SERVICE_CLASS);
                 lockSettings = ILockSettings.Stub.asInterface(
@@ -1202,115 +1212,115 @@
             } catch (Throwable e) {
                 reportWtf("starting LockSettingsService service", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             final boolean hasPdb = !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
             final boolean hasGsi = SystemProperties.getInt(GSI_RUNNING_PROP, 0) > 0;
             if (hasPdb && !hasGsi) {
-                traceBeginAndSlog("StartPersistentDataBlock");
+                t.traceBegin("StartPersistentDataBlock");
                 mSystemServiceManager.startService(PersistentDataBlockService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartTestHarnessMode");
+            t.traceBegin("StartTestHarnessMode");
             mSystemServiceManager.startService(TestHarnessModeService.class);
-            traceEnd();
+            t.traceEnd();
 
             if (hasPdb || OemLockService.isHalPresent()) {
                 // Implementation depends on pdb or the OemLock HAL
-                traceBeginAndSlog("StartOemLockService");
+                t.traceBegin("StartOemLockService");
                 mSystemServiceManager.startService(OemLockService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartDeviceIdleController");
+            t.traceBegin("StartDeviceIdleController");
             mSystemServiceManager.startService(DeviceIdleController.class);
-            traceEnd();
+            t.traceEnd();
 
             // Always start the Device Policy Manager, so that the API is compatible with
             // API8.
-            traceBeginAndSlog("StartDevicePolicyManager");
+            t.traceBegin("StartDevicePolicyManager");
             mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class);
-            traceEnd();
+            t.traceEnd();
 
             if (!isWatch) {
-                traceBeginAndSlog("StartStatusBarManagerService");
+                t.traceBegin("StartStatusBarManagerService");
                 try {
                     statusBar = new StatusBarManagerService(context, wm);
                     ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
                 } catch (Throwable e) {
                     reportWtf("starting StatusBarManagerService", e);
                 }
-                traceEnd();
+                t.traceEnd();
             }
 
-            startContentCaptureService(context);
-            startAttentionService(context);
+            startContentCaptureService(context, t);
+            startAttentionService(context, t);
 
-            startSystemCaptionsManagerService(context);
+            startSystemCaptionsManagerService(context, t);
 
             // App prediction manager service
-            traceBeginAndSlog("StartAppPredictionService");
+            t.traceBegin("StartAppPredictionService");
             mSystemServiceManager.startService(APP_PREDICTION_MANAGER_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
             // Content suggestions manager service
-            traceBeginAndSlog("StartContentSuggestionsService");
+            t.traceBegin("StartContentSuggestionsService");
             mSystemServiceManager.startService(CONTENT_SUGGESTIONS_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("InitNetworkStackClient");
+            t.traceBegin("InitNetworkStackClient");
             try {
                 NetworkStackClient.getInstance().init();
             } catch (Throwable e) {
                 reportWtf("initializing NetworkStackClient", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartNetworkManagementService");
+            t.traceBegin("StartNetworkManagementService");
             try {
                 networkManagement = NetworkManagementService.create(context);
                 ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
             } catch (Throwable e) {
                 reportWtf("starting NetworkManagement Service", e);
             }
-            traceEnd();
+            t.traceEnd();
 
 
-            traceBeginAndSlog("StartIpSecService");
+            t.traceBegin("StartIpSecService");
             try {
                 ipSecService = IpSecService.create(context);
                 ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
             } catch (Throwable e) {
                 reportWtf("starting IpSec Service", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartTextServicesManager");
+            t.traceBegin("StartTextServicesManager");
             mSystemServiceManager.startService(TextServicesManagerService.Lifecycle.class);
-            traceEnd();
+            t.traceEnd();
 
             if (!disableSystemTextClassifier) {
-                traceBeginAndSlog("StartTextClassificationManagerService");
+                t.traceBegin("StartTextClassificationManagerService");
                 mSystemServiceManager
                         .startService(TextClassificationManagerService.Lifecycle.class);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartNetworkScoreService");
+            t.traceBegin("StartNetworkScoreService");
             mSystemServiceManager.startService(NetworkScoreService.Lifecycle.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartNetworkStatsService");
+            t.traceBegin("StartNetworkStatsService");
             try {
                 networkStats = NetworkStatsService.create(context, networkManagement);
                 ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
             } catch (Throwable e) {
                 reportWtf("starting NetworkStats Service", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartNetworkPolicyManagerService");
+            t.traceBegin("StartNetworkPolicyManagerService");
             try {
                 networkPolicy = new NetworkPolicyManagerService(context, mActivityManagerService,
                         networkManagement);
@@ -1318,57 +1328,57 @@
             } catch (Throwable e) {
                 reportWtf("starting NetworkPolicy Service", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             if (context.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_WIFI)) {
                 // Wifi Service must be started first for wifi-related services.
-                traceBeginAndSlog("StartWifi");
+                t.traceBegin("StartWifi");
                 mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
-                traceEnd();
-                traceBeginAndSlog("StartWifiScanning");
+                t.traceEnd();
+                t.traceBegin("StartWifiScanning");
                 mSystemServiceManager.startService(
                         "com.android.server.wifi.scanner.WifiScanningService");
-                traceEnd();
+                t.traceEnd();
             }
 
             if (context.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_WIFI_RTT)) {
-                traceBeginAndSlog("StartRttService");
+                t.traceBegin("StartRttService");
                 mSystemServiceManager.startService(
                         "com.android.server.wifi.rtt.RttService");
-                traceEnd();
+                t.traceEnd();
             }
 
             if (context.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_WIFI_AWARE)) {
-                traceBeginAndSlog("StartWifiAware");
+                t.traceBegin("StartWifiAware");
                 mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (context.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_WIFI_DIRECT)) {
-                traceBeginAndSlog("StartWifiP2P");
+                t.traceBegin("StartWifiP2P");
                 mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (context.getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_LOWPAN)) {
-                traceBeginAndSlog("StartLowpan");
+                t.traceBegin("StartLowpan");
                 mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
                     mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
-                traceBeginAndSlog("StartEthernet");
+                t.traceBegin("StartEthernet");
                 mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartConnectivityService");
+            t.traceBegin("StartConnectivityService");
             try {
                 connectivity = new ConnectivityService(
                         context, networkManagement, networkStats, networkPolicy);
@@ -1379,9 +1389,9 @@
             } catch (Throwable e) {
                 reportWtf("starting Connectivity Service", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartNsdService");
+            t.traceBegin("StartNsdService");
             try {
                 serviceDiscovery = NsdService.create(context);
                 ServiceManager.addService(
@@ -1389,84 +1399,81 @@
             } catch (Throwable e) {
                 reportWtf("starting Service Discovery Service", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartSystemUpdateManagerService");
+            t.traceBegin("StartSystemUpdateManagerService");
             try {
                 ServiceManager.addService(Context.SYSTEM_UPDATE_SERVICE,
                         new SystemUpdateManagerService(context));
             } catch (Throwable e) {
                 reportWtf("starting SystemUpdateManagerService", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartUpdateLockService");
+            t.traceBegin("StartUpdateLockService");
             try {
                 ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,
                         new UpdateLockService(context));
             } catch (Throwable e) {
                 reportWtf("starting UpdateLockService", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartNotificationManager");
+            t.traceBegin("StartNotificationManager");
             mSystemServiceManager.startService(NotificationManagerService.class);
             SystemNotificationChannels.removeDeprecated(context);
             SystemNotificationChannels.createAll(context);
             notification = INotificationManager.Stub.asInterface(
                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartDeviceMonitor");
+            t.traceBegin("StartDeviceMonitor");
             mSystemServiceManager.startService(DeviceStorageMonitorService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartLocationManagerService");
+            t.traceBegin("StartLocationManagerService");
             try {
                 location = new LocationManagerService(context);
                 ServiceManager.addService(Context.LOCATION_SERVICE, location);
             } catch (Throwable e) {
                 reportWtf("starting Location Manager", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartCountryDetectorService");
+            t.traceBegin("StartCountryDetectorService");
             try {
                 countryDetector = new CountryDetectorService(context);
                 ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
             } catch (Throwable e) {
                 reportWtf("starting Country Detector", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            final boolean useNewTimeServices = true;
-            if (useNewTimeServices) {
-                traceBeginAndSlog("StartTimeDetectorService");
-                try {
-                    mSystemServiceManager.startService(TIME_DETECTOR_SERVICE_CLASS);
-                } catch (Throwable e) {
-                    reportWtf("starting StartTimeDetectorService service", e);
-                }
-                traceEnd();
+            t.traceBegin("StartTimeDetectorService");
+            try {
+                mSystemServiceManager.startService(TIME_DETECTOR_SERVICE_CLASS);
+            } catch (Throwable e) {
+                reportWtf("starting StartTimeDetectorService service", e);
             }
+            t.traceEnd();
 
             if (!isWatch) {
-                traceBeginAndSlog("StartSearchManagerService");
+                t.traceBegin("StartSearchManagerService");
                 try {
                     mSystemServiceManager.startService(SEARCH_MANAGER_SERVICE_CLASS);
                 } catch (Throwable e) {
                     reportWtf("starting Search Service", e);
                 }
-                traceEnd();
+                t.traceEnd();
             }
 
             if (context.getResources().getBoolean(R.bool.config_enableWallpaperService)) {
-                traceBeginAndSlog("StartWallpaperManagerService");
+                t.traceBegin("StartWallpaperManagerService");
                 mSystemServiceManager.startService(WALLPAPER_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartAudioService");
+            t.traceBegin("StartAudioService");
             if (!isArc) {
                 mSystemServiceManager.startService(AudioService.Lifecycle.class);
             } else {
@@ -1478,25 +1485,25 @@
                     reportWtf("starting " + className, e);
                 }
             }
-            traceEnd();
+            t.traceEnd();
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BROADCAST_RADIO)) {
-                traceBeginAndSlog("StartBroadcastRadioService");
+                t.traceBegin("StartBroadcastRadioService");
                 mSystemServiceManager.startService(BroadcastRadioService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartDockObserver");
+            t.traceBegin("StartDockObserver");
             mSystemServiceManager.startService(DockObserver.class);
-            traceEnd();
+            t.traceEnd();
 
             if (isWatch) {
-                traceBeginAndSlog("StartThermalObserver");
+                t.traceBegin("StartThermalObserver");
                 mSystemServiceManager.startService(THERMAL_OBSERVER_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartWiredAccessoryManager");
+            t.traceBegin("StartWiredAccessoryManager");
             try {
                 // Listen for wired headset changes
                 inputManager.setWiredAccessoryCallbacks(
@@ -1504,36 +1511,36 @@
             } catch (Throwable e) {
                 reportWtf("starting WiredAccessoryManager", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
                 // Start MIDI Manager service
-                traceBeginAndSlog("StartMidiManager");
+                t.traceBegin("StartMidiManager");
                 mSystemServiceManager.startService(MIDI_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             // Start ADB Debugging Service
-            traceBeginAndSlog("StartAdbService");
+            t.traceBegin("StartAdbService");
             try {
                 mSystemServiceManager.startService(ADB_SERVICE_CLASS);
             } catch (Throwable e) {
                 Slog.e(TAG, "Failure starting AdbService");
             }
-            traceEnd();
+            t.traceEnd();
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)
                     || mPackageManager.hasSystemFeature(
                     PackageManager.FEATURE_USB_ACCESSORY)
                     || isEmulator) {
                 // Manage USB host and device support
-                traceBeginAndSlog("StartUsbService");
+                t.traceBegin("StartUsbService");
                 mSystemServiceManager.startService(USB_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (!isWatch) {
-                traceBeginAndSlog("StartSerialService");
+                t.traceBegin("StartSerialService");
                 try {
                     // Serial port support
                     serial = new SerialService(context);
@@ -1541,10 +1548,10 @@
                 } catch (Throwable e) {
                     Slog.e(TAG, "Failure starting SerialService", e);
                 }
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartHardwarePropertiesManagerService");
+            t.traceBegin("StartHardwarePropertiesManagerService");
             try {
                 hardwarePropertiesService = new HardwarePropertiesManagerService(context);
                 ServiceManager.addService(Context.HARDWARE_PROPERTIES_SERVICE,
@@ -1552,83 +1559,83 @@
             } catch (Throwable e) {
                 Slog.e(TAG, "Failure starting HardwarePropertiesManagerService", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartTwilightService");
+            t.traceBegin("StartTwilightService");
             mSystemServiceManager.startService(TwilightService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartColorDisplay");
+            t.traceBegin("StartColorDisplay");
             mSystemServiceManager.startService(ColorDisplayService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartJobScheduler");
+            t.traceBegin("StartJobScheduler");
             mSystemServiceManager.startService(JobSchedulerService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartSoundTrigger");
+            t.traceBegin("StartSoundTrigger");
             mSystemServiceManager.startService(SoundTriggerService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartTrustManager");
+            t.traceBegin("StartTrustManager");
             mSystemServiceManager.startService(TrustManagerService.class);
-            traceEnd();
+            t.traceEnd();
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP)) {
-                traceBeginAndSlog("StartBackupManager");
+                t.traceBegin("StartBackupManager");
                 mSystemServiceManager.startService(BACKUP_MANAGER_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)
                     || context.getResources().getBoolean(R.bool.config_enableAppWidgetService)) {
-                traceBeginAndSlog("StartAppWidgetService");
+                t.traceBegin("StartAppWidgetService");
                 mSystemServiceManager.startService(APPWIDGET_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             // Grants default permissions and defines roles
-            traceBeginAndSlog("StartRoleManagerService");
+            t.traceBegin("StartRoleManagerService");
             mSystemServiceManager.startService(new RoleManagerService(
                     mSystemContext, new LegacyRoleResolutionPolicy(mSystemContext)));
-            traceEnd();
+            t.traceEnd();
 
             // We need to always start this service, regardless of whether the
             // FEATURE_VOICE_RECOGNIZERS feature is set, because it needs to take care
             // of initializing various settings.  It will internally modify its behavior
             // based on that feature.
-            traceBeginAndSlog("StartVoiceRecognitionManager");
+            t.traceBegin("StartVoiceRecognitionManager");
             mSystemServiceManager.startService(VOICE_RECOGNITION_MANAGER_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
             if (GestureLauncherService.isGestureLauncherEnabled(context.getResources())) {
-                traceBeginAndSlog("StartGestureLauncher");
+                t.traceBegin("StartGestureLauncher");
                 mSystemServiceManager.startService(GestureLauncherService.class);
-                traceEnd();
+                t.traceEnd();
             }
-            traceBeginAndSlog("StartSensorNotification");
+            t.traceBegin("StartSensorNotification");
             mSystemServiceManager.startService(SensorNotificationService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartContextHubSystemService");
+            t.traceBegin("StartContextHubSystemService");
             mSystemServiceManager.startService(ContextHubSystemService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartDiskStatsService");
+            t.traceBegin("StartDiskStatsService");
             try {
                 ServiceManager.addService("diskstats", new DiskStatsService(context));
             } catch (Throwable e) {
                 reportWtf("starting DiskStats Service", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("RuntimeService");
+            t.traceBegin("RuntimeService");
             try {
                 ServiceManager.addService("runtime", new RuntimeService(context));
             } catch (Throwable e) {
                 reportWtf("starting RuntimeService", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             // timezone.RulesManagerService will prevent a device starting up if the chain of trust
             // required for safe time zone updates might be broken. RuleManagerService cannot do
@@ -1638,111 +1645,106 @@
                     !mOnlyCore && context.getResources().getBoolean(
                             R.bool.config_enableUpdateableTimeZoneRules);
             if (startRulesManagerService) {
-                traceBeginAndSlog("StartTimeZoneRulesManagerService");
+                t.traceBegin("StartTimeZoneRulesManagerService");
                 mSystemServiceManager.startService(TIME_ZONE_RULES_MANAGER_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (!isWatch && !disableNetworkTime) {
-                traceBeginAndSlog("StartNetworkTimeUpdateService");
+                t.traceBegin("StartNetworkTimeUpdateService");
                 try {
-                    if (useNewTimeServices) {
-                        networkTimeUpdater = new NewNetworkTimeUpdateService(context);
-                    } else {
-                        networkTimeUpdater = new OldNetworkTimeUpdateService(context);
-                    }
-                    Slog.d(TAG, "Using networkTimeUpdater class=" + networkTimeUpdater.getClass());
+                    networkTimeUpdater = new NetworkTimeUpdateServiceImpl(context);
                     ServiceManager.addService("network_time_update_service", networkTimeUpdater);
                 } catch (Throwable e) {
                     reportWtf("starting NetworkTimeUpdate service", e);
                 }
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("CertBlacklister");
+            t.traceBegin("CertBlacklister");
             try {
                 CertBlacklister blacklister = new CertBlacklister(context);
             } catch (Throwable e) {
                 reportWtf("starting CertBlacklister", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             if (EmergencyAffordanceManager.ENABLED) {
                 // EmergencyMode service
-                traceBeginAndSlog("StartEmergencyAffordanceService");
+                t.traceBegin("StartEmergencyAffordanceService");
                 mSystemServiceManager.startService(EmergencyAffordanceService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
             // Dreams (interactive idle-time views, a/k/a screen savers, and doze mode)
-            traceBeginAndSlog("StartDreamManager");
+            t.traceBegin("StartDreamManager");
             mSystemServiceManager.startService(DreamManagerService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("AddGraphicsStatsService");
+            t.traceBegin("AddGraphicsStatsService");
             ServiceManager.addService(GraphicsStatsService.GRAPHICS_STATS_SERVICE,
                     new GraphicsStatsService(context));
-            traceEnd();
+            t.traceEnd();
 
             if (CoverageService.ENABLED) {
-                traceBeginAndSlog("AddCoverageService");
+                t.traceBegin("AddCoverageService");
                 ServiceManager.addService(CoverageService.COVERAGE_SERVICE, new CoverageService());
-                traceEnd();
+                t.traceEnd();
             }
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
-                traceBeginAndSlog("StartPrintManager");
+                t.traceBegin("StartPrintManager");
                 mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP)) {
-                traceBeginAndSlog("StartCompanionDeviceManager");
+                t.traceBegin("StartCompanionDeviceManager");
                 mSystemServiceManager.startService(COMPANION_DEVICE_MANAGER_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartRestrictionManager");
+            t.traceBegin("StartRestrictionManager");
             mSystemServiceManager.startService(RestrictionsManagerService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartMediaSessionService");
+            t.traceBegin("StartMediaSessionService");
             mSystemServiceManager.startService(MediaSessionService.class);
-            traceEnd();
+            t.traceEnd();
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
-                traceBeginAndSlog("StartHdmiControlService");
+                t.traceBegin("StartHdmiControlService");
                 mSystemServiceManager.startService(HdmiControlService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_LIVE_TV)
                     || mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
-                traceBeginAndSlog("StartTvInputManager");
+                t.traceBegin("StartTvInputManager");
                 mSystemServiceManager.startService(TvInputManagerService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {
-                traceBeginAndSlog("StartMediaResourceMonitor");
+                t.traceBegin("StartMediaResourceMonitor");
                 mSystemServiceManager.startService(MediaResourceMonitorService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
-                traceBeginAndSlog("StartTvRemoteService");
+                t.traceBegin("StartTvRemoteService");
                 mSystemServiceManager.startService(TvRemoteService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartMediaRouterService");
+            t.traceBegin("StartMediaRouterService");
             try {
                 mediaRouter = new MediaRouterService(context);
                 ServiceManager.addService(Context.MEDIA_ROUTER_SERVICE, mediaRouter);
             } catch (Throwable e) {
                 reportWtf("starting MediaRouterService", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             final boolean hasFeatureFace
                     = mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE);
@@ -1752,168 +1754,172 @@
                     = mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
 
             if (hasFeatureFace) {
-                traceBeginAndSlog("StartFaceSensor");
+                t.traceBegin("StartFaceSensor");
                 mSystemServiceManager.startService(FaceService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (hasFeatureIris) {
-                traceBeginAndSlog("StartIrisSensor");
+                t.traceBegin("StartIrisSensor");
                 mSystemServiceManager.startService(IrisService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (hasFeatureFingerprint) {
-                traceBeginAndSlog("StartFingerprintSensor");
+                t.traceBegin("StartFingerprintSensor");
                 mSystemServiceManager.startService(FingerprintService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
             if (hasFeatureFace || hasFeatureIris || hasFeatureFingerprint) {
                 // Start this service after all biometric services.
-                traceBeginAndSlog("StartBiometricService");
+                t.traceBegin("StartBiometricService");
                 mSystemServiceManager.startService(BiometricService.class);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartBackgroundDexOptService");
+            t.traceBegin("StartBackgroundDexOptService");
             try {
                 BackgroundDexOptService.schedule(context);
             } catch (Throwable e) {
                 reportWtf("starting StartBackgroundDexOptService", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             if (!isWatch) {
                 // We don't run this on watches as there are no plans to use the data logged
                 // on watch devices.
-                traceBeginAndSlog("StartDynamicCodeLoggingService");
+                t.traceBegin("StartDynamicCodeLoggingService");
                 try {
                     DynamicCodeLoggingService.schedule(context);
                 } catch (Throwable e) {
                     reportWtf("starting DynamicCodeLoggingService", e);
                 }
-                traceEnd();
+                t.traceEnd();
             }
 
             if (!isWatch) {
-                traceBeginAndSlog("StartPruneInstantAppsJobService");
+                t.traceBegin("StartPruneInstantAppsJobService");
                 try {
                     PruneInstantAppsJobService.schedule(context);
                 } catch (Throwable e) {
                     reportWtf("StartPruneInstantAppsJobService", e);
                 }
-                traceEnd();
+                t.traceEnd();
             }
 
             // LauncherAppsService uses ShortcutService.
-            traceBeginAndSlog("StartShortcutServiceLifecycle");
+            t.traceBegin("StartShortcutServiceLifecycle");
             mSystemServiceManager.startService(ShortcutService.Lifecycle.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartLauncherAppsService");
+            t.traceBegin("StartLauncherAppsService");
             mSystemServiceManager.startService(LauncherAppsService.class);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartCrossProfileAppsService");
+            t.traceBegin("StartCrossProfileAppsService");
             mSystemServiceManager.startService(CrossProfileAppsService.class);
-            traceEnd();
+            t.traceEnd();
         }
 
         if (!isWatch) {
-            traceBeginAndSlog("StartMediaProjectionManager");
+            t.traceBegin("StartMediaProjectionManager");
             mSystemServiceManager.startService(MediaProjectionManagerService.class);
-            traceEnd();
+            t.traceEnd();
         }
 
         if (isWatch) {
             // Must be started before services that depend it, e.g. WearConnectivityService
-            traceBeginAndSlog("StartWearPowerService");
+            t.traceBegin("StartWearPowerService");
             mSystemServiceManager.startService(WEAR_POWER_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartWearConnectivityService");
+            t.traceBegin("StartWearConnectivityService");
             mSystemServiceManager.startService(WEAR_CONNECTIVITY_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartWearDisplayService");
+            t.traceBegin("StartWearDisplayService");
             mSystemServiceManager.startService(WEAR_DISPLAY_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("StartWearTimeService");
+            t.traceBegin("StartWearTimeService");
             mSystemServiceManager.startService(WEAR_TIME_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
 
             if (enableLeftyService) {
-                traceBeginAndSlog("StartWearLeftyService");
+                t.traceBegin("StartWearLeftyService");
                 mSystemServiceManager.startService(WEAR_LEFTY_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartWearGlobalActionsService");
+            t.traceBegin("StartWearGlobalActionsService");
             mSystemServiceManager.startService(WEAR_GLOBAL_ACTIONS_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
         }
 
         if (!disableSlices) {
-            traceBeginAndSlog("StartSliceManagerService");
+            t.traceBegin("StartSliceManagerService");
             mSystemServiceManager.startService(SLICE_MANAGER_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
         }
 
         if (!disableCameraService) {
-            traceBeginAndSlog("StartCameraServiceProxy");
+            t.traceBegin("StartCameraServiceProxy");
             mSystemServiceManager.startService(CameraServiceProxy.class);
-            traceEnd();
+            t.traceEnd();
         }
 
         if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_EMBEDDED)) {
-            traceBeginAndSlog("StartIoTSystemService");
+            t.traceBegin("StartIoTSystemService");
             mSystemServiceManager.startService(IOT_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
         }
 
         // Statsd helper
-        traceBeginAndSlog("StartStatsCompanionService");
+        t.traceBegin("StartStatsCompanionService");
         mSystemServiceManager.startService(StatsCompanionService.Lifecycle.class);
-        traceEnd();
+        t.traceEnd();
 
         // Incidentd and dumpstated helper
-        traceBeginAndSlog("StartIncidentCompanionService");
+        t.traceBegin("StartIncidentCompanionService");
         mSystemServiceManager.startService(IncidentCompanionService.class);
-        traceEnd();
+        t.traceEnd();
+
+        if (safeMode) {
+            mActivityManagerService.enterSafeMode();
+        }
 
         // MMS service broker
-        traceBeginAndSlog("StartMmsService");
+        t.traceBegin("StartMmsService");
         mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
-        traceEnd();
+        t.traceEnd();
 
         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOFILL)) {
-            traceBeginAndSlog("StartAutoFillService");
+            t.traceBegin("StartAutoFillService");
             mSystemServiceManager.startService(AUTO_FILL_MANAGER_SERVICE_CLASS);
-            traceEnd();
+            t.traceEnd();
         }
 
         // NOTE: ClipboardService depends on ContentCapture and Autofill
-        traceBeginAndSlog("StartClipboardService");
+        t.traceBegin("StartClipboardService");
         mSystemServiceManager.startService(ClipboardService.class);
-        traceEnd();
+        t.traceEnd();
 
-        traceBeginAndSlog("AppServiceManager");
+        t.traceBegin("AppServiceManager");
         mSystemServiceManager.startService(AppBindingService.Lifecycle.class);
-        traceEnd();
+        t.traceEnd();
 
         // It is now time to start up the app processes...
 
-        traceBeginAndSlog("MakeVibratorServiceReady");
+        t.traceBegin("MakeVibratorServiceReady");
         try {
             vibrator.systemReady();
         } catch (Throwable e) {
             reportWtf("making Vibrator Service ready", e);
         }
-        traceEnd();
+        t.traceEnd();
 
-        traceBeginAndSlog("MakeLockSettingsServiceReady");
+        t.traceBegin("MakeLockSettingsServiceReady");
         if (lockSettings != null) {
             try {
                 lockSettings.systemReady();
@@ -1921,24 +1927,24 @@
                 reportWtf("making Lock Settings Service ready", e);
             }
         }
-        traceEnd();
+        t.traceEnd();
 
         // Needed by DevicePolicyManager for initialization
-        traceBeginAndSlog("StartBootPhaseLockSettingsReady");
-        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
-        traceEnd();
+        t.traceBegin("StartBootPhaseLockSettingsReady");
+        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_LOCK_SETTINGS_READY);
+        t.traceEnd();
 
-        traceBeginAndSlog("StartBootPhaseSystemServicesReady");
-        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
-        traceEnd();
+        t.traceBegin("StartBootPhaseSystemServicesReady");
+        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_SYSTEM_SERVICES_READY);
+        t.traceEnd();
 
-        traceBeginAndSlog("MakeWindowManagerServiceReady");
+        t.traceBegin("MakeWindowManagerServiceReady");
         try {
             wm.systemReady();
         } catch (Throwable e) {
             reportWtf("making Window Manager Service ready", e);
         }
-        traceEnd();
+        t.traceEnd();
 
         if (safeMode) {
             mActivityManagerService.showSafeModeOverlay();
@@ -1959,53 +1965,53 @@
             systemTheme.rebase();
         }
 
-        traceBeginAndSlog("MakePowerManagerServiceReady");
+        t.traceBegin("MakePowerManagerServiceReady");
         try {
             // TODO: use boot phase
             mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
         } catch (Throwable e) {
             reportWtf("making Power Manager Service ready", e);
         }
-        traceEnd();
+        t.traceEnd();
 
-        traceBeginAndSlog("MakePackageManagerServiceReady");
+        t.traceBegin("MakePackageManagerServiceReady");
         mPackageManagerService.systemReady();
-        traceEnd();
+        t.traceEnd();
 
-        traceBeginAndSlog("MakeDisplayManagerServiceReady");
+        t.traceBegin("MakeDisplayManagerServiceReady");
         try {
             // TODO: use boot phase and communicate these flags some other way
             mDisplayManagerService.systemReady(safeMode, mOnlyCore);
         } catch (Throwable e) {
             reportWtf("making Display Manager Service ready", e);
         }
-        traceEnd();
+        t.traceEnd();
 
         mSystemServiceManager.setSafeMode(safeMode);
 
         // Start device specific services
-        traceBeginAndSlog("StartDeviceSpecificServices");
+        t.traceBegin("StartDeviceSpecificServices");
         final String[] classes = mSystemContext.getResources().getStringArray(
                 R.array.config_deviceSpecificSystemServices);
         for (final String className : classes) {
-            traceBeginAndSlog("StartDeviceSpecificServices " + className);
+            t.traceBegin("StartDeviceSpecificServices " + className);
             try {
                 mSystemServiceManager.startService(className);
             } catch (Throwable e) {
                 reportWtf("starting " + className, e);
             }
-            traceEnd();
+            t.traceEnd();
         }
-        traceEnd();
+        t.traceEnd();
 
-        traceBeginAndSlog("StartBootPhaseDeviceSpecificServicesReady");
-        mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
-        traceEnd();
+        t.traceBegin("StartBootPhaseDeviceSpecificServicesReady");
+        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
+        t.traceEnd();
 
         // Permission policy service
-        traceBeginAndSlog("StartPermissionPolicyService");
+        t.traceBegin("StartPermissionPolicyService");
         mSystemServiceManager.startService(PermissionPolicyService.class);
-        traceEnd();
+        t.traceEnd();
 
         // These are needed to propagate to the runnable below.
         final NetworkManagementService networkManagementF = networkManagement;
@@ -2029,17 +2035,16 @@
         // initialization.
         mActivityManagerService.systemReady(() -> {
             Slog.i(TAG, "Making services ready");
-            traceBeginAndSlog("StartActivityManagerReadyPhase");
-            mSystemServiceManager.startBootPhase(
-                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
-            traceEnd();
-            traceBeginAndSlog("StartObservingNativeCrashes");
+            t.traceBegin("StartActivityManagerReadyPhase");
+            mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
+            t.traceEnd();
+            t.traceBegin("StartObservingNativeCrashes");
             try {
                 mActivityManagerService.startObservingNativeCrashes();
             } catch (Throwable e) {
                 reportWtf("observing native crashes", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             // No dependency on Webview preparation in system server. But this should
             // be completed before allowing 3rd party
@@ -2048,8 +2053,7 @@
             if (!mOnlyCore && mWebViewUpdateService != null) {
                 webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
                     Slog.i(TAG, WEBVIEW_PREPARATION);
-                    TimingsTraceLog traceLog = new TimingsTraceLog(
-                            SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+                    TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
                     traceLog.traceBegin(WEBVIEW_PREPARATION);
                     ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");
                     mZygotePreload = null;
@@ -2059,33 +2063,33 @@
             }
 
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
-                traceBeginAndSlog("StartCarServiceHelperService");
+                t.traceBegin("StartCarServiceHelperService");
                 mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
-                traceEnd();
+                t.traceEnd();
             }
 
-            traceBeginAndSlog("StartSystemUI");
+            t.traceBegin("StartSystemUI");
             try {
                 startSystemUi(context, windowManagerF);
             } catch (Throwable e) {
                 reportWtf("starting System UI", e);
             }
-            traceEnd();
+            t.traceEnd();
             // Enable airplane mode in safe mode. setAirplaneMode() cannot be called
             // earlier as it sends broadcasts to other services.
             // TODO: This may actually be too late if radio firmware already started leaking
             // RF before the respective services start. However, fixing this requires changes
             // to radio firmware and interfaces.
             if (safeMode) {
-                traceBeginAndSlog("EnableAirplaneModeInSafeMode");
+                t.traceBegin("EnableAirplaneModeInSafeMode");
                 try {
                     connectivityF.setAirplaneMode(true);
                 } catch (Throwable e) {
                     reportWtf("enabling Airplane Mode during Safe Mode bootup", e);
                 }
-                traceEnd();
+                t.traceEnd();
             }
-            traceBeginAndSlog("MakeNetworkManagementServiceReady");
+            t.traceBegin("MakeNetworkManagementServiceReady");
             try {
                 if (networkManagementF != null) {
                     networkManagementF.systemReady();
@@ -2098,8 +2102,8 @@
                 networkPolicyInitReadySignal = networkPolicyF
                         .networkScoreAndNetworkManagementServiceReady();
             }
-            traceEnd();
-            traceBeginAndSlog("MakeIpSecServiceReady");
+            t.traceEnd();
+            t.traceBegin("MakeIpSecServiceReady");
             try {
                 if (ipSecServiceF != null) {
                     ipSecServiceF.systemReady();
@@ -2107,8 +2111,8 @@
             } catch (Throwable e) {
                 reportWtf("making IpSec Service ready", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeNetworkStatsServiceReady");
+            t.traceEnd();
+            t.traceBegin("MakeNetworkStatsServiceReady");
             try {
                 if (networkStatsF != null) {
                     networkStatsF.systemReady();
@@ -2116,8 +2120,8 @@
             } catch (Throwable e) {
                 reportWtf("making Network Stats Service ready", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeConnectivityServiceReady");
+            t.traceEnd();
+            t.traceBegin("MakeConnectivityServiceReady");
             try {
                 if (connectivityF != null) {
                     connectivityF.systemReady();
@@ -2125,8 +2129,8 @@
             } catch (Throwable e) {
                 reportWtf("making Connectivity Service ready", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeNetworkPolicyServiceReady");
+            t.traceEnd();
+            t.traceBegin("MakeNetworkPolicyServiceReady");
             try {
                 if (networkPolicyF != null) {
                     networkPolicyF.systemReady(networkPolicyInitReadySignal);
@@ -2134,23 +2138,22 @@
             } catch (Throwable e) {
                 reportWtf("making Network Policy Service ready", e);
             }
-            traceEnd();
+            t.traceEnd();
 
             // Wait for all packages to be prepared
             mPackageManagerService.waitForAppDataPrepared();
 
             // It is now okay to let the various system services start their
             // third party code...
-            traceBeginAndSlog("PhaseThirdPartyAppsCanStart");
+            t.traceBegin("PhaseThirdPartyAppsCanStart");
             // confirm webview completion before starting 3rd party
             if (webviewPrep != null) {
                 ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
             }
-            mSystemServiceManager.startBootPhase(
-                    SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
-            traceEnd();
+            mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
+            t.traceEnd();
 
-            traceBeginAndSlog("StartNetworkStack");
+            t.traceBegin("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
@@ -2161,9 +2164,9 @@
             } catch (Throwable e) {
                 reportWtf("starting Network Stack", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("MakeLocationServiceReady");
+            t.traceBegin("MakeLocationServiceReady");
             try {
                 if (locationF != null) {
                     locationF.systemRunning();
@@ -2171,8 +2174,8 @@
             } catch (Throwable e) {
                 reportWtf("Notifying Location Service running", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeCountryDetectionServiceReady");
+            t.traceEnd();
+            t.traceBegin("MakeCountryDetectionServiceReady");
             try {
                 if (countryDetectorF != null) {
                     countryDetectorF.systemRunning();
@@ -2180,8 +2183,8 @@
             } catch (Throwable e) {
                 reportWtf("Notifying CountryDetectorService running", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeNetworkTimeUpdateReady");
+            t.traceEnd();
+            t.traceBegin("MakeNetworkTimeUpdateReady");
             try {
                 if (networkTimeUpdaterF != null) {
                     networkTimeUpdaterF.systemRunning();
@@ -2189,8 +2192,8 @@
             } catch (Throwable e) {
                 reportWtf("Notifying NetworkTimeService running", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeInputManagerServiceReady");
+            t.traceEnd();
+            t.traceBegin("MakeInputManagerServiceReady");
             try {
                 // TODO(BT) Pass parameter to input manager
                 if (inputManagerF != null) {
@@ -2199,8 +2202,8 @@
             } catch (Throwable e) {
                 reportWtf("Notifying InputManagerService running", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeTelephonyRegistryReady");
+            t.traceEnd();
+            t.traceBegin("MakeTelephonyRegistryReady");
             try {
                 if (telephonyRegistryF != null) {
                     telephonyRegistryF.systemRunning();
@@ -2208,8 +2211,8 @@
             } catch (Throwable e) {
                 reportWtf("Notifying TelephonyRegistry running", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeMediaRouterServiceReady");
+            t.traceEnd();
+            t.traceBegin("MakeMediaRouterServiceReady");
             try {
                 if (mediaRouterF != null) {
                     mediaRouterF.systemRunning();
@@ -2217,8 +2220,8 @@
             } catch (Throwable e) {
                 reportWtf("Notifying MediaRouterService running", e);
             }
-            traceEnd();
-            traceBeginAndSlog("MakeMmsServiceReady");
+            t.traceEnd();
+            t.traceBegin("MakeMmsServiceReady");
             try {
                 if (mmsServiceF != null) {
                     mmsServiceF.systemRunning();
@@ -2226,9 +2229,9 @@
             } catch (Throwable e) {
                 reportWtf("Notifying MmsService running", e);
             }
-            traceEnd();
+            t.traceEnd();
 
-            traceBeginAndSlog("IncidentDaemonReady");
+            t.traceBegin("IncidentDaemonReady");
             try {
                 // TODO: Switch from checkService to getService once it's always
                 // in the build and should reliably be there.
@@ -2240,11 +2243,14 @@
             } catch (Throwable e) {
                 reportWtf("Notifying incident daemon running", e);
             }
-            traceEnd();
-        }, BOOT_TIMINGS_TRACE_LOG);
+            t.traceEnd();
+        }, t);
+
+        t.traceEnd(); // startOtherServices
     }
 
-    private void startSystemCaptionsManagerService(@NonNull Context context) {
+    private void startSystemCaptionsManagerService(@NonNull Context context,
+            @NonNull TimingsTraceAndSlog t) {
         String serviceName = context.getString(
                 com.android.internal.R.string.config_defaultSystemCaptionsManagerService);
         if (TextUtils.isEmpty(serviceName)) {
@@ -2252,12 +2258,13 @@
             return;
         }
 
-        traceBeginAndSlog("StartSystemCaptionsManagerService");
+        t.traceBegin("StartSystemCaptionsManagerService");
         mSystemServiceManager.startService(SYSTEM_CAPTIONS_MANAGER_SERVICE_CLASS);
-        traceEnd();
+        t.traceEnd();
     }
 
-    private void startContentCaptureService(@NonNull Context context) {
+    private void startContentCaptureService(@NonNull Context context,
+            @NonNull TimingsTraceAndSlog t) {
         // First check if it was explicitly enabled by DeviceConfig
         boolean explicitlyEnabled = false;
         String settings = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
@@ -2282,7 +2289,7 @@
             }
         }
 
-        traceBeginAndSlog("StartContentCaptureService");
+        t.traceBegin("StartContentCaptureService");
         mSystemServiceManager.startService(CONTENT_CAPTURE_MANAGER_SERVICE_CLASS);
 
         ContentCaptureManagerInternal ccmi =
@@ -2291,18 +2298,18 @@
             mActivityManagerService.setContentCaptureManager(ccmi);
         }
 
-        traceEnd();
+        t.traceEnd();
     }
 
-    private void startAttentionService(@NonNull Context context) {
+    private void startAttentionService(@NonNull Context context, @NonNull TimingsTraceAndSlog t) {
         if (!AttentionManagerService.isServiceConfigured(context)) {
             Slog.d(TAG, "AttentionService is not configured on this device");
             return;
         }
 
-        traceBeginAndSlog("StartAttentionManagerService");
+        t.traceBegin("StartAttentionManagerService");
         mSystemServiceManager.startService(AttentionManagerService.class);
-        traceEnd();
+        t.traceEnd();
     }
 
     private static void startSystemUi(Context context, WindowManagerService windowManager) {
@@ -2314,13 +2321,4 @@
         context.startServiceAsUser(intent, UserHandle.SYSTEM);
         windowManager.onSystemUiStarted();
     }
-
-    private static void traceBeginAndSlog(@NonNull String name) {
-        Slog.i(TAG, name);
-        BOOT_TIMINGS_TRACE_LOG.traceBegin(name);
-    }
-
-    private static void traceEnd() {
-        BOOT_TIMINGS_TRACE_LOG.traceEnd();
-    }
 }
diff --git a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
index 1e688d0..30893b2 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface IIpMemoryStore {
   oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
index cf02c26..535ae2c 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface IIpMemoryStoreCallbacks {
   oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
index 291dbef..6d2dc0c 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable Blob {
   byte[] data;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
index 52f40d4..48c1fb8 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnBlobRetrievedListener {
   oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
index 7853514..aebc724 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnL2KeyResponseListener {
   oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
index 3dd2ae6..b66db5a 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnNetworkAttributesRetrievedListener {
   oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
index 46d4ecb..e9f2db4 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnSameL3NetworkResponseListener {
   oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
index 54e654b..49172ce 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnStatusListener {
   oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
index 9531ea3..188db20 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable NetworkAttributesParcelable {
   byte[] assignedV4Address;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
index 414272b..7a2ed48 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable SameL3NetworkResponseParcelable {
   String l2Key1;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
index 92c6779..d9b0678 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable StatusParcelable {
   int resultCode;
diff --git a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
index 31891de..07ff321 100644
--- a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable DhcpResultsParcelable {
   android.net.StaticIpConfiguration baseConfiguration;
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
index 029968b..8aa68bd 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkMonitor {
   oneway void start();
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
index ee9871d..ea93729 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkMonitorCallbacks {
   oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
index 7da11e4..e3a83d1 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkStackConnector {
   oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
index f6ca6f7..3112a08 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkStackStatusCallback {
   oneway void onStatusAvailable(int statusCode);
diff --git a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
index c80a787..f846b26 100644
--- a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable InitialConfigurationParcelable {
   android.net.LinkAddress[] ipAddresses;
diff --git a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
index 65de883..de75940 100644
--- a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable NattKeepalivePacketDataParcelable {
   byte[] srcAddress;
diff --git a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
index 2de790b..cf0fbce9 100644
--- a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
+++ b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable PrivateDnsConfigParcel {
   String hostname;
diff --git a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
index 3a6c304..c0f2d4d 100644
--- a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable ProvisioningConfigurationParcelable {
   boolean enableIPv4;
diff --git a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
index e121c06..5926794 100644
--- a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable TcpKeepalivePacketDataParcelable {
   byte[] srcAddress;
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
index 67193ae..7ab156f 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 parcelable DhcpServingParamsParcel {
   int serverAddr;
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
index 9143158..d281ecf 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 interface IDhcpServer {
   oneway void start(in android.net.INetworkStackStatusCallback cb);
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
index dcc4489..98be0ab 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 interface IDhcpServerCallbacks {
   oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
index 176a5ce..85c8676 100644
--- a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ip;
 interface IIpClient {
   oneway void completedPreDhcpAction();
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
index d6bc808..7fe39ed 100644
--- a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ip;
 interface IIpClientCallbacks {
   oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
diff --git a/services/net/java/android/net/NattKeepalivePacketData.java b/services/net/java/android/net/NattKeepalivePacketData.java
deleted file mode 100644
index 06838fe..0000000
--- a/services/net/java/android/net/NattKeepalivePacketData.java
+++ /dev/null
@@ -1,95 +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.net;
-
-import static android.net.SocketKeepalive.ERROR_INVALID_IP_ADDRESS;
-import static android.net.SocketKeepalive.ERROR_INVALID_PORT;
-
-import android.annotation.NonNull;
-import android.net.SocketKeepalive.InvalidPacketException;
-import android.net.util.IpUtils;
-import android.os.Parcelable;
-import android.system.OsConstants;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/** @hide */
-public final class NattKeepalivePacketData extends KeepalivePacketData implements Parcelable {
-    // This should only be constructed via static factory methods, such as
-    // nattKeepalivePacket
-    private NattKeepalivePacketData(InetAddress srcAddress, int srcPort,
-            InetAddress dstAddress, int dstPort, byte[] data) throws
-            InvalidPacketException {
-        super(srcAddress, srcPort, dstAddress, dstPort, data);
-    }
-
-    /**
-     * Factory method to create Nat-T keepalive packet structure.
-     */
-    public static NattKeepalivePacketData nattKeepalivePacket(
-            InetAddress srcAddress, int srcPort, InetAddress dstAddress, int dstPort)
-            throws InvalidPacketException {
-
-        if (!(srcAddress instanceof Inet4Address) || !(dstAddress instanceof Inet4Address)) {
-            throw new InvalidPacketException(ERROR_INVALID_IP_ADDRESS);
-        }
-
-        if (dstPort != NattSocketKeepalive.NATT_PORT) {
-            throw new InvalidPacketException(ERROR_INVALID_PORT);
-        }
-
-        int length = IPV4_HEADER_LENGTH + UDP_HEADER_LENGTH + 1;
-        ByteBuffer buf = ByteBuffer.allocate(length);
-        buf.order(ByteOrder.BIG_ENDIAN);
-        buf.putShort((short) 0x4500);             // IP version and TOS
-        buf.putShort((short) length);
-        buf.putInt(0);                            // ID, flags, offset
-        buf.put((byte) 64);                       // TTL
-        buf.put((byte) OsConstants.IPPROTO_UDP);
-        int ipChecksumOffset = buf.position();
-        buf.putShort((short) 0);                  // IP checksum
-        buf.put(srcAddress.getAddress());
-        buf.put(dstAddress.getAddress());
-        buf.putShort((short) srcPort);
-        buf.putShort((short) dstPort);
-        buf.putShort((short) (length - 20));      // UDP length
-        int udpChecksumOffset = buf.position();
-        buf.putShort((short) 0);                  // UDP checksum
-        buf.put((byte) 0xff);                     // NAT-T keepalive
-        buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
-        buf.putShort(udpChecksumOffset, IpUtils.udpChecksum(buf, 0, IPV4_HEADER_LENGTH));
-
-        return new NattKeepalivePacketData(srcAddress, srcPort, dstAddress, dstPort, buf.array());
-    }
-
-     /**
-     * Convert this NattKeepalivePacketData to a NattKeepalivePacketDataParcelable.
-     */
-    @NonNull
-    public NattKeepalivePacketDataParcelable toStableParcelable() {
-        final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
-
-        parcel.srcAddress = srcAddress.getAddress();
-        parcel.srcPort = srcPort;
-        parcel.dstAddress = dstAddress.getAddress();
-        parcel.dstPort = dstPort;
-        return parcel;
-    }
-}
diff --git a/services/net/java/android/net/NetworkMonitorManager.java b/services/net/java/android/net/NetworkMonitorManager.java
new file mode 100644
index 0000000..0f41302
--- /dev/null
+++ b/services/net/java/android/net/NetworkMonitorManager.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * A convenience wrapper for INetworkMonitor.
+ *
+ * Wraps INetworkMonitor calls, making them a bit more friendly to use. Currently handles:
+ * - Clearing calling identity
+ * - Ignoring RemoteExceptions
+ * - Converting to stable parcelables
+ *
+ * By design, all methods on INetworkMonitor are asynchronous oneway IPCs and are thus void. All the
+ * wrapper methods in this class return a boolean that callers can use to determine whether
+ * RemoteException was thrown.
+ */
+public class NetworkMonitorManager {
+
+    @NonNull private final INetworkMonitor mNetworkMonitor;
+    @NonNull private final String mTag;
+
+    public NetworkMonitorManager(@NonNull INetworkMonitor networkMonitorManager,
+            @NonNull String tag) {
+        mNetworkMonitor = networkMonitorManager;
+        mTag = tag;
+    }
+
+    public NetworkMonitorManager(@NonNull INetworkMonitor networkMonitorManager) {
+        this(networkMonitorManager, NetworkMonitorManager.class.getSimpleName());
+    }
+
+    private void log(String s, Throwable e) {
+        Log.e(mTag, s, e);
+    }
+
+    // CHECKSTYLE:OFF Generated code
+
+    public boolean start() {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.start();
+            return true;
+        } catch (RemoteException e) {
+            log("Error in start", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean launchCaptivePortalApp() {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.launchCaptivePortalApp();
+            return true;
+        } catch (RemoteException e) {
+            log("Error in launchCaptivePortalApp", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean notifyCaptivePortalAppFinished(int response) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.notifyCaptivePortalAppFinished(response);
+            return true;
+        } catch (RemoteException e) {
+            log("Error in notifyCaptivePortalAppFinished", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean setAcceptPartialConnectivity() {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.setAcceptPartialConnectivity();
+            return true;
+        } catch (RemoteException e) {
+            log("Error in setAcceptPartialConnectivity", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean forceReevaluation(int uid) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.forceReevaluation(uid);
+            return true;
+        } catch (RemoteException e) {
+            log("Error in forceReevaluation", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean notifyPrivateDnsChanged(PrivateDnsConfigParcel config) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.notifyPrivateDnsChanged(config);
+            return true;
+        } catch (RemoteException e) {
+            log("Error in notifyPrivateDnsChanged", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean notifyDnsResponse(int returnCode) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.notifyDnsResponse(returnCode);
+            return true;
+        } catch (RemoteException e) {
+            log("Error in notifyDnsResponse", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.notifyNetworkConnected(lp, nc);
+            return true;
+        } catch (RemoteException e) {
+            log("Error in notifyNetworkConnected", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean notifyNetworkDisconnected() {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.notifyNetworkDisconnected();
+            return true;
+        } catch (RemoteException e) {
+            log("Error in notifyNetworkDisconnected", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean notifyLinkPropertiesChanged(LinkProperties lp) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.notifyLinkPropertiesChanged(lp);
+            return true;
+        } catch (RemoteException e) {
+            log("Error in notifyLinkPropertiesChanged", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    public boolean notifyNetworkCapabilitiesChanged(NetworkCapabilities nc) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mNetworkMonitor.notifyNetworkCapabilitiesChanged(nc);
+            return true;
+        } catch (RemoteException e) {
+            log("Error in notifyNetworkCapabilitiesChanged", e);
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // CHECKSTYLE:ON Generated code
+}
diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java
index 09c9b6d..56b728c 100644
--- a/services/net/java/android/net/NetworkStackClient.java
+++ b/services/net/java/android/net/NetworkStackClient.java
@@ -33,6 +33,7 @@
 import android.net.ip.IIpClientCallbacks;
 import android.net.util.SharedLog;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Environment;
 import android.os.IBinder;
 import android.os.Process;
@@ -41,6 +42,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
+import android.text.format.DateUtils;
 import android.util.ArraySet;
 import android.util.Slog;
 
@@ -60,14 +62,22 @@
     private static final int NETWORKSTACK_TIMEOUT_MS = 10_000;
     private static final String IN_PROCESS_SUFFIX = ".InProcess";
     private static final String PREFS_FILE = "NetworkStackClientPrefs.xml";
-    private static final String PREF_KEY_LAST_CRASH_UPTIME = "lastcrash";
+    private static final String PREF_KEY_LAST_CRASH_TIME = "lastcrash_time";
     private static final String CONFIG_MIN_CRASH_INTERVAL_MS = "min_crash_interval";
+    private static final String CONFIG_MIN_UPTIME_BEFORE_CRASH_MS = "min_uptime_before_crash";
+    private static final String CONFIG_ALWAYS_RATELIMIT_NETWORKSTACK_CRASH =
+            "always_ratelimit_networkstack_crash";
 
     // Even if the network stack is lost, do not crash the system more often than this.
     // Connectivity would be broken, but if the user needs the device for something urgent
     // (like calling emergency services) we should not bootloop the device.
     // This is the default value: the actual value can be adjusted via device config.
-    private static final long DEFAULT_MIN_CRASH_INTERVAL_MS = 6 * 3_600_000L;
+    private static final long DEFAULT_MIN_CRASH_INTERVAL_MS = 6 * DateUtils.HOUR_IN_MILLIS;
+
+    // Even if the network stack is lost, do not crash the system server if it was less than
+    // this much after boot. This avoids bootlooping the device, and crashes should address very
+    // infrequent failures, not failures on boot.
+    private static final long DEFAULT_MIN_UPTIME_BEFORE_CRASH_MS = 30 * DateUtils.MINUTE_IN_MILLIS;
 
     private static NetworkStackClient sInstance;
 
@@ -83,12 +93,6 @@
 
     private volatile boolean mWasSystemServerInitialized = false;
 
-    /**
-     * If non-zero, indicates that the last framework start happened after a crash of the
-     * NetworkStack which was at the specified uptime.
-     */
-    private volatile long mLastCrashUptime = 0L;
-
     @GuardedBy("mHealthListeners")
     private final ArraySet<NetworkStackHealthListener> mHealthListeners = new ArraySet<>();
 
@@ -258,12 +262,6 @@
     public void start(Context context) {
         log("Starting network stack");
 
-        final SharedPreferences prefs = getSharedPreferences(context);
-        mLastCrashUptime = prefs.getLong(PREF_KEY_LAST_CRASH_UPTIME, 0L);
-        // Remove the preference after getting the last crash uptime, so mLastCrashUptime always
-        // indicates this is the first start since the last crash.
-        prefs.edit().remove(PREF_KEY_LAST_CRASH_UPTIME).commit();
-
         final PackageManager pm = context.getPackageManager();
 
         // Try to bind in-process if the device was shipped with an in-process version
@@ -344,21 +342,40 @@
         logWtf(message, null);
         // uptime is monotonic even after a framework restart
         final long uptime = SystemClock.elapsedRealtime();
+        final long now = System.currentTimeMillis();
         final long minCrashIntervalMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_CONNECTIVITY,
                 CONFIG_MIN_CRASH_INTERVAL_MS, DEFAULT_MIN_CRASH_INTERVAL_MS);
+        final long minUptimeBeforeCrash = DeviceConfig.getLong(DeviceConfig.NAMESPACE_CONNECTIVITY,
+                CONFIG_MIN_UPTIME_BEFORE_CRASH_MS, DEFAULT_MIN_UPTIME_BEFORE_CRASH_MS);
+        final boolean alwaysRatelimit = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CONNECTIVITY,
+                CONFIG_ALWAYS_RATELIMIT_NETWORKSTACK_CRASH, false);
 
-        // Either the framework was not restarted after a crash of the NetworkStack, or the min
-        // crash interval has passed since then.
-        if (mLastCrashUptime == 0L || uptime - mLastCrashUptime > minCrashIntervalMs) {
+        final SharedPreferences prefs = getSharedPreferences(context);
+        final long lastCrashTime = tryGetLastCrashTime(prefs);
+
+        // Only crash if there was enough time since boot, and (if known) enough time passed since
+        // the last crash.
+        // time and lastCrashTime may be unreliable if devices have incorrect clock time, but they
+        // are only used to limit the number of crashes compared to only using the time since boot,
+        // which would also be OK behavior by itself.
+        // - If lastCrashTime is incorrectly more than the current time, only look at uptime
+        // - If it is much less than current time, only look at uptime
+        // - If current time is during the next few hours after last crash time, don't crash.
+        //   Considering that this only matters if last boot was some time ago, it's likely that
+        //   time will be set correctly. Otherwise, not crashing is not a big problem anyway. Being
+        //   in this last state would also not last for long since the window is only a few hours.
+        final boolean alwaysCrash = Build.IS_DEBUGGABLE && !alwaysRatelimit;
+        final boolean justBooted = uptime < minUptimeBeforeCrash;
+        final boolean haveLastCrashTime = (lastCrashTime != 0) && (lastCrashTime < now);
+        final boolean haveKnownRecentCrash =
+                haveLastCrashTime && (now < lastCrashTime + minCrashIntervalMs);
+        if (alwaysCrash || (!justBooted && !haveKnownRecentCrash)) {
             // The system is not bound to its network stack (for example due to a crash in the
             // network stack process): better crash rather than stay in a bad state where all
             // networking is broken.
             // Using device-encrypted SharedPreferences as DeviceConfig does not have a synchronous
             // API to persist settings before a crash.
-            final SharedPreferences prefs = getSharedPreferences(context);
-            if (!prefs.edit().putLong(PREF_KEY_LAST_CRASH_UPTIME, uptime).commit()) {
-                logWtf("Could not persist last crash uptime", null);
-            }
+            tryWriteLastCrashTime(prefs, now);
             throw new IllegalStateException(message);
         }
 
@@ -375,11 +392,36 @@
         }
     }
 
-    private SharedPreferences getSharedPreferences(Context context) {
-        final File prefsFile = new File(
-                Environment.getDataSystemDeDirectory(UserHandle.USER_SYSTEM), PREFS_FILE);
-        return context.createDeviceProtectedStorageContext()
-                .getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
+    @Nullable
+    private SharedPreferences getSharedPreferences(@NonNull Context context) {
+        try {
+            final File prefsFile = new File(
+                    Environment.getDataSystemDeDirectory(UserHandle.USER_SYSTEM), PREFS_FILE);
+            return context.createDeviceProtectedStorageContext()
+                    .getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
+        } catch (Throwable e) {
+            logWtf("Error loading shared preferences", e);
+            return null;
+        }
+    }
+
+    private long tryGetLastCrashTime(@Nullable SharedPreferences prefs) {
+        if (prefs == null) return 0L;
+        try {
+            return prefs.getLong(PREF_KEY_LAST_CRASH_TIME, 0L);
+        } catch (Throwable e) {
+            logWtf("Error getting last crash time", e);
+            return 0L;
+        }
+    }
+
+    private void tryWriteLastCrashTime(@Nullable SharedPreferences prefs, long value) {
+        if (prefs == null) return;
+        try {
+            prefs.edit().putLong(PREF_KEY_LAST_CRASH_TIME, value).commit();
+        } catch (Throwable e) {
+            logWtf("Error writing last crash time", e);
+        }
     }
 
     /**
@@ -444,7 +486,9 @@
     private void requestConnector(@NonNull NetworkStackCallback request) {
         // TODO: PID check.
         final int caller = Binder.getCallingUid();
-        if (caller != Process.SYSTEM_UID && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)
+        if (caller != Process.SYSTEM_UID
+                && caller != Process.NETWORK_STACK_UID
+                && !UserHandle.isSameApp(caller, Process.BLUETOOTH_UID)
                 && !UserHandle.isSameApp(caller, Process.PHONE_UID)) {
             // Don't even attempt to obtain the connector and give a nice error message
             throw new SecurityException(
diff --git a/services/net/java/android/net/ip/IpClientManager.java b/services/net/java/android/net/ip/IpClientManager.java
index f8d7e84..1e653cd 100644
--- a/services/net/java/android/net/ip/IpClientManager.java
+++ b/services/net/java/android/net/ip/IpClientManager.java
@@ -21,6 +21,7 @@
 import android.net.ProxyInfo;
 import android.net.TcpKeepalivePacketData;
 import android.net.shared.ProvisioningConfiguration;
+import android.net.util.KeepalivePacketDataUtil;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.util.Log;
@@ -229,7 +230,8 @@
     public boolean addKeepalivePacketFilter(int slot, NattKeepalivePacketData pkt) {
         final long token = Binder.clearCallingIdentity();
         try {
-            mIpClient.addNattKeepalivePacketFilter(slot, pkt.toStableParcelable());
+            mIpClient.addNattKeepalivePacketFilter(
+                    slot, KeepalivePacketDataUtil.toStableParcelable(pkt));
             return true;
         } catch (RemoteException e) {
             log("Error adding Keepalive Packet Filter ", e);
diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java
index 66884c6..6a6a130 100644
--- a/services/net/java/android/net/ip/IpServer.java
+++ b/services/net/java/android/net/ip/IpServer.java
@@ -433,6 +433,9 @@
                 }
             }
             ifcg.clearFlag("running");
+
+            // TODO: this may throw if the interface is already gone. Do proper handling and
+            // simplify the DHCP server start/stop.
             mNMService.setInterfaceConfig(mIfaceName, ifcg);
 
             if (!configureDhcp(enabled, (Inet4Address) addr, prefixLen)) {
@@ -440,6 +443,14 @@
             }
         } catch (Exception e) {
             mLog.e("Error configuring interface " + e);
+            if (!enabled) {
+                try {
+                    // Calling stopDhcp several times is fine
+                    stopDhcp();
+                } catch (Exception dhcpError) {
+                    mLog.e("Error stopping DHCP", dhcpError);
+                }
+            }
             return false;
         }
 
diff --git a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
index e769769..818515a 100644
--- a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
+++ b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
@@ -127,6 +127,7 @@
 
     @Nullable
     private static InetAddress getByAddressOrNull(@Nullable final byte[] address) {
+        if (null == address) return null;
         try {
             return InetAddress.getByAddress(address);
         } catch (UnknownHostException e) {
@@ -227,7 +228,9 @@
         }
 
         /**
-         * Set the lease expiry timestamp of assigned v4 address.
+         * Set the lease expiry timestamp of assigned v4 address. Long.MAX_VALUE is used
+         * to represent "infinite lease".
+         *
          * @param assignedV4AddressExpiry The lease expiry timestamp of assigned v4 address.
          * @return This builder.
          */
diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
index ca6f302..395ad98 100644
--- a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
@@ -40,8 +40,8 @@
                 // NonNull, but still don't crash the system server if null
                 if (null != listener) {
                     listener.onNetworkAttributesRetrieved(
-                            new Status(statusParcelable), l2Key,
-                            new NetworkAttributes(networkAttributesParcelable));
+                            new Status(statusParcelable), l2Key, null == networkAttributesParcelable
+                                ? null : new NetworkAttributes(networkAttributesParcelable));
                 }
             }
 
diff --git a/services/net/java/android/net/util/KeepalivePacketDataUtil.java b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
new file mode 100644
index 0000000..9a51729
--- /dev/null
+++ b/services/net/java/android/net/util/KeepalivePacketDataUtil.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.util;
+
+import android.annotation.NonNull;
+import android.net.NattKeepalivePacketData;
+import android.net.NattKeepalivePacketDataParcelable;
+
+/** @hide */
+public final class KeepalivePacketDataUtil {
+     /**
+     * Convert this NattKeepalivePacketData to a NattKeepalivePacketDataParcelable.
+     */
+    @NonNull
+    public static NattKeepalivePacketDataParcelable toStableParcelable(
+            NattKeepalivePacketData pkt) {
+        final NattKeepalivePacketDataParcelable parcel = new NattKeepalivePacketDataParcelable();
+
+        parcel.srcAddress = pkt.srcAddress.getAddress();
+        parcel.srcPort = pkt.srcPort;
+        parcel.dstAddress = pkt.dstAddress.getAddress();
+        parcel.dstPort = pkt.dstPort;
+        return parcel;
+    }
+}
diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
index 0cb21d0..be93d6ba 100644
--- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -21,7 +21,6 @@
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static android.Manifest.permission.PACKAGE_USAGE_STATS;
 
-import static com.android.server.backup.testing.BackupManagerServiceTestUtils.startBackupThread;
 import static com.android.server.backup.testing.TransportData.backupTransport;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -133,8 +132,7 @@
                 () ->
                         new BackupManagerService(
                                 /* context */ null,
-                                new Trampoline(mContext),
-                                startBackupThread(null)));
+                                new Trampoline(mContext)));
     }
 
     /** Test that the constructor handles {@code null} parameters. */
@@ -144,17 +142,7 @@
                 NullPointerException.class,
                 () ->
                         new BackupManagerService(
-                                mContext, /* trampoline */ null, startBackupThread(null)));
-    }
-
-    /** Test that the constructor handles {@code null} parameters. */
-    @Test
-    public void testConstructor_withNullBackupThread_throws() throws Exception {
-        expectThrows(
-                NullPointerException.class,
-                () ->
-                        new BackupManagerService(
-                                mContext, new Trampoline(mContext), /* backupThread */ null));
+                                mContext, /* trampoline */ null));
     }
 
     /** Test that the service registers users. */
@@ -1581,8 +1569,7 @@
 
     private BackupManagerService createService() {
         mShadowContext.grantPermissions(BACKUP);
-        return new BackupManagerService(
-                mContext, new Trampoline(mContext), startBackupThread(null));
+        return new BackupManagerService(mContext, new Trampoline(mContext));
     }
 
     private BackupManagerService createServiceAndRegisterUser(
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java b/services/robotests/backup/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java
new file mode 100644
index 0000000..823a63c
--- /dev/null
+++ b/services/robotests/backup/src/com/android/server/backup/encryption/chunking/DecryptedChunkFileOutputTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.encryption.chunking;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.backup.encryption.tasks.DecryptedChunkOutput;
+
+import com.google.common.io.Files;
+import com.google.common.primitives.Bytes;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.util.Arrays;
+
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class DecryptedChunkFileOutputTest {
+    private static final byte[] TEST_CHUNK_1 = {1, 2, 3};
+    private static final byte[] TEST_CHUNK_2 = {4, 5, 6, 7, 8, 9, 10};
+    private static final int TEST_BUFFER_LENGTH =
+            Math.max(TEST_CHUNK_1.length, TEST_CHUNK_2.length);
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+    private File mOutputFile;
+    private DecryptedChunkFileOutput mDecryptedChunkFileOutput;
+
+    @Before
+    public void setUp() throws Exception {
+        mOutputFile = temporaryFolder.newFile();
+        mDecryptedChunkFileOutput = new DecryptedChunkFileOutput(mOutputFile);
+    }
+
+    @Test
+    public void open_returnsInstance() throws Exception {
+        DecryptedChunkOutput result = mDecryptedChunkFileOutput.open();
+        assertThat(result).isEqualTo(mDecryptedChunkFileOutput);
+    }
+
+    @Test
+    public void open_nonExistentOutputFolder_throwsException() throws Exception {
+        mDecryptedChunkFileOutput =
+                new DecryptedChunkFileOutput(
+                        new File(temporaryFolder.newFolder(), "mOutput/directory"));
+        assertThrows(FileNotFoundException.class, () -> mDecryptedChunkFileOutput.open());
+    }
+
+    @Test
+    public void open_whenRunTwice_throwsException() throws Exception {
+        mDecryptedChunkFileOutput.open();
+        assertThrows(IllegalStateException.class, () -> mDecryptedChunkFileOutput.open());
+    }
+
+    @Test
+    public void processChunk_beforeOpen_throwsException() throws Exception {
+        assertThrows(IllegalStateException.class,
+                () -> mDecryptedChunkFileOutput.processChunk(new byte[0], 0));
+    }
+
+    @Test
+    public void processChunk_writesChunksToFile() throws Exception {
+        processTestChunks();
+
+        assertThat(Files.toByteArray(mOutputFile))
+                .isEqualTo(Bytes.concat(TEST_CHUNK_1, TEST_CHUNK_2));
+    }
+
+    @Test
+    public void getDigest_beforeClose_throws() throws Exception {
+        mDecryptedChunkFileOutput.open();
+        assertThrows(IllegalStateException.class, () -> mDecryptedChunkFileOutput.getDigest());
+    }
+
+    @Test
+    public void getDigest_returnsCorrectDigest() throws Exception {
+        processTestChunks();
+
+        byte[] actualDigest = mDecryptedChunkFileOutput.getDigest();
+
+        MessageDigest expectedDigest =
+                MessageDigest.getInstance(DecryptedChunkFileOutput.DIGEST_ALGORITHM);
+        expectedDigest.update(TEST_CHUNK_1);
+        expectedDigest.update(TEST_CHUNK_2);
+        assertThat(actualDigest).isEqualTo(expectedDigest.digest());
+    }
+
+    @Test
+    public void getDigest_whenRunTwice_returnsIdenticalDigestBothTimes() throws Exception {
+        processTestChunks();
+
+        byte[] digest1 = mDecryptedChunkFileOutput.getDigest();
+        byte[] digest2 = mDecryptedChunkFileOutput.getDigest();
+
+        assertThat(digest1).isEqualTo(digest2);
+    }
+
+    private void processTestChunks() throws IOException {
+        mDecryptedChunkFileOutput.open();
+        mDecryptedChunkFileOutput.processChunk(Arrays.copyOf(TEST_CHUNK_1, TEST_BUFFER_LENGTH),
+                TEST_CHUNK_1.length);
+        mDecryptedChunkFileOutput.processChunk(Arrays.copyOf(TEST_CHUNK_2, TEST_BUFFER_LENGTH),
+                TEST_CHUNK_2.length);
+        mDecryptedChunkFileOutput.close();
+    }
+}
diff --git a/services/robotests/backup/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java b/services/robotests/backup/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java
new file mode 100644
index 0000000..21c4e07
--- /dev/null
+++ b/services/robotests/backup/src/com/android/server/backup/encryption/tasks/BackupStreamEncrypterTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.encryption.tasks;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.backup.encryption.chunk.ChunkHash;
+import com.android.server.backup.encryption.chunking.EncryptedChunk;
+import com.android.server.backup.testing.CryptoTestUtils;
+import com.android.server.backup.testing.RandomInputStream;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.io.ByteArrayInputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+
+import javax.crypto.SecretKey;
+
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class BackupStreamEncrypterTest {
+    private static final int SALT_LENGTH = 32;
+    private static final int BITS_PER_BYTE = 8;
+    private static final int BYTES_PER_KILOBYTE = 1024;
+    private static final int BYTES_PER_MEGABYTE = 1024 * 1024;
+    private static final int MIN_CHUNK_SIZE = 2 * BYTES_PER_KILOBYTE;
+    private static final int AVERAGE_CHUNK_SIZE = 4 * BYTES_PER_KILOBYTE;
+    private static final int MAX_CHUNK_SIZE = 64 * BYTES_PER_KILOBYTE;
+    private static final int BACKUP_SIZE = 2 * BYTES_PER_MEGABYTE;
+    private static final int SMALL_BACKUP_SIZE = BYTES_PER_KILOBYTE;
+    // 16 bytes for the mac. iv is encoded in a separate field.
+    private static final int BYTES_OVERHEAD_PER_CHUNK = 16;
+    private static final int MESSAGE_DIGEST_SIZE_IN_BYTES = 256 / BITS_PER_BYTE;
+    private static final int RANDOM_SEED = 42;
+    private static final double TOLERANCE = 0.1;
+
+    private Random mRandom;
+    private SecretKey mSecretKey;
+    private byte[] mSalt;
+
+    @Before
+    public void setUp() throws Exception {
+        mSecretKey = CryptoTestUtils.generateAesKey();
+
+        mSalt = new byte[SALT_LENGTH];
+        // Make these tests deterministic
+        mRandom = new Random(RANDOM_SEED);
+        mRandom.nextBytes(mSalt);
+    }
+
+    @Test
+    public void testBackup_producesChunksOfTheGivenAverageSize() throws Exception {
+        BackupEncrypter.Result result = runBackup(BACKUP_SIZE);
+
+        long totalSize = 0;
+        for (EncryptedChunk chunk : result.getNewChunks()) {
+            totalSize += chunk.encryptedBytes().length;
+        }
+
+        double meanSize = totalSize / result.getNewChunks().size();
+        double expectedChunkSize = AVERAGE_CHUNK_SIZE + BYTES_OVERHEAD_PER_CHUNK;
+        assertThat(Math.abs(meanSize - expectedChunkSize) / expectedChunkSize)
+                .isLessThan(TOLERANCE);
+    }
+
+    @Test
+    public void testBackup_producesNoChunksSmallerThanMinSize() throws Exception {
+        BackupEncrypter.Result result = runBackup(BACKUP_SIZE);
+        List<EncryptedChunk> chunks = result.getNewChunks();
+
+        // Last chunk could be smaller, depending on the file size and how it is chunked
+        for (EncryptedChunk chunk : chunks.subList(0, chunks.size() - 2)) {
+            assertThat(chunk.encryptedBytes().length)
+                    .isAtLeast(MIN_CHUNK_SIZE + BYTES_OVERHEAD_PER_CHUNK);
+        }
+    }
+
+    @Test
+    public void testBackup_producesNoChunksLargerThanMaxSize() throws Exception {
+        BackupEncrypter.Result result = runBackup(BACKUP_SIZE);
+        List<EncryptedChunk> chunks = result.getNewChunks();
+
+        for (EncryptedChunk chunk : chunks) {
+            assertThat(chunk.encryptedBytes().length)
+                    .isAtMost(MAX_CHUNK_SIZE + BYTES_OVERHEAD_PER_CHUNK);
+        }
+    }
+
+    @Test
+    public void testBackup_producesAFileOfTheExpectedSize() throws Exception {
+        BackupEncrypter.Result result = runBackup(BACKUP_SIZE);
+        HashMap<ChunkHash, EncryptedChunk> chunksBySha256 =
+                chunksIndexedByKey(result.getNewChunks());
+
+        int expectedSize = BACKUP_SIZE + result.getAllChunks().size() * BYTES_OVERHEAD_PER_CHUNK;
+        int size = 0;
+        for (ChunkHash byteString : result.getAllChunks()) {
+            size += chunksBySha256.get(byteString).encryptedBytes().length;
+        }
+        assertThat(size).isEqualTo(expectedSize);
+    }
+
+    @Test
+    public void testBackup_forSameFile_producesNoNewChunks() throws Exception {
+        byte[] backupData = getRandomData(BACKUP_SIZE);
+        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
+
+        BackupEncrypter.Result incrementalResult = runBackup(backupData, result.getAllChunks());
+
+        assertThat(incrementalResult.getNewChunks()).isEmpty();
+    }
+
+    @Test
+    public void testBackup_onlyUpdatesChangedChunks() throws Exception {
+        byte[] backupData = getRandomData(BACKUP_SIZE);
+        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
+
+        // Let's update the 2nd and 5th chunk
+        backupData[positionOfChunk(result, 1)]++;
+        backupData[positionOfChunk(result, 4)]++;
+        BackupEncrypter.Result incrementalResult = runBackup(backupData, result.getAllChunks());
+
+        assertThat(incrementalResult.getNewChunks()).hasSize(2);
+    }
+
+    @Test
+    public void testBackup_doesNotIncludeUpdatedChunksInNewListing() throws Exception {
+        byte[] backupData = getRandomData(BACKUP_SIZE);
+        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
+
+        // Let's update the 2nd and 5th chunk
+        backupData[positionOfChunk(result, 1)]++;
+        backupData[positionOfChunk(result, 4)]++;
+        BackupEncrypter.Result incrementalResult = runBackup(backupData, result.getAllChunks());
+
+        List<EncryptedChunk> newChunks = incrementalResult.getNewChunks();
+        List<ChunkHash> chunkListing = result.getAllChunks();
+        assertThat(newChunks).doesNotContain(chunkListing.get(1));
+        assertThat(newChunks).doesNotContain(chunkListing.get(4));
+    }
+
+    @Test
+    public void testBackup_includesUnchangedChunksInNewListing() throws Exception {
+        byte[] backupData = getRandomData(BACKUP_SIZE);
+        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
+
+        // Let's update the 2nd and 5th chunk
+        backupData[positionOfChunk(result, 1)]++;
+        backupData[positionOfChunk(result, 4)]++;
+        BackupEncrypter.Result incrementalResult = runBackup(backupData, result.getAllChunks());
+
+        HashSet<ChunkHash> chunksPresentInIncremental =
+                new HashSet<>(incrementalResult.getAllChunks());
+        chunksPresentInIncremental.removeAll(result.getAllChunks());
+
+        assertThat(chunksPresentInIncremental).hasSize(2);
+    }
+
+    @Test
+    public void testBackup_forSameData_createsSameDigest() throws Exception {
+        byte[] backupData = getRandomData(SMALL_BACKUP_SIZE);
+
+        BackupEncrypter.Result result = runBackup(backupData, ImmutableList.of());
+        BackupEncrypter.Result result2 = runBackup(backupData, ImmutableList.of());
+        assertThat(result.getDigest()).isEqualTo(result2.getDigest());
+    }
+
+    @Test
+    public void testBackup_forDifferentData_createsDifferentDigest() throws Exception {
+        byte[] backup1Data = getRandomData(SMALL_BACKUP_SIZE);
+        byte[] backup2Data = getRandomData(SMALL_BACKUP_SIZE);
+
+        BackupEncrypter.Result result = runBackup(backup1Data, ImmutableList.of());
+        BackupEncrypter.Result result2 = runBackup(backup2Data, ImmutableList.of());
+        assertThat(result.getDigest()).isNotEqualTo(result2.getDigest());
+    }
+
+    @Test
+    public void testBackup_createsDigestOf32Bytes() throws Exception {
+        assertThat(runBackup(getRandomData(SMALL_BACKUP_SIZE), ImmutableList.of()).getDigest())
+                .hasLength(MESSAGE_DIGEST_SIZE_IN_BYTES);
+    }
+
+    private byte[] getRandomData(int size) throws Exception {
+        RandomInputStream randomInputStream = new RandomInputStream(mRandom, size);
+        byte[] backupData = new byte[size];
+        randomInputStream.read(backupData);
+        return backupData;
+    }
+
+    private BackupEncrypter.Result runBackup(int backupSize) throws Exception {
+        RandomInputStream dataStream = new RandomInputStream(mRandom, backupSize);
+        BackupStreamEncrypter task =
+                new BackupStreamEncrypter(
+                        dataStream, MIN_CHUNK_SIZE, MAX_CHUNK_SIZE, AVERAGE_CHUNK_SIZE);
+        return task.backup(mSecretKey, mSalt, ImmutableSet.of());
+    }
+
+    private BackupEncrypter.Result runBackup(byte[] data, List<ChunkHash> existingChunks)
+            throws Exception {
+        ByteArrayInputStream dataStream = new ByteArrayInputStream(data);
+        BackupStreamEncrypter task =
+                new BackupStreamEncrypter(
+                        dataStream, MIN_CHUNK_SIZE, MAX_CHUNK_SIZE, AVERAGE_CHUNK_SIZE);
+        return task.backup(mSecretKey, mSalt, ImmutableSet.copyOf(existingChunks));
+    }
+
+    /** Returns a {@link HashMap} of the chunks, indexed by the SHA-256 Mac key. */
+    private static HashMap<ChunkHash, EncryptedChunk> chunksIndexedByKey(
+            List<EncryptedChunk> chunks) {
+        HashMap<ChunkHash, EncryptedChunk> chunksByKey = new HashMap<>();
+        for (EncryptedChunk chunk : chunks) {
+            chunksByKey.put(chunk.key(), chunk);
+        }
+        return chunksByKey;
+    }
+
+    /**
+     * Returns the start position of the chunk in the plaintext backup data.
+     *
+     * @param result The result from a backup.
+     * @param index The index of the chunk in question.
+     * @return the start position.
+     */
+    private static int positionOfChunk(BackupEncrypter.Result result, int index) {
+        HashMap<ChunkHash, EncryptedChunk> byKey = chunksIndexedByKey(result.getNewChunks());
+        List<ChunkHash> listing = result.getAllChunks();
+
+        int position = 0;
+        for (int i = 0; i < index - 1; i++) {
+            EncryptedChunk chunk = byKey.get(listing.get(i));
+            position += chunk.encryptedBytes().length - BYTES_OVERHEAD_PER_CHUNK;
+        }
+
+        return position;
+    }
+}
diff --git a/services/robotests/backup/src/com/android/server/backup/testing/RandomInputStream.java b/services/robotests/backup/src/com/android/server/backup/testing/RandomInputStream.java
new file mode 100644
index 0000000..998da0b
--- /dev/null
+++ b/services/robotests/backup/src/com/android/server/backup/testing/RandomInputStream.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.backup.testing;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Random;
+
+/** {@link InputStream} that generates random bytes up to a given length. For testing purposes. */
+public class RandomInputStream extends InputStream {
+    private static final int BYTE_MAX_VALUE = 255;
+
+    private final Random mRandom;
+    private final int mSizeBytes;
+    private int mBytesRead;
+
+    /**
+     * A new instance, generating {@code sizeBytes} from {@code random} as a source.
+     *
+     * @param random Source of random bytes.
+     * @param sizeBytes The number of bytes to generate before closing the stream.
+     */
+    public RandomInputStream(Random random, int sizeBytes) {
+        mRandom = random;
+        mSizeBytes = sizeBytes;
+        mBytesRead = 0;
+    }
+
+    @Override
+    public int read() throws IOException {
+        if (isFinished()) {
+            return -1;
+        }
+        mBytesRead++;
+        return mRandom.nextInt(BYTE_MAX_VALUE);
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        checkArgument(off + len <= b.length);
+        if (isFinished()) {
+            return -1;
+        }
+        int length = Math.min(len, mSizeBytes - mBytesRead);
+        int end = off + length;
+
+        for (int i = off; i < end; ) {
+            for (int rnd = mRandom.nextInt(), n = Math.min(end - i, Integer.SIZE / Byte.SIZE);
+                    n-- > 0;
+                    rnd >>= Byte.SIZE) {
+                b[i++] = (byte) rnd;
+            }
+        }
+
+        mBytesRead += length;
+        return length;
+    }
+
+    private boolean isFinished() {
+        return mBytesRead >= mSizeBytes;
+    }
+}
diff --git a/services/tests/mockingservicestests/AndroidManifest.xml b/services/tests/mockingservicestests/AndroidManifest.xml
index 32d7d02..b3b5af0 100644
--- a/services/tests/mockingservicestests/AndroidManifest.xml
+++ b/services/tests/mockingservicestests/AndroidManifest.xml
@@ -20,6 +20,7 @@
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
     <uses-permission android:name="android.permission.HARDWARE_TEST"/>
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.MANAGE_APPOPS"/>
 
     <application android:testOnly="true"
                  android:debuggable="true">
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index cdcdf91..1e29ed6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -1032,6 +1032,16 @@
         assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1));
     }
 
+    @Test
+    public void alarmCountOnPendingIntentCancel() {
+        final PendingIntent pi = getNewMockPendingIntent();
+        setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 123, pi);
+        verify(pi).registerCancelListener(mService.mOperationCancelListener);
+        assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+        mService.mOperationCancelListener.onCancelled(pi);
+        assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
+    }
+
     @After
     public void tearDown() {
         if (mMockingSession != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index e51ee94..06c83a2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -52,6 +52,7 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.longThat;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -894,6 +895,54 @@
         verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
     }
 
+    @Test
+    public void testLightIdleAlarmUnaffectedByMotion() {
+        setNetworkConnected(true);
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+        spyOn(mDeviceIdleController);
+
+        InOrder inOrder = inOrder(mDeviceIdleController);
+
+        // Set state to INACTIVE.
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+        // No active ops means INACTIVE should go straight to IDLE.
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+        inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
+                longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT));
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+        inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
+                longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET));
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+        inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
+                longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT));
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+        inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
+                longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET));
+
+        // Test that motion doesn't reset the idle timeout.
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+        inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
+                longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT));
+    }
+
     ///////////////// EXIT conditions ///////////////////
 
     @Test
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 475901a..4a33739 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java
@@ -62,7 +62,8 @@
     private CountDownLatch mCountDown;
 
     @Rule
-    public TestableDeviceConfig mDeviceConfig = new TestableDeviceConfig();
+    public TestableDeviceConfig.TestableDeviceConfigRule
+            mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
 
     @Before
     public void setUp() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index 539dac8..06366cf 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -35,19 +35,24 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 
 import android.app.ActivityManager;
+import android.app.AppOpsManager;
 import android.app.AppOpsManager.OpEntry;
 import android.app.AppOpsManager.PackageOps;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManagerInternal;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
+import android.os.RemoteCallback;
+import android.provider.Settings;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -64,6 +69,9 @@
 
 import java.io.File;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Unit tests for AppOpsService. Covers functionality that is difficult to test using CTS tests
@@ -88,24 +96,9 @@
     private long mTestStartMillis;
     private StaticMockitoSession mMockingSession;
 
-    @Before
-    public void mockPackageManagerInternalGetApplicationInfo() {
-        mMockingSession = mockitoSession()
-                .strictness(Strictness.LENIENT)
-                .spyStatic(LocalServices.class)
-                .startMocking();
-
-        // Mock LocalServices.getService(PackageManagerInternal.class).getApplicationInfo dependency
-        // needed by AppOpsService
-        PackageManagerInternal mockPackageManagerInternal = mock(PackageManagerInternal.class);
-        when(mockPackageManagerInternal.getApplicationInfo(eq(sMyPackageName), anyInt(), anyInt(),
-                anyInt())).thenReturn(sContext.getApplicationInfo());
-        doReturn(mockPackageManagerInternal).when(
-                () -> LocalServices.getService(PackageManagerInternal.class));
-    }
-
     private void setupAppOpsService() {
         mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+        mAppOpsService.mHistoricalRegistry.systemReady(sContext.getContentResolver());
         mAppOpsService.mContext = spy(sContext);
 
         // Always approve all permission checks
@@ -126,7 +119,10 @@
         mHandler = new Handler(handlerThread.getLooper());
         mMyUid = Process.myUid();
 
+        initializeStaticMocks();
+
         setupAppOpsService();
+
         mTestStartMillis = System.currentTimeMillis();
     }
 
@@ -135,6 +131,26 @@
         mMockingSession.finishMocking();
     }
 
+    private void initializeStaticMocks() {
+        mMockingSession = mockitoSession()
+                .strictness(Strictness.LENIENT)
+                .spyStatic(LocalServices.class)
+                .spyStatic(Settings.Global.class)
+                .startMocking();
+
+        // Mock LocalServices.getService(PackageManagerInternal.class).getApplicationInfo dependency
+        // needed by AppOpsService
+        PackageManagerInternal mockPackageManagerInternal = mock(PackageManagerInternal.class);
+        when(mockPackageManagerInternal.getApplicationInfo(eq(sMyPackageName), anyInt(), anyInt(),
+                anyInt())).thenReturn(sContext.getApplicationInfo());
+        doReturn(mockPackageManagerInternal).when(
+                () -> LocalServices.getService(PackageManagerInternal.class));
+
+        // Mock behavior to use specific Settings.Global.APPOP_HISTORY_PARAMETERS
+        doReturn(null).when(() -> Settings.Global.getString(any(ContentResolver.class),
+                eq(Settings.Global.APPOP_HISTORY_PARAMETERS)));
+    }
+
     @Test
     public void testGetOpsForPackage_noOpsLogged() {
         assertThat(getLoggedOps()).isNull();
@@ -258,6 +274,46 @@
         assertThat(getLoggedOps()).isNull();
     }
 
+
+    @Test
+    public void testPackageRemovedHistoricalOps() throws InterruptedException {
+        mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
+        mAppOpsService.noteOperation(OP_READ_SMS, mMyUid, sMyPackageName);
+
+        AppOpsManager.HistoricalOps historicalOps = new AppOpsManager.HistoricalOps(0, 15000);
+        historicalOps.increaseAccessCount(OP_READ_SMS, mMyUid, sMyPackageName,
+                AppOpsManager.UID_STATE_PERSISTENT, 0, 1);
+
+        mAppOpsService.addHistoricalOps(historicalOps);
+
+        AtomicReference<AppOpsManager.HistoricalOps> resultOpsRef = new AtomicReference<>();
+        AtomicReference<CountDownLatch> latchRef = new AtomicReference<>(new CountDownLatch(1));
+        RemoteCallback callback = new RemoteCallback(result -> {
+            resultOpsRef.set(result.getParcelable(AppOpsManager.KEY_HISTORICAL_OPS));
+            latchRef.get().countDown();
+        });
+
+        // First, do a fetch to ensure it's written
+        mAppOpsService.getHistoricalOps(mMyUid, sMyPackageName, null, 0, Long.MAX_VALUE, 0,
+                callback);
+
+        latchRef.get().await(5, TimeUnit.SECONDS);
+        assertThat(latchRef.get().getCount()).isEqualTo(0);
+        assertThat(resultOpsRef.get().isEmpty()).isFalse();
+
+        // Then, check it's deleted on removal
+        mAppOpsService.packageRemoved(mMyUid, sMyPackageName);
+
+        latchRef.set(new CountDownLatch(1));
+
+        mAppOpsService.getHistoricalOps(mMyUid, sMyPackageName, null, 0, Long.MAX_VALUE, 0,
+                callback);
+
+        latchRef.get().await(5, TimeUnit.SECONDS);
+        assertThat(latchRef.get().getCount()).isEqualTo(0);
+        assertThat(resultOpsRef.get().isEmpty()).isTrue();
+    }
+
     @Test
     public void testUidRemoved() {
         mAppOpsService.setMode(OP_READ_SMS, mMyUid, sMyPackageName, MODE_ALLOWED);
@@ -299,7 +355,7 @@
     }
 
     @Test
-    public void testUidProcStateChange_cachedToFgs() throws Exception {
+    public void testUidProcStateChange_cachedToFgs() {
         setupProcStateTests();
 
         mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
@@ -312,7 +368,7 @@
     }
 
     @Test
-    public void testUidProcStateChange_cachedToFgsLocation() throws Exception {
+    public void testUidProcStateChange_cachedToFgsLocation() {
         setupProcStateTests();
 
         mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
index 73b3b8b..a785300 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/color/DisplayTransformManagerTest.java
@@ -19,6 +19,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
+import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE;
 import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_DISPLAY_COLOR;
 import static com.android.server.display.color.DisplayTransformManager.PERSISTENT_PROPERTY_SATURATION;
 
@@ -28,6 +29,7 @@
 
 import android.hardware.display.ColorDisplayManager;
 import android.os.SystemProperties;
+import android.view.Display;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -79,7 +81,7 @@
 
     @Test
     public void setColorMode_natural() {
-        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix);
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo("0" /* managed */);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -88,7 +90,7 @@
 
     @Test
     public void setColorMode_boosted() {
-        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix);
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED, mNightDisplayMatrix, -1);
 
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo("0" /* managed */);
@@ -98,7 +100,7 @@
 
     @Test
     public void setColorMode_saturated() {
-        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix);
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo("1" /* unmanaged */);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -107,7 +109,7 @@
 
     @Test
     public void setColorMode_automatic() {
-        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix);
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo("2" /* enhanced */);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -116,7 +118,7 @@
 
     @Test
     public void setColorMode_vendor() {
-        mDtm.setColorMode(0x100, mNightDisplayMatrix);
+        mDtm.setColorMode(0x100, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo(Integer.toString(0x100) /* pass-through */);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
@@ -125,10 +127,38 @@
 
     @Test
     public void setColorMode_outOfBounds() {
-        mDtm.setColorMode(0x50, mNightDisplayMatrix);
+        mDtm.setColorMode(0x50, mNightDisplayMatrix, -1);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_DISPLAY_COLOR))
                 .isEqualTo(null);
         assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
                 .isEqualTo(null);
     }
+
+    @Test
+    public void setColorMode_withoutColorSpace() {
+        String magicPropertyValue = "magic";
+
+        // Start with a known state, which we expect to remain unmodified
+        SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE, magicPropertyValue);
+
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix,
+                Display.COLOR_MODE_INVALID);
+        assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE))
+                .isEqualTo(magicPropertyValue);
+    }
+
+    @Test
+    public void setColorMode_withColorSpace() {
+        String magicPropertyValue = "magic";
+        int testPropertyValue = Display.COLOR_MODE_SRGB;
+
+        // Start with a known state, which we expect to get modified
+        SystemProperties.set(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE, magicPropertyValue);
+
+        mDtm.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL, mNightDisplayMatrix,
+                testPropertyValue);
+        assertThat(mSystemProperties.get(PERSISTENT_PROPERTY_COMPOSITION_COLOR_MODE))
+                .isEqualTo(Integer.toString(testPropertyValue));
+    }
+
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 18c524a..22cd3d3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.job;
 
+import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.HOUR_IN_MILLIS;
 import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
 
@@ -24,6 +25,8 @@
 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;
+import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX;
+import static com.android.server.job.JobSchedulerService.RARE_INDEX;
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 
 import static org.junit.Assert.assertEquals;
@@ -162,6 +165,56 @@
 
     /**
      * Confirm that {@link JobSchedulerService#getRescheduleJobForPeriodic(JobStatus)} returns a job
+     * with the correct delay and deadline constraints if the periodic job is scheduled with the
+     * minimum possible period.
+     */
+    @Test
+    public void testGetRescheduleJobForPeriodic_minPeriod() {
+        final long now = sElapsedRealtimeClock.millis();
+        JobStatus job = createJobStatus("testGetRescheduleJobForPeriodic_insideWindow",
+                createJobInfo().setPeriodic(15 * MINUTE_IN_MILLIS));
+        final long nextWindowStartTime = now + 15 * MINUTE_IN_MILLIS;
+        final long nextWindowEndTime = now + 30 * MINUTE_IN_MILLIS;
+
+        for (int i = 0; i < 25; i++) {
+            JobStatus rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+            assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+            assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+            advanceElapsedClock(30_000); // 30 seconds
+        }
+
+        for (int i = 0; i < 5; i++) {
+            // Window buffering in last 1/6 of window.
+            JobStatus rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+            assertEquals(nextWindowStartTime + i * 30_000, rescheduledJob.getEarliestRunTime());
+            assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+            advanceElapsedClock(30_000); // 30 seconds
+        }
+    }
+
+    /**
+     * Confirm that {@link JobSchedulerService#getRescheduleJobForPeriodic(JobStatus)} returns a job
+     * with the correct delay and deadline constraints if the periodic job is scheduled with a
+     * period that's too large.
+     */
+    @Test
+    public void testGetRescheduleJobForPeriodic_largePeriod() {
+        final long now = sElapsedRealtimeClock.millis();
+        JobStatus job = createJobStatus("testGetRescheduleJobForPeriodic_insideWindow",
+                createJobInfo().setPeriodic(2 * 365 * DAY_IN_MILLIS));
+        assertEquals(now, job.getEarliestRunTime());
+        // Periods are capped at 365 days (1 year).
+        assertEquals(now + 365 * DAY_IN_MILLIS, job.getLatestRunTimeElapsed());
+        final long nextWindowStartTime = now + 365 * DAY_IN_MILLIS;
+        final long nextWindowEndTime = nextWindowStartTime + 365 * DAY_IN_MILLIS;
+
+        JobStatus rescheduledJob = mService.getRescheduleJobForPeriodic(job);
+        assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
+        assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
+    }
+
+    /**
+     * Confirm that {@link JobSchedulerService#getRescheduleJobForPeriodic(JobStatus)} returns a job
      * with the correct delay and deadline constraints if the periodic job is completed and
      * rescheduled while run in its expected running window.
      */
@@ -611,4 +664,86 @@
         assertEquals(nextWindowStartTime, rescheduledJob.getEarliestRunTime());
         assertEquals(nextWindowEndTime, rescheduledJob.getLatestRunTimeElapsed());
     }
+
+    /** Tests that rare job batching works as expected. */
+    @Test
+    public void testRareJobBatching() {
+        spyOn(mService);
+        doNothing().when(mService).evaluateControllerStatesLocked(any());
+        doNothing().when(mService).noteJobsPending(any());
+        doReturn(true).when(mService).isReadyToBeExecutedLocked(any());
+        advanceElapsedClock(24 * HOUR_IN_MILLIS);
+
+        JobSchedulerService.MaybeReadyJobQueueFunctor maybeQueueFunctor =
+                mService.new MaybeReadyJobQueueFunctor();
+        mService.mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT = 5;
+        mService.mConstants.MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS = HOUR_IN_MILLIS;
+        mService.mConstants.MIN_CONNECTIVITY_COUNT = 2;
+        mService.mConstants.MIN_READY_JOBS_COUNT = 1;
+
+        JobStatus job = createJobStatus(
+                "testRareJobBatching",
+                createJobInfo().setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY));
+        job.setStandbyBucket(RARE_INDEX);
+
+        // Not enough RARE jobs to run.
+        mService.mPendingJobs.clear();
+        maybeQueueFunctor.reset();
+        for (int i = 0; i < mService.mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT / 2; ++i) {
+            maybeQueueFunctor.accept(job);
+            assertEquals(i + 1, maybeQueueFunctor.forceBatchedCount);
+            assertEquals(i + 1, maybeQueueFunctor.runnableJobs.size());
+            assertEquals(sElapsedRealtimeClock.millis(), job.getFirstForceBatchedTimeElapsed());
+        }
+        maybeQueueFunctor.postProcess();
+        assertEquals(0, mService.mPendingJobs.size());
+
+        // Enough RARE jobs to run.
+        mService.mPendingJobs.clear();
+        maybeQueueFunctor.reset();
+        for (int i = 0; i < mService.mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT; ++i) {
+            maybeQueueFunctor.accept(job);
+            assertEquals(i + 1, maybeQueueFunctor.forceBatchedCount);
+            assertEquals(i + 1, maybeQueueFunctor.runnableJobs.size());
+            assertEquals(sElapsedRealtimeClock.millis(), job.getFirstForceBatchedTimeElapsed());
+        }
+        maybeQueueFunctor.postProcess();
+        assertEquals(5, mService.mPendingJobs.size());
+
+        // Not enough RARE jobs to run, but a non-batched job saves the day.
+        mService.mPendingJobs.clear();
+        maybeQueueFunctor.reset();
+        JobStatus activeJob = createJobStatus(
+                "testRareJobBatching",
+                createJobInfo().setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY));
+        activeJob.setStandbyBucket(ACTIVE_INDEX);
+        for (int i = 0; i < mService.mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT / 2; ++i) {
+            maybeQueueFunctor.accept(job);
+            assertEquals(i + 1, maybeQueueFunctor.forceBatchedCount);
+            assertEquals(i + 1, maybeQueueFunctor.runnableJobs.size());
+            assertEquals(sElapsedRealtimeClock.millis(), job.getFirstForceBatchedTimeElapsed());
+        }
+        maybeQueueFunctor.accept(activeJob);
+        maybeQueueFunctor.postProcess();
+        assertEquals(3, mService.mPendingJobs.size());
+
+        // Not enough RARE jobs to run, but an old RARE job saves the day.
+        mService.mPendingJobs.clear();
+        maybeQueueFunctor.reset();
+        JobStatus oldRareJob = createJobStatus("testRareJobBatching", createJobInfo());
+        oldRareJob.setStandbyBucket(RARE_INDEX);
+        final long oldBatchTime = sElapsedRealtimeClock.millis()
+                - 2 * mService.mConstants.MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS;
+        oldRareJob.setFirstForceBatchedTimeElapsed(oldBatchTime);
+        for (int i = 0; i < mService.mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT / 2; ++i) {
+            maybeQueueFunctor.accept(job);
+            assertEquals(i + 1, maybeQueueFunctor.forceBatchedCount);
+            assertEquals(i + 1, maybeQueueFunctor.runnableJobs.size());
+            assertEquals(sElapsedRealtimeClock.millis(), job.getFirstForceBatchedTimeElapsed());
+        }
+        maybeQueueFunctor.accept(oldRareJob);
+        assertEquals(oldBatchTime, oldRareJob.getFirstForceBatchedTimeElapsed());
+        maybeQueueFunctor.postProcess();
+        assertEquals(3, mService.mPendingJobs.size());
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index c45122e..328e8f4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -59,6 +59,7 @@
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.JobSchedulerService.Constants;
+import com.android.server.job.JobServiceContext;
 import com.android.server.net.NetworkPolicyManagerInternal;
 
 import org.junit.Before;
@@ -109,7 +110,7 @@
         JobSchedulerService.sSystemClock =
                 Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
         JobSchedulerService.sUptimeMillisClock =
-                Clock.fixed(SystemClock.uptimeMillisClock().instant(), ZoneOffset.UTC);
+                Clock.fixed(SystemClock.uptimeClock().instant(), ZoneOffset.UTC);
         JobSchedulerService.sElapsedRealtimeClock =
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC);
 
@@ -134,43 +135,86 @@
     public void testInsane() throws Exception {
         final Network net = new Network(101);
         final JobInfo.Builder job = createJob()
-                .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1))
+                .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1),
+                        DataUnit.MEBIBYTES.toBytes(1))
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
 
+        final ConnectivityController controller = new ConnectivityController(mService);
+        when(mService.getMaxJobExecutionTimeMs(any()))
+                .thenReturn(JobServiceContext.EXECUTING_TIMESLICE_MILLIS);
+
         // Slow network is too slow
-        assertFalse(ConnectivityController.isSatisfied(createJobStatus(job), net,
+        assertFalse(controller.isSatisfied(createJobStatus(job), net,
                 createCapabilities().setLinkUpstreamBandwidthKbps(1)
                         .setLinkDownstreamBandwidthKbps(1), mConstants));
+        // Slow downstream
+        assertFalse(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(1024)
+                        .setLinkDownstreamBandwidthKbps(1), mConstants));
+        // Slow upstream
+        assertFalse(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(1)
+                        .setLinkDownstreamBandwidthKbps(1024), mConstants));
         // Fast network looks great
-        assertTrue(ConnectivityController.isSatisfied(createJobStatus(job), net,
+        assertTrue(controller.isSatisfied(createJobStatus(job), net,
                 createCapabilities().setLinkUpstreamBandwidthKbps(1024)
                         .setLinkDownstreamBandwidthKbps(1024), mConstants));
+        // Slow network still good given time
+        assertTrue(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(130)
+                        .setLinkDownstreamBandwidthKbps(130), mConstants));
+
+        when(mService.getMaxJobExecutionTimeMs(any())).thenReturn(60_000L);
+
+        // Slow network is too slow
+        assertFalse(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(1)
+                        .setLinkDownstreamBandwidthKbps(1), mConstants));
+        // Slow downstream
+        assertFalse(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(137)
+                        .setLinkDownstreamBandwidthKbps(1), mConstants));
+        // Slow upstream
+        assertFalse(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(1)
+                        .setLinkDownstreamBandwidthKbps(137), mConstants));
+        // Network good enough
+        assertTrue(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(137)
+                        .setLinkDownstreamBandwidthKbps(137), mConstants));
+        // Network slightly too slow given reduced time
+        assertFalse(controller.isSatisfied(createJobStatus(job), net,
+                createCapabilities().setLinkUpstreamBandwidthKbps(130)
+                        .setLinkDownstreamBandwidthKbps(130), mConstants));
     }
 
     @Test
     public void testCongestion() throws Exception {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         final JobInfo.Builder job = createJob()
-                .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1))
+                .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1),
+                        DataUnit.MEBIBYTES.toBytes(1))
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
         final JobStatus early = createJobStatus(job, now - 1000, now + 2000);
         final JobStatus late = createJobStatus(job, now - 2000, now + 1000);
 
+        final ConnectivityController controller = new ConnectivityController(mService);
+
         // Uncongested network is whenever
         {
             final Network net = new Network(101);
             final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED);
-            assertTrue(ConnectivityController.isSatisfied(early, net, caps, mConstants));
-            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
+            assertTrue(controller.isSatisfied(early, net, caps, mConstants));
+            assertTrue(controller.isSatisfied(late, net, caps, mConstants));
         }
 
         // Congested network is more selective
         {
             final Network net = new Network(101);
             final NetworkCapabilities caps = createCapabilities();
-            assertFalse(ConnectivityController.isSatisfied(early, net, caps, mConstants));
-            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
+            assertFalse(controller.isSatisfied(early, net, caps, mConstants));
+            assertTrue(controller.isSatisfied(late, net, caps, mConstants));
         }
     }
 
@@ -178,25 +222,28 @@
     public void testRelaxed() throws Exception {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         final JobInfo.Builder job = createJob()
-                .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1))
+                .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1),
+                        DataUnit.MEBIBYTES.toBytes(1))
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
         final JobStatus early = createJobStatus(job, now - 1000, now + 2000);
         final JobStatus late = createJobStatus(job, now - 2000, now + 1000);
 
-        job.setIsPrefetch(true);
+        job.setPrefetch(true);
         final JobStatus earlyPrefetch = createJobStatus(job, now - 1000, now + 2000);
         final JobStatus latePrefetch = createJobStatus(job, now - 2000, now + 1000);
 
+        final ConnectivityController controller = new ConnectivityController(mService);
+
         // Unmetered network is whenever
         {
             final Network net = new Network(101);
             final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED)
                     .addCapability(NET_CAPABILITY_NOT_METERED);
-            assertTrue(ConnectivityController.isSatisfied(early, net, caps, mConstants));
-            assertTrue(ConnectivityController.isSatisfied(late, net, caps, mConstants));
-            assertTrue(ConnectivityController.isSatisfied(earlyPrefetch, net, caps, mConstants));
-            assertTrue(ConnectivityController.isSatisfied(latePrefetch, net, caps, mConstants));
+            assertTrue(controller.isSatisfied(early, net, caps, mConstants));
+            assertTrue(controller.isSatisfied(late, net, caps, mConstants));
+            assertTrue(controller.isSatisfied(earlyPrefetch, net, caps, mConstants));
+            assertTrue(controller.isSatisfied(latePrefetch, net, caps, mConstants));
         }
 
         // Metered network is only when prefetching and late
@@ -204,10 +251,10 @@
             final Network net = new Network(101);
             final NetworkCapabilities caps = createCapabilities()
                     .addCapability(NET_CAPABILITY_NOT_CONGESTED);
-            assertFalse(ConnectivityController.isSatisfied(early, net, caps, mConstants));
-            assertFalse(ConnectivityController.isSatisfied(late, net, caps, mConstants));
-            assertFalse(ConnectivityController.isSatisfied(earlyPrefetch, net, caps, mConstants));
-            assertTrue(ConnectivityController.isSatisfied(latePrefetch, net, caps, mConstants));
+            assertFalse(controller.isSatisfied(early, net, caps, mConstants));
+            assertFalse(controller.isSatisfied(late, net, caps, mConstants));
+            assertFalse(controller.isSatisfied(earlyPrefetch, net, caps, mConstants));
+            assertTrue(controller.isSatisfied(latePrefetch, net, caps, mConstants));
         }
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
index 4bf62c6..94e02d3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
@@ -82,7 +82,7 @@
         JobSchedulerService.sSystemClock =
                 Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
         JobSchedulerService.sUptimeMillisClock =
-                Clock.fixed(SystemClock.uptimeMillisClock().instant(), ZoneOffset.UTC);
+                Clock.fixed(SystemClock.uptimeClock().instant(), ZoneOffset.UTC);
         JobSchedulerService.sElapsedRealtimeClock =
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC);
     }
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 1db6b8e..2d70231 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
@@ -28,6 +28,7 @@
 import static com.android.server.job.JobSchedulerService.NEVER_INDEX;
 import static com.android.server.job.JobSchedulerService.RARE_INDEX;
 import static com.android.server.job.JobSchedulerService.WORKING_INDEX;
+import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -73,6 +74,7 @@
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
 import com.android.server.job.JobSchedulerService.Constants;
+import com.android.server.job.JobServiceContext;
 import com.android.server.job.JobStore;
 import com.android.server.job.controllers.QuotaController.ExecutionStats;
 import com.android.server.job.controllers.QuotaController.TimingSession;
@@ -170,7 +172,7 @@
                 getAdvancedClock(Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC),
                         24 * HOUR_IN_MILLIS);
         JobSchedulerService.sUptimeMillisClock = getAdvancedClock(
-                Clock.fixed(SystemClock.uptimeMillisClock().instant(), ZoneOffset.UTC),
+                Clock.fixed(SystemClock.uptimeClock().instant(), ZoneOffset.UTC),
                 24 * HOUR_IN_MILLIS);
         JobSchedulerService.sElapsedRealtimeClock = getAdvancedClock(
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC),
@@ -975,6 +977,37 @@
         assertEquals(expectedStats, newStatsRare);
     }
 
+    @Test
+    public void testGetMaxJobExecutionTimeLocked() {
+        mQuotaController.saveTimingSession(0, SOURCE_PACKAGE,
+                createTimingSession(sElapsedRealtimeClock.millis() - (6 * MINUTE_IN_MILLIS),
+                        3 * MINUTE_IN_MILLIS, 5));
+        JobStatus job = createJobStatus("testGetMaxJobExecutionTimeLocked", 0);
+        job.setStandbyBucket(RARE_INDEX);
+
+        setCharging();
+        assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS,
+                mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
+
+        setDischarging();
+        setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+        assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS,
+                mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
+
+        // Top-started job
+        setProcessState(ActivityManager.PROCESS_STATE_TOP);
+        mQuotaController.maybeStartTrackingJobLocked(job, null);
+        mQuotaController.prepareForExecutionLocked(job);
+        setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+        assertEquals(JobServiceContext.EXECUTING_TIMESLICE_MILLIS,
+                mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
+        mQuotaController.maybeStopTrackingJobLocked(job, null, false);
+
+        setProcessState(ActivityManager.PROCESS_STATE_RECEIVER);
+        assertEquals(7 * MINUTE_IN_MILLIS,
+                mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+    }
+
     /**
      * Test getTimeUntilQuotaConsumedLocked when the determination is based within the bucket
      * window.
@@ -1892,6 +1925,16 @@
         assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[RARE_INDEX]);
         assertEquals(0, mQuotaController.getTimingSessionCoalescingDurationMs());
 
+        // Invalid configurations.
+        // In_QUOTA_BUFFER should never be greater than ALLOWED_TIME_PER_PERIOD
+        mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 2 * MINUTE_IN_MILLIS;
+        mQcConstants.IN_QUOTA_BUFFER_MS = 5 * MINUTE_IN_MILLIS;
+
+        mQcConstants.updateConstants();
+
+        assertTrue(mQuotaController.getInQuotaBufferMs()
+                <= mQuotaController.getAllowedTimePerPeriodMs());
+
         // Test larger than a day. Controller should cap at one day.
         mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 25 * HOUR_IN_MILLIS;
         mQcConstants.IN_QUOTA_BUFFER_MS = 25 * HOUR_IN_MILLIS;
@@ -2450,6 +2493,8 @@
                 timeout(remainingTimeMs + 2 * SECOND_IN_MILLIS).times(1))
                 .onControllerStateChanged();
         assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+        assertEquals(JobSchedulerService.sElapsedRealtimeClock.millis(),
+                jobStatus.getWhenStandbyDeferred());
     }
 
     /**
@@ -2606,6 +2651,8 @@
                 "testStartAlarmScheduled_TimingSessionCount_AllowedTime", 42);
         mQuotaController.maybeStartTrackingJobLocked(throttledJob, null);
         assertFalse(throttledJob.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+        assertEquals(JobSchedulerService.sElapsedRealtimeClock.millis(),
+                throttledJob.getWhenStandbyDeferred());
 
         ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID,
                 SOURCE_PACKAGE, standbyBucket);
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/StateControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/StateControllerTest.java
index db69242..7a12b42 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/StateControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/StateControllerTest.java
@@ -117,7 +117,7 @@
         JobSchedulerService.sSystemClock =
                 Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
         JobSchedulerService.sUptimeMillisClock =
-                Clock.fixed(SystemClock.uptimeMillisClock().instant(), ZoneOffset.UTC);
+                Clock.fixed(SystemClock.uptimeClock().instant(), ZoneOffset.UTC);
         JobSchedulerService.sElapsedRealtimeClock =
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC);
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
index 19369db..3614763 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
@@ -71,7 +71,6 @@
     private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests";
     private static final int SOURCE_USER_ID = 0;
 
-    private TimeController.TcConstants mConstants;
     private TimeController mTimeController;
 
     private MockitoSession mMockingSession;
@@ -105,13 +104,12 @@
         JobSchedulerService.sSystemClock =
                 Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
         JobSchedulerService.sUptimeMillisClock =
-                Clock.fixed(SystemClock.uptimeMillisClock().instant(), ZoneOffset.UTC);
+                Clock.fixed(SystemClock.uptimeClock().instant(), ZoneOffset.UTC);
         JobSchedulerService.sElapsedRealtimeClock =
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC);
 
         // Initialize real objects.
         mTimeController = new TimeController(mJobSchedulerService);
-        mConstants = mTimeController.getTcConstants();
         spyOn(mTimeController);
     }
 
@@ -159,18 +157,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DelayInOrder_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
-
-        runTestMaybeStartTrackingJobLocked_DelayInOrder();
-    }
-
-    @Test
-    public void testMaybeStartTrackingJobLocked_DelayInOrder_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
-
+    public void testMaybeStartTrackingJobLocked_DelayInOrder_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestMaybeStartTrackingJobLocked_DelayInOrder();
@@ -201,9 +188,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DelayInOrder_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+    public void testMaybeStartTrackingJobLocked_DelayInOrder_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testMaybeStartTrackingJobLocked_DelayInOrder",
@@ -235,18 +220,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
-
-        runTestMaybeStartTrackingJobLocked_DelayReverseOrder();
-    }
-
-    @Test
-    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
-
+    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestMaybeStartTrackingJobLocked_DelayReverseOrder();
@@ -279,9 +253,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+    public void testMaybeStartTrackingJobLocked_DelayReverseOrder_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testMaybeStartTrackingJobLocked_DelayReverseOrder",
@@ -315,18 +287,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
-
-        runTestMaybeStartTrackingJobLocked_DeadlineInOrder();
-    }
-
-    @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
-
+    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestMaybeStartTrackingJobLocked_DeadlineInOrder();
@@ -357,9 +318,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+    public void testMaybeStartTrackingJobLocked_DeadlineInOrder_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testMaybeStartTrackingJobLocked_DeadlineInOrder",
@@ -391,18 +350,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
-
-        runTestMaybeStartTrackingJobLocked_DeadlineReverseOrder();
-    }
-
-    @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
-
+    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestMaybeStartTrackingJobLocked_DeadlineReverseOrder();
@@ -438,9 +386,7 @@
     }
 
     @Test
-    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+    public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus(
@@ -478,62 +424,7 @@
     }
 
     @Test
-    public void testJobSkipToggling() {
-        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-
-        JobStatus jobLatest = createJobStatus(
-                "testMaybeStartTrackingJobLocked_DeadlineReverseOrder",
-                createJob().setOverrideDeadline(HOUR_IN_MILLIS));
-        JobStatus jobEarliest = createJobStatus(
-                "testMaybeStartTrackingJobLocked_DeadlineReverseOrder",
-                createJob().setOverrideDeadline(5 * MINUTE_IN_MILLIS));
-
-        doReturn(true).when(mTimeController)
-                .wouldBeReadyWithConstraintLocked(eq(jobLatest), anyInt());
-        doReturn(false).when(mTimeController)
-                .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt());
-
-        // Starting off with the skipping off, we should still set an alarm for the earlier job.
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-        InOrder inOrder = inOrder(mAlarmManager);
-
-        mTimeController.maybeStartTrackingJobLocked(jobEarliest, null);
-        mTimeController.maybeStartTrackingJobLocked(jobLatest, null);
-        inOrder.verify(mAlarmManager, times(1))
-                .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(),
-                        eq(TAG_DEADLINE), any(), any(), any());
-
-        // Turn it on, use alarm for later job.
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
-
-        inOrder.verify(mAlarmManager, times(1))
-                .set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), anyLong(), eq(TAG_DEADLINE),
-                        any(), any(), any());
-
-        // Back off, use alarm for earlier job.
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-
-        inOrder.verify(mAlarmManager, times(1))
-                .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(),
-                        eq(TAG_DEADLINE), any(), any(), any());
-    }
-
-    @Test
-    public void testCheckExpiredDelaysAndResetAlarm_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-
-        runTestCheckExpiredDelaysAndResetAlarm();
-    }
-
-    @Test
-    public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
-
+    public void testCheckExpiredDelaysAndResetAlarm_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestCheckExpiredDelaysAndResetAlarm();
@@ -589,9 +480,7 @@
     }
 
     @Test
-    public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
+    public void testCheckExpiredDelaysAndResetAlarm_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testCheckExpiredDelaysAndResetAlarm",
@@ -639,18 +528,7 @@
     }
 
     @Test
-    public void testCheckExpiredDeadlinesAndResetAlarm_NoSkipping() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-
-        runTestCheckExpiredDeadlinesAndResetAlarm();
-    }
-
-    @Test
-    public void testCheckExpiredDeadlinesAndResetAlarm_WithSkipping_AllReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
-
+    public void testCheckExpiredDeadlinesAndResetAlarm_AllReady() {
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
         runTestCheckExpiredDeadlinesAndResetAlarm();
@@ -706,9 +584,7 @@
     }
 
     @Test
-    public void testCheckExpiredDeadlinesAndResetAlarm_WithSkipping_SomeNotReady() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
+    public void testCheckExpiredDeadlinesAndResetAlarm_SomeNotReady() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testCheckExpiredDeadlinesAndResetAlarm",
@@ -756,28 +632,14 @@
     }
 
     @Test
-    public void testEvaluateStateLocked_SkippingOff() {
-        mConstants.SKIP_NOT_READY_JOBS = false;
-        mTimeController.recheckAlarmsLocked();
-        JobStatus job = createJobStatus("testEvaluateStateLocked_SkippingOff",
-                createJob().setOverrideDeadline(HOUR_IN_MILLIS));
-
-        mTimeController.evaluateStateLocked(job);
-        verify(mAlarmManager, never())
-                .set(anyInt(), anyLong(), anyLong(), anyLong(), anyString(), any(), any(), any());
-    }
-
-    @Test
-    public void testEvaluateStateLocked_SkippingOn_Delay() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
+    public void testEvaluateStateLocked_Delay() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
-        JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_SkippingOn_Delay",
+        JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_Delay",
                 createJob().setMinimumLatency(HOUR_IN_MILLIS));
-        JobStatus jobMiddle = createJobStatus("testEvaluateStateLocked_SkippingOn_Delay",
+        JobStatus jobMiddle = createJobStatus("testEvaluateStateLocked_Delay",
                 createJob().setMinimumLatency(30 * MINUTE_IN_MILLIS));
-        JobStatus jobEarliest = createJobStatus("testEvaluateStateLocked_SkippingOn_Delay",
+        JobStatus jobEarliest = createJobStatus("testEvaluateStateLocked_Delay",
                 createJob().setMinimumLatency(5 * MINUTE_IN_MILLIS));
 
         doReturn(false).when(mTimeController)
@@ -827,16 +689,14 @@
     }
 
     @Test
-    public void testEvaluateStateLocked_SkippingOn_Deadline() {
-        mConstants.SKIP_NOT_READY_JOBS = true;
-        mTimeController.recheckAlarmsLocked();
+    public void testEvaluateStateLocked_Deadline() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
-        JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_SkippingOn_Deadline",
+        JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_Deadline",
                 createJob().setOverrideDeadline(HOUR_IN_MILLIS));
-        JobStatus jobMiddle = createJobStatus("testEvaluateStateLocked_SkippingOn_Deadline",
+        JobStatus jobMiddle = createJobStatus("testEvaluateStateLocked_Deadline",
                 createJob().setOverrideDeadline(30 * MINUTE_IN_MILLIS));
-        JobStatus jobEarliest = createJobStatus("testEvaluateStateLocked_SkippingOn_Deadline",
+        JobStatus jobEarliest = createJobStatus("testEvaluateStateLocked_Deadline",
                 createJob().setOverrideDeadline(5 * MINUTE_IN_MILLIS));
 
         doReturn(false).when(mTimeController)
diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/MultipleStaticMocksTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/MultipleStaticMocksTest.java
new file mode 100644
index 0000000..c0ab70a
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/testables/MultipleStaticMocksTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.testables;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MultipleStaticMocksTest {
+    @Rule
+    public StaticMockFixtureRule mStaticMockFixtureRule =
+            new StaticMockFixtureRule(AB::new, CD::new);
+
+    private List<String> mCollected;
+
+    @Test
+    public void testMultipleStaticMocks() throws Exception {
+        mCollected = new ArrayList<>();
+        int n = 0;
+
+        A.a();
+        n = verifyCollected(n, "A.a");
+
+        D.b();
+        n = verifyCollected(n, "D.b");
+
+        C.b();
+        n = verifyCollected(n, "C.b");
+
+        B.a();
+        n = verifyCollected(n, "B.a");
+    }
+
+    private int verifyCollected(int n, String... last) {
+        assertThat(mCollected).hasSize(n + last.length);
+        assertThat(mCollected.subList(n, mCollected.size()))
+                .containsExactlyElementsIn(last).inOrder();
+        return n + last.length;
+    }
+
+    private static class A {
+        /* package */ static void a() {}
+        /* package */ static void b() {}
+    }
+
+    private static class B {
+        /* package */ static void a() {}
+        /* package */ static void b() {}
+    }
+
+    private static class C {
+        /* package */ static void a() {}
+        /* package */ static void b() {}
+    }
+
+    private static class D {
+        /* package */ static void a() {}
+        /* package */ static void b() {}
+    }
+
+    /**
+     * AB StaticMockFixture class that handles two mocked classes, {@link A} and {@link B}.
+     */
+    private class AB implements StaticMockFixture {
+        @Override
+        public StaticMockitoSessionBuilder setUpMockedClasses(
+                StaticMockitoSessionBuilder sessionBuilder) {
+            sessionBuilder.spyStatic(A.class);
+            sessionBuilder.spyStatic(B.class);
+            return sessionBuilder;
+        }
+
+        @Override
+        public void setUpMockBehaviors() {
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("A.a");
+                return null;
+            }).when(A::a);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("A.b");
+                return null;
+            }).when(A::b);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("B.a");
+                return null;
+            }).when(B::a);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("B.b");
+                return null;
+            }).when(B::b);
+        }
+
+        @Override
+        public void tearDown() {
+
+        }
+    }
+
+    /**
+     * AB StaticMockFixture class that handles two mocked classes, {@link C} and {@link D}.
+     */
+    private class CD implements StaticMockFixture {
+        @Override
+        public StaticMockitoSessionBuilder setUpMockedClasses(
+                StaticMockitoSessionBuilder sessionBuilder) {
+            sessionBuilder.spyStatic(C.class);
+            sessionBuilder.spyStatic(D.class);
+            return sessionBuilder;
+        }
+
+        @Override
+        public void setUpMockBehaviors() {
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("C.a");
+                return null;
+            }).when(C::a);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("C.b");
+                return null;
+            }).when(C::b);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("D.a");
+                return null;
+            }).when(D::a);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("D.b");
+                return null;
+            }).when(D::b);
+        }
+
+        @Override
+        public void tearDown() {
+
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixture.java b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixture.java
new file mode 100644
index 0000000..0303fe1
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixture.java
@@ -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.
+ */
+
+package com.android.server.testables;
+
+
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+
+/**
+ * Provides support for a set of static mocks for use within a single shared
+ * {@link StaticMockitoSession}.
+ */
+public interface StaticMockFixture {
+    /**
+     * Adds any required mock or spy classes managed by this {@link StaticMockFixture} to the
+     * {@link StaticMockitoSessionBuilder} provided.
+     *
+     * Call this to set up the classes that this expects to be mocked, by adding them to the
+     * {@link StaticMockitoSessionBuilder} using
+     * {@link StaticMockitoSessionBuilder#mockStatic(Class)},
+     * {@link StaticMockitoSessionBuilder#spyStatic(Class)} or similar as appropriate.
+     *
+     * @param sessionBuilder the {@link StaticMockitoSessionBuilder} to which the classes should be
+     *                       added to mock, spy, or otherwise as required
+     * @return sessionBuilder, to allow for fluent programming
+     */
+    StaticMockitoSessionBuilder setUpMockedClasses(StaticMockitoSessionBuilder sessionBuilder);
+
+    /**
+     * Configures the behaviours of any mock or spy classes managed by this
+     * {@link StaticMockFixture}.
+     *
+     * Call this after {@link StaticMockitoSessionBuilder#startMocking()} has been called.
+     * This sets up any default behaviors for the mocks, spys, etc.
+     */
+    void setUpMockBehaviors();
+
+    /**
+     * Tear everything down.
+     */
+    void tearDown();
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRule.java b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRule.java
new file mode 100644
index 0000000..8e9d7ee
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRule.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.testables;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+
+import org.junit.rules.TestRule;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.mockito.quality.Strictness;
+
+import java.util.function.Supplier;
+
+/**
+ * <p>StaticMockFixtureRule is a {@link TestRule} that wraps one or more {@link StaticMockFixture}s
+ * to set them up and tear it down automatically. This works well when you have no other static
+ * mocks than the ones supported by their respective {@link StaticMockFixture}s.</p>
+ *
+ * <p>StaticMockFixtureRule should be defined as a rule on your test so it can clean up after
+ * itself. Like the following:</p>
+ * <pre class="prettyprint">
+*  public final StaticMockFixture mStaticMockFixtures = ...;
+ * &#064;Rule
+ * public final StaticMockFixtureRule mStaticMockFixtureRule =
+ *     new StaticMockFixtureRule(mStaticMockFixtures);
+ * </pre>
+ */
+public class StaticMockFixtureRule implements TestRule {
+    private StaticMockitoSession mMockitoSession;
+    private StaticMockFixture[] mStaticMockFixtures;
+    private Supplier<? extends StaticMockFixture>[] mSupplier;
+
+    /**
+     * Constructs a StaticMockFixtureRule that always uses the same {@link StaticMockFixture}
+     * instance(s).
+     *
+     * @param staticMockFixtures the {@link StaticMockFixture}(s) to use.
+     */
+    public StaticMockFixtureRule(StaticMockFixture... staticMockFixtures) {
+        mStaticMockFixtures = staticMockFixtures;
+        mSupplier = null;
+    }
+
+    /**
+     * Constructs a StaticMockFixtureRule that retrieves a new {@link StaticMockFixture} instance
+     * from one or more {@link Supplier<? extends   StaticMockFixture  >}s for each test invocation.
+     *
+     * @param supplier the {@link Supplier<? extends   StaticMockFixture  >}(s) that will supply the
+     * {@link StaticMockFixture}(s).
+     */
+    @SafeVarargs
+    public StaticMockFixtureRule(Supplier<? extends StaticMockFixture>... supplier) {
+        mStaticMockFixtures = null;
+        mSupplier = supplier;
+    }
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        StaticMockitoSessionBuilder sessionBuilder = getSessionBuilder();
+
+        if (mSupplier != null) {
+            mStaticMockFixtures = new StaticMockFixture[mSupplier.length];
+            for (int i = 0; i < mSupplier.length; i++) {
+                mStaticMockFixtures[i] = mSupplier[i].get();
+            }
+        }
+
+        for (int i = 0; i < mStaticMockFixtures.length; i++) {
+            sessionBuilder = mStaticMockFixtures[i].setUpMockedClasses(sessionBuilder);
+        }
+
+        mMockitoSession = sessionBuilder.startMocking();
+
+        for (int i = 0; i < mStaticMockFixtures.length; i++) {
+            mStaticMockFixtures[i].setUpMockBehaviors();
+        }
+
+        return new TestWatcher() {
+            @Override
+            protected void succeeded(Description description) {
+                tearDown(null);
+            }
+
+            @Override
+            protected void failed(Throwable e, Description description) {
+                tearDown(e);
+            }
+        }.apply(base, description);
+    }
+
+    /**
+     * This allows overriding the creation of the builder for a new {@link StaticMockitoSession}.
+     * Mainly for testing, but also useful if you have other requirements for the session.
+     *
+     * @return a new {@link StaticMockitoSessionBuilder}.
+     */
+    public StaticMockitoSessionBuilder getSessionBuilder() {
+        return mockitoSession().strictness(Strictness.LENIENT);
+    }
+
+    private void tearDown(Throwable e) {
+        mMockitoSession.finishMocking(e);
+
+        for (int i = mStaticMockFixtures.length - 1; i >= 0; i--) {
+            mStaticMockFixtures[i].tearDown();
+            if (mSupplier != null) {
+                mStaticMockFixtures[i] = null;
+            }
+        }
+
+        if (mSupplier != null) {
+            mStaticMockFixtures = null;
+        }
+
+        mMockitoSession = null;
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRuleTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRuleTest.java
new file mode 100644
index 0000000..b7e71de
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/testables/StaticMockFixtureRuleTest.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.testables;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.quality.Strictness.LENIENT;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runners.model.Statement;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoSession;
+
+import java.util.function.Supplier;
+
+/** Tests that StaticMockFixture manages fixtures and suppliers correctly. */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StaticMockFixtureRuleTest {
+    private MockitoSession mMockitoSession;
+
+    @Mock private StaticMockitoSessionBuilder mSessionBuilder;
+    @Mock private StaticMockitoSession mSession;
+    @Mock private StaticMockFixture mA1;
+    @Mock private StaticMockFixture mB1;
+    @Mock private StaticMockFixture mA2;
+    @Mock private StaticMockFixture mB2;
+    @Mock private Supplier<StaticMockFixture> mSupplyA;
+    @Mock private Supplier<StaticMockFixture> mSupplyB;
+    @Mock private Statement mStatement;
+    @Mock private Description mDescription;
+
+    @Before
+    public void setUp() throws Throwable {
+        mMockitoSession = Mockito.mockitoSession()
+                .strictness(LENIENT)
+                .initMocks(this)
+                .startMocking();
+        prepareMockBehaviours();
+    }
+
+    @After
+    public void tearDown() {
+        mMockitoSession.finishMocking();
+    }
+
+    private void prepareFixtureMocks(StaticMockFixture... mocks) {
+        for (StaticMockFixture mock : mocks) {
+            when(mock.setUpMockedClasses(any())).thenAnswer(
+                    invocation -> invocation.getArgument(0));
+            doNothing().when(mock).setUpMockBehaviors();
+        }
+    }
+
+    private void prepareMockBehaviours() throws Throwable {
+        when(mSessionBuilder.startMocking()).thenReturn(mSession);
+        when(mSupplyA.get()).thenReturn(mA1, mA2);
+        when(mSupplyB.get()).thenReturn(mB1, mB2);
+        prepareFixtureMocks(mA1, mA2, mB1, mB2);
+        when(mA1.setUpMockedClasses(any())).thenAnswer(invocation -> invocation.getArgument(0));
+        doNothing().when(mA1).setUpMockBehaviors();
+        when(mB1.setUpMockedClasses(any())).thenAnswer(invocation -> invocation.getArgument(0));
+        doNothing().when(mB1).setUpMockBehaviors();
+        doNothing().when(mStatement).evaluate();
+        doNothing().when(mA1).tearDown();
+        doNothing().when(mB1).tearDown();
+    }
+
+    private InOrder mocksInOrder()  {
+        return inOrder(mSessionBuilder, mSession, mSupplyA, mSupplyB,
+                mA1, mA2, mB1, mB2, mStatement, mDescription);
+    }
+
+    private void verifyNoMoreImportantMockInteractions()  {
+        verifyNoMoreInteractions(mSupplyA, mSupplyB, mA1, mA2, mB1, mB2, mStatement);
+    }
+
+    @Test
+    public void testRuleWorksWithExplicitFixtures() throws Throwable {
+        InOrder inOrder = mocksInOrder();
+
+        StaticMockFixtureRule rule = new StaticMockFixtureRule(mA1, mB1) {
+            @Override public StaticMockitoSessionBuilder getSessionBuilder() {
+                return mSessionBuilder;
+            }
+        };
+        Statement runMe = rule.apply(mStatement, mDescription);
+
+        inOrder.verify(mA1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class));
+        inOrder.verify(mB1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class));
+        inOrder.verify(mA1).setUpMockBehaviors();
+        inOrder.verify(mB1).setUpMockBehaviors();
+
+        runMe.evaluate();
+
+        inOrder.verify(mStatement).evaluate();
+        // note: tearDown in reverse order
+        inOrder.verify(mB1).tearDown();
+        inOrder.verify(mA1).tearDown();
+
+        // Round two: use the same fixtures again.
+        rule.apply(mStatement, mDescription).evaluate();
+
+        inOrder.verify(mA1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class));
+        inOrder.verify(mB1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class));
+        inOrder.verify(mA1).setUpMockBehaviors();
+        inOrder.verify(mB1).setUpMockBehaviors();
+        inOrder.verify(mStatement).evaluate();
+        // note: tearDown in reverse order
+        inOrder.verify(mB1).tearDown();
+        inOrder.verify(mA1).tearDown();
+
+        verifyNoMoreImportantMockInteractions();
+    }
+
+    @Test
+    public void testRuleWorksWithFixtureSuppliers() throws Throwable {
+        InOrder inOrder = mocksInOrder();
+
+        StaticMockFixtureRule rule = new StaticMockFixtureRule(mSupplyA, mSupplyB) {
+            @Override public StaticMockitoSessionBuilder getSessionBuilder() {
+                return mSessionBuilder;
+            }
+        };
+        Statement runMe = rule.apply(mStatement, mDescription);
+
+        inOrder.verify(mSupplyA).get();
+        inOrder.verify(mSupplyB).get();
+        inOrder.verify(mA1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class));
+        inOrder.verify(mB1).setUpMockedClasses(any(StaticMockitoSessionBuilder.class));
+        inOrder.verify(mA1).setUpMockBehaviors();
+        inOrder.verify(mB1).setUpMockBehaviors();
+
+        runMe.evaluate();
+
+        inOrder.verify(mStatement).evaluate();
+        // note: tearDown in reverse order
+        inOrder.verify(mB1).tearDown();
+        inOrder.verify(mA1).tearDown();
+
+        // Round two: use the same suppliers again to retrieve different fixtures: mA2 and mB2
+        rule.apply(mStatement, mDescription).evaluate();
+
+        inOrder.verify(mSupplyA).get();
+        inOrder.verify(mSupplyB).get();
+        inOrder.verify(mA2).setUpMockedClasses(any(StaticMockitoSessionBuilder.class));
+        inOrder.verify(mB2).setUpMockedClasses(any(StaticMockitoSessionBuilder.class));
+        inOrder.verify(mA2).setUpMockBehaviors();
+        inOrder.verify(mB2).setUpMockBehaviors();
+        inOrder.verify(mStatement).evaluate();
+        // note: tearDown in reverse order
+        inOrder.verify(mB2).tearDown();
+        inOrder.verify(mA2).tearDown();
+
+        verifyNoMoreImportantMockInteractions();
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java
index dae3d30..32631be 100644
--- a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java
+++ b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfig.java
@@ -17,7 +17,6 @@
 package com.android.server.testables;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -31,14 +30,10 @@
 import android.provider.DeviceConfig.Properties;
 import android.util.Pair;
 
-import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
 
 import org.junit.rules.TestRule;
-import org.junit.rules.TestWatcher;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
 import org.mockito.Mockito;
-import org.mockito.quality.Strictness;
 import org.mockito.stubbing.Answer;
 
 import java.util.Collections;
@@ -48,22 +43,12 @@
 import java.util.concurrent.Executor;
 
 /**
- * TestableDeviceConfig uses ExtendedMockito to replace the real implementation of DeviceConfig
- * with essentially a local HashMap in the callers process. This allows for unit testing that do not
- * modify the real DeviceConfig on the device at all.
- *
- * <p>TestableDeviceConfig should be defined as a rule on your test so it can clean up after itself.
- * Like the following:</p>
- * <pre class="prettyprint">
- * &#064;Rule
- * public final TestableDeviceConfig mTestableDeviceConfig = new TestableDeviceConfig();
- * </pre>
+ * TestableDeviceConfig is a {@link StaticMockFixture} that uses ExtendedMockito to replace the real
+ * implementation of DeviceConfig with essentially a local HashMap in the callers process. This
+ * allows for unit testing that do not modify the real DeviceConfig on the device at all.
  */
-public final class TestableDeviceConfig implements TestRule {
+public final class TestableDeviceConfig implements StaticMockFixture {
 
-    private StaticMockitoSession mMockitoSession;
-    private Map<DeviceConfig.OnPropertyChangedListener, Pair<String, Executor>>
-            mOnPropertyChangedListenerMap = new HashMap<>();
     private Map<DeviceConfig.OnPropertiesChangedListener, Pair<String, Executor>>
             mOnPropertiesChangedListenerMap = new HashMap<>();
     private Map<String, String> mKeyValueMap = new ConcurrentHashMap<>();
@@ -75,14 +60,21 @@
         mKeyValueMap.clear();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public Statement apply(Statement base, Description description) {
-        mMockitoSession = mockitoSession()
-                .initMocks(this)
-                .strictness(Strictness.LENIENT)
-                .spyStatic(DeviceConfig.class)
-                .startMocking();
+    public StaticMockitoSessionBuilder setUpMockedClasses(
+            StaticMockitoSessionBuilder sessionBuilder) {
+        sessionBuilder.spyStatic(DeviceConfig.class);
+        return sessionBuilder;
+    }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUpMockBehaviors() {
         doAnswer((Answer<Void>) invocationOnMock -> {
             String namespace = invocationOnMock.getArgument(0);
             Executor executor = invocationOnMock.getArgument(1);
@@ -95,18 +87,6 @@
                 anyString(), any(Executor.class),
                 any(DeviceConfig.OnPropertiesChangedListener.class)));
 
-        doAnswer((Answer<Void>) invocationOnMock -> {
-            String namespace = invocationOnMock.getArgument(0);
-            Executor executor = invocationOnMock.getArgument(1);
-            DeviceConfig.OnPropertyChangedListener onPropertyChangedListener =
-                    invocationOnMock.getArgument(2);
-            mOnPropertyChangedListenerMap.put(
-                    onPropertyChangedListener, new Pair<>(namespace, executor));
-            return null;
-        }).when(() -> DeviceConfig.addOnPropertyChangedListener(
-                anyString(), any(Executor.class),
-                any(DeviceConfig.OnPropertyChangedListener.class)));
-
         doAnswer((Answer<Boolean>) invocationOnMock -> {
                     String namespace = invocationOnMock.getArgument(0);
                     String name = invocationOnMock.getArgument(1);
@@ -120,13 +100,6 @@
                                             getProperties(namespace, name, value)));
                         }
                     }
-                    for (DeviceConfig.OnPropertyChangedListener listener :
-                            mOnPropertyChangedListenerMap.keySet()) {
-                        if (namespace.equals(mOnPropertyChangedListenerMap.get(listener).first)) {
-                            mOnPropertyChangedListenerMap.get(listener).second.execute(
-                                    () -> listener.onPropertyChanged(namespace, name, value));
-                        }
-                    }
                     return true;
                 }
         ).when(() -> DeviceConfig.setProperty(anyString(), anyString(), anyString(), anyBoolean()));
@@ -136,22 +109,15 @@
             String name = invocationOnMock.getArgument(1);
             return mKeyValueMap.get(getKey(namespace, name));
         }).when(() -> DeviceConfig.getProperty(anyString(), anyString()));
+    }
 
-        return new TestWatcher() {
-            @Override
-            protected void succeeded(Description description) {
-                mMockitoSession.finishMocking();
-                mOnPropertyChangedListenerMap.clear();
-                mOnPropertiesChangedListenerMap.clear();
-            }
-
-            @Override
-            protected void failed(Throwable e, Description description) {
-                mMockitoSession.finishMocking(e);
-                mOnPropertyChangedListenerMap.clear();
-                mOnPropertiesChangedListenerMap.clear();
-            }
-        }.apply(base, description);
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void tearDown() {
+        clearDeviceConfig();
+        mOnPropertiesChangedListenerMap.clear();
     }
 
     private static String getKey(String namespace, String name) {
@@ -233,4 +199,22 @@
         return properties;
     }
 
+    /**
+     * <p>TestableDeviceConfigRule is a {@link TestRule} that wraps a {@link TestableDeviceConfig}
+     * to set it up and tear it down automatically. This works well when you have no other static
+     * mocks.</p>
+     *
+     * <p>TestableDeviceConfigRule should be defined as a rule on your test so it can clean up after
+     * itself. Like the following:</p>
+     * <pre class="prettyprint">
+     * &#064;Rule
+     * public final TestableDeviceConfigRule mTestableDeviceConfigRule =
+     *     new TestableDeviceConfigRule();
+     * </pre>
+     */
+    public static class TestableDeviceConfigRule extends StaticMockFixtureRule {
+        public TestableDeviceConfigRule() {
+            super(TestableDeviceConfig::new);
+        }
+    }
 }
diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigAndOtherStaticMocksTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigAndOtherStaticMocksTest.java
new file mode 100644
index 0000000..9616d13
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigAndOtherStaticMocksTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.testables;
+
+import android.provider.DeviceConfig;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class TestableDeviceConfigAndOtherStaticMocksTest {
+    @Rule
+    public StaticMockFixtureRule mStaticMockFixtureRule =
+            new StaticMockFixtureRule(TestableDeviceConfig::new, AB::new, CD::new);
+
+    private List<String> mCollected;
+
+    @Test
+    public void testDeviceConfigAndOtherStaticMocks() throws Exception {
+        mCollected = new ArrayList<>();
+        int n = 0;
+
+        String namespace = "foo";
+        String flag = "bar";
+        String flagValue = "new value";
+
+        Assert.assertNull(DeviceConfig.getProperty(namespace, flag));
+
+        A.a();
+        verifyCollected(++n, "A.a");
+
+        DeviceConfig.setProperty(namespace, flag, flagValue, false);
+
+        D.b();
+        verifyCollected(++n, "D.b");
+
+        Assert.assertEquals(flagValue, DeviceConfig.getProperty(namespace, flag));
+
+        C.b();
+        verifyCollected(++n, "C.b");
+
+        B.a();
+        verifyCollected(++n, "B.a");
+    }
+
+    private void verifyCollected(int n, String last) {
+        Assert.assertEquals(n, mCollected.size());
+        Assert.assertEquals(last, mCollected.get(n - 1));
+    }
+
+    private static class A {
+        /* package */ static void a() {}
+        /* package */ static void b() {}
+    }
+
+    private static class B {
+        /* package */ static void a() {}
+        /* package */ static void b() {}
+    }
+
+    private static class C {
+        /* package */ static void a() {}
+        /* package */ static void b() {}
+    }
+
+    private static class D {
+        /* package */ static void a() {}
+        /* package */ static void b() {}
+    }
+
+    /**
+     * AB StaticMockFixture class that handles two mocked classes, {@link A} and {@link B}.
+     */
+    private class AB implements StaticMockFixture {
+        @Override
+        public StaticMockitoSessionBuilder setUpMockedClasses(
+                StaticMockitoSessionBuilder sessionBuilder) {
+            sessionBuilder.spyStatic(A.class);
+            sessionBuilder.spyStatic(B.class);
+            return sessionBuilder;
+        }
+
+        @Override
+        public void setUpMockBehaviors() {
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("A.a");
+                return null;
+            }).when(A::a);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("A.b");
+                return null;
+            }).when(A::b);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("B.a");
+                return null;
+            }).when(B::a);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("B.b");
+                return null;
+            }).when(B::b);
+        }
+
+        @Override
+        public void tearDown() {
+
+        }
+    }
+
+    /**
+     * AB StaticMockFixture class that handles two mocked classes, {@link C} and {@link D}.
+     */
+    private class CD implements StaticMockFixture {
+        @Override
+        public StaticMockitoSessionBuilder setUpMockedClasses(
+                StaticMockitoSessionBuilder sessionBuilder) {
+            sessionBuilder.spyStatic(C.class);
+            sessionBuilder.spyStatic(D.class);
+            return sessionBuilder;
+        }
+
+        @Override
+        public void setUpMockBehaviors() {
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("C.a");
+                return null;
+            }).when(C::a);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("C.b");
+                return null;
+            }).when(C::b);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("D.a");
+                return null;
+            }).when(D::a);
+            ExtendedMockito.doAnswer(invocation -> {
+                mCollected.add("D.b");
+                return null;
+            }).when(D::b);
+        }
+
+        @Override
+        public void tearDown() {
+
+        }
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java
index 3eb7209..d76c938 100644
--- a/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/testables/TestableDeviceConfigTest.java
@@ -45,7 +45,8 @@
     private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec
 
     @Rule
-    public TestableDeviceConfig mTestableDeviceConfig = new TestableDeviceConfig();
+    public TestableDeviceConfig.TestableDeviceConfigRule
+            mTestableDeviceConfig = new TestableDeviceConfig.TestableDeviceConfigRule();
 
     @Test
     public void getProperty_empty() {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index e9e96c9..1ad7b6e 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -72,6 +72,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.devicepolicy.MockUtils;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 
 import com.google.android.collect.Lists;
 
@@ -132,9 +133,10 @@
     @Mock private UnaryOperator<List<ScoredNetwork>> mScanResultsFilter;
     @Mock private WifiInfo mWifiInfo;
     @Mock private NetworkScoreService.ScoringServiceConnection mServiceConnection;
-    @Mock private PackageManagerInternal mPackageManagerInternal;
+    @Mock private PermissionManagerServiceInternal mPermissionManagerInternal;
     @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
-    @Captor private ArgumentCaptor<PackageManagerInternal.PackagesProvider> mPackagesProviderCaptor;
+    @Captor private
+    ArgumentCaptor<PermissionManagerServiceInternal.PackagesProvider> mPackagesProviderCaptor;
 
     private ContentResolver mContentResolver;
     private NetworkScoreService mNetworkScoreService;
@@ -162,7 +164,8 @@
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
         mHandlerThread = new HandlerThread("NetworkScoreServiceTest");
         mHandlerThread.start();
-        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternal);
+        LocalServices.addService(
+                PermissionManagerServiceInternal.class, mPermissionManagerInternal);
         mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager,
                 networkScorerAppData -> mServiceConnection, mHandlerThread.getLooper());
         WifiConfiguration configuration = new WifiConfiguration();
@@ -196,7 +199,7 @@
         Settings.Global.putString(mContentResolver,
                 Settings.Global.USE_OPEN_WIFI_PACKAGE, "com.some.app");
 
-        verify(mPackageManagerInternal)
+        verify(mPermissionManagerInternal)
                 .setUseOpenWifiAppPackagesProvider(mPackagesProviderCaptor.capture());
 
         String[] packages = mPackagesProviderCaptor.getValue().getPackages(0);
@@ -209,7 +212,7 @@
         Settings.Global.putString(mContentResolver,
                 Settings.Global.USE_OPEN_WIFI_PACKAGE, "com.some.other.app");
 
-        verify(mPackageManagerInternal, timeout(500))
+        verify(mPermissionManagerInternal, timeout(500))
                 .grantDefaultPermissionsToDefaultUseOpenWifiApp("com.some.other.app", 0);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
new file mode 100644
index 0000000..a4267b8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
@@ -0,0 +1,797 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibility;
+
+import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_HOME;
+import static android.accessibilityservice.AccessibilityServiceInfo.CAPABILITY_CAN_CONTROL_MAGNIFICATION;
+import static android.accessibilityservice.AccessibilityServiceInfo.CAPABILITY_CAN_PERFORM_GESTURES;
+import static android.accessibilityservice.AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
+import static android.accessibilityservice.AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION;
+import static android.accessibilityservice.AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT;
+import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
+import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_HAPTIC;
+import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_SPOKEN;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_REQUEST_FINGERPRINT_GESTURES;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
+import static android.view.View.FOCUS_DOWN;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_CLICKED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_LONG_CLICKED;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import static android.view.accessibility.AccessibilityNodeInfo.FOCUS_INPUT;
+import static android.view.accessibility.AccessibilityNodeInfo.ROOT_NODE_ID;
+
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+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.when;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.IAccessibilityServiceClient;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.graphics.Region;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IPowerManager;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.RemoteException;
+import android.testing.DexmakerShareClassLoaderRule;
+import android.view.KeyEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
+import android.view.accessibility.IAccessibilityInteractionConnection;
+import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+
+import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
+import com.android.server.wm.WindowManagerInternal;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * Tests for the AbstractAccessibilityServiceConnection
+ */
+public class AbstractAccessibilityServiceConnectionTest {
+    private static final ComponentName COMPONENT_NAME = new ComponentName(
+            "com.android.server.accessibility", ".AbstractAccessibilityServiceConnectionTest");
+    private static final String PACKAGE_NAME1 = "com.android.server.accessibility1";
+    private static final String PACKAGE_NAME2 = "com.android.server.accessibility2";
+    private static final String VIEWID_RESOURCE_NAME = "test_viewid_resource_name";
+    private static final String VIEW_TEXT = "test_view_text";
+    private static final int WINDOWID = 12;
+    private static final int PIP_WINDOWID = 13;
+    private static final int SERVICE_ID = 42;
+    private static final int A11Y_SERVICE_CAPABILITY = CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
+            | CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
+            | CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
+            | CAPABILITY_CAN_CONTROL_MAGNIFICATION
+            | CAPABILITY_CAN_PERFORM_GESTURES;
+    private static final int A11Y_SERVICE_FLAG = DEFAULT
+            | FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+            | FLAG_REPORT_VIEW_IDS
+            | FLAG_REQUEST_TOUCH_EXPLORATION_MODE
+            | FLAG_REQUEST_FILTER_KEY_EVENTS
+            | FLAG_REQUEST_FINGERPRINT_GESTURES
+            | FLAG_REQUEST_ACCESSIBILITY_BUTTON
+            | FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+    private static final int USER_ID = 1;
+    private static final int USER_ID2 = 2;
+    private static final int INTERACTION_ID = 199;
+    private static final int PID = Process.myPid();
+    private static final long TID = Process.myTid();
+    private static final int UID = Process.myUid();
+
+    private AbstractAccessibilityServiceConnection mServiceConnection;
+    private MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
+    private final List<AccessibilityWindowInfo> mA11yWindowInfos = new ArrayList<>();
+    private Callable[] mFindA11yNodesFunctions;
+    private Callable<Boolean> mPerformA11yAction;
+
+    // To mock package-private class.
+    @Rule public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+            new DexmakerShareClassLoaderRule();
+
+    @Mock private Context mMockContext;
+    @Mock private IPowerManager mMockIPowerManager;
+    @Mock private PackageManager mMockPackageManager;
+    @Spy  private AccessibilityServiceInfo mSpyServiceInfo = new AccessibilityServiceInfo();
+    @Mock private AccessibilitySecurityPolicy mMockSecurityPolicy;
+    @Mock private AccessibilityWindowManager mMockA11yWindowManager;
+    @Mock private AbstractAccessibilityServiceConnection.SystemSupport mMockSystemSupport;
+    @Mock private WindowManagerInternal mMockWindowManagerInternal;
+    @Mock private GlobalActionPerformer mMockGlobalActionPerformer;
+    @Mock private IBinder mMockService;
+    @Mock private IAccessibilityServiceClient mMockServiceInterface;
+    @Mock private KeyEventDispatcher mMockKeyEventDispatcher;
+    @Mock private IAccessibilityInteractionConnection mMockIA11yInteractionConnection;
+    @Mock private IAccessibilityInteractionConnectionCallback mMockCallback;
+    @Mock private FingerprintGestureDispatcher mMockFingerprintGestureDispatcher;
+    @Mock private MagnificationController mMockMagnificationController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID);
+        when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mMockKeyEventDispatcher);
+        when(mMockSystemSupport.getFingerprintGestureDispatcher())
+                .thenReturn(mMockFingerprintGestureDispatcher);
+        when(mMockSystemSupport.getMagnificationController())
+                .thenReturn(mMockMagnificationController);
+
+        PowerManager powerManager =
+                new PowerManager(mMockContext, mMockIPowerManager, mHandler);
+        when(mMockContext.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
+        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+        when(mMockPackageManager.hasSystemFeature(FEATURE_FINGERPRINT)).thenReturn(true);
+
+        // Fake a11yWindowInfo and remote a11y connection for tests.
+        addA11yWindowInfo(mA11yWindowInfos, WINDOWID, false);
+        addA11yWindowInfo(mA11yWindowInfos, PIP_WINDOWID, true);
+        when(mMockA11yWindowManager.getWindowListLocked()).thenReturn(mA11yWindowInfos);
+        when(mMockA11yWindowManager.findA11yWindowInfoById(WINDOWID))
+                .thenReturn(mA11yWindowInfos.get(0));
+        when(mMockA11yWindowManager.findA11yWindowInfoById(PIP_WINDOWID))
+                .thenReturn(mA11yWindowInfos.get(1));
+        final RemoteAccessibilityConnection conn = getRemoteA11yConnection(
+                WINDOWID, mMockIA11yInteractionConnection, PACKAGE_NAME1);
+        final RemoteAccessibilityConnection connPip = getRemoteA11yConnection(
+                PIP_WINDOWID, mMockIA11yInteractionConnection, PACKAGE_NAME2);
+        when(mMockA11yWindowManager.getConnectionLocked(USER_ID, WINDOWID)).thenReturn(conn);
+        when(mMockA11yWindowManager.getConnectionLocked(USER_ID, PIP_WINDOWID)).thenReturn(connPip);
+        when(mMockA11yWindowManager.getPictureInPictureActionReplacingConnection())
+                .thenReturn(connPip);
+
+        // Update a11yServiceInfo to full capability, full flags and target sdk jelly bean
+        final ResolveInfo mockResolveInfo = mock(ResolveInfo.class);
+        mockResolveInfo.serviceInfo = mock(ServiceInfo.class);
+        mockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
+        mockResolveInfo.serviceInfo.applicationInfo.targetSdkVersion =
+                Build.VERSION_CODES.JELLY_BEAN;
+        doReturn(mockResolveInfo).when(mSpyServiceInfo).getResolveInfo();
+        mSpyServiceInfo.setCapabilities(A11Y_SERVICE_CAPABILITY);
+        updateServiceInfo(mSpyServiceInfo, 0, 0, A11Y_SERVICE_FLAG, null, 0);
+
+        mServiceConnection = new TestAccessibilityServiceConnection(mMockContext, COMPONENT_NAME,
+                mSpyServiceInfo, SERVICE_ID, mHandler, new Object(), mMockSecurityPolicy,
+                mMockSystemSupport, mMockWindowManagerInternal, mMockGlobalActionPerformer,
+                mMockA11yWindowManager);
+        // Assume that the service is connected
+        mServiceConnection.mService = mMockService;
+        mServiceConnection.mServiceInterface = mMockServiceInterface;
+
+        // Update security policy for this service
+        when(mMockSecurityPolicy.checkAccessibilityAccess(mServiceConnection)).thenReturn(true);
+        when(mMockSecurityPolicy.canRetrieveWindowsLocked(mServiceConnection)).thenReturn(true);
+        when(mMockSecurityPolicy.canGetAccessibilityNodeInfoLocked(
+                eq(USER_ID), eq(mServiceConnection), anyInt())).thenReturn(true);
+        when(mMockSecurityPolicy.canControlMagnification(mServiceConnection)).thenReturn(true);
+
+        // init test functions for accessAccessibilityNodeInfo test case.
+        initTestFunctions();
+    }
+
+    @Test
+    public void getCapabilities() {
+        assertThat(mServiceConnection.getCapabilities(), is(A11Y_SERVICE_CAPABILITY));
+    }
+
+    @Test
+    public void onKeyEvent() throws RemoteException {
+        final int sequenceNumber = 100;
+        final KeyEvent mockKeyEvent = mock(KeyEvent.class);
+
+        mServiceConnection.onKeyEvent(mockKeyEvent, sequenceNumber);
+        verify(mMockServiceInterface).onKeyEvent(mockKeyEvent, sequenceNumber);
+    }
+
+    @Test
+    public void setServiceInfo_invokeOnClientChange() {
+        final AccessibilityServiceInfo serviceInfo = new AccessibilityServiceInfo();
+        updateServiceInfo(serviceInfo,
+                TYPE_VIEW_CLICKED | TYPE_VIEW_LONG_CLICKED,
+                FEEDBACK_SPOKEN | FEEDBACK_HAPTIC,
+                A11Y_SERVICE_FLAG,
+                new String[] {PACKAGE_NAME1, PACKAGE_NAME2},
+                1000);
+
+        mServiceConnection.setServiceInfo(serviceInfo);
+        verify(mMockSystemSupport).onClientChangeLocked(true);
+    }
+
+    @Test
+    public void canReceiveEvents_hasEventType_returnTrue() {
+        final AccessibilityServiceInfo serviceInfo = new AccessibilityServiceInfo();
+        updateServiceInfo(serviceInfo,
+                TYPE_VIEW_CLICKED | TYPE_VIEW_LONG_CLICKED, 0,
+                0, null, 0);
+
+        mServiceConnection.setServiceInfo(serviceInfo);
+        assertThat(mServiceConnection.canReceiveEventsLocked(), is(true));
+    }
+
+    @Test
+    public void setOnKeyEventResult() {
+        final int sequenceNumber = 100;
+        final boolean handled = true;
+        mServiceConnection.setOnKeyEventResult(handled, sequenceNumber);
+
+        verify(mMockKeyEventDispatcher).setOnKeyEventResult(
+                mServiceConnection, handled, sequenceNumber);
+    }
+
+    @Test
+    public void getWindows() {
+        assertThat(mServiceConnection.getWindows(), is(mA11yWindowInfos));
+    }
+
+    @Test
+    public void getWindows_returnNull() {
+        // no canRetrieveWindows, should return null
+        when(mMockSecurityPolicy.canRetrieveWindowsLocked(mServiceConnection)).thenReturn(false);
+        assertThat(mServiceConnection.getWindows(), is(nullValue()));
+
+        // no checkAccessibilityAccess, should return null
+        when(mMockSecurityPolicy.canRetrieveWindowsLocked(mServiceConnection)).thenReturn(true);
+        when(mMockSecurityPolicy.checkAccessibilityAccess(mServiceConnection)).thenReturn(false);
+        assertThat(mServiceConnection.getWindows(), is(nullValue()));
+    }
+
+    @Test
+    public void getWindows_notTrackingWindows_invokeOnClientChange() {
+        when(mMockA11yWindowManager.getWindowListLocked()).thenReturn(null);
+        when(mMockA11yWindowManager.isTrackingWindowsLocked()).thenReturn(false);
+
+        mServiceConnection.getWindows();
+        verify(mMockSystemSupport).onClientChangeLocked(false);
+    }
+
+    @Test
+    public void getWindow() {
+        assertThat(mServiceConnection.getWindow(WINDOWID), is(mA11yWindowInfos.get(0)));
+    }
+
+    @Test
+    public void getWindow_returnNull() {
+        // no canRetrieveWindows, should return null
+        when(mMockSecurityPolicy.canRetrieveWindowsLocked(mServiceConnection)).thenReturn(false);
+        assertThat(mServiceConnection.getWindow(WINDOWID), is(nullValue()));
+
+        // no checkAccessibilityAccess, should return null
+        when(mMockSecurityPolicy.canRetrieveWindowsLocked(mServiceConnection)).thenReturn(true);
+        when(mMockSecurityPolicy.checkAccessibilityAccess(mServiceConnection)).thenReturn(false);
+        assertThat(mServiceConnection.getWindow(WINDOWID), is(nullValue()));
+    }
+
+    @Test
+    public void getWindow_notTrackingWindows_invokeOnClientChange() {
+        when(mMockA11yWindowManager.getWindowListLocked()).thenReturn(null);
+        when(mMockA11yWindowManager.isTrackingWindowsLocked()).thenReturn(false);
+
+        mServiceConnection.getWindow(WINDOWID);
+        verify(mMockSystemSupport).onClientChangeLocked(false);
+    }
+
+    @Test
+    public void accessAccessibilityNodeInfo_whenCantGetInfo_returnNullOrFalse()
+            throws Exception {
+        when(mMockSecurityPolicy.canGetAccessibilityNodeInfoLocked(
+                USER_ID, mServiceConnection, WINDOWID)).thenReturn(false);
+        for (int i = 0; i < mFindA11yNodesFunctions.length; i++) {
+            assertThat(mFindA11yNodesFunctions[i].call(), is(nullValue()));
+        }
+        assertThat(mPerformA11yAction.call(), is(false));
+
+        verifyNoMoreInteractions(mMockIA11yInteractionConnection);
+        verify(mMockSecurityPolicy, never()).computeValidReportedPackages(any(), anyInt());
+    }
+
+    @Test
+    public void accessAccessibilityNodeInfo_whenNoA11yAccess_returnNullOrFalse()
+            throws Exception {
+        when(mMockSecurityPolicy.checkAccessibilityAccess(mServiceConnection)).thenReturn(false);
+        for (int i = 0; i < mFindA11yNodesFunctions.length; i++) {
+            assertThat(mFindA11yNodesFunctions[i].call(), is(nullValue()));
+        }
+        assertThat(mPerformA11yAction.call(), is(false));
+
+        verifyNoMoreInteractions(mMockIA11yInteractionConnection);
+        verify(mMockSecurityPolicy, never()).computeValidReportedPackages(any(), anyInt());
+    }
+
+    @Test
+    public void accessAccessibilityNodeInfo_whenNoRemoteA11yConnection_returnNullOrFalse()
+            throws Exception {
+        when(mMockA11yWindowManager.getConnectionLocked(USER_ID, WINDOWID)).thenReturn(null);
+        for (int i = 0; i < mFindA11yNodesFunctions.length; i++) {
+            assertThat(mFindA11yNodesFunctions[i].call(), is(nullValue()));
+        }
+        assertThat(mPerformA11yAction.call(), is(false));
+
+        verifyNoMoreInteractions(mMockIA11yInteractionConnection);
+        verify(mMockSecurityPolicy, never()).computeValidReportedPackages(any(), anyInt());
+    }
+
+    @Test
+    public void findAccessibilityNodeInfosByViewId_withPipWindow_shouldReplaceCallback()
+            throws RemoteException {
+        final ArgumentCaptor<IAccessibilityInteractionConnectionCallback> captor =
+                ArgumentCaptor.forClass(IAccessibilityInteractionConnectionCallback.class);
+        mServiceConnection.findAccessibilityNodeInfosByViewId(PIP_WINDOWID, ROOT_NODE_ID,
+                VIEWID_RESOURCE_NAME, INTERACTION_ID, mMockCallback, TID);
+        verify(mMockIA11yInteractionConnection).findAccessibilityNodeInfosByViewId(
+                eq(ROOT_NODE_ID), eq(VIEWID_RESOURCE_NAME), any(), eq(INTERACTION_ID),
+                captor.capture(), anyInt(), eq(PID), eq(TID), any());
+        verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
+        verifyReplaceActions(captor.getValue());
+    }
+
+    @Test
+    public void findAccessibilityNodeInfosByText_withPipWindow_shouldReplaceCallback()
+            throws RemoteException {
+        final ArgumentCaptor<IAccessibilityInteractionConnectionCallback> captor =
+                ArgumentCaptor.forClass(IAccessibilityInteractionConnectionCallback.class);
+        mServiceConnection.findAccessibilityNodeInfosByText(PIP_WINDOWID, ROOT_NODE_ID,
+                VIEW_TEXT, INTERACTION_ID, mMockCallback, TID);
+        verify(mMockIA11yInteractionConnection).findAccessibilityNodeInfosByText(
+                eq(ROOT_NODE_ID), eq(VIEW_TEXT), any(), eq(INTERACTION_ID),
+                captor.capture(), anyInt(), eq(PID), eq(TID), any());
+        verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
+        verifyReplaceActions(captor.getValue());
+    }
+
+    @Test
+    public void findAccessibilityNodeInfoByAccessibilityId_withPipWindow_shouldReplaceCallback()
+            throws RemoteException {
+        final ArgumentCaptor<IAccessibilityInteractionConnectionCallback> captor =
+                ArgumentCaptor.forClass(IAccessibilityInteractionConnectionCallback.class);
+        mServiceConnection.findAccessibilityNodeInfoByAccessibilityId(PIP_WINDOWID, ROOT_NODE_ID,
+                INTERACTION_ID, mMockCallback, 0, TID, null);
+        verify(mMockIA11yInteractionConnection).findAccessibilityNodeInfoByAccessibilityId(
+                eq(ROOT_NODE_ID), any(), eq(INTERACTION_ID), captor.capture(), anyInt(),
+                eq(PID), eq(TID), any(), any());
+        verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
+        verifyReplaceActions(captor.getValue());
+    }
+
+    @Test
+    public void findFocus_withPipWindow_shouldReplaceCallback()
+            throws RemoteException {
+        final ArgumentCaptor<IAccessibilityInteractionConnectionCallback> captor =
+                ArgumentCaptor.forClass(IAccessibilityInteractionConnectionCallback.class);
+        mServiceConnection.findFocus(PIP_WINDOWID, ROOT_NODE_ID, FOCUS_INPUT, INTERACTION_ID,
+                mMockCallback, TID);
+        verify(mMockIA11yInteractionConnection).findFocus(eq(ROOT_NODE_ID), eq(FOCUS_INPUT),
+                any(), eq(INTERACTION_ID), captor.capture(), anyInt(), eq(PID), eq(TID), any());
+        verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
+        verifyReplaceActions(captor.getValue());
+    }
+
+    @Test
+    public void focusSearch_withPipWindow_shouldReplaceCallback()
+            throws RemoteException {
+        final ArgumentCaptor<IAccessibilityInteractionConnectionCallback> captor =
+                ArgumentCaptor.forClass(IAccessibilityInteractionConnectionCallback.class);
+        mServiceConnection.focusSearch(PIP_WINDOWID, ROOT_NODE_ID, FOCUS_DOWN, INTERACTION_ID,
+                mMockCallback, TID);
+        verify(mMockIA11yInteractionConnection).focusSearch(eq(ROOT_NODE_ID), eq(FOCUS_DOWN),
+                any(), eq(INTERACTION_ID), captor.capture(), anyInt(), eq(PID), eq(TID), any());
+        verify(mMockSecurityPolicy).computeValidReportedPackages(any(), anyInt());
+        verifyReplaceActions(captor.getValue());
+    }
+
+    @Test
+    public void performAccessibilityAction_withPipWindow_invokeGetPipReplacingConnection()
+            throws RemoteException {
+        mServiceConnection.performAccessibilityAction(PIP_WINDOWID, ROOT_NODE_ID,
+                ACTION_ACCESSIBILITY_FOCUS, null, INTERACTION_ID, mMockCallback, TID);
+
+        verify(mMockIPowerManager).userActivity(anyLong(), anyInt(), anyInt());
+        verify(mMockIA11yInteractionConnection).performAccessibilityAction(eq(ROOT_NODE_ID),
+                eq(ACTION_ACCESSIBILITY_FOCUS), any(), eq(INTERACTION_ID), eq(mMockCallback),
+                anyInt(), eq(PID), eq(TID));
+        verify(mMockA11yWindowManager).getPictureInPictureActionReplacingConnection();
+    }
+
+    @Test
+    public void performAccessibilityAction_withClick_shouldNotifyOutsideTouch()
+            throws RemoteException {
+        mServiceConnection.performAccessibilityAction(WINDOWID, ROOT_NODE_ID,
+                ACTION_CLICK, null, INTERACTION_ID, mMockCallback, TID);
+        mServiceConnection.performAccessibilityAction(PIP_WINDOWID, ROOT_NODE_ID,
+                ACTION_LONG_CLICK, null, INTERACTION_ID, mMockCallback, TID);
+        verify(mMockA11yWindowManager).notifyOutsideTouch(eq(USER_ID), eq(WINDOWID));
+        verify(mMockA11yWindowManager).notifyOutsideTouch(eq(USER_ID), eq(PIP_WINDOWID));
+    }
+
+    @Test
+    public void performGlobalAction() {
+        mServiceConnection.performGlobalAction(GLOBAL_ACTION_HOME);
+        verify(mMockGlobalActionPerformer).performGlobalAction(GLOBAL_ACTION_HOME);
+    }
+
+    @Test
+    public void isFingerprintGestureDetectionAvailable_hasFingerPrintSupport_returnTrue() {
+        when(mMockFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable())
+                .thenReturn(true);
+        final boolean result = mServiceConnection.isFingerprintGestureDetectionAvailable();
+        assertThat(result, is(true));
+    }
+
+    @Test
+    public void isFingerprintGestureDetectionAvailable_noFingerPrintSupport_returnFalse() {
+        when(mMockFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable())
+                .thenReturn(true);
+
+        // Return false if device does not support fingerprint
+        when(mMockPackageManager.hasSystemFeature(FEATURE_FINGERPRINT)).thenReturn(false);
+        boolean result = mServiceConnection.isFingerprintGestureDetectionAvailable();
+        assertThat(result, is(false));
+
+        // Return false if service does not have flag
+        when(mMockPackageManager.hasSystemFeature(FEATURE_FINGERPRINT)).thenReturn(true);
+        mSpyServiceInfo.flags = A11Y_SERVICE_FLAG & ~FLAG_REQUEST_FINGERPRINT_GESTURES;
+        mServiceConnection.setServiceInfo(mSpyServiceInfo);
+        result = mServiceConnection.isFingerprintGestureDetectionAvailable();
+        assertThat(result, is(false));
+    }
+
+    @Test
+    public void getMagnificationScale() {
+        final int displayId = 1;
+        final float scale = 2.0f;
+        when(mMockMagnificationController.getScale(displayId)).thenReturn(scale);
+
+        final float result = mServiceConnection.getMagnificationScale(displayId);
+        assertThat(result, is(scale));
+    }
+
+    @Test
+    public void getMagnificationScale_serviceNotBelongCurrentUser_returnNoScale() {
+        final int displayId = 1;
+        final float scale = 2.0f;
+        when(mMockMagnificationController.getScale(displayId)).thenReturn(scale);
+        when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
+
+        final float result = mServiceConnection.getMagnificationScale(displayId);
+        assertThat(result, is(1.0f));
+    }
+
+    @Test
+    public void getMagnificationRegion_notRegistered_shouldRegisterThenUnregister() {
+        final int displayId = 1;
+        final Region region = new Region(10, 20, 100, 200);
+        doAnswer((invocation) -> {
+            ((Region) invocation.getArguments()[1]).set(region);
+            return null;
+        }).when(mMockMagnificationController).getMagnificationRegion(eq(displayId), any());
+        when(mMockMagnificationController.isRegistered(displayId)).thenReturn(false);
+
+        final Region result = mServiceConnection.getMagnificationRegion(displayId);
+        assertThat(result, is(region));
+        verify(mMockMagnificationController).register(displayId);
+        verify(mMockMagnificationController).unregister(displayId);
+    }
+
+    @Test
+    public void getMagnificationRegion_serviceNotBelongCurrentUser_returnEmptyRegion() {
+        final int displayId = 1;
+        final Region region = new Region(10, 20, 100, 200);
+        doAnswer((invocation) -> {
+            ((Region) invocation.getArguments()[1]).set(region);
+            return null;
+        }).when(mMockMagnificationController).getMagnificationRegion(eq(displayId), any());
+        when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
+
+        final Region result = mServiceConnection.getMagnificationRegion(displayId);
+        assertThat(result.isEmpty(), is(true));
+    }
+
+    @Test
+    public void getMagnificationCenterX_notRegistered_shouldRegisterThenUnregister() {
+        final int displayId = 1;
+        final float centerX = 480.0f;
+        when(mMockMagnificationController.getCenterX(displayId)).thenReturn(centerX);
+        when(mMockMagnificationController.isRegistered(displayId)).thenReturn(false);
+
+        final float result = mServiceConnection.getMagnificationCenterX(displayId);
+        assertThat(result, is(centerX));
+        verify(mMockMagnificationController).register(displayId);
+        verify(mMockMagnificationController).unregister(displayId);
+    }
+
+    @Test
+    public void getMagnificationCenterX_serviceNotBelongCurrentUser_returnZero() {
+        final int displayId = 1;
+        final float centerX = 480.0f;
+        when(mMockMagnificationController.getCenterX(displayId)).thenReturn(centerX);
+        when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
+
+        final float result = mServiceConnection.getMagnificationCenterX(displayId);
+        assertThat(result, is(0.0f));
+    }
+
+    @Test
+    public void getMagnificationCenterY_notRegistered_shouldRegisterThenUnregister() {
+        final int displayId = 1;
+        final float centerY = 640.0f;
+        when(mMockMagnificationController.getCenterY(displayId)).thenReturn(centerY);
+        when(mMockMagnificationController.isRegistered(displayId)).thenReturn(false);
+
+        final float result = mServiceConnection.getMagnificationCenterY(displayId);
+        assertThat(result, is(centerY));
+        verify(mMockMagnificationController).register(displayId);
+        verify(mMockMagnificationController).unregister(displayId);
+    }
+
+    @Test
+    public void getMagnificationCenterY_serviceNotBelongCurrentUser_returnZero() {
+        final int displayId = 1;
+        final float centerY = 640.0f;
+        when(mMockMagnificationController.getCenterY(displayId)).thenReturn(centerY);
+        when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
+
+        final float result = mServiceConnection.getMagnificationCenterY(displayId);
+        assertThat(result, is(0.0f));
+    }
+
+    @Test
+    public void resetMagnification() {
+        final int displayId = 1;
+        when(mMockMagnificationController.reset(displayId, true)).thenReturn(true);
+
+        final boolean result = mServiceConnection.resetMagnification(displayId, true);
+        assertThat(result, is(true));
+    }
+
+    @Test
+    public void resetMagnification_cantControlMagnification_returnFalse() {
+        final int displayId = 1;
+        when(mMockMagnificationController.reset(displayId, true)).thenReturn(true);
+        when(mMockSecurityPolicy.canControlMagnification(mServiceConnection)).thenReturn(false);
+
+        final boolean result = mServiceConnection.resetMagnification(displayId, true);
+        assertThat(result, is(false));
+    }
+
+    @Test
+    public void resetMagnification_serviceNotBelongCurrentUser_returnFalse() {
+        final int displayId = 1;
+        when(mMockMagnificationController.reset(displayId, true)).thenReturn(true);
+        when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
+
+        final boolean result = mServiceConnection.resetMagnification(displayId, true);
+        assertThat(result, is(false));
+    }
+
+    @Test
+    public void setMagnificationScaleAndCenter_notRegistered_shouldRegister() {
+        final int displayId = 1;
+        final float scale = 1.8f;
+        final float centerX = 50.5f;
+        final float centerY = 100.5f;
+        when(mMockMagnificationController.setScaleAndCenter(displayId,
+                scale, centerX, centerY, true, SERVICE_ID)).thenReturn(true);
+        when(mMockMagnificationController.isRegistered(displayId)).thenReturn(false);
+
+        final boolean result = mServiceConnection.setMagnificationScaleAndCenter(
+                displayId, scale, centerX, centerY, true);
+        assertThat(result, is(true));
+        verify(mMockMagnificationController).register(displayId);
+    }
+
+    @Test
+    public void setMagnificationScaleAndCenter_cantControlMagnification_returnFalse() {
+        final int displayId = 1;
+        final float scale = 1.8f;
+        final float centerX = 50.5f;
+        final float centerY = 100.5f;
+        when(mMockMagnificationController.setScaleAndCenter(displayId,
+                scale, centerX, centerY, true, SERVICE_ID)).thenReturn(true);
+        when(mMockSecurityPolicy.canControlMagnification(mServiceConnection)).thenReturn(false);
+
+        final boolean result = mServiceConnection.setMagnificationScaleAndCenter(
+                displayId, scale, centerX, centerY, true);
+        assertThat(result, is(false));
+    }
+
+    @Test
+    public void setMagnificationScaleAndCenter_serviceNotBelongCurrentUser_returnFalse() {
+        final int displayId = 1;
+        final float scale = 1.8f;
+        final float centerX = 50.5f;
+        final float centerY = 100.5f;
+        when(mMockMagnificationController.setScaleAndCenter(displayId,
+                scale, centerX, centerY, true, SERVICE_ID)).thenReturn(true);
+        when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
+
+        final boolean result = mServiceConnection.setMagnificationScaleAndCenter(
+                displayId, scale, centerX, centerY, true);
+        assertThat(result, is(false));
+    }
+
+    private void updateServiceInfo(AccessibilityServiceInfo serviceInfo, int eventType,
+            int feedbackType, int flags, String[] packageNames, int notificationTimeout) {
+        serviceInfo.eventTypes = eventType;
+        serviceInfo.feedbackType = feedbackType;
+        serviceInfo.flags = flags;
+        serviceInfo.packageNames = packageNames;
+        serviceInfo.notificationTimeout = notificationTimeout;
+    }
+
+    private AccessibilityWindowInfo addA11yWindowInfo(List<AccessibilityWindowInfo> infos,
+            int windowId, boolean isPip) {
+        final AccessibilityWindowInfo info = AccessibilityWindowInfo.obtain();
+        info.setId(windowId);
+        info.setPictureInPicture(isPip);
+        infos.add(info);
+        return info;
+    }
+
+    private RemoteAccessibilityConnection getRemoteA11yConnection(int windowId,
+            IAccessibilityInteractionConnection connection,
+            String packageName) {
+        return mMockA11yWindowManager.new RemoteAccessibilityConnection(
+                windowId, connection, packageName, UID, USER_ID);
+    }
+
+    private void initTestFunctions() {
+        // Init functions for accessibility nodes finding and searching by different filter rules.
+        // We group them together for the tests because they have similar implementation.
+        mFindA11yNodesFunctions = new Callable[] {
+                // findAccessibilityNodeInfosByViewId
+                () -> mServiceConnection.findAccessibilityNodeInfosByViewId(WINDOWID,
+                        ROOT_NODE_ID, VIEWID_RESOURCE_NAME, INTERACTION_ID,
+                        mMockCallback, TID),
+                // findAccessibilityNodeInfosByText
+                () -> mServiceConnection.findAccessibilityNodeInfosByText(WINDOWID,
+                        ROOT_NODE_ID, VIEW_TEXT, INTERACTION_ID, mMockCallback, TID),
+                // findAccessibilityNodeInfoByAccessibilityId
+                () -> mServiceConnection.findAccessibilityNodeInfoByAccessibilityId(WINDOWID,
+                        ROOT_NODE_ID, INTERACTION_ID, mMockCallback, 0, TID, null),
+                // findFocus
+                () -> mServiceConnection.findFocus(WINDOWID, ROOT_NODE_ID, FOCUS_INPUT,
+                        INTERACTION_ID, mMockCallback, TID),
+                // focusSearch
+                () -> mServiceConnection.focusSearch(WINDOWID, ROOT_NODE_ID, FOCUS_DOWN,
+                        INTERACTION_ID, mMockCallback, TID)
+        };
+        // performAccessibilityAction
+        mPerformA11yAction = () ->  mServiceConnection.performAccessibilityAction(WINDOWID,
+                ROOT_NODE_ID, ACTION_ACCESSIBILITY_FOCUS, null, INTERACTION_ID,
+                mMockCallback, TID);
+    }
+
+    private void verifyReplaceActions(IAccessibilityInteractionConnectionCallback replacedCallback)
+            throws RemoteException {
+        final AccessibilityNodeInfo nodeFromApp = AccessibilityNodeInfo.obtain();
+        nodeFromApp.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID, WINDOWID);
+
+        final AccessibilityNodeInfo nodeFromReplacer = AccessibilityNodeInfo.obtain();
+        nodeFromReplacer.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID,
+                AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
+        nodeFromReplacer.addAction(AccessibilityAction.ACTION_CLICK);
+        nodeFromReplacer.addAction(AccessibilityAction.ACTION_EXPAND);
+        final List<AccessibilityNodeInfo> replacerList = Arrays.asList(nodeFromReplacer);
+
+        replacedCallback.setFindAccessibilityNodeInfoResult(nodeFromApp, INTERACTION_ID);
+        replacedCallback.setFindAccessibilityNodeInfosResult(replacerList, INTERACTION_ID + 1);
+
+        final ArgumentCaptor<AccessibilityNodeInfo> captor =
+                ArgumentCaptor.forClass(AccessibilityNodeInfo.class);
+        verify(mMockCallback).setFindAccessibilityNodeInfoResult(captor.capture(),
+                eq(INTERACTION_ID));
+        assertThat(captor.getValue().getActionList(),
+                hasItems(AccessibilityAction.ACTION_CLICK, AccessibilityAction.ACTION_EXPAND));
+    }
+
+    private static class TestAccessibilityServiceConnection
+            extends AbstractAccessibilityServiceConnection {
+        int mResolvedUserId;
+
+        TestAccessibilityServiceConnection(Context context, ComponentName componentName,
+                AccessibilityServiceInfo accessibilityServiceInfo, int id, Handler mainHandler,
+                Object lock, AccessibilitySecurityPolicy securityPolicy,
+                SystemSupport systemSupport, WindowManagerInternal windowManagerInternal,
+                GlobalActionPerformer globalActionPerfomer,
+                AccessibilityWindowManager a11yWindowManager) {
+            super(context, componentName, accessibilityServiceInfo, id, mainHandler, lock,
+                    securityPolicy, systemSupport, windowManagerInternal, globalActionPerfomer,
+                    a11yWindowManager);
+            mResolvedUserId = USER_ID;
+        }
+
+        @Override
+        protected boolean isCalledForCurrentUserLocked() {
+            return mResolvedUserId == mSystemSupport.getCurrentUserIdLocked();
+        }
+
+        @Override
+        public void disableSelf() throws RemoteException {}
+
+        @Override
+        public boolean setSoftKeyboardShowMode(int showMode) throws RemoteException {
+            return false;
+        }
+
+        @Override
+        public int getSoftKeyboardShowMode() throws RemoteException {
+            return 0;
+        }
+
+        @Override
+        public boolean isAccessibilityButtonAvailable() throws RemoteException {
+            return false;
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {}
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {}
+
+        @Override
+        public void binderDied() {}
+
+        @Override
+        public boolean isCapturingFingerprintGestures() {
+            return mCaptureFingerprintGestures;
+        }
+
+        @Override
+        public void onFingerprintGestureDetectionActiveChanged(boolean active) {}
+
+        @Override
+        public void onFingerprintGesture(int gesture) {}
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 04ca40e..7e64caf 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -33,6 +33,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -42,6 +43,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.IWindow;
 import android.view.WindowInfo;
 import android.view.accessibility.AccessibilityEvent;
@@ -70,6 +72,8 @@
  */
 public class AccessibilityWindowManagerTest {
     private static final String PACKAGE_NAME = "com.android.server.accessibility";
+    private static final boolean FORCE_SEND = true;
+    private static final boolean SEND_ON_WINDOW_CHANGES = false;
     private static final int USER_SYSTEM_ID = UserHandle.USER_SYSTEM;
     private static final int NUM_GLOBAL_WINDOWS = 4;
     private static final int NUM_APP_WINDOWS = 4;
@@ -122,7 +126,7 @@
         mWindowInfos.get(DEFAULT_FOCUSED_INDEX).focused = true;
         // Turn on windows tracking, and update window info
         mA11yWindowManager.startTrackingWindows();
-        mA11yWindowManager.onWindowsForAccessibilityChanged(mWindowInfos);
+        mA11yWindowManager.onWindowsForAccessibilityChanged(FORCE_SEND, mWindowInfos);
         assertEquals(mA11yWindowManager.getWindowListLocked().size(),
                 mWindowInfos.size());
 
@@ -140,7 +144,9 @@
     public void startTrackingWindows_shouldEnableWindowManagerCallback() {
         // AccessibilityWindowManager#startTrackingWindows already invoked in setup
         assertTrue(mA11yWindowManager.isTrackingWindowsLocked());
-        verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(any());
+        // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
+        verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(
+                eq(Display.DEFAULT_DISPLAY), any());
     }
 
     @Test
@@ -150,7 +156,9 @@
 
         mA11yWindowManager.stopTrackingWindows();
         assertFalse(mA11yWindowManager.isTrackingWindowsLocked());
-        verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(any());
+        // TODO [Multi-Display] : using correct display Id to replace DEFAULT_DISPLAY
+        verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(
+                eq(Display.DEFAULT_DISPLAY), any());
     }
 
     @Test
@@ -169,16 +177,16 @@
     @Test
     public void onWindowsChanged_duringTouchInteractAndFocusChange_shouldChangeActiveWindow() {
         final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-        WindowInfo focuedWindowInfo = mWindowInfos.get(DEFAULT_FOCUSED_INDEX);
+        WindowInfo focusedWindowInfo = mWindowInfos.get(DEFAULT_FOCUSED_INDEX);
         assertEquals(activeWindowId, mA11yWindowManager.findWindowIdLocked(
-                USER_SYSTEM_ID, focuedWindowInfo.token));
+                USER_SYSTEM_ID, focusedWindowInfo.token));
 
-        focuedWindowInfo.focused = false;
-        focuedWindowInfo = mWindowInfos.get(DEFAULT_FOCUSED_INDEX + 1);
-        focuedWindowInfo.focused = true;
+        focusedWindowInfo.focused = false;
+        focusedWindowInfo = mWindowInfos.get(DEFAULT_FOCUSED_INDEX + 1);
+        focusedWindowInfo.focused = true;
 
         mA11yWindowManager.onTouchInteractionStart();
-        mA11yWindowManager.onWindowsForAccessibilityChanged(mWindowInfos);
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
         assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
     }
 
@@ -208,6 +216,52 @@
     }
 
     @Test
+    public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
+        final WindowInfo windowInfo = mWindowInfos.get(0);
+        final int correctLayer = mA11yWindowManager.getWindowListLocked().get(0).getLayer();
+        windowInfo.layer += 1;
+
+        mA11yWindowManager.onWindowsForAccessibilityChanged(FORCE_SEND, mWindowInfos);
+        assertNotEquals(correctLayer, mA11yWindowManager.getWindowListLocked().get(0).getLayer());
+    }
+
+    @Test
+    public void onWindowsChangedNoForceSend_layerChanged_shouldNotUpdateWindows() {
+        final WindowInfo windowInfo = mWindowInfos.get(0);
+        final int correctLayer = mA11yWindowManager.getWindowListLocked().get(0).getLayer();
+        windowInfo.layer += 1;
+
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
+        assertEquals(correctLayer, mA11yWindowManager.getWindowListLocked().get(0).getLayer());
+    }
+
+    @Test
+    public void onWindowsChangedNoForceSend_windowChanged_shouldUpdateWindows()
+            throws RemoteException {
+        final AccessibilityWindowInfo oldWindow = mA11yWindowManager.getWindowListLocked().get(0);
+        final IWindow token = addAccessibilityInteractionConnection(true);
+        final WindowInfo windowInfo = WindowInfo.obtain();
+        windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
+        windowInfo.token = token.asBinder();
+        windowInfo.layer = 0;
+        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+        mWindowInfos.set(0, windowInfo);
+
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
+        assertNotEquals(oldWindow, mA11yWindowManager.getWindowListLocked().get(0));
+    }
+
+    @Test
+    public void onWindowsChangedNoForceSend_focusChanged_shouldUpdateWindows() {
+        final WindowInfo focusedWindowInfo = mWindowInfos.get(DEFAULT_FOCUSED_INDEX);
+        final WindowInfo windowInfo = mWindowInfos.get(0);
+        focusedWindowInfo.focused = false;
+        windowInfo.focused = true;
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
+        assertTrue(mA11yWindowManager.getWindowListLocked().get(0).isFocused());
+    }
+
+    @Test
     public void removeAccessibilityInteractionConnection_byWindowToken_shouldRemoved() {
         for (int i = 0; i < NUM_OF_WINDOWS; i++) {
             final int windowId = mA11yWindowTokens.keyAt(i);
@@ -257,67 +311,73 @@
     }
 
     @Test
-    public void computePartialInteractiveRegionForWindow_wholeWindowVisible_returnWholeRegion() {
+    public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
         // Updates top 2 z-order WindowInfo are whole visible.
         WindowInfo windowInfo = mWindowInfos.get(0);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
+        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
         windowInfo = mWindowInfos.get(1);
-        windowInfo.boundsInScreen.set(0, SCREEN_HEIGHT / 2,
-                SCREEN_WIDTH, SCREEN_HEIGHT);
-        mA11yWindowManager.onWindowsForAccessibilityChanged(mWindowInfos);
+        windowInfo.regionInScreen.set(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT);
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
 
         final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(0).getId();
 
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
-                windowId, outBounds);
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
         assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
         assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
 
         windowId = a11yWindows.get(1).getId();
 
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
-                windowId, outBounds);
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
         assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
         assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
     }
 
     @Test
-    public void computePartialInteractiveRegionForWindow_halfWindowVisible_returnHalfRegion() {
+    public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
         // Updates z-order #1 WindowInfo is half visible
         WindowInfo windowInfo = mWindowInfos.get(0);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
-        windowInfo = mWindowInfos.get(1);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
 
-        mA11yWindowManager.onWindowsForAccessibilityChanged(mWindowInfos);
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
         final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(1).getId();
 
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
-                windowId, outBounds);
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
         assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
         assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
     }
 
     @Test
-    public void computePartialInteractiveRegionForWindow_windowNotVisible_returnEmptyRegion() {
-        // Updates z-order #1 WindowInfo is not visible
+    public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
+        // Since z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+        final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
+        final Region outBounds = new Region();
+        int windowId = a11yWindows.get(1).getId();
+
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
+        assertTrue(outBounds.getBounds().isEmpty());
+    }
+
+    @Test
+    public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
+        // Updates z-order #0 WindowInfo to have two interact-able areas.
+        Region region = new Region(0, 0, SCREEN_WIDTH, 200);
+        region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
         WindowInfo windowInfo = mWindowInfos.get(0);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-        windowInfo = mWindowInfos.get(1);
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-        mA11yWindowManager.onWindowsForAccessibilityChanged(mWindowInfos);
+        windowInfo.regionInScreen.set(region);
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
 
         final List<AccessibilityWindowInfo> a11yWindows = mA11yWindowManager.getWindowListLocked();
         final Region outBounds = new Region();
         int windowId = a11yWindows.get(1).getId();
 
-        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(
-                windowId, outBounds);
-        assertTrue(outBounds.getBounds().isEmpty());
+        mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
+        assertFalse(outBounds.getBounds().isEmpty());
+        assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
+        assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT - 400));
     }
 
     @Test
@@ -498,7 +558,7 @@
     public void getPictureInPictureWindow_shouldNotNull() {
         assertNull(mA11yWindowManager.getPictureInPictureWindow());
         mWindowInfos.get(1).inPictureInPicture = true;
-        mA11yWindowManager.onWindowsForAccessibilityChanged(mWindowInfos);
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
 
         assertNotNull(mA11yWindowManager.getPictureInPictureWindow());
     }
@@ -511,7 +571,7 @@
                 mA11yWindowManager.getConnectionLocked(
                         USER_SYSTEM_ID, outsideWindowId).getRemote();
         mWindowInfos.get(0).hasFlagWatchOutsideTouch = true;
-        mA11yWindowManager.onWindowsForAccessibilityChanged(mWindowInfos);
+        mA11yWindowManager.onWindowsForAccessibilityChanged(SEND_ON_WINDOW_CHANGES, mWindowInfos);
 
         mA11yWindowManager.notifyOutsideTouch(USER_SYSTEM_ID, targetWindowId);
         verify(mockRemoteConnection).notifyOutsideTouch();
@@ -540,7 +600,7 @@
         windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
         windowInfo.token = windowToken.asBinder();
         windowInfo.layer = layer;
-        windowInfo.boundsInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
+        windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
         mWindowInfos.add(windowInfo);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
index d854582..210de53 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.accessibility;
 
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -31,6 +33,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.hardware.display.DisplayManager;
 import android.os.IBinder;
 import android.view.accessibility.AccessibilityEvent;
 
@@ -78,6 +81,11 @@
 
         when(mMockAccessibilityServiceClient.asBinder()).thenReturn(mMockServiceAsBinder);
 
+        final Context context = getInstrumentation().getTargetContext();
+        when(mMockContext.getSystemService(Context.DISPLAY_SERVICE)).thenReturn(
+                context.getSystemService(
+                        DisplayManager.class));
+
         mMessageCapturingHandler = new MessageCapturingHandler(null);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 7a96f4c..0f11566 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -1065,7 +1065,7 @@
 
         waitForLatch(latch);
         // Verify notification is cancelled
-        verify(mMockNotificationManager).cancelNotificationWithTag(
+        verify(mMockNotificationManager).cancelNotificationWithTag(anyString(),
                 anyString(), nullable(String.class), anyInt(), anyInt());
 
         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
@@ -1943,7 +1943,7 @@
                 UserHandle.USER_SYSTEM);
         waitForLatch(latch);
         // Verify notification is cancelled
-        verify(mMockNotificationManager).cancelNotificationWithTag(
+        verify(mMockNotificationManager).cancelNotificationWithTag(anyString(),
                 anyString(), nullable(String.class), anyInt(), anyInt());
 
         verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
diff --git a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
index 174571d..6678a78 100644
--- a/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/MemoryStatUtilTest.java
@@ -23,13 +23,18 @@
 import static com.android.server.am.MemoryStatUtil.parseIonHeapSizeFromDebugfs;
 import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromMemcg;
 import static com.android.server.am.MemoryStatUtil.parseMemoryStatFromProcfs;
+import static com.android.server.am.MemoryStatUtil.parseProcessIonHeapSizesFromDebugfs;
 import static com.android.server.am.MemoryStatUtil.parseVmHWMFromProcfs;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.server.am.MemoryStatUtil.IonAllocations;
+
 import org.junit.Test;
 
 import java.io.ByteArrayOutputStream;
@@ -178,32 +183,70 @@
             + "voluntary_ctxt_switches:\t903\n"
             + "nonvoluntary_ctxt_switches:\t104\n";
 
+    // Repeated lines have been removed.
     private static final String DEBUG_SYSTEM_ION_HEAP_CONTENTS = String.join(
-            "          client              pid             size\n",
-            "----------------------------------------------------\n",
-            " audio@2.0-servi              765             4096\n",
-            " audio@2.0-servi              765            61440\n",
-            " audio@2.0-servi              765             4096\n",
-            "     voip_client               96             8192\n",
-            "     voip_client               96             4096\n",
-            "   system_server             1232         16728064\n",
-            "  surfaceflinger              611         50642944\n",
-            "----------------------------------------------------\n",
-            "orphaned allocations (info is from last known client):\n",
-            "----------------------------------------------------\n",
-            "  total orphaned                0\n",
-            "          total          55193600\n",
-            "   deferred free                0\n",
-            "----------------------------------------------------\n",
-            "0 order 4 highmem pages in uncached pool = 0 total\n",
-            "0 order 4 lowmem pages in uncached pool = 0 total\n",
-            "1251 order 4 lowmem pages in cached pool = 81985536 total\n",
-            "VMID 8: 0 order 4 highmem pages in secure pool = 0 total\n",
-            "VMID  8: 0 order 4 lowmem pages in secure pool = 0 total\n",
-            "--------------------------------------------\n",
-            "uncached pool = 4096 cached pool = 83566592 secure pool = 0\n",
-            "pool total (uncached + cached + secure) = 83570688\n",
-            "--------------------------------------------\n");
+            "\n",
+            "          client              pid             size",
+            "----------------------------------------------------",
+            " audio@2.0-servi              765             4096",
+            " audio@2.0-servi              765            61440",
+            " audio@2.0-servi              765             4096",
+            "     voip_client               96             8192",
+            "     voip_client               96             4096",
+            "   system_server             1232         16728064",
+            "  surfaceflinger              611         50642944",
+            "----------------------------------------------------",
+            "orphaned allocations (info is from last known client):",
+            "----------------------------------------------------",
+            "  total orphaned                0",
+            "          total          55193600",
+            "   deferred free                0",
+            "----------------------------------------------------",
+            "0 order 4 highmem pages in uncached pool = 0 total",
+            "0 order 4 lowmem pages in uncached pool = 0 total",
+            "1251 order 4 lowmem pages in cached pool = 81985536 total",
+            "VMID 8: 0 order 4 highmem pages in secure pool = 0 total",
+            "VMID  8: 0 order 4 lowmem pages in secure pool = 0 total",
+            "--------------------------------------------",
+            "uncached pool = 4096 cached pool = 83566592 secure pool = 0",
+            "pool total (uncached + cached + secure) = 83570688",
+            "--------------------------------------------");
+
+    // Repeated lines have been removed.
+    private static final String DEBUG_SYSTEM_ION_HEAP_CONTENTS_SARGO = String.join(
+            "\n",
+            "          client              pid             size      page counts"
+                    + "--------------------------------------------------       4K       8K      "
+                    + "16K      32K      64K     128K     256K     512K       1M       2M       "
+                    + "4M      >=8M",
+            "   system_server             1705         58097664    13120      532        "
+                    + "0        0        0        0        0        0        0        0        "
+                    + "0        0M",
+            " audio@2.0-servi              851            16384        0        2        0        "
+                    + "0        0        0        0        0        0        0        "
+                    + "0        0M",
+            " audio@2.0-servi              851             4096        1        0        0       "
+                    + " 0        0        0        0        0        0        0        0        "
+                    + "0M",
+            " audio@2.0-servi              851             4096        1        0      "
+                    + "  0        0        0        0        0        0        0        0        "
+                    + "0        0M",
+            "----------------------------------------------------",
+            "orphaned allocations (info is from last known client):",
+            "----------------------------------------------------",
+            "  total orphaned                0",
+            "          total         159928320",
+            "   deferred free                0",
+            "----------------------------------------------------",
+            "0 order 4 highmem pages in uncached pool = 0 total",
+            "0 order 4 lowmem pages in uncached pool = 0 total",
+            "1251 order 4 lowmem pages in cached pool = 81985536 total",
+            "VMID 8: 0 order 4 highmem pages in secure pool = 0 total",
+            "VMID  8: 0 order 4 lowmem pages in secure pool = 0 total",
+            "--------------------------------------------",
+            "uncached pool = 4096 cached pool = 83566592 secure pool = 0",
+            "pool total (uncached + cached + secure) = 83570688",
+            "--------------------------------------------");
 
     @Test
     public void testParseMemoryStatFromMemcg_parsesCorrectValues() {
@@ -233,6 +276,7 @@
         assertEquals(0, stat.cacheInBytes);
         assertEquals(22 * BYTES_IN_KILOBYTE, stat.swapInBytes);
         assertEquals(2222 * JIFFY_NANOS, stat.startTimeNanos);
+        assertEquals(37860 * BYTES_IN_KILOBYTE, stat.anonRssInBytes);
     }
 
     @Test
@@ -322,5 +366,47 @@
     @Test
     public void testParseIonHeapSizeFromDebugfs_correctValue() {
         assertEquals(55193600, parseIonHeapSizeFromDebugfs(DEBUG_SYSTEM_ION_HEAP_CONTENTS));
+
+        assertEquals(159928320, parseIonHeapSizeFromDebugfs(DEBUG_SYSTEM_ION_HEAP_CONTENTS_SARGO));
+    }
+
+    @Test
+    public void testParseProcessIonHeapSizesFromDebugfs_emptyContents() {
+        assertEquals(0, parseProcessIonHeapSizesFromDebugfs("").size());
+
+        assertEquals(0, parseProcessIonHeapSizesFromDebugfs(null).size());
+    }
+
+    @Test
+    public void testParseProcessIonHeapSizesFromDebugfs_invalidValue() {
+        assertEquals(0, parseProcessIonHeapSizesFromDebugfs("<<no-value>>").size());
+    }
+
+    @Test
+    public void testParseProcessIonHeapSizesFromDebugfs_correctValue1() {
+        assertThat(parseProcessIonHeapSizesFromDebugfs(DEBUG_SYSTEM_ION_HEAP_CONTENTS))
+                .containsExactly(
+                        createIonAllocations(765, 61440 + 4096 + 4096, 3, 61440),
+                        createIonAllocations(96, 8192 + 4096, 2, 8192),
+                        createIonAllocations(1232, 16728064, 1, 16728064),
+                        createIonAllocations(611, 50642944, 1, 50642944));
+    }
+
+    @Test
+    public void testParseProcessIonHeapSizesFromDebugfs_correctValue2() {
+        assertThat(parseProcessIonHeapSizesFromDebugfs(DEBUG_SYSTEM_ION_HEAP_CONTENTS_SARGO))
+                .containsExactly(
+                        createIonAllocations(1705, 58097664, 1, 58097664),
+                        createIonAllocations(851, 16384 + 4096 + 4096, 3, 16384));
+    }
+
+    private static IonAllocations createIonAllocations(int pid, long totalSizeInBytes, int count,
+            long maxSizeInBytes) {
+        IonAllocations allocations = new IonAllocations();
+        allocations.pid = pid;
+        allocations.totalSizeInBytes = totalSizeInBytes;
+        allocations.count = count;
+        allocations.maxSizeInBytes = maxSizeInBytes;
+        return allocations;
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
index bb9f49e..184dc3d 100644
--- a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
@@ -86,6 +86,7 @@
         UserState mUserState = new UserState(0,
                 mContext,
                 mLock,
+                mMockHandler,
                 componentName);
         mUserState.mService = new MockIAttentionService();
         mSpyUserState = spy(mUserState);
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
new file mode 100644
index 0000000..e6c484a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.compat;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.pm.ApplicationInfo;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CompatConfigTest {
+
+    private ApplicationInfo makeAppInfo(String pName, int targetSdkVersion) {
+        ApplicationInfo ai = new ApplicationInfo();
+        ai.packageName = pName;
+        ai.targetSdkVersion = targetSdkVersion;
+        return ai;
+    }
+
+    @Test
+    public void testUnknownChangeEnabled() {
+        CompatConfig pc = new CompatConfig();
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isTrue();
+    }
+
+    @Test
+    public void testDisabledChangeDisabled() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true));
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isFalse();
+    }
+
+    @Test
+    public void testTargetSdkChangeDisabled() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, false));
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isFalse();
+    }
+
+    @Test
+    public void testTargetSdkChangeEnabled() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, false));
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 3))).isTrue();
+    }
+
+    @Test
+    public void testDisabledOverrideTargetSdkChange() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, true));
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 3))).isFalse();
+    }
+
+    @Test
+    public void testGetDisabledChanges() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true));
+        pc.addChange(new CompatChange(2345L, "OTHER_CHANGE", -1, false));
+        assertThat(pc.getDisabledChanges(
+                makeAppInfo("com.some.package", 2))).asList().containsExactly(1234L);
+    }
+
+    @Test
+    public void testGetDisabledChangesSorted() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", 2, true));
+        pc.addChange(new CompatChange(123L, "OTHER_CHANGE", 2, true));
+        pc.addChange(new CompatChange(12L, "THIRD_CHANGE", 2, true));
+        assertThat(pc.getDisabledChanges(
+                makeAppInfo("com.some.package", 2))).asList().containsExactly(12L, 123L, 1234L);
+    }
+
+    @Test
+    public void testPackageOverrideEnabled() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, true)); // disabled
+        pc.addOverride(1234L, "com.some.package", true);
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isTrue();
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.other.package", 2))).isFalse();
+    }
+
+    @Test
+    public void testPackageOverrideDisabled() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false));
+        pc.addOverride(1234L, "com.some.package", false);
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isFalse();
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.other.package", 2))).isTrue();
+    }
+
+    @Test
+    public void testPackageOverrideUnknownPackage() {
+        CompatConfig pc = new CompatConfig();
+        pc.addOverride(1234L, "com.some.package", false);
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isFalse();
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.other.package", 2))).isTrue();
+    }
+
+    @Test
+    public void testPackageOverrideUnknownChange() {
+        CompatConfig pc = new CompatConfig();
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 1))).isTrue();
+    }
+
+    @Test
+    public void testRemovePackageOverride() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false));
+        pc.addOverride(1234L, "com.some.package", false);
+        pc.removeOverride(1234L, "com.some.package");
+        assertThat(pc.isChangeEnabled(1234L, makeAppInfo("com.some.package", 2))).isTrue();
+    }
+
+    @Test
+    public void testLookupChangeId() {
+        CompatConfig pc = new CompatConfig();
+        pc.addChange(new CompatChange(1234L, "MY_CHANGE", -1, false));
+        pc.addChange(new CompatChange(2345L, "ANOTHER_CHANGE", -1, false));
+        assertThat(pc.lookupChangeId("MY_CHANGE")).isEqualTo(1234L);
+    }
+
+    @Test
+    public void testLookupChangeIdNotPresent() {
+        CompatConfig pc = new CompatConfig();
+        assertThat(pc.lookupChangeId("MY_CHANGE")).isEqualTo(-1L);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
index 62b0ca8..891ca74 100644
--- a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java
@@ -30,7 +30,7 @@
 import com.android.server.content.ContentService.ObserverNode;
 
 /**
- * bit FrameworksServicesTests:com.android.server.content.ObserverNodeTest
+ * atest FrameworksServicesTests:com.android.server.content.ObserverNodeTest
  */
 @SmallTest
 public class ObserverNodeTest extends AndroidTestCase {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index 2ce4c54..ce83df7 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -37,6 +37,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
+import android.permission.IPermissionManager;
 import android.security.KeyChain;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
@@ -199,6 +200,11 @@
         }
 
         @Override
+        IPermissionManager getIPermissionManager() {
+            return services.ipermissionManager;
+        }
+
+        @Override
         IBackupManager getIBackupManager() {
             return services.ibackupManager;
         }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 8f0aeea..f6f365e 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -52,6 +52,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.UserManagerInternal;
+import android.permission.IPermissionManager;
 import android.provider.Settings;
 import android.security.KeyChain;
 import android.telephony.TelephonyManager;
@@ -97,6 +98,7 @@
     public ActivityManagerInternal activityManagerInternal;
     public ActivityTaskManagerInternal activityTaskManagerInternal;
     public final IPackageManager ipackageManager;
+    public final IPermissionManager ipermissionManager;
     public final IBackupManager ibackupManager;
     public final IAudioService iaudioService;
     public final LockPatternUtils lockPatternUtils;
@@ -137,6 +139,7 @@
         activityManagerInternal = mock(ActivityManagerInternal.class);
         activityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
         ipackageManager = mock(IPackageManager.class);
+        ipermissionManager = mock(IPermissionManager.class);
         ibackupManager = mock(IBackupManager.class);
         iaudioService = mock(IAudioService.class);
         lockPatternUtils = mock(LockPatternUtils.class);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
index 757a046..a3cc915 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
@@ -79,7 +79,6 @@
                 InstrumentationRegistry.getTargetContext().getCacheDir());
 
         setSystemInputMethods();
-        setIsPerProfileModeEnabled(false);
         setRequiredAppsManagedDevice();
         setVendorRequiredAppsManagedDevice();
         setDisallowedAppsManagedDevice();
@@ -164,15 +163,6 @@
     }
 
     @Test
-    public void testProfileOwnerImesAreRequiredForPerProfileImeMode() {
-        setSystemAppsWithLauncher("app.a", "app.b");
-        setSystemInputMethods("app.a");
-        setIsPerProfileModeEnabled(true);
-
-        verifyAppsAreNonRequired(ACTION_PROVISION_MANAGED_PROFILE, "app.b");
-    }
-
-    @Test
     public void testManagedUserImesAreRequired() {
         setSystemAppsWithLauncher("app.a", "app.b");
         setSystemInputMethods("app.a");
@@ -344,10 +334,6 @@
         when(mInjector.getInputMethodListAsUser(eq(TEST_USER_ID))).thenReturn(inputMethods);
     }
 
-    private void setIsPerProfileModeEnabled(boolean enabled) {
-        when(mInjector.isPerProfileImeEnabled()).thenReturn(enabled);
-    }
-
     private void setSystemAppsWithLauncher(String... apps) {
         mSystemAppsWithLauncher = apps;
     }
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 8bb8aae..a19b387 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
@@ -18,13 +18,19 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.res.Resources;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.Time;
 import android.os.Handler;
@@ -33,6 +39,7 @@
 import android.provider.Settings.Secure;
 import android.provider.Settings.System;
 import android.test.mock.MockContentResolver;
+import android.view.Display;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -73,6 +80,8 @@
     private ColorDisplayService mCds;
     private ColorDisplayService.BinderService mBinderService;
 
+    private Resources mResourcesSpy;
+
     @BeforeClass
     public static void setDtm() {
         final DisplayTransformManager dtm = Mockito.mock(DisplayTransformManager.class);
@@ -84,6 +93,9 @@
         mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
         doReturn(mContext).when(mContext).getApplicationContext();
 
+        mResourcesSpy = Mockito.spy(mContext.getResources());
+        when(mContext.getResources()).thenReturn(mResourcesSpy);
+
         mUserId = ActivityManager.getCurrentUser();
 
         final MockContentResolver cr = new MockContentResolver(mContext);
@@ -113,6 +125,8 @@
         mUserId = UserHandle.USER_NULL;
         mContext = null;
 
+        FakeSettingsProvider.clearSettingsProvider();
+
         LocalServices.removeServiceForTest(ColorDisplayService.ColorDisplayServiceInternal.class);
     }
 
@@ -924,11 +938,8 @@
 
         startService();
         assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
-        if (isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
-            assertActiveColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
-        } else if (isColorModeValid(ColorDisplayManager.COLOR_MODE_AUTOMATIC)) {
-            assertActiveColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC);
-        }
+        assertActiveColorMode(mContext.getResources().getInteger(
+                R.integer.config_accessibilityColorMode));
     }
 
     @Test
@@ -942,11 +953,8 @@
 
         startService();
         assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
-        if (isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
-            assertActiveColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
-        } else if (isColorModeValid(ColorDisplayManager.COLOR_MODE_AUTOMATIC)) {
-            assertActiveColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC);
-        }
+        assertActiveColorMode(mContext.getResources().getInteger(
+                R.integer.config_accessibilityColorMode));
     }
 
     @Test
@@ -961,11 +969,8 @@
 
         startService();
         assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
-        if (isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
-            assertActiveColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
-        } else if (isColorModeValid(ColorDisplayManager.COLOR_MODE_AUTOMATIC)) {
-            assertActiveColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC);
-        }
+        assertActiveColorMode(mContext.getResources().getInteger(
+                R.integer.config_accessibilityColorMode));
     }
 
     @Test
@@ -1020,11 +1025,15 @@
 
     @Test
     public void displayWhiteBalance_enabledAfterLinearColorModeSelected() {
+        if (!isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
+            return;
+        }
         setDisplayWhiteBalanceEnabled(true);
-        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
         startService();
-        mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+        assertDwbActive(false);
 
+        mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
         mCds.updateDisplayWhiteBalanceStatus();
         assertDwbActive(true);
     }
@@ -1032,10 +1041,8 @@
     @Test
     public void displayWhiteBalance_disabledWhileAccessibilityColorCorrectionEnabled() {
         setDisplayWhiteBalanceEnabled(true);
-        startService();
         setAccessibilityColorCorrection(true);
-
-        mCds.updateDisplayWhiteBalanceStatus();
+        startService();
         assertDwbActive(false);
 
         setAccessibilityColorCorrection(false);
@@ -1046,10 +1053,8 @@
     @Test
     public void displayWhiteBalance_disabledWhileAccessibilityColorInversionEnabled() {
         setDisplayWhiteBalanceEnabled(true);
-        startService();
         setAccessibilityColorInversion(true);
-
-        mCds.updateDisplayWhiteBalanceStatus();
+        startService();
         assertDwbActive(false);
 
         setAccessibilityColorInversion(false);
@@ -1057,6 +1062,80 @@
         assertDwbActive(true);
     }
 
+    @Test
+    public void compositionColorSpaces_noResources() {
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+        reset(dtm);
+
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+            .thenReturn(new int[] {});
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+            .thenReturn(new int[] {});
+        setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+        startService();
+        verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+                eq(Display.COLOR_MODE_INVALID));
+    }
+
+    @Test
+    public void compositionColorSpaces_invalidResources() {
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+        reset(dtm);
+
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+            .thenReturn(new int[] {
+               ColorDisplayManager.COLOR_MODE_NATURAL,
+               // Missing second color mode
+            });
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+            .thenReturn(new int[] {
+               Display.COLOR_MODE_SRGB,
+               Display.COLOR_MODE_DISPLAY_P3
+            });
+        setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+        startService();
+        verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+                eq(Display.COLOR_MODE_INVALID));
+    }
+
+    @Test
+    public void compositionColorSpaces_validResources_validColorMode() {
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+        reset(dtm);
+
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+            .thenReturn(new int[] {
+               ColorDisplayManager.COLOR_MODE_NATURAL
+            });
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+            .thenReturn(new int[] {
+               Display.COLOR_MODE_SRGB,
+            });
+        setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+        startService();
+        verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_NATURAL), any(),
+                eq(Display.COLOR_MODE_SRGB));
+    }
+
+    @Test
+    public void compositionColorSpaces_validResources_invalidColorMode() {
+        final DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
+        reset(dtm);
+
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorModes))
+            .thenReturn(new int[] {
+               ColorDisplayManager.COLOR_MODE_NATURAL
+            });
+        when(mResourcesSpy.getIntArray(R.array.config_displayCompositionColorSpaces))
+            .thenReturn(new int[] {
+               Display.COLOR_MODE_SRGB,
+            });
+        setColorMode(ColorDisplayManager.COLOR_MODE_BOOSTED);
+        startService();
+        verify(dtm).setColorMode(eq(ColorDisplayManager.COLOR_MODE_BOOSTED), any(),
+                eq(Display.COLOR_MODE_INVALID));
+    }
+
     /**
      * Configures Night display to use a custom schedule.
      *
@@ -1159,7 +1238,7 @@
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
             mCds.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
-            mCds.onStartUser(mUserId);
+            mCds.onUserChanged(mUserId);
         });
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
new file mode 100644
index 0000000..6b0798b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.whitebalance;
+
+import com.android.internal.R;
+import com.google.common.collect.ImmutableList;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
+import org.mockito.stubbing.Answer;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import android.content.ContextWrapper;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.TypedValue;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public final class AmbientLuxTest {
+    private static final int AMBIENT_COLOR_TYPE = 20705;
+    private static final String AMBIENT_COLOR_TYPE_STR = "colorSensoryDensoryDoc";
+    private static final float LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE = 5432.1f;
+    private static final float HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE = 3456.7f;
+
+    private Handler mHandler = new Handler(Looper.getMainLooper());
+    private Sensor mLightSensor;
+    private Sensor mAmbientColorSensor;
+    private ContextWrapper mContextSpy;
+    private Resources mResourcesSpy;
+
+    @Mock private SensorManager mSensorManagerMock;
+
+    @Mock private TypedArray mBrightnesses;
+    @Mock private TypedArray mBiases;
+    @Mock private TypedArray mHighLightBrightnesses;
+    @Mock private TypedArray mHighLightBiases;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mLightSensor = createSensor(Sensor.TYPE_LIGHT, null);
+        mAmbientColorSensor = createSensor(AMBIENT_COLOR_TYPE, AMBIENT_COLOR_TYPE_STR);
+        mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
+        mResourcesSpy = spy(mContextSpy.getResources());
+        when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
+        when(mSensorManagerMock.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(mLightSensor);
+        final List<Sensor> sensorList = ImmutableList.of(mLightSensor, mAmbientColorSensor);
+        when(mSensorManagerMock.getSensorList(Sensor.TYPE_ALL)).thenReturn(sensorList);
+        when(mResourcesSpy.getString(
+                R.string.config_displayWhiteBalanceColorTemperatureSensorName))
+                .thenReturn(AMBIENT_COLOR_TYPE_STR);
+        when(mResourcesSpy.getInteger(
+                R.integer.config_displayWhiteBalanceDecreaseDebounce))
+                .thenReturn(0);
+        when(mResourcesSpy.getInteger(
+                R.integer.config_displayWhiteBalanceIncreaseDebounce))
+                .thenReturn(0);
+        mockResourcesFloat(R.dimen.config_displayWhiteBalanceLowLightAmbientColorTemperature,
+                LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE);
+        mockResourcesFloat(R.dimen.config_displayWhiteBalanceHighLightAmbientColorTemperature,
+                HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE);
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceAmbientColorTemperatures))
+                .thenReturn(createTypedArray());
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceDisplayColorTemperatures))
+                .thenReturn(createTypedArray());
+
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceLowLightAmbientBrightnesses))
+                .thenReturn(mBrightnesses);
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceLowLightAmbientBiases))
+                .thenReturn(mBiases);
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceHighLightAmbientBrightnesses))
+                .thenReturn(mHighLightBrightnesses);
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceHighLightAmbientBiases))
+                .thenReturn(mHighLightBiases);
+        mockThrottler();
+    }
+
+    @Test
+    public void testNoSpline() throws Exception {
+        setBrightnesses();
+        setBiases();
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = 8000.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
+            setEstimatedBrightnessAndUpdate(controller, luxOverride);
+            assertEquals(controller.mPendingAmbientColorTemperature,
+                    ambientColorTemperature, 0.001);
+        }
+    }
+
+    @Test
+    public void testSpline_OneSegment() throws Exception {
+        final float lowerBrightness = 10.0f;
+        final float upperBrightness = 50.0f;
+        setBrightnesses(lowerBrightness, upperBrightness);
+        setBiases(0.0f, 1.0f);
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = 8000.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+            setEstimatedBrightnessAndUpdate(controller,
+                    mix(lowerBrightness, upperBrightness, t));
+            assertEquals(controller.mPendingAmbientColorTemperature,
+                    mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, t), 0.001);
+        }
+
+        setEstimatedBrightnessAndUpdate(controller, 0.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature,
+                LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+        setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+    }
+
+    @Test
+    public void testSpline_TwoSegments() throws Exception {
+        final float brightness0 = 10.0f;
+        final float brightness1 = 50.0f;
+        final float brightness2 = 60.0f;
+        setBrightnesses(brightness0, brightness1, brightness2);
+        final float bias0 = 0.0f;
+        final float bias1 = 0.25f;
+        final float bias2 = 1.0f;
+        setBiases(bias0, bias1, bias2);
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = 8000.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+            float luxOverride = mix(brightness0, brightness1, t);
+            setEstimatedBrightnessAndUpdate(controller, luxOverride);
+            float bias = mix(bias0, bias1, t);
+            assertEquals(controller.mPendingAmbientColorTemperature,
+                    mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, bias), 0.001);
+        }
+
+        for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+            float luxOverride = mix(brightness1, brightness2, t);
+            setEstimatedBrightnessAndUpdate(controller, luxOverride);
+            float bias = mix(bias1, bias2, t);
+            assertEquals(controller.mPendingAmbientColorTemperature,
+                    mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, bias), 0.001);
+        }
+
+        setEstimatedBrightnessAndUpdate(controller, 0.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature,
+                LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+        setEstimatedBrightnessAndUpdate(controller, brightness2 + 1.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+    }
+
+    @Test
+    public void testSpline_VerticalSegment() throws Exception {
+        final float lowerBrightness = 10.0f;
+        final float upperBrightness = 10.0f;
+        setBrightnesses(lowerBrightness, upperBrightness);
+        setBiases(0.0f, 1.0f);
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = 8000.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        setEstimatedBrightnessAndUpdate(controller, 0.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature,
+                LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+        setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+    }
+
+    @Test
+    public void testSpline_InvalidEndBias() throws Exception {
+        setBrightnesses(10.0f, 1000.0f);
+        setBiases(0.0f, 2.0f);
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = 8000.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
+        setEstimatedBrightnessAndUpdate(controller, luxOverride);
+        assertEquals(controller.mPendingAmbientColorTemperature,
+                ambientColorTemperature, 0.001);
+        }
+    }
+
+    @Test
+    public void testSpline_InvalidBeginBias() throws Exception {
+        setBrightnesses(10.0f, 1000.0f);
+        setBiases(0.1f, 1.0f);
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = 8000.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
+        setEstimatedBrightnessAndUpdate(controller, luxOverride);
+        assertEquals(controller.mPendingAmbientColorTemperature,
+                ambientColorTemperature, 0.001);
+        }
+    }
+
+    @Test
+    public void testSpline_OneSegmentHighLight() throws Exception {
+        final float lowerBrightness = 10.0f;
+        final float upperBrightness = 50.0f;
+        setHighLightBrightnesses(lowerBrightness, upperBrightness);
+        setHighLightBiases(0.0f, 1.0f);
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = 8000.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+            setEstimatedBrightnessAndUpdate(controller,
+                    mix(lowerBrightness, upperBrightness, t));
+            assertEquals(controller.mPendingAmbientColorTemperature,
+                    mix(HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, 1.0f - t),
+                    0.001);
+        }
+
+        setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature,
+                HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+        setEstimatedBrightnessAndUpdate(controller, 0.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+    }
+
+    @Test
+    public void testSpline_TwoSegmentsHighLight() throws Exception {
+        final float brightness0 = 10.0f;
+        final float brightness1 = 50.0f;
+        final float brightness2 = 60.0f;
+        setHighLightBrightnesses(brightness0, brightness1, brightness2);
+        final float bias0 = 0.0f;
+        final float bias1 = 0.25f;
+        final float bias2 = 1.0f;
+        setHighLightBiases(bias0, bias1, bias2);
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = 6000.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+            float luxOverride = mix(brightness0, brightness1, t);
+            setEstimatedBrightnessAndUpdate(controller, luxOverride);
+            float bias = mix(bias0, bias1, t);
+            assertEquals(controller.mPendingAmbientColorTemperature,
+                    mix(HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, 1.0f - bias),
+                    0.01);
+        }
+
+        for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+            float luxOverride = mix(brightness1, brightness2, t);
+            setEstimatedBrightnessAndUpdate(controller, luxOverride);
+            float bias = mix(bias1, bias2, t);
+            assertEquals(controller.mPendingAmbientColorTemperature,
+                    mix(HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, 1.0f - bias),
+                    0.01);
+        }
+
+        setEstimatedBrightnessAndUpdate(controller, brightness2 + 1.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature,
+                HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+        setEstimatedBrightnessAndUpdate(controller, 0.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+    }
+
+    @Test
+    public void testSpline_InvalidCombinations() throws Exception {
+            setBrightnesses(100.0f, 200.0f);
+            setBiases(0.0f, 1.0f);
+            setHighLightBrightnesses(150.0f, 250.0f);
+            setHighLightBiases(0.0f, 1.0f);
+
+            DisplayWhiteBalanceController controller =
+                    DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+            final float ambientColorTemperature = 8000.0f;
+            setEstimatedColorTemperature(controller, ambientColorTemperature);
+            controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+            for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
+                setEstimatedBrightnessAndUpdate(controller, luxOverride);
+                assertEquals(controller.mPendingAmbientColorTemperature,
+                        ambientColorTemperature, 0.001);
+            }
+    }
+
+    @Test
+    public void testLowLight_DefaultAmbient() throws Exception {
+        final float lowerBrightness = 10.0f;
+        final float upperBrightness = 50.0f;
+        setBrightnesses(lowerBrightness, upperBrightness);
+        setBiases(0.0f, 1.0f);
+
+        DisplayWhiteBalanceController controller =
+                DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+        final float ambientColorTemperature = -1.0f;
+        setEstimatedColorTemperature(controller, ambientColorTemperature);
+        controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+        for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+            setEstimatedBrightnessAndUpdate(controller,
+                    mix(lowerBrightness, upperBrightness, t));
+            assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature,
+                        0.001);
+        }
+
+        setEstimatedBrightnessAndUpdate(controller, 0.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+
+        setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
+        assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+    }
+
+    void mockThrottler() {
+        when(mResourcesSpy.getInteger(
+                R.integer.config_displayWhiteBalanceDecreaseDebounce)).thenReturn(0);
+        when(mResourcesSpy.getInteger(
+                R.integer.config_displayWhiteBalanceIncreaseDebounce)).thenReturn(0);
+        TypedArray base = mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceBaseThresholds);
+        TypedArray inc = mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceIncreaseThresholds);
+        TypedArray dec = mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceDecreaseThresholds);
+        base = spy(base);
+        inc = spy(inc);
+        dec = spy(dec);
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceBaseThresholds)).thenReturn(base);
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceIncreaseThresholds)).thenReturn(inc);
+        when(mResourcesSpy.obtainTypedArray(
+                R.array.config_displayWhiteBalanceDecreaseThresholds)).thenReturn(dec);
+        setFloatArrayResource(base, new float[]{0.0f});
+        setFloatArrayResource(inc, new float[]{0.0f});
+        setFloatArrayResource(dec, new float[]{0.0f});
+    }
+
+    private void mockResourcesFloat(int id, float floatValue) {
+        doAnswer(new Answer<Void>() {
+            public Void answer(InvocationOnMock invocation) {
+                TypedValue value = (TypedValue)invocation.getArgument(1);
+                value.type = TypedValue.TYPE_FLOAT;
+                value.data = Float.floatToIntBits(floatValue);
+                return null;
+            }
+        }).when(mResourcesSpy).getValue(
+                eq(id),
+                any(TypedValue.class), eq(true));
+    }
+
+    private void setEstimatedColorTemperature(DisplayWhiteBalanceController controller,
+                                              float ambientColorTemperature) {
+        AmbientFilter colorTemperatureFilter = spy(controller.mColorTemperatureFilter);
+        controller.mColorTemperatureFilter = colorTemperatureFilter;
+        when(colorTemperatureFilter.getEstimate(anyLong())).thenReturn(ambientColorTemperature);
+    }
+
+    private void setEstimatedBrightnessAndUpdate(DisplayWhiteBalanceController controller,
+                                                 float brightness) {
+        when(controller.mBrightnessFilter.getEstimate(anyLong())).thenReturn(brightness);
+        controller.updateAmbientColorTemperature();
+    }
+
+    private void setBrightnesses(float... vals) {
+        setFloatArrayResource(mBrightnesses, vals);
+    }
+
+    private void setBiases(float... vals) {
+        setFloatArrayResource(mBiases, vals);
+    }
+
+    private void setHighLightBrightnesses(float... vals) {
+        setFloatArrayResource(mHighLightBrightnesses, vals);
+    }
+
+    private void setHighLightBiases(float... vals) {
+        setFloatArrayResource(mHighLightBiases, vals);
+    }
+
+    private void setFloatArrayResource(TypedArray array, float[] vals) {
+        when(array.length()).thenReturn(vals.length);
+        for (int i = 0; i < vals.length; i++) {
+            when(array.getFloat(i, Float.NaN)).thenReturn(vals[i]);
+        }
+    }
+
+    private void setSensorType(Sensor sensor, int type, String strType) throws Exception {
+        Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE);
+        setter.setAccessible(true);
+        setter.invoke(sensor, type);
+        if (strType != null) {
+            Field f = sensor.getClass().getDeclaredField("mStringType");
+            f.setAccessible(true);
+            f.set(sensor, strType);
+        }
+    }
+
+    private Sensor createSensor(int type, String strType) throws Exception {
+        Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
+        constr.setAccessible(true);
+        Sensor sensor = constr.newInstance();
+        setSensorType(sensor, type, strType);
+        return sensor;
+    }
+
+    private TypedArray createTypedArray() throws Exception {
+        TypedArray mockArray = mock(TypedArray.class);
+        return mockArray;
+    }
+
+    private static float mix(float a, float b, float t) {
+        return (1.0f - t) * a + t * b;
+    }
+}
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 604637a..0309dbe 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -85,7 +85,7 @@
         JobSchedulerService.sSystemClock =
                 Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
         JobSchedulerService.sUptimeMillisClock =
-                Clock.fixed(SystemClock.uptimeMillisClock().instant(), ZoneOffset.UTC);
+                Clock.fixed(SystemClock.uptimeClock().instant(), ZoneOffset.UTC);
         JobSchedulerService.sElapsedRealtimeClock =
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC);
     }
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 f85e2cc..5c67d04 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -110,7 +110,7 @@
         }
 
         @Override
-        public boolean hasEnrolledBiometrics() {
+        public boolean hasEnrolledBiometrics(int userId) {
             return false;
         }
 
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 18453aa..f9e4c34 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -122,19 +122,17 @@
     }
 
     public void testKeyValue_Concurrency() {
-        final Object monitor = new Object();
+        final CountDownLatch latch = new CountDownLatch(1);
         List<Thread> threads = new ArrayList<>();
         for (int i = 0; i < 100; i++) {
             final int threadId = i;
             threads.add(new Thread("testKeyValue_Concurrency_" + i) {
                 @Override
                 public void run() {
-                    synchronized (monitor) {
-                        try {
-                            monitor.wait();
-                        } catch (InterruptedException e) {
-                            return;
-                        }
+                    try {
+                        latch.await();
+                    } catch (InterruptedException e) {
+                        return;
                     }
                     mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
                     mStorage.readKeyValue("key", "default", 0);
@@ -151,9 +149,7 @@
             threads.get(i).start();
         }
         mStorage.writeKeyValue("key", "initalValue", 0);
-        synchronized (monitor) {
-            monitor.notifyAll();
-        }
+        latch.countDown();
         joinAll(threads, 10000);
         assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
         mStorage.clearCache();
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index bdc46ec..09ae3a2 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -49,7 +49,6 @@
 import static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT;
 import static android.telephony.SubscriptionPlan.BYTES_UNLIMITED;
 import static android.telephony.SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED;
-import static android.text.format.Time.TIMEZONE_UTC;
 
 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS;
 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
@@ -128,7 +127,6 @@
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.text.TextUtils;
-import android.text.format.Time;
 import android.util.DataUnit;
 import android.util.Log;
 import android.util.Pair;
@@ -184,6 +182,7 @@
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.TimeZone;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -213,6 +212,7 @@
      * Path on assets where files used by {@link NetPolicyXml} are located.
      */
     private static final String NETPOLICY_DIR = "NetworkPolicyManagerServiceTest/netpolicy";
+    private static final String TIMEZONE_UTC = "UTC";
 
     private BroadcastInterceptingContext mServiceContext;
     private File mPolicyDir;
@@ -559,7 +559,25 @@
                 .build();
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
-        // RestrictBackground should be on, following its previous state
+        // RestrictBackground should be on, as before.
+        assertTrue(mService.getRestrictBackground());
+
+        stateOn = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(true)
+                .setBatterySaverEnabled(true)
+                .build();
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
+
+        // RestrictBackground should be on.
+        assertTrue(mService.getRestrictBackground());
+
+        stateOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(false)
+                .setBatterySaverEnabled(false)
+                .build();
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
+
+        // RestrictBackground should be on, as it was enabled manually before battery saver.
         assertTrue(mService.getRestrictBackground());
     }
 
@@ -585,6 +603,20 @@
 
         // RestrictBackground should be off, following its previous state
         assertFalse(mService.getRestrictBackground());
+
+        PowerSaveState stateOnRestrictOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(true)
+                .setBatterySaverEnabled(false)
+                .build();
+
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOnRestrictOff);
+
+        assertFalse(mService.getRestrictBackground());
+
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
+
+        // RestrictBackground should still be off.
+        assertFalse(mService.getRestrictBackground());
     }
 
     @Test
@@ -602,11 +634,49 @@
 
         // User turns off RestrictBackground manually
         setRestrictBackground(false);
-        PowerSaveState stateOff = new PowerSaveState.Builder().setBatterySaverEnabled(
-                false).build();
+        // RestrictBackground should be off because user changed it manually
+        assertFalse(mService.getRestrictBackground());
+
+        PowerSaveState stateOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(false)
+                .setBatterySaverEnabled(false)
+                .build();
         mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
 
-        // RestrictBackground should be off because user changes it manually
+        // RestrictBackground should remain off.
+        assertFalse(mService.getRestrictBackground());
+    }
+
+    @Test
+    public void updateRestrictBackgroundByLowPowerMode_RestrictOnWithGlobalOff()
+            throws Exception {
+        setRestrictBackground(false);
+        PowerSaveState stateOn = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(false)
+                .setBatterySaverEnabled(true)
+                .build();
+
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
+
+        // RestrictBackground should be turned on because of battery saver.
+        assertTrue(mService.getRestrictBackground());
+
+        PowerSaveState stateRestrictOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(true)
+                .setBatterySaverEnabled(false)
+                .build();
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateRestrictOff);
+
+        // RestrictBackground should be off, returning to its state before battery saver's change.
+        assertFalse(mService.getRestrictBackground());
+
+        PowerSaveState stateOff = new PowerSaveState.Builder()
+                .setGlobalBatterySaverEnabled(false)
+                .setBatterySaverEnabled(false)
+                .build();
+        mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
+
+        // RestrictBackground should still be off, back in its pre-battery saver state.
         assertFalse(mService.getRestrictBackground());
     }
 
@@ -1796,7 +1866,7 @@
     private static NetworkPolicy buildFakeMobilePolicy(int cycleDay, long warningBytes,
             long limitBytes, boolean inferred) {
         final NetworkTemplate template = buildTemplateMobileAll(FAKE_SUBSCRIBER_ID);
-        return new NetworkPolicy(template, cycleDay, new Time().timezone, warningBytes,
+        return new NetworkPolicy(template, cycleDay, TimeZone.getDefault().getID(), warningBytes,
                 limitBytes, SNOOZE_NEVER, SNOOZE_NEVER, true, inferred);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
index d3f33a1..43bcd4f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageInstallerSessionTest.java
@@ -36,7 +36,9 @@
 import libcore.io.IoUtils;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -56,6 +58,9 @@
 
 @RunWith(AndroidJUnit4.class)
 public class PackageInstallerSessionTest {
+    @Rule
+    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+
     private File mTmpDir;
     private AtomicFile mSessionsFile;
     private static final String TAG_SESSIONS = "sessions";
@@ -65,7 +70,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mTmpDir = IoUtils.createTemporaryDirectory("PackageInstallerSessionTest");
+        mTmpDir = mTemporaryFolder.newFolder("PackageInstallerSessionTest");
         mSessionsFile = new AtomicFile(
                 new File(mTmpDir.getAbsolutePath() + "/sessions.xml"), "package-session");
         MockitoAnnotations.initMocks(this);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 95ec3d9..fc7cfec 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -115,7 +115,7 @@
 
     @Test
     public void testPartitions() throws Exception {
-        String[] partitions = { "system", "vendor", "odm", "oem", "product", "product_services" };
+        String[] partitions = { "system", "vendor", "odm", "oem", "product", "system_ext" };
         String[] appdir = { "app", "priv-app" };
         for (int i = 0; i < partitions.length; i++) {
             for (int j = 0; j < appdir.length; j++) {
@@ -128,7 +128,7 @@
                 Assert.assertEquals(i == 1 || i == 2, PackageManagerService.locationIsVendor(path));
                 Assert.assertEquals(i == 3, PackageManagerService.locationIsOem(path));
                 Assert.assertEquals(i == 4, PackageManagerService.locationIsProduct(path));
-                Assert.assertEquals(i == 5, PackageManagerService.locationIsProductServices(path));
+                Assert.assertEquals(i == 5, PackageManagerService.locationIsSystemExt(path));
             }
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 3c3721c..13a8eb1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -43,13 +43,14 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import libcore.io.IoUtils;
-
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.nio.charset.StandardCharsets;
@@ -62,13 +63,16 @@
 @RunWith(AndroidJUnit4.class)
 @MediumTest
 public class PackageParserTest {
+    @Rule
+    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+
     private File mTmpDir;
     private static final File FRAMEWORK = new File("/system/framework/framework-res.apk");
 
     @Before
-    public void setUp() {
+    public void setUp() throws IOException {
         // Create a new temporary directory for each of our tests.
-        mTmpDir = IoUtils.createTemporaryDirectory("PackageParserTest");
+        mTmpDir = mTemporaryFolder.newFolder("PackageParserTest");
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 7e6b7da..6c917b7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -97,16 +97,25 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 import android.util.SparseArray;
+import android.util.Xml;
 
 import com.android.frameworks.servicestests.R;
+import com.android.internal.util.FastXmlSerializer;
 import com.android.server.pm.ShortcutService.ConfigConstants;
 import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
 import com.android.server.pm.ShortcutUser.PackageWithUser;
 
 import org.mockito.ArgumentCaptor;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -8089,4 +8098,70 @@
             }
         }
     }
+
+    public void testShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
+        List<ShareTargetInfo> expectedValues = new ArrayList<>();
+        expectedValues.add(new ShareTargetInfo(
+                new ShareTargetInfo.TargetData[]{new ShareTargetInfo.TargetData(
+                        "http", "www.google.com", "1234", "somePath", "somePathPattern",
+                        "somePathPrefix", "text/plain")}, "com.test.directshare.TestActivity1",
+                new String[]{"com.test.category.CATEGORY1", "com.test.category.CATEGORY2"}));
+        expectedValues.add(new ShareTargetInfo(new ShareTargetInfo.TargetData[]{
+                new ShareTargetInfo.TargetData(null, null, null, null, null, null, "video/mp4"),
+                new ShareTargetInfo.TargetData("content", null, null, null, null, null, "video/*")},
+                "com.test.directshare.TestActivity5",
+                new String[]{"com.test.category.CATEGORY5", "com.test.category.CATEGORY6"}));
+
+        // Write ShareTargets to Xml
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        final XmlSerializer outXml = new FastXmlSerializer();
+        outXml.setOutput(outStream, StandardCharsets.UTF_8.name());
+        outXml.startDocument(null, true);
+        for (int i = 0; i < expectedValues.size(); i++) {
+            expectedValues.get(i).saveToXml(outXml);
+        }
+        outXml.endDocument();
+        outXml.flush();
+
+        // Read ShareTargets from Xml
+        ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new InputStreamReader(inStream));
+        List<ShareTargetInfo> shareTargets = new ArrayList<>();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+            if (type == XmlPullParser.START_TAG && parser.getName().equals("share-target")) {
+                shareTargets.add(ShareTargetInfo.loadFromXml(parser));
+            }
+        }
+
+        // Assert two lists are equal
+        assertNotNull(shareTargets);
+        assertEquals(expectedValues.size(), shareTargets.size());
+
+        for (int i = 0; i < expectedValues.size(); i++) {
+            ShareTargetInfo expected = expectedValues.get(i);
+            ShareTargetInfo actual = shareTargets.get(i);
+
+            assertEquals(expected.mTargetData.length, actual.mTargetData.length);
+            for (int j = 0; j < expected.mTargetData.length; j++) {
+                assertEquals(expected.mTargetData[j].mScheme, actual.mTargetData[j].mScheme);
+                assertEquals(expected.mTargetData[j].mHost, actual.mTargetData[j].mHost);
+                assertEquals(expected.mTargetData[j].mPort, actual.mTargetData[j].mPort);
+                assertEquals(expected.mTargetData[j].mPath, actual.mTargetData[j].mPath);
+                assertEquals(expected.mTargetData[j].mPathPrefix,
+                        actual.mTargetData[j].mPathPrefix);
+                assertEquals(expected.mTargetData[j].mPathPattern,
+                        actual.mTargetData[j].mPathPattern);
+                assertEquals(expected.mTargetData[j].mMimeType, actual.mTargetData[j].mMimeType);
+            }
+
+            assertEquals(expected.mTargetClass, actual.mTargetClass);
+
+            assertEquals(expected.mCategories.length, actual.mCategories.length);
+            for (int j = 0; j < expected.mCategories.length; j++) {
+                assertEquals(expected.mCategories[j], actual.mCategories[j]);
+            }
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
index a63f49b..4476918 100644
--- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
@@ -42,6 +42,8 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.server.wm.WindowManagerInternal;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -57,6 +59,8 @@
     @Mock
     private AttentionManagerInternal mAttentionManagerInternal;
     @Mock
+    private WindowManagerInternal mWindowManagerInternal;
+    @Mock
     private Runnable mOnUserAttention;
     private TestableAttentionDetector mAttentionDetector;
     private long mAttentionTimeout;
@@ -71,6 +75,7 @@
                 PackageManager.PERMISSION_GRANTED);
         when(mAttentionManagerInternal.checkAttention(anyLong(), any()))
                 .thenReturn(true);
+        when(mWindowManagerInternal.isKeyguardShowingAndNotOccluded()).thenReturn(false);
         mAttentionDetector = new TestableAttentionDetector();
         mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_AWAKE);
         mAttentionDetector.setAttentionServiceSupported(true);
@@ -117,6 +122,15 @@
     }
 
     @Test
+    public void testOnUserActivity_doesntCheckIfInLockscreen() {
+        when(mWindowManagerInternal.isKeyguardShowingAndNotOccluded()).thenReturn(true);
+
+        long when = registerAttention();
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
+        assertThat(mNextDimming).isEqualTo(when);
+    }
+
+    @Test
     public void testOnUserActivity_doesntCheckIfNotSufficientPermissions() {
         when(mPackageManager.checkPermission(any(), any())).thenReturn(
                 PackageManager.PERMISSION_DENIED);
@@ -299,6 +313,7 @@
         TestableAttentionDetector() {
             super(AttentionDetectorTest.this.mOnUserAttention, new Object());
             mAttentionManager = mAttentionManagerInternal;
+            mWindowManager = mWindowManagerInternal;
             mPackageManager = AttentionDetectorTest.this.mPackageManager;
             mContentResolver = getContext().getContentResolver();
             mMaximumExtensionMillis = 10000L;
diff --git a/services/tests/servicestests/src/com/android/server/textservices/LazyIntToIntMapTest.java b/services/tests/servicestests/src/com/android/server/textservices/LazyIntToIntMapTest.java
deleted file mode 100644
index f80afb2..0000000
--- a/services/tests/servicestests/src/com/android/server/textservices/LazyIntToIntMapTest.java
+++ /dev/null
@@ -1,92 +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.server.textservices;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.IntUnaryOperator;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class LazyIntToIntMapTest {
-    @Test
-    public void testLaziness() {
-        final IntUnaryOperator func = mock(IntUnaryOperator.class);
-        when(func.applyAsInt(eq(1))).thenReturn(11);
-        when(func.applyAsInt(eq(2))).thenReturn(22);
-
-        final LazyIntToIntMap map = new LazyIntToIntMap(func);
-
-        verify(func, never()).applyAsInt(anyInt());
-
-        assertEquals(22, map.get(2));
-        verify(func, times(0)).applyAsInt(eq(1));
-        verify(func, times(1)).applyAsInt(eq(2));
-
-        // Accessing to the same key does not evaluate the function again.
-        assertEquals(22, map.get(2));
-        verify(func, times(0)).applyAsInt(eq(1));
-        verify(func, times(1)).applyAsInt(eq(2));
-    }
-
-    @Test
-    public void testDelete() {
-        final IntUnaryOperator func1 = mock(IntUnaryOperator.class);
-        when(func1.applyAsInt(eq(1))).thenReturn(11);
-        when(func1.applyAsInt(eq(2))).thenReturn(22);
-
-        final IntUnaryOperator func2 = mock(IntUnaryOperator.class);
-        when(func2.applyAsInt(eq(1))).thenReturn(111);
-        when(func2.applyAsInt(eq(2))).thenReturn(222);
-
-        final AtomicReference<IntUnaryOperator> funcRef = new AtomicReference<>(func1);
-        final LazyIntToIntMap map = new LazyIntToIntMap(i -> funcRef.get().applyAsInt(i));
-
-        verify(func1, never()).applyAsInt(anyInt());
-        verify(func2, never()).applyAsInt(anyInt());
-
-        assertEquals(22, map.get(2));
-        verify(func1, times(1)).applyAsInt(eq(2));
-        verify(func2, times(0)).applyAsInt(eq(2));
-
-        // Swap func1 with func2 then invalidate the key=2
-        funcRef.set(func2);
-        map.delete(2);
-
-        // Calling get(2) again should re-evaluate the value.
-        assertEquals(222, map.get(2));
-        verify(func1, times(1)).applyAsInt(eq(2));
-        verify(func2, times(1)).applyAsInt(eq(2));
-
-        // Trying to delete non-existing keys does nothing.
-        map.delete(1);
-    }
-}
diff --git a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
index a1d48cc..14b71ec 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
@@ -49,7 +49,7 @@
     }
 
     @Before
-    public void setup() {
+    public final void setup() {
         MockitoAnnotations.initMocks(this);
 
         // Share classloader to allow package access.
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 6061d51..8c3373f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -156,7 +156,7 @@
         mService.setUsageStats(mUsageStats);
         mService.setAccessibilityManager(accessibilityManager);
         mService.mScreenOn = false;
-        mService.mInCall = false;
+        mService.mInCallStateOffHook = false;
         mService.mNotificationPulseEnabled = true;
     }
 
@@ -681,7 +681,7 @@
         mService.buzzBeepBlinkLocked(r);
         Mockito.reset(mRingtonePlayer);
 
-        mService.mInCall = true;
+        mService.mInCallStateOffHook = true;
         mService.buzzBeepBlinkLocked(r);
 
         verify(mService, times(1)).playInCallNotification();
@@ -1137,7 +1137,7 @@
 
     @Test
     public void testLightsInCall() {
-        mService.mInCall = true;
+        mService.mInCallStateOffHook = true;
         NotificationRecord r = getLightsNotification();
         mService.buzzBeepBlinkLocked(r);
         verifyNeverLights();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelTest.java
deleted file mode 100644
index 1408749..0000000
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.notification;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-
-import android.app.NotificationChannel;
-import android.net.Uri;
-import android.os.Parcel;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Xml;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.util.FastXmlSerializer;
-import com.android.server.UiServiceTestCase;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NotificationChannelTest extends UiServiceTestCase {
-
-    @Test
-    public void testWriteToParcel() {
-        NotificationChannel channel =
-                new NotificationChannel("1", "one", IMPORTANCE_DEFAULT);
-        Parcel parcel = Parcel.obtain();
-        channel.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        NotificationChannel channel1 = NotificationChannel.CREATOR.createFromParcel(parcel);
-        assertEquals(channel, channel1);
-    }
-
-    @Test
-    public void testSystemBlockable() {
-        NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
-        assertEquals(false, channel.isBlockableSystem());
-        channel.setBlockableSystem(true);
-        assertEquals(true, channel.isBlockableSystem());
-    }
-
-    @Test
-    public void testEmptyVibration_noException() throws Exception {
-        NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
-        channel.setVibrationPattern(new long[0]);
-
-        XmlSerializer serializer = new FastXmlSerializer();
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
-        channel.writeXml(serializer);
-    }
-
-    @Test
-    public void testBackupEmptySound() throws Exception {
-        NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
-        channel.setSound(Uri.EMPTY, null);
-
-        XmlSerializer serializer = new FastXmlSerializer();
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
-        channel.writeXmlForBackup(serializer, getContext());
-
-        XmlPullParser parser = Xml.newPullParser();
-        parser.setInput(new BufferedInputStream(
-                new ByteArrayInputStream(baos.toByteArray())), null);
-        NotificationChannel restored = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
-        restored.populateFromXmlForRestore(parser, getContext());
-
-        assertNull(restored.getSound());
-    }
-}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 52c199a3..397d215 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -16,12 +16,16 @@
 
 package com.android.server.notification;
 
+import static android.app.Notification.EXTRA_SMALL_ICON;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
@@ -31,31 +35,49 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.PendingIntent;
+import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
 import android.os.Binder;
-import android.os.Bundle;
+import android.os.Build;
 import android.os.IBinder;
+import android.os.Parcel;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.NotificationRankingUpdate;
 import android.service.notification.SnoozeCriterion;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.server.UiServiceTestCase;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import androidx.test.runner.AndroidJUnit4;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class NotificationListenerServiceTest extends UiServiceTestCase {
 
-    private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
+    int targetSdk = 0;
+
+    @Before
+    public void setUp() {
+        targetSdk = mContext.getApplicationInfo().targetSdkVersion;
+    }
+
+    @After
+    public void tearDown() {
+        mContext.getApplicationInfo().targetSdkVersion = targetSdk;
+    }
 
     @Test
     public void testGetActiveNotifications_notNull() throws Exception {
@@ -97,52 +119,150 @@
         }
     }
 
-    private NotificationRankingUpdate generateUpdate() {
-        List<String> interceptedKeys = new ArrayList<>();
-        Bundle visibilityOverrides = new Bundle();
-        Bundle overrideGroupKeys = new Bundle();
-        Bundle suppressedVisualEffects = new Bundle();
-        Bundle explanation = new Bundle();
-        Bundle channels = new Bundle();
-        Bundle overridePeople = new Bundle();
-        Bundle snoozeCriteria = new Bundle();
-        Bundle showBadge = new Bundle();
-        int[] importance = new int[mKeys.length];
-        Bundle userSentiment = new Bundle();
-        Bundle mHidden = new Bundle();
-        Bundle smartActions = new Bundle();
-        Bundle smartReplies = new Bundle();
-        Bundle lastAudiblyAlerted = new Bundle();
-        Bundle noisy = new Bundle();
-        boolean[] canBubble = new boolean[mKeys.length];
+    // Tests parceling of NotificationRankingUpdate, and by extension, RankingMap and Ranking.
+    @Test
+    public void testRankingUpdate_parcel() {
+        NotificationRankingUpdate nru = generateUpdate();
+        Parcel parcel = Parcel.obtain();
+        nru.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        NotificationRankingUpdate nru1 = NotificationRankingUpdate.CREATOR.createFromParcel(parcel);
+        assertEquals(nru, nru1);
+    }
 
+    // Tests parceling of RankingMap and RankingMap.equals
+    @Test
+    public void testRankingMap_parcel() {
+        RankingMap rmap = generateUpdate().getRankingMap();
+        Parcel parcel = Parcel.obtain();
+        rmap.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        RankingMap rmap1 = RankingMap.CREATOR.createFromParcel(parcel);
+
+        detailedAssertEquals(rmap, rmap1);
+        assertEquals(rmap, rmap1);
+    }
+
+    // Tests parceling of Ranking and Ranking.equals
+    @Test
+    public void testRanking_parcel() {
+        Ranking ranking = generateUpdate().getRankingMap().getRawRankingObject(mKeys[0]);
+        Parcel parcel = Parcel.obtain();
+        ranking.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        Ranking ranking1 = new Ranking(parcel);
+        detailedAssertEquals("rankings differ: ", ranking, ranking1);
+        assertEquals(ranking, ranking1);
+    }
+
+    // Tests NotificationRankingUpdate.equals(), and by extension, RankingMap and Ranking.
+    @Test
+    public void testRankingUpdate_equals() {
+        NotificationRankingUpdate nru = generateUpdate();
+        NotificationRankingUpdate nru2 = generateUpdate();
+        detailedAssertEquals(nru, nru2);
+        assertEquals(nru, nru2);
+        Ranking tweak = nru2.getRankingMap().getRawRankingObject(mKeys[0]);
+        tweak.populate(
+                tweak.getKey(),
+                tweak.getRank(),
+                !tweak.matchesInterruptionFilter(), // note the inversion here!
+                tweak.getVisibilityOverride(),
+                tweak.getSuppressedVisualEffects(),
+                tweak.getImportance(),
+                tweak.getImportanceExplanation(),
+                tweak.getOverrideGroupKey(),
+                tweak.getChannel(),
+                (ArrayList) tweak.getAdditionalPeople(),
+                (ArrayList) tweak.getSnoozeCriteria(),
+                tweak.canShowBadge(),
+                tweak.getUserSentiment(),
+                tweak.isSuspended(),
+                tweak.getLastAudiblyAlertedMillis(),
+                tweak.isNoisy(),
+                (ArrayList) tweak.getSmartActions(),
+                (ArrayList) tweak.getSmartReplies(),
+                tweak.canBubble()
+        );
+        assertNotEquals(nru, nru2);
+    }
+
+    @Test
+    public void testLegacyIcons_preM() {
+        TestListenerService service = new TestListenerService();
+        service.attachBaseContext(mContext);
+        service.targetSdk = Build.VERSION_CODES.LOLLIPOP_MR1;
+
+        Bitmap largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
+
+        Notification n = new Notification.Builder(mContext, "channel")
+                .setSmallIcon(android.R.drawable.star_on)
+                .setLargeIcon(Icon.createWithBitmap(largeIcon))
+                .setContentTitle("test")
+                .build();
+
+        service.createLegacyIconExtras(n);
+
+        assertEquals(android.R.drawable.star_on, n.extras.getInt(EXTRA_SMALL_ICON));
+        assertEquals(android.R.drawable.star_on, n.icon);
+        assertNotNull(n.largeIcon);
+        assertNotNull(n.extras.getParcelable(Notification.EXTRA_LARGE_ICON));
+    }
+
+    @Test
+    public void testLegacyIcons_mPlus() {
+        TestListenerService service = new TestListenerService();
+        service.attachBaseContext(mContext);
+        service.targetSdk = Build.VERSION_CODES.M;
+
+        Bitmap largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
+
+        Notification n = new Notification.Builder(mContext, "channel")
+                .setSmallIcon(android.R.drawable.star_on)
+                .setLargeIcon(Icon.createWithBitmap(largeIcon))
+                .setContentTitle("test")
+                .build();
+
+        service.createLegacyIconExtras(n);
+
+        assertEquals(0, n.extras.getInt(EXTRA_SMALL_ICON));
+        assertNull(n.largeIcon);
+    }
+
+
+    // Test data
+
+    private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
+
+    private NotificationRankingUpdate generateUpdate() {
+        Ranking[] rankings = new Ranking[mKeys.length];
         for (int i = 0; i < mKeys.length; i++) {
-            String key = mKeys[i];
-            visibilityOverrides.putInt(key, getVisibilityOverride(i));
-            overrideGroupKeys.putString(key, getOverrideGroupKey(key));
-            if (isIntercepted(i)) {
-                interceptedKeys.add(key);
-            }
-            suppressedVisualEffects.putInt(key, getSuppressedVisualEffects(i));
-            importance[i] = getImportance(i);
-            explanation.putString(key, getExplanation(key));
-            channels.putParcelable(key, getChannel(key, i));
-            overridePeople.putStringArrayList(key, getPeople(key, i));
-            snoozeCriteria.putParcelableArrayList(key, getSnoozeCriteria(key, i));
-            showBadge.putBoolean(key, getShowBadge(i));
-            userSentiment.putInt(key, getUserSentiment(i));
-            mHidden.putBoolean(key, getHidden(i));
-            smartActions.putParcelableArrayList(key, getSmartActions(key, i));
-            smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i));
-            lastAudiblyAlerted.putLong(key, lastAudiblyAlerted(i));
-            noisy.putBoolean(key, getNoisy(i));
-            canBubble[i] = canBubble(i);
+            final String key = mKeys[i];
+            Ranking ranking = new Ranking();
+            ranking.populate(
+                    key,
+                    i,
+                    !isIntercepted(i),
+                    getVisibilityOverride(i),
+                    getSuppressedVisualEffects(i),
+                    getImportance(i),
+                    getExplanation(key),
+                    getOverrideGroupKey(key),
+                    getChannel(key, i),
+                    getPeople(key, i),
+                    getSnoozeCriteria(key, i),
+                    getShowBadge(i),
+                    getUserSentiment(i),
+                    getHidden(i),
+                    lastAudiblyAlerted(i),
+                    getNoisy(i),
+                    getSmartActions(key, i),
+                    getSmartReplies(key, i),
+                    canBubble(i)
+            );
+            rankings[i] = ranking;
         }
-        NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
-                interceptedKeys.toArray(new String[0]), visibilityOverrides,
-                suppressedVisualEffects, importance, explanation, overrideGroupKeys,
-                channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden,
-                smartActions, smartReplies, lastAudiblyAlerted, noisy, canBubble);
+        NotificationRankingUpdate update = new NotificationRankingUpdate(rankings);
         return update;
     }
 
@@ -253,8 +373,46 @@
         }
     }
 
+    private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) {
+        assertEquals(a.getRankingMap(), b.getRankingMap());
+    }
+
+    private void detailedAssertEquals(String comment, Ranking a, Ranking b) {
+        assertEquals(comment, a.getKey(), b.getKey());
+        assertEquals(comment, a.getRank(), b.getRank());
+        assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter());
+        assertEquals(comment, a.getVisibilityOverride(), b.getVisibilityOverride());
+        assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects());
+        assertEquals(comment, a.getImportance(), b.getImportance());
+        assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation());
+        assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey());
+        assertEquals(comment, a.getChannel(), b.getChannel());
+        assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople());
+        assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria());
+        assertEquals(comment, a.canShowBadge(), b.canShowBadge());
+        assertEquals(comment, a.getUserSentiment(), b.getUserSentiment());
+        assertEquals(comment, a.isSuspended(), b.isSuspended());
+        assertEquals(comment, a.getLastAudiblyAlertedMillis(), b.getLastAudiblyAlertedMillis());
+        assertEquals(comment, a.isNoisy(), b.isNoisy());
+        assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
+        assertEquals(comment, a.canBubble(), b.canBubble());
+        assertActionsEqual(a.getSmartActions(), b.getSmartActions());
+    }
+
+    private void detailedAssertEquals(RankingMap a, RankingMap b) {
+        Ranking arank = new Ranking();
+        Ranking brank = new Ranking();
+        assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys());
+        for (String key : a.getOrderedKeys()) {
+            a.getRanking(key, arank);
+            b.getRanking(key, brank);
+            detailedAssertEquals("ranking for key <" + key + ">", arank, brank);
+        }
+    }
+
     public static class TestListenerService extends NotificationListenerService {
         private final IBinder binder = new LocalBinder();
+        public int targetSdk = 0;
 
         public TestListenerService() {
             mWrapper = mock(NotificationListenerWrapper.class);
@@ -276,5 +434,19 @@
                 return TestListenerService.this;
             }
         }
+
+        @Override
+        protected void attachBaseContext(Context base) {
+            super.attachBaseContext(base);
+        }
+
+        @Override
+        public ApplicationInfo getApplicationInfo() {
+            ApplicationInfo info = super.getApplicationInfo();
+            if (targetSdk != 0) {
+                info.targetSdkVersion = targetSdk;
+            }
+            return info;
+        }
     }
 }
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 e75a30b..f14e8d2 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -131,6 +131,8 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.Xml;
+import android.widget.RemoteViews;
 
 import androidx.annotation.Nullable;
 import androidx.test.InstrumentationRegistry;
@@ -138,6 +140,7 @@
 import com.android.internal.R;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.util.FastXmlSerializer;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.UiServiceTestCase;
@@ -156,9 +159,13 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.stubbing.Answer;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
 
 import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.util.ArrayList;
@@ -168,6 +175,7 @@
 import java.util.Map;
 import java.util.function.Consumer;
 
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
@@ -342,12 +350,17 @@
         mHandler = mService.new WorkerHandler(mTestableLooper.getLooper());
         // MockPackageManager - default returns ApplicationInfo with matching calling UID
         mContext.setMockPackageManager(mPackageManagerClient);
-        final ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = mUid;
+
         when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
-                .thenReturn(applicationInfo);
+                .thenAnswer((Answer<ApplicationInfo>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return getApplicationInfo((String) args[0], mUid);
+                });
         when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
-                .thenReturn(applicationInfo);
+                .thenAnswer((Answer<ApplicationInfo>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return getApplicationInfo((String) args[0], mUid);
+                });
         when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
         final LightsManager mockLightsManager = mock(LightsManager.class);
         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
@@ -383,7 +396,6 @@
 
         when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true);
 
-
         mService.init(mTestableLooper.getLooper(),
                 mPackageManager, mPackageManagerClient, mockLightsManager,
                 mListeners, mAssistants, mConditionProviders,
@@ -407,12 +419,32 @@
 
     @After
     public void tearDown() throws Exception {
-        mFile.delete();
+        if (mFile != null) mFile.delete();
         clearDeviceConfig();
         InstrumentationRegistry.getInstrumentation()
                 .getUiAutomation().dropShellPermissionIdentity();
     }
 
+    private ApplicationInfo getApplicationInfo(String pkg, int uid) {
+        final ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.uid = uid;
+        switch (pkg) {
+            case PKG_N_MR1:
+                applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+                break;
+            case PKG_O:
+                applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
+                break;
+            case PKG_P:
+                applicationInfo.targetSdkVersion = Build.VERSION_CODES.P;
+                break;
+            default:
+                applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+                break;
+        }
+        return applicationInfo;
+    }
+
     public void waitForIdle() {
         mTestableLooper.processAllMessages();
     }
@@ -733,7 +765,7 @@
                 mService.getNotificationRecord(sbn.getKey()).getImportance());
         assertEquals(IMPORTANCE_LOW, mBinderService.getNotificationChannel(
                 PKG, mContext.getUserId(), PKG, channel.getId()).getImportance());
-        mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
+        mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", sbn.getId(), sbn.getUserId());
         waitForIdle();
 
         update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
@@ -908,7 +940,7 @@
     public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
                 generateNotificationRecord(null).getNotification(), 0);
-        mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
+        mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", 0, 0);
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(PKG);
@@ -923,7 +955,7 @@
         waitForIdle();
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0,
                 generateNotificationRecord(null).getNotification(), 0);
-        mBinderService.cancelNotificationWithTag(PKG, "tag", 0, 0);
+        mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", 0, 0);
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(PKG);
@@ -1207,7 +1239,7 @@
         sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
         mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
+        mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", sbn.getId(), sbn.getUserId());
         waitForIdle();
         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
         assertEquals(0, mService.getNotificationRecordCount());
@@ -1508,14 +1540,22 @@
     public void testUpdateAppNotifyCreatorBlock() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
 
-        mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
+        mBinderService.setNotificationsEnabledForPackage(PKG, 0, true);
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
 
         assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
         assertEquals(PKG, captor.getValue().getPackage());
-        assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
+        assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
+    }
+
+    @Test
+    public void testUpdateAppNotifyCreatorBlock_notIfMatchesExistingSetting() throws Exception {
+        mService.setPreferencesHelper(mPreferencesHelper);
+
+        mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
+        verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
     }
 
     @Test
@@ -3052,6 +3092,25 @@
     }
 
     @Test
+    public void testBackupEmptySound() throws Exception {
+        NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
+        channel.setSound(Uri.EMPTY, null);
+
+        XmlSerializer serializer = new FastXmlSerializer();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+        channel.writeXmlForBackup(serializer, getContext());
+
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(
+                new ByteArrayInputStream(baos.toByteArray())), null);
+        NotificationChannel restored = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
+        restored.populateFromXmlForRestore(parser, getContext());
+
+        assertNull(restored.getSound());
+    }
+
+    @Test
     public void testBackup() throws Exception {
         int systemChecks = mService.countSystemChecks;
         mBinderService.getBackupPayload(1);
@@ -3059,6 +3118,17 @@
     }
 
     @Test
+    public void testEmptyVibration_noException() throws Exception {
+        NotificationChannel channel = new NotificationChannel("a", "ab", IMPORTANCE_DEFAULT);
+        channel.setVibrationPattern(new long[0]);
+
+        XmlSerializer serializer = new FastXmlSerializer();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        serializer.setOutput(new BufferedOutputStream(baos), "utf-8");
+        channel.writeXml(serializer);
+    }
+
+    @Test
     public void updateUriPermissions_update() throws Exception {
         NotificationChannel c = new NotificationChannel(
                 TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
@@ -3807,6 +3877,20 @@
     }
 
     @Test
+    public void testIsCallerInstantApp_userAllNotification() throws Exception {
+        ApplicationInfo info = new ApplicationInfo();
+        info.privateFlags = ApplicationInfo.PRIVATE_FLAG_INSTANT;
+        when(mPackageManager.getApplicationInfo(anyString(), anyInt(), eq(UserHandle.USER_SYSTEM)))
+                .thenReturn(info);
+        when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{"any"});
+
+        assertTrue(mService.isCallerInstantApp(45770, UserHandle.USER_ALL));
+
+        info.privateFlags = 0;
+        assertFalse(mService.isCallerInstantApp(575370, UserHandle.USER_ALL ));
+    }
+
+    @Test
     public void testResolveNotificationUid_sameApp_nonSystemUser() throws Exception {
         ApplicationInfo info = new ApplicationInfo();
         info.uid = Binder.getCallingUid();
@@ -4395,7 +4479,7 @@
                 nr1.sbn.getKey()).getNotification().isBubbleNotification());
 
         // Remove the bubble
-        mBinderService.cancelNotificationWithTag(PKG, "tag", nr1.sbn.getId(),
+        mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", nr1.sbn.getId(),
                 nr1.sbn.getUserId());
         waitForIdle();
 
@@ -4794,7 +4878,7 @@
         assertEquals(1, notifs.length);
         assertEquals(1, mService.getNotificationRecordCount());
 
-        mBinderService.cancelNotificationWithTag(PKG, null, nrBubble.sbn.getId(),
+        mBinderService.cancelNotificationWithTag(PKG, PKG, null, nrBubble.sbn.getId(),
                 nrBubble.sbn.getUserId());
         waitForIdle();
 
@@ -5064,4 +5148,66 @@
         assertEquals(1, notifsAfter.length);
         assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
     }
+
+    @Test
+    public void testRemoveLargeRemoteViews() throws Exception {
+        int removeSize = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_notificationStripRemoteViewSizeBytes);
+
+        RemoteViews rv = mock(RemoteViews.class);
+        when(rv.estimateMemoryUsage()).thenReturn(removeSize);
+        when(rv.clone()).thenReturn(rv);
+        RemoteViews rv1 = mock(RemoteViews.class);
+        when(rv1.estimateMemoryUsage()).thenReturn(removeSize);
+        when(rv1.clone()).thenReturn(rv1);
+        RemoteViews rv2 = mock(RemoteViews.class);
+        when(rv2.estimateMemoryUsage()).thenReturn(removeSize);
+        when(rv2.clone()).thenReturn(rv2);
+        RemoteViews rv3 = mock(RemoteViews.class);
+        when(rv3.estimateMemoryUsage()).thenReturn(removeSize);
+        when(rv3.clone()).thenReturn(rv3);
+        RemoteViews rv4 = mock(RemoteViews.class);
+        when(rv4.estimateMemoryUsage()).thenReturn(removeSize);
+        when(rv4.clone()).thenReturn(rv4);
+        // note: different!
+        RemoteViews rv5 = mock(RemoteViews.class);
+        when(rv5.estimateMemoryUsage()).thenReturn(removeSize - 1);
+        when(rv5.clone()).thenReturn(rv5);
+
+        Notification np = new Notification.Builder(mContext, "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setContentText("test")
+                .setCustomContentView(rv)
+                .setCustomBigContentView(rv1)
+                .setCustomHeadsUpContentView(rv2)
+                .build();
+        Notification n = new Notification.Builder(mContext, "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setContentText("test")
+                .setCustomContentView(rv3)
+                .setCustomBigContentView(rv4)
+                .setCustomHeadsUpContentView(rv5)
+                .setPublicVersion(np)
+                .build();
+
+        assertNotNull(np.contentView);
+        assertNotNull(np.bigContentView);
+        assertNotNull(np.headsUpContentView);
+
+        assertTrue(n.publicVersion.extras.containsKey(Notification.EXTRA_CONTAINS_CUSTOM_VIEW));
+        assertNotNull(n.publicVersion.contentView);
+        assertNotNull(n.publicVersion.bigContentView);
+        assertNotNull(n.publicVersion.headsUpContentView);
+
+        mService.fixNotification(n, PKG, "tag", 9, 0);
+
+        assertNull(n.contentView);
+        assertNull(n.bigContentView);
+        assertNotNull(n.headsUpContentView);
+        assertNull(n.publicVersion.contentView);
+        assertNull(n.publicVersion.bigContentView);
+        assertNull(n.publicVersion.headsUpContentView);
+
+        verify(mUsageStats, times(5)).registerImageRemoved(PKG);
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
index 4c2822a..f5002ac 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
@@ -68,7 +68,7 @@
     private IBinder mToken = new Binder();
 
     @Before
-    public void setup() {
+    public void setUp() {
         mSliceService = mock(SliceManagerService.class);
         when(mSliceService.getContext()).thenReturn(mContext);
         when(mSliceService.getLock()).thenReturn(new Object());
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java
index d942c5a..4958daf 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java
@@ -47,7 +47,7 @@
     private SliceFullAccessList mAccessList;
 
     @Before
-    public void setup() {
+    public void setUp() {
         mAccessList = new SliceFullAccessList(mContext);
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index 7182f0f..a443695 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -71,7 +71,7 @@
     private TestableContext mContextSpy;
 
     @Before
-    public void setup() {
+    public void setUp() {
         LocalServices.addService(UsageStatsManagerInternal.class,
                 mock(UsageStatsManagerInternal.class));
         mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 4c27a3c..8c454424 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -36,6 +36,7 @@
     <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.REORDER_TASKS" />
+    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
 
     <!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
     <application android:debuggable="true"
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
new file mode 100644
index 0000000..fc24f5e
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.policy;
+
+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.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+
+import android.app.ActivityManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test class for {@link PhoneWindowManager}.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:PhoneWindowManagerTests
+ */
+@SmallTest
+public class PhoneWindowManagerTests {
+
+    PhoneWindowManager mPhoneWindowManager;
+
+    @Before
+    public void setUp() {
+        mPhoneWindowManager = spy(new PhoneWindowManager());
+        spyOn(ActivityManager.getService());
+    }
+
+    @After
+    public void tearDown() {
+        reset(ActivityManager.getService());
+    }
+
+    @Test
+    public void testShouldNotStartDockOrHomeWhenSetup() throws Exception {
+        mockStartDockOrHome();
+        doReturn(false).when(mPhoneWindowManager).isUserSetupComplete();
+
+        mPhoneWindowManager.startDockOrHome(
+                0 /* displayId */, false /* fromHomeKey */, false /* awakenFromDreams */);
+
+        verify(mPhoneWindowManager, never()).createHomeDockIntent();
+    }
+
+    @Test
+    public void testShouldStartDockOrHomeAfterSetup() throws Exception {
+        mockStartDockOrHome();
+        doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
+
+        mPhoneWindowManager.startDockOrHome(
+                0 /* displayId */, false /* fromHomeKey */, false /* awakenFromDreams */);
+
+        verify(mPhoneWindowManager).createHomeDockIntent();
+    }
+
+    private void mockStartDockOrHome() throws Exception {
+        doNothing().when(ActivityManager.getService()).stopAppSwitches();
+        ActivityTaskManagerInternal mMockActivityTaskManagerInternal =
+                mock(ActivityTaskManagerInternal.class);
+        when(mMockActivityTaskManagerInternal.startHomeOnDisplay(
+                anyInt(), anyString(), anyInt(), anyBoolean(), anyBoolean())).thenReturn(false);
+        mPhoneWindowManager.mActivityTaskManagerInternal = mMockActivityTaskManagerInternal;
+    }
+}
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 11a177a..ef11a43 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.os.Process.NOBODY_UID;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_90;
@@ -33,12 +34,16 @@
 import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
 import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.wm.ActivityStack.ActivityState.STARTED;
 import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
+import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
 import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE;
 import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
 import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
 
+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.assertNotEquals;
@@ -53,10 +58,13 @@
 import android.app.servertransaction.ActivityConfigurationChangeItem;
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.PauseActivityItem;
+import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Rect;
-import android.os.RemoteException;
+import android.os.Bundle;
+import android.os.PersistableBundle;
 import android.platform.test.annotations.Presubmit;
 import android.util.MergedConfiguration;
 import android.util.MutableBoolean;
@@ -67,6 +75,7 @@
 
 import androidx.test.filters.MediumTest;
 
+import com.android.internal.R;
 import com.android.server.wm.utils.WmDisplayCutout;
 
 import org.junit.Before;
@@ -163,12 +172,16 @@
         // Make sure the state does not change if we are not the current top activity.
         mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped behind");
 
-        // Make sure that the state does not change when we have an activity becoming translucent
         final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
         mStack.mTranslucentActivityWaiting = topActivity;
         mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
+        assertTrue(mActivity.isState(STARTED));
 
-        assertTrue(mActivity.isState(STOPPED));
+        mStack.mTranslucentActivityWaiting = null;
+        topActivity.changeWindowTranslucency(false);
+        mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped behind non-opaque");
+        mActivity.makeVisibleIfNeeded(null /* starting */, true /* reportToClient */);
+        assertTrue(mActivity.isState(STARTED));
     }
 
     private void ensureActivityConfiguration() {
@@ -190,7 +203,7 @@
     public void testRestartProcessIfVisible() {
         doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity);
         mActivity.visible = true;
-        mActivity.haveState = false;
+        mActivity.setSavedState(null /* savedState */);
         mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart");
         prepareFixedAspectRatioUnresizableActivity();
 
@@ -439,6 +452,15 @@
     }
 
     @Test
+    public void testShouldPauseWhenMakeClientVisible() {
+        ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+        topActivity.changeWindowTranslucency(false);
+        mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
+        mActivity.makeClientVisible();
+        assertEquals(STARTED, mActivity.getState());
+    }
+
+    @Test
     public void testSizeCompatMode_FixedAspectRatioBoundsWithDecor() {
         setupDisplayContentForCompatDisplayInsets();
         final int decorHeight = 200; // e.g. The device has cutout.
@@ -598,6 +620,67 @@
         assertNull(mActivity.pendingOptions);
     }
 
+    @Test
+    public void testCanLaunchHomeActivityFromChooser() {
+        ComponentName chooserComponent = ComponentName.unflattenFromString(
+                Resources.getSystem().getString(R.string.config_chooserActivity));
+        ActivityRecord chooserActivity = new ActivityBuilder(mService).setComponent(
+                chooserComponent).build();
+        assertThat(mActivity.canLaunchHomeActivity(NOBODY_UID, chooserActivity)).isTrue();
+    }
+
+    /**
+     * Verify that an {@link ActivityRecord} reports that it has saved state after creation, and
+     * that it is cleared after activity is resumed.
+     */
+    @Test
+    public void testHasSavedState() {
+        assertTrue(mActivity.hasSavedState());
+
+        ActivityRecord.activityResumedLocked(mActivity.appToken);
+        assertFalse(mActivity.hasSavedState());
+        assertNull(mActivity.getSavedState());
+    }
+
+    /** Verify the behavior of {@link ActivityRecord#setSavedState(Bundle)}. */
+    @Test
+    public void testUpdateSavedState() {
+        mActivity.setSavedState(null /* savedState */);
+        assertFalse(mActivity.hasSavedState());
+        assertNull(mActivity.getSavedState());
+
+        final Bundle savedState = new Bundle();
+        savedState.putString("test", "string");
+        mActivity.setSavedState(savedState);
+        assertTrue(mActivity.hasSavedState());
+        assertEquals(savedState, mActivity.getSavedState());
+    }
+
+    /** Verify the correct updates of saved state when activity client reports stop. */
+    @Test
+    public void testUpdateSavedState_activityStopped() {
+        final Bundle savedState = new Bundle();
+        savedState.putString("test", "string");
+        final PersistableBundle persistentSavedState = new PersistableBundle();
+        persistentSavedState.putString("persist", "string");
+
+        // Set state to STOPPING, or ActivityRecord#activityStoppedLocked() call will be ignored.
+        mActivity.setState(STOPPING, "test");
+        mActivity.activityStoppedLocked(savedState, persistentSavedState, "desc");
+        assertTrue(mActivity.hasSavedState());
+        assertEquals(savedState, mActivity.getSavedState());
+        assertEquals(persistentSavedState, mActivity.getPersistentSavedState());
+
+        // Sending 'null' for saved state can only happen due to timeout, so previously stored saved
+        // states should not be overridden.
+        mActivity.setState(STOPPING, "test");
+        mActivity.activityStoppedLocked(null /* savedState */, null /* persistentSavedState */,
+                "desc");
+        assertTrue(mActivity.hasSavedState());
+        assertEquals(savedState, mActivity.getSavedState());
+        assertEquals(persistentSavedState, mActivity.getPersistentSavedState());
+    }
+
     /** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */
     private void prepareFixedAspectRatioUnresizableActivity() {
         setupDisplayContentForCompatDisplayInsets();
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 757267e5..e5278d8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.Activity.RESULT_CANCELED;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -262,6 +263,35 @@
     }
 
     @Test
+    public void testFindTaskAlias() {
+        final String targetActivity = "target.activity";
+        final String aliasActivity = "alias.activity";
+        final ComponentName target = new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME,
+                targetActivity);
+        final ComponentName alias = new ComponentName(DEFAULT_COMPONENT_PACKAGE_NAME,
+                aliasActivity);
+        final TaskRecord task = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+        task.origActivity = alias;
+        task.realActivity = target;
+        new ActivityBuilder(mService).setComponent(target).setTask(task).setTargetActivity(
+                targetActivity).build();
+
+        // Using target activity to find task.
+        final ActivityRecord r1 = new ActivityBuilder(mService).setComponent(
+                target).setTargetActivity(targetActivity).build();
+        RootActivityContainer.FindTaskResult result = new RootActivityContainer.FindTaskResult();
+        mStack.findTaskLocked(r1, result);
+        assertThat(result.mRecord).isNotNull();
+
+        // Using alias activity to find task.
+        final ActivityRecord r2 = new ActivityBuilder(mService).setComponent(
+                alias).setTargetActivity(targetActivity).build();
+        result = new RootActivityContainer.FindTaskResult();
+        mStack.findTaskLocked(r2, result);
+        assertThat(result.mRecord).isNotNull();
+    }
+
+    @Test
     public void testMoveStackToBackIncludingParent() {
         final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
         final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
@@ -863,7 +893,7 @@
         firstActivity.app = null;
 
         // second activity will be immediately removed as it has no state.
-        secondActivity.haveState = false;
+        secondActivity.setSavedState(null /* savedState */);
 
         assertEquals(2, mTask.mActivities.size());
 
@@ -879,7 +909,7 @@
 
         activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
         activity.launchCount = 1;
-        activity.haveState = false;
+        activity.setSavedState(null /* savedState */);
 
         mStack.handleAppDiedLocked(activity.app);
 
@@ -893,7 +923,7 @@
 
         activity.mRelaunchReason = RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
         activity.launchCount = 3;
-        activity.haveState = false;
+        activity.setSavedState(null /* savedState */);
 
         mStack.handleAppDiedLocked(activity.app);
 
@@ -907,7 +937,7 @@
 
         activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
         activity.launchCount = 1;
-        activity.haveState = false;
+        activity.setSavedState(null /* savedState */);
 
         mStack.handleAppDiedLocked(activity.app);
 
@@ -921,7 +951,7 @@
 
         activity.mRelaunchReason = RELAUNCH_REASON_FREE_RESIZE;
         activity.launchCount = 3;
-        activity.haveState = false;
+        activity.setSavedState(null /* savedState */);
 
         mStack.handleAppDiedLocked(activity.app);
 
@@ -940,7 +970,7 @@
         homeStask.removeTask(homeTask, "testAdjustFocusedStack", REMOVE_TASK_MODE_DESTROYING);
 
         // Finish the only activity.
-        mStack.finishActivityLocked(topActivity, 0 /* resultCode */, null /* resultData */,
+        topActivity.finishActivityLocked(RESULT_CANCELED /* resultCode */, null /* resultData */,
                 "testAdjustFocusedStack", false /* oomAdj */);
         // Although home stack is empty, it should still be the focused stack.
         assertEquals(homeStask, mDefaultDisplay.getFocusedStack());
@@ -985,7 +1015,7 @@
         assertNotNull(activity);
         activity.setState(PAUSED, "finishCurrentActivity");
         activity.makeFinishingLocked();
-        stack.finishCurrentActivityLocked(activity, ActivityStack.FINISH_AFTER_VISIBLE,
+        activity.finishCurrentActivityLocked(ActivityRecord.FINISH_AFTER_VISIBLE,
                 false /* oomAdj */, "finishCurrentActivity");
         return activity;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 5803385..a08923b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -553,7 +553,7 @@
         runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
     }
 
     /**
@@ -568,22 +568,22 @@
                 "disallowed_unsupportedUsecase_aborted", true,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callingUidProcessStateTop_aborted", true,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_realCallingUidProcessStateTop_aborted", true,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_hasForegroundActivities_aborted", true,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                true, false, false, false, false, false);
+                true, false, false, false, false);
     }
 
     /**
@@ -598,51 +598,46 @@
         runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false,
                 Process.ROOT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false,
                 Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest("disallowed_nfcUid_notAborted", false,
                 Process.NFC_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callingUidHasVisibleWindow_notAborted", false,
                 UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_realCallingUidHasVisibleWindow_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, false);
+                false, false, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callerIsRecents_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, true, false, false, false, false);
+                false, true, false, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callerIsWhitelisted_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, true, false, false, false);
+                false, false, true, false, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callerIsInstrumentingWithBackgroundActivityStartPrivileges_notAborted",
                 false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, true, false, false);
+                false, false, false, true, false);
         runAndVerifyBackgroundActivityStartsSubtest(
                 "disallowed_callingPackageNameIsDeviceOwner_notAborted", false,
                 UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                 UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, true, false);
-        runAndVerifyBackgroundActivityStartsSubtest(
-                "disallowed_callingPackageNameIsTempWhitelisted_notAborted", false,
-                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
-                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
-                false, false, false, false, false, true);
+                false, false, false, false, true);
     }
 
     private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
@@ -651,7 +646,7 @@
             boolean hasForegroundActivities, boolean callerIsRecents,
             boolean callerIsTempWhitelisted,
             boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
-            boolean isCallingUidDeviceOwner, boolean isCallingPackageTempWhitelisted) {
+            boolean isCallingUidDeviceOwner) {
         // window visibility
         doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
                 .isAnyNonToastWindowVisibleForUid(callingUid);
@@ -679,9 +674,6 @@
                 callerIsInstrumentingWithBackgroundActivityStartPrivileges);
         // callingUid is the device owner
         doReturn(isCallingUidDeviceOwner).when(mService).isDeviceOwner(callingUid);
-        // calling package name is temporarily whitelisted
-        doReturn(isCallingPackageTempWhitelisted).when(mService)
-                .isPackageNameWhitelistedForBgActivityStarts("com.whatever.dude");
 
         final ActivityOptions options = spy(ActivityOptions.makeBasic());
         ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 53b0add..ecf3acd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -85,6 +85,7 @@
 
 import java.io.File;
 import java.util.List;
+import java.util.function.Consumer;
 
 /**
  * A base class to handle common operations in activity related unit tests.
@@ -169,8 +170,12 @@
      * Delegates task creation to {@link #TaskBuilder} to avoid the dependency of window hierarchy
      * when starting activity in unit tests.
      */
-    void mockTaskRecordFactory() {
-        final TaskRecord task = new TaskBuilder(mSupervisor).setCreateStack(false).build();
+    void mockTaskRecordFactory(Consumer<TaskBuilder> taskBuilderSetup) {
+        final TaskBuilder taskBuilder = new TaskBuilder(mSupervisor).setCreateStack(false);
+        if (taskBuilderSetup != null) {
+            taskBuilderSetup.accept(taskBuilder);
+        }
+        final TaskRecord task = taskBuilder.build();
         final TaskRecordFactory factory = mock(TaskRecordFactory.class);
         TaskRecord.setTaskRecordFactory(factory);
         doReturn(task).when(factory).create(any() /* service */, anyInt() /* taskId */,
@@ -178,6 +183,10 @@
                 any() /* voiceInteractor */);
     }
 
+    void mockTaskRecordFactory() {
+        mockTaskRecordFactory(null /* taskBuilderSetup */);
+    }
+
     /**
      * Builder for creating new activities.
      */
@@ -585,7 +594,10 @@
         }
 
         void tearDown() {
-            mHandlerThread.quitSafely();
+            // Make sure there are no running messages and then quit the thread so the next test
+            // won't be affected.
+            mHandlerThread.getThreadHandler().runWithScissors(mHandlerThread::quit,
+                    0 /* timeout */);
         }
     }
 
@@ -630,7 +642,8 @@
             mWindowManager = prepareMockWindowManager();
             mKeyguardController = mock(KeyguardController.class);
 
-            // Do not schedule idle timeouts
+            // Do not schedule idle that may touch methods outside the scope of the test.
+            doNothing().when(this).scheduleIdleLocked();
             doNothing().when(this).scheduleIdleTimeoutLocked(any());
             // unit test version does not handle launch wake lock
             doNothing().when(this).acquireLaunchWakelock();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 5a72a58..f602418 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -18,6 +18,7 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
 import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
@@ -45,6 +46,7 @@
 import android.view.IRemoteAnimationRunner;
 import android.view.RemoteAnimationAdapter;
 import android.view.RemoteAnimationTarget;
+import android.view.WindowManager;
 
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
@@ -224,6 +226,21 @@
         assertTrue(runner.mCancelled);
     }
 
+    @Test
+    public void testGetAnimationStyleResId() {
+        // Verify getAnimationStyleResId will return as LayoutParams.windowAnimations when without
+        // specifying window type.
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams();
+        attrs.windowAnimations = 0x12345678;
+        assertEquals(attrs.windowAnimations, mDc.mAppTransition.getAnimationStyleResId(attrs));
+
+        // Verify getAnimationStyleResId will return system resource Id when the window type is
+        // starting window.
+        attrs.type = TYPE_APPLICATION_STARTING;
+        assertEquals(mDc.mAppTransition.getDefaultWindowAnimationStyleResId(),
+                mDc.mAppTransition.getAnimationStyleResId(attrs));
+    }
+
     private class TestRemoteAnimationRunner implements IRemoteAnimationRunner {
         boolean mCancelled = false;
         @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 292a05b..a98f79c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -169,7 +169,7 @@
 
         mDimmer.updateDims(mTransaction, new Rect());
         verify(mTransaction).show(getDimLayer());
-        verify(dimLayer, never()).remove();
+        verify(mTransaction, never()).remove(dimLayer);
     }
 
     @Test
@@ -231,7 +231,7 @@
 
         mDimmer.updateDims(mTransaction, new Rect());
         verify(mTransaction).show(dimLayer);
-        verify(dimLayer, never()).remove();
+        verify(mTransaction, never()).remove(dimLayer);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index f49a575..c5e7c47 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -26,8 +26,13 @@
 import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
 import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
 import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
+import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -663,8 +668,8 @@
                 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
 
         final ArgumentCaptor<Configuration> captor = ArgumentCaptor.forClass(Configuration.class);
-        verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(),
-                same(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
+        verify(dc.mAcitvityDisplay).updateDisplayOverrideConfigurationLocked(captor.capture(),
+                same(activityRecord), anyBoolean(), same(null));
         final Configuration newDisplayConfig = captor.getValue();
         assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation);
     }
@@ -688,8 +693,8 @@
         assertFalse("Display shouldn't rotate to handle orientation request if fixed to"
                         + " user rotation.",
                 dc.onDescendantOrientationChanged(window.mToken.token, activityRecord));
-        verify(mWm.mAtmService, never()).updateDisplayOverrideConfigurationLocked(any(),
-                eq(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
+        verify(dc.mAcitvityDisplay, never()).updateDisplayOverrideConfigurationLocked(any(),
+                eq(activityRecord), anyBoolean(), same(null));
     }
 
     @Test
@@ -789,6 +794,58 @@
     }
 
     @Test
+    public void testCalculateSystemGestureExclusion_modal() throws Exception {
+        final DisplayContent dc = createNewDisplay();
+        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "base");
+        win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+        win.setSystemGestureExclusion(Collections.singletonList(new Rect(0, 0, 1000, 1000)));
+
+        final WindowState win2 = createWindow(null, TYPE_APPLICATION, dc, "modal");
+        win2.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+        win2.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
+        win2.getAttrs().width = 10;
+        win2.getAttrs().height = 10;
+        win2.setSystemGestureExclusion(Collections.emptyList());
+
+        dc.setLayoutNeeded();
+        dc.performLayout(true /* initial */, false /* updateImeWindows */);
+
+        win.setHasSurface(true);
+        win2.setHasSurface(true);
+
+        final Region expected = Region.obtain();
+        assertEquals(expected, dc.calculateSystemGestureExclusion());
+    }
+
+    @Test
+    public void testCalculateSystemGestureExclusion_immersiveStickyLegacyWindow() throws Exception {
+        synchronized (mWm.mGlobalLock) {
+            mWm.mSystemGestureExcludedByPreQStickyImmersive = true;
+
+            final DisplayContent dc = createNewDisplay();
+            final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
+            win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;
+            win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+            win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
+            win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility =
+                    SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                            | SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+            win.mAppToken.mTargetSdk = P;
+
+            dc.setLayoutNeeded();
+            dc.performLayout(true /* initial */, false /* updateImeWindows */);
+
+            win.setHasSurface(true);
+
+            final Region expected = Region.obtain();
+            expected.set(dc.getBounds());
+            assertEquals(expected, dc.calculateSystemGestureExclusion());
+
+            win.setHasSurface(false);
+        }
+    }
+
+    @Test
     public void testOrientationChangeLogging() {
         MetricsLogger mockLogger = mock(MetricsLogger.class);
         Configuration oldConfig = new Configuration();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 4a87aa4..de184b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -16,6 +16,10 @@
 
 package com.android.server.wm;
 
+import static android.view.Gravity.BOTTOM;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.RIGHT;
+import static android.view.Gravity.TOP;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
@@ -26,9 +30,11 @@
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -66,6 +72,7 @@
     private WindowState mWindow;
     private int mRotation = ROTATION_0;
     private boolean mHasDisplayCutout;
+    private static final int DECOR_WINDOW_INSET = 50;
 
     @Before
     public void setUp() throws Exception {
@@ -520,6 +527,58 @@
         }
     }
 
+    @Test
+    public void testScreenDecorWindows() {
+        synchronized (mWm.mGlobalLock) {
+            final WindowState decorWindow = createWindow(null, TYPE_APPLICATION_OVERLAY,
+                    "decorWindow");
+            decorWindow.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
+            decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR;
+            addWindow(decorWindow);
+            addWindow(mWindow);
+
+            // Decor on top
+            updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT);
+
+            // Decor on bottom
+            updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, BOTTOM);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT,
+                    DECOR_WINDOW_INSET);
+
+            // Decor on the left
+            updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, LEFT);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            assertInsetBy(mWindow.getContentFrameLw(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0,
+                    NAV_BAR_HEIGHT);
+
+            // Decor on the right
+            updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, RIGHT);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            assertInsetBy(mWindow.getContentFrameLw(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET,
+                    NAV_BAR_HEIGHT);
+
+            // Decor not allowed as inset
+            updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, DECOR_WINDOW_INSET, TOP);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        }
+    }
+
+    private void updateDecorWindow(WindowState decorWindow, int width, int height, int gravity) {
+        decorWindow.mAttrs.width = width;
+        decorWindow.mAttrs.height = height;
+        decorWindow.mAttrs.gravity = gravity;
+        decorWindow.setRequestedSize(width, height);
+    }
+
     /**
      * Asserts that {@code actual} is inset by the given amounts from the full display rect.
      *
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 1684f97..6a3c81a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -32,6 +32,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -49,10 +50,12 @@
 import static org.mockito.Mockito.when;
 
 import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.Surface;
 import android.view.WindowManager;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
@@ -273,4 +276,37 @@
         win.mHasSurface = true;
         return win;
     }
+
+    @Test
+    @FlakyTest(bugId = 131005232)
+    public void testOverlappingWithNavBar() {
+        final WindowState targetWin = createApplicationWindow();
+        final WindowFrames winFrame = targetWin.getWindowFrames();
+        winFrame.mFrame.set(new Rect(100, 100, 200, 200));
+
+        final WindowState navigationBar = createNavigationBarWindow();
+
+        navigationBar.getFrameLw().set(new Rect(100, 200, 200, 300));
+
+        assertFalse("Freeform is overlapping with navigation bar",
+                DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+        winFrame.mFrame.set(new Rect(100, 101, 200, 201));
+        assertTrue("Freeform should be overlapping with navigation bar (bottom)",
+                DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+        winFrame.mFrame.set(new Rect(99, 200, 199, 300));
+        assertTrue("Freeform should be overlapping with navigation bar (right)",
+                DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+
+        winFrame.mFrame.set(new Rect(199, 200, 299, 300));
+        assertTrue("Freeform should be overlapping with navigation bar (left)",
+                DisplayPolicy.isOverlappingWithNavBar(targetWin, navigationBar));
+    }
+
+    private WindowState createNavigationBarWindow() {
+        final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "NavigationBar");
+        win.mHasSurface = true;
+        return win;
+    }
 }
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 a735b09..2933b4a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
@@ -102,7 +102,8 @@
         mDisplayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(),
                 Binder.getCallingUid());
         assertEquals(WindowManagerGlobal.ADD_OKAY,
-                mDisplayPolicy.prepareAddWindowLw(win, win.mAttrs));
+                mDisplayPolicy.validateAddingWindowLw(win.mAttrs));
+        mDisplayPolicy.addWindowLw(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 336fa04..bfede51 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -41,6 +41,7 @@
 import static org.mockito.Matchers.eq;
 
 import android.app.WindowConfiguration;
+import android.content.res.Configuration;
 import android.platform.test.annotations.Presubmit;
 import android.util.Xml;
 import android.view.Display;
@@ -606,6 +607,32 @@
         }
     }
 
+    @Test
+    public void testDisplayWindowSettingsAppliedOnDisplayReady() {
+        // Set forced densities for two displays in DisplayWindowSettings
+        final DisplayContent dc = createMockSimulatedDisplay();
+        final DisplayWindowSettings settings = new DisplayWindowSettings(mWm, mStorage);
+        settings.setForcedDensity(mPrimaryDisplay, 123, 0 /* userId */);
+        settings.setForcedDensity(dc, 456, 0 /* userId */);
+
+        // Apply settings to displays - the settings will be stored, but config will not be
+        // recalculated immediately.
+        settings.applySettingsToDisplayLocked(mPrimaryDisplay);
+        settings.applySettingsToDisplayLocked(dc);
+        assertFalse(mPrimaryDisplay.mWaitingForConfig);
+        assertFalse(dc.mWaitingForConfig);
+
+        // Notify WM that the displays are ready and check that they are reconfigured.
+        mWm.displayReady();
+        waitUntilHandlersIdle();
+
+        final Configuration config = new Configuration();
+        mPrimaryDisplay.computeScreenConfiguration(config);
+        assertEquals(123, config.densityDpi);
+        dc.computeScreenConfiguration(config);
+        assertEquals(456, config.densityDpi);
+    }
+
     /**
      * Prepares display settings and stores in {@link #mStorage}. Uses provided display identifier
      * and stores windowingMode=WINDOWING_MODE_PINNED.
diff --git a/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java b/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java
index 5586726..daee911 100644
--- a/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateBlacklistTest.java
@@ -16,71 +16,168 @@
 
 package com.android.server.wm;
 
+import static android.provider.DeviceConfig.WindowManager.KEY_HIGH_REFRESH_RATE_BLACKLIST;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
+import android.content.res.Resources;
 import android.platform.test.annotations.Presubmit;
+import android.provider.DeviceConfig;
+import android.util.Pair;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
-import com.android.server.wm.HighRefreshRateBlacklist.SystemPropertyGetter;
+import com.android.internal.R;
+import com.android.server.wm.HighRefreshRateBlacklist.DeviceConfigInterface;
 
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Build/Install/Run:
- *  atest WmTests:HighRefreshRateBlacklistTest
+ * atest WmTests:HighRefreshRateBlacklistTest
  */
 @SmallTest
 @Presubmit
-@FlakyTest
 public class HighRefreshRateBlacklistTest {
 
     @Test
-    public void testBlacklist() {
-        HighRefreshRateBlacklist blacklist = new HighRefreshRateBlacklist(
-                new SystemPropertyGetter() {
-
-                    @Override
-                    public int getInt(String key, int def) {
-                        if ("ro.window_manager.high_refresh_rate_blacklist_length".equals(key)) {
-                            return 2;
-                        }
-                        return def;
-                    }
-
-                    @Override
-                    public String get(String key) {
-                        if ("ro.window_manager.high_refresh_rate_blacklist_entry1".equals(key)) {
-                            return "com.android.sample1";
-                        }
-                        if ("ro.window_manager.high_refresh_rate_blacklist_entry2".equals(key)) {
-                            return "com.android.sample2";
-                        }
-                        return "";
-                    }
-                });
+    public void testDefaultBlacklist() {
+        final Resources r = createResources("com.android.sample1", "com.android.sample2");
+        HighRefreshRateBlacklist blacklist =
+                new HighRefreshRateBlacklist(r, new FakeDeviceConfigInterface());
         assertTrue(blacklist.isBlacklisted("com.android.sample1"));
         assertTrue(blacklist.isBlacklisted("com.android.sample2"));
         assertFalse(blacklist.isBlacklisted("com.android.sample3"));
     }
 
     @Test
-    public void testNoBlacklist() {
-        HighRefreshRateBlacklist blacklist = new HighRefreshRateBlacklist(
-                new SystemPropertyGetter() {
-
-                    @Override
-                    public int getInt(String key, int def) {
-                        return def;
-                    }
-
-                    @Override
-                    public String get(String key) {
-                        return "";
-                    }
-                });
+    public void testNoDefaultBlacklist() {
+        final Resources r = createResources();
+        HighRefreshRateBlacklist blacklist =
+                new HighRefreshRateBlacklist(r, new FakeDeviceConfigInterface());
         assertFalse(blacklist.isBlacklisted("com.android.sample1"));
     }
+
+    @Test
+    public void testDefaultBlacklistIsOverriddenByDeviceConfig() {
+        final Resources r = createResources("com.android.sample1");
+        final FakeDeviceConfigInterface config = new FakeDeviceConfigInterface();
+        config.setBlacklist("com.android.sample2,com.android.sample3");
+        HighRefreshRateBlacklist blacklist = new HighRefreshRateBlacklist(r, config);
+        assertFalse(blacklist.isBlacklisted("com.android.sample1"));
+        assertTrue(blacklist.isBlacklisted("com.android.sample2"));
+        assertTrue(blacklist.isBlacklisted("com.android.sample3"));
+    }
+
+    @Test
+    public void testDefaultBlacklistIsOverriddenByEmptyDeviceConfig() {
+        final Resources r = createResources("com.android.sample1");
+        final FakeDeviceConfigInterface config = new FakeDeviceConfigInterface();
+        config.setBlacklist("");
+        HighRefreshRateBlacklist blacklist = new HighRefreshRateBlacklist(r, config);
+        assertFalse(blacklist.isBlacklisted("com.android.sample1"));
+    }
+
+    @Test
+    public void testDefaultBlacklistIsOverriddenByDeviceConfigUpdate() {
+        final Resources r = createResources("com.android.sample1");
+        final FakeDeviceConfigInterface config = new FakeDeviceConfigInterface();
+        HighRefreshRateBlacklist blacklist = new HighRefreshRateBlacklist(r, config);
+
+        // First check that the default blacklist is in effect
+        assertTrue(blacklist.isBlacklisted("com.android.sample1"));
+        assertFalse(blacklist.isBlacklisted("com.android.sample2"));
+        assertFalse(blacklist.isBlacklisted("com.android.sample3"));
+
+        //  Then confirm that the DeviceConfig list has propagated and taken effect.
+        config.setBlacklist("com.android.sample2,com.android.sample3");
+        assertFalse(blacklist.isBlacklisted("com.android.sample1"));
+        assertTrue(blacklist.isBlacklisted("com.android.sample2"));
+        assertTrue(blacklist.isBlacklisted("com.android.sample3"));
+
+        //  Finally make sure we go back to the default list if the DeviceConfig gets deleted.
+        config.setBlacklist(null);
+        assertTrue(blacklist.isBlacklisted("com.android.sample1"));
+        assertFalse(blacklist.isBlacklisted("com.android.sample2"));
+        assertFalse(blacklist.isBlacklisted("com.android.sample3"));
+    }
+
+    private Resources createResources(String... defaultBlacklist) {
+        Resources r = mock(Resources.class);
+        when(r.getStringArray(R.array.config_highRefreshRateBlacklist))
+                .thenReturn(defaultBlacklist);
+        return r;
+    }
+
+
+    class FakeDeviceConfigInterface implements DeviceConfigInterface {
+        private List<Pair<DeviceConfig.OnPropertiesChangedListener, Executor>> mListeners =
+                new ArrayList<>();
+        private String mBlacklist;
+
+        @Override
+        public String getProperty(String namespace, String name) {
+            if (!DeviceConfig.NAMESPACE_WINDOW_MANAGER.equals(namespace)
+                    || !KEY_HIGH_REFRESH_RATE_BLACKLIST.equals(name)) {
+                throw new IllegalArgumentException("Only things in NAMESPACE_WINDOW_MANAGER "
+                        + "supported.");
+            }
+            return mBlacklist;
+        }
+
+        @Override
+        public void addOnPropertiesChangedListener(String namespace, Executor executor,
+                DeviceConfig.OnPropertiesChangedListener listener) {
+
+            if (!DeviceConfig.NAMESPACE_WINDOW_MANAGER.equals(namespace)) {
+                throw new IllegalArgumentException("Only things in NAMESPACE_WINDOW_MANAGER "
+                        + "supported.");
+            }
+            mListeners.add(new Pair<>(listener, executor));
+        }
+
+        void setBlacklist(String blacklist) {
+            mBlacklist = blacklist;
+            CountDownLatch latch = new CountDownLatch(mListeners.size());
+            for (Pair<DeviceConfig.OnPropertiesChangedListener, Executor> listenerInfo :
+                    mListeners) {
+                final Executor executor = listenerInfo.second;
+                final DeviceConfig.OnPropertiesChangedListener listener = listenerInfo.first;
+                DeviceConfig.Properties properties = createBlacklistProperties(blacklist);
+                executor.execute(() -> {
+                    listener.onPropertiesChanged(properties);
+                    latch.countDown();
+                });
+            }
+            try {
+                latch.await(10, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Failed to notify all blacklist listeners in time.", e);
+            }
+        }
+
+        private DeviceConfig.Properties createBlacklistProperties(final String blacklist) {
+            DeviceConfig.Properties properties = mock(DeviceConfig.Properties.class);
+            when(properties.getString(anyString(), any())).thenAnswer(invocation -> {
+                final Object[] args = invocation.getArguments();
+                if (KEY_HIGH_REFRESH_RATE_BLACKLIST.equals(args[0])) {
+                    return blacklist;
+                } else {
+                    return args[1];
+                }
+            });
+            return properties;
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 8f41a42..9630b7d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -24,22 +24,29 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
+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.eq;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 
+import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.platform.test.annotations.Presubmit;
 import android.view.IRecentsAnimationRunner;
 
@@ -107,6 +114,90 @@
     }
 
     @Test
+    public void testPreloadRecentsActivity() {
+        // Ensure that the fake recent component can be resolved by the recents intent.
+        mockTaskRecordFactory(builder -> builder.setComponent(mRecentsComponent));
+        ActivityInfo aInfo = new ActivityInfo();
+        aInfo.applicationInfo = new ApplicationInfo();
+        aInfo.applicationInfo.uid = 10001;
+        aInfo.applicationInfo.targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
+        aInfo.packageName = aInfo.applicationInfo.packageName = mRecentsComponent.getPackageName();
+        aInfo.processName = "recents";
+        doReturn(aInfo).when(mSupervisor).resolveActivity(any() /* intent */, any() /* rInfo */,
+                anyInt() /* startFlags */, any() /* profilerInfo */);
+
+        // Assume its process is alive because the caller should be the recents service.
+        WindowProcessController wpc = new WindowProcessController(mService, aInfo.applicationInfo,
+                aInfo.processName, aInfo.applicationInfo.uid, 0 /* userId */,
+                mock(Object.class) /* owner */, mock(WindowProcessListener.class));
+        wpc.setThread(mock(IApplicationThread.class));
+        doReturn(wpc).when(mService).getProcessController(eq(wpc.mName), eq(wpc.mUid));
+
+        Intent recentsIntent = new Intent().setComponent(mRecentsComponent);
+        // Null animation indicates to preload.
+        mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
+                null /* recentsAnimationRunner */);
+
+        ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
+        ActivityStack recentsStack = display.getStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_RECENTS);
+        assertThat(recentsStack).isNotNull();
+
+        ActivityRecord recentsActivity = recentsStack.getTopActivity();
+        // The activity is started in background so it should be invisible and will be stopped.
+        assertThat(recentsActivity).isNotNull();
+        assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity);
+        assertFalse(recentsActivity.visible);
+
+        // Assume it is stopped to test next use case.
+        recentsActivity.activityStoppedLocked(null /* newIcicle */, null /* newPersistentState */,
+                null /* description */);
+        mSupervisor.mStoppingActivities.remove(recentsActivity);
+
+        spyOn(recentsActivity);
+        // Start when the recents activity exists. It should ensure the configuration.
+        mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
+                null /* recentsAnimationRunner */);
+
+        verify(recentsActivity).ensureActivityConfiguration(anyInt() /* globalChanges */,
+                anyBoolean() /* preserveWindow */, eq(true) /* ignoreVisibility */);
+        assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity);
+    }
+
+    @Test
+    public void testRestartRecentsActivity() throws Exception {
+        // Have a recents activity that is not attached to its process (ActivityRecord.app = null).
+        ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
+        ActivityStack recentsStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        ActivityRecord recentActivity = new ActivityBuilder(mService).setComponent(
+                mRecentsComponent).setCreateTask(true).setStack(recentsStack).build();
+        WindowProcessController app = recentActivity.app;
+        recentActivity.app = null;
+
+        // Start an activity on top.
+        new ActivityBuilder(mService).setCreateTask(true).build().getActivityStack().moveToFront(
+                "testRestartRecentsActivity");
+
+        doCallRealMethod().when(mRootActivityContainer).ensureActivitiesVisible(
+                any() /* starting */, anyInt() /* configChanges */,
+                anyBoolean() /* preserveWindows */);
+        doReturn(app).when(mService).getProcessController(eq(recentActivity.processName), anyInt());
+        ClientLifecycleManager lifecycleManager = mService.getLifecycleManager();
+        doNothing().when(lifecycleManager).scheduleTransaction(any());
+        AppWarnings appWarnings = mService.getAppWarningsLocked();
+        spyOn(appWarnings);
+        doNothing().when(appWarnings).onStartActivity(any());
+
+        startRecentsActivity();
+
+        // Recents activity must be restarted, but not be resumed while running recents animation.
+        verify(mRootActivityContainer.mStackSupervisor).startSpecificActivityLocked(
+                eq(recentActivity), eq(false), anyBoolean());
+        assertThat(recentActivity.getState()).isEqualTo(PAUSED);
+    }
+
+    @Test
     public void testSetLaunchTaskBehindOfTargetActivity() {
         ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
         display.mDisplayContent.mBoundsAnimationController = mock(BoundsAnimationController.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 0f7b35c..d4f24f9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -30,10 +31,12 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
 import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
+import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.wm.RootActivityContainer.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
 
 import static org.junit.Assert.assertEquals;
@@ -54,6 +57,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.util.Pair;
@@ -395,6 +399,58 @@
     }
 
     /**
+     * Verify that home activity will be started on a display even if another display has a
+     * focusable activity.
+     */
+    @Test
+    public void testResumeFocusedStacksStartsHomeActivity_NoActivities() {
+        mFullscreenStack.remove();
+        mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY).getHomeStack().remove();
+        mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY)
+                .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
+        doReturn(true).when(mRootActivityContainer).resumeHomeActivity(any(), any(), anyInt());
+
+        mService.setBooted(true);
+
+        // Trigger resume on all displays
+        mRootActivityContainer.resumeFocusedStacksTopActivities();
+
+        // Verify that home activity was started on the default display
+        verify(mRootActivityContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
+    }
+
+    /**
+     * Verify that home activity will be started on a display even if another display has a
+     * focusable activity.
+     */
+    @Test
+    public void testResumeFocusedStacksStartsHomeActivity_ActivityOnSecondaryScreen() {
+        mFullscreenStack.remove();
+        mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY).getHomeStack().remove();
+        mService.mRootActivityContainer.getActivityDisplay(DEFAULT_DISPLAY)
+                .createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
+        // Create an activity on secondary display.
+        final TestActivityDisplay secondDisplay = addNewActivityDisplayAt(
+                ActivityDisplay.POSITION_TOP);
+        final ActivityStack stack = secondDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+        new ActivityBuilder(mService).setTask(task).build();
+
+        doReturn(true).when(mRootActivityContainer).resumeHomeActivity(any(), any(), anyInt());
+
+        mService.setBooted(true);
+
+        // Trigger resume on all displays
+        mRootActivityContainer.resumeFocusedStacksTopActivities();
+
+        // Verify that home activity was started on the default display
+        verify(mRootActivityContainer).resumeHomeActivity(any(), any(), eq(DEFAULT_DISPLAY));
+    }
+
+    /**
      * Verify that a lingering transition is being executed in case the activity to be resumed is
      * already resumed
      */
@@ -446,6 +502,7 @@
     @Test
     public void testStartHomeOnAllDisplays() {
         mockResolveHomeActivity();
+        mockResolveSecondaryHomeActivity();
 
         // Create secondary displays.
         final TestActivityDisplay secondDisplay = spy(createNewActivityDisplay());
@@ -601,6 +658,73 @@
     }
 
     /**
+     * Tests that the default secondary home activity is always picked when it is in forced by
+     * config_useSystemProvidedLauncherForSecondary.
+     */
+    @Test
+    public void testResolveSecondaryHomeActivityForced() throws Exception {
+        Resources resources = mContext.getResources();
+        spyOn(resources);
+        try {
+            // setUp: set secondary launcher and force it.
+            final String defaultSecondaryHome =
+                    "com.android.test/com.android.test.TestDefaultSecondaryHome";
+            final ComponentName secondaryComp = ComponentName.unflattenFromString(
+                    defaultSecondaryHome);
+            doReturn(defaultSecondaryHome).when(resources).getString(
+                    com.android.internal.R.string.config_secondaryHomeComponent);
+            doReturn(true).when(resources).getBoolean(
+                    com.android.internal.R.bool.config_useSystemProvidedLauncherForSecondary);
+            final Intent secondaryHomeIntent = mService.getSecondaryHomeIntent(null);
+            assertEquals(secondaryComp, secondaryHomeIntent.getComponent());
+            final ActivityInfo aInfoSecondary = new ActivityInfo();
+            aInfoSecondary.name = secondaryComp.getClassName();
+            aInfoSecondary.applicationInfo = new ApplicationInfo();
+            aInfoSecondary.applicationInfo.packageName = secondaryComp.getPackageName();
+            doReturn(aInfoSecondary).when(mRootActivityContainer).resolveHomeActivity(anyInt(),
+                    refEq(secondaryHomeIntent));
+            final Intent homeIntent = mService.getHomeIntent();
+            final ActivityInfo aInfoDefault = new ActivityInfo();
+            aInfoDefault.name = "fakeHomeActivity";
+            aInfoDefault.applicationInfo = new ApplicationInfo();
+            aInfoDefault.applicationInfo.packageName = "fakeHomePackage";
+            doReturn(aInfoDefault).when(mRootActivityContainer).resolveHomeActivity(anyInt(),
+                    refEq(homeIntent));
+            // Let resolveActivities call to validate both main launcher and second launcher so that
+            // resolveActivities call does not work as enabler for secondary.
+            final List<ResolveInfo> resolutions1 = new ArrayList<>();
+            final ResolveInfo resolveInfo1 = new ResolveInfo();
+            resolveInfo1.activityInfo = new ActivityInfo();
+            resolveInfo1.activityInfo.name = aInfoDefault.name;
+            resolveInfo1.activityInfo.applicationInfo = aInfoDefault.applicationInfo;
+            resolutions1.add(resolveInfo1);
+            doReturn(resolutions1).when(mRootActivityContainer).resolveActivities(anyInt(),
+                    refEq(homeIntent));
+            final List<ResolveInfo> resolutions2 = new ArrayList<>();
+            final ResolveInfo resolveInfo2 = new ResolveInfo();
+            resolveInfo2.activityInfo = new ActivityInfo();
+            resolveInfo2.activityInfo.name = aInfoSecondary.name;
+            resolveInfo2.activityInfo.applicationInfo = aInfoSecondary.applicationInfo;
+            resolutions2.add(resolveInfo2);
+            doReturn(resolutions2).when(mRootActivityContainer).resolveActivities(anyInt(),
+                    refEq(secondaryHomeIntent));
+            doReturn(true).when(mRootActivityContainer).canStartHomeOnDisplay(
+                    any(), anyInt(), anyBoolean());
+
+            // Run the test
+            final Pair<ActivityInfo, Intent> resolvedInfo = mRootActivityContainer
+                    .resolveSecondaryHomeActivity(0 /* userId */, 1 /* displayId */);
+            assertEquals(secondaryComp.getClassName(), resolvedInfo.first.name);
+            assertEquals(secondaryComp.getPackageName(),
+                    resolvedInfo.first.applicationInfo.packageName);
+            assertEquals(aInfoSecondary.name, resolvedInfo.first.name);
+        } finally {
+            // tearDown
+            reset(resources);
+        }
+    }
+
+    /**
      * Tests that secondary home should be selected if default home not support secondary displays
      * or there is no matched activity in the same package as selected default home.
      */
@@ -694,7 +818,7 @@
     }
 
     /**
-     * Mock {@link RootActivityContainerTests#resolveHomeActivity} for returning consistent activity
+     * Mock {@link RootActivityContainer#resolveHomeActivity} for returning consistent activity
      * info for test cases (the original implementation will resolve from the real package manager).
      */
     private ActivityInfo mockResolveHomeActivity() {
@@ -707,4 +831,20 @@
                 refEq(homeIntent));
         return aInfoDefault;
     }
+
+    /**
+     * Mock {@link RootActivityContainer#resolveSecondaryHomeActivity} for returning consistent
+     * activity info for test cases (the original implementation will resolve from the real package
+     * manager).
+     */
+    private void mockResolveSecondaryHomeActivity() {
+        final Intent secondaryHomeIntent = mService
+                .getSecondaryHomeIntent(null /* preferredPackage */);
+        final ActivityInfo aInfoSecondary = new ActivityInfo();
+        aInfoSecondary.name = "fakeSecondaryHomeActivity";
+        aInfoSecondary.applicationInfo = new ApplicationInfo();
+        aInfoSecondary.applicationInfo.packageName = "fakeSecondaryHomePackage";
+        doReturn(Pair.create(aInfoSecondary, secondaryHomeIntent)).when(mRootActivityContainer)
+                .resolveSecondaryHomeActivity(anyInt(), anyInt());
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index dec88f0..83dd69a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -145,8 +145,8 @@
     }
 
     @Override
-    public SurfaceControl.Transaction deferTransactionUntil(SurfaceControl sc, IBinder handle,
-            long frameNumber) {
+    public SurfaceControl.Transaction deferTransactionUntil(SurfaceControl sc,
+            SurfaceControl barrier, long frameNumber) {
         return this;
     }
 
@@ -158,7 +158,8 @@
     }
 
     @Override
-    public SurfaceControl.Transaction reparentChildren(SurfaceControl sc, IBinder newParentHandle) {
+    public SurfaceControl.Transaction reparentChildren(SurfaceControl sc,
+            SurfaceControl newParent) {
         return this;
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 366acea..df7c9a4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -162,6 +162,9 @@
         }
 
         final ActivityTaskManagerService atms = mock(ActivityTaskManagerService.class);
+        final TaskChangeNotificationController taskChangeNotificationController = mock(
+                TaskChangeNotificationController.class);
+        doReturn(taskChangeNotificationController).when(atms).getTaskChangeNotificationController();
         final WindowManagerGlobalLock wmLock = new WindowManagerGlobalLock();
         doReturn(wmLock).when(atms).getGlobalLock();
 
@@ -174,7 +177,9 @@
         final Display display = mWindowManagerService.mDisplayManager.getDisplay(DEFAULT_DISPLAY);
         // Display creation is driven by the ActivityManagerService via
         // ActivityStackSupervisor. We emulate those steps here.
-        mWindowManagerService.mRoot.createDisplayContent(display, mock(ActivityDisplay.class));
+        DisplayContent displayContent = mWindowManagerService.mRoot
+                .createDisplayContent(display, mock(ActivityDisplay.class));
+        displayContent.reconfigureDisplayLocked();
 
         mMockTracker.stopTracking();
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index f918149..29398b6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -76,7 +76,7 @@
     @Before
     public void setUp() throws Exception {
         mActivity = new ActivityBuilder(mService).build();
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
         mActivity.info.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
 
         mTarget = new TaskLaunchParamsModifier(mSupervisor);
@@ -346,6 +346,19 @@
     }
 
     @Test
+    public void testLaunchesFullscreenOnFullscreenDisplayWithFreeformHistory() {
+        mCurrent.mPreferredDisplayId = Display.INVALID_DISPLAY;
+        mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+        mCurrent.mBounds.set(0, 0, 200, 100);
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FULLSCREEN);
+    }
+
+    @Test
     public void testRespectsFullyResolvedCurrentParam_Fullscreen() {
         final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
                 WINDOWING_MODE_FREEFORM);
@@ -389,7 +402,7 @@
         mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
         mCurrent.mBounds.set(0, 0, 200, 100);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.CUPCAKE;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUPCAKE;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, /* source */ null, options, mCurrent, mResult));
@@ -411,7 +424,7 @@
         mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
         mCurrent.mBounds.set(0, 0, 200, 100);
 
-        mActivity.appInfo.flags = 0;
+        mActivity.info.applicationInfo.flags = 0;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, /* source */ null, options, mCurrent, mResult));
@@ -512,7 +525,7 @@
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setLaunchDisplayId(freeformDisplay.mDisplayId);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, /* source */ null, options, mCurrent, mResult));
@@ -526,7 +539,7 @@
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setLaunchDisplayId(DEFAULT_DISPLAY);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, /* source */ null, options, mCurrent, mResult));
@@ -879,7 +892,7 @@
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setLaunchDisplayId(freeformDisplay.mDisplayId);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, /* source */ null, options, mCurrent, mResult));
@@ -903,7 +916,7 @@
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setLaunchDisplayId(freeformDisplay.mDisplayId);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, /* source */ null, options, mCurrent, mResult));
@@ -928,7 +941,7 @@
         final ActivityRecord source = createSourceActivity(freeformDisplay);
         source.setBounds(0, 0, 412, 732);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, source, options, mCurrent, mResult));
@@ -955,7 +968,7 @@
         final ActivityRecord source = createSourceActivity(freeformDisplay);
         source.setBounds(0, 0, 200, 400);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, source, options, mCurrent, mResult));
@@ -977,7 +990,7 @@
         final ActivityRecord source = createSourceActivity(freeformDisplay);
         source.setBounds(1720, 680, 1920, 1080);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, source, options, mCurrent, mResult));
@@ -999,7 +1012,7 @@
         mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
         mCurrent.mBounds.set(100, 200, 2120, 1380);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, /* source */ null, options, mCurrent, mResult));
@@ -1025,7 +1038,7 @@
         mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
         mCurrent.mBounds.set(100, 200, 2120, 1380);
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
                 mActivity, /* source */ null, options, mCurrent, mResult));
@@ -1045,7 +1058,7 @@
         final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
                 .setMinWidth(500).setMinHeight(800).build();
 
-        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+        mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
                 /* source */ null, options, mCurrent, mResult));
@@ -1174,6 +1187,19 @@
     }
 
     @Test
+    public void returnsNonFullscreenBoundsOnFullscreenDisplayWithFreeformHistory() {
+        mCurrent.mPreferredDisplayId = Display.INVALID_DISPLAY;
+        mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+        mCurrent.mBounds.set(0, 0, 200, 100);
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+
+        // Returned bounds with in fullscreen mode will be set to last non-fullscreen bounds.
+        assertEquals(new Rect(0, 0, 200, 100), mResult.mBounds);
+    }
+
+    @Test
     public void testAdjustsBoundsToFitInDisplayFullyResolvedBounds() {
         final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
                 WINDOWING_MODE_FREEFORM);
@@ -1186,7 +1212,7 @@
         options.setLaunchDisplayId(freeformDisplay.mDisplayId);
 
         assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
-                mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+                mActivity, /* source */ null, options, mCurrent, mResult));
 
         assertEquals(new Rect(0, 0, 300, 300), mResult.mBounds);
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 0ecd878..a0302f6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -16,11 +16,13 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
+import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -29,6 +31,9 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 import static org.hamcrest.Matchers.not;
@@ -36,6 +41,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
@@ -51,6 +57,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.DisplayMetrics;
@@ -443,6 +450,342 @@
                 task.isSameIntentFilter(defaultActivity));
     }
 
+    /** Test that root activity index is reported correctly for several activities in the task. */
+    @Test
+    public void testFindRootIndex() {
+        final TaskRecord task = getTestTask();
+        // Add an extra activity on top of the root one
+        new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals("The root activity in the task must be reported.",
+                0, task.findRootIndex(false /* effectiveRoot*/));
+    }
+
+    /**
+     * Test that root activity index is reported correctly for several activities in the task when
+     * the activities on the bottom are finishing.
+     */
+    @Test
+    public void testFindRootIndex_finishing() {
+        final TaskRecord task = getTestTask();
+        // Add extra two activities and mark the two on the bottom as finishing.
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.finishing = true;
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        activity1.finishing = true;
+        new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals("The first non-finishing activity in the task must be reported.",
+                2, task.findRootIndex(false /* effectiveRoot*/));
+    }
+
+    /**
+     * Test that root activity index is reported correctly for several activities in the task when
+     * looking for the 'effective root'.
+     */
+    @Test
+    public void testFindRootIndex_effectiveRoot() {
+        final TaskRecord task = getTestTask();
+        // Add an extra activity on top of the root one
+        new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals("The root activity in the task must be reported.",
+                0, task.findRootIndex(true /* effectiveRoot*/));
+    }
+
+    /**
+     * Test that root activity index is reported correctly when looking for the 'effective root' in
+     * case when bottom activities are relinquishing task identity or finishing.
+     */
+    @Test
+    public void testFindRootIndex_effectiveRoot_finishingAndRelinquishing() {
+        final TaskRecord task = getTestTask();
+        // Add extra two activities. Mark the one on the bottom with "relinquishTaskIdentity" and
+        // one above as finishing.
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        activity1.finishing = true;
+        new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals("The first non-finishing activity and non-relinquishing task identity "
+                        + "must be reported.", 2, task.findRootIndex(true /* effectiveRoot*/));
+    }
+
+    /**
+     * Test that root activity index is reported correctly when looking for the 'effective root'
+     * for the case when there is only a single activity that also has relinquishTaskIdentity set.
+     */
+    @Test
+    public void testFindRootIndex_effectiveRoot_relinquishingAndSingleActivity() {
+        final TaskRecord task = getTestTask();
+        // Set relinquishTaskIdentity for the only activity in the task
+        task.getChildAt(0).info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+
+        assertEquals("The root activity in the task must be reported.",
+                0, task.findRootIndex(true /* effectiveRoot*/));
+    }
+
+    /**
+     * Test that the topmost activity index is reported correctly when looking for the
+     * 'effective root' for the case when all activities have relinquishTaskIdentity set.
+     */
+    @Test
+    public void testFindRootIndex_effectiveRoot_relinquishingMultipleActivities() {
+        final TaskRecord task = getTestTask();
+        // Set relinquishTaskIdentity for all activities in the task
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        activity1.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+
+        assertEquals("The topmost activity in the task must be reported.",
+                task.getChildCount() - 1, task.findRootIndex(true /* effectiveRoot*/));
+    }
+
+    /** Test that bottom-most activity is reported in {@link TaskRecord#getRootActivity()}. */
+    @Test
+    public void testGetRootActivity() {
+        final TaskRecord task = getTestTask();
+        // Add an extra activity on top of the root one
+        new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals("The root activity in the task must be reported.",
+                task.getChildAt(0), task.getRootActivity());
+    }
+
+    /**
+     * Test that first non-finishing activity is reported in {@link TaskRecord#getRootActivity()}.
+     */
+    @Test
+    public void testGetRootActivity_finishing() {
+        final TaskRecord task = getTestTask();
+        // Add an extra activity on top of the root one
+        new ActivityBuilder(mService).setTask(task).build();
+        // Mark the root as finishing
+        task.getChildAt(0).finishing = true;
+
+        assertEquals("The first non-finishing activity in the task must be reported.",
+                task.getChildAt(1), task.getRootActivity());
+    }
+
+    /**
+     * Test that relinquishTaskIdentity flag is ignored in {@link TaskRecord#getRootActivity()}.
+     */
+    @Test
+    public void testGetRootActivity_relinquishTaskIdentity() {
+        final TaskRecord task = getTestTask();
+        // Mark the bottom-most activity with FLAG_RELINQUISH_TASK_IDENTITY.
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+        // Add an extra activity on top of the root one.
+        new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals("The root activity in the task must be reported.",
+                task.getChildAt(0), task.getRootActivity());
+    }
+
+    /**
+     * Test that no activity is reported in {@link TaskRecord#getRootActivity()} when all activities
+     * in the task are finishing.
+     */
+    @Test
+    public void testGetRootActivity_allFinishing() {
+        final TaskRecord task = getTestTask();
+        // Mark the bottom-most activity as finishing.
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one and mark it as finishing
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        activity1.finishing = true;
+
+        assertNull("No activity must be reported if all are finishing", task.getRootActivity());
+    }
+
+    /**
+     * Test that first non-finishing activity is the root of task.
+     */
+    @Test
+    public void testIsRootActivity() {
+        final TaskRecord task = getTestTask();
+        // Mark the bottom-most activity as finishing.
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one.
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+
+        assertFalse("Finishing activity must not be the root of task", activity0.isRootOfTask());
+        assertTrue("Non-finishing activity must be the root of task", activity1.isRootOfTask());
+    }
+
+    /**
+     * Test that if all activities in the task are finishing, then the one on the bottom is the
+     * root of task.
+     */
+    @Test
+    public void testIsRootActivity_allFinishing() {
+        final TaskRecord task = getTestTask();
+        // Mark the bottom-most activity as finishing.
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one and mark it as finishing
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        activity1.finishing = true;
+
+        assertTrue("Bottom activity must be the root of task", activity0.isRootOfTask());
+        assertFalse("Finishing activity on top must not be the root of task",
+                activity1.isRootOfTask());
+    }
+
+    /**
+     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)}.
+     */
+    @Test
+    public void testGetTaskForActivity() {
+        final TaskRecord task0 = getTestTask();
+        final ActivityRecord activity0 = task0.getChildAt(0);
+
+        final TaskRecord task1 = getTestTask();
+        final ActivityRecord activity1 = task0.getChildAt(0);
+
+        assertEquals(task0.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
+        assertEquals(task1.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity1.appToken,  false /* onlyRoot */));
+    }
+
+    /**
+     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} with finishing
+     * activity.
+     */
+    @Test
+    public void testGetTaskForActivity_onlyRoot_finishing() {
+        final TaskRecord task = getTestTask();
+        // Make the current root activity finishing
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.finishing = true;
+        // Add an extra activity on top - this will be the new root
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        // Add one more on top
+        final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals(task.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
+        assertEquals(task.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity1.appToken, true /* onlyRoot */));
+        assertEquals("No task must be reported for activity that is above root", INVALID_TASK_ID,
+                ActivityRecord.getTaskForActivityLocked(activity2.appToken, true /* onlyRoot */));
+    }
+
+    /**
+     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} with activity that
+     * relinquishes task identity.
+     */
+    @Test
+    public void testGetTaskForActivity_onlyRoot_relinquishTaskIdentity() {
+        final TaskRecord task = getTestTask();
+        // Make the current root activity relinquish task identity
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+        // Add an extra activity on top - this will be the new root
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        // Add one more on top
+        final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals(task.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity0.appToken, true /* onlyRoot */));
+        assertEquals(task.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity1.appToken, true /* onlyRoot */));
+        assertEquals("No task must be reported for activity that is above root", INVALID_TASK_ID,
+                ActivityRecord.getTaskForActivityLocked(activity2.appToken, true /* onlyRoot */));
+    }
+
+    /**
+     * Test {@link ActivityRecord#getTaskForActivityLocked(IBinder, boolean)} allowing non-root
+     * entries.
+     */
+    @Test
+    public void testGetTaskForActivity_notOnlyRoot() {
+        final TaskRecord task = getTestTask();
+        // Mark the bottom-most activity as finishing.
+        final ActivityRecord activity0 = task.getChildAt(0);
+        activity0.finishing = true;
+
+        // Add an extra activity on top of the root one and make it relinquish task identity
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        activity1.info.flags |= FLAG_RELINQUISH_TASK_IDENTITY;
+
+        // Add one more activity on top
+        final ActivityRecord activity2 = new ActivityBuilder(mService).setTask(task).build();
+
+        assertEquals(task.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity0.appToken, false /* onlyRoot */));
+        assertEquals(task.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity1.appToken, false /* onlyRoot */));
+        assertEquals(task.taskId,
+                ActivityRecord.getTaskForActivityLocked(activity2.appToken, false /* onlyRoot */));
+    }
+
+    /**
+     * Test {@link TaskRecord#updateEffectiveIntent()}.
+     */
+    @Test
+    public void testUpdateEffectiveIntent() {
+        // Test simple case with a single activity.
+        final TaskRecord task = getTestTask();
+        final ActivityRecord activity0 = task.getChildAt(0);
+
+        spyOn(task);
+        task.updateEffectiveIntent();
+        verify(task).setIntent(eq(activity0));
+    }
+
+    /**
+     * Test {@link TaskRecord#updateEffectiveIntent()} with root activity marked as finishing. This
+     * should make the task use the second activity when updating the intent.
+     */
+    @Test
+    public void testUpdateEffectiveIntent_rootFinishing() {
+        // Test simple case with a single activity.
+        final TaskRecord task = getTestTask();
+        final ActivityRecord activity0 = task.getChildAt(0);
+        // Mark the bottom-most activity as finishing.
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+
+        spyOn(task);
+        task.updateEffectiveIntent();
+        verify(task).setIntent(eq(activity1));
+    }
+
+    /**
+     * Test {@link TaskRecord#updateEffectiveIntent()} when all activities are finishing or
+     * relinquishing task identity. In this case the root activity should still be used when
+     * updating the intent (legacy behavior).
+     */
+    @Test
+    public void testUpdateEffectiveIntent_allFinishing() {
+        // Test simple case with a single activity.
+        final TaskRecord task = getTestTask();
+        final ActivityRecord activity0 = task.getChildAt(0);
+        // Mark the bottom-most activity as finishing.
+        activity0.finishing = true;
+        // Add an extra activity on top of the root one and make it relinquish task identity
+        final ActivityRecord activity1 = new ActivityBuilder(mService).setTask(task).build();
+        activity1.finishing = true;
+
+        // Task must still update the intent using the root activity (preserving legacy behavior).
+        spyOn(task);
+        task.updateEffectiveIntent();
+        verify(task).setIntent(eq(activity0));
+    }
+
+    private TaskRecord getTestTask() {
+        final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
+        return stack.getChildAt(0);
+    }
+
     private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,
             Rect expectedConfigBounds) {
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index b0eafee..b29453a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -64,6 +64,7 @@
         assertTrueForFiles(files, File::exists, " must exist");
         final TaskSnapshot snapshot = mLoader.loadTask(1, mTestUserId, false /* reduced */);
         assertNotNull(snapshot);
+        assertEquals(MOCK_SNAPSHOT_ID, snapshot.getId());
         assertEquals(TEST_INSETS, snapshot.getContentInsets());
         assertNotNull(snapshot.getSnapshot());
         assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
@@ -145,7 +146,10 @@
 
     @Test
     public void testLowResolutionPersistAndLoadSnapshot() {
-        TaskSnapshot a = createSnapshot(0.5f /* reducedResolution */);
+        TaskSnapshot a = new TaskSnapshotBuilder()
+                .setScale(0.5f)
+                .setReducedResolution(true)
+                .build();
         assertTrue(a.isReducedResolution());
         mPersister.persistSnapshot(1 , mTestUserId, a);
         mPersister.waitForQueueEmpty();
@@ -253,6 +257,27 @@
     }
 
     @Test
+    public void testScalePersistAndLoadSnapshot() {
+        TaskSnapshot a = new TaskSnapshotBuilder()
+                .setScale(0.25f)
+                .build();
+        TaskSnapshot b = new TaskSnapshotBuilder()
+                .setScale(0.75f)
+                .build();
+        assertEquals(0.25f, a.getScale(), 1E-5);
+        assertEquals(0.75f, b.getScale(), 1E-5);
+        mPersister.persistSnapshot(1, mTestUserId, a);
+        mPersister.persistSnapshot(2, mTestUserId, b);
+        mPersister.waitForQueueEmpty();
+        final TaskSnapshot snapshotA = mLoader.loadTask(1, mTestUserId, false /* reduced */);
+        final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */);
+        assertNotNull(snapshotA);
+        assertNotNull(snapshotB);
+        assertEquals(0.25f, snapshotA.getScale(), 1E-5);
+        assertEquals(0.75f, snapshotB.getScale(), 1E-5);
+    }
+
+    @Test
     public void testRemoveObsoleteFiles() {
         mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
         mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index c3b0a67..f749622 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -45,6 +45,7 @@
 
     private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
     static final File FILES_DIR = getInstrumentation().getTargetContext().getFilesDir();
+    static final long MOCK_SNAPSHOT_ID = 12345678;
 
     TaskSnapshotPersister mPersister;
     TaskSnapshotLoader mLoader;
@@ -77,12 +78,7 @@
     }
 
     TaskSnapshot createSnapshot() {
-        return createSnapshot(1f /* scale */);
-    }
-
-    TaskSnapshot createSnapshot(float scale) {
         return new TaskSnapshotBuilder()
-                .setScale(scale)
                 .build();
     }
 
@@ -92,6 +88,7 @@
     static class TaskSnapshotBuilder {
 
         private float mScale = 1f;
+        private boolean mReducedResolution = false;
         private boolean mIsRealSnapshot = true;
         private boolean mIsTranslucent = false;
         private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
@@ -102,6 +99,11 @@
             return this;
         }
 
+        TaskSnapshotBuilder setReducedResolution(boolean reducedResolution) {
+            mReducedResolution = reducedResolution;
+            return this;
+        }
+
         TaskSnapshotBuilder setIsRealSnapshot(boolean isRealSnapshot) {
             mIsRealSnapshot = isRealSnapshot;
             return this;
@@ -128,9 +130,9 @@
             Canvas c = buffer.lockCanvas();
             c.drawColor(Color.RED);
             buffer.unlockCanvasAndPost(c);
-            return new TaskSnapshot(new ComponentName("", ""), buffer,
+            return new TaskSnapshot(MOCK_SNAPSHOT_ID, new ComponentName("", ""), buffer,
                     ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, TEST_INSETS,
-                    mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot,
+                    mReducedResolution, mScale, mIsRealSnapshot,
                     mWindowingMode, mSystemUiVisibility, mIsTranslucent);
         }
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index 4ca01ec..74db820 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -64,7 +64,9 @@
             int windowFlags, Rect taskBounds) {
         final GraphicBuffer buffer = GraphicBuffer.create(width, height, PixelFormat.RGBA_8888,
                 GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
-        final TaskSnapshot snapshot = new TaskSnapshot(new ComponentName("", ""), buffer,
+        final TaskSnapshot snapshot = new TaskSnapshot(
+                System.currentTimeMillis(),
+                new ComponentName("", ""), buffer,
                 ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT, contentInsets, false,
                 1.0f, true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN,
                 0 /* systemUiVisibility */, false /* isTranslucent */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index c3561f4..2e5ce69 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -49,6 +49,7 @@
 
     int mRotationToReport = 0;
     boolean mKeyguardShowingAndNotOccluded = false;
+    boolean mOkToAnimate = true;
 
     private Runnable mRunnableWhenAddingSplashScreen;
 
@@ -141,7 +142,7 @@
 
     @Override
     public Animation createHiddenByKeyguardExit(boolean onWallpaper,
-            boolean goingToNotificationShade) {
+            boolean goingToNotificationShade, boolean subtleAnimation) {
         return null;
     }
 
@@ -222,7 +223,7 @@
 
     @Override
     public boolean okToAnimate() {
-        return true;
+        return mOkToAnimate;
     }
 
     @Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index b93c994..acfc2ea 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -114,16 +114,12 @@
     @Test
     public void testAddChildSetsSurfacePosition() {
         try (MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer(mWm)) {
-
-            final SurfaceControl.Transaction transaction = mock(SurfaceControl.Transaction.class);
-            mWm.mTransactionFactory = () -> transaction;
-
             WindowContainer child = new WindowContainer(mWm);
             child.setBounds(1, 1, 10, 10);
 
-            verify(transaction, never()).setPosition(any(), anyFloat(), anyFloat());
+            verify(mTransaction, never()).setPosition(any(), anyFloat(), anyFloat());
             top.addChild(child, 0);
-            verify(transaction, times(1)).setPosition(any(), eq(1.f), eq(1.f));
+            verify(mTransaction, times(1)).setPosition(any(), eq(1.f), eq(1.f));
         }
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 3a8d3b7..36698ea 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -18,6 +18,7 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
 import static android.view.InsetsState.TYPE_TOP_BAR;
 import static android.view.Surface.ROTATION_0;
@@ -36,6 +37,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 
 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.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
@@ -249,6 +251,23 @@
         // Invisible window can't be IME targets even if they have the right flags.
         assertFalse(appWindow.canBeImeTarget());
         assertFalse(imeWindow.canBeImeTarget());
+
+        // Simulate the window is in split screen primary stack and the current state is
+        // minimized and home stack is resizable, so that we should ignore input for the stack.
+        final DockedStackDividerController controller =
+                mDisplayContent.getDockedDividerController();
+        final TaskStack stack = createTaskStackOnDisplay(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY,
+                ACTIVITY_TYPE_STANDARD, mDisplayContent);
+        spyOn(appWindow);
+        spyOn(controller);
+        spyOn(stack);
+        doReturn(true).when(controller).isMinimizedDock();
+        doReturn(true).when(controller).isHomeStackResizable();
+        doReturn(stack).when(appWindow).getStack();
+
+        // Make sure canBeImeTarget is false due to shouldIgnoreInput is true;
+        assertFalse(appWindow.canBeImeTarget());
+        assertTrue(stack.shouldIgnoreInput());
     }
 
     @Test
@@ -283,43 +302,38 @@
 
     @Test
     public void testPrepareWindowToDisplayDuringRelayout() {
-        testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);
-
-        // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON
-        // before calling prepareWindowToDisplayDuringRelayout for windows with flag in the same
-        // appWindowToken.
+        // Call prepareWindowToDisplayDuringRelayout for a window without FLAG_TURN_SCREEN_ON before
+        // calling setCurrentLaunchCanTurnScreenOn for windows with flag in the same appWindowToken.
         final AppWindowToken appWindowToken = createAppWindowToken(mDisplayContent,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         final WindowState first = createWindow(null, TYPE_APPLICATION, appWindowToken, "first");
         final WindowState second = createWindow(null, TYPE_APPLICATION, appWindowToken, "second");
         second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
 
-        reset(sPowerManagerWrapper);
-        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
-        assertTrue(appWindowToken.canTurnScreenOn());
-
-        reset(sPowerManagerWrapper);
-        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
-        assertFalse(appWindowToken.canTurnScreenOn());
+        testPrepareWindowToDisplayDuringRelayout(first, false /* expectedWakeupCalled */,
+                true /* expectedCurrentLaunchCanTurnScreenOn */);
+        testPrepareWindowToDisplayDuringRelayout(second, true /* expectedWakeupCalled */,
+                false /* expectedCurrentLaunchCanTurnScreenOn */);
 
         // Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
         // from the same appWindowToken. Only one should trigger the wakeup.
-        appWindowToken.setCanTurnScreenOn(true);
+        appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
         first.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
         second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
 
-        reset(sPowerManagerWrapper);
-        first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
-        assertFalse(appWindowToken.canTurnScreenOn());
+        testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
+                false /* expectedCurrentLaunchCanTurnScreenOn */);
+        testPrepareWindowToDisplayDuringRelayout(second, false /* expectedWakeupCalled */,
+                false /* expectedCurrentLaunchCanTurnScreenOn */);
 
-        reset(sPowerManagerWrapper);
-        second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
-        verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
-        assertFalse(appWindowToken.canTurnScreenOn());
+        // Without window flags, the state of ActivityRecord.canTurnScreenOn should still be able to
+        // turn on the screen.
+        appWindowToken.setCurrentLaunchCanTurnScreenOn(true);
+        first.mAttrs.flags &= ~WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
+        doReturn(true).when(appWindowToken.mActivityRecord).canTurnScreenOn();
+
+        testPrepareWindowToDisplayDuringRelayout(first, true /* expectedWakeupCalled */,
+                false /* expectedCurrentLaunchCanTurnScreenOn */);
 
         // Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
         // appWindowToken. Both windows have the FLAG_TURNS_SCREEN_ON so both should call wakeup
@@ -341,6 +355,22 @@
         verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
     }
 
+    private void testPrepareWindowToDisplayDuringRelayout(WindowState appWindow,
+            boolean expectedWakeupCalled, boolean expectedCurrentLaunchCanTurnScreenOn) {
+        reset(sPowerManagerWrapper);
+        appWindow.prepareWindowToDisplayDuringRelayout(false /* wasVisible */);
+
+        if (expectedWakeupCalled) {
+            verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
+        } else {
+            verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
+        }
+        // If wakeup is expected to be called, the currentLaunchCanTurnScreenOn should be false
+        // because the state will be consumed.
+        assertThat(appWindow.mAppToken.currentLaunchCanTurnScreenOn(),
+                is(expectedCurrentLaunchCanTurnScreenOn));
+    }
+
     @Test
     public void testCanAffectSystemUiFlags() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
@@ -468,15 +498,6 @@
         assertThat(app.getWmDisplayCutout().getDisplayCutout(), is(cutout.inset(7, 10, 5, 20)));
     }
 
-    private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
-        reset(sPowerManagerWrapper);
-        final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
-        root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
-
-        root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
-        verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
-    }
-
     @Test
     public void testVisibilityChangeSwitchUser() {
         final WindowState window = createWindow(null, TYPE_APPLICATION, "app");
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 3a702cb9..dc461d1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -435,7 +435,9 @@
             // Display creation is driven by DisplayWindowController via ActivityStackSupervisor.
             // We skip those steps here.
             final ActivityDisplay mockAd = mock(ActivityDisplay.class);
-            return mWm.mRoot.createDisplayContent(display, mockAd);
+            final DisplayContent displayContent = mWm.mRoot.createDisplayContent(display, mockAd);
+            displayContent.reconfigureDisplayLocked();
+            return displayContent;
         }
     }
 
diff --git a/services/usage/java/com/android/server/usage/UsageStatsProto.java b/services/usage/java/com/android/server/usage/UsageStatsProto.java
index 63bf7e7..3e88d93 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsProto.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsProto.java
@@ -44,7 +44,7 @@
 
         final long token = proto.start(IntervalStatsProto.STRINGPOOL);
         List<String> stringPool;
-        if (proto.isNextField(IntervalStatsProto.StringPool.SIZE)) {
+        if (proto.nextField(IntervalStatsProto.StringPool.SIZE)) {
             stringPool = new ArrayList(proto.readInt(IntervalStatsProto.StringPool.SIZE));
         } else {
             stringPool = new ArrayList();
@@ -66,12 +66,12 @@
 
         final long token = proto.start(fieldId);
         UsageStats stats;
-        if (proto.isNextField(IntervalStatsProto.UsageStats.PACKAGE_INDEX)) {
+        if (proto.nextField(IntervalStatsProto.UsageStats.PACKAGE_INDEX)) {
             // Fast path reading the package name index. Most cases this should work since it is
             // written first
             stats = statsOut.getOrCreateUsageStats(
                     stringPool.get(proto.readInt(IntervalStatsProto.UsageStats.PACKAGE_INDEX) - 1));
-        } else if (proto.isNextField(IntervalStatsProto.UsageStats.PACKAGE)) {
+        } else if (proto.nextField(IntervalStatsProto.UsageStats.PACKAGE)) {
             // No package index, try package name instead
             stats = statsOut.getOrCreateUsageStats(
                     proto.readString(IntervalStatsProto.UsageStats.PACKAGE));
@@ -177,7 +177,7 @@
         }
         String action = null;
         ArrayMap<String, Integer> counts;
-        if (proto.isNextField(IntervalStatsProto.UsageStats.ChooserAction.NAME)) {
+        if (proto.nextField(IntervalStatsProto.UsageStats.ChooserAction.NAME)) {
             // Fast path reading the action name. Most cases this should work since it is written
             // first
             action = proto.readString(IntervalStatsProto.UsageStats.ChooserAction.NAME);
@@ -244,7 +244,7 @@
         boolean configActive = false;
         final Configuration config = new Configuration();
         ConfigurationStats configStats;
-        if (proto.isNextField(IntervalStatsProto.Configuration.CONFIG)) {
+        if (proto.nextField(IntervalStatsProto.Configuration.CONFIG)) {
             // Fast path reading the configuration. Most cases this should work since it is
             // written first
             config.readFromProto(proto, IntervalStatsProto.Configuration.CONFIG);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 5b7d816..7f7a78b 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -909,6 +909,8 @@
                     if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
                         // If the screen is unlocked, also set current functions.
                         setScreenUnlockedFunctions();
+                    } else {
+                        setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
                     }
                     break;
                 case MSG_UPDATE_SCREEN_LOCK:
@@ -1196,7 +1198,8 @@
                             intent, 0, null, UserHandle.CURRENT);
 
                     Notification notification =
-                            new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
+                            new Notification.Builder(mContext,
+                                    SystemNotificationChannels.DEVELOPER_IMPORTANT)
                                     .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                                     .setWhen(0)
                                     .setOngoing(true)
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 7a83469..a8cafb3 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -61,6 +61,7 @@
 import android.os.ParcelUuid;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.ArrayMap;
@@ -75,6 +76,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Map;
 import java.util.TreeMap;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
@@ -102,6 +104,80 @@
     private Object mCallbacksLock;
     private final TreeMap<UUID, IRecognitionStatusCallback> mCallbacks;
 
+    class SoundModelStatTracker {
+        private class SoundModelStat {
+            SoundModelStat() {
+                mStartCount = 0;
+                mTotalTimeMsec = 0;
+                mLastStartTimestampMsec = 0;
+                mLastStopTimestampMsec = 0;
+                mIsStarted = false;
+            }
+            long mStartCount; // Number of times that given model started
+            long mTotalTimeMsec; // Total time (msec) that given model was running since boot
+            long mLastStartTimestampMsec; // SystemClock.elapsedRealtime model was last started
+            long mLastStopTimestampMsec; // SystemClock.elapsedRealtime model was last stopped
+            boolean mIsStarted; // true if model is currently running
+        }
+        private final TreeMap<UUID, SoundModelStat> mModelStats;
+
+        SoundModelStatTracker() {
+            mModelStats = new TreeMap<UUID, SoundModelStat>();
+        }
+
+        public synchronized void onStart(UUID id) {
+            SoundModelStat stat = mModelStats.get(id);
+            if (stat == null) {
+                stat = new SoundModelStat();
+                mModelStats.put(id, stat);
+            }
+
+            if (stat.mIsStarted) {
+                Slog.e(TAG, "error onStart(): Model " + id + " already started");
+                return;
+            }
+
+            stat.mStartCount++;
+            stat.mLastStartTimestampMsec = SystemClock.elapsedRealtime();
+            stat.mIsStarted = true;
+        }
+
+        public synchronized void onStop(UUID id) {
+            SoundModelStat stat = mModelStats.get(id);
+            if (stat == null) {
+                Slog.e(TAG, "error onStop(): Model " + id + " has no stats available");
+                return;
+            }
+
+            if (!stat.mIsStarted) {
+                Slog.e(TAG, "error onStop(): Model " + id + " already stopped");
+                return;
+            }
+
+            stat.mLastStopTimestampMsec = SystemClock.elapsedRealtime();
+            stat.mTotalTimeMsec += stat.mLastStopTimestampMsec - stat.mLastStartTimestampMsec;
+            stat.mIsStarted = false;
+        }
+
+        public synchronized void dump(PrintWriter pw) {
+            long curTime = SystemClock.elapsedRealtime();
+            pw.println("Model Stats:");
+            for (Map.Entry<UUID, SoundModelStat> entry : mModelStats.entrySet()) {
+                UUID uuid = entry.getKey();
+                SoundModelStat stat = entry.getValue();
+                long totalTimeMsec = stat.mTotalTimeMsec;
+                if (stat.mIsStarted) {
+                    totalTimeMsec += curTime - stat.mLastStartTimestampMsec;
+                }
+                pw.println(uuid + ", total_time(msec)=" + totalTimeMsec
+                        + ", total_count=" + stat.mStartCount
+                        + ", last_start=" + stat.mLastStartTimestampMsec
+                        + ", last_stop=" + stat.mLastStopTimestampMsec);
+            }
+        }
+    }
+
+    private final SoundModelStatTracker mSoundModelStatTracker;
     /** Number of ops run by the {@link RemoteSoundTriggerDetectionService} per package name */
     @GuardedBy("mLock")
     private final ArrayMap<String, NumOps> mNumOpsPerPackage = new ArrayMap<>();
@@ -115,6 +191,7 @@
         mCallbacksLock = new Object();
         mCallbacks = new TreeMap<>();
         mLock = new Object();
+        mSoundModelStatTracker = new SoundModelStatTracker();
     }
 
     @Override
@@ -193,8 +270,12 @@
                 return STATUS_ERROR;
             }
 
-            return mSoundTriggerHelper.startGenericRecognition(parcelUuid.getUuid(), model,
+            int ret = mSoundTriggerHelper.startGenericRecognition(parcelUuid.getUuid(), model,
                     callback, config);
+            if (ret == STATUS_OK) {
+                mSoundModelStatTracker.onStart(parcelUuid.getUuid());
+            }
+            return ret;
         }
 
         @Override
@@ -208,7 +289,12 @@
                     + parcelUuid));
 
             if (!isInitialized()) return STATUS_ERROR;
-            return mSoundTriggerHelper.stopGenericRecognition(parcelUuid.getUuid(), callback);
+
+            int ret = mSoundTriggerHelper.stopGenericRecognition(parcelUuid.getUuid(), callback);
+            if (ret == STATUS_OK) {
+                mSoundModelStatTracker.onStop(parcelUuid.getUuid());
+            }
+            return ret;
         }
 
         @Override
@@ -252,6 +338,9 @@
             // Unload the model if it is loaded.
             mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid());
             mDbHelper.deleteGenericSoundModel(soundModelId.getUuid());
+
+            // Stop recognition if it is started.
+            mSoundModelStatTracker.onStop(soundModelId.getUuid());
         }
 
         @Override
@@ -403,6 +492,8 @@
                 synchronized (mCallbacksLock) {
                     mCallbacks.put(soundModelId.getUuid(), callback);
                 }
+
+                mSoundModelStatTracker.onStart(soundModelId.getUuid());
             }
             return STATUS_OK;
         }
@@ -467,6 +558,8 @@
                 synchronized (mCallbacksLock) {
                     mCallbacks.remove(soundModelId.getUuid());
                 }
+
+                mSoundModelStatTracker.onStop(soundModelId.getUuid());
             }
             return STATUS_OK;
         }
@@ -1266,6 +1359,9 @@
             mSoundTriggerHelper.dump(fd, pw, args);
             // log
             sEventLogger.dump(pw);
+
+            // stats
+            mSoundModelStatTracker.dump(pw);
         }
 
         private synchronized boolean isInitialized() {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index d77ea6e..b2fde54 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -33,7 +33,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.ShortcutServiceInternal;
@@ -77,9 +76,9 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
-import com.android.server.SystemServerInitThreadPool;
 import com.android.server.SystemService;
 import com.android.server.UiThread;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.soundtrigger.SoundTriggerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
@@ -121,10 +120,10 @@
         mUserManager = Preconditions.checkNotNull(
                 context.getSystemService(UserManager.class));
 
-        PackageManagerInternal packageManagerInternal = LocalServices.getService(
-                PackageManagerInternal.class);
-        packageManagerInternal.setVoiceInteractionPackagesProvider(
-                new PackageManagerInternal.PackagesProvider() {
+        PermissionManagerServiceInternal permissionManagerInternal = LocalServices.getService(
+                PermissionManagerServiceInternal.class);
+        permissionManagerInternal.setVoiceInteractionPackagesProvider(
+                new PermissionManagerServiceInternal.PackagesProvider() {
             @Override
             public String[] getPackages(int userId) {
                 mServiceStub.initForUser(userId);
@@ -1284,9 +1283,7 @@
                 mRm.addOnRoleHoldersChangedListenerAsUser(executor, this, UserHandle.ALL);
                 UserHandle currentUser = UserHandle.of(LocalServices.getService(
                         ActivityManagerInternal.class).getCurrentUserId());
-                SystemServerInitThreadPool.get().submit(() -> onRoleHoldersChanged(
-                        RoleManager.ROLE_ASSISTANT, currentUser),
-                        "VoiceInteractionManagerService RoleObserver initialization");
+                onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser);
             }
 
             private @NonNull String getDefaultRecognizer(@NonNull UserHandle user) {
diff --git a/startop/OWNERS b/startop/OWNERS
index 5cf9582..3394be9 100644
--- a/startop/OWNERS
+++ b/startop/OWNERS
@@ -4,3 +4,4 @@
 iam@google.com
 mathieuc@google.com
 sehr@google.com
+yawanng@google.com
diff --git a/startop/apps/ColorChanging/.gitignore b/startop/apps/ColorChanging/.gitignore
new file mode 100644
index 0000000..2b75303
--- /dev/null
+++ b/startop/apps/ColorChanging/.gitignore
@@ -0,0 +1,13 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/startop/apps/ColorChanging/.idea/encodings.xml b/startop/apps/ColorChanging/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/startop/apps/ColorChanging/.idea/encodings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" addBOMForNewFiles="with NO BOM" />
+</project>
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/.idea/gradle.xml b/startop/apps/ColorChanging/.idea/gradle.xml
new file mode 100644
index 0000000..2996d53
--- /dev/null
+++ b/startop/apps/ColorChanging/.idea/gradle.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <compositeConfiguration>
+          <compositeBuild compositeDefinitionSource="SCRIPT" />
+        </compositeConfiguration>
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="resolveModulePerSourceSet" value="false" />
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/.idea/misc.xml b/startop/apps/ColorChanging/.idea/misc.xml
new file mode 100644
index 0000000..37a7509
--- /dev/null
+++ b/startop/apps/ColorChanging/.idea/misc.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/.idea/runConfigurations.xml b/startop/apps/ColorChanging/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/startop/apps/ColorChanging/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RunConfigurationProducerService">
+    <option name="ignoredProducers">
+      <set>
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
+        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
+      </set>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/README.md b/startop/apps/ColorChanging/README.md
new file mode 100644
index 0000000..eb8b9cc
--- /dev/null
+++ b/startop/apps/ColorChanging/README.md
@@ -0,0 +1,5 @@
+This directory contains a simple Android app that is meant to help in 
+syncing a trace along with a video in Perfetto.
+
+This app changes the colors of the screen that has traces to go along
+with the colors.
diff --git a/startop/apps/ColorChanging/app/.gitignore b/startop/apps/ColorChanging/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/startop/apps/ColorChanging/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/startop/apps/ColorChanging/app/build.gradle b/startop/apps/ColorChanging/app/build.gradle
new file mode 100644
index 0000000..ab955aa
--- /dev/null
+++ b/startop/apps/ColorChanging/app/build.gradle
@@ -0,0 +1,29 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 29
+    buildToolsVersion "29.0.0"
+    defaultConfig {
+        applicationId "com.android.startop.colorchanging"
+        minSdkVersion 15
+        targetSdkVersion 29
+        versionCode 1
+        versionName "1.0"
+        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    implementation 'androidx.appcompat:appcompat:1.0.2'
+    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+    testImplementation 'junit:junit:4.12'
+    androidTestImplementation 'androidx.test:runner:1.2.0'
+    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+}
diff --git a/startop/apps/ColorChanging/app/proguard-rules.pro b/startop/apps/ColorChanging/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/startop/apps/ColorChanging/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/startop/apps/ColorChanging/app/src/androidTest/java/com/android/startop/colorchanging/ExampleInstrumentedTest.java b/startop/apps/ColorChanging/app/src/androidTest/java/com/android/startop/colorchanging/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..31736f3
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/androidTest/java/com/android/startop/colorchanging/ExampleInstrumentedTest.java
@@ -0,0 +1,27 @@
+package com.android.startop.colorchanging;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.android.startop.colorchanging", appContext.getPackageName());
+    }
+}
diff --git a/startop/apps/ColorChanging/app/src/main/AndroidManifest.xml b/startop/apps/ColorChanging/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..37193b5
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.startop.colorchanging">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+        <activity android:name="com.android.startop.colorchanging.MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/app/src/main/java/com/android/startop/colorchanging/MainActivity.java b/startop/apps/ColorChanging/app/src/main/java/com/android/startop/colorchanging/MainActivity.java
new file mode 100644
index 0000000..b8f4faf
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/java/com/android/startop/colorchanging/MainActivity.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.startop.colorchanging;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+import android.os.Trace;
+import android.view.View;
+
+public class MainActivity extends AppCompatActivity {
+    View view;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        view = this.getWindow().getDecorView();
+        view.setBackgroundResource(R.color.gray);
+        Trace.beginSection("gray");
+    }
+
+    public void goRed(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.red);
+        Trace.beginSection("red");
+    }
+
+    public void goOrange(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.orange);
+        Trace.beginSection("orange");
+    }
+
+    public void goYellow(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.yellow);
+        Trace.beginSection("yellow");
+    }
+
+    public void goGreen(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.green);
+        Trace.beginSection("green");
+    }
+
+    public void goBlue(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.blue);
+        Trace.beginSection("blue");
+    }
+
+    public void goIndigo(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.indigo);
+        Trace.beginSection("indigo");
+    }
+
+    public void goViolet(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.violet);
+        Trace.beginSection("violet");
+    }
+
+    public void goCyan(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.cyan);
+        Trace.beginSection("cyan");
+    }
+
+    public void goBlack(View v) {
+        Trace.endSection();
+        view.setBackgroundResource(R.color.black);
+        Trace.beginSection("black");
+    }
+
+}
diff --git a/startop/apps/ColorChanging/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/startop/apps/ColorChanging/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..1f6bb29
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillType="evenOdd"
+        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="78.5885"
+                android:endY="90.9159"
+                android:startX="48.7653"
+                android:startY="61.0927"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
+        android:strokeWidth="1"
+        android:strokeColor="#00000000" />
+</vector>
diff --git a/startop/apps/ColorChanging/app/src/main/res/drawable/ic_launcher_background.xml b/startop/apps/ColorChanging/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..0d025f9
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportWidth="108"
+    android:viewportHeight="108">
+    <path
+        android:fillColor="#008577"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeWidth="0.8"
+        android:strokeColor="#33FFFFFF" />
+</vector>
diff --git a/startop/apps/ColorChanging/app/src/main/res/layout/activity_main.xml b/startop/apps/ColorChanging/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..fb18df7
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity">
+
+    <Button
+        android:id="@+id/button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:layout_marginLeft="16dp"
+        android:layout_marginTop="16dp"
+        android:onClick="goRed"
+        android:text="red"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <Button
+        android:id="@+id/button4"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginRight="16dp"
+        android:onClick="goYellow"
+        android:text="YELLOW"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <Button
+        android:id="@+id/button6"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="16dp"
+        android:layout_marginLeft="16dp"
+        android:layout_marginTop="32dp"
+        android:onClick="goGreen"
+        android:text="GREEN"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/button" />
+
+    <Button
+        android:id="@+id/button7"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="165dp"
+        android:layout_marginLeft="165dp"
+        android:layout_marginTop="115dp"
+        android:layout_marginEnd="165dp"
+        android:layout_marginRight="165dp"
+        android:onClick="goViolet"
+        android:text="VIOLET"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintHorizontal_bias="0.428"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/button8" />
+
+    <Button
+        android:id="@+id/button10"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="165dp"
+        android:layout_marginLeft="165dp"
+        android:layout_marginTop="32dp"
+        android:layout_marginEnd="165dp"
+        android:layout_marginRight="165dp"
+        android:onClick="goBlue"
+        android:text="BLUE"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/button8" />
+
+    <Button
+        android:id="@+id/button8"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="165dp"
+        android:layout_marginLeft="165dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginEnd="165dp"
+        android:layout_marginRight="165dp"
+        android:onClick="goOrange"
+        android:text="ORANGE"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <Button
+        android:id="@+id/button11"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="32dp"
+        android:layout_marginEnd="16dp"
+        android:layout_marginRight="16dp"
+        android:onClick="goIndigo"
+        android:text="INDIGO"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/button4" />
+
+    <Button
+        android:id="@+id/button12"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="162dp"
+        android:layout_marginLeft="162dp"
+        android:layout_marginTop="25dp"
+        android:layout_marginEnd="161dp"
+        android:layout_marginRight="161dp"
+        android:onClick="goCyan"
+        android:text="CYAN"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/button7" />
+
+    <Button
+        android:id="@+id/button13"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="162dp"
+        android:layout_marginLeft="162dp"
+        android:layout_marginTop="25dp"
+        android:layout_marginEnd="161dp"
+        android:layout_marginRight="161dp"
+        android:onClick="goBlack"
+        android:text="BLACK"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/button12" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/startop/apps/ColorChanging/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/startop/apps/ColorChanging/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-hdpi/ic_launcher.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..898f3ed
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dffca36
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-mdpi/ic_launcher.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..64ba76f
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dae5e08
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e5ed465
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..14ed0af
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b0907ca
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ae031
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2c18de9
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/startop/apps/ColorChanging/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..beed3cd
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/ColorChanging/app/src/main/res/values/colors.xml b/startop/apps/ColorChanging/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..209790f
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/values/colors.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#008577</color>
+    <color name="colorPrimaryDark">#00574B</color>
+    <color name="colorAccent">#D81B60</color>
+    <color name="black">#000000</color>
+    <color name="red">#F44336</color>
+    <color name="green">#2CF035</color>
+    <color name="blue">#2C70F0</color>
+    <color name="yellow">#F0EA2C</color>
+    <color name="gray">#D3D3D3</color>
+    <color name="orange">#E57E0A</color>
+    <color name="indigo">#4B0082</color>
+    <color name="violet">#EE82EE</color>
+    <color name="cyan">#00E8FF</color>
+</resources>
diff --git a/startop/apps/ColorChanging/app/src/main/res/values/strings.xml b/startop/apps/ColorChanging/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..ff062fb
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">ColorChanging</string>
+</resources>
diff --git a/startop/apps/ColorChanging/app/src/main/res/values/styles.xml b/startop/apps/ColorChanging/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>
diff --git a/startop/apps/ColorChanging/app/src/test/java/com/android/startop/colorchanging/ExampleUnitTest.java b/startop/apps/ColorChanging/app/src/test/java/com/android/startop/colorchanging/ExampleUnitTest.java
new file mode 100644
index 0000000..8423674
--- /dev/null
+++ b/startop/apps/ColorChanging/app/src/test/java/com/android/startop/colorchanging/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.android.startop.colorchanging;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}
\ No newline at end of file
diff --git a/startop/apps/ColorChanging/build.gradle b/startop/apps/ColorChanging/build.gradle
new file mode 100644
index 0000000..a960ab3
--- /dev/null
+++ b/startop/apps/ColorChanging/build.gradle
@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.4.1'
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}
diff --git a/startop/apps/ColorChanging/gradle.properties b/startop/apps/ColorChanging/gradle.properties
new file mode 100644
index 0000000..199d16e
--- /dev/null
+++ b/startop/apps/ColorChanging/gradle.properties
@@ -0,0 +1,20 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+
diff --git a/startop/apps/ColorChanging/gradle/wrapper/gradle-wrapper.jar b/startop/apps/ColorChanging/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
--- /dev/null
+++ b/startop/apps/ColorChanging/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/startop/apps/ColorChanging/gradle/wrapper/gradle-wrapper.properties b/startop/apps/ColorChanging/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..09f2718
--- /dev/null
+++ b/startop/apps/ColorChanging/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Jun 17 13:40:58 PDT 2019
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
diff --git a/startop/apps/ColorChanging/gradlew b/startop/apps/ColorChanging/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/startop/apps/ColorChanging/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/startop/apps/ColorChanging/gradlew.bat b/startop/apps/ColorChanging/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/startop/apps/ColorChanging/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windows variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/startop/apps/ColorChanging/settings.gradle b/startop/apps/ColorChanging/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/startop/apps/ColorChanging/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/startop/apps/test/Android.bp b/startop/apps/test/Android.bp
new file mode 100644
index 0000000..7a1678a
--- /dev/null
+++ b/startop/apps/test/Android.bp
@@ -0,0 +1,26 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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_app {
+    name: "startop_test_app",
+    srcs: [
+        "src/EmptyActivity.java",
+        "src/LayoutInflationActivity.java",
+        "src/ComplexLayoutInflationActivity.java",
+        "src/FrameLayoutInflationActivity.java",
+        "src/TextViewInflationActivity.java",
+    ],
+}
diff --git a/startop/apps/test/AndroidManifest.xml b/startop/apps/test/AndroidManifest.xml
new file mode 100644
index 0000000..467d8f7
--- /dev/null
+++ b/startop/apps/test/AndroidManifest.xml
@@ -0,0 +1,76 @@
+<?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.startop.test">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true">
+
+        <activity
+            android:label="Complex Layout Test"
+            android:name=".ComplexLayoutInflationActivity"
+            android:exported="true" >
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:label="Empty Activity Layout Test"
+            android:name=".EmptyActivity"
+            android:exported="true" >
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:label="FrameLayout Layout Test"
+            android:name=".FrameLayoutInflationActivity"
+            android:exported="true" >
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:label="TextView Layout Test"
+            android:name=".TextViewInflationActivity"
+            android:exported="true" >
+
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/startop/apps/test/README.md b/startop/apps/test/README.md
new file mode 100644
index 0000000..dadc66a
--- /dev/null
+++ b/startop/apps/test/README.md
@@ -0,0 +1,26 @@
+This directory contains a simple Android app that is meant to help in doing
+controlled startup performance experiments.
+
+This app is structured as a number of activities that each are useful for a
+different aspect of startup testing.
+
+# Activities
+
+## EmptyActivity
+
+This is the simplest possible Android activity. Starting this exercises only the
+system parts of startup without any app-specific behavior.
+
+    adb shell am start -n com.android.startop.test/.EmptyActivity
+
+## LayoutInflation
+
+This activity inflates a reasonably complex layout to see the impact of layout
+inflation. The layout is supported by the viewcompiler, so this can be used for
+testing precompiled layout performance.
+
+The activity adds an `inflate#activity_main` slice to atrace around the time
+spent in view inflation to make it easier to focus on the time spent in view
+inflation.
+
+    adb shell am start -n com.android.startop.test/.ComplexLayoutInflationActivity
diff --git a/startop/apps/test/res/drawable-v24/ic_launcher_foreground.xml b/startop/apps/test/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..c7bd21d
--- /dev/null
+++ b/startop/apps/test/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108">
+    <path
+        android:fillType="evenOdd"
+        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="78.5885"
+                android:endY="90.9159"
+                android:startX="48.7653"
+                android:startY="61.0927"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1" />
+</vector>
diff --git a/startop/apps/test/res/drawable/ic_launcher_background.xml b/startop/apps/test/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..d5fccc5
--- /dev/null
+++ b/startop/apps/test/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108">
+    <path
+        android:fillColor="#26A69A"
+        android:pathData="M0,0h108v108h-108z" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M9,0L9,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,0L19,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,0L29,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,0L39,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,0L49,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,0L59,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,0L69,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,0L79,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M89,0L89,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M99,0L99,108"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,9L108,9"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,19L108,19"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,29L108,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,39L108,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,49L108,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,59L108,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,69L108,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,79L108,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,89L108,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M0,99L108,99"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,29L89,29"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,39L89,39"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,49L89,49"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,59L89,59"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,69L89,69"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M19,79L89,79"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M29,19L29,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M39,19L39,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M49,19L49,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M59,19L59,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M69,19L69,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+    <path
+        android:fillColor="#00000000"
+        android:pathData="M79,19L79,89"
+        android:strokeColor="#33FFFFFF"
+        android:strokeWidth="0.8" />
+</vector>
diff --git a/startop/apps/test/res/layout/activity_main.xml b/startop/apps/test/res/layout/activity_main.xml
new file mode 100644
index 0000000..16f5641f2
--- /dev/null
+++ b/startop/apps/test/res/layout/activity_main.xml
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_weight="0.5"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <CheckBox
+            android:id="@+id/checkBox5"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckBox" />
+
+        <EditText
+            android:id="@+id/myEditText"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText" />
+
+        <EditText
+            android:id="@+id/myEditText2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText" />
+
+        <Button
+            android:id="@+id/myButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <Button
+            android:id="@+id/myButton2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <ProgressBar
+            android:id="@+id/progressBar"
+            style="?android:attr/progressBarStyle"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <CheckBox
+            android:id="@+id/checkBox2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckBox" />
+
+        <RadioButton
+            android:id="@+id/radioButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="RadioButton" />
+
+        <CheckedTextView
+            android:id="@+id/checkedTextView2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckedTextView" />
+
+        <TextView
+            android:id="@+id/textView"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <Switch
+            android:id="@+id/switch1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Switch" />
+
+        <CheckBox
+            android:id="@+id/checkBox3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckBox" />
+
+        <CheckBox
+            android:id="@+id/checkBox4"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckBox" />
+
+        <EditText
+            android:id="@+id/editText2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:ems="10"
+            android:inputType="textPassword" />
+
+        <RadioButton
+            android:id="@+id/radioButton2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="RadioButton" />
+
+        <EditText
+            android:id="@+id/editText3"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:ems="10"
+            android:inputType="numberDecimal" />
+
+        <SearchView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" >
+
+        </SearchView>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_weight="0.5"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <Button
+            android:id="@+id/myButton3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <Button
+            android:id="@+id/myButton4"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <Button
+            android:id="@+id/button14"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <EditText
+            android:id="@+id/myEditText3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText" />
+
+        <Button
+            android:id="@+id/button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Button" />
+
+        <EditText
+            android:id="@+id/myEditText4"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="EditText" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton5"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton4"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ProgressBar
+            android:id="@+id/progressBar2"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <EditText
+            android:id="@+id/editText"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:ems="10"
+            android:inputType="date" />
+
+        <CheckedTextView
+            android:id="@+id/checkedTextView"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CheckedTextView" />
+
+        <SeekBar
+            android:id="@+id/seekBar"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton6"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+        <ToggleButton
+            android:id="@+id/toggleButton7"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="ToggleButton" />
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/startop/apps/test/res/layout/framelayout_list.xml b/startop/apps/test/res/layout/framelayout_list.xml
new file mode 100644
index 0000000..2dd8219
--- /dev/null
+++ b/startop/apps/test/res/layout/framelayout_list.xml
@@ -0,0 +1,5013 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ffaaaaaa" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:background="#ff000000" />
+    </LinearLayout>
+</ScrollView>
diff --git a/startop/apps/test/res/layout/textview_list.xml b/startop/apps/test/res/layout/textview_list.xml
new file mode 100644
index 0000000..1cff5b2
--- /dev/null
+++ b/startop/apps/test/res/layout/textview_list.xml
@@ -0,0 +1,5014 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="TextView" />
+
+    </LinearLayout>
+</ScrollView>
diff --git a/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher.xml b/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
\ No newline at end of file
diff --git a/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher_round.xml b/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/startop/apps/test/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background" />
+    <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
\ No newline at end of file
diff --git a/startop/apps/test/res/mipmap-hdpi/ic_launcher.png b/startop/apps/test/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a2f5908
--- /dev/null
+++ b/startop/apps/test/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-hdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1b52399
--- /dev/null
+++ b/startop/apps/test/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-mdpi/ic_launcher.png b/startop/apps/test/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..ff10afd
--- /dev/null
+++ b/startop/apps/test/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-mdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..115a4c7
--- /dev/null
+++ b/startop/apps/test/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xhdpi/ic_launcher.png b/startop/apps/test/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dcd3cd8
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xhdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..459ca60
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xxhdpi/ic_launcher.png b/startop/apps/test/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..8ca12fe
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xxhdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8e19b41
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher.png b/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b824ebd
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher_round.png b/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4c19a13
--- /dev/null
+++ b/startop/apps/test/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/startop/apps/test/res/values/colors.xml b/startop/apps/test/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/startop/apps/test/res/values/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>
diff --git a/startop/apps/test/res/values/strings.xml b/startop/apps/test/res/values/strings.xml
new file mode 100644
index 0000000..18419b5
--- /dev/null
+++ b/startop/apps/test/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">Startup Testing Swiss Army Knife</string>
+</resources>
diff --git a/startop/apps/test/src/ComplexLayoutInflationActivity.java b/startop/apps/test/src/ComplexLayoutInflationActivity.java
new file mode 100644
index 0000000..a357073
--- /dev/null
+++ b/startop/apps/test/src/ComplexLayoutInflationActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.startop.test;
+
+import android.os.Bundle;
+
+/**
+ * This activity inflates a reasonably complex layout to see the impact of
+ * layout inflation. The layout is supported by the viewcompiler, so this can be
+ * used for testing precompiled layout performance.
+ */
+public class ComplexLayoutInflationActivity extends LayoutInflationActivity {
+    protected void onCreate(Bundle savedInstanceState) {
+        Bundle newState = savedInstanceState == null
+                ? new Bundle() : new Bundle(savedInstanceState);
+        newState.putInt(LAYOUT_ID, R.layout.activity_main);
+
+        super.onCreate(newState);
+    }
+}
diff --git a/startop/apps/test/src/EmptyActivity.java b/startop/apps/test/src/EmptyActivity.java
new file mode 100644
index 0000000..bcb2e70
--- /dev/null
+++ b/startop/apps/test/src/EmptyActivity.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.startop.test;
+
+import android.app.Activity;
+
+/**
+ * The simplest possible Android activity, for testing startup with no
+ * app-specific behavior.
+ */
+public class EmptyActivity extends Activity {
+}
diff --git a/startop/apps/test/src/FrameLayoutInflationActivity.java b/startop/apps/test/src/FrameLayoutInflationActivity.java
new file mode 100644
index 0000000..b995e79
--- /dev/null
+++ b/startop/apps/test/src/FrameLayoutInflationActivity.java
@@ -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.
+ */
+
+package com.android.startop.test;
+
+import android.os.Bundle;
+
+public class FrameLayoutInflationActivity extends LayoutInflationActivity {
+    protected void onCreate(Bundle savedInstanceState) {
+        Bundle newState = savedInstanceState == null
+                ? new Bundle() : new Bundle(savedInstanceState);
+        newState.putInt(LAYOUT_ID, R.layout.framelayout_list);
+
+        super.onCreate(newState);
+    }
+}
diff --git a/startop/apps/test/src/LayoutInflationActivity.java b/startop/apps/test/src/LayoutInflationActivity.java
new file mode 100644
index 0000000..06a0570
--- /dev/null
+++ b/startop/apps/test/src/LayoutInflationActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.startop.test;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Trace;
+import android.view.LayoutInflater;
+import android.view.View;
+
+public class LayoutInflationActivity extends Activity {
+    public static String LAYOUT_ID = "layout-id";
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        int layoutId = savedInstanceState.getInt(LAYOUT_ID);
+        String layoutName = getResources().getResourceEntryName(layoutId);
+
+        LayoutInflater inflater = LayoutInflater.from(this);
+        Trace.beginSection("inflate layout: " + layoutName);
+        View view = inflater.inflate(layoutId, /*root=*/null);
+        Trace.endSection();
+        setContentView(view);
+    }
+}
diff --git a/startop/apps/test/src/TextViewInflationActivity.java b/startop/apps/test/src/TextViewInflationActivity.java
new file mode 100644
index 0000000..30e308e
--- /dev/null
+++ b/startop/apps/test/src/TextViewInflationActivity.java
@@ -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.
+ */
+
+package com.android.startop.test;
+
+import android.os.Bundle;
+
+public class TextViewInflationActivity extends LayoutInflationActivity {
+    protected void onCreate(Bundle savedInstanceState) {
+        Bundle newState = savedInstanceState == null
+                ? new Bundle() : new Bundle(savedInstanceState);
+        newState.putInt(LAYOUT_ID, R.layout.textview_list);
+
+        super.onCreate(newState);
+    }
+}
diff --git a/startop/iorap/DISABLED_TEST_MAPPING b/startop/iorap/TEST_MAPPING
similarity index 100%
rename from startop/iorap/DISABLED_TEST_MAPPING
rename to startop/iorap/TEST_MAPPING
diff --git a/startop/iorap/tests/AndroidTest.xml b/startop/iorap/tests/AndroidTest.xml
index bcd1103..6102c44 100644
--- a/startop/iorap/tests/AndroidTest.xml
+++ b/startop/iorap/tests/AndroidTest.xml
@@ -33,18 +33,34 @@
     <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer">
     </target_preparer>
 
+    <!-- do not use DeviceSetup#set-property because it reboots the device b/136200738.
+         furthermore the changes in /data/local.prop don't actually seem to get picked up.
+    -->
     <target_preparer
         class="com.android.tradefed.targetprep.DeviceSetup">
+        <!-- we need this magic flag, otherwise it always reboots and breaks the selinux -->
+        <option name="force-skip-system-props" value="true" />
+
         <!-- Crash instead of using Log.wtf within the system_server iorap code. -->
-        <option name="set-property" key="iorapd.forwarding_service.wtf_crash" value="true" />
+        <option name="run-command" value="setprop iorapd.forwarding_service.wtf_crash true" />
         <!-- IIorapd has fake behavior: it doesn't do anything but reply with 'DONE' status -->
-        <option name="set-property" key="iorapd.binder.fake" value="true" />
-        <option name="restore-properties" value="true" />
+        <option name="run-command" value="setprop iorapd.binder.fake true" />
+
+        <!-- iorapd does not pick up the above changes until we restart it -->
+        <option name="run-command" value="stop iorapd" />
+        <option name="run-command" value="start iorapd" />
+        <!-- give it some time to restart the service; otherwise the first unit test might fail -->
+        <option name="run-command" value="sleep 1" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.google.android.startop.iorap.tests" />
         <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
     </test>
+
+    <!-- using DeviceSetup again does not work. we simply leave the device in a semi-bad
+         state. there is no way to clean this up as far as I know.
+         -->
+
 </configuration>
 
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
index 883d094..460add8 100644
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
+++ b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
@@ -14,6 +14,7 @@
 
 package com.google.android.startop.iorap
 
+import android.net.Uri
 import android.os.ServiceManager
 import androidx.test.filters.MediumTest
 import org.junit.Test
@@ -85,6 +86,9 @@
 
     @Test
     fun testOnPackageEvent() {
+        // FIXME (b/137134253): implement PackageEvent parsing on the C++ side.
+        // This is currently (silently: b/137135024) failing because IIorap is 'oneway' and the
+        // C++ PackageEvent un-parceling fails since its not implemented fully.
         /*
         testAnyMethod { requestId : RequestId ->
             iorapService.onPackageEvent(requestId,
@@ -92,7 +96,6 @@
                             Uri.parse("https://www.google.com"), "com.fake.package"))
         }
         */
-        // FIXME: Broken for some reason. C++ side never sees this call.
     }
 
     @Test
@@ -107,7 +110,7 @@
     @Test
     fun testOnAppLaunchEvent() {
         testAnyMethod { requestId : RequestId ->
-            // iorapService.onAppLaunchEvent(requestId, AppLaunchEvent.IntentStarted())
+            iorapService.onAppLaunchEvent(requestId, AppLaunchEvent.IntentFailed(/*sequenceId*/123))
         }
     }
 
diff --git a/startop/scripts/app_startup/app_startup_runner.py b/startop/scripts/app_startup/app_startup_runner.py
index adf2ad8..7cba780 100755
--- a/startop/scripts/app_startup/app_startup_runner.py
+++ b/startop/scripts/app_startup/app_startup_runner.py
@@ -27,28 +27,40 @@
 #
 
 import argparse
-import asyncio
 import csv
 import itertools
 import os
 import sys
 import tempfile
-import time
-from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union
+from typing import Any, Callable, Iterable, List, NamedTuple, TextIO, Tuple, \
+    TypeVar, Union
+
+# local import
+DIR = os.path.abspath(os.path.dirname(__file__))
+sys.path.append(os.path.dirname(DIR))
+import app_startup.run_app_with_prefetch as run_app_with_prefetch
+import app_startup.lib.args_utils as args_utils
+from app_startup.lib.data_frame import DataFrame
+import lib.cmd_utils as cmd_utils
+import lib.print_utils as print_utils
 
 # The following command line options participate in the combinatorial generation.
 # All other arguments have a global effect.
-_COMBINATORIAL_OPTIONS=['packages', 'readaheads', 'compiler_filters']
-_TRACING_READAHEADS=['mlock', 'fadvise']
-_FORWARD_OPTIONS={'loop_count': '--count'}
-_RUN_SCRIPT=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'run_app_with_prefetch')
+_COMBINATORIAL_OPTIONS = ['package', 'readahead', 'compiler_filter', 'activity']
+_TRACING_READAHEADS = ['mlock', 'fadvise']
+_FORWARD_OPTIONS = {'loop_count': '--count'}
+_RUN_SCRIPT = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+                           'run_app_with_prefetch.py')
 
-RunCommandArgs = NamedTuple('RunCommandArgs', [('package', str), ('readahead', str), ('compiler_filter', Optional[str])])
-CollectorPackageInfo = NamedTuple('CollectorPackageInfo', [('package', str), ('compiler_filter', str)])
-_COLLECTOR_SCRIPT=os.path.join(os.path.dirname(os.path.realpath(__file__)), '../iorap/collector')
-_COLLECTOR_TIMEOUT_MULTIPLIER = 2 # take the regular --timeout and multiply by 2; systrace starts up slowly.
+CollectorPackageInfo = NamedTuple('CollectorPackageInfo',
+                                  [('package', str), ('compiler_filter', str)])
+_COLLECTOR_SCRIPT = os.path.join(os.path.dirname(os.path.realpath(__file__)),
+                                 '../iorap/collector')
+_COLLECTOR_TIMEOUT_MULTIPLIER = 10  # take the regular --timeout and multiply
+# by 2; systrace starts up slowly.
 
-_UNLOCK_SCREEN_SCRIPT=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'unlock_screen')
+_UNLOCK_SCREEN_SCRIPT = os.path.join(
+    os.path.dirname(os.path.realpath(__file__)), 'unlock_screen')
 
 # This must be the only mutable global variable. All other global variables are constants to avoid magic literals.
 _debug = False  # See -d/--debug flag.
@@ -56,105 +68,70 @@
 
 # Type hinting names.
 T = TypeVar('T')
-NamedTupleMeta = Callable[..., T]  # approximation of a (S : NamedTuple<T> where S() == T) metatype.
+NamedTupleMeta = Callable[
+    ..., T]  # approximation of a (S : NamedTuple<T> where S() == T) metatype.
 
 def parse_options(argv: List[str] = None):
   """Parse command line arguments and return an argparse Namespace object."""
-  parser = argparse.ArgumentParser(description="Run one or more Android applications under various settings in order to measure startup time.")
+  parser = argparse.ArgumentParser(description="Run one or more Android "
+                                               "applications under various "
+                                               "settings in order to measure "
+                                               "startup time.")
   # argparse considers args starting with - and -- optional in --help, even though required=True.
   # by using a named argument group --help will clearly say that it's required instead of optional.
   required_named = parser.add_argument_group('required named arguments')
-  required_named.add_argument('-p', '--package', action='append', dest='packages', help='package of the application', required=True)
-  required_named.add_argument('-r', '--readahead', action='append', dest='readaheads', help='which readahead mode to use', choices=('warm', 'cold', 'mlock', 'fadvise'), required=True)
+  required_named.add_argument('-p', '--package', action='append',
+                              dest='packages',
+                              help='package of the application', required=True)
+  required_named.add_argument('-r', '--readahead', action='append',
+                              dest='readaheads',
+                              help='which readahead mode to use',
+                              choices=('warm', 'cold', 'mlock', 'fadvise'),
+                              required=True)
 
   # optional arguments
   # use a group here to get the required arguments to appear 'above' the optional arguments in help.
   optional_named = parser.add_argument_group('optional named arguments')
-  optional_named.add_argument('-c', '--compiler-filter', action='append', dest='compiler_filters', help='which compiler filter to use. if omitted it does not enforce the app\'s compiler filter', choices=('speed', 'speed-profile', 'quicken'))
-  optional_named.add_argument('-s', '--simulate', dest='simulate', action='store_true', help='Print which commands will run, but don\'t run the apps')
-  optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
-  optional_named.add_argument('-o', '--output', dest='output', action='store', help='Write CSV output to file.')
-  optional_named.add_argument('-t', '--timeout', dest='timeout', action='store', type=int, help='Timeout after this many seconds when executing a single run.')
-  optional_named.add_argument('-lc', '--loop-count', dest='loop_count', default=1, type=int, action='store', help='How many times to loop a single run.')
-  optional_named.add_argument('-in', '--inodes', dest='inodes', type=str, action='store', help='Path to inodes file (system/extras/pagecache/pagecache.py -d inodes)')
+  optional_named.add_argument('-c', '--compiler-filter', action='append',
+                              dest='compiler_filters',
+                              help='which compiler filter to use. if omitted it does not enforce the app\'s compiler filter',
+                              choices=('speed', 'speed-profile', 'quicken'))
+  optional_named.add_argument('-s', '--simulate', dest='simulate',
+                              action='store_true',
+                              help='Print which commands will run, but don\'t run the apps')
+  optional_named.add_argument('-d', '--debug', dest='debug',
+                              action='store_true',
+                              help='Add extra debugging output')
+  optional_named.add_argument('-o', '--output', dest='output', action='store',
+                              help='Write CSV output to file.')
+  optional_named.add_argument('-t', '--timeout', dest='timeout', action='store',
+                              type=int, default=10,
+                              help='Timeout after this many seconds when executing a single run.')
+  optional_named.add_argument('-lc', '--loop-count', dest='loop_count',
+                              default=1, type=int, action='store',
+                              help='How many times to loop a single run.')
+  optional_named.add_argument('-in', '--inodes', dest='inodes', type=str,
+                              action='store',
+                              help='Path to inodes file (system/extras/pagecache/pagecache.py -d inodes)')
 
   return parser.parse_args(argv)
 
-# TODO: refactor this with a common library file with analyze_metrics.py
-def _debug_print(*args, **kwargs):
-  """Print the args to sys.stderr if the --debug/-d flag was passed in."""
+def make_script_command_with_temp_output(script: str,
+                                         args: List[str],
+                                         **kwargs) -> Tuple[str, TextIO]:
+  """
+  Create a command to run a script given the args.
+  Appends --count <loop_count> --output <tmp-file-name>.
+  Returns a tuple (cmd, tmp_file)
+  """
+  tmp_output_file = tempfile.NamedTemporaryFile(mode='r')
+  cmd = [script] + args
+  for key, value in kwargs.items():
+    cmd += ['--%s' % (key), "%s" % (value)]
   if _debug:
-    print(*args, **kwargs, file=sys.stderr)
-
-def _expand_gen_repr(args):
-  """Like repr but any generator-like object has its iterator consumed
-  and then called repr on."""
-  new_args_list = []
-  for i in args:
-    # detect iterable objects that do not have their own override of __str__
-    if hasattr(i, '__iter__'):
-      to_str = getattr(i, '__str__')
-      if to_str.__objclass__ == object:
-        # the repr for a generator is just type+address, expand it out instead.
-        new_args_list.append([_expand_gen_repr([j])[0] for j in i])
-        continue
-    # normal case: uses the built-in to-string
-    new_args_list.append(i)
-  return new_args_list
-
-def _debug_print_gen(*args, **kwargs):
-  """Like _debug_print but will turn any iterable args into a list."""
-  if not _debug:
-    return
-
-  new_args_list = _expand_gen_repr(args)
-  _debug_print(*new_args_list, **kwargs)
-
-def _debug_print_nd(*args, **kwargs):
-  """Like _debug_print but will turn any NamedTuple-type args into a string."""
-  if not _debug:
-    return
-
-  new_args_list = []
-  for i in args:
-    if hasattr(i, '_field_types'):
-      new_args_list.append("%s: %s" %(i.__name__, i._field_types))
-    else:
-      new_args_list.append(i)
-
-  _debug_print(*new_args_list, **kwargs)
-
-def dict_lookup_any_key(dictionary: dict, *keys: List[Any]):
-  for k in keys:
-    if k in dictionary:
-      return dictionary[k]
-  raise KeyError("None of the keys %s were in the dictionary" %(keys))
-
-def generate_run_combinations(named_tuple: NamedTupleMeta[T], opts_dict: Dict[str, List[Optional[str]]])\
-    -> Iterable[T]:
-  """
-  Create all possible combinations given the values in opts_dict[named_tuple._fields].
-
-  :type T: type annotation for the named_tuple type.
-  :param named_tuple: named tuple type, whose fields are used to make combinations for
-  :param opts_dict: dictionary of keys to value list. keys correspond to the named_tuple fields.
-  :return: an iterable over named_tuple instances.
-  """
-  combinations_list = []
-  for k in named_tuple._fields:
-    # the key can be either singular or plural , e.g. 'package' or 'packages'
-    val = dict_lookup_any_key(opts_dict, k, k + "s")
-
-    # treat {'x': None} key value pairs as if it was [None]
-    # otherwise itertools.product throws an exception about not being able to iterate None.
-    combinations_list.append(val or [None])
-
-  _debug_print("opts_dict: ", opts_dict)
-  _debug_print_nd("named_tuple: ", named_tuple)
-  _debug_print("combinations_list: ", combinations_list)
-
-  for combo in itertools.product(*combinations_list):
-    yield named_tuple(*combo)
+    cmd += ['--verbose']
+  cmd = cmd + ["--output", tmp_output_file.name]
+  return cmd, tmp_output_file
 
 def key_to_cmdline_flag(key: str) -> str:
   """Convert key into a command line flag, e.g. 'foo-bars' -> '--foo-bar' """
@@ -176,190 +153,143 @@
     args.append(value)
   return args
 
-def generate_group_run_combinations(run_combinations: Iterable[NamedTuple], dst_nt: NamedTupleMeta[T])\
-    -> Iterable[Tuple[T, Iterable[NamedTuple]]]:
+def run_collector_script(collector_info: CollectorPackageInfo,
+                         inodes_path: str,
+                         timeout: int,
+                         simulate: bool) -> Tuple[bool, TextIO]:
+  """Run collector to collect prefetching trace. """
+  # collector_args = ["--package", package_name]
+  collector_args = as_run_command(collector_info)
+  # TODO: forward --wait_time for how long systrace runs?
+  # TODO: forward --trace_buffer_size for size of systrace buffer size?
+  collector_cmd, collector_tmp_output_file = make_script_command_with_temp_output(
+      _COLLECTOR_SCRIPT, collector_args, inodes=inodes_path)
 
-  def group_by_keys(src_nt):
-    src_d = src_nt._asdict()
-    # now remove the keys that aren't legal in dst.
-    for illegal_key in set(src_d.keys()) - set(dst_nt._fields):
-      if illegal_key in src_d:
-        del src_d[illegal_key]
+  collector_timeout = timeout and _COLLECTOR_TIMEOUT_MULTIPLIER * timeout
+  (collector_passed, collector_script_output) = \
+    cmd_utils.execute_arbitrary_command(collector_cmd,
+                                        collector_timeout,
+                                        shell=False,
+                                        simulate=simulate)
 
-    return dst_nt(**src_d)
+  return collector_passed, collector_tmp_output_file
 
-  for args_list_it in itertools.groupby(run_combinations, group_by_keys):
-    (group_key_value, args_it) = args_list_it
-    yield (group_key_value, args_it)
-
-def parse_run_script_csv_file(csv_file: TextIO) -> List[int]:
-  """Parse a CSV file full of integers into a flat int list."""
+def parse_run_script_csv_file(csv_file: TextIO) -> DataFrame:
+  """Parse a CSV file full of integers into a DataFrame."""
   csv_reader = csv.reader(csv_file)
-  arr = []
+
+  try:
+    header_list = next(csv_reader)
+  except StopIteration:
+    header_list = []
+
+  if not header_list:
+    return None
+
+  headers = [i for i in header_list]
+
+  d = {}
   for row in csv_reader:
+    header_idx = 0
+
     for i in row:
+      v = i
       if i:
-        arr.append(int(i))
-  return arr
+        v = int(i)
 
-def make_script_command_with_temp_output(script: str, args: List[str], **kwargs)\
-    -> Tuple[str, TextIO]:
-  """
-  Create a command to run a script given the args.
-  Appends --count <loop_count> --output <tmp-file-name>.
-  Returns a tuple (cmd, tmp_file)
-  """
-  tmp_output_file = tempfile.NamedTemporaryFile(mode='r')
-  cmd = [script] + args
-  for key, value in kwargs.items():
-    cmd += ['--%s' %(key), "%s" %(value)]
-  if _debug:
-    cmd += ['--verbose']
-  cmd = cmd + ["--output", tmp_output_file.name]
-  return cmd, tmp_output_file
+      header_key = headers[header_idx]
+      l = d.get(header_key, [])
+      l.append(v)
+      d[header_key] = l
 
-async def _run_command(*args : List[str], timeout: Optional[int] = None) -> Tuple[int, bytes]:
-  # start child process
-  # NOTE: universal_newlines parameter is not supported
-  process = await asyncio.create_subprocess_exec(*args,
-      stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
+      header_idx = header_idx + 1
 
-  script_output = b""
+  return DataFrame(d)
 
-  _debug_print("[PID]", process.pid)
-
-#hack
-#  stdout, stderr = await process.communicate()
-#  return (process.returncode, stdout)
-
-  timeout_remaining = timeout
-  time_started = time.time()
-
-  # read line (sequence of bytes ending with b'\n') asynchronously
-  while True:
-    try:
-      line = await asyncio.wait_for(process.stdout.readline(), timeout_remaining)
-      _debug_print("[STDOUT]", line)
-      script_output += line
-
-      if timeout_remaining:
-        time_elapsed = time.time() - time_started
-        timeout_remaining = timeout - time_elapsed
-    except asyncio.TimeoutError:
-      _debug_print("[TIMEDOUT] Process ", process.pid)
-
-#      if process.returncode is not None:
-#        #_debug_print("[WTF] can-write-eof?", process.stdout.can_write_eof())
-#
-#        _debug_print("[TIMEDOUT] Process already terminated")
-#        (remaining_stdout, remaining_stderr) = await process.communicate()
-#        script_output += remaining_stdout
-#
-#        code = await process.wait()
-#        return (code, script_output)
-
-      _debug_print("[TIMEDOUT] Sending SIGTERM.")
-      process.terminate()
-
-      # 1 second timeout for process to handle SIGTERM nicely.
-      try:
-       (remaining_stdout, remaining_stderr) = await asyncio.wait_for(process.communicate(), 5)
-       script_output += remaining_stdout
-      except asyncio.TimeoutError:
-        _debug_print("[TIMEDOUT] Sending SIGKILL.")
-        process.kill()
-
-      # 1 second timeout to finish with SIGKILL.
-      try:
-        (remaining_stdout, remaining_stderr) = await asyncio.wait_for(process.communicate(), 5)
-        script_output += remaining_stdout
-      except asyncio.TimeoutError:
-        # give up, this will leave a zombie process.
-        _debug_print("[TIMEDOUT] SIGKILL failed for process ", process.pid)
-        time.sleep(100)
-        #await process.wait()
-
-      return (-1, script_output)
-    else:
-      if not line: # EOF
-        break
-
-      #if process.returncode is not None:
-      #  _debug_print("[WTF] can-write-eof?", process.stdout.can_write_eof())
-      #  process.stdout.write_eof()
-
-      #if process.stdout.at_eof():
-      #  break
-
-  code = await process.wait() # wait for child process to exit
-  return (code, script_output)
-
-def execute_arbitrary_command(cmd: List[str], simulate: bool, timeout: Optional[int]) -> Tuple[bool, str]:
-  if simulate:
-    print(" ".join(cmd))
-    return (True, "")
-  else:
-    _debug_print("[EXECUTE]", cmd)
-
-    # block until either command finishes or the timeout occurs.
-    loop = asyncio.get_event_loop()
-    (return_code, script_output) = loop.run_until_complete(_run_command(*cmd, timeout=timeout))
-
-    script_output = script_output.decode() # convert bytes to str
-
-    passed = (return_code == 0)
-    _debug_print("[$?]", return_code)
-    if not passed:
-      print("[FAILED, code:%s]" %(return_code), script_output, file=sys.stderr)
-
-    return (passed, script_output)
-
-def execute_run_combos(grouped_run_combos: Iterable[Tuple[CollectorPackageInfo, Iterable[RunCommandArgs]]], simulate: bool, inodes_path: str, timeout: int, loop_count: int, need_trace: bool):
+def execute_run_combos(
+    grouped_run_combos: Iterable[Tuple[CollectorPackageInfo, Iterable[
+      run_app_with_prefetch.RunCommandArgs]]],
+    simulate: bool,
+    inodes_path: str,
+    timeout: int):
   # nothing will work if the screen isn't unlocked first.
-  execute_arbitrary_command([_UNLOCK_SCREEN_SCRIPT], simulate, timeout)
+  cmd_utils.execute_arbitrary_command([_UNLOCK_SCREEN_SCRIPT],
+                                      timeout,
+                                      simulate=simulate,
+                                      shell=False)
 
   for collector_info, run_combos in grouped_run_combos:
-    #collector_args = ["--package", package_name]
-    collector_args = as_run_command(collector_info)
-    # TODO: forward --wait_time for how long systrace runs?
-    # TODO: forward --trace_buffer_size for size of systrace buffer size?
-    collector_cmd, collector_tmp_output_file = make_script_command_with_temp_output(_COLLECTOR_SCRIPT, collector_args, inodes=inodes_path)
+    for combos in run_combos:
+      args = as_run_command(combos)
+      if combos.readahead in _TRACING_READAHEADS:
+        passed, collector_tmp_output_file = run_collector_script(collector_info,
+                                                                 inodes_path,
+                                                                 timeout,
+                                                                 simulate)
+        combos = combos._replace(input=collector_tmp_output_file.name)
 
-    with collector_tmp_output_file:
-      collector_passed = True
-      if need_trace:
-        collector_timeout = timeout and _COLLECTOR_TIMEOUT_MULTIPLIER * timeout
-        (collector_passed, collector_script_output) = execute_arbitrary_command(collector_cmd, simulate, collector_timeout)
-        # TODO: consider to print a ; collector wrote file to <...> into the CSV file so we know it was ran.
+      print_utils.debug_print(combos)
+      output = run_app_with_prefetch.run_test(combos)
 
-      for combos in run_combos:
-        args = as_run_command(combos)
+      yield DataFrame(dict((x, [y]) for x, y in output)) if output else None
 
-        cmd, tmp_output_file = make_script_command_with_temp_output(_RUN_SCRIPT, args, count=loop_count, input=collector_tmp_output_file.name)
-        with tmp_output_file:
-          (passed, script_output) = execute_arbitrary_command(cmd, simulate, timeout)
-          parsed_output = simulate and [1,2,3] or parse_run_script_csv_file(tmp_output_file)
-          yield (passed, script_output, parsed_output)
-
-def gather_results(commands: Iterable[Tuple[bool, str, List[int]]], key_list: List[str], value_list: List[Tuple[str, ...]]):
-  _debug_print("gather_results: key_list = ", key_list)
-  yield key_list + ["time(ms)"]
-
+def gather_results(commands: Iterable[Tuple[DataFrame]],
+                   key_list: List[str], value_list: List[Tuple[str, ...]]):
+  print_utils.debug_print("gather_results: key_list = ", key_list)
   stringify_none = lambda s: s is None and "<none>" or s
+  #  yield key_list + ["time(ms)"]
+  for (run_result_list, values) in itertools.zip_longest(commands, value_list):
+    print_utils.debug_print("run_result_list = ", run_result_list)
+    print_utils.debug_print("values = ", values)
 
-  for ((passed, script_output, run_result_list), values) in itertools.zip_longest(commands, value_list):
-    if not passed:
+    if not run_result_list:
       continue
-    for result in run_result_list:
-      yield [stringify_none(i) for i in values] + [result]
 
-    yield ["; avg(%s), min(%s), max(%s), count(%s)" %(sum(run_result_list, 0.0) / len(run_result_list), min(run_result_list), max(run_result_list), len(run_result_list)) ]
+    # RunCommandArgs(package='com.whatever', readahead='warm', compiler_filter=None)
+    # -> {'package':['com.whatever'], 'readahead':['warm'], 'compiler_filter':[None]}
+    values_dict = {}
+    for k, v in values._asdict().items():
+      if not k in key_list:
+        continue
+      values_dict[k] = [stringify_none(v)]
+
+    values_df = DataFrame(values_dict)
+    # project 'values_df' to be same number of rows as run_result_list.
+    values_df = values_df.repeat(run_result_list.data_row_len)
+
+    # the results are added as right-hand-side columns onto the existing labels for the table.
+    values_df.merge_data_columns(run_result_list)
+
+    yield values_df
 
 def eval_and_save_to_csv(output, annotated_result_values):
+  printed_header = False
+
   csv_writer = csv.writer(output)
   for row in annotated_result_values:
-    csv_writer.writerow(row)
-    output.flush() # see the output live.
+    if not printed_header:
+      headers = row.headers
+      csv_writer.writerow(headers)
+      printed_header = True
+      # TODO: what about when headers change?
+
+    for data_row in row.data_table:
+      data_row = [d for d in data_row]
+      csv_writer.writerow(data_row)
+
+    output.flush()  # see the output live.
+
+def coerce_to_list(opts: dict):
+  """Tranform values of the dictionary to list.
+  For example:
+  1 -> [1], None -> [None], [1,2,3] -> [1,2,3]
+  [[1],[2]] -> [[1],[2]], {1:1, 2:2} -> [{1:1, 2:2}]
+  """
+  result = {}
+  for key in opts:
+    val = opts[key]
+    result[key] = val if issubclass(type(val), list) else [val]
+  return result
 
 def main():
   global _debug
@@ -368,26 +298,34 @@
   _debug = opts.debug
   if _DEBUG_FORCE is not None:
     _debug = _DEBUG_FORCE
-  _debug_print("parsed options: ", opts)
-  need_trace = not not set(opts.readaheads).intersection(set(_TRACING_READAHEADS))
-  if need_trace and not opts.inodes:
-    print("Error: Missing -in/--inodes, required when using a readahead of %s" %(_TRACING_READAHEADS), file=sys.stderr)
-    return 1
+
+  print_utils.DEBUG = _debug
+  cmd_utils.SIMULATE = opts.simulate
+
+  print_utils.debug_print("parsed options: ", opts)
 
   output_file = opts.output and open(opts.output, 'w') or sys.stdout
 
-  combos = lambda: generate_run_combinations(RunCommandArgs, vars(opts))
-  _debug_print_gen("run combinations: ", combos())
+  combos = lambda: args_utils.generate_run_combinations(
+      run_app_with_prefetch.RunCommandArgs,
+      coerce_to_list(vars(opts)),
+      opts.loop_count)
+  print_utils.debug_print_gen("run combinations: ", combos())
 
-  grouped_combos = lambda: generate_group_run_combinations(combos(), CollectorPackageInfo)
-  _debug_print_gen("grouped run combinations: ", grouped_combos())
+  grouped_combos = lambda: args_utils.generate_group_run_combinations(combos(),
+                                                                      CollectorPackageInfo)
 
-  exec = execute_run_combos(grouped_combos(), opts.simulate, opts.inodes, opts.timeout, opts.loop_count, need_trace)
+  print_utils.debug_print_gen("grouped run combinations: ", grouped_combos())
+  exec = execute_run_combos(grouped_combos(),
+                            opts.simulate,
+                            opts.inodes,
+                            opts.timeout)
+
   results = gather_results(exec, _COMBINATORIAL_OPTIONS, combos())
+
   eval_and_save_to_csv(output_file, results)
 
-  return 0
-
+  return 1
 
 if __name__ == '__main__':
   sys.exit(main())
diff --git a/startop/scripts/app_startup/app_startup_runner_test.py b/startop/scripts/app_startup/app_startup_runner_test.py
index f96f802a..9aa7014 100755
--- a/startop/scripts/app_startup/app_startup_runner_test.py
+++ b/startop/scripts/app_startup/app_startup_runner_test.py
@@ -31,18 +31,17 @@
 See also https://docs.pytest.org/en/latest/usage.html
 """
 
-# global imports
-from contextlib import contextmanager
 import io
 import shlex
 import sys
 import typing
-
-# pip imports
-import pytest
+# global imports
+from contextlib import contextmanager
 
 # local imports
 import app_startup_runner as asr
+# pip imports
+import pytest
 
 #
 # Argument Parsing Helpers
@@ -91,7 +90,8 @@
   """
   # Combine it with all of the "optional" parameters' default values.
   """
-  d = {'compiler_filters': None, 'simulate': False, 'debug': False, 'output': None, 'timeout': None, 'loop_count': 1, 'inodes': None}
+  d = {'compiler_filters': None, 'simulate': False, 'debug': False,
+       'output': None, 'timeout': 10, 'loop_count': 1, 'inodes': None}
   d.update(kwargs)
   return d
 
@@ -111,7 +111,7 @@
   in default_mock_dict_for_parsed_args.
   """
   req = "--package com.fake.package --readahead warm"
-  return parse_args("%s %s" %(req, str))
+  return parse_args("%s %s" % (req, str))
 
 def test_argparse():
   # missing arguments
@@ -124,15 +124,22 @@
   # required arguments are parsed correctly
   ad = default_dict_for_parsed_args  # assert dict
 
-  assert parse_args("--package xyz --readahead warm") == ad(packages=['xyz'], readaheads=['warm'])
-  assert parse_args("-p xyz -r warm") == ad(packages=['xyz'], readaheads=['warm'])
+  assert parse_args("--package xyz --readahead warm") == ad(packages=['xyz'],
+                                                            readaheads=['warm'])
+  assert parse_args("-p xyz -r warm") == ad(packages=['xyz'],
+                                            readaheads=['warm'])
 
-  assert parse_args("-p xyz -r warm -s") == ad(packages=['xyz'], readaheads=['warm'], simulate=True)
-  assert parse_args("-p xyz -r warm --simulate") == ad(packages=['xyz'], readaheads=['warm'], simulate=True)
+  assert parse_args("-p xyz -r warm -s") == ad(packages=['xyz'],
+                                               readaheads=['warm'],
+                                               simulate=True)
+  assert parse_args("-p xyz -r warm --simulate") == ad(packages=['xyz'],
+                                                       readaheads=['warm'],
+                                                       simulate=True)
 
   # optional arguments are parsed correctly.
   mad = default_mock_dict_for_parsed_args  # mock assert dict
-  assert parse_optional_args("--output filename.csv") == mad(output='filename.csv')
+  assert parse_optional_args("--output filename.csv") == mad(
+    output='filename.csv')
   assert parse_optional_args("-o filename.csv") == mad(output='filename.csv')
 
   assert parse_optional_args("--timeout 123") == mad(timeout=123)
@@ -145,36 +152,6 @@
   assert parse_optional_args("-in baz") == mad(inodes="baz")
 
 
-def generate_run_combinations(*args):
-  # expand out the generator values so that assert x == y works properly.
-  return [i for i in asr.generate_run_combinations(*args)]
-
-def test_generate_run_combinations():
-  blank_nd = typing.NamedTuple('Blank')
-  assert generate_run_combinations(blank_nd, {}) == [()], "empty"
-  assert generate_run_combinations(blank_nd, {'a' : ['a1', 'a2']}) == [()], "empty filter"
-  a_nd = typing.NamedTuple('A', [('a', str)])
-  assert generate_run_combinations(a_nd, {'a': None}) == [(None,)], "None"
-  assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}) == [('a1',), ('a2',)], "one item"
-  assert generate_run_combinations(a_nd,
-                                   {'a' : ['a1', 'a2'], 'b': ['b1', 'b2']}) == [('a1',), ('a2',)],\
-      "one item filter"
-  ab_nd = typing.NamedTuple('AB', [('a', str), ('b', str)])
-  assert generate_run_combinations(ab_nd,
-                                   {'a': ['a1', 'a2'],
-                                    'b': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
-                                                            ab_nd('a1', 'b2'),
-                                                            ab_nd('a2', 'b1'),
-                                                            ab_nd('a2', 'b2')],\
-      "two items"
-
-  assert generate_run_combinations(ab_nd,
-                                   {'as': ['a1', 'a2'],
-                                    'bs': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
-                                                             ab_nd('a1', 'b2'),
-                                                             ab_nd('a2', 'b1'),
-                                                             ab_nd('a2', 'b2')],\
-      "two items plural"
 
 def test_key_to_cmdline_flag():
   assert asr.key_to_cmdline_flag("abc") == "--abc"
@@ -182,29 +159,30 @@
   assert asr.key_to_cmdline_flag("ba_r") == "--ba-r"
   assert asr.key_to_cmdline_flag("ba_zs") == "--ba-z"
 
-
 def test_make_script_command_with_temp_output():
-  cmd_str, tmp_file = asr.make_script_command_with_temp_output("fake_script", args=[], count=1)
+  cmd_str, tmp_file = asr.make_script_command_with_temp_output("fake_script",
+                                                               args=[], count=1)
   with tmp_file:
     assert cmd_str == ["fake_script", "--count", "1", "--output", tmp_file.name]
 
-  cmd_str, tmp_file = asr.make_script_command_with_temp_output("fake_script", args=['a', 'b'], count=2)
+  cmd_str, tmp_file = asr.make_script_command_with_temp_output("fake_script",
+                                                               args=['a', 'b'],
+                                                               count=2)
   with tmp_file:
-    assert cmd_str == ["fake_script", "a", "b", "--count", "2", "--output", tmp_file.name]
+    assert cmd_str == ["fake_script", "a", "b", "--count", "2", "--output",
+                       tmp_file.name]
 
 def test_parse_run_script_csv_file():
   # empty file -> empty list
   f = io.StringIO("")
-  assert asr.parse_run_script_csv_file(f) == []
+  assert asr.parse_run_script_csv_file(f) == None
 
   # common case
-  f = io.StringIO("1,2,3")
-  assert asr.parse_run_script_csv_file(f) == [1,2,3]
+  f = io.StringIO("TotalTime_ms,Displayed_ms\n1,2")
+  df = asr.DataFrame({'TotalTime_ms': [1], 'Displayed_ms': [2]})
 
-  # ignore trailing comma
-  f = io.StringIO("1,2,3,4,5,")
-  assert asr.parse_run_script_csv_file(f) == [1,2,3,4,5]
-
+  pf = asr.parse_run_script_csv_file(f)
+  assert pf == df
 
 if __name__ == '__main__':
   pytest.main()
diff --git a/startop/scripts/app_startup/launch_application b/startop/scripts/app_startup/launch_application
index bc7ca80..6704a5a 100755
--- a/startop/scripts/app_startup/launch_application
+++ b/startop/scripts/app_startup/launch_application
@@ -39,22 +39,9 @@
   # if the $ is not escaped, adb shell will try to evaluate $HomeActivity to a variable.
   activity=${activity//\$/\\$}
 
-  local am_output="$(adb shell am start -S -W "$package"/"$activity")"
-  verbose_print adb shell am start -S -W "$package"/"$activity"
-  if [[ $? -ne 0 ]]; then
-    echo "am start failed" >&2
+  adb shell am start -S -W "$package"/"$activity"
 
-    return 1
-  fi
-
-  # for everything else use the am start "TotalTime" output.
-  verbose_print "$am_output"
-  local total_time="$(echo "$am_output" | grep 'TotalTime:' | sed 's/TotalTime: //g')"
-  verbose_print "total time: $total_time"
-
-  # TODO: Extract alternative metrics such as the #reportFullyDrawn.
-
-  echo "$total_time"
+  # pipe this into 'parse_metrics' to parse the output.
 }
 
 if [[ $# -lt 2 ]]; then
diff --git a/startop/scripts/app_startup/lib/adb_utils.py b/startop/scripts/app_startup/lib/adb_utils.py
new file mode 100644
index 0000000..0e0065d
--- /dev/null
+++ b/startop/scripts/app_startup/lib/adb_utils.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+"""Helper util libraries for calling adb command line."""
+
+import datetime
+import os
+import re
+import sys
+import time
+from typing import Optional
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(
+  os.path.abspath(__file__)))))
+import lib.cmd_utils as cmd_utils
+import lib.logcat_utils as logcat_utils
+
+
+def logcat_save_timestamp() -> str:
+  """Gets the current logcat timestamp.
+
+  Returns:
+    A string of timestamp.
+  """
+  _, output = cmd_utils.run_adb_shell_command(
+    "date -u +\'%Y-%m-%d %H:%M:%S.%N\'")
+  return output
+
+def vm_drop_cache():
+  """Free pagecache and slab object."""
+  cmd_utils.run_adb_shell_command('echo 3 > /proc/sys/vm/drop_caches')
+
+def root():
+  """Roots adb and successive adb commands will run under root."""
+  cmd_utils.run_shell_command('adb root')
+
+def disable_selinux():
+  """Disables selinux setting."""
+  _, output = cmd_utils.run_adb_shell_command('getenforce')
+  if output == 'Permissive':
+    return
+
+  print('Disable selinux permissions and restart framework.')
+  cmd_utils.run_adb_shell_command('setenforce 0')
+  cmd_utils.run_adb_shell_command('stop')
+  cmd_utils.run_adb_shell_command('start')
+  cmd_utils.run_shell_command('adb wait-for-device')
+
+def pkill(procname: str):
+  """Kills a process on device specified by the substring pattern in procname"""
+  _, pids = cmd_utils.run_shell_command('adb shell ps | grep "{}" | '
+                                        'awk \'{{print $2;}}\''.
+                                          format(procname))
+
+  for pid in pids.split('\n'):
+    pid = pid.strip()
+    if pid:
+      passed,_ = cmd_utils.run_adb_shell_command('kill {}'.format(pid))
+      time.sleep(1)
+
+def parse_time_to_milliseconds(time: str) -> int:
+  """Parses the time string to milliseconds."""
+  # Example: +1s56ms, +56ms
+  regex = r'\+((?P<second>\d+?)s)?(?P<millisecond>\d+?)ms'
+  result = re.search(regex, time)
+  second = 0
+  if result.group('second'):
+    second = int(result.group('second'))
+  ms = int(result.group('millisecond'))
+  return second * 1000 + ms
+
+def blocking_wait_for_logcat_displayed_time(timestamp: datetime.datetime,
+                                            package: str,
+                                            timeout: int) -> Optional[int]:
+  """Parses the displayed time in the logcat.
+
+  Returns:
+    the displayed time.
+  """
+  pattern = re.compile('.*ActivityTaskManager: Displayed {}.*'.format(package))
+  # 2019-07-02 22:28:34.469453349 -> 2019-07-02 22:28:34.469453
+  timestamp = datetime.datetime.strptime(timestamp[:-3],
+                                         '%Y-%m-%d %H:%M:%S.%f')
+  timeout_dt = timestamp + datetime.timedelta(0, timeout)
+  # 2019-07-01 14:54:21.946 27365 27392 I ActivityTaskManager:
+  # Displayed com.android.settings/.Settings: +927ms
+  result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
+                                                         pattern,
+                                                         timeout_dt)
+  if not result or not '+' in result:
+    return None
+  displayed_time = result[result.rfind('+'):]
+
+  return parse_time_to_milliseconds(displayed_time)
\ No newline at end of file
diff --git a/startop/scripts/app_startup/lib/adb_utils_test.py b/startop/scripts/app_startup/lib/adb_utils_test.py
new file mode 100644
index 0000000..e590fed
--- /dev/null
+++ b/startop/scripts/app_startup/lib/adb_utils_test.py
@@ -0,0 +1,16 @@
+import adb_utils
+
+# pip imports
+import pytest
+
+def test_parse_time_to_milliseconds():
+  # Act
+  result1 = adb_utils.parse_time_to_milliseconds('+1s7ms')
+  result2 = adb_utils.parse_time_to_milliseconds('+523ms')
+
+  # Assert
+  assert result1 == 1007
+  assert result2 == 523
+
+if __name__ == '__main__':
+  pytest.main()
diff --git a/startop/scripts/app_startup/lib/args_utils.py b/startop/scripts/app_startup/lib/args_utils.py
new file mode 100644
index 0000000..080f3b5
--- /dev/null
+++ b/startop/scripts/app_startup/lib/args_utils.py
@@ -0,0 +1,77 @@
+import itertools
+import os
+import sys
+from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, \
+    TypeVar, Optional
+
+# local import
+sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(
+    os.path.abspath(__file__)))))
+import lib.print_utils as print_utils
+
+T = TypeVar('T')
+NamedTupleMeta = Callable[
+    ..., T]  # approximation of a (S : NamedTuple<T> where S() == T) metatype.
+FilterFuncType = Callable[[NamedTuple], bool]
+
+def dict_lookup_any_key(dictionary: dict, *keys: List[Any]):
+  for k in keys:
+    if k in dictionary:
+      return dictionary[k]
+
+
+  print_utils.debug_print("None of the keys {} were in the dictionary".format(
+      keys))
+  return [None]
+
+def generate_run_combinations(named_tuple: NamedTupleMeta[T],
+                              opts_dict: Dict[str, List[Optional[object]]],
+                              loop_count: int = 1) -> Iterable[T]:
+  """
+  Create all possible combinations given the values in opts_dict[named_tuple._fields].
+
+  :type T: type annotation for the named_tuple type.
+  :param named_tuple: named tuple type, whose fields are used to make combinations for
+  :param opts_dict: dictionary of keys to value list. keys correspond to the named_tuple fields.
+  :param loop_count: number of repetitions.
+  :return: an iterable over named_tuple instances.
+  """
+  combinations_list = []
+  for k in named_tuple._fields:
+    # the key can be either singular or plural , e.g. 'package' or 'packages'
+    val = dict_lookup_any_key(opts_dict, k, k + "s")
+
+    # treat {'x': None} key value pairs as if it was [None]
+    # otherwise itertools.product throws an exception about not being able to iterate None.
+    combinations_list.append(val or [None])
+
+  print_utils.debug_print("opts_dict: ", opts_dict)
+  print_utils.debug_print_nd("named_tuple: ", named_tuple)
+  print_utils.debug_print("combinations_list: ", combinations_list)
+
+  for i in range(loop_count):
+    for combo in itertools.product(*combinations_list):
+      yield named_tuple(*combo)
+
+def filter_run_combinations(named_tuple: NamedTuple,
+                            filters: List[FilterFuncType]) -> bool:
+  for filter in filters:
+    if filter(named_tuple):
+      return False
+  return True
+
+def generate_group_run_combinations(run_combinations: Iterable[NamedTuple],
+                                    dst_nt: NamedTupleMeta[T]) \
+    -> Iterable[Tuple[T, Iterable[NamedTuple]]]:
+  def group_by_keys(src_nt):
+    src_d = src_nt._asdict()
+    # now remove the keys that aren't legal in dst.
+    for illegal_key in set(src_d.keys()) - set(dst_nt._fields):
+      if illegal_key in src_d:
+        del src_d[illegal_key]
+
+    return dst_nt(**src_d)
+
+  for args_list_it in itertools.groupby(run_combinations, group_by_keys):
+    (group_key_value, args_it) = args_list_it
+    yield (group_key_value, args_it)
diff --git a/startop/scripts/app_startup/lib/args_utils_test.py b/startop/scripts/app_startup/lib/args_utils_test.py
new file mode 100644
index 0000000..4b7e0fa
--- /dev/null
+++ b/startop/scripts/app_startup/lib/args_utils_test.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+#
+# Copyright 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.
+#
+
+"""Unit tests for the args_utils.py script."""
+
+import typing
+
+import args_utils
+
+def generate_run_combinations(*args):
+  # expand out the generator values so that assert x == y works properly.
+  return [i for i in args_utils.generate_run_combinations(*args)]
+
+def test_generate_run_combinations():
+  blank_nd = typing.NamedTuple('Blank')
+  assert generate_run_combinations(blank_nd, {}, 1) == [()], "empty"
+  assert generate_run_combinations(blank_nd, {'a': ['a1', 'a2']}) == [
+    ()], "empty filter"
+  a_nd = typing.NamedTuple('A', [('a', str)])
+  assert generate_run_combinations(a_nd, {'a': None}) == [(None,)], "None"
+  assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}) == [('a1',), (
+    'a2',)], "one item"
+  assert generate_run_combinations(a_nd,
+                                   {'a': ['a1', 'a2'], 'b': ['b1', 'b2']}) == [
+           ('a1',), ('a2',)], \
+    "one item filter"
+  assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}, 2) == [('a1',), (
+    'a2',), ('a1',), ('a2',)], "one item"
+  ab_nd = typing.NamedTuple('AB', [('a', str), ('b', str)])
+  assert generate_run_combinations(ab_nd,
+                                   {'a': ['a1', 'a2'],
+                                    'b': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
+                                                            ab_nd('a1', 'b2'),
+                                                            ab_nd('a2', 'b1'),
+                                                            ab_nd('a2', 'b2')], \
+    "two items"
+
+  assert generate_run_combinations(ab_nd,
+                                   {'as': ['a1', 'a2'],
+                                    'bs': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
+                                                             ab_nd('a1', 'b2'),
+                                                             ab_nd('a2', 'b1'),
+                                                             ab_nd('a2', 'b2')], \
+    "two items plural"
diff --git a/startop/scripts/app_startup/lib/common b/startop/scripts/app_startup/lib/common
index 41f8cda..bedaa1e 100755
--- a/startop/scripts/app_startup/lib/common
+++ b/startop/scripts/app_startup/lib/common
@@ -83,17 +83,7 @@
 #
 # First use 'logcat_save_timestamp'
 # Then do whatever action you want.
-# Then us 'logcat_from_timestamp $timestamp'
-logcat_from_timestamp() {
-  local timestamp="$1"
-  shift # drop timestamp from args.
-  echo "DONT CALL THIS FUNCTION" >&2
-  exit 1
-
-  verbose_print adb logcat -T \"$timestamp\" \"$@\"
-  adb logcat -T "$timestamp" "$@"
-}
-
+# Then use 'logcat_from_timestamp_bg $timestamp'
 logcat_from_timestamp_bg() {
   local timestamp="$1"
   shift # drop timestamp from args.
@@ -104,9 +94,10 @@
 
 # Starting at timestamp $2, wait until we seen pattern $3
 # or until a timeout happens in $1 seconds.
+# If successful, also echo the line that matched the pattern.
 #
 # Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
-logcat_wait_for_pattern() {
+logcat_select_pattern() {
   local timeout="$1"
   local timestamp="$2"
   local pattern="$3"
@@ -143,6 +134,7 @@
     if [[ "$logcat_output:" == *"$pattern"* ]]; then
       verbose_print "LOGCAT: " "$logcat_output"
       verbose_print "WE DID SEE PATTERN" '<<' "$pattern" '>>.'
+      echo "$logcat_output"
       return_code=0
       break
     fi
@@ -162,3 +154,45 @@
 
   return $return_code
 }
+
+# Starting at timestamp $2, wait until we seen pattern $3
+# or until a timeout happens in $1 seconds.
+#
+# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
+logcat_wait_for_pattern() {
+  logcat_select_pattern "$@" > /dev/null
+}
+
+# Starting at timestamp $2, wait until we seen pattern $3
+# or until a timeout happens in $1 seconds.
+# If successful, extract with the regular expression pattern in #4
+# and return the first capture group.
+#
+# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
+logcat_extract_pattern() {
+  local timeout="$1"
+  local timestamp="$2"
+  local pattern="$3"
+  local re_pattern="$4"
+
+  local result
+  local exit_code
+
+  result="$(logcat_select_pattern "$@")"
+  exit_code=$?
+
+  if [[ $exit_code -ne 0 ]]; then
+    return $exit_code
+  fi
+
+  echo "$result" | sed 's/'"$re_pattern"'/\1/g'
+}
+
+# Join array
+#   FOO=(a b c)
+#   join_by , "${FOO[@]}" #a,b,c
+join_by() {
+  local IFS="$1"
+  shift
+  echo "$*"
+}
diff --git a/startop/scripts/app_startup/lib/data_frame.py b/startop/scripts/app_startup/lib/data_frame.py
new file mode 100644
index 0000000..20a2308
--- /dev/null
+++ b/startop/scripts/app_startup/lib/data_frame.py
@@ -0,0 +1,201 @@
+import itertools
+from typing import Dict, List
+
+class DataFrame:
+  """Table-like class for storing a 2D cells table with named columns."""
+  def __init__(self, data: Dict[str, List[object]] = {}):
+    """
+    Create a new DataFrame from a dictionary (keys = headers,
+    values = columns).
+    """
+    self._headers = [i for i in data.keys()]
+    self._rows = []
+
+    row_num = 0
+
+    def get_data_row(idx):
+      r = {}
+      for header, header_data in data.items():
+
+        if not len(header_data) > idx:
+          continue
+
+        r[header] = header_data[idx]
+
+      return r
+
+    while True:
+      row_dict = get_data_row(row_num)
+      if len(row_dict) == 0:
+        break
+
+      self._append_row(row_dict.keys(), row_dict.values())
+      row_num = row_num + 1
+
+  def concat_rows(self, other: 'DataFrame') -> None:
+    """
+    In-place concatenate rows of other into the rows of the
+    current DataFrame.
+
+    None is added in pre-existing cells if new headers
+    are introduced.
+    """
+    other_datas = other._data_only()
+
+    other_headers = other.headers
+
+    for d in other_datas:
+      self._append_row(other_headers, d)
+
+  def _append_row(self, headers: List[str], data: List[object]):
+    new_row = {k:v for k,v in zip(headers, data)}
+    self._rows.append(new_row)
+
+    for header in headers:
+      if not header in self._headers:
+        self._headers.append(header)
+
+  def __repr__(self):
+#     return repr(self._rows)
+    repr = ""
+
+    header_list = self._headers_only()
+
+    row_format = u""
+    for header in header_list:
+      row_format = row_format + u"{:>%d}" %(len(header) + 1)
+
+    repr = row_format.format(*header_list) + "\n"
+
+    for v in self._data_only():
+      repr = repr + row_format.format(*v) + "\n"
+
+    return repr
+
+  def __eq__(self, other):
+    if isinstance(other, self.__class__):
+      return self.headers == other.headers and self.data_table == other.data_table
+    else:
+      print("wrong instance", other.__class__)
+      return False
+
+  @property
+  def headers(self) -> List[str]:
+    return [i for i in self._headers_only()]
+
+  @property
+  def data_table(self) -> List[List[object]]:
+    return list(self._data_only())
+
+  @property
+  def data_table_transposed(self) -> List[List[object]]:
+    return list(self._transposed_data())
+
+  @property
+  def data_row_len(self) -> int:
+    return len(self._rows)
+
+  def data_row_at(self, idx) -> List[object]:
+    """
+    Return a single data row at the specified index (0th based).
+
+    Accepts negative indices, e.g. -1 is last row.
+    """
+    row_dict = self._rows[idx]
+    l = []
+
+    for h in self._headers_only():
+      l.append(row_dict.get(h)) # Adds None in blank spots.
+
+    return l
+
+  def copy(self) -> 'DataFrame':
+    """
+    Shallow copy of this DataFrame.
+    """
+    return self.repeat(count=0)
+
+  def repeat(self, count: int) -> 'DataFrame':
+    """
+    Returns a new DataFrame where each row of this dataframe is repeated count times.
+    A repeat of a row is adjacent to other repeats of that same row.
+    """
+    df = DataFrame()
+    df._headers = self._headers.copy()
+
+    rows = []
+    for row in self._rows:
+      for i in range(count):
+        rows.append(row.copy())
+
+    df._rows = rows
+
+    return df
+
+  def merge_data_columns(self, other: 'DataFrame'):
+    """
+    Merge self and another DataFrame by adding the data from other column-wise.
+    For any headers that are the same, data from 'other' is preferred.
+    """
+    for h in other._headers:
+      if not h in self._headers:
+        self._headers.append(h)
+
+    append_rows = []
+
+    for self_dict, other_dict in itertools.zip_longest(self._rows, other._rows):
+      if not self_dict:
+        d = {}
+        append_rows.append(d)
+      else:
+        d = self_dict
+
+      d_other = other_dict
+      if d_other:
+        for k,v in d_other.items():
+          d[k] = v
+
+    for r in append_rows:
+      self._rows.append(r)
+
+  def data_row_reduce(self, fnc) -> 'DataFrame':
+    """
+    Reduces the data row-wise by applying the fnc to each row (column-wise).
+    Empty cells are skipped.
+
+    fnc(Iterable[object]) -> object
+    fnc is applied over every non-empty cell in that column (descending row-wise).
+
+    Example:
+      DataFrame({'a':[1,2,3]}).data_row_reduce(sum) == DataFrame({'a':[6]})
+
+    Returns a new single-row DataFrame.
+    """
+    df = DataFrame()
+    df._headers = self._headers.copy()
+
+    def yield_by_column(header_key):
+      for row_dict in self._rows:
+        val = row_dict.get(header_key)
+        if val:
+          yield val
+
+    new_row_dict = {}
+    for h in df._headers:
+      cell_value = fnc(yield_by_column(h))
+      new_row_dict[h] = cell_value
+
+    df._rows = [new_row_dict]
+    return df
+
+  def _headers_only(self):
+    return self._headers
+
+  def _data_only(self):
+    row_len = len(self._rows)
+
+    for i in range(row_len):
+      yield self.data_row_at(i)
+
+  def _transposed_data(self):
+    return zip(*self._data_only())
\ No newline at end of file
diff --git a/startop/scripts/app_startup/lib/data_frame_test.py b/startop/scripts/app_startup/lib/data_frame_test.py
new file mode 100644
index 0000000..1cbc1cb
--- /dev/null
+++ b/startop/scripts/app_startup/lib/data_frame_test.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python3
+#
+# Copyright 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.
+#
+
+"""Unit tests for the data_frame.py script."""
+
+from data_frame import DataFrame
+
+def test_data_frame():
+  # trivial empty data frame
+  df = DataFrame()
+  assert df.headers == []
+  assert df.data_table == []
+  assert df.data_table_transposed == []
+
+  # common case, same number of values in each place.
+  df = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
+  assert df.headers == ['TotalTime_ms', 'Displayed_ms']
+  assert df.data_table == [[1, 4], [2, 5], [3, 6]]
+  assert df.data_table_transposed == [(1, 2, 3), (4, 5, 6)]
+
+  # varying num values.
+  df = DataFrame({'many': [1, 2], 'none': []})
+  assert df.headers == ['many', 'none']
+  assert df.data_table == [[1, None], [2, None]]
+  assert df.data_table_transposed == [(1, 2), (None, None)]
+
+  df = DataFrame({'many': [], 'none': [1, 2]})
+  assert df.headers == ['many', 'none']
+  assert df.data_table == [[None, 1], [None, 2]]
+  assert df.data_table_transposed == [(None, None), (1, 2)]
+
+  # merge multiple data frames
+  df = DataFrame()
+  df.concat_rows(DataFrame())
+  assert df.headers == []
+  assert df.data_table == []
+  assert df.data_table_transposed == []
+
+  df = DataFrame()
+  df2 = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
+
+  df.concat_rows(df2)
+  assert df.headers == ['TotalTime_ms', 'Displayed_ms']
+  assert df.data_table == [[1, 4], [2, 5], [3, 6]]
+  assert df.data_table_transposed == [(1, 2, 3), (4, 5, 6)]
+
+  df = DataFrame({'TotalTime_ms': [1, 2]})
+  df2 = DataFrame({'Displayed_ms': [4, 5]})
+
+  df.concat_rows(df2)
+  assert df.headers == ['TotalTime_ms', 'Displayed_ms']
+  assert df.data_table == [[1, None], [2, None], [None, 4], [None, 5]]
+
+  df = DataFrame({'TotalTime_ms': [1, 2]})
+  df2 = DataFrame({'TotalTime_ms': [3, 4], 'Displayed_ms': [5, 6]})
+
+  df.concat_rows(df2)
+  assert df.headers == ['TotalTime_ms', 'Displayed_ms']
+  assert df.data_table == [[1, None], [2, None], [3, 5], [4, 6]]
+
+  # data_row_at
+  df = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
+  assert df.data_row_at(-1) == [3, 6]
+  assert df.data_row_at(2) == [3, 6]
+  assert df.data_row_at(1) == [2, 5]
+
+  # repeat
+  df = DataFrame({'TotalTime_ms': [1], 'Displayed_ms': [4]})
+  df2 = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
+  assert df.repeat(3) == df2
+
+  # repeat
+  df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
+  assert df.data_row_len == 3
+  df = DataFrame({'TotalTime_ms': [1, 1]})
+  assert df.data_row_len == 2
+
+  # repeat
+  df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
+  assert df.data_row_len == 3
+  df = DataFrame({'TotalTime_ms': [1, 1]})
+  assert df.data_row_len == 2
+
+  # data_row_reduce
+  df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
+  df_sum = DataFrame({'TotalTime_ms': [3], 'Displayed_ms': [12]})
+  assert df.data_row_reduce(sum) == df_sum
+
+  # merge_data_columns
+  df = DataFrame({'TotalTime_ms': [1, 2, 3]})
+  df2 = DataFrame({'Displayed_ms': [3, 4, 5, 6]})
+
+  df.merge_data_columns(df2)
+  assert df == DataFrame(
+    {'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [3, 4, 5, 6]})
+
+  df = DataFrame({'TotalTime_ms': [1, 2, 3]})
+  df2 = DataFrame({'Displayed_ms': [3, 4]})
+
+  df.merge_data_columns(df2)
+  assert df == DataFrame(
+    {'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [3, 4]})
+
+  df = DataFrame({'TotalTime_ms': [1, 2, 3]})
+  df2 = DataFrame({'TotalTime_ms': [10, 11]})
+
+  df.merge_data_columns(df2)
+  assert df == DataFrame({'TotalTime_ms': [10, 11, 3]})
+
+  df = DataFrame({'TotalTime_ms': []})
+  df2 = DataFrame({'TotalTime_ms': [10, 11]})
+
+  df.merge_data_columns(df2)
+  assert df == DataFrame({'TotalTime_ms': [10, 11]})
diff --git a/startop/scripts/app_startup/metrics/com.google.android.GoogleCamera b/startop/scripts/app_startup/metrics/com.google.android.GoogleCamera
new file mode 100755
index 0000000..d95fa32
--- /dev/null
+++ b/startop/scripts/app_startup/metrics/com.google.android.GoogleCamera
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# 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.
+
+# 05-06 14:51:17.688 29691 29897 I CAM_Timing: CameraActivity: START -> ACTIVITY_FIRST_PREVIEW_FRAME_RECEIVED: 385ms
+pattern="CAM_Timing: CameraActivity: START -> ACTIVITY_FIRST_PREVIEW_FRAME_RECEIVED:"
+re_pattern='.*ACTIVITY_FIRST_PREVIEW_FRAME_RECEIVED: \([[:digit:]]\+\)ms'
+parse_metric_from_logcat "ACTIVITY_FIRST_PREVIEW_FRAME_RECEIVED_ms" "$pattern" "$re_pattern"
+
+# 05-06 14:51:17.724 29691 29691 I CAM_Timing: CameraActivity: START -> ACTIVITY_FIRST_PREVIEW_FRAME_RENDERED: 421ms
+pattern="CAM_Timing: CameraActivity: START -> ACTIVITY_FIRST_PREVIEW_FRAME_RENDERED:"
+re_pattern='.*ACTIVITY_FIRST_PREVIEW_FRAME_RENDERED: \([[:digit:]]\+\)ms'
+parse_metric_from_logcat "ACTIVITY_FIRST_PREVIEW_FRAME_RENDERED_ms" "$pattern" "$re_pattern"
diff --git a/startop/scripts/app_startup/parse_metrics b/startop/scripts/app_startup/parse_metrics
new file mode 100755
index 0000000..c6bf08e
--- /dev/null
+++ b/startop/scripts/app_startup/parse_metrics
@@ -0,0 +1,181 @@
+#!/bin/bash
+#
+# 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.
+
+usage() {
+    cat <<EOF
+Usage: launch_application package activity | parse_metrics --package <name> --timestamp <timestamp> [OPTIONS]...
+
+  Reads from stdin the result of 'am start' metrics. May also parse logcat
+  for additional metrics.
+
+  Output form:
+
+    MetricName_unit=numeric_value
+    MetricName2_unit=numeric_value2
+
+  This may block until all desired metrics are parsed from logcat.
+  To get a list of metrics without doing real parsing, use --simulate.
+
+  To add package-specific metrics, add a script called 'metrics/\$full_package_name'
+  that exposes additional metrics in same way as above.
+
+  (required)
+    -p, --package <name>        package of the app that is being used
+    -ts, --timestamp <name>     logcat timestamp [only looks at logcat entries after this timestamp].
+
+  (optional)
+    -s, --simulate              prints dummy values instead of real metrics
+    -a, --activity <name>       activity to use (default: inferred)
+    -h, --help                  usage information (this)
+    -v, --verbose               enable extra verbose printing
+    -t, --timeout <sec>         how many seconds to timeout when trying to wait for logcat to change
+EOF
+}
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source "$DIR/lib/common"
+
+package=""
+activity=""
+timeout=10
+simulate="n"
+parse_arguments() {
+  while [[ $# -gt 0 ]]; do
+    case "$1" in
+      -h|--help)
+        usage
+        exit 0
+        ;;
+      -p|--package)
+        package="$2"
+        shift
+        ;;
+      -a|--activity)
+        activity="$2"
+        shift
+        ;;
+      -v|--verbose)
+        export verbose="y"
+        ;;
+      -t|--timeout)
+        timeout="$2"
+        shift
+        ;;
+      -ts|--timestamp)
+        timestamp="$2"
+        shift
+        ;;
+      -s|--simulate)
+        simulate="y"
+        ;;
+      *)
+        echo "Invalid argument: $1" >&2
+        exit 1
+    esac
+    shift
+  done
+}
+
+# Main entry point
+if [[ $# -eq 0 ]]; then
+  usage
+  exit 1
+else
+  parse_arguments "$@"
+
+  # if we do not have have package exit early with an error
+  [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 64
+
+  # ignore timestamp for --simulate. it's optional.
+  if [[ $simulate == y ]]; then
+    timestamp=0
+  fi
+
+  # if we do not have timestamp, exit early with an error
+  [[ "$timestamp" == "" ]] && echo "--timestamp not specified" 1>&2 && exit 64
+
+  if [[ "$activity" == "" ]] && [[ "$simulate" != "y" ]]; then
+    activity="$(get_activity_name "$package")"
+    if [[ "$activity" == "" ]]; then
+      echo "Activity name could not be found, invalid package name?" 1>&2
+      exit 64
+    else
+      verbose_print "Activity name inferred: " "$activity"
+    fi
+  fi
+fi
+
+parse_metric_from_logcat() {
+  local metric_name="$1"
+  local pattern="$2"
+  local re_pattern="$3"
+  local retcode
+
+  # parse logcat for 'Displayed...' and that other one...
+
+  # 05-06 14:34:08.854 29460 29481 I ActivityTaskManager: Displayed com.google.android.dialer/.extensions.GoogleDialtactsActivity: +361ms
+  verbose_print "parse_metric_from_logcat: $re_pattern"
+
+
+  echo -ne "$metric_name="
+
+  if [[ $simulate == y ]]; then
+    echo "-1"
+    return 0
+  fi
+
+  logcat_extract_pattern "$timeout" "$timestamp" "$pattern" "$re_pattern"
+  retcode=$?
+
+  if [[ $retcode -ne 0 ]]; then
+    # Timed out before finding the pattern. Could also mean the pattern is wrong.
+    echo "-$?"
+  fi
+
+  return $retcode
+}
+
+
+total_time="-1"
+if [[ $simulate != y ]]; then
+  verbose_print 'logcat timestamp NOW: ' $(logcat_save_timestamp)
+
+  # parse stdin for 'am start' result
+  while read -t "$timeout" -r input_line; do
+    verbose_print 'stdin:' "$input_line"
+    if [[ $input_line == *TotalTime:* ]]; then
+      total_time="$(echo "$input_line" | sed 's/TotalTime: \([[:digit:]]\+\)/\1/g')"
+      # but keep reading the rest from stdin until <EOF>
+    fi
+  done
+fi
+
+echo "TotalTime_ms=$total_time"
+
+# parse logcat for 'Displayed...' and that other one...
+
+# 05-06 14:34:08.854 29460 29481 I ActivityTaskManager: Displayed com.google.android.dialer/.extensions.GoogleDialtactsActivity: +361ms
+pattern="ActivityTaskManager: Displayed ${package}"
+re_pattern='.*Displayed[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+\).*'
+
+parse_metric_from_logcat "Displayed_ms" "$pattern" "$re_pattern"
+
+# also call into package-specific scripts if there are additional metrics
+if [[ -x "$DIR/metrics/$package" ]]; then
+  source "$DIR/metrics/$package" "$timestamp"
+else
+  verbose_print parse_metrics: no per-package metrics script found at "$DIR/metrics/$package"
+fi
diff --git a/startop/scripts/app_startup/query_compiler_filter.py b/startop/scripts/app_startup/query_compiler_filter.py
index dc97c66..ea14264 100755
--- a/startop/scripts/app_startup/query_compiler_filter.py
+++ b/startop/scripts/app_startup/query_compiler_filter.py
@@ -31,13 +31,15 @@
 #
 
 import argparse
-import sys
+import os
 import re
+import sys
 
 # TODO: refactor this with a common library file with analyze_metrics.py
-import app_startup_runner
-from app_startup_runner import _debug_print
-from app_startup_runner import execute_arbitrary_command
+DIR = os.path.abspath(os.path.dirname(__file__))
+sys.path.append(os.path.dirname(DIR))
+import lib.cmd_utils as cmd_utils
+import lib.print_utils as print_utils
 
 from typing import List, NamedTuple, Iterable
 
@@ -74,7 +76,11 @@
       x86: [status=quicken] [reason=install]
 """ %(package, package, package, package)
 
-  code, res = execute_arbitrary_command(['adb', 'shell', 'dumpsys', 'package', package], simulate=False, timeout=5)
+  code, res = cmd_utils.execute_arbitrary_command(['adb', 'shell', 'dumpsys',
+                                                   'package', package],
+                                                  simulate=False,
+                                                  timeout=5,
+                                                  shell=False)
   if code:
     return res
   else:
@@ -115,7 +121,7 @@
       line = str_lines[line_num]
       current_indent = get_indent_level(line)
 
-      _debug_print("INDENT=%d, LINE=%s" %(current_indent, line))
+      print_utils.debug_print("INDENT=%d, LINE=%s" %(current_indent, line))
 
       current_label = line.lstrip()
 
@@ -135,7 +141,7 @@
       break
 
   new_remainder = str_lines[line_num::]
-  _debug_print("NEW REMAINDER: ", new_remainder)
+  print_utils.debug_print("NEW REMAINDER: ", new_remainder)
 
   parse_tree = ParseTree(label, children)
   return ParseResult(new_remainder, parse_tree)
@@ -159,7 +165,7 @@
 def find_first_compiler_filter(dexopt_state: DexoptState, package: str, instruction_set: str) -> str:
   lst = find_all_compiler_filters(dexopt_state, package)
 
-  _debug_print("all compiler filters: ", lst)
+  print_utils.debug_print("all compiler filters: ", lst)
 
   for compiler_filter_info in lst:
     if not instruction_set:
@@ -180,10 +186,10 @@
   if not package_tree:
     raise AssertionError("Could not find any package subtree for package %s" %(package))
 
-  _debug_print("package tree: ", package_tree)
+  print_utils.debug_print("package tree: ", package_tree)
 
   for path_tree in find_parse_children(package_tree, "path: "):
-    _debug_print("path tree: ", path_tree)
+    print_utils.debug_print("path tree: ", path_tree)
 
     matchre = re.compile("([^:]+):\s+\[status=([^\]]+)\]\s+\[reason=([^\]]+)\]")
 
@@ -198,16 +204,16 @@
 
 def main() -> int:
   opts = parse_options()
-  app_startup_runner._debug = opts.debug
+  cmd_utils._debug = opts.debug
   if _DEBUG_FORCE is not None:
-    app_startup_runner._debug = _DEBUG_FORCE
-  _debug_print("parsed options: ", opts)
+    cmd_utils._debug = _DEBUG_FORCE
+  print_utils.debug_print("parsed options: ", opts)
 
   # Note: This can often 'fail' if the package isn't actually installed.
   package_dumpsys = remote_dumpsys_package(opts.package, opts.simulate)
-  _debug_print("package dumpsys: ", package_dumpsys)
+  print_utils.debug_print("package dumpsys: ", package_dumpsys)
   dumpsys_parse_tree = parse_tab_tree(package_dumpsys, package_dumpsys)
-  _debug_print("parse tree: ", dumpsys_parse_tree)
+  print_utils.debug_print("parse tree: ", dumpsys_parse_tree)
   dexopt_state = parse_dexopt_state(dumpsys_parse_tree)
 
   filter = find_first_compiler_filter(dexopt_state, opts.package, opts.instruction_set)
diff --git a/startop/scripts/app_startup/run_app_with_prefetch b/startop/scripts/app_startup/run_app_with_prefetch
index 18aaf32..92a31c3 100755
--- a/startop/scripts/app_startup/run_app_with_prefetch
+++ b/startop/scripts/app_startup/run_app_with_prefetch
@@ -101,6 +101,15 @@
     esac
     shift
   done
+
+  if [[ $when == "aot" ]]; then
+    # TODO: re-implement aot later for experimenting.
+    echo "Error: --when $when is unsupported" >&2
+    exit 1
+  elif [[ $when != "jit" ]]; then
+    echo "Error: --when must be one of (aot jit)." >&2
+    exit 1
+  fi
 }
 
 echo_to_output_file() {
@@ -212,6 +221,12 @@
   local the_when="$1" # user: aot, jit
   local the_mode="$2" # warm, cold, fadvise, mlock, etc.
 
+  # iorapd readahead for jit+(mlock/fadvise)
+  if [[ $the_when == "jit" && $the_mode != 'warm' && $the_mode != 'cold' ]]; then
+    iorapd_readahead_enable
+    return 0
+  fi
+
   if [[ $the_when != "aot" ]]; then
     # TODO: just in time implementation.. should probably use system server.
     return 0
@@ -250,13 +265,18 @@
   local the_when="$1" # user: aot, jit
   local the_mode="$2" # warm, cold, fadvise, mlock, etc.
   local logcat_timestamp="$3"  # timestamp from before am start.
+  local res
 
   if [[ $the_when != "aot" ]]; then
     if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
       # Validate that readahead completes.
       # If this fails for some reason, then this will also discard the timing of the run.
       iorapd_readahead_wait_until_finished "$package" "$activity" "$logcat_timestamp" "$timeout"
-      return $?
+      res=$?
+
+      iorapd_readahead_disable
+
+      return $res
     fi
     # Don't need to do anything for warm or cold.
     return 0
@@ -317,6 +337,74 @@
 # No-op if this option was not passed in.
 configure_compiler_filter "$compiler_filter" "$package" "$activity" || exit 1
 
+# convert 'a=b\nc=d\ne=f\n...' into 'b,d,f,...'
+parse_metrics_output_string() {
+  # single string with newlines in it.
+  local input="$1"
+
+  local metric_name
+  local metric_value
+  local rest
+
+  local all_metrics=()
+
+  # (n1=v1 n2=v2 n3=v3 ...)
+  readarray -t all_metrics <<< "$input"
+
+  local kv_pair=()
+  local i
+
+  for i in "${all_metrics[@]}"
+  do
+    verbose_print "parse_metrics_output: element '$i'"
+    # name=value
+
+    IFS='=' read -r metric_name metric_value rest <<< "$i"
+
+    verbose_print "parse_metrics_output: metric_value '$metric_value'"
+
+    # (value1 value2 value3 ...)
+    all_metrics+=(${metric_value})
+  done
+
+  # "value1,value2,value3,..."
+  join_by ',' "${all_metrics[@]}"
+}
+
+# convert 'a=b\nc=d\ne=f\n... into b,d,f,...'
+parse_metrics_output() {
+  local metric_name
+  local metric_value
+  local rest
+
+  local all_metrics=()
+
+  while IFS='=' read -r metric_name metric_value rest; do
+    verbose_print "metric: $metric_name, value: $metric_value; rest: $rest"
+    all_metrics+=($metric_value)
+  done
+
+  join_by ',' "${all_metrics[@]}"
+}
+
+# convert 'a=b\nc=d\ne=f\n... into b,d,f,...'
+parse_metrics_header() {
+  local metric_name
+  local metric_value
+  local rest
+
+  local all_metrics=()
+
+  while IFS='=' read -r metric_name metric_value rest; do
+    verbose_print "metric: $metric_name, value: $metric_value; rest: $rest"
+    all_metrics+=($metric_name)
+  done
+
+  join_by ',' "${all_metrics[@]}"
+}
+
+metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate | parse_metrics_header)"
+
 # TODO: This loop logic could probably be moved into app_startup_runner.py
 for ((i=0;i<count;++i)) do
   verbose_print "=========================================="
@@ -335,7 +423,7 @@
   pre_launch_timestamp="$(logcat_save_timestamp)"
 
   # TODO: multiple metrics output.
-  total_time="$(timeout $timeout $DIR/launch_application "$package" "$activity")"
+  total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" | parse_metrics_output)"
 
   if [[ $? -ne 0 ]]; then
     echo "WARNING: Skip bad result, try iteration again." >&2
@@ -353,22 +441,21 @@
 
   echo "Iteration $i. Total time was: $total_time"
 
-  timings_array+=($total_time)
+  timings_array+=("$total_time")
 done
 
 # drop the first result which is usually garbage.
 timings_array=("${timings_array[@]:1}")
 
+# Print the CSV header first.
+echo_to_output_file "$metrics_header"
 
 # Print out interactive/debugging timings and averages.
 # Other scripts should use the --output flag and parse the CSV.
 for tim in "${timings_array[@]}"; do
-  echo_to_output_file -ne "$tim,"
+  echo_to_output_file "$tim"
 done
-echo_to_output_file ""
 
-average_string=$(echo "${timings_array[@]}" | awk '{s+=$0}END{print "Average:",s/NR}' RS=" ")
-echo -ne ${average_string}.
 if [[ x$output != x ]]; then
   echo " Saved results to '$output'"
 fi
diff --git a/startop/scripts/app_startup/run_app_with_prefetch.py b/startop/scripts/app_startup/run_app_with_prefetch.py
new file mode 100644
index 0000000..464742d
--- /dev/null
+++ b/startop/scripts/app_startup/run_app_with_prefetch.py
@@ -0,0 +1,377 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+"""Runner of one test given a setting.
+
+Run app and gather the measurement in a certain configuration.
+Print the result to stdout.
+See --help for more details.
+
+Sample usage:
+  $> ./python run_app_with_prefetch.py  -p com.android.settings -a
+     com.android.settings.Settings -r fadvise -i input
+
+"""
+
+import argparse
+import os
+import sys
+import time
+from typing import List, Tuple, Optional, NamedTuple
+
+# local imports
+import lib.adb_utils as adb_utils
+
+# global variables
+DIR = os.path.abspath(os.path.dirname(__file__))
+IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(DIR,
+                                                         '../iorap/common'))
+APP_STARTUP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(DIR,
+                                                               'lib/common'))
+
+sys.path.append(os.path.dirname(DIR))
+import lib.print_utils as print_utils
+import lib.cmd_utils as cmd_utils
+import iorap.lib.iorapd_utils as iorapd_utils
+
+RunCommandArgs = NamedTuple('RunCommandArgs',
+                            [('package', str),
+                             ('readahead', str),
+                             ('activity', Optional[str]),
+                             ('compiler_filter', Optional[str]),
+                             ('timeout', Optional[int]),
+                             ('debug', bool),
+                             ('simulate', bool),
+                             ('input', Optional[str])])
+
+def parse_options(argv: List[str] = None):
+  """Parses command line arguments and return an argparse Namespace object."""
+  parser = argparse.ArgumentParser(
+      description='Run an Android application once and measure startup time.'
+  )
+
+  required_named = parser.add_argument_group('required named arguments')
+  required_named.add_argument('-p', '--package', action='store', dest='package',
+                              help='package of the application', required=True)
+
+  # optional arguments
+  # use a group here to get the required arguments to appear 'above' the
+  # optional arguments in help.
+  optional_named = parser.add_argument_group('optional named arguments')
+  optional_named.add_argument('-a', '--activity', action='store',
+                              dest='activity',
+                              help='launch activity of the application')
+  optional_named.add_argument('-s', '--simulate', dest='simulate',
+                              action='store_true',
+                              help='simulate the process without executing '
+                                   'any shell commands')
+  optional_named.add_argument('-d', '--debug', dest='debug',
+                              action='store_true',
+                              help='Add extra debugging output')
+  optional_named.add_argument('-i', '--input', action='store', dest='input',
+                              help='perfetto trace file protobuf',
+                              default='TraceFile.pb')
+  optional_named.add_argument('-r', '--readahead', action='store',
+                              dest='readahead',
+                              help='which readahead mode to use',
+                              default='cold',
+                              choices=('warm', 'cold', 'mlock', 'fadvise'))
+  optional_named.add_argument('-t', '--timeout', dest='timeout', action='store',
+                              type=int,
+                              help='Timeout after this many seconds when '
+                                   'executing a single run.',
+                              default=10)
+  optional_named.add_argument('--compiler-filter', dest='compiler_filter',
+                              action='store',
+                              help='Which compiler filter to use.',
+                              default=None)
+
+  return parser.parse_args(argv)
+
+def validate_options(args: RunCommandArgs) -> Tuple[bool, RunCommandArgs]:
+  """Validates the activity and trace file if needed.
+
+  Returns:
+    A bool indicates whether the activity is valid and trace file exists if
+    necessary.
+  """
+  needs_trace_file = (args.readahead != 'cold' and args.readahead != 'warm')
+  if needs_trace_file and (args.input is None or
+                           not os.path.exists(args.input)):
+    print_utils.error_print('--input not specified!')
+    return False, args
+
+  if args.simulate:
+    args = args._replace(activity='act')
+
+  if not args.activity:
+    _, activity = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
+                                           'get_activity_name',
+                                           [args.package])
+    args = args._replace(activity=activity)
+
+  if not args.activity:
+    print_utils.error_print('Activity name could not be found, '
+                            'invalid package name?!')
+    return False, args
+
+  # Install necessary trace file. This must be after the activity checking.
+  if needs_trace_file:
+    passed = iorapd_utils.iorapd_compiler_install_trace_file(
+        args.package, args.activity, args.input)
+    if not cmd_utils.SIMULATE and not passed:
+      print_utils.error_print('Failed to install compiled TraceFile.pb for '
+                              '"{}/{}"'.
+                                format(args.package, args.activity))
+      return False, args
+
+  return True, args
+
+def set_up_adb_env():
+  """Sets up adb environment."""
+  adb_utils.root()
+  adb_utils.disable_selinux()
+  time.sleep(1)
+
+def configure_compiler_filter(compiler_filter: str, package: str,
+                              activity: str) -> bool:
+  """Configures compiler filter (e.g. speed).
+
+  Returns:
+    A bool indicates whether configure of compiler filer succeeds or not.
+  """
+  if not compiler_filter:
+    print_utils.debug_print('No --compiler-filter specified, don\'t'
+                            ' need to force it.')
+    return True
+
+  passed, current_compiler_filter_info = \
+    cmd_utils.run_shell_command(
+        '{} --package {}'.format(os.path.join(DIR, 'query_compiler_filter.py'),
+                                 package))
+
+  if passed != 0:
+    return passed
+
+  # TODO: call query_compiler_filter directly as a python function instead of
+  #  these shell calls.
+  current_compiler_filter, current_reason, current_isa = \
+    current_compiler_filter_info.split(' ')
+  print_utils.debug_print('Compiler Filter={} Reason={} Isa={}'.format(
+      current_compiler_filter, current_reason, current_isa))
+
+  # Don't trust reasons that aren't 'unknown' because that means
+  #  we didn't manually force the compilation filter.
+  # (e.g. if any automatic system-triggered compilations are not unknown).
+  if current_reason != 'unknown' or current_compiler_filter != compiler_filter:
+    passed, _ = adb_utils.run_shell_command('{}/force_compiler_filter '
+                                            '--compiler-filter "{}" '
+                                            '--package "{}"'
+                                            ' --activity "{}'.
+                                              format(DIR, compiler_filter,
+                                                     package, activity))
+  else:
+    adb_utils.debug_print('Queried compiler-filter matched requested '
+                          'compiler-filter, skip forcing.')
+    passed = False
+  return passed
+
+def parse_metrics_output(input: str,
+                         simulate: bool = False) -> List[Tuple[str, str, str]]:
+  """Parses ouput of app startup to metrics and corresponding values.
+
+  It converts 'a=b\nc=d\ne=f\n...' into '[(a,b,''),(c,d,''),(e,f,'')]'
+
+  Returns:
+    A list of tuples that including metric name, metric value and rest info.
+  """
+  all_metrics = []
+  for line in input.split('\n'):
+    if not line:
+      continue
+    splits = line.split('=')
+    if len(splits) < 2:
+      print_utils.error_print('Bad line "{}"'.format(line))
+      continue
+    metric_name = splits[0]
+    metric_value = splits[1]
+    rest = splits[2] if len(splits) > 2 else ''
+    if rest:
+      print_utils.error_print('Corrupt line "{}"'.format(line))
+    print_utils.debug_print('metric: "{metric_name}", '
+                            'value: "{metric_value}" '.
+                              format(metric_name=metric_name,
+                                   metric_value=metric_value))
+
+    all_metrics.append((metric_name, metric_value))
+  return all_metrics
+
+def _parse_total_time(am_start_output: str) -> Optional[str]:
+  """Parses the total time from 'adb shell am start pkg' output.
+
+  Returns:
+    the total time of app startup.
+  """
+  for line in am_start_output.split('\n'):
+    if 'TotalTime:' in line:
+      return line[len('TotalTime:'):].strip()
+  return None
+
+def blocking_parse_all_metrics(am_start_output: str, package: str,
+                               pre_launch_timestamp: str,
+                               timeout: int) -> str:
+  """Parses the metric after app startup by reading from logcat in a blocking
+  manner until all metrics have been found".
+
+  Returns:
+    the total time and displayed time of app startup.
+    For example: "TotalTime=123\nDisplayedTime=121
+  """
+  total_time = _parse_total_time(am_start_output)
+  displayed_time = adb_utils.blocking_wait_for_logcat_displayed_time(
+      pre_launch_timestamp, package, timeout)
+
+  return 'TotalTime={}\nDisplayedTime={}'.format(total_time, displayed_time)
+
+def run(readahead: str,
+        package: str,
+        activity: str,
+        timeout: int,
+        simulate: bool,
+        debug: bool) -> List[Tuple[str, str]]:
+  """Runs app startup test.
+
+  Returns:
+    A list of tuples that including metric name, metric value and rest info.
+  """
+  print_utils.debug_print('==========================================')
+  print_utils.debug_print('=====             START              =====')
+  print_utils.debug_print('==========================================')
+
+  # Kill any existing process of this app
+  adb_utils.pkill(package)
+
+  if readahead != 'warm':
+    print_utils.debug_print('Drop caches for non-warm start.')
+    # Drop all caches to get cold starts.
+    adb_utils.vm_drop_cache()
+
+  if readahead != 'warm' and readahead != 'cold':
+    iorapd_utils.enable_iorapd_readahead()
+
+  print_utils.debug_print('Running with timeout {}'.format(timeout))
+
+  pre_launch_timestamp = adb_utils.logcat_save_timestamp()
+
+  passed, output = cmd_utils.run_shell_command('timeout {timeout} '
+                                               '"{DIR}/launch_application" '
+                                               '"{package}" '
+                                               '"{activity}"'
+                                                 .format(timeout=timeout,
+                                                       DIR=DIR,
+                                                       package=package,
+                                                       activity=activity))
+  if not passed and not simulate:
+    return None
+
+  if simulate:
+    results = [('TotalTime', '123')]
+  else:
+    output = blocking_parse_all_metrics(output,
+                                        package,
+                                        pre_launch_timestamp,
+                                        timeout)
+    results = parse_metrics_output(output, simulate)
+
+  passed = perform_post_launch_cleanup(
+      readahead, package, activity, timeout, debug, pre_launch_timestamp)
+  if not passed and not simulate:
+    print_utils.error_print('Cannot perform post launch cleanup!')
+    return None
+
+  adb_utils.pkill(package)
+  return results
+
+def perform_post_launch_cleanup(readahead: str,
+                                package: str,
+                                activity: str,
+                                timeout: int,
+                                debug: bool,
+                                logcat_timestamp: str) -> bool:
+  """Performs cleanup at the end of each loop iteration.
+
+  Returns:
+    A bool indicates whether the cleanup succeeds or not.
+  """
+  if readahead != 'warm' and readahead != 'cold':
+    passed = iorapd_utils.wait_for_iorapd_finish(package,
+                                                 activity,
+                                                 timeout,
+                                                 debug,
+                                                 logcat_timestamp)
+
+    if not passed:
+      return passed
+
+    return iorapd_utils.disable_iorapd_readahead()
+
+  # Don't need to do anything for warm or cold.
+  return True
+
+def run_test(args: RunCommandArgs) -> List[Tuple[str, str]]:
+  """Runs one test using given options.
+
+  Returns:
+    A list of tuples that including metric name, metric value.
+  """
+  print_utils.DEBUG = args.debug
+  cmd_utils.SIMULATE = args.simulate
+
+  passed, args = validate_options(args)
+  if not passed:
+    return None
+
+  set_up_adb_env()
+
+  # Ensure the APK is currently compiled with whatever we passed in
+  # via --compiler-filter.
+  # No-op if this option was not passed in.
+  if not configure_compiler_filter(args.compiler_filter, args.package,
+                                   args.activity):
+    return None
+
+  return run(args.readahead, args.package, args.activity, args.timeout,
+             args.simulate, args.debug)
+
+def get_args_from_opts(opts: argparse.Namespace) -> RunCommandArgs:
+  kwargs = {}
+  for field in RunCommandArgs._fields:
+    kwargs[field] = getattr(opts, field)
+  return RunCommandArgs(**kwargs)
+
+def main():
+  opts = parse_options()
+  args = get_args_from_opts(opts)
+  result = run_test(args)
+
+  if result is None:
+    return 1
+
+  print(result)
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/startop/scripts/app_startup/run_app_with_prefetch_test.py b/startop/scripts/app_startup/run_app_with_prefetch_test.py
new file mode 100644
index 0000000..8536ce5
--- /dev/null
+++ b/startop/scripts/app_startup/run_app_with_prefetch_test.py
@@ -0,0 +1,283 @@
+#!/usr/bin/env python3
+#
+# 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.
+#
+"""Unit tests for the run_app_with_prefetch_test.py script.
+
+Install:
+  $> sudo apt-get install python3-pytest   ##  OR
+  $> pip install -U pytest
+See also https://docs.pytest.org/en/latest/getting-started.html
+
+Usage:
+  $> ./run_app_with_prefetch_test.py
+  $> pytest run_app_with_prefetch_test.py
+  $> python -m pytest run_app_with_prefetch_test.py
+
+See also https://docs.pytest.org/en/latest/usage.html
+"""
+
+import io
+import os
+import shlex
+import sys
+# global imports
+from contextlib import contextmanager
+
+# pip imports
+import pytest
+# local imports
+import run_app_with_prefetch as run
+from mock import Mock, call, patch
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+#
+# Argument Parsing Helpers
+#
+
+@contextmanager
+def ignore_stdout_stderr():
+  """Ignore stdout/stderr output for duration of this context."""
+  old_stdout = sys.stdout
+  old_stderr = sys.stderr
+  sys.stdout = io.StringIO()
+  sys.stderr = io.StringIO()
+  try:
+    yield
+  finally:
+    sys.stdout = old_stdout
+    sys.stderr = old_stderr
+
+@contextmanager
+def argparse_bad_argument(msg):
+  """Asserts that a SystemExit is raised when executing this context.
+
+  If the assertion fails, print the message 'msg'.
+  """
+  with pytest.raises(SystemExit, message=msg):
+    with ignore_stdout_stderr():
+      yield
+
+def assert_bad_argument(args, msg):
+  """Asserts that the command line arguments in 'args' are malformed.
+
+    Prints 'msg' if the assertion fails.
+  """
+  with argparse_bad_argument(msg):
+    parse_args(args)
+
+def parse_args(args):
+  """
+    :param args: command-line like arguments as a single string
+    :return:  dictionary of parsed key/values
+    """
+  # "-a b -c d"    => ['-a', 'b', '-c', 'd']
+  return vars(run.parse_options(shlex.split(args)))
+
+def default_dict_for_parsed_args(**kwargs):
+  """Combines it with all of the "optional" parameters' default values."""
+  d = {
+    'readahead': 'cold',
+    'simulate': None,
+    'simulate': False,
+    'debug': False,
+    'input': 'TraceFile.pb',
+    'timeout': 10,
+    'compiler_filter': None,
+    'activity': None
+  }
+  d.update(kwargs)
+  return d
+
+def default_mock_dict_for_parsed_args(include_optional=True, **kwargs):
+  """Combines default dict with all optional parameters with some mock required
+    parameters.
+    """
+  d = {'package': 'com.fake.package'}
+  if include_optional:
+    d.update(default_dict_for_parsed_args())
+  d.update(kwargs)
+  return d
+
+def parse_optional_args(str):
+  """
+    Parses an argument string which already includes all the required arguments
+    in default_mock_dict_for_parsed_args.
+  """
+  req = '--package com.fake.package'
+  return parse_args('%s %s' % (req, str))
+
+def test_argparse():
+  # missing arguments
+  assert_bad_argument('', '-p are required')
+
+  # required arguments are parsed correctly
+  ad = default_dict_for_parsed_args  # assert dict
+  assert parse_args('--package xyz') == ad(package='xyz')
+
+  assert parse_args('-p xyz') == ad(package='xyz')
+
+  assert parse_args('-p xyz -s') == ad(package='xyz', simulate=True)
+  assert parse_args('-p xyz --simulate') == ad(package='xyz', simulate=True)
+
+  # optional arguments are parsed correctly.
+  mad = default_mock_dict_for_parsed_args  # mock assert dict
+  assert parse_optional_args('--input trace.pb') == mad(input='trace.pb')
+
+  assert parse_optional_args('--compiler-filter speed') == \
+         mad(compiler_filter='speed')
+
+  assert parse_optional_args('-d') == mad(debug=True)
+  assert parse_optional_args('--debug') == mad(debug=True)
+
+  assert parse_optional_args('--timeout 123') == mad(timeout=123)
+  assert parse_optional_args('-t 456') == mad(timeout=456)
+
+  assert parse_optional_args('-r warm') == mad(readahead='warm')
+  assert parse_optional_args('--readahead warm') == mad(readahead='warm')
+
+  assert parse_optional_args('-a act') == mad(activity='act')
+  assert parse_optional_args('--activity act') == mad(activity='act')
+
+def test_main():
+  args = '--package com.fake.package --activity act -s'
+  opts = run.parse_options(shlex.split(args))
+
+  args = run.get_args_from_opts(opts)
+  result = run.run_test(args)
+  assert result == [('TotalTime', '123')]
+
+def test_set_up_adb_env():
+  with patch('lib.cmd_utils.run_shell_command',
+             new_callable=Mock) as mock_run_shell_command:
+    mock_run_shell_command.return_value = (True, '')
+    run.set_up_adb_env()
+
+    calls = [call('adb root'),
+             call('adb shell "getenforce"'),
+             call('adb shell "setenforce 0"'),
+             call('adb shell "stop"'),
+             call('adb shell "start"'),
+             call('adb wait-for-device')]
+    mock_run_shell_command.assert_has_calls(calls)
+
+def test_set_up_adb_env_with_permissive():
+  with patch('lib.cmd_utils.run_shell_command',
+             new_callable=Mock) as mock_run_shell_command:
+    mock_run_shell_command.return_value = (True, 'Permissive')
+    run.set_up_adb_env()
+
+    calls = [call('adb root'), call('adb shell "getenforce"')]
+    mock_run_shell_command.assert_has_calls(calls)
+
+def test_configure_compiler_filter():
+  with patch('lib.cmd_utils.run_shell_command',
+             new_callable=Mock) as mock_run_shell_command:
+    mock_run_shell_command.return_value = (True, 'speed arm64 kUpToDate')
+    run.configure_compiler_filter('speed', 'music', 'MainActivity')
+
+    calls = [call(os.path.join(run.DIR, 'query_compiler_filter.py') +
+                  ' --package music')]
+    mock_run_shell_command.assert_has_calls(calls)
+
+def test_parse_metrics_output():
+  input = 'a1=b1\nc1=d1\ne1=f1'
+  ret = run.parse_metrics_output(input)
+
+  assert ret == [('a1', 'b1'), ('c1', 'd1'), ('e1', 'f1')]
+
+def _mocked_run_shell_command(*args, **kwargs):
+  if args[0] == 'adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"':
+    return (True, "2019-07-02 23:20:06.972674825")
+  elif args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'':
+    return (True, '9999')
+  else:
+    return (True, 'a1=b1\nc1=d1=d2\ne1=f1')
+
+@patch('lib.adb_utils.blocking_wait_for_logcat_displayed_time')
+@patch('lib.cmd_utils.run_shell_command')
+def test_run_no_vm_cache_drop(mock_run_shell_command,
+                              mock_blocking_wait_for_logcat_displayed_time):
+  mock_run_shell_command.side_effect = _mocked_run_shell_command
+  mock_blocking_wait_for_logcat_displayed_time.return_value = 123
+
+  run.run('warm',
+          'music',
+          'MainActivity',
+          timeout=10,
+          simulate=False,
+          debug=False)
+
+  calls = [call('adb shell ps | grep "music" | awk \'{print $2;}\''),
+           call('adb shell "kill 9999"'),
+           call('adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"'),
+           call(
+             'timeout {timeout} "{DIR}/launch_application" "{package}" "{activity}"'
+               .format(timeout=10,
+                       DIR=run.DIR,
+                       package='music',
+                       activity='MainActivity',
+                       timestamp='2019-07-02 23:20:06.972674825')),
+           call('adb shell ps | grep "music" | awk \'{print $2;}\''),
+           call('adb shell "kill 9999"')]
+  mock_run_shell_command.assert_has_calls(calls)
+
+@patch('lib.adb_utils.blocking_wait_for_logcat_displayed_time')
+@patch('lib.cmd_utils.run_shell_command')
+def test_run_with_vm_cache_drop_and_post_launch_cleanup(
+    mock_run_shell_command,
+    mock_blocking_wait_for_logcat_displayed_time):
+  mock_run_shell_command.side_effect = _mocked_run_shell_command
+  mock_blocking_wait_for_logcat_displayed_time.return_value = 123
+
+  run.run('fadvise',
+          'music',
+          'MainActivity',
+          timeout=10,
+          simulate=False,
+          debug=False)
+
+  calls = [call('adb shell ps | grep "music" | awk \'{print $2;}\''),
+           call('adb shell "kill 9999"'),
+           call('adb shell "echo 3 > /proc/sys/vm/drop_caches"'),
+           call('bash -c "source {}; iorapd_readahead_enable"'.
+                format(run.IORAP_COMMON_BASH_SCRIPT)),
+           call('adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"'),
+           call(
+             'timeout {timeout} "{DIR}/launch_application" '
+             '"{package}" "{activity}"'
+               .format(timeout=10,
+                       DIR=run.DIR,
+                       package='music',
+                       activity='MainActivity',
+                       timestamp='2019-07-02 23:20:06.972674825')),
+           call(
+             'bash -c "source {script_path}; '
+             'iorapd_readahead_wait_until_finished '
+             '\'{package}\' \'{activity}\' \'{timestamp}\' \'{timeout}\'"'.
+               format(timeout=10,
+                      package='music',
+                      activity='MainActivity',
+                      timestamp='2019-07-02 23:20:06.972674825',
+                      script_path=run.IORAP_COMMON_BASH_SCRIPT)),
+           call('bash -c "source {}; iorapd_readahead_disable"'.
+                format(run.IORAP_COMMON_BASH_SCRIPT)),
+           call('adb shell ps | grep "music" | awk \'{print $2;}\''),
+           call('adb shell "kill 9999"')]
+  mock_run_shell_command.assert_has_calls(calls)
+
+if __name__ == '__main__':
+  pytest.main()
diff --git a/startop/scripts/iorap/collector b/startop/scripts/iorap/collector
index 8d105ad..3dc080a 100755
--- a/startop/scripts/iorap/collector
+++ b/startop/scripts/iorap/collector
@@ -263,9 +263,19 @@
   # Ensure application isn't running already.
   remote_pkill "$package"
 
+  # 5 second trace of Home screen causes
+  # a trace of the home screen.
+  # There is no way to abort the trace
+  # so just wait for it to complete instead.
+  sleep 30
+
   local time_now="$(logcat_save_timestamp)"
   local retcode=0
 
+  verbose_print "Drop caches for non-warm start."
+  # Drop all caches to get cold starts.
+  adb shell "echo 3 > /proc/sys/vm/drop_caches"
+
   verbose_print "now launching application"
   # Launch an application
   "$APP_STARTUP_DIR"/launch_application "$package" "$activity"
@@ -312,11 +322,15 @@
   iorapd_compiler_purge_trace_file "$package" "$activity" || return $?
 
   iorapd_perfetto_enable || return $?
+  iorapd_readahead_disable || return $?
   iorapd_start || return $?
 
   # Wait for perfetto trace to finished writing itself out.
   launch_application_and_wait_for_trace "$package" "$activity" || return $?
 
+  # Pull the perfetto trace for manual inspection.
+  iorapd_perfetto_pull_trace_file "$package" "$activity" "perfetto_trace.pb"
+
   # Compile the trace so that the next app run can use prefetching.
   iorapd_compiler_for_app_trace "$package" "$activity" "$inodes" || return $?
 
diff --git a/startop/scripts/iorap/common b/startop/scripts/iorap/common
index 6dde3d5..031dabf 100755
--- a/startop/scripts/iorap/common
+++ b/startop/scripts/iorap/common
@@ -15,7 +15,7 @@
 # limitations under the License.
 
 DIR_IORAP_COMMON="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-APP_STARTUP_DIR="$DIR/../app_startup/"
+APP_STARTUP_DIR="$DIR_IORAP_COMMON/../app_startup/"
 source "$APP_STARTUP_DIR/lib/common"
 
 IORAPD_DATA_PATH="/data/misc/iorapd"
@@ -45,7 +45,7 @@
   iorapd_reset # iorapd only reads this flag when initializing
 }
 
-# Enable perfetto tracing.
+# Disable perfetto tracing.
 # Subsequent launches of applications will no longer record perfetto trace protobufs.
 iorapd_perfetto_disable() {
   verbose_print 'disable perfetto'
@@ -53,6 +53,31 @@
   iorapd_reset # iorapd only reads this flag when initializing
 }
 
+# Enable readahead
+# Subsequent launches of an application will be sped up by iorapd readahead prefetching
+# (Provided an appropriate compiled trace exists for that application)
+iorapd_readahead_enable() {
+  if [[ "$(adb shell getprop iorapd.readahead.enable)" == true ]]; then
+    verbose_print 'enable readahead [already enabled]'
+    return 0
+  fi
+  verbose_print 'enable readahead [reset iorapd]'
+  adb shell setprop iorapd.readahead.enable true
+  iorapd_reset # iorapd only reads this flag when initializing
+}
+
+# Disable readahead
+# Subsequent launches of an application will be not be sped up by iorapd readahead prefetching.
+iorapd_readahead_disable() {
+  if [[ "$(adb shell getprop iorapd.readahead.enable)" == false ]]; then
+    verbose_print 'disable readahead [already disabled]'
+    return 0
+  fi
+  verbose_print 'disable readahead [reset iorapd]'
+  adb shell setprop iorapd.readahead.enable false
+  iorapd_reset # iorapd only reads this flag when initializing
+}
+
 _iorapd_path_to_data_file() {
   local package="$1"
   local activity="$2"
@@ -88,6 +113,26 @@
   adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
 }
 
+# Pull the remote perfetto trace file into a local file.
+iorapd_perfetto_pull_trace_file() {
+  local package="$1"
+  local activity="$2"
+  local output_file="$3" # local path
+
+  local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
+
+  if ! adb shell "[[ -f '$compiled_path' ]]"; then
+    echo "Error: Remote path '$compiled_path' invalid" >&2
+    return 1
+  fi
+  if ! mkdir -p "$(dirname "$output_file")"; then
+    echo "Error: Fail to make output directory for '$output_file'" >&2
+    return 1
+  fi
+  verbose_print adb pull "$compiled_path" "$output_file"
+  adb pull "$compiled_path" "$output_file"
+}
+
 # Compile a perfetto trace for a given application.
 # This requires the app has run at least once with perfetto tracing enabled.
 iorapd_compiler_for_app_trace() {
@@ -114,6 +159,7 @@
   # inodes file needs to be on the device for iorap.cmd.compiler to access it
   local remote_inodes=/data/local/tmp/prefetch/inodes.txt
   adb shell "mkdir -p \"$(dirname "$remote_inodes")\"" || return 1
+  verbose_print adb push "$inodes" "$remote_inodes"
   adb push "$inodes" "$remote_inodes"
 
   verbose_print 'iorapd-compiler: compile app trace in ' "$input_path"
@@ -130,7 +176,7 @@
   fi
 
   # Clean up inodes file we just pushed.
-  adb shell "[[ -f '$remote_inodes' ]] && rm -f '$remote_inodes'"
+#  adb shell "[[ -f '$remote_inodes' ]] && rm -f '$remote_inodes'"
 
   return $retcode
 }
diff --git a/startop/scripts/iorap/compile_handcrafted_file.py b/startop/scripts/iorap/compile_handcrafted_file.py
new file mode 100755
index 0000000..6dbbeaf
--- /dev/null
+++ b/startop/scripts/iorap/compile_handcrafted_file.py
@@ -0,0 +1,297 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+import argparse
+import asyncio
+import csv
+import itertools
+import os
+import re
+import struct
+import sys
+import tempfile
+import time
+import zipfile
+from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union
+
+# Include generated protos.
+dir_name = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(dir_name + "/generated")
+
+from TraceFile_pb2 import *
+
+
+def parse_options(argv: List[str] = None):
+  """Parse command line arguments and return an argparse Namespace object."""
+  parser = argparse.ArgumentParser(description="Compile a TraceFile.proto from a manual text file.")
+  # argparse considers args starting with - and -- optional in --help, even though required=True.
+  # by using a named argument group --help will clearly say that it's required instead of optional.
+  required_named = parser.add_argument_group('required named arguments')
+
+  # optional arguments
+  # use a group here to get the required arguments to appear 'above' the optional arguments in help.
+  optional_named = parser.add_argument_group('optional named arguments')
+  optional_named.add_argument('-opb', '--output-proto-binary', dest='output_proto_binary', action='store', help='Write binary proto output to file.')
+  optional_named.add_argument('-pm', '--pinlist-meta', dest='pinlist_meta', action='store', help='Path to pinlist.meta (default=none) binary file.')
+  optional_named.add_argument('-pmp', '--pinlist-meta-parent', dest='pinlist_meta_parent', action='store', help='Device path that the pinlist.meta applies to (e.g. /data/.../somefile.apk)')
+  optional_named.add_argument('-i', '--input', dest='input', action='store', help='Input text file (default stdin).')
+  optional_named.add_argument('-zp', '--zip_path', dest='zip_path', action='append', help='Directory containing zip files.')
+  optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
+  optional_named.add_argument('-ot', '--output-text', dest='output_text', action='store', help='Output text file (default stdout).')
+
+  return parser.parse_args(argv)
+
+# TODO: refactor this with a common library file with analyze_metrics.py
+def _debug_print(*args, **kwargs):
+  """Print the args to sys.stderr if the --debug/-d flag was passed in."""
+  if _debug:
+    print(*args, **kwargs, file=sys.stderr)
+
+class BadInputError(Exception):
+  pass
+
+InputRecord = NamedTuple('InputRecord', [('filepath', str), ('offset', int), ('length', int), ('remark', str)])
+
+def find_zip_in_paths(original_name, zip_paths):
+  # /foo/bar/bax.zip -> bax.zip
+  file_basename = os.path.split(original_name)[1]
+
+  # the file must be located in one of the --zip-path arguments
+  matched = None
+  for zip_path in zip_paths:
+    for dir_entry in os.listdir(zip_path):
+      if dir_entry == file_basename:
+        matched = os.path.join(zip_path, dir_entry)
+        break
+    if matched:
+      break
+
+  if not matched:
+    raise ValueError("%s could not be found in any of the --zip_path specified." %(file_basename))
+
+  _debug_print("found zip file ", file_basename, " in ", matched)
+
+  if not zipfile.is_zipfile(matched):
+    raise ValueError("%s is not a zip file" %(matched))
+
+  return matched
+
+def handle_zip_entry(input_record, zip_paths):
+
+  res = re.match("([^!]+)[!](.*)", input_record.filepath)
+
+  if not res:
+    return input_record
+
+                         # 'foo!bar'
+  in_filepath = res[1]   # -> 'foo'
+  in_zip_entry = res[2]  # -> 'bar'
+
+  matched = find_zip_in_paths(in_filepath, zip_paths)
+
+  zip = zipfile.ZipFile(matched)
+
+  try:
+    zip_info = zip.getinfo(in_zip_entry)
+  except KeyError:
+    raise ValueError("%s is not an item in the zip file %s" %(in_zip_entry, matched))
+
+  # TODO: do we also need to add header size to this?
+  in_offset = zip_info.header_offset
+
+  # TODO: if a range is specified, use that instead.
+  in_length = zip_info.compress_size
+
+  return InputRecord(in_filepath, in_offset, in_length, 'zip entry (%s)' %(in_zip_entry))
+
+def parse_input_file(input: Iterable[str], zip_paths: List[str]) -> Iterable[InputRecord]:
+  for line in input:
+    line = line.strip()
+
+    _debug_print("Line = ", line)
+    if not line:
+      _debug_print("  skip empty line", line)
+      continue
+    elif line[0] == "#":
+      _debug_print("  skip commented line", line)
+      continue
+
+    res = re.match("([^\s]+)\s+(\d+)\s+(\d+)", line)
+    if not res:
+      raise BadInputError("Expected input of form: <str:filepath> <int:offset> <int:length>")
+
+    in_filepath = res[1]
+    in_offset = int(res[2])
+    in_length = int(res[3])
+
+    yield handle_zip_entry(InputRecord(in_filepath, in_offset, in_length, 'regular file'), zip_paths)
+
+# format:
+#   (<big_endian(i32):file_offset> <big_endian(i32):range_length>)+
+PIN_META_FORMAT = ">ii"
+PIN_META_READ_SIZE = struct.calcsize(PIN_META_FORMAT)
+
+def parse_pin_meta(pin_meta_file, pinlist_meta_parent, zip_paths):
+  if not pin_meta_file:
+    return ()
+
+  global PIN_META_FORMAT
+  global PIN_META_READ_SIZE
+
+  # '/data/app/com.google.android.GoogleCamera-aNQhzSznf4h_bvJ_MRbweQ==/base.apk'
+  #  -> 'com.google.android.GoogleCamera'
+  package_name_match = re.match('/.*/(.*)-.*=/base.apk', pinlist_meta_parent)
+
+  if not package_name_match:
+    raise ValueError("%s did not contain the <packagename>.apk" %(pinlist_meta_parent))
+
+  package_name = package_name_match[1]
+  # "com.google.android.GoogleCamera" -> "GoogleCamera.apk"
+  apk_name = package_name.split(".")[-1] + ".apk"
+
+  path_to_zip_on_host = find_zip_in_paths(apk_name, zip_paths)
+  apk_file_size = os.path.getsize(path_to_zip_on_host)
+  _debug_print("APK path '%s' file size '%d'" %(path_to_zip_on_host, apk_file_size))
+
+  while True:
+    data = pin_meta_file.read(PIN_META_READ_SIZE)
+
+    if not data:
+      break
+
+    (pin_offset, pin_length) = struct.unpack(PIN_META_FORMAT, data)  # (offset, length)
+
+    remark = 'regular file (pinlist.meta)'
+
+    remaining_size = apk_file_size - pin_offset
+    if remaining_size < 0:
+      print("WARNING: Clamp entry (%d, %d), offset too large (max file size = %d)" %(pin_offset, pin_length, apk_file_size))
+
+      pin_length = pin_length + remaining_size
+      pin_offset = pin_offset + remaining_size
+
+      if pin_offset < 0:
+        pin_offset = 0
+
+      remark += '[clamped.offset]'
+
+    pin_last_offset = pin_offset + pin_length
+    remaining_size = apk_file_size - pin_last_offset
+
+    if remaining_size < 0:
+      print("WARNING: Clamp entry (%d, %d), length too large (max file size = %d)" %(pin_offset, pin_length, apk_file_size))
+      pin_length = pin_length + remaining_size
+
+      remark += '[clamped.length]'
+
+    yield InputRecord(pinlist_meta_parent, pin_offset, pin_length, remark)
+
+def write_text_file_output(input_records: Iterable[InputRecord], output_text_file):
+  for rec in input_records:
+    output_text_file.write("%s %d %d #%s\n" %(rec.filepath, rec.offset, rec.length, rec.remark))
+
+def build_trace_file(input_records: Iterable[InputRecord]) -> TraceFile:
+  trace_file = TraceFile()
+  trace_file_index = trace_file.index
+
+  file_id_counter = 0
+  file_id_map = {} # filename -> id
+
+  stats_length_total = 0
+  filename_stats = {} # filename -> total size
+
+  for rec in input_records:
+    filename = rec.filepath
+
+    file_id = file_id_map.get(filename)
+    if not file_id:
+      file_id = file_id_counter
+      file_id_map[filename] = file_id_counter
+      file_id_counter = file_id_counter + 1
+
+      file_index_entry = trace_file_index.entries.add()
+      file_index_entry.id = file_id
+      file_index_entry.file_name = filename
+
+    # already in the file index, add the file entry.
+    file_entry = trace_file.list.entries.add()
+    file_entry.index_id = file_id
+    file_entry.file_length = rec.length
+    stats_length_total += file_entry.file_length
+    file_entry.file_offset = rec.offset
+
+    filename_stats[filename] = filename_stats.get(filename, 0) + file_entry.file_length
+
+  return trace_file
+
+def main():
+  global _debug
+
+  options= parse_options()
+  _debug = options.debug
+  _debug_print("parsed options: ", options)
+
+  if not options.input:
+    input_file = sys.stdin
+    _debug_print("input = stdin")
+  else:
+    input_file = open(options.input)
+    _debug_print("input = (file)", options.input)
+
+  if not options.output_proto_binary:
+    output_proto_file = None
+  else:
+    output_proto_file = open(options.output_proto_binary, 'wb')
+  _debug_print("output_proto_binary = ", output_proto_file)
+
+  pinlist_meta_parent = options.pinlist_meta_parent
+  if options.pinlist_meta:
+    pin_meta_file = open(options.pinlist_meta, 'rb')
+  else:
+    pin_meta_file = None
+
+  if (pinlist_meta_parent == None) != (pin_meta_file == None):
+    print("Options must be used together: --pinlist-meta and --pinlist-meta-path")
+    return 1
+
+  if not options.output_text:
+    output_text_file = sys.stdout
+    _debug_print("output = stdout")
+  else:
+    output_text_file = open(options.output_text, 'w')
+    _debug_print("output = (file)", options.output_text)
+
+  zip_paths = options.zip_path or []
+
+  input_records = list(parse_pin_meta(pin_meta_file, pinlist_meta_parent, zip_paths))
+  input_records = input_records + list(parse_input_file(input_file, zip_paths))
+
+  for p in input_records:
+    _debug_print(p)
+
+  write_text_file_output(input_records, output_text_file)
+  output_text_file.close()
+
+  out_proto = build_trace_file(input_records)
+
+  if output_proto_file:
+    output_proto_file.write(out_proto.SerializeToString())
+    output_proto_file.close()
+
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/startop/scripts/iorap/compiler.py b/startop/scripts/iorap/compiler.py
new file mode 100755
index 0000000..1e15736
--- /dev/null
+++ b/startop/scripts/iorap/compiler.py
@@ -0,0 +1,271 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+#
+# Dependencies:
+#
+# $> sudo apt-get install python3-pip
+# $> pip3 install --user protobuf sqlalchemy sqlite3
+#
+
+import optparse
+import os
+import re
+import sys
+from typing import Iterable, Optional
+
+from generated.TraceFile_pb2 import *
+from lib.inode2filename import Inode2Filename
+
+parent_dir_name = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+sys.path.append(parent_dir_name + "/trace_analyzer")
+from lib.trace2db import Trace2Db, MmFilemapAddToPageCache, RawFtraceEntry
+
+_PAGE_SIZE = 4096 # adb shell getconf PAGESIZE ## size of a memory page in bytes.
+
+class PageRun:
+  """
+  Intermediate representation for a run of one or more pages.
+  """
+  def __init__(self, device_number: int, inode: int, offset: int, length: int):
+    self.device_number = device_number
+    self.inode = inode
+    self.offset = offset
+    self.length = length
+
+  def __str__(self):
+    return "PageRun(device_number=%d, inode=%d, offset=%d, length=%d)" \
+        %(self.device_number, self.inode, self.offset, self.length)
+
+def debug_print(msg):
+  #print(msg)
+  pass
+
+UNDER_LAUNCH = False
+
+def page_cache_entries_to_runs(page_cache_entries: Iterable[MmFilemapAddToPageCache]):
+  global _PAGE_SIZE
+
+  runs = [
+      PageRun(device_number=pg_entry.dev, inode=pg_entry.ino, offset=pg_entry.ofs,
+              length=_PAGE_SIZE)
+        for pg_entry in page_cache_entries
+  ]
+
+  for r in runs:
+    debug_print(r)
+
+  print("Stats: Page runs totaling byte length: %d" %(len(runs) * _PAGE_SIZE))
+
+  return runs
+
+def optimize_page_runs(page_runs):
+  new_entries = []
+  last_entry = None
+  for pg_entry in page_runs:
+    if last_entry:
+      if pg_entry.device_number == last_entry.device_number and pg_entry.inode == last_entry.inode:
+        # we are dealing with a run for the same exact file as a previous run.
+        if pg_entry.offset == last_entry.offset + last_entry.length:
+          # trivially contiguous entries. merge them together.
+          last_entry.length += pg_entry.length
+          continue
+    # Default: Add the run without merging it to a previous run.
+    last_entry = pg_entry
+    new_entries.append(pg_entry)
+  return new_entries
+
+def is_filename_matching_filter(file_name, filters=[]):
+  """
+  Blacklist-style regular expression filters.
+
+  :return: True iff file_name has an RE match in one of the filters.
+  """
+  for filt in filters:
+    res = re.search(filt, file_name)
+    if res:
+      return True
+
+  return False
+
+def build_protobuf(page_runs, inode2filename, filters=[]):
+  trace_file = TraceFile()
+  trace_file_index = trace_file.index
+
+  file_id_counter = 0
+  file_id_map = {} # filename -> id
+
+  stats_length_total = 0
+  filename_stats = {} # filename -> total size
+
+  skipped_inode_map = {}
+  filtered_entry_map = {} # filename -> count
+
+  for pg_entry in page_runs:
+    fn = inode2filename.resolve(pg_entry.device_number, pg_entry.inode)
+    if not fn:
+      skipped_inode_map[pg_entry.inode] = skipped_inode_map.get(pg_entry.inode, 0) + 1
+      continue
+
+    filename = fn
+
+    if filters and not is_filename_matching_filter(filename, filters):
+      filtered_entry_map[filename] = filtered_entry_map.get(filename, 0) + 1
+      continue
+
+    file_id = file_id_map.get(filename)
+    if not file_id:
+      file_id = file_id_counter
+      file_id_map[filename] = file_id_counter
+      file_id_counter = file_id_counter + 1
+
+      file_index_entry = trace_file_index.entries.add()
+      file_index_entry.id = file_id
+      file_index_entry.file_name = filename
+
+    # already in the file index, add the file entry.
+    file_entry = trace_file.list.entries.add()
+    file_entry.index_id = file_id
+    file_entry.file_length = pg_entry.length
+    stats_length_total += file_entry.file_length
+    file_entry.file_offset = pg_entry.offset
+
+    filename_stats[filename] = filename_stats.get(filename, 0) + file_entry.file_length
+
+  for inode, count in skipped_inode_map.items():
+    print("WARNING: Skip inode %s because it's not in inode map (%d entries)" %(inode, count))
+
+  print("Stats: Sum of lengths %d" %(stats_length_total))
+
+  if filters:
+    print("Filter: %d total files removed." %(len(filtered_entry_map)))
+
+    for fn, count in filtered_entry_map.items():
+      print("Filter: File '%s' removed '%d' entries." %(fn, count))
+
+  for filename, file_size in filename_stats.items():
+    print("%s,%s" %(filename, file_size))
+
+  return trace_file
+
+def calc_trace_end_time(trace2db: Trace2Db,
+                        trace_duration: Optional[int]) -> float:
+  """
+  Calculates the end time based on the trace duration.
+  The start time is the first receiving mm file map event.
+  The end time is the start time plus the trace duration.
+  All of them are in milliseconds.
+  """
+  # If the duration is not set, assume all time is acceptable.
+  if trace_duration is None:
+    # float('inf')
+    return RawFtraceEntry.__table__.c.timestamp.type.python_type('inf')
+
+  first_event = trace2db.session.query(MmFilemapAddToPageCache).join(
+      MmFilemapAddToPageCache.raw_ftrace_entry).order_by(
+      RawFtraceEntry.timestamp).first()
+
+  return first_event.raw_ftrace_entry.timestamp + trace_duration
+
+def query_add_to_page_cache(trace2db: Trace2Db, trace_duration: Optional[int]):
+  end_time = calc_trace_end_time(trace2db, trace_duration)
+  # SELECT * FROM tbl ORDER BY id;
+  return trace2db.session.query(MmFilemapAddToPageCache).join(
+      MmFilemapAddToPageCache.raw_ftrace_entry).filter(
+      RawFtraceEntry.timestamp <= end_time).order_by(
+      MmFilemapAddToPageCache.id).all()
+
+def main(argv):
+  parser = optparse.OptionParser(usage="Usage: %prog [options]", description="Compile systrace file into TraceFile.pb")
+  parser.add_option('-i', dest='inode_data_file', metavar='FILE',
+                    help='Read cached inode data from a file saved earlier with pagecache.py -d')
+  parser.add_option('-t', dest='trace_file', metavar='FILE',
+                    help='Path to systrace file (trace.html) that will be parsed')
+
+  parser.add_option('--db', dest='sql_db', metavar='FILE',
+                    help='Path to intermediate sqlite3 database [default: in-memory].')
+
+  parser.add_option('-f', dest='filter', action="append", default=[],
+                    help="Add file filter. All file entries not matching one of the filters are discarded.")
+
+  parser.add_option('-l', dest='launch_lock', action="store_true", default=False,
+                    help="Exclude all events not inside launch_lock")
+
+  parser.add_option('-o', dest='output_file', metavar='FILE',
+                    help='Output protobuf file')
+
+  parser.add_option('--duration', dest='trace_duration', action="store",
+                    type=int, help='The duration of trace in milliseconds.')
+
+  options, categories = parser.parse_args(argv[1:])
+
+  # TODO: OptionParser should have some flags to make these mandatory.
+  if not options.inode_data_file:
+    parser.error("-i is required")
+  if not options.trace_file:
+    parser.error("-t is required")
+  if not options.output_file:
+    parser.error("-o is required")
+
+  if options.launch_lock:
+    print("INFO: Launch lock flag (-l) enabled; filtering all events not inside launch_lock.")
+
+
+  inode_table = Inode2Filename.new_from_filename(options.inode_data_file)
+
+  trace_file = open(options.trace_file)
+
+  sql_db_path = ":memory:"
+  if options.sql_db:
+    sql_db_path = options.sql_db
+
+  trace2db = Trace2Db(sql_db_path)
+  # Speed optimization: Skip any entries that aren't mm_filemap_add_to_pagecache.
+  trace2db.set_raw_ftrace_entry_filter(\
+      lambda entry: entry['function'] == 'mm_filemap_add_to_page_cache')
+  # TODO: parse multiple trace files here.
+  parse_count = trace2db.parse_file_into_db(options.trace_file)
+
+  mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db,
+                                                              options.trace_duration)
+  print("DONE. Parsed %d entries into sql db." %(len(mm_filemap_add_to_page_cache_rows)))
+
+  page_runs = page_cache_entries_to_runs(mm_filemap_add_to_page_cache_rows)
+  print("DONE. Converted %d entries" %(len(page_runs)))
+
+  # TODO: flags to select optimizations.
+  optimized_page_runs = optimize_page_runs(page_runs)
+  print("DONE. Optimized down to %d entries" %(len(optimized_page_runs)))
+
+  print("Build protobuf...")
+  trace_file = build_protobuf(optimized_page_runs, inode_table, options.filter)
+
+  print("Write protobuf to file...")
+  output_file = open(options.output_file, 'wb')
+  output_file.write(trace_file.SerializeToString())
+  output_file.close()
+
+  print("DONE")
+
+  # TODO: Silent running mode [no output except on error] for build runs.
+
+  return 0
+
+if __name__ == '__main__':
+  print(sys.argv)
+  sys.exit(main(sys.argv))
diff --git a/startop/scripts/iorap/compiler_test.py b/startop/scripts/iorap/compiler_test.py
new file mode 100644
index 0000000..fcb7269
--- /dev/null
+++ b/startop/scripts/iorap/compiler_test.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+#
+# 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.
+#
+
+"""
+Unit tests for the compiler.py script.
+
+Install:
+  $> sudo apt-get install python3-pytest   ##  OR
+  $> pip install -U pytest
+See also https://docs.pytest.org/en/latest/getting-started.html
+
+Usage:
+  $> pytest compiler_test.py
+
+See also https://docs.pytest.org/en/latest/usage.html
+"""
+import os
+
+import compiler
+
+DIR = os.path.abspath(os.path.dirname(__file__))
+TEXTCACHE = os.path.join(DIR, 'test_fixtures/compiler/common_textcache')
+SYSTRACE = os.path.join(DIR, 'test_fixtures/compiler/common_systrace')
+ARGV = [os.path.join(DIR, 'compiler.py'), '-i', TEXTCACHE, '-t', SYSTRACE]
+
+def assert_compile_result(output, expected, *extra_argv):
+  argv = ARGV + ['-o', output] + [args for args in extra_argv]
+
+  compiler.main(argv)
+
+  with open(output, 'rb') as f1, open(expected, 'rb') as f2:
+    assert f1.read() == f2.read()
+
+def test_compiler_main(tmpdir):
+  output = tmpdir.mkdir('compiler').join('output')
+
+  # No duration
+  expected = os.path.join(DIR,
+                          'test_fixtures/compiler/test_result_without_duration.TraceFile.pb')
+  assert_compile_result(output, expected)
+
+  # 10ms duration
+  expected = os.path.join(DIR,
+                          'test_fixtures/compiler/test_result_with_duration.TraceFile.pb')
+  assert_compile_result(output, expected, '--duration', '10')
+
+  # 30ms duration
+  expected = os.path.join(DIR,
+                          'test_fixtures/compiler/test_result_without_duration.TraceFile.pb')
+  assert_compile_result(output, expected, '--duration', '30')
diff --git a/startop/scripts/iorap/generated/TraceFile_pb2.py b/startop/scripts/iorap/generated/TraceFile_pb2.py
new file mode 100644
index 0000000..f005bed
--- /dev/null
+++ b/startop/scripts/iorap/generated/TraceFile_pb2.py
@@ -0,0 +1,259 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: TraceFile.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='TraceFile.proto',
+  package='iorap.serialize.proto',
+  syntax='proto2',
+  serialized_pb=_b('\n\x0fTraceFile.proto\x12\x15iorap.serialize.proto\"u\n\tTraceFile\x12\x34\n\x05index\x18\x01 \x02(\x0b\x32%.iorap.serialize.proto.TraceFileIndex\x12\x32\n\x04list\x18\x02 \x02(\x0b\x32$.iorap.serialize.proto.TraceFileList\"M\n\x0eTraceFileIndex\x12;\n\x07\x65ntries\x18\x01 \x03(\x0b\x32*.iorap.serialize.proto.TraceFileIndexEntry\"4\n\x13TraceFileIndexEntry\x12\n\n\x02id\x18\x01 \x02(\x03\x12\x11\n\tfile_name\x18\x02 \x02(\t\"G\n\rTraceFileList\x12\x36\n\x07\x65ntries\x18\x01 \x03(\x0b\x32%.iorap.serialize.proto.TraceFileEntry\"L\n\x0eTraceFileEntry\x12\x10\n\x08index_id\x18\x01 \x02(\x03\x12\x13\n\x0b\x66ile_offset\x18\x02 \x02(\x03\x12\x13\n\x0b\x66ile_length\x18\x03 \x02(\x03\x42\x1c\n\x18\x63om.google.android.iorapH\x03')
+)
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+
+_TRACEFILE = _descriptor.Descriptor(
+  name='TraceFile',
+  full_name='iorap.serialize.proto.TraceFile',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='index', full_name='iorap.serialize.proto.TraceFile.index', index=0,
+      number=1, type=11, cpp_type=10, label=2,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='list', full_name='iorap.serialize.proto.TraceFile.list', index=1,
+      number=2, type=11, cpp_type=10, label=2,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=42,
+  serialized_end=159,
+)
+
+
+_TRACEFILEINDEX = _descriptor.Descriptor(
+  name='TraceFileIndex',
+  full_name='iorap.serialize.proto.TraceFileIndex',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='entries', full_name='iorap.serialize.proto.TraceFileIndex.entries', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=161,
+  serialized_end=238,
+)
+
+
+_TRACEFILEINDEXENTRY = _descriptor.Descriptor(
+  name='TraceFileIndexEntry',
+  full_name='iorap.serialize.proto.TraceFileIndexEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='iorap.serialize.proto.TraceFileIndexEntry.id', index=0,
+      number=1, type=3, cpp_type=2, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='file_name', full_name='iorap.serialize.proto.TraceFileIndexEntry.file_name', index=1,
+      number=2, type=9, cpp_type=9, label=2,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=240,
+  serialized_end=292,
+)
+
+
+_TRACEFILELIST = _descriptor.Descriptor(
+  name='TraceFileList',
+  full_name='iorap.serialize.proto.TraceFileList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='entries', full_name='iorap.serialize.proto.TraceFileList.entries', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=294,
+  serialized_end=365,
+)
+
+
+_TRACEFILEENTRY = _descriptor.Descriptor(
+  name='TraceFileEntry',
+  full_name='iorap.serialize.proto.TraceFileEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='index_id', full_name='iorap.serialize.proto.TraceFileEntry.index_id', index=0,
+      number=1, type=3, cpp_type=2, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='file_offset', full_name='iorap.serialize.proto.TraceFileEntry.file_offset', index=1,
+      number=2, type=3, cpp_type=2, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='file_length', full_name='iorap.serialize.proto.TraceFileEntry.file_length', index=2,
+      number=3, type=3, cpp_type=2, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=367,
+  serialized_end=443,
+)
+
+_TRACEFILE.fields_by_name['index'].message_type = _TRACEFILEINDEX
+_TRACEFILE.fields_by_name['list'].message_type = _TRACEFILELIST
+_TRACEFILEINDEX.fields_by_name['entries'].message_type = _TRACEFILEINDEXENTRY
+_TRACEFILELIST.fields_by_name['entries'].message_type = _TRACEFILEENTRY
+DESCRIPTOR.message_types_by_name['TraceFile'] = _TRACEFILE
+DESCRIPTOR.message_types_by_name['TraceFileIndex'] = _TRACEFILEINDEX
+DESCRIPTOR.message_types_by_name['TraceFileIndexEntry'] = _TRACEFILEINDEXENTRY
+DESCRIPTOR.message_types_by_name['TraceFileList'] = _TRACEFILELIST
+DESCRIPTOR.message_types_by_name['TraceFileEntry'] = _TRACEFILEENTRY
+
+TraceFile = _reflection.GeneratedProtocolMessageType('TraceFile', (_message.Message,), dict(
+  DESCRIPTOR = _TRACEFILE,
+  __module__ = 'TraceFile_pb2'
+  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFile)
+  ))
+_sym_db.RegisterMessage(TraceFile)
+
+TraceFileIndex = _reflection.GeneratedProtocolMessageType('TraceFileIndex', (_message.Message,), dict(
+  DESCRIPTOR = _TRACEFILEINDEX,
+  __module__ = 'TraceFile_pb2'
+  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileIndex)
+  ))
+_sym_db.RegisterMessage(TraceFileIndex)
+
+TraceFileIndexEntry = _reflection.GeneratedProtocolMessageType('TraceFileIndexEntry', (_message.Message,), dict(
+  DESCRIPTOR = _TRACEFILEINDEXENTRY,
+  __module__ = 'TraceFile_pb2'
+  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileIndexEntry)
+  ))
+_sym_db.RegisterMessage(TraceFileIndexEntry)
+
+TraceFileList = _reflection.GeneratedProtocolMessageType('TraceFileList', (_message.Message,), dict(
+  DESCRIPTOR = _TRACEFILELIST,
+  __module__ = 'TraceFile_pb2'
+  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileList)
+  ))
+_sym_db.RegisterMessage(TraceFileList)
+
+TraceFileEntry = _reflection.GeneratedProtocolMessageType('TraceFileEntry', (_message.Message,), dict(
+  DESCRIPTOR = _TRACEFILEENTRY,
+  __module__ = 'TraceFile_pb2'
+  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileEntry)
+  ))
+_sym_db.RegisterMessage(TraceFileEntry)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\030com.google.android.iorapH\003'))
+# @@protoc_insertion_point(module_scope)
diff --git a/startop/scripts/iorap/generated/codegen_protos b/startop/scripts/iorap/generated/codegen_protos
new file mode 100755
index 0000000..5688711
--- /dev/null
+++ b/startop/scripts/iorap/generated/codegen_protos
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# 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.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+APROTOC="$(which aprotoc)"
+
+IORAP_SERIALIZE_DIR="${DIR}/../../../../../../system/iorap/src/serialize"
+IORAP_PROTOS=($IORAP_SERIALIZE_DIR/*.proto)
+
+if [[ $? -ne 0 ]]; then
+  echo "Fatal: Missing aprotoc. Set APROTOC=... or lunch build/envsetup.sh?" >&2
+  exit 1
+fi
+
+if ! [[ -d $IORAP_SERIALIZE_DIR ]]; then
+  echo "Fatal: Directory '$IORAP_SERIALIZE_DIR' does not exist." >&2
+  exit 1
+fi
+
+# codegen the .py files into the same directory as this script.
+echo "$APROTOC" --proto_path="$IORAP_SERIALIZE_DIR" --python_out="$DIR" "${IORAP_PROTOS[@]}"
+"$APROTOC" --proto_path="$IORAP_SERIALIZE_DIR" --python_out="$DIR" "${IORAP_PROTOS[@]}"
diff --git a/startop/scripts/iorap/lib/inode2filename.py b/startop/scripts/iorap/lib/inode2filename.py
new file mode 100644
index 0000000..2e71393
--- /dev/null
+++ b/startop/scripts/iorap/lib/inode2filename.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union, TextIO
+
+import re
+
+class Inode2Filename:
+  """
+  Parses a text file of the format
+     "uint(dev_t) uint(ino_t) int(file_size) string(filepath)\\n"*
+
+  Lines not matching this format are ignored.
+  """
+
+  def __init__(self, inode_data_file: TextIO):
+    """
+    Create an Inode2Filename that reads cached inode from a file saved earlier
+    (e.g. with pagecache.py -d or with inode2filename --format=textcache)
+
+    :param inode_data_file: a file object (e.g. created with open or StringIO).
+
+    Lifetime: inode_data_file is only used during the construction of the object.
+    """
+    self._inode_table = Inode2Filename.build_inode_lookup_table(inode_data_file)
+
+  @classmethod
+  def new_from_filename(cls, textcache_filename: str) -> 'Inode2Filename':
+    """
+    Create an Inode2Filename that reads cached inode from a file saved earlier
+    (e.g. with pagecache.py -d or with inode2filename --format=textcache)
+
+    :param textcache_filename: path to textcache
+    """
+    with open(textcache_filename) as inode_data_file:
+      return cls(inode_data_file)
+
+  @staticmethod
+  def build_inode_lookup_table(inode_data_file: TextIO) -> Dict[Tuple[int, int], Tuple[str, str]]:
+    """
+    :return: map { (device_int, inode_int) -> (filename_str, size_str) }
+    """
+    inode2filename = {}
+    for line in inode_data_file:
+      # stat -c "%d %i %s %n
+      # device number, inode number, total size in bytes, file name
+      result = re.match('([0-9]+)d? ([0-9]+) -?([0-9]+) (.*)', line)
+      if result:
+        inode2filename[(int(result.group(1)), int(result.group(2)))] = \
+            (result.group(4), result.group(3))
+
+    return inode2filename
+
+  def resolve(self, dev_t: int, ino_t: int) -> Optional[str]:
+    """
+    Return a filename (str) from a (dev_t, ino_t) inode pair.
+
+    Returns None if the lookup fails.
+    """
+    maybe_result = self._inode_table.get((dev_t, ino_t))
+
+    if not maybe_result:
+      return None
+
+    return maybe_result[0] # filename str
+
+  def __len__(self) -> int:
+    """
+    :return: the number of inode entries parsed from the file.
+    """
+    return len(self._inode_table)
+
+  def __repr__(self) -> str:
+    """
+    :return: string representation for debugging/test failures.
+    """
+    return "Inode2Filename%s" %(repr(self._inode_table))
+
+  # end of class.
diff --git a/startop/scripts/iorap/lib/inode2filename_test.py b/startop/scripts/iorap/lib/inode2filename_test.py
new file mode 100755
index 0000000..1224c61
--- /dev/null
+++ b/startop/scripts/iorap/lib/inode2filename_test.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+#
+# 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.
+#
+
+"""
+Unit tests for inode2filename module.
+
+Install:
+  $> sudo apt-get install python3-pytest   ##  OR
+  $> pip install -U pytest
+See also https://docs.pytest.org/en/latest/getting-started.html
+
+Usage:
+  $> ./inode2filename_test.py
+  $> pytest inode2filename_test.py
+  $> python -m pytest inode2filename_test.py
+
+See also https://docs.pytest.org/en/latest/usage.html
+"""
+
+# global imports
+from contextlib import contextmanager
+import io
+import shlex
+import sys
+import typing
+
+# pip imports
+import pytest
+
+# local imports
+from inode2filename import *
+
+def create_inode2filename(*contents):
+  buf = io.StringIO()
+
+  for c in contents:
+    buf.write(c)
+    buf.write("\n")
+
+  buf.seek(0)
+
+  i2f = Inode2Filename(buf)
+
+  buf.close()
+
+  return i2f
+
+def test_inode2filename():
+  a = create_inode2filename("")
+  assert len(a) == 0
+  assert a.resolve(1, 2) == None
+
+  a = create_inode2filename("1 2 3 foo.bar")
+  assert len(a) == 1
+  assert a.resolve(1, 2) == "foo.bar"
+  assert a.resolve(4, 5) == None
+
+  a = create_inode2filename("1 2 3 foo.bar", "4 5 6 bar.baz")
+  assert len(a) == 2
+  assert a.resolve(1, 2) == "foo.bar"
+  assert a.resolve(4, 5) == "bar.baz"
+
+  a = create_inode2filename("1567d 8910 -1 /a/b/c/", "4 5 6 bar.baz")
+  assert len(a) == 2
+  assert a.resolve(1567, 8910) == "/a/b/c/"
+  assert a.resolve(4, 5) == "bar.baz"
+
+if __name__ == '__main__':
+  pytest.main()
diff --git a/startop/scripts/iorap/lib/iorapd_utils.py b/startop/scripts/iorap/lib/iorapd_utils.py
new file mode 100644
index 0000000..c03e9b0
--- /dev/null
+++ b/startop/scripts/iorap/lib/iorapd_utils.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+"""Helper util libraries for iorapd related operations."""
+
+import os
+import sys
+from pathlib import Path
+
+# up to two level, like '../../'
+sys.path.append(Path(os.path.abspath(__file__)).parents[2])
+import lib.cmd_utils as cmd_utils
+
+IORAPID_LIB_DIR = os.path.abspath(os.path.dirname(__file__))
+IORAPD_DATA_PATH = '/data/misc/iorapd'
+IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(IORAPID_LIB_DIR,
+                                                         '../common'))
+
+def _iorapd_path_to_data_file(package: str, activity: str, suffix: str) -> str:
+  """Gets conventional data filename.
+
+   Returns:
+     The path of iorapd data file.
+
+  """
+  # Match logic of 'AppComponentName' in iorap::compiler C++ code.
+  return '{}/{}%2F{}.{}'.format(IORAPD_DATA_PATH, package, activity, suffix)
+
+def iorapd_compiler_install_trace_file(package: str, activity: str,
+                                       input_file: str) -> bool:
+  """Installs a compiled trace file.
+
+  Returns:
+    Whether the trace file is installed successful or not.
+  """
+  # remote path calculations
+  compiled_path = _iorapd_path_to_data_file(package, activity,
+                                            'compiled_trace.pb')
+
+  if not os.path.exists(input_file):
+    print('Error: File {} does not exist'.format(input_file))
+    return False
+
+  passed, _ = cmd_utils.run_adb_shell_command(
+    'mkdir -p "$(dirname "{}")"'.format(compiled_path))
+  if not passed:
+    return False
+
+  passed, _ = cmd_utils.run_shell_command('adb push "{}" "{}"'.format(
+    input_file, compiled_path))
+
+  return passed
+
+def wait_for_iorapd_finish(package: str,
+                           activity: str,
+                           timeout: int,
+                           debug: bool,
+                           logcat_timestamp: str)->bool:
+  """Waits for the finish of iorapd.
+
+  Returns:
+    A bool indicates whether the iorapd is done successfully or not.
+  """
+  # Set verbose for bash script based on debug flag.
+  if debug:
+    os.putenv('verbose', 'y')
+
+  # Validate that readahead completes.
+  # If this fails for some reason, then this will also discard the timing of
+  # the run.
+  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
+                                       'iorapd_readahead_wait_until_finished',
+                                       [package, activity, logcat_timestamp,
+                                        str(timeout)])
+  return passed
+
+
+def enable_iorapd_readahead() -> bool:
+  """
+  Disable readahead. Subsequent launches of an application will be sped up
+  by iorapd readahead prefetching.
+
+  Returns:
+    A bool indicates whether the enabling is done successfully or not.
+  """
+  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
+                                       'iorapd_readahead_enable', [])
+  return passed
+
+def disable_iorapd_readahead() -> bool:
+  """
+  Disable readahead. Subsequent launches of an application will be not be sped
+  up by iorapd readahead prefetching.
+
+  Returns:
+    A bool indicates whether the disabling is done successfully or not.
+  """
+  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
+                                       'iorapd_readahead_disable', [])
+  return passed
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_systrace b/startop/scripts/iorap/test_fixtures/compiler/common_systrace
new file mode 100644
index 0000000..4573738
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/common_systrace
@@ -0,0 +1,5 @@
+<...>-2965  (-----) [001] .... 10000.746629: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000679ee1ec pfn=1299913 ofs=192512
+<...>-2965  (-----) [001] .... 10010.746664: mm_filemap_add_to_page_cache: dev 253:6 ino 2 page=0000000006cd2fb7 pfn=1296251 ofs=196608
+<...>-2965  (-----) [001] .... 10020.746677: mm_filemap_add_to_page_cache: dev 253:6 ino 3 page=00000000af82f3d6 pfn=1419330 ofs=200704
+<...>-2965  (-----) [001] .... 10030.746693: mm_filemap_add_to_page_cache: dev 253:6 ino 4 page=000000002840f054 pfn=1304928 ofs=204800
+<...>-2965  (-----) [001] .... 10040.746706: mm_filemap_add_to_page_cache: dev 253:6 ino 5 page=000000004a59da17 pfn=1288069 ofs=208896
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_textcache b/startop/scripts/iorap/test_fixtures/compiler/common_textcache
new file mode 100644
index 0000000..da03004
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/common_textcache
@@ -0,0 +1,2 @@
+64774 1 -1 /system/test1
+64774 3 -1 /data/test2
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
new file mode 100644
index 0000000..ab3df45
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
Binary files differ
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
new file mode 100644
index 0000000..17cb116
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
Binary files differ
diff --git a/startop/scripts/lib/cmd_utils.py b/startop/scripts/lib/cmd_utils.py
new file mode 100644
index 0000000..bc5ca31
--- /dev/null
+++ b/startop/scripts/lib/cmd_utils.py
@@ -0,0 +1,172 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+"""Helper util libraries for command line operations."""
+
+import asyncio
+import sys
+import time
+from typing import Tuple, Optional, List
+
+import lib.print_utils as print_utils
+
+TIMEOUT = 50
+SIMULATE = False
+
+def run_adb_shell_command(cmd: str) -> Tuple[bool, str]:
+  """Runs command using adb shell.
+
+  Returns:
+    A tuple of running status (True=succeeded, False=failed or timed out) and
+    std output (string contents of stdout with trailing whitespace removed).
+  """
+  return run_shell_command('adb shell "{}"'.format(cmd))
+
+def run_shell_func(script_path: str,
+                   func: str,
+                   args: List[str]) -> Tuple[bool, str]:
+  """Runs shell function with default timeout.
+
+  Returns:
+    A tuple of running status (True=succeeded, False=failed or timed out) and
+    std output (string contents of stdout with trailing whitespace removed) .
+  """
+  if args:
+    cmd = 'bash -c "source {script_path}; {func} {args}"'.format(
+      script_path=script_path,
+      func=func,
+      args=' '.join("'{}'".format(arg) for arg in args))
+  else:
+    cmd = 'bash -c "source {script_path}; {func}"'.format(
+      script_path=script_path,
+      func=func)
+
+  print_utils.debug_print(cmd)
+  return run_shell_command(cmd)
+
+def run_shell_command(cmd: str) -> Tuple[bool, str]:
+  """Runs shell command with default timeout.
+
+  Returns:
+    A tuple of running status (True=succeeded, False=failed or timed out) and
+    std output (string contents of stdout with trailing whitespace removed) .
+  """
+  return execute_arbitrary_command([cmd],
+                                   TIMEOUT,
+                                   shell=True,
+                                   simulate=SIMULATE)
+
+def execute_arbitrary_command(cmd: List[str],
+                              timeout: int,
+                              shell: bool,
+                              simulate: bool) -> Tuple[bool, str]:
+  """Run arbitrary shell command with default timeout.
+
+    Mostly copy from
+    frameworks/base/startop/scripts/app_startup/app_startup_runner.py.
+
+  Args:
+    cmd: list of cmd strings.
+    timeout: the time limit of running cmd.
+    shell: indicate if the cmd is a shell command.
+    simulate: if it's true, do not run the command and assume the running is
+        successful.
+
+  Returns:
+    A tuple of running status (True=succeeded, False=failed or timed out) and
+    std output (string contents of stdout with trailing whitespace removed) .
+  """
+  if simulate:
+    print(cmd)
+    return True, ''
+
+  print_utils.debug_print('[EXECUTE]', cmd)
+  # block until either command finishes or the timeout occurs.
+  loop = asyncio.get_event_loop()
+
+  (return_code, script_output) = loop.run_until_complete(
+    _run_command(*cmd, shell=shell, timeout=timeout))
+
+  script_output = script_output.decode()  # convert bytes to str
+
+  passed = (return_code == 0)
+  print_utils.debug_print('[$?]', return_code)
+  if not passed:
+    print('[FAILED, code:%s]' % (return_code), script_output, file=sys.stderr)
+
+  return passed, script_output.rstrip()
+
+async def _run_command(*args: List[str],
+                       shell: bool = False,
+                       timeout: Optional[int] = None) -> Tuple[int, bytes]:
+  if shell:
+    process = await asyncio.create_subprocess_shell(
+      *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
+  else:
+    process = await asyncio.create_subprocess_exec(
+      *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
+
+  script_output = b''
+
+  print_utils.debug_print('[PID]', process.pid)
+
+  timeout_remaining = timeout
+  time_started = time.time()
+
+  # read line (sequence of bytes ending with b'\n') asynchronously
+  while True:
+    try:
+      line = await asyncio.wait_for(process.stdout.readline(),
+                                    timeout_remaining)
+      print_utils.debug_print('[STDOUT]', line)
+      script_output += line
+
+      if timeout_remaining:
+        time_elapsed = time.time() - time_started
+        timeout_remaining = timeout - time_elapsed
+    except asyncio.TimeoutError:
+      print_utils.debug_print('[TIMEDOUT] Process ', process.pid)
+
+      print_utils.debug_print('[TIMEDOUT] Sending SIGTERM.')
+      process.terminate()
+
+      # 5 second timeout for process to handle SIGTERM nicely.
+      try:
+        (remaining_stdout,
+         remaining_stderr) = await asyncio.wait_for(process.communicate(), 5)
+        script_output += remaining_stdout
+      except asyncio.TimeoutError:
+        print_utils.debug_print('[TIMEDOUT] Sending SIGKILL.')
+        process.kill()
+
+      # 5 second timeout to finish with SIGKILL.
+      try:
+        (remaining_stdout,
+         remaining_stderr) = await asyncio.wait_for(process.communicate(), 5)
+        script_output += remaining_stdout
+      except asyncio.TimeoutError:
+        # give up, this will leave a zombie process.
+        print_utils.debug_print('[TIMEDOUT] SIGKILL failed for process ',
+                                process.pid)
+        time.sleep(100)
+
+      return -1, script_output
+    else:
+      if not line:  # EOF
+        break
+
+  code = await process.wait()  # wait for child process to exit
+  return code, script_output
diff --git a/startop/scripts/lib/logcat_utils.py b/startop/scripts/lib/logcat_utils.py
new file mode 100644
index 0000000..8a3d00b
--- /dev/null
+++ b/startop/scripts/lib/logcat_utils.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+"""Helper util libraries for parsing logcat logs."""
+
+import asyncio
+import re
+from datetime import datetime
+from typing import Optional, Pattern
+
+# local import
+import lib.print_utils as print_utils
+
+def parse_logcat_datetime(timestamp: str) -> Optional[datetime]:
+  """Parses the timestamp of logcat.
+
+  Params:
+    timestamp: for example "2019-07-01 16:13:55.221".
+
+  Returns:
+    a datetime of timestamp with the year now.
+  """
+  try:
+    # Match the format of logcat. For example: "2019-07-01 16:13:55.221",
+    # because it doesn't have year, set current year to it.
+    timestamp = datetime.strptime(timestamp,
+                                  '%Y-%m-%d %H:%M:%S.%f')
+    return timestamp
+  except ValueError as ve:
+    print_utils.debug_print('Invalid line: ' + timestamp)
+    return None
+
+def _is_time_out(timeout: datetime, line: str) -> bool:
+  """Checks if the timestamp of this line exceeds the timeout.
+
+  Returns:
+    true if the timestamp exceeds the timeout.
+  """
+  # Get the timestampe string.
+  cur_timestamp_str = ' '.join(re.split(r'\s+', line)[0:2])
+  timestamp = parse_logcat_datetime(cur_timestamp_str)
+  if not timestamp:
+    return False
+
+  return timestamp > timeout
+
+async def _blocking_wait_for_logcat_pattern(timestamp: datetime,
+                                            pattern: Pattern,
+                                            timeout: datetime) -> Optional[str]:
+  # Show the year in the timestampe.
+  logcat_cmd = 'adb logcat -v UTC -v year -v threadtime -T'.split()
+  logcat_cmd.append(str(timestamp))
+  print_utils.debug_print('[LOGCAT]:' + ' '.join(logcat_cmd))
+
+  # Create subprocess
+  process = await asyncio.create_subprocess_exec(
+      *logcat_cmd,
+      # stdout must a pipe to be accessible as process.stdout
+      stdout=asyncio.subprocess.PIPE)
+
+  while (True):
+    # Read one line of output.
+    data = await process.stdout.readline()
+    line = data.decode('utf-8').rstrip()
+
+    # 2019-07-01 14:54:21.946 27365 27392 I ActivityTaskManager: Displayed
+    # com.android.settings/.Settings: +927ms
+    # TODO: Detect timeouts even when there is no logcat output.
+    if _is_time_out(timeout, line):
+      print_utils.debug_print('DID TIMEOUT BEFORE SEEING ANYTHING ('
+                              'timeout={timeout} seconds << {pattern} '
+                              '>>'.format(timeout=timeout, pattern=pattern))
+      return None
+
+    if pattern.match(line):
+      print_utils.debug_print(
+          'WE DID SEE PATTERN << "{}" >>.'.format(pattern))
+      return line
+
+def blocking_wait_for_logcat_pattern(timestamp: datetime,
+                                     pattern: Pattern,
+                                     timeout: datetime) -> Optional[str]:
+  """Selects the line that matches the pattern and within the timeout.
+
+  Returns:
+    the line that matches the pattern and within the timeout.
+  """
+  loop = asyncio.get_event_loop()
+  result = loop.run_until_complete(
+      _blocking_wait_for_logcat_pattern(timestamp, pattern, timeout))
+  return result
diff --git a/startop/scripts/lib/logcat_utils_test.py b/startop/scripts/lib/logcat_utils_test.py
new file mode 100644
index 0000000..ab82515
--- /dev/null
+++ b/startop/scripts/lib/logcat_utils_test.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+#
+# 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.
+#
+"""Unit tests for the logcat_utils.py script."""
+
+import asyncio
+import datetime
+import re
+
+import logcat_utils
+from mock import MagicMock, patch
+
+def test_parse_logcat_datatime():
+  # Act
+  result = logcat_utils.parse_logcat_datetime('2019-07-01 16:13:55.221')
+
+  # Assert
+  assert result == datetime.datetime(2019, 7, 1, 16, 13, 55, 221000)
+
+class AsyncMock(MagicMock):
+  async def __call__(self, *args, **kwargs):
+    return super(AsyncMock, self).__call__(*args, **kwargs)
+
+def _async_return():
+  f = asyncio.Future()
+  f.set_result(
+      b'2019-07-01 15:51:53.290 27365 27392 I ActivityTaskManager: '
+      b'Displayed com.google.android.music/com.android.music.activitymanagement.'
+      b'TopLevelActivity: +1s7ms')
+  return f
+
+def test_parse_displayed_time_succeed():
+  # Act
+  with patch('asyncio.create_subprocess_exec',
+             new_callable=AsyncMock) as asyncio_mock:
+    asyncio_mock.return_value.stdout.readline = _async_return
+    timestamp = datetime.datetime(datetime.datetime.now().year, 7, 1, 16, 13,
+                                  55, 221000)
+    timeout_dt = timestamp + datetime.timedelta(0, 10)
+    pattern = re.compile('.*ActivityTaskManager: Displayed '
+                         'com.google.android.music/com.android.music.*')
+    result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
+                                                           pattern,
+                                                           timeout_dt)
+
+    # Assert
+    assert result == '2019-07-01 15:51:53.290 27365 27392 I ' \
+                     'ActivityTaskManager: ' \
+                     'Displayed com.google.android.music/com.android.music.' \
+                     'activitymanagement.TopLevelActivity: +1s7ms'
+
+def _async_timeout_return():
+  f = asyncio.Future()
+  f.set_result(
+      b'2019-07-01 17:51:53.290 27365 27392 I ActivityTaskManager: '
+      b'Displayed com.google.android.music/com.android.music.activitymanagement.'
+      b'TopLevelActivity: +1s7ms')
+  return f
+
+def test_parse_displayed_time_timeout():
+  # Act
+  with patch('asyncio.create_subprocess_exec',
+             new_callable=AsyncMock) as asyncio_mock:
+    asyncio_mock.return_value.stdout.readline = _async_timeout_return
+    timestamp = datetime.datetime(datetime.datetime.now().year,
+                                  7, 1, 16, 13, 55, 221000)
+    timeout_dt = timestamp + datetime.timedelta(0, 10)
+    pattern = re.compile('.*ActivityTaskManager: Displayed '
+                         'com.google.android.music/com.android.music.*')
+    result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
+                                                           pattern,
+                                                           timeout_dt)
+
+    # Assert
+    assert result == None
diff --git a/startop/scripts/lib/print_utils.py b/startop/scripts/lib/print_utils.py
new file mode 100644
index 0000000..8c5999d
--- /dev/null
+++ b/startop/scripts/lib/print_utils.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+#
+# 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.
+
+"""Helper util libraries for debug printing."""
+
+import sys
+
+DEBUG = False
+
+def debug_print(*args, **kwargs):
+  """Prints the args to sys.stderr if the DEBUG is set."""
+  if DEBUG:
+    print(*args, **kwargs, file=sys.stderr)
+
+def error_print(*args, **kwargs):
+  print('[ERROR]:', *args, file=sys.stderr, **kwargs)
+
+def _expand_gen_repr(args):
+  """Like repr but any generator-like object has its iterator consumed
+  and then called repr on."""
+  new_args_list = []
+  for i in args:
+    # detect iterable objects that do not have their own override of __str__
+    if hasattr(i, '__iter__'):
+      to_str = getattr(i, '__str__')
+      if to_str.__objclass__ == object:
+        # the repr for a generator is just type+address, expand it out instead.
+        new_args_list.append([_expand_gen_repr([j])[0] for j in i])
+        continue
+    # normal case: uses the built-in to-string
+    new_args_list.append(i)
+  return new_args_list
+
+def debug_print_gen(*args, **kwargs):
+  """Like _debug_print but will turn any iterable args into a list."""
+  if not DEBUG:
+    return
+
+  new_args_list = _expand_gen_repr(args)
+  debug_print(*new_args_list, **kwargs)
+
+def debug_print_nd(*args, **kwargs):
+  """Like _debug_print but will turn any NamedTuple-type args into a string."""
+  if not DEBUG:
+    return
+
+  new_args_list = []
+  for i in args:
+    if hasattr(i, '_field_types'):
+      new_args_list.append("%s: %s" % (i.__name__, i._field_types))
+    else:
+      new_args_list.append(i)
+
+  debug_print(*new_args_list, **kwargs)
diff --git a/startop/scripts/trace_analyzer/lib/trace2db.py b/startop/scripts/trace_analyzer/lib/trace2db.py
new file mode 100644
index 0000000..42a33af
--- /dev/null
+++ b/startop/scripts/trace_analyzer/lib/trace2db.py
@@ -0,0 +1,355 @@
+#!/usr/bin/python3
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import re
+import sys
+
+from sqlalchemy import create_engine
+from sqlalchemy import Column, Date, Integer, Float, String, ForeignKey
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship
+
+from sqlalchemy.orm import sessionmaker
+
+import sqlalchemy
+
+from typing import Optional, Tuple
+
+_DEBUG = False        # print sql commands to console
+_FLUSH_LIMIT = 10000  # how many entries are parsed before flushing to DB from memory
+
+Base = declarative_base()
+
+class RawFtraceEntry(Base):
+  __tablename__ = 'raw_ftrace_entries'
+
+  id = Column(Integer, primary_key=True)
+  task_name = Column(String, nullable=True) # <...> -> None.
+  task_pid = Column(String, nullable=False)
+  tgid = Column(Integer, nullable=True)     # ----- -> None.
+  cpu = Column(Integer, nullable=False)
+  timestamp = Column(Float, nullable=False)
+  function = Column(String, nullable=False)
+  function_args = Column(String, nullable=False)
+
+  # 1:1 relation with MmFilemapAddToPageCache.
+  mm_filemap_add_to_page_cache = relationship("MmFilemapAddToPageCache",
+                                              back_populates="raw_ftrace_entry")
+
+  @staticmethod
+  def parse_dict(line):
+    # '           <...>-5521  (-----) [003] ...1 17148.446877: tracing_mark_write: trace_event_clock_sync: parent_ts=17148.447266'
+    m = re.match('\s*(.*)-(\d+)\s+\(([^\)]+)\)\s+\[(\d+)\]\s+([\w.]{4})\s+(\d+[.]\d+):\s+(\w+):\s+(.*)', line)
+    if not m:
+      return None
+
+    groups = m.groups()
+    # groups example:
+    # ('<...>',
+    #  '5521',
+    #  '-----',
+    #  '003',
+    #  '...1',
+    #  '17148.446877',
+    #  'tracing_mark_write',
+    #  'trace_event_clock_sync: parent_ts=17148.447266')
+    task_name = groups[0]
+    if task_name == '<...>':
+      task_name = None
+
+    task_pid = int(groups[1])
+    tgid = groups[2]
+    if tgid == '-----':
+      tgid = None
+
+    cpu = int(groups[3])
+    # irq_flags = groups[4]
+    timestamp = float(groups[5])
+    function = groups[6]
+    function_args = groups[7]
+
+    return {'task_name': task_name, 'task_pid': task_pid, 'tgid': tgid, 'cpu': cpu, 'timestamp': timestamp, 'function': function, 'function_args': function_args}
+
+class SchedSwitch(Base):
+  __tablename__ = 'sched_switches'
+
+  id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
+
+  prev_comm = Column(String, nullable=False)
+  prev_pid = Column(Integer, nullable=False)
+  prev_prio = Column(Integer, nullable=False)
+  prev_state = Column(String, nullable=False)
+
+  next_comm = Column(String, nullable=False)
+  next_pid = Column(Integer, nullable=False)
+  next_prio = Column(Integer, nullable=False)
+
+  @staticmethod
+  def parse_dict(function_args, id = None):
+    # 'prev_comm=kworker/u16:5 prev_pid=13971 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120'
+    m = re.match("prev_comm=(.*) prev_pid=(\d+) prev_prio=(\d+) prev_state=(.*) ==> next_comm=(.*) next_pid=(\d+) next_prio=(\d+) ?", function_args)
+    if not m:
+      return None
+
+    groups = m.groups()
+    # ('kworker/u16:5', '13971', '120', 'S', 'swapper/4', '0', '120')
+    d = {}
+    if id is not None:
+      d['id'] = id
+    d['prev_comm'] = groups[0]
+    d['prev_pid'] = int(groups[1])
+    d['prev_prio'] = int(groups[2])
+    d['prev_state'] = groups[3]
+    d['next_comm'] = groups[4]
+    d['next_pid'] = int(groups[5])
+    d['next_prio'] = int(groups[6])
+
+    return d
+
+class SchedBlockedReason(Base):
+  __tablename__ = 'sched_blocked_reasons'
+
+  id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
+
+  pid = Column(Integer, nullable=False)
+  iowait = Column(Integer, nullable=False)
+  caller = Column(String, nullable=False)
+
+  @staticmethod
+  def parse_dict(function_args, id = None):
+    # 'pid=2289 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f'
+    m = re.match("pid=(\d+) iowait=(\d+) caller=(.*) ?", function_args)
+    if not m:
+      return None
+
+    groups = m.groups()
+    # ('2289', '1', 'wait_on_page_bit_common+0x2a8/0x5f8')
+    d = {}
+    if id is not None:
+      d['id'] = id
+    d['pid'] = int(groups[0])
+    d['iowait'] = int(groups[1])
+    d['caller'] = groups[2]
+
+    return d
+
+class MmFilemapAddToPageCache(Base):
+  __tablename__ = 'mm_filemap_add_to_page_caches'
+
+  id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
+
+  dev = Column(Integer, nullable=False)        # decoded from ${major}:${minor} syntax.
+  dev_major = Column(Integer, nullable=False)  # original ${major} value.
+  dev_minor = Column(Integer, nullable=False)  # original ${minor} value.
+
+  ino = Column(Integer, nullable=False)  # decoded from hex to base 10
+  page = Column(Integer, nullable=False) # decoded from hex to base 10
+
+  pfn = Column(Integer, nullable=False)
+  ofs = Column(Integer, nullable=False)
+
+  # 1:1 relation with RawFtraceEntry.
+  raw_ftrace_entry = relationship("RawFtraceEntry", uselist=False)
+
+  @staticmethod
+  def parse_dict(function_args, id = None):
+    # dev 253:6 ino b2c7 page=00000000ec787cd9 pfn=1478539 ofs=4096
+    m = re.match("dev (\d+):(\d+) ino ([0-9a-fA-F]+) page=([0-9a-fA-F]+) pfn=(\d+) ofs=(\d+)", function_args)
+    if not m:
+      return None
+
+    groups = m.groups()
+    # ('253', '6', 'b2c7', '00000000ec787cd9', '1478539', '4096')
+    d = {}
+    if id is not None:
+      d['id'] = id
+
+    device_major = d['dev_major'] = int(groups[0])
+    device_minor = d['dev_minor'] = int(groups[1])
+    d['dev'] = device_major << 8 | device_minor
+    d['ino'] = int(groups[2], 16)
+    d['page'] = int(groups[3], 16)
+    d['pfn'] = int(groups[4])
+    d['ofs'] = int(groups[5])
+
+    return d
+
+class Trace2Db:
+  def __init__(self, db_filename: str):
+    (s, e) = self._init_sqlalchemy(db_filename)
+    self._session = s
+    self._engine = e
+    self._raw_ftrace_entry_filter = lambda x: True
+
+  def set_raw_ftrace_entry_filter(self, flt):
+    """
+    Install a function dict(RawFtraceEntry) -> bool
+
+    If this returns 'false', then we skip adding the RawFtraceEntry to the database.
+    """
+    self._raw_ftrace_entry_filter = flt
+
+  @staticmethod
+  def _init_sqlalchemy(db_filename: str) -> Tuple[object, object]:
+    global _DEBUG
+    engine = create_engine('sqlite:///' + db_filename, echo=_DEBUG)
+
+    # CREATE ... (tables)
+    Base.metadata.create_all(engine)
+
+    Session = sessionmaker(bind=engine)
+    session = Session()
+    return (session, engine)
+
+  def parse_file_into_db(self, filename: str, limit: Optional[int] = None):
+    """
+    Parse the ftrace/systrace at 'filename',
+    inserting the values into the current sqlite database.
+
+    :return: number of RawFtraceEntry inserted.
+    """
+    return parse_file(filename, self._session, self._engine, self._raw_ftrace_entry_filter, limit)
+
+  def parse_file_buf_into_db(self, file_buf, limit: Optional[int] = None):
+    """
+    Parse the ftrace/systrace at 'filename',
+    inserting the values into the current sqlite database.
+
+    :return: number of RawFtraceEntry inserted.
+    """
+    return parse_file_buf(file_buf, self._session, self._engine, self._raw_ftrace_entry_filter, limit)
+
+
+  @property
+  def session(self):
+    return self._session
+
+def insert_pending_entries(engine, kls, lst):
+  if len(lst) > 0:
+    # for some reason, it tries to generate an empty INSERT statement with len=0,
+    # which of course violates the first non-null constraint.
+    try:
+      # Performance-sensitive parsing according to:
+      # https://docs.sqlalchemy.org/en/13/faq/performance.html#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow
+      engine.execute(kls.__table__.insert(), lst)
+      lst.clear()
+    except sqlalchemy.exc.IntegrityError as err:
+      # possibly violating some SQL constraint, print data here.
+      print(err)
+      print(lst)
+      raise
+
+def parse_file(filename: str, *args, **kwargs) -> int:
+  # use explicit encoding to avoid UnicodeDecodeError.
+  with open(filename, encoding="ISO-8859-1") as f:
+    return parse_file_buf(f, *args, **kwargs)
+
+def parse_file_buf(filebuf, session, engine, raw_ftrace_entry_filter, limit=None) -> int:
+  global _FLUSH_LIMIT
+  count = 0
+  # count and id are not equal, because count still increases for invalid lines.
+  id = 0
+
+  pending_entries = []
+  pending_sched_switch = []
+  pending_sched_blocked_reasons = []
+  pending_mm_filemap_add_to_pagecaches = []
+
+  def insert_all_pending_entries():
+    insert_pending_entries(engine, RawFtraceEntry, pending_entries)
+    insert_pending_entries(engine, SchedSwitch, pending_sched_switch)
+    insert_pending_entries(engine, SchedBlockedReason, pending_sched_blocked_reasons)
+    insert_pending_entries(engine, MmFilemapAddToPageCache, pending_mm_filemap_add_to_pagecaches)
+
+  # for trace.html files produced by systrace,
+  # the actual ftrace is in the 'second' trace-data script class.
+  parsing_trace_data = 0
+  parsing_systrace_file = False
+
+  f = filebuf
+  for l in f:
+    if parsing_trace_data == 0 and l == "<!DOCTYPE html>\n":
+      parsing_systrace_file = True
+      continue
+    if parsing_trace_data != 2 and parsing_systrace_file:
+      if l == '  <script class="trace-data" type="application/text">\n':
+        parsing_trace_data = parsing_trace_data + 1
+      continue
+
+    if parsing_systrace_file and parsing_trace_data != 2:
+      continue
+    elif parsing_systrace_file and parsing_trace_data == 2 and l == "  </script>\n":
+      # the rest of this file is just random html
+      break
+
+    # now parsing the ftrace data.
+    if len(l) > 1 and l[0] == '#':
+      continue
+
+    count = count + 1
+
+    if limit and count >= limit:
+      break
+
+    raw_ftrace_entry = RawFtraceEntry.parse_dict(l)
+    if not raw_ftrace_entry:
+      print("WARNING: Failed to parse raw ftrace entry: " + l)
+      continue
+
+    if not raw_ftrace_entry_filter(raw_ftrace_entry):
+      # Skip processing raw ftrace entries that don't match a filter.
+      # This is an optimization for when Trace2Db is used programatically
+      # to avoid having an overly large database.
+      continue
+
+    pending_entries.append(raw_ftrace_entry)
+    id = id + 1
+
+    if raw_ftrace_entry['function'] == 'sched_switch':
+      sched_switch = SchedSwitch.parse_dict(raw_ftrace_entry['function_args'], id)
+
+      if not sched_switch:
+        print("WARNING: Failed to parse sched_switch: " + l)
+      else:
+        pending_sched_switch.append(sched_switch)
+
+    elif raw_ftrace_entry['function'] == 'sched_blocked_reason':
+      sbr = SchedBlockedReason.parse_dict(raw_ftrace_entry['function_args'], id)
+
+      if not sbr:
+        print("WARNING: Failed to parse sched_blocked_reason: " + l)
+      else:
+        pending_sched_blocked_reasons.append(sbr)
+
+    elif raw_ftrace_entry['function'] == 'mm_filemap_add_to_page_cache':
+      d = MmFilemapAddToPageCache.parse_dict(raw_ftrace_entry['function_args'],
+                                             id)
+      if not d:
+        print("WARNING: Failed to parse mm_filemap_add_to_page_cache: " + l)
+      else:
+        pending_mm_filemap_add_to_pagecaches.append(d)
+
+    # Objects are cached in python memory, not yet sent to SQL database.
+
+    # Send INSERT/UPDATE/etc statements to the underlying SQL database.
+    if count % _FLUSH_LIMIT == 0:
+      insert_all_pending_entries()
+
+  insert_all_pending_entries()
+
+  # Ensure underlying database commits changes from memory to disk.
+  session.commit()
+
+  return count
diff --git a/startop/scripts/trace_analyzer/lib/trace2db_test.py b/startop/scripts/trace_analyzer/lib/trace2db_test.py
new file mode 100755
index 0000000..3b326f0
--- /dev/null
+++ b/startop/scripts/trace_analyzer/lib/trace2db_test.py
@@ -0,0 +1,222 @@
+#!/usr/bin/env python3
+#
+# 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.
+#
+
+"""
+Unit tests for inode2filename module.
+
+Install:
+  $> sudo apt-get install python3-pytest   ##  OR
+  $> pip install -U pytest
+See also https://docs.pytest.org/en/latest/getting-started.html
+
+Usage:
+  $> ./inode2filename_test.py
+  $> pytest inode2filename_test.py
+  $> python -m pytest inode2filename_test.py
+
+See also https://docs.pytest.org/en/latest/usage.html
+"""
+
+# global imports
+import io
+from copy import deepcopy
+
+# pip imports
+# local imports
+from trace2db import *
+
+# This pretty-prints the raw dictionary of the sqlalchemy object if it fails.
+class EqualsSqlAlchemyObject:
+  # For convenience to write shorter tests, we also add 'ignore_fields' which allow us to specify
+  # which fields to ignore when doing the comparison.
+  def __init__(self_, self, ignore_fields=[]):
+    self_.self = self
+    self_.ignore_fields = ignore_fields
+
+  # Do field-by-field comparison.
+  # It seems that SQLAlchemy does not implement __eq__ itself so we have to do it ourselves.
+  def __eq__(self_, other):
+    if isinstance(other, EqualsSqlAlchemyObject):
+      other = other.self
+
+    self = self_.self
+
+    classes_match = isinstance(other, self.__class__)
+    a, b = deepcopy(self.__dict__), deepcopy(other.__dict__)
+
+    #compare based on equality our attributes, ignoring SQLAlchemy internal stuff
+
+    a.pop('_sa_instance_state', None)
+    b.pop('_sa_instance_state', None)
+
+    for f in self_.ignore_fields:
+      a.pop(f, None)
+      b.pop(f, None)
+
+    attrs_match = (a == b)
+    return classes_match and attrs_match
+
+  def __repr__(self):
+    return repr(self.self.__dict__)
+
+
+def assert_eq_ignore_id(left, right):
+  # This pretty-prints the raw dictionary of the sqlalchemy object if it fails.
+  # It does field-by-field comparison, but ignores the 'id' field.
+  assert EqualsSqlAlchemyObject(left, ignore_fields=['id']) == EqualsSqlAlchemyObject(right)
+
+def parse_trace_file_to_db(*contents):
+  """
+  Make temporary in-memory sqlite3 database by parsing the string contents as a trace.
+
+  :return: Trace2Db instance
+  """
+  buf = io.StringIO()
+
+  for c in contents:
+    buf.write(c)
+    buf.write("\n")
+
+  buf.seek(0)
+
+  t2d = Trace2Db(":memory:")
+  t2d.parse_file_buf_into_db(buf)
+
+  buf.close()
+
+  return t2d
+
+def test_ftrace_mm_filemap_add_to_pagecache():
+  test_contents = """
+MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
+MediaStoreImpor-27212 (27176) [000] .... 16136.595920: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000048e2e156 pfn=677645 ofs=126976
+MediaStoreImpor-27212 (27176) [000] .... 16136.597793: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000051eabfb2 pfn=677644 ofs=122880
+MediaStoreImpor-27212 (27176) [000] .... 16136.597815: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000ce7cd606 pfn=677643 ofs=131072
+MediaStoreImpor-27212 (27176) [000] .... 16136.603732: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=000000008ffd3030 pfn=730119 ofs=186482688
+MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0
+          <...>-27197 (-----) [002] .... 16136.613471: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000aca88a97 pfn=743346 ofs=241664
+          <...>-27197 (-----) [002] .... 16136.615979: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000351f2bc1 pfn=777799 ofs=106496
+          <...>-27224 (-----) [006] .... 16137.400090: mm_filemap_add_to_page_cache: dev 253:6 ino 712d page=000000006ff7ffdb pfn=754861 ofs=0
+          <...>-1396  (-----) [000] .... 16137.451660: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000ba0cbb34 pfn=769173 ofs=187191296
+          <...>-1396  (-----) [000] .... 16137.453020: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000f6ef038e pfn=820291 ofs=0
+          <...>-1396  (-----) [000] .... 16137.453067: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=0000000083ebc446 pfn=956463 ofs=4096
+          <...>-1396  (-----) [000] .... 16137.453101: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000009dc2cd25 pfn=822813 ofs=8192
+          <...>-1396  (-----) [000] .... 16137.453113: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000a11167fb pfn=928650 ofs=12288
+          <...>-1396  (-----) [000] .... 16137.453126: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000c1c3311b pfn=621110 ofs=16384
+          <...>-1396  (-----) [000] .... 16137.453139: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000009aa78342 pfn=689370 ofs=20480
+          <...>-1396  (-----) [000] .... 16137.453151: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=0000000082cddcd6 pfn=755584 ofs=24576
+          <...>-1396  (-----) [000] .... 16137.453162: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000b0249bc7 pfn=691431 ofs=28672
+          <...>-1396  (-----) [000] .... 16137.453183: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000006a776ff0 pfn=795084 ofs=32768
+          <...>-1396  (-----) [000] .... 16137.453203: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000001a4918a7 pfn=806998 ofs=36864
+          <...>-2578  (-----) [002] .... 16137.561871: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000d65af9d2 pfn=719246 ofs=187015168
+          <...>-2578  (-----) [002] .... 16137.562846: mm_filemap_add_to_page_cache: dev 253:6 ino b25a page=000000002f6ba74f pfn=864982 ofs=0
+          <...>-2578  (-----) [000] .... 16138.104500: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000f888d0f6 pfn=805812 ofs=192794624
+          <...>-2578  (-----) [000] .... 16138.105836: mm_filemap_add_to_page_cache: dev 253:6 ino b7dd page=000000003749523b pfn=977196 ofs=0
+          <...>-27215 (-----) [001] .... 16138.256881: mm_filemap_add_to_page_cache: dev 253:6 ino 758f page=000000001b375de1 pfn=755928 ofs=0
+          <...>-27215 (-----) [001] .... 16138.257526: mm_filemap_add_to_page_cache: dev 253:6 ino 7591 page=000000004e039481 pfn=841534 ofs=0
+ NonUserFacing6-5246  ( 1322) [005] .... 16138.356491: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000d65af9d2 pfn=719246 ofs=161890304
+ NonUserFacing6-5246  ( 1322) [005] .... 16138.357538: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000002f6ba74f pfn=864982 ofs=0
+ NonUserFacing6-5246  ( 1322) [005] .... 16138.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
+          <...>-27197 (-----) [005] .... 16140.143224: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000a42527c6 pfn=1076669 ofs=32768
+  """
+
+  t2d = parse_trace_file_to_db(test_contents)
+  session = t2d.session
+
+  first_row = session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).first()
+
+  #dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
+  assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+      ino=0x7580, page=0x0000000060e990c7, pfn=677646, ofs=159744), first_row)
+
+  second_to_last_row = session.query(MmFilemapAddToPageCache).filter(MmFilemapAddToPageCache.page.in_([0x000000006e0f8322])).first()
+
+  # dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
+  assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+      ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row)
+
+def test_systrace_mm_filemap_add_to_pagecache():
+  test_contents = """
+<!DOCTYPE html>
+<html>
+<head i18n-values="dir:textdirection;">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta charset="utf-8"/>
+<title>Android System Trace</title>
+  <script class="trace-data" type="application/text">
+PROCESS DUMP
+USER           PID  PPID     VSZ    RSS WCHAN  PC S NAME                        COMM
+root             1     0   62148   5976 0       0 S init                        [init]
+root             2     0       0      0 0       0 S [kthreadd]                  [kthreadd]
+  </script>
+
+  <script class="trace-data" type="application/text">
+MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
+NonUserFacing6-5246  ( 1322) [005] .... 16138.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
+  </script>
+
+  <script class="trace-data" type="application/text">
+{"traceEvents": [{"category": "process_argv", "name": "process_argv", "args": {"argv": ["/mnt/ssd3/workspace/master/external/chromium-trace/systrace.py", "-t", "5", "pagecache"]}, "pid": 160383, "ts": 1037300940509.7991, "tid": 139628672526080, "ph": "M"}, {"category": "python", "name": "clock_sync", "args": {"issue_ts": 1037307346185.212, "sync_id": "9a7e4fe3-89ad-441f-8226-8fe533fe973e"}, "pid": 160383, "ts": 1037307351643.906, "tid": 139628726089536, "ph": "c"}], "metadata": {"clock-domain": "SYSTRACE"}}
+  </script>
+<!-- END TRACE -->
+  """
+
+  t2d = parse_trace_file_to_db(test_contents)
+  session = t2d.session
+
+  first_row = session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).first()
+
+  #dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
+  assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+      ino=0x7580, page=0x0000000060e990c7, pfn=677646, ofs=159744), first_row)
+
+  second_to_last_row = session.query(MmFilemapAddToPageCache).filter(MmFilemapAddToPageCache.page.in_([0x000000006e0f8322])).first()
+
+  # dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
+  assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+      ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row)
+
+def test_timestamp_filter():
+  test_contents = """
+    MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
+    NonUserFacing6-5246  ( 1322) [005] .... 16139.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
+    MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0
+  """
+
+  t2d = parse_trace_file_to_db(test_contents)
+  session = t2d.session
+
+  end_time = 16137.0
+
+  results = session.query(MmFilemapAddToPageCache).join(
+      MmFilemapAddToPageCache.raw_ftrace_entry).filter(
+      RawFtraceEntry.timestamp <= end_time).order_by(
+      MmFilemapAddToPageCache.id).all()
+
+  assert len(results) == 2
+  assert_eq_ignore_id(
+      MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+                              ino=0x7580, page=0x0000000060e990c7, pfn=677646,
+                              ofs=159744), results[0])
+  assert_eq_ignore_id(
+      MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
+                              ino=0xb1d8, page=0x0000000098d4d2e2, pfn=829676,
+                              ofs=0), results[1])
+
+
+if __name__ == '__main__':
+  pytest.main()
diff --git a/startop/scripts/trace_analyzer/queries_all.sql b/startop/scripts/trace_analyzer/queries_all.sql
new file mode 100644
index 0000000..41d1c08
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_all.sql
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+-- filter for atrace writes
+CREATE VIEW IF NOT EXISTS tracing_mark_writes AS
+    SELECT *
+      FROM raw_ftrace_entries
+     WHERE function = 'tracing_mark_write';
+
+-- split the tracing_mark_write function args by ||s
+DROP TABLE IF exists tracing_mark_write_split_array;
+
+CREATE TABLE tracing_mark_write_split_array (
+    predictorset_id INT REFERENCES raw_ftrace_entries (id),
+    predictor_name,
+    rest,
+    gen,
+    
+    UNIQUE(predictorset_id, gen) -- drops redundant inserts into table
+);
+
+CREATE INDEX "tracing_mark_write_split_array_id" ON tracing_mark_write_split_array (
+    predictorset_id COLLATE BINARY COLLATE BINARY
+);
+
+INSERT INTO tracing_mark_write_split_array
+  WITH 
+    split(predictorset_id, predictor_name, rest, gen) AS (
+      -- split by |
+      SELECT id, '', function_args || '|', 0 FROM tracing_mark_writes WHERE id
+       UNION ALL
+      SELECT predictorset_id, 
+             substr(rest, 0, instr(rest, '|')),
+             substr(rest, instr(rest, '|')+1),
+             gen + 1
+        FROM split
+       WHERE rest <> ''),
+     split_results AS (
+       SELECT * FROM split WHERE predictor_name <> ''
+     )
+  SELECT * from split_results
+;
+
+
diff --git a/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql b/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql
new file mode 100644
index 0000000..c28475e
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql
@@ -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.
+ */
+
+-- use the 'launching: $process_name' async slice to figure out launch duration.
+DROP VIEW IF EXISTS launch_durations_named;
+
+CREATE VIEW launch_durations_named AS
+WITH
+    launch_traces_raw AS (
+        SELECT *
+        FROM tracing_mark_write_split AS tmw,
+             raw_ftrace_entries AS rfe
+        WHERE atrace_message LIKE 'launching: %' AND rfe.id = tmw.raw_ftrace_entry_id
+    ),
+    launch_traces_joined AS (
+        SELECT started.timestamp AS started_timestamp,
+               finished.timestamp AS finished_timestamp,
+               started.id AS started_id,
+               finished.id AS finished_id,
+               SUBSTR(started.atrace_message, 12) AS proc_name   -- crop out "launching: " from the string.
+        FROM launch_traces_raw AS started,
+             launch_traces_raw AS finished
+        -- async slices ('S' -> 'F') have matching counters given the same PID.
+        WHERE started.atrace_type == 'S'
+              AND finished.atrace_type == 'F'
+              AND started.atrace_count == finished.atrace_count
+              AND started.atrace_pid == finished.atrace_pid
+    )
+SELECT * from launch_traces_joined;
+
+SELECT * FROM launch_durations_named;
diff --git a/startop/scripts/trace_analyzer/queries_block_launch.sql b/startop/scripts/trace_analyzer/queries_block_launch.sql
new file mode 100644
index 0000000..34e5f03
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_block_launch.sql
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+DROP VIEW IF EXISTS blocked_iowait_for_app_launches;
+
+CREATE VIEW blocked_iowait_for_app_launches AS
+WITH
+    block_launch_join AS (
+        SELECT *
+        FROM blocking_durations AS bd,
+             launch_durations_named AS ld
+        WHERE bd.block_timestamp >= ld.started_timestamp
+              AND bd.unblock_timestamp <= ld.finished_timestamp
+    ),
+    blocked_ui_threads AS (
+        SELECT *
+        FROM start_process_ui_threads AS sp,
+             block_launch_join AS blj
+        WHERE sp.atm_ui_thread_tid == unblock_pid
+              AND sp.process_name = blj.proc_name
+    ),
+    summed_raw AS (
+        SELECT SUM(unblock_timestamp-block_timestamp)*1000 AS sum_block_duration_ms,
+               *
+        FROM blocked_ui_threads
+        GROUP BY unblock_pid
+    ),
+    summed_neat AS (
+        SELECT sum_block_duration_ms AS blocked_iowait_duration_ms,
+               process_name,
+               (finished_timestamp - started_timestamp) * 1000 AS launching_duration_ms,
+               started_timestamp * 1000 AS launching_started_timestamp_ms,
+               finished_timestamp * 1000 AS launching_finished_timestamp_ms
+                -- filter out the rest because its just selecting 1 arbitrary row (due to the SUM aggregate).,
+        FROM summed_raw
+    )
+SELECT * FROM summed_neat;
+
+SELECT * FROM blocked_iowait_for_app_launches;
diff --git a/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql b/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql
new file mode 100644
index 0000000..788d0da
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+DROP VIEW IF EXISTS sched_switch_iowaits_pre;
+
+-- scan for the closest pair such that:
+--                  sched_block_reason pid=$PID iowait=1 ...
+--                  ...
+--                  sched_switch next_pid=$PID
+CREATE VIEW sched_switch_iowaits_pre AS
+    SELECT MAX(sbr.id) AS blocked_id,
+           ss.id AS sched_switch_id,
+           pid,         -- iow.pid
+           iowait,      -- iowait=0 or iowait=1
+           caller,
+           sbr_f.timestamp AS blocked_timestamp,
+           ss_f.timestamp AS sched_switch_timestamp,
+           next_comm,   -- name of next_pid
+           next_pid     -- same as iow.pid
+    FROM sched_blocked_reasons AS sbr,
+         raw_ftrace_entries AS sbr_f,
+         sched_switches AS ss,
+         raw_ftrace_entries AS ss_f
+    WHERE sbr_f.id == sbr.id
+          AND ss_f.id == ss.id
+          AND sbr.pid == ss.next_pid
+          AND sbr.iowait = 1
+          AND sbr_f.timestamp < ss_f.timestamp     -- ensures the 'closest' sched_blocked_reason is selected.
+    GROUP BY ss.id
+;
+
+DROP VIEW IF EXISTS sched_switch_iowaits;
+
+CREATE VIEW sched_switch_iowaits AS
+    SELECT *, MIN(sched_switch_timestamp) AS ss_timestamp      -- drop all of the 'too large' sched_switch entries except the closest one.
+    FROM sched_switch_iowaits_pre
+    GROUP BY blocked_id;
+
+SELECT * FROM sched_switch_iowaits;
+
+-- use a real table here instead of a view, otherwise SQLiteStudio segfaults for some reason.
+DROP TABLE IF EXISTS blocking_durations;
+
+CREATE TABLE blocking_durations AS
+WITH
+    blocking_durations_raw AS (
+        SELECT MAX(ss.id) AS block_id,
+               ssf.timestamp AS block_timestamp,
+               iow.sched_switch_timestamp AS unblock_timestamp,
+               ss.prev_comm as block_prev_comm,
+               iow.next_comm AS unblock_next_comm,
+               ss.prev_state AS block_prev_state,
+               iow.sched_switch_id AS unblock_id,
+               iow.pid AS unblock_pid,
+               iow.caller AS unblock_caller
+        FROM sched_switches AS ss,          -- this is the sched_switch that caused a block (in the future when it unblocks, the reason is iowait=1).
+             sched_switch_iowaits AS iow,    -- this is the sched_switch that removes the block (it is now running again).
+             raw_ftrace_entries AS ssf
+        WHERE ssf.id = ss.id AND ss.prev_pid == iow.next_pid AND ssf.timestamp < iow.sched_switch_timestamp
+        GROUP BY unblock_timestamp 
+    ),
+    blocking_durations_tmp AS (
+        SELECT block_id,
+               unblock_timestamp,
+               block_timestamp,
+               block_prev_comm as comm,
+               block_prev_state as block_state,
+               unblock_id,
+               unblock_pid,
+               unblock_caller
+        FROM blocking_durations_raw
+    )
+    SELECT * FROM blocking_durations_tmp;-- ORDER BY block_id ASC;
+    --SELECT SUM(block_duration_ms) AS sum, * FROM blocking_durations GROUP BY unblock_pid ORDER BY sum DESC;
+
+DROP INDEX IF EXISTS "blocking_durations_block_timestamp";
+
+CREATE INDEX "blocking_durations_block_timestamp" ON blocking_durations (
+    block_timestamp COLLATE BINARY COLLATE BINARY
+);
+
+DROP INDEX IF EXISTS "blocking_durations_unblock_timestamp";
+
+CREATE INDEX "blocking_durations_unblock_timestamp" ON blocking_durations (
+    unblock_timestamp COLLATE BINARY COLLATE BINARY
+);
+
+SELECT * FROM blocking_durations;
diff --git a/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql b/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql
new file mode 100644
index 0000000..0c166b0
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql
@@ -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.
+ */
+
+DROP VIEW IF EXISTS sched_switch_next_comm_pids;
+
+CREATE VIEW IF NOT EXISTS sched_switch_next_comm_pids AS
+
+-- TODO: switch to using sched_switches table.
+
+WITH
+    sched_switchs AS (
+        SELECT * FROM raw_ftrace_entries WHERE function = 'sched_switch' AND function_args LIKE '% next_pid=%' AND function_args NOT LIKE '% next_comm=main %'
+    ),
+    comm_and_pids_raws AS (
+        SELECT id,
+               SUBSTR(function_args, instr(function_args, "next_comm="), instr(function_args, "next_pid=") - instr(function_args, "next_comm=")) AS next_comm_raw,
+               SUBSTR(function_args, instr(function_args, "next_pid="), instr(function_args, "next_prio=") - instr(function_args, "next_pid=")) AS next_pid_raw
+        FROM sched_switchs
+    ),
+    comm_and_pids AS (
+        SELECT id,
+               id AS raw_ftrace_entry_id,
+               TRIM(SUBSTR(next_pid_raw, 10)) AS next_pid, -- len("next_pid=") is 10
+               TRIM(SUBSTR(next_comm_raw, 11)) AS next_comm -- len("next_comm=") is 11
+        FROM comm_and_pids_raws
+    )
+SELECT * from comm_and_pids;
+
+SELECT * from sched_switch_next_comm_pids;
diff --git a/startop/scripts/trace_analyzer/queries_get_procs.sql b/startop/scripts/trace_analyzer/queries_get_procs.sql
new file mode 100644
index 0000000..06871c6
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_get_procs.sql
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+DROP VIEW IF EXISTS start_procs;
+
+CREATE VIEW IF NOT EXISTS start_procs AS
+WITH
+  start_procs_raw AS (
+      SELECT * from tracing_mark_write_split WHERE atrace_message LIKE 'Start proc: %'
+  ),
+  start_procs_substr AS (
+      -- note: "12" is len("Start proc: ")+1. sqlite indices start at 1.
+      SELECT raw_ftrace_entry_id, atrace_pid, SUBSTR(atrace_message, 13) AS process_name FROM start_procs_raw
+  )
+SELECT * from start_procs_substr;
+
+SELECT * from start_procs;
diff --git a/startop/scripts/trace_analyzer/queries_get_ui_threads.sql b/startop/scripts/trace_analyzer/queries_get_ui_threads.sql
new file mode 100644
index 0000000..876e50e
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_get_ui_threads.sql
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+-- note: These queries do comparisons based on raw_ftrace_entries.id by treating it as if it was equivalent to the temporal timestamp.
+-- in practice, the ID of raw_ftrace_entries is based on its order in the ftrace buffer [and on the same cpu its equivalent].
+-- we can always resort raw_ftrace_entries to ensure id order matches timestamp order. We should rarely need to compare by timestamp directly.
+-- accessing 'floats' is inferior as they are harder to index, and will result in slower queries.
+--
+-- Naming convention note: '_fid' corresponds to 'raw_ftrace_entry.id'.
+DROP VIEW IF EXISTS start_process_ui_threads;
+
+-- Map of started process names to their UI thread's TID (as returned by gettid).
+CREATE VIEW IF NOT EXISTS start_process_ui_threads AS
+WITH
+  start_proc_tids AS (
+    SELECT sp.raw_ftrace_entry_id AS start_proc_fid,
+           sp.atrace_pid AS atrace_pid,
+           sp.process_name AS process_name,
+           --MIN(nc.raw_ftrace_entry_id) as next_comm_fid,
+           nc.raw_ftrace_entry_id AS next_comm_fid,
+           nc.next_pid as next_pid,
+           nc.next_comm as next_comm,
+           SUBSTR(sp.process_name, -15) AS cut      -- why -15? See TASK_MAX in kernel, the sched_switch name is truncated to 16 bytes.
+    FROM start_procs AS sp,
+         sched_switch_next_comm_pids AS nc
+    WHERE sp.process_name LIKE '%' || nc.next_comm  -- kernel truncates the sched_switch::next_comm event, so we must match the prefix of the full name.
+    --WHERE SUBSTR(sp.process_name, -16) == nc.next_comm
+    --WHERE cut == nc.next_comm
+  ),
+  start_proc_tids_filtered AS (
+      SELECT *
+      FROM start_proc_tids
+      WHERE next_comm_fid > start_proc_fid        -- safeguard that avoids choosing "earlier" sched_switch before process was even started.
+      --ORDER BY start_proc_fid, next_comm_fid
+  ),
+  start_proc_all_threads AS (
+    SELECT DISTINCT
+        start_proc_fid, -- this is the ftrace entry of the system server 'Start proc: $process_name'. only need this to join for timestamp.
+        process_name,               -- this is the '$process_name' from the system server entry.
+        -- next up we have all the possible thread IDs as parsed from sched_switch that corresponds most closest to the start proc.
+        next_pid AS ui_thread_tpid, -- sched_switch.next_pid. This can be any of the threads in that process, it's not necessarily the main UI thread yet.
+        next_comm,
+        MIN(next_comm_fid) AS next_comm_fid   -- don't pick the 'later' next_comm_fid because it could correspond to another app start.
+    FROM start_proc_tids_filtered
+    GROUP BY start_proc_fid, ui_thread_tpid
+  ),
+  activity_thread_mains AS (
+    SELECT * FROM tracing_mark_write_split WHERE atrace_message = 'ActivityThreadMain'
+  ),
+  start_proc_ui_threads AS (
+    SELECT start_proc_fid,
+           process_name,
+           ui_thread_tpid,
+           next_comm,
+           next_comm_fid,
+           atm.raw_ftrace_entry_id as atm_fid,
+           atm.atrace_pid as atm_ui_thread_tid
+    FROM start_proc_all_threads AS spt, 
+         activity_thread_mains AS atm
+    WHERE atm.atrace_pid == spt.ui_thread_tpid AND atm.raw_ftrace_entry_id > spt.start_proc_fid -- Ensure we ignore earlier ActivityThreadMains prior to their Start proc.
+  ),
+  start_proc_ui_threads_filtered AS (
+    SELECT start_proc_fid,
+           process_name,                -- e.g. 'com.android.settings'
+           --ui_thread_tpid,
+           --next_comm,
+           --next_comm_fid,
+           MIN(atm_fid) AS atm_fid,
+           atm_ui_thread_tid            -- equivalent to gettid() for the process's UI thread.
+    FROM start_proc_ui_threads
+    GROUP BY start_proc_fid, atm_ui_thread_tid    -- find the temporally closest ActivityTaskMain to a "Start proc: $process_name"
+  )
+SELECT * FROM start_proc_ui_threads_filtered;
+
+SELECT * FROM start_process_ui_threads;
diff --git a/startop/scripts/trace_analyzer/queries_mark_write_join.sql b/startop/scripts/trace_analyzer/queries_mark_write_join.sql
new file mode 100644
index 0000000..100f0740
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_mark_write_join.sql
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+DROP TABLE IF EXISTS tracing_mark_write_split;
+
+CREATE TABLE tracing_mark_write_split (
+    raw_ftrace_entry_id INT REFERENCES raw_ftrace_entries (id),
+    atrace_type CHAR(1), -- only null for the first 2 sync timers. usually 'B', 'C', E', ...
+    atrace_pid INT,      -- only null for first 2 sync timers
+    atrace_message,      -- usually null for type='E' etc.
+    atrace_count,        -- usually non-null only for 'C'
+
+    UNIQUE(raw_ftrace_entry_id) -- drops redundant inserts into table
+);
+
+INSERT INTO tracing_mark_write_split
+WITH
+    pivoted AS (
+        SELECT tx.predictorset_id,
+               --ty.predictorset_id,
+               --tz.predictorset_id,
+               --tzz.predictorset_id,
+               tx.predictor_name AS atrace_type,
+               CAST(ty.predictor_name  AS integer) AS atrace_pid,
+               tz.predictor_name AS atrace_message,
+               CAST(tzz.predictor_name AS integer) AS atrace_count
+        FROM (SELECT * from tracing_mark_write_split_array WHERE gen = 1) AS tx
+        LEFT JOIN
+             (SELECT * FROM tracing_mark_write_split_array WHERE gen = 2) AS ty
+        ON tx.predictorset_id = ty.predictorset_id
+        LEFT JOIN
+             (SELECT * FROM tracing_mark_write_split_array WHERE gen = 3) AS tz
+        ON tx.predictorset_id = tz.predictorset_id
+        LEFT JOIN
+             (SELECT * FROM tracing_mark_write_split_array WHERE gen = 4) AS tzz
+        ON tx.predictorset_id = tzz.predictorset_id
+    )
+SELECT * from pivoted ORDER BY predictorset_id;-- LIMIT 100;
+
+SELECT * FROM tracing_mark_write_split;
diff --git a/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql b/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql
new file mode 100644
index 0000000..bf5e3cc
--- /dev/null
+++ b/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql
@@ -0,0 +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.
+ */
+
+.headers on
+.mode quote
+
+SELECT * FROM blocked_iowait_for_app_launches;
+
+/*
+Output as CSV example:
+
+'blocked_iowait_duration_ms','process_name','launching_duration_ms','launching_started_timestamp_ms','launching_finished_timestamp_ms'
+125.33199995596078224,'com.android.settings',1022.4840000009862706,17149896.822000000626,17150919.305999998003
+
+*/
diff --git a/startop/scripts/trace_analyzer/run-sql-queries b/startop/scripts/trace_analyzer/run-sql-queries
new file mode 100755
index 0000000..61a0ad4
--- /dev/null
+++ b/startop/scripts/trace_analyzer/run-sql-queries
@@ -0,0 +1,79 @@
+#!/bin/bash
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR="$( cd "$(dirname "$0")" ; pwd -P )"
+
+if [[ $# -lt 1 ]]; then
+  echo "Usage: $0 <db-file>"
+fi
+
+DB_TARGET=$1
+
+if ! [[ -f $DB_TARGET ]]; then
+  echo "ERROR: File '$DB_TARGET' does not exist." >&2
+  exit 1
+fi
+
+exec_sql_file() {
+  local filename="$1"
+  if ! [[ -f $filename ]]; then
+    echo "ERROR: Can't exec SQL file, '$filename' does not exist." >&2
+    return 1
+  fi
+
+  sqlite3 "$DB_TARGET" < "$DIR"/"$filename"
+}
+
+exec_sql_file_quiet() {
+  exec_sql_file "$@" > /dev/null
+}
+
+# Some views/tables need other views already created, so order does matter.
+# x -> y , means x depends on y.
+
+# View: tracing_mark_writes
+# Table: tracing_mark_write_split_array -> tracing_mark_writes
+exec_sql_file_quiet "queries_all.sql"
+
+# Table: tracing_mark_write_split -> tracing_mark_write_split_array
+exec_sql_file_quiet "queries_mark_write_join.sql"
+
+# View: start_procs -> tracing_mark_write_split
+exec_sql_file_quiet "queries_get_procs.sql"
+
+# View: sched_switch_next_comm_pids
+exec_sql_file_quiet "queries_get_comm_and_pids.sql"
+
+# View: start_process_ui_threads -> start_procs, sched_switch_next_comm_pids
+exec_sql_file_quiet "queries_get_ui_threads.sql"
+
+# View: launch_durations_named -> tracing_mark_write_split
+exec_sql_file_quiet "queries_app_launch_spans_with_name.sql"
+
+# View: sched_switch_iowaits_pre
+# View: sched_switch_iowaits -> sched_switch_iowaits_pre
+# Table: blocking_durations -> sched_switch_iowaits
+exec_sql_file_quiet "queries_find_sched_switch_unblocked.sql"
+
+# View: blocked_iowait_for_app_launches -> launch_durations_named, blocking_durations
+exec_sql_file_quiet "queries_block_launch.sql"
+
+#####
+#####
+#####
+
+# Final queries
+
+exec_sql_file "queries_pretty_print_block_launch.sql"
diff --git a/startop/scripts/trace_analyzer/test_fixtures/common_systrace b/startop/scripts/trace_analyzer/test_fixtures/common_systrace
new file mode 100644
index 0000000..802cb55
--- /dev/null
+++ b/startop/scripts/trace_analyzer/test_fixtures/common_systrace
@@ -0,0 +1,518 @@
+# tracer: nop
+#
+# entries-in-buffer/entries-written: 411983/411983   #P:8
+#
+#                                      _-----=> irqs-off
+#                                     / _----=> need-resched
+#                                    | / _---=> hardirq/softirq
+#                                    || / _--=> preempt-depth
+#                                    ||| /     delay
+#           TASK-PID    TGID   CPU#  ||||    TIMESTAMP  FUNCTION
+#              | |        |      |   ||||       |         |
+           <...>-14603 (-----) [000] ...1 14592.893157: tracing_mark_write: trace_event_clock_sync: parent_ts=14592.892578
+           <...>-14603 (-----) [000] ...1 14592.893172: tracing_mark_write: trace_event_clock_sync: realtime_ts=1557129597951
+           <...>-18150 (-----) [004] d..2 14594.182110: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:16 next_pid=23269 next_prio=120
+  kworker/u16:16-23269 (23269) [004] d.h3 14594.182228: sched_blocked_reason: pid=18150 iowait=0 caller=a6xx_oob_set+0x194/0x3dc
+  kworker/u16:16-23269 (23269) [004] d..2 14594.182248: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182312: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182488: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+  kworker/u16:16-23269 (23269) [005] d..2 14594.182610: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182626: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182755: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.182975: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.183209: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.183371: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.184286: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
+  kworker/u16:16-23269 (23269) [005] d..2 14594.184495: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-18150 (-----) [004] d..2 14594.184498: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
+     ksoftirqd/4-47    (   47) [004] d..2 14594.185678: sched_switch: prev_comm=ksoftirqd/4 prev_pid=47 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
+     kworker/6:2-10610 (10610) [006] d..2 14594.186012: sched_switch: prev_comm=kworker/6:2 prev_pid=10610 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-656   (-----) [001] .... 14594.219464: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-1803  (-----) [000] d..2 14594.219595: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-3359  (-----) [001] ...1 14594.219856: tracing_mark_write: S|1368|launching: com.google.android.dialer|0
+           <...>-3359  (-----) [001] ...1 14594.219863: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunched
+           <...>-3359  (-----) [001] ...1 14594.219869: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto
+           <...>-1398  (-----) [006] ...1 14594.220160: tracing_mark_write: B|1368|updateInputWindows
+           <...>-3359  (-----) [001] .... 14594.220230: binder_set_priority: proc=1368 thread=3359 old=110 => new=120 desired=120
+           <...>-1398  (-----) [006] ...1 14594.220588: tracing_mark_write: B|1368|android.os.Handler: com.android.server.wm.AppWindowToken$1
+           <...>-1398  (-----) [006] ...1 14594.220722: tracing_mark_write: B|1368|ResourcesManager#getResources
+           <...>-1052  (-----) [002] d..2 14594.220884: sched_switch: prev_comm=statsd.writer prev_pid=1052 prev_prio=120 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118
+           <...>-1398  (-----) [006] ...1 14594.220926: tracing_mark_write: B|1368|Theme::ApplyStyle
+           <...>-1398  (-----) [006] ...1 14594.220929: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-2007  (-----) [007] ...1 14594.220996: tracing_mark_write: B|2007|Choreographer#doFrame
+           <...>-2007  (-----) [007] ...1 14594.221005: tracing_mark_write: B|2007|animation
+           <...>-1398  (-----) [006] ...1 14594.221015: tracing_mark_write: B|1368|ResourcesManager#getResources
+           <...>-2045  (-----) [002] ...2 14594.221035: binder_set_priority: proc=1368 thread=1903 old=120 => new=118 desired=118
+           <...>-2045  (-----) [002] d..2 14594.221065: sched_switch: prev_comm=UiThreadHelper prev_pid=2045 prev_prio=118 prev_state=S ==> next_comm=Binder:1368_4 next_pid=1903 next_prio=118
+           <...>-1398  (-----) [006] ...1 14594.221080: tracing_mark_write: B|1368|AssetManager::SetApkAssets
+           <...>-2007  (-----) [007] ...1 14594.221110: tracing_mark_write: B|2007|traversal
+           <...>-656   (-----) [000] ...1 14594.221137: tracing_mark_write: B|625|requestNextVsync
+           <...>-656   (-----) [000] ...1 14594.221141: tracing_mark_write: B|625|resetIdleTimer
+           <...>-2007  (-----) [007] ...1 14594.221146: tracing_mark_write: B|2007|draw
+           <...>-2007  (-----) [007] ...1 14594.221160: tracing_mark_write: B|2007|Record View#draw()
+           <...>-660   (-----) [005] d..2 14594.221285: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
+           <...>-658   (-----) [004] d..2 14594.221327: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=android.display next_pid=1397 next_prio=117
+           <...>-2738  (-----) [005] ...1 14594.221342: tracing_mark_write: B|2007|notifyFramePending
+           <...>-2738  (-----) [005] ...1 14594.221362: tracing_mark_write: B|2007|DrawFrame
+           <...>-2738  (-----) [005] ...1 14594.221369: tracing_mark_write: B|2007|query
+           <...>-2007  (-----) [007] d..2 14594.221369: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-1903  (-----) [002] .... 14594.221397: binder_set_priority: proc=1368 thread=1903 old=118 => new=120 desired=120
+           <...>-2738  (-----) [005] ...2 14594.221400: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [005] d..2 14594.221430: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-1368  (-----) [003] ...1 14594.221431: tracing_mark_write: B|1368|Lock contention on GC thread flip lock (owner tid: 0)
+           <...>-656   (-----) [005] ...1 14594.221460: tracing_mark_write: B|625|query
+           <...>-656   (-----) [005] .... 14594.221528: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-2738  (-----) [007] ...1 14594.221552: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...2 14594.221563: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [007] d..2 14594.221600: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-1368  (-----) [003] d..2 14594.221623: sched_switch: prev_comm=system_server prev_pid=1368 prev_prio=118 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
+           <...>-656   (-----) [007] ...1 14594.221628: tracing_mark_write: B|625|query
+           <...>-23031 (-----) [001] d..2 14594.221643: sched_switch: prev_comm=UiAutomation prev_pid=23031 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [007] ...1 14594.221664: tracing_mark_write: B|2007|syncFrameState
+           <...>-2738  (-----) [007] ...1 14594.221697: tracing_mark_write: B|2007|prepareTree
+           <...>-23008 (-----) [005] d..2 14594.221706: sched_switch: prev_comm=hub.uiautomator prev_pid=23008 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-656   (-----) [000] .... 14594.221737: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-1803  (-----) [003] d..2 14594.221747: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
+           <...>-1397  (-----) [004] d..2 14594.221806: sched_switch: prev_comm=android.display prev_pid=1397 prev_prio=117 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120
+           <...>-1398  (-----) [006] d..2 14594.221816: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=R ==> next_comm=s.nexuslauncher next_pid=2007 next_prio=110
+           <...>-2738  (-----) [007] ...1 14594.221824: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221830: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221834: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221841: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221843: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221846: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.221850: tracing_mark_write: B|2007|dequeueBuffer
+           <...>-2738  (-----) [007] ...2 14594.221864: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [007] d..2 14594.221985: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=crtc_event:97 next_pid=303 next_prio=83
+           <...>-2007  (-----) [006] ...1 14594.221989: tracing_mark_write: B|2007|topResumedActivityChangeItem
+           <...>-303   (-----) [007] d..2 14594.222016: sched_switch: prev_comm=crtc_event:97 prev_pid=303 prev_prio=83 prev_state=S ==> next_comm=rcu_preempt next_pid=7 next_prio=120
+     rcu_preempt-7     (    7) [007] d..2 14594.222035: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
+     migration/4-46    (   46) [004] d..2 14594.222037: sched_switch: prev_comm=migration/4 prev_pid=46 prev_prio=0 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-2738  (-----) [007] d..2 14594.222039: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
+           <...>-656   (-----) [004] ...1 14594.222100: tracing_mark_write: B|625|dequeueBuffer
+           <...>-656   (-----) [004] ...1 14594.222114: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
+           <...>-2007  (-----) [006] ...2 14594.222131: binder_set_priority: proc=1368 thread=1903 old=120 => new=110 desired=110
+           <...>-2007  (-----) [006] d..2 14594.222143: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118
+           <...>-2613  (-----) [001] d..2 14594.222158: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-18150 (-----) [007] d..2 14594.222193: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-656   (-----) [004] .... 14594.222220: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-2738  (-----) [007] ...1 14594.222267: tracing_mark_write: B|2007|HWC release fence 36027 has signaled
+           <...>-656   (-----) [007] ...1 14594.223842: tracing_mark_write: B|625|queueBuffer
+           <...>-656   (-----) [007] ...1 14594.223845: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
+           <...>-656   (-----) [007] ...1 14594.223871: tracing_mark_write: B|625|requestNextVsync
+           <...>-656   (-----) [007] ...1 14594.223873: tracing_mark_write: B|625|resetIdleTimer
+           <...>-656   (-----) [007] ...1 14594.223881: tracing_mark_write: B|625|addAndGetFrameTimestamps
+           <...>-1395  (-----) [001] d..2 14594.223909: sched_switch: prev_comm=android.ui prev_pid=1395 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [007] ...1 14594.223959: tracing_mark_write: B|2007|Trace GPU completion fence 36027
+           <...>-11799 (-----) [006] ...1 14594.224006: tracing_mark_write: B|2007|waiting for GPU completion 36027
+           <...>-11799 (-----) [006] ...1 14594.224009: tracing_mark_write: B|2007|waitForever
+           <...>-2613  (-----) [004] d..2 14594.224014: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=Binder:1803_6 next_pid=2173 next_prio=120
+           <...>-11799 (-----) [006] d..1 14594.224014: fence_enable_signal: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78002
+           <...>-11799 (-----) [006] d..2 14594.224021: sched_switch: prev_comm=GPU completion prev_pid=11799 prev_prio=110 prev_state=S ==> next_comm=rcuop/6 next_pid=68 next_prio=120
+         rcuop/6-68    (   68) [006] d..2 14594.224044: sched_switch: prev_comm=rcuop/6 prev_pid=68 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-259   (-----) [006] d..2 14594.224132: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120
+           <...>-3206  (-----) [001] d..2 14594.224167: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=R ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
+    lowpool[847]-14589 ( 2446) [005] d..1 14594.224300: mm_filemap_delete_from_page_cache: dev 0:1 ino 3d0034 page=000000008247d586 pfn=676904 ofs=0
+           <...>-1803  (-----) [001] d..2 14594.224302: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=aiai-vc-0 next_pid=3206 next_prio=139
+           <...>-3206  (-----) [001] d..2 14594.224433: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-1903  (-----) [003] ...1 14594.224490: tracing_mark_write: B|1368|dispatchingStartProcess:com.google.android.dialer
+           <...>-1903  (-----) [003] ...1 14594.224659: tracing_mark_write: B|1368|wmLayout
+           <...>-1903  (-----) [003] ...1 14594.224666: tracing_mark_write: B|1368|performSurfacePlacement
+           <...>-1903  (-----) [003] ...1 14594.224683: tracing_mark_write: B|1368|applySurfaceChanges
+           <...>-1903  (-----) [003] ...1 14594.224688: tracing_mark_write: B|1368|openSurfaceTransaction
+           <...>-2738  (-----) [007] ...1 14594.224711: tracing_mark_write: B|2007|query
+           <...>-1903  (-----) [003] ...1 14594.224714: tracing_mark_write: B|1368|performLayout
+           <...>-2738  (-----) [007] ...1 14594.224714: tracing_mark_write: B|2007|query
+           <...>-1903  (-----) [003] ...1 14594.224723: tracing_mark_write: B|1368|applyPostLayoutPolicy
+           <...>-2738  (-----) [007] d..2 14594.224752: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-656   (-----) [007] .... 14594.224766: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-1398  (-----) [002] ...1 14594.224801: tracing_mark_write: B|1368|Theme::ApplyStyle
+           <...>-1398  (-----) [002] ...1 14594.224805: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224820: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224826: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224833: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224838: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224846: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224853: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224859: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-1398  (-----) [002] ...1 14594.224864: tracing_mark_write: B|1368|AssetManager::GetBag
+           <...>-18150 (-----) [006] d..2 14594.228407: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
+           <...>-2738  (-----) [007] d..2 14594.228411: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=kworker/7:0H next_pid=76 next_prio=100
+           <...>-1409  (-----) [004] ...1 14594.228417: tracing_mark_write: B|1368|Start proc: com.google.android.dialer
+           <...>-440   (-----) [006] d..2 14594.228418: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
+           <...>-76    (-----) [007] d..2 14594.228430: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
+           <...>-440   (-----) [007] d..2 14594.228434: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/7:0H next_pid=76 next_prio=100
+           <...>-18150 (-----) [006] d..3 14594.228442: sched_blocked_reason: pid=1398 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8
+           <...>-76    (-----) [007] d..2 14594.228442: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
+           <...>-2738  (-----) [007] ...2 14594.228446: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-18150 (-----) [006] d..2 14594.228447: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=110
+           <...>-2738  (-----) [007] d..2 14594.228479: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-1409  (-----) [004] d..2 14594.228499: sched_switch: prev_comm=ActivityManager prev_pid=1409 prev_prio=118 prev_state=D ==> next_comm=Binder:965_2 next_pid=1041 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229271: tracing_mark_write: B|625|handleTransaction
+           <...>-1773  (-----) [004] .... 14594.229285: binder_set_priority: proc=625 thread=1773 old=110 => new=120 desired=120
+           <...>-440   (-----) [007] d..2 14594.229301: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110
+           <...>-2738  (-----) [007] ...1 14594.229318: tracing_mark_write: B|2007|HWC release fence 36028 has signaled
+           <...>-2738  (-----) [007] ...1 14594.229331: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.229337: tracing_mark_write: B|2007|eglBeginFrame
+           <...>-2738  (-----) [007] ...1 14594.229352: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...1 14594.229354: tracing_mark_write: B|2007|query
+           <...>-791   (-----) [000] d..2 14594.229357: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229440: tracing_mark_write: B|625|doTransaction
+           <...>-13916 (-----) [002] d..2 14594.229482: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=D|K ==> next_comm=swapper/2 next_pid=0 next_prio=120
+           <...>-13917 (-----) [001] d..2 14594.229492: sched_blocked_reason: pid=13916 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-625   (-----) [003] ...1 14594.229492: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229507: tracing_mark_write: B|625|doTransaction
+           <...>-13917 (-----) [001] d..2 14594.229523: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-13916 (-----) [002] d..2 14594.229535: sched_blocked_reason: pid=13917 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-625   (-----) [003] ...1 14594.229538: tracing_mark_write: B|625|doTransaction
+           <...>-2738  (-----) [007] ...1 14594.229543: tracing_mark_write: B|2007|flush commands
+           <...>-13916 (-----) [002] .... 14594.229562: sched_process_exit: comm=HeapTaskDaemon pid=13916 prio=124
+           <...>-625   (-----) [003] ...1 14594.229567: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229588: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229628: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229652: tracing_mark_write: B|625|doTransaction
+           <...>-13916 (-----) [002] d..2 14594.229676: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=x ==> next_comm=swapper/2 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229676: tracing_mark_write: B|625|doTransaction
+           <...>-2007  (-----) [006] d..2 14594.229688: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229703: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229725: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229750: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229772: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.229792: tracing_mark_write: B|625|doTransaction
+           <...>-791   (-----) [000] d..2 14594.229811: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229824: tracing_mark_write: B|625|doTransaction
+           <...>-2738  (-----) [007] ...1 14594.229827: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR
+           <...>-13917 (-----) [001] d..2 14594.229836: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [007] ...1 14594.229837: tracing_mark_write: B|2007|setSurfaceDamage
+           <...>-625   (-----) [003] ...1 14594.229850: tracing_mark_write: B|625|doTransaction
+           <...>-13918 (-----) [002] d..2 14594.229856: sched_blocked_reason: pid=13917 iowait=0 caller=SyS_madvise+0xd34/0xd3c
+           <...>-5281  (-----) [001] d..2 14594.229932: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-89    (-----) [006] d..2 14594.229951: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.229982: tracing_mark_write: B|625|handleMessageInvalidate
+           <...>-625   (-----) [003] ...1 14594.229984: tracing_mark_write: B|625|handlePageFlip
+           <...>-625   (-----) [003] ...1 14594.230013: tracing_mark_write: B|625|latchBuffer
+           <...>-13917 (-----) [000] .... 14594.230015: sched_process_exit: comm=ReferenceQueueD pid=13917 prio=124
+           <...>-625   (-----) [003] ...1 14594.230020: tracing_mark_write: B|625|query
+           <...>-625   (-----) [003] ...1 14594.230028: tracing_mark_write: B|625|updateTexImage
+           <...>-625   (-----) [003] ...1 14594.230035: tracing_mark_write: B|625|acquireBuffer
+           <...>-625   (-----) [003] ...1 14594.230044: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
+           <...>-2738  (-----) [007] d..2 14594.230057: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=D ==> next_comm=smem_native_lpa next_pid=88 next_prio=120
+           <...>-14607 (-----) [000] d..2 14594.259609: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-2738  (-----) [005] d..2 14594.259620: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
+           <...>-1773  (-----) [005] ...1 14594.259649: tracing_mark_write: B|625|query
+           <...>-2738  (-----) [005] ...1 14594.259714: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] d..2 14594.259743: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
+           <...>-1773  (-----) [005] ...1 14594.259757: tracing_mark_write: B|625|query
+           <...>-2738  (-----) [005] ...1 14594.259810: tracing_mark_write: B|2007|syncFrameState
+           <...>-2738  (-----) [005] ...1 14594.259856: tracing_mark_write: B|2007|prepareTree
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259863: tracing_mark_write: B|14607|AttachCurrentThread
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259869: tracing_mark_write: B|14607|Thread::Attach
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259873: tracing_mark_write: B|14607|Thread birth
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259916: tracing_mark_write: B|14607|Thread::Init
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259920: tracing_mark_write: B|14607|InitStackHwm
+           <...>-14607 (-----) [000] d..2 14594.259932: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_1-14624 (14607) [002] d..2 14594.259941: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-3198  (-----) [001] ...1 14594.259942: tracing_mark_write: B|2007|Update SurfaceView position
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259963: tracing_mark_write: B|14607|InitTlsEntryPoints
+  Binder:14607_1-14624 (14607) [002] ...1 14594.259974: tracing_mark_write: B|14607|InitInterpreterTls
+           <...>-14607 (-----) [000] d..2 14594.260005: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-3198  (-----) [001] d..2 14594.260007: sched_switch: prev_comm=hwuiTask1 prev_pid=3198 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-14607 (-----) [000] d..2 14594.260024: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_1-14624 (14607) [002] d..2 14594.260038: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260064: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+  Binder:14607_1-14624 (14607) [002] ...1 14594.260101: tracing_mark_write: B|14607|ThreadList::Register
+           <...>-2738  (-----) [005] ...1 14594.260128: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260140: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260148: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260155: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260161: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260167: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260173: tracing_mark_write: B|2007|dequeueBuffer
+           <...>-2007  (-----) [001] d..2 14594.260201: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [005] d..2 14594.260214: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
+           <...>-1773  (-----) [005] ...1 14594.260236: tracing_mark_write: B|625|dequeueBuffer
+           <...>-1773  (-----) [005] ...1 14594.260249: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
+           <...>-14607 (-----) [000] d..2 14594.260334: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_1-14624 (14607) [002] d..2 14594.260343: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260376: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.260387: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-2738  (-----) [005] ...1 14594.260401: tracing_mark_write: B|2007|HWC release fence 36030 has signaled
+  Binder:14607_1-14624 (14607) [002] d..2 14594.260407: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-2738  (-----) [005] ...1 14594.260419: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260427: tracing_mark_write: B|2007|eglBeginFrame
+           <...>-2738  (-----) [005] ...1 14594.260445: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [005] ...1 14594.260450: tracing_mark_write: B|2007|query
+  Binder:14607_1-14624 (14607) [002] .... 14594.260472: task_newtask: pid=14625 comm=Binder:14607_1 clone_flags=3d0f00 oom_score_adj=-1000
+           <...>-14607 (-----) [000] d..2 14594.260517: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260525: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260555: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] ...1 14594.260569: tracing_mark_write: B|14607|ActivityThreadMain
+           <...>-14607 (-----) [000] d..2 14594.260581: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260588: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260611: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.260623: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260636: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260663: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.260674: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260694: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.260724: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-2738  (-----) [005] ...1 14594.260734: tracing_mark_write: B|2007|flush commands
+           <...>-14607 (-----) [000] d..2 14594.260735: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260753: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260925: tracing_mark_write: B|14607|AttachCurrentThread
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260930: tracing_mark_write: B|14607|Thread::Attach
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260933: tracing_mark_write: B|14607|Thread birth
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260973: tracing_mark_write: B|14607|Thread::Init
+  Binder:14607_2-14625 (14607) [001] ...1 14594.260977: tracing_mark_write: B|14607|InitStackHwm
+           <...>-14607 (-----) [000] d..2 14594.260990: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.260998: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+  Binder:14607_2-14625 (14607) [001] ...1 14594.261023: tracing_mark_write: B|14607|InitTlsEntryPoints
+  Binder:14607_2-14625 (14607) [001] ...1 14594.261034: tracing_mark_write: B|14607|InitInterpreterTls
+           <...>-14607 (-----) [000] d..2 14594.261064: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.261075: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.261094: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] d..2 14594.261120: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-14607 (-----) [000] d..2 14594.261132: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+  Binder:14607_2-14625 (14607) [001] d..2 14594.261146: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+  Binder:14607_2-14625 (14607) [001] ...1 14594.261167: tracing_mark_write: B|14607|ThreadList::Register
+           <...>-14607 (-----) [000] d..2 14594.261209: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
+           <...>-2738  (-----) [005] ...1 14594.261212: tracing_mark_write: B|2007|waitOnFences
+           <...>-14607 (-----) [000] d..2 14594.261220: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-2738  (-----) [005] ...1 14594.261232: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR
+           <...>-2738  (-----) [005] ...1 14594.261244: tracing_mark_write: B|2007|setSurfaceDamage
+  Binder:14607_2-14625 (14607) [001] d..2 14594.261246: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
+           <...>-14607 (-----) [000] ...1 14594.261326: tracing_mark_write: B|14607|VerifyClass com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
+           <...>-2738  (-----) [005] .... 14594.261621: fence_init: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78005
+           <...>-625   (-----) [003] ...1 14594.263903: tracing_mark_write: B|625|resetIdleTimer
+           <...>-625   (-----) [003] ...1 14594.263912: tracing_mark_write: B|625|rebuildLayerStacks
+           <...>-625   (-----) [003] ...1 14594.263915: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
+           <...>-625   (-----) [003] ...1 14594.263919: tracing_mark_write: B|625|computeVisibleRegions
+           <...>-1398  (-----) [006] d..2 14594.263966: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
+           <...>-1695  (-----) [001] d..2 14594.264086: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.264293: tracing_mark_write: B|625|calculateWorkingSet
+           <...>-625   (-----) [003] ...1 14594.264500: tracing_mark_write: B|625|prepare
+           <...>-625   (-----) [003] ...1 14594.264513: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client
+           <...>-625   (-----) [003] ...2 14594.264584: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98
+           <...>-625   (-----) [003] d..2 14594.264617: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=logd.writer next_pid=588 next_prio=130
+           <...>-588   (-----) [003] d..2 14594.264851: sched_switch: prev_comm=logd.writer prev_pid=588 prev_prio=130 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
+     rcu_preempt-7     (    7) [007] d..2 14594.265273: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=kworker/u16:3 next_pid=18008 next_prio=120
+           <...>-18008 (-----) [007] d..2 14594.265404: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-18008 (-----) [007] d..2 14594.265471: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.265496: tracing_mark_write: B|625|doComposition
+           <...>-625   (-----) [003] ...1 14594.265507: tracing_mark_write: B|625|doComposeSurfaces
+           <...>-625   (-----) [003] ...1 14594.265552: tracing_mark_write: B|625|acquireBuffer
+           <...>-625   (-----) [003] ...1 14594.265563: tracing_mark_write: B|625|postFramebuffer
+           <...>-625   (-----) [003] ...1 14594.265567: tracing_mark_write: B|625|presentAndGetReleaseFences
+           <...>-625   (-----) [003] d..1 14594.265601: fence_enable_signal: driver=sde_fence:crtc97:91650 timeline=crtc97 context=3 seqno=91650
+           <...>-625   (-----) [003] ...1 14594.265735: tracing_mark_write: B|625|logLayerStats
+           <...>-625   (-----) [003] ...1 14594.265744: tracing_mark_write: B|625|postComposition
+           <...>-625   (-----) [003] ...1 14594.265749: tracing_mark_write: B|625|releaseBuffer
+           <...>-625   (-----) [003] ...1 14594.265753: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1
+           <...>-625   (-----) [003] ...1 14594.265791: tracing_mark_write: B|625|releaseBuffer
+           <...>-440   (-----) [007] d..2 14594.342366: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u17:2 next_pid=1778 next_prio=100
+           <...>-2007  (-----) [006] ...1 14594.342375: tracing_mark_write: B|2007|input
+           <...>-2007  (-----) [006] ...1 14594.342399: tracing_mark_write: B|2007|animation
+           <...>-625   (-----) [003] ...1 14594.342447: tracing_mark_write: B|625|doTransaction
+           <...>-625   (-----) [003] ...1 14594.342489: tracing_mark_write: B|625|doTransaction
+   kworker/u17:2-1778  ( 1778) [007] d..3 14594.342532: sched_blocked_reason: pid=14607 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8
+   kworker/u17:2-1778  ( 1778) [007] d..2 14594.342544: sched_switch: prev_comm=kworker/u17:2 prev_pid=1778 prev_prio=100 prev_state=S ==> next_comm=kworker/u16:2 next_pid=27544 next_prio=120
+           <...>-1773  (-----) [000] ...1 14594.342575: tracing_mark_write: B|625|requestNextVsync
+           <...>-1773  (-----) [000] ...1 14594.342579: tracing_mark_write: B|625|resetIdleTimer
+           <...>-27544 (-----) [007] d..2 14594.342589: sched_switch: prev_comm=kworker/u16:2 prev_pid=27544 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-656   (-----) [002] d.h3 14594.342604: sched_blocked_reason: pid=1233 iowait=0 caller=geni_i2c_xfer+0x4d8/0x1398
+           <...>-1803  (-----) [001] d..2 14594.342605: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.342632: tracing_mark_write: B|625|handleMessageInvalidate
+           <...>-625   (-----) [003] ...1 14594.342634: tracing_mark_write: B|625|handlePageFlip
+           <...>-2738  (-----) [007] ...1 14594.342641: tracing_mark_write: B|2007|notifyFramePending
+           <...>-658   (-----) [002] d..2 14594.342653: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=120
+           <...>-656   (-----) [002] ...1 14594.342656: tracing_mark_write: B|625|requestNextVsync
+           <...>-2738  (-----) [007] d..2 14594.342658: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
+           <...>-656   (-----) [002] ...1 14594.342660: tracing_mark_write: B|625|resetIdleTimer
+           <...>-660   (-----) [005] d..2 14594.342663: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.342665: tracing_mark_write: B|625|latchBuffer
+           <...>-625   (-----) [003] ...1 14594.342673: tracing_mark_write: B|625|query
+           <...>-625   (-----) [003] ...1 14594.342682: tracing_mark_write: B|625|updateTexImage
+           <...>-625   (-----) [003] ...1 14594.342693: tracing_mark_write: B|625|acquireBuffer
+           <...>-625   (-----) [003] ...1 14594.342703: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1
+           <...>-660   (-----) [005] d..2 14594.342709: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
+           <...>-2007  (-----) [006] ...1 14594.342733: tracing_mark_write: B|2007|traversal
+           <...>-2007  (-----) [006] ...1 14594.342776: tracing_mark_write: B|2007|draw
+           <...>-2007  (-----) [006] ...1 14594.342791: tracing_mark_write: B|2007|Record View#draw()
+           <...>-625   (-----) [003] ...1 14594.342849: tracing_mark_write: B|625|updateInputFlinger
+           <...>-2007  (-----) [006] d..2 14594.342903: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=kworker/6:2H next_pid=24261 next_prio=100
+           <...>-2738  (-----) [007] ...1 14594.342910: tracing_mark_write: B|2007|DrawFrame
+           <...>-2738  (-----) [007] d..2 14594.342917: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
+           <...>-24261 (-----) [006] d..2 14594.342918: sched_switch: prev_comm=kworker/6:2H prev_pid=24261 prev_prio=100 prev_state=S ==> next_comm=.android.dialer next_pid=14607 next_prio=110
+           <...>-440   (-----) [007] d..2 14594.342926: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110
+           <...>-2738  (-----) [007] ...1 14594.342927: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [007] ...2 14594.342959: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [007] d..2 14594.342975: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-656   (-----) [007] ...1 14594.343021: tracing_mark_write: B|625|query
+           <...>-656   (-----) [007] .... 14594.343033: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-2738  (-----) [007] ...1 14594.343070: tracing_mark_write: B|2007|query
+           <...>-1233  (-----) [004] d..2 14594.343074: sched_switch: prev_comm=sound trigger c prev_pid=1233 prev_prio=120 prev_state=R+ ==> next_comm=irq/144-1436400 next_pid=2522 next_prio=49
+           <...>-2738  (-----) [007] ...2 14594.343078: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-625   (-----) [003] ...1 14594.343084: tracing_mark_write: B|625|onMessageReceived
+           <...>-625   (-----) [003] ...1 14594.343087: tracing_mark_write: B|625|handleMessageRefresh
+           <...>-625   (-----) [003] ...1 14594.343090: tracing_mark_write: B|625|preComposition
+           <...>-2738  (-----) [007] d..2 14594.343090: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-625   (-----) [003] ...1 14594.343122: tracing_mark_write: B|625|rebuildLayerStacks
+           <...>-625   (-----) [003] ...1 14594.343124: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
+           <...>-89    (-----) [007] d..2 14594.343126: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-625   (-----) [003] ...1 14594.343129: tracing_mark_write: B|625|computeVisibleRegions
+           <...>-656   (-----) [007] ...1 14594.343136: tracing_mark_write: B|625|query
+           <...>-14607 (-----) [006] ...2 14594.343141: binder_set_priority: proc=1368 thread=3253 old=120 => new=110 desired=110
+                      <...>-2965  (-----) [001] .... 14596.746610: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002ae8fcff pfn=1522884 ofs=188416
+          <idle>-0     (-----) [002] d..2 14596.746619: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
+           <...>-2965  (-----) [001] .... 14596.746629: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000679ee1ec pfn=1299913 ofs=192512
+           <...>-2965  (-----) [001] .... 14596.746664: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000006cd2fb7 pfn=1296251 ofs=196608
+           <...>-2965  (-----) [001] .... 14596.746677: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000af82f3d6 pfn=1419330 ofs=200704
+           <...>-2965  (-----) [001] .... 14596.746693: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002840f054 pfn=1304928 ofs=204800
+           <...>-2965  (-----) [001] .... 14596.746706: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000004a59da17 pfn=1288069 ofs=208896
+           <...>-2965  (-----) [001] .... 14596.746717: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000023a80dca pfn=1419686 ofs=212992
+           <...>-2965  (-----) [001] .... 14596.746730: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000001cf89eab pfn=1315372 ofs=217088
+           <...>-2965  (-----) [001] .... 14596.746743: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000005b4c6cb6 pfn=1380698 ofs=221184
+           <...>-2965  (-----) [001] .... 14596.746760: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f8304ae7 pfn=1206753 ofs=225280
+           <...>-2965  (-----) [001] .... 14596.746773: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000cb912305 pfn=1325465 ofs=229376
+           <...>-2965  (-----) [001] .... 14596.746785: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f16f3774 pfn=1408056 ofs=233472
+           <...>-2965  (-----) [001] .... 14596.746801: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000056d4c926 pfn=1418352 ofs=237568
+           <...>-2965  (-----) [001] .... 14596.746815: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f3eeb42c pfn=1320957 ofs=241664
+           <...>-440   (-----) [002] d..2 14596.746916: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=swapper/2 next_pid=0 next_prio=120
+
+           <...>-656   (-----) [007] .... 14594.343145: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
+           <...>-14607 (-----) [006] d..2 14594.343164: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-5281  (-----) [002] d..2 14594.343177: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
+ irq/144-1436400-2522  ( 2522) [004] d..2 14594.343223: sched_switch: prev_comm=irq/144-1436400 prev_pid=2522 prev_prio=49 prev_state=D ==> next_comm=sound trigger c next_pid=1233 next_prio=120
+           <...>-88    (-----) [006] d..2 14594.343240: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-1238  (-----) [001] d..2 14594.343243: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-2738  (-----) [002] ...1 14594.343244: tracing_mark_write: B|2007|syncFrameState
+           <...>-2738  (-----) [002] ...1 14594.343293: tracing_mark_write: B|2007|prepareTree
+           <...>-1695  (-----) [001] d..2 14594.343318: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
+           <...>-5281  (-----) [005] d..2 14594.343322: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=110
+           <...>-1238  (-----) [001] d..2 14594.343442: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=InputDispatcher next_pid=1695 next_prio=112
+           <...>-1695  (-----) [001] d..2 14594.343467: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
+           <...>-5281  (-----) [000] d..2 14594.343484: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
+           <...>-625   (-----) [003] ...1 14594.343519: tracing_mark_write: B|625|calculateWorkingSet
+           <...>-2738  (-----) [002] ...1 14594.343568: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343577: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343586: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343591: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343597: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343602: tracing_mark_write: B|2007|query
+           <...>-2738  (-----) [002] ...1 14594.343609: tracing_mark_write: B|2007|dequeueBuffer
+           <...>-2007  (-----) [006] d..2 14594.343612: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
+           <...>-2738  (-----) [002] ...2 14594.343633: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
+           <...>-2738  (-----) [002] d..2 14594.343683: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
+           <...>-625   (-----) [003] ...1 14594.343704: tracing_mark_write: B|625|prepare
+           <...>-656   (-----) [002] ...1 14594.343707: tracing_mark_write: B|625|dequeueBuffer
+           <...>-625   (-----) [004] ...1 14594.812869: tracing_mark_write: B|625|com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#0: 2
+           <...>-2048  (-----) [000] d..2 14594.812895: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_3 next_pid=1431 next_prio=120
+           <...>-1431  (-----) [000] ...1 14594.812911: tracing_mark_write: B|625|query
+           <...>-625   (-----) [004] ...1 14594.812914: tracing_mark_write: B|625|latchBuffer
+           <...>-625   (-----) [004] ...1 14594.812919: tracing_mark_write: B|625|query
+           <...>-625   (-----) [004] ...1 14594.812925: tracing_mark_write: B|625|updateTexImage
+           <...>-625   (-----) [004] ...1 14594.812928: tracing_mark_write: B|625|acquireBuffer
+           <...>-625   (-----) [004] ...1 14594.812934: tracing_mark_write: B|625|StatusBar#0: 1
+           <...>-2048  (-----) [000] ...1 14594.812962: tracing_mark_write: B|1803|syncFrameState
+           <...>-656   (-----) [002] ...1 14594.813044: tracing_mark_write: B|625|setTransactionState
+           <...>-14607 (-----) [007] ...2 14594.813083: binder_set_priority: proc=10691 thread=18733 old=120 => new=110 desired=110
+           <...>-14607 (-----) [007] d..2 14594.813114: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120
+           <...>-14655 (-----) [006] d..2 14594.813128: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=lpass_smem_glin next_pid=89 next_prio=98
+           <...>-89    (-----) [006] d..2 14594.813163: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
+           <...>-656   (-----) [002] ...1 14594.813218: tracing_mark_write: B|625|requestNextVsync
+           <...>-656   (-----) [002] ...1 14594.813222: tracing_mark_write: B|625|resetIdleTimer
+     kworker/7:1-7092  ( 7092) [007] d..2 14594.813239: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98
+           <...>-5281  (-----) [001] d..2 14594.813245: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110
+           <...>-88    (-----) [007] d..2 14594.813248: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=R ==> next_comm=kgsl_worker_thr next_pid=259 next_prio=97
+           <...>-2048  (-----) [000] d..2 14594.813249: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
+           <...>-14655 (-----) [006] d..2 14594.813263: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98
+           <...>-661   (-----) [002] d..2 14594.813265: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
+           <...>-259   (-----) [007] d..2 14594.813265: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120
+     kworker/7:1-7092  ( 7092) [007] d..2 14594.813271: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
+           <...>-108   (-----) [007] .... 14594.813275: ion_heap_shrink: heap_name=system, len=9469952, total_allocated=189620224
+           <...>-88    (-----) [006] d..2 14594.813294: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
+           <...>-625   (-----) [004] ...1 14594.813310: tracing_mark_write: B|625|updateInputFlinger
+           <...>-1238  (-----) [000] d..2 14594.813312: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
+           <...>-661   (-----) [002] d..2 14594.813317: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
+           <...>-14640 (-----) [005] d..2 14594.813319: sched_switch: prev_comm=DialerExecutors prev_pid=14640 prev_prio=130 prev_state=R ==> next_comm=DispSync next_pid=658 next_prio=97
+           <...>-656   (-----) [002] ...1 14594.813336: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-658   (-----) [005] d..2 14594.813345: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=DialerExecutors next_pid=14640 next_prio=130
+           <...>-656   (-----) [002] ...1 14594.813345: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813353: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-2048  (-----) [000] d..2 14594.813358: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
+           <...>-656   (-----) [002] ...1 14594.813364: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-5281  (-----) [001] d..2 14594.813369: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110
+           <...>-656   (-----) [002] ...1 14594.813372: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813380: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813391: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813398: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813408: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813416: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813424: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813432: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] .n.1 14594.813443: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-1238  (-----) [000] d..2 14594.813464: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
+           <...>-5281  (-----) [002] d..2 14594.813525: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
+           <...>-656   (-----) [002] ...1 14594.813544: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-656   (-----) [002] ...1 14594.813557: tracing_mark_write: B|625|~GraphicBuffer
+           <...>-2048  (-----) [000] d..2 14594.813594: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120
+           <...>-18733 (-----) [001] ...2 14594.813635: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110
+           <...>-656   (-----) [002] .... 14594.813637: binder_set_priority: proc=625 thread=656 old=116 => new=120 desired=120
+           <...>-108   (-----) [007] d..2 14594.813646: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116
+           <...>-625   (-----) [004] ...1 14594.813646: tracing_mark_write: B|625|onMessageReceived
+           <...>-625   (-----) [004] ...1 14594.813649: tracing_mark_write: B|625|handleMessageRefresh
+           <...>-625   (-----) [004] ...1 14594.813651: tracing_mark_write: B|625|preComposition
+           <...>-625   (-----) [004] ...1 14594.813693: tracing_mark_write: B|625|rebuildLayerStacks
+           <...>-625   (-----) [004] ...1 14594.813696: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
+           <...>-625   (-----) [004] ...1 14594.813701: tracing_mark_write: B|625|computeVisibleRegions
+           <...>-1398  (-----) [007] d..2 14594.813718: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=116 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
+           <...>-108   (-----) [007] d..2 14594.813739: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116
+           <...>-1695  (-----) [002] d..2 14594.813970: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
+           <...>-1398  (-----) [007] ...1 14594.814029: tracing_mark_write: B|1368|wmLayout
+           <...>-1398  (-----) [007] ...1 14594.814033: tracing_mark_write: B|1368|performSurfacePlacement
+           <...>-1398  (-----) [007] ...1 14594.814040: tracing_mark_write: B|1368|applySurfaceChanges
+           <...>-1398  (-----) [007] ...1 14594.814043: tracing_mark_write: B|1368|openSurfaceTransaction
+           <...>-1398  (-----) [007] ...1 14594.814063: tracing_mark_write: B|1368|performLayout
+           <...>-625   (-----) [004] ...1 14594.814119: tracing_mark_write: B|625|calculateWorkingSet
+           <...>-1398  (-----) [007] ...1 14594.814241: tracing_mark_write: B|1368|layoutInputConsumer
+           <...>-2048  (-----) [000] ...1 14594.814260: tracing_mark_write: B|1803|prepareTree
+           <...>-1398  (-----) [007] ...1 14594.814263: tracing_mark_write: B|1368|applyPostLayoutPolicy
+           <...>-2048  (-----) [000] d..2 14594.814408: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120
+           <...>-625   (-----) [004] ...1 14594.814411: tracing_mark_write: B|625|prepare
+           <...>-625   (-----) [004] ...1 14594.814428: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client
+           <...>-2048  (-----) [000] d..2 14594.814533: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
+           <...>-1803  (-----) [000] d..2 14594.814558: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
+           <...>-2048  (-----) [000] d..2 14594.814572: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
+           <...>-625   (-----) [004] ...2 14594.814589: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98
+           <...>-108   (-----) [002] d..2 14594.814650: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=composer@2.2-se next_pid=627 next_prio=98
+           <...>-625   (-----) [004] d..2 14594.814664: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=ashmemd next_pid=854 next_prio=129
+           <...>-1398  (-----) [007] ...1 14594.814723: tracing_mark_write: B|1368|applyWindowSurfaceChanges
+           <...>-854   (-----) [004] .... 14594.814746: binder_set_priority: proc=854 thread=854 old=129 => new=120 desired=120
+           <...>-854   (-----) [004] d..2 14594.814757: sched_switch: prev_comm=ashmemd prev_pid=854 prev_prio=120 prev_state=R+ ==> next_comm=highpool[0] next_pid=3493 next_prio=129
+           <...>-1803  (-----) [000] d..2 14594.814763: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
+           <...>-18733 (-----) [001] d..1 14594.814819: mm_filemap_delete_from_page_cache: dev 0:1 ino 3ce5e7 page=0000000083f10c7a pfn=1298474 ofs=0
+           <...>-2048  (-----) [000] ...1 14594.814842: tracing_mark_write: B|1803|dequeueBuffer
+           <...>-1398  (-----) [007] ...1 14594.814850: tracing_mark_write: F|1368|launching: com.google.android.dialer|0
+           <...>-1398  (-----) [007] ...1 14594.814855: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunchFinished
+           <...>-1398  (-----) [007] ...1 14594.814857: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto
+           <...>-2048  (-----) [000] d..2 14594.814905: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=120
+           <...>-1410  (-----) [006] .... 14592.997816: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=00000000615a8f24 pfn=1134764 ofs=0
+           <...>-1410  (-----) [006] .... 14592.997831: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=000000008768a58f pfn=1134751 ofs=4096
+
+           <...>-18733 (-----) [001] .... 14594.814914: binder_set_priority: proc=10691 thread=18733 old=110 => new=120 desired=120
+           <...>-14655 (-----) [006] d..2 14594.814932: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=.android.dialer next_pid=14607 next_prio=110
+           <...>-656   (-----) [000] ...1 14594.814948: tracing_mark_write: B|625|dequeueBuffer
+           <...>-3514  (-----) [001] .... 14594.814954: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120
+           <...>-656   (-----) [000] ...1 14594.814963: tracing_mark_write: B|625|NavigationBar0#0: 2
+           <...>-14607 (-----) [006] ...2 14594.815022: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110
+           <...>-1398  (-----) [007] ...1 14594.815039: tracing_mark_write: B|1368|prepareSurfaces
+           <...>-14607 (-----) [006] d..2 14594.815041: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
+           <...>-3493  (-----) [004] d..2 14594.815057: sched_switch: prev_comm=highpool[0] prev_pid=3493 prev_prio=129 prev_state=R ==> next_comm=Binder:1368_18 next_pid=3514 next_prio=110
+           <...>-2048  (-----) [000] ...1 14594.815088: tracing_mark_write: B|1803|HWC release fence 45750 has signaled
+           <...>-2048  (-----) [000] ...1 14594.815119: tracing_mark_write: B|1803|eglBeginFrame
+           <...>-14655 (-----) [006] d..2 14594.815190: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=crtc_commit:97 next_pid=301 next_prio=83
+           <...>-3514  (-----) [004] .... 14594.815193: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120
+           <...>-1398  (-----) [007] ...1 14594.815322: tracing_mark_write: B|1368|closeSurfaceTransaction
+           <...>-3493  (-----) [004] .... 14594.815353: mm_filemap_add_to_page_cache: dev 253:6 ino 113b page=0000000069e2b98a pfn=628464 ofs=2723840
+           <...>-1398  (-----) [007] ...2 14594.815393: binder_set_priority: proc=625 thread=656 old=120 => new=116 desired=116
+       rcu_sched-8     (    8) [007] d..2 14594.815449: sched_switch: prev_comm=rcu_sched prev_pid=8 prev_prio=120 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
diff --git a/startop/scripts/trace_analyzer/trace_analyzer b/startop/scripts/trace_analyzer/trace_analyzer
new file mode 100755
index 0000000..8c03964
--- /dev/null
+++ b/startop/scripts/trace_analyzer/trace_analyzer
@@ -0,0 +1,42 @@
+#!/bin/bash
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR="$( cd "$(dirname "$0")" ; pwd -P )"
+
+if [[ "$#" -lt 2 ]]; then
+  echo "Usage: $0 <filename.trace> <sqlite-filename.db>" >&2
+  exit 1
+fi
+
+TRACE_FILENAME="$1"
+SQLITE_FILENAME="$2"
+
+#echo "Trace filename: $TRACE_FILENAME"
+#echo "SQLite filename: $SQLITE_FILENAME"
+
+if ! [[ -f "$TRACE_FILENAME" ]]; then
+  echo "Error: Trace '$TRACE_FILENAME' does not exist." >&2
+  exit 1
+fi
+
+if ! "$DIR/trace_analyzer.py" "$SQLITE_FILENAME" "$TRACE_FILENAME" > /dev/null; then
+  echo "Fatal: trace_analyzer.py failed, aborting." >&2
+  exit 1
+fi
+
+if ! "$DIR/run-sql-queries" "$SQLITE_FILENAME"; then
+  echo "Fatal: Failed to run sql queries, aborting." >&2
+  exit 1
+fi
diff --git a/startop/scripts/trace_analyzer/trace_analyzer.py b/startop/scripts/trace_analyzer/trace_analyzer.py
new file mode 100755
index 0000000..62ae018
--- /dev/null
+++ b/startop/scripts/trace_analyzer/trace_analyzer.py
@@ -0,0 +1,51 @@
+#!/usr/bin/python3
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import re
+import sys
+import argparse
+
+from lib.trace2db import Trace2Db
+
+# This script requires 'sqlalchemy' to access the sqlite3 database.
+#
+# $> sudo apt-get install python3-pip
+# $> pip3 install --user sqlalchemy
+#
+
+def main(argv):
+  parser = argparse.ArgumentParser(description='Convert ftrace/systrace file into sqlite3 db.')
+  parser.add_argument('db_filename', metavar='sql_filename.db', type=str,
+                      help='path to sqlite3 db filename')
+  parser.add_argument('trace_filename', metavar='systrace.ftrace', type=str,
+                      help='path to ftrace/systrace filename')
+  parser.add_argument('--limit', type=int, help='limit the number of entries parsed [for debugging]')
+
+  args = parser.parse_args()
+
+  db_filename = args.db_filename
+  trace_filename = args.trace_filename
+
+  trace2db = Trace2Db(db_filename)
+  print("SQL Alchemy db initialized")
+
+  # parse 'raw_ftrace_entries' table
+  count = trace2db.parse_file_into_db(trace_filename, limit=args.limit)
+  print("Count was ", count)
+
+  return 0
+
+if __name__ == '__main__':
+  main(sys.argv)
diff --git a/startop/scripts/trace_analyzer/trace_analyzer_recursive b/startop/scripts/trace_analyzer/trace_analyzer_recursive
new file mode 100755
index 0000000..4d9ee0e
--- /dev/null
+++ b/startop/scripts/trace_analyzer/trace_analyzer_recursive
@@ -0,0 +1,78 @@
+#!/bin/bash
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DIR="$( cd "$(dirname "$0")" ; pwd -P )"
+
+if [[ "$#" -lt 3 ]]; then
+  echo "Usage: $0 <trace-dir> <db-dir> <output.csv>" >&2
+  exit 1
+fi
+
+simulate="n"
+
+TRACE_DIRNAME="$1"
+SQLITE_DIRNAME="$2"
+OUTPUT_FILENAME="$3"
+
+echo "Trace filename: $TRACE_DIRNAME"
+echo "SQLite filename: $SQLITE_DIRNAME"
+
+if ! [[ -d "$TRACE_DIRNAME" ]]; then
+  echo "Error: Trace '$TRACE_DIRNAME' does not exist." >&2
+  exit 1
+fi
+
+process_trace_file() {
+  local trace_filename="$1"
+  local db_dirname="$2"
+  local output_file="$3"
+
+  local db_filename="$db_dirname/$(basename "$trace_filename").db"
+
+  if [[ $simulate == y ]]; then
+    echo "$DIR/trace_analyzer.py" "$db_filename" "$trace_filename" "> /dev/null"
+  else
+    if ! "$DIR/trace_analyzer.py" "$db_filename" "$trace_filename" > /dev/null; then
+      echo "Fatal: trace_analyzer.py failed, aborting." >&2
+      return 1
+    fi
+  fi
+
+  if [[ $simulate == y ]]; then
+    echo "$DIR/run-sql-queries" "$db_filename" ">> '$output_file'"
+  else
+    # append name of trace to CSV, so we can see where data came from
+    echo "; $trace_filename" >> "$output_file"
+    if ! "$DIR/run-sql-queries" "$db_filename" >> "$output_file"; then
+      echo "Fatal: Failed to run sql queries, aborting." >&2
+      return 1
+    fi
+  fi
+
+  return 0
+}
+
+find "$TRACE_DIRNAME" -type f -name '*.trace' -print0 |
+while IFS= read -r -d '' file; do
+  if [[ $file == *#*.trace && $file != *#1.trace ]]; then
+    echo "Skip $file"
+    continue
+  fi
+
+  printf '%s\n' "$file"
+  process_trace_file "$file" "$SQLITE_DIRNAME" "$OUTPUT_FILENAME"
+done
+
+echo "Done"
diff --git a/startop/scripts/trace_analyzer/trace_analyzer_test.py b/startop/scripts/trace_analyzer/trace_analyzer_test.py
new file mode 100644
index 0000000..579529c
--- /dev/null
+++ b/startop/scripts/trace_analyzer/trace_analyzer_test.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+#
+# 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.
+#
+
+"""
+Unit tests for trace_analyzer module.
+
+Install:
+  $> sudo apt-get install python3-pytest   ##  OR
+  $> pip install -U pytest
+See also https://docs.pytest.org/en/latest/getting-started.html
+
+Usage:
+  $> pytest trace_analyzer_test.py
+
+See also https://docs.pytest.org/en/latest/usage.html
+"""
+
+# global imports
+import os
+import sys
+
+DIR = os.path.abspath(os.path.dirname(__file__))
+
+sys.path.append(os.path.dirname(DIR))
+import lib.cmd_utils as cmd_utils
+
+def test_trace_analyzer(tmpdir):
+  # Setup
+  bin = os.path.join(DIR, 'trace_analyzer')
+  systrace = os.path.join(DIR, 'test_fixtures/common_systrace')
+  db_file = tmpdir.mkdir('trace_analyzer').join('test.db')
+
+  # Act
+  passed, output = cmd_utils.execute_arbitrary_command([bin, systrace,
+                                                        str(db_file)],
+                                                       timeout=300,
+                                                       shell=False,
+                                                       simulate=False)
+
+  # Assert
+  assert passed
+  assert output == """\
+'blocked_iowait_duration_ms',\
+'process_name',\
+'launching_duration_ms',\
+'launching_started_timestamp_ms',\
+'launching_finished_timestamp_ms'
+81.697999999960302375,\
+'com.google.android.dialer',\
+594.99400000095192808,\
+14594219.85600000061,\
+14594814.85000000149"""
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 6000b56..cd5fd97 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -95,6 +95,10 @@
     private Bundle mExtras;
     private Set<String> mPreviousExtraKeys;
     private final Object mExtrasLock = new Object();
+    private Uri mAddress;
+    private int mAddressPresentation;
+    private String mCallerDisplayName;
+    private int mCallerDisplayNamePresentation;
 
     private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
         @Override
@@ -987,12 +991,67 @@
      */
     public final void setAddress(Uri address, int presentation) {
         Log.d(this, "setAddress %s", address);
+        mAddress = address;
+        mAddressPresentation = presentation;
         for (Listener l : mListeners) {
             l.onAddressChanged(this, address, presentation);
         }
     }
 
     /**
+     * Returns the "address" associated with the conference.  This is applicable in two cases:
+     * <ol>
+     *     <li>When {@link #setConferenceState(boolean)} is used to mark a conference as
+     *     temporarily "not a conference"; we need to present the correct address in the in-call
+     *     UI.</li>
+     *     <li>When the conference is not hosted on the current device, we need to know the address
+     *     information for the purpose of showing the original address to the user, as well as for
+     *     logging to the call log.</li>
+     * </ol>
+     * @return The address of the conference, or {@code null} if not applicable.
+     * @hide
+     */
+    public final Uri getAddress() {
+        return mAddress;
+    }
+
+    /**
+     * Returns the address presentation associated with the conference.
+     * <p>
+     * This is applicable in two cases:
+     * <ol>
+     *     <li>When {@link #setConferenceState(boolean)} is used to mark a conference as
+     *     temporarily "not a conference"; we need to present the correct address in the in-call
+     *     UI.</li>
+     *     <li>When the conference is not hosted on the current device, we need to know the address
+     *     information for the purpose of showing the original address to the user, as well as for
+     *     logging to the call log.</li>
+     * </ol>
+     * @return The address of the conference, or {@code null} if not applicable.
+     * @hide
+     */
+    public final int getAddressPresentation() {
+        return mAddressPresentation;
+    }
+
+    /**
+     * @return The caller display name (CNAP).
+     * @hide
+     */
+    public final String getCallerDisplayName() {
+        return mCallerDisplayName;
+    }
+
+    /**
+     * @return The presentation requirements for the handle.
+     *         See {@link TelecomManager} for valid values.
+     * @hide
+     */
+    public final int getCallerDisplayNamePresentation() {
+        return mCallerDisplayNamePresentation;
+    }
+
+    /**
      * Sets the caller display name (CNAP) of this {@link Conference}.  Used when
      * {@link #setConferenceState(boolean)} is called to mark a conference temporarily as NOT a
      * conference.
@@ -1004,6 +1063,8 @@
      */
     public final void setCallerDisplayName(String callerDisplayName, int presentation) {
         Log.d(this, "setCallerDisplayName %s", callerDisplayName);
+        mCallerDisplayName = callerDisplayName;
+        mCallerDisplayNamePresentation = presentation;
         for (Listener l : mListeners) {
             l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
         }
diff --git a/telecomm/java/android/telecom/ConferenceParticipant.java b/telecomm/java/android/telecom/ConferenceParticipant.java
index 2f1505c..5e4818a 100644
--- a/telecomm/java/android/telecom/ConferenceParticipant.java
+++ b/telecomm/java/android/telecom/ConferenceParticipant.java
@@ -19,6 +19,7 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -69,18 +70,28 @@
     private long mConnectElapsedTime;
 
     /**
+     * The direction of the call;
+     * {@link Call.Details#DIRECTION_INCOMING} for incoming calls, or
+     * {@link Call.Details#DIRECTION_OUTGOING} for outgoing calls.
+     */
+    private int mCallDirection;
+
+    /**
      * Creates an instance of {@code ConferenceParticipant}.
      *
      * @param handle      The conference participant's handle (e.g., phone number).
      * @param displayName The display name for the participant.
      * @param endpoint    The enpoint Uri which uniquely identifies this conference participant.
      * @param state       The state of the participant in the conference.
+     * @param callDirection The direction of the call (incoming/outgoing).
      */
-    public ConferenceParticipant(Uri handle, String displayName, Uri endpoint, int state) {
+    public ConferenceParticipant(Uri handle, String displayName, Uri endpoint, int state,
+            int callDirection) {
         mHandle = handle;
         mDisplayName = displayName;
         mEndpoint = endpoint;
         mState = state;
+        mCallDirection = callDirection;
     }
 
     /**
@@ -96,7 +107,16 @@
                     String displayName = source.readString();
                     Uri endpoint = source.readParcelable(classLoader);
                     int state = source.readInt();
-                    return new ConferenceParticipant(handle, displayName, endpoint, state);
+                    long connectTime = source.readLong();
+                    long elapsedRealTime = source.readLong();
+                    int callDirection = source.readInt();
+                    ConferenceParticipant participant =
+                            new ConferenceParticipant(handle, displayName, endpoint, state,
+                                    callDirection);
+                    participant.setConnectTime(connectTime);
+                    participant.setConnectElapsedTime(elapsedRealTime);
+                    participant.setCallDirection(callDirection);
+                    return participant;
                 }
 
                 @Override
@@ -170,6 +190,9 @@
         dest.writeString(mDisplayName);
         dest.writeParcelable(mEndpoint, 0);
         dest.writeInt(mState);
+        dest.writeLong(mConnectTime);
+        dest.writeLong(mConnectElapsedTime);
+        dest.writeInt(mCallDirection);
     }
 
     /**
@@ -192,6 +215,8 @@
         sb.append(getConnectTime());
         sb.append(" ConnectElapsedTime: ");
         sb.append(getConnectElapsedTime());
+        sb.append(" Direction: ");
+        sb.append(getCallDirection() == Call.Details.DIRECTION_INCOMING ? "Incoming" : "Outgoing");
         sb.append("]");
         return sb.toString();
     }
@@ -239,7 +264,7 @@
     }
 
     /**
-     * The connect elpased time of the participant to the conference.
+     * The connect elapsed time of the participant to the conference.
      */
     public long getConnectElapsedTime() {
         return mConnectElapsedTime;
@@ -248,4 +273,76 @@
     public void setConnectElapsedTime(long connectElapsedTime) {
         mConnectElapsedTime = connectElapsedTime;
     }
+
+    /**
+     * @return The direction of the call (incoming/outgoing).
+     */
+    public @Call.Details.CallDirection int getCallDirection() {
+        return mCallDirection;
+    }
+
+    /**
+     * Sets the direction of the call.
+     * @param callDirection Whether the call is incoming or outgoing.
+     */
+    public void setCallDirection(@Call.Details.CallDirection int callDirection) {
+        mCallDirection = callDirection;
+    }
+
+    /**
+     * Attempts to build a tel: style URI from a conference participant.
+     * Conference event package data contains SIP URIs, so we try to extract the phone number and
+     * format into a typical tel: style URI.
+     *
+     * @param address The conference participant's address.
+     * @param countryIso The country ISO of the current subscription; used when formatting the
+     *                   participant phone number to E.164 format.
+     * @return The participant's address URI.
+     * @hide
+     */
+    @VisibleForTesting
+    public static Uri getParticipantAddress(Uri address, String countryIso) {
+        if (address == null) {
+            return address;
+        }
+        // Even if address is already in tel: format, still parse it and rebuild.
+        // This is to recognize tel URIs such as:
+        // tel:6505551212;phone-context=ims.mnc012.mcc034.3gppnetwork.org
+
+        // Conference event package participants are identified using SIP URIs (see RFC3261).
+        // A valid SIP uri has the format: sip:user:password@host:port;uri-parameters?headers
+        // Per RFC3261, the "user" can be a telephone number.
+        // For example: sip:1650555121;phone-context=blah.com@host.com
+        // In this case, the phone number is in the user field of the URI, and the parameters can be
+        // ignored.
+        //
+        // A SIP URI can also specify a phone number in a format similar to:
+        // sip:+1-212-555-1212@something.com;user=phone
+        // In this case, the phone number is again in user field and the parameters can be ignored.
+        // We can get the user field in these instances by splitting the string on the @, ;, or :
+        // and looking at the first found item.
+        String number = address.getSchemeSpecificPart();
+        if (TextUtils.isEmpty(number)) {
+            return address;
+        }
+
+        String numberParts[] = number.split("[@;:]");
+        if (numberParts.length == 0) {
+            return address;
+        }
+        number = numberParts[0];
+
+        // Attempt to format the number in E.164 format and use that as part of the TEL URI.
+        // RFC2806 recommends to format telephone numbers using E.164 since it is independent of
+        // how the dialing of said numbers takes place.
+        // If conversion to E.164 fails, the returned value is null.  In that case, fallback to the
+        // number which was in the CEP data.
+        String formattedNumber = null;
+        if (!TextUtils.isEmpty(countryIso)) {
+            formattedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
+        }
+
+        return Uri.fromParts(PhoneAccount.SCHEME_TEL,
+                formattedNumber != null ? formattedNumber : number, null);
+    }
 }
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 28e6596..0983eea 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -424,8 +424,16 @@
      */
     public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1 << 10;
 
+    /**
+     * Set by the framework to indicate that a Conference or Connection is hosted by a device other
+     * than the current one.  Used in scenarios where the conference originator is the remote device
+     * and the current device is a participant of that conference.
+     * @hide
+     */
+    public static final int PROPERTY_REMOTELY_HOSTED = 1 << 11;
+
     //**********************************************************************************************
-    // Next PROPERTY value: 1<<10
+    // Next PROPERTY value: 1<<12
     //**********************************************************************************************
 
     /**
@@ -850,6 +858,10 @@
             builder.append(isLong ? " PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL" : " ecall");
         }
 
+        if (can(properties, PROPERTY_REMOTELY_HOSTED)) {
+            builder.append(isLong ? " PROPERTY_REMOTELY_HOSTED" : " remote_hst");
+        }
+
         builder.append("]");
         return builder.toString();
     }
@@ -1781,6 +1793,11 @@
     private ConnectionService mConnectionService;
     private Bundle mExtras;
     private final Object mExtrasLock = new Object();
+    /**
+     * The direction of the connection; used where an existing connection is created and we need to
+     * communicate to Telecom whether its incoming or outgoing.
+     */
+    private @Call.Details.CallDirection int mCallDirection = Call.Details.DIRECTION_UNKNOWN;
 
     /**
      * Tracks the key set for the extras bundle provided on the last invocation of
@@ -3345,4 +3362,21 @@
             l.onConnectionEvent(this, event, extras);
         }
     }
+
+    /**
+     * @return The direction of the call.
+     * @hide
+     */
+    public final @Call.Details.CallDirection int getCallDirection() {
+        return mCallDirection;
+    }
+
+    /**
+     * Sets the direction of this connection.
+     * @param callDirection The direction of this connection.
+     * @hide
+     */
+    public void setCallDirection(@Call.Details.CallDirection int callDirection) {
+        mCallDirection = callDirection;
+    }
 }
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index c66e92b..3548810 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -2056,7 +2056,11 @@
                     conference.getConnectTimeMillis(),
                     conference.getConnectionStartElapsedRealTime(),
                     conference.getStatusHints(),
-                    conference.getExtras());
+                    conference.getExtras(),
+                    conference.getAddress(),
+                    conference.getAddressPresentation(),
+                    conference.getCallerDisplayName(),
+                    conference.getCallerDisplayNamePresentation());
 
             mAdapter.addConferenceCall(id, parcelableConference);
             mAdapter.setVideoProvider(id, conference.getVideoProvider());
@@ -2140,7 +2144,8 @@
                     connection.getDisconnectCause(),
                     emptyList,
                     connection.getExtras(),
-                    conferenceId);
+                    conferenceId,
+                    connection.getCallDirection());
             mAdapter.addExistingConnection(id, parcelableConnection);
         }
     }
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index 3acd83a..04e930c 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -325,6 +325,15 @@
             } catch (RemoteException e) {
                 Log.e(this, e, "Exception trying to query for remote CSs");
             }
+        } else {
+            try {
+                // This is not an error condition, so just pass back an empty list.
+                // This happens when querying from a remote connection service, not the connection
+                // manager itself.
+                callback.onResult(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
+            } catch (RemoteException e) {
+                Log.e(this, e, "Exception trying to query for remote CSs");
+            }
         }
     }
 
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index b281589..60b2172 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -477,7 +477,7 @@
             SomeArgs args = SomeArgs.obtain();
             args.arg1 = callback;
             args.arg2 = callingPackage;
-            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
+            mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, args).sendToTarget();
         }
 
         @Override
diff --git a/telecomm/java/android/telecom/ParcelableConference.java b/telecomm/java/android/telecom/ParcelableConference.java
index 636e4b2..ede0594 100644
--- a/telecomm/java/android/telecom/ParcelableConference.java
+++ b/telecomm/java/android/telecom/ParcelableConference.java
@@ -16,6 +16,7 @@
 
 package android.telecom;
 
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -42,6 +43,10 @@
     private StatusHints mStatusHints;
     private Bundle mExtras;
     private long mConnectElapsedTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
+    private final Uri mAddress;
+    private final int mAddressPresentation;
+    private final String mCallerDisplayName;
+    private final int mCallerDisplayNamePresentation;
 
     public ParcelableConference(
             PhoneAccountHandle phoneAccount,
@@ -54,7 +59,11 @@
             long connectTimeMillis,
             long connectElapsedTimeMillis,
             StatusHints statusHints,
-            Bundle extras) {
+            Bundle extras,
+            Uri address,
+            int addressPresentation,
+            String callerDisplayName,
+            int callerDisplayNamePresentation) {
         mPhoneAccount = phoneAccount;
         mState = state;
         mConnectionCapabilities = connectionCapabilities;
@@ -66,6 +75,10 @@
         mStatusHints = statusHints;
         mExtras = extras;
         mConnectElapsedTimeMillis = connectElapsedTimeMillis;
+        mAddress = address;
+        mAddressPresentation = addressPresentation;
+        mCallerDisplayName = callerDisplayName;
+        mCallerDisplayNamePresentation = callerDisplayNamePresentation;
     }
 
     @Override
@@ -134,6 +147,14 @@
         return mExtras;
     }
 
+    public Uri getHandle() {
+        return mAddress;
+    }
+
+    public int getHandlePresentation() {
+        return mAddressPresentation;
+    }
+
     public static final @android.annotation.NonNull Parcelable.Creator<ParcelableConference> CREATOR =
             new Parcelable.Creator<ParcelableConference> () {
         @Override
@@ -152,10 +173,15 @@
             Bundle extras = source.readBundle(classLoader);
             int properties = source.readInt();
             long connectElapsedTimeMillis = source.readLong();
+            Uri address = source.readParcelable(classLoader);
+            int addressPresentation = source.readInt();
+            String callerDisplayName = source.readString();
+            int callerDisplayNamePresentation = source.readInt();
 
             return new ParcelableConference(phoneAccount, state, capabilities, properties,
                     connectionIds, videoCallProvider, videoState, connectTimeMillis,
-                    connectElapsedTimeMillis, statusHints, extras);
+                    connectElapsedTimeMillis, statusHints, extras, address, addressPresentation,
+                    callerDisplayName, callerDisplayNamePresentation);
         }
 
         @Override
@@ -185,5 +211,9 @@
         destination.writeBundle(mExtras);
         destination.writeInt(mConnectionProperties);
         destination.writeLong(mConnectElapsedTimeMillis);
+        destination.writeParcelable(mAddress, 0);
+        destination.writeInt(mAddressPresentation);
+        destination.writeString(mCallerDisplayName);
+        destination.writeInt(mCallerDisplayNamePresentation);
     }
 }
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index dab1c6e..4734af6 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -53,6 +53,7 @@
     private final List<String> mConferenceableConnectionIds;
     private final Bundle mExtras;
     private String mParentCallId;
+    private @Call.Details.CallDirection int mCallDirection;
 
     /** @hide */
     public ParcelableConnection(
@@ -75,13 +76,15 @@
             DisconnectCause disconnectCause,
             List<String> conferenceableConnectionIds,
             Bundle extras,
-            String parentCallId) {
+            String parentCallId,
+            @Call.Details.CallDirection int callDirection) {
         this(phoneAccount, state, capabilities, properties, supportedAudioRoutes, address,
                 addressPresentation, callerDisplayName, callerDisplayNamePresentation,
                 videoProvider, videoState, ringbackRequested, isVoipAudioMode, connectTimeMillis,
                 connectElapsedTimeMillis, statusHints, disconnectCause, conferenceableConnectionIds,
                 extras);
         mParentCallId = parentCallId;
+        mCallDirection = callDirection;
     }
 
     /** @hide */
@@ -125,6 +128,7 @@
         mConferenceableConnectionIds = conferenceableConnectionIds;
         mExtras = extras;
         mParentCallId = null;
+        mCallDirection = Call.Details.DIRECTION_UNKNOWN;
     }
 
     public PhoneAccountHandle getPhoneAccount() {
@@ -219,6 +223,10 @@
         return mParentCallId;
     }
 
+    public @Call.Details.CallDirection int getCallDirection() {
+        return mCallDirection;
+    }
+
     @Override
     public String toString() {
         return new StringBuilder()
@@ -234,6 +242,8 @@
                 .append(mExtras)
                 .append(", parent:")
                 .append(mParentCallId)
+                .append(", callDirection:")
+                .append(mCallDirection)
                 .toString();
     }
 
@@ -265,6 +275,7 @@
             int supportedAudioRoutes = source.readInt();
             String parentCallId = source.readString();
             long connectElapsedTimeMillis = source.readLong();
+            int callDirection = source.readInt();
 
             return new ParcelableConnection(
                     phoneAccount,
@@ -286,7 +297,8 @@
                     disconnectCause,
                     conferenceableConnectionIds,
                     extras,
-                    parentCallId);
+                    parentCallId,
+                    callDirection);
         }
 
         @Override
@@ -325,5 +337,6 @@
         destination.writeInt(mSupportedAudioRoutes);
         destination.writeString(mParentCallId);
         destination.writeLong(mConnectElapsedTimeMillis);
+        destination.writeInt(mCallDirection);
     }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 50c25d0..91bea5f 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -672,6 +672,22 @@
     public static final String KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING
             = "carrier_data_service_wlan_package_override_string";
 
+    /**
+     * Override the device's configuration for the cellular data service class to use
+     * for this SIM card.
+     * @hide
+     */
+    public static final String KEY_CARRIER_DATA_SERVICE_WWAN_CLASS_OVERRIDE_STRING =
+            "carrier_data_service_wwan_class_override_string";
+
+    /**
+     * Override the device's configuration for the IWLAN data service class to use
+     * for this SIM card.
+     * @hide
+     */
+    public static final String KEY_CARRIER_DATA_SERVICE_WLAN_CLASS_OVERRIDE_STRING =
+            "carrier_data_service_wlan_class_override_string";
+
     /** Flag specifying whether VoLTE TTY is supported. */
     public static final String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
             = "carrier_volte_tty_supported_bool";
@@ -836,6 +852,19 @@
             "carrier_metered_roaming_apn_types_strings";
 
     /**
+     * APN types that are not allowed on cellular
+     * @hide
+     */
+    public static final String KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY =
+            "carrier_wwan_disallowed_apn_types_string_array";
+
+    /**
+     * APN types that are not allowed on IWLAN
+     * @hide
+     */
+    public static final String KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY =
+            "carrier_wlan_disallowed_apn_types_string_array";
+    /**
      * CDMA carrier ERI (Enhanced Roaming Indicator) file name
      * @hide
      */
@@ -1021,6 +1050,15 @@
             "support_manage_ims_conference_call_bool";
 
     /**
+     * Determines whether the IMS conference merge process supports and returns its participants
+     * data. When {@code true}, on merge complete, conference call would have a list of its
+     * participants returned in XML format, {@code false otherwise}.
+     * @hide
+     */
+    public static final String KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL =
+            "support_ims_conference_event_package_bool";
+
+    /**
      * Determines whether High Definition audio property is displayed in the dialer UI.
      * If {@code false}, remove the HD audio property from the connection so that HD audio related
      * UI is not displayed. If {@code true}, keep HD audio property as it is configured.
@@ -1132,6 +1170,7 @@
      * <li>  8: Wi-Fi</li>
      * <li>  9: WiFi Calling</li>
      * <li> 10: VoWifi</li>
+     * <li> 11: %s WiFi Calling</li>
      * @hide
      */
     public static final String KEY_WFC_SPN_FORMAT_IDX_INT = "wfc_spn_format_idx_int";
@@ -2382,6 +2421,14 @@
             "carrier_network_service_wlan_package_override_string";
 
     /**
+     * Decides when clients try to bind to iwlan network service, which class name will
+     * the binding intent go to.
+     * @hide
+     */
+    public static final String KEY_CARRIER_NETWORK_SERVICE_WLAN_CLASS_OVERRIDE_STRING =
+            "carrier_network_service_wlan_class_override_string";
+
+    /**
      * Decides when clients try to bind to wwan (cellular) network service, which package name will
      * the binding intent go to.
      * @hide
@@ -2390,12 +2437,28 @@
             "carrier_network_service_wwan_package_override_string";
 
     /**
+     * Decides when clients try to bind to wwan (cellular) network service, which class name will
+     * the binding intent go to.
+     * @hide
+     */
+    public static final String KEY_CARRIER_NETWORK_SERVICE_WWAN_CLASS_OVERRIDE_STRING =
+            "carrier_network_service_wwan_class_override_string";
+
+    /**
      * The package name of qualified networks service that telephony binds to.
      *
      * @hide
      */
     public static final String KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING =
             "carrier_qualified_networks_service_package_override_string";
+
+    /**
+     * The class name of qualified networks service that telephony binds to.
+     *
+     * @hide
+     */
+    public static final String KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_CLASS_OVERRIDE_STRING =
+            "carrier_qualified_networks_service_class_override_string";
     /**
      * A list of 4 LTE RSCP thresholds above which a signal level is considered POOR,
      * MODERATE, GOOD, or EXCELLENT, to be used in SignalStrength reporting.
@@ -2684,6 +2747,30 @@
         public static final String KEY_PREFIX = "gps.";
 
         /**
+         * Location information during (and after) an emergency call is only provided over control
+         * plane signaling from the network.
+         * @hide
+         */
+        public static final int SUPL_EMERGENCY_MODE_TYPE_CP_ONLY = 0;
+
+        /**
+         * Location information during (and after) an emergency call is provided over the data
+         * plane and serviced by the framework GNSS service, but if it fails, the carrier also
+         * supports control plane backup signaling.
+         * @hide
+         */
+        public static final int SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK = 1;
+
+        /**
+         * Location information during (and after) an emergency call is provided over the data plane
+         * and serviced by the framework GNSS service only. There is no backup signalling over the
+         * control plane if it fails.
+         * @hide
+         */
+        public static final int SUPL_EMERGENCY_MODE_TYPE_DP_ONLY = 2;
+
+
+        /**
          * Determine whether current lpp_mode used for E-911 needs to be kept persistently.
          * {@code false} - not keeping the lpp_mode means using default configuration of gps.conf
          *                 when sim is not presented.
@@ -2773,6 +2860,23 @@
          */
         public static final String KEY_NFW_PROXY_APPS_STRING = KEY_PREFIX + "nfw_proxy_apps";
 
+        /**
+         * Determines whether or not SUPL ES mode supports a control-plane mechanism to get a user's
+         * location in the event that data plane SUPL fails or is otherwise unavailable.
+         * <p>
+         * An integer value determines the support type of this carrier. If this carrier only
+         * supports data plane SUPL ES, then the value will be
+         * {@link #SUPL_EMERGENCY_MODE_TYPE_DP_ONLY}. If the carrier supports control plane fallback
+         * for emergency SUPL, the value will be {@link #SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK}.
+         * If the carrier does not support data plane SUPL using the framework, the value will be
+         * {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
+         * <p>
+         * The default value for this configuration is {@link #SUPL_EMERGENCY_MODE_TYPE_CP_ONLY}.
+         * @hide
+         */
+        public static final String KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT = KEY_PREFIX
+                + "es_supl_control_plane_support_int";
+
         private static PersistableBundle getDefaults() {
             PersistableBundle defaults = new PersistableBundle();
             defaults.putBoolean(KEY_PERSIST_LPP_MODE_BOOL, true);
@@ -2787,6 +2891,8 @@
             defaults.putString(KEY_GPS_LOCK_STRING, "3");
             defaults.putString(KEY_ES_EXTENSION_SEC_STRING, "0");
             defaults.putString(KEY_NFW_PROXY_APPS_STRING, "");
+            defaults.putInt(KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
+                    SUPL_EMERGENCY_MODE_TYPE_CP_ONLY);
             return defaults;
         }
     }
@@ -3079,6 +3185,10 @@
                 new String[]{"default", "mms", "dun", "supl"});
         sDefaults.putStringArray(KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
                 new String[]{"default", "mms", "dun", "supl"});
+        sDefaults.putStringArray(KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
+                new String[]{""});
+        sDefaults.putStringArray(KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
+                new String[]{""});
         sDefaults.putIntArray(KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY,
                 new int[]{
                     4, /* IS95A */
@@ -3103,6 +3213,7 @@
         sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_CALL_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_MANAGE_IMS_CONFERENCE_CALL_BOOL, true);
+        sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_VIDEO_CONFERENCE_CALL_BOOL, false);
         sDefaults.putBoolean(KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL, false);
         sDefaults.putInt(KEY_IMS_CONFERENCE_SIZE_LIMIT_INT, 5);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 5d39a2c..2651346 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1997,4 +1997,18 @@
     public void setIwlanPreferred(boolean isIwlanPreferred) {
         mIsIwlanPreferred = isIwlanPreferred;
     }
+
+    /**
+     * @return {@code true} if any data network is preferred on IWLAN.
+     *
+     * Note only when this value is true, {@link #getDataNetworkType()} will return
+     * {@link TelephonyManager#NETWORK_TYPE_IWLAN} when AP-assisted mode device camps on both
+     * cellular and IWLAN. This value does not affect legacy mode devices as the data network
+     * type is directly reported by the modem.
+     *
+     * @hide
+     */
+    public boolean isIwlanPreferred() {
+        return mIsIwlanPreferred;
+    }
 }
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 6860235..b44e4f1 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -1975,9 +1975,11 @@
      */
     public static int getDefaultSmsSubscriptionId() {
         try {
-            return getISmsServiceOrThrow().getPreferredSmsSubscription();
+            return getISmsService().getPreferredSmsSubscription();
         } catch (RemoteException e) {
             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        } catch (NullPointerException e) {
+            return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         }
     }
 
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 7d4bcb7..b705d71 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -843,20 +843,16 @@
     }
 
     /**
-     * GSM:
-     * For an SMS-STATUS-REPORT message, this returns the status field from
-     * the status report.  This field indicates the status of a previously
-     * submitted SMS, if requested.  See TS 23.040, 9.2.3.15 TP-Status for a
-     * description of values.
-     * CDMA:
-     * For not interfering with status codes from GSM, the value is
-     * shifted to the bits 31-16.
-     * The value is composed of an error class (bits 25-24) and a status code (bits 23-16).
-     * Possible codes are described in C.S0015-B, v2.0, 4.5.21.
+     * GSM: For an SMS-STATUS-REPORT message, this returns the status field from the status report.
+     * This field indicates the status of a previously submitted SMS, if requested.
+     * See TS 23.040, 9.2.3.15 TP-Status for a description of values.
+     * CDMA: For not interfering with status codes from GSM, the value is shifted to the bits 31-16.
+     * The value is composed of an error class (bits 25-24) and a status code (bits 23-16). Possible
+     * codes are described in C.S0015-B, v2.0, 4.5.21.
      *
-     * @return 0 indicates the previously sent message was received.
-     *         See TS 23.040, 9.9.2.3.15 and C.S0015-B, v2.0, 4.5.21
-     *         for a description of other possible values.
+     * @return 0 for GSM or 2 shifted left by 16 for CDMA indicates the previously sent message was
+     *         received. See TS 23.040, 9.2.3.15 and C.S0015-B, v2.0, 4.5.21 for a description of
+     *         other possible values.
      */
     public int getStatus() {
         return mWrappedSmsMessage.getStatus();
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 1e6cd47..a8491d3 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -732,19 +732,19 @@
     public String toString() {
         String iccIdToPrint = givePrintableIccid(mIccId);
         String cardStringToPrint = givePrintableIccid(mCardString);
-        return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
+        return "{id=" + mId + " iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
                 + " carrierId=" + mCarrierId + " displayName=" + mDisplayName
                 + " carrierName=" + mCarrierName + " nameSource=" + mNameSource
                 + " iconTint=" + mIconTint + " mNumber=" + Rlog.pii(Build.IS_DEBUGGABLE, mNumber)
-                + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
-                + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
-                + " accessRules " + Arrays.toString(mAccessRules)
+                + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc=" + mMcc
+                + " mnc=" + mMnc + " mCountryIso=" + mCountryIso + " isEmbedded=" + mIsEmbedded
+                + " accessRules=" + Arrays.toString(mAccessRules)
                 + " cardString=" + cardStringToPrint + " cardId=" + mCardId
-                + " isOpportunistic " + mIsOpportunistic + " mGroupUUID=" + mGroupUUID
+                + " isOpportunistic=" + mIsOpportunistic + " mGroupUUID=" + mGroupUUID
                 + " mIsGroupDisabled=" + mIsGroupDisabled
                 + " profileClass=" + mProfileClass
-                + " ehplmns = " + Arrays.toString(mEhplmns)
-                + " hplmns = " + Arrays.toString(mHplmns)
+                + " ehplmns=" + Arrays.toString(mEhplmns)
+                + " hplmns=" + Arrays.toString(mHplmns)
                 + " subscriptionType=" + mSubscriptionType
                 + " mGroupOwner=" + mGroupOwner + "}";
     }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index b13a44f..2822fcc 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -302,11 +302,27 @@
      * subscription.
      *
      * Default value is 0.
+     *
+     * @deprecated Replaced by {@link #DATA_ENABLED_OVERRIDE_RULES}
+     * @hide
      */
-    /** @hide */
+    @Deprecated
     public static final String WHITE_LISTED_APN_DATA = "white_listed_apn_data";
 
     /**
+     * TelephonyProvider column name data_enabled_override_rules.
+     * It's a list of rules for overriding data enabled settings. The syntax is
+     * For example, "mms=nonDefault" indicates enabling data for mms in non-default subscription.
+     * "default=nonDefault&inVoiceCall" indicates enabling data for internet in non-default
+     * subscription and while is in voice call.
+     *
+     * Default value is empty string.
+     *
+     * @hide
+     */
+    public static final String DATA_ENABLED_OVERRIDE_RULES = "data_enabled_override_rules";
+
+    /**
      * This constant is to designate a subscription as a Local-SIM Subscription.
      * <p> A Local-SIM can be a physical SIM inserted into a sim-slot in the device, or eSIM on the
      * device.
@@ -2100,29 +2116,36 @@
     }
 
     /**
+     * TODO(b/137102918) Make this static, tests use this as an instance method currently.
+     *
      * @return the list of subId's that are active,
      *         is never null but the length maybe 0.
      * @hide
      */
     @UnsupportedAppUsage
     public @NonNull int[] getActiveSubscriptionIdList() {
-        int[] subId = null;
+        return getActiveSubscriptionIdList(/* visibleOnly */ true);
+    }
 
+    /**
+     * TODO(b/137102918) Make this static, tests use this as an instance method currently.
+     *
+     * @return a non-null list of subId's that are active.
+     *
+     * @hide
+     */
+    public @NonNull int[] getActiveSubscriptionIdList(boolean visibleOnly) {
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                subId = iSub.getActiveSubIdList(/*visibleOnly*/true);
+                int[] subId = iSub.getActiveSubIdList(visibleOnly);
+                if (subId != null) return subId;
             }
         } catch (RemoteException ex) {
             // ignore it
         }
 
-        if (subId == null) {
-            subId = new int[0];
-        }
-
-        return subId;
-
+        return new int[0];
     }
 
     /**
@@ -2968,10 +2991,10 @@
      * @param info the subscriptionInfo to check against.
      * @return true if this subscription should be visible to the API caller.
      *
+     * @hide
      */
-    private boolean isSubscriptionVisible(SubscriptionInfo info) {
+    public boolean isSubscriptionVisible(SubscriptionInfo info) {
         if (info == null) return false;
-
         // If subscription is NOT grouped opportunistic subscription, it's visible.
         if (info.getGroupUuid() == null || !info.isOpportunistic()) return true;
 
@@ -3062,18 +3085,10 @@
     }
 
     /**
-     * Returns whether the subscription is enabled or not. This is different from activated
-     * or deactivated for two aspects. 1) For when user disables a physical subscription, we
-     * actually disable the modem because we can't switch off the subscription. 2) For eSIM,
-     * user may enable one subscription but the system may activate another temporarily. In this
-     * case, user enabled one is different from current active one.
-
-     * @param subscriptionId The subscription it asks about.
-     * @return whether it's enabled or not. {@code true} if user set this subscription enabled
-     * earlier, or user never set subscription enable / disable on this slot explicitly, and
-     * this subscription is currently active. Otherwise, it returns {@code false}.
-     *
+     * DO NOT USE.
+     * This API is designed for features that are not finished at this point. Do not call this API.
      * @hide
+     * TODO b/135547512: further clean up
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@@ -3091,14 +3106,10 @@
     }
 
     /**
-     * Get which subscription is enabled on this slot. See {@link #isSubscriptionEnabled(int)}
-     * for more details.
-     *
-     * @param slotIndex which slot it asks about.
-     * @return which subscription is enabled on this slot. If there's no enabled subscription
-     *         in this slot, it will return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
-     *
+     * DO NOT USE.
+     * This API is designed for features that are not finished at this point. Do not call this API.
      * @hide
+     * TODO b/135547512: further clean up
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@@ -3167,4 +3178,24 @@
 
         return result;
     }
+
+    /**
+     * Get active data subscription id.
+     * See {@link PhoneStateListener#onActiveDataSubscriptionIdChanged(int)} for the details.
+     *
+     * @return Active data subscription id
+     *
+     * //TODO: Refactor this API in b/134702460
+     * @hide
+     */
+    public static int getActiveDataSubscriptionId() {
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                return iSub.getActiveDataSubscriptionId();
+            }
+        } catch (RemoteException ex) {
+        }
+        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d6500f4..fd47561 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -105,6 +105,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.UUID;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 import java.util.regex.Matcher;
@@ -1497,6 +1498,48 @@
      */
     public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4;
 
+    /**
+     * Integer intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED}
+     * to indicate if the SIM combination in DSDS has limitation or compatible issue.
+     * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios.
+     *
+     * @hide
+     */
+    public static final String EXTRA_SIM_COMBINATION_WARNING_TYPE =
+            "android.telephony.extra.SIM_COMBINATION_WARNING_TYPE";
+
+    /** @hide */
+    @IntDef({
+            EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE,
+            EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SimCombinationWarningType{}
+
+    /**
+     * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
+     * to indicate there's no SIM combination warning.
+     * @hide
+     */
+    public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE = 0;
+
+    /**
+     * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
+     * to indicate two active SIMs are both CDMA hence there might be functional limitation.
+     * @hide
+     */
+    public static final int EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA = 1;
+
+    /**
+     * String intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED}
+     * to indicate what's the name of SIM combination it has limitation or compatible issue.
+     * e.g. two CDMA SIMs may disrupt each other's voice call in certain scenarios, and the
+     * name will be "operator1 & operator2".
+     *
+     * @hide
+     */
+    public static final String EXTRA_SIM_COMBINATION_NAMES =
+            "android.telephony.extra.SIM_COMBINATION_NAMES";
     //
     //
     // Device Info
@@ -1562,7 +1605,7 @@
      *     higher, then a SecurityException is thrown.</li>
      * </ul>
      *
-     * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
+     * @deprecated Use {@link #getImei} which returns IMEI for GSM or {@link #getMeid} which returns
      * MEID for CDMA.
      */
     @Deprecated
@@ -1605,7 +1648,7 @@
      *
      * @param slotIndex of which deviceID is returned
      *
-     * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
+     * @deprecated Use {@link #getImei} which returns IMEI for GSM or {@link #getMeid} which returns
      * MEID for CDMA.
      */
     @Deprecated
@@ -1629,23 +1672,8 @@
      * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
      * available.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
-     * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
-     * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
-     * managed profile on the device; for more details see <a
-     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
-     * access is deprecated and will be removed in a future release.
-     *
-     * <p>If the calling app does not meet one of these requirements then this method will behave
-     * as follows:
-     *
-     * <ul>
-     *     <li>If the calling app's target SDK is API level 28 or lower and the app has the
-     *     READ_PHONE_STATE permission then null is returned.</li>
-     *     <li>If the calling app's target SDK is API level 28 or lower and the app does not have
-     *     the READ_PHONE_STATE permission, or if the calling app is targeting API level 29 or
-     *     higher, then a SecurityException is thrown.</li>
-     * </ul>
+     * See {@link #getImei(int)} for details on the required permissions and behavior
+     * when the caller does not hold sufficient permissions.
      */
     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
@@ -1657,12 +1685,17 @@
      * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
      * available.
      *
-     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
-     * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
-     * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
-     * managed profile on the device; for more details see <a
-     * href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
-     * access is deprecated and will be removed in a future release.
+     * <p>This API requires one of the following:
+     * <ul>
+     *     <li>The caller holds the READ_PRIVILEGED_PHONE_STATE permission.</li>
+     *     <li>If the caller is the device or profile owner, the caller holds the
+     *     {@link Manifest.permission#READ_PHONE_STATE} permission.</li>
+     *     <li>The caller has carrier privileges (see {@link #hasCarrierPrivileges()}.</li>
+     *     <li>The caller is the default SMS app for the device.</li>
+     * </ul>
+     * <p>The profile owner is an app that owns a managed profile on the device; for more details
+     * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
+     * Access by profile owners is deprecated and will be removed in a future release.
      *
      * <p>If the calling app does not meet one of these requirements then this method will behave
      * as follows:
@@ -2520,7 +2553,7 @@
     @Deprecated
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public @NetworkType int getNetworkType() {
-        return getNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
+        return getNetworkType(getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
     }
 
     /**
@@ -2603,7 +2636,7 @@
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public @NetworkType int getDataNetworkType() {
-        return getDataNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
+        return getDataNetworkType(getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
     }
 
     /**
@@ -3950,9 +3983,14 @@
      * The returned set of subscriber IDs will include the subscriber ID corresponding to this
      * TelephonyManager's subId.
      *
+     * This is deprecated and {@link #getMergedSubscriberIdsFromGroup()} should be used for data
+     * usage merging purpose.
+     * TODO: remove this API.
+     *
      * @hide
      */
     @UnsupportedAppUsage
+    @Deprecated
     public @Nullable String[] getMergedSubscriberIds() {
         try {
             ITelephony telephony = getITelephony();
@@ -3965,6 +4003,28 @@
     }
 
     /**
+     * Return the set of subscriber IDs that should be considered "merged together" for data usage
+     * purposes. Unlike {@link #getMergedSubscriberIds()} this API merge subscriberIds based on
+     * subscription grouping: subscriberId of those in the same group will all be returned.
+     *
+     * <p>Requires the calling app to have READ_PRIVILEGED_PHONE_STATE permission.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public @Nullable String[] getMergedSubscriberIdsFromGroup() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getMergedSubscriberIdsFromGroup(getSubId(), getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return null;
+    }
+
+    /**
      * Returns the MSISDN string.
      * for a GSM phone. Return null if it is unavailable.
      *
@@ -4868,7 +4928,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return DATA_ACTIVITY_NONE;
-            return telephony.getDataActivity();
+            return telephony.getDataActivityForSubId(
+                    getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return DATA_ACTIVITY_NONE;
@@ -4916,7 +4977,8 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return DATA_DISCONNECTED;
-            return telephony.getDataState();
+            return telephony.getDataStateForSubId(
+                    getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
         } catch (RemoteException ex) {
             // the phone process is restarting.
             return DATA_DISCONNECTED;
@@ -7389,7 +7451,7 @@
      * @hide
      */
     public boolean getTetherApnRequired() {
-        return getTetherApnRequired(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
+        return getTetherApnRequired(getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
     }
 
     /**
@@ -8172,7 +8234,7 @@
             ITelephony telephony = getITelephony();
             if (telephony != null)
                 return telephony.isDataConnectivityPossible(getSubId(SubscriptionManager
-                        .getDefaultDataSubscriptionId()));
+                        .getActiveDataSubscriptionId()));
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isDataAllowed", e);
         }
@@ -9285,6 +9347,10 @@
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e);
+        } catch (NullPointerException e) {
+            AnomalyReporter.reportAnomaly(
+                    UUID.fromString("a3ab0b9d-f2aa-4baf-911d-7096c0d4645a"),
+                    "getServiceStateForSubscriber " + subId + " NPE");
         }
         return null;
     }
@@ -10797,7 +10863,6 @@
      * @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.
-     *
      */
     public void setPreferredOpportunisticDataSubscription(int subId, boolean needValidation,
             @Nullable @CallbackExecutor Executor executor, @Nullable Consumer<Integer> callback) {
@@ -10805,6 +10870,12 @@
         try {
             IOns iOpportunisticNetworkService = getIOns();
             if (iOpportunisticNetworkService == null) {
+                if (executor == null || callback == null) {
+                    return;
+                }
+                Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
+                    callback.accept(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
+                }));
                 return;
             }
             ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
@@ -10883,9 +10954,19 @@
         try {
             IOns iOpportunisticNetworkService = getIOns();
             if (iOpportunisticNetworkService == null || availableNetworks == null) {
-                Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
-                    callback.accept(UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS);
-                }));
+                if (executor == null || callback == null) {
+                    return;
+                }
+                if (iOpportunisticNetworkService == null) {
+                    /* Todo<b/130595455> passing unknown due to lack of good error codes */
+                    Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
+                        callback.accept(UPDATE_AVAILABLE_NETWORKS_UNKNOWN_FAILURE);
+                    }));
+                } else {
+                    Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
+                        callback.accept(UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS);
+                    }));
+                }
                 return;
             }
             IUpdateAvailableNetworksCallback callbackStub =
@@ -11187,4 +11268,52 @@
         }
         return true;
     }
+
+    /**
+     * Set allowing mobile data during voice call.
+     *
+     * @param allow {@code true} if allowing using data during voice call, {@code false} if
+     * disallowed
+     *
+     * @return {@code false} if the setting is changed.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean setDataAllowedDuringVoiceCall(boolean allow) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.setDataAllowedDuringVoiceCall(getSubId(), allow);
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check whether data is allowed during voice call. Note this is for dual sim device that
+     * data might be disabled on non-default data subscription but explicitly turned on by settings.
+     *
+     * @return {@code true} if data is allowed during voice call.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isDataAllowedInVoiceCall() {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.isDataAllowedInVoiceCall(getSubId());
+            }
+        } catch (RemoteException ex) {
+            if (!isSystemProcess()) {
+                ex.rethrowAsRuntimeException();
+            }
+        }
+        return false;
+    }
 }
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index a78bae4..116c051 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1310,6 +1310,9 @@
      * @hide
      */
     public static String getApnTypeString(int apnType) {
+        if (apnType == TYPE_ALL) {
+            return "*";
+        }
         String apnTypeString = APN_TYPE_INT_MAP.get(apnType);
         return apnTypeString == null ? "Unknown" : apnTypeString;
     }
@@ -1414,6 +1417,28 @@
         return port == UNSPECIFIED_INT ? null : Integer.toString(port);
     }
 
+    /**
+     * Check if this APN setting can support the given network
+     *
+     * @param networkType The network type
+     * @return {@code true} if this APN setting can support the given network.
+     *
+     * @hide
+     */
+    public boolean canSupportNetworkType(@TelephonyManager.NetworkType int networkType) {
+        // Do a special checking for GSM. In reality, GSM is a voice only network type and can never
+        // be used for data. We allow it here because in some DSDS corner cases, on the non-DDS
+        // sub, modem reports data rat unknown. In that case if voice is GSM and this APN supports
+        // GPRS or EDGE, this APN setting should be selected.
+        if (networkType == TelephonyManager.NETWORK_TYPE_GSM
+                && (mNetworkTypeBitmask & (TelephonyManager.NETWORK_TYPE_BITMASK_GPRS
+                | TelephonyManager.NETWORK_TYPE_BITMASK_EDGE)) != 0) {
+            return true;
+        }
+
+        return ServiceState.bitmaskHasTech(mNetworkTypeBitmask, networkType);
+    }
+
     // Implement Parcelable.
     @Override
     /** @hide */
diff --git a/telephony/java/android/telephony/ims/RcsControllerCall.java b/telephony/java/android/telephony/ims/RcsControllerCall.java
index a2d68ad..ce03c3c 100644
--- a/telephony/java/android/telephony/ims/RcsControllerCall.java
+++ b/telephony/java/android/telephony/ims/RcsControllerCall.java
@@ -19,10 +19,11 @@
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.telephony.ims.aidl.IRcs;
+import android.telephony.ims.aidl.IRcsMessage;
 
 /**
- * A wrapper class around RPC calls that {@link RcsMessageStore} APIs to minimize boilerplate code.
+ * A wrapper class around RPC calls that {@link RcsMessageManager} APIs to minimize boilerplate
+ * code.
  *
  * @hide - not meant for public use
  */
@@ -34,13 +35,14 @@
     }
 
     <R> R call(RcsServiceCall<R> serviceCall) throws RcsMessageStoreException {
-        IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_RCS_SERVICE));
-        if (iRcs == null) {
+        IRcsMessage iRcsMessage = IRcsMessage.Stub.asInterface(ServiceManager.getService(
+                Context.TELEPHONY_RCS_MESSAGE_SERVICE));
+        if (iRcsMessage == null) {
             throw new RcsMessageStoreException("Could not connect to RCS storage service");
         }
 
         try {
-            return serviceCall.methodOnIRcs(iRcs, mContext.getOpPackageName());
+            return serviceCall.methodOnIRcs(iRcsMessage, mContext.getOpPackageName());
         } catch (RemoteException exception) {
             throw new RcsMessageStoreException(exception.getMessage());
         }
@@ -48,17 +50,17 @@
 
     void callWithNoReturn(RcsServiceCallWithNoReturn serviceCall)
             throws RcsMessageStoreException {
-        call((iRcs, callingPackage) -> {
-            serviceCall.methodOnIRcs(iRcs, callingPackage);
+        call((iRcsMessage, callingPackage) -> {
+            serviceCall.methodOnIRcs(iRcsMessage, callingPackage);
             return null;
         });
     }
 
     interface RcsServiceCall<R> {
-        R methodOnIRcs(IRcs iRcs, String callingPackage) throws RemoteException;
+        R methodOnIRcs(IRcsMessage iRcs, String callingPackage) throws RemoteException;
     }
 
     interface RcsServiceCallWithNoReturn {
-        void methodOnIRcs(IRcs iRcs, String callingPackage) throws RemoteException;
+        void methodOnIRcs(IRcsMessage iRcs, String callingPackage) throws RemoteException;
     }
 }
diff --git a/telephony/java/android/telephony/ims/RcsManager.java b/telephony/java/android/telephony/ims/RcsManager.java
deleted file mode 100644
index 0d6ca3c..0000000
--- a/telephony/java/android/telephony/ims/RcsManager.java
+++ /dev/null
@@ -1,43 +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.telephony.ims;
-
-import android.annotation.SystemService;
-import android.content.Context;
-
-/**
- * The manager class for RCS related utilities.
- *
- * @hide
- */
-@SystemService(Context.TELEPHONY_RCS_SERVICE)
-public class RcsManager {
-    private final RcsMessageStore mRcsMessageStore;
-
-    /**
-     * @hide
-     */
-    public RcsManager(Context context) {
-        mRcsMessageStore = new RcsMessageStore(context);
-    }
-
-    /**
-     * Returns an instance of {@link RcsMessageStore}
-     */
-    public RcsMessageStore getRcsMessageStore() {
-        return mRcsMessageStore;
-    }
-}
diff --git a/telephony/java/android/telephony/ims/RcsMessageManager.java b/telephony/java/android/telephony/ims/RcsMessageManager.java
new file mode 100644
index 0000000..a1c7c0f
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsMessageManager.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.ims;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemService;
+import android.annotation.WorkerThread;
+import android.content.Context;
+import android.net.Uri;
+
+import java.util.List;
+
+/**
+ * RcsMessageManager is the application interface to RcsProvider and provides access methods to
+ * RCS related database tables.
+ *
+ * @hide
+ */
+@SystemService(Context.TELEPHONY_RCS_MESSAGE_SERVICE)
+public class RcsMessageManager {
+    RcsControllerCall mRcsControllerCall;
+
+    /**
+     * Use {@link Context#getSystemService(String)} to get an instance of this service.
+     * @hide
+     */
+    public RcsMessageManager(Context context) {
+        mRcsControllerCall = new RcsControllerCall(context);
+    }
+
+    /**
+     * Returns the first chunk of existing {@link RcsThread}s in the common storage.
+     *
+     * @param queryParameters Parameters to specify to return a subset of all RcsThreads.
+     *                        Passing a value of null will return all threads.
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParams queryParameters)
+            throws RcsMessageStoreException {
+        return new RcsThreadQueryResult(mRcsControllerCall,
+                mRcsControllerCall.call(
+                        (iRcs, callingPackage) -> iRcs.getRcsThreads(queryParameters,
+                                callingPackage)));
+    }
+
+    /**
+     * Returns the next chunk of {@link RcsThread}s in the common storage.
+     *
+     * @param continuationToken A token to continue the query to get the next chunk. This is
+     *                          obtained through {@link RcsThreadQueryResult#getContinuationToken}.
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsThreadQueryResult getRcsThreads(@NonNull RcsQueryContinuationToken continuationToken)
+            throws RcsMessageStoreException {
+        return new RcsThreadQueryResult(mRcsControllerCall,
+                mRcsControllerCall.call(
+                        (iRcs, callingPackage) -> iRcs.getRcsThreadsWithToken(continuationToken,
+                                callingPackage)));
+    }
+
+    /**
+     * Returns the first chunk of existing {@link RcsParticipant}s in the common storage.
+     *
+     * @param queryParameters Parameters to specify to return a subset of all RcsParticipants.
+     *                        Passing a value of null will return all participants.
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsParticipantQueryResult getRcsParticipants(
+            @Nullable RcsParticipantQueryParams queryParameters)
+            throws RcsMessageStoreException {
+        return new RcsParticipantQueryResult(mRcsControllerCall,
+                mRcsControllerCall.call(
+                        (iRcs, callingPackage) -> iRcs.getParticipants(queryParameters,
+                                callingPackage)));
+    }
+
+    /**
+     * Returns the next chunk of {@link RcsParticipant}s in the common storage.
+     *
+     * @param continuationToken A token to continue the query to get the next chunk. This is
+     *                          obtained through
+     *                          {@link RcsParticipantQueryResult#getContinuationToken}
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsParticipantQueryResult getRcsParticipants(
+            @NonNull RcsQueryContinuationToken continuationToken)
+            throws RcsMessageStoreException {
+        return new RcsParticipantQueryResult(mRcsControllerCall,
+                mRcsControllerCall.call(
+                        (iRcs, callingPackage) -> iRcs.getParticipantsWithToken(continuationToken,
+                                callingPackage)));
+    }
+
+    /**
+     * Returns the first chunk of existing {@link RcsMessage}s in the common storage.
+     *
+     * @param queryParams Parameters to specify to return a subset of all RcsMessages.
+     *                    Passing a value of null will return all messages.
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsMessageQueryResult getRcsMessages(
+            @Nullable RcsMessageQueryParams queryParams) throws RcsMessageStoreException {
+        return new RcsMessageQueryResult(mRcsControllerCall,
+                mRcsControllerCall.call(
+                        (iRcs, callingPackage) -> iRcs.getMessages(queryParams, callingPackage)));
+    }
+
+    /**
+     * Returns the next chunk of {@link RcsMessage}s in the common storage.
+     *
+     * @param continuationToken A token to continue the query to get the next chunk. This is
+     *                          obtained through {@link RcsMessageQueryResult#getContinuationToken}
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsMessageQueryResult getRcsMessages(
+            @NonNull RcsQueryContinuationToken continuationToken) throws RcsMessageStoreException {
+        return new RcsMessageQueryResult(mRcsControllerCall,
+                mRcsControllerCall.call(
+                        (iRcs, callingPackage) -> iRcs.getMessagesWithToken(continuationToken,
+                                callingPackage)));
+    }
+
+    /**
+     * Returns the first chunk of existing {@link RcsEvent}s in the common storage.
+     *
+     * @param queryParams Parameters to specify to return a subset of all RcsEvents.
+     *                    Passing a value of null will return all events.
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsEventQueryResult getRcsEvents(
+            @Nullable RcsEventQueryParams queryParams) throws RcsMessageStoreException {
+        return mRcsControllerCall.call(
+                (iRcs, callingPackage) -> iRcs.getEvents(queryParams, callingPackage))
+                .getRcsEventQueryResult(mRcsControllerCall);
+    }
+
+    /**
+     * Returns the next chunk of {@link RcsEvent}s in the common storage.
+     *
+     * @param continuationToken A token to continue the query to get the next chunk. This is
+     *                          obtained through {@link RcsEventQueryResult#getContinuationToken}.
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsEventQueryResult getRcsEvents(
+            @NonNull RcsQueryContinuationToken continuationToken) throws RcsMessageStoreException {
+        return mRcsControllerCall.call(
+                (iRcs, callingPackage) -> iRcs.getEventsWithToken(continuationToken,
+                        callingPackage))
+                .getRcsEventQueryResult(mRcsControllerCall);
+    }
+
+    /**
+     * Persists an {@link RcsEvent} to common storage.
+     *
+     * @param rcsEvent The {@link RcsEvent} to persist into storage.
+     * @throws RcsMessageStoreException if the query could not be completed on the storage
+     * @see RcsGroupThreadNameChangedEvent
+     * @see RcsGroupThreadIconChangedEvent
+     * @see RcsGroupThreadParticipantJoinedEvent
+     * @see RcsGroupThreadParticipantLeftEvent
+     * @see RcsParticipantAliasChangedEvent
+     */
+    @WorkerThread
+    @NonNull
+    public void persistRcsEvent(RcsEvent rcsEvent) throws RcsMessageStoreException {
+        rcsEvent.persist(mRcsControllerCall);
+    }
+
+    /**
+     * Creates a new 1 to 1 thread with the given participant and persists it in the storage.
+     *
+     * @param recipient The {@link RcsParticipant} that will receive the messages in this thread.
+     * @return The newly created {@link Rcs1To1Thread}
+     * @throws RcsMessageStoreException if the thread could not be persisted in the storage
+     */
+    @WorkerThread
+    @NonNull
+    public Rcs1To1Thread createRcs1To1Thread(@NonNull RcsParticipant recipient)
+            throws RcsMessageStoreException {
+        return new Rcs1To1Thread(
+                mRcsControllerCall,
+                mRcsControllerCall.call(
+                        (iRcs, callingPackage) -> iRcs.createRcs1To1Thread(recipient.getId(),
+                                callingPackage)));
+    }
+
+    /**
+     * Creates a new group thread with the given participants and persists it in the storage.
+     *
+     * @throws RcsMessageStoreException if the thread could not be persisted in the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsGroupThread createGroupThread(@Nullable List<RcsParticipant> recipients,
+            @Nullable String groupName, @Nullable Uri groupIcon) throws RcsMessageStoreException {
+        int[] recipientIds = null;
+        if (recipients != null) {
+            recipientIds = new int[recipients.size()];
+
+            for (int i = 0; i < recipients.size(); i++) {
+                recipientIds[i] = recipients.get(i).getId();
+            }
+        }
+
+        int[] finalRecipientIds = recipientIds;
+
+        int threadId = mRcsControllerCall.call(
+                (iRcs, callingPackage) -> iRcs.createGroupThread(finalRecipientIds, groupName,
+                        groupIcon, callingPackage));
+
+        return new RcsGroupThread(mRcsControllerCall, threadId);
+    }
+
+    /**
+     * Delete the given {@link RcsThread} from the storage.
+     *
+     * @param thread The thread to be deleted.
+     * @throws RcsMessageStoreException if the thread could not be deleted from the storage
+     */
+    @WorkerThread
+    public void deleteThread(@NonNull RcsThread thread) throws RcsMessageStoreException {
+        if (thread == null) {
+            return;
+        }
+
+        boolean isDeleteSucceeded = mRcsControllerCall.call(
+                (iRcs, callingPackage) -> iRcs.deleteThread(thread.getThreadId(),
+                        thread.getThreadType(), callingPackage));
+
+        if (!isDeleteSucceeded) {
+            throw new RcsMessageStoreException("Could not delete RcsThread");
+        }
+    }
+
+    /**
+     * Creates a new participant and persists it in the storage.
+     *
+     * @param canonicalAddress The defining address (e.g. phone number) of the participant.
+     * @param alias            The RCS alias for the participant.
+     * @throws RcsMessageStoreException if the participant could not be created on the storage
+     */
+    @WorkerThread
+    @NonNull
+    public RcsParticipant createRcsParticipant(String canonicalAddress, @Nullable String alias)
+            throws RcsMessageStoreException {
+        return new RcsParticipant(mRcsControllerCall, mRcsControllerCall.call(
+                (iRcs, callingPackage) -> iRcs.createRcsParticipant(canonicalAddress, alias,
+                        callingPackage)));
+    }
+}
diff --git a/telephony/java/android/telephony/ims/RcsMessageStore.java b/telephony/java/android/telephony/ims/RcsMessageStore.java
deleted file mode 100644
index d112798..0000000
--- a/telephony/java/android/telephony/ims/RcsMessageStore.java
+++ /dev/null
@@ -1,275 +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.telephony.ims;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.WorkerThread;
-import android.content.Context;
-import android.net.Uri;
-
-import java.util.List;
-
-/**
- * RcsMessageStore is the application interface to RcsProvider and provides access methods to
- * RCS related database tables.
- *
- * @hide
- */
-public class RcsMessageStore {
-    RcsControllerCall mRcsControllerCall;
-
-    RcsMessageStore(Context context) {
-        mRcsControllerCall = new RcsControllerCall(context);
-    }
-
-    /**
-     * Returns the first chunk of existing {@link RcsThread}s in the common storage.
-     *
-     * @param queryParameters Parameters to specify to return a subset of all RcsThreads.
-     *                        Passing a value of null will return all threads.
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsThreadQueryResult getRcsThreads(@Nullable RcsThreadQueryParams queryParameters)
-            throws RcsMessageStoreException {
-        return new RcsThreadQueryResult(mRcsControllerCall,
-                mRcsControllerCall.call(
-                        (iRcs, callingPackage) -> iRcs.getRcsThreads(queryParameters,
-                                callingPackage)));
-    }
-
-    /**
-     * Returns the next chunk of {@link RcsThread}s in the common storage.
-     *
-     * @param continuationToken A token to continue the query to get the next chunk. This is
-     *                          obtained through {@link RcsThreadQueryResult#getContinuationToken}.
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsThreadQueryResult getRcsThreads(@NonNull RcsQueryContinuationToken continuationToken)
-            throws RcsMessageStoreException {
-        return new RcsThreadQueryResult(mRcsControllerCall,
-                mRcsControllerCall.call(
-                        (iRcs, callingPackage) -> iRcs.getRcsThreadsWithToken(continuationToken,
-                                callingPackage)));
-    }
-
-    /**
-     * Returns the first chunk of existing {@link RcsParticipant}s in the common storage.
-     *
-     * @param queryParameters Parameters to specify to return a subset of all RcsParticipants.
-     *                        Passing a value of null will return all participants.
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsParticipantQueryResult getRcsParticipants(
-            @Nullable RcsParticipantQueryParams queryParameters)
-            throws RcsMessageStoreException {
-        return new RcsParticipantQueryResult(mRcsControllerCall,
-                mRcsControllerCall.call(
-                        (iRcs, callingPackage) -> iRcs.getParticipants(queryParameters,
-                                callingPackage)));
-    }
-
-    /**
-     * Returns the next chunk of {@link RcsParticipant}s in the common storage.
-     *
-     * @param continuationToken A token to continue the query to get the next chunk. This is
-     *                          obtained through
-     *                          {@link RcsParticipantQueryResult#getContinuationToken}
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsParticipantQueryResult getRcsParticipants(
-            @NonNull RcsQueryContinuationToken continuationToken)
-            throws RcsMessageStoreException {
-        return new RcsParticipantQueryResult(mRcsControllerCall,
-                mRcsControllerCall.call(
-                        (iRcs, callingPackage) -> iRcs.getParticipantsWithToken(continuationToken,
-                                callingPackage)));
-    }
-
-    /**
-     * Returns the first chunk of existing {@link RcsMessage}s in the common storage.
-     *
-     * @param queryParams Parameters to specify to return a subset of all RcsMessages.
-     *                    Passing a value of null will return all messages.
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsMessageQueryResult getRcsMessages(
-            @Nullable RcsMessageQueryParams queryParams) throws RcsMessageStoreException {
-        return new RcsMessageQueryResult(mRcsControllerCall,
-                mRcsControllerCall.call(
-                        (iRcs, callingPackage) -> iRcs.getMessages(queryParams, callingPackage)));
-    }
-
-    /**
-     * Returns the next chunk of {@link RcsMessage}s in the common storage.
-     *
-     * @param continuationToken A token to continue the query to get the next chunk. This is
-     *                          obtained through {@link RcsMessageQueryResult#getContinuationToken}
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsMessageQueryResult getRcsMessages(
-            @NonNull RcsQueryContinuationToken continuationToken) throws RcsMessageStoreException {
-        return new RcsMessageQueryResult(mRcsControllerCall,
-                mRcsControllerCall.call(
-                        (iRcs, callingPackage) -> iRcs.getMessagesWithToken(continuationToken,
-                                callingPackage)));
-    }
-
-    /**
-     * Returns the first chunk of existing {@link RcsEvent}s in the common storage.
-     *
-     * @param queryParams Parameters to specify to return a subset of all RcsEvents.
-     *                    Passing a value of null will return all events.
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsEventQueryResult getRcsEvents(
-            @Nullable RcsEventQueryParams queryParams) throws RcsMessageStoreException {
-        return mRcsControllerCall.call(
-                (iRcs, callingPackage) -> iRcs.getEvents(queryParams, callingPackage))
-                .getRcsEventQueryResult(mRcsControllerCall);
-    }
-
-    /**
-     * Returns the next chunk of {@link RcsEvent}s in the common storage.
-     *
-     * @param continuationToken A token to continue the query to get the next chunk. This is
-     *                          obtained through {@link RcsEventQueryResult#getContinuationToken}.
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsEventQueryResult getRcsEvents(
-            @NonNull RcsQueryContinuationToken continuationToken) throws RcsMessageStoreException {
-        return mRcsControllerCall.call(
-                (iRcs, callingPackage) -> iRcs.getEventsWithToken(continuationToken,
-                        callingPackage))
-                .getRcsEventQueryResult(mRcsControllerCall);
-    }
-
-    /**
-     * Persists an {@link RcsEvent} to common storage.
-     *
-     * @param rcsEvent The {@link RcsEvent} to persist into storage.
-     * @throws RcsMessageStoreException if the query could not be completed on the storage
-     * @see RcsGroupThreadNameChangedEvent
-     * @see RcsGroupThreadIconChangedEvent
-     * @see RcsGroupThreadParticipantJoinedEvent
-     * @see RcsGroupThreadParticipantLeftEvent
-     * @see RcsParticipantAliasChangedEvent
-     */
-    @WorkerThread
-    @NonNull
-    public void persistRcsEvent(RcsEvent rcsEvent) throws RcsMessageStoreException {
-        rcsEvent.persist(mRcsControllerCall);
-    }
-
-    /**
-     * Creates a new 1 to 1 thread with the given participant and persists it in the storage.
-     *
-     * @param recipient The {@link RcsParticipant} that will receive the messages in this thread.
-     * @return The newly created {@link Rcs1To1Thread}
-     * @throws RcsMessageStoreException if the thread could not be persisted in the storage
-     */
-    @WorkerThread
-    @NonNull
-    public Rcs1To1Thread createRcs1To1Thread(@NonNull RcsParticipant recipient)
-            throws RcsMessageStoreException {
-        return new Rcs1To1Thread(
-                mRcsControllerCall,
-                mRcsControllerCall.call(
-                        (iRcs, callingPackage) -> iRcs.createRcs1To1Thread(recipient.getId(),
-                                callingPackage)));
-    }
-
-    /**
-     * Creates a new group thread with the given participants and persists it in the storage.
-     *
-     * @throws RcsMessageStoreException if the thread could not be persisted in the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsGroupThread createGroupThread(@Nullable List<RcsParticipant> recipients,
-            @Nullable String groupName, @Nullable Uri groupIcon) throws RcsMessageStoreException {
-        int[] recipientIds = null;
-        if (recipients != null) {
-            recipientIds = new int[recipients.size()];
-
-            for (int i = 0; i < recipients.size(); i++) {
-                recipientIds[i] = recipients.get(i).getId();
-            }
-        }
-
-        int[] finalRecipientIds = recipientIds;
-
-        int threadId = mRcsControllerCall.call(
-                (iRcs, callingPackage) -> iRcs.createGroupThread(finalRecipientIds, groupName,
-                        groupIcon, callingPackage));
-
-        return new RcsGroupThread(mRcsControllerCall, threadId);
-    }
-
-    /**
-     * Delete the given {@link RcsThread} from the storage.
-     *
-     * @param thread The thread to be deleted.
-     * @throws RcsMessageStoreException if the thread could not be deleted from the storage
-     */
-    @WorkerThread
-    public void deleteThread(@NonNull RcsThread thread) throws RcsMessageStoreException {
-        if (thread == null) {
-            return;
-        }
-
-        boolean isDeleteSucceeded = mRcsControllerCall.call(
-                (iRcs, callingPackage) -> iRcs.deleteThread(thread.getThreadId(),
-                        thread.getThreadType(), callingPackage));
-
-        if (!isDeleteSucceeded) {
-            throw new RcsMessageStoreException("Could not delete RcsThread");
-        }
-    }
-
-    /**
-     * Creates a new participant and persists it in the storage.
-     *
-     * @param canonicalAddress The defining address (e.g. phone number) of the participant.
-     * @param alias            The RCS alias for the participant.
-     * @throws RcsMessageStoreException if the participant could not be created on the storage
-     */
-    @WorkerThread
-    @NonNull
-    public RcsParticipant createRcsParticipant(String canonicalAddress, @Nullable String alias)
-            throws RcsMessageStoreException {
-        return new RcsParticipant(mRcsControllerCall, mRcsControllerCall.call(
-                (iRcs, callingPackage) -> iRcs.createRcsParticipant(canonicalAddress, alias,
-                        callingPackage)));
-    }
-}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcs.aidl b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
deleted file mode 100644
index 9ee15da..0000000
--- a/telephony/java/android/telephony/ims/aidl/IRcs.aidl
+++ /dev/null
@@ -1,266 +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.telephony.ims.aidl;
-
-import android.net.Uri;
-import android.telephony.ims.RcsEventQueryParams;
-import android.telephony.ims.RcsEventQueryResultDescriptor;
-import android.telephony.ims.RcsFileTransferCreationParams;
-import android.telephony.ims.RcsIncomingMessageCreationParams;
-import android.telephony.ims.RcsMessageSnippet;
-import android.telephony.ims.RcsMessageQueryParams;
-import android.telephony.ims.RcsMessageQueryResultParcelable;
-import android.telephony.ims.RcsOutgoingMessageCreationParams;
-import android.telephony.ims.RcsParticipantQueryParams;
-import android.telephony.ims.RcsParticipantQueryResultParcelable;
-import android.telephony.ims.RcsQueryContinuationToken;
-import android.telephony.ims.RcsThreadQueryParams;
-import android.telephony.ims.RcsThreadQueryResultParcelable;
-
-/**
- * RPC definition between RCS storage APIs and phone process.
- * {@hide}
- */
-interface IRcs {
-    /////////////////////////
-    // RcsMessageStore APIs
-    /////////////////////////
-    RcsThreadQueryResultParcelable getRcsThreads(in RcsThreadQueryParams queryParams, String callingPackage);
-
-    RcsThreadQueryResultParcelable getRcsThreadsWithToken(
-        in RcsQueryContinuationToken continuationToken, String callingPackage);
-
-    RcsParticipantQueryResultParcelable getParticipants(in RcsParticipantQueryParams queryParams, String callingPackage);
-
-    RcsParticipantQueryResultParcelable getParticipantsWithToken(
-        in RcsQueryContinuationToken continuationToken, String callingPackage);
-
-    RcsMessageQueryResultParcelable getMessages(in RcsMessageQueryParams queryParams, String callingPackage);
-
-    RcsMessageQueryResultParcelable getMessagesWithToken(
-        in RcsQueryContinuationToken continuationToken, String callingPackage);
-
-    RcsEventQueryResultDescriptor getEvents(in RcsEventQueryParams queryParams, String callingPackage);
-
-    RcsEventQueryResultDescriptor getEventsWithToken(
-        in RcsQueryContinuationToken continuationToken, String callingPackage);
-
-    // returns true if the thread was successfully deleted
-    boolean deleteThread(int threadId, int threadType, String callingPackage);
-
-    // Creates an Rcs1To1Thread and returns its row ID
-    int createRcs1To1Thread(int participantId, String callingPackage);
-
-    // Creates an RcsGroupThread and returns its row ID
-    int createGroupThread(in int[] participantIds, String groupName, in Uri groupIcon, String callingPackage);
-
-    /////////////////////////
-    // RcsThread APIs
-    /////////////////////////
-
-    // Creates a new RcsIncomingMessage on the given thread and returns its row ID
-    int addIncomingMessage(int rcsThreadId,
-            in RcsIncomingMessageCreationParams rcsIncomingMessageCreationParams, String callingPackage);
-
-    // Creates a new RcsOutgoingMessage on the given thread and returns its row ID
-    int addOutgoingMessage(int rcsThreadId,
-            in RcsOutgoingMessageCreationParams rcsOutgoingMessageCreationParams, String callingPackage);
-
-    // TODO: modify RcsProvider URI's to allow deleting a message without specifying its thread
-    void deleteMessage(int rcsMessageId, boolean isIncoming, int rcsThreadId, boolean isGroup, String callingPackage);
-
-    RcsMessageSnippet getMessageSnippet(int rcsThreadId, String callingPackage);
-
-    /////////////////////////
-    // Rcs1To1Thread APIs
-    /////////////////////////
-    void set1To1ThreadFallbackThreadId(int rcsThreadId, long fallbackId, String callingPackage);
-
-    long get1To1ThreadFallbackThreadId(int rcsThreadId, String callingPackage);
-
-    int get1To1ThreadOtherParticipantId(int rcsThreadId, String callingPackage);
-
-    /////////////////////////
-    // RcsGroupThread APIs
-    /////////////////////////
-    void setGroupThreadName(int rcsThreadId, String groupName, String callingPackage);
-
-    String getGroupThreadName(int rcsThreadId, String callingPackage);
-
-    void setGroupThreadIcon(int rcsThreadId, in Uri groupIcon, String callingPackage);
-
-    Uri getGroupThreadIcon(int rcsThreadId, String callingPackage);
-
-    void setGroupThreadOwner(int rcsThreadId, int participantId, String callingPackage);
-
-    int getGroupThreadOwner(int rcsThreadId, String callingPackage);
-
-    void setGroupThreadConferenceUri(int rcsThreadId, in Uri conferenceUri, String callingPackage);
-
-    Uri getGroupThreadConferenceUri(int rcsThreadId, String callingPackage);
-
-    void addParticipantToGroupThread(int rcsThreadId, int participantId, String callingPackage);
-
-    void removeParticipantFromGroupThread(int rcsThreadId, int participantId, String callingPackage);
-
-    /////////////////////////
-    // RcsParticipant APIs
-    /////////////////////////
-
-    // Creates a new RcsParticipant and returns its rowId
-    int createRcsParticipant(String canonicalAddress, String alias, String callingPackage);
-
-    String getRcsParticipantCanonicalAddress(int participantId, String callingPackage);
-
-    String getRcsParticipantAlias(int participantId, String callingPackage);
-
-    void setRcsParticipantAlias(int id, String alias, String callingPackage);
-
-    String getRcsParticipantContactId(int participantId, String callingPackage);
-
-    void setRcsParticipantContactId(int participantId, String contactId, String callingPackage);
-
-    /////////////////////////
-    // RcsMessage APIs
-    /////////////////////////
-    void setMessageSubId(int messageId, boolean isIncoming, int subId, String callingPackage);
-
-    int getMessageSubId(int messageId, boolean isIncoming, String callingPackage);
-
-    void setMessageStatus(int messageId, boolean isIncoming, int status, String callingPackage);
-
-    int getMessageStatus(int messageId, boolean isIncoming, String callingPackage);
-
-    void setMessageOriginationTimestamp(int messageId, boolean isIncoming, long originationTimestamp, String callingPackage);
-
-    long getMessageOriginationTimestamp(int messageId, boolean isIncoming, String callingPackage);
-
-    void setGlobalMessageIdForMessage(int messageId, boolean isIncoming, String globalId, String callingPackage);
-
-    String getGlobalMessageIdForMessage(int messageId, boolean isIncoming, String callingPackage);
-
-    void setMessageArrivalTimestamp(int messageId, boolean isIncoming, long arrivalTimestamp, String callingPackage);
-
-    long getMessageArrivalTimestamp(int messageId, boolean isIncoming, String callingPackage);
-
-    void setMessageSeenTimestamp(int messageId, boolean isIncoming, long seenTimestamp, String callingPackage);
-
-    long getMessageSeenTimestamp(int messageId, boolean isIncoming, String callingPackage);
-
-    void setTextForMessage(int messageId, boolean isIncoming, String text, String callingPackage);
-
-    String getTextForMessage(int messageId, boolean isIncoming, String callingPackage);
-
-    void setLatitudeForMessage(int messageId, boolean isIncoming, double latitude, String callingPackage);
-
-    double getLatitudeForMessage(int messageId, boolean isIncoming, String callingPackage);
-
-    void setLongitudeForMessage(int messageId, boolean isIncoming, double longitude, String callingPackage);
-
-    double getLongitudeForMessage(int messageId, boolean isIncoming, String callingPackage);
-
-    // Returns the ID's of the file transfers attached to the given message
-    int[] getFileTransfersAttachedToMessage(int messageId, boolean isIncoming, String callingPackage);
-
-    int getSenderParticipant(int messageId, String callingPackage);
-
-    /////////////////////////
-    // RcsOutgoingMessageDelivery APIs
-    /////////////////////////
-
-    // Returns the participant ID's that this message is intended to be delivered to
-    int[] getMessageRecipients(int messageId, String callingPackage);
-
-    long getOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, String callingPackage);
-
-    void setOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, long deliveredTimestamp, String callingPackage);
-
-    long getOutgoingDeliverySeenTimestamp(int messageId, int participantId, String callingPackage);
-
-    void setOutgoingDeliverySeenTimestamp(int messageId, int participantId, long seenTimestamp, String callingPackage);
-
-    int getOutgoingDeliveryStatus(int messageId, int participantId, String callingPackage);
-
-    void setOutgoingDeliveryStatus(int messageId, int participantId, int status, String callingPackage);
-
-    /////////////////////////
-    // RcsFileTransferPart APIs
-    /////////////////////////
-
-    // Performs the initial write to storage and returns the row ID.
-    int storeFileTransfer(int messageId, boolean isIncoming,
-            in RcsFileTransferCreationParams fileTransferCreationParams, String callingPackage);
-
-    void deleteFileTransfer(int partId, String callingPackage);
-
-    void setFileTransferSessionId(int partId, String sessionId, String callingPackage);
-
-    String getFileTransferSessionId(int partId, String callingPackage);
-
-    void setFileTransferContentUri(int partId, in Uri contentUri, String callingPackage);
-
-    Uri getFileTransferContentUri(int partId, String callingPackage);
-
-    void setFileTransferContentType(int partId, String contentType, String callingPackage);
-
-    String getFileTransferContentType(int partId, String callingPackage);
-
-    void setFileTransferFileSize(int partId, long fileSize, String callingPackage);
-
-    long getFileTransferFileSize(int partId, String callingPackage);
-
-    void setFileTransferTransferOffset(int partId, long transferOffset, String callingPackage);
-
-    long getFileTransferTransferOffset(int partId, String callingPackage);
-
-    void setFileTransferStatus(int partId, int transferStatus, String callingPackage);
-
-    int getFileTransferStatus(int partId, String callingPackage);
-
-    void setFileTransferWidth(int partId, int width, String callingPackage);
-
-    int getFileTransferWidth(int partId, String callingPackage);
-
-    void setFileTransferHeight(int partId, int height, String callingPackage);
-
-    int getFileTransferHeight(int partId, String callingPackage);
-
-    void setFileTransferLength(int partId, long length, String callingPackage);
-
-    long getFileTransferLength(int partId, String callingPackage);
-
-    void setFileTransferPreviewUri(int partId, in Uri uri, String callingPackage);
-
-    Uri getFileTransferPreviewUri(int partId, String callingPackage);
-
-    void setFileTransferPreviewType(int partId, String type, String callingPackage);
-
-    String getFileTransferPreviewType(int partId, String callingPackage);
-
-    /////////////////////////
-    // RcsEvent APIs
-    /////////////////////////
-    int createGroupThreadNameChangedEvent(long timestamp, int threadId, int originationParticipantId, String newName, String callingPackage);
-
-    int createGroupThreadIconChangedEvent(long timestamp, int threadId, int originationParticipantId, in Uri newIcon, String callingPackage);
-
-    int createGroupThreadParticipantJoinedEvent(long timestamp, int threadId, int originationParticipantId, int participantId, String callingPackage);
-
-    int createGroupThreadParticipantLeftEvent(long timestamp, int threadId, int originationParticipantId, int participantId, String callingPackage);
-
-    int createParticipantAliasChangedEvent(long timestamp, int participantId, String newAlias, String callingPackage);
-}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsMessage.aidl b/telephony/java/android/telephony/ims/aidl/IRcsMessage.aidl
new file mode 100644
index 0000000..0ae6303
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IRcsMessage.aidl
@@ -0,0 +1,266 @@
+/*
+ * 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.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.RcsEventQueryParams;
+import android.telephony.ims.RcsEventQueryResultDescriptor;
+import android.telephony.ims.RcsFileTransferCreationParams;
+import android.telephony.ims.RcsIncomingMessageCreationParams;
+import android.telephony.ims.RcsMessageSnippet;
+import android.telephony.ims.RcsMessageQueryParams;
+import android.telephony.ims.RcsMessageQueryResultParcelable;
+import android.telephony.ims.RcsOutgoingMessageCreationParams;
+import android.telephony.ims.RcsParticipantQueryParams;
+import android.telephony.ims.RcsParticipantQueryResultParcelable;
+import android.telephony.ims.RcsQueryContinuationToken;
+import android.telephony.ims.RcsThreadQueryParams;
+import android.telephony.ims.RcsThreadQueryResultParcelable;
+
+/**
+ * RPC definition between RCS storage APIs and phone process.
+ * {@hide}
+ */
+interface IRcsMessage {
+    /////////////////////////
+    // RcsMessageStore APIs
+    /////////////////////////
+    RcsThreadQueryResultParcelable getRcsThreads(in RcsThreadQueryParams queryParams, String callingPackage);
+
+    RcsThreadQueryResultParcelable getRcsThreadsWithToken(
+        in RcsQueryContinuationToken continuationToken, String callingPackage);
+
+    RcsParticipantQueryResultParcelable getParticipants(in RcsParticipantQueryParams queryParams, String callingPackage);
+
+    RcsParticipantQueryResultParcelable getParticipantsWithToken(
+        in RcsQueryContinuationToken continuationToken, String callingPackage);
+
+    RcsMessageQueryResultParcelable getMessages(in RcsMessageQueryParams queryParams, String callingPackage);
+
+    RcsMessageQueryResultParcelable getMessagesWithToken(
+        in RcsQueryContinuationToken continuationToken, String callingPackage);
+
+    RcsEventQueryResultDescriptor getEvents(in RcsEventQueryParams queryParams, String callingPackage);
+
+    RcsEventQueryResultDescriptor getEventsWithToken(
+        in RcsQueryContinuationToken continuationToken, String callingPackage);
+
+    // returns true if the thread was successfully deleted
+    boolean deleteThread(int threadId, int threadType, String callingPackage);
+
+    // Creates an Rcs1To1Thread and returns its row ID
+    int createRcs1To1Thread(int participantId, String callingPackage);
+
+    // Creates an RcsGroupThread and returns its row ID
+    int createGroupThread(in int[] participantIds, String groupName, in Uri groupIcon, String callingPackage);
+
+    /////////////////////////
+    // RcsThread APIs
+    /////////////////////////
+
+    // Creates a new RcsIncomingMessage on the given thread and returns its row ID
+    int addIncomingMessage(int rcsThreadId,
+            in RcsIncomingMessageCreationParams rcsIncomingMessageCreationParams, String callingPackage);
+
+    // Creates a new RcsOutgoingMessage on the given thread and returns its row ID
+    int addOutgoingMessage(int rcsThreadId,
+            in RcsOutgoingMessageCreationParams rcsOutgoingMessageCreationParams, String callingPackage);
+
+    // TODO: modify RcsProvider URI's to allow deleting a message without specifying its thread
+    void deleteMessage(int rcsMessageId, boolean isIncoming, int rcsThreadId, boolean isGroup, String callingPackage);
+
+    RcsMessageSnippet getMessageSnippet(int rcsThreadId, String callingPackage);
+
+    /////////////////////////
+    // Rcs1To1Thread APIs
+    /////////////////////////
+    void set1To1ThreadFallbackThreadId(int rcsThreadId, long fallbackId, String callingPackage);
+
+    long get1To1ThreadFallbackThreadId(int rcsThreadId, String callingPackage);
+
+    int get1To1ThreadOtherParticipantId(int rcsThreadId, String callingPackage);
+
+    /////////////////////////
+    // RcsGroupThread APIs
+    /////////////////////////
+    void setGroupThreadName(int rcsThreadId, String groupName, String callingPackage);
+
+    String getGroupThreadName(int rcsThreadId, String callingPackage);
+
+    void setGroupThreadIcon(int rcsThreadId, in Uri groupIcon, String callingPackage);
+
+    Uri getGroupThreadIcon(int rcsThreadId, String callingPackage);
+
+    void setGroupThreadOwner(int rcsThreadId, int participantId, String callingPackage);
+
+    int getGroupThreadOwner(int rcsThreadId, String callingPackage);
+
+    void setGroupThreadConferenceUri(int rcsThreadId, in Uri conferenceUri, String callingPackage);
+
+    Uri getGroupThreadConferenceUri(int rcsThreadId, String callingPackage);
+
+    void addParticipantToGroupThread(int rcsThreadId, int participantId, String callingPackage);
+
+    void removeParticipantFromGroupThread(int rcsThreadId, int participantId, String callingPackage);
+
+    /////////////////////////
+    // RcsParticipant APIs
+    /////////////////////////
+
+    // Creates a new RcsParticipant and returns its rowId
+    int createRcsParticipant(String canonicalAddress, String alias, String callingPackage);
+
+    String getRcsParticipantCanonicalAddress(int participantId, String callingPackage);
+
+    String getRcsParticipantAlias(int participantId, String callingPackage);
+
+    void setRcsParticipantAlias(int id, String alias, String callingPackage);
+
+    String getRcsParticipantContactId(int participantId, String callingPackage);
+
+    void setRcsParticipantContactId(int participantId, String contactId, String callingPackage);
+
+    /////////////////////////
+    // RcsMessage APIs
+    /////////////////////////
+    void setMessageSubId(int messageId, boolean isIncoming, int subId, String callingPackage);
+
+    int getMessageSubId(int messageId, boolean isIncoming, String callingPackage);
+
+    void setMessageStatus(int messageId, boolean isIncoming, int status, String callingPackage);
+
+    int getMessageStatus(int messageId, boolean isIncoming, String callingPackage);
+
+    void setMessageOriginationTimestamp(int messageId, boolean isIncoming, long originationTimestamp, String callingPackage);
+
+    long getMessageOriginationTimestamp(int messageId, boolean isIncoming, String callingPackage);
+
+    void setGlobalMessageIdForMessage(int messageId, boolean isIncoming, String globalId, String callingPackage);
+
+    String getGlobalMessageIdForMessage(int messageId, boolean isIncoming, String callingPackage);
+
+    void setMessageArrivalTimestamp(int messageId, boolean isIncoming, long arrivalTimestamp, String callingPackage);
+
+    long getMessageArrivalTimestamp(int messageId, boolean isIncoming, String callingPackage);
+
+    void setMessageSeenTimestamp(int messageId, boolean isIncoming, long seenTimestamp, String callingPackage);
+
+    long getMessageSeenTimestamp(int messageId, boolean isIncoming, String callingPackage);
+
+    void setTextForMessage(int messageId, boolean isIncoming, String text, String callingPackage);
+
+    String getTextForMessage(int messageId, boolean isIncoming, String callingPackage);
+
+    void setLatitudeForMessage(int messageId, boolean isIncoming, double latitude, String callingPackage);
+
+    double getLatitudeForMessage(int messageId, boolean isIncoming, String callingPackage);
+
+    void setLongitudeForMessage(int messageId, boolean isIncoming, double longitude, String callingPackage);
+
+    double getLongitudeForMessage(int messageId, boolean isIncoming, String callingPackage);
+
+    // Returns the ID's of the file transfers attached to the given message
+    int[] getFileTransfersAttachedToMessage(int messageId, boolean isIncoming, String callingPackage);
+
+    int getSenderParticipant(int messageId, String callingPackage);
+
+    /////////////////////////
+    // RcsOutgoingMessageDelivery APIs
+    /////////////////////////
+
+    // Returns the participant ID's that this message is intended to be delivered to
+    int[] getMessageRecipients(int messageId, String callingPackage);
+
+    long getOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, String callingPackage);
+
+    void setOutgoingDeliveryDeliveredTimestamp(int messageId, int participantId, long deliveredTimestamp, String callingPackage);
+
+    long getOutgoingDeliverySeenTimestamp(int messageId, int participantId, String callingPackage);
+
+    void setOutgoingDeliverySeenTimestamp(int messageId, int participantId, long seenTimestamp, String callingPackage);
+
+    int getOutgoingDeliveryStatus(int messageId, int participantId, String callingPackage);
+
+    void setOutgoingDeliveryStatus(int messageId, int participantId, int status, String callingPackage);
+
+    /////////////////////////
+    // RcsFileTransferPart APIs
+    /////////////////////////
+
+    // Performs the initial write to storage and returns the row ID.
+    int storeFileTransfer(int messageId, boolean isIncoming,
+            in RcsFileTransferCreationParams fileTransferCreationParams, String callingPackage);
+
+    void deleteFileTransfer(int partId, String callingPackage);
+
+    void setFileTransferSessionId(int partId, String sessionId, String callingPackage);
+
+    String getFileTransferSessionId(int partId, String callingPackage);
+
+    void setFileTransferContentUri(int partId, in Uri contentUri, String callingPackage);
+
+    Uri getFileTransferContentUri(int partId, String callingPackage);
+
+    void setFileTransferContentType(int partId, String contentType, String callingPackage);
+
+    String getFileTransferContentType(int partId, String callingPackage);
+
+    void setFileTransferFileSize(int partId, long fileSize, String callingPackage);
+
+    long getFileTransferFileSize(int partId, String callingPackage);
+
+    void setFileTransferTransferOffset(int partId, long transferOffset, String callingPackage);
+
+    long getFileTransferTransferOffset(int partId, String callingPackage);
+
+    void setFileTransferStatus(int partId, int transferStatus, String callingPackage);
+
+    int getFileTransferStatus(int partId, String callingPackage);
+
+    void setFileTransferWidth(int partId, int width, String callingPackage);
+
+    int getFileTransferWidth(int partId, String callingPackage);
+
+    void setFileTransferHeight(int partId, int height, String callingPackage);
+
+    int getFileTransferHeight(int partId, String callingPackage);
+
+    void setFileTransferLength(int partId, long length, String callingPackage);
+
+    long getFileTransferLength(int partId, String callingPackage);
+
+    void setFileTransferPreviewUri(int partId, in Uri uri, String callingPackage);
+
+    Uri getFileTransferPreviewUri(int partId, String callingPackage);
+
+    void setFileTransferPreviewType(int partId, String type, String callingPackage);
+
+    String getFileTransferPreviewType(int partId, String callingPackage);
+
+    /////////////////////////
+    // RcsEvent APIs
+    /////////////////////////
+    int createGroupThreadNameChangedEvent(long timestamp, int threadId, int originationParticipantId, String newName, String callingPackage);
+
+    int createGroupThreadIconChangedEvent(long timestamp, int threadId, int originationParticipantId, in Uri newIcon, String callingPackage);
+
+    int createGroupThreadParticipantJoinedEvent(long timestamp, int threadId, int originationParticipantId, int participantId, String callingPackage);
+
+    int createGroupThreadParticipantLeftEvent(long timestamp, int threadId, int originationParticipantId, int participantId, String callingPackage);
+
+    int createParticipantAliasChangedEvent(long timestamp, int participantId, String newAlias, String callingPackage);
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index a1bea4d..6498e49 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -22,6 +22,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.os.RemoteException;
+import android.permission.IPermissionManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
@@ -71,8 +72,8 @@
      * privileged apps may have changed.
      */
     public synchronized static void disableCarrierAppsUntilPrivileged(String callingPackage,
-            IPackageManager packageManager, TelephonyManager telephonyManager,
-            ContentResolver contentResolver, int userId) {
+            IPackageManager packageManager, IPermissionManager permissionManager,
+            TelephonyManager telephonyManager, ContentResolver contentResolver, int userId) {
         if (DEBUG) {
             Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
         }
@@ -81,8 +82,8 @@
                 config.getDisabledUntilUsedPreinstalledCarrierApps();
         ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
                 config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
-        disableCarrierAppsUntilPrivileged(callingPackage, packageManager, telephonyManager,
-                contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
+        disableCarrierAppsUntilPrivileged(callingPackage, packageManager, permissionManager,
+                telephonyManager, contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
                 systemCarrierAssociatedAppsDisabledUntilUsed);
     }
 
@@ -98,7 +99,8 @@
      * Manager can kill it, and this can lead to crashes as the app is in an unexpected state.
      */
     public synchronized static void disableCarrierAppsUntilPrivileged(String callingPackage,
-            IPackageManager packageManager, ContentResolver contentResolver, int userId) {
+            IPackageManager packageManager, IPermissionManager permissionManager,
+            ContentResolver contentResolver, int userId) {
         if (DEBUG) {
             Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
         }
@@ -109,7 +111,7 @@
 
         ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
                 config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
-        disableCarrierAppsUntilPrivileged(callingPackage, packageManager,
+        disableCarrierAppsUntilPrivileged(callingPackage, packageManager, permissionManager,
                 null /* telephonyManager */, contentResolver, userId,
                 systemCarrierAppsDisabledUntilUsed, systemCarrierAssociatedAppsDisabledUntilUsed);
     }
@@ -117,7 +119,8 @@
     // Must be public b/c framework unit tests can't access package-private methods.
     @VisibleForTesting
     public static void disableCarrierAppsUntilPrivileged(String callingPackage,
-            IPackageManager packageManager, @Nullable TelephonyManager telephonyManager,
+            IPackageManager packageManager, IPermissionManager permissionManager,
+            @Nullable TelephonyManager telephonyManager,
             ContentResolver contentResolver, int userId,
             ArraySet<String> systemCarrierAppsDisabledUntilUsed,
             ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed) {
@@ -256,7 +259,7 @@
                 // apps.
                 String[] packageNames = new String[enabledCarrierPackages.size()];
                 enabledCarrierPackages.toArray(packageNames);
-                packageManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
+                permissionManager.grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId);
             }
         } catch (RemoteException e) {
             Slog.w(TAG, "Could not reach PackageManager", e);
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index bb5c251..cde6db4 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -94,7 +94,7 @@
     public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
     public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
     public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 50;
-    public static final int EVENT_APN_WHITE_LIST_CHANGE = BASE + 51;
+    public static final int EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED = BASE + 51;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index c34feed..7441c26 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -22,20 +22,11 @@
 import android.telephony.IFinancialSmsCallback;
 import com.android.internal.telephony.SmsRawData;
 
-/** Interface for applications to access the ICC phone book.
+/**
+ * Interface for applications to access the ICC phone book.
  *
- * <p>The following code snippet demonstrates a static method to
- * retrieve the ISms interface from Android:</p>
- * <pre>private static ISms getSmsInterface()
-            throws DeadObjectException {
-    IServiceManager sm = ServiceManagerNative.getDefault();
-    ISms ss;
-    ss = ISms.Stub.asInterface(sm.getService("isms"));
-    return ss;
-}
- * </pre>
+ * See also SmsManager.java.
  */
-
 interface ISms {
     /**
      * Retrieves all messages currently stored on ICC.
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index b081228..7cc37d0d2 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -281,4 +281,6 @@
     boolean isActiveSubId(int subId, String callingPackage);
 
     boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow);
+
+    int getActiveDataSubscriptionId();
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index cf1323a..dcfd193 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -308,18 +308,46 @@
      */
     List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
 
-     @UnsupportedAppUsage
-     int getCallState();
+    @UnsupportedAppUsage
+    int getCallState();
 
     /**
      * Returns the call state for a slot.
      */
-     int getCallStateForSlot(int slotIndex);
+    int getCallStateForSlot(int slotIndex);
 
-     @UnsupportedAppUsage
-     int getDataActivity();
-     @UnsupportedAppUsage
-     int getDataState();
+    /**
+     * Replaced by getDataActivityForSubId.
+     */
+    int getDataActivity();
+
+    /**
+     * Returns a constant indicating the type of activity on a data connection
+     * (cellular).
+     *
+     * @see #DATA_ACTIVITY_NONE
+     * @see #DATA_ACTIVITY_IN
+     * @see #DATA_ACTIVITY_OUT
+     * @see #DATA_ACTIVITY_INOUT
+     * @see #DATA_ACTIVITY_DORMANT
+     */
+    int getDataActivityForSubId(int subId);
+
+    /**
+     * Replaced by getDataStateForSubId.
+     */
+    int getDataState();
+
+    /**
+     * Returns a constant indicating the current data connection state
+     * (cellular).
+     *
+     * @see #DATA_DISCONNECTED
+     * @see #DATA_CONNECTING
+     * @see #DATA_CONNECTED
+     * @see #DATA_SUSPENDED
+     */
+    int getDataStateForSubId(int subId);
 
     /**
      * Returns the current active phone type as integer.
@@ -1059,6 +1087,11 @@
     String[] getMergedSubscriberIds(int subId, String callingPackage);
 
     /**
+     * @hide
+     */
+    String[] getMergedSubscriberIdsFromGroup(int subId, String callingPackage);
+
+    /**
      * Override the operator branding for the current ICCID.
      *
      * Once set, whenever the SIM is present in the device, the service
@@ -1619,7 +1652,7 @@
      * <p>
      * See {@link UiccCardInfo} for more details on the kind of information available.
      *
-     * @param callingPackage package making the call, used to evaluate carrier privileges 
+     * @param callingPackage package making the call, used to evaluate carrier privileges
      * @return a list of UiccCardInfo objects, representing information on the currently inserted
      * UICCs and eUICCs. Each UiccCardInfo in the list will have private information filtered out if
      * the caller does not have adequate permissions for that card.
@@ -1996,4 +2029,15 @@
      * Returns the MMS user agent profile URL.
      */
     String getMmsUAProfUrl(int subId);
+
+    /**
+     * Set allowing mobile data during voice call.
+     */
+    boolean setDataAllowedDuringVoiceCall(int subId, boolean allow);
+
+    /**
+     * Check whether data is allowed during voice call. Note this is for dual sim device that
+     * data might be disabled on non-default data subscription but explicitly turned on by settings.
+     */
+    boolean isDataAllowedInVoiceCall(int subId);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index f2f3c2d..dc026d4 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -68,8 +68,7 @@
     void notifyOtaspChanged(in int subId, in int otaspMode);
     @UnsupportedAppUsage
     void notifyCellInfo(in List<CellInfo> cellInfo);
-    void notifyPhysicalChannelConfiguration(in List<PhysicalChannelConfig> configs);
-    void notifyPhysicalChannelConfigurationForSubscriber(in int subId,
+    void notifyPhysicalChannelConfigurationForSubscriber(in int phoneId, in int subId,
             in List<PhysicalChannelConfig> configs);
     void notifyPreciseCallState(int phoneId, int subId, int ringingCallState,
             int foregroundCallState, int backgroundCallState);
diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java
index ef7c605..98f52cb 100644
--- a/telephony/java/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/java/com/android/internal/telephony/SmsApplication.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import android.Manifest.permission;
+import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.role.RoleManager;
 import android.content.ComponentName;
@@ -465,7 +466,11 @@
             int userId) {
         TelephonyManager tm = (TelephonyManager)
                 context.getSystemService(Context.TELEPHONY_SERVICE);
-        if (!tm.isSmsCapable()) {
+        RoleManager roleManager = (RoleManager) context.getSystemService(Context.ROLE_SERVICE);
+        // (b/134400042) RoleManager might be null in unit tests running older mockito versions
+        // that do not support mocking final classes.
+        if (!tm.isSmsCapable() && (roleManager == null || !roleManager.isRoleAvailable(
+                RoleManager.ROLE_SMS))) {
             // No phone, no SMS
             return null;
         }
@@ -584,7 +589,11 @@
     public static void setDefaultApplicationAsUser(String packageName, Context context,
             int userId) {
         TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
-        if (!tm.isSmsCapable()) {
+        RoleManager roleManager = (RoleManager) context.getSystemService(Context.ROLE_SERVICE);
+        // (b/134400042) RoleManager might be null in unit tests running older mockito versions
+        // that do not support mocking final classes.
+        if (!tm.isSmsCapable() && (roleManager == null || !roleManager.isRoleAvailable(
+                RoleManager.ROLE_SMS))) {
             // No phone, no SMS
             return;
         }
@@ -654,49 +663,69 @@
             }
 
             defaultSmsAppChanged(context);
+        }
+    }
 
-            if (DEBUG_MULTIUSER) {
-                Log.i(LOG_TAG, "setDefaultApplicationInternal oldAppData=" + oldAppData);
-            }
-            if (oldAppData != null && oldAppData.mSmsAppChangedReceiverClass != null) {
-                // Notify the old sms app that it's no longer the default
-                final Intent oldAppIntent =
-                        new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED);
-                final ComponentName component = new ComponentName(oldAppData.mPackageName,
-                        oldAppData.mSmsAppChangedReceiverClass);
-                oldAppIntent.setComponent(component);
-                oldAppIntent.putExtra(Telephony.Sms.Intents.EXTRA_IS_DEFAULT_SMS_APP, false);
-                if (DEBUG_MULTIUSER) {
-                    Log.i(LOG_TAG, "setDefaultApplicationInternal old=" + oldAppData.mPackageName);
-                }
-                context.sendBroadcastAsUser(oldAppIntent, userHandle);
-            }
-            // Notify the new sms app that it's now the default (if the new sms app has a receiver
-            // to handle the changed default sms intent).
-            if (DEBUG_MULTIUSER) {
-                Log.i(LOG_TAG, "setDefaultApplicationInternal new applicationData=" +
-                        applicationData);
-            }
-            if (applicationData.mSmsAppChangedReceiverClass != null) {
-                final Intent intent =
-                        new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED);
-                final ComponentName component = new ComponentName(applicationData.mPackageName,
-                        applicationData.mSmsAppChangedReceiverClass);
-                intent.setComponent(component);
-                intent.putExtra(Telephony.Sms.Intents.EXTRA_IS_DEFAULT_SMS_APP, true);
-                if (DEBUG_MULTIUSER) {
-                    Log.i(LOG_TAG, "setDefaultApplicationInternal new=" + packageName);
-                }
-                context.sendBroadcastAsUser(intent, userHandle);
-            }
+    /**
+     * Sends broadcasts on sms app change:
+     * {@link Intent#ACTION_DEFAULT_SMS_PACKAGE_CHANGED}
+     * {@link Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL}
+     */
+    public static void broadcastSmsAppChange(Context context,
+            UserHandle userHandle, @Nullable String oldPackage, @Nullable String newPackage) {
+        Collection<SmsApplicationData> apps = getApplicationCollection(context);
 
-            // Send an implicit broadcast for the system server.
-            // (or anyone with MONITOR_DEFAULT_SMS_PACKAGE, really.)
+        broadcastSmsAppChange(context, userHandle,
+                getApplicationForPackage(apps, oldPackage),
+                getApplicationForPackage(apps, newPackage));
+    }
+
+    private static void broadcastSmsAppChange(Context context, UserHandle userHandle,
+            @Nullable SmsApplicationData oldAppData,
+            @Nullable SmsApplicationData applicationData) {
+        if (DEBUG_MULTIUSER) {
+            Log.i(LOG_TAG, "setDefaultApplicationInternal oldAppData=" + oldAppData);
+        }
+        if (oldAppData != null && oldAppData.mSmsAppChangedReceiverClass != null) {
+            // Notify the old sms app that it's no longer the default
+            final Intent oldAppIntent =
+                    new Intent(Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED);
+            final ComponentName component = new ComponentName(oldAppData.mPackageName,
+                    oldAppData.mSmsAppChangedReceiverClass);
+            oldAppIntent.setComponent(component);
+            oldAppIntent.putExtra(Intents.EXTRA_IS_DEFAULT_SMS_APP, false);
+            if (DEBUG_MULTIUSER) {
+                Log.i(LOG_TAG, "setDefaultApplicationInternal old=" + oldAppData.mPackageName);
+            }
+            context.sendBroadcastAsUser(oldAppIntent, userHandle);
+        }
+        // Notify the new sms app that it's now the default (if the new sms app has a receiver
+        // to handle the changed default sms intent).
+        if (DEBUG_MULTIUSER) {
+            Log.i(LOG_TAG, "setDefaultApplicationInternal new applicationData=" +
+                    applicationData);
+        }
+        if (applicationData != null && applicationData.mSmsAppChangedReceiverClass != null) {
             final Intent intent =
-                    new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
-            context.sendBroadcastAsUser(intent, userHandle,
-                    permission.MONITOR_DEFAULT_SMS_PACKAGE);
+                    new Intent(Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED);
+            final ComponentName component = new ComponentName(applicationData.mPackageName,
+                    applicationData.mSmsAppChangedReceiverClass);
+            intent.setComponent(component);
+            intent.putExtra(Intents.EXTRA_IS_DEFAULT_SMS_APP, true);
+            if (DEBUG_MULTIUSER) {
+                Log.i(LOG_TAG, "setDefaultApplicationInternal new=" + applicationData.mPackageName);
+            }
+            context.sendBroadcastAsUser(intent, userHandle);
+        }
 
+        // Send an implicit broadcast for the system server.
+        // (or anyone with MONITOR_DEFAULT_SMS_PACKAGE, really.)
+        final Intent intent =
+                new Intent(Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL);
+        context.sendBroadcastAsUser(intent, userHandle,
+                permission.MONITOR_DEFAULT_SMS_PACKAGE);
+
+        if (applicationData != null) {
             MetricsLogger.action(context, MetricsEvent.ACTION_DEFAULT_SMS_APP_CHANGED,
                     applicationData.mPackageName);
         }
diff --git a/telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java b/telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java
index 14e02de..15fbc40 100644
--- a/telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java
+++ b/telephony/java/com/android/internal/telephony/SmsCbEtwsInfo.java
@@ -18,10 +18,11 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.format.Time;
 
 import com.android.internal.telephony.uicc.IccUtils;
 
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.util.Arrays;
 
 /**
@@ -165,19 +166,21 @@
         int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
 
         timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
+        // timezoneOffset is in quarter hours.
+        int timeZoneOffsetSeconds = timezoneOffset * 15 * 60;
 
-        Time time = new Time(Time.TIMEZONE_UTC);
+        LocalDateTime localDateTime = LocalDateTime.of(
+                // We only need to support years above 2000.
+                year + 2000,
+                month /* 1-12 */,
+                day,
+                hour,
+                minute,
+                second);
 
-        // We only need to support years above 2000.
-        time.year = year + 2000;
-        time.month = month - 1;
-        time.monthDay = day;
-        time.hour = hour;
-        time.minute = minute;
-        time.second = second;
-
-        // Timezone offset is in quarter hours.
-        return time.toMillis(true) - timezoneOffset * 15 * 60 * 1000;
+        long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds;
+        // Convert to milliseconds, ignore overflow.
+        return epochSeconds * 1000;
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index e8e2a3d..51c5d12 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -29,8 +29,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -364,23 +362,8 @@
      */
     private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid,
             int uid, String callingPackage, String message) {
-        // Check if the application is not preinstalled; if not then a separate setting is required
-        // to relax the check to begin flagging problems with non-preinstalled apps early.
-        boolean relax3PDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED, 0) == 1;
         boolean isPreinstalled = false;
-        // Also check if the application is a preloaded non-privileged app; if so there is a
-        // separate setting to relax the check for these apps to ensure users can relax the check
-        // for non-preinstalled or non-priv apps as needed while continuing to test the other.
-        boolean relaxNonPrivDeviceIdentifierCheck = Settings.Global.getInt(
-                context.getContentResolver(),
-                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_NON_PRIV_CHECK_RELAXED, 0) == 1;
         boolean isPrivApp = false;
-        // Similar to above support relaxing the check for privileged apps while still enforcing it
-        // for non-privileged and non-preinstalled apps.
-        boolean relaxPrivDeviceIdentifierCheck = Settings.Global.getInt(
-                context.getContentResolver(),
-                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_PRIV_CHECK_RELAXED, 0) == 1;
         ApplicationInfo callingPackageInfo = null;
         try {
             callingPackageInfo = context.getPackageManager().getApplicationInfoAsUser(
@@ -399,58 +382,40 @@
             Log.e(LOG_TAG, "Exception caught obtaining package info for package " + callingPackage,
                     e);
         }
-        // The new Q restrictions for device identifier access will be enforced for all apps with
-        // settings to individually disable the new restrictions for privileged, preloaded
-        // non-privileged, and non-preinstalled apps.
-        if (!isIdentifierCheckDisabled() && (
-                (isPrivApp && !relaxPrivDeviceIdentifierCheck)
-                        || (!isPreinstalled && !relax3PDeviceIdentifierCheck)
-                        || (isPreinstalled && !isPrivApp && !relaxNonPrivDeviceIdentifierCheck))) {
-            // The current package should only be reported in StatsLog if it has not previously been
-            // reported for the currently invoked device identifier method.
-            boolean packageReported = sReportedDeviceIDPackages.containsKey(callingPackage);
-            if (!packageReported || !sReportedDeviceIDPackages.get(callingPackage).contains(
-                    message)) {
-                Set invokedMethods;
-                if (!packageReported) {
-                    invokedMethods = new HashSet<String>();
-                    sReportedDeviceIDPackages.put(callingPackage, invokedMethods);
-                } else {
-                    invokedMethods = sReportedDeviceIDPackages.get(callingPackage);
-                }
-                invokedMethods.add(message);
-                StatsLog.write(StatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, callingPackage, message,
-                        isPreinstalled, isPrivApp);
+        // The current package should only be reported in StatsLog if it has not previously been
+        // reported for the currently invoked device identifier method.
+        boolean packageReported = sReportedDeviceIDPackages.containsKey(callingPackage);
+        if (!packageReported || !sReportedDeviceIDPackages.get(callingPackage).contains(
+                message)) {
+            Set invokedMethods;
+            if (!packageReported) {
+                invokedMethods = new HashSet<String>();
+                sReportedDeviceIDPackages.put(callingPackage, invokedMethods);
+            } else {
+                invokedMethods = sReportedDeviceIDPackages.get(callingPackage);
             }
-            Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
-                    + ":isPreinstalled=" + isPreinstalled + ":isPrivApp=" + isPrivApp);
-            // if the target SDK is pre-Q then check if the calling package would have previously
-            // had access to device identifiers.
-            if (callingPackageInfo != null && (
-                    callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q)) {
-                if (context.checkPermission(
-                        android.Manifest.permission.READ_PHONE_STATE,
-                        pid,
-                        uid) == PackageManager.PERMISSION_GRANTED) {
-                    return false;
-                }
-                if (checkCarrierPrivilegeForSubId(subId)) {
-                    return false;
-                }
-            }
-            throw new SecurityException(message + ": The user " + uid
-                    + " does not meet the requirements to access device identifiers.");
-        } else {
-            return checkReadPhoneState(context, subId, pid, uid, callingPackage, message);
+            invokedMethods.add(message);
+            StatsLog.write(StatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, callingPackage, message,
+                    isPreinstalled, isPrivApp);
         }
-    }
-
-    /**
-     * Returns true if the new device identifier access restrictions are disabled.
-     */
-    private static boolean isIdentifierCheckDisabled() {
-        return DeviceConfig.getInt(DeviceConfig.NAMESPACE_PRIVACY,
-                PROPERTY_DEVICE_IDENTIFIER_ACCESS_RESTRICTIONS_DISABLED, 0) == 1;
+        Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
+                + ":isPreinstalled=" + isPreinstalled + ":isPrivApp=" + isPrivApp);
+        // if the target SDK is pre-Q then check if the calling package would have previously
+        // had access to device identifiers.
+        if (callingPackageInfo != null && (
+                callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q)) {
+            if (context.checkPermission(
+                    android.Manifest.permission.READ_PHONE_STATE,
+                    pid,
+                    uid) == PackageManager.PERMISSION_GRANTED) {
+                return false;
+            }
+            if (checkCarrierPrivilegeForSubId(subId)) {
+                return false;
+            }
+        }
+        throw new SecurityException(message + ": The user " + uid
+                + " does not meet the requirements to access device identifiers.");
     }
 
     /**
@@ -635,26 +600,21 @@
         }
     }
 
-    /**
-     * Returns whether the provided uid has carrier privileges for any active subscription ID.
-     */
-    private static boolean checkCarrierPrivilegeForAnySubId(Context context,
-            Supplier<ITelephony> telephonySupplier, int uid) {
+    /** Returns whether the provided uid has carrier privileges for any active subscription ID. */
+    private static boolean checkCarrierPrivilegeForAnySubId(
+            Context context, Supplier<ITelephony> telephonySupplier, int uid) {
         SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
                 Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-        int[] activeSubIds = sm.getActiveSubscriptionIdList();
-        if (activeSubIds != null) {
-            for (int activeSubId : activeSubIds) {
-                if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid)
-                        == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
-                    return true;
-                }
+        int[] activeSubIds = sm.getActiveSubscriptionIdList(/* visibleOnly */ false);
+        for (int activeSubId : activeSubIds) {
+            if (getCarrierPrivilegeStatus(telephonySupplier, activeSubId, uid)
+                    == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                return true;
             }
         }
         return false;
     }
 
-
     private static int getCarrierPrivilegeStatus(
             Supplier<ITelephony> telephonySupplier, int subId, int uid) {
         ITelephony telephony = telephonySupplier.get();
diff --git a/telephony/java/com/android/internal/telephony/cdma/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/BearerData.java
index 694cc69..9e6f19f 100644
--- a/telephony/java/com/android/internal/telephony/cdma/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/BearerData.java
@@ -20,7 +20,6 @@
 import android.telephony.SmsCbCmasInfo;
 import android.telephony.cdma.CdmaSmsCbProgramData;
 import android.telephony.cdma.CdmaSmsCbProgramResults;
-import android.text.format.Time;
 import android.telephony.Rlog;
 
 import com.android.internal.telephony.GsmAlphabet;
@@ -32,8 +31,10 @@
 import com.android.internal.util.BitwiseInputStream;
 import com.android.internal.util.BitwiseOutputStream;
 
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.ArrayList;
-import java.util.TimeZone;
 
 /**
  * An object to encode and decode CDMA SMS bearer data.
@@ -228,10 +229,23 @@
     /**
      * 6-byte-field, see 3GPP2 C.S0015-B, v2, 4.5.4
      */
-    public static class TimeStamp extends Time {
+    public static class TimeStamp {
+
+        public int second;
+        public int minute;
+        public int hour;
+        public int monthDay;
+
+        /** Month [0-11] */
+        public int month;
+
+        /** Full year. For example, 1970. */
+        public int year;
+
+        private ZoneId mZoneId;
 
         public TimeStamp() {
-            super(TimeZone.getDefault().getID());   // 3GPP2 timestamps use the local timezone
+            mZoneId = ZoneId.systemDefault();   // 3GPP2 timestamps use the local timezone
         }
 
         public static TimeStamp fromByteArray(byte[] data) {
@@ -258,6 +272,14 @@
             return ts;
         }
 
+        public long toMillis() {
+            LocalDateTime localDateTime =
+                    LocalDateTime.of(year, month + 1, monthDay, hour, minute, second);
+            Instant instant = localDateTime.toInstant(mZoneId.getRules().getOffset(localDateTime));
+            return instant.toEpochMilli();
+        }
+
+
         @Override
         public String toString() {
             StringBuilder builder = new StringBuilder();
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/SmsEnvelope.java
index f73df56..de93b57 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsEnvelope.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsEnvelope.java
@@ -97,6 +97,12 @@
     public CdmaSmsSubaddress origSubaddress;
 
     /**
+     * The destination subaddress identifies the target of the SMS message.
+     * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+     */
+    public CdmaSmsSubaddress destSubaddress;
+
+    /**
      * The 6-bit bearer reply parameter is used to request the return of a
      * SMS Acknowledge Message.
      * (See 3GPP2 C.S0015-B, v2, 3.4.3.5)
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 1bd054b..e2a8913b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -16,6 +16,9 @@
 
 package com.android.internal.telephony.cdma;
 
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_IDP_STRING;
+
+import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.SystemProperties;
 import android.telephony.PhoneNumberUtils;
@@ -23,9 +26,8 @@
 import android.telephony.SmsCbMessage;
 import android.telephony.cdma.CdmaSmsCbProgramData;
 import android.telephony.Rlog;
-import android.util.Log;
 import android.text.TextUtils;
-import android.content.res.Resources;
+import android.util.Log;
 
 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
 import com.android.internal.telephony.SmsAddress;
@@ -613,10 +615,11 @@
                         }
                         addr.origBytes = data;
                         Rlog.pii(LOG_TAG, "Addr=" + addr.toString());
-                        mOriginatingAddress = addr;
-                        if (parameterId == DESTINATION_ADDRESS) {
-                            // Original address awlays indicates one sender's address for 3GPP2
-                            // Here add recipient address support along with 3GPP
+                        if (parameterId == ORIGINATING_ADDRESS) {
+                            env.origAddress = addr;
+                            mOriginatingAddress = addr;
+                        } else {
+                            env.destAddress = addr;
                             mRecipientAddress = addr;
                         }
                         break;
@@ -634,6 +637,11 @@
                             subdata[index] = convertDtmfToAscii(b);
                         }
                         subAddr.origBytes = subdata;
+                        if (parameterId == ORIGINATING_SUB_ADDRESS) {
+                            env.origSubaddress = subAddr;
+                        } else {
+                            env.destSubaddress = subAddr;
+                        }
                         break;
                     case BEARER_REPLY_OPTION:
                         dis.read(parameterData, 0, parameterLen);
@@ -663,9 +671,6 @@
         }
 
         // link the filled objects to this SMS
-        mOriginatingAddress = addr;
-        env.origAddress = addr;
-        env.origSubaddress = subAddr;
         mEnvelope = env;
         mPdu = pdu;
 
@@ -704,16 +709,16 @@
 
         if (mOriginatingAddress != null) {
             decodeSmsDisplayAddress(mOriginatingAddress);
-            if (VDBG) Rlog.v(LOG_TAG, "SMS originating address: "
-                    + mOriginatingAddress.address);
+            if (VDBG) Rlog.v(LOG_TAG, "SMS originating address: " + mOriginatingAddress.address);
         }
 
         if (mRecipientAddress != null) {
             decodeSmsDisplayAddress(mRecipientAddress);
+            if (VDBG) Rlog.v(LOG_TAG, "SMS destination address: " + mRecipientAddress.address);
         }
 
         if (mBearerData.msgCenterTimeStamp != null) {
-            mScTimeMillis = mBearerData.msgCenterTimeStamp.toMillis(true);
+            mScTimeMillis = mBearerData.msgCenterTimeStamp.toMillis();
         }
 
         if (VDBG) Rlog.d(LOG_TAG, "SMS SC timestamp: " + mScTimeMillis);
@@ -726,12 +731,12 @@
             // being reported refers to.  The MsgStatus subparameter
             // is primarily useful to indicate error conditions -- a
             // message without this subparameter is assumed to
-            // indicate successful delivery (status == 0).
-            if (! mBearerData.messageStatusSet) {
+            // indicate successful delivery.
+            if (!mBearerData.messageStatusSet) {
                 Rlog.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" +
                         (mUserData == null ? "also missing" : "does have") +
                         " userData).");
-                status = 0;
+                status = (BearerData.ERROR_NONE << 8) | BearerData.STATUS_DELIVERED;
             } else {
                 status = mBearerData.errorClass << 8;
                 status |= mBearerData.messageStatus;
@@ -750,8 +755,16 @@
     }
 
     private void decodeSmsDisplayAddress(SmsAddress addr) {
+        // PCD(Plus Code Dialing)
+        // 1) Replaces IDD(International Direct Dialing) with the '+' if address starts with it.
+        // TODO: Skip it for EF SMS(SUBMIT and DELIVER) because the IDD depends on current network?
+        // 2) Adds the '+' prefix if TON is International
+        // 3) Keeps the '+' if address starts with the '+'
+        String idd = SystemProperties.get(PROPERTY_OPERATOR_IDP_STRING, null);
         addr.address = new String(addr.origBytes);
-        if (addr.ton == CdmaSmsAddress.TON_INTERNATIONAL_OR_IP) {
+        if (!TextUtils.isEmpty(idd) && addr.address.startsWith(idd)) {
+            addr.address = "+" + addr.address.substring(idd.length());
+        } else if (addr.ton == CdmaSmsAddress.TON_INTERNATIONAL_OR_IP) {
             if (addr.address.charAt(0) != '+') {
                 addr.address = "+" + addr.address;
             }
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index a6156ff..5667387 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony.gsm;
 
 import android.telephony.PhoneNumberUtils;
-import android.text.format.Time;
 import android.telephony.Rlog;
 import android.content.res.Resources;
 import android.text.TextUtils;
@@ -33,6 +32,8 @@
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
 import java.text.ParseException;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 
 import static com.android.internal.telephony.SmsConstants.MessageClass;
 import static com.android.internal.telephony.SmsConstants.ENCODING_UNKNOWN;
@@ -722,19 +723,21 @@
             int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
 
             timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
-
-            Time time = new Time(Time.TIMEZONE_UTC);
+            // timezoneOffset is in quarter hours.
+            int timeZoneOffsetSeconds = timezoneOffset * 15 * 60;
 
             // It's 2006.  Should I really support years < 2000?
-            time.year = year >= 90 ? year + 1900 : year + 2000;
-            time.month = month - 1;
-            time.monthDay = day;
-            time.hour = hour;
-            time.minute = minute;
-            time.second = second;
-
-            // Timezone offset is in quarter hours.
-            return time.toMillis(true) - (timezoneOffset * 15 * 60 * 1000);
+            int fullYear = year >= 90 ? year + 1900 : year + 2000;
+            LocalDateTime localDateTime = LocalDateTime.of(
+                    fullYear,
+                    month /* 1-12 */,
+                    day,
+                    hour,
+                    minute,
+                    second);
+            long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds;
+            // Convert to milliseconds.
+            return epochSeconds * 1000;
         }
 
         /**
diff --git a/test-base/Android.bp b/test-base/Android.bp
index 8aa0aaf..69c296e 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -25,7 +25,7 @@
     srcs: ["src/**/*.java"],
 
     errorprone: {
-      javacflags: ["-Xep:DepAnn:ERROR"],
+        javacflags: ["-Xep:DepAnn:ERROR"],
     },
 
     hostdex: true,
@@ -96,3 +96,14 @@
     ],
 }
 
+// Make the current.txt available for use by the cts/tests/signature tests.
+// ========================================================================
+filegroup {
+    name: "android-test-base-current.txt",
+    visibility: [
+        "//cts/tests/signature/api",
+    ],
+    srcs: [
+        "api/current.txt",
+    ],
+}
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index e1d6e01..a5cd175 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -30,3 +30,15 @@
     srcs_lib_whitelist_pkgs: ["android"],
     compile_dex: true,
 }
+
+// Make the current.txt available for use by the cts/tests/signature tests.
+// ========================================================================
+filegroup {
+    name: "android-test-mock-current.txt",
+    visibility: [
+        "//cts/tests/signature/api",
+    ],
+    srcs: [
+        "api/current.txt",
+    ],
+}
diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt
index a87e2f5..cc260ac 100644
--- a/test-mock/api/test-current.txt
+++ b/test-mock/api/test-current.txt
@@ -7,6 +7,7 @@
   }
 
   @Deprecated public class MockPackageManager extends android.content.pm.PackageManager {
+    method public void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
     method public boolean arePermissionsIndividuallyControlled();
     method public String getDefaultBrowserPackageNameAsUser(int);
     method public int getInstallReason(String, android.os.UserHandle);
@@ -18,6 +19,7 @@
     method @NonNull public String getServicesSystemSharedLibraryPackageName();
     method @NonNull public String getSharedSystemSharedLibraryPackageName();
     method public void grantRuntimePermission(String, String, android.os.UserHandle);
+    method public void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
     method public void revokeRuntimePermission(String, String, android.os.UserHandle);
     method public void updatePermissionFlags(String, String, int, int, android.os.UserHandle);
   }
diff --git a/test-mock/src/android/test/mock/MockContentProvider.java b/test-mock/src/android/test/mock/MockContentProvider.java
index e9a5ff7..4d8c7d9 100644
--- a/test-mock/src/android/test/mock/MockContentProvider.java
+++ b/test-mock/src/android/test/mock/MockContentProvider.java
@@ -16,6 +16,7 @@
 
 package android.test.mock;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentProvider;
 import android.content.ContentProviderOperation;
@@ -23,6 +24,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.IContentProvider;
+import android.content.Intent;
 import android.content.OperationApplicationException;
 import android.content.pm.PathPermission;
 import android.content.pm.ProviderInfo;
@@ -154,6 +156,11 @@
                 ICancellationSignal cancellationSignal) throws RemoteException {
             return MockContentProvider.this.refresh(url, args);
         }
+
+        @Override
+        public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+            return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
+        }
     }
     private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();
 
@@ -266,6 +273,12 @@
         throw new UnsupportedOperationException("unimplemented mock method call");
     }
 
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
+
     /**
      * Returns IContentProvider which calls back same methods in this class.
      * By overriding this class, we avoid the mechanism hidden behind ContentProvider
diff --git a/test-mock/src/android/test/mock/MockIContentProvider.java b/test-mock/src/android/test/mock/MockIContentProvider.java
index fc2a464..b072d74 100644
--- a/test-mock/src/android/test/mock/MockIContentProvider.java
+++ b/test-mock/src/android/test/mock/MockIContentProvider.java
@@ -16,12 +16,14 @@
 
 package android.test.mock;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentValues;
 import android.content.EntityIterator;
 import android.content.IContentProvider;
+import android.content.Intent;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.net.Uri;
@@ -144,4 +146,10 @@
             ICancellationSignal cancellationSignal) throws RemoteException {
         throw new UnsupportedOperationException("unimplemented mock method");
     }
+
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(String callingPkg, Uri uri, int uid, int modeFlags) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
 }
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index 3521202..75f5b5a 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -40,7 +40,7 @@
         "junit.textui",
     ],
 
-    compile_dex: true
+    compile_dex: true,
 }
 
 // Build the android.test.runner-minus-junit library
@@ -86,3 +86,14 @@
     java_version: "1.8",
 }
 
+// Make the current.txt available for use by the cts/tests/signature tests.
+// ========================================================================
+filegroup {
+    name: "android-test-runner-current.txt",
+    visibility: [
+        "//cts/tests/signature/api",
+    ],
+    srcs: [
+        "api/current.txt",
+    ],
+}
diff --git a/tests/CanvasCompare/res/drawable/sunset1.jpg b/tests/CanvasCompare/res/drawable/sunset1.jpg
index 92851f3..3b4e056 100644
--- a/tests/CanvasCompare/res/drawable/sunset1.jpg
+++ b/tests/CanvasCompare/res/drawable/sunset1.jpg
Binary files differ
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
similarity index 100%
rename from tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs
rename to tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rscript
diff --git a/tests/Codegen/Android.bp b/tests/Codegen/Android.bp
new file mode 100644
index 0000000..966c560
--- /dev/null
+++ b/tests/Codegen/Android.bp
@@ -0,0 +1,25 @@
+android_test {
+    name: "CodegenTests",
+    srcs: [
+        "**/*.java",
+    ],
+
+    platform_apis: true,
+    test_suites: ["device-tests"],
+    certificate: "platform",
+
+    optimize: {
+        enabled: false,
+    },
+
+    plugins: [
+        "staledataclass-annotation-processor",
+    ],
+    static_libs: [
+        "junit",
+        "hamcrest",
+        "hamcrest-library",
+        "androidx.test.runner",
+        "androidx.test.rules",
+    ],
+}
diff --git a/tests/Codegen/AndroidManifest.xml b/tests/Codegen/AndroidManifest.xml
new file mode 100644
index 0000000..2f18550
--- /dev/null
+++ b/tests/Codegen/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ 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
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.codegentest">
+
+    <application/>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.codegentest"
+        android:label="Codegen test" />
+</manifest>
diff --git a/tests/Codegen/AndroidTest.xml b/tests/Codegen/AndroidTest.xml
new file mode 100644
index 0000000..4dbbc55
--- /dev/null
+++ b/tests/Codegen/AndroidTest.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.
+-->
+<configuration description="Runs Codegen Tests.">
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.codegentest" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/tests/Codegen/OWNERS b/tests/Codegen/OWNERS
new file mode 100644
index 0000000..da723b3
--- /dev/null
+++ b/tests/Codegen/OWNERS
@@ -0,0 +1 @@
+eugenesusla@google.com
\ No newline at end of file
diff --git a/tests/Codegen/runTest.sh b/tests/Codegen/runTest.sh
new file mode 100755
index 0000000..fe3adf9
--- /dev/null
+++ b/tests/Codegen/runTest.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+if [[ "$0" = *"/Codegen/runTest.sh" ]]; then
+	#running in subshell - print code to eval and exit
+	echo "source $0"
+else
+    function header_and_eval() {
+        printf "\n[ $* ]\n" 1>&2
+        eval "$@"
+        return $?
+    }
+
+    header_and_eval m -j16 codegen && \
+        header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java && \
+        cd $ANDROID_BUILD_TOP &&
+        header_and_eval mmma -j16 frameworks/base/tests/Codegen && \
+        header_and_eval adb install -r -t $ANDROID_PRODUCT_OUT/testcases/CodegenTests/arm64/CodegenTests.apk && \
+        # header_and_eval adb shell am set-debug-app -w com.android.codegentest && \
+        header_and_eval adb shell am instrument -w -e package com.android.codegentest com.android.codegentest/androidx.test.runner.AndroidJUnitRunner
+
+        exitCode=$?
+
+        # header_and_eval adb shell am clear-debug-app
+
+        return $exitCode
+fi
\ No newline at end of file
diff --git a/tests/Codegen/src/com/android/codegentest/DateParcelling.java b/tests/Codegen/src/com/android/codegentest/DateParcelling.java
new file mode 100644
index 0000000..b0b00d0
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/DateParcelling.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.codegentest;
+
+import android.os.Parcel;
+
+import com.android.internal.util.Parcelling;
+
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Sample {@link Parcelling} implementation for {@link Date}.
+ *
+ * See {@link SampleDataClass#mDate} for usage.
+ * See {@link SampleDataClass#writeToParcel} + {@link SampleDataClass#sParcellingForDate}
+ * for resulting generated code.
+ *
+ * Ignore {@link #sInstanceCount} - used for testing.
+ */
+public class DateParcelling implements Parcelling<Date> {
+
+    static AtomicInteger sInstanceCount = new AtomicInteger(0);
+
+    public DateParcelling() {
+        sInstanceCount.getAndIncrement();
+    }
+
+    @Override
+    public void parcel(Date item, Parcel dest, int parcelFlags) {
+        dest.writeLong(item.getTime());
+    }
+
+    @Override
+    public Date unparcel(Parcel source) {
+        return new Date(source.readLong());
+    }
+}
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.aidl b/tests/Codegen/src/com/android/codegentest/SampleDataClass.aidl
new file mode 100644
index 0000000..f14d47c
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.aidl
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.codegentest;
+
+parcelable SampleDataClass;
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
new file mode 100644
index 0000000..03127ec
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -0,0 +1,1542 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.codegentest;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.Size;
+import android.annotation.StringDef;
+import android.annotation.StringRes;
+import android.annotation.UserIdInt;
+import android.net.LinkAddress;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.internal.util.AnnotationValidations;
+import com.android.internal.util.DataClass;
+import com.android.internal.util.DataClass.Each;
+import com.android.internal.util.Parcelling;
+import com.android.internal.util.Preconditions;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * Sample data class, showing off various code generation features.
+ *
+ * See javadoc on non-generated code for the explanation of the various features.
+ *
+ * See {@link SampleDataClassTest} for various invariants the generated code is expected to hold.
+ */
+@DataClass(
+//        genParcelable = true, // implied by `implements Parcelable`
+//        genAidl = true,       // implied by `implements Parcelable`
+//        genGetters = true,    // on by default
+//        genConstDefs = true,  // implied by presence of constants with common prefix
+        genEqualsHashCode = true,
+        genBuilder = true,
+        genToString = true,
+        genForEachField = true,
+        genConstructor = true   // on by default but normally suppressed by genBuilder
+)
+public final class SampleDataClass implements Parcelable {
+
+    /**
+     * For any group of {@link int} or {@link String} constants like these, a corresponding
+     * {@link IntDef}/{@link StringDef} will get generated, with name based on common prefix
+     * by default.
+     *
+     * When {@link #SampleDataClass constructing} an instance, fields annotated with these
+     * annotations get automatically validated, with only provided constants being a valid value.
+     *
+     * @see StateName, the generated {@link StringDef}
+     * @see #mStateName annotated with {@link StateName}
+     */
+    public static final String STATE_NAME_UNDEFINED = "?";
+    public static final String STATE_NAME_ON = "on";
+    public static final String STATE_NAME_OFF = "off";
+
+    /**
+     * Additionally, for any generated {@link IntDef} a corresponding static
+     * *ToString method will be also generated, and used in {@link #toString()}.
+     *
+     * @see #stateToString(int)
+     * @see #toString()
+     * @see State
+     */
+    public static final int STATE_UNDEFINED = -1;
+    public static final int STATE_ON = 1;
+    public static final int STATE_OFF = 0;
+
+    /**
+     * {@link IntDef}s with values specified in hex("0x...") are considered to be
+     * {@link IntDef#flag flags}, while ones specified with regular int literals are considered
+     * not to be flags.
+     *
+     * This affects their string representation, e.g. see the difference in
+     * {@link #requestFlagsToString} vs {@link #stateToString}.
+     *
+     * This also affects the validation logic when {@link #SampleDataClass constructing}
+     * an instance, with any flag combination("|") being valid.
+     *
+     * You can customize the name of the generated {@link IntDef}/{@link StringDef} annotation
+     * by annotating each constant with the desired name before running the generation.
+     *
+     * Here the annotation is named {@link RequestFlags} instead of the default {@code Flags}.
+     */
+    public static final @RequestFlags int FLAG_MANUAL_REQUEST = 0x1;
+    public static final @RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST = 0x2;
+    public static final @RequestFlags int FLAG_AUGMENTED_REQUEST = 0x80000000;
+
+
+    /**
+     * Any property javadoc should go onto the field, and will be copied where appropriate,
+     * including getters, constructor parameters, builder setters, etc.
+     *
+     * <p>
+     * This allows to avoid the burden of maintaining copies of the same documentation
+     * pieces in multiple places for each field.
+     */
+    private int mNum;
+    /**
+     * Various javadoc features should work as expected when copied, e.g {@code code},
+     * {@link #mName links}, <a href="https://google.com">html links</a>, etc.
+     *
+     * @see #mNum2 ..and so should blocks at the bottom, e.g. {@code @see} blocks.
+     */
+    private int mNum2;
+    /**
+     * {@code @hide} javadoc annotation is also propagated, which can be used to adjust the
+     * desired public API surface.
+     *
+     * @see #getNum4() is hidden
+     * @see Builder#setNum4(int) also hidden
+     * @hide
+     */
+    private int mNum4;
+
+    /**
+     * {@link Nullable} fields are considered optional and will not throw an exception if omitted
+     * (or set to null) when creating an instance either via a {@link Builder} or constructor.
+     */
+    private @Nullable String mName;
+    /**
+     * Fields with default value expressions ("mFoo = ...") are also optional, and are automatically
+     * initialized to the provided default expression, unless explicitly set.
+     */
+    private String mName2 = "Bob";
+    /**
+     * Fields without {@link Nullable} annotation or default value are considered required.
+     *
+     * {@link NonNull} annotation is recommended on such non-primitive fields for documentation.
+     */
+    private @NonNull String mName4;
+
+    /**
+     * For parcelling, any field type supported by {@link Parcel} is supported out of the box.
+     * E.g. {@link Parcelable} subclasses, {@link String}, {@link int}, {@link boolean}, etc.
+     */
+    private AccessibilityNodeInfo mOtherParcelable = null;
+    /**
+     * Additionally, support for parcelling other types can be added by implementing a
+     * {@link Parcelling}, and referencing it in the {@link DataClass.ParcelWith} field annotation.
+     *
+     * @see DateParcelling an example {@link Parcelling} implementation
+     */
+    @DataClass.ParcelWith(DateParcelling.class)
+    private Date mDate = new Date(42 * 42);
+    /**
+     * If a {@link Parcelling} is fairly common, consider putting it in {@link Parcelling.BuiltIn}
+     * to encourage its reuse.
+     */
+    @DataClass.ParcelWith(Parcelling.BuiltIn.ForPattern.class)
+    private Pattern mPattern = Pattern.compile("");
+
+    /**
+     * For lists, when using a {@link Builder}, other than a regular
+     * {@link Builder#setLinkAddresses2(List) setter}, and additional
+     * {@link Builder#addLinkAddresses2(LinkAddress) add} method is generated for convenience.
+     */
+    private List<LinkAddress> mLinkAddresses2 = new ArrayList<>();
+    /**
+     * For aesthetics, you may want to consider providing a singular version of the plural field
+     * name, which would be used for the {@link #mLinkAddresses2 above mentioned} "add" method.
+     *
+     * @see Builder#addLinkAddress(LinkAddress)
+     */
+    @DataClass.PluralOf("linkAddress")
+    private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<>();
+    /**
+     * For array fields, when using a {@link Builder}, vararg argument format is used for
+     * convenience.
+     *
+     * @see Builder#setLinkAddresses4(LinkAddress...)
+     */
+    private @Nullable LinkAddress[] mLinkAddresses4 = null;
+    /**
+     * For boolean fields, when using a {@link Builder}, in addition to a regular setter, methods
+     * like {@link Builder#markActive()} and {@link Builder#markNotActive()} are generated.
+     */
+    private boolean mActive = true;
+
+    /**
+     * {@link IntDef}/{@link StringDef}-annotated fields propagate the annotation to
+     * getter/constructor/setter/builder parameters, making for a nicer api.
+     *
+     * @see #getStateName
+     * @see Builder#setStateName
+     */
+    private @StateName String mStateName = STATE_NAME_UNDEFINED;
+    /**
+     * Fields annotated with {@link IntDef} annotations also get a proper {@link #toString()} value.
+     */
+    private @RequestFlags int mFlags;
+    /**
+     * Above is true for both {@link IntDef#flag flags} and enum-like {@link IntDef}s
+     */
+    private @State int mState = STATE_UNDEFINED;
+
+
+    /**
+     * Making a field public will suppress getter generation in favor of accessing it directly.
+     */
+    public CharSequence charSeq = "";
+    /**
+     * Final fields suppress generating a setter (when setters are requested).
+     */
+    private final LinkAddress[] mLinkAddresses5;
+    /**
+     * Transient fields are completely ignored and can be used for caching.
+     */
+    private transient LinkAddress[] mLinkAddresses6;
+    /**
+     * When using transient fields for caching it's often also a good idea to initialize them
+     * lazily.
+     *
+     * You can declare a special method like {@link #lazyInitTmpStorage()}, to let the
+     * {@link #getTmpStorage getter} lazily-initialize the value on demand.
+     */
+    transient int[] mTmpStorage;
+    private int[] lazyInitTmpStorage() {
+        return new int[100];
+    }
+
+    /**
+     * Fields with certain annotations are automatically validated in constructor
+     *
+     * You can see overloads in {@link AnnotationValidations} for a list of currently
+     * supported ones.
+     *
+     * You can also extend support to your custom annotations by creating another corresponding
+     * overloads like
+     * {@link AnnotationValidations#validate(Class, UserIdInt, int)}.
+     *
+     * @see #SampleDataClass
+     */
+    private @StringRes int mStringRes = 0;
+    /**
+     * Validation annotations may also have parameters.
+     *
+     * Parameter values will be supplied to validation method as name-value pairs.
+     *
+     * @see AnnotationValidations#validate(Class, Size, int, String, int, String, int)
+     */
+    private @android.annotation.IntRange(from = 0, to = 4) int mLimited = 3;
+    /**
+     * Unnamed validation annotation parameter gets supplied to the validating method named as
+     * "value".
+     *
+     * Validation annotations following {@link Each} annotation, will be applied for each
+     * array/collection element instead.
+     *
+     * @see AnnotationValidations#validate(Class, Size, int, String, int)
+     */
+    @Size(2)
+    @Each @FloatRange(from = 0f)
+    private float[] mCoords = new float[] {0f, 0f};
+
+
+    /**
+     * Manually declaring any method that would otherwise be generated suppresses its generation,
+     * allowing for fine-grained overrides of the generated behavior.
+     */
+    public LinkAddress[] getLinkAddresses4() {
+        //Suppress autogen
+        return null;
+    }
+
+    /**
+     * Additionally, some methods like {@link #equals}, {@link #hashCode}, {@link #toString},
+     * {@link #writeToParcel}, {@link Parcelable.Creator#createFromParcel} allow you to define
+     * special methods to override their behavior on a per-field basis.
+     *
+     * See the generateted methods' descriptions for the detailed instructions of what the method
+     * signatures for such methods are expected to be.
+     *
+     * Here we use this to "fix" {@link Pattern} not implementing equals/hashCode.
+     *
+     * @see #equals
+     * @see #hashCode
+     */
+    private boolean patternEquals(Pattern other) {
+        return Objects.equals(mPattern.pattern(), other.pattern());
+    }
+    private int patternHashCode() {
+        return Objects.hashCode(mPattern.pattern());
+    }
+
+    /**
+     * Similarly, {@link #onConstructed()}, if defined, gets called at the end of constructing an
+     * instance.
+     *
+     * At this point all fields should be in place, so this is the right place to put any custom
+     * validation logic.
+     */
+    private void onConstructed() {
+        Preconditions.checkState(mNum2 == mNum4);
+    }
+
+    /**
+     * {@link DataClass#genForEachField} can be used to generate a generic {@link #forEachField}
+     * utility, which can be used for various use-cases not covered out of the box.
+     * Callback passed to {@link #forEachField} will be called once per each property with its name
+     * and value.
+     *
+     * Here for example it's used to implement a typical dump method.
+     *
+     * Note that there are 2 {@link #forEachField} versions provided, one that treats each field
+     * value as an {@link Object}, thus boxing primitives if any, and one that additionally takes
+     * specialized callbacks for particular primitive field types used in given class.
+     *
+     * Some primitives like {@link Boolean}s and {@link Integer}s within [-128, 127] don't allocate
+     * when boxed, so it's up to you to decide which one to use for a given use-case.
+     */
+    public void dump(PrintWriter pw) {
+        forEachField((self, name, value) -> {
+            pw.append("  ").append(name).append(": ").append(String.valueOf(value)).append('\n');
+        });
+    }
+
+
+
+    // Code below generated by codegen v0.0.1.
+    //   on Jul 17, 2019, 5:10:26 PM PDT
+    //
+    // DO NOT MODIFY!
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+    //
+    // CHECKSTYLE:OFF Generated code
+
+    @IntDef(prefix = "STATE_", value = {
+        STATE_UNDEFINED,
+        STATE_ON,
+        STATE_OFF
+    })
+    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface State {}
+
+    @DataClass.Generated.Member
+    public static String stateToString(@State int value) {
+        switch (value) {
+            case STATE_UNDEFINED:
+                    return "STATE_UNDEFINED";
+            case STATE_ON:
+                    return "STATE_ON";
+            case STATE_OFF:
+                    return "STATE_OFF";
+            default: return Integer.toHexString(value);
+        }
+    }
+
+    @IntDef(flag = true, prefix = "FLAG_", value = {
+        FLAG_MANUAL_REQUEST,
+        FLAG_COMPATIBILITY_MODE_REQUEST,
+        FLAG_AUGMENTED_REQUEST
+    })
+    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface RequestFlags {}
+
+    @DataClass.Generated.Member
+    public static String requestFlagsToString(@RequestFlags int value) {
+        return com.android.internal.util.BitUtils.flagsToString(
+                value, SampleDataClass::singleRequestFlagsToString);
+    }
+
+    @DataClass.Generated.Member
+    static String singleRequestFlagsToString(@RequestFlags int value) {
+        switch (value) {
+            case FLAG_MANUAL_REQUEST:
+                    return "FLAG_MANUAL_REQUEST";
+            case FLAG_COMPATIBILITY_MODE_REQUEST:
+                    return "FLAG_COMPATIBILITY_MODE_REQUEST";
+            case FLAG_AUGMENTED_REQUEST:
+                    return "FLAG_AUGMENTED_REQUEST";
+            default: return Integer.toHexString(value);
+        }
+    }
+
+    @StringDef(prefix = "STATE_NAME_", value = {
+        STATE_NAME_UNDEFINED,
+        STATE_NAME_ON,
+        STATE_NAME_OFF
+    })
+    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface StateName {}
+
+    @DataClass.Generated(
+            time = 1563408627046L,
+            codegenVersion = "0.0.1",
+            sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
+            inputSignatures = "public static final  java.lang.String STATE_NAME_UNDEFINED\npublic static final  java.lang.String STATE_NAME_ON\npublic static final  java.lang.String STATE_NAME_OFF\npublic static final  int STATE_UNDEFINED\npublic static final  int STATE_ON\npublic static final  int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate  int mNum\nprivate  int mNum2\nprivate  int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate  java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate  android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.DateParcelling.class) java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) java.util.regex.Pattern mPattern\nprivate  java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate  boolean mActive\nprivate @com.android.codegentest.SampleDataClass.StateName java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic  java.lang.CharSequence charSeq\nprivate final  android.net.LinkAddress[] mLinkAddresses5\nprivate transient  android.net.LinkAddress[] mLinkAddresses6\ntransient  int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=4L) int mLimited\nprivate @android.annotation.Size(2L) @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate  int[] lazyInitTmpStorage()\npublic  android.net.LinkAddress[] getLinkAddresses4()\nprivate  boolean patternEquals(java.util.regex.Pattern)\nprivate  int patternHashCode()\nprivate  void onConstructed()\npublic  void dump(java.io.PrintWriter)")
+
+/**
+     * @param num
+     *   Any property javadoc should go onto the field, and will be copied where appropriate,
+     *   including getters, constructor parameters, builder setters, etc.
+     *
+     *   <p>
+     *   This allows to avoid the burden of maintaining copies of the same documentation
+     *   pieces in multiple places for each field.
+     * @param num2
+     *   Various javadoc features should work as expected when copied, e.g {@code code},
+     *   {@link #mName links}, <a href="https://google.com">html links</a>, etc.
+     * @param num4
+     *   {@code @hide} javadoc annotation is also propagated, which can be used to adjust the
+     *   desired public API surface.
+     * @param name
+     *   {@link Nullable} fields are considered optional and will not throw an exception if omitted
+     *   (or set to null) when creating an instance either via a {@link Builder} or constructor.
+     * @param name2
+     *   Fields with default value expressions ("mFoo = ...") are also optional, and are automatically
+     *   initialized to the provided default expression, unless explicitly set.
+     * @param name4
+     *   Fields without {@link Nullable} annotation or default value are considered required.
+     *
+     *   {@link NonNull} annotation is recommended on such non-primitive fields for documentation.
+     * @param otherParcelable
+     *   For parcelling, any field type supported by {@link Parcel} is supported out of the box.
+     *   E.g. {@link Parcelable} subclasses, {@link String}, {@link int}, {@link boolean}, etc.
+     * @param date
+     *   Additionally, support for parcelling other types can be added by implementing a
+     *   {@link Parcelling}, and referencing it in the {@link DataClass.ParcelWith} field annotation.
+     * @param pattern
+     *   If a {@link Parcelling} is fairly common, consider putting it in {@link Parcelling.BuiltIn}
+     *   to encourage its reuse.
+     * @param linkAddresses2
+     *   For lists, when using a {@link Builder}, other than a regular
+     *   {@link Builder#setLinkAddresses2(List) setter}, and additional
+     *   {@link Builder#addLinkAddresses2(LinkAddress) add} method is generated for convenience.
+     * @param linkAddresses
+     *   For aesthetics, you may want to consider providing a singular version of the plural field
+     *   name, which would be used for the {@link #mLinkAddresses2 above mentioned} "add" method.
+     * @param linkAddresses4
+     *   For array fields, when using a {@link Builder}, vararg argument format is used for
+     *   convenience.
+     * @param active
+     *   For boolean fields, when using a {@link Builder}, in addition to a regular setter, methods
+     *   like {@link Builder#markActive()} and {@link Builder#markNotActive()} are generated.
+     * @param stateName
+     *   {@link IntDef}/{@link StringDef}-annotated fields propagate the annotation to
+     *   getter/constructor/setter/builder parameters, making for a nicer api.
+     * @param flags
+     *   Fields annotated with {@link IntDef} annotations also get a proper {@link #toString()} value.
+     * @param state
+     *   Above is true for both {@link IntDef#flag flags} and enum-like {@link IntDef}s
+     * @param charSeq
+     *   Making a field public will suppress getter generation in favor of accessing it directly.
+     * @param linkAddresses5
+     *   Final fields suppress generating a setter (when setters are requested).
+     * @param stringRes
+     *   Fields with certain annotations are automatically validated in constructor
+     *
+     *   You can see overloads in {@link AnnotationValidations} for a list of currently
+     *   supported ones.
+     *
+     *   You can also extend support to your custom annotations by creating another corresponding
+     *   overloads like
+     *   {@link AnnotationValidations#validate(Class, UserIdInt, int)}.
+     * @param limited
+     *   Validation annotations may also have parameters.
+     *
+     *   Parameter values will be supplied to validation method as name-value pairs.
+     * @param coords
+     *   Unnamed validation annotation parameter gets supplied to the validating method named as
+     *   "value".
+     *
+     *   Validation annotations following {@link Each} annotation, will be applied for each
+     *   array/collection element instead.
+     */
+    @DataClass.Generated.Member
+    public SampleDataClass(
+            int num,
+            int num2,
+            int num4,
+            @Nullable String name,
+            String name2,
+            @NonNull String name4,
+            AccessibilityNodeInfo otherParcelable,
+            Date date,
+            Pattern pattern,
+            List<LinkAddress> linkAddresses2,
+            ArrayList<LinkAddress> linkAddresses,
+            @Nullable LinkAddress[] linkAddresses4,
+            boolean active,
+            @StateName String stateName,
+            @RequestFlags int flags,
+            @State int state,
+            CharSequence charSeq,
+            LinkAddress[] linkAddresses5,
+            @StringRes int stringRes,
+            @android.annotation.IntRange(from = 0, to = 4) int limited,
+            @Size(2) @FloatRange(from = 0f) float[] coords) {
+        this.mNum = num;
+        this.mNum2 = num2;
+        this.mNum4 = num4;
+        this.mName = name;
+        this.mName2 = name2;
+        this.mName4 = Preconditions.checkNotNull(name4);
+        this.mOtherParcelable = otherParcelable;
+        this.mDate = date;
+        this.mPattern = pattern;
+        this.mLinkAddresses2 = linkAddresses2;
+        this.mLinkAddresses = linkAddresses;
+        this.mLinkAddresses4 = linkAddresses4;
+        this.mActive = active;
+        this.mStateName = stateName;
+        this.mFlags = flags;
+        this.mState = state;
+        this.charSeq = charSeq;
+        this.mLinkAddresses5 = linkAddresses5;
+        this.mStringRes = stringRes;
+        this.mLimited = limited;
+        this.mCoords = coords;
+        AnnotationValidations.validate(
+                NonNull.class, null, mName4);
+
+        //noinspection PointlessBooleanExpression
+        if (true
+                && !(Objects.equals(mStateName, STATE_NAME_UNDEFINED))
+                && !(Objects.equals(mStateName, STATE_NAME_ON))
+                && !(Objects.equals(mStateName, STATE_NAME_OFF))) {
+            throw new java.lang.IllegalArgumentException(
+                    "stateName was " + mStateName + " but must be one of: "
+                            + "STATE_NAME_UNDEFINED(" + STATE_NAME_UNDEFINED + "), "
+                            + "STATE_NAME_ON(" + STATE_NAME_ON + "), "
+                            + "STATE_NAME_OFF(" + STATE_NAME_OFF + ")");
+        }
+
+
+        //noinspection PointlessBitwiseExpression
+        Preconditions.checkFlagsArgument(
+                mFlags, 0
+                        | FLAG_MANUAL_REQUEST
+                        | FLAG_COMPATIBILITY_MODE_REQUEST
+                        | FLAG_AUGMENTED_REQUEST);
+
+        //noinspection PointlessBooleanExpression
+        if (true
+                && !(mState == STATE_UNDEFINED)
+                && !(mState == STATE_ON)
+                && !(mState == STATE_OFF)) {
+            throw new java.lang.IllegalArgumentException(
+                    "state was " + mState + " but must be one of: "
+                            + "STATE_UNDEFINED(" + STATE_UNDEFINED + "), "
+                            + "STATE_ON(" + STATE_ON + "), "
+                            + "STATE_OFF(" + STATE_OFF + ")");
+        }
+
+        AnnotationValidations.validate(
+                StringRes.class, null, mStringRes);
+        AnnotationValidations.validate(
+                android.annotation.IntRange.class, null, mLimited,
+                "from", 0,
+                "to", 4);
+        AnnotationValidations.validate(
+                Size.class, null, mCoords.length,
+                "value", 2);
+        int coordsSize = mCoords.length;
+        for (int i = 0; i < coordsSize; i++) {
+            AnnotationValidations.validate(
+                    FloatRange.class, null, mCoords[i],
+                    "from", 0f);
+        }
+
+
+        onConstructed();
+    }
+
+    /**
+     * Any property javadoc should go onto the field, and will be copied where appropriate,
+     * including getters, constructor parameters, builder setters, etc.
+     *
+     * <p>
+     * This allows to avoid the burden of maintaining copies of the same documentation
+     * pieces in multiple places for each field.
+     */
+    @DataClass.Generated.Member
+    public int getNum() {
+        return mNum;
+    }
+
+    /**
+     * Various javadoc features should work as expected when copied, e.g {@code code},
+     * {@link #mName links}, <a href="https://google.com">html links</a>, etc.
+     *
+     * @see #mNum2 ..and so should blocks at the bottom, e.g. {@code @see} blocks.
+     */
+    @DataClass.Generated.Member
+    public int getNum2() {
+        return mNum2;
+    }
+
+    /**
+     * {@code @hide} javadoc annotation is also propagated, which can be used to adjust the
+     * desired public API surface.
+     *
+     * @see #getNum4() is hidden
+     * @see Builder#setNum4(int) also hidden
+     * @hide
+     */
+    @DataClass.Generated.Member
+    public int getNum4() {
+        return mNum4;
+    }
+
+    /**
+     * {@link Nullable} fields are considered optional and will not throw an exception if omitted
+     * (or set to null) when creating an instance either via a {@link Builder} or constructor.
+     */
+    @DataClass.Generated.Member
+    public @Nullable String getName() {
+        return mName;
+    }
+
+    /**
+     * Fields with default value expressions ("mFoo = ...") are also optional, and are automatically
+     * initialized to the provided default expression, unless explicitly set.
+     */
+    @DataClass.Generated.Member
+    public String getName2() {
+        return mName2;
+    }
+
+    /**
+     * Fields without {@link Nullable} annotation or default value are considered required.
+     *
+     * {@link NonNull} annotation is recommended on such non-primitive fields for documentation.
+     */
+    @DataClass.Generated.Member
+    public @NonNull String getName4() {
+        return mName4;
+    }
+
+    /**
+     * For parcelling, any field type supported by {@link Parcel} is supported out of the box.
+     * E.g. {@link Parcelable} subclasses, {@link String}, {@link int}, {@link boolean}, etc.
+     */
+    @DataClass.Generated.Member
+    public AccessibilityNodeInfo getOtherParcelable() {
+        return mOtherParcelable;
+    }
+
+    /**
+     * Additionally, support for parcelling other types can be added by implementing a
+     * {@link Parcelling}, and referencing it in the {@link DataClass.ParcelWith} field annotation.
+     *
+     * @see DateParcelling an example {@link Parcelling} implementation
+     */
+    @DataClass.Generated.Member
+    public Date getDate() {
+        return mDate;
+    }
+
+    /**
+     * If a {@link Parcelling} is fairly common, consider putting it in {@link Parcelling.BuiltIn}
+     * to encourage its reuse.
+     */
+    @DataClass.Generated.Member
+    public Pattern getPattern() {
+        return mPattern;
+    }
+
+    /**
+     * For lists, when using a {@link Builder}, other than a regular
+     * {@link Builder#setLinkAddresses2(List) setter}, and additional
+     * {@link Builder#addLinkAddresses2(LinkAddress) add} method is generated for convenience.
+     */
+    @DataClass.Generated.Member
+    public List<LinkAddress> getLinkAddresses2() {
+        return mLinkAddresses2;
+    }
+
+    /**
+     * For aesthetics, you may want to consider providing a singular version of the plural field
+     * name, which would be used for the {@link #mLinkAddresses2 above mentioned} "add" method.
+     *
+     * @see Builder#addLinkAddress(LinkAddress)
+     */
+    @DataClass.Generated.Member
+    public ArrayList<LinkAddress> getLinkAddresses() {
+        return mLinkAddresses;
+    }
+
+    /**
+     * For boolean fields, when using a {@link Builder}, in addition to a regular setter, methods
+     * like {@link Builder#markActive()} and {@link Builder#markNotActive()} are generated.
+     */
+    @DataClass.Generated.Member
+    public boolean isActive() {
+        return mActive;
+    }
+
+    /**
+     * {@link IntDef}/{@link StringDef}-annotated fields propagate the annotation to
+     * getter/constructor/setter/builder parameters, making for a nicer api.
+     *
+     * @see #getStateName
+     * @see Builder#setStateName
+     */
+    @DataClass.Generated.Member
+    public @StateName String getStateName() {
+        return mStateName;
+    }
+
+    /**
+     * Fields annotated with {@link IntDef} annotations also get a proper {@link #toString()} value.
+     */
+    @DataClass.Generated.Member
+    public @RequestFlags int getFlags() {
+        return mFlags;
+    }
+
+    /**
+     * Above is true for both {@link IntDef#flag flags} and enum-like {@link IntDef}s
+     */
+    @DataClass.Generated.Member
+    public @State int getState() {
+        return mState;
+    }
+
+    /**
+     * Final fields suppress generating a setter (when setters are requested).
+     */
+    @DataClass.Generated.Member
+    public LinkAddress[] getLinkAddresses5() {
+        return mLinkAddresses5;
+    }
+
+    /**
+     * Fields with certain annotations are automatically validated in constructor
+     *
+     * You can see overloads in {@link AnnotationValidations} for a list of currently
+     * supported ones.
+     *
+     * You can also extend support to your custom annotations by creating another corresponding
+     * overloads like
+     * {@link AnnotationValidations#validate(Class, UserIdInt, int)}.
+     *
+     * @see #SampleDataClass
+     */
+    @DataClass.Generated.Member
+    public @StringRes int getStringRes() {
+        return mStringRes;
+    }
+
+    /**
+     * Validation annotations may also have parameters.
+     *
+     * Parameter values will be supplied to validation method as name-value pairs.
+     *
+     * @see AnnotationValidations#validate(Class, Size, int, String, int, String, int)
+     */
+    @DataClass.Generated.Member
+    public @android.annotation.IntRange(from = 0, to = 4) int getLimited() {
+        return mLimited;
+    }
+
+    /**
+     * Unnamed validation annotation parameter gets supplied to the validating method named as
+     * "value".
+     *
+     * Validation annotations following {@link Each} annotation, will be applied for each
+     * array/collection element instead.
+     *
+     * @see AnnotationValidations#validate(Class, Size, int, String, int)
+     */
+    @DataClass.Generated.Member
+    public @Size(2) @FloatRange(from = 0f) float[] getCoords() {
+        return mCoords;
+    }
+
+    /**
+     * When using transient fields for caching it's often also a good idea to initialize them
+     * lazily.
+     *
+     * You can declare a special method like {@link #lazyInitTmpStorage()}, to let the
+     * {@link #getTmpStorage getter} lazily-initialize the value on demand.
+     */
+    @DataClass.Generated.Member
+    public int[] getTmpStorage() {
+        int[] tmpStorage = mTmpStorage;
+        if (tmpStorage == null) {
+            // You can mark field as volatile for thread-safe double-check init
+            tmpStorage = mTmpStorage = lazyInitTmpStorage();
+        }
+        return tmpStorage;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "SampleDataClass { " +
+                "num = " + mNum + ", " +
+                "num2 = " + mNum2 + ", " +
+                "num4 = " + mNum4 + ", " +
+                "name = " + mName + ", " +
+                "name2 = " + mName2 + ", " +
+                "name4 = " + mName4 + ", " +
+                "otherParcelable = " + mOtherParcelable + ", " +
+                "date = " + mDate + ", " +
+                "pattern = " + mPattern + ", " +
+                "linkAddresses2 = " + mLinkAddresses2 + ", " +
+                "linkAddresses = " + mLinkAddresses + ", " +
+                "linkAddresses4 = " + java.util.Arrays.toString(mLinkAddresses4) + ", " +
+                "active = " + mActive + ", " +
+                "stateName = " + mStateName + ", " +
+                "flags = " + requestFlagsToString(mFlags) + ", " +
+                "state = " + stateToString(mState) + ", " +
+                "charSeq = " + charSeq + ", " +
+                "linkAddresses5 = " + java.util.Arrays.toString(mLinkAddresses5) + ", " +
+                "stringRes = " + mStringRes + ", " +
+                "limited = " + mLimited + ", " +
+                "coords = " + java.util.Arrays.toString(mCoords) +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public boolean equals(Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(SampleDataClass other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        SampleDataClass that = (SampleDataClass) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && mNum == that.mNum
+                && mNum2 == that.mNum2
+                && mNum4 == that.mNum4
+                && Objects.equals(mName, that.mName)
+                && Objects.equals(mName2, that.mName2)
+                && Objects.equals(mName4, that.mName4)
+                && Objects.equals(mOtherParcelable, that.mOtherParcelable)
+                && Objects.equals(mDate, that.mDate)
+                && patternEquals(that.mPattern)
+                && Objects.equals(mLinkAddresses2, that.mLinkAddresses2)
+                && Objects.equals(mLinkAddresses, that.mLinkAddresses)
+                && java.util.Arrays.equals(mLinkAddresses4, that.mLinkAddresses4)
+                && mActive == that.mActive
+                && Objects.equals(mStateName, that.mStateName)
+                && mFlags == that.mFlags
+                && mState == that.mState
+                && Objects.equals(charSeq, that.charSeq)
+                && java.util.Arrays.equals(mLinkAddresses5, that.mLinkAddresses5)
+                && mStringRes == that.mStringRes
+                && mLimited == that.mLimited
+                && java.util.Arrays.equals(mCoords, that.mCoords);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + mNum;
+        _hash = 31 * _hash + mNum2;
+        _hash = 31 * _hash + mNum4;
+        _hash = 31 * _hash + Objects.hashCode(mName);
+        _hash = 31 * _hash + Objects.hashCode(mName2);
+        _hash = 31 * _hash + Objects.hashCode(mName4);
+        _hash = 31 * _hash + Objects.hashCode(mOtherParcelable);
+        _hash = 31 * _hash + Objects.hashCode(mDate);
+        _hash = 31 * _hash + patternHashCode();
+        _hash = 31 * _hash + Objects.hashCode(mLinkAddresses2);
+        _hash = 31 * _hash + Objects.hashCode(mLinkAddresses);
+        _hash = 31 * _hash + java.util.Arrays.hashCode(mLinkAddresses4);
+        _hash = 31 * _hash + Boolean.hashCode(mActive);
+        _hash = 31 * _hash + Objects.hashCode(mStateName);
+        _hash = 31 * _hash + mFlags;
+        _hash = 31 * _hash + mState;
+        _hash = 31 * _hash + Objects.hashCode(charSeq);
+        _hash = 31 * _hash + java.util.Arrays.hashCode(mLinkAddresses5);
+        _hash = 31 * _hash + mStringRes;
+        _hash = 31 * _hash + mLimited;
+        _hash = 31 * _hash + java.util.Arrays.hashCode(mCoords);
+        return _hash;
+    }
+
+    @DataClass.Generated.Member
+    void forEachField(
+            DataClass.PerIntFieldAction<SampleDataClass> actionInt,
+            DataClass.PerObjectFieldAction<SampleDataClass> actionObject) {
+        actionInt.acceptInt(this, "num", mNum);
+        actionInt.acceptInt(this, "num2", mNum2);
+        actionInt.acceptInt(this, "num4", mNum4);
+        actionObject.acceptObject(this, "name", mName);
+        actionObject.acceptObject(this, "name2", mName2);
+        actionObject.acceptObject(this, "name4", mName4);
+        actionObject.acceptObject(this, "otherParcelable", mOtherParcelable);
+        actionObject.acceptObject(this, "date", mDate);
+        actionObject.acceptObject(this, "pattern", mPattern);
+        actionObject.acceptObject(this, "linkAddresses2", mLinkAddresses2);
+        actionObject.acceptObject(this, "linkAddresses", mLinkAddresses);
+        actionObject.acceptObject(this, "linkAddresses4", mLinkAddresses4);
+        actionObject.acceptObject(this, "active", mActive);
+        actionObject.acceptObject(this, "stateName", mStateName);
+        actionInt.acceptInt(this, "flags", mFlags);
+        actionInt.acceptInt(this, "state", mState);
+        actionObject.acceptObject(this, "charSeq", charSeq);
+        actionObject.acceptObject(this, "linkAddresses5", mLinkAddresses5);
+        actionInt.acceptInt(this, "stringRes", mStringRes);
+        actionInt.acceptInt(this, "limited", mLimited);
+        actionObject.acceptObject(this, "coords", mCoords);
+    }
+
+    /** @deprecated May cause boxing allocations - use with caution! */
+    @Deprecated
+    @DataClass.Generated.Member
+    void forEachField(DataClass.PerObjectFieldAction<SampleDataClass> action) {
+        action.acceptObject(this, "num", mNum);
+        action.acceptObject(this, "num2", mNum2);
+        action.acceptObject(this, "num4", mNum4);
+        action.acceptObject(this, "name", mName);
+        action.acceptObject(this, "name2", mName2);
+        action.acceptObject(this, "name4", mName4);
+        action.acceptObject(this, "otherParcelable", mOtherParcelable);
+        action.acceptObject(this, "date", mDate);
+        action.acceptObject(this, "pattern", mPattern);
+        action.acceptObject(this, "linkAddresses2", mLinkAddresses2);
+        action.acceptObject(this, "linkAddresses", mLinkAddresses);
+        action.acceptObject(this, "linkAddresses4", mLinkAddresses4);
+        action.acceptObject(this, "active", mActive);
+        action.acceptObject(this, "stateName", mStateName);
+        action.acceptObject(this, "flags", mFlags);
+        action.acceptObject(this, "state", mState);
+        action.acceptObject(this, "charSeq", charSeq);
+        action.acceptObject(this, "linkAddresses5", mLinkAddresses5);
+        action.acceptObject(this, "stringRes", mStringRes);
+        action.acceptObject(this, "limited", mLimited);
+        action.acceptObject(this, "coords", mCoords);
+    }
+
+    @DataClass.Generated.Member
+    static Parcelling<Date> sParcellingForDate =
+            Parcelling.Cache.get(
+                    DateParcelling.class);
+    static {
+        if (sParcellingForDate == null) {
+            sParcellingForDate = Parcelling.Cache.put(
+                    new DateParcelling());
+        }
+    }
+
+    @DataClass.Generated.Member
+    static Parcelling<Pattern> sParcellingForPattern =
+            Parcelling.Cache.get(
+                    Parcelling.BuiltIn.ForPattern.class);
+    static {
+        if (sParcellingForPattern == null) {
+            sParcellingForPattern = Parcelling.Cache.put(
+                    new Parcelling.BuiltIn.ForPattern());
+        }
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        long flg = 0;
+        if (mActive) flg |= 0x1000;
+        if (mName != null) flg |= 0x8;
+        if (mName2 != null) flg |= 0x10;
+        if (mOtherParcelable != null) flg |= 0x40;
+        if (mDate != null) flg |= 0x80;
+        if (mPattern != null) flg |= 0x100;
+        if (mLinkAddresses2 != null) flg |= 0x200;
+        if (mLinkAddresses != null) flg |= 0x400;
+        if (mLinkAddresses4 != null) flg |= 0x800;
+        if (mStateName != null) flg |= 0x2000;
+        if (charSeq != null) flg |= 0x10000;
+        if (mLinkAddresses5 != null) flg |= 0x20000;
+        if (mCoords != null) flg |= 0x100000;
+        dest.writeLong(flg);
+        dest.writeInt(mNum);
+        dest.writeInt(mNum2);
+        dest.writeInt(mNum4);
+        if (mName != null) dest.writeString(mName);
+        if (mName2 != null) dest.writeString(mName2);
+        dest.writeString(mName4);
+        if (mOtherParcelable != null) dest.writeTypedObject(mOtherParcelable, flags);
+        sParcellingForDate.parcel(mDate, dest, flags);
+        sParcellingForPattern.parcel(mPattern, dest, flags);
+        if (mLinkAddresses2 != null) dest.writeParcelableList(mLinkAddresses2, flags);
+        if (mLinkAddresses != null) dest.writeParcelableList(mLinkAddresses, flags);
+        if (mLinkAddresses4 != null) dest.writeTypedArray(mLinkAddresses4, flags);
+        if (mStateName != null) dest.writeString(mStateName);
+        dest.writeInt(mFlags);
+        dest.writeInt(mState);
+        if (charSeq != null) dest.writeCharSequence(charSeq);
+        if (mLinkAddresses5 != null) dest.writeTypedArray(mLinkAddresses5, flags);
+        dest.writeInt(mStringRes);
+        dest.writeInt(mLimited);
+        if (mCoords != null) dest.writeFloatArray(mCoords);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<SampleDataClass> CREATOR
+            = new Parcelable.Creator<SampleDataClass>() {
+        @Override
+        public SampleDataClass[] newArray(int size) {
+            return new SampleDataClass[size];
+        }
+
+        @Override
+        @SuppressWarnings({"unchecked", "RedundantCast"})
+        public SampleDataClass createFromParcel(Parcel in) {
+            // You can override field unparcelling by defining methods like:
+            // static FieldType unparcelFieldName(Parcel in) { ... }
+
+            long flg = in.readLong();
+            boolean active = (flg & 0x1000) != 0;
+            int num = in.readInt();
+            int num2 = in.readInt();
+            int num4 = in.readInt();
+            String name = (flg & 0x8) == 0 ? null : in.readString();
+            String name2 = (flg & 0x10) == 0 ? null : in.readString();
+            String name4 = in.readString();
+            AccessibilityNodeInfo otherParcelable = (flg & 0x40) == 0 ? null : (AccessibilityNodeInfo) in.readTypedObject(AccessibilityNodeInfo.CREATOR);
+            Date date = sParcellingForDate.unparcel(in);
+            Pattern pattern = sParcellingForPattern.unparcel(in);
+            List<LinkAddress> linkAddresses2 = null;
+            if ((flg & 0x200) != 0) {
+                linkAddresses2 = new ArrayList<>();
+                in.readParcelableList(linkAddresses2, LinkAddress.class.getClassLoader());
+            }
+            ArrayList<LinkAddress> linkAddresses = null;
+            if ((flg & 0x400) != 0) {
+                linkAddresses = new ArrayList<>();
+                in.readParcelableList(linkAddresses, LinkAddress.class.getClassLoader());
+            }
+            LinkAddress[] linkAddresses4 = (flg & 0x800) == 0 ? null : (LinkAddress[]) in.createTypedArray(LinkAddress.CREATOR);
+            String stateName = (flg & 0x2000) == 0 ? null : in.readString();
+            int flags = in.readInt();
+            int state = in.readInt();
+            CharSequence _charSeq = (flg & 0x10000) == 0 ? null : (CharSequence) in.readCharSequence();
+            LinkAddress[] linkAddresses5 = (flg & 0x20000) == 0 ? null : (LinkAddress[]) in.createTypedArray(LinkAddress.CREATOR);
+            int stringRes = in.readInt();
+            int limited = in.readInt();
+            float[] coords = (flg & 0x100000) == 0 ? null : in.createFloatArray();
+            return new SampleDataClass(
+                    num,
+                    num2,
+                    num4,
+                    name,
+                    name2,
+                    name4,
+                    otherParcelable,
+                    date,
+                    pattern,
+                    linkAddresses2,
+                    linkAddresses,
+                    linkAddresses4,
+                    active,
+                    stateName,
+                    flags,
+                    state,
+                    _charSeq,
+                    linkAddresses5,
+                    stringRes,
+                    limited,
+                    coords);
+        }
+    };
+
+    /**
+     * A builder for {@link SampleDataClass}
+     */
+    @SuppressWarnings("WeakerAccess")
+    @DataClass.Generated.Member
+    public static class Builder
+            extends android.provider.OneTimeUseBuilder<SampleDataClass> {
+
+        protected int mNum;
+        protected int mNum2;
+        protected int mNum4;
+        protected @Nullable String mName;
+        protected String mName2;
+        protected @NonNull String mName4;
+        protected AccessibilityNodeInfo mOtherParcelable;
+        protected Date mDate;
+        protected Pattern mPattern;
+        protected List<LinkAddress> mLinkAddresses2;
+        protected ArrayList<LinkAddress> mLinkAddresses;
+        protected @Nullable LinkAddress[] mLinkAddresses4;
+        protected boolean mActive;
+        protected @StateName String mStateName;
+        protected @RequestFlags int mFlags;
+        protected @State int mState;
+        protected CharSequence charSeq;
+        protected LinkAddress[] mLinkAddresses5;
+        protected @StringRes int mStringRes;
+        protected @android.annotation.IntRange(from = 0, to = 4) int mLimited;
+        protected @Size(2) @FloatRange(from = 0f) float[] mCoords;
+
+        protected long mBuilderFieldsSet = 0L;
+
+        public Builder() {};
+
+        /**
+         * Any property javadoc should go onto the field, and will be copied where appropriate,
+         * including getters, constructor parameters, builder setters, etc.
+         *
+         * <p>
+         * This allows to avoid the burden of maintaining copies of the same documentation
+         * pieces in multiple places for each field.
+         */
+        @DataClass.Generated.Member
+        public Builder setNum(int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x1;
+            mNum = value;
+            return this;
+        }
+
+        /**
+         * Various javadoc features should work as expected when copied, e.g {@code code},
+         * {@link #mName links}, <a href="https://google.com">html links</a>, etc.
+         *
+         * @see #mNum2 ..and so should blocks at the bottom, e.g. {@code @see} blocks.
+         */
+        @DataClass.Generated.Member
+        public Builder setNum2(int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x2;
+            mNum2 = value;
+            return this;
+        }
+
+        /**
+         * {@code @hide} javadoc annotation is also propagated, which can be used to adjust the
+         * desired public API surface.
+         *
+         * @see #getNum4() is hidden
+         * @see Builder#setNum4(int) also hidden
+         * @hide
+         */
+        @DataClass.Generated.Member
+        public Builder setNum4(int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4;
+            mNum4 = value;
+            return this;
+        }
+
+        /**
+         * {@link Nullable} fields are considered optional and will not throw an exception if omitted
+         * (or set to null) when creating an instance either via a {@link Builder} or constructor.
+         */
+        @DataClass.Generated.Member
+        public Builder setName(@Nullable String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8;
+            mName = value;
+            return this;
+        }
+
+        /**
+         * Fields with default value expressions ("mFoo = ...") are also optional, and are automatically
+         * initialized to the provided default expression, unless explicitly set.
+         */
+        @DataClass.Generated.Member
+        public Builder setName2(String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x10;
+            mName2 = value;
+            return this;
+        }
+
+        /**
+         * Fields without {@link Nullable} annotation or default value are considered required.
+         *
+         * {@link NonNull} annotation is recommended on such non-primitive fields for documentation.
+         */
+        @DataClass.Generated.Member
+        public Builder setName4(@NonNull String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x20;
+            mName4 = value;
+            return this;
+        }
+
+        /**
+         * For parcelling, any field type supported by {@link Parcel} is supported out of the box.
+         * E.g. {@link Parcelable} subclasses, {@link String}, {@link int}, {@link boolean}, etc.
+         */
+        @DataClass.Generated.Member
+        public Builder setOtherParcelable(AccessibilityNodeInfo value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x40;
+            mOtherParcelable = value;
+            return this;
+        }
+
+        /**
+         * Additionally, support for parcelling other types can be added by implementing a
+         * {@link Parcelling}, and referencing it in the {@link DataClass.ParcelWith} field annotation.
+         *
+         * @see DateParcelling an example {@link Parcelling} implementation
+         */
+        @DataClass.Generated.Member
+        public Builder setDate(Date value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x80;
+            mDate = value;
+            return this;
+        }
+
+        /**
+         * If a {@link Parcelling} is fairly common, consider putting it in {@link Parcelling.BuiltIn}
+         * to encourage its reuse.
+         */
+        @DataClass.Generated.Member
+        public Builder setPattern(Pattern value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x100;
+            mPattern = value;
+            return this;
+        }
+
+        /**
+         * For lists, when using a {@link Builder}, other than a regular
+         * {@link Builder#setLinkAddresses2(List) setter}, and additional
+         * {@link Builder#addLinkAddresses2(LinkAddress) add} method is generated for convenience.
+         */
+        @DataClass.Generated.Member
+        public Builder setLinkAddresses2(List<LinkAddress> value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x200;
+            mLinkAddresses2 = value;
+            return this;
+        }
+
+        /** @see #setLinkAddresses2 */
+        @DataClass.Generated.Member
+        public Builder addLinkAddresses2(@NonNull LinkAddress value) {
+            // You can refine this method's name by providing item's singular name, e.g.:
+            // @DataClass.PluralOf("item")) mItems = ...
+
+            if (mLinkAddresses2 == null) setLinkAddresses2(new ArrayList<>());
+            mLinkAddresses2.add(value);
+            return this;
+        }
+
+        /**
+         * For aesthetics, you may want to consider providing a singular version of the plural field
+         * name, which would be used for the {@link #mLinkAddresses2 above mentioned} "add" method.
+         *
+         * @see Builder#addLinkAddress(LinkAddress)
+         */
+        @DataClass.Generated.Member
+        public Builder setLinkAddresses(ArrayList<LinkAddress> value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x400;
+            mLinkAddresses = value;
+            return this;
+        }
+
+        /** @see #setLinkAddresses */
+        @DataClass.Generated.Member
+        public Builder addLinkAddress(@NonNull LinkAddress value) {
+            if (mLinkAddresses == null) setLinkAddresses(new ArrayList<>());
+            mLinkAddresses.add(value);
+            return this;
+        }
+
+        /**
+         * For array fields, when using a {@link Builder}, vararg argument format is used for
+         * convenience.
+         *
+         * @see Builder#setLinkAddresses4(LinkAddress...)
+         */
+        @DataClass.Generated.Member
+        public Builder setLinkAddresses4(@Nullable LinkAddress... value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x800;
+            mLinkAddresses4 = value;
+            return this;
+        }
+
+        /**
+         * For boolean fields, when using a {@link Builder}, in addition to a regular setter, methods
+         * like {@link Builder#markActive()} and {@link Builder#markNotActive()} are generated.
+         */
+        @DataClass.Generated.Member
+        public Builder setActive(boolean value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x1000;
+            mActive = value;
+            return this;
+        }
+
+        /** @see #setActive */
+        @DataClass.Generated.Member
+        public Builder markActive() {
+            return setActive(true);
+        }
+
+        /** @see #setActive */
+        @DataClass.Generated.Member
+        public Builder markNotActive() {
+            return setActive(false);
+        }
+
+        /**
+         * {@link IntDef}/{@link StringDef}-annotated fields propagate the annotation to
+         * getter/constructor/setter/builder parameters, making for a nicer api.
+         *
+         * @see #getStateName
+         * @see Builder#setStateName
+         */
+        @DataClass.Generated.Member
+        public Builder setStateName(@StateName String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x2000;
+            mStateName = value;
+            return this;
+        }
+
+        /**
+         * Fields annotated with {@link IntDef} annotations also get a proper {@link #toString()} value.
+         */
+        @DataClass.Generated.Member
+        public Builder setFlags(@RequestFlags int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4000;
+            mFlags = value;
+            return this;
+        }
+
+        /**
+         * Above is true for both {@link IntDef#flag flags} and enum-like {@link IntDef}s
+         */
+        @DataClass.Generated.Member
+        public Builder setState(@State int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8000;
+            mState = value;
+            return this;
+        }
+
+        /**
+         * Making a field public will suppress getter generation in favor of accessing it directly.
+         */
+        @DataClass.Generated.Member
+        public Builder setCharSeq(CharSequence value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x10000;
+            charSeq = value;
+            return this;
+        }
+
+        /**
+         * Final fields suppress generating a setter (when setters are requested).
+         */
+        @DataClass.Generated.Member
+        public Builder setLinkAddresses5(LinkAddress... value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x20000;
+            mLinkAddresses5 = value;
+            return this;
+        }
+
+        /**
+         * Fields with certain annotations are automatically validated in constructor
+         *
+         * You can see overloads in {@link AnnotationValidations} for a list of currently
+         * supported ones.
+         *
+         * You can also extend support to your custom annotations by creating another corresponding
+         * overloads like
+         * {@link AnnotationValidations#validate(Class, UserIdInt, int)}.
+         *
+         * @see #SampleDataClass
+         */
+        @DataClass.Generated.Member
+        public Builder setStringRes(@StringRes int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x40000;
+            mStringRes = value;
+            return this;
+        }
+
+        /**
+         * Validation annotations may also have parameters.
+         *
+         * Parameter values will be supplied to validation method as name-value pairs.
+         *
+         * @see AnnotationValidations#validate(Class, Size, int, String, int, String, int)
+         */
+        @DataClass.Generated.Member
+        public Builder setLimited(@android.annotation.IntRange(from = 0, to = 4) int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x80000;
+            mLimited = value;
+            return this;
+        }
+
+        /**
+         * Unnamed validation annotation parameter gets supplied to the validating method named as
+         * "value".
+         *
+         * Validation annotations following {@link Each} annotation, will be applied for each
+         * array/collection element instead.
+         *
+         * @see AnnotationValidations#validate(Class, Size, int, String, int)
+         */
+        @DataClass.Generated.Member
+        public Builder setCoords(@Size(2) @FloatRange(from = 0f) float... value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x100000;
+            mCoords = value;
+            return this;
+        }
+
+        /** Builds the instance. This builder should not be touched after calling this! */
+        public SampleDataClass build() {
+            markUsed();
+            if ((mBuilderFieldsSet & 0x1) == 0) {
+                throw new IllegalStateException("Required field not set: num");
+            }
+            if ((mBuilderFieldsSet & 0x2) == 0) {
+                throw new IllegalStateException("Required field not set: num2");
+            }
+            if ((mBuilderFieldsSet & 0x4) == 0) {
+                throw new IllegalStateException("Required field not set: num4");
+            }
+            if ((mBuilderFieldsSet & 0x10) == 0) {
+                mName2 = "Bob";
+            }
+            if ((mBuilderFieldsSet & 0x20) == 0) {
+                throw new IllegalStateException("Required field not set: name4");
+            }
+            if ((mBuilderFieldsSet & 0x40) == 0) {
+                mOtherParcelable = null;
+            }
+            if ((mBuilderFieldsSet & 0x80) == 0) {
+                mDate = new Date(42 * 42);
+            }
+            if ((mBuilderFieldsSet & 0x100) == 0) {
+                mPattern = Pattern.compile("");
+            }
+            if ((mBuilderFieldsSet & 0x200) == 0) {
+                mLinkAddresses2 = new ArrayList<>();
+            }
+            if ((mBuilderFieldsSet & 0x400) == 0) {
+                mLinkAddresses = new ArrayList<>();
+            }
+            if ((mBuilderFieldsSet & 0x800) == 0) {
+                mLinkAddresses4 = null;
+            }
+            if ((mBuilderFieldsSet & 0x1000) == 0) {
+                mActive = true;
+            }
+            if ((mBuilderFieldsSet & 0x2000) == 0) {
+                mStateName = STATE_NAME_UNDEFINED;
+            }
+            if ((mBuilderFieldsSet & 0x4000) == 0) {
+                throw new IllegalStateException("Required field not set: flags");
+            }
+            if ((mBuilderFieldsSet & 0x8000) == 0) {
+                mState = STATE_UNDEFINED;
+            }
+            if ((mBuilderFieldsSet & 0x10000) == 0) {
+                charSeq = "";
+            }
+            if ((mBuilderFieldsSet & 0x20000) == 0) {
+                throw new IllegalStateException("Required field not set: linkAddresses5");
+            }
+            if ((mBuilderFieldsSet & 0x40000) == 0) {
+                mStringRes = 0;
+            }
+            if ((mBuilderFieldsSet & 0x80000) == 0) {
+                mLimited = 3;
+            }
+            if ((mBuilderFieldsSet & 0x100000) == 0) {
+                mCoords = new float[] { 0f, 0f };
+            }
+            SampleDataClass o = new SampleDataClass(
+                    mNum,
+                    mNum2,
+                    mNum4,
+                    mName,
+                    mName2,
+                    mName4,
+                    mOtherParcelable,
+                    mDate,
+                    mPattern,
+                    mLinkAddresses2,
+                    mLinkAddresses,
+                    mLinkAddresses4,
+                    mActive,
+                    mStateName,
+                    mFlags,
+                    mState,
+                    charSeq,
+                    mLinkAddresses5,
+                    mStringRes,
+                    mLimited,
+                    mCoords);
+            return o;
+        }
+    }
+
+}
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java b/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java
new file mode 100644
index 0000000..71e85ab
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.codegentest;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+
+import android.net.LinkAddress;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Tests {@link SampleDataClass} after it's augmented with dataclass codegen.
+ *
+ * Use {@code $ . runTest.sh} to run.
+ */
+@RunWith(AndroidJUnit4.class)
+public class SampleDataClassTest {
+
+    private SampleDataClass mSpecimen = newBuilder().build();
+
+    private static SampleDataClass.Builder newBuilder() {
+        return newIncompleteBuilder()
+                .setNum(42)
+                .setNum2(42)
+                .setNum4(42)
+                .setName4("foobar")
+                .setLinkAddresses5();
+    }
+
+    private static SampleDataClass.Builder newIncompleteBuilder() {
+        return new SampleDataClass.Builder()
+                .markActive()
+                .setName("some parcelable")
+                .setFlags(SampleDataClass.FLAG_MANUAL_REQUEST);
+    }
+
+    @Test
+    public void testParcelling_producesEqualInstance() {
+        SampleDataClass copy = parcelAndUnparcel(mSpecimen, SampleDataClass.CREATOR);
+        assertEquals(mSpecimen, copy);
+        assertEquals(mSpecimen.hashCode(), copy.hashCode());
+    }
+
+    @Test
+    public void testParcelling_producesInstanceWithEqualFields() {
+        SampleDataClass copy = parcelAndUnparcel(mSpecimen, SampleDataClass.CREATOR);
+        copy.forEachField((self, copyFieldName, copyFieldValue) -> {
+            mSpecimen.forEachField((self2, specimenFieldName, specimenFieldValue) -> {
+                if (copyFieldName.equals(specimenFieldName)
+                        && !copyFieldName.equals("pattern")
+                        && (specimenFieldValue == null
+                                || !specimenFieldValue.getClass().isArray())) {
+                    assertEquals("Mismatched field values for " + copyFieldName,
+                            specimenFieldValue, copyFieldValue);
+                }
+            });
+        });
+    }
+
+    @Test
+    public void testCustomParcelling_instanceIsCached() {
+        parcelAndUnparcel(mSpecimen, SampleDataClass.CREATOR);
+        parcelAndUnparcel(mSpecimen, SampleDataClass.CREATOR);
+        assertEquals(1, DateParcelling.sInstanceCount.get());
+    }
+
+    @Test
+    public void testDefaultFieldValue_isPropagated() {
+        assertEquals(new Date(42 * 42), mSpecimen.getDate());
+    }
+
+    @Test
+    public void testForEachField_avoidsBoxing() {
+        AtomicInteger intFieldCount = new AtomicInteger(0);
+        mSpecimen.forEachField(
+                (self, name, intValue) -> intFieldCount.getAndIncrement(),
+                (self, name, objectValue) -> {
+                    if (objectValue != null) {
+                        assertThat("Boxed field " + name,
+                                objectValue, not(instanceOf(Integer.class)));
+                    }
+                });
+        assertThat(intFieldCount.get(), greaterThanOrEqualTo(1));
+    }
+
+    @Test
+    public void testToString_containsEachField() {
+        String toString = mSpecimen.toString();
+
+        mSpecimen.forEachField((self, name, value) -> {
+            assertThat(toString, containsString(name));
+            if (value instanceof Integer) {
+                // Could be flags, their special toString tested separately
+            } else if (value instanceof Object[]) {
+                assertThat(toString, containsString(Arrays.toString((Object[]) value)));
+            } else if (value != null && value.getClass().isArray()) {
+                // Primitive array, uses multiple specialized Arrays.toString overloads
+            } else {
+                assertThat(toString, containsString("" + value));
+            }
+        });
+    }
+
+    @Test
+    public void testBuilder_propagatesValuesToInstance() {
+        assertEquals(43, newBuilder().setNum(43).build().getNum());
+    }
+
+    @Test
+    public void testPluralFields_canHaveCustomSingularBuilderName() {
+        newBuilder().addLinkAddress(new LinkAddress("127.0.0.1/24"));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testBuilder_usableOnlyOnce() {
+        SampleDataClass.Builder builder = newBuilder();
+        builder.build();
+        builder.build();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testBuilder_throwsWhenRequiredFieldMissing() {
+        newIncompleteBuilder().build();
+    }
+
+    @Test
+    public void testIntDefs_haveCorrectToString() {
+        int flagsAsInt = SampleDataClass.FLAG_MANUAL_REQUEST
+                | SampleDataClass.FLAG_COMPATIBILITY_MODE_REQUEST;
+        String flagsAsString = SampleDataClass.requestFlagsToString(flagsAsInt);
+
+        assertThat(flagsAsString, containsString("MANUAL_REQUEST"));
+        assertThat(flagsAsString, containsString("COMPATIBILITY_MODE_REQUEST"));
+        assertThat(flagsAsString, not(containsString("1")));
+        assertThat(flagsAsString, not(containsString("" + flagsAsInt)));
+
+        String dataclassToString = newBuilder()
+                .setFlags(flagsAsInt)
+                .setState(SampleDataClass.STATE_UNDEFINED)
+                .build()
+                .toString();
+        assertThat(dataclassToString, containsString(flagsAsString));
+        assertThat(dataclassToString, containsString("UNDEFINED"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testFlags_getValidated() {
+        newBuilder().setFlags(12345).build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testIntEnums_getValidated() {
+        newBuilder().setState(12345).build();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testStringEnums_getValidated() {
+        newBuilder().setStateName("foo").build();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testCustomValidation_isTriggered() {
+        newBuilder().setNum2(-1).setNum4(1).build();
+    }
+
+    @Test
+    public void testLazyInit_isLazilyCalledOnce() {
+        assertNull(mSpecimen.mTmpStorage);
+
+        int[] tmpStorage = mSpecimen.getTmpStorage();
+        assertNotNull(tmpStorage);
+        assertSame(tmpStorage, mSpecimen.mTmpStorage);
+
+        int[] tmpStorageAgain = mSpecimen.getTmpStorage();
+        assertSame(tmpStorage, tmpStorageAgain);
+    }
+
+    private static <T extends Parcelable> T parcelAndUnparcel(
+            T original, Parcelable.Creator<T> creator) {
+        Parcel p = Parcel.obtain();
+        try {
+            original.writeToParcel(p, 0);
+            p.setDataPosition(0);
+            return creator.createFromParcel(p);
+        } finally {
+            p.recycle();
+        }
+    }
+}
diff --git a/tests/FeatureSplit/feature1/Android.bp b/tests/FeatureSplit/feature1/Android.bp
index 1a93e84..706a4f5 100644
--- a/tests/FeatureSplit/feature1/Android.bp
+++ b/tests/FeatureSplit/feature1/Android.bp
@@ -18,7 +18,7 @@
     name: "FeatureSplit1",
     srcs: ["**/*.java"],
     sdk_version: "current",
-    libs: ["FeatureSplitBase"],
+    libs: ["FeatureSplitBase", "FeatureSplit2"],
     aaptflags: [
         "--package-id",
         "0x80",
diff --git a/tests/FeatureSplit/feature1/AndroidManifest.xml b/tests/FeatureSplit/feature1/AndroidManifest.xml
index b87361f..086c2c3 100644
--- a/tests/FeatureSplit/feature1/AndroidManifest.xml
+++ b/tests/FeatureSplit/feature1/AndroidManifest.xml
@@ -19,6 +19,7 @@
     featureSplit="feature1">
 
     <uses-sdk android:minSdkVersion="21" />
+    <uses-split android:name="feature2" />
 
     <application>
         <activity android:name=".one.One" android:label="Feature One">
diff --git a/tests/FeatureSplit/feature1/res/layout/included.xml b/tests/FeatureSplit/feature1/res/layout/included.xml
index c64bdb7..f0c56f8 100644
--- a/tests/FeatureSplit/feature1/res/layout/included.xml
+++ b/tests/FeatureSplit/feature1/res/layout/included.xml
@@ -2,4 +2,5 @@
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/text"
     android:layout_width="wrap_content"
-    android:layout_height="wrap_content" />
+    android:layout_height="wrap_content"
+    android:text="@string/feature2_string" />
diff --git a/tests/FeatureSplit/feature1/res/values/values.xml b/tests/FeatureSplit/feature1/res/values/values.xml
index 7d58865..6a840df 100644
--- a/tests/FeatureSplit/feature1/res/values/values.xml
+++ b/tests/FeatureSplit/feature1/res/values/values.xml
@@ -20,7 +20,8 @@
     <integer name="test_integer2">200</integer>
     <color name="test_color2">#00ff00</color>
     <string-array name="string_array2">
-        <item>@string/app_title</item>
+      <item>@string/app_title</item>
+      <item>@string/feature2_string</item>
     </string-array>
 </resources>
 
diff --git a/tests/FeatureSplit/feature2/res/values/values.xml b/tests/FeatureSplit/feature2/res/values/values.xml
index af5ed1b..70e772c 100644
--- a/tests/FeatureSplit/feature2/res/values/values.xml
+++ b/tests/FeatureSplit/feature2/res/values/values.xml
@@ -15,10 +15,11 @@
 -->
 
 <resources>
+    <string name="feature2_string">feature 2 string referenced from feature 1</string>
     <integer name="test_integer3">300</integer>
     <color name="test_color3">#0000ff</color>
     <string-array name="string_array3">
-        <item>@string/app_title</item>
+      <item>@string/app_title</item>
     </string-array>
 </resources>
 
diff --git a/tests/FrameworkPerf/res/drawable-161dpi/wallpaper_goldengate_scale.jpg b/tests/FrameworkPerf/res/drawable-161dpi/wallpaper_goldengate_scale.jpg
index 2271091..8b7c6db 100644
--- a/tests/FrameworkPerf/res/drawable-161dpi/wallpaper_goldengate_scale.jpg
+++ b/tests/FrameworkPerf/res/drawable-161dpi/wallpaper_goldengate_scale.jpg
Binary files differ
diff --git a/tests/FrameworkPerf/res/drawable-nodpi/wallpaper_goldengate.jpg b/tests/FrameworkPerf/res/drawable-nodpi/wallpaper_goldengate.jpg
index 2271091..8b7c6db 100644
--- a/tests/FrameworkPerf/res/drawable-nodpi/wallpaper_goldengate.jpg
+++ b/tests/FrameworkPerf/res/drawable-nodpi/wallpaper_goldengate.jpg
Binary files differ
diff --git a/tests/GamePerformance/AndroidManifest.xml b/tests/GamePerformance/AndroidManifest.xml
index b331e2c..2ff7fa6 100644
--- a/tests/GamePerformance/AndroidManifest.xml
+++ b/tests/GamePerformance/AndroidManifest.xml
@@ -16,7 +16,9 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.gameperformance">
+    package="android.gameperformance"
+    android:versionCode="3"
+    android:versionName="3.0" >
     <uses-sdk android:minSdkVersion="25"/>
     <uses-feature android:glEsVersion="0x00020000" android:required="true" />
 
@@ -24,7 +26,8 @@
     <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" >
+        <activity android:name="android.gameperformance.GamePerformanceActivity"
+                  android:screenOrientation="landscape" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
diff --git a/tests/GamePerformance/res/drawable/animation.xml b/tests/GamePerformance/res/drawable/animation.xml
new file mode 100644
index 0000000..b423ff0
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/animation.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.
+ -->
+
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
+     android:id="@+id/animation" android:oneshot="false">
+    <item android:drawable="@drawable/digit_0" android:duration="15" />
+    <item android:drawable="@drawable/digit_1" android:duration="15" />
+    <item android:drawable="@drawable/digit_2" android:duration="15" />
+    <item android:drawable="@drawable/digit_3" android:duration="15" />
+    <item android:drawable="@drawable/digit_4" android:duration="15" />
+    <item android:drawable="@drawable/digit_5" android:duration="15" />
+    <item android:drawable="@drawable/digit_6" android:duration="15" />
+    <item android:drawable="@drawable/digit_7" android:duration="15" />
+    <item android:drawable="@drawable/digit_8" android:duration="15" />
+    <item android:drawable="@drawable/digit_9" android:duration="15" />
+ </animation-list>
\ No newline at end of file
diff --git a/tests/GamePerformance/res/drawable/digit_0.png b/tests/GamePerformance/res/drawable/digit_0.png
new file mode 100644
index 0000000..7264e3e
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_0.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_1.png b/tests/GamePerformance/res/drawable/digit_1.png
new file mode 100644
index 0000000..f098a71
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_1.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_2.png b/tests/GamePerformance/res/drawable/digit_2.png
new file mode 100644
index 0000000..f08cd31
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_2.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_3.png b/tests/GamePerformance/res/drawable/digit_3.png
new file mode 100644
index 0000000..497df8a
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_3.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_4.png b/tests/GamePerformance/res/drawable/digit_4.png
new file mode 100644
index 0000000..10efe8c
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_4.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_5.png b/tests/GamePerformance/res/drawable/digit_5.png
new file mode 100644
index 0000000..1018a2f
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_5.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_6.png b/tests/GamePerformance/res/drawable/digit_6.png
new file mode 100644
index 0000000..593c467
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_6.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_7.png b/tests/GamePerformance/res/drawable/digit_7.png
new file mode 100644
index 0000000..041b95f
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_7.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_8.png b/tests/GamePerformance/res/drawable/digit_8.png
new file mode 100644
index 0000000..f8fa496
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_8.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/digit_9.png b/tests/GamePerformance/res/drawable/digit_9.png
new file mode 100644
index 0000000..303b1da
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/digit_9.png
Binary files differ
diff --git a/tests/GamePerformance/res/drawable/logo.png b/tests/GamePerformance/res/drawable/logo.png
new file mode 100644
index 0000000..61391df
--- /dev/null
+++ b/tests/GamePerformance/res/drawable/logo.png
Binary files differ
diff --git a/tests/GamePerformance/src/android/gameperformance/BaseTest.java b/tests/GamePerformance/src/android/gameperformance/BaseTest.java
new file mode 100644
index 0000000..b0640b4
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/BaseTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.text.DecimalFormat;
+import java.util.concurrent.TimeUnit;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.util.Log;
+import android.view.WindowManager;
+
+/**
+ * Base class for a test that performs bisection to determine maximum
+ * performance of a metric test measures.
+ */
+public abstract class BaseTest  {
+    private final static String TAG = "BaseTest";
+
+    // Time to wait for render warm up. No statistics is collected during this pass.
+    private final static long WARM_UP_TIME = TimeUnit.SECONDS.toMillis(5);
+
+    // Perform pass to probe the configuration using iterations. After each iteration current FPS is
+    // checked and if it looks obviously bad, pass gets stopped earlier. Once all iterations are
+    // done and final FPS is above PASS_THRESHOLD pass to probe is considered successful.
+    private final static long TEST_ITERATION_TIME = TimeUnit.SECONDS.toMillis(12);
+    private final static int TEST_ITERATION_COUNT = 5;
+
+    // FPS pass test threshold, in ratio from ideal FPS, that matches device
+    // refresh rate.
+    private final static double PASS_THRESHOLD = 0.95;
+    // FPS threshold, in ratio from ideal FPS, to identify that current pass to probe is obviously
+    // bad and to stop pass earlier.
+    private final static double OBVIOUS_BAD_THRESHOLD = 0.90;
+
+    private static DecimalFormat DOUBLE_FORMATTER = new DecimalFormat("#.##");
+
+    private final GamePerformanceActivity mActivity;
+
+    // Device's refresh rate.
+    private final double mRefreshRate;
+
+    public BaseTest(@NonNull GamePerformanceActivity activity) {
+        mActivity = activity;
+        final WindowManager windowManager =
+                (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
+        mRefreshRate = windowManager.getDefaultDisplay().getRefreshRate();
+    }
+
+    @NonNull
+    public Context getContext() {
+        return mActivity;
+    }
+
+    @NonNull
+    public GamePerformanceActivity getActivity() {
+        return mActivity;
+    }
+
+    // Returns name of the test.
+    public abstract String getName();
+
+    // Returns unit name.
+    public abstract String getUnitName();
+
+    // Returns number of measured units per one bisection unit.
+    public abstract double getUnitScale();
+
+    // Initializes test.
+    public abstract void initUnits(double unitCount);
+
+    // Initializes probe pass.
+    protected abstract void initProbePass(int probe);
+
+    // Frees probe pass.
+    protected abstract void freeProbePass();
+
+    /**
+     * Performs the test and returns maximum number of measured units achieved. Unit is test
+     * specific and name is returned by getUnitName. Returns 0 in case of failure.
+     */
+    public double run() {
+        try {
+            Log.i(TAG, "Test started " + getName());
+
+            final double passFps = PASS_THRESHOLD * mRefreshRate;
+            final double obviousBadFps = OBVIOUS_BAD_THRESHOLD * mRefreshRate;
+
+            // Bisection bounds. Probe value is taken as middle point. Then it used to initialize
+            // test with probe * getUnitScale units. In case probe passed, lowLimit is updated to
+            // probe, otherwise upLimit is updated to probe. lowLimit contains probe that passes
+            // and upLimit contains the probe that fails. Each iteration narrows the range.
+            // Iterations continue until range is collapsed and lowLimit contains actual test
+            // result.
+            int lowLimit = 0;  // Initially 0, that is recognized as failure.
+            int upLimit = 250;
+
+            while (true) {
+                int probe = (lowLimit + upLimit) / 2;
+                if (probe == lowLimit) {
+                    Log.i(TAG, "Test done: " + DOUBLE_FORMATTER.format(probe * getUnitScale()) +
+                               " " + getUnitName());
+                    return probe * getUnitScale();
+                }
+
+                Log.i(TAG, "Start probe: " + DOUBLE_FORMATTER.format(probe * getUnitScale()) + " " +
+                           getUnitName());
+                initProbePass(probe);
+
+                Thread.sleep(WARM_UP_TIME);
+
+                getActivity().resetFrameTimes();
+
+                double fps = 0.0f;
+                for (int i = 0; i < TEST_ITERATION_COUNT; ++i) {
+                    Thread.sleep(TEST_ITERATION_TIME);
+                    fps = getActivity().getFps();
+                    if (fps < obviousBadFps) {
+                        // Stop test earlier, we could not fit the loading.
+                        break;
+                    }
+                }
+
+                freeProbePass();
+
+                Log.i(TAG, "Finish probe: " + DOUBLE_FORMATTER.format(probe * getUnitScale()) +
+                           " " + getUnitName() + " - " + DOUBLE_FORMATTER.format(fps) + " FPS.");
+                if (fps < passFps) {
+                    upLimit = probe;
+                } else {
+                    lowLimit = probe;
+                }
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/CPULoadThread.java b/tests/GamePerformance/src/android/gameperformance/CPULoadThread.java
new file mode 100644
index 0000000..fa6f03b
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/CPULoadThread.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+/**
+ * Ballast thread that emulates CPU load by performing heavy computation in loop.
+ */
+public class CPULoadThread extends Thread {
+    private boolean mStopRequest;
+
+    public CPULoadThread() {
+        mStopRequest = false;
+    }
+
+    private static double computePi() {
+        double accumulator = 0;
+        double prevAccumulator = -1;
+        int index = 1;
+        while (true) {
+            accumulator += ((1.0 / (2.0 * index - 1)) - (1.0 / (2.0 * index + 1)));
+            if (accumulator == prevAccumulator) {
+                break;
+            }
+            prevAccumulator = accumulator;
+            index += 2;
+        }
+        return 4 * accumulator;
+    }
+
+    // Requests thread to stop.
+    public void issueStopRequest() {
+        synchronized (this) {
+            mStopRequest = true;
+        }
+    }
+
+    @Override
+    public void run() {
+        // Load CPU by PI computation.
+        while (computePi() != 0) {
+            synchronized (this) {
+                if (mStopRequest) {
+                    break;
+                }
+            }
+        }
+    }
+}
diff --git a/tests/GamePerformance/src/android/gameperformance/ControlsTest.java b/tests/GamePerformance/src/android/gameperformance/ControlsTest.java
new file mode 100644
index 0000000..6c36ddc
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/ControlsTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 android.annotation.NonNull;
+
+/**
+ * Tests that verifies how many UI controls can be handled to keep FPS close to device refresh rate.
+ * As a test UI control ImageView with an infinite animation is chosen. The animation has refresh
+ * rate ~67Hz that forces all devices to refresh UI at highest possible rate.
+ */
+public class ControlsTest extends BaseTest {
+    public ControlsTest(@NonNull GamePerformanceActivity activity) {
+        super(activity);
+    }
+
+    @NonNull
+    public CustomControlView getView() {
+        return getActivity().getControlView();
+    }
+
+    @Override
+    protected void initProbePass(int probe) {
+        try {
+            getActivity().attachControlView();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            return;
+        }
+        initUnits(probe * getUnitScale());
+    }
+
+    @Override
+    protected void freeProbePass() {
+    }
+
+    @Override
+    public String getName() {
+        return "control_count";
+    }
+
+    @Override
+    public String getUnitName() {
+        return "controls";
+    }
+
+    @Override
+    public double getUnitScale() {
+        return 5.0;
+    }
+
+    @Override
+    public void initUnits(double controlCount) {
+        try {
+            getView().createControls(getActivity(), (int)Math.round(controlCount));
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/CustomControlView.java b/tests/GamePerformance/src/android/gameperformance/CustomControlView.java
new file mode 100644
index 0000000..219085a
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/CustomControlView.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.concurrent.CountDownLatch;
+
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.WorkerThread;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.drawable.AnimationDrawable;
+import android.util.Log;
+import android.view.WindowManager;
+import android.widget.AbsoluteLayout;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+/**
+ * View that holds requested number of UI controls as ImageView with an infinite animation.
+ */
+public class CustomControlView extends AbsoluteLayout {
+    private final static int CONTROL_DIMENTION = 48;
+
+    private final int mPerRowControlCount;
+    private List<Long> mFrameTimes = new ArrayList<>();
+
+    public CustomControlView(@NonNull Context context) {
+        super(context);
+
+        final WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+        mPerRowControlCount = windowManager.getDefaultDisplay().getWidth() / CONTROL_DIMENTION;
+    }
+
+    /**
+     * Helper class that overrides ImageView and observes draw requests. Only
+     * one such control is created which is the first control in the view.
+     */
+    class ReferenceImageView extends ImageView {
+        public ReferenceImageView(Context context) {
+            super(context);
+        }
+        @Override
+        public void draw(Canvas canvas) {
+            reportFrame();
+            super.draw(canvas);
+        }
+    }
+
+    @WorkerThread
+    public void createControls(
+            @NonNull Activity activity, int controlCount) throws InterruptedException {
+        synchronized (this) {
+            final CountDownLatch latch = new CountDownLatch(1);
+            activity.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    removeAllViews();
+
+                    for (int i = 0; i < controlCount; ++i) {
+                        final ImageView image = (i == 0) ?
+                                new ReferenceImageView(activity) : new ImageView(activity);
+                        final int x = (i % mPerRowControlCount) * CONTROL_DIMENTION;
+                        final int y = (i / mPerRowControlCount) * CONTROL_DIMENTION;
+                        final AbsoluteLayout.LayoutParams layoutParams =
+                                new AbsoluteLayout.LayoutParams(
+                                        CONTROL_DIMENTION, CONTROL_DIMENTION, x, y);
+                        image.setLayoutParams(layoutParams);
+                        image.setBackgroundResource(R.drawable.animation);
+                        final AnimationDrawable animation =
+                                (AnimationDrawable)image.getBackground();
+                        animation.start();
+                        addView(image);
+                    }
+
+                    latch.countDown();
+                }
+            });
+            latch.await();
+        }
+    }
+
+    @MainThread
+    private void reportFrame() {
+        final long time = System.currentTimeMillis();
+        synchronized (mFrameTimes) {
+            mFrameTimes.add(time);
+        }
+    }
+
+    /**
+     * Resets frame times in order to calculate FPS for the 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));
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java b/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java
index 2b37280..08697ae 100644
--- a/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java
+++ b/tests/GamePerformance/src/android/gameperformance/CustomOpenGLView.java
@@ -17,23 +17,36 @@
 
 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.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.opengl.GLES20;
 import android.opengl.GLSurfaceView;
+import android.util.Log;
 
 public class CustomOpenGLView extends GLSurfaceView {
-    private Random mRandom;
-    private List<Long> mFrameTimes;
+    public final static String TAG = "CustomOpenGLView";
 
-    public CustomOpenGLView(Context context) {
+    private final List<Long> mFrameTimes;
+    private final Object mLock = new Object();
+    private boolean mRenderReady = false;
+    private FrameDrawer mFrameDrawer = null;
+
+    private float mRenderRatio;
+    private int mRenderWidth;
+    private int mRenderHeight;
+
+    public interface FrameDrawer {
+        public void drawFrame(@NonNull GL10 gl);
+    }
+
+    public CustomOpenGLView(@NonNull Context context) {
         super(context);
 
-        mRandom = new Random();
         mFrameTimes = new ArrayList<Long>();
 
         setEGLContextClientVersion(2);
@@ -41,25 +54,35 @@
         setRenderer(new GLSurfaceView.Renderer() {
             @Override
             public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+                Log.i(TAG, "SurfaceCreated: " + config);
                 GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
                 gl.glClearDepthf(1.0f);
-                gl.glEnable(GL10.GL_DEPTH_TEST);
+                gl.glDisable(GL10.GL_DEPTH_TEST);
                 gl.glDepthFunc(GL10.GL_LEQUAL);
 
                 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
-                          GL10.GL_NICEST);            }
+                          GL10.GL_NICEST);
+                synchronized (mLock) {
+                    mRenderReady = true;
+                    mLock.notify();
+                }
+            }
 
             @Override
             public void onSurfaceChanged(GL10 gl, int width, int height) {
+                Log.i(TAG, "SurfaceChanged: " + width + "x" + height);
                 GLES20.glViewport(0, 0, width, height);
+                setRenderBounds(width, height);
             }
 
             @Override
             public void onDrawFrame(GL10 gl) {
-                GLES20.glClearColor(
-                        mRandom.nextFloat(), mRandom.nextFloat(), mRandom.nextFloat(), 1.0f);
+                GLES20.glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
                 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-                synchronized (mFrameTimes) {
+                synchronized (mLock) {
+                    if (mFrameDrawer != null) {
+                        mFrameDrawer.drawFrame(gl);
+                    }
                     mFrameTimes.add(System.currentTimeMillis());
                 }
             }
@@ -67,20 +90,38 @@
         setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
     }
 
+    public void setRenderBounds(int width, int height) {
+        mRenderWidth = width;
+        mRenderHeight = height;
+        mRenderRatio = (float) mRenderWidth / mRenderHeight;
+    }
+
+    public float getRenderRatio() {
+        return mRenderRatio;
+    }
+
+    public int getRenderWidth() {
+        return mRenderWidth;
+    }
+
+    public int getRenderHeight() {
+        return mRenderHeight;
+    }
+
     /**
-     * Resets frame times in order to calculate fps for different test pass.
+     * Resets frame times in order to calculate FPS for the different test pass.
      */
     public void resetFrameTimes() {
-        synchronized (mFrameTimes) {
+        synchronized (mLock) {
             mFrameTimes.clear();
         }
     }
 
     /**
-     * Returns current fps based on collected frame times.
+     * Returns current FPS based on collected frame times.
      */
     public double getFps() {
-        synchronized (mFrameTimes) {
+        synchronized (mLock) {
             if (mFrameTimes.size() < 2) {
                 return 0.0f;
             }
@@ -88,4 +129,26 @@
                     (mFrameTimes.get(mFrameTimes.size() - 1) - mFrameTimes.get(0));
         }
     }
+
+    /**
+     * Waits for render attached to the view.
+     */
+    public void waitRenderReady() {
+        synchronized (mLock) {
+            while (!mRenderReady) {
+                try {
+                    mLock.wait();
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets/resets frame drawer.
+     */
+    public void setFrameDrawer(@Nullable FrameDrawer frameDrawer) {
+        mFrameDrawer = frameDrawer;
+    }
 }
diff --git a/tests/GamePerformance/src/android/gameperformance/DeviceCallsOpenGLTest.java b/tests/GamePerformance/src/android/gameperformance/DeviceCallsOpenGLTest.java
new file mode 100644
index 0000000..df2ae5c
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/DeviceCallsOpenGLTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.annotation.NonNull;
+
+/**
+ * Tests that verifies maximum number of device calls to render the geometry to keep FPS close to
+ * the device refresh rate. This uses trivial one triangle patch that is rendered multiple times.
+ */
+public class DeviceCallsOpenGLTest extends RenderPatchOpenGLTest  {
+
+    public DeviceCallsOpenGLTest(@NonNull GamePerformanceActivity activity) {
+        super(activity);
+    }
+
+    @Override
+    public String getName() {
+        return "device_calls";
+    }
+
+    @Override
+    public String getUnitName() {
+        return "calls";
+    }
+
+    @Override
+    public double getUnitScale() {
+        return 25.0;
+    }
+
+    @Override
+    public void initUnits(double deviceCallsD) {
+        final List<RenderPatchAnimation> renderPatches = new ArrayList<>();
+        final RenderPatch renderPatch = new RenderPatch(1 /* triangleCount */,
+                                                        0.05f /* dimension */,
+                                                        RenderPatch.TESSELLATION_BASE);
+        final int deviceCalls = (int)Math.round(deviceCallsD);
+        for (int i = 0; i < deviceCalls; ++i) {
+            renderPatches.add(new RenderPatchAnimation(renderPatch, getView().getRenderRatio()));
+        }
+        setRenderPatches(renderPatches);
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/FillRateOpenGLTest.java b/tests/GamePerformance/src/android/gameperformance/FillRateOpenGLTest.java
new file mode 100644
index 0000000..9b26193
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/FillRateOpenGLTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 javax.microedition.khronos.opengles.GL;
+
+import android.annotation.NonNull;
+import android.opengl.GLES20;
+
+/**
+ * Tests that verifies maximum fill rate per frame can be used to keep FPS close to the device
+ * refresh rate. It works in two modes, blend disabled and blend enabled. This uses few big simple
+ * quad patches.
+ */
+public class FillRateOpenGLTest extends RenderPatchOpenGLTest  {
+    private final float[] BLEND_COLOR = new float[] { 1.0f, 1.0f, 1.0f, 0.2f };
+
+    private final boolean mTestBlend;
+
+    public FillRateOpenGLTest(@NonNull GamePerformanceActivity activity, boolean testBlend) {
+        super(activity);
+        mTestBlend = testBlend;
+    }
+
+    @Override
+    public String getName() {
+        return mTestBlend ? "blend_rate" : "fill_rate";
+    }
+
+    @Override
+    public String getUnitName() {
+        return "screens";
+    }
+
+    @Override
+    public double getUnitScale() {
+        return 0.2;
+    }
+
+    @Override
+    public void initUnits(double screens) {
+        final CustomOpenGLView view = getView();
+        final int pixelRate = (int)Math.round(screens * view.getHeight() * view.getWidth());
+        final int maxPerPath = view.getHeight() * view.getHeight();
+
+        final int patchCount = (int)(pixelRate + maxPerPath -1) / maxPerPath;
+        final float patchDimension =
+                (float)((Math.sqrt(2.0f) * pixelRate / patchCount) / maxPerPath);
+
+        final List<RenderPatchAnimation> renderPatches = new ArrayList<>();
+        final RenderPatch renderPatch = new RenderPatch(2 /* triangleCount for quad */,
+                                                        patchDimension,
+                                                        RenderPatch.TESSELLATION_BASE);
+        for (int i = 0; i < patchCount; ++i) {
+            renderPatches.add(new RenderPatchAnimation(renderPatch, getView().getRenderRatio()));
+        }
+        setRenderPatches(renderPatches);
+    }
+
+    @Override
+    public float[] getColor() {
+        return BLEND_COLOR;
+    }
+
+    @Override
+    public void onBeforeDraw(GL gl) {
+        if (!mTestBlend) {
+            return;
+        }
+
+        // Enable blend if needed.
+        GLES20.glEnable(GLES20.GL_BLEND);
+        OpenGLUtils.checkGlError("disableBlend");
+        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
+        OpenGLUtils.checkGlError("blendFunction");
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java b/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java
index b0e6196..dc745f1 100644
--- a/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java
+++ b/tests/GamePerformance/src/android/gameperformance/GamePerformanceActivity.java
@@ -25,14 +25,32 @@
 import android.widget.RelativeLayout;
 
 /**
- * Minimal activity that holds SurfaceView or GLSurfaceView.
- * call attachSurfaceView or attachOpenGLView to switch views.
+ * Minimal activity that holds different types of views.
+ * call attachSurfaceView, attachOpenGLView or attachControlView to switch
+ * the view.
  */
 public class GamePerformanceActivity extends Activity {
     private CustomSurfaceView mSurfaceView = null;
     private CustomOpenGLView mOpenGLView = null;
+    private CustomControlView mControlView = null;
+
     private RelativeLayout mRootLayout;
 
+    private void detachAllViews() {
+        if (mOpenGLView != null) {
+            mRootLayout.removeView(mOpenGLView);
+            mOpenGLView = null;
+        }
+        if (mSurfaceView != null) {
+            mRootLayout.removeView(mSurfaceView);
+            mSurfaceView = null;
+        }
+        if (mControlView != null) {
+            mRootLayout.removeView(mControlView);
+            mControlView = null;
+        }
+    }
+
     public void attachSurfaceView() throws InterruptedException {
         synchronized (mRootLayout) {
             if (mSurfaceView != null) {
@@ -42,10 +60,7 @@
             runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
-                    if (mOpenGLView != null) {
-                        mRootLayout.removeView(mOpenGLView);
-                        mOpenGLView = null;
-                    }
+                    detachAllViews();
                     mSurfaceView = new CustomSurfaceView(GamePerformanceActivity.this);
                     mRootLayout.addView(mSurfaceView);
                     latch.countDown();
@@ -65,10 +80,7 @@
             runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
-                    if (mSurfaceView != null) {
-                        mRootLayout.removeView(mSurfaceView);
-                        mSurfaceView = null;
-                    }
+                    detachAllViews();
                     mOpenGLView = new CustomOpenGLView(GamePerformanceActivity.this);
                     mRootLayout.addView(mOpenGLView);
                     latch.countDown();
@@ -78,6 +90,40 @@
         }
     }
 
+    public void attachControlView() throws InterruptedException {
+        synchronized (mRootLayout) {
+            if (mControlView != null) {
+                return;
+            }
+            final CountDownLatch latch = new CountDownLatch(1);
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    detachAllViews();
+                    mControlView = new CustomControlView(GamePerformanceActivity.this);
+                    mRootLayout.addView(mControlView);
+                    latch.countDown();
+                }
+            });
+            latch.await();
+        }
+    }
+
+
+    public CustomOpenGLView getOpenGLView() {
+        if (mOpenGLView == null) {
+            throw new RuntimeException("OpenGL view is not attached");
+        }
+        return mOpenGLView;
+    }
+
+    public CustomControlView getControlView() {
+        if (mControlView == null) {
+            throw new RuntimeException("Control view is not attached");
+        }
+        return mControlView;
+    }
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -105,6 +151,8 @@
             mSurfaceView.resetFrameTimes();
         } else if (mOpenGLView != null) {
             mOpenGLView.resetFrameTimes();
+        } else if (mControlView != null) {
+            mControlView.resetFrameTimes();
         } else {
             throw new IllegalStateException("Nothing attached");
         }
@@ -115,6 +163,8 @@
             return mSurfaceView.getFps();
         } else if (mOpenGLView != null) {
             return mOpenGLView.getFps();
+        } else if (mControlView != null) {
+            return mControlView.getFps();
         } else {
             throw new IllegalStateException("Nothing attached");
         }
diff --git a/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
index e5de7d7..d6e2861 100644
--- a/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
+++ b/tests/GamePerformance/src/android/gameperformance/GamePerformanceTest.java
@@ -17,14 +17,18 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 
+import android.annotation.NonNull;
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Trace;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -84,4 +88,50 @@
 
         getInstrumentation().sendStatus(Activity.RESULT_OK, status);
     }
+
+    @SmallTest
+    public void testPerformanceMetricsWithoutExtraLoad() throws IOException, InterruptedException {
+        final Bundle status = runPerformanceTests("no_extra_load_");
+        getInstrumentation().sendStatus(Activity.RESULT_OK, status);
+    }
+
+    @SmallTest
+    public void testPerformanceMetricsWithExtraLoad() throws IOException, InterruptedException {
+        // Start CPU ballast threads first.
+        CPULoadThread[] cpuLoadThreads = new CPULoadThread[2];
+        for (int i = 0; i < cpuLoadThreads.length; ++i) {
+            cpuLoadThreads[i] = new CPULoadThread();
+            cpuLoadThreads[i].start();
+        }
+
+        final Bundle status = runPerformanceTests("extra_load_");
+
+        for (int i = 0; i < cpuLoadThreads.length; ++i) {
+            cpuLoadThreads[i].issueStopRequest();
+            cpuLoadThreads[i].join();
+        }
+
+        getInstrumentation().sendStatus(Activity.RESULT_OK, status);
+    }
+
+    @NonNull
+    private Bundle runPerformanceTests(@NonNull String prefix) {
+        final Bundle status = new Bundle();
+
+        final GamePerformanceActivity activity = getActivity();
+
+        final List<BaseTest> tests = new ArrayList<>();
+        tests.add(new TriangleCountOpenGLTest(activity));
+        tests.add(new FillRateOpenGLTest(activity, false /* testBlend */));
+        tests.add(new FillRateOpenGLTest(activity, true /* testBlend */));
+        tests.add(new DeviceCallsOpenGLTest(activity));
+        tests.add(new ControlsTest(activity));
+
+        for (BaseTest test : tests) {
+            final double result = test.run();
+            status.putDouble(prefix + test.getName(), result);
+        }
+
+        return status;
+    }
 }
diff --git a/tests/GamePerformance/src/android/gameperformance/OpenGLTest.java b/tests/GamePerformance/src/android/gameperformance/OpenGLTest.java
new file mode 100644
index 0000000..1d3f95c
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/OpenGLTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.annotation.NonNull;
+import android.gameperformance.CustomOpenGLView.FrameDrawer;
+
+/**
+ * Base class for all OpenGL based tests.
+ */
+public abstract class OpenGLTest extends BaseTest {
+    public OpenGLTest(@NonNull GamePerformanceActivity activity) {
+        super(activity);
+    }
+
+    @NonNull
+    public CustomOpenGLView getView() {
+        return getActivity().getOpenGLView();
+    }
+
+    // Performs test drawing.
+    protected abstract void draw(GL gl);
+
+    // Initializes the test on first draw call.
+    private class ParamFrameDrawer implements FrameDrawer {
+        private final double mUnitCount;
+        private boolean mInited;
+
+        public ParamFrameDrawer(double unitCount) {
+            mUnitCount = unitCount;
+            mInited = false;
+        }
+
+        @Override
+        public void drawFrame(GL10 gl) {
+            if (!mInited) {
+                initUnits(mUnitCount);
+                mInited = true;
+            }
+            draw(gl);
+        }
+    }
+
+    @Override
+    protected void initProbePass(int probe) {
+        try {
+            getActivity().attachOpenGLView();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            return;
+        }
+        getView().waitRenderReady();
+        getView().setFrameDrawer(new ParamFrameDrawer(probe * getUnitScale()));
+    }
+
+    @Override
+    protected void freeProbePass() {
+        getView().setFrameDrawer(null);
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/OpenGLUtils.java b/tests/GamePerformance/src/android/gameperformance/OpenGLUtils.java
new file mode 100644
index 0000000..4f98c52
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/OpenGLUtils.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.gameperformance;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.graphics.BitmapFactory;
+import android.opengl.GLES20;
+import android.opengl.GLUtils;
+import android.util.Log;
+
+/**
+ * Helper class for OpenGL.
+ */
+public class OpenGLUtils {
+    private final static String TAG = "OpenGLUtils";
+
+    public static void checkGlError(String glOperation) {
+        final int error = GLES20.glGetError();
+        if (error == GLES20.GL_NO_ERROR) {
+            return;
+        }
+        final String errorMessage = glOperation + ": glError " + error;
+        Log.e(TAG, errorMessage);
+    }
+
+    public static int loadShader(int type, String shaderCode) {
+        final int shader = GLES20.glCreateShader(type);
+        checkGlError("createShader");
+
+        GLES20.glShaderSource(shader, shaderCode);
+        checkGlError("shaderSource");
+        GLES20.glCompileShader(shader);
+        checkGlError("shaderCompile");
+
+        return shader;
+    }
+
+    public static int createProgram(@NonNull String vertexShaderCode,
+                                    @NonNull String fragmentShaderCode) {
+        final int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
+        final int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+
+        final int program = GLES20.glCreateProgram();
+        checkGlError("createProgram");
+        GLES20.glAttachShader(program, vertexShader);
+        checkGlError("attachVertexShader");
+        GLES20.glAttachShader(program, fragmentShader);
+        checkGlError("attachFragmentShader");
+        GLES20.glLinkProgram(program);
+        checkGlError("linkProgram");
+
+        return program;
+    }
+
+    public static int createTexture(@NonNull Context context, int resource) {
+        final BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inScaled = false;
+
+        final int[] textureHandle = new int[1];
+        GLES20.glGenTextures(1, textureHandle, 0);
+        OpenGLUtils.checkGlError("GenTextures");
+        final int handle = textureHandle[0];
+
+        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, handle);
+        GLES20.glTexParameteri(
+                GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+        GLES20.glTexParameteri(
+                GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
+        GLUtils.texImage2D(
+                GLES20.GL_TEXTURE_2D,
+                0,
+                BitmapFactory.decodeResource(
+                        context.getResources(), resource, options),
+                0);
+
+        return handle;
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/RenderPatch.java b/tests/GamePerformance/src/android/gameperformance/RenderPatch.java
new file mode 100644
index 0000000..2e69a61
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/RenderPatch.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Helper class that generates patch to render. Patch is a regular polygon with the center in 0.
+ * Regular polygon fits in circle with requested radius.
+ */
+public class RenderPatch {
+    public static final int FLOAT_SIZE = 4;
+    public static final int SHORT_SIZE = 2;
+    public static final int VERTEX_COORD_COUNT = 3;
+    public static final int VERTEX_STRIDE = VERTEX_COORD_COUNT * FLOAT_SIZE;
+    public static final int TEXTURE_COORD_COUNT = 2;
+    public static final int TEXTURE_STRIDE = TEXTURE_COORD_COUNT * FLOAT_SIZE;
+
+    // Tessellation is done using points on circle.
+    public static final int TESSELLATION_BASE = 0;
+    // Tesselation is done using extra point in 0.
+    public static final int TESSELLATION_TO_CENTER = 1;
+
+    // Radius of circle that fits polygon.
+    private final float mDimension;
+
+    private final ByteBuffer mVertexBuffer;
+    private final ByteBuffer mTextureBuffer;
+    private final ByteBuffer mIndexBuffer;
+
+    public RenderPatch(int triangleCount, float dimension, int tessellation) {
+        mDimension = dimension;
+
+        int pointCount;
+        int externalPointCount;
+
+        if (triangleCount < 1) {
+            throw new IllegalArgumentException("Too few triangles to perform tessellation");
+        }
+
+        switch (tessellation) {
+        case TESSELLATION_BASE:
+            externalPointCount = triangleCount + 2;
+            pointCount = externalPointCount;
+            break;
+        case TESSELLATION_TO_CENTER:
+            if (triangleCount < 3) {
+                throw new IllegalArgumentException(
+                        "Too few triangles to perform tessellation to center");
+            }
+            externalPointCount = triangleCount;
+            pointCount = triangleCount + 1;
+            break;
+        default:
+            throw new IllegalArgumentException("Wrong tesselation requested");
+        }
+
+        if (pointCount > Short.MAX_VALUE) {
+            throw new IllegalArgumentException("Number of requested triangles is too big");
+        }
+
+        mVertexBuffer = ByteBuffer.allocateDirect(pointCount * VERTEX_STRIDE);
+        mVertexBuffer.order(ByteOrder.nativeOrder());
+
+        mTextureBuffer = ByteBuffer.allocateDirect(pointCount * TEXTURE_STRIDE);
+        mTextureBuffer.order(ByteOrder.nativeOrder());
+
+        for (int i = 0; i < externalPointCount; ++i) {
+            // Use 45 degree rotation to make quad aligned along axises in case
+            // triangleCount is four.
+            final double angle = Math.PI * 0.25 + (Math.PI * 2.0 * i) / (externalPointCount);
+            // Positions
+            mVertexBuffer.putFloat((float) (dimension * Math.sin(angle)));
+            mVertexBuffer.putFloat((float) (dimension * Math.cos(angle)));
+            mVertexBuffer.putFloat(0.0f);
+            // Texture coordinates.
+            mTextureBuffer.putFloat((float) (0.5 + 0.5 * Math.sin(angle)));
+            mTextureBuffer.putFloat((float) (0.5 - 0.5 * Math.cos(angle)));
+        }
+
+        if (tessellation == TESSELLATION_TO_CENTER) {
+            // Add center point.
+            mVertexBuffer.putFloat(0.0f);
+            mVertexBuffer.putFloat(0.0f);
+            mVertexBuffer.putFloat(0.0f);
+            mTextureBuffer.putFloat(0.5f);
+            mTextureBuffer.putFloat(0.5f);
+        }
+
+        mIndexBuffer =
+                ByteBuffer.allocateDirect(
+                        triangleCount * 3 /* indices per triangle */ * SHORT_SIZE);
+        mIndexBuffer.order(ByteOrder.nativeOrder());
+
+        switch (tessellation) {
+        case TESSELLATION_BASE:
+            for (int i = 0; i < triangleCount; ++i) {
+                mIndexBuffer.putShort((short) 0);
+                mIndexBuffer.putShort((short) (i + 1));
+                mIndexBuffer.putShort((short) (i + 2));
+            }
+            break;
+        case TESSELLATION_TO_CENTER:
+            for (int i = 0; i < triangleCount; ++i) {
+                mIndexBuffer.putShort((short)i);
+                mIndexBuffer.putShort((short)((i + 1) % externalPointCount));
+                mIndexBuffer.putShort((short)externalPointCount);
+            }
+            break;
+        }
+
+        if (mVertexBuffer.remaining() != 0 || mTextureBuffer.remaining() != 0 || mIndexBuffer.remaining() != 0) {
+            throw new RuntimeException("Failed to fill buffers");
+        }
+
+        mVertexBuffer.position(0);
+        mTextureBuffer.position(0);
+        mIndexBuffer.position(0);
+    }
+
+    public float getDimension() {
+        return mDimension;
+    }
+
+    public ByteBuffer getVertexBuffer() {
+        return mVertexBuffer;
+    }
+
+    public ByteBuffer getTextureBuffer() {
+        return mTextureBuffer;
+    }
+
+    public ByteBuffer getIndexBuffer() {
+        return mIndexBuffer;
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/RenderPatchAnimation.java b/tests/GamePerformance/src/android/gameperformance/RenderPatchAnimation.java
new file mode 100644
index 0000000..7dcdb00
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/RenderPatchAnimation.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.Random;
+
+import android.annotation.NonNull;
+import android.opengl.Matrix;
+
+/**
+ * Class that performs bouncing animation for RenderPatch on the screen.
+ */
+public class RenderPatchAnimation {
+    private final static Random RANDOM = new Random();
+
+    private final RenderPatch mRenderPatch;
+    // Bounds of animation
+    private final float mAvailableX;
+    private final float mAvailableY;
+
+    // Crurrent position.
+    private float mPosX;
+    private float mPosY;
+    // Direction of movement.
+    private float mDirX;
+    private float mDirY;
+
+    private float[] mMatrix;
+
+    public RenderPatchAnimation(@NonNull RenderPatch renderPatch, float ratio) {
+        mRenderPatch = renderPatch;
+
+        mAvailableX = ratio - mRenderPatch.getDimension();
+        mAvailableY = 1.0f - mRenderPatch.getDimension();
+
+        mPosX = 2.0f * mAvailableX * RANDOM.nextFloat() - mAvailableX;
+        mPosY = 2.0f * mAvailableY * RANDOM.nextFloat() - mAvailableY;
+        mMatrix = new float[16];
+
+        // Evenly distributed in cycle, normalized.
+        while (true) {
+            mDirX = 2.0f * RANDOM.nextFloat() - 1.0f;
+            mDirY = mRenderPatch.getDimension() < 1.0f ? 2.0f * RANDOM.nextFloat() - 1.0f : 0.0f;
+
+            final float length = (float)Math.sqrt(mDirX * mDirX + mDirY * mDirY);
+            if (length <= 1.0f && length > 0.0f) {
+                mDirX /= length;
+                mDirY /= length;
+                break;
+            }
+        }
+    }
+
+    @NonNull
+    public RenderPatch getRenderPatch() {
+        return mRenderPatch;
+    }
+
+    /**
+     * Performs the next update. t specifies the distance to travel along the direction. This checks
+     * if patch goes out of screen and invert axis direction if needed.
+     */
+    public void update(float t) {
+        mPosX += mDirX * t;
+        mPosY += mDirY * t;
+        if (mPosX < -mAvailableX) {
+            mDirX = Math.abs(mDirX);
+        } else if (mPosX > mAvailableX) {
+            mDirX = -Math.abs(mDirX);
+        }
+        if (mPosY < -mAvailableY) {
+            mDirY = Math.abs(mDirY);
+        } else if (mPosY > mAvailableY) {
+            mDirY = -Math.abs(mDirY);
+        }
+    }
+
+    /**
+     * Returns Model/View/Projection transform for the patch.
+     */
+    public float[] getTransform(@NonNull float[] vpMatrix) {
+        Matrix.setIdentityM(mMatrix, 0);
+        mMatrix[12] = mPosX;
+        mMatrix[13] = mPosY;
+        Matrix.multiplyMM(mMatrix, 0, vpMatrix, 0, mMatrix, 0);
+        return mMatrix;
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/RenderPatchOpenGLTest.java b/tests/GamePerformance/src/android/gameperformance/RenderPatchOpenGLTest.java
new file mode 100644
index 0000000..7492cc0
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/RenderPatchOpenGLTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.List;
+
+import javax.microedition.khronos.opengles.GL;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.opengl.GLES20;
+import android.opengl.Matrix;
+
+/**
+ * Base class for all OpenGL based tests that use RenderPatch as a base.
+ */
+public abstract class RenderPatchOpenGLTest extends OpenGLTest {
+    private final float[] COLOR = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
+
+    private final String VERTEX_SHADER =
+            "uniform mat4 uMVPMatrix;"
+                    + "attribute vec4 vPosition;"
+                    + "attribute vec2 vTexture;"
+                    + "varying vec2 vTex;"
+                    + "void main() {"
+                    + "  vTex = vTexture;"
+                    + "  gl_Position = uMVPMatrix * vPosition;"
+                    + "}";
+
+    private final String FRAGMENT_SHADER =
+            "precision mediump float;"
+                    + "uniform sampler2D uTexture;"
+                    + "uniform vec4 uColor;"
+                    + "varying vec2 vTex;"
+                    + "void main() {"
+                    + "  vec4 color = texture2D(uTexture, vTex);"
+                    + "  gl_FragColor = uColor * color;"
+                    + "}";
+
+    private List<RenderPatchAnimation> mRenderPatches;
+
+    private int mProgram = -1;
+    private int mMVPMatrixHandle;
+    private int mTextureHandle;
+    private int mPositionHandle;
+    private int mColorHandle;
+    private int mTextureCoordHandle;
+
+    private final float[] mVPMatrix = new float[16];
+
+    public RenderPatchOpenGLTest(@NonNull GamePerformanceActivity activity) {
+        super(activity);
+    }
+
+    protected void setRenderPatches(@NonNull List<RenderPatchAnimation> renderPatches) {
+        mRenderPatches = renderPatches;
+    }
+
+    private void ensureInited() {
+        if (mProgram >= 0) {
+            return;
+        }
+
+        mProgram = OpenGLUtils.createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+
+        // get handle to fragment shader's uColor member
+        GLES20.glUseProgram(mProgram);
+        OpenGLUtils.checkGlError("useProgram");
+
+        // get handle to shape's transformation matrix
+        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+        OpenGLUtils.checkGlError("get uMVPMatrix");
+
+        mTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTexture");
+        OpenGLUtils.checkGlError("uTexture");
+        // get handle to vertex shader's vPosition member
+        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
+        OpenGLUtils.checkGlError("vPosition");
+        mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "vTexture");
+        OpenGLUtils.checkGlError("vTexture");
+        mColorHandle = GLES20.glGetUniformLocation(mProgram, "uColor");
+        OpenGLUtils.checkGlError("uColor");
+
+        mTextureHandle = OpenGLUtils.createTexture(getContext(), R.drawable.logo);
+
+        final float[] projectionMatrix = new float[16];
+        final float[] viewMatrix = new float[16];
+
+        final float ratio = getView().getRenderRatio();
+        Matrix.orthoM(projectionMatrix, 0, -ratio, ratio, -1, 1, -1, 1);
+        Matrix.setLookAtM(viewMatrix, 0, 0, 0, -0.5f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+        Matrix.multiplyMM(mVPMatrix, 0, projectionMatrix, 0, viewMatrix, 0);
+    }
+
+    /**
+     * Returns global color for patch.
+     */
+    public float[] getColor() {
+        return COLOR;
+    }
+
+    /**
+     * Extra setup for particular tests.
+     */
+    public void onBeforeDraw(GL gl) {
+    }
+
+    @Override
+    public void draw(GL gl) {
+        ensureInited();
+
+        GLES20.glUseProgram(mProgram);
+        OpenGLUtils.checkGlError("useProgram");
+
+        GLES20.glDisable(GLES20.GL_BLEND);
+        OpenGLUtils.checkGlError("disableBlend");
+
+        GLES20.glEnableVertexAttribArray(mPositionHandle);
+        OpenGLUtils.checkGlError("enableVertexAttributes");
+
+        GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
+        OpenGLUtils.checkGlError("enableTexturesAttributes");
+
+        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureHandle);
+        OpenGLUtils.checkGlError("setTexture");
+
+        GLES20.glUniform4fv(mColorHandle, 1, getColor(), 0);
+        OpenGLUtils.checkGlError("setColor");
+
+        onBeforeDraw(gl);
+
+        for (final RenderPatchAnimation renderPatchAnimation : mRenderPatches) {
+
+            renderPatchAnimation.update(0.01f);
+            GLES20.glUniformMatrix4fv(mMVPMatrixHandle,
+                                      1,
+                                      false,
+                                      renderPatchAnimation.getTransform(mVPMatrix),
+                                      0);
+            OpenGLUtils.checkGlError("setTransform");
+
+            GLES20.glVertexAttribPointer(
+                    mPositionHandle,
+                    RenderPatch.VERTEX_COORD_COUNT,
+                    GLES20.GL_FLOAT,
+                    false /* normalized */,
+                    RenderPatch.VERTEX_STRIDE,
+                    renderPatchAnimation.getRenderPatch().getVertexBuffer());
+            OpenGLUtils.checkGlError("setVertexAttribute");
+
+            GLES20.glVertexAttribPointer(
+                    mTextureCoordHandle,
+                    RenderPatch.TEXTURE_COORD_COUNT,
+                    GLES20.GL_FLOAT,
+                    false /* normalized */,
+                    RenderPatch.TEXTURE_STRIDE,
+                    renderPatchAnimation.getRenderPatch().getTextureBuffer());
+            OpenGLUtils.checkGlError("setTextureAttribute");
+
+            // Draw the patch.
+            final int indicesCount =
+                    renderPatchAnimation.getRenderPatch().getIndexBuffer().capacity() /
+                    RenderPatch.SHORT_SIZE;
+            GLES20.glDrawElements(
+                    GLES20.GL_TRIANGLES,
+                    indicesCount,
+                    GLES20.GL_UNSIGNED_SHORT,
+                    renderPatchAnimation.getRenderPatch().getIndexBuffer());
+            OpenGLUtils.checkGlError("drawPatch");
+        }
+
+        GLES20.glDisableVertexAttribArray(mPositionHandle);
+        GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
+    }
+}
\ No newline at end of file
diff --git a/tests/GamePerformance/src/android/gameperformance/TriangleCountOpenGLTest.java b/tests/GamePerformance/src/android/gameperformance/TriangleCountOpenGLTest.java
new file mode 100644
index 0000000..593f37b
--- /dev/null
+++ b/tests/GamePerformance/src/android/gameperformance/TriangleCountOpenGLTest.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 android.gameperformance;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.annotation.NonNull;
+
+/**
+ * Test that measures maximum amount of triangles can be rasterized keeping FPS close to the device
+ * refresh rate. It is has very few devices call and each call contains big amount of triangles.
+ * Total filling area is around one screen.
+ */
+public class TriangleCountOpenGLTest extends RenderPatchOpenGLTest  {
+    // Based on index buffer of short values.
+    private final static int MAX_TRIANGLES_IN_PATCH = 32000;
+
+    public TriangleCountOpenGLTest(@NonNull GamePerformanceActivity activity) {
+        super(activity);
+    }
+
+    @Override
+    public String getName() {
+        return "triangle_count";
+    }
+
+    @Override
+    public String getUnitName() {
+        return "ktriangles";
+    }
+
+    @Override
+    public double getUnitScale() {
+        return 2.0;
+    }
+
+    @Override
+    public void initUnits(double trianlgeCountD) {
+        final int triangleCount = (int)Math.round(trianlgeCountD * 1000.0);
+        final List<RenderPatchAnimation> renderPatches = new ArrayList<>();
+        final int patchCount =
+                (triangleCount + MAX_TRIANGLES_IN_PATCH - 1) / MAX_TRIANGLES_IN_PATCH;
+        final int patchTriangleCount = triangleCount / patchCount;
+        for (int i = 0; i < patchCount; ++i) {
+            final RenderPatch renderPatch = new RenderPatch(patchTriangleCount,
+                                                            0.5f /* dimension */,
+                                                            RenderPatch.TESSELLATION_TO_CENTER);
+            renderPatches.add(new RenderPatchAnimation(renderPatch, getView().getRenderRatio()));
+        }
+        setRenderPatches(renderPatches);
+    }
+}
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/res/drawable-hdpi/sunset1.jpg b/tests/HwAccelerationTest/res/drawable-hdpi/sunset1.jpg
index 92851f3..086c055 100644
--- a/tests/HwAccelerationTest/res/drawable-hdpi/sunset1.jpg
+++ b/tests/HwAccelerationTest/res/drawable-hdpi/sunset1.jpg
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
index 7f047b1..6e1a866 100644
--- a/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
+++ b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
Binary files differ
diff --git a/tests/HwAccelerationTest/res/drawable/sunset1.jpg b/tests/HwAccelerationTest/res/drawable/sunset1.jpg
index 92851f3..3b4e056 100644
--- a/tests/HwAccelerationTest/res/drawable/sunset1.jpg
+++ b/tests/HwAccelerationTest/res/drawable/sunset1.jpg
Binary files differ
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
index 17fa931..f88a7c4 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -47,17 +47,19 @@
 @RunWith(AndroidJUnit4.class)
 public class ColorExtractorTest {
 
-    Context mContext;
+    private Context mContext;
+    private WallpaperManager mWallpaperManager;
 
     @Before
     public void setup() {
         mContext = InstrumentationRegistry.getContext();
+        mWallpaperManager = mock(WallpaperManager.class);
     }
 
     @Test
     public void ColorExtractor_extractWhenInitialized() {
         ExtractionType type = mock(Tonal.class);
-        new ColorExtractor(mContext, type, true);
+        new ColorExtractor(mContext, type, true, mWallpaperManager);
         // 1 for lock and 1 for system
         verify(type, times(2))
                 .extractInto(any(), any(), any(), any());
@@ -84,7 +86,7 @@
                     outGradientColorsDark.set(colorsExpectedDark);
                     outGradientColorsExtraDark.set(colorsExpectedExtraDark);
                 };
-        ColorExtractor extractor = new ColorExtractor(mContext, type, true);
+        ColorExtractor extractor = new ColorExtractor(mContext, type, true, mWallpaperManager);
 
         GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM,
                 ColorExtractor.TYPE_NORMAL);
@@ -99,7 +101,8 @@
     public void addOnColorsChangedListener_invokesListener() {
         ColorExtractor.OnColorsChangedListener mockedListeners =
                 mock(ColorExtractor.OnColorsChangedListener.class);
-        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext), true);
+        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext), true,
+                mWallpaperManager);
         extractor.addOnColorsChangedListener(mockedListeners);
 
         extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),
diff --git a/tests/JobSchedulerPerfTests/Android.bp b/tests/JobSchedulerPerfTests/Android.bp
new file mode 100644
index 0000000..2230807
--- /dev/null
+++ b/tests/JobSchedulerPerfTests/Android.bp
@@ -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.
+
+android_test {
+    name: "JobSchedulerPerfTests",
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "androidx.test.rules",
+        "apct-perftests-utils",
+        "services",
+    ],
+    platform_apis: true,
+    certificate: "platform",
+}
diff --git a/tests/JobSchedulerPerfTests/AndroidManifest.xml b/tests/JobSchedulerPerfTests/AndroidManifest.xml
new file mode 100644
index 0000000..39e751c
--- /dev/null
+++ b/tests/JobSchedulerPerfTests/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?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.frameworks.perftests.job">
+    <uses-sdk
+            android:minSdkVersion="21" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.frameworks.perftests.job"/>
+</manifest>
diff --git a/tests/JobSchedulerPerfTests/AndroidTest.xml b/tests/JobSchedulerPerfTests/AndroidTest.xml
new file mode 100644
index 0000000..ca4b6c8
--- /dev/null
+++ b/tests/JobSchedulerPerfTests/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 JobScheduler Performance Tests">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="JobSchedulerPerfTests.apk"/>
+        <option name="cleanup-apks" value="true"/>
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-tag" value="JobSchedulerPerfTests"/>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+        <option name="package" value="com.android.frameworks.perftests.job"/>
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
+    </test>
+</configuration>
diff --git a/tests/JobSchedulerPerfTests/src/com/android/frameworks/perftests/job/JobStorePerfTests.java b/tests/JobSchedulerPerfTests/src/com/android/frameworks/perftests/job/JobStorePerfTests.java
new file mode 100644
index 0000000..e956be3
--- /dev/null
+++ b/tests/JobSchedulerPerfTests/src/com/android/frameworks/perftests/job/JobStorePerfTests.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.frameworks.perftests.job;
+
+
+import android.app.job.JobInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.SystemClock;
+import android.perftests.utils.ManualBenchmarkState;
+import android.perftests.utils.PerfManualStatusReporter;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.job.JobStore;
+import com.android.server.job.JobStore.JobSet;
+import com.android.server.job.controllers.JobStatus;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class JobStorePerfTests {
+    private static final String SOURCE_PACKAGE = "com.android.frameworks.perftests.job";
+    private static final int SOURCE_USER_ID = 0;
+    private static final int CALLING_UID = 10079;
+
+    private static Context sContext;
+    private static File sTestDir;
+    private static JobStore sJobStore;
+
+    private static List<JobStatus> sFewJobs = new ArrayList<>();
+    private static List<JobStatus> sManyJobs = new ArrayList<>();
+
+    @Rule
+    public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter();
+
+    @BeforeClass
+    public static void setUpOnce() {
+        sContext = InstrumentationRegistry.getTargetContext();
+        sTestDir = new File(sContext.getFilesDir(), "JobStorePerfTests");
+        sJobStore = JobStore.initAndGetForTesting(sContext, sTestDir);
+
+        for (int i = 0; i < 50; i++) {
+            sFewJobs.add(createJobStatus("fewJobs", i));
+        }
+        for (int i = 0; i < 500; i++) {
+            sManyJobs.add(createJobStatus("manyJobs", i));
+        }
+    }
+
+    @AfterClass
+    public static void tearDownOnce() {
+        sTestDir.deleteOnExit();
+    }
+
+    private void runPersistedJobWriting(List<JobStatus> jobList) {
+        final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState();
+
+        long elapsedTimeNs = 0;
+        while (benchmarkState.keepRunning(elapsedTimeNs)) {
+            sJobStore.clear();
+            for (JobStatus job : jobList) {
+                sJobStore.add(job);
+            }
+            sJobStore.waitForWriteToCompleteForTesting(10_000);
+
+            final long startTime = SystemClock.elapsedRealtimeNanos();
+            sJobStore.writeStatusToDiskForTesting();
+            final long endTime = SystemClock.elapsedRealtimeNanos();
+            elapsedTimeNs = endTime - startTime;
+        }
+    }
+
+    @Test
+    public void testPersistedJobWriting_fewJobs() {
+        runPersistedJobWriting(sFewJobs);
+    }
+
+    @Test
+    public void testPersistedJobWriting_manyJobs() {
+        runPersistedJobWriting(sManyJobs);
+    }
+
+    private void runPersistedJobReading(List<JobStatus> jobList, boolean rtcIsGood) {
+        final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState();
+
+        long elapsedTimeNs = 0;
+        while (benchmarkState.keepRunning(elapsedTimeNs)) {
+            sJobStore.clear();
+            for (JobStatus job : jobList) {
+                sJobStore.add(job);
+            }
+            sJobStore.waitForWriteToCompleteForTesting(10_000);
+
+            JobSet jobSet = new JobSet();
+
+            final long startTime = SystemClock.elapsedRealtimeNanos();
+            sJobStore.readJobMapFromDisk(jobSet, rtcIsGood);
+            final long endTime = SystemClock.elapsedRealtimeNanos();
+            elapsedTimeNs = endTime - startTime;
+        }
+    }
+
+    @Test
+    public void testPersistedJobReading_fewJobs_goodRTC() {
+        runPersistedJobReading(sFewJobs, true);
+    }
+
+    @Test
+    public void testPersistedJobReading_fewJobs_badRTC() {
+        runPersistedJobReading(sFewJobs, false);
+    }
+
+    @Test
+    public void testPersistedJobReading_manyJobs_goodRTC() {
+        runPersistedJobReading(sManyJobs, true);
+    }
+
+    @Test
+    public void testPersistedJobReading_manyJobs_badRTC() {
+        runPersistedJobReading(sManyJobs, false);
+    }
+
+    private static JobStatus createJobStatus(String testTag, int jobId) {
+        JobInfo jobInfo = new JobInfo.Builder(jobId,
+                new ComponentName(sContext, "JobStorePerfTestJobService"))
+                .setPersisted(true)
+                .build();
+        return JobStatus.createFromJobInfo(
+                jobInfo, CALLING_UID, SOURCE_PACKAGE, SOURCE_USER_ID, testTag);
+    }
+}
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBoolTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBoolTest.java
index c21c403..3415d2e 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBoolTest.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBoolTest.java
@@ -384,55 +384,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBytesTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBytesTest.java
index 09fe40e..8796807 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBytesTest.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamBytesTest.java
@@ -306,55 +306,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamDoubleTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamDoubleTest.java
index 118fe34..2b54e96 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamDoubleTest.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamDoubleTest.java
@@ -611,55 +611,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamEnumTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamEnumTest.java
index f55d951..19bad70 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamEnumTest.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamEnumTest.java
@@ -454,55 +454,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed32Test.java
index df68476..2bc61a0 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed32Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed32Test.java
@@ -431,55 +431,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed64Test.java
index af4130b..a54ecf9 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed64Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFixed64Test.java
@@ -532,55 +532,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFloatTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFloatTest.java
index 9bc07dc..0477e9e 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFloatTest.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamFloatTest.java
@@ -563,55 +563,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt32Test.java
index 0065870..a7f3f65 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt32Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt32Test.java
@@ -449,55 +449,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt64Test.java
index 4d6d105..dc42468 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt64Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamInt64Test.java
@@ -529,55 +529,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamObjectTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamObjectTest.java
index 5e49eea..1c0832e 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamObjectTest.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamObjectTest.java
@@ -391,55 +391,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed32Test.java
index 75c88a4..d349ea2 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed32Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed32Test.java
@@ -431,55 +431,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed64Test.java
index 4c65cf4..81a9c59 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed64Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSFixed64Test.java
@@ -531,55 +531,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt32Test.java
index 6854cd8..9719444 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt32Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt32Test.java
@@ -431,55 +431,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt64Test.java
index c53e9d7..118476c 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt64Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamSInt64Test.java
@@ -506,55 +506,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamStringTest.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamStringTest.java
index 816d5f9..51ee78f 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamStringTest.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamStringTest.java
@@ -287,55 +287,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt32Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt32Test.java
index 50fc537..42f3e99 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt32Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt32Test.java
@@ -448,55 +448,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readLong(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt64Test.java b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt64Test.java
index 20969e9..8ba2c0c 100644
--- a/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt64Test.java
+++ b/tests/ProtoInputStreamTests/src/com/android/test/protoinputstream/ProtoInputStreamUInt64Test.java
@@ -525,55 +525,55 @@
         };
 
         ProtoInputStream pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readFloat(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readDouble(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readInt(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBoolean(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readBytes(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
 
         pi = new ProtoInputStream(protobuf);
-        pi.isNextField(fieldId1);
+        pi.nextField();
         try {
             pi.readString(fieldId1);
-            fail("Should have throw IllegalArgumentException");
+            fail("Should have thrown IllegalArgumentException");
         } catch (IllegalArgumentException iae) {
             // good
         }
diff --git a/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg b/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg
index 755232d..14d6027 100644
--- a/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg
+++ b/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg
Binary files differ
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
index aec4055..2bd5931 100644
--- a/tests/RollbackTest/Android.bp
+++ b/tests/RollbackTest/Android.bp
@@ -12,88 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-android_test_helper_app {
-    name: "RollbackTestAppAv1",
-    manifest: "TestApp/Av1.xml",
-    sdk_version: "current",
-    srcs: ["TestApp/src/**/*.java"],
-    resource_dirs: ["TestApp/res_v1"],
-}
-
-android_test_helper_app {
-    name: "RollbackTestAppAv2",
-    manifest: "TestApp/Av2.xml",
-    sdk_version: "current",
-    srcs: ["TestApp/src/**/*.java"],
-    resource_dirs: ["TestApp/res_v2"],
-}
-
-android_test_helper_app {
-    name: "RollbackTestAppAv3",
-    manifest: "TestApp/Av3.xml",
-    sdk_version: "current",
-    srcs: ["TestApp/src/**/*.java"],
-    resource_dirs: ["TestApp/res_v3"],
-}
-
-android_test_helper_app {
-    name: "RollbackTestAppACrashingV2",
-    manifest: "TestApp/ACrashingV2.xml",
-    sdk_version: "current",
-    srcs: ["TestApp/src/**/*.java"],
-    resource_dirs: ["TestApp/res_v2"],
-}
-
-android_test_helper_app {
-    name: "RollbackTestAppBv1",
-    manifest: "TestApp/Bv1.xml",
-    sdk_version: "current",
-    srcs: ["TestApp/src/**/*.java"],
-    resource_dirs: ["TestApp/res_v1"],
-}
-
-android_test_helper_app {
-    name: "RollbackTestAppBv2",
-    manifest: "TestApp/Bv2.xml",
-    sdk_version: "current",
-    srcs: ["TestApp/src/**/*.java"],
-    resource_dirs: ["TestApp/res_v2"],
-}
-
-android_test_helper_app {
-    name: "RollbackTestAppASplitV1",
-    manifest: "TestApp/Av1.xml",
-    sdk_version: "current",
-    srcs: ["TestApp/src/**/*.java"],
-    resource_dirs: ["TestApp/res_v1"],
-    package_splits: ["anydpi"],
-}
-
-android_test_helper_app {
-    name: "RollbackTestAppASplitV2",
-    manifest: "TestApp/Av2.xml",
-    sdk_version: "current",
-    srcs: ["TestApp/src/**/*.java"],
-    resource_dirs: ["TestApp/res_v2"],
-    package_splits: ["anydpi"],
-}
-
 android_test {
     name: "RollbackTest",
     manifest: "RollbackTest/AndroidManifest.xml",
     srcs: ["RollbackTest/src/**/*.java"],
-    static_libs: ["androidx.test.rules"],
+    static_libs: ["androidx.test.rules", "cts-rollback-lib", "cts-install-lib"],
     test_suites: ["general-tests"],
-    java_resources: [
-        ":RollbackTestAppAv1",
-        ":RollbackTestAppAv2",
-        ":RollbackTestAppAv3",
-        ":RollbackTestAppACrashingV2",
-        ":RollbackTestAppBv1",
-        ":RollbackTestAppBv2",
-        ":RollbackTestAppASplitV1",
-        ":RollbackTestAppASplitV2",
-    ],
     test_config: "RollbackTest.xml",
     // TODO: sdk_version: "test_current" when Intent#resolveSystemservice is TestApi
 }
@@ -105,3 +29,11 @@
     test_suites: ["general-tests"],
     test_config: "StagedRollbackTest.xml",
 }
+
+java_test_host {
+    name: "SecondaryUserRollbackTest",
+    srcs: ["SecondaryUserRollbackTest/src/**/*.java"],
+    libs: ["tradefed"],
+    test_suites: ["general-tests"],
+    test_config: "SecondaryUserRollbackTest.xml",
+}
diff --git a/tests/RollbackTest/RollbackTest/AndroidManifest.xml b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
index 5380dc9..2b8c964 100644
--- a/tests/RollbackTest/RollbackTest/AndroidManifest.xml
+++ b/tests/RollbackTest/RollbackTest/AndroidManifest.xml
@@ -18,7 +18,7 @@
     package="com.android.tests.rollback" >
 
     <application>
-        <receiver android:name="com.android.tests.rollback.LocalIntentSender"
+        <receiver android:name="com.android.cts.install.lib.LocalIntentSender"
                   android:exported="true" />
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java
deleted file mode 100644
index 267ef73..0000000
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/LocalIntentSender.java
+++ /dev/null
@@ -1,60 +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.tests.rollback;
-
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * Make IntentSender that sends intent locally.
- */
-public class LocalIntentSender extends BroadcastReceiver {
-
-    private static final String TAG = "RollbackTest";
-
-    private static final BlockingQueue<Intent> sIntentSenderResults = new LinkedBlockingQueue<>();
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        sIntentSenderResults.add(intent);
-    }
-
-    /**
-     * Get a LocalIntentSender.
-     */
-    static IntentSender getIntentSender() {
-        Context context = InstrumentationRegistry.getContext();
-        Intent intent = new Intent(context, LocalIntentSender.class);
-        PendingIntent pending = PendingIntent.getBroadcast(context, 0, intent, 0);
-        return pending.getIntentSender();
-    }
-
-    /**
-     * Returns the most recent Intent sent by a LocalIntentSender.
-     */
-    static Intent getIntentSenderResult() throws InterruptedException {
-        return sIntentSenderResults.take();
-    }
-}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java
deleted file mode 100644
index ebe5418..0000000
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java
+++ /dev/null
@@ -1,78 +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.tests.rollback;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A broadcast receiver that can be used to get
- * ACTION_ROLLBACK_COMMITTED broadcasts.
- */
-class RollbackBroadcastReceiver extends BroadcastReceiver {
-
-    private static final String TAG = "RollbackTest";
-
-    private final BlockingQueue<Intent> mRollbackBroadcasts = new LinkedBlockingQueue<>();
-
-    /**
-     * Creates a RollbackBroadcastReceiver and registers it with the given
-     * context.
-     */
-    RollbackBroadcastReceiver() {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_ROLLBACK_COMMITTED);
-        InstrumentationRegistry.getContext().registerReceiver(this, filter);
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        Log.i(TAG, "Received rollback broadcast intent");
-        mRollbackBroadcasts.add(intent);
-    }
-
-    /**
-     * Polls for at most the given amount of time for the next rollback
-     * broadcast.
-     */
-    Intent poll(long timeout, TimeUnit unit) throws InterruptedException {
-        return mRollbackBroadcasts.poll(timeout, unit);
-    }
-
-    /**
-     * Waits forever for the next rollback broadcast.
-     */
-    Intent take() throws InterruptedException {
-        return mRollbackBroadcasts.take();
-    }
-
-    /**
-     * Unregisters this broadcast receiver.
-     */
-    void unregister() {
-        InstrumentationRegistry.getContext().unregisterReceiver(this);
-    }
-}
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 beff0c6..a27df47 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -16,14 +16,12 @@
 
 package com.android.tests.rollback;
 
-import static com.android.tests.rollback.RollbackTestUtils.assertPackageRollbackInfoEquals;
-import static com.android.tests.rollback.RollbackTestUtils.assertRollbackInfoEquals;
-import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage;
-import static com.android.tests.rollback.RollbackTestUtils.processUserData;
+import static com.android.cts.install.lib.InstallUtils.processUserData;
+import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
+import static com.android.cts.rollback.lib.RollbackUtils.getUniqueRollbackInfoForPackage;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.fail;
 
 import android.Manifest;
@@ -31,15 +29,21 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.VersionedPackage;
 import android.content.rollback.RollbackInfo;
 import android.content.rollback.RollbackManager;
 import android.provider.DeviceConfig;
-import android.provider.Settings;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
+import com.android.cts.install.lib.TestApp;
+import com.android.cts.install.lib.Uninstall;
+import com.android.cts.rollback.lib.Rollback;
+import com.android.cts.rollback.lib.RollbackBroadcastReceiver;
+import com.android.cts.rollback.lib.RollbackUtils;
+
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -57,8 +61,6 @@
 
     private static final String TAG = "RollbackTest";
 
-    private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A";
-    private static final String TEST_APP_B = "com.android.tests.rollback.testapp.B";
     private static final String INSTRUMENTED_APP = "com.android.tests.rollback";
 
     // copied from PackageManagerService#PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS
@@ -88,7 +90,7 @@
         context.registerReceiver(enableRollbackReceiver, enableRollbackFilter);
 
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -97,18 +99,18 @@
             // Register a broadcast receiver for notification when the
             // rollback has been committed.
             RollbackBroadcastReceiver broadcastReceiver = new RollbackBroadcastReceiver();
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
-            // Uninstall TEST_APP_A
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            // Uninstall TestApp.A
+            Uninstall.packages(TestApp.A);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
 
             // TODO: There is currently a race condition between when the app is
             // uninstalled and when rollback manager deletes the rollback. Fix it
             // so that's not the case!
             for (int i = 0; i < 5; ++i) {
                 RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                        rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
+                        rm.getRecentlyCommittedRollbacks(), TestApp.A);
                 if (rollback != null) {
                     Log.i(TAG, "Sleeping 1 second to wait for uninstall to take effect.");
                     Thread.sleep(1000);
@@ -116,50 +118,65 @@
             }
 
             // The app should not be available for rollback.
-            assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+            assertThat(
+                getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
 
             // There should be no recently committed rollbacks for this package.
-            assertNull(getUniqueRollbackInfoForPackage(
-                        rm.getRecentlyCommittedRollbacks(), TEST_APP_A));
+            assertThat(getUniqueRollbackInfoForPackage(
+                        rm.getRecentlyCommittedRollbacks(), TestApp.A)).isNull();
 
             // Install v1 of the app (without rollbacks enabled).
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Install.single(TestApp.A1).commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
 
             // Upgrade from v1 to v2, with rollbacks enabled.
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
             // The app should now be available for rollback.
-            RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+            RollbackInfo available = getUniqueRollbackInfoForPackage(
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(available).isNotNull();
+            assertThat(available).isNotStaged();
+            assertThat(available).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             // We should not have received any rollback requests yet.
             // TODO: Possibly flaky if, by chance, some other app on device
             // happens to be rolled back at the same time?
-            assertNull(broadcastReceiver.poll(0, TimeUnit.SECONDS));
+            assertThat(broadcastReceiver.poll(0, TimeUnit.SECONDS)).isNull();
 
             // Roll back the app.
-            RollbackTestUtils.rollback(rollback.getRollbackId());
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            RollbackUtils.rollback(available.getRollbackId());
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
 
             // Verify we received a broadcast for the rollback.
             // TODO: Race condition between the timeout and when the broadcast is
             // received could lead to test flakiness.
             Intent broadcast = broadcastReceiver.poll(5, TimeUnit.SECONDS);
-            assertNotNull(broadcast);
-            assertNull(broadcastReceiver.poll(0, TimeUnit.SECONDS));
+            if (context.getUser().isSystem()) {
+                // Only system user should receive those broadcasts.
+                assertThat(broadcast).isNotNull();
+                assertThat(broadcastReceiver.poll(0, TimeUnit.SECONDS)).isNull();
+            } else {
+                // This is in case the test was running under a secondary user, in which case
+                // the broadcast won't be received here.
+                assertThat(broadcast).isNull();
+            }
 
             // Verify the recent rollback has been recorded.
-            rollback = getUniqueRollbackInfoForPackage(
-                    rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+            RollbackInfo committed = getUniqueRollbackInfoForPackage(
+                    rm.getRecentlyCommittedRollbacks(), TestApp.A);
+            assertThat(committed).isNotNull();
+            assertThat(committed).isNotStaged();
+            assertThat(committed).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
+            assertThat(committed).hasRollbackId(available.getRollbackId());
 
             broadcastReceiver.unregister();
             context.unregisterReceiver(enableRollbackReceiver);
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -169,50 +186,58 @@
     @Test
     public void testAvailableRollbackPersistence() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
 
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
-            RollbackTestUtils.uninstall(TEST_APP_B);
-            RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            Uninstall.packages(TestApp.B);
+            Install.single(TestApp.B1).commit();
+            Install.single(TestApp.B2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
 
             // Both test apps should now be available for rollback.
             RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollbackA).isNotNull();
+            assertThat(rollbackA).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_B);
-            assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);
+                    rm.getAvailableRollbacks(), TestApp.B);
+            assertThat(rollbackB).isNotNull();
+            assertThat(rollbackB).packagesContainsExactly(
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
             // Reload the persisted data.
             rm.reloadPersistedData();
 
             // The apps should still be available for rollback.
             rollbackA = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollbackA).isNotNull();
+            assertThat(rollbackA).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             rollbackB = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_B);
-            assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);
+                    rm.getAvailableRollbacks(), TestApp.B);
+            assertThat(rollbackB).isNotNull();
+            assertThat(rollbackB).packagesContainsExactly(
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
             // Rollback of B should not rollback A
-            RollbackTestUtils.rollback(rollbackB.getRollbackId());
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            RollbackUtils.rollback(rollbackB.getRollbackId());
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -222,49 +247,78 @@
     @Test
     public void testAvailableMultiPackageRollbackPersistence() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
 
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.uninstall(TEST_APP_B);
-            RollbackTestUtils.installMultiPackage(false,
-                    "RollbackTestAppAv1.apk",
-                    "RollbackTestAppBv1.apk");
-            RollbackTestUtils.installMultiPackage(true,
-                    "RollbackTestAppAv2.apk",
-                    "RollbackTestAppBv2.apk");
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            Uninstall.packages(TestApp.A, TestApp.B);
+            Install.multi(TestApp.A1, TestApp.B1).commit();
+            Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
+
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
 
             // The app should now be available for rollback.
-            RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoForAandB(rollbackA);
+            RollbackInfo availableA = getUniqueRollbackInfoForPackage(
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(availableA).isNotNull();
+            assertThat(availableA).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1),
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
-            RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_B);
-            assertRollbackInfoForAandB(rollbackB);
+            RollbackInfo availableB = getUniqueRollbackInfoForPackage(
+                    rm.getAvailableRollbacks(), TestApp.B);
+            assertThat(availableB).isNotNull();
+            assertThat(availableB).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1),
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
+
+            // Assert they're both the same rollback
+            assertThat(availableA).hasRollbackId(availableB.getRollbackId());
 
             // Reload the persisted data.
             rm.reloadPersistedData();
 
             // The apps should still be available for rollback.
-            rollbackA = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoForAandB(rollbackA);
+            availableA = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(availableA).isNotNull();
+            assertThat(availableA).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1),
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
-            rollbackB = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_B);
-            assertRollbackInfoForAandB(rollbackB);
+            availableB = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.B);
+            assertThat(availableB).isNotNull();
+            assertThat(availableB).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1),
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
             // Rollback of B should rollback A as well
-            RollbackTestUtils.rollback(rollbackB.getRollbackId());
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            RollbackUtils.rollback(availableB.getRollbackId());
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
+
+            RollbackInfo committedA = getUniqueRollbackInfoForPackage(
+                    rm.getRecentlyCommittedRollbacks(), TestApp.A);
+            assertThat(committedA).isNotNull();
+            assertThat(committedA).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1),
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
+
+            RollbackInfo committedB = getUniqueRollbackInfoForPackage(
+                    rm.getRecentlyCommittedRollbacks(), TestApp.A);
+            assertThat(committedB).isNotNull();
+            assertThat(committedB).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1),
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
+
+            // Assert they're both the same rollback
+            assertThat(committedA).hasRollbackId(committedB.getRollbackId());
+            assertThat(committedA).hasRollbackId(availableA.getRollbackId());
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -274,42 +328,50 @@
     @Test
     public void testRecentlyCommittedRollbackPersistence() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
 
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
             // The app should now be available for rollback.
-            RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
+            RollbackInfo available = getUniqueRollbackInfoForPackage(
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(available).isNotNull();
 
             // Roll back the app.
-            VersionedPackage cause = new VersionedPackage(
-                    "com.android.tests.rollback.testapp.Foo", 42);
-            RollbackTestUtils.rollback(rollback.getRollbackId(), cause);
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            TestApp cause = new TestApp("Foo", "com.android.tests.rollback.testapp.Foo",
+                    /*versionCode*/ 42, /*isApex*/ false);
+            RollbackUtils.rollback(available.getRollbackId(), cause);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
 
             // Verify the recent rollback has been recorded.
-            rollback = getUniqueRollbackInfoForPackage(
-                    rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback, cause);
+            RollbackInfo committed = getUniqueRollbackInfoForPackage(
+                    rm.getRecentlyCommittedRollbacks(), TestApp.A);
+            assertThat(committed).isNotNull();
+            assertThat(committed).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
+            assertThat(committed).causePackagesContainsExactly(cause);
 
             // Reload the persisted data.
             rm.reloadPersistedData();
 
             // Verify the recent rollback is still recorded.
-            rollback = getUniqueRollbackInfoForPackage(
-                    rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback, cause);
+            committed = getUniqueRollbackInfoForPackage(
+                    rm.getRecentlyCommittedRollbacks(), TestApp.A);
+            assertThat(committed).isNotNull();
+            assertThat(committed).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
+            assertThat(committed).causePackagesContainsExactly(cause);
+            assertThat(committed).hasRollbackId(available.getRollbackId());
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -320,10 +382,10 @@
     public void testRollbackExpiresAfterLifetime() throws Exception {
         long expirationTime = TimeUnit.SECONDS.toMillis(30);
         long defaultExpirationTime = TimeUnit.HOURS.toMillis(48);
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
+        RollbackManager rm = RollbackUtils.getRollbackManager();
 
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -336,39 +398,45 @@
             // Pull the new expiration time from DeviceConfig
             rm.reloadPersistedData();
 
-            // Uninstall TEST_APP_A
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            // Uninstall TestApp.A
+            Uninstall.packages(TestApp.A);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
 
             // Install v1 of the app (without rollbacks enabled).
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Install.single(TestApp.A1).commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
 
             // Upgrade from v1 to v2, with rollbacks enabled.
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
             // Check that the rollback data has not expired
             Thread.sleep(1000);
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollback).isNotNull();
+            assertThat(rollback).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             // Give it a little more time, but still not the long enough to expire
             Thread.sleep(expirationTime / 2);
             rollback = getUniqueRollbackInfoForPackage(
-                rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollback).isNotNull();
+            assertThat(rollback).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             // Check that the data has expired after the expiration time (with a buffer of 1 second)
             Thread.sleep(expirationTime / 2);
-            assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+            rollback = getUniqueRollbackInfoForPackage(
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollback).isNull();
 
         } finally {
             DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                     RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                     Long.toString(defaultExpirationTime), false /* makeDefault*/);
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -380,10 +448,10 @@
     public void testTimeChangeDoesNotAffectLifetime() throws Exception {
         long expirationTime = TimeUnit.SECONDS.toMillis(30);
         long defaultExpirationTime = TimeUnit.HOURS.toMillis(48);
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
+        RollbackManager rm = RollbackUtils.getRollbackManager();
 
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -398,24 +466,25 @@
             rm.reloadPersistedData();
 
             // Install app A with rollback enabled
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
             Thread.sleep(expirationTime / 2);
 
             // Install app B with rollback enabled
-            RollbackTestUtils.uninstall(TEST_APP_B);
-            RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            Uninstall.packages(TestApp.B);
+            Install.single(TestApp.B1).commit();
+            Install.single(TestApp.B2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
+
             // 1 second buffer
             Thread.sleep(1000);
 
             try {
                 // Change the time
-                RollbackTestUtils.forwardTimeBy(expirationTime);
+                RollbackUtils.forwardTimeBy(expirationTime);
 
                 // 1 second buffer to allow Rollback Manager to handle time change before loading
                 // persisted data
@@ -427,24 +496,31 @@
                 // Wait until rollback for app A has expired
                 // This will trigger an expiration run that should expire app A but not B
                 Thread.sleep(expirationTime / 2);
-                assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+                RollbackInfo rollback =
+                        getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A);
+                assertThat(rollback).isNull();
 
                 // Rollback for app B should not be expired
-                RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                        rm.getAvailableRollbacks(), TEST_APP_B);
-                assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollback);
+                rollback = getUniqueRollbackInfoForPackage(
+                        rm.getAvailableRollbacks(), TestApp.B);
+                assertThat(rollback).isNotNull();
+                assertThat(rollback).packagesContainsExactly(
+                        Rollback.from(TestApp.B2).to(TestApp.B1));
 
                 // Wait until rollback for app B has expired
                 Thread.sleep(expirationTime / 2);
-                assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_B));
+                rollback = getUniqueRollbackInfoForPackage(
+                        rm.getAvailableRollbacks(), TestApp.B);
+                // Rollback should be expired by now
+                assertThat(rollback).isNull();
             } finally {
-                RollbackTestUtils.forwardTimeBy(-expirationTime);
+                RollbackUtils.forwardTimeBy(-expirationTime);
             }
         } finally {
             DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                     RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                     Long.toString(defaultExpirationTime), false /* makeDefault*/);
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -455,30 +531,32 @@
     @Test
     public void testRollbackExpiration() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
 
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            RollbackManager rm = RollbackUtils.getRollbackManager();
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
             // The app should now be available for rollback.
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollback).isNotNull();
+            assertThat(rollback).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             // Expire the rollback.
-            rm.expireRollbackForPackage(TEST_APP_A);
+            rm.expireRollbackForPackage(TestApp.A);
 
             // The rollback should no longer be available.
-            assertNull(getUniqueRollbackInfoForPackage(
-                        rm.getAvailableRollbacks(), TEST_APP_A));
+            assertThat(getUniqueRollbackInfoForPackage(
+                        rm.getAvailableRollbacks(), TestApp.A)).isNull();
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -488,24 +566,24 @@
     @Test
     public void testUserDataRollback() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            processUserData(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            processUserData(TEST_APP_A);
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            processUserData(TestApp.A);
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            processUserData(TestApp.A);
 
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            RollbackTestUtils.rollback(rollback.getRollbackId());
-            processUserData(TEST_APP_A);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            RollbackUtils.rollback(rollback.getRollbackId());
+            processUserData(TestApp.A);
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -515,30 +593,26 @@
     @Test
     public void testRollbackWithSplits() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.installSplit(false,
-                    "RollbackTestAppASplitV1.apk",
-                    "RollbackTestAppASplitV1_anydpi.apk");
-            processUserData(TEST_APP_A);
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.ASplit1).commit();
+            processUserData(TestApp.A);
 
-            RollbackTestUtils.installSplit(true,
-                    "RollbackTestAppASplitV2.apk",
-                    "RollbackTestAppASplitV2_anydpi.apk");
-            processUserData(TEST_APP_A);
+            Install.single(TestApp.ASplit2).setEnableRollback().commit();
+            processUserData(TestApp.A);
 
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertNotNull(rollback);
-            RollbackTestUtils.rollback(rollback.getRollbackId());
-            processUserData(TEST_APP_A);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollback).isNotNull();
+            RollbackUtils.rollback(rollback.getRollbackId());
+            processUserData(TestApp.A);
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -559,7 +633,7 @@
 
         // Confirm that we really haven't received the broadcast.
         // TODO: How long to wait for the expected timeout?
-        assertNull(broadcastReceiver.poll(5, TimeUnit.SECONDS));
+        assertThat(broadcastReceiver.poll(5, TimeUnit.SECONDS)).isNull();
 
         // TODO: Do we need to do this? Do we need to ensure this is always
         // called, even when the test fails?
@@ -573,48 +647,52 @@
     @Test
     public void testMultipleRollbackAvailable() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
             // Prep installation of the test apps.
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
-            RollbackTestUtils.uninstall(TEST_APP_B);
-            RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            Uninstall.packages(TestApp.B);
+            Install.single(TestApp.B1).commit();
+            Install.single(TestApp.B2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
 
             // Both test apps should now be available for rollback, and the
             // RollbackInfo returned for the rollbacks should be correct.
             RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollbackA).isNotNull();
+            assertThat(rollbackA).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_B);
-            assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);
+                    rm.getAvailableRollbacks(), TestApp.B);
+            assertThat(rollbackB).isNotNull();
+            assertThat(rollbackB).packagesContainsExactly(
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
             // Executing rollback should roll back the correct package.
-            RollbackTestUtils.rollback(rollbackA.getRollbackId());
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            RollbackUtils.rollback(rollbackA.getRollbackId());
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
-            RollbackTestUtils.rollback(rollbackB.getRollbackId());
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            RollbackUtils.rollback(rollbackB.getRollbackId());
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -626,7 +704,7 @@
     public void testManageRollbacksPermission() throws Exception {
         // We shouldn't be allowed to call any of the RollbackManager APIs
         // without the MANAGE_ROLLBACKS permission.
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
+        RollbackManager rm = RollbackUtils.getRollbackManager();
 
         try {
             rm.getAvailableRollbacks();
@@ -659,7 +737,7 @@
         }
 
         try {
-            rm.expireRollbackForPackage(TEST_APP_A);
+            rm.expireRollbackForPackage(TestApp.A);
             fail("expected SecurityException");
         } catch (SecurityException e) {
             // Expected.
@@ -673,26 +751,27 @@
     @Test
     public void testEnableRollbackPermission() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES);
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", /* enableRollback */ false);
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
 
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", /* enableRollback */ true);
+            Install.single(TestApp.A2).setEnableRollback().commit();
 
             // We expect v2 of the app was installed, but rollback has not
             // been enabled.
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
-            assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+            RollbackManager rm = RollbackUtils.getRollbackManager();
+            assertThat(
+                getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -703,25 +782,26 @@
     @Test
     public void testNonModuleEnableRollback() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.MANAGE_ROLLBACKS);
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", /* enableRollback */ false);
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
 
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", /* enableRollback */ true);
+            Install.single(TestApp.A2).setEnableRollback().commit();
 
             // We expect v2 of the app was installed, but rollback has not
             // been enabled because the test app is not a module.
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
-            assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+            RollbackManager rm = RollbackUtils.getRollbackManager();
+            assertThat(
+                getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -731,54 +811,54 @@
     @Test
     public void testMultiPackage() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
             // Prep installation of the test apps.
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.uninstall(TEST_APP_B);
-            RollbackTestUtils.installMultiPackage(false,
-                    "RollbackTestAppAv1.apk",
-                    "RollbackTestAppBv1.apk");
-            processUserData(TEST_APP_A);
-            processUserData(TEST_APP_B);
-            RollbackTestUtils.installMultiPackage(true,
-                    "RollbackTestAppAv2.apk",
-                    "RollbackTestAppBv2.apk");
-            processUserData(TEST_APP_A);
-            processUserData(TEST_APP_B);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            Uninstall.packages(TestApp.A, TestApp.B);
+            Install.multi(TestApp.A1, TestApp.B1).commit();
+            processUserData(TestApp.A);
+            processUserData(TestApp.B);
+            Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
+            processUserData(TestApp.A);
+            processUserData(TestApp.B);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
 
-            // TEST_APP_A should now be available for rollback.
+            // TestApp.A should now be available for rollback.
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoForAandB(rollback);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollback).isNotNull();
+            assertThat(rollback).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1),
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
             // Rollback the app. It should cause both test apps to be rolled
             // back.
-            RollbackTestUtils.rollback(rollback.getRollbackId());
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            RollbackUtils.rollback(rollback.getRollbackId());
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
 
             // We should see recent rollbacks listed for both A and B.
             Thread.sleep(1000);
             RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
-                    rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
+                    rm.getRecentlyCommittedRollbacks(), TestApp.A);
 
             RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
-                    rm.getRecentlyCommittedRollbacks(), TEST_APP_B);
-            assertRollbackInfoForAandB(rollbackB);
+                    rm.getRecentlyCommittedRollbacks(), TestApp.B);
+            assertThat(rollback).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1),
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
-            assertEquals(rollbackA.getRollbackId(), rollbackB.getRollbackId());
+            assertThat(rollbackA).hasRollbackId(rollbackB.getRollbackId());
 
-            processUserData(TEST_APP_A);
-            processUserData(TEST_APP_B);
+            processUserData(TestApp.A);
+            processUserData(TestApp.B);
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -790,31 +870,27 @@
     @Test
     public void testMultiPackageEnableFail() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.uninstall(TEST_APP_B);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-
+            Uninstall.packages(TestApp.A, TestApp.B);
+            Install.single(TestApp.A1).commit();
             // We should fail to enable rollback here because TestApp B is not
             // already installed.
-            RollbackTestUtils.installMultiPackage(true,
-                    "RollbackTestAppAv2.apk",
-                    "RollbackTestAppBv2.apk");
+            Install.multi(TestApp.A2, TestApp.B2).setEnableRollback().commit();
 
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
 
-            assertNull(getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A));
-            assertNull(getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_B));
+            assertThat(getUniqueRollbackInfoForPackage(
+                    rm.getAvailableRollbacks(), TestApp.A)).isNull();
+            assertThat(getUniqueRollbackInfoForPackage(
+                    rm.getAvailableRollbacks(), TestApp.B)).isNull();
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -825,30 +901,33 @@
      */
     public void testSameVersionUpdate() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            RollbackTestUtils.install("RollbackTestAppACrashingV2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            Install.single(TestApp.ACrashing2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 2, rollback);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollback).isNotNull();
+            assertThat(rollback).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A2));
 
-            RollbackTestUtils.rollback(rollback.getRollbackId());
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            RollbackUtils.rollback(rollback.getRollbackId());
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
             rollback = getUniqueRollbackInfoForPackage(
-                    rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 2, rollback);
+                    rm.getRecentlyCommittedRollbacks(), TestApp.A);
+            assertThat(rollback).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A2));
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
@@ -860,54 +939,55 @@
         BroadcastReceiver crashCountReceiver = null;
         Context context = InstrumentationRegistry.getContext();
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.MANAGE_ROLLBACKS,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS,
                     Manifest.permission.KILL_BACKGROUND_PROCESSES,
                     Manifest.permission.RESTART_PACKAGES);
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
             // Prep installation of the test apps.
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppACrashingV2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A, TestApp.B);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.ACrashing2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
-            RollbackTestUtils.uninstall(TEST_APP_B);
-            RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            Install.single(TestApp.B1).commit();
+            Install.single(TestApp.B2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
 
             // Both test apps should now be available for rollback, and the
             // targetPackage returned for rollback should be correct.
             RollbackInfo rollbackA = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollbackA);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollbackA).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             RollbackInfo rollbackB = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_B);
-            assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB);
+                    rm.getAvailableRollbacks(), TestApp.B);
+            assertThat(rollbackB).packagesContainsExactly(
+                    Rollback.from(TestApp.B2).to(TestApp.B1));
 
             // Register rollback committed receiver
             RollbackBroadcastReceiver rollbackReceiver = new RollbackBroadcastReceiver();
 
-            // Crash TEST_APP_A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
-            crashCountReceiver = RollbackTestUtils.sendCrashBroadcast(context, TEST_APP_A, 5);
+            // Crash TestApp.A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
+            crashCountReceiver = RollbackUtils.sendCrashBroadcast(context, TestApp.A, 5);
 
             // Verify we received a broadcast for the rollback.
             rollbackReceiver.take();
 
-            // TEST_APP_A is automatically rolled back by the RollbackPackageHealthObserver
-            assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            // TestApp.A is automatically rolled back by the RollbackPackageHealthObserver
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
             // Instrumented app is still the package installer
-            String installer = context.getPackageManager().getInstallerPackageName(TEST_APP_A);
-            assertEquals(INSTRUMENTED_APP, installer);
-            // TEST_APP_B is untouched
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+            String installer = context.getPackageManager().getInstallerPackageName(TestApp.A);
+            assertThat(installer).isEqualTo(INSTRUMENTED_APP);
+            // TestApp.B is untouched
+            assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
             if (crashCountReceiver != null) {
                 context.unregisterReceiver(crashCountReceiver);
             }
@@ -920,31 +1000,32 @@
     @Test
     public void testRollForwardRace() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS,
                     Manifest.permission.MANAGE_ROLLBACKS);
 
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
+            Install.single(TestApp.A2).setEnableRollback().commit();
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
 
             RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                    rm.getAvailableRollbacks(), TEST_APP_A);
-            assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+                    rm.getAvailableRollbacks(), TestApp.A);
+            assertThat(rollback).packagesContainsExactly(
+                    Rollback.from(TestApp.A2).to(TestApp.A1));
 
             // Install a new version of package A, then immediately rollback
             // the previous version. We expect the rollback to fail, because
             // it is no longer available.
             // There are a couple different ways this could fail depending on
             // thread interleaving, so don't ignore flaky failures.
-            RollbackTestUtils.install("RollbackTestAppAv3.apk", false);
+            Install.single(TestApp.A3).commit();
             try {
-                RollbackTestUtils.rollback(rollback.getRollbackId());
+                RollbackUtils.rollback(rollback.getRollbackId());
                 // Note: Don't ignore flaky failures here.
                 fail("Expected rollback to fail, but it did not.");
             } catch (AssertionError e) {
@@ -953,16 +1034,16 @@
             }
 
             // Note: Don't ignore flaky failures here.
-            assertEquals(3, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(3);
         } finally {
-            RollbackTestUtils.dropShellPermissionIdentity();
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 
     @Test
     public void testEnableRollbackTimeoutFailsRollback() throws Exception {
         try {
-            RollbackTestUtils.adoptShellPermissionIdentity(
+            InstallUtils.adoptShellPermissionIdentity(
                     Manifest.permission.INSTALL_PACKAGES,
                     Manifest.permission.DELETE_PACKAGES,
                     Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -972,36 +1053,27 @@
             //setting the timeout to a very short amount that will definitely be triggered
             DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
                     PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
-                    Long.toString(1), false /* makeDefault*/);
-            RollbackManager rm = RollbackTestUtils.getRollbackManager();
+                    Long.toString(0), false /* makeDefault*/);
+            RollbackManager rm = RollbackUtils.getRollbackManager();
 
-            RollbackTestUtils.uninstall(TEST_APP_A);
-            RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
-            RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+            Uninstall.packages(TestApp.A);
+            Install.single(TestApp.A1).commit();
 
-            assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+            // Block the RollbackManager to make extra sure it will not be
+            // able to enable the rollback in time.
+            rm.blockRollbackManager(TimeUnit.SECONDS.toMillis(1));
+            Install.single(TestApp.A2).setEnableRollback().commit();
 
-            assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+
+            assertThat(
+                getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A)).isNull();
         } finally {
             //setting the timeout back to default
             DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
                     PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
                     null, false /* makeDefault*/);
-            RollbackTestUtils.dropShellPermissionIdentity();
-        }
-    }
-
-    // Helper function to test that the given rollback info is a rollback for
-    // the atomic set {A2, B2} -> {A1, B1}.
-    private void assertRollbackInfoForAandB(RollbackInfo rollback) {
-        assertNotNull(rollback);
-        assertEquals(2, rollback.getPackages().size());
-        if (TEST_APP_A.equals(rollback.getPackages().get(0).getPackageName())) {
-            assertPackageRollbackInfoEquals(TEST_APP_A, 2, 1, rollback.getPackages().get(0));
-            assertPackageRollbackInfoEquals(TEST_APP_B, 2, 1, rollback.getPackages().get(1));
-        } else {
-            assertPackageRollbackInfoEquals(TEST_APP_B, 2, 1, rollback.getPackages().get(0));
-            assertPackageRollbackInfoEquals(TEST_APP_A, 2, 1, rollback.getPackages().get(1));
+            InstallUtils.dropShellPermissionIdentity();
         }
     }
 }
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
deleted file mode 100644
index a9e20cd..0000000
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
+++ /dev/null
@@ -1,547 +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.tests.rollback;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import android.app.ActivityManager;
-import android.app.AlarmManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.content.rollback.PackageRollbackInfo;
-import android.content.rollback.RollbackInfo;
-import android.content.rollback.RollbackManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.SynchronousQueue;
-
-/**
- * Utilities to facilitate testing rollbacks.
- */
-class RollbackTestUtils {
-
-    private static final String TAG = "RollbackTest";
-
-    static RollbackManager getRollbackManager() {
-        Context context = InstrumentationRegistry.getContext();
-        RollbackManager rm = (RollbackManager) context.getSystemService(Context.ROLLBACK_SERVICE);
-        if (rm == null) {
-            throw new AssertionError("Failed to get RollbackManager");
-        }
-        return rm;
-    }
-
-    private static void setTime(long millis) {
-        Context context = InstrumentationRegistry.getContext();
-        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-        am.setTime(millis);
-    }
-
-    static void forwardTimeBy(long offsetMillis) {
-        setTime(System.currentTimeMillis() + offsetMillis);
-        Log.i(TAG, "Forwarded time on device by " + offsetMillis + " millis");
-    }
-
-    /**
-     * Returns the version of the given package installed on device.
-     * Returns -1 if the package is not currently installed.
-     */
-    static long getInstalledVersion(String packageName) {
-        PackageInfo pi = getPackageInfo(packageName);
-        if (pi == null) {
-            return -1;
-        } else {
-            return pi.getLongVersionCode();
-        }
-    }
-
-    private static boolean isSystemAppWithoutUpdate(String packageName) {
-        PackageInfo pi = getPackageInfo(packageName);
-        if (pi == null) {
-            return false;
-        } else {
-            return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)
-                    && ((pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0);
-        }
-    }
-
-    private static PackageInfo getPackageInfo(String packageName) {
-        Context context = InstrumentationRegistry.getContext();
-        PackageManager pm = context.getPackageManager();
-        try {
-            return pm.getPackageInfo(packageName, PackageManager.MATCH_APEX);
-        } catch (PackageManager.NameNotFoundException e) {
-            return null;
-        }
-    }
-
-    private static void assertStatusSuccess(Intent result) {
-        int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
-                PackageInstaller.STATUS_FAILURE);
-        if (status == -1) {
-            throw new AssertionError("PENDING USER ACTION");
-        } else if (status > 0) {
-            String message = result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
-            throw new AssertionError(message == null ? "UNKNOWN FAILURE" : message);
-        }
-    }
-
-    /**
-     * Uninstalls the given package.
-     * Does nothing if the package is not installed.
-     * @throws AssertionError if package can't be uninstalled.
-     */
-    static void uninstall(String packageName) throws InterruptedException, IOException {
-        // No need to uninstall if the package isn't installed or is installed on /system.
-        if (getInstalledVersion(packageName) == -1 || isSystemAppWithoutUpdate(packageName)) {
-            return;
-        }
-
-        Context context = InstrumentationRegistry.getContext();
-        PackageManager packageManager = context.getPackageManager();
-        PackageInstaller packageInstaller = packageManager.getPackageInstaller();
-        packageInstaller.uninstall(packageName, LocalIntentSender.getIntentSender());
-        assertStatusSuccess(LocalIntentSender.getIntentSenderResult());
-    }
-
-    /**
-     * Commit the given rollback.
-     * @throws AssertionError if the rollback fails.
-     */
-    static void rollback(int rollbackId, VersionedPackage... causePackages)
-            throws InterruptedException {
-        RollbackManager rm = getRollbackManager();
-        rm.commitRollback(rollbackId, Arrays.asList(causePackages),
-                LocalIntentSender.getIntentSender());
-        Intent result = LocalIntentSender.getIntentSenderResult();
-        int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
-                RollbackManager.STATUS_FAILURE);
-        if (status != RollbackManager.STATUS_SUCCESS) {
-            String message = result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE);
-            throw new AssertionError(message);
-        }
-    }
-
-    /**
-     * Installs the apk with the given name.
-     *
-     * @param resourceName name of class loader resource for the apk to
-     *        install.
-     * @param enableRollback if rollback should be enabled.
-     * @throws AssertionError if the installation fails.
-     */
-    static void install(String resourceName, boolean enableRollback)
-            throws InterruptedException, IOException {
-        installSplit(enableRollback, resourceName);
-    }
-
-    /**
-     * Installs the apk with the given name and its splits.
-     *
-     * @param enableRollback if rollback should be enabled.
-     * @param resourceNames names of class loader resources for the apk and
-     *        its splits to install.
-     * @throws AssertionError if the installation fails.
-     */
-    static void installSplit(boolean enableRollback, String... resourceNames)
-            throws InterruptedException, IOException {
-        Context context = InstrumentationRegistry.getContext();
-        PackageInstaller.Session session = null;
-        PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
-        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
-                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-        params.setEnableRollback(enableRollback);
-        int sessionId = packageInstaller.createSession(params);
-        session = packageInstaller.openSession(sessionId);
-
-        ClassLoader loader = RollbackTest.class.getClassLoader();
-        for (String resourceName : resourceNames) {
-            try (OutputStream packageInSession = session.openWrite(resourceName, 0, -1);
-                    InputStream is = loader.getResourceAsStream(resourceName);) {
-                byte[] buffer = new byte[4096];
-                int n;
-                while ((n = is.read(buffer)) >= 0) {
-                    packageInSession.write(buffer, 0, n);
-                }
-            }
-        }
-
-        // Commit the session (this will start the installation workflow).
-        session.commit(LocalIntentSender.getIntentSender());
-        assertStatusSuccess(LocalIntentSender.getIntentSenderResult());
-    }
-
-    /** Launches {@code packageName} with {@link Intent#ACTION_MAIN}. */
-    private static void launchPackage(String packageName)
-            throws InterruptedException, IOException {
-        Context context = InstrumentationRegistry.getContext();
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setPackage(packageName);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        context.startActivity(intent);
-    }
-
-    /**
-     * Installs the APKs or APEXs with the given resource names as an atomic
-     * set. A resource is assumed to be an APEX if it has the .apex extension.
-     * <p>
-     * In case of staged installs, this function will return succesfully after
-     * the staged install has been committed and is ready for the device to
-     * reboot.
-     *
-     * @param staged if the rollback should be staged.
-     * @param enableRollback if rollback should be enabled.
-     * @param resourceNames names of the class loader resource for the apks to
-     *        install.
-     * @throws AssertionError if the installation fails.
-     */
-    private static void install(boolean staged, boolean enableRollback,
-            String... resourceNames) throws InterruptedException, IOException {
-        Context context = InstrumentationRegistry.getContext();
-        PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
-
-        PackageInstaller.SessionParams multiPackageParams = new PackageInstaller.SessionParams(
-                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-        multiPackageParams.setMultiPackage();
-        if (staged) {
-            multiPackageParams.setStaged();
-        }
-        // TODO: Do we set this on the parent params, the child params, or
-        // both?
-        multiPackageParams.setEnableRollback(enableRollback);
-        int multiPackageId = packageInstaller.createSession(multiPackageParams);
-        PackageInstaller.Session multiPackage = packageInstaller.openSession(multiPackageId);
-
-        for (String resourceName : resourceNames) {
-            PackageInstaller.Session session = null;
-            PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
-                    PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-            if (staged) {
-                params.setStaged();
-            }
-            if (resourceName.endsWith(".apex")) {
-                params.setInstallAsApex();
-            }
-            params.setEnableRollback(enableRollback);
-            int sessionId = packageInstaller.createSession(params);
-            session = packageInstaller.openSession(sessionId);
-
-            ClassLoader loader = RollbackTest.class.getClassLoader();
-            try (OutputStream packageInSession = session.openWrite(resourceName, 0, -1);
-                 InputStream is = loader.getResourceAsStream(resourceName);) {
-                byte[] buffer = new byte[4096];
-                int n;
-                while ((n = is.read(buffer)) >= 0) {
-                    packageInSession.write(buffer, 0, n);
-                }
-            }
-            multiPackage.addChildSessionId(sessionId);
-        }
-
-        // Commit the session (this will start the installation workflow).
-        multiPackage.commit(LocalIntentSender.getIntentSender());
-        assertStatusSuccess(LocalIntentSender.getIntentSenderResult());
-
-        if (staged) {
-            waitForSessionReady(multiPackageId);
-        }
-    }
-
-    /**
-     * Installs the apks with the given resource names as an atomic set.
-     *
-     * @param enableRollback if rollback should be enabled.
-     * @param resourceNames names of the class loader resource for the apks to
-     *        install.
-     * @throws AssertionError if the installation fails.
-     */
-    static void installMultiPackage(boolean enableRollback, String... resourceNames)
-            throws InterruptedException, IOException {
-        install(false, enableRollback, resourceNames);
-    }
-
-    /**
-     * Installs the APKs or APEXs with the given resource names as a staged
-     * atomic set. A resource is assumed to be an APEX if it has the .apex
-     * extension.
-     *
-     * @param enableRollback if rollback should be enabled.
-     * @param resourceNames names of the class loader resource for the apks to
-     *        install.
-     * @throws AssertionError if the installation fails.
-     */
-    static void installStaged(boolean enableRollback, String... resourceNames)
-            throws InterruptedException, IOException {
-        install(true, enableRollback, resourceNames);
-    }
-
-    static void adoptShellPermissionIdentity(String... permissions) {
-        InstrumentationRegistry
-            .getInstrumentation()
-            .getUiAutomation()
-            .adoptShellPermissionIdentity(permissions);
-    }
-
-    static void dropShellPermissionIdentity() {
-        InstrumentationRegistry
-            .getInstrumentation()
-            .getUiAutomation()
-            .dropShellPermissionIdentity();
-    }
-
-    /**
-     * Returns the RollbackInfo with a given package in the list of rollbacks.
-     * Throws an assertion failure if there is more than one such rollback
-     * info. Returns null if there are no such rollback infos.
-     */
-    static RollbackInfo getUniqueRollbackInfoForPackage(List<RollbackInfo> rollbacks,
-            String packageName) {
-        RollbackInfo found = null;
-        for (RollbackInfo rollback : rollbacks) {
-            for (PackageRollbackInfo info : rollback.getPackages()) {
-                if (packageName.equals(info.getPackageName())) {
-                    assertNull(found);
-                    found = rollback;
-                    break;
-                }
-            }
-        }
-        return found;
-    }
-
-    /**
-     * Asserts that the given PackageRollbackInfo has the expected package
-     * name and versions.
-     */
-    static void assertPackageRollbackInfoEquals(String packageName,
-            long versionRolledBackFrom, long versionRolledBackTo,
-            PackageRollbackInfo info) {
-        assertEquals(packageName, info.getPackageName());
-        assertEquals(packageName, info.getVersionRolledBackFrom().getPackageName());
-        assertEquals(versionRolledBackFrom, info.getVersionRolledBackFrom().getLongVersionCode());
-        assertEquals(packageName, info.getVersionRolledBackTo().getPackageName());
-        assertEquals(versionRolledBackTo, info.getVersionRolledBackTo().getLongVersionCode());
-    }
-
-    /**
-     * Asserts that the given RollbackInfo has the given packages with expected
-     * package names and all are rolled to and from the same given versions.
-     */
-    static void assertRollbackInfoEquals(String[] packageNames,
-            long versionRolledBackFrom, long versionRolledBackTo,
-            RollbackInfo info, VersionedPackage... causePackages) {
-        assertNotNull(info);
-        assertEquals(packageNames.length, info.getPackages().size());
-        int foundPackages = 0;
-        for (String packageName : packageNames) {
-            for (PackageRollbackInfo pkgRollbackInfo : info.getPackages()) {
-                if (packageName.equals(pkgRollbackInfo.getPackageName())) {
-                    foundPackages++;
-                    assertPackageRollbackInfoEquals(packageName, versionRolledBackFrom,
-                            versionRolledBackTo, pkgRollbackInfo);
-                    break;
-                }
-            }
-        }
-        assertEquals(packageNames.length, foundPackages);
-        assertEquals(causePackages.length, info.getCausePackages().size());
-        for (int i = 0; i < causePackages.length; ++i) {
-            assertEquals(causePackages[i].getPackageName(),
-                    info.getCausePackages().get(i).getPackageName());
-            assertEquals(causePackages[i].getLongVersionCode(),
-                    info.getCausePackages().get(i).getLongVersionCode());
-        }
-    }
-
-    /**
-     * Asserts that the given RollbackInfo has a single package with expected
-     * package name and versions.
-     */
-    static void assertRollbackInfoEquals(String packageName,
-            long versionRolledBackFrom, long versionRolledBackTo,
-            RollbackInfo info, VersionedPackage... causePackages) {
-        String[] packageNames = {packageName};
-        assertRollbackInfoEquals(packageNames, versionRolledBackFrom, versionRolledBackTo, info,
-                causePackages);
-    }
-
-    /**
-     * Waits for the given session to be marked as ready.
-     * Throws an assertion if the session fails.
-     */
-    static void waitForSessionReady(int sessionId) {
-        BlockingQueue<PackageInstaller.SessionInfo> sessionStatus = new LinkedBlockingQueue<>();
-        BroadcastReceiver sessionUpdatedReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                PackageInstaller.SessionInfo info =
-                        intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
-                if (info != null && info.getSessionId() == sessionId) {
-                    if (info.isStagedSessionReady() || info.isStagedSessionFailed()) {
-                        try {
-                            sessionStatus.put(info);
-                        } catch (InterruptedException e) {
-                            Log.e(TAG, "Failed to put session info.", e);
-                        }
-                    }
-                }
-            }
-        };
-        IntentFilter sessionUpdatedFilter =
-                new IntentFilter(PackageInstaller.ACTION_SESSION_UPDATED);
-
-        Context context = InstrumentationRegistry.getContext();
-        context.registerReceiver(sessionUpdatedReceiver, sessionUpdatedFilter);
-
-        PackageInstaller installer = context.getPackageManager().getPackageInstaller();
-        PackageInstaller.SessionInfo info = installer.getSessionInfo(sessionId);
-
-        try {
-            if (info.isStagedSessionReady() || info.isStagedSessionFailed()) {
-                sessionStatus.put(info);
-            }
-
-            info = sessionStatus.take();
-            context.unregisterReceiver(sessionUpdatedReceiver);
-            if (info.isStagedSessionFailed()) {
-                throw new AssertionError(info.getStagedSessionErrorMessage());
-            }
-        } catch (InterruptedException e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    private static final String NO_RESPONSE = "NO RESPONSE";
-
-    /**
-     * Calls into the test app to process user data.
-     * Asserts if the user data could not be processed or was version
-     * incompatible with the previously processed user data.
-     */
-    static void processUserData(String packageName) {
-        Intent intent = new Intent();
-        intent.setComponent(new ComponentName(packageName,
-                    "com.android.tests.rollback.testapp.ProcessUserData"));
-        Context context = InstrumentationRegistry.getContext();
-
-        HandlerThread handlerThread = new HandlerThread("RollbackTestHandlerThread");
-        handlerThread.start();
-
-        // It can sometimes take a while after rollback before the app will
-        // receive this broadcast, so try a few times in a loop.
-        String result = NO_RESPONSE;
-        for (int i = 0; result.equals(NO_RESPONSE) && i < 5; ++i) {
-            BlockingQueue<String> resultQueue = new LinkedBlockingQueue<>();
-            context.sendOrderedBroadcast(intent, null, new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    if (getResultCode() == 1) {
-                        resultQueue.add("OK");
-                    } else {
-                        // If the test app doesn't receive the broadcast or
-                        // fails to set the result data, then getResultData
-                        // here returns the initial NO_RESPONSE data passed to
-                        // the sendOrderedBroadcast call.
-                        resultQueue.add(getResultData());
-                    }
-                }
-            }, new Handler(handlerThread.getLooper()), 0, NO_RESPONSE, null);
-
-            try {
-                result = resultQueue.take();
-            } catch (InterruptedException e) {
-                throw new AssertionError(e);
-            }
-        }
-
-        handlerThread.quit();
-        if (!"OK".equals(result)) {
-            fail(result);
-        }
-    }
-
-    /**
-     * Return the rollback info for a recently committed rollback, by matching the rollback id, or
-     * return null if no matching rollback is found.
-     */
-    static RollbackInfo getRecentlyCommittedRollbackInfoById(int getRollbackId) {
-        for (RollbackInfo info : getRollbackManager().getRecentlyCommittedRollbacks()) {
-            if (info.getRollbackId() == getRollbackId) {
-                return info;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Send broadcast to crash {@code packageName} {@code count} times. If {@code count} is at least
-     * {@link PackageWatchdog#TRIGGER_FAILURE_COUNT}, watchdog crash detection will be triggered.
-     */
-    static BroadcastReceiver sendCrashBroadcast(Context context, String packageName, int count)
-            throws InterruptedException, IOException {
-        BlockingQueue<Integer> crashQueue = new SynchronousQueue<>();
-        IntentFilter crashCountFilter = new IntentFilter();
-        crashCountFilter.addAction("com.android.tests.rollback.CRASH");
-        crashCountFilter.addCategory(Intent.CATEGORY_DEFAULT);
-
-        BroadcastReceiver crashCountReceiver = new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    try {
-                        // Sleep long enough for packagewatchdog to be notified of crash
-                        Thread.sleep(1000);
-                        // Kill app and close AppErrorDialog
-                        ActivityManager am = context.getSystemService(ActivityManager.class);
-                        am.killBackgroundProcesses(packageName);
-                        // Allow another package launch
-                        crashQueue.put(intent.getIntExtra("count", 0));
-                    } catch (InterruptedException e) {
-                        fail("Failed to communicate with test app");
-                    }
-                }
-            };
-        context.registerReceiver(crashCountReceiver, crashCountFilter);
-
-        do {
-            launchPackage(packageName);
-        } while(crashQueue.take() < count);
-        return crashCountReceiver;
-    }
-}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 1a29c4c..db81831 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -16,26 +16,35 @@
 
 package com.android.tests.rollback;
 
-import static com.android.tests.rollback.RollbackTestUtils.assertRollbackInfoEquals;
-import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage;
+import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
+import static com.android.cts.rollback.lib.RollbackUtils.getUniqueRollbackInfoForPackage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
 
 import android.Manifest;
+import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.VersionedPackage;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
 import android.content.rollback.RollbackInfo;
 import android.content.rollback.RollbackManager;
+import android.text.TextUtils;
 
 import androidx.test.InstrumentationRegistry;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-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 com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
+import com.android.cts.install.lib.LocalIntentSender;
+import com.android.cts.install.lib.TestApp;
+import com.android.cts.install.lib.Uninstall;
+import com.android.cts.rollback.lib.Rollback;
+import com.android.cts.rollback.lib.RollbackUtils;
+import com.android.internal.R;
 
 import org.junit.After;
 import org.junit.Before;
@@ -54,19 +63,17 @@
 @RunWith(JUnit4.class)
 public class StagedRollbackTest {
 
-    private static final String TAG = "RollbackTest";
-    private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A";
-    private static final String TEST_APP_A_V1 = "RollbackTestAppAv1.apk";
-    private static final String TEST_APP_A_CRASHING_V2 = "RollbackTestAppACrashingV2.apk";
     private static final String NETWORK_STACK_CONNECTOR_CLASS =
             "android.net.INetworkStackConnector";
 
+    private static final String MODULE_META_DATA_PACKAGE = getModuleMetadataPackageName();
+
     /**
      * Adopts common shell permissions needed for rollback tests.
      */
     @Before
     public void adoptShellPermissions() {
-        RollbackTestUtils.adoptShellPermissionIdentity(
+        InstallUtils.adoptShellPermissionIdentity(
                 Manifest.permission.INSTALL_PACKAGES,
                 Manifest.permission.DELETE_PACKAGES,
                 Manifest.permission.TEST_MANAGE_ROLLBACKS,
@@ -78,7 +85,7 @@
      */
     @After
     public void dropShellPermissions() {
-        RollbackTestUtils.dropShellPermissionIdentity();
+        InstallUtils.dropShellPermissionIdentity();
     }
 
     /**
@@ -87,14 +94,14 @@
      */
     @Test
     public void testBadApkOnlyEnableRollback() throws Exception {
-        RollbackTestUtils.uninstall(TEST_APP_A);
-        assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+        Uninstall.packages(TestApp.A);
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
 
-        RollbackTestUtils.install(TEST_APP_A_V1, false);
-        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-        RollbackTestUtils.processUserData(TEST_APP_A);
+        Install.single(TestApp.A1).commit();
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+        InstallUtils.processUserData(TestApp.A);
 
-        RollbackTestUtils.installStaged(true, TEST_APP_A_CRASHING_V2);
+        Install.single(TestApp.ACrashing2).setEnableRollback().setStaged().commit();
 
         // At this point, the host test driver will reboot the device and run
         // testBadApkOnlyConfirmEnableRollback().
@@ -106,14 +113,16 @@
      */
     @Test
     public void testBadApkOnlyConfirmEnableRollback() throws Exception {
-        assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-        RollbackTestUtils.processUserData(TEST_APP_A);
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+        InstallUtils.processUserData(TestApp.A);
 
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
+        RollbackManager rm = RollbackUtils.getRollbackManager();
         RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                rm.getAvailableRollbacks(), TEST_APP_A);
-        assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
-        assertTrue(rollback.isStaged());
+                rm.getAvailableRollbacks(), TestApp.A);
+        assertThat(rollback).isNotNull();
+        assertThat(rollback).packagesContainsExactly(
+                Rollback.from(TestApp.A2).to(TestApp.A1));
+        assertThat(rollback.isStaged()).isTrue();
 
         // At this point, the host test driver will run
         // testBadApkOnlyTriggerRollback().
@@ -128,11 +137,10 @@
     public void testBadApkOnlyTriggerRollback() throws Exception {
         BroadcastReceiver crashCountReceiver = null;
         Context context = InstrumentationRegistry.getContext();
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
 
         try {
-            // Crash TEST_APP_A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
-            crashCountReceiver = RollbackTestUtils.sendCrashBroadcast(context, TEST_APP_A, 5);
+            // Crash TestApp.A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
+            crashCountReceiver = RollbackUtils.sendCrashBroadcast(context, TestApp.A, 5);
         } finally {
             if (crashCountReceiver != null) {
                 context.unregisterReceiver(crashCountReceiver);
@@ -153,48 +161,80 @@
      */
     @Test
     public void testBadApkOnlyConfirmRollback() throws Exception {
-        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
-        RollbackTestUtils.processUserData(TEST_APP_A);
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+        InstallUtils.processUserData(TestApp.A);
 
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
+        RollbackManager rm = RollbackUtils.getRollbackManager();
         RollbackInfo rollback = getUniqueRollbackInfoForPackage(
-                rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
-        assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback, new VersionedPackage(TEST_APP_A, 2));
-        assertTrue(rollback.isStaged());
-        assertNotEquals(-1, rollback.getCommittedSessionId());
+                rm.getRecentlyCommittedRollbacks(), TestApp.A);
+        assertThat(rollback).isNotNull();
+        assertThat(rollback).packagesContainsExactly(
+                Rollback.from(TestApp.A2).to(TestApp.A1));
+        assertThat(rollback).causePackagesContainsExactly(TestApp.ACrashing2);
+        assertThat(rollback).isStaged();
+        assertThat(rollback.getCommittedSessionId()).isNotEqualTo(-1);
     }
 
     @Test
     public void resetNetworkStack() throws Exception {
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
+        RollbackManager rm = RollbackUtils.getRollbackManager();
         String networkStack = getNetworkStackPackageName();
 
         rm.expireRollbackForPackage(networkStack);
-        RollbackTestUtils.uninstall(networkStack);
+        Uninstall.packages(networkStack);
 
-        assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
-                        networkStack));
+        assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+                        networkStack)).isNull();
+    }
+
+    @Test
+    public void installModuleMetadataPackage() throws Exception {
+        resetModuleMetadataPackage();
+        Context context = InstrumentationRegistry.getContext();
+        PackageInfo metadataPackageInfo = context.getPackageManager().getPackageInfo(
+                MODULE_META_DATA_PACKAGE, 0);
+        String metadataApkPath = metadataPackageInfo.applicationInfo.sourceDir;
+        assertThat(metadataApkPath).isNotNull();
+        assertThat(metadataApkPath).isNotEqualTo("");
+
+        runShellCommand("pm install "
+                + "-r --enable-rollback --staged --wait "
+                + metadataApkPath);
     }
 
     @Test
     public void assertNetworkStackRollbackAvailable() throws Exception {
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
-        assertNotNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
-                        getNetworkStackPackageName()));
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+        assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+                        getNetworkStackPackageName())).isNotNull();
     }
 
     @Test
     public void assertNetworkStackRollbackCommitted() throws Exception {
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
-        assertNotNull(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
-                        getNetworkStackPackageName()));
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+        assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
+                        getNetworkStackPackageName())).isNotNull();
     }
 
     @Test
     public void assertNoNetworkStackRollbackCommitted() throws Exception {
-        RollbackManager rm = RollbackTestUtils.getRollbackManager();
-        assertNull(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
-                        getNetworkStackPackageName()));
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+        assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
+                        getNetworkStackPackageName())).isNull();
+    }
+
+    @Test
+    public void assertModuleMetadataRollbackAvailable() throws Exception {
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+        assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+                        MODULE_META_DATA_PACKAGE)).isNotNull();
+    }
+
+    @Test
+    public void assertModuleMetadataRollbackCommitted() throws Exception {
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+        assertThat(getUniqueRollbackInfoForPackage(rm.getRecentlyCommittedRollbacks(),
+                        MODULE_META_DATA_PACKAGE)).isNotNull();
     }
 
     private String getNetworkStackPackageName() {
@@ -203,4 +243,65 @@
                 InstrumentationRegistry.getContext().getPackageManager(), 0);
         return comp.getPackageName();
     }
+
+    @Test
+    public void testPreviouslyAbandonedRollbacksEnableRollback() throws Exception {
+        Uninstall.packages(TestApp.A);
+        Install.single(TestApp.A1).commit();
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+
+        int sessionId = Install.single(TestApp.A2).setStaged().setEnableRollback().commit();
+        PackageInstaller pi = InstrumentationRegistry.getContext().getPackageManager()
+                .getPackageInstaller();
+        pi.abandonSession(sessionId);
+
+        // Remove the first intent sender result, so that the next staged install session does not
+        // erroneously think that it has itself been abandoned.
+        // TODO(b/136260017): Restructure LocalIntentSender to negate the need for this step.
+        LocalIntentSender.getIntentSenderResult();
+        Install.single(TestApp.A2).setStaged().setEnableRollback().commit();
+    }
+
+    @Test
+    public void testPreviouslyAbandonedRollbacksCommitRollback() throws Exception {
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+        InstallUtils.processUserData(TestApp.A);
+
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+        RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+                rm.getAvailableRollbacks(), TestApp.A);
+        RollbackUtils.rollback(rollback.getRollbackId());
+    }
+
+    @Test
+    public void testPreviouslyAbandonedRollbacksCheckUserdataRollback() throws Exception {
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+        InstallUtils.processUserData(TestApp.A);
+        Uninstall.packages(TestApp.A);
+    }
+
+    @Nullable
+    private static String getModuleMetadataPackageName() {
+        String packageName = InstrumentationRegistry.getContext().getResources().getString(
+                R.string.config_defaultModuleMetadataProvider);
+        if (TextUtils.isEmpty(packageName)) {
+            return null;
+        }
+        return packageName;
+    }
+
+    private void resetModuleMetadataPackage() {
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+
+        assertThat(MODULE_META_DATA_PACKAGE).isNotNull();
+        rm.expireRollbackForPackage(MODULE_META_DATA_PACKAGE);
+
+        assertThat(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(),
+                MODULE_META_DATA_PACKAGE)).isNull();
+    }
+
+    private void runShellCommand(String cmd) {
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .executeShellCommand(cmd);
+    }
 }
diff --git a/tests/RollbackTest/SecondaryUserRollbackTest.xml b/tests/RollbackTest/SecondaryUserRollbackTest.xml
new file mode 100644
index 0000000..6b3f05c
--- /dev/null
+++ b/tests/RollbackTest/SecondaryUserRollbackTest.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<configuration description="Runs the rollback test from a secondary user">
+    <option name="test-suite-tag" value="SecondaryUserRollbackTest" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="RollbackTest.apk" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="pm uninstall com.android.cts.install.lib.testapp.A" />
+        <option name="run-command" value="pm uninstall com.android.cts.install.lib.testapp.B" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.HostTest" >
+        <option name="class" value="com.android.tests.rollback.host.SecondaryUserRollbackTest" />
+    </test>
+</configuration>
diff --git a/tests/RollbackTest/SecondaryUserRollbackTest/src/com/android/tests/rollback/host/SecondaryUserRollbackTest.java b/tests/RollbackTest/SecondaryUserRollbackTest/src/com/android/tests/rollback/host/SecondaryUserRollbackTest.java
new file mode 100644
index 0000000..11a0fbb
--- /dev/null
+++ b/tests/RollbackTest/SecondaryUserRollbackTest/src/com/android/tests/rollback/host/SecondaryUserRollbackTest.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 com.android.tests.rollback.host;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Runs rollback tests from a secondary user.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class SecondaryUserRollbackTest extends BaseHostJUnit4Test {
+    private static final int SYSTEM_USER_ID = 0;
+    // The user that was running originally when the test starts.
+    private int mOriginalUser = SYSTEM_USER_ID;
+    private int mSecondaryUserId = -1;
+    private static final long SWITCH_USER_COMPLETED_NUMBER_OF_POLLS = 60;
+    private static final long SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS = 1000;
+
+
+    @After
+    public void tearDown() throws Exception {
+        getDevice().switchUser(mOriginalUser);
+        getDevice().executeShellCommand("pm uninstall com.android.cts.install.lib.testapp.A");
+        getDevice().executeShellCommand("pm uninstall com.android.cts.install.lib.testapp.B");
+        removeSecondaryUserIfNecessary();
+    }
+
+    @Before
+    public void setup() throws Exception {
+        createAndSwitchToSecondaryUserIfNecessary();
+        installPackageAsUser("RollbackTest.apk", true, mSecondaryUserId, "--user current");
+    }
+
+    @Test
+    public void testBasic() throws Exception {
+        assertTrue(runDeviceTests("com.android.tests.rollback",
+                "com.android.tests.rollback.RollbackTest",
+                "testBasic"));
+    }
+
+    private void removeSecondaryUserIfNecessary() throws Exception {
+        if (mSecondaryUserId != -1) {
+            getDevice().removeUser(mSecondaryUserId);
+            mSecondaryUserId = -1;
+        }
+    }
+
+    private void createAndSwitchToSecondaryUserIfNecessary() throws Exception {
+        if (mSecondaryUserId == -1) {
+            mOriginalUser = getDevice().getCurrentUser();
+            mSecondaryUserId = getDevice().createUser("SecondaryUserRollbackTest_User");
+            assertTrue(getDevice().switchUser(mSecondaryUserId));
+            // give time for user to be switched
+            waitForSwitchUserCompleted(mSecondaryUserId);
+        }
+    }
+
+    private void waitForSwitchUserCompleted(int userId) throws Exception {
+        for (int i = 0; i < SWITCH_USER_COMPLETED_NUMBER_OF_POLLS; ++i) {
+            String logs = getDevice().executeAdbCommand("logcat", "-v", "brief", "-d",
+                    "ActivityManager:D");
+            if (logs.contains("Posting BOOT_COMPLETED user #" + userId)) {
+                return;
+            }
+            Thread.sleep(SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS);
+        }
+        fail("User switch to user " + userId + " timed out");
+    }
+}
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index bad2947..b2e5a62 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -33,6 +33,8 @@
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class StagedRollbackTest extends BaseHostJUnit4Test {
+    private static final int NATIVE_CRASHES_THRESHOLD = 5;
+
     /**
      * Runs the given phase of a test by calling into the device.
      * Throws an exception if the test phase fails.
@@ -83,6 +85,29 @@
         runPhase("testBadApkOnlyConfirmRollback");
     }
 
+    @Test
+    public void testNativeWatchdogTriggersRollback() throws Exception {
+        //Stage install ModuleMetadata package - this simulates a Mainline module update
+        runPhase("installModuleMetadataPackage");
+
+        // Reboot device to activate staged package
+        getDevice().reboot();
+        getDevice().waitForDeviceAvailable();
+
+        runPhase("assertModuleMetadataRollbackAvailable");
+
+        // crash system_server enough times to trigger a rollback
+        crashProcess("system_server", NATIVE_CRASHES_THRESHOLD);
+
+        // Rollback should be committed automatically now
+        // Give time for rollback to be committed
+        assertTrue(getDevice().waitForDeviceNotAvailable(60000));
+        getDevice().waitForDeviceAvailable();
+
+        // verify rollback committed
+        runPhase("assertModuleMetadataRollbackCommitted");
+    }
+
     /**
      * Tests failed network health check triggers watchdog staged rollbacks.
      */
@@ -165,4 +190,30 @@
         // Verify rollback was not executed after health check deadline
         runPhase("assertNoNetworkStackRollbackCommitted");
     }
+
+    /**
+     * Tests rolling back user data where there are multiple rollbacks for that package.
+     */
+    @Test
+    public void testPreviouslyAbandonedRollbacks() throws Exception {
+        runPhase("testPreviouslyAbandonedRollbacksEnableRollback");
+        getDevice().reboot();
+        runPhase("testPreviouslyAbandonedRollbacksCommitRollback");
+        getDevice().reboot();
+        runPhase("testPreviouslyAbandonedRollbacksCheckUserdataRollback");
+    }
+
+    private void crashProcess(String processName, int numberOfCrashes) throws Exception {
+        String pid = "";
+        String lastPid = "invalid";
+        for (int i = 0; i < numberOfCrashes; ++i) {
+            // This condition makes sure before we kill the process, the process is running AND
+            // the last crash was finished.
+            while ("".equals(pid) || lastPid.equals(pid)) {
+                pid = getDevice().executeShellCommand("pidof " + processName);
+            }
+            getDevice().executeShellCommand("kill " + pid);
+            lastPid = pid;
+        }
+    }
 }
diff --git a/tests/RollbackTest/TEST_MAPPING b/tests/RollbackTest/TEST_MAPPING
index 6be93a0..7ae03e6 100644
--- a/tests/RollbackTest/TEST_MAPPING
+++ b/tests/RollbackTest/TEST_MAPPING
@@ -5,6 +5,9 @@
     },
     {
       "name": "StagedRollbackTest"
+    },
+    {
+      "name": "SecondaryUserRollbackTest"
     }
   ]
 }
diff --git a/tests/RollbackTest/TestApp/ACrashingV2.xml b/tests/RollbackTest/TestApp/ACrashingV2.xml
deleted file mode 100644
index 77bfd4e..0000000
--- a/tests/RollbackTest/TestApp/ACrashingV2.xml
+++ /dev/null
@@ -1,36 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp.A"
-    android:versionCode="2"
-    android:versionName="2.0" >
-
-
-    <uses-sdk android:minSdkVersion="19" />
-
-    <application android:label="Rollback Test App A v2">
-        <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
-                  android:exported="true" />
-        <activity android:name="com.android.tests.rollback.testapp.CrashingMainActivity">
-            <intent-filter>
-              <action android:name="android.intent.action.MAIN" />
-              <category android:name="android.intent.category.DEFAULT"/>
-              <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Av1.xml b/tests/RollbackTest/TestApp/Av1.xml
deleted file mode 100644
index 63729fb..0000000
--- a/tests/RollbackTest/TestApp/Av1.xml
+++ /dev/null
@@ -1,35 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp.A"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-
-    <uses-sdk android:minSdkVersion="19" />
-
-    <application android:label="Rollback Test App A v1">
-        <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
-                  android:exported="true" />
-        <activity android:name="com.android.tests.rollback.testapp.MainActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Av2.xml b/tests/RollbackTest/TestApp/Av2.xml
deleted file mode 100644
index f0e909f..0000000
--- a/tests/RollbackTest/TestApp/Av2.xml
+++ /dev/null
@@ -1,35 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp.A"
-    android:versionCode="2"
-    android:versionName="2.0" >
-
-
-    <uses-sdk android:minSdkVersion="19" />
-
-    <application android:label="Rollback Test App A v2">
-        <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
-                  android:exported="true" />
-        <activity android:name="com.android.tests.rollback.testapp.MainActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Av3.xml b/tests/RollbackTest/TestApp/Av3.xml
deleted file mode 100644
index 9725c9f7..0000000
--- a/tests/RollbackTest/TestApp/Av3.xml
+++ /dev/null
@@ -1,35 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp.A"
-    android:versionCode="3"
-    android:versionName="3.0" >
-
-
-    <uses-sdk android:minSdkVersion="19" />
-
-    <application android:label="Rollback Test App A v3">
-        <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
-                  android:exported="true" />
-        <activity android:name="com.android.tests.rollback.testapp.MainActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Bv1.xml b/tests/RollbackTest/TestApp/Bv1.xml
deleted file mode 100644
index ca9c2ec..0000000
--- a/tests/RollbackTest/TestApp/Bv1.xml
+++ /dev/null
@@ -1,35 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp.B"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-
-    <uses-sdk android:minSdkVersion="19" />
-
-    <application android:label="Rollback Test App B v1">
-        <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
-                  android:exported="true" />
-        <activity android:name="com.android.tests.rollback.testapp.MainActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/Bv2.xml b/tests/RollbackTest/TestApp/Bv2.xml
deleted file mode 100644
index bd3e613..0000000
--- a/tests/RollbackTest/TestApp/Bv2.xml
+++ /dev/null
@@ -1,35 +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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.tests.rollback.testapp.B"
-    android:versionCode="2"
-    android:versionName="2.0" >
-
-
-    <uses-sdk android:minSdkVersion="19" />
-
-    <application android:label="Rollback Test App B v2">
-        <receiver android:name="com.android.tests.rollback.testapp.ProcessUserData"
-                  android:exported="true" />
-        <activity android:name="com.android.tests.rollback.testapp.MainActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/tests/RollbackTest/TestApp/res_v1/values-anydpi/values.xml b/tests/RollbackTest/TestApp/res_v1/values-anydpi/values.xml
deleted file mode 100644
index 90d3da2..0000000
--- a/tests/RollbackTest/TestApp/res_v1/values-anydpi/values.xml
+++ /dev/null
@@ -1,19 +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.
--->
-
-<resources>
-    <integer name="split_version">1</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v1/values/values.xml b/tests/RollbackTest/TestApp/res_v1/values/values.xml
deleted file mode 100644
index 0447c74..0000000
--- a/tests/RollbackTest/TestApp/res_v1/values/values.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<resources>
-    <integer name="app_version">1</integer>
-    <integer name="split_version">0</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v2/values-anydpi/values.xml b/tests/RollbackTest/TestApp/res_v2/values-anydpi/values.xml
deleted file mode 100644
index 9a1aa7f..0000000
--- a/tests/RollbackTest/TestApp/res_v2/values-anydpi/values.xml
+++ /dev/null
@@ -1,19 +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.
--->
-
-<resources>
-    <integer name="split_version">2</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v2/values/values.xml b/tests/RollbackTest/TestApp/res_v2/values/values.xml
deleted file mode 100644
index fd988f5..0000000
--- a/tests/RollbackTest/TestApp/res_v2/values/values.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<resources>
-    <integer name="app_version">2</integer>
-    <integer name="split_version">0</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v3/values-anydpi/values.xml b/tests/RollbackTest/TestApp/res_v3/values-anydpi/values.xml
deleted file mode 100644
index f2d8992..0000000
--- a/tests/RollbackTest/TestApp/res_v3/values-anydpi/values.xml
+++ /dev/null
@@ -1,19 +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.
--->
-
-<resources>
-    <integer name="split_version">3</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/res_v3/values/values.xml b/tests/RollbackTest/TestApp/res_v3/values/values.xml
deleted file mode 100644
index 968168a..0000000
--- a/tests/RollbackTest/TestApp/res_v3/values/values.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<resources>
-    <integer name="app_version">3</integer>
-    <integer name="split_version">0</integer>
-</resources>
diff --git a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/CrashingMainActivity.java b/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/CrashingMainActivity.java
deleted file mode 100644
index 97958ac..0000000
--- a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/CrashingMainActivity.java
+++ /dev/null
@@ -1,46 +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.tests.rollback.testapp;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-
-/**
- * A crashing test app for testing apk rollback support.
- */
-public class CrashingMainActivity extends Activity {
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        incrementCountAndBroadcast();
-        throw new RuntimeException("Intended force crash");
-    }
-
-    private void incrementCountAndBroadcast() {
-        SharedPreferences preferences = getSharedPreferences("prefs", Context.MODE_PRIVATE);
-        SharedPreferences.Editor editor = preferences.edit();
-        int count = preferences.getInt("crash_count", 0);
-        editor.putInt("crash_count", ++count).commit();
-
-        Intent intent = new Intent("com.android.tests.rollback.CRASH");
-        intent.putExtra("count", count);
-        sendBroadcast(intent);
-    }
-}
diff --git a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java b/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java
deleted file mode 100644
index 9f1a060..0000000
--- a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/MainActivity.java
+++ /dev/null
@@ -1,37 +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.tests.rollback.testapp;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-/**
- * A test app for testing apk rollback support.
- */
-public class MainActivity extends Activity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        try {
-            new ProcessUserData().processUserData(this);
-        } catch (ProcessUserData.UserDataException e) {
-            throw new AssertionError("Failed to process app user data", e);
-        }
-    }
-}
diff --git a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/ProcessUserData.java b/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/ProcessUserData.java
deleted file mode 100644
index 38c658e..0000000
--- a/tests/RollbackTest/TestApp/src/com/android/tests/rollback/testapp/ProcessUserData.java
+++ /dev/null
@@ -1,111 +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.tests.rollback.testapp;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Scanner;
-
-/**
- * A broadcast reciever to check for and update user app data version
- * compatibility.
- */
-public class ProcessUserData extends BroadcastReceiver {
-
-    private static final String TAG = "RollbackTestApp";
-
-    /**
-     * Exception thrown in case of issue with user data.
-     */
-    public static class UserDataException extends Exception {
-        public UserDataException(String message) {
-            super(message);
-        }
-
-        public UserDataException(String message, Throwable cause) {
-           super(message, cause);
-        }
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        try {
-            processUserData(context);
-            setResultCode(1);
-        } catch (UserDataException e) {
-            setResultCode(0);
-            setResultData(e.getMessage());
-        }
-    }
-
-    /**
-     * Update the app's user data version to match the app version.
-     *
-     * @param context The application context.
-     * @throws UserDataException in case of problems with app user data.
-     */
-    public void processUserData(Context context) throws UserDataException {
-        Resources res = context.getResources();
-        String packageName = context.getPackageName();
-
-        int appVersionId = res.getIdentifier("app_version", "integer", packageName);
-        int appVersion = res.getInteger(appVersionId);
-
-        int splitVersionId = res.getIdentifier("split_version", "integer", packageName);
-        int splitVersion = res.getInteger(splitVersionId);
-
-        // Make sure the app version and split versions are compatible.
-        if (appVersion != splitVersion) {
-            throw new UserDataException("Split version " + splitVersion
-                    + " does not match app version " + appVersion);
-        }
-
-        // Read the version of the app's user data and ensure it is compatible
-        // with our version of the application.
-        File versionFile = new File(context.getFilesDir(), "version.txt");
-        try {
-            Scanner s = new Scanner(versionFile);
-            int userDataVersion = s.nextInt();
-            s.close();
-
-            if (userDataVersion > appVersion) {
-                throw new UserDataException("User data is from version " + userDataVersion
-                        + ", which is not compatible with this version " + appVersion
-                        + " of the RollbackTestApp");
-            }
-        } catch (FileNotFoundException e) {
-            // No problem. This is a fresh install of the app or the user data
-            // has been wiped.
-        }
-
-        // Record the current version of the app in the user data.
-        try {
-            PrintWriter pw = new PrintWriter(versionFile);
-            pw.println(appVersion);
-            pw.close();
-        } catch (IOException e) {
-            throw new UserDataException("Unable to write user data.", e);
-        }
-    }
-}
diff --git a/tests/UiBench/res/drawable-nodpi/frantic.jpg b/tests/UiBench/res/drawable-nodpi/frantic.jpg
index 4c62333..856b419 100644
--- a/tests/UiBench/res/drawable-nodpi/frantic.jpg
+++ b/tests/UiBench/res/drawable-nodpi/frantic.jpg
Binary files differ
diff --git a/tests/WindowlessWmTest/Android.bp b/tests/WindowlessWmTest/Android.bp
new file mode 100644
index 0000000..2ace3f3
--- /dev/null
+++ b/tests/WindowlessWmTest/Android.bp
@@ -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.
+//
+
+android_test {
+    name: "WindowlessWmTest",
+    srcs: ["**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
+}
diff --git a/tests/WindowlessWmTest/AndroidManifest.xml b/tests/WindowlessWmTest/AndroidManifest.xml
new file mode 100644
index 0000000..babfd76
--- /dev/null
+++ b/tests/WindowlessWmTest/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?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.test.viewembed">
+
+    <application>
+        <activity android:name="WindowlessWmTest" android:label="View Embedding Test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+
+</manifest>
diff --git a/tests/WindowlessWmTest/src/com/android/test/viewembed/WindowlessWmTest.java b/tests/WindowlessWmTest/src/com/android/test/viewembed/WindowlessWmTest.java
new file mode 100644
index 0000000..5a146da
--- /dev/null
+++ b/tests/WindowlessWmTest/src/com/android/test/viewembed/WindowlessWmTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.viewembed;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.view.Gravity;
+import android.view.WindowlessViewRoot;
+import android.view.SurfaceHolder;
+import android.view.SurfaceHolder.Callback;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.FrameLayout;
+
+
+public class WindowlessWmTest extends Activity implements SurfaceHolder.Callback{
+    SurfaceView mView;
+    WindowlessViewRoot mVr;
+
+    protected void onCreate(Bundle savedInstanceState) {
+        FrameLayout content = new FrameLayout(this);
+        super.onCreate(savedInstanceState);
+        mView = new SurfaceView(this);
+        content.addView(mView, new FrameLayout.LayoutParams(
+                500, 500, Gravity.CENTER_HORIZONTAL | Gravity.TOP));
+        setContentView(content);
+
+        mView.setZOrderOnTop(true);
+        mView.getHolder().addCallback(this);
+    }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+        mVr = new WindowlessViewRoot(this, this.getDisplay(),
+                mView.getSurfaceControl());
+        Button v = new Button(this);
+        v.setBackgroundColor(Color.BLUE);
+        v.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    v.setBackgroundColor(Color.RED);
+                }
+        });
+        WindowManager.LayoutParams lp =
+            new WindowManager.LayoutParams(500, 500, WindowManager.LayoutParams.TYPE_APPLICATION,
+                    0, PixelFormat.OPAQUE);
+        mVr.addView(v, lp);
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+        Canvas canvas = holder.lockCanvas();
+        canvas.drawColor(Color.GREEN);
+        holder.unlockCanvasAndPost(canvas);
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+    }
+}
diff --git a/tests/libs-permissions/Android.bp b/tests/libs-permissions/Android.bp
index c7c4b10..330bfc9 100644
--- a/tests/libs-permissions/Android.bp
+++ b/tests/libs-permissions/Android.bp
@@ -14,16 +14,16 @@
 }
 
 java_library {
-    name: "com.android.test.libs.product_services",
+    name: "com.android.test.libs.system_ext",
     installable: true,
-    product_services_specific: true,
-    srcs: ["product_services/java/**/*.java"],
-    required: ["com.android.test.libs.product_services.xml"],
+    system_ext_specific: true,
+    srcs: ["system_ext/java/**/*.java"],
+    required: ["com.android.test.libs.system_ext.xml"],
 }
 
 prebuilt_etc {
-    name: "com.android.test.libs.product_services.xml",
-    src: "product_services/com.android.test.libs.product_services.xml",
+    name: "com.android.test.libs.system_ext.xml",
+    src: "system_ext/com.android.test.libs.system_ext.xml",
     sub_dir: "permissions",
-    product_services_specific: true,
+    system_ext_specific: true,
 }
diff --git a/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml b/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml
deleted file mode 100644
index 082a9be..0000000
--- a/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<permissions>
-    <library name="com.android.test.libs.product_services"
-            file="/product_services/framework/com.android.test.libs.product_services.jar" />
-</permissions>
diff --git a/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java b/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java
deleted file mode 100644
index dcbdae8..0000000
--- a/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java
+++ /dev/null
@@ -1,29 +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.test.libs.product_services;
-
-/**
- * Test class for product_services libs.
- */
-public class LibsProductServicesTest {
-
-    /**
-     * Dummy method for testing.
-     */
-    public static void test() {
-    }
-}
diff --git a/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml b/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
new file mode 100644
index 0000000..fa56004
--- /dev/null
+++ b/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<permissions>
+    <library name="com.android.test.libs.system_ext"
+            file="/system_ext/framework/com.android.test.libs.system_ext.jar" />
+</permissions>
diff --git a/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
new file mode 100644
index 0000000..9999aba
--- /dev/null
+++ b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.test.libs.system_ext;
+
+/**
+ * Test class for system_ext libs.
+ */
+public class LibsSystemExtTest {
+
+    /**
+     * Dummy method for testing.
+     */
+    public static void test() {
+    }
+}
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index eb25acf..5260b30 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -3,23 +3,6 @@
 //########################################################################
 java_defaults {
     name: "FrameworksNetTests-jni-defaults",
-    static_libs: [
-        "FrameworksNetCommonTests",
-        "frameworks-base-testutils",
-        "frameworks-net-testutils",
-        "framework-protos",
-        "androidx.test.rules",
-        "mockito-target-minus-junit4",
-        "net-tests-utils",
-        "platform-test-annotations",
-        "services.core",
-        "services.net",
-    ],
-    libs: [
-        "android.test.runner",
-        "android.test.base",
-        "android.test.mock",
-    ],
     jni_libs: [
         "ld-android",
         "libartbase",
@@ -45,20 +28,20 @@
         "libnativehelper",
         "libnetdbpf",
         "libnetdutils",
+        "libnetworkstatsfactorytestjni",
         "libpackagelistparser",
         "libpcre2",
         "libprocessgroup",
         "libselinux",
-        "libui",
-        "libutils",
-        "libvndksupport",
         "libtinyxml2",
+        "libui",
         "libunwindstack",
+        "libutils",
         "libutilscallstack",
+        "libvndksupport",
         "libziparchive",
         "libz",
         "netd_aidl_interface-V2-cpp",
-        "libnetworkstatsfactorytestjni",
     ],
 }
 
@@ -69,4 +52,20 @@
     platform_apis: true,
     test_suites: ["device-tests"],
     certificate: "platform",
+    static_libs: [
+        "androidx.test.rules",
+        "FrameworksNetCommonTests",
+        "frameworks-base-testutils",
+        "framework-protos",
+        "mockito-target-minus-junit4",
+        "net-tests-utils",
+        "platform-test-annotations",
+        "services.core",
+        "services.net",
+    ],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
 }
diff --git a/tests/net/common/Android.bp b/tests/net/common/Android.bp
index db1ccb4..e44d460 100644
--- a/tests/net/common/Android.bp
+++ b/tests/net/common/Android.bp
@@ -21,12 +21,12 @@
     srcs: ["java/**/*.java", "java/**/*.kt"],
     static_libs: [
         "androidx.test.rules",
-        "frameworks-net-testutils",
         "junit",
         "mockito-target-minus-junit4",
+        "net-tests-utils",
         "platform-test-annotations",
     ],
     libs: [
         "android.test.base.stubs",
     ],
-}
\ No newline at end of file
+}
diff --git a/tests/net/common/java/android/net/IpPrefixTest.java b/tests/net/common/java/android/net/IpPrefixTest.java
index 719960d..985e10d 100644
--- a/tests/net/common/java/android/net/IpPrefixTest.java
+++ b/tests/net/common/java/android/net/IpPrefixTest.java
@@ -16,16 +16,18 @@
 
 package android.net;
 
+import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
+import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.os.Parcel;
-
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -171,56 +173,46 @@
 
     }
 
-    private void assertAreEqual(Object o1, Object o2) {
-        assertTrue(o1.equals(o2));
-        assertTrue(o2.equals(o1));
-    }
-
-    private void assertAreNotEqual(Object o1, Object o2) {
-        assertFalse(o1.equals(o2));
-        assertFalse(o2.equals(o1));
-    }
-
     @Test
     public void testEquals() {
         IpPrefix p1, p2;
 
         p1 = new IpPrefix("192.0.2.251/23");
         p2 = new IpPrefix(new byte[]{(byte) 192, (byte) 0, (byte) 2, (byte) 251}, 23);
-        assertAreEqual(p1, p2);
+        assertEqualBothWays(p1, p2);
 
         p1 = new IpPrefix("192.0.2.5/23");
-        assertAreEqual(p1, p2);
+        assertEqualBothWays(p1, p2);
 
         p1 = new IpPrefix("192.0.2.5/24");
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
 
         p1 = new IpPrefix("192.0.4.5/23");
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
 
 
         p1 = new IpPrefix("2001:db8:dead:beef:f00::80/122");
         p2 = new IpPrefix(IPV6_BYTES, 122);
         assertEquals("2001:db8:dead:beef:f00::80/122", p2.toString());
-        assertAreEqual(p1, p2);
+        assertEqualBothWays(p1, p2);
 
         p1 = new IpPrefix("2001:db8:dead:beef:f00::bf/122");
-        assertAreEqual(p1, p2);
+        assertEqualBothWays(p1, p2);
 
         p1 = new IpPrefix("2001:db8:dead:beef:f00::8:0/123");
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
 
         p1 = new IpPrefix("2001:db8:dead:beef::/122");
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
 
         // 192.0.2.4/32 != c000:0204::/32.
         byte[] ipv6bytes = new byte[16];
         System.arraycopy(IPV4_BYTES, 0, ipv6bytes, 0, IPV4_BYTES.length);
         p1 = new IpPrefix(ipv6bytes, 32);
-        assertAreEqual(p1, new IpPrefix("c000:0204::/32"));
+        assertEqualBothWays(p1, new IpPrefix("c000:0204::/32"));
 
         p2 = new IpPrefix(IPV4_BYTES, 32);
-        assertAreNotEqual(p1, p2);
+        assertNotEqualEitherWay(p1, p2);
     }
 
     @Test
@@ -356,25 +348,6 @@
         assertEquals(InetAddress.parseNumericAddress("192.0.2.0"), p.getAddress());
     }
 
-    public IpPrefix passThroughParcel(IpPrefix p) {
-        Parcel parcel = Parcel.obtain();
-        IpPrefix p2 = null;
-        try {
-            p.writeToParcel(parcel, 0);
-            parcel.setDataPosition(0);
-            p2 = IpPrefix.CREATOR.createFromParcel(parcel);
-        } finally {
-            parcel.recycle();
-        }
-        assertNotNull(p2);
-        return p2;
-    }
-
-    public void assertParcelingIsLossless(IpPrefix p) {
-        IpPrefix p2 = passThroughParcel(p);
-        assertEquals(p, p2);
-    }
-
     @Test
     public void testParceling() {
         IpPrefix p;
@@ -386,5 +359,7 @@
         p = new IpPrefix("192.0.2.0/25");
         assertParcelingIsLossless(p);
         assertTrue(p.isIPv4());
+
+        assertFieldCountEquals(2, IpPrefix.class);
     }
 }
diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java
index d462441b..b2e573b 100644
--- a/tests/net/common/java/android/net/LinkAddressTest.java
+++ b/tests/net/common/java/android/net/LinkAddressTest.java
@@ -27,15 +27,17 @@
 import static android.system.OsConstants.RT_SCOPE_SITE;
 import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
 
+import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
+import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.os.Parcel;
-
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -217,67 +219,56 @@
                 l1.isSameAddressAs(l2));
     }
 
-    private void assertLinkAddressesEqual(LinkAddress l1, LinkAddress l2) {
-        assertTrue(l1 + " unexpectedly not equal to " + l2, l1.equals(l2));
-        assertTrue(l2 + " unexpectedly not equal to " + l1, l2.equals(l1));
-        assertEquals(l1.hashCode(), l2.hashCode());
-    }
-
-    private void assertLinkAddressesNotEqual(LinkAddress l1, LinkAddress l2) {
-        assertFalse(l1 + " unexpectedly equal to " + l2, l1.equals(l2));
-        assertFalse(l2 + " unexpectedly equal to " + l1, l2.equals(l1));
-    }
-
     @Test
     public void testEqualsAndSameAddressAs() {
         LinkAddress l1, l2, l3;
 
         l1 = new LinkAddress("2001:db8::1/64");
         l2 = new LinkAddress("2001:db8::1/64");
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         l2 = new LinkAddress("2001:db8::1/65");
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
         l2 = new LinkAddress("2001:db8::2/64");
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
 
         l1 = new LinkAddress("192.0.2.1/24");
         l2 = new LinkAddress("192.0.2.1/24");
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         l2 = new LinkAddress("192.0.2.1/23");
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
         l2 = new LinkAddress("192.0.2.2/24");
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
 
         // Check equals() and isSameAddressAs() on identical addresses with different flags.
         l1 = new LinkAddress(V6_ADDRESS, 64);
         l2 = new LinkAddress(V6_ADDRESS, 64, 0, RT_SCOPE_UNIVERSE);
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         l2 = new LinkAddress(V6_ADDRESS, 64, IFA_F_DEPRECATED, RT_SCOPE_UNIVERSE);
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         // Check equals() and isSameAddressAs() on identical addresses with different scope.
         l1 = new LinkAddress(V4_ADDRESS, 24);
         l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_UNIVERSE);
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         l2 = new LinkAddress(V4_ADDRESS, 24, 0, RT_SCOPE_HOST);
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsSameAddressAs(l1, l2);
 
         // Addresses with the same start or end bytes aren't equal between families.
@@ -291,10 +282,10 @@
         assertTrue(Arrays.equals(ipv4Bytes, l2FirstIPv6Bytes));
         assertTrue(Arrays.equals(ipv4Bytes, l3LastIPv6Bytes));
 
-        assertLinkAddressesNotEqual(l1, l2);
+        assertNotEqualEitherWay(l1, l2);
         assertIsNotSameAddressAs(l1, l2);
 
-        assertLinkAddressesNotEqual(l1, l3);
+        assertNotEqualEitherWay(l1, l3);
         assertIsNotSameAddressAs(l1, l3);
 
         // Because we use InetAddress, an IPv4 address is equal to its IPv4-mapped address.
@@ -302,7 +293,7 @@
         String addressString = V4 + "/24";
         l1 = new LinkAddress(addressString);
         l2 = new LinkAddress("::ffff:" + addressString);
-        assertLinkAddressesEqual(l1, l2);
+        assertEqualBothWays(l1, l2);
         assertIsSameAddressAs(l1, l2);
     }
 
@@ -319,25 +310,6 @@
         assertNotEquals(l1.hashCode(), l2.hashCode());
     }
 
-    private LinkAddress passThroughParcel(LinkAddress l) {
-        Parcel p = Parcel.obtain();
-        LinkAddress l2 = null;
-        try {
-            l.writeToParcel(p, 0);
-            p.setDataPosition(0);
-            l2 = LinkAddress.CREATOR.createFromParcel(p);
-        } finally {
-            p.recycle();
-        }
-        assertNotNull(l2);
-        return l2;
-    }
-
-    private void assertParcelingIsLossless(LinkAddress l) {
-      LinkAddress l2 = passThroughParcel(l);
-      assertEquals(l, l2);
-    }
-
     @Test
     public void testParceling() {
         LinkAddress l;
@@ -346,7 +318,7 @@
         assertParcelingIsLossless(l);
 
         l = new LinkAddress(V4 + "/28", IFA_F_PERMANENT, RT_SCOPE_LINK);
-        assertParcelingIsLossless(l);
+        assertParcelSane(l, 4);
     }
 
     private void assertGlobalPreferred(LinkAddress l, String msg) {
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index e1c4238..b0464d9 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -31,8 +33,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.util.TestUtils;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -942,13 +942,13 @@
 
         source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
 
-        TestUtils.assertParcelingIsLossless(source);
+        assertParcelingIsLossless(source);
     }
 
     @Test
     public void testParcelUninitialized() throws Exception {
         LinkProperties empty = new LinkProperties();
-        TestUtils.assertParcelingIsLossless(empty);
+        assertParcelingIsLossless(empty);
     }
 
     @Test
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 6bc7c1b..2ca0d1a 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -38,6 +38,9 @@
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
 
+import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -45,7 +48,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.os.Parcel;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
 
@@ -267,9 +269,9 @@
             .setUids(uids)
             .addCapability(NET_CAPABILITY_EIMS)
             .addCapability(NET_CAPABILITY_NOT_METERED);
-        assertEqualsThroughMarshalling(netCap);
+        assertParcelingIsLossless(netCap);
         netCap.setSSID(TEST_SSID);
-        assertEqualsThroughMarshalling(netCap);
+        assertParcelSane(netCap, 11);
     }
 
     @Test
@@ -542,18 +544,6 @@
         nc1.combineCapabilities(nc3);
     }
 
-    private void assertEqualsThroughMarshalling(NetworkCapabilities netCap) {
-        Parcel p = Parcel.obtain();
-        netCap.writeToParcel(p, /* flags */ 0);
-        p.setDataPosition(0);
-        byte[] marshalledData = p.marshall();
-
-        p = Parcel.obtain();
-        p.unmarshall(marshalledData, 0, marshalledData.length);
-        p.setDataPosition(0);
-        assertEquals(NetworkCapabilities.CREATOR.createFromParcel(p), netCap);
-    }
-
     @Test
     public void testSet() {
         NetworkCapabilities nc1 = new NetworkCapabilities();
diff --git a/tests/net/common/java/android/net/NetworkTest.java b/tests/net/common/java/android/net/NetworkTest.java
index 38bc744..11d44b8 100644
--- a/tests/net/common/java/android/net/NetworkTest.java
+++ b/tests/net/common/java/android/net/NetworkTest.java
@@ -18,13 +18,10 @@
 
 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 static org.junit.Assert.fail;
 
-import android.net.LocalServerSocket;
-import android.net.LocalSocket;
-import android.net.LocalSocketAddress;
-import android.net.Network;
 import android.platform.test.annotations.AppModeFull;
 
 import androidx.test.filters.SmallTest;
@@ -40,7 +37,6 @@
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.SocketException;
-import java.util.Objects;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -123,29 +119,29 @@
         Network three = new Network(3);
 
         // None of the hashcodes are zero.
-        assertNotEqual(0, one.hashCode());
-        assertNotEqual(0, two.hashCode());
-        assertNotEqual(0, three.hashCode());
+        assertNotEquals(0, one.hashCode());
+        assertNotEquals(0, two.hashCode());
+        assertNotEquals(0, three.hashCode());
 
         // All the hashcodes are distinct.
-        assertNotEqual(one.hashCode(), two.hashCode());
-        assertNotEqual(one.hashCode(), three.hashCode());
-        assertNotEqual(two.hashCode(), three.hashCode());
+        assertNotEquals(one.hashCode(), two.hashCode());
+        assertNotEquals(one.hashCode(), three.hashCode());
+        assertNotEquals(two.hashCode(), three.hashCode());
 
         // None of the handles are zero.
-        assertNotEqual(0, one.getNetworkHandle());
-        assertNotEqual(0, two.getNetworkHandle());
-        assertNotEqual(0, three.getNetworkHandle());
+        assertNotEquals(0, one.getNetworkHandle());
+        assertNotEquals(0, two.getNetworkHandle());
+        assertNotEquals(0, three.getNetworkHandle());
 
         // All the handles are distinct.
-        assertNotEqual(one.getNetworkHandle(), two.getNetworkHandle());
-        assertNotEqual(one.getNetworkHandle(), three.getNetworkHandle());
-        assertNotEqual(two.getNetworkHandle(), three.getNetworkHandle());
+        assertNotEquals(one.getNetworkHandle(), two.getNetworkHandle());
+        assertNotEquals(one.getNetworkHandle(), three.getNetworkHandle());
+        assertNotEquals(two.getNetworkHandle(), three.getNetworkHandle());
 
         // The handles are not equal to the hashcodes.
-        assertNotEqual(one.hashCode(), one.getNetworkHandle());
-        assertNotEqual(two.hashCode(), two.getNetworkHandle());
-        assertNotEqual(three.hashCode(), three.getNetworkHandle());
+        assertNotEquals(one.hashCode(), one.getNetworkHandle());
+        assertNotEquals(two.hashCode(), two.getNetworkHandle());
+        assertNotEquals(three.hashCode(), three.getNetworkHandle());
 
         // Adjust as necessary to test an implementation's specific constants.
         // When running with runtest, "adb logcat -s TestRunner" can be useful.
@@ -154,15 +150,11 @@
         assertEquals(16290598925L, three.getNetworkHandle());
     }
 
-    private static <T> void assertNotEqual(T t1, T t2) {
-        assertFalse(Objects.equals(t1, t2));
-    }
-
     @Test
     public void testGetPrivateDnsBypassingCopy() {
         final Network copy = mNetwork.getPrivateDnsBypassingCopy();
         assertEquals(mNetwork.netId, copy.netId);
-        assertNotEqual(copy.netId, copy.getNetIdForResolv());
-        assertNotEqual(mNetwork.getNetIdForResolv(), copy.getNetIdForResolv());
+        assertNotEquals(copy.netId, copy.getNetIdForResolv());
+        assertNotEquals(mNetwork.getNetIdForResolv(), copy.getNetIdForResolv());
     }
 }
diff --git a/tests/net/common/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java
index 2edbd40..5ce8436 100644
--- a/tests/net/common/java/android/net/RouteInfoTest.java
+++ b/tests/net/common/java/android/net/RouteInfoTest.java
@@ -18,7 +18,11 @@
 
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 
-import android.os.Parcel;
+import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
+import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import android.test.suitebuilder.annotation.SmallTest;
 
 import junit.framework.TestCase;
@@ -109,47 +113,37 @@
         assertFalse(ipv4Default.matches(Address("2001:db8::f00")));
     }
 
-    private void assertAreEqual(Object o1, Object o2) {
-        assertTrue(o1.equals(o2));
-        assertTrue(o2.equals(o1));
-    }
-
-    private void assertAreNotEqual(Object o1, Object o2) {
-        assertFalse(o1.equals(o2));
-        assertFalse(o2.equals(o1));
-    }
-
     public void testEquals() {
         // IPv4
         RouteInfo r1 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0");
         RouteInfo r2 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "wlan0");
-        assertAreEqual(r1, r2);
+        assertEqualBothWays(r1, r2);
 
         RouteInfo r3 = new RouteInfo(Prefix("2001:db8:ace::/49"), Address("2001:db8::1"), "wlan0");
         RouteInfo r4 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::2"), "wlan0");
         RouteInfo r5 = new RouteInfo(Prefix("2001:db8:ace::/48"), Address("2001:db8::1"), "rmnet0");
-        assertAreNotEqual(r1, r3);
-        assertAreNotEqual(r1, r4);
-        assertAreNotEqual(r1, r5);
+        assertNotEqualEitherWay(r1, r3);
+        assertNotEqualEitherWay(r1, r4);
+        assertNotEqualEitherWay(r1, r5);
 
         // IPv6
         r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0");
         r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "wlan0");
-        assertAreEqual(r1, r2);
+        assertEqualBothWays(r1, r2);
 
         r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0");
         r4 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.2"), "wlan0");
         r5 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), "rmnet0");
-        assertAreNotEqual(r1, r3);
-        assertAreNotEqual(r1, r4);
-        assertAreNotEqual(r1, r5);
+        assertNotEqualEitherWay(r1, r3);
+        assertNotEqualEitherWay(r1, r4);
+        assertNotEqualEitherWay(r1, r5);
 
         // Interfaces (but not destinations or gateways) can be null.
         r1 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null);
         r2 = new RouteInfo(Prefix("192.0.2.0/25"), Address("192.0.2.1"), null);
         r3 = new RouteInfo(Prefix("192.0.2.0/24"), Address("192.0.2.1"), "wlan0");
-        assertAreEqual(r1, r2);
-        assertAreNotEqual(r1, r3);
+        assertEqualBothWays(r1, r2);
+        assertNotEqualEitherWay(r1, r3);
     }
 
     public void testHostAndDefaultRoutes() {
@@ -257,25 +251,6 @@
       // No exceptions? Good.
     }
 
-    public RouteInfo passThroughParcel(RouteInfo r) {
-        Parcel p = Parcel.obtain();
-        RouteInfo r2 = null;
-        try {
-            r.writeToParcel(p, 0);
-            p.setDataPosition(0);
-            r2 = RouteInfo.CREATOR.createFromParcel(p);
-        } finally {
-            p.recycle();
-        }
-        assertNotNull(r2);
-        return r2;
-    }
-
-    public void assertParcelingIsLossless(RouteInfo r) {
-      RouteInfo r2 = passThroughParcel(r);
-      assertEquals(r, r2);
-    }
-
     public void testParceling() {
         RouteInfo r;
 
@@ -283,6 +258,6 @@
         assertParcelingIsLossless(r);
 
         r = new RouteInfo(Prefix("192.0.2.0/24"), null, "wlan0");
-        assertParcelingIsLossless(r);
+        assertParcelSane(r, 6);
     }
 }
diff --git a/tests/net/common/java/android/net/StaticIpConfigurationTest.java b/tests/net/common/java/android/net/StaticIpConfigurationTest.java
index 5096be2..b5f23bf 100644
--- a/tests/net/common/java/android/net/StaticIpConfigurationTest.java
+++ b/tests/net/common/java/android/net/StaticIpConfigurationTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -34,7 +35,6 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -61,10 +61,6 @@
         assertEquals(0, s.dnsServers.size());
     }
 
-    private static <T> void assertNotEquals(T t1, T t2) {
-        assertFalse(Objects.equals(t1, t2));
-    }
-
     private StaticIpConfiguration makeTestObject() {
         StaticIpConfiguration s = new StaticIpConfiguration();
         s.ipAddress = ADDR;
diff --git a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index 0ce7c91..f4f804a 100644
--- a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -16,6 +16,8 @@
 
 package android.net.apf;
 
+import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -24,9 +26,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.util.ParcelableTestUtil;
-import com.android.internal.util.TestUtils;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -40,9 +39,7 @@
         assertEquals(456, caps.maximumApfProgramSize);
         assertEquals(789, caps.apfPacketFormat);
 
-        ParcelableTestUtil.assertFieldCountEquals(3, ApfCapabilities.class);
-
-        TestUtils.assertParcelingIsLossless(caps);
+        assertParcelSane(caps, 3);
     }
 
     @Test
diff --git a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt b/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt
index 8d055c9..0b7b740 100644
--- a/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/ApfProgramEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics;
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
@@ -30,11 +28,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ApfProgramEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     private infix fun Int.hasFlag(flag: Int) = (this and (1 shl flag)) != 0
 
     @Test
@@ -55,7 +48,7 @@
         assertEquals(5, apfProgramEvent.programLength)
         assertEquals(ApfProgramEvent.flagsFor(true, true), apfProgramEvent.flags)
 
-        testParcel(apfProgramEvent, 6)
+        assertParcelSane(apfProgramEvent, 6)
     }
 
     @Test
diff --git a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt b/tests/net/common/java/android/net/metrics/ApfStatsTest.kt
index f8eb40c..46a8c8e 100644
--- a/tests/net/common/java/android/net/metrics/ApfStatsTest.kt
+++ b/tests/net/common/java/android/net/metrics/ApfStatsTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,11 +26,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ApfStatsTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testBuilderAndParcel() {
         val apfStats = ApfStats.Builder()
@@ -59,6 +52,6 @@
         assertEquals(8, apfStats.programUpdatesAllowingMulticast)
         assertEquals(9, apfStats.maxProgramSize)
 
-        testParcel(apfStats, 10)
+        assertParcelSane(apfStats, 10)
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt
index 36e9f8c..8d7a9c4 100644
--- a/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/DhcpClientEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -30,11 +28,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class DhcpClientEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testBuilderAndParcel() {
         val dhcpClientEvent = DhcpClientEvent.Builder()
@@ -45,6 +38,6 @@
         assertEquals(FAKE_MESSAGE, dhcpClientEvent.msg)
         assertEquals(Integer.MAX_VALUE, dhcpClientEvent.durationMs)
 
-        testParcel(dhcpClientEvent, 2)
+        assertParcelSane(dhcpClientEvent, 2)
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
index e9d5e6d..236f72e 100644
--- a/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/DhcpErrorEventTest.kt
@@ -1,10 +1,10 @@
 package android.net.metrics
 
-import android.net.metrics.DhcpErrorEvent.errorCodeWithOption
 import android.net.metrics.DhcpErrorEvent.DHCP_INVALID_OPTION_LENGTH
+import android.net.metrics.DhcpErrorEvent.errorCodeWithOption
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.TestUtils.parcelingRoundTrip
+import com.android.testutils.parcelingRoundTrip
 import java.lang.reflect.Modifier
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
@@ -62,4 +62,4 @@
     fun testToString_InvalidErrorCode() {
         assertNotNull(DhcpErrorEvent(TEST_ERROR_CODE).toString())
     }
-}
\ No newline at end of file
+}
diff --git a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt b/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt
index 5144ca5..64be508 100644
--- a/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/IpManagerEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,11 +26,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class IpManagerEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testConstructorAndParcel() {
         (IpManagerEvent.PROVISIONING_OK..IpManagerEvent.ERROR_INTERFACE_NOT_FOUND).forEach {
@@ -40,7 +33,7 @@
             assertEquals(it, ipManagerEvent.eventType)
             assertEquals(Long.MAX_VALUE, ipManagerEvent.durationMs)
 
-            testParcel(ipManagerEvent, 2)
+            assertParcelSane(ipManagerEvent, 2)
         }
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt b/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt
index d76ebf6..55b5e49 100644
--- a/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/IpReachabilityEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,18 +26,13 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class IpReachabilityEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testConstructorAndParcel() {
         (IpReachabilityEvent.PROBE..IpReachabilityEvent.PROVISIONING_LOST_ORGANIC).forEach {
             val ipReachabilityEvent = IpReachabilityEvent(it)
             assertEquals(it, ipReachabilityEvent.eventType)
 
-            testParcel(ipReachabilityEvent, 1)
+            assertParcelSane(ipReachabilityEvent, 1)
         }
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt b/tests/net/common/java/android/net/metrics/NetworkEventTest.kt
index 8b52e81..41430b0 100644
--- a/tests/net/common/java/android/net/metrics/NetworkEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/NetworkEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,11 +26,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class NetworkEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testConstructorAndParcel() {
         (NetworkEvent.NETWORK_CONNECTED..NetworkEvent.NETWORK_PARTIAL_CONNECTIVITY).forEach {
@@ -44,7 +37,7 @@
             assertEquals(it, networkEvent.eventType)
             assertEquals(Long.MAX_VALUE, networkEvent.durationMs)
 
-            testParcel(networkEvent, 2)
+            assertParcelSane(networkEvent, 2)
         }
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/RaEventTest.kt b/tests/net/common/java/android/net/metrics/RaEventTest.kt
index f38d328..d9b7203 100644
--- a/tests/net/common/java/android/net/metrics/RaEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/RaEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -30,11 +28,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class RaEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     @Test
     fun testConstructorAndParcel() {
         var raEvent = RaEvent.Builder().build()
@@ -74,6 +67,6 @@
         assertEquals(5, raEvent.rdnssLifetime)
         assertEquals(6, raEvent.dnsslLifetime)
 
-        testParcel(raEvent, 6)
+        assertParcelSane(raEvent, 6)
     }
 }
diff --git a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt b/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt
index c0cef8f..51c0d41 100644
--- a/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt
+++ b/tests/net/common/java/android/net/metrics/ValidationProbeEventTest.kt
@@ -16,11 +16,9 @@
 
 package android.net.metrics
 
-import android.os.Parcelable
 import androidx.test.filters.SmallTest
 import androidx.test.runner.AndroidJUnit4
-import com.android.internal.util.ParcelableTestUtil
-import com.android.internal.util.TestUtils
+import com.android.testutils.assertParcelSane
 import java.lang.reflect.Modifier
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
@@ -33,11 +31,6 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class ValidationProbeEventTest {
-    private fun <T: Parcelable> testParcel(obj: T, fieldCount: Int) {
-        ParcelableTestUtil.assertFieldCountEquals(fieldCount, obj::class.java)
-        TestUtils.assertParcelingIsLossless(obj)
-    }
-
     private infix fun Int.hasType(type: Int) = (type and this) == type
 
     @Test
@@ -58,7 +51,7 @@
         assertTrue(validationProbeEvent.probeType hasType FIRST_VALIDATION)
         assertEquals(ValidationProbeEvent.DNS_SUCCESS, validationProbeEvent.returnCode)
 
-        testParcel(validationProbeEvent, 3)
+        assertParcelSane(validationProbeEvent, 3)
     }
 
     @Test
diff --git a/tests/net/common/java/android/net/util/SocketUtilsTest.kt b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
new file mode 100644
index 0000000..9c7cfb0
--- /dev/null
+++ b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.util;
+
+import android.system.NetlinkSocketAddress
+import android.system.Os
+import android.system.OsConstants.AF_INET
+import android.system.OsConstants.ETH_P_ALL
+import android.system.OsConstants.IPPROTO_UDP
+import android.system.OsConstants.RTMGRP_NEIGH
+import android.system.OsConstants.SOCK_DGRAM
+import android.system.PacketSocketAddress
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val TEST_INDEX = 123
+private const val TEST_PORT = 555
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class SocketUtilsTest {
+    @Test
+    fun testMakeNetlinkSocketAddress() {
+        val nlAddress = SocketUtils.makeNetlinkSocketAddress(TEST_PORT, RTMGRP_NEIGH)
+        if (nlAddress is NetlinkSocketAddress) {
+            assertEquals(TEST_PORT, nlAddress.getPortId())
+            assertEquals(RTMGRP_NEIGH, nlAddress.getGroupsMask())
+        } else {
+            fail("Not NetlinkSocketAddress object")
+        }
+    }
+
+    @Test
+    fun testMakePacketSocketAddress() {
+        val pkAddress = SocketUtils.makePacketSocketAddress(ETH_P_ALL, TEST_INDEX)
+        assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress)
+
+        val ff = 0xff.toByte()
+        val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX,
+                byteArrayOf(ff, ff, ff, ff, ff, ff))
+        assertTrue("Not PacketSocketAddress object", pkAddress2 is PacketSocketAddress)
+    }
+
+    @Test
+    fun testCloseSocket() {
+        // Expect no exception happening with null object.
+        SocketUtils.closeSocket(null)
+
+        val fd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
+        assertTrue(fd.valid())
+        SocketUtils.closeSocket(fd)
+        assertFalse(fd.valid())
+        // Expecting socket should be still invalid even closed socket again.
+        SocketUtils.closeSocket(fd)
+        assertFalse(fd.valid())
+    }
+}
diff --git a/tests/net/deflake/Android.bp b/tests/net/deflake/Android.bp
new file mode 100644
index 0000000..1c48c74
--- /dev/null
+++ b/tests/net/deflake/Android.bp
@@ -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.
+//
+
+java_test_host {
+    name: "FrameworksNetDeflakeTest",
+    srcs: ["src/**/*.kt"],
+    libs: [
+        "junit",
+        "tradefed",
+    ],
+    static_libs: [
+        "kotlin-test",
+        "net-host-tests-utils",
+    ],
+    data: [":FrameworksNetTests"],
+}
\ No newline at end of file
diff --git a/tests/net/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt b/tests/net/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt
new file mode 100644
index 0000000..6285525
--- /dev/null
+++ b/tests/net/deflake/src/com/android/server/net/FrameworksNetDeflakeTest.kt
@@ -0,0 +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
+ */
+
+package com.android.server.net
+
+import com.android.testutils.host.DeflakeHostTestBase
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
+import org.junit.runner.RunWith
+
+@RunWith(DeviceJUnit4ClassRunner::class)
+class FrameworksNetDeflakeTest: DeflakeHostTestBase() {
+    override val runCount = 20
+    override val testApkFilename = "FrameworksNetTests.apk"
+    override val testClasses = listOf("com.android.server.ConnectivityServiceTest")
+}
\ No newline at end of file
diff --git a/tests/net/java/android/app/usage/NetworkStatsManagerTest.java b/tests/net/java/android/app/usage/NetworkStatsManagerTest.java
index fd555c1..899295a 100644
--- a/tests/net/java/android/app/usage/NetworkStatsManagerTest.java
+++ b/tests/net/java/android/app/usage/NetworkStatsManagerTest.java
@@ -202,8 +202,7 @@
         assertFalse(stats.hasNextBucket());
     }
 
-    private void assertBucketMatches(Entry expected,
-            NetworkStats.Bucket actual) {
+    private void assertBucketMatches(Entry expected, NetworkStats.Bucket actual) {
         assertEquals(expected.uid, actual.getUid());
         assertEquals(expected.rxBytes, actual.getRxBytes());
         assertEquals(expected.rxPackets, actual.getRxPackets());
diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java
index 215506c..c9888b2 100644
--- a/tests/net/java/android/net/IpSecConfigTest.java
+++ b/tests/net/java/android/net/IpSecConfigTest.java
@@ -16,12 +16,12 @@
 
 package android.net;
 
-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 com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
 
-import android.os.Parcel;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
 
 import androidx.test.filters.SmallTest;
 
@@ -89,23 +89,15 @@
         IpSecConfig original = getSampleConfig();
         IpSecConfig copy = new IpSecConfig(original);
 
-        assertTrue(IpSecConfig.equals(original, copy));
-        assertFalse(original == copy);
+        assertEquals(original, copy);
+        assertNotSame(original, copy);
     }
 
     @Test
-    public void testParcelUnparcel() throws Exception {
+    public void testParcelUnparcel() {
         assertParcelingIsLossless(new IpSecConfig());
 
         IpSecConfig c = getSampleConfig();
-        assertParcelingIsLossless(c);
-    }
-
-    private void assertParcelingIsLossless(IpSecConfig ci) throws Exception {
-        Parcel p = Parcel.obtain();
-        ci.writeToParcel(p, 0);
-        p.setDataPosition(0);
-        IpSecConfig co = IpSecConfig.CREATOR.createFromParcel(p);
-        assertTrue(IpSecConfig.equals(co, ci));
+        assertParcelSane(c, 15);
     }
 }
diff --git a/tests/net/java/android/net/IpSecTransformTest.java b/tests/net/java/android/net/IpSecTransformTest.java
index 2308a3c..424f23d 100644
--- a/tests/net/java/android/net/IpSecTransformTest.java
+++ b/tests/net/java/android/net/IpSecTransformTest.java
@@ -16,8 +16,8 @@
 
 package android.net;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 
 import androidx.test.filters.SmallTest;
 
@@ -43,7 +43,7 @@
         config.setSpiResourceId(1985);
         IpSecTransform postModification = new IpSecTransform(null, config);
 
-        assertFalse(IpSecTransform.equals(preModification, postModification));
+        assertNotEquals(preModification, postModification);
     }
 
     @Test
@@ -57,6 +57,6 @@
         IpSecTransform config1 = new IpSecTransform(null, config);
         IpSecTransform config2 = new IpSecTransform(null, config);
 
-        assertTrue(IpSecTransform.equals(config1, config2));
+        assertEquals(config1, config2);
     }
 }
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index 583d3fd..5cb0d7e 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -16,14 +16,14 @@
 
 package android.net;
 
+import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
 import android.net.SocketKeepalive.InvalidPacketException;
 
-import com.android.internal.util.TestUtils;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -79,7 +79,7 @@
         assertEquals(testInfo.tos, resultData.ipTos);
         assertEquals(testInfo.ttl, resultData.ipTtl);
 
-        TestUtils.assertParcelingIsLossless(resultData);
+        assertParcelingIsLossless(resultData);
 
         final byte[] packet = resultData.getPacket();
         // IP version and IHL
diff --git a/tests/net/java/android/net/shared/InitialConfigurationTest.java b/tests/net/java/android/net/shared/InitialConfigurationTest.java
index 2fb8b19..17f8324 100644
--- a/tests/net/java/android/net/shared/InitialConfigurationTest.java
+++ b/tests/net/java/android/net/shared/InitialConfigurationTest.java
@@ -18,7 +18,7 @@
 
 import static android.net.InetAddresses.parseNumericAddress;
 
-import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
diff --git a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
index f9dbdc7..f987389 100644
--- a/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
+++ b/tests/net/java/android/net/shared/IpConfigurationParcelableUtilTest.java
@@ -20,7 +20,7 @@
 import static android.net.shared.IpConfigurationParcelableUtil.fromStableParcelable;
 import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
 
-import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
 
 import static org.junit.Assert.assertEquals;
 
diff --git a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
index 382afe0..7079a28 100644
--- a/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
+++ b/tests/net/java/android/net/shared/ProvisioningConfigurationTest.java
@@ -19,7 +19,7 @@
 import static android.net.InetAddresses.parseNumericAddress;
 import static android.net.shared.ProvisioningConfiguration.fromStableParcelable;
 
-import static com.android.internal.util.ParcelableTestUtil.assertFieldCountEquals;
+import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
diff --git a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
index 814e06e..8ea226d 100644
--- a/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
+++ b/tests/net/java/android/net/util/KeepaliveUtilsTest.kt
@@ -78,7 +78,6 @@
         assertRunWithException(arrayOf("5"))
 
         // Check resource with invalid slots value.
-        assertRunWithException(arrayOf("2,2"))
         assertRunWithException(arrayOf("3,-1"))
 
         // Check resource with invalid transport type.
diff --git a/tests/net/java/com/android/internal/util/RingBufferTest.java b/tests/net/java/com/android/internal/util/RingBufferTest.java
index eff334f..d06095a 100644
--- a/tests/net/java/com/android/internal/util/RingBufferTest.java
+++ b/tests/net/java/com/android/internal/util/RingBufferTest.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.util;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
@@ -25,9 +26,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.Arrays;
-import java.util.Objects;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class RingBufferTest {
@@ -36,7 +34,7 @@
     public void testEmptyRingBuffer() {
         RingBuffer<String> buffer = new RingBuffer<>(String.class, 100);
 
-        assertArraysEqual(new String[0], buffer.toArray());
+        assertArrayEquals(new String[0], buffer.toArray());
     }
 
     @Test
@@ -65,7 +63,7 @@
         buffer.append("e");
 
         String[] expected = {"a", "b", "c", "d", "e"};
-        assertArraysEqual(expected, buffer.toArray());
+        assertArrayEquals(expected, buffer.toArray());
     }
 
     @Test
@@ -73,19 +71,19 @@
         RingBuffer<String> buffer = new RingBuffer<>(String.class, 1);
 
         buffer.append("a");
-        assertArraysEqual(new String[]{"a"}, buffer.toArray());
+        assertArrayEquals(new String[]{"a"}, buffer.toArray());
 
         buffer.append("b");
-        assertArraysEqual(new String[]{"b"}, buffer.toArray());
+        assertArrayEquals(new String[]{"b"}, buffer.toArray());
 
         buffer.append("c");
-        assertArraysEqual(new String[]{"c"}, buffer.toArray());
+        assertArrayEquals(new String[]{"c"}, buffer.toArray());
 
         buffer.append("d");
-        assertArraysEqual(new String[]{"d"}, buffer.toArray());
+        assertArrayEquals(new String[]{"d"}, buffer.toArray());
 
         buffer.append("e");
-        assertArraysEqual(new String[]{"e"}, buffer.toArray());
+        assertArrayEquals(new String[]{"e"}, buffer.toArray());
     }
 
     @Test
@@ -100,7 +98,7 @@
         buffer.append("e");
 
         String[] expected1 = {"a", "b", "c", "d", "e"};
-        assertArraysEqual(expected1, buffer.toArray());
+        assertArrayEquals(expected1, buffer.toArray());
 
         String[] expected2 = new String[capacity];
         int firstIndex = 0;
@@ -111,22 +109,22 @@
             buffer.append("x");
             expected2[i] = "x";
         }
-        assertArraysEqual(expected2, buffer.toArray());
+        assertArrayEquals(expected2, buffer.toArray());
 
         buffer.append("x");
         expected2[firstIndex] = "x";
-        assertArraysEqual(expected2, buffer.toArray());
+        assertArrayEquals(expected2, buffer.toArray());
 
         for (int i = 0; i < 10; i++) {
             for (String s : expected2) {
                 buffer.append(s);
             }
         }
-        assertArraysEqual(expected2, buffer.toArray());
+        assertArrayEquals(expected2, buffer.toArray());
 
         buffer.append("a");
         expected2[lastIndex] = "a";
-        assertArraysEqual(expected2, buffer.toArray());
+        assertArrayEquals(expected2, buffer.toArray());
     }
 
     @Test
@@ -143,7 +141,7 @@
             expected[i] = new DummyClass1();
             expected[i].x = capacity * i;
         }
-        assertArraysEqual(expected, buffer.toArray());
+        assertArrayEquals(expected, buffer.toArray());
 
         for (int i = 0; i < capacity; ++i) {
             if (actual[i] != buffer.getNextSlot()) {
@@ -177,18 +175,4 @@
     }
 
     private static final class DummyClass3 {}
-
-    static <T> void assertArraysEqual(T[] expected, T[] got) {
-        if (expected.length != got.length) {
-            fail(Arrays.toString(expected) + " and " + Arrays.toString(got)
-                    + " did not have the same length");
-        }
-
-        for (int i = 0; i < expected.length; i++) {
-            if (!Objects.equals(expected[i], got[i])) {
-                fail(Arrays.toString(expected) + " and " + Arrays.toString(got)
-                        + " were not equal");
-            }
-        }
-    }
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index e099270..5cc95d9 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -18,6 +18,7 @@
 
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.net.ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.NETID_UNSET;
 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
@@ -68,7 +69,16 @@
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 
-import static org.junit.Assert.assertArrayEquals;
+import static com.android.testutils.ConcurrentUtilsKt.await;
+import static com.android.testutils.ConcurrentUtilsKt.durationOf;
+import static com.android.testutils.ExceptionUtils.ignoreExceptions;
+import static com.android.testutils.HandlerUtilsKt.waitForIdleSerialExecutor;
+import static com.android.testutils.MiscAssertsKt.assertContainsExactly;
+import static com.android.testutils.MiscAssertsKt.assertEmpty;
+import static com.android.testutils.MiscAssertsKt.assertLength;
+import static com.android.testutils.MiscAssertsKt.assertRunsInAtMost;
+import static com.android.testutils.MiscAssertsKt.assertThrows;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -76,13 +86,13 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -137,6 +147,7 @@
 import android.net.NetworkMisc;
 import android.net.NetworkRequest;
 import android.net.NetworkSpecifier;
+import android.net.NetworkStack;
 import android.net.NetworkStackClient;
 import android.net.NetworkState;
 import android.net.NetworkUtils;
@@ -149,7 +160,9 @@
 import android.net.shared.NetworkMonitorUtils;
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.MultinetworkPolicyTracker;
+import android.os.BadParcelableException;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -187,12 +200,16 @@
 import com.android.server.connectivity.IpConnectivityMetrics;
 import com.android.server.connectivity.MockableSystemProperties;
 import com.android.server.connectivity.Nat464Xlat;
+import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
 import com.android.server.connectivity.ProxyTracker;
 import com.android.server.connectivity.Tethering;
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.NetworkPinner;
 import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.testutils.ExceptionUtils;
 import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.RecorderCallback.CallbackRecord;
+import com.android.testutils.TestableNetworkCallback;
 
 import org.junit.After;
 import org.junit.Before;
@@ -213,14 +230,12 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
-import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
@@ -229,7 +244,8 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Predicate;
+
+import kotlin.reflect.KClass;
 
 /**
  * Tests for {@link ConnectivityService}.
@@ -279,6 +295,7 @@
     @Mock NetworkStackClient mNetworkStack;
     @Mock PackageManager mPackageManager;
     @Mock UserManager mUserManager;
+    @Mock NotificationManager mNotificationManager;
 
     private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
             ArgumentCaptor.forClass(ResolverParamsParcel.class);
@@ -348,7 +365,7 @@
         @Override
         public Object getSystemService(String name) {
             if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
-            if (Context.NOTIFICATION_SERVICE.equals(name)) return mock(NotificationManager.class);
+            if (Context.NOTIFICATION_SERVICE.equals(name)) return mNotificationManager;
             if (Context.NETWORK_STACK_SERVICE.equals(name)) return mNetworkStack;
             if (Context.USER_SERVICE.equals(name)) return mUserManager;
             return super.getSystemService(name);
@@ -368,7 +385,17 @@
         public PackageManager getPackageManager() {
             return mPackageManager;
         }
-   }
+
+        @Override
+        public void enforceCallingOrSelfPermission(String permission, String message) {
+            // The mainline permission can only be held if signed with the network stack certificate
+            // Skip testing for this permission.
+            if (NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK.equals(permission)) return;
+            // All other permissions should be held by the test or unnecessary: check as normal to
+            // make sure the code does not rely on unexpected permissions.
+            super.enforceCallingOrSelfPermission(permission, message);
+        }
+    }
 
     public void waitForIdle(int timeoutMsAsInt) {
         long timeoutMs = timeoutMsAsInt;
@@ -392,7 +419,7 @@
     }
 
     @Test
-    public void testWaitForIdle() {
+    public void testWaitForIdle() throws Exception {
         final int attempts = 50;  // Causes the test to take about 200ms on bullhead-eng.
 
         // Tests that waitForIdle returns immediately if the service is already idle.
@@ -419,7 +446,7 @@
     // This test has an inherent race condition in it, and cannot be enabled for continuous testing
     // or presubmit tests. It is kept for manual runs and documentation purposes.
     @Ignore
-    public void verifyThatNotWaitingForIdleCausesRaceConditions() {
+    public void verifyThatNotWaitingForIdleCausesRaceConditions() throws Exception {
         // Bring up a network that we can use to send messages to ConnectivityService.
         ConditionVariable cv = waitForConnectivityBroadcasts(1);
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -442,7 +469,7 @@
         fail("expected race condition at least once in " + attempts + " attempts");
     }
 
-    private class MockNetworkAgent {
+    private class MockNetworkAgent implements TestableNetworkCallback.HasNetwork {
         private static final int VALIDATION_RESULT_BASE = NETWORK_VALIDATION_PROBE_DNS
                 | NETWORK_VALIDATION_PROBE_HTTP
                 | NETWORK_VALIDATION_PROBE_HTTPS;
@@ -499,11 +526,11 @@
             mNmValidationRedirectUrl = null;
         }
 
-        MockNetworkAgent(int transport) {
+        MockNetworkAgent(int transport) throws Exception {
             this(transport, new LinkProperties());
         }
 
-        MockNetworkAgent(int transport, LinkProperties linkProperties) {
+        MockNetworkAgent(int transport, LinkProperties linkProperties) throws Exception {
             final int type = transportToLegacyType(transport);
             final String typeName = ConnectivityManager.getNetworkTypeName(type);
             mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock");
@@ -534,16 +561,12 @@
 
             mNetworkMonitor = mock(INetworkMonitor.class);
             final Answer validateAnswer = inv -> {
-                new Thread(this::onValidationRequested).start();
+                new Thread(ignoreExceptions(this::onValidationRequested)).start();
                 return null;
             };
 
-            try {
-                doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any());
-                doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt());
-            } catch (RemoteException e) {
-                fail(e.getMessage());
-            }
+            doAnswer(validateAnswer).when(mNetworkMonitor).notifyNetworkConnected(any(), any());
+            doAnswer(validateAnswer).when(mNetworkMonitor).forceReevaluation(anyInt());
 
             final ArgumentCaptor<Network> nmNetworkCaptor = ArgumentCaptor.forClass(Network.class);
             final ArgumentCaptor<INetworkMonitorCallbacks> nmCbCaptor =
@@ -598,35 +621,27 @@
             assertEquals(mNetworkAgent.netId, nmNetworkCaptor.getValue().netId);
             mNmCallbacks = nmCbCaptor.getValue();
 
-            try {
-                mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor);
-            } catch (RemoteException e) {
-                fail(e.getMessage());
-            }
+            mNmCallbacks.onNetworkMonitorCreated(mNetworkMonitor);
 
             // Waits for the NetworkAgent to be registered, which includes the creation of the
             // NetworkMonitor.
             waitForIdle();
         }
 
-        private void onValidationRequested() {
-            try {
-                if (mNmProvNotificationRequested
-                        && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) {
-                    mNmCallbacks.hideProvisioningNotification();
-                    mNmProvNotificationRequested = false;
-                }
+        private void onValidationRequested() throws Exception {
+            if (mNmProvNotificationRequested
+                    && ((mNmValidationResult & NETWORK_VALIDATION_RESULT_VALID) != 0)) {
+                mNmCallbacks.hideProvisioningNotification();
+                mNmProvNotificationRequested = false;
+            }
 
-                mNmCallbacks.notifyNetworkTested(
-                        mNmValidationResult, mNmValidationRedirectUrl);
+            mNmCallbacks.notifyNetworkTested(
+                    mNmValidationResult, mNmValidationRedirectUrl);
 
-                if (mNmValidationRedirectUrl != null) {
-                    mNmCallbacks.showProvisioningNotification(
-                            "test_provisioning_notif_action", "com.android.test.package");
-                    mNmProvNotificationRequested = true;
-                }
-            } catch (RemoteException e) {
-                fail(e.getMessage());
+            if (mNmValidationRedirectUrl != null) {
+                mNmCallbacks.showProvisioningNotification(
+                        "test_provisioning_notif_action", "com.android.test.package");
+                mNmProvNotificationRequested = true;
             }
         }
 
@@ -639,8 +654,8 @@
             return mScore;
         }
 
-        public void explicitlySelected(boolean acceptUnvalidated) {
-            mNetworkAgent.explicitlySelected(acceptUnvalidated);
+        public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) {
+            mNetworkAgent.explicitlySelected(explicitlySelected, acceptUnvalidated);
         }
 
         public void addCapability(int capability) {
@@ -743,6 +758,11 @@
             connect(false);
         }
 
+        public void connectWithPartialValidConnectivity() {
+            setNetworkPartialValid();
+            connect(false);
+        }
+
         public void suspend() {
             mNetworkInfo.setDetailedState(DetailedState.SUSPENDED, null, null);
             mNetworkAgent.sendNetworkInfo(mNetworkInfo);
@@ -1224,18 +1244,13 @@
             waitForIdle(TIMEOUT_MS);
         }
 
-        public void setUidRulesChanged(int uidRules) {
-            try {
-                mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules);
-            } catch (RemoteException ignored) {
-            }
+        public void setUidRulesChanged(int uidRules) throws RemoteException {
+            mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules);
         }
 
-        public void setRestrictBackgroundChanged(boolean restrictBackground) {
-            try {
-                mPolicyListener.onRestrictBackgroundChanged(restrictBackground);
-            } catch (RemoteException ignored) {
-            }
+        public void setRestrictBackgroundChanged(boolean restrictBackground)
+                throws RemoteException {
+            mPolicyListener.onRestrictBackgroundChanged(restrictBackground);
         }
     }
 
@@ -1690,274 +1705,33 @@
                 mCm.getDefaultRequest().networkCapabilities));
     }
 
-    enum CallbackState {
-        NONE,
-        AVAILABLE,
-        NETWORK_CAPABILITIES,
-        LINK_PROPERTIES,
-        SUSPENDED,
-        RESUMED,
-        LOSING,
-        LOST,
-        UNAVAILABLE,
-        BLOCKED_STATUS
-    }
-
-    private static class CallbackInfo {
-        public final CallbackState state;
-        public final Network network;
-        public final Object arg;
-        public CallbackInfo(CallbackState s, Network n, Object o) {
-            state = s; network = n; arg = o;
-        }
-        public String toString() {
-            return String.format("%s (%s) (%s)", state, network, arg);
-        }
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof CallbackInfo)) return false;
-            // Ignore timeMs, since it's unpredictable.
-            CallbackInfo other = (CallbackInfo) o;
-            return (state == other.state) && Objects.equals(network, other.network);
-        }
-        @Override
-        public int hashCode() {
-            return Objects.hash(state, network);
-        }
-    }
-
     /**
      * Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks
      * this class receives, by calling expectCallback() exactly once each time a callback is
      * received. assertNoCallback may be called at any time.
      */
-    private class TestNetworkCallback extends NetworkCallback {
-        private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
-        private Network mLastAvailableNetwork;
-
-        protected void setLastCallback(CallbackState state, Network network, Object o) {
-            mCallbacks.offer(new CallbackInfo(state, network, o));
+    private class TestNetworkCallback extends TestableNetworkCallback {
+        @Override
+        public void assertNoCallback() {
+            // TODO: better support this use case in TestableNetworkCallback
+            waitForIdle();
+            assertNoCallback(0 /* timeout */);
         }
 
         @Override
-        public void onAvailable(Network network) {
-            mLastAvailableNetwork = network;
-            setLastCallback(CallbackState.AVAILABLE, network, null);
-        }
-
-        @Override
-        public void onCapabilitiesChanged(Network network, NetworkCapabilities netCap) {
-            setLastCallback(CallbackState.NETWORK_CAPABILITIES, network, netCap);
-        }
-
-        @Override
-        public void onLinkPropertiesChanged(Network network, LinkProperties linkProp) {
-            setLastCallback(CallbackState.LINK_PROPERTIES, network, linkProp);
-        }
-
-        @Override
-        public void onUnavailable() {
-            setLastCallback(CallbackState.UNAVAILABLE, null, null);
-        }
-
-        @Override
-        public void onNetworkSuspended(Network network) {
-            setLastCallback(CallbackState.SUSPENDED, network, null);
-        }
-
-        @Override
-        public void onNetworkResumed(Network network) {
-            setLastCallback(CallbackState.RESUMED, network, null);
-        }
-
-        @Override
-        public void onLosing(Network network, int maxMsToLive) {
-            setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
-        }
-
-        @Override
-        public void onLost(Network network) {
-            mLastAvailableNetwork = null;
-            setLastCallback(CallbackState.LOST, network, null);
-        }
-
-        @Override
-        public void onBlockedStatusChanged(Network network, boolean blocked) {
-            setLastCallback(CallbackState.BLOCKED_STATUS, network, blocked);
-        }
-
-        public Network getLastAvailableNetwork() {
-            return mLastAvailableNetwork;
-        }
-
-        CallbackInfo nextCallback(int timeoutMs) {
-            CallbackInfo cb = null;
-            try {
-                cb = mCallbacks.poll(timeoutMs, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-            }
-            if (cb == null) {
-                // LinkedBlockingQueue.poll() returns null if it timeouts.
-                fail("Did not receive callback after " + timeoutMs + "ms");
-            }
-            return cb;
-        }
-
-        CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent, int timeoutMs) {
-            final Network expectedNetwork = (agent != null) ? agent.getNetwork() : null;
-            CallbackInfo expected = new CallbackInfo(state, expectedNetwork, 0);
-            CallbackInfo actual = nextCallback(timeoutMs);
-            assertEquals("Unexpected callback:", expected, actual);
-
-            if (state == CallbackState.LOSING) {
+        public <T extends CallbackRecord> T expectCallback(final KClass<T> type, final HasNetwork n,
+                final long timeoutMs) {
+            final T callback = super.expectCallback(type, n, timeoutMs);
+            if (callback instanceof CallbackRecord.Losing) {
+                // TODO : move this to the specific test(s) needing this rather than here.
+                final CallbackRecord.Losing losing = (CallbackRecord.Losing) callback;
+                final int maxMsToLive = losing.getMaxMsToLive();
                 String msg = String.format(
                         "Invalid linger time value %d, must be between %d and %d",
-                        actual.arg, 0, mService.mLingerDelayMs);
-                int maxMsToLive = (Integer) actual.arg;
+                        maxMsToLive, 0, mService.mLingerDelayMs);
                 assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= mService.mLingerDelayMs);
             }
-
-            return actual;
-        }
-
-        CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent) {
-            return expectCallback(state, agent, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        CallbackInfo expectCallbackLike(Predicate<CallbackInfo> fn) {
-            return expectCallbackLike(fn, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        CallbackInfo expectCallbackLike(Predicate<CallbackInfo> fn, int timeoutMs) {
-            int timeLeft = timeoutMs;
-            while (timeLeft > 0) {
-                long start = SystemClock.elapsedRealtime();
-                CallbackInfo info = nextCallback(timeLeft);
-                if (fn.test(info)) {
-                    return info;
-                }
-                timeLeft -= (SystemClock.elapsedRealtime() - start);
-            }
-            fail("Did not receive expected callback after " + timeoutMs + "ms");
-            return null;
-        }
-
-        // Expects onAvailable and the callbacks that follow it. These are:
-        // - onSuspended, iff the network was suspended when the callbacks fire.
-        // - onCapabilitiesChanged.
-        // - onLinkPropertiesChanged.
-        // - onBlockedStatusChanged.
-        //
-        // @param agent the network to expect the callbacks on.
-        // @param expectSuspended whether to expect a SUSPENDED callback.
-        // @param expectValidated the expected value of the VALIDATED capability in the
-        //        onCapabilitiesChanged callback.
-        // @param timeoutMs how long to wait for the callbacks.
-        void expectAvailableCallbacks(MockNetworkAgent agent, boolean expectSuspended,
-                boolean expectValidated, boolean expectBlocked, int timeoutMs) {
-            expectCallback(CallbackState.AVAILABLE, agent, timeoutMs);
-            if (expectSuspended) {
-                expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
-            }
-            if (expectValidated) {
-                expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent, timeoutMs);
-            } else {
-                expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, agent, timeoutMs);
-            }
-            expectCallback(CallbackState.LINK_PROPERTIES, agent, timeoutMs);
-            expectBlockedStatusCallback(expectBlocked, agent);
-        }
-
-        // Expects the available callbacks (validated), plus onSuspended.
-        void expectAvailableAndSuspendedCallbacks(MockNetworkAgent agent, boolean expectValidated) {
-            expectAvailableCallbacks(agent, true, expectValidated, false, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        void expectAvailableCallbacksValidated(MockNetworkAgent agent) {
-            expectAvailableCallbacks(agent, false, true, false, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        void expectAvailableCallbacksValidatedAndBlocked(MockNetworkAgent agent) {
-            expectAvailableCallbacks(agent, false, true, true, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        void expectAvailableCallbacksUnvalidated(MockNetworkAgent agent) {
-            expectAvailableCallbacks(agent, false, false, false, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        void expectAvailableCallbacksUnvalidatedAndBlocked(MockNetworkAgent agent) {
-            expectAvailableCallbacks(agent, false, false, true, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        // Expects the available callbacks (where the onCapabilitiesChanged must contain the
-        // VALIDATED capability), plus another onCapabilitiesChanged which is identical to the
-        // one we just sent.
-        // TODO: this is likely a bug. Fix it and remove this method.
-        void expectAvailableDoubleValidatedCallbacks(MockNetworkAgent agent) {
-            expectCallback(CallbackState.AVAILABLE, agent, TEST_CALLBACK_TIMEOUT_MS);
-            NetworkCapabilities nc1 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
-            expectCallback(CallbackState.LINK_PROPERTIES, agent, TEST_CALLBACK_TIMEOUT_MS);
-            // Implicitly check the network is allowed to use.
-            // TODO: should we need to consider if network is in blocked status in this case?
-            expectBlockedStatusCallback(false, agent);
-            NetworkCapabilities nc2 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
-            assertEquals(nc1, nc2);
-        }
-
-        // Expects the available callbacks where the onCapabilitiesChanged must not have validated,
-        // then expects another onCapabilitiesChanged that has the validated bit set. This is used
-        // when a network connects and satisfies a callback, and then immediately validates.
-        void expectAvailableThenValidatedCallbacks(MockNetworkAgent agent) {
-            expectAvailableCallbacksUnvalidated(agent);
-            expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
-        }
-
-        NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent) {
-            return expectCapabilitiesWith(capability, agent, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent,
-                int timeoutMs) {
-            CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs);
-            NetworkCapabilities nc = (NetworkCapabilities) cbi.arg;
-            assertTrue(nc.hasCapability(capability));
-            return nc;
-        }
-
-        NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent) {
-            return expectCapabilitiesWithout(capability, agent, TEST_CALLBACK_TIMEOUT_MS);
-        }
-
-        NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent,
-                int timeoutMs) {
-            CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs);
-            NetworkCapabilities nc = (NetworkCapabilities) cbi.arg;
-            assertFalse(nc.hasCapability(capability));
-            return nc;
-        }
-
-        void expectCapabilitiesLike(Predicate<NetworkCapabilities> fn, MockNetworkAgent agent) {
-            CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent);
-            assertTrue("Received capabilities don't match expectations : " + cbi.arg,
-                    fn.test((NetworkCapabilities) cbi.arg));
-        }
-
-        void expectLinkPropertiesLike(Predicate<LinkProperties> fn, MockNetworkAgent agent) {
-            CallbackInfo cbi = expectCallback(CallbackState.LINK_PROPERTIES, agent);
-            assertTrue("Received LinkProperties don't match expectations : " + cbi.arg,
-                    fn.test((LinkProperties) cbi.arg));
-        }
-
-        void expectBlockedStatusCallback(boolean expectBlocked, MockNetworkAgent agent) {
-            CallbackInfo cbi = expectCallback(CallbackState.BLOCKED_STATUS, agent);
-            boolean actualBlocked = (boolean) cbi.arg;
-            assertEquals(expectBlocked, actualBlocked);
-        }
-
-        void assertNoCallback() {
-            waitForIdle();
-            CallbackInfo c = mCallbacks.peek();
-            assertNull("Unexpected callback: " + c, c);
+            return callback;
         }
     }
 
@@ -2011,16 +1785,16 @@
 
         cv = waitForConnectivityBroadcasts(2);
         mWiFiNetworkAgent.disconnect();
-        genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        wifiNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         cellNetworkCallback.assertNoCallback();
         waitFor(cv);
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
 
         cv = waitForConnectivityBroadcasts(1);
         mCellNetworkAgent.disconnect();
-        genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         waitFor(cv);
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
 
@@ -2041,26 +1815,26 @@
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
         genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        genericNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
 
         mWiFiNetworkAgent.disconnect();
-        genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        wifiNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
 
         mCellNetworkAgent.disconnect();
-        genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
     }
 
     @Test
-    public void testMultipleLingering() {
+    public void testMultipleLingering() throws Exception {
         // This test would be flaky with the default 120ms timer: that is short enough that
         // lingered networks are torn down before assertions can be run. We don't want to mock the
         // lingering timer to keep the WakeupMessage logic realistic: this has already proven useful
@@ -2095,7 +1869,7 @@
         // We then get LOSING when wifi validates and cell is outscored.
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         // TODO: Investigate sending validated before losing.
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
@@ -2104,15 +1878,15 @@
         mEthernetNetworkAgent.connect(true);
         callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
         // TODO: Investigate sending validated before losing.
-        callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mWiFiNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
         assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         mEthernetNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
         defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
@@ -2128,7 +1902,7 @@
                 newNetwork = mWiFiNetworkAgent;
 
             }
-            callback.expectCallback(CallbackState.LOSING, oldNetwork);
+            callback.expectCallback(CallbackRecord.LOSING, oldNetwork);
             // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no
             // longer lingering?
             defaultCallback.expectAvailableCallbacksValidated(newNetwork);
@@ -2142,7 +1916,7 @@
         // We expect a notification about the capabilities change, and nothing else.
         defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent);
         defaultCallback.assertNoCallback();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Wifi no longer satisfies our listen, which is for an unmetered network.
@@ -2151,11 +1925,11 @@
 
         // Disconnect our test networks.
         mWiFiNetworkAgent.disconnect();
-        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
         mCellNetworkAgent.disconnect();
-        defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         waitForIdle();
         assertEquals(null, mCm.getActiveNetwork());
 
@@ -2186,8 +1960,8 @@
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -2198,15 +1972,15 @@
         mWiFiNetworkAgent.adjustScore(50);
         mWiFiNetworkAgent.connect(false);   // Score: 70
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Tear down wifi.
         mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -2217,19 +1991,19 @@
         mWiFiNetworkAgent.connect(true);
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         // TODO: Investigate sending validated before losing.
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
         mCellNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         waitForIdle();
         assertEquals(null, mCm.getActiveNetwork());
 
@@ -2244,7 +2018,7 @@
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         // TODO: Investigate sending validated before losing.
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
@@ -2255,13 +2029,13 @@
         // TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer
         // lingering?
         mCm.unregisterNetworkCallback(noopCallback);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
 
         // Similar to the above: lingering can start even after the lingered request is removed.
         // Disconnect wifi and switch to cell.
         mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
@@ -2280,12 +2054,12 @@
         callback.assertNoCallback();
         // Now unregister cellRequest and expect cell to start lingering.
         mCm.unregisterNetworkCallback(noopCallback);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
 
         // Let linger run its course.
         callback.assertNoCallback();
         final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4;
-        callback.expectCallback(CallbackState.LOST, mCellNetworkAgent, lingerTimeoutMs);
+        callback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent, lingerTimeoutMs);
 
         // Register a TRACK_DEFAULT request and check that it does not affect lingering.
         TestNetworkCallback trackDefaultCallback = new TestNetworkCallback();
@@ -2294,20 +2068,20 @@
         mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);
         mEthernetNetworkAgent.connect(true);
         callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
-        callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mWiFiNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
         trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         // Let linger run its course.
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
 
         // Clean up.
         mEthernetNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
-        trackDefaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
+        trackDefaultCallback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
 
         mCm.unregisterNetworkCallback(callback);
         mCm.unregisterNetworkCallback(defaultCallback);
@@ -2315,7 +2089,7 @@
     }
 
     @Test
-    public void testNetworkGoesIntoBackgroundAfterLinger() {
+    public void testNetworkGoesIntoBackgroundAfterLinger() throws Exception {
         setAlwaysOnNetworks(true);
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities()
@@ -2337,7 +2111,7 @@
         mWiFiNetworkAgent.connect(true);
         defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
 
         // File a request for cellular, then release it.
@@ -2346,7 +2120,7 @@
         NetworkCallback noopCallback = new NetworkCallback();
         mCm.requestNetwork(cellRequest, noopCallback);
         mCm.unregisterNetworkCallback(noopCallback);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
 
         // Let linger run its course.
         callback.assertNoCallback();
@@ -2360,7 +2134,7 @@
     }
 
     @Test
-    public void testExplicitlySelected() {
+    public void testExplicitlySelected() throws Exception {
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
                 .build();
@@ -2374,7 +2148,7 @@
 
         // Bring up unvalidated wifi with explicitlySelected=true.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        mWiFiNetworkAgent.explicitlySelected(false);
+        mWiFiNetworkAgent.explicitlySelected(true, false);
         mWiFiNetworkAgent.connect(false);
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
 
@@ -2390,28 +2164,28 @@
         // If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to
         // wifi even though it's unvalidated.
         mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         // Disconnect wifi, and then reconnect, again with explicitlySelected=true.
         mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        mWiFiNetworkAgent.explicitlySelected(false);
+        mWiFiNetworkAgent.explicitlySelected(true, false);
         mWiFiNetworkAgent.connect(false);
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
 
         // If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the
         // network to disconnect.
         mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false);
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
         // Reconnect, again with explicitlySelected=true, but this time validate.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
-        mWiFiNetworkAgent.explicitlySelected(false);
+        mWiFiNetworkAgent.explicitlySelected(true, false);
         mWiFiNetworkAgent.connect(true);
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
@@ -2423,14 +2197,36 @@
         assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         callback.assertNoCallback();
 
+        // Disconnect wifi, and then reconnect as if the user had selected "yes, don't ask again"
+        // (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to
+        // wifi immediately.
+        mWiFiNetworkAgent.disconnect();
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.explicitlySelected(true, true);
+        mWiFiNetworkAgent.connect(false);
+        callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mEthernetNetworkAgent);
+        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+        mEthernetNetworkAgent.disconnect();
+        callback.expectCallback(CallbackRecord.LOST, mEthernetNetworkAgent);
+
+        // Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true.
+        // Check that the network is not scored specially and that the device prefers cell data.
+        mWiFiNetworkAgent.disconnect();
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.explicitlySelected(false, true);
+        mWiFiNetworkAgent.connect(false);
+        callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+
         // Clean up.
         mWiFiNetworkAgent.disconnect();
         mCellNetworkAgent.disconnect();
-        mEthernetNetworkAgent.disconnect();
 
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
-        callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
     }
 
     private int[] makeIntArray(final int size, final int value) {
@@ -2566,10 +2362,10 @@
                 .build();
 
         Class<IllegalArgumentException> expected = IllegalArgumentException.class;
-        assertException(() -> { mCm.requestNetwork(request1, new NetworkCallback()); }, expected);
-        assertException(() -> { mCm.requestNetwork(request1, pendingIntent); }, expected);
-        assertException(() -> { mCm.requestNetwork(request2, new NetworkCallback()); }, expected);
-        assertException(() -> { mCm.requestNetwork(request2, pendingIntent); }, expected);
+        assertThrows(expected, () -> mCm.requestNetwork(request1, new NetworkCallback()));
+        assertThrows(expected, () -> mCm.requestNetwork(request1, pendingIntent));
+        assertThrows(expected, () -> mCm.requestNetwork(request2, new NetworkCallback()));
+        assertThrows(expected, () -> mCm.requestNetwork(request2, pendingIntent));
     }
 
     @Test
@@ -2641,7 +2437,7 @@
     }
 
     @Test
-    public void testPartialConnectivity() {
+    public void testPartialConnectivity() throws Exception {
         // Register network callback.
         NetworkRequest request = new NetworkRequest.Builder()
                 .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET)
@@ -2674,15 +2470,12 @@
         // If user accepts partial connectivity network,
         // NetworkMonitor#setAcceptPartialConnectivity() should be called too.
         waitForIdle();
-        try {
-            verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
-        } catch (RemoteException e) {
-            fail(e.getMessage());
-        }
+        verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
+
         // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
         // validated.
         mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED,
                 mWiFiNetworkAgent);
         assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY));
@@ -2690,7 +2483,7 @@
 
         // Disconnect and reconnect wifi with partial connectivity again.
         mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connectWithPartialConnectivity();
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
@@ -2702,69 +2495,79 @@
         // If the user chooses no, disconnect wifi immediately.
         mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), false/* accept */,
                 false /* always */);
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
         // If user accepted partial connectivity before, and device reconnects to that network
         // again, but now the network has full connectivity. The network shouldn't contain
         // NET_CAPABILITY_PARTIAL_CONNECTIVITY.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         // acceptUnvalidated is also used as setting for accepting partial networks.
-        mWiFiNetworkAgent.explicitlySelected(true /* acceptUnvalidated */);
+        mWiFiNetworkAgent.explicitlySelected(true /* 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());
-        }
+        verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY));
+
         // Wifi should be the default network.
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
-        // If user accepted partial connectivity before, and now the device reconnects to the
-        // partial connectivity network. The network should be valid and contain
-        // NET_CAPABILITY_PARTIAL_CONNECTIVITY.
+        // The user accepted partial connectivity and selected "don't ask again". Now the user
+        // reconnects to the partial connectivity network. Switch to wifi as soon as partial
+        // connectivity is detected.
         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.explicitlySelected(true /* explicitlySelected */,
+                true /* acceptUnvalidated */);
         mWiFiNetworkAgent.connectWithPartialConnectivity();
         // 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());
-        }
+        verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
-        // TODO: If the user accepted partial connectivity, we shouldn't switch to wifi until
-        // NetworkMonitor detects partial connectivity
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         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);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+
+        // If the user accepted partial connectivity, and the device auto-reconnects to the partial
+        // connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED.
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.explicitlySelected(false /* explicitlySelected */,
+                true /* acceptUnvalidated */);
+
+        // NetworkMonitor will immediately (once the HTTPS probe fails...) report the network as
+        // valid, because ConnectivityService calls setAcceptPartialConnectivity before it calls
+        // notifyNetworkConnected.
+        mWiFiNetworkAgent.connectWithPartialValidConnectivity();
+        waitForIdle();
+        verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
+        callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
+        callback.expectCapabilitiesWith(
+                NET_CAPABILITY_PARTIAL_CONNECTIVITY | NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        mWiFiNetworkAgent.disconnect();
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
     }
 
     @Test
-    public void testCaptivePortalOnPartialConnectivity() throws RemoteException {
+    public void testCaptivePortalOnPartialConnectivity() throws Exception {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
@@ -2802,7 +2605,7 @@
                 false /* always */);
         waitForIdle();
         mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
-        captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        captivePortalCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
         NetworkCapabilities nc =
                 validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
@@ -2813,7 +2616,7 @@
     }
 
     @Test
-    public void testCaptivePortal() {
+    public void testCaptivePortal() throws Exception {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
@@ -2835,7 +2638,7 @@
         // Take down network.
         // Expect onLost callback.
         mWiFiNetworkAgent.disconnect();
-        captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        captivePortalCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
         // Bring up a network with a captive portal.
         // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
@@ -2849,20 +2652,23 @@
         // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
         mWiFiNetworkAgent.setNetworkValid();
         mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
-        captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        captivePortalCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
         // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
         validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+        // Expect no notification to be shown when captive portal disappears by itself
+        verify(mNotificationManager, never()).notifyAsUser(
+                anyString(), eq(NotificationType.LOGGED_IN.eventId), any(), any());
 
         // Break network connectivity.
         // Expect NET_CAPABILITY_VALIDATED onLost callback.
         mWiFiNetworkAgent.setNetworkInvalid();
         mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
-        validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        validatedCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
     }
 
     @Test
-    public void testCaptivePortalApp() throws RemoteException {
+    public void testCaptivePortalApp() throws Exception {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
@@ -2882,31 +2688,45 @@
         // Check that calling startCaptivePortalApp does nothing.
         final int fastTimeoutMs = 100;
         mCm.startCaptivePortalApp(wifiNetwork);
+        waitForIdle();
+        verify(mWiFiNetworkAgent.mNetworkMonitor, never()).launchCaptivePortalApp();
         mServiceContext.expectNoStartActivityIntent(fastTimeoutMs);
 
         // Turn into a captive portal.
         mWiFiNetworkAgent.setNetworkPortal("http://example.com");
         mCm.reportNetworkConnectivity(wifiNetwork, false);
         captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        validatedCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
         // Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
         mCm.startCaptivePortalApp(wifiNetwork);
-        verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1))
-                .launchCaptivePortalApp();
+        waitForIdle();
+        verify(mWiFiNetworkAgent.mNetworkMonitor).launchCaptivePortalApp();
+
+        // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal)
+        final Bundle testBundle = new Bundle();
+        final String testKey = "testkey";
+        final String testValue = "testvalue";
+        testBundle.putString(testKey, testValue);
+        mCm.startCaptivePortalApp(wifiNetwork, testBundle);
+        final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS);
+        assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction());
+        assertEquals(testValue, signInIntent.getStringExtra(testKey));
 
         // Report that the captive portal is dismissed, and check that callbacks are fired
         mWiFiNetworkAgent.setNetworkValid();
         mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
         validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
-        captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        captivePortalCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        verify(mNotificationManager, times(1)).notifyAsUser(anyString(),
+                eq(NotificationType.LOGGED_IN.eventId), any(), eq(UserHandle.ALL));
 
         mCm.unregisterNetworkCallback(validatedCallback);
         mCm.unregisterNetworkCallback(captivePortalCallback);
     }
 
     @Test
-    public void testAvoidOrIgnoreCaptivePortals() {
+    public void testAvoidOrIgnoreCaptivePortals() throws Exception {
         final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
         final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
@@ -2946,7 +2766,7 @@
      * does work.
      */
     @Test
-    public void testNetworkSpecifier() {
+    public void testNetworkSpecifier() throws Exception {
         // A NetworkSpecifier subclass that matches all networks but must not be visible to apps.
         class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements
                 Parcelable {
@@ -3037,24 +2857,24 @@
         mWiFiNetworkAgent.setNetworkSpecifier(nsFoo);
         cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         for (TestNetworkCallback c: emptyCallbacks) {
-            c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsFoo),
-                    mWiFiNetworkAgent);
+            c.expectCapabilitiesThat(mWiFiNetworkAgent,
+                    (caps) -> caps.getNetworkSpecifier().equals(nsFoo));
         }
-        cFoo.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsFoo),
-                mWiFiNetworkAgent);
+        cFoo.expectCapabilitiesThat(mWiFiNetworkAgent,
+                (caps) -> caps.getNetworkSpecifier().equals(nsFoo));
         assertEquals(nsFoo,
                 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
         cFoo.assertNoCallback();
 
         mWiFiNetworkAgent.setNetworkSpecifier(nsBar);
-        cFoo.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        cFoo.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         cBar.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         for (TestNetworkCallback c: emptyCallbacks) {
-            c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsBar),
-                    mWiFiNetworkAgent);
+            c.expectCapabilitiesThat(mWiFiNetworkAgent,
+                    (caps) -> caps.getNetworkSpecifier().equals(nsBar));
         }
-        cBar.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier().equals(nsBar),
-                mWiFiNetworkAgent);
+        cBar.expectCapabilitiesThat(mWiFiNetworkAgent,
+                (caps) -> caps.getNetworkSpecifier().equals(nsBar));
         assertEquals(nsBar,
                 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
         cBar.assertNoCallback();
@@ -3062,23 +2882,23 @@
         mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier());
         cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         for (TestNetworkCallback c : emptyCallbacks) {
-            c.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null,
-                    mWiFiNetworkAgent);
+            c.expectCapabilitiesThat(mWiFiNetworkAgent,
+                    (caps) -> caps.getNetworkSpecifier() == null);
         }
-        cFoo.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null,
-                mWiFiNetworkAgent);
-        cBar.expectCapabilitiesLike((caps) -> caps.getNetworkSpecifier() == null,
-                mWiFiNetworkAgent);
+        cFoo.expectCapabilitiesThat(mWiFiNetworkAgent,
+                (caps) -> caps.getNetworkSpecifier() == null);
+        cBar.expectCapabilitiesThat(mWiFiNetworkAgent,
+                (caps) -> caps.getNetworkSpecifier() == null);
         assertNull(
                 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
         cFoo.assertNoCallback();
         cBar.assertNoCallback();
 
         mWiFiNetworkAgent.setNetworkSpecifier(null);
-        cFoo.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        cBar.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        cFoo.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        cBar.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         for (TestNetworkCallback c: emptyCallbacks) {
-            c.expectCallback(CallbackState.NETWORK_CAPABILITIES, mWiFiNetworkAgent);
+            c.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent);
         }
 
         assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
@@ -3086,24 +2906,18 @@
 
     @Test
     public void testInvalidNetworkSpecifier() {
-        try {
+        assertThrows(IllegalArgumentException.class, () -> {
             NetworkRequest.Builder builder = new NetworkRequest.Builder();
             builder.setNetworkSpecifier(new MatchAllNetworkSpecifier());
-            fail("NetworkRequest builder with MatchAllNetworkSpecifier");
-        } catch (IllegalArgumentException expected) {
-            // expected
-        }
+        });
 
-        try {
+        assertThrows(IllegalArgumentException.class, () -> {
             NetworkCapabilities networkCapabilities = new NetworkCapabilities();
             networkCapabilities.addTransportType(TRANSPORT_WIFI)
                     .setNetworkSpecifier(new MatchAllNetworkSpecifier());
             mService.requestNetwork(networkCapabilities, null, 0, null,
                     ConnectivityManager.TYPE_WIFI);
-            fail("ConnectivityService requestNetwork with MatchAllNetworkSpecifier");
-        } catch (IllegalArgumentException expected) {
-            // expected
-        }
+        });
 
         class NonParcelableSpecifier extends NetworkSpecifier {
             public boolean satisfiedBy(NetworkSpecifier other) { return false; }
@@ -3112,24 +2926,22 @@
             @Override public int describeContents() { return 0; }
             @Override public void writeToParcel(Parcel p, int flags) {}
         }
-        NetworkRequest.Builder builder;
 
-        builder = new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
-        try {
+        final NetworkRequest.Builder builder =
+                new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
+        assertThrows(ClassCastException.class, () -> {
             builder.setNetworkSpecifier(new NonParcelableSpecifier());
             Parcel parcelW = Parcel.obtain();
             builder.build().writeToParcel(parcelW, 0);
-            fail("Parceling a non-parcelable specifier did not throw an exception");
-        } catch (Exception e) {
-            // expected
-        }
+        });
 
-        builder = new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
-        builder.setNetworkSpecifier(new ParcelableSpecifier());
-        NetworkRequest nr = builder.build();
+        final NetworkRequest nr =
+                new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET)
+                .setNetworkSpecifier(new ParcelableSpecifier())
+                .build();
         assertNotNull(nr);
 
-        try {
+        assertThrows(BadParcelableException.class, () -> {
             Parcel parcelW = Parcel.obtain();
             nr.writeToParcel(parcelW, 0);
             byte[] bytes = parcelW.marshall();
@@ -3139,14 +2951,11 @@
             parcelR.unmarshall(bytes, 0, bytes.length);
             parcelR.setDataPosition(0);
             NetworkRequest rereadNr = NetworkRequest.CREATOR.createFromParcel(parcelR);
-            fail("Unparceling a non-framework NetworkSpecifier did not throw an exception");
-        } catch (Exception e) {
-            // expected
-        }
+        });
     }
 
     @Test
-    public void testNetworkSpecifierUidSpoofSecurityException() {
+    public void testNetworkSpecifierUidSpoofSecurityException() throws Exception {
         class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
             @Override
             public boolean satisfiedBy(NetworkSpecifier other) {
@@ -3171,12 +2980,9 @@
         NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier(
                 networkSpecifier).build();
         TestNetworkCallback networkCallback = new TestNetworkCallback();
-        try {
+        assertThrows(SecurityException.class, () -> {
             mCm.requestNetwork(networkRequest, networkCallback);
-            fail("Network request with spoofed UID did not throw a SecurityException");
-        } catch (SecurityException e) {
-            // expected
-        }
+        });
     }
 
     @Test
@@ -3188,36 +2994,20 @@
                 .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
-        }
+        assertThrows(SecurityException.class, () ->
+                mCm.registerNetworkCallback(r, new NetworkCallback()));
 
-        try {
-            mCm.registerNetworkCallback(r, PendingIntent.getService(
-                    mServiceContext, 0, new Intent(), 0));
-            fail("Expected SecurityException filing a callback with signal strength");
-        } catch (SecurityException expected) {
-            // expected
-        }
+        assertThrows(SecurityException.class, () ->
+                mCm.registerNetworkCallback(r, PendingIntent.getService(
+                        mServiceContext, 0, new Intent(), 0)));
 
         // 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
-        }
+        assertThrows(IllegalArgumentException.class, () ->
+                mCm.requestNetwork(r, new NetworkCallback()));
 
-        try {
-            mCm.requestNetwork(r, PendingIntent.getService(
-                    mServiceContext, 0, new Intent(), 0));
-            fail("Expected IllegalArgumentException filing a request with signal strength");
-        } catch (IllegalArgumentException expected) {
-            // expected
-        }
+        assertThrows(IllegalArgumentException.class, () ->
+                mCm.requestNetwork(r, PendingIntent.getService(
+                        mServiceContext, 0, new Intent(), 0)));
     }
 
     @Test
@@ -3251,7 +3041,7 @@
 
         // Bring down cell. Expect no default network callback, since it wasn't the default.
         mCellNetworkAgent.disconnect();
-        cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         defaultNetworkCallback.assertNoCallback();
         assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
@@ -3266,11 +3056,11 @@
         // followed by AVAILABLE cell.
         mWiFiNetworkAgent.disconnect();
         cellNetworkCallback.assertNoCallback();
-        defaultNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        defaultNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
         mCellNetworkAgent.disconnect();
-        cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
-        defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
+        defaultNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         waitForIdle();
         assertEquals(null, mCm.getActiveNetwork());
 
@@ -3286,7 +3076,7 @@
         assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         vpnNetworkAgent.disconnect();
-        defaultNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        defaultNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
         waitForIdle();
         assertEquals(null, mCm.getActiveNetwork());
     }
@@ -3314,14 +3104,15 @@
         lp.setInterfaceName("foonet_data0");
         mCellNetworkAgent.sendLinkProperties(lp);
         // We should get onLinkPropertiesChanged().
-        cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
+                mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
 
         // Suspend the network.
         mCellNetworkAgent.suspend();
         cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED,
                 mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.SUSPENDED, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.SUSPENDED, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
 
         // Register a garden variety default network request.
@@ -3336,7 +3127,7 @@
         mCellNetworkAgent.resume();
         cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED,
                 mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.RESUMED, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.RESUMED, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
 
         dfltNetworkCallback = new TestNetworkCallback();
@@ -3399,10 +3190,10 @@
 
         // When wifi connects, cell lingers.
         callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         fgCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        fgCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        fgCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         assertTrue(isForegroundNetwork(mCellNetworkAgent));
         assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
@@ -3410,7 +3201,7 @@
         // When lingering is complete, cell is still there but is now in the background.
         waitForIdle();
         int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4;
-        fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent, timeoutMs);
+        fgCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent, timeoutMs);
         // Expect a network capabilities update sans FOREGROUND.
         callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
         assertFalse(isForegroundNetwork(mCellNetworkAgent));
@@ -3436,7 +3227,7 @@
         // Release the request. The network immediately goes into the background, since it was not
         // lingering.
         mCm.unregisterNetworkCallback(cellCallback);
-        fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        fgCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         // Expect a network capabilities update sans FOREGROUND.
         callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
         assertFalse(isForegroundNetwork(mCellNetworkAgent));
@@ -3444,8 +3235,8 @@
 
         // Disconnect wifi and check that cell is foreground again.
         mWiFiNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        fgCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        fgCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
         assertTrue(isForegroundNetwork(mCellNetworkAgent));
 
@@ -3481,7 +3272,7 @@
             };
         }
 
-        assertTimeLimit("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> {
+        assertRunsInAtMost("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> {
             for (NetworkCallback cb : callbacks) {
                 mCm.registerNetworkCallback(request, cb);
             }
@@ -3494,7 +3285,7 @@
         mCellNetworkAgent.connect(false);
 
         long onAvailableDispatchingDuration = durationOf(() -> {
-            awaitLatch(availableLatch, 10 * CONNECT_TIME_LIMIT_MS);
+            await(availableLatch, 10 * CONNECT_TIME_LIMIT_MS);
         });
         Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms",
                 NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS,
@@ -3509,7 +3300,7 @@
         mWiFiNetworkAgent.connect(false);
 
         long onLostDispatchingDuration = durationOf(() -> {
-            awaitLatch(losingLatch, 10 * SWITCH_TIME_LIMIT_MS);
+            await(losingLatch, 10 * SWITCH_TIME_LIMIT_MS);
         });
         Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms",
                 NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration));
@@ -3517,33 +3308,13 @@
                 NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS),
                 onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS);
 
-        assertTimeLimit("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> {
+        assertRunsInAtMost("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> {
             for (NetworkCallback cb : callbacks) {
                 mCm.unregisterNetworkCallback(cb);
             }
         });
     }
 
-    private long durationOf(Runnable fn) {
-        long startTime = SystemClock.elapsedRealtime();
-        fn.run();
-        return SystemClock.elapsedRealtime() - startTime;
-    }
-
-    private void assertTimeLimit(String descr, long timeLimit, Runnable fn) {
-        long timeTaken = durationOf(fn);
-        String msg = String.format("%s: took %dms, limit was %dms", descr, timeTaken, timeLimit);
-        Log.d(TAG, msg);
-        assertTrue(msg, timeTaken <= timeLimit);
-    }
-
-    private boolean awaitLatch(CountDownLatch l, long timeoutMs) {
-        try {
-            return l.await(timeoutMs, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {}
-        return false;
-    }
-
     @Test
     public void testMobileDataAlwaysOn() throws Exception {
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
@@ -3602,7 +3373,7 @@
         testFactory.waitForNetworkRequests(1);
 
         // ...  and cell data to be torn down.
-        cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         assertLength(1, mCm.getAllNetworks());
 
         testFactory.unregister();
@@ -3693,7 +3464,7 @@
         mWiFiNetworkAgent.setNetworkInvalid();
         mCm.reportNetworkConnectivity(wifiNetwork, false);
         defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
-        validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        validatedWifiCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
         // Because avoid bad wifi is off, we don't switch to cellular.
         defaultCallback.assertNoCallback();
@@ -3737,7 +3508,7 @@
         mWiFiNetworkAgent.setNetworkInvalid();
         mCm.reportNetworkConnectivity(wifiNetwork, false);
         defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
-        validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        validatedWifiCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
         // Simulate the user selecting "switch" and checking the don't ask again checkbox.
         Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
@@ -3764,7 +3535,7 @@
 
         // If cell goes down, we switch to wifi.
         mCellNetworkAgent.disconnect();
-        defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         validatedWifiCallback.assertNoCallback();
 
@@ -3798,7 +3569,7 @@
      * time-out period expires.
      */
     @Test
-    public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
+    public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() throws Exception {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
         final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3818,7 +3589,7 @@
      * not trigger onUnavailable() once the time-out period expires.
      */
     @Test
-    public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() {
+    public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() throws Exception {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
         final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3829,7 +3600,7 @@
         networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
                 TEST_CALLBACK_TIMEOUT_MS);
         mWiFiNetworkAgent.disconnect();
-        networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
 
         // Validate that UNAVAILABLE is not called
         networkCallback.assertNoCallback();
@@ -3841,7 +3612,7 @@
      * (somehow) satisfied - the callback isn't called later.
      */
     @Test
-    public void testTimedoutNetworkRequest() {
+    public void testTimedoutNetworkRequest() throws Exception {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
         final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3849,7 +3620,7 @@
         mCm.requestNetwork(nr, networkCallback, timeoutMs);
 
         // pass timeout and validate that UNAVAILABLE is called
-        networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
+        networkCallback.expectCallback(CallbackRecord.UNAVAILABLE, null);
 
         // create a network satisfying request - validate that request not triggered
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -3862,7 +3633,7 @@
      * trigger the callback.
      */
     @Test
-    public void testNoCallbackAfterUnregisteredNetworkRequest() {
+    public void testNoCallbackAfterUnregisteredNetworkRequest() throws Exception {
         NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
                 NetworkCapabilities.TRANSPORT_WIFI).build();
         final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -3940,7 +3711,7 @@
             // Simulate the factory releasing the request as unfulfillable and expect onUnavailable!
             testFactory.triggerUnfulfillable(requests.get(newRequestId));
 
-            networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
+            networkCallback.expectCallback(CallbackRecord.UNAVAILABLE, null);
             testFactory.waitForRequests();
 
             // unregister network callback - a no-op (since already freed by the
@@ -3954,7 +3725,7 @@
 
     private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
 
-        public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
+        public enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR }
 
         private class CallbackValue {
             public CallbackType callbackType;
@@ -4002,25 +3773,19 @@
             mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
         }
 
-        private void expectCallback(CallbackValue callbackValue) {
-            try {
-                assertEquals(
-                        callbackValue,
-                        mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            } catch (InterruptedException e) {
-                fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
-            }
+        private void expectCallback(CallbackValue callbackValue) throws InterruptedException {
+            assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         }
 
-        public void expectStarted() {
+        public void expectStarted() throws Exception {
             expectCallback(new CallbackValue(CallbackType.ON_STARTED));
         }
 
-        public void expectStopped() {
+        public void expectStopped() throws Exception {
             expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
         }
 
-        public void expectError(int error) {
+        public void expectError(int error) throws Exception {
             expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
         }
     }
@@ -4081,36 +3846,31 @@
             mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
         }
 
-        private void expectCallback(CallbackValue callbackValue) {
-            try {
-                assertEquals(
-                        callbackValue,
-                        mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-            } catch (InterruptedException e) {
-                fail(callbackValue.callbackType + " callback not seen after " + TIMEOUT_MS + " ms");
-            }
+        private void expectCallback(CallbackValue callbackValue) throws InterruptedException {
+            assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
         }
 
-        public void expectStarted() {
+        public void expectStarted() throws InterruptedException {
             expectCallback(new CallbackValue(CallbackType.ON_STARTED));
         }
 
-        public void expectStopped() {
+        public void expectStopped() throws InterruptedException {
             expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
         }
 
-        public void expectError(int error) {
+        public void expectError(int error) throws InterruptedException {
             expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
         }
 
         public void assertNoCallback() {
-            HandlerUtilsKt.waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS);
+            waitForIdleSerialExecutor(mExecutor, TIMEOUT_MS);
             CallbackValue cv = mCallbacks.peek();
             assertNull("Unexpected callback: " + cv, cv);
         }
     }
 
-    private Network connectKeepaliveNetwork(LinkProperties lp) {
+    private Network connectKeepaliveNetwork(LinkProperties lp) throws Exception {
         // Ensure the network is disconnected before we do anything.
         if (mWiFiNetworkAgent != null) {
             assertNull(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()));
@@ -4243,13 +4003,9 @@
         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(ThrowingConsumer<Executor> functor) throws Exception {
+    private void runTestWithSerialExecutors(ExceptionUtils.ThrowingConsumer<Executor> functor)
+            throws Exception {
         final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor();
         final Executor executorInline = (Runnable r) -> r.run();
         functor.accept(executorSingleThread);
@@ -4567,7 +4323,7 @@
     private static boolean isUdpPortInUse(int port) {
         try (DatagramSocket ignored = new DatagramSocket(port)) {
             return false;
-        } catch (IOException ignored) {
+        } catch (IOException alreadyInUse) {
             return true;
         }
     }
@@ -4579,23 +4335,19 @@
     }
 
     private static class TestNetworkPinner extends NetworkPinner {
-        public static boolean awaitPin(int timeoutMs) {
+        public static boolean awaitPin(int timeoutMs) throws InterruptedException {
             synchronized(sLock) {
                 if (sNetwork == null) {
-                    try {
-                        sLock.wait(timeoutMs);
-                    } catch (InterruptedException e) {}
+                    sLock.wait(timeoutMs);
                 }
                 return sNetwork != null;
             }
         }
 
-        public static boolean awaitUnpin(int timeoutMs) {
+        public static boolean awaitUnpin(int timeoutMs) throws InterruptedException {
             synchronized(sLock) {
                 if (sNetwork != null) {
-                    try {
-                        sLock.wait(timeoutMs);
-                    } catch (InterruptedException e) {}
+                    sLock.wait(timeoutMs);
                 }
                 return sNetwork == null;
             }
@@ -4618,7 +4370,7 @@
     }
 
     @Test
-    public void testNetworkPinner() {
+    public void testNetworkPinner() throws Exception {
         NetworkRequest wifiRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_WIFI)
                 .build();
@@ -4713,25 +4465,20 @@
         }
 
         // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
-        try {
-            mCm.requestNetwork(networkRequest, new NetworkCallback());
-            fail("Registering " + MAX_REQUESTS + " network requests did not throw exception");
-        } catch (TooManyRequestsException expected) {}
-        try {
-            mCm.registerNetworkCallback(networkRequest, new NetworkCallback());
-            fail("Registering " + MAX_REQUESTS + " network callbacks did not throw exception");
-        } catch (TooManyRequestsException expected) {}
-        try {
-            mCm.requestNetwork(networkRequest,
-                PendingIntent.getBroadcast(mContext, 0, new Intent("c"), 0));
-            fail("Registering " + MAX_REQUESTS + " PendingIntent requests did not throw exception");
-        } catch (TooManyRequestsException expected) {}
-        try {
-            mCm.registerNetworkCallback(networkRequest,
-                PendingIntent.getBroadcast(mContext, 0, new Intent("d"), 0));
-            fail("Registering " + MAX_REQUESTS
-                    + " PendingIntent callbacks did not throw exception");
-        } catch (TooManyRequestsException expected) {}
+        assertThrows(TooManyRequestsException.class, () ->
+                mCm.requestNetwork(networkRequest, new NetworkCallback())
+        );
+        assertThrows(TooManyRequestsException.class, () ->
+                mCm.registerNetworkCallback(networkRequest, new NetworkCallback())
+        );
+        assertThrows(TooManyRequestsException.class, () ->
+                mCm.requestNetwork(networkRequest,
+                        PendingIntent.getBroadcast(mContext, 0, new Intent("c"), 0))
+        );
+        assertThrows(TooManyRequestsException.class, () ->
+                mCm.registerNetworkCallback(networkRequest,
+                        PendingIntent.getBroadcast(mContext, 0, new Intent("d"), 0))
+        );
 
         for (Object o : registered) {
             if (o instanceof NetworkCallback) {
@@ -4775,7 +4522,7 @@
     }
 
     @Test
-    public void testNetworkInfoOfTypeNone() {
+    public void testNetworkInfoOfTypeNone() throws Exception {
         ConditionVariable broadcastCV = waitForConnectivityBroadcasts(1);
 
         verifyNoNetwork();
@@ -4805,7 +4552,7 @@
 
         // Disconnect wifi aware network.
         wifiAware.disconnect();
-        callback.expectCallbackLike((info) -> info.state == CallbackState.LOST, TIMEOUT_MS);
+        callback.expectCallbackThat(TIMEOUT_MS, (info) -> info instanceof CallbackRecord.Lost);
         mCm.unregisterNetworkCallback(callback);
 
         verifyNoNetwork();
@@ -4822,21 +4569,21 @@
         assertNull(mCm.getLinkProperties(TYPE_NONE));
         assertFalse(mCm.isNetworkSupported(TYPE_NONE));
 
-        assertException(() -> { mCm.networkCapabilitiesForType(TYPE_NONE); },
-                IllegalArgumentException.class);
+        assertThrows(IllegalArgumentException.class,
+                () -> { mCm.networkCapabilitiesForType(TYPE_NONE); });
 
         Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class;
-        assertException(() -> { mCm.startUsingNetworkFeature(TYPE_WIFI, ""); }, unsupported);
-        assertException(() -> { mCm.stopUsingNetworkFeature(TYPE_WIFI, ""); }, unsupported);
+        assertThrows(unsupported, () -> { mCm.startUsingNetworkFeature(TYPE_WIFI, ""); });
+        assertThrows(unsupported, () -> { mCm.stopUsingNetworkFeature(TYPE_WIFI, ""); });
         // TODO: let test context have configuration application target sdk version
         // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED
-        assertException(() -> { mCm.startUsingNetworkFeature(TYPE_NONE, ""); }, unsupported);
-        assertException(() -> { mCm.stopUsingNetworkFeature(TYPE_NONE, ""); }, unsupported);
-        assertException(() -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); }, unsupported);
+        assertThrows(unsupported, () -> { mCm.startUsingNetworkFeature(TYPE_NONE, ""); });
+        assertThrows(unsupported, () -> { mCm.stopUsingNetworkFeature(TYPE_NONE, ""); });
+        assertThrows(unsupported, () -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); });
     }
 
     @Test
-    public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() {
+    public void testLinkPropertiesEnsuresDirectlyConnectedRoutes() throws Exception {
         final NetworkRequest networkRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_WIFI).build();
         final TestNetworkCallback networkCallback = new TestNetworkCallback();
@@ -4854,14 +4601,15 @@
         // ConnectivityService.
         MockNetworkAgent networkAgent = new MockNetworkAgent(TRANSPORT_WIFI, lp);
         networkAgent.connect(true);
-        networkCallback.expectCallback(CallbackState.AVAILABLE, networkAgent);
-        networkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, networkAgent);
-        CallbackInfo cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+        networkCallback.expectCallback(CallbackRecord.AVAILABLE, networkAgent);
+        networkCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, networkAgent);
+        CallbackRecord.LinkPropertiesChanged cbi =
+                networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
                 networkAgent);
-        networkCallback.expectCallback(CallbackState.BLOCKED_STATUS, networkAgent);
+        networkCallback.expectCallback(CallbackRecord.BLOCKED_STATUS, networkAgent);
         networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
         networkCallback.assertNoCallback();
-        checkDirectlyConnectedRoutes(cbi.arg, Arrays.asList(myIpv4Address),
+        checkDirectlyConnectedRoutes(cbi.getLp(), Arrays.asList(myIpv4Address),
                 Arrays.asList(myIpv4DefaultRoute));
         checkDirectlyConnectedRoutes(mCm.getLinkProperties(networkAgent.getNetwork()),
                 Arrays.asList(myIpv4Address), Arrays.asList(myIpv4DefaultRoute));
@@ -4873,9 +4621,9 @@
         newLp.addLinkAddress(myIpv6Address1);
         newLp.addLinkAddress(myIpv6Address2);
         networkAgent.sendLinkProperties(newLp);
-        cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, networkAgent);
+        cbi = networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, networkAgent);
         networkCallback.assertNoCallback();
-        checkDirectlyConnectedRoutes(cbi.arg,
+        checkDirectlyConnectedRoutes(cbi.getLp(),
                 Arrays.asList(myIpv4Address, myIpv6Address1, myIpv6Address2),
                 Arrays.asList(myIpv4DefaultRoute));
         mCm.unregisterNetworkCallback(networkCallback);
@@ -4899,11 +4647,8 @@
         mCellNetworkAgent.sendLinkProperties(cellLp);
         waitForIdle();
         verify(mStatsService, atLeastOnce())
-                .forceUpdateIfaces(
-                        eq(onlyCell),
-                        eq(new VpnInfo[0]),
-                        any(NetworkState[].class),
-                        eq(MOBILE_IFNAME));
+                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+                        eq(new VpnInfo[0]));
         reset(mStatsService);
 
         // Default network switch should update ifaces.
@@ -4912,65 +4657,47 @@
         waitForIdle();
         assertEquals(wifiLp, mService.getActiveLinkProperties());
         verify(mStatsService, atLeastOnce())
-                .forceUpdateIfaces(
-                        eq(onlyWifi),
-                        eq(new VpnInfo[0]),
-                        any(NetworkState[].class),
-                        eq(WIFI_IFNAME));
+                .forceUpdateIfaces(eq(onlyWifi), any(NetworkState[].class), eq(WIFI_IFNAME),
+                        eq(new VpnInfo[0]));
         reset(mStatsService);
 
         // Disconnect should update ifaces.
         mWiFiNetworkAgent.disconnect();
         waitForIdle();
         verify(mStatsService, atLeastOnce())
-                .forceUpdateIfaces(
-                        eq(onlyCell),
-                        eq(new VpnInfo[0]),
-                        any(NetworkState[].class),
-                        eq(MOBILE_IFNAME));
+                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class),
+                        eq(MOBILE_IFNAME), eq(new VpnInfo[0]));
         reset(mStatsService);
 
         // Metered change should update ifaces
         mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
         waitForIdle();
         verify(mStatsService, atLeastOnce())
-                .forceUpdateIfaces(
-                        eq(onlyCell),
-                        eq(new VpnInfo[0]),
-                        any(NetworkState[].class),
-                        eq(MOBILE_IFNAME));
+                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+                        eq(new VpnInfo[0]));
         reset(mStatsService);
 
         mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
         waitForIdle();
         verify(mStatsService, atLeastOnce())
-                .forceUpdateIfaces(
-                        eq(onlyCell),
-                        eq(new VpnInfo[0]),
-                        any(NetworkState[].class),
-                        eq(MOBILE_IFNAME));
+                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+                        eq(new VpnInfo[0]));
         reset(mStatsService);
 
         // Captive portal change shouldn't update ifaces
         mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
         waitForIdle();
         verify(mStatsService, never())
-                .forceUpdateIfaces(
-                        eq(onlyCell),
-                        eq(new VpnInfo[0]),
-                        any(NetworkState[].class),
-                        eq(MOBILE_IFNAME));
+                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+                        eq(new VpnInfo[0]));
         reset(mStatsService);
 
         // Roaming change should update ifaces
         mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
         waitForIdle();
         verify(mStatsService, atLeastOnce())
-                .forceUpdateIfaces(
-                        eq(onlyCell),
-                        eq(new VpnInfo[0]),
-                        any(NetworkState[].class),
-                        eq(MOBILE_IFNAME));
+                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
+                        eq(new VpnInfo[0]));
         reset(mStatsService);
     }
 
@@ -5094,21 +4821,21 @@
         ResolverParamsParcel resolvrParams = mResolverParamsParcelCaptor.getValue();
         assertEquals(2, resolvrParams.tlsServers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         // Opportunistic mode.
         assertEquals(2, resolvrParams.tlsServers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         reset(mMockDnsResolver);
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
+        cellNetworkCallback.expectCallback(CallbackRecord.AVAILABLE, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED,
                 mCellNetworkAgent);
-        CallbackInfo cbi = cellNetworkCallback.expectCallback(
-                CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.BLOCKED_STATUS, mCellNetworkAgent);
+        CallbackRecord.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback(
+                CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.BLOCKED_STATUS, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
-        assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
-        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        assertFalse(cbi.getLp().isPrivateDnsActive());
+        assertNull(cbi.getLp().getPrivateDnsServerName());
 
         setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
         verify(mMockDnsResolver, times(1)).setResolverConfiguration(
@@ -5116,7 +4843,7 @@
         resolvrParams = mResolverParamsParcelCaptor.getValue();
         assertEquals(2, resolvrParams.servers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         reset(mMockDnsResolver);
         cellNetworkCallback.assertNoCallback();
 
@@ -5126,21 +4853,21 @@
         resolvrParams = mResolverParamsParcelCaptor.getValue();
         assertEquals(2, resolvrParams.servers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.servers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         assertEquals(2, resolvrParams.tlsServers.length);
         assertTrue(ArrayUtils.containsAll(resolvrParams.tlsServers,
-                new String[]{"2001:db8::1", "192.0.2.1"}));
+                new String[] { "2001:db8::1", "192.0.2.1" }));
         reset(mMockDnsResolver);
         cellNetworkCallback.assertNoCallback();
 
         setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com");
         // Can't test dns configuration for strict mode without properly mocking
         // out the DNS lookups, but can test that LinkProperties is updated.
-        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+        cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
                 mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
-        assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
-        assertEquals("strict.example.com", ((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        assertTrue(cbi.getLp().isPrivateDnsActive());
+        assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName());
     }
 
     @Test
@@ -5159,17 +4886,17 @@
         mCellNetworkAgent.sendLinkProperties(lp);
         mCellNetworkAgent.connect(false);
         waitForIdle();
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
+        cellNetworkCallback.expectCallback(CallbackRecord.AVAILABLE, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED,
                 mCellNetworkAgent);
-        CallbackInfo cbi = cellNetworkCallback.expectCallback(
-                CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.BLOCKED_STATUS, mCellNetworkAgent);
+        CallbackRecord.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback(
+                CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackRecord.BLOCKED_STATUS, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
-        assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
-        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        assertFalse(cbi.getLp().isPrivateDnsActive());
+        assertNull(cbi.getLp().getPrivateDnsServerName());
         Set<InetAddress> dnsServers = new HashSet<>();
-        checkDnsServers(cbi.arg, dnsServers);
+        checkDnsServers(cbi.getLp(), dnsServers);
 
         // Send a validation event for a server that is not part of the current
         // resolver config. The validation event should be ignored.
@@ -5181,13 +4908,13 @@
         LinkProperties lp2 = new LinkProperties(lp);
         lp2.addDnsServer(InetAddress.getByName("145.100.185.16"));
         mCellNetworkAgent.sendLinkProperties(lp2);
-        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+        cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
                 mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
-        assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
-        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        assertFalse(cbi.getLp().isPrivateDnsActive());
+        assertNull(cbi.getLp().getPrivateDnsServerName());
         dnsServers.add(InetAddress.getByName("145.100.185.16"));
-        checkDnsServers(cbi.arg, dnsServers);
+        checkDnsServers(cbi.getLp(), dnsServers);
 
         // Send a validation event containing a hostname that is not part of
         // the current resolver config. The validation event should be ignored.
@@ -5205,39 +4932,39 @@
         // private dns fields should be sent.
         mService.mNetdEventCallback.onPrivateDnsValidationEvent(
                 mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true);
-        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+        cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
                 mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
-        assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
-        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
-        checkDnsServers(cbi.arg, dnsServers);
+        assertTrue(cbi.getLp().isPrivateDnsActive());
+        assertNull(cbi.getLp().getPrivateDnsServerName());
+        checkDnsServers(cbi.getLp(), dnsServers);
 
         // The private dns fields in LinkProperties should be preserved when
         // the network agent sends unrelated changes.
         LinkProperties lp3 = new LinkProperties(lp2);
         lp3.setMtu(1300);
         mCellNetworkAgent.sendLinkProperties(lp3);
-        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+        cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
                 mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
-        assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
-        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
-        checkDnsServers(cbi.arg, dnsServers);
-        assertEquals(1300, ((LinkProperties)cbi.arg).getMtu());
+        assertTrue(cbi.getLp().isPrivateDnsActive());
+        assertNull(cbi.getLp().getPrivateDnsServerName());
+        checkDnsServers(cbi.getLp(), dnsServers);
+        assertEquals(1300, cbi.getLp().getMtu());
 
         // Removing the only validated server should affect the private dns
         // fields in LinkProperties.
         LinkProperties lp4 = new LinkProperties(lp3);
         lp4.removeDnsServer(InetAddress.getByName("145.100.185.16"));
         mCellNetworkAgent.sendLinkProperties(lp4);
-        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+        cbi = cellNetworkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED,
                 mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
-        assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
-        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        assertFalse(cbi.getLp().isPrivateDnsActive());
+        assertNull(cbi.getLp().getPrivateDnsServerName());
         dnsServers.remove(InetAddress.getByName("145.100.185.16"));
-        checkDnsServers(cbi.arg, dnsServers);
-        assertEquals(1300, ((LinkProperties)cbi.arg).getMtu());
+        checkDnsServers(cbi.getLp(), dnsServers);
+        assertEquals(1300, cbi.getLp().getMtu());
     }
 
     private void checkDirectlyConnectedRoutes(Object callbackObj,
@@ -5264,31 +4991,8 @@
         assertTrue(lp.getDnsServers().containsAll(dnsServers));
     }
 
-    private static <T> void assertEmpty(T[] ts) {
-        int length = ts.length;
-        assertEquals("expected empty array, but length was " + length, 0, length);
-    }
-
-    private static <T> void assertLength(int expected, T[] got) {
-        int length = got.length;
-        assertEquals(String.format("expected array of length %s, but length was %s for %s",
-                expected, length, Arrays.toString(got)), expected, length);
-    }
-
-    private static <T> void assertException(Runnable block, Class<T> expected) {
-        try {
-            block.run();
-            fail("Expected exception of type " + expected);
-        } catch (Exception got) {
-            if (!got.getClass().equals(expected)) {
-                fail("Expected exception of type " + expected + " but got " + got);
-            }
-            return;
-        }
-    }
-
     @Test
-    public void testVpnNetworkActive() {
+    public void testVpnNetworkActive() throws Exception {
         final int uid = Process.myUid();
 
         final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
@@ -5342,19 +5046,19 @@
         defaultCallback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
-        genericNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
         genericNotVpnNetworkCallback.assertNoCallback();
-        vpnNetworkCallback.expectCapabilitiesLike(nc -> null == nc.getUids(), vpnNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent, nc -> null == nc.getUids());
+        defaultCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         ranges.clear();
         vpnNetworkAgent.setUids(ranges);
 
-        genericNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
         genericNotVpnNetworkCallback.assertNoCallback();
         wifiNetworkCallback.assertNoCallback();
-        vpnNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        vpnNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
 
         // TODO : The default network callback should actually get a LOST call here (also see the
         // comment below for AVAILABLE). This is because ConnectivityService does not look at UID
@@ -5362,7 +5066,7 @@
         // can't currently update their UIDs without disconnecting, so this does not matter too
         // much, but that is the reason the test here has to check for an update to the
         // capabilities instead of the expected LOST then AVAILABLE.
-        defaultCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
 
         ranges.add(new UidRange(uid, uid));
         mMockVpn.setUids(ranges);
@@ -5374,23 +5078,23 @@
         vpnNetworkCallback.expectAvailableCallbacksValidated(vpnNetworkAgent);
         // TODO : Here like above, AVAILABLE would be correct, but because this can't actually
         // happen outside of the test, ConnectivityService does not rematch callbacks.
-        defaultCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
 
         mWiFiNetworkAgent.disconnect();
 
-        genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        genericNotVpnNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        genericNotVpnNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
+        wifiNetworkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         vpnNetworkCallback.assertNoCallback();
         defaultCallback.assertNoCallback();
 
         vpnNetworkAgent.disconnect();
 
-        genericNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        genericNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
         genericNotVpnNetworkCallback.assertNoCallback();
         wifiNetworkCallback.assertNoCallback();
-        vpnNetworkCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        vpnNetworkCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
         assertEquals(null, mCm.getActiveNetwork());
 
         mCm.unregisterNetworkCallback(genericNetworkCallback);
@@ -5400,7 +5104,7 @@
     }
 
     @Test
-    public void testVpnWithoutInternet() {
+    public void testVpnWithoutInternet() throws Exception {
         final int uid = Process.myUid();
 
         final TestNetworkCallback defaultCallback = new TestNetworkCallback();
@@ -5430,7 +5134,7 @@
     }
 
     @Test
-    public void testVpnWithInternet() {
+    public void testVpnWithInternet() throws Exception {
         final int uid = Process.myUid();
 
         final TestNetworkCallback defaultCallback = new TestNetworkCallback();
@@ -5454,7 +5158,7 @@
         assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
 
         vpnNetworkAgent.disconnect();
-        defaultCallback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
         defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
 
         mCm.unregisterNetworkCallback(defaultCallback);
@@ -5484,7 +5188,7 @@
         // Even though the VPN is unvalidated, it becomes the default network for our app.
         callback.expectAvailableCallbacksUnvalidated(vpnNetworkAgent);
         // TODO: this looks like a spurious callback.
-        callback.expectCallback(CallbackState.NETWORK_CAPABILITIES, vpnNetworkAgent);
+        callback.expectCallback(CallbackRecord.NETWORK_CAPS_UPDATED, vpnNetworkAgent);
         callback.assertNoCallback();
 
         assertTrue(vpnNetworkAgent.getScore() > mEthernetNetworkAgent.getScore());
@@ -5508,12 +5212,12 @@
         callback.assertNoCallback();
 
         vpnNetworkAgent.disconnect();
-        callback.expectCallback(CallbackState.LOST, vpnNetworkAgent);
+        callback.expectCallback(CallbackRecord.LOST, vpnNetworkAgent);
         callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent);
     }
 
     @Test
-    public void testVpnSetUnderlyingNetworks() {
+    public void testVpnSetUnderlyingNetworks() throws Exception {
         final int uid = Process.myUid();
 
         final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
@@ -5548,10 +5252,10 @@
         mService.setUnderlyingNetworksForVpn(
                 new Network[] { mCellNetworkAgent.getNetwork() });
 
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
-                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
@@ -5560,58 +5264,58 @@
         mService.setUnderlyingNetworksForVpn(
                 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
 
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
-                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         // Don't disconnect, but note the VPN is not using wifi any more.
         mService.setUnderlyingNetworksForVpn(
                 new Network[] { mCellNetworkAgent.getNetwork() });
 
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
-                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         // Use Wifi but not cell. Note the VPN is now unmetered.
         mService.setUnderlyingNetworksForVpn(
                 new Network[] { mWiFiNetworkAgent.getNetwork() });
 
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
-                && caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         // Use both again.
         mService.setUnderlyingNetworksForVpn(
                 new Network[] { mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork() });
 
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
-                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         // Disconnect cell. Receive update without even removing the dead network from the
         // underlying networks – it's dead anyway. Not metered any more.
         mCellNetworkAgent.disconnect();
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
-                && caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         // Disconnect wifi too. No underlying networks means this is now metered.
         mWiFiNetworkAgent.disconnect();
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
-                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         mMockVpn.disconnect();
     }
 
     @Test
-    public void testNullUnderlyingNetworks() {
+    public void testNullUnderlyingNetworks() throws Exception {
         final int uid = Process.myUid();
 
         final TestNetworkCallback vpnNetworkCallback = new TestNetworkCallback();
@@ -5644,20 +5348,20 @@
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
 
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
-                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         // Connect to WiFi; WiFi is the new default.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
         mWiFiNetworkAgent.connect(true);
 
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && !caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
-                && caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         // Disconnect Cell. The default network did not change, so there shouldn't be any changes in
         // the capabilities.
@@ -5666,16 +5370,16 @@
         // Disconnect wifi too. Now we have no default network.
         mWiFiNetworkAgent.disconnect();
 
-        vpnNetworkCallback.expectCapabilitiesLike((caps) -> caps.hasTransport(TRANSPORT_VPN)
+        vpnNetworkCallback.expectCapabilitiesThat(vpnNetworkAgent,
+                (caps) -> caps.hasTransport(TRANSPORT_VPN)
                 && !caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
-                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED),
-                vpnNetworkAgent);
+                && !caps.hasCapability(NET_CAPABILITY_NOT_METERED));
 
         mMockVpn.disconnect();
     }
 
     @Test
-    public void testIsActiveNetworkMeteredOverWifi() {
+    public void testIsActiveNetworkMeteredOverWifi() throws Exception {
         // Returns true by default when no network is available.
         assertTrue(mCm.isActiveNetworkMetered());
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -5687,7 +5391,7 @@
     }
 
     @Test
-    public void testIsActiveNetworkMeteredOverCell() {
+    public void testIsActiveNetworkMeteredOverCell() throws Exception {
         // Returns true by default when no network is available.
         assertTrue(mCm.isActiveNetworkMetered());
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -5699,7 +5403,7 @@
     }
 
     @Test
-    public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() {
+    public void testIsActiveNetworkMeteredOverVpnTrackingPlatformDefault() throws Exception {
         // Returns true by default when no network is available.
         assertTrue(mCm.isActiveNetworkMetered());
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -5753,7 +5457,7 @@
     }
 
    @Test
-   public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() {
+   public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception {
         // Returns true by default when no network is available.
         assertTrue(mCm.isActiveNetworkMetered());
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -5824,7 +5528,7 @@
     }
 
     @Test
-    public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() {
+    public void testIsActiveNetworkMeteredOverAlwaysMeteredVpn() throws Exception {
         // Returns true by default when no network is available.
         assertTrue(mCm.isActiveNetworkMetered());
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -5871,7 +5575,7 @@
     }
 
     @Test
-    public void testNetworkBlockedStatus() {
+    public void testNetworkBlockedStatus() throws Exception {
         final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
         final NetworkRequest cellRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_CELLULAR)
@@ -5922,7 +5626,7 @@
     }
 
     @Test
-    public void testNetworkBlockedStatusBeforeAndAfterConnect() {
+    public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception {
         final TestNetworkCallback defaultCallback = new TestNetworkCallback();
         mCm.registerDefaultNetworkCallback(defaultCallback);
 
@@ -5945,7 +5649,7 @@
 
         // Switch to METERED network. Restrict the use of the network.
         mWiFiNetworkAgent.disconnect();
-        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent);
 
         // Network becomes NOT_METERED.
@@ -5959,7 +5663,7 @@
         defaultCallback.assertNoCallback();
 
         mCellNetworkAgent.disconnect();
-        defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        defaultCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         defaultCallback.assertNoCallback();
 
         mCm.unregisterNetworkCallback(defaultCallback);
@@ -5991,7 +5695,7 @@
     }
 
     @Test
-    public void testStackedLinkProperties() throws UnknownHostException, RemoteException {
+    public void testStackedLinkProperties() throws Exception {
         final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24");
         final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64");
         final String kNat64PrefixString = "2001:db8:64:64:64:64::";
@@ -6035,7 +5739,7 @@
         // the NAT64 prefix was removed because one was never discovered.
         cellLp.addLinkAddress(myIpv4);
         mCellNetworkAgent.sendLinkProperties(cellLp);
-        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
         verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
         verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
 
@@ -6048,7 +5752,7 @@
         cellLp.removeLinkAddress(myIpv4);
         cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
         mCellNetworkAgent.sendLinkProperties(cellLp);
-        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
         verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
 
         // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
@@ -6056,15 +5760,15 @@
         assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix());
         mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
                 kNat64PrefixString, 96);
-        LinkProperties lpBeforeClat = (LinkProperties) networkCallback.expectCallback(
-                CallbackState.LINK_PROPERTIES, mCellNetworkAgent).arg;
+        LinkProperties lpBeforeClat = networkCallback.expectCallback(
+                CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp();
         assertEquals(0, lpBeforeClat.getStackedLinks().size());
         assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix());
         verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString());
 
         // Clat iface comes up. Expect stacked link to be added.
         clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
-        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
         List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork())
                 .getStackedLinks();
         assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0));
@@ -6072,7 +5776,7 @@
         // Change trivial linkproperties and see if stacked link is preserved.
         cellLp.addDnsServer(InetAddress.getByName("8.8.8.8"));
         mCellNetworkAgent.sendLinkProperties(cellLp);
-        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
 
         List<LinkProperties> stackedLpsAfterChange =
                 mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getStackedLinks();
@@ -6090,12 +5794,12 @@
         cellLp.addLinkAddress(myIpv4);
         cellLp.addRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
         mCellNetworkAgent.sendLinkProperties(cellLp);
-        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
         verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
         verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
 
         // As soon as stop is called, the linkproperties lose the stacked interface.
-        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
         LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork());
         LinkProperties expected = new LinkProperties(cellLp);
         expected.setNat64Prefix(kNat64Prefix);
@@ -6114,47 +5818,45 @@
         // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
         mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
                 kNat64PrefixString, 96);
-        networkCallback.expectLinkPropertiesLike((lp) -> lp.getNat64Prefix() == null,
-                mCellNetworkAgent);
+        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
+                (lp) -> lp.getNat64Prefix() == null);
 
         // Remove IPv4 address and expect prefix discovery and clatd to be started again.
         cellLp.removeLinkAddress(myIpv4);
         cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
         cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8"));
         mCellNetworkAgent.sendLinkProperties(cellLp);
-        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
         verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
         mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
                 kNat64PrefixString, 96);
-        networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
         verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString());
 
 
         // Clat iface comes up. Expect stacked link to be added.
         clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
-        networkCallback.expectLinkPropertiesLike(
-                (lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null,
-                mCellNetworkAgent);
+        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
+                (lp) -> lp.getStackedLinks().size() == 1 && lp.getNat64Prefix() != null);
 
         // NAT64 prefix is removed. Expect that clat is stopped.
         mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
                 kNat64PrefixString, 96);
-        networkCallback.expectLinkPropertiesLike(
-                (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null,
-                mCellNetworkAgent);
+        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
+                (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null);
         verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
-        networkCallback.expectLinkPropertiesLike((lp) -> lp.getStackedLinks().size() == 0,
-                mCellNetworkAgent);
+        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
+                (lp) -> lp.getStackedLinks().size() == 0);
 
         // Clean up.
         mCellNetworkAgent.disconnect();
-        networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         networkCallback.assertNoCallback();
         mCm.unregisterNetworkCallback(networkCallback);
     }
 
     @Test
-    public void testDataActivityTracking() throws RemoteException {
+    public void testDataActivityTracking() throws Exception {
         final TestNetworkCallback networkCallback = new TestNetworkCallback();
         final NetworkRequest networkRequest = new NetworkRequest.Builder()
                 .addCapability(NET_CAPABILITY_INTERNET)
@@ -6180,7 +5882,7 @@
         reset(mNetworkManagementService);
         mWiFiNetworkAgent.connect(true);
         networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
                 eq(ConnectivityManager.TYPE_WIFI));
@@ -6189,7 +5891,7 @@
         // Disconnect wifi and switch back to cell
         reset(mNetworkManagementService);
         mWiFiNetworkAgent.disconnect();
-        networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LOST, mWiFiNetworkAgent);
         assertNoCallbacks(networkCallback);
         verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
         verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
@@ -6201,14 +5903,14 @@
         mWiFiNetworkAgent.sendLinkProperties(wifiLp);
         mWiFiNetworkAgent.connect(true);
         networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LOSING, mCellNetworkAgent);
         networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
 
         // Disconnect cell
         reset(mNetworkManagementService);
         reset(mMockNetd);
         mCellNetworkAgent.disconnect();
-        networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        networkCallback.expectCallback(CallbackRecord.LOST, mCellNetworkAgent);
         // LOST callback is triggered earlier than removing idle timer. Broadcast should also be
         // sent as network being switched. Ensure rule removal for cell will not be triggered
         // unexpectedly before network being removed.
@@ -6229,21 +5931,17 @@
         mCm.unregisterNetworkCallback(networkCallback);
     }
 
-    private void verifyTcpBufferSizeChange(String tcpBufferSizes) {
+    private void verifyTcpBufferSizeChange(String tcpBufferSizes) throws Exception {
         String[] values = tcpBufferSizes.split(",");
         String rmemValues = String.join(" ", values[0], values[1], values[2]);
         String wmemValues = String.join(" ", values[3], values[4], values[5]);
         waitForIdle();
-        try {
-            verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues);
-        } catch (RemoteException e) {
-            fail("mMockNetd should never throw RemoteException");
-        }
+        verify(mMockNetd, atLeastOnce()).setTcpRWmemorySize(rmemValues, wmemValues);
         reset(mMockNetd);
     }
 
     @Test
-    public void testTcpBufferReset() {
+    public void testTcpBufferReset() throws Exception {
         final String testTcpBufferSizes = "1,2,3,4,5,6";
 
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -6260,7 +5958,7 @@
     }
 
     @Test
-    public void testGetGlobalProxyForNetwork() {
+    public void testGetGlobalProxyForNetwork() throws Exception {
         final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888);
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         final Network wifiNetwork = mWiFiNetworkAgent.getNetwork();
@@ -6269,7 +5967,7 @@
     }
 
     @Test
-    public void testGetProxyForActiveNetwork() {
+    public void testGetProxyForActiveNetwork() throws Exception {
         final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888);
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
@@ -6286,7 +5984,7 @@
     }
 
     @Test
-    public void testGetProxyForVPN() {
+    public void testGetProxyForVPN() throws Exception {
         final ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("test", 8888);
 
         // Set up a WiFi network with no proxy
@@ -6472,7 +6170,7 @@
 
 
     private MockNetworkAgent establishVpn(LinkProperties lp, int establishingUid,
-            Set<UidRange> vpnRange) {
+            Set<UidRange> vpnRange) throws Exception {
         final MockNetworkAgent vpnNetworkAgent = new MockNetworkAgent(TRANSPORT_VPN, lp);
         vpnNetworkAgent.getNetworkCapabilities().setEstablishingVpnAppUid(establishingUid);
         mMockVpn.setNetworkAgent(vpnNetworkAgent);
@@ -6483,14 +6181,6 @@
         return vpnNetworkAgent;
     }
 
-    private void assertContainsExactly(int[] actual, int... expected) {
-        int[] sortedActual = Arrays.copyOf(actual, actual.length);
-        int[] sortedExpected = Arrays.copyOf(expected, expected.length);
-        Arrays.sort(sortedActual);
-        Arrays.sort(sortedExpected);
-        assertArrayEquals(sortedExpected, sortedActual);
-    }
-
     private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid) {
         final PackageInfo packageInfo = new PackageInfo();
         packageInfo.requestedPermissions = new String[0];
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index e4117b8..aef9386 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -19,8 +19,9 @@
 import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
 import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
 
+import static com.android.testutils.MiscAssertsKt.assertStringContains;
+
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -111,15 +112,15 @@
         String[] events2 = remove(listNetdEvent(), baseline);
         int expectedLength2 = uids.length + 1; // +1 for the WakeupStats line
         assertEquals(expectedLength2, events2.length);
-        assertContains(events2[0], "WakeupStats");
-        assertContains(events2[0], "wlan0");
-        assertContains(events2[0], "0x800");
-        assertContains(events2[0], "0x86dd");
+        assertStringContains(events2[0], "WakeupStats");
+        assertStringContains(events2[0], "wlan0");
+        assertStringContains(events2[0], "0x800");
+        assertStringContains(events2[0], "0x86dd");
         for (int i = 0; i < uids.length; i++) {
             String got = events2[i+1];
-            assertContains(got, "WakeupEvent");
-            assertContains(got, "wlan0");
-            assertContains(got, "uid: " + uids[i]);
+            assertStringContains(got, "WakeupEvent");
+            assertStringContains(got, "wlan0");
+            assertStringContains(got, "uid: " + uids[i]);
         }
 
         int uid = 20000;
@@ -131,13 +132,13 @@
         String[] events3 = remove(listNetdEvent(), baseline);
         int expectedLength3 = BUFFER_LENGTH + 1; // +1 for the WakeupStats line
         assertEquals(expectedLength3, events3.length);
-        assertContains(events2[0], "WakeupStats");
-        assertContains(events2[0], "wlan0");
+        assertStringContains(events2[0], "WakeupStats");
+        assertStringContains(events2[0], "wlan0");
         for (int i = 1; i < expectedLength3; i++) {
             String got = events3[i];
-            assertContains(got, "WakeupEvent");
-            assertContains(got, "wlan0");
-            assertContains(got, "uid: " + uid);
+            assertStringContains(got, "WakeupEvent");
+            assertStringContains(got, "wlan0");
+            assertStringContains(got, "uid: " + uid);
         }
 
         uid = 45678;
@@ -145,9 +146,9 @@
 
         String[] events4 = remove(listNetdEvent(), baseline);
         String lastEvent = events4[events4.length - 1];
-        assertContains(lastEvent, "WakeupEvent");
-        assertContains(lastEvent, "wlan0");
-        assertContains(lastEvent, "uid: " + uid);
+        assertStringContains(lastEvent, "WakeupEvent");
+        assertStringContains(lastEvent, "wlan0");
+        assertStringContains(lastEvent, "uid: " + uid);
     }
 
     @Test
@@ -529,10 +530,6 @@
         return buffer.toString().split("\\n");
     }
 
-    static void assertContains(String got, String want) {
-        assertTrue(got + " did not contain \"" + want + "\"", got.contains(want));
-    }
-
     static <T> T[] remove(T[] array, T[] filtered) {
         List<T> c = Arrays.asList(filtered);
         int next = 0;
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 6c42ac3..8c522f4 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -100,6 +100,8 @@
 import android.os.test.TestLooper;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
 import android.test.mock.MockContentResolver;
 
 import androidx.test.filters.SmallTest;
@@ -111,6 +113,7 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
 import com.android.server.connectivity.tethering.OffloadHardwareInterface;
+import com.android.server.connectivity.tethering.TetheringConfiguration;
 import com.android.server.connectivity.tethering.TetheringDependencies;
 import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
 
@@ -118,6 +121,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;
 
@@ -147,6 +151,7 @@
     @Mock private MockableSystemProperties mSystemProperties;
     @Mock private OffloadHardwareInterface mOffloadHardwareInterface;
     @Mock private Resources mResources;
+    @Mock private TelephonyManager mTelephonyManager;
     @Mock private UsbManager mUsbManager;
     @Mock private WifiManager mWifiManager;
     @Mock private CarrierConfigManager mCarrierConfigManager;
@@ -171,6 +176,7 @@
     private MockContentResolver mContentResolver;
     private BroadcastReceiver mBroadcastReceiver;
     private Tethering mTethering;
+    private PhoneStateListener mPhoneStateListener;
 
     private class MockContext extends BroadcastInterceptingContext {
         MockContext(Context base) {
@@ -193,6 +199,7 @@
         public Object getSystemService(String name) {
             if (Context.WIFI_SERVICE.equals(name)) return mWifiManager;
             if (Context.USB_SERVICE.equals(name)) return mUsbManager;
+            if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
             return super.getSystemService(name);
         }
     }
@@ -234,6 +241,17 @@
         }
     }
 
+    private class MockTetheringConfiguration extends TetheringConfiguration {
+        MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
+            super(ctx, log, id);
+        }
+
+        @Override
+        protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
+            return mResources;
+        }
+    }
+
     public class MockTetheringDependencies extends TetheringDependencies {
         StateMachine upstreamNetworkMonitorMasterSM;
         ArrayList<IpServer> ipv6CoordinatorNotifyList;
@@ -276,8 +294,9 @@
         }
 
         @Override
-        public int getDefaultDataSubscriptionId() {
-            return INVALID_SUBSCRIPTION_ID;
+        public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log,
+                int subId) {
+            return new MockTetheringConfiguration(ctx, log, subId);
         }
     }
 
@@ -372,6 +391,11 @@
         mTetheringDependencies.reset();
         mTethering = makeTethering();
         verify(mNMService).registerTetheringStatsProvider(any(), anyString());
+        final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
+                ArgumentCaptor.forClass(PhoneStateListener.class);
+        verify(mTelephonyManager).listen(phoneListenerCaptor.capture(),
+                eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE));
+        mPhoneStateListener = phoneListenerCaptor.getValue();
     }
 
     private Tethering makeTethering() {
@@ -982,6 +1006,17 @@
         callback2.expectUpstreamChanged(upstreamState.network);
     }
 
+    @Test
+    public void testMultiSimAware() throws Exception {
+        final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration();
+        assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.subId);
+
+        final int fakeSubId = 1234;
+        mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId);
+        final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration();
+        assertEquals(fakeSubId, newConfig.subId);
+    }
+
     // TODO: Test that a request for hotspot mode doesn't interfere with an
     // already operating tethering mode interface.
 }
diff --git a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
index 762b76c..9931aec 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/OffloadControllerTest.java
@@ -25,6 +25,7 @@
 import static android.provider.Settings.Global.TETHER_OFFLOAD_DISABLED;
 
 import static com.android.server.connectivity.tethering.OffloadHardwareInterface.ForwardedStats;
+import static com.android.testutils.MiscAssertsKt.assertContainsAll;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -244,7 +245,7 @@
         inOrder.verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
         ArrayList<String> localPrefixes = mStringArrayCaptor.getValue();
         assertEquals(4, localPrefixes.size());
-        assertArrayListContains(localPrefixes,
+        assertContainsAll(localPrefixes,
                 "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64");
         inOrder.verifyNoMoreInteractions();
 
@@ -360,7 +361,7 @@
         inOrder.verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
         localPrefixes = mStringArrayCaptor.getValue();
         assertEquals(6, localPrefixes.size());
-        assertArrayListContains(localPrefixes,
+        assertContainsAll(localPrefixes,
                 "127.0.0.0/8", "192.0.2.0/24", "fe80::/64", "2001:db8::/64",
                 "2001:db8::6173:7369:676e:6564/128", "2001:db8::7261:6e64:6f6d/128");
         // The relevant parts of the LinkProperties have not changed, but at the
@@ -717,7 +718,7 @@
         verify(mHardware, times(1)).setLocalPrefixes(mStringArrayCaptor.capture());
         ArrayList<String> localPrefixes = mStringArrayCaptor.getValue();
         assertEquals(4, localPrefixes.size());
-        assertArrayListContains(localPrefixes,
+        assertContainsAll(localPrefixes,
                 // TODO: The logic to find and exclude downstream IP prefixes
                 // is currently in Tethering's OffloadWrapper but must be moved
                 // into OffloadController proper. After this, also check for:
@@ -730,9 +731,4 @@
         verifyNoMoreInteractions(mHardware);
     }
 
-    private static void assertArrayListContains(ArrayList<String> list, String... elems) {
-        for (String element : elems) {
-            assertTrue(element + " not in list", list.contains(element));
-        }
-    }
 }
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 2140322..e282963 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java
@@ -29,6 +29,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.when;
 
 import android.content.ContentResolver;
@@ -141,7 +142,7 @@
 
     @Test
     public void testDunFromTelephonyManagerMeansDun() {
-        when(mTelephonyManager.getTetherApnRequired()).thenReturn(true);
+        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(true);
 
         final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
         final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
@@ -165,7 +166,7 @@
 
     @Test
     public void testDunNotRequiredFromTelephonyManagerMeansNoDun() {
-        when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
+        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false);
 
         final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI);
         final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration(
@@ -208,7 +209,7 @@
     @Test
     public void testNoDefinedUpstreamTypesAddsEthernet() {
         when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{});
-        when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
+        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false);
 
         final TetheringConfiguration cfg = new TetheringConfiguration(
                 mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -231,7 +232,7 @@
     public void testDefinedUpstreamTypesSansEthernetAddsEthernet() {
         when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(
                 new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI});
-        when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
+        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false);
 
         final TetheringConfiguration cfg = new TetheringConfiguration(
                 mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -249,7 +250,7 @@
     public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() {
         when(mResources.getIntArray(config_tether_upstream_types))
                 .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI});
-        when(mTelephonyManager.getTetherApnRequired()).thenReturn(false);
+        when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false);
 
         final TetheringConfiguration cfg = new TetheringConfiguration(
                 mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
new file mode 100644
index 0000000..28785f7
--- /dev/null
+++ b/tests/net/java/com/android/server/net/NetworkStatsBaseTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net;
+
+import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
+import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
+import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
+import static android.net.NetworkStats.METERED_ALL;
+import static android.net.NetworkStats.METERED_NO;
+import static android.net.NetworkStats.METERED_YES;
+import static android.net.NetworkStats.ROAMING_ALL;
+import static android.net.NetworkStats.ROAMING_NO;
+import static android.net.NetworkStats.ROAMING_YES;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.SET_FOREGROUND;
+import static android.net.NetworkStats.TAG_NONE;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.NetworkStats;
+
+import com.android.internal.net.VpnInfo;
+
+/** Superclass with utilities for NetworkStats(Service|Factory)Test */
+abstract class NetworkStatsBaseTest {
+    static final String TEST_IFACE = "test0";
+    static final String TEST_IFACE2 = "test1";
+    static final String TUN_IFACE = "test_nss_tun0";
+
+    static final int UID_RED = 1001;
+    static final int UID_BLUE = 1002;
+    static final int UID_GREEN = 1003;
+    static final int UID_VPN = 1004;
+
+    void assertValues(NetworkStats stats, String iface, int uid, long rxBytes,
+            long rxPackets, long txBytes, long txPackets) {
+        assertValues(
+                stats, iface, uid, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+                rxBytes, rxPackets, txBytes, txPackets, 0);
+    }
+
+    void assertValues(NetworkStats stats, String iface, int uid, int set, int tag,
+            int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
+            long txBytes, long txPackets, long operations) {
+        final NetworkStats.Entry entry = new NetworkStats.Entry();
+        final int[] sets;
+        if (set == SET_ALL) {
+            sets = new int[] {SET_ALL, SET_DEFAULT, SET_FOREGROUND};
+        } else {
+            sets = new int[] {set};
+        }
+
+        final int[] roamings;
+        if (roaming == ROAMING_ALL) {
+            roamings = new int[] {ROAMING_ALL, ROAMING_YES, ROAMING_NO};
+        } else {
+            roamings = new int[] {roaming};
+        }
+
+        final int[] meterings;
+        if (metered == METERED_ALL) {
+            meterings = new int[] {METERED_ALL, METERED_YES, METERED_NO};
+        } else {
+            meterings = new int[] {metered};
+        }
+
+        final int[] defaultNetworks;
+        if (defaultNetwork == DEFAULT_NETWORK_ALL) {
+            defaultNetworks =
+                    new int[] {DEFAULT_NETWORK_ALL, DEFAULT_NETWORK_YES, DEFAULT_NETWORK_NO};
+        } else {
+            defaultNetworks = new int[] {defaultNetwork};
+        }
+
+        for (int s : sets) {
+            for (int r : roamings) {
+                for (int m : meterings) {
+                    for (int d : defaultNetworks) {
+                        final int i = stats.findIndex(iface, uid, s, tag, m, r, d);
+                        if (i != -1) {
+                            entry.add(stats.getValues(i, null));
+                        }
+                    }
+                }
+            }
+        }
+
+        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
+        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+        assertEquals("unexpected operations", operations, entry.operations);
+    }
+
+    VpnInfo createVpnInfo(String[] underlyingIfaces) {
+        VpnInfo info = new VpnInfo();
+        info.ownerUid = UID_VPN;
+        info.vpnIface = TUN_IFACE;
+        info.underlyingIfaces = underlyingIfaces;
+        return info;
+    }
+}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 9b4f49c..8f90f13 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -29,6 +29,7 @@
 
 import static com.android.server.net.NetworkStatsCollection.multiplySafe;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
@@ -43,7 +44,6 @@
 import android.os.UserHandle;
 import android.telephony.SubscriptionPlan;
 import android.telephony.TelephonyManager;
-import android.test.MoreAsserts;
 import android.text.format.DateUtils;
 import android.util.RecurrenceRule;
 
@@ -240,11 +240,11 @@
                 60 * MINUTE_IN_MILLIS, entry);
 
         // Verify the set of relevant UIDs for each access level.
-        MoreAsserts.assertEquals(new int[] { myUid },
+        assertArrayEquals(new int[] { myUid },
                 collection.getRelevantUids(NetworkStatsAccess.Level.DEFAULT));
-        MoreAsserts.assertEquals(new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser },
+        assertArrayEquals(new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser },
                 collection.getRelevantUids(NetworkStatsAccess.Level.USER));
-        MoreAsserts.assertEquals(
+        assertArrayEquals(
                 new int[] { Process.SYSTEM_UID, myUid, otherUidInSameUser, uidInDifferentUser },
                 collection.getRelevantUids(NetworkStatsAccess.Level.DEVICE));
 
diff --git a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
index 95bc7d9..a21f509 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -16,8 +16,11 @@
 
 package com.android.server.net;
 
+import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
 import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
+import static android.net.NetworkStats.METERED_ALL;
 import static android.net.NetworkStats.METERED_NO;
+import static android.net.NetworkStats.ROAMING_ALL;
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
@@ -39,6 +42,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.frameworks.tests.net.R;
+import com.android.internal.net.VpnInfo;
 
 import libcore.io.IoUtils;
 import libcore.io.Streams;
@@ -54,12 +58,12 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
-/**
- * Tests for {@link NetworkStatsFactory}.
- */
+/** Tests for {@link NetworkStatsFactory}. */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class NetworkStatsFactoryTest {
+public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
+    private static final String CLAT_PREFIX = "v4-";
+
     private File mTestProc;
     private NetworkStatsFactory mFactory;
 
@@ -75,6 +79,7 @@
         // related to networkStatsFactory is compiled to a minimal native library and loaded here.
         System.loadLibrary("networkstatsfactorytestjni");
         mFactory = new NetworkStatsFactory(mTestProc, false);
+        mFactory.updateVpnInfos(new VpnInfo[0]);
     }
 
     @After
@@ -99,6 +104,236 @@
     }
 
     @Test
+    public void vpnRewriteTrafficThroughItself() throws Exception {
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        //
+        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
+        // over VPN.
+        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
+        // over VPN.
+        //
+        // VPN UID rewrites packets read from TUN back to TUN, plus some of its own traffic
+
+        final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_rewrite_through_self);
+
+        assertValues(tunStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, 2000L, 200L, 1000L, 100L, 0);
+        assertValues(tunStats, TUN_IFACE, UID_BLUE, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, 1000L, 100L, 500L, 50L, 0);
+        assertValues(tunStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
+                DEFAULT_NETWORK_ALL, 0L, 0L, 1600L, 160L, 0);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L);
+        assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 260L, 26L);
+    }
+
+    @Test
+    public void vpnWithClat() throws Exception {
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})};
+        mFactory.updateVpnInfos(vpnInfos);
+        mFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
+        // over VPN.
+        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
+        // over VPN.
+        // VPN sent 1650 bytes (150 packets), and received 3300 (300 packets) over v4-WiFi, and clat
+        // added 20 bytes per packet of extra overhead
+        //
+        // For 1650 bytes sent over v4-WiFi, 4650 bytes were actually sent over WiFi, which is
+        // expected to be split as follows:
+        // UID_RED: 1000 bytes, 100 packets
+        // UID_BLUE: 500 bytes, 50 packets
+        // UID_VPN: 3150 bytes, 0 packets
+        //
+        // For 3300 bytes received over v4-WiFi, 9300 bytes were actually sent over WiFi, which is
+        // expected to be split as follows:
+        // UID_RED: 2000 bytes, 200 packets
+        // UID_BLUE: 1000 bytes, 100 packets
+        // UID_VPN: 6300 bytes, 0 packets
+        final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_with_clat);
+
+        assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_RED, 2000L, 200L, 1000, 100L);
+        assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
+        assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_VPN, 6300L, 0L, 3150L, 0L);
+    }
+
+    @Test
+    public void vpnWithOneUnderlyingIface() throws Exception {
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
+        // over VPN.
+        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
+        // over VPN.
+        // VPN sent 1650 bytes (150 packets), and received 3300 (300 packets) over WiFi.
+        // Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
+        // attributed to UID_BLUE, and 150 bytes attributed to UID_VPN.
+        // Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
+        // attributed to UID_BLUE, and 300 bytes attributed to UID_VPN.
+        final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L);
+        assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 150L, 0L);
+    }
+
+    @Test
+    public void vpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
+        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
+        // over VPN.
+        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
+        // over VPN.
+        // Additionally, the VPN sends 6000 bytes (600 packets) of its own traffic into the tun
+        // interface (passing that traffic to the VPN endpoint), and receives 5000 bytes (500
+        // packets) from it. Including overhead that is 6600/5500 bytes.
+        // VPN sent 8250 bytes (750 packets), and received 8800 (800 packets) over WiFi.
+        // Of 8250 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
+        // attributed to UID_BLUE, and 6750 bytes attributed to UID_VPN.
+        // Of 8800 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
+        // attributed to UID_BLUE, and 5800 bytes attributed to UID_VPN.
+        final NetworkStats tunStats =
+                parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_own_traffic);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L);
+        assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 5800L, 500L, 6750L, 600L);
+    }
+
+    @Test
+    public void vpnWithOneUnderlyingIface_withCompression() throws Exception {
+        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
+        // 3000 bytes (300 packets) were sent/received by UID_BLUE over VPN.
+        // VPN sent/received 1000 bytes (100 packets) over WiFi.
+        // Of 1000 bytes over WiFi, expect 250 bytes attributed UID_RED and 750 bytes to UID_BLUE,
+        // with nothing attributed to UID_VPN for both rx/tx traffic.
+        final NetworkStats tunStats =
+                parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_compression);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 250L, 25L, 250L, 25L);
+        assertValues(tunStats, TEST_IFACE, UID_BLUE, 750L, 75L, 750L, 75L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L);
+    }
+
+    @Test
+    public void vpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception {
+        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
+        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
+        // Additionally, VPN is duplicating traffic across both WiFi and Cell.
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        // 1000 bytes (100 packets) were sent/received by UID_RED and UID_BLUE over VPN.
+        // VPN sent/received 4400 bytes (400 packets) over both WiFi and Cell (8800 bytes in total).
+        // Of 8800 bytes over WiFi/Cell, expect:
+        // - 500 bytes rx/tx each over WiFi/Cell attributed to both UID_RED and UID_BLUE.
+        // - 1200 bytes rx/tx each over WiFi/Cell for VPN_UID.
+        final NetworkStats tunStats =
+                parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_duplication);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 500L, 50L, 500L, 50L);
+        assertValues(tunStats, TEST_IFACE, UID_BLUE, 500L, 50L, 500L, 50L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 1200L, 100L, 1200L, 100L);
+        assertValues(tunStats, TEST_IFACE2, UID_RED, 500L, 50L, 500L, 50L);
+        assertValues(tunStats, TEST_IFACE2, UID_BLUE, 500L, 50L, 500L, 50L);
+        assertValues(tunStats, TEST_IFACE2, UID_VPN, 1200L, 100L, 1200L, 100L);
+    }
+
+    @Test
+    public void vpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception {
+        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
+        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
+        // Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell.
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        // 1000 bytes (100 packets) were sent, and 500 bytes (50 packets) received by UID_RED over
+        // VPN.
+        // VPN sent 660 bytes (60 packets) over WiFi and 440 bytes (40 packets) over Cell.
+        // And, it received 330 bytes (30 packets) over WiFi and 220 bytes (20 packets) over Cell.
+        // For UID_RED, expect 600 bytes attributed over WiFi and 400 bytes over Cell for sent (tx)
+        // traffic. For received (rx) traffic, expect 300 bytes over WiFi and 200 bytes over Cell.
+        //
+        // For UID_VPN, expect 60 bytes attributed over WiFi and 40 bytes over Cell for tx traffic.
+        // And, 30 bytes over WiFi and 20 bytes over Cell for rx traffic.
+        final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_split);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 300L, 30L, 600L, 60L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 30L, 0L, 60L, 0L);
+        assertValues(tunStats, TEST_IFACE2, UID_RED, 200L, 20L, 400L, 40L);
+        assertValues(tunStats, TEST_IFACE2, UID_VPN, 20L, 0L, 40L, 0L);
+    }
+
+    @Test
+    public void vpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception {
+        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
+        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
+        // Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell.
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface:
+        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
+        // VPN sent/received 600 bytes (60 packets) over WiFi and 200 bytes (20 packets) over Cell.
+        // For UID_RED, expect 600 bytes attributed over WiFi and 200 bytes over Cell for both
+        // rx/tx.
+        // UID_VPN gets nothing attributed to it (avoiding negative stats).
+        final NetworkStats tunStats =
+                parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_split_compression);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 600L, 60L, 600L, 60L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L);
+        assertValues(tunStats, TEST_IFACE2, UID_RED, 200L, 20L, 200L, 20L);
+        assertValues(tunStats, TEST_IFACE2, UID_VPN, 0L, 0L, 0L, 0L);
+    }
+
+    @Test
+    public void vpnWithIncorrectUnderlyingIface() throws Exception {
+        // WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
+        // but has declared only WiFi (TEST_IFACE) in its underlying network set.
+        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
+        mFactory.updateVpnInfos(vpnInfos);
+
+        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
+        // overhead per packet):
+        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
+        // VPN sent/received 1100 bytes (100 packets) over Cell.
+        // Of 1100 bytes over Cell, expect all of it attributed to UID_VPN for both rx/tx traffic.
+        final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_incorrect_iface);
+
+        assertValues(tunStats, TEST_IFACE, UID_RED, 0L, 0L, 0L, 0L);
+        assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L);
+        assertValues(tunStats, TEST_IFACE2, UID_RED, 0L, 0L, 0L, 0L);
+        assertValues(tunStats, TEST_IFACE2, UID_VPN, 1100L, 100L, 1100L, 100L);
+    }
+
+    @Test
     public void testKernelTags() throws Exception {
         assertEquals(0, kernelToTag("0x0000000000000000"));
         assertEquals(0x32, kernelToTag("0x0000003200000000"));
@@ -146,20 +381,25 @@
     }
 
     @Test
-    public void testDoubleClatAccounting() throws Exception {
-        NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
+    public void testDoubleClatAccountingSimple() throws Exception {
+        mFactory.noteStackedIface("v4-wlan0", "wlan0");
 
         // xt_qtaguid_with_clat_simple is a synthetic file that simulates
         //  - 213 received 464xlat packets of size 200 bytes
         //  - 41 sent 464xlat packets of size 100 bytes
         //  - no other traffic on base interface for root uid.
         NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_simple);
-        assertEquals(4, stats.size());
+        assertEquals(3, stats.size());
 
         assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 46860L, 4920L);
         assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 0L, 0L);
+    }
 
-        stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat);
+    @Test
+    public void testDoubleClatAccounting() throws Exception {
+        mFactory.noteStackedIface("v4-wlan0", "wlan0");
+
+        NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat);
         assertEquals(42, stats.size());
 
         assertStatsEntry(stats, "v4-wlan0", 0, SET_DEFAULT, 0x0, 356L, 276L);
@@ -178,8 +418,6 @@
         assertStatsEntry(stats, "lo", 0, SET_DEFAULT, 0x0, 1288L, 1288L);
 
         assertNoStatsEntry(stats, "wlan0", 1029, SET_DEFAULT, 0x0);
-
-        NetworkStatsFactory.clearStackedIfaces();
     }
 
     @Test
@@ -194,7 +432,7 @@
         long rootRxBytesAfter = 1398634L;
         assertEquals("UID 0 traffic should be ~0", 4623, rootRxBytesAfter - rootRxBytesBefore);
 
-        NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
+        mFactory.noteStackedIface("v4-wlan0", "wlan0");
         NetworkStats stats;
 
         // Stats snapshot before the download
@@ -206,8 +444,6 @@
         stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_100mb_download_after);
         assertStatsEntry(stats, "v4-wlan0", 10106, SET_FOREGROUND, 0x0, appRxBytesAfter, 7867488L);
         assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, rootRxBytesAfter, 0L);
-
-        NetworkStatsFactory.clearStackedIfaces();
     }
 
     /**
@@ -272,11 +508,19 @@
 
     private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
             int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
-        final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO,
-                DEFAULT_NETWORK_NO);
+        assertStatsEntry(stats, iface, uid, set, tag, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO,
+                rxBytes, rxPackets, txBytes, txPackets);
+    }
+
+    private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
+            int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
+            long txBytes, long txPackets) {
+        final int i = stats.findIndex(iface, uid, set, tag, metered, roaming, defaultNetwork);
+
         if (i < 0) {
-            fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d)",
-                    iface, uid, set, tag));
+            fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d, metered:"
+                    + " %d, roaming: %d, defaultNetwork: %d)",
+                    iface, uid, set, tag, metered, roaming, defaultNetwork));
         }
         final NetworkStats.Entry entry = stats.getValues(i, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index 9a47f35..c0f9dc1 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -52,7 +52,6 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.net.VpnInfo;
 import com.android.server.net.NetworkStatsServiceTest.LatchedHandler;
 import com.android.testutils.HandlerUtilsKt;
 
@@ -93,8 +92,6 @@
     private static final long BASE_BYTES = 7 * MB_IN_BYTES;
     private static final int INVALID_TYPE = -1;
 
-    private static final VpnInfo[] VPN_INFO = new VpnInfo[0];
-
     private long mElapsedRealtime;
 
     private HandlerThread mObserverHandlerThread;
@@ -247,8 +244,7 @@
         NetworkStats uidSnapshot = null;
 
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
     }
 
@@ -271,15 +267,13 @@
                 .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
         NetworkStats uidSnapshot = null;
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
                 .addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
     }
 
@@ -303,16 +297,14 @@
                 .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
         NetworkStats uidSnapshot = null;
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */)
                 .addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
                         BASE_BYTES + THRESHOLD_BYTES, 22L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
         assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
     }
@@ -337,8 +329,7 @@
                 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
@@ -346,8 +337,7 @@
                         DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
         assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
     }
@@ -372,8 +362,7 @@
                 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
@@ -381,8 +370,7 @@
                         DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
     }
 
@@ -406,8 +394,7 @@
                 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
                         DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
@@ -415,8 +402,7 @@
                         DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
         assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
     }
@@ -441,8 +427,7 @@
                 .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
                         ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
 
         // Delta
         uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
@@ -450,8 +435,7 @@
                         ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
                         BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
         mStatsObservers.updateStats(
-                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
-                VPN_INFO, TEST_START);
+                xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
         waitForObserverToIdle();
     }
 
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 31df9f3..1d29a82 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -23,7 +23,6 @@
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
-import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.INTERFACES_ALL;
@@ -38,11 +37,11 @@
 import static android.net.NetworkStats.SET_FOREGROUND;
 import static android.net.NetworkStats.STATS_PER_IFACE;
 import static android.net.NetworkStats.STATS_PER_UID;
+import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStatsHistory.FIELD_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
 import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.net.TrafficStats.UID_REMOVED;
@@ -56,7 +55,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -129,13 +127,9 @@
  */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class NetworkStatsServiceTest {
+public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
     private static final String TAG = "NetworkStatsServiceTest";
 
-    private static final String TEST_IFACE = "test0";
-    private static final String TEST_IFACE2 = "test1";
-    private static final String TUN_IFACE = "test_nss_tun0";
-
     private static final long TEST_START = 1194220800000L;
 
     private static final String IMSI_1 = "310004";
@@ -146,11 +140,6 @@
     private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
     private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
 
-    private static final int UID_RED = 1001;
-    private static final int UID_BLUE = 1002;
-    private static final int UID_GREEN = 1003;
-    private static final int UID_VPN = 1004;
-
     private static final Network WIFI_NETWORK =  new Network(100);
     private static final Network MOBILE_NETWORK =  new Network(101);
     private static final Network VPN_NETWORK = new Network(102);
@@ -167,6 +156,7 @@
     private File mStatsDir;
 
     private @Mock INetworkManagementService mNetManager;
+    private @Mock NetworkStatsFactory mStatsFactory;
     private @Mock NetworkStatsSettings mSettings;
     private @Mock IBinder mBinder;
     private @Mock AlarmManager mAlarmManager;
@@ -202,8 +192,8 @@
 
         mService = new NetworkStatsService(
                 mServiceContext, mNetManager, mAlarmManager, wakeLock, mClock,
-                TelephonyManager.getDefault(), mSettings, new NetworkStatsObservers(),
-                mStatsDir, getBaseDir(mStatsDir));
+                TelephonyManager.getDefault(), mSettings, mStatsFactory,
+                new NetworkStatsObservers(),  mStatsDir, getBaseDir(mStatsDir));
         mHandlerThread = new HandlerThread("HandlerThread");
         mHandlerThread.start();
         Handler.Callback callback = new NetworkStatsService.HandlerCallback(mService);
@@ -216,12 +206,9 @@
         expectNetworkStatsUidDetail(buildEmptyStats());
         expectSystemReady();
 
-        assertNull(mService.getTunAdjustedStats());
         mService.systemReady();
-        // Verify that system ready fetches realtime stats and initializes tun adjusted stats.
-        verify(mNetManager).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
-        assertNotNull("failed to initialize TUN adjusted stats", mService.getTunAdjustedStats());
-        assertEquals(0, mService.getTunAdjustedStats().size());
+        // Verify that system ready fetches realtime stats
+        verify(mStatsFactory).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
 
         mSession = mService.openSession();
         assertNotNull("openSession() failed", mSession);
@@ -255,9 +242,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // verify service has empty history for wifi
         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -299,9 +285,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // verify service has empty history for wifi
         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -373,10 +358,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // modify some number on wifi, and trigger poll event
         incrementCurrentTime(2 * HOUR_IN_MILLIS);
@@ -415,10 +398,8 @@
         NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
 
         // create some traffic on first network
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -451,9 +432,8 @@
                 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
                 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
                 .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states));
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
         forcePollAndWaitForIdle();
 
 
@@ -491,10 +471,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // create some traffic
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -550,10 +528,8 @@
         NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
 
         // create some traffic
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -578,9 +554,8 @@
         expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
                 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
                 .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states));
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
         forcePollAndWaitForIdle();
 
 
@@ -608,10 +583,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // create some traffic for two apps
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -667,9 +640,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         NetworkStats.Entry entry1 = new NetworkStats.Entry(
                 TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L);
@@ -711,9 +683,8 @@
 
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         NetworkStats.Entry uidStats = new NetworkStats.Entry(
                 TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L);
@@ -725,10 +696,13 @@
                 "otherif", UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L);
 
         final String[] ifaceFilter = new String[] { TEST_IFACE };
+        final String[] augmentedIfaceFilter = new String[] { stackedIface, TEST_IFACE };
         incrementCurrentTime(HOUR_IN_MILLIS);
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats());
-        when(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL), any()))
+        when(mStatsFactory.augmentWithStackedInterfaces(eq(ifaceFilter)))
+                .thenReturn(augmentedIfaceFilter);
+        when(mStatsFactory.readNetworkStatsDetail(eq(UID_ALL), any(), eq(TAG_ALL)))
                 .thenReturn(new NetworkStats(getElapsedRealtime(), 1)
                         .addValues(uidStats));
         when(mNetManager.getNetworkStatsTethering(STATS_PER_UID))
@@ -738,11 +712,17 @@
 
         NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
 
-        // mNetManager#getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL) has following invocations:
+        // mStatsFactory#readNetworkStatsDetail() has the following invocations:
         // 1) NetworkStatsService#systemReady from #setUp.
         // 2) mService#forceUpdateIfaces in the test above.
-        // 3) Finally, mService#getDetailedUidStats.
-        verify(mNetManager, times(3)).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
+        //
+        // Additionally, we should have one call from the above call to mService#getDetailedUidStats
+        // with the augmented ifaceFilter.
+        verify(mStatsFactory, times(2)).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
+        verify(mStatsFactory, times(1)).readNetworkStatsDetail(
+                eq(UID_ALL),
+                eq(augmentedIfaceFilter),
+                eq(TAG_ALL));
         assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), TEST_IFACE));
         assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), stackedIface));
         assertEquals(2, stats.size());
@@ -757,10 +737,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // create some initial traffic
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -815,10 +793,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState(true /* isMetered */)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // create some initial traffic
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -856,10 +832,8 @@
             new NetworkState[] {buildMobile3gState(IMSI_1, true /* isRoaming */)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
 
         // Create some traffic
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -895,10 +869,8 @@
         NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states));
-
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states), new VpnInfo[0]);
 
         // create some tethering traffic
         incrementCurrentTime(HOUR_IN_MILLIS);
@@ -930,481 +902,6 @@
     }
 
     @Test
-    public void vpnRewriteTrafficThroughItself() throws Exception {
-        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
-        expectDefaultSettings();
-        NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        //
-        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
-        // over VPN.
-        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
-        // over VPN.
-        //
-        // VPN UID rewrites packets read from TUN back to TUN, plus some of its own traffic
-        // (100 bytes).
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 5)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 1000L, 100L, 1L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 500L, 50L, 1L)
-                // VPN rewrites all the packets read from TUN + 100 additional bytes of VPN's
-                // own traffic.
-                .addValues(TUN_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 0L, 0L, 1600L, 160L, 2L)
-                // VPN sent 1760 bytes over WiFi in foreground (SET_FOREGROUND) i.e. 1600
-                // bytes (160 packets) + 1 byte/packet overhead (=160 bytes).
-                .addValues(TEST_IFACE, UID_VPN, SET_FOREGROUND, TAG_NONE, 0L, 0L, 1760L, 176L, 1L)
-                // VPN received 3300 bytes over WiFi in background (SET_DEFAULT) i.e. 3000 bytes
-                // (300 packets) + 1 byte/packet encryption overhead (=300 bytes).
-                .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 3300L, 300L, 0L, 0L, 1L));
-
-        forcePollAndWaitForIdle();
-
-        // Verify increased TUN usage by UID_VPN does not get attributed to other apps.
-        NetworkStats tunStats =
-                mService.getDetailedUidStats(new String[] {TUN_IFACE});
-        assertValues(
-                tunStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 2000L, 200L, 1000L, 100L, 1);
-        assertValues(
-                tunStats, TUN_IFACE, UID_BLUE, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 500L, 50L, 1);
-        assertValues(
-                tunStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 0L, 0L, 1600L, 160L, 2);
-
-        // Verify correct attribution over WiFi.
-        assertUidTotal(sTemplateWifi, UID_RED, 2000L, 200L, 1000L, 100L, 1);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 1000L, 100L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 300L, 0L, 260L, 26L, 2);
-    }
-
-    @Test
-    public void vpnWithOneUnderlyingIface() throws Exception {
-        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
-        expectDefaultSettings();
-        NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
-        // over VPN.
-        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
-        // over VPN.
-        // VPN sent 1650 bytes (150 packets), and received 3300 (300 packets) over WiFi.
-        // Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
-        // attributed to UID_BLUE, and 150 bytes attributed to UID_VPN.
-        // Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
-        // attributed to UID_BLUE, and 300 bytes attributed to UID_VPN.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 1000L, 100L, 1L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 500L, 50L, 1L)
-                // VPN received 3300 bytes over WiFi in background (SET_DEFAULT).
-                .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 3300L, 300L, 0L, 0L, 1L)
-                // VPN sent 1650 bytes over WiFi in foreground (SET_FOREGROUND).
-                .addValues(TEST_IFACE, UID_VPN, SET_FOREGROUND, TAG_NONE, 0L, 0L, 1650L, 150L, 1L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 2000L, 200L, 1000L, 100L, 1);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 1000L, 100L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 300L, 0L, 150L, 0L, 2);
-    }
-
-    @Test
-    public void vpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
-        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
-        expectDefaultSettings();
-        NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
-        // over VPN.
-        // 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
-        // over VPN.
-        // Additionally, the VPN sends 6000 bytes (600 packets) of its own traffic into the tun
-        // interface (passing that traffic to the VPN endpoint), and receives 5000 bytes (500
-        // packets) from it. Including overhead that is 6600/5500 bytes.
-        // VPN sent 8250 bytes (750 packets), and received 8800 (800 packets) over WiFi.
-        // Of 8250 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
-        // attributed to UID_BLUE, and 6750 bytes attributed to UID_VPN.
-        // Of 8800 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
-        // attributed to UID_BLUE, and 5800 bytes attributed to UID_VPN.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 1000L, 100L, 1L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 500L, 50L, 1L)
-                .addValues(TUN_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 5000L, 500L, 6000L, 600L, 1L)
-                // VPN received 8800 bytes over WiFi in background (SET_DEFAULT).
-                .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 8800L, 800L, 0L, 0L, 1L)
-                // VPN sent 8250 bytes over WiFi in foreground (SET_FOREGROUND).
-                .addValues(TEST_IFACE, UID_VPN, SET_FOREGROUND, TAG_NONE, 0L, 0L, 8250L, 750L, 1L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 2000L, 200L, 1000L, 100L, 1);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 1000L, 100L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 5800L, 500L, 6750L, 600L, 2);
-    }
-
-    @Test
-    public void vpnWithOneUnderlyingIface_withCompression() throws Exception {
-        // WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
-        expectDefaultSettings();
-        NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
-        // 3000 bytes (300 packets) were sent/received by UID_BLUE over VPN.
-        // VPN sent/received 1000 bytes (100 packets) over WiFi.
-        // Of 1000 bytes over WiFi, expect 250 bytes attributed UID_RED and 750 bytes to UID_BLUE,
-        // with nothing attributed to UID_VPN for both rx/tx traffic.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 3000L, 300L, 3000L, 300L, 1L)
-                .addValues(
-                    TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 0L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 250L, 25L, 250L, 25L, 0);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 750L, 75L, 750L, 75L, 0);
-        assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
-    public void vpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception {
-        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
-        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
-        // Additionally, VPN is duplicating traffic across both WiFi and Cell.
-        expectDefaultSettings();
-        NetworkState[] networkStates =
-                new NetworkState[] {
-                    buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
-                };
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent/received by UID_RED and UID_BLUE over VPN.
-        // VPN sent/received 4400 bytes (400 packets) over both WiFi and Cell (8800 bytes in total).
-        // Of 8800 bytes over WiFi/Cell, expect:
-        // - 500 bytes rx/tx each over WiFi/Cell attributed to both UID_RED and UID_BLUE.
-        // - 1200 bytes rx/tx each over WiFi/Cell for VPN_UID.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 2L)
-                .addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 2L)
-                .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 2200L, 200L, 2L)
-                .addValues(
-                    TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 2200L, 200L, 2L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 500L, 50L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 500L, 50L, 500L, 50L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 1200L, 100L, 1200L, 100L, 2);
-
-        assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 500L, 50L, 500L, 50L, 1);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_BLUE, 500L, 50L, 500L, 50L, 1);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 1200L, 100L, 1200L, 100L, 2);
-    }
-
-    @Test
-    public void vpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception {
-        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
-        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
-        // Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell.
-        expectDefaultSettings();
-        NetworkState[] networkStates =
-                new NetworkState[] {
-                    buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
-                };
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent, and 500 bytes (50 packets) received by UID_RED over
-        // VPN.
-        // VPN sent 660 bytes (60 packets) over WiFi and 440 bytes (40 packets) over Cell.
-        // And, it received 330 bytes (30 packets) over WiFi and 220 bytes (20 packets) over Cell.
-        // For UID_RED, expect 600 bytes attributed over WiFi and 400 bytes over Cell for sent (tx)
-        // traffic. For received (rx) traffic, expect 300 bytes over WiFi and 200 bytes over Cell.
-        //
-        // For UID_VPN, expect 60 bytes attributed over WiFi and 40 bytes over Cell for tx traffic.
-        // And, 30 bytes over WiFi and 20 bytes over Cell for rx traffic.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 500L, 50L, 1000L, 100L, 2L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 330L, 30L, 660L, 60L, 1L)
-              .addValues(TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 220L, 20L, 440L, 40L, 1L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 300L, 30L, 600L, 60L, 1);
-        assertUidTotal(sTemplateWifi, UID_VPN, 30L, 0L, 60L, 0L, 1);
-
-        assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 200L, 20L, 400L, 40L, 1);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 20L, 0L, 40L, 0L, 1);
-    }
-
-    @Test
-    public void vpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception {
-        // WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
-        // Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
-        // Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell.
-        expectDefaultSettings();
-        NetworkState[] networkStates =
-                new NetworkState[] {
-                    buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
-                };
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface:
-        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
-        // VPN sent/received 600 bytes (60 packets) over WiFi and 200 bytes (20 packets) over Cell.
-        // For UID_RED, expect 600 bytes attributed over WiFi and 200 bytes over Cell for both
-        // rx/tx.
-        // UID_VPN gets nothing attributed to it (avoiding negative stats).
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 600L, 60L, 600L, 60L, 0L)
-              .addValues(TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 200L, 20L, 200L, 20L, 0L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 600L, 60L, 600L, 60L, 0);
-        assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
-
-        assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 200L, 20L, 200L, 20L, 0);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 0L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
-    public void vpnWithIncorrectUnderlyingIface() throws Exception {
-        // WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
-        // but has declared only WiFi (TEST_IFACE) in its underlying network set.
-        expectDefaultSettings();
-        NetworkState[] networkStates =
-                new NetworkState[] {
-                    buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
-                };
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
-
-        mService.forceUpdateIfaces(
-                new Network[] {WIFI_NETWORK, VPN_NETWORK},
-                vpnInfos,
-                networkStates,
-                getActiveIface(networkStates));
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
-        // VPN sent/received 1100 bytes (100 packets) over Cell.
-        // Of 1100 bytes over Cell, expect all of it attributed to UID_VPN for both rx/tx traffic.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-                .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
-                .addValues(
-                    TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 1100L, 100L, 1L));
-
-        forcePollAndWaitForIdle();
-
-        assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
-        assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 0L, 0L, 0L, 0L, 0);
-        assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 1100L, 100L, 1100L, 100L, 1);
-    }
-
-    @Test
-    public void recordSnapshot_migratesTunTrafficAndUpdatesTunAdjustedStats() throws Exception {
-        assertEquals(0, mService.getTunAdjustedStats().size());
-        // VPN using WiFi (TEST_IFACE).
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectBandwidthControlCheck();
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
-        // VPN received 1100 bytes (100 packets) over WiFi.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
-
-        // this should lead to NSS#recordSnapshotLocked
-        mService.forceUpdateIfaces(
-                new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
-
-        // Verify TUN adjusted stats have traffic migrated correctly.
-        // Of 1100 bytes VPN received over WiFi, expect 1000 bytes attributed to UID_RED and 100
-        // bytes attributed to UID_VPN.
-        NetworkStats tunAdjStats = mService.getTunAdjustedStats();
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
-    public void getDetailedUidStats_migratesTunTrafficAndUpdatesTunAdjustedStats()
-            throws Exception {
-        assertEquals(0, mService.getTunAdjustedStats().size());
-        // VPN using WiFi (TEST_IFACE).
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectBandwidthControlCheck();
-        mService.forceUpdateIfaces(
-                new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
-        // VPN received 1100 bytes (100 packets) over WiFi.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
-
-        mService.getDetailedUidStats(INTERFACES_ALL);
-
-        // Verify internally maintained TUN adjusted stats
-        NetworkStats tunAdjStats = mService.getTunAdjustedStats();
-        // Verify stats for TEST_IFACE (WiFi):
-        // Of 1100 bytes VPN received over WiFi, expect 1000 bytes attributed to UID_RED and 100
-        // bytes attributed to UID_VPN.
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
-        // Verify stats for TUN_IFACE; only UID_RED should have usage on it.
-        assertValues(
-                tunAdjStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 0);
-
-        // lets assume that since last time, VPN received another 1100 bytes (same assumptions as
-        // before i.e. UID_RED downloaded another 1000 bytes).
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        // Note - NetworkStatsFactory returns counters that are monotonically increasing.
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 2000L, 200L, 0L, 0L, 0L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 2200L, 200L, 0L, 0L, 0L));
-
-        mService.getDetailedUidStats(INTERFACES_ALL);
-
-        tunAdjStats = mService.getTunAdjustedStats();
-        // verify TEST_IFACE stats:
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 2000L, 200L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 200L, 0L, 0L, 0L, 0);
-        // verify TUN_IFACE stats:
-        assertValues(
-                tunAdjStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 2000L, 200L, 0L, 0L, 0);
-        assertValues(
-                tunAdjStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 0L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
-    public void getDetailedUidStats_returnsCorrectStatsWithVpnRunning() throws Exception {
-        // VPN using WiFi (TEST_IFACE).
-        VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
-        expectBandwidthControlCheck();
-        mService.forceUpdateIfaces(
-                new Network[0], vpnInfos, new NetworkState[0], null /* activeIface */);
-        // create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
-        // overhead per packet):
-        // 1000 bytes (100 packets) were downloaded by UID_RED over VPN.
-        // VPN received 1100 bytes (100 packets) over WiFi.
-        incrementCurrentTime(HOUR_IN_MILLIS);
-        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
-              .addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 0L, 0L, 0L)
-              .addValues(TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 0L, 0L, 0L));
-
-        // Query realtime stats for TEST_IFACE.
-        NetworkStats queriedStats =
-                mService.getDetailedUidStats(new String[] {TEST_IFACE});
-
-        assertEquals(HOUR_IN_MILLIS, queriedStats.getElapsedRealtime());
-        // verify that returned stats are only for TEST_IFACE and VPN traffic is migrated correctly.
-        assertEquals(new String[] {TEST_IFACE}, queriedStats.getUniqueIfaces());
-        assertValues(
-                queriedStats, TEST_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 1000L, 100L, 0L, 0L, 0);
-        assertValues(
-                queriedStats, TEST_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, 100L, 0L, 0L, 0L, 0);
-    }
-
-    @Test
     public void testRegisterUsageCallback() throws Exception {
         // pretend that wifi network comes online; service should ask about full
         // network state, and poll any existing interfaces before updating.
@@ -1412,9 +909,8 @@
         NetworkState[] states = new NetworkState[] {buildWifiState()};
         expectNetworkStatsSummary(buildEmptyStats());
         expectNetworkStatsUidDetail(buildEmptyStats());
-        expectBandwidthControlCheck();
 
-        mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states));
+        mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]);
 
         // verify service has empty history for wifi
         assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -1553,7 +1049,6 @@
 
     private void expectSystemReady() throws Exception {
         expectNetworkStatsSummary(buildEmptyStats());
-        expectBandwidthControlCheck();
     }
 
     private String getActiveIface(NetworkState... states) throws Exception {
@@ -1575,11 +1070,11 @@
     }
 
     private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
-        when(mNetManager.getNetworkStatsSummaryDev()).thenReturn(summary);
+        when(mStatsFactory.readNetworkStatsSummaryDev()).thenReturn(summary);
     }
 
     private void expectNetworkStatsSummaryXt(NetworkStats summary) throws Exception {
-        when(mNetManager.getNetworkStatsSummaryXt()).thenReturn(summary);
+        when(mStatsFactory.readNetworkStatsSummaryXt()).thenReturn(summary);
     }
 
     private void expectNetworkStatsTethering(int how, NetworkStats stats)
@@ -1593,7 +1088,8 @@
 
     private void expectNetworkStatsUidDetail(NetworkStats detail, NetworkStats tetherStats)
             throws Exception {
-        when(mNetManager.getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL)).thenReturn(detail);
+        when(mStatsFactory.readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL))
+                .thenReturn(detail);
 
         // also include tethering details, since they are folded into UID
         when(mNetManager.getNetworkStatsTethering(STATS_PER_UID)).thenReturn(tetherStats);
@@ -1621,10 +1117,6 @@
         when(mSettings.getUidTagPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
     }
 
-    private void expectBandwidthControlCheck() throws Exception {
-        when(mNetManager.isBandwidthControlEnabled()).thenReturn(true);
-    }
-
     private void assertStatsFilesExist(boolean exist) {
         final File basePath = new File(mStatsDir, "netstats");
         if (exist) {
@@ -1634,59 +1126,6 @@
         }
     }
 
-    private static void assertValues(NetworkStats stats, String iface, int uid, int set,
-            int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
-            long txBytes, long txPackets, int operations) {
-        final NetworkStats.Entry entry = new NetworkStats.Entry();
-        final int[] sets;
-        if (set == SET_ALL) {
-            sets = new int[] { SET_ALL, SET_DEFAULT, SET_FOREGROUND };
-        } else {
-            sets = new int[] { set };
-        }
-
-        final int[] roamings;
-        if (roaming == ROAMING_ALL) {
-            roamings = new int[] { ROAMING_ALL, ROAMING_YES, ROAMING_NO };
-        } else {
-            roamings = new int[] { roaming };
-        }
-
-        final int[] meterings;
-        if (metered == METERED_ALL) {
-            meterings = new int[] { METERED_ALL, METERED_YES, METERED_NO };
-        } else {
-            meterings = new int[] { metered };
-        }
-
-        final int[] defaultNetworks;
-        if (defaultNetwork == DEFAULT_NETWORK_ALL) {
-            defaultNetworks = new int[] { DEFAULT_NETWORK_ALL, DEFAULT_NETWORK_YES,
-                    DEFAULT_NETWORK_NO };
-        } else {
-            defaultNetworks = new int[] { defaultNetwork };
-        }
-
-        for (int s : sets) {
-            for (int r : roamings) {
-                for (int m : meterings) {
-                    for (int d : defaultNetworks) {
-                        final int i = stats.findIndex(iface, uid, s, tag, m, r, d);
-                        if (i != -1) {
-                            entry.add(stats.getValues(i, null));
-                        }
-                    }
-                }
-            }
-        }
-
-        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
-        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
-        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
-        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
-        assertEquals("unexpected operations", operations, entry.operations);
-    }
-
     private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
             long rxPackets, long txBytes, long txPackets, int operations) {
         final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
@@ -1752,14 +1191,6 @@
         return new NetworkState(info, prop, new NetworkCapabilities(), VPN_NETWORK, null, null);
     }
 
-    private static VpnInfo createVpnInfo(String[] underlyingIfaces) {
-        VpnInfo info = new VpnInfo();
-        info.ownerUid = UID_VPN;
-        info.vpnIface = TUN_IFACE;
-        info.underlyingIfaces = underlyingIfaces;
-        return info;
-    }
-
     private long getElapsedRealtime() {
         return mElapsedRealtime;
     }
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_incorrect_iface b/tests/net/res/raw/xt_qtaguid_vpn_incorrect_iface
new file mode 100644
index 0000000..fc92715
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_incorrect_iface
@@ -0,0 +1,3 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test1 0x0 1004 0 1100 100 1100 100 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying
new file mode 100644
index 0000000..1ef1889
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying
@@ -0,0 +1,5 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
+4 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+5 test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_compression b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_compression
new file mode 100644
index 0000000..6d6bf55
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_compression
@@ -0,0 +1,4 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test_nss_tun0 0x0 1002 0 3000 300 3000 300 0 0 0 0 0 0 0 0 0 0 0 0
+4 test0 0x0 1004 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic
new file mode 100644
index 0000000..2c2e5d2
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_one_underlying_own_traffic
@@ -0,0 +1,6 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
+4 test_nss_tun0 0x0 1004 0 5000 500 6000 600 0 0 0 0 0 0 0 0 0 0 0 0
+5 test0 0x0 1004 0 8800 800 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+6 test0 0x0 1004 1 0 0 8250 750 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_rewrite_through_self b/tests/net/res/raw/xt_qtaguid_vpn_rewrite_through_self
new file mode 100644
index 0000000..afcdd71
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_rewrite_through_self
@@ -0,0 +1,6 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
+4 test_nss_tun0 0x0 1004 0 0 0 1600 160 0 0 0 0 0 0 0 0 0 0 0 0
+5 test0 0x0 1004 1 0 0 1760 176 0 0 0 0 0 0 0 0 0 0 0 0
+6 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_duplication b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_duplication
new file mode 100644
index 0000000..d7c7eb9
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_duplication
@@ -0,0 +1,5 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test_nss_tun0 0x0 1002 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+4 test0 0x0 1004 0 2200 200 2200 200 0 0 0 0 0 0 0 0 0 0 0 0
+5 test1 0x0 1004 0 2200 200 2200 200 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split
new file mode 100644
index 0000000..38a3dce
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split
@@ -0,0 +1,4 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 500 50 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test0 0x0 1004 0 330 30 660 60 0 0 0 0 0 0 0 0 0 0 0 0
+4 test1 0x0 1004 0 220 20 440 40 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split_compression b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split_compression
new file mode 100644
index 0000000..d35244b
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_two_underlying_split_compression
@@ -0,0 +1,4 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test0 0x0 1004 0 600 60 600 60 0 0 0 0 0 0 0 0 0 0 0 0
+4 test1 0x0 1004 0 200 20 200 20 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_vpn_with_clat b/tests/net/res/raw/xt_qtaguid_vpn_with_clat
new file mode 100644
index 0000000..0d893d5
--- /dev/null
+++ b/tests/net/res/raw/xt_qtaguid_vpn_with_clat
@@ -0,0 +1,8 @@
+idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
+2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
+3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
+4 v4-test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+5 v4-test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0
+6 test0 0x0 0 0 9300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+7 test0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+8 test0 0x0 1029 0 0 0 4650 150 0 0 0 0 0 0 0 0 0 0 0 0
\ No newline at end of file
diff --git a/tests/net/res/raw/xt_qtaguid_with_clat_simple b/tests/net/res/raw/xt_qtaguid_with_clat_simple
index 8c132e7..b37fae6 100644
--- a/tests/net/res/raw/xt_qtaguid_with_clat_simple
+++ b/tests/net/res/raw/xt_qtaguid_with_clat_simple
@@ -2,5 +2,4 @@
 2 v4-wlan0 0x0 10060 0 42600 213 4100 41 42600 213 0 0 0 0 4100 41 0 0 0 0
 3 v4-wlan0 0x0 10060 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 4 wlan0 0x0 0 0 46860 213 0 0 46860 213 0 0 0 0 0 0 0 0 0 0
-5 wlan0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-6 wlan0 0x0 1029 0 0 0 4920 41 0 0 0 0 0 0 4920 41 0 0 0 0
+5 wlan0 0x0 1029 0 0 0 4920 41 0 0 0 0 0 0 4920 41 0 0 0 0
diff --git a/tests/net/smoketest/Android.bp b/tests/net/smoketest/Android.bp
index ef1ad2c..84ae2b5 100644
--- a/tests/net/smoketest/Android.bp
+++ b/tests/net/smoketest/Android.bp
@@ -14,4 +14,9 @@
     defaults: ["FrameworksNetTests-jni-defaults"],
     srcs: ["java/SmokeTest.java"],
     test_suites: ["device-tests"],
-}
+    static_libs: [
+        "androidx.test.rules",
+        "mockito-target-minus-junit4",
+        "services.core",
+    ],
+}
\ No newline at end of file
diff --git a/tests/net/util/Android.bp b/tests/net/util/Android.bp
deleted file mode 100644
index d8c502d..0000000
--- a/tests/net/util/Android.bp
+++ /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.
-//
-
-// Common utilities for network tests.
-java_library {
-    name: "frameworks-net-testutils",
-    srcs: ["java/**/*.java"],
-    // test_current to be also appropriate for CTS tests
-    sdk_version: "test_current",
-    static_libs: [
-        "androidx.annotation_annotation",
-        "junit",
-    ],
-    libs: [
-        "android.test.base.stubs",
-    ],
-}
\ No newline at end of file
diff --git a/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java b/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
deleted file mode 100644
index 87537b9..0000000
--- a/tests/net/util/java/com/android/internal/util/ParcelableTestUtil.java
+++ /dev/null
@@ -1,41 +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.internal.util;
-
-import static org.junit.Assert.assertEquals;
-
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-
-/**
- * Utility classes to write tests for stable AIDL parceling/unparceling
- */
-public final class ParcelableTestUtil {
-
-    /**
-     * Verifies that the number of nonstatic fields in a class equals a given count.
-     *
-     * <p>This assertion serves as a reminder to update test code around it if fields are added
-     * after the test is written.
-     * @param count Expected number of nonstatic fields in the class.
-     * @param clazz Class to test.
-     */
-    public static <T> void assertFieldCountEquals(int count, Class<T> clazz) {
-        assertEquals(count, Arrays.stream(clazz.getDeclaredFields())
-                .filter(f -> !Modifier.isStatic(f.getModifiers())).count());
-    }
-}
diff --git a/tests/net/util/java/com/android/internal/util/TestUtils.java b/tests/net/util/java/com/android/internal/util/TestUtils.java
deleted file mode 100644
index daa00d2..0000000
--- a/tests/net/util/java/com/android/internal/util/TestUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public final class TestUtils {
-    private TestUtils() { }
-
-    /**
-     * Return a new instance of {@code T} after being parceled then unparceled.
-     */
-    public static <T extends Parcelable> T parcelingRoundTrip(T source) {
-        final Parcelable.Creator<T> creator;
-        try {
-            creator = (Parcelable.Creator<T>) source.getClass().getField("CREATOR").get(null);
-        } catch (IllegalAccessException | NoSuchFieldException e) {
-            fail("Missing CREATOR field: " + e.getMessage());
-            return null;
-        }
-        Parcel p = Parcel.obtain();
-        source.writeToParcel(p, /* flags */ 0);
-        p.setDataPosition(0);
-        final byte[] marshalled = p.marshall();
-        p = Parcel.obtain();
-        p.unmarshall(marshalled, 0, marshalled.length);
-        p.setDataPosition(0);
-        return creator.createFromParcel(p);
-    }
-
-    /**
-     * Assert that after being parceled then unparceled, {@code source} is equal to the original
-     * object.
-     */
-    public static <T extends Parcelable> void assertParcelingIsLossless(T source) {
-        assertEquals(source, parcelingRoundTrip(source));
-    }
-}
diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
deleted file mode 100644
index dcbbdbb..0000000
--- a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.framework.permission.tests;
-
-import com.android.internal.os.BinderInternal;
-
-import android.app.AppOpsManager;
-import android.os.Binder;
-import android.os.IPermissionController;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.ServiceManagerNative;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-/**
- * TODO: Remove this. This is only a placeholder, need to implement this.
- */
-public class ServiceManagerPermissionTests extends TestCase {
-    @SmallTest
-    public void testAddService() {
-        try {
-            // The security in the service manager is that you can't replace
-            // a service that is already published.
-            Binder binder = new Binder();
-            ServiceManager.addService("activity", binder);
-            fail("ServiceManager.addService did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    @SmallTest
-    public void testSetPermissionController() {
-        try {
-            IPermissionController pc = new IPermissionController.Stub() {
-                @Override
-                public boolean checkPermission(java.lang.String permission, int pid, int uid) {
-                    return true;
-                }
-
-                @Override
-                public int noteOp(String op, int uid, String packageName) {
-                    return AppOpsManager.MODE_ALLOWED;
-                }
-
-                @Override
-                public String[] getPackagesForUid(int uid) {
-                    return new String[0];
-                }
-
-                @Override
-                public boolean isRuntimePermission(String permission) {
-                    return false;
-                }
-
-                @Override
-                public int getPackageUid(String packageName, int flags) {
-                    return -1;
-                }
-            };
-            ServiceManagerNative.asInterface(BinderInternal.getContextObject())
-                    .setPermissionController(pc);
-            fail("IServiceManager.setPermissionController did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-    }
-}
diff --git a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
index 388c7d0..c50229a 100644
--- a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
@@ -16,9 +16,7 @@
 
 package com.android.framework.permission.tests;
 
-import junit.framework.TestCase;
-
-import android.media.AudioManager;
+import android.media.AudioAttributes;
 import android.os.Binder;
 import android.os.IVibratorService;
 import android.os.Process;
@@ -27,6 +25,9 @@
 import android.os.VibrationEffect;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import junit.framework.TestCase;
+
+
 /**
  * Verify that Hardware apis cannot be called without required permissions.
  */
@@ -51,7 +52,10 @@
         try {
             final VibrationEffect effect =
                     VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);
-            mVibratorService.vibrate(Process.myUid(), null, effect, AudioManager.STREAM_ALARM,
+            final AudioAttributes attrs = new AudioAttributes.Builder()
+                    .setUsage(AudioAttributes.USAGE_ALARM)
+                    .build();
+            mVibratorService.vibrate(Process.myUid(), null, effect, attrs,
                     "testVibrate", new Binder());
             fail("vibrate did not throw SecurityException as expected");
         } catch (SecurityException e) {
diff --git a/tests/privapp-permissions/Android.bp b/tests/privapp-permissions/Android.bp
index ca7864f..b661850 100644
--- a/tests/privapp-permissions/Android.bp
+++ b/tests/privapp-permissions/Android.bp
@@ -45,17 +45,17 @@
 }
 
 android_app {
-    name: "ProductServicesPrivAppPermissionTest",
+    name: "SystemExtPrivAppPermissionTest",
     sdk_version: "current",
     privileged: true,
-    manifest: "product_services/AndroidManifest.xml",
-    product_services_specific: true,
-    required: ["product_servicesprivapp-permissions-test.xml"],
+    manifest: "system_ext/AndroidManifest.xml",
+    system_ext_specific: true,
+    required: ["system_extprivapp-permissions-test.xml"],
 }
 
 prebuilt_etc {
-    name: "product_servicesprivapp-permissions-test.xml",
-    src: "product_services/privapp-permissions-test.xml",
+    name: "system_extprivapp-permissions-test.xml",
+    src: "system_ext/privapp-permissions-test.xml",
     sub_dir: "permissions",
-    product_services_specific: true,
+    system_ext_specific: true,
 }
diff --git a/tests/privapp-permissions/product_services/AndroidManifest.xml b/tests/privapp-permissions/product_services/AndroidManifest.xml
deleted file mode 100644
index 511ddee..0000000
--- a/tests/privapp-permissions/product_services/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2018 Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.framework.permission.privapp.tests.product_services">
-
-    <!-- MANAGE_USB is signature|privileged -->
-    <uses-permission android:name="android.permission.MANAGE_USB"/>
-</manifest>
diff --git a/tests/privapp-permissions/product_services/privapp-permissions-test.xml b/tests/privapp-permissions/product_services/privapp-permissions-test.xml
deleted file mode 100644
index 43baebb..0000000
--- a/tests/privapp-permissions/product_services/privapp-permissions-test.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<permissions>
-    <privapp-permissions package="com.android.framework.permission.privapp.tests.product_services">
-        <permission name="android.permission.MANAGE_USB"/>
-    </privapp-permissions>
-</permissions>
diff --git a/tests/privapp-permissions/system_ext/AndroidManifest.xml b/tests/privapp-permissions/system_ext/AndroidManifest.xml
new file mode 100644
index 0000000..4a0e82f
--- /dev/null
+++ b/tests/privapp-permissions/system_ext/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.framework.permission.privapp.tests.system_ext">
+
+    <!-- MANAGE_USB is signature|privileged -->
+    <uses-permission android:name="android.permission.MANAGE_USB"/>
+</manifest>
diff --git a/tests/privapp-permissions/system_ext/privapp-permissions-test.xml b/tests/privapp-permissions/system_ext/privapp-permissions-test.xml
new file mode 100644
index 0000000..ad63e86
--- /dev/null
+++ b/tests/privapp-permissions/system_ext/privapp-permissions-test.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<permissions>
+    <privapp-permissions package="com.android.framework.permission.privapp.tests.system_ext">
+        <permission name="android.permission.MANAGE_USB"/>
+    </privapp-permissions>
+</permissions>
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index b13731f..1be4ea8 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -56,7 +56,7 @@
         "libziparchive",
         "libpng",
         "libbase",
-        "libprotobuf-cpp-lite",
+        "libprotobuf-cpp-full",
         "libz",
         "libbuildversion",
     ],
diff --git a/tools/aapt2/AppInfo.h b/tools/aapt2/AppInfo.h
index 7512353..d3ca357 100644
--- a/tools/aapt2/AppInfo.h
+++ b/tools/aapt2/AppInfo.h
@@ -17,6 +17,7 @@
 #ifndef AAPT_APP_INFO_H
 #define AAPT_APP_INFO_H
 
+#include <set>
 #include <string>
 
 #include "util/Maybe.h"
@@ -42,6 +43,9 @@
 
   // The app's split name, if it is a split.
   Maybe<std::string> split_name;
+
+  // The split names that this split depends on.
+  std::set<std::string> split_name_dependencies;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/Configuration.proto b/tools/aapt2/Configuration.proto
index fc636a4..8a4644c 100644
--- a/tools/aapt2/Configuration.proto
+++ b/tools/aapt2/Configuration.proto
@@ -19,7 +19,6 @@
 package aapt.pb;
 
 option java_package = "com.android.aapt";
-option optimize_for = LITE_RUNTIME;
 
 // A description of the requirements a device must have in order for a
 // resource to be matched and selected.
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 859fe80..c557656 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -1387,7 +1387,7 @@
 
   return Attribute::Symbol{
       Reference(ResourceNameRef({}, ResourceType::kId, maybe_name.value())),
-      val.data};
+      val.data, val.dataType};
 }
 
 bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) {
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 464225f..4237469 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -401,7 +401,7 @@
   std::string input = R"(
       <attr name="foo">
         <enum name="bar" value="0"/>
-        <enum name="bat" value="1"/>
+        <enum name="bat" value="0x1"/>
         <enum name="baz" value="2"/>
       </attr>)";
   ASSERT_TRUE(TestParse(input));
@@ -414,14 +414,17 @@
   ASSERT_TRUE(enum_attr->symbols[0].symbol.name);
   EXPECT_THAT(enum_attr->symbols[0].symbol.name.value().entry, Eq("bar"));
   EXPECT_THAT(enum_attr->symbols[0].value, Eq(0u));
+  EXPECT_THAT(enum_attr->symbols[0].type, Eq(Res_value::TYPE_INT_DEC));
 
   ASSERT_TRUE(enum_attr->symbols[1].symbol.name);
   EXPECT_THAT(enum_attr->symbols[1].symbol.name.value().entry, Eq("bat"));
   EXPECT_THAT(enum_attr->symbols[1].value, Eq(1u));
+  EXPECT_THAT(enum_attr->symbols[1].type, Eq(Res_value::TYPE_INT_HEX));
 
   ASSERT_TRUE(enum_attr->symbols[2].symbol.name);
   EXPECT_THAT(enum_attr->symbols[2].symbol.name.value().entry, Eq("baz"));
   EXPECT_THAT(enum_attr->symbols[2].value, Eq(2u));
+  EXPECT_THAT(enum_attr->symbols[2].type, Eq(Res_value::TYPE_INT_DEC));
 }
 
 TEST_F(ResourceParserTest, ParseFlagAttr) {
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index e0040e4..bd2ab53 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -378,7 +378,7 @@
     const ResourceName& enum_symbol_resource_name = symbol.symbol.name.value();
     if (trimmed_str == enum_symbol_resource_name.entry) {
       android::Res_value value = {};
-      value.dataType = android::Res_value::TYPE_INT_DEC;
+      value.dataType = symbol.type;
       value.data = symbol.value;
       return util::make_unique<BinaryPrimitive>(value);
     }
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index 168ad61..fe0883b 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -292,6 +292,7 @@
   struct Symbol {
     Reference symbol;
     uint32_t value;
+    uint8_t type;
 
     friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol);
   };
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index b2fc084..7498e13 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -21,7 +21,6 @@
 package aapt.pb;
 
 option java_package = "com.android.aapt";
-option optimize_for = LITE_RUNTIME;
 
 // A string pool that wraps the binary form of the C++ class android::ResStringPool.
 message StringPool {
@@ -388,6 +387,9 @@
 
     // The value of the enum/flag.
     uint32 value = 4;
+
+    // The data type of the enum/flag as defined in android::Res_value.
+    uint32 type = 5;
   }
 
   // Bitmask of formats allowed for an attribute.
diff --git a/tools/aapt2/ResourcesInternal.proto b/tools/aapt2/ResourcesInternal.proto
index 520b242..b0ed3da3 100644
--- a/tools/aapt2/ResourcesInternal.proto
+++ b/tools/aapt2/ResourcesInternal.proto
@@ -22,7 +22,6 @@
 package aapt.pb.internal;
 
 option java_package = "android.aapt.pb.internal";
-option optimize_for = LITE_RUNTIME;
 
 // The top level message representing an external resource file (layout XML, PNG, etc).
 // This is used to represent a compiled file before it is linked. Only useful to aapt2.
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 9b81369f..c7ac438 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -629,6 +629,12 @@
     return 0;
   }
 
+  const std::set<std::string>& GetSplitNameDependencies() override {
+    UNIMPLEMENTED(FATAL) << "No Split Name Dependencies be needed in compile phase";
+    static std::set<std::string> empty;
+    return empty;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(CompileContext);
 
diff --git a/tools/aapt2/cmd/Compile_test.cpp b/tools/aapt2/cmd/Compile_test.cpp
index 5f637bd..fb786a3 100644
--- a/tools/aapt2/cmd/Compile_test.cpp
+++ b/tools/aapt2/cmd/Compile_test.cpp
@@ -200,7 +200,7 @@
   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));
+  ctf->WriteFile(source_file, sTranslatableXmlContent);
   CHECK(file::mkdirs(compiled_files_dir.data()));
 
   ASSERT_EQ(CompileCommand(&diag).Execute({
diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp
index 0cf86cc..22bcd85 100644
--- a/tools/aapt2/cmd/Convert.cpp
+++ b/tools/aapt2/cmd/Convert.cpp
@@ -243,6 +243,12 @@
     return 0u;
   }
 
+  const std::set<std::string>& GetSplitNameDependencies() override {
+    UNIMPLEMENTED(FATAL) << "Split Name Dependencies should not be necessary";
+    static std::set<std::string> empty;
+    return empty;
+  }
+
   bool verbose_ = false;
   std::string package_;
 
diff --git a/tools/aapt2/cmd/Convert_test.cpp b/tools/aapt2/cmd/Convert_test.cpp
index ddc146c..f35237e 100644
--- a/tools/aapt2/cmd/Convert_test.cpp
+++ b/tools/aapt2/cmd/Convert_test.cpp
@@ -132,7 +132,7 @@
   int count = 0;
 
   // Can't pass nullptrs into Next()
-  ZipString zip_name;
+  std::string zip_name;
   ZipEntry zip_data;
 
   while ((result = Next(cookie, &zip_data, &zip_name)) == 0) {
diff --git a/tools/aapt2/cmd/Diff.cpp b/tools/aapt2/cmd/Diff.cpp
index 262f4fc4e..d56994e 100644
--- a/tools/aapt2/cmd/Diff.cpp
+++ b/tools/aapt2/cmd/Diff.cpp
@@ -65,6 +65,12 @@
     return 0;
   }
 
+  const std::set<std::string>& GetSplitNameDependencies() override {
+    UNIMPLEMENTED(FATAL) << "Split Name Dependencies should not be necessary";
+    static std::set<std::string> empty;
+    return empty;
+  }
+
  private:
   std::string empty_;
   StdErrDiagnostics diagnostics_;
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index a23a6a4..429aff1 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -118,6 +118,12 @@
     return 0;
   }
 
+  const std::set<std::string>& GetSplitNameDependencies() override {
+    UNIMPLEMENTED(FATAL) << "Split Name Dependencies should not be necessary";
+    static std::set<std::string> empty;
+    return empty;
+  }
+
  private:
   StdErrDiagnostics diagnostics_;
   bool verbose_ = false;
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index f354bb6..bbf71e7 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -140,6 +140,14 @@
     min_sdk_version_ = minSdk;
   }
 
+  const std::set<std::string>& GetSplitNameDependencies() override {
+    return split_name_dependencies_;
+  }
+
+  void SetSplitNameDependencies(const std::set<std::string>& split_name_dependencies) {
+    split_name_dependencies_ = split_name_dependencies;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(LinkContext);
 
@@ -151,6 +159,7 @@
   SymbolTable symbols_;
   bool verbose_ = false;
   int min_sdk_version_ = 0;
+  std::set<std::string> split_name_dependencies_;
 };
 
 // A custom delegate that generates compatible pre-O IDs for use with feature splits.
@@ -269,6 +278,7 @@
   bool keep_raw_values = false;
   bool do_not_compress_anything = false;
   bool update_proguard_spec = false;
+  bool do_not_fail_on_missing_resources = false;
   OutputFormat output_format = OutputFormat::kApk;
   std::unordered_set<std::string> extensions_to_not_compress;
   Maybe<std::regex> regex_to_not_compress;
@@ -297,6 +307,25 @@
   };
 };
 
+template <typename T>
+uint32_t GetCompressionFlags(const StringPiece& str, T options) {
+  if (options.do_not_compress_anything) {
+    return 0;
+  }
+
+  if (options.regex_to_not_compress
+      && std::regex_search(str.to_string(), options.regex_to_not_compress.value())) {
+    return 0;
+  }
+
+  for (const std::string& extension : options.extensions_to_not_compress) {
+    if (util::EndsWith(str, extension)) {
+      return 0;
+    }
+  }
+  return ArchiveEntry::kCompress;
+}
+
 class ResourceFileFlattener {
  public:
   ResourceFileFlattener(const ResourceFileFlattenerOptions& options, IAaptContext* context,
@@ -321,8 +350,6 @@
     std::string dst_path;
   };
 
-  uint32_t GetCompressionFlags(const StringPiece& str);
-
   std::vector<std::unique_ptr<xml::XmlResource>> LinkAndVersionXmlFile(ResourceTable* table,
                                                                        FileOperation* file_op);
 
@@ -381,26 +408,6 @@
   }
 }
 
-// TODO(rtmitchell): turn this function into a variable that points to a method that retrieves the
-// compression flag
-uint32_t ResourceFileFlattener::GetCompressionFlags(const StringPiece& str) {
-  if (options_.do_not_compress_anything) {
-    return 0;
-  }
-
-  if (options_.regex_to_not_compress
-      && std::regex_search(str.to_string(), options_.regex_to_not_compress.value())) {
-    return 0;
-  }
-
-  for (const std::string& extension : options_.extensions_to_not_compress) {
-    if (util::EndsWith(str, extension)) {
-      return 0;
-    }
-  }
-  return ArchiveEntry::kCompress;
-}
-
 static bool IsTransitionElement(const std::string& name) {
   return name == "fade" || name == "changeBounds" || name == "slide" || name == "explode" ||
          name == "changeImageTransform" || name == "changeTransform" ||
@@ -438,7 +445,7 @@
   xml::StripAndroidStudioAttributes(doc->root.get());
 
   XmlReferenceLinker xml_linker;
-  if (!xml_linker.Consume(context_, doc)) {
+  if (!options_.do_not_fail_on_missing_resources && !xml_linker.Consume(context_, doc)) {
     return {};
   }
 
@@ -640,7 +647,8 @@
           }
         } else {
           error |= !io::CopyFileToArchive(context_, file_op.file_to_copy, file_op.dst_path,
-                                          GetCompressionFlags(file_op.dst_path), archive_writer);
+                                          GetCompressionFlags(file_op.dst_path, options_),
+                                          archive_writer);
         }
       }
     }
@@ -965,6 +973,17 @@
         app_info.min_sdk_version = ResourceUtils::ParseSdkVersion(min_sdk->value);
       }
     }
+
+    for (const xml::Element* child_el : manifest_el->GetChildElements()) {
+      if (child_el->namespace_uri.empty() && child_el->name == "uses-split") {
+        if (const xml::Attribute* split_name =
+            child_el->FindAttribute(xml::kSchemaAndroid, "name")) {
+          if (!split_name->value.empty()) {
+            app_info.split_name_dependencies.insert(split_name->value);
+          }
+        }
+      }
+    }
     return app_info;
   }
 
@@ -1547,16 +1566,7 @@
     }
 
     for (auto& entry : merged_assets) {
-      uint32_t compression_flags = ArchiveEntry::kCompress;
-      std::string extension = file::GetExtension(entry.first).to_string();
-
-      if (options_.do_not_compress_anything
-          || options_.extensions_to_not_compress.count(extension) > 0
-          || (options_.regex_to_not_compress
-              && std::regex_search(extension, options_.regex_to_not_compress.value()))) {
-        compression_flags = 0u;
-      }
-
+      uint32_t compression_flags = GetCompressionFlags(entry.first, options_);
       if (!io::CopyFileToArchive(context_, entry.second.get(), entry.first, compression_flags,
                                  writer)) {
         return false;
@@ -1565,6 +1575,93 @@
     return true;
   }
 
+  void AliasAdaptiveIcon(xml::XmlResource* manifest, ResourceTable* table) {
+    xml::Element* application = manifest->root->FindChild("", "application");
+    if (!application) {
+      return;
+    }
+
+    xml::Attribute* icon = application->FindAttribute(xml::kSchemaAndroid, "icon");
+    xml::Attribute* round_icon = application->FindAttribute(xml::kSchemaAndroid, "roundIcon");
+    if (!icon || !round_icon) {
+      return;
+    }
+
+    // Find the icon resource defined within the application.
+    auto icon_reference = ValueCast<Reference>(icon->compiled_value.get());
+    if (!icon_reference || !icon_reference->name) {
+      return;
+    }
+    auto package = table->FindPackageById(icon_reference->id.value().package_id());
+    if (!package) {
+      return;
+    }
+    auto type = package->FindType(icon_reference->name.value().type);
+    if (!type) {
+      return;
+    }
+    auto icon_entry = type->FindEntry(icon_reference->name.value().entry);
+    if (!icon_entry) {
+      return;
+    }
+
+    int icon_max_sdk = 0;
+    for (auto& config_value : icon_entry->values) {
+      icon_max_sdk = (icon_max_sdk < config_value->config.sdkVersion)
+          ? config_value->config.sdkVersion : icon_max_sdk;
+    }
+    if (icon_max_sdk < SDK_O) {
+      // Adaptive icons must be versioned with v26 qualifiers, so this is not an adaptive icon.
+      return;
+    }
+
+    // Find the roundIcon resource defined within the application.
+    auto round_icon_reference = ValueCast<Reference>(round_icon->compiled_value.get());
+    if (!round_icon_reference || !round_icon_reference->name) {
+      return;
+    }
+    package = table->FindPackageById(round_icon_reference->id.value().package_id());
+    if (!package) {
+      return;
+    }
+    type = package->FindType(round_icon_reference->name.value().type);
+    if (!type) {
+      return;
+    }
+    auto round_icon_entry = type->FindEntry(round_icon_reference->name.value().entry);
+    if (!round_icon_entry) {
+      return;
+    }
+
+    int round_icon_max_sdk = 0;
+    for (auto& config_value : round_icon_entry->values) {
+      round_icon_max_sdk = (round_icon_max_sdk < config_value->config.sdkVersion)
+                     ? config_value->config.sdkVersion : round_icon_max_sdk;
+    }
+    if (round_icon_max_sdk >= SDK_O) {
+      // The developer explicitly used a v26 compatible drawable as the roundIcon, meaning we should
+      // not generate an alias to the icon drawable.
+      return;
+    }
+
+    // Add an equivalent v26 entry to the roundIcon for each v26 variant of the regular icon.
+    for (auto& config_value : icon_entry->values) {
+      if (config_value->config.sdkVersion < SDK_O) {
+        continue;
+      }
+
+      context_->GetDiagnostics()->Note(DiagMessage() << "generating "
+                                                     << round_icon_reference->name.value()
+                                                     << " with config \"" << config_value->config
+                                                     << "\" for round icon compatibility");
+
+      auto value = icon_reference->Clone(&table->string_pool);
+      auto round_config_value = round_icon_entry->FindOrCreateValue(
+          config_value->config, config_value->product);
+      round_config_value->value.reset(value);
+    }
+  }
+
   // Writes the AndroidManifest, ResourceTable, and all XML files referenced by the ResourceTable
   // to the IArchiveWriter.
   bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest,
@@ -1578,6 +1675,14 @@
       return false;
     }
 
+    // When a developer specifies an adaptive application icon, and a non-adaptive round application
+    // icon, create an alias from the round icon to the regular icon for v26 APIs and up. We do this
+    // because certain devices prefer android:roundIcon over android:icon regardless of the API
+    // levels of the drawables set for either. This auto-aliasing behaviour allows an app to prefer
+    // the android:roundIcon on API 25 devices, and prefer the adaptive icon on API 26 devices.
+    // See (b/34829129)
+    AliasAdaptiveIcon(manifest, table);
+
     ResourceFileFlattenerOptions file_flattener_options;
     file_flattener_options.keep_raw_values = keep_raw_values;
     file_flattener_options.do_not_compress_anything = options_.do_not_compress_anything;
@@ -1590,9 +1695,9 @@
     file_flattener_options.update_proguard_spec =
         static_cast<bool>(options_.generate_proguard_rules_path);
     file_flattener_options.output_format = options_.output_format;
+    file_flattener_options.do_not_fail_on_missing_resources = options_.merge_only;
 
     ResourceFileFlattener file_flattener(file_flattener_options, context_, keep_set);
-
     if (!file_flattener.Flatten(table, writer)) {
       context_->GetDiagnostics()->Error(DiagMessage() << "failed linking file resources");
       return false;
@@ -1687,6 +1792,7 @@
     context_->SetMinSdkVersion(app_info_.min_sdk_version.value_or_default(0));
 
     context_->SetNameManglerPolicy(NameManglerPolicy{context_->GetCompilationPackage()});
+    context_->SetSplitNameDependencies(app_info_.split_name_dependencies);
 
     // Override the package ID when it is "android".
     if (context_->GetCompilationPackage() == "android") {
@@ -1702,6 +1808,8 @@
 
     TableMergerOptions table_merger_options;
     table_merger_options.auto_add_overlay = options_.auto_add_overlay;
+    table_merger_options.override_styles_instead_of_overlaying =
+        options_.override_styles_instead_of_overlaying;
     table_merger_options.strict_visibility = options_.strict_visibility;
     table_merger_ = util::make_unique<TableMerger>(context_, &final_table_, table_merger_options);
 
@@ -1816,7 +1924,7 @@
     }
 
     ReferenceLinker linker;
-    if (!linker.Consume(context_, &final_table_)) {
+    if (!options_.merge_only && !linker.Consume(context_, &final_table_)) {
       context_->GetDiagnostics()->Error(DiagMessage() << "failed linking references");
       return 1;
     }
@@ -1968,7 +2076,7 @@
       manifest_xml->file.name.package = context_->GetCompilationPackage();
 
       XmlReferenceLinker manifest_linker;
-      if (manifest_linker.Consume(context_, manifest_xml.get())) {
+      if (options_.merge_only || manifest_linker.Consume(context_, manifest_xml.get())) {
         if (options_.generate_proguard_rules_path &&
             !proguard::CollectProguardRulesForManifest(manifest_xml.get(), &proguard_keep_set)) {
           error = true;
@@ -2102,6 +2210,12 @@
     return 1;
   }
 
+  if (options_.merge_only && !static_lib_) {
+    context.GetDiagnostics()->Error(
+        DiagMessage() << "the --merge-only flag can be only used when building a static library");
+    return 1;
+  }
+
   // The default build type.
   context.SetPackageType(PackageType::kApp);
   context.SetPackageId(kAppPackageId);
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index 7c58385..324807c 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -42,6 +42,7 @@
   std::vector<std::string> assets_dirs;
   bool output_to_directory = false;
   bool auto_add_overlay = false;
+  bool override_styles_instead_of_overlaying = false;
   OutputFormat output_format = OutputFormat::kApk;
 
   // Java/Proguard options.
@@ -70,6 +71,7 @@
 
   // Static lib options.
   bool no_static_lib_packages = false;
+  bool merge_only = false;
 
   // AndroidManifest.xml massaging options.
   ManifestFixerOptions manifest_fixer_options;
@@ -242,13 +244,17 @@
         "Allows the addition of new resources in overlays without\n"
             "<add-resource> tags.",
         &options_.auto_add_overlay);
+    AddOptionalSwitch("--override-styles-instead-of-overlaying",
+                      "Causes styles defined in -R resources to replace previous definitions\n"
+                      "instead of merging into them\n",
+                      &options_.override_styles_instead_of_overlaying);
     AddOptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml.",
         &options_.manifest_fixer_options.rename_manifest_package);
     AddOptionalFlag("--rename-instrumentation-target-package",
         "Changes the name of the target package for instrumentation. Most useful\n"
             "when used in conjunction with --rename-manifest-package.",
         &options_.manifest_fixer_options.rename_instrumentation_target_package);
-    AddOptionalFlagList("-0", "File extensions not to compress.",
+    AddOptionalFlagList("-0", "File suffix not to compress.",
         &options_.extensions_to_not_compress);
     AddOptionalSwitch("--no-compress", "Do not compress any resources.",
         &options_.do_not_compress_anything);
@@ -280,6 +286,10 @@
     AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
     AddOptionalFlag("--trace-folder", "Generate systrace json trace fragment to specified folder.",
                     &trace_folder_);
+    AddOptionalSwitch("--merge-only",
+          "Only merge the resources, without verifying resource references. This flag\n"
+          "should only be used together with the --static-lib flag.",
+          &options_.merge_only);
   }
 
   int Action(const std::vector<std::string>& args) override;
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index 9ea93f6..062dd8e 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "AppInfo.h"
 #include "Link.h"
 
 #include "LoadedApk.h"
@@ -43,10 +44,8 @@
   // Load the binary xml tree
   android::ResXMLTree tree;
   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
-
   std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml");
   ASSERT_THAT(data, Ne(nullptr));
-
   AssertLoadXml(apk.get(), data.get(), &tree);
 
   // Check that the raw string index has not been assigned
@@ -71,10 +70,8 @@
   // Load the binary xml tree
   android::ResXMLTree tree;
   std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
-
   std::unique_ptr<io::IData> data = OpenFileAsData(apk.get(), "res/xml/test.xml");
   ASSERT_THAT(data, Ne(nullptr));
-
   AssertLoadXml(apk.get(), data.get(), &tree);
 
   // Check that the raw string index has been set to the correct string pool entry
@@ -83,4 +80,241 @@
   EXPECT_THAT(util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)), Eq("007"));
 }
 
-}  // namespace aapt
\ No newline at end of file
+TEST_F(LinkTest, NoCompressAssets) {
+  StdErrDiagnostics diag;
+  std::string content(500, 'a');
+  WriteFile(GetTestPath("assets/testtxt"), content);
+  WriteFile(GetTestPath("assets/testtxt2"), content);
+  WriteFile(GetTestPath("assets/test.txt"), content);
+  WriteFile(GetTestPath("assets/test.hello.txt"), content);
+  WriteFile(GetTestPath("assets/test.hello.xml"), content);
+
+  const std::string out_apk = GetTestPath("out.apk");
+  std::vector<std::string> link_args = {
+      "--manifest", GetDefaultManifest(),
+      "-o", out_apk,
+      "-0", ".txt",
+      "-0", "txt2",
+      "-0", ".hello.txt",
+      "-0", "hello.xml",
+      "-A", GetTestPath("assets")
+  };
+
+  ASSERT_TRUE(Link(link_args, &diag));
+
+  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  ASSERT_THAT(apk, Ne(nullptr));
+  io::IFileCollection* zip = apk->GetFileCollection();
+  ASSERT_THAT(zip, Ne(nullptr));
+
+  auto file = zip->FindFile("assets/testtxt");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_TRUE(file->WasCompressed());
+
+  file = zip->FindFile("assets/testtxt2");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_FALSE(file->WasCompressed());
+
+  file = zip->FindFile("assets/test.txt");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_FALSE(file->WasCompressed());
+
+  file = zip->FindFile("assets/test.hello.txt");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_FALSE(file->WasCompressed());
+
+  file = zip->FindFile("assets/test.hello.xml");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_FALSE(file->WasCompressed());
+}
+
+TEST_F(LinkTest, NoCompressResources) {
+  StdErrDiagnostics diag;
+  std::string content(500, 'a');
+  const std::string compiled_files_dir = GetTestPath("compiled");
+  ASSERT_TRUE(CompileFile(GetTestPath("res/raw/testtxt"), content, compiled_files_dir, &diag));
+  ASSERT_TRUE(CompileFile(GetTestPath("res/raw/test.txt"), content, compiled_files_dir, &diag));
+  ASSERT_TRUE(CompileFile(GetTestPath("res/raw/test1.hello.txt"), content, compiled_files_dir,
+              &diag));
+  ASSERT_TRUE(CompileFile(GetTestPath("res/raw/test2.goodbye.xml"), content, compiled_files_dir,
+              &diag));
+
+  const std::string out_apk = GetTestPath("out.apk");
+  std::vector<std::string> link_args = {
+      "--manifest", GetDefaultManifest(),
+      "-o", out_apk,
+      "-0", ".txt",
+      "-0", ".hello.txt",
+      "-0", "goodbye.xml",
+  };
+
+  ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
+
+  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  ASSERT_THAT(apk, Ne(nullptr));
+  io::IFileCollection* zip = apk->GetFileCollection();
+  ASSERT_THAT(zip, Ne(nullptr));
+
+  auto file = zip->FindFile("res/raw/testtxt");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_TRUE(file->WasCompressed());
+
+  file = zip->FindFile("res/raw/test.txt");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_FALSE(file->WasCompressed());
+
+  file = zip->FindFile("res/raw/test1.hello.hello.txt");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_FALSE(file->WasCompressed());
+
+  file = zip->FindFile("res/raw/test2.goodbye.goodbye.xml");
+  ASSERT_THAT(file, Ne(nullptr));
+  EXPECT_FALSE(file->WasCompressed());
+}
+
+TEST_F(LinkTest, OverlayStyles) {
+  StdErrDiagnostics diag;
+  const std::string compiled_files_dir = GetTestPath("compiled");
+  const std::string override_files_dir = GetTestPath("compiled-override");
+  ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
+                          R"(<resources>
+                               <style name="MyStyle">
+                                 <item name="android:textColor">#123</item>
+                               </style>
+                             </resources>)",
+                          compiled_files_dir, &diag));
+  ASSERT_TRUE(CompileFile(GetTestPath("res/values/values-override.xml"),
+                          R"(<resources>
+                               <style name="MyStyle">
+                                 <item name="android:background">#456</item>
+                               </style>
+                             </resources>)",
+                          override_files_dir, &diag));
+
+
+  const std::string out_apk = GetTestPath("out.apk");
+  std::vector<std::string> link_args = {
+      "--manifest", GetDefaultManifest(kDefaultPackageName),
+      "-o", out_apk,
+  };
+  const auto override_files = file::FindFiles(override_files_dir, &diag);
+  for (const auto &override_file : override_files.value()) {
+      link_args.push_back("-R");
+      link_args.push_back(file::BuildPath({override_files_dir, override_file}));
+  }
+  ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
+
+  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  const Style* actual_style = test::GetValue<Style>(
+      apk->GetResourceTable(), std::string(kDefaultPackageName) + ":style/MyStyle");
+  ASSERT_NE(actual_style, nullptr);
+  ASSERT_EQ(actual_style->entries.size(), 2);
+  EXPECT_EQ(actual_style->entries[0].key.id, 0x01010098);  // android:textColor
+  EXPECT_EQ(actual_style->entries[1].key.id, 0x010100d4);  // android:background
+}
+
+TEST_F(LinkTest, OverrideStylesInsteadOfOverlaying) {
+  StdErrDiagnostics diag;
+  const std::string compiled_files_dir = GetTestPath("compiled");
+  const std::string override_files_dir = GetTestPath("compiled-override");
+  ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
+                          R"(<resources>
+                               <style name="MyStyle">
+                                 <item name="android:textColor">#123</item>
+                               </style>
+                             </resources>)",
+                          compiled_files_dir, &diag));
+  ASSERT_TRUE(CompileFile(GetTestPath("res/values/values-override.xml"),
+                          R"(<resources>
+                               <style name="MyStyle">
+                                 <item name="android:background">#456</item>
+                               </style>
+                             </resources>)",
+                          override_files_dir, &diag));
+
+
+  const std::string out_apk = GetTestPath("out.apk");
+  std::vector<std::string> link_args = {
+      "--manifest", GetDefaultManifest(kDefaultPackageName),
+      "--override-styles-instead-of-overlaying",
+      "-o", out_apk,
+  };
+  const auto override_files = file::FindFiles(override_files_dir, &diag);
+  for (const auto &override_file : override_files.value()) {
+      link_args.push_back("-R");
+      link_args.push_back(file::BuildPath({override_files_dir, override_file}));
+  }
+  ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));
+
+  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  const Style* actual_style = test::GetValue<Style>(
+      apk->GetResourceTable(), std::string(kDefaultPackageName) + ":style/MyStyle");
+  ASSERT_NE(actual_style, nullptr);
+  ASSERT_EQ(actual_style->entries.size(), 1);
+  EXPECT_EQ(actual_style->entries[0].key.id, 0x010100d4);  // android:background
+}
+
+TEST_F(LinkTest, AppInfoWithUsesSplit) {
+  StdErrDiagnostics diag;
+  const std::string base_files_dir = GetTestPath("base");
+  ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
+                          R"(<resources>
+                               <string name="bar">bar</string>
+                             </resources>)",
+                          base_files_dir, &diag));
+  const std::string base_apk = GetTestPath("base.apk");
+  std::vector<std::string> link_args = {
+      "--manifest", GetDefaultManifest("com.aapt2.app"),
+      "-o", base_apk,
+  };
+  ASSERT_TRUE(Link(link_args, base_files_dir, &diag));
+
+  const std::string feature_manifest = GetTestPath("feature_manifest.xml");
+  WriteFile(feature_manifest, android::base::StringPrintf(R"(
+      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.aapt2.app" split="feature1">
+      </manifest>)"));
+  const std::string feature_files_dir = GetTestPath("feature");
+  ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
+                          R"(<resources>
+                               <string name="foo">foo</string>
+                             </resources>)",
+                          feature_files_dir, &diag));
+  const std::string feature_apk = GetTestPath("feature.apk");
+  const std::string feature_package_id = "0x80";
+  link_args = {
+      "--manifest", feature_manifest,
+      "-I", base_apk,
+      "--package-id", feature_package_id,
+      "-o", feature_apk,
+  };
+  ASSERT_TRUE(Link(link_args, feature_files_dir, &diag));
+
+  const std::string feature2_manifest = GetTestPath("feature2_manifest.xml");
+  WriteFile(feature2_manifest, android::base::StringPrintf(R"(
+        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+            package="com.aapt2.app" split="feature2">
+          <uses-split android:name="feature1"/>
+        </manifest>)"));
+  const std::string feature2_files_dir = GetTestPath("feature2");
+  ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"),
+                          R"(<resources>
+                               <string-array name="string_array">
+                                 <item>@string/bar</item>
+                                 <item>@string/foo</item>
+                               </string-array>
+                             </resources>)",
+                          feature2_files_dir, &diag));
+  const std::string feature2_apk = GetTestPath("feature2.apk");
+  const std::string feature2_package_id = "0x81";
+  link_args = {
+      "--manifest", feature2_manifest,
+      "-I", base_apk,
+      "-I", feature_apk,
+      "--package-id", feature2_package_id,
+      "-o", feature2_apk,
+  };
+  ASSERT_TRUE(Link(link_args, feature2_files_dir, &diag));
+}
+
+}  // namespace aapt
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index 2e6af18..5e06818 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -108,6 +108,12 @@
     return sdk_version_;
   }
 
+  const std::set<std::string>& GetSplitNameDependencies() override {
+    UNIMPLEMENTED(FATAL) << "Split Name Dependencies should not be necessary";
+    static std::set<std::string> empty;
+    return empty;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(OptimizeContext);
 
diff --git a/tools/aapt2/cmd/Optimize.h b/tools/aapt2/cmd/Optimize.h
index 7f4a3ed..0be7dad 100644
--- a/tools/aapt2/cmd/Optimize.h
+++ b/tools/aapt2/cmd/Optimize.h
@@ -57,7 +57,7 @@
   std::unordered_set<std::string> kept_artifacts;
 
   // Whether or not to shorten resource paths in the APK.
-  bool shorten_resource_paths;
+  bool shorten_resource_paths = false;
 
   // Path to the output map of original resource paths to shortened paths.
   Maybe<std::string> shortened_paths_map_path;
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index c5de9e0..5e0300b 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -231,7 +231,7 @@
       Visitor sub_visitor(pool_, method_);
       if (plural->values[i]) {
         plural->values[i]->Accept(&sub_visitor);
-        if (sub_visitor.value) {
+        if (sub_visitor.item) {
           localized->values[i] = std::move(sub_visitor.item);
         } else {
           localized->values[i] = std::unique_ptr<Item>(plural->values[i]->Clone(pool_));
diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
index 3135802..e816c86 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
@@ -234,6 +234,27 @@
                                             test::ParseConfigOrDie("ar-rXB")));
 }
 
+TEST(PseudolocaleGeneratorTest, PluralsArePseudolocalized) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder().SetPackageId("com.pkg", 0x7F).Build();
+  std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+  plural->values = {util::make_unique<String>(table->string_pool.MakeRef("zero")),
+                    util::make_unique<String>(table->string_pool.MakeRef("one"))};
+  ASSERT_TRUE(table->AddResource(test::ParseNameOrDie("com.pkg:plurals/foo"), ConfigDescription{},
+                                 {}, std::move(plural), context->GetDiagnostics()));
+  std::unique_ptr<Plural> expected = util::make_unique<Plural>();
+  expected->values = {util::make_unique<String>(table->string_pool.MakeRef("[žéŕö one]")),
+                      util::make_unique<String>(table->string_pool.MakeRef("[öñé one]"))};
+
+  PseudolocaleGenerator generator;
+  ASSERT_TRUE(generator.Consume(context.get(), table.get()));
+
+  const auto* actual = test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo",
+                                                       test::ParseConfigOrDie("en-rXA"));
+  EXPECT_TRUE(actual->Equals(expected.get()));
+}
+
 TEST(PseudolocaleGeneratorTest, RespectUntranslateableSections) {
   std::unique_ptr<IAaptContext> context =
       test::ContextBuilder().SetCompilationPackage("android").Build();
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index 92f1ddb..54f0816 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -291,7 +291,10 @@
             }
           }
         }
-        return &attr->value;
+
+        if (!attr->value.empty()) {
+          return &attr->value;
+        }
       }
       return nullptr;
     }
@@ -425,6 +428,8 @@
   const std::string* split = nullptr;
   const std::string* platformVersionName = nullptr;
   const std::string* platformVersionCode = nullptr;
+  const int32_t* platformVersionNameInt = nullptr;
+  const int32_t* platformVersionCodeInt = nullptr;
   const int32_t* compilesdkVersion = nullptr;
   const std::string* compilesdkVersionCodename = nullptr;
   const int32_t* installLocation = nullptr;
@@ -440,6 +445,10 @@
                                                            "platformBuildVersionName"));
     platformVersionCode = GetAttributeString(FindAttribute(manifest, {},
                                                            "platformBuildVersionCode"));
+    platformVersionNameInt = GetAttributeInteger(FindAttribute(manifest, {},
+                                                               "platformBuildVersionName"));
+    platformVersionCodeInt = GetAttributeInteger(FindAttribute(manifest, {},
+                                                               "platformBuildVersionCode"));
 
     // Extract the compile sdk info
     compilesdkVersion = GetAttributeInteger(FindAttribute(manifest, COMPILE_SDK_VERSION_ATTR));
@@ -460,9 +469,15 @@
     if (platformVersionName) {
       printer->Print(StringPrintf(" platformBuildVersionName='%s'", platformVersionName->data()));
     }
+    if (platformVersionNameInt) {
+      printer->Print(StringPrintf(" platformBuildVersionName='%d'", *platformVersionNameInt));
+    }
     if (platformVersionCode) {
       printer->Print(StringPrintf(" platformBuildVersionCode='%s'", platformVersionCode->data()));
     }
+    if (platformVersionCodeInt) {
+      printer->Print(StringPrintf(" platformBuildVersionCode='%d'", *platformVersionCodeInt));
+    }
     if (compilesdkVersion) {
       printer->Print(StringPrintf(" compileSdkVersion='%d'", *compilesdkVersion));
     }
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index fd8e36e..fcd6aaa 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -614,6 +614,7 @@
     if (attr->type_mask & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) {
       Attribute::Symbol symbol;
       symbol.value = util::DeviceToHost32(map_entry.value.data);
+      symbol.type = map_entry.value.dataType;
       symbol.symbol = Reference(util::DeviceToHost32(map_entry.name.ident));
       attr->symbols.push_back(std::move(symbol));
     }
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index f2e72da..b932117 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -107,7 +107,7 @@
     }
 
     for (Attribute::Symbol& s : attr->symbols) {
-      BinaryPrimitive val(Res_value::TYPE_INT_DEC, s.value);
+      BinaryPrimitive val(s.type, s.value);
       FlattenEntry(&s.symbol, &val);
     }
   }
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index bb21c1c..efbf636 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -708,6 +708,8 @@
             return {};
           }
           symbol.value = pb_symbol.value();
+          symbol.type = pb_symbol.type() != 0U ? pb_symbol.type()
+                                               : android::Res_value::TYPE_INT_DEC;
           attr->symbols.push_back(std::move(symbol));
         }
         value = std::move(attr);
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index a54822b..aa6547e 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -552,6 +552,7 @@
       SerializeItemMetaDataToPb(symbol.symbol, pb_symbol, src_pool_);
       SerializeReferenceToPb(symbol.symbol, pb_symbol->mutable_name());
       pb_symbol->set_value(symbol.value);
+      pb_symbol->set_type(symbol.type);
     }
   }
 
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index f252f33..e7f2330 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -80,7 +80,7 @@
       test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 123u), context->GetDiagnostics()));
   ASSERT_TRUE(table->AddResource(
       test::ParseNameOrDie("com.app.a:integer/one"), test::ParseConfigOrDie("land"), "tablet",
-      test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 321u), context->GetDiagnostics()));
+      test::BuildPrimitive(android::Res_value::TYPE_INT_HEX, 321u), context->GetDiagnostics()));
 
   // Make a reference with both resource name and resource ID.
   // The reference should point to a resource outside of this table to test that both name and id
@@ -133,11 +133,13 @@
       &new_table, "com.app.a:integer/one", test::ParseConfigOrDie("land"), "");
   ASSERT_THAT(prim, NotNull());
   EXPECT_THAT(prim->value.data, Eq(123u));
+  EXPECT_THAT(prim->value.dataType, Eq(0x10));
 
   prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
       &new_table, "com.app.a:integer/one", test::ParseConfigOrDie("land"), "tablet");
   ASSERT_THAT(prim, NotNull());
   EXPECT_THAT(prim->value.data, Eq(321u));
+  EXPECT_THAT(prim->value.dataType, Eq(0x11));
 
   Reference* actual_ref = test::GetValue<Reference>(&new_table, "com.app.a:layout/abc");
   ASSERT_THAT(actual_ref, NotNull());
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/Android.mk b/tools/aapt2/integration-tests/MergeOnlyTest/Android.mk
new file mode 100644
index 0000000..6361f9b
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/App/Android.mk b/tools/aapt2/integration-tests/MergeOnlyTest/App/Android.mk
new file mode 100644
index 0000000..6bc2064
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/App/Android.mk
@@ -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.
+//
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_NAMESPACES := true
+LOCAL_PACKAGE_NAME := AaptTestMergeOnly_App
+LOCAL_SDK_VERSION := current
+LOCAL_EXPORT_PACKAGE_RESOURCES := true
+LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+    AaptTestMergeOnly_LeafLib \
+    AaptTestMergeOnly_LocalLib
+include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/App/AndroidManifest.xml b/tools/aapt2/integration-tests/MergeOnlyTest/App/AndroidManifest.xml
new file mode 100644
index 0000000..bc3a7e5
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/App/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.app">
+
+    <application
+        android:label="@*com.local.lib:string/lib_string"/>
+
+</manifest>
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/Android.mk b/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/Android.mk
new file mode 100644
index 0000000..7bf8cf8
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/Android.mk
@@ -0,0 +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.
+//
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_NAMESPACES := true
+LOCAL_MODULE := AaptTestMergeOnly_LeafLib
+LOCAL_SDK_VERSION := current
+LOCAL_MODULE_TAGS := tests
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MIN_SDK_VERSION := 21
+LOCAL_AAPT_FLAGS := --merge-only
+include $(BUILD_STATIC_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/AndroidManifest.xml b/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/AndroidManifest.xml
new file mode 100644
index 0000000..9907bd9
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?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 package="com.leaf.lib" />
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/res/layout/activity.xml b/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/res/layout/activity.xml
new file mode 100644
index 0000000..07de87f
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/res/layout/activity.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.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:leaf="http://schemas.android.com/apk/res/com.leaf.lib">
+
+    <TextView android:text="@string/leaf_string"
+        leaf:leaf_attr="hello"
+        style="@style/LeafChildStyle"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/res/values/values.xml b/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/res/values/values.xml
new file mode 100644
index 0000000..7f94c26
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LeafLib/res/values/values.xml
@@ -0,0 +1,43 @@
+<?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>
+    <attr format="string" name="leaf_attr"/>
+    <attr format="string" name="leaf_attr2"/>
+
+    <string name="leaf_string">I am a leaf</string>
+
+    <style name="LeafParentStyle">
+        <item type="attr" name="leaf_attr"/>
+        <item type="attr" name="leaf_attr2"/>
+    </style>
+
+    <style name="LeafChildStyle" parent="LeafParentStyle">
+        <item type="attr" name="leaf_attr2">hello</item>
+    </style>
+
+    <style name="LeafParentStyle.DottedChild"/>
+
+    <declare-styleable name="leaf_ds">
+        <attr name="leaf_attr">hello</attr>
+    </declare-styleable>
+
+    <public type="attr" name="leaf_attr"/>
+    <public type="attr" name="leaf_attr2"/>
+    <public type="style" name="LeafParentStyle"/>
+    <public type="style" name="LeafChildStyle"/>
+    <public type="style" name="LeafParentStyle.DottedChild"/>
+</resources>
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/Android.mk b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/Android.mk
new file mode 100644
index 0000000..ba781c5
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/Android.mk
@@ -0,0 +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.
+//
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_NAMESPACES := true
+LOCAL_MODULE := AaptTestMergeOnly_LocalLib
+LOCAL_SDK_VERSION := current
+LOCAL_MODULE_TAGS := tests
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_MIN_SDK_VERSION := 21
+LOCAL_AAPT_FLAGS := --merge-only
+include $(BUILD_STATIC_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/AndroidManifest.xml b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/AndroidManifest.xml
new file mode 100644
index 0000000..aa0ff5d
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?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.local.lib">
+
+    <application>
+
+    <activity
+        android:name="com.myapp.MyActivity"
+        android:theme="@com.leaf.lib:style/LeafParentStyle.DottedChild"/>
+
+    </application>
+
+</manifest>
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/layout/activity.xml b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/layout/activity.xml
new file mode 100644
index 0000000..80d2fd6
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/layout/activity.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.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:leaf="http://schemas.android.com/apk/res/com.leaf.lib">
+
+    <TextView android:text="@*com.leaf.lib:string/leaf_string"
+        leaf:leaf_attr="hello"
+        style="@com.leaf.lib:style/LeafChildStyle"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/layout/includer.xml b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/layout/includer.xml
new file mode 100644
index 0000000..f063718
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/layout/includer.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.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:leaf="http://schemas.android.com/apk/res/com.leaf.lib">
+
+    <include layout="@layout/activity"/>
+
+    <include layout="@*com.leaf.lib:layout/activity"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/values/values.xml b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/values/values.xml
new file mode 100644
index 0000000..2f9704d
--- /dev/null
+++ b/tools/aapt2/integration-tests/MergeOnlyTest/LocalLib/res/values/values.xml
@@ -0,0 +1,29 @@
+<?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>
+    <string name="lib_string">@*com.leaf.lib:string/leaf_string</string>
+
+    <style name="lib_style" parent="@com.leaf.lib:style/LeafChildStyle">
+        <item name="com.leaf.lib:leaf_attr">hello</item>
+    </style>
+
+    <style name="LeafParentStyle.DottedChild.LocalLibStyle" 
+        parent="@com.leaf.lib:style/LeafParentStyle.DottedChild"/>
+
+    <public type="style" name="LeafParentStyle.DottedChild.LocalLibStyle"/>
+
+</resources>
\ No newline at end of file
diff --git a/tools/aapt2/io/Util.cpp b/tools/aapt2/io/Util.cpp
index ce6d9352..bb925c9 100644
--- a/tools/aapt2/io/Util.cpp
+++ b/tools/aapt2/io/Util.cpp
@@ -58,7 +58,7 @@
   return CopyFileToArchive(context, file, out_path, compression_flags, writer);
 }
 
-bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* proto_msg,
+bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::Message* proto_msg,
                         const std::string& out_path, uint32_t compression_flags,
                         IArchiveWriter* writer) {
   TRACE_CALL();
diff --git a/tools/aapt2/io/Util.h b/tools/aapt2/io/Util.h
index 5f978a8..5cb8206 100644
--- a/tools/aapt2/io/Util.h
+++ b/tools/aapt2/io/Util.h
@@ -19,7 +19,7 @@
 
 #include <string>
 
-#include "google/protobuf/message_lite.h"
+#include "google/protobuf/message.h"
 #include "google/protobuf/io/coded_stream.h"
 
 #include "format/Archive.h"
@@ -39,7 +39,7 @@
 bool CopyFileToArchivePreserveCompression(IAaptContext* context, IFile* file,
                                           const std::string& out_path, IArchiveWriter* writer);
 
-bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* proto_msg,
+bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::Message* proto_msg,
                         const std::string& out_path, uint32_t compression_flags,
                         IArchiveWriter* writer);
 
@@ -127,13 +127,13 @@
  public:
   explicit ProtoInputStreamReader(io::InputStream* in) : in_(in) { }
 
-  /** Deserializes a MessageLite proto from the current position in the input stream.*/
-  template <typename T> bool ReadMessage(T *message_lite) {
+  /** Deserializes a Message proto from the current position in the input stream.*/
+  template <typename T> bool ReadMessage(T *message) {
     ZeroCopyInputAdaptor adapter(in_);
     google::protobuf::io::CodedInputStream coded_stream(&adapter);
     coded_stream.SetTotalBytesLimit(std::numeric_limits<int32_t>::max(),
                                     coded_stream.BytesUntilTotalBytesLimit());
-    return message_lite->ParseFromCodedStream(&coded_stream);
+    return message->ParseFromCodedStream(&coded_stream);
   }
 
  private:
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index a692ba5..4380586 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -123,13 +123,9 @@
   using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>;
   IterationEnder iteration_ender(cookie, EndIteration);
 
-  ZipString zip_entry_name;
+  std::string zip_entry_path;
   ZipEntry zip_data;
-  while ((result = Next(cookie, &zip_data, &zip_entry_name)) == 0) {
-    std::string zip_entry_path =
-        std::string(reinterpret_cast<const char*>(zip_entry_name.name),
-                    zip_entry_name.name_length);
-
+  while ((result = Next(cookie, &zip_data, &zip_entry_path)) == 0) {
     // Do not add folders to the file collection
     if (util::EndsWith(zip_entry_path, "/")) {
       continue;
diff --git a/tools/aapt2/java/ProguardRules.h b/tools/aapt2/java/ProguardRules.h
index f9656d1..b15df59 100644
--- a/tools/aapt2/java/ProguardRules.h
+++ b/tools/aapt2/java/ProguardRules.h
@@ -99,11 +99,13 @@
 //
 
 inline bool operator==(const UsageLocation& lhs, const UsageLocation& rhs) {
+  // The "source" member is ignored because we only need "name" for outputting
+  // keep rules; "source" is used for comments.
   return lhs.name == rhs.name;
 }
 
-inline int operator<(const UsageLocation& lhs, const UsageLocation& rhs) {
-  return lhs.name.compare(rhs.name);
+inline bool operator<(const UsageLocation& lhs, const UsageLocation& rhs) {
+  return lhs.name.compare(rhs.name) < 0;
 }
 
 //
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
index 559b07a..25b55ab 100644
--- a/tools/aapt2/java/ProguardRules_test.cpp
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -364,4 +364,12 @@
     "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
 }
 
+TEST(ProguardRulesTest, UsageLocationComparator) {
+  proguard::UsageLocation location1 = {{"pkg", ResourceType::kAttr, "x"}};
+  proguard::UsageLocation location2 = {{"pkg", ResourceType::kAttr, "y"}};
+
+  EXPECT_EQ(location1 < location2, true);
+  EXPECT_EQ(location2 < location1, false);
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 49909f6..11150dd 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -214,6 +214,33 @@
   return true;
 }
 
+// Ensure that 'ns_decls' contains a declaration for 'uri', using 'prefix' as
+// the xmlns prefix if possible.
+static void EnsureNamespaceIsDeclared(const std::string& prefix, const std::string& uri,
+                                      std::vector<xml::NamespaceDecl>* ns_decls) {
+  if (std::find_if(ns_decls->begin(), ns_decls->end(), [&](const xml::NamespaceDecl& ns_decl) {
+        return ns_decl.uri == uri;
+      }) != ns_decls->end()) {
+    return;
+  }
+
+  std::set<std::string> used_prefixes;
+  for (const auto& ns_decl : *ns_decls) {
+    used_prefixes.insert(ns_decl.prefix);
+  }
+
+  // Make multiple attempts in the unlikely event that 'prefix' is already taken.
+  std::string disambiguator;
+  for (int i = 0; i < used_prefixes.size() + 1; i++) {
+    std::string attempted_prefix = prefix + disambiguator;
+    if (used_prefixes.find(attempted_prefix) == used_prefixes.end()) {
+      ns_decls->push_back(xml::NamespaceDecl{attempted_prefix, uri});
+      return;
+    }
+    disambiguator = std::to_string(i);
+  }
+}
+
 bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
                                IDiagnostics* diag) {
   // First verify some options.
@@ -262,6 +289,8 @@
   manifest_action.Action(VerifyManifest);
   manifest_action.Action(FixCoreAppAttribute);
   manifest_action.Action([&](xml::Element* el) -> bool {
+    EnsureNamespaceIsDeclared("android", xml::kSchemaAndroid, &el->namespace_decls);
+
     if (options_.version_name_default) {
       if (options_.replace_version) {
         el->RemoveAttribute(xml::kSchemaAndroid, "versionName");
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 3f1ee36..3af06f5 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -727,8 +727,7 @@
 }
 
 TEST_F(ManifestFixerTest, InsertCompileSdkVersions) {
-  std::string input = R"(
-      <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android" />)";
+  std::string input = R"(<manifest package="com.pkg" />)";
   ManifestFixerOptions options;
   options.compile_sdk_version = {"28"};
   options.compile_sdk_version_codename = {"P"};
@@ -736,6 +735,12 @@
   std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
   ASSERT_THAT(manifest, NotNull());
 
+  // There should be a declaration of kSchemaAndroid, even when the input
+  // didn't have one.
+  EXPECT_EQ(manifest->root->namespace_decls.size(), 1);
+  EXPECT_EQ(manifest->root->namespace_decls[0].prefix, "android");
+  EXPECT_EQ(manifest->root->namespace_decls[0].uri, xml::kSchemaAndroid);
+
   xml::Attribute* attr = manifest->root->FindAttribute(xml::kSchemaAndroid, "compileSdkVersion");
   ASSERT_THAT(attr, NotNull());
   EXPECT_THAT(attr->value, StrEq("28"));
@@ -782,6 +787,27 @@
   EXPECT_THAT(attr->value, StrEq("P"));
 }
 
+TEST_F(ManifestFixerTest, AndroidPrefixAlreadyUsed) {
+  std::string input =
+      R"(<manifest package="com.pkg"
+         xmlns:android="http://schemas.android.com/apk/prv/res/android"
+         android:private_attr="foo" />)";
+  ManifestFixerOptions options;
+  options.compile_sdk_version = {"28"};
+  options.compile_sdk_version_codename = {"P"};
+
+  std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
+  ASSERT_THAT(manifest, NotNull());
+
+  // Make sure that we don't redefine "android".
+  EXPECT_EQ(manifest->root->namespace_decls.size(), 2);
+  EXPECT_EQ(manifest->root->namespace_decls[0].prefix, "android");
+  EXPECT_EQ(manifest->root->namespace_decls[0].uri,
+            "http://schemas.android.com/apk/prv/res/android");
+  EXPECT_EQ(manifest->root->namespace_decls[1].prefix, "android0");
+  EXPECT_EQ(manifest->root->namespace_decls[1].uri, xml::kSchemaAndroid);
+}
+
 TEST_F(ManifestFixerTest, UnexpectedElementsInManifest) {
   std::string input = R"(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 28f09aa..8e49fab 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -17,6 +17,7 @@
 #include "link/ReferenceLinker.h"
 
 #include "android-base/logging.h"
+#include "android-base/stringprintf.h"
 #include "androidfw/ResourceTypes.h"
 
 #include "Diagnostics.h"
@@ -33,6 +34,7 @@
 
 using ::aapt::ResourceUtils::StringBuilder;
 using ::android::StringPiece;
+using ::android::base::StringPrintf;
 
 namespace aapt {
 
@@ -81,7 +83,7 @@
 
       // Find the attribute in the symbol table and check if it is visible from this callsite.
       const SymbolTable::Symbol* symbol = ReferenceLinker::ResolveAttributeCheckVisibility(
-          transformed_reference, callsite_, symbols_, &err_str);
+          transformed_reference, callsite_, context_, symbols_, &err_str);
       if (symbol) {
         // Assign our style key the correct ID. The ID may not exist.
         entry.key.id = symbol->id;
@@ -203,12 +205,35 @@
 
 const SymbolTable::Symbol* ReferenceLinker::ResolveSymbol(const Reference& reference,
                                                           const CallSite& callsite,
+                                                          IAaptContext* context,
                                                           SymbolTable* symbols) {
   if (reference.name) {
     const ResourceName& name = reference.name.value();
     if (name.package.empty()) {
       // Use the callsite's package name if no package name was defined.
-      return symbols->FindByName(ResourceName(callsite.package, name.type, name.entry));
+      const SymbolTable::Symbol* symbol = symbols->FindByName(
+          ResourceName(callsite.package, name.type, name.entry));
+      if (symbol) {
+        return symbol;
+      }
+
+      // If the callsite package is the same as the current compilation package,
+      // check the feature split dependencies as well. Feature split resources
+      // can be referenced without a namespace, just like the base package.
+      // TODO: modify the package name of included splits instead of having the
+      // symbol table look up the resource in in every package. b/136105066
+      if (callsite.package == context->GetCompilationPackage()) {
+        const auto& split_name_dependencies = context->GetSplitNameDependencies();
+        for (const std::string& split_name : split_name_dependencies) {
+          std::string split_package =
+              StringPrintf("%s.%s", callsite.package.c_str(), split_name.c_str());
+          symbol = symbols->FindByName(ResourceName(split_package, name.type, name.entry));
+          if (symbol) {
+            return symbol;
+          }
+        }
+      }
+      return nullptr;
     }
     return symbols->FindByName(name);
   } else if (reference.id) {
@@ -220,9 +245,10 @@
 
 const SymbolTable::Symbol* ReferenceLinker::ResolveSymbolCheckVisibility(const Reference& reference,
                                                                          const CallSite& callsite,
+                                                                         IAaptContext* context,
                                                                          SymbolTable* symbols,
                                                                          std::string* out_error) {
-  const SymbolTable::Symbol* symbol = ResolveSymbol(reference, callsite, symbols);
+  const SymbolTable::Symbol* symbol = ResolveSymbol(reference, callsite, context, symbols);
   if (!symbol) {
     if (out_error) *out_error = "not found";
     return nullptr;
@@ -236,10 +262,10 @@
 }
 
 const SymbolTable::Symbol* ReferenceLinker::ResolveAttributeCheckVisibility(
-    const Reference& reference, const CallSite& callsite, SymbolTable* symbols,
-    std::string* out_error) {
+    const Reference& reference, const CallSite& callsite, IAaptContext* context,
+    SymbolTable* symbols, std::string* out_error) {
   const SymbolTable::Symbol* symbol =
-      ResolveSymbolCheckVisibility(reference, callsite, symbols, out_error);
+      ResolveSymbolCheckVisibility(reference, callsite, context, symbols, out_error);
   if (!symbol) {
     return nullptr;
   }
@@ -253,10 +279,11 @@
 
 Maybe<xml::AaptAttribute> ReferenceLinker::CompileXmlAttribute(const Reference& reference,
                                                                const CallSite& callsite,
+                                                               IAaptContext* context,
                                                                SymbolTable* symbols,
                                                                std::string* out_error) {
   const SymbolTable::Symbol* symbol =
-      ResolveAttributeCheckVisibility(reference, callsite, symbols, out_error);
+      ResolveAttributeCheckVisibility(reference, callsite, context, symbols, out_error);
   if (!symbol) {
     return {};
   }
@@ -335,7 +362,7 @@
 
   std::string err_str;
   const SymbolTable::Symbol* s =
-      ResolveSymbolCheckVisibility(transformed_reference, callsite, symbols, &err_str);
+      ResolveSymbolCheckVisibility(transformed_reference, callsite, context, symbols, &err_str);
   if (s) {
     // The ID may not exist. This is fine because of the possibility of building
     // against libraries without assigned IDs.
diff --git a/tools/aapt2/link/ReferenceLinker.h b/tools/aapt2/link/ReferenceLinker.h
index b0b4945..1256709 100644
--- a/tools/aapt2/link/ReferenceLinker.h
+++ b/tools/aapt2/link/ReferenceLinker.h
@@ -39,13 +39,16 @@
   // package if the reference has no package name defined (implicit).
   // Returns nullptr if the symbol was not found.
   static const SymbolTable::Symbol* ResolveSymbol(const Reference& reference,
-                                                  const CallSite& callsite, SymbolTable* symbols);
+                                                  const CallSite& callsite,
+                                                  IAaptContext* context,
+                                                  SymbolTable* symbols);
 
   // Performs name mangling and looks up the resource in the symbol table. If the symbol is not
   // visible by the reference at the callsite, nullptr is returned.
   // `out_error` holds the error message.
   static const SymbolTable::Symbol* ResolveSymbolCheckVisibility(const Reference& reference,
                                                                  const CallSite& callsite,
+                                                                 IAaptContext* context,
                                                                  SymbolTable* symbols,
                                                                  std::string* out_error);
 
@@ -53,6 +56,7 @@
   // That is, the return value will have a non-null value for ISymbolTable::Symbol::attribute.
   static const SymbolTable::Symbol* ResolveAttributeCheckVisibility(const Reference& reference,
                                                                     const CallSite& callsite,
+                                                                    IAaptContext* context,
                                                                     SymbolTable* symbols,
                                                                     std::string* out_error);
 
@@ -60,6 +64,7 @@
   // If resolution fails, outError holds the error message.
   static Maybe<xml::AaptAttribute> CompileXmlAttribute(const Reference& reference,
                                                        const CallSite& callsite,
+                                                       IAaptContext* context,
                                                        SymbolTable* symbols,
                                                        std::string* out_error);
 
diff --git a/tools/aapt2/link/ReferenceLinker_test.cpp b/tools/aapt2/link/ReferenceLinker_test.cpp
index be38b96..a31ce94 100644
--- a/tools/aapt2/link/ReferenceLinker_test.cpp
+++ b/tools/aapt2/link/ReferenceLinker_test.cpp
@@ -266,8 +266,13 @@
 
   std::string error;
   const CallSite call_site{"com.app.test"};
+  std::unique_ptr<IAaptContext> context =
+    test::ContextBuilder()
+        .SetCompilationPackage("com.app.test")
+        .SetPackageId(0x7f)
+        .Build();
   const SymbolTable::Symbol* symbol = ReferenceLinker::ResolveSymbolCheckVisibility(
-      *test::BuildReference("com.app.test:string/foo"), call_site, &table, &error);
+      *test::BuildReference("com.app.test:string/foo"), call_site, context.get(), &table, &error);
   ASSERT_THAT(symbol, NotNull());
   EXPECT_TRUE(error.empty());
 }
@@ -281,17 +286,23 @@
                          .AddPublicSymbol("com.app.test:attr/public_foo", ResourceId(0x7f010001),
                                           test::AttributeBuilder().Build())
                          .Build());
+  std::unique_ptr<IAaptContext> context =
+    test::ContextBuilder()
+        .SetCompilationPackage("com.app.ext")
+        .SetPackageId(0x7f)
+        .Build();
 
   std::string error;
   const CallSite call_site{"com.app.ext"};
 
   EXPECT_FALSE(ReferenceLinker::CompileXmlAttribute(
-      *test::BuildReference("com.app.test:attr/foo"), call_site, &table, &error));
+      *test::BuildReference("com.app.test:attr/foo"), call_site, context.get(), &table, &error));
   EXPECT_FALSE(error.empty());
 
   error = "";
   ASSERT_TRUE(ReferenceLinker::CompileXmlAttribute(
-      *test::BuildReference("com.app.test:attr/public_foo"), call_site, &table, &error));
+      *test::BuildReference("com.app.test:attr/public_foo"), call_site, context.get(), &table,
+      &error));
   EXPECT_TRUE(error.empty());
 }
 
@@ -302,20 +313,62 @@
                          .AddSymbol("com.app.test:string/foo", ResourceId(0x7f010000))
                          .AddSymbol("com.app.lib:string/foo", ResourceId(0x7f010001))
                          .Build());
+  std::unique_ptr<IAaptContext> context =
+    test::ContextBuilder()
+        .SetCompilationPackage("com.app.test")
+        .SetPackageId(0x7f)
+        .Build();
 
   const SymbolTable::Symbol* s = ReferenceLinker::ResolveSymbol(*test::BuildReference("string/foo"),
-                                                                CallSite{"com.app.test"}, &table);
+                                                                CallSite{"com.app.test"},
+                                                                context.get(), &table);
   ASSERT_THAT(s, NotNull());
   EXPECT_THAT(s->id, Eq(make_value<ResourceId>(0x7f010000)));
 
   s = ReferenceLinker::ResolveSymbol(*test::BuildReference("string/foo"), CallSite{"com.app.lib"},
-                                     &table);
+                                     context.get(), &table);
   ASSERT_THAT(s, NotNull());
   EXPECT_THAT(s->id, Eq(make_value<ResourceId>(0x7f010001)));
 
   EXPECT_THAT(ReferenceLinker::ResolveSymbol(*test::BuildReference("string/foo"),
-                                             CallSite{"com.app.bad"}, &table),
+                                             CallSite{"com.app.bad"}, context.get(), &table),
               IsNull());
 }
 
+TEST(ReferenceLinkerTest, ReferenceSymbolFromOtherSplit) {
+  NameMangler mangler(NameManglerPolicy{"com.app.test"});
+  SymbolTable table(&mangler);
+  table.AppendSource(test::StaticSymbolSourceBuilder()
+                         .AddSymbol("com.app.test.feature:string/bar", ResourceId(0x80010000))
+                         .Build());
+  std::set<std::string> split_name_dependencies;
+  split_name_dependencies.insert("feature");
+  std::unique_ptr<IAaptContext> context =
+      test::ContextBuilder()
+          .SetCompilationPackage("com.app.test")
+          .SetPackageId(0x81)
+          .SetSplitNameDependencies(split_name_dependencies)
+          .Build();
+
+  const SymbolTable::Symbol* s = ReferenceLinker::ResolveSymbol(*test::BuildReference("string/bar"),
+                                                                CallSite{"com.app.test"},
+                                                                context.get(), &table);
+  ASSERT_THAT(s, NotNull());
+  EXPECT_THAT(s->id, Eq(make_value<ResourceId>(0x80010000)));
+
+  s = ReferenceLinker::ResolveSymbol(*test::BuildReference("string/foo"), CallSite{"com.app.lib"},
+                                     context.get(), &table);
+  EXPECT_THAT(s, IsNull());
+
+  context =
+    test::ContextBuilder()
+        .SetCompilationPackage("com.app.test")
+        .SetPackageId(0x81)
+        .Build();
+  s = ReferenceLinker::ResolveSymbol(*test::BuildReference("string/bar"),CallSite{"com.app.test"},
+                                     context.get(), &table);
+
+  EXPECT_THAT(s, IsNull());
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index c0802e6..c25e450 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -172,19 +172,22 @@
 //
 // Styleables and Styles don't simply overlay each other, their definitions merge and accumulate.
 // If both values are Styleables/Styles, we just merge them into the existing value.
-static ResourceTable::CollisionResult ResolveMergeCollision(Value* existing, Value* incoming,
-                                                            StringPool* pool) {
+static ResourceTable::CollisionResult ResolveMergeCollision(
+    bool override_styles_instead_of_overlaying, Value* existing, Value* incoming,
+    StringPool* pool) {
   if (Styleable* existing_styleable = ValueCast<Styleable>(existing)) {
     if (Styleable* incoming_styleable = ValueCast<Styleable>(incoming)) {
       // Styleables get merged.
       existing_styleable->MergeWith(incoming_styleable);
       return ResourceTable::CollisionResult::kKeepOriginal;
     }
-  } else if (Style* existing_style = ValueCast<Style>(existing)) {
-    if (Style* incoming_style = ValueCast<Style>(incoming)) {
-      // Styles get merged.
-      existing_style->MergeWith(incoming_style, pool);
-      return ResourceTable::CollisionResult::kKeepOriginal;
+  } else if (!override_styles_instead_of_overlaying) {
+    if (Style* existing_style = ValueCast<Style>(existing)) {
+      if (Style* incoming_style = ValueCast<Style>(incoming)) {
+        // Styles get merged.
+        existing_style->MergeWith(incoming_style, pool);
+        return ResourceTable::CollisionResult::kKeepOriginal;
+      }
     }
   }
   // Delegate to the default handler.
@@ -194,6 +197,7 @@
 static ResourceTable::CollisionResult MergeConfigValue(IAaptContext* context,
                                                        const ResourceNameRef& res_name,
                                                        bool overlay,
+                                                       bool override_styles_instead_of_overlaying,
                                                        ResourceConfigValue* dst_config_value,
                                                        ResourceConfigValue* src_config_value,
                                                        StringPool* pool) {
@@ -204,7 +208,8 @@
 
   CollisionResult collision_result;
   if (overlay) {
-    collision_result = ResolveMergeCollision(dst_value, src_value, pool);
+    collision_result =
+        ResolveMergeCollision(override_styles_instead_of_overlaying, dst_value, src_value, pool);
   } else {
     collision_result = ResourceTable::ResolveValueCollision(dst_value, src_value);
   }
@@ -272,9 +277,9 @@
         ResourceConfigValue* dst_config_value = dst_entry->FindValue(
             src_config_value->config, src_config_value->product);
         if (dst_config_value) {
-          CollisionResult collision_result =
-              MergeConfigValue(context_, res_name, overlay, dst_config_value,
-                               src_config_value.get(), &master_table_->string_pool);
+          CollisionResult collision_result = MergeConfigValue(
+              context_, res_name, overlay, options_.override_styles_instead_of_overlaying,
+              dst_config_value, src_config_value.get(), &master_table_->string_pool);
           if (collision_result == CollisionResult::kConflict) {
             error = true;
             continue;
diff --git a/tools/aapt2/link/TableMerger.h b/tools/aapt2/link/TableMerger.h
index 51305cf..a35a134 100644
--- a/tools/aapt2/link/TableMerger.h
+++ b/tools/aapt2/link/TableMerger.h
@@ -37,6 +37,8 @@
   bool auto_add_overlay = false;
   // If true, resource overlays with conflicting visibility are not allowed.
   bool strict_visibility = false;
+  // If true, styles specified via "aapt2 link -R" completely replace any previously-seen resources.
+  bool override_styles_instead_of_overlaying = false;
 };
 
 // TableMerger takes resource tables and merges all packages within the tables that have the same
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index 9dd31e6..0be4ccf 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -436,6 +436,53 @@
               Eq(make_value(Reference(test::ParseNameOrDie("com.app.a:style/OverlayParent")))));
 }
 
+TEST_F(TableMergerTest, OverrideStyleInsteadOfOverlaying) {
+  std::unique_ptr<ResourceTable> table_a =
+      test::ResourceTableBuilder()
+          .SetPackageId("com.app.a", 0x7f)
+          .AddValue(
+              "com.app.a:styleable/MyWidget",
+              test::StyleableBuilder().AddItem("com.app.a:attr/foo", ResourceId(0x1234)).Build())
+          .AddValue("com.app.a:style/Theme",
+                    test::StyleBuilder()
+                        .AddItem("com.app.a:attr/foo", ResourceUtils::MakeBool(false))
+                        .Build())
+          .Build();
+  std::unique_ptr<ResourceTable> table_b =
+      test::ResourceTableBuilder()
+          .SetPackageId("com.app.a", 0x7f)
+          .AddValue(
+              "com.app.a:styleable/MyWidget",
+              test::StyleableBuilder().AddItem("com.app.a:attr/bar", ResourceId(0x5678)).Build())
+          .AddValue(
+              "com.app.a:style/Theme",
+              test::StyleBuilder().AddItem("com.app.a:attr/bat", util::make_unique<Id>()).Build())
+          .Build();
+
+  ResourceTable final_table;
+  TableMergerOptions options;
+  options.auto_add_overlay = true;
+  options.override_styles_instead_of_overlaying = true;
+  TableMerger merger(context_.get(), &final_table, options);
+  ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
+  ASSERT_TRUE(merger.Merge({}, table_b.get(), true /*overlay*/));
+
+  // Styleables are always overlaid
+  std::unique_ptr<Styleable> expected_styleable = test::StyleableBuilder()
+      // The merged Styleable has its entries ordered by name.
+      .AddItem("com.app.a:attr/bar", ResourceId(0x5678))
+      .AddItem("com.app.a:attr/foo", ResourceId(0x1234))
+      .Build();
+  const Styleable* actual_styleable =
+      test::GetValue<Styleable>(&final_table, "com.app.a:styleable/MyWidget");
+  ASSERT_NE(actual_styleable, nullptr);
+  EXPECT_TRUE(actual_styleable->Equals(expected_styleable.get()));
+  // Style should be overridden
+  const Style* actual_style = test::GetValue<Style>(&final_table, "com.app.a:style/Theme");
+  ASSERT_NE(actual_style, nullptr);
+  EXPECT_TRUE(actual_style->Equals(test::GetValue<Style>(table_b.get(), "com.app.a:style/Theme")));
+}
+
 TEST_F(TableMergerTest, SetOverlayable) {
   auto overlayable = std::make_shared<Overlayable>("CustomizableResources",
                                                   "overlay://customization");
diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp
index d68f7dd..f3be483 100644
--- a/tools/aapt2/link/XmlReferenceLinker.cpp
+++ b/tools/aapt2/link/XmlReferenceLinker.cpp
@@ -99,7 +99,7 @@
 
         std::string err_str;
         attr.compiled_attribute =
-            ReferenceLinker::CompileXmlAttribute(attr_ref, callsite_, symbols_, &err_str);
+            ReferenceLinker::CompileXmlAttribute(attr_ref, callsite_, context_, symbols_, &err_str);
 
         if (!attr.compiled_attribute) {
           DiagMessage error_msg(source);
diff --git a/tools/aapt2/optimize/MultiApkGenerator.cpp b/tools/aapt2/optimize/MultiApkGenerator.cpp
index 8c9c434..c686a10 100644
--- a/tools/aapt2/optimize/MultiApkGenerator.cpp
+++ b/tools/aapt2/optimize/MultiApkGenerator.cpp
@@ -101,6 +101,10 @@
         util::make_unique<SourcePathDiagnostics>(Source{source}, context_->GetDiagnostics());
   }
 
+  const std::set<std::string>& GetSplitNameDependencies() override {
+    return context_->GetSplitNameDependencies();
+  }
+
  private:
   IAaptContext* context_;
   std::unique_ptr<SourcePathDiagnostics> source_diag_;
diff --git a/tools/aapt2/optimize/ResourcePathShortener.cpp b/tools/aapt2/optimize/ResourcePathShortener.cpp
index 845262b..6b11de7 100644
--- a/tools/aapt2/optimize/ResourcePathShortener.cpp
+++ b/tools/aapt2/optimize/ResourcePathShortener.cpp
@@ -23,6 +23,7 @@
 
 #include "ResourceTable.h"
 #include "ValueVisitor.h"
+#include "util/Util.h"
 
 
 static const std::string base64_chars =
@@ -95,8 +96,8 @@
     android::StringPiece res_subdir, actual_filename, extension;
     util::ExtractResFilePathParts(*file_ref->path, &res_subdir, &actual_filename, &extension);
 
-    // Android detects ColorStateLists via pathname, skip res/color/*
-    if (res_subdir == android::StringPiece("res/color/"))
+    // Android detects ColorStateLists via pathname, skip res/color*
+    if (util::StartsWith(res_subdir, "res/color"))
       continue;
 
     std::string shortened_filename = ShortenFileName(*file_ref->path, num_chars);
diff --git a/tools/aapt2/optimize/ResourcePathShortener_test.cpp b/tools/aapt2/optimize/ResourcePathShortener_test.cpp
index efbef8f..1f45694 100644
--- a/tools/aapt2/optimize/ResourcePathShortener_test.cpp
+++ b/tools/aapt2/optimize/ResourcePathShortener_test.cpp
@@ -75,6 +75,9 @@
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
           .AddFileReference("android:color/colorlist", "res/color/colorlist.xml")
+          .AddFileReference("android:color/colorlist",
+                            "res/color-mdp-v21/colorlist.xml",
+                            test::ParseConfigOrDie("mdp-v21"))
           .Build();
 
   std::map<std::string, std::string> path_map;
@@ -82,6 +85,7 @@
 
   // Expect that the path map to not contain the ColorStateList
   ASSERT_THAT(path_map.find("res/color/colorlist.xml"), Eq(path_map.end()));
+  ASSERT_THAT(path_map.find("res/color-mdp-v21/colorlist.xml"), Eq(path_map.end()));
 }
 
 TEST(ResourcePathShortenerTest, KeepExtensions) {
diff --git a/tools/aapt2/process/IResourceTableConsumer.h b/tools/aapt2/process/IResourceTableConsumer.h
index 30dad802..9c4b323 100644
--- a/tools/aapt2/process/IResourceTableConsumer.h
+++ b/tools/aapt2/process/IResourceTableConsumer.h
@@ -19,6 +19,7 @@
 
 #include <iostream>
 #include <list>
+#include <set>
 #include <sstream>
 
 #include "Diagnostics.h"
@@ -50,6 +51,7 @@
   virtual NameMangler* GetNameMangler() = 0;
   virtual bool IsVerbose() = 0;
   virtual int GetMinSdkVersion() = 0;
+  virtual const std::set<std::string>& GetSplitNameDependencies() = 0;
 };
 
 struct IResourceTableConsumer {
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index 61a8fbb..bc09f19 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -313,6 +313,7 @@
       symbol.symbol.name = parsed_name.value();
       symbol.symbol.id = ResourceId(map_entry.key);
       symbol.value = map_entry.value.data;
+      symbol.type = map_entry.value.dataType;
       s->attribute->symbols.push_back(std::move(symbol));
     }
   }
diff --git a/tools/aapt2/test/Context.h b/tools/aapt2/test/Context.h
index 0564db0..7e10a59 100644
--- a/tools/aapt2/test/Context.h
+++ b/tools/aapt2/test/Context.h
@@ -81,6 +81,10 @@
     return min_sdk_version_;
   }
 
+ const std::set<std::string>& GetSplitNameDependencies() override {
+    return split_name_dependencies_;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(Context);
 
@@ -93,6 +97,7 @@
   NameMangler name_mangler_;
   SymbolTable symbols_;
   int min_sdk_version_;
+  std::set<std::string> split_name_dependencies_;
 };
 
 class ContextBuilder {
@@ -127,6 +132,11 @@
     return *this;
   }
 
+  ContextBuilder& SetSplitNameDependencies(const std::set<std::string>& split_name_dependencies) {
+    context_->split_name_dependencies_ = split_name_dependencies;
+    return *this;
+  }
+
   std::unique_ptr<Context> Build() { return std::move(context_); }
 
  private:
diff --git a/tools/aapt2/test/Fixture.cpp b/tools/aapt2/test/Fixture.cpp
index a51b4a4..5386802d 100644
--- a/tools/aapt2/test/Fixture.cpp
+++ b/tools/aapt2/test/Fixture.cpp
@@ -80,7 +80,7 @@
   ClearDirectory(temp_dir_);
 }
 
-bool TestDirectoryFixture::WriteFile(const std::string& path, const std::string& contents) {
+void TestDirectoryFixture::WriteFile(const std::string& path, const std::string& contents) {
   CHECK(util::StartsWith(path, temp_dir_))
       << "Attempting to create a file outside of test temporary directory.";
 
@@ -91,16 +91,31 @@
     file::mkdirs(dirs);
   }
 
-  return android::base::WriteStringToFile(contents, path);
+  CHECK(android::base::WriteStringToFile(contents, path));
 }
 
 bool CommandTestFixture::CompileFile(const std::string& path, const std::string& contents,
                                      const android::StringPiece& out_dir, IDiagnostics* diag) {
-  CHECK(WriteFile(path, contents));
+  WriteFile(path, contents);
   CHECK(file::mkdirs(out_dir.data()));
   return CompileCommand(diag).Execute({path, "-o", out_dir, "-v"}, &std::cerr) == 0;
 }
 
+bool CommandTestFixture::Link(const std::vector<std::string>& args, IDiagnostics* diag) {
+  std::vector<android::StringPiece> link_args;
+  for(const std::string& arg : args) {
+    link_args.emplace_back(arg);
+  }
+
+  // Link against the android SDK
+  std::string android_sdk = file::BuildPath({android::base::GetExecutableDirectory(),
+                                             "integration-tests", "CommandTests",
+                                             "android-28.jar"});
+  link_args.insert(link_args.end(), {"-I", android_sdk});
+
+  return LinkCommand(diag).Execute(link_args, &std::cerr) == 0;
+}
+
 bool CommandTestFixture::Link(const std::vector<std::string>& args,
                               const android::StringPiece& flat_dir, IDiagnostics* diag) {
   std::vector<android::StringPiece> link_args;
@@ -128,10 +143,10 @@
 
 std::string CommandTestFixture::GetDefaultManifest(const char* package_name) {
   const std::string manifest_file = GetTestPath("AndroidManifest.xml");
-  CHECK(WriteFile(manifest_file, android::base::StringPrintf(R"(
+  WriteFile(manifest_file, android::base::StringPrintf(R"(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="%s">
-      </manifest>)", package_name)));
+      </manifest>)", package_name));
   return manifest_file;
 }
 
diff --git a/tools/aapt2/test/Fixture.h b/tools/aapt2/test/Fixture.h
index fce2aeb..457d65e 100644
--- a/tools/aapt2/test/Fixture.h
+++ b/tools/aapt2/test/Fixture.h
@@ -58,7 +58,7 @@
 
   // Creates a file with the specified contents, creates any intermediate directories in the
   // process. The file path must be an absolute path within the test directory.
-  bool WriteFile(const std::string& path, const std::string& contents);
+  void WriteFile(const std::string& path, const std::string& contents);
 
  private:
   std::string temp_dir_;
@@ -75,6 +75,9 @@
   bool CompileFile(const std::string& path, const std::string& contents,
                    const android::StringPiece& flat_out_dir, IDiagnostics* diag);
 
+  // Executes the link command with the specified arguments.
+  bool Link(const std::vector<std::string>& args, IDiagnostics* diag);
+
   // Executes the link command with the specified arguments. The flattened files residing in the
   // flat directory will be added to the link command as file arguments.
   bool Link(const std::vector<std::string>& args, const android::StringPiece& flat_dir,
diff --git a/tools/codegen/.gitignore b/tools/codegen/.gitignore
new file mode 100755
index 0000000..9fb18b4
--- /dev/null
+++ b/tools/codegen/.gitignore
@@ -0,0 +1,2 @@
+.idea
+out
diff --git a/tools/codegen/Android.bp b/tools/codegen/Android.bp
new file mode 100644
index 0000000..805b296
--- /dev/null
+++ b/tools/codegen/Android.bp
@@ -0,0 +1,18 @@
+java_binary_host {
+    name: "codegen",
+    manifest: "manifest.txt",
+    srcs: [
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "javaparser",
+    ],
+}
+
+java_library_host {
+    name: "codegen-version-info",
+
+    srcs: [
+        "src/**/SharedConstants.kt",
+    ],
+}
diff --git a/tools/codegen/OWNERS b/tools/codegen/OWNERS
new file mode 100644
index 0000000..da723b3
--- /dev/null
+++ b/tools/codegen/OWNERS
@@ -0,0 +1 @@
+eugenesusla@google.com
\ No newline at end of file
diff --git a/tools/codegen/manifest.txt b/tools/codegen/manifest.txt
new file mode 100644
index 0000000..6e1018b
--- /dev/null
+++ b/tools/codegen/manifest.txt
@@ -0,0 +1 @@
+Main-class: com.android.codegen.MainKt
diff --git a/tools/codegen/src/com/android/codegen/ClassInfo.kt b/tools/codegen/src/com/android/codegen/ClassInfo.kt
new file mode 100644
index 0000000..7ee79f6
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/ClassInfo.kt
@@ -0,0 +1,49 @@
+package com.android.codegen
+
+import com.github.javaparser.JavaParser
+import com.github.javaparser.ParseProblemException
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+
+open class ClassInfo(val sourceLines: List<String>) {
+
+    private val userSourceCode = (sourceLines + "}").joinToString("\n")
+    val fileAst = try {
+        JavaParser.parse(userSourceCode)!!
+    } catch (e: ParseProblemException) {
+        throw RuntimeException("Failed to parse code:\n" +
+                userSourceCode
+                        .lines()
+                        .mapIndexed { lnNum, ln -> "/*$lnNum*/$ln" }
+                        .joinToString("\n"),
+                e)
+    }
+    val classAst = fileAst.types[0] as ClassOrInterfaceDeclaration
+
+    fun hasMethod(name: String, vararg argTypes: String): Boolean {
+        return classAst.methods.any {
+            it.name.asString() == name &&
+                    it.parameters.map { it.type.asString() } == argTypes.toList()
+        }
+    }
+
+    val superInterfaces = (fileAst.types[0] as ClassOrInterfaceDeclaration)
+            .implementedTypes.map { it.asString() }
+
+    val ClassName = classAst.nameAsString
+    private val genericArgsAst = classAst.typeParameters
+    val genericArgs = if (genericArgsAst.isEmpty()) "" else {
+        genericArgsAst.map { it.nameAsString }.joinToString(", ").let { "<$it>" }
+    }
+    val ClassType = ClassName + genericArgs
+
+    val constDefs = mutableListOf<ConstDef>()
+
+    val fields = classAst.fields
+            .filterNot { it.isTransient || it.isStatic }
+            .mapIndexed { i, node -> FieldInfo(index = i, fieldAst = node, classInfo = this) }
+            .apply { lastOrNull()?.isLast = true }
+    val lazyTransientFields = classAst.fields
+            .filter { it.isTransient && !it.isStatic }
+            .mapIndexed { i, node -> FieldInfo(index = i, fieldAst = node, classInfo = this) }
+            .filter { hasMethod("lazyInit${it.NameUpperCamel}") }
+}
\ No newline at end of file
diff --git a/tools/codegen/src/com/android/codegen/ClassPrinter.kt b/tools/codegen/src/com/android/codegen/ClassPrinter.kt
new file mode 100644
index 0000000..33256b7
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/ClassPrinter.kt
@@ -0,0 +1,311 @@
+package com.android.codegen
+
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+import com.github.javaparser.ast.body.TypeDeclaration
+import com.github.javaparser.ast.expr.BooleanLiteralExpr
+import com.github.javaparser.ast.expr.NormalAnnotationExpr
+import com.github.javaparser.ast.type.ClassOrInterfaceType
+
+/**
+ * [ClassInfo] + utilities for printing out new class code with proper indentation and imports
+ */
+class ClassPrinter(
+    source: List<String>,
+    private val stringBuilder: StringBuilder,
+    var cliArgs: Array<String>
+) : ClassInfo(source) {
+
+    val GENERATED_MEMBER_HEADER by lazy { "@$GeneratedMember" }
+
+    // Imports
+    val NonNull by lazy { classRef("android.annotation.NonNull") }
+    val NonEmpty by lazy { classRef("android.annotation.NonEmpty") }
+    val Nullable by lazy { classRef("android.annotation.Nullable") }
+    val TextUtils by lazy { classRef("android.text.TextUtils") }
+    val LinkedHashMap by lazy { classRef("java.util.LinkedHashMap") }
+    val Collections by lazy { classRef("java.util.Collections") }
+    val Preconditions by lazy { classRef("com.android.internal.util.Preconditions") }
+    val ArrayList by lazy { classRef("java.util.ArrayList") }
+    val DataClass by lazy { classRef("com.android.internal.util.DataClass") }
+    val DataClassEnum by lazy { classRef("com.android.internal.util.DataClass.Enum") }
+    val ParcelWith by lazy { classRef("com.android.internal.util.DataClass.ParcelWith") }
+    val PluralOf by lazy { classRef("com.android.internal.util.DataClass.PluralOf") }
+    val Each by lazy { classRef("com.android.internal.util.DataClass.Each") }
+    val DataClassGenerated by lazy { classRef("com.android.internal.util.DataClass.Generated") }
+    val GeneratedMember by lazy { classRef("com.android.internal.util.DataClass.Generated.Member") }
+    val Parcelling by lazy { classRef("com.android.internal.util.Parcelling") }
+    val UnsupportedAppUsage by lazy { classRef("android.annotation.UnsupportedAppUsage") }
+
+
+    /**
+     * Optionally shortens a class reference if there's a corresponding import present
+     */
+    fun classRef(fullName: String): String {
+        if (cliArgs.contains(FLAG_NO_FULL_QUALIFIERS)) {
+            return fullName.split(".").dropWhile { it[0].isLowerCase() }.joinToString(".")
+        }
+
+        val pkg = fullName.substringBeforeLast(".")
+        val simpleName = fullName.substringAfterLast(".")
+        if (fileAst.imports.any { imprt ->
+                    imprt.nameAsString == fullName
+                            || (imprt.isAsterisk && imprt.nameAsString == pkg)
+                }) {
+            return simpleName
+        } else {
+            val outerClass = pkg.substringAfterLast(".", "")
+            if (outerClass.firstOrNull()?.isUpperCase() ?: false) {
+                return classRef(pkg) + "." + simpleName
+            }
+        }
+        return fullName
+    }
+
+    /** @see classRef */
+    inline fun <reified T : Any> classRef(): String {
+        return classRef(T::class.java.name)
+    }
+
+    /** @see classRef */
+    fun memberRef(fullName: String): String {
+        val className = fullName.substringBeforeLast(".")
+        val methodName = fullName.substringAfterLast(".")
+        return if (fileAst.imports.any {
+                    it.isStatic
+                            && (it.nameAsString == fullName
+                            || (it.isAsterisk && it.nameAsString == className))
+                }) {
+            className.substringAfterLast(".") + "." + methodName
+        } else {
+            classRef(className) + "." + methodName
+        }
+    }
+
+    val dataClassAnnotationFeatures = classAst.annotations
+            .find { it.nameAsString == DataClass }
+            ?.let { it as? NormalAnnotationExpr }
+            ?.pairs
+            ?.map { pair -> pair.nameAsString to (pair.value as BooleanLiteralExpr).value }
+            ?.toMap()
+            ?: emptyMap()
+
+    val internalAnnotations = setOf(ParcelWith, DataClassEnum, PluralOf, Each, UnsupportedAppUsage)
+
+    /**
+     * @return whether the given feature is enabled
+     */
+    operator fun FeatureFlag.invoke(): Boolean {
+        if (cliArgs.contains("--no-$kebabCase")) return false
+        if (cliArgs.contains("--$kebabCase")) return true
+
+        val annotationKey = "gen$upperCamelCase"
+        if (dataClassAnnotationFeatures.containsKey(annotationKey)) {
+            return dataClassAnnotationFeatures[annotationKey]!!
+        }
+
+        if (cliArgs.contains("--all")) return true
+        if (hidden) return true
+
+        return when (this) {
+            FeatureFlag.SETTERS ->
+                !FeatureFlag.CONSTRUCTOR() && !FeatureFlag.BUILDER() && fields.any { !it.isFinal }
+            FeatureFlag.BUILDER -> cliArgs.contains(FLAG_BUILDER_PROTECTED_SETTERS) || onByDefault
+            FeatureFlag.CONSTRUCTOR -> !FeatureFlag.BUILDER()
+            FeatureFlag.PARCELABLE -> "Parcelable" in superInterfaces
+            FeatureFlag.AIDL -> FeatureFlag.PARCELABLE()
+            FeatureFlag.IMPLICIT_NONNULL -> fields.any { it.isNullable }
+                    && fields.none { "@$NonNull" in it.annotations }
+            else -> onByDefault
+        }
+    }
+
+    val FeatureFlag.hidden
+        get(): Boolean = when {
+            cliArgs.contains("--hidden-$kebabCase") -> true
+            this == FeatureFlag.BUILD_UPON -> FeatureFlag.BUILDER.hidden
+            else -> false
+        }
+
+    var currentIndent = INDENT_SINGLE
+        private set
+
+    fun pushIndent() {
+        currentIndent += INDENT_SINGLE
+    }
+
+    fun popIndent() {
+        currentIndent = currentIndent.substring(0, currentIndent.length - INDENT_SINGLE.length)
+    }
+
+    fun backspace() = stringBuilder.setLength(stringBuilder.length - 1)
+    val lastChar get() = stringBuilder[stringBuilder.length - 1]
+
+    private fun appendRaw(s: String) {
+        stringBuilder.append(s)
+    }
+
+    fun append(s: String) {
+        if (s.isBlank() && s != "\n") {
+            appendRaw(s)
+        } else {
+            appendRaw(s.lines().map { line ->
+                if (line.startsWith(" *")) line else line.trimStart()
+            }.joinToString("\n$currentIndent"))
+        }
+    }
+
+    fun appendSameLine(s: String) {
+        while (lastChar.isWhitespace() || lastChar.isNewline()) {
+            backspace()
+        }
+        appendRaw(s)
+    }
+
+    fun rmEmptyLine() {
+        while (lastChar.isWhitespaceNonNewline()) backspace()
+        if (lastChar.isNewline()) backspace()
+    }
+
+    /**
+     * Syntactic sugar for:
+     * ```
+     * +"code()";
+     * ```
+     * to append the given string plus a newline
+     */
+    operator fun String.unaryPlus() = append("$this\n")
+
+    /**
+     * Syntactic sugar for:
+     * ```
+     * !"code()";
+     * ```
+     * to append the given string without a newline
+     */
+    operator fun String.not() = append(this)
+
+    /**
+     * Syntactic sugar for:
+     * ```
+     * ... {
+     *     ...
+     * }+";"
+     * ```
+     * to append a ';' on same line after a block, and a newline afterwards
+     */
+    operator fun Unit.plus(s: String) {
+        appendSameLine(s)
+        +""
+    }
+
+    /**
+     * A multi-purpose syntactic sugar for appending the given string plus anything generated in
+     * the given [block], the latter with the appropriate deeper indent,
+     * and resetting the indent back to original at the end
+     *
+     * Usage examples:
+     *
+     * ```
+     * "if (...)" {
+     *     ...
+     * }
+     * ```
+     * to append a corresponding if block appropriate indentation
+     *
+     * ```
+     * "void foo(...)" {
+     *      ...
+     * }
+     * ```
+     * similar to the previous one, plus an extra empty line after the function body
+     *
+     * ```
+     * "void foo(" {
+     *      <args code>
+     * }
+     * ```
+     * to use proper indentation for args code and close the bracket on same line at end
+     *
+     * ```
+     * "..." {
+     *     ...
+     * }
+     * to use the correct indentation for inner code, resetting it at the end
+     */
+    inline operator fun String.invoke(block: ClassPrinter.() -> Unit) {
+        if (this == " {") {
+            appendSameLine(this)
+        } else {
+            append(this)
+        }
+        when {
+            endsWith("(") -> {
+                indentedBy(2, block)
+                appendSameLine(")")
+            }
+            endsWith("{") || endsWith(")") -> {
+                if (!endsWith("{")) appendSameLine(" {")
+                indentedBy(1, block)
+                +"}"
+                if ((endsWith(") {") || endsWith(")") || this == " {")
+                        && !startsWith("synchronized")
+                        && !startsWith("switch")
+                        && !startsWith("if ")
+                        && !contains(" else ")
+                        && !contains("new ")
+                        && !contains("return ")) {
+                    +"" // extra line after function definitions
+                }
+            }
+            else -> indentedBy(2, block)
+        }
+    }
+
+    inline fun indentedBy(level: Int, block: ClassPrinter.() -> Unit) {
+        append("\n")
+        level times {
+            append(INDENT_SINGLE)
+            pushIndent()
+        }
+        block()
+        level times { popIndent() }
+        rmEmptyLine()
+        +""
+    }
+
+    inline fun Iterable<FieldInfo>.forEachTrimmingTrailingComma(b: FieldInfo.() -> Unit) {
+        forEachApply {
+            b()
+            if (isLast) {
+                while (lastChar == ' ' || lastChar == '\n') backspace()
+                if (lastChar == ',') backspace()
+            }
+        }
+    }
+
+    inline operator fun <R> invoke(f: ClassPrinter.() -> R): R = run(f)
+
+    var BuilderClass = CANONICAL_BUILDER_CLASS
+    var BuilderType = BuilderClass + genericArgs
+
+    init {
+        val builderFactoryOverride = classAst.methods.find {
+            it.isStatic && it.nameAsString == "builder"
+        }
+        if (builderFactoryOverride != null) {
+            BuilderClass = (builderFactoryOverride.type as ClassOrInterfaceType).nameAsString
+            BuilderType = builderFactoryOverride.type.asString()
+        } else {
+            val builderExtension = (fileAst.types
+                    + classAst.childNodes.filterIsInstance(TypeDeclaration::class.java)).find {
+                it.nameAsString == CANONICAL_BUILDER_CLASS
+            }
+            if (builderExtension != null) {
+                BuilderClass = GENERATED_BUILDER_CLASS
+                val tp = (builderExtension as ClassOrInterfaceDeclaration).typeParameters
+                BuilderType = if (tp.isEmpty()) BuilderClass
+                else "$BuilderClass<${tp.map { it.nameAsString }.joinToString(", ")}>"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tools/codegen/src/com/android/codegen/ConstDef.kt b/tools/codegen/src/com/android/codegen/ConstDef.kt
new file mode 100644
index 0000000..f559d6f
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/ConstDef.kt
@@ -0,0 +1,17 @@
+package com.android.codegen
+
+import com.github.javaparser.ast.body.FieldDeclaration
+
+/**
+ * `@IntDef` or `@StringDef`
+ */
+data class ConstDef(val type: Type, val AnnotationName: String, val values: List<FieldDeclaration>) {
+
+    enum class Type {
+        INT, INT_FLAGS, STRING;
+
+        val isInt get() = this == INT || this == INT_FLAGS
+    }
+
+    val CONST_NAMES get() = values.flatMap { it.variables }.map { it.nameAsString }
+}
\ No newline at end of file
diff --git a/tools/codegen/src/com/android/codegen/FeatureFlag.kt b/tools/codegen/src/com/android/codegen/FeatureFlag.kt
new file mode 100644
index 0000000..24150d6
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/FeatureFlag.kt
@@ -0,0 +1,27 @@
+package com.android.codegen
+
+
+/**
+ * See also [ClassPrinter.invoke] for more default flag values resolution rules
+ */
+enum class FeatureFlag(val onByDefault: Boolean, val desc: String = "") {
+    PARCELABLE(false, "implement Parcelable contract"),
+    AIDL(false, "generate a 'parcelable declaration' .aidl file alongside"),
+    CONSTRUCTOR(true, "an all-argument constructor"),
+    BUILDER(false, "e.g. MyClass.builder().setFoo(..).build();"),
+    GETTERS(true, "getters, e.g. getFoo()"),
+    SETTERS(false, "chainable/fluent setters, e.g. setFoo(..).setBar(..)"),
+    WITHERS(false, "'immutable setters' returning a new instance, " +
+            "e.g. newFoo = foo.withBar(barValue)"),
+    EQUALS_HASH_CODE(false, "equals + hashCode based on fields"),
+    TO_STRING(false, "toString based on fields"),
+    BUILD_UPON(false, "builder factory from existing instance, " +
+            "e.g. instance.buildUpon().setFoo(..).build()"),
+    IMPLICIT_NONNULL(true, "treat lack of @Nullable as @NonNull for Object fields"),
+    COPY_CONSTRUCTOR(false, "a constructor for an instance identical to the given one"),
+    CONST_DEFS(true, "@Int/StringDef's based on declared static constants"),
+    FOR_EACH_FIELD(false, "forEachField((name, value) -> ...)");
+
+    val kebabCase = name.toLowerCase().replace("_", "-")
+    val upperCamelCase = name.split("_").map { it.toLowerCase().capitalize() }.joinToString("")
+}
diff --git a/tools/codegen/src/com/android/codegen/FieldInfo.kt b/tools/codegen/src/com/android/codegen/FieldInfo.kt
new file mode 100644
index 0000000..f326fd5
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/FieldInfo.kt
@@ -0,0 +1,216 @@
+package com.android.codegen
+
+import com.github.javaparser.JavaParser
+import com.github.javaparser.ast.body.FieldDeclaration
+import com.github.javaparser.ast.expr.ClassExpr
+import com.github.javaparser.ast.expr.Name
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
+import com.github.javaparser.ast.expr.StringLiteralExpr
+import com.github.javaparser.ast.type.ArrayType
+import com.github.javaparser.ast.type.ClassOrInterfaceType
+import com.github.javaparser.javadoc.Javadoc
+import java.lang.Long
+
+data class FieldInfo(
+    val index: Int,
+    val fieldAst: FieldDeclaration,
+    private val classInfo: ClassInfo
+) {
+
+    val classPrinter = classInfo as ClassPrinter
+
+    // AST
+    internal val variableAst = fieldAst.variables[0]
+    val typeAst = variableAst.type
+
+    // Field type
+    val Type = typeAst.asString()
+    val FieldClass = Type.takeWhile { it != '<' }
+    val isPrimitive = Type in PRIMITIVE_TYPES
+
+    // Javadoc
+    val javadoc: Javadoc? = fieldAst.javadoc.orElse(null)
+    private val javadocText = javadoc?.toText()?.let {
+        // Workaround for a bug in Javaparser for javadocs starting with {
+        if (it.hasUnbalancedCurlyBrace()) "{$it" else it
+    }
+    val javadocTextNoAnnotationLines = javadocText
+            ?.lines()
+            ?.dropLastWhile { it.startsWith("@") || it.isBlank() }
+            ?.let { if (it.isEmpty()) null else it }
+    val javadocFull = javadocText
+            ?.trimBlankLines()
+            ?.mapLines { " * $this" }
+            ?.let { "/**\n$it\n */" }
+
+
+    // Field name
+    val name = variableAst.name.asString()!!
+    private val isNameHungarian = name[0] == 'm' && name[1].isUpperCase()
+    val NameUpperCamel = if (isNameHungarian) name.substring(1) else name.capitalize()
+    val nameLowerCamel = if (isNameHungarian) NameUpperCamel.decapitalize() else name
+    val _name = if (name != nameLowerCamel) nameLowerCamel else "_$nameLowerCamel"
+    val SingularNameOrNull by lazy {
+        classPrinter {
+            fieldAst.annotations
+                    .find { it.nameAsString == PluralOf }
+                    ?.let { it as? SingleMemberAnnotationExpr }
+                    ?.memberValue
+                    ?.let { it as? StringLiteralExpr }
+                    ?.value
+                    ?.toLowerCamel()
+                    ?.capitalize()
+        }
+    }
+    val SingularName by lazy { SingularNameOrNull ?: NameUpperCamel }
+
+
+    // Field value
+    val mayBeNull: Boolean
+        get() = when {
+            isPrimitive -> false
+            "@${classPrinter.NonNull}" in annotations -> false
+            "@${classPrinter.NonEmpty}" in annotations -> false
+            isNullable -> true
+            lazyInitializer != null -> true
+            else -> classPrinter { !FeatureFlag.IMPLICIT_NONNULL() }
+        }
+    val lazyInitializer
+        get() = classInfo.classAst.methods.find { method ->
+            method.nameAsString == "lazyInit$NameUpperCamel" && method.parameters.isEmpty()
+        }?.nameAsString
+    val internalGetter get() = if (lazyInitializer != null) "get$NameUpperCamel()" else name
+    val defaultExpr: Any?
+        get() {
+            variableAst.initializer.orElse(null)?.let { return it }
+            classInfo.classAst.methods.find {
+                it.nameAsString == "default$NameUpperCamel" && it.parameters.isEmpty()
+            }?.run { "$nameAsString()" }?.let { return it }
+            if (FieldClass == "List") return "${classPrinter.memberRef("java.util.Collections.emptyList")}()"
+            return null
+        }
+    val hasDefault get() = defaultExpr != null
+
+
+    // Generic args
+    val isArray = Type.endsWith("[]")
+    val isList = FieldClass == "List" || FieldClass == "ArrayList"
+    val fieldBit = "0x${Long.toHexString(1L shl index)}"
+    var isLast = false
+    val isFinal = fieldAst.isFinal
+    val fieldTypeGenegicArgs = when (typeAst) {
+        is ArrayType -> listOf(fieldAst.elementType.asString())
+        is ClassOrInterfaceType -> {
+            typeAst.typeArguments.orElse(null)?.map { it.asString() } ?: emptyList()
+        }
+        else -> emptyList()
+    }
+    val FieldInnerType = fieldTypeGenegicArgs.firstOrNull()
+    val FieldInnerClass = FieldInnerType?.takeWhile { it != '<' }
+
+
+    // Annotations
+    var intOrStringDef = null as ConstDef?
+    val annotations by lazy {
+        if (FieldClass in BUILTIN_SPECIAL_PARCELLINGS) {
+            classPrinter {
+                fieldAst.addAnnotation(SingleMemberAnnotationExpr(
+                        Name(ParcelWith),
+                        ClassExpr(JavaParser.parseClassOrInterfaceType(
+                                "$Parcelling.BuiltIn.For$FieldClass"))))
+            }
+        }
+        fieldAst.annotations.map { it.removeComment().toString() }
+    }
+    val annotationsNoInternal by lazy {
+        annotations.filterNot { ann ->
+            classPrinter {
+                internalAnnotations.any {
+                    it in ann
+                }
+            }
+        }
+    }
+
+    fun hasAnnotation(a: String) = annotations.any { it.startsWith(a) }
+    val isNullable by lazy { hasAnnotation("@Nullable") }
+    val isNonEmpty by lazy { hasAnnotation("@${classPrinter.NonEmpty}") }
+    val customParcellingClass by lazy {
+        fieldAst.annotations.find { it.nameAsString == classPrinter.ParcelWith }
+                ?.singleArgAs<ClassExpr>()
+                ?.type
+                ?.asString()
+    }
+    val annotationsAndType by lazy { (annotationsNoInternal + Type).joinToString(" ") }
+    val sParcelling by lazy { customParcellingClass?.let { "sParcellingFor$NameUpperCamel" } }
+    val annotatedTypeForSetterParam by lazy {
+        (annotationsNoInternal + if (isArray) "$FieldInnerType..." else Type).joinToString(" ")
+    }
+
+    // Utilities
+
+    /**
+     * `mFoo.size()`
+     */
+    val ClassPrinter.sizeExpr get() = when {
+        isArray && FieldInnerClass !in PRIMITIVE_TYPES ->
+            memberRef("com.android.internal.util.ArrayUtils.size") + "($name)"
+        isArray -> "$name.length"
+        listOf("List", "Set", "Map").any { FieldClass.endsWith(it) } ->
+            memberRef("com.android.internal.util.CollectionUtils.size") + "($name)"
+        Type == "String" -> memberRef("android.text.TextUtils.length") + "($name)"
+        Type == "CharSequence" -> "$name.length()"
+        else -> "$name.size()"
+    }
+    /**
+     * `mFoo.get(0)`
+     */
+    fun elemAtIndexExpr(indexExpr: String) = when {
+        isArray -> "$name[$indexExpr]"
+        FieldClass == "ArraySet" -> "$name.valueAt($indexExpr)"
+        else -> "$name.get($indexExpr)"
+    }
+    /**
+     * `mFoo.isEmpty()`
+     */
+    val ClassPrinter.isEmptyExpr get() = when {
+        isArray || Type == "CharSequence" -> "$sizeExpr == 0"
+        else -> "$name.isEmpty()"
+    }
+
+    /**
+     * `mFoo == that` or `Objects.equals(mFoo, that)`, etc.
+     */
+    fun ClassPrinter.isEqualToExpr(that: String) = when {
+        Type in PRIMITIVE_TYPES -> "$internalGetter == $that"
+        isArray -> "${memberRef("java.util.Arrays.equals")}($internalGetter, $that)"
+        else -> "${memberRef("java.util.Objects.equals")}($internalGetter, $that)"
+    }
+
+    /**
+     * Parcel.write* and Parcel.read* method name wildcard values
+     */
+    val ParcelMethodsSuffix = when {
+        FieldClass in PRIMITIVE_TYPES - "char" - "boolean" +
+                listOf("String", "CharSequence", "Exception", "Size", "SizeF", "Bundle",
+                        "FileDescriptor", "SparseBooleanArray", "SparseIntArray", "SparseArray") ->
+            FieldClass
+        FieldClass == "Map" && fieldTypeGenegicArgs[0] == "String" -> "Map"
+        isArray -> when {
+            FieldInnerType!! in (PRIMITIVE_TYPES + "String") -> FieldInnerType + "Array"
+            isBinder(FieldInnerType) -> "BinderArray"
+            else -> "TypedArray"
+        }
+        isList -> when {
+            FieldInnerType == "String" -> "StringList"
+            isBinder(FieldInnerType!!) -> "BinderList"
+            else -> "ParcelableList"
+        }
+        isIInterface(Type) -> "StrongInterface"
+        isBinder(Type) -> "StrongBinder"
+        else -> "TypedObject"
+    }.capitalize()
+
+    private fun isBinder(type: String) = type == "Binder" || type == "IBinder" || isIInterface(type)
+    private fun isIInterface(type: String) = type.length >= 2 && type[0] == 'I' && type[1].isUpperCase()
+}
\ No newline at end of file
diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt
new file mode 100644
index 0000000..ab64f4e
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/Generators.kt
@@ -0,0 +1,847 @@
+package com.android.codegen
+
+import com.github.javaparser.ast.body.FieldDeclaration
+import com.github.javaparser.ast.body.VariableDeclarator
+import com.github.javaparser.ast.expr.*
+import java.io.File
+
+
+/**
+ * IntDefs and StringDefs based on constants
+ */
+fun ClassPrinter.generateConstDefs() {
+    val consts = classAst.fields.filter {
+        it.isStatic && it.isFinal && it.variables.all { variable ->
+            val initializer = variable.initializer.orElse(null)
+            val isLiteral = initializer is LiteralExpr
+                    || (initializer is UnaryExpr && initializer.expression is LiteralExpr)
+            isLiteral && variable.type.asString() in listOf("int", "String")
+        }
+    }.flatMap { field -> field.variables.map { it to field } }
+    val intConsts = consts.filter { it.first.type.asString() == "int" }
+    val strConsts = consts.filter { it.first.type.asString() == "String" }
+    val intGroups = intConsts.groupBy { it.first.nameAsString.split("_")[0] }.values
+    val strGroups = strConsts.groupBy { it.first.nameAsString.split("_")[0] }.values
+    intGroups.forEach {
+        generateConstDef(it)
+    }
+    strGroups.forEach {
+        generateConstDef(it)
+    }
+}
+
+fun ClassPrinter.generateConstDef(consts: List<Pair<VariableDeclarator, FieldDeclaration>>) {
+    if (consts.size <= 1) return
+
+    val names = consts.map { it.first.nameAsString!! }
+    val prefix = names
+            .reduce { a, b -> a.commonPrefixWith(b) }
+            .dropLastWhile { it != '_' }
+            .dropLast(1)
+    if (prefix.isEmpty()) {
+        println("Failed to generate const def for $names")
+        return
+    }
+    var AnnotationName = prefix.split("_")
+            .filterNot { it.isBlank() }
+            .map { it.toLowerCase().capitalize() }
+            .joinToString("")
+    val annotatedConst = consts.find { it.second.annotations.isNonEmpty }
+    if (annotatedConst != null) {
+        AnnotationName = annotatedConst.second.annotations.first().nameAsString
+    }
+    val type = consts[0].first.type.asString()
+    val flag = type == "int" && consts.all { it.first.initializer.get().toString().startsWith("0x") }
+    val constDef = ConstDef(type = when {
+        type == "String" -> ConstDef.Type.STRING
+        flag -> ConstDef.Type.INT_FLAGS
+        else -> ConstDef.Type.INT
+    },
+            AnnotationName = AnnotationName,
+            values = consts.map { it.second }
+    )
+    constDefs += constDef
+    fields.forEachApply {
+        if (fieldAst.annotations.any { it.nameAsString == AnnotationName }) {
+            this.intOrStringDef = constDef
+        }
+    }
+
+    val visibility = if (consts[0].second.isPublic) "public" else "/* package-*/"
+
+    val Retention = classRef("java.lang.annotation.Retention")
+    val RetentionPolicySource = memberRef("java.lang.annotation.RetentionPolicy.SOURCE")
+    val ConstDef = classRef("android.annotation.${type.capitalize()}Def")
+
+    "@$ConstDef(${if_(flag, "flag = true, ")}prefix = \"${prefix}_\", value = {" {
+        names.forEachLastAware { name, isLast ->
+            +"$name${if_(!isLast, ",")}"
+        }
+    } + ")"
+    +"@$Retention($RetentionPolicySource)"
+    +GENERATED_MEMBER_HEADER
+    +"$visibility @interface $AnnotationName {}"
+    +""
+
+    if (type == "int") {
+        +GENERATED_MEMBER_HEADER
+        val methodDefLine = "$visibility static String ${AnnotationName.decapitalize()}ToString(" +
+                "@$AnnotationName int value)"
+        if (flag) {
+            val flg2str = memberRef("com.android.internal.util.BitUtils.flagsToString")
+            methodDefLine {
+                "return $flg2str(" {
+                    +"value, $ClassName::single${AnnotationName}ToString"
+                } + ";"
+            }
+            +GENERATED_MEMBER_HEADER
+            !"static String single${AnnotationName}ToString(@$AnnotationName int value)"
+        } else {
+            !methodDefLine
+        }
+        " {" {
+            "switch (value) {" {
+                names.forEach { name ->
+                    "case $name:" {
+                        +"return \"$name\";"
+                    }
+                }
+                +"default: return Integer.toHexString(value);"
+            }
+        }
+    }
+}
+
+fun ClassPrinter.generateAidl(javaFile: File) {
+    val aidl = File(javaFile.path.substringBeforeLast(".java") + ".aidl")
+    if (aidl.exists()) return
+    aidl.writeText(buildString {
+        sourceLines.dropLastWhile { !it.startsWith("package ") }.forEach {
+            appendln(it)
+        }
+        append("\nparcelable $ClassName;\n")
+    })
+}
+
+/**
+ * ```
+ * Foo newFoo = oldFoo.withBar(newBar);
+ * ```
+ */
+fun ClassPrinter.generateWithers() {
+    fields.forEachApply {
+        val metodName = "with$NameUpperCamel"
+        if (!hasMethod(metodName, Type)) {
+            generateFieldJavadoc(forceHide = FeatureFlag.WITHERS.hidden)
+            """@$NonNull
+                        $GENERATED_MEMBER_HEADER
+                        public $ClassType $metodName($annotatedTypeForSetterParam value)""" {
+                val changedFieldName = name
+
+                "return new $ClassType(" {
+                    fields.forEachTrimmingTrailingComma {
+                        if (name == changedFieldName) +"value," else +"$name,"
+                    }
+                } + ";"
+            }
+        }
+    }
+}
+
+fun ClassPrinter.generateCopyConstructor() {
+    if (classAst.constructors.any {
+                it.parameters.size == 1 &&
+                        it.parameters[0].type.asString() == ClassType
+            }) {
+        return
+    }
+
+    +"/** Copy constructor */"
+    +GENERATED_MEMBER_HEADER
+    "public $ClassName(@$NonNull $ClassName orig)" {
+        fields.forEachApply {
+            +"$name = orig.$name;"
+        }
+    }
+}
+
+/**
+ * ```
+ * Foo newFoo = oldFoo.buildUpon().setBar(newBar).build();
+ * ```
+ */
+fun ClassPrinter.generateBuildUpon() {
+    if (hasMethod("buildUpon")) return
+
+    +"/**"
+    +" * Provides an instance of {@link $BuilderClass} with state corresponding to this instance."
+    if (FeatureFlag.BUILD_UPON.hidden) {
+        +" * @hide"
+    }
+    +" */"
+    +GENERATED_MEMBER_HEADER
+    "public $BuilderType buildUpon()" {
+        "return new $BuilderType()" {
+            fields.forEachApply {
+                +".set$NameUpperCamel($internalGetter)"
+            } + ";"
+        }
+    }
+}
+
+fun ClassPrinter.generateBuilder() {
+    val setterVisibility = if (cliArgs.contains(FLAG_BUILDER_PROTECTED_SETTERS))
+        "protected" else "public"
+    val constructorVisibility = if (BuilderClass == CANONICAL_BUILDER_CLASS)
+        "public" else "/* package-*/"
+
+    val OneTimeUseBuilder = classRef("android.provider.OneTimeUseBuilder")
+
+    +"/**"
+    +" * A builder for {@link $ClassName}"
+    if (FeatureFlag.BUILDER.hidden) +" * @hide"
+    +" */"
+    +"@SuppressWarnings(\"WeakerAccess\")"
+    +GENERATED_MEMBER_HEADER
+    "public static class $BuilderClass$genericArgs" {
+        +"extends $OneTimeUseBuilder<$ClassType>"
+    }
+    " {" {
+
+        +""
+        fields.forEachApply {
+            +"protected $annotationsAndType $name;"
+        }
+        +""
+        +"protected long mBuilderFieldsSet = 0L;"
+        +""
+        +"$constructorVisibility $BuilderClass() {};"
+        +""
+
+        generateBuilderSetters(setterVisibility)
+
+        generateBuilderBuild()
+
+        rmEmptyLine()
+    }
+}
+
+private fun ClassPrinter.generateBuilderSetters(visibility: String) {
+
+    fields.forEachApply {
+        val maybeCast =
+                if_(BuilderClass != CANONICAL_BUILDER_CLASS, " ($CANONICAL_BUILDER_CLASS)")
+
+        generateFieldJavadoc()
+        +GENERATED_MEMBER_HEADER
+        "$visibility $CANONICAL_BUILDER_CLASS set$NameUpperCamel($annotatedTypeForSetterParam value)" {
+            +"checkNotUsed();"
+            +"mBuilderFieldsSet |= $fieldBit;"
+            +"$name = value;"
+            +"return$maybeCast this;"
+        }
+
+
+        val javadocSeeSetter = "/** @see #set$NameUpperCamel */"
+        val singularNameCustomizationHint = if (SingularNameOrNull == null) {
+            "// You can refine this method's name by providing item's singular name, e.g.:\n" +
+                    "// @DataClass.PluralOf(\"item\")) mItems = ...\n\n"
+        } else ""
+
+        if (isList && FieldInnerType != null) {
+
+            +javadocSeeSetter
+            +GENERATED_MEMBER_HEADER
+            "$visibility $CANONICAL_BUILDER_CLASS add$SingularName(@$NonNull $FieldInnerType value)" {
+                !singularNameCustomizationHint
+                +"if ($name == null) set$NameUpperCamel(new $ArrayList<>());"
+                +"$name.add(value);"
+                +"return$maybeCast this;"
+            }
+        }
+
+        if (Type.contains("Map<")) {
+            val (Key, Value) = fieldTypeGenegicArgs
+
+            +javadocSeeSetter
+            +GENERATED_MEMBER_HEADER
+            "$visibility $CANONICAL_BUILDER_CLASS add$SingularName($Key key, $Value value)" {
+                !singularNameCustomizationHint
+                +"if ($name == null) set$NameUpperCamel(new $LinkedHashMap());"
+                +"$name.put(key, value);"
+                +"return$maybeCast this;"
+            }
+        }
+
+        if (Type == "boolean") {
+            +javadocSeeSetter
+            +GENERATED_MEMBER_HEADER
+            "$visibility $CANONICAL_BUILDER_CLASS mark$NameUpperCamel()" {
+                +"return set$NameUpperCamel(true);"
+            }
+
+            +javadocSeeSetter
+            +GENERATED_MEMBER_HEADER
+            "$visibility $CANONICAL_BUILDER_CLASS markNot$NameUpperCamel()" {
+                +"return set$NameUpperCamel(false);"
+            }
+        }
+    }
+}
+
+private fun ClassPrinter.generateBuilderBuild() {
+    +"/** Builds the instance. This builder should not be touched after calling this! */"
+    "public $ClassType build()" {
+        +"markUsed();"
+        fields.forEachApply {
+            if (!isNullable || hasDefault) {
+                "if ((mBuilderFieldsSet & $fieldBit) == 0)" {
+                    if (!isNullable && !hasDefault) {
+                        +"throw new IllegalStateException(\"Required field not set: $nameLowerCamel\");"
+                    } else {
+                        +"$name = $defaultExpr;"
+                    }
+                }
+            }
+        }
+        "$ClassType o = new $ClassType(" {
+            fields.forEachTrimmingTrailingComma {
+                +"$name,"
+            }
+        } + ";"
+        +"return o;"
+    }
+}
+
+fun ClassPrinter.generateParcelable() {
+    val booleanFields = fields.filter { it.Type == "boolean" }
+    val objectFields = fields.filter { it.Type !in PRIMITIVE_TYPES }
+    val nullableFields = objectFields.filter { it.mayBeNull }
+    val nonBooleanFields = fields - booleanFields
+
+
+    val flagStorageType = when (fields.size) {
+        in 0..7 -> "byte"
+        in 8..15 -> "int"
+        in 16..31 -> "long"
+        else -> throw NotImplementedError("32+ field classes not yet supported")
+    }
+    val FlagStorageType = flagStorageType.capitalize()
+
+    fields.forEachApply {
+        if (sParcelling != null) {
+            +GENERATED_MEMBER_HEADER
+            "static $Parcelling<$Type> $sParcelling =" {
+                "$Parcelling.Cache.get(" {
+                    +"$customParcellingClass.class"
+                } + ";"
+            }
+            "static {" {
+                "if ($sParcelling == null)" {
+                    "$sParcelling = $Parcelling.Cache.put(" {
+                        +"new $customParcellingClass()"
+                    } + ";"
+                }
+            }
+            +""
+        }
+    }
+
+    val Parcel = classRef("android.os.Parcel")
+    if (!hasMethod("writeToParcel", Parcel, "int")) {
+        +"@Override"
+        +GENERATED_MEMBER_HEADER
+        "public void writeToParcel($Parcel dest, int flags)" {
+            +"// You can override field parcelling by defining methods like:"
+            +"// void parcelFieldName(Parcel dest, int flags) { ... }"
+            +""
+
+            if (booleanFields.isNotEmpty() || nullableFields.isNotEmpty()) {
+                +"$flagStorageType flg = 0;"
+                booleanFields.forEachApply {
+                    +"if ($internalGetter) flg |= $fieldBit;"
+                }
+                nullableFields.forEachApply {
+                    +"if ($internalGetter != null) flg |= $fieldBit;"
+                }
+                +"dest.write$FlagStorageType(flg);"
+            }
+
+            nonBooleanFields.forEachApply {
+                val customParcellingMethod = "parcel$NameUpperCamel"
+                when {
+                    hasMethod(customParcellingMethod, Parcel, "int") ->
+                        +"$customParcellingMethod(dest, flags);"
+                    customParcellingClass != null -> +"$sParcelling.parcel($name, dest, flags);"
+                    hasAnnotation("@$DataClassEnum") ->
+                        +"dest.writeInt($internalGetter == null ? -1 : $internalGetter.ordinal());"
+                    else -> {
+                        if (mayBeNull) !"if ($internalGetter != null) "
+                        var args = internalGetter
+                        if (ParcelMethodsSuffix.startsWith("Parcelable")
+                                || ParcelMethodsSuffix.startsWith("TypedObject")
+                                || ParcelMethodsSuffix == "TypedArray") {
+                            args += ", flags"
+                        }
+                        +"dest.write$ParcelMethodsSuffix($args);"
+                    }
+                }
+            }
+        }
+    }
+
+    if (!hasMethod("describeContents")) {
+        +"@Override"
+        +GENERATED_MEMBER_HEADER
+        +"public int describeContents() { return 0; }"
+        +""
+    }
+
+    if (classAst.fields.none { it.variables[0].nameAsString == "CREATOR" }) {
+        val Creator = classRef("android.os.Parcelable.Creator")
+
+        +GENERATED_MEMBER_HEADER
+        "public static final @$NonNull $Creator<$ClassName> CREATOR" {
+            +"= new $Creator<$ClassName>()"
+        }; " {" {
+
+            +"@Override"
+            "public $ClassName[] newArray(int size)" {
+                +"return new $ClassName[size];"
+            }
+
+            +"@Override"
+            +"@SuppressWarnings({\"unchecked\", \"RedundantCast\"})"
+            "public $ClassName createFromParcel($Parcel in)" {
+                +"// You can override field unparcelling by defining methods like:"
+                +"// static FieldType unparcelFieldName(Parcel in) { ... }"
+                +""
+                if (booleanFields.isNotEmpty() || nullableFields.isNotEmpty()) {
+                    +"$flagStorageType flg = in.read$FlagStorageType();"
+                }
+                booleanFields.forEachApply {
+                    +"$Type $_name = (flg & $fieldBit) != 0;"
+                }
+                nonBooleanFields.forEachApply {
+
+                    // Handle customized parceling
+                    val customParcellingMethod = "unparcel$NameUpperCamel"
+                    if (hasMethod(customParcellingMethod, Parcel)) {
+                        +"$Type $_name = $customParcellingMethod(in);"
+                    } else if (customParcellingClass != null) {
+                        +"$Type $_name = $sParcelling.unparcel(in);"
+                    } else if (hasAnnotation("@$DataClassEnum")) {
+                        val ordinal = "${_name}Ordinal"
+                        +"int $ordinal = in.readInt();"
+                        +"$Type $_name = $ordinal < 0 ? null : $FieldClass.values()[$ordinal];"
+                    } else {
+                        val methodArgs = mutableListOf<String>()
+
+                        // Create container if any
+                        val containerInitExpr = when {
+                            FieldClass.endsWith("Map") -> "new $LinkedHashMap<>()"
+                            FieldClass == "List" || FieldClass == "ArrayList" ->
+                                "new ${classRef("java.util.ArrayList")}<>()"
+//                            isArray && FieldInnerType in (PRIMITIVE_TYPES + "String") ->
+//                                "new $FieldInnerType[in.readInt()]"
+                            else -> ""
+                        }
+                        val passContainer = containerInitExpr.isNotEmpty()
+
+                        // nullcheck +
+                        // "FieldType fieldName = (FieldType)"
+                        if (passContainer) {
+                            methodArgs.add(_name)
+                            !"$Type $_name = "
+                            if (mayBeNull) {
+                                +"null;"
+                                !"if ((flg & $fieldBit) != 0) {"
+                                pushIndent()
+                                +""
+                                !"$_name = "
+                            }
+                            +"$containerInitExpr;"
+                        } else {
+                            !"$Type $_name = "
+                            if (mayBeNull) !"(flg & $fieldBit) == 0 ? null : "
+                            if (ParcelMethodsSuffix == "StrongInterface") {
+                                !"$FieldClass.Stub.asInterface("
+                            } else if (Type !in PRIMITIVE_TYPES + "String" + "Bundle" &&
+                                    (!isArray || FieldInnerType !in PRIMITIVE_TYPES + "String") &&
+                                    ParcelMethodsSuffix != "Parcelable") {
+                                !"($Type) "
+                            }
+                        }
+
+                        // Determine method args
+                        when {
+                            ParcelMethodsSuffix == "Parcelable" ->
+                                methodArgs += "$FieldClass.class.getClassLoader()"
+                            ParcelMethodsSuffix == "TypedObject" ->
+                                methodArgs += "$FieldClass.CREATOR"
+                            ParcelMethodsSuffix == "TypedArray" ->
+                                methodArgs += "$FieldInnerClass.CREATOR"
+                            ParcelMethodsSuffix.startsWith("Parcelable")
+                                    || FieldClass == "Map"
+                                    || (isList || isArray)
+                                    && FieldInnerType !in PRIMITIVE_TYPES + "String" ->
+                                methodArgs += "$FieldInnerClass.class.getClassLoader()"
+                        }
+
+                        // ...in.readFieldType(args...);
+                        when {
+                            ParcelMethodsSuffix == "StrongInterface" -> !"in.readStrongBinder"
+                            isArray -> !"in.create$ParcelMethodsSuffix"
+                            else -> !"in.read$ParcelMethodsSuffix"
+                        }
+                        !"(${methodArgs.joinToString(", ")})"
+                        if (ParcelMethodsSuffix == "StrongInterface") !")"
+                        +";"
+
+                        // Cleanup if passContainer
+                        if (passContainer && mayBeNull) {
+                            popIndent()
+                            rmEmptyLine()
+                            +"\n}"
+                        }
+                    }
+                }
+                "return new $ClassType(" {
+                    fields.forEachTrimmingTrailingComma {
+                        +"$_name,"
+                    }
+                } + ";"
+            }
+            rmEmptyLine()
+        } + ";"
+        +""
+    }
+}
+
+fun ClassPrinter.generateEqualsHashcode() {
+    if (!hasMethod("equals", "Object")) {
+        +"@Override"
+        +GENERATED_MEMBER_HEADER
+        "public boolean equals(Object o)" {
+            +"// You can override field equality logic by defining either of the methods like:"
+            +"// boolean fieldNameEquals($ClassName other) { ... }"
+            +"// boolean fieldNameEquals(FieldType otherValue) { ... }"
+            +""
+            """if (this == o) return true;
+                        if (o == null || getClass() != o.getClass()) return false;
+                        @SuppressWarnings("unchecked")
+                        $ClassType that = ($ClassType) o;
+                        //noinspection PointlessBooleanExpression
+                        return true""" {
+                fields.forEachApply {
+                    val sfx = if (isLast) ";" else ""
+                    val customEquals = "${nameLowerCamel}Equals"
+                    when {
+                        hasMethod(customEquals, Type) -> +"&& $customEquals(that.$internalGetter)$sfx"
+                        hasMethod(customEquals, ClassType) -> +"&& $customEquals(that)$sfx"
+                        else -> +"&& ${isEqualToExpr("that.$internalGetter")}$sfx"
+                    }
+                }
+            }
+        }
+    }
+
+    if (!hasMethod("hashCode")) {
+        +"@Override"
+        +GENERATED_MEMBER_HEADER
+        "public int hashCode()" {
+            +"// You can override field hashCode logic by defining methods like:"
+            +"// int fieldNameHashCode() { ... }"
+            +""
+            +"int _hash = 1;"
+            fields.forEachApply {
+                !"_hash = 31 * _hash + "
+                val customHashCode = "${nameLowerCamel}HashCode"
+                when {
+                    hasMethod(customHashCode) -> +"$customHashCode();"
+                    Type == "int" || Type == "byte" -> +"$internalGetter;"
+                    Type in PRIMITIVE_TYPES -> +"${Type.capitalize()}.hashCode($internalGetter);"
+                    isArray -> +"${memberRef("java.util.Arrays.hashCode")}($internalGetter);"
+                    else -> +"${memberRef("java.util.Objects.hashCode")}($internalGetter);"
+                }
+            }
+            +"return _hash;"
+        }
+    }
+}
+
+//TODO support IntDef flags?
+fun ClassPrinter.generateToString() {
+    if (!hasMethod("toString")) {
+        +"@Override"
+        +GENERATED_MEMBER_HEADER
+        "public String toString()" {
+            +"// You can override field toString logic by defining methods like:"
+            +"// String fieldNameToString() { ... }"
+            +""
+            "return \"$ClassName { \" +" {
+                fields.forEachApply {
+                    val customToString = "${nameLowerCamel}ToString"
+                    val expr = when {
+                        hasMethod(customToString) -> "$customToString()"
+                        isArray -> "${memberRef("java.util.Arrays.toString")}($internalGetter)"
+                        intOrStringDef?.type?.isInt == true ->
+                            "${intOrStringDef!!.AnnotationName.decapitalize()}ToString($name)"
+                        else -> internalGetter
+                    }
+                    +"\"$nameLowerCamel = \" + $expr${if_(!isLast, " + \", \"")} +"
+                }
+            }
+            +"\" }\";"
+        }
+    }
+}
+
+fun ClassPrinter.generateSetters() {
+    fields.forEachApply {
+        if (!hasMethod("set$NameUpperCamel", Type)
+                && !fieldAst.isPublic
+                && !isFinal) {
+
+            generateFieldJavadoc(forceHide = FeatureFlag.SETTERS.hidden)
+            +GENERATED_MEMBER_HEADER
+            "public $ClassType set$NameUpperCamel($annotatedTypeForSetterParam value)" {
+                generateSetFrom("value")
+                +"return this;"
+            }
+        }
+    }
+}
+
+fun ClassPrinter.generateGetters() {
+    (fields + lazyTransientFields).forEachApply {
+        val methodPrefix = if (Type == "boolean") "is" else "get"
+        val methodName = methodPrefix + NameUpperCamel
+
+        if (!hasMethod(methodName) && !fieldAst.isPublic) {
+
+            generateFieldJavadoc(forceHide = FeatureFlag.GETTERS.hidden)
+            +GENERATED_MEMBER_HEADER
+            "public $annotationsAndType $methodName()" {
+                if (lazyInitializer == null) {
+                    +"return $name;"
+                } else {
+                    +"$Type $_name = $name;"
+                    "if ($_name == null)" {
+                        if (fieldAst.isVolatile) {
+                            "synchronized(this)" {
+                                +"$_name = $name;"
+                                "if ($_name == null)" {
+                                    +"$_name = $name = $lazyInitializer();"
+                                }
+                            }
+                        } else {
+                            +"// You can mark field as volatile for thread-safe double-check init"
+                            +"$_name = $name = $lazyInitializer();"
+                        }
+                    }
+                    +"return $_name;"
+                }
+            }
+        }
+    }
+}
+
+fun FieldInfo.generateFieldJavadoc(forceHide: Boolean = false) = classPrinter {
+    if (javadocFull != null || forceHide) {
+        var hidden = false
+        (javadocFull ?: "/**\n */").lines().forEach {
+            if (it.contains("@hide")) hidden = true
+            if (it.contains("*/") && forceHide && !hidden) {
+                if (javadocFull != null) +" *"
+                +" * @hide"
+            }
+            +it
+        }
+    }
+}
+
+fun FieldInfo.generateSetFrom(source: String) = classPrinter {
+    !"$name = "
+    if (Type in PRIMITIVE_TYPES || mayBeNull) {
+        +"$source;"
+    } else if (defaultExpr != null) {
+        "$source != null" {
+            +"? $source"
+            +": $defaultExpr;"
+        }
+    } else {
+        val checkNotNull = memberRef("com.android.internal.util.Preconditions.checkNotNull")
+        +"$checkNotNull($source);"
+    }
+    if (isNonEmpty) {
+        "if ($isEmptyExpr)" {
+            +"throw new IllegalArgumentException(\"$nameLowerCamel cannot be empty\");"
+        }
+    }
+}
+
+fun ClassPrinter.generateConstructor(visibility: String = "public") {
+    if (visibility == "public") {
+        generateConstructorJavadoc()
+    }
+    +GENERATED_MEMBER_HEADER
+    "$visibility $ClassName(" {
+        fields.forEachApply {
+            +"$annotationsAndType $nameLowerCamel${if_(!isLast, ",")}"
+        }
+    }
+    " {" {
+        fields.forEachApply {
+            !"this."
+            generateSetFrom(nameLowerCamel)
+        }
+
+        generateStateValidation()
+
+        generateOnConstructedCallback()
+    }
+}
+
+private fun ClassPrinter.generateConstructorJavadoc() {
+    if (fields.all { it.javadoc == null } && !FeatureFlag.CONSTRUCTOR.hidden) return
+    +"/**"
+    fields.filter { it.javadoc != null }.forEachApply {
+        javadocTextNoAnnotationLines?.apply {
+            +" * @param $nameLowerCamel"
+            forEach {
+                +" *   $it"
+            }
+        }
+    }
+    if (FeatureFlag.CONSTRUCTOR.hidden) +" * @hide"
+    +" */"
+}
+
+private fun ClassPrinter.generateStateValidation() {
+    val Size = classRef("android.annotation.Size")
+    val knownNonValidationAnnotations = internalAnnotations + Nullable
+
+    val validate = memberRef("com.android.internal.util.AnnotationValidations.validate")
+    fun appendValidateCall(annotation: AnnotationExpr, valueToValidate: String) {
+        "$validate(" {
+            !"${annotation.nameAsString}.class, null, $valueToValidate"
+            val params = when (annotation) {
+                is MarkerAnnotationExpr -> emptyMap()
+                is SingleMemberAnnotationExpr -> mapOf("value" to annotation.memberValue)
+                is NormalAnnotationExpr ->
+                    annotation.pairs.map { it.name.asString() to it.value }.toMap()
+                else -> throw IllegalStateException()
+            }
+            params.forEach { name, value ->
+                !",\n\"$name\", $value"
+            }
+        }
+        +";"
+    }
+
+    fields.forEachApply {
+        if (intOrStringDef != null) {
+            if (intOrStringDef!!.type == ConstDef.Type.INT_FLAGS) {
+                +""
+                +"//noinspection PointlessBitwiseExpression"
+                "$Preconditions.checkFlagsArgument(" {
+                    "$name, 0" {
+                        intOrStringDef!!.CONST_NAMES.forEach {
+                            +"| $it"
+                        }
+                    }
+                }
+                +";"
+            } else {
+                +""
+                +"//noinspection PointlessBooleanExpression"
+                "if (true" {
+                    intOrStringDef!!.CONST_NAMES.forEach { CONST_NAME ->
+                        +"&& !(${isEqualToExpr(CONST_NAME)})"
+                    }
+                }; rmEmptyLine(); ") {" {
+                    "throw new ${classRef<IllegalArgumentException>()}(" {
+                        "\"$nameLowerCamel was \" + $internalGetter + \" but must be one of: \"" {
+
+                            intOrStringDef!!.CONST_NAMES.forEachLastAware { CONST_NAME, isLast ->
+                                +"""+ "$CONST_NAME(" + $CONST_NAME + ")${if_(!isLast, ", ")}""""
+                            }
+                        }
+                    }
+                    +";"
+                }
+            }
+        }
+
+        val eachLine = fieldAst.annotations.find { it.nameAsString == Each }?.range?.orElse(null)?.end?.line
+        val perElementValidations = if (eachLine == null) emptyList() else fieldAst.annotations.filter {
+            it.nameAsString != Each &&
+                it.range.orElse(null)?.begin?.line?.let { it >= eachLine } ?: false
+        }
+
+        fieldAst.annotations.filterNot {
+            it.nameAsString == intOrStringDef?.AnnotationName
+                    || it.nameAsString in knownNonValidationAnnotations
+                    || it in perElementValidations
+        }.forEach { annotation ->
+            appendValidateCall(annotation,
+                    valueToValidate = if (annotation.nameAsString == Size) sizeExpr else name)
+        }
+
+        if (perElementValidations.isNotEmpty()) {
+            +"int ${nameLowerCamel}Size = $sizeExpr;"
+            "for (int i = 0; i < ${nameLowerCamel}Size; i++) {" {
+                perElementValidations.forEach { annotation ->
+                    appendValidateCall(annotation,
+                            valueToValidate = elemAtIndexExpr("i"))
+                }
+            }
+        }
+    }
+}
+
+private fun ClassPrinter.generateOnConstructedCallback(prefix: String = "") {
+    +""
+    val call = "${prefix}onConstructed();"
+    if (hasMethod("onConstructed")) {
+        +call
+    } else {
+        +"// $call // You can define this method to get a callback"
+    }
+}
+
+fun ClassPrinter.generateForEachField() {
+    val specializations = listOf("Object", "int")
+    val usedSpecializations = fields.map { if (it.Type in specializations) it.Type else "Object" }
+    val usedSpecializationsSet = usedSpecializations.toSet()
+
+    val PerObjectFieldAction = classRef("com.android.internal.util.DataClass.PerObjectFieldAction")
+
+    +GENERATED_MEMBER_HEADER
+    "void forEachField(" {
+        usedSpecializationsSet.toList().forEachLastAware { specType, isLast ->
+            val SpecType = specType.capitalize()
+            val ActionClass = classRef("com.android.internal.util.DataClass.Per${SpecType}FieldAction")
+            +"$ActionClass<$ClassType> action$SpecType${if_(!isLast, ",")}"
+        }
+    }; " {" {
+        usedSpecializations.forEachIndexed { i, specType ->
+            val SpecType = specType.capitalize()
+            fields[i].apply {
+                +"action$SpecType.accept$SpecType(this, \"$nameLowerCamel\", $name);"
+            }
+        }
+    }
+
+    if (usedSpecializationsSet.size > 1) {
+        +"/** @deprecated May cause boxing allocations - use with caution! */"
+        +"@Deprecated"
+        +GENERATED_MEMBER_HEADER
+        "void forEachField($PerObjectFieldAction<$ClassType> action)" {
+            fields.forEachApply {
+                +"action.acceptObject(this, \"$nameLowerCamel\", $name);"
+            }
+        }
+    }
+}
diff --git a/tools/codegen/src/com/android/codegen/InputSignaturesComputation.kt b/tools/codegen/src/com/android/codegen/InputSignaturesComputation.kt
new file mode 100644
index 0000000..d1dc88f
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/InputSignaturesComputation.kt
@@ -0,0 +1,122 @@
+package com.android.codegen
+
+import com.github.javaparser.ast.body.TypeDeclaration
+import com.github.javaparser.ast.expr.*
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations
+import com.github.javaparser.ast.type.ClassOrInterfaceType
+import com.github.javaparser.ast.type.Type
+
+
+fun ClassPrinter.getInputSignatures(): List<String> {
+    return classAst.fields.map { fieldAst ->
+        buildString {
+            append(fieldAst.modifiers.joinToString(" ") {it.asString()})
+            append(" ")
+            append(annotationsToString(fieldAst))
+            append(" ")
+            append(getFullClassName(fieldAst.commonType))
+            append(" ")
+            append(fieldAst.variables.joinToString(", ") { it.nameAsString })
+        }
+    } + classAst.methods.map { methodAst ->
+        buildString {
+            append(methodAst.modifiers.joinToString(" ") {it.asString()})
+            append(" ")
+            append(annotationsToString(methodAst))
+            append(" ")
+            append(getFullClassName(methodAst.type))
+            append(" ")
+            append(methodAst.nameAsString)
+            append("(")
+            append(methodAst.parameters.joinToString(",") {getFullClassName(it.type)})
+            append(")")
+        }
+    }
+}
+
+private fun ClassPrinter.annotationsToString(annotatedAst: NodeWithAnnotations<*>): String {
+    return annotatedAst.annotations.joinToString(" ") {
+        annotationToString(it)
+    }
+}
+
+private fun ClassPrinter.annotationToString(ann: AnnotationExpr): String {
+    return buildString {
+        append("@")
+        append(getFullClassName(ann.nameAsString))
+        if (ann is MarkerAnnotationExpr) return@buildString
+
+        append("(")
+
+        when (ann) {
+            is SingleMemberAnnotationExpr -> {
+                appendExpr(this, ann.memberValue)
+            }
+            is NormalAnnotationExpr -> {
+                ann.pairs.forEachLastAware { pair, isLast ->
+                    append(pair.nameAsString)
+                    append("=")
+                    appendExpr(this, pair.value)
+                    if (!isLast) append(", ")
+                }
+            }
+        }
+
+        append(")")
+    }.replace("\"", "\\\"")
+}
+
+private fun ClassPrinter.appendExpr(sb: StringBuilder, ex: Expression?) {
+    when (ex) {
+        is ClassExpr -> sb.append(getFullClassName(ex.typeAsString)).append(".class")
+        is IntegerLiteralExpr -> sb.append(ex.asInt()).append("L")
+        is LongLiteralExpr -> sb.append(ex.asLong()).append("L")
+        is DoubleLiteralExpr -> sb.append(ex.asDouble())
+        else -> sb.append(ex)
+    }
+}
+
+private fun ClassPrinter.getFullClassName(type: Type): String {
+    return if (type is ClassOrInterfaceType) {
+        getFullClassName(buildString {
+            type.scope.ifPresent { append(it).append(".") }
+            type.isArrayType
+            append(type.nameAsString)
+        }) + (type.typeArguments.orElse(null)?.let { args -> args.joinToString(", ") {getFullClassName(it)}}?.let { "<$it>" } ?: "")
+    } else getFullClassName(type.asString())
+}
+
+private fun ClassPrinter.getFullClassName(className: String): String {
+    if (className.endsWith("[]")) return getFullClassName(className.removeSuffix("[]")) + "[]"
+
+    if (className.matches("\\.[a-z]".toRegex())) return className //qualified name
+
+    if ("." in className) return getFullClassName(className.substringBeforeLast(".")) + "." + className.substringAfterLast(".")
+
+    fileAst.imports.find { imp ->
+        imp.nameAsString.endsWith(".$className")
+    }?.nameAsString?.let { return it }
+
+    val thisPackagePrefix = fileAst.packageDeclaration.map { it.nameAsString + "." }.orElse("")
+    val thisClassPrefix = thisPackagePrefix + classAst.nameAsString + "."
+
+    classAst.childNodes.filterIsInstance<TypeDeclaration<*>>().find {
+        it.nameAsString == className
+    }?.let { return thisClassPrefix + it.nameAsString }
+
+    constDefs.find { it.AnnotationName == className }?.let { return thisClassPrefix + className }
+
+    if (tryOrNull { Class.forName("java.lang.$className") } != null) {
+        return "java.lang.$className"
+    }
+
+    if (className[0].isLowerCase()) return className //primitive
+
+    return thisPackagePrefix + className
+}
+
+private inline fun <T> tryOrNull(f: () -> T?) = try {
+    f()
+} catch (e: Exception) {
+    null
+}
diff --git a/tools/codegen/src/com/android/codegen/Main.kt b/tools/codegen/src/com/android/codegen/Main.kt
new file mode 100755
index 0000000..8fafa7c
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/Main.kt
@@ -0,0 +1,199 @@
+package com.android.codegen
+
+import java.io.File
+
+
+const val THIS_SCRIPT_LOCATION = ""
+const val GENERATED_WARNING_PREFIX = "Code below generated by $CODEGEN_NAME"
+const val INDENT_SINGLE = "    "
+
+val PRIMITIVE_TYPES = listOf("byte", "short", "int", "long", "char", "float", "double", "boolean")
+
+const val CANONICAL_BUILDER_CLASS = "Builder"
+const val GENERATED_BUILDER_CLASS = "GeneratedBuilder"
+
+val BUILTIN_SPECIAL_PARCELLINGS = listOf("Pattern")
+
+const val FLAG_BUILDER_PROTECTED_SETTERS = "--builder-protected-setters"
+const val FLAG_NO_FULL_QUALIFIERS = "--no-full-qualifiers"
+
+
+/** @see [FeatureFlag] */
+val USAGE = """
+Usage: $CODEGEN_NAME [--[PREFIX-]FEATURE...] JAVAFILE
+
+Generates boilerplade parcelable/data class code at the bottom of JAVAFILE, based o fields' declaration in the given JAVAFILE's top-level class
+
+FEATURE represents some generatable code, and can be among:
+${FeatureFlag.values().map { feature ->
+    "  ${feature.kebabCase}" to feature.desc
+}.columnize(" - ")}
+
+And PREFIX can be:
+  <empty> - request to generate the feature
+    no    - suppress generation of the feature
+  hidden  - request to generate the feature with @hide
+
+Extra options:
+  --help        - view this help
+  --update-only - auto-detect flags from the previously auto-generated comment within the file
+  $FLAG_NO_FULL_QUALIFIERS
+                - when referring to classes don't use package name prefix; handy with IDE auto-import
+  $FLAG_BUILDER_PROTECTED_SETTERS
+                - make builder's setters protected to expose them as public in a subclass on a whitelist basis
+
+
+Special field modifiers and annotations:
+  transient                 - ignore the field completely
+  @Nullable                 - support null value when parcelling, and never throw on null input
+  @NonNull                  - throw on null input and don't parcel the nullness bit for the field
+  @DataClass.Enum           - parcel field as an enum value by ordinal
+  @DataClass.PluralOf(..)   - provide a singular version of a collection field name to be used in the builder's 'addFoo(..)'
+  @DataClass.ParcelWith(..) - provide a custom Parcelling class, specifying the custom (un)parcelling logic for this field
+  = <initializer>;          - provide default value and never throw if this field was not provided e.g. when using builder
+  /** ... */                - copy given javadoc on field's getters/setters/constructor params/builder setters etc.
+  @hide (in javadoc)        - force field's getters/setters/withers/builder setters to be @hide-den if generated
+
+
+Special methods/etc. you can define:
+
+  <any auto-generatable method>
+      For any method to be generated, if a method with same name and argument types is already
+      defined, than that method will not be generated.
+      This allows you to override certain details on granular basis.
+
+  void onConstructed()
+      Will be called in constructor, after all the fields have been initialized.
+      This is a good place to put any custom validation logic that you may have
+
+  static class $CANONICAL_BUILDER_CLASS extends $GENERATED_BUILDER_CLASS
+      If a class extending $GENERATED_BUILDER_CLASS is specified, generated builder's setters will
+      return the provided $CANONICAL_BUILDER_CLASS type.
+      $GENERATED_BUILDER_CLASS's constructor(s) will be package-private to encourage using $CANONICAL_BUILDER_CLASS instead
+      This allows you to extend the generated builder, adding or overriding any methods you may want
+
+
+In addition, for any field mMyField(or myField) of type FieldType you can define the following methods:
+
+  void parcelMyField(Parcel dest, int flags)
+      Allows you to provide custom logic for storing mMyField into a Parcel
+
+  static FieldType unparcelMyField(Parcel in)
+      Allows you to provide custom logic to deserialize the value of mMyField from a Parcel
+
+  String myFieldToString()
+      Allows you to provide a custom toString representation of mMyField's value
+
+  FieldType lazyInitMyField()
+      Requests a lazy initialization in getMyField(), with the provided method being the constructor
+      You may additionally mark the fields as volatile to cause this to generate a thread-safe
+      double-check locking lazy initialization
+
+  FieldType defaultMyField()
+      Allows you to provide a default value to initialize the field to, in case an explicit one
+      was not provided.
+      This is an alternative to providing a field initializer that, unlike the initializer,
+      you can use with final fields.
+
+Version: $CODEGEN_VERSION
+Questions? Feedback? Contact: eugenesusla@
+"""
+
+fun main(args: Array<String>) {
+    if (args.contains("--help")) {
+        println(USAGE)
+        System.exit(0)
+    }
+    if (args.contains("--version")) {
+        println(CODEGEN_VERSION)
+        System.exit(0)
+    }
+    val file = File(args.last())
+    val sourceLinesNoClosingBrace = file.readLines().dropLastWhile {
+        it.startsWith("}") || it.all(Char::isWhitespace)
+    }
+    val cliArgs = handleUpdateFlag(args, sourceLinesNoClosingBrace)
+    val sourceLinesAsIs = discardGeneratedCode(sourceLinesNoClosingBrace)
+    val sourceLines = sourceLinesAsIs
+            .filterNot { it.trim().startsWith("//") }
+            .map { it.trimEnd().dropWhile { it == '\n' } }
+
+    val stringBuilder = StringBuilder(sourceLinesAsIs.joinToString("\n"))
+    ClassPrinter(sourceLines, stringBuilder, cliArgs).run {
+
+        val cliExecutable = "$THIS_SCRIPT_LOCATION$CODEGEN_NAME"
+        val fileEscaped = file.absolutePath.replace(
+                System.getenv("ANDROID_BUILD_TOP"), "\$ANDROID_BUILD_TOP")
+
+
+        +"""
+
+
+
+        // $GENERATED_WARNING_PREFIX v$CODEGEN_VERSION.
+        //   on ${currentTimestamp()}
+        //
+        // DO NOT MODIFY!
+        //
+        // To regenerate run:
+        // $ $cliExecutable ${cliArgs.dropLast(1).joinToString("") { "$it " }}$fileEscaped
+        //
+        // CHECKSTYLE:OFF Generated code
+        """
+
+        if (FeatureFlag.CONST_DEFS()) generateConstDefs()
+
+        "@$DataClassGenerated(" {
+            +"time = ${System.currentTimeMillis()}L,"
+            +"codegenVersion = \"$CODEGEN_VERSION\","
+            +"sourceFile = \"${file.relativeTo(File(System.getenv("ANDROID_BUILD_TOP")))}\","
+            +"inputSignatures = \"${getInputSignatures().joinToString("\\n")}\""
+        }
+        +"\n"
+
+
+        if (FeatureFlag.CONSTRUCTOR()) {
+            generateConstructor("public")
+        } else if (FeatureFlag.BUILDER()
+                || FeatureFlag.COPY_CONSTRUCTOR()
+                || FeatureFlag.WITHERS()
+                || FeatureFlag.PARCELABLE()) {
+            generateConstructor("/* package-private */")
+        }
+
+        if (FeatureFlag.GETTERS()) generateGetters()
+        if (FeatureFlag.SETTERS()) generateSetters()
+        if (FeatureFlag.TO_STRING()) generateToString()
+        if (FeatureFlag.EQUALS_HASH_CODE()) generateEqualsHashcode()
+
+        if (FeatureFlag.FOR_EACH_FIELD()) generateForEachField()
+
+        if (FeatureFlag.COPY_CONSTRUCTOR()) generateCopyConstructor()
+        if (FeatureFlag.WITHERS()) generateWithers()
+
+        if (FeatureFlag.PARCELABLE()) generateParcelable()
+
+        if (FeatureFlag.BUILDER() && FeatureFlag.BUILD_UPON()) generateBuildUpon()
+        if (FeatureFlag.BUILDER()) generateBuilder()
+
+        if (FeatureFlag.AIDL()) generateAidl(file)
+
+        rmEmptyLine()
+    }
+    stringBuilder.append("\n}\n")
+    file.writeText(stringBuilder.toString().mapLines { trimEnd() })
+}
+
+internal fun discardGeneratedCode(sourceLinesNoClosingBrace: List<String>): List<String> {
+    return sourceLinesNoClosingBrace
+            .takeWhile { GENERATED_WARNING_PREFIX !in it }
+            .dropLastWhile(String::isBlank)
+}
+
+private fun handleUpdateFlag(cliArgs: Array<String>, sourceLines: List<String>): Array<String> {
+    if ("--update-only" in cliArgs
+            && sourceLines.none { GENERATED_WARNING_PREFIX in it || it.startsWith("@DataClass") }) {
+        System.exit(0)
+    }
+    return cliArgs - "--update-only"
+}
\ No newline at end of file
diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt
new file mode 100644
index 0000000..41641f6
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt
@@ -0,0 +1,4 @@
+package com.android.codegen
+
+const val CODEGEN_NAME = "codegen"
+const val CODEGEN_VERSION = "0.0.1"
\ No newline at end of file
diff --git a/tools/codegen/src/com/android/codegen/Utils.kt b/tools/codegen/src/com/android/codegen/Utils.kt
new file mode 100644
index 0000000..95c9909
--- /dev/null
+++ b/tools/codegen/src/com/android/codegen/Utils.kt
@@ -0,0 +1,76 @@
+package com.android.codegen
+
+import com.github.javaparser.ast.expr.AnnotationExpr
+import com.github.javaparser.ast.expr.Expression
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
+import java.time.Instant
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
+import java.time.format.FormatStyle
+
+/**
+ * [Iterable.forEach] + [Any.apply]
+ */
+inline fun <T> Iterable<T>.forEachApply(block: T.() -> Unit) = forEach(block)
+
+inline fun String.mapLines(f: String.() -> String?) = lines().mapNotNull(f).joinToString("\n")
+inline fun <T> Iterable<T>.trim(f: T.() -> Boolean) = dropWhile(f).dropLastWhile(f)
+fun String.trimBlankLines() = lines().trim { isBlank() }.joinToString("\n")
+
+fun Char.isNewline() = this == '\n' || this == '\r'
+fun Char.isWhitespaceNonNewline() = isWhitespace() && !isNewline()
+
+fun if_(cond: Boolean, then: String) = if (cond) then else ""
+
+inline infix fun Int.times(action: () -> Unit) {
+    for (i in 1..this) action()
+}
+
+/**
+ * a bbb
+ * cccc dd
+ *
+ * ->
+ *
+ * a    bbb
+ * cccc dd
+ */
+fun Iterable<Pair<String, String>>.columnize(separator: String = " | "): String {
+    val col1w = map { (a, _) -> a.length }.max()!!
+    val col2w = map { (_, b) -> b.length }.max()!!
+    return map { it.first.padEnd(col1w) + separator + it.second.padEnd(col2w) }.joinToString("\n")
+}
+
+fun String.hasUnbalancedCurlyBrace(): Boolean {
+    var braces = 0
+    forEach {
+        if (it == '{') braces++
+        if (it == '}') braces--
+        if (braces < 0) return true
+    }
+    return false
+}
+
+fun String.toLowerCamel(): String {
+    if (length >= 2 && this[0] == 'm' && this[1].isUpperCase()) return substring(1).capitalize()
+    if (all { it.isLetterOrDigit() }) return decapitalize()
+    return split("[^a-zA-Z0-9]".toRegex())
+            .map { it.toLowerCase().capitalize() }
+            .joinToString("")
+            .decapitalize()
+}
+
+inline fun <T> List<T>.forEachLastAware(f: (T, Boolean) -> Unit) {
+    forEachIndexed { index, t -> f(t, index == size - 1) }
+}
+
+@Suppress("UNCHECKED_CAST")
+fun <T : Expression> AnnotationExpr.singleArgAs()
+        = ((this as SingleMemberAnnotationExpr).memberValue as T)
+
+inline operator fun <reified T> Array<T>.minus(item: T) = toList().minus(item).toTypedArray()
+
+fun currentTimestamp() = DateTimeFormatter
+        .ofLocalizedDateTime(/* date */ FormatStyle.MEDIUM, /* time */ FormatStyle.LONG)
+        .withZone(ZoneId.systemDefault())
+        .format(Instant.now())
\ No newline at end of file
diff --git a/tools/dump-coverage/Android.bp b/tools/dump-coverage/Android.bp
new file mode 100644
index 0000000..4519ce3
--- /dev/null
+++ b/tools/dump-coverage/Android.bp
@@ -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.
+//
+
+// Build variants {target,host} x {32,64}
+cc_library {
+    name: "libdumpcoverage",
+    srcs: ["dump_coverage.cc"],
+    header_libs: [
+        "libopenjdkjvmti_headers",
+    ],
+
+    host_supported: true,
+    shared_libs: [
+        "libbase",
+    ],
+}
diff --git a/tools/dump-coverage/README.md b/tools/dump-coverage/README.md
new file mode 100644
index 0000000..2bab4bc
--- /dev/null
+++ b/tools/dump-coverage/README.md
@@ -0,0 +1,50 @@
+# dumpcoverage
+
+libdumpcoverage.so is a JVMTI agent designed to dump coverage information for a process, where the binaries have been instrumented by JaCoCo. JaCoCo automatically starts recording data on process start, and we need a way to trigger the resetting or dumping of this data.
+
+The JVMTI agent is used to make the calls to JaCoCo in its process.
+
+# Usage
+
+Note that these examples assume you have an instrumented build (userdebug_coverage). Here is, for example, how to dump coverage information regarding the default clock app. First some setup is necessary:
+
+```
+adb root # necessary to copy files in/out of the /data/data/{package} folder
+adb shell 'mkdir /data/data/com.android.deskclock/folder-to-use'
+```
+
+Then we can run the command to dump the data:
+
+```
+adb shell 'am attach-agent com.android.deskclock /system/lib/libdumpcoverage.so=dump:/data/data/com.android.deskclock/folder-to-use'
+```
+
+We can also reset the coverage information with
+
+```
+adb shell 'am attach-agent com.android.deskclock /system/lib/libdumpcoverage.so=reset'
+```
+
+then perform more actions, then dump the data again. To get the files, we can get
+
+```
+adb pull /data/data/com.android.deskclock/folder-to-use ~/path-on-your-computer
+```
+
+And you should have timestamped `.exec` files on your machine under the folder `~/path-on-your-computer`
+
+# Details
+
+In dump mode, the agent makes JNI calls equivalent to
+
+```
+Agent.getInstance().getExecutionData(/*reset = */ false);
+```
+
+and then saves the result to a file specified by the passed in directory
+
+In reset mode, it makes a JNI call equivalent to
+
+```
+Agent.getInstance().reset();
+```
diff --git a/tools/dump-coverage/dump_coverage.cc b/tools/dump-coverage/dump_coverage.cc
new file mode 100644
index 0000000..3de1865
--- /dev/null
+++ b/tools/dump-coverage/dump_coverage.cc
@@ -0,0 +1,239 @@
+// 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.
+//
+
+#include <android-base/logging.h>
+#include <jni.h>
+#include <jvmti.h>
+#include <string.h>
+
+#include <atomic>
+#include <ctime>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <istream>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+using std::get;
+using std::tuple;
+using std::chrono::system_clock;
+
+namespace dump_coverage {
+
+#define CHECK_JVMTI(x) CHECK_EQ((x), JVMTI_ERROR_NONE)
+#define CHECK_NOTNULL(x) CHECK((x) != nullptr)
+#define CHECK_NO_EXCEPTION(env) CHECK(!(env)->ExceptionCheck());
+
+static JavaVM* java_vm = nullptr;
+
+// Get the current JNI environment.
+static JNIEnv* GetJNIEnv() {
+  JNIEnv* env = nullptr;
+  CHECK_EQ(java_vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6),
+           JNI_OK);
+  return env;
+}
+
+// Get the JaCoCo Agent class and an instance of the class, given a JNI
+// environment.
+// Will crash if the Agent isn't found or if any Java Exception occurs.
+static tuple<jclass, jobject> GetJavaAgent(JNIEnv* env) {
+  jclass java_agent_class =
+      env->FindClass("org/jacoco/agent/rt/internal/Agent");
+  CHECK_NOTNULL(java_agent_class);
+
+  jmethodID java_agent_get_instance =
+      env->GetStaticMethodID(java_agent_class, "getInstance",
+                             "()Lorg/jacoco/agent/rt/internal/Agent;");
+  CHECK_NOTNULL(java_agent_get_instance);
+
+  jobject java_agent_instance =
+      env->CallStaticObjectMethod(java_agent_class, java_agent_get_instance);
+  CHECK_NO_EXCEPTION(env);
+  CHECK_NOTNULL(java_agent_instance);
+
+  return tuple(java_agent_class, java_agent_instance);
+}
+
+// Runs equivalent of Agent.getInstance().getExecutionData(false) and returns
+// the result.
+// Will crash if the Agent isn't found or if any Java Exception occurs.
+static jbyteArray GetExecutionData(JNIEnv* env) {
+  auto java_agent = GetJavaAgent(env);
+  jmethodID java_agent_get_execution_data =
+      env->GetMethodID(get<0>(java_agent), "getExecutionData", "(Z)[B");
+  CHECK_NO_EXCEPTION(env);
+  CHECK_NOTNULL(java_agent_get_execution_data);
+
+  jbyteArray java_result_array = (jbyteArray)env->CallObjectMethod(
+      get<1>(java_agent), java_agent_get_execution_data, false);
+  CHECK_NO_EXCEPTION(env);
+
+  return java_result_array;
+}
+
+// Gets the filename to write execution data to
+//  dirname: the directory in which to place the file
+//  outputs <dirname>/YYYY-MM-DD-HH-MM-SS.SSS.exec
+static std::string GetFilename(const std::string& dirname) {
+  system_clock::time_point time_point = system_clock::now();
+  auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(time_point);
+  auto fractional_time = time_point - seconds;
+  auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(fractional_time);
+
+  std::time_t time = system_clock::to_time_t(time_point);
+  auto tm = *std::gmtime(&time);
+
+  std::ostringstream oss;
+  oss
+    << dirname
+    << "/"
+    << std::put_time(&tm, "%Y-%m-%d-%H-%M-%S.")
+    << std::setfill('0') << std::setw(3) << millis.count()
+    << ".ec";
+  return oss.str();
+}
+
+// Writes the execution data to a file
+//  data, length: represent the data, as a sequence of bytes
+//  dirname: directory name to contain the file
+//  returns JNI_ERR if there is an error in writing the file, otherwise JNI_OK.
+static jint WriteFile(const char* data, int length, const std::string& dirname) {
+  auto filename = GetFilename(dirname);
+
+  LOG(INFO) << "Writing file of length " << length << " to '" << filename
+            << "'";
+  std::ofstream file(filename, std::ios::binary);
+
+  if (!file.is_open()) {
+    LOG(ERROR) << "Could not open file: '" << filename << "'";
+    return JNI_ERR;
+  }
+  file.write(data, length);
+  file.close();
+
+  if (!file) {
+    LOG(ERROR) << "I/O error in reading file";
+    return JNI_ERR;
+  }
+
+  LOG(INFO) << "Done writing file";
+  return JNI_OK;
+}
+
+// Grabs execution data and writes it to a file
+//  dirname: directory name to contain the file
+//  returns JNI_ERR if there is an error writing the file.
+// Will crash if the Agent isn't found or if any Java Exception occurs.
+static jint Dump(const std::string& dirname) {
+  LOG(INFO) << "Dumping file";
+
+  JNIEnv* env = GetJNIEnv();
+  jbyteArray java_result_array = GetExecutionData(env);
+  CHECK_NOTNULL(java_result_array);
+
+  jbyte* result_ptr = env->GetByteArrayElements(java_result_array, 0);
+  CHECK_NOTNULL(result_ptr);
+
+  int result_len = env->GetArrayLength(java_result_array);
+
+  return WriteFile((const char*) result_ptr, result_len, dirname);
+}
+
+// Resets execution data, performing the equivalent of
+//  Agent.getInstance().reset();
+//  args: should be empty
+//  returns JNI_ERR if the arguments are invalid.
+// Will crash if the Agent isn't found or if any Java Exception occurs.
+static jint Reset(const std::string& args) {
+  if (args != "") {
+    LOG(ERROR) << "reset takes no arguments, but received '" << args << "'";
+    return JNI_ERR;
+  }
+
+  JNIEnv* env = GetJNIEnv();
+  auto java_agent = GetJavaAgent(env);
+
+  jmethodID java_agent_reset =
+      env->GetMethodID(get<0>(java_agent), "reset", "()V");
+  CHECK_NOTNULL(java_agent_reset);
+
+  env->CallVoidMethod(get<1>(java_agent), java_agent_reset);
+  CHECK_NO_EXCEPTION(env);
+  return JNI_OK;
+}
+
+// Given a string of the form "<a>:<b>" returns (<a>, <b>).
+// Given a string <a> that doesn't contain a colon, returns (<a>, "").
+static tuple<std::string, std::string> SplitOnColon(const std::string& options) {
+  size_t loc_delim = options.find(':');
+  std::string command, args;
+
+  if (loc_delim == std::string::npos) {
+    command = options;
+  } else {
+    command = options.substr(0, loc_delim);
+    args = options.substr(loc_delim + 1, options.length());
+  }
+  return tuple(command, args);
+}
+
+// Parses and executes a command specified by options of the form
+// "<command>:<args>" where <command> is either "dump" or "reset".
+static jint ParseOptionsAndExecuteCommand(const std::string& options) {
+  auto split = SplitOnColon(options);
+  auto command = get<0>(split), args = get<1>(split);
+
+  LOG(INFO) << "command: '" << command << "' args: '" << args << "'";
+
+  if (command == "dump") {
+    return Dump(args);
+  }
+
+  if (command == "reset") {
+    return Reset(args);
+  }
+
+  LOG(ERROR) << "Invalid command: expected 'dump' or 'reset' but was '"
+             << command << "'";
+  return JNI_ERR;
+}
+
+static jint AgentStart(JavaVM* vm, char* options) {
+  android::base::InitLogging(/* argv= */ nullptr);
+  java_vm = vm;
+
+  return ParseOptionsAndExecuteCommand(options);
+}
+
+// Late attachment (e.g. 'am attach-agent').
+extern "C" JNIEXPORT jint JNICALL
+Agent_OnAttach(JavaVM* vm, char* options, void* reserved ATTRIBUTE_UNUSED) {
+  return AgentStart(vm, options);
+}
+
+// Early attachment.
+extern "C" JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM* jvm ATTRIBUTE_UNUSED, char* options ATTRIBUTE_UNUSED, void* reserved ATTRIBUTE_UNUSED) {
+  LOG(ERROR)
+    << "The dumpcoverage agent will not work on load,"
+    << " as it does not have access to the runtime.";
+  return JNI_ERR;
+}
+
+}  // namespace dump_coverage
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index c9c0edc..91f875e 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -408,9 +408,10 @@
     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) {
-            continue;
+        if (field->type() != FieldDescriptor::TYPE_MESSAGE &&
+            field->type() != FieldDescriptor::TYPE_STRING &&
+            field->type() != FieldDescriptor::TYPE_BYTES) {
+          continue;
         }
 
         const SectionFlags s = getSectionFlags(field);
diff --git a/tools/lock_agent/Android.bp b/tools/lock_agent/Android.bp
index c54e5b5..79dce4a 100644
--- a/tools/lock_agent/Android.bp
+++ b/tools/lock_agent/Android.bp
@@ -12,11 +12,9 @@
     ],
     sdk_version: "current",
     stl: "c++_static",
-    include_dirs: [
-        // NDK headers aren't available in platform NDK builds.
-        "libnativehelper/include_jni",
-    ],
     header_libs: [
+        // Use ScopedUtfChars.
+        "libnativehelper_header_only",
         "libopenjdkjvmti_headers",
     ],
     compile_multilib: "both",
@@ -30,11 +28,9 @@
         "libz",
         "slicer",
     ],
-    include_dirs: [
-        // NDK headers aren't available in platform NDK builds.
-        "libnativehelper/include_jni",
-    ],
     header_libs: [
+        // Use ScopedUtfChars.
+        "libnativehelper_header_only",
         "libopenjdkjvmti_headers",
     ],
 }
@@ -51,11 +47,22 @@
     installable: true,
 }
 
+cc_binary {
+    name: "lockagent_crasher",
+    srcs: ["crasher.cpp"],
+    static_libs: ["libbase_ndk"],
+    shared_libs: ["liblog"],
+    sdk_version: "current",
+    stl: "c++_static",
+    compile_multilib: "first",
+}
+
 sh_binary {
     name: "start_with_lockagent",
     src: "start_with_lockagent.sh",
     required: [
         "liblockagent",
         "lockagent",
+        "lockagent_crasher",
     ],
 }
diff --git a/tools/lock_agent/agent.cpp b/tools/lock_agent/agent.cpp
index 59bfa2b..40293b6 100644
--- a/tools/lock_agent/agent.cpp
+++ b/tools/lock_agent/agent.cpp
@@ -19,6 +19,8 @@
 #include <memory>
 #include <sstream>
 
+#include <unistd.h>
+
 #include <jni.h>
 
 #include <jvmti.h>
@@ -26,10 +28,14 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/macros.h>
+#include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <nativehelper/scoped_utf_chars.h>
 
 // We need dladdr.
 #if !defined(__APPLE__) && !defined(_WIN32)
@@ -61,6 +67,8 @@
 namespace {
 
 JavaVM* gJavaVM = nullptr;
+bool gForkCrash = false;
+bool gJavaCrash = false;
 
 // Converts a class name to a type descriptor
 // (ex. "java.lang.String" to "Ljava/lang/String;")
@@ -77,118 +85,143 @@
 using namespace dex;
 using namespace lir;
 
-bool transform(std::shared_ptr<ir::DexFile> dexIr) {
-    bool modified = false;
+class Transformer {
+public:
+    explicit Transformer(std::shared_ptr<ir::DexFile> dexIr) : dexIr_(dexIr) {}
 
-    std::unique_ptr<ir::Builder> builder;
+    bool transform() {
+        bool classModified = false;
 
-    for (auto& method : dexIr->encoded_methods) {
-        // Do not look into abstract/bridge/native/synthetic methods.
-        if ((method->access_flags & (kAccAbstract | kAccBridge | kAccNative | kAccSynthetic))
-                != 0) {
-            continue;
+        std::unique_ptr<ir::Builder> builder;
+
+        for (auto& method : dexIr_->encoded_methods) {
+            // Do not look into abstract/bridge/native/synthetic methods.
+            if ((method->access_flags & (kAccAbstract | kAccBridge | kAccNative | kAccSynthetic))
+                    != 0) {
+                continue;
+            }
+
+            struct HookVisitor: public Visitor {
+                HookVisitor(Transformer* transformer, CodeIr* c_ir)
+                        : transformer(transformer), cIr(c_ir) {
+                }
+
+                bool Visit(Bytecode* bytecode) override {
+                    if (bytecode->opcode == OP_MONITOR_ENTER) {
+                        insertHook(bytecode, true,
+                                reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
+                        return true;
+                    }
+                    if (bytecode->opcode == OP_MONITOR_EXIT) {
+                        insertHook(bytecode, false,
+                                reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
+                        return true;
+                    }
+                    return false;
+                }
+
+                void insertHook(lir::Instruction* before, bool pre, u4 reg) {
+                    transformer->preparePrePost();
+                    transformer->addCall(cIr, before, OP_INVOKE_STATIC_RANGE,
+                            transformer->hookType_, pre ? "preLock" : "postLock",
+                            transformer->voidType_, transformer->objectType_, reg);
+                    myModified = true;
+                }
+
+                Transformer* transformer;
+                CodeIr* cIr;
+                bool myModified = false;
+            };
+
+            CodeIr c(method.get(), dexIr_);
+            bool methodModified = false;
+
+            HookVisitor visitor(this, &c);
+            for (auto it = c.instructions.begin(); it != c.instructions.end(); ++it) {
+                lir::Instruction* fi = *it;
+                fi->Accept(&visitor);
+            }
+            methodModified |= visitor.myModified;
+
+            if (methodModified) {
+                classModified = true;
+                c.Assemble();
+            }
         }
 
-        struct HookVisitor: public Visitor {
-            HookVisitor(std::unique_ptr<ir::Builder>* b, std::shared_ptr<ir::DexFile> d_ir,
-                    CodeIr* c_ir) :
-                    b(b), dIr(d_ir), cIr(c_ir) {
-            }
+        return classModified;
+    }
 
-            bool Visit(Bytecode* bytecode) override {
-                if (bytecode->opcode == OP_MONITOR_ENTER) {
-                    prepare();
-                    addCall(bytecode, OP_INVOKE_STATIC_RANGE, hookType, "preLock", voidType,
-                            objectType, reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
-                    myModified = true;
-                    return true;
-                }
-                if (bytecode->opcode == OP_MONITOR_EXIT) {
-                    prepare();
-                    addCall(bytecode, OP_INVOKE_STATIC_RANGE, hookType, "postLock", voidType,
-                            objectType, reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
-                    myModified = true;
-                    return true;
-                }
-                return false;
-            }
+private:
+    void preparePrePost() {
+        // Insert "void LockHook.(pre|post)(Object o)."
 
-            void prepare() {
-                if (*b == nullptr) {
-                    *b = std::unique_ptr<ir::Builder>(new ir::Builder(dIr));
-                }
-                if (voidType == nullptr) {
-                    voidType = (*b)->GetType("V");
-                    hookType = (*b)->GetType("Lcom/android/lock_checker/LockHook;");
-                    objectType = (*b)->GetType("Ljava/lang/Object;");
-                }
-            }
+        prepareBuilder();
 
-            void addInst(lir::Instruction* instructionAfter, Opcode opcode,
-                    const std::list<Operand*>& operands) {
-                auto instruction = cIr->Alloc<Bytecode>();
-
-                instruction->opcode = opcode;
-
-                for (auto it = operands.begin(); it != operands.end(); it++) {
-                    instruction->operands.push_back(*it);
-                }
-
-                cIr->instructions.InsertBefore(instructionAfter, instruction);
-            }
-
-            void addCall(lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
-                    const char* methodName, ir::Type* returnType,
-                    const std::vector<ir::Type*>& types, const std::list<int>& regs) {
-                auto proto = (*b)->GetProto(returnType, (*b)->GetTypeList(types));
-                auto method = (*b)->GetMethodDecl((*b)->GetAsciiString(methodName), proto, type);
-
-                VRegList* paramRegs = cIr->Alloc<VRegList>();
-                for (auto it = regs.begin(); it != regs.end(); it++) {
-                    paramRegs->registers.push_back(*it);
-                }
-
-                addInst(instructionAfter, opcode,
-                        { paramRegs, cIr->Alloc<Method>(method, method->orig_index) });
-            }
-
-            void addCall(lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
-                    const char* methodName, ir::Type* returnType, ir::Type* paramType,
-                    u4 paramVReg) {
-                auto proto = (*b)->GetProto(returnType, (*b)->GetTypeList( { paramType }));
-                auto method = (*b)->GetMethodDecl((*b)->GetAsciiString(methodName), proto, type);
-
-                VRegRange* args = cIr->Alloc<VRegRange>(paramVReg, 1);
-
-                addInst(instructionAfter, opcode,
-                        { args, cIr->Alloc<Method>(method, method->orig_index) });
-            }
-
-            std::unique_ptr<ir::Builder>* b;
-            std::shared_ptr<ir::DexFile> dIr;
-            CodeIr* cIr;
-            ir::Type* voidType = nullptr;
-            ir::Type* hookType = nullptr;
-            ir::Type* objectType = nullptr;
-            bool myModified = false;
-        };
-
-        CodeIr c(method.get(), dexIr);
-        HookVisitor visitor(&builder, dexIr, &c);
-
-        for (auto it = c.instructions.begin(); it != c.instructions.end(); ++it) {
-            lir::Instruction* fi = *it;
-            fi->Accept(&visitor);
+        if (voidType_ == nullptr) {
+            voidType_ = builder_->GetType("V");
         }
-
-        if (visitor.myModified) {
-            modified = true;
-            c.Assemble();
+        if (hookType_ == nullptr) {
+            hookType_ = builder_->GetType("Lcom/android/lock_checker/LockHook;");
+        }
+        if (objectType_ == nullptr) {
+            objectType_ = builder_->GetType("Ljava/lang/Object;");
         }
     }
 
-    return modified;
-}
+    void prepareBuilder() {
+        if (builder_ == nullptr) {
+            builder_ = std::unique_ptr<ir::Builder>(new ir::Builder(dexIr_));
+        }
+    }
+
+    static void addInst(CodeIr* cIr, lir::Instruction* instructionAfter, Opcode opcode,
+            const std::list<Operand*>& operands) {
+        auto instruction = cIr->Alloc<Bytecode>();
+
+        instruction->opcode = opcode;
+
+        for (auto it = operands.begin(); it != operands.end(); it++) {
+            instruction->operands.push_back(*it);
+        }
+
+        cIr->instructions.InsertBefore(instructionAfter, instruction);
+    }
+
+    void addCall(CodeIr* cIr, lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
+            const char* methodName, ir::Type* returnType,
+            const std::vector<ir::Type*>& types, const std::list<int>& regs) {
+        auto proto = builder_->GetProto(returnType, builder_->GetTypeList(types));
+        auto method = builder_->GetMethodDecl(builder_->GetAsciiString(methodName), proto, type);
+
+        VRegList* paramRegs = cIr->Alloc<VRegList>();
+        for (auto it = regs.begin(); it != regs.end(); it++) {
+            paramRegs->registers.push_back(*it);
+        }
+
+        addInst(cIr, instructionAfter, opcode,
+                { paramRegs, cIr->Alloc<Method>(method, method->orig_index) });
+    }
+
+    void addCall(CodeIr* cIr, lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
+            const char* methodName, ir::Type* returnType, ir::Type* paramType,
+            u4 paramVReg) {
+        auto proto = builder_->GetProto(returnType, builder_->GetTypeList( { paramType }));
+        auto method = builder_->GetMethodDecl(builder_->GetAsciiString(methodName), proto, type);
+
+        VRegRange* args = cIr->Alloc<VRegRange>(paramVReg, 1);
+
+        addInst(cIr, instructionAfter, opcode,
+                { args, cIr->Alloc<Method>(method, method->orig_index) });
+    }
+
+    std::shared_ptr<ir::DexFile> dexIr_;
+    std::unique_ptr<ir::Builder> builder_;
+
+    ir::Type* voidType_ = nullptr;
+    ir::Type* hookType_ = nullptr;
+    ir::Type* objectType_ = nullptr;
+};
 
 std::pair<dex::u1*, size_t> maybeTransform(const char* name, size_t classDataLen,
         const unsigned char* classData, dex::Writer::Allocator* allocator) {
@@ -201,8 +234,11 @@
     reader.CreateClassIr(index);
     std::shared_ptr<ir::DexFile> ir = reader.GetIr();
 
-    if (!transform(ir)) {
-        return std::make_pair(nullptr, 0);
+    {
+        Transformer transformer(ir);
+        if (!transformer.transform()) {
+            return std::make_pair(nullptr, 0);
+        }
     }
 
     size_t new_size;
@@ -372,7 +408,7 @@
     }
 }
 
-jint attach(JavaVM* vm, char* options ATTRIBUTE_UNUSED, void* reserved ATTRIBUTE_UNUSED) {
+jint attach(JavaVM* vm, char* options, void* reserved ATTRIBUTE_UNUSED) {
     gJavaVM = vm;
 
     jvmtiEnv* env;
@@ -383,9 +419,66 @@
 
     prepareHook(env);
 
+    std::vector<std::string> config = android::base::Split(options, ",");
+    for (const std::string& c : config) {
+        if (c == "native_crash") {
+            gForkCrash = true;
+        } else if (c == "java_crash") {
+            gJavaCrash = true;
+        }
+    }
+
     return JVMTI_ERROR_NONE;
 }
 
+extern "C" JNIEXPORT
+jboolean JNICALL Java_com_android_lock_1checker_LockHook_getNativeHandlingConfig(JNIEnv*, jclass) {
+    return gForkCrash ? JNI_TRUE : JNI_FALSE;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_android_lock_1checker_LockHook_getSimulateCrashConfig(JNIEnv*, jclass) {
+    return gJavaCrash ? JNI_TRUE : JNI_FALSE;
+}
+
+extern "C" JNIEXPORT void JNICALL Java_com_android_lock_1checker_LockHook_nWtf(JNIEnv* env, jclass,
+        jstring msg) {
+    if (!gForkCrash || msg == nullptr) {
+        return;
+    }
+
+    // Create a native crash with the given message. Decouple from the current crash to create a
+    // tombstone but continue on.
+    //
+    // TODO: Once there are not so many reports, consider making this fatal for the calling process.
+    ScopedUtfChars utf(env, msg);
+    if (utf.c_str() == nullptr) {
+        return;
+    }
+    const char* args[] = {
+        "/system/bin/lockagent_crasher",
+        utf.c_str(),
+        nullptr
+    };
+    pid_t pid = fork();
+    if (pid < 0) {
+        return;
+    }
+    if (pid == 0) {
+        // Double fork so we return quickly. Leave init to deal with the zombie.
+        pid_t pid2 = fork();
+        if (pid2 == 0) {
+            execv(args[0], const_cast<char* const*>(args));
+            _exit(1);
+            __builtin_unreachable();
+        }
+        _exit(0);
+        __builtin_unreachable();
+    }
+    int status;
+    waitpid(pid, &status, 0);  // Ignore any results.
+}
+
 extern "C" JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char* options, void* reserved) {
     return attach(vm, options, reserved);
 }
diff --git a/tools/lock_agent/crasher.cpp b/tools/lock_agent/crasher.cpp
new file mode 100644
index 0000000..2829d6d
--- /dev/null
+++ b/tools/lock_agent/crasher.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+// Simple binary that will just crash with the message given as the first parameter.
+//
+// This is helpful in cases the caller does not want to crash itself, e.g., fork+crash
+// instead, as LOG(FATAL) might not be safe (for example in a multi-threaded environment).
+int main(int argc, char *argv[]) {
+    if (argc != 2) {
+        LOG(FATAL) << "Need one argument for abort message";
+        __builtin_unreachable();
+    }
+    LOG(FATAL) << argv[1];
+    __builtin_unreachable();
+}
diff --git a/tools/lock_agent/java/com/android/lock_checker/LockHook.java b/tools/lock_agent/java/com/android/lock_checker/LockHook.java
index 95b3181..35c75cb 100644
--- a/tools/lock_agent/java/com/android/lock_checker/LockHook.java
+++ b/tools/lock_agent/java/com/android/lock_checker/LockHook.java
@@ -16,6 +16,7 @@
 
 package com.android.lock_checker;
 
+import android.app.ActivityThread;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -24,6 +25,7 @@
 import android.util.Log;
 import android.util.LogWriter;
 
+import com.android.internal.os.RuntimeInit;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.StatLogger;
 
@@ -66,19 +68,29 @@
 
     static final StatLogger sStats = new StatLogger(new String[] { "on-thread", });
 
-    private static final ConcurrentLinkedQueue<Object> sViolations = new ConcurrentLinkedQueue<>();
+    private static final ConcurrentLinkedQueue<Violation> sViolations =
+            new ConcurrentLinkedQueue<>();
     private static final int MAX_VIOLATIONS = 50;
 
     private static final LockChecker[] sCheckers;
 
+    private static boolean sNativeHandling = false;
+    private static boolean sSimulateCrash = false;
+
     static {
         sHandlerThread = new HandlerThread("LockHook:wtf", Process.THREAD_PRIORITY_BACKGROUND);
         sHandlerThread.start();
         sHandler = new WtfHandler(sHandlerThread.getLooper());
 
         sCheckers = new LockChecker[] { new OnThreadLockChecker() };
+
+        sNativeHandling = getNativeHandlingConfig();
+        sSimulateCrash = getSimulateCrashConfig();
     }
 
+    private static native boolean getNativeHandlingConfig();
+    private static native boolean getSimulateCrashConfig();
+
     static <T> boolean shouldDumpStacktrace(StacktraceHasher hasher, Map<String, T> dumpedSet,
             T val, AnnotatedStackTraceElement[] st, int from, int to) {
         final String stacktraceHash = hasher.stacktraceHash(st, from, to);
@@ -101,8 +113,8 @@
         }
     }
 
-    static void wtf(String message) {
-        sHandler.wtf(message);
+    static void wtf(Violation v) {
+        sHandler.wtf(v);
     }
 
     static void doCheckOnThisThread(boolean check) {
@@ -151,10 +163,10 @@
             super(looper);
         }
 
-        public void wtf(String msg) {
+        public void wtf(Violation v) {
             sDoCheck.set(false);
             SomeArgs args = SomeArgs.obtain();
-            args.arg1 = msg;
+            args.arg1 = v;
             obtainMessage(MSG_WTF, args).sendToTarget();
             sDoCheck.set(true);
         }
@@ -164,13 +176,29 @@
             switch (msg.what) {
                 case MSG_WTF:
                     SomeArgs args = (SomeArgs) msg.obj;
-                    Log.wtf(TAG, (String) args.arg1);
+                    handleViolation((Violation) args.arg1);
                     args.recycle();
                     break;
             }
         }
     }
 
+    private static void handleViolation(Violation v) {
+        String msg = v.toString();
+        Log.wtf(TAG, msg);
+        if (sNativeHandling) {
+            nWtf(msg);  // Also send to native.
+        }
+        if (sSimulateCrash) {
+            RuntimeInit.logUncaught("LockAgent",
+                    ActivityThread.isSystem() ? "system_server"
+                            : ActivityThread.currentProcessName(),
+                    Process.myPid(), v.getException());
+        }
+    }
+
+    private static native void nWtf(String msg);
+
     /**
      * Generates a hash for a given stacktrace of a {@link Throwable}.
      */
@@ -224,8 +252,10 @@
         }
     }
 
-    static void addViolation(Object o) {
-        sViolations.offer(o);
+    static void addViolation(Violation v) {
+        wtf(v);
+
+        sViolations.offer(v);
         while (sViolations.size() > MAX_VIOLATIONS) {
             sViolations.poll();
         }
@@ -287,4 +317,8 @@
 
         void dump(PrintWriter pw);
     }
+
+    interface Violation {
+        Throwable getException();
+    }
 }
diff --git a/tools/lock_agent/java/com/android/lock_checker/OnThreadLockChecker.java b/tools/lock_agent/java/com/android/lock_checker/OnThreadLockChecker.java
index 0f3a285..e74ccf9 100644
--- a/tools/lock_agent/java/com/android/lock_checker/OnThreadLockChecker.java
+++ b/tools/lock_agent/java/com/android/lock_checker/OnThreadLockChecker.java
@@ -220,7 +220,7 @@
         heldLocks.remove(index);
     }
 
-    private static class Violation {
+    private static class Violation implements LockHook.Violation {
         int mSelfTid;
         String mSelfName;
         Object mAlreadyHeld;
@@ -228,6 +228,8 @@
         AnnotatedStackTraceElement[] mStack;
         OrderData mOppositeData;
 
+        private static final int STACK_OFFSET = 4;
+
         Violation(Thread self, Object alreadyHeld, Object lock,
                 AnnotatedStackTraceElement[] stack, OrderData oppositeData) {
             this.mSelfTid = (int) self.getId();
@@ -284,6 +286,26 @@
                     lock.getClass().getName());
         }
 
+        // Synthesize an exception.
+        public Throwable getException() {
+            RuntimeException inner = new RuntimeException("Previously locked");
+            inner.setStackTrace(synthesizeStackTrace(mOppositeData.mStack));
+
+            RuntimeException outer = new RuntimeException(toString(), inner);
+            outer.setStackTrace(synthesizeStackTrace(mStack));
+
+            return outer;
+        }
+
+        private StackTraceElement[] synthesizeStackTrace(AnnotatedStackTraceElement[] stack) {
+
+            StackTraceElement[] out = new StackTraceElement[stack.length - STACK_OFFSET];
+            for (int i = 0; i < out.length; i++) {
+                out[i] = stack[i + STACK_OFFSET].getStackTraceElement();
+            }
+            return out;
+        }
+
         public String toString() {
             StringBuilder sb = new StringBuilder();
             sb.append("Lock inversion detected!\n");
@@ -294,7 +316,7 @@
             sb.append(" on thread ").append(mOppositeData.mTid).append(" (")
                     .append(mOppositeData.mThreadName).append(")");
             sb.append(" at:\n");
-            sb.append(getAnnotatedStackString(mOppositeData.mStack, 4,
+            sb.append(getAnnotatedStackString(mOppositeData.mStack, STACK_OFFSET,
                     describeLocking(mAlreadyHeld, "will lock"), getTo(mOppositeData.mStack, mLock)
                     + 1, "    | "));
             sb.append("  Locking ");
@@ -303,7 +325,8 @@
             sb.append(describeLock(mLock));
             sb.append(" on thread ").append(mSelfTid).append(" (").append(mSelfName).append(")");
             sb.append(" at:\n");
-            sb.append(getAnnotatedStackString(mStack, 4, describeLocking(mLock, "will lock"),
+            sb.append(getAnnotatedStackString(mStack, STACK_OFFSET,
+                    describeLocking(mLock, "will lock"),
                     getTo(mStack, mAlreadyHeld) + 1, "    | "));
 
             return sb.toString();
@@ -323,7 +346,6 @@
         if (LockHook.shouldDumpStacktrace(mStacktraceHasher.get(), mDumpedStacktraceHashes,
                 Boolean.TRUE, v.mStack, 0, to)) {
             mNumDetectedUnique.incrementAndGet();
-            LockHook.wtf(v.toString());
             LockHook.addViolation(v);
         }
     }
diff --git a/tools/lock_agent/start_with_lockagent.sh b/tools/lock_agent/start_with_lockagent.sh
index 9539222..70ed5c5 100755
--- a/tools/lock_agent/start_with_lockagent.sh
+++ b/tools/lock_agent/start_with_lockagent.sh
@@ -1,5 +1,13 @@
 #!/system/bin/sh
+
+AGENT_OPTIONS=
+if [[ "$1" == --agent-options ]] ; then
+  shift
+  AGENT_OPTIONS="=$1"
+  shift
+fi
+
 APP=$1
 shift
-$APP -Xplugin:libopenjdkjvmti.so -agentpath:liblockagent.so $@
 
+$APP -Xplugin:libopenjdkjvmti.so "-agentpath:liblockagent.so$AGENT_OPTIONS" $@
diff --git a/tools/preload2/Android.bp b/tools/preload2/Android.bp
new file mode 100644
index 0000000..5809421
--- /dev/null
+++ b/tools/preload2/Android.bp
@@ -0,0 +1,50 @@
+// 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.
+
+java_library_host {
+    name: "preload2",
+
+    srcs: ["src/**/*.java"],
+
+    // To connect to devices (and take hprof dumps).
+    static_libs: [
+        "ddmlib-prebuilt",
+        "tools-common-prebuilt",
+
+        // To process hprof dumps.
+        "perflib-prebuilt",
+
+        "trove-prebuilt",
+        "guavalib",
+
+        // For JDWP access we use the framework in the JDWP tests from Apache Harmony, for
+        // convenience (and to not depend on internal JDK APIs).
+        "apache-harmony-jdwp-tests",
+        "junit",
+    ],
+
+    // Copy to build artifacts
+    dist: {
+        targets: [
+            "dist_files",
+        ],
+    },
+}
+
+// Copy the preload-tool shell script to the host's bin directory.
+sh_binary_host {
+    name: "preload-tool",
+    src: "preload-tool",
+    required: ["preload2"],
+}
diff --git a/tools/preload2/Android.mk b/tools/preload2/Android.mk
deleted file mode 100644
index d3ee1d3..0000000
--- a/tools/preload2/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-# To connect to devices (and take hprof dumps).
-LOCAL_STATIC_JAVA_LIBRARIES := ddmlib-prebuilt tools-common-prebuilt
-
-# To process hprof dumps.
-LOCAL_STATIC_JAVA_LIBRARIES += perflib-prebuilt trove-prebuilt guavalib
-
-# For JDWP access we use the framework in the JDWP tests from Apache Harmony, for
-# convenience (and to not depend on internal JDK APIs).
-LOCAL_STATIC_JAVA_LIBRARIES += apache-harmony-jdwp-tests-host junit-host
-
-LOCAL_MODULE:= preload2
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-# Copy to build artifacts
-$(call dist-for-goals,dist_files,$(LOCAL_BUILT_MODULE):$(LOCAL_MODULE).jar)
-
-# Copy the preload-tool shell script to the host's bin directory.
-include $(CLEAR_VARS)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := preload-tool
-LOCAL_SRC_FILES := preload-tool
-LOCAL_REQUIRED_MODULES := preload2
-include $(BUILD_PREBUILT)
diff --git a/tools/processors/staledataclass/Android.bp b/tools/processors/staledataclass/Android.bp
new file mode 100644
index 0000000..c81d410
--- /dev/null
+++ b/tools/processors/staledataclass/Android.bp
@@ -0,0 +1,27 @@
+
+java_plugin {
+    name: "staledataclass-annotation-processor",
+    processor_class: "android.processor.staledataclass.StaleDataclassProcessor",
+
+    java_resources: [
+        "META-INF/**/*",
+    ],
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "codegen-version-info",
+    ],
+    openjdk9: {
+        javacflags: [
+            "--add-modules=jdk.compiler",
+            "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
+            "--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
+            "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+            "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+        ],
+    },
+
+    use_tools_jar: true,
+}
diff --git a/tools/processors/staledataclass/META-INF/services/javax.annotation.processing.Processor b/tools/processors/staledataclass/META-INF/services/javax.annotation.processing.Processor
new file mode 100644
index 0000000..15ee623
--- /dev/null
+++ b/tools/processors/staledataclass/META-INF/services/javax.annotation.processing.Processor
@@ -0,0 +1 @@
+android.processor.staledataclass.StaleDataclassProcessorOld
diff --git a/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
new file mode 100644
index 0000000..9e51180
--- /dev/null
+++ b/tools/processors/staledataclass/src/android/processor/staledataclass/StaleDataclassProcessor.kt
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.processor.staledataclass
+
+import com.android.codegen.CODEGEN_NAME
+import com.android.codegen.CODEGEN_VERSION
+import com.sun.tools.javac.code.Symbol
+import com.sun.tools.javac.code.Type
+import java.io.File
+import java.io.FileNotFoundException
+import javax.annotation.processing.AbstractProcessor
+import javax.annotation.processing.RoundEnvironment
+import javax.annotation.processing.SupportedAnnotationTypes
+import javax.lang.model.SourceVersion
+import javax.lang.model.element.AnnotationMirror
+import javax.lang.model.element.Element
+import javax.lang.model.element.TypeElement
+import javax.tools.Diagnostic
+
+private const val STALE_FILE_THRESHOLD_MS = 1000
+private val WORKING_DIR = File(".").absoluteFile
+
+private const val DATACLASS_ANNOTATION_NAME = "com.android.internal.util.DataClass"
+private const val GENERATED_ANNOTATION_NAME = "com.android.internal.util.DataClass.Generated"
+private const val GENERATED_MEMBER_ANNOTATION_NAME
+        = "com.android.internal.util.DataClass.Generated.Member"
+
+
+@SupportedAnnotationTypes(DATACLASS_ANNOTATION_NAME, GENERATED_ANNOTATION_NAME)
+class StaleDataclassProcessor: AbstractProcessor() {
+
+    private var dataClassAnnotation: TypeElement? = null
+    private var generatedAnnotation: TypeElement? = null
+    private var repoRoot: File? = null
+
+    private val stale = mutableListOf<Stale>()
+
+    /**
+     * This is the main entry point in the processor, called by the compiler.
+     */
+    override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
+
+        if (generatedAnnotation == null) {
+            generatedAnnotation = annotations.find {
+                it.qualifiedName.toString() == GENERATED_ANNOTATION_NAME
+            }
+        }
+        if (dataClassAnnotation == null) {
+            dataClassAnnotation = annotations.find {
+                it.qualifiedName.toString() == DATACLASS_ANNOTATION_NAME
+            }
+        }
+
+        val generatedAnnotatedElements = roundEnv.getElementsAnnotatedWith(generatedAnnotation)
+        generatedAnnotatedElements.forEach {
+            processSingleFile(it)
+        }
+
+
+        val dataClassesWithoutGeneratedPart =
+                roundEnv.getElementsAnnotatedWith(dataClassAnnotation) -
+                        generatedAnnotatedElements.map { it.enclosingElement }
+
+        dataClassesWithoutGeneratedPart.forEach { dataClass ->
+            stale += Stale(dataClass.toString(), file = null, lastGenerated = 0L)
+        }
+
+
+        if (!stale.isEmpty()) {
+            error("Stale generated dataclass(es) detected. " +
+                    "Run the following command(s) to update them:" +
+                    stale.joinToString("") { "\n" + it.refreshCmd })
+        }
+        return true
+    }
+
+    private fun elemToString(elem: Element): String {
+        return buildString {
+            append(elem.modifiers.joinToString(" ") { it.name.toLowerCase() }).append(" ")
+            append(elem.annotationMirrors.joinToString(" ")).append(" ")
+            if (elem is Symbol) {
+                if (elem.type is Type.MethodType) {
+                    append((elem.type as Type.MethodType).returnType)
+                } else {
+                    append(elem.type)
+                }
+                append(" ")
+            }
+            append(elem)
+        }
+    }
+
+    private fun processSingleFile(elementAnnotatedWithGenerated: Element) {
+
+        val inputSignatures = elementAnnotatedWithGenerated
+                .enclosingElement
+                .enclosedElements
+                .filterNot {
+                    it.annotationMirrors.any { "Generated" in it.annotationType.toString() }
+                }.map {
+                    elemToString(it)
+                }.toSet()
+
+        val annotationParams = elementAnnotatedWithGenerated
+                .annotationMirrors
+                .find { ann -> isGeneratedAnnotation(ann) }!!
+                .elementValues
+                .map { (k, v) -> k.getSimpleName().toString() to v.getValue() }
+                .toMap()
+
+        val lastGenerated = annotationParams["time"] as Long
+        val codegenVersion = annotationParams["codegenVersion"] as String
+        val sourceRelative = File(annotationParams["sourceFile"] as String)
+
+        val lastGenInputSignatures = (annotationParams["inputSignatures"] as String).lines().toSet()
+
+        if (repoRoot == null) {
+            repoRoot = generateSequence(WORKING_DIR) { it.parentFile }
+                    .find { it.resolve(sourceRelative).isFile }
+                    ?.canonicalFile
+                    ?: throw FileNotFoundException(
+                            "Failed to detect repository root: " +
+                                    "no parent of $WORKING_DIR contains $sourceRelative")
+        }
+
+        val source = repoRoot!!.resolve(sourceRelative)
+        val clazz = elementAnnotatedWithGenerated.enclosingElement.toString()
+
+        if (inputSignatures != lastGenInputSignatures) {
+            error(buildString {
+                append(sourceRelative).append(":\n")
+                append("  Added:\n").append((inputSignatures-lastGenInputSignatures).joinToString("\n"))
+                append("\n")
+                append("  Removed:\n").append((lastGenInputSignatures-inputSignatures).joinToString("\n"))
+            })
+            stale += Stale(clazz, source, lastGenerated)
+        }
+
+        if (codegenVersion != CODEGEN_VERSION) {
+            stale += Stale(clazz, source, lastGenerated)
+        }
+    }
+
+    private fun error(msg: String) {
+        processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, msg)
+    }
+
+    private fun isGeneratedAnnotation(ann: AnnotationMirror): Boolean {
+        return generatedAnnotation!!.qualifiedName.toString() == ann.annotationType.toString()
+    }
+
+    data class Stale(val clazz: String, val file: File?, val lastGenerated: Long) {
+        val refreshCmd = if (file != null) {
+            "$CODEGEN_NAME $file"
+        } else {
+            "find \$ANDROID_BUILD_TOP -path */${clazz.replace('.', '/')}.java -exec $CODEGEN_NAME {} \\;"
+        }
+    }
+
+    override fun getSupportedSourceVersion(): SourceVersion {
+        return SourceVersion.latest()
+    }
+}
\ No newline at end of file
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 1aad4be..f62fef0 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -131,14 +131,10 @@
                                                  "mobile_bytes_transfer"};
     fprintf(out,
             "const std::set<int> "
-            "AtomsInfo::kNotTruncatingTimestampAtomWhiteList = {\n");
-    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
-         atom != atoms.decls.end(); atom++) {
-        if (kTruncatingAtomNames.find(atom->name) ==
-            kTruncatingAtomNames.end()) {
-            string constant = make_constant_name(atom->name);
-            fprintf(out, " %s,\n", constant.c_str());
-        }
+            "AtomsInfo::kTruncatingTimestampAtomBlackList = {\n");
+    for (set<string>::const_iterator blacklistedAtom = kTruncatingAtomNames.begin();
+         blacklistedAtom != kTruncatingAtomNames.end(); blacklistedAtom++) {
+            fprintf(out, " %s,\n", make_constant_name(*blacklistedAtom).c_str());
     }
     fprintf(out, "};\n");
     fprintf(out, "\n");
@@ -840,7 +836,7 @@
         fprintf(out, "struct AtomsInfo {\n");
         fprintf(out,
                 "  const static std::set<int> "
-                "kNotTruncatingTimestampAtomWhiteList;\n");
+                "kTruncatingTimestampAtomBlackList;\n");
         fprintf(out, "  const static std::map<int, int> kAtomsWithUidField;\n");
         fprintf(out,
                 "  const static std::set<int> kAtomsWithAttributionChain;\n");
diff --git a/tools/streaming_proto/Android.bp b/tools/streaming_proto/Android.bp
index 1121ead..14eead8 100644
--- a/tools/streaming_proto/Android.bp
+++ b/tools/streaming_proto/Android.bp
@@ -49,3 +49,18 @@
 
     defaults: ["protoc-gen-stream-defaults"],
 }
+
+// ==========================================================
+// Build the java test
+// ==========================================================
+java_library {
+    name: "StreamingProtoTest",
+    srcs: [
+        "test/**/*.java",
+        "test/**/*.proto",
+    ],
+    proto: {
+        plugin: "javastream",
+    },
+    static_libs: ["libprotobuf-java-lite"],
+}
diff --git a/tools/streaming_proto/Android.mk b/tools/streaming_proto/Android.mk
deleted file mode 100644
index ebb77a1..0000000
--- a/tools/streaming_proto/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# 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.
-#
-LOCAL_PATH:= $(call my-dir)
-
-# ==========================================================
-# Build the java test
-# ==========================================================
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, test) \
-    $(call all-proto-files-under, test)
-LOCAL_MODULE := StreamingProtoTest
-LOCAL_PROTOC_OPTIMIZE_TYPE := stream
-include $(BUILD_JAVA_LIBRARY)
-
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 9010f3c9..1829baa 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -29,7 +29,6 @@
 import android.net.wifi.ISoftApCallback;
 import android.net.wifi.ITrafficStateCallback;
 import android.net.wifi.IOnWifiUsabilityStatsListener;
-import android.net.wifi.PasspointManagementObjectDefinition;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiActivityEnergyInfo;
 import android.net.wifi.WifiConfiguration;
diff --git a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.aidl b/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.aidl
deleted file mode 100644
index eb7cc39..0000000
--- a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-parcelable PasspointManagementObjectDefinition;
diff --git a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java b/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java
deleted file mode 100644
index 70577b9..0000000
--- a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * This object describes a partial tree structure in the Hotspot 2.0 release 2 management object.
- * The object is used during subscription remediation to modify parts of an existing PPS MO
- * tree (Hotspot 2.0 specification section 9.1).
- * @hide
- */
-public class PasspointManagementObjectDefinition implements Parcelable {
-    private final String mBaseUri;
-    private final String mUrn;
-    private final String mMoTree;
-
-    public PasspointManagementObjectDefinition(String baseUri, String urn, String moTree) {
-        mBaseUri = baseUri;
-        mUrn = urn;
-        mMoTree = moTree;
-    }
-
-    public String getBaseUri() {
-        return mBaseUri;
-    }
-
-    public String getUrn() {
-        return mUrn;
-    }
-
-    public String getMoTree() {
-        return mMoTree;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mBaseUri);
-        dest.writeString(mUrn);
-        dest.writeString(mMoTree);
-    }
-
-    /**
-     * Implement the Parcelable interface {@hide}
-     */
-    public static final @android.annotation.NonNull Creator<PasspointManagementObjectDefinition> CREATOR =
-            new Creator<PasspointManagementObjectDefinition>() {
-                public PasspointManagementObjectDefinition createFromParcel(Parcel in) {
-                    return new PasspointManagementObjectDefinition(
-                            in.readString(),    /* base URI */
-                            in.readString(),    /* URN */
-                            in.readString()     /* Tree XML */
-                    );
-                }
-
-                public PasspointManagementObjectDefinition[] newArray(int size) {
-                    return new PasspointManagementObjectDefinition[size];
-                }
-            };
-}
-
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 1a16aaa..89ed080 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1691,6 +1691,8 @@
 
     /**
      * Remove some or all of the network suggestions that were previously provided by the app.
+     * If the current network is a suggestion being removed and if it was only provided by this app
+     * and is not a saved network then the framework will immediately disconnect.
      * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters.
      * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used.
      *
diff --git a/wifi/java/android/net/wifi/WpsResult.aidl b/wifi/java/android/net/wifi/WpsResult.aidl
deleted file mode 100644
index eb4c4f5..0000000
--- a/wifi/java/android/net/wifi/WpsResult.aidl
+++ /dev/null
@@ -1,19 +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.
- */
-
-package android.net.wifi;
-
-parcelable WpsResult;
diff --git a/wifi/java/android/net/wifi/WpsResult.java b/wifi/java/android/net/wifi/WpsResult.java
deleted file mode 100644
index f2ffb6f..0000000
--- a/wifi/java/android/net/wifi/WpsResult.java
+++ /dev/null
@@ -1,90 +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.
- */
-
-package android.net.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A class representing the result of a WPS request
- * @hide
- */
-public class WpsResult implements Parcelable {
-
-    public enum Status {
-        SUCCESS,
-        FAILURE,
-        IN_PROGRESS,
-    }
-
-    public Status status;
-
-    public String pin;
-
-    public WpsResult() {
-        status = Status.FAILURE;
-        pin = null;
-    }
-
-    public WpsResult(Status s) {
-        status = s;
-        pin = null;
-    }
-
-    public String toString() {
-        StringBuffer sbuf = new StringBuffer();
-        sbuf.append(" status: ").append(status.toString());
-        sbuf.append('\n');
-        sbuf.append(" pin: ").append(pin);
-        sbuf.append("\n");
-        return sbuf.toString();
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public int describeContents() {
-        return 0;
-    }
-
-    /** copy constructor {@hide} */
-    public WpsResult(WpsResult source) {
-        if (source != null) {
-            status = source.status;
-            pin = source.pin;
-        }
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(status.name());
-        dest.writeString(pin);
-    }
-
-    /** Implement the Parcelable interface {@hide} */
-    public static final @android.annotation.NonNull Creator<WpsResult> CREATOR =
-        new Creator<WpsResult>() {
-            public WpsResult createFromParcel(Parcel in) {
-                WpsResult result = new WpsResult();
-                result.status = Status.valueOf(in.readString());
-                result.pin = in.readString();
-                return result;
-            }
-
-            public WpsResult[] newArray(int size) {
-                return new WpsResult[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index daea601..0511f24 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -31,11 +31,8 @@
 import java.util.Objects;
 
 /**
- * Network specifier object used to request a Wi-Fi Aware network. Apps do not create these objects
- * directly but obtain them using
- * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} or
- * {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)} or their secure (Passphrase)
- * versions.
+ * Network specifier object used to request a Wi-Fi Aware network. Apps should use the
+ * {@link WifiAwareNetworkSpecifier.Builder} class to create an instance.
  */
 public final class WifiAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
     /**
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.aidl b/wifi/java/android/net/wifi/hotspot2/pps/Policy.aidl
deleted file mode 100644
index e923f1f..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-parcelable Policy;
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.aidl b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.aidl
deleted file mode 100644
index 701db47..0000000
--- a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2017, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.hotspot2.pps;
-
-parcelable UpdateParameter;
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl
deleted file mode 100644
index 3d8a476..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p;
-
-parcelable WifiP2pGroupList;
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index cd659e2..d37c4a2 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -190,7 +190,7 @@
      * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in
      * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides
      * the network info in the form of a {@link android.net.NetworkInfo}. A third extra provides
-     * the details of the group.
+     * the details of the group and may contain a {@code null}.
      *
      * All of these permissions are required to receive this broadcast:
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
diff --git a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.aidl b/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.aidl
deleted file mode 100644
index c81d1f9..0000000
--- a/wifi/java/android/net/wifi/p2p/nsd/WifiP2pServiceResponse.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.p2p.servicediscovery;
-
-parcelable WifiP2pServiceResponse;